source: trunk/source/persistency/ascii/src/G4tgrUtils.cc@ 1351

Last change on this file since 1351 was 1347, checked in by garnier, 15 years ago

geant4 tag 9.4

File size: 20.2 KB
RevLine 
[1035]1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26//
27//
28// class G4tgrUtils
29
30// History:
31// - Created. P.Arce, CIEMAT (November 2007)
32// -------------------------------------------------------------------------
33
34#include "geomdefs.hh"
35
36#include <iomanip>
37#include <set>
38
39#include "G4tgrUtils.hh"
40#include "G4tgrParameterMgr.hh"
41#include "G4tgrMessenger.hh"
42#include "G4UnitsTable.hh"
43#include "G4GeometryTolerance.hh"
44#include "G4UIcommand.hh"
45
46
47G4tgrEvaluator* G4tgrUtils::theEvaluator = new G4tgrEvaluator;
48
49
50//-------------------------------------------------------------
51G4tgrUtils::G4tgrUtils()
52{
53}
54
55
56//-------------------------------------------------------------
57G4tgrUtils::~G4tgrUtils()
58{
59}
60
61
62//-------------------------------------------------------------
63G4bool G4tgrUtils::IsSeparator( const char ch)
64{
65 char nonCharacters[7] = {"()+-*/"};
66 for( size_t ii = 0; ii < 6; ii++ )
67 {
68 if( ch == nonCharacters[ii] )
69 {
70 return true;
71 }
72 }
73 return false;
74}
75
76
77//-------------------------------------------------------------
78G4bool G4tgrUtils::IsNumber( const G4String& str)
79{
[1347]80 G4int isnum = true;
[1035]81 G4int numE = 0;
82 for(size_t ii=0; ii<str.length(); ii++)
83 {
84 if(!isdigit(str[ii]) && (str[ii]!='.') && (str[ii]!='-') && (str[ii]!='+'))
85 {
86 //--- check for E(xponential)
87 if(str[ii] == 'E' || str[ii] == 'e' )
88 {
89 if( ii == 0 ) { return 0; }
90 if(numE != 0 || ii == str.length()-1)
91 {
[1347]92 isnum = false;
[1035]93 break;
94 }
95 numE++;
96 }
97 else
98 {
[1347]99 isnum = false;
[1035]100 break;
101 }
102 }
103 }
104 return isnum;
105}
106
107
108//-------------------------------------------------------------
109G4bool G4tgrUtils::IsInteger( const G4double val, const G4double precision )
110{
111 if( G4int(val) / val - 1 > precision )
112 {
113 return 0;
114 }
115 else
116 {
117 return 1;
118 }
119}
120
121
122//-------------------------------------------------------------
123void G4tgrUtils::Dump3v( const G4ThreeVector& vec, const char* msg)
124{
[1347]125 G4cout << msg << std::setprecision(8)
126 << vec << std::setprecision(6) << G4endl;
[1035]127}
128
129
130//-------------------------------------------------------------
131void G4tgrUtils::Dumprm( const G4RotationMatrix& rm, const char* msg)
132{
133 G4cout << msg << G4endl
134 << " xx=" << rm.xx() << " yx=" << rm.yx() << " zx=" << rm.zx() << G4endl
135 << " xy=" << rm.xy() << " yy=" << rm.yy() << " zy=" << rm.zy() << G4endl
136 << " xz=" << rm.xz() << " yz=" << rm.yz() << " zz=" << rm.zz() << G4endl;
137}
138
139
140//-------------------------------------------------------------
141void G4tgrUtils::DumpVS( const std::vector<G4String>& wl,
142 const char* msg, std::ostream& outs )
143{
144 outs << msg << G4endl;
145 std::vector<G4String>::const_iterator ite;
146 for( ite = wl.begin(); ite != wl.end(); ite++ )
147 {
148 outs << *ite << " ";
149 }
150 outs << G4endl;
151}
152
153
154//-------------------------------------------------------------
155void G4tgrUtils::DumpVS( const std::vector<G4String>& wl , const char* msg)
156{
157 DumpVS( wl, msg, G4cout);
158}
159
160
161//-------------------------------------------------------------
162G4String G4tgrUtils::SubColon( const G4String& str )
163{
164 if( str.find(':') != 0 )
165 {
166 G4String ErrMessage = "Trying to subtract leading colon from a word\n"
167 + G4String("that has no leading colon: ") + str;
168 G4Exception("G4tgrUtils::SubColon()", "ParseError",
169 FatalException, ErrMessage);
170 }
171 G4String strt = str.substr(1,str.size()-1);
172 return strt;
173}
174
175
176//-------------------------------------------------------------
177G4String G4tgrUtils::GetString( const G4String& str )
178{
179 //----------- first check if it is parameter
180 const char* cstr = str.c_str();
181 if( cstr[0] == '$' )
182 {
183#ifdef G4VERBOSE
184 if( G4tgrMessenger::GetVerboseLevel() >= 3 )
185 {
186 G4cout << " G4tgrUtils::GetString() - Substitute parameter: "
187 << G4tgrParameterMgr::GetInstance()
188 ->FindParameter( str.substr(1,str.size())) << G4endl;
189 }
190#endif
191 return G4tgrParameterMgr::GetInstance()
192 ->FindParameter( str.substr(1,str.size()) );
193 }
194 else
195 {
196 return str;
197 }
198}
199
200
201//-------------------------------------------------------------
202G4double G4tgrUtils::GetDouble( const G4String& str, G4double unitval )
203{
204#ifdef G4VERBOSE
205 if( G4tgrMessenger::GetVerboseLevel() >= 3 )
206 {
207 G4cout << "G4tgrUtils::GetDouble() - Processing: "
208 << str << " default unit " << unitval << G4endl;
209 }
210#endif
211 if( str == "DBL_MAX" ) {
212 return DBL_MAX;
213 }else if( str == "DBL_MIN" ) {
214 return DBL_MIN;
215 }else if( str == "FLT_MAX" ) {
216 return FLT_MAX;
217 }else if( str == "FLT_MIN" ) {
218 return FLT_MIN;
219 }else if( str == "INT_MAX" ) {
220 return INT_MAX;
221 }else if( str == "INT_MIN" ) {
222 return INT_MIN;
223 }
224 //----- Look for arithmetic symbols, (, )
225 const char* cstr = str.c_str();
226 std::set<G4int> separators;
227 separators.insert(-1);
228 G4int strlen = G4int(str.length());
229 for(G4int ii=0; ii<strlen; ii++)
230 {
231 char cs = cstr[ii];
232 if( cs == '*' || cs == '/' || cs == '(' || cs == ')' )
233 {
234 separators.insert(ii);
235 }
236 else if( cs == '+' || cs == '-' )
237 {
238 // Check if it is not an exponential
239 //
240 if( (ii < 2)
241 || ( (cstr[ii-1] != 'E') && (cstr[ii-1] != 'e') )
242 || !IsNumber(cstr[ii-2]) )
243 {
244 separators.insert(ii);
245 }
246 }
247 }
248 separators.insert(strlen);
249 std::string strnew; // build a new word with Parameters
250 // and units substituted by values
251 //----- Process words, defined as characters between two separators
252 G4int nUnits = 0;
253 std::set<G4int>::const_iterator site, site2;
254 site = separators.begin();
255 site2 = site; site2++;
256 for( ; site2 != separators.end(); site++,site2++)
257 {
258#ifdef G4VERBOSE
259 if( G4tgrMessenger::GetVerboseLevel() >= 3 )
260 {
261 G4cout << " Loop to find word between " << *site
262 << " " << *site2 << G4endl;
263 }
264#endif
265
266 if( *site != -1 ) { strnew += str.substr(*site,1); }
267
268 G4int wlen = (*site2)-(*site)-1; //do not count contiguous separators
269 std::string word;
270 if(wlen != 0)
271 {
272 word = str.substr((*site)+1,(*site2)-(*site)-1);
273 }
274 else
275 {
276 //--- Check combination of separators
277 //--- Check number of parentheses
278 continue;
279 }
280
281#ifdef G4VERBOSE
282 if( G4tgrMessenger::GetVerboseLevel() >= 3 )
283 {
284 G4cout << " Processing word: " << word << G4endl;
285 }
286#endif
287 //----------- first check if it is parameter
288 const char* cword = word.c_str();
289 if( cword[0] == '$' )
290 {
291 G4String parstr = G4tgrParameterMgr::GetInstance()
292 ->FindParameter( word.substr(1,word.size()));
293 if( parstr.substr(0,1) == "-" )
294 {
295 strnew += "(";
296 }
297 strnew += parstr;
298 if( parstr.substr(0,1) == "-" )
299 {
300 strnew += ")";
301 }
302#ifdef G4VERBOSE
303 if( G4tgrMessenger::GetVerboseLevel() >= 3 )
304 {
305 G4cout << " G4tgrutils::GetDouble() - Param found: "
306 << word << " in string " << str
307 << " , substituted by " << parstr << G4endl;
308 }
309#endif
310 }
311 else
312 {
313 //----- Get if it is a number
314 if( IsNumber(word) )
315 {
316 //--- left separator cannot be ')'
317 if( (*site != -1) && (cstr[*site] == ')') )
318 {
319 G4String ErrMessage = "There cannot be a ')' before a number: "
320 + word + " in string: " + str;
321 G4Exception("G4tgrUtils::GetDouble()", "ParseError",
322 FatalException, ErrMessage);
323 }
324 //--- right separator cannot be '('
325 if( (*site2 != strlen) && (cstr[*site2] == '(') )
326 {
327 G4String ErrMessage = "There cannot be a '(' after a number: "
328 + word + " in string: " + str;
329 G4Exception("G4tgrUtils::GetDouble()", "ParseError",
330 FatalException, ErrMessage);
331 }
332 strnew += word;
333
334 //------ If it is an string, check if it is a unit
335 }
336 else
337 {
338 //--- First character cannot be a digit
339 if( isdigit(word[0]) )
340 {
341 G4String ErrMessage = "String words cannot start with a digit: "
342 + word + " in string: " + str;
343 G4Exception("G4tgrUtils::GetDouble()", "ParseError",
344 FatalException, ErrMessage );
345 }
346
347 //----- Check if it is a function
348 G4bool bWordOK = false;
[1347]349 if( G4tgrUtils::IsFunction( word ) )
[1035]350 {
351 //--- It must be followed by '('
352 if( (*site2 == strlen) || (cstr[*site2] != '(') )
353 {
354 G4String ErrMessage = "There must be a '(' after a function: "
355 + word + " in string: " + str;
356 G4Exception("G4tgrUtils::GetDouble()", "ParseError",
357 FatalException, ErrMessage );
358 }
359 strnew += word;
360 bWordOK = true;
361 //----- Check if it is a unit
362 }
[1347]363 else if( !G4tgrUtils::IsNumber( word ) )
[1035]364 {
365 //--- It must be preceded by a *
366 if( (*site == -1)
367 || ( (cstr[*site] != '*') && (cstr[*site] != '/') ) )
368 {
369 G4String ErrMess = "There must be a '*' before a unit definition: "
370 + word + " in string " + str;
371 G4Exception("G4tgrUtils::GetDouble()", "ParseError",
372 FatalException, ErrMess );
373 }
374 //--- check that it is indeed a CLHEP unit
375 if( G4UnitDefinition::GetValueOf(word) != 0. )
376 {
377 bWordOK = true;
378 nUnits++;
379 if( nUnits > 1 )
380 {
381 // G4String ErrMess = "There cannot be two unit definitions: "
382 // + word + " in string " + str;
383 // G4Exception("G4tgrUtils::GetDouble()", "ParseError",
384 // FatalException, ErrMess );
385 }
386 strnew += G4UIcommand::ConvertToString( G4UnitDefinition::GetValueOf(word) );
387 }
388 }
389 if( !bWordOK )
390 {
391 G4String ErrMess = "String word is not a parameter, nor a unit\n";
392 + G4String("definition nor a function: ") + word
393 + G4String(" in string: ") + str;
394 G4Exception("G4tgrUtils::GetDouble()", "ParseError",
395 FatalException, ErrMess );
396 }
397 }
398 }
399 }
400
401 G4double val = theEvaluator->evaluate( strnew.c_str() );
402 if (theEvaluator->status() != HepTool::Evaluator::OK)
403 {
404 theEvaluator->print_error(theEvaluator->status());
405 G4String ErrMessage = "Evaluator error: " + strnew;
406 G4Exception("G4tgrUtils::GetDouble()", "ParseError",
407 FatalException, ErrMessage );
408 }
409
410 if( nUnits == 0 ) { val *= unitval; }
411
412#ifdef G4VERBOSE
413 if( G4tgrMessenger::GetVerboseLevel() >= 3 )
414 {
415 G4cout << " G4tgrUtils::GetDouble() - RESULT= " << val << G4endl
416 << " from string: " << str << " converted to: " << strnew
417 << " with unit val: " << unitval << G4endl;
418 }
419#endif
420
421 return val;
422}
423
424
425//-------------------------------------------------------------
426G4int G4tgrUtils::GetInt( const G4String& str )
427{
428 //----- Convert it to a number (it can be a parameter)
429 G4double val = GetDouble(str);
430
431 //----- Check it is an integer
432 if( !IsInteger(val) )
433 {
434 G4String ErrMessage = G4String("Trying to get the integer from a number")
435 + G4String(" which is not an integer ") + str;
436 G4Exception("G4tgrUtils::GetInt()", "ParseError",
437 FatalException, ErrMessage );
438 }
439 return G4int( val );
440}
441
442
443//-------------------------------------------------------------
444G4bool G4tgrUtils::GetBool( const G4String& str )
445{
446 G4bool val = false;
447
448 //----------- first check that it is a not number
449 if( (str == "ON") || (str == "TRUE") )
450 {
451 val = true;
452 }
453 else if( (str == "OFF") || (str == "FALSE") )
454 {
455 val = false;
456 }
457 else
458 {
459 G4String ErrMessage = G4String("Trying to get a float from a string")
460 + G4String(" which is not 'ON'/'OFF'/'TRUE'/'FALSE' ")
461 + str;
462 G4Exception("G4tgrUtils::GetBool()", "ParseError",
463 FatalException, ErrMessage );
464 }
465
466 return val;
467}
468
469
470//-------------------------------------------------------------
471void G4tgrUtils::CheckWLsize( const std::vector<G4String>& wl,
472 unsigned int nWcheck, WLSIZEtype st,
473 const G4String& methodName )
474{
475
476 G4String outStr = methodName + G4String(". Line read with number of words ");
477 unsigned int wlsize = wl.size();
478
479 G4bool isOK = CheckListSize( wlsize, nWcheck, st, outStr );
480
481 if( !isOK )
482 {
483 G4String chartmp = G4UIcommand::ConvertToString( G4int(nWcheck) );
484 outStr += chartmp + G4String(" words");
485 DumpVS( wl, outStr.c_str() );
486 G4String ErrMessage = " NUMBER OF WORDS: "
487 + G4UIcommand::ConvertToString(G4int(wlsize));
488 G4Exception("G4tgrUtils::CheckWLsize()", "ParseError",
489 FatalException, ErrMessage);
490 }
491}
492
493//-------------------------------------------------------------
494G4bool G4tgrUtils::CheckListSize( unsigned int nWreal, unsigned int nWcheck,
495 WLSIZEtype st, G4String& outStr )
496{
497 G4bool isOK = true;
498 switch (st)
499 {
500 case WLSIZE_EQ:
501 if( nWreal != nWcheck )
502 {
503 isOK = false;
504 outStr += G4String("not equal than ");
505 }
506 break;
507 case WLSIZE_NE:
508 if( nWreal == nWcheck )
509 {
510 isOK = false;
511 outStr += G4String("equal than ");
512 }
513 break;
514 case WLSIZE_LE:
515 if( nWreal > nWcheck )
516 {
517 isOK = false;
518 outStr += G4String("greater than ");
519 }
520 break;
521 case WLSIZE_LT:
522 if( nWreal >= nWcheck )
523 {
524 isOK = false;
525 outStr += G4String("greater or equal than ");
526 }
527 break;
528 case WLSIZE_GE:
529 if( nWreal < nWcheck )
530 {
531 isOK = false;
532 outStr += G4String("less than ");
533 }
534 break;
535 case WLSIZE_GT:
536 if( nWreal <= nWcheck )
537 {
538 isOK = false;
539 outStr += G4String("less or equal than ");
540 }
541 break;
542 default:
543 G4cerr << " ERROR!! - G4tgrUtils::CheckListSize()" << G4endl
544 << " Type of WLSIZE type not found " << st << G4endl;
545 break;
546 }
547
548 return isOK;
549}
550
551
552//-------------------------------------------------------------
[1347]553G4bool G4tgrUtils::IsFunction( const G4String& word )
[1035]554{
555 if( word == "sin"
556 || word == "cos"
557 || word == "tan"
558 || word == "asin"
559 || word == "acos"
560 || word == "atan"
561 || word == "atan2"
562 || word == "sinh"
563 || word == "cosh"
564 || word == "tanh"
565 || word == "asinh"
566 || word == "acosh"
567 || word == "atanh"
568 || word == "sqrt"
569 || word == "exp"
570 || word == "log"
571 || word == "log10"
572 || word == "pow" )
573 {
574 return true;
575 }
576 else
577 {
578 return false;
579 }
580}
581
582
583//-------------------------------------------------------------
584G4RotationMatrix G4tgrUtils::GetRotationFromDirection( G4ThreeVector dir )
585{
586 G4RotationMatrix rotation;
587
588 if( std::fabs(dir.mag()-1.) > G4GeometryTolerance::GetInstance()
589 ->GetSurfaceTolerance() )
590 {
591 G4String WarMessage = "Direction cosines have been normalized to one.\n"
592 + G4String("They were normalized to ")
593 + G4UIcommand::ConvertToString(dir.mag());
594 G4Exception("G4tgrUtils::GetRotationFromDirection()", "WrongArgument",
595 JustWarning, WarMessage);
596 dir /= dir.mag();
597 }
598 G4double angx = -std::asin(dir.y());
599
600 // There are always two solutions angx, angy and PI-angx,
601 // PI+angy, choose first
602 //
603 G4double angy;
604 if( dir.y() == 1. )
605 {
606 angy = 0.;
607 }
608 else if( dir.y() == 0. )
609 {
610 angy = 0.;
611 }
612 else
613 {
614 angy = std::asin( dir.x()/std::sqrt(1-dir.y()*dir.y()) );
615 }
616
617 // choose between angy and PI-angy
618 if( dir.z() * std::cos(angx)*std::cos(angy) < 0 )
619 {
620 angy = CLHEP::pi - angy;
621 }
622 rotation.rotateX( angx );
623 rotation.rotateY( angy );
624
625 return rotation;
626}
627
628
629//-------------------------------------------------------------
630G4bool G4tgrUtils::AreWordsEquivalent( const G4String& word1,
631 const G4String& word2 )
632{
633 G4bool bEqual = true;
634 std::vector< std::pair<G4int,G4int> > stringPairs;
635 // start of substring, number of characters
636
637 //--- Get string limits between asterisks in word1
638
639 size_t cStart = 0;
640 for( ;; )
641 {
642 size_t cAster = word1.find("*",cStart);
643 if( cAster != std::string::npos )
644 {
645 if( cAster == cStart )
646 {
647 if( cAster != 0 )
648 {
649 G4Exception("G4tgrUtils::AreWordsEquivalent()",
650 "A word has two asterisks together, please correct it",
651 FatalException,("Offending word is: " + word1).c_str() );
652 }
653 else
654 {
655 // word1 == *
656 if(word1.size() == 1 ) { return true; }
657 }
658 }
659 if( cAster!= cStart )
660 {
661 stringPairs.push_back( std::pair<G4int,G4int>(cStart, cAster-cStart) );
662 }
663 cStart = cAster+1;
664 }
665 else
666 {
667 if( cStart == 0 )
668 {
669 //--- If there is no asterisk check if they are the same
670 return word1 == word2;
671 }
672 break;
673 }
674 }
675
676 //---- Add characters after last asterisk as string pair
677 if( cStart <= word1.length() )
678 {
679 if( word1.length() != cStart )
680 {
681 stringPairs.push_back( std::pair<G4int,G4int>(cStart,
682 word1.length()-cStart) );
683 }
684 }
685
686 //--- If there are not asterisk, simple comparison
687 if( stringPairs.size() == 0 )
688 {
689 if( word1 == word2 )
690 {
691 return true;
692 }
693 else
694 {
695 return false;
696 }
697 }
698
699 //--- Find substrings in word2, in same order as in word1
700 cStart = 0;
701 for( size_t ii = 0; ii < stringPairs.size(); ii++ )
702 {
703 std::pair<G4int,G4int> spair = stringPairs[ii];
704 size_t sFound = word2.find(word1.substr(spair.first, spair.second),cStart);
705 if( sFound == std::string::npos )
706 {
707 bEqual = false;
708 break;
709 }
710 else
711 {
712 //---- If there is no asterisk before first character,
713 // the fisrt string pair found has to start at the first character
714 if( spair.first == 0 && sFound != 0 )
715 {
716 bEqual = false;
717 break;
718 //---- If there is no asterisk after last character,
719 // the last string pair found has to end at the last character
720 }
721 else if( (spair.first+spair.second-1 == G4int(word1.length()))
722 && (G4int(sFound)+spair.second-1 != G4int(word2.length())) )
723 {
724 bEqual = false;
725 break;
726 }
727 cStart += spair.second;
728 }
729 }
730
731 return bEqual;
732}
Note: See TracBrowser for help on using the repository browser.