Belle II Software development
KLMTimeAlgorithm Class Reference

KLM time calibration algorithm. More...

#include <KLMTimeAlgorithm.h>

Inheritance diagram for KLMTimeAlgorithm:
CalibrationAlgorithm

Classes

struct  Event
 Event data. More...
 

Public Types

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

Public Member Functions

 KLMTimeAlgorithm ()
 Constructor.
 
 ~KLMTimeAlgorithm () override
 Destructor.
 
void setDebug ()
 Turn on debug mode (prints histograms and output running log).
 
void setMC (bool mc)
 Set flag indicating whether the input is MC sample.
 
void useEvtT0 ()
 Use event T0 as the initial time point or not.
 
void setMinimalDigitNumber (int minimalDigitNumber)
 Set minimal digit number (total).
 
void setLowerLimit (int counts)
 Set the lower number of hits collected on one single strip.
 
void setApplyChargeRestriction (bool apply)
 Enable or disable ADC/charge restriction cuts for scintillators.
 
void setSaveAllPlots (bool on)
 Save every preallocated debug histogram family (sectors/layers/planes/2D maps).
 
void setSaveChannelHists (bool on)
 When running in minimal mode, also write the per-channel temporary histograms (the vital tc, raw, hc 1D’s created on-the-fly) before deleting them.
 
void saveHist ()
 Save histograms to file.
 
double esti_timeShift (const KLMChannelIndex &klmChannel)
 Estimate value of calibration constant for uncalibrated channels.
 
std::pair< int, double > tS_upperStrip (const KLMChannelIndex &klmChannel)
 Tracing available channels with increasing strip number.
 
std::pair< int, double > tS_lowerStrip (const KLMChannelIndex &klmChannel)
 Tracing available channels with decreasing strip number.
 
double esti_timeRes (const KLMChannelIndex &klmChannel)
 Estimate value of calibration constant for calibrated channels.
 
std::pair< int, double > tR_upperStrip (const KLMChannelIndex &klmChannel)
 Tracing available channels with increasing strip number.
 
std::pair< int, double > tR_lowerStrip (const KLMChannelIndex &klmChannel)
 Tracing available channels with decreasing strip number.
 
const std::string & getPrefix () const
 Get the prefix used for getting calibration data.
 
const std::string & getCollectorName () const
 Alias for prefix.
 
void setPrefix (const std::string &prefix)
 Set the prefix used to identify datastore objects.
 
void setInputFileNames (PyObject *inputFileNames)
 Set the input file names used for this algorithm from a Python list.
 
PyObject * getInputFileNames ()
 Get the input file names used for this algorithm and pass them out as a Python list of unicode strings.
 
std::vector< Calibration::ExpRun > getRunListFromAllData () const
 Get the complete list of runs from inspection of collected data.
 
RunRange getRunRangeFromAllData () const
 Get the complete RunRange from inspection of collected data.
 
IntervalOfValidity getIovFromAllData () const
 Get the complete IoV from inspection of collected data.
 
void fillRunToInputFilesMap ()
 Fill the mapping of ExpRun -> Files.
 
const std::string & getGranularity () const
 Get the granularity of collected data.
 
EResult execute (std::vector< Calibration::ExpRun > runs={}, int iteration=0, IntervalOfValidity iov=IntervalOfValidity())
 Runs calibration over vector of runs for a given iteration.
 
EResult execute (PyObject *runs, int iteration=0, IntervalOfValidity iov=IntervalOfValidity())
 Runs calibration over Python list of runs. Converts to C++ and then calls the other execute() function.
 
std::list< Database::DBImportQuery > & getPayloads ()
 Get constants (in TObjects) for database update from last execution.
 
std::list< Database::DBImportQuery > getPayloadValues () 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 KLMElementNumbers * m_ElementNumbers
 Element numbers.
 
const bklm::GeometryPar * m_BKLMGeometry = nullptr
 BKLM geometry data.
 
const EKLM::GeometryData * m_EKLMGeometry = nullptr
 EKLM geometry data.
 
KLMChannelIndex m_klmChannels
 KLM ChannelIndex object.
 
ROOT::Math::MinimizerOptions m_minimizerOptions
 Minimization options.
 
KLMTimeConstants * m_timeConstants = nullptr
 DBObject of time cost on some parts of the detector.
 
KLMTimeCableDelay * m_timeCableDelay = nullptr
 DBObject of the calibration constant of each channel due to cable decay.
 
KLMTimeResolution * m_timeResolution = nullptr
 DBObject of time resolution.
 
KLMEventT0HitResolution * m_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 = true
 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_z_bklm_scint = nullptr
 Normalised di-muon time difference z = dT0 / sqrt(1/N+ + 1/N-).
 
TH1F * h_z_bklm_rpc_phi = nullptr
 Normalised di-muon time difference, BKLM RPC phi readout.
 
TH1F * h_z_bklm_rpc_z = nullptr
 Normalised di-muon time difference, BKLM RPC z readout.
 
TH1F * h_z_bklm_rpc = nullptr
 Normalised di-muon time difference, BKLM RPC, phi and z readouts together.
 
TH1F * h_z_eklm_scint = nullptr
 Normalised di-muon time difference, EKLM scintillator.
 
TH1F * h_nHits_plus_rpc = nullptr
 Number of RPC hits per mu+ track.
 
TH1F * h_nHits_minus_rpc = nullptr
 Number of RPC hits per mu- track.
 
TH1F * h_nHits_plus_scint = nullptr
 Number of BKLM scintillator hits per mu+ track.
 
TH1F * h_nHits_minus_scint = nullptr
 Number of BKLM scintillator hits per mu- track.
 
TH1F * h_nHits_plus_scint_end = nullptr
 Number of EKLM scintillator hits per mu+ track.
 
TH1F * h_nHits_minus_scint_end = nullptr
 Number of EKLM scintillator hits per mu- track.
 
TH2F * h2_deltaT0_vs_v_rpc = nullptr
 DeltaT0 vs inverse hit count for RPC.
 
TH2F * h2_deltaT0_vs_v_scint = nullptr
 DeltaT0 vs inverse hit count for BKLM scintillator.
 
TH2F * h2_deltaT0_vs_v_scint_end = nullptr
 DeltaT0 vs inverse hit count for EKLM scintillator.
 
TProfile * prof_deltaT0_rms_vs_v_rpc = nullptr
 DeltaT0 RMS vs inverse hit count profile for RPC.
 
TProfile * prof_deltaT0_rms_vs_v_scint = nullptr
 DeltaT0 RMS vs inverse hit count profile for BKLM scintillator.
 
