Belle II Software development
KLMTimeAlgorithm Class Reference

KLM time calibration algorithm. More...

#include <KLMTimeAlgorithm.h>

Inheritance diagram for KLMTimeAlgorithm:
CalibrationAlgorithm

Classes

struct  Event
 Event data. More...
 

Public Types

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

Public Member Functions

 KLMTimeAlgorithm ()
 Constructor.
 
 ~KLMTimeAlgorithm ()
 Destructor.
 
void setDebug ()
 Turn on debug mode (prints histograms and output running log).
 
void setMC (bool mc)
 Set flag indicating whether the input is MC sample.
 
void useEvtT0 ()
 Use event T0 as the initial time point or not.
 
void setMinimalDigitNumber (int minimalDigitNumber)
 Set minimal digit number (total).
 
void setLowerLimit (int counts)
 Set the lower number of hits collected on one single strip.
 
void setApplyChargeRestriction (bool apply)
 Enable or disable ADC/charge restriction cuts for scintillators.
 
void setSaveAllPlots (bool on)
 Save every preallocated debug histogram family (sectors/layers/planes/2D maps).
 
void setSaveChannelHists (bool on)
 When running in minimal mode, also write the per-channel temporary histograms (the vital tc, raw, hc 1D’s created on-the-fly) before deleting them.
 
void saveHist ()
 Save histograms to file.
 
double esti_timeShift (const KLMChannelIndex &klmChannel)
 Estimate value of calibration constant for uncalibrated channels.
 
std::pair< int, double > tS_upperStrip (const KLMChannelIndex &klmChannel)
 Tracing available channels with increasing strip number.
 
std::pair< int, double > tS_lowerStrip (const KLMChannelIndex &klmChannel)
 Tracing available channels with decreasing strip number.
 
double esti_timeRes (const KLMChannelIndex &klmChannel)
 Estimate value of calibration constant for calibrated channels.
 
std::pair< int, double > tR_upperStrip (const KLMChannelIndex &klmChannel)
 Tracing available channels with increasing strip number.
 
std::pair< int, double > tR_lowerStrip (const KLMChannelIndex &klmChannel)
 Tracing available channels with decreasing strip number.
 
std::string getPrefix () const
 Get the prefix used for getting calibration data.
 
bool checkPyExpRun (PyObject *pyObj)
 Checks that a PyObject can be successfully converted to an ExpRun type.
 
Calibration::ExpRun convertPyExpRun (PyObject *pyObj)
 Performs the conversion of PyObject to ExpRun.
 
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.
 
std::string getGranularity () const
 Get the granularity of collected data.
 
EResult execute (std::vector< Calibration::ExpRun > runs={}, int iteration=0, IntervalOfValidity iov=IntervalOfValidity())
 Runs calibration over vector of runs for a given iteration.
 
EResult execute (PyObject *runs, int iteration=0, IntervalOfValidity iov=IntervalOfValidity())
 Runs calibration over Python list of runs. Converts to C++ and then calls the other execute() function.
 
std::list< Database::DBImportQuery > & getPayloads ()
 Get constants (in TObjects) for database update from last execution.
 
std::list< Database::DBImportQuerygetPayloadValues ()
 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>.
 

Protected Member Functions

virtual EResult calibrate () override
 Run algorithm on data.
 
