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

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

Static Public Attributes

static const float ERR_LIMIT = 0.000001f

Private Member Functions

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

Private Attributes

float matrix [3][4]

Static Private Attributes

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


Detailed Description

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

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

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

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

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

Definition at line 83 of file transform.h.


Constructor & Destructor Documentation

Transform::Transform (  ) 

Default constructor Internal matrix is the identity.

Definition at line 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 1319 of file transform.cpp.

References ERR_LIMIT, matrix, and UnexpectedBehaviorException.

Referenced by get_rotation(), and set_rotation().

01319                                       {
01320         int rotation_error = 0;
01321         int translation_error = 0;
01322         if (fabs(matrix[2][0]) > ERR_LIMIT) rotation_error++;
01323         if (fabs(matrix[2][1]) > ERR_LIMIT) rotation_error++;
01324         if (fabs(matrix[2][3]) > ERR_LIMIT) translation_error++;
01325         if (fabs(matrix[0][2]) > ERR_LIMIT) rotation_error++;
01326         if (fabs(matrix[1][2]) > ERR_LIMIT) rotation_error++;
01327 //      if (fabs(matrix[2][2]-1.0) >ERR_LIMIT) rotation_error++; 
01328         if ( translation_error && rotation_error ) {
01329                 throw UnexpectedBehaviorException("Error, the internal matrix contains 3D rotations and 3D translations. This object can not be considered 2D");
01330         } else if ( translation_error ) {
01331                 throw UnexpectedBehaviorException("Error, the internal matrix contains a non zero z component for a 3D translation. This object can not be considered 2D");
01332         }
01333         else if ( rotation_error ) {
01334                 throw UnexpectedBehaviorException("Error, the internal matrix contains 3D rotations and this object can not be considered 2D");
01335         }
01336 
01337 }

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

01233 {
01234         float det;
01235         double det2;
01236         det2  = matrix[0][0]*((double)matrix[1][1]*matrix[2][2]-(double)matrix[2][1]*matrix[1][2]);
01237         det2 -= matrix[0][1]*((double)matrix[1][0]*matrix[2][2]-(double)matrix[2][0]*matrix[1][2]);
01238         det2 += matrix[0][2]*((double)matrix[1][0]*matrix[2][1]-(double)matrix[2][0]*matrix[1][1]);
01239 
01240         det = (float)det2;
01241         Util::apply_precision(det,ERR_LIMIT);
01242 
01243         return det;
01244 }

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(), and get_trans().

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        // This is the same as new_alt= 180-alt, new_phi=-phi, new_az=180+az
00784 
00785         Transform ret(*this); // Is the identity
00786         ret.set_rotation(rot);
00787 
00788         Vec3f trans = get_trans();
00789         trans[0] = -trans[0];
00790         ret.set_trans(trans);
00791 
00792 //      ret.set_mirror(self.get_mirror());
00793 
00794         return ret;
00795 }

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::Util::BPCQ(), 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.

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

01203                                  {
01204         float determinant = get_determinant();
01205 
01206         bool x_mirror = false;
01207         if ( determinant < 0 ) x_mirror = true;
01208 
01209         return x_mirror;
01210 
01211 }

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

get the number of symmetries associated with the given symmetry name

Definition at line 1469 of file transform.cpp.

References EMAN::Symmetry3D::get_nsym().

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

01470 {
01471         Symmetry3D* sym = Factory<Symmetry3D>::get(sym_name);
01472         int nsym = sym->get_nsym();
01473         delete sym;
01474         return nsym;
01475 }

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(), and v.

Referenced by EMAN::Util::BPCQ(), compose_transform2(), and EMAN::Util::get_transform_params().

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(), and v.

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

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

Referenced by get_params_inverse().

01054 {
01055         Transform T(*this);
01056         T.set_trans(0,0,0);
01057         T.invert();
01058 
01059         Transform soln  = T*(*this);
01060 //      soln.printme();
01061         return soln.get_trans();
01062 }

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

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

01065 {
01066         Transform T(*this);
01067         T.set_trans(0,0,0);
01068         T.invert();
01069 
01070         Transform soln  = T*(*this);
01071 //      soln.printme();
01072         return soln.get_trans_2d();
01073 }

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

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

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

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

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

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

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

