Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

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_origin_newBasis (const Transform &tcs, const float &Omega, const float &n1, const float &n2, const float &n3)
 Increment the rotation by multipling the rotation bit of the argument transfrom by the rotation part of the current transfrom This version rotates in the standard coordinate system, even after it have been modified by tcs.
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.
void translate_newBasis (const Transform &tcs, const float &tx, const float &ty, const float &tz=0)
 Increment the current translation by tx, ty, tz using a non standard basis Actualy what it does is remove the effect of tcs when a composite transfrom tcs*t (where t is the current transform) This function is used in the scenegraph.
void translate (const Transform &tcs, const Vec3f &v)
 Increment the current translation using vec3f& v and a non standard basis.
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.
bool is_rot_identity () const
 Returns whethers or this matrix rotation 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

int get_nsym (const string &sym)
 get the number of symmetries associated with the given symmetry name
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.
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

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

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.
vector< string > permissable_3d_not_rot
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 104 of file transform.cpp.

References to_identity().

Referenced by rotate_origin_newBasis(), set_params_inverse(), and translate_newBasis().

00105 {
00106         to_identity();
00107 }

Transform::Transform const Transform rhs  ) 
 

Copy constructor.

Parameters:
rhs the object to be copied

Definition at line 109 of file transform.cpp.

00110 {
00111         *this = that;
00112 }

Transform::Transform const Dict d  ) 
 

Construction using a dictionary.

Parameters:
d the dictionary containing the parameters

Definition at line 135 of file transform.cpp.

References set_params(), and to_identity().

00135                                    {
00136         to_identity();
00137         set_params(d);
00138 }

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 141 of file transform.cpp.

References matrix.

00141                                           {
00142         memcpy(matrix,array,12*sizeof(float));
00143 }

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 145 of file transform.cpp.

References set_matrix().

00146 {
00147         set_matrix(array);
00148 }

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 1307 of file transform.cpp.

References matrix, and UnexpectedBehaviorException.

Referenced by get_rotation(), and set_rotation().

01307                                       {
01308         int rotation_error = 0;
01309         int translation_error = 0;
01310         if (fabs(matrix[2][0]) > ERR_LIMIT) rotation_error++;
01311         if (fabs(matrix[2][1]) > ERR_LIMIT) rotation_error++;
01312         if (fabs(matrix[2][3]) > ERR_LIMIT) translation_error++;
01313         if (fabs(matrix[0][2]) > ERR_LIMIT) rotation_error++;
01314         if (fabs(matrix[1][2]) > ERR_LIMIT) rotation_error++;
01315 //      if (fabs(matrix[2][2]-1.0) >ERR_LIMIT) rotation_error++; 
01316         if ( translation_error && rotation_error ) {
01317                 throw UnexpectedBehaviorException("Error, the internal matrix contains 3D rotations and 3D translations. This object can not be considered 2D");
01318         } else if ( translation_error ) {
01319                 throw UnexpectedBehaviorException("Error, the internal matrix contains a non zero z component for a 3D translation. This object can not be considered 2D");
01320         }
01321         else if ( rotation_error ) {
01322                 throw UnexpectedBehaviorException("Error, the internal matrix contains 3D rotations and this object can not be considered 2D");
01323         }
01324 
01325 }

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 401 of file transform.h.

References matrix().

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

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

void Transform::copy_matrix_into_array float *  const  )  const
 

Definition at line 161 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().

00161                                                                {
00162 
00163         int idx = 0;
00164         for(int i=0; i<3; ++i) {
00165                 for(int j=0; j<4; ++j) {
00166                         array[idx] = matrix[i][j];
00167                         idx ++;
00168                 }
00169         }
00170 }

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 361 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().

00361                                                  {
00362         if (permissable_rot_keys.size() == 0 ) {
00363                 init_permissable_keys();
00364         }
00365 
00366         vector<string> verification;
00367         vector<string> problem_keys;
00368         bool is_2d = false;
00369         if (d.has_key_ci("type") ) {
00370                 string type = Util::str_to_lower((string)d["type"]);
00371                 bool problem = false;
00372                 if (permissable_rot_keys.find(type) == permissable_rot_keys.end() ) {
00373                         problem_keys.push_back(type);
00374                         problem = true;
00375                 }
00376                 if ( !problem ) {
00377                         vector<string> perm = permissable_rot_keys[type];
00378                         std::copy(perm.begin(),perm.end(),back_inserter(verification));
00379 
00380                         if ( type == "2d" ) {
00381                                 is_2d = true;
00382                                 std::copy(permissable_2d_not_rot.begin(),permissable_2d_not_rot.end(),back_inserter(verification));
00383                         }
00384                 }
00385         }
00386         if ( !is_2d ) {
00387                 std::copy(permissable_3d_not_rot.begin(),permissable_3d_not_rot.end(),back_inserter(verification));
00388         }
00389 
00390         for (Dict::const_iterator it = d.begin(); it != d.end();  ++it) {
00391                 if ( std::find(verification.begin(),verification.end(), it->first) == verification.end() ) {
00392                         problem_keys.push_back(it->first);
00393                 }
00394         }
00395 
00396         if (problem_keys.size() != 0 ) {
00397                 string error;
00398                 if (problem_keys.size() == 1) {
00399                         error = "Transform Error: The \"" +problem_keys[0]+ "\" key is unsupported";
00400                 } else {
00401                         error = "Transform Error: The ";
00402                         for(vector<string>::const_iterator cit = problem_keys.begin(); cit != problem_keys.end(); ++cit ) {
00403                                 if ( cit != problem_keys.begin() ) {
00404                                         if (cit == (problem_keys.end() -1) ) error += " and ";
00405                                         else error += ", ";
00406                                 }
00407                                 error += "\"";
00408                                 error += *cit;
00409                                 error += "\"";
00410                         }
00411                         error += " keys are unsupported";
00412                 }
00413                 throw InvalidParameterException(error);
00414         }
00415 }

float Transform::get_determinant  )  const
 

Get the determinant of the matrix.

Returns:
the determinant

Definition at line 1220 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().

01221 {
01222         float det;
01223         double det2;
01224         det2  = matrix[0][0]*((double)matrix[1][1]*matrix[2][2]-(double)matrix[2][1]*matrix[1][2]);
01225         det2 -= matrix[0][1]*((double)matrix[1][0]*matrix[2][2]-(double)matrix[2][0]*matrix[1][2]);
01226         det2 += matrix[0][2]*((double)matrix[1][0]*matrix[2][1]-(double)matrix[2][0]*matrix[1][1]);
01227 
01228         det = (float)det2;
01229         Util::apply_precision(det,ERR_LIMIT);
01230 
01231         return det;
01232 }

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 778 of file transform.cpp.

References get_rotation(), get_trans(), set_rotation(), set_trans(), and EMAN::Vec3f.

00778                                                {
00779 
00780         Dict rot = get_rotation("eman");
00781         rot["alt"] = 180.0f + static_cast<float>(rot["alt"]);
00782         rot["phi"] = 180.0f - static_cast<float>(rot["phi"]);
00783 
00784         Transform ret(*this); // Is the identity
00785         ret.set_rotation(rot);
00786 
00787         Vec3f trans = get_trans();
00788         trans[0] = -trans[0];
00789         ret.set_trans(trans);
00790 
00791 //      ret.set_mirror(self.get_mirror());
00792 
00793         return ret;
00794 }

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 172 of file transform.cpp.

References matrix.

Referenced by EMAN::EMData::extract_box(), rotate(), and rotate_origin().

00173 {
00174         vector<float> ret(12);
00175         for(int i=0; i<3; ++i) {
00176                 for(int j=0; j<4; ++j) {
00177                         ret[i*4+j] = matrix[i][j];
00178                 }
00179         }
00180         return ret;
00181 }

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 470 of file transform.h.

