ATLAS Offline Software
CalibrationDataContainer.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 
7 
8 #include <iostream>
9 #include <cassert>
10 #include <limits>
11 #include <algorithm>
12 #include <cmath>
13 
14 #include "TH1.h"
15 #include "TAxis.h"
16 #include "TF1.h"
17 #include "TVectorT.h"
18 #include "TMatrixT.h"
19 #include "TMatrixDSym.h"
20 #include "TMath.h"
21 #include "TString.h"
22 #include "TObjString.h"
23 
30 
31 // Things that are best hidden from the outside world...
32 namespace {
33 
34  // The value below is added to (subtracted from) the lower (upper) bound of validity
35  // when a variable is restricted to be within its validity range.
36  const double rangeEpsilon = 1.e-5;
37 
38  // array size for boundary specifications
39  const int maxParameters = 10;
40 
41 }
42 
43 
44 
45 
47 // //
48 // CalibrationDataContainer //
49 // //
50 // These container classes represent the basic b-tagging calibration information //
51 // stored in ROOT files. The abstract base class is the CalibrationDataContainer, //
52 // and this "container" is meant to be used for basic jet-by-jet usage. The idea //
53 // is that the container object itself contains sufficient information to determine //
54 // how b-tagging information (mostly efficiencies for given working points, but in //
55 // the case of so-called "continuous tagging" it can be the fractions of jets in //
56 // tag weight bins) is parametrised. The retrieval of the requested information is //
57 // then done by passing a (reference to a) CalibrationDataVariables struct, which is //
58 // a very simple object containing information that can potentially be used for the //
59 // parametrisation. It is then up to the container object to figure out what subset //
60 // of the information then to use in reality. The user may request a fairly wide //
61 // range of information, ranging from mere central values (typically, //
62 // CalibrationDataContainer::getResult() will be used for this) to individual //
63 // contributions to the total systematic uncertainty (using //
64 // CalibrationDataContainer::getUncertainty()). The container class derives from a //
65 // TMap, with keys being strings (TObjString, for technical reasons) ensuring significant //
66 // flexibility as to the specification of uncertainty information. //
67 // //
68 // The underlying information can be presented in two forms: in histogram form (this //
69 // corresponds to the CalibrationDataHistogramContainer derived class), and as a //
70 // functional parametrisation (the CalibrationDataFunctionContainer derived class). //
71 // So far, the CalibrationDataHistogramContainer has been used for the storage of //
72 // data/MC calibration scale factor information, while up to recently the //
73 // CalibrationDataFunctionContainer was used to store MC information. Recently, the //
74 // storage of MC information also moved to the use of histograms, because of biases //
75 // in the functional parametrisations (in addition to the fact that in order to //
76 // derive these parametrisations in the first place, a non-negligible amount of //
77 // manual intervention is required). //
78 // //
79 // CalibrationDataContainer.cxx, (c) ATLAS Detector software //
81 
82 #ifndef __CINT__
84 #endif
85 
86 //________________________________________________________________________________
87 CalibrationDataContainer::CalibrationDataContainer(const char* name) :
88  TMap(), m_objResult(0), m_objSystematics(0), m_restrict(false)
89 {
90  // default constructor
91  SetName(name);
92 }
93 
94 //________________________________________________________________________________
95 CalibrationDataContainer::~CalibrationDataContainer()
96 {
97 }
98 
99 //________________________________________________________________________________
102  UncertaintyResult& result, TObject* obj)
103 {
104  // short-hand for the total systematic uncertainty retrieval.
105  // For "normal" usage (retrieval of central values and total uncertainties), the total systematic
106  // uncertainty object needs to be accessed frequently. In order to avoid nee
107 
108  // cache the pointer to the "systematics" object (to avoid string comparisons)
109  if (!obj) {
110  if (! m_objSystematics) {
111  m_objSystematics = GetValue("systematics");
112  }
114  }
115  return getUncertainty("systematics", x, result, obj);
116 }
117 
118 //________________________________________________________________________________
119 std::vector<std::string>
121 {
122  // Retrieve the list of uncertainties for this calibration.
123  // Note that this is an un-pruned list: it contains also entries that
124  // are not proper uncertainties (e.g. "result", "comment")
125 
126  std::vector<std::string> uncertainties;
127  TIter it(GetTable());
128  while (TPair* pair = (TPair*) it()) {
129  std::string spec(pair->Key()->GetName());
130  uncertainties.push_back(spec);
131  }
132  return uncertainties;
133 }
134 
135 //________________________________________________________________________________
138  std::map<std::string, UncertaintyResult>& all)
139 {
140  // Retrieve all uncertainties for this calibration.
141 
144 
145  // first treat the "result" entry separately
146  double single_result;
147  CalibrationStatus code = getResult(x, single_result);
148  if (code == Analysis::kError) {
149  std::cerr << "in CalibrationDataContainer::getUncertainties(): error retrieving result!" << std::endl;
150  return code;
151  }
152  else if (code != Analysis::kSuccess) mycode = code;
153  result.first = single_result;
154  result.second = 0;
155  all[std::string("result")] = result;
156 
157  // similar for the "statistics" entry
158  code = getStatUncertainty(x, single_result);
159  if (code == Analysis::kError) {
160  std::cerr << "in CalibrationDataContainer::getUncertainties(): error retrieving stat. uncertainty!" << std::endl;
161  return code;
162  }
163  else if (code != Analysis::kSuccess) mycode = code;
164  result.first = single_result;
165  result.second = -single_result;
166  all[std::string("statistics")] = result;
167 
168  // then cycle through the other (systematic) uncertainties
169  TIter it(GetTable());
170  while (TPair* pair = (TPair*) it()) {
171  std::string spec(pair->Key()->GetName());
172  // ignore these specific entries
173  if (spec == "comment" || spec == "result" || spec == "statistics" || spec == "MChadronisation" || spec == "excluded_set") continue;
174  code = getUncertainty(spec, x, result, pair->Value());
175  // we should never be finding any errors
176  if (code == Analysis::kError) {
177  std::cerr << "in CalibrationDataContainer::getUncertainties(): error retrieving named uncertainty "
178  << spec << "!" << std::endl;
179  return code;
180  }
181  // this assumes that non-success codes are likely to be correlated between uncertainty sources
182  else if (code != Analysis::kSuccess) mycode = code;
183  all[spec] = result;
184  }
185  return mycode;
186 }
187 
188 //________________________________________________________________________________
189 std::string
191 {
192  // Retrieve the comments for this calibration (if any)
193 
194  TObject* obj = GetValue("comment");
195  if (! obj) return std::string("");
196  TObjString* s = dynamic_cast<TObjString*>(obj);
197  if (! s ) return std::string("");
198  return std::string(s->GetName());
199 }
200 
201 //________________________________________________________________________________
202 std::string
204 {
205  // Retrieve the hadronisation reference for this calibration (if any)
206  const static std::string null("");
207 
208  TObject* obj = GetValue("MChadronisation");
209  if (! obj) return null;
210  TObjString* s = dynamic_cast<TObjString*>(obj);
211  if (! s ) return null;
212  return std::string(s->GetName());
213 }
214 
215 //________________________________________________________________________________
216 std::string
218 {
219  // Retrieve the (semicolon-separated) set of uncertainties that are recommended for removal from the eigenvector decomposition (if any)
220  const static std::string null("");
221 
222  TObject* obj = GetValue("excluded_set");
223  if (! obj) return null;
224  TObjString* s = dynamic_cast<TObjString*>(obj);
225  if (! s ) return null;
226  return std::string(s->GetName());
227 }
228 
229 //________________________________________________________________________________
230 void
231 CalibrationDataContainer::setUncertainty(const std::string& unc, TObject* obj)
232 {
233  // Insert (or replace) the given object at the position indicated by the given index.
234  //
235  // unc: uncertainty index
236  // obj: object to be entered (needs to inherit from TObject)
237 
238  if (TPair* p = (TPair*) FindObject(unc.c_str())) DeleteEntry(p->Key());
239  Add(new TObjString(unc.c_str()), obj);
240 }
241 
242 //________________________________________________________________________________
243 void
245 {
246  // Specialization of the setUncertainty() method: insert the calibration result
247  //
248  // obj: object to be entered (needs to inherit from TObject)
249 
250  setUncertainty(std::string("result"), obj);
251 }
252 
253 //________________________________________________________________________________
254 void
256 {
257  // Insert (or replace) the comment field. This needs to be handled somewhat
258  // specially as TString itself doesn't inherit from TObject.
259  //
260  // text: comment field (will be converted to TObjString)
261 
262  if (TPair* p = (TPair*) FindObject("comment")) DeleteEntry(p->Key());
263  Add(new TObjString("comment"), new TObjString(text.c_str()));
264 }
265 
266 //________________________________________________________________________________
267 void
269 {
270  // Insert (or replace) the hadronisation reference.
271  //
272  // text: hadronisation reference in string form (will be converted to TObjString)
273 
274  if (TPair* p = (TPair*) FindObject("MChadronisation")) DeleteEntry(p->Key());
275  Add(new TObjString("MChadronisation"), new TObjString(text.c_str()));
276 }
277 
278 //________________________________________________________________________________
279 void
281 {
282  // Insert (or replace) the (semicolon-separated) list of uncertainties that are recommended to be excluded from the eigenvector decomposition
283  //
284  // text: the (semicolon-separated) list of uncertainties in string form (will be converted to TObjString)
285 
286  if (TPair* p = (TPair*) FindObject("excluded_set")) DeleteEntry(p->Key());
287  Add(new TObjString("excluded_set"), new TObjString(text.c_str()));
288 }
289 
290 //________________________________________________________________________________
291 int
293 {
294  // Small utility function collecting the correspondence between axis labels and (integer) variable indices.
295  // In case of an unknown label, a negative number will be returned to flag the issue.
296 
297  if (key == "eta") return kEta;
298  else if (key == "abseta") return kAbsEta;
299  else if (key == "pt") return kPt;
300  else if (key == "tagweight") return kTagWeight;
301  // return value for unknown keywords
302  else return -1;
303 }
304 
305 //________________________________________________________________________________
308 {
309  // Determine which variables are to be used, and insert them in a separate array (which is only used internally).
310  // The return value is used to indicate whether any input co-ordinate was out of bounds; where a distinction
311  // is made between being outside the extrapolation region (kExtrapolatedRange) or merely the calibration region
312  // (kRange).
313  // The "extrapolate" variable is used to flag whether an extrapolation uncertainty applies
314  // (this should anyway occur only for histogram containers).
315  // This is also the place where any computations are being done (e.g. jet pt values are divided by 1000
316  // to convert them from MeV to GeV).
317 
318  // ensure that the variable types have been computed properly
319  if (m_variables.size() == 0) computeVariableTypes();
320 
321  // also keep track of whether the variables are within bounds
323 
324  // std::cout << "computeVariables(): input jet pt: " << x.jetPt << ", eta " << x.jetEta << ", tag weight " << x.jetTagWeight << std::endl;
325 
326  for (unsigned int var = 0; var < m_variables.size(); ++var) {
327  switch (m_variables[var]) {
328  case kPt:
329  // assume that the input values are given in MeV but the performance calibration in GeV!
330  m_vars[var] = x.jetPt * 0.001;
331  break;
332  case kEta:
333  m_vars[var] = x.jetEta;
334  break;
335  case kAbsEta:
336  m_vars[var] = x.jetEta;
337  if (m_vars[var] < 0) m_vars[var] *= -1.0;
338  break;
339  case kTagWeight:
340  m_vars[var] = x.jetTagWeight;
341  }
343  if (status != kExtrapolatedRange) {
345  // std::cout << "computeVariables(): variable " << var << ", value: " << m_vars[var] << ", setting status to " << status << std::endl;
346  }
347  if (m_restrict) m_vars[var] = getLowerBound(m_variables[var], extrapolate) + rangeEpsilon;
348  } else if (m_vars[var] >= getUpperBound(m_variables[var], extrapolate)) {
349  if (status != kExtrapolatedRange) {
351  // std::cout << "computeVariables(): variable " << var << ", value: " << m_vars[var] << ", extrapolate? " << extrapolate
352  // << ", upper bound: " << getUpperBound(m_variables[var],extrapolate)
353  // << " (extrapolation bound: " << getUpperBound(m_variables[var],true) << "), setting status to " << status << std::endl;
354  }
355  if (m_restrict) m_vars[var] = getUpperBound(m_variables[var], extrapolate) - rangeEpsilon;
356  }
357  }
358 
359  // std::cout << "computeVariables(): output variables: " << m_vars[0] << ", " << m_vars[1] << ", " << m_vars[2] << std::endl;
360 
361  return status;
362 }
363 
364 //________________________________________________________________________________
365 double
366 CalibrationDataContainer::getLowerBound(unsigned int vartype, bool extrapolate) const
367 {
368  // Utility function returning the lower validity bound for the given variable type.
369  // The "extrapolate" variable flags whether normal validity bounds are to be used,
370  // or instead those relevant for the extrapolation uncertainty.
371 
372  double minDefault = (vartype == kAbsEta || vartype == kPt) ? 0 : -std::numeric_limits<double>::max();
373  if (! (vartype < m_lowerBounds.size())) return minDefault;
374  return extrapolate ? m_lowerBoundsExtrapolated[vartype] : m_lowerBounds[vartype];
375 }
376 
377 //________________________________________________________________________________
378 double
379 CalibrationDataContainer::getUpperBound(unsigned int vartype, bool extrapolate) const
380 {
381  // Utility function returning the upper validity bound for the given variable type.
382  // The "extrapolate" variable flags whether normal validity bounds are to be used,
383  // or instead those relevant for the extrapolation uncertainty.
384 
385  if (! (vartype < m_lowerBounds.size())) return std::numeric_limits<double>::max();
386  return extrapolate ? m_upperBoundsExtrapolated[vartype] : m_upperBounds[vartype];
387 }
388 
389 //________________________________________________________________________________
390 std::vector<std::pair<double, double> >
392 {
393  // List the validity bounds relevant to this container.
394 
395  // ensure that the variable types have been computed properly
396  if (m_variables.size() == 0) computeVariableTypes();
397 
398  std::vector<std::pair<double, double> > bounds;
399  for (unsigned int t = 0; t < m_lowerBounds.size() && t <= kAbsEta; ++t) {
400  bounds.push_back(std::make_pair(m_lowerBounds[t], m_upperBounds[t]));
401  }
402  return bounds;
403 }
404 
405 
406 //________________________________________________________________________________
407 std::vector<unsigned int>
409 {
410  // List the variable types used for this calibration object.
411  // The meaning of the types is encapsulated by the CalibrationParametrization enum.
412 
413  // ensure that the variable types have been computed properly
414  if (m_variables.size() == 0) computeVariableTypes();
415 
416  return m_variables;
417 }
418 
420 // //
421 // CalibrationDataHistogramContainer //
422 // //
423 /* Begin_Html
424 <p> The CalibrationDataHistogramContainer class inherits from the CalibrationDataContainer
425  abstract class. It covers the cases where the relevant information is presented in
426  binned form.
427 </p>
428 <p> This class allows for the following features:
429 <ul>
430  <li>Access to individual uncertainty contributions, in addition to total (or separate
431  statistical and systematic) uncertainties.</li>
432  <li>Access to correlations between calibration bins. Note that exploiting this
433  requires using the CalibrationDataEigenVariations class.</li>
434  <li>Histogram interpolation (note that this implementation is not complete; however it
435  should work at least for the most common implementation of 2D MC efficiencies. For
436  this case, interpolation has been demonstrated to be more accurate than
437  parametrisations).</li>
438  <li>Use with "continuous tagging" (in which the -binned- tag weight distribution is
439  considered in different kinematic bins) in addition to the more straightforward
440  consideration of the efficiency to pass a given tag weight cut.</li>
441 </ul>
442 </p>
443 End_Html */
444 // //
446 
447 #ifndef __CINT__
449 #endif
450 
451 //________________________________________________________________________________
453  CalibrationDataContainer(name), m_interpolate(false)
454 {
455  // default constructor.
456 
457  // // Reset 'regular' bin ranges to a nonsensical value
458  // for (unsigned int t = 0; t < 3; ++t) {
459  // m_binmin[t] = m_binmax[t] = 0;
460  // m_noExtrapolation[t] = false;
461  // }
462 
463  // Reset the validity bounds (including those for extrapolation uncertainties) to reflect 'no bounds'.
464  // They will be re-determined upon the first computation.
465 
466  m_lowerBounds.clear();
467  m_lowerBounds.resize(maxParameters, -std::numeric_limits<double>::max());
468  m_lowerBounds[kPt] = m_lowerBounds[kAbsEta] = 0;
469  m_upperBounds.clear();
470  m_upperBounds.resize(maxParameters, std::numeric_limits<double>::max());
471 
472  m_lowerBoundsExtrapolated.clear();
473  m_lowerBoundsExtrapolated.resize(maxParameters, -std::numeric_limits<double>::max());
474  m_lowerBoundsExtrapolated[kPt] = m_lowerBounds[kAbsEta] = 0;
475  m_upperBoundsExtrapolated.clear();
476  m_upperBoundsExtrapolated.resize(maxParameters, std::numeric_limits<double>::max());
477 
478  // But by default, switch on the range checking
479  restrictToRange(true);
480 }
481 
482 //________________________________________________________________________________
483 CalibrationDataHistogramContainer::~CalibrationDataHistogramContainer()
484 {
485 }
486 
487 
488 //________________________________________________________________________________
489 void
491 {
492  // Compute the variable types for this container object, using the histogram axis labels.
493  // Valid axis labels can be found in the CalibrationDataContainer::typeFromString() method.
494  // Note that only the "result" histogram is inspected; it is assumed that all
495  // histograms provided use the same binning (a small exception is the "extrapolation"
496  // uncertainty histogram, which may have additional bins beyond the usual validity bounds).
497  //
498  // This function will be called upon first usage, and its results cached internally.
499  // It also calls checkBounds() to determine the validity bounds.
500 
501  // cache pointer to central values histogram
502  if (! m_objResult) m_objResult = GetValue("result");
503 
504  // histograms need a special treatment, as the coordinate titles are not actually stored
505  // with the title itself, but instead moved off to the axis titles...
506  const TH1* hobj = dynamic_cast<const TH1*>(m_objResult);
507  if (not hobj){
508  std::cerr << "in CalibrationDataHistogramContainer::computeVariableTypes(): dynamic_cast failed\n";
509  return;
510  }
511 
512  int dims = hobj->GetDimension();
513  for (int dim = 0; dim < dims; ++dim) {
514  const TAxis* axis = 0;
515  switch (dim) {
516  case 0: axis = hobj->GetXaxis(); break;
517  case 1: axis = hobj->GetYaxis(); break;
518  default: axis = hobj->GetZaxis();
519  }
520  int vartype = typeFromString(axis->GetTitle());
521  if (vartype < 0) {
522  // Only flag the issue but otherwise take no action (assume non-argument use of a semicolon)
523  std::cerr << "in CalibrationDataHistogramContainer::computeVariableTypes(): cannot construct variable type from name "
524  << axis->GetTitle() << std::endl;
525  } else {
526  m_variables.push_back((unsigned int) vartype);
527  }
528  }
529 
530  // After doing this, we should always have a non-null vector!
531  assert(m_variables.size() > 0);
532 
533  // also compute the validity bounds for this calibration object
534  const_cast<CalibrationDataHistogramContainer*>(this)->checkBounds();
535 }
536 
537 //________________________________________________________________________________
540  double& result, TObject* obj, bool extrapolate)
541 {
542  // Retrieve the central value for the given input variables. There are cases where
543  // it may be useful to provide an alternative histogram rather than the original
544  // one; in such cases (notably used with eigenvector variations) it is possible to
545  // provide a pointer to this alternative histogram.
546  //
547  // x: input variables
548  // result: result
549  // obj: pointer to alternative results histogram
550  // extrapolate: set to true if bounds checking is to be carried out to looser
551  // validity bounds as relevant for extrapolation uncertainties
552  if (!obj) {
553  if (! m_objResult) {
554  m_objResult = GetValue("result");
555  }
556  obj = m_objResult;
557  }
558  TH1* hist = dynamic_cast<TH1*>(obj);
559  if (! hist) return Analysis::kError;
560 
561  // select the relevant kinematic variables
563  // find the relevant "global" bin.
564  // Note the limitation: at most three dimensions are supported.
565  // TH1::FindFixBin() will ignore the variables not needed.
566  // Note: FindFixBin() is only available in "recent" ROOT versions (FindBin() is appropriate for older versions)
567  // (otherwise we need to rely on the ResetBit(TH1::kCanRebin) method having been used)
568  if (m_interpolate) {
570  } else {
571  Int_t bin = hist->FindFixBin(m_vars[0], m_vars[1], m_vars[2]);
572  result = hist->GetBinContent(bin);
573  }
574 
575  return status;
576 }
577 
578 // statistical uncertainty retrieval (special since it is stored with the result itself)
579 
580 //________________________________________________________________________________
583  double& result)
584 {
585  // Retrieve the statistical uncertainty for the given input variables.
586  //
587  // x: input variables
588  // result: result
589 
590  if (! m_objResult) {
591  m_objResult = GetValue("result");
592  }
593  TH1* hist = dynamic_cast<TH1*>(m_objResult);
594  if (! hist) {
595  std::cout << " getStatUncertainty error: no (valid) central values object!" << std::endl;
596  return Analysis::kError;
597  }
598 
599  // select the relevant kinematic variables
601  // find the relevant "global" bin.
602  // Note the limitation: at most three dimensions are supported.
603  // TH1::FindFixBin() will ignore the variables not needed.
604  // Note: FindFixBin() is only available in "recent" ROOT versions (FindBin() is appropriate for older versions)
605  // (otherwise we need to rely on the ResetBit(TH1::kCanRebin) method having been used)
606  if (m_interpolate) {
607  // interpolating the uncertainties doesn't seem very sensible..
609  } else {
610  Int_t bin = hist->FindFixBin(m_vars[0], m_vars[1], m_vars[2]);
611  // Int_t bin = findBin(hist, false);
612  result = hist->GetBinError(bin);
613  }
614 
615  return status;
616 }
617 
618 // general uncertainty retrieval
619 
620 //________________________________________________________________________________
624  UncertaintyResult& result, TObject* obj)
625 {
626  // Retrieve the uncertainty for the given input variables.
627  //
628  // unc: keyword indicating requested source of uncertainty. This should
629  // correspond to one of the histograms added explicitly as a systematic
630  // uncertainty or the keyword "statistics" (statistical uncertainties are
631  // accessed differently, see method getStatUncertainty()).
632  // x: input variables
633  // result: result
634  // obj: pointer to alternative or cached histogram
635 
636  if (unc == "statistics") {
637  // treat statistical uncertainties separately (they are stored with the actual result)
638  double res;
640  if (code == Analysis::kError) return code;
641  result.first = res;
642  result.second = -res;
643  return code;
644  }
645 
646  if (!obj) obj = GetValue(unc.c_str());
647  TH1* hist = dynamic_cast<TH1*>(obj);
648  if (! hist) return Analysis::kError;
649 
650  // select the relevant kinematic variables
651  CalibrationStatus status = computeVariables(x, (unc == "extrapolation") );
652 
653  if (m_interpolate) {
655  // symmetrise the uncertainty (as there is no code to interpolate the bin errors)
656  result.second = -result.first;
657  } else {
658  // TH1::FindFixBin() will ignore the variables not needed.
659  // Note: FindFixBin() is only available in "recent" ROOT versions (FindBin() is appropriate for older versions)
660  // (otherwise we need to rely on the ResetBit(TH1::kCanRebin) method having been used)
661  Int_t bin = hist->FindFixBin(m_vars[0], m_vars[1], m_vars[2]);
662  // the "first" and "second" entries are filled with the
663  // "positive" and "negative" uncertainties, respectively.
664  result.first = hist->GetBinContent(bin);
665  result.second = hist->GetBinError(bin);
666  }
667 
668  return status;
669 }
670 
671 //________________________________________________________________________________
672 void
674 {
675  // Determine the bounds of validity for this calibration object. If an "extrapolation"
676  // uncertainty histogram exists, it is used to determine the (typically) looser bounds
677  // of validity appropriate for extrapolation uncertainties.
678 
679  const TH1* hist = dynamic_cast<const TH1*>(m_objResult);
680  if (!hist) {
681  std::cerr << "in CalibrationDataHistogramContainer::checkBounds(): object type does not derive from TH1" << std::endl;
682  return;
683  } else if (hist->GetDimension() != int(m_variables.size())) {
684  std::cerr << "in CalibrationDataHistogramContainer::checkBounds(): given number of variable types ("
685  << m_variables.size() << ") doesn't match histogram dimension ("
686  << hist->GetDimension() << ")!" << std::endl;
687  return;
688  }
689  // if an extrapolation uncertainty histogram was provided, use this to determine a second set of validity bounds
690  const TH1* hExtrapolate = dynamic_cast<const TH1*>(GetValue("extrapolation"));
691  for (unsigned int t = 0; int(t) < hist->GetDimension(); ++t) {
692  const TAxis* axis; const TAxis* axis2 = 0;
693  switch (t) {
694  case 0: axis = hist->GetXaxis(); if (hExtrapolate) axis2 = hExtrapolate->GetXaxis(); break;
695  case 1: axis = hist->GetYaxis(); if (hExtrapolate) axis2 = hExtrapolate->GetYaxis(); break;
696  default: axis = hist->GetZaxis(); if (hExtrapolate) axis2 = hExtrapolate->GetZaxis();
697  }
698 
699  // for (unsigned int t = 0; t < m_variables.size(); ++t) {
700  // if (m_variables[t] > m_upperBounds.size()) {
701  // std::cerr << "in CalibrationDataHistogramContainer::checkBounds(): variable " << t << "type ("
702  // << m_variables[t] << "exceeds maximum type number (" << m_upperBounds.size() << ")!"
703  // << std::endl;
704  // return;
705  // }
706  // }
707  m_upperBounds[m_variables[t]] = axis->GetXmax();
708  m_lowerBounds[m_variables[t]] = axis->GetXmin();
709  m_upperBoundsExtrapolated[m_variables[t]] = (axis2) ? axis2->GetXmax() : m_upperBounds[m_variables[t]];
710  m_lowerBoundsExtrapolated[m_variables[t]] = (axis2) ? axis2->GetXmin() : m_lowerBounds[m_variables[t]];
711  // std::cout << "debug: min = " << m_lowerBounds[m_variables[t]] << ", max = " << m_upperBounds[m_variables[t]]
712  // << ", extrap min = " << m_lowerBoundsExtrapolated[m_variables[t]] << ", extrap max = "
713  // << m_upperBoundsExtrapolated[m_variables[t]] << std::endl;
714  }
715 }
716 
717 //________________________________________________________________________________
718 bool
720 {
721  // Indicate whether the given uncertainty is correlated from bin to bin or not
722  // (note that this function is to be used only for _systematic_ uncertainties)
723  return (m_uncorrelatedSyst.FindObject(unc.c_str()) == 0);
724 }
725 
726 //________________________________________________________________________________
727 void
729 {
730  // Indicate that the given uncertainty is to be treated uncorrelated from bin to bin
731  // (the default is for all systematic uncertainties to be treated as correlated).
732  // This method is not normall intended to be used during physics analysis; this
733  // information is written to and read back from the calibration file.
734 
735  m_uncorrelatedSyst.Add(new TObjString(unc.c_str()));
736 }
737 
738 //________________________________________________________________________________
739 void
741 {
742  // Indicate whether results are to be interpolated between bins or not
743  // (this feature is thought to be useful mostly for MC efficiencies).
744  // The default is not to use any interpolation.
745 
746  m_interpolate = doInterpolate;
747 }
748 
749 //________________________________________________________________________________
750 bool
752 {
753  // Indicate whether histogram interpolation is used or not.
754 
755  return m_interpolate;
756 }
757 
758 //________________________________________________________________________________
759 double
761 {
762  // Small utility function (intended for internal use only) for the retrieval of interpolated results
763 
764  switch (hist->GetDimension()) {
765  case 3:
766  return hist->Interpolate(m_vars[0], m_vars[1], m_vars[2]);
767  case 2:
768  return hist->Interpolate(m_vars[0], m_vars[1]);
769  case 1:
770  default:
771  return hist->Interpolate(m_vars[0]);
772  }
773 }
774 
775 //________________________________________________________________________________
776 double
778 {
779  TAxis* xAxis = hist->GetXaxis();
780  TAxis* yAxis = 0; TAxis* zAxis = 0;
781  Double_t x0,x1,y0,y1;
782 
783  Int_t ndim = hist->GetDimension();
784  if (ndim == 1) {
785  // Code copied from TH1::Interpolate()
786 
787  Int_t xbin = hist->FindBin(m_vars[0]);
788 
789  if(m_vars[0] <= hist->GetBinCenter(1)) {
790  return hist->GetBinError(1);
791  } else if(m_vars[0] >= hist->GetBinCenter(hist->GetNbinsX())) {
792  return hist->GetBinError(hist->GetNbinsX());
793  }
794 
795  if(m_vars[0] <= hist->GetBinCenter(xbin)) {
796  y0 = hist->GetBinError(xbin-1);
797  x0 = hist->GetBinCenter(xbin-1);
798  y1 = hist->GetBinError(xbin);
799  x1 = hist->GetBinCenter(xbin);
800  } else {
801  y0 = hist->GetBinError(xbin);
802  x0 = hist->GetBinCenter(xbin);
803  y1 = hist->GetBinError(xbin+1);
804  x1 = hist->GetBinCenter(xbin+1);
805  }
806  return y0 + (m_vars[0]-x0)*((y1-y0)/(x1-x0));
807 
808  } else if (ndim == 2) {
809 
810  // Code copied from TH2::Interpolate()
811 
812  Double_t f=0;
813  x1 = y1 = 0;
814  Double_t x2=0,y2=0;
815  Double_t dx,dy;
816  yAxis = hist->GetYaxis();
817  Int_t bin_x = xAxis->FindBin(m_vars[0]);
818  Int_t bin_y = yAxis->FindBin(m_vars[1]);
819  if (bin_x<1 || bin_x>hist->GetNbinsX() || bin_y<1 || bin_y>hist->GetNbinsY()) {
820  Error("Interpolate","Cannot interpolate outside histogram domain.");
821  return 0;
822  }
823  // Int_t quadrant = 0; // CCW from UR 1,2,3,4
824  // which quadrant of the bin (bin_P) are we in?
825  dx = xAxis->GetBinUpEdge(bin_x)-m_vars[0];
826  dy = yAxis->GetBinUpEdge(bin_y)-m_vars[1];
827  if (dx<=xAxis->GetBinWidth(bin_x)/2 && dy<=yAxis->GetBinWidth(bin_y)/2) {
828  // quadrant = 1; // upper right
829  x1 = xAxis->GetBinCenter(bin_x);
830  y1 = yAxis->GetBinCenter(bin_y);
831  x2 = xAxis->GetBinCenter(bin_x+1);
832  y2 = yAxis->GetBinCenter(bin_y+1);
833  } else if (dx>xAxis->GetBinWidth(bin_x)/2 && dy<=yAxis->GetBinWidth(bin_y)/2) {
834  // quadrant = 2; // upper left
835  x1 = xAxis->GetBinCenter(bin_x-1);
836  y1 = yAxis->GetBinCenter(bin_y);
837  x2 = xAxis->GetBinCenter(bin_x);
838  y2 = yAxis->GetBinCenter(bin_y+1);
839  } else if (dx>xAxis->GetBinWidth(bin_x)/2 && dy>yAxis->GetBinWidth(bin_y)/2) {
840  // quadrant = 3; // lower left
841  x1 = xAxis->GetBinCenter(bin_x-1);
842  y1 = yAxis->GetBinCenter(bin_y-1);
843  x2 = xAxis->GetBinCenter(bin_x);
844  y2 = yAxis->GetBinCenter(bin_y);
845  } else {
846  // quadrant = 4; // lower right
847  x1 = xAxis->GetBinCenter(bin_x);
848  y1 = yAxis->GetBinCenter(bin_y-1);
849  x2 = xAxis->GetBinCenter(bin_x+1);
850  y2 = yAxis->GetBinCenter(bin_y);
851  }
852  Int_t bin_x1 = xAxis->FindBin(x1);
853  if(bin_x1<1) bin_x1=1;
854  Int_t bin_x2 = xAxis->FindBin(x2);
855  if(bin_x2>hist->GetNbinsX()) bin_x2=hist->GetNbinsX();
856  Int_t bin_y1 = yAxis->FindBin(y1);
857  if(bin_y1<1) bin_y1=1;
858  Int_t bin_y2 = yAxis->FindBin(y2);
859  if(bin_y2>hist->GetNbinsY()) bin_y2=hist->GetNbinsY();
860  Int_t bin_q22 = hist->GetBin(bin_x2,bin_y2);
861  Int_t bin_q12 = hist->GetBin(bin_x1,bin_y2);
862  Int_t bin_q11 = hist->GetBin(bin_x1,bin_y1);
863  Int_t bin_q21 = hist->GetBin(bin_x2,bin_y1);
864  Double_t q11 = hist->GetBinError(bin_q11);
865  Double_t q12 = hist->GetBinError(bin_q12);
866  Double_t q21 = hist->GetBinError(bin_q21);
867  Double_t q22 = hist->GetBinError(bin_q22);
868  Double_t d = 1.0*(x2-x1)*(y2-y1);
869  f = 1.0*q11/d*(x2-m_vars[0])*(y2-m_vars[1])
870  + 1.0*q21/d*(m_vars[0]-x1)*(y2-m_vars[1])
871  + 1.0*q12/d*(x2-m_vars[0])*(m_vars[1]-y1)
872  + 1.0*q22/d*(m_vars[0]-x1)*(m_vars[1]-y1);
873  return f;
874 
875  } else {
876 
877  // Copied from TH3::Interpolate()
878 
879  yAxis = hist->GetYaxis();
880  zAxis = hist->GetZaxis();
881 
882  Int_t ubx = xAxis->FindBin(m_vars[0]);
883  if ( m_vars[0] < xAxis->GetBinCenter(ubx) ) ubx -= 1;
884  Int_t obx = ubx + 1;
885 
886  Int_t uby = yAxis->FindBin(m_vars[1]);
887  if ( m_vars[1] < yAxis->GetBinCenter(uby) ) uby -= 1;
888  Int_t oby = uby + 1;
889 
890  Int_t ubz = zAxis->FindBin(m_vars[2]);
891  if ( m_vars[2] < zAxis->GetBinCenter(ubz) ) ubz -= 1;
892  Int_t obz = ubz + 1;
893 
894 
895  // if ( IsBinUnderflow(GetBin(ubx, uby, ubz)) ||
896  // IsBinOverflow (GetBin(obx, oby, obz)) ) {
897  if (ubx <=0 || uby <=0 || ubz <= 0 ||
898  obx > xAxis->GetNbins() || oby > yAxis->GetNbins() || obz > zAxis->GetNbins() ) {
899  }
900 
901  Double_t xw = xAxis->GetBinCenter(obx) - xAxis->GetBinCenter(ubx);
902  Double_t yw = yAxis->GetBinCenter(oby) - yAxis->GetBinCenter(uby);
903  Double_t zw = zAxis->GetBinCenter(obz) - zAxis->GetBinCenter(ubz);
904 
905  Double_t xd = (m_vars[0] - xAxis->GetBinCenter(ubx)) / xw;
906  Double_t yd = (m_vars[1] - yAxis->GetBinCenter(uby)) / yw;
907  Double_t zd = (m_vars[2] - zAxis->GetBinCenter(ubz)) / zw;
908 
909 
910  Double_t v[] = { hist->GetBinError( ubx, uby, ubz ), hist->GetBinError( ubx, uby, obz ),
911  hist->GetBinError( ubx, oby, ubz ), hist->GetBinError( ubx, oby, obz ),
912  hist->GetBinError( obx, uby, ubz ), hist->GetBinError( obx, uby, obz ),
913  hist->GetBinError( obx, oby, ubz ), hist->GetBinError( obx, oby, obz ) };
914 
915 
916  Double_t i1 = v[0] * (1 - zd) + v[1] * zd;
917  Double_t i2 = v[2] * (1 - zd) + v[3] * zd;
918  Double_t j1 = v[4] * (1 - zd) + v[5] * zd;
919  Double_t j2 = v[6] * (1 - zd) + v[7] * zd;
920 
921 
922  Double_t w1 = i1 * (1 - yd) + i2 * yd;
923  Double_t w2 = j1 * (1 - yd) + j2 * yd;
924 
925 
926  Double_t result = w1 * (1 - xd) + w2 * xd;
927 
928  return result;
929  };
930 }
931 
932 
933 //________________________________________________________________________________
934 int
936 {
937  // Test whether this calibration object is one for "continuous" calibration
938  // (this has some subtle consequences for the treatment of bin-to-bin correlations).
939  // The return value will be -1 in case this is not a "continuous" calibration object,
940  // and the axis number (0 for X, 1 for Y, 2 for Z) otherwise.
941 
942  // Ensure that the variable types have been computed at this point
943  if (m_variables.size() == 0) computeVariableTypes();
944 
945  for (unsigned int type = 0; type < m_variables.size(); ++type)
946  if (m_variables[type] == kTagWeight) return int(type);
947  return -1;
948 }
949 
950 //________________________________________________________________________________
951 std::vector<double>
953 {
954  // Retrieve the bin boundaries for the specified variable type (which should be a CalibrationParametrization enum).
955  // An empty vector will be returned if the specified variable is not actually used.
956 
957  // Ensure that the variable types have been computed at this point
958  if (m_variables.size() == 0) computeVariableTypes();
959 
960  // Check whether the variable type is actually being used
961  std::vector<double> boundaries;
962  if (std::find(m_variables.begin(), m_variables.end(), vartype) == m_variables.end()) return boundaries;
963 
964  // use cached information if available
965  std::map<unsigned int, std::vector<double> >::iterator it = m_binBoundaries.find(vartype);
966  if (it != m_binBoundaries.end()) return it->second;
967 
968  // Retrieve the appropriate histogram axis
969  if (! m_objResult) m_objResult = GetValue("result");
970  const TH1* hobj = dynamic_cast<const TH1*>(m_objResult);
971  const TAxis* axis = 0;
972  if (m_variables[0] == vartype) axis = hobj->GetXaxis();
973  else if (m_variables[1] == vartype) axis = hobj->GetYaxis();
974  else axis = hobj->GetZaxis();
975 
976  // Retrieve the actual bin boundaries
977  const TArrayD* bins = axis->GetXbins(); int nb = bins->GetSize();
978  for (int b = 0; b < nb; ++b) boundaries.push_back(bins->At(b));
979 
980  m_binBoundaries[vartype] = boundaries;
981  return boundaries;
982 }
983 
984 //________________________________________________________________________________
985 int
987 {
988  TObject* obj = GetValue("ReducedSets");
989  if (! obj) return -1;
990  TVectorT<double>* v = dynamic_cast<TVectorT<double>* >(obj);
991  if (! (v && v->GetNoElements() > int(choice)) ) return -1;
992  return int((*v)[choice]);
993 }
994 
996 // //
997 // CalibrationDataMappedHistogramContainer //
998 // //
999 // The CalibrationDataMappedHistogramContainer class inherits from the //
1000 // CalibrationDataHistogramContainer class. It covers the special case (for at least two //
1001 // dimensions) where the calibration is not done in a rectangular grid as would be implied //
1002 // by the use of a TH2 or TH3. Instead, the class implements a mapping from a set of //
1003 // general bins to bins on a given TH2 or TH3 axis. This generality implies that this class //
1004 // in principle could be used also for the storage of higher-dimensional results. The only //
1005 // assumptions made are that //
1006 // - all bins have the same dimensions //
1007 // - and the bins cover the 'mapped' dimensions completely, without any overlaps //
1008 // Necessarily, the added flexibility makes access slower (even if caching of the mapped //
1009 // bin is used). //
1010 // //
1012 
1013 #ifndef __CINT__
1015 #endif
1016 
1017 //________________________________________________________________________________
1019  CalibrationDataHistogramContainer(name), m_beginMapped(0),m_lastBin(0)
1020 {
1021 }
1022 
1023 //________________________________________________________________________________
1024 CalibrationDataMappedHistogramContainer::~CalibrationDataMappedHistogramContainer()
1025 {
1026 }
1027 
1028 //________________________________________________________________________________
1029 void
1031 {
1032  // Compute the variable types for this container object.
1033  // The computation differs from that used for the parent CalibrationDataHistogramContainer
1034  // class, as also the 'mapped' variables (the variables that are mapped onto a single histogram
1035  // axis) need to be accounted for properly. This is handled as a special case.
1036 
1037  // cache pointer to central values histogram
1038  if (! m_objResult) m_objResult = GetValue("result");
1039 
1040  // histograms need a special treatment, as the coordinate titles are not actually stored
1041  // with the title itself, but instead moved off to the axis titles...
1042  const TH1* hobj = dynamic_cast<const TH1*>(m_objResult);
1043  if (not hobj){
1044  std::cerr << "in CalibrationDataMappedHistogramContainer::computeVariableTypes(): dynamic cast failed\n";
1045  return;
1046  }
1047 
1048  int dims = hobj->GetDimension();
1049  for (int dim = 0; dim < dims; ++dim) {
1050  const TAxis* axis = 0;
1051  switch (dim) {
1052  case 0: axis = hobj->GetXaxis(); break;
1053  case 1: axis = hobj->GetYaxis(); break;
1054  default: axis = hobj->GetZaxis();
1055  }
1056  std::string var(axis->GetTitle());
1057  if (var == "mapped") {
1058  // Special case: mapped variables, so make sure to specify the original variables (not the mapped ones).
1059  // Note that the code here assumes that the mapping is identical for all objects..
1060  for (unsigned int m = 0; m < m_mapped.size(); ++m) {
1061  int vartype = typeFromString(m_mapped[m]);
1062  // this check should never fail; therefore, bail out if this does happen
1063  assert (! (vartype < 0));
1064  m_variables.push_back((unsigned int)vartype);
1065  }
1066  // In this case, also flag _where_ in the resulting list of variables the mapping starts
1067  m_beginMapped = dim;
1068  } else {
1069  int vartype = typeFromString(var);
1070  if (vartype < 0) {
1071  // Only flag the issue but otherwise take no action (assume non-argument use of a semicolon)
1072  std::cerr << "in CalibrationDataMappedHistogramContainer::computeVariableTypes(): cannot construct variable type from name "
1073  << var << std::endl;
1074  } else {
1075  m_variables.push_back((unsigned int)vartype);
1076  }
1077  }
1078  }
1079 
1080  // After doing this, we should always have a non-null vector!
1081  assert(m_variables.size() > 0);
1082 
1083  // Also compute the validity bounds for this calibration object
1085 }
1086 
1087 
1088 //________________________________________________________________________________
1089 void
1091 {
1092  // Check the bounds of validity for this calibration object.
1093  // See the CalibrationDataHistogramContainer::checkBounds() method. The difference is
1094  // that the 'mapped' dimensions need to be handled separately (this is carried out by
1095  // looping over the mapped bins and inspecting each bin's validity bounds individually).
1096  // Note that extrapolation uncertainties are not covered at this point.
1097 
1098  const TH1* hist = dynamic_cast<const TH1*>(m_objResult);
1099  if (!hist) {
1100  std::cerr << "in CalibrationDataHistogramContainer::checkBounds(): object type does not derive from TH1" << std::endl;
1101  return;
1102  } else if (hist->GetDimension() + int(m_mapped.size()) - 1 != int(m_variables.size())) {
1103  std::cerr << "in CalibrationDataMappedHistogramContainer::checkBounds(): given number of variable types ("
1104  << m_variables.size() << ") doesn't match (mapped) histogram dimension ("
1105  << hist->GetDimension() + m_mapped.size() - 1 << ")!" << std::endl;
1106  return;
1107  }
1108 
1109  // Carry out the only cross-check that's possible for the binning: check that the dimensionality
1110  // for all bins matches the number of variables specified for the mapping
1111  for (unsigned int bin = 0; bin < m_bins.size(); ++bin)
1112  assert(m_bins[bin].getDimension() == m_mapped.size());
1113 
1114  for (unsigned int t = 0, t2 = 0; int(t) < hist->GetDimension(); ++t) {
1115  const TAxis* axis = 0;
1116  switch (t) {
1117  case 0: axis = hist->GetXaxis(); break;
1118  case 1: axis = hist->GetYaxis(); break;
1119  default: axis = hist->GetZaxis();
1120  }
1121 
1122  // Special case for the mapped dimension: here the only thing that can be done is to
1123  // cycle through all Bins and inspect the boundaries of each bin manually.
1124  if (t == m_beginMapped) {
1125  for (unsigned int mapped = 0; mapped < m_mapped.size(); ++mapped) {
1126  for (unsigned int bin = 0; bin < m_bins.size(); ++bin) {
1127  double amax = m_bins[bin].getUpperBound(mapped), amin = m_bins[bin].getLowerBound(mapped);
1128  if (bin == 0 || amax > m_upperBounds[m_variables[t2]]) m_upperBounds[m_variables[t2]] = amax;
1129  if (bin == 0 || amin < m_lowerBounds[m_variables[t2]]) m_lowerBounds[m_variables[t2]] = amin;
1130  }
1131  ++t2;
1132  }
1133  } else {
1134  // for (unsigned int t = 0; t < m_variables.size(); ++t) {
1135  // if (m_variables[t] > m_upperBounds.size()) {
1136  // std::cerr << "in CalibrationDataHistogramContainer::checkBounds(): variable " << t << "type ("
1137  // << m_variables[t] << "exceeds maximum type number (" << m_upperBounds.size() << ")!"
1138  // << std::endl;
1139  // return;
1140  // }
1141  // }
1142  double amax = axis->GetXmax(), amin = axis->GetXmin();
1143  if (amax < m_upperBounds[m_variables[t2]]) m_upperBounds[m_variables[t2]] = amax;
1144  if (amin > m_lowerBounds[m_variables[t2]]) m_lowerBounds[m_variables[t2]] = amin;
1145  ++t2;
1146  }
1147  }
1148 }
1149 
1150 //________________________________________________________________________________
1153  double& result, TObject* obj, bool /* extrapolate */)
1154 {
1155  // Retrieve the central value for the given input variables. There are cases where
1156  // it may be useful to provide an alternative histogram rather than the original
1157  // one; in such cases (notably used with eigenvector variations) it is possible to
1158  // provide a pointer to this alternative histogram.
1159  // The method here differs from CalibrationDataHistogramContainer::getResult()
1160  // since histogram interpolation does not make sense for mapped bins.
1161  //
1162  // x: input variables
1163  // result: result
1164  // obj: pointer to alternative results histogram
1165 
1166  if (!obj) {
1167  if (! m_objResult) {
1168  m_objResult = GetValue("result");
1169  }
1170  obj = m_objResult;
1171  }
1172  TH1* hist = dynamic_cast<TH1*>(obj);
1173  if (! hist) return Analysis::kError;
1174 
1175  // select the relevant kinematic variables
1177  // find the relevant "global" bin and retrieve its contents
1178  result = hist->GetBinContent(findBin());
1179 
1180  return status;
1181 }
1182 
1183 //________________________________________________________________________________
1186  double& result)
1187 {
1188  // Retrieve the statistical uncertainty for the given input variables.
1189  //
1190  // x: input variables
1191  // result: result
1192 
1193  if (! m_objResult) {
1194  m_objResult = GetValue("result");
1195  }
1196  TH1* hist = dynamic_cast<TH1*>(m_objResult);
1197  if (! hist) return Analysis::kError;
1198 
1199  // select the relevant kinematic variables
1201  // find the relevant "global" bin and retrieve its contents
1202  result = hist->GetBinError(findBin());
1203 
1204  return status;
1205 }
1206 
1207 //________________________________________________________________________________
1210  const CalibrationDataVariables& x,
1211  UncertaintyResult& result, TObject* obj)
1212 {
1213  // Retrieve the uncertainty for the given input variables.
1214  //
1215  // unc: keyword indicating requested source of uncertainty. This should
1216  // correspond to one of the histograms added explicitly as a systematic
1217  // uncertainty or the keyword "statistics" (statistical uncertainties are
1218  // accessed differently, see method getStatUncertainty()).
1219  // x: input variables
1220  // result: result
1221  // obj: pointer to alternative or cached histogram
1222 
1223  // treat statistical uncertainties separately (they are stored with the actual result)
1224  if (unc == "statistics") {
1225  double res;
1227  if (code == Analysis::kError) return code;
1228  result.first = res;
1229  result.second = -res;
1230  return code;
1231  }
1232 
1233  if (!obj) obj = GetValue(unc.c_str());
1234  TH1* hist = dynamic_cast<TH1*>(obj);
1235  if (! hist) return Analysis::kError;
1236 
1237  // select the relevant kinematic variables
1239  // find the relevant "global" bin and retrieve its contents
1240  Int_t bin = findBin();
1241  result.first = hist->GetBinError(bin);
1242  result.second = hist->GetBinError(bin);
1243 
1244  return status;
1245 }
1246 
1247 //________________________________________________________________________________
1248 int
1250 {
1251  // Test whether this calibration object is one for "continuous" calibration
1252  // (this has some subtle consequences for the treatment of bin-to-bin correlations).
1253  // The return value will be -1 in case this is not a "continuous" calibration object,
1254  // and the axis number (0 for X, 1 for Y, 2 for Z) otherwise.
1255 
1256  for (unsigned int type = 0; type < m_variables.size(); ++type)
1257  if (m_variables[type] == kTagWeight) {
1258  int hist_type = int(type);
1259  return (hist_type > int(m_beginMapped)) ? hist_type - m_mapped.size() + 1 : hist_type;
1260  }
1261  return -1;
1262 }
1263 
1264 //________________________________________________________________________________
1265 void
1267 {
1268  // Set (by hand) the variables that will be mapped onto a single histogram axis
1269 
1270  m_mapped = variables;
1271 }
1272 
1273 //________________________________________________________________________________
1274 std::vector<std::string>
1276 {
1277  // List which variables get mapped onto a single histogram axis
1278 
1279  return m_mapped;
1280 }
1281 
1282 //________________________________________________________________________________
1283 unsigned int
1285 {
1286  // Add a bin to the present list
1287  // Note the absence of a -1 in the return value: this is because ROOT's histogram axes start counting from 1
1288 
1289  m_bins.push_back(bin);
1290  return m_bins.size();
1291 }
1292 
1293 //________________________________________________________________________________
1294 unsigned int
1296 {
1297  // Return the number of mapped bins
1298  // Note the absence of a -1 in the return value: this is because ROOT's histogram axes start counting from 1
1299 
1300  return m_bins.size();
1301 }
1302 
1303 //________________________________________________________________________________
1304 Int_t
1306 {
1307  // Find the mapped bin corresponding to the variables used for the mapping
1308 
1309  if (m_bins[m_lastBin].contains(x)) return m_lastBin + 1; // First check quickly whether the last bin (cached) matches
1310 
1311  // Search the whole array for a match
1312  for (unsigned int bin = 0; bin < m_bins.size(); ++bin)
1313  if (m_bins[bin].contains(x)) {
1314  m_lastBin = bin;
1315  return m_lastBin + 1;
1316  }
1317  std::cerr << "CalibrationDataMappedHistogramContainer::findMappedBin(): unable to find bin for mapping variables:";
1318  for (unsigned int d = 0; d < m_mapped.size(); ++d) std::cerr << "\t" << x[d];
1319  std::cerr << std::endl;
1320  // -1 means invalid..
1321  return -1;
1322 }
1323 
1324 //________________________________________________________________________________
1325 Int_t
1327 {
1328  // Find the bin corresponding to the computed variables (the computation is assumed to have just
1329  // taken place and resulted in the m_vars array having been filled appropriately)
1330 
1331  Int_t mapped[3] = {0};
1332  const TH1* hist = dynamic_cast<const TH1*>(m_objResult);
1333  if (not hist){
1334  std::cerr << "CalibrationDataMappedHistogramContainer::findBin(): dynamic cast failed\n";
1335  return 0;
1336  }
1337  Int_t ndim = hist->GetDimension();
1338  // Push the mapped variables onto an array.
1339  // Since we derive from TH1 this need never be more than 3 elements long.
1340  for (unsigned int dim = 0; dim < (unsigned int) ndim; ++dim) {
1341  if (dim == m_beginMapped) {
1342  if ((mapped[dim] = findMappedBin(&(m_vars[dim]))) < 0) return -1;
1343  } else {
1344  const TAxis* axis = 0;
1345  switch (dim) {
1346  case 0: axis = hist->GetXaxis(); break;
1347  case 1: axis = hist->GetYaxis(); break;
1348  default: axis = hist->GetZaxis();
1349  }
1350  mapped[dim] = axis->FindFixBin((dim < m_beginMapped) ? m_vars[dim] : m_vars[dim+m_mapped.size()-1]);
1351  }
1352  }
1353  return hist->GetBin(mapped[0], mapped[1], mapped[2]);
1354 }
1355 
1356 //________________________________________________________________________________
1357 std::vector<double>
1359 {
1360  // Retrieve the bin boundaries for the specified variable type (which should be a CalibrationParametrization enum).
1361  // An empty vector will be returned if the specified variable is not actually used.
1362 
1363  // Ensure that the variable types have been computed at this point
1364  if (m_variables.size() == 0) computeVariableTypes();
1365 
1366  // use cached information if available
1367  std::map<unsigned int, std::vector<double> >::iterator it = m_binBoundaries.find(vartype);
1368  if (it != m_binBoundaries.end()) return it->second;
1369 
1370  // Check whether the variable type is actually being used
1371  std::vector<double> boundaries;
1372  int var = -1;
1373  for (unsigned int v = 0; v < m_variables.size(); ++v)
1374  if (m_variables[v] == vartype) var = (int) v;
1375  if (var == -1) return boundaries;
1376 
1377  // Retrieve the appropriate histogram axis
1378  if (! m_objResult) m_objResult = GetValue("result");
1379  const TH1* hobj = dynamic_cast<const TH1*>(m_objResult);
1380 
1381  if (var >= int(m_beginMapped) && var < int(m_beginMapped + m_mapped.size())) {
1382  // Special case of a mapped variable. In this case, test all Bins for their boundaries
1383  unsigned int mapped = var - m_beginMapped;
1384  for (unsigned int bin = 0; bin < m_bins.size(); ++bin) {
1385  double binBoundaries[2];
1386  binBoundaries[0] = m_bins[bin].getLowerBound(mapped);
1387  binBoundaries[1] = m_bins[bin].getUpperBound(mapped);
1388  // Insert the bin boundaries, if not already present (the test is whether the relative difference
1389  // is smaller than 1e-8)
1390  if (boundaries.size() == 0) {
1391  boundaries.push_back(binBoundaries[0]); boundaries.push_back(binBoundaries[1]);
1392  } else {
1393  for (unsigned int ib = 0; ib < 2; ++ib) {
1394  double newvalue = binBoundaries[ib];
1395  bool done = false;
1396  for (std::vector<double>::iterator it = boundaries.begin(); it != boundaries.end(); ++it) {
1397  if (isNearlyEqual(newvalue, *it)) {
1398  // consider this value to have been inserted already
1399  done = true; break;
1400  } else if (newvalue < *it) {
1401  // the interesting case: insert the new value
1402  boundaries.insert(it, newvalue);
1403  done = true; break;
1404  }
1405  }
1406  // last case: new value is larger than any of the values in the array so far
1407  if (! done) boundaries.push_back(newvalue);
1408  }
1409  }
1410  }
1411  } else {
1412  // Normal case:
1413  unsigned int dim = (var < int(m_beginMapped)) ? var : var + 1 - m_mapped.size();
1414  const TAxis* axis = 0;
1415  switch (dim) {
1416  case 0: axis = hobj->GetXaxis(); break;
1417  case 1: axis = hobj->GetYaxis(); break;
1418  default: axis = hobj->GetZaxis();
1419  }
1420  // Retrieve the actual bin boundaries
1421  const TArrayD* bins = axis->GetXbins(); int nb = bins->GetSize();
1422  for (int b = 0; b < nb; ++b) boundaries.push_back(bins->At(b));
1423  }
1424 
1425  m_binBoundaries[vartype] = boundaries;
1426  return boundaries;
1427 }
1428 
1429 // Bin helper class methods
1430 
1432 // //
1433 // CalibrationDataMappedHistogramContainer::Bin //
1434 // //
1435 // This is a small nested class collecting 'mapped' bin information. Its purpose is mostly //
1436 // to store binning information in a structured way. The only relevant event-level method //
1437 // is the contains() method. //
1438 // //
1440 
1441 #ifndef __CINT__
1442 ClassImp(CalibrationDataMappedHistogramContainer::Bin)
1443 #endif
1444 
1445 //________________________________________________________________________________
1447  m_dimension(0), m_low(0), m_up(0)
1448 {
1449  // Default constructor (for persistency)
1450 }
1451 
1452 //________________________________________________________________________________
1453 CalibrationDataMappedHistogramContainer::Bin::Bin(unsigned int dimension, const double* low, const double* up):
1454  m_dimension(dimension)
1455 {
1456  // Normal constructor, containing a full specification of the bin boundaries
1457 
1458  m_up = new double[dimension];
1459  m_low = new double[dimension];
1460  for (unsigned int dim = 0; dim < dimension; ++dim) {
1461  m_up[dim] = up[dim];
1462  m_low[dim] = low[dim];
1463  }
1464 }
1465 
1466 //________________________________________________________________________________
1468  m_dimension(other.m_dimension)
1469 {
1470  m_up = new double[m_dimension];
1471  m_low = new double[m_dimension];
1472  for (unsigned int dim = 0; dim < m_dimension; ++dim) {
1473  m_up[dim] = other.m_up[dim];
1474  m_low[dim] = other.m_low[dim];
1475  }
1476 }
1477 
1478 //________________________________________________________________________________
1479 CalibrationDataMappedHistogramContainer::Bin&
1481 {
1482  if (this != &other) {
1483  m_dimension = other.m_dimension;
1484  delete[] m_up;
1485  delete[] m_low;
1486  m_up = new double[m_dimension];
1487  m_low = new double[m_dimension];
1488  for (unsigned int dim = 0; dim < m_dimension; ++dim) {
1489  m_up[dim] = other.m_up[dim];
1490  m_low[dim] = other.m_low[dim];
1491  }
1492  }
1493  return *this;
1494 }
1495 
1496 //________________________________________________________________________________
1498 {
1499  delete[] m_up;
1500  delete[] m_low;
1501 }
1502 
1503 //________________________________________________________________________________
1504 bool
1506 {
1507  // Determine whether the given set of variables is within the bin boundaries.
1508 
1509  for (unsigned int dim = 0; dim < m_dimension; ++dim)
1510  if (x[dim] < m_low[dim] || x[dim] > m_up[dim]) return false;
1511  return true;
1512 }
1513 
1514 //________________________________________________________________________________
1515 double
1517 {
1518  // Return the upper bound for the specified dimension
1519  return m_up[dim];
1520 }
1521 
1522 //________________________________________________________________________________
1523 double
1525 {
1526  // Return the lower bound for the specified dimension
1527  return m_low[dim];
1528 }
1529 
1531 // //
1532 // CalibrationDataFunctionContainer //
1533 // //
1534 // The CalibrationDataFunctionContainer class inherits from the CalibrationDataContainer //
1535 // abstract class. It covers the cases where the relevant information is presented in //
1536 // parametrised form. //
1537 // //
1539 
1540 #ifndef __CINT__
1542 #endif
1543 
1544 //________________________________________________________________________________
1546  CalibrationDataContainer(name), m_objStatistics(0)
1547 {
1548  // Default constructor
1549 
1550  // Reset the validity bounds to reflect 'no bounds'.
1551  m_lowerBounds.clear();
1552  m_lowerBounds.resize(maxParameters, -std::numeric_limits<double>::max());
1553  m_lowerBounds[kPt] = m_lowerBounds[kAbsEta] = 0;
1554  m_upperBounds.clear();
1555  m_upperBounds.resize(maxParameters, std::numeric_limits<double>::max());
1556  // and do the same for the validity bounds associated with extrapolation uncertainties
1557  // (this should anyway not be relevant for function containers)
1558  m_lowerBoundsExtrapolated.clear();
1559  m_lowerBoundsExtrapolated.resize(maxParameters, -std::numeric_limits<double>::max());
1560  m_lowerBoundsExtrapolated[kPt] = m_lowerBoundsExtrapolated[kAbsEta] = 0;
1561  m_upperBoundsExtrapolated.clear();
1562  m_upperBoundsExtrapolated.resize(maxParameters, std::numeric_limits<double>::max());
1563 }
1564 
1565 //________________________________________________________________________________
1566 CalibrationDataFunctionContainer::~CalibrationDataFunctionContainer()
1567 {
1568 }
1569 
1570 //________________________________________________________________________________
1571 void
1573 {
1574  // Determine which variable types are to be used.
1575  // This needs to be done only once per calibration object, as the results will be
1576  // cached (even if not persistified).
1577  // This method should normally only be used internally.
1578 
1579  if (! m_objResult) m_objResult = GetValue("result");
1580 
1581  std::string title(m_objResult->GetTitle());
1582  std::string::size_type pos = title.find(";");
1583  while (pos != std::string::npos && pos != title.size()) {
1584  title = title.substr(pos+1);
1585  pos = title.find(";");
1586  std::string var = title.substr(0, pos);
1587  int vartype = typeFromString(var);
1588  if (vartype < 0) {
1589  // Only flag the issue but otherwise take no action (assume non-argument use of a semicolon)
1590  std::cerr << "in CalibrationDataFunctionContainer::computeVariableTypes(): cannot construct variable type from name "
1591  << var << std::endl;
1592  } else {
1593  m_variables.push_back((unsigned int)vartype);
1594  }
1595  }
1596 
1597  // After doing this, we should always have a non-null vector!
1598  assert(m_variables.size() > 0);
1599 }
1600 
1601 // result retrieval
1602 
1603 //________________________________________________________________________________
1606  double& result, TObject* obj, bool /* extrapolate */)
1607 {
1608  // Retrieve the central value for the given input variables. There are cases where
1609  // it may be useful to provide an alternative parametrisation rather than the original
1610  // one; in such cases it is possible to provide a pointer to this alternative parametrisation.
1611  //
1612  // x: input variables
1613  // result: result
1614  // obj: pointer to alternative results histogram
1615  if (!obj) {
1616  if (! m_objResult) m_objResult = GetValue("result");
1617  obj = m_objResult;
1618  }
1619  TF1* func = dynamic_cast<TF1*>(obj);
1620  if (! func) return Analysis::kError;
1621 
1622  // select the relevant kinematic variables
1624  result = func->EvalPar(m_vars);
1625 
1626  return status;
1627 }
1628 
1629 // general uncertainty retrieval
1630 
1631 //________________________________________________________________________________
1634  const CalibrationDataVariables& x,
1635  UncertaintyResult& result, TObject* obj)
1636 {
1637  // Retrieve the uncertainty for the given input variables.
1638  // Note that the uncertainties returned will be symmetrised.
1639  //
1640  // unc: keyword indicating requested source of uncertainty. This should
1641  // correspond to one of the parametrisations added explicitly as a systematic
1642  // uncertainty or the keyword "statistics" (statistical uncertainties are
1643  // accessed differently, see method getStatUncertainty()).
1644  // x: input variables
1645  // result: result
1646  // obj: pointer to alternative or cached parametrisation
1647  if (unc == "statistics") {
1648  // treat statistical uncertainties separately (they are stored with the actual result)
1649  double res;
1651  if (code == Analysis::kError) return code;
1652  result.first = res;
1653  result.second = -res;
1654  return code;
1655  }
1656 
1657  if (!obj) obj = GetValue(unc.c_str());
1658  TF1* func = dynamic_cast<TF1*>(obj);
1659  if (! func) return Analysis::kError;
1660 
1661  // select the relevant kinematic variables
1663 
1664  // the "first" and "second" entries are filled with the
1665  // "positive" and "negative" uncertainties, respectively.
1666  // Note: no "negative" uncertainties implemented as yet!
1667  result.first = func->EvalPar(m_vars);
1668  result.second = -result.first;
1669 
1670  return status;
1671 }
1672 
1673 //________________________________________________________________________________
1676  double& result)
1677 {
1678  // Retrieve the statistical uncertainty for the given input variables.
1679  // The model that is assumed here is that statistical uncertainties follow from
1680  // a fit of the function to other information, and that the parameter covariance matrix
1681  // resulting from the fit are stored in a TMatrixDSym object identified by the
1682  // keyword "statistics". The effect of a change of fit parameters is then used to
1683  // evaluate the change in function value at the given co-ordinates.
1684  //
1685  // x: input variables
1686  // result: result
1687 
1688  if (! m_objResult) m_objResult = GetValue("result"); // ensure that the requested objects exist
1689  TF1* func = dynamic_cast<TF1*>(m_objResult);
1690  if (! func) {
1691  // std::cerr << "... unable to retrieve the result" << std::endl;
1692  return Analysis::kError;
1693  }
1694 
1695  if (! m_objStatistics) m_objStatistics = GetValue("statistics");
1696  // m_objStatistics->Dump();
1697  TMatrixTSym<double>* cov = dynamic_cast<TMatrixTSym<double>*>(m_objStatistics);
1698  if (! cov) {
1699  // std::cerr << "... unable to retrieve the covariance matrix" << std::endl;
1700  return Analysis::kError;
1701  }
1702 
1703  // select the relevant kinematic variables
1705 
1706  // use a large value for "eps": this multiplies the uncertainties that
1707  // are expected to be associated with the parameters. Choosing a large
1708  // value expresses the fact that we are not primarily interested in the
1709  // parabolic behaviour at the minimum
1710  // const Double_t eps = 1.0;
1711  // test: set to 0.5
1712  const Double_t eps = 0.5;
1713 
1714  int npar = func->GetNpar();
1715  if (npar == 0) {
1716  result = 0.;
1717  return status;
1718  }
1719 
1720  TMatrixT<double> gradients(npar,1);
1721  for (int ipar = 0; ipar < npar; ++ipar) {
1722  gradients(ipar,0) = func->GradientPar(ipar, m_vars, eps);
1723  }
1724 
1725  // carry out the matrix multiplication
1726  TMatrixT<double> gradientsTransposed(TMatrixT<double>::kTransposed, gradients);
1727  // std::cout << "parametricVariance: transposed gradients:";
1728  // for (int ipar = 0; ipar < npar; ++ipar)
1729  // std::cout << " " << gradients(0,ipar);
1730  // std::cout << std::endl;
1731  TMatrixT<double> tmp1(*cov, TMatrixT<double>::kMult, gradients);
1732  // std::cout << "parametricVariance: cov * gradients:";
1733  // for (int ipar = 0; ipar < npar; ++ipar)
1734  // std::cout << " " << tmp1(ipar,0);
1735  TMatrixT<double> tmp2(gradientsTransposed, TMatrixT<double>::kMult, tmp1);
1736 
1737  result = TMath::Sqrt(tmp2(0,0));
1738 
1739  return status;
1740 }
1741 
1742 //________________________________________________________________________________
1743 bool
1745  // Simple utility function testing whether two double values are sufficiently similar.
1746  // The test carried out is on their relative difference, which should be within a given tolerance.
1747 
1748  static const double tolerance = 1.e-8;
1749 
1750  double diff = a - b;
1751  double ref = std::fabs(a) + std::fabs(b);
1752  return (ref == 0 || std::fabs(diff) < tolerance*ref);
1753 }
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
Analysis::CalibrationDataHistogramContainer::getUncertainty
virtual CalibrationStatus getUncertainty(const std::string &unc, const CalibrationDataVariables &x, UncertaintyResult &result, TObject *obj=0)
retrieve the calibration uncertainty due to the given source.
Definition: CalibrationDataContainer.cxx:622
Analysis::CalibrationDataMappedHistogramContainer::Bin::m_dimension
unsigned int m_dimension
Definition: CalibrationDataContainer.h:380
Analysis::CalibrationDataContainer::getUncertainties
CalibrationStatus getUncertainties(const CalibrationDataVariables &x, std::map< std::string, Analysis::UncertaintyResult > &all)
retrieve the list of "uncertainties" accessible to this object.
Definition: CalibrationDataContainer.cxx:137
Analysis::CalibrationDataContainer::getUncertainty
virtual CalibrationStatus getUncertainty(const std::string &unc, const CalibrationDataVariables &x, UncertaintyResult &result, TObject *obj=0)=0
retrieve the calibration uncertainty due to the given source.
Analysis::CalibrationDataMappedHistogramContainer
Definition: CalibrationDataContainer.h:335
plotBeamSpotCompare.x1
x1
Definition: plotBeamSpotCompare.py:216
beamspotnt.var
var
Definition: bin/beamspotnt.py:1394
Analysis::CalibrationDataFunctionContainer::getResult
virtual CalibrationStatus getResult(const CalibrationDataVariables &x, double &result, TObject *obj=0, bool=false)
retrieve the calibration result.
Definition: CalibrationDataContainer.cxx:1605
python.CaloRecoConfig.f
f
Definition: CaloRecoConfig.py:127
Analysis::CalibrationDataMappedHistogramContainer::Bin::operator=
Bin & operator=(const Bin &other)
Definition: CalibrationDataContainer.cxx:1480
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
yodamerge_tmp.dim
dim
Definition: yodamerge_tmp.py:239
get_generator_info.result
result
Definition: get_generator_info.py:21
Analysis::CalibrationDataMappedHistogramContainer::CalibrationDataMappedHistogramContainer
CalibrationDataMappedHistogramContainer(const char *name="default")
Analysis::CalibrationDataContainer
Definition: CalibrationDataContainer.h:51
DeMoUpdate.tmp2
string tmp2
Definition: DeMoUpdate.py:1168
python.SystemOfUnits.m
int m
Definition: SystemOfUnits.py:91
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
max
#define max(a, b)
Definition: cfImp.cxx:41
checkCoolLatestUpdate.variables
variables
Definition: checkCoolLatestUpdate.py:13
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
PlotCalibFromCool.zAxis
zAxis
Definition: PlotCalibFromCool.py:76
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
Analysis::CalibrationDataHistogramContainer::getInterpolatedUncertainty
double getInterpolatedUncertainty(TH1 *hist) const
Retrieve interpolated result (utility function)
Definition: CalibrationDataContainer.cxx:777
python.App.bins
bins
Definition: App.py:410
Analysis::CalibrationDataMappedHistogramContainer::computeVariableTypes
virtual void computeVariableTypes()
decode the 'uncertainty' objects' names to determine the relevant variable types
Definition: CalibrationDataContainer.cxx:1030
Analysis::CalibrationDataHistogramContainer::getTagWeightAxis
virtual int getTagWeightAxis()
Test whether this calibration object is one for "continuous" calibration (this has some subtle conseq...
Definition: CalibrationDataContainer.cxx:935
CalibrationDataContainer.h
CaloCondBlobAlgs_fillNoiseFromASCII.spec
spec
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:47
Analysis::CalibrationDataContainer::m_restrict
bool m_restrict
persistency not needed for this variable
Definition: CalibrationDataContainer.h:230
Analysis::CalibrationDataContainer::setExcludedUncertainties
void setExcludedUncertainties(const std::string &text)
insert the set of uncertainties that are recommended for removal from the eigenvector decomposition.
Definition: CalibrationDataContainer.cxx:280
Analysis::CalibrationDataHistogramContainer::isBinCorrelated
bool isBinCorrelated(const std::string &unc) const
Indicate whether the given uncertainty is correlated from bin to bin or not (note that this function ...
Definition: CalibrationDataContainer.cxx:719
hist_file_dump.d
d
Definition: hist_file_dump.py:137
Analysis::CalibrationDataContainer::m_upperBounds
std::vector< double > m_upperBounds
Definition: CalibrationDataContainer.h:211
Analysis::CalibrationDataMappedHistogramContainer::Bin::contains
bool contains(const double *x) const
Definition: CalibrationDataContainer.cxx:1505
plotmaker.hist
hist
Definition: plotmaker.py:148
Analysis::CalibrationDataContainer::getExcludedUncertainties
std::string getExcludedUncertainties() const
retrieve the (semicolon-separated) set of uncertainties that are recommended for removal from the eig...
Definition: CalibrationDataContainer.cxx:217
Analysis::CalibrationDataHistogramContainer::CalibrationDataHistogramContainer
CalibrationDataHistogramContainer(const char *name="default")
plotBeamSpotCompare.x2
x2
Definition: plotBeamSpotCompare.py:218
Analysis::CalibrationDataHistogramContainer::m_interpolate
bool m_interpolate
If true, interpolate between bins rather than doing a straight bin-wise evaluation.
Definition: CalibrationDataContainer.h:299
yodamerge_tmp.axis
list axis
Definition: yodamerge_tmp.py:241
Analysis::CalibrationDataContainer::computeVariableTypes
virtual void computeVariableTypes()=0
decode the 'uncertainty' objects' names to determine the relevant variable types
Analysis::CalibrationDataContainer::m_objSystematics
TObject * m_objSystematics
don't persistify
Definition: CalibrationDataContainer.h:218
skel.it
it
Definition: skel.GENtoEVGEN.py:423
plotBeamSpotVxVal.cov
cov
Definition: plotBeamSpotVxVal.py:201
bin
Definition: BinsDiffFromStripMedian.h:43
Analysis::CalibrationDataMappedHistogramContainer::Bin::m_up
double * m_up
Definition: CalibrationDataContainer.h:382
PlotCalibFromCool.ib
ib
Definition: PlotCalibFromCool.py:419
mc.diff
diff
Definition: mc.SFGenPy8_MuMu_DD.py:14
Analysis::CalibrationDataHistogramContainer::getStatUncertainty
virtual CalibrationStatus getStatUncertainty(const CalibrationDataVariables &x, double &result)
retrieve the calibration statistical uncertainty.
Definition: CalibrationDataContainer.cxx:582
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
Analysis::CalibrationDataContainer::setComment
void setComment(const std::string &text)
insert the given text as comment for this calibration
Definition: CalibrationDataContainer.cxx:255
Analysis::CalibrationDataContainer::getSystUncertainty
CalibrationStatus getSystUncertainty(const CalibrationDataVariables &x, UncertaintyResult &result, TObject *obj=0)
retrieve the calibration total systematic uncertainty
Definition: CalibrationDataContainer.cxx:101
x
#define x
Analysis::CalibrationDataContainer::getResult
virtual CalibrationStatus getResult(const CalibrationDataVariables &x, double &result, TObject *obj=0, bool extrapolate=false)=0
retrieve the calibration result.
Analysis::CalibrationDataContainer::getLowerBound
double getLowerBound(unsigned int vartype, bool extrapolate=false) const
retrieve the lower bound of validity for the requested variable type
Definition: CalibrationDataContainer.cxx:366
Analysis::CalibrationDataFunctionContainer::computeVariableTypes
virtual void computeVariableTypes()
cached
Definition: CalibrationDataContainer.cxx:1572
Analysis::CalibrationDataContainer::kAbsEta
@ kAbsEta
Definition: CalibrationDataContainer.h:66
makeTRTBarrelCans.y1
tuple y1
Definition: makeTRTBarrelCans.py:15
Analysis::CalibrationDataMappedHistogramContainer::Bin::getUpperBound
double getUpperBound(unsigned int dim) const
Definition: CalibrationDataContainer.cxx:1516
Analysis::CalibrationDataMappedHistogramContainer::getUncertainty
virtual CalibrationStatus getUncertainty(const std::string &unc, const CalibrationDataVariables &x, UncertaintyResult &result, TObject *obj=0)
retrieve the calibration uncertainty due to the given source.
Definition: CalibrationDataContainer.cxx:1209
Analysis::kSuccess
@ kSuccess
Definition: CalibrationDataVariables.h:57
Analysis::CalibrationDataFunctionContainer
Definition: CalibrationDataContainer.h:427
Analysis::CalibrationDataMappedHistogramContainer::Bin::getLowerBound
double getLowerBound(unsigned int dim) const
Definition: CalibrationDataContainer.cxx:1524
Analysis::CalibrationDataMappedHistogramContainer::m_mapped
std::vector< std::string > m_mapped
mapped variables.
Definition: CalibrationDataContainer.h:396
Analysis::CalibrationDataMappedHistogramContainer::setMappedVariables
void setMappedVariables(const std::vector< std::string > &variables)
Set (by hand) the variables that will be mapped onto a single histogram axis.
Definition: CalibrationDataContainer.cxx:1266
Analysis::CalibrationDataFunctionContainer::CalibrationDataFunctionContainer
CalibrationDataFunctionContainer(const char *name="default")
Analysis::CalibrationDataContainer::m_variables
std::vector< unsigned int > m_variables
don't persistify
Definition: CalibrationDataContainer.h:223
Analysis::CalibrationDataMappedHistogramContainer::getBinBoundaries
virtual std::vector< double > getBinBoundaries(unsigned int vartype)
Retrieve the bin boundaries for the specified variable type (which should be a CalibrationParametriza...
Definition: CalibrationDataContainer.cxx:1358
Analysis::CalibrationDataContainer::m_vars
double m_vars[MaxCalibrationVars]
don't persistify
Definition: CalibrationDataContainer.h:220
Analysis::CalibrationDataContainer::computeVariables
CalibrationStatus computeVariables(const CalibrationDataVariables &x, bool extrapolate=false)
Compute the variables to be used.
Definition: CalibrationDataContainer.cxx:307
Analysis::CalibrationDataMappedHistogramContainer::Bin
Helper class for the specification of custom binning.
Definition: CalibrationDataContainer.h:367
doubleTestComp.j1
j1
Definition: doubleTestComp.py:21
Analysis::CalibrationDataContainer::listUncertainties
std::vector< std::string > listUncertainties() const
retrieve the list of "uncertainties" accessible to this object.
Definition: CalibrationDataContainer.cxx:120
Analysis::kExtrapolatedRange
@ kExtrapolatedRange
Definition: CalibrationDataVariables.h:59
Analysis::CalibrationDataMappedHistogramContainer::getNMappedBins
unsigned int getNMappedBins() const
return the number of mapped bins
Definition: CalibrationDataContainer.cxx:1295
Analysis::CalibrationDataHistogramContainer::isInterpolated
virtual bool isInterpolated() const
Indicate whether histogram interpolation is used or not.
Definition: CalibrationDataContainer.cxx:751
Analysis::CalibrationDataContainer::kEta
@ kEta
Definition: CalibrationDataContainer.h:65
Analysis::kError
@ kError
Definition: CalibrationDataVariables.h:60
Analysis::CalibrationDataContainer::setHadronisation
void setHadronisation(const std::string &text)
insert the given text as the 'hadronisation reference' for this calibration
Definition: CalibrationDataContainer.cxx:268
makeTRTBarrelCans.y2
tuple y2
Definition: makeTRTBarrelCans.py:18
Analysis::CalibrationDataHistogramContainer::m_uncorrelatedSyst
THashList m_uncorrelatedSyst
no need to persistify
Definition: CalibrationDataContainer.h:296
covarianceTool.title
title
Definition: covarianceTool.py:542
contains
bool contains(const std::string &s, const std::string &regx)
does a string contain the substring
Definition: hcg.cxx:111
Analysis::CalibrationDataHistogramContainer::m_binBoundaries
std::map< unsigned int, std::vector< double > > m_binBoundaries
Cache for bin boundary information.
Definition: CalibrationDataContainer.h:291
Analysis::CalibrationDataContainer::setResult
void setResult(TObject *obj)
insert the main object for this calibration
Definition: CalibrationDataContainer.cxx:244
res
std::pair< std::vector< unsigned int >, bool > res
Definition: JetGroupProductTest.cxx:14
CalibCoolCompareRT.up
up
Definition: CalibCoolCompareRT.py:109
Analysis::CalibrationDataMappedHistogramContainer::addBin
unsigned int addBin(const Bin &bin)
Add mapping bin.
Definition: CalibrationDataContainer.cxx:1284
Analysis::kRange
@ kRange
Definition: CalibrationDataVariables.h:58
Analysis::UncertaintyResult
std::pair< double, double > UncertaintyResult
The following typedef is for convenience: most uncertainties can be asymmetric.
Definition: CalibrationDataContainer.h:33
Analysis::CalibrationDataHistogramContainer::getResult
virtual CalibrationStatus getResult(const CalibrationDataVariables &x, double &result, TObject *obj=0, bool extrapolate=false)
retrieve the calibration result.
Definition: CalibrationDataContainer.cxx:539
Analysis::CalibrationDataFunctionContainer::m_objStatistics
TObject * m_objStatistics
Definition: CalibrationDataContainer.h:445
Analysis::CalibrationDataHistogramContainer::getInterpolatedResult
double getInterpolatedResult(TH1 *hist) const
Retrieve interpolated result (utility function)
Definition: CalibrationDataContainer.cxx:760
Analysis::CalibrationDataHistogramContainer::computeVariableTypes
virtual void computeVariableTypes()
decode the 'uncertainty' objects' names to determine the relevant variable types
Definition: CalibrationDataContainer.cxx:490
plotBeamSpotCompare.xd
xd
Definition: plotBeamSpotCompare.py:220
Analysis::CalibrationDataMappedHistogramContainer::findBin
Int_t findBin()
don't persistify
Definition: CalibrationDataContainer.cxx:1326
Analysis::CalibrationDataContainer::m_objResult
TObject * m_objResult
(possibly looser) upper validity bounds for extrapolation
Definition: CalibrationDataContainer.h:217
Analysis::CalibrationDataContainer::m_lowerBoundsExtrapolated
std::vector< double > m_lowerBoundsExtrapolated
Definition: CalibrationDataContainer.h:213
tolerance
Definition: suep_shower.h:17
ClassImp
ClassImp(CalibrationDataContainer) CalibrationDataContainer
Definition: CalibrationDataContainer.cxx:83
python.grid.Add
def Add(name)
Definition: grid.py:41
Analysis::CalibrationStatus
CalibrationStatus
Definition: CalibrationDataVariables.h:56
Analysis::CalibrationDataMappedHistogramContainer::m_bins
std::vector< Bin > m_bins
don't persistify
Definition: CalibrationDataContainer.h:402
Analysis::CalibrationDataContainer::getVariableTypes
std::vector< unsigned int > getVariableTypes()
utility to retrieve variable types
Definition: CalibrationDataContainer.cxx:408
pmontree.code
code
Definition: pmontree.py:443
Analysis::CalibrationDataContainer::getHadronisation
std::string getHadronisation() const
retrieve the 'hadronisation reference' entered for this calibration, if any
Definition: CalibrationDataContainer.cxx:203
Analysis::CalibrationDataContainer::m_lowerBounds
std::vector< double > m_lowerBounds
Definition: CalibrationDataContainer.h:210
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
plotBeamSpotVxVal.bin
int bin
Definition: plotBeamSpotVxVal.py:83
Analysis::CalibrationDataHistogramContainer
Definition: CalibrationDataContainer.h:247
Analysis::CalibrationDataContainer::typeFromString
int typeFromString(const std::string &key) const
Connection between variable names (on histogram axes etc.) and variable 'types' as used in actual eva...
Definition: CalibrationDataContainer.cxx:292
Analysis::CalibrationDataContainer::kTagWeight
@ kTagWeight
Definition: CalibrationDataContainer.h:67
Analysis::CalibrationDataMappedHistogramContainer::Bin::~Bin
~Bin()
Definition: CalibrationDataContainer.cxx:1497
Analysis::CalibrationDataMappedHistogramContainer::checkBounds
void checkBounds()
check the bounds of validity for this calibration object
Definition: CalibrationDataContainer.cxx:1090
Analysis::CalibrationDataContainer::setUncertainty
void setUncertainty(const std::string &unc, TObject *obj)
insert the relevant object for the requested source of 'uncertainty'
Definition: CalibrationDataContainer.cxx:231
Analysis::CalibrationDataMappedHistogramContainer::getTagWeightAxis
virtual int getTagWeightAxis()
Test whether this calibration object is one for "continuous" calibration (this has some subtle conseq...
Definition: CalibrationDataContainer.cxx:1249
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:18
Analysis::CalibrationDataMappedHistogramContainer::getResult
virtual CalibrationStatus getResult(const CalibrationDataVariables &x, double &result, TObject *obj=0, bool extrapolate=false)
retrieve the calibration result.
Definition: CalibrationDataContainer.cxx:1152
Analysis::CalibrationDataContainer::isNearlyEqual
static bool isNearlyEqual(double a, double b)
utility for comparison of doubles
Definition: CalibrationDataContainer.cxx:1744
Cut::all
@ all
Definition: SUSYToolsAlg.cxx:64
Analysis::CalibrationDataMappedHistogramContainer::m_beginMapped
unsigned int m_beginMapped
starting position of mapped variables
Definition: CalibrationDataContainer.h:399
python.PyAthena.v
v
Definition: PyAthena.py:157
Analysis::CalibrationDataHistogramContainer::checkBounds
void checkBounds()
check the bounds of validity for this calibration object
Definition: CalibrationDataContainer.cxx:673
makeTRTBarrelCans.dy
tuple dy
Definition: makeTRTBarrelCans.py:21
ALFA_EventTPCnv_Dict::t2
std::vector< ALFA_RawDataContainer_p1 > t2
Definition: ALFA_EventTPCnvDict.h:44
Analysis::CalibrationDataHistogramContainer::setUncorrelated
void setUncorrelated(const std::string &unc)
Indicate that the given uncertainty is to be treated uncorrelated from bin to bin (note that the defa...
Definition: CalibrationDataContainer.cxx:728
Analysis::CalibrationDataFunctionContainer::getUncertainty
virtual CalibrationStatus getUncertainty(const std::string &unc, const CalibrationDataVariables &x, UncertaintyResult &result, TObject *obj=0)
retrieve the calibration uncertainty due to the given source.
Definition: CalibrationDataContainer.cxx:1633
a
TList * a
Definition: liststreamerinfos.cxx:10
InDetDD::other
@ other
Definition: InDetDD_Defs.h:16
Analysis::CalibrationDataContainer::getComment
std::string getComment() const
retrieve the comments entered for this calibration, if any
Definition: CalibrationDataContainer.cxx:190
ref
const boost::regex ref(r_ef)
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
TH1
Definition: rootspy.cxx:268
Analysis::CalibrationDataContainer::getUpperBound
double getUpperBound(unsigned int vartype, bool extrapolate=false) const
retrieve the upper bound of validity for the requested variable type
Definition: CalibrationDataContainer.cxx:379
Analysis::CalibrationDataMappedHistogramContainer::m_lastBin
unsigned int m_lastBin
Definition: CalibrationDataContainer.h:404
makeTRTBarrelCans.dx
tuple dx
Definition: makeTRTBarrelCans.py:20
Analysis::CalibrationDataMappedHistogramContainer::Bin::m_low
double * m_low
Definition: CalibrationDataContainer.h:381
Analysis::CalibrationDataContainer::getBounds
std::vector< std::pair< double, double > > getBounds()
allow the user to inspect the bounds of validity
Definition: CalibrationDataContainer.cxx:391
Analysis::CalibrationDataVariables
Definition: CalibrationDataVariables.h:42
mapped
std::vector< std::string > mapped
Definition: hcg.cxx:51
python.AtlRunQueryAMI.choice
int choice
Definition: AtlRunQueryAMI.py:210
Analysis::CalibrationDataHistogramContainer::setInterpolated
void setInterpolated(bool doInterpolate)
Indicate whether results are to be interpolated between bins or not (this feature is thought to be us...
Definition: CalibrationDataContainer.cxx:740
makeTransCanvas.text
text
Definition: makeTransCanvas.py:11
Analysis::CalibrationDataMappedHistogramContainer::findMappedBin
Int_t findMappedBin(const double *x)
Definition: CalibrationDataContainer.cxx:1305
MuonHough::extrapolate
float extrapolate(const MuonLayerHough::Maximum &ref, const MuonLayerHough::Maximum &ex, bool doparabolic=false)
Definition: MuonLayerHough.cxx:519
Analysis::CalibrationDataContainer::kPt
@ kPt
Definition: CalibrationDataContainer.h:64
merge.status
status
Definition: merge.py:17
Analysis::CalibrationDataMappedHistogramContainer::getStatUncertainty
virtual CalibrationStatus getStatUncertainty(const CalibrationDataVariables &x, double &result)
retrieve the calibration statistical uncertainty.
Definition: CalibrationDataContainer.cxx:1185
Analysis::CalibrationDataHistogramContainer::getEigenvectorReduction
virtual int getEigenvectorReduction(unsigned int choice) const
Retrieve the number of eigenvectors to be retained for the purpose of eigenvector variation reduction...
Definition: CalibrationDataContainer.cxx:986
Analysis::CalibrationDataFunctionContainer::getStatUncertainty
virtual CalibrationStatus getStatUncertainty(const CalibrationDataVariables &x, double &result)
retrieve the calibration statistical uncertainty.
Definition: CalibrationDataContainer.cxx:1675
Analysis::CalibrationDataMappedHistogramContainer::Bin::Bin
Bin()
hotSpotInTAG.nb
nb
Definition: hotSpotInTAG.py:164
python.PyAthena.obj
obj
Definition: PyAthena.py:135
Analysis::CalibrationDataMappedHistogramContainer::getMappedVariables
std::vector< std::string > getMappedVariables() const
List which variables get mapped onto a single histogram axis.
Definition: CalibrationDataContainer.cxx:1275
Analysis::CalibrationDataContainer::getStatUncertainty
virtual CalibrationStatus getStatUncertainty(const CalibrationDataVariables &x, double &result)=0
retrieve the calibration statistical uncertainty.
doubleTestComp.j2
j2
Definition: doubleTestComp.py:22
Analysis::CalibrationDataContainer::m_upperBoundsExtrapolated
std::vector< double > m_upperBoundsExtrapolated
(possibly looser) lower validity bounds for extrapolation
Definition: CalibrationDataContainer.h:214
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37
Analysis::CalibrationDataHistogramContainer::getBinBoundaries
virtual std::vector< double > getBinBoundaries(unsigned int vartype)
Retrieve the bin boundaries for the specified variable type (which should be a CalibrationParametriza...
Definition: CalibrationDataContainer.cxx:952