Belle II Software development
eclBhabhaTAlgorithm Class Reference

Calibrate ecl crystals using bhabha events. More...

#include <eclBhabhaTAlgorithm.h>

Inheritance diagram for eclBhabhaTAlgorithm:
CalibrationAlgorithm

Public Types

enum  EResult {
  c_OK ,
  c_Iterate ,
  c_NotEnoughData ,
  c_Failure ,
  c_Undefined
}
 The result of calibration. More...
 

Public Member Functions

 eclBhabhaTAlgorithm ()
 ..Constructor
 
 ~eclBhabhaTAlgorithm () override
 ..Destructor
 
const std::string & getPrefix () const
 Get the prefix used for getting calibration data.
 
const std::string & getCollectorName () const
 Alias for prefix.
 
void setPrefix (const std::string &prefix)
 Set the prefix used to identify datastore objects.
 
void setInputFileNames (PyObject *inputFileNames)
 Set the input file names used for this algorithm from a Python list.
 
PyObject * getInputFileNames ()
 Get the input file names used for this algorithm and pass them out as a Python list of unicode strings.
 
std::vector< Calibration::ExpRun > getRunListFromAllData () const
 Get the complete list of runs from inspection of collected data.
 
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 fillRunToInputFilesMap ()
 Fill the mapping of ExpRun -> Files.
 
const std::string & getGranularity () const
 Get the granularity of collected data.
 
EResult execute (std::vector< Calibration::ExpRun > runs={}, int iteration=0, IntervalOfValidity iov=IntervalOfValidity())
 Runs calibration over vector of runs for a given iteration.
 
EResult execute (PyObject *runs, int iteration=0, IntervalOfValidity iov=IntervalOfValidity())
 Runs calibration over Python list of runs. Converts to C++ and then calls the other execute() function.
 
std::list< Database::DBImportQuery > & getPayloads ()
 Get constants (in TObjects) for database update from last execution.
 
std::list< Database::DBImportQuerygetPayloadValues () const
 Get constants (in TObjects) for database update from last execution but passed by VALUE.
 
bool commit ()
 Submit constants from last calibration into database.
 
bool commit (std::list< Database::DBImportQuery > payloads)
 Submit constants from a (potentially previous) set of payloads.
 
const std::string & getDescription () const
 Get the description of the algorithm (set by developers in constructor)
 
bool loadInputJson (const std::string &jsonString)
 Load the m_inputJson variable from a string (useful from Python interface). The return bool indicates success or failure.
 
const std::string dumpOutputJson () const
 Dump the JSON string of the output JSON object.
 
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. This is optional and only used in some.
 
template<>
std::shared_ptr< TTree > getObjectPtr (const std::string &name, const std::vector< Calibration::ExpRun > &requestedRuns)
 Specialization of getObjectPtr<TTree>.
 

Static Public Member Functions

static bool checkPyExpRun (PyObject *pyObj)
 Checks that a PyObject can be successfully converted to an ExpRun type.
 
static Calibration::ExpRun convertPyExpRun (PyObject *pyObj)
 Performs the conversion of PyObject to ExpRun.
 

Public Attributes

int cellIDLo = 0
 Fit crystals with cellID0 in the inclusive range [cellIDLo,cellIDHi].
 
int cellIDHi = 0
 Fit crystals with cellID0 in the inclusive range [cellIDLo,cellIDHi].
 
double meanCleanRebinFactor = 0.0
 Rebinning factor for mean calculation.
 
double meanCleanCutMinFactor = 0.0
 After rebinning, create a mask for bins that have values less than meanCleanCutMinFactor times the maximum bin value.
 
int crateIDLo = 0
 Fit crates with crateID0 in the inclusive range [crateIDLo,crateIDHi].
 
int crateIDHi = 0
 Fit crates with crateID0 in the inclusive range [crateIDLo,crateIDHi].
 
bool savePrevCrysPayload = false
 Save the previous crystal payload values for comparison.
 
bool readPrevCrysPayload = false
 Read the previous crystal payload values for comparison.
 
bool debugOutput = false
 Save every histogram and fitted function to debugFilename.
 
std::string debugFilenameBase
 Name of file with debug output, eclBhabhaTAlgorithm.root by default.
 
std::string collectorName
 Name of the collector.
 
int refCrysPerCrate [52] = {}
 List of crystals, one per crate, used as reference time for crystal time calibration.
 

Protected Member Functions

EResult calibrate () override
 ..Run algorithm on events
 
void setInputFileNames (const std::vector< std::string > &inputFileNames)
 Set the input file names used for this algorithm.
 
virtual bool isBoundaryRequired (const Calibration::ExpRun &)
 Given the current collector data, make a decision about whether or not this run should be the start of a payload boundary.
 
virtual void boundaryFindingSetup (std::vector< Calibration::ExpRun >, int)
 If you need to make some changes to your algorithm class before 'findPayloadBoundaries' is run, make them in this function.
 
virtual void boundaryFindingTearDown ()
 Put your algorithm back into a state ready for normal execution if you need to.
 
const std::vector< Calibration::ExpRun > & getRunList () const
 Get the list of runs for which calibration is called.
 
int getIteration () const
 Get current iteration.
 
const std::vector< std::string > & getVecInputFileNames () const
 Get the input file names used for this algorithm as a STL vector.
 
template<class T>
std::shared_ptr< T > getObjectPtr (const std::string &name, const std::vector< Calibration::ExpRun > &requestedRuns)
 Get calibration data object by name and list of runs, the Merge function will be called to generate the overall object.
 
template<class T>
std::shared_ptr< T > getObjectPtr (std::string name)
 Get calibration data object (for all runs the calibration is requested for) This function will only work during or after execute() has been called once.
 
template<>
shared_ptr< TTree > getObjectPtr (const string &name, const vector< ExpRun > &requestedRuns)
 We cheekily cast the TChain to TTree for the returned pointer so that the user never knows Hopefully this doesn't cause issues if people do low level stuff to the tree...
 
std::string getGranularityFromData () const
 Get the granularity of collected data.
 
void saveCalibration (TClonesArray *data, const std::string &name)
 Store DBArray payload with given name with default IOV.
 
void saveCalibration (TClonesArray *data, const std::string &name, const IntervalOfValidity &iov)
 Store DBArray with given name and custom IOV.
 
void saveCalibration (TObject *data)
 Store DB payload with default name and default IOV.
 
void saveCalibration (TObject *data, const IntervalOfValidity &iov)
 Store DB payload with default name and custom IOV.
 
void saveCalibration (TObject *data, const std::string &name)
 Store DB payload with given name with default IOV.
 
void saveCalibration (TObject *data, const std::string &name, const IntervalOfValidity &iov)
 Store DB payload with given name and custom IOV.
 
void setDescription (const std::string &description)
 Set algorithm description (in constructor)
 
void clearCalibrationData ()
 Clear calibration data.
 
void resetInputJson ()
 Clears the m_inputJson member variable.
 
void resetOutputJson ()
 Clears the m_outputJson member variable.
 
template<class T>
void setOutputJsonValue (const std::string &key, const T &value)
 Set a key:value pair for the outputJson object, expected to used internally during calibrate()
 
template<class T>
const T getOutputJsonValue (const std::string &key) const
 Get a value using a key from the JSON output object, not sure why you would want to do this.
 
template<class T>
const T getInputJsonValue (const std::string &key) const
 Get an input JSON value using a key. The normal exceptions are raised when the key doesn't exist.
 
const nlohmann::json & getInputJsonObject () const
 Get the entire top level JSON object. We explicitly say this must be of object type so that we might pick.
 
bool inputJsonKeyExists (const std::string &key) const
 Test for a key in the input JSON object.
 

Static Protected Member Functions

static void updateDBObjPtrs (const unsigned int event, const int run, const int experiment)
 Updates any DBObjPtrs by calling update(event) for DBStore.
 
static Calibration::ExpRun getAllGranularityExpRun ()
 Returns the Exp,Run pair that means 'Everything'. Currently unused.
 

Protected Attributes

std::vector< Calibration::ExpRun > m_boundaries
 When using the boundaries functionality from isBoundaryRequired, this is used to store the boundaries. It is cleared when.
 

Private Member Functions

std::string getExpRunString (Calibration::ExpRun &expRun) const
 Gets the "exp.run" string repr. of (exp,run)
 
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
 

Private Attributes

std::vector< std::string > m_inputFileNames
 List of input files to the Algorithm, will initially be user defined but then gets the wildcards expanded during execute()
 
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 setting input files again.
 
std::string m_granularityOfData
 Granularity of input data. This only changes when the input files change so it isn't specific to an execution.
 
ExecutionData m_data
 Data specific to a SINGLE execution of the algorithm. Gets reset at the beginning of execution.
 
std::string m_description {""}
 Description of the algorithm.
 
std::string m_prefix {""}
 The name of the TDirectory the collector objects are contained within.
 
nlohmann::json m_jsonExecutionInput = nlohmann::json::object()
 Optional input JSON object used to make decisions about how to execute the algorithm code.
 
nlohmann::json m_jsonExecutionOutput = nlohmann::json::object()
 Optional output JSON object that can be set during the execution by the underlying algorithm code.
 

Static Private Attributes

static const Calibration::ExpRun m_allExpRun = make_pair(-1, -1)
 allExpRun
 

Detailed Description

Calibrate ecl crystals using bhabha events.

Definition at line 25 of file eclBhabhaTAlgorithm.h.

Member Enumeration Documentation

◆ EResult

enum EResult
inherited

The result of calibration.

Enumerator
c_OK 

Finished successfully =0 in Python.

c_Iterate 

Needs iteration =1 in Python.

c_NotEnoughData 

Needs more data =2 in Python.

c_Failure 

Failed =3 in Python.

c_Undefined 

Not yet known (before execution) =4 in Python.

Definition at line 40 of file CalibrationAlgorithm.h.

40 {
41 c_OK,
42 c_Iterate,
43 c_NotEnoughData,
44 c_Failure,
45 c_Undefined
46 };

Constructor & Destructor Documentation

◆ eclBhabhaTAlgorithm()

..Constructor

Definition at line 36 of file eclBhabhaTAlgorithm.cc.