References matrix(), and EMAN::Vec3f.

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

00470                                                                   {
00471                                 return Vec3f(matrix[i][0], matrix[i][1], matrix[i][2]);
00472                         }

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 183 of file transform.cpp.

References matrix.

00184 {
00185         vector<float> ret(16);
00186         for(int i=0; i<3; ++i) {
00187                 for(int j=0; j<4; ++j) {
00188                         ret[i*4+j] = matrix[i][j];
00189                 }
00190         }
00191         ret[12] = 0.0; 
00192         ret[13] = 0.0;
00193         ret[14] = 0.0;
00194         ret[15] = 1.0;
00195         
00196         return ret;
00197 }

bool Transform::get_mirror  )  const
 

Query whether x_mirroring is occuring.

Returns:
whether x_mirroring is occuring

Definition at line 1191 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().

01191                                  {
01192         float determinant = get_determinant();
01193 
01194         bool x_mirror = false;
01195         if ( determinant < 0 ) x_mirror = true;
01196 
01197         return x_mirror;
01198 
01199 }

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

get the number of symmetries associated with the given symmetry name

Definition at line 1457 of file transform.cpp.

References EMAN::Factory< T >::get(), and 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(), and EMAN::nn4Reconstructor::setup().

01458 {
01459         Symmetry3D* sym = Factory<Symmetry3D>::get(sym_name);
01460         int nsym = sym->get_nsym();
01461         delete sym;
01462         return nsym;
01463 }

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 471 of file transform.cpp.

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

Referenced by EMAN::RefineAligner::align(), EMAN::Util::BPCQ(), EMAN::Util::multiref_polar_ali_2d_local(), EMAN::Util::multiref_polar_ali_2d_local_psi(), EMAN::Util::multiref_polar_ali_helical_90_local(), EMAN::Util::multiref_polar_ali_helical_local(), EMAN::TomoTiltEdgeMaskProcessor::process_inplace(), and EMAN::SpiderIO::write_single_header().

00471                                                          {
00472         Dict params = get_rotation(euler_type);
00473 
00474         Vec3f v = get_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 = get_scale();
00481         params["scale"] = scale;
00482 
00483         bool mirror = get_mirror();
00484         params["mirror"] = mirror;
00485 
00486         return params;
00487 }

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 491 of file transform.cpp.

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

00491                                                                  {
00492         Transform inv(inverse());
00493 
00494         Dict params = inv.get_rotation(euler_type);
00495         Vec3f v = inv.get_pre_trans();
00496         params["tx"] = v[0]; params["ty"] = v[1];
00497 
00498         string type = Util::str_to_lower(euler_type);
00499         if ( type != "2d") params["tz"] = v[2];
00500 
00501         float scale = inv.get_scale();
00502         params["scale"] = scale;
00503 
00504         bool mirror = inv.get_mirror();
00505         params["mirror"] = mirror;
00506 
00507         return params;
00508 }

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 1036 of file transform.cpp.

References get_trans(), invert(), set_trans(), and EMAN::Vec3f.

Referenced by get_params_inverse().

01037 {
01038         Transform T(*this);
01039         T.set_trans(0,0,0);
01040         T.invert();
01041 
01042         Transform soln  = T*(*this);
01043 //      soln.printme();
01044         return soln.get_trans();
01045 }

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 1047 of file transform.cpp.

References get_trans_2d(), invert(), set_trans(), and EMAN::Vec2f.

01048 {
01049         Transform T(*this);
01050         T.set_trans(0,0,0);
01051         T.invert();
01052 
01053         Transform soln  = T*(*this);
01054 //      soln.printme();
01055         return soln.get_trans_2d();
01056 }

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 812 of file transform.cpp.

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

Referenced by EMAN::file_store::add_image(), 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(), main(), EMAN::ChaoProjector::project3d(), EMAN::FourierGriddingProjector::project3d(), set_pre_trans(), and EMAN::RT3DSymmetryAligner::xform_align_nbest().

