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

Last change on this file since 1261 was 1035, checked in by garnier, 17 years ago

dossiers oublies

File size: 21.0 KB
Line 
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{
80 G4int isnum = 1;
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 {
92 isnum = 0;
93 break;
94 }
95 numE++;
96 }
97 else
98 {
99 isnum = 0;
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{
125 G4cout << msg << std::setprecision(8) << vec << G4endl;
126}
127
128
129//-------------------------------------------------------------
130void G4tgrUtils::Dumprm( const G4RotationMatrix& rm, const char* msg)
131{
132 G4cout << msg << G4endl
133 << " xx=" << rm.xx() << " yx=" << rm.yx() << " zx=" << rm.zx() << G4endl
134 << " xy=" << rm.xy() << " yy=" << rm.yy() << " zy=" << rm.zy() << G4endl
135 << " xz=" << rm.xz() << " yz=" << rm.yz() << " zz=" << rm.zz() << G4endl;
136}
137
138
139//-------------------------------------------------------------
140void G4tgrUtils::DumpVS( const std::vector<G4String>& wl,
141 const char* msg, std::ostream& outs )
142{
143 outs << msg << G4endl;
144 std::vector<G4String>::const_iterator ite;
145 for( ite = wl.begin(); ite != wl.end(); ite++ )
146 {
147 outs << *ite << " ";
148 }
149 outs << G4endl;
150}
151
152
153//-------------------------------------------------------------
154void G4tgrUtils::DumpVS( const std::vector<G4String>& wl , const char* msg)
155{
156 DumpVS( wl, msg, G4cout);
157}
158
159
160//-------------------------------------------------------------
161G4String G4tgrUtils::SubColon( const G4String& str )
162{
163 if( str.find(':') != 0 )
164 {
165 G4String ErrMessage = "Trying to subtract leading colon from a word\n"
166 + G4String("that has no leading colon: ") + str;
167 G4Exception("G4tgrUtils::SubColon()", "ParseError",
168 FatalException, ErrMessage);
169 }
170 G4String strt = str.substr(1,str.size()-1);
171 return strt;
172}
173
174
175//-------------------------------------------------------------
176G4String G4tgrUtils::GetString( const G4String& str )
177{
178 //----------- first check if it is parameter
179 const char* cstr = str.c_str();
180 if( cstr[0] == '$' )
181 {
182#ifdef G4VERBOSE
183 if( G4tgrMessenger::GetVerboseLevel() >= 3 )
184 {
185 G4cout << " G4tgrUtils::GetString() - Substitute parameter: "
186 << G4tgrParameterMgr::GetInstance()
187 ->FindParameter( str.substr(1,str.size())) << G4endl;
188 }
189#endif
190 return G4tgrParameterMgr::GetInstance()
191 ->FindParameter( str.substr(1,str.size()) );
192 }
193 else
194 {
195 return str;
196 }
197}
198
199
200//-------------------------------------------------------------
201G4double G4tgrUtils::GetDouble( const G4String& str, G4double unitval )
202{
203#ifdef G4VERBOSE
204 if( G4tgrMessenger::GetVerboseLevel() >= 3 )
205 {
206 G4cout << "G4tgrUtils::GetDouble() - Processing: "
207 << str << " default unit " << unitval << G4endl;
208 }
209#endif
210 if( str == "DBL_MAX" ) {
211 return DBL_MAX;
212 }else if( str == "DBL_MIN" ) {
213 return DBL_MIN;
214 }else if( str == "FLT_MAX" ) {
215 return FLT_MAX;
216 }else if( str == "FLT_MIN" ) {
217 return FLT_MIN;
218 }else if( str == "INT_MAX" ) {
219 return INT_MAX;
220 }else if( str == "INT_MIN" ) {
221 return INT_MIN;
222 }
223 //----- Look for arithmetic symbols, (, )
224 const char* cstr = str.c_str();
225 std::set<G4int> separators;
226 separators.insert(-1);
227 G4int strlen = G4int(str.length());
228 for(G4int ii=0; ii<strlen; ii++)
229 {
230 char cs = cstr[ii];
231 if( cs == '*' || cs == '/' || cs == '(' || cs == ')' )
232 {
233 separators.insert(ii);
234 }
235 else if( cs == '+' || cs == '-' )
236 {
237 // Check if it is not an exponential
238 //
239 if( (ii < 2)
240 || ( (cstr[ii-1] != 'E') && (cstr[ii-1] != 'e') )
241 || !IsNumber(cstr[ii-2]) )
242 {
243 separators.insert(ii);
244 }
245 }
246 }
247 separators.insert(strlen);
248 std::string strnew; // build a new word with Parameters
249 // and units substituted by values
250 //----- Process words, defined as characters between two separators
251 G4int nUnits = 0;
252 std::set<G4int>::const_iterator site, site2;
253 site = separators.begin();
254 site2 = site; site2++;
255 for( ; site2 != separators.end(); site++,site2++)
256 {
257#ifdef G4VERBOSE
258 if( G4tgrMessenger::GetVerboseLevel() >= 3 )
259 {
260 G4cout << " Loop to find word between " << *site
261 << " " << *site2 << G4endl;
262 }
263#endif
264
265 if( *site != -1 ) { strnew += str.substr(*site,1); }
266
267 G4int wlen = (*site2)-(*site)-1; //do not count contiguous separators
268 std::string word;
269 if(wlen != 0)
270 {
271 word = str.substr((*site)+1,(*site2)-(*site)-1);
272 }
273 else
274 {
275 //--- Check combination of separators
276 //--- Check number of parentheses
277 continue;
278 }
279
280#ifdef G4VERBOSE
281 if( G4tgrMessenger::GetVerboseLevel() >= 3 )
282 {
283 G4cout << " Processing word: " << word << G4endl;
284 }
285#endif
286 //----------- first check if it is parameter
287 const char* cword = word.c_str();
288 if( cword[0] == '$' )
289 {
290 G4String parstr = G4tgrParameterMgr::GetInstance()
291 ->FindParameter( word.substr(1,word.size()));
292 if( parstr.substr(0,1) == "-" )
293 {
294 strnew += "(";
295 }
296 strnew += parstr;
297 if( parstr.substr(0,1) == "-" )
298 {
299 strnew += ")";
300 }
301#ifdef G4VERBOSE
302 if( G4tgrMessenger::GetVerboseLevel() >= 3 )
303 {
304 G4cout << " G4tgrutils::GetDouble() - Param found: "
305 << word << " in string " << str
306 << " , substituted by " << parstr << G4endl;
307 }
308#endif
309 }
310 else
311 {
312 //----- Get if it is a number
313 if( IsNumber(word) )
314 {
315 //--- left separator cannot be ')'
316 if( (*site != -1) && (cstr[*site] == ')') )
317 {
318 G4String ErrMessage = "There cannot be a ')' before a number: "
319 + word + " in string: " + str;
320 G4Exception("G4tgrUtils::GetDouble()", "ParseError",
321 FatalException, ErrMessage);
322 }
323 //--- right separator cannot be '('
324 if( (*site2 != strlen) && (cstr[*site2] == '(') )
325 {
326 G4String ErrMessage = "There cannot be a '(' after a number: "
327 + word + " in string: " + str;
328 G4Exception("G4tgrUtils::GetDouble()", "ParseError",
329 FatalException, ErrMessage);
330 }
331 strnew += word;
332
333 //------ If it is an string, check if it is a unit
334 }
335 else
336 {
337 //--- First character cannot be a digit
338 if( isdigit(word[0]) )
339 {
340 G4String ErrMessage = "String words cannot start with a digit: "
341 + word + " in string: " + str;
342 G4Exception("G4tgrUtils::GetDouble()", "ParseError",
343 FatalException, ErrMessage );
344 }
345
346 //----- Check if it is a function
347 G4bool bWordOK = false;
348 if( G4tgrUtils::WordIsFunction( word ) )
349 {
350 //--- It must be followed by '('
351 if( (*site2 == strlen) || (cstr[*site2] != '(') )
352 {
353 G4String ErrMessage = "There must be a '(' after a function: "
354 + word + " in string: " + str;
355 G4Exception("G4tgrUtils::GetDouble()", "ParseError",
356 FatalException, ErrMessage );
357 }
358 strnew += word;
359 bWordOK = true;
360 //----- Check if it is a unit
361 }
362 else if( G4tgrUtils::WordIsUnit( word ) )
363 {
364 //--- It must be preceded by a *
365 if( (*site == -1)
366 || ( (cstr[*site] != '*') && (cstr[*site] != '/') ) )
367 {
368 G4String ErrMess = "There must be a '*' before a unit definition: "
369 + word + " in string " + str;
370 G4Exception("G4tgrUtils::GetDouble()", "ParseError",
371 FatalException, ErrMess );
372 }
373 //--- check that it is indeed a CLHEP unit
374 if( G4UnitDefinition::GetValueOf(word) != 0. )
375 {
376 bWordOK = true;
377 nUnits++;
378 if( nUnits > 1 )
379 {
380 // G4String ErrMess = "There cannot be two unit definitions: "
381 // + word + " in string " + str;
382 // G4Exception("G4tgrUtils::GetDouble()", "ParseError",
383 // FatalException, ErrMess );
384 }
385 strnew += G4UIcommand::ConvertToString( G4UnitDefinition::GetValueOf(word) );
386 }
387 }
388 if( !bWordOK )
389 {
390 G4String ErrMess = "String word is not a parameter, nor a unit\n";
391 + G4String("definition nor a function: ") + word
392 + G4String(" in string: ") + str;
393 G4Exception("G4tgrUtils::GetDouble()", "ParseError",
394 FatalException, ErrMess );
395 }
396 }
397 }
398 }
399
400 G4double val = theEvaluator->evaluate( strnew.c_str() );
401 if (theEvaluator->status() != HepTool::Evaluator::OK)
402 {
403 theEvaluator->print_error(theEvaluator->status());
404 G4String ErrMessage = "Evaluator error: " + strnew;
405 G4Exception("G4tgrUtils::GetDouble()", "ParseError",
406 FatalException, ErrMessage );
407 }
408
409 if( nUnits == 0 ) { val *= unitval; }
410
411#ifdef G4VERBOSE
412 if( G4tgrMessenger::GetVerboseLevel() >= 3 )
413 {
414 G4cout << " G4tgrUtils::GetDouble() - RESULT= " << val << G4endl
415 << " from string: " << str << " converted to: " << strnew
416 << " with unit val: " << unitval << G4endl;
417 }
418#endif
419
420 return val;
421}
422
423
424//-------------------------------------------------------------
425G4int G4tgrUtils::GetInt( const G4String& str )
426{
427 //----- Convert it to a number (it can be a parameter)
428 G4double val = GetDouble(str);
429
430 //----- Check it is an integer
431 if( !IsInteger(val) )
432 {
433 G4String ErrMessage = G4String("Trying to get the integer from a number")
434 + G4String(" which is not an integer ") + str;
435 G4Exception("G4tgrUtils::GetInt()", "ParseError",
436 FatalException, ErrMessage );
437 }
438 return G4int( val );
439}
440
441
442//-------------------------------------------------------------
443G4bool G4tgrUtils::GetBool( const G4String& str )
444{
445 G4bool val = false;
446
447 //----------- first check that it is a not number
448 if( (str == "ON") || (str == "TRUE") )
449 {
450 val = true;
451 }
452 else if( (str == "OFF") || (str == "FALSE") )
453 {
454 val = false;
455 }
456 else
457 {
458 G4String ErrMessage = G4String("Trying to get a float from a string")
459 + G4String(" which is not 'ON'/'OFF'/'TRUE'/'FALSE' ")
460 + str;
461 G4Exception("G4tgrUtils::GetBool()", "ParseError",
462 FatalException, ErrMessage );
463 }
464
465 return val;
466}
467
468
469//-------------------------------------------------------------
470void G4tgrUtils::CheckWLsize( const std::vector<G4String>& wl,
471 unsigned int nWcheck, WLSIZEtype st,
472 const G4String& methodName )
473{
474
475 G4String outStr = methodName + G4String(". Line read with number of words ");
476 unsigned int wlsize = wl.size();
477
478 G4bool isOK = CheckListSize( wlsize, nWcheck, st, outStr );
479
480 if( !isOK )
481 {
482 G4String chartmp = G4UIcommand::ConvertToString( G4int(nWcheck) );
483 outStr += chartmp + G4String(" words");
484 DumpVS( wl, outStr.c_str() );
485 G4String ErrMessage = " NUMBER OF WORDS: "
486 + G4UIcommand::ConvertToString(G4int(wlsize));
487 G4Exception("G4tgrUtils::CheckWLsize()", "ParseError",
488 FatalException, ErrMessage);
489 }
490}
491
492//-------------------------------------------------------------
493G4bool G4tgrUtils::CheckListSize( unsigned int nWreal, unsigned int nWcheck,
494 WLSIZEtype st, G4String& outStr )
495{
496 G4bool isOK = true;
497 switch (st)
498 {
499 case WLSIZE_EQ:
500 if( nWreal != nWcheck )
501 {
502 isOK = false;
503 outStr += G4String("not equal than ");
504 }
505 break;
506 case WLSIZE_NE:
507 if( nWreal == nWcheck )
508 {
509 isOK = false;
510 outStr += G4String("equal than ");
511 }
512 break;
513 case WLSIZE_LE:
514 if( nWreal > nWcheck )
515 {
516 isOK = false;
517 outStr += G4String("greater than ");
518 }
519 break;
520 case WLSIZE_LT:
521 if( nWreal >= nWcheck )
522 {
523 isOK = false;
524 outStr += G4String("greater or equal than ");
525 }
526 break;
527 case WLSIZE_GE:
528 if( nWreal < nWcheck )
529 {
530 isOK = false;
531 outStr += G4String("less than ");
532 }
533 break;
534 case WLSIZE_GT:
535 if( nWreal <= nWcheck )
536 {
537 isOK = false;
538 outStr += G4String("less or equal than ");
539 }
540 break;
541 default:
542 G4cerr << " ERROR!! - G4tgrUtils::CheckListSize()" << G4endl
543 << " Type of WLSIZE type not found " << st << G4endl;
544 break;
545 }
546
547 return isOK;
548}
549
550
551//-------------------------------------------------------------
552G4bool G4tgrUtils::WordIsUnit( const G4String& word )
553{
554 return !IsNumber(word);
555 if( word == "mm"
556 || word == "cm"
557 || word == "m"
558 || word == "km"
559 || word == "millimeter"
560 || word == "centimeter"
561 || word == "meter"
562 || word == "kilometer"
563 || word == "parsec"
564 || word == "micrometer"
565 || word == "nanometer"
566 || word == "angstrom"
567 || word == "fermi"
568 || word == "nm"
569 || word == "um"
570 || word == "pc"
571 || word == "radian"
572 || word == "milliradian"
573 || word == "degree"
574 || word == "rad"
575 || word == "mrad"
576 || word == "deg"
577 || word == "ns"
578 || word == "curie"
579 || word == "curie" )
580 {
581 return true;
582 }
583 else
584 {
585 return false;
586 }
587}
588
589
590//-------------------------------------------------------------
591G4bool G4tgrUtils::WordIsFunction( const G4String& word )
592{
593 if( word == "sin"
594 || word == "cos"
595 || word == "tan"
596 || word == "asin"
597 || word == "acos"
598 || word == "atan"
599 || word == "atan2"
600 || word == "sinh"
601 || word == "cosh"
602 || word == "tanh"
603 || word == "asinh"
604 || word == "acosh"
605 || word == "atanh"
606 || word == "sqrt"
607 || word == "exp"
608 || word == "log"
609 || word == "log10"
610 || word == "pow" )
611 {
612 return true;
613 }
614 else
615 {
616 return false;
617 }
618}
619
620
621//-------------------------------------------------------------
622G4RotationMatrix G4tgrUtils::GetRotationFromDirection( G4ThreeVector dir )
623{
624 G4RotationMatrix rotation;
625
626 if( std::fabs(dir.mag()-1.) > G4GeometryTolerance::GetInstance()
627 ->GetSurfaceTolerance() )
628 {
629 G4String WarMessage = "Direction cosines have been normalized to one.\n"
630 + G4String("They were normalized to ")
631 + G4UIcommand::ConvertToString(dir.mag());
632 G4Exception("G4tgrUtils::GetRotationFromDirection()", "WrongArgument",
633 JustWarning, WarMessage);
634 dir /= dir.mag();
635 }
636 G4double angx = -std::asin(dir.y());
637
638 // There are always two solutions angx, angy and PI-angx,
639 // PI+angy, choose first
640 //
641 G4double angy;
642 if( dir.y() == 1. )
643 {
644 angy = 0.;
645 }
646 else if( dir.y() == 0. )
647 {
648 angy = 0.;
649 }
650 else
651 {
652 angy = std::asin( dir.x()/std::sqrt(1-dir.y()*dir.y()) );
653 }
654
655 // choose between angy and PI-angy
656 if( dir.z() * std::cos(angx)*std::cos(angy) < 0 )
657 {
658 angy = CLHEP::pi - angy;
659 }
660 rotation.rotateX( angx );
661 rotation.rotateY( angy );
662
663 return rotation;
664}
665
666
667//-------------------------------------------------------------
668G4bool G4tgrUtils::AreWordsEquivalent( const G4String& word1,
669 const G4String& word2 )
670{
671 G4bool bEqual = true;
672 std::vector< std::pair<G4int,G4int> > stringPairs;
673 // start of substring, number of characters
674
675 //--- Get string limits between asterisks in word1
676
677 size_t cStart = 0;
678 for( ;; )
679 {
680 size_t cAster = word1.find("*",cStart);
681 if( cAster != std::string::npos )
682 {
683 if( cAster == cStart )
684 {
685 if( cAster != 0 )
686 {
687 G4Exception("G4tgrUtils::AreWordsEquivalent()",
688 "A word has two asterisks together, please correct it",
689 FatalException,("Offending word is: " + word1).c_str() );
690 }
691 else
692 {
693 // word1 == *
694 if(word1.size() == 1 ) { return true; }
695 }
696 }
697 if( cAster!= cStart )
698 {
699 stringPairs.push_back( std::pair<G4int,G4int>(cStart, cAster-cStart) );
700 }
701 cStart = cAster+1;
702 }
703 else
704 {
705 if( cStart == 0 )
706 {
707 //--- If there is no asterisk check if they are the same
708 return word1 == word2;
709 }
710 break;
711 }
712 }
713
714 //---- Add characters after last asterisk as string pair
715 if( cStart <= word1.length() )
716 {
717 if( word1.length() != cStart )
718 {
719 stringPairs.push_back( std::pair<G4int,G4int>(cStart,
720 word1.length()-cStart) );
721 }
722 }
723
724 //--- If there are not asterisk, simple comparison
725 if( stringPairs.size() == 0 )
726 {
727 if( word1 == word2 )
728 {
729 return true;
730 }
731 else
732 {
733 return false;
734 }
735 }
736
737 //--- Find substrings in word2, in same order as in word1
738 cStart = 0;
739 for( size_t ii = 0; ii < stringPairs.size(); ii++ )
740 {
741 std::pair<G4int,G4int> spair = stringPairs[ii];
742 size_t sFound = word2.find(word1.substr(spair.first, spair.second),cStart);
743 if( sFound == std::string::npos )
744 {
745 bEqual = false;
746 break;
747 }
748 else
749 {
750 //---- If there is no asterisk before first character,
751 // the fisrt string pair found has to start at the first character
752 if( spair.first == 0 && sFound != 0 )
753 {
754 bEqual = false;
755 break;
756 //---- If there is no asterisk after last character,
757 // the last string pair found has to end at the last character
758 }
759 else if( (spair.first+spair.second-1 == G4int(word1.length()))
760 && (G4int(sFound)+spair.second-1 != G4int(word2.length())) )
761 {
762 bEqual = false;
763 break;
764 }
765 cStart += spair.second;
766 }
767 }
768
769 return bEqual;
770}
Note: See TracBrowser for help on using the repository browser.