All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Public Types | Public Member Functions | Private Member Functions | Private Attributes | List of all members
sbnd::crt::CRTDetSimAlg Class Reference

#include <CRTDetSimAlg.h>

Public Types

using Parameters = fhicl::Table< CRTDetSimParams >
 

Public Member Functions

 CRTDetSimAlg (const Parameters &p, CLHEP::HepRandomEngine &fRandEngine, double g4RefTime)
 
void ClearTaggers ()
 
void FillTaggers (const uint32_t adid, const uint32_t adsid, std::vector< AuxDetIDE > ides)
 
void CreateData ()
 
std::vector< std::pair
< sbnd::crt::FEBData,
std::vector< AuxDetIDE > > > 
GetData ()
 
std::vector< std::vector< int > > GetAuxData ()
 
uint32_t getChannelTriggerTicks (float t0, float npeMean, float r)
 
void ChargeResponse (double eDep, double d0, double d1, double distToReadout, long &npe0, long &npe1, double &q0, double &q1)
 
uint16_t WaveformEmulation (const uint32_t &time_delay, const double &adc)
 
const CRTDetSimParamsParams ()
 

Private Member Functions

void ConfigureWaveform ()
 
void ConfigureTimeOffset ()
 
void ProcessStrips (const std::vector< StripData > &strips)
 
void AddADC (sbnd::crt::FEBData &feb_data, const int &sipmID, const uint16_t &adc)
 

Private Attributes

CRTDetSimParams fParams
 The table of CRT simulation parameters. More...
 
CLHEP::HepRandomEngine & fEngine
 The random-number engine. More...
 
double fG4RefTime
 The G4 reference time that can be used as a time offset. More...
 
double fTimeOffset
 The time that will be used in the simulation. More...
 
std::unique_ptr
< ROOT::Math::Interpolator > 
fInterpolator
 The interpolator used to estimate the CRT waveform. More...
 
std::map< std::string, TaggerfTaggers
 A list of hit taggers, before any coincidence requirement (name -> tagger) More...
 
std::vector< std::pair
< sbnd::crt::FEBData,
std::vector< AuxDetIDE > > > 
fData
 This member stores the final FEBData for the CRT simulation. More...
 
std::vector< std::vector< int > > fAuxData
 This member stores the indeces of SiPM per AuxDetIDE. More...
 

Detailed Description

Definition at line 119 of file sbndcode/sbndcode/CRT/CRTSimulation/CRTDetSimAlg.h.

Member Typedef Documentation

Constructor & Destructor Documentation

sbnd::crt::CRTDetSimAlg::CRTDetSimAlg ( const Parameters p,
CLHEP::HepRandomEngine &  fRandEngine,
double  g4RefTime 
)

Definition at line 9 of file CRTDetSimAlg.cxx.

10  : fParams(params())
11  , fEngine(engine)
12  , fG4RefTime(g4RefTime)
13  {
16 
17  fTaggers.clear();
18  fData.clear();
19  fAuxData.clear();
20  }
CRTDetSimParams fParams
The table of CRT simulation parameters.
double fG4RefTime
The G4 reference time that can be used as a time offset.
std::vector< std::pair< sbnd::crt::FEBData, std::vector< AuxDetIDE > > > fData
This member stores the final FEBData for the CRT simulation.
std::map< std::string, Tagger > fTaggers
A list of hit taggers, before any coincidence requirement (name -&gt; tagger)
CLHEP::HepRandomEngine & fEngine
The random-number engine.
std::vector< std::vector< int > > fAuxData
This member stores the indeces of SiPM per AuxDetIDE.

Member Function Documentation

void sbnd::crt::CRTDetSimAlg::AddADC ( sbnd::crt::FEBData feb_data,
const int &  sipmID,
const uint16_t &  adc 
)
private

Adds ADCs to a certain SiPM in a FEBData object

Parameters
feb_dataThe FEBData object.
sipmIDThe SiPM index (0-31).
adcADC value to be added.

Definition at line 104 of file CRTDetSimAlg.cxx.

106  {
107  uint16_t original_adc = feb_data.ADC(sipmID);
108  uint16_t new_adc = original_adc + adc;
109 
110  if (new_adc > fParams.AdcSaturation())
111  {
112  new_adc = fParams.AdcSaturation();
113  }
114 
115  feb_data.SetADC(sipmID, new_adc);
116 
117  if (fParams.DebugTrigger()) std::cout << "Updating ADC value for FEB " << feb_data.Mac5()
118  << ", sipmID " << sipmID
119  << " with adc " << adc
120  << ": was " << original_adc
121  << ", now is " << feb_data.ADC(sipmID) << std::endl;
122 
123  }
CRTDetSimParams fParams
The table of CRT simulation parameters.
fhicl::Atom< uint32_t > AdcSaturation
adc_array_t ADC() const
Definition: FEBData.cxx:44
void SetADC(size_t sipmID, uint16_t adc)
Definition: FEBData.cxx:78
fhicl::Atom< bool > DebugTrigger
uint16_t Mac5() const
Definition: FEBData.cxx:29
BEGIN_PROLOG could also be cout
void sbnd::crt::CRTDetSimAlg::ChargeResponse ( double  eDep,
double  d0,
double  d1,
double  distToReadout,
long &  npe0,
long &  npe1,
double &  q0,
double &  q1 
)

Simulated the CRT charge response. Does not include waveform emulation.

Parameters
eDepThe simulated energy deposited on the strip from G4
d0The distance to the optical fiber connected to SiPM 0
d1The distance to the optical fiber connected to SiPM 1
distToReadoutThe distance to the readout
npe0The output number of PEs for SiPM 0
npe1The output number of PEs for SiPM 1
q0The output ADC simulated value (double) for SiPM 0
q1The output ADC simulated value (double) for SiPM 1