00813 {
00814         Dict result;
00815 
00816         //float max = 1 - ERR_LIMIT;
00817         float scale;
00818         bool x_mirror;
00819         get_scale_and_mirror(scale,x_mirror);
00820         if (scale == 0) throw UnexpectedBehaviorException("The determinant of the Transform is 0. This is unexpected.");
00821 
00822         double cosalt = matrix[2][2]/scale;
00823         double x_mirror_scale = (x_mirror ? -1.0f : 1.0f);
00824         double inv_scale = 1.0f/scale;
00825 
00826         double az  = 0;
00827         double alt = 0;
00828         double phi = 0;
00829         double phiS = 0;  // like az  (but in SPIDER ZYZ)
00830         double psiS = 0;  // like phi (but in SPIDER ZYZ)
00831 
00832         // get alt, az, phi in EMAN convention
00833 
00834         if (cosalt >= 1) {  // that is, alt close to 0
00835                         alt = 0;
00836                         az = 0;
00837                         phi = (double)EMConsts::rad2deg * atan2(x_mirror_scale*matrix[0][1], x_mirror_scale*matrix[0][0]);
00838         } else if (cosalt <= -1) {  // that is, alt close to 180
00839                         alt = 180;
00840                         az = 0;
00841                         phi = (double)EMConsts::rad2deg * atan2(-x_mirror_scale*matrix[0][1], x_mirror_scale*matrix[0][0]);
00842         } else {   // for non exceptional cases:  0 < alt < 180
00843 
00844                 az  = (double)EMConsts::rad2deg * atan2(scale*matrix[2][0], -scale*matrix[2][1]);
00845 
00846                 if (matrix[2][2]==0.0)
00847                         alt = 90.0;
00848                 else
00849                         alt = (double)EMConsts::rad2deg * atan(sqrt((double)matrix[2][0]*matrix[2][0]+(double)matrix[2][1]*matrix[2][1])/fabs(matrix[2][2]));
00850 
00851                 if (matrix[2][2] * scale < 0)
00852                         alt = 180.0f-alt;
00853                 
00854                 phi = (double)EMConsts::rad2deg * atan2(x_mirror_scale*(double)matrix[0][2], (double)matrix[1][2]);
00855 
00856         } // ends separate cases: alt close to 0, 180, or neither
00857 
00858         phi = phi-360.0*floor(phi/360.0);
00859         az  = az -360.0*floor(az/360.0);
00860 
00861 //  get phiS, psiS (SPIDER)
00862         if (cosalt >= 1) {  // that is, alt close to 0
00863                 phiS = 0;
00864                 psiS = phi;
00865         } else if (cosalt <= -1) {  // that is, alt close to 180
00866                 phiS = 0;
00867                 psiS = phi + 180.0;
00868         } else {
00869                 phiS = az  - 90.0;
00870                 psiS = phi + 90.0;
00871         }
00872 
00873         phiS = phiS-360.0*floor(phiS/360.0);
00874         psiS = psiS-360.0*floor(psiS/360.0);
00875 
00876 //   do some quaternionic stuff here
00877 
00878         double nphi = (az-phi)/2.0;
00879     // The next is also e0
00880         double cosOover2 = cos((az+phi)*EMConsts::deg2rad/2.0) * cos(alt*EMConsts::deg2rad/2.0);
00881         double sinOover2 = sqrt(1 -cosOover2*cosOover2);
00882         double cosnTheta = sin((az+phi)*EMConsts::deg2rad/2.0) * cos(alt*EMConsts::deg2rad/2.0) / sqrt(1-cosOover2*cosOover2);
00883         double sinnTheta = sqrt(1-cosnTheta*cosnTheta);
00884         double n1 = sinnTheta*cos(nphi*EMConsts::deg2rad);
00885         double n2 = sinnTheta*sin(nphi*EMConsts::deg2rad);
00886         double n3 = cosnTheta;
00887         double xtilt = 0;
00888         double ytilt = 0;
00889         double ztilt = 0;
00890 
00891 
00892         if (cosOover2<0) {
00893                 cosOover2*=-1; n1 *=-1; n2*=-1; n3*=-1;
00894         }
00895 
00896         string type = Util::str_to_lower(euler_type);
00897 
00898         result["type"] = type;
00899         if (type == "2d") {
00900                 assert_valid_2d();
00901                 result["alpha"]  = phi;
00902         } else if (type == "eman") {
00903 //              assert_consistent_type(THREED);
00904                 result["az"]  = az;
00905                 result["alt"] = alt;
00906                 result["phi"] = phi;
00907         } else if (type == "imagic") {
00908 //              assert_consistent_type(THREED);
00909                 result["alpha"] = az;
00910                 result["beta"]  = alt;
00911                 result["gamma"] = phi;
00912         } else if (type == "spider") {
00913 //              assert_consistent_type(THREED);
00914                 result["phi"]   = phiS;  // The first Euler like az
00915                 result["theta"] = alt;
00916                 result["psi"]   = psiS;
00917         } else if (type == "mrc") {
00918 //              assert_consistent_type(THREED);
00919                 result["phi"]   = phiS;
00920                 result["theta"] = alt;
00921                 result["omega"] = psiS;
00922         } else if (type == "xyz") {               // need to double-check these 3 equations ********
00923 //              assert_consistent_type(THREED);
00924                 xtilt = atan2(-sin(EMConsts::deg2rad*phiS)*sin(EMConsts::deg2rad*alt),cos(EMConsts::deg2rad*alt));
00925                 ytilt = asin(  cos(EMConsts::deg2rad*phiS)*sin(EMConsts::deg2rad*alt));
00926                 ztilt = psiS*EMConsts::deg2rad - atan2(sin(xtilt), cos(xtilt) *sin(ytilt));
00927 
00928                 xtilt *= EMConsts::rad2deg; ytilt *= EMConsts::rad2deg; ztilt *= EMConsts::rad2deg;
00929                 xtilt = xtilt-360*.0*floor((xtilt+180.0)/360.0);
00930                 ytilt = ytilt-360*.0*floor((ytilt+180.0)/360.0);  //already in range [-90,90] but anyway...
00931                 ztilt = ztilt-360*.0*floor((ztilt+180.0)/360.0);
00932 
00933                 result["xtilt"]  = xtilt;
00934                 result["ytilt"]  = ytilt;
00935                 result["ztilt"]  = ztilt;
00936         } else if (type == "quaternion") {
00937 //              assert_consistent_type(THREED);
00938                 result["e0"] = cosOover2 ;
00939                 result["e1"] = sinOover2 * n1 ;
00940                 result["e2"] = sinOover2 * n2;
00941                 result["e3"] = sinOover2 * n3;
00942         } else if (type == "spin") {
00943 //              assert_consistent_type(THREED);
00944                 result["Omega"] = 2.0*EMConsts::rad2deg * acos(cosOover2);
00945                 result["n1"] = n1;
00946                 result["n2"] = n2;
00947                 result["n3"] = n3;
00948         } else if (type == "sgirot") {
00949 //              assert_consistent_type(THREED);
00950                 result["q"] = 2.0*EMConsts::rad2deg * acos(cosOover2);
00951                 result["n1"] = n1;
00952                 result["n2"] = n2;
00953                 result["n3"] = n3;
00954         } else if (type == "matrix") {
00955 //              assert_consistent_type(THREED);
00956                 result["m11"] = x_mirror_scale*matrix[0][0]*inv_scale;
00957                 result["m12"] = x_mirror_scale*matrix[0][1]*inv_scale;
00958                 result["m13"] = x_mirror_scale*matrix[0][2]*inv_scale;
00959                 result["m21"] = matrix[1][0]*inv_scale;
00960                 result["m22"] = matrix[1][1]*inv_scale;
00961                 result["m23"] = matrix[1][2]*inv_scale;
00962                 result["m31"] = matrix[2][0]*inv_scale;
00963                 result["m32"] = matrix[2][1]*inv_scale;
00964                 result["m33"] = matrix[2][2]*inv_scale;
00965         } else {
00966                 throw InvalidStringException(euler_type, "unknown Euler Type");
00967         }
00968 
00969         return result;
00970 }

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 674 of file transform.cpp.

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

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

00675 {
00676         Transform ret(*this);
00677         ret.set_scale(1.0);
00678         ret.set_mirror(false);
00679         ret.set_trans(0,0,0);
00680         //ret.orthogonalize(); // ?
00681         return ret;
00682 }

float Transform::get_scale  )  const
 

Get the scale that was applied.

Returns:
the scale factor

Definition at line 1081 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::TransformProcessor::process(), EMAN::TransformProcessor::process_inplace(), EMAN::GaussFFTProjector::project3d(), set_pre_trans(), and set_scale().

01081                                  {
01082         float determinant = get_determinant();
01083         if (determinant < 0 ) determinant *= -1;
01084 
01085         float scale = std::pow(determinant,1.0f/3.0f);
01086         int int_scale = static_cast<int>(scale);
01087         float scale_residual = scale-static_cast<float>(int_scale);
01088         if  ( scale_residual < ERR_LIMIT ) { scale = static_cast<float>(int_scale); };
01089 
01090         Util::apply_precision(scale, ERR_LIMIT);
01091 
01092         return scale;
01093 }

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 1201 of file transform.cpp.

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

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

01201                                                                        {
01202 
01203         float determinant = get_determinant();
01204         x_mirror = false;
01205         if ( determinant < 0 ) {
01206                 x_mirror = true;
01207                 determinant *= -1;
01208         }
01209         if (determinant != 1 ) {
01210                 scale = std::pow(determinant,1.0f/3.0f);
01211                 int int_scale = static_cast<int>(scale);
01212                 float scale_residual = scale-static_cast<float>(int_scale);
01213                 if  ( scale_residual < ERR_LIMIT ) { scale = static_cast<float>(int_scale); };
01214         }
01215         else scale = 1;
01216 
01217         Util::apply_precision(scale,ERR_LIMIT);
01218 }

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 1329 of file transform.cpp.

References EMAN::Factory< T >::get(), and EMAN::Symmetry3D::get_sym().

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

01330 {
01331         Symmetry3D* sym = Factory<Symmetry3D>::get(sym_name);
01332         Transform ret;
01333         ret = (*this) * sym->get_sym(n);
01334         delete sym;
01335         return ret;
01336 }

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

Definition at line 1338 of file transform.cpp.

References EMAN::Factory< T >::get(), EMAN::Symmetry3D::get_nsym(), get_rotation(), EMAN::Symmetry3D::get_sym(), matrix, set_rotation(), and t.

Referenced by EMAN::nn4_ctf_rectReconstructor::insert_padfft_slice(), EMAN::nn4_ctfReconstructor::insert_padfft_slice(), EMAN::nn4_rectReconstructor::insert_padfft_slice(), and EMAN::nn4Reconstructor::insert_padfft_slice().