36 :
37 // Parameters
38 CalibrationAlgorithm("ECLBhabhaTCollector"),
39 cellIDLo(1),
43 crateIDLo(1),
44 crateIDHi(52),
47 debugOutput(true),
48 debugFilenameBase("eclBhabhaTAlgorithm"), // base of filename (without ".root")
49 collectorName("ECLBhabhaTCollector"),
50 refCrysPerCrate{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
51 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
52 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
53 -1, -1, -1, -1, -1, -1, -1} //,
54{
55 setDescription("Calculate time offsets from bhabha events by fitting gaussian function to the (t - T0) difference.");
56}
void setDescription(const std::string &description)
Set algorithm description (in constructor)
CalibrationAlgorithm(const std::string &collectorModuleName)
Constructor - sets the prefix for collected objects (won't be accesses until execute(....
int crateIDHi
Fit crates with crateID0 in the inclusive range [crateIDLo,crateIDHi].
int cellIDHi
Fit crystals with cellID0 in the inclusive range [cellIDLo,cellIDHi].
int cellIDLo
Fit crystals with cellID0 in the inclusive range [cellIDLo,cellIDHi].
bool debugOutput
Save every histogram and fitted function to debugFilename.
double meanCleanRebinFactor
Rebinning factor for mean calculation.
int crateIDLo
Fit crates with crateID0 in the inclusive range [crateIDLo,crateIDHi].
double meanCleanCutMinFactor
After rebinning, create a mask for bins that have values less than meanCleanCutMinFactor times the ma...
bool savePrevCrysPayload
Save the previous crystal payload values for comparison.
std::string collectorName
Name of the collector.
bool readPrevCrysPayload
Read the previous crystal payload values for comparison.
int refCrysPerCrate[52]
List of crystals, one per crate, used as reference time for crystal time calibration.
std::string debugFilenameBase
Name of file with debug output, eclBhabhaTAlgorithm.root by default.
const int c_NCrystals
Number of crystals.

◆ ~eclBhabhaTAlgorithm()

~eclBhabhaTAlgorithm ( )
inlineoverride

..Destructor

Definition at line 32 of file eclBhabhaTAlgorithm.h.

32{}

Member Function Documentation

◆ boundaryFindingSetup()

virtual void boundaryFindingSetup ( std::vector< Calibration::ExpRun > ,
int  )
inlineprotectedvirtualinherited

If you need to make some changes to your algorithm class before 'findPayloadBoundaries' is run, make them in this function.

Reimplemented in PXDAnalyticGainCalibrationAlgorithm, PXDValidationAlgorithm, SVD3SampleCoGTimeCalibrationAlgorithm, SVD3SampleELSTimeCalibrationAlgorithm, SVDClusterAbsoluteTimeShifterAlgorithm, SVDCoGTimeCalibrationAlgorithm, TestBoundarySettingAlgorithm, and TestCalibrationAlgorithm.

Definition at line 252 of file CalibrationAlgorithm.h.

252{};

◆ boundaryFindingTearDown()

virtual void boundaryFindingTearDown ( )
inlineprotectedvirtualinherited

Put your algorithm back into a state ready for normal execution if you need to.

Definition at line 257 of file CalibrationAlgorithm.h.

257{};

◆ calibrate()

CalibrationAlgorithm::EResult calibrate ( )
overrideprotectedvirtual

..Run algorithm on events

Put root into batch mode so that we don't try to open a graphics window

Write out job parameters


Implements CalibrationAlgorithm.

Definition at line 60 of file eclBhabhaTAlgorithm.cc.

61{
63 gROOT->SetBatch();
64
65
67 B2INFO("eclBhabhaTAlgorithm parameters:");
68 B2INFO("cellIDLo = " << cellIDLo);
69 B2INFO("cellIDHi = " << cellIDHi);
70 B2INFO("meanCleanRebinFactor = " << meanCleanRebinFactor);
71 B2INFO("meanCleanCutMinFactor = " << meanCleanCutMinFactor);
72 B2INFO("crateIDLo = " << crateIDLo);
73 B2INFO("crateIDHi = " << crateIDHi);
74 B2INFO("savePrevCrysPayload = " << savePrevCrysPayload);
75 B2INFO("readPrevCrysPayload = " << readPrevCrysPayload);
76 B2INFO("refCrysPerCrate = {");
77 for (int crateTest = 0; crateTest < 52 - 1; crateTest++) {
78 B2INFO(refCrysPerCrate[crateTest] << ",");
79 }
80 B2INFO(refCrysPerCrate[52 - 1] << "}");
81
82
83 /* Histogram with the data collected by eclBhabhaTCollectorModule */
84
85 auto TimevsCrysPrevCrateCalibPrevCrystCalib = getObjectPtr<TH2F>("TimevsCrysPrevCrateCalibPrevCrystCalib");
86 auto TimevsCratePrevCrateCalibPrevCrystCalib = getObjectPtr<TH2F>("TimevsCratePrevCrateCalibPrevCrystCalib");
87 auto TimevsCrysNoCalibrations = getObjectPtr<TH2F>("TimevsCrysNoCalibrations");
88 auto TimevsCrysPrevCrateCalibNoCrystCalib = getObjectPtr<TH2F>("TimevsCrysPrevCrateCalibNoCrystCalib");
89 auto TimevsCrateNoCrateCalibPrevCrystCalib = getObjectPtr<TH2F>("TimevsCrateNoCrateCalibPrevCrystCalib");
90
91 // Collect other plots just for reference - combines all the runs for these plots.
92 auto cutflow = getObjectPtr<TH1F>("cutflow");
93 auto svdEventT0 = getObjectPtr<TH1D>("svdEventT0");
94
95
96 // Define new plots to make
97 // New calibration constant values minus older values from previous iteration plotted as a function of the crystal or crate id
98 unique_ptr<TH1F> tsNew_MINUS_tsOld__cid(new TH1F("TsNew_MINUS_TsOld__cid",
99 ";cell id; ts(new|bhabha) - ts(previous iteration|merged) [ns]", ECLElementNumbers::c_NCrystals,
101 unique_ptr<TH1F> tcrateNew_MINUS_tcrateOld__crateID(new TH1F("tcrateNew_MINUS_tcrateOld__crateID",
102 ";crate id; tcrate(new | bhabha) - tcrate(previous iteration | merged) [ns]",
103 52, 1, 52 + 1));
104 unique_ptr<TH1F> tsNew_MINUS_tsCustomPrev__cid(new TH1F("TsNew_MINUS_TsCustomPrev__cid",
105 ";cell id; ts(new|bhabha) - ts(old = 'before 1st iter'|merged) [ns]",
107 unique_ptr<TH1F> tsNew_MINUS_tsOldBhabha__cid(new TH1F("TsNew_MINUS_TsOldBhabha__cid",
108 ";cell id; ts(new|bhabha) - ts(previous iteration|bhabha) [ns]", ECLElementNumbers::c_NCrystals,
110
111
112 // Histogram of the new time constant values minus values from previous iteration
113 unique_ptr<TH1F> tsNew_MINUS_tsOld(new TH1F("TsNew_MINUS_TsOld",
114 ";ts(new | bhabha) - ts(previous iteration | merged) [ns];Number of crystals",
115 201, -10.05, 10.05));
116 unique_ptr<TH1F> tcrateNew_MINUS_tcrateOld(new TH1F("tcrateNew_MINUS_tcrateOld",
117 ";tcrate(new) - tcrate(previous iteration) [ns];Number of crates",
118 201, -10.05, 10.05));
119 unique_ptr<TH1F> tsNew_MINUS_tsCustomPrev(new TH1F("TsNew_MINUS_TsCustomPrev",
120 ";ts(new | bhabha) - ts(old = 'before 1st iter' | merged) [ns];Number of crystals",
121 285, -69.5801, 69.5801));
122 unique_ptr<TH1F> tsNew_MINUS_tsOldBhabha(new TH1F("TsNew_MINUS_TsOldBhabha",
123 ";ts(new | bhabha) - ts(previous iteration | bhabha) [ns];Number of crystals",
124 201, -10.05, 10.05));
125
126
127
128 // Histograms just for crates and collecting for all the different runs rather than run by run.
129 unique_ptr<TH1F> tcrateNew_MINUS_tcrateOld_allRuns(new TH1F("tcrateNew_MINUS_tcrateOld_allRuns",
130 "Crate time constant changes over all runs : tcrate(new) uncertainty < 0.1ns;tcrate(new) - tcrate(previous iteration) [ns];Number of crates",
131 201, -10.05, 10.05));
132
133 unique_ptr<TH1F> tcrateNew_MINUS_tcrateOld_allRuns_allCrates(new TH1F("tcrateNew_MINUS_tcrateOld_allRuns_allCrates",
134 "Crate time constant changes over all runs : all crates;tcrate(new) - tcrate(previous iteration) [ns];Number of crates",
135 201, -10.05, 10.05));
136
137 unique_ptr<TH1I> num_tcrates_perRun(new TH1I("num_tcrates_perRun",
138 "Number of good tcrates in each run;Run number;Number of good tcrates",
139 6000, 0, 6000));
140
141 unique_ptr<TH2F> tcrateNew_MINUS_tcrateOld__vs__runNum(new TH2F("tcrateNew_MINUS_tcrateOld__vs__runNum",
142 "Crate time constant changes vs run number : tcrate(new) uncertainty < 0.1ns;Run number;tcrate(new) - tcrate(previous iteration) [ns]",
143 6000, 0, 6000, 21, -10.5, 10.5));
144
145
146
147
148
149 if (!TimevsCrysNoCalibrations) return c_Failure;
150
152
153 TFile* histfile = 0;
154 TFile* histExtraCrateInfofile = 0; // Only created if needed for crates
155
156
157 unique_ptr<TTree> tree_crystal(new TTree("tree_crystal", "Debug data from bhabha time calibration algorithm for crystals"));
158
159 unique_ptr<TTree> tree_crate(new TTree("tree_crate", "Debug data from bhabha time calibration algorithm for crates"));
160 int tree_cid;
161
162 // Vector of time offsets to be saved in the database.
163 vector<float> t_offsets;
164 // Vector of time offset uncertainties to be saved in the database.
165 vector<float> t_offsets_unc;
166 vector<float> t_offsets_prev; // previous time offsets
167
168
169 int minNumEntries = 40;
170 int minNumEntriesCrateConvergence = 1000;
171
172
173 double mean = 0;
174 double sigma = -1;
175 double mean_unc = 0;
176 int crystalCalibSaved = 0;
177 double tsPrev = 0;
178
179
180 bool minRunNumBool = false;
181 bool maxRunNumBool = false;
182 int minRunNum = -1;
183 int maxRunNum = -1;
184 int minExpNum = -1;
185 int maxExpNum = -1;
186 for (auto expRun : getRunList()) {
187 int expNumber = expRun.first;
188 int runNumber = expRun.second;
189 if (!minRunNumBool) {
190 minExpNum = expNumber;
191 minRunNum = runNumber;
192 minRunNumBool = true;
193 }
194 if (!maxRunNumBool) {
195 maxExpNum = expNumber;
196 maxRunNum = runNumber;
197 maxRunNumBool = true;
198 }
199 if (((minRunNum > runNumber) && (minExpNum >= expNumber)) ||
200 (minExpNum > expNumber)) {
201 minExpNum = expNumber;
202 minRunNum = runNumber;
203 }
204 if (((maxRunNum < runNumber) && (maxExpNum <= expNumber)) ||
205 (maxExpNum < expNumber))
206
207 {
208 maxExpNum = expNumber;
209 maxRunNum = runNumber;
210 }
211 }
212
213 B2INFO("debugFilenameBase = " << debugFilenameBase);
214 string runNumsString = string("_") + to_string(minExpNum) + "_" + to_string(minRunNum) + string("-") +
215 to_string(maxExpNum) + "_" + to_string(maxRunNum);
216 string debugFilename = debugFilenameBase + runNumsString + string(".root");
217 string extraCratedebugFilename = debugFilenameBase + string("_cratesAllRuns.root");
218
219
220 // Need to load information about the event/run/experiment to get the right database information
221 // Will be used for:
222 // * ECLChannelMapper (to map crystal to crates)
223 // * crystal payload updating for iterating crystal and crate fits
224 int eventNumberForCrates = 1;
225
226 StoreObjPtr<EventMetaData> evtPtr;
227 // simulate the initialize() phase where we can register objects in the DataStore
229 evtPtr.registerInDataStore();
231 // now construct the event metadata
232 evtPtr.construct(eventNumberForCrates, minRunNum, minExpNum);
233 // and update the database contents
234 DBStore& dbstore = DBStore::Instance();
235 dbstore.update();
236 // this is only needed it the payload might be intra-run dependent,
237 // that is if it might change during one run as well
238 dbstore.updateEvent();
239
240
241 B2INFO("Uploading payload for exp " << minExpNum << ", run " << minRunNum << ", event " << eventNumberForCrates);
242 updateDBObjPtrs(eventNumberForCrates, minRunNum, minExpNum);
243 unique_ptr<ECLChannelMapper> crystalMapper(new ECL::ECLChannelMapper());
244 crystalMapper->initFromDB();
245
246
247 //------------------------------------------------------------------------
248 //..Read payloads from database
249 B2INFO("Reading payloads: ECLCrystalTimeOffset and ECLCrateTimeOffset");
250 DBObjPtr<Belle2::ECLCrystalCalib> crystalTimeObject("ECLCrystalTimeOffset");
251 DBObjPtr<Belle2::ECLCrystalCalib> crateTimeObject("ECLCrateTimeOffset");
252
253 //..Get vectors of values from the payloads
254 vector<float> currentValuesCrys = crystalTimeObject->getCalibVector();
255 vector<float> currentUncCrys = crystalTimeObject->getCalibUncVector();
256 vector<float> currentValuesCrate = crateTimeObject->getCalibVector();
257 vector<float> currentUncCrate = crateTimeObject->getCalibUncVector();
258
259 //..Print out a few values for quality control
260 B2INFO("Values read from database. Write out for their values for comparison against those from tcol");
261 for (int ic = 0; ic < ECLElementNumbers::c_NCrystals; ic += 500) {
262 B2INFO("ts: cellID " << ic + 1 << " " << currentValuesCrys[ic] << " +/- " << currentUncCrys[ic]);
263 B2INFO("tcrate: cellID " << ic + 1 << " " << currentValuesCrate[ic] << " +/- " << currentUncCrate[ic]);
264 }
265
266
267 //..Read in the previous crystal payload values
268 vector<float> prevValuesCrys(ECLElementNumbers::c_NCrystals);
270 DBObjPtr<Belle2::ECLCrystalCalib> customPrevCrystalTimeObject("ECLCrystalTimeOffsetPreviousValues");
271 //..Get vectors of values from the payloads
272 prevValuesCrys = customPrevCrystalTimeObject->getCalibVector();
273
274 //..Print out a few values for quality control
275 B2INFO("Previous values read from database. Write out for their values for comparison against those from tcol");
276 for (int ic = 0; ic < ECLElementNumbers::c_NCrystals; ic += 500) {
277 B2INFO("ts custom previous payload: cellID " << ic + 1 << " " << prevValuesCrys[ic]);
278 }
279 }
280
281
282 //..Read bhabha payloads from database
283 B2INFO("Reading payloads: ECLCrystalTimeOffsetBhabha");
284 DBObjPtr<Belle2::ECLCrystalCalib> crystalBhabhaTimeObject("ECLCrystalTimeOffsetBhabha");
285
286 //..Get vectors of values from the payloads
287 vector<float> currentBhabhaValuesCrys = crystalBhabhaTimeObject->getCalibVector();
288 vector<float> currentBhabhaUncCrys = crystalBhabhaTimeObject->getCalibUncVector();
289
290 //..Print out a few values for quality control
291 for (int ic = 0; ic < ECLElementNumbers::c_NCrystals; ic += 500) {
292 B2INFO("ts bhabha: cellID " << ic + 1 << " " << currentBhabhaValuesCrys[ic] << " +/- " << currentBhabhaUncCrys[ic]);
293 }
294
295
296 //------------------------------------------------------------------------
297 //..Get the reference crystal information
298 auto refCrysIDzeroingCrate = getObjectPtr<TH1F>("refCrysIDzeroingCrate");
299
300 // crystal index for the crystals (one per crate) that is used as the reference crystal. This one has
301 // ts defined as zero. The crystal id runs 1...8636, not starting at 0.
302 B2INFO("Extract reference crystals from collector histogram.");
303 vector <short> crystalIDreferenceUntested;
304 for (int bin = 1; bin <= ECLElementNumbers::c_NCrystals; bin++) {
305 if (refCrysIDzeroingCrate->GetBinContent(bin) > 0.5) {
306 crystalIDreferenceUntested.push_back(bin);
307 }
308 }
309
310 // Output for the user the crystal id to be used as a reference
311 // and also state which crate the crystal is in.
312 B2INFO("Reference crystals to define as having ts=0. Base 1 counting for both crates and crystals");
313 for (long unsigned int crysRefCounter = 0; crysRefCounter < crystalIDreferenceUntested.size(); crysRefCounter++) {
314 int crys_id = crystalIDreferenceUntested[crysRefCounter] ;
315 int crate_id_from_crystal = crystalMapper->getCrateID(crys_id);
316 B2INFO(" crystal " << crys_id << " is a reference for crate " << crate_id_from_crystal);
317 }
318
319 // Check that the reference crystals make sense. There should be exactly one per crate but
320 // since the crystal calibration executes over multiple runs, it is possible that the
321 // reference crystals could change but we don't want to allow this.
322 B2INFO("Checking number of reference crystals");
323 B2INFO("Number of reference crystals = " << crystalIDreferenceUntested.size());
324
325 // Check that there are exactly 52 reference crystals
326 if (crystalIDreferenceUntested.size() != 52) {
327 B2FATAL("The number of reference crystals does not equal 52, which is one per crate");
328 return c_Failure;
329 } else {
330 B2INFO("Number of reference crystals is 52 as required");
331 }
332
333 // Count the number of reference crystals for each crate to make sure that there is exactly
334 // one reference crystal for each crate as defined by the payload/database.
335 // also fill the final vector that maps the crate id to the reference crystal id
336 vector <short> crateIDsNumRefCrystalsUntested(52, 0);
337 vector <short> crystalIDReferenceForZeroTs(52, 0);
338
339 for (long unsigned int crysRefCounter = 0; crysRefCounter < crystalIDreferenceUntested.size(); crysRefCounter++) {
340 int crys_id = crystalIDreferenceUntested[crysRefCounter] ;
341 int crate_id_from_crystal = crystalMapper->getCrateID(crys_id);
342 crateIDsNumRefCrystalsUntested[crate_id_from_crystal - 1]++;
343 crystalIDReferenceForZeroTs[crate_id_from_crystal - 1] = crys_id;
344 }
345 B2INFO("crystalIDReferenceForZeroTs = {");
346 for (int crateTest = 0; crateTest < 52 - 1; crateTest++) {
347 B2INFO(crystalIDReferenceForZeroTs[crateTest] << ",");
348 }
349 B2INFO(crystalIDReferenceForZeroTs[52 - 1] << "}");
350
351
352 // Make sure that there is only one reference crystal per crate as defined by the payload/database
353 for (int crateTest = 0; crateTest < 52; crateTest++) {
354 if (crateIDsNumRefCrystalsUntested[crateTest] != 1) {
355 B2FATAL("Crate " << crateTest + 1 << " (base 1) has " << crateIDsNumRefCrystalsUntested[crateTest] << " reference crystals");
356 return c_Failure;
357 }
358 }
359 B2INFO("All reference crystals are reasonably mapped one crystal to one crate for all crates");
360
361
362
363 B2INFO("Extract reference crystals from algorithm steering script if provided. If user inputs custom values via steering script for this algorithm, they are only applied after all the tests are performed on the values from the histogram and override the histogram valuees. User can adjust just a single crystal if desired. Use -1 to indicate that a crystal is not to be modified. Position of crystal in list determines the crate to which the crystal is meant to be associated.");
364
365 /* Test if the user wants to modify the reference crystals. This will probably be done very rarely,
366 perhaps less than once per year. If the user does want to change one or more reference
367 crystals then perform the checks again to make sure that there is still just one reference crystal
368 per crate after the modifications to the payload values with the user values.*/
369 bool userSetRefCrysPerCrate = false ;
370 for (int crateTest = 0; crateTest < 52; crateTest++) {
371 if (refCrysPerCrate[crateTest] != -1) {
372 crystalIDReferenceForZeroTs[crateTest] = refCrysPerCrate[crateTest] ;
373 B2INFO("Crate " << crateTest + 1 << " (base 1) new reference crystal = " << crystalIDReferenceForZeroTs[crateTest]);
374 userSetRefCrysPerCrate = true ;
375 }
376 }
377 if (userSetRefCrysPerCrate) {
378 B2INFO("User changed reference crystals via steering script");
379
380 // Validate crystals per crate again with the new user set values
381 fill(crateIDsNumRefCrystalsUntested.begin(), crateIDsNumRefCrystalsUntested.end(), 0);
382 for (long unsigned int crysRefCounter = 0; crysRefCounter < 52; crysRefCounter++) {
383 int crys_id = crystalIDReferenceForZeroTs[crysRefCounter] ;
384 int crate_id_from_crystal = crystalMapper->getCrateID(crys_id);
385 crateIDsNumRefCrystalsUntested[crate_id_from_crystal - 1]++;
386 }
387 for (int crateTest = 0; crateTest < 52; crateTest++) {
388 if (crateIDsNumRefCrystalsUntested[crateTest] != 1) {
389 B2FATAL("Crate " << crateTest + 1 << " (base 1) has " << crateIDsNumRefCrystalsUntested[crateTest] << " reference crystals");
390 return c_Failure;
391 }
392 }
393 B2INFO("All reference crystals are reasonably mapped one crystal to one crate for all crates after changes made by user steering script.");
394
395 // Save the information to the payload if there is at least one crate
396 // reference crystal that has been modified by the user steering file
397 ECLReferenceCrystalPerCrateCalib* refCrystalsCalib = new ECLReferenceCrystalPerCrateCalib();
398 refCrystalsCalib->setCalibVector(crystalIDReferenceForZeroTs);
399 saveCalibration(refCrystalsCalib, "ECLReferenceCrystalPerCrateCalib");
400 B2INFO("Created reference crystal per crate payload: ECLReferenceCrystalPerCrateCalib");
401 } else {
402 B2INFO("User did not change reference crystals via steering script");
403 }
404
405
406 //------------------------------------------------------------------------
407 //..Start looking at timing information
408
409 B2INFO("Debug output rootfile: " << debugFilename);
410 histfile = new TFile(debugFilename.c_str(), "recreate");
411
412
413 TimevsCrysPrevCrateCalibPrevCrystCalib ->Write();
414 TimevsCratePrevCrateCalibPrevCrystCalib->Write();
415 TimevsCrysNoCalibrations ->Write();
416 TimevsCrysPrevCrateCalibNoCrystCalib ->Write();
417 TimevsCrateNoCrateCalibPrevCrystCalib ->Write();
418
419 cutflow->Write();
420 svdEventT0->Write();
421
422
423 if (debugOutput) {
424 tree_crystal->Branch("cid", &tree_cid)->SetTitle("Cell ID, 1..8736");
425 tree_crystal->Branch("ts", &mean)->SetTitle("Time offset mean, ts, ns");
426 tree_crystal->Branch("tsUnc", &mean_unc)->SetTitle("Error of time ts mean, ns.");
427 tree_crystal->Branch("tsSigma", &sigma)->SetTitle("Sigma of time ts distribution, ns");
428 tree_crystal->Branch("crystalCalibSaved",
429 &crystalCalibSaved)->SetTitle("0=crystal skipped, 1=crystal calib saved (num entries based)");
430 tree_crystal->Branch("tsPrev", &tsPrev)->SetTitle("Previous crystal time offset, ts, ns");
431 tree_crystal->SetAutoSave(10);
432 }
433
434
435 double hist_tmin = TimevsCrysNoCalibrations->GetYaxis()->GetXmin();
436 double hist_tmax = TimevsCrysNoCalibrations->GetYaxis()->GetXmax();
437
438 double time_fit_min = hist_tmax; // Set min value to largest possible value so that it gets reset
439 double time_fit_max = hist_tmin; // Set max value to smallest possible value so that it gets reset
440
441 B2INFO("hist_tmin = " << hist_tmin);
442 B2INFO("hist_tmax = " << hist_tmax);
443
444 /* 1/(4fRF) = 0.4913 ns/clock tick, where fRF is the accelerator RF frequency.
445 Same for all crystals. */
446 const double TICKS_TO_NS = 1.0 / (4.0 * EclConfiguration::getRF()) * 1e3;
447
448 // The ts and tcrate database values are filled once per tcol instance so count the number of times that the database values
449 // were summed together by the histogram merging process and extract out the original values again.
450 auto databaseCounter = getObjectPtr<TH1I>("databaseCounter");
451 float numTimesFilled = databaseCounter->GetBinContent(1);
452 B2INFO("Number of times database histograms were merged = " << numTimesFilled);
453
454
455 auto TsDatabase = getObjectPtr<TH1F>("TsDatabase");
456 auto TsDatabaseUnc = getObjectPtr<TH1F>("TsDatabaseUnc");
457 for (int i = 1; i <= ECLElementNumbers::c_NCrystals; i++) {
458 t_offsets.push_back(TsDatabase->GetBinContent(i) / numTimesFilled);
459 t_offsets_prev.push_back(TsDatabase->GetBinContent(i) / numTimesFilled);
460
461 B2INFO("t_offsets_prev (last iter) at crysID " << i << " = " << t_offsets_prev[i - 1]);
462
463 t_offsets_unc.push_back(TsDatabaseUnc->GetBinContent(i) / numTimesFilled);
464 }
465
466
467 /* CRYSTAL CORRECTIONS */
468
469 /* Make a 1D histogram of the number of hits per crystal. This will help with the validations
470 to make sure that all the crystals had enough hits and to look for problems.*/
471 TH1D* h_crysHits = TimevsCrysPrevCrateCalibNoCrystCalib->ProjectionX("h_crysHits");
472 h_crysHits->SetTitle("Hits per crystal;Crystal id");
473
474 histfile->WriteTObject(h_crysHits, "h_crysHits");
475
476
477 // Loop over all the crystals for doing the crystal calibation
478 for (int crys_id = cellIDLo; crys_id <= cellIDHi; crys_id++) {
479 crystalCalibSaved = 0;
480
481 double database_mean = 0;
482 double database_mean_unc = 0;
483
484 B2INFO("Crystal id = " << crys_id);
485
486
487
488
489 /* Determining which bins to mask out for mean calculation
490 */
491
492 TH1D* h_time = TimevsCrysPrevCrateCalibNoCrystCalib->ProjectionY((string("h_time_psi__") + to_string(crys_id)).c_str(),
493 crys_id, crys_id);
494 TH1D* h_timeMask = static_cast<TH1D*>(h_time->Clone());
495 TH1D* h_timeMasked = static_cast<TH1D*>(h_time->Clone((string("h_time_psi_masked__") + to_string(crys_id)).c_str()));
496 TH1D* h_timeRebin = static_cast<TH1D*>(h_time->Clone());
497
498 // Do rebinning and cleaning of some bins but only if the user selection values call for it since it slows the code down
500
501 h_timeRebin->Rebin(meanCleanRebinFactor);
502
503 h_timeMask->Scale(0.0); // set all bins to being masked off
504
505 time_fit_min = hist_tmax; // Set min value to largest possible value so that it gets reset
506 time_fit_max = hist_tmin; // Set max value to smallest possible value so that it gets reset
507
508 // Find value of bin with max value
509 double histRebin_max = h_timeRebin->GetMaximum();
510
511 bool maskedOutNonZeroBin = false;
512 // Loop over all bins to find those with content less than a certain threshold. Mask the non-rebinned histogram for the corresponding bins
513 for (int bin = 1; bin <= h_timeRebin->GetNbinsX(); bin++) {
514 for (int rebinCounter = 1; rebinCounter <= meanCleanRebinFactor; rebinCounter++) {
515 int nonRebinnedBinNumber = (bin - 1) * meanCleanRebinFactor + rebinCounter;
516 if (nonRebinnedBinNumber < h_time->GetNbinsX()) {
517 if (h_timeRebin->GetBinContent(bin) >= histRebin_max * meanCleanCutMinFactor) {
518 h_timeMask->SetBinContent(nonRebinnedBinNumber, 1);
519
520 // Save the lower and upper edges of the rebin histogram time range for fitting purposes
521 double x_lower = h_timeRebin->GetXaxis()->GetBinLowEdge(bin);
522 double x_upper = h_timeRebin->GetXaxis()->GetBinUpEdge(bin);
523 if (x_lower < time_fit_min) {
524 time_fit_min = x_lower;
525 }
526 if (x_upper > time_fit_max) {
527 time_fit_max = x_upper;
528 }
529
530 } else {
531 if (h_time->GetBinContent(nonRebinnedBinNumber) > 0) {
532 B2DEBUG(22, "Setting bin " << nonRebinnedBinNumber << " from " << h_timeMasked->GetBinContent(nonRebinnedBinNumber) << " to 0");
533 maskedOutNonZeroBin = true;
534 }
535 h_timeMasked->SetBinContent(nonRebinnedBinNumber, 0);
536 }
537 }
538 }
539 }
540 B2INFO("Bins with non-zero values have been masked out: " << maskedOutNonZeroBin);
541 h_timeMasked->ResetStats();
542 h_timeMask->ResetStats();
543
544 }
545
546 // Calculate mean from masked histogram
547 double default_meanMasked = h_timeMasked->GetMean();
548 //double default_meanMasked_unc = h_timeMasked->GetMeanError();
549 B2INFO("default_meanMasked = " << default_meanMasked);
550
551
552 // Get the overall mean and standard deviation of the distribution within the plot. This doesn't require a fit.
553 double default_mean = h_time->GetMean();
554 double default_mean_unc = h_time->GetMeanError();
555 double default_sigma = h_time->GetStdDev();
556
557 B2INFO("Fitting crystal between " << time_fit_min << " and " << time_fit_max);
558
559 // gaus(0) is a substitute for [0]*exp(-0.5*((x-[1])/[2])**2)
560 TF1* gaus = new TF1("func", "gaus(0)", time_fit_min, time_fit_max);
561 gaus->SetParNames("numCrystalHitsNormalization", "mean", "sigma");
562 /*
563 gaus->ReleaseParameter(0); // number of crystals
564 gaus->ReleaseParameter(1); // mean
565 gaus->ReleaseParameter(2); // standard deviation
566 */
567
568 double hist_max = h_time->GetMaximum();
569
570 //=== Estimate initial value of sigma as std dev.
571 double stddev = h_time->GetStdDev();
572 sigma = stddev;
573 mean = default_mean;
574
575 //=== Setting parameters for initial iteration
576 gaus->SetParameter(0, hist_max / 2.);
577 gaus->SetParameter(1, mean);
578 gaus->SetParameter(2, sigma);
579 // L -- Use log likelihood method
580 // I -- Use integral of function in bin instead of value at bin center // not using
581 // R -- Use the range specified in the function range
582 // B -- Fix one or more parameters with predefined function // not using
583 // Q -- Quiet mode
584
585 h_timeMasked->Fit(gaus, "LQR"); // L for likelihood, R for x-range, Q for fit quiet mode
586
587 double fit_mean = gaus->GetParameter(1);
588 double fit_mean_unc = gaus->GetParError(1);
589 double fit_sigma = gaus->GetParameter(2);
590
591 double meanDiff = fit_mean - default_mean;
592 double meanUncDiff = fit_mean_unc - default_mean_unc;
593 double sigmaDiff = fit_sigma - default_sigma;
594
595 bool good_fit = false;
596
597 if ((fabs(meanDiff) > 10) ||
598 (fabs(meanUncDiff) > 10) ||
599 (fabs(sigmaDiff) > 10) ||
600 (fit_mean_unc > 0.09) ||
601 (fit_sigma < 0.1) ||
602 (fit_mean < time_fit_min) ||
603 (fit_mean > time_fit_max)) {
604 B2INFO("Crystal id = " << crys_id);
605 B2INFO("fit mean, default mean = " << fit_mean << ", " << default_mean);
606 B2INFO("fit mean unc, default mean unc = " << fit_mean_unc << ", " << default_mean_unc);
607 B2INFO("fit sigma, default sigma = " << fit_sigma << ", " << default_sigma);
608
609 B2INFO("crystal fit mean - hist mean = " << meanDiff);
610 B2INFO("fit mean unc. - hist mean unc. = " << meanUncDiff);
611 B2INFO("fit sigma - hist sigma = " << sigmaDiff);
612
613 B2INFO("fit_mean = " << fit_mean);
614 B2INFO("time_fit_min = " << time_fit_min);
615 B2INFO("time_fit_max = " << time_fit_max);
616
617 if (fabs(meanDiff) > 10) B2INFO("fit mean diff too large");
618 if (fabs(meanUncDiff) > 10) B2INFO("fit mean unc diff too large");
619 if (fabs(sigmaDiff) > 10) B2INFO("fit mean sigma diff too large");
620 if (fit_mean_unc > 0.09) B2INFO("fit mean unc too large");
621 if (fit_sigma < 0.1) B2INFO("fit sigma too small");
622
623 } else {
624 good_fit = true;
625 }
626
627
628
629 // Set the tree_crystal values - ignore fit values !!!!!!!!!!!!!!!!
630 sigma = default_sigma;
631
632
633 int numEntries = h_time->GetEntries();
634 /* If number of entries in histogram is greater than X then use the statistical information from the data otherwise
635 leave crystal uncalibrated. Histograms are still shown though. ALSO require the that fits are good.*/
636 if ((numEntries >= minNumEntries) && good_fit) {
637 crystalCalibSaved = 1;
638 database_mean = fit_mean;
639 database_mean_unc = fit_mean_unc;
640 } else {
641 database_mean = default_mean;
642 database_mean_unc = -fabs(default_mean_unc);
643 }
644
645 if (numEntries < minNumEntries) B2INFO("Number of entries less than minimum");
646 if (numEntries == 0) B2INFO("Number of entries == 0");
647
648
649 tree_cid = crys_id;
650
651 // For the database, convert back from ns to ADC ticks.
652 t_offsets[crys_id - 1] = database_mean / TICKS_TO_NS;
653 t_offsets_unc[crys_id - 1] = database_mean_unc / TICKS_TO_NS;
654
655
656 histfile->WriteTObject(h_time, (string("h_time_psi") + to_string(crys_id)).c_str());
657 histfile->WriteTObject(h_timeMasked, (string("h_time_psi_masked") + to_string(crys_id)).c_str());
658
659 mean = database_mean;
660 mean_unc = database_mean_unc;
661
662 tsPrev = t_offsets_prev[crys_id - 1] * TICKS_TO_NS;
663
664 delete gaus;
665 tree_crystal->Fill();
666 }
667
668
669 // Shift the crystal time calibration constants by the reference crystal calibration constant values
670 if (cellIDLo <= cellIDHi) {
671 vector <double> tsRefCID ;
672 B2INFO("crystal times before shift");
673 for (int crate_id = 1; crate_id <= 52; crate_id++) {
674 tsRefCID.push_back(t_offsets[ crystalIDReferenceForZeroTs[crate_id - 1] - 1 ]);
675 B2INFO("crystal time [crystal = " << crystalIDReferenceForZeroTs[crate_id - 1] << ", crate = " << crate_id << " (base 1)] = " <<
676 t_offsets[ crystalIDReferenceForZeroTs[crate_id - 1] - 1 ] << " ticks");
677 }
678
679 B2INFO("crystal times after shift wrt reference crystal");
680 for (int crys_id = 1; crys_id <= ECLElementNumbers::c_NCrystals; crys_id++) {
681 int crate_id_from_crystal = crystalMapper->getCrateID(crys_id);
682 B2INFO("crystal time before shift [crystal = " << crys_id << ", crate = " << crate_id_from_crystal << " (base 1)] = " <<
683 t_offsets[crys_id - 1] << " +- " << t_offsets_unc[crys_id - 1] << " ticks");
684
685 /* Shift the crystal time constant by that of the reference crystal, but only if
686 there were values to shift. If there were no entries, ts=0 and ts_unc=0, which
687 are special values so do not shift these crystals. */
688 if (t_offsets[crys_id - 1] == 0 && t_offsets_unc[crys_id - 1] == 0) {
689 B2INFO("crystal time after shift [crystal = " << crys_id << ", crate = " << crate_id_from_crystal << " (base 1)] = " <<
690 t_offsets[crys_id - 1] << " ticks. No change because ts=0 and ts_unc=0 (no entries).");
691 } else {
692 t_offsets[crys_id - 1] = t_offsets[crys_id - 1] - tsRefCID[crate_id_from_crystal - 1];
693 B2INFO("crystal time after shift [crystal = " << crys_id << ", crate = " << crate_id_from_crystal << " (base 1)] = " <<
694 t_offsets[crys_id - 1] << " ticks");
695 }
696
697
698 // Fill histograms with the difference in the ts values between iterations
699 double tsDiff_ns = (t_offsets[crys_id - 1] - t_offsets_prev[crys_id - 1]) * TICKS_TO_NS;
700 double tsDiffBhabha_ns = -999;
702 tsDiffBhabha_ns = (t_offsets[crys_id - 1] - currentBhabhaValuesCrys[crys_id - 1]) * TICKS_TO_NS;
703 }
704
705 B2INFO("Crystal " << crys_id << ": ts new bhabha - old merged = (" <<
706 t_offsets[crys_id - 1] << " - " << t_offsets_prev[crys_id - 1] <<
707 ") ticks * " << TICKS_TO_NS << " ns/tick = " << tsDiff_ns << " ns");
708 B2INFO("Crystal " << crys_id << ": ts new bhabha - old bhabha = (" <<
709 t_offsets[crys_id - 1] << " - " << currentBhabhaValuesCrys[crys_id - 1] <<
710 ") ticks * " << TICKS_TO_NS << " ns/tick = " << tsDiffBhabha_ns << " ns");
711
712 tsNew_MINUS_tsOld__cid->SetBinContent(crys_id, tsDiff_ns);
713 tsNew_MINUS_tsOld__cid->SetBinError(crys_id, 0);
714 tsNew_MINUS_tsOld__cid->ResetStats();
715
716 tsNew_MINUS_tsOld->Fill(tsDiff_ns);
717
718
719 tsNew_MINUS_tsOldBhabha__cid->SetBinContent(crys_id, tsDiffBhabha_ns);
720 tsNew_MINUS_tsOldBhabha__cid->SetBinError(crys_id, 0);
721 tsNew_MINUS_tsOldBhabha__cid->ResetStats();
722
723 tsNew_MINUS_tsOldBhabha->Fill(tsDiffBhabha_ns);
724
725
726
727 /* Fill histograms with the difference in the ts values from this iteration
728 and the previous values read in from the payload. */
729 double tsDiffCustomOld_ns = -999;
731 tsDiffCustomOld_ns = (t_offsets[crys_id - 1] - prevValuesCrys[crys_id - 1]) * TICKS_TO_NS;
732 B2INFO("Crystal " << crys_id << ": ts new bhabha - 'before 1st iter' merged = (" <<
733 t_offsets[crys_id - 1] << " - " << prevValuesCrys[crys_id - 1] <<
734 ") ticks * " << TICKS_TO_NS << " ns/tick = " << tsDiffCustomOld_ns << " ns");
735 }
736 tsNew_MINUS_tsCustomPrev__cid->SetBinContent(crys_id, tsDiffCustomOld_ns);
737 tsNew_MINUS_tsCustomPrev__cid->SetBinError(crys_id, 0);
738 tsNew_MINUS_tsCustomPrev__cid->ResetStats();
739
740 tsNew_MINUS_tsCustomPrev->Fill(tsDiffCustomOld_ns);
741
742 }
743
744 // Save the histograms to the output root file
745 histfile->WriteTObject(tsNew_MINUS_tsOld__cid.get(), "tsNew_MINUS_tsOld__cid");
746 histfile->WriteTObject(tsNew_MINUS_tsOld.get(), "tsNew_MINUS_tsOld");
747
748 histfile->WriteTObject(tsNew_MINUS_tsCustomPrev__cid.get(), "tsNew_MINUS_tsCustomPrev__cid");
749 histfile->WriteTObject(tsNew_MINUS_tsCustomPrev.get(), "tsNew_MINUS_tsCustomPrev");
750
751 histfile->WriteTObject(tsNew_MINUS_tsOldBhabha__cid.get(), "tsNew_MINUS_tsOldBhabha__cid");
752 histfile->WriteTObject(tsNew_MINUS_tsOldBhabha.get(), "tsNew_MINUS_tsOldBhabha");
753 }
754
755
756 //..Store previous crystal calibration constants to payload under different
757 // names so that they can be read in for comparison later. These are temporary
758 // payloads that are only used for plotting purposes while running the calibration
759 // and does not need to be added to any global tag.
761 ECLCrystalCalib* crysTCalib_prev = new ECLCrystalCalib();
762 crysTCalib_prev->setCalibVector(currentValuesCrys, currentUncCrys);
763
764 ECLCrystalCalib* crysBhabhaTCalib_prev = new ECLCrystalCalib();
765 crysBhabhaTCalib_prev->setCalibVector(currentBhabhaValuesCrys, currentBhabhaUncCrys);
766
767
768 // Save the information to the payload if there is at least one crystal
769 // begin calibrated.
770 if (cellIDLo <= cellIDHi) {
771 saveCalibration(crysTCalib_prev, "ECLCrystalTimeOffsetPreviousValues");
772 B2INFO("Previous overall crystal payload made");
773
774 saveCalibration(crysBhabhaTCalib_prev, "ECLCrystalTimeOffsetBhabhaPreviousValues");
775 B2INFO("Previous bhabha crystal payload made");
776 }
777 }
778
779
780 ECLCrystalCalib* BhabhaTCalib = new ECLCrystalCalib();
781 BhabhaTCalib->setCalibVector(t_offsets, t_offsets_unc);
782
783 // Save the information to the payload if there is at least one crystal
784 // begin calibrated.
785 if (cellIDLo <= cellIDHi) {
786 saveCalibration(BhabhaTCalib, "ECLCrystalTimeOffset");
787 saveCalibration(BhabhaTCalib, "ECLCrystalTimeOffsetBhabha");
788 B2DEBUG(22, "crystal payload made");
789 }
790
791
792 B2DEBUG(22, "end of crystal start of crate corrections .....");
793
794
795 //==============================================================
796 /* CRATE CORRECTIONS */
797
798 hist_tmin = TimevsCrateNoCrateCalibPrevCrystCalib->GetYaxis()->GetXmin();
799 hist_tmax = TimevsCrateNoCrateCalibPrevCrystCalib->GetYaxis()->GetXmax();
800
801 B2DEBUG(22, "Found min/max of X axis of TimevsCrateNoCrateCalibPrevCrystCalib");
802
803 // Vector of time offsets to be saved in the database.
804
805 auto TcrateDatabase = getObjectPtr<TH1F>("TcrateDatabase");
806
807
808 B2DEBUG(22, "Retrieved Ts and Tcrate histograms from tcol root file");
809
810
811 vector<float> tcrate_mean_new(52, 0.0);
812 vector<float> tcrate_mean_unc_new(52, 0.0);
813 vector<float> tcrate_sigma_new(52, 0.0);
814 vector<float> tcrate_mean_prev(52, 0.0);
815 // vector<float> tcrate_sigma_prev(52, 0.0); // currently not used
816 vector<bool> tcrate_new_was_set(52, false);
817 vector<bool> tcrate_new_goodQuality(52, false);
818
819 B2DEBUG(22, "crate vectors set");
820
821
822
823 // Crate time calibration constants are saved per crystal so read them per crystal
824 // and save as one entry per crate in the array
825 for (int crys_id = 1; crys_id <= ECLElementNumbers::c_NCrystals; crys_id++) {
826 int crate_id_from_crystal = crystalMapper->getCrateID(crys_id);
827 tcrate_mean_prev[crate_id_from_crystal - 1] = TcrateDatabase->GetBinContent(crys_id) / numTimesFilled;
828 }
829
830
831 B2INFO("Print out previous crate time calibration constants to make sure they match from the two different sources.");
832 for (int crate_id = 1; crate_id <= 52; crate_id++) {
833 B2INFO("tcrate_mean_prev[crate " << crate_id << " (base 1)] = " << tcrate_mean_prev[crate_id - 1]);
834
835 int thisRefCellID = crystalIDReferenceForZeroTs[crate_id - 1];
836 B2INFO("tcrate from payload: ref cellID " << thisRefCellID << " " << currentValuesCrate[thisRefCellID - 1] << " +/- " <<
837 currentUncCrate[thisRefCellID - 1]);
838 }
839
840
841 /* Read in the histogram about the crate calibration constant differences between iterations
842 if it exists. This way the histograms can be updated after each run.*/
843 if (crateIDLo <= crateIDHi) {
844 TFile* histExtraCrateInfofile_dummy = 0; // Only created if needed for crates
845 B2INFO("Debug output rootfile used for crate iterations: " << extraCratedebugFilename);
846 histExtraCrateInfofile_dummy = new TFile(extraCratedebugFilename.c_str(), "UPDATE");
847
848
849 // If the histogram already exists then read it in and recreate the file so that we can save an updated version of the histogram.
850 const TKey* key = histExtraCrateInfofile_dummy->FindKey("tcrateNew_MINUS_tcrateOld_allRuns");
851 if (key != 0) {
852 TH1F* h = static_cast<TH1F*>(histExtraCrateInfofile_dummy->Get("tcrateNew_MINUS_tcrateOld_allRuns"));
853 tcrateNew_MINUS_tcrateOld_allRuns->Add(h);
854 }
855
856 key = histExtraCrateInfofile_dummy->FindKey("tcrateNew_MINUS_tcrateOld_allRuns_allCrates");
857 if (key != 0) {
858 TH1F* h = static_cast<TH1F*>(histExtraCrateInfofile_dummy->Get("tcrateNew_MINUS_tcrateOld_allRuns_allCrates"));
859 tcrateNew_MINUS_tcrateOld_allRuns_allCrates->Add(h);
860 }
861
862 key = histExtraCrateInfofile_dummy->FindKey("num_tcrates_perRun");
863 if (key != 0) {
864 TH1F* h = static_cast<TH1F*>(histExtraCrateInfofile_dummy->Get("num_tcrates_perRun"));
865 num_tcrates_perRun->Add(h);
866 }
867
868 key = histExtraCrateInfofile_dummy->FindKey("tcrateNew_MINUS_tcrateOld__vs__runNum");
869 if (key != 0) {
870 TH1F* h = static_cast<TH1F*>(histExtraCrateInfofile_dummy->Get("tcrateNew_MINUS_tcrateOld__vs__runNum"));
871 tcrateNew_MINUS_tcrateOld__vs__runNum->Add(h);
872 }
873
874 histExtraCrateInfofile_dummy->Close();
875
876 /* After reading in all the histograms, recreate the root file from empty so that the
877 histograms can be made again with the updated values.*/
878 histExtraCrateInfofile = new TFile(extraCratedebugFilename.c_str(), "recreate");
879 }
880
881
882
883 for (int crate_id = crateIDLo; crate_id <= crateIDHi; crate_id++) {
884
885 B2DEBUG(22, "Start of crate id = " << crate_id);
886
887 TH1D* h_time_crate = TimevsCrateNoCrateCalibPrevCrystCalib->ProjectionY("h_time_psi_crate", crate_id, crate_id);
888 TH1D* h_time_crate_mask = static_cast<TH1D*>(h_time_crate->Clone());
889 TH1D* h_time_crate_masked = static_cast<TH1D*>(h_time_crate->Clone());
890 TH1D* h_time_crate_rebin = static_cast<TH1D*>(h_time_crate->Clone());
891
892
893 // Do rebinning and cleaning of some bins but only if the user selection values call for it since it slows the code down
895
896 h_time_crate_rebin->Rebin(meanCleanRebinFactor);
897 h_time_crate_mask->Scale(0.0); // set all bins to being masked off
898
899 time_fit_min = hist_tmax; // Set min value to largest possible value so that it gets reset
900 time_fit_max = hist_tmin; // Set max value to smallest possible value so that it gets reset
901
902 // Find value of bin with max value
903 double histRebin_max = h_time_crate_rebin->GetMaximum();
904
905 bool maskedOutNonZeroBin = false;
906 // Loop over all bins to find those with content less than a certain threshold. Mask the non-rebinned histogram for the corresponding bins
907 for (int bin = 1; bin <= h_time_crate_rebin->GetNbinsX(); bin++) {
908 for (int rebinCounter = 1; rebinCounter <= meanCleanRebinFactor; rebinCounter++) {
909 int nonRebinnedBinNumber = (bin - 1) * meanCleanRebinFactor + rebinCounter;
910 if (nonRebinnedBinNumber < h_time_crate->GetNbinsX()) {
911 if (h_time_crate_rebin->GetBinContent(bin) >= histRebin_max * meanCleanCutMinFactor) {
912 h_time_crate_mask->SetBinContent(nonRebinnedBinNumber, 1);
913
914 // Save the lower and upper edges of the rebin histogram time range for fitting purposes
915 double x_lower = h_time_crate_rebin->GetXaxis()->GetBinLowEdge(bin);
916 double x_upper = h_time_crate_rebin->GetXaxis()->GetBinUpEdge(bin);
917 if (x_lower < time_fit_min) {
918 time_fit_min = x_lower;
919 }
920 if (x_upper > time_fit_max) {
921 time_fit_max = x_upper;
922 }
923 } else {
924 if (h_time_crate->GetBinContent(nonRebinnedBinNumber) > 0) {
925 B2DEBUG(22, "Setting bin " << nonRebinnedBinNumber << " from " << h_time_crate_masked->GetBinContent(
926 nonRebinnedBinNumber) << " to 0");
927 maskedOutNonZeroBin = true;
928 }
929 h_time_crate_masked->SetBinContent(nonRebinnedBinNumber, 0);
930 }
931 }
932 }
933 }
934 B2INFO("Bins with non-zero values have been masked out: " << maskedOutNonZeroBin);
935 h_time_crate_masked->ResetStats();
936 h_time_crate_mask->ResetStats();
937
938 }
939
940
941
942 B2DEBUG(22, "crate loop - projected h_time_psi_crate");
943
944
945 double default_mean_crate = h_time_crate_masked->GetMean();
946 double default_mean_crate_unc = h_time_crate_masked->GetMeanError();
947 double default_sigma_crate = h_time_crate_masked->GetStdDev();
948 B2INFO("Fitting crate between " << time_fit_min << " and " << time_fit_max);
949 TF1* gaus = new TF1("func", "gaus(0)", time_fit_min, time_fit_max);
950 gaus->SetParNames("numCrateHisNormalization", "mean", "sigma");
951 double hist_max = h_time_crate->GetMaximum();
952 double stddev = h_time_crate->GetStdDev();
953 double sigma_crate = stddev;
954 double mean_crate = default_mean_crate;
955 gaus->SetParameter(0, hist_max / 2.);
956 gaus->SetParameter(1, mean_crate);
957 gaus->SetParameter(2, sigma_crate);
958
959 h_time_crate_masked->Fit(gaus, "LQR"); // L for likelihood, R for x-range, Q for fit quiet mode
960
961 double fit_mean_crate = gaus->GetParameter(1);
962 double fit_mean_crate_unc = gaus->GetParError(1);
963 double fit_sigma_crate = gaus->GetParameter(2);
964
965 double meanDiff = fit_mean_crate - default_mean_crate;
966 double meanUncDiff = fit_mean_crate_unc - default_mean_crate_unc;
967 double sigmaDiff = fit_sigma_crate - default_sigma_crate;
968
969 bool good_fit = false;
970
971 B2DEBUG(22, "Crate id = " << crate_id << " with crate mean = " << default_mean_crate << " +- " << fit_mean_crate_unc);
972
973 if ((fabs(meanDiff) > 7) ||
974 (fabs(meanUncDiff) > 7) ||
975 (fabs(sigmaDiff) > 7) ||
976 (fit_mean_crate_unc > 3) ||
977 (fit_sigma_crate < 0.1) ||
978 (fit_mean_crate < time_fit_min) ||
979 (fit_mean_crate > time_fit_max)) {
980 B2INFO("Crate id = " << crate_id);
981 B2INFO("fit mean, default mean = " << fit_mean_crate << ", " << default_mean_crate);
982 B2INFO("fit sigma, default sigma = " << fit_sigma_crate << ", " << default_sigma_crate);
983
984 B2INFO("crate fit mean - hist mean = " << meanDiff);
985 B2INFO("fit mean unc. - hist mean unc. = " << meanUncDiff);
986 B2INFO("fit sigma - hist sigma = " << sigmaDiff);
987 B2INFO("fit_mean_crate = " << fit_mean_crate);
988 B2INFO("time_fit_min = " << time_fit_min);
989 B2INFO("time_fit_max = " << time_fit_max);
990 } else {
991 good_fit = true;
992 }
993
994 int numEntries = h_time_crate->GetEntries();
995 B2INFO("Number entries = " << numEntries);
996 double database_mean_crate = 0;
997 double database_mean_crate_unc = 0;
998 tcrate_new_was_set[crate_id - 1] = false;
999 tcrate_new_goodQuality[crate_id - 1] = false;
1000 if ((numEntries >= minNumEntries) && good_fit) {
1001 database_mean_crate = fit_mean_crate;
1002 database_mean_crate_unc = fit_mean_crate_unc;
1003 tcrate_new_was_set[crate_id - 1] = true;
1004
1005 if ((numEntries >= minNumEntriesCrateConvergence) && (fit_mean_crate_unc < 0.1)) {
1006 tcrate_new_goodQuality[crate_id - 1] = true;
1007 }
1008 }
1009
1010 tcrate_mean_new[crate_id - 1] = database_mean_crate;
1011 tcrate_mean_unc_new[crate_id - 1] = database_mean_crate_unc;
1012 tcrate_sigma_new[crate_id - 1] = fit_sigma_crate;
1013
1014 histfile->WriteTObject(h_time_crate, (string("h_time_psi_crate") + to_string(crate_id)).c_str());
1015 histfile->WriteTObject(h_time_crate_masked, (string("h_time_psi_crate_masked") + to_string(crate_id)).c_str());
1016 histfile->WriteTObject(h_time_crate_rebin, (string("h_time_psi_crate_rebinned") + to_string(crate_id)).c_str());
1017
1018 delete gaus;
1019 }
1020
1021 B2DEBUG(22, "crate histograms made");
1022
1023
1024 // Save database for crates
1025 // Vector of time offsets to be saved in the database.
1026 vector<float> t_offsets_crate;
1027 // Vector of time offset uncertainties to be saved in the database.
1028 vector<float> t_offsets_crate_unc;
1029 for (int i = 1; i <= ECLElementNumbers::c_NCrystals; i++) {
1030 t_offsets_crate.push_back(0);
1031 t_offsets_crate_unc.push_back(0);
1032 }
1033
1034
1035 for (int crys_id = 1; crys_id <= ECLElementNumbers::c_NCrystals; crys_id++) {
1036 int crate_id_from_crystal = crystalMapper->getCrateID(crys_id);
1037 if (tcrate_new_was_set[crate_id_from_crystal - 1]) {
1038 t_offsets_crate[crys_id - 1] = tcrate_mean_new[crate_id_from_crystal - 1] / TICKS_TO_NS;
1039 t_offsets_crate_unc[crys_id - 1] = tcrate_mean_unc_new[crate_id_from_crystal - 1] / TICKS_TO_NS;
1040
1041 } else {
1042 t_offsets_crate[crys_id - 1] = tcrate_mean_prev[crate_id_from_crystal - 1];
1043 B2INFO("used old crate mean but zeroed uncertainty since not saved in root file");
1044 }
1045 }
1046
1047
1048 // Fill histograms with the difference in the tcrate values
1049 if (crateIDLo <= crateIDHi) {
1050 for (int crate_id = crateIDLo; crate_id <= crateIDHi; crate_id++) {
1051 // tcrate_mean_new already in ns, but tcrate_mean_prev in ticks.
1052 double tCrateDiff_ns = tcrate_mean_new[crate_id - 1] - (tcrate_mean_prev[crate_id - 1] * TICKS_TO_NS);
1053 B2INFO("Crate " << crate_id << ": tcrate new - previous iteration = "
1054 << tcrate_mean_new[crate_id - 1]
1055 << " - " << tcrate_mean_prev[crate_id - 1] * TICKS_TO_NS
1056 << " = " << tCrateDiff_ns << " ns");
1057 tcrateNew_MINUS_tcrateOld__crateID->SetBinContent(crate_id, tCrateDiff_ns);
1058 tcrateNew_MINUS_tcrateOld__crateID->SetBinError(crate_id, 0);
1059 tcrateNew_MINUS_tcrateOld__crateID->ResetStats();
1060
1061 tcrateNew_MINUS_tcrateOld->Fill(tCrateDiff_ns);
1062
1063 // Save the histograms monitoring the change between iterations
1064 tcrateNew_MINUS_tcrateOld_allRuns_allCrates->Fill(tCrateDiff_ns);
1065 if (tcrate_new_goodQuality[crate_id - 1]) {
1066 tcrateNew_MINUS_tcrateOld_allRuns->Fill(tCrateDiff_ns);
1067 num_tcrates_perRun->Fill(minRunNum);
1068 tcrateNew_MINUS_tcrateOld__vs__runNum->Fill(minRunNum, tCrateDiff_ns);
1069 }
1070 }
1071
1072 // Save the histograms to the output root file
1073 histfile->WriteTObject(tcrateNew_MINUS_tcrateOld__crateID.get(), "tcrateNew_MINUS_tcrateOld__crateID");
1074 histfile->WriteTObject(tcrateNew_MINUS_tcrateOld.get(), "tcrateNew_MINUS_tcrateOld");
1075
1076 // Save the histograms to the crate iterations file
1077 histExtraCrateInfofile->WriteTObject(tcrateNew_MINUS_tcrateOld_allRuns.get(), "tcrateNew_MINUS_tcrateOld_allRuns");
1078 histExtraCrateInfofile->WriteTObject(tcrateNew_MINUS_tcrateOld_allRuns_allCrates.get(),
1079 "tcrateNew_MINUS_tcrateOld_allRuns_allCrates");
1080 histExtraCrateInfofile->WriteTObject(num_tcrates_perRun.get(), "num_tcrates_perRun");
1081 histExtraCrateInfofile->WriteTObject(tcrateNew_MINUS_tcrateOld__vs__runNum.get(), "tcrateNew_MINUS_tcrateOld__vs__runNum");
1082 }
1083
1084
1085 ECLCrystalCalib* BhabhaTCrateCalib = new ECLCrystalCalib();
1086 BhabhaTCrateCalib->setCalibVector(t_offsets_crate, t_offsets_crate_unc);
1087
1088
1089 // Save the information to the payload if there is at least one crate
1090 // begin calibrated.
1091 if (crateIDLo <= crateIDHi) {
1092 saveCalibration(BhabhaTCrateCalib, "ECLCrateTimeOffset");
1093 B2DEBUG(22, "crate payload made");
1094
1095 histExtraCrateInfofile->Close();
1096 }
1097
1098
1099 int tree_crateid;
1100 int tree_runNum;
1101 double tree_tcrate_mean;
1102 double tree_tcrate_mean_unc;
1103 double tree_tcrate_sigma;
1104 double tree_tcrate_meanPrev;
1105
1106 tree_crate->Branch("runNum", &tree_runNum)->SetTitle("Run number, 0..infinity and beyond!");
1107 tree_crate->Branch("crateid", &tree_crateid)->SetTitle("Crate id, 1..52");
1108 tree_crate->Branch("tcrate", &tree_tcrate_mean)->SetTitle("Crate time offset mean, tcrate, ns");
1109 tree_crate->Branch("tcratePrev", &tree_tcrate_meanPrev)->SetTitle("Previous crate time offset mean, tcrate, ns");
1110 tree_crate->Branch("tcrate_unc", &tree_tcrate_mean_unc)->SetTitle("Error of time tcrate mean, ns.");
1111 tree_crate->Branch("tcrate_sigma", &tree_tcrate_sigma)->SetTitle("Sigma of time tcrate distribution, ns");
1112 tree_crate->SetAutoSave(10);
1113
1114
1115 for (auto expRun : getRunList()) {
1116 // Key command to make sure your DBObjPtrs are correct
1117 B2INFO("run num, exp num: " << expRun.second << ", " << expRun.first);
1118 int runNumber = expRun.second;
1119
1120 for (int crate_id = 1; crate_id <= 52; crate_id++) {
1121 if (tcrate_new_was_set[crate_id - 1]) {
1122 tree_runNum = runNumber;
1123 tree_crateid = crate_id;
1124 tree_tcrate_mean = tcrate_mean_new[crate_id - 1];
1125 tree_tcrate_mean_unc = tcrate_mean_unc_new[crate_id - 1];
1126 tree_tcrate_sigma = tcrate_sigma_new[crate_id - 1];
1127 tree_tcrate_meanPrev = tcrate_mean_prev[crate_id - 1] * TICKS_TO_NS;
1128 tree_crate->Fill();
1129 }
1130 }
1131 }
1132
1133 B2DEBUG(22, "end of crate corrections .....");
1134
1135 tree_crystal->Write();
1136 tree_crate->Write();
1137
1138 histfile->Close();
1139
1140 B2INFO("Finished talgorithm");
1141 return c_OK;
1142}
void saveCalibration(TClonesArray *data, const std::string &name)
Store DBArray payload with given name with default IOV.
static void updateDBObjPtrs(const unsigned int event, const int run, const int experiment)
Updates any DBObjPtrs by calling update(event) for DBStore.
const std::vector< Calibration::ExpRun > & getRunList() const
Get the list of runs for which calibration is called.
@ c_OK
Finished successfully =0 in Python.
static DataStore & Instance()
Instance of singleton Store.
Definition DataStore.cc:53
void setInitializeActive(bool active)
Setter for m_initializeActive.
Definition DataStore.cc:93
void setCalibVector(const std::vector< float > &CalibConst, const std::vector< float > &CalibConstUnc)
Set vector of constants with uncertainties.
void setCalibVector(const std::vector< short > &refCrystals)
Set vector of constants with uncertainties.
static double getRF()
See m_rf.
bool registerInDataStore(DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut)
Register the object/array in the DataStore.
bool construct(Args &&... params)
Construct an object of type T in this StoreObjPtr, using the provided constructor arguments.
std::shared_ptr< T > getObjectPtr(const std::string &name, const std::vector< Calibration::ExpRun > &requestedRuns)
Get calibration data object by name and list of runs, the Merge function will be called to generate t...
static DBStore & Instance()
Instance of a singleton DBStore.
Definition DBStore.cc:26
void updateEvent()
Updates all intra-run dependent objects.
Definition DBStore.cc:140
void update()
Updates all objects that are outside their interval of validity.
Definition DBStore.cc:77

◆ checkPyExpRun()

bool checkPyExpRun ( PyObject * pyObj)
staticinherited

Checks that a PyObject can be successfully converted to an ExpRun type.

Checks if the PyObject can be converted to ExpRun.

Definition at line 28 of file CalibrationAlgorithm.cc.

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}

