12 #include <ecl/modules/eclDQMInjection/eclDQMInjection.h>
15 #include <boost/format.hpp>
16 #include <boost/range/combine.hpp>
19 #include <ecl/dataobjects/ECLDsp.h>
20 #include <ecl/utility/ECLDspUtilities.h>
23 #include "TDirectory.h"
27 using namespace Belle2::ECL;
40 m_calibrationThrApsd("ECL_FPGA_StoreWaveform")
43 setDescription(
"Monitor Occupancy after Injection");
44 setPropertyFlags(c_ParallelProcessingCertified);
45 addParam(
"histogramDirectoryName", m_histogramDirectoryName,
"Name of the directory where histograms will be placed",
46 std::string(
"ECLINJ"));
47 addParam(
"ECLDigitsName", m_ECLDigitsName,
"Name of ECL hits", std::string(
""));
51 addParam(
"BeamRevolutionCycle", m_revolutionTime,
"Beam revolution cycle in musec", 5120 / 508.);
52 addParam(
"ECLThresholdforVetoTuning", m_ECLThresholdforVetoTuning,
"ECL Threshold for injection veto tuning, ADC channels", 400.);
53 addParam(
"DPHYTTYP", m_DPHYTTYP,
54 "Flag to control trigger of delayed bhabha events; 0 - select events by 'bha_delay' trigger bit, 1 - select by TTYP_DPHY",
false);
58 void ECLDQMInjectionModule::defineHisto()
60 TDirectory* oldDir = gDirectory;
61 oldDir->mkdir(m_histogramDirectoryName.c_str());
62 oldDir->cd(m_histogramDirectoryName.c_str());
64 hHitsAfterInjLER =
new TH1F(
"ECLHitsInjLER",
"ECLHitsInjLER/Time;Time in #mus;Count/Time (5 #mus bins)", 4000, 0, 20000);
65 hHitsAfterInjHER =
new TH1F(
"ECLHitsInjHER",
"ECLHitsInjHER/Time;Time in #mus;Count/Time (5 #mus bins)", 4000, 0, 20000);
66 hEHitsAfterInjLER =
new TH1F(
"ECLEHitsInjLER",
"ECLEHitsInjLER/Time;Time in #mus;Triggers/Time (5 #mus bins)", 4000, 0, 20000);
67 hEHitsAfterInjHER =
new TH1F(
"ECLEHitsInjHER",
"ECLEHitsInjHER/Time;Time in #mus;Triggers/Time (5 #mus bins)", 4000, 0, 20000);
68 hBurstsAfterInjLER =
new TH1F(
"ECLBurstsInjLER",
"ECLBurstsInjLER/Time;Time in #mus;Count/Time (1 #mus bins)", 20000, 0, 20000);
69 hBurstsAfterInjHER =
new TH1F(
"ECLBurstsInjHER",
"ECLBurstsInjHER/Time;Time in #mus;Count/Time (1 #mus bins)", 20000, 0, 20000);
70 hEBurstsAfterInjLER =
new TH1F(
"ECLEBurstsInjLER",
"ECLEBurstsInjLER/Time;Time in #mus;Triggers/Time (1 #mus bins)", 20000, 0,
72 hEBurstsAfterInjHER =
new TH1F(
"ECLEBurstsInjHER",
"ECLEBurstsInjHER/Time;Time in #mus;Triggers/Time (1 #mus bins)", 20000, 0,
74 hVetoAfterInjLER =
new TH2F(
"ECLVetoAfterInjLER",
75 "ECL Hits for LER veto tuning (E > 20 MeV);"
76 "Time since last injection in #mus;Time within beam cycle in #mus", 500, 0, 30000, 100, 0,
78 hVetoAfterInjHER =
new TH2F(
"ECLVetoAfterInjHER",
79 "ECL Hits for HER veto tuning (E > 20 MeV);"
80 "Time since last injection in #mus;Time within beam cycle in #mus", 500, 0, 30000, 100, 0,
82 hOccAfterInjLER =
new TH2F(
"ECLOccAfterInjLER",
83 "ECL Occupancy after LER injection (E > 1 MeV); Time since last injection in #mus;Occupancy (Nhits/8736) [%]",
84 100, 0, 20000, 98, 2, 100);
85 hOccAfterInjHER =
new TH2F(
"ECLOccAfterInjHER",
86 "ECL Occupancy after HER injection (E > 1 MeV); Time since last injection in #mus;Occupancy (Nhits/8736) [%]",
87 100, 0, 20000, 98, 2, 100);
93 1.0, 1.5, 2.0, 4, 6, 8, 10
95 int ped_peak_range_count = m_ped_peak_range.size() - 1;
97 static const std::string part_names[] = {
"fwd",
"bar",
"bwd"};
98 static const std::string title_suffix[] = {
99 "in fwd endcap",
"in barrel",
"in bwd endcap"
102 for (
int ler_her = 0; ler_her < 2; ler_her++) {
103 std::string ring_name = (ler_her == 0) ?
"LER" :
"HER";
104 for (
int part = 0; part < 3; part++) {
105 std::string suffix = title_suffix[part];
106 for (
int i = 0; i < ped_peak_range_count; i++) {
107 float min_time = m_ped_peak_range[i];
108 float max_time = m_ped_peak_range[i + 1];
109 std::string name, title;
110 name = str(boost::format(
"ped_peak_%s_%s_%d") %
111 ring_name % part_names[part] % i);
112 title = str(boost::format(
"Peak height %.1f-%.1f ms after %s inj %s") %
113 min_time % max_time % ring_name % suffix);
115 auto h =
new TH1F(name.c_str(), title.c_str(), 300, 0.0, 0.3);
116 h->GetXaxis()->SetTitle(
"Peak height in first 16 points [GeV]");
118 h_ped_peak.push_back(h);
124 ECLDspUtilities::initPedestalFit();
130 void ECLDQMInjectionModule::initialize()
133 m_rawTTD.isOptional();
134 m_storeHits.isRequired(m_ECLDigitsName);
135 m_ECLTrigs.isOptional();
136 m_ECLDsps.isOptional();
137 m_l1Trigger.isOptional();
139 if (!mapper.initFromDB()) B2FATAL(
"ECL Display:: Can't initialize eclChannelMapper");
141 v_totalthrApsd.resize((m_calibrationThrApsd->getCalibVector()).size());
142 for (
size_t i = 0; i < v_totalthrApsd.size(); i++) v_totalthrApsd[i] = (
int)(m_calibrationThrApsd->getCalibVector())[i];
145 void ECLDQMInjectionModule::beginRun()
148 hHitsAfterInjLER->Reset();
149 hHitsAfterInjHER->Reset();
150 hEHitsAfterInjLER->Reset();
151 hEHitsAfterInjHER->Reset();
152 hBurstsAfterInjLER->Reset();
153 hBurstsAfterInjHER->Reset();
154 hEBurstsAfterInjLER->Reset();
155 hEBurstsAfterInjHER->Reset();
156 hVetoAfterInjLER->Reset();
157 hVetoAfterInjHER->Reset();
158 hOccAfterInjHER->Reset();
159 hOccAfterInjLER->Reset();
162 void ECLDQMInjectionModule::event()
164 bool bhatrig =
false;
166 if (m_l1Trigger.isValid() && m_DPHYTTYP) bhatrig = m_l1Trigger->getTimType() == TRGSummary::ETimingType::TTYP_DPHY;
167 else if (m_l1Trigger.isValid() && !m_DPHYTTYP) bhatrig = m_l1Trigger->testInput(
"bha_delay");
169 if (m_eventmetadata.isValid() && m_eventmetadata->getErrorFlag() != 0x10) {
170 m_iEvent = m_eventmetadata->getEvent();
171 }
else m_iEvent = -1;
172 int discarded_wfs = 0;
173 for (
auto& aECLTrig : m_ECLTrigs) {
174 int crate = aECLTrig.getTrigId();
175 int suppress = aECLTrig.getBurstSuppressionMask();
179 bool shaper_bit = suppress & 1;
181 if (m_iEvent % 1000 == 999 || (m_l1Trigger.isValid() && m_l1Trigger->getTimType() == TRGSummary::ETimingType::TTYP_RAND) ||
182 (m_l1Trigger.isValid() && bhatrig)) {
183 for (
int channel_pos = 0; channel_pos < 16; channel_pos ++) {
184 if (mapper.getCellId(crate, shaper_pos, channel_pos) > 0) discarded_wfs += 1;
187 for (
auto& aECLDigit : m_storeHits) {
188 if (crate == mapper.getCrateID(aECLDigit.getCellId()) && shaper_pos == mapper.getShaperPosition(aECLDigit.getCellId()) &&
189 aECLDigit.getAmp() >= (v_totalthrApsd[aECLDigit.getCellId() - 1] / 4 * 4)) discarded_wfs += 1;
197 unsigned int ECLDigitsAboveThr = 0;
198 unsigned int ECLDigitsAboveThr1MeV = 0;
199 for (
auto& aECLDigit : m_storeHits) {
200 if (aECLDigit.getAmp() > m_ECLThresholdforVetoTuning) ECLDigitsAboveThr += 1;
201 if (aECLDigit.getAmp() > 20) ECLDigitsAboveThr1MeV += 1;
204 for (
auto& it : m_rawTTD) {
205 B2DEBUG(29,
"TTD FTSW : " << hex << it.GetTTUtime(0) <<
" " << it.GetTTCtime(0) <<
" EvtNr " << it.GetEveNo(0) <<
" Type " <<
206 (it.GetTTCtimeTRGType(0) & 0xF) <<
" TimeSincePrev " << it.GetTimeSincePrevTrigger(0) <<
" TimeSinceInj " <<
207 it.GetTimeSinceLastInjection(0) <<
" IsHER " << it.GetIsHER(0) <<
" Bunch " << it.GetBunchNumber(0));
210 auto difference = it.GetTimeSinceLastInjection(0);
212 if (difference != 0x7FFFFFFF) {
213 unsigned int all = m_storeHits.getEntries();
214 float diff2 = difference / 127.;
215 int is_her = it.GetIsHER(0);
217 hHitsAfterInjHER->Fill(diff2, all);
218 hEHitsAfterInjHER->Fill(diff2);
219 hBurstsAfterInjHER->Fill(diff2, discarded_wfs);
220 hEBurstsAfterInjHER->Fill(diff2);
221 hVetoAfterInjHER->Fill(diff2, diff2 -
int(diff2 / m_revolutionTime)*m_revolutionTime, ECLDigitsAboveThr);
222 if (all > 0) hOccAfterInjHER->Fill(diff2, ECLDigitsAboveThr1MeV / 8736.*100.);
224 hHitsAfterInjLER->Fill(diff2, all);
225 hEHitsAfterInjLER->Fill(diff2);
226 hBurstsAfterInjLER->Fill(diff2, discarded_wfs);
227 hEBurstsAfterInjLER->Fill(diff2);
228 hVetoAfterInjLER->Fill(diff2, diff2 -
int(diff2 / m_revolutionTime)*m_revolutionTime, ECLDigitsAboveThr);
229 if (all > 0) hOccAfterInjLER->Fill(diff2, ECLDigitsAboveThr1MeV / 8736.*100.);
233 int range_count = m_ped_peak_range.size() - 1;
234 if (diff2 < m_ped_peak_range[range_count] * 1000) {
237 for (range_id = 0; range_id < range_count; range_id++) {
239 float min_time = m_ped_peak_range[range_id ] * 1000;
240 float max_time = m_ped_peak_range[range_id + 1] * 1000;
241 if (diff2 > min_time && diff2 < max_time)
break;
244 if (range_id < range_count) {
245 for (
auto& aECLDsp : m_ECLDsps) {
246 auto result = ECLDspUtilities::pedestalFit(aECLDsp.getDspA());
249 int cid = aECLDsp.getCellId();
251 if (cid >= 1153) part_id = 1;
252 if (cid >= 7777) part_id = 2;
254 int hist_id = is_her * 3 * range_count + part_id * range_count + range_id;
257 h_ped_peak[hist_id]->Fill(result.amp / 2e4);