Belle II Software  release-05-01-25
ECLHitRateCounter.cc
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2019 - Belle II Collaboration *
4  * *
5  * Author: The Belle II Collaboration *
6  * Contributors: Marko Staric, Andrea Fodor *
7  * *
8  * This software is provided "as is" without any warranty. *
9  **************************************************************************/
10 
11 // Own include
12 #include <background/modules/BeamBkgHitRateMonitor/ECLHitRateCounter.h>
13 
14 #include <ecl/dbobjects/ECLCrystalCalib.h>
15 #include <framework/database/DBObjPtr.h>
16 #include <framework/geometry/B2Vector3.h>
17 
18 #include <numeric>
19 
20 using namespace std;
21 
22 
23 namespace Belle2 {
28  namespace Background {
29 
30  void ECLHitRateCounter::initialize(TTree* tree)
31  {
32  segmentECL();
33  // register collection(s) as optional, your detector might be excluded in DAQ
34  m_dsps.isOptional();
35 
36  // set branch address
37  tree->Branch("ecl", &m_rates, "averageDspBkgRate[16]/F:numEvents/I:validDspRate/O");
38 
39  //ECL calibration
40  DBObjPtr<ECLCrystalCalib> ECLElectronicsCalib("ECLCrystalElectronics"), ECLECalib("ECLCrystalEnergy"),
41  ECLWaveformNoise("ECLWaveformRMS");
42  m_ADCtoEnergy.resize(8736);
43  if (ECLElectronicsCalib) for (int i = 0; i < 8736; i++) m_ADCtoEnergy[i] = ECLElectronicsCalib->getCalibVector()[i];
44  if (ECLECalib) for (int i = 0; i < 8736; i++) m_ADCtoEnergy[i] *= ECLECalib->getCalibVector()[i];
45  m_waveformNoise.resize(8736);
46  if (ECLWaveformNoise) for (int i = 0; i < 8736; i++) m_waveformNoise[i] = ECLWaveformNoise->getCalibVector()[i];
47  }
48 
49  void ECLHitRateCounter::clear()
50  {
51  m_buffer.clear();
52  }
53 
54  void ECLHitRateCounter::accumulate(unsigned timeStamp)
55  {
56  // check if data are available
57  if (not m_dsps.isValid()) return;
58 
59  //calculate rates using waveforms
60  //The background rate for a crystal is calculated as
61  //rate = rms_pedestal_squared / (average_photon_energy_squared * time_constant)
62  //where time_constant=2.53 us and average_photon_energy_squared = 1 MeV
63  if (m_dsps.getEntries() == 8736) {
64 
65  // get buffer element
66  auto& rates = m_buffer[timeStamp];
67 
68  // increment event counter
69  rates.numEvents++;
70 
71  for (auto& aECLDsp : m_dsps) {
72 
73  int nadc = aECLDsp.getNADCPoints();
74  int cellID = aECLDsp.getCellId();
75  int segmentNumber = findECLSegment(cellID);
76  int crysID = cellID - 1;
77  std::vector<int> dspAv = aECLDsp.getDspA();
78 
79  //finding the pedestal value
80  double dspMean = (std::accumulate(dspAv.begin(), dspAv.begin() + nadc, 0.0)) / nadc;
81  double wpsum = 0;
82  for (int v = 0; v < nadc; v++) {
83  wpsum += pow(dspAv[v] - dspMean, 2);
84  }
85  double dspRMS = sqrt(wpsum / nadc);
86  double dspSigma = dspRMS * abs(m_ADCtoEnergy[crysID]);
87 
88  //calculating the background rate per second
89  double dspBkgRate = ((pow(dspSigma, 2)) - (pow(m_waveformNoise[crysID], 2))) / (2.53 * 1e-12);
90  if (dspBkgRate < 0) {
91  dspBkgRate = 0;
92  }
93 
94  //hit rate for segment in ECL, which is later normalized per 1Hz
95  rates.averageDspBkgRate[segmentNumber] += dspBkgRate;
96 
97  }
98 
99  // set flag to true to indicate the rates are valid
100  rates.validDspRate = true;
101  }
102  }
103 
104  void ECLHitRateCounter::normalize(unsigned timeStamp)
105  {
106  // copy buffer element
107  m_rates = m_buffer[timeStamp];
108 
109  if (not m_rates.validDspRate) return;
110 
111  // normalize
112  m_rates.normalize();
113 
114  //get average ret per crystal in segment
115  for (int i = 0; i < 16; i++) {
116  m_rates.averageDspBkgRate[i] /= m_crystalsInSegment[i];
117  }
118  }
119 
120 
121  void ECLHitRateCounter::segmentECL()
122  {
124  for (int cid = 1; cid < 8737; cid++) {
125  m_geometry->Mapping(cid);
126  const B2Vector3D position = m_geometry->GetCrystalPos(cid - 1);
127  const double phi = position.Phi();
128  const double z = position.Z();
129 
130  if (cid < 1297) {
131  if (phi > 0.7853 && phi < 2.356) {
132  m_segmentMap.insert(std::pair<int, int>(cid, 0));
133  m_crystalsInSegment[0] += 1;
134  } else if (phi >= 2.356 || phi <= -2.356) {
135  m_segmentMap.insert(std::pair<int, int>(cid, 1));
136  m_crystalsInSegment[1] += 1;
137  } else if (phi > -2.356 && phi < -0.7853) {
138  m_segmentMap.insert(std::pair<int, int>(cid, 2));
139  m_crystalsInSegment[2] += 1;
140  } else {
141  m_segmentMap.insert(std::pair<int, int>(cid, 3));
142  m_crystalsInSegment[3] += 1;
143  }
144  } else if (cid > 1152 && cid < 7777) {
145  if (z > 0) {
146  if (phi > 0.7853 && phi < 2.356) {
147  m_segmentMap.insert(std::pair<int, int>(cid, 4));
148  m_crystalsInSegment[4] += 1;
149  } else if (phi >= 2.356 || phi <= -2.356) {
150  m_segmentMap.insert(std::pair<int, int>(cid, 5));
151  m_crystalsInSegment[5] += 1;
152  } else if (phi > -2.356 && phi < -0.7853) {
153  m_segmentMap.insert(std::pair<int, int>(cid, 6));
154  m_crystalsInSegment[6] += 1;
155  } else {
156  m_segmentMap.insert(std::pair<int, int>(cid, 7));
157  m_crystalsInSegment[7] += 1;
158  }
159  } else {
160  if (phi > 0.7853 && phi < 2.356) {
161  m_segmentMap.insert(std::pair<int, int>(cid, 8));
162  m_crystalsInSegment[8] += 1;
163  } else if (phi >= 2.356 || phi <= -2.356) {
164  m_segmentMap.insert(std::pair<int, int>(cid, 9));
165  m_crystalsInSegment[9] += 1;
166  } else if (phi > -2.356 && phi < -0.7853) {
167  m_segmentMap.insert(std::pair<int, int>(cid, 10));
168  m_crystalsInSegment[10] += 1;
169  } else {
170  m_segmentMap.insert(std::pair<int, int>(cid, 11));
171  m_crystalsInSegment[11] += 1;
172  }
173  }
174  } else {
175  if (phi > 0.7853 && phi < 2.356) {
176  m_segmentMap.insert(std::pair<int, int>(cid, 12));
177  m_crystalsInSegment[12] += 1;
178  } else if (phi >= 2.356 || phi <= -2.356) {
179  m_segmentMap.insert(std::pair<int, int>(cid, 13));
180  m_crystalsInSegment[13] += 1;
181  } else if (phi > -2.356 && phi < -0.7853) {
182  m_segmentMap.insert(std::pair<int, int>(cid, 14));
183  m_crystalsInSegment[14] += 1;
184  } else {
185  m_segmentMap.insert(std::pair<int, int>(cid, 15));
186  m_crystalsInSegment[15] += 1;
187  }
188  }
189  }
190  }
191 
192  } // Background namespace
194 } // Belle2 namespace
Belle2::B2Vector3::Z
DataType Z() const
access variable Z (= .at(2) without boundary check)
Definition: B2Vector3.h:434
Belle2::DBObjPtr
Class for accessing objects in the database.
Definition: DBObjPtr.h:31
Belle2::B2Vector3< double >
Belle2::ECL::ECLGeometryPar::Instance
static ECLGeometryPar * Instance()
Static method to get a reference to the ECLGeometryPar instance.
Definition: ECLGeometryPar.cc:151
Belle2::B2Vector3::Phi
DataType Phi() const
The azimuth angle.
Definition: B2Vector3.h:150
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19