◆ clearCalibrationData()

void clearCalibrationData ( )
inlineprotectedinherited

Clear calibration data.

Definition at line 324 of file CalibrationAlgorithm.h.

324{m_data.clearCalibrationData();}

◆ commit() [1/2]

bool commit ( )
inherited

Submit constants from last calibration into database.

Definition at line 302 of file CalibrationAlgorithm.cc.

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}
std::list< Database::DBImportQuery > & getPayloads()
Get constants (in TObjects) for database update from last execution.
static Database & Instance()
Instance of a singleton Database.
Definition Database.cc:42
bool storeData(const std::string &name, TObject *object, const IntervalOfValidity &iov)
Store an object in the database.
Definition Database.cc:141

◆ commit() [2/2]

bool commit ( std::list< Database::DBImportQuery > payloads)
inherited

Submit constants from a (potentially previous) set of payloads.

Definition at line 312 of file CalibrationAlgorithm.cc.

313{
314 if (payloads.empty())
315 return false;
316 return Database::Instance().storeData(payloads);
317}

◆ convertPyExpRun()

ExpRun convertPyExpRun ( PyObject * pyObj)
staticinherited

Performs the conversion of PyObject to ExpRun.

Converts the PyObject to an ExpRun. We've preoviously checked the object so this assumes a lot about the PyObject.

