EMAN::Transform Class Reference
[unit test in Python]

A Transform object is a somewhat specialized object designed specifically for EMAN2/Sparx storage of alignment parameters and euler orientations. More...

#include <transform.h>

List of all members.

Public Member Functions

 Transform ()
 Default constructor Internal matrix is the identity.
 Transform (const Transform &rhs)
 Copy constructor.
Transformoperator= (const Transform &that)
 Assignment operator.
bool operator== (const Transform &rhs) const
 Equality comparision operator.
bool operator!= (const Transform &rhs) const
 Unequality comparision operator.
 Transform (const Dict &d)
 Construction using a dictionary.
 Transform (const float array[12])
 Construction using an array of floats.
 Transform (const vector< float > array)
 Construction using a vector of size 12.
 ~Transform ()
void set_rotation (const Dict &rotation)
 Set a rotation using a specific Euler type and the dictionary interface Works for all Euler types.
void set_rotation (const Vec3f &v)
 Determine the rotation that would transform a vector pointing in the Z direction so that it points in the direction of the argument vector Automatically normalizes the vector.
void rotate_origin (const Transform &by)
 Increment the rotation by multipling the rotation bit of the argument transfrom by the rotation part of the current transfrom.
void rotate (const Transform &by)
 Increment the rotation by multipling the rotation bit of the argument transfrom by the current transfrom.
Dict get_rotation (const string &euler_type="eman") const
 Get a rotation in any Euler format.
Transform get_rotation_transform () const
 Get the rotation part of the tranformation matrix as a Transform object.
Transform get_hflip_transform () const
 How do I get the transform that will yield the horizontally flipped projection?
Transform get_vflip_transform () const
 How do I get the transform that will yield the vertically flipped projection?
void set_params (const Dict &d)
 Set the parameters of the entire transform.
void set_params_inverse (const Dict &d)
 Set the parameters of the entire transform as though they there in the inverse format.
Dict get_params (const string &euler_type) const
 Get the parameters of the entire transform, using a specific euler convention.
Dict get_params_inverse (const string &euler_type) const
 Get the parameters of the inverse of the transform as though it were in RSMT order not MTSR.
void set_trans (const float &x, const float &y, const float &z=0)
 Set the post translation component.
void set_trans (const Vec3f &v)
 Set the post translation component using a Vec3f.
void set_trans (const Vec2f &v)
 Set the post translation component using a Vec2f.
Vec3f get_trans () const
 Get the post trans as a vec3f.
void translate (const float &tx, const float &ty, const float &tz=0)
 Increment the current translation by tx, ty, tz.
void translate (const Vec3f &v)
 Increment the current translation using vec3f& v.
void translate (const Vec2f &v)
 Increment the current translation using vec2f& v.
Vec2f get_trans_2d () const
 Get the degenerant 2D post trans as a vec2f.
Vec3f get_pre_trans () const
 Get the translation vector as though this object was MSRT_ not MTSR, where T_ is what you want Note M means post x mirror, T means translation, S means scale, and R means rotaiton.
Vec2f get_pre_trans_2d () const
 2D version of getting the translation vector as though this object was MSRT_ not MTSR, where T_ is what you want Note M means post x mirror, T means translation, S means scale, and R means rotation
template<typename type>
void set_pre_trans (const type &v)
 Set the translational component of the matrix as though it was MSRT_ not MTSR, where T_ is the pre translation.
void set_scale (const float &scale)
 Set the scale.
float get_scale () const
 Get the scale that was applied.
void scale (const float &scale)
 Increment the scale.
bool get_mirror () const
 Query whether x_mirroring is occuring.
void set_mirror (const bool x_mirror)
 Set whether or not x_mirroring is occuring.
void get_scale_and_mirror (float &scale, bool &x_mirror) const
 Get scale and x_mirror with 1 function call.
void to_identity ()
 Force the internal matrix to become the identity.
bool is_identity () const
 Returns whethers or this matrix is the identity.
void orthogonalize ()
 Reorthogonalize the rotation part of the matrix in place.
float get_determinant () const
 Get the determinant of the matrix.
void printme () const
 Print the contents of the internal matrix verbatim to standard out.
void set_matrix (const vector< float > &v)
 Set the transformation matrix using a vector.
vector< float > get_matrix () const
 Get the transformation matrix using a vector.
vector< float > get_matrix_4x4 () const
 Get the 4x4 transformation matrix using a vector.
void invert ()
 Get the inverse of this transformation matrix.
Transform inverse () const
 Get the inverse of this transformation matrix.
void transpose_inplace ()
 Get the transpose of this transformation matrix.
Transform transpose () const
 Get the transpose of this transformation matrix.
float at (int r, int c) const
 Get the value stored in the internal transformation matrix at at coordinate (r,c).
void set (int r, int c, float value)
 Set the value stored in the internal transformation matrix at at coordinate (r,c) to value.
float * operator[] (int i)
 Operator[] convenience so Transform3D[2][2] etc terminology can be used.
const float * operator[] (int i) const
 Operator[] convenience so Transform3D[2][2] etc terminology can be used.
Vec2f transform (const float &x, const float &y) const
 Transform 2D coordinates using the internal transformation matrix.
template<typename Type>
Vec2f transform (const Vec2< Type > &v) const
 Transform a 2D vector using the internal transformation matrix.
Vec3f transform (const float &x, const float &y, const float &z) const
 Transform 3D coordinates using the internal transformation matrix.
template<typename Type>
Vec3f transform (const Vec3< Type > &v) const
 Transform a 3D vector using the internal transformation matrix.
Vec3f get_matrix3_row (int i) const
 Get a matrix row as a Vec3f required for back compatibility with Tranform3D - see PawelProjector.
Transform get_sym (const string &sym, int n) const
 Apply the symmetry deduced from the function arguments to this Transform and return the result.
vector< Transformget_sym_proj (const string &sym) const
void copy_matrix_into_array (float *const) const
Transform negate () const
 Negates the Transform - a useful way, for example, for getting an orientation on the opposite side of the sphere.

Static Public Member Functions

static int get_nsym (const string &sym)
 get the number of symmetries associated with the given symmetry name
static Transform tet_3_to_2 ()
 Get the transform that moves any tetrahedron generated by eman2 so that it matches the 2-2-2 (MRC, FREALIGN) convention.
static Transform icos_5_to_2 ()
 Get the transform that moves any icosahedron generated by eman2 so that it matches the 2-2-2 (MRC, FREALIGN) convention.

Static Public Attributes

static const float ERR_LIMIT = 0.000001f

Private Member Functions

void assert_valid_2d () const
void init_permissable_keys ()
 Called internally to initialize permissable_2d_not_rot, permissable_3d_not_rot, and permissable_rot_keys static members.
void detect_problem_keys (const Dict &d)
 Test to ensure the parametes in the given dictionary are valid Throws if an error is detected Generic - works in every circumstance (set_params, set_rotation, set_params_inv) Uses static members permissable_2d_not_rot, permissable_3d_not_rot, and permissable_rot_keys as basis of decision.

Private Attributes

float matrix [3][4]

Static Private Attributes

static vector< string > permissable_2d_not_rot
 This map is used to validate keys in the argument maps - e.g. if the type is 2d and the angle is not "alpha" then we should throw.
static vector< string > permissable_3d_not_rot
static map< string, vector<
string > > 
permissable_rot_keys


Detailed Description

A Transform object is a somewhat specialized object designed specifically for EMAN2/Sparx storage of alignment parameters and euler orientations.

It's designed to store four transformations in a specific order, namely Transform = MTSR Where M is a mirroring operation (about the x-axis) or the identity T is a Translation matrix S is a uniform scaling matrix R is a rotation matrix This means you can call set_scale, set_trans, set_rotation in any order but still have the operations arranged internally in the order of MTSR. This is somewhat restrictive, for example in the context of how OpenGL handles transformations, but in practice is nicely suited to the situations that arise in EMAN2 - namely, alignment and projection orientation characterization.

Note that you can fool the Transform object into storing any matrix by using the constructors that take array arguments. This can useful, for example, for shearing your image.

See http://blake.bcm.tmc.edu/emanwiki/Eman2TransformInPython for using it from Python and detailed discussion See test_transform.py for examples of the way it is unit tested See http://blake.bcm.tmc.edu/emanwiki/EMAN2/Tutorials/RotateTranslate for examples showing how to transform EMDatas with it.

