//*-- Modified : v0.50 17/07/00 by D. Buskulic//*-- Modified : v0.49 26/06/00 by D. Buskulic//*-- Modified : v0.47 26/04/00 by D. Buskulic//*-- Author : Damir Buskulic 11/01/00//////////////////////////////////////////////////////////////////////////// //// VConditionFormula //// //// The Frame conditions formula class //// ////////////////////////////////////////////////////////////////////////////
#include "VConditionFormula.h"
#include "VConditionNames.h"
#include "string.h"
#include "TRandom.h"
ClassImp(VConditionFormula)
//______________________________________________________________________________//// A Condition formula is used to pass a selection expression// to the frame selection routines in the database//// A ConditionFormula can contain any arithmetic expression including// standard operators and mathematical functions separated by operators.// Examples of valid expression:// "x<y && sqrt(z)>3.2"////______________________________________________________________________________VConditionFormula::VConditionFormula(): TFormula()
{
//*-*-*-*-*-*-*-*-*-*-*Condition Formula default constructor*-*-*-*-*-*-*-*-*//*-* =====================================mDataBase = 0;
mNCodes = 0;
}
//______________________________________________________________________________VConditionFormula::VConditionFormula(const char *name,const char *expression, VVirtualFrameInfoDB *db)
:TFormula()
{
//*-*-*-*-*-*-*-*-*-*-*Normal Condition Formula constructor*-*-*-*-*-*-*-*-*-*//*-* ====================================//mDataBase = db;
mNCodes = 0;
if (Compile(expression)) {mDataBase = 0; return; }
SetName(name);
}
//______________________________________________________________________________VConditionFormula::VConditionFormula(const VConditionFormula &cformula)
{
// Copy constructor
((VConditionFormula&)cformula).Copy(*this);
}
//______________________________________________________________________________VConditionFormula::~VConditionFormula()
{
//*-*-*-*-*-*-*-*-*-*- Condition Formula default destructor -*-*-*-*-*-*-*-*-*//*-* ====================================
}
//______________________________________________________________________________voidVConditionFormula::Copy(TObject &obj)
{
//*-*-*-*-*-*-*-*-*-*- Copy this condition formula -*-*-*-*-*-*-*-*-*-*-*-*-*//*-* ===========================Int_t i;
TFormula::Copy(obj);
((VConditionFormula&)obj).mDataBase = mDataBase;
((VConditionFormula&)obj).mNCodes = mNCodes;
for (i=0;i<mNCodes;i++) ((VConditionFormula&)obj).mCodes[i] = mCodes[i];
for (i=0;i<mNCodes;i++) ((VConditionFormula&)obj).mVarCodes[i] = mVarCodes[i];
}
//______________________________________________________________________________Int_tVConditionFormula::DefinedVariable(TString &name)
{
//*-*-*-*-*-* Check if name is in the list of conditions *-*-*-*-*//*-* ==================================================//// This member function redefines the function in TFormula// If a condition has a name corresponding to the argument name, then// returns a new code.// A VConditionFormula may contain more than one variable.//// name can be :// - Condition_Name// - Condition_Name.Variable_Name//// Variable name can be a standard name like "amplitude" or any of// the var names defined for the condition. The standard names// are defined in VConditionFormula::CheckStandardVar// If variable name is omitted, it is assumed to be "amplitude"//
if (!mDataBase) return -1;
fNpar = 0;
Int_t nchname = name.Length();
if (nchname > 60) return -1;
static char lname[64];
static char lvarname[128];
Int_t i;
strcpy(lname,name.Data());
Int_t dot = 0;
lvarname[0] = 0;
for (i=0;i<nchname;i++) {
if (lname[i] == '.') {
if (i == nchname-1) break; // for example 999.
if (!dot) {
dot = i;
strcpy(lvarname,&lname[i+1]);
lname[i] = 0;
break;
}
}
}
VConditionNames *lscond = mDataBase->GetConditionNames();
//*-*- There is a dot.
if (dot) {
// Look for specific variable names// (corresponding to a defined condition)
if (lscond->CheckConditionName(lname,lvarname)){
Int_t code = mNCodes;
// Condition number. It is the index in the list of condition names.mCodes[code] = lscond->IndexOf(lname);
// Variable number. It is the index in the list of variables// corresponding to one condition.mVarCodes[code] = lscond->IndexOfVar(lname,lvarname);
mNCodes++;
return code;
}
// Look for standard variable names :// probability, amplitude, triggerStatus, timeAfter, timeBefore// these names are defined in the CheckStandardVar() method
if (lscond->CheckConditionName(lname,"")){
Int_t numstand = CheckStandardVar(lvarname);
if (numstand) {
Int_t code = mNCodes;
// Condition number. It is the index in the list of condition names.mCodes[code] = lscond->IndexOf(lname);
// Standard variable code, defined in VConditionFormula::CheckStandardVarmVarCodes[code] = -numstand;
mNCodes++;
return code;
}
}
//*-*- There is no dot. assume variable = boolean trigger exists or not
} else {
if (lscond->CheckConditionName(lname,"")){
Int_t numstand = 6; // i.e. CheckStandardVar("amplitude");
Int_t code = mNCodes;
// Condition number. It is the index in the list of condition names.mCodes[code] = lscond->IndexOf(lname);
// Standard variable code, defined in VConditionFormula::CheckStandardVarmVarCodes[code] = -numstand;
mNCodes++;
return code;
}
}
return -1;
}
//______________________________________________________________________________Int_tVConditionFormula::CheckStandardVar(const Text_t* name)
{
// Checks that the name of the condition variable is a standard one.// Accepts a name that is not complete, provided it is not ambiguous// Returns a number indicating the variable :// 1 = "timeBefore",// 2 = "timeAfter",// 3 = "triggerStatus",// 4 = "amplitude",// 5 = "probability"// 6 = "boolean, trigger exists or not" used in DefinedVariable()// 0 = no match
static char* standname[5] = {"timeBefore","timeAfter","triggerStatus",
"amplitude","probability"};
unsigned int indic, istand, numfound, index, foundone;
char* spoint;
const Text_t* namepoint;
indic = 0;
numfound = 0;
for (istand=0;istand<5;istand++) {
spoint = standname[istand];
namepoint = name;
foundone = 1;
if (strlen(name)<=strlen(spoint)) {
for (index = 0; index<strlen(name);index++) {
if (*namepoint != *spoint) {foundone = 0; break;}
namepoint++;
spoint++;
}
} else {foundone = 0;}
if (foundone) {
numfound++;
indic=istand+1;
}
}
if (numfound != 1) return 0;
return indic;
}
// //______________________________________________________________________________// Double_tVConditionFormula::EvalInstance()// {// //*-*-*-*-*-*-*-*-*-*-*Evaluate this condition formula*-*-*-*-*-*-*-*-*-*-*-*-*// //*-* ===============================// // The formula applies to the conditions last loaded by the database// //// return EvalInstance(mDataBase->GetConditionsArray(),mDataBase->GetNConditions());// }//______________________________________________________________________________Double_tVConditionFormula::EvalInstance(VFrCondition** condarray, Int_t ncond)
{
//*-*-*-*-*-*-*-*-*-*-*Evaluate this condition formula*-*-*-*-*-*-*-*-*-*-*-*-*//*-* ===============================// The formula applies to the conditions last loaded by the database//Double_t result;
TObjArray* tmparray = new TObjArray();
for (int i=0;i<ncond;i++) tmparray->Add(condarray[i]);
result = EvalInstance(tmparray);
delete tmparray;
return result;
}
//______________________________________________________________________________Double_tVConditionFormula::EvalInstance(VConditionSet* condset)
{
//*-*-*-*-*-*-*-*-*-*-*Evaluate this condition formula*-*-*-*-*-*-*-*-*-*-*-*-*//*-* ===============================// The formula applies to the current conditions in the condition set "condset"//
return EvalInstance(condset->GetCurConditions());
}
//______________________________________________________________________________Double_tVConditionFormula::EvalInstance(TObjArray* lcond)
{
//*-*-*-*-*-*-*-*-*-*-*Evaluate this condition formula*-*-*-*-*-*-*-*-*-*-*-*-*//*-* ===============================// It is supposed that the formula applies to the array of conditions "lcond"//Int_t i,pos,pos2,int1,int2;
Float_t aresult;
Double_t tab[255];
Float_t param[50];
Double_t dexp;
char *tab2[20];
VFrCondition* condition;
VConditionNames* lcondnames;
// Database not defined, probably wrong formula
if (!mDataBase) return 0;
lcondnames = mDataBase->GetConditionNames();
// Case where it is only asked for one value
if (fNoper == 1 && mNCodes > 0) {
// TLeaf *leaf = GetLeaf(0);// if (instance) {// if (instance < leaf->GetNdata()) return leaf->GetValue(instance);// else return leaf->GetValue(0);// } else {// leaf->GetBranch()->GetEntry(mTree->GetReadEntry());// if (!(leaf->IsA() == TLeafObject::Class())) return leaf->GetValue(mIndex[0]);// return GetValueLeafObject(mIndex[0],(TLeafObject *)leaf);// }
}
// Sets the parameters corresponding to the names found while analyzing// the formula
for (i=0;i<fNval;i++) {
// condname = lcondnames->GetConditionName(mCodes[i]);// condition = (VFrCondition*)(lcond->FindObject(condname));
condition = (VFrCondition*)(lcond->At(mCodes[i]));
// printf("name to search : %s, i=%d, mCodes[i] %d,mVarCodes[i] %d cond=%xn",condname,i,mCodes[i],mVarCodes[i],condition);// In case there is no condition with that name
if (!condition) {
param[i] = 0;
// Standard conditions
} else if (mVarCodes[i] < 0) {
if (mVarCodes[i] == -1) param[i] = 0;
else if (mVarCodes[i] == -2) param[i] = 0;
else if (mVarCodes[i] == -3) param[i] = condition->GetTriggerStatus();
else if (mVarCodes[i] == -4) param[i] = condition->GetAmplitude();
else if (mVarCodes[i] == -5) param[i] = condition->GetProbability();
else if (mVarCodes[i] == -6) param[i] = 1;
else param[i] = 0;
} else {
param[i] = condition->GetVar(mVarCodes[i]);
}
}
pos = 0;
pos2 = 0;
for (i=0; i<fNoper; i++) {
Int_t action = fOper[i];
//*-*- a condition variable// (code on output of DefinedVariable is added to 100000 in TFormula)
if (action >= 100000) {
pos++; tab[pos-1] = param[action-100000];
continue;
}
//*-*- String
if (action == 80000) {
pos2++; tab2[pos2-1] = (char*)fExpr[i].Data();
continue;
}
//*-*- numerical value
if (action >= 50000) {
pos++; tab[pos-1] = fConst[action-50000];
continue;
}
if (action == 0) {
pos++;
sscanf((const char*)fExpr[i],"%g",&aresult);
tab[pos-1] = aresult;
//*-*- basic operators and mathematical library
} else if (action < 100) {
switch(action) {
case 1 : pos--; tab[pos-1] += tab[pos]; break;
case 2 : pos--; tab[pos-1] -= tab[pos]; break;
case 3 : pos--; tab[pos-1] *= tab[pos]; break;
case 4 : pos--; if (tab[pos] == 0) tab[pos-1] = 0; // division by 0
else tab[pos-1] /= tab[pos];
break;
case 5 : {pos--; int1=Int_t(tab[pos-1]); int2=Int_t(tab[pos]); tab[pos-1] = Double_t(int1%int2); break;}
case 10 : tab[pos-1] = TMath::Cos(tab[pos-1]); break;
case 11 : tab[pos-1] = TMath::Sin(tab[pos-1]); break;
case 12 : if (TMath::Cos(tab[pos-1]) == 0) {tab[pos-1] = 0;} // { tangente indeterminee }
else tab[pos-1] = TMath::Tan(tab[pos-1]);
break;
case 13 : if (TMath::Abs(tab[pos-1]) > 1) {tab[pos-1] = 0;} // indetermination
else tab[pos-1] = TMath::ACos(tab[pos-1]);
break;
case 14 : if (TMath::Abs(tab[pos-1]) > 1) {tab[pos-1] = 0;} // indetermination
else tab[pos-1] = TMath::ASin(tab[pos-1]);
break;
case 15 : tab[pos-1] = TMath::ATan(tab[pos-1]); break;
case 70 : tab[pos-1] = TMath::CosH(tab[pos-1]); break;
case 71 : tab[pos-1] = TMath::SinH(tab[pos-1]); break;
case 72 : if (TMath::CosH(tab[pos-1]) == 0) {tab[pos-1] = 0;} // { tangente indeterminee }
else tab[pos-1] = TMath::TanH(tab[pos-1]);
break;
case 73 : if (tab[pos-1] < 1) {tab[pos-1] = 0;} // indetermination
else tab[pos-1] = TMath::ACosH(tab[pos-1]);
break;
case 74 : tab[pos-1] = TMath::ASinH(tab[pos-1]); break;
case 75 : if (TMath::Abs(tab[pos-1]) > 1) {tab[pos-1] = 0;} // indetermination
else tab[pos-1] = TMath::ATanH(tab[pos-1]); break;
case 16 : pos--; tab[pos-1] = TMath::ATan2(tab[pos-1],tab[pos]); break;
case 17 : pos--; tab[pos-1] = fmod(tab[pos-1],tab[pos]); break;
case 20 : pos--; tab[pos-1] = TMath::Power(tab[pos-1],tab[pos]); break;
case 21 : tab[pos-1] = tab[pos-1]*tab[pos-1]; break;
case 22 : tab[pos-1] = TMath::Sqrt(TMath::Abs(tab[pos-1])); break;
case 23 : pos2 -= 2; pos++;if (strstr(tab2[pos2],tab2[pos2+1])) tab[pos-1]=1;
else tab[pos-1]=0; break;
case 30 : if (tab[pos-1] > 0) tab[pos-1] = TMath::Log(tab[pos-1]);
else {tab[pos-1] = 0;} //{indetermination }
break;
case 31 : dexp = tab[pos-1];
if (dexp < -70) {tab[pos-1] = 0; break;}
if (dexp > 70) {tab[pos-1] = TMath::Exp(70); break;}
tab[pos-1] = TMath::Exp(dexp); break;
case 32 : if (tab[pos-1] > 0) tab[pos-1] = TMath::Log10(tab[pos-1]);
else {tab[pos-1] = 0;} //{indetermination }
break;
case 40 : pos++; tab[pos-1] = TMath::ACos(-1); break;
case 41 : tab[pos-1] = TMath::Abs(tab[pos-1]); break;
case 42 : if (tab[pos-1] < 0) tab[pos-1] = -1; else tab[pos-1] = 1; break;
case 50 : pos++; tab[pos-1] = gRandom->Rndm(1); break;
case 60 : pos--; if (tab[pos-1]!=0 && tab[pos]!=0) tab[pos-1]=1;
else tab[pos-1]=0; break;
case 61 : pos--; if (tab[pos-1]!=0 || tab[pos]!=0) tab[pos-1]=1;
else tab[pos-1]=0; break;
case 62 : pos--; if (tab[pos-1] == tab[pos]) tab[pos-1]=1;
else tab[pos-1]=0; break;
case 63 : pos--; if (tab[pos-1] != tab[pos]) tab[pos-1]=1;
else tab[pos-1]=0; break;
case 64 : pos--; if (tab[pos-1] < tab[pos]) tab[pos-1]=1;
else tab[pos-1]=0; break;
case 65 : pos--; if (tab[pos-1] > tab[pos]) tab[pos-1]=1;
else tab[pos-1]=0; break;
case 66 : pos--; if (tab[pos-1]<=tab[pos]) tab[pos-1]=1;
else tab[pos-1]=0; break;
case 67 : pos--; if (tab[pos-1]>=tab[pos]) tab[pos-1]=1;
else tab[pos-1]=0; break;
case 68 : if (tab[pos-1]!=0) tab[pos-1] = 0; else tab[pos-1] = 1; break;
case 76 : pos2 -= 2; pos++; if (!strcmp(tab2[pos2+1],tab2[pos2])) tab[pos-1]=1;
else tab[pos-1]=0; break;
case 77 : pos2 -= 2; pos++;if (strcmp(tab2[pos2+1],tab2[pos2])) tab[pos-1]=1;
else tab[pos-1]=0; break;
case 78 : pos--; tab[pos-1]= ((Int_t) tab[pos-1]) & ((Int_t) tab[pos]); break;
case 79 : pos--; tab[pos-1]= ((Int_t) tab[pos-1]) | ((Int_t) tab[pos]); break;
}
}
}
Double_t result = tab[0];
mLastResult = result;
return result;
}
- ROOT page - VEGA page - Class index - Top of the page This page has been automatically generated. If you have any comments or suggestions
about the page layout send a mail to
, or
contact
with any questions or problems regarding ROOT or VEGA.