01339 {
01340         vector<Transform> ret;
01341         Transform t;
01342         Symmetry3D* sym = Factory<Symmetry3D>::get(sym_name);
01343         int nsym = sym->get_nsym();
01344         int n = nsym;
01345         
01346         if ((sym_name[0] == 'c' || sym_name[0] == 'd' ) &&  fabs(matrix[2][2]) < 1.e-6){
01347                 
01348                 Dict d1,d2;                             
01349                 d2["theta"] = (double)90.0;
01350                 d2["psi"] = (double)0.0;
01351                 d2["phi"] = (double)0.0;
01352                 d2["type"] = "spider";
01353                 d1 = this->get_rotation("spider");
01354                 
01355                 if (sym_name[0] == 'c') {
01356                         if( nsym%2 == 0)        n = nsym/2;
01357                         
01358                         for (int k=0;k<n;k++) {                         
01359                                 d2["phi"] = (double)d1["phi"] + k*double(360.0)/ nsym;
01360                                 d2["psi"] = d1["psi"];
01361                                 t.set_rotation(d2);
01362                                 ret.push_back( t );
01363                         }
01364                                 
01365                 }
01366                 else {
01367                         nsym = nsym/2;
01368                         
01369                         if (nsym%2 == 0) {
01370                                 n = nsym;
01371                                 float cos_phi = cos( EMConsts::deg2rad*360.0/2/nsym );
01372                         
01373                                 for (int k=0;k<n;k++){
01374                                         
01375                                         if(k%2==0)      {
01376                                         
01377                                                 d2["phi"] = (double)d1["phi"] + k/2*double(360.0)/ nsym;
01378                                                 d2["psi"] = d1["psi"];
01379                                                 t.set_rotation(d2);
01380                                                 ret.push_back( t );     
01381                                         }
01382                                         else    {
01383                                                         
01384                                                 if( ( fabs(1.0-matrix[2][0])>1.0e-6 )&& fabs( matrix[2][0]-cos_phi)>1.0e-6  ){
01385                                                         //cout<<"jumped into"<<endl;
01386                                                         d2["phi"] = k/2*double(360.0)/ nsym +180 - (double)d1["phi"];
01387                                                         d2["psi"] = (double)d1["psi"] + 180;
01388                                                         t.set_rotation(d2);
01389                                                         ret.push_back( t );
01390                                                 }
01391                                         }
01392                                 
01393                                 }
01394                         }
01395                         
01396                         
01397                         
01398                         else    {
01399                                 n = nsym*2;
01400                                 float cos_phi = cos( EMConsts::deg2rad*360.0/4/nsym );
01401                                 for (int k=0;k<n;k++){
01402                                         
01403                                         if(k%4==0)      {
01404                                         
01405                                                 d2["phi"] = (double)d1["phi"] + k/4*360.0/ nsym;
01406                                                 d2["psi"] = (double)d1["psi"];
01407                                                 t.set_rotation(d2);
01408                                                 ret.push_back( t );     
01409                                         }
01410                                         else if( k%4 ==1)       {
01411                                                 if( ( fabs(1.0-matrix[2][0])>1.0e-6 )&& fabs( matrix[2][0]-cos_phi)>1.0e-6  ){
01412                                                 
01413                                                         d2["phi"] = k/4*360.0/nsym + 360.0/2/nsym+180 - (double)d1["phi"];
01414                                                         d2["psi"] = (double)d1["psi"] + 180;
01415                                                         t.set_rotation(d2);
01416                                                         ret.push_back( t );
01417                                                 }
01418                                 
01419                                         }
01420                                         
01421                                         else if( k%4 ==2)       {
01422                                         
01423                                                 d2["phi"] =  k/4*360.0/ nsym+360.0/2/nsym+180 + (double)d1["phi"];
01424                                                 d2["psi"] = (double)d1["psi"];
01425                                                 t.set_rotation(d2);
01426                                                 ret.push_back( t );
01427                                 
01428                                         }
01429                                         
01430                                         else if( k%4 ==3)       {
01431                                                 if( ( fabs(1.0-matrix[2][0])>1.0e-6 )&& fabs( matrix[2][0]-cos_phi)>1.0e-6  ) {
01432                                                         d2["phi"] = k/4*360.0/nsym+ 2.0*360.0/2/nsym - (double)d1["phi"];
01433                                                         d2["psi"] = (double)d1["psi"] + 180;
01434                                                         t.set_rotation(d2);
01435                                                         ret.push_back( t );
01436                                                 }
01437                                         }
01438                                 
01439                                 }
01440                         }
01441                         
01442                 }
01443                 
01444         }
01445         else {
01446                 for (int k=0;k<nsym;k++) {
01447                         t =  sym->get_sym(k);
01448                         ret.push_back( (*this) * t );
01449                 }
01450                 
01451         }
01452         delete sym;
01453         return ret;
01454 }

Vec3f Transform::get_trans  )  const
 

Get the post trans as a vec3f.

Returns:
the translation vector

Definition at line 982 of file transform.cpp.

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

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

00983 {
00984         // No type asserted
00985         bool x_mirror = get_mirror();
00986         Vec3f v;
00987         if (x_mirror) v[0] = -matrix[0][3];
00988         else v[0] = matrix[0][3];
00989         v[1] = matrix[1][3];
00990         v[2] = matrix[2][3];
00991 
00992         Util::apply_precision(v[0],ERR_LIMIT);
00993         Util::apply_precision(v[1],ERR_LIMIT);
00994         Util::apply_precision(v[2],ERR_LIMIT);
00995 
00996         return v;
00997 }

Vec2f Transform::get_trans_2d  )  const
 

Get the degenerant 2D post trans as a vec2f.

Returns:
the 2D translation vector

Definition at line 1024 of file transform.cpp.

References get_mirror(), matrix, v, and EMAN::Vec2f.

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

01025 {
01026         bool x_mirror = get_mirror();
01027         Vec2f v;
01028         if (x_mirror) v[0] = -matrix[0][3];
01029         else v[0] = matrix[0][3];
01030         v[1] = matrix[1][3];
01031         return v;
01032 }

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 796 of file transform.cpp.

References get_rotation(), get_trans(), set_rotation(), set_trans(), and EMAN::Vec3f.

00796                                                {
00797 
00798         Dict rot = get_rotation("eman");
00799         rot["alt"] = 180.0f + static_cast<float>(rot["alt"]);
00800         rot["phi"] = - static_cast<float>(rot["phi"]);
00801 
00802         Transform ret(*this);
00803         ret.set_rotation(rot);
00804 
00805         Vec3f trans = get_trans();
00806         trans[1] = -trans[1];
00807         ret.set_trans(trans);
00808 
00809         return ret;
00810 }

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

Definition at line 67 of file transform.cpp.

References set_rotation(), and t.

00067                                  {
00068         Transform t;
00069         Dict d;
00070         d["type"] = "eman";
00071         d["phi"] = 0;
00072         d["az"] = 90.0f;
00073         d["alt"] = 31.717474; // 5 fold to the nearest 2-fold
00085         t.set_rotation(d);
00086         return t;
00087 }

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 276 of file transform.cpp.

References permissable_2d_not_rot, permissable_3d_not_rot, and permissable_rot_keys.

Referenced by detect_problem_keys().

