Belle II Software  release-08-01-10
CsIDigitizerModule.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 <beast/csi/modules/CsIDigitizerModule.h>
11 
12 // Beast headers
13 #include <beast/csi/geometry/CsiGeometryPar.h>
14 
15 // Basf2 headers
16 #include <framework/core/RandomNumbers.h>
17 #include <framework/dataobjects/EventMetaData.h>
18 #include <framework/datastore/StoreObjPtr.h>
19 
20 // ROOT headers
21 #include <TGraph.h>
22 #include <TH1F.h>
23 #include <TH1I.h>
24 #include <TVector3.h>
25 
26 // C++ headers
27 #include <math.h>
28 #include <vector>
29 
30 using namespace std;
31 using namespace Belle2;
32 using namespace csi;
33 //-----------------------------------------------------------------
34 // Register the Module
35 //-----------------------------------------------------------------
36 REG_MODULE(CsIDigitizer);
37 
38 //-----------------------------------------------------------------
39 // Implementation
40 //-----------------------------------------------------------------
41 
42 //Calibration constants (hard-coded for now, put in the xml file for later)
43 CsIDigitizerModule::CsIDigitizerModule() : Module(), m_hitNum(0),
44  m_TrueEdep(0.0),
45  m_nWFcounter(0),
46  m_aDigiHit("CsiDigiHits"),
47  m_calibConstants(16, 5),
48  m_noiseLevels(16, 0.25e-3),
49  m_LY(16, 40e6),
50  m_tRatio(16, 0),
51  m_tFast(16, 1),
52  m_tSlow(16, 1),
53  m_LCE(16, 0.1),
54  m_PmtQE(16, 0.05),
55  m_PmtGain(16, 1e5)
56 {
57  // Set module properties
58  setDescription("Digitizer for the BEAST CsI system");
59 
60  // Parameter definitions
61  addParam("Resolution", m_Resolution, "Resolution (in mV) of the ACD", 4.8828e-4);
62  addParam("SampleRate", m_SampleRate, "Sample rate (in samples/sec) of the ADC", 250e6);
63  addParam("nWaveforms", m_nWaveforms, "Number of waveforms to save. 0: none, -1: all ", 0);
64 }
65 
67 {
68 }
69 
71 {
72 
73  B2DEBUG(100, "Initializing ");
74 
75  m_aSimHit.isRequired();
76  m_aDigiHit.registerInDataStore();
77 
78  //Calculation of the derived parameters
79  m_dt = 1e9 / m_SampleRate;
80  setnSamples(8192);
81 
82  //Get crystal and PMT constants from xml files
84  for (uint i = 0; i != m_LY.size(); ++i) {
85  csip->Print(i, 80);
86 
87  m_LY.at(i) = 1;//1e3 * csip->GetMaterialProperty(i, "SCINTILLATIONYIELD");
88  m_tFast.at(i) = 1;//csip->GetMaterialProperty(i, "FASTTIMECONSTANT");
89  m_tSlow.at(i) = 1;//csip->GetMaterialProperty(i, "SLOWTIMECONSTANT");
90  m_tRatio.at(i) = 1;//csip->GetMaterialProperty(i, "YIELDRATIO");
91  }
92 
93  //Operate the pure CsI at higher gain to compensate for lower light yield
94  for (int i = 8; i < 16; i++) {
95  m_PmtGain[i] = 35e5;
96  }
97 
98 }
99 
101 {
102  //Signal tempo = genTimeSignal(10, 10, 2, 0, 1);
103 }
104 
106 {
107  StoreObjPtr<EventMetaData> eventMetaDataPtr;
108  int m_currentEventNumber = eventMetaDataPtr->getEvent();
109 
110  B2DEBUG(80, "Digitingevent " << m_currentEventNumber);
111 
112  //Loop over CsiSimHits
113  if (m_aSimHit.getEntries() > 0) {
114  int hitNum = m_aSimHit.getEntries();
116  // double E_tmp[16] = {0}; /**< Sum energy deposited in each cell */
117  // double edepSum = 0; /**< Sum energy deposited in all cells */
118 
119  for (int i = 0 ; i < 16 ; i++) {
120  m_SimHitTimes[i].clear();
121  m_SimHitEdeps[i].clear();
122  }
123 
124 
125  B2DEBUG(150, "Looping over CsISimHits");
126  for (int i = 0; i < hitNum; i++) { // Loop over CsISimHits
127  CsiSimHit* aCsISimHit = m_aSimHit[i];
128  int m_cellID = aCsISimHit->getCellId();
129  double edep = aCsISimHit->getEnergyDep();
130  double tof = aCsISimHit->getFlightTime();
131  // double hitTime = aCsISimHit->getTimeAve(); /**< Time average of the hit*/
132  // double hitTimeRMS = sqrt( aCsISimHit->getTimeVar()/aCsISimHit->getEnergyDep()); /**< Time rms of the hit*/
134 
135  TVector3 hitPos = aCsISimHit->getPosition();
136  TVector3 cellPos = csip->GetPositionTV3(m_cellID);
137  TVector3 cellAngle = csip->GetOrientationTV3(m_cellID);
138 
139  double localPos = (15. - (hitPos - cellPos) *
140  cellAngle);
142  // 0.06 is the speed of light in CsI(Tl)
143  double propagTime = m_SampleRate *
144  (0.0600 * localPos + (tof / CLHEP::ns)) * 1E-9;
147  m_SimHitTimes[m_cellID].push_back(propagTime);
148  m_SimHitEdeps[m_cellID].push_back(edep);
149 
150  /*
151  if (i<10){
152  B2INFO("Hit No = : " << i );
153  B2INFO("Deposited energy = : " << edep );
154  B2INFO("Average time = : " << hitTime );
155  B2INFO("Time RMS = : " << hitTimeRMS );
156 
157  csip->Print(m_cellID);
158  }
159  */
160 
161  }
162 
163  for (int iCh = 0; iCh < 16; iCh++) {
164 
165  int n = m_SimHitTimes[iCh].size();
166 
167  if (n > 0) {
168 
169  B2DEBUG(140, "Generating Time signal");
170  Signal tempSignal;
171  m_TrueEdep = genTimeSignal(&tempSignal, m_SimHitEdeps[iCh], m_SimHitTimes[iCh], iCh, m_dt, m_nSamples, false);
172 
173 
174  B2DEBUG(140, "Launching Charge integration");
175  bool recordWaveform = false;
176  if ((m_nWaveforms == -1) || (m_nWFcounter < m_nWaveforms)) {
177  m_nWFcounter++;
178  recordWaveform = true;
179  B2DEBUG(80, "Recording WF");
180  }
181  uint16_t max = doChargeIntegration(tempSignal, 128, &m_Baseline, &m_Charge, &m_Time, &m_Waveform,
182  &m_DPPCIBits, 5, 1.2e4, 1e4, 1e3, recordWaveform);
183 
184  if (m_Charge > 0) {
185  m_aDigiHit.appendNew();
186  m_hitNum = m_aDigiHit.getEntries() - 1;
187  m_aDigiHit[m_hitNum]->setCellId(iCh);
188  m_aDigiHit[m_hitNum]->setCharge(m_Charge);
189  m_aDigiHit[m_hitNum]->setTime(m_Time);
190  m_aDigiHit[m_hitNum]->setBaseline(m_Baseline);
191  m_aDigiHit[m_hitNum]->setTrueEdep(m_TrueEdep);
192 
193  m_aDigiHit[m_hitNum]->setMaxVal(max);
194 
195  m_aDigiHit[m_hitNum]->setWaveform(&m_Waveform);
196  m_aDigiHit[m_hitNum]->setStatusBits(&m_DPPCIBits);
197  }
198  }
199  }
200  }
201 }
202 
203 
205 {
206 }
207 
209 {
210 }
211 
212 uint16_t CsIDigitizerModule::doChargeIntegration(Signal _u, int _NsamBL, uint16_t* _BSL, uint32_t* _Q,
213  uint32_t* _t, vector<uint16_t>* _Waveform,
214  vector<uint8_t>* _DPPCIBits, int _Treshold,
215  double _TriggerHoldoff, double _GateWidth,
216  double _GateOffset, bool _recordTraces)
217 {
218 
219  B2DEBUG(80, "Arguments: " << &_u << ", " << _NsamBL << ", " << _BSL << ", " << _Q << ", " << _t
220  << ", " << _Waveform << ", " << _Treshold << ", " << _TriggerHoldoff << ", " << _GateWidth
221  << ", " << _GateOffset << ", " << _recordTraces);
222 
223  vector<int> x = doDigitization(_u, m_Resolution);
224  int nSam = x.size();
225 
226  // Plots for debugging (see CAEN DPP-CI figs 2.2,2.3
227  TH1I h_trigger("h_trigger", "Trigger", nSam, 0, nSam - 1);
228  TH1I h_gate("h_gate", "Gate", nSam, 0, nSam - 1);
229  TH1I h_holdoff("h_holdoff", "Holdoff", nSam, 0, nSam - 1);
230  TH1I h_baseline("h_baseline", "Baseline", nSam, 0, nSam - 1);
231  TH1I h_charge("h_charge", "Charge", nSam, 0, nSam - 1);
232  TH1F h_signal("h_signal", "Continuous signal", nSam, 0, nSam - 1);
233  TH1I h_digsig("h_digsig", "Digital signal", nSam, 0, nSam - 1);
234 
235 
236  int max_gated = (int) floor(_GateWidth / m_dt);
237  int gate_offset = (int) floor(_GateOffset / m_dt);
238  int max_holdoff = (int) floor(_TriggerHoldoff / m_dt);
239 
240  int baseline = 0;
241  int charge = 0;
242  int n_holdoff = 0;
243  int n_gated = 0;
244 
245  bool gate = false;
246  bool holdoff = false;
247  bool stop = false;
248  bool trigger = false;
249 
250  // Find trigger position
251  int i = 0;
252  int iFirstTrigger = 0;
253  list<int> baselineBuffer;
254  vector<int>::iterator it;
255  float tempBaseline;
256 
257  // Saving inverse number of samples used for baseline averaging (avoid division)
258  const double invMaxNavgBL = 1.0 / _NsamBL;
259  double invNavgBL;
261  _Waveform->resize(nSam, 0);
262  _DPPCIBits->resize(nSam, 0);
263 
264  B2DEBUG(140, "Scanning vector: all should have nSam=" << nSam);
265 
266  uint16_t maxval = 0;
267 
268  for (it = x.begin(); (it != x.end()); ++it, ++i) {
269 
270  if (*it > maxval)
271  maxval = *it;
272 
273  _Waveform->at(i) = *it;
274  _DPPCIBits->at(i) = trigger + (gate << 1) + (holdoff << 2) + (stop << 3);
275 
276  if (_recordTraces) {
277 
278  h_trigger.Fill(i, (int) trigger) ;
279  h_gate.Fill(i, (int) gate) ;
280  h_holdoff.Fill(i, (int) holdoff) ;
281  h_baseline.Fill(i, baseline) ;
282  h_charge.Fill(i, charge) ;
283  h_digsig.Fill(i, *it) ;
284  h_signal.Fill(i, _u.at(i)) ;
285  }
286 
287  if (!gate && !holdoff) {
288 
289  baselineBuffer.push_back(*it);
290 
291 
292  if ((i + 1) > _NsamBL) {
293  baselineBuffer.pop_front();
294  invNavgBL = invMaxNavgBL;
295  } else {
296  invNavgBL = (1.0 / i);
297  }
298 
299  tempBaseline = 0;
300  for (list<int>::iterator itbl = baselineBuffer.begin(); itbl != baselineBuffer.end(); ++itbl)
301  tempBaseline += (float) * itbl;
302 
303  tempBaseline *= invNavgBL;
304 
305  baseline = (int) round(tempBaseline);
306 
307  trigger = (*it - baseline) > _Treshold;
308 
309  //first time we see a trigger
310  if (trigger && !iFirstTrigger)
311  iFirstTrigger = i;
312 
313  } else {
314 
315  if (gate) {
316  charge += (*(it - gate_offset) - baseline);
317  *_BSL = baseline;
318  n_gated++;
319  }
320 
321  if (holdoff) {
322  n_holdoff++;
323  }
324 
325  trigger = false;
326  }
327 
328  holdoff = trigger || (holdoff && (n_holdoff < max_holdoff));
329  gate = trigger || (gate && (n_gated < max_gated));
330 
331  stop = iFirstTrigger && !gate && !holdoff;
332  }
333 
334  *_Q = charge;
335  // from the doc: 2 sample uncertainty.
336  *_t = (uint)(iFirstTrigger + 2.0 * (gRandom->Rndm() - 0.5));
337 
338  if (not(_recordTraces)) {
339  _Waveform->clear();
340  _DPPCIBits->clear();
341  }
342 
343  return maxval;
344 }
345 
346 vector<int> CsIDigitizerModule::doDigitization(Signal _v, double _LSB)
347 {
348  vector<int> output(_v.size(), 0);
349  double invLSB = 1.0 / _LSB;
350 
351  int i = 0;
352  for (Signal::iterator it = _v.begin() ; it != _v.end(); ++it, ++i) {
353  output.at(i) = (int) round(*it * invLSB);
354  }
355 
356  return output;
357 }
358 
359 double CsIDigitizerModule::genTimeSignal(Signal* _output, Signal _energies, Signal _times, int _iChannel, int _dt, int _nsam,
360  bool _save)
361 {
362 
363  double invdt = 1.0 / _dt;
364 
365  double tf = 0;
366  double t0 = 1e9;
367  double sumEnergies = 0.0;
368 
369  for (Signal::iterator it = _times.begin() ; it != _times.end(); ++it) {
370  if (*it < t0)
371  t0 = *it;
372 
373  if (*it > tf)
374  tf = *it;
375  }
376 
377  Signal edepos(_nsam, 0.0);
378 
379  int i = 0;
380  int ioffset = floor(_nsam * 0.25);
381  B2DEBUG(150, "Filling edepos vector. Container length is " << _nsam);
382 
383  for (Signal::iterator it = _times.begin() ; it != _times.end(); ++it, ++i) {
384  sumEnergies += _energies.at(i);
385  // time index +/- 1 time bin
386  int timeIndex = ((int)(*it - t0) * invdt + ioffset);
387  if ((timeIndex - 1) > (int) edepos.size()) {
388  B2WARNING(" genTimeSignal: TimeIndex greater than length of signal container. Skipping deposit of " << _energies.at(i) << "GeV");
389  } else {
390  edepos.at(timeIndex) += _energies.at(i);
391  }
392  }
393 
394  B2DEBUG(80, "Generating time responses for channel " << _iChannel);
395  B2DEBUG(80, " Fast time constant " << m_tFast[_iChannel]);
396  B2DEBUG(80, " Slow time constant " << m_tSlow[_iChannel]);
397  /*
398  Signal Qcathode = firstOrderResponse(m_LY[_iChannel] * m_LCE[_iChannel] * m_PmtQE[_iChannel],
399  edepos, 0, _dt, m_tSlow[_iChannel], 0.0, m_tRatio[_iChannel], m_tFast[_iChannel]);
400  */
401 
402  Signal Qcathode = firstOrderResponse((1 - m_tRatio[_iChannel]) * m_LY[_iChannel] * m_LCE[_iChannel] * m_PmtQE[_iChannel], edepos, 0,
403  _dt, m_tSlow[_iChannel], 0.0);
404 
405 
406  if (m_tRatio[_iChannel]) {
407  Signal QcathodeF = firstOrderResponse(m_tRatio[_iChannel] * m_LY[_iChannel] * m_LCE[_iChannel] * m_PmtQE[_iChannel], edepos, 0, _dt,
408  m_tFast[_iChannel], 0.0);
409 
410  int j = 0;
411  for (Signal::iterator it = Qcathode.begin() ; it != Qcathode.end(); ++it, ++j)
412  *it += QcathodeF.at(j);
413  }
414 
415  Signal Vanode = firstOrderResponse(1.602e-10 * m_Zl * invdt * m_PmtGain[_iChannel], Qcathode, 0, _dt, m_tRisePMT, m_tTransitPMT);
416 
417  B2DEBUG(150, "Adding noise. Container length is " << Vanode.size());
418  addNoise(&Vanode, m_noiseLevels[_iChannel], 5e-3 * gRandom->Rndm() + 1e-2);
419 
420  if (_save) {
421  Signal t(_nsam, 0);
422  t.at(0) = t0;
423 
424  for (i = 1; i < _nsam; i++)
425  t.at(i) = t.at(i - 1) + _dt;
426 
427  TGraph gPlot1(_nsam, &t[0], &edepos[0]);
428  gPlot1.SaveAs("EdeposOut.root");
429 
430  TGraph gPlot2(_nsam, &t[0], &Qcathode[0]);
431  gPlot2.SaveAs("QOut.root");
432 
433  TGraph gPlot3(_nsam, &t[0], &Vanode[0]);
434  gPlot3.SaveAs("VOut.root");
435  }
436 
437  *_output = Vanode;
438 
439  return sumEnergies;
440 }
441 
442 
443 int CsIDigitizerModule::addNoise(Signal* y, double _rms, double _offset)
444 {
445  for (Signal::iterator it = y->begin() ; it != y->end(); ++it)
446  *it += _offset + gRandom->Gaus(0, _rms);
447 
448  return y->size();
449 }
450 
451 /*
452 Signal CsIDigitizerModule::firstOrderResponse(double _gain, Signal _u, double _y0, double _dt, double _tSlow, double _delay, double _tRatio, double _tFast)
453 {
454 
455  Signal slowLight = firstOrderResponse(_gain*(1-_tRatio), _u, _y0, _dt, _tFast, _delay);
456 
457  if (_tRatio>0) {
458  Signal fastLight = firstOrderResponse(_gain* _tRatio , _u, _y0, _dt, _tFast, _delay);
459  int i=0;
460  for (Signal::iterator it = slowLight.begin() ; it != slowLight.end(); ++it, ++i)
461  *it += fastLight.at(i);
462  }
463  B2WARNING("You shouldn't see this!");
464  return slowLight;
465 
466 }
467 */
468 
469 Signal CsIDigitizerModule::firstOrderResponse(double _gain, Signal _u, double _y0, double _dt, double _tau, double _delay)
470 {
471 
472  B2DEBUG(80, "Generating 1st order response with arguments");
473  B2DEBUG(80, " _gain: " << _gain);
474  B2DEBUG(80, " length(_u): " << _u.size());
475  B2DEBUG(80, " _y0: " << _y0);
476  B2DEBUG(80, " _dt: " << _dt);
477  B2DEBUG(80, " _tau: " << _tau);
478  B2DEBUG(80, " _delay: " << _delay);
479 
480 
481  // First skip everything if the time constant in infinitely short.
482  if (_tau == 0)
483  return _u;
484 
485  int n = _u.size();
486  Signal y;
487  double k[4] = {0};
488 
489  static const double invSix = 1.0 / 6.0;
490  double invtau = 1.0 / _tau;
491  y.push_back(_y0);
492 
493  // Apply delay to input
494  int n_delay = (int) round(_delay / _dt);
495  Signal::iterator it = _u.begin();
496  double _u_0 = _u.front();
497  _u.insert(it, n_delay, _u_0);
498  _u.resize(n);
499 
500  // Apply that input to the good old Runge-Kutta 4 routine.
501  for (int i = 0, j = 0; i < (n - 1); i++) {
502  j = i + 1;
503  k[0] = f(i, _u[i], _u[j], y[i], invtau);
504  k[1] = f(i + 0.5, _u[i], _u[j], y[i] + 0.5 * _dt * k[0], invtau);
505  k[2] = f(i + 0.5, _u[i], _u[j], y[i] + 0.5 * _dt * k[1], invtau);
506  k[3] = f(j, _u[i], _u[j], y[i] + _dt * k[2], invtau);
507 
508  y.push_back(y[i] + _dt * invSix * (k[0] + 2 * k[1] + 2 * k[2] + k[3]));
509  }
510 
511 
512  // Apply gain
513  if (_gain != 1) {
514  for (Signal::iterator it2 = y.begin() ; it2 != y.end(); ++it2)
515  *it2 *= _gain;
516  }
517 
518  return y;
519 }
520 
521 
522 double CsIDigitizerModule::f(double fi, double u_i, double u_j, double y, double invtau)
523 {
524  //linear interpolation of the input at fractional index fi
525  double u = u_i * (fi - floor(fi)) + u_j * (ceil(fi) - fi);
526 
527  return u - invtau * y;
528 }
529 
R E
internal precision of FFTW codelets
ClassCsiSimHit - Geant4 simulated hits in CsI crystals in BEAST.
Definition: CsiSimHit.h:31
int getCellId() const
Get Cell ID.
Definition: CsiSimHit.h:87
double getFlightTime() const
Get Flight time from IP.
Definition: CsiSimHit.h:102
double getEnergyDep() const
Get Deposit energy.
Definition: CsiSimHit.h:107
TVector3 getPosition() const
Get Position.
Definition: CsiSimHit.h:122
Base class for Modules.
Definition: Module.h:72
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
Type-safe access to single objects in the data store.
Definition: StoreObjPtr.h:96
uint16_t m_Baseline
Baseline (pedestal) frozen during charge integration.
int addNoise(Signal *y, double _rms, double _offset)
Adds noise to the signal.
Signal m_SimHitEdeps[16]
Array of signals (each corresponding to one channel)
double m_Resolution
Parameter: Resolution (in mV) of the ACD.
DigitalSignal doDigitization(Signal _v, double _LSB)
Digitizes the signal the signal.
double m_TrueEdep
Sum of the MC (true) deposited energies in the event-channel.
std::vector< double > m_noiseLevels
Noise level for each channel (in V)
std::vector< uint16_t > m_Waveform
Saved waveform.
virtual void initialize() override
Register input and output data.
double f(double fi, double u_i, double u_j, double y, double invtau)
This returns the RHS of first order differential equation.
const double m_Zl
Line impedance of the analog chain (to get voltage from anode current)
virtual void event() override
Each event This is where the actual digitization is done, and the hits are written to the DataStore.
Signal firstOrderResponse(double _gain, Signal _u, double _y0, double _dt, double _tSlow, double _delay)
Calculates the time response of a first order system (such as crystal, PMT, etc)
virtual void endRun() override
Clean up.
Signal genTimeSignal(double _energy, double _timeAvg, double _timeRMS, int iChannel, bool _save=0)
Generates a time signal for a mean energy deposit The energy deposit is modelled at a Gaussian whose ...
StoreArray< CsiSimHit > m_aSimHit
Each simulated particle in the crystal.
int m_nWFcounter
Counter for the number of waveforms to save.
virtual void terminate() override
Final clean up.
double m_dt
Time interval (in ns) (calculated from m_SampleRate.
std::vector< double > m_LCE
Light collection efficiency for each channel.
void setnSamples(int nsamples)
Sets the number of points in the waveforms arrays.
const double m_tTransitPMT
48Mean transit time of the PMT signal (in ns)
std::vector< double > m_LY
Light yield for each channel (gamma per GeV)
int m_nSamples
Number of points requested in the waveform arrays.
virtual ~CsIDigitizerModule()
Default destructor.
virtual void beginRun() override
To do before each runs.
std::vector< double > m_PmtGain
PMT gain for each channel.
std::vector< double > m_PmtQE
PMT quantum efficiency for each channel.
std::vector< uint8_t > m_DPPCIBits
status of the DPP-CI
const double m_tRisePMT
2.6 Rise time of the PMT signal (in ns)
std::vector< double > m_tSlow
Slow time constant for each channel (ns)
std::vector< double > m_tRatio
Ratio fast light / slow light for each channel.
StoreArray< CsiDigiHit > m_aDigiHit
Output: a digitized hit.
uint16_t doChargeIntegration(Signal _u, int _NsamBL, uint16_t *BSL, uint32_t *Q, uint32_t *t, std::vector< uint16_t > *_Waveform, std::vector< uint8_t > *_DPPCIBits, int _Treshold, double _TriggerHoldoff=0.0, double _GateWidth=320.0, double _GateOffset=40.0, bool _recordTraces=false)
Realizes the charge integration of the input signal.
double m_SampleRate
Parameter: Sample rate (in samples/sec) of the ADC.
int m_nWaveforms
Number of waveforms to save.
Signal m_SimHitTimes[16]
Array of signals (each corresponding to one channel)
uint32_t m_Charge
Integrated Charge.
std::vector< double > m_tFast
Fast time constant for each channel (ns)
The Class for CSI Geometry Parameters.
void Print(const int cid, int debuglevel=80)
Print crystal information.
TVector3 GetOrientationTV3(int cid)
Get the orientation of the crystal in a root TVector3.
static CsiGeometryPar * Instance()
Static method to get a reference to the CsiGeometryPar instance.
TVector3 GetPositionTV3(int cid)
Get the position of the crystal in a root TVector3.
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
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
std::vector< double > Signal
Designed to hold a "continuous" (in time and amplitude) signal
Abstract base class for different kinds of events.