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 ()
 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
 Number of RPC hits per mu+ track.
 
TH1F * h_nHits_minus_rpc
 Number of RPC hits per mu- track.
 
TH1F * h_nHits_plus_scint
 Number of BKLM scintillator hits per mu+ track.
 
TH1F * h_nHits_minus_scint
 Number of BKLM scintillator hits per mu- track.
 
TH1F * h_nHits_plus_scint_end
 Number of EKLM scintillator hits per mu+ track.
 
TH1F * h_nHits_minus_scint_end
 Number of EKLM scintillator hits per mu- track.
 
TH2F * h2_deltaT0_vs_v_rpc
 DeltaT0 vs inverse hit count for RPC.
 
TH2F * h2_deltaT0_vs_v_scint
 DeltaT0 vs inverse hit count for BKLM scintillator.
 
TH2F * h2_deltaT0_vs_v_scint_end
 DeltaT0 vs inverse hit count for EKLM scintillator.
 
TProfile * prof_deltaT0_rms_vs_v_rpc
 DeltaT0 RMS vs inverse hit count profile for RPC.
 
TProfile * prof_deltaT0_rms_vs_v_scint
 DeltaT0 RMS vs inverse hit count profile for BKLM scintillator.
 
TProfile * prof_deltaT0_rms_vs_v_scint_end
 DeltaT0 RMS vs inverse hit count profile for EKLM scintillator.
 
TH2F * h2_deltaT0_vs_nhits_rpc
 DeltaT0 vs total hit count for RPC.
 
TH2F * h2_deltaT0_vs_nhits_scint
 DeltaT0 vs total hit count for BKLM scintillator.
 
TH2F * h2_deltaT0_vs_nhits_scint_end
 DeltaT0 vs total hit count for EKLM scintillator.
 
TH1F * hc_eventT0_rpc_lowN
 Corrected EventT0 for RPC with low hit count.
 
TH1F * hc_eventT0_rpc_midN
 Corrected EventT0 for RPC with medium hit count.
 
TH1F * hc_eventT0_rpc_highN
 Corrected EventT0 for RPC with high hit count.
 
TH1F * hc_eventT0_scint_lowN
 Corrected EventT0 for BKLM scintillator with low hit count.
 
TH1F * hc_eventT0_scint_midN
 Corrected EventT0 for BKLM scintillator with medium hit count.
 
TH1F * hc_eventT0_scint_highN
 Corrected EventT0 for BKLM scintillator with high hit count.
 
TH1F * hc_eventT0_scint_end_lowN
 Corrected EventT0 for EKLM scintillator with low hit count.
 
TH1F * hc_eventT0_scint_end_midN
 Corrected EventT0 for EKLM scintillator with medium hit count.
 
TH1F * hc_eventT0_scint_end_highN
 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 98 of file KLMTimeAlgorithm.cc.

98 :
99 CalibrationAlgorithm("KLMTimeCollector")
100{
102 m_minimizerOptions = ROOT::Math::MinimizerOptions();
103}
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()

Destructor.

Definition at line 105 of file KLMTimeAlgorithm.cc.

106{
107}

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 1119 of file KLMTimeAlgorithm.cc.

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

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

2713{
2714 double tR = 0.0;
2715 int iSub = klmChannel.getSubdetector();
2716 int iF = klmChannel.getSection();
2717 int iS = klmChannel.getSector();
2718 int iL = klmChannel.getLayer();
2719 int iP = klmChannel.getPlane();
2720 int iC = klmChannel.getStrip();
2722 if (iSub == KLMElementNumbers::c_BKLM)
2723 totNStrips = BKLMElementNumbers::getNStrips(iF, iS, iL, iP);
2724 if (iC == 1) {
2725 KLMChannelIndex kCIndex_upper(iSub, iF, iS, iL, iP, iC + 1);
2726 tR = tR_upperStrip(kCIndex_upper).second;
2727 } else if (iC == totNStrips) {
2728 KLMChannelIndex kCIndex_lower(iSub, iF, iS, iL, iP, iC - 1);
2729 tR = tR_lowerStrip(kCIndex_lower).second;
2730 } else {
2731 KLMChannelIndex kCIndex_upper(iSub, iF, iS, iL, iP, iC + 1);
2732 KLMChannelIndex kCIndex_lower(iSub, iF, iS, iL, iP, iC - 1);
2733 std::pair<int, double> tR_upper = tR_upperStrip(kCIndex_upper);
2734 std::pair<int, double> tR_lower = tR_lowerStrip(kCIndex_lower);
2735 unsigned int tr_upper = tR_upper.first - iC;
2736 unsigned int tr_lower = iC - tR_lower.first;
2737 unsigned int tr = tR_upper.first - tR_lower.first;
2738 tR = (double(tr_upper) * tR_lower.second + double(tr_lower) * tR_upper.second) / double(tr);
2739 }
2740 return tR;
2741}
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 2632 of file KLMTimeAlgorithm.cc.

