#include "THaFormula.h"
#include "THaArrayString.h"
#include "THaVarList.h"
#include "THaCutList.h"
#include "THaCut.h"
#include "TROOT.h"
#include "TError.h"
#include <iostream>
#include <cstring>
#include <cstdlib>
using namespace std;
const Option_t* const THaFormula::kPRINTFULL = "FULL";
const Option_t* const THaFormula::kPRINTBRIEF = "BRIEF";
static const Double_t kBig = 1e38;
THaFormula::THaFormula( const char* name, const char* expression,
const THaVarList* vlst, const THaCutList* clst )
: TFormula(), fVarDef(NULL), fVarList(vlst), fCutList(clst),
fError(kFALSE), fRegister(kTRUE)
{
SetName(name);
Int_t nch = strlen(expression);
char *expr = new char[nch+1];
Int_t j = 0;
for (Int_t i=0;i<nch;i++) {
if (expression[i] == ' ') continue;
if (i > 0 && (expression[i] == '*') && (expression[i-1] == '*')) {
expr[j-1] = '^';
continue;
}
expr[j] = expression[i]; j++;
}
expr[j] = 0;
if (j) SetTitle(expr);
delete [] expr;
Compile();
}
THaFormula::THaFormula( const THaFormula& rhs ) :
TFormula(rhs), fNcodes(rhs.fNcodes), fVarList(rhs.fVarList),
fCutList(rhs.fCutList), fError(rhs.fError), fRegister(rhs.fRegister)
{
fVarDef = new FVarDef_t[ kMAXCODES ];
memcpy( fVarDef, rhs.fVarDef, kMAXCODES*sizeof(FVarDef_t));
}
THaFormula& THaFormula::operator=( const THaFormula& rhs )
{
if( this != &rhs ) {
TFormula::operator=(rhs);
fNcodes = rhs.fNcodes;
fVarList = rhs.fVarList;
fCutList = rhs.fCutList;
fError = rhs.fError;
fRegister = rhs.fRegister;
delete fVarDef;
fVarDef = new FVarDef_t[ kMAXCODES ];
memcpy( fVarDef, rhs.fVarDef, kMAXCODES*sizeof(FVarDef_t));
}
return *this;
}
Int_t THaFormula::Compile( const char* expression )
{
fNcodes = 0;
fNval = 0;
fAlreadyFound.ResetAllBits();
delete [] fVarDef;
fVarDef = new FVarDef_t[ kMAXCODES ];
memset( fVarDef, 0, kMAXCODES*sizeof(FVarDef_t));
Int_t status = TFormula::Compile( expression );
fError = (status != 0);
if( fError ) {
if( fRegister) gROOT->GetListOfFunctions()->Remove(this);
} else {
#ifdef WITH_DEBUG
R__ASSERT( fNval+fNstring == fNcodes );
R__ASSERT( fNstring >= 0 && fNval >= 0 );
#endif
if( fRegister ) {
TObject* old = gROOT->GetListOfFunctions()->FindObject(GetName());
if (old) gROOT->GetListOfFunctions()->Remove(old);
gROOT->GetListOfFunctions()->Add(this);
}
if( fNstring > 0 && fNval > 0 )
fNval = fNstring = fNcodes;
}
return status;
}
THaFormula::~THaFormula()
{
delete [] fVarDef; fVarDef = 0;
}
char* THaFormula::DefinedString( Int_t i )
{
#ifdef WITH_DEBUG
R__ASSERT( i>=0 && i<fNcodes );
#endif
FVarDef_t* def = fVarDef+i;
if( def->type == kString ) {
const THaVar* pvar = reinterpret_cast<const THaVar*>( def->code );
char** ppc = (char**)pvar->GetValuePointer();
return *ppc;
}
return (char*)"";
}
Bool_t THaFormula::IsString(Int_t oper) const
{
Int_t action = GetAction(oper);
return ( action == kStringConst || action == kDefinedString );
}
Double_t THaFormula::DefinedValue( Int_t i )
{
#ifdef WITH_DEBUG
R__ASSERT( i>=0 && i<fNcodes );
#endif
FVarDef_t* def = fVarDef+i;
const void* ptr = def->code;
if( !ptr ) return kBig;
switch( def->type ) {
case kVariable:
case kString:
return reinterpret_cast<const THaVar*>(ptr)->GetValue( def->index );
break;
case kCut:
return reinterpret_cast<const THaCut*>(ptr)->GetResult();
break;
default:
return kBig;
}
}
#if ROOT_VERSION_CODE >= ROOT_VERSION(4,0,0)
Int_t THaFormula::DefinedVariable(TString& name, Int_t& action)
#else
Int_t THaFormula::DefinedVariable(TString& name)
#endif
{
#if ROOT_VERSION_CODE >= ROOT_VERSION(4,0,0)
action = kDefinedVariable;
#endif
Int_t k = DefinedGlobalVariable( name );
if( k>=0 ) {
FVarDef_t* def = fVarDef+k;
const THaVar* pvar = reinterpret_cast<const THaVar*>( def->code );
if( pvar->GetType() == kCharP ) {
#if ROOT_VERSION_CODE >= ROOT_VERSION(4,0,0)
action = kDefinedString;
#endif
def->type = kString;
if( k < kMAXFOUND && !fAlreadyFound.TestBitNumber(k) )
fAlreadyFound.SetBitNumber(k);
else
--fNstring;
}
return k;
}
return DefinedCut( name );
}
Int_t THaFormula::DefinedCut( const TString& name )
{
if( fCutList ) {
const THaCut* pcut = fCutList->FindCut( name );
if( pcut ) {
if( fNcodes >= kMAXCODES ) return -1;
FVarDef_t* def = fVarDef;
for( Int_t i=0; i<fNcodes; i++, def++ ) {
if( def->type == kCut && pcut == def->code )
return i;
}
def->type = kCut;
def->code = pcut;
def->index = 0;
fNpar = 0;
return fNcodes++;
}
}
return -1;
}
Int_t THaFormula::DefinedGlobalVariable( const TString& name )
{
if( !fVarList || fNcodes >= kMAXCODES )
return -2;
THaArrayString var(name);
if( var.IsError() ) return -1;
const THaVar* obj = fVarList->Find( var.GetName() );
if( !obj )
return -1;
if( var.IsArray() && !obj->IsArray() )
return -2;
Int_t index = 0;
if( var.IsArray()
&& (index = obj->Index( var )) <0 ) return -2;
FVarDef_t* def = fVarDef;
for( Int_t i=0; i<fNcodes; i++, def++ ) {
if( obj == def->code && index == def->index )
return i;
}
def->type = kVariable;
def->code = obj;
def->index = index;
fNpar = 0;
return fNcodes++;
}
Double_t THaFormula::Eval( void )
{
if( fError ) return kBig;
if (fNoper == 1 && fNcodes == 1 ) return DefinedValue(0);
return EvalPar( 0 );
}
#if ROOT_VERSION_CODE >= ROOT_VERSION(3,5,7)
#if ROOT_VERSION_CODE >= ROOT_VERSION(5,16,0)
TString THaFormula::GetExpFormula( Option_t* ) const
#else
TString THaFormula::GetExpFormula() const
#endif
{
return fTitle;
}
#endif
void THaFormula::Print( Option_t* option ) const
{
if( !strcmp( option, kPRINTFULL ))
TFormula::Print( option );
else
TNamed::Print(option);
}
ClassImp(THaFormula)
Last change: Sat Nov 7 21:26:46 2009
Last generated: 2009-11-07 21:26
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.