TProfile * prof_deltaT0_rms_vs_v_scint_end = nullptr
 DeltaT0 RMS vs inverse hit count profile for EKLM scintillator.
 
TH2F * h2_deltaT0_vs_nhits_rpc = nullptr
 DeltaT0 vs total hit count for RPC.
 
TH2F * h2_deltaT0_vs_nhits_scint = nullptr
 DeltaT0 vs total hit count for BKLM scintillator.
 
TH2F * h2_deltaT0_vs_nhits_scint_end = nullptr
 DeltaT0 vs total hit count for EKLM scintillator.
 
TH1F * hc_eventT0_rpc_lowN = nullptr
 Corrected EventT0 for RPC with low hit count.
 
TH1F * hc_eventT0_rpc_midN = nullptr
 Corrected EventT0 for RPC with medium hit count.
 
TH1F * hc_eventT0_rpc_highN = nullptr
 Corrected EventT0 for RPC with high hit count.
 
TH1F * hc_eventT0_scint_lowN = nullptr
 Corrected EventT0 for BKLM scintillator with low hit count.
 
TH1F * hc_eventT0_scint_midN = nullptr
 Corrected EventT0 for BKLM scintillator with medium hit count.
 
TH1F * hc_eventT0_scint_highN = nullptr
 Corrected EventT0 for BKLM scintillator with high hit count.
 
TH1F * hc_eventT0_scint_end_lowN = nullptr
 Corrected EventT0 for EKLM scintillator with low hit count.
 
TH1F * hc_eventT0_scint_end_midN = nullptr
 Corrected EventT0 for EKLM scintillator with medium hit count.
 
TH1F * hc_eventT0_scint_end_highN = nullptr
 Corrected EventT0 for EKLM scintillator with high hit count.
 
TF1 * fcn_pol1 = nullptr
 Pol1 function.
 
TF1 * fcn_const = nullptr
 Const function.
 
TF1 * fcn_gaus = nullptr
 Gaussian function.
 
TF1 * fcn_land = nullptr
 Landau function.
 
TFile * m_outFile = nullptr
 Output file.
 
bool m_saveAllPlots = false
 Default minimal unless you set true in your header script.
 
bool m_saveChannelHists = false
 Write per-channel temporary histograms (tc/raw/hc) in minimal mode.
 
TDirectory * m_channelHistDir_BKLM [2][8][15][2] = {}
 Directory structure for per-channel histograms (BKLM).
 
TDirectory * m_channelHistDir_EKLM [2][4][14][2] = {}
 Directory structure for per-channel histograms (EKLM).
 
std::vector< std::string > m_inputFileNames
 List of input files to the Algorithm, will initially be user defined but then gets the wildcards expanded during execute()
 
std::map< Calibration::ExpRun, std::vector< std::string > > m_runsToInputFiles
 Map of Runs to input files. Gets filled when you call getRunRangeFromAllData, gets cleared when setting input files again.
 
std::string m_granularityOfData
 Granularity of input data. This only changes when the input files change so it isn't specific to an execution.
 
ExecutionData m_data
 Data specific to a SINGLE execution of the algorithm. Gets reset at the beginning of execution.
 
std::string m_description {""}
 Description of the algorithm.
 
std::string m_prefix {""}
 The name of the TDirectory the collector objects are contained within.
 
nlohmann::json m_jsonExecutionInput = nlohmann::json::object()
 Optional input JSON object used to make decisions about how to execute the algorithm code.
 
nlohmann::json m_jsonExecutionOutput = nlohmann::json::object()
 Optional output JSON object that can be set during the execution by the underlying algorithm code.
 

Static Private Attributes

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

Detailed Description

KLM time calibration algorithm.

Definition at line 50 of file KLMTimeAlgorithm.h.

Member Enumeration Documentation

◆ ChannelCalibrationStatus

Channel calibration status.

Definition at line 129 of file KLMTimeAlgorithm.h.

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

◆ EResult

enum EResult
inherited

The result of calibration.

Enumerator
c_OK 

Finished successfully =0 in Python.

c_Iterate 

Needs iteration =1 in Python.

c_NotEnoughData 

Needs more data =2 in Python.

c_Failure 

Failed =3 in Python.

c_Undefined 

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

Definition at line 40 of file CalibrationAlgorithm.h.

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

Constructor & Destructor Documentation

◆ KLMTimeAlgorithm()

Constructor.

Definition at line 101 of file KLMTimeAlgorithm.cc.

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

◆ ~KLMTimeAlgorithm()

~KLMTimeAlgorithm ( )
override

Destructor.

Definition at line 108 of file KLMTimeAlgorithm.cc.

109{
110}

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

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

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

2822{
2823 double tR = 0.0;
2824 int iSub = klmChannel.getSubdetector();
2825 int iF = klmChannel.getSection();
2826 int iS = klmChannel.getSector();
2827 int iL = klmChannel.getLayer();
2828 int iP = klmChannel.getPlane();
2829 int iC = klmChannel.getStrip();
2831 if (iSub == KLMElementNumbers::c_BKLM)
2832 totNStrips = BKLMElementNumbers::getNStrips(iF, iS, iL, iP);
2833 if (iC == 1) {
2834 KLMChannelIndex kCIndex_upper(iSub, iF, iS, iL, iP, iC + 1);
2835 tR = tR_upperStrip(kCIndex_upper).second;
2836 } else if (iC == totNStrips) {
2837 KLMChannelIndex kCIndex_lower(iSub, iF, iS, iL, iP, iC - 1);
2838 tR = tR_lowerStrip(kCIndex_lower).second;
2839 } else {
2840 KLMChannelIndex kCIndex_upper(iSub, iF, iS, iL, iP, iC + 1);
2841 KLMChannelIndex kCIndex_lower(iSub, iF, iS, iL, iP, iC - 1);
2842 std::pair<int, double> tR_upper = tR_upperStrip(kCIndex_upper);
2843 std::pair<int, double> tR_lower = tR_lowerStrip(kCIndex_lower);
2844 unsigned int tr_upper = tR_upper.first - iC;
2845 unsigned int tr_lower = iC - tR_lower.first;
2846 unsigned int tr = tR_upper.first - tR_lower.first;
2847 tR = (double(tr_upper) * tR_lower.second + double(tr_lower) * tR_upper.second) / double(tr);
2848 }
2849 return tR;
2850}
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 2741 of file KLMTimeAlgorithm.cc.