2633{
2634 double tS = 0.0;
2635 int iSub = klmChannel.getSubdetector();
2636 int iF = klmChannel.getSection();
2637 int iS = klmChannel.getSector();
2638 int iL = klmChannel.getLayer();
2639 int iP = klmChannel.getPlane();
2640 int iC = klmChannel.getStrip();
2642 if (iSub == KLMElementNumbers::c_BKLM)
2643 totNStrips = BKLMElementNumbers::getNStrips(iF, iS, iL, iP);
2644 if (iC == 1) {
2645 KLMChannelIndex kCIndex_upper(iSub, iF, iS, iL, iP, iC + 1);
2646 tS = tS_upperStrip(kCIndex_upper).second;
2647 } else if (iC == totNStrips) {
2648 KLMChannelIndex kCIndex_lower(iSub, iF, iS, iL, iP, iC - 1);
2649 tS = tS_lowerStrip(kCIndex_lower).second;
2650 } else {
2651 KLMChannelIndex kCIndex_upper(iSub, iF, iS, iL, iP, iC + 1);
2652 KLMChannelIndex kCIndex_lower(iSub, iF, iS, iL, iP, iC - 1);
2653 std::pair<int, double> tS_upper = tS_upperStrip(kCIndex_upper);
2654 std::pair<int, double> tS_lower = tS_lowerStrip(kCIndex_lower);
2655 unsigned int td_upper = tS_upper.first - iC;
2656 unsigned int td_lower = iC - tS_lower.first;
2657 unsigned int td = tS_upper.first - tS_lower.first;
2658 tS = (double(td_upper) * tS_lower.second + double(td_lower) * tS_upper.second) / double(td);
2659 }
2660 return tS;
2661}
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 767 of file KLMTimeAlgorithm.cc.

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

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

◆ 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 147 of file KLMTimeAlgorithm.cc.

148{
149 B2INFO("Read tree entries (initial data check only).");
150 std::shared_ptr<TTree> timeCalibrationData;
151 timeCalibrationData = getObjectPtr<TTree>("time_calibration_data");
152
153 int n = timeCalibrationData->GetEntries();
154 B2INFO(LogVar("Total number of digits:", n));
155
156 if (n < m_MinimalDigitNumber)
158
160}
@ 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 238 of file KLMTimeAlgorithm.cc.

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

◆ 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 162 of file KLMTimeAlgorithm.cc.

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

◆ 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 181 of file KLMTimeAlgorithm.cc.

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

◆ 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 2408 of file KLMTimeAlgorithm.cc.

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

◆ 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 109 of file KLMTimeAlgorithm.cc.

110{
111 const std::vector<Calibration::ExpRun>& runs = getRunList();
112 int firstExperiment = runs[0].first;
113 int lastExperiment = runs[runs.size() - 1].first;
114 if (firstExperiment != lastExperiment) {
115 B2FATAL("Runs from different experiments are used "
116 "for KLM time calibration (single algorithm run).");
117 }
118 /* DataStore. */
120 StoreObjPtr<EventMetaData> eventMetaData;
121 eventMetaData.registerInDataStore();
123 /* Database. */
124 if (eventMetaData.isValid()) {
125 if (eventMetaData->getExperiment() != firstExperiment) {
126 B2FATAL("Runs from different experiments are used "
127 "for KLM time calibration (consecutive algorithm runs).");
128 }
129 eventMetaData->setExperiment(firstExperiment);
130 eventMetaData->setRun(runs[0].second);
131 } else {
132 eventMetaData.construct(1, runs[0].second, firstExperiment);
133 }
134 DBStore& dbStore = DBStore::Instance();
135 dbStore.update();
136 dbStore.updateEvent();
137 /*
138 * For calibration algorithms, the database is not initialized on class
139 * creation. Do not move the database object to class members.
140 */
141 DBObjPtr<BKLMGeometryPar> bklmGeometry;
144}
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 972 of file KLMTimeAlgorithm.cc.

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

2770{
2771 std::pair<int, double> tR;
2772 int cId = klmChannel.getKLMChannelNumber();
2773 int iSub = klmChannel.getSubdetector();
2774 int iF = klmChannel.getSection();
2775 int iS = klmChannel.getSector();
2776 int iL = klmChannel.getLayer();
2777 int iP = klmChannel.getPlane();
2778 int iC = klmChannel.getStrip();
2779 if (m_timeRes.find(cId) != m_timeRes.end()) {
2780 tR.first = iC;
2781 tR.second = m_timeRes[cId];
2782 } else if (iC == 1) {
2783 tR.first = iC;
2784 tR.second = 0.0;
2785 } else {
2786 KLMChannelIndex kCIndex(iSub, iF, iS, iL, iP, iC - 1);
2787 tR = tR_lowerStrip(kCIndex);
2788 }
2789 return tR;
2790}
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 2743 of file KLMTimeAlgorithm.cc.

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

◆ 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 2689 of file KLMTimeAlgorithm.cc.

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

◆ 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 2663 of file KLMTimeAlgorithm.cc.

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

◆ 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 1060 of file KLMTimeAlgorithm.cc.

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

◆ writeThenDelete_() [2/2]

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

Same as above, but for 2D histograms.

Definition at line 1079 of file KLMTimeAlgorithm.cc.

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

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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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: