Belle II Software  release-08-01-10
FANGSDigitizerModule.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 #include <beast/fangs/modules/FANGSDigitizerModule.h>
10 #include <beast/fangs/dataobjects/FANGSSimHit.h>
11 
12 #include <mdst/dataobjects/MCParticle.h>
13 #include <framework/logging/Logger.h>
14 #include <framework/gearbox/GearDir.h>
15 #include <framework/core/RandomNumbers.h>
16 
17 //c++
18 #include <cmath>
19 #include <vector>
20 
21 using namespace Belle2;
22 using namespace fangs;
23 
24 
25 //-----------------------------------------------------------------
26 // Register the Module
27 //-----------------------------------------------------------------
28 REG_MODULE(FANGSDigitizer);
29 
30 //-----------------------------------------------------------------
31 // Implementation
32 //-----------------------------------------------------------------
33 
35 {
36  // Set module properties
37  setDescription("FANGS digitizer module");
38 
39  //Default values are set here. New values can be in FANGS.xml.
40  addParam("LowerTimingCut", m_lowerTimingCut, "Lower timing cut", 0.);
41  addParam("UpperTimingCut", m_upperTimingCut, "Upper timing cut", 1000000.);
42 }
43 
44 FANGSDigitizerModule::~FANGSDigitizerModule()
45 {
46 }
47 
49 {
50  B2INFO("FANGSDigitizer: Initializing");
51  m_fangsHit.registerInDataStore();
52 
53  //get xml data
54  getXMLData();
55 
56  //converter: electron number to TOT part I
57  fctToT_Calib1 = new TF1("fctToT_Calib1", "[0]*(x/[3]+[1])/(x/[3]+[2])", 0., 100000.);
58  fctToT_Calib1->SetParameters(m_TOTA1, m_TOTB1, m_TOTC1, m_TOTQ1);
59  //converter: electron number to TOT part II
60  fctToT_Calib2 = new TF1("fctToT_Calib2", "[0]*(x/[3]+[1])/(x/[3]+[2])", 0., 100000.);
61  fctToT_Calib2->SetParameters(m_TOTA2, m_TOTB2, m_TOTC2, m_TOTQ2);
62 }
63 
65 {
66 }
67 
69 {
70  StoreArray<FANGSSimHit> FANGSSimHits;
71  m_nFANGS = 15;
72  std::vector<double> T0(m_nFANGS,
74 
75  //Find the start time
76  for (const auto& FANGSSimHit : FANGSSimHits) {
77  const int lad = FANGSSimHit.getLadder();
78  const int sen = FANGSSimHit.getSensor();
79  const int detNb = (lad - 1) * 5 + sen - 1;
80  const TVector3 trackPosition = FANGSSimHit.getLocalPosEntry();
81  const double z = trackPosition.Y() + m_sensor_width / 2.; //cm
82  if (z < T0[detNb]) {
83  T0[detNb] = z;
84  }
85  }
86 
87  for (auto& val : T0) {
88  if (m_lowerTimingCut < val && val < m_upperTimingCut) {
89  val = val / m_v_sensor; //cm / (cm / ns) = ns
90  } else {
91  val = -1.;
92  }
93  }
94 
95  //loop on all entries to store in 3D the ionization for each FANGS
96  for (const auto& FANGSSimHit : FANGSSimHits) {
97 
98  const int lad = FANGSSimHit.getLadder();
99  const int sen = FANGSSimHit.getSensor();
100  const int detNb = (lad - 1) * 5 + sen - 1;
101  const TVector3 simHitPosition = FANGSSimHit.getLocalPosEntry();
102  const double edep = FANGSSimHit.getEnergyDep() * 1e9; //GeV to eV
103 
104  const TVector3 chipPosition(//cm
105  simHitPosition.X(),
106  simHitPosition.Z(),
107  simHitPosition.Y() + m_sensor_width / 2.);
108 
109  //If new detector filled the chip
110  if (olddetNb != detNb && m_dchip_map.size() > 0) {
111  Pixelization();
112  olddetNb = detNb;
113  m_dchip_map.clear();
114  m_dchip.clear();
115  m_dchip_detNb_map.clear();
116  m_dchip_pdg_map.clear();
117  m_dchip_trkID_map.clear();
118  }
119 
120  // There is some issue with these cuts! please check, remove for now!
121  //check if ionization within sensitive volume
122  /*if ((-m_ChipColumnX < chipPosition.X() && chipPosition.X() < m_ChipColumnX) &&
123  (-m_ChipRowY < chipPosition.Y() && chipPosition.Y() < m_ChipRowY) &&
124  (0. < chipPosition.Z() && chipPosition.Z() < m_sensor_width) &&
125  (m_lowerTimingCut < T0[detNb] && T0[detNb] < m_upperTimingCut)) {*/
126  if (1) {
127 
128  if (edep < m_Workfct) break;
130  // check if enough energy to ionize
131  else if (edep > m_Workfct) {
132 
133  const double meanEl = edep / m_Workfct;
134  const double sigma = sqrt(m_Fanofac * meanEl);
135  const int NbEle = (int)gRandom->Gaus(meanEl, sigma);
136 
137  int col = (int)((chipPosition.X() + m_ChipColumnX) / (2. * m_ChipColumnX / (double)m_ChipColumnNb));
138  int row = (int)((chipPosition.Y() + m_ChipRowY) / (2. * m_ChipRowY / (double)m_ChipRowNb));
139  int pix = col + m_ChipColumnNb * row;
140  int quT = gRandom->Uniform(-1, 1);
141  int bci = (int)((chipPosition.Z() / m_v_sensor - T0[detNb]) / (double)m_PixelTimeBin) + quT;
142  if (bci < 0)bci = 0;
143 
144  //check if amplified drifted electron are within pixel boundaries
145  if ((0 <= col && col < m_ChipColumnNb) &&
146  (0 <= row && row < m_ChipRowNb) &&
147  (0 <= pix && pix < m_ChipColumnNb * m_ChipRowNb) &&
148  (0 <= bci && bci < MAXtSIZE)) {
149  //store info into 3D array for each FANGSs
150  m_dchip_map[std::tuple<int, int>(col, row)] = 1;
151  m_dchip_detNb_map[std::tuple<int, int>(col, row)] = detNb;
152  m_dchip_pdg_map[std::tuple<int, int>(col, row)] = FANGSSimHit.getPDG();
153  m_dchip_trkID_map[std::tuple<int, int>(col, row)] = FANGSSimHit.gettrkID();
154  m_dchip[std::tuple<int, int, int>(col, row, bci)] += (int)(NbEle);
155  }
156  }
157  }
158  }
159 
160  if (m_dchip_map.size() > 0) Pixelization();
161  m_dchip_map.clear();
162  m_dchip.clear();
163  m_dchip_detNb_map.clear();
164  m_dchip_pdg_map.clear();
165  m_dchip_trkID_map.clear();
166 }
167 
169 {
170  std::vector<int> t0;
171  std::vector<int> col;
172  std::vector<int> row;
173  std::vector<int> ToT;
174  std::vector<int> bci;
175 
176  StoreArray<FANGSHit> FANGSHits;
177 
178  for (auto& keyValuePair : m_dchip_map) {
179  const auto& key = keyValuePair.first;
180  //column
181  int i = std::get<0>(key);
182  //raw
183  int j = std::get<1>(key);
184 
185  if (m_dchip_map[std::tuple<int, int>(i, j)] == 1) {
186 
187  int k0 = 1e9;
188  const int quE = gRandom->Uniform(0, 2);
189  const double thresEl = m_PixelThreshold + gRandom->Uniform(-1.*m_PixelThresholdRMS, 1.*m_PixelThresholdRMS);
190  int kcounter = 0;
191  //determined t0 ie first time above pixel threshold
192  for (auto& keyValuePair2 : m_dchip) {
193  const auto& key2 = keyValuePair2.first;
194  int k = std::get<2>(key2);
195  if (m_dchip[std::tuple<int, int, int>(i, j, k)] > thresEl) {
196  if (k0 > k)k0 = k;
197  kcounter ++;
198  }
199  }
200  //determined nb of bc per pixel
201  //if good t0
202  if (k0 != 1e9) {
203  int ik = 0;
204  int NbOfEl = 0;
205  for (auto& keyValuePair2 : m_dchip) {
206  const auto& key2 = keyValuePair2.first;
207  int k = std::get<2>(key2);
208  //sum up charge with 16 cycles
209  if (ik < 16) {
210  NbOfEl += m_dchip[std::tuple<int, int, int>(i, j, k)];
211  } else {
212  //calculate ToT
213  int tot = -1;
214  if (NbOfEl > thresEl && NbOfEl <= 45.*m_TOTQ1) {
215  tot = (int)fctToT_Calib1->Eval((double)NbOfEl) + quE;
216  } else if (NbOfEl > 45.*m_TOTQ1 && NbOfEl <= 900.*m_TOTQ1) {
217  tot = (int)fctToT_Calib2->Eval((double)NbOfEl);
218  } else if (NbOfEl > 800.*m_TOTQ1) {
219  tot = 14;
220  }
221  if (tot > 13) {
222  tot = 14;
223  }
224  if (tot >= 0) {
225  ToT.push_back(tot);
226  t0.push_back(k0);
227  col.push_back(i);
228  row.push_back(j);
229  bci.push_back(k0);
230  }
231  ik = 0;
232  NbOfEl = 0;
233  }
234  ik++;
235  }
236 
237  if (kcounter < 16) {
238  //calculate ToT
239  int tot = -1;
240  if (NbOfEl > thresEl && NbOfEl <= 45.*m_TOTQ1) {
241  tot = (int)fctToT_Calib1->Eval((double)NbOfEl) + quE;
242  } else if (NbOfEl > 45.*m_TOTQ1 && NbOfEl <= 900.*m_TOTQ1) {
243  tot = (int)fctToT_Calib2->Eval((double)NbOfEl);
244  } else if (NbOfEl > 800.*m_TOTQ1) {
245  tot = 14;
246  }
247  if (tot > 13) {
248  tot = 14;
249  }
250  if (tot >= 0) {
251  ToT.push_back(tot);
252  t0.push_back(k0);
253  col.push_back(i);
254  row.push_back(j);
255  bci.push_back(k0);
256  }
257  }
258 
259  }
260  } //end loop on row
261  } // end loop on col
262 
263  //bool PixHit = false;
264  //if entry
265  if (bci.size() > 0) {
266  //PixHit = true;
267  //find start time
268  sort(t0.begin(), t0.end());
269 
270  //loop on nb of hit
271  for (int j = 0; j < (int)bci.size(); j++) {
272  if ((bci[j] - t0[0]) > (m_PixelTimeBinNb - 1)) {
273  continue;
274  }
275  //create FANGSHit
276  FANGSHits.appendNew(FANGSHit(col[j], row[j], bci[j] - t0[0], ToT[j],
277  m_dchip_detNb_map[std::tuple<int, int>(col[j], row[j])],
278  m_dchip_pdg_map[std::tuple<int, int>(col[j], row[j])],
279  m_dchip_trkID_map[std::tuple<int, int>(col[j], row[j])]));
280  } //end if entry
281  }
282  //return PixHit;
283 }
284 //read tube centers, impulse response, and garfield drift data filename from FANGS.xml
286 {
287  //const GearDir& content;
288  GearDir content = GearDir("/Detector/DetectorComponent[@name=\"FANGS\"]/Content/");
289 
290  //get the location of the tubes
291 
292  m_PixelThreshold = content.getInt("PixelThreshold");
293  m_PixelThresholdRMS = content.getInt("PixelThresholdRMS");
294  m_PixelTimeBinNb = content.getInt("PixelTimeBinNb");
295  m_PixelTimeBin = content.getDouble("PixelTimeBin");
296  m_ChipColumnNb = content.getInt("ChipColumnNb");
297  m_ChipRowNb = content.getInt("ChipRowNb");
298  m_ChipColumnX = content.getDouble("ChipColumnX");
299  m_ChipRowY = content.getDouble("ChipRowY");
300  m_TOTA1 = content.getDouble("TOTA1");
301  m_TOTB1 = content.getDouble("TOTB1");
302  m_TOTC1 = content.getDouble("TOTC1");
303  m_TOTQ1 = content.getDouble("TOTQ1");
304  m_TOTA2 = content.getDouble("TOTA2");
305  m_TOTB2 = content.getDouble("TOTB2");
306  m_TOTC2 = content.getDouble("TOTC2");
307  m_TOTQ2 = content.getDouble("TOTQ2");
308  m_v_sensor = content.getDouble("v_sensor");
309  m_sensor_width = content.getDouble("sensor_width");
310  m_Workfct = content.getDouble("Workfct");
311  m_Fanofac = content.getDouble("Fanofac");
312 
313  B2INFO("FANGSDigitizer: Aquired FANGS locations and gas parameters");
314  B2INFO(" from FANGS.xml. There are " << m_nFANGS << " FANGSs implemented");
315 
316 }
317 
319 {
320 }
321 
323 {
324 }
325 
326 
ClassFANGSHit - digitization simulated hit for the FANGS detector.
Definition: FANGSHit.h:26
Class FANGSSimHit - Geant4 simulated hit for the FANGS detector.
Definition: FANGSSimHit.h:28
float getEnergyDep() const
Return the energy deposition in electrons.
Definition: FANGSSimHit.h:76
int getLadder() const
Return the Ladder number (starting at 1, increasing with phi)
Definition: FANGSSimHit.h:68
int getSensor() const
Return the Sensor number (starting at 1, increasing with decreasing z)
Definition: FANGSSimHit.h:70
int getPDG() const
Return the PDG number of the track.
Definition: FANGSSimHit.h:72
int gettrkID() const
Return track ID.
Definition: FANGSSimHit.h:66
TVector3 getLocalPosEntry() const
Return the local entry track position.
Definition: FANGSSimHit.h:80
GearDir is the basic class used for accessing the parameter store.
Definition: GearDir.h:31
Base class for Modules.
Definition: Module.h:72
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
Accessor to arrays stored in the data store.
Definition: StoreArray.h:113
T * appendNew()
Construct a new T object at the end of the array.
Definition: StoreArray.h:246
double m_ChipRowY
Chip row y dimension.
std::map< std::tuple< int, int >, int > m_dchip_pdg_map
chip pdg map arrays
std::map< std::tuple< int, int >, int > m_dchip_trkID_map
chip track ID map arrays
virtual void initialize() override
Initialize the Module.
TF1 * fctToT_Calib1
Define ToT calib 1.
StoreArray< FANGSHit > m_fangsHit
array for FANGSHit
virtual void event() override
This method is the core of the module.
virtual void endRun() override
This method is called if the current run ends.
double m_ChipColumnX
Chip column x dimension.
void getXMLData()
reads data from MICROFANGS.xml: tube location, drift data filename, sigma of impulse response functio...
virtual void terminate() override
This method is called at the end of the event processing.
double m_v_sensor
Drift velocity in sensor.
std::map< std::tuple< int, int, int >, int > m_dchip
chip store arrays
TF1 * fctToT_Calib2
Define ToT calib 2.
std::map< std::tuple< int, int >, int > m_dchip_detNb_map
chip Nb map arrays
virtual void beginRun() override
Called when entering a new run.
std::map< std::tuple< int, int >, int > m_dchip_map
chip map arrays
int m_PixelTimeBinNb
Pixel time number of bin.
void Pixelization()
Produces the pixelization.
int m_PixelThresholdRMS
Pixel threshold RMS.
FANGSDigitizerModule()
Constructor: Sets the description, the properties and the parameters of the module.
REG_MODULE(arichBtest)
Register the Module.
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:560
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
Abstract base class for different kinds of events.