Belle II Software development
eclLOMModule.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8
9/* Own header. */
10#include <ecl/modules/eclLOM/eclLOMModule.h>
11
12/* ROOT headers. */
13#include <Math/Boost.h>
14
15using namespace std;
16using namespace Belle2;
17using namespace ECL;
18
19REG_MODULE(ECLLOM);
20
21
23{
24 setDescription("module to emulate Luminosity Online Monitor");
25 addParam("thresholdFE", m_thresholdFE, "Threshold for Forward Endcap [GeV]", 3.0);
26 addParam("thresholdBE", m_thresholdBE, "Threshold for Backward Endcap [GeV]", 1.0);
27 addParam("thresholdBkg", m_thresholdBkg, "Threshold when sector considered as lighted [GeV]", 0.5);
28 addParam("discrTime", m_discrTime, "Duration of '1' (positive) signal from discriminators [ns]", 1000.0);
29 addParam("includeInnerFE", m_includeInnerFE, "Flag to include/exclude Inner part of the Forward Endcap", false);
30 addParam("saveSignal", m_saveSignal, "Flag to store or not signals' waveforms", false);
31 addParam("testFileName", m_testFileName, "output file", std::string("lomtest.root"));
32
33 m_evtNum = 0;
34 for (int i = 0; i < 16; i++) {
35 for (int j = 0; j < 16; j++) {
38 }
39 }
40}
41
46
48{
49 if (!(m_MCParticles.isRequired() && m_TrgEclWaveforms.isRequired())) {
50 //Fatal is not necessary here as the storeArrays should just look
51 //empty if not registered but let's make sure everything is present
52 B2FATAL("Not all collections found, exiting processing");
53 }
54
55 m_testfile = new TFile(m_testFileName.c_str(), "RECREATE");
56 m_testtree = new TTree("lom_tree", "");
57
58 m_testtree->Branch("ev", &m_evtNum);
59 m_testtree->Branch("BE_amp[16]", m_BE_Amplitude, "BE_amp[16]/D");
60 m_testtree->Branch("FE_amp[16]", m_FE_Amplitude, "FE_amp[16]/D");
61 m_testtree->Branch("FESum_MaxAmp", &m_FESum_MaxAmp);
62 m_testtree->Branch("BESum_MaxAmp", &m_BESum_MaxAmp);
63 m_testtree->Branch("FESum_MaxId", &m_FESum_MaxId);
64 m_testtree->Branch("BESum_MaxId", &m_BESum_MaxId);
65 m_testtree->Branch("BE_Pedal[16]", m_BE_Pedal, "BE_Pedal[16]/D");
66 m_testtree->Branch("FE_Pedal[16]", m_FE_Pedal, "FE_Pedal[16]/D");
67
68 m_testtree->Branch("Bhabha", &m_isBhabha);
69 m_testtree->Branch("BhNum", &m_BhNum);
70
71 m_testtree->Branch("mc_en[2]", m_mcen, "mc_en[2]/D");
72 m_testtree->Branch("mc_th[2]", m_mcth, "mc_th[2]/D");
73 m_testtree->Branch("mc_ph[2]", m_mcph, "mc_ph[2]/D");
74
75 m_testtree->Branch("com_en[2]", m_com_en, "com_en[2]/D");
76 m_testtree->Branch("com_th[2]", m_com_th, "com_th[2]/D");
77 m_testtree->Branch("com_ph[2]", m_com_ph, "com_ph[2]/D");
78
79 if (m_saveSignal) {
80 m_testtree->Branch("BE_wf[16][64]", m_BE_Waveform_100ns, "BE_wf[16][64]/D");
81 m_testtree->Branch("FE_wf[16][64]", m_FE_Waveform_100ns, "FE_wf[16][64]/D");
82 }
83
84 //additional histograms. Represent data over the whole dataset:
85 m_h2Coin = new TH2D("Coins", "Coincidence Matrix", 16, 0, 16, 16, 0, 16);
86 m_h2SumCoin = new TH2D("SumCoins", "Sum Coincidence Matrix", 16, 0, 16, 16, 0, 16);
87 m_h2FEAmp = new TH2D("FE_AmpId", "", 16, 0, 16, 100, 0, 8);
88 m_h2BEAmp = new TH2D("BE_AmpId", "", 16, 0, 16, 100, 0, 8);
89 m_h1BEHits = new TH1D("BE_Fired", "", 16, 0, 16);
90 m_h1FEHits = new TH1D("FE_Fired", "", 16, 0, 16);
91
92 m_NSamples = 631;
93}
94
96{
102 // LOM logic
103 for (int iSample = 300; iSample < 500; iSample++) { //300-500 window where BhaBha is expected
106 calculate_coincidence(iSample);
107 // generate bhabha signal
108 for (int iFESector = 0; iFESector < 16; iFESector++) {
109 // check opposite running sum:
110 int iBESector = (iFESector + 8) % 16;
111 if (m_SumCoincidenceMatrix[iFESector][iBESector] == 1 && m_isBhabhaPatternFE && m_isBhabhaPatternBE) {
112 //coincidence at first tick
113 m_isBhabha = true;
114 m_BhNum++;
115 }
116 }
117 }
118 m_testtree->Fill();
119 m_evtNum++;
120}
121
123{
124
125 for (int i = 0; i < 16; i++) {
126 for (int j = 0; j < 16; j++) {
127 std::cout << m_CoincidenceCounterMatrix[i][j] << " ";
128 m_h2Coin->SetBinContent(i + 1, j + 1, m_CoincidenceCounterMatrix[i][j]);
129 m_h2SumCoin->SetBinContent(i + 1, j + 1, m_SumCoincidenceCounterMatrix[i][j]);
130 }
131 std::cout << std::endl;
132 }
133 m_testfile->Write();
134 m_testfile->Close();
135}
136
137
139{
140 int nm_MCParticles = m_MCParticles.getEntries();
141 if (nm_MCParticles >= 4) {
142 for (int ind = 2; ind < 4; ind++) {
143 m_mcen[ind - 2] = m_MCParticles[ind]->getEnergy();
144 m_mcth[ind - 2] = m_MCParticles[ind]->getMomentum().Theta();
145 m_mcph[ind - 2] = m_MCParticles[ind]->getMomentum().Phi();
146 }
147
148 ROOT::Math::PxPyPzEVector SummP(m_MCParticles[0]->get4Vector() + m_MCParticles[1]->get4Vector());
149 ROOT::Math::XYZVector Boost_backV = SummP.BoostToCM();
150 ROOT::Math::PxPyPzEVector ComP[2];
151 ComP[0] = m_MCParticles[2]->get4Vector();
152 ComP[1] = m_MCParticles[3]->get4Vector();
153 ComP[0] = ROOT::Math::Boost(Boost_backV) * ComP[0];
154 ComP[1] = ROOT::Math::Boost(Boost_backV) * ComP[1];
155 for (int ind = 0; ind < 2; ind++) {
156 m_com_en[ind] = ComP[ind].E();
157 m_com_th[ind] = ComP[ind].Theta();
158 m_com_ph[ind] = ComP[ind].Phi();
159 }
160 }
161}
162
164{
165 //int n_trg_digi = TrgEclDigiArray.getEntries();
166 int n_trg_wf = m_TrgEclWaveforms.getEntries();
167 // calculate signals of endcap sectors for LOM input
168 // as sum of corresponding TC signals
169 for (int i = 0; i < n_trg_wf; i++) {
170 const TRGECLWaveform* TCWaveform = m_TrgEclWaveforms[i];
171 //int m_tcid = TCWaveform->getTCID();
172 int tc_theta_id = TCWaveform->getThetaID(); //FE:1,2,3 BE:16,17 Checked for rel 4 02 08
173 int tc_phi_id = TCWaveform->getPhiID(); // 1 - 32
174 double m_wf[64];
175 TCWaveform->fillWaveform(m_wf);
176
177 int iSectorIndex = (tc_phi_id - 1) / 2; // from 0 to 15
178 if (tc_theta_id == 1 && !m_includeInnerFE) continue;
179
180 for (int iSample = 0; iSample < 64; iSample++) {
181 if (tc_theta_id <= 3) { //Forward Endcap
182 m_FE_Waveform_100ns[iSectorIndex][iSample] += m_wf[iSample];
183 } else { // Backward Endcap
184 if (tc_theta_id == 16 || tc_theta_id == 17) m_BE_Waveform_100ns[iSectorIndex][iSample] += m_wf[iSample];
185 }
186 }
187 }
188}
189
191{
192 for (int iSector = 0; iSector < 16; iSector++) { // Calculating pedestals
193 for (int iSample = 15; iSample < 36; iSample++) {
194 m_BE_Pedal[iSector] += m_BE_Waveform_100ns[iSector][iSample] / 20;
195 m_FE_Pedal[iSector] += m_FE_Waveform_100ns[iSector][iSample] / 20;
196 }
197 }
198 double dAdT; // convert 100 ns signal to 10 ns
199 for (int iSector = 0; iSector < 16; iSector++) { // Linear interpolation from 100ns to 10ns
200 for (int iSample = 0; iSample < 63; iSample++) {
201 // forward
202 dAdT = (m_FE_Waveform_100ns[iSector][iSample + 1] - m_FE_Waveform_100ns[iSector][iSample]) / 10.0;
203 m_FE_Waveform_100ns[iSector][iSample] -= m_FE_Pedal[iSector]; //remove pedestals
204 for (int j = 0; j < 10; j++) m_FE_Waveform_10ns[iSector][iSample * 10 + j] = m_FE_Waveform_100ns[iSector][iSample] + j * dAdT;
205 m_FE_Waveform_10ns[iSector][630] = m_FE_Waveform_100ns[iSector][63] - m_FE_Pedal[iSector];
206 //backward
207 dAdT = (m_BE_Waveform_100ns[iSector][iSample + 1] - m_BE_Waveform_100ns[iSector][iSample]) / 10.0;
208 m_BE_Waveform_100ns[iSector][iSample] -= m_BE_Pedal[iSector];
209 for (int j = 0; j < 10; j++) m_BE_Waveform_10ns[iSector][iSample * 10 + j] = m_BE_Waveform_100ns[iSector][iSample] + j * dAdT;
210 m_BE_Waveform_10ns[iSector][630] = m_BE_Waveform_100ns[iSector][63] - m_BE_Pedal[iSector];
211 }
212 }
213 // calculate running sums for 10ns signal
214 int TimeOfDiscr = int(m_discrTime / 10); //discriminator duration in samples
215 for (int iSector = 0; iSector < 16; iSector++) {
216 for (int iSample = 1; iSample < m_NSamples; iSample++) {
217 int iNextSector = (iSector + 1) % 16;
218 m_BESum_Waveform_10ns[iSector][iSample] = m_BE_Waveform_10ns[iSector][iSample] + m_BE_Waveform_10ns[iNextSector][iSample];
219 m_FESum_Waveform_10ns[iSector][iSample] = m_FE_Waveform_10ns[iSector][iSample] + m_FE_Waveform_10ns[iNextSector][iSample];
220
221 //filling Discriminators' signals
222 if (m_FESum_Waveform_10ns[iSector][iSample] > m_thresholdFE && m_FESum_Discr[iSector][iSample] == 0) {
223 for (int j = iSample; j < iSample + TimeOfDiscr; j++) {
224 if (j < m_NSamples) m_FESum_Discr[iSector][j] = 1;
225 }
226 }
227 if (m_BESum_Waveform_10ns[iSector][iSample] > m_thresholdBE && m_BESum_Discr[iSector][iSample] == 0) {
228 for (int j = iSample; j < iSample + TimeOfDiscr; j++) {
229 if (j < m_NSamples) m_BESum_Discr[iSector][j] = 1;
230 }
231 }
232 if (m_FE_Waveform_10ns[iSector][iSample] > m_thresholdBkg && m_FEQual_Discr[iSector][iSample] == 0) {
233 for (int j = iSample; j < iSample + TimeOfDiscr; j++) {
234 if (j < m_NSamples) m_FEQual_Discr[iSector][j] = 1;
235 }
236 }
237 if (m_BE_Waveform_10ns[iSector][iSample] > m_thresholdBkg && m_BEQual_Discr[iSector][iSample] == 0) {
238 for (int j = iSample; j < iSample + TimeOfDiscr; j++) {
239 if (j < m_NSamples) m_BEQual_Discr[iSector][j] = 1;
240 }
241 }
242 }
243 }
244}
245
246
248{
249 int nhit = 0;
250 int First = 0;
251 // calculate quality signal for backward endcap
252 for (int iBESector = 0; iBESector < 16; iBESector++) {
253 if (m_BEQual_Discr[iBESector][iSample]) {
254 nhit++;
255 if (nhit == 1) First = iBESector;
256 if (nhit == 2 && !((iBESector + 1) % 16 == First || (First + 1) % 16 == iBESector)) return (false);
257 if (nhit >= 3) return (false);
258 }
259 }
260 return (true);
261}
262
264{
265 int nhit = 0;
266 int First = 0;
267 for (int iFESector = 0; iFESector < 16; iFESector++) {
268 if (m_FEQual_Discr[iFESector][iSample]) {
269 nhit++;
270 if (nhit == 1) First = iFESector;
271 if (nhit == 2 && !((iFESector + 1) % 16 == First || (First + 1) % 16 == iFESector)) return (false);
272 if (nhit >= 3) return (false);
273 }
274 }
275 return (true);
276}
277
279{
280 for (int iFESector = 0; iFESector < 16; iFESector++) {
281 for (int iBESector = 0; iBESector < 16; iBESector++) {
282
283 if (m_FE_Waveform_10ns[iFESector][iSample] > m_thresholdFE && m_BE_Waveform_10ns[iBESector][iSample] > m_thresholdBE) {
284 if (m_CoincidenceMatrix[iFESector][iBESector] == 0) m_CoincidenceCounterMatrix[iFESector][iBESector]++;
285 m_CoincidenceMatrix[iFESector][iBESector]++;
286 } else {
287 m_CoincidenceMatrix[iFESector][iBESector] = 0;
288 }
289
290 if (m_FESum_Discr[iFESector][iSample] && m_BESum_Discr[iBESector][iSample]) {
291 if (m_SumCoincidenceMatrix[iFESector][iBESector] == 0) m_SumCoincidenceCounterMatrix[iFESector][iBESector]++;
292 m_SumCoincidenceMatrix[iFESector][iBESector]++;
293 }
294 m_SumCoincidenceMatrix[iFESector][iBESector] = 0;
295 }
296 }
297}
298
299
301{
302 for (int isector = 0; isector < 16; isector++) {
303 for (int iSample = 0; iSample < 64; iSample++) {
304 m_BE_Waveform_100ns[isector][iSample] = 0;
305 m_FE_Waveform_100ns[isector][iSample] = 0;
306 }
307 for (int iSample = 0; iSample < m_NSamples; iSample++) {
308 m_BE_Waveform_10ns[isector][iSample] = 0;
309 m_FE_Waveform_10ns[isector][iSample] = 0;
310 m_BESum_Waveform_10ns[isector][iSample] = 0;
311 m_FESum_Waveform_10ns[isector][iSample] = 0;
312 m_FESum_Discr[isector][iSample] = 0;
313 m_BESum_Discr[isector][iSample] = 0;
314 m_FEQual_Discr[isector][iSample] = 0;
315 m_BEQual_Discr[isector][iSample] = 0;
316 }
317 m_BE_Pedal[isector] = 0;
318 m_FE_Pedal[isector] = 0;
319 m_BE_Amplitude[isector] = 0;
320 m_FE_Amplitude[isector] = 0;
321 m_BESum_Amplitude[isector] = 0;
322 m_FESum_Amplitude[isector] = 0;
323 for (int jsector = 0; jsector < 16; jsector++) {
324 m_CoincidenceMatrix[isector][jsector] = 0;
325 m_SumCoincidenceMatrix[isector][jsector] = 0;
326 }
327 }
328 m_isBhabha = 0;
329 m_BhNum = 0;
330 m_FESum_MaxAmp = 0;
331 m_BESum_MaxAmp = 0;
332 m_FESum_MaxId = -1;
333 m_BESum_MaxId = -1;
334}
335
337{
338 for (int iSample = 0; iSample < m_NSamples; iSample++) {
339 for (int isector = 0; isector < 16; isector++) {
340 if (m_FE_Waveform_10ns[isector][iSample] > m_FE_Amplitude[isector]) m_FE_Amplitude[isector] = m_FE_Waveform_10ns[isector][iSample];
341 if (m_FESum_Waveform_10ns[isector][iSample] > m_FESum_Amplitude[isector]) m_FESum_Amplitude[isector] =
342 m_FESum_Waveform_10ns[isector][iSample];
343 if (m_BE_Waveform_10ns[isector][iSample] > m_BE_Amplitude[isector]) m_BE_Amplitude[isector] = m_BE_Waveform_10ns[isector][iSample];
344 if (m_BESum_Waveform_10ns[isector][iSample] > m_BESum_Amplitude[isector]) m_BESum_Amplitude[isector] =
345 m_BESum_Waveform_10ns[isector][iSample];
346 }
347 }
348 for (int i = 0; i < 16; i++) {
351 m_FESum_MaxId = i;
352 }
355 m_BESum_MaxId = i;
356 }
357 if (m_FE_Amplitude[i] > 0.5) m_h2FEAmp->Fill(i, m_FE_Amplitude[i]);
358 if (m_BE_Amplitude[i] > 0.5) m_h2BEAmp->Fill(i, m_BE_Amplitude[i]);
359
360 if (m_FE_Amplitude[i] > m_thresholdFE) m_h1FEHits->Fill(i);
361 if (m_BE_Amplitude[i] > m_thresholdBE) m_h1BEHits->Fill(i);
362 }
363}
bool m_isBhabhaPatternBE
Quality signal for Backward endcap.
double m_FESum_MaxAmp
Maximum running sum amplitude in an event for Forward endcap.
int m_BESum_MaxId
Id of a sector with maximum amplitude in Backward endcap.
int m_BhNum
Number of Bha-bha signals in an event.
TH2D * m_h2BEAmp
Store sectors amplitudes for Backward endcap over all events.
TH2D * m_h2FEAmp
Store sectors amplitudes for Forward endcap over all events.
TH2D * m_h2SumCoin
Store number of coincedencies in running sums for i:j sectors (Forward:Backward) over all events.
double m_FE_Waveform_100ns[16][64]
Waveforms with 100ns sampling for Forward Endcap sectors.
double m_mcph[2]
Monte Carlo phi of the final state particles in main frame.
int m_NSamples
m_NSamples=631, number of samples for 10ns sampling.
int m_evtNum
Event number.
TFile * m_testfile
File to save output.
void calculate_discr_output()
Transforms waveforms into discriminators output.
double m_BESum_MaxAmp
Maximum running sum amplitude in an event for Backward endcap.
bool calculate_BE_quality(int iSample)
Return Quality (topology) flag at sample point, iSample, for Backward Endcap.
int m_CoincidenceCounterMatrix[16][16]
Stores number of concidences between waveforms exceeding threshold in i:j sectors (Forward:Backward).
int m_FESum_MaxId
Id of a sector with maximum amplitude in Forward endcap.
virtual void initialize() override
Initialize variables.
double m_thresholdBE
Threshold [GeV] on signal for Backward Endcap .
TH1D * m_h1BEHits
Store number of events when Backward sector i has signal exceeding Bha-Bha threshold over all events.
virtual void event() override
event per event.
void get_MCparticles()
Get MC particles parameters.
double m_thresholdFE
Threshold [GeV] on signal for Forward Endcap .
double m_BE_Waveform_10ns[16][631]
Waveforms with 10ns sampling for Backward Endcap sectors.
StoreArray< TRGECLWaveform > m_TrgEclWaveforms
Trigger waveforms.
bool m_FESum_Discr[16][631]
Discriminators values for running sums of Forward Endcap.
int m_SumCoincidenceMatrix[16][16]
Stores current coincidence duration [in samples] between running sums discriminators in i:j sectors (...
virtual void terminate() override
terminate.
void get_waveforms()
Get ECL waveforms comdined into sectors.
double m_discrTime
Discriminator's signal duration in ns.
double m_FESum_Amplitude[16]
Calculated amplitudes in running sums of Forward Endcap.
bool m_FEQual_Discr[16][631]
Discriminators values for Quality signal of Forward Endcap.
int m_CoincidenceMatrix[16][16]
Stores current coincidence duration [in samples] between waveforms exceeding threshold in i:j sectors...
void clear_lom_data()
Clear internal data.
double m_com_th[2]
Monte Carlo thetha of the final state particles in CMS frame.
TH1D * m_h1FEHits
Store number of events when Forward sector i has signal exceeding Bha-Bha threshold over all events.
bool m_BEQual_Discr[16][631]
Discriminators values for Quality signal of Backward Endcap.
virtual ~ECLLOMModule() override
Destructor.
double m_BE_Waveform_100ns[16][64]
Waveforms with 100ns sampling for Backward Endcap sectors.
double m_mcth[2]
Monte Carlo thetha of the final state particles in main frame.
double m_FE_Pedal[16]
Calculated pedestal values for Forward Endcap.
TTree * m_testtree
Tree to store output.
double m_BESum_Amplitude[16]
Calculated amplitudes in running sums of Backward Endcap.
bool m_isBhabhaPatternFE
Quality signal for Forward endcap.
bool calculate_FE_quality(int iSample)
Return Quality (topology) flag at sample point, iSample, for Forward Endcap.
double m_FESum_Waveform_10ns[16][631]
Running sum's waveforms with 10ns sampling for Forward Endcap sectors.
bool m_BESum_Discr[16][631]
Discriminators values for running sums of Backward Endcap.
bool m_isBhabha
Bha-bha signal for an event.
double m_BESum_Waveform_10ns[16][631]
Running sum's waveforms with 10ns sampling for Backward Endcap sectors.
TH2D * m_h2Coin
Store number of coincedencies for i:j sectors (Forward:Backward) over all events.
double m_mcen[2]
Monte Carlo energy of the final state particles in main frame.
double m_FE_Amplitude[16]
Calculated amplitudes in sectors of Forward Endcap.
void calculate_coincidence(int iSample)
Calculates Coincidence Matrix at sample point, iSample.
int m_SumCoincidenceCounterMatrix[16][16]
Stores number of concidences between running sums discriminators in i:j sectors (Forward:Backward).
double m_BE_Amplitude[16]
Calculated amplitudes in sectors of Backward Endcap.
double m_com_en[2]
Monte Carlo energy of the final state particles in CMS frame.
double m_FE_Waveform_10ns[16][631]
Waveforms with 10ns sampling for Forward Endcap sectors.
double m_BE_Pedal[16]
Calculated pedestal values for Backward Endcap.
bool m_includeInnerFE
Flag to include Inner part of the Forward Endcap.
bool m_saveSignal
Flag to save signal wavefroms into file.
StoreArray< MCParticle > m_MCParticles
MC particles.
void calculate_amplitudes()
Calculates amplitude [GeV] in an event for each sector.
double m_thresholdBkg
Threshold [GeV] on signal when sector considered as lighted.
std::string m_testFileName
Name of file to save output.
double m_com_ph[2]
Monte Carlo phi of the final state particles in CMS frame.
void setDescription(const std::string &description)
Sets the description of the module.
Definition Module.cc:214
void addParam(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Definition Module.h:559
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition Module.h:649
Abstract base class for different kinds of events.
STL namespace.