00001
00002
00003
00004
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 #include <iomanip>
00035 #include <set>
00036
00037 #include "G4tgrUtils.hh"
00038
00039 #include "geomdefs.hh"
00040 #include "G4PhysicalConstants.hh"
00041 #include "G4tgrParameterMgr.hh"
00042 #include "G4tgrMessenger.hh"
00043 #include "G4UnitsTable.hh"
00044 #include "G4GeometryTolerance.hh"
00045 #include "G4UIcommand.hh"
00046
00047
00048 G4tgrEvaluator* G4tgrUtils::theEvaluator = new G4tgrEvaluator;
00049
00050
00051
00052 G4tgrUtils::G4tgrUtils()
00053 {
00054 }
00055
00056
00057
00058 G4tgrUtils::~G4tgrUtils()
00059 {
00060 }
00061
00062
00063
00064 G4bool G4tgrUtils::IsSeparator( const char ch)
00065 {
00066 char nonCharacters[7] = {"()+-*/"};
00067 for( size_t ii = 0; ii < 6; ii++ )
00068 {
00069 if( ch == nonCharacters[ii] )
00070 {
00071 return true;
00072 }
00073 }
00074 return false;
00075 }
00076
00077
00078
00079 G4bool G4tgrUtils::IsNumber( const G4String& str)
00080 {
00081 G4int isnum = 1;
00082 G4int numE = 0;
00083 for(size_t ii=0; ii<str.length(); ii++)
00084 {
00085 if(!isdigit(str[ii]) && (str[ii]!='.') && (str[ii]!='-') && (str[ii]!='+'))
00086 {
00087
00088 if(str[ii] == 'E' || str[ii] == 'e' )
00089 {
00090 if( ii == 0 ) { return 0; }
00091 if(numE != 0 || ii == str.length()-1)
00092 {
00093 isnum = 0;
00094 break;
00095 }
00096 numE++;
00097 }
00098 else
00099 {
00100 isnum = 0;
00101 break;
00102 }
00103 }
00104 }
00105 return isnum;
00106 }
00107
00108
00109
00110 G4bool G4tgrUtils::IsInteger( const G4double val, const G4double precision )
00111 {
00112 if( G4int(val) / val - 1 > precision )
00113 {
00114 return 0;
00115 }
00116 else
00117 {
00118 return 1;
00119 }
00120 }
00121
00122
00123
00124 void G4tgrUtils::Dump3v( const G4ThreeVector& vec, const char* msg)
00125 {
00126 G4cout << msg << std::setprecision(8)
00127 << vec << std::setprecision(6) << G4endl;
00128 }
00129
00130
00131
00132 void G4tgrUtils::Dumprm( const G4RotationMatrix& rm, const char* msg)
00133 {
00134 G4cout << msg << G4endl
00135 << " xx=" << rm.xx() << " yx=" << rm.yx() << " zx=" << rm.zx() << G4endl
00136 << " xy=" << rm.xy() << " yy=" << rm.yy() << " zy=" << rm.zy() << G4endl
00137 << " xz=" << rm.xz() << " yz=" << rm.yz() << " zz=" << rm.zz() << G4endl;
00138 }
00139
00140
00141
00142 void G4tgrUtils::DumpVS( const std::vector<G4String>& wl,
00143 const char* msg, std::ostream& outs )
00144 {
00145 outs << msg << G4endl;
00146 std::vector<G4String>::const_iterator ite;
00147 for( ite = wl.begin(); ite != wl.end(); ite++ )
00148 {
00149 outs << *ite << " ";
00150 }
00151 outs << G4endl;
00152 }
00153
00154
00155
00156 void G4tgrUtils::DumpVS( const std::vector<G4String>& wl , const char* msg)
00157 {
00158 DumpVS( wl, msg, G4cout);
00159 }
00160
00161
00162
00163 G4String G4tgrUtils::SubColon( const G4String& str )
00164 {
00165 if( str.find(':') != 0 )
00166 {
00167 G4String ErrMessage = "Trying to subtract leading colon from a word\n"
00168 + G4String("that has no leading colon: ") + str;
00169 G4Exception("G4tgrUtils::SubColon()", "ParseError",
00170 FatalException, ErrMessage);
00171 }
00172 G4String strt = str.substr(1,str.size()-1);
00173 return strt;
00174 }
00175
00176
00177
00178 G4String G4tgrUtils::GetString( const G4String& str )
00179 {
00180
00181 const char* cstr = str.c_str();
00182 if( cstr[0] == '$' )
00183 {
00184 #ifdef G4VERBOSE
00185 if( G4tgrMessenger::GetVerboseLevel() >= 3 )
00186 {
00187 G4cout << " G4tgrUtils::GetString() - Substitute parameter: "
00188 << G4tgrParameterMgr::GetInstance()
00189 ->FindParameter( str.substr(1,str.size())) << G4endl;
00190 }
00191 #endif
00192 return G4tgrParameterMgr::GetInstance()
00193 ->FindParameter( str.substr(1,str.size()) );
00194 }
00195 else
00196 {
00197 return str;
00198 }
00199 }
00200
00201
00202
00203 G4double G4tgrUtils::GetDouble( const G4String& str, G4double unitval )
00204 {
00205 #ifdef G4VERBOSE
00206 if( G4tgrMessenger::GetVerboseLevel() >= 3 )
00207 {
00208 G4cout << "G4tgrUtils::GetDouble() - Processing: "
00209 << str << " default unit " << unitval << G4endl;
00210 }
00211 #endif
00212 if( str == "DBL_MAX" ) {
00213 return DBL_MAX;
00214 }else if( str == "DBL_MIN" ) {
00215 return DBL_MIN;
00216 }else if( str == "FLT_MAX" ) {
00217 return FLT_MAX;
00218 }else if( str == "FLT_MIN" ) {
00219 return FLT_MIN;
00220 }else if( str == "INT_MAX" ) {
00221 return INT_MAX;
00222 }else if( str == "INT_MIN" ) {
00223 return INT_MIN;
00224 }
00225
00226 const char* cstr = str.c_str();
00227 std::set<G4int> separators;
00228 separators.insert(-1);
00229 G4int strlen = G4int(str.length());
00230 for(G4int ii=0; ii<strlen; ii++)
00231 {
00232 char cs = cstr[ii];
00233 if( cs == '*' || cs == '/' || cs == '(' || cs == ')' )
00234 {
00235 separators.insert(ii);
00236 }
00237 else if( cs == '+' || cs == '-' )
00238 {
00239
00240
00241 if( (ii < 2)
00242 || ( (cstr[ii-1] != 'E') && (cstr[ii-1] != 'e') )
00243 || !IsNumber(cstr[ii-2]) )
00244 {
00245 separators.insert(ii);
00246 }
00247 }
00248 }
00249 separators.insert(strlen);
00250 std::string strnew;
00251
00252
00253 G4int nUnits = 0;
00254 std::set<G4int>::const_iterator site, site2;
00255 site = separators.begin();
00256 site2 = site; site2++;
00257 for( ; site2 != separators.end(); site++,site2++)
00258 {
00259 #ifdef G4VERBOSE
00260 if( G4tgrMessenger::GetVerboseLevel() >= 3 )
00261 {
00262 G4cout << " Loop to find word between " << *site
00263 << " " << *site2 << G4endl;
00264 }
00265 #endif
00266
00267 if( *site != -1 ) { strnew += str.substr(*site,1); }
00268
00269 G4int wlen = (*site2)-(*site)-1;
00270 std::string word;
00271 if(wlen != 0)
00272 {
00273 word = str.substr((*site)+1,(*site2)-(*site)-1);
00274 }
00275 else
00276 {
00277
00278
00279 continue;
00280 }
00281
00282 #ifdef G4VERBOSE
00283 if( G4tgrMessenger::GetVerboseLevel() >= 3 )
00284 {
00285 G4cout << " Processing word: " << word << G4endl;
00286 }
00287 #endif
00288
00289 const char* cword = word.c_str();
00290 if( cword[0] == '$' )
00291 {
00292 G4String parstr = G4tgrParameterMgr::GetInstance()
00293 ->FindParameter( word.substr(1,word.size()));
00294 if( parstr.substr(0,1) == "-" )
00295 {
00296 strnew += "(";
00297 }
00298 strnew += parstr;
00299 if( parstr.substr(0,1) == "-" )
00300 {
00301 strnew += ")";
00302 }
00303 #ifdef G4VERBOSE
00304 if( G4tgrMessenger::GetVerboseLevel() >= 3 )
00305 {
00306 G4cout << " G4tgrutils::GetDouble() - Param found: "
00307 << word << " in string " << str
00308 << " , substituted by " << parstr << G4endl;
00309 }
00310 #endif
00311 }
00312 else
00313 {
00314
00315 if( IsNumber(word) )
00316 {
00317
00318 if( (*site != -1) && (cstr[*site] == ')') )
00319 {
00320 G4String ErrMessage = "There cannot be a ')' before a number: "
00321 + word + " in string: " + str;
00322 G4Exception("G4tgrUtils::GetDouble()", "ParseError",
00323 FatalException, ErrMessage);
00324 }
00325
00326 if( (*site2 != strlen) && (cstr[*site2] == '(') )
00327 {
00328 G4String ErrMessage = "There cannot be a '(' after a number: "
00329 + word + " in string: " + str;
00330 G4Exception("G4tgrUtils::GetDouble()", "ParseError",
00331 FatalException, ErrMessage);
00332 }
00333 strnew += word;
00334
00335
00336 }
00337 else
00338 {
00339
00340 if( isdigit(word[0]) )
00341 {
00342 G4String ErrMessage = "String words cannot start with a digit: "
00343 + word + " in string: " + str;
00344 G4Exception("G4tgrUtils::GetDouble()", "ParseError",
00345 FatalException, ErrMessage );
00346 }
00347
00348
00349 G4bool bWordOK = false;
00350 if( G4tgrUtils::IsFunction( word ) )
00351 {
00352
00353 if( (*site2 == strlen) || (cstr[*site2] != '(') )
00354 {
00355 G4String ErrMessage = "There must be a '(' after a function: "
00356 + word + " in string: " + str;
00357 G4Exception("G4tgrUtils::GetDouble()", "ParseError",
00358 FatalException, ErrMessage );
00359 }
00360 strnew += word;
00361 bWordOK = true;
00362
00363 }
00364 else if( G4tgrUtils::WordIsUnit( word ) )
00365 {
00366
00367 if( (*site == -1)
00368 || ( (cstr[*site] != '*') && (cstr[*site] != '/') ) )
00369 {
00370 G4String ErrMess = "There must be a '*' before a unit definition: "
00371 + word + " in string " + str;
00372 G4Exception("G4tgrUtils::GetDouble()", "ParseError",
00373 FatalException, ErrMess );
00374 }
00375
00376 if( G4UnitDefinition::GetValueOf(word) != 0. )
00377 {
00378 bWordOK = true;
00379 nUnits++;
00380 if( nUnits > 1 )
00381 {
00382
00383
00384
00385
00386 }
00387 strnew += G4UIcommand::ConvertToString( G4UnitDefinition::GetValueOf(word) );
00388 }
00389 }
00390 if( !bWordOK )
00391 {
00392 G4String ErrMess = "String word is not a parameter, nor a unit\n";
00393 + G4String("definition nor a function: ") + word
00394 + G4String(" in string: ") + str;
00395 G4Exception("G4tgrUtils::GetDouble()", "ParseError",
00396 FatalException, ErrMess );
00397 }
00398 }
00399 }
00400 }
00401
00402 G4double val = theEvaluator->evaluate( strnew.c_str() );
00403 if (theEvaluator->status() != HepTool::Evaluator::OK)
00404 {
00405 theEvaluator->print_error(theEvaluator->status());
00406 G4String ErrMessage = "Evaluator error: " + strnew;
00407 G4Exception("G4tgrUtils::GetDouble()", "ParseError",
00408 FatalException, ErrMessage );
00409 }
00410
00411 if( nUnits == 0 ) { val *= unitval; }
00412
00413 #ifdef G4VERBOSE
00414 if( G4tgrMessenger::GetVerboseLevel() >= 3 )
00415 {
00416 G4cout << " G4tgrUtils::GetDouble() - RESULT= " << val << G4endl
00417 << " from string: " << str << " converted to: " << strnew.c_str()
00418 << " with unit val: " << unitval << G4endl;
00419 }
00420 #endif
00421
00422 return val;
00423 }
00424
00425
00426
00427 G4int G4tgrUtils::GetInt( const G4String& str )
00428 {
00429
00430 G4double val = GetDouble(str);
00431
00432
00433 if( !IsInteger(val) )
00434 {
00435 G4String ErrMessage = G4String("Trying to get the integer from a number")
00436 + G4String(" which is not an integer ") + str;
00437 G4Exception("G4tgrUtils::GetInt()", "ParseError",
00438 FatalException, ErrMessage );
00439 }
00440 return G4int( val );
00441 }
00442
00443
00444
00445 G4bool G4tgrUtils::GetBool( const G4String& str )
00446 {
00447 G4bool val = false;
00448
00449
00450 if( (str == "ON") || (str == "TRUE") )
00451 {
00452 val = true;
00453 }
00454 else if( (str == "OFF") || (str == "FALSE") )
00455 {
00456 val = false;
00457 }
00458 else
00459 {
00460 G4String ErrMessage = G4String("Trying to get a float from a string")
00461 + G4String(" which is not 'ON'/'OFF'/'TRUE'/'FALSE' ")
00462 + str;
00463 G4Exception("G4tgrUtils::GetBool()", "ParseError",
00464 FatalException, ErrMessage );
00465 }
00466
00467 return val;
00468 }
00469
00470
00471
00472 void G4tgrUtils::CheckWLsize( const std::vector<G4String>& wl,
00473 unsigned int nWcheck, WLSIZEtype st,
00474 const G4String& methodName )
00475 {
00476
00477 G4String outStr = methodName + G4String(". Line read with number of words ");
00478 unsigned int wlsize = wl.size();
00479
00480 G4bool isOK = CheckListSize( wlsize, nWcheck, st, outStr );
00481
00482 if( !isOK )
00483 {
00484 G4String chartmp = G4UIcommand::ConvertToString( G4int(nWcheck) );
00485 outStr += chartmp + G4String(" words");
00486 DumpVS( wl, outStr.c_str() );
00487 G4String ErrMessage = " NUMBER OF WORDS: "
00488 + G4UIcommand::ConvertToString(G4int(wlsize));
00489 G4Exception("G4tgrUtils::CheckWLsize()", "ParseError",
00490 FatalException, ErrMessage);
00491 }
00492 }
00493
00494
00495 G4bool G4tgrUtils::CheckListSize( unsigned int nWreal, unsigned int nWcheck,
00496 WLSIZEtype st, G4String& outStr )
00497 {
00498 G4bool isOK = true;
00499 switch (st)
00500 {
00501 case WLSIZE_EQ:
00502 if( nWreal != nWcheck )
00503 {
00504 isOK = false;
00505 outStr += G4String("not equal than ");
00506 }
00507 break;
00508 case WLSIZE_NE:
00509 if( nWreal == nWcheck )
00510 {
00511 isOK = false;
00512 outStr += G4String("equal than ");
00513 }
00514 break;
00515 case WLSIZE_LE:
00516 if( nWreal > nWcheck )
00517 {
00518 isOK = false;
00519 outStr += G4String("greater than ");
00520 }
00521 break;
00522 case WLSIZE_LT:
00523 if( nWreal >= nWcheck )
00524 {
00525 isOK = false;
00526 outStr += G4String("greater or equal than ");
00527 }
00528 break;
00529 case WLSIZE_GE:
00530 if( nWreal < nWcheck )
00531 {
00532 isOK = false;
00533 outStr += G4String("less than ");
00534 }
00535 break;
00536 case WLSIZE_GT:
00537 if( nWreal <= nWcheck )
00538 {
00539 isOK = false;
00540 outStr += G4String("less or equal than ");
00541 }
00542 break;
00543 default:
00544 G4cerr << " ERROR!! - G4tgrUtils::CheckListSize()" << G4endl
00545 << " Type of WLSIZE type not found " << st << G4endl;
00546 break;
00547 }
00548
00549 return isOK;
00550 }
00551
00552
00553
00554 G4bool G4tgrUtils::WordIsUnit( const G4String& word )
00555 {
00556 return !IsNumber(word);
00557 if( word == "mm"
00558 || word == "cm"
00559 || word == "m"
00560 || word == "km"
00561 || word == "millimeter"
00562 || word == "centimeter"
00563 || word == "meter"
00564 || word == "kilometer"
00565 || word == "parsec"
00566 || word == "micrometer"
00567 || word == "nanometer"
00568 || word == "angstrom"
00569 || word == "fermi"
00570 || word == "nm"
00571 || word == "um"
00572 || word == "pc"
00573 || word == "radian"
00574 || word == "milliradian"
00575 || word == "degree"
00576 || word == "rad"
00577 || word == "mrad"
00578 || word == "deg"
00579 || word == "ns"
00580 || word == "curie"
00581 || word == "curie" )
00582 {
00583 return true;
00584 }
00585 else
00586 {
00587 return false;
00588 }
00589 }
00590
00591
00592
00593 G4bool G4tgrUtils::IsFunction( const G4String& word )
00594 {
00595 if( word == "sin"
00596 || word == "cos"
00597 || word == "tan"
00598 || word == "asin"
00599 || word == "acos"
00600 || word == "atan"
00601 || word == "atan2"
00602 || word == "sinh"
00603 || word == "cosh"
00604 || word == "tanh"
00605 || word == "asinh"
00606 || word == "acosh"
00607 || word == "atanh"
00608 || word == "sqrt"
00609 || word == "exp"
00610 || word == "log"
00611 || word == "log10"
00612 || word == "pow" )
00613 {
00614 return true;
00615 }
00616 else
00617 {
00618 return false;
00619 }
00620 }
00621
00622
00623
00624 G4RotationMatrix G4tgrUtils::GetRotationFromDirection( G4ThreeVector dir )
00625 {
00626 G4RotationMatrix rotation;
00627
00628 if( std::fabs(dir.mag()-1.) > G4GeometryTolerance::GetInstance()
00629 ->GetSurfaceTolerance() )
00630 {
00631 G4String WarMessage = "Direction cosines have been normalized to one.\n"
00632 + G4String("They were normalized to ")
00633 + G4UIcommand::ConvertToString(dir.mag());
00634 G4Exception("G4tgrUtils::GetRotationFromDirection()", "WrongArgument",
00635 JustWarning, WarMessage);
00636 dir /= dir.mag();
00637 }
00638 G4double angx = -std::asin(dir.y());
00639
00640
00641
00642
00643 G4double angy;
00644 if( dir.y() == 1. )
00645 {
00646 angy = 0.;
00647 }
00648 else if( dir.y() == 0. )
00649 {
00650 angy = 0.;
00651 }
00652 else
00653 {
00654 angy = std::asin( dir.x()/std::sqrt(1-dir.y()*dir.y()) );
00655 }
00656
00657
00658 if( dir.z() * std::cos(angx)*std::cos(angy) < 0 )
00659 {
00660 angy = pi - angy;
00661 }
00662 rotation.rotateX( angx );
00663 rotation.rotateY( angy );
00664
00665 return rotation;
00666 }
00667
00668
00669
00670 G4bool G4tgrUtils::AreWordsEquivalent( const G4String& word1,
00671 const G4String& word2 )
00672 {
00673 G4bool bEqual = true;
00674 std::vector< std::pair<size_t,size_t> > stringPairs;
00675
00676
00677
00678
00679 size_t cStart = 0;
00680 for( ;; )
00681 {
00682 size_t cAster = word1.find("*",cStart);
00683 if( cAster != std::string::npos )
00684 {
00685 if( cAster == cStart )
00686 {
00687 if( cAster != 0 )
00688 {
00689 G4Exception("G4tgrUtils::AreWordsEquivalent()",
00690 "A word has two asterisks together, please correct it",
00691 FatalException,("Offending word is: " + word1).c_str() );
00692 }
00693 else
00694 {
00695
00696 if(word1.size() == 1 ) { return true; }
00697 }
00698 }
00699 if( cAster!= cStart )
00700 {
00701 stringPairs.push_back( std::pair<size_t,size_t>(cStart, cAster-cStart) );
00702 }
00703 cStart = cAster+1;
00704 }
00705 else
00706 {
00707 if( cStart == 0 )
00708 {
00709
00710 return word1 == word2;
00711 }
00712 break;
00713 }
00714 }
00715
00716
00717 if( cStart <= word1.length() )
00718 {
00719 if( word1.length() != cStart )
00720 {
00721 stringPairs.push_back( std::pair<size_t,size_t>(cStart,
00722 word1.length()-cStart) );
00723 }
00724 }
00725
00726
00727 if( stringPairs.size() == 0 )
00728 {
00729 if( word1 == word2 )
00730 {
00731 return true;
00732 }
00733 else
00734 {
00735 return false;
00736 }
00737 }
00738
00739
00740 cStart = 0;
00741 for( size_t ii = 0; ii < stringPairs.size(); ii++ )
00742 {
00743 std::pair<size_t,size_t> spair = stringPairs[ii];
00744 size_t sFound = word2.find(word1.substr(spair.first, spair.second),cStart);
00745 if( sFound == std::string::npos )
00746 {
00747 bEqual = false;
00748 break;
00749 }
00750 else
00751 {
00752
00753
00754 if( spair.first == 0 && sFound != 0 )
00755 {
00756 bEqual = false;
00757 break;
00758
00759
00760 }
00761 else if( (spair.first+spair.second-1 == word1.length())
00762 && (sFound+spair.second-1 != word2.length()) )
00763 {
00764 bEqual = false;
00765 break;
00766 }
00767 cStart += spair.second;
00768 }
00769 }
00770
00771 return bEqual;
00772 }