01098                                  {
01099         float determinant = get_determinant();
01100         if (determinant < 0 ) determinant *= -1;
01101 
01102         float scale = std::pow(determinant,1.0f/3.0f);
01103         int int_scale = static_cast<int>(scale);
01104         float scale_residual = scale-static_cast<float>(int_scale);
01105         if  ( scale_residual < ERR_LIMIT ) { scale = static_cast<float>(int_scale); };
01106 
01107         Util::apply_precision(scale, ERR_LIMIT);
01108 
01109         return scale;
01110 }

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

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

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

01213                                                                        {
01214 
01215         float determinant = get_determinant();
01216         x_mirror = false;
01217         if ( determinant < 0 ) {
01218                 x_mirror = true;
01219                 determinant *= -1;
01220         }
01221         if (determinant != 1 ) {
01222                 scale = std::pow(determinant,1.0f/3.0f);
01223                 int int_scale = static_cast<int>(scale);
01224                 float scale_residual = scale-static_cast<float>(int_scale);
01225                 if  ( scale_residual < ERR_LIMIT ) { scale = static_cast<float>(int_scale); };
01226         }
01227         else scale = 1;
01228 
01229         Util::apply_precision(scale,ERR_LIMIT);
01230 }

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

References EMAN::Symmetry3D::get_sym().

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

01342 {
01343         Symmetry3D* sym = Factory<Symmetry3D>::get(sym_name);
01344         Transform ret;
01345         ret = (*this) * sym->get_sym(n);
01346         delete sym;
01347         return ret;
01348 }

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

Definition at line 1350 of file transform.cpp.

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

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

Vec3f Transform::get_trans (  )  const

Get the post trans as a vec3f.

Returns:
the translation vector

Definition at line 999 of file transform.cpp.

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

Referenced by get_hflip_transform(), get_params(), get_pre_trans(), get_vflip_transform(), EMAN::GaussFFTProjector::project3d(), rotate_origin_newBasis(), set_params_inverse(), and translate_newBasis().

01000 {
01001         // No type asserted
01002         bool x_mirror = get_mirror();
01003         Vec3f v;
01004         if (x_mirror) v[0] = -matrix[0][3];
01005         else v[0] = matrix[0][3];
01006         v[1] = matrix[1][3];
01007         v[2] = matrix[2][3];
01008 
01009         Util::apply_precision(v[0],ERR_LIMIT);
01010         Util::apply_precision(v[1],ERR_LIMIT);
01011         Util::apply_precision(v[2],ERR_LIMIT);
01012 
01013         return v;
01014 }

Vec2f Transform::get_trans_2d (  )  const

Get the degenerant 2D post trans as a vec2f.

Returns:
the 2D translation vector

Definition at line 1041 of file transform.cpp.

References get_mirror(), matrix, and v.

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

01042 {
01043         bool x_mirror = get_mirror();
01044         Vec2f v;
01045         if (x_mirror) v[0] = -matrix[0][3];
01046         else v[0] = matrix[0][3];
01047         v[1] = matrix[1][3];
01048         return v;
01049 }

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

References get_rotation(), and get_trans().

00797                                                {
00798 
00799         Dict rot = get_rotation("eman");
00800         rot["alt"] = 180.0f + static_cast<float>(rot["alt"]);
00801         rot["phi"] = - static_cast<float>(rot["phi"]);
00802         
00803        // This is the same as new_alt= 180-alt, new_phi=180-phi, new_az=180+az
00804 
00805         Transform ret(*this);
00806         ret.set_rotation(rot);
00807 
00808         Vec3f trans = get_trans();
00809         trans[1] = -trans[1];
00810         ret.set_trans(trans);
00811 
00812         return ret;
00813 }

Transform Transform::icos_5_to_2 (  )  [static]

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

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

Doctor Steve says Phil's answer put the 2-fold in the wrong place based on the standard Virus convention (empirically). It was also 2 to 5 not 5 to 2. It is possible to rotate to a 2-fold directly from a 5-fold, though there are 2 possible orientations for the 2-2-2 convention, and this finds only one of them :^(

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

Definition at line 67 of file transform.cpp.

References t.