void setInputFileNames (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.
 
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 updateDBObjPtrs (const unsigned int event, const int run, const int experiment)
 Updates any DBObjPtrs by calling update(event) for DBStore.
 
void setDescription (const std::string &description)
 Set algorithm description (in constructor)
 
void clearCalibrationData ()
 Clear calibration data.
 
Calibration::ExpRun getAllGranularityExpRun () const
 Returns the Exp,Run pair that means 'Everything'. Currently unused.
 
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.
 

Protected Attributes

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

Private Member Functions

void setupDatabase ()
 Setup the database.
 
CalibrationAlgorithm::EResult readCalibrationData ()
 Read calibration data.
 
void readCalibrationDataCounts (std::map< KLMChannelNumber, unsigned int > &eventCounts)
 Count events per channel (lightweight scan without loading full data).
 
void readCalibrationDataFor2DFit (const std::vector< std::pair< KLMChannelNumber, unsigned int > > &channelsBKLM, const std::vector< std::pair< KLMChannelNumber, unsigned int > > &channelsEKLM)
 Load calibration data only for channels needed for 2D fit.
 
void readCalibrationDataBatch (std::function< bool(const KLMChannelIndex &)> channelFilter)
 Load calibration data for a specific batch of channels.
 
void createHistograms ()
 Create histograms.
 
void writeThenDelete_ (TH1 *h, bool write, TDirectory *dir=nullptr)
 Optionally write a histogram, then delete it to free memory.
 
void writeThenDelete_ (TH2 *h, bool write, TDirectory *dir=nullptr)
 Same as above, but for 2D histograms.
 
bool passesADCCut (const Event &event, int subdetector, int layer) const
 Check if event passes ADC count cuts for quality selection.
 
void fillTimeDistanceProfiles (TProfile *profileRpcPhi, TProfile *profileRpcZ, TProfile *profileBKLMScintillatorPhi, TProfile *profileBKLMScintillatorZ, TProfile *profileEKLMScintillatorPlane1, TProfile *profileEKLMScintillatorPlane2, bool fill2dHistograms)
 Fill profiles of time versus distance.
 
void timeDistance2dFit (const std::vector< std::pair< KLMChannelNumber, unsigned int > > &channels, double &delay, double &delayError)
 Two-dimensional fit for individual channels.
 
std::string getExpRunString (Calibration::ExpRun &expRun) const
 Gets the "exp.run" string repr. of (exp,run)
 
std::string getFullObjectPath (const std::string &name, Calibration::ExpRun expRun) const
 constructs the full TDirectory + Key name of an object in a TFile based on its name and exprun
 

Private Attributes

std::map< KLMChannelNumber, std::vector< struct Event > > m_evts
 Container of hit information.
 
std::map< KLMChannelNumber, int > m_cFlag
 Calibration flag if the channel has enough hits collected and fitted OK.
 
std::map< KLMChannelNumber, double > m_timeShift
 Shift values of each channel.
 
std::map< KLMChannelNumber, double > m_timeRes
 Resolution values of each channel.
 
std::map< KLMChannelNumber, double > m_time_channel
 Time distribution central value of each channel.
 
std::map< KLMChannelNumber, double > m_etime_channel
 Time distribution central value Error of each channel.
 
std::map< KLMChannelNumber, double > m_ctime_channel
 Calibrated time distribution central value of each channel.
 
std::map< KLMChannelNumber, double > mc_etime_channel
 Calibrated time distribution central value Error of each channel.
 
double m_LowerTimeBoundaryRPC = -10.0
 Lower time boundary for RPC.
 
double m_UpperTimeBoundaryRPC = 10.0
 Upper time boundary for RPC.
 
double m_LowerTimeBoundaryScintillatorsBKLM = 20.0
 Lower time boundary for BKLM scintillators.
 
double m_UpperTimeBoundaryScintillatorsBKLM = 70.0
 Upper time boundary for BKLM scintillators.
 
double m_LowerTimeBoundaryScintillatorsEKLM = 20.0
 Lower time boundary for EKLM scintillators.
 
double m_UpperTimeBoundaryScintillatorsEKLM = 70.0
 Upper time boundary for BKLM scintillators.
 
double m_LowerTimeBoundaryCalibratedRPC = -40.0
 Lower time boundary for RPC (calibrated data).
 
double m_UpperTimeBoundaryCalibratedRPC = 40.0
 Upper time boundary for RPC (calibrated data).
 
bool m_useFixedRPCDelay = false
 Whether to use fixed propagation delay for RPCs.
 
double m_fixedRPCDelay = 0.0667
 Fixed propagation delay for RPCs (ns/cm).
 
double m_LowerTimeBoundaryCalibratedScintillatorsBKLM = -40.0
 Lower time boundary for BKLM scintillators (calibrated data).
 
double m_UpperTimeBoundaryCalibratedScintillatorsBKLM = 40.0
 Upper time boundary for BKLM scintillators (calibrated data).
 
double m_LowerTimeBoundaryCalibratedScintillatorsEKLM = -40.0
 Lower time boundary for EKLM scintillators (calibrated data).
 
double m_UpperTimeBoundaryCalibratedScintillatorsEKLM = 40.0
 Upper time boundary for BKLM scintillators (calibrated data).
 
double m_time_channelAvg_rpc = 0.0
 Central value of the global time distribution (BKLM RPC part).
 
double m_etime_channelAvg_rpc = 0.0
 Central value error of the global time distribution (BKLM RPC part).
 
double m_time_channelAvg_scint = 0.0
 Central value of the global time distribution (BKLM scintillator part).
 
double m_etime_channelAvg_scint = 0.0
 Central value error of the global time distribution (BKLM scintillator part).
 
double m_time_channelAvg_scint_end = 0.0
 Central value of the global time distribution (EKLM scintillator part).
 
double m_etime_channelAvg_scint_end = 0.0
 Central value error of the global time distribution (EKLM scintillator part).
 
double m_ctime_channelAvg_rpc = 0.0
 Calibrated central value of the global time distribution (BKLM RPC part).
 
double mc_etime_channelAvg_rpc = 0.0
 Calibrated central value error of the global time distribution (BKLM RPC part).
 
double m_ctime_channelAvg_scint = 0.0
 Calibrated central value of the global time distribution (BKLM scintillator part).
 
double mc_etime_channelAvg_scint = 0.0
 Calibrated central value error of the global time distribution (BKLM scintillator part).
 
double m_ctime_channelAvg_scint_end = 0.0
 Calibrated central value of the global time distribution (EKLM scintillator part).
 
double mc_etime_channelAvg_scint_end = 0.0
 Calibrated central value error of the global time distribution (EKLM scintillator part).
 
int m_MinimalDigitNumber = 100000000
 Minimal digit number (total).
 
int m_lower_limit_counts = 50
 Lower limit of hits collected for on single channel.
 
const KLMElementNumbersm_ElementNumbers
 Element numbers.
 
const bklm::GeometryParm_BKLMGeometry = nullptr
 BKLM geometry data.
 
const EKLM::GeometryDatam_EKLMGeometry = nullptr
 EKLM geometry data.
 
KLMChannelIndex m_klmChannels
 KLM ChannelIndex object.
 
ROOT::Math::MinimizerOptions m_minimizerOptions
 Minimization options.
 
KLMTimeConstantsm_timeConstants = nullptr
 DBObject of time cost on some parts of the detector.
 
KLMTimeCableDelaym_timeCableDelay = nullptr
 DBObject of the calibration constant of each channel due to cable decay.
 
KLMTimeResolutionm_timeResolution = nullptr
 DBObject of time resolution.
 
KLMEventT0HitResolutionm_eventT0HitResolution = nullptr
 DBObject of per-hit time resolution for EventT0.
 
bool m_debug = false
 Debug mode.
 
bool m_mc = false
 MC or data.
 
bool m_useEventT0 = true
 Whether to use event T0 from CDC.
 
bool m_applyChargeRestriction = false
 Whether to apply ADC/charge restriction cuts for scintillators.
 
TH1I * h_calibrated = nullptr
 Calibration statistics for each channel.
 
TH1I * hc_calibrated = nullptr
 Calibration statistics for each channel.
 
TH1F * h_diff = nullptr
 Distance between global and local position.
 
TGraphErrors * gre_time_channel_rpc = nullptr
 BKLM RPC.
 
TGraphErrors * gre_time_channel_scint = nullptr
 BKLM Scintillator.
 
TGraphErrors * gre_time_channel_scint_end = nullptr
 EKLM.
 
TGraphErrors * gre_ctime_channel_rpc = nullptr
 BKLM RPC.
 
TGraphErrors * gre_ctime_channel_scint = nullptr
 BKLM Scintillator.
 
TGraphErrors * gre_ctime_channel_scint_end = nullptr
 EKLM.
 
TGraph * gr_timeShift_channel_rpc = nullptr
 BKLM RPC.
 
TGraph * gr_timeShift_channel_scint = nullptr
 BKLM scintillator.
 
TGraph * gr_timeShift_channel_scint_end = nullptr
 EKLM.
 
TGraph * gr_timeRes_channel_rpc = nullptr
 BKLM RPC.
 
TGraph * gr_timeRes_channel_scint = nullptr
 BKLM scintillator.
 
TGraph * gr_timeRes_channel_scint_end = nullptr
 EKLM.
 
TProfile * m_ProfileRpcPhi = nullptr
 For BKLM RPC phi plane.
 
TProfile * m_ProfileRpcZ = nullptr
 For BKLM RPC z plane.
 
TProfile * m_ProfileBKLMScintillatorPhi = nullptr
 For BKLM scintillator phi plane.
 
TProfile * m_ProfileBKLMScintillatorZ = nullptr
 For BKLM scintillator z plane.
 
TProfile * m_ProfileEKLMScintillatorPlane1 = nullptr
 For EKLM scintillator plane1.
 
TProfile * m_ProfileEKLMScintillatorPlane2 = nullptr
 For EKLM scintillator plane2.
 
TProfile * m_Profile2RpcPhi = nullptr
 For BKLM RPC phi plane.
 
TProfile * m_Profile2RpcZ = nullptr
 For BKLM RPC z plane.
 
TProfile * m_Profile2BKLMScintillatorPhi = nullptr
 For BKLM scintillator phi plane.
 
TProfile * m_Profile2BKLMScintillatorZ = nullptr
 For BKLM scintillator z plane.
 
TProfile * m_Profile2EKLMScintillatorPlane1 = nullptr
 For EKLM scintillator plane1.
 
TProfile * m_Profile2EKLMScintillatorPlane2 = nullptr
 For EKLM scintillator plane2.
 
TH1F * h_time_rpc_tc = nullptr
 BKLM RPC part.
 
TH1F * h_time_scint_tc = nullptr
 BKLM scintillator part.
 
TH1F * h_time_scint_tc_end = nullptr
 EKLM part.
 
TH1F * h_time_rpc = nullptr
 BKLM RPC part.
 
TH1F * h_time_scint = nullptr
 BKLM scintillator part.
 
TH1F * h_time_scint_end = nullptr
 EKLM part.
 
TH1F * hc_time_rpc = nullptr
 BKLM RPC part.
 
TH1F * hc_time_scint = nullptr
 BKLM scintillator part.
 
TH1F * hc_time_scint_end = nullptr
 EKLM part.
 
TH1F * h_timeF_rpc [2] = {nullptr}
 BKLM RPC part.
 
TH1F * h_timeF_scint [2] = {nullptr}
 BKLM scintillator part.
 
TH1F * h_timeF_scint_end [2] = {nullptr}
 EKLM part.
 
TH1F * hc_timeF_rpc [2] = {nullptr}
 BKLM RPC part.
 
TH1F * hc_timeF_scint [2] = {nullptr}
 BKLM scintillator part.
 
TH1F * hc_timeF_scint_end [2] = {nullptr}
 EKLM part.
 
TH2F * h2_timeF_rpc [2] = {nullptr}
 BKLM RPC part.
 
TH2F * h2_timeF_scint [2] = {nullptr}
 BKLM scintillator part.
 
TH2F * h2_timeF_scint_end [2] = {nullptr}
 EKLM part.
 
TH2F * h2c_timeF_rpc [2] = {nullptr}
 BKLM RPC part.
 
TH2F * h2c_timeF_scint [2] = {nullptr}
 BKLM scintillator part.
 
TH2F * h2c_timeF_scint_end [2] = {nullptr}
 EKLM part.
 
TH1F * h_timeFS_rpc [2][8] = {{nullptr}}
 BKLM RPC part.
 
TH1F * h_timeFS_scint [2][8] = {{nullptr}}
 BKLM scintillator part.
 
TH1F * h_timeFS_scint_end [2][4] = {{nullptr}}
 EKLM part.
 
TH1F * hc_timeFS_rpc [2][8] = {{nullptr}}
 BKLM RPC part.
 
TH1F * hc_timeFS_scint [2][8] = {{nullptr}}
 BKLM scintillator part.
 
TH1F * hc_timeFS_scint_end [2][4] = {{nullptr}}
 EKLM part.
 
TH2F * h2_timeFS [2][8] = {{nullptr}}
 BKLM part.
 
TH2F * h2_timeFS_end [2][4] = {{nullptr}}
 EKLM part.
 
TH2F * h2c_timeFS [2][8] = {{nullptr}}
 BKLM part.
 
TH2F * h2c_timeFS_end [2][4] = {{nullptr}}
 EKLM part.
 
TH1F * h_timeFSL [2][8][15] = {{{nullptr}}}
 BKLM part.
 
TH1F * h_timeFSL_end [2][4][14] = {{{nullptr}}}
 EKLM part.
 
TH1F * hc_timeFSL [2][8][15] = {{{nullptr}}}
 BKLM part.
 
TH1F * hc_timeFSL_end [2][4][14] = {{{nullptr}}}
 EKLM part.
 
TH1F * h_timeFSLP [2][8][15][2] = {{{{nullptr}}}}
 BKLM part.
 
TH1F * h_timeFSLP_end [2][4][14][2] = {{{{nullptr}}}}
 EKLM part.
 
TH1F * hc_timeFSLP [2][8][15][2] = {{{{nullptr}}}}
 BKLM part.
 
TH1F * hc_timeFSLP_end [2][4][14][2] = {{{{nullptr}}}}
 EKLM part.
 
TH2F * h2_timeFSLP [2][8][15][2] = {{{{nullptr}}}}
 BKLM part.
 
TH2F * h2_timeFSLP_end [2][4][14][2] = {{{{nullptr}}}}
 EKLM part.
 
TH2F * h2c_timeFSLP [2][8][15][2] = {{{{nullptr}}}}
 BKLM part.
 
TH2F * h2c_timeFSLP_end [2][4][14][2] = {{{{nullptr}}}}
 EKLM part.
 
TH1F * h_timeFSLPC_tc [2][8][15][2][54] = {{{{{nullptr}}}}}
 BKLM part, used for effective light speed estimation.
 
TH1F * h_timeFSLPC [2][8][15][2][54] = {{{{{nullptr}}}}}
 BKLM part.
 
TH2F * m_HistTimeLengthBKLM [2][8][15][2][54] = {{{{{nullptr}}}}}
 Two-dimensional distributions of time versus propagation length.
 
TH1F * h_timeFSLPC_tc_end [2][4][14][2][75] = {{{{{nullptr}}}}}
 EKLM part, used for effective light speed estimation.
 
TH1F * h_timeFSLPC_end [2][4][14][2][75] = {{{{{nullptr}}}}}
 EKLM part.
 
TH2F * m_HistTimeLengthEKLM [2][4][14][2][75] = {{{{{nullptr}}}}}
 Two-dimensional distributions of time versus propagation length.
 
TH1F * hc_timeFSLPC [2][8][15][2][54] = {{{{{nullptr}}}}}
 BKLM part.
 
TH1F * hc_timeFSLPC_end [2][4][14][2][75] = {{{{{nullptr}}}}}
 EKLM part.
 
TH1F * h_eventT0_rpc = nullptr
 EventT0 seen by RPC hits.
 
TH1F * h_eventT0_scint = nullptr
 EventT0 seen by BKLM scintillator hits.
 
TH1F * h_eventT0_scint_end = nullptr
 EventT0 seen by EKLM scintillator hits.
 
TH1F * hc_eventT0_rpc = nullptr
 Corrected EventT0 for RPC hits.
 
TH1F * hc_eventT0_scint = nullptr
 Corrected EventT0 for BKLM scintillator hits.
 
TH1F * hc_eventT0_scint_end = nullptr
 Corrected EventT0 for EKLM scintillator hits.
 
TH1F * h_nHits_plus_rpc
 Number of RPC hits per mu+ track.
 
TH1F * h_nHits_minus_rpc
 Number of RPC hits per mu- track.
 
TH1F * h_nHits_plus_scint
 Number of BKLM scintillator hits per mu+ track.
 
TH1F * h_nHits_minus_scint
 Number of BKLM scintillator hits per mu- track.
 
TH1F * h_nHits_plus_scint_end
 Number of EKLM scintillator hits per mu+ track.
 
TH1F * h_nHits_minus_scint_end
 Number of EKLM scintillator hits per mu- track.
 
TH2F * h2_deltaT0_vs_v_rpc
 DeltaT0 vs inverse hit count for RPC.
 
TH2F * h2_deltaT0_vs_v_scint
 DeltaT0 vs inverse hit count for BKLM scintillator.
 
TH2F * h2_deltaT0_vs_v_scint_end
 DeltaT0 vs inverse hit count for EKLM scintillator.
 
TProfile * prof_deltaT0_rms_vs_v_rpc
 DeltaT0 RMS vs inverse hit count profile for RPC.
 
TProfile * prof_deltaT0_rms_vs_v_scint
 DeltaT0 RMS vs inverse hit count profile for BKLM scintillator.
 
TProfile * prof_deltaT0_rms_vs_v_scint_end
 DeltaT0 RMS vs inverse hit count profile for EKLM scintillator.
 
TH2F * h2_deltaT0_vs_nhits_rpc
 DeltaT0 vs total hit count for RPC.
 
TH2F * h2_deltaT0_vs_nhits_scint
 DeltaT0 vs total hit count for BKLM scintillator.
 
TH2F * h2_deltaT0_vs_nhits_scint_end
 DeltaT0 vs total hit count for EKLM scintillator.
 
TH1F * hc_eventT0_rpc_lowN
 Corrected EventT0 for RPC with low hit count.
 
TH1F * hc_eventT0_rpc_midN
 Corrected EventT0 for RPC with medium hit count.
 
TH1F * hc_eventT0_rpc_highN
 Corrected EventT0 for RPC with high hit count.
 
TH1F * hc_eventT0_scint_lowN
 Corrected EventT0 for BKLM scintillator with low hit count.
 
TH1F * hc_eventT0_scint_midN
 Corrected EventT0 for BKLM scintillator with medium hit count.
 
TH1F * hc_eventT0_scint_highN
 Corrected EventT0 for BKLM scintillator with high hit count.
 
TH1F * hc_eventT0_scint_end_lowN
 Corrected EventT0 for EKLM scintillator with low hit count.
 
TH1F * hc_eventT0_scint_end_midN
 Corrected EventT0 for EKLM scintillator with medium hit count.
 
TH1F * hc_eventT0_scint_end_highN
 Corrected EventT0 for EKLM scintillator with high hit count.
 
TF1 * fcn_pol1 = nullptr
 Pol1 function.
 
TF1 * fcn_const = nullptr
 Const function.
 
TF1 * fcn_gaus = nullptr
 Gaussian function.
 
TF1 * fcn_land = nullptr
 Landau function.
 
TFile * m_outFile = nullptr
 Output file.
 
bool m_saveAllPlots = false
 Default minimal unless you set true in your header script.
 
bool m_saveChannelHists = false
 Write per-channel temporary histograms (tc/raw/hc) in minimal mode.
 
TDirectory * m_channelHistDir_BKLM [2][8][15][2] = {}
 Directory structure for per-channel histograms (BKLM).
 
TDirectory * m_channelHistDir_EKLM [2][4][14][2] = {}
 Directory structure for per-channel histograms (EKLM).
 
std::vector< std::string > m_inputFileNames
 List of input files to the Algorithm, will initially be user defined but then gets the wildcards expanded during execute()
 
std::map< Calibration::ExpRun, std::vector< std::string > > m_runsToInputFiles
 Map of Runs to input files. Gets filled when you call getRunRangeFromAllData, gets cleared when setting input files again.
 
std::string m_granularityOfData
 Granularity of input data. This only changes when the input files change so it isn't specific to an execution.
 
ExecutionData m_data
 Data specific to a SINGLE execution of the algorithm. Gets reset at the beginning of execution.
 
std::string m_description {""}
 Description of the algorithm.
 
std::string m_prefix {""}
 The name of the TDirectory the collector objects are contained within.
 
nlohmann::json m_jsonExecutionInput = nlohmann::json::object()
 Optional input JSON object used to make decisions about how to execute the algorithm code.
 
nlohmann::json m_jsonExecutionOutput = nlohmann::json::object()
 Optional output JSON object that can be set during the execution by the underlying algorithm code.
 

Static Private Attributes

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

Detailed Description

KLM time calibration algorithm.

Definition at line 50 of file KLMTimeAlgorithm.h.

Member Enumeration Documentation

◆ ChannelCalibrationStatus

Channel calibration status.

Definition at line 129 of file KLMTimeAlgorithm.h.

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

◆ EResult

enum EResult
inherited

The result of calibration.

Enumerator
c_OK 

Finished successfully =0 in Python.

c_Iterate 

Needs iteration =1 in Python.

c_NotEnoughData 

Needs more data =2 in Python.

c_Failure 

Failed =3 in Python.

c_Undefined 

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

Definition at line 40 of file CalibrationAlgorithm.h.

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

Constructor & Destructor Documentation

◆ KLMTimeAlgorithm()

Constructor.

Definition at line 97 of file KLMTimeAlgorithm.cc.

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

◆ ~KLMTimeAlgorithm()

Destructor.

Definition at line 104 of file KLMTimeAlgorithm.cc.

105{
106}

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

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

◆ checkPyExpRun()

bool checkPyExpRun ( PyObject * pyObj)
inherited

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:41
bool storeData(const std::string &name, TObject *object, const IntervalOfValidity &iov)
Store an object in the database.
Definition Database.cc:140

◆ commit() [2/2]

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

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

Definition at line 311 of file CalibrationAlgorithm.cc.

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

◆ convertPyExpRun()

ExpRun convertPyExpRun ( PyObject * pyObj)
inherited

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

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

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

2632{
2633 double tS = 0.0;
2634 int iSub = klmChannel.getSubdetector();
2635 int iF = klmChannel.getSection();
2636 int iS = klmChannel.getSector();
2637 int iL = klmChannel.getLayer();
2638 int iP = klmChannel.getPlane();
2639 int iC = klmChannel.getStrip();
2641 if (iSub == KLMElementNumbers::c_BKLM)
2642 totNStrips = BKLMElementNumbers::getNStrips(iF, iS, iL, iP);
2643 if (iC == 1) {
2644 KLMChannelIndex kCIndex_upper(iSub, iF, iS, iL, iP, iC + 1);
2645 tS = tS_upperStrip(kCIndex_upper).second;
2646 } else if (iC == totNStrips) {
2647 KLMChannelIndex kCIndex_lower(iSub, iF, iS, iL, iP, iC - 1);
2648 tS = tS_lowerStrip(kCIndex_lower).second;
2649 } else {
2650 KLMChannelIndex kCIndex_upper(iSub, iF, iS, iL, iP, iC + 1);
2651 KLMChannelIndex kCIndex_lower(iSub, iF, iS, iL, iP, iC - 1);
2652 std::pair<int, double> tS_upper = tS_upperStrip(kCIndex_upper);
2653 std::pair<int, double> tS_lower = tS_lowerStrip(kCIndex_lower);
2654 unsigned int td_upper = tS_upper.first - iC;
2655 unsigned int td_lower = iC - tS_lower.first;
2656 unsigned int td = tS_upper.first - tS_lower.first;
2657 tS = (double(td_upper) * tS_lower.second + double(td_lower) * tS_upper.second) / double(td);
2658 }
2659 return tS;
2660}
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}
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.
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.
virtual EResult calibrate()=0
Run algo on data - pure virtual: needs to be implemented.
std::string getGranularity() const
Get the granularity of collected data.

