//*-- 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 -*-*-*-*-*-*-*-*-*
//*-*                  ====================================

}

//______________________________________________________________________________
 void VConditionFormula::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_t VConditionFormula::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::CheckStandardVar
            mVarCodes[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::CheckStandardVar
         mVarCodes[code] = -numstand;
         mNCodes++;
         return code;
       }
   }

   return -1;
}

//______________________________________________________________________________
 Int_t VConditionFormula::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_t VConditionFormula::EvalInstance()
// {
// //*-*-*-*-*-*-*-*-*-*-*Evaluate this condition formula*-*-*-*-*-*-*-*-*-*-*-*-*
// //*-*                  ===============================
// // The formula applies to the conditions last loaded by the database
// //
//    return EvalInstance(mDataBase->GetConditionsArray(),mDataBase->GetNConditions());
// }

//______________________________________________________________________________
 Double_t VConditionFormula::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_t VConditionFormula::EvalInstance(VConditionSet* condset)
{
//*-*-*-*-*-*-*-*-*-*-*Evaluate this condition formula*-*-*-*-*-*-*-*-*-*-*-*-*
//*-*                  ===============================
// The formula applies to the current conditions in the condition set "condset"
//
   return EvalInstance(condset->GetCurConditions());
}

//______________________________________________________________________________
 Double_t VConditionFormula::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.