Belle II Software development
top modules

Classes

class  TOPAlignmentCollectorModule
 Collector for geometrical alignment of a TOP module with dimuons or Bhabhas. More...
 
class  TOPAsicShiftsBS13dCollectorModule
 Collector for carrier shifts of BS13d. More...
 
class  TOPChannelMaskCollectorModule
 Collector for preparing masks of hot and dead channels. More...
 
class  TOPCommonT0BFCollectorModule
 Collector for common T0 calibration with a fit of bunch finder residuals (method BF) More...
 
class  TOPCommonT0LLCollectorModule
 Collector for common T0 calibration with neg. More...
 
class  TOPModuleT0DeltaTCollectorModule
 Collector for module T0 calibration with chi2 minimization of time differences between slots (method DeltaT). More...
 
class  TOPModuleT0LLCollectorModule
 Collector for module T0 calibration with neg. More...
 
class  TOPOffsetCollectorModule
 Collector for eventT0 and fill pattern offset calibrations. More...
 
class  TOPPhotonYieldsCollectorModule
 Collector for photon pixel yields aimed for PMT ageing studies and for finding optically decoupled PMT's. More...
 
class  TOPPulseHeightCollectorModule
 Collector for channel pulse-height distributions. More...
 
class  TOPValidationCollectorModule
 Collector for automatic validation of calibration with dimuon events. More...
 
class  OpticalGunModule
 Source of optical photons for the simulation of the TOP laser system. More...
 
class  TOPAlignerModule
 Alignment of TOP. More...
 
class  TOPBackgroundModule
 TOP background module. More...
 
class  TOPBunchFinderModule
 Bunch finder: searches for the bunch crossing where the interaction happened using track-based TOP likelihood. More...
 
class  TOPChannelMaskerModule
 Masks dead PMs from the reconstruction. More...
 
class  TOPChannelT0CalibratorModule
 A module for alternative channel T0 calibration with collision data Note: after this kind of calibration one cannot do the geometrical alignment This module can also be used to check the calibration. More...
 
class  TOPChannelT0MCModule
 TOP Channel T0 MC Extraction module (under development) More...
 
class  TOPCommonT0CalibratorModule
 A module for common T0 calibration with collision data (dimuons or bhabhas) More...
 
class  TOPCosmicT0FinderModule
 Event T0 finder for global cosmic runs. More...
 
class  TOPDigitizerModule
 TOP digitizer. More...
 
class  TOPTriggerDigitizerModule
 Digitizer that provides time stamps for TOP trigger. More...
 
class  TOPCalPulseGeneratorModule
 Generator of calibration pulses Output to TOPSimCalPulses. More...
 
class  TOPDoublePulseGeneratorModule
 Generator of double calibration pulses Output to TOPDigits. More...
 
class  TOPDQMModule
 TOP DQM histogrammer. More...
 
class  TOPGainEfficiencyCalculatorModule
 Module for channel-by-channel gain/efficiency analysis. More...
 
class  TOPLaserHitSelectorModule
 Module for pixel-by-pixel gain/efficiency analysis. More...
 
class  TOPGeometryParInitializerModule
 Class for initializing TOPGeometryPar. More...
 
class  TOPInterimFENtupleModule
 Module to produce ntuple from TOPDigits and TOPRawDigits. More...
 
class  TOPLaserCalibratorModule
 T0 Laser calibration module (under development) More...
 
class  TOPLaserCalibratorCollectorModule
 Collector module for the TOP channelT0 calibration and, more in general, for the time resolution studies using the laser and pulser data. More...
 
class  TOPLLScannerModule
 A module to perform the TOP PID likelihood scan and find the actual minimum as function of the mass. More...
 
class  TOPMCTrackMakerModule
 Constructs Tracks and ExtHits from MCParticles and TOPBarHits Utility needed for testing and debugging of TOP reconstruction. More...
 
class  TOPModuleT0CalibratorModule
 A module for module T0 calibration with collision data (dimuons or bhabhas) Useful when the geometrical alignment need not to be repeated. More...
 
class  TOPNtupleModule
 Module to write out a ntuple summarizing TOP reconstruction output. More...
 
class  TOPPackerModule
 Raw data packer. More...
 
class  TOPPDFCheckerModule
 Module for checking analytic PDF used in likelihood calculation. More...
 
class  TOPPDFDebuggerModule
 TOP reconstruction module. More...
 
class  TOPRawDigitConverterModule
 TOPRawDigits to TOPDigits converter. More...
 
class  TOPReconstructorModule
 TOP reconstruction module. More...
 
class  TOPRingPlotterModule
 A module to plot the x-t images from TOP, and in general study the distribution of the digits associated to the particles in a particleList. More...
 
class  TOPTBCComparatorModule
 Module for the comparison of different sets of time base correction (TBC) constants and to produce monitoring plots out of a given set. More...
 
struct  Hit
 Structure to hold some of the calpulse data. More...
 
struct  TwoTimes
 Structure to hold calpulse raw times expressed in samples since sample 0 of window 0. More...
 
class  TOPTimeBaseCalibratorModule
 Time base calibrator. More...
 
class  TOPTimeRecalibratorModule
 Utility module for re-calibrating time of TOPDigits pulseWidth and timeError are not changed although they may depend no calibration! More...
 
class  TOPUnpackerModule
 Raw data unpacker. More...
 
class  TOPWaveformFeatureExtractorModule
 Waveform feature extractor: module adds rawDigits that are found in waveforms by feature extraction but are not already present in RawDigits. More...
 
class  TOPWaveformQualityPlotterModule
 Plots and histograms of waveforms and feature extracted parameters. More...
 
class  TOPXTalkChargeShareSetterModule
 Crosstalk & chargeshare flag setter. More...
 

Enumerations

enum  {
  c_NChannelPerAsic = 8 ,
  c_NModule = 16 ,
  c_NChannelPerPMT = 16 ,
  c_NChannelPerPMTRow = 4 ,
  c_NPMTPerRow = 16 ,
  c_NPMTPerModule = 32 ,
  c_NPixelPerRow = 64 ,
  c_NPixelPerModule = 512
}
 enum for maximum number of array elements (# of hits per event) More...
 

Functions

 REG_MODULE (TOPAlignmentCollector)
 Register module.
 
 REG_MODULE (TOPAsicShiftsBS13dCollector)
 Register module.
 
 REG_MODULE (TOPChannelMaskCollector)
 Register module.
 
 REG_MODULE (TOPCommonT0BFCollector)
 Register module.
 
 REG_MODULE (TOPCommonT0LLCollector)
 Register module.
 
 REG_MODULE (TOPModuleT0DeltaTCollector)
 Register module.
 
 REG_MODULE (TOPModuleT0LLCollector)
 Register module.
 
 REG_MODULE (TOPOffsetCollector)
 Register module.
 
 REG_MODULE (TOPPhotonYieldsCollector)
 Register module.
 
 REG_MODULE (TOPPulseHeightCollector)
 Register module.
 
 REG_MODULE (TOPValidationCollector)
 Register module.
 
 REG_MODULE (OpticalGun)
 Register module.
 
 REG_MODULE (TOPAligner)
 Register module.
 
 REG_MODULE (TOPBackground)
 Register the Module.
 
 REG_MODULE (TOPBunchFinder)
 Register module.
 
 REG_MODULE (TOPChannelMasker)
 Register the Module.
 
 REG_MODULE (TOPChannelT0Calibrator)
 Register module.
 
 REG_MODULE (TOPChannelT0MC)
 Register module.
 
 REG_MODULE (TOPCommonT0Calibrator)
 Register module.
 
 REG_MODULE (TOPCosmicT0Finder)
 Register module.
 
 REG_MODULE (TOPDigitizer)
 Register the Module.
 
 REG_MODULE (TOPTriggerDigitizer)
 Register the Module.
 
 REG_MODULE (TOPCalPulseGenerator)
 Register module.
 
 REG_MODULE (TOPDoublePulseGenerator)
 Register module.
 
 REG_MODULE (TOPDQM)
 Register module.
 
 REG_MODULE (TOPGainEfficiencyCalculator)
 Register the Module.
 
 REG_MODULE (TOPLaserHitSelector)
 Register the Module.
 
 REG_MODULE (TOPGeometryParInitializer)
 Register module.
 
 REG_MODULE (TOPInterimFENtuple)
 Register module.
 
 REG_MODULE (TOPLaserCalibrator)
 Register module.
 
 REG_MODULE (TOPMCTrackMaker)
 Register module.
 
 REG_MODULE (TOPModuleT0Calibrator)
 Register module.
 
 REG_MODULE (TOPNtuple)
 Register module.
 
 REG_MODULE (TOPPacker)
 Register module.
 
 REG_MODULE (TOPPDFChecker)
 Register module.
 
 REG_MODULE (TOPPDFDebugger)
 Register the Module.
 
 REG_MODULE (TOPRawDigitConverter)
 Register module.
 
 REG_MODULE (TOPReconstructor)
 Register the Module.
 
 REG_MODULE (TOPTBCComparator)
 Register module.
 
 REG_MODULE (TOPTimeBaseCalibrator)
 Register module.
 
 REG_MODULE (TOPTimeRecalibrator)
 Register module.
 
 REG_MODULE (TOPUnpacker)
 Register module.
 
 REG_MODULE (TOPWaveformFeatureExtractor)
 Register module.
 
 REG_MODULE (TOPWaveformQualityPlotter)
 Register module.
 
 TOPAlignmentCollectorModule ()
 Constructor.
 
virtual void prepare () final
 Replacement for initialize().
 
virtual void collect () final
 Replacement for event().
 
 TOPAsicShiftsBS13dCollectorModule ()
 Constructor.
 
virtual void prepare () final
 Replacement for initialize().
 
virtual void collect () final
 Replacement for event().
 
 TOPChannelMaskCollectorModule ()
 Constructor.
 
virtual void prepare () final
 Replacement for initialize().
 
virtual void collect () final
 Replacement for event().
 
 TOPCommonT0BFCollectorModule ()
 Constructor.
 
virtual void prepare () final
 Replacement for initialize().
 
virtual void collect () final
 Replacement for event().
 
 TOPCommonT0LLCollectorModule ()
 Constructor.
 
virtual void prepare () final
 Replacement for initialize().
 
virtual void collect () final
 Replacement for event().
 
 TOPModuleT0DeltaTCollectorModule ()
 Constructor.
 
virtual void prepare () final
 Replacement for initialize().
 
virtual void collect () final
 Replacement for event().
 
 TOPModuleT0LLCollectorModule ()
 Constructor.
 
virtual void prepare () final
 Replacement for initialize().
 
virtual void collect () final
 Replacement for event().
 
 TOPOffsetCollectorModule ()
 Constructor.
 
virtual void prepare () final
 Replacement for initialize().
 
virtual void startRun () final
 Replacement for beginRun().
 
virtual void collect () final
 Replacement for event().
 
 TOPPhotonYieldsCollectorModule ()
 Constructor.
 
virtual void prepare () final
 Replacement for initialize().
 
virtual void collect () final
 Replacement for event().
 
 TOPPulseHeightCollectorModule ()
 Constructor.
 
virtual void prepare () final
 Replacement for initialize().
 
virtual void collect () final
 Replacement for event().
 
 TOPValidationCollectorModule ()
 Constructor.
 
virtual void prepare () final
 Replacement for initialize().
 
virtual void startRun () final
 Replacement for beginRun().
 
virtual void collect () final
 Replacement for event().
 
virtual void closeRun () final
 Replacement for endRun().
 
 OpticalGunModule ()
 Constructor.
 
virtual void initialize () override
 Initialize the Module.
 
virtual void event () override
 Event processor.
 
bool isInsideSlit (const ROOT::Math::XYZPoint &point, const ROOT::Math::XYZVector &direction) const
 Checks if photon passes the slit.
 
ROOT::Math::XYZVector getDirectionGaussian () const
 Return photon direction according to a projected 2D gaussian distribution based on numerical aperture NA.
 
ROOT::Math::XYZVector getDirectionUniform () const
 Return photon direction according to a projected uniform distribution with opening angle alpha.
 
ROOT::Math::XYZVector getDirectionLambertian () const
 Return photon direction according to a lambertian distribution with opening angle alpha.
 
ROOT::Math::XYZVector getDirectionCustom () const
 Return photon direction according to a custom angular distribution given by TFormula.
 
 TOPAlignerModule ()
 Constructor.
 
virtual void initialize () override
 Initialize the Module.
 
virtual void event () override
 Event processor.
 
virtual void terminate () override
 Termination action.
 
 TOPBackgroundModule ()
 Constructor.
 
virtual void initialize () override
 Initialize the Module.
 
virtual void beginRun () override
 Called when entering a new run.
 
virtual void event () override
 Event processor.
 
void myprint (TH1F *histo, const char *path, const char *xtit, const char *ytit, double tresh)
 Print histogram 1D, helper function.
 
virtual void endRun () override
 End-of-run action.
 
virtual void terminate () override
 Termination action.
 
 TOPBunchFinderModule ()
 Constructor.
 
virtual void initialize () override
 Initialize the Module.
 
virtual void beginRun () override
 Called when entering a new run.
 
virtual void event () override
 Event processor.
 
virtual void terminate () override
 Termination action.
 
Const::ChargedStable getMostProbable (const Track &track)
 Returns most probable charged stable particle according to dEdx and predefined prior probabilities.
 
int setFinder (TOP::Chi2MinimumFinder1D &finder, const TOP::PDFConstructor &reco, double timeMin, double timeMax)
 Sets finder object with chi2 values.
 
TimeSeed getTimeSeed ()
 Returns a time seed.
 
bool isBucketFilled (int bunchNo)
 Does reconstructed bunch number correspond to filled bucket.
 
 TOPChannelMaskerModule ()
 Constructor: Sets the description of the module.
 
virtual void initialize () override
 initialize method: registers datastore objects (the TOP hits)
 
virtual void beginRun () override
 Called when entering a new run.
 
virtual void event () override
 event method: removes channels from the reconstruction pdf, flags hits from noisy channels as junk
 
 TOPChannelT0CalibratorModule ()
 Constructor.
 
virtual void initialize () override
 Initialize the Module.
 
virtual void event () override
 Event processor.
 
virtual void terminate () override
 Termination action.
 
 TOPChannelT0MCModule ()
 Constructor.
 
virtual void initialize () override
 Initialize the Module.
 
virtual void event () override
 Event processor.
 
virtual void terminate () override
 Termination action.
 
 TOPCommonT0CalibratorModule ()
 Constructor.
 
virtual void initialize () override
 Initialize the Module.
 
virtual void event () override
 Event processor.
 
virtual void terminate () override
 Termination action.
 
bool isRunningOffsetSubtracted ()
 Checks if running offset is subtracted in TOPDigits.
 
 TOPCosmicT0FinderModule ()
 Constructor.
 
virtual void initialize () override
 Initialize the Module.
 
virtual void event () override
 Event processor.
 
virtual void terminate () override
 Termination action.
 
 TOPDigitizerModule ()
 Constructor.
 
virtual void initialize () override
 Initialize the Module.
 
virtual void beginRun () override
 Called when entering a new run.
 
virtual void event () override
 Event processor.
 
TimeOffset getTimeOffset (double trgOffset, int moduleID, int pixelID, bool generate=false)
 Returns a complete time offset by adding time mis-calibration to trgOffset.
 
double generatePulseHeight (int moduleID, int pixelID) const
 Generates and returns pulse height.
 
 TOPTriggerDigitizerModule ()
 Constructor.
 
virtual void initialize () override
 Initialize the Module.
 
virtual void event () override
 Event processor.
 
 TOPCalPulseGeneratorModule ()
 Constructor.
 
virtual void initialize () override
 Initialize the Module.
 
virtual void event () override
 Event processor.
 
 TOPDoublePulseGeneratorModule ()
 Constructor.
 
virtual void initialize () override
 Initialize the Module.
 
virtual void beginRun () override
 Called when entering a new run.
 
virtual void event () override
 Event processor.
 
void storeSampleTimes (const std::string &fileName)
 Optionally store sample times used by the generator as root histograms fileName root output file name.
 
static void saveAsHistogram (const std::vector< double > &vec, const std::string &name, const std::string &title, const std::string &xTitle="", const std::string &yTitle="")
 Save vector to histogram and write it out.
 
 TOPDQMModule ()
 Constructor.
 
virtual void defineHisto () override
 Histogram definitions such as TH1(), TH2(), TNtuple(), TTree()....
 
virtual void initialize () override
 Initialize the Module.
 
virtual void beginRun () override
 Called when entering a new run.
 
virtual void event () override
 Event processor.
 
int getModuleID (const Track &track) const
 Returns slot ID of the module that is hit by the track.
 
 TOPGainEfficiencyCalculatorModule ()
 Constructor.
 
virtual void initialize () override
 Load time vs charge 2D histogram from a given input file (parameter "inputFile") and prepare hit timing and pulse charge distribution for each channel.
 
virtual void defineHisto () override
 Define TTree branches to store fit results for each channel This TTree is saved in an output file given by "histoFileName" parameter of "HistoManager" module.
 
virtual void terminate () override
 Termination action.
 
void LoadHistograms (const std::string &histotype)
 Load 2D histograms from a given input file (output of TOPLaserHitSelector) and create timing and charge distribution as projection histograms for the x- and y-axis, respectively.
 
void FitHistograms (EHistogramType LoadHisto)
 Fit charge (or integrated charged) distribution to calculate gain and efficiency for each channel.
 
void DummyFillBranch (EHistogramType LoadHisto)
 Fill Dummy for Branch.
 
void DrawResult (const std::string &histotype, EHistogramType LoadHisto)
 Draw results of gain/efficiency calculation for each channel to a given output file.
 
static double TOPGainFunc (double *var, double *par)
 Fit function of pulse charge (or charge) distribution for channel(pixel)-by-channel gain extraction, given by "[0]*pow(x-[4],[1])*exp(-pow(x-[4],[2])/[3])" smeared by Gaussian with a constant sigma to consider baseline fluctuation.
 
static double FindPeakForSmallerXThan (TH1 *histo, double xmax=0)
 Find peak and return its position for a limited range of x (x smaller than the given value (xmax))
 
 TOPLaserHitSelectorModule ()
 Constructor.
 
virtual void initialize () override
 Initialize the Module.
 
virtual void defineHisto () override
 create timing-height 2D histograms for all 8192 pixels
 
virtual void event () override
 Event processor.
 
 TOPGeometryParInitializerModule ()
 Constructor.
 
virtual void initialize () override
 Initialize the Module.
 
 TOPInterimFENtupleModule ()
 Constructor.
 
virtual void initialize () override
 Initialize the Module.
 
virtual void defineHisto () override
 Module functions to define histograms.
 
virtual void event () override
 Event processor.
 
void getReferenceTiming ()
 Find reference timing.
 
 TOPLaserCalibratorModule ()
 Constructor.
 
virtual void initialize () override
 Initialize the Module.
 
virtual void event () override
 Event processor.
 
virtual void terminate () override
 Termination action.
 
 TOPMCTrackMakerModule ()
 Constructor.
 
virtual void initialize () override
 Initialize the Module.
 
virtual void event () override
 Event processor.
 
 TOPModuleT0CalibratorModule ()
 Constructor.
 
virtual void initialize () override
 Initialize the Module.
 
virtual void beginRun () override
 Called when entering a new run.
 
virtual void event () override
 Event processor.
 
virtual void terminate () override
 Termination action.
 
bool isRunningOffsetSubtracted ()
 Checks if running offset is subtracted in TOPDigits.
 
 TOPNtupleModule ()
 Constructor.
 
virtual void initialize () override
 Initialize the Module.
 
virtual void event () override
 Event processor.
 
virtual void terminate () override
 Termination action.
 
 TOPPackerModule ()
 Constructor.
 
virtual void initialize () override
 Initialize the Module.
 
virtual void event () override
 Event processor.
 
void packProductionDraft ()
 Pack in format: c_Draft (tentative production format) this format was never implemented in firmware!
 
void packType0Ver16 ()
 Pack in format: c_Type0Ver16 (Feature-extracted data) this format was never implemented in firmware!
 
void packProductionDebug ()
 Pack in format: Production Debugging Data Format 01.
 
 TOPPDFCheckerModule ()
 Constructor.
 
virtual void defineHisto () override
 Histogram definitions such as TH1(), TH2(), TNtuple(), TTree()....
 
virtual void initialize () override
 Initialize the Module.
 
virtual void event () override
 Event processor.
 
virtual void terminate () override
 Termination action.
 
bool isFromThisParticle (const TOPDigit &digit, const MCParticle *particle)
 Checks if digit comes from given MC particle.
 
 TOPPDFDebuggerModule ()
 Constructor.
 
virtual void initialize () override
 Initialize the Module.
 
virtual void event () override
 Event processor.
 
void associatePDFPeaks (const TOP::PDFConstructor &pdfConstructor)
 Associate PDF peaks with photons using S-plot technique.
 
 TOPRawDigitConverterModule ()
 Constructor.
 
virtual void initialize () override
 Initialize the Module.
 
virtual void beginRun () override
 Called when entering a new run.
 
virtual void event () override
 Event processor.
 
 TOPReconstructorModule ()
 Constructor.
 
virtual void initialize () override
 Initialize the Module.
 
virtual void event () override
 Event processor.
 
 TOPTBCComparatorModule ()
 Constructor.
 
void defineHisto () override
 Defining the histograms.
 
int analyzeCalFile ()
 Analyzes the calibrations stored in the file m_calSetFile.
 
int makeComparisons ()
 Last function to be called, compared the histograms of different datasets filled by analyzeCalFile() Every new comparison histogram added to the module has to be filled here.
 
void initialize () override
 Initialize the module.
 
void endRun () override
 End-of-run action.
 
void terminate () override
 Termination action.
 
int parseInputDirectoryLine (const std::string &)
 Utility function to get the directory name and the label from a line of the m_inputDirectoryList file Sets the values of m_calSetDirectory and m_calSetLabel.
 
int parseSlotAndScrodIDfromFileName (const std::string &)
 Utility function to parse the slot and BS id from the calibration file names.
 
TH1F * calculateHistoRatio (TH1F *, TH1F *, TH1F *)
 Utility function to take the ratio of two histograms using TH1::Divide(), without overwriting the output name and title initialized in defineHisto().
 
TH2F * calculateHistoRatio (TH2F *, TH2F *, TH2F *)
 Utility function to take the ratio of two histograms using TH2::Divide(), without overwriting the output name and title initialized in defineHisto().
 
 TOPTimeBaseCalibratorModule ()
 Constructor.
 
virtual void initialize () override
 Initialize the Module.
 
virtual void event () override
 Event processor.
 
virtual void terminate () override
 Termination action.
 
bool calibrateChannel (std::vector< TwoTimes > &ntuple, unsigned scrodID, unsigned scrodChannel, TH1F &Hchi2, TH1F &Hndf, TH1F &HDeltaT)
 calibrate single channel
 
bool matrixInversion (const std::vector< TwoTimes > &ntuple, unsigned scrodID, unsigned scrodChannel, double meanTimeDifference, TH1F &Hchi2, TH1F &Hndf, TH1F &HDeltaT)
 Method by matrix inversion.
 
bool iterativeTBC (const std::vector< TwoTimes > &ntuple, unsigned scrodID, unsigned scrodChannel, double meanTimeDifference, TH1F &Hchi2, TH1F &Hndf, TH1F &HDeltaT)
 Method by iteration of chi2 minimization.
 
void Iteration (const std::vector< TwoTimes > &ntuple, std::vector< double > &xval)
 Iteration function called by iterativeTBC()
 
double Chisq (const std::vector< TwoTimes > &ntuple, const std::vector< double > &xxval)
 Return the chisqure of one set of TBC constants (xval) in iTBC calculation.
 
static void saveAsHistogram (const std::vector< double > &vec, const std::string &name, const std::string &title, const std::string &xTitle="", const std::string &yTitle="")
 Save vector to histogram and write it out.
 
static void saveAsHistogram (const std::vector< double > &vec, const std::vector< double > &err, const std::string &name, const std::string &title, const std::string &xTitle="", const std::string &yTitle="")
 Save vector and errors to histogram and write it out.
 
static void saveAsHistogram (const TMatrixDSym &M, const std::string &name, const std::string &title)
 Save matrix to histogram and write it out.
 
 TOPTimeRecalibratorModule ()
 Constructor.
 
virtual void initialize () override
 Initialize the Module.
 
virtual void beginRun () override
 Called when entering a new run.
 
virtual void event () override
 Event processor.
 
 TOPUnpackerModule ()
 Constructor.
 
virtual void initialize () override
 Initialize the Module.
 
virtual void beginRun () override
 Called when entering a new run.
 
virtual void event () override
 Event processor.
 
static std::string getFrontEndName (RawTOP &raw, int finesse)
 Returns the name of the front-end.
 
bool printTheError ()
 Error messages suppression logic.
 
void unpackProductionDraft (const int *buffer, int bufferSize)
 Unpack raw data given in a tentative production format (will vanish in future)
 
void unpackType0Ver16 (const int *buffer, int bufferSize)
 Unpack raw data given in feature-extraction production format.
 
static bool unpackHeadersInterimFEVer01 (const int *buffer, int bufferSize, bool swapBytes)
 Tries to unpack raw data assuming it is in feature-extraction interim format.
 
int unpackInterimFEVer01 (const int *buffer, int bufferSize, bool pedestalSubtracted)
 Unpack raw data given in feature-extraction interim format.
 
int unpackProdDebug (const int *buffer, int bufferSize, TOP::RawDataType dataFormat, bool pedestalSubtracted, int expNo)
 Unpack raw data given in production debugging format.
 
virtual void endRun () override
 End-of-run action.
 
 TOPWaveformFeatureExtractorModule ()
 Constructor.
 
virtual void initialize () override
 Initialize the Module.
 
virtual void event () override
 Event processor.
 
 TOPWaveformQualityPlotterModule ()
 Constructor.
 
void defineHisto () override
 Books the empty histograms.
 
void initialize () override
 Module initialization, calls defineHisto and gets waveform.
 
void basicDebuggingPlots (const TOPRawWaveform &rawwave)
 Fills the debugging 1D histograms and hitmaps.
 
void drawWaveforms (const TOPRawWaveform &rawwave)
 Draws the full waveforms onto the TProfiles.
 
void event () override
 Event processor.
 
void endRun () override
 End-of-run action.
 

Detailed Description

Enumeration Type Documentation

◆ anonymous enum

anonymous enum

enum for maximum number of array elements (# of hits per event)

Definition at line 24 of file TOPLaserHitSelectorModule.h.

24 { c_NChannelPerAsic = 8, c_NModule = 16, c_NChannelPerPMT = 16,
25 c_NChannelPerPMTRow = 4, c_NPMTPerRow = 16,
26 c_NPMTPerModule = 32, c_NPixelPerRow = 64, c_NPixelPerModule = 512
27 };

Function Documentation

◆ analyzeCalFile()

int analyzeCalFile ( )

Analyzes the calibrations stored in the file m_calSetFile.

This is the main function in which the analysis and the hisogram filling takes place. Every new monitoring histogram added to the module has to be filled here.

Definition at line 207 of file TOPTBCComparatorModule.cc.

208 {
209 // Here the histograms are filled
210 // WARNING! What root calls "RMS" is actually a standard deviation
211
212 // Sanity check on the parsed parameters
213 if (m_slotID < 0 || m_boardstackID < 0 || m_scrodID < 0) {
214 B2WARNING("Negative slot, BS or scrod ID found while calling analyzeCalFile(). Looks like they have not been initialized, or that a function re-initialized them");
215 return 0;
216 }
217
218 // Loop over all the histograms that should be found in the file
219 for (short iChannel = 0; iChannel < 128; iChannel++) {
220
221 // Pics up one histogram just to check that the channel iChannel was actually used to calculate the calibrations
222 if (!m_calSetFile->Get(str(format("timeDiff_ch%1%") % (iChannel)).c_str())) {
223 continue;
224 }
225
226
227 // ---------
228 // 1) Define some channel numbering quantities
229 // Watchout: m_slotID is in [1..16] so slot m_slotID is on the element m_slotID-1 of the array
230 // ---------
231
232 short hardwareChannel = iChannel + 128 * m_boardstackID; // 0-511 across the whole module, BS by BS
233 auto& chMapper = TOP::TOPGeometryPar::Instance()->getChannelMapper();
234 short pixelID = chMapper.getPixelID(hardwareChannel); // 1-512 across the whole module, in rows
235 short colNum = (pixelID - 1) % 64 + 1; // 1- 64 column ID (right to left looking from the quartz to the PMTs)
236 short rowNum = (pixelID - 1) / 64 + 1 ; // 1- 8 row ID (bottom to top looking from the quartz to the PMTs)
237 short globalChannel = hardwareChannel + 512 * (m_slotID -
238 1); // channel number across the whole detector, 0-8191. Used for cal monitoring only
239
240
241 // ---------
242 // 2) Channel-by-channel DeltaT summaries (average on the 256 samples of each set)
243 // ---------
244
245 // Checks that the histogram needed here is not corrupted before using it
246 if (!m_calSetFile->Get(str(format("timeDiffcal_ch%1%") % (iChannel)).c_str())) {
247 B2WARNING("Error opening " << str(format("timeDiffcal_ch%1%") % (iChannel)));
248 } else {
249 TH2F* h_timeDiffcal = static_cast<TH2F*>(m_calSetFile->Get(str(format("timeDiffcal_ch%1%") % (iChannel)).c_str()));
250 TH1D* h_projection = h_timeDiffcal->ProjectionY("h_projection", 1, m_numSamples); // full projection
251
252 m_slotAverageDeltaT[m_slotID - 1][m_calSetID]->SetBinContent(hardwareChannel + 1, h_projection->GetMean());
253 m_slotAverageDeltaT[m_slotID - 1][m_calSetID]->SetBinError(hardwareChannel + 1,
254 h_projection->GetMeanError()); // Do we trust root on this?
255 m_slotSigmaDeltaT[m_slotID - 1][m_calSetID]->SetBinContent(hardwareChannel + 1,
256 h_projection->GetRMS()); // WARNING! What root calls "RMS" is actually a standard deviation
257 m_slotSigmaDeltaT[m_slotID - 1][m_calSetID]->SetBinError(hardwareChannel + 1,
258 h_projection->GetRMSError()); // WARNING! What root calls "RMS" is actually a standard deviation
259
260 m_slotAverageDeltaTMap[m_slotID - 1][m_calSetID]->SetBinContent(colNum, rowNum, h_projection->GetMean());
261 m_slotSigmaDeltaTMap[m_slotID - 1][m_calSetID]->SetBinContent(colNum, rowNum,
262 h_projection->GetRMS());
263
264 m_topAverageDeltaT[m_calSetID]->SetBinContent(globalChannel + 1, h_projection->GetMean());
265 m_topSigmaDeltaT[m_calSetID]->SetBinContent(globalChannel + 1, h_projection->GetRMS());
266 }
267
268 // ---------
269 // 3) Channel-by-channel average occupancy
270 // ---------
271
272 // Checks that the histogram needed here is not corrupted before using it
273 if (!m_calSetFile->Get(str(format("sampleOccup_ch%1%") % (iChannel)).c_str())) {
274 B2WARNING("Error opening " << str(format("sampleOccup_ch%1%") % (iChannel)));
275 } else {
276 TH1F* h_sampleOccup = static_cast<TH1F*>(m_calSetFile->Get(str(format("sampleOccup_ch%1%") % (iChannel)).c_str()));
277
278 // reads the occupancy histogram bin-by-by to look for (almost) empty samples
279 int nEmpty = 0;
280 for (int iSample = 1; iSample < m_numSamples + 1 ; iSample++) {
281 if (h_sampleOccup->GetBinContent(iSample) < m_minCalPulses) nEmpty++;
282 }
283
284 m_slotSampleOccupancy[m_slotID - 1][m_calSetID]->SetBinContent(hardwareChannel + 1, h_sampleOccup->Integral() / m_numSamples);
285 m_slotEmptySamples[m_slotID - 1][m_calSetID]->SetBinContent(hardwareChannel + 1, nEmpty);
286
287 m_slotSampleOccupancyMap[m_slotID - 1][m_calSetID]->SetBinContent(colNum, rowNum, h_sampleOccup->Integral() / m_numSamples);
288 m_slotEmptySamplesMap[m_slotID - 1][m_calSetID]->SetBinContent(colNum, rowNum, nEmpty);
289
290 m_topSampleOccupancy[m_calSetID]->SetBinContent(globalChannel + 1, h_sampleOccup->Integral() / m_numSamples);
291
292 }
293
294
295
296 }
297 return 1;
298 }

◆ associatePDFPeaks()

void associatePDFPeaks ( const TOP::PDFConstructor & pdfConstructor)
private

Associate PDF peaks with photons using S-plot technique.

Parameters
pdfConstructorreconstruction object for given track and hypothesis

Definition at line 192 of file TOPPDFDebuggerModule.cc.

193 {
194
195 const auto& signalPDFs = pdfConstructor.getSignalPDF();
196 auto signalPhotons = pdfConstructor.getExpectedSignalPhotons();
197 auto bkgPhotons = pdfConstructor.getExpectedBkgPhotons();
198 auto deltaPhotons = pdfConstructor.getExpectedDeltaPhotons();
199 int PDGCode = pdfConstructor.getHypothesis().getPDGCode();
200
201 for (const auto& digit : m_digits) {
202 if (digit.getModuleID() != pdfConstructor.getModuleID()) continue;
203 if (digit.getHitQuality() != TOPDigit::c_Good) continue;
204 int pixelID = digit.getPixelID();
205 unsigned index = pixelID - 1;
206 if (index >= signalPDFs.size()) continue;
207 const auto& signalPDF = signalPDFs[index];
208 const auto* tts = signalPDF.getTTS();
209 const auto& pdfPeaks = signalPDF.getPDFPeaks();
210 const auto& extraInfos = signalPDF.getPDFExtraInfo();
211 if (extraInfos.size() != pdfPeaks.size()) {
212 B2ERROR("associatePDFPeaks: sizes of PDFPeaks and ExtraInfo's differ");
213 continue;
214 }
215
216 auto* associatedPDF = m_associatedPDFs.appendNew(PDGCode);
217 digit.addRelationTo(associatedPDF);
218
219 double bkgLevel = pdfConstructor.getBackgroundPDF()->getPDFValue(pixelID) * bkgPhotons;
220 associatedPDF->setBackgroundWeight(bkgLevel);
221 double deltaLevel = pdfConstructor.getDeltaRayPDF().getPDFValue(pixelID, digit.getTime()) * deltaPhotons;
222 associatedPDF->setDeltaRayWeight(deltaLevel);
223
224 float time = digit.getTime();
225 float timeErr = digit.getTimeError();
226
227 for (size_t k = 0; k < pdfPeaks.size(); k++) {
228 const auto& pdfPeak = pdfPeaks[k];
229 const auto& pdfExtra = extraInfos[k];
230 TOPAssociatedPDF::PDFPeak peak;
231 peak.position = pdfPeak.t0;
232 peak.width = sqrt(pdfPeak.wid);
233 peak.numPhotons = pdfPeak.nph * signalPhotons;
234 float wt = 0;
235 for (const auto& gaus : tts->getTTS()) {
236 float sig2 = peak.width * peak.width + gaus.sigma * gaus.sigma + timeErr * timeErr;
237 float x = pow(time - peak.position - gaus.position, 2) / sig2;
238 if (x > 20) continue;
239 wt += peak.numPhotons * gaus.fraction / sqrt(2 * M_PI * sig2) * exp(-x / 2);
240 }
241 if (wt > 0) {
242 peak.fic = pdfPeak.fic;
243 peak.e = pdfExtra.e;
244 peak.sige = pdfExtra.sige;
245 peak.nx = abs(pdfExtra.Nxm) + abs(pdfExtra.Nxb) + abs(pdfExtra.Nxe);
246 peak.ny = abs(pdfExtra.Nym) + abs(pdfExtra.Nyb) + abs(pdfExtra.Nye);
247 peak.nxm = abs(pdfExtra.Nxm);
248 peak.nym = abs(pdfExtra.Nym);
249 peak.nxe = abs(pdfExtra.Nxe);
250 peak.nye = abs(pdfExtra.Nye);
251 peak.xd = pdfExtra.xD;
252 peak.yd = pdfExtra.yD;
253 peak.type = pdfExtra.type;
254 peak.kxe = pdfExtra.kxE;
255 peak.kye = pdfExtra.kyE;
256 peak.kze = pdfExtra.kzE;
257 peak.kxd = pdfExtra.kxD;
258 peak.kyd = pdfExtra.kyD;
259 peak.kzd = pdfExtra.kzD;
260 associatedPDF->appendPeak(peak, wt);
261 }
262 }
263 }
264
265 }
double sqrt(double a)
sqrt for double
Definition beamHelpers.h:28

◆ basicDebuggingPlots()

void basicDebuggingPlots ( const TOPRawWaveform & rawwave)

Fills the debugging 1D histograms and hitmaps.

Parameters
rawwavethe raw waveform

Definition at line 80 of file TOPWaveformQualityPlotterModule.cc.

81 {
82 int scrodid = v.getScrodID();
83 int asicid = v.getASICNumber();
84 int channelid = v.getASICChannel();
85 int carrierid = v.getCarrierNumber();
86 m_scrod_id->Fill(scrodid);
87 m_asic_ch->Fill(channelid);
88 m_asic->Fill(asicid);
89 m_carrier->Fill(carrierid);
90 m_asic_win->Fill(v.getStorageWindow());
91 m_entries->Fill(v.getWaveform().size());
92 m_moduleID->Fill(v.getModuleID());
93 m_pixelID->Fill(v.getPixelID());
94
95 if (not m_hitmap[scrodid]) {
96 m_hitmap[scrodid] = new TH2F((string("scrod_") + to_string(scrodid) + string("Hitmap")).c_str(),
97 (string("scrod ") + to_string(scrodid) + string(" carrier vs. asic;asic;carrier")).c_str(), 4, 0, 4, 4, 0, 4);
98 }
99 m_hitmap[scrodid]->Fill(asicid, carrierid);
100 const vector<short>& waveform = v.getWaveform();
101 if (waveform.empty()) {
102 return;
103 }
104 for (short adc : waveform) {
105 m_samples->Fill(adc);
106 }
107 }

◆ beginRun() [1/10]

void beginRun ( void )
overridevirtual

Called when entering a new run.

Set run dependent things like run header parameters, alignment, etc.

Reimplemented from Module.

Definition at line 189 of file TOPBackgroundModule.cc.

190 {
191 // Print run number
192 B2INFO("TOPBackground: Processing:");
193
194 }

◆ beginRun() [2/10]

void beginRun ( void )
overridevirtual

Called when entering a new run.

Reimplemented from Module.

Definition at line 202 of file TOPBunchFinderModule.cc.

203 {
204 StoreObjPtr<EventMetaData> evtMetaData;
205
206 if (not m_commonT0.isValid()) {
207 B2FATAL("Common T0 calibration payload requested but not available for run "
208 << evtMetaData->getRun()
209 << " of experiment " << evtMetaData->getExperiment());
210 }
211
212 if (m_HLTmode) return;
213
214 if (m_useTimeSeed and not m_eventT0Offset.isValid()) {
215 B2WARNING("EventT0Offset not available for run "
216 << evtMetaData->getRun()
217 << " of experiment " << evtMetaData->getExperiment()
218 << ": seeding with SVD or CDC eventT0 will not be done.");
219 }
220 if (m_useFillPattern) {
221 if (not m_bunchStructure->isSet()) {
222 B2WARNING("BunchStructure not available for run "
223 << evtMetaData->getRun()
224 << " of experiment " << evtMetaData->getExperiment()
225 << ": fill pattern will not be used.");
226 }
227 if (not m_fillPatternOffset.isValid()) {
228 B2WARNING("FillPatternOffset not available for run "
229 << evtMetaData->getRun()
230 << " of experiment " << evtMetaData->getExperiment()
231 << ": fill pattern will not be used.");
232 }
233 }
234
235 }

◆ beginRun() [3/10]

void beginRun ( void )
overridevirtual

Called when entering a new run.

Set run dependent things like run header parameters, alignment, etc.

Reimplemented from Module.

Definition at line 54 of file TOPChannelMaskerModule.cc.

55 {
56
57 if (not m_channelMask.isValid()) {
58 B2FATAL("channel mask not available");
59 }
60 if (not m_channelT0.isValid()) {
61 B2FATAL("channel T0 calibration not available");
62 }
63 if (not m_timebase.isValid()) {
64 B2FATAL("timebase calibration not available");
65 }
66
67 }

◆ beginRun() [4/10]

void beginRun ( void )
overridevirtual

Called when entering a new run.

Reimplemented from Module.

Definition at line 142 of file TOPDigitizerModule.cc.

143 {
144 StoreObjPtr<EventMetaData> evtMetaData;
145
146 // check availability of mappers
147 const auto& channelMapper = TOPGeometryPar::Instance()->getChannelMapper();
148 if (not channelMapper.isValid()) {
149 B2FATAL("No valid channel mapper found for run "
150 << evtMetaData->getRun()
151 << " of experiment " << evtMetaData->getExperiment());
152 }
153 const auto& frontEndMapper = TOPGeometryPar::Instance()->getFrontEndMapper();
154 if (not frontEndMapper.isValid()) {
155 B2FATAL("No valid front-end mapper found for run "
156 << evtMetaData->getRun()
157 << " of experiment " << evtMetaData->getExperiment());
158 }
159
160 // check availability of constants in database
161 if (m_useDatabase) {
162 if (not m_timebases.isValid()) {
163 B2FATAL("Sample time calibration constants requested but not available for run "
164 << evtMetaData->getRun()
165 << " of experiment " << evtMetaData->getExperiment());
166 }
167 if (not m_channelT0.isValid()) {
168 B2FATAL("Channel T0 calibration constants requested but not available for run "
169 << evtMetaData->getRun()
170 << " of experiment " << evtMetaData->getExperiment());
171 }
172 if (not m_asicShift.isValid()) {
173 B2FATAL("ASIC shifts calibration requested but not available for run "
174 << evtMetaData->getRun()
175 << " of experiment " << evtMetaData->getExperiment());
176 }
177 if (not m_moduleT0.isValid()) {
178 B2FATAL("Module T0 calibration constants requested but not available for run "
179 << evtMetaData->getRun()
180 << " of experiment " << evtMetaData->getExperiment());
181 }
182 if (not m_commonT0.isValid()) {
183 B2FATAL("Common T0 calibration constants requested but not available for run "
184 << evtMetaData->getRun()
185 << " of experiment " << evtMetaData->getExperiment());
186 }
187 if (not m_pulseHeights.isValid()) {
188 B2FATAL("Pulse height calibration constants requested but not available for run "
189 << evtMetaData->getRun()
190 << " of experiment " << evtMetaData->getExperiment());
191 }
192 if (not m_thresholds.isValid()) {
193 B2FATAL("Channel thresholds requested but not available for run "
194 << evtMetaData->getRun()
195 << " of experiment " << evtMetaData->getExperiment());
196 }
197 if (not m_noises.isValid()) {
198 B2FATAL("Channel noise levels requested but not available for run "
199 << evtMetaData->getRun()
200 << " of experiment " << evtMetaData->getExperiment());
201 }
202 if (m_timeWalk.isValid()) {
203 TimeDigitizer::setTimeWalk(&m_timeWalk);
204 } else {
205 B2FATAL("Time-walk parameters requested but not available for run "
206 << evtMetaData->getRun()
207 << " of experiment " << evtMetaData->getExperiment());
208 }
209 if (not m_calPrecision.isValid()) {
210 B2FATAL("Calibration precision requested but not available for run "
211 << evtMetaData->getRun()
212 << " of experiment " << evtMetaData->getExperiment());
213 }
214 } else if (m_useSampleTimeCalibration) {
215 if (not m_timebases.isValid()) {
216 B2FATAL("Sample time calibration constants requested but not available for run "
217 << evtMetaData->getRun()
218 << " of experiment " << evtMetaData->getExperiment());
219 }
220 }
221
222 // check availability of front-end settings
223 if (not m_feSetting.isValid()) {
224 B2FATAL("Front-end settings are not available for run "
225 << evtMetaData->getRun()
226 << " of experiment " << evtMetaData->getExperiment());
227 }
228
229 // pass a parameter to TimeDigitizer
230 TimeDigitizer::setReadoutWindows(m_feSetting->getReadoutWindows());
231 if ((evtMetaData->getExperiment() > 0 and evtMetaData->getExperiment() < 5) or
232 evtMetaData->getExperiment() == 1002) {
233 TimeDigitizer::maskSamples(true); // phase-2: mask samples at window boundaries
234 } else {
235 TimeDigitizer::maskSamples(false); // phase-3: no masking
236 }
237
238 }

◆ beginRun() [5/10]

void beginRun ( void )
overridevirtual

Called when entering a new run.

Set run dependent things like run header parameters, alignment, etc.

Reimplemented from Module.

Definition at line 143 of file TOPDoublePulseGeneratorModule.cc.

144 {
145 StoreObjPtr<EventMetaData> evtMetaData;
146 if (m_useDatabase) {
147 if (!m_timebase.isValid()) {
148 B2FATAL("Sample time calibration requested but not available for run "
149 << evtMetaData->getRun()
150 << " of experiment " << evtMetaData->getExperiment());
151 }
152 }
153
154 }

◆ beginRun() [6/10]

void beginRun ( void )
overridevirtual

Called when entering a new run.

Set run dependent things like run header parameters, alignment, etc.

Reimplemented from HistoModule.

Definition at line 326 of file TOPDQMModule.cc.

327 {
328 m_BoolEvtMonitor->Reset();
329 m_window_vs_slot->Reset();
330 m_eventT0->Reset();
331 m_bunchOffset->Reset();
332 m_time->Reset();
333 m_timeBG->Reset();
334 m_signalHits->Reset();
335 m_backgroundHits->Reset();
336 m_trackHits->Reset();
337 m_goodTDCAll->Reset();
338 m_badTDCAll->Reset();
339 m_goodHitsPerEventAll->Reset();
340 m_badHitsPerEventAll->Reset();
341 m_TOPOccAfterInjLER->Reset();
342 m_TOPOccAfterInjHER->Reset();
343 m_TOPEOccAfterInjLER->Reset();
344 m_TOPEOccAfterInjHER->Reset();
345 m_nhitInjLER->Reset();
346 m_nhitInjHER->Reset();
347 m_nhitInjLERcut->Reset();
348 m_nhitInjHERcut->Reset();
349 m_eventInjLER->Reset();
350 m_eventInjHER->Reset();
351 m_eventInjLERcut->Reset();
352 m_eventInjHERcut->Reset();
353
354 for (int i = 0; i < m_numModules; i++) {
355 m_window_vs_asic[i]->Reset();
356 m_goodHitsXY[i]->Reset();
357 m_badHitsXY[i]->Reset();
358 m_goodHitsAsics[i]->Reset();
359 m_badHitsAsics[i]->Reset();
360 m_goodTDC[i]->Reset();
361 m_badTDC[i]->Reset();
362 m_goodTiming[i]->Reset();
363 m_goodTimingBG[i]->Reset();
364 m_goodChannelHits[i]->Reset();
365 m_badChannelHits[i]->Reset();
366 m_pulseHeights[i]->Reset();
367 }
368
369 m_skipProcFlag->Reset();
370 m_injVetoFlag->Reset();
371 m_injVetoFlagDiff->Reset();
372 m_PSBypassMode->Reset();
373 }

◆ beginRun() [7/10]

void beginRun ( void )
overridevirtual

Called when entering a new run.

Set run dependent things like run header parameters, alignment, etc.

Reimplemented from Module.

Definition at line 160 of file TOPModuleT0CalibratorModule.cc.

161 {
162 if (m_moduleT0.hasChanged()) {
163 StoreObjPtr<EventMetaData> evtMetaData;
164 B2WARNING("ModuleT0 payload has changed. Calibration results may not be correct."
165 << LogVar("run", evtMetaData->getRun()));
166 }
167 }

◆ beginRun() [8/10]

void beginRun ( void )
overridevirtual

Called when entering a new run.

Set run dependent things like run header parameters, alignment, etc.

Reimplemented from Module.

Definition at line 127 of file TOPRawDigitConverterModule.cc.

128 {
129
130 StoreObjPtr<EventMetaData> evtMetaData;
131
132 // check if calibrations are available when needed - if not, terminate
133
134 if (m_useSampleTimeCalibration) {
135 if (not m_timebase.isValid()) {
136 B2FATAL("Sample time calibration requested but not available for run "
137 << evtMetaData->getRun()
138 << " of experiment " << evtMetaData->getExperiment());
139 }
140 }
141 if (m_useChannelT0Calibration) {
142 if (not m_channelT0.isValid()) {
143 B2FATAL("Channel T0 calibration requested but not available for run "
144 << evtMetaData->getRun()
145 << " of experiment " << evtMetaData->getExperiment());
146 }
147 if (not m_calPrecision.isValid()) {
148 B2WARNING("Calibration precision requested but not available for run "
149 << evtMetaData->getRun()
150 << " of experiment " << evtMetaData->getExperiment());
151 }
152 }
153 if (m_useAsicShiftCalibration) {
154 if (not m_asicShift.isValid()) {
155 B2FATAL("ASIC shifts calibration requested but not available for run "
156 << evtMetaData->getRun()
157 << " of experiment " << evtMetaData->getExperiment());
158 }
159 }
160 if (m_useModuleT0Calibration) {
161 if (not m_moduleT0.isValid()) {
162 B2FATAL("Module T0 calibration requested but not available for run "
163 << evtMetaData->getRun()
164 << " of experiment " << evtMetaData->getExperiment());
165 }
166 }
167 if (m_useCommonT0Calibration) {
168 if (not m_commonT0.isValid()) {
169 B2FATAL("Common T0 calibration requested but not available for run "
170 << evtMetaData->getRun()
171 << " of experiment " << evtMetaData->getExperiment());
172 }
173 }
174 if (m_useTimeWalkCalibration) {
175 if (not m_timeWalk.isValid()) {
176 B2FATAL("Time-walk calibration is not available for run "
177 << evtMetaData->getRun()
178 << " of experiment " << evtMetaData->getExperiment());
179 }
180 }
181 if (m_pedestalRMS > 0 and not m_noises.isValid()) {
182 B2FATAL("Channel noise levels are not available for run "
183 << evtMetaData->getRun()
184 << " of experiment " << evtMetaData->getExperiment());
185 }
186 if (not m_feSetting.isValid()) {
187 B2FATAL("Front-end settings are not available for run "
188 << evtMetaData->getRun()
189 << " of experiment " << evtMetaData->getExperiment());
190 }
191
192 }

◆ beginRun() [9/10]

void beginRun ( void )
overridevirtual

Called when entering a new run.

Set run dependent things like run header parameters, alignment, etc.

Reimplemented from Module.

Definition at line 85 of file TOPTimeRecalibratorModule.cc.

86 {
87 StoreObjPtr<EventMetaData> evtMetaData;
88
89 // check if calibrations are available when needed - if not, terminate
90
91 if (m_useSampleTimeCalibration) {
92 if (not m_timebase.isValid()) {
93 B2FATAL("Sample time calibration requested but not available for run "
94 << evtMetaData->getRun()
95 << " of experiment " << evtMetaData->getExperiment());
96 }
97 }
98 if (m_useChannelT0Calibration) {
99 if (not m_channelT0.isValid()) {
100 B2FATAL("Channel T0 calibration requested but not available for run "
101 << evtMetaData->getRun()
102 << " of experiment " << evtMetaData->getExperiment());
103 }
104 }
105 if (m_useAsicShiftCalibration) {
106 if (not m_asicShift.isValid()) {
107 B2FATAL("ASIC shifts calibration requested but not available for run "
108 << evtMetaData->getRun()
109 << " of experiment " << evtMetaData->getExperiment());
110 }
111 }
112 if (m_useModuleT0Calibration) {
113 if (not m_moduleT0.isValid()) {
114 B2FATAL("Module T0 calibration requested but not available for run "
115 << evtMetaData->getRun()
116 << " of experiment " << evtMetaData->getExperiment());
117 }
118 }
119 if (m_useCommonT0Calibration) {
120 if (not m_commonT0.isValid()) {
121 B2FATAL("Common T0 calibration requested but not available for run "
122 << evtMetaData->getRun()
123 << " of experiment " << evtMetaData->getExperiment());
124 }
125 }
126 if (m_useTimeWalkCalibration) {
127 if (not m_timeWalk.isValid()) {
128 // B2FATAL("Time-walk calibration requested but not available for run "
129 B2WARNING("Time-walk calibration is not available for run "
130 << evtMetaData->getRun()
131 << " of experiment " << evtMetaData->getExperiment());
132 }
133 }
134
135 if (not m_feSetting.isValid()) {
136 B2FATAL("Front-end settings are not available for run "
137 << evtMetaData->getRun()
138 << " of experiment " << evtMetaData->getExperiment());
139 }
140
141 }

◆ beginRun() [10/10]

void beginRun ( void )
overridevirtual

Called when entering a new run.

Set run dependent things like run header parameters, alignment, etc.

Reimplemented from Module.

Definition at line 110 of file TOPUnpackerModule.cc.

111 {
112 m_channelStatistics.clear();
113 }

◆ calculateHistoRatio() [1/2]

TH1F * calculateHistoRatio ( TH1F * hRatio,
TH1F * hNum,
TH1F * hDen )

Utility function to take the ratio of two histograms using TH1::Divide(), without overwriting the output name and title initialized in defineHisto().

Definition at line 578 of file TOPTBCComparatorModule.cc.

579 {
580 // Saves the name and titple of the output histogram, as defined in defineHisto
581 const char* name = hRatio->GetName();
582 const char* title = hRatio->GetTitle();
583
584 const char* xAxisTitle = hRatio->GetXaxis()->GetTitle();
585 const char* yAxisTitle = hRatio->GetYaxis()->GetTitle();
586
587 // clone the numerator histogram into the output one
588 hRatio = static_cast<TH1F*>(hNum->Clone());
589
590
591 // makes the ratio
592 hRatio->Divide(hDen);
593
594 //ri-sets name, title and axis labels
595 hRatio->SetName(name);
596 hRatio->SetTitle(title);
597 hRatio->GetXaxis()->SetTitle(xAxisTitle);
598 hRatio->GetYaxis()->SetTitle(yAxisTitle);
599 return hRatio;
600 }

◆ calculateHistoRatio() [2/2]

TH2F * calculateHistoRatio ( TH2F * hRatio,
TH2F * hNum,
TH2F * hDen )

Utility function to take the ratio of two histograms using TH2::Divide(), without overwriting the output name and title initialized in defineHisto().

Definition at line 602 of file TOPTBCComparatorModule.cc.

603 {
604 // Saves the name and titple of the output histogram, as defined in defineHisto
605 const char* name = hRatio->GetName();
606 const char* title = hRatio->GetTitle();
607
608 const char* xAxisTitle = hRatio->GetXaxis()->GetTitle();
609 const char* yAxisTitle = hRatio->GetYaxis()->GetTitle();
610
611 // clone the numerator histogram into the output one
612 hRatio = static_cast<TH2F*>(hNum->Clone());
613
614
615 // makes the ratio
616 hRatio->Divide(hDen);
617
618 //ri-sets name, title and axis labels
619 hRatio->SetName(name);
620 hRatio->SetTitle(title);
621 hRatio->GetXaxis()->SetTitle(xAxisTitle);
622 hRatio->GetYaxis()->SetTitle(yAxisTitle);
623 return hRatio;
624 }

◆ calibrateChannel()

bool calibrateChannel ( std::vector< TwoTimes > & ntuple,
unsigned scrodID,
unsigned scrodChannel,
TH1F & Hchi2,
TH1F & Hndf,
TH1F & HDeltaT )
private

calibrate single channel

Parameters
ntuplentuple data
scrodIDSCROD ID
scrodChannelchannel number within SCROD (0 - 127)
Hchi2histogram to store normalized chi^2
Hndfhistogram to store degrees of freedom
HDeltaThistogram to store fittet double pulse delay
Returns
true on success

Definition at line 299 of file TOPTimeBaseCalibratorModule.cc.

303 {
304
305 // determine outlayer removal cuts
306
307 string name = "timeDiff_ch" + to_string(chan);
308 string forWhat = "scrod " + to_string(scrodID) + " channel " + to_string(chan);
309 string title = "Cal pulse time difference vs. sample for " + forWhat;
310 TProfile prof(name.c_str(), title.c_str(), c_TimeAxisSize, 0, c_TimeAxisSize,
311 m_minTimeDiff, m_maxTimeDiff, "S");
312 prof.SetXTitle("sample number");
313 prof.SetYTitle("time difference [samples]");
314
315 name = "sampleOccup_ch" + to_string(chan);
316 title = "Occupancy for " + forWhat;
317 TH1F hist(name.c_str(), title.c_str(), c_TimeAxisSize, 0, c_TimeAxisSize);
318 hist.SetXTitle("sample number");
319 hist.SetYTitle("entries per sample");
320
321 vector<double> profMeans(c_TimeAxisSize, (m_maxTimeDiff + m_minTimeDiff) / 2);
322 double sigma = (m_maxTimeDiff - m_minTimeDiff) / 6;
323
324 for (int iter = 0; iter < 5; iter++) {
325 prof.Reset();
326 double x = 0;
327 double x2 = 0;
328 int n = 0;
329 for (auto& twoTimes : ntuple) {
330 int sample = int(twoTimes.t1) % c_TimeAxisSize;
331 double diff = twoTimes.t2 - twoTimes.t1;
332 double Ddiff = diff - profMeans[sample];
333 if (fabs(Ddiff) < 3 * sigma) {
334 prof.Fill(sample, diff);
335 hist.Fill(sample);
336 x += Ddiff;
337 x2 += Ddiff * Ddiff;
338 n++;
339 twoTimes.good = true;
340 } else {
341 twoTimes.good = false;
342 }
343 }
344 for (int i = 0; i < c_TimeAxisSize; i++) {
345 profMeans[i] = prof.GetBinContent(i + 1);
346 }
347 if (n == 0) return false;
348 x2 /= n;
349 x /= n;
350 sigma = sqrt(x2 - x * x);
351 }
352 prof.Write();
353 hist.Write();
354
355 // calculate average time difference
356
357 double meanTimeDifference = 0;
358 for (const auto& x : profMeans) meanTimeDifference += x;
359 meanTimeDifference /= profMeans.size();
360 meanTimeDifference -= int(meanTimeDifference / static_cast<double>(c_TimeAxisSize)) * c_TimeAxisSize;
361
362 // perform the fit
363
364 switch (m_method) {
365 case 0:
366 B2INFO("... channel " << chan << ": "
367 << ntuple.size() << " double cal pulses)");
368 return false;
369 case 1:
370 return matrixInversion(ntuple, scrodID, chan, meanTimeDifference,
371 Hchi2, Hndf, HDeltaT);
372 case 2:
373 return iterativeTBC(ntuple, scrodID, chan, meanTimeDifference,
374 Hchi2, Hndf, HDeltaT);
375 case 3:
376 B2ERROR("Singuler value decomposition not implemented yet");
377 return false;
378 default:
379 B2ERROR("Unknown method " << m_method);
380 return false;
381 }
382
383 }

◆ Chisq()

double Chisq ( const std::vector< TwoTimes > & ntuple,
const std::vector< double > & xxval )
private

Return the chisqure of one set of TBC constants (xval) in iTBC calculation.

Parameters
ntuplentuple data
xxvalTBC constants of 256 samples, and xxval[0]=0, xxval[256]=2*FTSW

Definition at line 657 of file TOPTimeBaseCalibratorModule.cc.

658 {
659 double sum1 = 0.0;
660 double sum2 = 0.0; //sum od dt and dt**2
661
662 m_good = 0;
663
664 for (const auto& twoTimes : ntuple) {
665 if (!twoTimes.good) continue;
666
667 int i1 = int(twoTimes.t1);
668 double fr = twoTimes.t1 - i1;
669 double samp0 = i1 % 256;
670 double ctdc1 = xxval[samp0] + fr * (xxval[samp0 + 1] - xxval[samp0]);
671 int i2 = int(twoTimes.t2);
672 fr = twoTimes.t2 - i2;
673 double samp1 = i2 % 256;
674 double ctdc2 = xxval[samp1] + fr * (xxval[samp1 + 1] - xxval[samp1]);
675 double cdt = 0.0;
676 if (samp1 > samp0) cdt = ctdc2 - ctdc1;
677 else cdt = ctdc2 - ctdc1 + m_syncTimeBase * 2;
678
679 if (cdt < m_dt_max && cdt > m_dt_min) {
680 sum1 += cdt;
681 sum2 += cdt * cdt;
682 m_good++;
683 }
684 }
685
686 double chi2 = -1.0;
687
688 if (m_good > 10) {
689 double mean = sum1 / m_good;
690 chi2 = (sum2 - m_good * mean * mean) / m_good / m_sigm2_exp;
691 }
692 return chi2;
693 }

◆ closeRun()

void closeRun ( )
finalprivatevirtual

Replacement for endRun().

Do anything you would normally do in endRun here.

Reimplemented from CalibrationCollectorModule.

Definition at line 288 of file TOPValidationCollectorModule.cc.

289 {
290
291 // module T0 pulls
292
293 for (int module = 0; module < c_numModules; module++) {
294 std::vector<double> pos, err;
295 for (int set = 0; set < c_numSets; set++) {
296 const auto& minimum = m_finders[set][module].getMinimum();
297 if (minimum.valid) {
298 pos.push_back(minimum.position);
299 err.push_back(minimum.error);
300 }
301 }
302 auto h_pulls = getObjectPtr<TH1F>("moduleT0_pulls");
303 for (unsigned i = 0; i < pos.size(); i++) {
304 for (unsigned j = i + 1; j < pos.size(); j++) {
305 double pull = (pos[i] - pos[j]) / sqrt(err[i] * err[i] + err[j] * err[j]);
306 h_pulls->Fill(pull);
307 }
308 }
309 }
310
311 // module T0 residuals
312
313 for (int module = 0; module < c_numModules; module++) {
314 auto& finder = m_finders[0][module];
315 for (int set = 1; set < c_numSets; set++) {
316 finder.add(m_finders[set][module]);
317 }
318 const auto& minimum = finder.getMinimum();
319 if (minimum.valid) {
320 m_treeEntry.moduleT0[module] = minimum.position;
321 m_treeEntry.moduleT0Err[module] = minimum.error;
322 }
323 }
324
325 // common T0 residual
326
327 auto& finder = m_finders[0][0];
328 for (int module = 1; module < c_numModules; module++) {
329 finder.add(m_finders[0][module]);
330 }
331 const auto& minimum = finder.getMinimum();
332 if (minimum.valid) {
333 m_treeEntry.commonT0 = minimum.position;
334 m_treeEntry.commonT0Err = minimum.error;
335 }
336
337 // fill the tree
338
339 auto tree = getObjectPtr<TTree>("tree");
340 tree->Fill();
341 }

◆ collect() [1/11]

void collect ( )
finalprivatevirtual

Replacement for event().

Fill your calibration data objects here

Reimplemented from CalibrationCollectorModule.

Definition at line 216 of file TOPAlignmentCollectorModule.cc.

217 {
218 // bunch must be reconstructed
219
220 if (not m_recBunch.isValid()) return;
221 if (not m_recBunch->isReconstructed()) return;
222
223 // track-by-track iterations
224
225 for (const auto& track : m_tracks) {
226
227 // construct TOPTrack from mdst track
228 TOPTrack trk(track);
229 if (not trk.isValid()) continue;
230
231 // skip if track not hitting target module
232 if (trk.getModuleID() != m_targetMid) continue;
233
234 // track selection
235 if (not m_selector.isSelected(trk)) continue;
236
237 // generate sub-sample number
238 int sub = gRandom->Integer(c_numSets);
239 auto& align = m_align[sub];
240 auto& countFails = m_countFails[sub];
241 const auto& name = m_treeNames[sub];
242 auto h1 = getObjectPtr<TH2F>("tracks_per_slot");
243 h1->Fill(trk.getModuleID(), sub);
244
245 // do an iteration
246 int err = align.iterate(trk, m_selector.getChargedStable());
247 m_iter++;
248
249 // check number of consecutive failures, and in case reset
250 if (err == 0) {
251 countFails = 0;
252 } else if (countFails <= m_maxFails) {
253 countFails++;
254 } else {
255 B2INFO("Reached maximum allowed number of failed iterations. "
256 "Resetting TOPalign object of set = " << sub << " at iter = " << m_iter);
257 align.reset();
258 countFails = 0;
259 }
260
261 // get new parameter values and estimated errors
262 m_vAlignPars = align.getParameters();
263 m_vAlignParsErr = align.getErrors();
264 m_ntrk = align.getNumUsedTracks();
265 m_errorCode = err;
266 m_valid = align.isValid();
267 m_numPhot = align.getNumOfPhotons();
268
269 // set other ntuple variables
270 const auto& localPosition = m_selector.getLocalPosition();
271 m_x = localPosition.X();
272 m_y = localPosition.Y();
273 m_z = localPosition.Z();
274 const auto& localMomentum = m_selector.getLocalMomentum();
275 m_p = localMomentum.R();
276 m_theta = localMomentum.Theta();
277 m_phi = localMomentum.Phi();
278 const auto& pocaPosition = m_selector.getPOCAPosition();
279 m_pocaR = pocaPosition.Rho();
280 m_pocaZ = pocaPosition.Z();
281 m_pocaX = pocaPosition.X();
282 m_pocaY = pocaPosition.Y();
283 m_cmsE = m_selector.getCMSEnergy();
284 m_charge = trk.getCharge();
285 m_PDG = trk.getPDGCode();
286
287 // fill output tree
288 auto alignTree = getObjectPtr<TTree>(name);
289 alignTree->Fill();
290
291 // fill control histograms
292 std::string slotName = "_s" + to_string(m_targetMid);
293 auto h2 = getObjectPtr<TH1F>("local_z" + slotName);
294 h2->Fill(m_z);
295 auto h3 = getObjectPtr<TH2F>("cth_vs_p" + slotName);
296 h3->Fill(m_p, cos(m_theta));
297 auto h4 = getObjectPtr<TH2F>("poca_xy" + slotName);
298 h4->Fill(m_pocaX, m_pocaY);
299 auto h5 = getObjectPtr<TH1F>("poca_z" + slotName);
300 h5->Fill(m_pocaZ);
301 auto h6 = getObjectPtr<TH1F>("Ecms" + slotName);
302 h6->Fill(m_cmsE);
303 auto h7 = getObjectPtr<TH1F>("charge" + slotName);
304 h7->Fill(m_charge);
305 auto h8 = getObjectPtr<TH2F>("timeHits" + slotName);
306 for (const auto& digit : m_digits) {
307 if (digit.getHitQuality() != TOPDigit::c_Good) continue;
308 if (digit.getModuleID() != m_targetMid) continue;
309 h8->Fill(digit.getChannel(), digit.getTime());
310 }
311 auto h9 = getObjectPtr<TH1F>("numPhot" + slotName);
312 h9->Fill(m_numPhot);
313
314 } // tracks
315
316 }

◆ collect() [2/11]

void collect ( )
finalprivatevirtual

Replacement for event().

Fill your calibration data objects here.

Reimplemented from CalibrationCollectorModule.

Definition at line 91 of file TOPAsicShiftsBS13dCollectorModule.cc.

92 {
93
94 if (m_requireRecBunch) {
95 if (not m_recBunch.isValid()) return;
96 if (not m_recBunch->isReconstructed()) return;
97 }
98
99 auto time_vs_BS = getObjectPtr<TH2F>("time_vs_BS");
100 auto timeReference = getObjectPtr<TH1F>("time_reference");
101 std::vector<TH1F*> timeCarriers;
102 for (unsigned i = 0; i < 4; i++) {
103 string name = "time_carr_" + to_string(i);
104 auto h = getObjectPtr<TH1F>(name);
105 timeCarriers.push_back(h);
106 }
107
108 for (const auto& digit : m_topDigits) {
109 if (digit.getModuleID() != 13) continue;
110 if (digit.getHitQuality() != TOPDigit::c_Good) continue;
111 double time = digit.getTime() - m_timeOffset;
112 time_vs_BS->Fill(digit.getChannel(), time);
113 if (digit.getBoardstackNumber() < 3) {
114 timeReference->Fill(time);
115 } else {
116 auto c = digit.getCarrierNumber();
117 timeCarriers[c]->Fill(time);
118 }
119 }
120
121 }

◆ collect() [3/11]

void collect ( )
finalprivatevirtual

Replacement for event().

Fill your calibration data objects here

Reimplemented from CalibrationCollectorModule.

Definition at line 70 of file TOPChannelMaskCollectorModule.cc.

71 {
72
73 std::vector<TH1F*> slots;
74 for (const auto& name : m_names) {
75 auto h = getObjectPtr<TH1F>(name);
76 slots.push_back(h);
77 }
78
79 std::vector<TH2F*> asics;
80 for (const auto& name : m_asicNames) {
81 auto h = getObjectPtr<TH2F>(name);
82 asics.push_back(h);
83 }
84
85 int NGood = 0;
86 for (const auto& digit : m_digits) {
87 if (digit.getHitQuality() == TOPDigit::c_Junk) continue;
88 NGood++;
89 unsigned m = digit.getModuleID() - 1;
90 if (m < slots.size()) slots[m]->Fill(digit.getChannel());
91 if (m < asics.size()) asics[m]->Fill(digit.getChannel() / 8, digit.getRawTime() / 64 + 220);
92 }
93
94 auto h = getObjectPtr<TH1F>("nhits");
95 h->Fill(NGood);
96
97 }

◆ collect() [4/11]

void collect ( )
finalprivatevirtual

Replacement for event().

Fill your calibration data objects here

Reimplemented from CalibrationCollectorModule.

Definition at line 68 of file TOPCommonT0BFCollectorModule.cc.

69 {
70
71 if (not m_recBunch.isValid()) return;
72 if (not m_recBunch->isReconstructed()) return;
73 if (m_recBunch->getNumTracks() != 2) return;
74
75 auto h1a = getObjectPtr<TH1F>("offset_a");
76 auto h1b = getObjectPtr<TH1F>("offset_b");
77 auto offset = m_recBunch->getCurrentOffset();
78 if (m_commonT0->isCalibrated()) offset += m_commonT0->getT0();
79
80 // wrap-around into [-1/2, 1/2] of bunch cycle
81 auto a = offset - round(offset / m_bunchTimeSep) * m_bunchTimeSep;
82 h1a->Fill(a);
83
84 // wrap-around into [0, 1] of bunch cycle
85 auto b = offset - round(offset / m_bunchTimeSep - 0.5) * m_bunchTimeSep;
86 h1b->Fill(b);
87
88 }

◆ collect() [5/11]

void collect ( )
finalprivatevirtual

Replacement for event().

Fill your calibration data objects here

Reimplemented from CalibrationCollectorModule.

Definition at line 148 of file TOPCommonT0LLCollectorModule.cc.

149 {
150 // bunch must be reconstructed
151
152 if (not m_recBunch.isValid()) return;
153 if (not m_recBunch->isReconstructed()) return;
154
155 TOPRecoManager::setDefaultTimeWindow();
156 double timeMin = TOPRecoManager::getMinTime();
157 double timeMax = TOPRecoManager::getMaxTime();
158
159 // correct-back digits for common T0
160
161 double T0 = 0;
162 if (m_commonT0->isCalibrated()) T0 = m_commonT0->getT0();
163 for (auto& digit : m_digits) {
164 if (digit.isCommonT0Calibrated()) digit.subtractT0(-T0);
165 if (digit.hasStatus(TOPDigit::c_BunchOffsetSubtracted)) digit.subtractT0(-m_recBunch->getAverageOffset());
166 }
167
168 // loop over reconstructed tracks, make a selection and accumulate log likelihoods
169
170 int ntra = 0;
171 for (const auto& track : m_tracks) {
172
173 // track selection
174 TOPTrack trk(track);
175 if (not trk.isValid()) continue;
176
177 if (not m_selector.isSelected(trk)) continue;
178
179 // construct PDF
180 PDFConstructor pdfConstructor(trk, m_selector.getChargedStable(), m_PDFOption);
181 if (not pdfConstructor.isValid()) continue;
182
183 // minimization procedure: accumulate
184 int sub = gRandom->Integer(c_numSets); // generate sub-sample number
185 auto h = getObjectPtr<TH1D>(m_names[sub]);
186 for (int ibin = 0; ibin < h->GetNbinsX(); ibin++) {
187 double t0 = h->GetBinCenter(ibin + 1);
188 double chi = h->GetBinContent(ibin + 1);
189 chi += -2 * pdfConstructor.getLogL(t0, m_sigmaSmear).logL;
190 h->SetBinContent(ibin + 1, chi);
191 }
192 auto h1 = getObjectPtr<TH1F>("tracks_per_set");
193 h1->Fill(sub);
194
195 // fill histograms of hits
196 auto h2 = getObjectPtr<TH1F>("numHits");
197 auto h3 = getObjectPtr<TH2F>("timeHits");
198 for (const auto& digit : m_digits) {
199 if (digit.getHitQuality() != TOPDigit::c_Good) continue;
200 if (digit.getModuleID() != trk.getModuleID()) continue;
201 if (digit.getTime() < timeMin) continue;
202 if (digit.getTime() > timeMax) continue;
203 h2->Fill(digit.getModuleID());
204 int bs = digit.getBoardstackNumber();
205 h3->Fill((digit.getModuleID() * 4 + bs - 1.5) / 4.0, digit.getTime());
206 }
207 ntra++;
208 }
209
210 // fill just another control histogram
211
212 if (ntra > 0) {
213 auto h4 = getObjectPtr<TH1F>("offset");
214 h4->Fill(m_recBunch->getCurrentOffset());
215 }
216
217 }

◆ collect() [6/11]

void collect ( )
finalprivatevirtual

Replacement for event().

Fill your calibration data objects here

Reimplemented from CalibrationCollectorModule.

Definition at line 78 of file TOPModuleT0DeltaTCollectorModule.cc.

79 {
80
81 if (m_timeZeros.getEntries() != 2) return;
82
83 const auto* timeZero1 = m_timeZeros[0];
84 const auto* timeZero2 = m_timeZeros[1];
85 if (timeZero1->getModuleID() > timeZero2->getModuleID()) {
86 timeZero1 = m_timeZeros[1];
87 timeZero2 = m_timeZeros[0];
88 }
89
90 int slot1 = timeZero1->getModuleID();
91 int slot2 = timeZero2->getModuleID();
92 if (slot1 > 9 or slot2 - slot1 < 7 or slot2 - slot1 > 9) return;
93 string name = "deltaT0_" + to_string(slot1) + "-" + to_string(slot2);
94 auto h = getObjectPtr<TH1F>(name);
95 if (not h) return;
96
97 double t1 = timeZero1->getTime();
98 if (m_moduleT0->isCalibrated(slot1)) t1 += m_moduleT0->getT0(slot1);
99 double t2 = timeZero2->getTime();
100 if (m_moduleT0->isCalibrated(slot2)) t2 += m_moduleT0->getT0(slot2);
101 h->Fill(t1 - t2);
102
103 auto slotPairs = getObjectPtr<TH2F>("slots");
104 slotPairs->Fill(slot1, slot2);
105 }

◆ collect() [7/11]

void collect ( )
finalprivatevirtual

Replacement for event().

Fill your calibration data objects here

Reimplemented from CalibrationCollectorModule.

Definition at line 150 of file TOPModuleT0LLCollectorModule.cc.

151 {
152 // bunch must be reconstructed
153
154 if (not m_recBunch.isValid()) return;
155 if (not m_recBunch->isReconstructed()) return;
156
157 TOPRecoManager::setDefaultTimeWindow();
158 double timeMin = TOPRecoManager::getMinTime();
159 double timeMax = TOPRecoManager::getMaxTime();
160
161 // correct-back digits for module T0
162
163 for (auto& digit : m_digits) {
164 int slot = digit.getModuleID();
165 if (digit.isModuleT0Calibrated()) digit.subtractT0(-m_moduleT0->getT0(slot));
166 if (digit.hasStatus(TOPDigit::c_BunchOffsetSubtracted)) digit.subtractT0(-m_recBunch->getAverageOffset());
167 }
168
169 // loop over reconstructed tracks, make a selection and accumulate log likelihoods
170
171 int ntra = 0;
172 for (const auto& track : m_tracks) {
173
174 // track selection
175 TOPTrack trk(track);
176 if (not trk.isValid()) continue;
177
178 if (not m_selector.isSelected(trk)) continue;
179
180 // construct PDF
181 PDFConstructor pdfConstructor(trk, m_selector.getChargedStable(), m_PDFOption);
182 if (not pdfConstructor.isValid()) continue;
183
184 // minimization procedure: accumulate
185 int sub = gRandom->Integer(c_numSets); // generate sub-sample number
186 unsigned module = trk.getModuleID() - 1;
187 if (module >= m_names[sub].size()) continue;
188 auto h = getObjectPtr<TH1D>(m_names[sub][module]);
189 for (int ibin = 0; ibin < h->GetNbinsX(); ibin++) {
190 double t0 = h->GetBinCenter(ibin + 1);
191 double chi = h->GetBinContent(ibin + 1);
192 chi += -2 * pdfConstructor.getLogL(t0, m_sigmaSmear).logL;
193 h->SetBinContent(ibin + 1, chi);
194 }
195 auto h1 = getObjectPtr<TH2F>("tracks_per_slot");
196 h1->Fill(trk.getModuleID(), sub);
197
198 // fill histograms of hits
199 auto h2 = getObjectPtr<TH1F>("numHits");
200 auto h3 = getObjectPtr<TH2F>("timeHits");
201 for (const auto& digit : m_digits) {
202 if (digit.getHitQuality() != TOPDigit::c_Good) continue;
203 if (digit.getModuleID() != trk.getModuleID()) continue;
204 if (digit.getTime() < timeMin) continue;
205 if (digit.getTime() > timeMax) continue;
206 h2->Fill(digit.getModuleID());
207 int bs = digit.getBoardstackNumber();
208 h3->Fill((digit.getModuleID() * 4 + bs - 1.5) / 4.0, digit.getTime());
209 }
210 ntra++;
211 }
212
213 // fill just another control histogram
214
215 if (ntra > 0) {
216 auto h4 = getObjectPtr<TH1F>("offset");
217 h4->Fill(m_recBunch->getCurrentOffset());
218 }
219
220 }

◆ collect() [8/11]

void collect ( )
finalprivatevirtual

Replacement for event().

Fill your calibration data objects here

Reimplemented from CalibrationCollectorModule.

Definition at line 72 of file TOPOffsetCollectorModule.cc.

73 {
74 if (not m_recBunch->isReconstructed()) return;
75
76 for (const auto& x : m_names) {
77 const auto& detector = x.first;
78 if (m_eventT0->hasTemporaryEventT0(detector)) {
79 auto eventT0s = m_eventT0->getTemporaryEventT0s(detector);
80 if (eventT0s.empty()) continue;
81 if (detector == Const::CDC and eventT0s.back().algorithm != "chi2") continue;
82 double t0 = eventT0s.back().eventT0;
83 auto h = getObjectPtr<TH1F>(x.second);
84 h->Fill(t0 - m_recBunch->getTime());
85 }
86 }
87
88 auto h = getObjectPtr<TH1F>("recBuckets");
89 h->Fill(m_recBunch->getBucketNumber(0, m_bunchStructure->getRFBucketsPerRevolution()));
90 }

◆ collect() [9/11]

void collect ( )
finalprivatevirtual

Replacement for event().

Fill your calibration data objects here

Reimplemented from CalibrationCollectorModule.

Definition at line 186 of file TOPPhotonYieldsCollectorModule.cc.

187 {
188 // bunch must be reconstructed
189
190 if (not m_recBunch->isReconstructed()) return;
191
192 // loop over reconstructed tracks, make a selection and fill histograms
193
194 for (const auto& track : m_tracks) {
195 // track selection
196 TOPTrack trk(track);
197 if (not trk.isValid()) continue;
198 if (not m_selector.isSelected(trk)) continue;
199
200 // fill TOF corrections
201 double localZ = m_selector.getLocalPosition().Z();
202 const auto* timeZero = trk.getExtHit()->getRelated<TOPTimeZero>();
203 if (timeZero and timeZero->isValid()) {
204 auto tofCorrections = getObjectPtr<TProfile>("tofCorrections");
205 tofCorrections->Fill(localZ, timeZero->getTime());
206 }
207 if (localZ < m_minZ) continue;
208
209 // fill all the other histograms
210 auto timeStamp = getObjectPtr<TProfile>("timeStamp");
211 timeStamp->Fill(0.5, m_eventMetaData->getTime() / 1000000000);
212
213 int slot = trk.getModuleID();
214 auto numTracks = getObjectPtr<TH1F>("numTracks");
215 numTracks->Fill(slot);
216
217 auto muonZ = getObjectPtr<TH1F>(m_muonZNames[slot - 1]);
218 muonZ->Fill(m_selector.getLocalPosition().Z());
219
220 auto signalHits = getObjectPtr<TH1F>(m_signalNames[slot - 1]);
221 auto bkgHits = getObjectPtr<TH1F>(m_bkgNames[slot - 1]);
222 auto pulseHeight = getObjectPtr<TH2F>(m_pulseHeightNames[slot - 1]);
223 for (const auto& digit : m_digits) {
224 if (digit.getModuleID() != slot) continue;
225 if (digit.getHitQuality() != TOPDigit::c_Good) continue; // junk hit or pixel masked-out
226 if (std::abs(digit.getTime()) > m_timeWindow) continue;
227 if (digit.getTime() > 0) {
228 signalHits->Fill(digit.getPixelID());
229 pulseHeight->Fill(digit.getPixelID(), digit.getPulseHeight());
230 } else {
231 bkgHits->Fill(digit.getPixelID());
232 }
233 }
234
235 auto activePixels = getObjectPtr<TH1F>(m_activeNames[slot - 1]);
236 const auto& chMapper = TOPGeometryPar::Instance()->getChannelMapper();
237 for (int pixel = 1; pixel <= activePixels->GetNbinsX(); pixel++) {
238 unsigned channel = chMapper.getChannel(pixel);
239 if (m_channelMask->isActive(slot, channel) and m_asicMask->isActive(slot, channel)) activePixels->Fill(pixel);
240 }
241
242 auto alphaLow = getObjectPtr<TH1F>(m_alphaLowNames[slot - 1]);
243 auto alphaHigh = getObjectPtr<TH1F>(m_alphaHighNames[slot - 1]);
244 auto effectiveSignalHits = getObjectPtr<TH1F>(m_effectiveSignalNames[slot - 1]);
245 for (const auto& digit : m_digits) {
246 if (digit.getModuleID() != slot) continue;
247 if (digit.getHitQuality() != TOPDigit::c_Good) continue; // junk hit or pixel masked-out
248 const auto* pdf = digit.getRelated<TOPAssociatedPDF>();
249 if (not pdf) continue;
250 const auto* peak = pdf->getSinglePeak();
251 if (not peak) continue; // hit associated with background
252 effectiveSignalHits->Fill(digit.getPixelID());
253 if (std::abs(m_selector.getLocalPosition().Z()) > m_excludedZ) {
254 double alpha = acos(std::abs(peak->kzd)) / Unit::deg;
255 if (alpha > 60) continue;
256 if (alpha < 30) alphaLow->Fill(digit.getPixelID());
257 else alphaHigh->Fill(digit.getPixelID());
258 }
259 }
260 } // loop over tracks
261
262 }

◆ collect() [10/11]

void collect ( )
finalprivatevirtual

Replacement for event().

Fill your calibration data objects here

Reimplemented from CalibrationCollectorModule.

Definition at line 90 of file TOPPulseHeightCollectorModule.cc.

91 {
92
93 std::vector<TH2F*> slots;
94 for (const auto& name : m_names) {
95 auto h = getObjectPtr<TH2F>(name);
96 slots.push_back(h);
97 }
98
99 auto h1a = getObjectPtr<TH1F>("time");
100 auto h1b = getObjectPtr<TH1F>("time_sel");
101 auto h2a = getObjectPtr<TH2F>("ph_vs_width");
102 auto h2b = getObjectPtr<TH2F>("ph_vs_width_sel");
103
104 for (const auto& digit : m_digits) {
105 if (digit.getHitQuality() != TOPDigit::c_Good) continue;
106 auto t = digit.getTime();
107 auto w = digit.getPulseWidth();
108 auto ph = digit.getPulseHeight();
109 h1a->Fill(t);
110 h2a->Fill(w, ph);
111 if (m_widthWindow.size() == 2) {
112 if (w < m_widthWindow[0] or w > m_widthWindow[1]) continue;
113 }
114 if (m_timeWindow.size() == 2) {
115 if (t < m_timeWindow[0] or t > m_timeWindow[1]) continue;
116 }
117 h1b->Fill(t);
118 h2b->Fill(w, ph);
119 unsigned m = digit.getModuleID() - 1;
120 if (m < slots.size()) slots[m]->Fill(digit.getChannel(), ph);
121 }
122
123 }

◆ collect() [11/11]

void collect ( )
finalprivatevirtual

Replacement for event().

Fill your calibration data objects here

Reimplemented from CalibrationCollectorModule.

Definition at line 233 of file TOPValidationCollectorModule.cc.

234 {
235 // bunch must be reconstructed
236
237 if (not m_recBunch.isValid()) return;
238 if (not m_recBunch->isReconstructed()) return;
239
240 TOPRecoManager::setDefaultTimeWindow();
241 const auto& chMapper = TOPGeometryPar::Instance()->getChannelMapper();
242
243 // loop over reconstructed tracks, make a selection and accumulate log likelihoods
244
245 for (const auto& track : m_tracks) {
246
247 // track selection
248 TOPTrack trk(track);
249 if (not trk.isValid()) continue;
250
251 if (not m_selector.isSelected(trk)) continue;
252
253 // construct PDF
254 PDFConstructor pdfConstructor(trk, m_selector.getChargedStable(), m_PDFOption);
255 if (not pdfConstructor.isValid()) continue;
256
257 // minimization procedure: accumulate
258 unsigned module = trk.getModuleID() - 1;
259 if (module >= m_namesChi.size()) continue;
260 auto h = getObjectPtr<TH2F>(m_namesChi[module]);
261 int set = gRandom->Integer(c_numSets); // generate sub-sample number
262 auto& finder = m_finders[set][module];
263 for (int ibin = 0; ibin < h->GetNbinsY(); ibin++) {
264 double t0 = h->GetYaxis()->GetBinCenter(ibin + 1);
265 const auto& pixelLogLs = pdfConstructor.getPixelLogLs(t0, m_sigmaSmear);
266 for (unsigned channel = 0; channel < c_numChannels; channel++) {
267 int pix = chMapper.getPixelID(channel) - 1;
268 double chi = h->GetBinContent(channel + 1, ibin + 1);
269 chi += -2 * pixelLogLs[pix].logL;
270 h->SetBinContent(channel + 1, ibin + 1, chi);
271 }
272 double logL = 0;
273 for (const auto& LL : pixelLogLs) logL += LL.logL;
274 finder.add(ibin, -2 * logL);
275 }
276 m_treeEntry.numTracks++;
277
278 auto h1 = getObjectPtr<TH2F>(m_namesHit[module]);
279 for (const auto& digit : m_digits) {
280 if (digit.getHitQuality() != TOPDigit::c_Good) continue;
281 if (digit.getModuleID() != trk.getModuleID()) continue;
282 h1->Fill(digit.getChannel(), digit.getTime());
283 }
284
285 }
286 }

◆ defineHisto() [1/7]

void defineHisto ( )
overridevirtual

Histogram definitions such as TH1(), TH2(), TNtuple(), TTree()....

are supposed to be placed in this function.

Reimplemented from HistoModule.

Definition at line 55 of file TOPDQMModule.cc.

56 {
57 // Create a separate histogram directory and cd into it.
58
59 TDirectory* oldDir = gDirectory;
60 oldDir->mkdir(m_histogramDirectoryName.c_str())->cd();
61
62 // Variables needed for booking
63
64 const auto* geo = TOPGeometryPar::Instance()->getGeometry();
65 m_numModules = geo->getNumModules();
66 m_bunchTimeSep = geo->getNominalTDC().getSyncTimeBase() / 24;
67
68 // Histograms
69
70 m_BoolEvtMonitor = new TH1D("BoolEvtMonitor", "Event synchronization", 2, -0.5, 1.5);
71 m_BoolEvtMonitor->GetYaxis()->SetTitle("number of digits");
72 m_BoolEvtMonitor->GetXaxis()->SetBinLabel(1, "synchronized");
73 m_BoolEvtMonitor->GetXaxis()->SetBinLabel(2, "de-synchronized");
74 m_BoolEvtMonitor->GetXaxis()->SetLabelSize(0.05);
75 m_BoolEvtMonitor->GetXaxis()->SetAlphanumeric();
76 m_BoolEvtMonitor->SetMinimum(0);
77
78 m_window_vs_slot = new TH2F("window_vs_slot", "Asic windows", 16, 0.5, 16.5, 512, 0, 512);
79 m_window_vs_slot->SetXTitle("slot number");
80 m_window_vs_slot->SetYTitle("window number w.r.t reference window");
81 m_window_vs_slot->SetStats(kFALSE);
82 m_window_vs_slot->SetMinimum(0);
83 m_window_vs_slot->GetXaxis()->SetNdivisions(16);
84
85 int nbinsT0 = 75;
86 double rangeT0 = nbinsT0 * m_bunchTimeSep;
87 m_eventT0 = new TH1F("eventT0", "Event T0; event T0 [ns]; events per bin", nbinsT0, -rangeT0 / 2, rangeT0 / 2);
88
89 m_bunchOffset = new TH1F("bunchOffset", "Bunch offset", 100, -m_bunchTimeSep / 2, m_bunchTimeSep / 2);
90 m_bunchOffset->SetXTitle("offset [ns]");
91 m_bunchOffset->SetYTitle("events per bin");
92 m_bunchOffset->SetMinimum(0);
93
94 m_time = new TH1F("goodHitTimes", "Time distribution of good hits", 1000, -20, 80);
95 m_time->SetXTitle("time [ns]");
96 m_time->SetYTitle("hits per bin");
97
98 m_timeBG = new TH1F("goodHitTimesBG", "Time distribution of good hits (background)", 1000, -20, 80);
99 m_timeBG->SetXTitle("time [ns]");
100 m_timeBG->SetYTitle("hits per bin");
101
102 m_signalHits = new TProfile("signalHits", "Number of good hits per track in [0, 50] ns", 16, 0.5, 16.5, 0, 1000);
103 m_signalHits->SetXTitle("slot number");
104 m_signalHits->SetYTitle("hits per track");
105 m_signalHits->SetMinimum(0);
106 m_signalHits->GetXaxis()->SetNdivisions(16);
107
108 m_backgroundHits = new TProfile("backgroundHits", "Number of good hits pet track in [-50, 0] ns", 16, 0.5, 16.5, 0, 1000);
109 m_backgroundHits->SetXTitle("slot number");
110 m_backgroundHits->SetYTitle("hits per track");
111 m_backgroundHits->SetMinimum(0);
112 m_backgroundHits->GetXaxis()->SetNdivisions(16);
113
114 m_trackHits = new TH2F("trackHits", "Number of events w/ and w/o track in the slot", 16, 0.5, 16.5, 2, 0, 2);
115 m_trackHits->SetXTitle("slot number");
116 m_trackHits->SetYTitle("numTracks > 0");
117
118 int nbinsHits = 1000;
119 double xmaxHits = 10000;
120 m_goodHitsPerEventAll = new TH1F("goodHitsPerEventAll", "Number of good hits per event", nbinsHits, 0, xmaxHits);
121 m_goodHitsPerEventAll->GetXaxis()->SetTitle("hits per event");
122 m_goodHitsPerEventAll->GetYaxis()->SetTitle("entries per bin");
123
124 m_badHitsPerEventAll = new TH1F("badHitsPerEventAll", "Number of junk hits per event", nbinsHits, 0, xmaxHits);
125 m_badHitsPerEventAll->GetXaxis()->SetTitle("hits per event");
126 m_badHitsPerEventAll->GetYaxis()->SetTitle("entries per bin");
127
128 int nbinsTDC = 400;
129 double xminTDC = -100;
130 double xmaxTDC = 700;
131 m_goodTDCAll = new TH1F("goodTDCAll", "Raw time distribution of good hits", nbinsTDC, xminTDC, xmaxTDC);
132 m_goodTDCAll->SetXTitle("raw time [samples]");
133 m_goodTDCAll->SetYTitle("hits per sample");
134
135 m_badTDCAll = new TH1F("badTDCAll", "Raw time distribution of junk hits", nbinsTDC, xminTDC, xmaxTDC);
136 m_badTDCAll->SetXTitle("raw time [samples]");
137 m_badTDCAll->SetYTitle("hits per sample");
138
139 m_TOPOccAfterInjLER = new TH1F("TOPOccInjLER", "TOPOccInjLER/Time;Time in #mus;Nhits/Time (#mus bins)", 4000, 0, 20000);
140 m_TOPOccAfterInjHER = new TH1F("TOPOccInjHER", "TOPOccInjHER/Time;Time in #mus;Nhits/Time (#mus bins)", 4000, 0, 20000);
141 m_TOPEOccAfterInjLER = new TH1F("TOPEOccInjLER", "TOPEOccInjLER/Time;Time in #mus;Triggers/Time (#mus bins)", 4000, 0, 20000);
142 m_TOPEOccAfterInjHER = new TH1F("TOPEOccInjHER", "TOPEOccInjHER/Time;Time in #mus;Triggers/Time (#mus bins)", 4000, 0, 20000);
143
144 m_nhitInjLER = new TProfile2D("nhitInjLER",
145 "LER: average Nhits; "
146 "time since injection [msec]; time within beam cycle [syst. clk]; Nhits average",
147 160, 0, 80, 256, 0, 1280, 0, 100000);
148 m_nhitInjHER = new TProfile2D("nhitInjHER",
149 "HER: average Nhits; "
150 "time since injection [msec]; time within beam cycle [syst. clk]; Nhits average",
151 160, 0, 80, 256, 0, 1280, 0, 100000);
152 m_nhitInjLERcut = new TProfile2D("nhitInjLERcut",
153 "LER: average Nhits (Nhits>1000); "
154 "time since injection [msec]; time within beam cycle [syst. clk]; Nhits average",
155 160, 0, 80, 256, 0, 1280, 0, 100000);
156 m_nhitInjHERcut = new TProfile2D("nhitInjHERcut",
157 "HER: average Nhits (Nhits>1000); "
158 "time since injection [msec]; time within beam cycle [syst. clk]; Nhits average",
159 160, 0, 80, 256, 0, 1280, 0, 100000);
160 m_eventInjLER = new TH2F("eventInjLER",
161 "LER: event distribution; "
162 "time since injection [msec]; time within beam cycle [syst. clk]; events per bin",
163 160, 0, 80, 256, 0, 1280);
164 m_eventInjHER = new TH2F("eventInjHER",
165 "HER: event distribution; "
166 "time since injection [msec]; time within beam cycle [syst. clk]; events per bin",
167 160, 0, 80, 256, 0, 1280);
168 m_eventInjLERcut = new TH2F("eventInjLERcut",
169 "LER: event distribution (Nhits>1000); "
170 "time since injection [msec]; time within beam cycle [syst. clk]; events per bin",
171 160, 0, 80, 256, 0, 1280);
172 m_eventInjHERcut = new TH2F("eventInjHERcut",
173 "HER: event distribution (Nhits>1000); "
174 "time since injection [msec]; time within beam cycle [syst. clk]; events per bin",
175 160, 0, 80, 256, 0, 1280);
176
177 for (int i = 0; i < m_numModules; i++) {
178 int module = i + 1;
179 string name, title;
180 TH1F* h1 = 0;
181 TH2F* h2 = 0;
182
183 name = str(format("window_vs_asic_%1%") % (module));
184 title = str(format("Asic windows for slot #%1%") % (module));
185 h2 = new TH2F(name.c_str(), title.c_str(), 64, 0, 64, 512, 0, 512);
186 h2->SetStats(kFALSE);
187 h2->SetXTitle("ASIC number");
188 h2->SetYTitle("window number w.r.t reference window");
189 h2->SetMinimum(0);
190 m_window_vs_asic.push_back(h2);
191
192 name = str(format("good_hits_xy_%1%") % (module));
193 title = str(format("Distribution of good hits for slot #%1%") % (module));
194 h2 = new TH2F(name.c_str(), title.c_str(), 64, 0.5, 64.5, 8, 0.5, 8.5);
195 h2->SetStats(kFALSE);
196 h2->GetXaxis()->SetTitle("pixel column");
197 h2->GetYaxis()->SetTitle("pixel row");
198 h2->SetMinimum(0);
199 m_goodHitsXY.push_back(h2);
200
201 name = str(format("bad_hits_xy_%1%") % (module));
202 title = str(format("Distribution of junk hits for slot #%1%") % (module));
203 h2 = new TH2F(name.c_str(), title.c_str(), 64, 0.5, 64.5, 8, 0.5, 8.5);
204 h2->SetStats(kFALSE);
205 h2->GetXaxis()->SetTitle("pixel column");
206 h2->GetYaxis()->SetTitle("pixel row");
207 h2->SetMinimum(0);
208 m_badHitsXY.push_back(h2);
209
210 name = str(format("good_hits_asics_%1%") % (module));
211 title = str(format("Distribution of good hits for slot #%1%") % (module));
212 h2 = new TH2F(name.c_str(), title.c_str(), 64, 0, 64, 8, 0, 8);
213 h2->SetStats(kFALSE);
214 h2->GetXaxis()->SetTitle("ASIC number");
215 h2->GetYaxis()->SetTitle("ASIC channel");
216 h2->SetMinimum(0);
217 m_goodHitsAsics.push_back(h2);
218
219 name = str(format("bad_hits_asics_%1%") % (module));
220 title = str(format("Distribution of junk hits for slot #%1%") % (module));
221 h2 = new TH2F(name.c_str(), title.c_str(), 64, 0, 64, 8, 0, 8);
222 h2->SetStats(kFALSE);
223 h2->GetXaxis()->SetTitle("ASIC number");
224 h2->GetYaxis()->SetTitle("ASIC channel");
225 h2->SetMinimum(0);
226 m_badHitsAsics.push_back(h2);
227
228 name = str(format("good_TDC_%1%") % (module));
229 title = str(format("Raw time distribution of good hits for slot #%1%") % (module));
230 h1 = new TH1F(name.c_str(), title.c_str(), nbinsTDC, xminTDC, xmaxTDC);
231 h1->GetXaxis()->SetTitle("raw time [samples]");
232 h1->GetYaxis()->SetTitle("hits per sample");
233 m_goodTDC.push_back(h1);
234
235 name = str(format("bad_TDC_%1%") % (module));
236 title = str(format("Raw time distribution of junk hits for slot #%1%") % (module));
237 h1 = new TH1F(name.c_str(), title.c_str(), nbinsTDC, xminTDC, xmaxTDC);
238 h1->GetXaxis()->SetTitle("raw time [samples]");
239 h1->GetYaxis()->SetTitle("hits per sample");
240 m_badTDC.push_back(h1);
241
242 name = str(format("good_timing_%1%") % (module));
243 title = str(format("Time distribution of good hits for slot #%1%") % (module));
244 h1 = new TH1F(name.c_str(), title.c_str(), 200, -20, 80);
245 h1->GetXaxis()->SetTitle("time [ns]");
246 h1->GetYaxis()->SetTitle("hits per time bin");
247 m_goodTiming.push_back(h1);
248
249 name = str(format("good_timing_%1%BG") % (module));
250 title = str(format("Time distribution of good hits (background) for slot #%1%") % (module));
251 h1 = new TH1F(name.c_str(), title.c_str(), 200, -20, 80);
252 h1->GetXaxis()->SetTitle("time [ns]");
253 h1->GetYaxis()->SetTitle("hits per time bin");
254 m_goodTimingBG.push_back(h1);
255
256 name = str(format("good_channel_hits_%1%") % (module));
257 title = str(format("Distribution of good hits for slot #%1%") % (module));
258 int numPixels = geo->getModule(i + 1).getPMTArray().getNumPixels();
259 h1 = new TH1F(name.c_str(), title.c_str(), numPixels, 0, numPixels);
260 h1->GetXaxis()->SetTitle("channel number");
261 h1->GetYaxis()->SetTitle("hits per channel");
262 h1->SetMinimum(0);
263 m_goodChannelHits.push_back(h1);
264
265 name = str(format("bad_channel_hits_%1%") % (module));
266 title = str(format("Distribution of junk hits for slot #%1%") % (module));
267 h1 = new TH1F(name.c_str(), title.c_str(), numPixels, 0, numPixels);
268 h1->GetXaxis()->SetTitle("channel number");
269 h1->GetYaxis()->SetTitle("hits per channel");
270 h1->SetMinimum(0);
271 m_badChannelHits.push_back(h1);
272
273 name = str(format("pulseHeights_%1%") % (module));
274 title = str(format("Average pulse heights for slot #%1%") % (module));
275 auto* prof = new TProfile(name.c_str(), title.c_str(), 32, 0.5, 32.5, 0, 2000);
276 prof->GetXaxis()->SetTitle("PMT number");
277 prof->GetYaxis()->SetTitle("pulse height [ADC counts]");
278 prof->SetMarkerStyle(20);
279 prof->SetMinimum(0);
280 m_pulseHeights.push_back(prof);
281 }
282
283 m_skipProcFlag = new TH2F("skipProcFlag", "Skip processing flag; slot number; flag value", 64, 0.5, 16.5, 2, -0.5, 1.5);
284 m_skipProcFlag->GetXaxis()->SetNdivisions(16);
285 m_skipProcFlag->GetYaxis()->SetNdivisions(2);
286 m_skipProcFlag->SetMinimum(0);
287
288 m_injVetoFlag = new TH2F("injVetoFlag", "Injection veto flag; slot number; flag value", 64, 0.5, 16.5, 2, -0.5, 1.5);
289 m_injVetoFlag->GetXaxis()->SetNdivisions(16);
290 m_injVetoFlag->GetYaxis()->SetNdivisions(2);
291 m_injVetoFlag->SetMinimum(0);
292
293 m_injVetoFlagDiff = new TH1F("injVetoFlagDiff", "Injection veto flags check; ; fraction of events", 2, -0.5, 1.5);
294 m_injVetoFlagDiff->GetXaxis()->SetNdivisions(2);
295 m_injVetoFlagDiff->GetXaxis()->SetBinLabel(1, "flags the same");
296 m_injVetoFlagDiff->GetXaxis()->SetBinLabel(2, "flags differ");
297 m_injVetoFlagDiff->GetXaxis()->SetLabelSize(0.05);
298 m_injVetoFlagDiff->GetXaxis()->SetAlphanumeric();
299 m_injVetoFlagDiff->SetMinimum(0);
300
301 m_PSBypassMode = new TH2F("PSBypassMode", "PS-bypass mode; slot number; mode", 64, 0.5, 16.5, 8, -0.5, 7.5);
302 m_PSBypassMode->GetXaxis()->SetNdivisions(16);
303 m_PSBypassMode->GetYaxis()->SetNdivisions(8);
304 m_PSBypassMode->SetMinimum(0);
305
306 // cd back to root directory
307 oldDir->cd();
308 }

◆ defineHisto() [2/7]

void defineHisto ( )
overridevirtual

Define TTree branches to store fit results for each channel This TTree is saved in an output file given by "histoFileName" parameter of "HistoManager" module.

Reimplemented from HistoModule.

Definition at line 89 of file TOPGainEfficiencyCalculatorModule.cc.

90 {
91 m_tree = new TTree("tree", "TTree for gain/efficiency monitor summary");
92 m_branch[0].push_back(m_tree->Branch("slotId", &m_targetSlotId, "slotId/S"));
93 m_branch[0].push_back(m_tree->Branch("pmtId", &m_targetPmtId, "pmtId/S"));
94 m_branch[0].push_back(m_tree->Branch("pixelId", &m_pixelId, "pixelId/S"));
95 m_branch[0].push_back(m_tree->Branch("pmtChId", &m_pmtChId, "pmtChId/S"));
96 m_branch[0].push_back(m_tree->Branch("hvDiff", &m_hvDiff, "hvDiff/S"));
97 m_branch[0].push_back(m_tree->Branch("threshold", &m_threshold, "threshold/F"));
98 m_branch[0].push_back(m_tree->Branch("thresholdForIntegral", &m_thresholdForIntegral, "thresholdForIntegral/F"));
99
100 m_branch[1].push_back(m_tree->Branch("nCalPulse", &m_nCalPulse, "nCalPulse/I"));
101 m_branch[1].push_back(m_tree->Branch("hitTimingForGain", &m_hitTiming, "hitTimingForGain/F"));
102 m_branch[1].push_back(m_tree->Branch("hitTimingSigmaForGain", &m_hitTimingSigma, "hitTimingSigmaForGain/F"));
103 m_branch[1].push_back(m_tree->Branch("nEntriesForGain", &m_nEntries, "nEntriesForGain/I"));
104 m_branch[1].push_back(m_tree->Branch("nOverflowEventsForGain", &m_nOverflowEvents, "nOverflowEventsForGain/I"));
105 m_branch[1].push_back(m_tree->Branch("meanPulseHeightForGain", &m_meanPulseHeight, "meanPulseHeightForGain/F"));
106 m_branch[1].push_back(m_tree->Branch("meanPulseHeightErrorForGain", &m_meanPulseHeightError, "meanPulseHeightErrorForGain/F"));
107 m_branch[1].push_back(m_tree->Branch("fitMaxForGain", &m_fitMax, "fitMaxForGain/F"));
108 m_branch[1].push_back(m_tree->Branch("gain", &m_gain, "gain/F"));
109 m_branch[1].push_back(m_tree->Branch("efficiency", &m_efficiency, "efficiency/F"));
110 m_branch[1].push_back(m_tree->Branch("p0ForGain", &m_p0, "p0ForGain/F"));
111 m_branch[1].push_back(m_tree->Branch("p1ForGain", &m_p1, "p1ForGain/F"));
112 m_branch[1].push_back(m_tree->Branch("p2ForGain", &m_p2, "p2ForGain/F"));
113 m_branch[1].push_back(m_tree->Branch("x0ForGain", &m_x0, "x0ForGain/F"));
114 m_branch[1].push_back(m_tree->Branch("p0ErrorForGain", &m_p0Error, "p0ErrorForGain/F"));
115 m_branch[1].push_back(m_tree->Branch("p1ErrorForGain", &m_p1Error, "p1ErrorForGain/F"));
116 m_branch[1].push_back(m_tree->Branch("p2ErrorForGain", &m_p2Error, "p2ErrorForGain/F"));
117 m_branch[1].push_back(m_tree->Branch("x0ErrorForGain", &m_x0Error, "x0ErrorForGain/F"));
118 m_branch[1].push_back(m_tree->Branch("chisquareForGain", &m_chisquare, "chisquareForGain/F"));
119 m_branch[1].push_back(m_tree->Branch("ndfForGain", &m_ndf, "ndfForGain/I"));
120 m_branch[1].push_back(m_tree->Branch("funcFullRangeIntegralForGain", &m_funcFullRangeIntegral, "funcFullRangeIntegralForGain/F"));
121 m_branch[1].push_back(m_tree->Branch("funcFitRangeIntegralForGain", &m_funcFitRangeIntegral, "funcFitRangeIntegralForGain/F"));
122 m_branch[1].push_back(m_tree->Branch("histoFitRangeIntegralForGain", &m_histoFitRangeIntegral, "histoFitRangeIntegralForGain/F"));
123 m_branch[1].push_back(m_tree->Branch("histoMeanAboveThreForGain", &m_histoMeanAboveThre, "histoMeanAboveThreForGain/F"));
124
125 m_branch[2].push_back(m_tree->Branch("hitTimingForEff", &m_hitTiming, "hitTimingForEff/F"));
126 m_branch[2].push_back(m_tree->Branch("hitTimingSigmaForEff", &m_hitTimingSigma, "hitTimingSigmaForEff/F"));
127 m_branch[2].push_back(m_tree->Branch("nEntriesForEff", &m_nEntries, "nEntriesForEff/I"));
128 m_branch[2].push_back(m_tree->Branch("nOverflowEventsForEff", &m_nOverflowEvents, "nOverflowEventsForEff/I"));
129 m_branch[2].push_back(m_tree->Branch("meanPulseHeightForEff", &m_meanPulseHeight, "meanPulseHeightForEff/F"));
130 m_branch[2].push_back(m_tree->Branch("meanPulseHeightErrorForEff", &m_meanPulseHeightError, "meanPulseHeightErrorForEff/F"));
131 m_branch[2].push_back(m_tree->Branch("histoMeanAboveThreForEff", &m_histoMeanAboveThre, "histoMeanAboveThreForEff/F"));
132
133 m_branch[3].push_back(m_tree->Branch("meanIntegral", &m_meanPulseHeight, "meanIntegral/F"));
134 m_branch[3].push_back(m_tree->Branch("meanIntegralError", &m_meanPulseHeightError, "meanIntegralError/F"));
135 m_branch[3].push_back(m_tree->Branch("nOverflowEventsUseIntegral", &m_nOverflowEvents, "nOverflowEventsUseIntegral/I"));
136 m_branch[3].push_back(m_tree->Branch("fitMaxUseIntegral", &m_fitMax, "fitMaxUseIntegral/F"));
137 m_branch[3].push_back(m_tree->Branch("gainUseIntegral", &m_gain, "gainUseIntegral/F"));
138 m_branch[3].push_back(m_tree->Branch("efficiencyUseIntegral", &m_efficiency, "efficiencyUseIntegral/F"));
139 m_branch[3].push_back(m_tree->Branch("p0UseIntegral", &m_p0, "p0UseIntegral/F"));
140 m_branch[3].push_back(m_tree->Branch("p1UseIntegral", &m_p1, "p1UseIntegral/F"));
141 m_branch[3].push_back(m_tree->Branch("p2UseIntegral", &m_p2, "p2UseIntegral/F"));
142 m_branch[3].push_back(m_tree->Branch("x0UseIntegral", &m_x0, "x0UseIntegral/F"));
143 m_branch[3].push_back(m_tree->Branch("p0ErrorUseIntegral", &m_p0Error, "p0ErrorUseIntegral/F"));
144 m_branch[3].push_back(m_tree->Branch("p1ErrorUseIntegral", &m_p1Error, "p1ErrorUseIntegral/F"));
145 m_branch[3].push_back(m_tree->Branch("p2ErrorUseIntegral", &m_p2Error, "p2ErrorUseIntegral/F"));
146 m_branch[3].push_back(m_tree->Branch("x0ErrorUseIntegral", &m_x0Error, "x0ErrorUseIntegral/F"));
147 m_branch[3].push_back(m_tree->Branch("chisquareUseIntegral", &m_chisquare, "chisquareUseIntegral/F"));
148 m_branch[3].push_back(m_tree->Branch("ndfUseIntegral", &m_ndf, "ndfUseIntegral/I"));
149 m_branch[3].push_back(m_tree->Branch("funcFullRangeIntegralUseIntegral", &m_funcFullRangeIntegral,
150 "funcFullRangeIntegralUseIntegral/F"));
151 m_branch[3].push_back(m_tree->Branch("funcFitRangeIntegralUseIntegral", &m_funcFitRangeIntegral,
152 "funcFitRangeIntegralUseIntegral/F"));
153 m_branch[3].push_back(m_tree->Branch("histoFitRangeIntegralUseIntegral", &m_histoFitRangeIntegral,
154 "histoFitRangeIntegralUseIntegral/F"));
155 m_branch[3].push_back(m_tree->Branch("histoMeanAboveThreUseIntegral", &m_histoMeanAboveThre, "histoMeanAboveThreUseIntegral/F"));
156
157 }

◆ defineHisto() [3/7]

void defineHisto ( )
overridevirtual

Module functions to define histograms.

Reimplemented from HistoModule.

Definition at line 97 of file TOPInterimFENtupleModule.cc.

98 {
99
100 m_tree = new TTree("tree", "TTree for generator output");
101
102 std::ostringstream nModuleStr;
103 nModuleStr << "[" << c_NModule << "]";
104
105 m_tree->Branch("nHit", &m_nHit, "nHit/I");
106 m_tree->Branch("eventNum", &m_eventNum, "eventNum/i");
107 m_tree->Branch("eventNumCopper", m_eventNumCopper,
108 std::string(std::string("eventNumCopper") + nModuleStr.str() + "/i").c_str());
109 m_tree->Branch("ttuTime", m_ttuTime,
110 std::string(std::string("ttuTime") + nModuleStr.str() + "/i").c_str());
111 m_tree->Branch("ttcTime", m_ttcTime,
112 std::string(std::string("ttcTime") + nModuleStr.str() + "/i").c_str());
113 m_tree->Branch("slotNum", m_slotNum, "slotNum[nHit]/S");
114 m_tree->Branch("pixelId", m_pixelId, "pixelId[nHit]/S");
115 m_tree->Branch("channelId", m_channelId, "channel[nHit]/S");
116 m_tree->Branch("isCalCh", m_isCalCh, "isCalCh[nHit]/O");
117 m_tree->Branch("winNum", m_winNum, "winNum[nHit]/S");
118 m_tree->Branch("eventWinNum", m_eventWinNum, "eventWinNum[nHit]/S");
119 m_tree->Branch("trigWinNum", m_trigWinNum, "trigWinNum[nHit]/S");
120 m_tree->Branch("revo9Counter", m_revo9Counter, "revo9Counter[nHit]/S");
121 m_tree->Branch("windowsInOrder", m_windowsInOrder, "windowsInOrder[nHit]/O");
122 m_tree->Branch("hitQuality", m_hitQuality, "hitQuality[nHit]/b");
123 m_tree->Branch("time", m_time, "time[nHit]/F");
124 m_tree->Branch("rawTime", m_rawTime, "rawTime[nHit]/F");
125 m_tree->Branch("refTime", m_refTime, "refTime[nHit]/F");
126 m_tree->Branch("globalRefTime", &m_globalRefTime, "globalRefTime/F");
127 m_tree->Branch("sample", m_sample, "sample[nHit]/s");
128 m_tree->Branch("height", m_height, "height[nHit]/F");
129 m_tree->Branch("integral", m_integral, "integral[nHit]/F");
130 m_tree->Branch("width", m_width, "width[nHit]/F");
131 m_tree->Branch("peakSample", m_peakSample, "peakSampe[nHit]/s");
132 m_tree->Branch("offlineFlag", m_offlineFlag, "offlineFlag[nHit]/B");
133 m_tree->Branch("nHitOfflineFE", m_nHitOfflineFE, "nHitOfflineFE[nHit]/S");
134 std::ostringstream brstr[2];
135 brstr[0] << "winNumList[nHit][" << c_NWindow << "]/S";
136 m_tree->Branch("winNumList", m_winNumList, brstr[0].str().c_str());
137 if (m_saveWaveform) {
138 brstr[1] << "waveform[nHit][" << c_NWaveformSample << "]/S";
139 m_tree->Branch("waveform", m_waveform, brstr[1].str().c_str());
140 }
141 m_tree->Branch("waveformStartSample", m_waveformStartSample, "waveformStartSample[nHit]/S");
142 m_tree->Branch("nWaveformSample", m_nWaveformSample, "nWaveformSample[nHit]/s");
143
144 m_tree->Branch("nFEHeader", &m_nFEHeader, "nFEHeader/S");
145 m_tree->Branch("nEmptyFEHeader", &m_nEmptyFEHeader, "nEmptyFEHeader/S");
146 m_tree->Branch("nWaveform", &m_nWaveform, "nWaveform/S");
147 m_tree->Branch("errorFlag", &m_errorFlag, "errorFlag/i");
148 m_tree->Branch("eventErrorFlag", &m_eventErrorFlag, "eventErrorFlag/i");
149
150 m_tree->Branch("nDebugInfo", &m_nDebugInfo, "nDebugInfo/I");
151 m_tree->Branch("scordCtime", m_scrodCtime, "scrodCtime[nDebugInfo]/s");
152 m_tree->Branch("phase", m_phase, "phase[nDebugInfo]/s");
153 m_tree->Branch("asicMask", m_asicMask, "asicMask[nDebugInfo]/s");
154 m_tree->Branch("eventQueuDepth", m_eventQueuDepth, "eventQueuDepth[nDebugInfo]/s");
155 m_tree->Branch("eventNumberByte", m_eventNumberByte, "eventNumberByte[nDebugInfo]/s");
156 }

◆ defineHisto() [4/7]

void defineHisto ( )
overridevirtual

create timing-height 2D histograms for all 8192 pixels

Reimplemented from HistoModule.

Definition at line 101 of file TOPLaserHitSelectorModule.cc.

102 {
103 for (int iPixel = 0 ; iPixel < c_NPixelPerModule * c_NModule ; iPixel++) {
104
105 short slotId = (iPixel / c_NPixelPerModule) + 1;
106 short pixelId = (iPixel % c_NPixelPerModule) + 1;
107 short pmtId = ((pixelId - 1) % c_NPixelPerRow) / c_NChannelPerPMTRow + c_NPMTPerRow * ((pixelId - 1) / (c_NPixelPerModule / 2)) + 1;
108 short pmtChId = (pixelId - 1) % c_NChannelPerPMTRow + c_NChannelPerPMTRow * ((pixelId - 1) %
109 (c_NPixelPerModule / 2) / c_NPixelPerRow) + 1;
110
111 std::ostringstream pixelstr;
112 pixelstr << "s" << std::setw(2) << std::setfill('0') << slotId << "_PMT"
113 << std::setw(2) << std::setfill('0') << pmtId
114 << "_" << std::setw(2) << std::setfill('0') << pmtChId;
115
116 std::ostringstream hnameForgain;
117 hnameForgain << "hTimeHeight_gain_" << pixelstr.str();
118 std::ostringstream htitleForgain;
119 htitleForgain << "2D distribution of hit timing and pulse height for Gain" << pixelstr.str();
120 m_TimeHeightHistogramForFit[iPixel] = new TH2F(hnameForgain.str().c_str(), htitleForgain.str().c_str(),
121 m_timeHistogramBinning[0], m_timeHistogramBinning[1], m_timeHistogramBinning[2],
122 m_chargeHistogramBinning[0], m_chargeHistogramBinning[1],
123 m_chargeHistogramBinning[2]);
124
125 std::ostringstream hnameForIntegral;
126 hnameForIntegral << "hTimeIntegral_gain_" << pixelstr.str();
127 std::ostringstream htitleForIntegral;
128 htitleForIntegral << "2D distribution of hit timing and integral for Gain" << pixelstr.str();
129 m_TimeIntegralHistogramForFit[iPixel] = new TH2F(hnameForIntegral.str().c_str(), htitleForIntegral.str().c_str(),
130 m_timeHistogramBinning[0], m_timeHistogramBinning[1], m_timeHistogramBinning[2],
131 m_chargeHistogramBinning[3], m_chargeHistogramBinning[4],
132 m_chargeHistogramBinning[5]);
133
134 std::ostringstream hnameForeff;
135 hnameForeff << "hTimeHeight_efficiency_" << pixelstr.str();
136 std::ostringstream htitleForeff;
137 htitleForeff << "2D distribution of hit timing and pulse height for efficiency" << pixelstr.str();
138 m_TimeHeightHistogramForHitRate[iPixel] = new TH2F(hnameForeff.str().c_str(), htitleForeff.str().c_str(),
139 m_timeHistogramBinning[0], m_timeHistogramBinning[1], m_timeHistogramBinning[2],
140 m_chargeHistogramBinning[0], m_chargeHistogramBinning[1],
141 m_chargeHistogramBinning[2]);
142 }
143
144 const short nAsic = c_NPixelPerModule / c_NChannelPerAsic * c_NChannelPerPMT;
145 m_nCalPulseHistogram = new TH1F("hNCalPulse", "number of calibration pulses identificed for each asic",
146 nAsic, -0.5, nAsic - 0.5);
147 }

◆ defineHisto() [5/7]

void defineHisto ( )
overridevirtual

Histogram definitions such as TH1(), TH2(), TNtuple(), TTree()....

are supposed to be placed in this function.

Reimplemented from HistoModule.

Definition at line 69 of file TOPPDFCheckerModule.cc.

70 {
71
72 // time vs. pixel ID
73 m_hits = new TH2F("hits", "photon hits", 512, 0.5, 512.5,
74 m_numBins, m_minTime, m_maxTime);
75 m_hits->SetXTitle("pixel ID");
76 m_hits->SetYTitle("time [ns]");
77
78 m_pdf = new TH2F("pdf", "PDF", 512, 0.5, 512.5,
79 m_numBins, m_minTime, m_maxTime);
80 m_pdf->SetXTitle("pixel ID");
81 m_pdf->SetYTitle("time [ns]");
82
83 // time vs pixel column
84 m_hitsCol = new TH2F("hitsCol", "photon hits", 64, 0.5, 64.5,
85 m_numBins, m_minTime, m_maxTime);
86 m_hitsCol->SetXTitle("pixel column");
87 m_hitsCol->SetYTitle("time [ns]");
88
89 m_pdfCol = new TH2F("pdfCol", "PDF", 64, 0.5, 64.5,
90 m_numBins, m_minTime, m_maxTime);
91 m_pdfCol->SetXTitle("pixel column");
92 m_pdfCol->SetYTitle("time [ns]");
93
94 }

◆ defineHisto() [6/7]

void defineHisto ( )
overridevirtual

Defining the histograms.

Reads once the m_inputDirectoryList to initialize the proper amount of histograms. Every new histogram added to the module has to be initialized here.

Reimplemented from HistoModule.

Definition at line 61 of file TOPTBCComparatorModule.cc.

62 {
63 // opens the file containing the list of directories and the labels
64 ifstream inputDirectoryListFile(m_inputDirectoryList.c_str());
65
66 // checks the input file
67 if (!inputDirectoryListFile) {
68 B2ERROR("Unable to open the input file with the list of CalSets to analyze");
69 return;
70 }
71
72 B2INFO("Initializing histograms");
73
74
75 std::string inputString;
76
77 // reads the Input file line by-line to initialize the correct number of histogram sets, and reads the labels..
78 // This is effectively a loop over all the calsets.
79 while (std::getline(inputDirectoryListFile, inputString)) {
80
81 // This initializes m_calSetDirectory and m_calSetLabel, even if now only m_calSetLabel will be used
82 parseInputDirectoryLine(inputString);
83
84 B2INFO("Initializing histograms for Calibration set located at " << m_calSetDirectory << " with label " << m_calSetLabel);
85
86 // To be used to initialize the histograms in the following
87 std::string name;
88 std::string title;
89
90
91 // ------
92 // Calset-by-calset histograms.
93 // initialize here all the histograms that appear once per calibration set, and not slot-by-slot
94 // ------
95
96 // Average DeltaT across the whole detector
97 name = str(format("TOPAverageDeltaT_CalSet_%1%") % m_calSetLabel);
98 title = str(format("Average value of #Delta T VS global channel number. CalSet %1%") % m_calSetLabel);
99 m_topAverageDeltaT.push_back(new TH1F(name.c_str(), title.c_str(), 512 * 16, 0., 512 * 16.));
100
101 // St.dev. of Delta T across the whole detector
102 name = str(format("TOPSigmaDeltaT_CalSet_%1%") % m_calSetLabel);
103 title = str(format("Sigma value of #Delta T VS global channel number. CalSet %1%") % m_calSetLabel);
104 m_topSigmaDeltaT.push_back(new TH1F(name.c_str(), title.c_str(), 512 * 16, 0., 512 * 16.));
105
106 // Average occupancy agross the whole detector
107 name = str(format("TOPSampleOccupancy_CalSet_%1%") % m_calSetLabel);
108 title = str(format("Average number of calpulses per sample VS global channel number. CalSet %1%") % m_calSetLabel);
109 m_topSampleOccupancy.push_back(new TH1F(name.c_str(), title.c_str(), 512 * 16, 0., 512 * 16.));
110
111
112 // Ratio of the average DeltaT across the whole detector
113 name = str(format("TOPAverageDeltaTComparison_CalSet_%1%") % m_calSetLabel);
114 title = str(format("Ratio of the average #Delta T in CalSet %1% over the previous one, over the whole detector") % m_calSetLabel);
115 m_topAverageDeltaTComparison.push_back(new TH1F(name.c_str(), title.c_str(), 512 * 16, 0., 512 * 16.));
116
117 // Ratio of the st.dev on DeltaT across the whole detector
118 name = str(format("TOPSigmaDeltaTComparison_CalSet_%1%") % m_calSetLabel);
119 title = str(format("Ratio of the st. dev. of #Delta T in CalSet %1% over the previous one, , over the whole detector") %
120 m_calSetLabel);
121 m_topSigmaDeltaTComparison.push_back(new TH1F(name.c_str(), title.c_str(), 512 * 16, 0., 512 * 16.));
122
123 // Ratio of the average number of calpulses across the whole detector
124 name = str(format("TOPSampleOccupancyComparison_CalSet_%1%") % m_calSetLabel);
125 title = str(
126 format("Ratio of the average number of calpulses per sample in CalSet %1% over the previous one, over the whole detector") %
127 m_calSetLabel);
128 m_topSampleOccupancyComparison.push_back(new TH1F(name.c_str(), title.c_str(), 512 * 16, 0., 512 * 16.));
129
130
131 // ------
132 // Slot-by-slot histograms.
133 // Use this loop to initialize all the histograms that appear once per calibration set and per each slot
134 // ------
135 for (int iSlot = 0; iSlot < 16; iSlot ++) {
136
137 // Average DeltaT stuff
138 name = str(format("SlotAverageDeltaT_Slot%1%_CalSet_%2%") % (iSlot) % m_calSetLabel);
139 title = str(format("Average value of #Delta T VS Channel number. Slot %1%, CalSet %2%") % (iSlot) % m_calSetLabel);
140 m_slotAverageDeltaT[iSlot].push_back(new TH1F(name.c_str(), title.c_str(), 512, 0., 512.));
141
142 name = str(format("SlotSigmaDeltaT_Slot%1%_CalSet_%2%") % (iSlot) % m_calSetLabel);
143 title = str(format("Standard deviation of #Delta T VS Channel number. Slot %1%, CalSet %2%") % (iSlot) % m_calSetLabel);
144 m_slotSigmaDeltaT[iSlot].push_back(new TH1F(name.c_str(), title.c_str(), 512, 0., 512.));
145
146 name = str(format("SlotAverageDeltaTMap_Slot%1%_CalSet_%2%") % (iSlot) % m_calSetLabel);
147 title = str(format("Map of the average value of #Delta T on the 256 samples. Slot %1%, CalSet %2%") % (iSlot) % m_calSetLabel);
148 m_slotAverageDeltaTMap[iSlot].push_back(new TH2F(name.c_str(), title.c_str(), 64, 0., 64., 8, 0., 8.));
149
150 name = str(format("SlotSigmaDeltaTMap_Slot%1%_CalSet_%2%") % (iSlot) % m_calSetLabel);
151 title = str(format("Map of the RMS of #Delta T on the 256 samples . Slot %1%, CalSet %2%") % (iSlot) % m_calSetLabel);
152 m_slotSigmaDeltaTMap[iSlot].push_back(new TH2F(name.c_str(), title.c_str(), 64, 0., 64., 8, 0., 8.));
153
154
155 // Occupancy stuff
156 name = str(format("SlotSampleOccupancy_Slot%1%_CalSet_%2%") % (iSlot) % m_calSetLabel);
157 title = str(format("Average occupancy per sample. Slot %1%, CalSet %2%") % (iSlot) % m_calSetLabel);
158 m_slotSampleOccupancy[iSlot].push_back(new TH1F(name.c_str(), title.c_str(), 512, 0., 512.));
159
160 name = str(format("SlotEmptySamples_Slot%1%_CalSet_%2%") % (iSlot) % m_calSetLabel);
161 title = str(format("Number samples with less than %3% calpulses per each slot channel. Slot %1%, CalSet %2%") %
162 (iSlot) % m_calSetLabel % m_minCalPulses);
163 m_slotEmptySamples[iSlot].push_back(new TH1F(name.c_str(), title.c_str(), 512, 0., 512.));
164
165 name = str(format("SlotSampleOccupancyMap_Slot%1%_CalSet_%2%") % (iSlot) % m_calSetLabel);
166 title = str(format("Map of the average occupancy per sample. Slot %1%, CalSet %2%") %
167 (iSlot) % m_calSetLabel);
168 m_slotSampleOccupancyMap[iSlot].push_back(new TH2F(name.c_str(), title.c_str(), 64, 0., 64., 8, 0., 8.));
169
170 name = str(format("SlotEmptySamplesMap_Slot%1%_CalSet_%2%") % (iSlot) % m_calSetLabel);
171 title = str(format("Map of the number samples with less than %3% calpulses per each. Slot %1%, CalSet %2%") %
172 (iSlot) % m_calSetLabel % m_minCalPulses);
173 m_slotEmptySamplesMap[iSlot].push_back(new TH2F(name.c_str(), title.c_str(), 64, 0., 64., 8, 0., 8.));
174
175
176
177 // Ratios
178 name = str(format("SlotAverageDeltaTComparison_Slot%1%_CalSet_%2%") % (iSlot) % m_calSetLabel);
179 title = str(format("Ratio of the average #Delta T in CalSet %2% over the previous one. Slot %1%") % (iSlot) % m_calSetLabel);
180 m_slotAverageDeltaTComparison[iSlot].push_back(new TH1F(name.c_str(), title.c_str(), 512, 0., 512.));
181
182 name = str(format("SlotRMSDeltaTComparison_Slot%1%_CalSet_%2%") % (iSlot) % m_calSetLabel);
183 title = str(format("Ratio of the RMS of #Delta T in CalSet %2% over the previous one. Slot %1%") % (iSlot) % m_calSetLabel);
184 m_slotSigmaDeltaTComparison[iSlot].push_back(new TH1F(name.c_str(), title.c_str(), 512, 0., 512.));
185
186 name = str(format("SlotAverageDeltaTMapComparison_Slot%1%_CalSet_%2%") % (iSlot) % m_calSetLabel);
187 title = str(format("Map of the ratio of the average #Delta T in CalSet %2% over the previous one. Slot %1%") %
188 (iSlot) % m_calSetLabel);
189 m_slotAverageDeltaTMapComparison[iSlot].push_back(new TH2F(name.c_str(), title.c_str(), 64, 0., 64., 8, 0., 8.));
190
191 name = str(format("SlotRMSDeltaTMapComparison_Slot%1%_CalSet_%2%") % (iSlot) % m_calSetLabel);
192 title = str(format("Map of the ratio of the RMS of #Delta T in CalSet %2% over the previous one. Slot %1%") %
193 (iSlot) % m_calSetLabel);
194 m_slotSigmaDeltaTMapComparison[iSlot].push_back(new TH2F(name.c_str(), title.c_str(), 64, 0., 64., 8, 0., 8.));
195
196 }
197
198 //counts how many sets are there. To be used when doing the ratios
199 m_totCalSets++;
200 }
201 B2INFO("Initialization of the histograms for " << m_totCalSets << " CalSets done.");
202 return;
203 }

◆ defineHisto() [7/7]

void defineHisto ( )
overridevirtual

Books the empty histograms.

Reimplemented from HistoModule.

Definition at line 50 of file TOPWaveformQualityPlotterModule.cc.

51 {
52 TDirectory* oldDir = gDirectory;
53 m_directory = oldDir->mkdir(m_histogramDirectoryName.c_str());
54 m_directory->cd();
55 m_samples = new TH1F("ADCvalues", "ADC values ", 100, -50, 50);
56 m_samples->GetXaxis()->SetTitle("ADC Value");
57 m_samples->GetYaxis()->SetTitle("Number of Samples");
58 m_scrod_id = new TH1F("scrodID", "scrodID", 100, 0, 100);
59 m_asic = new TH1F("IRSX", "IRSX", 4, 0, 4);
60 m_carrier = new TH1F("carrier", "asic col", 4, 0, 4);
61 m_asic_ch = new TH1F("asicCh", "channel", 8, 0, 8);
62 m_errorFlag = new TH1F("errorFlag", "errorFlag", 1000, 0, 1000);
63 m_asic_win = new TH1F("window", "window", 4, 0, 4);
64 m_entries = new TH1F("entries", "entries", 100, 0, 2600);
65 m_moduleID = new TH1F("moduleID", "moduleID", 16, 1, 17);
66 m_pixelID = new TH1F("pixelID", "pixelID", 512, 1, 513);
67 oldDir->cd();
68 }

◆ DrawResult()

void DrawResult ( const std::string & histotype,
EHistogramType LoadHisto )

Draw results of gain/efficiency calculation for each channel to a given output file.

Definition at line 450 of file TOPGainEfficiencyCalculatorModule.cc.

451 {
452 std::ostringstream pdfFilename;
453 pdfFilename << m_outputPDFFile << "_" << histotype;
454 if (m_targetPmtChId != -1)
455 pdfFilename << "_" << "ch" << std::setw(2) << std::setfill('0') << m_targetPmtChId;
456 pdfFilename << ".pdf";
457
458 gStyle->SetFrameFillStyle(0);
459 gStyle->SetFillStyle(0);
460 gStyle->SetStatStyle(0);
461 gStyle->SetOptStat(112210);
462 gStyle->SetOptFit(1110);
463 TCanvas* canvas = new TCanvas();
464 canvas->SetFillStyle(0);
465 canvas->Print((pdfFilename.str() + "[").c_str());
466
467 TLine* line = new TLine();
468 line->SetLineWidth(1);
469 line->SetLineStyle(1);
470 line->SetLineColor(4);
471 TArrow* arrow = new TArrow();
472 arrow->SetLineWidth(1);
473 arrow->SetLineStyle(1);
474 arrow->SetLineColor(3);
475 TLatex* latex = new TLatex();
476 latex->SetNDC();
477 latex->SetTextFont(22);
478 latex->SetTextSize(0.05);
479 latex->SetTextAlign(32);
480 TObject* object;
481
482 float threshold;
483 if (LoadHisto == c_LoadForFitIntegral) threshold = m_thresholdForIntegral;
484 else threshold = m_threshold;
485
486 for (int iHisto = 0 ; iHisto < c_NChannelPerPMT ; iHisto++) {
487
488 if ((iHisto % c_NChannelPerPage) == 0) {
489 canvas->Clear();
490 canvas->Divide(c_NPlotsPerChannel, c_NChannelPerPage);
491 }
492
493 //2D (time vs pulse charge) histogram
494 canvas->cd(3 * (iHisto % c_NChannelPerPage) + 1);
495 gPad->SetFrameFillStyle(0);
496 gPad->SetFillStyle(0);
497 TH2F* h2D = m_timeChargeHistogram[iHisto];
498 if (h2D) {
499 h2D->Draw("colz");
500 h2D->GetXaxis()->SetTitle("hit timing [ns]");
501 h2D->GetYaxis()->SetTitle("pulse charge [ADC count]");
502 }
503
504 //timing histogram
505 canvas->cd(c_NPlotsPerChannel * (iHisto % c_NChannelPerPage) + 2);
506 gPad->SetFrameFillStyle(0);
507 gPad->SetFillStyle(0);
508 TH1D* hTime = m_timeHistogram[iHisto];
509 if (hTime) {
510 gPad->SetLogy();
511 hTime->Draw();
512 hTime->SetLineColor(1);
513 hTime->GetXaxis()->SetTitle("hit timing [ns]");
514 float binWidth = hTime->GetXaxis()->GetBinUpEdge(1) - hTime->GetXaxis()->GetBinLowEdge(1);
515 std::ostringstream ytitle;
516 ytitle << "Entries [/(" << binWidth << " ns)]";
517 hTime->GetYaxis()->SetTitle(ytitle.str().c_str());
518
519 TF1* funcLaser = m_funcForLaser[iHisto];
520 if (funcLaser) {
521 double charge = funcLaser->GetParameter(0);
522 double peakTime = funcLaser->GetParameter(1);
523 float xMin = hTime->GetXaxis()->GetBinLowEdge(hTime->GetXaxis()->FindBin(peakTime - 2 * m_fitHalfWidth));
524 float xMax = hTime->GetXaxis()->GetBinUpEdge(hTime->GetXaxis()->FindBin(peakTime + 2 * m_fitHalfWidth));
525 line->DrawLine(xMin, 0.5, xMin, charge * 2.);
526 line->DrawLine(xMax, 0.5, xMax, charge * 2.);
527 arrow->DrawArrow(xMin, charge * 1.5, xMax, charge * 1.5, 0.01, "<>");
528 }
529 }
530
531 //charge histogram with fit result (after timing cut)
532 canvas->cd(c_NPlotsPerChannel * (iHisto % c_NChannelPerPage) + 3);
533 gPad->SetFrameFillStyle(0);
534 gPad->SetFillStyle(0);
535 TH1D* hCharge = m_chargeHistogram[iHisto];
536 if (hCharge) {
537 gPad->SetLogy();
538 hCharge->Draw();
539 hCharge->SetLineColor(1);
540 hCharge->GetXaxis()->SetTitle("charge [ADC counts]");
541 float binWidth = hCharge->GetXaxis()->GetBinUpEdge(1) - hCharge->GetXaxis()->GetBinLowEdge(1);
542 std::ostringstream ytitle;
543 ytitle << "Entries [/(" << binWidth << " ADC counts)]";
544 hCharge->GetYaxis()->SetTitle(ytitle.str().c_str());
545
546 if (m_funcForFitRange[iHisto] && m_funcForFullRange[iHisto]) {
547 m_funcForFullRange[iHisto]->Draw("same");
548 m_funcForFitRange[iHisto]->Draw("same");
549 double charge = hCharge->GetBinContent(hCharge->GetMaximumBin());
550 line->DrawLine(threshold, 0.5, threshold, charge * 2.);
551
552 if ((object = gROOT->FindObject("dummy"))) delete object;
553 std::ostringstream cut;
554 cut << "pmtChId==" << (iHisto + 1);
555 long nEntries = 0;
556 std::ostringstream summarystr[2];
557 if (LoadHisto == c_LoadForFitHeight) {
558 nEntries = m_tree->Project("dummy", "gain:efficiency", cut.str().c_str());
559 if (nEntries == 1) {
560 summarystr[0] << "gain = " << std::setiosflags(std::ios::fixed) << std::setprecision(1)
561 << m_tree->GetV1()[0];
562 latex->DrawLatex(0.875, 0.34, summarystr[0].str().c_str());
563 summarystr[1] << "efficiency = " << std::setiosflags(std::ios::fixed) << std::setprecision(1)
564 << (m_tree->GetV2()[0] * 100) << " %";
565 latex->DrawLatex(0.875, 0.29, summarystr[1].str().c_str());
566 }
567 } else if (LoadHisto == c_LoadForFitIntegral) {
568 nEntries = m_tree->Project("dummy", "gainUseIntegral:efficiencyUseIntegral", cut.str().c_str());
569 if (nEntries == 1) {
570 summarystr[0] << "gain = " << std::setiosflags(std::ios::fixed) << std::setprecision(1)
571 << m_tree->GetV1()[0];
572 latex->DrawLatex(0.875, 0.34, summarystr[0].str().c_str());
573 summarystr[1] << "efficiency = " << std::setiosflags(std::ios::fixed) << std::setprecision(1)
574 << (m_tree->GetV2()[0] * 100) << " %";
575 latex->DrawLatex(0.875, 0.29, summarystr[1].str().c_str());
576 }
577 }
578
579 if (nEntries > 1) {
580 B2WARNING("TOPGainEfficiencyCalculator : multiple entries with the same channel ID ("
581 << m_pmtChId << ") in the output TTree");
582 }
583 }
584 }
585
586 if (((iHisto + 1) % c_NChannelPerPage) == 0)
587 canvas->Print(pdfFilename.str().c_str());
588 }
589 /* not clear what is to be done here (loop condition is always false)... commented out
590 for (int iHisto = (c_NChannelPerPMT - 1) % c_NChannelPerPage + 1 ; iHisto < c_NChannelPerPage ; iHisto++) {
591 for (int iPad = 0 ; iPad < c_NPlotsPerChannel ; iPad++) {
592 canvas->cd(c_NPlotsPerChannel * (iHisto % c_NChannelPerPage) + iPad + 1);
593 gPad->SetFrameFillStyle(0);
594 gPad->SetFillStyle(0);
595 }
596 if (((iHisto + 1) % c_NChannelPerPage) == 0)
597 canvas->Print(pdfFilename.str().c_str());
598 }
599 */
600 canvas->Print((pdfFilename.str() + "]").c_str());
601
602 delete latex;
603 delete arrow;
604 delete line;
605 delete canvas;
606 if ((object = gROOT->FindObject("dummy"))) delete object;
607
608 return;
609 }

◆ drawWaveforms()

void drawWaveforms ( const TOPRawWaveform & rawwave)

Draws the full waveforms onto the TProfiles.

Parameters
rawwavethe raw waveform

Definition at line 110 of file TOPWaveformQualityPlotterModule.cc.

111 {
112 vector<short> waveform = v.getWaveform();
113 if (waveform.empty()) {
114 return;
115 }
116 int scrodid = v.getScrodID();
117 // skip broken events
118 if (scrodid == 0) {
119 return;
120 }
121 int asicNumber = v.getASICNumber();
122 int carrierNumber = v.getCarrierNumber();
123 int iChannel = v.getASICChannel();
124 string gname = string("scrod_") + to_string(scrodid) + string("_carrier") + to_string(carrierNumber) + string("_asic") + to_string(
125 asicNumber) + to_string(iChannel);
126 if (m_waveformHists[scrodid][carrierNumber][asicNumber].find(iChannel) ==
127 m_waveformHists[scrodid][carrierNumber][asicNumber].end()) {
128 // FIXME ? This assumes exactly 256 samples in a waveform (FE data)
129 auto h = new TProfile(gname.c_str(), gname.c_str(), 256, 0, 256);
130 h->Sumw2(false); // unweighted filling.
131 m_waveformHists[scrodid][carrierNumber][asicNumber][iChannel] = h;
132 }
133 // FIXME assumes 256 samples in a waveform
134 for (size_t i = 0; i < 256; ++i) {
135 // exit broken waveforms early
136 if (i >= waveform.size()) {
137 break;
138 }
139 m_waveformHists[scrodid][carrierNumber][asicNumber][iChannel]->Fill(i + 0.5, iChannel * 1500 + waveform[i]);
140 }
141 }

◆ DummyFillBranch()

void DummyFillBranch ( EHistogramType LoadHisto)

Fill Dummy for Branch.

Use it when there aren't 2D-Histogram.

Definition at line 417 of file TOPGainEfficiencyCalculatorModule.cc.

418 {
419 m_fitMax = -1;
420 m_hitTiming = -1;
421 m_hitTimingSigma = -1;
422 m_nEntries = -1;
423 m_nCalPulse = -1;
424 m_nOverflowEvents = -1;
425 m_meanPulseHeight = -1;
426 m_meanPulseHeightError = -1;
427 m_gain = -1;
428 m_efficiency = -1;
429 m_p0 = -1;
430 m_p1 = -1;
431 m_p2 = -1;
432 m_x0 = -1;
433 m_p0Error = -1;
434 m_p1Error = -1;
435 m_p2Error = -1;
436 m_x0Error = -1;
437 m_chisquare = -1;
438 m_ndf = -1;
439 m_funcFullRangeIntegral = -1;
440 m_funcFitRangeIntegral = -1;
441 m_histoFitRangeIntegral = -1;
442 m_histoMeanAboveThre = -1;
443
444 for (auto itr = m_branch[LoadHisto].begin(); itr != m_branch[LoadHisto].end(); ++itr) {
445 (*itr)->Fill();
446 }
447 }

◆ endRun() [1/4]

void endRun ( void )
overridevirtual

End-of-run action.

Save run-related stuff, such as statistics.

Reimplemented from Module.

Definition at line 394 of file TOPBackgroundModule.cc.

395 {
396 B2INFO("TOPBackground: Finished:");
397 }

◆ endRun() [2/4]

void endRun ( void )
overridevirtual

End-of-run action.

The main analysis loop over the calibration sets happens here. This function has to be modified only if the directory structure of the TOPTimeBaseCalibrator module output is changed Both the core functions analyzeCalFile() and makeComparisons() are called here.

Reimplemented from HistoModule.

Definition at line 343 of file TOPTBCComparatorModule.cc.

344 {
345 // opens the file containing the list of directories and the labels
346 ifstream inputDirectoryListFile(m_inputDirectoryList.c_str());
347
348 // checsk the input file
349 if (!inputDirectoryListFile) {
350 B2ERROR("Unable to open the input file with the list of CalSets to analyze");
351 return;
352 }
353
354 std::string inputString;
355 // reads the Input file line by-line
356 while (std::getline(inputDirectoryListFile, inputString)) {
357 // This initializes m_calSetDirectory and m_calSetLabel
358
359 parseInputDirectoryLine(inputString);
360
361 B2INFO("Processing the calibration set located in " << m_calSetDirectory << " and labelled " << m_calSetLabel);
362 TSystemDirectory calSetDir(m_calSetDirectory.c_str(), (m_calSetDirectory).c_str());
363
364 // lists the content of the directory
365 TList* calSetDirContent = calSetDir.GetListOfFiles();
366 if (calSetDirContent) {
367 TSystemFile* entry;
368 TIter next(calSetDirContent);
369 while ((entry = static_cast<TSystemFile*>(next()))) {
370
371 // gets the name of the entry in the list of the content of m_calSetDirectory
372 std::string entryName = entry->GetName();
373
374 // Case 1: the entry is already a root file
375 if (!entry->IsDirectory() && TString(entryName.c_str()).EndsWith(".root")) {
376 // Initializes the file name
377 m_calSetFile = new TFile((m_calSetDirectory + entryName).c_str(), " ");
378 // Finds out the Slot and BS ID
379 int parserStatus = parseSlotAndScrodIDfromFileName(entryName);
380 // Fills the histograms
381 if (parserStatus == 1)
382 analyzeCalFile();
383 // Closes the file
384 m_calSetFile->Close();
385 }
386
387 // Case 2: the entry is a sub-foder, containing the rootfiles
388 // The default directory structure is
389 // calSetDirectory/tbc_chxx/*.root,
390 // so this should be the normal case
391 if (entry->IsDirectory() && entryName != "." && entryName != "..") {
392 entryName += "/";
393 // resets the directory where to look for root files
394 TSystemDirectory calSetSubDir((m_calSetDirectory + entryName).c_str(), (m_calSetDirectory + entryName).c_str());
395
396 // lists the content of the directory
397 TList* calSetSubDirContent = calSetSubDir.GetListOfFiles();
398 if (calSetSubDirContent) {
399 TSystemFile* file;
400 TIter nextSub(calSetSubDirContent);
401 while ((file = static_cast<TSystemFile*>(nextSub()))) {
402 // gets the name of the entry in the list of the content of m_calSetDirectory
403 std::string fileName = file->GetName();
404
405 if (!file->IsDirectory() && TString(fileName.c_str()).EndsWith(".root")) {
406 // Initializes the file name
407 m_calSetFile = new TFile((m_calSetDirectory + entryName + fileName).c_str(), " ");
408 // Finds out the Slot and BS ID
409 int parserStatus = parseSlotAndScrodIDfromFileName(fileName);
410 // Fills the histograms
411 if (parserStatus == 1)
412 analyzeCalFile();
413 // Closes the file
414 m_calSetFile->Close();
415 } else if (file->IsDirectory() && fileName != "." && fileName != "..") {
416 B2WARNING("Additional subdirectory " << fileName << " found in " << m_calSetDirectory + entryName <<
417 ", where only .root and .log files are expected ");
418 continue;
419 }
420
421 }
422 }
423 }
424 }
425 } else {
426 B2WARNING("Error in creating the TList form the directory " << m_calSetDirectory);
427 continue;
428 }
429 m_calSetID++; // jump to the next directory (i.e. the next calset)
430 }
431 B2INFO("Analysis concluded.");
432
433 makeComparisons();
434
435 return;
436 }

◆ endRun() [3/4]

void endRun ( void )
overridevirtual

End-of-run action.

Save run-related stuff, such as statistics.

Reimplemented from Module.

Definition at line 1254 of file TOPUnpackerModule.cc.

1255 {
1256 B2INFO("TOPUnpacker: Channels seen per event statistics:");
1257 B2INFO("TOPUnpacker: nChn\tcount");
1258 for (const auto& entry : m_channelStatistics) {
1259 B2INFO("TOPUnpacker: " << entry.first << "\t\t" << entry.second);
1260 }
1261 }

◆ endRun() [4/4]

void endRun ( void )
overridevirtual

End-of-run action.

Save run-related stuff, such as statistics.

Reimplemented from HistoModule.

Definition at line 180 of file TOPWaveformQualityPlotterModule.cc.

181 {
182 if (m_DRAWWAVES) {
183 // Each waveform was stored in a TH1F
184 // This now gets transformed to a TGraph
185 // All 8 channels for a given ASIC are put in the same TMultiGraph
186 // Then we make one canvas of several TMultigraphs for each scrod
187 // FIXME: This is going to get called at the end of the run; the mem leak I am introducing here should be fixed by somebody more patient with ROOT memory management than me.
188 for (auto scrod_it : m_waveformHists) {
189 int scrodid = scrod_it.first;
190 string name = string("scrod_") + to_string(scrodid);
191 TCanvas* c = new TCanvas(name.c_str(), name.c_str());
192 c->Divide(4, 4);
193 int canvasPad = 0;
194 for (auto carrier_it : scrod_it.second) {
195 int carrierNumber = carrier_it.first;
196 for (auto asic_it : carrier_it.second) {
197 int asicNumber = asic_it.first;
198 canvasPad += 1;
199 string gname = string("scrod_") + to_string(scrodid) + string("_carrier") + to_string(carrierNumber) + string("_asic") + to_string(
200 asicNumber);
201 TMultiGraph* mg = new TMultiGraph(gname.c_str(), gname.c_str());
202 for (auto channel_it : asic_it.second) {
203 // read the data from the TProfile
204 TGraphErrors* g = new TGraphErrors(channel_it.second);
205 g->SetMarkerStyle(7);
206 mg->Add(g);
207 }
208 // FIXME nSamples is hard-coded to 256
209 TH2F* h = new TH2F(gname.c_str(), gname.c_str(), 256, 0, 256, 8, -500, -500 + 8 * 1500);
210 for (int ibin = 0; ibin < 8; ibin++) {
211 h->GetYaxis()->SetBinLabel(ibin + 1, to_string(ibin).c_str());
212 }
213 h->GetYaxis()->SetTickSize(0);
214 h->GetYaxis()->SetTickLength(0);
215 h->SetStats(0);
216 c->cd(canvasPad);
217 h->Draw();
218 mg->Draw("P");
219 }
220 }
221 m_directory->WriteTObject(c);
222 }
223 }
224 }

◆ event() [1/30]

void event ( void )
overridevirtual

Event processor.

Reimplemented from Module.

Definition at line 145 of file OpticalGunModule.cc.

146 {
147 // generate number of photons
148 int numPhotons = 1;
149 if (m_numPhotons > 0) numPhotons = gRandom->Poisson(m_numPhotons);
150
151 // start time
152 double startTime = m_startTime;
153 if (m_simCalPulses.getEntries() > 0) { // TOPCalPulseGenerator in the path
154 startTime += m_simCalPulses[0]->getTime(); // set start time w.r.t cal pulse
155 }
156
157 // generate photons and store them to MCParticles
158 for (int i = 0; i < numPhotons; i++) {
159
160 // generate emission point
161 double x, y;
162 do {
163 x = m_diameter * (gRandom->Rndm() - 0.5);
164 y = m_diameter * (gRandom->Rndm() - 0.5);
165 } while (x * x + y * y > m_diameter * m_diameter / 4.0);
166 XYZPoint point(x, y, 0);
167
168 // generate direction
169 XYZVector direction;
170 if (m_angularDistribution == string("uniform")) {
171 direction = getDirectionUniform();
172 } else if (m_angularDistribution == string("Lambertian")) {
173 direction = getDirectionLambertian();
174 } else if (m_angularDistribution == string("Gaussian")) {
175 direction = getDirectionGaussian();
176 } else { // we already have tested the formula and initialized the TF1 in the initialize() method
177 direction = getDirectionCustom();
178 }
179 XYZVector momentum = m_energy * direction;
180
181 // check if photon passes the slit
182 if (not isInsideSlit(point, direction)) continue;
183
184 // generate polarization vector (unpolarized light source assumed)
185 double alphaPol = 2.0 * M_PI * gRandom->Rndm();
186 XYZVector polarization(cos(alphaPol), sin(alphaPol), 0);
187 func::rotateUz(polarization, direction);
188
189 // generate emission time
190 double emissionTime = gRandom->Gaus(startTime, m_pulseWidth);
191
192 // transform to Belle II frame
193 point = m_transform * point;
194 momentum = m_transform * momentum;
195 polarization = m_transform * polarization;
196
197 // store generated photon
198 auto* part = m_MCParticles.appendNew();
199 part->setPDG(0); // optical photon
200 part->setMass(0);
201 part->setStatus(MCParticle::c_PrimaryParticle);
202 part->addStatus(MCParticle::c_StableInGenerator);
203 part->setProductionVertex(static_cast<XYZVector>(point));
204 part->setProductionTime(emissionTime);
205 part->setMomentum(momentum);
206 part->setEnergy(m_energy);
207 part->setDecayVertex(polarization); // use this location temporary to pass photon polarization to FullSim
208 }
209
210 }

◆ event() [2/30]

void event ( void )
overridevirtual

Event processor.

Reimplemented from Module.

Definition at line 162 of file TOPAlignerModule.cc.

163 {
164
165 // check bunch reconstruction status and run alignment:
166 // - if object exists and bunch is found (collision data w/ bunch finder in the path)
167 // - if object doesn't exist (cosmic data and other cases w/o bunch finder)
168
169 if (m_recBunch.isValid()) {
170 if (not m_recBunch->isReconstructed()) return;
171 }
172
173 // track-by-track iterations
174
175 for (const auto& track : m_tracks) {
176
177 // construct TOPtrack from mdst track
178 TOPTrack trk(track);
179 if (not trk.isValid()) continue;
180
181 // skip if track not hitting target module
182 if (trk.getModuleID() != m_targetMid) continue;
183
184 // track selection
185 if (not m_selector.isSelected(trk)) continue;
186
187 // do an iteration
188 int err = m_align.iterate(trk, m_chargedStable);
189 m_iter++;
190
191 // check number of consecutive failures, and in case reset
192 if (err == 0) {
193 m_countFails = 0;
194 } else if (m_countFails <= m_maxFails) {
195 m_countFails++;
196 } else {
197 B2INFO("Reached maximum allowed number of failed iterations. "
198 "Resetting TOPalign object");
199 m_align.reset();
200 m_countFails = 0;
201 }
202
203 // get new parameter values and estimated errors
204 m_vAlignPars = m_align.getParameters();
205 m_vAlignParsErr = m_align.getErrors();
206 m_ntrk = m_align.getNumUsedTracks();
207 m_errorCode = err;
208 m_valid = m_align.isValid();
209 m_numPhot = m_align.getNumOfPhotons();
210
211 // set other ntuple variables
212 const auto& localPosition = m_selector.getLocalPosition();
213 m_x = localPosition.X();
214 m_y = localPosition.Y();
215 m_z = localPosition.Z();
216 const auto& localMomentum = m_selector.getLocalMomentum();
217 m_p = localMomentum.R();
218 m_theta = localMomentum.Theta();
219 m_phi = localMomentum.Phi();
220 const auto& pocaPosition = m_selector.getPOCAPosition();
221 m_pocaR = pocaPosition.Rho();
222 m_pocaZ = pocaPosition.Z();
223 m_pocaX = pocaPosition.X();
224 m_pocaY = pocaPosition.Y();
225 m_cmsE = m_selector.getCMSEnergy();
226 m_charge = trk.getCharge();
227 m_PDG = trk.getPDGCode();
228
229 // fill output tree
230 m_alignTree->Fill();
231
232 // print info
233 TString resMsg = "M= ";
234 resMsg += m_align.getModuleID();
235 resMsg += " ntr=";
236 resMsg += m_ntrk;
237 resMsg += " err=";
238 resMsg += m_errorCode;
239 resMsg += " v=";
240 resMsg += m_align.isValid();
241 for (auto par : m_vAlignPars) {
242 resMsg += " ";
243 resMsg += par;
244 }
245 B2DEBUG(20, resMsg);
246
247 }
248
249 }

◆ event() [3/30]

void event ( void )
overridevirtual

Event processor.

Convert TOPSimHits of the event to TOPHits.

Reimplemented from Module.

Definition at line 196 of file TOPBackgroundModule.cc.

197 {
198 StoreArray<TOPSimHit> topSimhits;
199 StoreArray<MCParticle> mcParticles;
200 StoreArray<TOPDigit> topDigits;
201 StoreArray<TOPBarHit> topTracks;
202
203 int nHits = topDigits.getEntries();
204 for (int i = 0; i < nHits; i++) {
205 const TOPDigit* aDigit = topDigits[i];
206 int barID = aDigit->getModuleID();
207
208 peflux->AddBinContent(barID * 2, 1. / m_TimeOfSimulation / 32.0);
209
210 const TOPSimHit* simHit = DataStore::getRelated<TOPSimHit>(aDigit);
211 if (!simHit) continue;
212 int PMTID = simHit->getPmtID();
213
214 module_occupancy->SetPoint(count_occ, PMTID, barID);
215 count_occ++;
216
217 genergy->Fill(simHit->getEnergy());
218
219 const MCParticle* particle = DataStore::getRelated<MCParticle>(simHit);
220
221 if (particle) {
222 const MCParticle* currParticle = particle;
223
224 const MCParticle* mother = currParticle->getMother();
225
226 while (mother) {
227 const MCParticle* pommother = mother->getMother();
228 if (!pommother) {
229
230 zdist->Fill(mother->getVertex().Z());
231 zdistg->Fill(mother->getVertex().Z(), 1. / m_TimeOfSimulation / 32.0 / 16.0);
232 originpe_x = mother->getVertex().X();
233 originpe_y = mother->getVertex().Y();
234 originpe_z = mother->getVertex().Z();
235 originpe->Fill();
236 ROOT::Math::XYZVector momentum = mother->getMomentum();
237 if (m_BkgType.at(m_BkgType.size() - 3) == 'L') ROOT::Math::VectorUtil::RotateY(momentum, 0.0415);
238 else if (m_BkgType.at(m_BkgType.size() - 3) == 'H') ROOT::Math::VectorUtil::RotateY(momentum, -0.0415);
239 double px = momentum.X();
240 double py = momentum.Y();
241 double pt = sqrt(px * px + py * py);
242 originpt->Fill(pt);
243 }
244 mother = pommother;
245 }
246 }
247 }
248
249
250 StoreArray<BeamBackHit> beamBackHits;
251 nHits = beamBackHits.getEntries();
252
253 for (int iHit = 0; iHit < nHits; ++iHit) {
254 const BeamBackHit* tophit = beamBackHits[iHit];
255 int subdet = tophit->getSubDet();
256 if (subdet != 5) continue;
257
258 auto pos = tophit->getPosition();
259 double phi = ROOT::Math::VectorUtil::Phi_0_2pi(pos.Phi()) * TMath::RadToDeg();
260 int barID = int (phi / 22.5 + 0.5);
261 if (barID == 16) {
262 barID = 0;
263 }
264 barID++;
265
266
267 if (tophit->getPDG() == Const::neutron.getPDGCode()) {
268 double w = tophit->getNeutronWeight();
269 double tlen = tophit->getTrackLength();
270
271 nflux->AddBinContent(barID * 2, w / m_TimeOfSimulation / PCBarea * yearns * tlen / 0.2);
272
273 } else {
274 double edep = tophit->getEnergyDeposit();
275 rdose->AddBinContent(barID * 2, edep / m_TimeOfSimulation * yearns / PCBmass * evtoJ);
276 }
277 }
278
279 nHits = topTracks.getEntries();
280 for (int iHit = 0; iHit < nHits; ++iHit) {
281 const TOPBarHit* toptrk = topTracks[iHit];
282
283 int PDG = toptrk->getPDG();
284 int barID = toptrk->getModuleID();
285
286 if (PDG == Const::neutron.getPDGCode()) {
287 nflux_bar->Fill(toptrk->getPosition().Z(), (barID - 1) * 22.5,
288 1. / 917.65 / m_TimeOfSimulation * yearns * 2.);
289 norigin->Fill(toptrk->getProductionPoint().Z());
290 } else {
291 if (PDG == Const::photon.getPDGCode()) {
292 gflux_bar->Fill(toptrk->getPosition().Z(), (barID - 1) * 22.5,
293 1. / 917.65 / m_TimeOfSimulation * 2.);
294 gorigin->Fill(toptrk->getProductionPoint().Z());
295 genergy2->Fill(toptrk->getMomentum().R() * 1000);
296 origin_zx->SetPoint(count, toptrk->getProductionPoint().Z(),
297 toptrk->getProductionPoint().X());
298 origin_zy->SetPoint(count, toptrk->getProductionPoint().Z() / 0.999143,
299 toptrk->getProductionPoint().Y());
300 origingamma_x = toptrk->getProductionPoint().X();
301 origingamma_y = toptrk->getProductionPoint().Y();
302 origingamma_z = toptrk->getProductionPoint().Z();
303 origingamma->Fill();
304 count++;
305
306 } else {
307 cflux_bar->Fill(toptrk->getPosition().Z(), (barID - 1) * 22.5,
308 1. / 917.65 / m_TimeOfSimulation * 2.);
309 corigin->Fill(toptrk->getProductionPoint().Z());
310 }
311 }
312
313 }
314 }

◆ event() [4/30]

void event ( void )
overridevirtual

Event processor.

Reimplemented from Module.

Definition at line 238 of file TOPBunchFinderModule.cc.

239 {
240
241 m_processed++;
242 TOPRecoManager::setDefaultTimeWindow();
243
244 // define output for the reconstructed bunch
245
246 if (not m_recBunch.isValid()) {
247 m_recBunch.create();
248 } else {
249 m_revo9Counter = m_recBunch->getRevo9Counter();
250 m_recBunch->clearReconstructed();
251 }
252 m_timeZeros.clear();
253
254 if (not m_eventT0.isValid()) m_eventT0.create();
255
256 // set MC truth if available
257
258 if (m_initialParticles.isValid()) {
259 double simTime = m_initialParticles->getTime();
260 int simBunchNumber = round(simTime / m_bunchTimeSep);
261 m_recBunch->setSimulated(simBunchNumber, simTime);
262 }
263 m_isMC = m_recBunch->isSimulated();
264
265 // set revo9 counter from the first raw digit if available (all should be the same)
266
267 if (m_topRawDigits.getEntries() > 0) {
268 const auto* rawDigit = m_topRawDigits[0];
269 m_revo9Counter = rawDigit->getRevo9Counter();
270 m_recBunch->setRevo9Counter(m_revo9Counter);
271 }
272
273 // full time window in which data are taken (smaller time window is used in reconstruction)
274
275 const auto& tdc = TOPGeometryPar::Instance()->getGeometry()->getNominalTDC();
276 double timeWindow = m_feSetting->getReadoutWindows() * tdc.getSyncTimeBase() / static_cast<double>(TOPNominalTDC::c_syncWindows);
277
278 // counters and temporary containers
279
280 int numTrk = 0;
281 m_nodEdxCount = 0;
282 std::vector<TOPTrack> topTracks;
283 std::vector<PDFConstructor> pdfConstructors;
284 std::vector<PDF1Dim> top1Dpdfs;
285 std::vector<int> numPhotons;
286 std::vector<double> assumedMasses;
287 std::vector<Chi2MinimumFinder1D> finders;
288
289 // loop over reconstructed tracks, make a selection and push to containers
290
291 for (const auto& track : m_tracks) {
292 TOPTrack trk(track);
293 if (not trk.isValid()) continue;
294
295 // track selection
296 const auto* fitResult = track.getTrackFitResultWithClosestMass(Const::pion);
297 if (not fitResult) {
298 B2ERROR("No TrackFitResult available. Must be a bug somewhere.");
299 continue;
300 }
301 if (fitResult->getHitPatternCDC().getNHits() < m_minNHitsCDC) continue;
302 if (fabs(fitResult->getD0()) > m_maxD0) continue;
303 if (fabs(fitResult->getZ0()) > m_maxZ0) continue;
304 auto pt = fitResult->getTransverseMomentum();
305 if (pt < m_minPt or pt > m_maxPt) continue;
306
307 // determine most probable particle mass
308 auto chargedStable = Const::pion;
309 if (m_useMCTruth) {
310 if (not trk.getMCParticle()) continue;
311 if (not trk.getBarHit()) continue;
312 chargedStable = Const::chargedStableSet.find(abs(trk.getMCParticle()->getPDG()));
313 if (chargedStable == Const::invalidParticle) continue;
314 } else {
315 if (trk.getMomentumMag() < 4.0) chargedStable = getMostProbable(track);
316 }
317
318 // construct PDF
319 PDFConstructor pdfConstructor(trk, chargedStable, PDFConstructor::c_Rough);
320 if (not pdfConstructor.isValid()) continue;
321 numTrk++;
322
323 // make PDF projection to time axis with bin size of ~0.5 ns
324 PDF1Dim pdf1d(pdfConstructor, 0.5, timeWindow);
325 pdfConstructor.switchOffDeltaRayPDF(); // to speed-up fine search
326
327 // do further track selection
328 double expSignal = pdf1d.getExpectedSignal();
329 double expDelta = pdf1d.getExpectedDeltaPhotons();
330 double expBG = pdf1d.getExpectedBG();
331 double expPhot = expSignal + expDelta + expBG;
332 double numPhot = pdf1d.getNumOfPhotons();
333 if (expSignal < m_minSignal) continue;
334 if (expSignal < m_minSBRatio * expBG) continue;
335 if (numPhot < m_minDERatio * expPhot) continue;
336 if (numPhot > m_maxDERatio * expPhot) continue;
337
338 topTracks.push_back(trk);
339 pdfConstructors.push_back(pdfConstructor);
340 top1Dpdfs.push_back(pdf1d);
341 numPhotons.push_back(numPhot);
342 assumedMasses.push_back(pdfConstructors.back().getHypothesis().getMass());
343 }
344 m_recBunch->setNumTracks(numTrk, topTracks.size(), m_nodEdxCount);
345 if (topTracks.empty()) return;
346
347 // get time seed
348
349 auto timeSeed = getTimeSeed();
350
351 if (timeSeed.sigma == 0) { // time seed is not given - perform coarse search
352
353 // set time region for coarse search
354
355 double minT0 = -m_timeRangeCoarse / 2;
356 double maxT0 = m_timeRangeCoarse / 2;
357 if (m_autoRange) {
358 minT0 = top1Dpdfs[0].getMinT0();
359 maxT0 = top1Dpdfs[0].getMaxT0();
360 for (const auto& pdf : top1Dpdfs) {
361 minT0 = std::min(minT0, pdf.getMinT0());
362 maxT0 = std::max(maxT0, pdf.getMaxT0());
363 }
364 }
365 double binSize = top1Dpdfs[0].getBinSize();
366 int numBins = (maxT0 - minT0) / binSize;
367 maxT0 = minT0 + binSize * numBins;
368
369 // find coarse T0
370
371 for (const auto& pdf : top1Dpdfs) {
372 finders.push_back(Chi2MinimumFinder1D(numBins, minT0, maxT0));
373 auto& finder = finders.back();
374 const auto& bins = finder.getBinCenters();
375 for (unsigned i = 0; i < bins.size(); i++) {
376 double t0 = bins[i];
377 finder.add(i, -2 * pdf.getLogL(t0));
378 }
379 }
380 auto coarseFinder = finders[0];
381 for (size_t i = 1; i < finders.size(); i++) {
382 coarseFinder.add(finders[i]);
383 }
384
385 const auto& t0Coarse = coarseFinder.getMinimum();
386 if (m_saveHistograms) {
387 m_recBunch->addHistogram(coarseFinder.getHistogram("chi2_coarse_",
388 "coarse T0; t_{0} [ns]; -2 log L"));
389 }
390 if (t0Coarse.position < minT0 or t0Coarse.position > maxT0 or not t0Coarse.valid) {
391 B2DEBUG(20, "Coarse T0 finder: returning invalid or out of range T0");
392 return;
393 }
394 timeSeed.t0 = t0Coarse.position;
395 }
396
397 // find precise T0
398
399 finders.clear();
400
401 double timeMin = TOPRecoManager::getMinTime() + timeSeed.t0;
402 double timeMax = TOPRecoManager::getMaxTime() + timeSeed.t0;
403 double timeRangeFine = std::max(m_timeRangeFine, timeSeed.sigma * 6);
404 double t0min = timeSeed.t0 - timeRangeFine / 2;
405 double t0max = timeSeed.t0 + timeRangeFine / 2;
406
407 for (size_t itrk = 0; itrk < topTracks.size(); itrk++) {
408 finders.push_back(Chi2MinimumFinder1D(m_numBins, t0min, t0max));
409 const auto& reco = pdfConstructors[itrk];
410 numPhotons[itrk] = setFinder(finders.back(), reco, timeMin, timeMax);
411 const auto& trk = topTracks[itrk];
412 double momentum = trk.getMomentumMag();
413 if (not m_useMCTruth and momentum > 0.7 and topTracks.size() <= m_nTrackLimit) {
414 std::vector<Const::ChargedStable> other;
415 if (reco.getHypothesis() == Const::kaon) {
416 other.push_back(Const::pion);
417 if (momentum < 4.0) other.push_back(Const::proton);
418 } else if (reco.getHypothesis() == Const::proton) {
419 other.push_back(Const::pion);
420 if (momentum < 2.0) other.push_back(Const::kaon);
421 } else {
422 if (momentum < 2.0) other.push_back(Const::kaon);
423 if (momentum < 4.0) other.push_back(Const::proton);
424 }
425 for (const auto& chargedStable : other) {
426 PDFConstructor pdfConstructor(trk, chargedStable, PDFConstructor::c_Rough);
427 if (not pdfConstructor.isValid()) continue;
428 pdfConstructor.switchOffDeltaRayPDF(); // to speed-up fine search
429 if (pdfConstructor.getExpectedSignalPhotons() < m_minSignal) continue;
430 Chi2MinimumFinder1D finder(m_numBins, t0min, t0max);
431 int numPhot = setFinder(finder, pdfConstructor, timeMin, timeMax);
432 if (numPhot != numPhotons[itrk])
433 B2ERROR("Different number of photons used for log likelihood of different mass hypotheses");
434 if (finder.getMinChi2() < finders.back().getMinChi2()) {
435 finders.back() = finder;
436 assumedMasses[itrk] = chargedStable.getMass();
437 }
438 }
439 }
440 }
441
442 if (finders.size() == 0) return; // just in case
443 auto finderSum = finders[0];
444 for (size_t i = 1; i < finders.size(); i++) {
445 finderSum.add(finders[i]);
446 }
447
448 if (timeSeed.sigma > 0) {
449 const auto& binCenters = finderSum.getBinCenters();
450 for (unsigned i = 0; i < binCenters.size(); i++) {
451 double t0 = binCenters[i];
452 finderSum.add(i, pow((t0 - timeSeed.t0) / timeSeed.sigma, 2)); // add chi2 according to timeSeed resolution
453 }
454 }
455
456 const auto& T0 = finderSum.getMinimum();
457 if (m_saveHistograms) {
458 m_recBunch->addHistogram(finderSum.getHistogram("chi2_fine_", "precise T0; t_{0} [ns]; -2 log L"));
459 }
460 if (T0.position < t0min or T0.position > t0max or not T0.valid) {
461 B2DEBUG(20, "Fine T0 finder: returning invalid or out of range T0");
462 return;
463 }
464
465 // bunch time and current offset
466
467 int bunchNo = lround(T0.position / m_bunchTimeSep); // round to nearest integer
468 double offset = T0.position - m_bunchTimeSep * bunchNo;
469 if (not m_commonT0->isCalibrated()) { // auto set offset range
470 double deltaOffset = offset - m_runningOffset;
471 if (fabs(deltaOffset + m_bunchTimeSep) < fabs(deltaOffset)) {
472 offset += m_bunchTimeSep;
473 bunchNo--;
474 } else if (fabs(deltaOffset - m_bunchTimeSep) < fabs(deltaOffset)) {
475 offset -= m_bunchTimeSep;
476 bunchNo++;
477 }
478 }
479 double error = T0.error;
480
481 // averaging with first order filter (with adoptable time constant)
482
483 double tau = 10 + m_success / 2; // empirically with toy MC
484 if (tau > m_tau) tau = m_tau;
485 double a = exp(-1.0 / tau);
486 m_runningOffset = a * m_runningOffset + (1 - a) * offset;
487 double err1 = a * m_runningError;
488 double err2 = (1 - a) * error;
489 m_runningError = sqrt(err1 * err1 + err2 * err2);
490
491 // when not running in HLT mode, check if reconstructed bunch is filled
492
493 if (not m_HLTmode) {
494 bool isFilled = isBucketFilled(bunchNo); // stores in addition the bucket number and fill status in m_recBunch
495 if (m_useFillPattern and not isFilled) return;
496 }
497
498 // store the results
499
500 double bunchTime = bunchNo * m_bunchTimeSep;
501 m_recBunch->setReconstructed(bunchNo, bunchTime, offset, error, m_runningOffset, m_runningError, timeSeed.detector);
502 m_recBunch->setMinChi2(T0.chi2);
503 double svdOffset = m_eventT0Offset.isValid() and not m_isMC ? m_eventT0Offset->get(Const::SVD).offset : 0;
504 m_eventT0->addTemporaryEventT0(EventT0::EventT0Component(bunchTime + svdOffset, error, Const::TOP, "bunchFinder"));
505 m_success++;
506
507 // store T0 of single tracks relative to bunchTime
508
509 if (finders.size() == topTracks.size()) {
510 for (size_t itrk = 0; itrk < topTracks.size(); itrk++) {
511 const auto& trk = topTracks[itrk];
512 auto& finder = finders[itrk];
513 const auto& t0trk = finder.getMinimum();
514 auto* timeZero = m_timeZeros.appendNew(trk.getModuleID(),
515 t0trk.position - bunchTime,
516 t0trk.error, numPhotons[itrk]);
517 timeZero->setAssumedMass(assumedMasses[itrk]);
518 if (not t0trk.valid) timeZero->setInvalid();
519 timeZero->setMinChi2(finder.getMinChi2());
520 timeZero->addRelationTo(trk.getExtHit());
521
522 if (m_saveHistograms) {
523 std::string num = std::to_string(itrk);
524 auto chi2 = finder.getHistogram("chi2_" + num,
525 "precise T0 single track; t_{0} [ns]; -2 log L");
526 auto pdf = top1Dpdfs[itrk].getHistogram("pdf1D_" + num,
527 "PDF projected to time axis; time [ns]");
528 TH1F hits(("hits_" + num).c_str(),
529 "time distribution of hits (t0-subtracted); time [ns]",
530 pdf.GetNbinsX(), pdf.GetXaxis()->GetXmin(), pdf.GetXaxis()->GetXmax());
531 for (const auto& hit : trk.getSelectedHits()) {
532 hits.Fill(hit.time - t0trk.position);
533 }
534 timeZero->setHistograms(chi2, pdf, hits);
535 }
536 }
537 }
538
539 // correct time in TOPDigits
540
541 if (m_correctDigits) {
542 for (auto& digit : m_topDigits) {
543 digit.subtractT0(bunchTime);
544 digit.addStatus(TOPDigit::c_EventT0Subtracted);
545 if (m_HLTmode and m_subtractRunningOffset) {
546 digit.subtractT0(m_runningOffset);
547 double err = digit.getTimeError();
548 digit.setTimeError(sqrt(err * err + m_runningError * m_runningError));
549 digit.addStatus(TOPDigit::c_BunchOffsetSubtracted);
550 }
551 }
552 }
553
554 }

◆ event() [5/30]

void event ( void )
overridevirtual

Event processor.

Reimplemented from Module.

Definition at line 101 of file TOPCalPulseGeneratorModule.cc.

102 {
103 const auto& chMapper = TOPGeometryPar::Instance()->getChannelMapper();
104
105 double time = m_delay + gRandom->Uniform(m_windowSize);
106 for (auto moduleID : m_moduleIDs) {
107 for (unsigned asic = 0; asic < 64; asic++) {
108 for (auto asicChannel : m_asicChannels) {
109 unsigned channel = asic * 8 + asicChannel;
110 auto pixelID = chMapper.getPixelID(channel);
111 m_calPulses.appendNew(moduleID, channel, pixelID, time, m_amplitude);
112 }
113 }
114 }
115
116 }

◆ event() [6/30]

void event ( void )
overridevirtual

event method: removes channels from the reconstruction pdf, flags hits from noisy channels as junk

Reimplemented from Module.

Definition at line 69 of file TOPChannelMaskerModule.cc.

70 {
71
72 // have those payloads changed?
73
74 bool pmtInstalled = m_pmtInstalled.hasChanged();
75 bool pmtQEData = m_pmtQEData.hasChanged();
76 bool channelRQE = m_channelRQE.hasChanged();
77 bool thresholdEff = m_thresholdEff.hasChanged();
78
79 // if at least one then pass pixel relative efficiencies to the reconstructon code
80
81 if (pmtInstalled or pmtQEData or channelRQE or thresholdEff) {
82 TOPRecoManager::setChannelEffi();
83 }
84
85 // have asic masks changed?
86
87 bool asicMasksChanged = false;
88 if (m_eventAsicMask.isValid()) {
89 if (m_eventAsicMask->get() != m_savedAsicMask.get()) {
90 m_savedAsicMask.set(m_eventAsicMask->get());
91 asicMasksChanged = true;
92 }
93 }
94
95 // have channel masks or calibration changed?
96
97 bool channelMaskChanged = m_channelMask.hasChanged();
98 bool channelT0Changed = m_channelT0.hasChanged();
99 bool timebaseChanged = m_timebase.hasChanged();
100
101 // if at least one then pass the new masking to the reconstruction code
102
103 if (channelMaskChanged or asicMasksChanged or
104 (m_maskUncalibratedChannelT0 and channelT0Changed) or
105 (m_maskUncalibratedTimebase and timebaseChanged)) {
106
107 TOPRecoManager::setChannelMask(m_channelMask, m_savedAsicMask);
108 if (m_maskUncalibratedChannelT0) {
109 TOPRecoManager::setUncalibratedChannelsOff(m_channelT0);
110 }
111 if (m_maskUncalibratedTimebase) {
112 TOPRecoManager::setUncalibratedChannelsOff(m_timebase);
113 }
114 }
115
116 // now flag actual data Cherenkov hits as coming from masked channels
117
118 for (auto& digit : m_digits) {
119 // if already set switch the state back to c_Good (e.g. for digits read from file)
120 if (digit.getHitQuality() == TOPDigit::c_Masked or
121 digit.getHitQuality() == TOPDigit::c_Uncalibrated) {
122 digit.setHitQuality(TOPDigit::c_Good);
123 }
124 if (digit.getHitQuality() != TOPDigit::c_Good) continue;
125
126 // now do the new masking of c_Good
127 auto slotID = digit.getModuleID();
128 auto channel = digit.getChannel();
129 if (not m_channelMask->isActive(slotID, channel)) {
130 digit.setHitQuality(TOPDigit::c_Masked);
131 continue;
132 }
133 if (not m_savedAsicMask.isActive(slotID, channel)) {
134 digit.setHitQuality(TOPDigit::c_Masked);
135 const unsigned maxCount = 10; // at HLT this means (10 * number-of-processes) messages before being suppressed
136 if (m_errorCount < maxCount) {
137 B2ERROR("Unexpected hit found in a channel that is masked-out by firmware"
138 << LogVar("slotID", slotID) << LogVar("channel", channel));
139 } else if (m_errorCount == maxCount) {
140 B2ERROR("Unexpected hit found in a channel that is masked-out by firmware"
141 << LogVar("slotID", slotID) << LogVar("channel", channel)
142 << LogVar("... message will be suppressed now, errorCount", m_errorCount));
143 }
144 m_errorCount++;
145 continue;
146 }
147 if (m_maskUncalibratedChannelT0 and not m_channelT0->isCalibrated(slotID, channel)) {
148 digit.setHitQuality(TOPDigit::c_Uncalibrated);
149 continue;
150 }
151 if (m_maskUncalibratedTimebase) {
152 const auto& fe_mapper = TOPGeometryPar::Instance()->getFrontEndMapper();
153 const auto* fe = fe_mapper.getMap(slotID, channel / 128);
154 if (not fe) {
155 B2ERROR("No front-end map found" << LogVar("slotID", slotID) << LogVar("channel", channel));
156 digit.setHitQuality(TOPDigit::c_Uncalibrated);
157 continue;
158 }
159 auto scrodID = fe->getScrodID();
160 const auto* sampleTimes = m_timebase->getSampleTimes(scrodID, channel);
161 if (not sampleTimes->isCalibrated()) {
162 digit.setHitQuality(TOPDigit::c_Uncalibrated);
163 }
164 }
165 }
166
167 }

◆ event() [7/30]

void event ( void )
overridevirtual

Event processor.

Reimplemented from Module.

Definition at line 176 of file TOPChannelT0CalibratorModule.cc.

177 {
178 /* check bunch reconstruction status and run alignment:
179 - if object exists and bunch is found (collision data w/ bunch finder in the path)
180 - if object doesn't exist (cosmic data and other cases w/o bunch finder)
181 */
182
183 if (m_recBunch.isValid()) {
184 if (not m_recBunch->isReconstructed()) return;
185 }
186
187 TOPRecoManager::setDefaultTimeWindow();
188 double timeMin = TOPRecoManager::getMinTime();
189 double timeMax = TOPRecoManager::getMaxTime();
190 const auto& chMapper = TOPGeometryPar::Instance()->getChannelMapper();
191
192 // loop over reconstructed tracks, make a selection and accumulate log likelihoods
193
194 for (const auto& track : m_tracks) {
195
196 // track selection
197 TOPTrack trk(track);
198 if (not trk.isValid()) continue;
199
200 if (not m_selector.isSelected(trk)) continue;
201
202 // construct PDF
203 PDFConstructor pdfConstructor(trk, m_selector.getChargedStable(), m_PDFOption);
204 if (not pdfConstructor.isValid()) continue;
205
206 // minimization procedure: accumulate
207 const unsigned module = trk.getModuleID() - 1;
208 if (module >= c_numModules) continue;
209 int sub = gRandom->Integer(2); // generate sub-sample number
210 auto& finders = m_finders[sub][module];
211 const auto& binCenters = finders[0].getBinCenters();
212 for (unsigned ibin = 0; ibin < binCenters.size(); ibin++) {
213 double t0 = binCenters[ibin];
214 const auto& pixelLogLs = pdfConstructor.getPixelLogLs(t0, m_sigmaSmear);
215 for (unsigned channel = 0; channel < c_numChannels; channel++) {
216 int pix = chMapper.getPixelID(channel) - 1;
217 finders[channel].add(ibin, -2 * pixelLogLs[pix].logL);
218 }
219 }
220
221 // fill histograms of hits
222 m_numPhotons = 0;
223 for (const auto& digit : m_digits) {
224 if (digit.getHitQuality() != TOPDigit::c_Good) continue;
225 if (digit.getModuleID() != trk.getModuleID()) continue;
226 if (digit.getTime() < timeMin) continue;
227 if (digit.getTime() > timeMax) continue;
228 m_numPhotons++;
229 auto& h1 = m_hits1D[module];
230 h1.Fill(digit.getChannel());
231 auto& h2 = m_hits2D[module];
232 h2.Fill(digit.getChannel(), digit.getTime());
233 }
234
235 // fill output tree
236 m_moduleID = trk.getModuleID();
237 const auto& localPosition = m_selector.getLocalPosition();
238 m_x = localPosition.X();
239 m_y = localPosition.Y();
240 m_z = localPosition.Z();
241 const auto& localMomentum = m_selector.getLocalMomentum();
242 m_p = localMomentum.R();
243 m_theta = localMomentum.Theta();
244 m_phi = localMomentum.Phi();
245 const auto& pocaPosition = m_selector.getPOCAPosition();
246 m_pocaR = pocaPosition.Rho();
247 m_pocaZ = pocaPosition.Z();
248 m_pocaX = pocaPosition.X();
249 m_pocaY = pocaPosition.Y();
250 m_cmsE = m_selector.getCMSEnergy();
251 m_charge = trk.getCharge();
252 m_PDG = trk.getPDGCode();
253 m_tree->Fill();
254 }
255
256 }

◆ event() [8/30]

void event ( void )
overridevirtual

Event processor.

Reimplemented from Module.

Definition at line 57 of file TOPChannelT0MCModule.cc.

58 {
59
60 for (auto& digit : m_digits) {
61 unsigned channel = digit.getChannel();
62 if (channel < c_NumChannels) {
63 auto histo = m_histo[channel];
64 if (!histo) {
65 stringstream ss;
66 ss << "chan" << channel ;
67 string name;
68 ss >> name;
69 string title = "Times " + name;
70 histo = new TH1F(name.c_str(), title.c_str(), (int)m_fitRange[0], m_fitRange[1], m_fitRange[2]);
71 m_histo[channel] = histo;
72 }
73 if (digit.getTime() < m_fitRange[1] || digit.getTime() > m_fitRange[2]) continue;
74 histo->Fill(digit.getTime());
75 }
76 }
77 }

◆ event() [9/30]

void event ( void )
overridevirtual

Event processor.

Reimplemented from Module.

Definition at line 162 of file TOPCommonT0CalibratorModule.cc.

163 {
164 /* check bunch reconstruction status and run alignment:
165 - if object exists and bunch is found (collision data w/ bunch finder in the path)
166 - if object doesn't exist (cosmic data and other cases w/o bunch finder)
167 */
168
169 if (m_recBunch.isValid()) {
170 if (not m_recBunch->isReconstructed()) return;
171 }
172
173 TOPRecoManager::setDefaultTimeWindow();
174 double timeMin = TOPRecoManager::getMinTime();
175 double timeMax = TOPRecoManager::getMaxTime();
176
177 // running offset must not be subtracted in TOPDigits: issue an error if it is
178
179 if (isRunningOffsetSubtracted()) {
180 B2ERROR("Running offset subtracted in TOPDigits: common T0 will not be correct");
181 }
182
183 // loop over reconstructed tracks, make a selection and accumulate log likelihoods
184
185 for (const auto& track : m_tracks) {
186
187 // track selection
188 TOPTrack trk(track);
189 if (not trk.isValid()) continue;
190
191 if (not m_selector.isSelected(trk)) continue;
192
193 // construct PDF
194 PDFConstructor pdfConstructor(trk, m_selector.getChargedStable(), m_PDFOption);
195 if (not pdfConstructor.isValid()) continue;
196
197 // minimization procedure: accumulate
198 int sub = gRandom->Integer(c_numSets); // generate sub-sample number
199 auto& finder = m_finders[sub];
200 const auto& binCenters = finder.getBinCenters();
201 for (unsigned ibin = 0; ibin < binCenters.size(); ibin++) {
202 double t0 = binCenters[ibin];
203 finder.add(ibin, -2 * pdfConstructor.getLogL(t0, m_sigmaSmear).logL);
204 }
205
206 // fill histograms of hits
207 m_numPhotons = 0;
208 for (const auto& digit : m_digits) {
209 if (digit.getHitQuality() != TOPDigit::c_Good) continue;
210 if (digit.getModuleID() != trk.getModuleID()) continue;
211 if (digit.getTime() < timeMin) continue;
212 if (digit.getTime() > timeMax) continue;
213 m_numPhotons++;
214 m_hits1D.Fill(digit.getModuleID());
215 int bs = digit.getBoardstackNumber();
216 m_hits2D.Fill((digit.getModuleID() * 4 + bs - 1.5) / 4.0, digit.getTime());
217 }
218
219 // fill output tree
220 m_moduleID = trk.getModuleID();
221 const auto& localPosition = m_selector.getLocalPosition();
222 m_x = localPosition.X();
223 m_y = localPosition.Y();
224 m_z = localPosition.Z();
225 const auto& localMomentum = m_selector.getLocalMomentum();
226 m_p = localMomentum.R();
227 m_theta = localMomentum.Theta();
228 m_phi = localMomentum.Phi();
229 const auto& pocaPosition = m_selector.getPOCAPosition();
230 m_pocaR = pocaPosition.Rho();
231 m_pocaZ = pocaPosition.Z();
232 m_pocaX = pocaPosition.X();
233 m_pocaY = pocaPosition.Y();
234 m_cmsE = m_selector.getCMSEnergy();
235 m_charge = trk.getCharge();
236 m_PDG = trk.getPDGCode();
237 m_tree->Fill();
238 }
239
240 }

◆ event() [10/30]

void event ( void )
overridevirtual

Event processor.

Reimplemented from Module.

Definition at line 103 of file TOPCosmicT0FinderModule.cc.

104 {
105 TOPRecoManager::setDefaultTimeWindow();
106
107 // select track: if several, choose highest momentum track
108
109 StoreArray<Track> tracks;
110 const ExtHit* selectedExtHit = 0;
111 double p0 = 0;
112 for (const auto& track : tracks) {
113 const auto extHits = track.getRelationsWith<ExtHit>();
114 const ExtHit* extHit0 = 0;
115 for (const auto& extHit : extHits) {
116 if (abs(extHit.getPdgCode()) != Const::muon.getPDGCode()) continue;
117 if (extHit.getDetectorID() != Const::EDetector::TOP) continue;
118 if (extHit.getCopyID() <= 0) continue;
119 double dot = extHit.getPosition().Dot(extHit.getMomentum());
120 if (m_useIncomingTrack) {
121 if (dot > 0) continue;
122 if (not extHit0) extHit0 = &extHit;
123 if (extHit.getTOF() < extHit0->getTOF()) extHit0 = &extHit;
124 } else {
125 if (dot < 0) continue;
126 if (not extHit0) extHit0 = &extHit;
127 if (extHit.getTOF() > extHit0->getTOF()) extHit0 = &extHit;
128 }
129 }
130 if (not extHit0) continue;
131 double p = extHit0->getMomentum().R();
132 if (p > p0) {
133 p0 = p;
134 selectedExtHit = extHit0;
135 }
136 }
137 if (not selectedExtHit) return;
138
139 TOPTrack topTrack(selectedExtHit);
140 if (not topTrack.isValid()) return;
141
142 // require minimal number of photon hits
143
144 if (topTrack.getSelectedHits().size() < m_minHits) return;
145
146 // construct PDF for muon
147
148 PDFConstructor pdfConstructor(topTrack, Const::muon, PDFConstructor::c_Rough);
149 if (not pdfConstructor.isValid()) return;
150
151 // require minimal expected signal
152
153 if (pdfConstructor.getExpectedSignalPhotons() < m_minSignal) return;
154
155 // event is accepted for t0 determination
156
157 m_acceptedCount++;
158
159 // full time window in which data are taken (smaller time window is used in reconstruction)
160
161 const auto& tdc = TOPGeometryPar::Instance()->getGeometry()->getNominalTDC();
162 double timeWindow = m_feSetting->getReadoutWindows() * tdc.getSyncTimeBase() / static_cast<double>(TOPNominalTDC::c_syncWindows);
163
164 // find rough t0
165
166 PDF1Dim pdf1d(pdfConstructor, 1.0, timeWindow); // ~1 ns bin size
167 pdfConstructor.switchOffDeltaRayPDF(); // to speed-up fine search
168
169 Chi2MinimumFinder1D roughFinder(pdf1d.getNumBinsT0(), pdf1d.getMinT0(), pdf1d.getMaxT0());
170 const auto& bins = roughFinder.getBinCenters();
171 for (unsigned i = 0; i < bins.size(); i++) {
172 double t0 = bins[i];
173 roughFinder.add(i, -2 * pdf1d.getLogL(t0));
174 }
175 const auto& t0Rough = roughFinder.getMinimum();
176
177 // find precise t0
178
179 double timeMin = TOPRecoManager::getMinTime() + t0Rough.position;
180 double timeMax = TOPRecoManager::getMaxTime() + t0Rough.position;
181 double t0min = t0Rough.position - m_timeRange / 2;
182 double t0max = t0Rough.position + m_timeRange / 2;
183 Chi2MinimumFinder1D finder(m_numBins, t0min, t0max);
184 const auto& binCenters = finder.getBinCenters();
185 int numPhotons = 0;
186 for (unsigned i = 0; i < binCenters.size(); i++) {
187 double t0 = binCenters[i];
188 auto LL = pdfConstructor.getLogL(t0, timeMin, timeMax, m_sigma);
189 finder.add(i, -2 * LL.logL);
190 if (i == 0) numPhotons = LL.numPhotons;
191 }
192 const auto& t0 = finder.getMinimum();
193 if (t0.position < t0min or t0.position > t0max or not t0.valid) return; // out of range
194
195 // event t0 is successfully determined
196
197 m_successCount++;
198
199 // store results
200
201 StoreArray<TOPTimeZero> timeZeros;
202 auto* timeZero = timeZeros.appendNew(topTrack.getModuleID(), t0.position, t0.error, numPhotons);
203 timeZero->addRelationTo(topTrack.getTrack());
204 timeZero->addRelationTo(topTrack.getExtHit());
205 if (topTrack.getBarHit()) timeZero->addRelationTo(topTrack.getBarHit());
206
207 // save histograms
208
209 if (m_saveHistograms) {
210 std::string name;
211
212 name = "chi2_" + to_string(m_num);
213 std::string title = "muon -2 logL vs. t0; t_{0} [ns]; -2 log L_{#mu}";
214 auto chi2 = finder.getHistogram(name, title);
215
216 name = "pdf_" + to_string(m_num);
217 auto pdf = pdf1d.getHistogram(name, "PDF projected to time axis");
218 pdf.SetName(name.c_str());
219 pdf.SetXTitle("time [ns]");
220 pdf.SetLineColor(2);
221 pdf.SetOption("hist");
222
223 name = "hits_" + to_string(m_num);
224 TH1F hits(name.c_str(), "time distribution of photons (t0-subtracted)",
225 pdf.GetNbinsX(), pdf.GetXaxis()->GetXmin(), pdf.GetXaxis()->GetXmax());
226 hits.SetXTitle("time [ns]");
227 for (const auto& hit : topTrack.getSelectedHits()) {
228 hits.Fill(hit.time - t0.position);
229 }
230 timeZero->setHistograms(chi2, pdf, hits);
231 m_num++;
232 }
233
234 // subtract T0 in digits
235
236 if (m_applyT0) {
237 StoreArray<TOPDigit> topDigits;
238 for (auto& digit : topDigits) {
239 digit.subtractT0(t0.position);
240 double err = digit.getTimeError();
241 digit.setTimeError(sqrt(err * err + t0.error * t0.error));
242 digit.addStatus(TOPDigit::c_EventT0Subtracted);
243 }
244 }
245
246 }
T dot(GeneralVector< T > a, GeneralVector< T > b)
dot product of two general vectors

◆ event() [11/30]

void event ( void )
overridevirtual

Event processor.

Reimplemented from Module.

Definition at line 240 of file TOPDigitizerModule.cc.

241 {
242
243 // get or generate revo9 count
244 unsigned revo9cnt = 0;
245 if (m_simClockState.isValid()) {
246 revo9cnt = m_simClockState->getRevo9Count();
247 } else {
248 revo9cnt = gRandom->Integer(11520);
249 }
250
251 // from revo9 count determine trigger time offset and the number of offset windows
252 double SSTfrac = (revo9cnt % 6) / 6.0;
253 double offset = m_feSetting->getOffset() / 24.0;
254 double trgTimeOffset = (SSTfrac + offset) * m_syncTimeBase; // in [ns]
255 int offsetWindows = m_feSetting->getWindowShift(revo9cnt);
256 TimeDigitizer::setOffsetWindows(offsetWindows);
257
258 // from revo9 and write depths determine reference window, phase and storage depth
259 int SSTcnt = revo9cnt / 6;
260 int refWindow = SSTcnt * 2; // same as lastWriteAddr
261 const auto& writeDepths = m_feSetting->getWriteDepths();
262 if (writeDepths.empty()) {
263 B2ERROR("TOPDigitzer: vector of write depths is empty. No digitization possible");
264 return;
265 }
266 int lastDepth = writeDepths.back();
267 unsigned phase = 0;
268 for (auto depth : writeDepths) {
269 SSTcnt -= depth;
270 if (SSTcnt < 0) break;
271 phase++;
272 refWindow = SSTcnt * 2;
273 lastDepth = depth;
274 }
275 unsigned storageDepth = lastDepth * 2;
276 TimeDigitizer::setStorageDepth(storageDepth);
277
278 // from reference window and lookback determine first of the readout windows
279 int lookBackWindows = m_feSetting->getLookbackWindows();
280 if (m_lookBackWindows > 0) lookBackWindows = m_lookBackWindows;
281 lookBackWindows -= m_feSetting->getExtraWindows();
282 int window = refWindow - lookBackWindows;
283 if (window < 0) window += storageDepth;
284 TimeDigitizer::setFirstWindow(window);
285
286 // geometry and nominal data
287 const auto* geo = TOPGeometryPar::Instance()->getGeometry();
288
289 // time range for digitization
290 double timeMin = geo->getSignalShape().getTMin() + offsetWindows * m_syncTimeBase / 2;
291 double timeMax = geo->getSignalShape().getTMax() +
292 (m_feSetting->getReadoutWindows() + offsetWindows) * m_syncTimeBase / 2;
293
294 // simulate start time jitter
295 double startTimeJitter = gRandom->Gaus(0, m_timeZeroJitter);
296
297 // get electronic efficiency
298 double electronicEfficiency = geo->getNominalTDC().getEfficiency();
299
300 // define pixels with time digitizers
301 std::map<unsigned, TimeDigitizer> pixels;
302 typedef std::map<unsigned, TimeDigitizer>::iterator Iterator;
303
304 // add simulated hits to time digitizers
305
306 for (const auto& simHit : m_simHits) {
307 if (not m_useWaveforms) {
308 // simulate electronic efficiency
309 if (gRandom->Rndm() > electronicEfficiency) continue;
310 }
311 // do spatial digitization
312 double x = simHit.getX();
313 double y = simHit.getY();
314 int pmtID = simHit.getPmtID();
315 int moduleID = simHit.getModuleID();
316 if (not geo->isModuleIDValid(moduleID)) continue;
317 int pixelID = geo->getModule(moduleID).getPMTArray().getPixelID(x, y, pmtID);
318 if (pixelID == 0) continue;
319
320 // add start time jitter and generated TTS to photon time
321 double time = simHit.getTime() + startTimeJitter;
322 if (m_simulateTTS) {
323 const auto& tts = TOPGeometryPar::Instance()->getTTS(moduleID, pmtID);
324 time += tts.generateTTS();
325 }
326
327 // get time offset for a given pixel
328 auto timeOffset = getTimeOffset(trgTimeOffset, moduleID, pixelID, true);
329
330 // time range cut (to speed up digitization)
331 if (time + timeOffset.value < timeMin + timeOffset.timeShift) continue;
332 if (time + timeOffset.value > timeMax + timeOffset.timeShift) continue;
333
334 // generate pulse height
335 double pulseHeight = generatePulseHeight(moduleID, pixelID);
336 auto hitType = TimeDigitizer::c_Hit;
337
338 // add time and pulse height to digitizer of a given pixel
339 TimeDigitizer digitizer(moduleID, pixelID, timeOffset.value, timeOffset.error,
340 timeOffset.windowShift, m_rmsNoise, m_sampleTimes);
341 if (not digitizer.isValid()) continue;
342 unsigned id = digitizer.getUniqueID();
343 Iterator it = pixels.insert(pair<unsigned, TimeDigitizer>(id, digitizer)).first;
344 it->second.addTimeOfHit(time, pulseHeight, hitType, &simHit);
345 }
346
347 // add calibration pulses
348
349 for (const auto& simCalPulses : m_simCalPulses) {
350 auto moduleID = simCalPulses.getModuleID();
351 auto pixelID = simCalPulses.getPixelID();
352 auto pulseHeight = simCalPulses.getAmplitude();
353 auto time = simCalPulses.getTime();
354 auto hitType = TimeDigitizer::c_CalPulse;
355
356 // get time offset for a given pixel
357 auto timeOffset = getTimeOffset(trgTimeOffset, moduleID, pixelID);
358
359 // time range cut (to speed up digitization)
360 if (time + timeOffset.value < timeMin + timeOffset.timeShift) continue;
361 if (time + timeOffset.value > timeMax + timeOffset.timeShift) continue;
362
363 // add time and pulse height to digitizer of a given pixel
364 TimeDigitizer digitizer(moduleID, pixelID, timeOffset.value, timeOffset.error,
365 timeOffset.windowShift, m_rmsNoise, m_sampleTimes);
366 if (not digitizer.isValid()) continue;
367 unsigned id = digitizer.getUniqueID();
368 Iterator it = pixels.insert(pair<unsigned, TimeDigitizer>(id, digitizer)).first;
369 it->second.addTimeOfHit(time, pulseHeight, hitType);
370 }
371
372 // add randomly distributed dark noise (maybe not needed anymore?)
373
374 if (m_darkNoise > 0) {
375 int numModules = geo->getNumModules();
376 for (int moduleID = 1; moduleID <= numModules; moduleID++) {
377 int numPixels = geo->getModule(moduleID).getPMTArray().getNumPixels();
378 int numHits = gRandom->Poisson(m_darkNoise);
379 for (int i = 0; i < numHits; i++) {
380 int pixelID = int(gRandom->Rndm() * numPixels) + 1;
381 double time = (timeMax - timeMin) * gRandom->Rndm() + timeMin;
382 double pulseHeight = generatePulseHeight(moduleID, pixelID);
383 auto hitType = TimeDigitizer::c_Hit;
384 auto timeOffset = getTimeOffset(trgTimeOffset, moduleID, pixelID);
385 time += timeOffset.timeShift;
386 time -= timeOffset.value;
387 TimeDigitizer digitizer(moduleID, pixelID, timeOffset.value, timeOffset.error,
388 timeOffset.windowShift, m_rmsNoise, m_sampleTimes);
389 if (not digitizer.isValid()) continue;
390 unsigned id = digitizer.getUniqueID();
391 Iterator it = pixels.insert(pair<unsigned, TimeDigitizer>(id, digitizer)).first;
392 it->second.addTimeOfHit(time, pulseHeight, hitType);
393 }
394 }
395 }
396
397 // if making waveforms for all channels, add missing digitizers.
398
399 if (m_allChannels) {
400 int numModules = geo->getNumModules();
401 for (int moduleID = 1; moduleID <= numModules; moduleID++) {
402 int numPixels = geo->getModule(moduleID).getPMTArray().getNumPixels();
403 for (int pixelID = 1; pixelID <= numPixels; pixelID++) {
404 auto timeOffset = getTimeOffset(trgTimeOffset, moduleID, pixelID);
405 TimeDigitizer digitizer(moduleID, pixelID, timeOffset.value, timeOffset.error,
406 timeOffset.windowShift, m_rmsNoise, m_sampleTimes);
407 if (not digitizer.isValid()) continue;
408 unsigned id = digitizer.getUniqueID();
409 pixels.insert(pair<unsigned, TimeDigitizer>(id, digitizer));
410 }
411 }
412 }
413
414 // replace equidistant time base with calibrated one if available
415
416 if (m_useDatabase or m_useSampleTimeCalibration) {
417 for (auto& pixel : pixels) {
418 auto& digitizer = pixel.second;
419 const auto* sampleTimes = m_timebases->getSampleTimes(digitizer.getScrodID(),
420 digitizer.getChannel());
421 if (not sampleTimes) continue;
422 if (sampleTimes->isCalibrated()) digitizer.setSampleTimes(sampleTimes);
423 }
424 }
425
426 // replace default noise level with channel dependent one if available,
427
428 if (m_useDatabase) {
429 for (auto& pixel : pixels) {
430 auto& digitizer = pixel.second;
431 auto moduleID = digitizer.getModuleID();
432 auto channel = digitizer.getChannel();
433 auto rmsNoise = m_noises->getNoise(moduleID, channel);
434 if (rmsNoise > 0) {
435 digitizer.setNoise(rmsNoise);
436 }
437 }
438 }
439
440 // digitize in time
441
442 for (const auto& pixel : pixels) {
443 const auto& digitizer = pixel.second;
444 int threshold = m_threshold;
445 if (m_useDatabase) { // use channel dependent ones
446 threshold = m_thresholds->getThr(digitizer.getModuleID(), digitizer.getChannel());
447 if (threshold <= 0) threshold = m_threshold; // not available, use the default
448 }
449 if (m_useWaveforms) {
450 digitizer.digitize(m_waveforms, m_rawDigits, m_digits,
451 threshold, m_hysteresis, m_thresholdCount);
452 } else {
453 digitizer.digitize(m_rawDigits, m_digits,
454 threshold, m_thresholdCount, m_electronicJitter);
455 }
456 }
457
458 // set additional info
459
460 for (auto& rawDigit : m_rawDigits) {
461 rawDigit.setRevo9Counter(revo9cnt);
462 rawDigit.setPhase(phase);
463 rawDigit.setLastWriteAddr(refWindow);
464 rawDigit.setLookBackWindows(lookBackWindows);
465 rawDigit.setOfflineFlag();
466 }
467
468 for (auto& waveform : m_waveforms) {
469 waveform.setRevo9Counter(revo9cnt);
470 waveform.setOffsetWindows(offsetWindows);
471 }
472
473 // set calibration flags
474
475 if (m_useDatabase) {
476 for (auto& digit : m_digits) {
477 if (m_channelT0->isCalibrated(digit.getModuleID(), digit.getChannel())) {
478 digit.addStatus(TOPDigit::c_ChannelT0Calibrated);
479 }
480 if (m_moduleT0->isCalibrated(digit.getModuleID())) {
481 digit.addStatus(TOPDigit::c_ModuleT0Calibrated);
482 }
483 if (m_commonT0->isCalibrated()) {
484 digit.addStatus(TOPDigit::c_CommonT0Calibrated);
485 }
486 }
487 }
488
489 // cut on product of pulse width and height, as for data in TOPRawDigitConverter
490
491 for (auto& digit : m_digits) {
492 if (digit.getPulseWidth() * digit.getPulseHeight() < m_minWidthXheight)
493 digit.setHitQuality(TOPDigit::c_Junk);
494 }
495
496 }
map< unsigned, size_t >::const_iterator Iterator
Iterator for m_map.

◆ event() [12/30]

void event ( void )
overridevirtual

Event processor.

Reimplemented from Module.

Definition at line 157 of file TOPDoublePulseGeneratorModule.cc.

158 {
159
160 StoreArray<TOPDigit> digits;
161
162 const auto& chMapper = TOPGeometryPar::Instance()->getChannelMapper();
163 const auto& feMapper = TOPGeometryPar::Instance()->getFrontEndMapper();
164
165 double timeError = m_timeResolution / sqrt(2.0); // for single pulse
166
167 for (auto moduleID : m_moduleIDs) {
168 for (unsigned asic = 0; asic < 64; asic++) {
169 for (auto asicChannel : m_asicChannels) {
170 unsigned channel = asic * 8 + asicChannel;
171 auto pixelID = chMapper.getPixelID(channel);
172
173 // sample times: from steering or database
174 const TOPSampleTimes* sampleTimes = &m_sampleTimes;
175 if (m_useDatabase) {
176 unsigned scrodID = 0;
177 int bs = asic / 16;
178 const auto* feMap = feMapper.getMap(moduleID, bs);
179 if (feMap) scrodID = feMap->getScrodID();
180 sampleTimes = m_timebase->getSampleTimes(scrodID, channel % 128);
181 if (!sampleTimes->isCalibrated()) {
182 B2WARNING("No sample time calibration available for SCROD " << scrodID
183 << " channel " << channel % 128 << " - equidistant will be used");
184 }
185 }
186
187 // first calpulse
188 double time = gRandom->Rndm() * sampleTimes->getTimeRange();
189 unsigned window = gRandom->Rndm() * m_storageWindows;
190 double sample = sampleTimes->getSample(window, time);
191 auto* digit = digits.appendNew(moduleID, pixelID, sample);
192 digit->setFirstWindow(window);
193 digit->setTime(time);
194 digit->setTimeError(timeError);
195 digit->setChannel(channel);
196 digit->setHitQuality(TOPDigit::c_CalPulse);
197
198 // second calpulse
199 time += gRandom->Gaus(m_timeDifference, m_timeResolution);
200 sample = sampleTimes->getSample(window, time);
201 digit = digits.appendNew(moduleID, pixelID, sample);
202 digit->setFirstWindow(window);
203 digit->setTime(time);
204 digit->setTimeError(timeError);
205 digit->setChannel(channel);
206 digit->setHitQuality(TOPDigit::c_CalPulse);
207 }
208 }
209 }
210
211 }

◆ event() [13/30]

void event ( void )
overridevirtual

Event processor.

Reimplemented from HistoModule.

Definition at line 375 of file TOPDQMModule.cc.

376 {
377
378 // check if event time is reconstructed; distinguish collision data and cosmics
379
380 bool recBunchValid = false;
381 bool cosmics = false;
382 if (m_recBunch.isValid()) { // collision data
383 recBunchValid = m_recBunch->isReconstructed(); // event time is reconstructed
384 } else if (m_timeZeros.getEntries() == 1) { // cosmics w/ reconstructed event time
385 cosmics = true;
386 m_eventT0->Fill(m_timeZeros[0]->getTime());
387 }
388
389 // fill bunch offset
390
391 if (recBunchValid) {
392 double t0 = m_commonT0->isRoughlyCalibrated() ? m_commonT0->getT0() : 0;
393 double offset = m_recBunch->getCurrentOffset() - t0;
394 offset -= m_bunchTimeSep * lround(offset / m_bunchTimeSep); // wrap around
395 m_bunchOffset->Fill(offset);
396 m_eventT0->Fill(m_recBunch->getTime());
397 }
398
399 // fill event desynchronization
400
401 if (m_digits.getEntries() > 0) {
402 for (const auto& digit : m_digits) {
403 int x = digit.getFirstWindow() != m_digits[0]->getFirstWindow() ? 1 : 0 ;
404 m_BoolEvtMonitor->Fill(x);
405 }
406 }
407
408 // count tracks in the modules and store the momenta
409
410 std::vector<int> numTracks(m_numModules, 0);
411 std::vector<double> trackMomenta(m_numModules, 0);
412 for (const auto& track : m_tracks) {
413 const auto* fitResult = track.getTrackFitResultWithClosestMass(Const::pion);
414 if (not fitResult) continue;
415 int slot = getModuleID(track);
416 if (slot == 0) continue;
417 numTracks[slot - 1]++;
418 trackMomenta[slot - 1] = std::max(trackMomenta[slot - 1], fitResult->getMomentum().R());
419 }
420
421 // count events w/ and w/o track in the slot
422
423 if (recBunchValid or cosmics) {
424 for (size_t i = 0; i < numTracks.size(); i++) {
425 bool hit = numTracks[i] > 0;
426 m_trackHits->Fill(i + 1, hit);
427 }
428 }
429
430 // select modules for counting hits in signal and background time windows
431
432 std::vector<bool> selectedSlots(m_numModules, false);
433 for (size_t i = 0; i < selectedSlots.size(); i++) {
434 selectedSlots[i] = (recBunchValid or cosmics) and numTracks[i] == 1 and trackMomenta[i] > m_momentumCut;
435 }
436
437 // prepare counters
438
439 int nHits_good = 0;
440 int nHits_bad = 0;
441 std::vector<int> numSignalHits(m_numModules, 0);
442 std::vector<int> numBackgroundHits(m_numModules, 0);
443
444 // loop over digits, fill histograms and increment counters
445
446 for (const auto& digit : m_digits) {
447 int slot = digit.getModuleID();
448 if (slot < 1 or slot > m_numModules) {
449 B2ERROR("Invalid slot ID found in TOPDigits: ID = " << slot);
450 continue;
451 }
452 int asic_no = digit.getChannel() / 8;
453 int asic_ch = digit.getChannel() % 8;
454
455 m_window_vs_slot->Fill(digit.getModuleID(), digit.getRawTime() / 64 + 220);
456 m_window_vs_asic[slot - 1]->Fill(asic_no, digit.getRawTime() / 64 + 220);
457
458 if (digit.getHitQuality() != TOPDigit::c_Junk) { // good hits
459 m_goodHitsXY[slot - 1]->Fill(digit.getPixelCol(), digit.getPixelRow());
460 m_goodHitsAsics[slot - 1]->Fill(asic_no, asic_ch);
461 m_goodTDC[slot - 1]->Fill(digit.getRawTime());
462 m_goodTDCAll->Fill(digit.getRawTime());
463 m_goodChannelHits[slot - 1]->Fill(digit.getChannel());
464 m_pulseHeights[slot - 1]->Fill(digit.getPMTNumber(), digit.getPulseHeight());
465 nHits_good++;
466 if (digit.hasStatus(TOPDigit::c_EventT0Subtracted)) {
467 double time = digit.getTime();
468 if (cosmics) time += 10; // move for 10 ns in order to get the complete signal at positive times
469 if (numTracks[slot - 1] > 0) {
470 m_goodTiming[slot - 1]->Fill(time);
471 m_time->Fill(time);
472 } else {
473 m_goodTimingBG[slot - 1]->Fill(time);
474 m_timeBG->Fill(time);
475 }
476 if (selectedSlots[slot - 1] and abs(time) < 50) {
477 if (time > 0) numSignalHits[slot - 1]++;
478 else numBackgroundHits[slot - 1]++;
479 }
480 }
481 } else { // bad hits: FE not valid, pedestal jump, too short or too wide pulses
482 m_badHitsXY[slot - 1]->Fill(digit.getPixelCol(), digit.getPixelRow());
483 m_badHitsAsics[slot - 1]->Fill(asic_no, asic_ch);
484 m_badTDC[slot - 1]->Fill(digit.getRawTime());
485 m_badTDCAll->Fill(digit.getRawTime());
486 m_badChannelHits[slot - 1]->Fill(digit.getChannel());
487 nHits_bad++;
488 }
489 }
490
491 // histogram counters
492
493 m_goodHitsPerEventAll->Fill(nHits_good);
494 m_badHitsPerEventAll->Fill(nHits_bad);
495 for (int slot = 1; slot <= m_numModules; slot++) {
496 if (selectedSlots[slot - 1]) {
497 m_signalHits->Fill(slot, numSignalHits[slot - 1]);
498 m_backgroundHits->Fill(slot, numBackgroundHits[slot - 1]);
499 }
500 }
501
502 // fill injection histograms
503
504 for (auto& it : m_rawFTSWs) {
505 B2DEBUG(29, "TTD FTSW : " << hex << it.GetTTUtime(0) << " " << it.GetTTCtime(0) << " EvtNr " << it.GetEveNo(0) << " Type " <<
506 (it.GetTTCtimeTRGType(0) & 0xF) << " TimeSincePrev " << it.GetTimeSincePrevTrigger(0) << " TimeSinceInj " <<
507 it.GetTimeSinceLastInjection(0) << " IsHER " << it.GetIsHER(0) << " Bunch " << it.GetBunchNumber(0));
508 auto time_clk = it.GetTimeSinceLastInjection(0); // expressed in system clock
509 if (time_clk != 0x7FFFFFFF) {
510 unsigned int nentries = m_digits.getEntries();
511 double time_us = time_clk / 127.0; // 127MHz clock ticks to us, inexact rounding
512 double time_ms = time_us / 1000;
513 double time_1280 = time_clk % 1280; // within beam cycle, expressed in system clock
514 if (it.GetIsHER(0)) {
515 m_TOPOccAfterInjHER->Fill(time_us, nentries);
516 m_TOPEOccAfterInjHER->Fill(time_us);
517 m_nhitInjHER->Fill(time_ms, time_1280, nHits_good);
518 m_eventInjHER->Fill(time_ms, time_1280);
519 if (nHits_good > 1000) {
520 m_nhitInjHERcut->Fill(time_ms, time_1280, nHits_good);
521 m_eventInjHERcut->Fill(time_ms, time_1280);
522 }
523 } else {
524 m_TOPOccAfterInjLER->Fill(time_us, nentries);
525 m_TOPEOccAfterInjLER->Fill(time_us);
526 m_nhitInjLER->Fill(time_ms, time_1280, nHits_good);
527 m_eventInjLER->Fill(time_ms, time_1280);
528 if (nHits_good > 1000) {
529 m_nhitInjLERcut->Fill(time_ms, time_1280, nHits_good);
530 m_eventInjLERcut->Fill(time_ms, time_1280);
531 }
532 }
533 }
534 }
535
536 // fill raw data header histograms
537
538 const auto& feMapper = TOPGeometryPar::Instance()->getFrontEndMapper();
539 double differ = 0;
540 for (const auto& dbg : m_productionEventDebugs) {
541 auto scrodID = dbg.getScrodID();
542 const auto* femap = feMapper.getMap(scrodID);
543 if (not femap) {
544 B2ERROR("No front-end map available for scrodID " << scrodID);
545 continue;
546 }
547 auto slot = femap->getModuleID();
548 auto bs = femap->getBoardstackNumber();
549 double x = slot + bs / 4. - 0.5;
550 m_skipProcFlag->Fill(x, dbg.getSkipProcessingFlag());
551 m_injVetoFlag->Fill(x, dbg.getInjectionVetoFlag());
552 m_PSBypassMode->Fill(x, dbg.getPSBypassMode());
553 if (dbg.getInjectionVetoFlag() != m_productionEventDebugs[0]->getInjectionVetoFlag()) differ = 1;
554 }
555 m_injVetoFlagDiff->Fill(differ);
556
557 }

◆ event() [14/30]

void event ( void )
overridevirtual

Event processor.

Reimplemented from HistoModule.

Definition at line 158 of file TOPInterimFENtupleModule.cc.

159 {
160
161 m_nHit = 0;
162 m_nFEHeader = 0;
163 m_nEmptyFEHeader = 0;
164 m_nWaveform = 0;
165 m_errorFlag = 0;
166
167 StoreObjPtr<EventMetaData> EventMetaDataPtr;
168 StoreArray<RawTOP> rawTOPs;
169 StoreArray<TOPDigit> digits;
170
171 for (int iSlot = 0 ; iSlot < c_NModule ; iSlot++) {
172 m_eventNumCopper[iSlot] = -1;
173 m_ttuTime[iSlot] = -1;
174 m_ttcTime[iSlot] = -1;
175 }
176 int iSlotTTC = 0;
177 short trigCtime = -1;
178 for (auto& rawTOP : rawTOPs) {
179 if (iSlotTTC >= c_NModule) {
180 B2WARNING("too many TTC information");
181 break;
182 }
183 m_eventNumCopper[iSlotTTC] = rawTOP.GetEveNo(0);
184 m_ttuTime[iSlotTTC] = rawTOP.GetTTUtime(0);
185 m_ttcTime[iSlotTTC] = rawTOP.GetTTCtime(0);
186
187 if (trigCtime < 0)
188 trigCtime = ((((long)m_ttcTime[iSlotTTC] + (long)(m_ttuTime[iSlotTTC] - 1524741300) * 127216000) % 11520) % 3840) % 1284;
189 iSlotTTC++;
190 }
191
192 std::map<short, short> nHitOfflineFEMap;
193 static std::set<short> noisyChannelBlackListSet;
194 UInt_t EventNum = EventMetaDataPtr->getEvent();
195 m_eventNum = EventNum;
196 m_eventErrorFlag = EventMetaDataPtr->getErrorFlag();
197 for (const auto& digit : digits) {
198
199 if (m_nHit >= c_NMaxHitEvent) {
200 B2WARNING("TOPInterimFENtuple : too many hits found (>=" << c_NMaxHitEvent
201 << "), EventNo = " << EventNum << ", no more hits are recorded.");
202 break;
203 }
204
205 m_slotNum[m_nHit] = digit.getModuleID();
206 m_pixelId[m_nHit] = (short)digit.getPixelID();
207 m_channelId[m_nHit] = (short)digit.getChannel();
208 m_isCalCh[m_nHit] = (digit.getASICChannel() == m_calibrationChannel);
209 m_winNum[m_nHit] = -1;
210 m_eventWinNum[m_nHit] = (short)digit.getFirstWindow();
211 m_trigWinNum[m_nHit] = trigCtime;
212 m_revo9Counter[m_nHit] = -1;
213 m_hitQuality[m_nHit] = (unsigned char)digit.getHitQuality();
214 m_isReallyJunk[m_nHit] = false;
215 m_windowsInOrder[m_nHit] = true;
216 m_rawTime[m_nHit] = digit.getRawTime();
217 m_time[m_nHit] = digit.getTime() + m_winNum[m_nHit] * m_timePerWin;
218 m_sample[m_nHit] = TMath::FloorNint(m_rawTime[m_nHit] + m_winNum[m_nHit] * c_NSamplePerWindow) % c_NSampleTBC;
219 m_height[m_nHit] = digit.getPulseHeight();
220 m_integral[m_nHit] = digit.getIntegral();
221 m_width[m_nHit] = digit.getPulseWidth();
222 m_peakSample[m_nHit] = -1;
223 for (int iWindow = 0 ; iWindow < c_NWindow ; iWindow++)
224 m_winNumList[m_nHit][iWindow] = -32767;
225 for (int iSample = 0 ; iSample < c_NWaveformSample ; iSample++)
226 m_waveform[m_nHit][iSample] = -32767;
227 m_waveformStartSample[m_nHit] = -1;
228
229 short globalChannelId = m_pixelId[m_nHit] - 1 + (m_slotNum[m_nHit] - 1) * c_NPixelPerModule;
230 if (nHitOfflineFEMap.count(globalChannelId) == 0) nHitOfflineFEMap[globalChannelId] = 0;
231 else if (nHitOfflineFEMap[globalChannelId] > c_NMaxHitPerChannel) {
232 if (noisyChannelBlackListSet.count(globalChannelId) == 0) {
233 // cppcheck-suppress stlFindInsert
234 noisyChannelBlackListSet.insert(globalChannelId);
235 B2WARNING("TOPInterimFENtuple : noisy channel with too many hits (slotNum="
236 << (globalChannelId / c_NPixelPerModule + 1) << ", pixelId = "
237 << (globalChannelId / c_NPixelPerModule + 1) << ") ");
238 }
239 continue;
240 }
241
242 const auto* rawDigit = digit.getRelated<TOPRawDigit>();
243 if (rawDigit) {
244 m_winNum[m_nHit] = rawDigit->getASICWindow();
245 m_revo9Counter[m_nHit] = rawDigit->getRevo9Counter();
246 m_peakSample[m_nHit] = rawDigit->getSamplePeak();
247 m_windowsInOrder[m_nHit] = rawDigit->areWindowsInOrder();
248 if (rawDigit->getDataType() == TOPRawDigit::c_Interim)
249 m_trigWinNum[m_nHit] = (short)rawDigit->getLastWriteAddr();
250 if (rawDigit->isPedestalJump()) m_isReallyJunk[m_nHit] = true;
251 const auto* waveform = rawDigit->getRelated<TOPRawWaveform>();
252 if (waveform) {
253 if (rawDigit->isMadeOffline()) {
254
255 //fill hit flags ; =1 : first hit from offline FE, =2 : second ... , =0 : online FE, -1 : no waveform
256 nHitOfflineFEMap[globalChannelId]++;
257 m_offlineFlag[m_nHit] = nHitOfflineFEMap[globalChannelId];
258 } else { //hit from online feature extraction
259 m_offlineFlag[m_nHit] = 0;
260
261 //store waveform data
262 unsigned nSampleWfm = waveform->getSize();
263 unsigned nSample = TMath::Min((UShort_t)nSampleWfm, (UShort_t)c_NWaveformSample);
264 if (nSample > c_NWaveformSample)
265 B2WARNING("TOPInterimFENtuple: too many waveform samples in TOPRawWaveform : " << nSampleWfm << ", only first " << nSample <<
266 " are considered.");
267 for (unsigned iSample = 0 ; iSample < nSample ; iSample++)
268 m_waveform[m_nHit][iSample] = waveform->getWaveform()[iSample];
269 m_waveformStartSample[m_nHit] = (short)waveform->getStartSample();
270 m_nWaveformSample[m_nHit] = nSampleWfm;
271 //store window number
272 int iWin = 0;
273 for (const auto& window : waveform->getStorageWindows()) {
274 if (iWin < c_NWindow)
275 m_winNumList[m_nHit][iWin] = window;
276 else
277 B2WARNING("TOPInterimFENtuple: too many windows were found");
278
279 iWin++;
280 }
281
282 }
283 }//if( waveform )
284 else m_offlineFlag[m_nHit] = -1;
285 } else {
286 B2WARNING("TOPInterimFENtuple : no TOPRawDigit object found!");
287 m_offlineFlag[m_nHit] = -100;
288 }//if( rawDigit )
289
290
291 m_nHit++;
292 }//for( const auto& digit : digits )
293
294 for (int iHit = 0 ; iHit < m_nHit ; iHit++) {
295
296 short globalChannelId = m_pixelId[iHit] - 1 + (m_slotNum[iHit] - 1) * c_NPixelPerModule;
297 m_nHitOfflineFE[iHit] = nHitOfflineFEMap[globalChannelId];
298
299 }//for(int iHit)
300
301 StoreArray<TOPInterimFEInfo> infos;
302 for (const auto& info : infos) {
303 m_nFEHeader += info.getFEHeadersCount();
304 m_nEmptyFEHeader += info.getEmptyFEHeadersCount();
305 m_nWaveform += info.getWaveformsCount();
306 m_errorFlag |= info.getErrorFlags();
307 }
308
309 StoreArray<TOPProductionEventDebug> prodDebugs;
310 m_nDebugInfo = 0;
311 for (const auto& prodDebug : prodDebugs) {
312 m_scrodCtime[m_nDebugInfo] = prodDebug.getCtime();
313 m_phase[m_nDebugInfo] = prodDebug.getPhase();
314 m_asicMask[m_nDebugInfo] = prodDebug.getAsicMask();
315 m_eventQueuDepth[m_nDebugInfo] = prodDebug.getEventQueueDepth();
316 m_eventNumberByte[m_nDebugInfo] = prodDebug.getEventNumberByte();
317 m_nDebugInfo++;
318 }
319
320 //identify cal. pulse timing
321 getReferenceTiming();
322
323 m_tree->Fill();
324 }

◆ event() [15/30]

void event ( void )
overridevirtual

Event processor.

Reimplemented from Module.

Definition at line 77 of file TOPLaserCalibratorModule.cc.

78 {
79 for (auto& digit : m_digits) {
80 if (m_barID != 0 && digit.getModuleID() != m_barID) continue; //if m_barID == 0, use all 16 slots(for MC test)
81 unsigned channel = digit.getChannel();
82 if (channel < c_NumChannels) {
83 auto histo = m_histo[channel];
84 if (!histo) {
85 stringstream ss;
86 ss << "chan" << channel ;
87 string name;
88 ss >> name;
89 string title = "Times " + name;
90 histo = new TH1F(name.c_str(), title.c_str(), (int)m_fitRange[0], m_fitRange[1], m_fitRange[2]);
91 m_histo[channel] = histo;
92 }
93 if (digit.getHitQuality() != TOPDigit::EHitQuality::c_Good) continue;
94 if (digit.getTime() < m_fitRange[1] || digit.getTime() > m_fitRange[2]) continue;
95 if (!digit.isTimeBaseCalibrated()) continue;
96 histo->Fill(digit.getTime()); //get Time from TOPDigit
97 }
98 }
99 }

◆ event() [16/30]

void event ( void )
overridevirtual

Event processor.

Reimplemented from HistoModule.

Definition at line 149 of file TOPLaserHitSelectorModule.cc.

150 {
151 StoreArray<TOPDigit> digits;
152
153 std::map<short, float> refTimingMap;//map of pixel id and time
154 std::map<short, std::vector<hitInfo_t> >
155 calPulsesMap;//map of pixel id and hit information (timing and pulse charge) for cal. pulse candidetes
156
157 //first, identify cal. pulse
158 for (const auto& digit : digits) {
159
160 short slotId = digit.getModuleID();
161 short pixelId = digit.getPixelID();
162 short globalPixelId = (slotId - 1) * c_NPixelPerModule + pixelId - 1;
163 if (digit.getHitQuality() == TOPDigit::c_CalPulse) {
164 calPulsesMap[globalPixelId].push_back((hitInfo_t) { (float)digit.getTime(), (float)digit.getPulseHeight() });
165 }
166 }// for digit pair
167
168
169 //cal. pulse timing calculation
170 for (const auto& calPulse : calPulsesMap) {
171
172 short globalPixelId = calPulse.first;
173 short globalAsicId = globalPixelId / c_NChannelPerAsic;
174 std::vector<hitInfo_t> vec = calPulse.second;
175 double calPulseTiming = 9999999;
176 unsigned nCalPulseCandidates = vec.size();
177 if (!m_useDoublePulse) { //try to find the first cal. pulse in case that both of double cal. pulses are not required (choose the largest hit)
178 double maxPulseHeight = -1;
179 double maxHeightTiming = 9999999;
180 for (unsigned iVec = 0 ; iVec < nCalPulseCandidates ; iVec++) {
181 if (maxPulseHeight < vec[iVec].m_height) {
182 maxPulseHeight = vec[iVec].m_height;
183 maxHeightTiming = vec[iVec].m_time;
184 }
185 }
186 if (maxPulseHeight > m_calibrationPulseThreshold1)
187 calPulseTiming = maxHeightTiming;
188 } else { //try to identify both of double cal. pulses when specified by option (default)
189 for (unsigned iVec = 0 ; iVec < nCalPulseCandidates ; iVec++) {
190 for (unsigned jVec = 0 ; jVec < nCalPulseCandidates ; jVec++) {
191
192 if (iVec == jVec || vec[iVec].m_time > vec[jVec].m_time) continue;
193 if (vec[iVec].m_height > m_calibrationPulseThreshold1
194 && vec[jVec].m_height > m_calibrationPulseThreshold2
195 && TMath::Abs(vec[jVec].m_time - vec[iVec].m_time - m_calibrationPulseInterval) < m_calibrationPulseIntervalRange) {
196
197 //in case multiple candidates of double cal. pulses are found,
198 //choose a pair with the earliest 1st cal. pulse timing
199 if (refTimingMap.count(globalAsicId) == 0 || refTimingMap[globalAsicId] > vec[iVec].m_time)
200 calPulseTiming = vec[iVec].m_time;
201 }
202 }//for(jVec)
203 }//for(iVec)
204 }//if(m_useDoublePulse)
205
206 if (calPulseTiming < 9999998) { //when cal. pulse(s) are properly identified
207 refTimingMap[globalAsicId] = calPulseTiming;
208 m_nCalPulseHistogram->Fill(globalAsicId);
209 }
210 }//for(pair)
211
212 //calculate hit timing with respect to cal. pulse and fill hit info. histogram
213 for (const auto& digit : digits) {
214 short slotId = digit.getModuleID();
215 short pixelId = digit.getPixelID();
216 short globalPixelId = (slotId - 1) * c_NPixelPerModule + pixelId - 1;
217 short globalAsicId = globalPixelId / c_NChannelPerAsic;
218
219 if (digit.getHitQuality() == TOPDigit::c_Junk
220 || digit.getHitQuality() == TOPDigit::c_CrossTalk) continue;
221
222 float hitTime = digit.getTime() - refTimingMap[globalAsicId];
223 float pulseHeight = digit.getPulseHeight();
224 float Integral = digit.getIntegral();
225 short windowNumberOfHit = (short)(digit.getFirstWindow()) + (short)(digit.getRawTime() / 64);
226 if (m_windowSelect && windowNumberOfHit % 2 != (m_windowSelect - 1)) continue;
227
228 if (m_includeAllChargeShare) {
229 m_TimeHeightHistogramForHitRate[globalPixelId]->Fill(hitTime, pulseHeight);
230 m_TimeIntegralHistogramForFit[globalPixelId]->Fill(hitTime, Integral);
231 m_TimeHeightHistogramForFit[globalPixelId]->Fill(hitTime, pulseHeight);
232 continue;
233 }
234
235 if (!digit.isSecondaryChargeShare()) {
236 m_TimeHeightHistogramForHitRate[globalPixelId]->Fill(hitTime, pulseHeight);
237 if (m_includePrimaryChargeShare) {
238 m_TimeIntegralHistogramForFit[globalPixelId]->Fill(hitTime, Integral);
239 m_TimeHeightHistogramForFit[globalPixelId]->Fill(hitTime, pulseHeight);
240 continue;
241 }
242 }
243
244 if (digit.isSecondaryChargeShare() || digit.isPrimaryChargeShare()) continue;
245 m_TimeIntegralHistogramForFit[globalPixelId]->Fill(hitTime, Integral);
246 m_TimeHeightHistogramForFit[globalPixelId]->Fill(hitTime, pulseHeight);
247 }
248
249 }

◆ event() [17/30]

void event ( void )
overridevirtual

Event processor.

Reimplemented from Module.

Definition at line 84 of file TOPMCTrackMakerModule.cc.

85 {
86
87 StoreArray<MCParticle> mcParticles;
88 StoreArray<TOPBarHit> barHits;
89
90 StoreArray<Track> tracks;
91 StoreArray<TrackFitResult> fitResults;
92 StoreArray<ExtHit> extHits;
93
94 for (const auto& mcParticle : mcParticles) {
95 if (mcParticle.getStatus(MCParticle::c_PrimaryParticle) == 0) continue;
96 if (mcParticle.getCharge() == 0) continue;
97 const auto* barHit = mcParticle.getRelated<TOPBarHit>();
98 if (!barHit) continue;
99
100 TMatrixDSym cov(6); // infinite precision
101 fitResults.appendNew(mcParticle.getVertex(),
102 mcParticle.getMomentum(),
103 cov,
104 mcParticle.getCharge(),
105 Const::pion,
106 1.0, // pValue
107 BFieldManager::getField(0, 0, 0).Z() / Unit::T,
108 0x38FFFFFFFFFFFFFF, // 56 hits, in all CDC layers
109 0, 56 - 5); // NDF = 56-5
110 auto* track = tracks.appendNew();
111 track->setTrackFitResultIndex(Const::pion, fitResults.getEntries() - 1);
112 track->addRelationTo(&mcParticle);
113
114 const Const::ChargedStable& chargedStable = Const::pion;
115 double pmom = barHit->getMomentum().R();
116 double mass = chargedStable.getMass();
117 double beta = pmom / sqrt(pmom * pmom + mass * mass);
118 double tof = barHit->getLength() / beta / Const::speedOfLight;
119 const auto* extHit = extHits.appendNew(tof,
120 chargedStable.getPDGCode(),
121 Const::TOP,
122 barHit->getModuleID(),
123 EXT_ENTER,
124 false,
125 barHit->getPosition(),
126 barHit->getMomentum(),
127 cov);
128 track->addRelationTo(extHit);
129 }
130
131 }

◆ event() [18/30]

void event ( void )
overridevirtual

Event processor.

Reimplemented from Module.

Definition at line 169 of file TOPModuleT0CalibratorModule.cc.

170 {
171 /* check bunch reconstruction status and run alignment:
172 - if object exists and bunch is found (collision data w/ bunch finder in the path)
173 - if object doesn't exist (cosmic data and other cases w/o bunch finder)
174 */
175
176 if (m_recBunch.isValid()) {
177 if (not m_recBunch->isReconstructed()) return;
178 }
179
180 TOPRecoManager::setDefaultTimeWindow();
181 double timeMin = TOPRecoManager::getMinTime();
182 double timeMax = TOPRecoManager::getMaxTime();
183
184 // running offset must not be subtracted in TOPDigits: issue an error if it is
185
186 if (isRunningOffsetSubtracted()) {
187 B2ERROR("Running offset subtracted in TOPDigits: module T0 will not be correct");
188 }
189
190 // loop over reconstructed tracks, make a selection and accumulate log likelihoods
191
192 for (const auto& track : m_tracks) {
193
194 // track selection
195 TOPTrack trk(track);
196 if (not trk.isValid()) continue;
197
198 if (not m_selector.isSelected(trk)) continue;
199
200 // construct PDF
201 PDFConstructor pdfConstructor(trk, m_selector.getChargedStable(), m_PDFOption);
202 if (not pdfConstructor.isValid()) continue;
203
204 // minimization procedure: accumulate
205 const unsigned module = trk.getModuleID() - 1;
206 if (module >= c_numModules) continue;
207 int sub = gRandom->Integer(2); // generate sub-sample number
208 auto& finder = m_finders[sub][module];
209 const auto& binCenters = finder.getBinCenters();
210 for (unsigned ibin = 0; ibin < binCenters.size(); ibin++) {
211 double t0 = binCenters[ibin];
212 finder.add(ibin, -2 * pdfConstructor.getLogL(t0, m_sigmaSmear).logL);
213 }
214
215 // fill histograms of hits
216 m_numPhotons = 0;
217 for (const auto& digit : m_digits) {
218 if (digit.getHitQuality() != TOPDigit::c_Good) continue;
219 if (digit.getModuleID() != trk.getModuleID()) continue;
220 if (digit.getTime() < timeMin) continue;
221 if (digit.getTime() > timeMax) continue;
222 m_numPhotons++;
223 m_hits1D.Fill(digit.getModuleID());
224 int bs = digit.getBoardstackNumber();
225 m_hits2D.Fill((digit.getModuleID() * 4 + bs - 1.5) / 4.0, digit.getTime());
226 }
227
228 // fill output tree
229 m_moduleID = trk.getModuleID();
230 const auto& localPosition = m_selector.getLocalPosition();
231 m_x = localPosition.X();
232 m_y = localPosition.Y();
233 m_z = localPosition.Z();
234 const auto& localMomentum = m_selector.getLocalMomentum();
235 m_p = localMomentum.R();
236 m_theta = localMomentum.Theta();
237 m_phi = localMomentum.Phi();
238 const auto& pocaPosition = m_selector.getPOCAPosition();
239 m_pocaR = pocaPosition.Rho();
240 m_pocaZ = pocaPosition.Z();
241 m_pocaX = pocaPosition.X();
242 m_pocaY = pocaPosition.Y();
243 m_cmsE = m_selector.getCMSEnergy();
244 m_charge = trk.getCharge();
245 m_PDG = trk.getPDGCode();
246 m_tree->Fill();
247 }
248
249 }

◆ event() [19/30]

void event ( void )
overridevirtual

Event processor.

Reimplemented from Module.

Definition at line 123 of file TOPNtupleModule.cc.

124 {
125
126 StoreObjPtr<EventMetaData> evtMetaData;
127 StoreArray<Track> tracks;
128 StoreObjPtr<MCInitialParticles> mcInitialParticles;
129 double trueEventT0 = 0;
130 if (mcInitialParticles.isValid()) trueEventT0 = mcInitialParticles->getTime();
131
132 const auto* geo = TOPGeometryPar::Instance()->getGeometry();
133
134 for (const auto& track : tracks) {
135 const auto* trackFit = track.getTrackFitResultWithClosestMass(Const::pion);
136 if (!trackFit) continue;
137 const TOPLikelihood* top = track.getRelated<TOPLikelihood>();
138 if (!top) continue;
139 if (top->getFlag() != 1) continue;
140
141 const ExtHit* extHit = top->getRelated<ExtHit>();
142 const TOPBarHit* barHit = top->getRelated<TOPBarHit>();
143 const MCParticle* mcParticle = track.getRelated<MCParticle>();
144 const MCParticle* mother = 0;
145 if (mcParticle) {
146 mother = mcParticle->getMother();
147 if (not barHit) { // Track MC matching probably done after TOPReconstructor so no relation from TOPLikelihood
148 const auto barHits = mcParticle->getRelationsWith<TOPBarHit>();
149 for (const auto& bHit : barHits) {
150 if (bHit.getModuleID() == extHit->getCopyID()) barHit = &bHit;
151 }
152 }
153 }
154
155 m_top.clear();
156
157 m_top.evt = evtMetaData->getEvent();
158 m_top.run = evtMetaData->getRun();
159
160 ROOT::Math::XYZVector mom = trackFit->getMomentum();
161 m_top.p = mom.R();
162 m_top.cth = cos(mom.Theta());
163 m_top.phi = mom.Phi();
164 m_top.pValue = trackFit->getPValue();
165
166 if (mcParticle) {
167 m_top.PDG = mcParticle->getPDG();
168 if (mother) m_top.motherPDG = mother->getPDG();
169 m_top.primary = mcParticle->getStatus(MCParticle::c_PrimaryParticle);
170 m_top.seen = mcParticle->hasSeenInDetector(Const::TOP);
171 ROOT::Math::XYZVector prodVertex = mcParticle->getProductionVertex();
172 m_top.rhoProd = prodVertex.Rho();
173 m_top.zProd = prodVertex.Z();
174 m_top.phiProd = prodVertex.Phi();
175 ROOT::Math::XYZVector decVertex = mcParticle->getDecayVertex();
176 m_top.rhoDec = decVertex.Rho();
177 m_top.zDec = decVertex.Z();
178 m_top.phiDec = decVertex.Phi();
179 const auto digits = mcParticle->getRelationsWith<TOPDigit>();
180 for (size_t i = 0; i < digits.size(); i++) {
181 double wt = digits.weight(i);
182 if (wt <= 0) continue; // photon not from this MC particle
183 const auto* digit = digits[i];
184 if (digit->getHitQuality() != TOPDigit::c_Good) continue;
185 if (digit->getModuleID() != top->getModuleID()) continue;
186 if (digit->getTime() < TOPRecoManager::getMinTime() or digit->getTime() > TOPRecoManager::getMaxTime()) continue;
187 m_top.yieldMC++;
188 }
189 }
190
191 m_top.numPhot = top->getNphot();
192 m_top.numBkg = top->getEstBkg();
193 m_top.moduleID = top->getModuleID();
194
195 m_top.phot.e = top->getEstPhot(Const::electron);
196 m_top.phot.mu = top->getEstPhot(Const::muon);
197 m_top.phot.pi = top->getEstPhot(Const::pion);
198 m_top.phot.K = top->getEstPhot(Const::kaon);
199 m_top.phot.p = top->getEstPhot(Const::proton);
200 m_top.phot.d = top->getEstPhot(Const::deuteron);
201
202 m_top.yield.e = top->getEffectiveSignalYield(Const::electron);
203 m_top.yield.mu = top->getEffectiveSignalYield(Const::muon);
204 m_top.yield.pi = top->getEffectiveSignalYield(Const::pion);
205 m_top.yield.K = top->getEffectiveSignalYield(Const::kaon);
206 m_top.yield.p = top->getEffectiveSignalYield(Const::proton);
207 m_top.yield.d = top->getEffectiveSignalYield(Const::deuteron);
208
209 m_top.logL.e = top->getLogL(Const::electron);
210 m_top.logL.mu = top->getLogL(Const::muon);
211 m_top.logL.pi = top->getLogL(Const::pion);
212 m_top.logL.K = top->getLogL(Const::kaon);
213 m_top.logL.p = top->getLogL(Const::proton);
214 m_top.logL.d = top->getLogL(Const::deuteron);
215
216 if (extHit) {
217 int moduleID = extHit->getCopyID();
218 auto position = static_cast<ROOT::Math::XYZPoint>(extHit->getPosition());
219 auto momentum = extHit->getMomentum();
220 if (geo->isModuleIDValid(moduleID)) {
221 const auto& module = geo->getModule(moduleID);
222 position = module.pointToLocal(position);
223 momentum = module.momentumToLocal(momentum);
224 }
225 m_top.extHit.moduleID = moduleID;
226 m_top.extHit.PDG = extHit->getPdgCode();
227 m_top.extHit.x = position.X();
228 m_top.extHit.y = position.Y();
229 m_top.extHit.z = position.Z();
230 m_top.extHit.p = momentum.R();
231 m_top.extHit.theta = momentum.Theta();
232 m_top.extHit.phi = momentum.Phi();
233 m_top.extHit.time = extHit->getTOF();
234 }
235
236 if (barHit) {
237 int moduleID = barHit->getModuleID();
238 auto position = barHit->getPosition();
239 auto momentum = barHit->getMomentum();
240 if (geo->isModuleIDValid(moduleID)) {
241 const auto& module = geo->getModule(moduleID);
242 position = module.pointToLocal(position);
243 momentum = module.momentumToLocal(momentum);
244 }
245 m_top.barHit.moduleID = moduleID;
246 m_top.barHit.PDG = barHit->getPDG();
247 m_top.barHit.x = position.X();
248 m_top.barHit.y = position.Y();
249 m_top.barHit.z = position.Z();
250 m_top.barHit.p = momentum.R();
251 m_top.barHit.theta = momentum.Theta();
252 m_top.barHit.phi = momentum.Phi();
253 m_top.barHit.time = barHit->getTime() - trueEventT0;
254 }
255
256 m_tree->Fill();
257 }
258
259 }
ROOT::Math::XYZVector getMomentum() const
Returns momentum vector.
Definition Particle.h:580

◆ event() [20/30]

void event ( void )
overridevirtual

Event processor.

Reimplemented from Module.

Definition at line 95 of file TOPPackerModule.cc.

96 {
97
98 switch (m_dataType) {
99 case TOP::RawDataType::c_Type0Ver16:
100 packType0Ver16();
101 break;
102 case TOP::RawDataType::c_ProductionDebug01:
103 packProductionDebug();
104 break;
105 case TOP::RawDataType::c_Draft:
106 packProductionDraft();
107 break;
108 default:
109 B2ERROR("TOPPacker: data format unknown or not implemented");
110 }
111
112 }

◆ event() [21/30]

void event ( void )
overridevirtual

Event processor.

Reimplemented from HistoModule.

Definition at line 118 of file TOPPDFCheckerModule.cc.

119 {
120 TOPRecoManager::setTimeWindow(m_minTime, m_maxTime);
121 const auto* geo = TOPGeometryPar::Instance()->getGeometry();
122
123 // loop over reconstructed tracks, call reconstruction and fill histograms
124
125 int numTrk = 0;
126 for (const auto& track : m_tracks) {
127 TOPTrack trk(track);
128 if (not trk.isValid()) continue;
129 if (not trk.getMCParticle()) continue;
130 if (not trk.getBarHit()) continue;
131
132 auto chargedStable = Const::chargedStableSet.find(abs(trk.getPDGCode()));
133 if (chargedStable == Const::invalidParticle) continue;
134
135 PDFConstructor pdfConstructor(trk, chargedStable, PDFConstructor::c_Fine);
136 if (not pdfConstructor.isValid()) continue;
137 numTrk++;
138
139 // average values - to print in terminate()
140 const auto& module = geo->getModule(trk.getModuleID());
141 m_avrgMomentum += module.momentumToLocal(trk.getExtHit()->getMomentum());
142 m_avrgPosition += static_cast<XYZVector>(module.pointToLocal(static_cast<XYZPoint>(trk.getExtHit()->getPosition())));
143 m_numTracks++;
144 m_slotIDs.emplace(trk.getModuleID());
145 m_PDGCodes.emplace(trk.getPDGCode());
146
147 // histogram photons in a slot crossed by the track
148 for (const auto& digit : m_digits) {
149 if (digit.getModuleID() == trk.getModuleID() and digit.getTime() < m_maxTime) {
150 if (not isFromThisParticle(digit, trk.getMCParticle())) continue;
151 m_hits->Fill(digit.getPixelID(), digit.getTime());
152 m_hitsCol->Fill(digit.getPixelCol(), digit.getTime());
153 }
154 }
155
156 // histogram PDF using MC approach
157 for (const auto& signalPDF : pdfConstructor.getSignalPDF()) {
158 int pixelID = signalPDF.getPixelID();
159 for (const auto& peak : signalPDF.getPDFPeaks()) {
160 double numPhot = pdfConstructor.getExpectedSignalPhotons() * peak.nph;
161 double sigma = sqrt(peak.wid);
162 for (ULong64_t i = 0; i < gRandom->Poisson(numPhot); i++) {
163 double time = gRandom->Gaus(peak.t0, sigma);
164 m_pdf->Fill(pixelID, time);
165 int pixelCol = (pixelID - 1) % 64 + 1;
166 m_pdfCol->Fill(pixelCol, time);
167 }
168 }
169 }
170
171 }
172
173 if (numTrk == 0) {
174 B2WARNING("No track hitting the bars");
175 } else if (numTrk > 1) {
176 B2WARNING("More than one track hits the bars");
177 }
178
179 }

◆ event() [22/30]

void event ( void )
overridevirtual

Event processor.

Reimplemented from Module.

Definition at line 121 of file TOPPDFDebuggerModule.cc.

122 {
123 const auto* geo = TOPGeometryPar::Instance()->getGeometry();
124 TOPRecoManager::setTimeWindow(m_minTime, m_maxTime);
125
126 // reconstruct track-by-track and store the results
127
128 for (const auto& track : m_tracks) {
129 TOPTrack trk(track);
130 if (not trk.isValid()) continue;
131
132 // add this vector of vector of triplets to the TOPPDFCollection
133 TOPPDFCollection* topPDFColl = m_pdfCollection.appendNew();
134 const auto& module = geo->getModule(trk.getModuleID());
135 topPDFColl->setLocalPositionMomentum(module.pointToLocal(static_cast<XYZPoint>(trk.getExtHit()->getPosition())),
136 module.momentumToLocal(trk.getExtHit()->getMomentum()),
137 trk.getModuleID());
138
139 TOPPixelLikelihood* topPLkhs = m_pixelData.appendNew();
140 topPLkhs->setModuleID(trk.getModuleID());
141
142 for (const auto& chargedStable : m_chargedStables) {
143 const PDFConstructor pdfConstructor(trk, chargedStable, m_PDFOption, PDFConstructor::c_Full);
144 if (not pdfConstructor.isValid()) {
145 B2ERROR("PDFConstructor found not valid - bug in reconstruction code?"
146 << LogVar("PDG", chargedStable.getPDGCode()));
147 continue;
148 }
149
150 // associate PDF peaks with photons using S-plot technique
151 associatePDFPeaks(pdfConstructor);
152
153 // collection of gaussian_t's for each pixel
154 TOPPDFCollection::modulePDF_t channelPDFCollection;
155
156 // store PDF peaks in the collection
157 for (const auto& signalPDF : pdfConstructor.getSignalPDF()) {
158 int pixelID = signalPDF.getPixelID();
159 for (const auto& peak : signalPDF.getPDFPeaks()) {
160 float position = peak.t0;
161 float width = sqrt(peak.wid);
162 float numPhotons = pdfConstructor.getExpectedSignalPhotons() * peak.nph;
163 auto tp = TOPPDFCollection::Gaussian(position, width, numPhotons);
164 channelPDFCollection.at(pixelID - 1).push_back(tp);
165 } // end loop over peaks in the pdf for this pixel
166 } // end loop over pixels
167
168 topPDFColl->addHypothesisPDF(channelPDFCollection, chargedStable.getPDGCode());
169
170 // Initialize logL and sfot pixel arrays
171 TOPPixelLikelihood::PixelArray_t pixLogLs, pixSigPhots;
172 pixLogLs.fill(0);
173 pixSigPhots.fill(0);
174
175 const auto& pixelLogLs = pdfConstructor.getPixelLogLs(0);
176 for (size_t i = 0; i < std::min(pixelLogLs.size(), pixLogLs.size()); i++) {
177 pixLogLs[i] = pixelLogLs[i].logL;
178 pixSigPhots[i] = pixelLogLs[i].expPhotons;
179 }
180
181 topPLkhs->addHypothesisLikelihoods(pixLogLs, chargedStable.getPDGCode());
182 topPLkhs->addHypothesisSignalPhotons(pixSigPhots, chargedStable.getPDGCode());
183 }
184 track.addRelationTo(topPDFColl);
185 track.addRelationTo(topPLkhs);
186
187 } // end loop over tracks
188
189 }

◆ event() [23/30]

void event ( void )
overridevirtual

Event processor.

Reimplemented from Module.

Definition at line 195 of file TOPRawDigitConverterModule.cc.

196 {
197
198 // get mappers
199
200 const auto& feMapper = TOPGeometryPar::Instance()->getFrontEndMapper();
201 const auto& chMapper = TOPGeometryPar::Instance()->getChannelMapper();
202 const auto* geo = TOPGeometryPar::Instance()->getGeometry();
203
204 // clear TOPDigits
205
206 m_digits.clear();
207
208 // set storage windows in RawDigits if not already done in unpacker
209
210 for (auto& rawDigit : m_rawDigits) {
211 const auto* waveform = rawDigit.getRelated<TOPRawWaveform>();
212 if (waveform and rawDigit.getStorageWindows().empty()) {
213 rawDigit.setStorageWindows(waveform->getStorageWindows());
214 }
215 }
216
217 // set asic masks (asics and whole boardstacks masked in firmware for this event)
218
219 m_asicMask.create();
220 if (m_eventDebugs.getEntries() > 0) {
221 std::vector<unsigned short> masks(64, 0xFFFF);
222 for (const auto& eventDebug : m_eventDebugs) {
223 auto scrodID = eventDebug.getScrodID();
224 const auto* feemap = feMapper.getMap(scrodID);
225 if (not feemap) {
226 B2WARNING("TOPRawDigitConverter: No front-end map available."
227 << LogVar("scrodID", scrodID));
228 continue;
229 }
230 auto moduleID = feemap->getModuleID();
231 auto boardstack = feemap->getBoardstackNumber();
232 unsigned bs = (moduleID - 1) * 4 + boardstack;
233 if (bs < 64) {
234 masks[bs] = eventDebug.getAsicMask();
235 } else {
236 B2ERROR("TOPRawDigitConverter: Invalid global boardstack number."
237 << LogVar("bs", bs));
238 }
239 }
240 m_asicMask->set(masks);
241 }
242
243 // convert to TOPDigits
244
245 for (const auto& rawDigit : m_rawDigits) {
246
247 if (rawDigit.getErrorFlags() != 0) continue;
248
249 // determine moduleID, pixedID and channel
250
251 auto scrodID = rawDigit.getScrodID();
252 const auto* feemap = feMapper.getMap(scrodID);
253 if (not feemap) {
254 B2WARNING("TOPRawDigitConverter: No front-end map available."
255 << LogVar("scrodID", scrodID));
256 continue;
257 }
258 auto moduleID = feemap->getModuleID();
259 auto boardstack = feemap->getBoardstackNumber();
260 auto channel = chMapper.getChannel(boardstack,
261 rawDigit.getCarrierNumber(),
262 rawDigit.getASICNumber(),
263 rawDigit.getASICChannel());
264 auto pixelID = chMapper.getPixelID(channel);
265
266 // get raw times
267
268 double rawTimeLeading = rawDigit.getCFDLeadingTime(); // time in [samples]
269 double rawTimeFalling = rawDigit.getCFDFallingTime(); // time in [samples]
270
271 // get ASIC window
272
273 int window = rawDigit.getASICWindow();
274
275 // timing alignment: set time origin according to data type
276
277 double timeOffset = 0;
278 int storageDepth = m_storageDepth;
279 if (rawDigit.getDataType() == TOPRawDigit::c_Interim) {
280
281 // correct raw times for possible window discontinuity
282 rawTimeLeading = rawDigit.correctTime(rawTimeLeading, m_storageDepth);
283 rawTimeFalling = rawDigit.correctTime(rawTimeFalling, m_storageDepth);
284
285 // set window number: number of look back windows back from the last write address
286 int lastWriteAddr = rawDigit.getLastWriteAddr();
287 int nback = lastWriteAddr - window;
288 if (nback < 0) nback += m_storageDepth;
289 int lookBackWindows = m_feSetting->getLookbackWindows();
290 if (m_lookBackWindows > 0) lookBackWindows = m_lookBackWindows;
291 int nwin = lookBackWindows - nback;
292 window -= nwin;
293 if (window < 0) window += m_storageDepth;
294 if (window >= (int) m_storageDepth) window -= m_storageDepth;
295
296 // add samples to raw time to account for the new window number
297 rawTimeLeading += nwin * TOPRawDigit::c_WindowSize;
298 rawTimeFalling += nwin * TOPRawDigit::c_WindowSize;
299 } else if (rawDigit.getDataType() == TOPRawDigit::c_ProductionDebug) {
300
301 // take revo9 counter and calculate corresponding SST count and its fraction
302 int revo9cnt = rawDigit.getRevo9Counter();
303 int SSTcnt = revo9cnt / 6;
304 double SSTfrac = (revo9cnt % 6) / 6.0;
305 double offset = m_feSetting->getOffset() / 24.0;
306 timeOffset = (SSTfrac + offset) * m_syncTimeBase; // in [ns], to be subtracted
307
308 // find reference window
309 int refWindow = SSTcnt * 2; // seems to be the same as lastWriteAddr
310 const auto& writeDepths = m_feSetting->getWriteDepths();
311 if (writeDepths.empty()) {
312 B2ERROR("TOPRawDigitConverter: vector of write depths is empty. Return!");
313 return;
314 }
315 int lastDepth = writeDepths.back();
316 unsigned phase = 0;
317 for (auto depth : writeDepths) {
318 SSTcnt -= depth;
319 if (SSTcnt < 0) break;
320 phase++;
321 refWindow = SSTcnt * 2;
322 lastDepth = depth;
323 }
324 if (m_setPhase) const_cast<TOPRawDigit&>(rawDigit).setPhase(phase);
325 storageDepth = lastDepth * 2;
326
327 if (window >= storageDepth) {
328 B2WARNING("TOPRawDigitConverter: window number greater than storage depth."
329 << LogVar("window number", window)
330 << LogVar("storage depth", storageDepth)
331 << LogVar("refWindow", refWindow)
332 << LogVar("phase", phase));
333 continue;
334 }
335
336 // set window number: number of look back windows back from the reference window
337 int deltaWindow = window - refWindow;
338 if (deltaWindow > 0) deltaWindow -= storageDepth;
339 int lookBackWindows = m_feSetting->getLookbackWindows();
340 if (m_lookBackWindows > 0) lookBackWindows = m_lookBackWindows;
341 lookBackWindows -= m_feSetting->getExtraWindows();
342
343 int nwin = lookBackWindows + deltaWindow;
344 int startWindow = refWindow - lookBackWindows;
345 if (startWindow < 0) startWindow += storageDepth;
346 window = startWindow;
347
348 // add samples to raw time to account for the new window number
349 rawTimeLeading += nwin * TOPRawDigit::c_WindowSize;
350 rawTimeFalling += nwin * TOPRawDigit::c_WindowSize;
351 }
352
353 // convert raw time to time using equidistant or calibrated time base
354
355 unsigned short statusBits = 0;
356 const auto* sampleTimes = &m_sampleTimes; // equidistant sample times
357 if (m_useSampleTimeCalibration) {
358 sampleTimes = m_timebase->getSampleTimes(scrodID, channel % 128);
359 if (sampleTimes->isCalibrated()) {
360 statusBits |= TOPDigit::c_TimeBaseCalibrated;
361 }
362 }
363 // time and width in [ns]
364 double time = sampleTimes->getTime(window, rawTimeLeading) - timeOffset;
365 double width = sampleTimes->getDeltaTime(window, rawTimeFalling, rawTimeLeading);
366
367 // default time uncertainty
368 double timeError = geo->getNominalTDC().getTimeJitter();
369
370 if (rawDigit.getDataType() == TOPRawDigit::c_MC) {
371 // MC with simplified digitization
372 time -= geo->getNominalTDC().getOffset();
373 statusBits |= TOPDigit::c_OffsetSubtracted;
374 } else {
375 // data and MC with full waveform digitization
376 if (m_pedestalRMS > 0) {
377 double rmsNoise = m_pedestalRMS;
378 if (m_noises->isCalibrated(moduleID, channel)) {
379 rmsNoise = m_noises->getNoise(moduleID, channel);
380 }
381 double rawErr = rawDigit.getCFDLeadingTimeError(rmsNoise); // in [samples]
382 int sample = static_cast<int>(rawTimeLeading);
383 if (rawTimeLeading < 0) sample--;
384 timeError = rawErr * sampleTimes->getTimeBin(window, sample); // [ns]
385 }
386
387 double timeErrorSq = timeError * timeError;
388
389 if (m_useTimeWalkCalibration) {
390 if (m_timeWalk->isCalibrated()) {
391 auto pulseHeight = rawDigit.getValuePeak();
392 time -= m_timeWalk->getTimeWalk(pulseHeight);
393 timeErrorSq += m_timeWalk->getSigmaSq(pulseHeight);
394 }
395 }
396 if (m_useChannelT0Calibration) {
397 const auto& cal = m_channelT0;
398 if (cal->isCalibrated(moduleID, channel)) {
399 time -= cal->getT0(moduleID, channel);
400 double err = cal->getT0Error(moduleID, channel); // statistical, from laser data fit
401 double sys = m_calPrecision.isValid() ? m_calPrecision->get(moduleID) : 0; // systematical, from di-muon events
402 timeErrorSq += err * err + sys * sys;
403 statusBits |= TOPDigit::c_ChannelT0Calibrated;
404 }
405 }
406 if (m_useAsicShiftCalibration) {
407 auto asic = channel / 8;
408 if (m_asicShift->isCalibrated(moduleID, asic)) {
409 time -= m_asicShift->getT0(moduleID, asic);
410 }
411 }
412 if (m_useModuleT0Calibration) {
413 const auto& cal = m_moduleT0;
414 if (cal->isCalibrated(moduleID)) {
415 time -= cal->getT0(moduleID);
416 double err = cal->getT0Error(moduleID);
417 timeErrorSq += err * err;
418 statusBits |= TOPDigit::c_ModuleT0Calibrated;
419 }
420 }
421 if (m_useCommonT0Calibration) {
422 const auto& cal = m_commonT0;
423 if (cal->isCalibrated()) {
424 time -= cal->getT0();
425 double err = cal->getT0Error();
426 timeErrorSq += err * err;
427 statusBits |= TOPDigit::c_CommonT0Calibrated;
428 }
429 }
430 timeError = sqrt(timeErrorSq);
431 }
432
433 // append new TOPDigit and set it
434
435 auto* digit = m_digits.appendNew(moduleID, pixelID, rawTimeLeading);
436 digit->setTime(time);
437 digit->setTimeError(timeError);
438 digit->setPulseHeight(rawDigit.getValuePeak());
439 digit->setIntegral(rawDigit.getIntegral());
440 digit->setPulseWidth(width);
441 digit->setChannel(channel);
442 digit->setFirstWindow(window);
443 digit->setStatus(statusBits);
444 if (m_addRelations) digit->addRelationTo(&rawDigit);
445
446 if (not rawDigit.isFEValid() or rawDigit.isPedestalJump())
447 digit->setHitQuality(TOPDigit::c_Junk);
448 if (rawDigit.isAtWindowDiscontinuity(storageDepth))
449 digit->setHitQuality(TOPDigit::c_Junk);
450 if (digit->getPulseWidth() < m_minPulseWidth or
451 digit->getPulseWidth() > m_maxPulseWidth or
452 digit->getPulseWidth() * digit->getPulseHeight() < m_minWidthXheight)
453 digit->setHitQuality(TOPDigit::c_Junk);
454 }
455
456 // if calibration channel given, select and flag cal pulses
457
458 unsigned calibrationChannel = m_calibrationChannel;
459 if (calibrationChannel < 8) {
460 for (auto& digit : m_digits) {
461 if (digit.getHitQuality() != TOPDigit::c_Good) continue;
462 if (digit.getASICChannel() != calibrationChannel) continue;
463 if (digit.getPulseHeight() < m_calpulseHeightMin) continue;
464 if (digit.getPulseHeight() > m_calpulseHeightMax) continue;
465 if (digit.getPulseWidth() < m_calpulseWidthMin) continue;
466 if (digit.getPulseWidth() > m_calpulseWidthMax) continue;
467 if (m_calpulseTimeMax > m_calpulseTimeMin) {
468 if (digit.getTime() < m_calpulseTimeMin) continue;
469 if (digit.getTime() > m_calpulseTimeMax) continue;
470 }
471 digit.setHitQuality(TOPDigit::c_CalPulse);
472 }
473 }
474
475 }

◆ event() [24/30]

void event ( void )
overridevirtual

Event processor.

Reimplemented from Module.

Definition at line 92 of file TOPReconstructorModule.cc.

93 {
94 // clear output collections
95
96 m_likelihoods.clear();
97 m_topPulls.clear();
98
99 // check bunch reconstruction status and do the reconstruction:
100 // - if object exists and bunch is found (collision data w/ bunch finder in the path)
101 // - if object doesn't exist (cosmic data and other cases w/o bunch finder in the path)
102
103 if (m_recBunch.isValid()) {
104 if (not m_recBunch->isReconstructed()) return;
105 }
106
107 // set time window in which photon hits are accepted for likelihood determination
108
109 TOPRecoManager::setTimeWindow(m_minTime, m_maxTime);
110
111 // is MC ?
112
113 bool isMC = Environment::Instance().isMC();
114
115 // sort tracks by module ID
116
117 std::unordered_multimap<int, const TOPTrack*> topTracks; // tracks sorted by top modules
118 for (const auto& track : m_tracks) {
119 auto* trk = new TOPTrack(track, m_topDigitCollectionName);
120 if (trk->isValid() and trk->getTransverseMomentum() > m_pTCut) {
121 if (not isMC) trk->setTOFCorrection(m_tofCorrections); // TOF corrections only for data
122 topTracks.emplace(trk->getModuleID(), trk);
123 } else {
124 delete trk;
125 }
126 }
127
128 // reconstruct module-by-module
129
130 const auto* geo = TOPGeometryPar::Instance()->getGeometry();
131 for (unsigned moduleID = 1; moduleID <= geo->getNumModules(); moduleID++) {
132
133 // make a vector of PDF collections for a given TOP module
134
135 std::vector<PDFCollection> pdfCollections;
136 const auto& range = topTracks.equal_range(moduleID);
137 for (auto it = range.first; it != range.second; ++it) {
138 const auto* trk = it->second;
139 PDFCollection collection(*trk, m_deltaRayModeling);
140 if (collection.isValid) pdfCollections.push_back(collection);
141 }
142 if (pdfCollections.empty()) continue;
143
144 // add most probable PDF's of other tracks if present
145
146 if (pdfCollections.size() > 1) {
147 std::vector<int> lastMostProbables;
148 for (int iter = 0; iter < 10; iter++) {
149 std::vector<int> mostProbables;
150 for (auto& collection : pdfCollections) { // set most probable PDF
151 collection.setMostProbable();
152 mostProbables.push_back(collection.mostProbable->getHypothesis().getPDGCode());
153 }
154 if (mostProbables == lastMostProbables) break;
155 else lastMostProbables = mostProbables;
156
157 for (auto& collection : pdfCollections) collection.clearPDFOther(); // reset
158 for (auto& collection : pdfCollections) { // append
159 for (const auto& other : pdfCollections) {
160 if (&other == &collection) continue;
161 collection.appendPDFOther(other.mostProbable);
162 }
163 }
164 } // loop: iter
165 }
166
167 // determine and save log likelihoods
168
169 for (const auto& collection : pdfCollections) {
170 auto* topLL = m_likelihoods.appendNew();
171 const auto* trk = collection.topTrack;
172 const auto* track = trk->getTrack();
173 track->addRelationTo(topLL);
174 topLL->addRelationTo(trk->getExtHit());
175 topLL->addRelationTo(trk->getBarHit());
176
177 int pdgCode = (m_PDGCode != 0) ? m_PDGCode : trk->getPDGCode(); // PDG code used for providing pulls
178 std::set<int> nfotSet; // to x-check if the number of photons is the same for all particle hypotheses
179 std::set<double> nbkgSet; // to x-check if the background is the same for all particle hypotheses
180
181 for (const auto* pdfConstructor : collection.PDFs) {
182 const auto& chargedStable = pdfConstructor->getHypothesis();
183 auto LL = pdfConstructor->getLogL();
184 auto expBkgPhotons = pdfConstructor->getExpectedBkgPhotons();
185 topLL->set(chargedStable, LL.numPhotons, LL.logL, LL.expPhotons, expBkgPhotons, LL.effectiveSignalYield);
186
187 nfotSet.insert(LL.numPhotons);
188 nbkgSet.insert(expBkgPhotons);
189
190 if (abs(chargedStable.getPDGCode()) == abs(pdgCode)) {
191 for (const auto& p : pdfConstructor->getPulls()) {
192 const auto* pull = m_topPulls.appendNew(p.pixelID, p.time, p.peakT0 + p.ttsT0, p.sigma, p.phiCer, p.wt);
193 track->addRelationTo(pull);
194 }
195 }
196 }
197 topLL->setFlag(1);
198 topLL->setModuleID(trk->getModuleID());
199 const auto& emi = trk->getEmissionPoint();
200 topLL->setXZ(emi.position.X(), emi.position.Z());
201
202 if (nfotSet.size() > 1) B2ERROR("Bug in TOP::PDFConstructor: number of photons differs between particle hypotheses");
203 if (nbkgSet.size() > 1) B2ERROR("Bug in TOP::PDFConstructor: estimated background differs between particle hypotheses");
204 }
205
206 for (auto& collection : pdfCollections) collection.deletePDFs();
207
208 } // loop: moduleID
209
210 for (const auto& x : topTracks) delete x.second;
211
212 }

◆ event() [25/30]

void event ( void )
overridevirtual

Event processor.

Reimplemented from Module.

Definition at line 139 of file TOPTimeBaseCalibratorModule.cc.

140 {
141 const auto* geo = TOPGeometryPar::Instance()->getGeometry();
142 double sampleWidth = geo->getNominalTDC().getSampleWidth();
143
144 vector<Hit> hits[c_NumChannels];
145
146 for (const auto& digit : m_digits) {
147 if (digit.getModuleID() != m_moduleID) continue;
148 if (digit.getHitQuality() != TOPDigit::c_Junk) {
149 m_goodHits.Fill(digit.getPulseWidth(), digit.getPulseHeight());
150 }
151 if (digit.getHitQuality() != TOPDigit::c_CalPulse) continue;
152 double rawTime = digit.getRawTime();
153 double errScaleFactor = 1;
154 if (m_useFallingEdge) {
155 const auto* rawDigit = digit.getRelated<TOPRawDigit>();
156 if (!rawDigit) {
157 B2ERROR("No relation to TOPRawDigit - can't determine falling edge time error");
158 continue;
159 }
160 // rawTime may include corrections due to window number discontinuity,
161 // therefore one must add the width and not just use getCFDFallingTime()
162 rawTime += rawDigit->getFWHM();
163 errScaleFactor = rawDigit->getCFDFallingTimeError(1.0) / rawDigit->getCFDLeadingTimeError(1.0);
164 }
165 double t = rawTime + digit.getFirstWindow() * c_WindowSize;
166 if (t < 0) {
167 B2ERROR("Got negative sample number - digit ignored");
168 continue;
169 }
170 double et = digit.getTimeError() / sampleWidth * errScaleFactor;
171 if (et <= 0) {
172 B2ERROR("Time error is not given - digit ignored");
173 continue;
174 }
175 unsigned channel = digit.getChannel();
176 if (channel < c_NumChannels) {
177 hits[channel].push_back(Hit(t, et, digit.getPulseHeight(), digit.getPulseWidth()));
178 }
179 }
180
181 for (unsigned channel = 0; channel < c_NumChannels; channel++) {
182 const auto& channelHits = hits[channel];
183 if (channelHits.size() == 2) {
184 double t0 = channelHits[0].time;
185 double t1 = channelHits[1].time;
186 auto diff = fabs(t0 - t1); // since not sorted yet
187 if (diff < m_minTimeDiff) continue;
188 if (diff > m_maxTimeDiff) continue;
189 double sig0 = channelHits[0].timeErr;
190 double sig1 = channelHits[1].timeErr;
191 double sigma = sqrt(sig0 * sig0 + sig1 * sig1);
192 m_ntuples[channel].push_back(TwoTimes(t0, t1, sigma));
193 if (t0 < t1) { // check, since not sorted yet
194 m_calPulseFirst.Fill(channelHits[0].pulseWidth, channelHits[0].pulseHeight);
195 m_calPulseSecond.Fill(channelHits[1].pulseWidth, channelHits[1].pulseHeight);
196 } else {
197 m_calPulseSecond.Fill(channelHits[0].pulseWidth, channelHits[0].pulseHeight);
198 m_calPulseFirst.Fill(channelHits[1].pulseWidth, channelHits[1].pulseHeight);
199 }
200 } else if (channelHits.size() > 2) {
201 B2WARNING("More than two cal pulses per channel found - ignored");
202 }
203 }
204
205 }

◆ event() [26/30]

void event ( void )
overridevirtual

Event processor.

Reimplemented from Module.

Definition at line 143 of file TOPTimeRecalibratorModule.cc.

144 {
145 int revo9cnt = m_recBunch->getRevo9Counter();
146 double SSTfrac = (revo9cnt % 6) / 6.0;
147 double offset = m_feSetting->getOffset() / 24.0;
148 double timeOffset = (SSTfrac + offset) * m_syncTimeBase; // in [ns], to be subtracted
149 const auto& feMapper = TOPGeometryPar::Instance()->getFrontEndMapper();
150 const auto* geo = TOPGeometryPar::Instance()->getGeometry();
151
152 for (auto& digit : m_digits) {
153
154 // save MC offset status
155 bool offsetStatus = digit.hasStatus(TOPDigit::c_OffsetSubtracted);
156
157 // reset status bits
158 unsigned short statusBits = 0;
159 digit.setStatus(statusBits);
160
161 // get what's needed from a digit
162 double rawTimeLeading = digit.getRawTime();
163 auto window = digit.getFirstWindow();
164 auto moduleID = digit.getModuleID();
165 auto channel = digit.getChannel();
166
167 // convert raw time to time using equidistant or calibrated time base
168 const auto* sampleTimes = &m_sampleTimes; // equidistant sample times
169 if (m_useSampleTimeCalibration) {
170 auto bs = channel / 128;
171 const auto* feemap = feMapper.getMap(moduleID, bs);
172 if (not feemap) {
173 B2ERROR("No front-end map available."
174 << LogVar("slot", moduleID)
175 << LogVar("boardstack", bs));
176 continue;
177 }
178 auto scrodID = feemap->getScrodID();
179 sampleTimes = m_timebase->getSampleTimes(scrodID, channel % 128);
180 if (sampleTimes->isCalibrated()) {
181 statusBits |= TOPDigit::c_TimeBaseCalibrated;
182 }
183 }
184 double time = sampleTimes->getTime(window, rawTimeLeading) - timeOffset;
185
186 // apply other calibrations
187 if (m_useTimeWalkCalibration and m_timeWalk.isValid()) {
188 if (m_timeWalk->isCalibrated()) {
189 time -= m_timeWalk->getTimeWalk(digit.getPulseHeight());
190 }
191 }
192 if (m_useChannelT0Calibration) {
193 const auto& cal = m_channelT0;
194 if (cal->isCalibrated(moduleID, channel)) {
195 time -= cal->getT0(moduleID, channel);
196 statusBits |= TOPDigit::c_ChannelT0Calibrated;
197 }
198 }
199 if (m_useAsicShiftCalibration) {
200 auto asic = channel / 8;
201 if (m_asicShift->isCalibrated(moduleID, asic)) {
202 time -= m_asicShift->getT0(moduleID, asic);
203 }
204 }
205 if (m_useModuleT0Calibration) {
206 const auto& cal = m_moduleT0;
207 if (cal->isCalibrated(moduleID)) {
208 time -= cal->getT0(moduleID);
209 statusBits |= TOPDigit::c_ModuleT0Calibrated;
210 }
211 }
212 if (m_useCommonT0Calibration) {
213 const auto& cal = m_commonT0;
214 if (cal->isCalibrated()) {
215 time -= cal->getT0();
216 statusBits |= TOPDigit::c_CommonT0Calibrated;
217 }
218 }
219
220 // subtract bunch time
221 if (m_subtractBunchTime and m_recBunch->isReconstructed()) {
222 time -= m_recBunch->getTime();
223 statusBits |= TOPDigit::c_EventT0Subtracted;
224 }
225
226 // subtract offset used in MC if status bit was set in this digit
227 if (offsetStatus) {
228 time -= geo->getNominalTDC().getOffset();
229 statusBits |= TOPDigit::c_OffsetSubtracted;
230 }
231
232 // set re-calibrated time and status bits
233 digit.setTime(time);
234 digit.setStatus(statusBits);
235 }
236
237 }

◆ event() [27/30]

void event ( void )
overridevirtual

Event processor.

Reimplemented from Module.

Definition at line 82 of file TOPTriggerDigitizerModule.cc.

83 {
84
85 // input: simulated waveforms
86 StoreArray<TOPRawWaveform> waveforms;
87
88 // output: time stamps for trigger input
89 StoreArray<TOPTriggerDigit> digits;
90 StoreObjPtr<TOPTriggerMCInfo> mcInfo;
91 mcInfo.create();
92
93 if (waveforms.getEntries() == 0) {
94 B2ERROR("No waveforms available for digitization");
95 return;
96 }
97 unsigned revo9count = waveforms[0]->getRevo9Counter();
98 int offsetSamples = waveforms[0]->getOffsetWindows() * TOPRawWaveform::c_WindowSize +
99 (revo9count % 6) * TOPRawWaveform::c_WindowSize / 3;
100
101 int bunchTimeStamp = int((revo9count + gRandom->Rndm()) * static_cast<double>(c_SamplingCycle) / 3.0);
102 mcInfo->setBunchTimeStamp(bunchTimeStamp);
103
104 int offset = bunchTimeStamp - offsetSamples / c_SamplingCycle;
105
106 for (const auto& waveform : waveforms) {
107 const auto& data = waveform.getWaveform();
108 int currentThr = m_threshold;
109 bool lastState = false;
110 int gate = 0;
111 TOPTriggerDigit* digit = 0;
112 for (int i = 0; i < (int) data.size(); i++) {
113 gate--;
114 if (data[i] > currentThr) {
115 currentThr = m_threshold - m_hysteresis;
116 if (!lastState) gate = m_gateWidth;
117 lastState = true;
118 } else {
119 currentThr = m_threshold;
120 lastState = false;
121 }
122 if (i % c_SamplingCycle == m_samplingPhase and gate > 0) {
123 if (i / c_SamplingCycle == 0) continue; // first time stamp is not correct
124 if (!digit) {
125 digit = digits.appendNew(waveform.getModuleID(),
126 waveform.getChannel(),
127 waveform.getScrodID());
128 digit->addRelationTo(&waveform);
129 }
130 int timeStamp = i / c_SamplingCycle + offset;
131 while (timeStamp < 0) {timeStamp += c_Frame9Period;};
132 timeStamp = timeStamp % c_Frame9Period;
133 digit->appendTimeStamp(timeStamp);
134 }
135 }
136 }
137
138 }

◆ event() [28/30]

void event ( void )
overridevirtual

Event processor.

Reimplemented from Module.

Definition at line 115 of file TOPUnpackerModule.cc.

116 {
117 if (m_resetEventCount) {
118 m_numErrors = m_errorCount;
119 m_errorCount = 0;
120 m_eventCount = 0;
121 m_resetEventCount = false;
122 }
123 m_eventCount++;
124
125 // clear output store arrays
126 m_digits.clear();
127 m_rawDigits.clear();
128 m_waveforms.clear();
129 m_productionEventDebugs.clear();
130 m_productionHitDebugs.clear();
131 m_templateFitResults.clear();
132 m_slowData.clear();
133 m_interimFEInfos.clear();
134
135 // create injection veto object
136 m_injectionVeto.create();
137
138 StoreObjPtr<EventMetaData> evtMetaData;
139 for (auto& raw : m_rawData) {
140 for (int finesse = 0; finesse < raw.GetMaxNumOfCh(0); finesse++) {
141 const int* buffer = raw.GetDetectorBuffer(0, finesse);
142 int bufferSize = raw.GetDetectorNwords(0, finesse);
143 if (bufferSize < 1) continue;
144
145 int err = 0;
146 m_swapBytes = m_swapBytesDefault;
147 int dataFormat = m_dataFormat;
148 if (dataFormat == 0) { // auto detect data format
149 DataArray array(buffer, bufferSize, m_swapBytes);
150 unsigned word = array.getWord();
151 dataFormat = (word >> 16);
152 bool isKnownDataFormat = false;
153 for (auto& t : TOP::membersRawDataType) {
154 if (static_cast<int>(t) == dataFormat) {
155 isKnownDataFormat = true;
156 break;
157 }
158 }
159
160 if (!isKnownDataFormat) { //dataformat word is not recognised, might be interim format.
161 if (evtMetaData->getExperiment() == 1) { // all exp.1 data was taken with interim format
162 dataFormat = 0x0301;
163 m_swapBytes = true;
164 } else {
165 if (unpackHeadersInterimFEVer01(buffer, bufferSize, true)) { //if buffer unpacks without errors assuming it's interim format
166 B2DEBUG(22, "Assuming interim FW data format");
167 dataFormat = 0x0301; //assume it's interim format
168 m_swapBytes = true;
169 } else {
170 B2DEBUG(22, "TOPUnpacker: Could not establish data format.");
171 }
172 }
173 }
174 }
175
176 switch (dataFormat) {
177 case static_cast<int>(TOP::RawDataType::c_Type0Ver16):
178 unpackType0Ver16(buffer, bufferSize);
179 break;
180 case static_cast<int>(TOP::RawDataType::c_Type2Ver1):
181 err = unpackInterimFEVer01(buffer, bufferSize, false);
182 break;
183 case static_cast<int>(TOP::RawDataType::c_Type3Ver1):
184 err = unpackInterimFEVer01(buffer, bufferSize, true);
185 break;
186 case static_cast<int>(TOP::RawDataType::c_Draft):
187 unpackProductionDraft(buffer, bufferSize);
188 break;
189 case static_cast<int>(TOP::RawDataType::c_ProductionDebug01):
190 err = unpackProdDebug(buffer, bufferSize, TOP::RawDataType::c_ProductionDebug01, true, evtMetaData->getExperiment());
191 break;
192 case static_cast<int>(TOP::RawDataType::c_ProductionDebug02):
193 err = unpackProdDebug(buffer, bufferSize, TOP::RawDataType::c_ProductionDebug02, true, evtMetaData->getExperiment());
194 break;
195
196 default:
197 if (printTheError()) {
198 auto boardstackName = getFrontEndName(raw, finesse);
199 B2ERROR("TOPUnpacker: unknown data format from " << boardstackName
200 << LogVar("Type", (dataFormat >> 8))
201 << LogVar("Version", (dataFormat & 0xFF))
202 << LogVar("Buffer size", bufferSize));
203 }
204 continue;
205 }
206
207 if (err != 0) {
208 if (printTheError()) {
209 auto boardstackName = getFrontEndName(raw, finesse);
210 B2ERROR("TOPUnpacker: error in unpacking data from " << boardstackName
211 << LogVar("words unused", err));
212 }
213 }
214
215 } // finesse loop
216 } // m_rawData loop
217
218 }

◆ event() [29/30]

void event ( void )
overridevirtual

Event processor.

Reimplemented from Module.

Definition at line 74 of file TOPWaveformFeatureExtractorModule.cc.

75 {
76
77 const auto* geo = TOPGeometryPar::Instance()->getGeometry();
78 const auto& tdc = geo->getNominalTDC();
79 int sampleDivisions = 0x1 << tdc.getSubBits();
80
81 StoreArray<TOPRawDigit> rawDigits(m_inputRawDigitsName);
82 int initSize = rawDigits.getEntries();
83
84 for (int i = 0; i < initSize; i++) {
85 auto& rawDigit = *rawDigits[i];
86 const auto* waveform = rawDigit.getRelated<TOPRawWaveform>();
87 if (!waveform) continue;
88 if (m_setIntegral) {
89 auto integral = waveform->getIntegral(rawDigit.getSampleRise(),
90 rawDigit.getSamplePeak(),
91 rawDigit.getSampleFall());
92 rawDigit.setIntegral(integral);
93 }
94 waveform->featureExtraction(m_threshold, m_hysteresis, m_thresholdCount);
95 const auto& features = waveform->getFeatureExtractionData();
96 int sampleRise = rawDigit.getSampleRise();
97 int sampleFall = rawDigit.getSampleFall() + 1;
98 for (const auto& feature : features) {
99
100 // skip it, if hit already in rawDigits
101 int sRise = feature.sampleRise;
102 if (sRise >= sampleRise and sRise <= sampleFall) continue;
103 int sFall = feature.sampleFall + 1;
104 if (sFall >= sampleRise and sFall <= sampleFall) continue;
105
106 // if not, append it
107 auto* newDigit = rawDigits.appendNew(rawDigit);
108 newDigit->setOfflineFlag();
109 newDigit->setSampleRise(feature.sampleRise);
110 newDigit->setDeltaSamplePeak(feature.samplePeak - feature.sampleRise);
111 newDigit->setDeltaSampleFall(feature.sampleFall - feature.sampleRise);
112 newDigit->setValueRise0(feature.vRise0);
113 newDigit->setValueRise1(feature.vRise1);
114 newDigit->setValueFall0(feature.vFall0);
115 newDigit->setValueFall1(feature.vFall1);
116 newDigit->setValuePeak(feature.vPeak);
117 newDigit->setIntegral(feature.integral);
118 double rawTime = newDigit->getCFDLeadingTime();
119 int tfine = int(rawTime * sampleDivisions) % sampleDivisions;
120 if (tfine < 0) tfine += sampleDivisions;
121 newDigit->setTFine(tfine);
122 newDigit->addRelationTo(waveform);
123 }
124 }
125
126 B2DEBUG(20, "TOPWaveformFeatureExtractor: appended " << rawDigits.getEntries() - initSize
127 << " raw digits to initial " << initSize);
128
129 }

◆ event() [30/30]

void event ( void )
overridevirtual

Event processor.

Reimplemented from HistoModule.

Definition at line 144 of file TOPWaveformQualityPlotterModule.cc.

145 {
146 if (not m_waveform) {
147 return;
148 }
149 for (auto evtwave : m_waveform) {
150 if (m_DRAWWAVES) {
151 drawWaveforms(evtwave);
152 }
153 if (m_DEBUGGING) {
154 basicDebuggingPlots(evtwave);
155 }
156 if (m_NOISE) {
157 auto channelID = evtwave.getChannel();
158 const vector<short> v_samples = evtwave.getWaveform();
159 size_t nsamples = v_samples.size();
160 if (m_channelNoiseMap.find(channelID) == m_channelNoiseMap.end()) {
161 string idName = string("noise_") + to_string(channelID);
162 m_channelNoiseMap.insert(make_pair(channelID, new TH1F(idName.c_str(), idName.c_str(), 200, -100, 100)));
163 m_channelEventMap.insert(make_pair(channelID, m_iEvent));
164 }
165 TH1F* noise = m_channelNoiseMap[channelID];
166 // Plot all samples in common histogram for quick sanity check
167 for (size_t s = 0; s < nsamples; s++) {
168 double adc = v_samples.at(s);
169 m_samples->Fill(adc);
170 if (s < nsamples - 1) {
171 noise->Fill(v_samples[s + 1] - adc);
172 }
173 }
174 }
175 }
176 m_iEvent += 1;
177 return;
178 }

◆ FindPeakForSmallerXThan()

double FindPeakForSmallerXThan ( TH1 * histo,
double xmax = 0 )
static

Find peak and return its position for a limited range of x (x smaller than the given value (xmax))

Definition at line 633 of file TOPGainEfficiencyCalculatorModule.cc.

634 {
635 double histo_xmax = histo->GetXaxis()->GetBinUpEdge(histo->GetXaxis()->GetNbins() - 1);
636 if (xmax > histo_xmax) xmax = histo_xmax;
637
638 int iBin = 1;
639 double peakPos = histo->GetXaxis()->GetBinCenter(iBin);
640 double peakCharge = histo->GetBinContent(iBin);
641 while (true) {
642 iBin++;
643 double x = histo->GetXaxis()->GetBinCenter(iBin);
644 if (x > xmax) break;
645
646 double binEntry = histo->GetBinContent(iBin);
647 if (binEntry > peakCharge) {
648 peakPos = x;
649 peakCharge = binEntry;
650 }
651 }
652
653 return peakPos;
654 }

◆ FitHistograms()

void FitHistograms ( EHistogramType LoadHisto)

Fit charge (or integrated charged) distribution to calculate gain and efficiency for each channel.

Definition at line 261 of file TOPGainEfficiencyCalculatorModule.cc.

262 {
263 float threshold = m_threshold;
264 int globalAsicId = 0;
265 if (LoadHisto == c_LoadForFitIntegral || LoadHisto == c_LoadHitRateIntegral) threshold = m_thresholdForIntegral;
266
267 for (int iHisto = 0 ; iHisto < c_NChannelPerPMT ; iHisto++) {
268 if (m_targetPmtChId != -1 && iHisto + 1 != m_targetPmtChId) continue;
269
270 m_pixelId = ((m_targetPmtId - 1) % c_NPMTPerRow) * c_NChannelPerPMTRow
271 + ((m_targetPmtId - 1) / c_NPMTPerRow) * c_NPixelPerModule / 2
272 + (iHisto / c_NChannelPerPMTRow) * c_NPixelPerRow + (iHisto % c_NChannelPerPMTRow) + 1;
273 m_pmtChId = (iHisto + 1);
274 globalAsicId = ((m_targetSlotId - 1) * c_NPixelPerModule + (m_pixelId - 1)) / c_NChannelPerAsic;
275 if (LoadHisto == c_LoadForFitHeight) {
276 for (auto itr = m_branch[0].begin(); itr != m_branch[0].end(); ++itr) {
277 (*itr)->Fill();
278 }
279 }
280
281 TH1D* hCharge = m_chargeHistogram[iHisto];
282 if (!hCharge) { DummyFillBranch(LoadHisto); continue;}
283
284 std::cout << " ***** fitting charge distribution for " << hCharge->GetName() << " *****" << std::endl;
285 int nBins = hCharge->GetXaxis()->GetNbins();
286 double binWidth = hCharge->GetXaxis()->GetBinUpEdge(1) - hCharge->GetXaxis()->GetBinLowEdge(1);
287 double histoMax = hCharge->GetXaxis()->GetBinUpEdge(nBins);
288 m_fitMax = threshold;
289 double wholeIntegral = hCharge->Integral(0, hCharge->GetXaxis()->GetNbins() + 1);
290 double fitRangeFraction = (m_fracFit > 0 ? m_fracFit : 1. - 10. / wholeIntegral);
291 while (hCharge->Integral(0, hCharge->GetXaxis()->FindBin(m_fitMax - 0.01 * binWidth)) / wholeIntegral < fitRangeFraction)
292 m_fitMax += binWidth;
293 if (m_fitMax < threshold + static_cast<double>(c_NParameterGainFit) * binWidth) {
294 B2WARNING("TOPGainEfficiencyCalculator : no enough entries for fitting at slot"
295 << std::setw(2) << std::setfill('0') << m_targetSlotId << ", PMT"
296 << std::setw(2) << std::setfill('0') << m_targetPmtId << ", Ch"
297 << std::setw(2) << std::setfill('0') << m_pmtChId);
298 DummyFillBranch(LoadHisto); continue;
299 }
300
301 std::ostringstream fname;
302 fname << "func_" << (iHisto + 1);
303 TObject* object = gROOT->FindObject(fname.str().c_str());
304 if (object) delete object;
305 TF1* func = new TF1(fname.str().c_str(), TOPGainFunc, threshold, m_fitMax, c_NParameterGainFit);
306 double initGain = TMath::Max(hCharge->GetMean(), 26.1) - 25;
307 double initP1 = TMath::Min(4.0, TMath::Max(10000.*TMath::Power(initGain - 25, -2), 0.01));
308 double initP2 = TMath::Min(0.8 + 0.005 * TMath::Power(initP1, -3), 4.);
309 double initX0 = TMath::Max(initGain * 2 - 150, 10.);
310 //if (initP1 > initP2) initX0 = initX0 / 10.
311 double initP1overP2 = initP1 / initP2;
312 double initP0 = hCharge->GetBinContent(hCharge->GetMaximumBin())
313 / (TMath::Power(initP1overP2, initP1overP2) * TMath::Exp(-initP1overP2)) / binWidth;
314 if (m_initialX0 < 0)func->SetParameter(3, initX0);
315 else if (LoadHisto == c_LoadForFitHeight)
316 func->SetParameter(3, 150 + 0.5 * hCharge->GetMean());
317 else if (LoadHisto == c_LoadForFitIntegral)
318 func->SetParameter(3, 1000 + 0.5 * hCharge->GetMean());
319 if (m_initialP2 < 0)func->SetParameter(2, initP2);
320 else func->SetParameter(2, m_initialP2);
321 if (m_initialP1 < 0)func->SetParameter(1, initP1);
322 else func->SetParameter(1, m_initialP1);
323 if (m_initialP0 < 0)func->SetParameter(0, initP0);
324 else func->SetParameter(0, m_initialP0 * hCharge->GetEntries()*binWidth);
325
326 func->FixParameter(4, 0);
327 func->FixParameter(5, m_pedestalSigma);
328 func->SetParName(0, "#it{p}_{0}");
329 func->SetParName(1, "#it{p}_{1}");
330 func->SetParName(2, "#it{p}_{2}");
331 func->SetParName(3, "#it{x}_{0}");
332 func->SetParName(4, "pedestal");
333 func->SetParName(5, "pedestal #sigma");
334 func->SetParLimits(0, 1e-8, 1e8);
335 func->SetParLimits(1, 1e-8, 10);
336 func->SetParLimits(2, 1e-8, 10);
337 func->SetParLimits(3, 1e-8, 1e8);
338 func->SetLineColor(2);
339 func->SetLineWidth(1);
340 TF1* funcFull = NULL;
341 if (LoadHisto == c_LoadForFitHeight or LoadHisto == c_LoadForFitIntegral) {
342 hCharge->Fit(func, m_fitoption.c_str(), "", threshold, m_fitMax);
343
344 if (func->GetNDF() < 2) { DummyFillBranch(LoadHisto); continue;}
345
346 double funcFullMax = histoMax * 2;
347 funcFull = new TF1((fname.str() + "_full").c_str(), TOPGainFunc, (-1)*func->GetParameter(5), funcFullMax, c_NParameterGainFit);
348 for (int iPar = 0 ; iPar < c_NParameterGainFit ; iPar++)
349 funcFull->SetParameter(iPar, func->GetParameter(iPar));
350 funcFull->SetLineColor(3);
351 funcFull->SetLineWidth(2);
352
353 double totalWeight = 0;
354 double weightedIntegral = 0;
355 double x = (-1) * func->GetParameter(5);
356 while (x < funcFullMax) {
357 double funcVal = funcFull->Eval(x);
358 totalWeight += funcVal;
359 weightedIntegral += funcVal * x;
360 x += binWidth / 5.;
361 }
362
363 //fill results to the output TTree
364 m_gain = weightedIntegral / totalWeight;
365 m_efficiency = funcFull->Integral(threshold, funcFullMax) / funcFull->Integral((-1) * func->GetParameter(5), funcFullMax);
366 m_p0 = func->GetParameter(0);
367 m_p1 = func->GetParameter(1);
368 m_p2 = func->GetParameter(2);
369 m_x0 = func->GetParameter(3);
370 m_p0Error = func->GetParError(0);
371 m_p1Error = func->GetParError(1);
372 m_p2Error = func->GetParError(2);
373 m_x0Error = func->GetParError(3);
374 m_chisquare = func->GetChisquare();
375 m_ndf = func->GetNDF();
376 m_funcFullRangeIntegral = funcFull->Integral((-1) * func->GetParameter(5), funcFullMax) / binWidth;
377 m_funcFitRangeIntegral = funcFull->Integral(threshold, m_fitMax) / binWidth;
378 } else std::cout << "*****fitting is skipped***** " << std::endl;
379 int threBin = hCharge->GetXaxis()->FindBin(threshold + 0.01 * binWidth);
380 int fitMaxBin = hCharge->GetXaxis()->FindBin(m_fitMax - 0.01 * binWidth);
381 m_histoFitRangeIntegral = hCharge->Integral(threBin, fitMaxBin);
382
383 m_histoMeanAboveThre = 0;
384 for (int iBin = threBin ; iBin < nBins + 1 ; iBin++) {
385 m_histoMeanAboveThre += (hCharge->GetBinContent(iBin) * hCharge->GetXaxis()->GetBinCenter(iBin));
386 }
387 m_histoMeanAboveThre /= hCharge->Integral(threBin, nBins);
388 m_nEntries = hCharge->GetEntries();
389 m_nCalPulse = (m_nCalPulseHistogram ? m_nCalPulseHistogram->GetBinContent(globalAsicId + 1) : -1);
390 m_nOverflowEvents = TMath::FloorNint(hCharge->GetBinContent(nBins + 1));
391 m_meanPulseHeight = hCharge->GetMean();
392 m_meanPulseHeightError = hCharge->GetMeanError();
393 m_hitTiming = 0;
394 m_hitTimingSigma = -1;
395
396 TF1* funcLaser = m_funcForLaser[iHisto];
397 if (m_timeHistogram[iHisto] && funcLaser) {
398 m_hitTiming = funcLaser->GetParameter(1);
399 m_hitTimingSigma = funcLaser->GetParameter(2);
400 }
401
402 m_funcForFitRange[iHisto] = func;
403 m_funcForFullRange[iHisto] = funcFull;
404
405 for (auto itr = m_branch[LoadHisto].begin(); itr != m_branch[LoadHisto].end(); ++itr) {
406 (*itr)->Fill();
407 }
408
409 std::cout << std::endl;
410 }
411 if (m_targetPmtChId == -1) m_tree->SetEntries(c_NChannelPerPMT);
412 else m_tree->SetEntries(1);
413
414 return;
415 }

◆ generatePulseHeight()

double generatePulseHeight ( int moduleID,
int pixelID ) const
private

Generates and returns pulse height.

Parameters
moduleIDmodule ID (1-based)
pixelIDpixel ID (1-based)
Returns
pulse height [ADC counts]

Definition at line 536 of file TOPDigitizerModule.cc.

537 {
538 if (m_useDatabase) {
539 const auto& channelMapper = TOPGeometryPar::Instance()->getChannelMapper();
540 auto channel = channelMapper.getChannel(pixelID);
541 if (m_pulseHeights->isCalibrated(moduleID, channel)) {
542 const auto& par = m_pulseHeights->getParameters(moduleID, channel);
543 PulseHeightGenerator generator(par.x0, par.p1, par.p2, m_ADCmax);
544 return generator.generate();
545 }
546 }
547
548 return m_pulseHeightGenerator.generate();
549 }

◆ getDirectionCustom()

XYZVector getDirectionCustom ( ) const
private

Return photon direction according to a custom angular distribution given by TFormula.

Returns
photon direction (unit vector)

Definition at line 264 of file OpticalGunModule.cc.

265 {
266 double alpha = m_customDistribution.GetRandom();
267 double phi = 2.0 * M_PI * gRandom->Rndm();
268 return XYZVector(cos(phi) * sin(alpha), sin(phi) * sin(alpha), cos(alpha));
269 }

◆ getDirectionGaussian()

XYZVector getDirectionGaussian ( ) const
private

Return photon direction according to a projected 2D gaussian distribution based on numerical aperture NA.

Returns
photon direction (unit vector)

Definition at line 232 of file OpticalGunModule.cc.

233 {
234 // NA is defined as the aperture where the amplitude is 5% of that of the
235 // peak, which translates into 2.45 sigma for a gaussian distribution
236 double x = 0;
237 double y = 0;
238 double z = 0;
239 do {
240 x = gRandom->Gaus(0., asin(m_na) / 2.45);
241 y = gRandom->Gaus(0., asin(m_na) / 2.45);
242 z = 1. - x * x - y * y;
243 } while (z < 0);
244 return XYZVector(x, y, sqrt(z));
245 }

◆ getDirectionLambertian()

XYZVector getDirectionLambertian ( ) const
private

Return photon direction according to a lambertian distribution with opening angle alpha.

Returns
photon direction (unit vector)

Definition at line 255 of file OpticalGunModule.cc.

256 {
257 double cosTheta = sqrt((m_cosMinAlpha * m_cosMinAlpha - m_cosMaxAlpha * m_cosMaxAlpha) * gRandom->Rndm() +
258 m_cosMaxAlpha * m_cosMaxAlpha);
259 double sinTheta = sqrt(1.0 - cosTheta * cosTheta);
260 double phi = 2.0 * M_PI * gRandom->Rndm();
261 return XYZVector(cos(phi) * sinTheta, sin(phi) * sinTheta, cosTheta);
262 }

◆ getDirectionUniform()

XYZVector getDirectionUniform ( ) const
private

Return photon direction according to a projected uniform distribution with opening angle alpha.

Be careful.

Returns
photon direction (unit vector)

Definition at line 247 of file OpticalGunModule.cc.

248 {
249 double cosTheta = (m_cosMinAlpha - m_cosMaxAlpha) * gRandom->Rndm() + m_cosMaxAlpha;
250 double sinTheta = sqrt(1.0 - cosTheta * cosTheta);
251 double phi = 2.0 * M_PI * gRandom->Rndm();
252 return XYZVector(cos(phi) * sinTheta, sin(phi) * sinTheta, cosTheta);
253 }

◆ getFrontEndName()

std::string getFrontEndName ( RawTOP & raw,
int finesse )
staticprivate

Returns the name of the front-end.

Parameters
rawraw data
finessefinesse number
Returns
front-end name

Definition at line 221 of file TOPUnpackerModule.cc.

222 {
223 std::string name;
224 if (raw.GetMaxNumOfCh(0) <= 4) { // COPPER
225 int copper = ((raw.GetNodeID(0) >> 24) * 1000 + (raw.GetNodeID(0) & 0x3FF));
226 name = "frontend cpr" + std::to_string(copper) + char('a' + finesse);
227 } else { // PCIe40
228 int slot = (raw.GetNodeID(0) & 0xF) * 8 - 7 + finesse / 4;
229 name = (slot < 10) ? "boardstack s0" : "boardstack s";
230 name += std::to_string(slot) + char('a' + finesse % 4);
231 }
232 return name;
233 }

◆ getModuleID()

int getModuleID ( const Track & track) const
private

Returns slot ID of the module that is hit by the track.

Parameters
trackcharged track
Returns
slotID or 0 if track does not hit any module

Definition at line 560 of file TOPDQMModule.cc.

561 {
562 Const::EDetector myDetID = Const::EDetector::TOP;
563 int pdgCode = std::abs(Const::pion.getPDGCode());
564
565 RelationVector<ExtHit> extHits = track.getRelationsWith<ExtHit>();
566 for (const auto& extHit : extHits) {
567 if (std::abs(extHit.getPdgCode()) != pdgCode) continue;
568 if (extHit.getDetectorID() != myDetID) continue;
569 if (extHit.getCopyID() < 1 or extHit.getCopyID() > m_numModules) continue;
570 return extHit.getCopyID();
571 }
572
573 return 0;
574 }

◆ getMostProbable()

Const::ChargedStable getMostProbable ( const Track & track)
private

Returns most probable charged stable particle according to dEdx and predefined prior probabilities.

Parameters
trackreconstructed track
Returns
charged stable

Definition at line 564 of file TOPBunchFinderModule.cc.

565 {
566
567 std::vector<double> logL;
568 std::vector<double> priors;
569
570 if (m_usePIDLikelihoods) {
571 const auto* pid = track.getRelated<PIDLikelihood>();
572 if (not pid) {
573 m_nodEdxCount++;
574 return Const::pion;
575 }
576 auto subset = Const::PIDDetectorSet(Const::SVD);
577 subset += Const::PIDDetectorSet(Const::CDC);
578 for (const auto& type : Const::chargedStableSet) {
579 logL.push_back(pid->getLogL(type, subset));
580 priors.push_back(m_priors[abs(type.getPDGCode())]);
581 }
582 } else {
583 const auto* cdcdedx = track.getRelated<CDCDedxLikelihood>();
584 const auto* vxddedx = track.getRelated<VXDDedxLikelihood>();
585 if (not cdcdedx and not vxddedx) {
586 m_nodEdxCount++;
587 return Const::pion;
588 }
589 for (const auto& type : Const::chargedStableSet) {
590 if (cdcdedx and vxddedx) {
591 logL.push_back(cdcdedx->getLogL(type) + vxddedx->getLogL(type));
592 } else if (cdcdedx) {
593 logL.push_back(cdcdedx->getLogL(type));
594 } else {
595 logL.push_back(vxddedx->getLogL(type));
596 }
597 priors.push_back(m_priors[abs(type.getPDGCode())]);
598 }
599 }
600
601 // get maximal logL
602 auto logL_max = logL[0];
603 for (auto x : logL) {
604 if (x > logL_max) logL_max = x;
605 }
606
607 // calculate probabilities, normalizaton is not needed
608 std::vector<double> probability(logL.size());
609 for (unsigned i = 0; i < logL.size(); ++i) {
610 probability[i] = exp(logL[i] - logL_max) * priors[i];
611 }
612
613 // find most probable
614 unsigned i0 = 0;
615 for (unsigned i = 0; i < probability.size(); ++i) {
616 if (probability[i] > probability[i0]) i0 = i;
617 }
618 return Const::chargedStableSet.at(i0);
619
620 }
std::bitset< max - min+1 > subset(std::bitset< nbits > set)
extract a subset of bitstring, like substring.
Definition Cosim.h:120

◆ getReferenceTiming()

void getReferenceTiming ( )
private

Find reference timing.

In case that the waveform analysis is enabled, try to find a pair of calibration pulses and timing of the first one is used as reference timing for the corresponding asic. If not enabled, feature extracted timing for a calibration channel is used.

Definition at line 326 of file TOPInterimFENtupleModule.cc.

327 {
328 static short globalRefAsic = m_globalRefAsicNum + 100 * m_globalRefSlotNum;
329 m_globalRefTime = -99999;
330 std::map<short, short> iRefHitMap;
331 for (int iHit = 0 ; iHit < m_nHit ; iHit++) {
332 if (!m_isCalCh[iHit]) continue;
333 short reducedPixelId = (m_pixelId[iHit] - 1) / 8 + 100 * m_slotNum[iHit];
334 if (iRefHitMap.count(reducedPixelId) > 0) continue;
335
336 if (!m_useDoublePulse) {
337 iRefHitMap[reducedPixelId] = iHit;
338 continue;
339 }
340
341 std::vector<short> iHitVec;
342 iHitVec.push_back(iHit);
343 for (int jHit = iHit + 1 ; jHit < m_nHit ; jHit++) {
344 short jReducedPixelId = (m_pixelId[jHit] - 1) / 8 + 100 * m_slotNum[jHit];
345 if (m_isCalCh[jHit] && jReducedPixelId == reducedPixelId) iHitVec.push_back(jHit);
346 }
347
348 int nCands = 0;
349 for (unsigned int iVec = 0 ; iVec < iHitVec.size() ; iVec++) {
350 int jHit = iHitVec[iVec];
351 for (unsigned int jVec = iVec + 1 ; jVec < iHitVec.size() ; jVec++) {
352 int kHit = iHitVec[jVec];
353 float timediff = m_time[kHit] - m_time[jHit];
354 if (m_height[jHit] > m_calibrationPulseThreshold1
355 && m_height[kHit] > m_calibrationPulseThreshold2
356 && TMath::Abs(timediff - m_calibrationPulseInterval) < m_calibrationPulseIntervalRange) {
357 if (nCands == 0) {
358 iRefHitMap[reducedPixelId] = jHit;
359 m_hitQuality[jHit] += 100;
360 m_hitQuality[kHit] += 200;
361 }
362 nCands++;
363 }
364 //in case jHit and kHit are not in time order (added at 28th Nov)
365 else if (timediff < 0 && m_height[kHit] > m_calibrationPulseThreshold1
366 && m_height[jHit] > m_calibrationPulseThreshold2
367 && TMath::Abs(timediff + m_calibrationPulseInterval) < m_calibrationPulseIntervalRange) {
368 if (nCands == 0) {
369 iRefHitMap[reducedPixelId] = kHit;
370 m_hitQuality[kHit] += 100;
371 m_hitQuality[jHit] += 200;
372 }
373 nCands++;
374 }//satisfy selection criteria for calibration signal
375 }
376 }//iVec (finish selecting a calibration signal candidate)
377 }
378
379
380 //loop all hits again to fill the array "refTime"
381 for (int iHit = 0 ; iHit < m_nHit ; iHit++) {
382 short reducedPixelId = (m_pixelId[iHit] - 1) / 8 + 100 * m_slotNum[iHit];
383 if (iRefHitMap.count(reducedPixelId) > 0) {
384 int iRef = iRefHitMap[reducedPixelId];
385 m_refTime[iHit] = m_time[iRef];
386 if (reducedPixelId == globalRefAsic) m_globalRefTime = m_time[iRef];
387 if (!m_isReallyJunk[iHit] && m_hitQuality[iRef] >= 100) {
388 m_hitQuality[iHit] += 10;
389 }
390 } else m_refTime[iHit] = -99999;
391 }
392
393 return;
394 }

◆ getTimeOffset()

TOPDigitizerModule::TimeOffset getTimeOffset ( double trgOffset,
int moduleID,
int pixelID,
bool generate = false )
private

Returns a complete time offset by adding time mis-calibration to trgOffset.

Parameters
trgOffsettrigger related time offset
moduleIDslot ID
pixelIDpixel ID
generateif true, generate additional time spread according to calibration systematics
Returns
time offset and its error squared

Definition at line 499 of file TOPDigitizerModule.cc.

500 {
501 double timeOffset = trgOffset;
502 double calErrorSq = 0;
503 int winShift = 0;
504 double timeShift = 0;
505 if (m_useDatabase) {
506 const auto& channelMapper = TOPGeometryPar::Instance()->getChannelMapper();
507 auto channel = channelMapper.getChannel(pixelID);
508 if (m_channelT0->isCalibrated(moduleID, channel)) {
509 timeOffset += m_channelT0->getT0(moduleID, channel);
510 double err = m_channelT0->getT0Error(moduleID, channel); // statistics from laser data fit
511 double sys = m_calPrecision->get(moduleID); // systematics from di-muon events (this is dominant)
512 if (generate and sys > 0) timeOffset += gRandom->Gaus(0, sys);
513 calErrorSq += err * err + sys * sys;
514 }
515 auto asic = channel / 8;
516 if (m_asicShift->isCalibrated(moduleID, asic)) {
517 timeOffset += m_asicShift->getT0(moduleID, asic);
518 winShift = lround(m_asicShift->getT0(moduleID, asic) / m_syncTimeBase * 2);
519 timeShift = winShift * m_syncTimeBase / 2;
520 }
521 if (m_moduleT0->isCalibrated(moduleID)) {
522 timeOffset += m_moduleT0->getT0(moduleID);
523 double err = m_moduleT0->getT0Error(moduleID);
524 calErrorSq += err * err;
525 }
526 if (m_commonT0->isCalibrated()) {
527 timeOffset += m_commonT0->getT0();
528 double err = m_commonT0->getT0Error();
529 calErrorSq += err * err;
530 }
531 }
532 return TimeOffset(timeOffset, calErrorSq, winShift, timeShift);
533 }

◆ getTimeSeed()

TOPBunchFinderModule::TimeSeed getTimeSeed ( )
private

Returns a time seed.

Returns
time seed

Definition at line 643 of file TOPBunchFinderModule.cc.

644 {
645 TimeSeed timeSeed; // default time seed; sigma == 0 signals that the seed is not given
646
647 if (m_HLTmode) return timeSeed;
648 if (m_autoRange) return timeSeed;
649 if (not m_useTimeSeed) return timeSeed;
650 if (not m_eventT0Offset.isValid()) return timeSeed;
651
652 for (auto detector : {Const::SVD, Const::CDC}) {
653 if (m_eventT0Offset->isAvailable(detector) and m_eventT0->hasTemporaryEventT0(detector)) {
654 auto eventT0s = m_eventT0->getTemporaryEventT0s(detector);
655 if (eventT0s.empty()) continue;
656 if (detector == Const::CDC and eventT0s.back().algorithm != "chi2") continue;
657 double t0 = eventT0s.back().eventT0;
658 if (std::abs(t0) > m_timeRangeCoarse / 2) continue;
659 timeSeed.t0 = m_isMC ? t0 : t0 - m_eventT0Offset->get(detector).offset;
660 timeSeed.sigma = m_eventT0Offset->get(detector).sigma;
661 timeSeed.detector = detector;
662 break;
663 }
664 }
665
666 return timeSeed;
667 }

◆ initialize() [1/33]

void initialize ( void )
overridevirtual

Initialize the Module.

This method is called at the beginning of data processing.

Reimplemented from Module.

Definition at line 85 of file OpticalGunModule.cc.

86 {
87 // data store objects registration
88 m_MCParticles.registerInDataStore();
89 m_simCalPulses.isOptional();
90
91 // parameters check
92 if (m_wavelength < 150 or m_wavelength > 1000)
93 B2FATAL("Wavelength does not correspond to optical photons.");
94 if (m_na < 0 or m_na > 1)
95 B2FATAL("Numerical aperture must be between 0 and 1.");
96 if (m_minAlpha < 0)
97 B2FATAL("Minimum emission angle must be positive");
98 if (m_maxAlpha < 0)
99 B2FATAL("Maximum emission angle must be positive");
100 if (m_minAlpha >= m_maxAlpha)
101 B2FATAL("Minimum emission angle must me smaller than the maximum emission angle");
102
103 if (m_angularDistribution == string("uniform") or
104 m_angularDistribution == string("Lambertian") or
105 m_angularDistribution == string("Gaussian"))
106 B2INFO("Using the pre-defined angular distribution " << m_angularDistribution);
107 else {
108 B2INFO(m_angularDistribution << " is not a pre-defined distribution. "
109 << "Checking if it's a valid, positively-defined TFormula.");
110 TFormula testFormula("testFormula", m_angularDistribution.c_str());
111 int result = testFormula.Compile();
112 if (result != 0) {
113 B2FATAL(m_angularDistribution << " TFormula does not compile.");
114 }
115 double testPoint = m_minAlpha; // let's test if the function is positive defined everywhere
116 while (testPoint < m_maxAlpha) {
117 double value = testFormula.Eval(testPoint * Unit::deg);
118 if (value < 0) {
119 B2FATAL("The formula " << m_angularDistribution << " is not positively defined at the test point "
120 << testPoint << " deg (value = " << value << ")");
121 }
122 testPoint += (m_maxAlpha - m_minAlpha) / 100.;
123 }
124 m_customDistribution = TF1("m_customDistribution", m_angularDistribution.c_str(), m_minAlpha * Unit::deg,
125 m_maxAlpha * Unit::deg);
126 }
127
128 // set other private variables
129 m_cosMinAlpha = cos(m_minAlpha * Unit::deg);
130 m_cosMaxAlpha = cos(m_maxAlpha * Unit::deg);
131 m_energy = TOPGeometryPar::c_hc / m_wavelength * Unit::eV;
132
133 EulerAngles ea(-m_phi * Unit::deg, -m_theta * Unit::deg, -m_psi * Unit::deg); // rotation of an object as in TRotation
134 m_transform = Transform3D(Rotation3D(ea), Translation3D(m_x, m_y, m_z)); // source positioning and elevation
135 if (m_slotID != 0) {
136 const auto* geo = TOPGeometryPar::Instance()->getGeometry();
137 if (not geo->isModuleIDValid(m_slotID)) B2FATAL("Slot ID is not valid");
138 const auto& T = geo->getModule(m_slotID).getTransformation(); // slot to BelleII
139 m_transform = T * m_transform;
140 }
141
142 }

◆ initialize() [2/33]

void initialize ( void )
overridevirtual

Initialize the Module.

This method is called at the beginning of data processing.

Reimplemented from Module.

Definition at line 87 of file TOPAlignerModule.cc.

88 {
89 // check if target module ID is valid
90
91 const auto* geo = TOPGeometryPar::Instance()->getGeometry();
92 if (not geo->isModuleIDValid(m_targetMid)) {
93 B2ERROR("Target module ID = " << m_targetMid << " is invalid.");
94 }
95
96 // check if sample type is valid
97
98 if (not(m_sample == "dimuon" or m_sample == "bhabha" or m_sample == "cosmics")) {
99 B2ERROR("Invalid sample type '" << m_sample << "'");
100 }
101 if (m_sample == "bhabha") m_chargedStable = Const::electron;
102
103 // set track selector
104
105 m_selector = TrackSelector(m_sample);
106 m_selector.setMinMomentum(m_minMomentum);
107 m_selector.setDeltaEcms(m_deltaEcms);
108 m_selector.setCutOnPOCA(m_dr, m_dz);
109 m_selector.setCutOnLocalZ(m_minZ, m_maxZ);
110
111 // set alignment object
112
113 m_align.setModuleID(m_targetMid);
114 m_align.setSteps(m_stepPosition, m_stepAngle, m_stepTime);
115 m_align.setParameters(m_parInit);
116 for (const auto& parName : m_parFixed) {
117 m_align.fixParameter(parName);
118 }
119
120 // input
121
122 m_digits.isRequired();
123 m_tracks.isRequired();
124 m_extHits.isRequired();
125 m_recBunch.isOptional();
126
127 // open output file
128
129 m_file = TFile::Open(m_outFileName.c_str(), "RECREATE");
130 if (m_file->IsZombie()) {
131 B2FATAL("Couldn't open file '" << m_outFileName << "' for writing!");
132 return;
133 }
134
135 // create output tree
136
137 m_alignTree = new TTree("alignTree", "TOP alignment results");
138 m_alignTree->Branch("ModuleId", &m_targetMid);
139 m_alignTree->Branch("iter", &m_iter);
140 m_alignTree->Branch("ntrk", &m_ntrk);
141 m_alignTree->Branch("errorCode", &m_errorCode);
142 m_alignTree->Branch("iterPars", &m_vAlignPars);
143 m_alignTree->Branch("iterParsErr", &m_vAlignParsErr);
144 m_alignTree->Branch("valid", &m_valid);
145 m_alignTree->Branch("numPhot", &m_numPhot);
146 m_alignTree->Branch("x", &m_x);
147 m_alignTree->Branch("y", &m_y);
148 m_alignTree->Branch("z", &m_z);
149 m_alignTree->Branch("p", &m_p);
150 m_alignTree->Branch("theta", &m_theta);
151 m_alignTree->Branch("phi", &m_phi);
152 m_alignTree->Branch("r_poca", &m_pocaR);
153 m_alignTree->Branch("z_poca", &m_pocaZ);
154 m_alignTree->Branch("x_poca", &m_pocaX);
155 m_alignTree->Branch("y_poca", &m_pocaY);
156 m_alignTree->Branch("Ecms", &m_cmsE);
157 m_alignTree->Branch("charge", &m_charge);
158 m_alignTree->Branch("PDG", &m_PDG);
159
160 }

◆ initialize() [3/33]

void initialize ( void )
overridevirtual

Initialize the Module.

This method is called at the beginning of data processing.

Reimplemented from Module.

Definition at line 110 of file TOPBackgroundModule.cc.

111 {
112
113 // CPU time start
114
115 // Initializing the output root file
116 m_rootFile = TFile::Open(m_OutputFileName.c_str(), "RECREATE");
117 origingamma = new TTree("origingamma", "tree");
118 originpe = new TTree("originpe", "tree2");
119
120 origingamma->Branch("x", &origingamma_x);
121 origingamma->Branch("y", &origingamma_y);
122 origingamma->Branch("z", &origingamma_z);
123 originpe->Branch("x", &originpe_x);
124 originpe->Branch("y", &originpe_y);
125 originpe->Branch("z", &originpe_z);
126
127 peflux = new TH1F("Photoelectron flux", "Photoelectron flux", 33, -11.25, 360);
128 nflux = new TH1F("Neutron flux", "Neutron flux", 33, -11.25, 360);
129 rdose = new TH1F("Radiation dose", "Radiation dose", 33, -11.25, 360);
130 zdist = new TH1F("Photoelectron origin", "Photoelectron origin", 200, -400, 400);
131 genergy = new TH1F("Energy distribution of photons", "Energy distribution of photons", 150, 0, 5);
132 genergy2 = new TH1F("Energy distribution of gammas", "Energy distribution of gammas", 500, 0, 5);
133
134 zdistg = new TH1F("Photoelectron flux z", "Photoelectron flux Z projection", 800, -400, 400);
135 originpt = new TH1F("P_t of origin electron", "P_t of origin electron", 300, 0.06, 0.14);
136
137 nflux_bar = new TH2F("Neutron flux on bar", "Neutron flux on bar", 32, -114.8, 211.5, 16, -0, 360);
138 gflux_bar = new TH2F("Gamma flux on bar", "Gamma flux on bar MHz/cm^{2}", 32, -114.8, 211.5, 16, -0, 360);
139 cflux_bar = new TH2F("Charged flux on bar", "Charged flux on bar MHz/cm^{2}", 32, -114.8, 211.5, 16, -0, 360);
140
141 norigin = new TH1F("neutron(BAR) origin", "neutron(BAR) origin", 200, -400, 400);
142 gorigin = new TH1F("gamma(BAR) origin", "gamma(BAR) origin", 200, -400, 400);
143 corigin = new TH1F("charged(BAR) origin", "charged(BAR) origin", 200, -400, 400);
144
145 nprim = new TH1F("neutron(BAR) primary", "neutron(BAR) primary", 200, -400, 400);
146 gprim = new TH1F("gamma(BAR) primary", "gamma(BAR) primary", 200, -400, 400);
147 cprim = new TH1F("charged(BAR) primary", "charged(BAR) primary", 200, -400, 400);
148
149 origin_zx = new TGraph();
150 origin_zy = new TGraph();
151
152 prim_zx = new TGraph();
153 prim_zy = new TGraph();
154 module_occupancy = new TGraph();
155
156 origin_zy->SetName("originZY");
157 origin_zx->SetName("originZX");
158 module_occupancy->SetName("occupancy");
159
160 const auto& geo = TOP::TOPGeometryPar::Instance()->getGeometry()->getFrontEnd();
161 double S1 = geo.getFrontBoardWidth() * geo.getFrontBoardHeight();
162 double S2 = geo.getHVBoardWidth() * geo.getHVBoardLength();
163 double V1 = S1 * geo.getFrontBoardThickness();
164 double V2 = S2 * geo.getHVBoardThickness();
165 G4Material* material1 = geometry::Materials::get(geo.getFrontBoardMaterial());
166 if (!material1) B2FATAL("Material '" << geo.getFrontBoardMaterial() << "' not found");
167 G4Material* material2 = geometry::Materials::get(geo.getHVBoardMaterial());
168 if (!material2) B2FATAL("Material '" << geo.getHVBoardMaterial() << "' not found");
169 double density1 = material1->GetDensity() / CLHEP::kg * CLHEP::cm * CLHEP::cm * CLHEP::cm;
170 double density2 = material2->GetDensity() / CLHEP::kg * CLHEP::cm * CLHEP::cm * CLHEP::cm;
171
172 PCBarea = S1 + S2; // [cm^2], old value was: 496.725
173 PCBmass = V1 * density1 + V2 * density2; // [kg], old value was: 0.417249
174
175 yearns = 1.e13;
176 evtoJ = 1.60217653 * 1e-10;
177 mtoc = 1.97530864197531;
178 count = 0;
179 count_occ = 0;
180
181 origingamma_x = 0;
182 origingamma_y = 0;
183 origingamma_z = 0;
184 originpe_x = 0;
185 originpe_y = 0;
186 originpe_z = 0;
187 }

◆ initialize() [4/33]

void initialize ( void )
overridevirtual

Initialize the Module.

This method is called at the beginning of data processing.

Reimplemented from Module.

Definition at line 111 of file TOPBunchFinderModule.cc.

112 {
113 // input collections
114
115 m_topDigits.isRequired();
116 m_topRawDigits.isOptional();
117 m_tracks.isRequired();
118 StoreArray<ExtHit> extHits;
119 extHits.isRequired();
120 m_initialParticles.isOptional();
121
122 if (m_useMCTruth) {
123 StoreArray<MCParticle> mcParticles;
124 mcParticles.isRequired();
125 StoreArray<TOPBarHit> barHits;
126 barHits.isRequired();
127 } else {
128 if (m_usePIDLikelihoods) {
129 StoreArray<PIDLikelihood> pidLikelihoods;
130 pidLikelihoods.isRequired();
131 } else {
132 StoreArray<CDCDedxLikelihood> cdcDedxLikelihoods;
133 cdcDedxLikelihoods.isRequired();
134 StoreArray<VXDDedxLikelihood> vxdDedxLikelihoods;
135 vxdDedxLikelihoods.isOptional();
136 }
137 }
138
139 // output
140
141 m_recBunch.registerInDataStore();
142 m_timeZeros.registerInDataStore();
143 m_timeZeros.registerRelationTo(extHits);
144 m_eventT0.registerInDataStore(); // usually it is already registered in tracking
145
146 // bunch separation in time
147
148 const auto* geo = TOPGeometryPar::Instance()->getGeometry();
149 m_bunchTimeSep = geo->getNominalTDC().getSyncTimeBase() / m_bunchesPerSSTclk;
150
151 // prior probabilities: from generic BBbar simulation
152 // - MCParticles with reconstructed track and at least 5 detected Cherenkov photons
153
154 m_priors[11] = 0.062; // electrons
155 m_priors[13] = 0.086; // muons
156 m_priors[211] = 0.734; // pions
157 m_priors[321] = 0.106; // kaons
158 m_priors[2212] = 0.013; // protons
159 m_priors[1000010020] = 0; // deuterons
160
161 double s = 0;
162 for (const auto& prior : m_priors) s += prior.second;
163 for (auto& prior : m_priors) prior.second /= s;
164
165 if (not m_commonT0.isValid()) {
166 B2ERROR("Common T0 calibration payload requested but not available");
167 return;
168 }
169
170 /*************************************************************************
171 * auto detection of HLT/express reco mode via status of common T0 payload:
172 * c_Default -> HLT/express reco mode
173 * c_Calibrated -> data processing mode
174 * c_Unusable -> HLT/express reco mode
175 * c_roughlyCalibrated -> HLT/express reco mode
176 *************************************************************************/
177
178 if (m_commonT0->isCalibrated()) {
179 m_HLTmode = false;
180 m_runningOffset = 0; // since digits are already commonT0 calibrated
181 m_runningError = m_commonT0->getT0Error();
182 } else if (m_commonT0->isRoughlyCalibrated()) {
183 m_HLTmode = true;
184 m_runningOffset = m_commonT0->getT0(); // since digits are not commonT0 calibrated
185 m_runningError = m_commonT0->getT0Error();
186 } else {
187 m_HLTmode = true;
188 m_runningOffset = 0;
189 m_runningError = m_bunchTimeSep / sqrt(12.0);
190 }
191
192 if (m_HLTmode) {
193 m_nTrackLimit = 0; // use single particle hypothesis to save execution time
194 B2INFO("TOPBunchFinder: running in HLT/express reco mode");
195 } else {
196 B2INFO("TOPBunchFinder: running in data processing mode");
197 }
198
199 }

◆ initialize() [5/33]

void initialize ( void )
overridevirtual

Initialize the Module.

This method is called at the beginning of data processing.

Reimplemented from Module.

Definition at line 68 of file TOPCalPulseGeneratorModule.cc.

69 {
70 // Output
71
72 m_calPulses.registerInDataStore();
73
74 // prepare vectors to loop on
75
76 const auto* geo = TOPGeometryPar::Instance()->getGeometry();
77
78 if (m_moduleIDs.empty()) {
79 for (const auto& module : geo->getModules()) {
80 m_moduleIDs.push_back(module.getModuleID());
81 }
82 } else {
83 for (auto moduleID : m_moduleIDs) {
84 if (!geo->isModuleIDValid(moduleID))
85 B2ERROR("Invalid module ID found in input list: " << moduleID);
86 }
87 }
88
89 if (m_asicChannels.empty()) {
90 for (unsigned ch = 0; ch < 8; ch++) m_asicChannels.push_back(ch);
91 } else {
92 for (unsigned ch : m_asicChannels) {
93 if (ch > 7)
94 B2ERROR("Invalid ASIC channel found in input list: " << ch);
95 }
96 }
97
98 }

◆ initialize() [6/33]

void initialize ( void )
overridevirtual

initialize method: registers datastore objects (the TOP hits)

Reimplemented from Module.

Definition at line 47 of file TOPChannelMaskerModule.cc.

48 {
49 // register data objects
50 m_digits.isRequired();
51 m_eventAsicMask.isOptional();
52 }

◆ initialize() [7/33]

void initialize ( void )
overridevirtual

Initialize the Module.

This method is called at the beginning of data processing.

Reimplemented from Module.

Definition at line 76 of file TOPChannelT0CalibratorModule.cc.

77 {
78 // input collections
79 m_digits.isRequired();
80 m_tracks.isRequired();
81 m_extHits.isRequired();
82 m_recBunch.isOptional();
83
84 // Parse PDF option
85 if (m_pdfOption == "rough") {
86 m_PDFOption = PDFConstructor::c_Rough;
87 } else if (m_pdfOption == "fine") {
88 m_PDFOption = PDFConstructor::c_Fine;
89 } else if (m_pdfOption == "optimal") {
90 m_PDFOption = PDFConstructor::c_Optimal;
91 } else {
92 B2ERROR("TOPPDFDebuggerModule: unknown PDF option '" << m_pdfOption << "'");
93 }
94
95 // set track selector
96 m_selector = TrackSelector(m_sample);
97 m_selector.setMinMomentum(m_minMomentum);
98 m_selector.setDeltaEcms(m_deltaEcms);
99 m_selector.setCutOnPOCA(m_dr, m_dz);
100 m_selector.setCutOnLocalZ(m_minZ, m_maxZ);
101
102 // minimum finders
103 double tmin = -m_timeRange / 2;
104 double tmax = m_timeRange / 2;
105 for (unsigned i = 0; i < 2; i++) {
106 for (unsigned m = 0; m < c_numModules; m++) {
107 for (unsigned c = 0; c < c_numChannels; c++) {
108 m_finders[i][m][c] = Chi2MinimumFinder1D(m_numBins, tmin, tmax);
109 }
110 }
111 }
112
113 // if file name includes *'s replace them with a run number
114 auto pos = m_outFileName.find("*");
115 if (pos != std::string::npos) {
116 StoreObjPtr<EventMetaData> evtMetaData;
117 auto run = std::to_string(evtMetaData->getRun());
118 while (run.size() < 5) run = "0" + run;
119 while (pos != std::string::npos) {
120 m_outFileName.replace(pos, 1, run);
121 pos = m_outFileName.find("*");
122 }
123 }
124
125 // open root file for ntuple and histogram output
126 m_file = TFile::Open(m_outFileName.c_str(), "RECREATE");
127 if (not m_file) {
128 B2ERROR("Cannot open output file '" << m_outFileName << "'");
129 return;
130 }
131
132 // histograms
133 for (unsigned module = 0; module < c_numModules; module++) {
134 int moduleID = module + 1;
135
136 std::string slotNum = std::to_string(moduleID);
137 if (moduleID < 10) slotNum = "0" + slotNum;
138
139 std::string name = "numHits_slot" + slotNum;
140 std::string title = "Number of hits per channel for slot " + slotNum;
141 TH1F h1(name.c_str(), title.c_str(), c_numChannels, 0, c_numChannels);
142 h1.SetXTitle("channel number");
143 h1.SetYTitle("hits per channel");
144 m_hits1D.push_back(h1);
145
146 name = "timeHits_slot" + slotNum;
147 title = "hit time vs. channel for slot " + slotNum;
148 TH2F h2(name.c_str(), title.c_str(), c_numChannels, 0, c_numChannels,
149 200, 0.0, 20.0);
150 h2.SetXTitle("channel number");
151 h2.SetYTitle("time [ns]");
152 m_hits2D.push_back(h2);
153 }
154
155 // create output tree
156
157 m_tree = new TTree("tree", "Channel T0 calibration results");
158 m_tree->Branch("slot", &m_moduleID);
159 m_tree->Branch("numPhotons", &m_numPhotons);
160 m_tree->Branch("x", &m_x);
161 m_tree->Branch("y", &m_y);
162 m_tree->Branch("z", &m_z);
163 m_tree->Branch("p", &m_p);
164 m_tree->Branch("theta", &m_theta);
165 m_tree->Branch("phi", &m_phi);
166 m_tree->Branch("r_poca", &m_pocaR);
167 m_tree->Branch("z_poca", &m_pocaZ);
168 m_tree->Branch("x_poca", &m_pocaX);
169 m_tree->Branch("y_poca", &m_pocaY);
170 m_tree->Branch("Ecms", &m_cmsE);
171 m_tree->Branch("charge", &m_charge);
172 m_tree->Branch("PDG", &m_PDG);
173
174 }

◆ initialize() [8/33]

void initialize ( void )
overridevirtual

Initialize the Module.

This method is called at the beginning of data processing.

Reimplemented from Module.

Definition at line 52 of file TOPChannelT0MCModule.cc.

53 {
54 m_digits.isRequired();
55 }

◆ initialize() [9/33]

void initialize ( void )
overridevirtual

Initialize the Module.

This method is called at the beginning of data processing.

Reimplemented from Module.

Definition at line 73 of file TOPCommonT0CalibratorModule.cc.

74 {
75 // input collections
76 m_digits.isRequired();
77 m_tracks.isRequired();
78 m_extHits.isRequired();
79 m_recBunch.isOptional();
80
81 // bunch separation in time
82
83 const auto* geo = TOPGeometryPar::Instance()->getGeometry();
84 m_bunchTimeSep = geo->getNominalTDC().getSyncTimeBase() / 24;
85
86 // Parse PDF option
87 if (m_pdfOption == "rough") {
88 m_PDFOption = PDFConstructor::c_Rough;
89 } else if (m_pdfOption == "fine") {
90 m_PDFOption = PDFConstructor::c_Fine;
91 } else if (m_pdfOption == "optimal") {
92 m_PDFOption = PDFConstructor::c_Optimal;
93 } else {
94 B2ERROR("TOPPDFDebuggerModule: unknown PDF option '" << m_pdfOption << "'");
95 }
96
97 // set track selector
98 m_selector = TrackSelector(m_sample);
99 m_selector.setMinMomentum(m_minMomentum);
100 m_selector.setDeltaEcms(m_deltaEcms);
101 m_selector.setCutOnPOCA(m_dr, m_dz);
102 m_selector.setCutOnLocalZ(m_minZ, m_maxZ);
103
104 // Chi2 minimum finders
105 double tmin = -m_timeRange / 2;
106 double tmax = m_timeRange / 2;
107 for (unsigned i = 0; i < c_numSets; i++) {
108 m_finders[i] = Chi2MinimumFinder1D(m_numBins, tmin, tmax);
109 }
110
111 // if file name includes *'s replace them with a run number
112 auto pos = m_outFileName.find("*");
113 if (pos != std::string::npos) {
114 StoreObjPtr<EventMetaData> evtMetaData;
115 auto run = std::to_string(evtMetaData->getRun());
116 while (run.size() < 5) run = "0" + run;
117 while (pos != std::string::npos) {
118 m_outFileName.replace(pos, 1, run);
119 pos = m_outFileName.find("*");
120 }
121 }
122
123 // open root file for ntuple and histogram output
124 m_file = TFile::Open(m_outFileName.c_str(), "RECREATE");
125 if (not m_file) {
126 B2ERROR("Cannot open output file '" << m_outFileName << "'");
127 return;
128 }
129
130 // control histograms
131 m_hits1D = TH1F("numHits", "Number of photons per slot",
132 c_numModules, 0.5, static_cast<float>(c_numModules) + 0.5);
133 m_hits1D.SetXTitle("slot number");
134 m_hits1D.SetYTitle("hits per slot");
135
136 m_hits2D = TH2F("timeHits", "Photon times vs. boardstacks",
137 c_numModules * 4, 0.5, static_cast<float>(c_numModules) + 0.5, 200, 0.0, 20.0);
138 m_hits2D.SetXTitle("slot number");
139 m_hits2D.SetYTitle("time [ns]");
140
141 // create output tree
142 m_tree = new TTree("tree", "Channel T0 calibration results");
143 m_tree->Branch("slot", &m_moduleID);
144 m_tree->Branch("numPhotons", &m_numPhotons);
145 m_tree->Branch("x", &m_x);
146 m_tree->Branch("y", &m_y);
147 m_tree->Branch("z", &m_z);
148 m_tree->Branch("p", &m_p);
149 m_tree->Branch("theta", &m_theta);
150 m_tree->Branch("phi", &m_phi);
151 m_tree->Branch("r_poca", &m_pocaR);
152 m_tree->Branch("z_poca", &m_pocaZ);
153 m_tree->Branch("x_poca", &m_pocaX);
154 m_tree->Branch("y_poca", &m_pocaY);
155 m_tree->Branch("Ecms", &m_cmsE);
156 m_tree->Branch("charge", &m_charge);
157 m_tree->Branch("PDG", &m_PDG);
158
159 }

◆ initialize() [10/33]

void initialize ( void )
overridevirtual

Initialize the Module.

This method is called at the beginning of data processing.

Reimplemented from Module.

Definition at line 78 of file TOPCosmicT0FinderModule.cc.

79 {
80 // input
81
82 StoreArray<TOPDigit> topDigits;
83 topDigits.isRequired();
84
85 StoreArray<Track> tracks;
86 tracks.isRequired();
87
88 StoreArray<ExtHit> extHits;
89 extHits.isRequired();
90
91 StoreArray<TOPBarHit> barHits;
92 barHits.isOptional();
93
94 // output
95
96 StoreArray<TOPTimeZero> timeZeros;
97 timeZeros.registerInDataStore();
98 timeZeros.registerRelationTo(tracks);
99 timeZeros.registerRelationTo(extHits);
100 timeZeros.registerRelationTo(barHits);
101 }

◆ initialize() [11/33]

void initialize ( void )
overridevirtual

Initialize the Module.

This method is called at the beginning of data processing.

Reimplemented from Module.

Definition at line 103 of file TOPDigitizerModule.cc.

104 {
105 // input from datastore
106 m_simHits.isRequired();
107 m_simCalPulses.isOptional();
108 m_mcParticles.isOptional();
109 m_simClockState.isOptional();
110
111 // output to datastore
112 m_rawDigits.registerInDataStore();
113 m_digits.registerInDataStore();
114 m_digits.registerRelationTo(m_simHits);
115 m_digits.registerRelationTo(m_mcParticles);
116 m_digits.registerRelationTo(m_rawDigits);
117 m_waveforms.registerInDataStore(DataStore::c_DontWriteOut);
118 m_rawDigits.registerRelationTo(m_waveforms, DataStore::c_Event,
119 DataStore::c_DontWriteOut);
120
121 // geometry and nominal data
122 const auto* geo = TOPGeometryPar::Instance()->getGeometry();
123
124 if (m_electronicJitter < 0) {
125 m_electronicJitter = geo->getNominalTDC().getTimeJitter();
126 }
127
128 // set pile-up and double hit resolution times (needed for BG overlay)
129 TOPDigit::setDoubleHitResolution(geo->getNominalTDC().getDoubleHitResolution());
130 TOPDigit::setPileupTime(geo->getNominalTDC().getPileupTime());
131
132 // default sample times (equidistant)
133 m_syncTimeBase = geo->getNominalTDC().getSyncTimeBase();
134 m_sampleTimes.setTimeAxis(m_syncTimeBase); // equidistant time base
135
136 // default pulse height generator
137 m_pulseHeightGenerator = PulseHeightGenerator(m_ADCx0, m_ADCp1, m_ADCp2, m_ADCmax);
138
139 }

◆ initialize() [12/33]

void initialize ( void )
overridevirtual

Initialize the Module.

This method is called at the beginning of data processing.

Reimplemented from Module.

Definition at line 85 of file TOPDoublePulseGeneratorModule.cc.

86 {
87 // Output
88
89 StoreArray<TOPDigit> digits;
90 digits.registerInDataStore();
91
92 // prepare vectors to loop on
93
94 const auto* geo = TOPGeometryPar::Instance()->getGeometry();
95
96 if (m_moduleIDs.empty()) {
97 for (const auto& module : geo->getModules()) {
98 m_moduleIDs.push_back(module.getModuleID());
99 }
100 } else {
101 for (auto moduleID : m_moduleIDs) {
102 if (!geo->isModuleIDValid(moduleID))
103 B2ERROR("Invalid module ID found in input list: " << moduleID);
104 }
105 }
106
107 if (m_asicChannels.empty()) {
108 for (unsigned ch = 0; ch < 8; ch++) m_asicChannels.push_back(ch);
109 } else {
110 for (unsigned ch : m_asicChannels) {
111 if (ch > 7)
112 B2ERROR("Invalid ASIC channel found in input list: " << ch);
113 }
114 }
115
116 // set sample times
117
118 double syncTimeBase = geo->getNominalTDC().getSyncTimeBase();
119 m_sampleTimes.setTimeAxis(syncTimeBase); // equidistant
120 m_sampleDivisions = (0x1 << geo->getNominalTDC().getSubBits());
121
122 if (m_useDatabase) {
123 B2INFO("TOPDoublePulseGenerator: using sample times from database");
124 } else if (m_sampleTimeIntervals.empty()) {
125 B2INFO("TOPDoublePulseGenerator: using equidistant sample times");
126 } else if (m_sampleTimeIntervals.size() == 256) {
127 std::vector<double> timeAxis;
128 timeAxis.push_back(0);
129 for (auto dt : m_sampleTimeIntervals) timeAxis.push_back(dt + timeAxis.back());
130 double rescale = 2 * syncTimeBase / timeAxis.back();
131 for (auto& t : timeAxis) t *= rescale;
132 m_sampleTimes.setTimeAxis(timeAxis, syncTimeBase); // given by steering
133 B2INFO("TOPDoublePulseGenerator: using sample times from steering");
134 } else {
135 B2ERROR("sampleTimeIntervals: size must be 256 or empty");
136 }
137
138 if (!m_outputFileName.empty()) storeSampleTimes(m_outputFileName);
139
140 }

◆ initialize() [13/33]

void initialize ( void )
overridevirtual

Initialize the Module.

This method is called at the beginning of data processing.

better use isRequired(), but RawFTSW is not in sim

Reimplemented from HistoModule.

Definition at line 310 of file TOPDQMModule.cc.

311 {
312 // Register histograms (calls back defineHisto)
313
314 REG_HISTOGRAM;
315
316 // register dataobjects
317
318 m_rawFTSWs.isOptional();
319 m_productionEventDebugs.isOptional(); // not in sim
320 m_digits.isRequired();
321 m_recBunch.isOptional();
322 m_timeZeros.isOptional();
323 m_tracks.isOptional();
324 }

◆ initialize() [14/33]

void initialize ( void )
overridevirtual

Load time vs charge 2D histogram from a given input file (parameter "inputFile") and prepare hit timing and pulse charge distribution for each channel.

Reimplemented from HistoModule.

Definition at line 84 of file TOPGainEfficiencyCalculatorModule.cc.

85 {
86 REG_HISTOGRAM;
87 }

◆ initialize() [15/33]

void initialize ( void )
overridevirtual

Initialize the Module.

This method is called at the beginning of data processing.

Reimplemented from Module.

Definition at line 53 of file TOPGeometryParInitializerModule.cc.

54 {
55 auto* gp = TOPGeometryPar::Instance();
56 if (gp->isValid()) {
57 B2WARNING("TOPGeometryPar has already been initialized");
58 return;
59 }
60
61 if (m_useDB) {
62 gp->Initialize();
63 } else {
64 bool found = false;
65 GearDir detectorDir("/Detector");
66 for (const GearDir& component : detectorDir.getNodes("DetectorComponent")) {
67 if (component.getString("@name") == "TOP") {
68 gp->Initialize(GearDir(component, "Content"));
69 found = true;
70 break;
71 }
72 }
73 if (not found) B2ERROR("Component TOP does not exist or is empty");
74 }
75
76 }

◆ initialize() [16/33]

void initialize ( void )
overridevirtual

Initialize the Module.

This method is called at the beginning of data processing.

Reimplemented from HistoModule.

Definition at line 79 of file TOPInterimFENtupleModule.cc.

80 {
81 REG_HISTOGRAM;
82
83 StoreArray<RawTOP> rawTOPs;
84 rawTOPs.isRequired();
85 StoreArray<TOPRawDigit> rawDigits;
86 rawDigits.isRequired();
87 StoreArray<TOPDigit> digits;
88 digits.isRequired();
89 StoreArray<TOPInterimFEInfo> infos;
90 infos.isRequired();
91 StoreArray<TOPProductionEventDebug> prodDebugs;
92 prodDebugs.isRequired();
93 StoreArray<TOPRawWaveform> waveforms;
94 waveforms.isRequired();
95 }

◆ initialize() [17/33]

void initialize ( void )
overridevirtual

Initialize the Module.

This method is called at the beginning of data processing.

Reimplemented from Module.

Definition at line 71 of file TOPLaserCalibratorModule.cc.

72 {
73 B2WARNING("You are using an old version of the laser fitter, now deprecated. This module has been superseded by the CAF collector TOPLaserCalibratorCollector and the CAF fitter TOPLocalCalFitter.");
74 m_digits.isRequired();
75 }

◆ initialize() [18/33]

void initialize ( void )
overridevirtual

Initialize the Module.

This method is called at the beginning of data processing.

Reimplemented from HistoModule.

Definition at line 93 of file TOPLaserHitSelectorModule.cc.

94 {
95 REG_HISTOGRAM;
96
97 StoreArray<TOPDigit> digits;
98 digits.isRequired();
99 }

◆ initialize() [19/33]

void initialize ( void )
overridevirtual

Initialize the Module.

This method is called at the beginning of data processing.

Reimplemented from Module.

Definition at line 57 of file TOPMCTrackMakerModule.cc.

58 {
59
60 // input
61
62 StoreArray<MCParticle> mcParticles;
63 mcParticles.isRequired();
64
65 StoreArray<TOPBarHit> barHits;
66 barHits.isRequired();
67
68 // output
69
70 StoreArray<Track> tracks;
71 tracks.registerInDataStore();
72
73 StoreArray<TrackFitResult> fitResults;
74 fitResults.registerInDataStore();
75
76 StoreArray<ExtHit> extHits;
77 extHits.registerInDataStore();
78
79 tracks.registerRelationTo(mcParticles);
80 tracks.registerRelationTo(extHits);
81
82 }

◆ initialize() [20/33]

void initialize ( void )
overridevirtual

Initialize the Module.

This method is called at the beginning of data processing.

Reimplemented from Module.

Definition at line 72 of file TOPModuleT0CalibratorModule.cc.

73 {
74 // input collections
75 m_digits.isRequired();
76 m_tracks.isRequired();
77 m_extHits.isRequired();
78 m_recBunch.isOptional();
79
80 // toggle has changed status to prevent warning in beginRun for the first IOV
81 m_moduleT0.hasChanged();
82
83 // Parse PDF option
84 if (m_pdfOption == "rough") {
85 m_PDFOption = PDFConstructor::c_Rough;
86 } else if (m_pdfOption == "fine") {
87 m_PDFOption = PDFConstructor::c_Fine;
88 } else if (m_pdfOption == "optimal") {
89 m_PDFOption = PDFConstructor::c_Optimal;
90 } else {
91 B2ERROR("TOPPDFDebuggerModule: unknown PDF option '" << m_pdfOption << "'");
92 }
93
94 // set track selector
95 m_selector = TrackSelector(m_sample);
96 m_selector.setMinMomentum(m_minMomentum);
97 m_selector.setDeltaEcms(m_deltaEcms);
98 m_selector.setCutOnPOCA(m_dr, m_dz);
99 m_selector.setCutOnLocalZ(m_minZ, m_maxZ);
100
101 // Chi2 minimum finders
102 double tmin = -m_timeRange / 2;
103 double tmax = m_timeRange / 2;
104 for (unsigned i = 0; i < 2; i++) {
105 for (unsigned m = 0; m < c_numModules; m++) {
106 m_finders[i][m] = Chi2MinimumFinder1D(m_numBins, tmin, tmax);
107 }
108 }
109
110 // if file name includes *'s replace them with a run number
111 auto pos = m_outFileName.find("*");
112 if (pos != std::string::npos) {
113 StoreObjPtr<EventMetaData> evtMetaData;
114 auto run = std::to_string(evtMetaData->getRun());
115 while (run.size() < 5) run = "0" + run;
116 while (pos != std::string::npos) {
117 m_outFileName.replace(pos, 1, run);
118 pos = m_outFileName.find("*");
119 }
120 }
121
122 // open root file for ntuple and histogram output
123 m_file = TFile::Open(m_outFileName.c_str(), "RECREATE");
124 if (not m_file) {
125 B2ERROR("Cannot open output file '" << m_outFileName << "'");
126 return;
127 }
128
129 // histograms
130 m_hits1D = TH1F("numHits", "Number of photons per slot",
131 c_numModules, 0.5, static_cast<float>(c_numModules) + 0.5);
132 m_hits1D.SetXTitle("slot number");
133 m_hits1D.SetYTitle("hits per slot");
134
135 m_hits2D = TH2F("timeHits", "Photon times vs. boardstacks",
136 c_numModules * 4, 0.5, static_cast<float>(c_numModules) + 0.5, 200, 0.0, 20.0);
137 m_hits2D.SetXTitle("slot number");
138 m_hits2D.SetYTitle("time [ns]");
139
140 // create output tree
141 m_tree = new TTree("tree", "Channel T0 calibration results");
142 m_tree->Branch("slot", &m_moduleID);
143 m_tree->Branch("numPhotons", &m_numPhotons);
144 m_tree->Branch("x", &m_x);
145 m_tree->Branch("y", &m_y);
146 m_tree->Branch("z", &m_z);
147 m_tree->Branch("p", &m_p);
148 m_tree->Branch("theta", &m_theta);
149 m_tree->Branch("phi", &m_phi);
150 m_tree->Branch("r_poca", &m_pocaR);
151 m_tree->Branch("z_poca", &m_pocaZ);
152 m_tree->Branch("x_poca", &m_pocaX);
153 m_tree->Branch("y_poca", &m_pocaY);
154 m_tree->Branch("Ecms", &m_cmsE);
155 m_tree->Branch("charge", &m_charge);
156 m_tree->Branch("PDG", &m_PDG);
157
158 }

◆ initialize() [21/33]

void initialize ( void )
overridevirtual

Initialize the Module.

This method is called at the beginning of data processing.

Reimplemented from Module.

Definition at line 68 of file TOPNtupleModule.cc.

69 {
70 TDirectory::TContext context;
71 m_file = TFile::Open(m_outputFileName.c_str(), "RECREATE");
72 if (m_file->IsZombie()) {
73 B2FATAL("Couldn't open file '" << m_outputFileName << "' for writing!");
74 return;
75 }
76
77 m_tree = new TTree("top", "TOP validation ntuple");
78
79 m_tree->Branch("evt", &m_top.evt, "evt/I");
80 m_tree->Branch("run", &m_top.run, "run/I");
81
82 m_tree->Branch("p", &m_top.p, "p/F");
83 m_tree->Branch("cth", &m_top.cth, "cth/F");
84 m_tree->Branch("phi", &m_top.phi, "phi/F");
85 m_tree->Branch("pValue", &m_top.pValue, "pValue/F");
86
87 m_tree->Branch("PDG", &m_top.PDG, "PDG/I");
88 m_tree->Branch("motherPDG", &m_top.motherPDG, "motherPDG/I");
89 m_tree->Branch("primary", &m_top.primary, "primary/S");
90 m_tree->Branch("seen", &m_top.seen, "seen/S");
91 m_tree->Branch("rhoProd", &m_top.rhoProd, "rhoProd/F");
92 m_tree->Branch("zProd", &m_top.zProd, "zProd/F");
93 m_tree->Branch("phiProd", &m_top.phiProd, "phiProd/F");
94 m_tree->Branch("rhoDec", &m_top.rhoDec, "rhoDec/F");
95 m_tree->Branch("zDec", &m_top.zDec, "zDec/F");
96 m_tree->Branch("phiDec", &m_top.phiDec, "phiDec/F");
97 m_tree->Branch("yieldMC", &m_top.yieldMC, "yieldMC/I");
98
99 m_tree->Branch("numPhot", &m_top.numPhot, "numPhot/I");
100 m_tree->Branch("numBkg", &m_top.numBkg, "numBkg/F");
101 m_tree->Branch("moduleID", &m_top.moduleID, "moduleID/I");
102 m_tree->Branch("phot", &m_top.phot, "e/F:mu:pi:K:p:d");
103 m_tree->Branch("yield", &m_top.yield, "e/F:mu:pi:K:p:d");
104 m_tree->Branch("logL", &m_top.logL, "e/F:mu:pi:K:p:d");
105
106 m_tree->Branch("extHit", &m_top.extHit, "moduleID/I:PDG:x/F:y:z:p:theta:phi:time");
107 m_tree->Branch("barHit", &m_top.barHit, "moduleID/I:PDG:x/F:y:z:p:theta:phi:time");
108
109 StoreArray<Track> tracks;
110 tracks.isRequired();
111 StoreArray<ExtHit> extHits;
112 extHits.isRequired();
113 StoreArray<TOPLikelihood> likelihoods;
114 likelihoods.isRequired();
115 StoreArray<MCParticle> mcParticles;
116 mcParticles.isOptional();
117 StoreArray<TOPBarHit> barHits;
118 barHits.isOptional();
119 StoreObjPtr<MCInitialParticles> mcInitialParticles;
120 mcInitialParticles.isOptional();
121 }

◆ initialize() [22/33]

void initialize ( void )
overridevirtual

Initialize the Module.

This method is called at the beginning of data processing.

Reimplemented from Module.

Definition at line 66 of file TOPPackerModule.cc.

67 {
68
69 if (m_format == "draft") {
70 m_dataType = TOP::RawDataType::c_Draft;
71 StoreArray<TOPDigit> digits(m_inputDigitsName);
72 digits.isRequired();
73 } else if (m_format == "FE") {
74 m_dataType = TOP::RawDataType::c_Type0Ver16;
75 StoreArray<TOPRawDigit> rawDigits(m_inputRawDigitsName);
76 rawDigits.isRequired();
77 } else if (m_format == "production") {
78 m_dataType = TOP::RawDataType::c_ProductionDebug01;
79 StoreArray<TOPRawDigit> rawDigits(m_inputRawDigitsName);
80 rawDigits.isRequired();
81 } else {
82 B2ERROR("TOPPacker: unknown data format."
83 << LogVar("format", m_format));
84 }
85
86 StoreArray<RawTOP> rawData(m_outputRawDataName);
87 rawData.registerInDataStore();
88
89 // check if front end mappings are available
90 const auto& mapper = m_topgp->getFrontEndMapper();
91 if (!mapper.isValid()) B2ERROR("No front-end mapping available for TOP");
92
93 }

◆ initialize() [23/33]

void initialize ( void )
overridevirtual

Initialize the Module.

This method is called at the beginning of data processing.

Reimplemented from HistoModule.

Definition at line 96 of file TOPPDFCheckerModule.cc.

97 {
98 // Register histograms (calls back defineHisto)
99 REG_HISTOGRAM;
100
101 // input
102
103 m_digits.isRequired();
104 m_tracks.isRequired();
105
106 StoreArray<ExtHit> extHits;
107 extHits.isRequired();
108
109 StoreArray<MCParticle> mcParticles;
110 mcParticles.isRequired();
111
112 StoreArray<TOPBarHit> barHits;
113 barHits.isRequired();
114
115 }

◆ initialize() [24/33]

void initialize ( void )
overridevirtual

Initialize the Module.

This method is called at the beginning of data processing.

Reimplemented from Module.

Definition at line 72 of file TOPPDFDebuggerModule.cc.

73 {
74 // input
75 m_digits.isRequired();
76 m_tracks.isRequired();
77
78 StoreArray<ExtHit> extHits;
79 extHits.isRequired();
80
81 StoreArray<MCParticle> mcParticles;
82 mcParticles.isOptional();
83
84 StoreArray<TOPBarHit> barHits;
85 barHits.isOptional();
86
87 // output
88 m_pdfCollection.registerInDataStore();
89 m_tracks.registerRelationTo(m_pdfCollection);
90 m_associatedPDFs.registerInDataStore();
91 m_digits.registerRelationTo(m_associatedPDFs);
92 m_pixelData.registerInDataStore();
93 m_tracks.registerRelationTo(m_pixelData);
94
95 // particle hypotheses
96 if (m_pdgCodes.empty()) {
97 for (const auto& part : Const::chargedStableSet) {
98 m_chargedStables.push_back(part);
99 }
100 } else {
101 for (auto pdg : m_pdgCodes) {
102 auto part = Const::ChargedStable(abs(pdg)); //throws runtime error for invalid pdg
103 m_chargedStables.push_back(part);
104 }
105 }
106
107 // Parse PDF option
108 if (m_pdfOption == "rough") {
109 m_PDFOption = PDFConstructor::c_Rough;
110 } else if (m_pdfOption == "fine") {
111 m_PDFOption = PDFConstructor::c_Fine;
112 } else if (m_pdfOption == "optimal") {
113 m_PDFOption = PDFConstructor::c_Optimal;
114 } else {
115 B2ERROR("TOPPDFDebuggerModule: unknown PDF option '" << m_pdfOption << "'");
116 }
117
118 }

◆ initialize() [25/33]

void initialize ( void )
overridevirtual

Initialize the Module.

This method is called at the beginning of data processing.

Reimplemented from Module.

Definition at line 109 of file TOPRawDigitConverterModule.cc.

110 {
111
112 // registration of objects in datastore
113 m_rawDigits.isRequired(m_inputRawDigitsName);
114 m_eventDebugs.isOptional();
115 m_digits.registerInDataStore(m_outputDigitsName);
116 m_digits.registerRelationTo(m_rawDigits);
117 m_asicMask.registerInDataStore();
118
119 // equidistant sample times in case calibration is not required
120 const auto* geo = TOPGeometryPar::Instance()->getGeometry();
121 m_syncTimeBase = geo->getNominalTDC().getSyncTimeBase();
122 m_sampleTimes.setTimeAxis(m_syncTimeBase);
123
124 }

◆ initialize() [26/33]

void initialize ( void )
overridevirtual

Initialize the Module.

This method is called at the beginning of data processing.

Reimplemented from Module.

Definition at line 70 of file TOPReconstructorModule.cc.

71 {
72 // input
73
74 m_digits.isRequired(m_topDigitCollectionName);
75 m_tracks.isRequired();
76 m_extHits.isRequired();
77 m_barHits.isOptional();
78 m_recBunch.isOptional();
79
80 // output
81
82 m_likelihoods.registerInDataStore(m_topLikelihoodCollectionName);
83 m_likelihoods.registerRelationTo(m_extHits);
84 m_likelihoods.registerRelationTo(m_barHits);
85 m_tracks.registerRelationTo(m_likelihoods);
86
87 m_topPulls.registerInDataStore(m_topPullCollectionName, DataStore::c_DontWriteOut);
88 m_tracks.registerRelationTo(m_topPulls, DataStore::c_Event, DataStore::c_DontWriteOut);
89 }

◆ initialize() [27/33]

void initialize ( void )
overridevirtual

Initialize the module.

Reimplemented from HistoModule.

Definition at line 336 of file TOPTBCComparatorModule.cc.

337 {
338 REG_HISTOGRAM;
339 }

◆ initialize() [28/33]

void initialize ( void )
overridevirtual

Initialize the Module.

This method is called at the beginning of data processing.

Reimplemented from Module.

Definition at line 102 of file TOPTimeBaseCalibratorModule.cc.

103 {
104
105 // input
106 m_digits.isRequired();
107
108 // checks
109 const auto* geo = TOPGeometryPar::Instance()->getGeometry();
110 if (!geo->isModuleIDValid(m_moduleID))
111 B2ERROR("Invalid module ID: " << m_moduleID);
112
113 // check for existence and mkdir if not
114 if (m_directoryName.empty()) m_directoryName = "./";
115 if (m_directoryName != "./") gSystem->mkdir(m_directoryName.c_str(), kTRUE);
116
117 // synchronization time corresponding to two ASIC windows
118 m_syncTimeBase = geo->getNominalTDC().getSyncTimeBase();
119
120 // control histograms
121 m_goodHits = TH2F("goodHits", "pulse height vs. pulse width of all good hits",
122 100, 0, 10, 100, 0, 2000);
123 m_goodHits.SetXTitle("pulse width (FWHM) [ns]");
124 m_goodHits.SetYTitle("pulse height [ADC counts]");
125 m_calPulseFirst = TH2F("calPulseFirst",
126 "pulse height vs. pulse width of the first calibration pulse",
127 100, 0, 10, 100, 0, 2000);
128 m_calPulseFirst.SetXTitle("pulse width (FWHM) [ns]");
129 m_calPulseFirst.SetYTitle("pulse height [ADC counts]");
130 m_calPulseSecond = TH2F("calPulseSecond",
131 "pulse height vs. pulse width of the second calibration pulse",
132 100, 0, 10, 100, 0, 2000);
133 m_calPulseSecond.SetXTitle("pulse width (FWHM) [ns]");
134 m_calPulseSecond.SetYTitle("pulse height [ADC counts]");
135
136 }

◆ initialize() [29/33]

void initialize ( void )
overridevirtual

Initialize the Module.

This method is called at the beginning of data processing.

Reimplemented from Module.

Definition at line 71 of file TOPTimeRecalibratorModule.cc.

72 {
73
74 // registration of objects in datastore
75 m_digits.isRequired();
76 m_recBunch.isRequired();
77
78 // equidistant sample times in case calibration is not required
79 const auto* geo = TOPGeometryPar::Instance()->getGeometry();
80 m_syncTimeBase = geo->getNominalTDC().getSyncTimeBase();
81 m_sampleTimes.setTimeAxis(m_syncTimeBase);
82
83 }

◆ initialize() [30/33]

void initialize ( void )
overridevirtual

Initialize the Module.

This method is called at the beginning of data processing.

Reimplemented from Module.

Definition at line 64 of file TOPTriggerDigitizerModule.cc.

65 {
66 // input
67 StoreArray<TOPRawWaveform> waveforms;
68 waveforms.isRequired();
69
70 // output
71 StoreArray<TOPTriggerDigit> digits;
72 digits.registerInDataStore();
73 digits.registerRelationTo(waveforms);
74 StoreObjPtr<TOPTriggerMCInfo> mcInfo;
75 mcInfo.registerInDataStore();
76
77 if (m_samplingPhase < 0 or m_samplingPhase >= c_SamplingCycle)
78 B2ERROR("samplingPhase must be positive and less than " << c_SamplingCycle);
79
80 }

◆ initialize() [31/33]

void initialize ( void )
overridevirtual

Initialize the Module.

This method is called at the beginning of data processing.

Reimplemented from Module.

Definition at line 78 of file TOPUnpackerModule.cc.

79 {
80
81 // input
82
83 m_rawData.isRequired(m_inputRawDataName);
84
85 // output
86
87 m_digits.registerInDataStore(m_outputDigitsName);
88 m_rawDigits.registerInDataStore(m_outputRawDigitsName);
89 m_slowData.registerInDataStore();
90 m_interimFEInfos.registerInDataStore(DataStore::c_DontWriteOut);
91 m_waveforms.registerInDataStore(m_outputWaveformsName, DataStore::c_DontWriteOut);
92 m_productionEventDebugs.registerInDataStore(DataStore::c_DontWriteOut);
93 m_productionHitDebugs.registerInDataStore(DataStore::c_DontWriteOut);
94 m_templateFitResults.registerInDataStore(m_templateFitResultName, DataStore::c_DontWriteOut);
95 m_injectionVeto.registerInDataStore();
96
97 m_rawDigits.registerRelationTo(m_waveforms, DataStore::c_Event, DataStore::c_DontWriteOut);
98 m_rawDigits.registerRelationTo(m_templateFitResults, DataStore::c_Event, DataStore::c_DontWriteOut);
99 m_rawDigits.registerRelationTo(m_interimFEInfos, DataStore::c_Event, DataStore::c_DontWriteOut);
100 m_rawDigits.registerRelationTo(m_productionHitDebugs, DataStore::c_Event, DataStore::c_DontWriteOut);
101 m_waveforms.registerRelationTo(m_interimFEInfos, DataStore::c_Event, DataStore::c_DontWriteOut);
102
103 // check if front end mappings are available
104 const auto& mapper = m_topgp->getFrontEndMapper();
105 int mapSize = mapper.getMapSize();
106 if (mapSize == 0) B2ERROR("TOPUnpacker: No front-end mapping available for TOP");
107
108 }

◆ initialize() [32/33]

void initialize ( void )
overridevirtual

Initialize the Module.

This method is called at the beginning of data processing.

Reimplemented from Module.

Definition at line 66 of file TOPWaveformFeatureExtractorModule.cc.

67 {
68
69 StoreArray<TOPRawDigit> rawDigits(m_inputRawDigitsName);
70 rawDigits.isRequired();
71
72 }

◆ initialize() [33/33]

void initialize ( void )
overridevirtual

Module initialization, calls defineHisto and gets waveform.

Reimplemented from HistoModule.

Definition at line 71 of file TOPWaveformQualityPlotterModule.cc.

72 {
73 // Register histograms (calls back defineHisto)
74 REG_HISTOGRAM;
75 //Get Waveform from datastore
76 m_waveform.isRequired();
77 }

◆ isBucketFilled()

bool isBucketFilled ( int bunchNo)
private

Does reconstructed bunch number correspond to filled bucket.

Parameters
bunchNoreconstructed relative bunch number
Returns
true if filled

Definition at line 670 of file TOPBunchFinderModule.cc.

671 {
672 // return true if needed information is not available or fill pattern offset is not calibrated
673
674 if (not m_bunchStructure->isSet()) return true;
675 if (m_revo9Counter == 0xFFFF) return true;
676 if (not m_fillPatternOffset.isValid()) return true;
677 if (not m_fillPatternOffset->isCalibrated()) return true;
678
679 // fill pattern offset; it is always zero on MC, because we are not simulating it
680
681 int offset = m_isMC ? 0 : m_fillPatternOffset->get();
682
683 // corresponding bucket number and fill status
684
685 int RFBuckets = m_bunchStructure->getRFBucketsPerRevolution();
686 int bucket = TOPRecBunch::getBucketNumber(bunchNo, m_revo9Counter, offset, RFBuckets);
687 bool isFilled = m_bunchStructure->getBucket(bucket);
688
689 // store them in TOPRecBunch
690
691 m_recBunch->setBucketNumber(bucket);
692 m_recBunch->setBucketFillStatus(isFilled);
693
694 return isFilled;
695 }

◆ isFromThisParticle()

bool isFromThisParticle ( const TOPDigit & digit,
const MCParticle * particle )
private

Checks if digit comes from given MC particle.

Parameters
digitTOP digit
particleMC particle

Definition at line 207 of file TOPPDFCheckerModule.cc.

209 {
210 const auto particles = digit.getRelationsWith<MCParticle>();
211 for (unsigned i = 0; i < particles.size(); ++i) {
212 if (particles[i] == particle and particles.weight(i) > 0) return true;
213 }
214 return false;
215 }

◆ isInsideSlit()

bool isInsideSlit ( const ROOT::Math::XYZPoint & point,
const ROOT::Math::XYZVector & direction ) const
private

Checks if photon passes the slit.

Parameters
pointphoton emission point
directionphoton emission direction
Returns
true on success

Definition at line 213 of file OpticalGunModule.cc.

215 {
216 if (m_slitZ < 0.01) return true; // no screen with a slit is put in front of a source
217 if (direction.Z() < 1.0e-6) return false; // must fly toward the slit
218
219 double pathLength = (m_slitZ - point.Z()) / direction.Z();
220 if (m_slitDX > 0) {
221 double x = point.X() + pathLength * direction.X();
222 if (abs(x - m_slitX0) > m_slitDX / 2.0) return false;
223 }
224 if (m_slitDY > 0) {
225 double y = point.Y() + pathLength * direction.Y();
226 if (abs(y - m_slitY0) > m_slitDY / 2.0) return false;
227 }
228
229 return true;
230 }

◆ isRunningOffsetSubtracted() [1/2]

bool isRunningOffsetSubtracted ( )
private

Checks if running offset is subtracted in TOPDigits.

Returns
true if subtracted at least in one digit

Definition at line 305 of file TOPCommonT0CalibratorModule.cc.

306 {
307 for (const auto& digit : m_digits) {
308 if (digit.hasStatus(TOPDigit::c_BunchOffsetSubtracted)) return true;
309 }
310 return false;
311 }

◆ isRunningOffsetSubtracted() [2/2]

bool isRunningOffsetSubtracted ( )
private

Checks if running offset is subtracted in TOPDigits.

Returns
true if subtracted at least in one digit

Definition at line 333 of file TOPModuleT0CalibratorModule.cc.

334 {
335 for (const auto& digit : m_digits) {
336 if (digit.hasStatus(TOPDigit::c_BunchOffsetSubtracted)) return true;
337 }
338 return false;
339 }

◆ Iteration()

void Iteration ( const std::vector< TwoTimes > & ntuple,
std::vector< double > & xval )
private

Iteration function called by iterativeTBC()

Parameters
ntuplentuple data
xvalTBC constants of 256 samples, time interval is the difference of nearby xvals, xval[0]=0 and xval[256]=2*m_syncTimeBase

Definition at line 611 of file TOPTimeBaseCalibratorModule.cc.

612 {
613 for (int i = 0; i < c_TimeAxisSize; i++) {
614 double wdth = xval[i + 1] - xval[i];
615 if (wdth < m_min_binwidth) {
616 xval[i] = xval[i] - 0.5 * fabs(wdth) - 0.5 * m_min_binwidth;
617 xval[i + 1] = xval[i + 1] + 0.5 * fabs(wdth) + 0.5 * m_min_binwidth;
618 }
619 if (wdth > m_max_binwidth) {
620 xval[i] = xval[i] - 0.5 * fabs(wdth) - 0.5 * m_max_binwidth;
621 xval[i + 1] = xval[i + 1] + 0.5 * fabs(wdth) + 0.5 * m_max_binwidth;
622 }
623 }
624
625 if (xval[0] != 0)
626 for (int i = 0; i < c_TimeAxisSize; i++) xval[i] = xval[i] - xval[0];
627
628 std::vector<double> xxval(c_TimeAxisSize + 1, 0.0);
629 for (int i = 0; i < c_TimeAxisSize + 1; i++) xxval[i] = xval[i];
630
631 double chi2_0 = Chisq(ntuple, xxval);
632 if (chi2_0 < 0) B2ERROR("iTBC chisq_0<0! xval has problem.");
633
634 std::vector<double> dr_chi2(c_TimeAxisSize + 1, 0.0);
635 TH1D hdrsamp_try("hdrsamp_try", "dchi2/dx distribution", 100, -0.01, 0.01);
636
637 for (int smp = 1; smp < c_TimeAxisSize; smp++) {
638 xxval[smp] = xval[smp] + m_dev_step;
639 double chi2_ch = Chisq(ntuple, xxval);
640 if (chi2_ch < 0)continue;
641 dr_chi2[smp] = (chi2_ch - chi2_0) / m_dev_step;
642 hdrsamp_try.Fill(dr_chi2[smp]);
643 xxval[smp] = xval[smp];
644 }
645
646 for (int smp = 1; smp < c_TimeAxisSize; smp++) {
647 double vx_it_step = dr_chi2[smp] * m_xstep;
648 xval[smp] = xval[smp] - vx_it_step;
649 }
650
651 //save rms of dchi2/dxval.
652 m_dchi2dxv = hdrsamp_try.GetRMS();
653 //change m_xstep
654 if (fabs(m_dchi2dxv) < m_change_xstep) m_xstep = m_new_xstep;
655 }

◆ iterativeTBC()

bool iterativeTBC ( const std::vector< TwoTimes > & ntuple,
unsigned scrodID,
unsigned scrodChannel,
double meanTimeDifference,
TH1F & Hchi2,
TH1F & Hndf,
TH1F & HDeltaT )
private

Method by iteration of chi2 minimization.

Parameters
ntuplentuple data
scrodIDSCROD ID
scrodChannelchannel number within SCROD (0 - 127)
meanTimeDifferenceaverage time difference [samples]
Hchi2histogram to store normalized chi^2
Hndfhistogram to store degrees of freedom
HDeltaThistogram to store fittet double pulse delay
Returns
true on success

Definition at line 526 of file TOPTimeBaseCalibratorModule.cc.

531 {
532 std::vector<double> xval(c_TimeAxisSize + 1, 0.0);
533 double wx = 2 * m_syncTimeBase / static_cast<double>(c_TimeAxisSize);
534 for (int i = 0; i < c_TimeAxisSize + 1; i++) xval[i] = i * wx;
535
536 B2INFO("TimeBaseCalibration starts for channel#" << chan);
537
538 double pre_chi2 = 10000000.0;
539 unsigned num_small_dev = 0;
540
541 for (unsigned j = 0; j < m_numIterations; j++) {
542
543 Iteration(ntuple, xval);
544 double this_chi2 = Chisq(ntuple, xval);
545 if (this_chi2 < 0)continue;
546 double deltaChi2 = pre_chi2 - this_chi2;
547 if (deltaChi2 < -m_dchi2_min) break;
548 if (fabs(deltaChi2) < m_deltamin) num_small_dev++;
549 if (num_small_dev > m_conv_iter) break;
550 pre_chi2 = this_chi2;
551 }
552
553 // calculate chi^2
554
555 double chi2 = Chisq(ntuple, xval);
556 Hchi2.SetBinContent(chan + 1, chi2);
557 Hndf.SetBinContent(chan + 1, m_good);
558
559 // constrain sum of x to 2*syncTimeBase and calculate sample times, not necessary here
560
561 double sum = 0;
562 for (auto xi : xval) sum += xi;
563 if (sum == 0) {
564 B2ERROR("sum == 0");
565 return false;
566 }
567
568 double DeltaT = meanTimeDifference * (2 * m_syncTimeBase / static_cast<double>(c_TimeAxisSize));
569 HDeltaT.SetBinContent(chan + 1, DeltaT);
570
571 std::vector<double> timeInterval;
572 for (int i = 0; i < c_TimeAxisSize; i++)timeInterval.push_back(xval[i + 1] - xval[i]);
573
574
575 std::vector<double> sampleTimes;
576 for (auto xi : xval) sampleTimes.push_back(xi);
577
578 // save results as histograms
579 std::string forWhat = "scrod " + to_string(scrodID) + " channel " + to_string(chan);
580 saveAsHistogram(timeInterval, "dt_ch" + to_string(chan), "Sample time bins for " + forWhat,
581 "sample number", "#Delta t [ns]");
582 saveAsHistogram(sampleTimes, "sampleTimes_ch" + to_string(chan),
583 "Time base corrections for " + forWhat, "sample number", "t [ns]");
584
585 // calibrated cal pulse time difference
586 std::string name = "timeDiffcal_ch" + to_string(chan);
587 std::string title = "Calibrated cal pulse time difference vs. sample for " + forWhat;
588 TH2F Hcor(name.c_str(), title.c_str(), c_TimeAxisSize, 0, c_TimeAxisSize,
589 100, DeltaT - 0.5, DeltaT + 0.5);
590 Hcor.SetXTitle("sample number");
591 Hcor.SetYTitle("time difference [ns]");
592 Hcor.SetStats(kTRUE);
593
594 TOPSampleTimes timeBase;
595 timeBase.setTimeAxis(sampleTimes, sampleTimes.back() / 2);
596
597 for (const auto& twoTimes : ntuple) {
598 if (!twoTimes.good) continue;
599 double dt = timeBase.getDeltaTime(0, twoTimes.t2, twoTimes.t1);
600 int sample = int(twoTimes.t1) % c_TimeAxisSize;
601 Hcor.Fill(sample, dt);
602 }
603 Hcor.Write();
604
605 B2INFO("... channel " << chan << " OK (chi^2/ndf = " << chi2
606 << ", ndf = " << m_good << ")");
607
608 return true;
609 }

◆ LoadHistograms()

void LoadHistograms ( const std::string & histotype)

Load 2D histograms from a given input file (output of TOPLaserHitSelector) and create timing and charge distribution as projection histograms for the x- and y-axis, respectively.

Timing cut is also applied for charge distributiion

Definition at line 204 of file TOPGainEfficiencyCalculatorModule.cc.

205 {
206
207 TFile* f = new TFile(m_inputFile.c_str());
208 if (!f->IsOpen()) {
209 B2ERROR("TOPGainEfficiencyCalculator : fail to open input file \"" << m_inputFile << "\"");
210 return;
211 }
212
213 for (int iHisto = 0 ; iHisto < c_NChannelPerPMT ; iHisto++) {
214 if (m_targetPmtChId != -1 && iHisto + 1 != m_targetPmtChId) continue;
215 std::ostringstream pixelstr;
216 pixelstr << histotype << "_"
217 << "s" << std::setw(2) << std::setfill('0') << m_targetSlotId << "_PMT"
218 << std::setw(2) << std::setfill('0') << m_targetPmtId
219 << "_" << std::setw(2) << std::setfill('0') << (iHisto + 1);
220 std::ostringstream hname;
221 hname << "hTime" << pixelstr.str();
222
223 //first get 2D histogram from a given input (=an output file of TOPLaserHitSelector)
224 m_timeChargeHistogram[iHisto] = static_cast<TH2F*>(f->Get(hname.str().c_str()));
225 TH2F* h2D = m_timeChargeHistogram[iHisto];
226 if (!h2D) continue;
227
228 //create a projection histogram along the x-axis and fit the distribution (hit timing) to get direct laser hit timing
229 std::ostringstream hnameProj[2];
230 hnameProj[0] << "hTime_" << pixelstr.str();
231 hnameProj[1] << "hCharge_" << pixelstr.str();
232 TH1D* hTime = static_cast<TH1D*>(h2D->ProjectionX(hnameProj[0].str().c_str()));
233 m_timeHistogram[iHisto] = hTime;
234 double peakTime = FindPeakForSmallerXThan(hTime, 0);
235 //double peakTime = hTime->GetXaxis()->GetBinCenter(hTime->GetMaximumBin());
236 double fitMin = peakTime - m_fitHalfWidth;
237 double fitMax = peakTime + m_fitHalfWidth;
238 TF1* funcLaser = new TF1(std::string(std::string("func_") + hnameProj[1].str()).c_str(),
239 "gaus(0)", fitMin, fitMax);
240 funcLaser->SetParameters(hTime->GetBinContent(hTime->GetXaxis()->FindBin(peakTime)), peakTime, m_fitHalfWidth);
241 funcLaser->SetParLimits(1, fitMin, fitMax);
242 hTime->Fit(funcLaser, "Q", "", fitMin, fitMax);
243 //if (funcLaser->GetNDF() < 1) continue;
244 m_funcForLaser[iHisto] = funcLaser;
245
246 //if the fitting is successful, create y-projection histogram with timing cut
247 m_hitTiming = funcLaser->GetParameter(1);
248 int binNumMin = hTime->GetXaxis()->FindBin(m_hitTiming - 2 * m_fitHalfWidth);
249 int binNumMax = hTime->GetXaxis()->FindBin(m_hitTiming + 2 * m_fitHalfWidth);
250 TH1D* hCharge = static_cast<TH1D*>(h2D->ProjectionY(hnameProj[1].str().c_str(), binNumMin, binNumMax));
251 m_chargeHistogram[iHisto] = hCharge;
252 }
253
254 m_nCalPulseHistogram = static_cast<TH1F*>(f->Get("hNCalPulse"));
255 if (!m_nCalPulseHistogram)
256 B2WARNING("TOPGainEfficiencyCalculator : no histogram for the number of events with calibration pulses identified in the given input file");
257 m_thresholdForIntegral = m_threshold * m_p1HeightIntegral + m_p0HeightIntegral;
258 return;
259 }

◆ makeComparisons()

int makeComparisons ( )

Last function to be called, compared the histograms of different datasets filled by analyzeCalFile() Every new comparison histogram added to the module has to be filled here.

Definition at line 301 of file TOPTBCComparatorModule.cc.

302 {
303 // Set to compare with
304 short refSet = 0;
305 B2INFO("Making comparisons for " << m_totCalSets << " sets.");
306
307 // Loop over the sets. Do not make the comparison for the set #0
308 for (int iSet = 1; iSet < m_totCalSets; iSet++) {
309 if (m_compareToPreviousSet) refSet = iSet - 1;
310
311 m_topAverageDeltaTComparison[iSet] = calculateHistoRatio(m_topAverageDeltaTComparison[iSet], m_topAverageDeltaT[iSet],
312 m_topAverageDeltaT[refSet]);
313 m_topSigmaDeltaTComparison[iSet] = calculateHistoRatio(m_topSigmaDeltaTComparison[iSet], m_topSigmaDeltaT[iSet],
314 m_topSigmaDeltaT[refSet]);
315 m_topSampleOccupancyComparison[iSet] = calculateHistoRatio(m_topSampleOccupancyComparison[iSet], m_topSampleOccupancy[iSet],
316 m_topSampleOccupancy[refSet]);
317
318 // Loop over the sets. Do not make the comparison for the set #0
319 for (int iSlot = 0; iSlot < 16; iSlot++) {
320 m_slotAverageDeltaTComparison[iSlot][iSet] = calculateHistoRatio(m_slotAverageDeltaTComparison[iSlot][iSet],
321 m_slotAverageDeltaT[iSlot][iSet], m_slotAverageDeltaT[iSlot][refSet]);
322 m_slotAverageDeltaTMapComparison[iSlot][iSet] = calculateHistoRatio(m_slotAverageDeltaTMapComparison[iSlot][iSet],
323 m_slotAverageDeltaTMap[iSlot][iSet], m_slotAverageDeltaTMap[iSlot][refSet]);
324 m_slotSigmaDeltaTComparison[iSlot][iSet] = calculateHistoRatio(m_slotSigmaDeltaTComparison[iSlot][iSet],
325 m_slotSigmaDeltaT[iSlot][iSet], m_slotSigmaDeltaT[iSlot][refSet]);
326 m_slotSigmaDeltaTMapComparison[iSlot][iSet] = calculateHistoRatio(m_slotSigmaDeltaTMapComparison[iSlot][iSet],
327 m_slotSigmaDeltaTMap[iSlot][iSet], m_slotSigmaDeltaTMap[iSlot][refSet]);
328 }
329 }
330 B2INFO("Comparisons done");
331
332 return 1;
333 }

◆ matrixInversion()

bool matrixInversion ( const std::vector< TwoTimes > & ntuple,
unsigned scrodID,
unsigned scrodChannel,
double meanTimeDifference,
TH1F & Hchi2,
TH1F & Hndf,
TH1F & HDeltaT )
private

Method by matrix inversion.

Parameters
ntuplentuple data
scrodIDSCROD ID
scrodChannelchannel number within SCROD (0 - 127)
meanTimeDifferenceaverage time difference [samples]
Hchi2histogram to store normalized chi^2
Hndfhistogram to store degrees of freedom
HDeltaThistogram to store fittet double pulse delay
Returns
true on success

Definition at line 386 of file TOPTimeBaseCalibratorModule.cc.

391 {
392
393 // Ax = b: construct matrix A and right side vector b
394
395 TMatrixDSym A(c_TimeAxisSize);
396 vector<double> b(c_TimeAxisSize, 0.0);
397
398 for (const auto& twoTimes : ntuple) {
399 if (!twoTimes.good) continue;
400
401 vector<double> m(c_TimeAxisSize, 0.0);
402 int i1 = int(twoTimes.t1);
403 m[i1 % c_TimeAxisSize] = 1.0 - (twoTimes.t1 - i1);
404 int i2 = int(twoTimes.t2);
405 m[i2 % c_TimeAxisSize] = twoTimes.t2 - i2;
406 i2 = i1 + (i2 - i1) % c_TimeAxisSize;
407 for (int k = i1 + 1; k < i2; k++) m[k % c_TimeAxisSize] = 1;
408
409 double relSigma = twoTimes.sigma / meanTimeDifference;
410 double sig2 = relSigma * relSigma;
411
412 for (int jj = i1; jj < i2 + 1; jj++) {
413 int j = jj % c_TimeAxisSize;
414 for (int kk = i1; kk < i2 + 1; kk++) {
415 int k = kk % c_TimeAxisSize;
416 A(j, k) += m[j] * m[k] / sig2;
417 }
418 }
419 for (int k = 0; k < c_TimeAxisSize; k++) b[k] += m[k] / sig2;
420 }
421
422 // save as histograms
423
424 string forWhat = "scrod " + to_string(scrodID) + " channel " + to_string(chan);
425 if (m_saveMatrix) {
426 saveAsHistogram(A, "matA_ch" + to_string(chan), "Matrix for " + forWhat);
427 saveAsHistogram(b, "vecB_ch" + to_string(chan), "Right side for " + forWhat);
428 }
429
430 // invert matrix A and solve the equation: x = A^{-1}b
431
432 double det = 0;
433 A.Invert(&det);
434 if (det == 0) {
435 B2INFO("... channel " << chan << " failed");
436 return false;
437 }
438
439 vector<double> x(c_TimeAxisSize, 0.0);
440 for (int k = 0; k < c_TimeAxisSize; k++) {
441 for (int j = 0; j < c_TimeAxisSize; j++) {
442 x[k] += A(k, j) * b[j];
443 }
444 }
445
446 // calculate chi^2
447
448 double chi2 = 0;
449 int ndf = -c_TimeAxisSize;
450
451 for (const auto& twoTimes : ntuple) {
452 if (!twoTimes.good) continue;
453
454 vector<double> m(c_TimeAxisSize, 0.0);
455 int i1 = int(twoTimes.t1);
456 m[i1 % c_TimeAxisSize] = 1.0 - (twoTimes.t1 - i1);
457 int i2 = int(twoTimes.t2);
458 m[i2 % c_TimeAxisSize] = twoTimes.t2 - i2;
459 i2 = i1 + (i2 - i1) % c_TimeAxisSize;
460 for (int k = i1 + 1; k < i2; k++) m[k % c_TimeAxisSize] = 1;
461 double s = -1.0;
462 for (int k = 0; k < c_TimeAxisSize; k++) s += m[k] * x[k];
463 double relSigma = twoTimes.sigma / meanTimeDifference;
464 double sig2 = relSigma * relSigma;
465 chi2 += s * s / sig2;
466 ndf++;
467 }
468 Hchi2.SetBinContent(chan + 1, chi2 / ndf);
469 Hndf.SetBinContent(chan + 1, ndf);
470
471 // constrain sum of x to 2*syncTimeBase and calculate sample times
472
473 double sum = 0;
474 for (auto xi : x) sum += xi;
475 if (sum == 0) {
476 B2ERROR("sum == 0");
477 return false;
478 }
479 double DeltaT = 2 * m_syncTimeBase / sum;
480 for (auto& xi : x) xi *= DeltaT;
481 HDeltaT.SetBinContent(chan + 1, DeltaT);
482
483 vector<double> err;
484 for (int k = 0; k < c_TimeAxisSize; k++) err.push_back(sqrt(A(k, k)) * DeltaT);
485
486 vector<double> sampleTimes;
487 sampleTimes.push_back(0);
488 for (auto xi : x) sampleTimes.push_back(xi + sampleTimes.back());
489
490 // save results as histograms
491
492 if (m_saveMatrix) saveAsHistogram(A, "invA_ch" + to_string(chan), "Inverted matrix for " + forWhat);
493 saveAsHistogram(x, err, "dt_ch" + to_string(chan), "Sample time bins for " + forWhat,
494 "sample number", "#Delta t [ns]");
495 saveAsHistogram(sampleTimes, "sampleTimes_ch" + to_string(chan),
496 "Time base corrections for " + forWhat, "sample number", "t [ns]");
497
498 // calibrated cal pulse time difference
499
500 string name = "timeDiffcal_ch" + to_string(chan);
501 string title = "Calibrated cal pulse time difference vs. sample for " + forWhat;
502 TH2F Hcor(name.c_str(), title.c_str(), c_TimeAxisSize, 0, c_TimeAxisSize,
503 100, DeltaT - 0.5, DeltaT + 0.5);
504 Hcor.SetXTitle("sample number");
505 Hcor.SetYTitle("time difference [ns]");
506 Hcor.SetStats(kTRUE);
507
508 TOPSampleTimes timeBase;
509 timeBase.setTimeAxis(sampleTimes, sampleTimes.back() / 2);
510
511 for (const auto& twoTimes : ntuple) {
512 if (!twoTimes.good) continue;
513 double dt = timeBase.getDeltaTime(0, twoTimes.t2, twoTimes.t1);
514 int sample = int(twoTimes.t1) % c_TimeAxisSize;
515 Hcor.Fill(sample, dt);
516 }
517 Hcor.Write();
518
519 B2INFO("... channel " << chan << " OK (chi^2/ndf = " << chi2 / ndf
520 << ", ndf = " << ndf << ")");
521
522 return true;
523 }

◆ myprint()

void myprint ( TH1F * histo,
const char * path,
const char * xtit = "",
const char * ytit = "",
double tresh = 0 )

Print histogram 1D, helper function.

Definition at line 317 of file TOPBackgroundModule.cc.

318 {
319
320 gROOT->Reset();
321 gStyle->SetOptStat("");
322 gStyle->SetOptFit(1111);
323
324 gStyle->SetCanvasColor(-1);
325 gStyle->SetPadColor(-1);
326 gStyle->SetFrameFillColor(-1);
327 gStyle->SetHistFillColor(-1);
328 gStyle->SetTitleFillColor(-1);
329 gStyle->SetFillColor(-1);
330 gStyle->SetFillStyle(4000);
331 gStyle->SetStatStyle(0);
332 gStyle->SetTitleStyle(0);
333 gStyle->SetCanvasBorderSize(0);
334 gStyle->SetCanvasBorderMode(0);
335 gStyle->SetPadBorderMode(0);
336 // gStyle->SetTitleMode(0);
337 gStyle->SetFrameBorderSize(0);
338 gStyle->SetLegendBorderSize(0);
339 gStyle->SetStatBorderSize(0);
340 gStyle->SetTitleBorderSize(0);
341 //gROOT->ForceStyle();*/
342
343
344
345 TCanvas* c1 = new TCanvas("c1", "", 1920, 1200);
346
347 double x1 = histo->GetBinLowEdge(1);
348 double nb = histo->GetNbinsX();
349 double bin = histo->GetBinWidth(1);
350 double x2 = x1 + bin * nb;
351
352 double max = histo->GetBinContent(histo->GetMaximumBin());
353
354 if (max < tresh) {
355 histo->GetYaxis()->SetRangeUser(0, tresh * 1.1);
356 }
357
358 TLine* line = new TLine(x1, tresh, x2, tresh);
359 line->SetLineColor(1);
360 line->SetLineWidth(3);
361 line->SetLineStyle(2);
362
363
364 histo->SetFillColor(2);
365 histo->SetLineColor(1);
366
367 gPad->SetTopMargin(0.08);
368 gPad->SetBottomMargin(0.15);
369 gPad->SetGridy();
370
371 histo->GetXaxis()->SetLabelSize(0.06);
372 histo->GetYaxis()->SetLabelSize(0.06);
373 histo->GetXaxis()->SetTitleSize(0.06);
374 histo->GetYaxis()->SetTitleSize(0.06);
375 histo->GetXaxis()->SetTitle(xtit);
376 histo->GetYaxis()->SetTitle(ytit);
377 histo->GetXaxis()->SetTitleOffset(0.9);
378 histo->GetYaxis()->SetTitleOffset(0.7);
379
380 histo->Draw();
381
382 TLegend* leg = new TLegend(0.75, 0.95, 0.90, 1.00);
383 leg->AddEntry(histo, m_BkgType.c_str(), "pf");
384 leg->Draw("SAME");
385 if (tresh > 0.01) {
386 line->Draw("SAME");
387 }
388
389 c1->Print(path);
390 }

◆ OpticalGunModule()

Constructor.

Definition at line 47 of file OpticalGunModule.cc.

47 : Module()
48 {
49 // set module description
50 setDescription("Source of optical photons");
51 setPropertyFlags(c_ParallelProcessingCertified);
52
53 // Add parameters
54 addParam("x", m_x, "position in x [cm]", 0.0);
55 addParam("y", m_y, "position in y [cm]", 0.0);
56 addParam("z", m_z, "position in z [cm]", 0.0);
57 addParam("diameter", m_diameter, "source diameter [cm]", 0.0);
58 addParam("minAlpha", m_minAlpha, "source minimum emission angle [deg]. ", 0.0);
59 addParam("maxAlpha", m_maxAlpha, "source maximum emission angle [deg]. ", 30.);
60 addParam("na", m_na, "source numerical aperture. It is used only by the Gaussian distribution", 0.50);
61 addParam("angularDistribution", m_angularDistribution,
62 "source angular distribution: uniform, Lambertian, an arbitrary TFormula, or Gaussian "
63 "(numerical aperture instead of minAlpha and maxAlpha). If you are writing a TFormula, "
64 "assume the angles are measured in degrees. The conversion to radians is done internally.",
65 string("Gaussian"));
66 addParam("wavelength", m_wavelength, "wavelength of photons [nm]", 405.0);
67 addParam("phi", m_phi, "first rotation angle (around z) [deg]", 0.0);
68 addParam("theta", m_theta, "second rotation angle (around x) [deg]", 0.0);
69 addParam("psi", m_psi, "third rotation angle (around z) [deg]", 0.0);
70 addParam("startTime", m_startTime,
71 "start time [ns]. If TOPCalPulseGenerator is in path this is relative to the first cal pulse", 0.0);
72 addParam("pulseWidth", m_pulseWidth, "pulse duration (Gaussian sigma) [ns]", 0.0);
73 addParam("numPhotons", m_numPhotons,
74 "average number of photons per pulse, if positive, otherwise exactly one", 0.0);
75 addParam("slotID", m_slotID,
76 "TOP slot ID (1-16): if valid, source position and rotation angles assumed to be given in a local bar frame, "
77 "otherwise Belle II frame is assumed", 0);
78 addParam("slitDX", m_slitDX, "slit size in x [cm], if positive, otherwise full open", 0.0);
79 addParam("slitDY", m_slitDY, "slit size in y [cm], if positive, otherwise full open", 0.0);
80 addParam("slitX0", m_slitX0, "slit x-offset in respect to source [cm] ", 0.0);
81 addParam("slitY0", m_slitY0, "slit y-offset in respect to source [cm] ", 0.0);
82 addParam("slitZ", m_slitZ, "slit distance to source [cm], if > 0.01, otherwise slit full open", 0.0);
83 }

◆ packProductionDebug()

void packProductionDebug ( )
private

Pack in format: Production Debugging Data Format 01.

Definition at line 278 of file TOPPackerModule.cc.

279 {
280 StoreObjPtr<EventMetaData> evtMetaData;
281 StoreArray<TOPRawDigit> digits(m_inputRawDigitsName);
282 StoreArray<RawTOP> rawData(m_outputRawDataName);
283
284 const auto& mapper = m_topgp->getFrontEndMapper();
285 int mapSize = mapper.getMapSize();
286 if (mapSize <= 0) return;
287
288 auto* sortedDigits = new vector<const TOPRawDigit*>[mapSize];
289
290 for (const auto& digit : digits) {
291 auto scrodID = digit.getScrodID();
292 const auto* feemap = mapper.getMap(scrodID);
293 if (!feemap) {
294 B2ERROR("TOPPacker: no front-end map available."
295 << LogVar("scrodID", scrodID));
296 continue;
297 }
298 sortedDigits[feemap->getIndex()].push_back(&digit);
299 }
300
301 unsigned revo9count = 0;
302 unsigned phase = 0;
303 if (digits.getEntries() > 0) {
304 revo9count = digits[0]->getRevo9Counter();
305 phase = digits[0]->getPhase();
306 }
307
308 for (const auto& copperID : mapper.getCopperIDs()) {
309 vector<int> Buffer[4];
310 for (int finesse = 0; finesse < 4; finesse++) {
311 const auto* feemap = mapper.getMapFromCopper(copperID, finesse);
312 if (!feemap) continue;
313 unsigned scrodID = feemap->getScrodID();
314 unsigned format = static_cast<unsigned>(TOP::RawDataType::c_ProductionDebug01);
315
316 unsigned head0 = (format << 16) | (0xA << 12) | (scrodID & 0x0FFF);
317 Buffer[finesse].push_back(head0);
318
319 unsigned numWordsCore = sortedDigits[feemap->getIndex()].size() * 5 + 1;
320 unsigned head1 = ((phase & 0xF) << 12) | (numWordsCore & 0xFFF);
321 Buffer[finesse].push_back(head1);
322
323 unsigned head2 = revo9count & 0xFFFF;
324 Buffer[finesse].push_back(head2);
325
326 unsigned head3 = 0;
327 Buffer[finesse].push_back(head3);
328
329 unsigned Nhits = 0;
330 for (const auto& digit : sortedDigits[feemap->getIndex()]) {
331 unsigned checkSum = 0; // IPv4 checksum
332 unsigned word0 =
333 (digit->getCarrierNumber() << 30) |
334 ((digit->getASICNumber() & 0x3) << 28) |
335 ((digit->getASICChannel() & 0x7) << 25) |
336 ((digit->getASICWindow() & 0x1FF) << 16) |
337 (0xB << 12) |
338 ((digit->getTFine() & 0xF) << 8);
339 checkSum += (word0 & 0xFFFF) + ((word0 >> 16) & 0xFFFF);
340 Buffer[finesse].push_back(word0);
341 unsigned word1 =
342 ((digit->getValuePeak() & 0x1FFF) << 16) |
343 (digit->getIntegral() & 0xFFFF);
344 checkSum += (word1 & 0xFFFF) + ((word1 >> 16) & 0xFFFF);
345 Buffer[finesse].push_back(word1);
346 unsigned word2 =
347 ((digit->getValueRise0() & 0x1FFF) << 16) |
348 (digit->getValueRise1() & 0x1FFF);
349 checkSum += (word2 & 0xFFFF) + ((word2 >> 16) & 0xFFFF);
350 Buffer[finesse].push_back(word2);
351 unsigned word3 =
352 ((digit->getValueFall0() & 0x1FFF) << 16) |
353 (digit->getValueFall1() & 0x1FFF);
354 checkSum += (word3 & 0xFFFF) + ((word3 >> 16) & 0xFFFF);
355 Buffer[finesse].push_back(word3);
356 unsigned word4 =
357 (digit->getSampleRise() << 24) |
358 ((digit->getDeltaSamplePeak() & 0xF) << 20) |
359 ((digit->getDeltaSampleFall() & 0xF) << 16);
360 checkSum += (word4 & 0xFFFF) + ((word4 >> 16) & 0xFFFF);
361 while ((checkSum >> 16) > 0) {
362 checkSum = (checkSum & 0xFFFF) + (checkSum >> 16);
363 }
364 word4 |= ((~checkSum) & 0xFFFF);
365 Buffer[finesse].push_back(word4);
366 Nhits++;
367 }
368 unsigned tail = (0x5 << 9) | (Nhits & 0x1FF);
369 Buffer[finesse].push_back(tail);
370 }
371
372 RawCOPPERPackerInfo info;
373 info.exp_num = evtMetaData->getExperiment();
374 // run number : 14bits, subrun # : 8bits
375 info.run_subrun_num = (evtMetaData->getRun() << 8) +
376 (evtMetaData->getSubrun() & 0xFF);
377 info.eve_num = evtMetaData->getEvent();
378 info.node_id = TOP_ID + copperID;
379 info.tt_ctime = 0;
380 info.tt_utime = 0;
381 info.b2l_ctime = 0;
382 info.hslb_crc16_error_bit = 0;
383 info.truncation_mask = 0;
384 info.type_of_data = 0;
385
386 auto* raw = rawData.appendNew();
387 raw->PackDetectorBuf(Buffer[0].data(), Buffer[0].size(),
388 Buffer[1].data(), Buffer[1].size(),
389 Buffer[2].data(), Buffer[2].size(),
390 Buffer[3].data(), Buffer[3].size(),
391 info);
392 }
393 delete [] sortedDigits;
394 }

◆ packProductionDraft()

void packProductionDraft ( )
private

Pack in format: c_Draft (tentative production format) this format was never implemented in firmware!

Definition at line 115 of file TOPPackerModule.cc.

116 {
117 StoreObjPtr<EventMetaData> evtMetaData;
118 StoreArray<TOPDigit> digits(m_inputDigitsName);
119 StoreArray<RawTOP> rawData(m_outputRawDataName);
120
121 const auto& mapper = m_topgp->getFrontEndMapper();
122 int mapSize = mapper.getMapSize();
123 if (mapSize <= 0) return;
124
125 vector<const TOPDigit*>* sortedDigits = new vector<const TOPDigit*>[mapSize];
126
127 for (const auto& digit : digits) {
128 int moduleID = digit.getModuleID();
129 int boardstack = digit.getChannel() / 128;
130 const auto* feemap = mapper.getMap(moduleID, boardstack);
131 if (!feemap) {
132 B2ERROR("TOPPacker: no front-end map available."
133 << LogVar("moduleID", moduleID)
134 << LogVar("boardstack", boardstack));
135 continue;
136 }
137 sortedDigits[feemap->getIndex()].push_back(&digit);
138 }
139
140 auto subBits = m_topgp->getGeometry()->getNominalTDC().getSubBits();
141 int sampleDivisions = 0x1 << subBits;
142
143 for (const auto& copperID : mapper.getCopperIDs()) {
144 vector<int> Buffer[4];
145 for (int finesse = 0; finesse < 4; finesse++) {
146 const auto* feemap = mapper.getMapFromCopper(copperID, finesse);
147 if (!feemap) continue;
148 unsigned scrodID = feemap->getScrodID();
149 unsigned dataFormat = static_cast<unsigned>(TOP::RawDataType::c_Draft);
150 Buffer[finesse].push_back(scrodID + (dataFormat << 16));
151 for (const auto& digit : sortedDigits[feemap->getIndex()]) {
152 double rawTime = digit->getRawTime();
153 unsigned tdc = int(rawTime * sampleDivisions) & 0xFFFF;
154 unsigned chan = digit->getChannel() % 128;
155 unsigned flags = (unsigned) digit->getHitQuality();
156 Buffer[finesse].push_back(tdc + (chan << 16) + (flags << 24));
157 }
158 }
159 RawCOPPERPackerInfo info;
160 info.exp_num = evtMetaData->getExperiment();
161 // run number : 14bits, subrun # : 8bits
162 info.run_subrun_num = (evtMetaData->getRun() << 8) +
163 (evtMetaData->getSubrun() & 0xFF);
164 info.eve_num = evtMetaData->getEvent();
165 info.node_id = TOP_ID + copperID;
166 info.tt_ctime = 0;
167 info.tt_utime = 0;
168 info.b2l_ctime = 0;
169 info.hslb_crc16_error_bit = 0;
170 info.truncation_mask = 0;
171 info.type_of_data = 0;
172
173 auto* raw = rawData.appendNew();
174 raw->PackDetectorBuf(Buffer[0].data(), Buffer[0].size(),
175 Buffer[1].data(), Buffer[1].size(),
176 Buffer[2].data(), Buffer[2].size(),
177 Buffer[3].data(), Buffer[3].size(),
178 info);
179 }
180 delete [] sortedDigits;
181 }

◆ packType0Ver16()

void packType0Ver16 ( )
private

Pack in format: c_Type0Ver16 (Feature-extracted data) this format was never implemented in firmware!

Definition at line 184 of file TOPPackerModule.cc.

185 {
186 StoreObjPtr<EventMetaData> evtMetaData;
187 StoreArray<TOPRawDigit> digits(m_inputRawDigitsName);
188 StoreArray<RawTOP> rawData(m_outputRawDataName);
189
190 const auto& mapper = m_topgp->getFrontEndMapper();
191 int mapSize = mapper.getMapSize();
192 if (mapSize <= 0) return;
193
194 auto* sortedDigits = new vector<const TOPRawDigit*>[mapSize];
195
196 for (const auto& digit : digits) {
197 auto scrodID = digit.getScrodID();
198 const auto* feemap = mapper.getMap(scrodID);
199 if (!feemap) {
200 B2ERROR("TOPPacker: no front-end map available."
201 << LogVar("scrodID", scrodID));
202 continue;
203 }
204 sortedDigits[feemap->getIndex()].push_back(&digit);
205 }
206
207 for (const auto& copperID : mapper.getCopperIDs()) {
208 vector<int> Buffer[4];
209 for (int finesse = 0; finesse < 4; finesse++) {
210 const auto* feemap = mapper.getMapFromCopper(copperID, finesse);
211 if (!feemap) continue;
212 unsigned scrodID = feemap->getScrodID();
213 unsigned dataFormat = static_cast<unsigned>(TOP::RawDataType::c_Type0Ver16);
214
215 // production data v2.1 (data_format_v2_1.xlsx from Lynn 06/26/2016)
216 unsigned head = (dataFormat << 16) | (0xA << 12) | (scrodID & 0x0FFF);
217 Buffer[finesse].push_back(head);
218 unsigned Nhits = 0;
219 for (const auto& digit : sortedDigits[feemap->getIndex()]) {
220 unsigned word1 =
221 (digit->getCarrierNumber() << 30) |
222 ((digit->getASICNumber() & 0x3) << 28) |
223 ((digit->getASICChannel() & 0x7) << 25) |
224 ((digit->getASICWindow() & 0x1FF) << 16) |
225 (0xB << 12) |
226 ((digit->getTFine() & 0xF) << 8);
227 Buffer[finesse].push_back(word1);
228 unsigned word2 =
229 ((digit->getValuePeak() & 0x1FFF) << 16) |
230 (digit->getIntegral() & 0xFFFF);
231 Buffer[finesse].push_back(word2);
232 unsigned word3 =
233 ((digit->getValueRise0() & 0x1FFF) << 16) |
234 (digit->getValueRise1() & 0x1FFF);
235 Buffer[finesse].push_back(word3);
236 unsigned word4 =
237 ((digit->getValueFall0() & 0x1FFF) << 16) |
238 (digit->getValueFall1() & 0x1FFF);
239 Buffer[finesse].push_back(word4);
240 unsigned word5 =
241 (digit->getSampleRise() << 24) |
242 ((digit->getDeltaSamplePeak() & 0xF) << 20) |
243 ((digit->getDeltaSampleFall() & 0xF) << 16);
244 short checkSum = -(sumShorts(word1) + sumShorts(word2) + sumShorts(word3) +
245 sumShorts(word4) + sumShorts(word5));
246 word5 |= (checkSum & 0xFFFF);
247 Buffer[finesse].push_back(word5);
248 Nhits++;
249 }
250 unsigned tail = (0x5 << 9) | (Nhits & 0x1FF);
251 Buffer[finesse].push_back(tail);
252 }
253 RawCOPPERPackerInfo info;
254 info.exp_num = evtMetaData->getExperiment();
255 // run number : 14bits, subrun # : 8bits
256 info.run_subrun_num = (evtMetaData->getRun() << 8) +
257 (evtMetaData->getSubrun() & 0xFF);
258 info.eve_num = evtMetaData->getEvent();
259 info.node_id = TOP_ID + copperID;
260 info.tt_ctime = 0;
261 info.tt_utime = 0;
262 info.b2l_ctime = 0;
263 info.hslb_crc16_error_bit = 0;
264 info.truncation_mask = 0;
265 info.type_of_data = 0;
266
267 auto* raw = rawData.appendNew();
268 raw->PackDetectorBuf(Buffer[0].data(), Buffer[0].size(),
269 Buffer[1].data(), Buffer[1].size(),
270 Buffer[2].data(), Buffer[2].size(),
271 Buffer[3].data(), Buffer[3].size(),
272 info);
273 }
274 delete [] sortedDigits;
275 }

◆ parseInputDirectoryLine()

int parseInputDirectoryLine ( const std::string & inputString)

Utility function to get the directory name and the label from a line of the m_inputDirectoryList file Sets the values of m_calSetDirectory and m_calSetLabel.

Definition at line 496 of file TOPTBCComparatorModule.cc.

497 {
498 // resets the strings
499 m_calSetDirectory.clear();
500 m_calSetLabel.clear();
501
502 // reads the string char by char to break it up in m_calSetDirectory and m_calSetLabel
503 bool isDirectoryNameChar = true;
504 bool isAtBeginning = true;
505
506 for (std::string::size_type i = 0; i < inputString.size(); ++i) {
507 char c = inputString[i];
508 // The following ifs should catch all the possible cases
509 if (c == ' ' && isAtBeginning) continue; // and empty space at the beginning of the line
510 if (c == ' ' && !isAtBeginning) { // an empty space between the two parts
511 isDirectoryNameChar = false;
512 isAtBeginning = false;
513 continue;
514 }
515 if (c != ' ' && isDirectoryNameChar) { // a good char belonging to the first part of the string
516 m_calSetDirectory += c;
517 isAtBeginning = false;
518 continue;
519 }
520 if (c != ' ' && !isDirectoryNameChar) { // a good char belonging to the second part of the string
521 m_calSetLabel += c;
522 isAtBeginning = false;
523 continue;
524 }
525 B2WARNING("Uncaught exception in parsing the input string. Ending the parsing."); // I should never reach thispoint
526 return 0;
527 }
528
529 return 1;
530 }

◆ parseSlotAndScrodIDfromFileName()

int parseSlotAndScrodIDfromFileName ( const std::string & inputString)

Utility function to parse the slot and BS id from the calibration file names.

Definition at line 534 of file TOPTBCComparatorModule.cc.

535 {
536 // resets the IDs
537 m_slotID = -1;
538 m_boardstackID = -1;
539 m_scrodID = -1;
540
541 // reads the string char by char to break it up in m_calSetDirectory and m_calSetLabel
542
543
544 std::string stringSlot = "";
545 std::string stringBS = "";
546 std::string stringScrod = "";
547
548
549 // We may eventually implement a more clever parsere that is not so sensitive to the file name...
550 //
551 // tbcSlotXX_Y-scrodZZZ.root
552 // tbcSlotXX_Y-scrodZZ.root
553 // 012345678901234567890
554 //
555
556 if (!(inputString[0] == 't' && inputString[1] == 'b' && inputString[2] == 'c')) {
557 B2WARNING(inputString << " is not a valid TBC file. Skipping it.");
558 return 0;
559 }
560 stringSlot += inputString[7];
561 stringSlot += inputString[8];
562 stringBS += inputString[10];
563 stringScrod += inputString[17];
564 stringScrod += inputString[18];
565 if (inputString[19] != '.')
566 stringScrod += inputString[19];
567
568
569 m_slotID = std::stoi(stringSlot);
570 m_scrodID = std::stoi(stringScrod);
571 m_boardstackID = std::stoi(stringBS);
572
573 return 1;
574 }

◆ prepare() [1/11]

void prepare ( )
finalprivatevirtual

Replacement for initialize().

Register calibration dataobjects here as well

Reimplemented from CalibrationCollectorModule.

Definition at line 79 of file TOPAlignmentCollectorModule.cc.

80 {
81 // input collections
82
83 m_digits.isRequired();
84 m_tracks.isRequired();
85 m_extHits.isRequired();
86 m_recBunch.isRequired();
87
88 // check if target module ID is valid
89
90 const auto* geo = TOPGeometryPar::Instance()->getGeometry();
91 if (!geo->isModuleIDValid(m_targetMid)) {
92 B2FATAL("Target module ID = " << m_targetMid << " is invalid. Exiting...");
93 }
94
95 // set track selector
96
97 if (m_sample == "dimuon" or m_sample == "bhabha") {
98 m_selector = TrackSelector(m_sample);
99 m_selector.setDeltaEcms(m_deltaEcms);
100 m_selector.setCutOnPOCA(m_dr, m_dz);
101 m_selector.setCutOnLocalZ(m_minZ, m_maxZ);
102 } else {
103 B2ERROR("Invalid sample type '" << m_sample << "'");
104 }
105
106 // set alignment objects
107
108 for (int set = 0; set < c_numSets; set++) {
109 auto align = ModuleAlignment();
110 align.setModuleID(m_targetMid);
111 align.setSteps(m_stepPosition, m_stepAngle, m_stepTime);
112 align.setParameters(m_parInit);
113 for (const auto& parName : m_parFixed) {
114 align.fixParameter(parName);
115 }
116 m_align.push_back(align);
117 m_countFails.push_back(0);
118 }
119
120 // create and register output histograms and ntuples
121
122 int numModules = geo->getNumModules();
123 auto h1 = new TH2F("tracks_per_slot", "Number of tracks per slot and sample",
124 numModules, 0.5, numModules + 0.5, c_numSets, 0, c_numSets);
125 h1->SetXTitle("slot number");
126 h1->SetYTitle("sample number");
127 registerObject<TH2F>("tracks_per_slot", h1);
128
129 for (int slot = 1; slot <= numModules; slot++) {
130 std::string slotName = "_s" + to_string(slot);
131 std::string slotTitle = "(slot " + to_string(slot) + ")";
132
133 std::string hname = "local_z" + slotName;
134 std::string title = "Distribution of tracks along bar " + slotTitle;
135 auto h2 = new TH1F(hname.c_str(), title.c_str(), 100, -150.0, 150.0);
136 h2->SetXTitle("local z [cm]");
137 registerObject<TH1F>(hname, h2);
138
139 hname = "cth_vs_p" + slotName;
140 title = "Track momentum " + slotTitle;
141 auto h3 = new TH2F(hname.c_str(), title.c_str(), 100, 0.0, 7.0, 100, -1.0, 1.0);
142 h3->SetXTitle("p [GeV/c]");
143 h3->SetYTitle("cos #theta");
144 registerObject<TH2F>(hname, h3);
145
146 hname = "poca_xy" + slotName;
147 title = "Track POCA in x-y " + slotTitle;
148 auto h4 = new TH2F(hname.c_str(), title.c_str(), 100, -m_dr, m_dr, 100, -m_dr, m_dr);
149 h4->SetXTitle("x [cm]");
150 h4->SetYTitle("y [cm]");
151 registerObject<TH2F>(hname, h4);
152
153 hname = "poca_z" + slotName;
154 title = "Track POCA in z " + slotTitle;
155 auto h5 = new TH1F(hname.c_str(), title.c_str(), 100, -m_dz, m_dz);
156 h5->SetXTitle("z [cm]");
157 registerObject<TH1F>(hname, h5);
158
159 hname = "Ecms" + slotName;
160 title = "Track c.m.s. energy " + slotTitle;
161 auto h6 = new TH1F(hname.c_str(), title.c_str(), 100, 5.1, 5.4);
162 h6->SetXTitle("E_{cms} [GeV]");
163 registerObject<TH1F>(hname, h6);
164
165 hname = "charge" + slotName;
166 title = "Charge of track " + slotTitle;
167 auto h7 = new TH1F(hname.c_str(), title.c_str(), 3, -1.5, 1.5);
168 h7->SetXTitle("charge");
169 registerObject<TH1F>(hname, h7);
170
171 hname = "timeHits" + slotName;
172 title = "Photon time distribution " + slotTitle;
173 auto h8 = new TH2F(hname.c_str(), title.c_str(), 512, 0, 512, 200, 0, 50);
174 h8->SetXTitle("channel number");
175 h8->SetYTitle("time [ns]");
176 registerObject<TH2F>(hname, h8);
177
178 hname = "numPhot" + slotName;
179 title = "Number of photons " + slotTitle;
180 auto h9 = new TH1F(hname.c_str(), title.c_str(), 100, 0, 100);
181 h9->SetXTitle("photons per track");
182 registerObject<TH1F>(hname, h9);
183 }
184
185 for (int set = 0; set < c_numSets; set++) {
186 std::string name = "alignTree" + to_string(set);
187 m_treeNames.push_back(name);
188 auto alignTree = new TTree(name.c_str(), "TOP alignment results");
189 alignTree->Branch("ModuleId", &m_targetMid);
190 alignTree->Branch("iter", &m_iter);
191 alignTree->Branch("ntrk", &m_ntrk);
192 alignTree->Branch("errorCode", &m_errorCode);
193 alignTree->Branch("iterPars", &m_vAlignPars);
194 alignTree->Branch("iterParsErr", &m_vAlignParsErr);
195 alignTree->Branch("valid", &m_valid);
196 alignTree->Branch("numPhot", &m_numPhot);
197 alignTree->Branch("x", &m_x);
198 alignTree->Branch("y", &m_y);
199 alignTree->Branch("z", &m_z);
200 alignTree->Branch("p", &m_p);
201 alignTree->Branch("theta", &m_theta);
202 alignTree->Branch("phi", &m_phi);
203 alignTree->Branch("r_poca", &m_pocaR);
204 alignTree->Branch("z_poca", &m_pocaZ);
205 alignTree->Branch("x_poca", &m_pocaX);
206 alignTree->Branch("y_poca", &m_pocaY);
207 alignTree->Branch("Ecms", &m_cmsE);
208 alignTree->Branch("charge", &m_charge);
209 alignTree->Branch("PDG", &m_PDG);
210 registerObject<TTree>(name, alignTree);
211 }
212
213 }

◆ prepare() [2/11]

void prepare ( )
finalprivatevirtual

Replacement for initialize().

Register calibration dataobjects here as well.

Reimplemented from CalibrationCollectorModule.

Definition at line 52 of file TOPAsicShiftsBS13dCollectorModule.cc.

53 {
54
55 m_topDigits.isRequired();
56 if (m_requireRecBunch) {
57 m_recBunch.isRequired();
58 } else {
59 m_recBunch.isOptional();
60 }
61
62 const auto* geo = TOPGeometryPar::Instance()->getGeometry();
63 double timeStep = geo->getNominalTDC().getSyncTimeBase() / 6;
64 double xmi = - m_nx * timeStep / 2;
65 double xma = m_nx * timeStep / 2;
66
67 auto time_vs_BS = new TH2F("time_vs_BS", "time vs BS, slot 13",
68 16, 0.0, 512.0, m_nx, xmi, xma);
69 time_vs_BS->SetXTitle("channel number");
70 time_vs_BS->SetYTitle("time [ns]");
71 registerObject<TH2F>("time_vs_BS", time_vs_BS);
72
73 auto timeReference = new TH1F("time_reference", "time, slot 13(a, b, c)",
74 m_nx, xmi, xma);
75 timeReference->SetXTitle("time [ns]");
76 timeReference->SetYTitle("entries per bin [arbitrary]");
77 registerObject<TH1F>("time_reference", timeReference);
78
79 for (unsigned i = 0; i < 4; i++) {
80 string name = "time_carr_" + to_string(i);
81 string title = "time, slot 13d, carrier " + to_string(i);
82 auto h = new TH1F(name.c_str(), title.c_str(), m_nx, xmi, xma);
83 h->SetXTitle("time [ns]");
84 h->SetYTitle("entries per bin [arbitrary]");
85 registerObject<TH1F>(name, h);
86 }
87
88 }

◆ prepare() [3/11]

void prepare ( )
finalprivatevirtual

Replacement for initialize().

Register calibration dataobjects here as well

Reimplemented from CalibrationCollectorModule.

Definition at line 39 of file TOPChannelMaskCollectorModule.cc.

40 {
41
42 m_digits.isRequired();
43
44 auto nhits = new TH1F("nhits", "Number of good hits per event; hits per event; entries per bin", 200, 0, 2000);
45 registerObject<TH1F>("nhits", nhits);
46
47 for (int slot = 1; slot <= 16; slot++) {
48 string name = "hits_" + to_string(slot);
49 string title = "Channel occupancies for slot " + to_string(slot);
50 auto h = new TH1F(name.c_str(), title.c_str(), 512, 0, 512);
51 h->SetXTitle("channel number");
52 h->SetYTitle("number of hits per channel");
53 registerObject<TH1F>(name, h);
54 m_names.push_back(name);
55 }
56
57 for (int slot = 1; slot <= 16; slot++) {
58 string name = "window_vs_asic_" + to_string(slot);
59 string title = "Window vs. asic for slot " + to_string(slot);
60 auto h = new TH2F(name.c_str(), title.c_str(), 64, 0, 64, 512, 0, 512);
61 h->SetXTitle("ASIC number");
62 h->SetYTitle("window number w.r.t reference window");
63 registerObject<TH2F>(name, h);
64 m_asicNames.push_back(name);
65 }
66
67 }

◆ prepare() [4/11]

void prepare ( )
finalprivatevirtual

Replacement for initialize().

Register calibration dataobjects here as well

Reimplemented from CalibrationCollectorModule.

Definition at line 49 of file TOPCommonT0BFCollectorModule.cc.

50 {
51
52 m_recBunch.isRequired();
53
54 const auto* geo = TOPGeometryPar::Instance()->getGeometry();
55 m_bunchTimeSep = geo->getNominalTDC().getSyncTimeBase() / m_bunchesPerSSTclk;
56
57 auto h1a = new TH1F("offset_a", "current offset; offset [ns]",
58 m_nx, -m_bunchTimeSep / 2, m_bunchTimeSep / 2);
59 registerObject<TH1F>("offset_a", h1a);
60
61 auto h1b = new TH1F("offset_b", "current offset; offset [ns]",
62 m_nx, 0.0, m_bunchTimeSep);
63 registerObject<TH1F>("offset_b", h1b);
64
65 }

◆ prepare() [5/11]

void prepare ( )
finalprivatevirtual

Replacement for initialize().

Register calibration dataobjects here as well

Reimplemented from CalibrationCollectorModule.

Definition at line 75 of file TOPCommonT0LLCollectorModule.cc.

76 {
77 // input collections
78
79 m_digits.isRequired();
80 m_tracks.isRequired();
81 m_extHits.isRequired();
82 m_recBunch.isRequired();
83
84 // bunch time separation
85
86 const auto* geo = TOPGeometryPar::Instance()->getGeometry();
87 m_bunchTimeSep = geo->getNominalTDC().getSyncTimeBase() / m_bunchesPerSSTclk;
88
89 // Parse PDF option
90
91 if (m_pdfOption == "rough") {
92 m_PDFOption = PDFConstructor::c_Rough;
93 } else if (m_pdfOption == "fine") {
94 m_PDFOption = PDFConstructor::c_Fine;
95 } else if (m_pdfOption == "optimal") {
96 m_PDFOption = PDFConstructor::c_Optimal;
97 } else {
98 B2ERROR("Unknown PDF option '" << m_pdfOption << "'");
99 }
100
101 // set track selector
102
103 if (m_sample == "dimuon" or m_sample == "bhabha") {
104 m_selector = TrackSelector(m_sample);
105 m_selector.setDeltaEcms(m_deltaEcms);
106 m_selector.setCutOnPOCA(m_dr, m_dz);
107 m_selector.setCutOnLocalZ(m_minZ, m_maxZ);
108 } else {
109 B2ERROR("Invalid sample type '" << m_sample << "'");
110 }
111
112 // create and register histograms
113
114 double tmin = -m_timeRange / 2;
115 double tmax = m_timeRange / 2;
116 for (unsigned i = 0; i < c_numSets; i++) {
117 string name = "chi2_set" + to_string(i);
118 auto h = new TH1D(name.c_str(), "chi2 scan; t0 [ns]; chi2", m_numBins, tmin, tmax);
119 registerObject<TH1D>(name, h);
120 m_names.push_back(name);
121 }
122
123 auto h1 = new TH1F("tracks_per_set", "tracks per sample; sample number; num tracks",
124 c_numSets, 0, c_numSets);
125 registerObject<TH1F>("tracks_per_set", h1);
126
127 auto h2 = new TH1F("numHits", "Number of photons per slot",
128 c_numModules, 0.5, static_cast<float>(c_numModules) + 0.5);
129 h2->SetXTitle("slot number");
130 h2->SetYTitle("hits per slot");
131 registerObject<TH1F>("numHits", h2);
132
133 auto h3 = new TH2F("timeHits", "Photon times vs. boardstacks",
134 c_numModules * 4, 0.5, static_cast<float>(c_numModules) + 0.5, 200, 0.0, 20.0);
135 h3->SetXTitle("slot number");
136 h3->SetYTitle("time [ns]");
137 registerObject<TH2F>("timeHits", h3);
138
139 // this one is needed primarily to pass bunch time separation to the algorithm,
140 // since DB interface doesn't work there
141 auto h4 = new TH1F("offset", "current offset from input files; offset [ns]",
142 200, -m_bunchTimeSep / 2, m_bunchTimeSep / 2);
143 registerObject<TH1F>("offset", h4);
144
145 }

◆ prepare() [6/11]

void prepare ( )
finalprivatevirtual

Replacement for initialize().

Register calibration dataobjects here as well

Reimplemented from CalibrationCollectorModule.

Definition at line 50 of file TOPModuleT0DeltaTCollectorModule.cc.

51 {
52
53 m_timeZeros.isRequired();
54
55 auto slotPairs = new TH2F("slots", "slot pairs: number of events",
56 16, 0.5, 16.5, 16, 0.5, 16.5);
57 slotPairs->SetXTitle("first slot number");
58 slotPairs->SetYTitle("second slot number");
59 registerObject<TH2F>("slots", slotPairs);
60
61 double xmin = -m_timeRange / 2;
62 double xmax = m_timeRange / 2;
63 for (int slot1 = 1; slot1 <= 9; slot1++) {
64 for (int slot2 = slot1 + 7; slot2 <= slot1 + 9; slot2++) {
65 if (slot2 > 16) continue;
66 string name = "deltaT0_" + to_string(slot1) + "-" + to_string(slot2);
67 string title = "time difference: slot " + to_string(slot1) + " - slot "
68 + to_string(slot2);
69 auto h = new TH1F(name.c_str(), title.c_str(), m_numBins, xmin, xmax);
70 h->SetXTitle("time difference [ns]");
71 registerObject<TH1F>(name, h);
72 }
73 }
74
75 }

◆ prepare() [7/11]

void prepare ( )
finalprivatevirtual

Replacement for initialize().

Register calibration dataobjects here as well

Reimplemented from CalibrationCollectorModule.

Definition at line 75 of file TOPModuleT0LLCollectorModule.cc.

76 {
77 // input collections
78
79 m_digits.isRequired();
80 m_tracks.isRequired();
81 m_extHits.isRequired();
82 m_recBunch.isRequired();
83
84 // Parse PDF option
85
86 if (m_pdfOption == "rough") {
87 m_PDFOption = PDFConstructor::c_Rough;
88 } else if (m_pdfOption == "fine") {
89 m_PDFOption = PDFConstructor::c_Fine;
90 } else if (m_pdfOption == "optimal") {
91 m_PDFOption = PDFConstructor::c_Optimal;
92 } else {
93 B2ERROR("Unknown PDF option '" << m_pdfOption << "'");
94 }
95
96 // set track selector
97
98 if (m_sample == "dimuon" or m_sample == "bhabha") {
99 m_selector = TrackSelector(m_sample);
100 m_selector.setDeltaEcms(m_deltaEcms);
101 m_selector.setCutOnPOCA(m_dr, m_dz);
102 m_selector.setCutOnLocalZ(m_minZ, m_maxZ);
103 } else {
104 B2ERROR("Invalid sample type '" << m_sample << "'");
105 }
106
107 // create and register histograms
108
109 double tmin = -m_timeRange / 2;
110 double tmax = m_timeRange / 2;
111 for (unsigned i = 0; i < c_numSets; i++) {
112 for (int slot = 1; slot <= c_numModules; slot++) {
113 double T0 = 0;
114 if (m_moduleT0->isCalibrated(slot)) T0 = m_moduleT0->getT0(slot);
115 string name = "chi2_set" + to_string(i) + "_slot" + to_string(slot);
116 string title = "chi2 scan, slot" + to_string(slot) + "; t0 [ns]; chi2";
117 auto h = new TH1D(name.c_str(), title.c_str(), m_numBins, tmin + T0, tmax + T0);
118 registerObject<TH1D>(name, h);
119 m_names[i].push_back(name);
120 }
121 }
122
123 auto h1 = new TH2F("tracks_per_slot", "tracks per slot and sample",
124 c_numModules, 0.5, static_cast<float>(c_numModules) + 0.5, c_numSets, 0, c_numSets);
125 h1->SetXTitle("slot number");
126 h1->SetYTitle("sample number");
127 registerObject<TH2F>("tracks_per_slot", h1);
128
129 auto h2 = new TH1F("numHits", "Number of photons per slot",
130 c_numModules, 0.5, static_cast<float>(c_numModules) + 0.5);
131 h2->SetXTitle("slot number");
132 h2->SetYTitle("hits per slot");
133 registerObject<TH1F>("numHits", h2);
134
135 auto h3 = new TH2F("timeHits", "Photon times vs. boardstacks",
136 c_numModules * 4, 0.5, static_cast<float>(c_numModules) + 0.5, 200, 0.0, 20.0);
137 h3->SetXTitle("slot number");
138 h3->SetYTitle("time [ns]");
139 registerObject<TH2F>("timeHits", h3);
140
141 const auto* geo = TOPGeometryPar::Instance()->getGeometry();
142 double bunchTimeSep = geo->getNominalTDC().getSyncTimeBase() / 24;
143 auto h4 = new TH1F("offset", "current offset from input files; offset [ns]",
144 200, -bunchTimeSep / 2, bunchTimeSep / 2);
145 registerObject<TH1F>("offset", h4);
146
147 }

◆ prepare() [8/11]

void prepare ( )
finalprivatevirtual

Replacement for initialize().

Register calibration dataobjects here as well

Reimplemented from CalibrationCollectorModule.

Definition at line 40 of file TOPOffsetCollectorModule.cc.

41 {
42 m_recBunch.isRequired();
43 m_eventT0.isRequired();
44
45 m_names[Const::SVD] = "svdOffset";
46 m_names[Const::CDC] = "cdcOffset";
47 for (const auto& x : m_names) {
48 registerObject<TH1F>(x.second, new TH1F(x.second.c_str(), "Event T0 difference w.r.t TOP; #Delta T_{0} [ns]",
49 500, -50, 50));
50 }
51
52 int RFBuckets = m_bunchStructure->getRFBucketsPerRevolution();
53 registerObject<TH1F>("fillPattern", new TH1F("fillPattern", "Fill pattern from DB; bucket number",
54 RFBuckets, 0, RFBuckets));
55 registerObject<TH1F>("recBuckets", new TH1F("recBuckets", "Reconstructed buckets; bucket number",
56 RFBuckets, 0, RFBuckets));
57 }

◆ prepare() [9/11]

void prepare ( )
finalprivatevirtual

Replacement for initialize().

Register calibration dataobjects here as well

Reimplemented from CalibrationCollectorModule.

Definition at line 58 of file TOPPhotonYieldsCollectorModule.cc.

59 {
60 // input collections
61 m_digits.isRequired();
62 m_tracks.isRequired();
63 m_extHits.isRequired();
64 m_recBunch.isRequired();
65 m_asicMask.isRequired();
66 m_associatedPDFs.isRequired();
67
68 // set track selector
69 if (m_sample == "dimuon" or m_sample == "bhabha") {
70 m_selector = TrackSelector(m_sample);
71 m_selector.setDeltaEcms(m_deltaEcms);
72 m_selector.setCutOnPOCA(m_dr, m_dz);
73 m_selector.setCutOnLocalZ(m_minZprism, m_maxZ);
74 } else {
75 B2ERROR("Invalid sample type '" << m_sample << "'");
76 }
77
78 // create and register histograms
79
80 const int numModules = 16;
81 const int numPixels = 512;
82
83 // TOF corrections
84 auto* tofCorrections = new TProfile("tofCorrections", "TOF corrections; local z [cm]; t0 [ns]", 1000, m_minZprism, m_maxZ, -1, 1);
85 registerObject<TProfile>("tofCorrections", tofCorrections);
86
87 // time stamp (average unix time and its standard deviation)
88 auto* timeStamp = new TProfile("timeStamp", "Time stamp; ; unix time", 1, 0, 1, 0, 1.0e10, "S");
89 registerObject<TProfile>("timeStamp", timeStamp);
90
91 // number of selected tracks per slot
92 auto* numTracks = new TH1F("numTracks", "Number of tracks per slot; slot number; track count", numModules, 0.5, numModules + 0.5);
93 registerObject<TH1F>("numTracks", numTracks);
94
95 // number of pixel hits in a signal time window
96 for (int slot = 1; slot <= numModules; slot++) {
97 string name = (slot < 10) ? "signalHits_0" + to_string(slot) : "signalHits_" + to_string(slot);
98 string title = "Hits in signal window for slot " + to_string(slot);
99 auto h = new TH1F(name.c_str(), title.c_str(), numPixels, 0.5, numPixels + 0.5);
100 h->SetXTitle("pixel number");
101 h->SetYTitle("hit count");
102 registerObject<TH1F>(name, h);
103 m_signalNames.push_back(name);
104 }
105
106 // number of pixel hits in a background time window
107 for (int slot = 1; slot <= numModules; slot++) {
108 string name = (slot < 10) ? "bkgHits_0" + to_string(slot) : "bkgHits_" + to_string(slot);
109 string title = "Hits in background window for slot " + to_string(slot);
110 auto h = new TH1F(name.c_str(), title.c_str(), numPixels, 0.5, numPixels + 0.5);
111 h->SetXTitle("pixel number");
112 h->SetYTitle("hit count");
113 registerObject<TH1F>(name, h);
114 m_bkgNames.push_back(name);
115 }
116
117 // active pixels
118 for (int slot = 1; slot <= numModules; slot++) {
119 string name = (slot < 10) ? "activePixels_0" + to_string(slot) : "activePixels_" + to_string(slot);
120 string title = "Active pixels for slot " + to_string(slot);
121 auto h = new TH1F(name.c_str(), title.c_str(), numPixels, 0.5, numPixels + 0.5);
122 h->SetXTitle("pixel number");
123 h->SetYTitle("track count");
124 registerObject<TH1F>(name, h);
125 m_activeNames.push_back(name);
126 }
127
128 // number of effective signal hits in pixels
129 for (int slot = 1; slot <= numModules; slot++) {
130 string name = (slot < 10) ? "effectiveSignalHits_0" + to_string(slot) : "effectiveSignalHits_" + to_string(slot);
131 string title = "Effective signal hits for slot " + to_string(slot);
132 auto h = new TH1F(name.c_str(), title.c_str(), numPixels, 0.5, numPixels + 0.5);
133 h->SetXTitle("pixel number");
134 h->SetYTitle("hit count");
135 registerObject<TH1F>(name, h);
136 m_effectiveSignalNames.push_back(name);
137 }
138
139 // number of pixel hits with low impact angle on photo cathode
140 for (int slot = 1; slot <= numModules; slot++) {
141 string name = (slot < 10) ? "alphaLow_0" + to_string(slot) : "alphaLow_" + to_string(slot);
142 string title = "Hits w/ low alpha for slot " + to_string(slot);
143 auto h = new TH1F(name.c_str(), title.c_str(), numPixels, 0.5, numPixels + 0.5);
144 h->SetXTitle("pixel number");
145 h->SetYTitle("hit count");
146 registerObject<TH1F>(name, h);
147 m_alphaLowNames.push_back(name);
148 }
149
150 // number of pixel hits with high impact angle on photo cathode
151 for (int slot = 1; slot <= numModules; slot++) {
152 string name = (slot < 10) ? "alphaHigh_0" + to_string(slot) : "alphaHigh_" + to_string(slot);
153 string title = "Hits w/ high alpha for slot " + to_string(slot);
154 auto h = new TH1F(name.c_str(), title.c_str(), numPixels, 0.5, numPixels + 0.5);
155 h->SetXTitle("pixel number");
156 h->SetYTitle("hit count");
157 registerObject<TH1F>(name, h);
158 m_alphaHighNames.push_back(name);
159 }
160
161 // pixel pulse-height distributions
162 for (int slot = 1; slot <= numModules; slot++) {
163 string name = (slot < 10) ? "pulseHeights_0" + to_string(slot) : "pulseHeights_" + to_string(slot);
164 string title = "Pulse height distributions for slot " + to_string(slot);
165 auto h = new TH2F(name.c_str(), title.c_str(), numPixels, 0.5, numPixels + 0.5, 200, 0, 2000);
166 h->SetXTitle("pixel number");
167 h->SetYTitle("pulse height");
168 registerObject<TH2F>(name, h);
169 m_pulseHeightNames.push_back(name);
170 }
171
172 // local z-distribution of tracks
173 for (int slot = 1; slot <= numModules; slot++) {
174 string name = (slot < 10) ? "muonZ_0" + to_string(slot) : "muonZ_" + to_string(slot);
175 string title = "Track z-distribution for slot " + to_string(slot);
176 auto h = new TH1F(name.c_str(), title.c_str(), 100, m_minZ, m_maxZ);
177 h->SetXTitle("local z [cm]");
178 h->SetYTitle("track count");
179 registerObject<TH1F>(name, h);
180 m_muonZNames.push_back(name);
181 }
182
183 }

◆ prepare() [10/11]

void prepare ( )
finalprivatevirtual

Replacement for initialize().

Register calibration dataobjects here as well

Reimplemented from CalibrationCollectorModule.

Definition at line 52 of file TOPPulseHeightCollectorModule.cc.

53 {
54
55 m_digits.isRequired();
56
57 auto h1a = new TH1F("time", "time distribution (all hits)", 1000, -100, 250);
58 h1a->SetXTitle("time [ns]");
59 registerObject<TH1F>("time", h1a);
60
61 auto h1b = new TH1F("time_sel", "time distribution (selected hits)", 1000, -100, 250);
62 h1b->SetXTitle("time [ns]");
63 registerObject<TH1F>("time_sel", h1b);
64
65 auto h2a = new TH2F("ph_vs_width", "pulse height vs. width (all hits)",
66 200, 0, 10, 200, 0, 2000);
67 h2a->SetXTitle("pulse width [ns]");
68 h2a->SetYTitle("pulse height [ADC counts]");
69 registerObject<TH2F>("ph_vs_width", h2a);
70
71 auto h2b = new TH2F("ph_vs_width_sel", "pulse height vs. width (selected hits)",
72 200, 0, 10, 200, 0, 2000);
73 h2b->SetXTitle("pulse width [ns]");
74 h2b->SetYTitle("pulse height [ADC counts]");
75 registerObject<TH2F>("ph_vs_width_sel", h2b);
76
77 for (int slot = 1; slot <= 16; slot++) {
78 string name = "ph_slot_" + to_string(slot);
79 string title = "pulse-height vs. channel for slot " + to_string(slot);
80 auto h = new TH2F(name.c_str(), title.c_str(), 512, 0, 512, m_nx, 0, m_xmax);
81 h->SetXTitle("channel number");
82 h->SetYTitle("pulse height [ADC counts]");
83 registerObject<TH2F>(name, h);
84 m_names.push_back(name);
85 }
86
87 }

◆ prepare() [11/11]

void prepare ( )
finalprivatevirtual

Replacement for initialize().

Register calibration dataobjects here as well

Reimplemented from CalibrationCollectorModule.

Definition at line 76 of file TOPValidationCollectorModule.cc.

77 {
78 // input collections
79
80 m_digits.isRequired();
81 m_tracks.isRequired();
82 m_extHits.isRequired();
83 m_recBunch.isRequired();
84
85 // Parse PDF option
86
87 if (m_pdfOption == "rough") {
88 m_PDFOption = PDFConstructor::c_Rough;
89 } else if (m_pdfOption == "fine") {
90 m_PDFOption = PDFConstructor::c_Fine;
91 } else if (m_pdfOption == "optimal") {
92 m_PDFOption = PDFConstructor::c_Optimal;
93 } else {
94 B2ERROR("Unknown PDF option '" << m_pdfOption << "'");
95 }
96
97 // set track selector
98
99 if (m_sample == "dimuon" or m_sample == "bhabha") {
100 m_selector = TrackSelector(m_sample);
101 m_selector.setDeltaEcms(m_deltaEcms);
102 m_selector.setCutOnPOCA(m_dr, m_dz);
103 m_selector.setCutOnLocalZ(m_minZ, m_maxZ);
104 } else {
105 B2ERROR("Invalid sample type '" << m_sample << "'");
106 }
107
108 // create chi2 minimum finders
109
110 double tmin = -m_timeRange / 2;
111 double tmax = m_timeRange / 2;
112 for (int set = 0; set < c_numSets; set++) {
113 for (int slot = 1; slot <= c_numModules; slot++) {
114 m_finders[set].push_back(Chi2MinimumFinder1D(m_numBins, tmin, tmax));
115 }
116 }
117
118 // create and register histograms and tree
119
120 for (int slot = 1; slot <= c_numModules; slot++) {
121 string slotName = to_string(slot);
122 if (slot < 10) slotName.insert(0, "0");
123 string name = "chi2_slot" + slotName;
124 string title = "Chi2 scan, slot" + slotName + "; channel; t0 [ns]";
125 auto h = new TH2F(name.c_str(), title.c_str(), c_numChannels, 0, c_numChannels, m_numBins, tmin, tmax);
126 registerObject<TH2F>(name, h);
127 m_namesChi.push_back(name);
128 }
129
130 for (int slot = 1; slot <= c_numModules; slot++) {
131 string slotName = to_string(slot);
132 if (slot < 10) slotName.insert(0, "0");
133 string name = "hits_slot" + slotName;
134 string title = "Photon hits, slot" + slotName + "; channel; time [ns]";
135 auto h = new TH2F(name.c_str(), title.c_str(), c_numChannels, 0, c_numChannels, 100, 0., 20.);
136 registerObject<TH2F>(name, h);
137 m_namesHit.push_back(name);
138 }
139
140 auto h = new TH1F("moduleT0_pulls", "Module T0 pulls; pulls", 200, -15.0, 15.0);
141 registerObject<TH1F>("moduleT0_pulls", h);
142
143 auto tree = new TTree("tree", "TOP calibration validation tree");
144 tree->Branch("expNo", &m_treeEntry.expNo, "expNo/I");
145 tree->Branch("runNo", &m_treeEntry.runNo, "runNo/I");
146 tree->Branch("numTracks", &m_treeEntry.numTracks, "numTracks/I");
147 tree->Branch("commonT0", &m_treeEntry.commonT0, "commonT0/F");
148 tree->Branch("commonT0Err", &m_treeEntry.commonT0Err, "commonT0Err/F");
149 tree->Branch("moduleT0", &m_treeEntry.moduleT0, "moduleT0[16]/F");
150 tree->Branch("moduleT0Err", &m_treeEntry.moduleT0Err, "moduleT0Err[16]/F");
151 tree->Branch("numTBCalibrated", &m_treeEntry.numTBCalibrated, "numTBCalibrated[16]/I");
152 tree->Branch("numT0Calibrated", &m_treeEntry.numT0Calibrated, "numT0Calibrated[16]/I");
153 tree->Branch("numActive", &m_treeEntry.numActive, "numActive[16]/I");
154 tree->Branch("numActiveCalibrated", &m_treeEntry.numActiveCalibrated, "numActiveCalibrated[16]/I");
155 tree->Branch("thrEffi", &m_treeEntry.thrEffi, "thrEffi[16]/F");
156 tree->Branch("asicShifts", &m_treeEntry.asicShifts, "asicShifts[4]/F");
157 tree->Branch("svdOffset", &m_treeEntry.svdOffset, "svdOffset/F");
158 tree->Branch("svdSigma", &m_treeEntry.svdSigma, "svdSigma/F");
159 tree->Branch("cdcOffset", &m_treeEntry.cdcOffset, "cdcOffset/F");
160 tree->Branch("cdcSigma", &m_treeEntry.cdcSigma, "cdcSigma/F");
161 tree->Branch("fillPatternOffset", &m_treeEntry.fillPatternOffset, "fillPatternOffset/F");
162 tree->Branch("fillPatternFraction", &m_treeEntry.fillPatternFraction, "fillPatternFraction/F");
163 registerObject<TTree>("tree", tree);
164 }

◆ printTheError()

bool printTheError ( )
private

Error messages suppression logic.

Returns
true to print the error message, false to suppress it

Definition at line 236 of file TOPUnpackerModule.cc.

237 {
238 if (m_eventCount < m_errorSuppressFactor * m_numErrors) return false;
239 m_errorCount++;
240 m_resetEventCount = true;
241 return true;
242 }

◆ saveAsHistogram() [1/4]

void saveAsHistogram ( const std::vector< double > & vec,
const std::string & name,
const std::string & title,
const std::string & xTitle = "",
const std::string & yTitle = "" )
staticprivate

Save vector to histogram and write it out.

Parameters
vecvector of bin values
namehistogram name
titlehistogram title
xTitlex-axis title
yTitley-axis title

Definition at line 285 of file TOPDoublePulseGeneratorModule.cc.

290 {
291 if (vec.empty()) return;
292
293 TH1F h(name.c_str(), title.c_str(), vec.size(), 0, vec.size());
294 h.SetXTitle(xTitle.c_str());
295 h.SetYTitle(yTitle.c_str());
296 if (name.find("Fit") != string::npos) h.SetLineColor(2);
297
298 for (unsigned i = 0; i < vec.size(); i++) h.SetBinContent(i + 1, vec[i]);
299
300 h.Write();
301 }

◆ saveAsHistogram() [2/4]

void saveAsHistogram ( const std::vector< double > & vec,
const std::string & name,
const std::string & title,
const std::string & xTitle = "",
const std::string & yTitle = "" )
staticprivate

Save vector to histogram and write it out.

Parameters
vecvector of bin values
namehistogram name
titlehistogram title
xTitlex-axis title
yTitley-axis title

Definition at line 697 of file TOPTimeBaseCalibratorModule.cc.

702 {
703 if (vec.empty()) return;
704
705 TH1F h(name.c_str(), title.c_str(), vec.size(), 0, vec.size());
706 h.SetXTitle(xTitle.c_str());
707 h.SetYTitle(yTitle.c_str());
708 if (name.find("Fit") != string::npos) h.SetLineColor(2);
709
710 for (unsigned i = 0; i < vec.size(); i++) h.SetBinContent(i + 1, vec[i]);
711
712 h.Write();
713 }

◆ saveAsHistogram() [3/4]

void saveAsHistogram ( const std::vector< double > & vec,
const std::vector< double > & err,
const std::string & name,
const std::string & title,
const std::string & xTitle = "",
const std::string & yTitle = "" )
staticprivate

Save vector and errors to histogram and write it out.

Parameters
vecvector of bin values
errvector of bin errors
namehistogram name
titlehistogram title
xTitlex-axis title
yTitley-axis title

Definition at line 716 of file TOPTimeBaseCalibratorModule.cc.

722 {
723 if (vec.empty()) return;
724
725 TH1F h(name.c_str(), title.c_str(), vec.size(), 0, vec.size());
726 h.SetXTitle(xTitle.c_str());
727 h.SetYTitle(yTitle.c_str());
728
729 for (unsigned i = 0; i < vec.size(); i++) h.SetBinContent(i + 1, vec[i]);
730 for (unsigned i = 0; i < err.size(); i++) h.SetBinError(i + 1, err[i]);
731
732 h.Write();
733 }

◆ saveAsHistogram() [4/4]

void saveAsHistogram ( const TMatrixDSym & M,
const std::string & name,
const std::string & title )
staticprivate

Save matrix to histogram and write it out.

Parameters
Mmatrix
namehistogram name
titlehistogram title

Definition at line 736 of file TOPTimeBaseCalibratorModule.cc.

739 {
740 int n = M.GetNrows();
741 TH2F h(name.c_str(), title.c_str(), n, 0, n, n, 0, n);
742 h.SetXTitle("columns");
743 h.SetYTitle("rows");
744
745 for (int j = 0; j < n; j++) {
746 for (int k = 0; k < n; k++) {
747 h.SetBinContent(j + 1, n - k, M(j, k));
748 }
749 }
750
751 h.Write();
752 }

◆ setFinder()

int setFinder ( TOP::Chi2MinimumFinder1D & finder,
const TOP::PDFConstructor & reco,
double timeMin,
double timeMax )
private

Sets finder object with chi2 values.

Parameters
finderfinder object
recoreconstruction object
timeMinlower edge of photon time window
timeMaxupper edge of photon time window
Returns
number of photons in the time window

Definition at line 623 of file TOPBunchFinderModule.cc.

624 {
625 std::set<int> nfotSet; // for control only
626 const auto& binCenters = finder.getBinCenters();
627 int numPhotons = 0;
628 double logL_bkg = reco.getBackgroundLogL(timeMin, timeMax).logL;
629 for (unsigned i = 0; i < binCenters.size(); i++) {
630 double t0 = binCenters[i];
631 auto LL = reco.getLogL(t0, timeMin, timeMax, m_sigmaSmear);
632 finder.add(i, -2 * (LL.logL - logL_bkg));
633 if (i == 0) numPhotons = LL.numPhotons;
634 nfotSet.insert(LL.numPhotons);
635 }
636
637 if (nfotSet.size() != 1) B2ERROR("Different number of photons used for log likelihood of different time shifts");
638
639 return numPhotons;
640 }

◆ startRun() [1/2]

void startRun ( )
finalprivatevirtual

Replacement for beginRun().

Do anything you would normally do in beginRun here

Reimplemented from CalibrationCollectorModule.

Definition at line 60 of file TOPOffsetCollectorModule.cc.

61 {
62 auto h = getObjectPtr<TH1F>("fillPattern");
63 if (m_bunchStructure->isSet()) {
64 int RFBuckets = m_bunchStructure->getRFBucketsPerRevolution();
65 for (int i = 0; i < RFBuckets; i++) {
66 if (m_bunchStructure->getBucket(i)) h->SetBinContent(i + 1, 1);
67 }
68 }
69 }

◆ startRun() [2/2]

void startRun ( )
finalprivatevirtual

Replacement for beginRun().

Do anything you would normally do in beginRun here

Reimplemented from CalibrationCollectorModule.

Definition at line 167 of file TOPValidationCollectorModule.cc.

168 {
169 // initialize tree variables
170
171 m_treeEntry.clear();
172 StoreObjPtr<EventMetaData> evtMetaData;
173 m_treeEntry.expNo = evtMetaData->getExperiment();
174 m_treeEntry.runNo = evtMetaData->getRun();
175
176 // clear minimum finders
177
178 for (auto& finders : m_finders) {
179 for (auto& finder : finders) finder.clear();
180 }
181
182 // pass payload summaries to tree
183
184 const auto& fe_mapper = TOPGeometryPar::Instance()->getFrontEndMapper();
185 for (unsigned module = 0; module < c_numModules; module++) {
186 auto& numTBCalibrated = m_treeEntry.numTBCalibrated[module];
187 auto& numT0Calibrated = m_treeEntry.numT0Calibrated[module];
188 auto& numActive = m_treeEntry.numActive[module];
189 auto& numActiveCalibrated = m_treeEntry.numActiveCalibrated[module];
190 auto& thrEffi = m_treeEntry.thrEffi[module];
191 int slot = module + 1;
192 for (unsigned channel = 0; channel < c_numChannels; channel++) {
193 bool tbCalibrated = false;
194 const auto* fe = fe_mapper.getMap(slot, channel / 128);
195 if (fe) {
196 tbCalibrated = m_timebase->isAvailable(fe->getScrodID(), channel);
197 } else {
198 B2ERROR("No front-end map found");
199 }
200 bool t0Calibrated = m_channelT0->isCalibrated(slot, channel);
201 bool active = m_channelMask->isActive(slot, channel);
202 if (tbCalibrated) numTBCalibrated++;
203 if (t0Calibrated) numT0Calibrated++;
204 if (active) numActive++;
205 if (tbCalibrated and t0Calibrated and active) {
206 numActiveCalibrated++;
207 thrEffi += m_thresholdEff->getThrEff(slot, channel);
208 }
209 }
210 if (numActiveCalibrated > 0) thrEffi /= numActiveCalibrated;
211 }
212
213 for (unsigned carrier = 0; carrier < 4; carrier++) {
214 unsigned asic = (3 * 4 + carrier) * 4;
215 m_treeEntry.asicShifts[carrier] = m_asicShift->isCalibrated(13, asic) ? m_asicShift->getT0(13, asic) :
216 std::numeric_limits<float>::quiet_NaN();
217 }
218
219 const auto& svd = m_eventT0Offset->get(Const::SVD);
220 m_treeEntry.svdOffset = svd.offset;
221 m_treeEntry.svdSigma = svd.sigma;
222
223 const auto& cdc = m_eventT0Offset->get(Const::CDC);
224 m_treeEntry.cdcOffset = cdc.offset;
225 m_treeEntry.cdcSigma = cdc.sigma;
226
227 m_treeEntry.fillPatternOffset = m_fillPatternOffset->isCalibrated() ? m_fillPatternOffset->get() :
228 std::numeric_limits<float>::quiet_NaN();
229 m_treeEntry.fillPatternFraction = m_fillPatternOffset->getFraction();
230 }

◆ storeSampleTimes()

void storeSampleTimes ( const std::string & fileName)
private

Optionally store sample times used by the generator as root histograms fileName root output file name.

Definition at line 214 of file TOPDoublePulseGeneratorModule.cc.

215 {
216 if (fileName.empty()) return;
217
218 TFile* fout = TFile::Open(fileName.c_str(), "recreate");
219 if (!fout) {
220 B2ERROR("Can't open the output file " << fileName);
221 return;
222 }
223
224 const auto& feMapper = TOPGeometryPar::Instance()->getFrontEndMapper();
225
226 TH1F scrods("scrodID", "scrod ID's mapped to slots/boardstacks", 64, -0.5, 63.5);
227 scrods.SetXTitle("(slot - 1) * 4 + boardstack");
228 scrods.SetYTitle("scrod ID");
229
230 for (auto moduleID : m_moduleIDs) {
231 for (int bs = 0; bs < 4; bs++) {
232 const auto* feMap = feMapper.getMap(moduleID, bs);
233 if (!feMap) {
234 B2ERROR("No front-end mapping available for slot " << moduleID
235 << " boardstack " << bs);
236 continue;
237 }
238 unsigned scrodID = feMap->getScrodID();
239 std::string subdir = "scrod" + std::to_string(scrodID);
240 int i = (moduleID - 1) * 4 + bs;
241 scrods.SetBinContent(i + 1, scrodID);
242 fout->mkdir(subdir.c_str());
243 }
244 }
245 scrods.Write();
246
247 for (auto moduleID : m_moduleIDs) {
248 for (unsigned asic = 0; asic < 64; asic++) {
249 int bs = asic / 16;
250 const auto* feMap = feMapper.getMap(moduleID, bs);
251 if (!feMap) continue;
252 unsigned scrodID = feMap->getScrodID();
253 std::string subdir = "scrod" + std::to_string(scrodID);
254 fout->cd(subdir.c_str());
255 for (auto asicChannel : m_asicChannels) {
256 unsigned channel = (asic * 8 + asicChannel) % 128;
257 const TOPSampleTimes* sampleTimes = &m_sampleTimes;
258 if (m_useDatabase) {
259 sampleTimes = m_timebase->getSampleTimes(scrodID, channel);
260 }
261 string forWhat = "scrod " + to_string(scrodID) +
262 " channel " + to_string(channel) +
263 " (slot" + to_string(moduleID) + ", as" + to_string(asic) +
264 ", ch" + to_string(asicChannel) + ")";
265 auto timeAxis = sampleTimes->getTimeAxis();
266 saveAsHistogram(timeAxis, "sampleTimes_ch" + to_string(channel),
267 "Generator input: sample times for " + forWhat,
268 "sample number", "t [ns]");
269 std::vector<double> dt;
270 for (unsigned i = 1; i < timeAxis.size(); i++) {
271 dt.push_back(timeAxis[i] - timeAxis[i - 1]);
272 }
273 saveAsHistogram(dt, "dt_ch" + to_string(channel),
274 "Generator input: sample time bins for " + forWhat,
275 "sample number", "#Delta t [ns]");
276 }
277 }
278 }
279
280 fout->Close();
281
282 }

◆ terminate() [1/14]

void terminate ( void )
overridevirtual

Termination action.

Clean-up, close files, summarize statistics, etc.

Reimplemented from Module.

Definition at line 252 of file TOPAlignerModule.cc.

253 {
254
255 m_file->cd();
256 m_alignTree->Write();
257
258 TH1F valid("valid", "status valid", 16, 0.5, 16.5);
259 valid.SetXTitle("slot ID");
260 valid.SetBinContent(m_targetMid, m_valid);
261 valid.Write();
262
263 TH1F ntrk("ntrk", "number of tracks", 16, 0.5, 16.5);
264 ntrk.SetXTitle("slot ID");
265 ntrk.SetBinContent(m_targetMid, m_ntrk);
266 ntrk.Write();
267
268 std::string name, title;
269 name = "results_slot" + to_string(m_targetMid);
270 title = "alignment parameters, slot " + to_string(m_targetMid);
271 int npar = m_align.getParams().size();
272 TH1F h0(name.c_str(), title.c_str(), npar, 0, npar);
273 const auto& par = m_align.getParams();
274 const auto& err = m_align.getErrors();
275 for (int i = 0; i < npar; i++) {
276 h0.SetBinContent(i + 1, par[i]);
277 h0.SetBinError(i + 1, err[i]);
278 }
279 h0.Write();
280
281 name = "errMatrix_slot" + to_string(m_targetMid);
282 title = "error matrix, slot " + to_string(m_targetMid);
283 TH2F h1(name.c_str(), title.c_str(), npar, 0, npar, npar, 0, npar);
284 const auto& errMatrix = m_align.getErrorMatrix();
285 for (int i = 0; i < npar; i++) {
286 for (int k = 0; k < npar; k++) {
287 h1.SetBinContent(i + 1, k + 1, errMatrix[i][k]);
288 }
289 }
290 h1.Write();
291
292 name = "corMatrix_slot" + to_string(m_targetMid);
293 title = "correlation matrix, slot " + to_string(m_targetMid);
294 TH2F h2(name.c_str(), title.c_str(), npar, 0, npar, npar, 0, npar);
295 std::vector<double> diag;
296 for (int i = 0; i < npar; i++) {
297 double d = errMatrix[i][i];
298 if (d != 0) d = 1.0 / sqrt(d);
299 diag.push_back(d);
300 }
301 for (int i = 0; i < npar; i++) {
302 for (int k = 0; k < npar; k++) {
303 h2.SetBinContent(i + 1, k + 1, diag[i] * diag[k] * errMatrix[i][k]);
304 }
305 }
306 h2.Write();
307
308 m_file->Close();
309
310 if (m_valid) {
311 B2RESULT("TOPAligner: slot = " << m_targetMid << ", status = successful, "
312 << "iterations = " << m_iter << ", tracks used = " << m_ntrk);
313 } else {
314 B2RESULT("TOPAligner: slot = " << m_targetMid << ", status = failed, "
315 << "error code = " << m_errorCode
316 << ", iterations = " << m_iter << ", tracks used = " << m_ntrk);
317 }
318 }

◆ terminate() [2/14]

void terminate ( void )
overridevirtual

Termination action.

Clean-up, close files, summarize statistics, etc.

Reimplemented from Module.

Definition at line 399 of file TOPBackgroundModule.cc.

400 {
401 /*
402 myprint(peflux, ("peflux_" + m_BkgType + ".pdf").c_str(), "#phi", "MHz / PMT", 1.);
403 myprint(zdist, ("zdist_" + m_BkgType + ".pdf").c_str(), "z[cm]", "", 0.0);
404 myprint(nflux, ("nflux_" + m_BkgType + ".pdf").c_str(), "#phi", "neutrons / cm^{2} / year", 0.0);
405 myprint(rdose, ("rdose_" + m_BkgType + ".pdf").c_str(), "#phi", "Gy/year", 0.0);
406 */
407
408 m_rootFile->cd();
409 origingamma->Write();
410 originpe->Write();
411 peflux->Write();
412 zdist->Write();
413 nflux->Write();
414 rdose->Write();
415 genergy->Write();
416 genergy2->Write();
417 nflux_bar->Write();
418 gflux_bar->Write();
419 origin_zx->Write();
420 origin_zy->Write();
421 module_occupancy->Write();
422 gorigin->Write();
423 norigin->Write();
424 zdistg->Write();
425 originpt->Write();
426 m_rootFile->Close();
427
428 // Announce
429 B2INFO("TOPBackground finished");
430
431
432 }

◆ terminate() [3/14]

void terminate ( void )
overridevirtual

Termination action.

Clean-up, close files, summarize statistics, etc.

Reimplemented from Module.

Definition at line 557 of file TOPBunchFinderModule.cc.

558 {
559 B2RESULT("TOPBunchFinder: event T0 determined for " << m_success << "/"
560 << m_processed << " events");
561 }

◆ terminate() [4/14]

void terminate ( void )
overridevirtual

Termination action.

Clean-up, close files, summarize statistics, etc.

Reimplemented from Module.

Definition at line 259 of file TOPChannelT0CalibratorModule.cc.

260 {
261
262 // determine scaling factor for errors from two statistically independent results
263
264 TH1F h_pulls("pulls", "Pulls of the two statistically independent results",
265 200, -15.0, 15.0);
266 h_pulls.SetXTitle("pulls");
267 for (unsigned module = 0; module < c_numModules; module++) {
268 for (unsigned channel = 0; channel < c_numChannels; channel++) {
269 std::vector<double> pos, err;
270 for (int i = 0; i < 2; i++) {
271 const auto& minimum = m_finders[i][module][channel].getMinimum();
272 if (not minimum.valid) continue;
273 pos.push_back(minimum.position);
274 err.push_back(minimum.error);
275 }
276 if (pos.size() < 2) continue;
277 double pull = (pos[0] - pos[1]) / sqrt(err[0] * err[0] + err[1] * err[1]);
278 h_pulls.Fill(pull);
279 }
280 }
281 h_pulls.Write();
282 double scaleError = h_pulls.GetRMS();
283
284 // merge two statistically independent finders and store results into histograms
285
286 for (unsigned module = 0; module < c_numModules; module++) {
287 int moduleID = module + 1;
288
289 std::string slotNum = std::to_string(moduleID);
290 if (moduleID < 10) slotNum = "0" + slotNum;
291
292 std::string name = "channelT0_slot" + slotNum;
293 std::string title = "Relative channel T0 for slot " + slotNum;
294 TH1F h_channelT0(name.c_str(), title.c_str(), c_numChannels, 0, c_numChannels);
295 h_channelT0.SetXTitle("channel number");
296 h_channelT0.SetYTitle("relative channel T0 [ns]");
297
298 for (unsigned channel = 0; channel < c_numChannels; channel++) {
299 auto& finder = m_finders[0][module][channel].add(m_finders[1][module][channel]);
300 const auto& minimum = finder.getMinimum();
301 if (minimum.valid) {
302 h_channelT0.SetBinContent(channel + 1, minimum.position);
303 h_channelT0.SetBinError(channel + 1, minimum.error * scaleError);
304 }
305 }
306
307 h_channelT0.Write();
308
309 }
310
311 // merge all finders of a slot to find module T0
312
313 TH1F h_moduleT0("moduleT0", "Relative module T0",
314 c_numModules, 0.5, static_cast<float>(c_numModules) + 0.5);
315 h_moduleT0.SetXTitle("slot number");
316 h_moduleT0.SetYTitle("relative module T0 [ns]");
317 auto finderCommon = m_finders[0][0][0];
318 finderCommon.clear();
319 for (unsigned module = 0; module < c_numModules; module++) {
320 auto finder = m_finders[0][module][0];
321 finder.clear();
322 for (unsigned channel = 0; channel < c_numChannels; channel++) {
323 finder.add(m_finders[0][module][channel]);
324 }
325 finderCommon.add(finder);
326 const auto& minimum = finder.getMinimum();
327 if (minimum.valid) {
328 h_moduleT0.SetBinContent(module + 1, minimum.position);
329 h_moduleT0.SetBinError(module + 1, minimum.error * scaleError);
330 }
331 }
332 h_moduleT0.Write();
333
334 // find common T0
335
336 TH1F h_commonT0("commonT0", "Relative common T0", 1, 0, 1);
337 h_commonT0.SetYTitle("relative common T0 [ns]");
338 const auto& minimum = finderCommon.getMinimum();
339 if (minimum.valid) {
340 h_commonT0.SetBinContent(1, minimum.position);
341 h_commonT0.SetBinError(1, minimum.error * scaleError);
342 }
343 h_commonT0.Write();
344
345 // write other histograms and ntuple; close the file
346
347 for (auto& h : m_hits1D) h.Write();
348 for (auto& h : m_hits2D) h.Write();
349
350 m_tree->Write();
351 m_file->Close();
352
353 B2RESULT("Results available in " << m_outFileName);
354 }

◆ terminate() [5/14]

void terminate ( void )
overridevirtual

Termination action.

Output MC extraction

Reimplemented from Module.

Definition at line 79 of file TOPChannelT0MCModule.cc.

80 {
81 auto file = new TFile(m_outputFile.c_str(), "RECREATE");
82 auto otree = new TTree("t0MC", "extract channel t0 info. from MC");
83
84 unsigned channel = 0;
85 double maxpos = 0;
86
87 otree->Branch("maxpos", &maxpos, "maxpos/D");
88 otree->Branch("channel", &channel, "channel/I");
89
90 for (int i = 0; i < c_NumChannels; i++) {
91 channel = i;
92 maxpos = m_histo[i]->GetXaxis()->GetBinCenter(m_histo[i]->GetMaximumBin());
93 otree->Fill();
94 }
95 otree->Write();
96 delete otree;
97 file->Close();
98 delete file;
99 }

◆ terminate() [6/14]

void terminate ( void )
overridevirtual

Termination action.

Clean-up, close files, summarize statistics, etc.

Reimplemented from Module.

Definition at line 243 of file TOPCommonT0CalibratorModule.cc.

244 {
245
246 // determine scaling factor for errors from statistically independent results
247
248 TH1F h_pulls("pulls", "Pulls of statistically independent results",
249 200, -15.0, 15.0);
250 h_pulls.SetXTitle("pulls");
251 std::vector<double> pos, err;
252 for (int i = 0; i < c_numSets; i++) {
253 const auto& minimum = m_finders[i].getMinimum();
254 if (not minimum.valid) continue;
255 pos.push_back(minimum.position);
256 err.push_back(minimum.error);
257 }
258 for (unsigned i = 0; i < pos.size(); i++) {
259 for (unsigned j = i + 1; j < pos.size(); j++) {
260 double pull = (pos[i] - pos[j]) / sqrt(err[i] * err[i] + err[j] * err[j]);
261 h_pulls.Fill(pull);
262 }
263 }
264 h_pulls.Write();
265 double scaleError = 1;
266 if (h_pulls.GetEntries() > 1) scaleError = h_pulls.GetRMS();
267
268 // merge statistically independent finders and store results into histograms
269
270 auto finder = m_finders[0];
271 for (int i = 1; i < c_numSets; i++) {
272 finder.add(m_finders[i]);
273 }
274
275 TH1F h_relCommonT0("relCommonT0", "relative common T0", 1, 0, 1);
276 h_relCommonT0.SetYTitle("common T0 residual [ns]");
277 TH1F h_commonT0("commonT0", "Common T0", 1, 0, 1);
278 h_commonT0.SetYTitle("common T0 [ns]");
279
280 const auto& minimum = finder.getMinimum();
281 auto h = finder.getHistogram("chi2", "chi2");
282 h.Write();
283 if (minimum.valid) {
284 h_relCommonT0.SetBinContent(1, minimum.position);
285 h_relCommonT0.SetBinError(1, minimum.error * scaleError);
286 double T0 = minimum.position;
287 if (m_commonT0->isCalibrated()) T0 += m_commonT0->getT0();
288 T0 -= round(T0 / m_bunchTimeSep) * m_bunchTimeSep; // wrap around
289 h_commonT0.SetBinContent(1, T0);
290 h_commonT0.SetBinError(1, minimum.error * scaleError);
291 }
292 h_relCommonT0.Write();
293 h_commonT0.Write();
294
295 // write other histograms and ntuple; close the file
296
297 m_hits1D.Write();
298 m_hits2D.Write();
299 m_tree->Write();
300 m_file->Close();
301
302 B2RESULT("Results available in " << m_outFileName);
303 }

◆ terminate() [7/14]

void terminate ( void )
overridevirtual

Termination action.

Clean-up, close files, summarize statistics, etc.

Reimplemented from Module.

Definition at line 249 of file TOPCosmicT0FinderModule.cc.

250 {
251 B2RESULT("TOPCosmicT0Finder: accepted events " << m_acceptedCount
252 << ", event T0 determined for " << m_successCount << " events");
253 }

◆ terminate() [8/14]

void terminate ( void )
overridevirtual

Termination action.

Clean-up, close files, summarize statistics, etc.

Reimplemented from HistoModule.

Definition at line 159 of file TOPGainEfficiencyCalculatorModule.cc.

160 {
161 //first, check validity of input parameters
162 bool areGoodParameters = true;
163 if (m_targetSlotId < 1 || m_targetSlotId > c_NModule) {
164 B2ERROR("TOPGainEfficiencyCalculator : invalid slotID : " << m_targetSlotId);
165 areGoodParameters = false;
166 }
167 if (m_targetPmtId < 1 || m_targetPmtId > c_NPMTPerModule) {
168 B2ERROR("TOPGainEfficiencyCalculator : invalid PMT ID : " << m_targetPmtId);
169 areGoodParameters = false;
170 }
171 if (m_pedestalSigma < 1e-6) {
172 B2ERROR("TOPGainEfficiencyCalculator : pedestal sigma must be non-zero positive value");
173 areGoodParameters = false;
174 }
175
176 //do not proceed to the main process unless all the input parameters are not valid
177 if (areGoodParameters) {
178 if (m_outputPDFFile.size() == 0) {
179 if (m_inputFile.rfind(".") == std::string::npos)
180 m_outputPDFFile = m_inputFile;
181 else
182 m_outputPDFFile = m_inputFile.substr(0, m_inputFile.rfind("."));
183 }
184
185 //gain run using height distribution
186 LoadHistograms("Height_gain");
187 FitHistograms(c_LoadForFitHeight);
188 DrawResult("Height_gain", c_LoadForFitHeight);
189
190 //efficiency run
191 LoadHistograms("Height_efficiency");
192 FitHistograms(c_LoadHitRateHeight);
193 DrawResult("Height_efficiency", c_LoadHitRateHeight);
194
195 //gain run using integral distribution
196 LoadHistograms("Integral_gain");
197 FitHistograms(c_LoadForFitIntegral);
198 DrawResult("Integral_gain", c_LoadForFitIntegral);
199
200 }
201 }

◆ terminate() [9/14]

void terminate ( void )
overridevirtual

Termination action.

Do fits , clean-up, close files, summarize statistics, etc.

Reimplemented from Module.

Definition at line 101 of file TOPLaserCalibratorModule.cc.

102 {
103 std::vector<TH1F*> v_histo;
104 for (int i = 0; i < c_NumChannels; ++i) {
105 v_histo.push_back(m_histo[i]);
106 }
107
108 double dataT[c_NumChannels] = {0};
109 double dataTErr[c_NumChannels] = {0};
110 double mcT[c_NumChannels] = {0};
111
112 TOP::LaserCalibratorFit t0fit(m_barID);
113 t0fit.setHist(v_histo); //set time hist vector
114 t0fit.setFitMethod(m_fitMethod);
115 t0fit.setFitRange(m_fitRange[1], m_fitRange[2]);
116 if (m_fitChannel == c_NumChannels) {
117 for (int i = 0; i < c_NumChannels; ++i) {
118 t0fit.fitChannel(i);
119 dataT[i] = t0fit.getFitT();
120 dataTErr[i] = t0fit.getFitTErr();
121 }
122 } else {
123 t0fit.fitChannel(m_fitChannel);
124 dataT[m_fitChannel] = t0fit.getFitT();
125 }
126 //cout<<"chisq=\t"<<t0fit.getFitChisq(6)<<endl;
127 t0fit.writeFile(m_dataFitOutput); //write to root file
128
129 //read laser propagation time from MC (TOPChannelT0MC)
130 auto mcFile = new TFile(m_mcInput.c_str());
131 auto tree = static_cast<TTree*>(mcFile->Get("t0MC"));
132 int channel_mc;
133 double maxpos;
134
135 tree->SetBranchAddress("channel", &channel_mc);
136 tree->SetBranchAddress("maxpos", &maxpos);
137 for (int i = 0; i < tree->GetEntries(); i++) {
138 tree->GetEntry(i);
139 mcT[channel_mc] = maxpos;
140 }
141
142 //w.r.t. ref. channel
143 for (int i = 0; i < c_NumChannels; i++) {
144 if (i == m_refCh) continue;
145 dataT[i] = dataT[i] - dataT[m_refCh];
146 mcT[i] = mcT[i] - mcT[m_refCh];
147 }
148
149 delete tree;
150 mcFile->Close();
151 delete mcFile;
152
153 //calculate T0 Const, write to root file
154 auto file = new TFile(m_chT0C.c_str(), "RECREATE");
155 auto otree = new TTree("chT0", "Channel T0 Const");
156
157 unsigned channel = 0;
158 double t0_const = 0;
159 double t0ConstRaw = 0;
160 double fittedTime = 0;
161 double fittedTimeError = 0;
162 double mcTime = 0;
163 double mcCorrection = 0;
164 double t0ConstError = 0;
165
166 otree->Branch("fittedTime", &fittedTime, "fittedTime/D");
167 otree->Branch("fittedTimeError", &fittedTimeError, "fittedTimeError/D");
168 otree->Branch("mcTime", &mcTime, "mcTime/D");
169 otree->Branch("t0ConstRaw", &t0ConstRaw, "t0ConstRaw/D");
170 otree->Branch("mcCorrection", &mcCorrection, "mcCorrection/D");
171 otree->Branch("t0Const", &t0_const, "t0_const/D");
172 otree->Branch("t0ConstError", &t0ConstError, "t0ConstError/D");
173 otree->Branch("channel", &channel, "channel/I");
174 otree->Branch("slot", &m_barID, "slot/I");
175
176 for (int i = 0; i < c_NumChannels; i++) {
177 if (i == m_refCh) {
178 fittedTime = dataT[i];
179 mcTime = mcT[i];
180 } else {
181 fittedTime = dataT[i] + dataT[m_refCh];
182 mcTime = mcT[i] + mcT[m_refCh];
183 }
184 fittedTimeError = dataTErr[i];
185 t0ConstRaw = dataT[i];
186 mcCorrection = mcT[i];
187 channel = i;
188 t0_const = dataT[i] - mcT[i];
189 // assuming that the MC error is negligible
190 t0ConstError = TMath::Sqrt(dataTErr[i] * dataTErr[i] + dataTErr[m_refCh] * dataTErr[m_refCh]);
191 if (i == m_refCh) {
192 t0_const = 0;
193 t0ConstError = dataTErr[m_refCh];
194 }
195 otree->Fill();
196 }
197 otree->Write();
198 delete otree;
199 file->Close();
200 delete file;
201
202 // ...
203 // write to database; next to do ...
204 // ...
205 }

◆ terminate() [10/14]

void terminate ( void )
overridevirtual

Termination action.

Clean-up, close files, summarize statistics, etc.

Reimplemented from Module.

Definition at line 252 of file TOPModuleT0CalibratorModule.cc.

253 {
254 // determine scaling factor for errors from two statistically independent results
255
256 TH1F h_pulls("pulls", "Pulls of the two statistically independent results",
257 200, -15.0, 15.0);
258 h_pulls.SetXTitle("pulls");
259 for (unsigned module = 0; module < c_numModules; module++) {
260 std::vector<double> pos, err;
261 for (int i = 0; i < 2; i++) {
262 const auto& minimum = m_finders[i][module].getMinimum();
263 if (not minimum.valid) continue;
264 pos.push_back(minimum.position);
265 err.push_back(minimum.error);
266 }
267 if (pos.size() < 2) continue;
268 double pull = (pos[0] - pos[1]) / sqrt(err[0] * err[0] + err[1] * err[1]);
269 h_pulls.Fill(pull);
270 }
271 h_pulls.Write();
272 double scaleError = h_pulls.GetRMS();
273
274 // merge two statistically independent finders and store results into histograms
275
276 TH1F h_relModuleT0("relModuleT0", "Module T0 relative to calibration",
277 c_numModules, 0.5, static_cast<float>(c_numModules) + 0.5);
278 h_relModuleT0.SetXTitle("slot number");
279 h_relModuleT0.SetYTitle("module T0 residual [ns]");
280
281 for (unsigned module = 0; module < c_numModules; module++) {
282 auto& finder = m_finders[0][module].add(m_finders[1][module]);
283 const auto& minimum = finder.getMinimum();
284 if (minimum.valid) {
285 h_relModuleT0.SetBinContent(module + 1, minimum.position);
286 h_relModuleT0.SetBinError(module + 1, minimum.error * scaleError);
287 }
288 std::string slotNum = to_string(module + 1);
289 auto h = finder.getHistogram("chi2_slot_" + slotNum, "slot " + slotNum);
290 h.Write();
291 }
292 h_relModuleT0.Write();
293
294 // absolute module T0
295 TH1F h_moduleT0("moduleT0", "Module T0",
296 c_numModules, 0.5, static_cast<float>(c_numModules) + 0.5);
297 h_moduleT0.SetXTitle("slot number");
298 h_moduleT0.SetYTitle("module T0 [ns]");
299
300 double average = 0; // average to be subtracted
301 int num = 0;
302 for (int slot = 1; slot <= c_numModules; slot++) {
303 if (h_relModuleT0.GetBinError(slot) > 0) {
304 double T0 = 0;
305 if (m_moduleT0->isCalibrated(slot)) T0 = m_moduleT0->getT0(slot);
306 average += h_relModuleT0.GetBinContent(slot) + T0;
307 num++;
308 }
309 }
310 if (num > 0) average /= num;
311
312 for (int slot = 1; slot <= c_numModules; slot++) {
313 double T0 = 0;
314 if (m_moduleT0->isCalibrated(slot)) T0 = m_moduleT0->getT0(slot);
315 double t0 = h_relModuleT0.GetBinContent(slot) + T0 - average;
316 double err = h_relModuleT0.GetBinError(slot);
317 h_moduleT0.SetBinContent(slot, t0);
318 h_moduleT0.SetBinError(slot, err);
319 }
320 h_moduleT0.Write();
321
322 // write other histograms and ntuple; close the file
323
324 m_hits1D.Write();
325 m_hits2D.Write();
326 m_tree->Write();
327 m_file->Close();
328
329 B2RESULT(num << "/16 calibrated. Results available in " << m_outFileName);
330 }

◆ terminate() [11/14]

void terminate ( void )
overridevirtual

Termination action.

Clean-up, close files, summarize statistics, etc.

Reimplemented from Module.

Definition at line 262 of file TOPNtupleModule.cc.

263 {
264 TDirectory::TContext context;
265 m_file->cd();
266 m_tree->Write();
267 m_file->Close();
268 }

◆ terminate() [12/14]

void terminate ( void )
overridevirtual

Termination action.

Clean-up, close files, summarize statistics, etc.

Reimplemented from HistoModule.

Definition at line 182 of file TOPPDFCheckerModule.cc.

183 {
184 m_avrgPosition *= 1.0 / m_numTracks;
185 m_avrgMomentum *= 1.0 / m_numTracks;
186
187 cout << "Average particle parameters at entrance to bar (in local frame):" << endl;
188 cout << " slot ID: ";
189 for (auto slot : m_slotIDs) cout << slot << " ";
190 cout << endl;
191 cout << " PDG code: ";
192 for (auto pdg : m_PDGCodes) cout << pdg << " ";
193 cout << endl;
194 cout << " position: x = " << m_avrgPosition.X()
195 << ", y = " << m_avrgPosition.Y()
196 << ", z = " << m_avrgPosition.Z() << endl;
197 cout << " momentum: p = " << m_avrgMomentum.R()
198 << ", theta = " << m_avrgMomentum.Theta() / Unit::deg
199 << ", phi = " << m_avrgMomentum.Phi() / Unit::deg << endl;
200 cout << "Number of particles: " << m_numTracks << endl;
201 cout << "Photons per particle: simulation = " << m_hits->GetSum() / m_numTracks
202 << ", PDF = " << m_pdf->GetSum() / m_numTracks << endl;
203
204 }

◆ terminate() [13/14]

void terminate ( void )
overridevirtual

Termination action.

The historam writing takes place here

Reimplemented from HistoModule.

Definition at line 440 of file TOPTBCComparatorModule.cc.

441 {
442 // writes the histos
443 B2INFO("Creating output file " << m_outputFile);
444 TFile outfile(m_outputFile.c_str(), "recreate");
445
446 B2INFO("Writing histograms ");
447
448 // opens the input list to retrieve, one last time, the labels
449 ifstream inputDirectoryListFile(m_inputDirectoryList.c_str());
450 std::string inputString;
451 int iSet = 0;
452
453 while (std::getline(inputDirectoryListFile, inputString)) {
454 parseInputDirectoryLine(inputString);
455 TDirectory* dirSet = outfile.mkdir(m_calSetLabel.c_str());
456 dirSet->cd();
457
458 m_topAverageDeltaT[iSet]->Write();
459 m_topSigmaDeltaT[iSet]->Write();
460 m_topSampleOccupancy[iSet]->Write();
461 m_topAverageDeltaTComparison[iSet]->Write();
462 m_topSigmaDeltaTComparison[iSet]->Write();
463 m_topSampleOccupancyComparison[iSet]->Write();
464
465 for (int iSlot = 0; iSlot < 16; iSlot ++) {
466 TDirectory* dirSlot = dirSet->mkdir(str(format("slot%1%") % (iSlot + 1)).c_str());
467 dirSlot->cd();
468
469 m_slotAverageDeltaT[iSlot][iSet]->Write();
470 m_slotSigmaDeltaT[iSlot][iSet]->Write();
471 m_slotAverageDeltaTMap[iSlot][iSet]->Write();
472 m_slotSigmaDeltaTMap[iSlot][iSet]->Write();
473 m_slotSampleOccupancy[iSlot][iSet]->Write();
474 m_slotEmptySamples[iSlot][iSet]->Write();
475 m_slotSampleOccupancyMap[iSlot][iSet]->Write();
476 m_slotEmptySamplesMap[iSlot][iSet]->Write();
477
478 m_slotAverageDeltaTComparison[iSlot][iSet]->Write();
479 m_slotSigmaDeltaTComparison[iSlot][iSet]->Write();
480 m_slotAverageDeltaTMapComparison[iSlot][iSet]->Write();
481 m_slotSigmaDeltaTMapComparison[iSlot][iSet]->Write();
482 }
483 dirSet->cd();
484 iSet++;
485 }
486 }

◆ terminate() [14/14]

void terminate ( void )
overridevirtual

Termination action.

Clean-up, close files, summarize statistics, etc.

Reimplemented from Module.

Definition at line 208 of file TOPTimeBaseCalibratorModule.cc.

209 {
210
211 const auto& feMapper = TOPGeometryPar::Instance()->getFrontEndMapper();
212
213 for (unsigned bs = 0; bs < c_NumBoardstacks; bs ++) {
214
215 // determine scrod ID
216
217 const auto* feMap = feMapper.getMap(m_moduleID, bs);
218 if (!feMap) {
219 B2ERROR("No front-end map available for slot " << m_moduleID << ", BS" << bs);
220 continue;
221 }
222 unsigned scrodID = feMap->getScrodID();
223
224 // open output root file
225
226 string fileName = m_directoryName + "/tbcSlot";
227 if (m_moduleID < 10) {
228 fileName += "0" + to_string(m_moduleID);
229 } else {
230 fileName += to_string(m_moduleID);
231 }
232 fileName += "_" + to_string(bs) + "-scrod" +
233 to_string(scrodID) + ".root";
234 TFile* fout = TFile::Open(fileName.c_str(), "recreate");
235 if (!fout) {
236 B2ERROR("Can't open the output file " << fileName);
237 continue;
238 }
239
240 // write control histograms
241
242 m_goodHits.Write();
243 m_calPulseFirst.Write();
244 m_calPulseSecond.Write();
245
246 B2INFO("Fitting time base corrections for SCROD " << scrodID
247 << ", output file: " << fileName);
248
249 // book histograms
250
251 TH1F Hchan("channels", "channels with cal pulse",
252 c_NumScrodChannels, 0, c_NumScrodChannels);
253 Hchan.SetXTitle("channel number");
254 Hchan.SetYTitle("double cal pulse counts");
255 TH1F Hsuccess("success", "successfully fitted channels",
256 c_NumScrodChannels, 0, c_NumScrodChannels);
257 Hsuccess.SetXTitle("channel number");
258 TH1F Hchi2("chi2", "normalized chi2",
259 c_NumScrodChannels, 0, c_NumScrodChannels);
260 Hchi2.SetXTitle("channel number");
261 Hchi2.SetYTitle("chi2/ndf");
262 TH1F Hndf("ndf", "degrees of freedom",
263 c_NumScrodChannels, 0, c_NumScrodChannels);
264 Hndf.SetXTitle("channel number");
265 Hndf.SetYTitle("ndf");
266 TH1F HDeltaT("DeltaT", "Fitted double pulse delay time",
267 c_NumScrodChannels, 0, c_NumScrodChannels);
268 HDeltaT.SetXTitle("channel number");
269 HDeltaT.SetYTitle("#Delta T [ns]");
270
271 // loop over channels of a single SCROD
272
273 for (unsigned chan = 0; chan < c_NumScrodChannels; chan++) {
274 unsigned channel = chan + bs * c_NumScrodChannels;
275 auto& ntuple = m_ntuples[channel];
276 Hchan.SetBinContent(chan + 1, ntuple.size());
277 if (ntuple.size() > m_minHits) {
278 bool ok = calibrateChannel(ntuple, scrodID, chan, Hchi2, Hndf, HDeltaT);
279 if (ok) Hsuccess.Fill(chan);
280 } else {
281 B2INFO("... channel " << chan << " statistics too low ("
282 << ntuple.size() << " double cal pulses)");
283 }
284 }
285
286 // write histograms and close the file
287
288 Hchan.Write();
289 Hsuccess.Write();
290 Hchi2.Write();
291 Hndf.Write();
292 HDeltaT.Write();
293 fout->Close();
294
295 }
296 }

◆ TOPAlignerModule()

Constructor.

Definition at line 44 of file TOPAlignerModule.cc.

44 : Module()
45
46 {
47 // set module description
48 setDescription("Alignment of TOP");
49 // setPropertyFlags(c_ParallelProcessingCertified);
50
51 // Add parameters
52 addParam("targetModule", m_targetMid,
53 "Module to be aligned. Must be 1 <= Mid <= 16.", 1);
54 addParam("maxFails", m_maxFails,
55 "Maximum number of consecutive failed iterations before resetting the procedure", 100);
56 addParam("sample", m_sample,
57 "sample type: one of dimuon, bhabha or cosmics", std::string("dimuon"));
58 addParam("minMomentum", m_minMomentum,
59 "minimal track momentum if sample is cosmics", 1.0);
60 addParam("deltaEcms", m_deltaEcms,
61 "c.m.s energy window (half size) if sample is dimuon or bhabha", 0.1);
62 addParam("dr", m_dr, "cut on POCA in r", 2.0);
63 addParam("dz", m_dz, "cut on POCA in abs(z)", 4.0);
64 addParam("minZ", m_minZ,
65 "minimal local z of extrapolated hit", -130.0);
66 addParam("maxZ", m_maxZ,
67 "maximal local z of extrapolated hit", 130.0);
68 addParam("outFileName", m_outFileName,
69 "Root output file name containing alignment results",
70 std::string("TopAlignPars.root"));
71 addParam("stepPosition", m_stepPosition, "step size for translations", 1.0);
72 addParam("stepAngle", m_stepAngle, "step size for rotations", 0.01);
73 addParam("stepTime", m_stepTime, "step size for t0", 0.05);
74 std::string names;
75 for (const auto& parName : m_align.getParameterNames()) names += parName + ", ";
76 names.pop_back();
77 names.pop_back();
78 addParam("parInit", m_parInit,
79 "initial parameter values in the order [" + names + "]. "
80 "If list is too short, the missing ones are set to 0.", m_parInit);
81 auto parFixed = m_parFixed;
82 addParam("parFixed", m_parFixed, "list of names of parameters to be fixed. "
83 "Valid names are: " + names, parFixed);
84
85 }

◆ TOPAlignmentCollectorModule()

Constructor.

Definition at line 42 of file TOPAlignmentCollectorModule.cc.

43 {
44 // set module description and processing properties
45 setDescription("A collector for geometrical alignment of a TOP module with dimuons or Bhabhas. Iterative alignment procedure (NIMA 876 (2017) 260-264) is run here, algorithm just collects the results.");
46 setPropertyFlags(c_ParallelProcessingCertified);
47
48 // module parameters
49 addParam("targetModule", m_targetMid,
50 "Module to be aligned. Must be 1 <= Mid <= 16.");
51 addParam("maxFails", m_maxFails,
52 "Maximum number of consecutive failed iterations before resetting the procedure", 100);
53 addParam("sample", m_sample,
54 "sample type: one of dimuon or bhabha", std::string("dimuon"));
55 addParam("deltaEcms", m_deltaEcms,
56 "c.m.s energy window (half size) if sample is dimuon or bhabha", 0.1);
57 addParam("dr", m_dr, "cut on POCA in r", 1.0);
58 addParam("dz", m_dz, "cut on POCA in abs(z)", 2.0);
59 addParam("minZ", m_minZ, "minimal local z of extrapolated hit", -130.0);
60 addParam("maxZ", m_maxZ, "maximal local z of extrapolated hit", 130.0);
61 addParam("stepPosition", m_stepPosition, "step size for translations", 1.0);
62 addParam("stepAngle", m_stepAngle, "step size for rotations", 0.01);
63 addParam("stepTime", m_stepTime, "step size for t0", 0.05);
64 std::string names;
65 auto align = ModuleAlignment();
66 for (const auto& parName : align.getParameterNames()) names += parName + ", ";
67 names.pop_back();
68 names.pop_back();
69 addParam("parInit", m_parInit,
70 "initial parameter values in the order [" + names + "]. "
71 "If list is too short, the missing ones are set to 0.", m_parInit);
72 auto parFixed = m_parFixed;
73 addParam("parFixed", m_parFixed, "list of names of parameters to be fixed. "
74 "Valid names are: " + names, parFixed);
75
76 }

◆ TOPAsicShiftsBS13dCollectorModule()

Constructor.

Definition at line 36 of file TOPAsicShiftsBS13dCollectorModule.cc.

37 {
38 // set module description and processing properties
39 setDescription("A collector for calibration of carrier shifts of BS13d.");
40 setPropertyFlags(c_ParallelProcessingCertified);
41
42 // module parameters
43 addParam("timeOffset", m_timeOffset, "time offset", 0.0);
44 addParam("nx", m_nx, "number of histogram bins (bin size ~8 ns)", 50);
45 addParam("requireRecBunch", m_requireRecBunch,
46 "if True, require reconstructed bunch (to be used on cdst files only!)",
47 false);
48
49 }

◆ TOPBackgroundModule()

Constructor.

Definition at line 59 of file TOPBackgroundModule.cc.

59 : Module(),
60 m_rootFile(0),
61 origingamma(0),
62 originpe(0),
63 peflux(0),
64 nflux(0),
65 rdose(0),
66 zdist(0),
67 genergy(0),
68 genergy2(0),
69 zdistg(0),
70 originpt(0),
71 nflux_bar(0),
72 gflux_bar(0),
73 cflux_bar(0),
74 norigin(0),
75 gorigin(0),
76 corigin(0),
77 nprim(0),
78 gprim(0),
79 cprim(0),
80 origin_zx(0),
81 origin_zy(0),
82 prim_zx(0),
83 prim_zy(0),
84 module_occupancy(0),
85 PCBmass(0),
86 PCBarea(0),
87 yearns(0),
88 evtoJ(0),
89 mtoc(0),
90 count(0),
91 count_occ(0),
92 origingamma_x(0),
93 origingamma_y(0),
94 origingamma_z(0),
95 originpe_x(0),
96 originpe_y(0),
97 originpe_z(0)
98 {
99 // Set description()
100 setDescription("A module to analyze beam background simulations regarding TOP");
101
102 // Add parameters
103 addParam("Type", m_BkgType, "Background type", string("Background"));
104 addParam("Output", m_OutputFileName, "Name of the output file",
105 string("Background.root"));
106 addParam("TimeOfSimulation", m_TimeOfSimulation,
107 "Real time in micro seconds that corresponds to simulated data", 5.);
108 }

◆ TOPBunchFinderModule()

Constructor.

Definition at line 53 of file TOPBunchFinderModule.cc.

53 : Module()
54 {
55 // set module description (e.g. insert text)
56 setDescription("A precise event T0 determination w.r.t local time reference of TOP counter. "
57 "Results available in TOPRecBunch.");
58 setPropertyFlags(c_ParallelProcessingCertified);
59
60 // Add parameters
61 addParam("numBins", m_numBins, "number of bins of fine search region", 200);
62 addParam("timeRangeFine", m_timeRangeFine,
63 "time range in which to do fine search [ns]", 10.0);
64 addParam("timeRangeCoarse", m_timeRangeCoarse,
65 "time range in which to do coarse search, if autoRange turned off [ns]", 100.0);
66 addParam("autoRange", m_autoRange,
67 "turn on/off automatic determination of the coarse search region (false means off)", false);
68 addParam("sigmaSmear", m_sigmaSmear,
69 "sigma in [ns] for additional smearing of PDF", 0.0);
70 addParam("minSignal", m_minSignal,
71 "minimal number of signal photons to accept track", 8.0);
72 addParam("minSBRatio", m_minSBRatio,
73 "minimal signal-to-background ratio to accept track", 0.0);
74 addParam("minDERatio", m_minDERatio,
75 "minimal ratio of detected-to-expected photons to accept track", 0.2);
76 addParam("maxDERatio", m_maxDERatio,
77 "maximal ratio of detected-to-expected photons to accept track", 2.5);
78 addParam("minPt", m_minPt, "minimal p_T of the track", 0.3);
79 addParam("maxPt", m_maxPt, "maximal p_T of the track", 6.0);
80 addParam("maxD0", m_maxD0, "maximal absolute value of helix perigee distance", 2.0);
81 addParam("maxZ0", m_maxZ0, "maximal absolute value of helix perigee z coordinate", 4.0);
82 addParam("minNHitsCDC", m_minNHitsCDC, "minimal number of hits in CDC", 20);
83 addParam("useMCTruth", m_useMCTruth,
84 "if true, use MC truth for particle mass instead of the most probable from dEdx",
85 false);
86 addParam("saveHistograms", m_saveHistograms,
87 "if true, save histograms to TOPRecBunch and TOPTimeZeros", false);
88 addParam("tau", m_tau,
89 "first order filter time constant [number of events]", 100.0);
90 addParam("correctDigits", m_correctDigits,
91 "if true, subtract bunch time in TOPDigits", true);
92 addParam("subtractRunningOffset", m_subtractRunningOffset,
93 "if true and correctDigits = True, subtract running offset in TOPDigits "
94 "when running in HLT mode. It must be set to false when running calibration.",
95 true);
96 addParam("bunchesPerSSTclk", m_bunchesPerSSTclk,
97 "number of bunches per SST clock period", 24);
98 addParam("usePIDLikelihoods", m_usePIDLikelihoods,
99 "use PIDLikelihoods instead of DedxLikelihoods (only if run on cdst files)",
100 false);
101 addParam("nTrackLimit", m_nTrackLimit,
102 "maximum number of tracks (inclusive) to use three particle hypotheses in fine search "
103 "(only when running in data processing mode).", unsigned(3));
104 addParam("useTimeSeed", m_useTimeSeed, "use SVD or CDC event T0 as a seed "
105 "(only when running in data processing mode and autoRange turned off).", true);
106 addParam("useFillPattern", m_useFillPattern, "use known accelerator fill pattern to enhance efficiency "
107 "(only when running in data processing mode).", true);
108 }

◆ TOPCalPulseGeneratorModule()

Constructor.

Definition at line 45 of file TOPCalPulseGeneratorModule.cc.

45 : Module()
46
47 {
48 // set module description
49 setDescription("Realistic generator of calibration double pulses. "
50 "Needs TOPDigitizer to digitize");
51 setPropertyFlags(c_ParallelProcessingCertified);
52
53 // Add parameters
54 addParam("moduleIDs", m_moduleIDs,
55 "list of slots for which to generate cal pulse, empty list means all slots.",
56 m_moduleIDs);
57 m_asicChannels.push_back(0);
58 addParam("asicChannels", m_asicChannels,
59 "ASIC calibration channels (0 - 7), empty list means all channels.",
60 m_asicChannels);
61 // default for these three below are set according to laser run 8/414
62 addParam("amplitude", m_amplitude, "amplitude of cal pulse [ADC counts]", 600.0);
63 addParam("delay", m_delay, "delay of cal pulse [ns]", 10.5);
64 addParam("windowSize", m_windowSize, "size of time window in which to generate cal pulses [ns]", 8.0);
65 }

◆ TOPChannelMaskCollectorModule()

Constructor.

Definition at line 31 of file TOPChannelMaskCollectorModule.cc.

32 {
33 // set module description and processing properties
34 setDescription("A collector for preparing masks of dead and hot channels");
35 setPropertyFlags(c_ParallelProcessingCertified);
36 }

◆ TOPChannelMaskerModule()

Constructor: Sets the description of the module.

Definition at line 32 of file TOPChannelMaskerModule.cc.

32 : Module()
33 {
34 // Set module properties
35 setDescription("Masks dead, hot and uncalibrated channels from the reconstruction");
36
37 // Set property flags
38 setPropertyFlags(c_ParallelProcessingCertified);
39
40 // Add parameters
41 addParam("maskUncalibratedChannelT0", m_maskUncalibratedChannelT0,
42 "if true, mask channelT0-uncalibrated channels", true);
43 addParam("maskUncalibratedTimebase", m_maskUncalibratedTimebase,
44 "if true, mask timebase-uncalibrated channels ", true);
45 }

◆ TOPChannelT0CalibratorModule()

Constructor.

Definition at line 38 of file TOPChannelT0CalibratorModule.cc.

38 : Module()
39
40 {
41 // set module description
42 setDescription("Alternative channel T0 calibration with dimuons or bhabhas. "
43 "This module can also be used to check the calibration "
44 "(channel, module and common T0).\n"
45 "Note: after this kind of calibration one cannot do the alignment.");
46 // setPropertyFlags(c_ParallelProcessingCertified);
47
48 // Add parameters
49 addParam("numBins", m_numBins, "number of bins of the search region", 200);
50 addParam("timeRange", m_timeRange,
51 "time range in which to search for the minimum [ns]", 10.0);
52 addParam("sigmaSmear", m_sigmaSmear,
53 "sigma in [ns] for additional smearing of PDF", 0.0);
54 addParam("sample", m_sample,
55 "sample type: one of dimuon, bhabha or cosmics", std::string("dimuon"));
56 addParam("minMomentum", m_minMomentum,
57 "minimal track momentum if sample is cosmics", 1.0);
58 addParam("deltaEcms", m_deltaEcms,
59 "c.m.s energy window (half size) if sample is dimuon or bhabha", 0.1);
60 addParam("dr", m_dr, "cut on POCA in r", 2.0);
61 addParam("dz", m_dz, "cut on POCA in abs(z)", 4.0);
62 addParam("minZ", m_minZ,
63 "minimal local z of extrapolated hit", -130.0);
64 addParam("maxZ", m_maxZ,
65 "maximal local z of extrapolated hit", 130.0);
66 addParam("outputFileName", m_outFileName,
67 "Root output file name containing calibration results. "
68 "File name can include *'s; "
69 "they will be replaced with a run number from the first input file",
70 std::string("calibrationT0_r*.root"));
71 addParam("pdfOption", m_pdfOption,
72 "PDF option, one of 'rough', 'fine', 'optimal'", std::string("rough"));
73
74 }

◆ TOPChannelT0MCModule()

Constructor.

Definition at line 40 of file TOPChannelT0MCModule.cc.

40 : Module()
41 {
42 std::vector<double> frange = {100, 0., 1.};
43 // set module description (e.g. insert text)
44 setDescription("TOP channel T0 Calibration of MC extraction");
45 // Add parameters
46 addParam("outputFile", m_outputFile, "Output root file name",
47 string(""));
48 addParam("fitRange", m_fitRange, "fit range[nbins, xmin, xmax]", frange);
49
50 }

◆ TOPCommonT0BFCollectorModule()

Constructor.

Definition at line 35 of file TOPCommonT0BFCollectorModule.cc.

36 {
37 // set module description and processing properties
38 setDescription("A collector for common T0 calibration with a fit of bunch finder residuals (method BF)");
39 setPropertyFlags(c_ParallelProcessingCertified);
40
41 // module parameters
42 addParam("bunchesPerSSTclk", m_bunchesPerSSTclk,
43 "number of bunches per SST clock period", 24);
44 addParam("nx", m_nx, "number of histogram bins", 200);
45
46 }

◆ TOPCommonT0CalibratorModule()

Constructor.

Definition at line 37 of file TOPCommonT0CalibratorModule.cc.

37 : Module()
38
39 {
40 // set module description
41 setDescription("Common T0 calibration with dimuons or bhabhas.");
42 // setPropertyFlags(c_ParallelProcessingCertified);
43
44 // Add parameters
45 addParam("numBins", m_numBins, "number of bins of the search region", 200);
46 addParam("timeRange", m_timeRange,
47 "time range in which to search for the minimum [ns]", 10.0);
48 addParam("sigmaSmear", m_sigmaSmear,
49 "sigma in [ns] for additional smearing of PDF", 0.0);
50 addParam("sample", m_sample,
51 "sample type: one of dimuon, bhabha or cosmics", std::string("dimuon"));
52 addParam("minMomentum", m_minMomentum,
53 "minimal track momentum if sample is cosmics", 1.0);
54 addParam("deltaEcms", m_deltaEcms,
55 "c.m.s energy window (half size) if sample is dimuon or bhabha", 0.1);
56 addParam("dr", m_dr, "cut on POCA in r", 2.0);
57 addParam("dz", m_dz, "cut on POCA in abs(z)", 4.0);
58 addParam("minZ", m_minZ,
59 "minimal local z of extrapolated hit", -130.0);
60 addParam("maxZ", m_maxZ,
61 "maximal local z of extrapolated hit", 130.0);
62 addParam("outputFileName", m_outFileName,
63 "Root output file name containing calibration results. "
64 "File name can include *'s; "
65 "they will be replaced with a run number from the first input file",
66 std::string("commonT0_r*.root"));
67 addParam("pdfOption", m_pdfOption,
68 "PDF option, one of 'rough', 'fine', 'optimal'", std::string("rough"));
69
70 }

◆ TOPCommonT0LLCollectorModule()

Constructor.

Definition at line 45 of file TOPCommonT0LLCollectorModule.cc.

46 {
47 // set module description and processing properties
48 setDescription("A collector for common T0 calibration with dimuons or Bhabha's using "
49 "neg. log likelihood minimization (method LL)");
50 setPropertyFlags(c_ParallelProcessingCertified);
51
52 // module parameters
53 addParam("bunchesPerSSTclk", m_bunchesPerSSTclk,
54 "number of bunches per SST clock period", 24);
55 addParam("numBins", m_numBins, "number of bins of the search region", 200);
56 addParam("timeRange", m_timeRange,
57 "time range in which to search for the minimum [ns]", 10.0);
58 addParam("sigmaSmear", m_sigmaSmear,
59 "sigma in [ns] for additional smearing of PDF", 0.0);
60 addParam("sample", m_sample,
61 "sample type: one of dimuon or bhabha", std::string("dimuon"));
62 addParam("deltaEcms", m_deltaEcms,
63 "c.m.s energy window (half size) if sample is dimuon or bhabha", 0.1);
64 addParam("dr", m_dr, "cut on POCA in r", 2.0);
65 addParam("dz", m_dz, "cut on POCA in abs(z)", 4.0);
66 addParam("minZ", m_minZ,
67 "minimal local z of extrapolated hit", -130.0);
68 addParam("maxZ", m_maxZ,
69 "maximal local z of extrapolated hit", 130.0);
70 addParam("pdfOption", m_pdfOption,
71 "PDF option, one of 'rough', 'fine', 'optimal'", std::string("rough"));
72 }

◆ TOPCosmicT0FinderModule()

Constructor.

Definition at line 56 of file TOPCosmicT0FinderModule.cc.

56 : Module()
57
58 {
59 // set module description
60 setDescription("Event T0 finder for global cosmic runs");
61 setPropertyFlags(c_ParallelProcessingCertified);
62
63 // Add parameters
64 addParam("useIncomingTrack", m_useIncomingTrack,
65 "if true, use incoming track, otherwise use outcoming track", true);
66 addParam("minHits", m_minHits,
67 "minimal number of detected photons in a module", (unsigned) 10);
68 addParam("minSignal", m_minSignal,
69 "minimal number of expected signal photons", 5.0);
70 addParam("applyT0", m_applyT0, "if true, subtract T0 in TOPDigits", true);
71 addParam("numBins", m_numBins, "number of bins time range is divided to", 200);
72 addParam("timeRange", m_timeRange, "time range in which to search [ns]", 10.0);
73 addParam("sigma", m_sigma, "additional time spread added to PDF [ns]", 0.0);
74 addParam("saveHistograms", m_saveHistograms,
75 "save histograms to TOPTimeZero", false);
76 }

◆ TOPDigitizerModule()

Constructor.

Definition at line 50 of file TOPDigitizerModule.cc.

50 : Module()
51 {
52 // Set description()
53 setDescription("Digitize TOPSimHits");
54 setPropertyFlags(c_ParallelProcessingCertified);
55
56 // Add parameters
57 addParam("timeZeroJitter", m_timeZeroJitter,
58 "r.m.s of T0 jitter [ns]", 15e-3);
59 addParam("electronicJitter", m_electronicJitter,
60 "r.m.s of electronic jitter [ns], "
61 "if negative the one from TOPNominalTDC is used. "
62 "This parameter is ignored in the full waveform digitization.", -1.0);
63 addParam("darkNoise", m_darkNoise,
64 "uniformly distributed dark noise (hits per module)", 0.0);
65 addParam("ADCx0", m_ADCx0,
66 "pulse height distribution parameter [ADC counts]", 204.1);
67 addParam("ADCp1", m_ADCp1,
68 "pulse height distribution parameter (must be non-negative)", 1.0);
69 addParam("ADCp2", m_ADCp2,
70 "pulse height distribution parameter (must be non-negative)", 1.025);
71 addParam("ADCmax", m_ADCmax,
72 "pulse height distribution upper bound [ADC counts]", 2000.0);
73 addParam("rmsNoise", m_rmsNoise,
74 "r.m.s of noise [ADC counts]", 9.7);
75 addParam("threshold", m_threshold,
76 "pulse height threshold [ADC counts]", 40);
77 addParam("hysteresis", m_hysteresis,
78 "pulse height threshold hysteresis [ADC counts]", 10);
79 addParam("thresholdCount", m_thresholdCount,
80 "minimal number of samples above threshold", 3);
81 addParam("useWaveforms", m_useWaveforms,
82 "if true, use full waveform digitization", true);
83 addParam("allChannels", m_allChannels,
84 "if true, make waveforms for all 8192 channels "
85 "(note: this will slow-down digitization)", false);
86 addParam("useDatabase", m_useDatabase,
87 "if true, use channel dependent constants from database (incl. time base)",
88 true);
89 addParam("useSampleTimeCalibration", m_useSampleTimeCalibration,
90 "if true, use only time base calibration from database "
91 "(has no effect if useDatabase = True)", false);
92 addParam("simulateTTS", m_simulateTTS,
93 "if true, simulate time transition spread. "
94 "Should be always switched ON, except for some dedicated timing studies.",
95 true);
96 addParam("minWidthXheight", m_minWidthXheight,
97 "minimal product of width and height [ns * ADC counts]", 100.0);
98 addParam("lookBackWindows", m_lookBackWindows,
99 "number of look back windows, if positive override the number from database", 0);
100 }

◆ TOPDoublePulseGeneratorModule()

Constructor.

Definition at line 52 of file TOPDoublePulseGeneratorModule.cc.

52 : Module()
53
54 {
55 // set module description
56 setDescription("Generator of calibration double pulses");
57 setPropertyFlags(c_ParallelProcessingCertified);
58
59 // Add parameters
60 addParam("moduleIDs", m_moduleIDs,
61 "list of slots for which to generate cal pulse, empty list means all slots.",
62 m_moduleIDs);
63 m_asicChannels.push_back(0);
64 addParam("asicChannels", m_asicChannels,
65 "ASIC calibration channels (0 - 7), empty list means all channels.",
66 m_asicChannels);
67 addParam("timeDifference", m_timeDifference,
68 "time difference between first and second pulse [ns].", 21.87);
69 addParam("timeResolution", m_timeResolution,
70 "sigma of time difference [ns].", 40.0e-3);
71 addParam("sampleTimeIntervals", m_sampleTimeIntervals,
72 "vector of 256 sample time intervals to construct sample times. "
73 "If empty, equidistant intervals will be used.", m_sampleTimeIntervals);
74 addParam("useDatabase", m_useDatabase,
75 "if true, use sample times from database instead of sampleTimeIntervals.",
76 false);
77 addParam("storageWindows", m_storageWindows,
78 "number of storage windows (old FW used 64 out of 512)", (unsigned) 512);
79 addParam("outputFileName", m_outputFileName,
80 "if given, sample times will be saved as root histograms in this file",
81 std::string(""));
82
83 }

◆ TOPDQMModule()

Constructor.

Definition at line 41 of file TOPDQMModule.cc.

41 : HistoModule()
42 {
43 // set module description (e.g. insert text)
44 setDescription("TOP DQM histogrammer");
45 setPropertyFlags(c_ParallelProcessingCertified);
46
47 // Add parameters
48 addParam("histogramDirectoryName", m_histogramDirectoryName,
49 "histogram directory in ROOT file", string("TOP"));
50 addParam("momentumCut", m_momentumCut,
51 "momentum cut used to histogram number of photons per track", 0.5);
52 }

◆ TOPGainEfficiencyCalculatorModule()

Constructor.

Definition at line 47 of file TOPGainEfficiencyCalculatorModule.cc.

47 : HistoModule()
48 {
49 // Set description()
50 setDescription("Calculate pixel gain and efficiency for a given PMT from 2D histogram of hit timing and pulse charge, "
51 "created by TOPLaserHitSelectorModule.");
52
53 // Add parameters
54 addParam("inputFile", m_inputFile, "input file name containing 2D histogram", std::string(""));
55 addParam("outputPDFFile", m_outputPDFFile, "output PDF file to store plots", std::string(""));
56 addParam("targetSlotId", m_targetSlotId, "TOP module ID in slot number (1-16)", (short)0);
57 addParam("targetPmtId", m_targetPmtId, "PMT number (1-32)", (short)0);
58 addParam("targetPmtChId", m_targetPmtChId, "PMT channel number (1-16)", (short) - 1);
59 addParam("hvDiff", m_hvDiff, "HV difference from nominal HV value", (short)0);
60 addParam("fitHalfWidth", m_fitHalfWidth, "half fit width for direct laser hit peak in [ns] unit", (float)1.0);
61 addParam("threshold", m_threshold,
62 "pulse height (or integrated charge) threshold in fitting its distribution and calculating efficiency", (float)100.);
63 addParam("p0HeightIntegral", m_p0HeightIntegral,
64 "Parameter from p0 + x*p1 function fitting height-integral distribution.", (float) - 50.0);
65 addParam("p1HeightIntegral", m_p1HeightIntegral,
66 "Parameter from p0 + x*p1 function fitting height-integral distribution.", (float)6.0);
67 addParam("fracFit", m_fracFit, "fraction of events to be used in fitting. "
68 "An upper limit of a fit range is given to cover this fraction of events. "
69 "Set negative value to calculate the fraction to exclude only 10 events in tail.", (float)(-1)); //,(float)0.99);
70 addParam("initialP0", m_initialP0, "initial value of the fit parameter p0 divided by histogram entries."
71 "Set negative value to calculate from histogram information automatically.", (float)(0.0001)); //,(float)1e-6);
72 addParam("initialP1", m_initialP1, "initial value of the fit parameter p1."
73 "Set negative value to calculate from histogram information automatically.", (float)(1.0)); //,(float)1.0);
74 addParam("initialP2", m_initialP2, "initial value of the fit parameter p2."
75 "Set negative value to calculate from histogram information automatically.", (float)(1.0)); //,(float)1.0);
76 addParam("initialX0", m_initialX0, "initial value of the fit parameter x0 divided by histogram bin width."
77 "Set negative value to calculate from histogram information automatically.", (float)(100)); //, (float)100.);
78 addParam("pedestalSigma", m_pedestalSigma, "sigma of pedestal width", (float)10.);
79 addParam("fitoption", m_fitoption, "fit option likelihood: default chisquare: R", std::string("L"));
80
81 }

◆ TOPGainFunc()

double TOPGainFunc ( double * var,
double * par )
static

Fit function of pulse charge (or charge) distribution for channel(pixel)-by-channel gain extraction, given by "[0]*pow(x-[4],[1])*exp(-pow(x-[4],[2])/[3])" smeared by Gaussian with a constant sigma to consider baseline fluctuation.

Definition at line 612 of file TOPGainEfficiencyCalculatorModule.cc.

613 {
614
615 double pedestal = par[4];
616 double pedestalWidth = par[5];
617 double x = (var[0] - pedestal);
618
619 double output = 0;
620 double step = pedestalWidth / 100.;
621 double t = TMath::Max(step, x - pedestalWidth * 10);
622 //double t = TMath::Max( g_xStep, x ); //for test
623 while (t < x + pedestalWidth * 10) {
624 output += TMath::Gaus(x, t, pedestalWidth) * TMath::Power(t / par[3], par[1])
625 * TMath::Exp((-1) * TMath::Power(t / par[3], par[2]));
626 t += step;
627 }
628 // TF1* func = new TF1( "func", "[0]*pow(x-[4],[1])*exp(-pow(x-[4],[2])/[3])",
629
630 return par[0] * output * step;
631 }

◆ TOPGeometryParInitializerModule()

Constructor.

Definition at line 39 of file TOPGeometryParInitializerModule.cc.

39 : Module()
40
41 {
42 // set module description
43 setDescription("Class for initializing TOPGeometryPar. "
44 "This class is by default initialized when Geant geometry is created. "
45 "Useful if Geant geometry is not needed. Be careful when using!");
46 setPropertyFlags(c_ParallelProcessingCertified);
47
48 // Add parameters
49 addParam("useDB", m_useDB,
50 "If true load the Geometry from the database instead of the gearbox", true);
51 }

◆ TOPInterimFENtupleModule()

Constructor.

Definition at line 47 of file TOPInterimFENtupleModule.cc.

47 : HistoModule()
48 {
49 setDescription("Create ntuple mainly from TOPDigit with double pulse identification. "
50 "Data taken with both InterimFE FW and production FW are available. (since Jan, 2017)");
51
52 addParam("calibrationChannel", m_calibrationChannel, "asic channel # where calibration pulses routed",
53 (unsigned)0);
54 addParam("saveWaveform", m_saveWaveform, "whether to save waveform data or not",
55 (bool)false);
56 addParam("useDoublePulse", m_useDoublePulse,
57 "set true when you require both of double calibration pulses for reference timing. You need to enable offline feature extraction.",
58 (bool)true);
59 // addParam("averageSamplingRate", m_averageSamplingRate, "sampling rate with assumption of uniform interval in a unit of GHz",
60 // (float)2.71394);
61 addParam("minHeightFirstCalPulse", m_calibrationPulseThreshold1, "pulse height threshold for the first cal. pulse",
62 (float)600.);
63 addParam("minHeightSecondCalPulse", m_calibrationPulseThreshold2, "pulse height threshold for the second cal. pulse",
64 (float)450.);
65 addParam("nominalDeltaT", m_calibrationPulseInterval, "nominal DeltaT (time interval of the double calibration pulses) [ns]",
66 (float)21.85);
67 addParam("nominalDeltaTRange", m_calibrationPulseIntervalRange,
68 "acceptable DeltaT shift from the noinal value before calibration [ns]",
69 (float)2.);
70 addParam("globalRefSlotNum", m_globalRefSlotNum,
71 "slot number where a global reference asic exists. slot01-asic0 (pixelId=1-8) is default.", 1);
72 addParam("globalRefAsicNum", m_globalRefAsicNum,
73 "asic number defined as int((pixelId-1)/8) of a global reference asic", 0);
74
75 addParam("timePerWin", m_timePerWin, "time interval of a single window (=64 samples) [ns]", (float)23.581939);
76 }

◆ TOPLaserCalibratorModule()

Constructor.

Definition at line 49 of file TOPLaserCalibratorModule.cc.

49 : Module()
50 {
51 setDescription("T0 Calibration using the laser calibration system");
52
53 std::vector<double> frange = {100, 0., 1.};
54 // Add parameters
55 addParam("dataFitOutput", m_dataFitOutput, "Output root file for data",
56 string("")); //output fitting results
57 addParam("mcInput", m_mcInput, "Input root file from MC", string(""));
58 addParam("channelT0constant", m_chT0C, "Output of channel T0 constant", string(""));
59 addParam("fitChannel", m_fitChannel, "set 0 - 511 to a specific channel; set 0 to all channels in the fit",
60 512);
61 addParam("barID", m_barID, "ID of TOP module to calibrate");
62 addParam("refCh", m_refCh, "reference channel of T0 constant");
63 addParam("fitMethod", m_fitMethod, "gauss: single gaussian; cb: single Crystal Ball; cb2: double Crystal Ball", string("gauss"));
64 addParam("fitRange", m_fitRange, "fit range[nbins, xmin, xmax]", frange);
65
66 for (int i = 0; i < c_NumChannels; ++i) {
67 m_histo[i] = 0;
68 }
69 }

◆ TOPLaserHitSelectorModule()

Constructor.

Definition at line 44 of file TOPLaserHitSelectorModule.cc.

44 : HistoModule()
45 {
46 // Set description()
47 setDescription("TOP pixel-by-pixel gain analysis - first step : create hit timing-pulse charge histogram");
48
49 // Add parameters
50 m_timeHistogramBinning.push_back(140);//140 for time axis
51 m_timeHistogramBinning.push_back(-55);//-25
52 m_timeHistogramBinning.push_back(15);//45
53 m_chargeHistogramBinning.push_back(125);//for height
54 m_chargeHistogramBinning.push_back(-50);//
55 m_chargeHistogramBinning.push_back(2450);//
56 m_chargeHistogramBinning.push_back(150);//for integral
57 m_chargeHistogramBinning.push_back(-500);//
58 m_chargeHistogramBinning.push_back(29500);//
59
60 addParam("timeHistogramBinning", m_timeHistogramBinning,
61 "histogram binning (the number of bins, lower limit, upper limit) for hit timing distribution (should be integer value)",
62 m_timeHistogramBinning);
63 addParam("chargeHistogramBinning", m_chargeHistogramBinning,
64 "histogram binning (the number of bins, lower limit, upper limit) for pulse charge distribution (should be integer value)",
65 m_chargeHistogramBinning);
66
67 // addParam("calibrationChannel", m_calibrationChannel, "asic channel # where calibration pulses routed",
68 // (unsigned)0);
69 addParam("useDoublePulse", m_useDoublePulse,
70 "set true when you require both of double calibration pulses for reference timing. You need to enable offline feature extraction.",
71 (bool)true);
72 addParam("minHeightFirstCalPulse", m_calibrationPulseThreshold1, "pulse height threshold for the first cal. pulse",
73 (float)300.);
74 addParam("minHeightSecondCalPulse", m_calibrationPulseThreshold2, "pulse height threshold for the second cal. pulse",
75 (float)100.);
76 addParam("nominalDeltaT", m_calibrationPulseInterval, "nominal DeltaT (time interval of the double calibration pulses) [ns]",
77 (float)25.5);
78 addParam("nominalDeltaTRange", m_calibrationPulseIntervalRange,
79 "acceptable DeltaT range from the nominal value before calibration [ns]",
80 (float)2.);
81 addParam("windowSelect", m_windowSelect,
82 "select window number (All=0, Odd=2, Even=1)",
83 0);
84 addParam("includePrimaryChargeShare", m_includePrimaryChargeShare,
85 "set true when you require without primary chargeshare cut for making 2D histogram",
86 (bool)false);
87 addParam("includeAllChargeShare", m_includeAllChargeShare,
88 "set true when you require without all chargeshare cut for making 2D histogram",
89 (bool)false);
90 }

◆ TOPMCTrackMakerModule()

Constructor.

Definition at line 45 of file TOPMCTrackMakerModule.cc.

45 : Module()
46
47 {
48 // set module description (e.g. insert text)
49 setDescription("Constructs Tracks and ExtHits from MCParticles and TOPBarHits. "
50 "Utility needed for testing and debugging of TOP reconstruction.");
51 setPropertyFlags(c_ParallelProcessingCertified);
52
53 // Add parameters
54
55 }

◆ TOPModuleT0CalibratorModule()

Constructor.

Definition at line 36 of file TOPModuleT0CalibratorModule.cc.

36 : Module()
37
38 {
39 // set module description
40 setDescription("Module T0 calibration with dimuons or bhabhas. "
41 "Useful when the geometrical alignment is fine.");
42 // setPropertyFlags(c_ParallelProcessingCertified);
43
44 // Add parameters
45 addParam("numBins", m_numBins, "number of bins of the search region", 200);
46 addParam("timeRange", m_timeRange,
47 "time range in which to search for the minimum [ns]", 10.0);
48 addParam("sigmaSmear", m_sigmaSmear,
49 "sigma in [ns] for additional smearing of PDF", 0.0);
50 addParam("sample", m_sample,
51 "sample type: one of dimuon, bhabha or cosmics", std::string("dimuon"));
52 addParam("minMomentum", m_minMomentum,
53 "minimal track momentum if sample is cosmics", 1.0);
54 addParam("deltaEcms", m_deltaEcms,
55 "c.m.s energy window (half size) if sample is dimuon or bhabha", 0.1);
56 addParam("dr", m_dr, "cut on POCA in r", 2.0);
57 addParam("dz", m_dz, "cut on POCA in abs(z)", 4.0);
58 addParam("minZ", m_minZ,
59 "minimal local z of extrapolated hit", -130.0);
60 addParam("maxZ", m_maxZ,
61 "maximal local z of extrapolated hit", 130.0);
62 addParam("outputFileName", m_outFileName,
63 "Root output file name containing calibration results. "
64 "File name can include *'s; "
65 "they will be replaced with a run number from the first input file",
66 std::string("moduleT0_r*.root"));
67 addParam("pdfOption", m_pdfOption,
68 "PDF option, one of 'rough', 'fine', 'optimal'", std::string("rough"));
69
70 }

◆ TOPModuleT0DeltaTCollectorModule()

Constructor.

Definition at line 32 of file TOPModuleT0DeltaTCollectorModule.cc.

33 {
34 // set module description and processing properties
35 setDescription("A collector for module T0 calibration with chi2 minimization of "
36 "time differences between slots (method DeltaT). Useful for initial "
37 "(rough) calibration, since the results are found slightly biased. "
38 "For the final (precise) calibration one has to use LL method.");
39 setPropertyFlags(c_ParallelProcessingCertified);
40
41 // module parameters
42 addParam("numBins", m_numBins,
43 "number of bins of histograms of time difference", 400);
44 addParam("timeRange", m_timeRange,
45 "time range [ns] of histograms of time difference", 20.0);
46
47 }

◆ TOPModuleT0LLCollectorModule()

Constructor.

Definition at line 45 of file TOPModuleT0LLCollectorModule.cc.

46 {
47 // set module description and processing properties
48 setDescription("A collector for module T0 calibration with neg. log likelihood "
49 "minimization (method LL). Aimed for the final (precise) calibration"
50 "after initial one with DeltaT method.");
51 setPropertyFlags(c_ParallelProcessingCertified);
52
53 // module parameters
54 addParam("numBins", m_numBins, "number of bins of the search region", 200);
55 addParam("timeRange", m_timeRange,
56 "time range in which to search for the minimum [ns]", 10.0);
57 addParam("sigmaSmear", m_sigmaSmear,
58 "sigma in [ns] for additional smearing of PDF", 0.0);
59 addParam("sample", m_sample,
60 "sample type: one of dimuon or bhabha", std::string("dimuon"));
61 addParam("deltaEcms", m_deltaEcms,
62 "c.m.s energy window (half size) if sample is dimuon or bhabha", 0.1);
63 addParam("dr", m_dr, "cut on POCA in r", 2.0);
64 addParam("dz", m_dz, "cut on POCA in abs(z)", 4.0);
65 addParam("minZ", m_minZ,
66 "minimal local z of extrapolated hit", -130.0);
67 addParam("maxZ", m_maxZ,
68 "maximal local z of extrapolated hit", 130.0);
69 addParam("pdfOption", m_pdfOption,
70 "PDF option, one of 'rough', 'fine', 'optimal'", std::string("rough"));
71
72 }

◆ TOPNtupleModule()

Constructor.

Definition at line 57 of file TOPNtupleModule.cc.

57 : Module()
58 {
59 // set module description
60 setDescription("Writes ntuple of TOPLikelihoods with tracking info into a root file");
61
62 // Add parameters
63 addParam("outputFileName", m_outputFileName, "Output file name",
64 string("TOPNtuple.root"));
65
66 }

◆ TOPOffsetCollectorModule()

Constructor.

Definition at line 32 of file TOPOffsetCollectorModule.cc.

33 {
34 // set module description and processing properties
35 setDescription("A collector for eventT0 and fill pattern offset calibrations");
36 setPropertyFlags(c_ParallelProcessingCertified);
37
38 }

◆ TOPPackerModule()

Constructor.

Definition at line 48 of file TOPPackerModule.cc.

48 : Module()
49 {
50 // set module description (e.g. insert text)
51 setDescription("Raw data packer for TOP");
52 setPropertyFlags(c_ParallelProcessingCertified);
53
54 // Add parameters
55 addParam("inputDigitsName", m_inputDigitsName,
56 "name of TOPDigit store array", string(""));
57 addParam("inputRawDigitsName", m_inputRawDigitsName,
58 "name of TOPRawDigit store array", string(""));
59 addParam("outputRawDataName", m_outputRawDataName,
60 "name of RawTOP store array", string(""));
61 addParam("format", m_format,
62 "data format (draft, FE, production)", string("production"));
63
64 }

◆ TOPPDFCheckerModule()

Constructor.

Definition at line 52 of file TOPPDFCheckerModule.cc.

52 : HistoModule()
53
54 {
55 // set module description
56 setDescription("Module for checking analytic PDF used in likelihood calculation");
57 setPropertyFlags(c_ParallelProcessingCertified);
58
59 // Add parameters
60 addParam("minTime", m_minTime,
61 "histogram lower bound in time [ns]", 0.0);
62 addParam("maxTime", m_maxTime,
63 "histogram upper bound in time [ns]", 50.0);
64 addParam("numBins", m_numBins,
65 "histogram number of bins in time", 1000);
66
67 }

◆ TOPPDFDebuggerModule()

Constructor.

Definition at line 49 of file TOPPDFDebuggerModule.cc.

49 : Module()
50 {
51 // Set description
52 setDescription("This module makes an analytic PDF available in "
53 "a store array TOPPDFCollections, related from Tracks");
54
55 // Set property flags
56 setPropertyFlags(c_ParallelProcessingCertified);
57
58 // Add parameters
59 addParam("minTime", m_minTime,
60 "lower limit for photon time [ns] (default from DB used, if minTime >= maxTime)", 0.0);
61 addParam("maxTime", m_maxTime,
62 "upper limit for photon time [ns] (default from DB used, if minTime >= maxTime)", 0.0);
63 addParam("pdfOption", m_pdfOption,
64 "PDF option, one of 'rough', 'fine', 'optimal'", std::string("fine"));
65 addParam("pdgCodes", m_pdgCodes,
66 "PDG codes of charged stable particles for which to construct PDF. "
67 "Empty list means all charged stable particles.",
68 m_pdgCodes);
69 }

◆ TOPPhotonYieldsCollectorModule()

Constructor.

Definition at line 43 of file TOPPhotonYieldsCollectorModule.cc.

44 {
45 // set module description and processing properties
46 setDescription("A collector for photon pixel yields aimed for PMT ageing studies and for finding optically decoupled PMT's");
47 setPropertyFlags(c_ParallelProcessingCertified);
48
49 // module parameters
50 addParam("sample", m_sample, "sample type: one of dimuon or bhabha", std::string("dimuon"));
51 addParam("deltaEcms", m_deltaEcms, "c.m.s energy window (half size) if sample is dimuon or bhabha", 0.1);
52 addParam("dr", m_dr, "cut on POCA in r", 2.0);
53 addParam("dz", m_dz, "cut on POCA in abs(z)", 4.0);
54
55 }

◆ TOPPulseHeightCollectorModule()

Constructor.

Definition at line 31 of file TOPPulseHeightCollectorModule.cc.

32 {
33 // set module description and processing properties
34 setDescription("A collector for channel pulse-height distributions");
35 setPropertyFlags(c_ParallelProcessingCertified);
36
37 // module parameters
38 addParam("nx", m_nx, "number of histogram bins", 200);
39 addParam("xmax", m_xmax, "histogram upper limit [ADC counts]", 2000.0);
40 addParam("pulseWidthWindow", m_widthWindow,
41 "lower and upper bound of pulse-width selection window [ns]. "
42 "Empty list means no selection on the pulse width. "
43 "Note: selection on pulse width will influence pulse-height distribution.",
44 m_widthWindow);
45 addParam("timeWindow", m_timeWindow,
46 "lower and upper bound of time selection window [ns]. "
47 "Empty list means no selection on photon time.", m_timeWindow);
48
49 }

◆ TOPRawDigitConverterModule()

Constructor.

Definition at line 48 of file TOPRawDigitConverterModule.cc.

48 : Module()
49
50 {
51 // set module description (e.g. insert text)
52 setDescription("Converts row digits to digits and applies time calibration");
53 setPropertyFlags(c_ParallelProcessingCertified);
54
55 // Add parameters
56 addParam("inputRawDigitsName", m_inputRawDigitsName,
57 "name of TOPRawDigit store array", string(""));
58 addParam("outputDigitsName", m_outputDigitsName,
59 "name of TOPDigit store array", string(""));
60 addParam("useSampleTimeCalibration", m_useSampleTimeCalibration,
61 "if true, use sample time calibration", true);
62 addParam("useAsicShiftCalibration", m_useAsicShiftCalibration,
63 "if true, use ASIC shifts calibration", true);
64 addParam("useChannelT0Calibration", m_useChannelT0Calibration,
65 "if true, use channel T0 calibration", true);
66 addParam("useModuleT0Calibration", m_useModuleT0Calibration,
67 "if true, use module T0 calibration", true);
68 addParam("useCommonT0Calibration", m_useCommonT0Calibration,
69 "if true, use common T0 calibration", true);
70 addParam("useTimeWalkCalibration", m_useTimeWalkCalibration,
71 "if true, use time-walk calibration", true);
72 addParam("pedestalRMS", m_pedestalRMS,
73 "r.m.s of pedestals [ADC counts], "
74 "if positive, timeError will be estimated from FE data. "
75 "This is the default value used if r.m.s is not available from DB.", 9.7);
76 addParam("minPulseWidth", m_minPulseWidth,
77 "minimal pulse width [ns] to flag digit as good", 1.0);
78 addParam("maxPulseWidth", m_maxPulseWidth,
79 "maximal pulse width [ns] to flag digit as good", 10.0);
80 addParam("minWidthXheight", m_minWidthXheight,
81 "minimal product of width and height [ns * ADC counts]", 100.0);
82 addParam("storageDepth", m_storageDepth,
83 "ASIC analog storage depth of Interim FE format (ignored in other formats)",
84 (unsigned) 508);
85 addParam("lookBackWindows", m_lookBackWindows,
86 "number of look back windows, if positive override the number from database",
87 0);
88 addParam("setPhase", m_setPhase,
89 "if true, set (override) phase in TOPRawDigits", true);
90 addParam("calibrationChannel", m_calibrationChannel,
91 "calpulse selection: ASIC channel (use -1 to turn off the selection)", -1);
92 addParam("calpulseWidthMin", m_calpulseWidthMin,
93 "calpulse selection: minimal width [ns]", 0.0);
94 addParam("calpulseWidthMax", m_calpulseWidthMax,
95 "calpulse selection: maximal width [ns]", 0.0);
96 addParam("calpulseHeightMin", m_calpulseHeightMin,
97 "calpulse selection: minimal height [ADC counts]", 0);
98 addParam("calpulseHeightMax", m_calpulseHeightMax,
99 "calpulse selection: maximal height [ADC counts]", 0);
100 addParam("calpulseTimeMin", m_calpulseTimeMin,
101 "calpulse selection (ON if max > min): minimal time [ns]", 0.0);
102 addParam("calpulseTimeMax", m_calpulseTimeMax,
103 "calpulse selection (ON if max > min): maximal time [ns]", 0.0);
104 addParam("addRelations", m_addRelations, "if true, make relations to TOPRawDigits", true);
105
106 }

◆ TOPReconstructorModule()

Constructor.

Definition at line 41 of file TOPReconstructorModule.cc.

41 : Module()
42 {
43 // Set description
44 setDescription("Reconstruction for TOP counter. Uses reconstructed tracks "
45 "extrapolated to TOP and TOPDigits to calculate log likelihoods "
46 "for charged stable particles");
47
48 // Set property flags
49 setPropertyFlags(c_ParallelProcessingCertified);
50
51 // Add parameters
52 addParam("minTime", m_minTime,
53 "lower limit for photon time [ns] (if minTime >= maxTime use the default from DB)", 0.0);
54 addParam("maxTime", m_maxTime,
55 "upper limit for photon time [ns] (if minTime >= maxTime use the default from DB)", 0.0);
56 addParam("PDGCode", m_PDGCode,
57 "PDG code of hypothesis to construct pulls (0 means: use MC truth, -1: switched off)", -1);
58 addParam("deltaRayModeling", m_deltaRayModeling,
59 "include (True) or exclude (False) delta-ray modeling in log likelihood calculation", false);
60 addParam("pTCut", m_pTCut,
61 "pT cut to suppress badly extrapolated tracks that cannot reach TOP counter", 0.27);
62 addParam("TOPDigitCollectionName", m_topDigitCollectionName,
63 "Name of the collection of TOPDigits", string(""));
64 addParam("TOPLikelihoodCollectionName", m_topLikelihoodCollectionName,
65 "Name of the produced collection of TOPLikelihoods", string(""));
66 addParam("TOPPullCollectionName", m_topPullCollectionName, "Name of the collection of produced TOPPulls", string(""));
67 }

◆ TOPTBCComparatorModule()

Constructor.

Definition at line 41 of file TOPTBCComparatorModule.cc.

41 : HistoModule()
42 {
43 setDescription("TOP Time Base Correction monitor module ");
44
45 addParam("inputDirectorList", m_inputDirectoryList,
46 "List of the directories (one per IOV) in which the files with the calibration constants of the SCODS are stored. The format of each line must be: folderpath/ label ",
47 string(" "));
48 addParam("compareToPreviousSet", m_compareToPreviousSet,
49 "If true, each CalSet is compared to the previous one in the order determined by the inputDirectorList file. If false, the reference CalSet is the first of the list",
50 bool(true));
51 addParam("outputFile", m_outputFile,
52 "output file containing the monitoring plots", string("TBCComparisonResults.root"));
53 addParam("minCalPulses", m_minCalPulses,
54 "minimum number of calibration pulses need to flag a sample as non-empty", short(200));
55 addParam("numSamples", m_numSamples,
56 "number of samples that have been calibrated", short(256));
57
58 }

◆ TOPTimeBaseCalibratorModule()

Constructor.

Definition at line 54 of file TOPTimeBaseCalibratorModule.cc.

54 : Module()
55
56 {
57 // set module description
58 setDescription("Sample time calibrator");
59 // setPropertyFlags(c_ParallelProcessingCertified | c_InitializeInProcess);
60
61 // Add parameters
62 addParam("moduleID", m_moduleID, "slot ID to calibrate.");
63 addParam("minTimeDiff", m_minTimeDiff,
64 "lower bound on time difference [samples].", 0.0);
65 addParam("maxTimeDiff", m_maxTimeDiff,
66 "upper bound on time difference [samples].", 100.0);
67 addParam("directoryName", m_directoryName,
68 "name (with path) of the directory for the output root files.",
69 string(""));
70 addParam("minHits", m_minHits,
71 "minimal required hits per channel.", (unsigned) 1000);
72 addParam("numIterations", m_numIterations,
73 "number of iTBC iterations", (unsigned) 100);
74 addParam("numConvIter", m_conv_iter,
75 "Max number of iTBC iterations for conversion.", (unsigned) 50);
76 addParam("minChi2Change", m_dchi2_min,
77 "Minimal of chi2 change in iterations.", 0.2);
78 addParam("dtMin", m_dt_min,
79 "minimum Delta T of raw calpulse in iTBC", 20.0);
80 addParam("dtMax", m_dt_max,
81 "maximum Delta T of raw calpulse in iTBC", 24.0);
82 addParam("xStep", m_xstep,
83 "unit for an interaction of delta(X_s)", 0.020);
84 addParam("devStep", m_dev_step,
85 "a step size to calculate the value of d(chisq)/dxval", 0.001);
86 addParam("chgStep", m_change_xstep,
87 "update m_xstep if m_dchi2dxv < m_change_step", 0.015);
88 addParam("newStep", m_new_xstep,
89 "a new step for delta(X_s) if m_dchi2dxv < m_change_step", 2.0 * m_xstep);
90 addParam("sigm2_exp", m_sigm2_exp,
91 "(sigma_0(dT))**2 for nomarlization of chisq = sum{dT^2/sigma^2}", 0.0424 * 0.0424);
92
93 addParam("method", m_method, "method: 0 - profile histograms only, "
94 "1 - matrix inversion, 2 - iterative, "
95 "3 - matrix inversion w/ singular value decomposition.", (unsigned) 1);
96 addParam("useFallingEdge", m_useFallingEdge,
97 "if true, use cal pulse falling edge instead of rising edge", false);
98 addParam("saveMatrix", m_saveMatrix, "if true, save also matrix and its inverse in a root file", false);
99
100 }

◆ TOPTimeRecalibratorModule()

Constructor.

Definition at line 43 of file TOPTimeRecalibratorModule.cc.

43 : Module()
44
45 {
46 // set module description
47 setDescription("Utility module for re-calibrating time of TOPDigits. "
48 "Useful for checking new calibrations on existing cDST files. "
49 "Note that pulseWidth and timeError are not changed "
50 "although they also depend on time calibration.");
51 setPropertyFlags(c_ParallelProcessingCertified);
52
53 // Add parameters
54 addParam("useSampleTimeCalibration", m_useSampleTimeCalibration,
55 "if true, use sample time calibration", true);
56 addParam("useAsicShiftCalibration", m_useAsicShiftCalibration,
57 "if true, use ASIC shifts calibration", true);
58 addParam("useChannelT0Calibration", m_useChannelT0Calibration,
59 "if true, use channel T0 calibration", true);
60 addParam("useModuleT0Calibration", m_useModuleT0Calibration,
61 "if true, use module T0 calibration", true);
62 addParam("useCommonT0Calibration", m_useCommonT0Calibration,
63 "if true, use common T0 calibration", true);
64 addParam("useTimeWalkCalibration", m_useTimeWalkCalibration,
65 "if true, use time-walk calibration", true);
66 addParam("subtractBunchTime", m_subtractBunchTime,
67 "if true, subtract reconstructed bunch time", true);
68
69 }

◆ TOPTriggerDigitizerModule()

Constructor.

Definition at line 47 of file TOPTriggerDigitizerModule.cc.

47 : Module()
48 {
49 // Set description()
50 setDescription("Digitizer that provides time stamps for TOP trigger");
51 setPropertyFlags(c_ParallelProcessingCertified);
52
53 // Add parameters
54 addParam("threshold", m_threshold,
55 "pulse height threshold [ADC counts]", 27);
56 addParam("hysteresis", m_hysteresis,
57 "pulse height threshold hysteresis [ADC counts]", 10);
58 addParam("gateWidth", m_gateWidth,
59 "width of discriminator gate [samples]", 8);
60 addParam("samplingPhase", m_samplingPhase,
61 "sampling phase [samples]", 7);
62 }

◆ TOPUnpackerModule()

Constructor.

Definition at line 51 of file TOPUnpackerModule.cc.

51 : Module()
52 {
53 // set module description
54 setDescription("Raw data unpacker for TOP");
55 setPropertyFlags(c_ParallelProcessingCertified);
56
57 // Add parameters
58 addParam("inputRawDataName", m_inputRawDataName,
59 "name of RawTOP store array", string(""));
60 addParam("outputDigitsName", m_outputDigitsName,
61 "name of TOPDigit store array", string(""));
62 addParam("outputWaveformsName", m_outputWaveformsName,
63 "name of TOP(Raw/Production)Waveform store array", string(""));
64 addParam("outputRawDigitsName", m_outputRawDigitsName,
65 "name of TOPRawDigit store array", string(""));
66 addParam("outputTemplateFitResultName", m_templateFitResultName,
67 "name of TOPTemplateFitResult", string(""));
68 addParam("swapBytes", m_swapBytesDefault, "if true, swap bytes", false);
69 addParam("dataFormat", m_dataFormat,
70 "data format as defined in top/include/RawDataTypes.h, 0 = auto detect", 0);
71 addParam("addRelations", m_addRelations,
72 "if true, make relations to TOPProductionHitDebugs (production debug data format only)", true);
73 addParam("errorSuppressFactor", m_errorSuppressFactor,
74 "error messages suppression factor (0 = no suppression)", (unsigned) 1000);
75
76 }

◆ TOPValidationCollectorModule()

Constructor.

Definition at line 48 of file TOPValidationCollectorModule.cc.

49 {
50 // set module description and processing properties
51 setDescription("A collector for automatic validation of TOP calibration");
52 setPropertyFlags(c_ParallelProcessingCertified);
53
54 // module parameters
55 addParam("numBins", m_numBins, "number of bins of the search region", 100);
56 addParam("timeRange", m_timeRange,
57 "time range in which to search for the minimum [ns]", 10.0);
58 addParam("sigmaSmear", m_sigmaSmear,
59 "sigma in [ns] for additional smearing of PDF", 0.0);
60 addParam("sample", m_sample,
61 "sample type: one of dimuon or bhabha", std::string("dimuon"));
62 addParam("deltaEcms", m_deltaEcms,
63 "c.m.s energy window (half size) if sample is dimuon or bhabha", 0.1);
64 addParam("dr", m_dr, "cut on POCA in r", 2.0);
65 addParam("dz", m_dz, "cut on POCA in abs(z)", 4.0);
66 addParam("minZ", m_minZ,
67 "minimal local z of extrapolated hit", -130.0);
68 addParam("maxZ", m_maxZ,
69 "maximal local z of extrapolated hit", 130.0);
70 addParam("pdfOption", m_pdfOption,
71 "PDF option, one of 'rough', 'fine', 'optimal'", std::string("rough"));
72
73 }

◆ TOPWaveformFeatureExtractorModule()

Constructor.

Definition at line 44 of file TOPWaveformFeatureExtractorModule.cc.

44 : Module()
45
46 {
47 // set module description (e.g. insert text)
48 setDescription("Module adds raw digits that are found in waveforms "
49 "but not already present in TOPRawDigits. "
50 "Only waveforms related to TOPRawDigits are used.");
51 setPropertyFlags(c_ParallelProcessingCertified);
52
53 addParam("inputRawDigitsName", m_inputRawDigitsName,
54 "name of TOPRawDigit store array", string(""));
55 addParam("threshold", m_threshold,
56 "pulse height threshold [ADC counts]", 40);
57 addParam("hysteresis", m_hysteresis,
58 "threshold hysteresis [ADC counts]", 10);
59 addParam("thresholdCount", m_thresholdCount,
60 "minimal number of samples above threshold", 3);
61 addParam("setIntegral", m_setIntegral,
62 "calculate and set integral for online-extracted hits", true);
63
64 }

◆ TOPWaveformQualityPlotterModule()

Constructor.

Definition at line 38 of file TOPWaveformQualityPlotterModule.cc.

39 : HistoModule()
40 {
41 setDescription("TOP DQM histogram module");
42 addParam("histogramDirectoryName", m_histogramDirectoryName,
43 "histogram directory in ROOT file", string("TOP"));
44 addParam("drawWaves", m_DRAWWAVES, "option to draw waveforms", true);
45 addParam("debugHistos", m_DEBUGGING, "option to draw debug histograms", true);
46 addParam("noisemaps", m_NOISE, "option to draw noisemaps", false);
47 }

◆ unpackHeadersInterimFEVer01()

bool unpackHeadersInterimFEVer01 ( const int * buffer,
int bufferSize,
bool swapBytes )
staticprivate

Tries to unpack raw data assuming it is in feature-extraction interim format.

Does not write out anything, just checks integrity.

Parameters
bufferraw data buffer
bufferSizebuffer size
swapBytesif true, swap bytes in buffer
Returns
true if buffer resembles interim format, false if not.

Definition at line 347 of file TOPUnpackerModule.cc.

348 {
349 B2DEBUG(22, "Checking whether buffer unpacks as InterimFEVer01, dataSize = " << bufferSize);
350
351 DataArray array(buffer, bufferSize, swapBytes);
352
353 array.getWord(); // header word 0
354 array.getWord(); // header word 1 (what it contains?)
355 while (array.getRemainingWords() > 0) {
356 unsigned header = array.getWord(); // word 0
357 if ((header & 0xFF) == 0xBE) { //this is a super short FE header
358 continue;
359 }
360
361 if (header != 0xaaaa0104 and header != 0xaaaa0103 and header != 0xaaaa0100) {//cannot be interim firmware
362 return false; //abort
363 }
364
365
366 array.getWord(); // word 1
367 array.getWord(); // word 2
368
369 if (header != 0xaaaa0104) {
370 // feature-extracted data (positive signal)
371 array.getWord(); // word 3
372 array.getWord(); // word 4
373 array.getWord(); // word 5
374 array.getWord(); // word 6
375 array.getWord(); // word 7
376 array.getWord(); // word 8
377 array.getWord(); // word 9
378 array.getWord(); // word 10
379 array.getWord(); // word 11
380 array.getWord(); // word 12
381 array.getWord(); // word 13
382 array.getWord(); // word 14
383 }
384
385 unsigned magicWord = array.getWord(); // word 15
386 if (magicWord != 0x7473616c) {//invalid magic word
387 return false; //abort
388 }
389
390 if (header != 0xaaaa0103) continue;
391 array.getWord(); // word 16
392
393 array.getWord(); // word 17
394 array.getWord(); // word 18
395 array.getWord(); // word 19
396
397 array.getWord(); // word 20
398
399 array.getWord(); // word 21
400
401 array.getWord(); // word 22
402
403 int numWords = 4 * 32; // (numPoints + 1) / 2;
404 if (array.getRemainingWords() < numWords) { //not enough remaining words for waveform data
405 return false; //abort
406 }
407
408 for (int i = 0; i < numWords; i++) {
409 array.getWord();
410 }
411 }
412
413 return true;
414 }

◆ unpackInterimFEVer01()

int unpackInterimFEVer01 ( const int * buffer,
int bufferSize,
bool pedestalSubtracted )
private

Unpack raw data given in feature-extraction interim format.

Parameters
bufferraw data buffer
bufferSizebuffer size
pedestalSubtractedfalse for version 2, true for version 3
Returns
number of words remaining in data buffer

Definition at line 417 of file TOPUnpackerModule.cc.

419 {
420
421 B2DEBUG(22, "Unpacking InterimFEVer01 to TOPRawDigits and TOPRawWaveforms, "
422 "dataSize = " << bufferSize);
423
424 int moduleID = 0;
425 int boardstack = 0;
426
427 DataArray array(buffer, bufferSize, m_swapBytes);
428
429 map<unsigned short, int> evtNumCounter; //counts the occurrence of carrier-generated event numbers.
430 std::vector<unsigned short> channelCounter(128, 0); //counts occurrence of carrier/asic/channel combinations
431
432 unsigned word = array.getWord(); // header word 0
433 unsigned short scrodID = word & 0x0FFF;
434 auto* info = m_interimFEInfos.appendNew(scrodID, bufferSize);
435
436 word = array.getWord(); // header word 1 (what it contains?)
437
438
439 while (array.getRemainingWords() > 0) {
440
441 unsigned header = array.getWord(); // word 0
442
443 if ((header & 0xFF) == 0xBE) { //this is a super short FE header
444// B2DEBUG(21, "0b" << std::bitset<8>(header & 0xFF) << " " << std::bitset<8>((header>>8) & 0xFF) << " " << std::bitset<8>((header>>16) & 0xFF) << " " << std::bitset<8>((header>>24) & 0xFF));
445
446 unsigned short scrodID_SSFE;
447 unsigned short carrier_SSFE;
448 unsigned short asic_SSFE;
449 unsigned short channel_SSFE;
450 unsigned short evtNum_SSFE;
451
452 evtNum_SSFE = (header >> 8) & 0xFF;
453 scrodID_SSFE = (header >> 16) & 0x7F;
454 channel_SSFE = (header >> 24) & 0x07;
455 asic_SSFE = (header >> 27) & 0x03;
456 carrier_SSFE = (header >> 29) & 0x03;
457
458 const auto* feemap = m_topgp->getFrontEndMapper().getMap(scrodID_SSFE);
459 if (feemap) {
460 moduleID = feemap->getModuleID();
461 boardstack = feemap->getBoardstackNumber();
462 } else {
463 B2ERROR("TOPUnpacker: no front-end map available."
464 << LogVar("SCROD ID", scrodID_SSFE));
465 info->setErrorFlag(TOPInterimFEInfo::c_InvalidScrodID);
466 }
467
468 if (scrodID_SSFE != scrodID) {
469 B2ERROR("TOPUnpacker: corrupted data - "
470 << "different scrodID's in HLSB and super short FE header."
471 << LogVar("SCROD", scrodID_SSFE)
472 << LogVar("slot", moduleID)
473 << LogVar("BS", boardstack));
474 B2DEBUG(21, "Different scrodID's in HLSB and FE header: " << scrodID << " " << scrodID_SSFE << " word = 0x" << std::hex << word);
475 info->setErrorFlag(TOPInterimFEInfo::c_DifferentScrodIDs);
476 return array.getRemainingWords();
477 }
478
479 B2DEBUG(21, scrodID_SSFE << "\t" << carrier_SSFE << "\t" << asic_SSFE << "\t" << channel_SSFE << "\t" << evtNum_SSFE);
480
481 int channelID = carrier_SSFE * 32 + asic_SSFE * 8 + channel_SSFE;
482 channelCounter[channelID] += 1;
483 evtNumCounter[evtNum_SSFE] += 1;
484
485 info->incrementFEHeadersCount();
486 info->incrementEmptyFEHeadersCount();
487
488 continue;
489 }
490
491 if (header != 0xaaaa0104 and header != 0xaaaa0103 and header != 0xaaaa0100) {
492 B2ERROR("TOPUnpacker: corrupted data - invalid FE header word");
493 B2DEBUG(21, "Invalid FE header word: " << std::hex << header << " 0b" << std::bitset<32>(header));
494 B2DEBUG(21, "SCROD ID: " << scrodID << " " << std::hex << scrodID);
495
496 info->setErrorFlag(TOPInterimFEInfo::c_InvalidFEHeader);
497 return array.getRemainingWords();
498 }
499
500
501 word = array.getWord(); // word 1
502 unsigned short scrodID_FE = word >> 25;
503 unsigned short convertedAddr = (word >> 16) & 0x1FF;
504 unsigned short evtNum_numWin_trigPat_FEheader = word & 0xFFFF;
505 unsigned short evtNum_FEheader = evtNum_numWin_trigPat_FEheader & 0xFF;
506 evtNumCounter[evtNum_FEheader] += 1;
507
508 if (scrodID_FE != scrodID) {
509 B2ERROR("TOPUnpacker: different scrodID's in HLSB and FE header."
510 << LogVar("scrodID (HSLB)", scrodID)
511 << LogVar("scrodID (FE)", scrodID_FE));
512
513 info->setErrorFlag(TOPInterimFEInfo::c_DifferentScrodIDs);
514 return array.getRemainingWords();
515 }
516
517 word = array.getWord(); // word 2
518 // unsigned lastWrAddr = word & 0x1FF;
519 unsigned lastWrAddr = (word & 0x0FF) << 1;
520 //unsigned short asicChannelFE = (word >> 9) & 0x07;
521 unsigned short asicChannelFE = (word >> 8) & 0x07;
522 unsigned short asicFE = (word >> 12) & 0x03;
523 unsigned short carrierFE = (word >> 14) & 0x03;
524 unsigned short channelID = carrierFE * 32 + asicFE * 8 + asicChannelFE;
525 //B2DEBUG(21, "carrier asic chn " << carrierFE << " " << asicFE << " " << asicChannelFE << " " << channelID << " 0b" << std::bitset<32>(word) );
526
527 B2DEBUG(21, scrodID_FE << "\t" << carrierFE << "\t" << asicFE << "\t" << asicChannelFE << "\t" << evtNum_FEheader);
528
529 channelCounter[channelID] += 1;
530
531 std::vector<TOPRawDigit*> digits; // needed for creating relations to waveforms
532
533 if (header != 0xaaaa0104) {
534 // feature-extracted data (positive signal)
535 array.getWord(); // word 3
536 word = array.getWord(); // word 4
537 short samplePeak_p = word & 0xFFFF;
538 short valuePeak_p = (word >> 16) & 0xFFFF;
539
540 word = array.getWord(); // word 5
541 short sampleRise_p = word & 0xFFFF;
542 short valueRise0_p = (word >> 16) & 0xFFFF;
543
544 word = array.getWord(); // word 6
545 short valueRise1_p = word & 0xFFFF;
546 short sampleFall_p = (word >> 16) & 0xFFFF;
547
548 word = array.getWord(); // word 7
549 short valueFall0_p = word & 0xFFFF;
550 short valueFall1_p = (word >> 16) & 0xFFFF;
551
552 word = array.getWord(); // word 8
553 short integral_p = word & 0xFFFF;
554 // short qualityFlags_p = (word >> 16) & 0xFFFF;
555
556 // feature-extracted data (negative signal)
557 array.getWord(); // word 9
558 //word = array.getWord(); // word 9
559 //short n_samp_i = (word >> 16) & 0xFFFF;
560 word = array.getWord(); // word 10
561 short samplePeak_n = word & 0xFFFF;
562 short valuePeak_n = (word >> 16) & 0xFFFF;
563
564 array.getWord(); // word 11
565 //word = array.getWord(); // word 11
566 //short sampleRise_n = word & 0xFFFF;
567 //short valueRise0_n = (word >> 16) & 0xFFFF;
568
569 array.getWord(); // word 12
570 //word = array.getWord(); // word 12
571 //short valueRise1_n = word & 0xFFFF;
572 //short sampleFall_n = (word >> 16) & 0xFFFF;
573
574 array.getWord(); // word 13
575 //word = array.getWord(); // word 13
576 //short valueFall0_n = word & 0xFFFF;
577 //short valueFall1_n = (word >> 16) & 0xFFFF;
578
579 word = array.getWord(); // word 14
580 short integral_n = word & 0xFFFF;
581 short qualityFlags_n = (word >> 16) & 0xFFFF;
582
583 if (abs(valuePeak_p) != 9999) {
584 auto* digit = m_rawDigits.appendNew(scrodID, TOPRawDigit::c_Interim);
585 digit->setCarrierNumber(carrierFE);
586 digit->setASICNumber(asicFE);
587 digit->setASICChannel(asicChannelFE);
588 digit->setASICWindow(convertedAddr);
589 digit->setLastWriteAddr(lastWrAddr);
590 digit->setSampleRise(sampleRise_p);
591 digit->setDeltaSamplePeak(samplePeak_p - sampleRise_p);
592 digit->setDeltaSampleFall(sampleFall_p - sampleRise_p);
593 digit->setValueRise0(valueRise0_p);
594 digit->setValueRise1(valueRise1_p);
595 digit->setValuePeak(valuePeak_p);
596 digit->setValueFall0(valueFall0_p);
597 digit->setValueFall1(valueFall1_p);
598 digit->setIntegral(integral_p);
599 // digit->setErrorFlags(qualityFlags_p); // not good solution !
600 digit->addRelationTo(info);
601 digits.push_back(digit);
602 //template fit result is saved in negative pulse fe data
603 if (valuePeak_p < 150) {
604 auto* tlpfResult = m_templateFitResults.appendNew();
605 tlpfResult->setBackgroundOffset(samplePeak_n);
606 tlpfResult->setAmplitude(valuePeak_n);
607 tlpfResult->setChisquare(qualityFlags_n);
608 tlpfResult->setRisingEdgeAndConvert(integral_n);
609 digit->addRelationTo(tlpfResult);
610 }
611 }
612 /*if (abs(valuePeak_n) != 9999) {
613 auto* digit = m_rawDigits.appendNew(scrodID, TOPRawDigit::c_Interim);
614 digit->setCarrierNumber(carrierFE);
615 digit->setASICNumber(asicFE);
616 digit->setASICChannel(asicChannelFE);
617 digit->setASICWindow(convertedAddr);
618 digit->setLastWriteAddr(lastWrAddr);
619 digit->setSampleRise(sampleRise_n);
620 digit->setDeltaSamplePeak(samplePeak_n - sampleRise_n);
621 digit->setDeltaSampleFall(sampleFall_n - sampleRise_n);
622 digit->setValueRise0(valueRise0_n);
623 digit->setValueRise1(valueRise1_n);
624 digit->setValuePeak(valuePeak_n);
625 digit->setValueFall0(valueFall0_n);
626 digit->setValueFall1(valueFall1_n);
627 digit->setIntegral(integral_n);
628 // digit->setErrorFlags(qualityFlags_n); // not good solution !
629 digit->addRelationTo(info);
630 digits.push_back(digit);
631 }*/
632 }
633
634 // magic word
635 word = array.getWord(); // word 15
636 if (word != 0x7473616c) {
637 //B2ERROR("TOPUnpacker: corrupted data - no magic word at the end of FE header");
638 //B2DEBUG(21, "No magic word at the end of FE header, found: "
639 //<< std::hex << word);
640 info->setErrorFlag(TOPInterimFEInfo::c_InvalidMagicWord);
641 //return array.getRemainingWords(); do not abort event for now as footer is invalid in current debugging version of firmware
642 }
643
644 // store to raw digits
645
646 info->incrementFEHeadersCount();
647 if (digits.empty()) info->incrementEmptyFEHeadersCount();
648
649 if (header != 0xaaaa0103) continue;
650
651 // waveform header
652 word = array.getWord(); // word 16
653 unsigned long evtNum_numWaves_refWin_WFheader = word;
654 unsigned short evtNum_WFheader = (evtNum_numWaves_refWin_WFheader >> 24) & 0xFF;
655
656 if (evtNum_WFheader != evtNum_FEheader) {
657 B2ERROR("TOPUnpacker: different carrier event number in WF and FE header."
658 << LogVar("Event number (FE header)", evtNum_FEheader)
659 << LogVar("Event number (WF header)", evtNum_WFheader));
660 }
661
662 array.getWord(); // word 17
663 array.getWord(); // word 18
664 word = array.getWord(); // word 19
665 // int numPoints = (word >> 16) & 0xFFFF;
666 unsigned short carrier = (word >> 14) & 0x03;
667 unsigned short asic = (word >> 12) & 0x03;
668 unsigned short asicChannel = (word >> 9) & 0x07;
669 unsigned short window = word & 0x1FF;
670
671 // checks for data corruption
672 if (carrier != carrierFE) {
673 B2ERROR("TOPUnpacker: different carrier numbers in FE and WF header");
674 B2DEBUG(21, "Different carrier numbers in FE and WF header: "
675 << carrierFE << " " << carrier);
676 info->setErrorFlag(TOPInterimFEInfo::c_DifferentCarriers);
677 }
678 if (asic != asicFE) {
679 B2ERROR("TOPUnpacker: different ASIC numbers in FE and WF header");
680 B2DEBUG(21, "Different ASIC numbers in FE and WF header: "
681 << asicFE << " " << asic);
682 info->setErrorFlag(TOPInterimFEInfo::c_DifferentAsics);
683 }
684 if (asicChannel != asicChannelFE) {
685 B2ERROR("TOPUnpacker: different ASIC channel numbers in FE and WF header");
686 B2DEBUG(21, "Different ASIC channel numbers in FE and WF header: "
687 << asicChannelFE << " " << asicChannel);
688 info->setErrorFlag(TOPInterimFEInfo::c_DifferentChannels);
689 }
690 if (window != convertedAddr) {
691 B2ERROR("TOPUnpacker: different window numbers in FE and WF header");
692 B2DEBUG(21, "Different window numbers in FE and WF header: "
693 << convertedAddr << " " << window);
694 info->setErrorFlag(TOPInterimFEInfo::c_DifferentWindows);
695 }
696
697 // reading out all four window addresses
698 // to be for correcnt alignment of individual readout windows in written waveform
699 std::vector<unsigned short> windows;
700 windows.push_back(window);
701
702 word = array.getWord(); // word 20
703 windows.push_back(word & 0x1FF);
704
705 word = array.getWord(); // word 21
706 windows.push_back(word & 0x1FF);
707
708 word = array.getWord(); // word 22
709 windows.push_back(word & 0x1FF);
710
711 int numWords = 4 * 32; // (numPoints + 1) / 2;
712 if (array.getRemainingWords() < numWords) {
713 B2ERROR("TOPUnpacker: too few words for waveform data."
714 << LogVar("needed", numWords)
715 << LogVar("available", array.getRemainingWords()));
716 info->setErrorFlag(TOPInterimFEInfo::c_InsufficientWFData);
717 return array.getRemainingWords();
718 }
719
720 // unpack waveforms
721 std::vector<short> adcData;
722 for (int i = 0; i < numWords; i++) {
723 word = array.getWord();
724 adcData.push_back(word & 0xFFFF);
725 adcData.push_back((word >> 16) & 0xFFFF);
726 }
727 // if (numWords * 2 != numPoints) adcData.pop_back(); // numPoints is even
728
729 // determine slot number (moduleID) and boardstack
730 moduleID = 0;
731 boardstack = 0;
732 const auto* feemap = m_topgp->getFrontEndMapper().getMap(scrodID);
733 if (feemap) {
734 moduleID = feemap->getModuleID();
735 boardstack = feemap->getBoardstackNumber();
736 } else {
737 B2ERROR("TOPUnpacker: no front-end map available."
738 << LogVar("SCROD ID", scrodID));
739 info->setErrorFlag(TOPInterimFEInfo::c_InvalidScrodID);
740 }
741
742 // determine hardware channel and pixelID (valid only if feemap available!)
743 const auto& mapper = m_topgp->getChannelMapper();
744 unsigned channel = mapper.getChannel(boardstack, carrier, asic, asicChannel);
745 int pixelID = mapper.getPixelID(channel);
746
747 // store to raw waveforms
748 auto* waveform = m_waveforms.appendNew(moduleID, pixelID, channel, scrodID,
749 window, 0, adcData);
750 waveform->setLastWriteAddr(lastWrAddr);
751 waveform->setStorageWindows(windows);
752 waveform->setPedestalSubtractedFlag(pedestalSubtracted);
753 waveform->addRelationTo(info);
754 info->incrementWaveformsCount();
755
756 // create relations btw. raw digits and waveform
757 for (const auto* digit : digits) digit->addRelationTo(waveform);
758
759 }
760
761 if (evtNumCounter.size() != 1) {
762 B2ERROR("TOPUnpacker: Possible frame shift detected "
763 << "(More than one unique carrier event number in this readout event)."
764 << LogVar("SCROD", scrodID)
765 << LogVar("slot", moduleID)
766 << LogVar("BS", boardstack));
767 }
768
769 int nASICs = 0;
770
771 string evtNumOutputString;
772 evtNumOutputString += "Carrier event numbers and their counts for SCROD ID " + std::to_string(scrodID) + ":\n";
773 for (auto const& it : evtNumCounter) {
774 nASICs += it.second;
775 evtNumOutputString += std::to_string(it.first) + ":\t" + std::to_string(it.second) + "\n";
776 }
777 evtNumOutputString += "Total:\t" + std::to_string(nASICs);
778 B2DEBUG(21, evtNumOutputString);
779
780 int nChannels = 0;
781 int nChannelsDiff = 0;
782
783 string channelOutputString;
784 channelOutputString += "Detected channels and their counts for SCROD ID (channels with count == 1 are omitted)" + std::to_string(
785 scrodID) + ":\n";
786
787 int channelIndex(0);
788 for (auto const& it : channelCounter) {
789 if (it > 0) {
790 nChannelsDiff += 1;
791 }
792 nChannels += it;
793
794 if (it != 1) {
795 int channelID = channelIndex;
796 int carrier = channelID / 32;
797 int asic = (channelID % 32) / 8;
798 int chn = channelID % 8;
799 channelOutputString += "carrier: " + std::to_string(carrier) + " asic: " + std::to_string(asic) + " chn: " + std::to_string(
800 chn) + " occurrence: " + std::to_string(it) + "\n";
801 B2WARNING("TOPUnpacker: interim FE - ASIC channel seen more than once"
802 << LogVar("ScrodID", scrodID)
803 << LogVar("carrier", carrier)
804 << LogVar("ASIC", asic)
805 << LogVar("channel", chn)
806 << LogVar("times seen", it));
807 }
808 channelIndex += 1;
809 }
810
811 m_channelStatistics[nChannels] += 1;
812
813 channelOutputString += "Total:\t" + std::to_string(nChannels) + " " + std::to_string(nChannelsDiff);
814 B2DEBUG(21, channelOutputString);
815
816 return array.getRemainingWords();
817
818
819 }

◆ unpackProdDebug()

int unpackProdDebug ( const int * buffer,
int bufferSize,
TOP::RawDataType dataFormat,
bool pedestalSubtracted,
int expNo )
private

Unpack raw data given in production debugging format.

Parameters
bufferraw data buffer
bufferSizebuffer size
dataFormatdata format
pedestalSubtractedtrue, if pedestal is subtracted in waveforms
expNoexperiment number
Returns
number of words remaining in data buffer

Definition at line 822 of file TOPUnpackerModule.cc.

824 {
825
826 B2DEBUG(22, "Unpacking Production firmware debug data format to TOPRawDigits "
827 "dataSize = " << bufferSize);
828
829 DataArray array(buffer, bufferSize, m_swapBytes);
830 unsigned word;
831
832 word = array.getWord(); // word 0, type(8)/version(8)/0xA(4)/ScrodID(12)
833 unsigned int evtType = word >> 24;
834 unsigned int evtVersion = (word >> 16) & 0xFF;
835 unsigned int evtMagicHeader = (word >> 12) & 0xF;
836 unsigned int evtScrodID = word & 0xFFF;
837
838 // determine slot number (moduleID) and boardstack
839 int moduleID = 0;
840 int boardstack = 0;
841 const auto* feemap = m_topgp->getFrontEndMapper().getMap(evtScrodID);
842 if (feemap) {
843 moduleID = feemap->getModuleID();
844 boardstack = feemap->getBoardstackNumber();
845 } else {
846 B2WARNING("TOPUnpacker: no front-end map available."
847 << LogVar("SCROD ID", evtScrodID));
848 }
849
850
851 B2DEBUG(22, std::dec << array.getIndex() << ":\t" << setfill('0') << setw(4) << std::hex <<
852 (word >> 16) << " " << setfill('0') << setw(4) << (word & 0xFFFF) << std::dec
853 << "\tevtType = " << evtType
854 << ", evtVersion = " << evtVersion
855 << ", evtMagicHeader = " << evtMagicHeader
856 << ", evtScrodID = " << evtScrodID);
857
858 if (evtMagicHeader != 0xA) {
859 B2WARNING("TOPUnpacker: event header magic word mismatch. should be 0xA."
860 << LogVar("Magic word", evtMagicHeader));
861 return array.getRemainingWords();
862 }
863
864 word = array.getWord(); // word 1, extra(3)/numWordsBonus(13)/phase(4)/numWordsCore(12)
865 unsigned int evtExtra = word >> 29;
866 unsigned int evtNumWordsBonus = (word >> 16) & 0x1FFF;
867 unsigned int evtPhase = (word >> 12) & 0xF;
868 unsigned int evtNumWordsCore = word & 0xFFF;
869
870 B2DEBUG(22, std::dec << array.getIndex() << ":\t" << setfill('0') << setw(4) << std::hex <<
871 (word >> 16) << " " << setfill('0') << setw(4) << (word & 0xFFFF) << std::dec
872 << "\tevtExtra = " << evtExtra
873 << ", evtNumWordsBonus = " << evtNumWordsBonus
874 << ", evtPhase = " << evtPhase
875 << ", numWordsCore = " << evtNumWordsCore);
876
877 word = array.getWord(); // word 2, skipHit(1)/injVetoFlag(1)/PSBypass(3)/ctime LSBs(11)/revo9counter(16)
878 bool evtSkipHit = word >> 31;
879 bool injVetoFlag = (word >> 30) & 0x1;
880 unsigned int PSBypass = (word >> 27) & 0x7;
881 unsigned int evtCtime = (word >> 16) & 0x7FF;
882 unsigned int evtRevo9Counter = word & 0xFFFF;
883
884 if (expNo > 36) m_injectionVeto->set(injVetoFlag); // before this experiment the bit field is not used and may not be correctly set
885
886 B2DEBUG(22, std::dec << array.getIndex() << ":\t" << setfill('0') << setw(4) << std::hex <<
887 (word >> 16) << " " << setfill('0') << setw(4) << (word & 0xFFFF) << std::dec
888 << "\tevtSkipHit = " << evtSkipHit
889 << ", injVetoFlag = " << injVetoFlag
890 << ", PSBypass = " << PSBypass
891 << ", evtCtime = " << evtCtime
892 << ", evtRevo9Counter = " << evtRevo9Counter);
893
894 word = array.getWord(); // word 3, asicMask(16)/eventQueueDepth(8)/eventNumberByte(8)
895 unsigned int evtAsicMask = word >> 16;
896 unsigned int evtEventQueueDepth = (word >> 8) & 0xFF;
897 unsigned int evtEventNumberByte = word & 0xFF;
898
899 B2DEBUG(22, std::dec << array.getIndex() << ":\t" << setfill('0') << setw(4) << std::hex <<
900 (word >> 16) << " " << setfill('0') << setw(4) << (word & 0xFFFF) << std::dec
901 << "\tevtAsicMask = " << evtAsicMask
902 << ", evtEventQueueDepth = " << evtEventQueueDepth
903 << ", evtEventNumberByte = " << evtEventNumberByte);
904
905 m_productionEventDebugs.appendNew(evtType,
906 evtVersion,
907 evtScrodID,
908 evtSkipHit,
909 injVetoFlag,
910 PSBypass,
911 evtCtime,
912 evtPhase,
913 evtAsicMask,
914 evtEventQueueDepth,
915 evtEventNumberByte);
916
917 B2DEBUG(22, "end of event header, start of hits:");
918
919 const int numWordsPerHit = 4 + evtExtra;
920 unsigned int numHitsFound = 0;
921 unsigned int numExpectedWaveforms = 0;
922
923 std::vector<TOPRawDigit*> digitsWithWaveform; // digits that have waveforms
924
925 while (array.getRemainingWords() > numWordsPerHit //one more full hit + one word of footer
926 && array.getIndex() < evtNumWordsCore - 2) { // -1 for 0-based counting, -1 for hit footer word
927 array.resetChecksum();
928
929
930 //need to predefine some variables here as we need to branch out between two data format versions for the next two words
931 unsigned int hitCarrier = 0;
932 unsigned int hitAsic = 0;
933 unsigned int hitChannel = 0;
934 unsigned int hitWindow = 0;
935 unsigned int hitMagicHeader = 0;
936 unsigned int hitTFine = 0;
937 bool hitHasWaveform = false;
938 bool hitIsOnHeap = false;
939 unsigned int hitHeapWindow = 0;
940 bool hitIsOnHeapStraddle = false;
941 unsigned int hitHeapWindowStraddle = 0;
942 bool hitIsWindowStraddle = false;
943 short hitIntegral = 0;
944 short hitVPeak = 0;
945
946 if (dataFormat == TOP::RawDataType::c_ProductionDebug01) { //dataformat 0x0401
947 word = array.getWord(); // hit word 0, carrier(2)/asic(2)/channel(3)/window(9)/0xB(4)/tFine(4)/hasWaveform(1)/isOnHeap(1)/heapWindow(6)
948 hitCarrier = word >> 30;
949 hitAsic = (word >> 28) & 0x3;
950 hitChannel = (word >> 25) & 0x7;
951 hitWindow = (word >> 16) & 0x1FF;
952 hitMagicHeader = (word >> 12) & 0xF;
953 hitTFine = (word >> 8) & 0xF;
954 hitHasWaveform = (word >> 7) & 0x1;
955 hitIsOnHeap = (word >> 6) & 0x1;
956 hitHeapWindow = word & 0x3F;
957
958
959 B2DEBUG(22, std::dec << array.getIndex() << ":\t" << setfill('0') << setw(4) << std::hex <<
960 (word >> 16) << " " << setfill('0') << setw(4) << (word & 0xFFFF) << std::dec
961 << "\thitCarrier = " << hitCarrier
962 << ", hitAsic = " << hitAsic
963 << ", hitChannel = " << hitChannel
964 << ", hitWindow = " << hitWindow
965 // << ", hitMagicHeader = " << hitMagicHeader
966 // << ", hitTFine = " << hitTFine
967 << ", hitHasWaveform = " << hitHasWaveform
968 // << ", hitIsOnHeap = " << hitIsOnHeap
969 // << ", hitHeapWindow = " << hitHeapWindow
970 );
971
972
973 word = array.getWord(); // hit word 1, reserved(3)/vPeak(13)/integral(16)
974 hitVPeak = expand13to16bits(word >> 16);
975 hitIntegral = word & 0xFFFF;
976 B2DEBUG(22, std::dec << array.getIndex() << ":\t" << setfill('0') << setw(4) << std::hex <<
977 (word >> 16) << " " << setfill('0') << setw(4) << (word & 0xFFFF) << std::dec
978 << "\thitVPeak = " << hitVPeak
979 << ", hitIntegral = " << hitIntegral);
980
981 } else if (dataFormat == TOP::RawDataType::c_ProductionDebug02) { //dataformat 0x0402
982 word = array.getWord(); // hit word 0, carrier(2)/asic(2)/channel(3)/window(9)/0xB(4)/tFine(4)/hasWaveform(1)/isWindowStraddle(1)/integral(6)
983 hitCarrier = word >> 30;
984 hitAsic = (word >> 28) & 0x3;
985 hitChannel = (word >> 25) & 0x7;
986 hitWindow = (word >> 16) & 0x1FF;
987 hitMagicHeader = (word >> 12) & 0xF;
988 hitTFine = (word >> 8) & 0xF;
989 hitHasWaveform = (word >> 7) & 0x1;
990 hitIsWindowStraddle = (word >> 6) & 0x1;
991 hitIntegral = word & 0x3F;
992
993
994 B2DEBUG(22, std::dec << array.getIndex() << ":\t" << setfill('0') << setw(4) << std::hex <<
995 (word >> 16) << " " << setfill('0') << setw(4) << (word & 0xFFFF) << std::dec
996 << "\thitCarrier = " << hitCarrier
997 << ", hitAsic = " << hitAsic
998 << ", hitChannel = " << hitChannel
999 << ", hitWindow = " << hitWindow
1000 // << ", hitMagicHeader = " << hitMagicHeader
1001 // << ", hitTFine = " << hitTFine
1002 << ", hitHasWaveform = " << hitHasWaveform
1003 << ", hitIsWindowStraddle = " << hitHasWaveform
1004 << ", hitIntegral = " << hitIntegral
1005 // << ", hitHeapWindow = " << hitHeapWindow
1006 );
1007
1008 word = array.getWord(); // hit word 1, reserved(3)/vPeak(13)/isOnHeap1(1)/heapWindow1(7)/isOnHeap0(1)/heapWindow0(7)
1009 hitVPeak = expand13to16bits(word >> 16);
1010 hitIsOnHeapStraddle = (word >> 15) & 0x1;
1011 hitHeapWindowStraddle = (word >> 8) & 0x7F;
1012 hitIsOnHeap = (word >> 7) & 0x1;
1013 hitHeapWindow = word & 0x1;
1014
1015 B2DEBUG(22, std::dec << array.getIndex() << ":\t" << setfill('0') << setw(4) << std::hex <<
1016 (word >> 16) << " " << setfill('0') << setw(4) << (word & 0xFFFF) << std::dec
1017 << "\thitVPeak = " << hitVPeak
1018 << ", hitIsOnHeapStraddle = " << hitIsOnHeapStraddle
1019 << ", hitHeapWindowStraddle = " << hitHeapWindowStraddle
1020 << ", hitIsOnHeap = " << hitIsOnHeap
1021 << ", hitHeapWindow = " << hitHeapWindow);
1022 } else { //could not match the data format
1023 B2WARNING("TOPUnpacker: could not match data type inside unpackProdDebug()"
1024 << LogVar("evtType", evtType) << LogVar("evtVersion", evtVersion));
1025 return array.getRemainingWords();
1026 }
1027
1028
1029 if (hitHasWaveform) {
1030 numExpectedWaveforms += 1;
1031 }
1032
1033 if (hitMagicHeader != 0xB) {
1034 B2WARNING("TOPUnpacker: hit header magic word mismatch. should be 0xB."
1035 << LogVar("Magic word", hitMagicHeader));
1036 return array.getRemainingWords();
1037 }
1038
1039 word = array.getWord(); // hit word 2, reserved(3)/vRise0(13)/reserved(3)/vRise1(13)
1040 short hitVRise0 = expand13to16bits(word >> 16);
1041 short hitVRise1 = expand13to16bits(word);
1042 B2DEBUG(22, std::dec << array.getIndex() << ":\t" << setfill('0') << setw(4) << std::hex <<
1043 (word >> 16) << " " << setfill('0') << setw(4) << (word & 0xFFFF) << std::dec
1044 << "\thitVRise0 = " << hitVRise0
1045 << ", hitVRise1 = " << hitVRise1);
1046
1047 word = array.getWord(); // hit word 3, reserved(3)/vFall0(13)/reserved(3)/vFall1(13)
1048 short hitVFall0 = expand13to16bits(word >> 16);
1049 short hitVFall1 = expand13to16bits(word);
1050 B2DEBUG(22, std::dec << array.getIndex() << ":\t" << setfill('0') << setw(4) << std::hex <<
1051 (word >> 16) << " " << setfill('0') << setw(4) << (word & 0xFFFF) << std::dec
1052 << "\thitVFall0 = " << hitVFall0
1053 << ", hitVFall1 = " << hitVFall1);
1054
1055 word = array.getWord(); // hit word 4, sampleRise(8)/dSampPeak(4)/dSampFall(4)/headerChecksum(16)
1056 unsigned short hitSampleRise = (word >> 24);
1057 short hitDSampPeak = (word >> 20) & 0xF;
1058 short hitDSampFall = (word >> 16) & 0xF;
1059 unsigned short hitHeaderChecksum = word & 0xFFFF;
1060 B2DEBUG(22, std::dec << array.getIndex() << ":\t" << setfill('0') << setw(4) << std::hex <<
1061 (word >> 16) << " " << setfill('0') << setw(4) << (word & 0xFFFF) << std::dec
1062 << "\thitSampleRise = " << hitSampleRise
1063 << ", hitDSampPeak = " << hitDSampPeak
1064 << ", hitDSampFall = " << hitDSampFall
1065 << ", hitheaderChecksum = " << hitHeaderChecksum
1066 << ", checksum " << (array.validateChecksum() ? "OK" : "NOT OK"));
1067
1068 if (!array.validateChecksum()) {
1069 B2WARNING("TOPUnpacker: hit checksum invalid.");
1070 return array.getRemainingWords();
1071 }
1072
1073 // append digit
1074 auto* digit = m_rawDigits.appendNew(evtScrodID, TOPRawDigit::c_ProductionDebug);
1075 digit->setCarrierNumber(hitCarrier);
1076 digit->setASICNumber(hitAsic);
1077 digit->setASICChannel(hitChannel);
1078 digit->setASICWindow(hitWindow);
1079 digit->setLastWriteAddr(0);
1080 digit->setSampleRise(hitSampleRise);
1081 digit->setDeltaSamplePeak(hitDSampPeak);
1082 digit->setDeltaSampleFall(hitDSampFall);
1083 digit->setValueRise0(hitVRise0);
1084 digit->setValueRise1(hitVRise1);
1085 digit->setValuePeak(hitVPeak);
1086 digit->setValueFall0(hitVFall0);
1087 digit->setValueFall1(hitVFall1);
1088 digit->setTFine(hitTFine);
1089 digit->setIntegral(hitIntegral);
1090 digit->setRevo9Counter(evtRevo9Counter);
1091 digit->setPhase(evtPhase);
1092
1093
1094 if (hitHasWaveform) {
1095 digitsWithWaveform.push_back(digit);
1096 }
1097
1098 TOPProductionHitDebug* hitDebug = 0;
1099 if (dataFormat == TOP::RawDataType::c_ProductionDebug01) { // dataformat 0x0401
1100 hitDebug = m_productionHitDebugs.appendNew(hitHasWaveform,
1101 hitIsOnHeap,
1102 hitWindow,
1103 hitIsOnHeap ? 428 + hitHeapWindow : hitWindow, //hitHeapWindow is counted from the start of the heap
1104 hitIsWindowStraddle);
1105 } else if (dataFormat == TOP::RawDataType::c_ProductionDebug02) { // dataformat 0x0402
1106 hitDebug = m_productionHitDebugs.appendNew(hitHasWaveform,
1107 hitIsOnHeap,
1108 hitWindow,
1109 hitIsOnHeap ? 428 + hitHeapWindow : hitWindow, //hitHeapWindow is counted from the start of the heap
1110 hitIsWindowStraddle,
1111 hitWindow + 1, //logical address of straddle window is always +1
1112 hitIsOnHeapStraddle ? 428 + hitHeapWindowStraddle : hitWindow +
1113 1); //physical address might be entirely different if straddled window is on heap
1114 }
1115
1116 //parse extra words if exist:
1117 for (unsigned int i = 0; i < evtExtra; ++i) {
1118 word = array.getWord(); // extra hit word i, undefined so far
1119 B2DEBUG(22, std::dec << array.getIndex() << ":\t" << setfill('0') << setw(4) << std::hex <<
1120 (word >> 16) << " " << setfill('0') << setw(4) << (word & 0xFFFF) << std::dec
1121 << "\thit extra word " << i << " (" << evtExtra << ")");
1122 hitDebug->appendExtraWord(word);
1123 }
1124
1125 if (m_addRelations and hitDebug) {
1126 digit->addRelationTo(hitDebug);
1127 }
1128
1129 numHitsFound += 1;
1130 } // end of hits loop
1131
1132 word = array.getWord(); // event footer word, sdType(8)/sdData(12)/0x5(3)/nHits(9)
1133 unsigned int evtSdType = (word >> 24);
1134 unsigned int evtSdData = (word >> 12) & 0xFFF;
1135 unsigned int evtMagicFooter = (word >> 9) & 0x7;
1136 unsigned int evtNHits = word & 0x1FF;
1137 B2DEBUG(22, std::dec << array.getIndex() << ":\t" << setfill('0') << setw(4) << std::hex <<
1138 (word >> 16) << " " << setfill('0') << setw(4) << (word & 0xFFFF) << std::dec
1139 << "\tevtSdType = " << evtSdType
1140 << ", evtSdData = " << evtSdData
1141 << ", evtMagicFooter = " << evtMagicFooter
1142 << ", evtNHits = " << evtNHits << " (" << numHitsFound << ")");
1143
1144 if (evtSdType != 0) {
1145 m_slowData.appendNew(evtScrodID, evtSdType, evtSdData);
1146 }
1147
1148 if (evtMagicFooter != 0x5) {
1149 B2WARNING("TOPUnpacker: event footer magic word mismatch. should be 0x5."
1150 << LogVar("Magic word", evtMagicFooter));
1151 return array.getRemainingWords();
1152 }
1153
1154 B2DEBUG(22, "the rest:");
1155
1156 unsigned int numParsedWaveforms = 0;
1157 while (array.peekWord() != 0x6c617374 //next word is not wf footer word
1158 && array.getRemainingWords() > 0) {
1159
1160 word = array.getWord(); // waveform word 0, nSamples(16)/0x0(5)/nWindows(3)/0(1)/carrier(2)/asic(2)/channel(3)
1161 unsigned int wfNSamples = (word >> 16);
1162 unsigned int wfNWindows = (word >> 8) & 0x7;
1163 unsigned int wfCarrier = (word >> 5) & 0x3;
1164 unsigned int wfAsic = (word >> 3) & 0x3;
1165 unsigned int wfChannel = word & 0x7;
1166
1167 // determine hardware channel and pixelID (valid only if feemap available!)
1168 const auto& mapper = m_topgp->getChannelMapper();
1169 unsigned channel = mapper.getChannel(boardstack, wfCarrier, wfAsic, wfChannel);
1170 int pixelID = mapper.getPixelID(channel);
1171
1172 B2DEBUG(22, std::dec << array.getIndex() << ":\t" << setfill('0') << setw(4) << std::hex <<
1173 (word >> 16) << " " << setfill('0') << setw(4) << (word & 0xFFFF) << std::dec
1174 << "\twfNSamples = " << wfNSamples
1175 << ", wfNWindows = " << wfNWindows
1176 << ", wfCarrier = " << wfCarrier
1177 << ", wfAsic = " << wfAsic
1178 << ", wfChannel " << wfChannel);
1179
1180 if (wfNSamples != 32 && wfNSamples != 16) {
1181 B2WARNING("TOPUnpacker: suspicious value for wfNSamples."
1182 << LogVar("wfNSamples", wfNSamples));
1183 return array.getRemainingWords();
1184 }
1185
1186 word = array.getWord(); // waveform word 1, 0x0(1)/startSamp(6)/logAddress(9)/carrierEventNumber(7)/readAddr(9)
1187 unsigned int wfStartSample = (word >> 25) & 0x3F;
1188 unsigned int wfWindowLogic = (word >> 16) & 0x1FF;
1189 unsigned int wfEventNumber = (word >> 9) & 0x7F;
1190 unsigned int wfWindowPhysical = word & 0x1FF;
1191
1192 B2DEBUG(22, std::dec << array.getIndex() << ":\t" << setfill('0') << setw(4) << std::hex <<
1193 (word >> 16) << " " << setfill('0') << setw(4) << (word & 0xFFFF) << std::dec
1194 << "\twfStartSample = " << wfStartSample
1195 << ", wfWindowLogic = " << wfWindowLogic
1196 << ", wfEventNumber = " << wfEventNumber
1197 << ", wfWindowPhysical = " << wfWindowPhysical);
1198
1199 std::vector<short> wfSamples;
1200
1201 for (unsigned int i = 0; i < wfNSamples / 2; ++i) {
1202 short wfSampleLast = 0;
1203 short wfSampleFirst = 0;
1204
1205
1206 word = array.getWord(); // waveform sample word i, reserved(4)/sample 2*i+1(12)/reserved(4)/sample 2*i(12)
1207 if (pedestalSubtracted) {
1208 wfSampleLast = (word >> 16);
1209 wfSampleFirst = word & 0xFFFF;
1210 } else {
1211 wfSampleLast = (word >> 16) & 0xFFF;
1212 wfSampleFirst = word & 0xFFF;
1213
1214 }
1215
1216 B2DEBUG(22, std::dec << array.getIndex() << ":\t" << setfill('0') << setw(4) << std::hex <<
1217 (word >> 16) << " " << setfill('0') << setw(4) << (word & 0xFFFF) << std::dec
1218 << "\twfSample" << 2 * i + 1 << " = " << wfSampleLast
1219 << ", wfSample" << 2 * i << " = " << wfSampleFirst);
1220
1221 wfSamples.push_back(wfSampleFirst);
1222 wfSamples.push_back(wfSampleLast);
1223 }
1224
1225 // append waveform
1226 auto* waveform = m_waveforms.appendNew(moduleID, pixelID, channel, evtScrodID,
1227 wfWindowLogic, wfStartSample, wfSamples);
1228 waveform->setPedestalSubtractedFlag(pedestalSubtracted);
1229 waveform->setPhysicalWindow(wfWindowPhysical);
1230 if (numParsedWaveforms < digitsWithWaveform.size()) {
1231 const auto* digit = digitsWithWaveform[numParsedWaveforms];
1232 if (digit->getScrodChannel() == channel % 128) {
1233 digit->addRelationTo(waveform);
1234 } else {
1235 B2WARNING("TOPUnpacker: hit and its waveform have different channel number."
1236 << LogVar("channel (hit)", digit->getScrodChannel())
1237 << LogVar("channel (waveform)", channel % 128));
1238 }
1239 }
1240 numParsedWaveforms += 1;
1241
1242 } // end of waveform segments loop
1243
1244 if (numExpectedWaveforms != numParsedWaveforms) {
1245 B2WARNING("TOPUnpacker: number of expected and parsed waveforms does not match."
1246 << LogVar("expected", numExpectedWaveforms)
1247 << LogVar("parsed", numParsedWaveforms));
1248 }
1249
1250 return array.getRemainingWords();
1251 }

◆ unpackProductionDraft()

void unpackProductionDraft ( const int * buffer,
int bufferSize )
private

Unpack raw data given in a tentative production format (will vanish in future)

Parameters
bufferraw data buffer
bufferSizebuffer size

Definition at line 245 of file TOPUnpackerModule.cc.

246 {
247
248 B2DEBUG(22, "Unpacking ProductionDraft to TOPDigits, dataSize = " << bufferSize);
249
250 unsigned short scrodID = buffer[0] & 0xFFFF;
251 const auto* feemap = m_topgp->getFrontEndMapper().getMap(scrodID);
252 if (!feemap) {
253 B2ERROR("TOPUnpacker: no front-end map available."
254 << LogVar("SCROD ID", scrodID));
255 return;
256 }
257 int moduleID = feemap->getModuleID();
258 int boardstack = feemap->getBoardstackNumber();
259 const auto& mapper = m_topgp->getChannelMapper();
260
261 const auto* geo = m_topgp->getGeometry();
262 auto subBits = geo->getNominalTDC().getSubBits();
263 int sampleDivisions = 0x1 << subBits;
264
265 for (int i = 1; i < bufferSize; i++) {
266 int word = buffer[i];
267 int tdc = word & 0xFFFF;
268 double rawTime = double(tdc) / sampleDivisions;
269 unsigned chan = ((word >> 16) & 0x7F) + boardstack * 128;
270 unsigned flags = (word >> 24) & 0xFF;
271 int pixelID = mapper.getPixelID(chan);
272 auto* digit = m_digits.appendNew(moduleID, pixelID, rawTime);
273 digit->setTime(geo->getNominalTDC().getTime(tdc));
274 digit->setChannel(chan);
275 digit->setHitQuality((TOPDigit::EHitQuality) flags);
276 }
277
278 }

◆ unpackType0Ver16()

void unpackType0Ver16 ( const int * buffer,
int bufferSize )
private

Unpack raw data given in feature-extraction production format.

Parameters
bufferraw data buffer
bufferSizebuffer size

Definition at line 281 of file TOPUnpackerModule.cc.

282 {
283
284 B2DEBUG(22, "Unpacking Type0Ver16 to TOPRawDigits, dataSize = " << bufferSize);
285
286 DataArray array(buffer, bufferSize, m_swapBytes);
287 unsigned word = array.getWord();
288 unsigned short scrodID = word & 0x0FFF;
289
290 unsigned last = array.getLastWord();
291 int Nhits = last & 0x01FF;
292 if (bufferSize != 5 * Nhits + 2) {
293 B2ERROR("TOPUnpacker: corrupted data (feature-extraction format)."
294 << LogVar("SCROD ID", scrodID));
295 return;
296 }
297
298 short SDType = last >> 24;
299 short SDValue = (last >> 12) & 0x0FFF;
300 if (SDType != 0) m_slowData.appendNew(scrodID, SDType, SDValue);
301
302 unsigned short errorFlags = 0;
303 if (((word >> 12) & 0x0F) != 0x0A) errorFlags |= TOPRawDigit::c_HeadMagic;
304 if (((last >> 9) & 0x07) != 0x05) errorFlags |= TOPRawDigit::c_TailMagic;
305
306 for (int hit = 0; hit < Nhits; hit++) {
307 auto* digit = m_rawDigits.appendNew(scrodID, TOPRawDigit::c_Production);
308
309 word = array.getWord(); // word 1
310 digit->setCarrierNumber((word >> 30) & 0x03);
311 digit->setASICNumber((word >> 28) & 0x03);
312 digit->setASICChannel((word >> 25) & 0x07);
313 digit->setASICWindow((word >> 16) & 0x1FF);
314 digit->setTFine((word >> 8) & 0x0F);
315 auto flags = errorFlags;
316 if (((word >> 12) & 0x0F) != 0x0B) flags |= TOPRawDigit::c_HitMagic;
317 unsigned short checkSum = sumShorts(word);
318
319 word = array.getWord(); // word 2
320 digit->setValuePeak(expand13to16bits(word >> 16));
321 digit->setIntegral(word & 0xFFFF);
322 checkSum += sumShorts(word);
323
324 word = array.getWord(); // word 3
325 digit->setValueRise0(expand13to16bits(word >> 16));
326 digit->setValueRise1(expand13to16bits(word));
327 checkSum += sumShorts(word);
328
329 word = array.getWord(); // word 4
330 digit->setValueFall0(expand13to16bits(word >> 16));
331 digit->setValueFall1(expand13to16bits(word));
332 checkSum += sumShorts(word);
333
334 word = array.getWord(); // word 5
335 digit->setSampleRise(word >> 24);
336 digit->setDeltaSamplePeak((word >> 20) & 0x0F);
337 digit->setDeltaSampleFall((word >> 16) & 0x0F);
338 checkSum += sumShorts(word);
339 if (checkSum != 0) flags |= TOPRawDigit::c_HitChecksum;
340
341 digit->setErrorFlags(flags);
342
343 }
344
345 }