Belle II Software  release-05-02-19
TestCalibrationAlgorithm.cc
1 #include <calibration/example_caf_lib/TestCalibrationAlgorithm.h>
2 
3 #include <memory>
4 
5 #include <TTree.h>
6 #include <TH1F.h>
7 #include <TClonesArray.h>
8 #include <TRandom.h>
9 
10 
11 #include <alignment/dataobjects/MilleData.h>
12 #include <calibration/dbobjects/TestCalibObject.h>
13 #include <calibration/dbobjects/TestCalibMean.h>
14 
15 using namespace Belle2;
16 using namespace Calibration;
17 
19 {
21  " -------------------------- Test Calibration Algoritm -------------------------\n"
22  " \n"
23  " Testing algorithm which just gets mean of a test histogram collected by \n"
24  " CaTest module and provides a DB object with another histogram with one \n"
25  " entry at calibrated value. \n"
26  " ------------------------------------------------------------------------------\n"
27  );
28 }
29 
31 {
32  std::string debugFileName = (this->getPrefix()) + "debug.root";
33  B2INFO("Storing histograms in " << debugFileName);
34 
35  // Save the current directory to change back later
36  TDirectory* currentDir = gDirectory;
37  TFile* debugFile = new TFile(debugFileName.c_str(), "RECREATE");
38  debugFile->cd();
39  TH1F* debugHisto = new TH1F("h1", "h1", 30, -3., 3.);
40  for (int i = 0; i < 1000; ++i) {
41  debugHisto->Fill(gRandom->Gaus());
42  }
43 
44  debugHisto->Write();
45  debugFile->Close();
46  currentDir->cd();
47 }
48 
50 {
51  // Some calibrations may want to pass information from one execution to the next.
52  // We do this via a json object that is created like a std::map (or Python dictionary).
53  // You will have set this json object up manually by calling loadInputJson(string),
54  // or the Python CAF may do this for you.
55  //
56  // USING THIS FEATURE IS OPTIONAL!!!
57  //
58  // It is only for cases where you really need to pass a message from one execution of the algorithm
59  // to the next. It is not supposed to be for all of your config variables. Use member variables for
60  // configuring your algorithm!
61 
62  // You can pull in from the Input JSON like so
63  // First you must know the string used to label the value, in this case we save the previous calculated mean
64  const std::string previousMeanKey = "previous_mean";
65  // Test if the key exists in our inputJson object (was it set?)
66  if (inputJsonKeyExists(previousMeanKey)) {
67  const float prevMean = getOutputJsonValue<float>(previousMeanKey);
68  B2INFO("An input JSON object was set with the previous calculated mean = " << prevMean);
69  }
70 
71  // Pulling in data from collector output. It now returns shared_ptr<T> so the underlying pointer
72  // will delete itself automatically at the end of this scope unless you do something
73  auto ttree = getObjectPtr<TTree>("MyTree");
74  auto hist = getObjectPtr<TH1F>("MyHisto");
75  auto mille = getObjectPtr<MilleData>("test_mille");
76  if (!ttree) return c_Failure;
77  if (!hist) return c_Failure;
78  if (!mille) return c_Failure;
79  B2INFO("Number of Entries in MyTree was " << ttree->GetEntries());
80  B2INFO("Number of Entries in MyHisto was " << hist->GetEntries());
81 
82  float mean = hist->GetMean();
83  float meanError = hist->GetMeanError();
84 
85  B2INFO("Mean of MyHisto was " << mean);
86  B2INFO("Mean Error of MyHisto was " << meanError);
87 
88  // Create debugging histo if we asked for it
90 
91  // Fail if we we're asked to. Useful for testing
92  if (getForceFail()) {
93  B2WARNING("We were asked to fail by the m_willFail flag. Failing");
94  return c_Failure;
95  }
96 
97  for (auto& fileName : mille->getFiles()) {
98  B2INFO("Stored Mille binary file: " << fileName);
99  }
100 
101  if (hist->GetEntries() < 100 || ttree->GetEntries() < getMinEntries() || mille->getFiles().empty())
102  return c_NotEnoughData;
103 
104  // Example of saving a DBObject.
105  TestCalibMean* correction = new TestCalibMean(mean, meanError);
106  saveCalibration(correction, "TestCalibMean");
107 
108  // Example of saving a Belle2 DBArray of DBObjects defined in the dbobjects directory
109  TClonesArray* exampleDBArrayConstants = new TClonesArray("Belle2::TestCalibObject", 2);
110  float val = 0.0;
111  for (int i = 0; i < 2; i++) {
112  val += 1.0;
113  new((*exampleDBArrayConstants)[i]) TestCalibObject(val);
114  }
115  saveCalibration(exampleDBArrayConstants, "TestCalibObjects");
116  // Iterate until we find answer to the most fundamental question...
117  B2INFO("mean: " << mean);
118  B2INFO("meanError: " << meanError);
119 
120  // Remember how we optionally had an input JSON object? Well this is how you can pass out JSON information
121  // to the Python CAF. You need to set the information into the object
122  setOutputJsonValue<float>(previousMeanKey, mean);
123 
124  // Decide if we need to iterate or if this value was fine
125  if (mean - 42. >= 1.) {
126  return c_Iterate;
127  } else {
128  return c_OK;
129  }
130 }
131 
133 {
134  auto hist = getObjectPtr<TH1F>("MyHisto");
135  float mean = hist->GetMean();
136  // First run?
137  if (!m_previousMean) {
138  B2INFO("This is the first run encountered, let's say it is a boundary.");
139  B2INFO("Initial mean was " << mean);
140  m_previousMean.emplace(mean);
141  return true;
142  }
143  // Shifted since last time?
144  else if ((mean - m_previousMean.value()) > m_allowedMeanShift) {
145  B2INFO("Histogram mean has shifted from " << m_previousMean.value()
146  << " to " << mean << ". We are requesting a new payload boundary for ("
147  << currentRun.first << "," << currentRun.second << ")");
148  m_previousMean.emplace(mean);
149  return true;
150  } else {
151  return false;
152  }
153 }
Belle2::TestCalibrationAlgorithm::getForceFail
bool getForceFail()
getter for m_willFail
Definition: TestCalibrationAlgorithm.h:44
Belle2::TestCalibrationAlgorithm::m_allowedMeanShift
float m_allowedMeanShift
Configurable parameter for deciding when to choose a new payload boundary (if used)
Definition: TestCalibrationAlgorithm.h:94
Belle2::CalibrationAlgorithm::saveCalibration
void saveCalibration(TClonesArray *data, const std::string &name)
Store DBArray payload with given name with default IOV.
Definition: CalibrationAlgorithm.cc:290
Belle2::CalibrationAlgorithm::c_Iterate
@ c_Iterate
Needs iteration =1 in Python.
Definition: CalibrationAlgorithm.h:52
Belle2::TestCalibrationAlgorithm::m_debugHisto
int m_debugHisto
Set if a debugging histogram should be created in the algorithm output directory.
Definition: TestCalibrationAlgorithm.h:85
Belle2::CalibrationAlgorithm::c_OK
@ c_OK
Finished successfuly =0 in Python.
Definition: CalibrationAlgorithm.h:51
Belle2::TestCalibObject
Test DBObject.
Definition: TestCalibObject.h:33
Belle2::CalibrationAlgorithm::setDescription
void setDescription(const std::string &description)
Set algorithm description (in constructor)
Definition: CalibrationAlgorithm.h:331
Belle2::TestCalibMean
Test DBObject.
Definition: TestCalibMean.h:27
Belle2::TestCalibrationAlgorithm::m_previousMean
std::optional< float > m_previousMean
During isBoundaryRequired this is used to define the previous run's mean.
Definition: TestCalibrationAlgorithm.h:91
Belle2::CalibrationAlgorithm::inputJsonKeyExists
bool inputJsonKeyExists(const std::string &key) const
Test for a key in the input JSON object.
Definition: CalibrationAlgorithm.h:370
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::TestCalibrationAlgorithm::createDebugHistogram
void createDebugHistogram()
Perform debug histogram file creation.
Definition: TestCalibrationAlgorithm.cc:30
Belle2::CalibrationAlgorithm::c_Failure
@ c_Failure
Failed =3 in Python.
Definition: CalibrationAlgorithm.h:54
Belle2::ExpRun
Struct containing exp number and run number.
Definition: Splitter.h:55
Belle2::TestCalibrationAlgorithm::calibrate
virtual EResult calibrate() override
Run algo on data.
Definition: TestCalibrationAlgorithm.cc:49
Belle2::CalibrationAlgorithm::EResult
EResult
The result of calibration.
Definition: CalibrationAlgorithm.h:50
Belle2::CalibrationAlgorithm::c_NotEnoughData
@ c_NotEnoughData
Needs more data =2 in Python.
Definition: CalibrationAlgorithm.h:53
Belle2::TestCalibrationAlgorithm::TestCalibrationAlgorithm
TestCalibrationAlgorithm()
Constructor set the prefix to TestCalibration.
Definition: TestCalibrationAlgorithm.cc:18
Belle2::CalibrationAlgorithm
Base class for calibration algorithms.
Definition: CalibrationAlgorithm.h:47
Belle2::TestCalibrationAlgorithm::getMinEntries
int getMinEntries()
getter for m_minEntries
Definition: TestCalibrationAlgorithm.h:50
Belle2::TestCalibrationAlgorithm::isBoundaryRequired
virtual bool isBoundaryRequired(const Calibration::ExpRun &currentRun) override
Decide if a run should be a payload boundary. Only used in certain Python Algorithm Starategies.
Definition: TestCalibrationAlgorithm.cc:132
Belle2::CalibrationAlgorithm::getPrefix
std::string getPrefix() const
Get the prefix used for getting calibration data.
Definition: CalibrationAlgorithm.h:156