Definition at line 575 of file CRTDetSimAlg.cxx.

577  {
578  // The expected number of PE, using a quadratic model for the distance
579  // dependence, and scaling linearly with deposited energy.
580  double qr = fParams.UseEdep() ? 1.0 * eDep / fParams.Q0() : 1.0;
581 
582  double npeExpected =
583  fParams.NpeScaleNorm() / pow(distToReadout - fParams.NpeScaleShift(), 2) * qr;
584 
585  // Put PE on channels weighted by transverse distance across the strip,
586  // using an exponential model
587 
588  double abs0 = exp(-d0 / fParams.AbsLenEff());
589  double abs1 = exp(-d1 / fParams.AbsLenEff());
590  double npeExp0 = npeExpected * abs0 / (abs0 + abs1);
591  double npeExp1 = npeExpected * abs1 / (abs0 + abs1);
592 
593  // Observed PE (Poisson-fluctuated)
594  npe0 = CLHEP::RandPoisson::shoot(&fEngine, npeExp0);
595  npe1 = CLHEP::RandPoisson::shoot(&fEngine, npeExp1);
596 
597  // SiPM and ADC response: Npe to ADC counts, pedestal is added later
598  q0 = CLHEP::RandGauss::shoot(&fEngine, /*fQPed + */fParams.QSlope() * npe0,
599  fParams.QRMS() * sqrt(npe0));
600  q1 = CLHEP::RandGauss::shoot(&fEngine, /*fQPed + */fParams.QSlope() * npe1,
601  fParams.QRMS() * sqrt(npe1));
602 
603  // Apply saturation
604  double saturation = static_cast<double>(fParams.AdcSaturation());
605  if (q0 > saturation) q0 = saturation;
606  if (q1 > saturation) q1 = saturation;
607 
608  mf::LogInfo("CRTSetSimAlg")
609  << "CRT CHARGE RESPONSE: eDep = " << eDep
610  << ", npeExpected = " << npeExpected
611  << ", npe0 = " << npe0 << " -> q0 = " << q0
612  << ", npe1 = " << npe1 << " -> q1 = " << q1 << std::endl;
613  }
fhicl::Atom< double > NpeScaleNorm
CRTDetSimParams fParams
The table of CRT simulation parameters.
fhicl::Atom< uint32_t > AdcSaturation
fhicl::Atom< double > QRMS
fhicl::Atom< double > Q0
fhicl::Atom< double > QSlope
fhicl::Atom< double > AbsLenEff
process_name drop raw::OpDetWaveforms_DataApr2016RecoStage1_saturation_ saturation
fhicl::Atom< bool > UseEdep
CLHEP::HepRandomEngine & fEngine
The random-number engine.
fhicl::Atom< double > NpeScaleShift
void sbnd::crt::CRTDetSimAlg::ClearTaggers ( )

Function to clear member data at beginning of each art::event

Definition at line 665 of file CRTDetSimAlg.cxx.

666  {
667 
668  fTaggers.clear();
669  fData.clear();
670  fAuxData.clear();
671  }
std::vector< std::pair< sbnd::crt::FEBData, std::vector< AuxDetIDE > > > fData
This member stores the final FEBData for the CRT simulation.
std::map< std::string, Tagger > fTaggers
A list of hit taggers, before any coincidence requirement (name -&gt; tagger)
std::vector< std::vector< int > > fAuxData
This member stores the indeces of SiPM per AuxDetIDE.
void sbnd::crt::CRTDetSimAlg::ConfigureTimeOffset ( )
private

Configures the time offset to use, either a custom number, of the G4RefTime, depending on user configuration.

Definition at line 43 of file CRTDetSimAlg.cxx.

44  {
46  {
48  mf::LogInfo("CRTDetSimAlg") << "Configured to use G4 ref time as time offset: "
49  << fTimeOffset << " ns." << std::endl;
50  }
51  else
52  {
54  mf::LogInfo("CRTDetSimAlg") << "Configured to use GlobalT0Offset as time offset: "
55  << fTimeOffset << " ns." << std::endl;
56  }
57  }
CRTDetSimParams fParams
The table of CRT simulation parameters.
double fG4RefTime
The G4 reference time that can be used as a time offset.
fhicl::Atom< double > GlobalT0Offset
double fTimeOffset
The time that will be used in the simulation.
fhicl::Atom< bool > UseG4RefTimeOffset
void sbnd::crt::CRTDetSimAlg::ConfigureWaveform ( )
private

Configures the waveform by reading waveform points from configuration and setting up the interpolator.

Definition at line 23 of file CRTDetSimAlg.cxx.