Definition at line 70 of file CalibrationAlgorithm.cc.

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}

◆ dumpOutputJson()

const std::string dumpOutputJson ( ) const
inlineinherited

Dump the JSON string of the output JSON object.

Definition at line 223 of file CalibrationAlgorithm.h.

223{return m_jsonExecutionOutput.dump();}

◆ execute() [1/2]

CalibrationAlgorithm::EResult execute ( PyObject * runs,
int iteration = 0,
IntervalOfValidity iov = IntervalOfValidity() )
inherited

Runs calibration over Python list of runs. Converts to C++ and then calls the other execute() function.

Definition at line 83 of file CalibrationAlgorithm.cc.

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++");
100 m_data.setResult(c_Failure);
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).");
108 m_data.setResult(c_Failure);
109 return c_Failure;
110 }
111 return execute(vecRuns, iteration, iov);
112}
static bool checkPyExpRun(PyObject *pyObj)
Checks that a PyObject can be successfully converted to an ExpRun type.
EResult execute(std::vector< Calibration::ExpRun > runs={}, int iteration=0, IntervalOfValidity iov=IntervalOfValidity())
Runs calibration over vector of runs for a given iteration.
static Calibration::ExpRun convertPyExpRun(PyObject *pyObj)
Performs the conversion of PyObject to ExpRun.
ExecutionData m_data
Data specific to a SINGLE execution of the algorithm. Gets reset at the beginning of execution.

