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

Last change on this file since 1275 was 1035, checked in by garnier, 15 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.