2742{
2743 double tS = 0.0;
2744 int iSub = klmChannel.getSubdetector();
2745 int iF = klmChannel.getSection();
2746 int iS = klmChannel.getSector();
2747 int iL = klmChannel.getLayer();
2748 int iP = klmChannel.getPlane();
2749 int iC = klmChannel.getStrip();
2751 if (iSub == KLMElementNumbers::c_BKLM)
2752 totNStrips = BKLMElementNumbers::getNStrips(iF, iS, iL, iP);
2753 if (iC == 1) {
2754 KLMChannelIndex kCIndex_upper(iSub, iF, iS, iL, iP, iC + 1);
2755 tS = tS_upperStrip(kCIndex_upper).second;
2756 } else if (iC == totNStrips) {
2757 KLMChannelIndex kCIndex_lower(iSub, iF, iS, iL, iP, iC - 1);
2758 tS = tS_lowerStrip(kCIndex_lower).second;
2759 } else {
2760 KLMChannelIndex kCIndex_upper(iSub, iF, iS, iL, iP, iC + 1);
2761 KLMChannelIndex kCIndex_lower(iSub, iF, iS, iL, iP, iC - 1);
2762 std::pair<int, double> tS_upper = tS_upperStrip(kCIndex_upper);
2763 std::pair<int, double> tS_lower = tS_lowerStrip(kCIndex_lower);
2764 unsigned int td_upper = tS_upper.first - iC;
2765 unsigned int td_lower = iC - tS_lower.first;
2766 unsigned int td = tS_upper.first - tS_lower.first;
2767 tS = (double(td_upper) * tS_lower.second + double(td_lower) * tS_upper.second) / double(td);
2768 }
2769 return tS;
2770}
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 783 of file KLMTimeAlgorithm.cc.

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

1114{
1115 // If charge restriction is disabled, accept all hits
1117 return true;
1118 }
1119
1120 uint16_t charge = event.getADCcount;
1121
1122 if (subdetector == KLMElementNumbers::c_BKLM) {
1123 // FIXED: Use constant for RPC check (0-indexed comparison)
1124 if (layer_0indexed >= (BKLMElementNumbers::c_FirstRPCLayer - 1)) {
1125 return true; // RPC - no ADC cut
1126 } else {
1127 return (charge > 30 && charge < 320); // Scintillator
1128 }
1129 } else {
1130 return (charge > 40 && charge < 350); // EKLM
1131 }
1132}

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

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

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

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

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

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

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

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