◆ fillRunToInputFilesMap()

void fillRunToInputFilesMap ( )
inherited

Fill the mapping of ExpRun -> Files.

Definition at line 330 of file CalibrationAlgorithm.cc.

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

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

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

Calibration::ExpRun getAllGranularityExpRun ( ) const
inlineprotectedinherited

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

Definition at line 327 of file CalibrationAlgorithm.h.

327{return m_allExpRun;}

◆ getCollectorName()

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()

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 383 of file CalibrationAlgorithm.cc.

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

326{
328}
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 ( )
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()

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 318 of file CalibrationAlgorithm.cc.

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

◆ getRunRangeFromAllData()

RunRange getRunRangeFromAllData ( ) const
inherited

Get the complete RunRange from inspection of collected data.

Definition at line 361 of file CalibrationAlgorithm.cc.

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

◆ getVecInputFileNames()

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, 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 502 of file CalibrationAlgorithm.cc.

503{
504 try {
505 auto jsonInput = nlohmann::json::parse(jsonString);
506 // Input string has an object (dict) as the top level object?
507 if (jsonInput.is_object()) {
508 m_jsonExecutionInput = jsonInput;
509 return true;
510 } else {
511 B2ERROR("JSON input string isn't an object type i.e. not a '{}' at the top level.");
512 return false;
513 }
514 } catch (nlohmann::json::parse_error&) {
515 B2ERROR("Parsing of JSON input string failed");
516 return false;
517 }
518}
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 1097 of file KLMTimeAlgorithm.cc.

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

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

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

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

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

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

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

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

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

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