◆ execute() [2/2]

CalibrationAlgorithm::EResult execute ( std::vector< Calibration::ExpRun > runs = {},
int iteration = 0,
IntervalOfValidity iov = IntervalOfValidity() )
inherited

Runs calibration over vector of runs for a given iteration.

You can also specify the IoV to save the database payload as. By default the Algorithm will create an IoV from your requested ExpRuns, or from the overall ExpRuns of the input data if you haven't specified ExpRuns in this function.

No checks are performed to make sure that a IoV you specify matches the data you ran over, it simply labels the IoV to commit to the database later.

Definition at line 114 of file CalibrationAlgorithm.cc.

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()");
124 m_data.setResult(c_Failure);
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.");
144 m_data.setResult(c_Failure);
145 return c_Failure;
146 }
147 for (auto expRun : runs) {
148 B2DEBUG(29, "ExpRun requested = (" << expRun.first << ", " << expRun.second << ")");
149 }
150 }
151
152 m_data.setRequestedRuns(runs);
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 }
157 m_data.setRequestedIov(iov);
158 // After here, the getObject<...>(...) helpers start to work
159
161 m_data.setResult(result);
162 return result;
163}
std::vector< Calibration::ExpRun > getRunListFromAllData() const
Get the complete list of runs from inspection of collected 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_Undefined
Not yet known (before execution) =4 in Python.
const std::string & getGranularity() const
Get the granularity of collected data.
virtual EResult calibrate()=0
Run algo on data - pure virtual: needs to be implemented.