2513{
2514 m_outFile->cd();
2515 B2INFO("Save Histograms into Files.");
2516
2517 /* Save vital plots. */
2518 TDirectory* dir_monitor = m_outFile->mkdir("monitor_Hists", "", true);
2519 dir_monitor->cd();
2520 h_calibrated->SetDirectory(dir_monitor);
2521 hc_calibrated->SetDirectory(dir_monitor);
2522 h_diff->SetDirectory(dir_monitor);
2523
2524 m_outFile->cd();
2525 TDirectory* dir_eventT0 = m_outFile->mkdir("EventT0", "", true);
2526 dir_eventT0->cd();
2527
2528 // Original histograms
2529 h_eventT0_rpc->SetDirectory(dir_eventT0);
2530 h_eventT0_scint->SetDirectory(dir_eventT0);
2531 h_eventT0_scint_end->SetDirectory(dir_eventT0);
2532
2533 hc_eventT0_rpc->SetDirectory(dir_eventT0);
2534 hc_eventT0_scint->SetDirectory(dir_eventT0);
2535 h_z_bklm_scint->SetDirectory(dir_eventT0);
2536 h_z_bklm_rpc_phi->SetDirectory(dir_eventT0);
2537 h_z_bklm_rpc_z->SetDirectory(dir_eventT0);
2538 h_z_bklm_rpc->SetDirectory(dir_eventT0);
2539 h_z_eklm_scint->SetDirectory(dir_eventT0);
2540 hc_eventT0_scint_end->SetDirectory(dir_eventT0);
2541
2542 // ==== NEW DIAGNOSTIC PLOTS ====
2543
2544 // Hit multiplicity
2545 h_nHits_plus_rpc->SetDirectory(dir_eventT0);
2546 h_nHits_minus_rpc->SetDirectory(dir_eventT0);
2547 h_nHits_plus_scint->SetDirectory(dir_eventT0);
2548 h_nHits_minus_scint->SetDirectory(dir_eventT0);
2549 h_nHits_plus_scint_end->SetDirectory(dir_eventT0);
2550 h_nHits_minus_scint_end->SetDirectory(dir_eventT0);
2551
2552 // ΔT0 vs v
2553 h2_deltaT0_vs_v_rpc->SetDirectory(dir_eventT0);
2554 h2_deltaT0_vs_v_scint->SetDirectory(dir_eventT0);
2555 h2_deltaT0_vs_v_scint_end->SetDirectory(dir_eventT0);
2556
2557 // Profile plots
2558 prof_deltaT0_rms_vs_v_rpc->SetDirectory(dir_eventT0);
2559 prof_deltaT0_rms_vs_v_scint->SetDirectory(dir_eventT0);
2560 prof_deltaT0_rms_vs_v_scint_end->SetDirectory(dir_eventT0);
2561
2562 // ΔT0 vs total hits
2563 h2_deltaT0_vs_nhits_rpc->SetDirectory(dir_eventT0);
2564 h2_deltaT0_vs_nhits_scint->SetDirectory(dir_eventT0);
2565 h2_deltaT0_vs_nhits_scint_end->SetDirectory(dir_eventT0);
2566
2567 // Multiplicity-binned ΔT0
2568 hc_eventT0_rpc_lowN->SetDirectory(dir_eventT0);
2569 hc_eventT0_rpc_midN->SetDirectory(dir_eventT0);
2570 hc_eventT0_rpc_highN->SetDirectory(dir_eventT0);
2571 hc_eventT0_scint_lowN->SetDirectory(dir_eventT0);
2572 hc_eventT0_scint_midN->SetDirectory(dir_eventT0);
2573 hc_eventT0_scint_highN->SetDirectory(dir_eventT0);
2574 hc_eventT0_scint_end_lowN->SetDirectory(dir_eventT0);
2575 hc_eventT0_scint_end_midN->SetDirectory(dir_eventT0);
2576 hc_eventT0_scint_end_highN->SetDirectory(dir_eventT0);
2577
2578 m_outFile->cd();
2579 TDirectory* dir_effC = m_outFile->mkdir("effC_Hists", "", true);
2580 dir_effC->cd();
2581 m_ProfileRpcPhi->SetDirectory(dir_effC);
2582 m_ProfileRpcZ->SetDirectory(dir_effC);
2583 m_ProfileBKLMScintillatorPhi->SetDirectory(dir_effC);
2584 m_ProfileBKLMScintillatorZ->SetDirectory(dir_effC);
2585 m_ProfileEKLMScintillatorPlane1->SetDirectory(dir_effC);
2586 m_ProfileEKLMScintillatorPlane2->SetDirectory(dir_effC);
2587 m_Profile2RpcPhi->SetDirectory(dir_effC);
2588 m_Profile2RpcZ->SetDirectory(dir_effC);
2589 m_Profile2BKLMScintillatorPhi->SetDirectory(dir_effC);
2590 m_Profile2BKLMScintillatorZ->SetDirectory(dir_effC);
2591 m_Profile2EKLMScintillatorPlane1->SetDirectory(dir_effC);
2592 m_Profile2EKLMScintillatorPlane2->SetDirectory(dir_effC);
2593
2594 m_outFile->cd();
2595 TDirectory* dir_time = m_outFile->mkdir("time", "", true);
2596 dir_time->cd();
2597
2598 h_time_scint->SetDirectory(dir_time);
2599 hc_time_scint->SetDirectory(dir_time);
2600
2601 h_time_scint_end->SetDirectory(dir_time);
2602 hc_time_scint_end->SetDirectory(dir_time);
2603
2604 h_time_rpc->SetDirectory(dir_time);
2605 hc_time_rpc->SetDirectory(dir_time);
2606
2607 gre_time_channel_rpc->Write("gre_time_channel_rpc");
2608 gre_time_channel_scint->Write("gre_time_channel_scint");
2609 gre_time_channel_scint_end->Write("gre_time_channel_scint_end");
2610 gr_timeShift_channel_rpc->Write("gr_timeShift_channel_rpc");
2611 gr_timeShift_channel_scint->Write("gr_timeShift_channel_scint");
2612 gr_timeShift_channel_scint_end->Write("gr_timeShift_channel_scint_end");
2613 gre_ctime_channel_rpc->Write("gre_ctime_channel_rpc");
2614 gre_ctime_channel_scint->Write("gre_ctime_channel_scint");
2615 gre_ctime_channel_scint_end->Write("gre_ctime_channel_scint_end");
2616 gr_timeRes_channel_rpc->Write("gr_timeRes_channel_rpc");
2617 gr_timeRes_channel_scint->Write("gr_timeRes_channel_scint");
2618 gr_timeRes_channel_scint_end->Write("gr_timeRes_channel_scint_end");
2619
2620 B2INFO("Top file setup Done.");
2621
2622 /* Save debug plots (only if m_saveAllPlots is true). */
2623 if (!m_saveAllPlots) {
2624 B2INFO("Skipping debug histogram directory creation (m_saveAllPlots = false)");
2625 m_outFile->cd();
2626 m_outFile->Write();
2627 m_outFile->Close();
2628 B2INFO("File Write and Close. Done.");
2629 return;
2630 }
2631
2632 TDirectory* dir_time_F[2];
2633 TDirectory* dir_time_FS[2][8];
2634 TDirectory* dir_time_FSL[2][8][15];
2635 TDirectory* dir_time_FSLP[2][8][15][2];
2636 TDirectory* dir_time_F_end[2];
2637 TDirectory* dir_time_FS_end[2][4];
2638 TDirectory* dir_time_FSL_end[2][4][14];
2639 TDirectory* dir_time_FSLP_end[2][4][14][2];
2640 char dirname[50];
2641 B2INFO("Sub files declare Done.");
2642 for (int iF = 0; iF < 2; ++iF) {
2643 h_timeF_rpc[iF]->SetDirectory(dir_time);
2644 hc_timeF_rpc[iF]->SetDirectory(dir_time);
2645
2646 h2_timeF_rpc[iF]->SetDirectory(dir_time);
2647 h2c_timeF_rpc[iF]->SetDirectory(dir_time);
2648
2649 h_timeF_scint[iF]->SetDirectory(dir_time);
2650 hc_timeF_scint[iF]->SetDirectory(dir_time);
2651
2652 h2_timeF_scint[iF]->SetDirectory(dir_time);
2653 h2c_timeF_scint[iF]->SetDirectory(dir_time);
2654
2655 h_timeF_scint_end[iF]->SetDirectory(dir_time);
2656 hc_timeF_scint_end[iF]->SetDirectory(dir_time);
2657
2658 h2_timeF_scint_end[iF]->SetDirectory(dir_time);
2659 h2c_timeF_scint_end[iF]->SetDirectory(dir_time);
2660
2661 sprintf(dirname, "isForward_%d", iF);
2662 dir_time_F[iF] = dir_time->mkdir(dirname, "", true);
2663 dir_time_F[iF]->cd();
2664
2665 for (int iS = 0; iS < 8; ++iS) {
2666 h_timeFS_rpc[iF][iS]->SetDirectory(dir_time_F[iF]);
2667 hc_timeFS_rpc[iF][iS]->SetDirectory(dir_time_F[iF]);
2668
2669 h_timeFS_scint[iF][iS]->SetDirectory(dir_time_F[iF]);
2670 hc_timeFS_scint[iF][iS]->SetDirectory(dir_time_F[iF]);
2671
2672 h2_timeFS[iF][iS]->SetDirectory(dir_time_F[iF]);
2673 h2c_timeFS[iF][iS]->SetDirectory(dir_time_F[iF]);
2674
2675 sprintf(dirname, "Sector_%d", iS + 1);
2676 dir_time_FS[iF][iS] = dir_time_F[iF]->mkdir(dirname, "", true);
2677 dir_time_FS[iF][iS]->cd();
2678
2679 for (int iL = 0; iL < 15; ++iL) {
2680 h_timeFSL[iF][iS][iL]->SetDirectory(dir_time_FS[iF][iS]);
2681 hc_timeFSL[iF][iS][iL]->SetDirectory(dir_time_FS[iF][iS]);
2682
2683 sprintf(dirname, "Layer_%d", iL + 1);
2684 dir_time_FSL[iF][iS][iL] = dir_time_FS[iF][iS]->mkdir(dirname, "", true);
2685 dir_time_FSL[iF][iS][iL]->cd();
2686 for (int iP = 0; iP < 2; ++iP) {
2687 h_timeFSLP[iF][iS][iL][iP]->SetDirectory(dir_time_FSL[iF][iS][iL]);
2688 hc_timeFSLP[iF][iS][iL][iP]->SetDirectory(dir_time_FSL[iF][iS][iL]);
2689 h2_timeFSLP[iF][iS][iL][iP]->SetDirectory(dir_time_FSL[iF][iS][iL]);
2690 h2c_timeFSLP[iF][iS][iL][iP]->SetDirectory(dir_time_FSL[iF][iS][iL]);
2691
2692 sprintf(dirname, "Plane_%d", iP);
2693 dir_time_FSLP[iF][iS][iL][iP] = dir_time_FSL[iF][iS][iL]->mkdir(dirname, "", true);
2694 dir_time_FSLP[iF][iS][iL][iP]->cd();
2695
2696 }
2697 }
2698 }
2699
2700 sprintf(dirname, "isForward_%d_end", iF + 1);
2701 dir_time_F_end[iF] = dir_time->mkdir(dirname, "", true);
2702 dir_time_F_end[iF]->cd();
2703 int maxLayer = 12 + 2 * iF;
2704 for (int iS = 0; iS < 4; ++iS) {
2705 h_timeFS_scint_end[iF][iS]->SetDirectory(dir_time_F_end[iF]);
2706 hc_timeFS_scint_end[iF][iS]->SetDirectory(dir_time_F_end[iF]);
2707
2708 h2_timeFS_end[iF][iS]->SetDirectory(dir_time_F_end[iF]);
2709 h2c_timeFS_end[iF][iS]->SetDirectory(dir_time_F_end[iF]);
2710
2711 sprintf(dirname, "Sector_%d_end", iS + 1);
2712 dir_time_FS_end[iF][iS] = dir_time_F_end[iF]->mkdir(dirname, "", true);
2713 dir_time_FS_end[iF][iS]->cd();
2714 for (int iL = 0; iL < maxLayer; ++iL) {
2715 h_timeFSL_end[iF][iS][iL]->SetDirectory(dir_time_FS_end[iF][iS]);
2716 hc_timeFSL_end[iF][iS][iL]->SetDirectory(dir_time_FS_end[iF][iS]);
2717
2718 sprintf(dirname, "Layer_%d_end", iL + 1);
2719 dir_time_FSL_end[iF][iS][iL] = dir_time_FS_end[iF][iS]->mkdir(dirname, "", true);
2720 dir_time_FSL_end[iF][iS][iL]->cd();
2721 for (int iP = 0; iP < 2; ++iP) {
2722 h_timeFSLP_end[iF][iS][iL][iP]->SetDirectory(dir_time_FSL_end[iF][iS][iL]);
2723 hc_timeFSLP_end[iF][iS][iL][iP]->SetDirectory(dir_time_FSL_end[iF][iS][iL]);
2724 h2_timeFSLP_end[iF][iS][iL][iP]->SetDirectory(dir_time_FSL_end[iF][iS][iL]);
2725 h2c_timeFSLP_end[iF][iS][iL][iP]->SetDirectory(dir_time_FSL_end[iF][iS][iL]);
2726
2727 sprintf(dirname, "plane_%d_end", iP);
2728 dir_time_FSLP_end[iF][iS][iL][iP] = dir_time_FSL_end[iF][iS][iL]->mkdir(dirname, "", true);
2729 dir_time_FSLP_end[iF][iS][iL][iP]->cd();
2730
2731 }
2732 }
2733 }
2734 }
2735 m_outFile->cd();
2736 m_outFile->Write();
2737 m_outFile->Close();
2738 B2INFO("File Write and Close. Done.");
2739}

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

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

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