00277 {
00278 
00279         permissable_2d_not_rot.push_back("tx");
00280         permissable_2d_not_rot.push_back("ty");
00281         permissable_2d_not_rot.push_back("scale");
00282         permissable_2d_not_rot.push_back("mirror");
00283         permissable_2d_not_rot.push_back("type");
00284 
00285         permissable_3d_not_rot.push_back("tx");
00286         permissable_3d_not_rot.push_back("ty");
00287         permissable_3d_not_rot.push_back("tz");
00288         permissable_3d_not_rot.push_back("scale");
00289         permissable_3d_not_rot.push_back("mirror");
00290         permissable_3d_not_rot.push_back("type");
00291 
00292         vector<string> tmp;
00293         tmp.push_back("alpha");
00294         permissable_rot_keys["2d"] = tmp;
00295 
00296         tmp.clear();
00297         tmp.push_back("alt");
00298         tmp.push_back("az");
00299         tmp.push_back("phi");
00300         permissable_rot_keys["eman"] = tmp;
00301 
00302         tmp.clear();
00303         tmp.push_back("psi");
00304         tmp.push_back("theta");
00305         tmp.push_back("phi");
00306         permissable_rot_keys["spider"] = tmp;
00307 
00308         tmp.clear();
00309         tmp.push_back("alpha");
00310         tmp.push_back("beta");
00311         tmp.push_back("gamma");
00312         permissable_rot_keys["imagic"] = tmp;
00313 
00314         tmp.clear();
00315         tmp.push_back("ztilt");
00316         tmp.push_back("xtilt");
00317         tmp.push_back("ytilt");
00318         permissable_rot_keys["xyz"] = tmp;
00319 
00320         tmp.clear();
00321         tmp.push_back("phi");
00322         tmp.push_back("theta");
00323         tmp.push_back("omega");
00324         permissable_rot_keys["mrc"] = tmp;
00325 
00326         tmp.clear();
00327         tmp.push_back("e0");
00328         tmp.push_back("e1");
00329         tmp.push_back("e2");
00330         tmp.push_back("e3");
00331         permissable_rot_keys["quaternion"] = tmp;
00332 
00333         tmp.clear();
00334         tmp.push_back("n1");
00335         tmp.push_back("n2");
00336         tmp.push_back("n3");
00337         tmp.push_back("Omega");
00338         permissable_rot_keys["spin"] = tmp;
00339 
00340         tmp.clear();
00341         tmp.push_back("n1");
00342         tmp.push_back("n2");
00343         tmp.push_back("n3");
00344         tmp.push_back("q");
00345         permissable_rot_keys["sgirot"] = tmp;
00346 
00347         tmp.clear();
00348         tmp.push_back("m11");
00349         tmp.push_back("m12");
00350         tmp.push_back("m13");
00351         tmp.push_back("m21");
00352         tmp.push_back("m22");
00353         tmp.push_back("m23");
00354         tmp.push_back("m31");
00355         tmp.push_back("m32");
00356         tmp.push_back("m33");
00357         permissable_rot_keys["matrix"] = tmp;
00358 }

Transform Transform::inverse  )  const
 

Get the inverse of this transformation matrix.

Returns:
the inverse of this transformation matrix

Definition at line 1268 of file transform.cpp.

References invert(), and t.

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

01268                                    {
01269         Transform t(*this);
01270         t.invert();
01271         return t;
01272 }

void Transform::invert  ) 
 

Get the inverse of this transformation matrix.

Returns:
the inverse of this transformation matrix

Definition at line 1234 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(), inverse(), EMAN::GaussFFTProjector::project3d(), EMAN::Symmetry3D::reduce(), rotate_origin_newBasis(), set_params_inverse(), set_pre_trans(), translate_newBasis(), and EMAN::RT3DSphereAligner::xform_align_nbest().

01234                        {
01235 
01236         double m00 = matrix[0][0]; double m01=matrix[0][1]; double m02=matrix[0][2];
01237         double m10 = matrix[1][0]; double m11=matrix[1][1]; double m12=matrix[1][2];
01238         double m20 = matrix[2][0]; double m21=matrix[2][1]; double m22=matrix[2][2];
01239         double v0  = matrix[0][3]; double v1 =matrix[1][3]; double v2 =matrix[2][3];
01240 
01241         double cof00 = m11*m22-m12*m21;
01242         double cof11 = m22*m00-m20*m02;
01243         double cof22 = m00*m11-m01*m10;
01244         double cof01 = m10*m22-m20*m12;
01245         double cof02 = m10*m21-m20*m11;
01246         double cof12 = m00*m21-m01*m20;
01247         double cof10 = m01*m22-m02*m21;
01248         double cof20 = m01*m12-m02*m11;
01249         double cof21 = m00*m12-m10*m02;
01250 
01251         double det = m00* cof00 + m02* cof02 -m01*cof01;
01252 
01253         matrix[0][0] =   (float)(cof00/det);
01254         matrix[0][1] = - (float)(cof10/det);
01255         matrix[0][2] =   (float)(cof20/det);
01256         matrix[1][0] = - (float)(cof01/det);
01257         matrix[1][1] =   (float)(cof11/det);
01258         matrix[1][2] = - (float)(cof21/det);
01259         matrix[2][0] =   (float)(cof02/det);
01260         matrix[2][1] = - (float)(cof12/det);
01261         matrix[2][2] =   (float)(cof22/det);
01262 
01263         matrix[0][3] =  (float)((- cof00*v0 + cof10*v1 - cof20*v2)/det);
01264         matrix[1][3] =  (float)((  cof01*v0 - cof11*v1 + cof21*v2)/det);
01265         matrix[2][3] =  (float)((- cof02*v0 + cof12*v1 - cof22*v2)/det);
01266 }

bool Transform::is_identity  )  const
 

Returns whethers or this matrix is the identity.

Definition at line 213 of file transform.cpp.

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

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

00213                                   {
00214         for(int i=0; i<3; ++i) {
00215                 for(int j=0; j<4; ++j) {
00216                         float c = matrix[i][j];
00217                         Util::apply_precision(c,ERR_LIMIT);
00218                         if(i==j) {
00219                                 if (c != 1.0) return false;
00220                         }
00221                         else {
00222                                 if (c != 0.0) return false;
00223                         }
00224                 }
00225         }
00226         return true;
00227 }

bool Transform::is_rot_identity  )  const
 

Returns whethers or this matrix rotation is the identity.

Definition at line 229 of file transform.cpp.

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

00229                                       {
00230         for(int i=0; i<3; ++i) {
00231                 for(int j=0; j<3; ++j) {
00232                         float c = matrix[i][j];
00233                         Util::apply_precision(c,ERR_LIMIT);
00234                         if(i==j) {
00235                                 if (c != 1.0) return false;
00236                         }
00237                         else {
00238                                 if (c != 0.0) return false;
00239                         }
00240                 }
00241         }
00242         return true;
00243 }

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 767 of file transform.cpp.

References set(), and t.

00768 {
00769         Transform t(*this);
00770         for(unsigned int i = 0; i < 3; ++i) {
00771                 for(unsigned int j = 0; j < 4; ++j) {
00772                         t.set(i,j,t[i][j]*-1);
00773                 }
00774         }
00775         return t;
00776 }

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 131 of file transform.cpp.

References operator==(), and rhs.

00131                                                     {
00132         return !(operator==(rhs));
00133 }

Transform & Transform::operator= const Transform that  ) 
 

Assignment operator.

Parameters:
that that which this will become

Definition at line 114 of file transform.cpp.

References matrix.

00114                                                       {
00115         if (this != &that ) {
00116                 memcpy(matrix,that.matrix,12*sizeof(float));
00117 //              transform_type = that.transform_type;
00118         }
00119         return *this;
00120 }

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 122 of file transform.cpp.

References matrix, and rhs.

Referenced by operator!=().

00122                                                     {
00123         if (memcmp(this->matrix, rhs.matrix, 3*4*sizeof(float)) == 0) {
00124                 return true;
00125         }
00126         else {
00127                 return false;
00128         }
00129 }

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

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

Definition at line 415 of file transform.h.

References matrix().

00415 { return matrix[i]; }

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

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

Definition at line 410 of file transform.h.

References matrix().