◆ 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 ( 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}
void setInputFileNames(PyObject *inputFileNames)
Set the input file names used for this algorithm from a Python list.
Scalar convertPythonObject(const boost::python::object &pyObject, Scalar)
Convert from Python to given type.

◆ setInputFileNames() [2/2]

void setInputFileNames ( 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...
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.

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

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

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

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

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

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

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

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

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

◆ updateDBObjPtrs()

void updateDBObjPtrs ( const unsigned int event = 1,
const int run = 0,
const int experiment = 0 )
protectedinherited

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

Definition at line 404 of file CalibrationAlgorithm.cc.

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

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

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

◆ writeThenDelete_() [2/2]

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

Same as above, but for 2D histograms.

Definition at line 1078 of file KLMTimeAlgorithm.cc.

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

Member Data Documentation

◆ fcn_const

TF1* fcn_const = nullptr
private

Const function.

Global time distribution fitting.

Definition at line 958 of file KLMTimeAlgorithm.h.

◆ fcn_gaus

TF1* fcn_gaus = nullptr
private

Gaussian function.

Scitillator time distribution fitting.

Definition at line 961 of file KLMTimeAlgorithm.h.

◆ fcn_land

TF1* fcn_land = nullptr
private

Landau function.

RPC time distribution fitting.

Definition at line 964 of file KLMTimeAlgorithm.h.

◆ fcn_pol1

TF1* fcn_pol1 = nullptr
private

Pol1 function.

Effective light speed fitting.

Definition at line 955 of file KLMTimeAlgorithm.h.

◆ gr_timeRes_channel_rpc

TGraph* gr_timeRes_channel_rpc = nullptr
private

BKLM RPC.

Definition at line 596 of file KLMTimeAlgorithm.h.

◆ gr_timeRes_channel_scint

TGraph* gr_timeRes_channel_scint = nullptr
private

BKLM scintillator.

Definition at line 599 of file KLMTimeAlgorithm.h.

◆ gr_timeRes_channel_scint_end

TGraph* gr_timeRes_channel_scint_end = nullptr
private

EKLM.

Definition at line 602 of file KLMTimeAlgorithm.h.

◆ gr_timeShift_channel_rpc

TGraph* gr_timeShift_channel_rpc = nullptr
private

BKLM RPC.

Definition at line 585 of file KLMTimeAlgorithm.h.

◆ gr_timeShift_channel_scint

TGraph* gr_timeShift_channel_scint = nullptr
private

BKLM scintillator.

Definition at line 588 of file KLMTimeAlgorithm.h.

◆ gr_timeShift_channel_scint_end

TGraph* gr_timeShift_channel_scint_end = nullptr
private

EKLM.

Definition at line 591 of file KLMTimeAlgorithm.h.

◆ gre_ctime_channel_rpc

TGraphErrors* gre_ctime_channel_rpc = nullptr
private

BKLM RPC.

Definition at line 574 of file KLMTimeAlgorithm.h.

◆ gre_ctime_channel_scint

TGraphErrors* gre_ctime_channel_scint = nullptr
private

BKLM Scintillator.

Definition at line 577 of file KLMTimeAlgorithm.h.

◆ gre_ctime_channel_scint_end

TGraphErrors* gre_ctime_channel_scint_end = nullptr
private

EKLM.

Definition at line 580 of file KLMTimeAlgorithm.h.

◆ gre_time_channel_rpc

TGraphErrors* gre_time_channel_rpc = nullptr
private

BKLM RPC.

Definition at line 563 of file KLMTimeAlgorithm.h.

◆ gre_time_channel_scint

TGraphErrors* gre_time_channel_scint = nullptr
private

BKLM Scintillator.

Definition at line 566 of file KLMTimeAlgorithm.h.

◆ gre_time_channel_scint_end

TGraphErrors* gre_time_channel_scint_end = nullptr
private

EKLM.

Definition at line 569 of file KLMTimeAlgorithm.h.

◆ h2_deltaT0_vs_nhits_rpc

TH2F* h2_deltaT0_vs_nhits_rpc
private

DeltaT0 vs total hit count for RPC.

Definition at line 917 of file KLMTimeAlgorithm.h.

◆ h2_deltaT0_vs_nhits_scint

TH2F* h2_deltaT0_vs_nhits_scint
private

DeltaT0 vs total hit count for BKLM scintillator.

Definition at line 920 of file KLMTimeAlgorithm.h.

◆ h2_deltaT0_vs_nhits_scint_end

TH2F* h2_deltaT0_vs_nhits_scint_end
private

DeltaT0 vs total hit count for EKLM scintillator.

Definition at line 923 of file KLMTimeAlgorithm.h.

◆ h2_deltaT0_vs_v_rpc

TH2F* h2_deltaT0_vs_v_rpc
private

DeltaT0 vs inverse hit count for RPC.

Definition at line 899 of file KLMTimeAlgorithm.h.

◆ h2_deltaT0_vs_v_scint

TH2F* h2_deltaT0_vs_v_scint
private

DeltaT0 vs inverse hit count for BKLM scintillator.

Definition at line 902 of file KLMTimeAlgorithm.h.

◆ h2_deltaT0_vs_v_scint_end

TH2F* h2_deltaT0_vs_v_scint_end
private

DeltaT0 vs inverse hit count for EKLM scintillator.

Definition at line 905 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 863 of file KLMTimeAlgorithm.h.

◆ h_eventT0_scint

TH1F* h_eventT0_scint = nullptr
private

EventT0 seen by BKLM scintillator hits.

Definition at line 866 of file KLMTimeAlgorithm.h.

◆ h_eventT0_scint_end

TH1F* h_eventT0_scint_end = nullptr
private

EventT0 seen by EKLM scintillator hits.

Definition at line 869 of file KLMTimeAlgorithm.h.

◆ h_nHits_minus_rpc

TH1F* h_nHits_minus_rpc
private

Number of RPC hits per mu- track.

Definition at line 884 of file KLMTimeAlgorithm.h.

◆ h_nHits_minus_scint

TH1F* h_nHits_minus_scint
private

Number of BKLM scintillator hits per mu- track.

Definition at line 890 of file KLMTimeAlgorithm.h.

◆ h_nHits_minus_scint_end

TH1F* h_nHits_minus_scint_end
private

Number of EKLM scintillator hits per mu- track.

Definition at line 896 of file KLMTimeAlgorithm.h.

◆ h_nHits_plus_rpc

TH1F* h_nHits_plus_rpc
private

Number of RPC hits per mu+ track.

Definition at line 881 of file KLMTimeAlgorithm.h.

◆ h_nHits_plus_scint

TH1F* h_nHits_plus_scint
private

Number of BKLM scintillator hits per mu+ track.

Definition at line 887 of file KLMTimeAlgorithm.h.

◆ h_nHits_plus_scint_end

TH1F* h_nHits_plus_scint_end
private

Number of EKLM scintillator hits per mu+ track.

Definition at line 893 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_timeFSLPC

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

BKLM part.

Definition at line 840 of file KLMTimeAlgorithm.h.

840{{{{{nullptr}}}}};

◆ h_timeFSLPC_end

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

EKLM part.

Definition at line 849 of file KLMTimeAlgorithm.h.

849{{{{{nullptr}}}}};

◆ h_timeFSLPC_tc

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

BKLM part, used for effective light speed estimation.

Definition at line 837 of file KLMTimeAlgorithm.h.

837{{{{{nullptr}}}}};

◆ h_timeFSLPC_tc_end

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

EKLM part, used for effective light speed estimation.

Definition at line 846 of file KLMTimeAlgorithm.h.

846{{{{{nullptr}}}}};

◆ hc_calibrated

TH1I* hc_calibrated = nullptr
private

Calibration statistics for each channel.

Definition at line 555 of file KLMTimeAlgorithm.h.

◆ hc_eventT0_rpc

TH1F* hc_eventT0_rpc = nullptr
private

Corrected EventT0 for RPC hits.

Definition at line 872 of file KLMTimeAlgorithm.h.

◆ hc_eventT0_rpc_highN

TH1F* hc_eventT0_rpc_highN
private

Corrected EventT0 for RPC with high hit count.

Definition at line 932 of file KLMTimeAlgorithm.h.

◆ hc_eventT0_rpc_lowN

TH1F* hc_eventT0_rpc_lowN
private

Corrected EventT0 for RPC with low hit count.

Definition at line 926 of file KLMTimeAlgorithm.h.

◆ hc_eventT0_rpc_midN

TH1F* hc_eventT0_rpc_midN
private

Corrected EventT0 for RPC with medium hit count.

Definition at line 929 of file KLMTimeAlgorithm.h.

◆ hc_eventT0_scint

TH1F* hc_eventT0_scint = nullptr
private

Corrected EventT0 for BKLM scintillator hits.

Definition at line 875 of file KLMTimeAlgorithm.h.

◆ hc_eventT0_scint_end

TH1F* hc_eventT0_scint_end = nullptr
private

Corrected EventT0 for EKLM scintillator hits.

Definition at line 878 of file KLMTimeAlgorithm.h.

◆ hc_eventT0_scint_end_highN

TH1F* hc_eventT0_scint_end_highN
private

Corrected EventT0 for EKLM scintillator with high hit count.

Definition at line 950 of file KLMTimeAlgorithm.h.

◆ hc_eventT0_scint_end_lowN

TH1F* hc_eventT0_scint_end_lowN
private

Corrected EventT0 for EKLM scintillator with low hit count.

Definition at line 944 of file KLMTimeAlgorithm.h.

◆ hc_eventT0_scint_end_midN

TH1F* hc_eventT0_scint_end_midN
private

Corrected EventT0 for EKLM scintillator with medium hit count.

Definition at line 947 of file KLMTimeAlgorithm.h.

◆ hc_eventT0_scint_highN

TH1F* hc_eventT0_scint_highN
private

Corrected EventT0 for BKLM scintillator with high hit count.

Definition at line 941 of file KLMTimeAlgorithm.h.

◆ hc_eventT0_scint_lowN

TH1F* hc_eventT0_scint_lowN
private

Corrected EventT0 for BKLM scintillator with low hit count.

Definition at line 935 of file KLMTimeAlgorithm.h.

◆ hc_eventT0_scint_midN

TH1F* hc_eventT0_scint_midN
private

Corrected EventT0 for BKLM scintillator with medium hit count.

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

◆ hc_timeFSLPC

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

BKLM part.

Definition at line 857 of file KLMTimeAlgorithm.h.

857{{{{{nullptr}}}}};

◆ hc_timeFSLPC_end

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

EKLM part.

Definition at line 860 of file KLMTimeAlgorithm.h.

860{{{{{nullptr}}}}};

◆ m_allExpRun

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

allExpRun

Definition at line 364 of file CalibrationAlgorithm.h.

◆ m_applyChargeRestriction

bool m_applyChargeRestriction = false
private

Whether to apply ADC/charge restriction cuts for scintillators.

Definition at line 549 of file KLMTimeAlgorithm.h.

◆ m_BKLMGeometry

const bklm::GeometryPar* m_BKLMGeometry = nullptr
private

BKLM geometry data.

Definition at line 513 of file KLMTimeAlgorithm.h.

◆ m_boundaries

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

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

Definition at line 261 of file CalibrationAlgorithm.h.

◆ m_cFlag

std::map<KLMChannelNumber, int> m_cFlag
private

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

Definition at line 387 of file KLMTimeAlgorithm.h.

◆ m_channelHistDir_BKLM

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

Directory structure for per-channel histograms (BKLM).

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

Definition at line 979 of file KLMTimeAlgorithm.h.

979{};

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

985{};

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

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

Two-dimensional distributions of time versus propagation length.

Definition at line 843 of file KLMTimeAlgorithm.h.

843{{{{{nullptr}}}}};

◆ m_HistTimeLengthEKLM

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

Two-dimensional distributions of time versus propagation length.

Definition at line 852 of file KLMTimeAlgorithm.h.

852{{{{{nullptr}}}}};

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

◆ m_time_channel

std::map<KLMChannelNumber, double> m_time_channel
private

Time distribution central value of each channel.

Definition at line 396 of file KLMTimeAlgorithm.h.

◆ m_time_channelAvg_rpc

double m_time_channelAvg_rpc = 0.0
private

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

Definition at line 460 of file KLMTimeAlgorithm.h.

◆ m_time_channelAvg_scint

double m_time_channelAvg_scint = 0.0
private

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

Definition at line 467 of file KLMTimeAlgorithm.h.

◆ m_time_channelAvg_scint_end

double m_time_channelAvg_scint_end = 0.0
private

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

Definition at line 475 of file KLMTimeAlgorithm.h.

◆ m_timeCableDelay

KLMTimeCableDelay* m_timeCableDelay = nullptr
private

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

Definition at line 531 of file KLMTimeAlgorithm.h.

◆ m_timeConstants

KLMTimeConstants* m_timeConstants = nullptr
private

DBObject of time cost on some parts of the detector.

Definition at line 525 of file KLMTimeAlgorithm.h.

◆ m_timeRes

std::map<KLMChannelNumber, double> m_timeRes
private

Resolution values of each channel.

Definition at line 393 of file KLMTimeAlgorithm.h.

◆ m_timeResolution

KLMTimeResolution* m_timeResolution = nullptr
private

DBObject of time resolution.

Definition at line 534 of file KLMTimeAlgorithm.h.

◆ m_timeShift

std::map<KLMChannelNumber, double> m_timeShift
private

Shift values of each channel.

Definition at line 390 of file KLMTimeAlgorithm.h.

◆ m_UpperTimeBoundaryCalibratedRPC

double m_UpperTimeBoundaryCalibratedRPC = 40.0
private

Upper time boundary for RPC (calibrated data).

Definition at line 429 of file KLMTimeAlgorithm.h.

◆ m_UpperTimeBoundaryCalibratedScintillatorsBKLM

double m_UpperTimeBoundaryCalibratedScintillatorsBKLM = 40.0
private

Upper time boundary for BKLM scintillators (calibrated data).

Definition at line 451 of file KLMTimeAlgorithm.h.

◆ m_UpperTimeBoundaryCalibratedScintillatorsEKLM

double m_UpperTimeBoundaryCalibratedScintillatorsEKLM = 40.0
private

Upper time boundary for BKLM scintillators (calibrated data).

Definition at line 457 of file KLMTimeAlgorithm.h.

◆ m_UpperTimeBoundaryRPC

double m_UpperTimeBoundaryRPC = 10.0
private

Upper time boundary for RPC.

Definition at line 411 of file KLMTimeAlgorithm.h.

◆ m_UpperTimeBoundaryScintillatorsBKLM

double m_UpperTimeBoundaryScintillatorsBKLM = 70.0
private

Upper time boundary for BKLM scintillators.

Definition at line 417 of file KLMTimeAlgorithm.h.

◆ m_UpperTimeBoundaryScintillatorsEKLM

double m_UpperTimeBoundaryScintillatorsEKLM = 70.0
private

Upper time boundary for BKLM scintillators.

Definition at line 423 of file KLMTimeAlgorithm.h.

◆ m_useEventT0

bool m_useEventT0 = true
private

Whether to use event T0 from CDC.

Definition at line 546 of file KLMTimeAlgorithm.h.

◆ m_useFixedRPCDelay

bool m_useFixedRPCDelay = false
private

Whether to use fixed propagation delay for RPCs.

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

Definition at line 438 of file KLMTimeAlgorithm.h.

◆ mc_etime_channel

std::map<KLMChannelNumber, double> mc_etime_channel
private

Calibrated time distribution central value Error of each channel.

Definition at line 405 of file KLMTimeAlgorithm.h.

◆ mc_etime_channelAvg_rpc

double mc_etime_channelAvg_rpc = 0.0
private

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

Definition at line 485 of file KLMTimeAlgorithm.h.

◆ mc_etime_channelAvg_scint

double mc_etime_channelAvg_scint = 0.0
private

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

Definition at line 493 of file KLMTimeAlgorithm.h.

◆ mc_etime_channelAvg_scint_end

double mc_etime_channelAvg_scint_end = 0.0
private

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

Definition at line 501 of file KLMTimeAlgorithm.h.

◆ prof_deltaT0_rms_vs_v_rpc

TProfile* prof_deltaT0_rms_vs_v_rpc
private

DeltaT0 RMS vs inverse hit count profile for RPC.

Definition at line 908 of file KLMTimeAlgorithm.h.

◆ prof_deltaT0_rms_vs_v_scint

TProfile* prof_deltaT0_rms_vs_v_scint
private

DeltaT0 RMS vs inverse hit count profile for BKLM scintillator.

Definition at line 911 of file KLMTimeAlgorithm.h.

◆ prof_deltaT0_rms_vs_v_scint_end

TProfile* prof_deltaT0_rms_vs_v_scint_end
private

DeltaT0 RMS vs inverse hit count profile for EKLM scintillator.

Definition at line 914 of file KLMTimeAlgorithm.h.


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