2879{
2880 std::pair<int, double> tR;
2881 int cId = klmChannel.getKLMChannelNumber();
2882 int iC = klmChannel.getStrip();
2883 if (m_timeRes.find(cId) != m_timeRes.end()) {
2884 tR.first = iC;
2885 tR.second = m_timeRes[cId];
2886 } else if (iC == 1) {
2887 tR.first = iC;
2888 tR.second = 0.0;
2889 } else {
2890 int iSub = klmChannel.getSubdetector();
2891 int iF = klmChannel.getSection();
2892 int iS = klmChannel.getSector();
2893 int iL = klmChannel.getLayer();
2894 int iP = klmChannel.getPlane();
2895 KLMChannelIndex kCIndex(iSub, iF, iS, iL, iP, iC - 1);
2896 tR = tR_lowerStrip(kCIndex);
2897 }
2898 return tR;
2899}
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 2852 of file KLMTimeAlgorithm.cc.

2853{
2854 std::pair<int, double> tR;
2855 int cId = klmChannel.getKLMChannelNumber();
2856 int iSub = klmChannel.getSubdetector();
2857 int iF = klmChannel.getSection();
2858 int iS = klmChannel.getSector();
2859 int iL = klmChannel.getLayer();
2860 int iP = klmChannel.getPlane();
2861 int iC = klmChannel.getStrip();
2863 if (iSub == KLMElementNumbers::c_BKLM)
2864 totNStrips = BKLMElementNumbers::getNStrips(iF, iS, iL, iP);
2865 if (m_timeRes.find(cId) != m_timeRes.end()) {
2866 tR.first = iC;
2867 tR.second = m_timeRes[cId];
2868 } else if (iC == totNStrips) {
2869 tR.first = iC;
2870 tR.second = 0.0;
2871 } else {
2872 KLMChannelIndex kCIndex(iSub, iF, iS, iL, iP, iC + 1);
2873 tR = tR_upperStrip(kCIndex);
2874 }
2875 return tR;
2876}

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

2799{
2800 std::pair<int, double> tS;
2801 int cId = klmChannel.getKLMChannelNumber();
2802 int iC = klmChannel.getStrip();
2803 if (m_timeShift.find(cId) != m_timeShift.end()) {
2804 tS.first = iC;
2805 tS.second = m_timeShift[cId];
2806 } else if (iC == 1) {
2807 tS.first = iC;
2808 tS.second = 0.0;
2809 } else {
2810 int iSub = klmChannel.getSubdetector();
2811 int iF = klmChannel.getSection();
2812 int iS = klmChannel.getSector();
2813 int iL = klmChannel.getLayer();
2814 int iP = klmChannel.getPlane();
2815 KLMChannelIndex kCIndex(iSub, iF, iS, iL, iP, iC - 1);
2816 tS = tS_lowerStrip(kCIndex);
2817 }
2818 return tS;
2819}

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

2773{
2774 std::pair<int, double> tS;
2775 int cId = klmChannel.getKLMChannelNumber();
2776 int iSub = klmChannel.getSubdetector();
2777 int iF = klmChannel.getSection();
2778 int iS = klmChannel.getSector();
2779 int iL = klmChannel.getLayer();
2780 int iP = klmChannel.getPlane();
2781 int iC = klmChannel.getStrip();
2783 if (iSub == KLMElementNumbers::c_BKLM)
2784 totNStrips = BKLMElementNumbers::getNStrips(iF, iS, iL, iP);
2785 if (m_timeShift.find(cId) != m_timeShift.end()) {
2786 tS.first = iC;
2787 tS.second = m_timeShift[cId];
2788 } else if (iC == totNStrips) {
2789 tS.first = iC;
2790 tS.second = 0.0;
2791 } else {
2792 KLMChannelIndex kCIndex(iSub, iF, iS, iL, iP, iC + 1);
2793 tS = tS_upperStrip(kCIndex);
2794 }
2795 return tS;
2796}

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

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

