@@ -184,6 +184,41 @@ void replaceVarNamesWithIndexStyle(std::string &formula, RooArgList const &varLi
184
184
}
185
185
}
186
186
187
+ // //////////////////////////////////////////////////////////////////////////////
188
+ // / From the internal representation, construct a formula by replacing all index place holders
189
+ // / with the names of the variables that are being used to evaluate it, and return it as string.
190
+ std::string reconstructFormula (std::string internalRepr, RooArgList const & args) {
191
+ const auto nArgs = args.size ();
192
+ for (unsigned int i = 0 ; i < nArgs; ++i) {
193
+ const auto & var = args[i];
194
+ std::stringstream regexStr;
195
+ regexStr << " x\\ [" << i << " \\ ]|@" << i;
196
+ std::regex regex (regexStr.str ());
197
+
198
+ std::string replacement = std::string (" [" ) + var.GetName () + " ]" ;
199
+ internalRepr = std::regex_replace (internalRepr, regex, replacement);
200
+ }
201
+
202
+ return internalRepr;
203
+ }
204
+
205
+ // //////////////////////////////////////////////////////////////////////////////
206
+ // / From the internal representation, construct a null-formula by replacing all
207
+ // / index place holders with zeroes, and return it as string
208
+ std::string reconstructNullFormula (std::string internalRepr, RooArgList const & args) {
209
+ const auto nArgs = args.size ();
210
+ for (unsigned int i = 0 ; i < nArgs; ++i) {
211
+ std::stringstream regexStr;
212
+ regexStr << " x\\ [" << i << " \\ ]|@" << i;
213
+ std::regex regex (regexStr.str ());
214
+
215
+ std::string replacement = " 1e-18" ;
216
+ internalRepr = std::regex_replace (internalRepr, regex, replacement);
217
+ }
218
+
219
+ return internalRepr;
220
+ }
221
+
187
222
}
188
223
189
224
// //////////////////////////////////////////////////////////////////////////////
@@ -219,7 +254,6 @@ RooFormula::RooFormula(const RooFormula& other, const char* name) :
219
254
_tFormula = std::move (newTF);
220
255
}
221
256
222
-
223
257
// //////////////////////////////////////////////////////////////////////////////
224
258
// / Process given formula by replacing all ordinal and name references by
225
259
// / `x[i]`, where `i` matches the position of the argument in `_origList`.
@@ -284,7 +318,6 @@ std::string RooFormula::processFormula(std::string formula) const {
284
318
return formula;
285
319
}
286
320
287
-
288
321
// //////////////////////////////////////////////////////////////////////////////
289
322
// / Analyse internal formula to find out which variables are actually in use.
290
323
RooArgList RooFormula::usedVariables () const {
@@ -313,31 +346,11 @@ RooArgList RooFormula::usedVariables() const {
313
346
return useList;
314
347
}
315
348
316
-
317
- // //////////////////////////////////////////////////////////////////////////////
318
- // / From the internal representation, construct a formula by replacing all index place holders
319
- // / with the names of the variables that are being used to evaluate it.
320
- std::string RooFormula::reconstructFormula (std::string internalRepr) const {
321
- for (unsigned int i = 0 ; i < _origList.size (); ++i) {
322
- const auto & var = _origList[i];
323
- std::stringstream regexStr;
324
- regexStr << " x\\ [" << i << " \\ ]|@" << i;
325
- std::regex regex (regexStr.str ());
326
-
327
- std::string replacement = std::string (" [" ) + var.GetName () + " ]" ;
328
- internalRepr = std::regex_replace (internalRepr, regex, replacement);
329
- }
330
-
331
- return internalRepr;
332
- }
333
-
334
-
335
349
void RooFormula::dump () const
336
350
{
337
351
printMultiline (std::cout, 0 );
338
352
}
339
353
340
-
341
354
// //////////////////////////////////////////////////////////////////////////////
342
355
// / Change used variables to those with the same name in given list.
343
356
// / \param[in] newDeps New dependents to replace the old ones.
@@ -372,8 +385,6 @@ bool RooFormula::changeDependents(const RooAbsCollection& newDeps, bool mustRepl
372
385
return errorStat;
373
386
}
374
387
375
-
376
-
377
388
// //////////////////////////////////////////////////////////////////////////////
378
389
// / Evaluate the internal TFormula.
379
390
// /
@@ -433,13 +444,12 @@ void RooFormula::printMultiline(ostream& os, Int_t /*contents*/, bool /*verbose*
433
444
{
434
445
os << indent << " --- RooFormula ---" << std::endl;
435
446
os << indent << " Formula: '" << GetTitle () << " '" << std::endl;
436
- os << indent << " Interpretation: '" << reconstructFormula (GetTitle ()) << " '" << std::endl;
447
+ os << indent << " Interpretation: '" << reconstructFormula (GetTitle (), _origList ) << " '" << std::endl;
437
448
indent.Append (" " );
438
449
os << indent << " Servers: " << _origList << " \n " ;
439
450
os << indent << " In use : " << actualDependents () << std::endl;
440
451
}
441
452
442
-
443
453
// //////////////////////////////////////////////////////////////////////////////
444
454
// / Print value of formula
445
455
@@ -448,7 +458,6 @@ void RooFormula::printValue(ostream& os) const
448
458
os << const_cast <RooFormula*>(this )->eval (nullptr ) ;
449
459
}
450
460
451
-
452
461
// //////////////////////////////////////////////////////////////////////////////
453
462
// / Print name of formula
454
463
@@ -457,7 +466,6 @@ void RooFormula::printName(ostream& os) const
457
466
os << GetName () ;
458
467
}
459
468
460
-
461
469
// //////////////////////////////////////////////////////////////////////////////
462
470
// / Print title of formula
463
471
@@ -466,7 +474,6 @@ void RooFormula::printTitle(ostream& os) const
466
474
os << GetTitle () ;
467
475
}
468
476
469
-
470
477
// //////////////////////////////////////////////////////////////////////////////
471
478
// / Print class name of formula
472
479
@@ -475,7 +482,6 @@ void RooFormula::printClassName(ostream& os) const
475
482
os << ClassName () ;
476
483
}
477
484
478
-
479
485
// //////////////////////////////////////////////////////////////////////////////
480
486
// / Print arguments of formula, i.e. dependents that are actually used
481
487
@@ -488,7 +494,6 @@ void RooFormula::printArgs(ostream& os) const
488
494
os << " ]" ;
489
495
}
490
496
491
-
492
497
// //////////////////////////////////////////////////////////////////////////////
493
498
// / Check that the formula compiles, and also fulfills the assumptions.
494
499
// /
@@ -498,10 +503,10 @@ void RooFormula::installFormulaOrThrow(const std::string& formula) {
498
503
cxcoutD (InputArguments) << " RooFormula '" << GetName () << " ' will be compiled as "
499
504
<< " \n\t " << processedFormula
500
505
<< " \n and used as"
501
- << " \n\t " << reconstructFormula (processedFormula)
506
+ << " \n\t " << reconstructFormula (processedFormula, _origList )
502
507
<< " \n with the parameters " << _origList << std::endl;
503
508
504
- auto theFormula = std::make_unique<TFormula>(GetName (), processedFormula.c_str (), false );
509
+ auto theFormula = std::make_unique<TFormula>(GetName (), processedFormula.c_str (), /* addToGlobList= */ false );
505
510
506
511
if (!theFormula || !theFormula->IsValid ()) {
507
512
std::stringstream msg;
@@ -512,21 +517,19 @@ void RooFormula::installFormulaOrThrow(const std::string& formula) {
512
517
throw std::runtime_error (msg.str ());
513
518
}
514
519
515
- if (theFormula && theFormula->GetNdim () != 1 ) {
516
- // TFormula thinks that we have a multi-dimensional formula, e.g. with variables x,y,z,t.
517
- // We have to check now that this is not the case, as RooFit only uses the syntax x[0], x[1], x[2], ...
518
- bool haveProblem = false ;
519
- std::stringstream msg;
520
- msg << " TFormula interprets the formula " << formula << " as " << theFormula->GetNdim () << " -dimensional with the variable(s) {" ;
521
- for (int i=1 ; i < theFormula->GetNdim (); ++i) {
522
- const TString varName = theFormula->GetVarName (i);
523
- if (varName.BeginsWith (" x[" ) && varName[varName.Length ()-1 ] == ' ]' )
524
- continue ;
525
-
526
- haveProblem = true ;
527
- msg << theFormula->GetVarName (i) << " ," ;
528
- }
529
- if (haveProblem) {
520
+ if (theFormula && theFormula->GetNdim () != 0 ) {
521
+ TFormula nullFormula{" nullFormula" , reconstructNullFormula (processedFormula, _origList).c_str (), /* addToGlobList=*/ false };
522
+ const auto nullDim = nullFormula.GetNdim ();
523
+ if (nullDim != 0 ) {
524
+ // TFormula thinks that we have an n-dimensional formula (n>0), but it shouldn't, as
525
+ // these vars should have been replaced by zeroes in reconstructNullFormula
526
+ // since RooFit only uses the syntax x[0], x[1], x[2], ...
527
+ // This can happen e.g. with variables x,y,z,t that were not supplied in arglist.
528
+ std::stringstream msg;
529
+ msg << " TFormula interprets the formula " << formula << " as " << theFormula->GetNdim ()+nullDim << " -dimensional with undefined variable(s) {" ;
530
+ for (auto i=0 ; i < nullDim; ++i) {
531
+ msg << nullFormula.GetVarName (i) << " ," ;
532
+ }
530
533
msg << " }, which could not be supplied by RooFit."
531
534
<< " \n The formula must be modified, or those variables must be supplied in the list of variables." << std::endl;
532
535
coutF (InputArguments) << msg.str ();
0 commit comments