00001
00002
00003
00004
00005
00006
00007
00008 #include "Alignment/CocoaUtilities/interface/ALIUtils.h"
00009 #include "Alignment/CocoaUtilities/interface/GlobalOptionMgr.h"
00010
00011 #include <math.h>
00012 #include <stdlib.h>
00013 #include <iomanip>
00014
00015
00016 ALIint ALIUtils::debug = -1;
00017 ALIint ALIUtils::report = 1;
00018 ALIdouble ALIUtils::_LengthValueDimensionFactor = 1.;
00019 ALIdouble ALIUtils::_LengthSigmaDimensionFactor = 1.;
00020 ALIdouble ALIUtils::_AngleValueDimensionFactor = 1.;
00021 ALIdouble ALIUtils::_AngleSigmaDimensionFactor = 1.;
00022 ALIdouble ALIUtils::_OutputLengthValueDimensionFactor = 1.;
00023 ALIdouble ALIUtils::_OutputLengthSigmaDimensionFactor = 1.;
00024 ALIdouble ALIUtils::_OutputAngleValueDimensionFactor = 1.;
00025 ALIdouble ALIUtils::_OutputAngleSigmaDimensionFactor = 1.;
00026 time_t ALIUtils::_time_now;
00027 ALIdouble ALIUtils::deg = 0.017453293;
00028 ALIbool ALIUtils::firstTime = false;
00029 ALIdouble ALIUtils::maximum_deviation_derivative = 1.E-6;
00030
00031
00032
00033
00034 int ALIUtils::IsNumber( const ALIstring& str)
00035 {
00036 int isnum = 1;
00037 int numE = 0;
00038 for(ALIuint ii=0; ii<str.length(); ii++){
00039 if(!isdigit(str[ii]) && str[ii]!='.' && str[ii]!='-' && str[ii]!='+') {
00040
00041 if(str[ii] == 'E' || str[ii] == 'e' ) {
00042 if(numE != 0 || ii == str.length()-1) {
00043 isnum = 0;
00044 break;
00045 }
00046 numE++;
00047 } else {
00048 isnum = 0;
00049 break;
00050 }
00051 }
00052 }
00053
00054 return isnum;
00055 }
00056
00057
00058
00059
00060
00061 void ALIUtils::dump3v( const CLHEP::Hep3Vector& vec, const std::string& msg)
00062 {
00063
00064 std::cout << msg << std::setprecision(8) << vec;
00065 std::cout << std::endl;
00066
00067
00068
00069
00070
00071 }
00072
00073
00074
00075
00076
00077 void ALIUtils::dumprm( const CLHEP::HepRotation& rm, const std::string& msg, std::ostream& out)
00078 {
00079
00080 out << msg << " xx=" << rm.xx() << " xy=" << rm.xy() << " xz=" << rm.xz() << std::endl;
00081 out << msg << " yx=" << rm.yx() << " yy=" << rm.yy() << " yz=" << rm.yz() << std::endl;
00082 out << msg << " zx=" << rm.zx() << " zy=" << rm.zy() << " zz=" << rm.zz() << std::endl;
00083
00084 }
00085
00086
00087
00088
00089
00090
00091 void ALIUtils::SetLengthDimensionFactors()
00092 {
00093
00094
00095 GlobalOptionMgr* gomgr = GlobalOptionMgr::getInstance();
00096 ALIint ad = ALIint(gomgr->getGlobalOption("length_value_dimension"));
00097
00098 _LengthValueDimensionFactor = CalculateLengthDimensionFactorFromInt( ad );
00099 ad = ALIint(gomgr->GlobalOptions()[ ALIstring("length_error_dimension"
00100 ) ]);
00101 _LengthSigmaDimensionFactor = CalculateLengthDimensionFactorFromInt( ad );
00102
00103
00104
00105
00106
00107 if(ALIUtils::debug >= 6) std::cout << _LengthValueDimensionFactor << " Set Length DimensionFactors " << _LengthSigmaDimensionFactor << std::endl;
00108
00109 }
00110
00111
00112
00113
00114
00115
00116 void ALIUtils::SetAngleDimensionFactors()
00117 {
00118
00119
00120 GlobalOptionMgr* gomgr = GlobalOptionMgr::getInstance();
00121 ALIint ad = ALIint(gomgr->GlobalOptions()[ ALIstring("angle_value_dimension") ]);
00122 _AngleValueDimensionFactor = CalculateAngleDimensionFactorFromInt(ad);
00123
00124 ad = ALIint(gomgr->GlobalOptions()[ ALIstring("angle_error_dimension"
00125 ) ]);
00126 _AngleSigmaDimensionFactor = CalculateAngleDimensionFactorFromInt(ad);
00127
00128
00129
00130
00131
00132 if(ALIUtils::debug >= 6) std::cout << _AngleValueDimensionFactor << "Set Angle DimensionFactors" << _AngleSigmaDimensionFactor << std::endl;
00133
00134 }
00135
00136
00137
00138
00139
00140
00141 void ALIUtils::SetOutputLengthDimensionFactors()
00142 {
00143
00144
00145 GlobalOptionMgr* gomgr = GlobalOptionMgr::getInstance();
00146 ALIint ad = ALIint(gomgr->GlobalOptions()[ ALIstring("output_length_value_dimension") ]);
00147 if( ad == 0 ) ad = ALIint(gomgr->GlobalOptions()[ ALIstring("length_value_dimension") ]);
00148 _OutputLengthValueDimensionFactor = CalculateLengthDimensionFactorFromInt( ad );
00149
00150 ad = ALIint(gomgr->GlobalOptions()[ ALIstring("output_length_error_dimension"
00151 ) ]);
00152 if( ad == 0 ) ad = ALIint(gomgr->GlobalOptions()[ ALIstring("length_error_dimension"
00153 ) ]);
00154 _OutputLengthSigmaDimensionFactor = CalculateLengthDimensionFactorFromInt( ad );
00155
00156
00157
00158
00159
00160 if(ALIUtils::debug >= 6) std::cout << _OutputLengthValueDimensionFactor << "Output Length Dimension Factors" << _OutputLengthSigmaDimensionFactor << std::endl;
00161
00162 }
00163
00164
00165
00166
00167
00168
00169 void ALIUtils::SetOutputAngleDimensionFactors()
00170 {
00171
00172
00173 GlobalOptionMgr* gomgr = GlobalOptionMgr::getInstance();
00174 ALIint ad = ALIint(gomgr->GlobalOptions()[ ALIstring("output_angle_value_dimension") ]);
00175 if( ad == 0 ) ad = ALIint(gomgr->GlobalOptions()[ ALIstring("angle_value_dimension") ]);
00176 _OutputAngleValueDimensionFactor = CalculateAngleDimensionFactorFromInt(ad);
00177
00178
00179 ad = ALIint(gomgr->GlobalOptions()[ ALIstring("output_angle_error_dimension") ]);
00180 if( ad == 0) ad = ALIint(gomgr->GlobalOptions()[ ALIstring("angle_error_dimension") ]);
00181 _OutputAngleSigmaDimensionFactor = CalculateAngleDimensionFactorFromInt(ad);
00182
00183
00184
00185
00186
00187 if(ALIUtils::debug >= 9) std::cout << _OutputAngleValueDimensionFactor << "Output Angle Dimension Factors" << _OutputAngleSigmaDimensionFactor << std::endl;
00188
00189 }
00190
00191
00192
00193
00194
00195
00196 ALIdouble ALIUtils::CalculateLengthDimensionFactorFromString( ALIstring dimstr )
00197 {
00198 ALIdouble valsig = 1.;
00199 ALIstring internalDim = "m";
00200 if(internalDim == "m" ){
00201 if( dimstr == "m" ) {
00202 valsig = 1.;
00203 }else if( dimstr == "mm" ) {
00204 valsig = 1.E-3;
00205 }else if( dimstr == "mum" ) {
00206 valsig = 1.E-6;
00207 }else if( dimstr == "cm" ) {
00208 valsig = 1.E-2;
00209 }else {
00210 std::cerr << "!!! UNKNOWN DIMENSION SCALING " << dimstr << std::endl <<
00211 "VALUE MUST BE BETWEEN 0 AND 3 " << std::endl;
00212 exit(1);
00213 }
00214 }else if(internalDim == "mm" ){
00215 if( dimstr == "m" ) {
00216 valsig = 1.E3;
00217 }else if( dimstr == "mm" ) {
00218 valsig = 1.;
00219 }else if( dimstr == "mum" ) {
00220 valsig = 1.E-3;
00221 }else if( dimstr == "cm" ) {
00222 valsig = 1.E+1;
00223 }else {
00224 std::cerr << "!!! UNKNOWN DIMENSION SCALING: " << dimstr << std::endl <<
00225 "VALUE MUST BE A LENGTH DIMENSION " << std::endl;
00226 exit(1);
00227 }
00228 }
00229
00230 return valsig;
00231 }
00232
00233
00234
00235
00236
00237 ALIdouble ALIUtils::CalculateAngleDimensionFactorFromString( ALIstring dimstr )
00238 {
00239 ALIdouble valsig;
00240 if( dimstr == "rad" ) {
00241 valsig = 1.;
00242 }else
00243 if( dimstr == "mrad" ) {
00244 valsig = 1.E-3;
00245 }else
00246 if( dimstr == "murad" ) {
00247 valsig = 1.E-6;
00248 }else
00249 if( dimstr == "deg" ) {
00250 valsig = M_PI/180.;
00251 }else
00252 if( dimstr == "grad" ) {
00253 valsig = M_PI/200.;
00254 }else {
00255 std::cerr << "!!! UNKNOWN DIMENSION SCALING: " << dimstr << std::endl <<
00256 "VALUE MUST BE AN ANGLE DIMENSION " << std::endl;
00257 exit(1);
00258 }
00259
00260 return valsig;
00261 }
00262
00263
00264
00265
00266 ALIdouble ALIUtils::CalculateLengthDimensionFactorFromInt( ALIint ad )
00267 {
00268 ALIdouble valsig;
00269 switch ( ad ) {
00270 case 0:
00271 valsig = CalculateLengthDimensionFactorFromString( "m" );
00272 break;
00273 case 1:
00274 valsig = CalculateLengthDimensionFactorFromString( "mm" );
00275 break;
00276 case 2:
00277 valsig = CalculateLengthDimensionFactorFromString( "mum" );
00278 break;
00279 case 3:
00280 valsig = CalculateLengthDimensionFactorFromString( "cm" );
00281 break;
00282 default:
00283 std::cerr << "!!! UNKNOWN DIMENSION SCALING " << ad << std::endl <<
00284 "VALUE MUST BE BETWEEN 0 AND 3 " << std::endl;
00285 exit(1);
00286 }
00287
00288
00289
00290
00291 return valsig;
00292 }
00293
00294
00295
00296
00297
00298 ALIdouble ALIUtils::CalculateAngleDimensionFactorFromInt( ALIint ad )
00299 {
00300 ALIdouble valsig;
00301 switch ( ad ) {
00302 case 0:
00303 valsig = CalculateAngleDimensionFactorFromString( "rad" );
00304 break;
00305 case 1:
00306 valsig = CalculateAngleDimensionFactorFromString( "mrad" );
00307 break;
00308 case 2:
00309 valsig = CalculateAngleDimensionFactorFromString( "murad" );
00310 break;
00311 case 3:
00312 valsig = CalculateAngleDimensionFactorFromString( "deg" );
00313 break;
00314 case 4:
00315 valsig = CalculateAngleDimensionFactorFromString( "grad" );
00316 break;
00317 default:
00318 std::cerr << "!!! UNKNOWN DIMENSION SCALING " << ad << std::endl <<
00319 "VALUE MUST BE BETWEEN 0 AND 3 " << std::endl;
00320 exit(1);
00321 }
00322
00323
00324
00325
00326 return valsig;
00327 }
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337 void ALIUtils::dumpDimensions( std::ofstream& fout )
00338 {
00339 fout << "DIMENSIONS: lengths = ";
00340 ALIstring internalDim = "m";
00341 if(_OutputLengthValueDimensionFactor == 1. ) {
00342 fout << "m";
00343 }else if(_OutputLengthValueDimensionFactor == 1.E-3 ) {
00344 fout << "mm";
00345 }else if(_OutputLengthValueDimensionFactor == 1.E-6 ) {
00346 fout << "mum";
00347 }else if(_OutputLengthValueDimensionFactor == 1.E-2 ) {
00348 fout << "cm";
00349 } else {
00350 std::cerr << " !! unknown OutputLengthValueDimensionFactor " << _OutputLengthValueDimensionFactor << std::endl;
00351 exit(1);
00352 }
00353
00354 fout << " +- ";
00355 if(_OutputLengthSigmaDimensionFactor == 1. ) {
00356 fout << "m";
00357 }else if(_OutputLengthSigmaDimensionFactor == 1.E-3 ) {
00358 fout << "mm";
00359 }else if(_OutputLengthSigmaDimensionFactor == 1.E-6 ) {
00360 fout << "mum";
00361 }else if(_OutputLengthSigmaDimensionFactor == 1.E-2 ) {
00362 fout << "cm";
00363 } else {
00364 std::cerr << " !! unknown OutputLengthSigmaDimensionFactor " << _OutputLengthSigmaDimensionFactor << std::endl;
00365 exit(1);
00366 }
00367
00368 fout << " angles = ";
00369 if(_OutputAngleValueDimensionFactor == 1. ) {
00370 fout << "rad";
00371 }else if(_OutputAngleValueDimensionFactor == 1.E-3 ) {
00372 fout << "mrad";
00373 }else if(_OutputAngleValueDimensionFactor == 1.E-6 ) {
00374 fout << "murad";
00375 }else if(_OutputAngleValueDimensionFactor == M_PI/180. ) {
00376 fout << "deg";
00377 }else if(_OutputAngleValueDimensionFactor == M_PI/200. ) {
00378 fout << "grad";
00379 } else {
00380 std::cerr << " !! unknown OutputAngleValueDimensionFactor " << _OutputAngleValueDimensionFactor << std::endl;
00381 exit(1);
00382 }
00383
00384 fout << " +- ";
00385 if(_OutputAngleSigmaDimensionFactor == 1. ) {
00386 fout << "rad";
00387 }else if(_OutputAngleSigmaDimensionFactor == 1.E-3 ) {
00388 fout << "mrad";
00389 }else if(_OutputAngleSigmaDimensionFactor == 1.E-6 ) {
00390 fout << "murad";
00391 }else if(_OutputAngleSigmaDimensionFactor == M_PI/180. ) {
00392 fout << "deg";
00393 }else if(_OutputAngleSigmaDimensionFactor == M_PI/200. ) {
00394 fout << "grad";
00395 } else {
00396 std::cerr << " !! unknown OutputAngleSigmaDimensionFactor " << _OutputAngleSigmaDimensionFactor << std::endl;
00397 exit(1);
00398 }
00399 fout << std::endl;
00400
00401 }
00402
00403
00404 double ALIUtils::getFloat( const ALIstring& str )
00405 {
00406
00407 if(!IsNumber(str) ) {
00408 std::cerr << "!!!! EXITING: trying to get the float from a string that is not a number " << str << std::endl;
00409 exit(1);
00410 }
00411
00412 return atof( str.c_str() );
00413 }
00414
00415
00416
00417 int ALIUtils::getInt( const ALIstring& str )
00418 {
00419
00420 if(!IsNumber(str) ) {
00421
00422 std::cerr << "!!!! EXITING: trying to get the integer from a string that is not a number " << str << std::endl;
00423 exit(1);
00424 } else {
00425
00426 bool isFloat = 0;
00427 int ch = str.find('.');
00428 ALIuint ii = 0;
00429 if(ch != -1 ) {
00430 for( ii = ch+1; ii < str.size(); ii++) {
00431 if( str[ii] != '0' ) isFloat = 1;
00432 }
00433 }
00434
00435 ch = str.find('E');
00436 if(ch != -1 ) ch = str.find('e');
00437 if(ch != -1 ) {
00438 if(str[ch+1] == '-') isFloat = 1;
00439 }
00440
00441 if(isFloat) {
00442 std::cerr << "!!!! EXITING: trying to get the integer from a string that is a float: " << str << std::endl;
00443 std::cerr << ii << " ii " << ch <<std::endl;
00444 exit(1);
00445 }
00446 }
00447 return int( atof( str.c_str() ) );
00448 }
00449
00450
00451
00452
00453 bool ALIUtils::getBool( const ALIstring& str )
00454 {
00455 bool val;
00456
00457
00458
00459 if( str == "ON" || str == "TRUE" ) {
00460 val = true;
00461 } else if( str == "OFF" || str == "FALSE" ) {
00462 val = false;
00463 } else {
00464 std::cerr << "!!!! EXITING: trying to get the float from a string that is not 'ON'/'OFF'/'TRUE'/'FALSE' " << str << std::endl;
00465 exit(1);
00466 }
00467
00468 return val;
00469 }
00470
00471
00472 ALIstring ALIUtils::subQuotes( const ALIstring& str )
00473 {
00474
00475
00476 if( str.find('"') != 0 || str.rfind('"') != str.length()-1 ) {
00477 std::cerr << "!!!EXITING trying to substract quotes from a word that has no quotes " << str << std::endl;
00478 exit(1);
00479 }
00480
00481
00482
00483 ALIstring strt = str.substr(1,str.size()-2);
00484
00485
00486
00487 while( strt[0] == ' ' ) {
00488 strt = strt.substr(1,strt.size()-1);
00489 }
00490
00491
00492 while( strt[strt.size()-1] == ' ' ) {
00493 strt = strt.substr(0,strt.size()-1);
00494 }
00495
00496 return strt;
00497
00498 }
00499
00500
00501 void ALIUtils::dumpVS( const std::vector<ALIstring>& wl , const std::string& msg, std::ostream& outs )
00502 {
00503 outs << msg << std::endl;
00504 ALIuint siz = wl.size();
00505 for( ALIuint ii=0; ii< siz; ii++ ){
00506 outs << wl[ii] << " ";
00507
00508
00509 }
00510 outs << std::endl;
00511 }
00512
00513
00514
00515 ALIdouble ALIUtils::getDimensionValue( const ALIstring& dim, const ALIstring& dimType )
00516 {
00517 ALIdouble value;
00518 if( dimType == "Length" ) {
00519 if( dim == "mm" ) {
00520 value = 1.E-3;
00521 }else if( dim == "cm" ) {
00522 value = 1.E-2;
00523 }else if( dim == "m" ) {
00524 value = 1.;
00525 }else if( dim == "mum" ) {
00526 value = 1.E-6;
00527 }else if( dim == "dm" ) {
00528 value = 1.E-1;
00529 }else if( dim == "nm" ) {
00530 value = 1.E-9;
00531 }else {
00532 std::cerr << "!!!!FATAL ERROR: ALIUtils::GetDimensionValue. " << dim << " is a dimension not supported for dimension type " << dimType << std::endl;
00533 abort();
00534 }
00535 } else if( dimType == "Angle" ) {
00536 if( dim == "rad" ) {
00537 value = 1.;
00538 }else if( dim == "mrad" ) {
00539 value = 1.E-3;
00540 }else if( dim == "murad" ) {
00541 value = 1.E-6;
00542 }else if( dim == "deg" ) {
00543 value = M_PI/180.;
00544 }else if( dim == "grad" ) {
00545 value = M_PI/200.;
00546 }else {
00547 std::cerr << "!!!!FATAL ERROR: ALIUtils::GetDimensionValue. " << dim << " is a dimension not supported for dimension type " << dimType << std::endl;
00548 abort();
00549 }
00550 }else {
00551 std::cerr << "!!!!FATAL ERROR: ALIUtils::GetDimensionValue. " << dimType << " is a dimension type not supported " << std::endl;
00552 abort();
00553 }
00554
00555 return value;
00556
00557 }
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573 std::string ALIUtils::changeName( const std::string& oldName, const std::string& subsstr1, const std::string& subsstr2 )
00574 {
00575
00576 std::string newName = oldName;
00577 int il = oldName.find( subsstr1 );
00578
00579 while( il >= 0 ) {
00580 newName = newName.substr( 0, il ) + subsstr2 + newName.substr( il+subsstr1.length(), newName.length() );
00581
00582 il = oldName.find( subsstr1, il+1 );
00583 }
00584
00585 return newName;
00586 }
00587
00588
00589
00590
00591 std::vector<double> ALIUtils::getRotationAnglesFromMatrix( CLHEP::HepRotation& rmLocal, double origAngleX, double origAngleY, double origAngleZ )
00592 {
00593 double pii = acos(0.)*2;
00594 std::vector<double> newang(3);
00595 double angleX = origAngleX;
00596 double angleY = origAngleY;
00597 double angleZ = origAngleZ;
00598
00599 if( ALIUtils::debug >= 4 ) {
00600 std::cout << " angles as value entries: X= " << angleX << " Y= " << angleY << " Z " << angleZ << std::endl;
00601 }
00602
00603
00604 double rotzx = approxTo0( rmLocal.zx() );
00605 double rotzy = approxTo0( rmLocal.zy() );
00606 double rotzz = approxTo0( rmLocal.zz() );
00607 double rotyx = approxTo0( rmLocal.yx() );
00608 double rotxx = approxTo0( rmLocal.xx() );
00609 if( rotzy == 0. && rotzz == 0. ) {
00610
00611 newang[0] = angleX;
00612
00613 if( eq2ang( rmLocal.zx(), -1. ) ) {
00614 double aa = asin( rmLocal.xy() );
00615 if( diff2pi( angleZ, - aa + newang[0] ) < diff2pi( angleZ, - pii + aa + newang[0] ) ) {
00616 newang[2] = -aa + newang[0];
00617 if( ALIUtils::debug >= 5 ) std::cout << " newang[0] = -aa + newang[0] " << std::endl;
00618 } else {
00619 newang[2] = -pii + aa + newang[0];
00620 if( ALIUtils::debug >= 5 ) std::cout << " newang[0] = -pii + aa + newang[0] " << newang[0] << " " << aa << " " << newang[2] << std::endl;
00621 }
00622 } else {
00623 double aa = asin( -rmLocal.xy() );
00624 if( diff2pi( angleZ, aa - newang[0] ) < diff2pi( angleZ, pii - aa - newang[0] ) ) {
00625 newang[2] = aa - newang[0];
00626 if( ALIUtils::debug >= 5 ) std::cout << " newang[0] = aa - newang[2] " << std::endl;
00627 } else {
00628 newang[2] = pii - aa - newang[0];
00629 if( ALIUtils::debug >= 5 ) std::cout << " newang[0] = pii - aa - newang[2] " << newang[0] << " " << aa << " " << newang[2] << std::endl;
00630 }
00631 }
00632 } else {
00633 newang[0] = atan( rotzy / rotzz );
00634 newang[2] = atan( rotyx / rotxx );
00635 }
00636 if( rotzx < -1. ) {
00637
00638 rotzx = -1.;
00639 } else if( rotzx > 1. ) {
00640
00641 rotzx = 1.;
00642 }
00643 newang[1] = -asin( rotzx );
00644 if( ALIUtils::debug >= 5 ) std::cout << "First calculation of angles: " << std::endl
00645 << " newang[0] " << newang[0] << " " << rotzy << " " << rotzz << std::endl
00646 << " newang[1] " << newang[1] << " " << rotzx << std::endl
00647 << " newang[2] " << newang[2] << " " << rotyx << " " << rotxx << std::endl;
00648
00649
00650
00651
00652 double rotnewxx = cos( newang[1] ) * cos( newang[2] );
00653 double rotnewzz = cos( newang[0] ) * cos( newang[1] );
00654 double rotnewxy = sin( newang[0] ) * sin( newang[1] ) * cos( newang[2] ) - cos( newang[0] )* sin( newang[2] );
00655 double rotnewxz = cos( newang[0] ) * sin( newang[1] ) * cos( newang[2] ) + sin( newang[0] )* sin( newang[2] );
00656 double rotnewyy = sin( newang[0] ) * sin( newang[1] ) * sin( newang[2] ) + cos( newang[0] )* cos( newang[2] );
00657 double rotnewyz = cos( newang[0] ) * sin( newang[1] ) * sin( newang[2] ) - sin( newang[0] )* cos( newang[2] );
00658
00659 bool eqxx = eq2ang( rotnewxx, rmLocal.xx() );
00660 bool eqzz = eq2ang( rotnewzz, rmLocal.zz() );
00661 bool eqxy = eq2ang( rotnewxy, rmLocal.xy() );
00662 bool eqxz = eq2ang( rotnewxz, rmLocal.xz() );
00663 bool eqyy = eq2ang( rotnewyy, rmLocal.yy() );
00664 bool eqyz = eq2ang( rotnewyz, rmLocal.yz() );
00665
00666
00667 if( ALIUtils::debug >= 5 ) {
00668 std::cout << " pred rm.xx " << rotnewxx << " =? " << rmLocal.xx()
00669 << " pred rm.zz " << rotnewzz << " =? " << rmLocal.zz()
00670 << std::endl;
00671 std::cout << " eqxx " << eqxx << " eqzz " << eqzz << std::endl;
00672
00673 }
00674
00675 if( eqxx & !eqzz ) {
00676 newang[0] = pii + newang[0];
00677 if( ALIUtils::debug >= 5 ) std::cout << " change newang[0] " << newang[0] << std::endl;
00678 } else if( !eqxx & !eqzz ) {
00679 newang[1] = pii - newang[1];
00680 if( ALIUtils::debug >= 5 ) std::cout << " change newang[1] " << newang[1] << std::endl;
00681 } else if( !eqxx & eqzz ) {
00682 newang[2] = pii + newang[2];
00683 if( ALIUtils::debug >= 5 ) std::cout << " change newang[2] " << newang[2] << std::endl;
00684 }
00685
00686
00687 if( ALIUtils::debug >= 5 ) {
00688 std::cout << " pred rm.xy " << rotnewxy << " =? " << rmLocal.xy()
00689 << " pred rm.xz " << rotnewxz << " =? " << rmLocal.xz()
00690 << " pred rm.yy " << rotnewyy << " =? " << rmLocal.yy()
00691 << " pred rm.yz " << rotnewyz << " =? " << rmLocal.yz()
00692 << std::endl;
00693 std::cout << " eqxy " << eqxy << " eqxz " << eqxz << " eqyy " << eqyy << " eqyz " << eqyz << std::endl;
00694 }
00695
00696 if( !eqxy || !eqxz || !eqyy || !eqyz ) {
00697
00698 if( ALIUtils::debug >= 5 ) std::cout << " change the 3 newang " << std::endl;
00699 newang[0] = addPii( newang[0] );
00700 newang[1] = pii - newang[1];
00701 newang[2] = addPii( newang[2] );
00702 double rotnewxy = -sin( newang[0] ) * sin( newang[1] ) * cos( newang[2] ) - cos( newang[0] )* sin( newang[2] );
00703 double rotnewxz = -cos( newang[0] ) * sin( newang[1] ) * cos( newang[2] ) - sin( newang[0] )* sin( newang[2] );
00704 if( ALIUtils::debug >= 5 ) std::cout << " rotnewxy " << rotnewxy << " = " << rmLocal.xy()
00705 << " rotnewxz " << rotnewxz << " = " << rmLocal.xz() << std::endl;
00706 }
00707 if( diff2pi(angleX, newang[0] ) + diff2pi(angleY, newang[1] ) +diff2pi(angleZ, newang[2] )
00708 > diff2pi(angleX, pii+newang[0] ) + diff2pi(angleY, pii-newang[1] ) + diff2pi(angleZ, pii+newang[2] ) ){
00709
00710 if( ALIUtils::debug >= 5 ) std::cout << " change the 3 newang " << std::endl;
00711 newang[0] = addPii( newang[0] );
00712 newang[1] = pii - newang[1];
00713 newang[2] = addPii( newang[2] );
00714 double rotnewxy = -sin( newang[0] ) * sin( newang[1] ) * cos( newang[2] ) - cos( newang[0] )* sin( newang[2] );
00715 double rotnewxz = -cos( newang[0] ) * sin( newang[1] ) * cos( newang[2] ) - sin( newang[0] )* sin( newang[2] );
00716 if( ALIUtils::debug >= 5 ) std::cout << " rotnewxy " << rotnewxy << " = " << rmLocal.xy()
00717 << " rotnewxz " << rotnewxz << " = " << rmLocal.xz() << std::endl;
00718 }
00719
00720 for (int ii=0; ii<3; ii++) {
00721 newang[ii] = approxTo0( newang[ii] );
00722 }
00723
00724
00725 if( checkMatrixEquations( newang[0], newang[1], newang[2], &rmLocal ) != 0 ){
00726 std::cerr << " wrong rotation matrix " << newang[0] << " " << newang[1] << " " << newang[2] << std::endl;
00727 ALIUtils::dumprm( rmLocal, " matrix is " );
00728 }
00729 if( ALIUtils::debug >= 5 ) {
00730 std::cout << "Final angles: newang[0] " << newang[0] << " newang[1] " << newang[1] << " newang[2] " << newang[2] << std::endl;
00731 CLHEP::HepRotation rot;
00732 rot.rotateX( newang[0] );
00733 ALIUtils::dumprm( rot, " new rot after X ");
00734 rot.rotateY( newang[1] );
00735 ALIUtils::dumprm( rot, " new rot after Y ");
00736 rot.rotateZ( newang[2] );
00737 ALIUtils::dumprm( rot, " new rot ");
00738 ALIUtils::dumprm( rmLocal, " rmLocal " );
00739
00740 }
00741
00742
00743 return newang;
00744
00745 }
00746
00747
00748 double ALIUtils::diff2pi( double ang1, double ang2 )
00749 {
00750 double pii = acos(0.)*2;
00751 double diff = fabs( ang1 - ang2 );
00752 diff = diff - int(diff/2./pii) * 2 *pii;
00753 return diff;
00754 }
00755
00756
00757
00758 bool ALIUtils::eq2ang( double ang1, double ang2 )
00759 {
00760 bool beq = true;
00761
00762 double pii = acos(0.)*2;
00763 double diff = diff2pi( ang1, ang2 );
00764 if( diff > 0.00001 ) {
00765 if( fabs( diff - 2*pii ) > 0.00001 ) {
00766
00767 beq = false;
00768 }
00769 } else {
00770 beq = true;
00771 }
00772
00773 return beq;
00774 }
00775
00776
00777
00778 double ALIUtils::approxTo0( double val )
00779 {
00780 double precision = 1.e-9;
00781 if( fabs(val) < precision ) val = 0;
00782 return val;
00783 }
00784
00785
00786
00787 double ALIUtils::addPii( double val )
00788 {
00789 if( val < M_PI ) {
00790 val += M_PI;
00791 } else {
00792 val -= M_PI;
00793 }
00794
00795 return val;
00796 }
00797
00798
00799 int ALIUtils::checkMatrixEquations( double angleX, double angleY, double angleZ, CLHEP::HepRotation* rot)
00800 {
00801
00802 if( rot == 0 ) {
00803 rot = new CLHEP::HepRotation();
00804 rot->rotateX( angleX );
00805 rot->rotateY( angleY );
00806 rot->rotateZ( angleZ );
00807 }
00808 double sx = sin(angleX);
00809 double cx = cos(angleX);
00810 double sy = sin(angleY);
00811 double cy = cos(angleY);
00812 double sz = sin(angleZ);
00813 double cz = cos(angleZ);
00814
00815 double rotxx = cy*cz;
00816 double rotxy = sx*sy*cz-cx*sz;
00817 double rotxz = cx*sy*cz+sx*sz;
00818 double rotyx = cy*sz;
00819 double rotyy = sx*sy*sz+cx*cz;
00820 double rotyz = cx*sy*sz-sx*cz;
00821 double rotzx = -sy;
00822 double rotzy = sx*cy;
00823 double rotzz = cx*cy;
00824
00825 int matrixElemBad = 0;
00826 if( !eq2ang( rot->xx(), rotxx ) ) {
00827 std::cerr << " EQUATION for xx() IS BAD " << rot->xx() << " <> " << rotxx << std::endl;
00828 matrixElemBad++;
00829 }
00830 if( !eq2ang( rot->xy(), rotxy ) ) {
00831 std::cerr << " EQUATION for xy() IS BAD " << rot->xy() << " <> " << rotxy << std::endl;
00832 matrixElemBad++;
00833 }
00834 if( !eq2ang( rot->xz(), rotxz ) ) {
00835 std::cerr << " EQUATION for xz() IS BAD " << rot->xz() << " <> " << rotxz << std::endl;
00836 matrixElemBad++;
00837 }
00838 if( !eq2ang( rot->yx(), rotyx ) ) {
00839 std::cerr << " EQUATION for yx() IS BAD " << rot->yx() << " <> " << rotyx << std::endl;
00840 matrixElemBad++;
00841 }
00842 if( !eq2ang( rot->yy(), rotyy ) ) {
00843 std::cerr << " EQUATION for yy() IS BAD " << rot->yy() << " <> " << rotyy << std::endl;
00844 matrixElemBad++;
00845 }
00846 if( !eq2ang( rot->yz(), rotyz ) ) {
00847 std::cerr << " EQUATION for yz() IS BAD " << rot->yz() << " <> " << rotyz << std::endl;
00848 matrixElemBad++;
00849 }
00850 if( !eq2ang( rot->zx(), rotzx ) ) {
00851 std::cerr << " EQUATION for zx() IS BAD " << rot->zx() << " <> " << rotzx << std::endl;
00852 matrixElemBad++;
00853 }
00854 if( !eq2ang( rot->zy(), rotzy ) ) {
00855 std::cerr << " EQUATION for zy() IS BAD " << rot->zy() << " <> " << rotzy << std::endl;
00856 matrixElemBad++;
00857 }
00858 if( !eq2ang( rot->zz(), rotzz ) ) {
00859 std::cerr << " EQUATION for zz() IS BAD " << rot->zz() << " <> " << rotzz << std::endl;
00860 matrixElemBad++;
00861 }
00862
00863
00864 return matrixElemBad;
00865 }
00866