◆ fillRunToInputFilesMap()

void fillRunToInputFilesMap ( )
inherited

Fill the mapping of ExpRun -> Files.

Definition at line 331 of file CalibrationAlgorithm.cc.

332{
333 m_runsToInputFiles.clear();
334 // Save TDirectory to change back at the end
335 TDirectory* dir = gDirectory;
336 RunRange* runRange;
337 // Construct the TDirectory name where we expect our objects to be
338 string runRangeObjName(getPrefix() + "/" + RUN_RANGE_OBJ_NAME);
339 for (const auto& fileName : m_inputFileNames) {
340 //Open TFile to get the objects
341 unique_ptr<TFile> f;
342 f.reset(TFile::Open(fileName.c_str(), "READ"));
343 runRange = dynamic_cast<RunRange*>(f->Get(runRangeObjName.c_str()));
344 if (runRange) {
345 // Insert or extend the run -> file mapping for this ExpRun
346 auto expRuns = runRange->getExpRunSet();
347 for (const auto& expRun : expRuns) {
348 auto runFiles = m_runsToInputFiles.find(expRun);
349 if (runFiles != m_runsToInputFiles.end()) {
350 (runFiles->second).push_back(fileName);
351 } else {
352 m_runsToInputFiles.insert(std::make_pair(expRun, std::vector<std::string> {fileName}));
353 }
354 }
355 } else {
356 B2WARNING("Missing a RunRange object for file: " << fileName);
357 }
358 }
359 dir->cd();
360}
const std::string & getPrefix() const
Get the prefix used for getting calibration data.
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...
const std::set< Calibration::ExpRun > & getExpRunSet()
Get access to the stored set.
Definition RunRange.h:64