00067                                  {
00068         Transform t;
00069         Dict d;
00070         d["type"] = "eman";
00071         d["phi"] = 0;
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 1280 of file transform.cpp.

References t.

Referenced by get_params_inverse(), EMAN::EMData::max_3D_pixel_error(), EMAN::RotateInFSProcessor::process_inplace(), EMAN::MaxValProjector::project3d(), and EMAN::StandardProjector::project3d().

01280                                    {
01281         Transform t(*this);
01282         t.invert();
01283         return t;
01284 }

void Transform::invert (  ) 

Get the inverse of this transformation matrix.

Returns:
the inverse of this transformation matrix

Definition at line 1246 of file transform.cpp.

References matrix, and v0.

Referenced by get_pre_trans(), get_pre_trans_2d(), EMAN::Symmetry3D::in_which_asym_unit(), EMAN::BackProjectionReconstructor::insert_slice(), EMAN::GaussFFTProjector::project3d(), EMAN::Symmetry3D::reduce(), rotate_origin_newBasis(), set_params_inverse(), set_pre_trans(), and translate_newBasis().

01246                        {
01247 
01248         double m00 = matrix[0][0]; double m01=matrix[0][1]; double m02=matrix[0][2];
01249         double m10 = matrix[1][0]; double m11=matrix[1][1]; double m12=matrix[1][2];
01250         double m20 = matrix[2][0]; double m21=matrix[2][1]; double m22=matrix[2][2];
01251         double v0  = matrix[0][3]; double v1 =matrix[1][3]; double v2 =matrix[2][3];
01252 
01253         double cof00 = m11*m22-m12*m21;
01254         double cof11 = m22*m00-m20*m02;
01255         double cof22 = m00*m11-m01*m10;
01256         double cof01 = m10*m22-m20*m12;
01257         double cof02 = m10*m21-m20*m11;
01258         double cof12 = m00*m21-m01*m20;
01259         double cof10 = m01*m22-m02*m21;
01260         double cof20 = m01*m12-m02*m11;
01261         double cof21 = m00*m12-m10*m02;
01262 
01263         double det = m00* cof00 + m02* cof02 -m01*cof01;
01264 
01265         matrix[0][0] =   (float)(cof00/det);
01266         matrix[0][1] = - (float)(cof10/det);
01267         matrix[0][2] =   (float)(cof20/det);
01268         matrix[1][0] = - (float)(cof01/det);
01269         matrix[1][1] =   (float)(cof11/det);
01270         matrix[1][2] = - (float)(cof21/det);
01271         matrix[2][0] =   (float)(cof02/det);
01272         matrix[2][1] = - (float)(cof12/det);
01273         matrix[2][2] =   (float)(cof22/det);
01274 
01275         matrix[0][3] =  (float)((- cof00*v0 + cof10*v1 - cof20*v2)/det);
01276         matrix[1][3] =  (float)((  cof01*v0 - cof11*v1 + cof21*v2)/det);
01277         matrix[2][3] =  (float)((- cof02*v0 + cof12*v1 - cof22*v2)/det);
01278 }

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

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

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

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(), and Transform().

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

References get_determinant(), and set_scale().

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

01113 {
01114         float determinant = get_determinant();
01115         if (determinant < 0) determinant *= -1.0f;
01116         float newscale = std::pow(determinant,1.0f/3.0f) + scale;
01117         if(newscale > 0.0001) set_scale(newscale); // If scale ~ 0 things blowup, so we need a little fudge factor
01118 }

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

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, and matrix.

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

References get_mirror(), and matrix.

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

01191                                                {
01192 
01193         bool old_x_mirror = get_mirror();
01194         if (old_x_mirror == x_mirror) return; // The user is setting the same value
01195         else {
01196                 // Toggle the mirroring operation
01197                 for (int j = 0; j < 4; ++j ) {
01198                         matrix[0][j] *= -1;
01199                 }
01200         }
01201 }

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 EMAN::EMObject::BOOL, detect_problem_keys(), EMAN::Dict::get_ci(), EMAN::Dict::has_key_ci(), EMAN::EMObject::INT, InvalidParameterException, scale(), set_mirror(), set_rotation(), set_scale(), set_trans(), and EMAN::EMObject::UNSIGNEDINT.

Referenced by Transform().

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 EMAN::EMObject::BOOL, detect_problem_keys(), EMAN::Dict::get_ci(), get_trans(), EMAN::Dict::has_key_ci(), EMAN::EMObject::INT, InvalidParameterException, invert(), scale(), set_mirror(), set_rotation(), set_scale(), set_trans(), Transform(), and EMAN::EMObject::UNSIGNEDINT.

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(), and set_trans().

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

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(), EMAN::EMConsts::rad2deg, set_rotation(), theta, UnexpectedBehaviorException, and v.

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(), EMAN::EMConsts::deg2rad, detect_problem_keys(), EMAN::Dict::get_ci(), get_scale_and_mirror(), EMAN::Dict::has_key_ci(), InvalidParameterException, InvalidStringException, matrix, phi, scale(), EMAN::Util::str_to_lower(), and UnexpectedBehaviorException.

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

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

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

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

01076                                                 {
01077         if (new_scale <= 0) {
01078                 throw InvalidValueException(new_scale,"The scale factor in a Transform object must be positive and non zero");
01079         }
01080         // Transform = MTSR (Mirroring, Translation, Scaling, Rotate)
01081         // So changing the scale boils down to this....
01082 
01083         float old_scale = get_scale();
01084 
01085         float n_scale = new_scale;
01086         Util::apply_precision(n_scale,ERR_LIMIT);
01087 
01088         float corrected_scale = n_scale/old_scale;
01089         if ( corrected_scale != 1.0 ) {
01090                 for(int i = 0; i < 3;  ++i ) {
01091                         for(int j = 0; j < 3; ++j ) {
01092                                 matrix[i][j] *= corrected_scale;
01093                         }
01094                 }
01095         }
01096 }

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 set_trans(), and v.

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 set_trans(), and v.

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

References get_mirror(), and matrix.

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

00990 {
00991         bool x_mirror = get_mirror();
00992 
00993         if (x_mirror) matrix[0][3] = -x;
00994         else matrix[0][3] = x;
00995         matrix[1][3] = y;
00996         matrix[2][3] = z;
00997 }

Transform Transform::tet_3_to_2 (  )  [static]

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

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

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

Definition at line 89 of file transform.cpp.

References 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 transform(), and v.

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.

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 transform(), and v.

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.

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

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 translate_newBasis(), and v.

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 translate(), and v.

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 translate(), and v.

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

References get_mirror(), and matrix.

Referenced by translate(), and translate_newBasis().

01017 {
01018         bool x_mirror = get_mirror();
01019         if (x_mirror) matrix[0][3] = -matrix[0][3] + tx;
01020         else matrix[0][3] = matrix[0][3] + tx;
01021         matrix[1][3] = matrix[1][3] + ty;
01022         matrix[2][3] = matrix[2][3] + tz;
01023 }

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

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

Referenced by translate().

01026 {
01027         //Get the rotational inverse
01028         Transform tcsinv = Transform(tcs);
01029         tcsinv.set_trans(0.0, 0.0, 0.0);
01030         tcsinv.invert();
01031         
01032         //Now move the coordinate system
01033         Transform temp = Transform();
01034         temp.set_trans(tx, ty, tz);
01035         Transform nb_trans = tcsinv*temp;
01036         
01037         translate(nb_trans.get_trans());
01038         
01039 }

Transform Transform::transpose (  )  const

Get the transpose of this transformation matrix.

Returns:
the transpose of this transformation matrix

Definition at line 1299 of file transform.cpp.

References t.

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

01299                                      {
01300         Transform t(*this);
01301         t.transpose_inplace();
01302         return t;
01303 }

void Transform::transpose_inplace (  ) 

Get the transpose of this transformation matrix.

Definition at line 1286 of file transform.cpp.

References matrix.

01286                                   {
01287         float tempij;
01288         for (int i = 0; i < 3; i++) {
01289                 for (int j = 0; j < i; j++) {
01290                         if (i != j) {
01291                                 tempij= matrix[i][j];
01292                                 matrix[i][j] = matrix[j][i];
01293                                 matrix[j][i] = tempij;
01294                         }
01295                 }
01296         }
01297 }


Member Data Documentation

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

Definition at line 86 of file transform.h.

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

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

Definition at line 506 of file transform.h.

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

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

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

Definition at line 511 of file transform.h.

Referenced by detect_problem_keys(), and init_permissable_keys().

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

Definition at line 512 of file transform.h.

Referenced by detect_problem_keys(), and init_permissable_keys().

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

Definition at line 513 of file transform.h.

Referenced by detect_problem_keys(), and init_permissable_keys().


The documentation for this class was generated from the following files:
Generated on Tue Jun 11 12:45:32 2013 for EMAN2 by  doxygen 1.4.7