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

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.

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


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(), BLCMDtune::UserZSteppingAction(), BLCMDprofile::Entry::UserZSteppingAction(), and BLCMDprintf::UserZSteppingAction().

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

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().

00098 { 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(), BLCMDtune::UserZSteppingAction(), BLCMDprofile::Entry::UserZSteppingAction(), and BLCMDprintf::UserZSteppingAction().

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

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

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

Referenced by isumchar().

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

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

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

Referenced by evaluate().

00166                               { return c=='+' || c=='-' || c=='*' || c=='/' ||
00167                                         c=='^' || c=='<' || c=='>' || c=='!' ||
00168                                         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().

00172                               { return isidchar(c) || c=='.' ||
00173                                         c=='^' || c=='(' || c==')'; }


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