◆ writeThenDelete_() [2/2]

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

Same as above, but for 2D histograms.

Definition at line 1094 of file KLMTimeAlgorithm.cc.

1095{
1096 if (h == nullptr)
1097 return;
1098 if (write && m_outFile) {
1099 // Follow the pattern from saveHist(): cd into directory, then SetDirectory, then Write
1100 if (dir) {
1101 dir->cd();
1102 h->SetDirectory(dir);
1103 } else {
1104 m_outFile->cd();
1105 h->SetDirectory(m_outFile);
1106 }
1107 h->Write();
1108 m_outFile->cd(); // Return to root directory
1109 }
1110 delete h;
1111}

Member Data Documentation

◆ fcn_const

TF1* fcn_const = nullptr
private

Const function.

Global time distribution fitting.

Definition at line 946 of file KLMTimeAlgorithm.h.

◆ fcn_gaus

TF1* fcn_gaus = nullptr
private

Gaussian function.

Scitillator time distribution fitting.

Definition at line 949 of file KLMTimeAlgorithm.h.

◆ fcn_land

TF1* fcn_land = nullptr
private

Landau function.

RPC time distribution fitting.

Definition at line 952 of file KLMTimeAlgorithm.h.

◆ fcn_pol1

TF1* fcn_pol1 = nullptr
private

Pol1 function.

Effective light speed fitting.

Definition at line 943 of file KLMTimeAlgorithm.h.

◆ gr_timeRes_channel_rpc

TGraph* gr_timeRes_channel_rpc = nullptr
private

BKLM RPC.

Definition at line 596 of file KLMTimeAlgorithm.h.

◆ gr_timeRes_channel_scint

TGraph* gr_timeRes_channel_scint = nullptr
private

BKLM scintillator.

Definition at line 599 of file KLMTimeAlgorithm.h.

◆ gr_timeRes_channel_scint_end

TGraph* gr_timeRes_channel_scint_end = nullptr
private

EKLM.

Definition at line 602 of file KLMTimeAlgorithm.h.

◆ gr_timeShift_channel_rpc

TGraph* gr_timeShift_channel_rpc = nullptr
private

BKLM RPC.

Definition at line 585 of file KLMTimeAlgorithm.h.

◆ gr_timeShift_channel_scint

TGraph* gr_timeShift_channel_scint = nullptr
private

BKLM scintillator.

Definition at line 588 of file KLMTimeAlgorithm.h.

◆ gr_timeShift_channel_scint_end

TGraph* gr_timeShift_channel_scint_end = nullptr
private

EKLM.

Definition at line 591 of file KLMTimeAlgorithm.h.

◆ gre_ctime_channel_rpc

TGraphErrors* gre_ctime_channel_rpc = nullptr
private

BKLM RPC.

Definition at line 574 of file KLMTimeAlgorithm.h.

◆ gre_ctime_channel_scint

TGraphErrors* gre_ctime_channel_scint = nullptr
private

BKLM Scintillator.

Definition at line 577 of file KLMTimeAlgorithm.h.

◆ gre_ctime_channel_scint_end

TGraphErrors* gre_ctime_channel_scint_end = nullptr
private

EKLM.

Definition at line 580 of file KLMTimeAlgorithm.h.

◆ gre_time_channel_rpc

TGraphErrors* gre_time_channel_rpc = nullptr
private

BKLM RPC.

Definition at line 563 of file KLMTimeAlgorithm.h.

◆ gre_time_channel_scint

TGraphErrors* gre_time_channel_scint = nullptr
private

BKLM Scintillator.

Definition at line 566 of file KLMTimeAlgorithm.h.

◆ gre_time_channel_scint_end

TGraphErrors* gre_time_channel_scint_end = nullptr
private

EKLM.

Definition at line 569 of file KLMTimeAlgorithm.h.

◆ h2_deltaT0_vs_nhits_rpc

TH2F* h2_deltaT0_vs_nhits_rpc = nullptr
private

DeltaT0 vs total hit count for RPC.

Definition at line 905 of file KLMTimeAlgorithm.h.

◆ h2_deltaT0_vs_nhits_scint

TH2F* h2_deltaT0_vs_nhits_scint = nullptr
private

DeltaT0 vs total hit count for BKLM scintillator.

Definition at line 908 of file KLMTimeAlgorithm.h.

◆ h2_deltaT0_vs_nhits_scint_end

TH2F* h2_deltaT0_vs_nhits_scint_end = nullptr
private

DeltaT0 vs total hit count for EKLM scintillator.

Definition at line 911 of file KLMTimeAlgorithm.h.

◆ h2_deltaT0_vs_v_rpc

TH2F* h2_deltaT0_vs_v_rpc = nullptr
private

DeltaT0 vs inverse hit count for RPC.

Definition at line 887 of file KLMTimeAlgorithm.h.

◆ h2_deltaT0_vs_v_scint

TH2F* h2_deltaT0_vs_v_scint = nullptr
private

DeltaT0 vs inverse hit count for BKLM scintillator.

Definition at line 890 of file KLMTimeAlgorithm.h.

◆ h2_deltaT0_vs_v_scint_end

TH2F* h2_deltaT0_vs_v_scint_end = nullptr
private

DeltaT0 vs inverse hit count for EKLM scintillator.

Definition at line 893 of file KLMTimeAlgorithm.h.

◆ h2_timeF_rpc

TH2F* h2_timeF_rpc[2] = {nullptr}
private

BKLM RPC part.

Definition at line 714 of file KLMTimeAlgorithm.h.

714{nullptr};

◆ h2_timeF_scint

TH2F* h2_timeF_scint[2] = {nullptr}
private

BKLM scintillator part.

Definition at line 717 of file KLMTimeAlgorithm.h.

717{nullptr};

◆ h2_timeF_scint_end

TH2F* h2_timeF_scint_end[2] = {nullptr}
private

EKLM part.

Definition at line 720 of file KLMTimeAlgorithm.h.

720{nullptr};

◆ h2_timeFS

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

BKLM part.

Definition at line 764 of file KLMTimeAlgorithm.h.

764{{nullptr}};

◆ h2_timeFS_end

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

EKLM part.

Definition at line 767 of file KLMTimeAlgorithm.h.

767{{nullptr}};

◆ h2_timeFSLP

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

BKLM part.

Definition at line 818 of file KLMTimeAlgorithm.h.

