10 #include <ecl/modules/eclDQM/eclDQM.h>
13 #include <ecl/dataobjects/ECLCalDigit.h>
14 #include <ecl/dataobjects/ECLDigit.h>
15 #include <ecl/dataobjects/ECLDsp.h>
16 #include <ecl/dataobjects/ECLElementNumbers.h>
17 #include <ecl/dataobjects/ECLTrig.h>
18 #include <ecl/geometry/ECLGeometryPar.h>
19 #include <ecl/mapper/ECLChannelMapper.h>
22 #include <framework/core/HistoModule.h>
23 #include <framework/dataobjects/EventMetaData.h>
24 #include <framework/gearbox/Unit.h>
25 #include <framework/logging/Logger.h>
26 #include <mdst/dataobjects/TRGSummary.h>
29 #include <boost/format.hpp>
30 #include <boost/range/combine.hpp>
33 #include <TDirectory.h>
52 m_calibrationThrApsd(
"ECL_FPGA_StoreWaveform")
56 "Primary module for ECL Data Quality Monitor.\n"
57 "This module provides a large set of low-level histograms: occupancy, time distribution, number of saved waveforms, etc.");
63 "histogram directory in ROOT file", std::string(
"ECL"));
65 addParam(
"HitThresholds",
m_HitThresholds,
"Thresholds to display hit occupancy, MeV", std::vector<double> {0, 5, 10, 50});
69 "Upper limit (# of hits) to display hit multiplicity", std::vector<double> {10000, 1000, 700, 200});
73 "Flag to control trigger of delayed bhabha events; 0 - select events by 'bha_delay' trigger bit, 1 - select by TTYP_DPHY",
false);
83 TDirectory* oldDir = gDirectory;
92 h_evtot =
new TH1F(
"event",
"Total event bank", 1, 0, 1);
94 h_quality =
new TH1F(
"quality",
"Fit quality flag. 0-good, 1-integer overflow, 2-low amplitude, 3-bad chi2", 4, 0, 4);
95 h_quality->GetXaxis()->SetTitle(
"Quality flag");
96 h_quality->GetYaxis()->SetTitle(
"ECL hits count");
99 h_quality_other =
new TH1F(
"quality_other",
"Fit quality flag for unexpectedly saved waveforms", 4, 0, 4);
100 h_quality_other->GetXaxis()->SetTitle(
"Quality flag. 0-good,1-int overflow,2-low amplitude,3-bad chi2");
103 h_bad_quality =
new TH1F(
"bad_quality",
"Fraction of hits with bad chi2 (qual=3) and E > 1 GeV vs Cell ID",
108 h_trigtag1 =
new TH1F(
"trigtag1",
"Consistency b/w global event number and trigger tag. 0-good, 1-DQM error", 2, 0, 2);
109 h_trigtag1->GetXaxis()->SetTitle(
"Flag value");
110 h_trigtag1->GetYaxis()->SetTitle(
"Events count");
114 h_adc_hits =
new TH1F(
"adc_hits",
"Fraction of high-energy hits (E > 50 MeV)", 1001, 0, 1.001);
116 h_adc_hits->GetYaxis()->SetTitle(
"Events count");
119 "Number of hits with timing outside #pm 100 ns per Crate ID (E > 1 GeV)",
125 std::string h_name, h_title;
126 h_name = str(boost::format(
"cid_Thr%1%MeV") %
id);
127 h_title = str(boost::format(
"Occupancy per Cell ID (E > %1% MeV)") %
id);
128 TH1F* h =
new TH1F(h_name.c_str(), h_title.c_str(),
130 h->GetXaxis()->SetTitle(
"Cell ID");
131 h->GetYaxis()->SetTitle(
"Occupancy (hits / events_count)");
136 std::string h_name, h_title;
137 h_name = str(boost::format(
"edep_Thr%1%MeV") %
id);
138 h_title = str(boost::format(
"Total energy (thr = %1% MeV)") %
id);
140 h->GetXaxis()->SetTitle(
"Energy, [GeV]");
145 std::string h_bar_name, h_bar_title;
146 std::string h_end_name, h_end_title;
147 h_bar_name = str(boost::format(
"time_barrel_Thr%1%MeV") %
id);
148 h_bar_title = str(boost::format(
"Reconstructed time for ECL barrel (E > %1% MeV)") %
id);
149 h_end_name = str(boost::format(
"time_endcaps_Thr%1%MeV") %
id);
150 h_end_title = str(boost::format(
"Reconstructed time for ECL endcaps (E > %1% MeV)") %
id);
151 TH1F* h_time_barrel =
new TH1F(h_bar_name.c_str(), h_bar_title.c_str(), 206, -1030, 1030);
152 TH1F* h_time_endcap =
new TH1F(h_end_name.c_str(), h_end_title.c_str(), 206, -1030, 1030);
153 h_time_barrel->GetXaxis()->SetTitle(
"Time, [ns]");
154 h_time_endcap->GetXaxis()->SetTitle(
"Time, [ns]");
160 double id1 = 0, id2 = 0;
161 boost::tie(id1, id2) = id;
162 std::string h_name, h_title;
163 h_name = str(boost::format(
"ncev_Thr%1%MeV") % id1);
164 h_title = str(boost::format(
"Number of hits in event (E > %1% MeV)") % id1);
165 TH1F* h =
new TH1F(h_name.c_str(), h_title.c_str(), id2, 0, id2);
166 h->GetXaxis()->SetTitle(
"Number of hits");
170 for (
int i = 0; i < ECL_CRATES; i++) {
172 std::string h_name, h_title;
173 h_name = str(boost::format(
"time_crate_%1%_Thr1GeV") % (crate));
174 h_title = str(boost::format(
"Reconstructed time for ECL crate #%1% with E > 1 GeV") % (crate));
175 TH1F* h =
new TH1F(h_name.c_str(), h_title.c_str(), 400, -100, 100);
176 h->GetXaxis()->SetTitle(
"Time [ns]");
181 if (
id !=
"all" &&
id !=
"psd" &&
id !=
"logic" &&
id !=
"rand" &&
id !=
"dphy" &&
id !=
"other")
182 B2WARNING(
"Waveform Options are not correctly assigned. They must be 'all', 'psd', 'logic', 'rand', 'dphy', 'other'!");
184 std::string h_cell_name;
185 if (
id ==
"other") h_title =
"Unexpectedly saved waveforms";
186 if (
id ==
"psd") h_title =
"#frac{Saved}{Expected} waveforms for high-energy hits (E > 50 MeV)";
187 if (
id ==
"logic") h_title =
"#frac{Saved}{Expected} waveforms for every 1000th event";
188 if (
id ==
"rand") h_title =
"#frac{Saved}{Expected} waveforms for random trigger events";
189 if (
id ==
"dphy") h_title =
"#frac{Saved}{Expected} waveforms for delayed bhabha (DPHY) events";
190 if (
id ==
"all") h_title =
"#frac{Saved}{Expected} waveforms for all events";
191 h_cell_name = str(boost::format(
"wf_cid_%1%") % (
id));
192 TH1F* h_cell =
new TH1F(h_cell_name.c_str(), h_title.c_str(),
194 h_cell->GetXaxis()->SetTitle(
"Cell ID");
196 h_cell_psd_norm =
new TH1F(
"psd_cid",
"Normalization to psd hits for cid",
200 h_evtot_logic =
new TH1F(
"event_logic",
"Event bank for logic", 1, 0, 1);
203 h_evtot_rand =
new TH1F(
"event_rand",
"Event bank for rand", 1, 0, 1);
206 h_evtot_dphy =
new TH1F(
"event_dphy",
"Event bank for dphy", 1, 0, 1);
213 h_trigtag2_trigid =
new TH2F(
"trigtag2_trigid",
"Internal data consistency vs crate. 0-good, 1-data corruption",
214 52, 1, 53, 11, -1, 10);
221 h_pedmean_cellid->GetYaxis()->SetTitle(
"Ped. average (ADC units, #approx 0.05 MeV)");
223 h_pedrms_cellid =
new TProfile(
"pedrms_cellid",
"Pedestal stddev vs Cell ID",
226 h_pedrms_cellid->GetYaxis()->SetTitle(
"Ped. stddev (ADC units, #approx 0.05 MeV)");
228 h_pedrms_thetaid =
new TProfile(
"pedrms_thetaid",
"Pedestal stddev vs #theta ID",
230 h_pedrms_thetaid->GetXaxis()->SetTitle(
"#theta ID (0-12=FWD, 59-67=BWD endcap)");
231 h_pedrms_thetaid->GetYaxis()->SetTitle(
"Ped. stddev (ADC units, #approx 0.05 MeV)");
233 h_trigtime_trigid =
new TH2F(
"trigtime_trigid",
"Trigger time vs Crate ID", 52, 1, 53, 145, 0, 145);
251 if (!
mapper.
initFromDB()) B2FATAL(
"ECL DQM: Can't initialize eclChannelMapper");
275 std::for_each(
h_cids.begin(),
h_cids.end(), [](
auto & it) {it->Reset();});
276 std::for_each(
h_edeps.begin(),
h_edeps.end(), [](
auto & it) {it->Reset();});
279 std::for_each(
h_ncevs.begin(),
h_ncevs.end(), [](
auto & it) {it->Reset();});
280 std::for_each(
h_cells.begin(),
h_cells.end(), [](
auto & it) {it->Reset();});
293 for (
auto& value :
ecltot) value = 0;
294 for (
auto& value :
nhits) value = 0;
295 bool bhatrig =
false;
299 try { bhatrig =
m_l1Trigger->testInput(
"bha_delay"); }
300 catch (
const std::exception&) { bhatrig =
false; }
317 int i = aECLDigit.getCellId() - 1;
319 if (aECLDigit.getAmp() > 2.e04 && aECLDigit.getQuality() == 3)
h_bad_quality->Fill(aECLDigit.getCellId());
320 if (aECLDigit.getAmp() >= (
v_totalthrApsd[i] / 4 * 4)) NDigits ++;
322 if (
id !=
"psd")
continue;
323 else if (
id ==
"psd" && (
m_iEvent % 1000 == 999 ||
332 double itrg = aECLTrig.getTimeTrig();
335 int tg = (int)itrg - 2 * ((
int)itrg / 8);
337 trigtag1 += aECLTrig.getTrigTag();
345 if (compar == trigtag1) flagtag = 0;
350 int cid = aECLCalDigit.getCellId();
351 double energy = aECLCalDigit.getEnergy();
352 double timing = aECLCalDigit.getTime();
355 auto scale =
id / 1000.;
357 if (energy > scale) {
364 auto scale =
id / 1000.;
367 if (energy > scale)
ecltot[index] += energy;
371 auto scale =
id / 1000.;
373 if (energy > scale) {
374 if (cid > ECL_FWD_CHANNELS && cid <= ECL_FWD_CHANNELS + ECL_BARREL_CHANNELS)
h_time_barrels[index]->Fill(timing);
390 h->Fill(
nhits[index]);
394 int i = aECLDsp.getCellId() - 1;
413 if (
id !=
"all" &&
id !=
"psd" &&
id !=
"logic" &&
id !=
"rand" &&
id !=
"dphy" &&
id !=
"other")
continue;
416 else if (
id ==
"logic" &&
m_iEvent % 1000 != 999)
continue;
418 else if (
id ==
"dphy" && (
m_iEvent % 1000 == 999 || !bhatrig))
continue;
421 h_cells[index]->Fill(aECLDsp.getCellId());
441 return m_l1Trigger->getTimType() == TRGSummary::ETimingType::TTYP_RAND ||
442 m_l1Trigger->getTimType() == TRGSummary::ETimingType::TTYP_POIS;
double m_PedestalMean[ECLElementNumbers::c_NCrystals]
Pedestal average values.
TH1F * h_trigtag1
Histogram: Trigger tag flag #1.
std::vector< double > nhits
Container for channel multiplicity.
TH1F * h_bad_quality
Histogram: Cell IDs w/ bad fit quality flag.
double m_PedestalRms[ECLElementNumbers::c_NCrystals]
Pedestal rms error values.
bool m_DPHYTTYP
Flag to select events triggered by delayed bhabha.
std::vector< double > m_TimingThresholds
Parameters for timing histograms.
TH1F * h_adc_hits
Histogram: Fraction of digits above ADC threshold.
StoreArray< ECLDsp > m_ECLDsps
StoreArray ECLDsp.
virtual void initialize() override
Initialize the module.
virtual ~ECLDQMModule()
Destructor.
StoreArray< ECLCalDigit > m_ECLCalDigits
StoreArray ECLCalDigit.
StoreObjPtr< TRGSummary > m_l1Trigger
StoreObjPtr TRGSummary
TH1F * h_cell_psd_norm
Histogram: Normalize to psd hits for CellID.
virtual void event() override
Event processor.
TH2F * h_trigtime_trigid
Histogram: Trigger time vs.
ECLDQMModule()
< derived from HistoModule class.
std::vector< TH1F * > h_edeps
Histogram vector: Total energy.
virtual void endRun() override
Call when a run ends.
std::vector< TH1F * > h_ncevs
Histogram vector: Channel multiplicity.
virtual void terminate() override
Terminate.
TH1F * h_evtot
Histogram: Total event no (auxiliary) to normalize hit map .
int m_iEvent
Global event number.
ECL::ECLGeometryPar * m_geom
Geometry.
StoreArray< ECLDigit > m_ECLDigits
StoreArray ECLDigit.
std::vector< double > ecltot
Container for energy.
std::vector< TH1F * > h_time_barrels
Histogram vector: Reconstructed time for barrel.
double m_EnergyUpperThr
Upper threshold of energy deposition in event, [GeV].
TProfile * h_pedmean_cellid
Histogram: Pedestal Average vs.
TH1F * h_evtot_rand
Histogram: Event no for rand (auxiliary) to normalize rand waveform flow.
std::vector< TH1F * > h_time_crate_Thr1GeV
Histogram vector: Reconstructed signal time for all ECL crates above the threshold = 1 GeV.
TH1F * h_time_crate_Thr1GeV_large
Histogram: Entries with crate time offsets > 100 ns (E > 1 GeV).
virtual void beginRun() override
Call when a run begins.
std::string m_histogramDirectoryName
Histogram directory in ROOT file.
ECL::ECLChannelMapper mapper
ECL channel mapper.
TH1F * h_evtot_logic
Histogram: Event no for logic (auxiliary) to normalize logic waveform flow.
std::vector< double > m_HitNumberUpperLimits
Parameters for number of hits histograms.
std::vector< double > m_TotalEnergyThresholds
Parameters for histograms w/ total energy.
TProfile * h_pedrms_thetaid
Histogram: Pedestal rms error vs.
std::vector< std::string > m_WaveformOption
Parameters for waveform histograms.
int m_DspArray[ECLElementNumbers::c_NCrystals][31]
WF sampling points for digit array.
TH1F * h_evtot_dphy
Histogram: Event no for dphy (auxiliary) to normalize dphy waveform flow.
std::vector< double > m_HitThresholds
Parameters for hit occ.
TH1F * h_quality
Histogram: Fit quality flag (0 - good, 1 - large amplitude, 3 - bad chi2).
StoreArray< ECLTrig > m_ECLTrigs
StoreArray ECLTrig.
StoreObjPtr< EventMetaData > m_eventmetadata
StoreObjPtr EventMetaData.
TH2F * h_trigtag2_trigid
Histogram: Trigger tag flag #2 vs.
std::vector< int > v_totalthrApsd
Vector to store psd wf amplitude threshold.
TH1F * h_quality_other
Histogram: Fit quality flag for waveform type 'other'.
std::vector< TH1F * > h_cids
Histogram vector: Hit map.
TProfile * h_pedrms_cellid
Histogram: Pedestal rms error vs.
DBObjPtr< ECLCrystalCalib > m_calibrationThrApsd
PSD waveform amplitude threshold.
std::vector< TH1F * > h_cells
Histogram vector: Waveforms vs CellID.
virtual void defineHisto() override
Function to define histograms.
std::vector< TH1F * > h_time_endcaps
Histogram vector: Reconstructed time for endcaps.
Class to store ECL digitized hits (output of ECLDigi) relation to ECLHit filled in ecl/modules/eclDig...
int getAmp() const
Get Fitting Amplitude.
int getQuality() const
Get Fitting Quality.
static ECLDigit * getByCellID(int cid)
Find ECLDigit by Cell ID using linear search.
bool initFromDB()
Initialize channel mapper from the conditions database.
int getCrateID(int iCOPPERNode, int iFINESSE, bool pcie40=false)
Get crate number by given COPPER node number and FINESSE number.
static ECLGeometryPar * Instance()
Static method to get a reference to the ECLGeometryPar instance.
void Mapping(int cid)
Mapping theta, phi Id.
int GetThetaID()
Get Theta Id.
HistoModule.h is supposed to be used instead of Module.h for the modules with histogram definitions t...
void setDescription(const std::string &description)
Sets the description of the module.
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
static const double GeV
Standard of [energy, momentum, mass].
REG_MODULE(arichBtest)
Register the Module.
void addParam(const std::string &name, T ¶mVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
double sqrt(double a)
sqrt for double
const int c_NCrystals
Number of crystals.
Abstract base class for different kinds of events.