FdElectronicsSimulator.cc
Go to the documentation of this file.
1 
13 #include <iostream>
14 #include <iomanip>
15 #include <string>
16 
17 #include <utl/Reader.h>
18 #include <utl/ErrorLogger.h>
19 #include <utl/AugerUnits.h>
20 #include <utl/MathConstants.h>
21 #include <utl/Math.h>
22 #include <utl/PhysicalConstants.h>
23 #include <utl/RandomEngine.h>
24 #include <utl/TabulatedFunction.h>
25 #include <utl/TabulatedFunctionErrors.h>
26 #include <utl/Trace.h>
27 #include <utl/TraceAlgorithm.h>
28 #include <utl/MultiTabulatedFunction.h>
29 #include <utl/AugerException.h>
30 #include <utl/Md5Signature.h>
31 
32 #include <fwk/CentralConfig.h>
33 #include <fwk/RandomEngineRegistry.h>
34 
35 #include <det/Detector.h>
36 #include <fdet/FDetector.h>
37 #include <fdet/Eye.h>
38 #include <fdet/Telescope.h>
39 #include <fdet/Channel.h>
40 #include <fdet/Pixel.h>
41 #include <fdet/Mirror.h>
42 #include <fdet/Filter.h>
43 #include <fdet/Camera.h>
44 
45 #include <evt/Event.h>
46 
47 #include <fevt/FEvent.h>
48 #include <fevt/Eye.h>
49 #include <fevt/Telescope.h>
50 #include <fevt/TelescopeSimData.h>
51 #include <fevt/PixelSimData.h>
52 #include <fevt/Pixel.h>
53 #include <fevt/ChannelSimData.h>
54 #include <fevt/Channel.h>
55 
56 #include <CLHEP/Random/RandPoisson.h>
57 #include <CLHEP/Random/RandGauss.h>
58 
59 #include "FdElectronicsSimulator.h"
60 
61 using namespace FdElectronicsSimulatorOG;
62 using namespace std;
63 using namespace utl;
64 using namespace evt;
65 using namespace fwk;
66 using namespace det;
67 using namespace fevt;
68 using namespace fdet;
69 
70 
71 using CLHEP::RandGauss;
72 using CLHEP::RandPoisson;
73 
74 
76  fVerbosityLevel(0),
77  fBaseline(0),
78  fUseMonitoring(false),
79  fThresholdBoxCarReducedInMon(true),
80  fUseNewThreshold(false),
81  fThresholdMode(false),
82  fRandomEngine(0)
83 {
84 }
85 
87 {
88 }
89 
92 {
93  CentralConfig* cc = CentralConfig::GetInstance();
94  Branch topB = cc->GetTopBranch("FdElectronicsSimulator");
95 
97  &RandomEngineRegistry::GetInstance().Get(RandomEngineRegistry::eDetector);
98 
99  fVerbosityLevel = 0;
100  if (topB.GetChild("verbosityLevel"))
101  topB.GetChild("verbosityLevel").GetData(fVerbosityLevel);
102 
103  fPeFluctuations = true;
104  if (topB.GetChild("NoPeFluctuations")) {
105  topB.GetChild("NoPeFluctuations").GetData(fPeFluctuations);
107  }
108 
109  fDoAntiAliasingFilter = true;
110  if (topB.GetChild("NoAntiAliasingFilter")) {
111  topB.GetChild("NoAntiAliasingFilter").GetData(fDoAntiAliasingFilter);
113  }
114 
115  if (topB.GetChild("thresholdMode")) {
116  topB.GetChild("thresholdMode").GetData(fThresholdMode);
117  }
118 
119  if (topB.GetChild("useNewThreshold"))
120  topB.GetChild("useNewThreshold").GetData(fUseNewThreshold);
121 
122  if (fUseNewThreshold){
123  Branch topBThreshold = cc->GetTopBranch("FSimulationThreshold");
124  Branch it = topBThreshold.GetFirstChild();
125  while (it){
126  TabulatedFunction thresholdValues;
127  it.GetData(thresholdValues);
128  AttributeMap thresholdSignature = it.GetAttributes();
129  string configSignature = thresholdSignature.begin()->second;
130  fSimThresholdValues.insert(std::pair<string, TabulatedFunction>(configSignature, thresholdValues));
131  ++it;
132  }
133  }
134 
135  topB.GetChild("baseline").GetData(fBaseline);
136  topB.GetChild("useMonitoringInfo").GetData(fUseMonitoring);
138  if (topB.GetChild("thresholdBoxCarReducedInMon")) {
139  topB.GetChild("thresholdBoxCarReducedInMon").GetData(fThresholdBoxCarReducedInMon);
140  }
141 
142  // info output
143  ostringstream info;
144  info << " Version: "
145  << GetVersionInfo(VModule::eRevisionNumber) << "\n"
146  " Parameters:\n"
147  " baseline: " << fBaseline << "\n";
148  if (fUseMonitoring)
149  info << " use monitoring info: " << fUseMonitoring << '\n';
150  if (!fPeFluctuations)
151  info << " PE fluctuations: OFF\n";
153  info << " Anti-aliasing filer: OFF\n";
154  if (fVerbosityLevel)
155  info << " verbosity level: " << fVerbosityLevel << '\n';
156 
157  INFO(info);
158  return eSuccess;
159 }// end of Init
160 
161 
164 {
165  if (!event.HasFEvent()) {
166  ERROR ("Event has no FEvent.");
167  return eFailure;
168  }
169 
170  fDrumCalibMode = !event.HasSimShower();
171 
172  if (fDrumCalibMode) {
173  INFO ("Drum calibration mode!");
174  }
175 
176  FEvent& fEvent = event.GetFEvent();
177  for (fevt::FEvent::EyeIterator iEye =
180  ++iEye) {
181 
182  if (iEye->GetStatus()==fevt::ComponentSelector::eDeSelected)
183  continue;
184 
185  fevt::Eye& eyeEvent = *iEye;
186  bool eyeHasAtLeastOneGoodTelescope = false;
187 
188  if (fVerbosityLevel>2) {
189  ostringstream info;
190  info << " Eye=" << eyeEvent.GetId();
191  INFO(info);
192  }
193 
194  for (fevt::Eye::TelescopeIterator iTel =
197  ++iTel) {
198 
199  fevt::Telescope& telEvent = *iTel;
200 
201  if (fVerbosityLevel>2) {
202  ostringstream info;
203  info << " Eye=" << eyeEvent.GetId() << " Tel=" << telEvent.GetId();
204  INFO(info);
205  }
206 
207  for (fevt::Telescope::PixelIterator iPixel =
209  iPixel != telEvent.PixelsEnd(fevt::ComponentSelector::eInDAQ);
210  ++iPixel) {
211 
212  if (iPixel->GetStatus() == fevt::ComponentSelector::eDeSelected)
213  continue;
214 
215  if (fVerbosityLevel>2) {
216  ostringstream info;
217  info << " Eye=" << eyeEvent.GetId()
218  << " Tel=" << telEvent.GetId()
219  << " Pix=" << iPixel->GetId();
220  INFO(info);
221  }
222 
223  if (iPixel->HasSimData()) {
224 
225  // Simulate electronics only for the cameras that contain photons
226  if (InitCamera(telEvent)) {
227  ElecSim(telEvent);
228  eyeHasAtLeastOneGoodTelescope = true;
229  } else
231 
232  break;
233  }
234 
235  } // end loop over Pixels
236 
237  } // end loop over Telescopes
238 
239  if (!eyeHasAtLeastOneGoodTelescope)
241 
242  } // end loop over Eyes
243  return eSuccess;
244 } // end of Run
245 
246 
249 {
250  return eSuccess;
251 }// end of Finish
252 
253 
254 bool
256 {
257  const fdet::FDetector& detFD = Detector::GetInstance().GetFDetector();
258  const fdet::Telescope& detTel = detFD.GetTelescope(tel);
259  const fdet::Camera& detCamera = detTel.GetCamera();
260 
261  const bool hasCorrector = detTel.HasCorrectorRing();
262  bool telHasAtLeastOneValidPixel = false;
263 
264  const double normWavelength = detFD.GetReferenceLambda();
265 
266  const unsigned int nPixels = detTel.GetLastPixelId();
267  fPeBgNoiseTable.clear();
268  fCalibCorrection.clear();
269  fQEffAtNormWavelength.clear();
270 
271  // first loop to finalize the config checksum
272  map<int, double> gainOfPixel;
273  for (unsigned int pixelId=1; pixelId<=nPixels; pixelId++) {
274 
275  if (!tel.HasPixel(pixelId))
276  continue;
277 
278  fevt::Pixel& pix = tel.GetPixel(pixelId);
279  const fdet::Pixel& detPixel = detFD.GetPixel(pix);
280  const fdet::Channel& detChannel = detFD.GetChannel(pix); // mapped channel
281  const TabulatedFunction& qEff = detPixel.GetQEfficiency();
282  const double absGain = detChannel.GetElectronicsGain();
283 
284  fQEffAtNormWavelength[pixelId] = qEff.Y(normWavelength);
285  gainOfPixel[pixelId] = absGain;
286  }
287 
288  PrepareTimeConvolution(detTel);
289 
290  //GetThresholdConfigSignature
291  const string thresholdConfigSignature = detTel.GetCamera().GetThresholdConfigSignature();
292 
293  // Get the calibration constants
294  for (unsigned int pixelId=1; pixelId<=nPixels; pixelId++) {
295 
296  if (!tel.HasPixel(pixelId))
297  continue;
298 
299  fevt::Pixel& pix = tel.GetPixel(pixelId);
301  continue;
302 
303  if (!pix.HasSimData())
304  continue;
305 
306  // Get the calibration constant for this channel
307  const fdet::Pixel& detPixel = detFD.GetPixel(pix);
308  const fdet::Channel& detChannel = detFD.GetChannel(pix); // mapped channel
309 
310  // get calibration constant
311  const TabulatedFunction& calibration = detPixel.GetEndToEndCalibrationConstant();
312  if (!calibration.GetNPoints()) {
313  ostringstream errorMsg;
314  errorMsg<< "Could not find calibration for eye=" << pix.GetEyeId()
315  << " tel=" << pix.GetTelescopeId() << " pix=" << pixelId;
316  ERROR(errorMsg);
317  continue;
318  }
319 
320  // check calibration status
321  if ( detPixel.GetStatus() != fdet::Pixel::eGood ) {
322  ostringstream warn;
323  warn << " bad calibration data for eye " << pix.GetEyeId()
324  << " tel " << pix.GetTelescopeId() << " pix " << pixelId
325  << " status = " << detPixel.GetStatus();
326  warn << " setting fevt::PixelStatus to DeSelected..."<<endl;
327  WARNING(warn.str());
329  continue;
330  }
331  telHasAtLeastOneValidPixel = true;
332 
333  const double caliconst =
335  const double opticalEfficiencyCorrection =
337 
338  if (caliconst==0) {
339  ostringstream err;
340  err << "\n **************************************************************************\n"
341  << " **************************************************************************\n"
342  << " ERROR caliconst=0 of pixelId=" << pixelId
343  << " ! Cannot use telId=" << pix.GetTelescopeId() << " of eyeId=" << pix.GetEyeId() << '\n'
344  << " **************************************************************************\n"
345  << " **************************************************************************";
346  ERROR(err);
347  return false;
348  }
349 
350  // Pixel constants into arrays
351  fevt::PixelSimData& pxsimdata = pix.GetSimData();
352  const double backphotons =
355  pxsimdata.GetMeanBgPhotonFlux();
356 
357  const double absGain = gainOfPixel[pixelId];
358 
359  if (fVerbosityLevel>2) {
360  cout << " drum=" << fDrumCalibMode //<< " (" <<!event.HasSimShower()<<")"
361  << " PeToADC=" << absGain
362  << " hasCorrector=" << hasCorrector
363  << " caliconst=" << caliconst
364  << endl;
365  }
366 
367  //correction for calib const in reconstruction
368  const string& configSignature = tel.GetSimData().GetConfigSignature();
369 
370  // The simulation of threshold values is done in ADC therefore no scaling to calib constants
371  // In all other cases: adapt sim gain to data
372  const double calibCorrection = fThresholdMode ? 1.0 : detPixel.GetSimulatedEndToEndCalibration(configSignature) / caliconst;
373 
374  // npe is calculated with default gain in FdBackgroundSimulator
375  // npe is not affected by optical efficiency loss correction
376  double meanBgPe = backphotons * fQEffAtNormWavelength[pixelId];
377 
378  const double gainVariance = detChannel.GetGainVariance();
379  const double elecNoiseVariance = detChannel.GetElectronicNoiseVariance();
380 
381  // correct Gaussian approximation
382  if (!fThresholdMode)
383  meanBgPe *= fBandWidthFactor;
384 
385  // from FdBackgroundSimulator we have: bgPhotons -> (ideal det simulation) -> ADC counts
386  // but in ElecSim we do: photons -> (ideal det simulation) -> (calibCorrection) -> ADC counts
387  // so we should apply inverse calibCorrection to bgPhotons to be consistent with ElecSim
388  // since this is used only for Poisson variance calculation, we need to correct in quadrature
389 
390  if (!detChannel.IsVirtual()) {
391  meanBgPe /= calibCorrection * calibCorrection;
392  }
393 
394  fPeBgNoiseTable[pixelId] = meanBgPe;
395 
396 
397  // Set pixel threshold & n. samples (trigger)
398 
399  const unsigned int fltBoxCarSize = detCamera.GetFLTBoxcarSumLength();
400 
401  double threshold = 0;
402  double ADCVar = 0;
403  double baseline = 0;
404 
405  if (fUseMonitoring) {
406  baseline = detChannel.GetBaseline();
408  threshold = (int) detChannel.GetThreshold()*fltBoxCarSize;
409  } else {
410  threshold = (int) detChannel.GetThreshold();
411  }
412  ADCVar = detChannel.GetADCVariance();
413  }
414  else {
415  baseline = fBaseline;
416  ADCVar = ( meanBgPe * (1 + gainVariance) * absGain*absGain )
417  + elecNoiseVariance;
418  if (meanBgPe) {
419  if (!fUseNewThreshold) {
420  const double baseN = baseline * fltBoxCarSize;
421  const double sigmaN = sqrt(ADCVar * fltBoxCarSize);
422  const double referenceADCBinSize = 100*ns;
423  const double cameraADCBinSize = detCamera.GetFADCBinSize();
424  // equivalent numbers for 100 ns binning
425  // (for which EvalRedThreshold was made for)
426  const unsigned int equivalentBoxCarSize =
427  fltBoxCarSize * (cameraADCBinSize/referenceADCBinSize);
428  const double equivalentMeanPe =
429  meanBgPe;// * (referenceADCBinSize/cameraADCBinSize);
430  threshold = sigmaN*EvalRedThreshold(equivalentMeanPe,
431  equivalentBoxCarSize,
432  gainVariance) + baseN;
433  } else {
434  //New threshold values are baseline subtracted as the baseline is a free parameter in the simulation
435  threshold = fSimThresholdValues[thresholdConfigSignature].Y(meanBgPe);
436  threshold += fltBoxCarSize * baseline;
437  }
438  }
439  else { // meanBgPe==0
440  // this is for noisefree simulations
441  threshold = baseline*fltBoxCarSize + sqrt(ADCVar)*3 + 1;
442  }
443  }
444 
445  fCalibCorrection[pixelId] = calibCorrection;
446  fOpticalEfficiencyCorrection[pixelId] = opticalEfficiencyCorrection;
447 
448  //we should not correct measured quantities
449  if (!fUseMonitoring) {
450  threshold = int(baseline*fltBoxCarSize + (threshold-baseline*fltBoxCarSize)*calibCorrection + .5);
451  ADCVar *= calibCorrection * calibCorrection;
452  }
453 
454  pxsimdata.SetMean(baseline);
455  pxsimdata.SetRMS(sqrt(ADCVar));
456  pxsimdata.SetThreshold(threshold);
457  pxsimdata.SetNumSamples(fltBoxCarSize);
458 
459 
460  if (fVerbosityLevel>2) {
461  cout << " pixelId=" << pixelId
462  << " gain=" << absGain
463  << " var=" << ADCVar
464  << " base=" << baseline
465  << " thresh=" << threshold
466  << " ph_bg=" << backphotons
467  << " meanPE=" << meanBgPe
468  << " num=" << fltBoxCarSize
469  << " caliCorr=" << calibCorrection
470  << endl;
471  }
472 
473  } // end of loop over pixels
474 
475 
476  // all pixels have been DeSelected -> DeSelect whole camera
477  if (!telHasAtLeastOneValidPixel)
478  {
479  ostringstream warn;
480  warn << "********** All pixels of tel=" << tel.GetId() << " at eye=" << tel.GetEyeId()
481  << " have invalid calibration constants -> switch OFF telescope **********";
482  WARNING(warn);
483  return false;
484  }
485 
486  return true;
487 
488 } // end of InitCamera
489 
490 
491 void
493 {
494  const fdet::FDetector& detFD = Detector::GetInstance().GetFDetector();
495  const fdet::Telescope& detTel = detFD.GetTelescope(tel);
496  const fdet::Camera& detCamera = detTel.GetCamera();
497 
498  const double timeBinSize = detCamera.GetFADCBinSize();
499  double cutoffFrequency = detCamera.GetCutoffFrequency();
500 
501  const unsigned int SLTbin = detCamera.GetSLTTriggerBin();
502  const double adcBinsPer100ns = detCamera.GetFADCBinSize() / (100.*ns);
503  const unsigned int adcTriggerBin = (unsigned int)(SLTbin / adcBinsPer100ns);
504 
505  const unsigned int fadcTraceLength = detCamera.GetFADCTraceLength();
506 
507  fevt::TelescopeSimData& telSim = tel.GetSimData();
508  const unsigned int traceSize = telSim.GetNumberOfPhotonBins()
509  + adcTriggerBin // reserve space in front of the photon signal
510  + (fadcTraceLength-adcTriggerBin); // reserve space after the photon signal
511 
512  // for the time convolution, we need a little larger trace
513  const unsigned int nSafety = (fDoAntiAliasingFilter ? fErrFuncFactors.size() - 1 : 0);
514  const unsigned int workTraceSize = traceSize + 2*nSafety;
515 
516  const unsigned int binShift = adcTriggerBin + nSafety;
517 
518 
519  /*
520  RU Mi 9. Aug 18:13:12 CEST 2017
521 
522  first loop over pixels with photon content and calculate signal after PMT and before
523  ADC for all channels and virtual channels:
524  */
525 
526  map<unsigned int, vector<double>> traceMap;
527 
528  // loop all pixels
529  for (unsigned int pixelId=1; pixelId<=detTel.GetLastPixelId(); pixelId++) {
530 
531  if (tel.HasPixel(pixelId)) {
532 
533  fevt::Pixel& pixel = tel.GetPixel(pixelId);
534 
536  pixel.HasSimData()) {
537 
538  fevt::PixelSimData& pxsimdata = pixel.GetSimData();
539 
540  const fdet::Channel& detChannel = detTel.GetChannel(pixel);
541  const unsigned int channelId = detChannel.GetId();
542  const double gainVariance = detChannel.GetGainVariance(); // of PMT (!)
543 
544  const double meanPeBgr = fPeBgNoiseTable[pixelId]; // background light PE
545 
546  // AND the corresponding virtual pixel (low gain)
547  const unsigned int virtualChannelId = detChannel.GetVirtualChannelId();
548 
549  if (fVerbosityLevel>2) {
550  cout << " elec: "
551  << " eyeId=" << tel.GetEyeId()
552  << " telId=" << tel.GetId()
553  << " pixelId=" << pixelId
554  << " channelId=" << channelId
555  << " SLTbin=" << SLTbin
556  << " FADClength=" << fadcTraceLength
557  << " PhotonTrace=" << telSim.GetNumberOfPhotonBins()
558  << " simElecTrace=" << traceSize
559  << endl;
560  }
561 
562  // the simulated pixel light to (nPE*gain) - trace
563  {
564  if (traceMap.count(channelId)!=0) {
565  ERROR("*** normal camera channel is used twice !!! ***");
566  }
567  vector<double> originalChannelTrace(workTraceSize, 0);
568  traceMap[channelId] = originalChannelTrace;
569 
570  vector<double> originalChannelTraceVirtual(workTraceSize, 0);
571  if (traceMap.count(virtualChannelId)==0) {
572  traceMap[virtualChannelId] = originalChannelTraceVirtual;
573  }
574  }
575 
576  vector<double>& tracePix = traceMap[channelId];
577  vector<double>& traceVPix = traceMap[virtualChannelId];
578 
579  const double quantEff = fQEffAtNormWavelength[pixelId];
580 
581  // now applying fluctuations from PMT
582  vector<double> gaussRandomArray(workTraceSize);
583  RandGauss::shootArray(&fRandomEngine->GetEngine(), gaussRandomArray.size(),
584  &gaussRandomArray.front(), 0., 1.);
585 
586 
587  TraceD const * photonTraceOrg = 0;
588  unsigned int photonSize = 0;
589  if (pxsimdata.HasPhotonTrace(fevt::FdConstants::eTotal)) {
590  photonTraceOrg = &pxsimdata.GetPhotonTrace(fevt::FdConstants::eTotal);
591  photonSize = photonTraceOrg->GetSize();
592  if (fVerbosityLevel>3)
593  cout << "photonSize=" << photonSize << endl;
594  if (photonSize+binShift > workTraceSize) {
595  ERROR (" ***** simulated photon trace will be truncated!!!! ****");
596  }
597  }
598 
599  // use photon signal, add PE noise from photon background
600  for (unsigned int ti=0; ti<workTraceSize; ti++) {
601 
602  double nPePh = 0;
603  // the photon pulse is shifted by binShift
604  if (photonTraceOrg && ti>=binShift) {
605  const unsigned int ti_shift = ti-binShift;
606  if (ti_shift<photonSize) {
607  nPePh = (*photonTraceOrg)[ti_shift] * quantEff;
608  //apply optical efficiency loss correction
609  if (!detChannel.IsVirtual()) {
610  nPePh /= fOpticalEfficiencyCorrection[pixelId];
611  }
612  }
613  }
614 
615  double nPe = nPePh + meanPeBgr;
616 
617  if (fVerbosityLevel>3) {
618  cout << "pe-noise: channelId=" << channelId
619  << " virt-channelId=" << virtualChannelId
620  << " ti=" << ti
621  << " nPe=" << nPe
622  << " nPePh=" << nPePh
623  << " meanPeBgr=" << meanPeBgr
624  << " fPeFluctuations=" << fPeFluctuations
625  << " gauss=" << gaussRandomArray[ti]
626  << " gainVariance=" << gainVariance
627  << endl;
628  }
629 
630  // next: add PE poisson fluctuations
631  if (fPeFluctuations)
632  nPe = RandPoisson::shoot(&fRandomEngine->GetEngine(), nPe);
633  // add gaussian fluctuation due to gain
634  nPe += gaussRandomArray[ti] * sqrt(nPe * gainVariance);
635  nPe -= meanPeBgr; // BG is added explicitly below
636 
637  tracePix[ti] = nPe;
638  traceVPix[ti] += nPe; // add this up
639  } // end loop time bins
640  } // pixel has sim data
641  } // has pixel
642  }// end loop over Pixels
643 
644 
645  /*
646  RU Mi 9. Aug 18:13:12 CEST 2017
647 
648  Loop over channel-map and apply electronics gain, variance and filter smoothing
649  for both normal and virtual channels. Also set saturation bit!
650 
651  copy traces into fevt::ChannelSimData Objects
652  */
653 
654  const unsigned int fadcDynamicRange = detCamera.GetADCDynamicRange();
655  const int maxADC = (1<<fadcDynamicRange) - 1;
656 
657  for (auto& iChannelMap : traceMap) {
658 
659  const unsigned int channelId = iChannelMap.first;
660  vector<double>& channelTrace = iChannelMap.second;
661  const unsigned int binMax = channelTrace.size();
662 
663  const fdet::Channel& detChannel = detTel.GetChannel(channelId);
664  const double fadcConvert = detChannel.GetElectronicsGain();
665 
666  const double elecNoiseVariance = detChannel.GetElectronicNoiseVariance();
667  const double noiseEqBdw = 0.5*cutoffFrequency*sqrt(kPi/log(2.0));
668  const double samplingFrequency = 1./timeBinSize;
669  const double analogElectronicsFactor = 2. * noiseEqBdw / samplingFrequency;
670 
671  const double sqrtNoiseVar = sqrt(elecNoiseVariance / analogElectronicsFactor *
673 
674 
675  if (fVerbosityLevel>2) {
676  cout << "channelId=" << channelId
677  << " sqrtNoiseVar=" << sqrtNoiseVar
678  << " workTraceSize=" << workTraceSize
679  << " nSafety=" << nSafety
680  << " binMax=" << binMax
681  << " fadcConvert=" << fadcConvert
682  << endl;
683  }
684 
685  // fluctuations from electronics
686  vector<double> elecNoiseArray(workTraceSize);
687  RandGauss::shootArray(&fRandomEngine->GetEngine(), elecNoiseArray.size(),
688  &elecNoiseArray.front(), 0., sqrtNoiseVar);
689 
690  // the normal channel trace:
691  for (unsigned int ti=0; ti<binMax; ti++) {
692  channelTrace[ti] *= fadcConvert;
693  channelTrace[ti] += elecNoiseArray[ti];
694  }
695 
696  // convolute trace with gaussian response of anti-aliasing filter
697  vector<double> convolutedPMTTrace(traceSize, 0.);
698  if (fDoAntiAliasingFilter) {
699  DoTimeConvolution(channelTrace, convolutedPMTTrace, nSafety);
700  }
701  else {
702  for ( unsigned int ti=0; ti<traceSize; ti++) {
703  convolutedPMTTrace[ti] = channelTrace[ti+nSafety];
704  }
705  }
706 
707  // get the baseline and calib-correction factor per pixel
708  double baseline = fBaseline; // for virtual channels just use this
709  double calibCorrection = 1; // does not exist for virtual channels
710  if (!detChannel.IsVirtual()) {
711  const int pixelId = detChannel.GetPixelId();
712  fevt::Pixel& evtPix = tel.GetPixel(pixelId);
713  fevt::PixelSimData& pxsimdata = evtPix.GetSimData();
714  baseline = pxsimdata.GetMean(); // from DB or xml
715  calibCorrection = fCalibCorrection[pixelId];
716 
717  // CalibCorrection: ONLY for real pixels!
718  for (unsigned int ti=0; ti<traceSize; ti++) {
719  convolutedPMTTrace[ti] *= calibCorrection;
720  }
721  }
722 
723 
724  // create final digital FADC trace
725  // create new data structures
726  if (!tel.HasChannel(channelId))
727  tel.MakeChannel(channelId);
728  fevt::Channel& channel = tel.GetChannel(channelId);
729 
730  if (!channel.HasSimData())
731  channel.MakeSimData();
732  fevt::ChannelSimData& channelSimData = channel.GetSimData();
733 
734  if (!channelSimData.HasFADCTrace(fevt::FdConstants::eTotal))
735  channelSimData.MakeFADCTrace(traceSize, timeBinSize, fevt::FdConstants::eTotal);
736  TraceI& digitTrace = channelSimData.GetFADCTrace(fevt::FdConstants::eTotal);
737 
738  // now convert temporary pmtTrace into final FADC trace
739  for (unsigned int ti=0; ti<traceSize; ti++) {
740  digitTrace[ti] = min(max(0, int(convolutedPMTTrace[ti] + baseline + 0.5)), maxADC);
741  } // end loop bins
742  } // loop channels
743 }// end of ElecSim
744 
745 
746 // --------------------------------------------------------------------------------------
747 void
749 {
750  const fdet::Camera& detCamera = detTel.GetCamera();
751  const double timeBinSize = detCamera.GetFADCBinSize();
752 
753  // see IEEE Trans.Nucl.Sci.50:1208-1213,2003
754  const double cutoffFrequency = detCamera.GetCutoffFrequency();
755  const double tau = sqrt(log(2.)) / (kTwoPi * cutoffFrequency);
756  const double noiseEqBdw = 0.5 * cutoffFrequency * sqrt(kPi/log(2.));
757  const double samplingFrequency = 1./timeBinSize;
758  const double analogElectronicsFactor = 2 * noiseEqBdw / samplingFrequency;
759 
760  fErrFuncFactors.clear();
761 
762  const double epsilon = 1e-6; // precision
763  const int maxIter = 50; // [bins]
764  int iter = 0;
765 
766  double sumE = 0.;
767  double sumESquare = 0.;
768 
769  // integrate the gaussian in timebins
770  while ( sumE < 1 - epsilon &&
771  iter < maxIter ) {
772 
773  const double t1 = (iter - 0.5) * timeBinSize;
774  const double t2 = (iter + 0.5) * timeBinSize;
775 
776  const double E1 = 0.5 * erf(t1 / (sqrt(2.)*tau));
777  const double E2 = 0.5 * erf(t2 / (sqrt(2.)*tau));
778  const double E = E2 - E1;
779 
780  fErrFuncFactors.push_back(E);
781 
782  if ( iter == 0 ) {
783  sumESquare += E*E;
784  sumE += E;
785  }
786  else {
787  sumESquare += 2*E*E;
788  sumE += 2*E;
789  }
790 
791  ++iter;
792  }
793 
794  if ( iter+1 >= maxIter || fErrFuncFactors.empty() ) {
795  ostringstream msg;
796  msg << " Error filling fErrFuncFactors !!! iter="
797  << iter << ", sumE=" << sumE;
798  ERROR(msg);
799  throw AugerException(msg.str());
800  }
801 
802  // correction factor for approximate formula used in
803  // FdBackGroundSimulator
804  fBandWidthFactor = analogElectronicsFactor / sumESquare;
805 
806  return;
807 }
808 
809 void
810 FdElectronicsSimulator::DoTimeConvolution(const vector<double>& originalTrace,
811  vector<double>& convolutedTrace,
812  unsigned int timeOffset)
813 {
814  const int convolutedTraceSize = convolutedTrace.size();
815  const int originialTraceSize = originalTrace.size();
816  const int nConv = (int) fErrFuncFactors.size();
817 
818  // check trace sizes...
819  if ( originialTraceSize-convolutedTraceSize < 2*(nConv-1) ) {
820  // this should never happend !!!!
821  ostringstream msg;
822  msg << " Trace size mismatch!!! "
823  << convolutedTraceSize << " " << originialTraceSize << " " << fErrFuncFactors.size();
824  ERROR(msg);
825  throw AugerException(msg.str());
826  }
827 
828  for ( int i=-nConv+1; i<nConv; ++i ) {
829  const double w = fErrFuncFactors[abs(i)];
830  for ( int tConv = 0; tConv<convolutedTraceSize; ++tConv ) {
831  const int tOrig = tConv + timeOffset + i;
832  convolutedTrace[tConv] += w * originalTrace[tOrig];
833  }
834  }
835 }
836 
837 
838 
839 //----------- see GAP-2003-083
840 
841 // threshold should produce a 100Hz FLT trigger rate (in data):
842 // dT = 1000*100ns = 100us, nFLT=1sec/100us/10=1e3, n(100Hz)=1sec*100Hz = 1e2, pFLT=
843 
844 double
846  double gainVariance)
847 {
848  // mean values of photoelectrons at photocathode
849  const int peTableSize = 12;
850  const double maxNpe = 10000.0;
851  const double vecNpe[peTableSize] = { 2.0, 3.0, 5.0, 10.0, 20.0, 30.0, 50.0, 100.0, 200.0, 500.0, 2000.0, 10000.0};
852 
853  // cutoff values [P (>cutoff) = 1.e-5] for pure Poisson (npe)
854  const int maxSamples = 20;
855  const double fgThrFactPG00[maxSamples][peTableSize] = {
856  {5.62553, 5.47466, 5.22473, 4.95916, 4.76080, 4.67745, 4.58724, 4.49212, 4.42888, 4.36924, 4.31726, 4.27359},
857  {5.33020, 5.14876, 4.95916, 4.76080, 4.62016, 4.55890, 4.49212, 4.42888, 4.38149, 4.33885, 4.30203, 4.26984},
858  {5.14876, 4.97170, 4.83641, 4.67745, 4.55890, 4.50640, 4.45387, 4.39864, 4.36009, 4.32552, 4.29530, 4.26818},
859  {5.01369, 4.88375, 4.76080, 4.62016, 4.52161, 4.47194, 4.42888, 4.38149, 4.34717, 4.31726, 4.29122, 4.26718},
860  {4.95916, 4.83641, 4.71542, 4.58724, 4.49212, 4.45387, 4.41152, 4.36924, 4.33885, 4.31192, 4.28845, 4.26650},
861  {4.88375, 4.78669, 4.67745, 4.55890, 4.47194, 4.43772, 4.39864, 4.36009, 4.33231, 4.30772, 4.28642, 4.26600},
862  {4.83906, 4.75062, 4.64813, 4.53423, 4.45954, 4.42361, 4.38857, 4.35303, 4.32738, 4.30466, 4.2848, 4.26562},
863  {4.81387, 4.71102, 4.62016, 4.52161, 4.44715, 4.41481, 4.38149, 4.34717, 4.32337, 4.30203, 4.28353, 4.26531},
864  {4.78669, 4.69794, 4.60003, 4.50640, 4.43772, 4.40640, 4.37459, 4.34290, 4.32022, 4.30000, 4.28248, 4.26505},
865  {4.76080, 4.67745, 4.58724, 4.49212, 4.42889, 4.39864, 4.36924, 4.33885, 4.31726, 4.29813, 4.28158, 4.26483},
866  {4.73603, 4.65687, 4.56868, 4.48066, 4.42147, 4.39268, 4.36448, 4.33546, 4.31500, 4.29665, 4.28079, 4.26465},
867  {4.71102, 4.63861, 4.55890, 4.47194, 4.41482, 4.38738, 4.36009, 4.33231, 4.31285, 4.29530, 4.28011, 4.26449},
868  {4.69514, 4.62323, 4.54854, 4.46522, 4.40773, 4.38301, 4.35605, 4.32974, 4.31094, 4.29409, 4.27952, 4.26435},
869  {4.68729, 4.61054, 4.53423, 4.45954, 4.40377, 4.37855, 4.35303, 4.32738, 4.30918, 4.29303, 4.27898, 4.26422},
870  {4.67745, 4.60003, 4.52760, 4.45387, 4.39865, 4.37460, 4.35001, 4.32552, 4.30772, 4.29210, 4.27851, 4.26410},
871  {4.66370, 4.59111, 4.52161, 4.44715, 4.39506, 4.37123, 4.34717, 4.32337, 4.30649, 4.29122, 4.27809, 4.26400},
872  {4.64398, 4.58317, 4.51415, 4.44087, 4.39013, 4.36829, 4.34518, 4.32175, 4.30512, 4.29046, 4.27769, 4.26391},
873  {4.63861, 4.57557, 4.50640, 4.43772, 4.38739, 4.36546, 4.34290, 4.32022, 4.30409, 4.28970, 4.27734, 4.26382},
874  {4.63335, 4.56769, 4.49896, 4.43135, 4.38454, 4.36238, 4.34077, 4.31873, 4.30305, 4.28904, 4.27700, 4.26374},
875  {4.62016, 4.55890, 4.49212, 4.42888, 4.38149, 4.36009, 4.33885, 4.31726, 4.30203, 4.28845, 4.27670, 4.26367}
876  };
877 
878  // cutoff values [P (>cutoff) = 1.e-5] for Poisson (npe) convoluted with
879  // Gauss (0,0.41*npe)
880  const double fgThrFactPG41[maxSamples][peTableSize] = {
881  {5.47757, 5.18121, 4.90285, 4.69526, 4.55630, 4.50512, 4.45118, 4.39478, 4.35642, 4.32268, 4.29289, 4.27359},
882  {5.16834, 4.92291, 4.74034, 4.56101, 4.47433, 4.43379, 4.39478, 4.35647, 4.32962, 4.30570, 4.28452, 4.26984},
883  {4.99797, 4.83452, 4.64616, 4.50969, 4.43384, 4.40344, 4.37184, 4.33990, 4.31792, 4.29814, 4.28077, 4.26818},
884  {4.92332, 4.74995, 4.60145, 4.47870, 4.41033, 4.38180, 4.35648, 4.32966, 4.31063, 4.29349, 4.27855, 4.26718},
885  {4.87796, 4.71279, 4.56867, 4.45550, 4.39485, 4.37185, 4.34742, 4.32287, 4.30584, 4.29056, 4.27699, 4.26650},
886  {4.80947, 4.67208, 4.54720, 4.43799, 4.38185, 4.36244, 4.33991, 4.31796, 4.30203, 4.28824, 4.27589, 4.26600},
887  {4.79474, 4.65794, 4.53000, 4.42349, 4.37572, 4.35394, 4.33437, 4.31401, 4.29925, 4.28651, 4.27502, 4.26562},
888  {4.75745, 4.63742, 4.51394, 4.41430, 4.36841, 4.34784, 4.32967, 4.31068, 4.29710, 4.28511, 4.27431, 4.26531},
889  {4.72165, 4.61372, 4.50083, 4.40739, 4.36249, 4.34402, 4.32560, 4.30817, 4.29538, 4.28396, 4.27372, 4.26505},
890  {4.71184, 4.60127, 4.48892, 4.39867, 4.35654, 4.33992, 4.32288, 4.30589, 4.29363, 4.28298, 4.27324, 4.26483},
891  {4.69720, 4.58849, 4.47548, 4.39364, 4.35292, 4.33668, 4.32026, 4.30401, 4.29233, 4.28209, 4.27282, 4.26465},
892  {4.68197, 4.56997, 4.46975, 4.38555, 4.34789, 4.33354, 4.31797, 4.30207, 4.29126, 4.28137, 4.27244, 4.26449},
893  {4.66760, 4.56238, 4.46344, 4.38306, 4.34539, 4.33087, 4.31584, 4.30070, 4.29019, 4.28071, 4.27212, 4.26435},
894  {4.65437, 4.55571, 4.45383, 4.37930, 4.34268, 4.32835, 4.31402, 4.29930, 4.28931, 4.28013, 4.27182, 4.26422},
895  {4.64203, 4.54710, 4.45082, 4.37543, 4.33997, 4.32561, 4.31219, 4.29833, 4.28839, 4.27959, 4.27157, 4.26410},
896  {4.63008, 4.53821, 4.44349, 4.37190, 4.33721, 4.32432, 4.31069, 4.29714, 4.28761, 4.27915, 4.27134, 4.26400},
897  {4.61792, 4.52983, 4.43929, 4.36876, 4.33495, 4.32208, 4.30926, 4.29630, 4.28699, 4.27872, 4.27112, 4.26391},
898  {4.60487, 4.52228, 4.43568, 4.36588, 4.33359, 4.32067, 4.30817, 4.29542, 4.28640, 4.27829, 4.27092, 4.26382},
899  {4.59857, 4.51564, 4.42911, 4.36302, 4.33156, 4.31938, 4.30699, 4.29457, 4.28581, 4.27794, 4.27074, 4.26374},
900  {4.59471, 4.50988, 4.42631, 4.35986, 4.32972, 4.31798, 4.30589, 4.29368, 4.28526, 4.27759, 4.27058, 4.26367}
901  };
902 
903  if ( nSamp > maxSamples ) {
904  ostringstream msg;
905  msg << " number of samples to large "
906  << nSamp << " max=" << maxSamples;
907  ERROR(msg);
908  throw OutOfBoundException(msg.str());
909  }
910 
911  if ( npe > maxNpe ) {
912  ostringstream msg;
913  msg << " number of photo electrons to high "
914  << npe << " max=" << maxNpe;
915  ERROR(msg);
916  throw OutOfBoundException(msg.str());
917  }
918 
919  int i2 = 0;
920 
921  for (int i=0; i<peTableSize; i++)
922  if (npe > vecNpe[i])
923  i2 = i + 1;
924 
925  if (i2 == 0)
926  i2 = 1;
927  if (i2 == peTableSize)
928  i2 = peTableSize-1;
929  int i1 = i2 - 1;
930 
931  double fac00 = (fgThrFactPG00[nSamp-1][i2]
932  - fgThrFactPG00[nSamp-1][i1])/(log(vecNpe[i2])
933  - log(vecNpe[i1])) * (log(npe) - log(vecNpe[i1]));
934 
935  fac00 += fgThrFactPG00[nSamp-1][i1];
936 
937  double fac41 = (fgThrFactPG41[nSamp-1][i2] - fgThrFactPG41[nSamp-1][i1])
938  /(log(vecNpe[i2]) - log(vecNpe[i1]))*(log(npe) - log(vecNpe[i1]));
939 
940  fac41 += fgThrFactPG41[nSamp-1][i1];
941 
942  const double fac = fac00 + (fac41 - fac00)*gainVariance/0.41;
943 
944  return fac;
945 
946 }// end of EvalThreshold
947 
948 
949 // Configure (x)emacs for this file ...
950 // Local Variables:
951 // mode:c++
952 // compile-command: "cd $AUGER_BASE && make"
953 // End:
Status GetStatus() const
Get the pixel status flag.
unsigned int GetId() const
Definition: FEvent/Eye.h:54
void MakeFADCTrace(unsigned int size, double binning, const FdConstants::LightSource source=FdConstants::eTotal)
double GetThreshold() const
unsigned int GetNPoints() const
ComponentSelector::Status GetStatus() const
Definition: FEvent/Pixel.h:54
double GetFADCBinSize() const
double GetBaseline() const
void SetNumSamples(const int nSamp)
Set the no. of samples for running sums.
Definition: PixelSimData.h:115
Description of the electronic channel for the 480 channels of the crate.
void DoTimeConvolution(const std::vector< double > &originalTrace, std::vector< double > &convolutedTrace, unsigned int timeOffset)
Report success to RunController.
Definition: VModule.h:62
int GetNumberOfPhotonBins() const
Base class for all exceptions used in the auger offline code.
Fluorescence Detector Eye Event.
Definition: FEvent/Eye.h:29
const utl::TabulatedFunction & GetEndToEndCalibrationConstant() const
end to end calibration function
RandomEngineType & GetEngine()
Definition: RandomEngine.h:32
void SetStatus(const ComponentSelector::Status status)
bool HasFEvent() const
fwk::VModule::ResultFlag Finish()
Finish: invoked at end of the run (NOT end of the event)
const Pixel & GetPixel(const fevt::Pixel &eventPixel) const
Get fdet::Pixel from fevt::Channel.
Definition: FDetector.cc:198
Class to hold collection (x,y) points and provide interpolation between them.
void PrepareTimeConvolution(const fdet::Telescope &detTel)
double GetElectronicNoiseVariance() const
double GetCutoffFrequency() const
double GetMeanBgPhotonFlux() const
Get mean bg photon flux.
Definition: PixelSimData.h:137
std::map< std::string, std::string > AttributeMap
Definition: Branch.h:24
EyeIterator EyesEnd(const ComponentSelector::Status status)
Definition: FEvent.h:66
unsigned int GetEyeId() const
double GetSimulatedEndToEndCalibration(const std::string &configSignature) const
for the simulated end-to-end calibration constant
bool IsVirtual() const
const Channel & GetChannel(const unsigned int channelId) const
Get Channel by id, throw utl::NonExistentComponentException if n.a.
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
PixelSimData & GetSimData()
Definition: FEvent/Pixel.h:35
bool HasFADCTrace(const FdConstants::LightSource source) const
Check that source /par source is present.
boost::filter_iterator< ComponentSelector, AllEyeIterator > EyeIterator
selective Eye iterators
Definition: FEvent.h:55
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
Definition: Branch.cc:211
bool HasPhotonTrace(const FdConstants::LightSource source) const
Check that trace for source /par source is present.
Definition: PixelSimData.h:51
Fluorescence Detector Channel Simulated Data Event.
double GetEndToEndCalibrationConstantAtReferenceWavelength() const
calA(+drum) constant is returned
std::string GetVersionInfo(const VersionInfoType v) const
Retrieve different sorts of module version info.
Definition: VModule.cc:26
fwk::VModule::ResultFlag Init()
Initialize: invoked at beginning of run (NOT beginning of event)
double GetElectronicsGain() const
ChannelSimData & GetSimData()
void SetStatus(const ComponentSelector::Status status)
Definition: FEvent/Eye.h:119
const Camera & GetCamera() const
Get the Camera object that belongs to the telescope.
int GetFLTBoxcarSumLength() const
PixelIterator PixelsEnd()
iterator pointing to end of available pixels of status eHasData (DEPRECATED)
Detector description interface for FDetector-related data.
Definition: FDetector.h:44
bool HasCorrectorRing() const
flag for corrector ring presence
bool HasSimData() const
std::map< std::string, utl::TabulatedFunction > fSimThresholdValues
Exception for reporting variable out of valid range.
AttributeMap GetAttributes() const
Get a map&lt;string, string&gt; containing all the attributes of this Branch.
Definition: Branch.cc:267
bool HasPixel(const unsigned int pixelId, const ComponentSelector::Status status=ComponentSelector::eHasData) const
Check if the pixel is in the event.
fevt::TelescopeSimData & GetSimData()
Description of simulated data for one Telescope.
#define max(a, b)
Class representing a document branch.
Definition: Branch.h:107
unsigned int GetLastPixelId() const
Channel & GetChannel(const unsigned int channelId)
Fluorescence Detector Pixel event.
Definition: FEvent/Pixel.h:28
const utl::TabulatedFunction & GetQEfficiency() const
Average quantum efficiency as a function of the wavelength.
const double ns
TelescopeIterator TelescopesEnd()
first available tel of status eHasData (DEPRECATED)
Definition: FEvent/Eye.cc:230
constexpr double kPi
Definition: MathConstants.h:24
double abs(const SVector< n, T > &v)
void SetMean(const double mean)
Set the ADC baseline.
Definition: PixelSimData.h:120
EyeIterator EyesBegin(const ComponentSelector::Status status)
Definition: FEvent.h:58
constexpr double kTwoPi
Definition: MathConstants.h:27
const Channel & GetChannel(const fevt::Channel &eventChannel) const
Get fdet::Channel from fevt::Channel.
Definition: FDetector.cc:161
const std::string & GetConfigSignature() const
unsigned int GetId() const
utl::TraceI & GetFADCTrace(const FdConstants::LightSource source=FdConstants::eTotal)
bool HasSimData() const
Definition: FEvent/Pixel.h:38
boost::filter_iterator< ComponentSelector, AllTelescopeIterator > TelescopeIterator
selective Telescope iterators
Definition: FEvent/Eye.h:72
SizeType GetSize() const
Definition: Trace.h:156
#define WARNING(message)
Macro for logging warning messages.
Definition: ErrorLogger.h:163
Fluorescence Detector Channel Event.
void GetData(bool &b) const
Overloads of the GetData member template function.
Definition: Branch.cc:644
Top of Fluorescence Detector event hierarchy.
Definition: FEvent.h:33
a second level trigger
Definition: XbT2.h:8
TelescopeIterator TelescopesBegin()
first available tel of status eHasData (DEPRECATED)
Definition: FEvent/Eye.cc:207
double GetGainVariance() const
unsigned int GetEyeId() const
Definition: FEvent/Pixel.h:33
void MakeChannel(const unsigned int channelId)
double GetReferenceLambda() const
Definition: FDetector.cc:332
unsigned int GetTelescopeId() const
Definition: FEvent/Pixel.h:32
void SetStatus(ComponentSelector::Status status)
Definition: FEvent/Pixel.h:53
void SetThreshold(const int thr)
Set the simulated trigger threshold of the pixel.
Definition: PixelSimData.h:130
Pixel & GetPixel(const unsigned int pixelId, const ComponentSelector::Status status=ComponentSelector::eHasData)
Retrieve Pixel by Id, throw exception if not existent.
double EvalRedThreshold(double npe, int nSamp, double gainVariance)
boost::filter_iterator< ComponentSelector, AllPixelIterator > PixelIterator
selective Pixel iterators
Detector description interface for Telescope-related data.
ResultFlag
Flag returned by module methods to the RunController.
Definition: VModule.h:60
bool HasChannel(const unsigned int channelId) const
const Telescope & GetTelescope(const fevt::Telescope &eventTel) const
Get fdet::Telescope from fevt::Telescope.
Definition: FDetector.cc:150
unsigned int GetId() const
void SetRMS(const double rms)
Set the ADC variance.
Definition: PixelSimData.h:125
void MakeSimData()
double GetMean() const
Get the ADC baseline.
Definition: PixelSimData.h:122
Description of a pixel.
unsigned int GetVirtualChannelId() const
fwk::VModule::ResultFlag Run(evt::Event &event)
Run: invoked once per event.
utl::TraceD & GetPhotonTrace(const FdConstants::LightSource source=FdConstants::eTotal)
Simulated Photon Trace.
Definition: PixelSimData.h:37
Report failure to RunController, causing RunController to terminate execution.
Definition: VModule.h:64
Main configuration utility.
Definition: CentralConfig.h:51
double GetADCVariance() const
Branch GetFirstChild() const
Get first child of this Branch.
Definition: Branch.cc:98
Fluorescence Detector Telescope Event.
PixelIterator PixelsBegin()
iterator pointing to first available pixel of status eHasData (DEPRECATED)
double Y(const double x) const
Get or interpolate the Y value that corresponds to parameter x.
std::string GetThresholdConfigSignature() const
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
utl::Branch GetTopBranch(const std::string &id)
Get top branch for moduleConfigLink with given id (XML files)
Fluorescence Detector Pixel Simulated Data.
Definition: PixelSimData.h:28
Description of a camera.
double GetOpticalEfficiencyCorrectionAtReferenceWavelength() const
optical efficiency correction is returned
unsigned int GetPixelId() const

, generated on Tue Sep 26 2023.