BLEvaluator Class Reference

#include <BLEvaluator.hh>

List of all members.


Detailed Description

class BLEvaluator implements an expression evaluator.

Uses HepTool::Evaluator, but fixes up a few minor bugs: automatically calls setStdMath() adds floor(x) and ceil(x) fixes unary +/- by enclosing them in parens

NOTE: This is expensive, and should not be used during tracking unless unavoidable.

Public Member Functions

 BLEvaluator ()
 Constructor.
double evaluate (const char *expression)
 evaluate() will evaluate the expression. returns NAN if the expression is not valid (use either isOK() or std::isnan(double) or gsl_isnan(double) to check).
bool isOK ()
 isOK() returns true if the previous call to expression succeeded.
void setTrackVariables (const G4Track *track, BLCoordinateType coordType, G4String suffix="", bool fields=false)
 setTrackVariables() devines variables in the evaluator corresponding to the usual track variables. These can then be used in expressions.
bool isidchar (char c)
 isidchar() returns true if the char is valid for an identifier.
bool isopchar (char c)
 isopchar() returns true if the character is an operator (no parens)
bool isumchar (char c)
 isumchar() returns true if the char should be inside the parens generated to surround the unary minus (parens matched in evaluate())


Constructor & Destructor Documentation

BLEvaluator::BLEvaluator (  )  [inline]

Constructor.

00034                       : HepTool::Evaluator() {
00035                 setSystemOfUnits(1.e+3, 1./1.60217733e-25, 1.e+9,
00036                                 1./1.60217733e-10, 1.0, 1.0, 1.0);
00037                 setStdMath();
00038                 setFunction("floor",floor);
00039                 setFunction("ceil",ceil);
00040         }


Member Function Documentation

double BLEvaluator::evaluate ( const char *  expression  )  [inline]

evaluate() will evaluate the expression. returns NAN if the expression is not valid (use either isOK() or std::isnan(double) or gsl_isnan(double) to check).

References BLAssert, isopchar(), and isumchar().

Referenced by BLTrackNTuple::appendTrack(), BLCommand::argDouble(), BLCommand::argInt(), BLCMDsetdecay::command(), BLCMDparam::command(), BLCMDif::command(), BLTune::defineTunableArg(), BLParam::getDouble(), BLCommand::getDouble(), FieldComputation::GetFieldValue(), BLCMDfieldexpr::handleTimeDependence(), BLCMDtrace::newTrace(), BLTune::update(), ParticleFilterPlacement::UserSteppingAction(), MaterialFilter::UserSteppingAction(), BLCMDtune::UserZSteppingAction(), BLCMDprofile::Entry::UserZSteppingAction(), and BLCMDprintf::UserZSteppingAction().

00045                                                 {
00046                 char out[1024];
00047                 BLAssert(strlen(expression) < sizeof(out));
00048                 // remove whitespace (simpler parsing below)
00049                 int j=0;
00050                 for(int i=0; expression[i]!='\0'; ++i)
00051                         if(!isspace(expression[i])) out[j++] = expression[i];
00052                 out[j] = '\0';
00053                 // Workaround for serious bug in HepTool::Evaluator --
00054                 // it can only handle a unary +/- after a '(', so
00055                 // put parens around unary +/-
00056                 bool again=false;
00057                 do {
00058                     again = false;
00059                     char *in = strdup(out);
00060                     j = 0;
00061                     char prev=' ';
00062                     for(int i=0; in[i]!='\0'; ++i) {
00063                         char c = in[i];
00064                         if((c == '-' || c == '+') && isopchar(prev)) {
00065                                 again = true;
00066                                 out[j++] = '(';
00067                                 out[j++] = c;
00068                                 ++i;
00069                                 int level = 0;
00070                                 while(isumchar(in[i]) || level > 0) {
00071                                     if(in[i] == '(')
00072                                         ++level;
00073                                     if(in[i] == ')')
00074                                         --level;
00075                                     // unary +/- after operator -- copy now,
00076                                     // handle during next loop (again = true)
00077                                     // (^ is the only op with higher precedence)
00078                                     if(in[i]=='^' && (in[i+1]=='-' ||
00079                                                                 in[i+1]=='+'))
00080                                         out[j++] = in[i++];
00081                                     out[j++] = in[i++];
00082                                 }
00083                                 c = ')';
00084                                 --i;
00085                         }
00086                         prev = out[j++] = c;
00087                     }
00088                     BLAssert((unsigned)j < sizeof(out));
00089                     out[j] = '\0';
00090                     // if empty or all whitespace, force invalid
00091                     if(j == 0) strcpy(out,"x+-*/y");
00092                     free(in);
00093                 } while(again);
00094 
00095                 double v = HepTool::Evaluator::evaluate(out);
00096                 if(status() != OK) v = std::numeric_limits<double>::quiet_NaN();
00097                 return v;
00098         }

bool BLEvaluator::isOK (  )  [inline]

isOK() returns true if the previous call to expression succeeded.

