Belle II Software  release-05-02-19
TpcDigitizerModule.cc
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2013 - Belle II Collaboration *
4  * *
5  * Author: The Belle II Collaboration *
6  * Contributors: Igal Jaegle *
7  * *
8  * This software is provided "as is" without any warranty. *
9  **************************************************************************/
10 
11 #include <beast/microtpc/modules/TpcDigitizerModule.h>
12 #include <beast/microtpc/dataobjects/MicrotpcSimHit.h>
13 
14 #include <mdst/dataobjects/MCParticle.h>
15 #include <framework/logging/Logger.h>
16 #include <framework/gearbox/GearDir.h>
17 #include <framework/core/RandomNumbers.h>
18 
19 //c++
20 #include <cmath>
21 #include <boost/foreach.hpp>
22 #include <vector>
23 
24 using namespace Belle2;
25 using namespace microtpc;
26 
27 
28 //-----------------------------------------------------------------
29 // Register the Module
30 //-----------------------------------------------------------------
31 REG_MODULE(TpcDigitizer)
32 
33 //-----------------------------------------------------------------
34 // Implementation
35 //-----------------------------------------------------------------
36 
38 {
39  // Set module properties
40  setDescription("Microtpc digitizer module");
41 
42  //Default values are set here. New values can be in MICROTPC.xml.
43  addParam("LowerTimingCut", m_lowerTimingCut, "Lower timing cut", 0.);
44  addParam("UpperTimingCut", m_upperTimingCut, "Upper timing cut", 1000000.);
45 }
46 
47 TpcDigitizerModule::~TpcDigitizerModule()
48 {
49 }
50 
52 {
53  B2INFO("TpcDigitizer: Initializing");
54  m_microtpcHit.registerInDataStore();
55 
56  //get xml data
57  getXMLData();
58 
59  //converter: electron number to TOT part I
60  fctToT_Calib1 = new TF1("fctToT_Calib1", "[0]*(x/[3]+[1])/(x/[3]+[2])", 0., 100000.);
61  fctToT_Calib1->SetParameters(m_TOTA1, m_TOTB1, m_TOTC1, m_TOTQ1);
62  //converter: electron number to TOT part II
63  fctToT_Calib2 = new TF1("fctToT_Calib2", "[0]*(x/[3]+[1])/(x/[3]+[2])", 0., 100000.);
64  fctToT_Calib2->SetParameters(m_TOTA2, m_TOTB2, m_TOTC2, m_TOTQ2);
65  /*
66  for (int i = 0; i < m_nTPC; i++) {
67  for (int j = 0; j < 80; j++) {
68  for (int k = 0; k < 336; k++) {
69  for (int l = 0; l < MAXtSIZE; l++) {
70  m_dchip[i][j][k][l] = 0;
71  //dchip[j][k][l] = 0;
72  }
73  }
74  }
75  }
76  */
77 }
78 
80 {
81 }
82 
84 {
85  StoreArray<MCParticle> mcParticles;
86  StoreArray<MicrotpcSimHit> microtpcSimHits;
87 
88  m_dchip_map.clear();
89  m_dchip.clear();
90  m_dchip_detNb_map.clear();
91  m_dchip_pdg_map.clear();
92  m_dchip_trkID_map.clear();
93 
94  std::vector<double> T0(m_nTPC,
95  m_upperTimingCut); // TODO: why this number? Maybe pick something larger the the upperTiming cut? e.g. m_upperTimingCut + 1
96  //std::vector<bool> PixelFired(m_nTPC, false);
97 
98  for (const auto& microtpcSimHit : microtpcSimHits) {
99  const int detNb = microtpcSimHit.getdetNb();
100  const TVector3 simHitPosition = microtpcSimHit.gettkPos();
101  TVector3 chipPosition(
102  simHitPosition.X() / 100. - m_TPCCenter[detNb].X(),
103  simHitPosition.Y() / 100. - m_TPCCenter[detNb].Y(),
104  simHitPosition.Z() / 100. - m_TPCCenter[detNb].Z()
105  );
106  chipPosition.RotateZ(-m_TPCAngleZ[detNb] * TMath::DegToRad());
107  chipPosition.RotateX(-m_TPCAngleX[detNb] * TMath::DegToRad());
108  const double T = chipPosition.Z() + m_z_DG / 2.;
109  if (T < T0[detNb]) {
110  T0[detNb] = T;
111  }
112  }
113 
114  for (auto& val : T0) {
115  if (m_lowerTimingCut < val && val < m_upperTimingCut) {
116  val = val / m_v_DG;
117  } else {
118  val = -1.;
119  }
120  }
121  olddetNb = -1;
122  oldtrkID = -1;
123  //loop on all entries to store in 3D the ionization for each TPC
124  for (const auto& microtpcSimHit : microtpcSimHits) {
125 
126  const int PDGid = microtpcSimHit.gettkPDG();
127  if (m_LookAtRec == 1) {
128  if (PDGid != 1000020040 || PDGid != 1000060120 || PDGid != 1000080160 || PDGid != 2212) {
129  continue;
130  }
131  }
132 
133  const int detNb = microtpcSimHit.getdetNb();
134  const double edep = microtpcSimHit.getEnergyDep();
135  const double niel = microtpcSimHit.getEnergyNiel();
136  const int pdg = microtpcSimHit.gettkPDG();
137  const int trkID = microtpcSimHit.gettkID();
138 
139  const TVector3 simHitPosition = microtpcSimHit.gettkPos();
140  TVector3 chipPosition(
141  simHitPosition.X() / 100. - m_TPCCenter[detNb].X(),
142  simHitPosition.Y() / 100. - m_TPCCenter[detNb].Y(),
143  simHitPosition.Z() / 100. - m_TPCCenter[detNb].Z()
144  );
145  chipPosition.RotateZ(-m_TPCAngleZ[detNb] * TMath::DegToRad());
146  chipPosition.RotateX(-m_TPCAngleX[detNb] * TMath::DegToRad());
147 
148  TVector3 ChipPosition(0, 0, 0);
149  if (m_phase == 1) {
150  if (detNb == 0 || detNb == 3) {
151  ChipPosition.SetX(-chipPosition.Y());
152  ChipPosition.SetY(-chipPosition.X());
153  ChipPosition.SetZ(chipPosition.Z() + m_z_DG / 2.);
154  }
155  if (detNb == 1 || detNb == 2) {
156  ChipPosition.SetX(chipPosition.Y());
157  ChipPosition.SetY(chipPosition.X());
158  ChipPosition.SetZ(chipPosition.Z() + m_z_DG / 2.);
159  }
160  }
161  if (m_phase == 2) {
162  ChipPosition.SetX(chipPosition.Y());
163  ChipPosition.SetY(chipPosition.X());
164  ChipPosition.SetZ(chipPosition.Z() + m_z_DG / 2);
165  }
166 
167 
168  //If new detector filled the chip
169  if (olddetNb != detNb && m_dchip_map.size() > 0 && m_dchip.size() < 20000 && oldtrkID != trkID) {
170  Pixelization();
171  olddetNb = detNb;
172  oldtrkID = trkID;
173  m_dchip_map.clear();
174  m_dchip.clear();
175  m_dchip_detNb_map.clear();
176  m_dchip_pdg_map.clear();
177  m_dchip_trkID_map.clear();
178  }
179 
180  //check if ionization within sensitive volume
181  if ((-m_ChipColumnX < ChipPosition.X() && ChipPosition.X() < m_ChipColumnX) &&
182  (-m_ChipRowY < ChipPosition.Y() && ChipPosition.Y() < m_ChipRowY) &&
183  (0. < ChipPosition.Z() && ChipPosition.Z() < m_z_DG) &&
184  (m_lowerTimingCut < T0[detNb] && T0[detNb] < m_upperTimingCut)) {
185 
186  //ionization energy
187  //MeV -> keV
188  const double ionEn = (edep - niel) * 1e3; // TODO: Use Unit constants instead of self made magic numbers
189  // check if enough energy to ionize if not break
190  // keV -> eV
191 
192  //if ((ionEn * 1e3) < m_Workfct) continue; // TODO: Use Unit constants instead of self made magic numbers
194  // check if enough energy to ionize
195  //else if ((ionEn * 1e3) > m_Workfct) { // TODO: Use Unit constants instead of self made magic numbers
196  if ((ionEn * 1e3) > m_Workfct) { // TODO: Use Unit constants instead of self made magic numbers
197 
198  const double meanEl = ionEn * 1e3 / m_Workfct;
199  const double sigma = sqrt(m_Fanofac * meanEl);
200  const int NbEle = (int)gRandom->Gaus(meanEl, sigma);
201  const double NbEle_real = NbEle - NbEle * m_GasAbs * chipPosition.Z();
202 
203  // start loop on the number of electron-ion-pairs at each interaction point
204  for (int ie = 0; ie < (int)NbEle_real; ie++) {
205 
206  //drift ionization to GEM 1 plane
207  //const TLorentzVector driftGap(Drift(chipPosition.X(), chipPosition.Y(), chipPosition.Z(), m_Dt_DG, m_Dl_DG, m_v_DG));
208  double x_DG, y_DG, z_DG, t_DG;
209  Drift(ChipPosition.X(),
210  ChipPosition.Y(),
211  ChipPosition.Z(),
212  x_DG, y_DG, z_DG, t_DG, m_Dt_DG, m_Dl_DG, m_v_DG);
213 
214  //calculate and scale 1st GEM gain
215  const double GEM_gain1 = gRandom->Gaus(m_GEMGain1, m_GEMGain1 * m_GEMGainRMS1) / m_ScaleGain1;
216 
217  //calculate and scale 2nd GEM gain
218  const double GEM_gain2 = gRandom->Gaus(m_GEMGain2, m_GEMGain2 * m_GEMGainRMS2) / m_ScaleGain2;
219 
221  // start loop on amplification
222  for (int ig1 = 0; ig1 < (int)GEM_gain1; ig1++) {
223  //1st GEM geometrical effect
224  //const TVector2 GEM1(GEMGeo1(driftGap.X(), driftGap.Y()));
225  const TVector2 GEM1(GEMGeo1(x_DG, y_DG));
226  //drift 1st amplication to 2nd GEM
227  //const TLorentzVector transferGap(Drift(GEM1.X(), GEM1.Y(), m_z_TG, m_Dt_TG, m_Dl_TG, m_v_TG));
228  double x_TG, y_TG, z_TG, t_TG;
229  Drift(GEM1.X(), GEM1.Y(), m_z_TG, x_TG, y_TG, z_TG, t_TG, m_Dt_TG, m_Dl_TG, m_v_TG);
230 
232  // start loop on amplification
233  for (int ig2 = 0; ig2 < (int)GEM_gain2; ig2++) {
234  //2nd GEN geometrical effect
235  //const TVector2 GEM2(GEMGeo2(transferGap.X(), transferGap.Y()));
236  const TVector2 GEM2(GEMGeo2(x_TG, y_TG));
237  //drift 2nd amplification to chip
238  //const TLorentzVector collectionGap(Drift(GEM2.X(), GEM2.Y(), m_z_CG, m_Dt_CG, m_Dl_CG, m_v_CG));
239  double x_CG, y_CG, z_CG, t_CG;
240  Drift(GEM2.X(), GEM2.Y(), m_z_CG, x_CG, y_CG, z_CG, t_CG, m_Dt_CG, m_Dl_CG, m_v_CG);
241 
242  //determine col, row, and bc
243  int col = (int)((x_CG + m_ChipColumnX) / (2. * m_ChipColumnX / (double)m_ChipColumnNb));
244  int row = (int)((y_CG + m_ChipRowY) / (2. * m_ChipRowY / (double)m_ChipRowNb));
245  int pix = col + m_ChipColumnNb * row;
246  int quT = gRandom->Uniform(-1, 1);
247  int bci = (int)((t_DG + t_TG + t_CG - T0[detNb]) / (double)m_PixelTimeBin) + quT;
248  if (bci < 0)bci = 0;
249 
250  //check if amplified drifted electron are within pixel boundaries
251  if ((0 <= col && col < m_ChipColumnNb) &&
252  (0 <= row && row < m_ChipRowNb) &&
253  (0 <= pix && pix < m_ChipColumnNb * m_ChipRowNb) &&
254  (0 <= bci && bci < MAXtSIZE)) {
255  //PixelFired[detNb] = true;
256  //store info into 3D array for each TPCs
258  //m_dchip_map[std::tuple<int, int, int>(detNb, col, row)] = 1;
259  //m_dchip[std::tuple<int, int, int, int>(detNb, col, row, bci)] += (int)(m_ScaleGain1 * m_ScaleGain2);
260  m_dchip_map[std::tuple<int, int>(col, row)] = 1;
261  m_dchip_detNb_map[std::tuple<int, int>(col, row)] = detNb;
262  m_dchip_pdg_map[std::tuple<int, int>(col, row)] = pdg;
263  m_dchip_trkID_map[std::tuple<int, int>(col, row)] = trkID;
264  m_dchip[std::tuple<int, int, int>(col, row, bci)] += (int)(m_ScaleGain1 * m_ScaleGain2);
265  }
266  }
267  }
268  }
269  }
270  }
271  }
272 
273  //Pixelization of the 3D ionization cloud
274  /*for (int i = 0; i < m_nTPC; i++) {
275  if (m_lowerTimingCut < T0[i] && T0[i] < m_upperTimingCut && PixelFired[i]) {
276  Pixelization(i);
277 
278  for (int j = 0; j < 80; j++) {
279  for (int k = 0; k < 336; k++) {
280  for (int l = 0; l < MAXtSIZE; l++) {
281  m_dchip[i][j][k][l] = 0;
282  }
283  }
284  }
285 
286  }
287  }
288  */
289  if (m_dchip_map.size() > 0 && m_dchip.size() < 20000) {
290  //std::cout << " event size " << m_dchip_map.size() << " all " << m_dchip.size() << std::endl;
291  Pixelization();
292  }
293  m_dchip_map.clear();
294  m_dchip.clear();
295  m_dchip_detNb_map.clear();
296  m_dchip_pdg_map.clear();
297  m_dchip_trkID_map.clear();
298 }
299 /*
300 TLorentzVector TpcDigitizerModule::Drift(
301  double x1, double y1, double z1,
302  double st, double sl, double vd
303 )
304 {
305  double x2 = 0;
306  double y2 = 0;
307  double z2 = 0;
308  double t2 = 0;
309  if (z1 > 0.) {
310  //transverse diffusion
311  x2 = x1 + gRandom->Gaus(0., sqrt(z1) * st);
312  //transverse diffusion
313  y2 = y1 + gRandom->Gaus(0., sqrt(z1) * st);
314  //longitidinal diffusion
315  z2 = z1 + gRandom->Gaus(0., sqrt(z1) * sl);
316  //time to diffuse
317  t2 = z2 / vd;
318  } else {
319  x2 = -1000; y2 = -1000; z2 = -1000; t2 = -1000;
320  }
321  return TLorentzVector(x2, y2, z2, t2);
322 }
323 */
324 void TpcDigitizerModule::Drift(double x1, double y1, double z1, double& x2, double& y2, double& z2, double& t2, double st,
325  double sl, double vd)
326 {
327  //check if
328  if (z1 > 0.) {
329  //transverse diffusion
330  x2 = x1 + gRandom->Gaus(0., sqrt(z1) * st);
331  //transverse diffusion
332  y2 = y1 + gRandom->Gaus(0., sqrt(z1) * st);
333  //longitidinal diffusion
334  z2 = z1 + gRandom->Gaus(0., sqrt(z1) * sl);
335  //time to diffuse
336  t2 = z2 / vd;
337  } else {
338  x2 = -1000; y2 = -1000; z2 = -1000; t2 = -1000;
339  }
340 }
341 TVector2 TpcDigitizerModule::GEMGeo1(double x1, double y1)
342 {
343  static const double sqrt3o4 = std::sqrt(3. / 4.);
344  double x2 = 0;
345  double y2 = (int)(y1 / (sqrt3o4 * m_GEMpitch) + (y1 < 0 ? -0.5 : 0.5)) * sqrt3o4 * m_GEMpitch;
346  int yint = (int)(y1 / (sqrt3o4 * m_GEMpitch) + 0.5);
347  if (yint % 2) {
348  x2 = static_cast<int>(x1 / m_GEMpitch + (x1 < 0 ? -0.5 : 0.5)) * m_GEMpitch;
349  } else {
350  //everysecond row is shifted with half a pitch
351  x2 = (static_cast<int>(x1 / m_GEMpitch) + (x1 < 0 ? -0.5 : 0.5)) * m_GEMpitch;
352  }
353  return TVector2(x2, y2);
354 }
355 
356 TVector2 TpcDigitizerModule::GEMGeo2(double x1, double y1)
357 {
358  static const double sqrt3o4 = std::sqrt(3. / 4.);
359  double x2 = (int)(x1 / (sqrt3o4 * m_GEMpitch) + (x1 < 0 ? -0.5 : 0.5)) * sqrt3o4 * m_GEMpitch;
360  double y2 = 0;
361  int yint = (int)(x1 / (sqrt3o4 * m_GEMpitch) + 0.5);
362  if (yint % 2) {
363  y2 = static_cast<int>(y1 / m_GEMpitch + (y1 < 0 ? -0.5 : 0.5)) * m_GEMpitch;
364  } else {
365  //everysecond row is shifted with half a pitch
366  y2 = (static_cast<int>(y1 / m_GEMpitch) + (y1 < 0 ? -0.5 : 0.5)) * m_GEMpitch;
367  }
368  return TVector2(x2, y2);
369 }
370 
371 
372 
373 
374 
375 //bool TpcDigitizerModule::Pixelization(int detNb)
377 {
378  std::vector<int> t0;
379  std::vector<int> col;
380  std::vector<int> row;
381  std::vector<int> ToT;
382  std::vector<int> bci;
383  t0.clear();
384  col.clear();
385  row.clear();
386  ToT.clear();
387  bci.clear();
388  StoreArray<MicrotpcHit> microtpcHits;
389 
390  for (auto& keyValuePair : m_dchip_map) {
391  const auto& key = keyValuePair.first;
392  //column
393  int i = std::get<0>(key);
394  //raw
395  int j = std::get<1>(key);
396 
397  if (m_dchip_map[std::tuple<int, int>(i, j)] == 1) {
398 
399  int k0 = 1e9;
400  const int quE = gRandom->Uniform(0, 2);
401  const double thresEl = m_PixelThreshold + gRandom->Uniform(-1.*m_PixelThresholdRMS, 1.*m_PixelThresholdRMS);
402  int kcounter = 0;
403  //determined t0 ie first time above pixel threshold
404  for (auto& keyValuePair2 : m_dchip) {
405  const auto& key2 = keyValuePair2.first;
406  int k = std::get<2>(key2);
407  if (m_dchip[std::tuple<int, int, int>(i, j, k)] > thresEl) {
408  if (k0 > k)k0 = k;
409  kcounter ++;
410  }
411  }
412  //std::cout<<"kcounter " << kcounter << std::endl;
413  //determined nb of bc per pixel
414  //if good t0
415  if (k0 != 1e9) {
416  int ik = 0;
417  int NbOfEl = 0;
418  for (auto& keyValuePair2 : m_dchip) {
419  const auto& key2 = keyValuePair2.first;
420  int k = std::get<2>(key2);
421  //sum up charge with 16 cycles
422  if (ik < 16) {
423  NbOfEl += m_dchip[std::tuple<int, int, int>(i, j, k)];
424  } else {
425  //calculate ToT
426  int tot = -1;
427  if (NbOfEl > thresEl && NbOfEl <= 45.*m_TOTQ1) {
428  tot = (int)fctToT_Calib1->Eval((double)NbOfEl) + quE;
429  } else if (NbOfEl > 45.*m_TOTQ1 && NbOfEl <= 900.*m_TOTQ1) {
430  tot = (int)fctToT_Calib2->Eval((double)NbOfEl);
431  } else if (NbOfEl > 800.*m_TOTQ1) {
432  tot = 13;
433  }
434  if (tot > 12) {
435  tot = 13;
436  }
437  if (tot >= 0) {
438  ToT.push_back(tot);
439  t0.push_back(k0);
440  col.push_back(i);
441  row.push_back(j);
442  bci.push_back(k0);
443  }
444  ik = 0;
445  NbOfEl = 0;
446  }
447  ik++;
448  }
449 
450  if (kcounter < 16) {
451  //calculate ToT
452  int tot = -1;
453  if (NbOfEl > thresEl && NbOfEl <= 45.*m_TOTQ1) {
454  tot = (int)fctToT_Calib1->Eval((double)NbOfEl) + quE;
455  } else if (NbOfEl > 45.*m_TOTQ1 && NbOfEl <= 900.*m_TOTQ1) {
456  tot = (int)fctToT_Calib2->Eval((double)NbOfEl);
457  } else if (NbOfEl > 800.*m_TOTQ1) {
458  tot = 13;
459  }
460  if (tot > 12) {
461  tot = 13;
462  }
463  if (tot >= 0) {
464  ToT.push_back(tot);
465  t0.push_back(k0);
466  col.push_back(i);
467  row.push_back(j);
468  bci.push_back(k0);
469  }
470  }
471 
472  }
473  } //end loop on row
474  } // end loop on col
475 
476  //bool PixHit = false;
477  //if entry
478 
479  if (bci.size() > 0) {
480  //std::cout << " size " << bci.size() << std::endl;
481  //PixHit = true;
482  //find start time
483  sort(t0.begin(), t0.end());
484 
485  //loop on nb of hit
486  for (int j = 0; j < (int)bci.size(); j++) {
487  if ((bci[j] - t0[0]) > (m_PixelTimeBinNb - 1)) {
488  continue;
489  }
490  //create MicrotpcHit
491  microtpcHits.appendNew(MicrotpcHit(col[j] + 1, row[j] + 1, bci[j] - t0[0] + 1, ToT[j],
492  m_dchip_detNb_map[std::tuple<int, int>(col[j], row[j])],
493  m_dchip_pdg_map[std::tuple<int, int>(col[j], row[j])],
494  m_dchip_trkID_map[std::tuple<int, int>(col[j], row[j])]));
495  } //end if entry
496  }
497  //return PixHit;
498  /*
499  std::vector<int> t0[10];
500  std::vector<int> col[10];
501  std::vector<int> row[10];
502  std::vector<int> ToT[10];
503  std::vector<int> bci[10];
504 
505  StoreArray<MicrotpcHit> microtpcHits;
506 
507  for (auto& keyValuePair : m_dchip_map) {
508  const auto& key = keyValuePair.first;
509  //detector number
510  int detNb = std::get<0>(key);
511  //column
512  int i = std::get<1>(key);
513  //raw
514  int j = std::get<2>(key);
515 
516  if (m_dchip_map[std::tuple<int, int, int>(detNb, i, j)] == 1) {
517 
518  int k0 = -10;
519  const int quE = gRandom->Uniform(0, 2);
520  const double thresEl = m_PixelThreshold + gRandom->Uniform(-1.*m_PixelThresholdRMS, 1.*m_PixelThresholdRMS);
521  //determined t0 ie first time above pixel threshold
522  //for (int k = 0; k < MAXtSIZE; k++) {
523  for (auto& keyValuePair2 : m_dchip) {
524  const auto& key2 = keyValuePair2.first;
525  int k = std::get<3>(key2);
526  if (m_dchip[std::tuple<int, int, int, int>(detNb, i, j, k)] > thresEl) {
527  //if (m_dchip[detNb][i][j][k] > thresEl) {
528  k0 = k;
529  break;
530  }
531  }
532  //determined nb of bc per pixel
533 
534  //if good t0
535  if (k0 != -10) {
536  int ik = 0;
537  int NbOfEl = 0;
538  //for (int k = k0; k < MAXtSIZE; k++) {
539  for (auto& keyValuePair2 : m_dchip) {
540  const auto& key2 = keyValuePair2.first;
541  int k = std::get<3>(key2);
542  //sum up charge with 16 cycles
543  if (ik < 16) {
544  NbOfEl += m_dchip[std::tuple<int, int, int, int>(detNb, i, j, k)];
545  //NbOfEl += m_dchip[detNb][i][j][k];
546  } else {
547  //calculate ToT
548  int tot = -1;
549  if (NbOfEl > thresEl && NbOfEl <= 45.*m_TOTQ1) {
550  tot = (int)fctToT_Calib1->Eval((double)NbOfEl) + quE;
551  } else if (NbOfEl > 45.*m_TOTQ1 && NbOfEl <= 900.*m_TOTQ1) {
552  tot = (int)fctToT_Calib2->Eval((double)NbOfEl);
553  } else if (NbOfEl > 800.*m_TOTQ1) {
554  tot = 14;
555  }
556  if (tot > 13) {
557  tot = 14;
558  }
559  if (tot >= 0) {
560  ToT[detNb].push_back(tot);
561  t0[detNb].push_back(k0);
562  col[detNb].push_back(i);
563  row[detNb].push_back(j);
564  bci[detNb].push_back(k0);
565  }
566  ik = 0;
567  NbOfEl = 0;
568  }
569  ik++;
570  }
571  }
572  } //end loop on row
573  //for (int k = 0; k < MAXtSIZE; k++) m_dchip[detNb][i][j][k] = 0;
574  } // end loop on col
575 
576  //bool PixHit = false;
577  for (int i = 0; i < 10 ; i++) {
578  //if entry
579  if (bci[i].size() > 0) {
580  //PixHit = true;
581  //find start time
582  sort(t0[i].begin(), t0[i].end());
583 
584  //loop on nb of hit
585  for (int j = 0; j < (int)bci[i].size(); j++) {
586  if ((bci[i][j] - t0[i][0]) > (m_PixelTimeBinNb - 1)) {
587  continue;
588  }
589  //create MicrotpcHit
590  microtpcHits.appendNew(MicrotpcHit(col[i][j], row[i][j], bci[i][j] - t0[i][0], ToT[i][j], i));
591  } //end on loop nb of hit
592  } //end if entry
593  }
594  //return PixHit;
595  */
596 }
597 
598 /*
599 
600 bool TpcDigitizerModule::Pixelization(int detNb)
601 {
602  std::vector<int> t0;
603  std::vector<int> col;
604  std::vector<int> row;
605  std::vector<int> ToT;
606  std::vector<int> bci;
607 
608  StoreArray<MicrotpcHit> microtpcHits;
609 
610  //loop on col.
611  for (int i = 0; i < (int)m_ChipColumnNb; i++) {
612  //loop on row
613  for (int j = 0; j < (int)m_ChipRowNb; j++) {
614  int k0 = -10;
615  const int quE = gRandom->Uniform(0, 2);
616  const double thresEl = m_PixelThreshold + gRandom->Uniform(-1.*m_PixelThresholdRMS, 1.*m_PixelThresholdRMS);
617  //determined t0 ie first time above pixel threshold
618  for (int k = 0; k < MAXtSIZE; k++) {
619  //if (m_dchip[std::tuple<int, int, int, int>(detNb, i, j, k)] > thresEl) {
620  if (m_dchip[detNb][i][j][k] > thresEl) {
621  k0 = k;
622  break;
623  }
624  }
625  //determined nb of bc per pixel
626 
627  //if good t0
628  if (k0 != -10) {
629  int ik = 0;
630  int NbOfEl = 0;
631  for (int k = k0; k < MAXtSIZE; k++) {
632  //sum up charge with 16 cycles
633  if (ik < 16) {
634  //NbOfEl += m_dchip[std::tuple<int, int, int, int>(detNb, i, j, k)];
635  NbOfEl += m_dchip[detNb][i][j][k];
636  } else {
637  //calculate ToT
638  int tot = -1;
639  if (NbOfEl > thresEl && NbOfEl <= 45.*m_TOTQ1) {
640  tot = (int)fctToT_Calib1->Eval((double)NbOfEl) + quE;
641  } else if (NbOfEl > 45.*m_TOTQ1 && NbOfEl <= 900.*m_TOTQ1) {
642  tot = (int)fctToT_Calib2->Eval((double)NbOfEl);
643  } else if (NbOfEl > 800.*m_TOTQ1) {
644  tot = 14;
645  }
646  if (tot > 13) {
647  tot = 14;
648  }
649  if (tot >= 0) {
650  ToT.push_back(tot);
651  t0.push_back(k0);
652  col.push_back(i);
653  row.push_back(j);
654  bci.push_back(k0);
655  }
656  ik = 0;
657  NbOfEl = 0;
658  }
659  ik++;
660  }
661  }
662  } //end loop on row
663  } // end loop on col
664 
665  bool PixHit = false;
666  //if entry
667  if (bci.size() > 0) {
668  PixHit = true;
669  //find start time
670  sort(t0.begin(), t0.end());
671 
672  //loop on nb of hit
673  for (int i = 0; i < (int)bci.size(); i++) {
674  if ((bci[i] - t0[0]) > (m_PixelTimeBinNb - 1)) {
675  continue;
676  }
677  //create MicrotpcHit
678  microtpcHits.appendNew(MicrotpcHit(col[i], row[i], bci[i] - t0[0], ToT[i], detNb));
679  } //end on loop nb of hit
680  } //end if entry
681 
682  return PixHit;
683 }
684 */
685 //read tube centers, impulse response, and garfield drift data filename from MICROTPC.xml
687 {
688  //const GearDir& content;
689  GearDir content = GearDir("/Detector/DetectorComponent[@name=\"MICROTPC\"]/Content/");
690 
691  //get the location of the tubes
692  BOOST_FOREACH(const GearDir & activeParams, content.getNodes("Active")) {
693 
694  m_TPCCenter.push_back(TVector3(activeParams.getLength("SensVol_x"), activeParams.getLength("SensVol_y"),
695  activeParams.getLength("SensVol_z")));
696  m_TPCAngleX.push_back(activeParams.getLength("AngleX"));
697  m_TPCAngleZ.push_back(activeParams.getLength("AngleZ"));
698 
699  m_nTPC++;
700  }
701  m_phase = content.getDouble("Phase");
702  m_LookAtRec = content.getDouble("LookAtRec");
703  m_GEMGain1 = content.getDouble("GEMGain1");
704  m_GEMGain2 = content.getDouble("GEMGain2");
705  m_GEMGainRMS1 = content.getDouble("GEMGainRMS1");
706  m_GEMGainRMS2 = content.getDouble("GEMGainRMS2");
707  m_ScaleGain1 = content.getDouble("ScaleGain1");
708  m_ScaleGain2 = content.getDouble("ScaleGain2");
709  m_GEMpitch = content.getDouble("GEMpitch");
710  m_PixelThreshold = content.getInt("PixelThreshold");
711  m_PixelThresholdRMS = content.getInt("PixelThresholdRMS");
712  m_PixelTimeBinNb = content.getInt("PixelTimeBinNb");
713  m_PixelTimeBin = content.getDouble("PixelTimeBin");
714  m_ChipColumnNb = content.getInt("ChipColumnNb");
715  m_ChipRowNb = content.getInt("ChipRowNb");
716  m_ChipColumnX = content.getDouble("ChipColumnX");
717  m_ChipRowY = content.getDouble("ChipRowY");
718  m_TOTA1 = content.getDouble("TOTA1");
719  m_TOTB1 = content.getDouble("TOTB1");
720  m_TOTC1 = content.getDouble("TOTC1");
721  m_TOTQ1 = content.getDouble("TOTQ1");
722  m_TOTA2 = content.getDouble("TOTA2");
723  m_TOTB2 = content.getDouble("TOTB2");
724  m_TOTC2 = content.getDouble("TOTC2");
725  m_TOTQ2 = content.getDouble("TOTQ2");
726  m_z_DG = content.getDouble("z_DG");
727  m_z_TG = content.getDouble("z_TG");
728  m_z_CG = content.getDouble("z_CG");
729  m_Dl_DG = content.getDouble("Dl_DG");
730  m_Dl_TG = content.getDouble("Dl_TG");
731  m_Dl_CG = content.getDouble("Dl_CG");
732  m_Dt_DG = content.getDouble("Dt_DG");
733  m_Dt_TG = content.getDouble("Dt_TG");
734  m_Dt_CG = content.getDouble("Dt_CG");
735  m_v_DG = content.getDouble("v_DG");
736  m_v_TG = content.getDouble("v_TG");
737  m_v_CG = content.getDouble("v_CG");
738  m_Workfct = content.getDouble("Workfct");
739  m_Fanofac = content.getDouble("Fanofac");
740  m_GasAbs = content.getDouble("GasAbs");
741 
742  B2INFO("TpcDigitizer: Aquired tpc locations and gas parameters");
743  B2INFO(" from MICROTPC.xml. There are " << m_nTPC << " TPCs implemented");
744 
745 }
746 
748 {
749 }
750 
752 {
753 }
754 
755 
Belle2::StoreArray::appendNew
T * appendNew()
Construct a new T object at the end of the array.
Definition: StoreArray.h:256
Belle2::microtpc::TpcDigitizerModule::m_lowerTimingCut
double m_lowerTimingCut
Lower timing cut.
Definition: TpcDigitizerModule.h:209
Belle2::microtpc::TpcDigitizerModule::m_z_DG
double m_z_DG
z drift gap
Definition: TpcDigitizerModule.h:157
Belle2::microtpc::TpcDigitizerModule::m_upperTimingCut
double m_upperTimingCut
Upper timing cut.
Definition: TpcDigitizerModule.h:211
Belle2::microtpc::TpcDigitizerModule::fctToT_Calib2
TF1 * fctToT_Calib2
Define ToT calib 2.
Definition: TpcDigitizerModule.h:109
Belle2::microtpc::TpcDigitizerModule::m_Dl_TG
double m_Dl_TG
Longitudinal diffusion in transfer gap.
Definition: TpcDigitizerModule.h:171
Belle2::microtpc::TpcDigitizerModule::m_ScaleGain1
double m_ScaleGain1
Scale GEM 1 gain.
Definition: TpcDigitizerModule.h:115
Belle2::microtpc::TpcDigitizerModule::m_TOTC2
double m_TOTC2
TOT factor C2.
Definition: TpcDigitizerModule.h:153
Belle2::microtpc::TpcDigitizerModule::m_Dl_DG
double m_Dl_DG
Longitudinal diffusion in drift gap.
Definition: TpcDigitizerModule.h:169
Belle2::microtpc::TpcDigitizerModule::m_TOTQ2
double m_TOTQ2
TOT factor Q2.
Definition: TpcDigitizerModule.h:155
Belle2::microtpc::TpcDigitizerModule::endRun
virtual void endRun() override
This method is called if the current run ends.
Definition: TpcDigitizerModule.cc:747
REG_MODULE
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:652
Belle2::microtpc::TpcDigitizerModule::m_PixelThreshold
int m_PixelThreshold
Pixel threshold.
Definition: TpcDigitizerModule.h:125
Belle2::microtpc::TpcDigitizerModule::m_TOTB2
double m_TOTB2
TOT factor B2.
Definition: TpcDigitizerModule.h:151
Belle2::MicrotpcHit
ClassMicrotpcHit - digitization simulated hit for the Microtpc detector.
Definition: MicrotpcHit.h:36
Belle2::microtpc::TpcDigitizerModule::m_phase
Int_t m_phase
Phase.
Definition: TpcDigitizerModule.h:105
Belle2::microtpc::TpcDigitizerModule::m_ChipRowNb
int m_ChipRowNb
Chip row number.
Definition: TpcDigitizerModule.h:131
Belle2::microtpc::TpcDigitizerModule::Drift
virtual void Drift(double, double, double, double &, double &, double &, double &, double, double, double)
Drift ionization Make the ionization drifting from (x,y,z) to GEM1 top plane.
Definition: TpcDigitizerModule.cc:324
Belle2::microtpc::TpcDigitizerModule::m_TPCCenter
std::vector< TVector3 > m_TPCCenter
TPC coordinate.
Definition: TpcDigitizerModule.h:202
Belle2::microtpc::TpcDigitizerModule::m_PixelThresholdRMS
int m_PixelThresholdRMS
Pixel threshold RMS.
Definition: TpcDigitizerModule.h:127
Belle2::microtpc::TpcDigitizerModule::m_GEMGainRMS2
double m_GEMGainRMS2
GEM 2 RMS.
Definition: TpcDigitizerModule.h:119
Belle2::microtpc::TpcDigitizerModule::m_GasAbs
double m_GasAbs
Absorption in gas.
Definition: TpcDigitizerModule.h:185
Belle2::microtpc::TpcDigitizerModule::m_TPCAngleZ
std::vector< float > m_TPCAngleZ
TPC angle Z.
Definition: TpcDigitizerModule.h:206
Belle2::microtpc::TpcDigitizerModule
Micro TPC digitizer.
Definition: TpcDigitizerModule.h:43
Belle2::microtpc::TpcDigitizerModule::m_z_CG
double m_z_CG
z collection gap
Definition: TpcDigitizerModule.h:161
Belle2::microtpc::TpcDigitizerModule::m_GEMGain1
double m_GEMGain1
GEM 1 gain.
Definition: TpcDigitizerModule.h:111
Belle2::microtpc::TpcDigitizerModule::Pixelization
void Pixelization()
Produces the pixelization.
Definition: TpcDigitizerModule.cc:376
Belle2::microtpc::TpcDigitizerModule::GEMGeo1
TVector2 GEMGeo1(double x1, double y1)
GEMazition of GEM1.
Definition: TpcDigitizerModule.cc:341
Belle2::Module
Base class for Modules.
Definition: Module.h:74
Belle2::microtpc::TpcDigitizerModule::initialize
virtual void initialize() override
Initialize the Module.
Definition: TpcDigitizerModule.cc:51
Belle2::microtpc::TpcDigitizerModule::m_Dt_DG
double m_Dt_DG
Transverse diffusion in drift gap.
Definition: TpcDigitizerModule.h:163
Belle2::microtpc::TpcDigitizerModule::beginRun
virtual void beginRun() override
Called when entering a new run.
Definition: TpcDigitizerModule.cc:79
Belle2::microtpc::TpcDigitizerModule::m_TOTA2
double m_TOTA2
TOT factor A2.
Definition: TpcDigitizerModule.h:149
Belle2::microtpc::TpcDigitizerModule::m_GEMGainRMS1
double m_GEMGainRMS1
GEM 1 RMS.
Definition: TpcDigitizerModule.h:113
Belle2::microtpc::TpcDigitizerModule::oldtrkID
int oldtrkID
Old track ID.
Definition: TpcDigitizerModule.h:217
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::microtpc::TpcDigitizerModule::m_v_DG
double m_v_DG
Drift velocity in drift gap.
Definition: TpcDigitizerModule.h:175
Belle2::GearDir
GearDir is the basic class used for accessing the parameter store.
Definition: GearDir.h:41
Belle2::microtpc::TpcDigitizerModule::m_dchip_pdg_map
std::map< std::tuple< int, int >, int > m_dchip_pdg_map
chip pdg map arrays
Definition: TpcDigitizerModule.h:192
Belle2::microtpc::TpcDigitizerModule::m_TOTQ1
double m_TOTQ1
TOT factor Q1.
Definition: TpcDigitizerModule.h:147
Belle2::microtpc::TpcDigitizerModule::m_Fanofac
double m_Fanofac
Fano factor.
Definition: TpcDigitizerModule.h:183
Belle2::microtpc::TpcDigitizerModule::m_ScaleGain2
double m_ScaleGain2
Scale GEM 2 gain.
Definition: TpcDigitizerModule.h:121
Belle2::microtpc::TpcDigitizerModule::m_PixelTimeBin
double m_PixelTimeBin
Pixel time bin.
Definition: TpcDigitizerModule.h:139
Belle2::microtpc::TpcDigitizerModule::m_LookAtRec
int m_LookAtRec
Flag 0/1 only look at nuclear recoils.
Definition: TpcDigitizerModule.h:198
Belle2::microtpc::TpcDigitizerModule::m_Dt_CG
double m_Dt_CG
Transverse diffusion in collection gap.
Definition: TpcDigitizerModule.h:167
Belle2::microtpc::TpcDigitizerModule::m_TOTC1
double m_TOTC1
TOT factor C1.
Definition: TpcDigitizerModule.h:145
Belle2::microtpc::TpcDigitizerModule::m_dchip_map
std::map< std::tuple< int, int >, int > m_dchip_map
chip map arrays
Definition: TpcDigitizerModule.h:190
Belle2::microtpc::TpcDigitizerModule::m_TOTB1
double m_TOTB1
TOT factor B1.
Definition: TpcDigitizerModule.h:143
Belle2::microtpc::TpcDigitizerModule::olddetNb
int olddetNb
Old detector counter.
Definition: TpcDigitizerModule.h:214
Belle2::microtpc::TpcDigitizerModule::m_v_CG
double m_v_CG
Drift velocity in collection gap.
Definition: TpcDigitizerModule.h:179
Belle2::microtpc::TpcDigitizerModule::m_nTPC
int m_nTPC
number of detectors.
Definition: TpcDigitizerModule.h:200
Belle2::microtpc::TpcDigitizerModule::m_v_TG
double m_v_TG
Drift velocity in transfer gap.
Definition: TpcDigitizerModule.h:177
Belle2::gearbox::Interface::getLength
double getLength(const std::string &path="") const noexcept(false)
Get the parameter path as a double converted to the standard length unit.
Definition: Interface.h:261
Belle2::microtpc::TpcDigitizerModule::GEMGeo2
TVector2 GEMGeo2(double x1, double y1)
GEMazition of GEM2.
Definition: TpcDigitizerModule.cc:356
Belle2::microtpc::TpcDigitizerModule::m_Dt_TG
double m_Dt_TG
Transverse diffusion in transfer gap.
Definition: TpcDigitizerModule.h:165
Belle2::microtpc::TpcDigitizerModule::m_GEMGain2
double m_GEMGain2
GEM 2 gain.
Definition: TpcDigitizerModule.h:117
Belle2::microtpc::TpcDigitizerModule::m_Workfct
double m_Workfct
Work function.
Definition: TpcDigitizerModule.h:181
Belle2::microtpc::TpcDigitizerModule::m_TPCAngleX
std::vector< float > m_TPCAngleX
TPC angle X.
Definition: TpcDigitizerModule.h:204
Belle2::microtpc::TpcDigitizerModule::m_dchip_detNb_map
std::map< std::tuple< int, int >, int > m_dchip_detNb_map
chip Nb map arrays
Definition: TpcDigitizerModule.h:196
Belle2::microtpc::TpcDigitizerModule::m_dchip_trkID_map
std::map< std::tuple< int, int >, int > m_dchip_trkID_map
chip track ID map arrays
Definition: TpcDigitizerModule.h:194
Belle2::microtpc::TpcDigitizerModule::fctToT_Calib1
TF1 * fctToT_Calib1
Define ToT calib 1.
Definition: TpcDigitizerModule.h:107
Belle2::microtpc::TpcDigitizerModule::m_TOTA1
double m_TOTA1
TOT factor A1.
Definition: TpcDigitizerModule.h:141
Belle2::StoreArray< MCParticle >
Belle2::microtpc::TpcDigitizerModule::m_Dl_CG
double m_Dl_CG
Longitudinal diffusion in collection gap.
Definition: TpcDigitizerModule.h:173
Belle2::microtpc::TpcDigitizerModule::m_ChipRowY
double m_ChipRowY
Chip row y dimension.
Definition: TpcDigitizerModule.h:135
Belle2::microtpc::TpcDigitizerModule::event
virtual void event() override
This method is the core of the module.
Definition: TpcDigitizerModule.cc:83
Belle2::microtpc::TpcDigitizerModule::terminate
virtual void terminate() override
This method is called at the end of the event processing.
Definition: TpcDigitizerModule.cc:751
Belle2::microtpc::TpcDigitizerModule::m_z_TG
double m_z_TG
z transfer gap
Definition: TpcDigitizerModule.h:159
Belle2::microtpc::TpcDigitizerModule::m_ChipColumnNb
int m_ChipColumnNb
Chip column number.
Definition: TpcDigitizerModule.h:129
Belle2::microtpc::TpcDigitizerModule::m_GEMpitch
double m_GEMpitch
GEM pitch.
Definition: TpcDigitizerModule.h:123
Belle2::microtpc::TpcDigitizerModule::m_ChipColumnX
double m_ChipColumnX
Chip column x dimension.
Definition: TpcDigitizerModule.h:133
Belle2::microtpc::TpcDigitizerModule::getXMLData
void getXMLData()
Array for MicrotpcHit.
Definition: TpcDigitizerModule.cc:686
Belle2::microtpc::TpcDigitizerModule::m_PixelTimeBinNb
int m_PixelTimeBinNb
Pixel time number of bin.
Definition: TpcDigitizerModule.h:137
Belle2::microtpc::TpcDigitizerModule::m_dchip
std::map< std::tuple< int, int, int >, int > m_dchip
chip store arrays
Definition: TpcDigitizerModule.h:188