Belle II Software development
CalibrationAlgorithm.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8#include <set>
9#include <utility>
10#include <filesystem>
11#include <boost/algorithm/string.hpp>
12#include <boost/python.hpp>
13#include <boost/python/list.hpp>
14#include <TChain.h>
15#include <calibration/CalibrationAlgorithm.h>
16#include <framework/logging/Logger.h>
17#include <framework/core/PyObjConvUtils.h>
18#include <framework/io/RootIOUtilities.h>
19
20using namespace Belle2;
21using namespace std;
22using namespace Calibration;
23namespace fs = std::filesystem;
24
25const ExpRun CalibrationAlgorithm::m_allExpRun = make_pair(-1, -1);
26
29{
30 // Is it a sequence?
31 if (PySequence_Check(pyObj)) {
32 Py_ssize_t nObj = PySequence_Length(pyObj);
33 // Does it have 2 objects in it?
34 if (nObj != 2) {
35 B2DEBUG(29, "ExpRun was a Python sequence which didn't have exactly 2 entries!");
36 return false;
37 }
38 PyObject* item1, *item2;
39 item1 = PySequence_GetItem(pyObj, 0);
40 item2 = PySequence_GetItem(pyObj, 1);
41 // Did the GetItem work?
42 if ((item1 == NULL) || (item2 == NULL)) {
43 B2DEBUG(29, "A PyObject pointer was NULL in the sequence");
44 return false;
45 }
46 // Are they longs?
47 if (PyLong_Check(item1) && PyLong_Check(item2)) {
48 long value1, value2;
49 value1 = PyLong_AsLong(item1);
50 value2 = PyLong_AsLong(item2);
51 if (((value1 == -1) || (value2 == -1)) && PyErr_Occurred()) {
52 B2DEBUG(29, "An error occurred while converting the PyLong to long");
53 return false;
54 }
55 } else {
56 B2DEBUG(29, "One or more of the PyObjects in the ExpRun wasn't a long");
57 return false;
58 }
59 // Make sure to kill off the reference GetItem gave us responsibility for
60 Py_DECREF(item1);
61 Py_DECREF(item2);
62 } else {
63 B2DEBUG(29, "ExpRun was not a Python sequence.");
64 return false;
65 }
66 return true;
67}
68
71{
72 ExpRun expRun;
73 PyObject* itemExp, *itemRun;
74 itemExp = PySequence_GetItem(pyObj, 0);
75 itemRun = PySequence_GetItem(pyObj, 1);
76 expRun.first = PyLong_AsLong(itemExp);
77 Py_DECREF(itemExp);
78 expRun.second = PyLong_AsLong(itemRun);
79 Py_DECREF(itemRun);
80 return expRun;
81}
82
84{
85 B2DEBUG(29, "Running execute() using Python Object as input argument");
86 // Reset the execution specific data in case the algorithm was previously called
87 m_data.reset();
88 m_data.setIteration(iteration);
89 vector<ExpRun> vecRuns;
90 // Is it a list?
91 if (PySequence_Check(runs)) {
92 boost::python::handle<> handle(boost::python::borrowed(runs));
93 boost::python::list listRuns(handle);
94
95 int nList = boost::python::len(listRuns);
96 for (int iList = 0; iList < nList; ++iList) {
97 boost::python::object pyExpRun(listRuns[iList]);
98 if (!checkPyExpRun(pyExpRun.ptr())) {
99 B2ERROR("Received Python ExpRuns couldn't be converted to C++");
101 return c_Failure;
102 } else {
103 vecRuns.push_back(convertPyExpRun(pyExpRun.ptr()));
104 }
105 }
106 } else {
107 B2ERROR("Tried to set the input runs but we didn't receive a Python sequence object (list,tuple).");
109 return c_Failure;
110 }
111 return execute(vecRuns, iteration, iov);
112}
113
114CalibrationAlgorithm::EResult CalibrationAlgorithm::execute(vector<Calibration::ExpRun> runs, int iteration, IntervalOfValidity iov)
115{
116 // Check if we are calling this function directly and need to reset, or through Python where it was already done.
117 if (m_data.getResult() != c_Undefined) {
118 m_data.reset();
119 m_data.setIteration(iteration);
120 }
121
122 if (m_inputFileNames.empty()) {
123 B2ERROR("There aren't any input files set. Please use CalibrationAlgorithm::setInputFiles()");
125 return c_Failure;
126 }
127
128 // Did we receive runs to execute over explicitly?
129 if (!(runs.empty())) {
130 for (auto expRun : runs) {
131 B2DEBUG(29, "ExpRun requested = (" << expRun.first << ", " << expRun.second << ")");
132 }
133 // We've asked explicitly for certain runs, but we should check if the data granularity is 'run'
134 if (strcmp(getGranularity().c_str(), "all") == 0) {
135 B2ERROR(("The data is collected with granularity=all (exp=-1,run=-1), but you seem to request calibration for specific runs."
136 " We'll continue but using ALL the input data given instead of the specific runs requested."));
137 }
138 } else {
139 // If no runs are provided, infer the runs from all collected data
140 runs = getRunListFromAllData();
141 // Let's check that we have some now
142 if (runs.empty()) {
143 B2ERROR("No collected data in input files.");
145 return c_Failure;
146 }
147 for (auto expRun : runs) {
148 B2DEBUG(29, "ExpRun requested = (" << expRun.first << ", " << expRun.second << ")");
149 }
150 }
151
153 if (iov.empty()) {
154 // If no user specified IoV we use the IoV from the executed run list
155 iov = IntervalOfValidity(runs[0].first, runs[0].second, runs[runs.size() - 1].first, runs[runs.size() - 1].second);
156 }
158 // After here, the getObject<...>(...) helpers start to work
159
161 m_data.setResult(result);
162 return result;
163}
164
166void CalibrationAlgorithm::setInputFileNames(PyObject* inputFileNames)
167{
168 // The reasoning for this very 'manual' approach to extending the Python interface
169 // (instead of using boost::python) is down to my fear of putting off final users with
170 // complexity on their side.
171 //
172 // I didn't want users that inherit from this class to be forced to use boost and
173 // to have to define a new python module just to use the CAF. A derived class from
174 // from a boost exposed class would need to have its own boost python module definition
175 // to allow access from a steering file and to the base class functions (I think).
176 // I also couldn't be bothered to write a full framework to get around the issue in a similar
177 // way to Module()...maybe there's an easy way.
178 //
179 // But this way we can allow people to continue using their ROOT implemented classes and inherit
180 // easily from this one. But add in a few helper functions that work with Python objects
181 // created in their steering file i.e. instead of being forced to use STL objects as input
182 // to the algorithm.
183 if (PyList_Check(inputFileNames)) {
184 boost::python::handle<> handle(boost::python::borrowed(inputFileNames));
185 boost::python::list listInputFileNames(handle);
186 auto vecInputFileNames = PyObjConvUtils::convertPythonObject(listInputFileNames, vector<string>());
187 setInputFileNames(vecInputFileNames);
188 } else {
189 B2ERROR("Tried to set the input files but we didn't receive a Python list.");
190 }
191}
192
194void CalibrationAlgorithm::setInputFileNames(vector<string> inputFileNames)
195{
196 // A lot of code below is tweaked from RootInputModule::initialize,
197 // since we're basically copying the functionality anyway.
198 if (inputFileNames.empty()) {
199 B2WARNING("You have called setInputFileNames() with an empty list. Did you mean to do that?");
200 return;
201 }
202 auto tmpInputFileNames = RootIOUtilities::expandWordExpansions(inputFileNames);
203
204 // We'll use a set to enforce sorted unique file paths as we check them
205 set<string> setInputFileNames;
206 // Check that files exist and convert to absolute paths
207 for (auto path : tmpInputFileNames) {
208 string fullPath = fs::absolute(path).string();
209 if (fs::exists(fullPath)) {
210 setInputFileNames.insert(fs::canonical(fullPath).string());
211 } else {
212 B2WARNING("Couldn't find the file " << path);
213 }
214 }
215
216 if (setInputFileNames.empty()) {
217 B2WARNING("No valid files specified!");
218 return;
219 } else {
220 // Reset the run -> files map as our files are likely different
221 m_runsToInputFiles.clear();
222 }
223
224 // Open TFile to check they can be accessed by ROOT
225 TDirectory* dir = gDirectory;
226 for (const string& fileName : setInputFileNames) {
227 unique_ptr<TFile> f;
228 try {
229 f.reset(TFile::Open(fileName.c_str(), "READ"));
230 } catch (logic_error&) {
231 //this might happen for ~invaliduser/foo.root
232 //actually undefined behaviour per standard, reported as ROOT-8490 in JIRA
233 }
234 if (!f || !f->IsOpen()) {
235 B2FATAL("Couldn't open input file " + fileName);
236 }
237 }
238 dir->cd();
239
240 // Copy the entries of the set to a vector
241 m_inputFileNames = vector<string>(setInputFileNames.begin(), setInputFileNames.end());
243}
244
246{
247 PyObject* objInputFileNames = PyList_New(m_inputFileNames.size());
248 for (size_t i = 0; i < m_inputFileNames.size(); ++i) {
249 PyList_SetItem(objInputFileNames, i, Py_BuildValue("s", m_inputFileNames[i].c_str()));
250 }
251 return objInputFileNames;
252}
253
255{
256 string expRunString;
257 expRunString += to_string(expRun.first);
258 expRunString += ".";
259 expRunString += to_string(expRun.second);
260 return expRunString;
261}
262
263string CalibrationAlgorithm::getFullObjectPath(const string& name, ExpRun expRun) const
264{
265 string dirName = getPrefix() + "/" + name;
266 string objName = name + "_" + getExpRunString(expRun);
267 return dirName + "/" + objName;
268}
269
270void CalibrationAlgorithm::saveCalibration(TObject* data, const string& name, const IntervalOfValidity& iov)
271{
272 B2DEBUG(29, "Saving calibration TObject = '" << name << "' to payloads list.");
273 getPayloads().emplace_back(name, data, iov);
274}
275
276void CalibrationAlgorithm::saveCalibration(TClonesArray* data, const string& name, const IntervalOfValidity& iov)
277{
278 B2DEBUG(29, "Saving calibration TClonesArray '" << name << "' to payloads list.");
279 getPayloads().emplace_back(name, data, iov);
280}
281
283{
284 saveCalibration(data, DataStore::objectName(data->IsA(), ""), iov);
285}
286
288{
289 saveCalibration(data, DataStore::objectName(data->IsA(), ""));
290}
291
292void CalibrationAlgorithm::saveCalibration(TObject* data, const string& name)
293{
295}
296
297void CalibrationAlgorithm::saveCalibration(TClonesArray* data, const string& name)
298{
300}
301
303{
304 if (getPayloads().empty())
305 return false;
306 list<Database::DBImportQuery> payloads = getPayloads();
307 B2INFO("Committing " << payloads.size() << " payloads to database.");
308 return Database::Instance().storeData(payloads);
309}
310
311bool CalibrationAlgorithm::commit(list<Database::DBImportQuery> payloads)
312{
313 if (payloads.empty())
314 return false;
315 return Database::Instance().storeData(payloads);
316}
317
319{
320 RunRange runRange = getRunRangeFromAllData();
321 set<ExpRun> expRunSet = runRange.getExpRunSet();
322 return vector<ExpRun>(expRunSet.begin(), expRunSet.end());
323}
324
326{
328}
329
331{
332 m_runsToInputFiles.clear();
333 // Save TDirectory to change back at the end
334 TDirectory* dir = gDirectory;
335 RunRange* runRange;
336 // Construct the TDirectory name where we expect our objects to be
337 string runRangeObjName(getPrefix() + "/" + RUN_RANGE_OBJ_NAME);
338 for (const auto& fileName : m_inputFileNames) {
339 //Open TFile to get the objects
340 unique_ptr<TFile> f;
341 f.reset(TFile::Open(fileName.c_str(), "READ"));
342 runRange = dynamic_cast<RunRange*>(f->Get(runRangeObjName.c_str()));
343 if (runRange) {
344 // Insert or extend the run -> file mapping for this ExpRun
345 auto expRuns = runRange->getExpRunSet();
346 for (const auto& expRun : expRuns) {
347 auto runFiles = m_runsToInputFiles.find(expRun);
348 if (runFiles != m_runsToInputFiles.end()) {
349 (runFiles->second).push_back(fileName);
350 } else {
351 m_runsToInputFiles.insert(std::make_pair(expRun, std::vector<std::string> {fileName}));
352 }
353 }
354 } else {
355 B2WARNING("Missing a RunRange object for file: " << fileName);
356 }
357 }
358 dir->cd();
359}
360
362{
363 // Save TDirectory to change back at the end
364 TDirectory* dir = gDirectory;
365 RunRange runRange;
366 // Construct the TDirectory name where we expect our objects to be
367 string runRangeObjName(getPrefix() + "/" + RUN_RANGE_OBJ_NAME);
368 for (const auto& fileName : m_inputFileNames) {
369 //Open TFile to get the objects
370 unique_ptr<TFile> f;
371 f.reset(TFile::Open(fileName.c_str(), "READ"));
372 RunRange* runRangeOther = dynamic_cast<RunRange*>(f->Get(runRangeObjName.c_str()));
373 if (runRangeOther) {
374 runRange.merge(runRangeOther);
375 } else {
376 B2WARNING("Missing a RunRange object for file: " << fileName);
377 }
378 }
379 dir->cd();
380 return runRange;
381}
382
384{
385 // Save TDirectory to change back at the end
386 TDirectory* dir = gDirectory;
387 RunRange* runRange;
388 string runRangeObjName(getPrefix() + "/" + RUN_RANGE_OBJ_NAME);
389 // We only check the first file
390 string fileName = m_inputFileNames[0];
391 unique_ptr<TFile> f;
392 f.reset(TFile::Open(fileName.c_str(), "READ"));
393 runRange = dynamic_cast<RunRange*>(f->Get(runRangeObjName.c_str()));
394 if (!runRange) {
395 B2FATAL("The input file " << fileName << " does not contain a RunRange object at "
396 << runRangeObjName << ". Please set your input files to exclude it.");
397 return "";
398 }
399 string granularity = runRange->getGranularity();
400 dir->cd();
401 return granularity;
402}
403
404void CalibrationAlgorithm::updateDBObjPtrs(const unsigned int event = 1, const int run = 0, const int experiment = 0)
405{
406 // Construct an EventMetaData object but NOT in the Datastore
407 EventMetaData emd(event, run, experiment);
408 // Explicitly update while avoiding registering a Datastore object
410 // Also update the intra-run objects to the event at the same time (maybe unnessary...)
412}
413
414// Have to put the explicit template specialization in the enclosing namespace
415namespace Belle2 {
423 template<>
424 shared_ptr<TTree> CalibrationAlgorithm::getObjectPtr<TTree>(const string& name,
425 const vector<ExpRun>& requestedRuns)
426 {
427 // Check if this object already exists
428 RunRange runRangeRequested(requestedRuns);
429 std::shared_ptr<TTree> objOutputPtr = std::dynamic_pointer_cast<TTree>(m_data.getCalibObj(name, runRangeRequested));
430 if (objOutputPtr)
431 return objOutputPtr;
432
433 // If not we best make a new one
434 shared_ptr<TChain> chain = make_shared<TChain>(name.c_str());
435 chain->SetDirectory(0);
436 // Construct the TDirectory names where we expect our objects to be
437 string runRangeObjName(getPrefix() + "/" + RUN_RANGE_OBJ_NAME);
438
439 if (strcmp(getGranularity().c_str(), "run") == 0) {
440 // Loop over our runs requested for the right files
441 for (auto expRunRequested : requestedRuns) {
442 // Find the relevant files for this ExpRun
443 auto searchFiles = m_runsToInputFiles.find(expRunRequested);
444 if (searchFiles == m_runsToInputFiles.end()) {
445 B2WARNING("No input file found with data collected from run "
446 "(" << expRunRequested.first << "," << expRunRequested.second << ")");
447 continue;
448 } else {
449 auto files = searchFiles->second;
450 for (auto fileName : files) {
451 RunRange* runRangeData;
452 //Open TFile to get the objects
453 std::unique_ptr<TFile> f;
454 f.reset(TFile::Open(fileName.c_str(), "READ"));
455 runRangeData = dynamic_cast<RunRange*>(f->Get(runRangeObjName.c_str()));
456 // Check that nothing went wrong in the mapping and that this file definitely contains this run's data
457 auto runSet = runRangeData->getExpRunSet();
458 if (runSet.find(expRunRequested) == runSet.end()) {
459 B2WARNING("Something went wrong with the mapping of ExpRun -> Input Files. "
460 "(" << expRunRequested.first << "," << expRunRequested.second << ") not in " << fileName);
461 }
462 // Get the path/directory of the Exp,Run TDirectory that holds the object(s)
463 std::string objDirName = getFullObjectPath(name, expRunRequested);
464 TDirectory* objDir = f->GetDirectory(objDirName.c_str());
465 if (!objDir) {
466 B2ERROR("Directory for requested object " << name << " not found: " << objDirName);
467 return nullptr;
468 }
469 // Find all the objects inside, there may be more than one
470 for (auto key : * (objDir->GetListOfKeys())) {
471 string keyName = key->GetName();
472 string objectPath = fileName + "/" + objDirName + "/" + keyName;
473 B2DEBUG(29, "Adding TTree " << objectPath);
474 chain->Add(objectPath.c_str());
475 }
476 }
477 }
478 }
479 } else {
480 ExpRun allGranExpRun = getAllGranularityExpRun();
481 string objDirName = getFullObjectPath(name, allGranExpRun);
482 for (const auto& fileName : m_inputFileNames) {
483 string objectPath = fileName + "/" + objDirName + "/" + name + "_1"; // Only one index for this granularity
484 B2DEBUG(29, "Adding TTree " << objectPath);
485 chain->Add(objectPath.c_str());
486 }
487 }
488 if (!chain->GetListOfFiles()->GetEntries()) {
489 B2ERROR("No data found for object " << name);
490 return nullptr;
491 }
492 objOutputPtr = static_pointer_cast<TTree>(chain);
493 // make a TNamed version to input to the map of previous calib objects
494 shared_ptr<TNamed> storedObjPtr = static_pointer_cast<TNamed>(objOutputPtr);
495 m_data.setCalibObj(name, runRangeRequested, storedObjPtr);
496 B2DEBUG(29, "Passing back merged data " << name);
497 return objOutputPtr;
498 }
500}
501
502bool CalibrationAlgorithm::loadInputJson(const std::string& jsonString)
503{
504 try {
505 auto jsonInput = nlohmann::json::parse(jsonString);
506 // Input string has an object (dict) as the top level object?
507 if (jsonInput.is_object()) {
508 m_jsonExecutionInput = jsonInput;
509 return true;
510 } else {
511 B2ERROR("JSON input string isn't an object type i.e. not a '{}' at the top level.");
512 return false;
513 }
514 } catch (nlohmann::json::parse_error&) {
515 B2ERROR("Parsing of JSON input string failed");
516 return false;
517 }
518}
519
520const std::vector<ExpRun> CalibrationAlgorithm::findPayloadBoundaries(std::vector<ExpRun> runs, int iteration)
521{
522 m_boundaries.clear();
523 if (m_inputFileNames.empty()) {
524 B2ERROR("There aren't any input files set. Please use CalibrationAlgorithm::setInputFiles()");
525 return m_boundaries;
526 }
527 // Reset the internal execution data just in case something is hanging around
528 m_data.reset();
529 if (runs.empty()) {
530 // Want to loop over all runs we could possibly know about
531 runs = getRunListFromAllData();
532 }
533 // Let's check that we have some now
534 if (runs.empty()) {
535 B2ERROR("No collected data in input files.");
536 return m_boundaries;
537 }
538 // In order to find run boundaries we must have collected with data granularity == 'run'
539 if (strcmp(getGranularity().c_str(), "all") == 0) {
540 B2ERROR("The data is collected with granularity='all' (exp=-1,run=-1), and we can't use that to find run boundaries.");
541 return m_boundaries;
542 }
543 m_data.setIteration(iteration);
544 // User defined setup function
545 boundaryFindingSetup(runs, iteration);
546 std::vector<ExpRun> runList;
547 // Loop over run list and call derived class "isBoundaryRequired" member function
548 for (auto currentRun : runs) {
549 runList.push_back(currentRun);
550 m_data.setRequestedRuns(runList);
551 // After here, the getObject<...>(...) helpers start to work
552 if (isBoundaryRequired(currentRun)) {
553 m_boundaries.push_back(currentRun);
554 }
555 // Only want run-by-run
556 runList.clear();
557 // Don't want memory hanging around
559 }
560 m_data.reset();
562 return m_boundaries;
563}
void setResult(EResult result)
Setter for current iteration.
void setRequestedIov(const IntervalOfValidity &iov=IntervalOfValidity(0, 0, -1, -1))
Sets the requested IoV for this execution, based on the.
void setCalibObj(const std::string &name, const RunRange &runRange, const std::shared_ptr< TNamed > &objectPtr)
Insert a newly created object in m_mapCalibData. Overwrites a previous entry if one exists.
void setRequestedRuns(const std::vector< Calibration::ExpRun > &requestedRuns)
Sets the vector of ExpRuns.
void setIteration(int iteration)
Setter for current iteration.
EResult getResult() const
Getter for current result.
void reset()
Resets this class back to what is needed at the beginning of an execution.
std::shared_ptr< TNamed > getCalibObj(const std::string &name, const RunRange &runRange) const
Get a previously created object in m_mapCalibData if one exists, otherwise return shared_ptr(nullptr)
void clearCalibrationData()
Clear calibration data.
const IntervalOfValidity & getRequestedIov() const
Getter for requested IOV.
std::list< Database::DBImportQuery > & getPayloads()
Get constants (in TObjects) for database update from last execution.
std::string getExpRunString(Calibration::ExpRun &expRun) const
Gets the "exp.run" string repr. of (exp,run)
RunRange getRunRangeFromAllData() const
Get the complete RunRange from inspection of collected data.
IntervalOfValidity getIovFromAllData() const
Get the complete IoV from inspection of collected data.
void saveCalibration(TClonesArray *data, const std::string &name)
Store DBArray payload with given name with default IOV.
bool checkPyExpRun(PyObject *pyObj)
Checks that a PyObject can be successfully converted to an ExpRun type.
static const Calibration::ExpRun m_allExpRun
allExpRun
void updateDBObjPtrs(const unsigned int event, const int run, const int experiment)
Updates any DBObjPtrs by calling update(event) for DBStore.
std::vector< Calibration::ExpRun > m_boundaries
When using the boundaries functionality from isBoundaryRequired, this is used to store the boundaries...
PyObject * getInputFileNames()
Get the input file names used for this algorithm and pass them out as a Python list of unicode string...
EResult execute(std::vector< Calibration::ExpRun > runs={}, int iteration=0, IntervalOfValidity iov=IntervalOfValidity())
Runs calibration over vector of runs for a given iteration.
std::vector< Calibration::ExpRun > getRunListFromAllData() const
Get the complete list of runs from inspection of collected data.
Calibration::ExpRun getAllGranularityExpRun() const
Returns the Exp,Run pair that means 'Everything'. Currently unused.
virtual void boundaryFindingTearDown()
Put your algorithm back into a state ready for normal execution if you need to.
std::string getFullObjectPath(const std::string &name, Calibration::ExpRun expRun) const
constructs the full TDirectory + Key name of an object in a TFile based on its name and exprun
virtual void boundaryFindingSetup(std::vector< Calibration::ExpRun >, int)
If you need to make some changes to your algorithm class before 'findPayloadBoundaries' is run,...
std::string getPrefix() const
Get the prefix used for getting calibration data.
std::vector< std::string > m_inputFileNames
List of input files to the Algorithm, will initially be user defined but then gets the wildcards expa...
EResult
The result of calibration.
@ c_Failure
Failed =3 in Python.
@ c_Undefined
Not yet known (before execution) =4 in Python.
std::string m_granularityOfData
Granularity of input data. This only changes when the input files change so it isn't specific to an e...
nlohmann::json m_jsonExecutionInput
Optional input JSON object used to make decisions about how to execute the algorithm code.
void setInputFileNames(PyObject *inputFileNames)
Set the input file names used for this algorithm from a Python list.
const std::vector< Calibration::ExpRun > findPayloadBoundaries(std::vector< Calibration::ExpRun > runs, int iteration=0)
Used to discover the ExpRun boundaries that you want the Python CAF to execute on....
virtual bool isBoundaryRequired(const Calibration::ExpRun &)
Given the current collector data, make a decision about whether or not this run should be the start o...
std::map< Calibration::ExpRun, std::vector< std::string > > m_runsToInputFiles
Map of Runs to input files. Gets filled when you call getRunRangeFromAllData, gets cleared when setti...
bool loadInputJson(const std::string &jsonString)
Load the m_inputJson variable from a string (useful from Python interface). The rturn bool indicates ...
std::string getGranularityFromData() const
Get the granularity of collected data.
void fillRunToInputFilesMap()
Fill the mapping of ExpRun -> Files.
bool commit()
Submit constants from last calibration into database.
virtual EResult calibrate()=0
Run algo on data - pure virtual: needs to be implemented.
Calibration::ExpRun convertPyExpRun(PyObject *pyObj)
Performs the conversion of PyObject to ExpRun.
std::string getGranularity() const
Get the granularity of collected data.
ExecutionData m_data
Data specific to a SINGLE execution of the algorithm. Gets reset at the beginning of execution.
static std::string objectName(const TClass *t, const std::string &name)
Return the storage name for an object of the given TClass and name.
Definition: DataStore.cc:151
Store event, run, and experiment numbers.
Definition: EventMetaData.h:33
A class that describes the interval of experiments/runs for which an object in the database is valid.
Mergeable object holding (unique) set of (exp,run) pairs.
Definition: RunRange.h:25
virtual void merge(const RunRange *other)
Implementation of merging - other is added to the set (union)
Definition: RunRange.h:52
std::string getGranularity() const
Gets the m_granularity.
Definition: RunRange.h:110
IntervalOfValidity getIntervalOfValidity()
Make IntervalOfValidity from the set, spanning all runs. Works because sets are sorted by default.
Definition: RunRange.h:70
const std::set< Calibration::ExpRun > & getExpRunSet()
Get access to the stored set.
Definition: RunRange.h:64
static Database & Instance()
Instance of a singleton Database.
Definition: Database.cc:42
static DBStore & Instance()
Instance of a singleton DBStore.
Definition: DBStore.cc:28
bool storeData(const std::string &name, TObject *object, const IntervalOfValidity &iov)
Store an object in the database.
Definition: Database.cc:141
void updateEvent()
Updates all intra-run dependent objects.
Definition: DBStore.cc:142
void update()
Updates all objects that are outside their interval of validity.
Definition: DBStore.cc:79
Scalar convertPythonObject(const boost::python::object &pyObject, Scalar)
Convert from Python to given type.
std::vector< std::string > expandWordExpansions(const std::vector< std::string > &filenames)
Performs wildcard expansion using wordexp(), returns matches.
Abstract base class for different kinds of events.
STL namespace.
Struct containing exp number and run number.
Definition: Splitter.h:51