Referenced by BLTrackNTuple::appendTrack(), BLCMDfieldexpr::checkValidExpr(), BLCMDtrace::newTrace(), and BLCMDprofile::Entry::UserZSteppingAction().

00101 { return status() == OK; }

void BLEvaluator::setTrackVariables ( const G4Track *  track,
BLCoordinateType  coordType,
G4String  suffix = "",
bool  fields = false 
) [inline]

setTrackVariables() devines variables in the evaluator corresponding to the usual track variables. These can then be used in expressions.

References B, E, BLCoordinates::getCoords(), BLGlobalField::GetFieldValue(), BLManager::getObject(), BLGlobalField::getObject(), BLCoordinates::getRotation(), and BLCoordinates::isValid().

Referenced by BLCMDtrace::newTrace(), MaterialFilter::UserSteppingAction(), BLCMDtune::UserZSteppingAction(), BLCMDprofile::Entry::UserZSteppingAction(), and BLCMDprintf::UserZSteppingAction().

00107                                                                                {
00108                 G4RunManager* runmgr = G4RunManager::GetRunManager();
00109                 const G4Event* event = runmgr->GetCurrentEvent();
00110                 int evId = event->GetEventID();
00111                 G4ThreeVector position = track->GetPosition();
00112                 G4double time = track->GetGlobalTime();
00113                 G4ThreeVector momentum = track->GetMomentum();
00114 
00115                 // get B and E fields
00116                 G4ThreeVector B, E;
00117                 if(fields) {
00118                         G4double point[4], field[6];
00119                         point[0] = position[0];
00120                         point[1] = position[1];
00121                         point[2] = position[2];
00122                         point[3] = time;
00123                         BLGlobalField::getObject()->GetFieldValue(point,field);
00124                         B = G4ThreeVector(field[0],field[1],field[2]);
00125                         E = G4ThreeVector(field[3],field[4],field[5]);
00126                 }
00127 
00128                 // transform to desired coordinates, if available
00129                 BLCoordinates *c = (BLCoordinates *)track->GetUserInformation();
00130                 if(c && c->isValid()) {
00131                         c->getCoords(coordType,position);
00132                         momentum = c->getRotation() * momentum;
00133                         B = c->getRotation() * B;
00134                         E = c->getRotation() * E;
00135                 }
00136                 setVariable((G4String("x")+suffix).c_str(), position[0]/mm);
00137                 setVariable((G4String("y")+suffix).c_str(), position[1]/mm);
00138                 setVariable((G4String("z")+suffix).c_str(), position[2]/mm);
00139                 setVariable((G4String("Px")+suffix).c_str(), momentum[0]/MeV);
00140                 setVariable((G4String("Py")+suffix).c_str(), momentum[1]/MeV);
00141                 setVariable((G4String("Pz")+suffix).c_str(), momentum[2]/MeV);
00142                 setVariable((G4String("t")+suffix).c_str(), time/ns);
00143                 setVariable((G4String("PDGid")+suffix).c_str(), track->GetDefinition()->GetPDGEncoding());
00144                 setVariable((G4String("EventID")+suffix).c_str(), evId);
00145                 setVariable((G4String("TrackID")+suffix).c_str(), 
00146                                 BLManager::getObject()->
00147                                     getExternalTrackID(track));
00148                 setVariable((G4String("ParentID")+suffix).c_str(),
00149                                 BLManager::getObject()->
00150                                     getExternalParentID(track));
00151                 setVariable((G4String("wt")+suffix).c_str(),track->GetWeight());
00152                 if(fields) {
00153                         setVariable((G4String("Bx")+suffix).c_str(),B[0]/tesla);
00154                         setVariable((G4String("By")+suffix).c_str(),B[1]/tesla);
00155                         setVariable((G4String("Bz")+suffix).c_str(),B[2]/tesla);
00156                         setVariable((G4String("Ex")+suffix).c_str(),
00157                                                         E[0]/(megavolt/meter));
00158                         setVariable((G4String("Ey")+suffix).c_str(),
00159                                                         E[1]/(megavolt/meter));
00160                         setVariable((G4String("Ez")+suffix).c_str(),
00161                                                         E[2]/(megavolt/meter));
00162                 }
00163         }

bool BLEvaluator::isidchar ( char  c  )  [inline]

isidchar() returns true if the char is valid for an identifier.

Referenced by isumchar().

00166 { return isalnum(c) || c == '_'; }

bool BLEvaluator::isopchar ( char  c  )  [inline]

isopchar() returns true if the character is an operator (no parens)

Referenced by evaluate().

00169                               { return c=='+' || c=='-' || c=='*' || c=='/' ||
00170                                         c=='^' || c=='<' || c=='>' || c=='!' ||
00171                                         c=='|' || c=='&' || c=='=' || c=='%'; }

bool BLEvaluator::isumchar ( char  c  )  [inline]

isumchar() returns true if the char should be inside the parens generated to surround the unary minus (parens matched in evaluate())

References isidchar().

Referenced by evaluate().

00175                               { return isidchar(c) || c=='.' ||
00176                                         c=='^' || c=='(' || c==')'; }


The documentation for this class was generated from the following file:
g4beamline