23  {
24 
25  std::vector<double> wvf_x = fParams.WaveformX();
26  std::vector<double> wvf_y = fParams.WaveformY();
27 
28  // Normalize the waveform
29  float max_y = *std::max_element(std::begin(wvf_y), std::end(wvf_y));
30  for (auto & y : wvf_y) y /= max_y;
31 
32  // Reverse the waveform, as we are only interested to use it to
33  // estimate its effect on time delays.
34  std::reverse(wvf_y.begin(),wvf_y.end());
35 
36  fInterpolator = std::make_unique<ROOT::Math::Interpolator>
37  (wvf_y.size(), ROOT::Math::Interpolation::kLINEAR);
38 
39  fInterpolator->SetData(wvf_x, wvf_y);
40 
41  }
std::unique_ptr< ROOT::Math::Interpolator > fInterpolator
The interpolator used to estimate the CRT waveform.
CRTDetSimParams fParams
The table of CRT simulation parameters.
fhicl::Sequence< double > WaveformY
fhicl::Sequence< double > WaveformX
process_name opflash particleana ie ie y
auto end(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:585
auto begin(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:573
void sbnd::crt::CRTDetSimAlg::CreateData ( )

Returns FEBData objects.

This function is called after loop over AuxDetSimChannels where FillTaggers was used to perform first detsim step. This function applies trigger logic, deadtime, and close-in-time signal biasing effects. it produces the "triggered data" products which make it into the event. Use "GetData" to retrieve the result.

Returns
Vector of pairs (FEBData, vector of AuxDetIDE)

A struct to temporarily store information on a CRT Tagger trigger.

Resets this trigger object

Add a strip belonging to a particular trigger

Tells is a tagger is triggering or not

Returns true is the strip is in dead time

Definition at line 198 of file CRTDetSimAlg.cxx.

199  {
200 
201  /** A struct to temporarily store information on a CRT Tagger trigger.
202  */
203  struct Trigger {
204  bool _is_bottom;
205  double _dead_time;
206  bool _planeX;
207  bool _planeY;
208  std::set<int> _mac5s;
209  std::vector<StripData> _strips;
210  uint32_t _trigger_time;
211  bool _debug;
212 
213  Trigger(bool is_bottom, double dead_time, bool debug) {
214  _planeX = _planeY = false;
215  _is_bottom = is_bottom;
216  _dead_time = dead_time;
217  _debug = debug;
218  }
219 
220  /** \brief Resets this trigger object */
221  void reset(uint32_t trigger_time) {
222  _planeX = _planeY = false;
223  _strips.clear();
224  _mac5s.clear();
225  _trigger_time = trigger_time;
226 
227  if(_debug) std::cout << "TRIGGER TIME IS " << _trigger_time << std::endl;
228  }
229 
230  /** \brief Add a strip belonging to a particular trigger */
231  void add_strip(StripData strip) {
232  _strips.push_back(strip);
233  _mac5s.insert(strip.mac5);
234 
235  if (strip.sipm_coinc) {
236  if (strip.planeID == 0) _planeX = true;
237  if (strip.planeID == 1) _planeY = true;
238  }
239 
240  if(_debug) std::cout << "\tAdded strip with mac " << strip.mac5
241  << " on plane " << strip.planeID
242  << ", with time " << strip.sipm0.t1 << std::endl;
243  }
244 
245  /** \brief Tells is a tagger is triggering or not */
246  bool tagger_triggered() {
247  if (_is_bottom) {
248  return _planeX or _planeY;
249  }
250  return _planeX and _planeY;
251  }
252 
253  /** \brief Returns true is the strip is in dead time */
254  bool is_in_dead_time(int mac5, int time) {
255  if (!_mac5s.count(mac5)) { return false; }
256  return (time <= _dead_time);
257  }
258 
259  void print_no_coinc(StripData strip) {
260  if (_debug) std::cout << "\tStrip with mac " << strip.mac5
261  << " on plane " << strip.planeID
262  << ", with time " << strip.sipm0.t1
263  << " -> didn't have SiPMs coincidence" << std::endl;
264  }
265 
266  void print_dead_time(StripData strip) {
267  if (_debug) std::cout << "\tStrip with mac " << strip.mac5
268  << " on plane " << strip.planeID
269  << ", with time " << strip.sipm0.t1
270  << " -> happened during dead time." << std::endl;
271  }
272  };
273 
274 
275  // Loop over all the CRT Taggers and simulate triggering, dead time, ...
276  for (auto iter : fTaggers)
277  {
278  auto & name = iter.first;
279  auto & tagger = iter.second;
280 
281  mf::LogInfo("CRTDetSimAlg") << "Simulating trigger for tagger " << name << std::endl;
282 
283  bool is_bottom = name.find("Bottom") != std::string::npos;
284  Trigger trigger(is_bottom, fParams.DeadTime(), fParams.DebugTrigger());
285 
286  auto & strip_data_v = tagger.data;
287 
288  // Time order the data
289  std::sort(strip_data_v.begin(), strip_data_v.end(),
290  [](const StripData& strip1,
291  const StripData& strip2) {
292  return strip1.sipm0.t1 < strip2.sipm0.t1;
293  });
294 
295  uint32_t trigger_ts1 = 0, current_time = 0;
296  bool first_trigger = true;
297 
298  // Loop over all the strips in this tagger
299  for (size_t i = 0; i < strip_data_v.size(); i++)
300  {
301  auto & strip_data = strip_data_v[i];
302 
303  current_time = strip_data.sipm0.t1;
304 
305  // Save the first trigger
306  if (strip_data.sipm_coinc and first_trigger)
307  {
308  first_trigger = false;
309  trigger_ts1 = current_time;
310  trigger.reset(trigger_ts1);
311  }
312 
313  // Save strips belonging to this trigger
314  if (current_time - trigger_ts1 < fParams.TaggerPlaneCoincidenceWindow())
315  {
316  trigger.add_strip(strip_data);
317  }
318  // Create a new trigger if either the current tagger is not trigger, or,
319  // if it is triggered, if we are past the dead time. Also, always require
320  // both sipm coincidence.
321  else if ((!trigger.tagger_triggered() or
322  (trigger.tagger_triggered() and
323  !trigger.is_in_dead_time(strip_data.mac5, current_time - trigger_ts1))) and
324  strip_data.sipm_coinc)
325  {
326  if (trigger.tagger_triggered()) {
327  ProcessStrips(trigger._strips);
328  }
329 
330  // Set the current, new, trigger
331  trigger_ts1 = current_time;
332 
333  // Reset the trigger object
334  trigger.reset(trigger_ts1);
335 
336  // Add this strip, which created the trigger
337  trigger.add_strip(strip_data);
338  }
339  else if (!strip_data.sipm_coinc)
340  {
341  trigger.print_no_coinc(strip_data);
342  }
343  else
344  {
345  trigger.print_dead_time(strip_data);
346  }
347 
348  } // loop over strips
349 
350  if (trigger.tagger_triggered()) {
351  ProcessStrips(trigger._strips);
352  }
353 
354  } // loop over taggers
355 
356  mf::LogInfo("CRTDetSimAlg") << "There are " << fData.size() << " FEBData objects." << std::endl;
357 
358  }
CRTDetSimParams fParams
The table of CRT simulation parameters.
void ProcessStrips(const std::vector< StripData > &strips)
std::vector< std::pair< sbnd::crt::FEBData, std::vector< AuxDetIDE > > > fData
This member stores the final FEBData for the CRT simulation.
timescale_traits< TriggerTimeCategory >::time_point_t trigger_time
A point in time on the trigger time scale.
std::map< std::string, Tagger > fTaggers
A list of hit taggers, before any coincidence requirement (name -&gt; tagger)
return match has_match and(match.match_pdg==11 or match.match_pdg==-11)
fhicl::Atom< bool > DebugTrigger
fhicl::Atom< double > TaggerPlaneCoincidenceWindow
fhicl::Atom< double > DeadTime
then echo fcl name
BEGIN_PROLOG could also be cout
void sbnd::crt::CRTDetSimAlg::FillTaggers ( const uint32_t  adid,
const uint32_t  adsid,
std::vector< AuxDetIDE ides 
)

Filles CRT taggers from AuxDetSimChannels.

Intented to be called within loop over AuxDetChannels and provided the AuxDetChannelID, AuxDetSensitiveChannelID, vector of AuxDetIDEs and the number of ides from the end of the vector to include in the detector sim. It handles deposited energy ti light output at SiPM (including attenuation) and to PEs from the SiPM with associated time stamps.

Parameters
adidThe AuxDetChannelID
adsidThe AuxDetSensitiveChannelID
idesThe vector of AuxDetIDE

Definition at line 361 of file CRTDetSimAlg.cxx.

362  {
363 
364  art::ServiceHandle<geo::Geometry> geoService;
365 
366  const geo::AuxDetGeo& adGeo = geoService->AuxDet(adid);
367  const geo::AuxDetSensitiveGeo& adsGeo = adGeo.SensitiveVolume(adsid);
368 
369  // Return the vector of IDEs
370  std::sort(ides.begin(), ides.end(),
371  [](const sim::AuxDetIDE & a, const sim::AuxDetIDE & b) -> bool{
372  return ((a.entryT + a.exitT)/2) < ((b.entryT + b.exitT)/2);
373  });
374 
375  // std::set<std::string> volNames = { adsGeo.TotalVolume()->GetName() };
376  std::set<std::string> volNames = { adGeo.TotalVolume()->GetName() };
377  std::vector<std::vector<TGeoNode const*> > paths =
378  geoService->FindAllVolumePaths(volNames);
379 
380  std::string path = "";
381  for (size_t inode=0; inode<paths.at(0).size(); inode++) {
382  path += paths.at(0).at(inode)->GetName();
383  if (inode < paths.at(0).size() - 1) {
384  path += "/";
385  }
386  }
387 
388  TGeoManager* manager = geoService->ROOTGeoManager();
389  manager->cd(path.c_str());
390 
391  // We get the array of strips first, which is the AuxDet,
392  // then from the AuxDet, we get the strip by picking the
393  // daughter with the ID of the AuxDetSensitive, and finally
394  // from the AuxDet, we go up and pick the module and tagger
395  TGeoNode* nodeArray = manager->GetCurrentNode();
396  TGeoNode* nodeStrip = nodeArray->GetDaughter(adsid);
397  TGeoNode* nodeModule = manager->GetMother(1);
398  TGeoNode* nodeTagger = manager->GetMother(2);
399 
400  std::string volumeName = nodeStrip->GetVolume()->GetName();
401 
402  mf::LogDebug("CRTDetSimAlg") << "Strip name: " << nodeStrip->GetName()
403  << ", number = " << nodeStrip->GetNumber()
404  << "\n Array name: " << nodeArray->GetName()
405  << ", number = " << nodeArray->GetNumber()
406  << "\n Module name: " << nodeModule->GetName()
407  << ", number = " << nodeModule->GetNumber()
408  << "\n Tagger name: " << nodeTagger->GetName()
409  << ", number = " << nodeTagger->GetNumber()
410  << "\n Strip volume name: " << volumeName << std::endl;
411 
412  // Retrive the ID of this CRT module
413  uint16_t mac5 = static_cast<uint16_t>(nodeModule->GetNumber());
414 
415  // Module position in parent (tagger) frame
416  double origin[3] = {0, 0, 0};
417  double modulePosMother[3];
418  nodeModule->LocalToMaster(origin, modulePosMother);
419 
420  // Determine plane ID (1 for z > 0, 0 for z < 0 in local coordinates)
421  unsigned planeID = (modulePosMother[2] > 0);
422 
423  // Determine module orientation: which way is the top (readout end)?
424  bool top = (planeID == 1) ? (modulePosMother[1] > 0) : (modulePosMother[0] < 0);
425 
426  // Simulate the CRT response for each hit
427  mf::LogInfo("CRTDetSimAlg") << "We have " << ides.size() << " IDE for this SimChannel." << std::endl;
428  for (size_t ide_i = 0; ide_i < ides.size(); ide_i++) {
429 
430  sim::AuxDetIDE ide = ides[ide_i];
431 
432  // Finally, what is the distance from the hit (centroid of the entry
433  // and exit points) to the readout end?
434  double x = (ide.entryX + ide.exitX) / 2;
435  double y = (ide.entryY + ide.exitY) / 2;
436  double z = (ide.entryZ + ide.exitZ) / 2;
437 
438  double tTrue = (ide.entryT + ide.exitT) / 2 + fTimeOffset; // ns
439  double eDep = ide.energyDeposited;
440 
441  mf::LogInfo("CRTDetSimAlg") << "True IDE with time " << tTrue
442  << ", energy " << eDep << std::endl;
443 
444  if (tTrue < 0) {
445  throw art::Exception(art::errors::LogicError)
446  << "Time cannot be negative. Check the time offset used for the CRT simulation.\n"
447  << "True time: " << (ide.entryT + ide.exitT) / 2 << "\n"
448  << "TimeOffset: " << fTimeOffset << std::endl;
449  }
450 
451  double world[3] = {x, y, z};
452  double svHitPosLocal[3];
453  adsGeo.WorldToLocal(world, svHitPosLocal);
454 
455  // Calculate distance to the readout
456  double distToReadout;
457  if (top) {
458  distToReadout = abs( adsGeo.HalfWidth1() - svHitPosLocal[0]);
459  }
460  else {
461  distToReadout = abs(-adsGeo.HalfWidth1() - svHitPosLocal[0]);
462  }
463 
464  // Calculate distance to fibers
465  double d0 = abs(-adsGeo.HalfHeight() - svHitPosLocal[1]); // L
466  double d1 = abs( adsGeo.HalfHeight() - svHitPosLocal[1]); // R
467 
468  // Simulate time response
469  // Waveform emulation is added later, because
470  // it depends on trigger time
471  long npe0, npe1;
472  double q0, q1;
473  ChargeResponse(eDep, d0, d1, distToReadout,
474  npe0, npe1, q0, q1);
475 
476  // Time relative to trigger, accounting for propagation delay and 'walk'
477  // for the fixed-threshold discriminator
478  uint32_t ts1_ch0 =
479  getChannelTriggerTicks(/*trigClock,*/ tTrue, npe0, distToReadout);
480  uint32_t ts1_ch1 =
481  getChannelTriggerTicks(/*trigClock,*/ tTrue, npe1, distToReadout);
482 
483  if (fParams.EqualizeSiPMTimes()) {
484  mf::LogWarning("CRTDetSimAlg") << "EqualizeSiPMTimes is on." << std::endl;
485  ts1_ch1 = ts1_ch0;
486  }
487 
488  // Time relative to PPS: Random for now! (FIXME)
489  uint32_t ppsTicks =
490  CLHEP::RandFlat::shootInt(&fEngine, /*trigClock.Frequency()*/ fParams.ClockSpeedCRT() * 1e6);
491 
492  // Adjacent channels on a strip are numbered sequentially.
493  //
494  // In the AuxDetChannelMapAlg methods, channels are identified by an
495  // AuxDet name (retrievable given the hit AuxDet ID) which specifies a
496  // module, and a channel number from 0 to 32.
497  // uint32_t moduleID = adid;
498  uint32_t moduleID = mac5;
499  uint32_t stripID = adsid;
500  uint32_t channel0ID = 32 * moduleID + 2 * stripID + 0;
501  uint32_t channel1ID = 32 * moduleID + 2 * stripID + 1;
502  uint32_t sipm0ID = stripID * 2 + 0;
503  uint32_t sipm1ID = stripID * 2 + 1;
504 
505  if (volumeName.find("MINOS") != std::string::npos) {continue;} // Ignoring MINOS modules for now.
506 
507  // Apply ADC threshold and strip-level coincidence (both fibers fire)
508  double threshold = static_cast<double>(fParams.QThreshold());
509  bool sipm_coinc = false;
510 
511  if (q0 > threshold &&
512  q1 > threshold &&
513  util::absDiff(ts1_ch0, ts1_ch1) < fParams.StripCoincidenceWindow())
514  {
515  sipm_coinc = true;
516  }
517 
518  // Time ordered
519  if (ts1_ch0 > ts1_ch1)
520  {
521  std::swap(ts1_ch0, ts1_ch1);
522  std::swap(channel0ID, channel1ID);
523  std::swap(q0, q1);
524  std::swap(sipm0ID, sipm1ID);
525  }
526 
527  SiPMData sipm0 = SiPMData(sipm0ID,
528  channel0ID,
529  ppsTicks,
530  ts1_ch0,
531  q0);
532  SiPMData sipm1 = SiPMData(sipm1ID,
533  channel1ID,
534  ppsTicks,
535  ts1_ch1,
536  q1);
537 
538  StripData strip_data = StripData(mac5,
539  planeID,
540  sipm0,
541  sipm1,
542  sipm_coinc,
543  ide);
544 
545  // Retrive the Tagger object
546  Tagger& tagger = fTaggers[nodeTagger->GetName()];
547  tagger.data.push_back(strip_data);
548 
549  double poss[3];
550  adsGeo.LocalToWorld(origin, poss);
551  mf::LogInfo("CRTDetSimAlg")
552  << "CRT HIT in adid/adsid " << adid << "/" << adsid << "\n"
553  << "MAC5 " << mac5 << "\n"
554  << "TRUE TIME " << tTrue << "\n"
555  << "TRACK ID " << ide.trackID << "\n"
556  << "CRT HIT POS " << x << " " << y << " " << z << "\n"
557  << "CRT STRIP POS " << poss[0] << " " << poss[1] << " " << poss[2] << "\n"
558  << "CRT MODULE POS " << modulePosMother[0] << " "
559  << modulePosMother[1] << " "
560  << modulePosMother[2] << " "
561  << "\n"
562  << "CRT PATH: " << path << "\n"
563  << "CRT level 0 (strip): " << nodeStrip->GetName() << "\n"
564  << "CRT level 1 (array): " << nodeArray->GetName() << "\n"
565  << "CRT level 2 (module): " << nodeModule->GetName() << "\n"
566  << "CRT level 3 (tagger): " << nodeTagger->GetName() << "\n"
567  << "CRT PLANE ID: " << planeID << "\n"
568  << "CRT distToReadout: " << distToReadout << " " << (top ? "top" : "bot") << "\n"
569  << "CRT Q SiPM 0: " << q0 << ", SiPM 1: " << q1
570  << "CRT Ts1 SiPM 0: " << ts1_ch0 << " SiPM 1: " << ts1_ch1 << "\n";
571  }
572  } //end FillTaggers
uint32_t getChannelTriggerTicks(float t0, float npeMean, float r)
process_name opflash particleana ie ie ie z
fhicl::Atom< double > QThreshold
process_name opflash particleana ie x
vector< pair< ChanData, AuxDetIDE > > data
int trackID
Geant4 supplied track ID.
AuxDetSensitiveGeo const & SensitiveVolume(size_t sv) const
Definition: AuxDetGeo.h:171
CRTDetSimParams fParams
The table of CRT simulation parameters.
process_name gaushit a
float exitY
Exit position Y of particle.
BEGIN_PROLOG triggeremu_data_config_icarus settings PMTADCthresholds sequence::icarus_stage0_multiTPC_TPC physics sequence::icarus_stage0_EastHits_TPC physics sequence::icarus_stage0_WestHits_TPC physics producers purityana0 caloskimCalorimetryCryoE physics caloskimCalorimetryCryoW physics path
walls no top
Definition: selectors.fcl:105
T abs(T value)
process_name opflash particleana ie ie y
float entryT
Entry time of particle.
fhicl::Atom< bool > EqualizeSiPMTimes
std::map< std::string, Tagger > fTaggers
A list of hit taggers, before any coincidence requirement (name -&gt; tagger)
float exitT
Exit time of particle.
void ChargeResponse(double eDep, double d0, double d1, double distToReadout, long &npe0, long &npe1, double &q0, double &q1)
float exitZ
Exit position Z of particle.
float entryZ
Entry position Z of particle.
float exitX
Exit position X of particle.
constexpr auto absDiff(A const &a, B const &b)
Returns the absolute value of the difference between two values.
Definition: NumericUtils.h:43
float energyDeposited
total energy deposited for this track ID and time
fhicl::Atom< double > StripCoincidenceWindow
float entryX
Entry position X of particle.
float entryY
Entry position Y of particle.
const TGeoVolume * TotalVolume() const
Definition: AuxDetGeo.h:106
MC truth information to make RawDigits and do back tracking.
CLHEP::HepRandomEngine & fEngine
The random-number engine.
void WorldToLocal(const double *world, double *auxdet) const
Transform point from world frame to local auxiliary detector frame.
fhicl::Atom< double > ClockSpeedCRT
void LocalToWorld(const double *auxdet, double *world) const
Transform point from local auxiliary detector frame to world frame.
double fTimeOffset
The time that will be used in the simulation.
constexpr Point origin()
Returns a origin position with a point of the specified type.
Definition: geo_vectors.h:227
std::vector< std::vector< int > > sbnd::crt::CRTDetSimAlg::GetAuxData ( )

Returns the indeces of SiPMs associated to the AuxDetIDEs

Returns
Vector of vector (1: FEBs, 2: SiPMs indeces per AuxDetIDE)

Definition at line 64 of file CRTDetSimAlg.cxx.

65  {
66  return fAuxData;
67  }
std::vector< std::vector< int > > fAuxData
This member stores the indeces of SiPM per AuxDetIDE.
uint32_t sbnd::crt::CRTDetSimAlg::getChannelTriggerTicks ( float  t0,
float  npeMean,
float  r 
)

Get the channel trigger time relative to the start of the MC event.

Parameters
clockThe clock to count ticks on
t0The starting time (which delay is added to)
npeNumber of observed photoelectrons
rDistance between the energy deposit and strip readout end [mm]
Returns
Trigger clock ticks at this true hit time

Definition at line 615 of file CRTDetSimAlg.cxx.

617  {
618  // Hit timing, with smearing and NPE dependence
619  double tDelayMean =
620  fParams.TDelayNorm() *
621  exp(-0.5 * pow((npeMean - fParams.TDelayShift()) / fParams.TDelaySigma(), 2)) +
623 
624  double tDelayRMS =
626  exp(-pow(npeMean - fParams.TDelayRMSGausShift(), 2) / fParams.TDelayRMSGausSigma()) +
629 
630  double tDelay = CLHEP::RandGauss::shoot(&fEngine, tDelayMean, tDelayRMS);
631 
632  // Time resolution of the interpolator
633  tDelay += CLHEP::RandGauss::shoot(&fEngine, 0, fParams.TResInterpolator());
634 
635  // Propagation time
636  double tProp = CLHEP::RandGauss::shoot(fParams.PropDelay(), fParams.PropDelayError()) * r;
637 
638  double t = t0 + tProp + tDelay;
639 
640  // Get clock ticks
641  // FIXME no clock available for CRTs, have to do it by hand
642  //clock.SetTime(t / 1e3); // SetTime takes microseconds
643  float time = (t / 1e3) * fParams.ClockSpeedCRT();
644 
645  if (time < 0) {
646  mf::LogWarning("CRTSetSimAlg") << "Time is negative. Check the time offset used." << std::endl;
647  }
648 
649  uint32_t time_int = static_cast<uint32_t>(time);
650 
651  mf::LogInfo("CRTSetSimAlg")
652  << "CRT TIMING: t0 = " << t0 << " (true G4 time)"
653  << ", tDelayMean = " << tDelayMean
654  << ", tDelayRMS = " << tDelayRMS
655  << ", tDelay = " << tDelay
656  << ", tProp = " << tProp
657  << ", t = " << t
658  << ", time = " << time
659  << ", time_int = " << time_int << " (time in uint32_t)" << std::endl;
660 
661  return time_int; // clock.Ticks();
662  }
fhicl::Atom< double > PropDelay
fhicl::Atom< double > TDelayRMSGausShift
CRTDetSimParams fParams
The table of CRT simulation parameters.
fhicl::Atom< double > TDelayRMSExpShift
fhicl::Atom< double > TResInterpolator
fhicl::Atom< double > TDelayShift
fhicl::Atom< double > TDelaySigma
fhicl::Atom< double > TDelayOffset
fhicl::Atom< double > PropDelayError
fhicl::Atom< double > TDelayRMSExpNorm
fhicl::Atom< double > TDelayRMSGausNorm
fhicl::Atom< double > TDelayRMSGausSigma
CLHEP::HepRandomEngine & fEngine
The random-number engine.
fhicl::Atom< double > ClockSpeedCRT
fhicl::Atom< double > TDelayNorm
fhicl::Atom< double > TDelayRMSExpScale
esac echo uname r
std::vector< std::pair< sbnd::crt::FEBData, std::vector< AuxDetIDE > > > sbnd::crt::CRTDetSimAlg::GetData ( )

Returns the simulated FEBData and AuxDetIDEs

Returns
Vector of pairs (FEBData, vector of AuxDetIDE)

Definition at line 59 of file CRTDetSimAlg.cxx.

60  {
61  return fData;
62  }
std::vector< std::pair< sbnd::crt::FEBData, std::vector< AuxDetIDE > > > fData
This member stores the final FEBData for the CRT simulation.
const CRTDetSimParams& sbnd::crt::CRTDetSimAlg::Params ( )
inline

Returns the CRT simulation parmeters

Returns
The CRT simulation parameters

Definition at line 222 of file sbndcode/sbndcode/CRT/CRTSimulation/CRTDetSimAlg.h.

222 {return fParams;}
CRTDetSimParams fParams
The table of CRT simulation parameters.
void sbnd::crt::CRTDetSimAlg::ProcessStrips ( const std::vector< StripData > &  strips)
private

Proccesses a set of CRT strips that belong to the same trigger. This method takes as input all the strips that belong to a single CRT tagger-level trigger and constructs FEBData objects from them.

Parameters
stripsThe set of strips that belong to the same trigger

Definition at line 128 of file CRTDetSimAlg.cxx.

129  {
130  std::map<uint16_t, sbnd::crt::FEBData> mac_to_febdata;
131  std::map<uint16_t, std::vector<AuxDetIDE>> mac_to_ides;
132  std::map<uint16_t, std::vector<int>> mac_to_sipmids;
133 
134  // TODO Add pedestal fluctuations
135  std::array<uint16_t, 32> adc_pedestal = {static_cast<uint16_t>(fParams.QPed())};
136 
137  for (auto & strip : strips)
138  {
139 
140  // First time we encounter this FEB...
141  if (!mac_to_febdata.count(strip.mac5))
142  {
143  // Construct a new FEBData object with only pedestal values (will be filled later)
144  mac_to_febdata[strip.mac5] = sbnd::crt::FEBData(strip.mac5, // FEB ID
145  strip.sipm0.t0, // Ts0
146  strip.sipm0.t1, // Ts1
147  adc_pedestal, // ADCs
148  strip.sipm0.sipmID); // Coinc
149 
150  mac_to_ides[strip.mac5] = std::vector<AuxDetIDE>();
151  mac_to_sipmids[strip.mac5] = std::vector<int>();
152  }
153  // ... all the other times we encounter this FEB
154  else
155  {
156  // We want to save the earliest t1 and t0 for each FEB.
157  if (strip.sipm0.t1 < mac_to_febdata[strip.mac5].Ts1())
158  {
159  mac_to_febdata[strip.mac5].SetTs1(strip.sipm0.t1);
160  mac_to_febdata[strip.mac5].SetTs0(strip.sipm0.t0);
161  mac_to_febdata[strip.mac5].SetCoinc(strip.sipm0.sipmID);
162  }
163  }
164  }
165 
166 
167  for (auto & strip : strips)
168  {
169 
170  auto &feb_data = mac_to_febdata[strip.mac5];
171  uint32_t trigger_time = feb_data.Ts1();
172 
173  uint16_t adc_sipm0 = WaveformEmulation(strip.sipm0.t1 - trigger_time, strip.sipm0.adc);
174  uint16_t adc_sipm1 = WaveformEmulation(strip.sipm1.t1 - trigger_time, strip.sipm1.adc);
175 
176  AddADC(feb_data, strip.sipm0.sipmID, adc_sipm0);
177  AddADC(feb_data, strip.sipm1.sipmID, adc_sipm1);
178 
179  auto &ides = mac_to_ides[strip.mac5];
180  ides.push_back(strip.ide);
181 
182  auto &sipmids = mac_to_sipmids[strip.mac5];
183  sipmids.push_back(std::min(strip.sipm0.sipmID, strip.sipm1.sipmID));
184  }
185 
186  for (auto const& [mac, feb_data] : mac_to_febdata)
187  {
188  fData.push_back(std::make_pair(feb_data, mac_to_ides[mac]));
189  fAuxData.push_back(mac_to_sipmids[mac]);
190  }
191 
192  if (fParams.DebugTrigger()) std::cout << "Constructed " << mac_to_febdata.size()
193  << " FEBData object(s)." << std::endl << std::endl;
194  }
void AddADC(sbnd::crt::FEBData &feb_data, const int &sipmID, const uint16_t &adc)
CRTDetSimParams fParams
The table of CRT simulation parameters.
std::vector< std::pair< sbnd::crt::FEBData, std::vector< AuxDetIDE > > > fData
This member stores the final FEBData for the CRT simulation.
timescale_traits< TriggerTimeCategory >::time_point_t trigger_time
A point in time on the trigger time scale.
fhicl::Atom< bool > DebugTrigger
fhicl::Atom< double > QPed
std::vector< std::vector< int > > fAuxData
This member stores the indeces of SiPM per AuxDetIDE.
uint16_t WaveformEmulation(const uint32_t &time_delay, const double &adc)
BEGIN_PROLOG could also be cout
uint16_t sbnd::crt::CRTDetSimAlg::WaveformEmulation ( const uint32_t &  time_delay,
const double &  adc 
)

Emulated the CRT slow-shaped waveform. This is not a full waveform simulation, but it tries to encapsulate the main effect of the waveform, which is that the ADC counts are reduced if the signal arrives with a time delay w.r.t. the primary event trigger.

Parameters
time_delayThe time delay of this SiPM signal w.r.t. the primary event trigger.
adcThe simulated ADC counts (double) of this SiPM.
Returns
The simulated ADC counts after waveform emulation (in uint16_t format).

Definition at line 71 of file CRTDetSimAlg.cxx.

72  {
73 
75  {
76  return static_cast<uint16_t>(adc);
77  }
78 
79  if (time_delay < 0)
80  {
81  throw art::Exception(art::errors::LogicError)
82  << "Time delay cannot be negative for waveform emulation to happen." << std::endl;
83  }
84 
85  if (time_delay > fParams.WaveformX().back())
86  {
87  // If the time delay is more than the waveform rise time, we
88  // will never be able to see this signal. So return a 0 ADC value.
89  return 0;
90  }
91 
92  // Evaluate the waveform
93  double wf = fInterpolator->Eval(time_delay);
94  wf *= adc;
95 
96  if (fParams.DebugTrigger()) std::cout << "WaveformEmulation, time_delay " << time_delay
97  << ", adc " << adc
98  << ", waveform " << wf << std::endl;
99 
100  return static_cast<uint16_t>(wf);
101  }
std::unique_ptr< ROOT::Math::Interpolator > fInterpolator
The interpolator used to estimate the CRT waveform.
CRTDetSimParams fParams
The table of CRT simulation parameters.
fhicl::Atom< bool > DoWaveformEmulation
fhicl::Sequence< double > WaveformX
fhicl::Atom< bool > DebugTrigger
BEGIN_PROLOG could also be cout

Member Data Documentation

std::vector<std::vector<int> > sbnd::crt::CRTDetSimAlg::fAuxData
private

This member stores the indeces of SiPM per AuxDetIDE.

Definition at line 241 of file sbndcode/sbndcode/CRT/CRTSimulation/CRTDetSimAlg.h.

std::vector<std::pair<sbnd::crt::FEBData, std::vector<AuxDetIDE> > > sbnd::crt::CRTDetSimAlg::fData
private

This member stores the final FEBData for the CRT simulation.

Definition at line 239 of file sbndcode/sbndcode/CRT/CRTSimulation/CRTDetSimAlg.h.

CLHEP::HepRandomEngine& sbnd::crt::CRTDetSimAlg::fEngine
private

The random-number engine.

Definition at line 230 of file sbndcode/sbndcode/CRT/CRTSimulation/CRTDetSimAlg.h.

double sbnd::crt::CRTDetSimAlg::fG4RefTime
private

The G4 reference time that can be used as a time offset.

Definition at line 232 of file sbndcode/sbndcode/CRT/CRTSimulation/CRTDetSimAlg.h.

std::unique_ptr<ROOT::Math::Interpolator> sbnd::crt::CRTDetSimAlg::fInterpolator
private

The interpolator used to estimate the CRT waveform.

Definition at line 235 of file sbndcode/sbndcode/CRT/CRTSimulation/CRTDetSimAlg.h.

CRTDetSimParams sbnd::crt::CRTDetSimAlg::fParams
private

The table of CRT simulation parameters.

Definition at line 228 of file sbndcode/sbndcode/CRT/CRTSimulation/CRTDetSimAlg.h.

std::map<std::string, Tagger> sbnd::crt::CRTDetSimAlg::fTaggers
private

A list of hit taggers, before any coincidence requirement (name -> tagger)

Definition at line 237 of file sbndcode/sbndcode/CRT/CRTSimulation/CRTDetSimAlg.h.

double sbnd::crt::CRTDetSimAlg::fTimeOffset
private

The time that will be used in the simulation.

Definition at line 233 of file sbndcode/sbndcode/CRT/CRTSimulation/CRTDetSimAlg.h.


The documentation for this class was generated from the following files: