10 #include <ecl/modules/eclDQMInjection/eclDQMInjection.h>
13 #include <boost/format.hpp>
14 #include <boost/range/combine.hpp>
17 #include <ecl/dataobjects/ECLDsp.h>
18 #include <ecl/utility/ECLDspUtilities.h>
21 #include "TDirectory.h"
28 using namespace Belle2::ECL;
41 m_calibrationThrApsd("ECL_FPGA_StoreWaveform")
44 setDescription(
"Monitor Occupancy after Injection");
45 setPropertyFlags(c_ParallelProcessingCertified);
46 addParam(
"histogramDirectoryName", m_histogramDirectoryName,
"Name of the directory where histograms will be placed",
47 std::string(
"ECLINJ"));
48 addParam(
"ECLDigitsName", m_ECLDigitsName,
"Name of ECL hits", std::string(
""));
52 addParam(
"BeamRevolutionCycle", m_revolutionTime,
"Beam revolution cycle in musec", 5120 / 508.);
53 addParam(
"ECLThresholdforVetoTuning", m_ECLThresholdforVetoTuning,
"ECL Threshold for injection veto tuning, ADC channels", 400.);
54 addParam(
"DPHYTTYP", m_DPHYTTYP,
55 "Flag to control trigger of delayed bhabha events; 0 - select events by 'bha_delay' trigger bit, 1 - select by TTYP_DPHY",
false);
59 void ECLDQMInjectionModule::defineHisto()
61 TDirectory* oldDir = gDirectory;
62 oldDir->mkdir(m_histogramDirectoryName.c_str());
63 oldDir->cd(m_histogramDirectoryName.c_str());
65 hHitsAfterInjLER =
new TH1F(
"ECLHitsInjLER",
"ECLHitsInjLER/Time;Time in #mus;Count/Time (5 #mus bins)", 4000, 0, 20000);
66 hHitsAfterInjHER =
new TH1F(
"ECLHitsInjHER",
"ECLHitsInjHER/Time;Time in #mus;Count/Time (5 #mus bins)", 4000, 0, 20000);
67 hEHitsAfterInjLER =
new TH1F(
"ECLEHitsInjLER",
"ECLEHitsInjLER/Time;Time in #mus;Triggers/Time (5 #mus bins)", 4000, 0, 20000);
68 hEHitsAfterInjHER =
new TH1F(
"ECLEHitsInjHER",
"ECLEHitsInjHER/Time;Time in #mus;Triggers/Time (5 #mus bins)", 4000, 0, 20000);
69 hBurstsAfterInjLER =
new TH1F(
"ECLBurstsInjLER",
"ECLBurstsInjLER/Time;Time in #mus;Count/Time (1 #mus bins)", 20000, 0, 20000);
70 hBurstsAfterInjHER =
new TH1F(
"ECLBurstsInjHER",
"ECLBurstsInjHER/Time;Time in #mus;Count/Time (1 #mus bins)", 20000, 0, 20000);
71 hEBurstsAfterInjLER =
new TH1F(
"ECLEBurstsInjLER",
"ECLEBurstsInjLER/Time;Time in #mus;Triggers/Time (1 #mus bins)", 20000, 0,
73 hEBurstsAfterInjHER =
new TH1F(
"ECLEBurstsInjHER",
"ECLEBurstsInjHER/Time;Time in #mus;Triggers/Time (1 #mus bins)", 20000, 0,
75 hVetoAfterInjLER =
new TH2F(
"ECLVetoAfterInjLER",
76 "ECL Hits for LER veto tuning (E > 20 MeV);"
77 "Time since last injection in #mus;Time within beam cycle in #mus", 500, 0, 30000, 100, 0,
79 hVetoAfterInjHER =
new TH2F(
"ECLVetoAfterInjHER",
80 "ECL Hits for HER veto tuning (E > 20 MeV);"
81 "Time since last injection in #mus;Time within beam cycle in #mus", 500, 0, 30000, 100, 0,
83 hOccAfterInjLER =
new TH2F(
"ECLOccAfterInjLER",
84 "ECL Occupancy after LER injection (E > 1 MeV); Time since last injection in #mus;Occupancy (Nhits/8736) [%]",
85 100, 0, 20000, 98, 2, 100);
86 hOccAfterInjHER =
new TH2F(
"ECLOccAfterInjHER",
87 "ECL Occupancy after HER injection (E > 1 MeV); Time since last injection in #mus;Occupancy (Nhits/8736) [%]",
88 100, 0, 20000, 98, 2, 100);
94 1.0, 1.5, 2.0, 4, 6, 8, 10
96 int ped_peak_range_count = m_ped_peak_range.size() - 1;
98 static const std::string part_names[] = {
"fwd",
"bar",
"bwd"};
99 static const std::string title_suffix[] = {
100 "in fwd endcap",
"in barrel",
"in bwd endcap"
103 for (
int ler_her = 0; ler_her < 2; ler_her++) {
104 std::string ring_name = (ler_her == 0) ?
"LER" :
"HER";
105 for (
int part = 0; part < 3; part++) {
106 std::string suffix = title_suffix[part];
107 for (
int i = 0; i < ped_peak_range_count; i++) {
108 float min_time = m_ped_peak_range[i];
109 float max_time = m_ped_peak_range[i + 1];
110 std::string name, title;
111 name = str(boost::format(
"ped_peak_%s_%s_%d") %
112 ring_name % part_names[part] % i);
113 title = str(boost::format(
"Peak height %.1f-%.1f ms after %s inj %s") %
114 min_time % max_time % ring_name % suffix);
116 auto h =
new TH1F(name.c_str(), title.c_str(), 300, 0.0, 0.3);
117 h->GetXaxis()->SetTitle(
"Peak height in first 16 points [GeV]");
119 h_ped_peak.push_back(h);
125 ECLDspUtilities::initPedestalFit();
131 void ECLDQMInjectionModule::initialize()
134 m_rawTTD.isOptional();
135 m_storeHits.isRequired(m_ECLDigitsName);
136 m_ECLTrigs.isOptional();
137 m_ECLDsps.isOptional();
138 m_l1Trigger.isOptional();
140 if (!mapper.initFromDB()) B2FATAL(
"ECL Display:: Can't initialize eclChannelMapper");
142 v_totalthrApsd.resize((m_calibrationThrApsd->getCalibVector()).size());
143 for (
size_t i = 0; i < v_totalthrApsd.size(); i++) v_totalthrApsd[i] = (
int)(m_calibrationThrApsd->getCalibVector())[i];
146 void ECLDQMInjectionModule::beginRun()
149 hHitsAfterInjLER->Reset();
150 hHitsAfterInjHER->Reset();
151 hEHitsAfterInjLER->Reset();
152 hEHitsAfterInjHER->Reset();
153 hBurstsAfterInjLER->Reset();
154 hBurstsAfterInjHER->Reset();
155 hEBurstsAfterInjLER->Reset();
156 hEBurstsAfterInjHER->Reset();
157 hVetoAfterInjLER->Reset();
158 hVetoAfterInjHER->Reset();
159 hOccAfterInjHER->Reset();
160 hOccAfterInjLER->Reset();
163 void ECLDQMInjectionModule::event()
165 bool bhatrig =
false;
167 if (m_l1Trigger.isValid() && m_DPHYTTYP) bhatrig = m_l1Trigger->getTimType() == TRGSummary::ETimingType::TTYP_DPHY;
168 else if (m_l1Trigger.isValid() && !m_DPHYTTYP) {
169 try { bhatrig = m_l1Trigger->testInput(
"bha_delay"); }
170 catch (
const std::exception&) { bhatrig =
false; }
173 if (m_eventmetadata.isValid() && m_eventmetadata->getErrorFlag() != 0x10) {
174 m_iEvent = m_eventmetadata->getEvent();
175 }
else m_iEvent = -1;
178 unsigned int ECLDigitsAboveThr = 0;
179 unsigned int ECLDigitsAboveThr1MeV = 0;
180 for (
const auto& aECLDigit : m_storeHits) {
181 int amp = aECLDigit.getAmp();
182 amps[aECLDigit.getCellId() - 1] = amp;
183 if (amp > m_ECLThresholdforVetoTuning) ECLDigitsAboveThr += 1;
184 if (amp > 20) ECLDigitsAboveThr1MeV += 1;
187 int discarded_wfs = 0;
188 for (
auto& aECLTrig : m_ECLTrigs) {
189 int crate = aECLTrig.getTrigId();
190 int suppress = aECLTrig.getBurstSuppressionMask();
194 bool shaper_bit = suppress & 1;
196 if (m_iEvent % 1000 == 999 || (m_l1Trigger.isValid() && m_l1Trigger->getTimType() == TRGSummary::ETimingType::TTYP_RAND) ||
197 (m_l1Trigger.isValid() && bhatrig)) {
198 for (
int channel_pos = 0; channel_pos < 16; channel_pos ++) {
199 if (mapper.getCellId(crate, shaper_pos, channel_pos) > 0) discarded_wfs += 1;
202 for (
int channel_pos = 0; channel_pos < 16; channel_pos ++) {
203 int cid = mapper.getCellId(crate, shaper_pos, channel_pos);
204 if (cid > 0 && amps[cid - 1] >= (v_totalthrApsd[cid - 1] / 4 * 4)) discarded_wfs += 1;
212 for (
auto& it : m_rawTTD) {
213 B2DEBUG(29,
"TTD FTSW : " << hex << it.GetTTUtime(0) <<
" " << it.GetTTCtime(0) <<
" EvtNr " << it.GetEveNo(0) <<
" Type " <<
214 (it.GetTTCtimeTRGType(0) & 0xF) <<
" TimeSincePrev " << it.GetTimeSincePrevTrigger(0) <<
" TimeSinceInj " <<
215 it.GetTimeSinceLastInjection(0) <<
" IsHER " << it.GetIsHER(0) <<
" Bunch " << it.GetBunchNumber(0));
218 auto difference = it.GetTimeSinceLastInjection(0);
220 if (difference != 0x7FFFFFFF) {
221 unsigned int all = m_storeHits.getEntries();
222 float diff2 = difference / 127.;
223 int is_her = it.GetIsHER(0);
225 hHitsAfterInjHER->Fill(diff2, all);
226 hEHitsAfterInjHER->Fill(diff2);
227 hBurstsAfterInjHER->Fill(diff2, discarded_wfs);
228 hEBurstsAfterInjHER->Fill(diff2);
229 hVetoAfterInjHER->Fill(diff2, diff2 -
int(diff2 / m_revolutionTime)*m_revolutionTime, ECLDigitsAboveThr);
230 if (all > 0) hOccAfterInjHER->Fill(diff2, ECLDigitsAboveThr1MeV / 8736.*100.);
232 hHitsAfterInjLER->Fill(diff2, all);
233 hEHitsAfterInjLER->Fill(diff2);
234 hBurstsAfterInjLER->Fill(diff2, discarded_wfs);
235 hEBurstsAfterInjLER->Fill(diff2);
236 hVetoAfterInjLER->Fill(diff2, diff2 -
int(diff2 / m_revolutionTime)*m_revolutionTime, ECLDigitsAboveThr);
237 if (all > 0) hOccAfterInjLER->Fill(diff2, ECLDigitsAboveThr1MeV / 8736.*100.);
241 int range_count = m_ped_peak_range.size() - 1;
242 if (diff2 < m_ped_peak_range[range_count] * 1000) {
245 for (range_id = 0; range_id < range_count; range_id++) {
247 float min_time = m_ped_peak_range[range_id ] * 1000;
248 float max_time = m_ped_peak_range[range_id + 1] * 1000;
249 if (diff2 > min_time && diff2 < max_time)
break;
252 if (range_id < range_count) {
253 for (
auto& aECLDsp : m_ECLDsps) {
254 auto result = ECLDspUtilities::pedestalFit(aECLDsp.getDspA());
257 int cid = aECLDsp.getCellId();
259 if (cid >= 1153) part_id = 1;
260 if (cid >= 7777) part_id = 2;
262 int hist_id = is_her * 3 * range_count + part_id * range_count + range_id;
265 h_ped_peak[hist_id]->Fill(result.amp / 2e4);
The ECL Occ after Injection DQM module.
HistoModule.h is supposed to be used instead of Module.h for the modules with histogram definitions t...
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Abstract base class for different kinds of events.