818{{{{nullptr}}}};

◆ h2_timeFSLP_end

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

EKLM part.

Definition at line 821 of file KLMTimeAlgorithm.h.

821{{{{nullptr}}}};

◆ h2c_timeF_rpc

TH2F* h2c_timeF_rpc[2] = {nullptr}
private

BKLM RPC part.

Definition at line 728 of file KLMTimeAlgorithm.h.

728{nullptr};

◆ h2c_timeF_scint

TH2F* h2c_timeF_scint[2] = {nullptr}
private

BKLM scintillator part.

Definition at line 731 of file KLMTimeAlgorithm.h.

731{nullptr};

◆ h2c_timeF_scint_end

TH2F* h2c_timeF_scint_end[2] = {nullptr}
private

EKLM part.

Definition at line 734 of file KLMTimeAlgorithm.h.

734{nullptr};

◆ h2c_timeFS

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

BKLM part.

Definition at line 775 of file KLMTimeAlgorithm.h.

775{{nullptr}};

◆ h2c_timeFS_end

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

EKLM part.

Definition at line 778 of file KLMTimeAlgorithm.h.

778{{nullptr}};

◆ h2c_timeFSLP

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

BKLM part.

Definition at line 829 of file KLMTimeAlgorithm.h.

829{{{{nullptr}}}};

◆ h2c_timeFSLP_end

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

EKLM part.

Definition at line 832 of file KLMTimeAlgorithm.h.

832{{{{nullptr}}}};

◆ h_calibrated

TH1I* h_calibrated = nullptr
private

Calibration statistics for each channel.

Definition at line 552 of file KLMTimeAlgorithm.h.

◆ h_diff

TH1F* h_diff = nullptr
private

Distance between global and local position.

Definition at line 558 of file KLMTimeAlgorithm.h.

◆ h_eventT0_rpc

TH1F* h_eventT0_rpc = nullptr
private

EventT0 seen by RPC hits.

Definition at line 835 of file KLMTimeAlgorithm.h.

◆ h_eventT0_scint

TH1F* h_eventT0_scint = nullptr
private

EventT0 seen by BKLM scintillator hits.

Definition at line 838 of file KLMTimeAlgorithm.h.

◆ h_eventT0_scint_end

TH1F* h_eventT0_scint_end = nullptr
private

EventT0 seen by EKLM scintillator hits.

Definition at line 841 of file KLMTimeAlgorithm.h.

◆ h_nHits_minus_rpc

TH1F* h_nHits_minus_rpc = nullptr
private

Number of RPC hits per mu- track.

Definition at line 872 of file KLMTimeAlgorithm.h.

◆ h_nHits_minus_scint

TH1F* h_nHits_minus_scint = nullptr
private

Number of BKLM scintillator hits per mu- track.

Definition at line 878 of file KLMTimeAlgorithm.h.

◆ h_nHits_minus_scint_end

TH1F* h_nHits_minus_scint_end = nullptr
private

Number of EKLM scintillator hits per mu- track.

Definition at line 884 of file KLMTimeAlgorithm.h.

◆ h_nHits_plus_rpc

TH1F* h_nHits_plus_rpc = nullptr
private

Number of RPC hits per mu+ track.

Definition at line 869 of file KLMTimeAlgorithm.h.

◆ h_nHits_plus_scint

TH1F* h_nHits_plus_scint = nullptr
private

Number of BKLM scintillator hits per mu+ track.

Definition at line 875 of file KLMTimeAlgorithm.h.

◆ h_nHits_plus_scint_end

TH1F* h_nHits_plus_scint_end = nullptr
private

Number of EKLM scintillator hits per mu+ track.

Definition at line 881 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}}}};

◆ h_z_bklm_rpc

TH1F* h_z_bklm_rpc = nullptr
private

Normalised di-muon time difference, BKLM RPC, phi and z readouts together.

Definition at line 864 of file KLMTimeAlgorithm.h.

◆ h_z_bklm_rpc_phi

TH1F* h_z_bklm_rpc_phi = nullptr
private

Normalised di-muon time difference, BKLM RPC phi readout.

Definition at line 860 of file KLMTimeAlgorithm.h.

◆ h_z_bklm_rpc_z

TH1F* h_z_bklm_rpc_z = nullptr
private

Normalised di-muon time difference, BKLM RPC z readout.

Definition at line 862 of file KLMTimeAlgorithm.h.

◆ h_z_bklm_scint

TH1F* h_z_bklm_scint = nullptr
private

Normalised di-muon time difference z = dT0 / sqrt(1/N+ + 1/N-).

By construction z is distributed as N(0, sigma_hit), so a Gaussian fit to its core measures sigma_hit directly and is insensitive to the non-Gaussian tails that bias the plain second moment <dT0^2/v>.

Definition at line 858 of file KLMTimeAlgorithm.h.

◆ h_z_eklm_scint

TH1F* h_z_eklm_scint = nullptr
private

Normalised di-muon time difference, EKLM scintillator.

Definition at line 866 of file KLMTimeAlgorithm.h.

◆ hc_calibrated

TH1I* hc_calibrated = nullptr
private

Calibration statistics for each channel.

Definition at line 555 of file KLMTimeAlgorithm.h.

◆ hc_eventT0_rpc

TH1F* hc_eventT0_rpc = nullptr
private

Corrected EventT0 for RPC hits.

Definition at line 844 of file KLMTimeAlgorithm.h.

◆ hc_eventT0_rpc_highN

TH1F* hc_eventT0_rpc_highN = nullptr
private

Corrected EventT0 for RPC with high hit count.

Definition at line 920 of file KLMTimeAlgorithm.h.

◆ hc_eventT0_rpc_lowN

TH1F* hc_eventT0_rpc_lowN = nullptr
private

Corrected EventT0 for RPC with low hit count.

Definition at line 914 of file KLMTimeAlgorithm.h.

◆ hc_eventT0_rpc_midN

TH1F* hc_eventT0_rpc_midN = nullptr
private

Corrected EventT0 for RPC with medium hit count.

Definition at line 917 of file KLMTimeAlgorithm.h.

◆ hc_eventT0_scint

TH1F* hc_eventT0_scint = nullptr
private

Corrected EventT0 for BKLM scintillator hits.

Definition at line 847 of file KLMTimeAlgorithm.h.

◆ hc_eventT0_scint_end

TH1F* hc_eventT0_scint_end = nullptr
private

Corrected EventT0 for EKLM scintillator hits.

Definition at line 850 of file KLMTimeAlgorithm.h.

◆ hc_eventT0_scint_end_highN

TH1F* hc_eventT0_scint_end_highN = nullptr
private