00410 { 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 1120 of file transform.cpp.

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

01121 {
01122         float scale;
01123         bool x_mirror;
01124         get_scale_and_mirror(scale,x_mirror);
01125         if (scale == 0) throw UnexpectedBehaviorException("The determinant of the Transform is 0. This is unexpected.");
01126         double inv_scale = 1.0/static_cast<double>(scale);
01127         double mirror_scale = (x_mirror == true ? -1.0:1.0);
01128 
01129         gsl_matrix * R = gsl_matrix_calloc(3,3);
01130         for ( unsigned int i = 0; i < 3; ++i )
01131         {
01132                 for ( unsigned int j = 0; j < 3; ++j )
01133                 {
01134                         if (i == 0 && mirror_scale != 1.0 ) {
01135                                 gsl_matrix_set( R, i, j, static_cast<double>(matrix[i][j])*mirror_scale*inv_scale );
01136                         }
01137                         else {
01138                                 gsl_matrix_set( R, i, j, static_cast<double>(matrix[i][j])*inv_scale );
01139                         }
01140                 }
01141         }
01142 
01143         gsl_matrix * V = gsl_matrix_calloc(3,3);
01144         gsl_vector * S = gsl_vector_calloc(3);
01145         gsl_vector * work = gsl_vector_calloc(3);
01146         gsl_linalg_SV_decomp (R, V, S, work); // Now R is U of the SVD R = USV^T
01147 
01148         gsl_matrix * Soln = gsl_matrix_calloc(3,3);
01149         gsl_blas_dgemm (CblasNoTrans, CblasTrans, 1.0, R, V, 0.0, Soln);
01150 
01151         for ( unsigned int i = 0; i < 3; ++i )
01152         {
01153                 for ( unsigned int j = 0; j < 3; ++j )
01154                 {
01155                         matrix[i][j] = static_cast<float>( gsl_matrix_get(Soln,i,j) );
01156                 }
01157         }
01158 
01159         // Apply scale if it existed previously
01160         if (scale != 1.0f) {
01161                 for(int i=0; i<3; ++i) {
01162                         for(int j=0; j<3; ++j) {
01163                                 matrix[i][j] *= scale;
01164                         }
01165                 }
01166         }
01167 
01168         // Apply post x mirroring if it was applied previouslys
01169         if ( x_mirror ) {
01170                 for(int j=0; j<3; ++j) {
01171                         matrix[0][j] *= -1.0f;
01172                 }
01173         }
01174 
01175         gsl_matrix_free(V); gsl_matrix_free(R); gsl_matrix_free(Soln);
01176         gsl_vector_free(S); gsl_vector_free(work);
01177 }

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

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

Definition at line 356 of file transform.h.

References matrix().

00356                                              {
00357                                 printf("%8.6f %8.6f %8.6f %8.6f\n",matrix[0][0],matrix[0][1],matrix[0][2],matrix[0][3]);
00358                                 printf("%8.6f %8.6f %8.6f %8.6f\n",matrix[1][0],matrix[1][1],matrix[1][2],matrix[1][3]);
00359                                 printf("%8.6f %8.6f %8.6f %8.6f\n",matrix[2][0],matrix[2][1],matrix[2][2],matrix[2][3]);
00360                                 printf("%8.6f %8.6f %8.6f %8.6f\n",0.0,0.0,0.0,1.0);
00361 
00362                         }

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 749 of file transform.cpp.

References get_matrix(), and matrix.

00750 {
00751         vector<float> multmatrix = by.get_matrix();
00752         // First Multiply and put the result in a temp matrix
00753         Transform result;
00754         for (int i=0; i<3; i++) {
00755                 for (int j=0; j<4; j++) {
00756                         result[i][j] = multmatrix[i*4]*matrix[0][j] +  multmatrix[i*4+1]*matrix[1][j] + multmatrix[i*4+2]*matrix[2][j];
00757                 }
00758         }
00759         //Then put the result from the tmep matrix in the original one
00760         for (int i=0; i<3; i++) {
00761                 for (int j=0; j<4; j++) {
00762                         matrix[i][j] = result[i][j];
00763                 }
00764         }
00765 }

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:
by multiplican, a tranform, R'', by which to multiply the current one, R' == R''R'

Definition at line 706 of file transform.cpp.

References get_matrix(), and matrix.

Referenced by rotate_origin_newBasis().

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

void Transform::rotate_origin_newBasis const Transform tcs,
const float &  Omega,
const float &  n1,
const float &  n2,
const float &  n3
 

Increment the rotation by multipling the rotation bit of the argument transfrom by the rotation part of the current transfrom This version rotates in the standard coordinate system, even after it have been modified by tcs.

The effect is to undo the distortion casued by dcs. Useful in the scenegraph

Parameters:
tcs,the stansfrom that moves us to a non standard coordinate system
by multiplican, a tranform, R'', by which to multiply the current one, R' == R''R'

Definition at line 724 of file transform.cpp.

References get_trans(), invert(), rotate_origin(), set_scale(), set_trans(), Transform(), and EMAN::Vec3f.

00725 {
00726         //Get the rotational inverse
00727         Transform tcsinv = Transform(tcs);
00728         tcsinv.set_trans(0.0, 0.0, 0.0);
00729         tcsinv.set_scale(1.0);
00730         tcsinv.invert();
00731         
00732         //Get the current rotation
00733         Transform temp = Transform();
00734         temp.set_trans(n1, n2, n3);
00735         Transform cc = tcsinv*temp;
00736         Vec3f cctrans = cc.get_trans();
00737         
00738         //set the right rotation
00739         Dict spinrot = Dict();
00740         spinrot["type"] = "spin";
00741         spinrot["Omega"] = Omega;
00742         spinrot["n1"] = cctrans[0];
00743         spinrot["n2"] = cctrans[1];
00744         spinrot["n3"] = cctrans[2];
00745         Transform rightrot = Transform(spinrot);
00746         rotate_origin(rightrot);
00747 }

void Transform::scale const float &  scale  ) 
 

Increment the scale.

Parameters:
scale the amount increment by

Definition at line 1095 of file transform.cpp.

References get_determinant(), and set_scale().

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

01096 {
01097         float determinant = get_determinant();
01098         if (determinant < 0) determinant *= -1.0f;
01099         float newscale = std::pow(determinant,1.0f/3.0f) + scale;
01100         //IF scale is < 0.01 The det can sometime be computed to be 0 (The precission is a bit Rubbish here)
01101         if(newscale > 0.01) 
01102         {
01103                 //cout << newscale << endl;
01104                 set_scale(newscale); // If scale ~ 0 things blowup, so we need a little fudge factor
01105         }
01106 }

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 405 of file transform.h.

References matrix().

Referenced by EMAN::PointArray::align_2d(), and negate().