◆ findPayloadBoundaries()

const std::vector< ExpRun > findPayloadBoundaries ( std::vector< Calibration::ExpRun > runs,
int iteration = 0 )
inherited

Used to discover the ExpRun boundaries that you want the Python CAF to execute on. This is optional and only used in some.

Definition at line 521 of file CalibrationAlgorithm.cc.

522{
523 m_boundaries.clear();
524 if (m_inputFileNames.empty()) {
525 B2ERROR("There aren't any input files set. Please use CalibrationAlgorithm::setInputFiles()");
526 return m_boundaries;
527 }
528 // Reset the internal execution data just in case something is hanging around
529 m_data.reset();
530 if (runs.empty()) {
531 // Want to loop over all runs we could possibly know about
532 runs = getRunListFromAllData();
533 }
534 // Let's check that we have some now
535 if (runs.empty()) {
536 B2ERROR("No collected data in input files.");
537 return m_boundaries;
538 }
539 // In order to find run boundaries we must have collected with data granularity == 'run'
540 if (strcmp(getGranularity().c_str(), "all") == 0) {
541 B2ERROR("The data is collected with granularity='all' (exp=-1,run=-1), and we can't use that to find run boundaries.");
542 return m_boundaries;
543 }
544 m_data.setIteration(iteration);
545 // User defined setup function
546 boundaryFindingSetup(runs, iteration);
547 std::vector<ExpRun> runList;
548 // Loop over run list and call derived class "isBoundaryRequired" member function
549 for (auto currentRun : runs) {
550 runList.push_back(currentRun);
551 m_data.setRequestedRuns(runList);
552 // After here, the getObject<...>(...) helpers start to work
553 if (isBoundaryRequired(currentRun)) {
554 m_boundaries.push_back(currentRun);
555 }
556 // Only want run-by-run
557 runList.clear();
558 // Don't want memory hanging around
559 m_data.clearCalibrationData();
560 }
561 m_data.reset();
563 return m_boundaries;
564}
std::vector< Calibration::ExpRun > m_boundaries
When using the boundaries functionality from isBoundaryRequired, this is used to store the boundaries...
virtual void boundaryFindingTearDown()
Put your algorithm back into a state ready for normal execution if you need to.
virtual void boundaryFindingSetup(std::vector< Calibration::ExpRun >, int)
If you need to make some changes to your algorithm class before 'findPayloadBoundaries' is run,...
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...

◆ getAllGranularityExpRun()

static Calibration::ExpRun getAllGranularityExpRun ( )
inlinestaticprotectedinherited

Returns the Exp,Run pair that means 'Everything'. Currently unused.

Definition at line 327 of file CalibrationAlgorithm.h.

327{return m_allExpRun;}

◆ getCollectorName()

const std::string & getCollectorName ( ) const
inlineinherited

Alias for prefix.

For convenience and less writing, we say developers to set this to default collector module name in constructor of base class. One can however use the dublets of collector+algorithm multiple times with different settings. To bind these together correctly, the prefix has to be set the same for algo and collector. So we call the setter setPrefix rather than setModuleName or whatever. This getter will work out of the box for default cases -> return the name of module you have to add to your path to collect data for this algorithm.

Definition at line 164 of file CalibrationAlgorithm.h.

164{return getPrefix();}

◆ getDescription()

const std::string & getDescription ( ) const
inlineinherited

Get the description of the algorithm (set by developers in constructor)

Definition at line 216 of file CalibrationAlgorithm.h.

216{return m_description;}

◆ getExpRunString()

string getExpRunString ( Calibration::ExpRun & expRun) const
privateinherited

Gets the "exp.run" string repr. of (exp,run)

Definition at line 254 of file CalibrationAlgorithm.cc.

255{
256 string expRunString;
257 expRunString += to_string(expRun.first);
258 expRunString += ".";
259 expRunString += to_string(expRun.second);
260 return expRunString;
261}

◆ getFullObjectPath()

string getFullObjectPath ( const std::string & name,
Calibration::ExpRun expRun ) const
privateinherited

constructs the full TDirectory + Key name of an object in a TFile based on its name and exprun

Definition at line 263 of file CalibrationAlgorithm.cc.

264{
265 string dirName = getPrefix() + "/" + name;
266 string objName = name + "_" + getExpRunString(expRun);
267 return dirName + "/" + objName;
268}
std::string getExpRunString(Calibration::ExpRun &expRun) const
Gets the "exp.run" string repr. of (exp,run)

◆ getGranularity()

const std::string & getGranularity ( ) const
inlineinherited

Get the granularity of collected data.

Definition at line 188 of file CalibrationAlgorithm.h.

188{return m_granularityOfData;};

◆ getGranularityFromData()

string getGranularityFromData ( ) const
protectedinherited

Get the granularity of collected data.

Definition at line 384 of file CalibrationAlgorithm.cc.

385{
386 // Save TDirectory to change back at the end
387 TDirectory* dir = gDirectory;
388 const RunRange* runRange;
389 string runRangeObjName(getPrefix() + "/" + RUN_RANGE_OBJ_NAME);
390 // We only check the first file
391 string fileName = m_inputFileNames[0];
392 unique_ptr<TFile> f;
393 f.reset(TFile::Open(fileName.c_str(), "READ"));
394 runRange = dynamic_cast<RunRange*>(f->Get(runRangeObjName.c_str()));
395 if (!runRange) {
396 B2FATAL("The input file " << fileName << " does not contain a RunRange object at "
397 << runRangeObjName << ". Please set your input files to exclude it.");
398 return "";
399 }
400 string granularity = runRange->getGranularity();
401 dir->cd();
402 return granularity;
403}
const std::string & getGranularity() const
Gets the m_granularity.
Definition RunRange.h:110

◆ getInputFileNames()

PyObject * getInputFileNames ( )
inherited

Get the input file names used for this algorithm and pass them out as a Python list of unicode strings.

Definition at line 245 of file CalibrationAlgorithm.cc.

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}

◆ getInputJsonObject()

const nlohmann::json & getInputJsonObject ( ) const
inlineprotectedinherited

Get the entire top level JSON object. We explicitly say this must be of object type so that we might pick.

Definition at line 357 of file CalibrationAlgorithm.h.

357{return m_jsonExecutionInput;}

◆ getInputJsonValue()

template<class T>
const T getInputJsonValue ( const std::string & key) const
inlineprotectedinherited

Get an input JSON value using a key. The normal exceptions are raised when the key doesn't exist.

Definition at line 350 of file CalibrationAlgorithm.h.

351 {
352 return m_jsonExecutionInput.at(key);
353 }

◆ getIovFromAllData()

IntervalOfValidity getIovFromAllData ( ) const
inherited

Get the complete IoV from inspection of collected data.

Definition at line 326 of file CalibrationAlgorithm.cc.

327{
329}
RunRange getRunRangeFromAllData() const
Get the complete RunRange from inspection of collected data.
IntervalOfValidity getIntervalOfValidity()
Make IntervalOfValidity from the set, spanning all runs. Works because sets are sorted by default.
Definition RunRange.h:70

◆ getIteration()

int getIteration ( ) const
inlineprotectedinherited

Get current iteration.

Definition at line 269 of file CalibrationAlgorithm.h.

269{ return m_data.getIteration(); }

◆ getObjectPtr()

template<class T>
std::shared_ptr< T > getObjectPtr ( std::string name)
inlineprotectedinherited

Get calibration data object (for all runs the calibration is requested for) This function will only work during or after execute() has been called once.

Definition at line 285 of file CalibrationAlgorithm.h.

286 {
287 if (m_runsToInputFiles.size() == 0)
288 fillRunToInputFilesMap();
289 return getObjectPtr<T>(name, m_data.getRequestedRuns());
290 }

◆ getOutputJsonValue()

template<class T>
const T getOutputJsonValue ( const std::string & key) const
inlineprotectedinherited

Get a value using a key from the JSON output object, not sure why you would want to do this.

Definition at line 342 of file CalibrationAlgorithm.h.

343 {
344 return m_jsonExecutionOutput.at(key);
345 }

◆ getPayloads()

std::list< Database::DBImportQuery > & getPayloads ( )
inlineinherited

Get constants (in TObjects) for database update from last execution.

Definition at line 204 of file CalibrationAlgorithm.h.

204{return m_data.getPayloads();}

◆ getPayloadValues()

std::list< Database::DBImportQuery > getPayloadValues ( ) const
inlineinherited

Get constants (in TObjects) for database update from last execution but passed by VALUE.

Definition at line 207 of file CalibrationAlgorithm.h.

207{return m_data.getPayloadValues();}

◆ getPrefix()

const std::string & getPrefix ( ) const
inlineinherited

Get the prefix used for getting calibration data.

Definition at line 146 of file CalibrationAlgorithm.h.

146{return m_prefix;}

◆ getRunList()

const std::vector< Calibration::ExpRun > & getRunList ( ) const
inlineprotectedinherited

Get the list of runs for which calibration is called.

Definition at line 266 of file CalibrationAlgorithm.h.

266{return m_data.getRequestedRuns();}

◆ getRunListFromAllData()

vector< ExpRun > getRunListFromAllData ( ) const
inherited

Get the complete list of runs from inspection of collected data.

Definition at line 319 of file CalibrationAlgorithm.cc.

320{
321 RunRange runRange = getRunRangeFromAllData();
322 set<ExpRun> expRunSet = runRange.getExpRunSet();
323 return vector<ExpRun>(expRunSet.begin(), expRunSet.end());
324}

◆ getRunRangeFromAllData()

RunRange getRunRangeFromAllData ( ) const
inherited

Get the complete RunRange from inspection of collected data.

Definition at line 362 of file CalibrationAlgorithm.cc.

