#include "QFramework/TQMultiObservable.h"
#include "TROOT.h"
#include <limits>
#include <stdexcept>
#include "QFramework/TQSample.h"
bool TQMultiObservable::gEvaluateSubObservablesLazily(false);
#include "QFramework/TQLibrary.h"
ClassImp(TQMultiObservable)
TQMultiObservable::TQMultiObservable(){
DEBUGclass("default constructor called");
}
TQMultiObservable::~TQMultiObservable(){
DEBUGclass("destructor called");
}
int TQMultiObservable::getNevaluations() const {
DEBUGclass("getNevaluations called");
if (this->fObservableType != TQObservable::ObservableType::vector) return 1;
int nEvals = -1;
for (size_t i=0; i<this->fObservables.size(); ++i) {
if (this->fObservables[i]->getObservableType() != TQObservable::ObservableType::vector) continue;
int iEvals = this->fObservables[i]->getNevaluations();
if (nEvals < 0) nEvals = iEvals;
if (nEvals != iEvals) return -1;
}
DEBUGclass("returning");
return nEvals;
}
double TQMultiObservable::getValueAt(int index) const {
DEBUGclass("entering function");
if (!this->isInitialized()) {
throw std::runtime_error( TString::Format("caught attempt to evaluate uninitialized instance of TQMultiObservable with name '%s', expression '%s'. Make sure that its 'initialize(TQSample* s)' method is called before trying to evaluate it! (How elese should the Observable know what it should operate on?)",this->GetName(),this->getExpression().Data()).Data() );
return -999.;
}
if (index!=0 && this->fObservableType != TQObservable::ObservableType::vector) {throw std::runtime_error("Attempt to retrieve value from illegal index in observable."); return -999.;}
const int nEntries = this->getNevaluations();
if (index>=nEntries) throw std::runtime_error(TString::Format("Requested index '%d' is not available for TQMultiObservable with expression '%s' (%d entries available)",index,this->getExpression().Data(),nEntries).Data());
const int entry = this->getCurrentEntry();
if(entry < 0 || entry != this->fCachedEntry){
DEBUGclass("calculating value of '%s'",this->getActiveExpression().Data());
if (nEntries < 0) throw std::runtime_error(TString::Format("Illegal number of evaluations for TQMultiObservable with expression '%s'. Are you sure all vector observables are guaranteed to have the same number of evaluations?",this->getExpression().Data()).Data() );
this->fCachedValue.resize(std::max(nEntries,(int)this->fCachedValue.size()));
for (int myIndex = 0; myIndex<nEntries; myIndex++) {
#if ROOT_VERSION_CODE >= ROOT_VERSION(6,06,00)
if (TQMultiObservable::gEvaluateSubObservablesLazily) {
this->fCachedValue[myIndex] = this->fFormula->Eval(myIndex);
} else {
for(size_t i=0; i<this->fObservables.size(); ++i){
DEBUGclass("evaluating observable %d: %s",(int)(i),this->fObservables[i]->getActiveExpression().Data());
this->fFormula->SetParameter(i,this->fObservables[i]->getValueAt( this->fObservables[i]->getObservableType() == TQObservable::ObservableType::vector ? myIndex : 0 ));
DEBUGclass("setting parameter [%d]=%g (from '%s')",(int)(i),this->fObservables[i]->getValueAt(this->fObservables[i]->getObservableType() == TQObservable::ObservableType::vector ? myIndex : 0),this->fObservables[i]->getActiveExpression().Data());
}
this->fCachedValue[myIndex] = this->fFormula->Eval(0.);
}
#else
for(size_t i=0; i<this->fObservables.size(); ++i){
DEBUGclass("evaluating observable %d: %s",(int)(i),this->fObservables[i]->getActiveExpression().Data());
this->fFormula->SetParameter(i,this->fObservables[i]->getValueAt( this->fObservables[i]->getObservableType() == TQObservable::ObservableType::vector ? myIndex : 0 ));
DEBUGclass("setting parameter [%d]=%g (from '%s')",(int)(i),this->fObservables[i]->getValueAt(this->fObservables[i]->getObservableType() == TQObservable::ObservableType::vector ? myIndex : 0),this->fObservables[i]->getActiveExpression().Data());
}
this->fCachedValue[myIndex] = this->fFormula->Eval(0.);
#endif
DEBUGclass("value of '%s' is %g",this->fFormula->GetTitle(),this->fCachedValue[myIndex]);
}
this->fCachedEntry = entry;
} else {
DEBUGclass("skipping reevalution for event %d",entry);
}
return this->fCachedValue.at(index);
}
double TQMultiObservable::getValue() const {
if (this->fObservableType != TQObservable::ObservableType::vector) return this->getValueAt(0);
else throw std::runtime_error(TString::Format( "Caught attempt to perform scalar evaluation on vector valued instance of TQMultiObservable with expression '%s'",this->getExpression().Data() ).Data());
}
bool TQMultiObservable::initializeSelf(){
DEBUGclass("starting initialization");
this->fActiveExpression = TQObservable::unreplaceBools(this->compileExpression(this->fExpression,this->fSample,true));
DEBUGclass("initializing observable with expression '%s'",this->fActiveExpression.Data());
this->parseExpression(this->fActiveExpression);
bool retval = true;
if(!this->fParsedExpression.IsNull()){
if(!gAllowErrorMessages) TQLibrary::redirect_stdout("/dev/null");
#if ROOT_VERSION_CODE >= ROOT_VERSION(6,06,00)
TString expr;
if (TQMultiObservable::gEvaluateSubObservablesLazily) {
expr = this->fParsedExpression;
this->fFormula = new TFormula(this->GetName(),expr,1,this->fObservables.size(),false);
} else {
expr = this->compileExpression(this->fParsedExpression,this->fSample,true);
this->fFormula = new TFormula(this->GetName(),expr);
}
#else
TString expr(this->compileExpression(this->fParsedExpression,this->fSample,true));
this->fFormula = new TFormula(this->GetName(),expr);
#endif
if(!gAllowErrorMessages) TQLibrary::restore_stdout();
#if ROOT_VERSION_CODE >= ROOT_VERSION(6,04,00)
if(!this->fFormula->IsValid()){
throw std::runtime_error(TString::Format("unable to initialize formula with expression '%s'",expr.Data()).Data());
return false;
}
#endif
} else {
WARNclass("observable '%s' has Null-Expression!",this->GetName());
return false;
}
this->fObservableType = TQObservable::ObservableType::scalar;
for(size_t i=0; i<this->fObservables.size(); ++i){
if(!this->fObservables[i]->initialize(this->fSample)) {
ERRORclass("Failed to initialize sub-observable created from expression '%s'",this->fObservables[i]->getExpression().Data());
retval = false;
}
if (this->fObservables[i]->getObservableType() == TQObservable::ObservableType::vector) {
this->fObservableType = TQObservable::ObservableType::vector;
#if ROOT_VERSION_CODE >= ROOT_VERSION(6,06,00)
if (TQMultiObservable::gEvaluateSubObservablesLazily) {
this->fFormula->SetParameter(i,1.);
} else {
this->fFormula->SetParameter(i,0.);
}
#endif
}
}
this->fCachedEntry = -999;
DEBUGclass("successfully initialized");
return retval;
}
bool TQMultiObservable::finalizeSelf(){
DEBUGclass("finalizing '%s'",this->GetName());
bool ok = true;
for(size_t i=0; i<this->fObservables.size(); ++i){
if(!(this->fObservables[i]->finalize())){
ok = false;
}
}
if(this->fFormula) delete this->fFormula;
this->fFormula = NULL;
this->fActiveExpression.Clear();
this->fObservables.clear();
return ok;
}
Long64_t TQMultiObservable::getCurrentEntry() const {
if(this->fObservables.size() == 0) return -1;
for (size_t i = 0; i<this->fObservables.size(); i++) {
if (this->fObservables[i]->getCurrentEntry() >= 0) return this->fObservables[i]->getCurrentEntry();
}
return -1;
}
TObjArray* TQMultiObservable::getBranchNames() const {
DEBUGclass("retrieving branch names");
TObjArray* bnames = new TObjArray();
for(size_t i=0; i<this->fObservables.size(); ++i){
TQObservable* obs =this->fObservables[i];
if(!obs) throw std::runtime_error("encountered invalid sub-observable!");
DEBUGclass("retrieving branches of observable '%s' of class '%s'",obs->getExpression().Data(),obs->ClassName());
TCollection* c = obs->getBranchNames();
if(c){
c->SetOwner(false);
bnames->AddAll(c);
delete c;
}
}
DEBUGclass("returning");
return bnames;
}
TQMultiObservable::TQMultiObservable(const TString& expression):
TQObservable(expression)
{
DEBUGclass("constructor called with '%s'",expression.Data());
this->SetName(TQObservable::makeObservableName(expression));
this->setExpression(expression);
}
const TString& TQMultiObservable::getExpression() const {
return this->fExpression;
}
bool TQMultiObservable::hasExpression() const {
return true;
}
void TQMultiObservable::setExpression(const TString& expr){
this->fExpression = expr;
}
bool TQMultiObservable::parseExpression(const TString& expr){
this->clearParsedExpression();
#if ROOT_VERSION_CODE >= ROOT_VERSION(6,06,00)
if (TQMultiObservable::gEvaluateSubObservablesLazily) {
this->fParsedExpression="[](double* x, double* p) -> double { return (";
}
#endif
TString expression(expr);
int parcnt = 0;
while(!expression.IsNull()){
DEBUGclass("entering next parsing cycle: expr='%s', remainder='%s'",this->fParsedExpression.Data(),expression.Data());
TQStringUtils::readUpTo(expression,this->fParsedExpression,"[");
if(expression.IsNull()) break;
TString subExpr = "";
if(TQStringUtils::readBlock(expression,subExpr,"[]") < 1){
throw std::runtime_error(TString::Format("no sub expression block [...] found in '%s'",expression.Data()).Data());
return false;
}
TQObservable* obs = TQObservable::getObservable(subExpr,this->fSample);
if(obs){
#if ROOT_VERSION_CODE >= ROOT_VERSION(6,06,00)
if (TQMultiObservable::gEvaluateSubObservablesLazily) {
this->fParsedExpression.Append(TString::Format("(reinterpret_cast<TQObservable*>(%p)->getValueAt(x[0]*p[%d]))",(void*)obs,parcnt));
} else {
this->fParsedExpression.Append(TString::Format("[%d]",parcnt));
}
#else
this->fParsedExpression.Append(TString::Format("[%d]",parcnt));
#endif
this->fObservables.push_back(obs);
parcnt++;
} else {
this->fParsedExpression.Append(TString::Format("0."));
throw std::runtime_error(TString::Format("cannot parse expression '%s', unable to retrieve observable with expression '%s'",this->fParsedExpression.Data(),subExpr.Data()).Data());
}
DEBUGclass("result of parsing cycle: expr='%s', subExpr='%s', remainder='%s'",this->fParsedExpression.Data(),subExpr.Data(),expression.Data());
}
if(!expression.IsNull()){
throw std::runtime_error(TString::Format("there was an undefined error while parsing expression '%s'",this->fParsedExpression.Data()).Data());
return false;
}
#if ROOT_VERSION_CODE >= ROOT_VERSION(6,06,00)
if (TQMultiObservable::gEvaluateSubObservablesLazily) {
this->fParsedExpression.Append("); }");
}
#endif
return true;
}
void TQMultiObservable::clearParsedExpression(){
this->fParsedExpression.Clear();
this->fObservables.clear();
}
TString TQMultiObservable::getParsedExpression(){
return this->fParsedExpression;
}
TString TQMultiObservable::getActiveExpression() const {
return this->fActiveExpression;
}
TQObservable* TQMultiObservable::getObservable(int idx){
return this->fObservables.at(idx);
}
DEFINE_OBSERVABLE_FACTORY(TQMultiObservable,TString expression){
if(TQStringUtils::removeLeadingText(expression,"Multi:") ||
TQStringUtils::hasTFormulaParameters(expression)) {
return new TQMultiObservable(expression);
}
return NULL;
}
TQMultiObservable.cxx:100 TQMultiObservable.cxx:101 TQMultiObservable.cxx:102 TQMultiObservable.cxx:103 TQMultiObservable.cxx:104 TQMultiObservable.cxx:105 TQMultiObservable.cxx:106 TQMultiObservable.cxx:107 TQMultiObservable.cxx:108 TQMultiObservable.cxx:109 TQMultiObservable.cxx:110 TQMultiObservable.cxx:111 TQMultiObservable.cxx:112 TQMultiObservable.cxx:113 TQMultiObservable.cxx:114 TQMultiObservable.cxx:115 TQMultiObservable.cxx:116 TQMultiObservable.cxx:117 TQMultiObservable.cxx:118 TQMultiObservable.cxx:119 TQMultiObservable.cxx:120 TQMultiObservable.cxx:121 TQMultiObservable.cxx:122 TQMultiObservable.cxx:123 TQMultiObservable.cxx:124 TQMultiObservable.cxx:125 TQMultiObservable.cxx:126 TQMultiObservable.cxx:127 TQMultiObservable.cxx:128 TQMultiObservable.cxx:129 TQMultiObservable.cxx:130 TQMultiObservable.cxx:131 TQMultiObservable.cxx:132 TQMultiObservable.cxx:133 TQMultiObservable.cxx:134 TQMultiObservable.cxx:135 TQMultiObservable.cxx:136 TQMultiObservable.cxx:137 TQMultiObservable.cxx:138 TQMultiObservable.cxx:139 TQMultiObservable.cxx:140 TQMultiObservable.cxx:141 TQMultiObservable.cxx:142 TQMultiObservable.cxx:143 TQMultiObservable.cxx:144 TQMultiObservable.cxx:145 TQMultiObservable.cxx:146 TQMultiObservable.cxx:147 TQMultiObservable.cxx:148 TQMultiObservable.cxx:149 TQMultiObservable.cxx:150 TQMultiObservable.cxx:151 TQMultiObservable.cxx:152 TQMultiObservable.cxx:153 TQMultiObservable.cxx:154 TQMultiObservable.cxx:155 TQMultiObservable.cxx:156 TQMultiObservable.cxx:157 TQMultiObservable.cxx:158 TQMultiObservable.cxx:159 TQMultiObservable.cxx:160 TQMultiObservable.cxx:161 TQMultiObservable.cxx:162 TQMultiObservable.cxx:163 TQMultiObservable.cxx:164 TQMultiObservable.cxx:165 TQMultiObservable.cxx:166 TQMultiObservable.cxx:167 TQMultiObservable.cxx:168 TQMultiObservable.cxx:169 TQMultiObservable.cxx:170 TQMultiObservable.cxx:171 TQMultiObservable.cxx:172 TQMultiObservable.cxx:173 TQMultiObservable.cxx:174 TQMultiObservable.cxx:175 TQMultiObservable.cxx:176 TQMultiObservable.cxx:177 TQMultiObservable.cxx:178 TQMultiObservable.cxx:179 TQMultiObservable.cxx:180 TQMultiObservable.cxx:181 TQMultiObservable.cxx:182 TQMultiObservable.cxx:183 TQMultiObservable.cxx:184 TQMultiObservable.cxx:185 TQMultiObservable.cxx:186 TQMultiObservable.cxx:187 TQMultiObservable.cxx:188 TQMultiObservable.cxx:189 TQMultiObservable.cxx:190 TQMultiObservable.cxx:191 TQMultiObservable.cxx:192 TQMultiObservable.cxx:193 TQMultiObservable.cxx:194 TQMultiObservable.cxx:195 TQMultiObservable.cxx:196 TQMultiObservable.cxx:197 TQMultiObservable.cxx:198 TQMultiObservable.cxx:199 TQMultiObservable.cxx:200 TQMultiObservable.cxx:201 TQMultiObservable.cxx:202 TQMultiObservable.cxx:203 TQMultiObservable.cxx:204 TQMultiObservable.cxx:205 TQMultiObservable.cxx:206 TQMultiObservable.cxx:207 TQMultiObservable.cxx:208 TQMultiObservable.cxx:209 TQMultiObservable.cxx:210 TQMultiObservable.cxx:211 TQMultiObservable.cxx:212 TQMultiObservable.cxx:213 TQMultiObservable.cxx:214 TQMultiObservable.cxx:215 TQMultiObservable.cxx:216 TQMultiObservable.cxx:217 TQMultiObservable.cxx:218 TQMultiObservable.cxx:219 TQMultiObservable.cxx:220 TQMultiObservable.cxx:221 TQMultiObservable.cxx:222 TQMultiObservable.cxx:223 TQMultiObservable.cxx:224 TQMultiObservable.cxx:225 TQMultiObservable.cxx:226 TQMultiObservable.cxx:227 TQMultiObservable.cxx:228 TQMultiObservable.cxx:229 TQMultiObservable.cxx:230 TQMultiObservable.cxx:231 TQMultiObservable.cxx:232 TQMultiObservable.cxx:233 TQMultiObservable.cxx:234 TQMultiObservable.cxx:235 TQMultiObservable.cxx:236 TQMultiObservable.cxx:237 TQMultiObservable.cxx:238 TQMultiObservable.cxx:239 TQMultiObservable.cxx:240 TQMultiObservable.cxx:241 TQMultiObservable.cxx:242 TQMultiObservable.cxx:243 TQMultiObservable.cxx:244 TQMultiObservable.cxx:245 TQMultiObservable.cxx:246 TQMultiObservable.cxx:247 TQMultiObservable.cxx:248 TQMultiObservable.cxx:249 TQMultiObservable.cxx:250 TQMultiObservable.cxx:251 TQMultiObservable.cxx:252 TQMultiObservable.cxx:253 TQMultiObservable.cxx:254 TQMultiObservable.cxx:255 TQMultiObservable.cxx:256 TQMultiObservable.cxx:257 TQMultiObservable.cxx:258 TQMultiObservable.cxx:259 TQMultiObservable.cxx:260 TQMultiObservable.cxx:261 TQMultiObservable.cxx:262 TQMultiObservable.cxx:263 TQMultiObservable.cxx:264 TQMultiObservable.cxx:265 TQMultiObservable.cxx:266 TQMultiObservable.cxx:267 TQMultiObservable.cxx:268 TQMultiObservable.cxx:269 TQMultiObservable.cxx:270 TQMultiObservable.cxx:271 TQMultiObservable.cxx:272 TQMultiObservable.cxx:273 TQMultiObservable.cxx:274 TQMultiObservable.cxx:275 TQMultiObservable.cxx:276 TQMultiObservable.cxx:277 TQMultiObservable.cxx:278 TQMultiObservable.cxx:279 TQMultiObservable.cxx:280 TQMultiObservable.cxx:281 TQMultiObservable.cxx:282 TQMultiObservable.cxx:283 TQMultiObservable.cxx:284 TQMultiObservable.cxx:285 TQMultiObservable.cxx:286 TQMultiObservable.cxx:287 TQMultiObservable.cxx:288 TQMultiObservable.cxx:289 TQMultiObservable.cxx:290 TQMultiObservable.cxx:291 TQMultiObservable.cxx:292 TQMultiObservable.cxx:293 TQMultiObservable.cxx:294 TQMultiObservable.cxx:295 TQMultiObservable.cxx:296 TQMultiObservable.cxx:297 TQMultiObservable.cxx:298 TQMultiObservable.cxx:299 TQMultiObservable.cxx:300 TQMultiObservable.cxx:301 TQMultiObservable.cxx:302 TQMultiObservable.cxx:303 TQMultiObservable.cxx:304 TQMultiObservable.cxx:305 TQMultiObservable.cxx:306 TQMultiObservable.cxx:307 TQMultiObservable.cxx:308 TQMultiObservable.cxx:309 TQMultiObservable.cxx:310 TQMultiObservable.cxx:311 TQMultiObservable.cxx:312 TQMultiObservable.cxx:313 TQMultiObservable.cxx:314 TQMultiObservable.cxx:315 TQMultiObservable.cxx:316 TQMultiObservable.cxx:317 TQMultiObservable.cxx:318 TQMultiObservable.cxx:319 TQMultiObservable.cxx:320 TQMultiObservable.cxx:321 TQMultiObservable.cxx:322 TQMultiObservable.cxx:323 TQMultiObservable.cxx:324 TQMultiObservable.cxx:325 TQMultiObservable.cxx:326 TQMultiObservable.cxx:327 TQMultiObservable.cxx:328 TQMultiObservable.cxx:329 TQMultiObservable.cxx:330 TQMultiObservable.cxx:331 TQMultiObservable.cxx:332 TQMultiObservable.cxx:333 TQMultiObservable.cxx:334 TQMultiObservable.cxx:335 TQMultiObservable.cxx:336 TQMultiObservable.cxx:337 TQMultiObservable.cxx:338 TQMultiObservable.cxx:339 TQMultiObservable.cxx:340 TQMultiObservable.cxx:341 TQMultiObservable.cxx:342 TQMultiObservable.cxx:343 TQMultiObservable.cxx:344 TQMultiObservable.cxx:345 TQMultiObservable.cxx:346 TQMultiObservable.cxx:347 TQMultiObservable.cxx:348 TQMultiObservable.cxx:349 TQMultiObservable.cxx:350 TQMultiObservable.cxx:351 TQMultiObservable.cxx:352 TQMultiObservable.cxx:353 TQMultiObservable.cxx:354 TQMultiObservable.cxx:355 TQMultiObservable.cxx:356 TQMultiObservable.cxx:357 TQMultiObservable.cxx:358 TQMultiObservable.cxx:359 TQMultiObservable.cxx:360 TQMultiObservable.cxx:361 TQMultiObservable.cxx:362 TQMultiObservable.cxx:363 TQMultiObservable.cxx:364 TQMultiObservable.cxx:365 TQMultiObservable.cxx:366 TQMultiObservable.cxx:367 TQMultiObservable.cxx:368 TQMultiObservable.cxx:369 TQMultiObservable.cxx:370 TQMultiObservable.cxx:371 TQMultiObservable.cxx:372 TQMultiObservable.cxx:373 TQMultiObservable.cxx:374 TQMultiObservable.cxx:375 TQMultiObservable.cxx:376 TQMultiObservable.cxx:377 TQMultiObservable.cxx:378 TQMultiObservable.cxx:379