00405 { 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 150 of file transform.cpp.

References InvalidParameterException, matrix, and v.

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

00151 {
00152         if (v.size() != 12 ) throw InvalidParameterException("The construction array must be of size 12");
00153 
00154         for(int i=0; i<3; ++i) {
00155                 for(int j=0; j<4; ++j) {
00156                         matrix[i][j] = v[i*4+j];
00157                 }
00158         }
00159 }

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 1179 of file transform.cpp.

References get_mirror(), and matrix.

Referenced by EMAN::RTFSlowExhaustiveAligner::align(), EMAN::RTFExhaustiveAligner::align(), EMAN::RotateFlipAlignerIterative::align(), EMAN::RotateFlipAligner::align(), EMAN::RotateTranslateFlipAlignerIterative::align(), EMAN::RotateTranslateFlipAligner::align(), EMAN::WienerFourierReconstructor::determine_slice_agreement(), EMAN::FourierReconstructor::determine_slice_agreement(), get_rotation_transform(), EMAN::WienerFourierReconstructor::insert_slice(), EMAN::FourierReconstructor::insert_slice(), refalifn(), set_params(), and set_params_inverse().

01179                                                {
01180 
01181         bool old_x_mirror = get_mirror();
01182         if (old_x_mirror == x_mirror) return; // The user is setting the same value
01183         else {
01184                 // Toggle the mirroring operation
01185                 for (int j = 0; j < 4; ++j ) {
01186                         matrix[0][j] *= -1;
01187                 }
01188         }
01189 }

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 245 of file transform.cpp.

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

Referenced by Transform().

00245                                         {
00246         detect_problem_keys(d);
00247 
00248         if (d.has_key_ci("type") ) set_rotation(d);
00249 
00250         if (d.has_key_ci("scale")) {
00251                 float scale = static_cast<float>(d.get_ci("scale"));
00252                 set_scale(scale);
00253         }
00254 
00255         float dx=0,dy=0,dz=0;
00256 
00257         if (d.has_key_ci("tx")) dx = static_cast<float>(d.get_ci("tx"));
00258         if (d.has_key_ci("ty")) dy = static_cast<float>(d.get_ci("ty"));
00259         if (d.has_key_ci("tz")) dz = static_cast<float>(d.get_ci("tz"));
00260 
00261         if ( dx != 0.0 || dy != 0.0 || dz != 0.0 ) {
00262                 set_trans(dx,dy,dz);
00263         }
00264 
00265         if (d.has_key_ci("mirror")) {
00266                 EMObject e = d.get_ci("mirror");
00267                 if ( (e.get_type() != EMObject::BOOL ) && (e.get_type() != EMObject::INT ) && (e.get_type() != EMObject::UNSIGNEDINT ) )
00268                         throw InvalidParameterException("Error, mirror must be a bool or an int");
00269 
00270                 bool mirror = static_cast<bool>(e);
00271                 set_mirror(mirror);
00272         }
00273 }

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 417 of file transform.cpp.

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

00417                                                 {
00418         detect_problem_keys(d);
00419 
00420         if (d.has_key_ci("type") ) set_rotation(d);
00421 
00422         float dx=0,dy=0,dz=0;
00423         if (d.has_key_ci("tx")) dx = static_cast<float>(d.get_ci("tx"));
00424         if (d.has_key_ci("ty")) dy = static_cast<float>(d.get_ci("ty"));
00425         if (d.has_key_ci("tz")) dz = static_cast<float>(d.get_ci("tz"));
00426 
00427         if ( (dx != 0.0 || dy != 0.0 || dz != 0.0) && d.has_key_ci("type") ) {
00428                 Transform pre_trans;
00429                 pre_trans.set_trans(dx,dy,dz);
00430 
00431                 Transform tmp;
00432                 tmp.set_rotation(d);
00433 
00434                 if (d.has_key_ci("scale")) {
00435                         float scale = static_cast<float>(d.get_ci("scale"));
00436                         tmp.set_scale(scale);
00437                 }
00438 
00439                 Transform solution_trans = tmp*pre_trans;
00440 
00441                 if (d.has_key_ci("scale")) {
00442                         Transform tmp;
00443                         float scale = static_cast<float>(d.get_ci("scale"));
00444                         tmp.set_scale(scale);
00445                         solution_trans = solution_trans*tmp;
00446                 }
00447 
00448                 tmp = Transform();
00449                 tmp.set_rotation(d);
00450                 solution_trans = solution_trans*tmp;
00451                 set_trans(solution_trans.get_trans());
00452         }
00453 
00454         if (d.has_key_ci("scale")) {
00455                 float scale = static_cast<float>(d.get_ci("scale"));
00456                 set_scale(scale);
00457         }
00458 
00459         if (d.has_key_ci("mirror")) {
00460                 EMObject e = d.get_ci("mirror");
00461                 if ( (e.get_type() != EMObject::BOOL ) && (e.get_type() != EMObject::INT ) && (e.get_type() != EMObject::UNSIGNEDINT ) )
00462                         throw InvalidParameterException("Error, mirror must be a bool or an int");
00463 
00464                 bool mirror = static_cast<bool>(e);
00465                 set_mirror(mirror);
00466         }
00467         invert();
00468 }

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 559 of file transform.h.

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

Referenced by EMAN::RTFExhaustiveAligner::align(), EMAN::PointArray::align_2d(), and EMAN::EMData::rotate_translate().

00559                                                    {
00560 
00561                 Transform tmp;
00562                 Dict rot = get_rotation("eman");
00563                 tmp.set_rotation(rot);
00564 
00565                 float scale = get_scale();
00566                 if (scale != 1.0 ) tmp.set_scale(scale);
00567 
00568                 Transform trans;
00569                 trans.set_trans(v);
00570 
00571                 trans = tmp*trans;
00572 
00573                 Transform tmp2;
00574                 tmp2.set_rotation(rot);
00575                 tmp2.invert(); // invert
00576                 if (scale != 1.0 ) tmp2.set_scale(1.0f/scale);
00577 
00578 
00579                 trans = trans*tmp2;
00580 
00581                 set_trans(trans.get_trans());
00582         }

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 684 of file transform.cpp.

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

00685 {
00686         if ( v[0] == 0 && v[1] == 0 && v[2] == 0 )
00687                 throw UnexpectedBehaviorException("Can't set rotation for the null vector");
00688 
00689         Vec3f v1(v);
00690         v1.normalize();
00691 
00692         double theta = acos(v1[2]); // in radians
00693         double psi = atan2(v1[1],-v1[0]);
00694 
00695         Dict d;
00696         d["theta"] = (double)EMConsts::rad2deg*theta;
00697         d["psi"] = (double)EMConsts::rad2deg*psi;
00698         d["phi"] = (double)0.0;
00699         d["type"] = "spider";
00700 
00701         set_rotation(d);
00702 
00703 
00704 }

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 511 of file transform.cpp.

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

Referenced by EMAN::SymAlignProcessor::align(), EMAN::RotateTranslateAligner::align(), EMAN::RotatePrecenterAligner::align(), get_hflip_transform(), get_sym_proj(), get_vflip_transform(), icos_5_to_2(), EMAN::BackProjectionReconstructor::preprocess_slice(), EMAN::FourierReconstructor::preprocess_slice(), EMAN::TestTomoImage::process_inplace(), EMAN::EMData::rotate_translate(), set_params(), set_params_inverse(), set_pre_trans(), set_rotation(), tet_3_to_2(), and EMAN::RT3DSphereAligner::xform_align_nbest().

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

void Transform::set_scale const float &  scale  ) 
 

Set the scale.

Parameters:
scale the amount to scale by

Definition at line 1059 of file transform.cpp.

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

Referenced by EMAN::WienerFourierReconstructor::determine_slice_agreement(), EMAN::FourierReconstructor::determine_slice_agreement(), get_rotation_transform(), EMAN::WienerFourierReconstructor::insert_slice(), EMAN::FourierReconstructor::insert_slice(), main(), EMAN::ScaleTransformProcessor::process(), EMAN::ScaleTransformProcessor::process_inplace(), refalifn(), rotate_origin_newBasis(), scale(), EMAN::EMData::scale(), set_params(), set_params_inverse(), and set_pre_trans().

01059                                                 {
01060         if (new_scale <= 0) {
01061                 throw InvalidValueException(new_scale,"The scale factor in a Transform object must be positive and non zero");
01062         }
01063         // Transform = MTSR (Mirroring, Translation, Scaling, Rotate)
01064         // So changing the scale boils down to this....
01065 
01066         float old_scale = get_scale();
01067 
01068         float n_scale = new_scale;
01069         Util::apply_precision(n_scale,ERR_LIMIT);
01070 
01071         float corrected_scale = n_scale/old_scale;
01072         if ( corrected_scale != 1.0 ) {
01073                 for(int i = 0; i < 3;  ++i ) {
01074                         for(int j = 0; j < 3; ++j ) {
01075                                 matrix[i][j] *= corrected_scale;
01076                         }
01077                 }
01078         }
01079 }

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 229 of file transform.h.

References v, and EMAN::Vec2f.

