00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "transform.h"
00037 #include "util.h"
00038 #include "emobject.h"
00039 #include <cctype>
00040 #include <cstring>
00041 #include "symmetry.h"
00042 using namespace EMAN;
00043
00044 #ifdef WIN32
00045 #ifndef M_PI
00046 #define M_PI 3.14159265358979323846
00047 #endif
00048 #endif
00049
00050 #include <algorithm>
00051
00052 #include <gsl_matrix.h>
00053 #include <gsl_blas.h>
00054 #include <gsl_linalg.h>
00055
00056 #include <ostream>
00057 using std::ostream_iterator;
00058
00059
00060
00061 const float Transform::ERR_LIMIT = 0.000001f;
00062
00063 vector<string> Transform::permissable_2d_not_rot;
00064 vector<string> Transform::permissable_3d_not_rot;
00065 map<string,vector<string> > Transform::permissable_rot_keys;
00066
00067 Transform Transform::icos_5_to_2() {
00068 Transform t;
00069 Dict d;
00070 d["type"] = "eman";
00071 d["phi"] = 0.0f;
00072 d["az"] = 270.0f;
00073 d["alt"] = 58.282523f;
00079 t.set_rotation(d);
00080 return t;
00081 }
00082
00083 Transform Transform::tet_3_to_2() {
00084 Transform t;
00085 Dict d;
00086 d["type"] = "eman";
00087 d["phi"] = 45.0f;
00088 d["az"] = 0.0f;
00089 d["alt"] = 54.73561f;
00093 t.set_rotation(d);
00094 return t;
00095 }
00096
00097
00098 Transform::Transform()
00099 {
00100 to_identity();
00101 }
00102
00103 Transform::Transform( const Transform& that )
00104 {
00105 *this = that;
00106 }
00107
00108 Transform& Transform::operator=(const Transform& that ) {
00109 if (this != &that ) {
00110 memcpy(matrix,that.matrix,12*sizeof(float));
00111
00112 }
00113 return *this;
00114 }
00115
00116 bool Transform::operator==(const Transform& rhs) const{
00117 if (memcmp(this->matrix, rhs.matrix, 3*4*sizeof(float)) == 0) {
00118 return true;
00119 }
00120 else {
00121 return false;
00122 }
00123 }
00124
00125 bool Transform::operator!=(const Transform& rhs) const{
00126 return !(operator==(rhs));
00127 }
00128
00129 Transform::Transform(const Dict& d) {
00130 to_identity();
00131 set_params(d);
00132 }
00133
00134
00135 Transform::Transform(const float array[12]) {
00136 memcpy(matrix,array,12*sizeof(float));
00137 }
00138
00139 Transform::Transform(const vector<float> array)
00140 {
00141 set_matrix(array);
00142 }
00143
00144 void Transform::set_matrix(const vector<float>& v)
00145 {
00146 if (v.size() != 12 ) throw InvalidParameterException("The construction array must be of size 12");
00147
00148 for(int i=0; i<3; ++i) {
00149 for(int j=0; j<4; ++j) {
00150 matrix[i][j] = v[i*4+j];
00151 }
00152 }
00153 }
00154
00155 void Transform::copy_matrix_into_array(float* const array) const {
00156
00157 int idx = 0;
00158 for(int i=0; i<3; ++i) {
00159 for(int j=0; j<4; ++j) {
00160 array[idx] = matrix[i][j];
00161 idx ++;
00162 }
00163 }
00164 }
00165
00166 vector<float> Transform::get_matrix() const
00167 {
00168 vector<float> ret(12);
00169 for(int i=0; i<3; ++i) {
00170 for(int j=0; j<4; ++j) {
00171 ret[i*4+j] = matrix[i][j];
00172 }
00173 }
00174 return ret;
00175 }
00176
00177 void Transform::to_identity()
00178 {
00179
00180 for(int i=0; i<3; ++i) {
00181 for(int j=0; j<4; ++j) {
00182 if(i==j) {
00183 matrix[i][j] = 1;
00184 }
00185 else {
00186 matrix[i][j] = 0;
00187 }
00188 }
00189 }
00190 }
00191
00192 bool Transform::is_identity() const {
00193 for(int i=0; i<3; ++i) {
00194 for(int j=0; j<4; ++j) {
00195 float c = matrix[i][j];
00196 Util::apply_precision(c,ERR_LIMIT);
00197 if(i==j) {
00198 if (c != 1.0) return false;
00199 }
00200 else {
00201 if (c != 0.0) return false;
00202 }
00203 }
00204 }
00205 return true;
00206 }
00207
00208
00209 void Transform::set_params(const Dict& d) {
00210 detect_problem_keys(d);
00211
00212 if (d.has_key_ci("type") ) set_rotation(d);
00213
00214 if (d.has_key_ci("scale")) {
00215 float scale = static_cast<float>(d.get_ci("scale"));
00216 set_scale(scale);
00217 }
00218
00219 float dx=0,dy=0,dz=0;
00220
00221 if (d.has_key_ci("tx")) dx = static_cast<float>(d.get_ci("tx"));
00222 if (d.has_key_ci("ty")) dy = static_cast<float>(d.get_ci("ty"));
00223 if (d.has_key_ci("tz")) dz = static_cast<float>(d.get_ci("tz"));
00224
00225 if ( dx != 0.0 || dy != 0.0 || dz != 0.0 ) {
00226 set_trans(dx,dy,dz);
00227 }
00228
00229 if (d.has_key_ci("mirror")) {
00230 EMObject e = d.get_ci("mirror");
00231 if ( (e.get_type() != EMObject::BOOL ) && (e.get_type() != EMObject::INT ) && (e.get_type() != EMObject::UNSIGNEDINT ) )
00232 throw InvalidParameterException("Error, mirror must be a bool or an int");
00233
00234 bool mirror = static_cast<bool>(e);
00235 set_mirror(mirror);
00236 }
00237 }
00238
00239
00240 void Transform::init_permissable_keys()
00241 {
00242
00243 permissable_2d_not_rot.push_back("tx");
00244 permissable_2d_not_rot.push_back("ty");
00245 permissable_2d_not_rot.push_back("scale");
00246 permissable_2d_not_rot.push_back("mirror");
00247 permissable_2d_not_rot.push_back("type");
00248
00249 permissable_3d_not_rot.push_back("tx");
00250 permissable_3d_not_rot.push_back("ty");
00251 permissable_3d_not_rot.push_back("tz");
00252 permissable_3d_not_rot.push_back("scale");
00253 permissable_3d_not_rot.push_back("mirror");
00254 permissable_3d_not_rot.push_back("type");
00255
00256 vector<string> tmp;
00257 tmp.push_back("alpha");
00258 permissable_rot_keys["2d"] = tmp;
00259
00260 tmp.clear();
00261 tmp.push_back("alt");
00262 tmp.push_back("az");
00263 tmp.push_back("phi");
00264 permissable_rot_keys["eman"] = tmp;
00265
00266 tmp.clear();
00267 tmp.push_back("psi");
00268 tmp.push_back("theta");
00269 tmp.push_back("phi");
00270 permissable_rot_keys["spider"] = tmp;
00271
00272 tmp.clear();
00273 tmp.push_back("alpha");
00274 tmp.push_back("beta");
00275 tmp.push_back("gamma");
00276 permissable_rot_keys["imagic"] = tmp;
00277
00278 tmp.clear();
00279 tmp.push_back("ztilt");
00280 tmp.push_back("xtilt");
00281 tmp.push_back("ytilt");
00282 permissable_rot_keys["xyz"] = tmp;
00283
00284 tmp.clear();
00285 tmp.push_back("phi");
00286 tmp.push_back("theta");
00287 tmp.push_back("omega");
00288 permissable_rot_keys["mrc"] = tmp;
00289
00290 tmp.clear();
00291 tmp.push_back("e0");
00292 tmp.push_back("e1");
00293 tmp.push_back("e2");
00294 tmp.push_back("e3");
00295 permissable_rot_keys["quaternion"] = tmp;
00296
00297 tmp.clear();
00298 tmp.push_back("n1");
00299 tmp.push_back("n2");
00300 tmp.push_back("n3");
00301 tmp.push_back("Omega");
00302 permissable_rot_keys["spin"] = tmp;
00303
00304 tmp.clear();
00305 tmp.push_back("n1");
00306 tmp.push_back("n2");
00307 tmp.push_back("n3");
00308 tmp.push_back("q");
00309 permissable_rot_keys["sgirot"] = tmp;
00310
00311 tmp.clear();
00312 tmp.push_back("m11");
00313 tmp.push_back("m12");
00314 tmp.push_back("m13");
00315 tmp.push_back("m21");
00316 tmp.push_back("m22");
00317 tmp.push_back("m23");
00318 tmp.push_back("m31");
00319 tmp.push_back("m32");
00320 tmp.push_back("m33");
00321 permissable_rot_keys["matrix"] = tmp;
00322 }
00323
00324
00325 void Transform::detect_problem_keys(const Dict& d) {
00326 if (permissable_rot_keys.size() == 0 ) {
00327 init_permissable_keys();
00328 }
00329
00330 vector<string> verification;
00331 vector<string> problem_keys;
00332 bool is_2d = false;
00333 if (d.has_key_ci("type") ) {
00334 string type = Util::str_to_lower((string)d["type"]);
00335 bool problem = false;
00336 if (permissable_rot_keys.find(type) == permissable_rot_keys.end() ) {
00337 problem_keys.push_back(type);
00338 problem = true;
00339 }
00340 if ( !problem ) {
00341 vector<string> perm = permissable_rot_keys[type];
00342 std::copy(perm.begin(),perm.end(),back_inserter(verification));
00343
00344 if ( type == "2d" ) {
00345 is_2d = true;
00346 std::copy(permissable_2d_not_rot.begin(),permissable_2d_not_rot.end(),back_inserter(verification));
00347 }
00348 }
00349 }
00350 if ( !is_2d ) {
00351 std::copy(permissable_3d_not_rot.begin(),permissable_3d_not_rot.end(),back_inserter(verification));
00352 }
00353
00354 for (Dict::const_iterator it = d.begin(); it != d.end(); ++it) {
00355 if ( std::find(verification.begin(),verification.end(), it->first) == verification.end() ) {
00356 problem_keys.push_back(it->first);
00357 }
00358 }
00359
00360 if (problem_keys.size() != 0 ) {
00361 string error;
00362 if (problem_keys.size() == 1) {
00363 error = "Transform Error: The \"" +problem_keys[0]+ "\" key is unsupported";
00364 } else {
00365 error = "Transform Error: The ";
00366 for(vector<string>::const_iterator cit = problem_keys.begin(); cit != problem_keys.end(); ++cit ) {
00367 if ( cit != problem_keys.begin() ) {
00368 if (cit == (problem_keys.end() -1) ) error += " and ";
00369 else error += ", ";
00370 }
00371 error += "\"";
00372 error += *cit;
00373 error += "\"";
00374 }
00375 error += " keys are unsupported";
00376 }
00377 throw InvalidParameterException(error);
00378 }
00379 }
00380
00381 void Transform::set_params_inverse(const Dict& d) {
00382 detect_problem_keys(d);
00383
00384 if (d.has_key_ci("type") ) set_rotation(d);
00385
00386 float dx=0,dy=0,dz=0;
00387 if (d.has_key_ci("tx")) dx = static_cast<float>(d.get_ci("tx"));
00388 if (d.has_key_ci("ty")) dy = static_cast<float>(d.get_ci("ty"));
00389 if (d.has_key_ci("tz")) dz = static_cast<float>(d.get_ci("tz"));
00390
00391 if ( (dx != 0.0 || dy != 0.0 || dz != 0.0) && d.has_key_ci("type") ) {
00392 Transform pre_trans;
00393 pre_trans.set_trans(dx,dy,dz);
00394
00395 Transform tmp;
00396 tmp.set_rotation(d);
00397
00398 if (d.has_key_ci("scale")) {
00399 float scale = static_cast<float>(d.get_ci("scale"));
00400 tmp.set_scale(scale);
00401 }
00402
00403 Transform solution_trans = tmp*pre_trans;
00404
00405 if (d.has_key_ci("scale")) {
00406 Transform tmp;
00407 float scale = static_cast<float>(d.get_ci("scale"));
00408 tmp.set_scale(scale);
00409 solution_trans = solution_trans*tmp;
00410 }
00411
00412 tmp = Transform();
00413 tmp.set_rotation(d);
00414 solution_trans = solution_trans*tmp;
00415 set_trans(solution_trans.get_trans());
00416 }
00417
00418 if (d.has_key_ci("scale")) {
00419 float scale = static_cast<float>(d.get_ci("scale"));
00420 set_scale(scale);
00421 }
00422
00423 if (d.has_key_ci("mirror")) {
00424 EMObject e = d.get_ci("mirror");
00425 if ( (e.get_type() != EMObject::BOOL ) && (e.get_type() != EMObject::INT ) && (e.get_type() != EMObject::UNSIGNEDINT ) )
00426 throw InvalidParameterException("Error, mirror must be a bool or an int");
00427
00428 bool mirror = static_cast<bool>(e);
00429 set_mirror(mirror);
00430 }
00431 invert();
00432 }
00433
00434
00435 Dict Transform::get_params(const string& euler_type) const {
00436 Dict params = get_rotation(euler_type);
00437
00438 Vec3f v = get_trans();
00439 params["tx"] = v[0]; params["ty"] = v[1];
00440
00441 string type = Util::str_to_lower(euler_type);
00442 if ( type != "2d") params["tz"] = v[2];
00443
00444 float scale = get_scale();
00445 params["scale"] = scale;
00446
00447 bool mirror = get_mirror();
00448 params["mirror"] = mirror;
00449
00450 return params;
00451 }
00452
00453
00454
00455 Dict Transform::get_params_inverse(const string& euler_type) const {
00456 Transform inv(inverse());
00457
00458 Dict params = inv.get_rotation(euler_type);
00459 Vec3f v = inv.get_pre_trans();
00460 params["tx"] = v[0]; params["ty"] = v[1];
00461
00462 string type = Util::str_to_lower(euler_type);
00463 if ( type != "2d") params["tz"] = v[2];
00464
00465 float scale = inv.get_scale();
00466 params["scale"] = scale;
00467
00468 bool mirror = inv.get_mirror();
00469 params["mirror"] = mirror;
00470
00471 return params;
00472 }
00473
00474
00475 void Transform::set_rotation(const Dict& rotation)
00476 {
00477 detect_problem_keys(rotation);
00478 string euler_type;
00479
00480 if (!rotation.has_key_ci("type") ){
00481 throw InvalidParameterException("argument dictionary does not contain the type key");
00482 }
00483
00484 euler_type = static_cast<string>(rotation.get_ci("type"));
00485
00486
00487 double e0=0; double e1=0; double e2=0; double e3=0;
00488 double Omega=0;
00489 double az = 0;
00490 double alt = 0;
00491 double phi = 0;
00492 double cxtilt = 0;
00493 double sxtilt = 0;
00494 double cytilt = 0;
00495 double sytilt = 0;
00496 double cztilt = 0;
00497 double sztilt = 0;
00498 bool is_quaternion = 0;
00499 bool is_matrix = 0;
00500 bool is_xyz = 0;
00501
00502 bool x_mirror;
00503 float scale;
00504
00505 get_scale_and_mirror(scale,x_mirror);
00506 if (scale == 0) throw UnexpectedBehaviorException("The determinant of the Transform is 0. This is unexpected.");
00507
00508 string type = Util::str_to_lower(euler_type);
00509 if (type == "2d") {
00510 assert_valid_2d();
00511 az = 0;
00512 alt = 0;
00513 phi = (double)rotation["alpha"] ;
00514 } else if ( type == "eman" ) {
00515
00516 az = (double)rotation["az"] ;
00517 alt = (double)rotation["alt"] ;
00518 phi = (double)rotation["phi"] ;
00519 } else if ( type == "imagic" ) {
00520
00521 az = (double)rotation["alpha"] ;
00522 alt = (double)rotation["beta"] ;
00523 phi = (double)rotation["gamma"] ;
00524 } else if ( type == "spider" ) {
00525
00526 az = (double)rotation["phi"] + 90.0;
00527 alt = (double)rotation["theta"] ;
00528 phi = (double)rotation["psi"] - 90.0;
00529 } else if ( type == "xyz" ) {
00530
00531 is_xyz = 1;
00532 cxtilt = cos(EMConsts::deg2rad*(double)rotation["xtilt"]);
00533 sxtilt = sin(EMConsts::deg2rad*(double)rotation["xtilt"]);
00534 cytilt = cos(EMConsts::deg2rad*(double)rotation["ytilt"]);
00535 sytilt = sin(EMConsts::deg2rad*(double)rotation["ytilt"]);
00536 cztilt = cos(EMConsts::deg2rad*(double)rotation["ztilt"]);
00537 sztilt = sin(EMConsts::deg2rad*(double)rotation["ztilt"]);
00538 } else if ( type == "mrc" ) {
00539
00540 az = (double)rotation["phi"] + 90.0f ;
00541 alt = (double)rotation["theta"] ;
00542 phi = (double)rotation["omega"] - 90.0f ;
00543 } else if ( type == "quaternion" ) {
00544
00545 is_quaternion = 1;
00546 e0 = (double)rotation["e0"];
00547 e1 = (double)rotation["e1"];
00548 e2 = (double)rotation["e2"];
00549 e3 = (double)rotation["e3"];
00550 } else if ( type == "spin" ) {
00551
00552 is_quaternion = 1;
00553 Omega = (double)rotation["Omega"];
00554 e0 = cos(Omega*EMConsts::deg2rad/2.0);
00555 e1 = sin(Omega*EMConsts::deg2rad/2.0) * (double)rotation["n1"];
00556 e2 = sin(Omega*EMConsts::deg2rad/2.0) * (double)rotation["n2"];
00557 e3 = sin(Omega*EMConsts::deg2rad/2.0) * (double)rotation["n3"];
00558 } else if ( type == "sgirot" ) {
00559
00560 is_quaternion = 1;
00561 Omega = (double)rotation["q"] ;
00562 e0 = cos(Omega*EMConsts::deg2rad/2.0);
00563 e1 = sin(Omega*EMConsts::deg2rad/2.0) * (double)rotation["n1"];
00564 e2 = sin(Omega*EMConsts::deg2rad/2.0) * (double)rotation["n2"];
00565 e3 = sin(Omega*EMConsts::deg2rad/2.0) * (double)rotation["n3"];
00566 } else if ( type == "matrix" ) {
00567 is_matrix = 1;
00568 matrix[0][0] = (float)rotation["m11"];
00569 matrix[0][1] = (float)rotation["m12"];
00570 matrix[0][2] = (float)rotation["m13"];
00571 matrix[1][0] = (float)rotation["m21"];
00572 matrix[1][1] = (float)rotation["m22"];
00573 matrix[1][2] = (float)rotation["m23"];
00574 matrix[2][0] = (float)rotation["m31"];
00575 matrix[2][1] = (float)rotation["m32"];
00576 matrix[2][2] = (float)rotation["m33"];
00577 } else {
00578
00579 throw InvalidStringException(euler_type, "unknown Euler Type");
00580 }
00581
00582 double azp = az*EMConsts::deg2rad;
00583 double altp = alt*EMConsts::deg2rad;
00584 double phip = phi*EMConsts::deg2rad;
00585
00586 if (!is_quaternion && !is_matrix && !is_xyz) {
00587 matrix[0][0] = (float)(cos(phip)*cos(azp) - cos(altp)*sin(azp)*sin(phip));
00588 matrix[0][1] = (float)(cos(phip)*sin(azp) + cos(altp)*cos(azp)*sin(phip));
00589 matrix[0][2] = (float)(sin(altp)*sin(phip));
00590 matrix[1][0] = (float)(-sin(phip)*cos(azp) - cos(altp)*sin(azp)*cos(phip));
00591 matrix[1][1] = (float)(-sin(phip)*sin(azp) + cos(altp)*cos(azp)*cos(phip));
00592 matrix[1][2] = (float)(sin(altp)*cos(phip));
00593 matrix[2][0] = (float)(sin(altp)*sin(azp));
00594 matrix[2][1] = (float)(-sin(altp)*cos(azp));
00595 matrix[2][2] = (float)cos(altp);
00596 }
00597 if (is_quaternion){
00598 matrix[0][0] = (float)(e0 * e0 + e1 * e1 - e2 * e2 - e3 * e3);
00599 matrix[0][1] = (float)(2.0f * (e1 * e2 + e0 * e3));
00600 matrix[0][2] = (float)(2.0f * (e1 * e3 - e0 * e2));
00601 matrix[1][0] = (float)(2.0f * (e2 * e1 - e0 * e3));
00602 matrix[1][1] = (float)(e0 * e0 - e1 * e1 + e2 * e2 - e3 * e3);
00603 matrix[1][2] = (float)(2.0f * (e2 * e3 + e0 * e1));
00604 matrix[2][0] = (float)(2.0f * (e3 * e1 + e0 * e2));
00605 matrix[2][1] = (float)(2.0f * (e3 * e2 - e0 * e1));
00606 matrix[2][2] = (float)(e0 * e0 - e1 * e1 - e2 * e2 + e3 * e3);
00607
00608 }
00609 if (is_xyz){
00610 matrix[0][0] = (float)(cytilt*cztilt);
00611 matrix[0][1] = (float)(cxtilt*sztilt+sxtilt*sytilt*cztilt);
00612 matrix[0][2] = (float)(sxtilt*sztilt-cxtilt*sytilt*cztilt);
00613 matrix[1][0] = (float)(-cytilt*sztilt);
00614 matrix[1][1] = (float)(cxtilt*cztilt-sxtilt*sytilt*sztilt);
00615 matrix[1][2] = (float)(sxtilt*cztilt+cxtilt*sytilt*sztilt);
00616 matrix[2][0] = (float)(sytilt);
00617 matrix[2][1] = (float)(-sxtilt*cytilt);
00618 matrix[2][2] = (float)(cxtilt*cytilt);
00619 }
00620
00621
00622 if (scale != 1.0f) {
00623 for(int i=0; i<3; ++i) {
00624 for(int j=0; j<3; ++j) {
00625 matrix[i][j] *= scale;
00626 }
00627 }
00628 }
00629
00630
00631 if ( x_mirror ) {
00632 for(int j=0; j<3; ++j) {
00633 matrix[0][j] *= -1.0f;
00634 }
00635 }
00636 }
00637
00638 Transform Transform::get_rotation_transform() const
00639 {
00640 Transform ret(*this);
00641 ret.set_scale(1.0);
00642 ret.set_mirror(false);
00643 ret.set_trans(0,0,0);
00644
00645 return ret;
00646 }
00647
00648 void Transform::set_rotation(const Vec3f & v)
00649 {
00650 if ( v[0] == 0 && v[1] == 0 && v[2] == 0 )
00651 throw UnexpectedBehaviorException("Can't set rotation for the null vector");
00652
00653 Vec3f v1(v);
00654 v1.normalize();
00655
00656 double theta = acos(v1[2]);
00657 double psi = atan2(v1[1],-v1[0]);
00658
00659 Dict d;
00660 d["theta"] = (double)EMConsts::rad2deg*theta;
00661 d["psi"] = (double)EMConsts::rad2deg*psi;
00662 d["phi"] = (double)0.0;
00663 d["type"] = "spider";
00664
00665 set_rotation(d);
00666
00667
00668 }
00669
00670 Transform Transform::negate() const
00671 {
00672 Transform t(*this);
00673 for(unsigned int i = 0; i < 3; ++i) {
00674 for(unsigned int j = 0; j < 4; ++j) {
00675 t.set(i,j,t[i][j]*-1);
00676 }
00677 }
00678 return t;
00679 }
00680
00681 Transform Transform::get_hflip_transform() const {
00682
00683 Dict rot = get_rotation("eman");
00684 rot["alt"] = 180.0f + static_cast<float>(rot["alt"]);
00685 rot["phi"] = 180.0f - static_cast<float>(rot["phi"]);
00686
00687 Transform ret(*this);
00688 ret.set_rotation(rot);
00689
00690 Vec3f trans = get_trans();
00691 trans[0] = -trans[0];
00692 ret.set_trans(trans);
00693
00694
00695
00696 return ret;
00697 }
00698
00699 Transform Transform::get_vflip_transform() const {
00700
00701 Dict rot = get_rotation("eman");
00702 rot["alt"] = 180.0f + static_cast<float>(rot["alt"]);
00703 rot["phi"] = - static_cast<float>(rot["phi"]);
00704
00705 Transform ret(*this);
00706 ret.set_rotation(rot);
00707
00708 Vec3f trans = get_trans();
00709 trans[1] = -trans[1];
00710 ret.set_trans(trans);
00711
00712 return ret;
00713 }
00714
00715 Dict Transform::get_rotation(const string& euler_type) const
00716 {
00717 Dict result;
00718
00719
00720 float scale;
00721 bool x_mirror;
00722 get_scale_and_mirror(scale,x_mirror);
00723 if (scale == 0) throw UnexpectedBehaviorException("The determinant of the Transform is 0. This is unexpected.");
00724
00725 double cosalt = matrix[2][2]/scale;
00726 double x_mirror_scale = (x_mirror ? -1.0f : 1.0f);
00727 double inv_scale = 1.0f/scale;
00728
00729 double az = 0;
00730 double alt = 0;
00731 double phi = 0;
00732 double phiS = 0;
00733 double psiS = 0;
00734
00735
00736
00737 if (cosalt >= 1) {
00738 alt = 0;
00739 az = 0;
00740 phi = (double)EMConsts::rad2deg * atan2(x_mirror_scale*matrix[0][1], x_mirror_scale*matrix[0][0]);
00741 } else if (cosalt <= -1) {
00742 alt = 180;
00743 az = 0;
00744 phi = (double)EMConsts::rad2deg * atan2(-x_mirror_scale*matrix[0][1], x_mirror_scale*matrix[0][0]);
00745 } else {
00746
00747 az = (double)EMConsts::rad2deg * atan2(scale*matrix[2][0], -scale*matrix[2][1]);
00748
00749 if (matrix[2][2]==0.0)
00750 alt = 90.0;
00751 else
00752 alt = (double)EMConsts::rad2deg * atan(sqrt((double)matrix[2][0]*matrix[2][0]+(double)matrix[2][1]*matrix[2][1])/fabs(matrix[2][2]));
00753
00754 if (matrix[2][2] * scale < 0)
00755 alt = 180.0f-alt;
00756
00757 phi = (double)EMConsts::rad2deg * atan2(x_mirror_scale*(double)matrix[0][2], (double)matrix[1][2]);
00758
00759 }
00760
00761 phi = phi-360.0*floor(phi/360.0);
00762 az = az -360.0*floor(az/360.0);
00763
00764
00765 if (cosalt >= 1) {
00766 phiS = 0;
00767 psiS = phi;
00768 } else if (cosalt <= -1) {
00769 phiS = 0;
00770 psiS = phi + 180.0;
00771 } else {
00772 phiS = az - 90.0;
00773 psiS = phi + 90.0;
00774 }
00775
00776 phiS = phiS-360.0*floor(phiS/360.0);
00777 psiS = psiS-360.0*floor(psiS/360.0);
00778
00779
00780
00781 double nphi = (az-phi)/2.0;
00782
00783 double cosOover2 = cos((az+phi)*EMConsts::deg2rad/2.0) * cos(alt*EMConsts::deg2rad/2.0);
00784 double sinOover2 = sqrt(1 -cosOover2*cosOover2);
00785 double cosnTheta = sin((az+phi)*EMConsts::deg2rad/2.0) * cos(alt*EMConsts::deg2rad/2.0) / sqrt(1-cosOover2*cosOover2);
00786 double sinnTheta = sqrt(1-cosnTheta*cosnTheta);
00787 double n1 = sinnTheta*cos(nphi*EMConsts::deg2rad);
00788 double n2 = sinnTheta*sin(nphi*EMConsts::deg2rad);
00789 double n3 = cosnTheta;
00790 double xtilt = 0;
00791 double ytilt = 0;
00792 double ztilt = 0;
00793
00794
00795 if (cosOover2<0) {
00796 cosOover2*=-1; n1 *=-1; n2*=-1; n3*=-1;
00797 }
00798
00799 string type = Util::str_to_lower(euler_type);
00800
00801 result["type"] = type;
00802 if (type == "2d") {
00803 assert_valid_2d();
00804 result["alpha"] = phi;
00805 } else if (type == "eman") {
00806
00807 result["az"] = az;
00808 result["alt"] = alt;
00809 result["phi"] = phi;
00810 } else if (type == "imagic") {
00811
00812 result["alpha"] = az;
00813 result["beta"] = alt;
00814 result["gamma"] = phi;
00815 } else if (type == "spider") {
00816
00817 result["phi"] = phiS;
00818 result["theta"] = alt;
00819 result["psi"] = psiS;
00820 } else if (type == "mrc") {
00821
00822 result["phi"] = phiS;
00823 result["theta"] = alt;
00824 result["omega"] = psiS;
00825 } else if (type == "xyz") {
00826
00827 xtilt = atan2(-sin(EMConsts::deg2rad*phiS)*sin(EMConsts::deg2rad*alt),cos(EMConsts::deg2rad*alt));
00828 ytilt = asin( cos(EMConsts::deg2rad*phiS)*sin(EMConsts::deg2rad*alt));
00829 ztilt = psiS*EMConsts::deg2rad - atan2(sin(xtilt), cos(xtilt) *sin(ytilt));
00830
00831 xtilt *= EMConsts::rad2deg; ytilt *= EMConsts::rad2deg; ztilt *= EMConsts::rad2deg;
00832 xtilt = xtilt-360*.0*floor((xtilt+180.0)/360.0);
00833 ytilt = ytilt-360*.0*floor((ytilt+180.0)/360.0);
00834 ztilt = ztilt-360*.0*floor((ztilt+180.0)/360.0);
00835
00836 result["xtilt"] = xtilt;
00837 result["ytilt"] = ytilt;
00838 result["ztilt"] = ztilt;
00839 } else if (type == "quaternion") {
00840
00841 result["e0"] = cosOover2 ;
00842 result["e1"] = sinOover2 * n1 ;
00843 result["e2"] = sinOover2 * n2;
00844 result["e3"] = sinOover2 * n3;
00845 } else if (type == "spin") {
00846
00847 result["Omega"] = 2.0*EMConsts::rad2deg * acos(cosOover2);
00848 result["n1"] = n1;
00849 result["n2"] = n2;
00850 result["n3"] = n3;
00851 } else if (type == "sgirot") {
00852
00853 result["q"] = 2.0*EMConsts::rad2deg * acos(cosOover2);
00854 result["n1"] = n1;
00855 result["n2"] = n2;
00856 result["n3"] = n3;
00857 } else if (type == "matrix") {
00858
00859 result["m11"] = x_mirror_scale*matrix[0][0]*inv_scale;
00860 result["m12"] = x_mirror_scale*matrix[0][1]*inv_scale;
00861 result["m13"] = x_mirror_scale*matrix[0][2]*inv_scale;
00862 result["m21"] = matrix[1][0]*inv_scale;
00863 result["m22"] = matrix[1][1]*inv_scale;
00864 result["m23"] = matrix[1][2]*inv_scale;
00865 result["m31"] = matrix[2][0]*inv_scale;
00866 result["m32"] = matrix[2][1]*inv_scale;
00867 result["m33"] = matrix[2][2]*inv_scale;
00868 } else {
00869 throw InvalidStringException(euler_type, "unknown Euler Type");
00870 }
00871
00872 return result;
00873 }
00874
00875 void Transform::set_trans(const float& x, const float& y, const float& z)
00876 {
00877 bool x_mirror = get_mirror();
00878
00879 if (x_mirror) matrix[0][3] = -x;
00880 else matrix[0][3] = x;
00881 matrix[1][3] = y;
00882 matrix[2][3] = z;
00883 }
00884
00885 Vec3f Transform::get_trans() const
00886 {
00887
00888 bool x_mirror = get_mirror();
00889 Vec3f v;
00890 if (x_mirror) v[0] = -matrix[0][3];
00891 else v[0] = matrix[0][3];
00892 v[1] = matrix[1][3];
00893 v[2] = matrix[2][3];
00894
00895 Util::apply_precision(v[0],ERR_LIMIT);
00896 Util::apply_precision(v[1],ERR_LIMIT);
00897 Util::apply_precision(v[2],ERR_LIMIT);
00898
00899 return v;
00900 }
00901
00902 Vec2f Transform::get_trans_2d() const
00903 {
00904 bool x_mirror = get_mirror();
00905 Vec2f v;
00906 if (x_mirror) v[0] = -matrix[0][3];
00907 else v[0] = matrix[0][3];
00908 v[1] = matrix[1][3];
00909 return v;
00910 }
00911
00912
00913
00914 Vec3f Transform::get_pre_trans() const
00915 {
00916 Transform T(*this);
00917 T.set_trans(0,0,0);
00918 T.invert();
00919
00920 Transform soln = T*(*this);
00921
00922 return soln.get_trans();
00923 }
00924
00925 Vec2f Transform::get_pre_trans_2d() const
00926 {
00927 Transform T(*this);
00928 T.set_trans(0,0,0);
00929 T.invert();
00930
00931 Transform soln = T*(*this);
00932
00933 return soln.get_trans_2d();
00934 }
00935
00936
00937 void Transform::set_scale(const float& new_scale) {
00938 if (new_scale <= 0) {
00939 throw InvalidValueException(new_scale,"The scale factor in a Transform object must be positive and non zero");
00940 }
00941
00942
00943
00944 float old_scale = get_scale();
00945
00946 float n_scale = new_scale;
00947 Util::apply_precision(n_scale,ERR_LIMIT);
00948
00949 float corrected_scale = n_scale/old_scale;
00950 if ( corrected_scale != 1.0 ) {
00951 for(int i = 0; i < 3; ++i ) {
00952 for(int j = 0; j < 3; ++j ) {
00953 matrix[i][j] *= corrected_scale;
00954 }
00955 }
00956 }
00957 }
00958
00959 float Transform::get_scale() const {
00960 float determinant = get_determinant();
00961 if (determinant < 0 ) determinant *= -1;
00962
00963 float scale = std::pow(determinant,1.0f/3.0f);
00964 int int_scale = static_cast<int>(scale);
00965 float scale_residual = scale-static_cast<float>(int_scale);
00966 if ( scale_residual < ERR_LIMIT ) { scale = static_cast<float>(int_scale); };
00967
00968 Util::apply_precision(scale, ERR_LIMIT);
00969
00970 return scale;
00971 }
00972
00973 void print_matrix(gsl_matrix* M, unsigned int r, unsigned int c, const string& message ) {
00974 cout << "Message is " << message << endl;
00975 for ( unsigned int i = 0; i < r; ++i )
00976 {
00977 for ( unsigned int j = 0; j < c; ++j )
00978 {
00979 cout << gsl_matrix_get(M,i,j) << " ";
00980 }
00981 cout << endl;
00982 }
00983 }
00984
00985 void Transform::orthogonalize()
00986 {
00987 float scale;
00988 bool x_mirror;
00989 get_scale_and_mirror(scale,x_mirror);
00990 if (scale == 0) throw UnexpectedBehaviorException("The determinant of the Transform is 0. This is unexpected.");
00991 double inv_scale = 1.0/static_cast<double>(scale);
00992 double mirror_scale = (x_mirror == true ? -1.0:1.0);
00993
00994 gsl_matrix * R = gsl_matrix_calloc(3,3);
00995 for ( unsigned int i = 0; i < 3; ++i )
00996 {
00997 for ( unsigned int j = 0; j < 3; ++j )
00998 {
00999 if (i == 0 && mirror_scale != 1.0 ) {
01000 gsl_matrix_set( R, i, j, static_cast<double>(matrix[i][j])*mirror_scale*inv_scale );
01001 }
01002 else {
01003 gsl_matrix_set( R, i, j, static_cast<double>(matrix[i][j])*inv_scale );
01004 }
01005 }
01006 }
01007
01008 gsl_matrix * V = gsl_matrix_calloc(3,3);
01009 gsl_vector * S = gsl_vector_calloc(3);
01010 gsl_vector * work = gsl_vector_calloc(3);
01011 gsl_linalg_SV_decomp (R, V, S, work);
01012
01013 gsl_matrix * Soln = gsl_matrix_calloc(3,3);
01014 gsl_blas_dgemm (CblasNoTrans, CblasTrans, 1.0, R, V, 0.0, Soln);
01015
01016 for ( unsigned int i = 0; i < 3; ++i )
01017 {
01018 for ( unsigned int j = 0; j < 3; ++j )
01019 {
01020 matrix[i][j] = static_cast<float>( gsl_matrix_get(Soln,i,j) );
01021 }
01022 }
01023
01024
01025 if (scale != 1.0f) {
01026 for(int i=0; i<3; ++i) {
01027 for(int j=0; j<3; ++j) {
01028 matrix[i][j] *= scale;
01029 }
01030 }
01031 }
01032
01033
01034 if ( x_mirror ) {
01035 for(int j=0; j<3; ++j) {
01036 matrix[0][j] *= -1.0f;
01037 }
01038 }
01039
01040 gsl_matrix_free(V); gsl_matrix_free(R); gsl_matrix_free(Soln);
01041 gsl_vector_free(S); gsl_vector_free(work);
01042 }
01043
01044 void Transform::set_mirror(const bool x_mirror ) {
01045
01046 bool old_x_mirror = get_mirror();
01047 if (old_x_mirror == x_mirror) return;
01048 else {
01049
01050 for (int j = 0; j < 4; ++j ) {
01051 matrix[0][j] *= -1;
01052 }
01053 }
01054 }
01055
01056 bool Transform::get_mirror() const {
01057 float determinant = get_determinant();
01058
01059 bool x_mirror = false;
01060 if ( determinant < 0 ) x_mirror = true;
01061
01062 return x_mirror;
01063
01064 }
01065
01066 void Transform::get_scale_and_mirror(float& scale, bool& x_mirror) const {
01067
01068 float determinant = get_determinant();
01069 x_mirror = false;
01070 if ( determinant < 0 ) {
01071 x_mirror = true;
01072 determinant *= -1;
01073 }
01074 if (determinant != 1 ) {
01075 scale = std::pow(determinant,1.0f/3.0f);
01076 int int_scale = static_cast<int>(scale);
01077 float scale_residual = scale-static_cast<float>(int_scale);
01078 if ( scale_residual < ERR_LIMIT ) { scale = static_cast<float>(int_scale); };
01079 }
01080 else scale = 1;
01081
01082 Util::apply_precision(scale,ERR_LIMIT);
01083 }
01084
01085 float Transform::get_determinant() const
01086 {
01087 float det;
01088 double det2;
01089 det2 = matrix[0][0]*((double)matrix[1][1]*matrix[2][2]-(double)matrix[2][1]*matrix[1][2]);
01090 det2 -= matrix[0][1]*((double)matrix[1][0]*matrix[2][2]-(double)matrix[2][0]*matrix[1][2]);
01091 det2 += matrix[0][2]*((double)matrix[1][0]*matrix[2][1]-(double)matrix[2][0]*matrix[1][1]);
01092
01093 det = (float)det2;
01094 Util::apply_precision(det,ERR_LIMIT);
01095
01096 return det;
01097 }
01098
01099 void Transform::invert() {
01100
01101 double m00 = matrix[0][0]; double m01=matrix[0][1]; double m02=matrix[0][2];
01102 double m10 = matrix[1][0]; double m11=matrix[1][1]; double m12=matrix[1][2];
01103 double m20 = matrix[2][0]; double m21=matrix[2][1]; double m22=matrix[2][2];
01104 double v0 = matrix[0][3]; double v1 =matrix[1][3]; double v2 =matrix[2][3];
01105
01106 double cof00 = m11*m22-m12*m21;
01107 double cof11 = m22*m00-m20*m02;
01108 double cof22 = m00*m11-m01*m10;
01109 double cof01 = m10*m22-m20*m12;
01110 double cof02 = m10*m21-m20*m11;
01111 double cof12 = m00*m21-m01*m20;
01112 double cof10 = m01*m22-m02*m21;
01113 double cof20 = m01*m12-m02*m11;
01114 double cof21 = m00*m12-m10*m02;
01115
01116 double det = m00* cof00 + m02* cof02 -m01*cof01;
01117
01118 matrix[0][0] = (float)(cof00/det);
01119 matrix[0][1] = - (float)(cof10/det);
01120 matrix[0][2] = (float)(cof20/det);
01121 matrix[1][0] = - (float)(cof01/det);
01122 matrix[1][1] = (float)(cof11/det);
01123 matrix[1][2] = - (float)(cof21/det);
01124 matrix[2][0] = (float)(cof02/det);
01125 matrix[2][1] = - (float)(cof12/det);
01126 matrix[2][2] = (float)(cof22/det);
01127
01128 matrix[0][3] = (float)((- cof00*v0 + cof10*v1 - cof20*v2)/det);
01129 matrix[1][3] = (float)(( cof01*v0 - cof11*v1 + cof21*v2)/det);
01130 matrix[2][3] = (float)((- cof02*v0 + cof12*v1 - cof22*v2)/det);
01131 }
01132
01133 Transform Transform::inverse() const {
01134 Transform t(*this);
01135 t.invert();
01136 return t;
01137 }
01138
01139 void Transform::transpose_inplace() {
01140 float tempij;
01141 for (int i = 0; i < 3; i++) {
01142 for (int j = 0; j < i; j++) {
01143 if (i != j) {
01144 tempij= matrix[i][j];
01145 matrix[i][j] = matrix[j][i];
01146 matrix[j][i] = tempij;
01147 }
01148 }
01149 }
01150 }
01151
01152 Transform Transform::transpose() const {
01153 Transform t(*this);
01154 t.transpose_inplace();
01155 return t;
01156 }
01157
01158
01159 Transform EMAN::operator*(const Transform & M2, const Transform & M1)
01160 {
01161 Transform result;
01162 for (int i=0; i<3; i++) {
01163 for (int j=0; j<4; j++) {
01164 result[i][j] = M2[i][0] * M1[0][j] + M2[i][1] * M1[1][j] + M2[i][2] * M1[2][j];
01165 }
01166 result[i][3] += M2[i][3];
01167 }
01168
01169 return result;
01170 }
01171
01172 void Transform::assert_valid_2d() const {
01173 int rotation_error = 0;
01174 int translation_error = 0;
01175 if (fabs(matrix[2][0]) > ERR_LIMIT) rotation_error++;
01176 if (fabs(matrix[2][1]) > ERR_LIMIT) rotation_error++;
01177 if (fabs(matrix[2][3]) > ERR_LIMIT) translation_error++;
01178 if (fabs(matrix[0][2]) > ERR_LIMIT) rotation_error++;
01179 if (fabs(matrix[1][2]) > ERR_LIMIT) rotation_error++;
01180
01181 if ( translation_error && rotation_error ) {
01182 throw UnexpectedBehaviorException("Error, the internal matrix contains 3D rotations and 3D translations. This object can not be considered 2D");
01183 } else if ( translation_error ) {
01184 throw UnexpectedBehaviorException("Error, the internal matrix contains a non zero z component for a 3D translation. This object can not be considered 2D");
01185 }
01186 else if ( rotation_error ) {
01187 throw UnexpectedBehaviorException("Error, the internal matrix contains 3D rotations and this object can not be considered 2D");
01188 }
01189
01190 }
01191
01192
01193
01194 Transform Transform::get_sym(const string & sym_name, int n) const
01195 {
01196 Symmetry3D* sym = Factory<Symmetry3D>::get(sym_name);
01197 Transform ret;
01198 ret = (*this) * sym->get_sym(n);
01199 delete sym;
01200 return ret;
01201 }
01202
01203 vector<Transform > Transform::get_sym_proj(const string & sym_name) const
01204 {
01205 vector<Transform> ret;
01206 Transform t;
01207 Symmetry3D* sym = Factory<Symmetry3D>::get(sym_name);
01208 int nsym = sym->get_nsym();
01209 int n = nsym;
01210
01211 if ((sym_name[0] == 'c' || sym_name[0] == 'd' ) && fabs(matrix[2][2]) < 1.e-6){
01212
01213 Dict d1,d2;
01214 d2["theta"] = (double)90.0;
01215 d2["psi"] = (double)0.0;
01216 d2["phi"] = (double)0.0;
01217 d2["type"] = "spider";
01218 d1 = this->get_rotation("spider");
01219
01220 if (sym_name[0] == 'c') {
01221 if( nsym%2 == 0) n = nsym/2;
01222
01223 for (int k=0;k<n;k++) {
01224 d2["phi"] = (double)d1["phi"] + k*double(360.0)/ nsym;
01225 d2["psi"] = d1["psi"];
01226 t.set_rotation(d2);
01227 ret.push_back( t );
01228 }
01229
01230 }
01231 else {
01232 nsym = nsym/2;
01233
01234 if (nsym%2 == 0) {
01235 n = nsym;
01236 float cos_phi = cos( EMConsts::deg2rad*360.0/2/nsym );
01237
01238 for (int k=0;k<n;k++){
01239
01240 if(k%2==0) {
01241
01242 d2["phi"] = (double)d1["phi"] + k/2*double(360.0)/ nsym;
01243 d2["psi"] = d1["psi"];
01244 t.set_rotation(d2);
01245 ret.push_back( t );
01246 }
01247 else {
01248
01249 if( ( fabs(1.0-matrix[2][0])>1.0e-6 )&& fabs( matrix[2][0]-cos_phi)>1.0e-6 ){
01250
01251 d2["phi"] = k/2*double(360.0)/ nsym +180 - (double)d1["phi"];
01252 d2["psi"] = (double)d1["psi"] + 180;
01253 t.set_rotation(d2);
01254 ret.push_back( t );
01255 }
01256 }
01257
01258 }
01259 }
01260
01261
01262
01263 else {
01264 n = nsym*2;
01265 float cos_phi = cos( EMConsts::deg2rad*360.0/4/nsym );
01266 for (int k=0;k<n;k++){
01267
01268 if(k%4==0) {
01269
01270 d2["phi"] = (double)d1["phi"] + k/4*360.0/ nsym;
01271 d2["psi"] = (double)d1["psi"];
01272 t.set_rotation(d2);
01273 ret.push_back( t );
01274 }
01275 else if( k%4 ==1) {
01276 if( ( fabs(1.0-matrix[2][0])>1.0e-6 )&& fabs( matrix[2][0]-cos_phi)>1.0e-6 ){
01277
01278 d2["phi"] = k/4*360.0/nsym + 360.0/2/nsym+180 - (double)d1["phi"];
01279 d2["psi"] = (double)d1["psi"] + 180;
01280 t.set_rotation(d2);
01281 ret.push_back( t );
01282 }
01283
01284 }
01285
01286 else if( k%4 ==2) {
01287
01288 d2["phi"] = k/4*360.0/ nsym+360.0/2/nsym+180 + (double)d1["phi"];
01289 d2["psi"] = (double)d1["psi"];
01290 t.set_rotation(d2);
01291 ret.push_back( t );
01292
01293 }
01294
01295 else if( k%4 ==3) {
01296 if( ( fabs(1.0-matrix[2][0])>1.0e-6 )&& fabs( matrix[2][0]-cos_phi)>1.0e-6 ) {
01297 d2["phi"] = k/4*360.0/nsym+ 2.0*360.0/2/nsym - (double)d1["phi"];
01298 d2["psi"] = (double)d1["psi"] + 180;
01299 t.set_rotation(d2);
01300 ret.push_back( t );
01301 }
01302 }
01303
01304 }
01305 }
01306
01307 }
01308
01309 }
01310 else {
01311 for (int k=0;k<nsym;k++) {
01312 t = sym->get_sym(k);
01313 ret.push_back( (*this) * t );
01314 }
01315
01316 }
01317 delete sym;
01318 return ret;
01319 }
01320
01321
01322 int Transform::get_nsym(const string & sym_name)
01323 {
01324 Symmetry3D* sym = Factory<Symmetry3D>::get(sym_name);
01325 int nsym = sym->get_nsym();
01326 delete sym;
01327 return nsym;
01328 }
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01348
01349
01350
01351
01352
01353
01354
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368
01369
01370
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01386
01387
01388
01389
01390
01391
01392
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453
01456
01457
01458
01459
01460
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01479
01480
01481
01482
01483
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01512
01513
01514
01515
01516
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639
01640
01641
01642
01643
01644
01646
01647
01648
01649
01650
01651
01652
01653
01654
01656
01657
01658
01659
01660
01661
01662
01663
01664
01667
01668
01669
01670
01671
01672
01673
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683
01753
01754
01755
01756
01757
01758
01759
01760
01761
01762
01763
01765
01766
01767
01768
01769
01770
01771
01772
01773
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783
01784
01785
01786
01787
01788
01789
01790
01791
01792
01793
01794
01795
01796
01797
01798
01799
01800
01802
01803
01804
01805
01806
01807
01808
01809
01810
01811
01812
01813
01814
01815
01816
01817
01818
01819
01820
01821
01822
01823
01824
01825
01826
01827
01828
01829
01830
01831
01832
01833
01834
01835
01836
01837
01838
01839
01840
01841
01842
01843
01844
01845
01846
01847
01848
01849
01850
01851
01852
01853
01854
01855
01856
01857
01858
01859
01860
01861
01862
01863
01864
01865
01866
01867
01868
01869
01870
01871
01872
01873
01874
01875
01876
01877
01878
01879
01880
01881
01882
01883
01884
01885
01886
01887
01888
01889
01890
01891
01892
01893
01894
01895
01896
01897
01898
01899
01900
01901
01902
01903
01904
01905
01906
01907
01908
01909
01910
01911
01912
01913
01914
01915
01916
01917
01918
01919
01920
01921
01922
01923
01924
01925
01926
01927
01928
01929
01930
01931
01932
01933
01934
01935
01936
01937
01938
01939
01940
01941
01942
01943
01944
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961
01962
01963
01964
01965
01966
01967
01968
01969
01970
01971
01972
01973
01974
01975
01976
01977
01978
01979
01980
01981
01983
01984
01985
01986
01987
01988
01989
01990
01991
01992
01993
01994
01995
01996
01997
01998
01999
02000
02001
02002
02003
02004
02005
02006
02007
02008
02009
02010
02012
02013
02014
02015
02016
02017
02018
02020
02022
02023
02025
02026
02027
02028
02029
02030
02031
02032
02033
02034
02035
02036
02037
02038
02039
02040
02041
02042
02043
02044
02045
02046
02047
02048
02049
02050
02051
02052
02053
02054
02055
02056
02057
02058
02059
02060
02061
02062
02063
02064
02065
02066
02068
02069
02070
02071
02072
02073
02074
02075
02076
02077
02078
02079
02080
02081
02082
02083
02084
02085
02086
02088
02089
02090
02091
02092
02093
02094
02095
02096
02097
02098
02100
02101
02102
02103
02104
02105
02106
02107
02108
02109
02110
02111
02112
02113
02114
02115
02116
02117
02118
02119
02120
02121
02122
02123
02124
02125
02126
02127
02128
02129
02130
02131
02132
02133
02134
02135
02136
02137
02138
02139
02140
02141
02142
02143
02144
02145
02146
02147
02148
02149
02150
02151
02152
02153
02154
02155
02156
02157
02158
02159
02160
02161
02162
02163
02164
02165
02166
02167
02168
02169
02170
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182
02183
02184
02185
02186
02187
02188
02189
02190
02191
02192
02193
02194
02195
02196
02197
02198
02199
02200
02201
02202
02203
02204
02205
02206
02207
02208
02209
02210
02211
02212
02213
02220
02221
02222
02223
02224
02225
02226
02227
02228
02229
02230
02231
02232
02233
02234
02235
02236
02237
02238
02239
02240
02241
02242
02243
02244
02245
02246
02247
02248
02249
02250
02251
02252
02253
02254
02255
02256
02257
02258
02259
02260
02261
02262
02263
02264
02265
02266
02267
02268
02269
02270
02271
02272
02273
02274
02275
02276
02277
02278
02279
02280
02281
02282
02283
02284
02285
02286
02287
02289
02290
02291
02292
02293
02296
02297
02298
02299
02300
02301
02302
02303
02304
02305
02306
02307
02308
02309
02310
02311
02312
02313
02314
02315
02316
02317
02318
02319
02320
02321
02322
02323
02324
02325
02326
02327
02328
02329
02330
02331
02332
02333
02334
02335
02336
02337
02338
02339
02340
02341
02342
02343
02344
02345
02346
02347
02348
02349
02350
02351
02352
02353
02354
02355
02356
02357
02358
02359
02360
02361
02362
02363
02364
02365
02366
02367
02368
02369
02370
02371
02372
02373
02374
02375
02376
02377
02378
02379
02380
02381
02382
02383
02384
02385
02386
02387
02388
02389
02390
02391
02392
02393
02394
02395
02396
02397
02398
02399
02400
02401
02402
02403
02404
02405
02406
02407
02408
02409
02410
02411
02412
02413
02414
02415
02416
02417
02418
02419
02420
02421
02422
02423
02424
02425
02426
02427
02428
02429
02430
02431
02432
02433
02434
02435
02436
02437
02438
02439
02440
02441
02442
02443
02444
02445
02446
02447
02448
02449
02450
02451
02452
02453
02454
02455
02456
02457
02458
02459
02460
02461
02462
02463
02464
02465
02466
02467
02468
02469
02470
02471
02472
02473
02474
02475
02476
02477
02478
02479
02480
02481
02482
02483
02484
02485
02486
02487
02488
02489
02490
02491
02492
02493
02494
02495
02496
02497
02498
02499
02500
02501
02502
02503
02504
02505
02506
02507