Author:
David Woolford (based on Philip Baldwin's original Transform3D code)
Date:
September 2008

Definition at line 83 of file transform.h.


Constructor & Destructor Documentation

Transform::Transform (  ) 

Default constructor Internal matrix is the identity.

Definition at line 98 of file transform.cpp.

References to_identity().

Referenced by set_params_inverse().

00099 {
00100         to_identity();
00101 }

Transform::Transform ( const Transform rhs  ) 

Copy constructor.

Parameters:
rhs the object to be copied

Definition at line 103 of file transform.cpp.

00104 {
00105         *this = that;
00106 }

Transform::Transform ( const Dict d  ) 

Construction using a dictionary.

Parameters:
d the dictionary containing the parameters

Definition at line 129 of file transform.cpp.

References set_params(), and to_identity().

00129                                    {
00130         to_identity();
00131         set_params(d);
00132 }

Transform::Transform ( const float  array[12]  ) 

Construction using an array of floats.

Parameters:
array the array of values that will become the internal matrix. row order (3 rows of 4)

Definition at line 135 of file transform.cpp.

References matrix.

00135                                           {
00136         memcpy(matrix,array,12*sizeof(float));
00137 }

Transform::Transform ( const vector< float >  array  ) 

Construction using a vector of size 12.

Parameters:
array the array of values that will become the internal matrix. row order (3 rows of 4)

Definition at line 139 of file transform.cpp.

References set_matrix().

00140 {
00141         set_matrix(array);
00142 }

EMAN::Transform::~Transform (  )  [inline]

Definition at line 131 of file transform.h.

00131 { }


Member Function Documentation

void Transform::assert_valid_2d (  )  const [private]

Definition at line 1240 of file transform.cpp.

References ERR_LIMIT, matrix, and UnexpectedBehaviorException.

Referenced by get_rotation(), and set_rotation().

01240                                       {
01241         int rotation_error = 0;
01242         int translation_error = 0;
01243         if (fabs(matrix[2][0]) > ERR_LIMIT) rotation_error++;
01244         if (fabs(matrix[2][1]) > ERR_LIMIT) rotation_error++;
01245         if (fabs(matrix[2][3]) > ERR_LIMIT) translation_error++;
01246         if (fabs(matrix[0][2]) > ERR_LIMIT) rotation_error++;
01247         if (fabs(matrix[1][2]) > ERR_LIMIT) rotation_error++;
01248 //      if (fabs(matrix[2][2]-1.0) >ERR_LIMIT) rotation_error++; 
01249         if ( translation_error && rotation_error ) {
01250                 throw UnexpectedBehaviorException("Error, the internal matrix contains 3D rotations and 3D translations. This object can not be considered 2D");
01251         } else if ( translation_error ) {
01252                 throw UnexpectedBehaviorException("Error, the internal matrix contains a non zero z component for a 3D translation. This object can not be considered 2D");
01253         }
01254         else if ( rotation_error ) {
01255                 throw UnexpectedBehaviorException("Error, the internal matrix contains 3D rotations and this object can not be considered 2D");
01256         }
01257 
01258 }

float EMAN::Transform::at ( int  r,
int  c 
) const [inline]

Get the value stored in the internal transformation matrix at at coordinate (r,c).

Definition at line 374 of file transform.h.

References matrix.

Referenced by EMAN::PawelProjector::backproject3d().

00374 { return matrix[r][c]; }

void Transform::copy_matrix_into_array ( float *  const  )  const

Definition at line 155 of file transform.cpp.

References matrix.

Referenced by EMAN::FourierReconstructor::do_compare_slice_work(), EMAN::FourierReconstructor::do_insert_slice_work(), EMAN::TransformProcessor::process(), EMAN::TransformProcessor::process_inplace(), and EMAN::StandardProjector::project3d().

00155                                                                {
00156 
00157         int idx = 0;
00158         for(int i=0; i<3; ++i) {
00159                 for(int j=0; j<4; ++j) {
00160                         array[idx] = matrix[i][j];
00161                         idx ++;
00162                 }
00163         }
00164 }

void Transform::detect_problem_keys ( const Dict d  )  [private]

Test to ensure the parametes in the given dictionary are valid Throws if an error is detected Generic - works in every circumstance (set_params, set_rotation, set_params_inv) Uses static members permissable_2d_not_rot, permissable_3d_not_rot, and permissable_rot_keys as basis of decision.

Parameters:
d the dictionary that was the function argument of the set_params, set_rotation or the set_params_inv function
Exceptions:
InvalidParameterException if the dictionary is invalid in anyway

Definition at line 340 of file transform.cpp.

References EMAN::Dict::begin(), copy(), EMAN::Dict::end(), EMAN::Dict::has_key_ci(), init_permissable_keys(), InvalidParameterException, permissable_2d_not_rot, permissable_3d_not_rot, permissable_rot_keys, and EMAN::Util::str_to_lower().

Referenced by set_params(), set_params_inverse(), and set_rotation().

00340                                                  {
00341         if (permissable_rot_keys.size() == 0 ) {
00342                 init_permissable_keys();
00343         }
00344 
00345         vector<string> verification;
00346         vector<string> problem_keys;
00347         bool is_2d = false;
00348         if (d.has_key_ci("type") ) {
00349                 string type = Util::str_to_lower((string)d["type"]);
00350                 bool problem = false;
00351                 if (permissable_rot_keys.find(type) == permissable_rot_keys.end() ) {
00352                         problem_keys.push_back(type);
00353                         problem = true;
00354                 }
00355                 if ( !problem ) {
00356                         vector<string> perm = permissable_rot_keys[type];
00357                         std::copy(perm.begin(),perm.end(),back_inserter(verification));
00358 
00359                         if ( type == "2d" ) {
00360                                 is_2d = true;
00361                                 std::copy(permissable_2d_not_rot.begin(),permissable_2d_not_rot.end(),back_inserter(verification));
00362                         }
00363                 }
00364         }
00365         if ( !is_2d ) {
00366                 std::copy(permissable_3d_not_rot.begin(),permissable_3d_not_rot.end(),back_inserter(verification));
00367         }
00368 
00369         for (Dict::const_iterator it = d.begin(); it != d.end();  ++it) {
00370                 if ( std::find(verification.begin(),verification.end(), it->first) == verification.end() ) {
00371                         problem_keys.push_back(it->first);
00372                 }
00373         }
00374 
00375         if (problem_keys.size() != 0 ) {
00376                 string error;
00377                 if (problem_keys.size() == 1) {
00378                         error = "Transform Error: The \"" +problem_keys[0]+ "\" key is unsupported";
00379                 } else {
00380                         error = "Transform Error: The ";
00381                         for(vector<string>::const_iterator cit = problem_keys.begin(); cit != problem_keys.end(); ++cit ) {
00382                                 if ( cit != problem_keys.begin() ) {
00383                                         if (cit == (problem_keys.end() -1) ) error += " and ";
00384                                         else error += ", ";
00385                                 }
00386                                 error += "\"";
00387                                 error += *cit;
00388                                 error += "\"";
00389                         }
00390                         error += " keys are unsupported";
00391                 }
00392                 throw InvalidParameterException(error);
00393         }
00394 }

float Transform::get_determinant (  )  const

Get the determinant of the matrix.

Returns:
the determinant

Definition at line 1153 of file transform.cpp.

References EMAN::Util::apply_precision(), ERR_LIMIT, and matrix.

Referenced by get_mirror(), get_scale(), get_scale_and_mirror(), and scale().

01154 {
01155         float det;
01156         double det2;
01157         det2  = matrix[0][0]*((double)matrix[1][1]*matrix[2][2]-(double)matrix[2][1]*matrix[1][2]);
01158         det2 -= matrix[0][1]*((double)matrix[1][0]*matrix[2][2]-(double)matrix[2][0]*matrix[1][2]);
01159         det2 += matrix[0][2]*((double)matrix[1][0]*matrix[2][1]-(double)matrix[2][0]*matrix[1][1]);
01160 
01161         det = (float)det2;
01162         Util::apply_precision(det,ERR_LIMIT);
01163 
01164         return det;
01165 }

Transform Transform::get_hflip_transform (  )  const

How do I get the transform that will yield the horizontally flipped projection?

Returns:
the transform that will yield the horizontally flipped projection

Definition at line 732 of file transform.cpp.

References get_rotation(), and get_trans().

00732                                                {
00733 
00734         Dict rot = get_rotation("eman");
00735         rot["alt"] = 180.0f + static_cast<float>(rot["alt"]);
00736         rot["phi"] = 180.0f - static_cast<float>(rot["phi"]);
00737 
00738         Transform ret(*this); // Is the identity
00739         ret.set_rotation(rot);
00740 
00741         Vec3f trans = get_trans();
00742         trans[0] = -trans[0];
00743         ret.set_trans(trans);
00744 
00745 //      ret.set_mirror(self.get_mirror());
00746 
00747         return ret;
00748 }

vector< float > Transform::get_matrix (  )  const

Get the transformation matrix using a vector.

Returns:
a vector - 3 rows of 4 - that stores the values of the transformation matrix

Definition at line 166 of file transform.cpp.

References matrix.

Referenced by rotate(), and rotate_origin().

00167 {
00168         vector<float> ret(12);
00169         for(int i=0; i<3; ++i) {
00170                 for(int j=0; j<4; ++j) {
00171                         ret[i*4+j] = matrix[i][j];
00172                 }
00173         }
00174         return ret;
00175 }

Vec3f EMAN::Transform::get_matrix3_row ( int  i  )  const [inline]

Get a matrix row as a Vec3f required for back compatibility with Tranform3D - see PawelProjector.

Parameters:
i the row number (starting at 0)
Returns:
the ith row

Definition at line 443 of file transform.h.

References matrix.

Referenced by EMAN::PawelProjector::project3d().

00443                                                                   {
00444                                 return Vec3f(matrix[i][0], matrix[i][1], matrix[i][2]);
00445                         }

vector< float > Transform::get_matrix_4x4 (  )  const

Get the 4x4 transformation matrix using a vector.

Returns:
a vector - 4 rows of 4 - that stores the values of the transformation matrix

Definition at line 177 of file transform.cpp.

References matrix.

00178 {
00179         vector<float> ret(16);
00180         for(int i=0; i<3; ++i) {
00181                 for(int j=0; j<4; ++j) {
00182                         ret[i*4+j] = matrix[i][j];
00183                 }
00184         }
00185         ret[12] = 0.0; 
00186         ret[13] = 0.0;
00187         ret[14] = 0.0;
00188         ret[15] = 1.0;
00189         
00190         return ret;
00191 }

bool Transform::get_mirror (  )  const

Query whether x_mirroring is occuring.

Returns:
whether x_mirroring is occuring

Definition at line 1124 of file transform.cpp.

References get_determinant().

Referenced by get_params(), get_params_inverse(), get_trans(), get_trans_2d(), EMAN::BackProjectionReconstructor::preprocess_slice(), EMAN::GaussFFTProjector::project3d(), set_mirror(), set_trans(), and translate().

01124                                  {
01125         float determinant = get_determinant();
01126 
01127         bool x_mirror = false;
01128         if ( determinant < 0 ) x_mirror = true;
01129 
01130         return x_mirror;
01131 
01132 }

int Transform::get_nsym ( const string &  sym  )  [static]

get the number of symmetries associated with the given symmetry name

Definition at line 1390 of file transform.cpp.

References EMAN::Symmetry3D::get_nsym().

Referenced by EMAN::PointArray::set_from(), EMAN::nnSSNR_ctfReconstructor::setup(), EMAN::nn4_ctf_rectReconstructor::setup(), EMAN::nn4_ctfReconstructor::setup(), EMAN::nnSSNR_Reconstructor::setup(), EMAN::nn4_rectReconstructor::setup(), EMAN::nn4Reconstructor::setup(), and EMAN::EMData::symvol().

01391 {
01392         Symmetry3D* sym = Factory<Symmetry3D>::get(sym_name);
01393         int nsym = sym->get_nsym();
01394         delete sym;
01395         return nsym;
01396 }

Dict Transform::get_params ( const string &  euler_type  )  const

Get the parameters of the entire transform, using a specific euler convention.

Parameters:
euler_type the euler type of the retrieved rotation
Returns:
a dictionary containing the parameters

Definition at line 450 of file transform.cpp.

References get_mirror(), get_rotation(), get_scale(), get_trans(), scale(), EMAN::Util::str_to_lower(), and v.

00450                                                          {
00451         Dict params = get_rotation(euler_type);
00452 
00453         Vec3f v = get_trans();
00454         params["tx"] = v[0]; params["ty"] = v[1];
00455 
00456         string type = Util::str_to_lower(euler_type);
00457         if ( type != "2d") params["tz"] = v[2];
00458 
00459         float scale = get_scale();
00460         params["scale"] = scale;
00461 
00462         bool mirror = get_mirror();
00463         params["mirror"] = mirror;
00464 
00465         return params;
00466 }

Dict Transform::get_params_inverse ( const string &  euler_type  )  const

Get the parameters of the inverse of the transform as though it were in RSMT order not MTSR.

Parameters:
euler_type the euler type of the retrieved rotation
Returns:
a dictionary containing the parameters

Definition at line 470 of file transform.cpp.

References get_mirror(), get_pre_trans(), get_rotation(), get_scale(), inverse(), scale(), EMAN::Util::str_to_lower(), and v.

00470                                                                  {
00471         Transform inv(inverse());
00472 
00473         Dict params = inv.get_rotation(euler_type);
00474         Vec3f v = inv.get_pre_trans();
00475         params["tx"] = v[0]; params["ty"] = v[1];
00476 
00477         string type = Util::str_to_lower(euler_type);
00478         if ( type != "2d") params["tz"] = v[2];
00479 
00480         float scale = inv.get_scale();
00481         params["scale"] = scale;
00482 
00483         bool mirror = inv.get_mirror();
00484         params["mirror"] = mirror;
00485 
00486         return params;
00487 }

Vec3f Transform::get_pre_trans (  )  const

Get the translation vector as though this object was MSRT_ not MTSR, where T_ is what you want Note M means post x mirror, T means translation, S means scale, and R means rotaiton.

Returns:
the pre translation vector

Definition at line 974 of file transform.cpp.

References get_trans(), invert(), and set_trans().

Referenced by get_params_inverse().

00975 {
00976         Transform T(*this);
00977         T.set_trans(0,0,0);
00978         T.invert();
00979 
00980         Transform soln  = T*(*this);
00981 //      soln.printme();
00982         return soln.get_trans();
00983 }

Vec2f Transform::get_pre_trans_2d (  )  const

2D version of getting the translation vector as though this object was MSRT_ not MTSR, where T_ is what you want Note M means post x mirror, T means translation, S means scale, and R means rotation

Returns:
the pre translation vector

Definition at line 985 of file transform.cpp.

References get_trans_2d(), invert(), and set_trans().

00986 {
00987         Transform T(*this);
00988         T.set_trans(0,0,0);
00989         T.invert();
00990 
00991         Transform soln  = T*(*this);
00992 //      soln.printme();
00993         return soln.get_trans_2d();
00994 }

Dict Transform::get_rotation ( const string &  euler_type = "eman"  )  const

Get a rotation in any Euler format.

Parameters:
euler_type the requested Euler type
Returns:
a dictionary containing the key-entry pairs describing the rotations in terms of the requested Euler type

Definition at line 766 of file transform.cpp.

References assert_valid_2d(), EMAN::EMConsts::deg2rad, get_scale_and_mirror(), InvalidStringException, matrix, phi, EMAN::EMConsts::rad2deg, scale(), sqrt(), EMAN::Util::str_to_lower(), and UnexpectedBehaviorException.

Referenced by EMAN::RotateTranslateAligner::align(), EMAN::RotationalAligner::align(), EMAN::PawelProjector::backproject3d(), EMAN::ChaoProjector::backproject3d(), get_hflip_transform(), get_params(), get_params_inverse(), get_sym_proj(), get_vflip_transform(), EMAN::FourierReconstructorSimple2D::insert_slice(), EMAN::ChaoProjector::project3d(), EMAN::FourierGriddingProjector::project3d(), and set_pre_trans().

00767 {
00768         Dict result;
00769 
00770         //float max = 1 - ERR_LIMIT;
00771         float scale;
00772         bool x_mirror;
00773         get_scale_and_mirror(scale,x_mirror);
00774         if (scale == 0) throw UnexpectedBehaviorException("The determinant of the Transform is 0. This is unexpected.");
00775 
00776         double cosalt = matrix[2][2]/scale;
00777         double x_mirror_scale = (x_mirror ? -1.0f : 1.0f);
00778         double inv_scale = 1.0f/scale;
00779 
00780         double az  = 0;
00781         double alt = 0;
00782         double phi = 0;
00783         double phiS = 0;  // like az  (but in SPIDER ZYZ)
00784         double psiS = 0;  // like phi (but in SPIDER ZYZ)
00785 
00786         // get alt, az, phi in EMAN convention
00787 
00788         if (cosalt >= 1) {  // that is, alt close to 0
00789                         alt = 0;
00790                         az = 0;
00791                         phi = (double)EMConsts::rad2deg * atan2(x_mirror_scale*matrix[0][1], x_mirror_scale*matrix[0][0]);
00792         } else if (cosalt <= -1) {  // that is, alt close to 180
00793                         alt = 180;
00794                         az = 0;
00795                         phi = (double)EMConsts::rad2deg * atan2(-x_mirror_scale*matrix[0][1], x_mirror_scale*matrix[0][0]);
00796         } else {   // for non exceptional cases:  0 < alt < 180
00797 
00798                 az  = (double)EMConsts::rad2deg * atan2(scale*matrix[2][0], -scale*matrix[2][1]);
00799 
00800                 if (matrix[2][2]==0.0)
00801                         alt = 90.0;
00802                 else
00803                         alt = (double)EMConsts::rad2deg * atan(sqrt((double)matrix[2][0]*matrix[2][0]+(double)matrix[2][1]*matrix[2][1])/fabs(matrix[2][2]));
00804 
00805                 if (matrix[2][2] * scale < 0)
00806                         alt = 180.0f-alt;
00807                 
00808                 phi = (double)EMConsts::rad2deg * atan2(x_mirror_scale*(double)matrix[0][2], (double)matrix[1][2]);
00809 
00810         } // ends separate cases: alt close to 0, 180, or neither
00811 
00812         phi = phi-360.0*floor(phi/360.0);
00813         az  = az -360.0*floor(az/360.0);
00814 
00815 //  get phiS, psiS (SPIDER)
00816         if (cosalt >= 1) {  // that is, alt close to 0
00817                 phiS = 0;
00818                 psiS = phi;
00819         } else if (cosalt <= -1) {  // that is, alt close to 180
00820                 phiS = 0;
00821                 psiS = phi + 180.0;
00822         } else {
00823                 phiS = az  - 90.0;
00824                 psiS = phi + 90.0;
00825         }
00826 
00827         phiS = phiS-360.0*floor(phiS/360.0);
00828         psiS = psiS-360.0*floor(psiS/360.0);
00829 
00830 //   do some quaternionic stuff here
00831 
00832         double nphi = (az-phi)/2.0;
00833     // The next is also e0
00834         double cosOover2 = cos((az+phi)*EMConsts::deg2rad/2.0) * cos(alt*EMConsts::deg2rad/2.0);
00835         double sinOover2 = sqrt(1 -cosOover2*cosOover2);
00836         double cosnTheta = sin((az+phi)*EMConsts::deg2rad/2.0) * cos(alt*EMConsts::deg2rad/2.0) / sqrt(1-cosOover2*cosOover2);
00837         double sinnTheta = sqrt(1-cosnTheta*cosnTheta);
00838         double n1 = sinnTheta*cos(nphi*EMConsts::deg2rad);
00839         double n2 = sinnTheta*sin(nphi*EMConsts::deg2rad);
00840         double n3 = cosnTheta;
00841         double xtilt = 0;
00842         double ytilt = 0;
00843         double ztilt = 0;
00844 
00845 
00846         if (cosOover2<0) {
00847                 cosOover2*=-1; n1 *=-1; n2*=-1; n3*=-1;
00848         }
00849 
00850         string type = Util::str_to_lower(euler_type);
00851 
00852         result["type"] = type;
00853         if (type == "2d") {
00854                 assert_valid_2d();
00855                 result["alpha"]  = phi;
00856         } else if (type == "eman") {
00857 //              assert_consistent_type(THREED);
00858                 result["az"]  = az;
00859                 result["alt"] = alt;
00860                 result["phi"] = phi;
00861         } else if (type == "imagic") {
00862 //              assert_consistent_type(THREED);
00863                 result["alpha"] = az;
00864                 result["beta"]  = alt;
00865                 result["gamma"] = phi;
00866         } else if (type == "spider") {
00867 //              assert_consistent_type(THREED);
00868                 result["phi"]   = phiS;  // The first Euler like az
00869                 result["theta"] = alt;
00870                 result["psi"]   = psiS;
00871         } else if (type == "mrc") {
00872 //              assert_consistent_type(THREED);
00873                 result["phi"]   = phiS;
00874                 result["theta"] = alt;
00875                 result["omega"] = psiS;
00876         } else if (type == "xyz") {               // need to double-check these 3 equations ********
00877 //              assert_consistent_type(THREED);
00878                 xtilt = atan2(-sin(EMConsts::deg2rad*phiS)*sin(EMConsts::deg2rad*alt),cos(EMConsts::deg2rad*alt));
00879                 ytilt = asin(  cos(EMConsts::deg2rad*phiS)*sin(EMConsts::deg2rad*alt));
00880                 ztilt = psiS*EMConsts::deg2rad - atan2(sin(xtilt), cos(xtilt) *sin(ytilt));
00881 
00882                 xtilt *= EMConsts::rad2deg; ytilt *= EMConsts::rad2deg; ztilt *= EMConsts::rad2deg;
00883                 xtilt = xtilt-360*.0*floor((xtilt+180.0)/360.0);
00884                 ytilt = ytilt-360*.0*floor((ytilt+180.0)/360.0);  //already in range [-90,90] but anyway...
00885                 ztilt = ztilt-360*.0*floor((ztilt+180.0)/360.0);
00886 
00887                 result["xtilt"]  = xtilt;
00888                 result["ytilt"]  = ytilt;
00889                 result["ztilt"]  = ztilt;
00890         } else if (type == "quaternion") {
00891 //              assert_consistent_type(THREED);
00892                 result["e0"] = cosOover2 ;
00893                 result["e1"] = sinOover2 * n1 ;
00894                 result["e2"] = sinOover2 * n2;
00895                 result["e3"] = sinOover2 * n3;
00896         } else if (type == "spin") {
00897 //              assert_consistent_type(THREED);
00898                 result["Omega"] = 2.0*EMConsts::rad2deg * acos(cosOover2);
00899                 result["n1"] = n1;
00900                 result["n2"] = n2;
00901                 result["n3"] = n3;
00902         } else if (type == "sgirot") {
00903 //              assert_consistent_type(THREED);
00904                 result["q"] = 2.0*EMConsts::rad2deg * acos(cosOover2);
00905                 result["n1"] = n1;
00906                 result["n2"] = n2;
00907                 result["n3"] = n3;
00908         } else if (type == "matrix") {
00909 //              assert_consistent_type(THREED);
00910                 result["m11"] = x_mirror_scale*matrix[0][0]*inv_scale;
00911                 result["m12"] = x_mirror_scale*matrix[0][1]*inv_scale;
00912                 result["m13"] = x_mirror_scale*matrix[0][2]*inv_scale;
00913                 result["m21"] = matrix[1][0]*inv_scale;
00914                 result["m22"] = matrix[1][1]*inv_scale;
00915                 result["m23"] = matrix[1][2]*inv_scale;
00916                 result["m31"] = matrix[2][0]*inv_scale;
00917                 result["m32"] = matrix[2][1]*inv_scale;
00918                 result["m33"] = matrix[2][2]*inv_scale;
00919         } else {
00920                 throw InvalidStringException(euler_type, "unknown Euler Type");
00921         }
00922 
00923         return result;
00924 }

Transform Transform::get_rotation_transform (  )  const

Get the rotation part of the tranformation matrix as a Transform object.

Returns:
a Transform describing the rotation only

Definition at line 653 of file transform.cpp.

References set_mirror(), set_scale(), and set_trans().

Referenced by EMAN::GaussFFTProjector::project3d().

00654 {
00655         Transform ret(*this);
00656         ret.set_scale(1.0);
00657         ret.set_mirror(false);
00658         ret.set_trans(0,0,0);
00659         //ret.orthogonalize(); // ?
00660         return ret;
00661 }

float Transform::get_scale (  )  const

Get the scale that was applied.

Returns:
the scale factor

Definition at line 1019 of file transform.cpp.

References EMAN::Util::apply_precision(), ERR_LIMIT, get_determinant(), and scale().

Referenced by get_params(), get_params_inverse(), EMAN::BackProjectionReconstructor::preprocess_slice(), EMAN::GaussFFTProjector::project3d(), set_pre_trans(), and set_scale().

01019                                  {
01020         float determinant = get_determinant();
01021         if (determinant < 0 ) determinant *= -1;
01022 
01023         float scale = std::pow(determinant,1.0f/3.0f);
01024         int int_scale = static_cast<int>(scale);
01025         float scale_residual = scale-static_cast<float>(int_scale);
01026         if  ( scale_residual < ERR_LIMIT ) { scale = static_cast<float>(int_scale); };
01027 
01028         Util::apply_precision(scale, ERR_LIMIT);
01029 
01030         return scale;
01031 }

void Transform::get_scale_and_mirror ( float &  scale,
bool &  x_mirror 
) const

Get scale and x_mirror with 1 function call.

More efficient than calling get_scale and get_x_mirror separately

Parameters:
scale a reference to the value that will be assigned the scale value
x_mirror a reference to the value that will be assigned the x_mirror value

Definition at line 1134 of file transform.cpp.

References EMAN::Util::apply_precision(), ERR_LIMIT, and get_determinant().

Referenced by get_rotation(), orthogonalize(), and set_rotation().

01134                                                                        {
01135 
01136         float determinant = get_determinant();
01137         x_mirror = false;
01138         if ( determinant < 0 ) {
01139                 x_mirror = true;
01140                 determinant *= -1;
01141         }
01142         if (determinant != 1 ) {
01143                 scale = std::pow(determinant,1.0f/3.0f);
01144                 int int_scale = static_cast<int>(scale);
01145                 float scale_residual = scale-static_cast<float>(int_scale);
01146                 if  ( scale_residual < ERR_LIMIT ) { scale = static_cast<float>(int_scale); };
01147         }
01148         else scale = 1;
01149 
01150         Util::apply_precision(scale,ERR_LIMIT);
01151 }

Transform Transform::get_sym ( const string &  sym,
int  n 
) const

Apply the symmetry deduced from the function arguments to this Transform and return the result.

Definition at line 1262 of file transform.cpp.

References EMAN::Symmetry3D::get_sym().

Referenced by EMAN::PointArray::set_from(), and EMAN::EMData::symvol().

01263 {
01264         Symmetry3D* sym = Factory<Symmetry3D>::get(sym_name);
01265         Transform ret;
01266         ret = (*this) * sym->get_sym(n);
01267         delete sym;
01268         return ret;
01269 }

vector< Transform > Transform::get_sym_proj ( const string &  sym  )  const

Definition at line 1271 of file transform.cpp.

References EMAN::EMConsts::deg2rad, EMAN::Symmetry3D::get_nsym(), get_rotation(), EMAN::Symmetry3D::get_sym(), matrix, and t.

01272 {
01273         vector<Transform> ret;
01274         Transform t;
01275         Symmetry3D* sym = Factory<Symmetry3D>::get(sym_name);
01276         int nsym = sym->get_nsym();
01277         int n = nsym;
01278         
01279         if ((sym_name[0] == 'c' || sym_name[0] == 'd' ) &&  fabs(matrix[2][2]) < 1.e-6){
01280                 
01281                 Dict d1,d2;                             
01282                 d2["theta"] = (double)90.0;
01283                 d2["psi"] = (double)0.0;
01284                 d2["phi"] = (double)0.0;
01285                 d2["type"] = "spider";
01286                 d1 = this->get_rotation("spider");
01287                 
01288                 if (sym_name[0] == 'c') {
01289                         if( nsym%2 == 0)        n = nsym/2;
01290                         
01291                         for (int k=0;k<n;k++) {                         
01292                                 d2["phi"] = (double)d1["phi"] + k*double(360.0)/ nsym;
01293                                 d2["psi"] = d1["psi"];
01294                                 t.set_rotation(d2);
01295                                 ret.push_back( t );
01296                         }
01297                                 
01298                 }
01299                 else {
01300                         nsym = nsym/2;
01301                         
01302                         if (nsym%2 == 0) {
01303                                 n = nsym;
01304                                 float cos_phi = cos( EMConsts::deg2rad*360.0/2/nsym );
01305                         
01306                                 for (int k=0;k<n;k++){
01307                                         
01308                                         if(k%2==0)      {
01309                                         
01310                                                 d2["phi"] = (double)d1["phi"] + k/2*double(360.0)/ nsym;
01311                                                 d2["psi"] = d1["psi"];
01312                                                 t.set_rotation(d2);
01313                                                 ret.push_back( t );     
01314                                         }
01315                                         else    {
01316                                                         
01317                                                 if( ( fabs(1.0-matrix[2][0])>1.0e-6 )&& fabs( matrix[2][0]-cos_phi)>1.0e-6  ){
01318                                                         //cout<<"jumped into"<<endl;
01319                                                         d2["phi"] = k/2*double(360.0)/ nsym +180 - (double)d1["phi"];
01320                                                         d2["psi"] = (double)d1["psi"] + 180;
01321                                                         t.set_rotation(d2);
01322                                                         ret.push_back( t );
01323                                                 }
01324                                         }
01325                                 
01326                                 }
01327                         }
01328                         
01329                         
01330                         
01331                         else    {
01332                                 n = nsym*2;
01333                                 float cos_phi = cos( EMConsts::deg2rad*360.0/4/nsym );
01334                                 for (int k=0;k<n;k++){
01335                                         
01336                                         if(k%4==0)      {
01337                                         
01338                                                 d2["phi"] = (double)d1["phi"] + k/4*360.0/ nsym;
01339                                                 d2["psi"] = (double)d1["psi"];
01340                                                 t.set_rotation(d2);
01341                                                 ret.push_back( t );     
01342                                         }
01343                                         else if( k%4 ==1)       {
01344                                                 if( ( fabs(1.0-matrix[2][0])>1.0e-6 )&& fabs( matrix[2][0]-cos_phi)>1.0e-6  ){
01345                                                 
01346                                                         d2["phi"] = k/4*360.0/nsym + 360.0/2/nsym+180 - (double)d1["phi"];
01347                                                         d2["psi"] = (double)d1["psi"] + 180;
01348                                                         t.set_rotation(d2);
01349                                                         ret.push_back( t );
01350                                                 }
01351                                 
01352                                         }
01353                                         
01354                                         else if( k%4 ==2)       {
01355                                         
01356                                                 d2["phi"] =  k/4*360.0/ nsym+360.0/2/nsym+180 + (double)d1["phi"];
01357                                                 d2["psi"] = (double)d1["psi"];
01358                                                 t.set_rotation(d2);
01359                                                 ret.push_back( t );
01360                                 
01361                                         }
01362                                         
01363                                         else if( k%4 ==3)       {
01364                                                 if( ( fabs(1.0-matrix[2][0])>1.0e-6 )&& fabs( matrix[2][0]-cos_phi)>1.0e-6  ) {
01365                                                         d2["phi"] = k/4*360.0/nsym+ 2.0*360.0/2/nsym - (double)d1["phi"];
01366                                                         d2["psi"] = (double)d1["psi"] + 180;
01367                                                         t.set_rotation(d2);
01368                                                         ret.push_back( t );
01369                                                 }
01370                                         }
01371                                 
01372                                 }
01373                         }
01374                         
01375                 }
01376                 
01377         }
01378         else {
01379                 for (int k=0;k<nsym;k++) {
01380                         t =  sym->get_sym(k);
01381                         ret.push_back( (*this) * t );
01382                 }
01383                 
01384         }
01385         delete sym;
01386         return ret;
01387 }

Vec3f Transform::get_trans (  )  const

Get the post trans as a vec3f.

Returns:
the translation vector

Definition at line 936 of file transform.cpp.

References EMAN::Util::apply_precision(), ERR_LIMIT, get_mirror(), matrix, and v.

Referenced by get_hflip_transform(), get_params(), get_pre_trans(), get_vflip_transform(), EMAN::GaussFFTProjector::project3d(), EMAN::EMData::rot_scale_trans(), EMAN::EMData::rot_scale_trans_background(), and set_params_inverse().

00937 {
00938         // No type asserted
00939         bool x_mirror = get_mirror();
00940         Vec3f v;
00941         if (x_mirror) v[0] = -matrix[0][3];
00942         else v[0] = matrix[0][3];
00943         v[1] = matrix[1][3];
00944         v[2] = matrix[2][3];
00945 
00946         Util::apply_precision(v[0],ERR_LIMIT);
00947         Util::apply_precision(v[1],ERR_LIMIT);
00948         Util::apply_precision(v[2],ERR_LIMIT);
00949 
00950         return v;
00951 }

Vec2f Transform::get_trans_2d (  )  const

Get the degenerant 2D post trans as a vec2f.

Returns:
the 2D translation vector

Definition at line 962 of file transform.cpp.

References get_mirror(), matrix, and v.

Referenced by get_pre_trans_2d(), and EMAN::BackProjectionReconstructor::preprocess_slice().

00963 {
00964         bool x_mirror = get_mirror();
00965         Vec2f v;
00966         if (x_mirror) v[0] = -matrix[0][3];
00967         else v[0] = matrix[0][3];
00968         v[1] = matrix[1][3];
00969         return v;
00970 }

Transform Transform::get_vflip_transform (  )  const

How do I get the transform that will yield the vertically flipped projection?

Returns:
the transform that will yield the vertically flipped projection

Definition at line 750 of file transform.cpp.

References get_rotation(), and get_trans().

00750                                                {
00751 
00752         Dict rot = get_rotation("eman");
00753         rot["alt"] = 180.0f + static_cast<float>(rot["alt"]);
00754         rot["phi"] = - static_cast<float>(rot["phi"]);
00755 
00756         Transform ret(*this);
00757         ret.set_rotation(rot);
00758 
00759         Vec3f trans = get_trans();
00760         trans[1] = -trans[1];
00761         ret.set_trans(trans);
00762 
00763         return ret;
00764 }

Transform Transform::icos_5_to_2 (  )  [static]

Get the transform that moves any icosahedron generated by eman2 so that it matches the 2-2-2 (MRC, FREALIGN) convention.

Returns:
a Transforms, alt=58.282523, az=270

Doctor Phil says: alt = (acos(cos(pi/5)/sqrt(3)/sin(pi/5)) + acos(2*cos(pi/5)/ sqrt(3) ) )*180/pi This is the angle between a 5 and a 3 plus the angle between a 3 and a 2

Definition at line 67 of file transform.cpp.

References t.

00067                                  {
00068         Transform t;
00069         Dict d;
00070         d["type"] = "eman";
00071         d["phi"] = 0.0f;
00072         d["az"] = 270.0f;
00073         d["alt"] = 58.282523f; // 5 fold to a 3 fold to a 2 fold
00079         t.set_rotation(d);
00080         return t;
00081 }

void Transform::init_permissable_keys (  )  [private]

Called internally to initialize permissable_2d_not_rot, permissable_3d_not_rot, and permissable_rot_keys static members.

Definition at line 255 of file transform.cpp.

References permissable_2d_not_rot, permissable_3d_not_rot, and permissable_rot_keys.

Referenced by detect_problem_keys().

00256 {
00257 
00258         permissable_2d_not_rot.push_back("tx");
00259         permissable_2d_not_rot.push_back("ty");
00260         permissable_2d_not_rot.push_back("scale");
00261         permissable_2d_not_rot.push_back("mirror");
00262         permissable_2d_not_rot.push_back("type");
00263 
00264         permissable_3d_not_rot.push_back("tx");
00265         permissable_3d_not_rot.push_back("ty");
00266         permissable_3d_not_rot.push_back("tz");
00267         permissable_3d_not_rot.push_back("scale");
00268         permissable_3d_not_rot.push_back("mirror");
00269         permissable_3d_not_rot.push_back("type");
00270 
00271         vector<string> tmp;
00272         tmp.push_back("alpha");
00273         permissable_rot_keys["2d"] = tmp;
00274 
00275         tmp.clear();
00276         tmp.push_back("alt");
00277         tmp.push_back("az");
00278         tmp.push_back("phi");
00279         permissable_rot_keys["eman"] = tmp;
00280 
00281         tmp.clear();
00282         tmp.push_back("psi");
00283         tmp.push_back("theta");
00284         tmp.push_back("phi");
00285         permissable_rot_keys["spider"] = tmp;
00286 
00287         tmp.clear();
00288         tmp.push_back("alpha");
00289         tmp.push_back("beta");
00290         tmp.push_back("gamma");
00291         permissable_rot_keys["imagic"] = tmp;
00292 
00293         tmp.clear();
00294         tmp.push_back("ztilt");
00295         tmp.push_back("xtilt");
00296         tmp.push_back("ytilt");
00297         permissable_rot_keys["xyz"] = tmp;
00298 
00299         tmp.clear();
00300         tmp.push_back("phi");
00301         tmp.push_back("theta");
00302         tmp.push_back("omega");
00303         permissable_rot_keys["mrc"] = tmp;
00304 
00305         tmp.clear();
00306         tmp.push_back("e0");
00307         tmp.push_back("e1");
00308         tmp.push_back("e2");
00309         tmp.push_back("e3");
00310         permissable_rot_keys["quaternion"] = tmp;
00311 
00312         tmp.clear();
00313         tmp.push_back("n1");
00314         tmp.push_back("n2");
00315         tmp.push_back("n3");
00316         tmp.push_back("Omega");
00317         permissable_rot_keys["spin"] = tmp;
00318 
00319         tmp.clear();
00320         tmp.push_back("n1");
00321         tmp.push_back("n2");
00322         tmp.push_back("n3");
00323         tmp.push_back("q");
00324         permissable_rot_keys["sgirot"] = tmp;
00325 
00326         tmp.clear();
00327         tmp.push_back("m11");
00328         tmp.push_back("m12");
00329         tmp.push_back("m13");
00330         tmp.push_back("m21");
00331         tmp.push_back("m22");
00332         tmp.push_back("m23");
00333         tmp.push_back("m31");
00334         tmp.push_back("m32");
00335         tmp.push_back("m33");
00336         permissable_rot_keys["matrix"] = tmp;
00337 }

Transform Transform::inverse (  )  const

Get the inverse of this transformation matrix.

Returns:
the inverse of this transformation matrix

Definition at line 1201 of file transform.cpp.

References t.

Referenced by get_params_inverse(), EMAN::EMData::max_3D_pixel_error(), EMAN::StandardProjector::project3d(), EMAN::EMData::rot_scale_trans(), and EMAN::EMData::rot_scale_trans_background().

01201                                    {
01202         Transform t(*this);
01203         t.invert();
01204         return t;
01205 }

void Transform::invert (  ) 

Get the inverse of this transformation matrix.

Returns:
the inverse of this transformation matrix

Definition at line 1167 of file transform.cpp.

References matrix, and v0.

Referenced by EMAN::EMData::extract_plane(), EMAN::EMData::extract_plane_rect(), EMAN::EMData::extract_plane_rect_fast(), get_pre_trans(), get_pre_trans_2d(), EMAN::Symmetry3D::in_which_asym_unit(), EMAN::BackProjectionReconstructor::insert_slice(), EMAN::GaussFFTProjector::project3d(), EMAN::Symmetry3D::reduce(), set_params_inverse(), and set_pre_trans().

01167                        {
01168 
01169         double m00 = matrix[0][0]; double m01=matrix[0][1]; double m02=matrix[0][2];
01170         double m10 = matrix[1][0]; double m11=matrix[1][1]; double m12=matrix[1][2];
01171         double m20 = matrix[2][0]; double m21=matrix[2][1]; double m22=matrix[2][2];
01172         double v0  = matrix[0][3]; double v1 =matrix[1][3]; double v2 =matrix[2][3];
01173 
01174         double cof00 = m11*m22-m12*m21;
01175         double cof11 = m22*m00-m20*m02;
01176         double cof22 = m00*m11-m01*m10;
01177         double cof01 = m10*m22-m20*m12;
01178         double cof02 = m10*m21-m20*m11;
01179         double cof12 = m00*m21-m01*m20;
01180         double cof10 = m01*m22-m02*m21;
01181         double cof20 = m01*m12-m02*m11;
01182         double cof21 = m00*m12-m10*m02;
01183 
01184         double det = m00* cof00 + m02* cof02 -m01*cof01;
01185 
01186         matrix[0][0] =   (float)(cof00/det);
01187         matrix[0][1] = - (float)(cof10/det);
01188         matrix[0][2] =   (float)(cof20/det);
01189         matrix[1][0] = - (float)(cof01/det);
01190         matrix[1][1] =   (float)(cof11/det);
01191         matrix[1][2] = - (float)(cof21/det);
01192         matrix[2][0] =   (float)(cof02/det);
01193         matrix[2][1] = - (float)(cof12/det);
01194         matrix[2][2] =   (float)(cof22/det);
01195 
01196         matrix[0][3] =  (float)((- cof00*v0 + cof10*v1 - cof20*v2)/det);
01197         matrix[1][3] =  (float)((  cof01*v0 - cof11*v1 + cof21*v2)/det);
01198         matrix[2][3] =  (float)((- cof02*v0 + cof12*v1 - cof22*v2)/det);
01199 }

bool Transform::is_identity (  )  const

Returns whethers or this matrix is the identity.

Definition at line 207 of file transform.cpp.

References EMAN::Util::apply_precision(), ERR_LIMIT, and matrix.

Referenced by EMAN::TestTomoImage::insert_rectangle(), and EMAN::FourierReconstructor::preprocess_slice().

00207                                   {
00208         for(int i=0; i<3; ++i) {
00209                 for(int j=0; j<4; ++j) {
00210                         float c = matrix[i][j];
00211                         Util::apply_precision(c,ERR_LIMIT);
00212                         if(i==j) {
00213                                 if (c != 1.0) return false;
00214                         }
00215                         else {
00216                                 if (c != 0.0) return false;
00217                         }
00218                 }
00219         }
00220         return true;
00221 }

Transform Transform::negate (  )  const

Negates the Transform - a useful way, for example, for getting an orientation on the opposite side of the sphere.

Returns:
a transform that has been negated

Definition at line 721 of file transform.cpp.

References t.

00722 {
00723         Transform t(*this);
00724         for(unsigned int i = 0; i < 3; ++i) {
00725                 for(unsigned int j = 0; j < 4; ++j) {
00726                         t.set(i,j,t[i][j]*-1);
00727                 }
00728         }
00729         return t;
00730 }

bool Transform::operator!= ( const Transform rhs  )  const

Unequality comparision operator.

Parameters:
rhs the Transform object compared to
Returns:
a boolean indicate if the pass in transform is not equal this object

Definition at line 125 of file transform.cpp.

References operator==(), and rhs.

00125                                                     {
00126         return !(operator==(rhs));
00127 }

Transform & Transform::operator= ( const Transform that  ) 

Assignment operator.

Parameters:
that that which this will become

Definition at line 108 of file transform.cpp.

References matrix.

00108                                                       {
00109         if (this != &that ) {
00110                 memcpy(matrix,that.matrix,12*sizeof(float));
00111 //              transform_type = that.transform_type;
00112         }
00113         return *this;
00114 }

bool Transform::operator== ( const Transform rhs  )  const

Equality comparision operator.

Parameters:
rhs the Transform object compared to
Returns:
a boolean indicate if the pass in transform is equal this object

Definition at line 116 of file transform.cpp.

References rhs.

Referenced by operator!=().

00116                                                     {
00117         if (memcmp(this->matrix, rhs.matrix, 3*4*sizeof(float)) == 0) {
00118                 return true;
00119         }
00120         else {
00121                 return false;
00122         }
00123 }

const float* EMAN::Transform::operator[] ( int  i  )  const [inline]

Operator[] convenience so Transform3D[2][2] etc terminology can be used.

Definition at line 388 of file transform.h.

References matrix.

00388 { return matrix[i]; }

float* EMAN::Transform::operator[] ( int  i  )  [inline]

Operator[] convenience so Transform3D[2][2] etc terminology can be used.

Definition at line 383 of file transform.h.

References matrix.

00383 { return matrix[i]; }

void Transform::orthogonalize (  ) 

Reorthogonalize the rotation part of the matrix in place.

Does this by performing the SVD decomposition of the rotation matrix R such that R = USV^T - since the eigenvalues of a rotation matrix are all 1 we enforce that S should be the identity and produce a corrected matrix R' = UV^T

Definition at line 1053 of file transform.cpp.

References get_scale_and_mirror(), matrix, R, scale(), UnexpectedBehaviorException, and V.

01054 {
01055         float scale;
01056         bool x_mirror;
01057         get_scale_and_mirror(scale,x_mirror);
01058         if (scale == 0) throw UnexpectedBehaviorException("The determinant of the Transform is 0. This is unexpected.");
01059         double inv_scale = 1.0/static_cast<double>(scale);
01060         double mirror_scale = (x_mirror == true ? -1.0:1.0);
01061 
01062         gsl_matrix * R = gsl_matrix_calloc(3,3);
01063         for ( unsigned int i = 0; i < 3; ++i )
01064         {
01065                 for ( unsigned int j = 0; j < 3; ++j )
01066                 {
01067                         if (i == 0 && mirror_scale != 1.0 ) {
01068                                 gsl_matrix_set( R, i, j, static_cast<double>(matrix[i][j])*mirror_scale*inv_scale );
01069                         }
01070                         else {
01071                                 gsl_matrix_set( R, i, j, static_cast<double>(matrix[i][j])*inv_scale );
01072                         }
01073                 }
01074         }
01075 
01076         gsl_matrix * V = gsl_matrix_calloc(3,3);
01077         gsl_vector * S = gsl_vector_calloc(3);
01078         gsl_vector * work = gsl_vector_calloc(3);
01079         gsl_linalg_SV_decomp (R, V, S, work); // Now R is U of the SVD R = USV^T
01080 
01081         gsl_matrix * Soln = gsl_matrix_calloc(3,3);
01082         gsl_blas_dgemm (CblasNoTrans, CblasTrans, 1.0, R, V, 0.0, Soln);
01083 
01084         for ( unsigned int i = 0; i < 3; ++i )
01085         {
01086                 for ( unsigned int j = 0; j < 3; ++j )
01087                 {
01088                         matrix[i][j] = static_cast<float>( gsl_matrix_get(Soln,i,j) );
01089                 }
01090         }
01091 
01092         // Apply scale if it existed previously
01093         if (scale != 1.0f) {
01094                 for(int i=0; i<3; ++i) {
01095                         for(int j=0; j<3; ++j) {
01096                                 matrix[i][j] *= scale;
01097                         }
01098                 }
01099         }
01100 
01101         // Apply post x mirroring if it was applied previouslys
01102         if ( x_mirror ) {
01103                 for(int j=0; j<3; ++j) {
01104                         matrix[0][j] *= -1.0f;
01105                 }
01106         }
01107 
01108         gsl_matrix_free(V); gsl_matrix_free(R); gsl_matrix_free(Soln);
01109         gsl_vector_free(S); gsl_vector_free(work);
01110 }

void EMAN::Transform::printme (  )  const [inline]

Print the contents of the internal matrix verbatim to standard out.

Definition at line 329 of file transform.h.

References matrix.

00329                                              {
00330                                 printf("%8.6f %8.6f %8.6f %8.6f\n",matrix[0][0],matrix[0][1],matrix[0][2],matrix[0][3]);
00331                                 printf("%8.6f %8.6f %8.6f %8.6f\n",matrix[1][0],matrix[1][1],matrix[1][2],matrix[1][3]);
00332                                 printf("%8.6f %8.6f %8.6f %8.6f\n",matrix[2][0],matrix[2][1],matrix[2][2],matrix[2][3]);
00333                                 printf("%8.6f %8.6f %8.6f %8.6f\n",0.0,0.0,0.0,1.0);
00334 
00335                         }

void Transform::rotate ( const Transform by  ) 

Increment the rotation by multipling the rotation bit of the argument transfrom by the current transfrom.

Parameters:
rotation multiplican, a tranform, R'', by which to multiply the current one, R' == R''R'

Definition at line 703 of file transform.cpp.

References get_matrix(), and matrix.

00704 {
00705         vector<float> multmatrix = by.get_matrix();
00706         // First Multiply and put the result in a temp matrix
00707         Transform result;
00708         for (int i=0; i<3; i++) {
00709                 for (int j=0; j<4; j++) {
00710                         result[i][j] = multmatrix[i*4]*matrix[0][j] +  multmatrix[i*4+1]*matrix[1][j] + multmatrix[i*4+2]*matrix[2][j];
00711                 }
00712         }
00713         //Then put the result from the tmep matrix in the original one
00714         for (int i=0; i<3; i++) {
00715                 for (int j=0; j<4; j++) {
00716                         matrix[i][j] = result[i][j];
00717                 }
00718         }
00719 }

void Transform::rotate_origin ( const Transform by  ) 

Increment the rotation by multipling the rotation bit of the argument transfrom by the rotation part of the current transfrom.

Parameters:
rotation multiplican, a tranform, R'', by which to multiply the current one, R' == R''R'

Definition at line 685 of file transform.cpp.

References get_matrix(), and matrix.

00686 {
00687         vector<float> multmatrix = by.get_matrix();
00688         // First Multiply and put the result in a temp matrix
00689         Transform result;
00690         for (int i=0; i<3; i++) {
00691                 for (int j=0; j<3; j++) {
00692                         result[i][j] = multmatrix[i*4]*matrix[0][j] +  multmatrix[i*4+1]*matrix[1][j] + multmatrix[i*4+2]*matrix[2][j];
00693                 }
00694         }
00695         //Then put the result from the tmep matrix in the original one
00696         for (int i=0; i<3; i++) {
00697                 for (int j=0; j<3; j++) {
00698                         matrix[i][j] = result[i][j];
00699                 }
00700         }
00701 }

void Transform::scale ( const float &  scale  ) 

Increment the scale.

Parameters:
scale the amount increment by

Definition at line 1033 of file transform.cpp.

References get_determinant(), and set_scale().

Referenced by get_params(), get_params_inverse(), get_rotation(), get_scale(), orthogonalize(), set_params(), set_params_inverse(), set_pre_trans(), and set_rotation().

01034 {
01035         float determinant = get_determinant();
01036         if (determinant < 0) determinant *= -1.0f;
01037         float newscale = std::pow(determinant,1.0f/3.0f) + scale;
01038         if(newscale > 0.0001) set_scale(newscale); // If scale ~ 0 things blowup, so we need a little fudge factor
01039 }

void EMAN::Transform::set ( int  r,
int  c,
float  value 
) [inline]

Set the value stored in the internal transformation matrix at at coordinate (r,c) to value.

Definition at line 378 of file transform.h.

References matrix.

Referenced by EMAN::PointArray::align_2d().

00378 { matrix[r][c] = value; }

void Transform::set_matrix ( const vector< float > &  v  ) 

Set the transformation matrix using a vector.

Must be of length 12.

Parameters:
v the transformation matrix stored as a vector - 3 rows of 4.

Definition at line 144 of file transform.cpp.

References InvalidParameterException, and matrix.

Referenced by EMAN::EMObject::operator Transform *(), and Transform().

00145 {
00146         if (v.size() != 12 ) throw InvalidParameterException("The construction array must be of size 12");
00147 
00148         for(int i=0; i<3; ++i) {
00149                 for(int j=0; j<4; ++j) {
00150                         matrix[i][j] = v[i*4+j];
00151                 }
00152         }
00153 }

void Transform::set_mirror ( const bool  x_mirror  ) 

Set whether or not x_mirroring is occuring.

Parameters:
x_mirror whether x_mirroring should be applied

Definition at line 1112 of file transform.cpp.

References get_mirror(), and matrix.

Referenced by EMAN::RefineAligner::align(), EMAN::WienerFourierReconstructor::determine_slice_agreement(), EMAN::FourierReconstructor::determine_slice_agreement(), get_rotation_transform(), EMAN::BackProjectionReconstructor::insert_slice(), EMAN::WienerFourierReconstructor::insert_slice(), EMAN::FourierReconstructor::insert_slice(), set_params(), and set_params_inverse().

01112                                                {
01113 
01114         bool old_x_mirror = get_mirror();
01115         if (old_x_mirror == x_mirror) return; // The user is setting the same value
01116         else {
01117                 // Toggle the mirroring operation
01118                 for (int j = 0; j < 4; ++j ) {
01119                         matrix[0][j] *= -1;
01120                 }
01121         }
01122 }

void Transform::set_params ( const Dict d  ) 

Set the parameters of the entire transform.

keys acted upon are "type" - if this exists then the correct euler angles need to be included - also "tx","ty","tz", "scale", and "mirror"

Parameters:
d the dictionary containing the parameters

Definition at line 224 of file transform.cpp.

References EMAN::EMObject::BOOL, detect_problem_keys(), EMAN::Dict::get_ci(), EMAN::Dict::has_key_ci(), EMAN::EMObject::INT, InvalidParameterException, scale(), set_mirror(), set_rotation(), set_scale(), set_trans(), and EMAN::EMObject::UNSIGNEDINT.

Referenced by Transform().

00224                                         {
00225         detect_problem_keys(d);
00226 
00227         if (d.has_key_ci("type") ) set_rotation(d);
00228 
00229         if (d.has_key_ci("scale")) {
00230                 float scale = static_cast<float>(d.get_ci("scale"));
00231                 set_scale(scale);
00232         }
00233 
00234         float dx=0,dy=0,dz=0;
00235 
00236         if (d.has_key_ci("tx")) dx = static_cast<float>(d.get_ci("tx"));
00237         if (d.has_key_ci("ty")) dy = static_cast<float>(d.get_ci("ty"));
00238         if (d.has_key_ci("tz")) dz = static_cast<float>(d.get_ci("tz"));
00239 
00240         if ( dx != 0.0 || dy != 0.0 || dz != 0.0 ) {
00241                 set_trans(dx,dy,dz);
00242         }
00243 
00244         if (d.has_key_ci("mirror")) {
00245                 EMObject e = d.get_ci("mirror");
00246                 if ( (e.get_type() != EMObject::BOOL ) && (e.get_type() != EMObject::INT ) && (e.get_type() != EMObject::UNSIGNEDINT ) )
00247                         throw InvalidParameterException("Error, mirror must be a bool or an int");
00248 
00249                 bool mirror = static_cast<bool>(e);
00250                 set_mirror(mirror);
00251         }
00252 }

void Transform::set_params_inverse ( const Dict d  ) 

Set the parameters of the entire transform as though they there in the inverse format.

in other words, calling set_params_inverse(get_params_inverse()) should essentially leave the object unchanged.

Parameters:
d the dictionary containing the inverse parameters

Definition at line 396 of file transform.cpp.

References EMAN::EMObject::BOOL, detect_problem_keys(), EMAN::Dict::get_ci(), get_trans(), EMAN::Dict::has_key_ci(), EMAN::EMObject::INT, InvalidParameterException, invert(), scale(), set_mirror(), set_rotation(), set_scale(), set_trans(), Transform(), and EMAN::EMObject::UNSIGNEDINT.

00396                                                 {
00397         detect_problem_keys(d);
00398 
00399         if (d.has_key_ci("type") ) set_rotation(d);
00400 
00401         float dx=0,dy=0,dz=0;
00402         if (d.has_key_ci("tx")) dx = static_cast<float>(d.get_ci("tx"));
00403         if (d.has_key_ci("ty")) dy = static_cast<float>(d.get_ci("ty"));
00404         if (d.has_key_ci("tz")) dz = static_cast<float>(d.get_ci("tz"));
00405 
00406         if ( (dx != 0.0 || dy != 0.0 || dz != 0.0) && d.has_key_ci("type") ) {
00407                 Transform pre_trans;
00408                 pre_trans.set_trans(dx,dy,dz);
00409 
00410                 Transform tmp;
00411                 tmp.set_rotation(d);
00412 
00413                 if (d.has_key_ci("scale")) {
00414                         float scale = static_cast<float>(d.get_ci("scale"));
00415                         tmp.set_scale(scale);
00416                 }
00417 
00418                 Transform solution_trans = tmp*pre_trans;
00419 
00420                 if (d.has_key_ci("scale")) {
00421                         Transform tmp;
00422                         float scale = static_cast<float>(d.get_ci("scale"));
00423                         tmp.set_scale(scale);
00424                         solution_trans = solution_trans*tmp;
00425                 }
00426 
00427                 tmp = Transform();
00428                 tmp.set_rotation(d);
00429                 solution_trans = solution_trans*tmp;
00430                 set_trans(solution_trans.get_trans());
00431         }
00432 
00433         if (d.has_key_ci("scale")) {
00434                 float scale = static_cast<float>(d.get_ci("scale"));
00435                 set_scale(scale);
00436         }
00437 
00438         if (d.has_key_ci("mirror")) {
00439                 EMObject e = d.get_ci("mirror");
00440                 if ( (e.get_type() != EMObject::BOOL ) && (e.get_type() != EMObject::INT ) && (e.get_type() != EMObject::UNSIGNEDINT ) )
00441                         throw InvalidParameterException("Error, mirror must be a bool or an int");
00442 
00443                 bool mirror = static_cast<bool>(e);
00444                 set_mirror(mirror);
00445         }
00446         invert();
00447 }

template<typename type>
void EMAN::Transform::set_pre_trans ( const type &  v  ) 

Set the translational component of the matrix as though it was MSRT_ not MTSR, where T_ is the pre translation.

Internally the correct form of MTSR is computed.

Parameters:
v the vector (Vec3f or Vec2f) that is the pre trans

Definition at line 532 of file transform.h.

References get_rotation(), get_scale(), invert(), scale(), set_rotation(), set_scale(), and set_trans().

Referenced by EMAN::PointArray::align_2d().

00532                                                    {
00533 
00534                 Transform tmp;
00535                 Dict rot = get_rotation("eman");
00536                 tmp.set_rotation(rot);
00537 
00538                 float scale = get_scale();
00539                 if (scale != 1.0 ) tmp.set_scale(scale);
00540 
00541                 Transform trans;
00542                 trans.set_trans(v);
00543 
00544                 trans = tmp*trans;
00545 
00546                 Transform tmp2;
00547                 tmp2.set_rotation(rot);
00548                 tmp2.invert(); // invert
00549                 if (scale != 1.0 ) tmp2.set_scale(1.0f/scale);
00550 
00551 
00552                 trans = trans*tmp2;
00553 
00554                 set_trans(trans.get_trans());
00555         }

void Transform::set_rotation ( const Vec3f v  ) 

Determine the rotation that would transform a vector pointing in the Z direction so that it points in the direction of the argument vector Automatically normalizes the vector.

Parameters:
v the direction you want to solve for

Definition at line 663 of file transform.cpp.

References EMAN::Vec3< Type >::normalize(), EMAN::EMConsts::rad2deg, set_rotation(), theta, UnexpectedBehaviorException, and v.

00664 {
00665         if ( v[0] == 0 && v[1] == 0 && v[2] == 0 )
00666                 throw UnexpectedBehaviorException("Can't set rotation for the null vector");
00667 
00668         Vec3f v1(v);
00669         v1.normalize();
00670 
00671         double theta = acos(v1[2]); // in radians
00672         double psi = atan2(v1[1],-v1[0]);
00673 
00674         Dict d;
00675         d["theta"] = (double)EMConsts::rad2deg*theta;
00676         d["psi"] = (double)EMConsts::rad2deg*psi;
00677         d["phi"] = (double)0.0;
00678         d["type"] = "spider";
00679 
00680         set_rotation(d);
00681 
00682 
00683 }

void Transform::set_rotation ( const Dict rotation  ) 

Set a rotation using a specific Euler type and the dictionary interface Works for all Euler types.

Parameters:
rotation a dictionary containing all key-entry pair required of the associated Euler type

Definition at line 490 of file transform.cpp.

References assert_valid_2d(), EMAN::EMConsts::deg2rad, detect_problem_keys(), EMAN::Dict::get_ci(), get_scale_and_mirror(), EMAN::Dict::has_key_ci(), InvalidParameterException, InvalidStringException, matrix, phi, scale(), EMAN::Util::str_to_lower(), and UnexpectedBehaviorException.

Referenced by EMAN::RotatePrecenterAligner::align(), EMAN::BackProjectionReconstructor::preprocess_slice(), EMAN::FourierReconstructor::preprocess_slice(), set_params(), set_params_inverse(), set_pre_trans(), and set_rotation().

00491 {
00492         detect_problem_keys(rotation);
00493         string euler_type;
00494 
00495         if (!rotation.has_key_ci("type") ){
00496                         throw InvalidParameterException("argument dictionary does not contain the type key");
00497         }
00498 
00499         euler_type = static_cast<string>(rotation.get_ci("type"));// Warning, will throw
00500 
00501 
00502         double e0=0; double e1=0; double e2=0; double e3=0;
00503         double Omega=0;
00504         double az  = 0;
00505         double alt = 0;
00506         double phi = 0;
00507         double cxtilt = 0;
00508         double sxtilt = 0;
00509         double cytilt = 0;
00510         double sytilt = 0;
00511         double cztilt = 0;
00512         double sztilt = 0;
00513         bool is_quaternion = 0;
00514         bool is_matrix = 0;
00515         bool is_xyz = 0;
00516 
00517         bool x_mirror;
00518         float scale;
00519         // Get these before anything changes so we can apply them again after the rotation is set
00520         get_scale_and_mirror(scale,x_mirror);
00521         if (scale == 0) throw UnexpectedBehaviorException("The determinant of the Transform is 0. This is unexpected.");
00522 
00523         string type = Util::str_to_lower(euler_type);
00524         if (type == "2d") {
00525                 assert_valid_2d();
00526                 az  = 0;
00527                 alt = 0;
00528                 phi = (double)rotation["alpha"] ;
00529         } else if ( type == "eman" ) {
00530 //              validate_and_set_type(THREED);
00531                 az  = (double)rotation["az"] ;
00532                 alt = (double)rotation["alt"]  ;
00533                 phi = (double)rotation["phi"] ;
00534         } else if ( type == "imagic" ) {
00535 //              validate_and_set_type(THREED);
00536                 az  = (double)rotation["alpha"] ;
00537                 alt = (double)rotation["beta"]  ;
00538                 phi = (double)rotation["gamma"] ;
00539         } else if ( type == "spider" ) {
00540 //              validate_and_set_type(THREED);
00541                 az =  (double)rotation["phi"]    + 90.0;
00542                 alt = (double)rotation["theta"] ;
00543                 phi = (double)rotation["psi"]    - 90.0;
00544         } else if ( type == "xyz" ) {
00545 //              validate_and_set_type(THREED);
00546                 is_xyz = 1;
00547                 cxtilt = cos(EMConsts::deg2rad*(double)rotation["xtilt"]);
00548                 sxtilt = sin(EMConsts::deg2rad*(double)rotation["xtilt"]);
00549                 cytilt = cos(EMConsts::deg2rad*(double)rotation["ytilt"]);
00550                 sytilt = sin(EMConsts::deg2rad*(double)rotation["ytilt"]);
00551                 cztilt = cos(EMConsts::deg2rad*(double)rotation["ztilt"]);
00552                 sztilt = sin(EMConsts::deg2rad*(double)rotation["ztilt"]);
00553         } else if ( type == "mrc" ) {
00554 //              validate_and_set_type(THREED);
00555                 az  = (double)rotation["phi"]   + 90.0f ;
00556                 alt = (double)rotation["theta"] ;
00557                 phi = (double)rotation["omega"] - 90.0f ;
00558         } else if ( type == "quaternion" ) {
00559 //              validate_and_set_type(THREED);
00560                 is_quaternion = 1;
00561                 e0 = (double)rotation["e0"];
00562                 e1 = (double)rotation["e1"];
00563                 e2 = (double)rotation["e2"];
00564                 e3 = (double)rotation["e3"];
00565         } else if ( type == "spin" ) {
00566 //              validate_and_set_type(THREED);
00567                 is_quaternion = 1;
00568                 Omega = (double)rotation["Omega"];
00569                 e0 = cos(Omega*EMConsts::deg2rad/2.0);
00570                 e1 = sin(Omega*EMConsts::deg2rad/2.0) * (double)rotation["n1"];
00571                 e2 = sin(Omega*EMConsts::deg2rad/2.0) * (double)rotation["n2"];
00572                 e3 = sin(Omega*EMConsts::deg2rad/2.0) * (double)rotation["n3"];
00573         } else if ( type == "sgirot" ) {
00574 //              validate_and_set_type(THREED);
00575                 is_quaternion = 1;
00576                 Omega = (double)rotation["q"] ;
00577                 e0 = cos(Omega*EMConsts::deg2rad/2.0);
00578                 e1 = sin(Omega*EMConsts::deg2rad/2.0) * (double)rotation["n1"];
00579                 e2 = sin(Omega*EMConsts::deg2rad/2.0) * (double)rotation["n2"];
00580                 e3 = sin(Omega*EMConsts::deg2rad/2.0) * (double)rotation["n3"];
00581         } else if ( type == "matrix" ) {
00582                 is_matrix = 1;
00583                 matrix[0][0] = (float)rotation["m11"];
00584                 matrix[0][1] = (float)rotation["m12"];
00585                 matrix[0][2] = (float)rotation["m13"];
00586                 matrix[1][0] = (float)rotation["m21"];
00587                 matrix[1][1] = (float)rotation["m22"];
00588                 matrix[1][2] = (float)rotation["m23"];
00589                 matrix[2][0] = (float)rotation["m31"];
00590                 matrix[2][1] = (float)rotation["m32"];
00591                 matrix[2][2] = (float)rotation["m33"];
00592         } else {
00593 //              transform_type = UNKNOWN;
00594                 throw InvalidStringException(euler_type, "unknown Euler Type");
00595         }
00596 
00597         double azp  =  az*EMConsts::deg2rad;
00598         double altp = alt*EMConsts::deg2rad;
00599         double phip = phi*EMConsts::deg2rad;
00600 
00601         if (!is_quaternion && !is_matrix && !is_xyz) {
00602                 matrix[0][0] =  (float)(cos(phip)*cos(azp) - cos(altp)*sin(azp)*sin(phip));
00603                 matrix[0][1] =  (float)(cos(phip)*sin(azp) + cos(altp)*cos(azp)*sin(phip));
00604                 matrix[0][2] =  (float)(sin(altp)*sin(phip));
00605                 matrix[1][0] =  (float)(-sin(phip)*cos(azp) - cos(altp)*sin(azp)*cos(phip));
00606                 matrix[1][1] =  (float)(-sin(phip)*sin(azp) + cos(altp)*cos(azp)*cos(phip));
00607                 matrix[1][2] =  (float)(sin(altp)*cos(phip));
00608                 matrix[2][0] =  (float)(sin(altp)*sin(azp));
00609                 matrix[2][1] =  (float)(-sin(altp)*cos(azp));
00610                 matrix[2][2] =  (float)cos(altp);
00611         }
00612         if (is_quaternion){
00613                 matrix[0][0] = (float)(e0 * e0 + e1 * e1 - e2 * e2 - e3 * e3);
00614                 matrix[0][1] = (float)(2.0f * (e1 * e2 + e0 * e3));
00615                 matrix[0][2] = (float)(2.0f * (e1 * e3 - e0 * e2));
00616                 matrix[1][0] = (float)(2.0f * (e2 * e1 - e0 * e3));
00617                 matrix[1][1] = (float)(e0 * e0 - e1 * e1 + e2 * e2 - e3 * e3);
00618                 matrix[1][2] = (float)(2.0f * (e2 * e3 + e0 * e1));
00619                 matrix[2][0] = (float)(2.0f * (e3 * e1 + e0 * e2));
00620                 matrix[2][1] = (float)(2.0f * (e3 * e2 - e0 * e1));
00621                 matrix[2][2] = (float)(e0 * e0 - e1 * e1 - e2 * e2 + e3 * e3);
00622                 // keep in mind matrix[0][2] is M13 gives an e0 e2 piece, etc
00623         }
00624         if (is_xyz){
00625                 matrix[0][0] =  (float)(cytilt*cztilt);
00626                 matrix[0][1] =  (float)(cxtilt*sztilt+sxtilt*sytilt*cztilt);
00627                 matrix[0][2] =  (float)(sxtilt*sztilt-cxtilt*sytilt*cztilt);
00628                 matrix[1][0] =  (float)(-cytilt*sztilt);
00629                 matrix[1][1] =  (float)(cxtilt*cztilt-sxtilt*sytilt*sztilt);
00630                 matrix[1][2] =  (float)(sxtilt*cztilt+cxtilt*sytilt*sztilt);
00631                 matrix[2][0] =  (float)(sytilt);
00632                 matrix[2][1] =  (float)(-sxtilt*cytilt);
00633                 matrix[2][2] =  (float)(cxtilt*cytilt);
00634         }
00635         
00636         // Apply scale if it existed previously
00637         if (scale != 1.0f) {
00638                 for(int i=0; i<3; ++i) {
00639                         for(int j=0; j<3; ++j) {
00640                                 matrix[i][j] *= scale;
00641                         }
00642                 }
00643         }
00644 
00645         // Apply post x mirroring if it was applied previously
00646         if ( x_mirror ) {
00647                 for(int j=0; j<3; ++j) {
00648                         matrix[0][j] *= -1.0f;
00649                 }
00650         }
00651 }

void Transform::set_scale ( const float &  scale  ) 

Set the scale.

Parameters:
scale the amount to scale by

Definition at line 997 of file transform.cpp.

References EMAN::Util::apply_precision(), ERR_LIMIT, get_scale(), InvalidValueException, and matrix.

Referenced by EMAN::RefineAligner::align(), EMAN::WienerFourierReconstructor::determine_slice_agreement(), EMAN::FourierReconstructor::determine_slice_agreement(), get_rotation_transform(), EMAN::BackProjectionReconstructor::insert_slice(), EMAN::WienerFourierReconstructor::insert_slice(), EMAN::FourierReconstructor::insert_slice(), scale(), set_params(), set_params_inverse(), and set_pre_trans().

00997                                                 {
00998         if (new_scale <= 0) {
00999                 throw InvalidValueException(new_scale,"The scale factor in a Transform object must be positive and non zero");
01000         }
01001         // Transform = MTSR (Mirroring, Translation, Scaling, Rotate)
01002         // So changing the scale boils down to this....
01003 
01004         float old_scale = get_scale();
01005 
01006         float n_scale = new_scale;
01007         Util::apply_precision(n_scale,ERR_LIMIT);
01008 
01009         float corrected_scale = n_scale/old_scale;
01010         if ( corrected_scale != 1.0 ) {
01011                 for(int i = 0; i < 3;  ++i ) {
01012                         for(int j = 0; j < 3; ++j ) {
01013                                 matrix[i][j] *= corrected_scale;
01014                         }
01015                 }
01016         }
01017 }

void EMAN::Transform::set_trans ( const Vec2f v  )  [inline]

Set the post translation component using a Vec2f.

Parameters:
v the 2D translation vector

Definition at line 221 of file transform.h.

References set_trans(), and v.

00221 { set_trans(v[0],v[1]); }

void EMAN::Transform::set_trans ( const Vec3f v  )  [inline]

Set the post translation component using a Vec3f.

Parameters:
v the 3D translation vector

Definition at line 216 of file transform.h.

References set_trans(), and v.

00216 { set_trans(v[0],v[1],v[2]); }

void Transform::set_trans ( const float &  x,
const float &  y,
const float &  z = 0 
)

Set the post translation component.

Parameters:
x the x translation
y the y translation
z the z translation

Definition at line 926 of file transform.cpp.

References get_mirror(), and matrix.

Referenced by EMAN::Refine3DAlignerGrid::align(), EMAN::RefineAligner::align(), EMAN::WienerFourierReconstructor::determine_slice_agreement(), EMAN::FourierReconstructor::determine_slice_agreement(), frm_2d_Align(), get_pre_trans(), get_pre_trans_2d(), get_rotation_transform(), EMAN::HSym::get_sym(), EMAN::BackProjectionReconstructor::insert_slice(), EMAN::WienerFourierReconstructor::insert_slice(), EMAN::FourierReconstructor::insert_slice(), EMAN::MrcIO::read_mrc_header(), set_params(), set_params_inverse(), set_pre_trans(), set_trans(), EMAN::RT3DSphereAligner::xform_align_nbest(), and EMAN::RT3DGridAligner::xform_align_nbest().

00927 {
00928         bool x_mirror = get_mirror();
00929 
00930         if (x_mirror) matrix[0][3] = -x;
00931         else matrix[0][3] = x;
00932         matrix[1][3] = y;
00933         matrix[2][3] = z;
00934 }

Transform Transform::tet_3_to_2 (  )  [static]

Get the transform that moves any tetrahedron generated by eman2 so that it matches the 2-2-2 (MRC, FREALIGN) convention.

Returns:
a Transforms, alt=54.73561, phi=45

Doctor Phil says: AltAngle= acos(-1/3.0)*90/pi;

Definition at line 83 of file transform.cpp.

References t.

00083                                 {
00084         Transform t;
00085         Dict d;
00086         d["type"] = "eman";
00087         d["phi"] = 45.0f;
00088         d["az"] = 0.0f;
00089         d["alt"] = 54.73561f; // 3 fold to a 2 fold
00093         t.set_rotation(d);
00094         return t;
00095 }

void Transform::to_identity (  ) 

Force the internal matrix to become the identity.

Definition at line 192 of file transform.cpp.

References matrix.

Referenced by Transform().

00193 {
00194 //      transform_type = UNKNOWN;
00195         for(int i=0; i<3; ++i) {
00196                 for(int j=0; j<4; ++j) {
00197                         if(i==j) {
00198                                 matrix[i][j] = 1;
00199                         }
00200                         else {
00201                                 matrix[i][j] = 0;
00202                         }
00203                 }
00204         }
00205 }

template<typename Type>
Vec3f EMAN::Transform::transform ( const Vec3< Type > &  v  )  const [inline]

Transform a 3D vector using the internal transformation matrix.

Parameters:
v a three dimensional vector to be transformed
Returns:
the transformed vector

Definition at line 432 of file transform.h.

References transform(), and v.

00432                                                                           {
00433 //                              assert_consistent_type(THREED); // Transform does the assertion
00434                                 return transform(v[0],v[1],v[2]);
00435                         }

Vec3f EMAN::Transform::transform ( const float &  x,
const float &  y,
const float &  z 
) const [inline]

Transform 3D coordinates using the internal transformation matrix.

Parameters:
x the x coordinate of the transformed point
y the y coordinate of the transformed point
z the z coordinate of the transformed point
Returns:
the transformed vector

Definition at line 418 of file transform.h.

References matrix.

00418                                                                                                      {
00419 //                              assert_consistent_type(THREED);
00420                                 Vec3f ret;
00421                                 ret[0] = matrix[0][0] * x + matrix[0][1] * y + matrix[0][2] * z + matrix[0][3];
00422                                 ret[1] = matrix[1][0] * x + matrix[1][1] * y + matrix[1][2] * z + matrix[1][3];
00423                                 ret[2] = matrix[2][0] * x + matrix[2][1] * y + matrix[2][2] * z + matrix[2][3];
00424                                 return ret;
00425                         }

template<typename Type>
Vec2f EMAN::Transform::transform ( const Vec2< Type > &  v  )  const [inline]

Transform a 2D vector using the internal transformation matrix.

Parameters:
v a two dimensional vector to be transformed
Returns:
the transformed vector

Definition at line 408 of file transform.h.

References transform(), and v.

00408                                                                           {
00409                                 return transform(v[0],v[1]);
00410                         }

Vec2f EMAN::Transform::transform ( const float &  x,
const float &  y 
) const [inline]

Transform 2D coordinates using the internal transformation matrix.

Parameters:
x the x coordinate of the transformed point
y the y coordinate of the transformed point
Returns:
the transformed vector

Definition at line 395 of file transform.h.

References matrix.

Referenced by EMAN::EMData::get_rotated_clip(), EMAN::operator *(), and transform().

00395                                                                                      {
00396 //                              assert_valid_2d();
00397                                 Vec2f ret;
00398                                 ret[0] = matrix[0][0]*x + matrix[0][1]*y + matrix[0][3];
00399                                 ret[1] = matrix[1][0]*x + matrix[1][1]*y + matrix[1][3];
00400                                 return ret;
00401                         }

void EMAN::Transform::translate ( const Vec2f v  )  [inline]

Increment the current translation using vec2f& v.

Parameters:
v the translation vector

Definition at line 243 of file transform.h.

References translate(), and v.

00243 { translate(v[0],v[1]); }

void EMAN::Transform::translate ( const Vec3f v  )  [inline]

Increment the current translation using vec3f& v.

Parameters:
v the 3D translation vector

Definition at line 238 of file transform.h.

References translate(), and v.

00238 { translate(v[0],v[1],v[2]); }

void Transform::translate ( const float &  tx,
const float &  ty,
const float &  tz = 0 
)

Increment the current translation by tx, ty, tz.

Parameters:
tx the x incrementation
ty the y incrementation
tz the z incrementation

Definition at line 953 of file transform.cpp.

References get_mirror(), and matrix.

Referenced by translate().

00954 {
00955         bool x_mirror = get_mirror();
00956         if (x_mirror) matrix[0][3] = -matrix[0][3] + tx;
00957         else matrix[0][3] = matrix[0][3] + tx;
00958         matrix[1][3] = matrix[1][3] + ty;
00959         matrix[2][3] = matrix[2][3] + tz;
00960 }

Transform Transform::transpose (  )  const

Get the transpose of this transformation matrix.

Returns:
the transpose of this transformation matrix

Definition at line 1220 of file transform.cpp.

References t.

Referenced by EMAN::PDBReader::right_transform().

01220                                      {
01221         Transform t(*this);
01222         t.transpose_inplace();
01223         return t;
01224 }

void Transform::transpose_inplace (  ) 

Get the transpose of this transformation matrix.

Definition at line 1207 of file transform.cpp.

References matrix.

01207                                   {
01208         float tempij;
01209         for (int i = 0; i < 3; i++) {
01210                 for (int j = 0; j < i; j++) {
01211                         if (i != j) {
01212                                 tempij= matrix[i][j];
01213                                 matrix[i][j] = matrix[j][i];
01214                                 matrix[j][i] = tempij;
01215                         }
01216                 }
01217         }
01218 }


Member Data Documentation

const float Transform::ERR_LIMIT = 0.000001f [static]

Definition at line 86 of file transform.h.

Referenced by assert_valid_2d(), get_determinant(), get_scale(), get_scale_and_mirror(), get_trans(), is_identity(), EMAN::Symmetry3D::point_in_which_asym_unit(), EMAN::Util::point_is_in_triangle_2d(), and set_scale().

float EMAN::Transform::matrix[3][4] [private]

Definition at line 479 of file transform.h.

Referenced by assert_valid_2d(), at(), copy_matrix_into_array(), get_determinant(), get_matrix(), get_matrix3_row(), get_matrix_4x4(), get_rotation(), get_sym_proj(), get_trans(), get_trans_2d(), invert(), is_identity(), operator=(), operator[](), orthogonalize(), printme(), rotate(), rotate_origin(), set(), set_matrix(), set_mirror(), set_rotation(), set_scale(), set_trans(), to_identity(), transform(), Transform(), translate(), and transpose_inplace().

vector< string > Transform::permissable_2d_not_rot [static, private]

This map is used to validate keys in the argument maps - e.g. if the type is 2d and the angle is not "alpha" then we should throw.

Definition at line 484 of file transform.h.

Referenced by detect_problem_keys(), and init_permissable_keys().

vector< string > Transform::permissable_3d_not_rot [static, private]

Definition at line 485 of file transform.h.

Referenced by detect_problem_keys(), and init_permissable_keys().

map< string, vector< string > > Transform::permissable_rot_keys [static, private]

Definition at line 486 of file transform.h.

Referenced by detect_problem_keys(), and init_permissable_keys().


The documentation for this class was generated from the following files:
Generated on Tue Jul 12 13:50:25 2011 for EMAN2 by  doxygen 1.4.7