00229 { 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 224 of file transform.h.

References v, and EMAN::Vec3f.

00224 { 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 972 of file transform.cpp.

References get_mirror(), and matrix.

Referenced by EMAN::Refine3DAlignerGrid::align(), EMAN::RTFSlowExhaustiveAligner::align(), EMAN::TranslationalAligner::align(), EMAN::WienerFourierReconstructor::determine_slice_agreement(), EMAN::FourierReconstructor::determine_slice_agreement(), EMAN::TestUtil::emobject_transformarray_to_py(), frm_2d_Align(), EMAN::TestUtil::get_debug_transform(), get_hflip_transform(), get_pre_trans(), get_pre_trans_2d(), get_rotation_transform(), EMAN::HSym::get_sym(), get_vflip_transform(), EMAN::WienerFourierReconstructor::insert_slice(), EMAN::FourierReconstructor::insert_slice(), EMAN::TestTomoImage::process_inplace(), EMAN::PhaseToMassCenterProcessor::process_inplace(), EMAN::ToMassCenterProcessor::process_inplace(), EMAN::MrcIO::read_mrc_header(), refalifn(), refalin3d_perturbquat(), rotate_origin_newBasis(), EMAN::EMData::rotate_translate(), set_params(), set_params_inverse(), set_pre_trans(), EMAN::EMData::translate(), translate_newBasis(), EMAN::RT3DSphereAligner::xform_align_nbest(), and EMAN::RT3DGridAligner::xform_align_nbest().

00973 {
00974         bool x_mirror = get_mirror();
00975 
00976         if (x_mirror) matrix[0][3] = -x;
00977         else matrix[0][3] = x;
00978         matrix[1][3] = y;
00979         matrix[2][3] = z;
00980 }

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

Definition at line 89 of file transform.cpp.

References set_rotation(), and t.

00089                                 {
00090         Transform t;
00091         Dict d;
00092         d["type"] = "eman";
00093         d["phi"] = 45.0f;
00094         d["az"] = 0.0f;
00095         d["alt"] = 54.73561f; // 3 fold to a 2 fold
00099         t.set_rotation(d);
00100         return t;
00101 }

void Transform::to_identity  ) 
 

Force the internal matrix to become the identity.

Definition at line 198 of file transform.cpp.

References matrix.

Referenced by Transform().

00199 {
00200 //      transform_type = UNKNOWN;
00201         for(int i=0; i<3; ++i) {
00202                 for(int j=0; j<4; ++j) {
00203                         if(i==j) {
00204                                 matrix[i][j] = 1;
00205                         }
00206                         else {
00207                                 matrix[i][j] = 0;
00208                         }
00209                 }
00210         }
00211 }

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 459 of file transform.h.

References v, and EMAN::Vec3f.

00459                                                                           {
00460 //                              assert_consistent_type(THREED); // Transform does the assertion
00461                                 return transform(v[0],v[1],v[2]);
00462                         }

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 445 of file transform.h.

References matrix(), EMAN::Vec3f, x, and y.

00445                                                                                                      {
00446 //                              assert_consistent_type(THREED);
00447                                 Vec3f ret;
00448                                 ret[0] = matrix[0][0] * x + matrix[0][1] * y + matrix[0][2] * z + matrix[0][3];
00449                                 ret[1] = matrix[1][0] * x + matrix[1][1] * y + matrix[1][2] * z + matrix[1][3];
00450                                 ret[2] = matrix[2][0] * x + matrix[2][1] * y + matrix[2][2] * z + matrix[2][3];
00451                                 return ret;
00452                         }

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 435 of file transform.h.

References v, and EMAN::Vec2f.

00435                                                                           {
00436                                 return transform(v[0],v[1]);
00437                         }

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 422 of file transform.h.

References matrix(), EMAN::Vec2f, x, and y.

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

00422                                                                                      {
00423 //                              assert_valid_2d();
00424                                 Vec2f ret;
00425                                 ret[0] = matrix[0][0]*x + matrix[0][1]*y + matrix[0][3];
00426                                 ret[1] = matrix[1][0]*x + matrix[1][1]*y + matrix[1][3];
00427                                 return ret;
00428                         }

void EMAN::Transform::translate const Transform tcs,
const Vec3f v
[inline]
 

Increment the current translation using vec3f& v and a non standard basis.

Parameters:
v the 3D translation vector

Definition at line 266 of file transform.h.

References v, and EMAN::Vec3f.

00266 { translate_newBasis(tcs, v[0],v[1],v[2]); }

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

Increment the current translation using vec2f& v.

Parameters:
v the translation vector

Definition at line 251 of file transform.h.

References v, and EMAN::Vec2f.

00251 { 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 246 of file transform.h.

References v, and EMAN::Vec3f.

00246 { 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 999 of file transform.cpp.

References get_mirror(), and matrix.

Referenced by translate_newBasis().

01000 {
01001         bool x_mirror = get_mirror();
01002         if (x_mirror) matrix[0][3] = -matrix[0][3] + tx;
01003         else matrix[0][3] = matrix[0][3] + tx;
01004         matrix[1][3] = matrix[1][3] + ty;
01005         matrix[2][3] = matrix[2][3] + tz;
01006 }

void Transform::translate_newBasis const Transform tcs,
const float &  tx,
const float &  ty,
const float &  tz = 0
 

Increment the current translation by tx, ty, tz using a non standard basis Actualy what it does is remove the effect of tcs when a composite transfrom tcs*t (where t is the current transform) This function is used in the scenegraph.

Parameters:
tcs the transform specifing the new basis vectors
tx the x incrementation
ty the y incrementation
tz the z incrementation

Definition at line 1008 of file transform.cpp.

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

01009 {
01010         //Get the rotational inverse
01011         Transform tcsinv = Transform(tcs);
01012         tcsinv.set_trans(0.0, 0.0, 0.0);
01013         tcsinv.invert();
01014         
01015         //Now move the coordinate system
01016         Transform temp = Transform();
01017         temp.set_trans(tx, ty, tz);
01018         Transform nb_trans = tcsinv*temp;
01019         
01020         translate(nb_trans.get_trans());
01021         
01022 }

Transform Transform::transpose  )  const
 

Get the transpose of this transformation matrix.

Returns:
the transpose of this transformation matrix

Definition at line 1287 of file transform.cpp.

References t, and transpose_inplace().

Referenced by EMAN::PointArray::right_transform(), and EMAN::PDBReader::right_transform().

01287                                      {
01288         Transform t(*this);
01289         t.transpose_inplace();
01290         return t;
01291 }

void Transform::transpose_inplace  ) 
 

Get the transpose of this transformation matrix.

Definition at line 1274 of file transform.cpp.

References matrix.

Referenced by transpose().

01274                                   {
01275         float tempij;
01276         for (int i = 0; i < 3; i++) {
01277                 for (int j = 0; j < i; j++) {
01278                         if (i != j) {
01279                                 tempij= matrix[i][j];
01280                                 matrix[i][j] = matrix[j][i];
01281                                 matrix[j][i] = tempij;
01282                         }
01283                 }
01284         }
01285 }


Member Data Documentation

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

Definition at line 61 of file transform.cpp.

Referenced by get_determinant(), get_scale(), get_scale_and_mirror(), get_trans(), is_identity(), is_rot_identity(), and set_scale().

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

Definition at line 506 of file transform.h.

Referenced by assert_valid_2d(), copy_matrix_into_array(), get_determinant(), get_matrix(), get_matrix_4x4(), get_rotation(), get_sym_proj(), get_trans(), get_trans_2d(), invert(), is_identity(), is_rot_identity(), operator=(), operator==(), orthogonalize(), rotate(), rotate_origin(), set_matrix(), set_mirror(), set_rotation(), set_scale(), set_trans(), to_identity(), 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 63 of file transform.cpp.

Referenced by detect_problem_keys(), and init_permissable_keys().

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

Definition at line 64 of file transform.cpp.

Referenced by detect_problem_keys(), and init_permissable_keys().

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

Definition at line 65 of file transform.cpp.

Referenced by detect_problem_keys(), and init_permissable_keys().


The documentation for this class was generated from the following files:
Generated on Thu Nov 17 12:47:15 2011 for EMAN2 by  doxygen 1.3.9.1