#include "QFramework/TQCompiledCut.h"
#include "QFramework/TQCutFactory.h"
#include "TObjArray.h"
#include "TObjString.h"
#include "TFormula.h"
#include "QFramework/TQUtils.h"
#include "QFramework/TQStringUtils.h"
#include "QFramework/TQIterator.h"
#include "QFramework/TQLibrary.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include <cstdlib>
ClassImp(TQCutFactory)
TQCutFactory::TQCutFactory() : TObject() {
fCuts = new TList();
fTreeObservableTemplates = 0;
}
void TQCutFactory::addCut(TString definition) {
fCuts->AddLast(new TObjString(definition));
}
TString TQCutFactory::findCut(TString name) {
TString * cutName = new TString();
TString * baseCutName = new TString();
TString * cutExpr = new TString();
TString * weightExpr = new TString();
TString * cutName2 = new TString();
TString * baseCutName2= new TString();
TString * cutExpr2 = new TString();
TString * weightExpr2 = new TString();
TIterator * itr = fCuts->MakeIterator(false);
TObject * obj;
TString cutDef = "";
while ((obj = itr->Next())) {
TString tmpExp = ((TObjString*)obj)->String();
(*cutName)=""; (*baseCutName)="";
TQCompiledCut::parseCutDefinition(tmpExp, cutName, baseCutName, cutExpr, weightExpr);
if ((*cutName) == name) {
cutDef = tmpExp;
break;
}
}
delete itr;
delete cutName ;
delete baseCutName ;
delete cutExpr ;
delete weightExpr ;
delete cutName2 ;
delete baseCutName2 ;
delete cutExpr2 ;
delete weightExpr2 ;
return cutDef;
}
TString TQCutFactory::removeCut(TString name) {
TString * cutName = new TString();
TString * baseCutName = new TString();
TString * cutExpr = new TString();
TString * weightExpr = new TString();
TString * cutName2 = new TString();
TString * baseCutName2= new TString();
TString * cutExpr2 = new TString();
TString * weightExpr2 = new TString();
TIterator * itr = fCuts->MakeIterator(false);
TObject * obj;
TString cutDef = "";
bool found = false;
while ((obj = itr->Next())) {
cutDef = ((TObjString*)obj)->String();
(*cutName)=""; (*baseCutName)="";
TQCompiledCut::parseCutDefinition(cutDef, cutName, baseCutName, cutExpr, weightExpr);
if ((*cutName) == name) {
found = true;
fCuts->Remove(obj);
bool hasDependence=false;
TIterator * itr2 = fCuts->MakeIterator(false);
TObject * obj2;
while (!hasDependence && (obj2 = itr2->Next())) {
TString cutDef2 = ((TObjString*)obj2)->String();
TQCompiledCut::parseCutDefinition(cutDef2, cutName2, baseCutName2, cutExpr2, weightExpr2);
if ((*baseCutName2)==(*cutName)) {
hasDependence=true;
}
}
delete itr2;
}
if (found) break;
}
delete itr;
delete cutName ;
delete baseCutName ;
delete cutExpr ;
delete weightExpr ;
delete cutName2 ;
delete baseCutName2 ;
delete cutExpr2 ;
delete weightExpr2 ;
return cutDef;
}
void TQCutFactory::setTreeObservableTemplates(TList * treeObservableTemplates) {
WARNclass("this functionality is deprecated. please use 'TQObservable::addObservable(myObservable,name)' instead");
fTreeObservableTemplates = treeObservableTemplates;
TQObservableIterator itr(fTreeObservableTemplates);
while(itr.hasNext()){
TQObservable* obs = itr.readNext();
if(obs) TQObservable::addObservable(obs);
}
}
void TQCutFactory::print() {
for (int icut = 0; icut < fCuts->GetEntries(); ++icut) {
std::cout << ((TObjString*) fCuts->At(icut))->GetString() << std::endl;
}
}
void TQCutFactory::orderCutDefs() {
TList * outputCuts = new TList();
TString * cutName = new TString();
TString * baseCutName = new TString();
TString * cutExpr = new TString();
TString * weightExpr = new TString();
TString * cutName2 = new TString();
TString * baseCutName2= new TString();
TString * cutExpr2 = new TString();
TString * weightExpr2 = new TString();
while (fCuts->GetSize()>0) {
TIterator * itr = fCuts->MakeIterator(false);
TObject * obj;
while ((obj = itr->Next())) {
TString cutDef = ((TObjString*)obj)->String();
(*cutName)=""; (*baseCutName)="";
TQCompiledCut::parseCutDefinition(cutDef, cutName, baseCutName, cutExpr, weightExpr);
bool hasDependence=false;
TIterator * itr2 = fCuts->MakeIterator(false);
TObject * obj2;
while (!hasDependence && (obj2 = itr2->Next())) {
TString cutDef2 = ((TObjString*)obj2)->String();
TQCompiledCut::parseCutDefinition(cutDef2, cutName2, baseCutName2, cutExpr2, weightExpr2);
if ((*baseCutName2)==(*cutName))
hasDependence=true;
}
if (!hasDependence) {
outputCuts->AddFirst(new TObjString(cutDef));
fCuts->Remove(obj);
}
delete itr2;
}
delete itr;
}
delete cutName ;
delete baseCutName ;
delete cutExpr ;
delete weightExpr ;
delete cutName2 ;
delete baseCutName2 ;
delete cutExpr2 ;
delete weightExpr2 ;
delete fCuts;
fCuts = outputCuts;
}
TQCompiledCut * TQCutFactory::compileCutsWithoutEvaluation() {
TQIterator itr(fCuts);
TQCompiledCut * baseCut = 0;
while(itr.hasNext()){
TObjString* obj = dynamic_cast<TObjString*>(itr.readNext());
if(!obj) continue;
TString cutDefCompiled = obj->String();
if (baseCut) {
baseCut->addCut(cutDefCompiled);
} else {
baseCut = TQCompiledCut::createCut(cutDefCompiled);
}
}
return baseCut;
}
TQCompiledCut * TQCutFactory::compileCuts(TString parameter) {
TQIterator itr(fCuts);
TQCompiledCut * baseCut = 0;
while(itr.hasNext()){
TObjString* obj = dynamic_cast<TObjString*>(itr.readNext());
if(!obj) continue;
TString cutDefCompiled = evaluate(obj->String(), parameter);
if (baseCut) {
baseCut->addCut(cutDefCompiled);
} else {
baseCut = TQCompiledCut::createCut(cutDefCompiled);
}
}
return baseCut;
}
TString TQCutFactory::evaluateSubExpression(const TString& input_, const TString& parameter) {
TString input(input_);
TString resultExpression("");
while (!input.IsNull()) {
Ssiz_t pos = input.Index("{");
if (pos == kNPOS) {
resultExpression.Append(input);
input.Remove(0);
} else if (pos == 0) {
int depth = 1;
while (depth > 0 && ++pos < input.Length()) {
char ch = input(pos);
if (ch == '{') { depth++; }
if (ch == '}') { depth--; }
}
TString subInput(input(1, pos - 1));
input.Remove(0, pos + 1);
TString subExpression(TQStringUtils::trim(evaluate(subInput, parameter)));
resultExpression.Append(subExpression);
} else {
TString subInput = input(0, pos);
resultExpression.Append(subInput);
input.Remove(0, pos);
}
}
return resultExpression;
}
TString TQCutFactory::evaluate(const TString& input_, const TString& parameter) {
TString result = evaluateSubExpression(input_, parameter);
TList * tokens = TQStringUtils::tokenize(parameter, ",", true, "", "''");
result.ReplaceAll("'", "\"");
for (int iPar = 0; iPar < tokens->GetEntries(); iPar++) {
TString * key = new TString();
TString * value = new TString();
if (TQUtils::parseAssignment(((TObjString*)tokens->At(iPar))->String(), key, value)) {
key->ToUpper();
value->ReplaceAll("'", "\"");
result.ReplaceAll(TString::Format("$%s", key->Data()), *value);
}
delete key;
delete value;
}
tokens->Delete();
delete tokens;
Ssiz_t posIf = result.Index("?");
if (posIf == kNPOS) {
return TQStringUtils::trim(result);
} else {
TString ifExpr = result(0, posIf);
TFormula * formula = new TFormula("", ifExpr);
TString thenElseExpr = result(posIf + 1, result.Length());
TString thenExpr, elseExpr;
Ssiz_t posElse = thenElseExpr.Index(":");
if (posElse == kNPOS) {
thenExpr = thenElseExpr;
} else {
thenExpr = thenElseExpr(0, posElse);
elseExpr = thenElseExpr(posElse + 1, thenElseExpr.Length());
}
if (formula->Eval(0.)) {
delete formula;
return TQStringUtils::trim(thenExpr);
} else {
delete formula;
return TQStringUtils::trim(elseExpr);
}
}
}
TQCutFactory::~TQCutFactory() {
delete fCuts;
}
bool TQCutFactory::isEmpty() {
return (this->fCuts->GetEntries() < 1);
}