363{
364 // Save TDirectory to change back at the end
365 TDirectory* dir = gDirectory;
366 RunRange runRange;
367 // Construct the TDirectory name where we expect our objects to be
368 string runRangeObjName(getPrefix() + "/" + RUN_RANGE_OBJ_NAME);
369 for (const auto& fileName : m_inputFileNames) {
370 //Open TFile to get the objects
371 unique_ptr<TFile> f;
372 f.reset(TFile::Open(fileName.c_str(), "READ"));
373 const RunRange* runRangeOther = dynamic_cast<RunRange*>(f->Get(runRangeObjName.c_str()));
374 if (runRangeOther) {
375 runRange.merge(runRangeOther);
376 } else {
377 B2WARNING("Missing a RunRange object for file: " << fileName);
378 }
379 }
380 dir->cd();
381 return runRange;
382}
virtual void merge(const RunRange *other)
Implementation of merging - other is added to the set (union)
Definition RunRange.h:52

◆ getVecInputFileNames()

const std::vector< std::string > & getVecInputFileNames ( ) const
inlineprotectedinherited

Get the input file names used for this algorithm as a STL vector.

Definition at line 275 of file CalibrationAlgorithm.h.

275{return m_inputFileNames;}

◆ inputJsonKeyExists()

bool inputJsonKeyExists ( const std::string & key) const
inlineprotectedinherited

Test for a key in the input JSON object.

Definition at line 360 of file CalibrationAlgorithm.h.

360{return m_jsonExecutionInput.count(key);}

◆ isBoundaryRequired()

virtual bool isBoundaryRequired ( const Calibration::ExpRun & )
inlineprotectedvirtualinherited

Given the current collector data, make a decision about whether or not this run should be the start of a payload boundary.

Reimplemented in PXDAnalyticGainCalibrationAlgorithm, PXDValidationAlgorithm, SVD3SampleCoGTimeCalibrationAlgorithm, SVD3SampleELSTimeCalibrationAlgorithm, SVDClusterAbsoluteTimeShifterAlgorithm, SVDCoGTimeCalibrationAlgorithm, TestBoundarySettingAlgorithm, and TestCalibrationAlgorithm.

Definition at line 243 of file CalibrationAlgorithm.h.

244 {
245 B2ERROR("You didn't implement a isBoundaryRequired() member function in your CalibrationAlgorithm but you are calling it!");
246 return false;
247 }

◆ loadInputJson()

bool loadInputJson ( const std::string & jsonString)
inherited

Load the m_inputJson variable from a string (useful from Python interface). The return bool indicates success or failure.

Definition at line 503 of file CalibrationAlgorithm.cc.

504{
505 try {
506 auto jsonInput = nlohmann::json::parse(jsonString);
507 // Input string has an object (dict) as the top level object?
508 if (jsonInput.is_object()) {
509 m_jsonExecutionInput = jsonInput;
510 return true;
511 } else {
512 B2ERROR("JSON input string isn't an object type i.e. not a '{}' at the top level.");
513 return false;
514 }
515 } catch (nlohmann::json::parse_error&) {
516 B2ERROR("Parsing of JSON input string failed");
517 return false;
518 }
519}
nlohmann::json m_jsonExecutionInput
Optional input JSON object used to make decisions about how to execute the algorithm code.

◆ resetInputJson()

void resetInputJson ( )
inlineprotectedinherited

Clears the m_inputJson member variable.

Definition at line 330 of file CalibrationAlgorithm.h.

330{m_jsonExecutionInput.clear();}

◆ resetOutputJson()

void resetOutputJson ( )
inlineprotectedinherited

Clears the m_outputJson member variable.

Definition at line 333 of file CalibrationAlgorithm.h.

333{m_jsonExecutionOutput.clear();}

◆ saveCalibration() [1/6]

void saveCalibration ( TClonesArray * data,
const std::string & name )
protectedinherited

Store DBArray payload with given name with default IOV.

Definition at line 297 of file CalibrationAlgorithm.cc.

298{
299 saveCalibration(data, name, m_data.getRequestedIov());
300}

◆ saveCalibration() [2/6]

void saveCalibration ( TClonesArray * data,
const std::string & name,
const IntervalOfValidity & iov )
protectedinherited

Store DBArray with given name and custom IOV.

Definition at line 276 of file CalibrationAlgorithm.cc.

277{
278 B2DEBUG(29, "Saving calibration TClonesArray '" << name << "' to payloads list.");
279 getPayloads().emplace_back(name, data, iov);
280}

◆ saveCalibration() [3/6]

void saveCalibration ( TObject * data)
protectedinherited

Store DB payload with default name and default IOV.

Definition at line 287 of file CalibrationAlgorithm.cc.

288{
289 saveCalibration(data, DataStore::objectName(data->IsA(), ""));
290}
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:150

◆ saveCalibration() [4/6]

void saveCalibration ( TObject * data,
const IntervalOfValidity & iov )
protectedinherited

Store DB payload with default name and custom IOV.

Definition at line 282 of file CalibrationAlgorithm.cc.

283{
284 saveCalibration(data, DataStore::objectName(data->IsA(), ""), iov);
285}

◆ saveCalibration() [5/6]

void saveCalibration ( TObject * data,
const std::string & name )
protectedinherited

Store DB payload with given name with default IOV.

Definition at line 292 of file CalibrationAlgorithm.cc.

293{
294 saveCalibration(data, name, m_data.getRequestedIov());
295}

◆ saveCalibration() [6/6]

void saveCalibration ( TObject * data,
const std::string & name,
const IntervalOfValidity & iov )
protectedinherited

Store DB payload with given name and custom IOV.

Definition at line 270 of file CalibrationAlgorithm.cc.

271{
272 B2DEBUG(29, "Saving calibration TObject = '" << name << "' to payloads list.");
273 getPayloads().emplace_back(name, data, iov);
274}

◆ setDescription()

void setDescription ( const std::string & description)
inlineprotectedinherited

Set algorithm description (in constructor)

Definition at line 321 of file CalibrationAlgorithm.h.

321{m_description = description;}

◆ setInputFileNames() [1/2]

void setInputFileNames ( const std::vector< std::string > & inputFileNames)
protectedinherited

Set the input file names used for this algorithm.

Set the input file names used for this algorithm and resolve the wildcards.

Definition at line 194 of file CalibrationAlgorithm.cc.

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}
std::string m_granularityOfData
Granularity of input data. This only changes when the input files change so it isn't specific to an e...
void setInputFileNames(PyObject *inputFileNames)
Set the input file names used for this algorithm from a Python list.
std::string getGranularityFromData() const
Get the granularity of collected data.
std::vector< std::string > expandWordExpansions(const std::vector< std::string > &filenames)
Performs wildcard expansion using wordexp(), returns matches.

◆ setInputFileNames() [2/2]

void setInputFileNames ( PyObject * inputFileNames)
inherited

Set the input file names used for this algorithm from a Python list.

Set the input file names used for this algorithm and resolve the wildcards.

Definition at line 166 of file CalibrationAlgorithm.cc.

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}
Scalar convertPythonObject(const boost::python::object &pyObject, Scalar)
Convert from Python to given type.

◆ setOutputJsonValue()

template<class T>
void setOutputJsonValue ( const std::string & key,
const T & value )
inlineprotectedinherited

Set a key:value pair for the outputJson object, expected to used internally during calibrate()

Definition at line 337 of file CalibrationAlgorithm.h.

337{m_jsonExecutionOutput[key] = value;}

◆ setPrefix()

void setPrefix ( const std::string & prefix)
inlineinherited

Set the prefix used to identify datastore objects.

Definition at line 167 of file CalibrationAlgorithm.h.

167{m_prefix = prefix;}

◆ updateDBObjPtrs()

void updateDBObjPtrs ( const unsigned int event,
const int run,
const int experiment )
staticprotectedinherited

Updates any DBObjPtrs by calling update(event) for DBStore.

Definition at line 405 of file CalibrationAlgorithm.cc.

406{
407 // Construct an EventMetaData object but NOT in the Datastore
408 EventMetaData emd(event, run, experiment);
409 // Explicitly update while avoiding registering a Datastore object
411 // Also update the intra-run objects to the event at the same time (maybe unnecessary...)
413}

Member Data Documentation

◆ cellIDHi

int cellIDHi = 0

Fit crystals with cellID0 in the inclusive range [cellIDLo,cellIDHi].

Definition at line 37 of file eclBhabhaTAlgorithm.h.

◆ cellIDLo

int cellIDLo = 0

Fit crystals with cellID0 in the inclusive range [cellIDLo,cellIDHi].

Definition at line 36 of file eclBhabhaTAlgorithm.h.

◆ collectorName

std::string collectorName

Name of the collector.

Definition at line 49 of file eclBhabhaTAlgorithm.h.

◆ crateIDHi

int crateIDHi = 0

Fit crates with crateID0 in the inclusive range [crateIDLo,crateIDHi].

Definition at line 43 of file eclBhabhaTAlgorithm.h.

◆ crateIDLo

int crateIDLo = 0

Fit crates with crateID0 in the inclusive range [crateIDLo,crateIDHi].

Definition at line 42 of file eclBhabhaTAlgorithm.h.

◆ debugFilenameBase

std::string debugFilenameBase

Name of file with debug output, eclBhabhaTAlgorithm.root by default.

Definition at line 48 of file eclBhabhaTAlgorithm.h.

◆ debugOutput

bool debugOutput = false

Save every histogram and fitted function to debugFilename.

Definition at line 46 of file eclBhabhaTAlgorithm.h.

◆ m_allExpRun

const ExpRun m_allExpRun = make_pair(-1, -1)
staticprivateinherited

allExpRun

Definition at line 364 of file CalibrationAlgorithm.h.

◆ m_boundaries

std::vector<Calibration::ExpRun> m_boundaries
protectedinherited

When using the boundaries functionality from isBoundaryRequired, this is used to store the boundaries. It is cleared when.

Definition at line 261 of file CalibrationAlgorithm.h.

◆ m_data

ExecutionData m_data
privateinherited

Data specific to a SINGLE execution of the algorithm. Gets reset at the beginning of execution.

Definition at line 382 of file CalibrationAlgorithm.h.

◆ m_description

std::string m_description {""}
privateinherited

Description of the algorithm.

Definition at line 385 of file CalibrationAlgorithm.h.

385{""};

◆ m_granularityOfData

std::string m_granularityOfData
privateinherited

Granularity of input data. This only changes when the input files change so it isn't specific to an execution.

Definition at line 379 of file CalibrationAlgorithm.h.

◆ m_inputFileNames

std::vector<std::string> m_inputFileNames
privateinherited

List of input files to the Algorithm, will initially be user defined but then gets the wildcards expanded during execute()

Definition at line 373 of file CalibrationAlgorithm.h.

◆ m_jsonExecutionInput

nlohmann::json m_jsonExecutionInput = nlohmann::json::object()
privateinherited

Optional input JSON object used to make decisions about how to execute the algorithm code.

Definition at line 397 of file CalibrationAlgorithm.h.

◆ m_jsonExecutionOutput

nlohmann::json m_jsonExecutionOutput = nlohmann::json::object()
privateinherited

Optional output JSON object that can be set during the execution by the underlying algorithm code.

Definition at line 403 of file CalibrationAlgorithm.h.

◆ m_prefix

std::string m_prefix {""}
privateinherited

The name of the TDirectory the collector objects are contained within.

Definition at line 388 of file CalibrationAlgorithm.h.

388{""};

◆ m_runsToInputFiles

std::map<Calibration::ExpRun, std::vector<std::string> > m_runsToInputFiles
privateinherited

Map of Runs to input files. Gets filled when you call getRunRangeFromAllData, gets cleared when setting input files again.

Definition at line 376 of file CalibrationAlgorithm.h.

◆ meanCleanCutMinFactor

double meanCleanCutMinFactor = 0.0

After rebinning, create a mask for bins that have values less than meanCleanCutMinFactor times the maximum bin value.

Expand mask and apply to non-rebinned histogram.

Definition at line 39 of file eclBhabhaTAlgorithm.h.

◆ meanCleanRebinFactor

double meanCleanRebinFactor = 0.0

Rebinning factor for mean calculation.

Definition at line 38 of file eclBhabhaTAlgorithm.h.

◆ readPrevCrysPayload

bool readPrevCrysPayload = false

Read the previous crystal payload values for comparison.

Definition at line 45 of file eclBhabhaTAlgorithm.h.

◆ refCrysPerCrate

int refCrysPerCrate[52] = {}

List of crystals, one per crate, used as reference time for crystal time calibration.

Definition at line 50 of file eclBhabhaTAlgorithm.h.

50{};

◆ savePrevCrysPayload

bool savePrevCrysPayload = false

Save the previous crystal payload values for comparison.

Definition at line 44 of file eclBhabhaTAlgorithm.h.


The documentation for this class was generated from the following files: