Belle II Software development
KLMTimeAlgorithm Class Reference

KLM time calibration algorithm. More...

#include <KLMTimeAlgorithm.h>

Inheritance diagram for KLMTimeAlgorithm:
CalibrationAlgorithm

Classes

struct  Event
 Event data. More...
 

Public Types

enum  ChannelCalibrationStatus {
  c_NotEnoughData = 0 ,
  c_FailedFit = 1 ,
  c_SuccessfulCalibration = 2
}
 Channel calibration status. More...
 
enum  EResult {
  c_OK ,
  c_Iterate ,
  c_NotEnoughData ,
  c_Failure ,
  c_Undefined
}
 The result of calibration. More...
 

Public Member Functions

 KLMTimeAlgorithm ()
 Constructor.
 
 ~KLMTimeAlgorithm () override
 Destructor.
 
void setDebug ()
 Turn on debug mode (prints histograms and output running log).
 
void setMC (bool mc)
 Set flag indicating whether the input is MC sample.
 
void useEvtT0 ()
 Use event T0 as the initial time point or not.
 
void setMinimalDigitNumber (int minimalDigitNumber)
 Set minimal digit number (total).
 
void setLowerLimit (int counts)
 Set the lower number of hits collected on one single strip.
 
void setApplyChargeRestriction (bool apply)
 Enable or disable ADC/charge restriction cuts for scintillators.
 
void setSaveAllPlots (bool on)
 Save every preallocated debug histogram family (sectors/layers/planes/2D maps).
 
void setSaveChannelHists (bool on)
 When running in minimal mode, also write the per-channel temporary histograms (the vital tc, raw, hc 1D’s created on-the-fly) before deleting them.
 
void saveHist ()
 Save histograms to file.
 
double esti_timeShift (const KLMChannelIndex &klmChannel)
 Estimate value of calibration constant for uncalibrated channels.
 
std::pair< int, double > tS_upperStrip (const KLMChannelIndex &klmChannel)
 Tracing available channels with increasing strip number.
 
std::pair< int, double > tS_lowerStrip (const KLMChannelIndex &klmChannel)
 Tracing available channels with decreasing strip number.
 
double esti_timeRes (const KLMChannelIndex &klmChannel)
 Estimate value of calibration constant for calibrated channels.
 
std::pair< int, double > tR_upperStrip (const KLMChannelIndex &klmChannel)
 Tracing available channels with increasing strip number.
 
std::pair< int, double > tR_lowerStrip (const KLMChannelIndex &klmChannel)
 Tracing available channels with decreasing strip number.
 
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.
 

Protected Member Functions

virtual EResult calibrate () override
 Run algorithm on data.
 
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

void setupDatabase ()
 Setup the database.
 
CalibrationAlgorithm::EResult readCalibrationData ()
 Read calibration data.
 
void readCalibrationDataCounts (std::map< KLMChannelNumber, unsigned int > &eventCounts)
 Count events per channel (lightweight scan without loading full data).
 
void readCalibrationDataFor2DFit (const std::vector< std::pair< KLMChannelNumber, unsigned int > > &channelsBKLM, const std::vector< std::pair< KLMChannelNumber, unsigned int > > &channelsEKLM)
 Load calibration data only for channels needed for 2D fit.
 
void readCalibrationDataBatch (std::function< bool(const KLMChannelIndex &)> channelFilter)
 Load calibration data for a specific batch of channels.
 
void createHistograms ()
 Create histograms.
 
void writeThenDelete_ (TH1 *h, bool write, TDirectory *dir=nullptr)
 Optionally write a histogram, then delete it to free memory.
 
void writeThenDelete_ (TH2 *h, bool write, TDirectory *dir=nullptr)
 Same as above, but for 2D histograms.
 
bool passesADCCut (const Event &event, int subdetector, int layer) const
 Check if event passes ADC count cuts for quality selection.
 
void fillTimeDistanceProfiles (TProfile *profileRpcPhi, TProfile *profileRpcZ, TProfile *profileBKLMScintillatorPhi, TProfile *profileBKLMScintillatorZ, TProfile *profileEKLMScintillatorPlane1, TProfile *profileEKLMScintillatorPlane2, bool fill2dHistograms)
 Fill profiles of time versus distance.
 
void timeDistance2dFit (const std::vector< std::pair< KLMChannelNumber, unsigned int > > &channels, double &delay, double &delayError)
 Two-dimensional fit for individual channels.
 
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::map< KLMChannelNumber, std::vector< struct Event > > m_evts
 Container of hit information.
 
std::map< KLMChannelNumber, int > m_cFlag
 Calibration flag if the channel has enough hits collected and fitted OK.
 
std::map< KLMChannelNumber, double > m_timeShift
 Shift values of each channel.
 
std::map< KLMChannelNumber, double > m_timeRes
 Resolution values of each channel.
 
std::map< KLMChannelNumber, double > m_time_channel
 Time distribution central value of each channel.
 
std::map< KLMChannelNumber, double > m_etime_channel
 Time distribution central value Error of each channel.
 
std::map< KLMChannelNumber, double > m_ctime_channel
 Calibrated time distribution central value of each channel.
 
std::map< KLMChannelNumber, double > mc_etime_channel
 Calibrated time distribution central value Error of each channel.
 
double m_LowerTimeBoundaryRPC = -10.0
 Lower time boundary for RPC.
 
double m_UpperTimeBoundaryRPC = 10.0
 Upper time boundary for RPC.
 
double m_LowerTimeBoundaryScintillatorsBKLM = 20.0
 Lower time boundary for BKLM scintillators.
 
double m_UpperTimeBoundaryScintillatorsBKLM = 70.0
 Upper time boundary for BKLM scintillators.
 
double m_LowerTimeBoundaryScintillatorsEKLM = 20.0
 Lower time boundary for EKLM scintillators.
 
double m_UpperTimeBoundaryScintillatorsEKLM = 70.0
 Upper time boundary for BKLM scintillators.
 
double m_LowerTimeBoundaryCalibratedRPC = -40.0
 Lower time boundary for RPC (calibrated data).
 
double m_UpperTimeBoundaryCalibratedRPC = 40.0
 Upper time boundary for RPC (calibrated data).
 
bool m_useFixedRPCDelay = false
 Whether to use fixed propagation delay for RPCs.
 
double m_fixedRPCDelay = 0.0667
 Fixed propagation delay for RPCs (ns/cm).
 
double m_LowerTimeBoundaryCalibratedScintillatorsBKLM = -40.0
 Lower time boundary for BKLM scintillators (calibrated data).
 
double m_UpperTimeBoundaryCalibratedScintillatorsBKLM = 40.0
 Upper time boundary for BKLM scintillators (calibrated data).
 
double m_LowerTimeBoundaryCalibratedScintillatorsEKLM = -40.0
 Lower time boundary for EKLM scintillators (calibrated data).
 
double m_UpperTimeBoundaryCalibratedScintillatorsEKLM = 40.0
 Upper time boundary for BKLM scintillators (calibrated data).
 
double m_time_channelAvg_rpc = 0.0
 Central value of the global time distribution (BKLM RPC part).
 
double m_etime_channelAvg_rpc = 0.0
 Central value error of the global time distribution (BKLM RPC part).
 
double m_time_channelAvg_scint = 0.0
 Central value of the global time distribution (BKLM scintillator part).
 
double m_etime_channelAvg_scint = 0.0
 Central value error of the global time distribution (BKLM scintillator part).
 
double m_time_channelAvg_scint_end = 0.0
 Central value of the global time distribution (EKLM scintillator part).
 
double m_etime_channelAvg_scint_end = 0.0
 Central value error of the global time distribution (EKLM scintillator part).
 
double m_ctime_channelAvg_rpc = 0.0
 Calibrated central value of the global time distribution (BKLM RPC part).
 
double mc_etime_channelAvg_rpc = 0.0
 Calibrated central value error of the global time distribution (BKLM RPC part).
 
double m_ctime_channelAvg_scint = 0.0
 Calibrated central value of the global time distribution (BKLM scintillator part).
 
double mc_etime_channelAvg_scint = 0.0
 Calibrated central value error of the global time distribution (BKLM scintillator part).
 
double m_ctime_channelAvg_scint_end = 0.0
 Calibrated central value of the global time distribution (EKLM scintillator part).
 
double mc_etime_channelAvg_scint_end = 0.0
 Calibrated central value error of the global time distribution (EKLM scintillator part).
 
int m_MinimalDigitNumber = 100000000
 Minimal digit number (total).
 
int m_lower_limit_counts = 50
 Lower limit of hits collected for on single channel.
 
const KLMElementNumbersm_ElementNumbers
 Element numbers.
 
const bklm::GeometryParm_BKLMGeometry = nullptr
 BKLM geometry data.
 
const EKLM::GeometryDatam_EKLMGeometry = nullptr
 EKLM geometry data.
 
KLMChannelIndex m_klmChannels
 KLM ChannelIndex object.
 
ROOT::Math::MinimizerOptions m_minimizerOptions
 Minimization options.
 
KLMTimeConstantsm_timeConstants = nullptr
 DBObject of time cost on some parts of the detector.
 
KLMTimeCableDelaym_timeCableDelay = nullptr
 DBObject of the calibration constant of each channel due to cable decay.
 
KLMTimeResolutionm_timeResolution = nullptr
 DBObject of time resolution.
 
KLMEventT0HitResolutionm_eventT0HitResolution = nullptr
 DBObject of per-hit time resolution for EventT0.
 
bool m_debug = false
 Debug mode.
 
bool m_mc = false
 MC or data.
 
bool m_useEventT0 = true
 Whether to use event T0 from CDC.
 
bool m_applyChargeRestriction = false
 Whether to apply ADC/charge restriction cuts for scintillators.
 
TH1I * h_calibrated = nullptr
 Calibration statistics for each channel.
 
TH1I * hc_calibrated = nullptr
 Calibration statistics for each channel.
 
TH1F * h_diff = nullptr
 Distance between global and local position.
 
TGraphErrors * gre_time_channel_rpc = nullptr
 BKLM RPC.
 
TGraphErrors * gre_time_channel_scint = nullptr
 BKLM Scintillator.
 
TGraphErrors * gre_time_channel_scint_end = nullptr
 EKLM.
 
TGraphErrors * gre_ctime_channel_rpc = nullptr
 BKLM RPC.
 
TGraphErrors * gre_ctime_channel_scint = nullptr
 BKLM Scintillator.
 
TGraphErrors * gre_ctime_channel_scint_end = nullptr
 EKLM.
 
TGraph * gr_timeShift_channel_rpc = nullptr
 BKLM RPC.
 
TGraph * gr_timeShift_channel_scint = nullptr
 BKLM scintillator.
 
TGraph * gr_timeShift_channel_scint_end = nullptr
 EKLM.
 
TGraph * gr_timeRes_channel_rpc = nullptr
 BKLM RPC.
 
TGraph * gr_timeRes_channel_scint = nullptr
 BKLM scintillator.
 
TGraph * gr_timeRes_channel_scint_end = nullptr
 EKLM.
 
TProfile * m_ProfileRpcPhi = nullptr
 For BKLM RPC phi plane.
 
TProfile * m_ProfileRpcZ = nullptr
 For BKLM RPC z plane.
 
TProfile * m_ProfileBKLMScintillatorPhi = nullptr
 For BKLM scintillator phi plane.
 
TProfile * m_ProfileBKLMScintillatorZ = nullptr
 For BKLM scintillator z plane.
 
TProfile * m_ProfileEKLMScintillatorPlane1 = nullptr
 For EKLM scintillator plane1.
 
TProfile * m_ProfileEKLMScintillatorPlane2 = nullptr
 For EKLM scintillator plane2.
 
TProfile * m_Profile2RpcPhi = nullptr
 For BKLM RPC phi plane.
 
TProfile * m_Profile2RpcZ = nullptr
 For BKLM RPC z plane.
 
TProfile * m_Profile2BKLMScintillatorPhi = nullptr
 For BKLM scintillator phi plane.
 
TProfile * m_Profile2BKLMScintillatorZ = nullptr
 For BKLM scintillator z plane.
 
TProfile * m_Profile2EKLMScintillatorPlane1 = nullptr
 For EKLM scintillator plane1.
 
TProfile * m_Profile2EKLMScintillatorPlane2 = nullptr
 For EKLM scintillator plane2.
 
TH1F * h_time_rpc_tc = nullptr
 BKLM RPC part.
 
TH1F * h_time_scint_tc = nullptr
 BKLM scintillator part.
 
TH1F * h_time_scint_tc_end = nullptr
 EKLM part.
 
TH1F * h_time_rpc = nullptr
 BKLM RPC part.
 
TH1F * h_time_scint = nullptr
 BKLM scintillator part.
 
TH1F * h_time_scint_end = nullptr
 EKLM part.
 
TH1F * hc_time_rpc = nullptr
 BKLM RPC part.
 
TH1F * hc_time_scint = nullptr
 BKLM scintillator part.
 
TH1F * hc_time_scint_end = nullptr
 EKLM part.
 
TH1F * h_timeF_rpc [2] = {nullptr}
 BKLM RPC part.
 
TH1F * h_timeF_scint [2] = {nullptr}
 BKLM scintillator part.
 
TH1F * h_timeF_scint_end [2] = {nullptr}
 EKLM part.
 
TH1F * hc_timeF_rpc [2] = {nullptr}
 BKLM RPC part.
 
TH1F * hc_timeF_scint [2] = {nullptr}
 BKLM scintillator part.
 
TH1F * hc_timeF_scint_end [2] = {nullptr}
 EKLM part.
 
TH2F * h2_timeF_rpc [2] = {nullptr}
 BKLM RPC part.
 
TH2F * h2_timeF_scint [2] = {nullptr}
 BKLM scintillator part.
 
TH2F * h2_timeF_scint_end [2] = {nullptr}
 EKLM part.
 
TH2F * h2c_timeF_rpc [2] = {nullptr}
 BKLM RPC part.
 
TH2F * h2c_timeF_scint [2] = {nullptr}
 BKLM scintillator part.
 
TH2F * h2c_timeF_scint_end [2] = {nullptr}
 EKLM part.
 
TH1F * h_timeFS_rpc [2][8] = {{nullptr}}
 BKLM RPC part.
 
TH1F * h_timeFS_scint [2][8] = {{nullptr}}
 BKLM scintillator part.
 
TH1F * h_timeFS_scint_end [2][4] = {{nullptr}}
 EKLM part.
 
TH1F * hc_timeFS_rpc [2][8] = {{nullptr}}
 BKLM RPC part.
 
TH1F * hc_timeFS_scint [2][8] = {{nullptr}}
 BKLM scintillator part.
 
TH1F * hc_timeFS_scint_end [2][4] = {{nullptr}}
 EKLM part.
 
TH2F * h2_timeFS [2][8] = {{nullptr}}
 BKLM part.
 
TH2F * h2_timeFS_end [2][4] = {{nullptr}}
 EKLM part.
 
TH2F * h2c_timeFS [2][8] = {{nullptr}}
 BKLM part.
 
TH2F * h2c_timeFS_end [2][4] = {{nullptr}}
 EKLM part.
 
TH1F * h_timeFSL [2][8][15] = {{{nullptr}}}
 BKLM part.
 
TH1F * h_timeFSL_end [2][4][14] = {{{nullptr}}}
 EKLM part.
 
TH1F * hc_timeFSL [2][8][15] = {{{nullptr}}}
 BKLM part.
 
TH1F * hc_timeFSL_end [2][4][14] = {{{nullptr}}}
 EKLM part.
 
TH1F * h_timeFSLP [2][8][15][2] = {{{{nullptr}}}}
 BKLM part.
 
TH1F * h_timeFSLP_end [2][4][14][2] = {{{{nullptr}}}}
 EKLM part.
 
TH1F * hc_timeFSLP [2][8][15][2] = {{{{nullptr}}}}
 BKLM part.
 
TH1F * hc_timeFSLP_end [2][4][14][2] = {{{{nullptr}}}}
 EKLM part.
 
TH2F * h2_timeFSLP [2][8][15][2] = {{{{nullptr}}}}
 BKLM part.
 
TH2F * h2_timeFSLP_end [2][4][14][2] = {{{{nullptr}}}}
 EKLM part.
 
TH2F * h2c_timeFSLP [2][8][15][2] = {{{{nullptr}}}}
 BKLM part.
 
TH2F * h2c_timeFSLP_end [2][4][14][2] = {{{{nullptr}}}}
 EKLM part.
 
TH1F * h_eventT0_rpc = nullptr
 EventT0 seen by RPC hits.
 
TH1F * h_eventT0_scint = nullptr
 EventT0 seen by BKLM scintillator hits.
 
TH1F * h_eventT0_scint_end = nullptr
 EventT0 seen by EKLM scintillator hits.
 
TH1F * hc_eventT0_rpc = nullptr
 Corrected EventT0 for RPC hits.
 
TH1F * hc_eventT0_scint = nullptr
 Corrected EventT0 for BKLM scintillator hits.
 
TH1F * hc_eventT0_scint_end = nullptr
 Corrected EventT0 for EKLM scintillator hits.
 
TH1F * h_nHits_plus_rpc = nullptr
 Number of RPC hits per mu+ track.
 
TH1F * h_nHits_minus_rpc = nullptr
 Number of RPC hits per mu- track.
 
TH1F * h_nHits_plus_scint = nullptr
 Number of BKLM scintillator hits per mu+ track.
 
TH1F * h_nHits_minus_scint = nullptr
 Number of BKLM scintillator hits per mu- track.
 
TH1F * h_nHits_plus_scint_end = nullptr
 Number of EKLM scintillator hits per mu+ track.
 
TH1F * h_nHits_minus_scint_end = nullptr
 Number of EKLM scintillator hits per mu- track.
 
TH2F * h2_deltaT0_vs_v_rpc = nullptr
 DeltaT0 vs inverse hit count for RPC.
 
TH2F * h2_deltaT0_vs_v_scint = nullptr
 DeltaT0 vs inverse hit count for BKLM scintillator.
 
TH2F * h2_deltaT0_vs_v_scint_end = nullptr
 DeltaT0 vs inverse hit count for EKLM scintillator.
 
TProfile * prof_deltaT0_rms_vs_v_rpc = nullptr
 DeltaT0 RMS vs inverse hit count profile for RPC.
 
TProfile * prof_deltaT0_rms_vs_v_scint = nullptr
 DeltaT0 RMS vs inverse hit count profile for BKLM scintillator.
 
TProfile * prof_deltaT0_rms_vs_v_scint_end = nullptr
 DeltaT0 RMS vs inverse hit count profile for EKLM scintillator.
 
TH2F * h2_deltaT0_vs_nhits_rpc = nullptr
 DeltaT0 vs total hit count for RPC.
 
TH2F * h2_deltaT0_vs_nhits_scint = nullptr
 DeltaT0 vs total hit count for BKLM scintillator.
 
TH2F * h2_deltaT0_vs_nhits_scint_end = nullptr
 DeltaT0 vs total hit count for EKLM scintillator.
 
TH1F * hc_eventT0_rpc_lowN = nullptr
 Corrected EventT0 for RPC with low hit count.
 
TH1F * hc_eventT0_rpc_midN = nullptr
 Corrected EventT0 for RPC with medium hit count.
 
TH1F * hc_eventT0_rpc_highN = nullptr
 Corrected EventT0 for RPC with high hit count.
 
TH1F * hc_eventT0_scint_lowN = nullptr
 Corrected EventT0 for BKLM scintillator with low hit count.
 
TH1F * hc_eventT0_scint_midN = nullptr
 Corrected EventT0 for BKLM scintillator with medium hit count.
 
TH1F * hc_eventT0_scint_highN = nullptr
 Corrected EventT0 for BKLM scintillator with high hit count.
 
TH1F * hc_eventT0_scint_end_lowN = nullptr
 Corrected EventT0 for EKLM scintillator with low hit count.
 
TH1F * hc_eventT0_scint_end_midN = nullptr
 Corrected EventT0 for EKLM scintillator with medium hit count.
 
TH1F * hc_eventT0_scint_end_highN = nullptr
 Corrected EventT0 for EKLM scintillator with high hit count.
 
TF1 * fcn_pol1 = nullptr
 Pol1 function.
 
TF1 * fcn_const = nullptr
 Const function.
 
TF1 * fcn_gaus = nullptr
 Gaussian function.
 
TF1 * fcn_land = nullptr
 Landau function.
 
TFile * m_outFile = nullptr
 Output file.
 
bool m_saveAllPlots = false
 Default minimal unless you set true in your header script.
 
bool m_saveChannelHists = false
 Write per-channel temporary histograms (tc/raw/hc) in minimal mode.
 
TDirectory * m_channelHistDir_BKLM [2][8][15][2] = {}
 Directory structure for per-channel histograms (BKLM).
 
TDirectory * m_channelHistDir_EKLM [2][4][14][2] = {}
 Directory structure for per-channel histograms (EKLM).
 
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

KLM time calibration algorithm.

Definition at line 50 of file KLMTimeAlgorithm.h.

Member Enumeration Documentation

◆ ChannelCalibrationStatus

Channel calibration status.

Definition at line 129 of file KLMTimeAlgorithm.h.

129 {
130
131 /* Not enough data. */
132 c_NotEnoughData = 0,
133
134 /* Failed fit. */
135 c_FailedFit = 1,
136
137 /* Successful calibration. */
138 c_SuccessfulCalibration = 2,
139
140 };

◆ 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

◆ KLMTimeAlgorithm()

Constructor.

Definition at line 100 of file KLMTimeAlgorithm.cc.

100 :
101 CalibrationAlgorithm("KLMTimeCollector")
102{
104 m_minimizerOptions = ROOT::Math::MinimizerOptions();
105}
CalibrationAlgorithm(const std::string &collectorModuleName)
Constructor - sets the prefix for collected objects (won't be accesses until execute(....
static const KLMElementNumbers & Instance()
Instantiation.
const KLMElementNumbers * m_ElementNumbers
Element numbers.
ROOT::Math::MinimizerOptions m_minimizerOptions
Minimization options.

◆ ~KLMTimeAlgorithm()

~KLMTimeAlgorithm ( )
override

Destructor.

Definition at line 107 of file KLMTimeAlgorithm.cc.

108{
109}

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 data.

Implements CalibrationAlgorithm.

Definition at line 1120 of file KLMTimeAlgorithm.cc.

1121{
1122 int channelId;
1123 gROOT->SetBatch(kTRUE);
1124 setupDatabase();
1125 m_timeCableDelay = new KLMTimeCableDelay();
1126 m_timeConstants = new KLMTimeConstants();
1127 m_timeResolution = new KLMTimeResolution();
1128 m_eventT0HitResolution = new KLMEventT0HitResolution();
1129
1130 fcn_gaus = new TF1("fcn_gaus", "gaus");
1131 fcn_land = new TF1("fcn_land", "landau");
1132 fcn_pol1 = new TF1("fcn_pol1", "pol1");
1133 fcn_const = new TF1("fcn_const", "pol0");
1134
1135 // Initial validation only - DON'T load all data yet
1137 if (result != CalibrationAlgorithm::c_OK)
1138 return result;
1139
1140 /* Choose non-existing file name. */
1141 std::string name = "time_calibration.root";
1142 int i = 1;
1143 while (1) {
1144 struct stat buffer;
1145 if (stat(name.c_str(), &buffer) != 0)
1146 break;
1147 name = "time_calibration_" + std::to_string(i) + ".root";
1148 i = i + 1;
1149 if (i < 0)
1150 break;
1151 }
1152 m_outFile = new TFile(name.c_str(), "recreate");
1154
1155 std::vector<struct Event> eventsChannel;
1156 eventsChannel.clear();
1157 m_cFlag.clear();
1158 m_minimizerOptions.SetDefaultStrategy(2);
1159
1160 B2INFO("Counting events per channel...");
1161 std::map<KLMChannelNumber, unsigned int> eventCounts;
1162 readCalibrationDataCounts(eventCounts);
1163
1164 /* Sort channels by number of events and initialize flags. */
1165 std::vector< std::pair<KLMChannelNumber, unsigned int> > channelsBKLM;
1166 std::vector< std::pair<KLMChannelNumber, unsigned int> > channelsEKLM;
1167 KLMChannelIndex klmChannels;
1168
1169 for (const KLMChannelIndex& klmChannel : klmChannels) {
1170 KLMChannelNumber channel = klmChannel.getKLMChannelNumber();
1171 m_cFlag[channel] = ChannelCalibrationStatus::c_NotEnoughData;
1172
1173 if (eventCounts.find(channel) == eventCounts.end())
1174 continue;
1175
1176 int nEvents = eventCounts[channel];
1177 if (nEvents < m_lower_limit_counts) {
1178 B2WARNING("Not enough calibration data collected."
1179 << LogVar("channel", channel)
1180 << LogVar("number of digit", nEvents));
1181 continue;
1182 }
1183
1184 m_cFlag[channel] = ChannelCalibrationStatus::c_FailedFit;
1185
1186 if (klmChannel.getSubdetector() == KLMElementNumbers::c_BKLM &&
1187 klmChannel.getLayer() < BKLMElementNumbers::c_FirstRPCLayer) {
1188 channelsBKLM.push_back(std::pair<KLMChannelNumber, unsigned int>(channel, nEvents));
1189 }
1190 if (klmChannel.getSubdetector() == KLMElementNumbers::c_EKLM) {
1191 channelsEKLM.push_back(std::pair<KLMChannelNumber, unsigned int>(channel, nEvents));
1192 }
1193 }
1194
1195 std::sort(channelsBKLM.begin(), channelsBKLM.end(), compareEventNumber);
1196 std::sort(channelsEKLM.begin(), channelsEKLM.end(), compareEventNumber);
1197
1198 /* Two-dimensional fit using top channels only. */
1199 double delayBKLM, delayBKLMError;
1200 double delayEKLM, delayEKLMError;
1201
1202 /* Load data for 2D fit channels only. */
1203 readCalibrationDataFor2DFit(channelsBKLM, channelsEKLM);
1204 timeDistance2dFit(channelsBKLM, delayBKLM, delayBKLMError);
1205 timeDistance2dFit(channelsEKLM, delayEKLM, delayEKLMError);
1206 m_evts.clear();
1207
1208 B2INFO("2D fits complete, data cleared.");
1209
1210 /* Define processing batches for channel calibration. */
1211 auto isRPCBackward = [](const KLMChannelIndex & ch) {
1212 return ch.getSubdetector() == KLMElementNumbers::c_BKLM &&
1213 ch.getLayer() >= BKLMElementNumbers::c_FirstRPCLayer &&
1214 ch.getSection() == BKLMElementNumbers::c_BackwardSection;
1215 };
1216
1217 auto isRPCForward = [](const KLMChannelIndex & ch) {
1218 return ch.getSubdetector() == KLMElementNumbers::c_BKLM &&
1219 ch.getLayer() >= BKLMElementNumbers::c_FirstRPCLayer &&
1220 ch.getSection() == BKLMElementNumbers::c_ForwardSection;
1221 };
1222
1223 auto isBKLMScintillatorBackward = [](const KLMChannelIndex & ch) {
1224 return ch.getSubdetector() == KLMElementNumbers::c_BKLM &&
1225 ch.getLayer() < BKLMElementNumbers::c_FirstRPCLayer &&
1226 ch.getSection() == BKLMElementNumbers::c_BackwardSection;
1227 };
1228
1229 auto isBKLMScintillatorForward = [](const KLMChannelIndex & ch) {
1230 return ch.getSubdetector() == KLMElementNumbers::c_BKLM &&
1231 ch.getLayer() < BKLMElementNumbers::c_FirstRPCLayer &&
1232 ch.getSection() == BKLMElementNumbers::c_ForwardSection;
1233 };
1234
1235 auto isEKLMScintillatorBackward = [](const KLMChannelIndex & ch) {
1236 return ch.getSubdetector() == KLMElementNumbers::c_EKLM &&
1237 ch.getSection() == EKLMElementNumbers::c_BackwardSection;
1238 };
1239
1240 auto isEKLMScintillatorForward = [](const KLMChannelIndex & ch) {
1241 return ch.getSubdetector() == KLMElementNumbers::c_EKLM &&
1242 ch.getSection() == EKLMElementNumbers::c_ForwardSection;
1243 };
1244
1245 std::vector<std::pair<std::string, std::function<bool(const KLMChannelIndex&)>>> batches = {
1246 {"RPC Backward", isRPCBackward},
1247 {"RPC Forward", isRPCForward},
1248 {"BKLM Scintillator Backward", isBKLMScintillatorBackward},
1249 {"BKLM Scintillator Forward", isBKLMScintillatorForward},
1250 {"EKLM Scintillator Backward", isEKLMScintillatorBackward},
1251 {"EKLM Scintillator Forward", isEKLMScintillatorForward}
1252 };
1253
1254 /**********************************
1255 * FIRST LOOP (BATCHED)
1256 * Fill global histograms to compute global means
1257 **********************************/
1258 B2INFO("First loop: Computing global statistics (batched processing)...");
1259
1260 TString iFstring[2] = {"Backward", "Forward"};
1261 TString iPstring[2] = {"ZReadout", "PhiReadout"};
1262 int nBin = 80;
1263 int nBin_scint = 80;
1264
1265 for (const auto& batch : batches) {
1266 B2INFO("Processing batch for global stats: " << batch.first);
1267 readCalibrationDataBatch(batch.second);
1268
1269 for (KLMChannelIndex klmChannel = m_klmChannels.begin(); klmChannel != m_klmChannels.end(); ++klmChannel) {
1270 channelId = klmChannel.getKLMChannelNumber();
1271
1272 if (!batch.second(klmChannel))
1273 continue;
1274
1275 if (m_cFlag[channelId] == ChannelCalibrationStatus::c_NotEnoughData)
1276 continue;
1277
1278 if (m_evts.find(channelId) == m_evts.end())
1279 continue;
1280
1281 eventsChannel = m_evts[channelId];
1282 int iSub = klmChannel.getSubdetector();
1283 int iL = (iSub == KLMElementNumbers::c_BKLM) ? klmChannel.getLayer() - 1 : -1;
1284
1285 // Fill global histograms only
1286 for (const Event& event : eventsChannel) {
1287 // Apply ADC cut early
1288 if (!passesADCCut(event, iSub, iL))
1289 continue;
1290
1291 XYZVector diffD = XYZVector(event.diffDistX, event.diffDistY, event.diffDistZ);
1292 h_diff->Fill(diffD.R());
1293
1294 double timeHit = event.time();
1295 if (m_useEventT0)
1296 timeHit = timeHit - event.t0;
1297
1298 if (timeHit <= -400e3)
1299 continue;
1300
1301 if (iSub == KLMElementNumbers::c_BKLM) {
1302 // FIXED: Use constant instead of hardcoded value
1303 if (iL >= (BKLMElementNumbers::c_FirstRPCLayer - 1)) {
1304 h_time_rpc_tc->Fill(timeHit);
1305 } else {
1306 h_time_scint_tc->Fill(timeHit);
1307 }
1308 } else {
1309 h_time_scint_tc_end->Fill(timeHit);
1310 }
1311 }
1312 }
1313
1314 m_evts.clear();
1315 B2INFO("Batch processed and cleared: " << batch.first);
1316 }
1317
1318 // Compute global means
1319 m_timeShift.clear();
1320 double tmpMean_rpc_global = h_time_rpc_tc->GetMean();
1321 double tmpMean_scint_global = h_time_scint_tc->GetMean();
1322 double tmpMean_scint_global_end = h_time_scint_tc_end->GetMean();
1323
1324 B2INFO("Global Mean for Raw." << LogVar("RPC", tmpMean_rpc_global)
1325 << LogVar("Scint BKLM", tmpMean_scint_global)
1326 << LogVar("Scint EKLM", tmpMean_scint_global_end));
1327
1328 /**********************************
1329 * SECOND PASS (BATCHED)
1330 * Compute per-channel time shifts
1331 **********************************/
1332 B2INFO("Second pass: Computing per-channel time shifts (batched processing)...");
1333
1334 for (const auto& batch : batches) {
1335 B2INFO("Processing batch for time shifts: " << batch.first);
1336 readCalibrationDataBatch(batch.second);
1337
1338 for (KLMChannelIndex klmChannel = m_klmChannels.begin(); klmChannel != m_klmChannels.end(); ++klmChannel) {
1339 channelId = klmChannel.getKLMChannelNumber();
1340
1341 if (!batch.second(klmChannel))
1342 continue;
1343
1344 if (m_cFlag[channelId] == ChannelCalibrationStatus::c_NotEnoughData)
1345 continue;
1346
1347 if (m_evts.find(channelId) == m_evts.end())
1348 continue;
1349
1350 eventsChannel = m_evts[channelId];
1351 int iSub = klmChannel.getSubdetector();
1352 int iF, iS, iL, iP, iC;
1353
1354 if (iSub == KLMElementNumbers::c_BKLM) {
1355 iF = klmChannel.getSection();
1356 iS = klmChannel.getSector() - 1;
1357 iL = klmChannel.getLayer() - 1;
1358 iP = klmChannel.getPlane();
1359 iC = klmChannel.getStrip() - 1;
1360 } else {
1361 iF = klmChannel.getSection() - 1;
1362 iS = klmChannel.getSector() - 1;
1363 iL = klmChannel.getLayer() - 1;
1364 iP = klmChannel.getPlane() - 1;
1365 iC = klmChannel.getStrip() - 1;
1366 }
1367
1368 // Create and fill temp histogram
1369 TString hn, ht;
1370 TH1F* h_temp_tc = nullptr;
1371
1372 if (iSub == KLMElementNumbers::c_BKLM) {
1373 // FIXED: Use constant instead of hardcoded value
1374 if (iL >= (BKLMElementNumbers::c_FirstRPCLayer - 1)) {
1375 hn = Form("h_timeF%d_S%d_L%d_P%d_C%d_tc", iF, iS, iL, iP, iC);
1376 ht = Form("Time distribution for RPC of Channel%d, %s, Layer%d, Sector%d, %s",
1377 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1378 h_temp_tc = new TH1F(hn.Data(), ht.Data(), nBin, m_LowerTimeBoundaryRPC, m_UpperTimeBoundaryRPC);
1379 } else {
1380 hn = Form("h_timeF%d_S%d_L%d_P%d_C%d_tc", iF, iS, iL, iP, iC);
1381 ht = Form("time distribution for Scintillator of Channel%d, %s, Layer%d, Sector%d, %s",
1382 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1383 h_temp_tc = new TH1F(hn.Data(), ht.Data(), nBin_scint, m_LowerTimeBoundaryScintillatorsBKLM,
1385 }
1386 } else {
1387 hn = Form("h_timeF%d_S%d_L%d_P%d_C%d_tc_end", iF, iS, iL, iP, iC);
1388 ht = Form("Time distribution for Scintillator of Channel%d, %s, Layer%d, Sector%d, %s (Endcap)",
1389 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1390 h_temp_tc = new TH1F(hn.Data(), ht.Data(), nBin_scint, m_LowerTimeBoundaryScintillatorsEKLM,
1392 }
1393
1394 for (const Event& event : eventsChannel) {
1395 // Add ADC cut
1396 if (!passesADCCut(event, iSub, iL))
1397 continue;
1398
1399 double timeHit = event.time();
1400 if (m_useEventT0)
1401 timeHit = timeHit - event.t0;
1402 if (timeHit <= -400e3)
1403 continue;
1404 h_temp_tc->Fill(timeHit);
1405 }
1406
1407 h_temp_tc->Fit(fcn_gaus, "LESQ");
1408 double tmpMean_channel = fcn_gaus->GetParameter(1);
1409
1410 if (iSub == KLMElementNumbers::c_BKLM) {
1411 // FIXED: Use constant instead of hardcoded value
1412 if (iL >= (BKLMElementNumbers::c_FirstRPCLayer - 1)) {
1413 m_timeShift[channelId] = tmpMean_channel - tmpMean_rpc_global;
1414 } else {
1415 m_timeShift[channelId] = tmpMean_channel - tmpMean_scint_global;
1416 }
1417 } else {
1418 m_timeShift[channelId] = tmpMean_channel - tmpMean_scint_global_end;
1419 }
1420
1421 delete h_temp_tc;
1422 }
1423
1424 m_evts.clear();
1425 B2INFO("Batch processed and cleared: " << batch.first);
1426 }
1427
1428 delete h_time_scint_tc;
1429 delete h_time_scint_tc_end;
1430 delete h_time_rpc_tc;
1431 B2INFO("Effective Light m_timeShift obtained.");
1432
1433 // NOTE: fillTimeDistanceProfiles also needs batching - user will handle separately
1438
1439 B2INFO("Effective light speed fitting.");
1440
1441 // Fit the RPC profiles (for diagnostics), but use fixed values if configured
1442 m_ProfileRpcPhi->Fit("fcn_pol1", "EMQ");
1443 double fittedDelayRPCPhi = fcn_pol1->GetParameter(1);
1444 double e_slope_rpc_phi = fcn_pol1->GetParError(1);
1445
1446 m_ProfileRpcZ->Fit("fcn_pol1", "EMQ");
1447 double fittedDelayRPCZ = fcn_pol1->GetParameter(1);
1448 double e_slope_rpc_z = fcn_pol1->GetParError(1);
1449
1450 // Use fixed RPC delay if configured (per BELLE2-NOTE-TE-2021-015: c_eff = 0.5c)
1451 double delayRPCPhi, delayRPCZ;
1452 if (m_useFixedRPCDelay) {
1453 delayRPCPhi = m_fixedRPCDelay;
1454 delayRPCZ = m_fixedRPCDelay;
1455 B2INFO("Using fixed RPC propagation delay: " << m_fixedRPCDelay << " ns/cm (c_eff = 0.5c)"
1456 << LogVar("Fitted phi (not used)", fittedDelayRPCPhi)
1457 << LogVar("Fitted Z (not used)", fittedDelayRPCZ));
1458 } else {
1459 delayRPCPhi = fittedDelayRPCPhi;
1460 delayRPCZ = fittedDelayRPCZ;
1461 }
1462
1463 m_ProfileBKLMScintillatorPhi->Fit("fcn_pol1", "EMQ");
1464 double slope_scint_phi = fcn_pol1->GetParameter(1);
1465 double e_slope_scint_phi = fcn_pol1->GetParError(1);
1466
1467 m_ProfileBKLMScintillatorZ->Fit("fcn_pol1", "EMQ");
1468 double slope_scint_z = fcn_pol1->GetParameter(1);
1469 double e_slope_scint_z = fcn_pol1->GetParError(1);
1470
1471 m_ProfileEKLMScintillatorPlane1->Fit("fcn_pol1", "EMQ");
1472 double slope_scint_plane1_end = fcn_pol1->GetParameter(1);
1473 double e_slope_scint_plane1_end = fcn_pol1->GetParError(1);
1474
1475 m_ProfileEKLMScintillatorPlane2->Fit("fcn_pol1", "EMQ");
1476 double slope_scint_plane2_end = fcn_pol1->GetParameter(1);
1477 double e_slope_scint_plane2_end = fcn_pol1->GetParError(1);
1478
1479 TString logStr_phi, logStr_z;
1480 if (m_useFixedRPCDelay) {
1481 logStr_phi = Form("%.4f ns/cm (fixed)", delayRPCPhi);
1482 logStr_z = Form("%.4f ns/cm (fixed)", delayRPCZ);
1483 B2INFO("Delay in RPCs (using fixed value):"
1484 << LogVar("Used Value (phi readout)", logStr_phi.Data())
1485 << LogVar("Used Value (z readout)", logStr_z.Data()));
1486 } else {
1487 logStr_phi = Form("%.4f +/- %.4f ns/cm", delayRPCPhi, e_slope_rpc_phi);
1488 logStr_z = Form("%.4f +/- %.4f ns/cm", delayRPCZ, e_slope_rpc_z);
1489 B2INFO("Delay in RPCs:"
1490 << LogVar("Fitted Value (phi readout)", logStr_phi.Data())
1491 << LogVar("Fitted Value (z readout)", logStr_z.Data()));
1492 }
1493 logStr_phi = Form("%.4f +/- %.4f ns/cm", slope_scint_phi, e_slope_scint_phi);
1494 logStr_z = Form("%.4f +/- %.4f ns/cm", slope_scint_z, e_slope_scint_z);
1495 B2INFO("Delay in BKLM scintillators:"
1496 << LogVar("Fitted Value (phi readout) ", logStr_phi.Data())
1497 << LogVar("Fitted Value (z readout) ", logStr_z.Data()));
1498 logStr_phi = Form("%.4f +/- %.4f ns/cm", slope_scint_plane1_end,
1499 e_slope_scint_plane1_end);
1500 logStr_z = Form("%.4f +/- %.4f ns/cm", slope_scint_plane2_end,
1501 e_slope_scint_plane2_end);
1502 B2INFO("Delay in EKLM scintillators:"
1503 << LogVar("Fitted Value (plane1 readout) ", logStr_phi.Data())
1504 << LogVar("Fitted Value (plane2 readout) ", logStr_z.Data()));
1505
1506 logStr_z = Form("%.4f +/- %.4f ns/cm", delayBKLM, delayBKLMError);
1507 B2INFO("Delay in BKLM scintillators:"
1508 << LogVar("Fitted Value (2d fit) ", logStr_z.Data()));
1509 logStr_z = Form("%.4f +/- %.4f ns/cm", delayEKLM, delayEKLMError);
1510 B2INFO("Delay in EKLM scintillators:"
1511 << LogVar("Fitted Value (2d fit) ", logStr_z.Data()));
1512
1513 m_timeConstants->setDelay(delayEKLM, KLMTimeConstants::c_EKLM);
1514 m_timeConstants->setDelay(delayBKLM, KLMTimeConstants::c_BKLM);
1515 m_timeConstants->setDelay(delayRPCPhi, KLMTimeConstants::c_RPCPhi);
1516 m_timeConstants->setDelay(delayRPCZ, KLMTimeConstants::c_RPCZ);
1517
1518 /**********************************
1519 * THIRD LOOP (BATCHED)
1520 * Fill per-channel distributions and fit
1521 **********************************/
1522 B2INFO("Third loop: Time distribution filling (batched processing)...");
1523
1524 for (const auto& batch : batches) {
1525 B2INFO("Processing batch: " << batch.first);
1526 readCalibrationDataBatch(batch.second);
1527
1528 for (KLMChannelIndex klmChannel = m_klmChannels.begin(); klmChannel != m_klmChannels.end(); ++klmChannel) {
1529 channelId = klmChannel.getKLMChannelNumber();
1530
1531 if (!batch.second(klmChannel))
1532 continue;
1533
1534 if (m_cFlag[channelId] == ChannelCalibrationStatus::c_NotEnoughData)
1535 continue;
1536
1537 if (m_evts.find(channelId) == m_evts.end())
1538 continue;
1539
1540 eventsChannel = m_evts[channelId];
1541 int iSub = klmChannel.getSubdetector();
1542 int iF, iS, iL, iP, iC;
1543
1544 if (iSub == KLMElementNumbers::c_BKLM) {
1545 iF = klmChannel.getSection();
1546 iS = klmChannel.getSector() - 1;
1547 iL = klmChannel.getLayer() - 1;
1548 iP = klmChannel.getPlane();
1549 iC = klmChannel.getStrip() - 1;
1550 } else {
1551 iF = klmChannel.getSection() - 1;
1552 iS = klmChannel.getSector() - 1;
1553 iL = klmChannel.getLayer() - 1;
1554 iP = klmChannel.getPlane() - 1;
1555 iC = klmChannel.getStrip() - 1;
1556 }
1557
1558 // Create per-channel histogram
1559 TString hn, ht;
1560 TH1F* h_temp = nullptr;
1561
1562 if (iSub == KLMElementNumbers::c_BKLM) {
1563 // FIXED: Use constant instead of hardcoded value
1564 if (iL >= (BKLMElementNumbers::c_FirstRPCLayer - 1)) {
1565 hn = Form("h_timeF%d_S%d_L%d_P%d_C%d", iF, iS, iL, iP, iC);
1566 ht = Form("Time distribution for RPC of Channel%d, %s, Layer%d, Sector%d, %s",
1567 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1568 h_temp = new TH1F(hn.Data(), ht.Data(), nBin, m_LowerTimeBoundaryRPC, m_UpperTimeBoundaryRPC);
1569 } else {
1570 hn = Form("h_timeF%d_S%d_L%d_P%d_C%d", iF, iS, iL, iP, iC);
1571 ht = Form("time distribution for Scintillator of Channel%d, %s, Layer%d, Sector%d, %s",
1572 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1573 h_temp = new TH1F(hn.Data(), ht.Data(), nBin_scint, m_LowerTimeBoundaryScintillatorsBKLM,
1575 }
1576 } else {
1577 hn = Form("h_timeF%d_S%d_L%d_P%d_C%d_end", iF, iS, iL, iP, iC);
1578 ht = Form("Time distribution for Scintillator of Channel%d, %s, Layer%d, Sector%d, %s (Endcap)",
1579 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1580 h_temp = new TH1F(hn.Data(), ht.Data(), nBin_scint, m_LowerTimeBoundaryScintillatorsEKLM,
1582 }
1583
1584 // Fill histogram
1585 for (const Event& event : eventsChannel) {
1586 // Add ADC cut
1587 if (!passesADCCut(event, iSub, iL))
1588 continue;
1589
1590 double timeHit = event.time();
1591 if (m_useEventT0)
1592 timeHit = timeHit - event.t0;
1593 if (timeHit <= -400e3)
1594 continue;
1595
1596 if (iSub == KLMElementNumbers::c_BKLM) {
1597 // FIXED: Use constant instead of hardcoded value
1598 if (iL >= (BKLMElementNumbers::c_FirstRPCLayer - 1)) {
1599 double propgationT;
1601 propgationT = event.dist * delayRPCZ;
1602 else
1603 propgationT = event.dist * delayRPCPhi;
1604 double time = timeHit - propgationT;
1605
1606 h_time_rpc->Fill(time);
1607 h_temp->Fill(time);
1608
1609 if (m_saveAllPlots) {
1610 h_timeF_rpc[iF]->Fill(time);
1611 h_timeFS_rpc[iF][iS]->Fill(time);
1612 h_timeFSL[iF][iS][iL]->Fill(time);
1613 h_timeFSLP[iF][iS][iL][iP]->Fill(time);
1614 h2_timeF_rpc[iF]->Fill(iS, time);
1615 h2_timeFS[iF][iS]->Fill(iL, time);
1616 h2_timeFSLP[iF][iS][iL][iP]->Fill(iC, time);
1617 }
1618 } else {
1619 double propgationT = event.dist * delayBKLM;
1620 double time = timeHit - propgationT;
1621
1622 h_time_scint->Fill(time);
1623 h_temp->Fill(time);
1624
1625 if (m_saveAllPlots) {
1626 h_timeF_scint[iF]->Fill(time);
1627 h_timeFS_scint[iF][iS]->Fill(time);
1628 h_timeFSL[iF][iS][iL]->Fill(time);
1629 h_timeFSLP[iF][iS][iL][iP]->Fill(time);
1630 h2_timeF_scint[iF]->Fill(iS, time);
1631 h2_timeFS[iF][iS]->Fill(iL, time);
1632 h2_timeFSLP[iF][iS][iL][iP]->Fill(iC, time);
1633 }
1634 }
1635 } else {
1636 double propgationT = event.dist * delayEKLM;
1637 double time = timeHit - propgationT;
1638
1639 h_time_scint_end->Fill(time);
1640 h_temp->Fill(time);
1641
1642 if (m_saveAllPlots) {
1643 h_timeF_scint_end[iF]->Fill(time);
1644 h_timeFS_scint_end[iF][iS]->Fill(time);
1645 h_timeFSL_end[iF][iS][iL]->Fill(time);
1646 h_timeFSLP_end[iF][iS][iL][iP]->Fill(time);
1647 h2_timeF_scint_end[iF]->Fill(iS, time);
1648 h2_timeFS_end[iF][iS]->Fill(iL, time);
1649 h2_timeFSLP_end[iF][iS][iL][iP]->Fill(iC, time);
1650 }
1651 }
1652 }
1653
1654 TFitResultPtr r = h_temp->Fit(fcn_gaus, "LESQ");
1655 if (int(r) == 0) {
1656 m_cFlag[channelId] = ChannelCalibrationStatus::c_SuccessfulCalibration;
1657 m_time_channel[channelId] = fcn_gaus->GetParameter(1);
1658 m_etime_channel[channelId] = fcn_gaus->GetParError(1);
1659 }
1660
1661 // Get the appropriate directory for this channel
1662 TDirectory* dir = (iSub == KLMElementNumbers::c_BKLM) ?
1663 m_channelHistDir_BKLM[iF][iS][iL][iP] :
1664 m_channelHistDir_EKLM[iF][iS][iL][iP];
1666 }
1667
1668 m_evts.clear();
1669 B2INFO("Batch processed and cleared: " << batch.first);
1670 }
1671
1672 B2INFO("Original filling done.");
1673
1674 // Fill TGraphs with extracted parameters
1675 int iChannel_rpc = 0;
1676 int iChannel = 0;
1677 int iChannel_end = 0;
1678 for (KLMChannelIndex klmChannel = m_klmChannels.begin(); klmChannel != m_klmChannels.end(); ++klmChannel) {
1679 channelId = klmChannel.getKLMChannelNumber();
1680 if (m_cFlag[channelId] != ChannelCalibrationStatus::c_SuccessfulCalibration)
1681 continue;
1682
1683 int iSub = klmChannel.getSubdetector();
1684 if (iSub == KLMElementNumbers::c_BKLM) {
1685 int iL = klmChannel.getLayer() - 1;
1686 // FIXED: Use constant instead of hardcoded value
1687 if (iL >= (BKLMElementNumbers::c_FirstRPCLayer - 1)) {
1688 gre_time_channel_rpc->SetPoint(iChannel_rpc, channelId, m_time_channel[channelId]);
1689 gre_time_channel_rpc->SetPointError(iChannel_rpc, 0., m_etime_channel[channelId]);
1690 iChannel_rpc++;
1691 } else {
1692 gre_time_channel_scint->SetPoint(iChannel, channelId, m_time_channel[channelId]);
1693 gre_time_channel_scint->SetPointError(iChannel, 0., m_etime_channel[channelId]);
1694 iChannel++;
1695 }
1696 } else {
1697 gre_time_channel_scint_end->SetPoint(iChannel_end, channelId, m_time_channel[channelId]);
1698 gre_time_channel_scint_end->SetPointError(iChannel_end, 0., m_etime_channel[channelId]);
1699 iChannel_end++;
1700 }
1701 }
1702
1703 gre_time_channel_scint->Fit("fcn_const", "EMQ");
1704 m_time_channelAvg_scint = fcn_const->GetParameter(0);
1705 m_etime_channelAvg_scint = fcn_const->GetParError(0);
1706
1707 gre_time_channel_scint_end->Fit("fcn_const", "EMQ");
1708 m_time_channelAvg_scint_end = fcn_const->GetParameter(0);
1709 m_etime_channelAvg_scint_end = fcn_const->GetParError(0);
1710
1711 gre_time_channel_rpc->Fit("fcn_const", "EMQ");
1712 m_time_channelAvg_rpc = fcn_const->GetParameter(0);
1713 m_etime_channelAvg_rpc = fcn_const->GetParError(0);
1714
1715 B2INFO("Channel's time distribution fitting done.");
1716 B2DEBUG(20, LogVar("Average time (RPC)", m_time_channelAvg_rpc)
1717 << LogVar("Average time (BKLM scintillators)", m_time_channelAvg_scint)
1718 << LogVar("Average time (EKLM scintillators)", m_time_channelAvg_scint_end));
1719
1720 B2INFO("Calibrated channel's time distribution filling begins.");
1721
1722 m_timeShift.clear();
1723 for (KLMChannelIndex klmChannel = m_klmChannels.begin(); klmChannel != m_klmChannels.end(); ++klmChannel) {
1724 channelId = klmChannel.getKLMChannelNumber();
1725 h_calibrated->Fill(m_cFlag[channelId]);
1726 if (m_time_channel.find(channelId) == m_time_channel.end())
1727 continue;
1728 double timeShift = m_time_channel[channelId];
1729 m_timeShift[channelId] = timeShift;
1730 m_timeCableDelay->setTimeDelay(channelId, m_timeShift[channelId]);
1731 }
1732
1733 for (KLMChannelIndex klmChannel = m_klmChannels.begin(); klmChannel != m_klmChannels.end(); ++klmChannel) {
1734 channelId = klmChannel.getKLMChannelNumber();
1735 if (m_timeShift.find(channelId) != m_timeShift.end())
1736 continue;
1737 m_timeShift[channelId] = esti_timeShift(klmChannel);
1738 m_timeCableDelay->setTimeDelay(channelId, m_timeShift[channelId]);
1739 B2DEBUG(20, "Uncalibrated Estimation " << LogVar("Channel", channelId) << LogVar("Estimated value", m_timeShift[channelId]));
1740 }
1741
1742 iChannel_rpc = 0;
1743 iChannel = 0;
1744 iChannel_end = 0;
1745 for (KLMChannelIndex klmChannel = m_klmChannels.begin(); klmChannel != m_klmChannels.end(); ++klmChannel) {
1746 channelId = klmChannel.getKLMChannelNumber();
1747 if (m_timeShift.find(channelId) == m_timeShift.end()) {
1748 B2ERROR("!!! Not All Channels Calibration Constant Set. Error Happened on " << LogVar("Channel", channelId));
1749 continue;
1750 }
1751 int iSub = klmChannel.getSubdetector();
1752 if (iSub == KLMElementNumbers::c_BKLM) {
1753 // FIXED: Use 0-indexed layer and constant
1754 int iL = klmChannel.getLayer() - 1;
1755 if (iL >= (BKLMElementNumbers::c_FirstRPCLayer - 1)) {
1756 gr_timeShift_channel_rpc->SetPoint(iChannel_rpc, channelId, m_timeShift[channelId]);
1757 iChannel_rpc++;
1758 } else {
1759 gr_timeShift_channel_scint->SetPoint(iChannel, channelId, m_timeShift[channelId]);
1760 iChannel++;
1761 }
1762 } else {
1763 gr_timeShift_channel_scint_end->SetPoint(iChannel_end, channelId, m_timeShift[channelId]);
1764 iChannel_end++;
1765 }
1766 }
1767
1768 // NOTE: This also needs batching
1773
1774 /**********************************
1775 * FOURTH LOOP (BATCHED)
1776 * Fill calibrated per-channel histograms
1777 **********************************/
1778 B2INFO("Fourth loop: Calibrated time distribution filling (batched processing)...");
1779
1780 for (const auto& batch : batches) {
1781 B2INFO("Processing batch: " << batch.first);
1782 readCalibrationDataBatch(batch.second);
1783
1784 for (KLMChannelIndex klmChannel = m_klmChannels.begin(); klmChannel != m_klmChannels.end(); ++klmChannel) {
1785 channelId = klmChannel.getKLMChannelNumber();
1786
1787 if (!batch.second(klmChannel))
1788 continue;
1789
1790 if (m_evts.find(channelId) == m_evts.end())
1791 continue;
1792
1793 eventsChannel = m_evts[channelId];
1794 int iSub = klmChannel.getSubdetector();
1795 int iF, iS, iL, iP, iC;
1796
1797 if (iSub == KLMElementNumbers::c_BKLM) {
1798 iF = klmChannel.getSection();
1799 iS = klmChannel.getSector() - 1;
1800 iL = klmChannel.getLayer() - 1;
1801 iP = klmChannel.getPlane();
1802 iC = klmChannel.getStrip() - 1;
1803 } else {
1804 iF = klmChannel.getSection() - 1;
1805 iS = klmChannel.getSector() - 1;
1806 iL = klmChannel.getLayer() - 1;
1807 iP = klmChannel.getPlane() - 1;
1808 iC = klmChannel.getStrip() - 1;
1809 }
1810
1811 TString hn, ht;
1812 TH1F* hc_temp = nullptr;
1813
1814 if (iSub == KLMElementNumbers::c_BKLM) {
1815 // FIXED: Use constant instead of hardcoded value
1816 if (iL >= (BKLMElementNumbers::c_FirstRPCLayer - 1)) {
1817 hn = Form("hc_timeF%d_S%d_L%d_P%d_C%d", iF, iS, iL, iP, iC);
1818 ht = Form("Calibrated time distribution for RPC of Channel%d, %s, Layer%d, Sector%d, %s",
1819 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1820 hc_temp = new TH1F(hn.Data(), ht.Data(), nBin, m_LowerTimeBoundaryCalibratedRPC,
1822 } else {
1823 hn = Form("hc_timeF%d_S%d_L%d_P%d_C%d", iF, iS, iL, iP, iC);
1824 ht = Form("Calibrated time distribution for Scintillator of Channel%d, %s, Layer%d, Sector%d, %s",
1825 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1826 hc_temp = new TH1F(hn.Data(), ht.Data(), nBin_scint, m_LowerTimeBoundaryCalibratedScintillatorsBKLM,
1828 }
1829 } else {
1830 hn = Form("hc_timeF%d_S%d_L%d_P%d_C%d_end", iF, iS, iL, iP, iC);
1831 ht = Form("Calibrated time distribution for Scintillator of Channel%d, %s, Layer%d, Sector%d, %s (Endcap)",
1832 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1833 hc_temp = new TH1F(hn.Data(), ht.Data(), nBin_scint, m_LowerTimeBoundaryCalibratedScintillatorsEKLM,
1835 }
1836
1837 for (const Event& event : eventsChannel) {
1838 // Add ADC cut
1839 if (!passesADCCut(event, iSub, iL))
1840 continue;
1841
1842 double timeHit = event.time();
1843 if (m_useEventT0)
1844 timeHit = timeHit - event.t0;
1845 if (timeHit <= -400e3)
1846 continue;
1847
1848 if (iSub == KLMElementNumbers::c_BKLM) {
1849 // FIXED: Use constant instead of hardcoded value
1850 if (iL >= (BKLMElementNumbers::c_FirstRPCLayer - 1)) {
1851 double propgationT;
1853 propgationT = event.dist * delayRPCZ;
1854 else
1855 propgationT = event.dist * delayRPCPhi;
1856 double time = timeHit - propgationT - m_timeShift[channelId];
1857
1858 hc_time_rpc->Fill(time);
1859 hc_temp->Fill(time);
1860
1861 if (m_saveAllPlots) {
1862 hc_timeF_rpc[iF]->Fill(time);
1863 hc_timeFS_rpc[iF][iS]->Fill(time);
1864 hc_timeFSL[iF][iS][iL]->Fill(time);
1865 hc_timeFSLP[iF][iS][iL][iP]->Fill(time);
1866 h2c_timeF_rpc[iF]->Fill(iS, time);
1867 h2c_timeFS[iF][iS]->Fill(iL, time);
1868 h2c_timeFSLP[iF][iS][iL][iP]->Fill(iC, time);
1869 }
1870 } else {
1871 double propgationT = event.dist * delayBKLM;
1872 double time = timeHit - propgationT - m_timeShift[channelId];
1873
1874 hc_time_scint->Fill(time);
1875 hc_temp->Fill(time);
1876
1877 if (m_saveAllPlots) {
1878 hc_timeF_scint[iF]->Fill(time);
1879 hc_timeFS_scint[iF][iS]->Fill(time);
1880 hc_timeFSL[iF][iS][iL]->Fill(time);
1881 hc_timeFSLP[iF][iS][iL][iP]->Fill(time);
1882 h2c_timeF_scint[iF]->Fill(iS, time);
1883 h2c_timeFS[iF][iS]->Fill(iL, time);
1884 h2c_timeFSLP[iF][iS][iL][iP]->Fill(iC, time);
1885 }
1886 }
1887 } else {
1888 double propgationT = event.dist * delayEKLM;
1889 double time = timeHit - propgationT - m_timeShift[channelId];
1890
1891 hc_time_scint_end->Fill(time);
1892 hc_temp->Fill(time);
1893
1894 if (m_saveAllPlots) {
1895 hc_timeF_scint_end[iF]->Fill(time);
1896 hc_timeFS_scint_end[iF][iS]->Fill(time);
1897 hc_timeFSL_end[iF][iS][iL]->Fill(time);
1898 hc_timeFSLP_end[iF][iS][iL][iP]->Fill(time);
1899 h2c_timeF_scint_end[iF]->Fill(iS, time);
1900 h2c_timeFS_end[iF][iS]->Fill(iL, time);
1901 h2c_timeFSLP_end[iF][iS][iL][iP]->Fill(iC, time);
1902 }
1903 }
1904 }
1905
1906 if (m_cFlag[channelId] == ChannelCalibrationStatus::c_NotEnoughData) {
1907 delete hc_temp;
1908 continue;
1909 }
1910
1911 TFitResultPtr rc = hc_temp->Fit(fcn_gaus, "LESQ");
1912 if (int(rc) == 0) {
1913 m_cFlag[channelId] = ChannelCalibrationStatus::c_SuccessfulCalibration;
1914 m_ctime_channel[channelId] = fcn_gaus->GetParameter(1);
1915 mc_etime_channel[channelId] = fcn_gaus->GetParError(1);
1916 }
1917
1918 // Get the appropriate directory for this channel
1919 TDirectory* dir = (iSub == KLMElementNumbers::c_BKLM) ?
1920 m_channelHistDir_BKLM[iF][iS][iL][iP] :
1921 m_channelHistDir_EKLM[iF][iS][iL][iP];
1922 writeThenDelete_(hc_temp, m_saveChannelHists, dir);
1923 }
1924
1925 m_evts.clear();
1926 B2INFO("Batch processed and cleared: " << batch.first);
1927 }
1928
1929 // Fill TGraphs with calibrated parameters
1930 int icChannel_rpc = 0;
1931 int icChannel = 0;
1932 int icChannel_end = 0;
1933 for (KLMChannelIndex klmChannel = m_klmChannels.begin(); klmChannel != m_klmChannels.end(); ++klmChannel) {
1934 channelId = klmChannel.getKLMChannelNumber();
1935 if (m_cFlag[channelId] != ChannelCalibrationStatus::c_SuccessfulCalibration)
1936 continue;
1937
1938 int iSub = klmChannel.getSubdetector();
1939 if (iSub == KLMElementNumbers::c_BKLM) {
1940 int iL = klmChannel.getLayer() - 1;
1941 // FIXED: Use constant instead of hardcoded value
1942 if (iL >= (BKLMElementNumbers::c_FirstRPCLayer - 1)) {
1943 gre_ctime_channel_rpc->SetPoint(icChannel_rpc, channelId, m_ctime_channel[channelId]);
1944 gre_ctime_channel_rpc->SetPointError(icChannel_rpc, 0., mc_etime_channel[channelId]);
1945 icChannel_rpc++;
1946 } else {
1947 gre_ctime_channel_scint->SetPoint(icChannel, channelId, m_ctime_channel[channelId]);
1948 gre_ctime_channel_scint->SetPointError(icChannel, 0., mc_etime_channel[channelId]);
1949 icChannel++;
1950 }
1951 } else {
1952 gre_ctime_channel_scint_end->SetPoint(icChannel_end, channelId, m_ctime_channel[channelId]);
1953 gre_ctime_channel_scint_end->SetPointError(icChannel_end, 0., mc_etime_channel[channelId]);
1954 icChannel_end++;
1955 }
1956 }
1957
1958 gre_ctime_channel_scint->Fit("fcn_const", "EMQ");
1959 m_ctime_channelAvg_scint = fcn_const->GetParameter(0);
1960 mc_etime_channelAvg_scint = fcn_const->GetParError(0);
1961
1962 gre_ctime_channel_scint_end->Fit("fcn_const", "EMQ");
1963 m_ctime_channelAvg_scint_end = fcn_const->GetParameter(0);
1964 mc_etime_channelAvg_scint_end = fcn_const->GetParError(0);
1965
1966 gre_ctime_channel_rpc->Fit("fcn_const", "EMQ");
1967 m_ctime_channelAvg_rpc = fcn_const->GetParameter(0);
1968 mc_etime_channelAvg_rpc = fcn_const->GetParError(0);
1969
1970 B2INFO("Channel's time distribution fitting done.");
1971 B2DEBUG(20, LogVar("Average calibrated time (RPC)", m_ctime_channelAvg_rpc)
1972 << LogVar("Average calibrated time (BKLM scintillators)", m_ctime_channelAvg_scint)
1973 << LogVar("Average calibrated time (EKLM scintillators)", m_ctime_channelAvg_scint_end));
1974
1975 B2INFO("Calibrated channel's time distribution filling begins.");
1976
1977 m_timeRes.clear();
1978 for (KLMChannelIndex klmChannel = m_klmChannels.begin(); klmChannel != m_klmChannels.end(); ++klmChannel) {
1979 channelId = klmChannel.getKLMChannelNumber();
1980 hc_calibrated->Fill(m_cFlag[channelId]);
1981 if (m_ctime_channel.find(channelId) == m_ctime_channel.end())
1982 continue;
1983 double timeRes = m_ctime_channel[channelId];
1984 m_timeRes[channelId] = timeRes;
1985 m_timeResolution->setTimeResolution(channelId, m_timeRes[channelId]);
1986 }
1987
1988 for (KLMChannelIndex klmChannel = m_klmChannels.begin(); klmChannel != m_klmChannels.end(); ++klmChannel) {
1989 channelId = klmChannel.getKLMChannelNumber();
1990 if (m_timeRes.find(channelId) != m_timeRes.end())
1991 continue;
1992 m_timeRes[channelId] = esti_timeRes(klmChannel);
1993 m_timeResolution->setTimeResolution(channelId, m_timeRes[channelId]);
1994 B2DEBUG(20, "Calibrated Estimation " << LogVar("Channel", channelId) << LogVar("Estimated value", m_timeRes[channelId]));
1995 }
1996
1997 icChannel_rpc = 0;
1998 icChannel = 0;
1999 icChannel_end = 0;
2000 for (KLMChannelIndex klmChannel = m_klmChannels.begin(); klmChannel != m_klmChannels.end(); ++klmChannel) {
2001 channelId = klmChannel.getKLMChannelNumber();
2002 if (m_timeRes.find(channelId) == m_timeRes.end()) {
2003 B2ERROR("!!! Not All Channels Calibration Constant Set. Error Happened on " << LogVar("Channel", channelId));
2004 continue;
2005 }
2006 int iSub = klmChannel.getSubdetector();
2007 if (iSub == KLMElementNumbers::c_BKLM) {
2008 // FIXED: Use 0-indexed layer and constant
2009 int iL = klmChannel.getLayer() - 1;
2010 if (iL >= (BKLMElementNumbers::c_FirstRPCLayer - 1)) {
2011 gr_timeRes_channel_rpc->SetPoint(icChannel_rpc, channelId, m_timeRes[channelId]);
2012 icChannel_rpc++;
2013 } else {
2014 gr_timeRes_channel_scint->SetPoint(icChannel, channelId, m_timeRes[channelId]);
2015 icChannel++;
2016 }
2017 } else {
2018 gr_timeRes_channel_scint_end->SetPoint(icChannel_end, channelId, m_timeRes[channelId]);
2019 icChannel_end++;
2020 }
2021 }
2022
2023 // ===================================================================
2024 // FIFTH PASS: Di-muon EventT0 analysis for hit resolution calibration
2025 // ===================================================================
2026 B2INFO("Fifth pass: Computing di-muon ΔT0 for EventT0 hit resolution calibration...");
2027
2028 // Data structure for per-track T0 accumulation
2029 struct TrackT0Info {
2030 int charge;
2031 int nHits_BKLM_Scint;
2032 int nHits_BKLM_RPC_Phi; // Split RPC by readout direction
2033 int nHits_BKLM_RPC_Z;
2034 int nHits_EKLM_Scint;
2035 double sumT0_BKLM_Scint;
2036 double sumT0_BKLM_RPC_Phi;
2037 double sumT0_BKLM_RPC_Z;
2038 double sumT0_EKLM_Scint;
2039
2040 TrackT0Info() : charge(0),
2041 nHits_BKLM_Scint(0),
2042 nHits_BKLM_RPC_Phi(0),
2043 nHits_BKLM_RPC_Z(0),
2044 nHits_EKLM_Scint(0),
2045 sumT0_BKLM_Scint(0.0),
2046 sumT0_BKLM_RPC_Phi(0.0),
2047 sumT0_BKLM_RPC_Z(0.0),
2048 sumT0_EKLM_Scint(0.0) {}
2049 };
2050
2051 // Map: (Run, Event) -> (nTrack -> TrackT0Info)
2052 std::map<std::pair<int, int>, std::map<int, TrackT0Info>> eventTrackMap;
2053
2054 // Process all data in batches to build event-track map
2055 for (const auto& batch : batches) {
2056 B2INFO("Processing batch for di-muon analysis: " << batch.first);
2057 readCalibrationDataBatch(batch.second);
2058
2059 for (const auto& channelPair : m_evts) {
2060 KLMChannelNumber chId = channelPair.first;
2061 const std::vector<Event>& chEvents = channelPair.second;
2062
2063 // Get channel geometry
2064 int subdetector, section, sector, layer, plane, strip;
2065 m_ElementNumbers->channelNumberToElementNumbers(
2066 chId, &subdetector, &section, &sector, &layer, &plane, &strip);
2067
2068 // Convert to 0-indexed immediately (consistent with loops 1-4)
2069 int iSub = subdetector;
2070 int iL = layer - 1;
2071
2072 for (const Event& event : chEvents) {
2073 // Apply ADC cut with 0-indexed layer
2074 if (!passesADCCut(event, iSub, iL))
2075 continue;
2076
2077 // Event and track identification
2078 std::pair<int, int> eventKey(event.Run, event.Events);
2079 int trackIdx = event.nTrack;
2080 int charge = event.Track_Charge;
2081
2082 // Compute calibrated time for this hit
2083 double timeHit = event.time() - m_timeShift[chId];
2084
2085 if (timeHit <= -400e3)
2086 continue;
2087
2088 // Apply propagation correction (using 0-indexed layer)
2089 double propT = 0.0;
2090 if (iSub == KLMElementNumbers::c_BKLM) {
2091 if (iL >= (BKLMElementNumbers::c_FirstRPCLayer - 1)) {
2092 // RPC
2093 if (plane == BKLMElementNumbers::c_ZPlane)
2094 propT = event.dist * delayRPCZ;
2095 else
2096 propT = event.dist * delayRPCPhi;
2097 } else {
2098 // Scintillator
2099 propT = event.dist * delayBKLM;
2100 }
2101 } else {
2102 // EKLM
2103 propT = event.dist * delayEKLM;
2104 }
2105
2106 double t0_estimate = timeHit - propT;
2107
2108 // Accumulate per-track T0
2109 TrackT0Info& trackInfo = eventTrackMap[eventKey][trackIdx];
2110 trackInfo.charge = charge;
2111
2112 if (iSub == KLMElementNumbers::c_BKLM) {
2113 if (iL >= (BKLMElementNumbers::c_FirstRPCLayer - 1)) {
2114 // RPC - split by readout direction
2115 if (plane == BKLMElementNumbers::c_ZPlane) {
2116 trackInfo.nHits_BKLM_RPC_Z++;
2117 trackInfo.sumT0_BKLM_RPC_Z += t0_estimate;
2118 } else {
2119 trackInfo.nHits_BKLM_RPC_Phi++;
2120 trackInfo.sumT0_BKLM_RPC_Phi += t0_estimate;
2121 }
2122 } else {
2123 // Scintillator
2124 trackInfo.nHits_BKLM_Scint++;
2125 trackInfo.sumT0_BKLM_Scint += t0_estimate;
2126 }
2127 } else {
2128 trackInfo.nHits_EKLM_Scint++;
2129 trackInfo.sumT0_EKLM_Scint += t0_estimate;
2130 }
2131 }
2132 }
2133
2134 m_evts.clear();
2135 }
2136
2137 B2INFO("Event-track map built. Processing events for EventT0 histograms...");
2138
2139 // Accumulators for variance calculation using the Gaussian MLE
2140 // Model: ΔT0_i ~ N(0, σ_hit^2 * v_i), v_i = 1/N⁺_i + 1/N⁻_i
2141 double sum_delta2_over_v_BKLM_Scint = 0.0;
2142 double sum_delta2_over_v_BKLM_RPC_Phi = 0.0;
2143 double sum_delta2_over_v_BKLM_RPC_Z = 0.0;
2144 double sum_delta2_over_v_EKLM_Scint = 0.0;
2145
2146 int nDimuon_BKLM_Scint = 0;
2147 int nDimuon_BKLM_RPC_Phi = 0;
2148 int nDimuon_BKLM_RPC_Z = 0;
2149 int nDimuon_EKLM_Scint = 0;
2150
2151 for (const auto& eventPair : eventTrackMap) {
2152 const auto& trackMap = eventPair.second;
2153
2154 // Check if exactly 2 tracks (di-muon candidate)
2155 if (trackMap.size() != 2)
2156 continue;
2157
2158 auto it1 = trackMap.begin();
2159 auto it2 = trackMap.begin();
2160 ++it2;
2161 const TrackT0Info& track1 = it1->second;
2162 const TrackT0Info& track2 = it2->second;
2163
2164 // Check opposite charges
2165 if (track1.charge * track2.charge >= 0)
2166 continue;
2167
2168 // Identify mu+ and mu-
2169 const TrackT0Info& muPlus = (track1.charge > 0) ? track1 : track2;
2170 const TrackT0Info& muMinus = (track1.charge > 0) ? track2 : track1;
2171
2172 // === BKLM Scintillator ===
2173 if (muPlus.nHits_BKLM_Scint > 0 && muMinus.nHits_BKLM_Scint > 0) {
2174 double t0_plus = muPlus.sumT0_BKLM_Scint / muPlus.nHits_BKLM_Scint;
2175 double t0_minus = muMinus.sumT0_BKLM_Scint / muMinus.nHits_BKLM_Scint;
2176 double deltaT0 = t0_plus - t0_minus;
2177
2178 // v = 1/N⁺ + 1/N⁻ for this event
2179 double v = 1.0 / muPlus.nHits_BKLM_Scint + 1.0 / muMinus.nHits_BKLM_Scint;
2180 int nTotal = muPlus.nHits_BKLM_Scint + muMinus.nHits_BKLM_Scint;
2181
2182 if (v <= 0.0)
2183 continue;
2184
2185 // Accumulate for σ_hit^2 = (1/N_evt) Σ [ ΔT0^2 / v ]
2186 sum_delta2_over_v_BKLM_Scint += (deltaT0 * deltaT0) / v;
2187 nDimuon_BKLM_Scint++;
2188
2189 // Histograms for monitoring
2190 h_eventT0_scint->Fill(t0_plus);
2191 h_eventT0_scint->Fill(t0_minus);
2192 hc_eventT0_scint->Fill(deltaT0);
2193
2194 // ==== NEW DIAGNOSTIC FILLS ====
2195 h_nHits_plus_scint->Fill(muPlus.nHits_BKLM_Scint);
2196 h_nHits_minus_scint->Fill(muMinus.nHits_BKLM_Scint);
2197 h2_deltaT0_vs_v_scint->Fill(v, deltaT0);
2198 prof_deltaT0_rms_vs_v_scint->Fill(v, deltaT0);
2199 h2_deltaT0_vs_nhits_scint->Fill(nTotal, deltaT0);
2200
2201 // Fill multiplicity-binned histograms
2202 if (nTotal < 5) {
2203 hc_eventT0_scint_lowN->Fill(deltaT0);
2204 } else if (nTotal < 15) {
2205 hc_eventT0_scint_midN->Fill(deltaT0);
2206 } else {
2207 hc_eventT0_scint_highN->Fill(deltaT0);
2208 }
2209 }
2210
2211 // === BKLM RPC Phi ===
2212 if (muPlus.nHits_BKLM_RPC_Phi > 0 && muMinus.nHits_BKLM_RPC_Phi > 0) {
2213 double t0_plus = muPlus.sumT0_BKLM_RPC_Phi / muPlus.nHits_BKLM_RPC_Phi;
2214 double t0_minus = muMinus.sumT0_BKLM_RPC_Phi / muMinus.nHits_BKLM_RPC_Phi;
2215 double deltaT0 = t0_plus - t0_minus;
2216
2217 double v = 1.0 / muPlus.nHits_BKLM_RPC_Phi + 1.0 / muMinus.nHits_BKLM_RPC_Phi;
2218 int nTotal = muPlus.nHits_BKLM_RPC_Phi + muMinus.nHits_BKLM_RPC_Phi;
2219
2220 if (v <= 0.0)
2221 continue;
2222
2223 sum_delta2_over_v_BKLM_RPC_Phi += (deltaT0 * deltaT0) / v;
2224 nDimuon_BKLM_RPC_Phi++;
2225
2226 h_eventT0_rpc->Fill(t0_plus);
2227 h_eventT0_rpc->Fill(t0_minus);
2228 hc_eventT0_rpc->Fill(deltaT0);
2229
2230 // Diagnostic fills
2231 h_nHits_plus_rpc->Fill(muPlus.nHits_BKLM_RPC_Phi);
2232 h_nHits_minus_rpc->Fill(muMinus.nHits_BKLM_RPC_Phi);
2233 h2_deltaT0_vs_v_rpc->Fill(v, deltaT0);
2234 prof_deltaT0_rms_vs_v_rpc->Fill(v, deltaT0);
2235 h2_deltaT0_vs_nhits_rpc->Fill(nTotal, deltaT0);
2236
2237 if (nTotal < 10) {
2238 hc_eventT0_rpc_lowN->Fill(deltaT0);
2239 } else if (nTotal < 30) {
2240 hc_eventT0_rpc_midN->Fill(deltaT0);
2241 } else {
2242 hc_eventT0_rpc_highN->Fill(deltaT0);
2243 }
2244 }
2245
2246 // === BKLM RPC Z ===
2247 if (muPlus.nHits_BKLM_RPC_Z > 0 && muMinus.nHits_BKLM_RPC_Z > 0) {
2248 double t0_plus = muPlus.sumT0_BKLM_RPC_Z / muPlus.nHits_BKLM_RPC_Z;
2249 double t0_minus = muMinus.sumT0_BKLM_RPC_Z / muMinus.nHits_BKLM_RPC_Z;
2250 double deltaT0 = t0_plus - t0_minus;
2251
2252 double v = 1.0 / muPlus.nHits_BKLM_RPC_Z + 1.0 / muMinus.nHits_BKLM_RPC_Z;
2253 int nTotal = muPlus.nHits_BKLM_RPC_Z + muMinus.nHits_BKLM_RPC_Z;
2254
2255 if (v <= 0.0)
2256 continue;
2257
2258 sum_delta2_over_v_BKLM_RPC_Z += (deltaT0 * deltaT0) / v;
2259 nDimuon_BKLM_RPC_Z++;
2260
2261 h_eventT0_rpc->Fill(t0_plus);
2262 h_eventT0_rpc->Fill(t0_minus);
2263 hc_eventT0_rpc->Fill(deltaT0);
2264
2265 // Diagnostic fills
2266 h_nHits_plus_rpc->Fill(muPlus.nHits_BKLM_RPC_Z);
2267 h_nHits_minus_rpc->Fill(muMinus.nHits_BKLM_RPC_Z);
2268 h2_deltaT0_vs_v_rpc->Fill(v, deltaT0);
2269 prof_deltaT0_rms_vs_v_rpc->Fill(v, deltaT0);
2270 h2_deltaT0_vs_nhits_rpc->Fill(nTotal, deltaT0);
2271
2272 if (nTotal < 10) {
2273 hc_eventT0_rpc_lowN->Fill(deltaT0);
2274 } else if (nTotal < 30) {
2275 hc_eventT0_rpc_midN->Fill(deltaT0);
2276 } else {
2277 hc_eventT0_rpc_highN->Fill(deltaT0);
2278 }
2279 }
2280
2281 // === EKLM Scintillator ===
2282 if (muPlus.nHits_EKLM_Scint > 0 && muMinus.nHits_EKLM_Scint > 0) {
2283 double t0_plus = muPlus.sumT0_EKLM_Scint / muPlus.nHits_EKLM_Scint;
2284 double t0_minus = muMinus.sumT0_EKLM_Scint / muMinus.nHits_EKLM_Scint;
2285 double deltaT0 = t0_plus - t0_minus;
2286
2287 double v = 1.0 / muPlus.nHits_EKLM_Scint + 1.0 / muMinus.nHits_EKLM_Scint;
2288 int nTotal = muPlus.nHits_EKLM_Scint + muMinus.nHits_EKLM_Scint;
2289
2290 if (v <= 0.0)
2291 continue;
2292
2293 sum_delta2_over_v_EKLM_Scint += (deltaT0 * deltaT0) / v;
2294 nDimuon_EKLM_Scint++;
2295
2296 h_eventT0_scint_end->Fill(t0_plus);
2297 h_eventT0_scint_end->Fill(t0_minus);
2298 hc_eventT0_scint_end->Fill(deltaT0);
2299
2300 // ==== NEW DIAGNOSTIC FILLS ====
2301 h_nHits_plus_scint_end->Fill(muPlus.nHits_EKLM_Scint);
2302 h_nHits_minus_scint_end->Fill(muMinus.nHits_EKLM_Scint);
2303 h2_deltaT0_vs_v_scint_end->Fill(v, deltaT0);
2304 prof_deltaT0_rms_vs_v_scint_end->Fill(v, deltaT0);
2305 h2_deltaT0_vs_nhits_scint_end->Fill(nTotal, deltaT0);
2306
2307 // Fill multiplicity-binned histograms
2308 if (nTotal < 5) {
2309 hc_eventT0_scint_end_lowN->Fill(deltaT0);
2310 } else if (nTotal < 15) {
2311 hc_eventT0_scint_end_midN->Fill(deltaT0);
2312 } else {
2313 hc_eventT0_scint_end_highN->Fill(deltaT0);
2314 }
2315 }
2316 }
2317
2318 B2INFO("Di-muon ΔT0 data collected."
2319 << LogVar("BKLM Scint di-muon events", nDimuon_BKLM_Scint)
2320 << LogVar("BKLM RPC Phi di-muon events", nDimuon_BKLM_RPC_Phi)
2321 << LogVar("BKLM RPC Z di-muon events", nDimuon_BKLM_RPC_Z)
2322 << LogVar("EKLM Scint di-muon events", nDimuon_EKLM_Scint));
2323
2324 // === Extract σ_hit using the Gaussian MLE ===
2325 // σ_hit^2 = (1 / N_evt) Σ_i [ ΔT0_i^2 / (1/N⁺_i + 1/N⁻_i) ]
2326
2327 float sigma_BKLM_Scint = 10.0f; // Default fallback
2328 float sigma_BKLM_Scint_err = 1.0f;
2329 if (nDimuon_BKLM_Scint > 0) {
2330 double sigma2 = sum_delta2_over_v_BKLM_Scint / static_cast<double>(nDimuon_BKLM_Scint);
2331 sigma_BKLM_Scint = static_cast<float>(std::sqrt(sigma2));
2332 // Uncertainty approximation (Gaussian statistics)
2333 sigma_BKLM_Scint_err = sigma_BKLM_Scint / std::sqrt(2.0 * nDimuon_BKLM_Scint);
2334 }
2335
2336 float sigma_RPC_Phi = 10.0f;
2337 float sigma_RPC_Phi_err = 1.0f;
2338 if (nDimuon_BKLM_RPC_Phi > 0) {
2339 double sigma2 = sum_delta2_over_v_BKLM_RPC_Phi / static_cast<double>(nDimuon_BKLM_RPC_Phi);
2340 sigma_RPC_Phi = static_cast<float>(std::sqrt(sigma2));
2341 sigma_RPC_Phi_err = sigma_RPC_Phi / std::sqrt(2.0 * nDimuon_BKLM_RPC_Phi);
2342 }
2343
2344 float sigma_RPC_Z = 10.0f;
2345 float sigma_RPC_Z_err = 1.0f;
2346 if (nDimuon_BKLM_RPC_Z > 0) {
2347 double sigma2 = sum_delta2_over_v_BKLM_RPC_Z / static_cast<double>(nDimuon_BKLM_RPC_Z);
2348 sigma_RPC_Z = static_cast<float>(std::sqrt(sigma2));
2349 sigma_RPC_Z_err = sigma_RPC_Z / std::sqrt(2.0 * nDimuon_BKLM_RPC_Z);
2350 }
2351
2352 // Compute combined RPC sigma (weighted average by number of events)
2353 float sigma_RPC = 10.0f;
2354 float sigma_RPC_err = 1.0f;
2355 int nDimuon_RPC_total = nDimuon_BKLM_RPC_Phi + nDimuon_BKLM_RPC_Z;
2356 if (nDimuon_RPC_total > 0) {
2357 // Weighted average by statistics
2358 double w_phi = static_cast<double>(nDimuon_BKLM_RPC_Phi) / nDimuon_RPC_total;
2359 double w_z = static_cast<double>(nDimuon_BKLM_RPC_Z) / nDimuon_RPC_total;
2360 sigma_RPC = w_phi * sigma_RPC_Phi + w_z * sigma_RPC_Z;
2361 // Propagate uncertainties
2362 sigma_RPC_err = std::sqrt(w_phi * w_phi * sigma_RPC_Phi_err * sigma_RPC_Phi_err +
2363 w_z * w_z * sigma_RPC_Z_err * sigma_RPC_Z_err);
2364 }
2365
2366 float sigma_EKLM_Scint = 10.0f;
2367 float sigma_EKLM_Scint_err = 1.0f;
2368 if (nDimuon_EKLM_Scint > 0) {
2369 double sigma2 = sum_delta2_over_v_EKLM_Scint / static_cast<double>(nDimuon_EKLM_Scint);
2370 sigma_EKLM_Scint = static_cast<float>(std::sqrt(sigma2));
2371 sigma_EKLM_Scint_err = sigma_EKLM_Scint / std::sqrt(2.0 * nDimuon_EKLM_Scint);
2372 }
2373
2374 B2INFO("Extracted per-hit resolutions using event-by-event weighting:"
2375 << LogVar("σ_BKLM_Scint [ns]", sigma_BKLM_Scint) << LogVar("±", sigma_BKLM_Scint_err)
2376 << LogVar("σ_RPC_Phi [ns]", sigma_RPC_Phi) << LogVar("±", sigma_RPC_Phi_err)
2377 << LogVar("σ_RPC_Z [ns]", sigma_RPC_Z) << LogVar("±", sigma_RPC_Z_err)
2378 << LogVar("σ_RPC_combined [ns]", sigma_RPC) << LogVar("±", sigma_RPC_err)
2379 << LogVar("σ_EKLM_Scint [ns]", sigma_EKLM_Scint) << LogVar("±", sigma_EKLM_Scint_err));
2380
2381 // === Store in payload ===
2382 m_eventT0HitResolution->setSigmaBKLMScint(sigma_BKLM_Scint, sigma_BKLM_Scint_err);
2383 m_eventT0HitResolution->setSigmaRPC(sigma_RPC, sigma_RPC_err); // Combined for backward compatibility
2384 m_eventT0HitResolution->setSigmaRPCPhi(sigma_RPC_Phi, sigma_RPC_Phi_err); // Direction-specific
2385 m_eventT0HitResolution->setSigmaRPCZ(sigma_RPC_Z, sigma_RPC_Z_err); // Direction-specific
2386 m_eventT0HitResolution->setSigmaEKLMScint(sigma_EKLM_Scint, sigma_EKLM_Scint_err);
2387
2388 B2INFO("EventT0 hit resolution calibration complete and stored in payload.");
2389
2390 // Clear temporary data
2391 eventTrackMap.clear();
2392
2393 delete fcn_const;
2394 m_evts.clear();
2395 m_timeShift.clear();
2396 m_timeRes.clear();
2397 m_cFlag.clear();
2398
2399 saveHist();
2400
2401 saveCalibration(m_timeCableDelay, "KLMTimeCableDelay");
2402 saveCalibration(m_timeConstants, "KLMTimeConstants");
2403 saveCalibration(m_timeResolution, "KLMTimeResolution");
2404 saveCalibration(m_eventT0HitResolution, "KLMEventT0HitResolution");
2405
2407}
@ c_FirstRPCLayer
First RPC layer.
void saveCalibration(TClonesArray *data, const std::string &name)
Store DBArray payload with given name with default IOV.
EResult
The result of calibration.
@ c_OK
Finished successfully =0 in Python.
TProfile * m_Profile2EKLMScintillatorPlane2
For EKLM scintillator plane2.
TDirectory * m_channelHistDir_BKLM[2][8][15][2]
Directory structure for per-channel histograms (BKLM).
double mc_etime_channelAvg_rpc
Calibrated central value error of the global time distribution (BKLM RPC part).
TH2F * h2c_timeF_scint_end[2]
EKLM part.
KLMTimeResolution * m_timeResolution
DBObject of time resolution.
TH1F * hc_eventT0_scint_end_highN
Corrected EventT0 for EKLM scintillator with high hit count.
TProfile * prof_deltaT0_rms_vs_v_scint_end
DeltaT0 RMS vs inverse hit count profile for EKLM scintillator.
TH1F * h_time_scint_tc_end
EKLM part.
TH1F * hc_eventT0_scint_midN
Corrected EventT0 for BKLM scintillator with medium hit count.
void createHistograms()
Create histograms.
TGraphErrors * gre_time_channel_scint
BKLM Scintillator.
TH1F * h_timeFSL[2][8][15]
BKLM part.
TH1F * hc_timeFSL_end[2][4][14]
EKLM part.
TH1F * h_timeFSLP_end[2][4][14][2]
EKLM part.
TGraph * gr_timeRes_channel_rpc
BKLM RPC.
TH1F * hc_timeFSLP_end[2][4][14][2]
EKLM part.
TH1F * h_timeFSLP[2][8][15][2]
BKLM part.
TH1F * hc_timeF_scint_end[2]
EKLM part.
std::map< KLMChannelNumber, double > m_timeShift
Shift values of each channel.
TH1F * h_time_scint
BKLM scintillator part.
double m_time_channelAvg_scint
Central value of the global time distribution (BKLM scintillator part).
TH1F * hc_timeFS_scint_end[2][4]
EKLM part.
double esti_timeRes(const KLMChannelIndex &klmChannel)
Estimate value of calibration constant for calibrated channels.
double m_UpperTimeBoundaryCalibratedRPC
Upper time boundary for RPC (calibrated data).
double m_ctime_channelAvg_rpc
Calibrated central value of the global time distribution (BKLM RPC part).
KLMTimeConstants * m_timeConstants
DBObject of time cost on some parts of the detector.
void setupDatabase()
Setup the database.
TProfile * prof_deltaT0_rms_vs_v_rpc
DeltaT0 RMS vs inverse hit count profile for RPC.
TH1F * h_eventT0_scint
EventT0 seen by BKLM scintillator hits.
TH1F * hc_timeFS_scint[2][8]
BKLM scintillator part.
std::map< KLMChannelNumber, double > m_time_channel
Time distribution central value of each channel.
TH1F * hc_eventT0_rpc_lowN
Corrected EventT0 for RPC with low hit count.
double m_ctime_channelAvg_scint_end
Calibrated central value of the global time distribution (EKLM scintillator part).
CalibrationAlgorithm::EResult readCalibrationData()
Read calibration data.
TH1F * hc_eventT0_scint_lowN
Corrected EventT0 for BKLM scintillator with low hit count.
TGraph * gr_timeShift_channel_scint_end
EKLM.
TGraph * gr_timeRes_channel_scint
BKLM scintillator.
TH2F * h2_deltaT0_vs_v_scint
DeltaT0 vs inverse hit count for BKLM scintillator.
TH1F * hc_timeF_scint[2]
BKLM scintillator part.
TH1F * h_timeFS_scint[2][8]
BKLM scintillator part.
bool m_saveChannelHists
Write per-channel temporary histograms (tc/raw/hc) in minimal mode.
double m_UpperTimeBoundaryScintillatorsBKLM
Upper time boundary for BKLM scintillators.
void writeThenDelete_(TH1 *h, bool write, TDirectory *dir=nullptr)
Optionally write a histogram, then delete it to free memory.
TH1F * hc_timeF_rpc[2]
BKLM RPC part.
TH2F * h2c_timeFS_end[2][4]
EKLM part.
TGraphErrors * gre_ctime_channel_scint_end
EKLM.
TH1F * h_nHits_plus_scint_end
Number of EKLM scintillator hits per mu+ track.
TProfile * m_Profile2BKLMScintillatorPhi
For BKLM scintillator phi plane.
TH1F * hc_time_scint_end
EKLM part.
TH1F * hc_eventT0_scint
Corrected EventT0 for BKLM scintillator hits.
TGraphErrors * gre_time_channel_scint_end
EKLM.
TH2F * h2_timeFSLP[2][8][15][2]
BKLM part.
double m_UpperTimeBoundaryCalibratedScintillatorsEKLM
Upper time boundary for BKLM scintillators (calibrated data).
TGraph * gr_timeShift_channel_scint
BKLM scintillator.
double m_time_channelAvg_scint_end
Central value of the global time distribution (EKLM scintillator part).
TProfile * m_Profile2EKLMScintillatorPlane1
For EKLM scintillator plane1.
TH1F * hc_timeFS_rpc[2][8]
BKLM RPC part.
double m_UpperTimeBoundaryScintillatorsEKLM
Upper time boundary for BKLM scintillators.
void fillTimeDistanceProfiles(TProfile *profileRpcPhi, TProfile *profileRpcZ, TProfile *profileBKLMScintillatorPhi, TProfile *profileBKLMScintillatorZ, TProfile *profileEKLMScintillatorPlane1, TProfile *profileEKLMScintillatorPlane2, bool fill2dHistograms)
Fill profiles of time versus distance.
TFile * m_outFile
Output file.
double esti_timeShift(const KLMChannelIndex &klmChannel)
Estimate value of calibration constant for uncalibrated channels.
double m_LowerTimeBoundaryCalibratedScintillatorsEKLM
Lower time boundary for EKLM scintillators (calibrated data).
TH1F * hc_timeFSLP[2][8][15][2]
BKLM part.
TGraphErrors * gre_ctime_channel_rpc
BKLM RPC.
void saveHist()
Save histograms to file.
bool m_saveAllPlots
Default minimal unless you set true in your header script.
TH2F * h2c_timeFSLP[2][8][15][2]
BKLM part.
double m_ctime_channelAvg_scint
Calibrated central value of the global time distribution (BKLM scintillator part).
TF1 * fcn_const
Const function.
double m_UpperTimeBoundaryCalibratedScintillatorsBKLM
Upper time boundary for BKLM scintillators (calibrated data).
TProfile * m_Profile2RpcZ
For BKLM RPC z plane.
TH1F * h_nHits_minus_rpc
Number of RPC hits per mu- track.
TH2F * h2_timeFSLP_end[2][4][14][2]
EKLM part.
TH1I * hc_calibrated
Calibration statistics for each channel.
TH1F * h_eventT0_rpc
EventT0 seen by RPC hits.
void timeDistance2dFit(const std::vector< std::pair< KLMChannelNumber, unsigned int > > &channels, double &delay, double &delayError)
Two-dimensional fit for individual channels.
TGraph * gr_timeRes_channel_scint_end
EKLM.
TH1I * h_calibrated
Calibration statistics for each channel.
TProfile * m_ProfileBKLMScintillatorZ
For BKLM scintillator z plane.
double m_LowerTimeBoundaryScintillatorsBKLM
Lower time boundary for BKLM scintillators.
TH1F * hc_eventT0_scint_end_midN
Corrected EventT0 for EKLM scintillator with medium hit count.
TH1F * h_time_rpc_tc
BKLM RPC part.
TH1F * h_time_scint_end
EKLM part.
TH2F * h2c_timeF_scint[2]
BKLM scintillator part.
TF1 * fcn_pol1
Pol1 function.
double m_etime_channelAvg_scint_end
Central value error of the global time distribution (EKLM scintillator part).
TH1F * hc_time_rpc
BKLM RPC part.
double mc_etime_channelAvg_scint
Calibrated central value error of the global time distribution (BKLM scintillator part).
TH2F * h2c_timeFSLP_end[2][4][14][2]
EKLM part.
double mc_etime_channelAvg_scint_end
Calibrated central value error of the global time distribution (EKLM scintillator part).
bool passesADCCut(const Event &event, int subdetector, int layer) const
Check if event passes ADC count cuts for quality selection.
TH2F * h2_timeF_scint_end[2]
EKLM part.
KLMEventT0HitResolution * m_eventT0HitResolution
DBObject of per-hit time resolution for EventT0.
TF1 * fcn_gaus
Gaussian function.
double m_LowerTimeBoundaryCalibratedScintillatorsBKLM
Lower time boundary for BKLM scintillators (calibrated data).
TH1F * h_timeF_rpc[2]
BKLM RPC part.
TProfile * m_ProfileBKLMScintillatorPhi
For BKLM scintillator phi plane.
TH1F * hc_time_scint
BKLM scintillator part.
TH2F * h2_timeFS[2][8]
BKLM part.
double m_fixedRPCDelay
Fixed propagation delay for RPCs (ns/cm).
double m_etime_channelAvg_scint
Central value error of the global time distribution (BKLM scintillator part).
TH1F * h_timeF_scint_end[2]
EKLM part.
TH1F * hc_eventT0_scint_end
Corrected EventT0 for EKLM scintillator hits.
TProfile * m_ProfileRpcPhi
For BKLM RPC phi plane.
TGraphErrors * gre_ctime_channel_scint
BKLM Scintillator.
TH2F * h2_deltaT0_vs_nhits_scint
DeltaT0 vs total hit count for BKLM scintillator.
TH2F * h2_deltaT0_vs_nhits_rpc
DeltaT0 vs total hit count for RPC.
TProfile * m_ProfileEKLMScintillatorPlane2
For EKLM scintillator plane2.
TH1F * h_time_rpc
BKLM RPC part.
TH1F * h_timeFSL_end[2][4][14]
EKLM part.
TProfile * m_Profile2RpcPhi
For BKLM RPC phi plane.
TH1F * h_timeF_scint[2]
BKLM scintillator part.
TH1F * hc_timeFSL[2][8][15]
BKLM part.
TProfile * m_Profile2BKLMScintillatorZ
For BKLM scintillator z plane.
TH2F * h2_deltaT0_vs_v_scint_end
DeltaT0 vs inverse hit count for EKLM scintillator.
TH1F * h_timeFS_rpc[2][8]
BKLM RPC part.
KLMChannelIndex m_klmChannels
KLM ChannelIndex object.
TGraph * gr_timeShift_channel_rpc
BKLM RPC.
std::map< KLMChannelNumber, double > m_timeRes
Resolution values of each channel.
TH1F * h_eventT0_scint_end
EventT0 seen by EKLM scintillator hits.
TH1F * h_diff
Distance between global and local position.
TH1F * hc_eventT0_rpc_highN
Corrected EventT0 for RPC with high hit count.
TH1F * h_nHits_plus_scint
Number of BKLM scintillator hits per mu+ track.
TH2F * h2_timeF_scint[2]
BKLM scintillator part.
TH1F * h_time_scint_tc
BKLM scintillator part.
double m_LowerTimeBoundaryRPC
Lower time boundary for RPC.
std::map< KLMChannelNumber, double > m_ctime_channel
Calibrated time distribution central value of each channel.
double m_LowerTimeBoundaryCalibratedRPC
Lower time boundary for RPC (calibrated data).
TH2F * h2_deltaT0_vs_nhits_scint_end
DeltaT0 vs total hit count for EKLM scintillator.
bool m_useEventT0
Whether to use event T0 from CDC.
TProfile * m_ProfileEKLMScintillatorPlane1
For EKLM scintillator plane1.
double m_UpperTimeBoundaryRPC
Upper time boundary for RPC.
TH2F * h2c_timeF_rpc[2]
BKLM RPC part.
TH1F * hc_eventT0_scint_highN
Corrected EventT0 for BKLM scintillator with high hit count.
TF1 * fcn_land
Landau function.
KLMTimeCableDelay * m_timeCableDelay
DBObject of the calibration constant of each channel due to cable decay.
TH2F * h2_deltaT0_vs_v_rpc
DeltaT0 vs inverse hit count for RPC.
TProfile * m_ProfileRpcZ
For BKLM RPC z plane.
bool m_useFixedRPCDelay
Whether to use fixed propagation delay for RPCs.
std::map< KLMChannelNumber, double > mc_etime_channel
Calibrated time distribution central value Error of each channel.
void readCalibrationDataBatch(std::function< bool(const KLMChannelIndex &)> channelFilter)
Load calibration data for a specific batch of channels.
TH1F * hc_eventT0_rpc_midN
Corrected EventT0 for RPC with medium hit count.
TH1F * h_nHits_minus_scint
Number of BKLM scintillator hits per mu- track.
TProfile * prof_deltaT0_rms_vs_v_scint
DeltaT0 RMS vs inverse hit count profile for BKLM scintillator.
std::map< KLMChannelNumber, int > m_cFlag
Calibration flag if the channel has enough hits collected and fitted OK.
TGraphErrors * gre_time_channel_rpc
BKLM RPC.
TH2F * h2_timeFS_end[2][4]
EKLM part.
TH2F * h2_timeF_rpc[2]
BKLM RPC part.
TH1F * h_nHits_plus_rpc
Number of RPC hits per mu+ track.
std::map< KLMChannelNumber, std::vector< struct Event > > m_evts
Container of hit information.
TDirectory * m_channelHistDir_EKLM[2][4][14][2]
Directory structure for per-channel histograms (EKLM).
TH1F * hc_eventT0_rpc
Corrected EventT0 for RPC hits.
TH1F * h_nHits_minus_scint_end
Number of EKLM scintillator hits per mu- track.
TH1F * h_timeFS_scint_end[2][4]
EKLM part.
double m_time_channelAvg_rpc
Central value of the global time distribution (BKLM RPC part).
TH2F * h2c_timeFS[2][8]
BKLM part.
double m_etime_channelAvg_rpc
Central value error of the global time distribution (BKLM RPC part).
double m_LowerTimeBoundaryScintillatorsEKLM
Lower time boundary for EKLM scintillators.
void readCalibrationDataCounts(std::map< KLMChannelNumber, unsigned int > &eventCounts)
Count events per channel (lightweight scan without loading full data).
std::map< KLMChannelNumber, double > m_etime_channel
Time distribution central value Error of each channel.
int m_lower_limit_counts
Lower limit of hits collected for on single channel.
TH1F * hc_eventT0_scint_end_lowN
Corrected EventT0 for EKLM scintillator with low hit count.
void readCalibrationDataFor2DFit(const std::vector< std::pair< KLMChannelNumber, unsigned int > > &channelsBKLM, const std::vector< std::pair< KLMChannelNumber, unsigned int > > &channelsEKLM)
Load calibration data only for channels needed for 2D fit.
@ c_BKLM
BKLM scintillator.
@ c_EKLM
EKLM scintillator.
uint16_t KLMChannelNumber
Channel number.

◆ 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}

◆ createHistograms()

void createHistograms ( )
private

Create histograms.

Hist declaration Global time distribution

Definition at line 290 of file KLMTimeAlgorithm.cc.

291{
292 if (m_mc) {
299 } else {
300 m_LowerTimeBoundaryRPC = -800.0;
301 m_UpperTimeBoundaryRPC = -600.0;
306 }
307
308 // Create directory structure for per-channel histograms
309 // This must be done here (not in setupDatabase) because m_outFile is created just before this function is called
311 TDirectory* dir_channels = m_outFile->mkdir("channels", "Per-channel histograms", true);
312
313 // BKLM directories
314 TDirectory* dir_bklm = dir_channels->mkdir("BKLM", "", true);
315 TString sectionName[2] = {"Backward", "Forward"};
316 TString planeName[2] = {"Z", "Phi"};
317
318 for (int iF = 0; iF < 2; ++iF) {
319 TDirectory* dir_section = dir_bklm->mkdir(sectionName[iF].Data(), "", true);
320 for (int iS = 0; iS < 8; ++iS) {
321 TDirectory* dir_sector = dir_section->mkdir(Form("Sector_%d", iS + 1), "", true);
322 for (int iL = 0; iL < 15; ++iL) {
323 TDirectory* dir_layer = dir_sector->mkdir(Form("Layer_%d", iL + 1), "", true);
324 for (int iP = 0; iP < 2; ++iP) {
325 m_channelHistDir_BKLM[iF][iS][iL][iP] = dir_layer->mkdir(Form("Plane_%s", planeName[iP].Data()), "", true);
326 }
327 }
328 }
329 }
330
331 // EKLM directories
332 TDirectory* dir_eklm = dir_channels->mkdir("EKLM", "", true);
333 for (int iF = 0; iF < 2; ++iF) {
334 TDirectory* dir_section = dir_eklm->mkdir(sectionName[iF].Data(), "", true);
335 for (int iS = 0; iS < 4; ++iS) {
336 TDirectory* dir_sector = dir_section->mkdir(Form("Sector_%d", iS + 1), "", true);
337 int maxLayer = 12 + 2 * iF; // 12 for backward, 14 for forward
338 for (int iL = 0; iL < maxLayer; ++iL) {
339 TDirectory* dir_layer = dir_sector->mkdir(Form("Layer_%d", iL + 1), "", true);
340 for (int iP = 0; iP < 2; ++iP) {
341 m_channelHistDir_EKLM[iF][iS][iL][iP] = dir_layer->mkdir(Form("Plane_%d", iP + 1), "", true);
342 }
343 }
344 }
345 }
346
347 m_outFile->cd(); // Return to root directory
348 B2INFO("Created directory structure for per-channel histograms.");
349 }
350
351 int nBin = 80;
352 int nBin_scint = 80;
353
354 TString iFstring[2] = {"Backward", "Forward"};
355 TString iPstring[2] = {"ZReadout", "PhiReadout"};
356 TString hn, ht;
357
358 h_diff = new TH1F("h_diff", "Position difference between bklmHit2d and extHit;position difference", 100, 0, 10);
359 h_calibrated = new TH1I("h_calibrated_summary", "h_calibrated_summary;calibrated or not", 3, 0, 3);
360 hc_calibrated = new TH1I("hc_calibrated_summary", "hc_calibrated_summary;calibrated or not", 3, 0, 3);
361
362 gre_time_channel_scint = new TGraphErrors();
363 gre_time_channel_rpc = new TGraphErrors();
364 gre_time_channel_scint_end = new TGraphErrors();
365
366 gr_timeShift_channel_scint = new TGraph();
367 gr_timeShift_channel_rpc = new TGraph();
368 gr_timeShift_channel_scint_end = new TGraph();
369
370 gre_ctime_channel_scint = new TGraphErrors();
371 gre_ctime_channel_rpc = new TGraphErrors();
372 gre_ctime_channel_scint_end = new TGraphErrors();
373
374 gr_timeRes_channel_scint = new TGraph();
375 gr_timeRes_channel_rpc = new TGraph();
376 gr_timeRes_channel_scint_end = new TGraph();
377
378 double maximalPhiStripLengthBKLM =
379 m_BKLMGeometry->getMaximalPhiStripLength();
380 double maximalZStripLengthBKLM =
381 m_BKLMGeometry->getMaximalZStripLength();
382 double maximalStripLengthEKLM =
383 m_EKLMGeometry->getMaximalStripLength() / CLHEP::cm * Unit::cm;
384
385 m_ProfileRpcPhi = new TProfile("hprf_rpc_phi_effC",
386 "Time over propagation length for RPCs (Phi_Readout); propagation distance[cm]; T_rec-T_0-T_fly-'T_calibration'[ns]", 50, 0.0,
387 400.0);
388 m_ProfileRpcZ = new TProfile("hprf_rpc_z_effC",
389 "Time over propagation length for RPCs (Z_Readout); propagation distance[cm]; T_rec-T_0-T_fly-'T_calibration'[ns]", 50, 0.0,
390 400.0);
391 m_ProfileBKLMScintillatorPhi = new TProfile("hprf_scint_phi_effC",
392 "Time over propagation length for scintillators (Phi_Readout); propagation distance[cm]; T_rec-T_0-T_fly-'T_calibration'[ns]",
393 50, 0.0, maximalPhiStripLengthBKLM);
394 m_ProfileBKLMScintillatorZ = new TProfile("hprf_scint_z_effC",
395 "Time over propagation length for scintillators (Z_Readout); propagation distance[cm]; T_rec-T_0-T_fly-'T_calibration'[ns]",
396 50, 0.0, maximalZStripLengthBKLM);
397 m_ProfileEKLMScintillatorPlane1 = new TProfile("hprf_scint_plane1_effC_end",
398 "Time over propagation length for scintillators (plane1, Endcap); propagation distance[cm]; T_rec-T_0-T_fly-'T_calibration'[ns]",
399 50, 0.0, maximalStripLengthEKLM);
400 m_ProfileEKLMScintillatorPlane2 = new TProfile("hprf_scint_plane2_effC_end",
401 "Time over propagation length for scintillators (plane2, Endcap); propagation distance[cm]; T_rec-T_0-T_fly-'T_calibration'[ns]",
402 50, 0.0, maximalStripLengthEKLM);
403
404 m_Profile2RpcPhi = new TProfile("hprf2_rpc_phi_effC",
405 "Time over propagation length for RPCs (Phi_Readout); propagation distance[cm]; T_rec-T_0-T_fly-'T_calibration'[ns]", 50, 0.0,
406 400.0);
407 m_Profile2RpcZ = new TProfile("hprf2_rpc_z_effC",
408 "Time over propagation length for RPCs (Z_Readout); propagation distance[cm]; T_rec-T_0-T_fly-'T_calibration'[ns]", 50, 0.0,
409 400.0);
410 m_Profile2BKLMScintillatorPhi = new TProfile("hprf2_scint_phi_effC",
411 "Time over propagation length for scintillators (Phi_Readout); propagation distance[cm]; T_rec-T_0-T_fly-'T_calibration'[ns]",
412 50, 0.0, maximalPhiStripLengthBKLM);
413 m_Profile2BKLMScintillatorZ = new TProfile("hprf2_scint_z_effC",
414 "Time over propagation length for scintillators (Z_Readout); propagation distance[cm]; T_rec-T_0-T_fly-'T_calibration'[ns]",
415 50, 0.0, maximalZStripLengthBKLM);
416 m_Profile2EKLMScintillatorPlane1 = new TProfile("hprf2_scint_plane1_effC_end",
417 "Time over propagation length for scintillators (plane1, Endcap); propagation distance[cm]; T_rec-T_0-T_fly-'T_calibration'[ns]",
418 50, 0.0, maximalStripLengthEKLM);
419 m_Profile2EKLMScintillatorPlane2 = new TProfile("hprf2_scint_plane2_effC_end",
420 "Time over propagation length for scintillators (plane2, Endcap); propagation distance[cm]; T_rec-T_0-T_fly-'T_calibration'[ns]",
421 50, 0.0, maximalStripLengthEKLM);
422
423 h_time_rpc_tc = new TH1F("h_time_rpc_tc", "time distribution for RPC", nBin, m_LowerTimeBoundaryRPC, m_UpperTimeBoundaryRPC);
424 h_time_scint_tc = new TH1F("h_time_scint_tc", "time distribution for Scintillator", nBin_scint,
426 h_time_scint_tc_end = new TH1F("h_time_scint_tc_end", "time distribution for Scintillator (Endcap)", nBin_scint,
429
431 h_time_rpc = new TH1F("h_time_rpc", "time distribution for RPC; T_rec-T_0-T_fly-T_propagation[ns]", nBin, m_LowerTimeBoundaryRPC,
433 h_time_scint = new TH1F("h_time_scint", "time distribution for Scintillator; T_rec-T_0-T_fly-T_propagation[ns]", nBin_scint,
435 h_time_scint_end = new TH1F("h_time_scint_end", "time distribution for Scintillator (Endcap); T_rec-T_0-T_fly-T_propagation[ns]",
437
438 hc_time_rpc = new TH1F("hc_time_rpc", "Calibrated time distribution for RPC; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
440 hc_time_scint = new TH1F("hc_time_scint",
441 "Calibrated time distribution for Scintillator; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]", nBin_scint,
444 hc_time_scint_end = new TH1F("hc_time_scint_end",
445 "Calibrated time distribution for Scintillator (Endcap); T_rec-T_0-T_fly-T_propagation-T_calibration[ns]", nBin_scint,
447
448 int nBin_t0 = 100;
449 h_eventT0_rpc = new TH1F("h_eventT0_rpc",
450 "RPC: Event T0; T_{0}[ns]", nBin_t0, -100.0, 100.0);
451 h_eventT0_scint = new TH1F("h_eventT0_scint",
452 "BKLM scintillator: Event T0; T_{0}[ns]", nBin_t0, -100.0, 100.0);
453 h_eventT0_scint_end = new TH1F("h_eventT0_scint_end",
454 "EKLM scintillator: Event T0; T_{0}[ns]", nBin_t0, -100.0, 100.0);
455
456 // Corrected EventT0 distributions between 2 muon tracks in an event.
457 hc_eventT0_rpc = new TH1F("hc_eventT0_rpc",
458 "RPC: corrected Event T0; T_{0}^{+} - T_{0}^{-} [ns]", nBin_t0, -40.0, 40.0);
459 hc_eventT0_scint = new TH1F("hc_eventT0_scint",
460 "BKLM scintillator: corrected Event T0; T_{0}^{+} - T_{0}^{-} [ns]", nBin_t0, -40.0, 40.0);
461 hc_eventT0_scint_end = new TH1F("hc_eventT0_scint_end",
462 "EKLM scintillator: corrected Event T0; T_{0}^{+} - T_{0}^{-} [ns]", nBin_t0, -20.0, 20.0);
463
464 // ==== NEW DIAGNOSTIC PLOTS ====
465
466 // Hit multiplicity distributions
467 h_nHits_plus_rpc = new TH1F("h_nHits_plus_rpc",
468 "RPC: #mu^{+} hit multiplicity;N_{hits};Events", 100, 0, 100);
469 h_nHits_minus_rpc = new TH1F("h_nHits_minus_rpc",
470 "RPC: #mu^{-} hit multiplicity;N_{hits};Events", 100, 0, 100);
471 h_nHits_plus_scint = new TH1F("h_nHits_plus_scint",
472 "BKLM Scint: #mu^{+} hit multiplicity;N_{hits};Events", 30, 0, 30);
473 h_nHits_minus_scint = new TH1F("h_nHits_minus_scint",
474 "BKLM Scint: #mu^{-} hit multiplicity;N_{hits};Events", 30, 0, 30);
475 h_nHits_plus_scint_end = new TH1F("h_nHits_plus_scint_end",
476 "EKLM Scint: #mu^{+} hit multiplicity;N_{hits};Events", 30, 0, 30);
477 h_nHits_minus_scint_end = new TH1F("h_nHits_minus_scint_end",
478 "EKLM Scint: #mu^{-} hit multiplicity;N_{hits};Events", 30, 0, 30);
479
480 // ΔT0 vs variance weight v = 1/N+ + 1/N-
481 h2_deltaT0_vs_v_rpc = new TH2F("h2_deltaT0_vs_v_rpc",
482 "RPC: #DeltaT_{0} vs variance weight;v = 1/N^{+} + 1/N^{-};#DeltaT_{0} [ns]",
483 50, 0, 2.0, 100, -40, 40);
484 h2_deltaT0_vs_v_scint = new TH2F("h2_deltaT0_vs_v_scint",
485 "BKLM Scint: #DeltaT_{0} vs variance weight;v = 1/N^{+} + 1/N^{-};#DeltaT_{0} [ns]",
486 50, 0, 1.0, 100, -40, 40);
487 h2_deltaT0_vs_v_scint_end = new TH2F("h2_deltaT0_vs_v_scint_end",
488 "EKLM Scint: #DeltaT_{0} vs variance weight;v = 1/N^{+} + 1/N^{-};#DeltaT_{0} [ns]",
489 50, 0, 1.0, 100, -20, 20);
490
491 // Profile: RMS(ΔT0) vs v (should scale as √v if model is correct)
492 prof_deltaT0_rms_vs_v_rpc = new TProfile("prof_deltaT0_rms_vs_v_rpc",
493 "RPC: RMS(#DeltaT_{0}) vs v;v = 1/N^{+} + 1/N^{-};RMS(#DeltaT_{0}) [ns]",
494 20, 0, 2.0, "s"); // "s" option for RMS
495 prof_deltaT0_rms_vs_v_scint = new TProfile("prof_deltaT0_rms_vs_v_scint",
496 "BKLM Scint: RMS(#DeltaT_{0}) vs v;v = 1/N^{+} + 1/N^{-};RMS(#DeltaT_{0}) [ns]",
497 20, 0, 1.0, "s");
498 prof_deltaT0_rms_vs_v_scint_end = new TProfile("prof_deltaT0_rms_vs_v_scint_end",
499 "EKLM Scint: RMS(#DeltaT_{0}) vs v;v = 1/N^{+} + 1/N^{-};RMS(#DeltaT_{0}) [ns]",
500 20, 0, 1.0, "s");
501
502 // ΔT0 vs total hits
503 h2_deltaT0_vs_nhits_rpc = new TH2F("h2_deltaT0_vs_nhits_rpc",
504 "RPC: #DeltaT_{0} vs total hits;N^{+} + N^{-};#DeltaT_{0} [ns]",
505 50, 0, 200, 100, -40, 40);
506 h2_deltaT0_vs_nhits_scint = new TH2F("h2_deltaT0_vs_nhits_scint",
507 "BKLM Scint: #DeltaT_{0} vs total hits;N^{+} + N^{-};#DeltaT_{0} [ns]",
508 40, 0, 40, 100, -40, 40);
509 h2_deltaT0_vs_nhits_scint_end = new TH2F("h2_deltaT0_vs_nhits_scint_end",
510 "EKLM Scint: #DeltaT_{0} vs total hits;N^{+} + N^{-};#DeltaT_{0} [ns]",
511 40, 0, 40, 100, -20, 20);
512
513 // ΔT0 separated by hit multiplicity bins
514 hc_eventT0_rpc_lowN = new TH1F("hc_eventT0_rpc_lowN",
515 "RPC: #DeltaT_{0} (N^{+}+N^{-} < 10);#DeltaT_{0} [ns]", nBin_t0, -40.0, 40.0);
516 hc_eventT0_rpc_midN = new TH1F("hc_eventT0_rpc_midN",
517 "RPC: #DeltaT_{0} (10 #leq N^{+}+N^{-} < 30);#DeltaT_{0} [ns]", nBin_t0, -40.0, 40.0);
518 hc_eventT0_rpc_highN = new TH1F("hc_eventT0_rpc_highN",
519 "RPC: #DeltaT_{0} (N^{+}+N^{-} #geq 30);#DeltaT_{0} [ns]", nBin_t0, -40.0, 40.0);
520
521 hc_eventT0_scint_lowN = new TH1F("hc_eventT0_scint_lowN",
522 "BKLM Scint: #DeltaT_{0} (N^{+}+N^{-} < 5);#DeltaT_{0} [ns]", nBin_t0, -40.0, 40.0);
523 hc_eventT0_scint_midN = new TH1F("hc_eventT0_scint_midN",
524 "BKLM Scint: #DeltaT_{0} (5 #leq N^{+}+N^{-} < 15);#DeltaT_{0} [ns]", nBin_t0, -40.0, 40.0);
525 hc_eventT0_scint_highN = new TH1F("hc_eventT0_scint_highN",
526 "BKLM Scint: #DeltaT_{0} (N^{+}+N^{-} #geq 15);#DeltaT_{0} [ns]", nBin_t0, -40.0, 40.0);
527
528 hc_eventT0_scint_end_lowN = new TH1F("hc_eventT0_scint_end_lowN",
529 "EKLM Scint: #DeltaT_{0} (N^{+}+N^{-} < 5);#DeltaT_{0} [ns]", nBin_t0, -20.0, 20.0);
530 hc_eventT0_scint_end_midN = new TH1F("hc_eventT0_scint_end_midN",
531 "EKLM Scint: #DeltaT_{0} (5 #leq N^{+}+N^{-} < 15);#DeltaT_{0} [ns]", nBin_t0, -20.0, 20.0);
532 hc_eventT0_scint_end_highN = new TH1F("hc_eventT0_scint_end_highN",
533 "EKLM Scint: #DeltaT_{0} (N^{+}+N^{-} #geq 15);#DeltaT_{0} [ns]", nBin_t0, -20.0, 20.0);
534
535 if (!m_saveAllPlots) {
536 B2INFO("Skipping debug histogram allocation (m_saveAllPlots = false)");
537 return; // Skip all debugging histogram allocation
538 }
539
540 for (int iF = 0; iF < 2; ++iF) {
541 hn = Form("h_timeF%d_rpc", iF);
542 ht = Form("Time distribution for RPC of %s; T_rec-T_0-T_fly-T_propagation[ns]", iFstring[iF].Data());
543 h_timeF_rpc[iF] = new TH1F(hn.Data(), ht.Data(), nBin, m_LowerTimeBoundaryRPC, m_UpperTimeBoundaryRPC);
544 hn = Form("h_timeF%d_scint", iF);
545 ht = Form("Time distribution for Scintillator of %s; T_rec-T_0-T_fly-T_propagation[ns]", iFstring[iF].Data());
546 h_timeF_scint[iF] = new TH1F(hn.Data(), ht.Data(), nBin_scint, m_LowerTimeBoundaryScintillatorsBKLM,
548 hn = Form("h_timeF%d_scint_end", iF);
549 ht = Form("Time distribution for Scintillator of %s (Endcap); T_rec-T_0-T_fly-T_propagation[ns]", iFstring[iF].Data());
550 h_timeF_scint_end[iF] = new TH1F(hn.Data(), ht.Data(), nBin_scint, m_LowerTimeBoundaryScintillatorsEKLM,
552
553 hn = Form("h2_timeF%d_rpc", iF);
554 ht = Form("Time distribution for RPC of %s; Sector Index; T_rec-T_0-T_fly-T_propagation[ns]", iFstring[iF].Data());
555 h2_timeF_rpc[iF] = new TH2F(hn.Data(), ht.Data(), 8, 0, 8, nBin, m_LowerTimeBoundaryRPC, m_UpperTimeBoundaryRPC);
556 hn = Form("h2_timeF%d_scint", iF);
557 ht = Form("Time distribution for Scintillator of %s; Sector Index; T_rec-T_0-T_fly-T_propagation[ns]", iFstring[iF].Data());
558 h2_timeF_scint[iF] = new TH2F(hn.Data(), ht.Data(), 8, 0, 8, nBin_scint, m_LowerTimeBoundaryScintillatorsBKLM,
560 hn = Form("h2_timeF%d_scint_end", iF);
561 ht = Form("Time distribution for Scintillator of %s (Endcap); Sector Index; T_rec-T_0-T_fly-T_propagation[ns]",
562 iFstring[iF].Data());
563 h2_timeF_scint_end[iF] = new TH2F(hn.Data(), ht.Data(), 4, 0, 4, nBin_scint, m_LowerTimeBoundaryScintillatorsEKLM,
565
566 hn = Form("hc_timeF%d_rpc", iF);
567 ht = Form("Calibrated time distribution for RPC of %s; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]", iFstring[iF].Data());
568 hc_timeF_rpc[iF] = new TH1F(hn.Data(), ht.Data(), nBin, m_LowerTimeBoundaryCalibratedRPC, m_UpperTimeBoundaryCalibratedRPC);
569 hn = Form("hc_timeF%d_scint", iF);
570 ht = Form("Calibrated time distribution for Scintillator of %s; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
571 iFstring[iF].Data());
572 hc_timeF_scint[iF] = new TH1F(hn.Data(), ht.Data(), nBin_scint, m_LowerTimeBoundaryCalibratedScintillatorsBKLM,
574 hn = Form("hc_timeF%d_scint_end", iF);
575 ht = Form("Calibrated time distribution for Scintillator of %s (Endcap); T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
576 iFstring[iF].Data());
577 hc_timeF_scint_end[iF] = new TH1F(hn.Data(), ht.Data(), nBin_scint, m_LowerTimeBoundaryCalibratedScintillatorsEKLM,
579
580 hn = Form("h2c_timeF%d_rpc", iF);
581 ht = Form("Calibrated time distribution for RPC of %s; Sector Index; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
582 iFstring[iF].Data());
583 h2c_timeF_rpc[iF] = new TH2F(hn.Data(), ht.Data(), 8, 0, 8, nBin, m_LowerTimeBoundaryCalibratedRPC,
585 hn = Form("h2c_timeF%d_scint", iF);
586 ht = Form("Calibrated time distribution for Scintillator of %s; Sector Index; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
587 iFstring[iF].Data());
588 h2c_timeF_scint[iF] = new TH2F(hn.Data(), ht.Data(), 8, 0, 8, nBin_scint, m_LowerTimeBoundaryCalibratedScintillatorsBKLM,
590 hn = Form("h2c_timeF%d_scint_end", iF);
591 ht = Form("Calibrated time distribution for Scintillator of %s (Endcap) ; Sector Index; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
592 iFstring[iF].Data());
593 h2c_timeF_scint_end[iF] = new TH2F(hn.Data(), ht.Data(), 4, 0, 4, nBin_scint, m_LowerTimeBoundaryCalibratedScintillatorsEKLM,
595
596 for (int iS = 0; iS < 8; ++iS) {
597 // Barrel parts
598 hn = Form("h_timeF%d_S%d_scint", iF, iS);
599 ht = Form("Time distribution for Scintillator of Sector%d, %s; T_rec-T_0-T_fly-T_propagation[ns]", iS, iFstring[iF].Data());
600 h_timeFS_scint[iF][iS] = new TH1F(hn.Data(), ht.Data(), nBin_scint, m_LowerTimeBoundaryScintillatorsBKLM,
602 hn = Form("h_timeF%d_S%d_rpc", iF, iS);
603 ht = Form("Time distribution for RPC of Sector%d, %s; T_rec-T_0-T_fly-T_propagation[ns]", iS, iFstring[iF].Data());
604 h_timeFS_rpc[iF][iS] = new TH1F(hn.Data(), ht.Data(), nBin, m_LowerTimeBoundaryRPC, m_UpperTimeBoundaryRPC);
605 hn = Form("h2_timeF%d_S%d", iF, iS);
606 ht = Form("Time distribution of Sector%d, %s; Layer Index; T_rec-T_0-T_fly-T_propagation[ns]", iS, iFstring[iF].Data());
607 h2_timeFS[iF][iS] = new TH2F(hn.Data(), ht.Data(), 15, 0, 15, nBin_scint, m_LowerTimeBoundaryRPC,
609
610 hn = Form("hc_timeF%d_S%d_scint", iF, iS);
611 ht = Form("Calibrated time distribution for Scintillator of Sector%d, %s; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]", iS,
612 iFstring[iF].Data());
613 hc_timeFS_scint[iF][iS] = new TH1F(hn.Data(), ht.Data(), nBin_scint, m_LowerTimeBoundaryCalibratedScintillatorsBKLM,
615 hn = Form("hc_timeF%d_S%d_rpc", iF, iS);
616 ht = Form("Calibrated time distribution for RPC of Sector%d, %s; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]", iS,
617 iFstring[iF].Data());
618 hc_timeFS_rpc[iF][iS] = new TH1F(hn.Data(), ht.Data(), nBin_scint, m_LowerTimeBoundaryCalibratedRPC,
620 hn = Form("h2c_timeF%d_S%d", iF, iS);
621 ht = Form("Calibrated time distribution of Sector%d, %s; Layer Index; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]", iS,
622 iFstring[iF].Data());
623 h2c_timeFS[iF][iS] = new TH2F(hn.Data(), ht.Data(), 15, 0, 15, nBin_scint, m_LowerTimeBoundaryCalibratedRPC,
625
626 // Inner 2 layers --> Scintillators
627 for (int iL = 0; iL < 2; ++iL) {
628 hn = Form("h_timeF%d_S%d_L%d", iF, iS, iL);
629 ht = Form("Time distribution for Scintillator of Layer%d, Sector%d, %s; T_rec-T_0-T_fly-T_propagation[ns]", iL, iS,
630 iFstring[iF].Data());
631 h_timeFSL[iF][iS][iL] = new TH1F(hn.Data(), ht.Data(), nBin_scint, m_LowerTimeBoundaryScintillatorsBKLM,
633 hn = Form("hc_timeF%d_S%d_L%d", iF, iS, iL);
634 ht = Form("Calibrated time distribution for Scintillator of Layer%d, Sector%d, %s; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
635 iL, iS, iFstring[iF].Data());
636 hc_timeFSL[iF][iS][iL] = new TH1F(hn.Data(), ht.Data(), nBin_scint, m_LowerTimeBoundaryCalibratedScintillatorsBKLM,
638
639 for (int iP = 0; iP < 2; ++iP) {
640 hn = Form("h_timeF%d_S%d_L%d_P%d", iF, iS, iL, iP);
641 ht = Form("Time distribution for Scintillator of %s, Layer%d, Sector%d, %s; T_rec-T_0-T_fly-T_propagation[ns]",
642 iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
643 h_timeFSLP[iF][iS][iL][iP] = new TH1F(hn.Data(), ht.Data(), nBin_scint, m_LowerTimeBoundaryScintillatorsBKLM,
645 hn = Form("h2_timeF%d_S%d_L%d_P%d", iF, iS, iL, iP);
646 ht = Form("Time distribution for Scintillator of %s, Layer%d, Sector%d, %s; Channel Index; T_rec-T_0-T_fly-T_propagation[ns]",
647 iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
648 h2_timeFSLP[iF][iS][iL][iP] = new TH2F(hn.Data(), ht.Data(), 54, 0, 54, nBin_scint, m_LowerTimeBoundaryScintillatorsBKLM,
650
651 hn = Form("hc_timeF%d_S%d_L%d_P%d", iF, iS, iL, iP);
652 ht = Form("Calibrated time distribution for Scintillator of %s, Layer%d, Sector%d, %s; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
653 iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
654 hc_timeFSLP[iF][iS][iL][iP] = new TH1F(hn.Data(), ht.Data(), nBin_scint, m_LowerTimeBoundaryCalibratedScintillatorsBKLM,
656 hn = Form("h2c_timeF%d_S%d_L%d_P%d", iF, iS, iL, iP);
657 ht = Form("Calibrated time distribution for Scintillator of %s, Layer%d, Sector%d, %s; Channel Index; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
658 iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
659 h2c_timeFSLP[iF][iS][iL][iP] = new TH2F(hn.Data(), ht.Data(), 54, 0, 54, nBin_scint, m_LowerTimeBoundaryCalibratedScintillatorsBKLM,
661 }
662 }
663
664 for (int iL = 2; iL < 15; ++iL) {
665 hn = Form("h_timeF%d_S%d_L%d", iF, iS, iL);
666 ht = Form("time distribution for RPC of Layer%d, Sector%d, %s; T_rec-T_0-T_fly-T_propagation[ns]", iL, iS, iFstring[iF].Data());
667 h_timeFSL[iF][iS][iL] = new TH1F(hn.Data(), ht.Data(), nBin, m_LowerTimeBoundaryRPC, m_UpperTimeBoundaryRPC);
668
669 hn = Form("hc_timeF%d_S%d_L%d", iF, iS, iL);
670 ht = Form("Calibrated time distribution for RPC of Layer%d, Sector%d, %s; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]", iL, iS,
671 iFstring[iF].Data());
672 hc_timeFSL[iF][iS][iL] = new TH1F(hn.Data(), ht.Data(), nBin, m_LowerTimeBoundaryCalibratedRPC, m_UpperTimeBoundaryCalibratedRPC);
673
674 for (int iP = 0; iP < 2; ++iP) {
675 hn = Form("h_timeF%d_S%d_L%d_P%d", iF, iS, iL, iP);
676 ht = Form("time distribution for RPC of %s, Layer%d, Sector%d, %s; T_rec-T_0-T_fly-T_propagation[ns]", iPstring[iP].Data(), iL, iS,
677 iFstring[iF].Data());
678 h_timeFSLP[iF][iS][iL][iP] = new TH1F(hn.Data(), ht.Data(), nBin, m_LowerTimeBoundaryRPC, m_UpperTimeBoundaryRPC);
679
680 hn = Form("h2_timeF%d_S%d_L%d_P%d", iF, iS, iL, iP);
681 ht = Form("time distribution for RPC of %s, Layer%d, Sector%d, %s; Channel Index; T_rec-T_0-T_fly-T_propagation[ns]",
682 iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
683 h2_timeFSLP[iF][iS][iL][iP] = new TH2F(hn.Data(), ht.Data(), 48, 0, 48, nBin, m_LowerTimeBoundaryRPC, m_UpperTimeBoundaryRPC);
684
685 hn = Form("hc_timeF%d_S%d_L%d_P%d", iF, iS, iL, iP);
686 ht = Form("Calibrated time distribution for RPC of %s, Layer%d, Sector%d, %s; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
687 iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
688 hc_timeFSLP[iF][iS][iL][iP] = new TH1F(hn.Data(), ht.Data(), nBin, m_LowerTimeBoundaryCalibratedRPC,
690
691 hn = Form("h2c_timeF%d_S%d_L%d_P%d", iF, iS, iL, iP);
692 ht = Form("Calibrated time distribution for RPC of %s, Layer%d, Sector%d, %s; Channel Index; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
693 iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
694 h2c_timeFSLP[iF][iS][iL][iP] = new TH2F(hn.Data(), ht.Data(), 48, 0, 48, nBin, m_LowerTimeBoundaryCalibratedRPC,
696 }
697 }
698 }
699 // Endcap part
700 int maxLay = 12 + 2 * iF;
701 for (int iS = 0; iS < 4; ++iS) {
702 hn = Form("h_timeF%d_S%d_scint_end", iF, iS);
703 ht = Form("Time distribution for Scintillator of Sector%d, %s (Endcap); T_rec-T_0-T_fly-T_propagation[ns]", iS,
704 iFstring[iF].Data());
705 h_timeFS_scint_end[iF][iS] = new TH1F(hn.Data(), ht.Data(), nBin_scint, m_LowerTimeBoundaryScintillatorsEKLM,
707 hn = Form("h2_timeF%d_S%d_end", iF, iS);
708 ht = Form("Time distribution of Sector%d, %s (Endcap); Layer Index; T_rec-T_0-T_fly-T_propagation[ns]", iS, iFstring[iF].Data());
709 h2_timeFS_end[iF][iS] = new TH2F(hn.Data(), ht.Data(), maxLay, 0, maxLay, nBin_scint, m_LowerTimeBoundaryScintillatorsEKLM,
711 hn = Form("hc_timeF%d_S%d_scint_end", iF, iS);
712 ht = Form("Calibrated time distribution for Scintillator of Sector%d (Endcap), %s; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
713 iS, iFstring[iF].Data());
714 hc_timeFS_scint_end[iF][iS] = new TH1F(hn.Data(), ht.Data(), nBin_scint, m_LowerTimeBoundaryCalibratedScintillatorsEKLM,
716 hn = Form("h2c_timeF%d_S%d_end", iF, iS);
717 ht = Form("Calibrated time distribution of Sector%d, %s (Endcap); Layer Index; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
718 iS, iFstring[iF].Data());
719 h2c_timeFS_end[iF][iS] = new TH2F(hn.Data(), ht.Data(), maxLay, 0, maxLay, nBin_scint,
722
723 for (int iL = 0; iL < maxLay; ++iL) {
724 hn = Form("h_timeF%d_S%d_L%d_end", iF, iS, iL);
725 ht = Form("Time distribution for Scintillator of Layer%d, Sector%d, %s (Endcap); T_rec-T_0-T_fly-T_propagation[ns]", iL, iS,
726 iFstring[iF].Data());
727 h_timeFSL_end[iF][iS][iL] = new TH1F(hn.Data(), ht.Data(), nBin_scint, m_LowerTimeBoundaryScintillatorsEKLM,
729 hn = Form("hc_timeF%d_S%d_L%d_end", iF, iS, iL);
730 ht = Form("Calibrated time distribution for Scintillator of Layer%d, Sector%d, %s (Endcap); T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
731 iL, iS, iFstring[iF].Data());
732 hc_timeFSL_end[iF][iS][iL] = new TH1F(hn.Data(), ht.Data(), nBin_scint, m_LowerTimeBoundaryCalibratedScintillatorsEKLM,
734
735 for (int iP = 0; iP < 2; ++iP) {
736 hn = Form("h_timeF%d_S%d_L%d_P%d_end", iF, iS, iL, iP);
737 ht = Form("Time distribution for Scintillator of %s, Layer%d, Sector%d, %s (Endcap); T_rec-T_0-T_fly-T_propagation[ns]",
738 iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
739 h_timeFSLP_end[iF][iS][iL][iP] = new TH1F(hn.Data(), ht.Data(), nBin_scint, m_LowerTimeBoundaryScintillatorsEKLM,
741
742 hn = Form("h2_timeF%d_S%d_L%d_P%d_end", iF, iS, iL, iP);
743 ht = Form("Time distribution for Scintillator of %s, Layer%d, Sector%d, %s (Endcap); Channel Index; T_rec-T_0-T_fly-T_propagation[ns]",
744 iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
745 h2_timeFSLP_end[iF][iS][iL][iP] = new TH2F(hn.Data(), ht.Data(), 75, 0, 75, nBin_scint, m_LowerTimeBoundaryScintillatorsEKLM,
747
748 hn = Form("hc_timeF%d_S%d_L%d_P%d_end", iF, iS, iL, iP);
749 ht = Form("Calibrated time distribution for Scintillator of %s, Layer%d, Sector%d, %s (Endcap); T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
750 iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
751 hc_timeFSLP_end[iF][iS][iL][iP] = new TH1F(hn.Data(), ht.Data(), nBin_scint, m_LowerTimeBoundaryCalibratedScintillatorsEKLM,
753
754 hn = Form("h2c_timeF%d_S%d_L%d_P%d_end", iF, iS, iL, iP);
755 ht = Form("Calibrated time distribution for Scintillator of %s, Layer%d, Sector%d, %s (Endcap); Channel Index; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
756 iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
757 h2c_timeFSLP_end[iF][iS][iL][iP] = new TH2F(hn.Data(), ht.Data(), 75, 0, 75, nBin_scint,
760 }
761 }
762 }
763 }
764
765 // NOTE: Directory structure for per-channel histograms is created in createHistograms()
766 // because m_outFile is not yet created when setupDatabase() is called.
767}
const EKLM::GeometryData * m_EKLMGeometry
EKLM geometry data.
const bklm::GeometryPar * m_BKLMGeometry
BKLM geometry data.
static const double cm
Standard units with the value = 1.
Definition Unit.h:47

◆ 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();}

◆ esti_timeRes()

double esti_timeRes ( const KLMChannelIndex & klmChannel)

Estimate value of calibration constant for calibrated channels.

Parameters
[in]klmChannelKLM channel index.

Definition at line 2713 of file KLMTimeAlgorithm.cc.

2714{
2715 double tR = 0.0;
2716 int iSub = klmChannel.getSubdetector();
2717 int iF = klmChannel.getSection();
2718 int iS = klmChannel.getSector();
2719 int iL = klmChannel.getLayer();
2720 int iP = klmChannel.getPlane();
2721 int iC = klmChannel.getStrip();
2723 if (iSub == KLMElementNumbers::c_BKLM)
2724 totNStrips = BKLMElementNumbers::getNStrips(iF, iS, iL, iP);
2725 if (iC == 1) {
2726 KLMChannelIndex kCIndex_upper(iSub, iF, iS, iL, iP, iC + 1);
2727 tR = tR_upperStrip(kCIndex_upper).second;
2728 } else if (iC == totNStrips) {
2729 KLMChannelIndex kCIndex_lower(iSub, iF, iS, iL, iP, iC - 1);
2730 tR = tR_lowerStrip(kCIndex_lower).second;
2731 } else {
2732 KLMChannelIndex kCIndex_upper(iSub, iF, iS, iL, iP, iC + 1);
2733 KLMChannelIndex kCIndex_lower(iSub, iF, iS, iL, iP, iC - 1);
2734 std::pair<int, double> tR_upper = tR_upperStrip(kCIndex_upper);
2735 std::pair<int, double> tR_lower = tR_lowerStrip(kCIndex_lower);
2736 unsigned int tr_upper = tR_upper.first - iC;
2737 unsigned int tr_lower = iC - tR_lower.first;
2738 unsigned int tr = tR_upper.first - tR_lower.first;
2739 tR = (double(tr_upper) * tR_lower.second + double(tr_lower) * tR_upper.second) / double(tr);
2740 }
2741 return tR;
2742}
static int getNStrips(int section, int sector, int layer, int plane)
Get number of strips.
static constexpr int getMaximalStripNumber()
Get maximal strip number.
int getSubdetector() const
Get subdetector.
int getLayer() const
Get layer.
int getSection() const
Get section.
int getPlane() const
Get plane.
int getStrip() const
Get strip.
int getSector() const
Get sector.
std::pair< int, double > tR_upperStrip(const KLMChannelIndex &klmChannel)
Tracing available channels with increasing strip number.
std::pair< int, double > tR_lowerStrip(const KLMChannelIndex &klmChannel)
Tracing available channels with decreasing strip number.

◆ esti_timeShift()

double esti_timeShift ( const KLMChannelIndex & klmChannel)

Estimate value of calibration constant for uncalibrated channels.

Parameters
[in]klmChannelKLM channel index.

Definition at line 2633 of file KLMTimeAlgorithm.cc.

2634{
2635 double tS = 0.0;
2636 int iSub = klmChannel.getSubdetector();
2637 int iF = klmChannel.getSection();
2638 int iS = klmChannel.getSector();
2639 int iL = klmChannel.getLayer();
2640 int iP = klmChannel.getPlane();
2641 int iC = klmChannel.getStrip();
2643 if (iSub == KLMElementNumbers::c_BKLM)
2644 totNStrips = BKLMElementNumbers::getNStrips(iF, iS, iL, iP);
2645 if (iC == 1) {
2646 KLMChannelIndex kCIndex_upper(iSub, iF, iS, iL, iP, iC + 1);
2647 tS = tS_upperStrip(kCIndex_upper).second;
2648 } else if (iC == totNStrips) {
2649 KLMChannelIndex kCIndex_lower(iSub, iF, iS, iL, iP, iC - 1);
2650 tS = tS_lowerStrip(kCIndex_lower).second;
2651 } else {
2652 KLMChannelIndex kCIndex_upper(iSub, iF, iS, iL, iP, iC + 1);
2653 KLMChannelIndex kCIndex_lower(iSub, iF, iS, iL, iP, iC - 1);
2654 std::pair<int, double> tS_upper = tS_upperStrip(kCIndex_upper);
2655 std::pair<int, double> tS_lower = tS_lowerStrip(kCIndex_lower);
2656 unsigned int td_upper = tS_upper.first - iC;
2657 unsigned int td_lower = iC - tS_lower.first;
2658 unsigned int td = tS_upper.first - tS_lower.first;
2659 tS = (double(td_upper) * tS_lower.second + double(td_lower) * tS_upper.second) / double(td);
2660 }
2661 return tS;
2662}
std::pair< int, double > tS_upperStrip(const KLMChannelIndex &klmChannel)
Tracing available channels with increasing strip number.
std::pair< int, double > tS_lowerStrip(const KLMChannelIndex &klmChannel)
Tracing available channels with decreasing strip number.

◆ 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...
@ 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

◆ fillTimeDistanceProfiles()

void fillTimeDistanceProfiles ( TProfile * profileRpcPhi,
TProfile * profileRpcZ,
TProfile * profileBKLMScintillatorPhi,
TProfile * profileBKLMScintillatorZ,
TProfile * profileEKLMScintillatorPlane1,
TProfile * profileEKLMScintillatorPlane2,
bool fill2dHistograms )
private

Fill profiles of time versus distance.

Parameters
[out]profileRpcPhiBKLM RPC phi plane.
[out]profileRpcZBKLM RPC z plane.
[out]profileBKLMScintillatorPhiBKLM scintillator phi plane.
[out]profileBKLMScintillatorZBKLM scintillator z plane.
[out]profileEKLMScintillatorPlane1EKLM scintillator plane1.
[out]profileEKLMScintillatorPlane2EKLM scintillator plane2.
[in]fill2dHistogramsWhether to fill 2d histograms.

Definition at line 769 of file KLMTimeAlgorithm.cc.

774{
775 B2INFO("Filling time-distance profiles" << (fill2dHistograms ? " with 2D histograms" : "") << " (batched processing)...");
776
777 TString iFstring[2] = {"Backward", "Forward"};
778 TString iPstring[2] = {"ZReadout", "PhiReadout"};
779
780 // Define the 6 batches (same as in calibrate())
781 auto isRPCBackward = [](const KLMChannelIndex & ch) {
782 return ch.getSubdetector() == KLMElementNumbers::c_BKLM &&
783 ch.getLayer() >= BKLMElementNumbers::c_FirstRPCLayer &&
784 ch.getSection() == BKLMElementNumbers::c_BackwardSection;
785 };
786
787 auto isRPCForward = [](const KLMChannelIndex & ch) {
788 return ch.getSubdetector() == KLMElementNumbers::c_BKLM &&
789 ch.getLayer() >= BKLMElementNumbers::c_FirstRPCLayer &&
790 ch.getSection() == BKLMElementNumbers::c_ForwardSection;
791 };
792
793 auto isBKLMScintillatorBackward = [](const KLMChannelIndex & ch) {
794 return ch.getSubdetector() == KLMElementNumbers::c_BKLM &&
795 ch.getLayer() < BKLMElementNumbers::c_FirstRPCLayer &&
796 ch.getSection() == BKLMElementNumbers::c_BackwardSection;
797 };
798
799 auto isBKLMScintillatorForward = [](const KLMChannelIndex & ch) {
800 return ch.getSubdetector() == KLMElementNumbers::c_BKLM &&
801 ch.getLayer() < BKLMElementNumbers::c_FirstRPCLayer &&
802 ch.getSection() == BKLMElementNumbers::c_ForwardSection;
803 };
804
805 auto isEKLMScintillatorBackward = [](const KLMChannelIndex & ch) {
806 return ch.getSubdetector() == KLMElementNumbers::c_EKLM &&
807 ch.getSection() == EKLMElementNumbers::c_BackwardSection;
808 };
809
810 auto isEKLMScintillatorForward = [](const KLMChannelIndex & ch) {
811 return ch.getSubdetector() == KLMElementNumbers::c_EKLM &&
812 ch.getSection() == EKLMElementNumbers::c_ForwardSection;
813 };
814
815 std::vector<std::pair<std::string, std::function<bool(const KLMChannelIndex&)>>> batches = {
816 {"RPC Backward", isRPCBackward},
817 {"RPC Forward", isRPCForward},
818 {"BKLM Scintillator Backward", isBKLMScintillatorBackward},
819 {"BKLM Scintillator Forward", isBKLMScintillatorForward},
820 {"EKLM Scintillator Backward", isEKLMScintillatorBackward},
821 {"EKLM Scintillator Forward", isEKLMScintillatorForward}
822 };
823
824 // Process each batch
825 for (const auto& batch : batches) {
826 B2INFO("Processing batch for profiles: " << batch.first);
827 readCalibrationDataBatch(batch.second);
828
829 // Temporary storage for per-channel 2D histograms (only if fill2dHistograms is true)
830 // Store pairs of (histogram, target directory) so we can write to correct folder
831 std::map<KLMChannelNumber, std::pair<TH2F*, TDirectory*>> tempHistBKLM;
832 std::map<KLMChannelNumber, std::pair<TH2F*, TDirectory*>> tempHistEKLM;
833
834 for (KLMChannelIndex klmChannel = m_klmChannels.begin(); klmChannel != m_klmChannels.end(); ++klmChannel) {
835 KLMChannelNumber channel = klmChannel.getKLMChannelNumber();
836
837 // Skip if not in current batch
838 if (!batch.second(klmChannel))
839 continue;
840
841 if (m_cFlag[channel] == ChannelCalibrationStatus::c_NotEnoughData)
842 continue;
843
844 if (m_evts.find(channel) == m_evts.end())
845 continue;
846
847 std::vector<struct Event> eventsChannel = m_evts[channel];
848 int iSub = klmChannel.getSubdetector();
849
850 // Create 2D histogram for this channel if needed
851 TH2F* hist2d = nullptr;
852 if (fill2dHistograms) {
853 if (iSub == KLMElementNumbers::c_BKLM) {
854 int iL = klmChannel.getLayer() - 1;
855
856 // Only create for scintillators (layers 0-1)
857 if (iL < 2) {
858 int iF = klmChannel.getSection();
859 int iS = klmChannel.getSector() - 1;
860 int iP = klmChannel.getPlane();
861 int iC = klmChannel.getStrip() - 1;
862 TString hn = Form("time_length_bklm_F%d_S%d_L%d_P%d_C%d", iF, iS, iL, iP, iC);
863 double stripLength = 200;
864 hist2d = new TH2F(hn.Data(),
865 "Time versus propagation length; "
866 "propagation distance[cm]; "
867 "T_rec-T_0-T_fly-'T_calibration'[ns]",
868 50, 0.0, stripLength,
871 tempHistBKLM[channel] = std::make_pair(hist2d, m_channelHistDir_BKLM[iF][iS][iL][iP]);
872 }
873 } else { // EKLM
874 int iF = klmChannel.getSection() - 1;
875 int iS = klmChannel.getSector() - 1;
876 int iL = klmChannel.getLayer() - 1;
877 int iP = klmChannel.getPlane() - 1;
878 int iC = klmChannel.getStrip() - 1;
879
880 TString hn = Form("time_length_eklm_F%d_S%d_L%d_P%d_C%d", iF, iS, iL, iP, iC);
881 double stripLength = m_EKLMGeometry->getStripLength(iC + 1) / CLHEP::cm * Unit::cm;
882 hist2d = new TH2F(hn.Data(),
883 "Time versus propagation length; "
884 "propagation distance[cm]; "
885 "T_rec-T_0-T_fly-'T_calibration'[ns]",
886 50, 0.0, stripLength,
889 tempHistEKLM[channel] = std::make_pair(hist2d, m_channelHistDir_EKLM[iF][iS][iL][iP]);
890 }
891 }
892
893 // Fill histograms
894 for (const Event& event : eventsChannel) {
895 double timeHit = event.time() - m_timeShift[channel];
896 if (m_useEventT0)
897 timeHit = timeHit - event.t0;
898 double distHit = event.dist;
899
900 if (timeHit <= -400e3)
901 continue;
902
903 if (iSub == KLMElementNumbers::c_BKLM) {
904 int iL = klmChannel.getLayer() - 1;
905 int iP = klmChannel.getPlane();
906
907 if (iL > 1) {
908 // RPC
909 if (iP) {
910 profileRpcPhi->Fill(distHit, timeHit);
911 } else {
912 profileRpcZ->Fill(distHit, timeHit);
913 }
914 } else {
915 // Scintillator
917 uint16_t Charge = event.getADCcount;
918 if (Charge <= 30 || Charge >= 320) {
919 continue;
920 }
921 }
922
923 if (hist2d)
924 hist2d->Fill(distHit, timeHit);
925
926 if (iP) {
927 profileBKLMScintillatorPhi->Fill(distHit, timeHit);
928 } else {
929 profileBKLMScintillatorZ->Fill(distHit, timeHit);
930 }
931 }
932 } else {
933 // EKLM
935 uint16_t Charge = event.getADCcount;
936 if (Charge <= 40 || Charge >= 350) {
937 continue;
938 }
939 }
940
941 int iP = klmChannel.getPlane() - 1;
942
943 if (hist2d)
944 hist2d->Fill(distHit, timeHit);
945
946 if (iP) {
947 profileEKLMScintillatorPlane1->Fill(distHit, timeHit);
948 } else {
949 profileEKLMScintillatorPlane2->Fill(distHit, timeHit);
950 }
951 }
952 }
953 }
954
955 // Write and delete 2D histograms for this batch
956 // Use m_saveChannelHists (not m_saveAllPlots) since these are per-channel histograms
957 // and the directories are created based on m_saveChannelHists
958 if (fill2dHistograms) {
959 for (auto& entry : tempHistBKLM) {
960 writeThenDelete_(entry.second.first, m_saveChannelHists, entry.second.second);
961 }
962 for (auto& entry : tempHistEKLM) {
963 writeThenDelete_(entry.second.first, m_saveChannelHists, entry.second.second);
964 }
965 }
966
967 m_evts.clear();
968 B2INFO("Batch processed and cleared: " << batch.first);
969 }
970
971 B2INFO("Time-distance profile filling complete.");
972}
bool m_applyChargeRestriction
Whether to apply ADC/charge restriction cuts for scintillators.

◆ 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.

◆ passesADCCut()

bool passesADCCut ( const Event & event,
int subdetector,
int layer ) const
private

Check if event passes ADC count cuts for quality selection.

Parameters
eventThe event to check
subdetectorKLM subdetector (BKLM or EKLM)
layerLayer number (to distinguish RPC from scintillator in BKLM)
Returns
true if event passes ADC cuts, false otherwise

Definition at line 1099 of file KLMTimeAlgorithm.cc.

1100{
1101 // If charge restriction is disabled, accept all hits
1103 return true;
1104 }
1105
1106 uint16_t charge = event.getADCcount;
1107
1108 if (subdetector == KLMElementNumbers::c_BKLM) {
1109 // FIXED: Use constant for RPC check (0-indexed comparison)
1110 if (layer_0indexed >= (BKLMElementNumbers::c_FirstRPCLayer - 1)) {
1111 return true; // RPC - no ADC cut
1112 } else {
1113 return (charge > 30 && charge < 320); // Scintillator
1114 }
1115 } else {
1116 return (charge > 40 && charge < 350); // EKLM
1117 }
1118}

◆ readCalibrationData()

CalibrationAlgorithm::EResult readCalibrationData ( )
private

Read calibration data.

Returns
CalibrationAlgorithm::c_OK if the amount of data is sufficient, CalibrationAlgorithm::c_NotEnoughData otherwise.

Definition at line 149 of file KLMTimeAlgorithm.cc.

150{
151 B2INFO("Read tree entries (initial data check only).");
152 std::shared_ptr<TTree> timeCalibrationData;
153 timeCalibrationData = getObjectPtr<TTree>("time_calibration_data");
154
155 int n = timeCalibrationData->GetEntries();
156 B2INFO(LogVar("Total number of digits:", n));
157
158 if (n < m_MinimalDigitNumber)
160
162}
@ c_NotEnoughData
Needs more data =2 in Python.
int m_MinimalDigitNumber
Minimal digit number (total).
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...

◆ readCalibrationDataBatch()

void readCalibrationDataBatch ( std::function< bool(const KLMChannelIndex &)> channelFilter)
private

Load calibration data for a specific batch of channels.

Parameters
[in]channelFilterFunction that returns true for channels in the batch.

Definition at line 240 of file KLMTimeAlgorithm.cc.

241{
242 B2INFO("Loading calibration data batch...");
243 Event event;
244 std::shared_ptr<TTree> timeCalibrationData;
245 timeCalibrationData = getObjectPtr<TTree>("time_calibration_data");
246 timeCalibrationData->SetBranchAddress("Run", &event.Run);
247 timeCalibrationData->SetBranchAddress("Event", &event.Events);
248 timeCalibrationData->SetBranchAddress("nTrack", &event.nTrack);
249 timeCalibrationData->SetBranchAddress("Track_Charge", &event.Track_Charge);
250
251 timeCalibrationData->SetBranchAddress("t0", &event.t0);
252 timeCalibrationData->SetBranchAddress("t0_uc", &event.t0_uc);
253 timeCalibrationData->SetBranchAddress("flyTime", &event.flyTime);
254 timeCalibrationData->SetBranchAddress("recTime", &event.recTime);
255 timeCalibrationData->SetBranchAddress("dist", &event.dist);
256 timeCalibrationData->SetBranchAddress("diffDistX", &event.diffDistX);
257 timeCalibrationData->SetBranchAddress("diffDistY", &event.diffDistY);
258 timeCalibrationData->SetBranchAddress("diffDistZ", &event.diffDistZ);
259 timeCalibrationData->SetBranchAddress("eDep", &event.eDep);
260 timeCalibrationData->SetBranchAddress("nPE", &event.nPE);
261 timeCalibrationData->SetBranchAddress("channelId", &event.channelId);
262 timeCalibrationData->SetBranchAddress("inRPC", &event.inRPC);
263 timeCalibrationData->SetBranchAddress("isFlipped", &event.isFlipped);
264 timeCalibrationData->SetBranchAddress("isGood", &event.isGood);
265 timeCalibrationData->SetBranchAddress("getADCcount", &event.getADCcount);
266
267 m_evts.clear();
268
269 int n = timeCalibrationData->GetEntries();
270 int loadedEvents = 0;
271
272 for (int i = 0; i < n; ++i) {
273 timeCalibrationData->GetEntry(i);
274
275 // Convert channel number to KLMChannelIndex using channelNumberToElementNumbers
276 int subdetector, section, sector, layer, plane, strip;
277 m_ElementNumbers->channelNumberToElementNumbers(
278 event.channelId, &subdetector, &section, &sector, &layer, &plane, &strip);
279 KLMChannelIndex klmChannel(subdetector, section, sector, layer, plane, strip);
280
281 if (channelFilter(klmChannel)) {
282 m_evts[event.channelId].push_back(event);
283 loadedEvents++;
284 }
285 }
286
287 B2INFO("Batch loaded." << LogVar("Events", loadedEvents) << LogVar("Channels", m_evts.size()));
288}

◆ readCalibrationDataCounts()

void readCalibrationDataCounts ( std::map< KLMChannelNumber, unsigned int > & eventCounts)
private

Count events per channel (lightweight scan without loading full data).

Parameters
[out]eventCountsMap from channel number to event count.

Definition at line 164 of file KLMTimeAlgorithm.cc.

165{
166 B2INFO("Counting events per channel (lightweight scan)...");
167 Event event;
168 std::shared_ptr<TTree> timeCalibrationData;
169 timeCalibrationData = getObjectPtr<TTree>("time_calibration_data");
170 timeCalibrationData->SetBranchAddress("channelId", &event.channelId);
171
172 eventCounts.clear();
173
174 int n = timeCalibrationData->GetEntries();
175 for (int i = 0; i < n; ++i) {
176 timeCalibrationData->GetEntry(i);
177 eventCounts[event.channelId]++;
178 }
179
180 B2INFO("Event counting complete." << LogVar("Total events", n) << LogVar("Unique channels", eventCounts.size()));
181}

◆ readCalibrationDataFor2DFit()

void readCalibrationDataFor2DFit ( const std::vector< std::pair< KLMChannelNumber, unsigned int > > & channelsBKLM,
const std::vector< std::pair< KLMChannelNumber, unsigned int > > & channelsEKLM )
private

Load calibration data only for channels needed for 2D fit.

Parameters
[in]channelsBKLMBKLM channels sorted by event count.
[in]channelsEKLMEKLM channels sorted by event count.

Definition at line 183 of file KLMTimeAlgorithm.cc.

186{
187 B2INFO("Loading data for 2D fit (top 1000 channels from BKLM and EKLM)...");
188 Event event;
189 std::shared_ptr<TTree> timeCalibrationData;
190 timeCalibrationData = getObjectPtr<TTree>("time_calibration_data");
191 timeCalibrationData->SetBranchAddress("Run", &event.Run);
192 timeCalibrationData->SetBranchAddress("Event", &event.Events);
193 timeCalibrationData->SetBranchAddress("nTrack", &event.nTrack);
194 timeCalibrationData->SetBranchAddress("Track_Charge", &event.Track_Charge);
195
196 timeCalibrationData->SetBranchAddress("t0", &event.t0);
197 timeCalibrationData->SetBranchAddress("t0_uc", &event.t0_uc);
198 timeCalibrationData->SetBranchAddress("flyTime", &event.flyTime);
199 timeCalibrationData->SetBranchAddress("recTime", &event.recTime);
200 timeCalibrationData->SetBranchAddress("dist", &event.dist);
201 timeCalibrationData->SetBranchAddress("diffDistX", &event.diffDistX);
202 timeCalibrationData->SetBranchAddress("diffDistY", &event.diffDistY);
203 timeCalibrationData->SetBranchAddress("diffDistZ", &event.diffDistZ);
204 timeCalibrationData->SetBranchAddress("eDep", &event.eDep);
205 timeCalibrationData->SetBranchAddress("nPE", &event.nPE);
206 timeCalibrationData->SetBranchAddress("channelId", &event.channelId);
207 timeCalibrationData->SetBranchAddress("inRPC", &event.inRPC);
208 timeCalibrationData->SetBranchAddress("isFlipped", &event.isFlipped);
209 timeCalibrationData->SetBranchAddress("isGood", &event.isGood);
210 timeCalibrationData->SetBranchAddress("getADCcount", &event.getADCcount);
211
212 m_evts.clear();
213
214 // Build set of channels we need for 2D fit (top 1000 from each)
215 std::set<KLMChannelNumber> neededChannels;
216 int maxChannels = 1000;
217
218 for (size_t i = 0; i < channelsBKLM.size() && i < static_cast<size_t>(maxChannels); ++i) {
219 neededChannels.insert(channelsBKLM[i].first);
220 }
221 for (size_t i = 0; i < channelsEKLM.size() && i < static_cast<size_t>(maxChannels); ++i) {
222 neededChannels.insert(channelsEKLM[i].first);
223 }
224
225 int n = timeCalibrationData->GetEntries();
226 int loadedEvents = 0;
227
228 for (int i = 0; i < n; ++i) {
229 timeCalibrationData->GetEntry(i);
230
231 if (neededChannels.find(event.channelId) != neededChannels.end()) {
232 m_evts[event.channelId].push_back(event);
233 loadedEvents++;
234 }
235 }
236
237 B2INFO("2D fit data loaded." << LogVar("Events", loadedEvents) << LogVar("Channels", m_evts.size()));
238}

◆ 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}

◆ saveHist()

void saveHist ( )

Save histograms to file.

Definition at line 2409 of file KLMTimeAlgorithm.cc.

2410{
2411 m_outFile->cd();
2412 B2INFO("Save Histograms into Files.");
2413
2414 /* Save vital plots. */
2415 TDirectory* dir_monitor = m_outFile->mkdir("monitor_Hists", "", true);
2416 dir_monitor->cd();
2417 h_calibrated->SetDirectory(dir_monitor);
2418 hc_calibrated->SetDirectory(dir_monitor);
2419 h_diff->SetDirectory(dir_monitor);
2420
2421 m_outFile->cd();
2422 TDirectory* dir_eventT0 = m_outFile->mkdir("EventT0", "", true);
2423 dir_eventT0->cd();
2424
2425 // Original histograms
2426 h_eventT0_rpc->SetDirectory(dir_eventT0);
2427 h_eventT0_scint->SetDirectory(dir_eventT0);
2428 h_eventT0_scint_end->SetDirectory(dir_eventT0);
2429
2430 hc_eventT0_rpc->SetDirectory(dir_eventT0);
2431 hc_eventT0_scint->SetDirectory(dir_eventT0);
2432 hc_eventT0_scint_end->SetDirectory(dir_eventT0);
2433
2434 // ==== NEW DIAGNOSTIC PLOTS ====
2435
2436 // Hit multiplicity
2437 h_nHits_plus_rpc->SetDirectory(dir_eventT0);
2438 h_nHits_minus_rpc->SetDirectory(dir_eventT0);
2439 h_nHits_plus_scint->SetDirectory(dir_eventT0);
2440 h_nHits_minus_scint->SetDirectory(dir_eventT0);
2441 h_nHits_plus_scint_end->SetDirectory(dir_eventT0);
2442 h_nHits_minus_scint_end->SetDirectory(dir_eventT0);
2443
2444 // ΔT0 vs v
2445 h2_deltaT0_vs_v_rpc->SetDirectory(dir_eventT0);
2446 h2_deltaT0_vs_v_scint->SetDirectory(dir_eventT0);
2447 h2_deltaT0_vs_v_scint_end->SetDirectory(dir_eventT0);
2448
2449 // Profile plots
2450 prof_deltaT0_rms_vs_v_rpc->SetDirectory(dir_eventT0);
2451 prof_deltaT0_rms_vs_v_scint->SetDirectory(dir_eventT0);
2452 prof_deltaT0_rms_vs_v_scint_end->SetDirectory(dir_eventT0);
2453
2454 // ΔT0 vs total hits
2455 h2_deltaT0_vs_nhits_rpc->SetDirectory(dir_eventT0);
2456 h2_deltaT0_vs_nhits_scint->SetDirectory(dir_eventT0);
2457 h2_deltaT0_vs_nhits_scint_end->SetDirectory(dir_eventT0);
2458
2459 // Multiplicity-binned ΔT0
2460 hc_eventT0_rpc_lowN->SetDirectory(dir_eventT0);
2461 hc_eventT0_rpc_midN->SetDirectory(dir_eventT0);
2462 hc_eventT0_rpc_highN->SetDirectory(dir_eventT0);
2463 hc_eventT0_scint_lowN->SetDirectory(dir_eventT0);
2464 hc_eventT0_scint_midN->SetDirectory(dir_eventT0);
2465 hc_eventT0_scint_highN->SetDirectory(dir_eventT0);
2466 hc_eventT0_scint_end_lowN->SetDirectory(dir_eventT0);
2467 hc_eventT0_scint_end_midN->SetDirectory(dir_eventT0);
2468 hc_eventT0_scint_end_highN->SetDirectory(dir_eventT0);
2469
2470 m_outFile->cd();
2471 TDirectory* dir_effC = m_outFile->mkdir("effC_Hists", "", true);
2472 dir_effC->cd();
2473 m_ProfileRpcPhi->SetDirectory(dir_effC);
2474 m_ProfileRpcZ->SetDirectory(dir_effC);
2475 m_ProfileBKLMScintillatorPhi->SetDirectory(dir_effC);
2476 m_ProfileBKLMScintillatorZ->SetDirectory(dir_effC);
2477 m_ProfileEKLMScintillatorPlane1->SetDirectory(dir_effC);
2478 m_ProfileEKLMScintillatorPlane2->SetDirectory(dir_effC);
2479 m_Profile2RpcPhi->SetDirectory(dir_effC);
2480 m_Profile2RpcZ->SetDirectory(dir_effC);
2481 m_Profile2BKLMScintillatorPhi->SetDirectory(dir_effC);
2482 m_Profile2BKLMScintillatorZ->SetDirectory(dir_effC);
2483 m_Profile2EKLMScintillatorPlane1->SetDirectory(dir_effC);
2484 m_Profile2EKLMScintillatorPlane2->SetDirectory(dir_effC);
2485
2486 m_outFile->cd();
2487 TDirectory* dir_time = m_outFile->mkdir("time", "", true);
2488 dir_time->cd();
2489
2490 h_time_scint->SetDirectory(dir_time);
2491 hc_time_scint->SetDirectory(dir_time);
2492
2493 h_time_scint_end->SetDirectory(dir_time);
2494 hc_time_scint_end->SetDirectory(dir_time);
2495
2496 h_time_rpc->SetDirectory(dir_time);
2497 hc_time_rpc->SetDirectory(dir_time);
2498
2499 gre_time_channel_rpc->Write("gre_time_channel_rpc");
2500 gre_time_channel_scint->Write("gre_time_channel_scint");
2501 gre_time_channel_scint_end->Write("gre_time_channel_scint_end");
2502 gr_timeShift_channel_rpc->Write("gr_timeShift_channel_rpc");
2503 gr_timeShift_channel_scint->Write("gr_timeShift_channel_scint");
2504 gr_timeShift_channel_scint_end->Write("gr_timeShift_channel_scint_end");
2505 gre_ctime_channel_rpc->Write("gre_ctime_channel_rpc");
2506 gre_ctime_channel_scint->Write("gre_ctime_channel_scint");
2507 gre_ctime_channel_scint_end->Write("gre_ctime_channel_scint_end");
2508 gr_timeRes_channel_rpc->Write("gr_timeRes_channel_rpc");
2509 gr_timeRes_channel_scint->Write("gr_timeRes_channel_scint");
2510 gr_timeRes_channel_scint_end->Write("gr_timeRes_channel_scint_end");
2511
2512 B2INFO("Top file setup Done.");
2513
2514 /* Save debug plots (only if m_saveAllPlots is true). */
2515 if (!m_saveAllPlots) {
2516 B2INFO("Skipping debug histogram directory creation (m_saveAllPlots = false)");
2517 m_outFile->cd();
2518 m_outFile->Write();
2519 m_outFile->Close();
2520 B2INFO("File Write and Close. Done.");
2521 return;
2522 }
2523
2524 TDirectory* dir_time_F[2];
2525 TDirectory* dir_time_FS[2][8];
2526 TDirectory* dir_time_FSL[2][8][15];
2527 TDirectory* dir_time_FSLP[2][8][15][2];
2528 TDirectory* dir_time_F_end[2];
2529 TDirectory* dir_time_FS_end[2][4];
2530 TDirectory* dir_time_FSL_end[2][4][14];
2531 TDirectory* dir_time_FSLP_end[2][4][14][2];
2532 char dirname[50];
2533 B2INFO("Sub files declare Done.");
2534 for (int iF = 0; iF < 2; ++iF) {
2535 h_timeF_rpc[iF]->SetDirectory(dir_time);
2536 hc_timeF_rpc[iF]->SetDirectory(dir_time);
2537
2538 h2_timeF_rpc[iF]->SetDirectory(dir_time);
2539 h2c_timeF_rpc[iF]->SetDirectory(dir_time);
2540
2541 h_timeF_scint[iF]->SetDirectory(dir_time);
2542 hc_timeF_scint[iF]->SetDirectory(dir_time);
2543
2544 h2_timeF_scint[iF]->SetDirectory(dir_time);
2545 h2c_timeF_scint[iF]->SetDirectory(dir_time);
2546
2547 h_timeF_scint_end[iF]->SetDirectory(dir_time);
2548 hc_timeF_scint_end[iF]->SetDirectory(dir_time);
2549
2550 h2_timeF_scint_end[iF]->SetDirectory(dir_time);
2551 h2c_timeF_scint_end[iF]->SetDirectory(dir_time);
2552
2553 sprintf(dirname, "isForward_%d", iF);
2554 dir_time_F[iF] = dir_time->mkdir(dirname, "", true);
2555 dir_time_F[iF]->cd();
2556
2557 for (int iS = 0; iS < 8; ++iS) {
2558 h_timeFS_rpc[iF][iS]->SetDirectory(dir_time_F[iF]);
2559 hc_timeFS_rpc[iF][iS]->SetDirectory(dir_time_F[iF]);
2560
2561 h_timeFS_scint[iF][iS]->SetDirectory(dir_time_F[iF]);
2562 hc_timeFS_scint[iF][iS]->SetDirectory(dir_time_F[iF]);
2563
2564 h2_timeFS[iF][iS]->SetDirectory(dir_time_F[iF]);
2565 h2c_timeFS[iF][iS]->SetDirectory(dir_time_F[iF]);
2566
2567 sprintf(dirname, "Sector_%d", iS + 1);
2568 dir_time_FS[iF][iS] = dir_time_F[iF]->mkdir(dirname, "", true);
2569 dir_time_FS[iF][iS]->cd();
2570
2571 for (int iL = 0; iL < 15; ++iL) {
2572 h_timeFSL[iF][iS][iL]->SetDirectory(dir_time_FS[iF][iS]);
2573 hc_timeFSL[iF][iS][iL]->SetDirectory(dir_time_FS[iF][iS]);
2574
2575 sprintf(dirname, "Layer_%d", iL + 1);
2576 dir_time_FSL[iF][iS][iL] = dir_time_FS[iF][iS]->mkdir(dirname, "", true);
2577 dir_time_FSL[iF][iS][iL]->cd();
2578 for (int iP = 0; iP < 2; ++iP) {
2579 h_timeFSLP[iF][iS][iL][iP]->SetDirectory(dir_time_FSL[iF][iS][iL]);
2580 hc_timeFSLP[iF][iS][iL][iP]->SetDirectory(dir_time_FSL[iF][iS][iL]);
2581 h2_timeFSLP[iF][iS][iL][iP]->SetDirectory(dir_time_FSL[iF][iS][iL]);
2582 h2c_timeFSLP[iF][iS][iL][iP]->SetDirectory(dir_time_FSL[iF][iS][iL]);
2583
2584 sprintf(dirname, "Plane_%d", iP);
2585 dir_time_FSLP[iF][iS][iL][iP] = dir_time_FSL[iF][iS][iL]->mkdir(dirname, "", true);
2586 dir_time_FSLP[iF][iS][iL][iP]->cd();
2587
2588 }
2589 }
2590 }
2591
2592 sprintf(dirname, "isForward_%d_end", iF + 1);
2593 dir_time_F_end[iF] = dir_time->mkdir(dirname, "", true);
2594 dir_time_F_end[iF]->cd();
2595 int maxLayer = 12 + 2 * iF;
2596 for (int iS = 0; iS < 4; ++iS) {
2597 h_timeFS_scint_end[iF][iS]->SetDirectory(dir_time_F_end[iF]);
2598 hc_timeFS_scint_end[iF][iS]->SetDirectory(dir_time_F_end[iF]);
2599
2600 h2_timeFS_end[iF][iS]->SetDirectory(dir_time_F_end[iF]);
2601 h2c_timeFS_end[iF][iS]->SetDirectory(dir_time_F_end[iF]);
2602
2603 sprintf(dirname, "Sector_%d_end", iS + 1);
2604 dir_time_FS_end[iF][iS] = dir_time_F_end[iF]->mkdir(dirname, "", true);
2605 dir_time_FS_end[iF][iS]->cd();
2606 for (int iL = 0; iL < maxLayer; ++iL) {
2607 h_timeFSL_end[iF][iS][iL]->SetDirectory(dir_time_FS_end[iF][iS]);
2608 hc_timeFSL_end[iF][iS][iL]->SetDirectory(dir_time_FS_end[iF][iS]);
2609
2610 sprintf(dirname, "Layer_%d_end", iL + 1);
2611 dir_time_FSL_end[iF][iS][iL] = dir_time_FS_end[iF][iS]->mkdir(dirname, "", true);
2612 dir_time_FSL_end[iF][iS][iL]->cd();
2613 for (int iP = 0; iP < 2; ++iP) {
2614 h_timeFSLP_end[iF][iS][iL][iP]->SetDirectory(dir_time_FSL_end[iF][iS][iL]);
2615 hc_timeFSLP_end[iF][iS][iL][iP]->SetDirectory(dir_time_FSL_end[iF][iS][iL]);
2616 h2_timeFSLP_end[iF][iS][iL][iP]->SetDirectory(dir_time_FSL_end[iF][iS][iL]);
2617 h2c_timeFSLP_end[iF][iS][iL][iP]->SetDirectory(dir_time_FSL_end[iF][iS][iL]);
2618
2619 sprintf(dirname, "plane_%d_end", iP);
2620 dir_time_FSLP_end[iF][iS][iL][iP] = dir_time_FSL_end[iF][iS][iL]->mkdir(dirname, "", true);
2621 dir_time_FSLP_end[iF][iS][iL][iP]->cd();
2622
2623 }
2624 }
2625 }
2626 }
2627 m_outFile->cd();
2628 m_outFile->Write();
2629 m_outFile->Close();
2630 B2INFO("File Write and Close. Done.");
2631}

◆ setApplyChargeRestriction()

void setApplyChargeRestriction ( bool apply)
inline

Enable or disable ADC/charge restriction cuts for scintillators.

When enabled (default), BKLM scintillator requires 30 < ADC < 320 and EKLM requires 40 < ADC < 350.

Parameters
[in]applyTrue to apply charge cuts (default), false to disable.

Definition at line 202 of file KLMTimeAlgorithm.h.

203 {
204 m_applyChargeRestriction = apply;
205 }

◆ setDebug()

void setDebug ( )
inline

Turn on debug mode (prints histograms and output running log).

Definition at line 155 of file KLMTimeAlgorithm.h.

156 {
157 m_debug = true;
158 }

◆ 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.

◆ setLowerLimit()

void setLowerLimit ( int counts)
inline

Set the lower number of hits collected on one single strip.

If the hit number is lower than the limit, the strip will not be calibrated and set the average value of the calibration constant.

Definition at line 191 of file KLMTimeAlgorithm.h.

192 {
193 m_lower_limit_counts = counts;
194 }

◆ setMC()

void setMC ( bool mc)
inline

Set flag indicating whether the input is MC sample.

The histogram ranges are different for data and MC. This setting cannot be determined automatically, because the collector output does not contain metadata.

Definition at line 165 of file KLMTimeAlgorithm.h.

166 {
167 m_mc = mc;
168 }

◆ setMinimalDigitNumber()

void setMinimalDigitNumber ( int minimalDigitNumber)
inline

Set minimal digit number (total).

Definition at line 181 of file KLMTimeAlgorithm.h.

182 {
183 m_MinimalDigitNumber = minimalDigitNumber;
184 }

◆ 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;}

◆ setSaveAllPlots()

void setSaveAllPlots ( bool on)
inline

Save every preallocated debug histogram family (sectors/layers/planes/2D maps).

Default is false (minimal mode).

Definition at line 211 of file KLMTimeAlgorithm.h.

212 {
213 m_saveAllPlots = on;
214 }

◆ setSaveChannelHists()

void setSaveChannelHists ( bool on)
inline

When running in minimal mode, also write the per-channel temporary histograms (the vital tc, raw, hc 1D’s created on-the-fly) before deleting them.

Default is false.

Definition at line 221 of file KLMTimeAlgorithm.h.

222 {
223 m_saveChannelHists = on;
224 }

◆ setupDatabase()

void setupDatabase ( )
private

Setup the database.

Definition at line 111 of file KLMTimeAlgorithm.cc.

112{
113 const std::vector<Calibration::ExpRun>& runs = getRunList();
114 int firstExperiment = runs[0].first;
115 int lastExperiment = runs[runs.size() - 1].first;
116 if (firstExperiment != lastExperiment) {
117 B2FATAL("Runs from different experiments are used "
118 "for KLM time calibration (single algorithm run).");
119 }
120 /* DataStore. */
122 StoreObjPtr<EventMetaData> eventMetaData;
123 eventMetaData.registerInDataStore();
125 /* Database. */
126 if (eventMetaData.isValid()) {
127 if (eventMetaData->getExperiment() != firstExperiment) {
128 B2FATAL("Runs from different experiments are used "
129 "for KLM time calibration (consecutive algorithm runs).");
130 }
131 eventMetaData->setExperiment(firstExperiment);
132 eventMetaData->setRun(runs[0].second);
133 } else {
134 eventMetaData.construct(1, runs[0].second, firstExperiment);
135 }
136 DBStore& dbStore = DBStore::Instance();
137 dbStore.update();
138 dbStore.updateEvent();
139 /*
140 * For calibration algorithms, the database is not initialized on class
141 * creation. Do not move the database object to class members.
142 */
143 DBObjPtr<BKLMGeometryPar> bklmGeometry;
146}
const std::vector< Calibration::ExpRun > & getRunList() const
Get the list of runs for which calibration is called.
static DataStore & Instance()
Instance of singleton Store.
Definition DataStore.cc:53
void setInitializeActive(bool active)
Setter for m_initializeActive.
Definition DataStore.cc:93
static const GeometryData & Instance(enum DataSource dataSource=c_Database, const GearDir *gearDir=nullptr)
Instantiation.
bool registerInDataStore(DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut)
Register the object/array in the DataStore.
bool isValid() const
Check whether the object was created.
bool construct(Args &&... params)
Construct an object of type T in this StoreObjPtr, using the provided constructor arguments.
static GeometryPar * instance(void)
Static method to get a reference to the singleton GeometryPar instance.
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

◆ timeDistance2dFit()

void timeDistance2dFit ( const std::vector< std::pair< KLMChannelNumber, unsigned int > > & channels,
double & delay,
double & delayError )
private

Two-dimensional fit for individual channels.

Parameters
[in]channelsChannels.
[out]delayDelay (ns / cm).
[out]delayErrorDelay error.

Definition at line 974 of file KLMTimeAlgorithm.cc.

977{
978 int nFits = 1000;
979 int nConvergedFits = 0;
980 delay = 0;
981 delayError = 0;
982 if (nFits > (int)channels.size())
983 nFits = channels.size();
984 for (int i = 0; i < nFits; ++i) {
985 int subdetector, section, sector, layer, plane, strip;
986 m_ElementNumbers->channelNumberToElementNumbers(
987 channels[i].first, &subdetector, &section, &sector, &layer, &plane,
988 &strip);
989 if (subdetector == KLMElementNumbers::c_BKLM) {
990 s_LowerTimeBoundary = m_LowerTimeBoundaryScintillatorsBKLM;
991 s_UpperTimeBoundary = m_UpperTimeBoundaryScintillatorsBKLM;
992 const bklm::Module* module =
993 m_BKLMGeometry->findModule(section, sector, layer);
994 s_StripLength = module->getStripLength(plane, strip);
995 } else {
996 s_LowerTimeBoundary = m_LowerTimeBoundaryScintillatorsEKLM;
997 s_UpperTimeBoundary = m_UpperTimeBoundaryScintillatorsEKLM;
998 s_StripLength = m_EKLMGeometry->getStripLength(strip) /
999 CLHEP::cm * Unit::cm;
1000 }
1001 for (int j = 0; j < c_NBinsTime; ++j) {
1002 for (int k = 0; k < c_NBinsDistance; ++k)
1003 s_BinnedData[j][k] = 0;
1004 }
1005 std::vector<struct Event> eventsChannel = m_evts[channels[i].first];
1006 double averageTime = 0;
1007 for (const Event& event : eventsChannel) {
1008 double timeHit = event.time();
1009 if (m_useEventT0)
1010 timeHit = timeHit - event.t0;
1011
1012 if (timeHit <= -400e3) {
1013 continue;
1014 }
1015
1016 averageTime = averageTime + timeHit;
1017 int timeBin = std::floor((timeHit - s_LowerTimeBoundary) * c_NBinsTime /
1018 (s_UpperTimeBoundary - s_LowerTimeBoundary));
1019 if (timeBin < 0 || timeBin >= c_NBinsTime)
1020 continue;
1021 int distanceBin = std::floor(event.dist * c_NBinsDistance / s_StripLength);
1022 if (distanceBin < 0 || distanceBin >= c_NBinsDistance) {
1023 B2ERROR("The distance to SiPM is greater than the strip length.");
1024 continue;
1025 }
1026 s_BinnedData[timeBin][distanceBin] += 1;
1027 }
1028 averageTime = averageTime / eventsChannel.size();
1029 TMinuit minuit(5);
1030 minuit.SetPrintLevel(-1);
1031 int minuitResult;
1032 minuit.mnparm(0, "P0", 1, 0.001, 0, 0, minuitResult);
1033 minuit.mnparm(1, "N", 10, 0.001, 0, 0, minuitResult);
1034 minuit.mnparm(2, "T0", averageTime, 0.001, 0, 0, minuitResult);
1035 minuit.mnparm(3, "SIGMA", 10, 0.001, 0, 0, minuitResult);
1036 minuit.mnparm(4, "DELAY", 0.0, 0.001, 0, 0, minuitResult);
1037 minuit.SetFCN(fcn);
1038 minuit.mncomd("FIX 2 3 4 5", minuitResult);
1039 minuit.mncomd("MIGRAD 10000", minuitResult);
1040 minuit.mncomd("RELEASE 2", minuitResult);
1041 minuit.mncomd("MIGRAD 10000", minuitResult);
1042 minuit.mncomd("RELEASE 3", minuitResult);
1043 minuit.mncomd("MIGRAD 10000", minuitResult);
1044 minuit.mncomd("RELEASE 4", minuitResult);
1045 minuit.mncomd("MIGRAD 10000", minuitResult);
1046 minuit.mncomd("RELEASE 5", minuitResult);
1047 minuit.mncomd("MIGRAD 10000", minuitResult);
1048 /* Require converged fit with accurate error matrix. */
1049 if (minuit.fISW[1] != 3)
1050 continue;
1051 nConvergedFits++;
1052 double channelDelay, channelDelayError;
1053 minuit.GetParameter(4, channelDelay, channelDelayError);
1054 delay = delay + channelDelay;
1055 delayError = delayError + channelDelayError * channelDelayError;
1056 }
1057 delay = delay / nConvergedFits;
1058 delayError = sqrt(delayError) / (nConvergedFits - 1);
1059}
double sqrt(double a)
sqrt for double
Definition beamHelpers.h:28

◆ tR_lowerStrip()

std::pair< int, double > tR_lowerStrip ( const KLMChannelIndex & klmChannel)

Tracing available channels with decreasing strip number.

Parameters
[in]klmChannelKLM channel index.

Definition at line 2770 of file KLMTimeAlgorithm.cc.

2771{
2772 std::pair<int, double> tR;
2773 int cId = klmChannel.getKLMChannelNumber();
2774 int iC = klmChannel.getStrip();
2775 if (m_timeRes.find(cId) != m_timeRes.end()) {
2776 tR.first = iC;
2777 tR.second = m_timeRes[cId];
2778 } else if (iC == 1) {
2779 tR.first = iC;
2780 tR.second = 0.0;
2781 } else {
2782 int iSub = klmChannel.getSubdetector();
2783 int iF = klmChannel.getSection();
2784 int iS = klmChannel.getSector();
2785 int iL = klmChannel.getLayer();
2786 int iP = klmChannel.getPlane();
2787 KLMChannelIndex kCIndex(iSub, iF, iS, iL, iP, iC - 1);
2788 tR = tR_lowerStrip(kCIndex);
2789 }
2790 return tR;
2791}
KLMChannelNumber getKLMChannelNumber() const
Get KLM channel number.

◆ tR_upperStrip()

std::pair< int, double > tR_upperStrip ( const KLMChannelIndex & klmChannel)

Tracing available channels with increasing strip number.

Parameters
[in]klmChannelKLM channel index.

Definition at line 2744 of file KLMTimeAlgorithm.cc.

2745{
2746 std::pair<int, double> tR;
2747 int cId = klmChannel.getKLMChannelNumber();
2748 int iSub = klmChannel.getSubdetector();
2749 int iF = klmChannel.getSection();
2750 int iS = klmChannel.getSector();
2751 int iL = klmChannel.getLayer();
2752 int iP = klmChannel.getPlane();
2753 int iC = klmChannel.getStrip();
2755 if (iSub == KLMElementNumbers::c_BKLM)
2756 totNStrips = BKLMElementNumbers::getNStrips(iF, iS, iL, iP);
2757 if (m_timeRes.find(cId) != m_timeRes.end()) {
2758 tR.first = iC;
2759 tR.second = m_timeRes[cId];
2760 } else if (iC == totNStrips) {
2761 tR.first = iC;
2762 tR.second = 0.0;
2763 } else {
2764 KLMChannelIndex kCIndex(iSub, iF, iS, iL, iP, iC + 1);
2765 tR = tR_upperStrip(kCIndex);
2766 }
2767 return tR;
2768}

◆ tS_lowerStrip()

std::pair< int, double > tS_lowerStrip ( const KLMChannelIndex & klmChannel)

Tracing available channels with decreasing strip number.

Parameters
[in]klmChannelKLM channel index.

Definition at line 2690 of file KLMTimeAlgorithm.cc.

2691{
2692 std::pair<int, double> tS;
2693 int cId = klmChannel.getKLMChannelNumber();
2694 int iC = klmChannel.getStrip();
2695 if (m_timeShift.find(cId) != m_timeShift.end()) {
2696 tS.first = iC;
2697 tS.second = m_timeShift[cId];
2698 } else if (iC == 1) {
2699 tS.first = iC;
2700 tS.second = 0.0;
2701 } else {
2702 int iSub = klmChannel.getSubdetector();
2703 int iF = klmChannel.getSection();
2704 int iS = klmChannel.getSector();
2705 int iL = klmChannel.getLayer();
2706 int iP = klmChannel.getPlane();
2707 KLMChannelIndex kCIndex(iSub, iF, iS, iL, iP, iC - 1);
2708 tS = tS_lowerStrip(kCIndex);
2709 }
2710 return tS;
2711}

◆ tS_upperStrip()

std::pair< int, double > tS_upperStrip ( const KLMChannelIndex & klmChannel)

Tracing available channels with increasing strip number.

Parameters
[in]klmChannelKLM channel index.

Definition at line 2664 of file KLMTimeAlgorithm.cc.

2665{
2666 std::pair<int, double> tS;
2667 int cId = klmChannel.getKLMChannelNumber();
2668 int iSub = klmChannel.getSubdetector();
2669 int iF = klmChannel.getSection();
2670 int iS = klmChannel.getSector();
2671 int iL = klmChannel.getLayer();
2672 int iP = klmChannel.getPlane();
2673 int iC = klmChannel.getStrip();
2675 if (iSub == KLMElementNumbers::c_BKLM)
2676 totNStrips = BKLMElementNumbers::getNStrips(iF, iS, iL, iP);
2677 if (m_timeShift.find(cId) != m_timeShift.end()) {
2678 tS.first = iC;
2679 tS.second = m_timeShift[cId];
2680 } else if (iC == totNStrips) {
2681 tS.first = iC;
2682 tS.second = 0.0;
2683 } else {
2684 KLMChannelIndex kCIndex(iSub, iF, iS, iL, iP, iC + 1);
2685 tS = tS_upperStrip(kCIndex);
2686 }
2687 return tS;
2688}

◆ 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}

◆ useEvtT0()

void useEvtT0 ( )
inline

Use event T0 as the initial time point or not.

Definition at line 173 of file KLMTimeAlgorithm.h.

174 {
175 m_useEventT0 = true;
176 }

◆ writeThenDelete_() [1/2]

void writeThenDelete_ ( TH1 * h,
bool write,
TDirectory * dir = nullptr )
private

Optionally write a histogram, then delete it to free memory.

Used for on-the-fly per-channel hists in minimal mode.

Parameters
hHistogram to write and delete.
writeWhether to write the histogram.
dirOptional directory to write the histogram to.

Definition at line 1061 of file KLMTimeAlgorithm.cc.

1062{
1063 if (h == nullptr)
1064 return;
1065 if (write && m_outFile) {
1066 // Follow the pattern from saveHist(): cd into directory, then SetDirectory, then Write
1067 if (dir) {
1068 dir->cd();
1069 h->SetDirectory(dir);
1070 } else {
1071 m_outFile->cd();
1072 h->SetDirectory(m_outFile);
1073 }
1074 h->Write();
1075 m_outFile->cd(); // Return to root directory
1076 }
1077 delete h;
1078}

◆ writeThenDelete_() [2/2]

void writeThenDelete_ ( TH2 * h,
bool write,
TDirectory * dir = nullptr )
private

Same as above, but for 2D histograms.

Definition at line 1080 of file KLMTimeAlgorithm.cc.

1081{
1082 if (h == nullptr)
1083 return;
1084 if (write && m_outFile) {
1085 // Follow the pattern from saveHist(): cd into directory, then SetDirectory, then Write
1086 if (dir) {
1087 dir->cd();
1088 h->SetDirectory(dir);
1089 } else {
1090 m_outFile->cd();
1091 h->SetDirectory(m_outFile);
1092 }
1093 h->Write();
1094 m_outFile->cd(); // Return to root directory
1095 }
1096 delete h;
1097}

Member Data Documentation

◆ fcn_const

TF1* fcn_const = nullptr
private

Const function.

Global time distribution fitting.

Definition at line 930 of file KLMTimeAlgorithm.h.

◆ fcn_gaus

TF1* fcn_gaus = nullptr
private

Gaussian function.

Scitillator time distribution fitting.

Definition at line 933 of file KLMTimeAlgorithm.h.

◆ fcn_land

TF1* fcn_land = nullptr
private

Landau function.

RPC time distribution fitting.

Definition at line 936 of file KLMTimeAlgorithm.h.

◆ fcn_pol1

TF1* fcn_pol1 = nullptr
private

Pol1 function.

Effective light speed fitting.

Definition at line 927 of file KLMTimeAlgorithm.h.

◆ gr_timeRes_channel_rpc

TGraph* gr_timeRes_channel_rpc = nullptr
private

BKLM RPC.

Definition at line 596 of file KLMTimeAlgorithm.h.

◆ gr_timeRes_channel_scint

TGraph* gr_timeRes_channel_scint = nullptr
private

BKLM scintillator.

Definition at line 599 of file KLMTimeAlgorithm.h.

◆ gr_timeRes_channel_scint_end

TGraph* gr_timeRes_channel_scint_end = nullptr
private

EKLM.

Definition at line 602 of file KLMTimeAlgorithm.h.

◆ gr_timeShift_channel_rpc

TGraph* gr_timeShift_channel_rpc = nullptr
private

BKLM RPC.

Definition at line 585 of file KLMTimeAlgorithm.h.

◆ gr_timeShift_channel_scint

TGraph* gr_timeShift_channel_scint = nullptr
private

BKLM scintillator.

Definition at line 588 of file KLMTimeAlgorithm.h.

◆ gr_timeShift_channel_scint_end

TGraph* gr_timeShift_channel_scint_end = nullptr
private

EKLM.

Definition at line 591 of file KLMTimeAlgorithm.h.

◆ gre_ctime_channel_rpc

TGraphErrors* gre_ctime_channel_rpc = nullptr
private

BKLM RPC.

Definition at line 574 of file KLMTimeAlgorithm.h.

◆ gre_ctime_channel_scint

TGraphErrors* gre_ctime_channel_scint = nullptr
private

BKLM Scintillator.

Definition at line 577 of file KLMTimeAlgorithm.h.

◆ gre_ctime_channel_scint_end

TGraphErrors* gre_ctime_channel_scint_end = nullptr
private

EKLM.

Definition at line 580 of file KLMTimeAlgorithm.h.

◆ gre_time_channel_rpc

TGraphErrors* gre_time_channel_rpc = nullptr
private

BKLM RPC.

Definition at line 563 of file KLMTimeAlgorithm.h.

◆ gre_time_channel_scint

TGraphErrors* gre_time_channel_scint = nullptr
private

BKLM Scintillator.

Definition at line 566 of file KLMTimeAlgorithm.h.

◆ gre_time_channel_scint_end

TGraphErrors* gre_time_channel_scint_end = nullptr
private

EKLM.

Definition at line 569 of file KLMTimeAlgorithm.h.

◆ h2_deltaT0_vs_nhits_rpc

TH2F* h2_deltaT0_vs_nhits_rpc = nullptr
private

DeltaT0 vs total hit count for RPC.

Definition at line 889 of file KLMTimeAlgorithm.h.

◆ h2_deltaT0_vs_nhits_scint

TH2F* h2_deltaT0_vs_nhits_scint = nullptr
private

DeltaT0 vs total hit count for BKLM scintillator.

Definition at line 892 of file KLMTimeAlgorithm.h.

◆ h2_deltaT0_vs_nhits_scint_end

TH2F* h2_deltaT0_vs_nhits_scint_end = nullptr
private

DeltaT0 vs total hit count for EKLM scintillator.

Definition at line 895 of file KLMTimeAlgorithm.h.

◆ h2_deltaT0_vs_v_rpc

TH2F* h2_deltaT0_vs_v_rpc = nullptr
private

DeltaT0 vs inverse hit count for RPC.

Definition at line 871 of file KLMTimeAlgorithm.h.

◆ h2_deltaT0_vs_v_scint

TH2F* h2_deltaT0_vs_v_scint = nullptr
private

DeltaT0 vs inverse hit count for BKLM scintillator.

Definition at line 874 of file KLMTimeAlgorithm.h.

◆ h2_deltaT0_vs_v_scint_end

TH2F* h2_deltaT0_vs_v_scint_end = nullptr
private

DeltaT0 vs inverse hit count for EKLM scintillator.

Definition at line 877 of file KLMTimeAlgorithm.h.

◆ h2_timeF_rpc

TH2F* h2_timeF_rpc[2] = {nullptr}
private

BKLM RPC part.

Definition at line 714 of file KLMTimeAlgorithm.h.

714{nullptr};

◆ h2_timeF_scint

TH2F* h2_timeF_scint[2] = {nullptr}
private

BKLM scintillator part.

Definition at line 717 of file KLMTimeAlgorithm.h.

717{nullptr};

◆ h2_timeF_scint_end

TH2F* h2_timeF_scint_end[2] = {nullptr}
private

EKLM part.

Definition at line 720 of file KLMTimeAlgorithm.h.

720{nullptr};

◆ h2_timeFS

TH2F* h2_timeFS[2][8] = {{nullptr}}
private

BKLM part.

Definition at line 764 of file KLMTimeAlgorithm.h.

764{{nullptr}};

◆ h2_timeFS_end

TH2F* h2_timeFS_end[2][4] = {{nullptr}}
private

EKLM part.

Definition at line 767 of file KLMTimeAlgorithm.h.

767{{nullptr}};

◆ h2_timeFSLP

TH2F* h2_timeFSLP[2][8][15][2] = {{{{nullptr}}}}
private

BKLM part.

Definition at line 818 of file KLMTimeAlgorithm.h.

818{{{{nullptr}}}};

◆ h2_timeFSLP_end

TH2F* h2_timeFSLP_end[2][4][14][2] = {{{{nullptr}}}}
private

EKLM part.

Definition at line 821 of file KLMTimeAlgorithm.h.

821{{{{nullptr}}}};

◆ h2c_timeF_rpc

TH2F* h2c_timeF_rpc[2] = {nullptr}
private

BKLM RPC part.

Definition at line 728 of file KLMTimeAlgorithm.h.

728{nullptr};

◆ h2c_timeF_scint

TH2F* h2c_timeF_scint[2] = {nullptr}
private

BKLM scintillator part.

Definition at line 731 of file KLMTimeAlgorithm.h.

731{nullptr};

◆ h2c_timeF_scint_end

TH2F* h2c_timeF_scint_end[2] = {nullptr}
private

EKLM part.

Definition at line 734 of file KLMTimeAlgorithm.h.

734{nullptr};

◆ h2c_timeFS

TH2F* h2c_timeFS[2][8] = {{nullptr}}
private

BKLM part.

Definition at line 775 of file KLMTimeAlgorithm.h.

775{{nullptr}};

◆ h2c_timeFS_end

TH2F* h2c_timeFS_end[2][4] = {{nullptr}}
private

EKLM part.

Definition at line 778 of file KLMTimeAlgorithm.h.

778{{nullptr}};

◆ h2c_timeFSLP

TH2F* h2c_timeFSLP[2][8][15][2] = {{{{nullptr}}}}
private

BKLM part.

Definition at line 829 of file KLMTimeAlgorithm.h.

829{{{{nullptr}}}};

◆ h2c_timeFSLP_end

TH2F* h2c_timeFSLP_end[2][4][14][2] = {{{{nullptr}}}}
private

EKLM part.

Definition at line 832 of file KLMTimeAlgorithm.h.

832{{{{nullptr}}}};

◆ h_calibrated

TH1I* h_calibrated = nullptr
private

Calibration statistics for each channel.

Definition at line 552 of file KLMTimeAlgorithm.h.

◆ h_diff

TH1F* h_diff = nullptr
private

Distance between global and local position.

Definition at line 558 of file KLMTimeAlgorithm.h.

◆ h_eventT0_rpc

TH1F* h_eventT0_rpc = nullptr
private

EventT0 seen by RPC hits.

Definition at line 835 of file KLMTimeAlgorithm.h.

◆ h_eventT0_scint

TH1F* h_eventT0_scint = nullptr
private

EventT0 seen by BKLM scintillator hits.

Definition at line 838 of file KLMTimeAlgorithm.h.

◆ h_eventT0_scint_end

TH1F* h_eventT0_scint_end = nullptr
private

EventT0 seen by EKLM scintillator hits.

Definition at line 841 of file KLMTimeAlgorithm.h.

◆ h_nHits_minus_rpc

TH1F* h_nHits_minus_rpc = nullptr
private

Number of RPC hits per mu- track.

Definition at line 856 of file KLMTimeAlgorithm.h.

◆ h_nHits_minus_scint

TH1F* h_nHits_minus_scint = nullptr
private

Number of BKLM scintillator hits per mu- track.

Definition at line 862 of file KLMTimeAlgorithm.h.

◆ h_nHits_minus_scint_end

TH1F* h_nHits_minus_scint_end = nullptr
private

Number of EKLM scintillator hits per mu- track.

Definition at line 868 of file KLMTimeAlgorithm.h.

◆ h_nHits_plus_rpc

TH1F* h_nHits_plus_rpc = nullptr
private

Number of RPC hits per mu+ track.

Definition at line 853 of file KLMTimeAlgorithm.h.

◆ h_nHits_plus_scint

TH1F* h_nHits_plus_scint = nullptr
private

Number of BKLM scintillator hits per mu+ track.

Definition at line 859 of file KLMTimeAlgorithm.h.

◆ h_nHits_plus_scint_end

TH1F* h_nHits_plus_scint_end = nullptr
private

Number of EKLM scintillator hits per mu+ track.

Definition at line 865 of file KLMTimeAlgorithm.h.

◆ h_time_rpc

TH1F* h_time_rpc = nullptr
private

BKLM RPC part.

Definition at line 661 of file KLMTimeAlgorithm.h.

◆ h_time_rpc_tc

TH1F* h_time_rpc_tc = nullptr
private

BKLM RPC part.

Definition at line 650 of file KLMTimeAlgorithm.h.

◆ h_time_scint

TH1F* h_time_scint = nullptr
private

BKLM scintillator part.

Definition at line 664 of file KLMTimeAlgorithm.h.

◆ h_time_scint_end

TH1F* h_time_scint_end = nullptr
private

EKLM part.

Definition at line 667 of file KLMTimeAlgorithm.h.

◆ h_time_scint_tc

TH1F* h_time_scint_tc = nullptr
private

BKLM scintillator part.

Definition at line 653 of file KLMTimeAlgorithm.h.

◆ h_time_scint_tc_end

TH1F* h_time_scint_tc_end = nullptr
private

EKLM part.

Definition at line 656 of file KLMTimeAlgorithm.h.

◆ h_timeF_rpc

TH1F* h_timeF_rpc[2] = {nullptr}
private

BKLM RPC part.

Definition at line 686 of file KLMTimeAlgorithm.h.

686{nullptr};

◆ h_timeF_scint

TH1F* h_timeF_scint[2] = {nullptr}
private

BKLM scintillator part.

Definition at line 689 of file KLMTimeAlgorithm.h.

689{nullptr};

◆ h_timeF_scint_end

TH1F* h_timeF_scint_end[2] = {nullptr}
private

EKLM part.

Definition at line 692 of file KLMTimeAlgorithm.h.

692{nullptr};

◆ h_timeFS_rpc

TH1F* h_timeFS_rpc[2][8] = {{nullptr}}
private

BKLM RPC part.

Definition at line 739 of file KLMTimeAlgorithm.h.

739{{nullptr}};

◆ h_timeFS_scint

TH1F* h_timeFS_scint[2][8] = {{nullptr}}
private

BKLM scintillator part.

Definition at line 742 of file KLMTimeAlgorithm.h.

742{{nullptr}};

◆ h_timeFS_scint_end

TH1F* h_timeFS_scint_end[2][4] = {{nullptr}}
private

EKLM part.

Definition at line 745 of file KLMTimeAlgorithm.h.

745{{nullptr}};

◆ h_timeFSL

TH1F* h_timeFSL[2][8][15] = {{{nullptr}}}
private

BKLM part.

Definition at line 783 of file KLMTimeAlgorithm.h.

783{{{nullptr}}};

◆ h_timeFSL_end

TH1F* h_timeFSL_end[2][4][14] = {{{nullptr}}}
private

EKLM part.

Definition at line 786 of file KLMTimeAlgorithm.h.

786{{{nullptr}}};

◆ h_timeFSLP

TH1F* h_timeFSLP[2][8][15][2] = {{{{nullptr}}}}
private

BKLM part.

Definition at line 799 of file KLMTimeAlgorithm.h.

799{{{{nullptr}}}};

◆ h_timeFSLP_end

TH1F* h_timeFSLP_end[2][4][14][2] = {{{{nullptr}}}}
private

EKLM part.

Definition at line 802 of file KLMTimeAlgorithm.h.

802{{{{nullptr}}}};

◆ hc_calibrated

TH1I* hc_calibrated = nullptr
private

Calibration statistics for each channel.

Definition at line 555 of file KLMTimeAlgorithm.h.

◆ hc_eventT0_rpc

TH1F* hc_eventT0_rpc = nullptr
private

Corrected EventT0 for RPC hits.

Definition at line 844 of file KLMTimeAlgorithm.h.

◆ hc_eventT0_rpc_highN

TH1F* hc_eventT0_rpc_highN = nullptr
private

Corrected EventT0 for RPC with high hit count.

Definition at line 904 of file KLMTimeAlgorithm.h.

◆ hc_eventT0_rpc_lowN

TH1F* hc_eventT0_rpc_lowN = nullptr
private

Corrected EventT0 for RPC with low hit count.

Definition at line 898 of file KLMTimeAlgorithm.h.

◆ hc_eventT0_rpc_midN

TH1F* hc_eventT0_rpc_midN = nullptr
private

Corrected EventT0 for RPC with medium hit count.

Definition at line 901 of file KLMTimeAlgorithm.h.

◆ hc_eventT0_scint

TH1F* hc_eventT0_scint = nullptr
private

Corrected EventT0 for BKLM scintillator hits.

Definition at line 847 of file KLMTimeAlgorithm.h.

◆ hc_eventT0_scint_end

TH1F* hc_eventT0_scint_end = nullptr
private

Corrected EventT0 for EKLM scintillator hits.

Definition at line 850 of file KLMTimeAlgorithm.h.

◆ hc_eventT0_scint_end_highN

TH1F* hc_eventT0_scint_end_highN = nullptr
private

Corrected EventT0 for EKLM scintillator with high hit count.

Definition at line 922 of file KLMTimeAlgorithm.h.

◆ hc_eventT0_scint_end_lowN

TH1F* hc_eventT0_scint_end_lowN = nullptr
private

Corrected EventT0 for EKLM scintillator with low hit count.

Definition at line 916 of file KLMTimeAlgorithm.h.

◆ hc_eventT0_scint_end_midN

TH1F* hc_eventT0_scint_end_midN = nullptr
private

Corrected EventT0 for EKLM scintillator with medium hit count.

Definition at line 919 of file KLMTimeAlgorithm.h.

◆ hc_eventT0_scint_highN

TH1F* hc_eventT0_scint_highN = nullptr
private

Corrected EventT0 for BKLM scintillator with high hit count.

Definition at line 913 of file KLMTimeAlgorithm.h.

◆ hc_eventT0_scint_lowN

TH1F* hc_eventT0_scint_lowN = nullptr
private

Corrected EventT0 for BKLM scintillator with low hit count.

Definition at line 907 of file KLMTimeAlgorithm.h.

◆ hc_eventT0_scint_midN

TH1F* hc_eventT0_scint_midN = nullptr
private

Corrected EventT0 for BKLM scintillator with medium hit count.

Definition at line 910 of file KLMTimeAlgorithm.h.

◆ hc_time_rpc

TH1F* hc_time_rpc = nullptr
private

BKLM RPC part.

Definition at line 672 of file KLMTimeAlgorithm.h.

◆ hc_time_scint

TH1F* hc_time_scint = nullptr
private

BKLM scintillator part.

Definition at line 675 of file KLMTimeAlgorithm.h.

◆ hc_time_scint_end

TH1F* hc_time_scint_end = nullptr
private

EKLM part.

Definition at line 678 of file KLMTimeAlgorithm.h.

◆ hc_timeF_rpc

TH1F* hc_timeF_rpc[2] = {nullptr}
private

BKLM RPC part.

Definition at line 700 of file KLMTimeAlgorithm.h.

700{nullptr};

◆ hc_timeF_scint

TH1F* hc_timeF_scint[2] = {nullptr}
private

BKLM scintillator part.

Definition at line 703 of file KLMTimeAlgorithm.h.

703{nullptr};

◆ hc_timeF_scint_end

TH1F* hc_timeF_scint_end[2] = {nullptr}
private

EKLM part.

Definition at line 706 of file KLMTimeAlgorithm.h.

706{nullptr};

◆ hc_timeFS_rpc

TH1F* hc_timeFS_rpc[2][8] = {{nullptr}}
private

BKLM RPC part.

Definition at line 750 of file KLMTimeAlgorithm.h.

750{{nullptr}};

◆ hc_timeFS_scint

TH1F* hc_timeFS_scint[2][8] = {{nullptr}}
private

BKLM scintillator part.

Definition at line 753 of file KLMTimeAlgorithm.h.

753{{nullptr}};

◆ hc_timeFS_scint_end

TH1F* hc_timeFS_scint_end[2][4] = {{nullptr}}
private

EKLM part.

Definition at line 756 of file KLMTimeAlgorithm.h.

756{{nullptr}};

◆ hc_timeFSL

TH1F* hc_timeFSL[2][8][15] = {{{nullptr}}}
private

BKLM part.

Definition at line 791 of file KLMTimeAlgorithm.h.

791{{{nullptr}}};

◆ hc_timeFSL_end

TH1F* hc_timeFSL_end[2][4][14] = {{{nullptr}}}
private

EKLM part.

Definition at line 794 of file KLMTimeAlgorithm.h.

794{{{nullptr}}};

◆ hc_timeFSLP

TH1F* hc_timeFSLP[2][8][15][2] = {{{{nullptr}}}}
private

BKLM part.

Definition at line 807 of file KLMTimeAlgorithm.h.

807{{{{nullptr}}}};

◆ hc_timeFSLP_end

TH1F* hc_timeFSLP_end[2][4][14][2] = {{{{nullptr}}}}
private

EKLM part.

Definition at line 810 of file KLMTimeAlgorithm.h.

810{{{{nullptr}}}};

◆ m_allExpRun

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

allExpRun

Definition at line 364 of file CalibrationAlgorithm.h.

◆ m_applyChargeRestriction

bool m_applyChargeRestriction = false
private

Whether to apply ADC/charge restriction cuts for scintillators.

Definition at line 549 of file KLMTimeAlgorithm.h.

◆ m_BKLMGeometry

const bklm::GeometryPar* m_BKLMGeometry = nullptr
private

BKLM geometry data.

Definition at line 513 of file KLMTimeAlgorithm.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_cFlag

std::map<KLMChannelNumber, int> m_cFlag
private

Calibration flag if the channel has enough hits collected and fitted OK.

Definition at line 387 of file KLMTimeAlgorithm.h.

◆ m_channelHistDir_BKLM

TDirectory* m_channelHistDir_BKLM[2][8][15][2] = {}
private

Directory structure for per-channel histograms (BKLM).

Indexed as [forward/backward][sector][layer][plane].

Definition at line 951 of file KLMTimeAlgorithm.h.

951{};

◆ m_channelHistDir_EKLM

TDirectory* m_channelHistDir_EKLM[2][4][14][2] = {}
private

Directory structure for per-channel histograms (EKLM).

Indexed as [forward/backward][sector][layer][plane].

Definition at line 957 of file KLMTimeAlgorithm.h.

957{};

◆ m_ctime_channel

std::map<KLMChannelNumber, double> m_ctime_channel
private

Calibrated time distribution central value of each channel.

Definition at line 402 of file KLMTimeAlgorithm.h.

◆ m_ctime_channelAvg_rpc

double m_ctime_channelAvg_rpc = 0.0
private

Calibrated central value of the global time distribution (BKLM RPC part).

Definition at line 482 of file KLMTimeAlgorithm.h.

◆ m_ctime_channelAvg_scint

double m_ctime_channelAvg_scint = 0.0
private

Calibrated central value of the global time distribution (BKLM scintillator part).

Definition at line 489 of file KLMTimeAlgorithm.h.

◆ m_ctime_channelAvg_scint_end

double m_ctime_channelAvg_scint_end = 0.0
private

Calibrated central value of the global time distribution (EKLM scintillator part).

Definition at line 497 of file KLMTimeAlgorithm.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_debug

bool m_debug = false
private

Debug mode.

Definition at line 540 of file KLMTimeAlgorithm.h.

◆ m_description

std::string m_description {""}
privateinherited

Description of the algorithm.

Definition at line 385 of file CalibrationAlgorithm.h.

385{""};

◆ m_EKLMGeometry

const EKLM::GeometryData* m_EKLMGeometry = nullptr
private

EKLM geometry data.

Definition at line 516 of file KLMTimeAlgorithm.h.

◆ m_ElementNumbers

const KLMElementNumbers* m_ElementNumbers
private

Element numbers.

Definition at line 510 of file KLMTimeAlgorithm.h.

◆ m_etime_channel

std::map<KLMChannelNumber, double> m_etime_channel
private

Time distribution central value Error of each channel.

Definition at line 399 of file KLMTimeAlgorithm.h.

◆ m_etime_channelAvg_rpc

double m_etime_channelAvg_rpc = 0.0
private

Central value error of the global time distribution (BKLM RPC part).

Definition at line 463 of file KLMTimeAlgorithm.h.

◆ m_etime_channelAvg_scint

double m_etime_channelAvg_scint = 0.0
private

Central value error of the global time distribution (BKLM scintillator part).

Definition at line 471 of file KLMTimeAlgorithm.h.

◆ m_etime_channelAvg_scint_end

double m_etime_channelAvg_scint_end = 0.0
private

Central value error of the global time distribution (EKLM scintillator part).

Definition at line 479 of file KLMTimeAlgorithm.h.

◆ m_eventT0HitResolution

KLMEventT0HitResolution* m_eventT0HitResolution = nullptr
private

DBObject of per-hit time resolution for EventT0.

Definition at line 537 of file KLMTimeAlgorithm.h.

◆ m_evts

std::map<KLMChannelNumber, std::vector<struct Event> > m_evts
private

Container of hit information.

the global element number of the strip is used as the key.

Definition at line 381 of file KLMTimeAlgorithm.h.

◆ m_fixedRPCDelay

double m_fixedRPCDelay = 0.0667
private

Fixed propagation delay for RPCs (ns/cm).

Default value corresponds to c_eff = 0.5c = 15 cm/ns → delay = 0.0667 ns/cm. Used when m_useFixedRPCDelay is true.

Definition at line 445 of file KLMTimeAlgorithm.h.

◆ 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_klmChannels

KLMChannelIndex m_klmChannels
private

KLM ChannelIndex object.

Definition at line 519 of file KLMTimeAlgorithm.h.

◆ m_lower_limit_counts

int m_lower_limit_counts = 50
private

Lower limit of hits collected for on single channel.

Definition at line 507 of file KLMTimeAlgorithm.h.

◆ m_LowerTimeBoundaryCalibratedRPC

double m_LowerTimeBoundaryCalibratedRPC = -40.0
private

Lower time boundary for RPC (calibrated data).

Definition at line 426 of file KLMTimeAlgorithm.h.

◆ m_LowerTimeBoundaryCalibratedScintillatorsBKLM

double m_LowerTimeBoundaryCalibratedScintillatorsBKLM = -40.0
private

Lower time boundary for BKLM scintillators (calibrated data).

Definition at line 448 of file KLMTimeAlgorithm.h.

◆ m_LowerTimeBoundaryCalibratedScintillatorsEKLM

double m_LowerTimeBoundaryCalibratedScintillatorsEKLM = -40.0
private

Lower time boundary for EKLM scintillators (calibrated data).

Definition at line 454 of file KLMTimeAlgorithm.h.

◆ m_LowerTimeBoundaryRPC

double m_LowerTimeBoundaryRPC = -10.0
private

Lower time boundary for RPC.

Definition at line 408 of file KLMTimeAlgorithm.h.

◆ m_LowerTimeBoundaryScintillatorsBKLM

double m_LowerTimeBoundaryScintillatorsBKLM = 20.0
private

Lower time boundary for BKLM scintillators.

Definition at line 414 of file KLMTimeAlgorithm.h.

◆ m_LowerTimeBoundaryScintillatorsEKLM

double m_LowerTimeBoundaryScintillatorsEKLM = 20.0
private

Lower time boundary for EKLM scintillators.

Definition at line 420 of file KLMTimeAlgorithm.h.

◆ m_mc

bool m_mc = false
private

MC or data.

Definition at line 543 of file KLMTimeAlgorithm.h.

◆ m_MinimalDigitNumber

int m_MinimalDigitNumber = 100000000
private

Minimal digit number (total).

Definition at line 504 of file KLMTimeAlgorithm.h.

◆ m_minimizerOptions

ROOT::Math::MinimizerOptions m_minimizerOptions
private

Minimization options.

Definition at line 522 of file KLMTimeAlgorithm.h.

◆ m_outFile

TFile* m_outFile = nullptr
private

Output file.

Definition at line 939 of file KLMTimeAlgorithm.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_Profile2BKLMScintillatorPhi

TProfile* m_Profile2BKLMScintillatorPhi = nullptr
private

For BKLM scintillator phi plane.

Definition at line 633 of file KLMTimeAlgorithm.h.

◆ m_Profile2BKLMScintillatorZ

TProfile* m_Profile2BKLMScintillatorZ = nullptr
private

For BKLM scintillator z plane.

Definition at line 636 of file KLMTimeAlgorithm.h.

◆ m_Profile2EKLMScintillatorPlane1

TProfile* m_Profile2EKLMScintillatorPlane1 = nullptr
private

For EKLM scintillator plane1.

Definition at line 639 of file KLMTimeAlgorithm.h.

◆ m_Profile2EKLMScintillatorPlane2

TProfile* m_Profile2EKLMScintillatorPlane2 = nullptr
private

For EKLM scintillator plane2.

Definition at line 642 of file KLMTimeAlgorithm.h.

◆ m_Profile2RpcPhi

TProfile* m_Profile2RpcPhi = nullptr
private

For BKLM RPC phi plane.

Definition at line 627 of file KLMTimeAlgorithm.h.

◆ m_Profile2RpcZ

TProfile* m_Profile2RpcZ = nullptr
private

For BKLM RPC z plane.

Definition at line 630 of file KLMTimeAlgorithm.h.

◆ m_ProfileBKLMScintillatorPhi

TProfile* m_ProfileBKLMScintillatorPhi = nullptr
private

For BKLM scintillator phi plane.

Definition at line 613 of file KLMTimeAlgorithm.h.

◆ m_ProfileBKLMScintillatorZ

TProfile* m_ProfileBKLMScintillatorZ = nullptr
private

For BKLM scintillator z plane.

Definition at line 616 of file KLMTimeAlgorithm.h.

◆ m_ProfileEKLMScintillatorPlane1

TProfile* m_ProfileEKLMScintillatorPlane1 = nullptr
private

For EKLM scintillator plane1.

Definition at line 619 of file KLMTimeAlgorithm.h.

◆ m_ProfileEKLMScintillatorPlane2

TProfile* m_ProfileEKLMScintillatorPlane2 = nullptr
private

For EKLM scintillator plane2.

Definition at line 622 of file KLMTimeAlgorithm.h.

◆ m_ProfileRpcPhi

TProfile* m_ProfileRpcPhi = nullptr
private

For BKLM RPC phi plane.

Definition at line 607 of file KLMTimeAlgorithm.h.

◆ m_ProfileRpcZ

TProfile* m_ProfileRpcZ = nullptr
private

For BKLM RPC z plane.

Definition at line 610 of file KLMTimeAlgorithm.h.

◆ 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.

◆ m_saveAllPlots

bool m_saveAllPlots = false
private

Default minimal unless you set true in your header script.

Definition at line 942 of file KLMTimeAlgorithm.h.

◆ m_saveChannelHists

bool m_saveChannelHists = false
private

Write per-channel temporary histograms (tc/raw/hc) in minimal mode.

Definition at line 945 of file KLMTimeAlgorithm.h.

◆ m_time_channel

std::map<KLMChannelNumber, double> m_time_channel
private

Time distribution central value of each channel.

Definition at line 396 of file KLMTimeAlgorithm.h.

◆ m_time_channelAvg_rpc

double m_time_channelAvg_rpc = 0.0
private

Central value of the global time distribution (BKLM RPC part).

Definition at line 460 of file KLMTimeAlgorithm.h.

◆ m_time_channelAvg_scint

double m_time_channelAvg_scint = 0.0
private

Central value of the global time distribution (BKLM scintillator part).

Definition at line 467 of file KLMTimeAlgorithm.h.

◆ m_time_channelAvg_scint_end

double m_time_channelAvg_scint_end = 0.0
private

Central value of the global time distribution (EKLM scintillator part).

Definition at line 475 of file KLMTimeAlgorithm.h.

◆ m_timeCableDelay

KLMTimeCableDelay* m_timeCableDelay = nullptr
private

DBObject of the calibration constant of each channel due to cable decay.

Definition at line 531 of file KLMTimeAlgorithm.h.

◆ m_timeConstants

KLMTimeConstants* m_timeConstants = nullptr
private

DBObject of time cost on some parts of the detector.

Definition at line 525 of file KLMTimeAlgorithm.h.

◆ m_timeRes

std::map<KLMChannelNumber, double> m_timeRes
private

Resolution values of each channel.

Definition at line 393 of file KLMTimeAlgorithm.h.

◆ m_timeResolution

KLMTimeResolution* m_timeResolution = nullptr
private

DBObject of time resolution.

Definition at line 534 of file KLMTimeAlgorithm.h.

◆ m_timeShift

std::map<KLMChannelNumber, double> m_timeShift
private

Shift values of each channel.

Definition at line 390 of file KLMTimeAlgorithm.h.

◆ m_UpperTimeBoundaryCalibratedRPC

double m_UpperTimeBoundaryCalibratedRPC = 40.0
private

Upper time boundary for RPC (calibrated data).

Definition at line 429 of file KLMTimeAlgorithm.h.

◆ m_UpperTimeBoundaryCalibratedScintillatorsBKLM

double m_UpperTimeBoundaryCalibratedScintillatorsBKLM = 40.0
private

Upper time boundary for BKLM scintillators (calibrated data).

Definition at line 451 of file KLMTimeAlgorithm.h.

◆ m_UpperTimeBoundaryCalibratedScintillatorsEKLM

double m_UpperTimeBoundaryCalibratedScintillatorsEKLM = 40.0
private

Upper time boundary for BKLM scintillators (calibrated data).

Definition at line 457 of file KLMTimeAlgorithm.h.

◆ m_UpperTimeBoundaryRPC

double m_UpperTimeBoundaryRPC = 10.0
private

Upper time boundary for RPC.

Definition at line 411 of file KLMTimeAlgorithm.h.

◆ m_UpperTimeBoundaryScintillatorsBKLM

double m_UpperTimeBoundaryScintillatorsBKLM = 70.0
private

Upper time boundary for BKLM scintillators.

Definition at line 417 of file KLMTimeAlgorithm.h.

◆ m_UpperTimeBoundaryScintillatorsEKLM

double m_UpperTimeBoundaryScintillatorsEKLM = 70.0
private

Upper time boundary for BKLM scintillators.

Definition at line 423 of file KLMTimeAlgorithm.h.

◆ m_useEventT0

bool m_useEventT0 = true
private

Whether to use event T0 from CDC.

Definition at line 546 of file KLMTimeAlgorithm.h.

◆ m_useFixedRPCDelay

bool m_useFixedRPCDelay = false
private

Whether to use fixed propagation delay for RPCs.

Technical note BELLE2-NOTE-TE-2021-015 states that c_eff estimation for RPC is "meaningless" and should be fixed at 0.5c. Default is false to allow extraction from data (now that the propagation distance calculation is fixed for RPCs).

Definition at line 438 of file KLMTimeAlgorithm.h.

◆ mc_etime_channel

std::map<KLMChannelNumber, double> mc_etime_channel
private

Calibrated time distribution central value Error of each channel.

Definition at line 405 of file KLMTimeAlgorithm.h.

◆ mc_etime_channelAvg_rpc

double mc_etime_channelAvg_rpc = 0.0
private

Calibrated central value error of the global time distribution (BKLM RPC part).

Definition at line 485 of file KLMTimeAlgorithm.h.

◆ mc_etime_channelAvg_scint

double mc_etime_channelAvg_scint = 0.0
private

Calibrated central value error of the global time distribution (BKLM scintillator part).

Definition at line 493 of file KLMTimeAlgorithm.h.

◆ mc_etime_channelAvg_scint_end

double mc_etime_channelAvg_scint_end = 0.0
private

Calibrated central value error of the global time distribution (EKLM scintillator part).

Definition at line 501 of file KLMTimeAlgorithm.h.

◆ prof_deltaT0_rms_vs_v_rpc

TProfile* prof_deltaT0_rms_vs_v_rpc = nullptr
private

DeltaT0 RMS vs inverse hit count profile for RPC.

Definition at line 880 of file KLMTimeAlgorithm.h.

◆ prof_deltaT0_rms_vs_v_scint

TProfile* prof_deltaT0_rms_vs_v_scint = nullptr
private

DeltaT0 RMS vs inverse hit count profile for BKLM scintillator.

Definition at line 883 of file KLMTimeAlgorithm.h.

◆ prof_deltaT0_rms_vs_v_scint_end

TProfile* prof_deltaT0_rms_vs_v_scint_end = nullptr
private

DeltaT0 RMS vs inverse hit count profile for EKLM scintillator.

Definition at line 886 of file KLMTimeAlgorithm.h.


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