Corrected EventT0 for EKLM scintillator with high hit count.

Definition at line 938 of file KLMTimeAlgorithm.h.

◆ hc_eventT0_scint_end_lowN

TH1F* hc_eventT0_scint_end_lowN = nullptr
private

Corrected EventT0 for EKLM scintillator with low hit count.

Definition at line 932 of file KLMTimeAlgorithm.h.

◆ hc_eventT0_scint_end_midN

TH1F* hc_eventT0_scint_end_midN = nullptr
private

Corrected EventT0 for EKLM scintillator with medium hit count.

Definition at line 935 of file KLMTimeAlgorithm.h.

◆ hc_eventT0_scint_highN

TH1F* hc_eventT0_scint_highN = nullptr
private

Corrected EventT0 for BKLM scintillator with high hit count.

Definition at line 929 of file KLMTimeAlgorithm.h.

◆ hc_eventT0_scint_lowN

TH1F* hc_eventT0_scint_lowN = nullptr
private

Corrected EventT0 for BKLM scintillator with low hit count.

Definition at line 923 of file KLMTimeAlgorithm.h.

◆ hc_eventT0_scint_midN

TH1F* hc_eventT0_scint_midN = nullptr
private

Corrected EventT0 for BKLM scintillator with medium hit count.

Definition at line 926 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 = true
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 967 of file KLMTimeAlgorithm.h.

967{};

◆ 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 973 of file KLMTimeAlgorithm.h.

973{};

◆ 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 955 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 958 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 961 of file KLMTimeAlgorithm.h.

◆ m_time_channel

std::map<KLMChannelNumber, double> m_time_channel
private

Time distribution central value of each channel.

Definition at line 396 of file KLMTimeAlgorithm.h.

◆ m_time_channelAvg_rpc

double m_time_channelAvg_rpc = 0.0
private

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

Definition at line 460 of file KLMTimeAlgorithm.h.

◆ m_time_channelAvg_scint

double m_time_channelAvg_scint = 0.0
private

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

Definition at line 467 of file KLMTimeAlgorithm.h.

◆ m_time_channelAvg_scint_end

double m_time_channelAvg_scint_end = 0.0
private

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

Definition at line 475 of file KLMTimeAlgorithm.h.

◆ m_timeCableDelay

KLMTimeCableDelay* m_timeCableDelay = nullptr
private

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

Definition at line 531 of file KLMTimeAlgorithm.h.

◆ m_timeConstants

KLMTimeConstants* m_timeConstants = nullptr
private

DBObject of time cost on some parts of the detector.

Definition at line 525 of file KLMTimeAlgorithm.h.

◆ m_timeRes

std::map<KLMChannelNumber, double> m_timeRes
private

Resolution values of each channel.

Definition at line 393 of file KLMTimeAlgorithm.h.

◆ m_timeResolution

KLMTimeResolution* m_timeResolution = nullptr
private

DBObject of time resolution.

Definition at line 534 of file KLMTimeAlgorithm.h.

◆ m_timeShift

std::map<KLMChannelNumber, double> m_timeShift
private

Shift values of each channel.

Definition at line 390 of file KLMTimeAlgorithm.h.

◆ m_UpperTimeBoundaryCalibratedRPC

double m_UpperTimeBoundaryCalibratedRPC = 40.0
private

Upper time boundary for RPC (calibrated data).

Definition at line 429 of file KLMTimeAlgorithm.h.

◆ m_UpperTimeBoundaryCalibratedScintillatorsBKLM

double m_UpperTimeBoundaryCalibratedScintillatorsBKLM = 40.0
private

Upper time boundary for BKLM scintillators (calibrated data).

Definition at line 451 of file KLMTimeAlgorithm.h.

◆ m_UpperTimeBoundaryCalibratedScintillatorsEKLM

double m_UpperTimeBoundaryCalibratedScintillatorsEKLM = 40.0
private

Upper time boundary for BKLM scintillators (calibrated data).

Definition at line 457 of file KLMTimeAlgorithm.h.

◆ m_UpperTimeBoundaryRPC

double m_UpperTimeBoundaryRPC = 10.0
private

Upper time boundary for RPC.

Definition at line 411 of file KLMTimeAlgorithm.h.

◆ m_UpperTimeBoundaryScintillatorsBKLM

double m_UpperTimeBoundaryScintillatorsBKLM = 70.0
private

Upper time boundary for BKLM scintillators.

Definition at line 417 of file KLMTimeAlgorithm.h.

◆ m_UpperTimeBoundaryScintillatorsEKLM

double m_UpperTimeBoundaryScintillatorsEKLM = 70.0
private

Upper time boundary for BKLM scintillators.

Definition at line 423 of file KLMTimeAlgorithm.h.

◆ m_useEventT0

bool m_useEventT0 = true
private

Whether to use event T0 from CDC.

Definition at line 546 of file KLMTimeAlgorithm.h.

◆ m_useFixedRPCDelay

bool m_useFixedRPCDelay = false
private

Whether to use fixed propagation delay for RPCs.

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

Definition at line 438 of file KLMTimeAlgorithm.h.

◆ mc_etime_channel

std::map<KLMChannelNumber, double> mc_etime_channel
private

Calibrated time distribution central value Error of each channel.

Definition at line 405 of file KLMTimeAlgorithm.h.

◆ mc_etime_channelAvg_rpc

double mc_etime_channelAvg_rpc = 0.0
private

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

Definition at line 485 of file KLMTimeAlgorithm.h.

◆ mc_etime_channelAvg_scint

double mc_etime_channelAvg_scint = 0.0
private

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

Definition at line 493 of file KLMTimeAlgorithm.h.

◆ mc_etime_channelAvg_scint_end

double mc_etime_channelAvg_scint_end = 0.0
private

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

Definition at line 501 of file KLMTimeAlgorithm.h.

◆ prof_deltaT0_rms_vs_v_rpc

TProfile* prof_deltaT0_rms_vs_v_rpc = nullptr
private

DeltaT0 RMS vs inverse hit count profile for RPC.

Definition at line 896 of file KLMTimeAlgorithm.h.

◆ prof_deltaT0_rms_vs_v_scint

TProfile* prof_deltaT0_rms_vs_v_scint = nullptr
private

DeltaT0 RMS vs inverse hit count profile for BKLM scintillator.

Definition at line 899 of file KLMTimeAlgorithm.h.

◆ prof_deltaT0_rms_vs_v_scint_end

TProfile* prof_deltaT0_rms_vs_v_scint_end = nullptr
private

DeltaT0 RMS vs inverse hit count profile for EKLM scintillator.

Definition at line 902 of file KLMTimeAlgorithm.h.


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