LArPandoraInput.cxx
Go to the documentation of this file.
1 /**
2  * @file larpandora/LArPandoraInterface/LArPandoraInput.cxx
3  *
4  * @brief Helper functions for providing inputs to pandora
5  */
6 
12 
14 
17 
19 
21 
25 
26 #include "Api/PandoraApi.h"
27 #include "Managers/PluginManager.h"
28 #include "Plugins/LArTransformationPlugin.h"
29 
31 
35 
37 
38 #include <limits>
39 
40 namespace lar_pandora {
41 
42  void
44  const Settings& settings,
45  const LArDriftVolumeMap& driftVolumeMap,
46  const HitVector& hitVector,
47  IdToHitMap& idToHitMap)
48  {
49  mf::LogDebug("LArPandora") << " *** LArPandoraInput::CreatePandoraHits2D(...) *** "
50  << std::endl;
51 
52  if (!settings.m_pPrimaryPandora)
53  throw cet::exception("LArPandora")
54  << "CreatePandoraHits2D - primary Pandora instance does not exist ";
55 
56  const pandora::Pandora* pPandora(settings.m_pPrimaryPandora);
57 
59  auto const detProp = art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(e);
61 
62  // Loop over ART hits
63  int hitCounter(settings.m_hitCounterOffset);
64 
65  lar_content::LArCaloHitFactory caloHitFactory;
66 
67  for (HitVector::const_iterator iter = hitVector.begin(), iterEnd = hitVector.end();
68  iter != iterEnd;
69  ++iter) {
70  const art::Ptr<recob::Hit> hit = *iter;
71  const geo::WireID hit_WireID(hit->WireID());
72 
73  // Get basic hit properties (view, time, charge)
74  const geo::View_t hit_View(hit->View());
75  const double hit_Charge(hit->Integral());
76  const double hit_Time(hit->PeakTime());
77  const double hit_TimeStart(hit->PeakTimeMinusRMS());
78  const double hit_TimeEnd(hit->PeakTimePlusRMS());
79 
80  // Get hit X coordinate and, if using a single global drift volume, remove any out-of-time hits here
81  const double xpos_cm(
82  detProp.ConvertTicksToX(hit_Time, hit_WireID.Plane, hit_WireID.TPC, hit_WireID.Cryostat));
83  const double dxpos_cm(
84  std::fabs(detProp.ConvertTicksToX(
85  hit_TimeEnd, hit_WireID.Plane, hit_WireID.TPC, hit_WireID.Cryostat) -
86  detProp.ConvertTicksToX(
87  hit_TimeStart, hit_WireID.Plane, hit_WireID.TPC, hit_WireID.Cryostat)));
88 
89  // Get hit Y and Z coordinates, based on central position of wire
90  double xyz[3];
91  theGeometry->Cryostat(hit_WireID.Cryostat)
92  .TPC(hit_WireID.TPC)
93  .Plane(hit_WireID.Plane)
94  .Wire(hit_WireID.Wire)
95  .GetCenter(xyz);
96  const double y0_cm(xyz[1]);
97  const double z0_cm(xyz[2]);
98 
99  // Get other hit properties here
100  const double wire_pitch_cm(theGeometry->WirePitch(hit_View)); // cm
101  const double mips(LArPandoraInput::GetMips(detProp, settings, hit_Charge, hit_View));
102 
103  // Create Pandora CaloHit
104  lar_content::LArCaloHitParameters caloHitParameters;
105 
106  try {
107  caloHitParameters.m_expectedDirection = pandora::CartesianVector(0., 0., 1.);
108  caloHitParameters.m_cellNormalVector = pandora::CartesianVector(0., 0., 1.);
109  caloHitParameters.m_cellSize0 = settings.m_dx_cm;
110  caloHitParameters.m_cellSize1 = (settings.m_useHitWidths ? dxpos_cm : settings.m_dx_cm);
111  caloHitParameters.m_cellThickness = wire_pitch_cm;
112  caloHitParameters.m_cellGeometry = pandora::RECTANGULAR;
113  caloHitParameters.m_time = 0.;
114  caloHitParameters.m_nCellRadiationLengths = settings.m_dx_cm / settings.m_rad_cm;
115  caloHitParameters.m_nCellInteractionLengths = settings.m_dx_cm / settings.m_int_cm;
116  caloHitParameters.m_isDigital = false;
117  caloHitParameters.m_hitRegion = pandora::SINGLE_REGION;
118  caloHitParameters.m_layer = 0;
119  caloHitParameters.m_isInOuterSamplingLayer = false;
120  caloHitParameters.m_inputEnergy = hit_Charge;
121  caloHitParameters.m_mipEquivalentEnergy = mips;
122  caloHitParameters.m_electromagneticEnergy = mips * settings.m_mips_to_gev;
123  caloHitParameters.m_hadronicEnergy = mips * settings.m_mips_to_gev;
124  caloHitParameters.m_pParentAddress = (void*)((intptr_t)(++hitCounter));
125  caloHitParameters.m_larTPCVolumeId =
126  LArPandoraGeometry::GetVolumeID(driftVolumeMap, hit_WireID.Cryostat, hit_WireID.TPC);
128  driftVolumeMap, hit_WireID.Cryostat, hit_WireID.TPC);
129 
130  if (hit_View == detType->TargetViewW(hit_WireID.TPC, hit_WireID.Cryostat)) {
131  caloHitParameters.m_hitType = pandora::TPC_VIEW_W;
132  const double wpos_cm(
133  pPandora->GetPlugins()->GetLArTransformationPlugin()->YZtoW(y0_cm, z0_cm));
134  caloHitParameters.m_positionVector = pandora::CartesianVector(xpos_cm, 0., wpos_cm);
135  }
136  else if (hit_View == detType->TargetViewU(hit_WireID.TPC, hit_WireID.Cryostat)) {
137  caloHitParameters.m_hitType = pandora::TPC_VIEW_U;
138  const double upos_cm(
139  pPandora->GetPlugins()->GetLArTransformationPlugin()->YZtoU(y0_cm, z0_cm));
140  caloHitParameters.m_positionVector = pandora::CartesianVector(xpos_cm, 0., upos_cm);
141  }
142  else if (hit_View == detType->TargetViewV(hit_WireID.TPC, hit_WireID.Cryostat)) {
143  caloHitParameters.m_hitType = pandora::TPC_VIEW_V;
144  const double vpos_cm(
145  pPandora->GetPlugins()->GetLArTransformationPlugin()->YZtoV(y0_cm, z0_cm));
146  caloHitParameters.m_positionVector = pandora::CartesianVector(xpos_cm, 0., vpos_cm);
147  }
148  else {
149  throw cet::exception("LArPandora")
150  << "CreatePandoraHits2D - this wire view not recognised (View=" << hit_View << ") ";
151  }
152  }
153  catch (const pandora::StatusCodeException&) {
154  mf::LogWarning("LArPandora")
155  << "CreatePandoraHits2D - invalid calo hit parameter provided, all assigned values must "
156  "be finite, calo hit omitted "
157  << std::endl;
158  continue;
159  }
160 
161  // Store the hit address
162  if (hitCounter >= settings.m_uidOffset)
163  throw cet::exception("LArPandora")
164  << "CreatePandoraHits2D - detected an excessive number of hits (" << hitCounter << ") ";
165 
166  idToHitMap[hitCounter] = hit;
167 
168  // Create the Pandora hit
169  try {
170  PANDORA_THROW_RESULT_IF(
171  pandora::STATUS_CODE_SUCCESS,
172  !=,
173  PandoraApi::CaloHit::Create(*pPandora, caloHitParameters, caloHitFactory));
174  }
175  catch (const pandora::StatusCodeException&) {
176  mf::LogWarning("LArPandora") << "CreatePandoraHits2D - unable to create calo hit, "
177  "insufficient or invalid information supplied "
178  << std::endl;
179  continue;
180  }
181  }
182  }
183 
184  //------------------------------------------------------------------------------------------------------------------------------------------
185 
186  void
188  const LArDriftVolumeList& driftVolumeList)
189  {
190  mf::LogDebug("LArPandora") << " *** LArPandoraInput::CreatePandoraLArTPCs(...) *** "
191  << std::endl;
192 
193  if (!settings.m_pPrimaryPandora)
194  throw cet::exception("LArPandora")
195  << "CreatePandoraDetectorGaps - primary Pandora instance does not exist ";
196 
197  const pandora::Pandora* pPandora(settings.m_pPrimaryPandora);
198 
199  for (const LArDriftVolume& driftVolume : driftVolumeList) {
200  PandoraApi::Geometry::LArTPC::Parameters parameters;
201 
202  try {
203  parameters.m_larTPCVolumeId = driftVolume.GetVolumeID();
204  parameters.m_centerX = driftVolume.GetCenterX();
205  parameters.m_centerY = driftVolume.GetCenterY();
206  parameters.m_centerZ = driftVolume.GetCenterZ();
207  parameters.m_widthX = driftVolume.GetWidthX();
208  parameters.m_widthY = driftVolume.GetWidthY();
209  parameters.m_widthZ = driftVolume.GetWidthZ();
210  parameters.m_wirePitchU = driftVolume.GetWirePitchU();
211  parameters.m_wirePitchV = driftVolume.GetWirePitchV();
212  parameters.m_wirePitchW = driftVolume.GetWirePitchW();
213  parameters.m_wireAngleU = driftVolume.GetWireAngleU();
214  parameters.m_wireAngleV = driftVolume.GetWireAngleV();
215  parameters.m_wireAngleW = driftVolume.GetWireAngleW();
216  parameters.m_sigmaUVW = driftVolume.GetSigmaUVZ();
217  parameters.m_isDriftInPositiveX = driftVolume.IsPositiveDrift();
218  }
219  catch (const pandora::StatusCodeException&) {
220  mf::LogWarning("LArPandora") << "CreatePandoraLArTPCs - invalid tpc parameter provided, "
221  "all assigned values must be finite, tpc omitted "
222  << std::endl;
223  continue;
224  }
225 
226  try {
227  PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS,
228  !=,
229  PandoraApi::Geometry::LArTPC::Create(*pPandora, parameters));
230  }
231  catch (const pandora::StatusCodeException&) {
232  mf::LogWarning("LArPandora") << "CreatePandoraLArTPCs - unable to create tpc, insufficient "
233  "or invalid information supplied "
234  << std::endl;
235  continue;
236  }
237  }
238  }
239 
240  //------------------------------------------------------------------------------------------------------------------------------------------
241 
242  void
244  const LArDriftVolumeList& driftVolumeList,
245  const LArDetectorGapList& listOfGaps)
246  {
247  //ATTN - Unlike SP, DP detector gaps are not in the drift direction
250 
251  mf::LogDebug("LArPandora") << " *** LArPandoraInput::CreatePandoraDetectorGaps(...) *** "
252  << std::endl;
253 
254  if (!settings.m_pPrimaryPandora)
255  throw cet::exception("LArPandora")
256  << "CreatePandoraDetectorGaps - primary Pandora instance does not exist ";
257 
258  const pandora::Pandora* pPandora(settings.m_pPrimaryPandora);
259 
260  for (const LArDetectorGap& gap : listOfGaps) {
261  PandoraApi::Geometry::LineGap::Parameters parameters;
262 
263  try {
264  parameters = detType->CreateLineGapParametersFromDetectorGaps(gap);
265  }
266  catch (const pandora::StatusCodeException&) {
267  mf::LogWarning("LArPandora")
268  << "CreatePandoraDetectorGaps - invalid line gap parameter provided, all assigned values "
269  "must be finite, line gap omitted "
270  << std::endl;
271  continue;
272  }
273  try {
274  PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS,
275  !=,
276  PandoraApi::Geometry::LineGap::Create(*pPandora, parameters));
277  }
278  catch (const pandora::StatusCodeException&) {
279  mf::LogWarning("LArPandora") << "CreatePandoraDetectorGaps - unable to create line gap, "
280  "insufficient or invalid information supplied "
281  << std::endl;
282  continue;
283  }
284  }
285  }
286 
287  //------------------------------------------------------------------------------------------------------------------------------------------
288 
289  void
291  const LArDriftVolumeMap& driftVolumeMap)
292  {
293  mf::LogDebug("LArPandora") << " *** LArPandoraInput::CreatePandoraReadoutGaps(...) *** "
294  << std::endl;
295 
296  if (!settings.m_pPrimaryPandora)
297  throw cet::exception("LArPandora")
298  << "CreatePandoraReadoutGaps - primary Pandora instance does not exist ";
299 
300  const pandora::Pandora* pPandora(settings.m_pPrimaryPandora);
301 
303  const lariov::ChannelStatusProvider& channelStatus(
305 
307 
308  for (unsigned int icstat = 0; icstat < theGeometry->Ncryostats(); ++icstat) {
309  for (unsigned int itpc = 0; itpc < theGeometry->NTPC(icstat); ++itpc) {
310  const geo::TPCGeo& TPC(theGeometry->TPC(itpc));
311 
312  for (unsigned int iplane = 0; iplane < TPC.Nplanes(); ++iplane) {
313  const geo::PlaneGeo& plane(TPC.Plane(iplane));
314  const float halfWirePitch(0.5f * theGeometry->WirePitch(plane.View()));
315  const unsigned int nWires(theGeometry->Nwires(plane.ID()));
316 
317  int firstBadWire(-1), lastBadWire(-1);
318 
319  for (unsigned int iwire = 0; iwire < nWires; ++iwire) {
321  theGeometry->PlaneWireToChannel(iplane, iwire, itpc, icstat));
322  const bool isBadChannel(channelStatus.IsBad(channel));
323  const bool isLastWire(nWires == (iwire + 1));
324 
325  if (isBadChannel && (firstBadWire < 0)) firstBadWire = iwire;
326 
327  if (isBadChannel || isLastWire) lastBadWire = iwire;
328 
329  if (isBadChannel && !isLastWire) continue;
330 
331  if ((firstBadWire < 0) || (lastBadWire < 0)) continue;
332 
333  double firstXYZ[3], lastXYZ[3];
334  theGeometry->Cryostat(icstat)
335  .TPC(itpc)
336  .Plane(iplane)
337  .Wire(firstBadWire)
338  .GetCenter(firstXYZ);
339  theGeometry->Cryostat(icstat)
340  .TPC(itpc)
341  .Plane(iplane)
342  .Wire(lastBadWire)
343  .GetCenter(lastXYZ);
344 
345  firstBadWire = -1;
346  lastBadWire = -1;
347 
348  PandoraApi::Geometry::LineGap::Parameters parameters;
349 
350  try {
351  float xFirst(-std::numeric_limits<float>::max());
352  float xLast(std::numeric_limits<float>::max());
353 
354  const unsigned int volumeId(
355  LArPandoraGeometry::GetVolumeID(driftVolumeMap, icstat, itpc));
356  LArDriftVolumeMap::const_iterator volumeIter(driftVolumeMap.find(volumeId));
357 
358  if (driftVolumeMap.end() != volumeIter) {
359  xFirst = volumeIter->second.GetCenterX() - 0.5f * volumeIter->second.GetWidthX();
360  xLast = volumeIter->second.GetCenterX() + 0.5f * volumeIter->second.GetWidthX();
361  }
362 
363  const geo::View_t iview = plane.View();
364  parameters = detType->CreateLineGapParametersFromReadoutGaps(
365  iview, itpc, icstat, firstXYZ, lastXYZ, halfWirePitch, xFirst, xLast, pPandora);
366  }
367  catch (const pandora::StatusCodeException&) {
368  mf::LogWarning("LArPandora")
369  << "CreatePandoraReadoutGaps - invalid line gap parameter provided, all assigned "
370  "values must be finite, line gap omitted "
371  << std::endl;
372  continue;
373  }
374 
375  try {
376  PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS,
377  !=,
378  PandoraApi::Geometry::LineGap::Create(*pPandora, parameters));
379  }
380  catch (const pandora::StatusCodeException&) {
381  mf::LogWarning("LArPandora") << "CreatePandoraReadoutGaps - unable to create line "
382  "gap, insufficient or invalid information supplied "
383  << std::endl;
384  continue;
385  }
386  }
387  }
388  }
389  }
390  }
391 
392  //------------------------------------------------------------------------------------------------------------------------------------------
393 
394  void
396  const MCTruthToMCParticles& truthToParticleMap,
397  const MCParticlesToMCTruth& particleToTruthMap,
398  const RawMCParticleVector& generatorMCParticleVector)
399  {
400  mf::LogDebug("LArPandora") << " *** LArPandoraInput::CreatePandoraMCParticles(...) *** "
401  << std::endl;
403 
404  if (!settings.m_pPrimaryPandora)
405  throw cet::exception("LArPandora")
406  << "CreatePandoraMCParticles - primary Pandora instance does not exist ";
407 
408  const pandora::Pandora* pPandora(settings.m_pPrimaryPandora);
409 
410  // Make indexed list of MC particles
411  MCParticleMap particleMap;
412 
413  for (MCParticlesToMCTruth::const_iterator iter = particleToTruthMap.begin(),
414  iterEnd = particleToTruthMap.end();
415  iter != iterEnd;
416  ++iter) {
417  const art::Ptr<simb::MCParticle> particle = iter->first;
418  particleMap[particle->TrackId()] = particle;
419  }
420 
421  // Loop over MC truth objects
422  int neutrinoCounter(0);
423 
424  lar_content::LArMCParticleFactory mcParticleFactory;
425 
426  for (MCTruthToMCParticles::const_iterator iter1 = truthToParticleMap.begin(),
427  iterEnd1 = truthToParticleMap.end();
428  iter1 != iterEnd1;
429  ++iter1) {
430  const art::Ptr<simb::MCTruth> truth = iter1->first;
431 
432  if (truth->NeutrinoSet()) {
433  const simb::MCNeutrino neutrino(truth->GetNeutrino());
434  ++neutrinoCounter;
435 
436  if (neutrinoCounter >= settings.m_uidOffset)
437  throw cet::exception("LArPandora")
438  << "CreatePandoraMCParticles - detected an excessive number of mc neutrinos ("
439  << neutrinoCounter << ")";
440 
441  const int neutrinoID(neutrinoCounter + 9 * settings.m_uidOffset);
442 
443  // Create Pandora 3D MC Particle
444  lar_content::LArMCParticleParameters mcParticleParameters;
445 
446  try {
447  mcParticleParameters.m_nuanceCode = neutrino.InteractionType();
448  mcParticleParameters.m_process = lar_content::MC_PROC_INCIDENT_NU;
449  mcParticleParameters.m_energy = neutrino.Nu().E();
450  mcParticleParameters.m_momentum =
451  pandora::CartesianVector(neutrino.Nu().Px(), neutrino.Nu().Py(), neutrino.Nu().Pz());
452  mcParticleParameters.m_vertex =
453  pandora::CartesianVector(neutrino.Nu().Vx(), neutrino.Nu().Vy(), neutrino.Nu().Vz());
454  mcParticleParameters.m_endpoint =
455  pandora::CartesianVector(neutrino.Nu().Vx(), neutrino.Nu().Vy(), neutrino.Nu().Vz());
456  mcParticleParameters.m_particleId = neutrino.Nu().PdgCode();
457  mcParticleParameters.m_mcParticleType = pandora::MC_3D;
458  mcParticleParameters.m_pParentAddress = (void*)((intptr_t)neutrinoID);
459  }
460  catch (const pandora::StatusCodeException&) {
461  mf::LogWarning("LArPandora")
462  << "CreatePandoraMCParticles - invalid mc neutrino parameter provided, all assigned "
463  "values must be finite, mc neutrino omitted "
464  << std::endl;
465  continue;
466  }
467 
468  try {
469  PANDORA_THROW_RESULT_IF(
470  pandora::STATUS_CODE_SUCCESS,
471  !=,
472  PandoraApi::MCParticle::Create(*pPandora, mcParticleParameters, mcParticleFactory));
473  }
474  catch (const pandora::StatusCodeException&) {
475  mf::LogWarning("LArPandora") << "CreatePandoraMCParticles - unable to create mc "
476  "neutrino, insufficient or invalid information supplied "
477  << std::endl;
478  continue;
479  }
480 
481  // Loop over associated particles
482  const MCParticleVector& particleVector = iter1->second;
483 
484  for (MCParticleVector::const_iterator iter2 = particleVector.begin(),
485  iterEnd2 = particleVector.end();
486  iter2 != iterEnd2;
487  ++iter2) {
488  const art::Ptr<simb::MCParticle> particle = *iter2;
489  const int trackID(particle->TrackId());
490 
491  // Mother/Daughter Links
492  if (particle->Mother() == 0) {
493  try {
494  PANDORA_THROW_RESULT_IF(
495  pandora::STATUS_CODE_SUCCESS,
496  !=,
497  PandoraApi::SetMCParentDaughterRelationship(
498  *pPandora, (void*)((intptr_t)neutrinoID), (void*)((intptr_t)trackID)));
499  }
500  catch (const pandora::StatusCodeException&) {
501  mf::LogWarning("LArPandora") << "CreatePandoraMCParticles - unable to create mc "
502  "particle relationship, invalid information supplied "
503  << std::endl;
504  continue;
505  }
506  }
507  }
508  }
509  }
510 
511  mf::LogDebug("LArPandora") << " Number of Pandora neutrinos: " << neutrinoCounter
512  << std::endl;
513 
514  // Loop over G4 particles
515  int particleCounter(0);
516 
517  // Find Primary Generator Particles
518  std::map<const simb::MCParticle, bool> primaryGeneratorMCParticleMap;
519  LArPandoraInput::FindPrimaryParticles(generatorMCParticleVector, primaryGeneratorMCParticleMap);
520 
521  for (MCParticleMap::const_iterator iterI = particleMap.begin(), iterEndI = particleMap.end();
522  iterI != iterEndI;
523  ++iterI) {
524  const art::Ptr<simb::MCParticle> particle = iterI->second;
525 
526  if (particle->TrackId() != iterI->first)
527  throw cet::exception("LArPandora") << "CreatePandoraMCParticles - mc truth information "
528  "appears to be scrambled in this event";
529 
530  if (particle->TrackId() >= settings.m_uidOffset)
531  throw cet::exception("LArPandora")
532  << "CreatePandoraMCParticles - detected an excessive number of MC particles ("
533  << particle->TrackId() << ")";
534 
535  ++particleCounter;
536 
537  // Find start and end trajectory points
538  int firstT(-1), lastT(-1);
539  LArPandoraInput::GetTrueStartAndEndPoints(settings, particle, firstT, lastT);
540 
541  if (firstT < 0 && lastT < 0) {
542  firstT = 0;
543  lastT = 0;
544  }
545 
546  // Lookup position and kinematics at start and end points
547  const float vtxX(particle->Vx(firstT));
548  const float vtxY(particle->Vy(firstT));
549  const float vtxZ(particle->Vz(firstT));
550 
551  const float endX(particle->Vx(lastT));
552  const float endY(particle->Vy(lastT));
553  const float endZ(particle->Vz(lastT));
554 
555  const float pX(particle->Px(firstT));
556  const float pY(particle->Py(firstT));
557  const float pZ(particle->Pz(firstT));
558  const float E(particle->E(firstT));
559 
560  // Find the source of the mc particle
561  int nuanceCode(0);
562  const int trackID(particle->TrackId());
563  const simb::Origin_t origin(particleInventoryService->TrackIdToMCTruth(trackID).Origin());
564 
565  if (LArPandoraInput::IsPrimaryMCParticle(particle, primaryGeneratorMCParticleMap)) {
566  nuanceCode = 2001;
567  }
568  else if (simb::kCosmicRay == origin) {
569  nuanceCode = 3000;
570  }
571  else if (simb::kSingleParticle == origin) {
572  nuanceCode = 2000;
573  }
574 
575  // Create 3D Pandora MC Particle
576  lar_content::LArMCParticleParameters mcParticleParameters;
577 
578  try {
580  FillMCProcessMap(processMap);
581  mcParticleParameters.m_nuanceCode = nuanceCode;
582  if (processMap.find(particle->Process()) != processMap.end()) {
583  mcParticleParameters.m_process = processMap[particle->Process()];
584  }
585  else {
586  mcParticleParameters.m_process = lar_content::MC_PROC_UNKNOWN;
587  mf::LogWarning("LArPandora")
588  << "CreatePandoraMCParticles - found an unknown process" << std::endl;
589  }
590  mcParticleParameters.m_energy = E;
591  mcParticleParameters.m_particleId = particle->PdgCode();
592  mcParticleParameters.m_momentum = pandora::CartesianVector(pX, pY, pZ);
593  mcParticleParameters.m_vertex = pandora::CartesianVector(vtxX, vtxY, vtxZ);
594  mcParticleParameters.m_endpoint = pandora::CartesianVector(endX, endY, endZ);
595  mcParticleParameters.m_mcParticleType = pandora::MC_3D;
596  mcParticleParameters.m_pParentAddress = (void*)((intptr_t)particle->TrackId());
597  }
598  catch (const pandora::StatusCodeException&) {
599  mf::LogWarning("LArPandora")
600  << "CreatePandoraMCParticles - invalid mc particle parameter provided, all assigned "
601  "values must be finite, mc particle omitted "
602  << std::endl;
603  continue;
604  }
605 
606  try {
607  PANDORA_THROW_RESULT_IF(
608  pandora::STATUS_CODE_SUCCESS,
609  !=,
610  PandoraApi::MCParticle::Create(*pPandora, mcParticleParameters, mcParticleFactory));
611  }
612  catch (const pandora::StatusCodeException&) {
613  mf::LogWarning("LArPandora") << "CreatePandoraMCParticles - unable to create mc particle, "
614  "insufficient or invalid information supplied "
615  << std::endl;
616  continue;
617  }
618 
619  // Create Mother/Daughter Links between 3D MC Particles
620  const int id_mother(particle->Mother());
621  MCParticleMap::const_iterator iterJ = particleMap.find(id_mother);
622 
623  if (iterJ != particleMap.end()) {
624  try {
625  PANDORA_THROW_RESULT_IF(
626  pandora::STATUS_CODE_SUCCESS,
627  !=,
628  PandoraApi::SetMCParentDaughterRelationship(
629  *pPandora, (void*)((intptr_t)id_mother), (void*)((intptr_t)particle->TrackId())));
630  }
631  catch (const pandora::StatusCodeException&) {
632  mf::LogWarning("LArPandora") << "CreatePandoraMCParticles - Unable to create mc particle "
633  "relationship, invalid information supplied "
634  << std::endl;
635  continue;
636  }
637  }
638  }
639 
640  mf::LogDebug("LArPandora") << "Number of mc particles: " << particleCounter << std::endl;
641  }
642 
643  //------------------------------------------------------------------------------------------------------------------------------------------
644 
645  void
647  const RawMCParticleVector& mcParticleVector,
648  std::map<const simb::MCParticle, bool>& primaryMCParticleMap)
649  {
650  for (const simb::MCParticle& mcParticle : mcParticleVector) {
651  if ("primary" == mcParticle.Process()) {
652  primaryMCParticleMap.emplace(std::make_pair(mcParticle, false));
653  }
654  }
655  }
656 
657  //------------------------------------------------------------------------------------------------------------------------------------------
658 
659  bool
661  std::map<const simb::MCParticle, bool>& primaryMCParticleMap)
662  {
663  for (auto& mcParticleIter : primaryMCParticleMap) {
664  if (!mcParticleIter.second) {
665  const simb::MCParticle primaryMCParticle(mcParticleIter.first);
666 
667  if (std::fabs(primaryMCParticle.Px() - mcParticle->Px()) <
668  std::numeric_limits<double>::epsilon() &&
669  std::fabs(primaryMCParticle.Py() - mcParticle->Py()) <
670  std::numeric_limits<double>::epsilon() &&
671  std::fabs(primaryMCParticle.Pz() - mcParticle->Pz()) <
672  std::numeric_limits<double>::epsilon()) {
673  mcParticleIter.second = true;
674  return true;
675  }
676  }
677  }
678  return false;
679  }
680 
681  //------------------------------------------------------------------------------------------------------------------------------------------
682 
683  void
685  const IdToHitMap& idToHitMap,
686  const HitsToTrackIDEs& hitToParticleMap)
687  {
688  mf::LogDebug("LArPandora") << " *** LArPandoraInput::CreatePandoraMCLinks(...) *** "
689  << std::endl;
690 
691  if (!settings.m_pPrimaryPandora)
692  throw cet::exception("LArPandora")
693  << "CreatePandoraMCLinks2D - primary Pandora instance does not exist ";
694 
695  const pandora::Pandora* pPandora(settings.m_pPrimaryPandora);
696 
697  for (IdToHitMap::const_iterator iterI = idToHitMap.begin(), iterEndI = idToHitMap.end();
698  iterI != iterEndI;
699  ++iterI) {
700  const int hitID(iterI->first);
701  const art::Ptr<recob::Hit> hit(iterI->second);
702  // const geo::WireID hit_WireID(hit->WireID());
703 
704  // Get list of associated MC particles
705  HitsToTrackIDEs::const_iterator iterJ = hitToParticleMap.find(hit);
706 
707  if (hitToParticleMap.end() == iterJ) continue;
708 
709  const TrackIDEVector& trackCollection = iterJ->second;
710 
711  if (trackCollection.size() == 0)
712  throw cet::exception("LArPandora")
713  << "CreatePandoraMCLinks2D - found a hit without any associated MC truth information ";
714 
715  // Create links between hits and MC particles
716  for (unsigned int k = 0; k < trackCollection.size(); ++k) {
717  const sim::TrackIDE trackIDE(trackCollection.at(k));
718  const int trackID(std::abs(trackIDE.trackID)); // TODO: Find out why std::abs is needed
719  const float energyFrac(trackIDE.energyFrac);
720 
721  try {
722  PANDORA_THROW_RESULT_IF(
723  pandora::STATUS_CODE_SUCCESS,
724  !=,
725  PandoraApi::SetCaloHitToMCParticleRelationship(
726  *pPandora, (void*)((intptr_t)hitID), (void*)((intptr_t)trackID), energyFrac));
727  }
728  catch (const pandora::StatusCodeException&) {
729  mf::LogWarning("LArPandora") << "CreatePandoraMCLinks2D - unable to create calo hit to "
730  "mc particle relationship, invalid information supplied "
731  << std::endl;
732  continue;
733  }
734  }
735  }
736  }
737 
738  //------------------------------------------------------------------------------------------------------------------------------------------
739 
740  void
742  const art::Ptr<simb::MCParticle>& particle,
743  int& firstT,
744  int& lastT)
745  {
747  firstT = -1;
748  lastT = -1;
749 
750  for (unsigned int icstat = 0; icstat < theGeometry->Ncryostats(); ++icstat) {
751  for (unsigned int itpc = 0; itpc < theGeometry->NTPC(icstat); ++itpc) {
752  int thisfirstT(-1), thislastT(-1);
753  LArPandoraInput::GetTrueStartAndEndPoints(icstat, itpc, particle, thisfirstT, thislastT);
754 
755  if (thisfirstT < 0) continue;
756 
757  if (firstT < 0 || thisfirstT < firstT) firstT = thisfirstT;
758 
759  if (lastT < 0 || thislastT > lastT) lastT = thislastT;
760  }
761  }
762  }
763 
764  //------------------------------------------------------------------------------------------------------------------------------------------
765 
766  void
768  const unsigned int tpc,
769  const art::Ptr<simb::MCParticle>& particle,
770  int& startT,
771  int& endT)
772  {
774 
775  bool foundStartPosition(false);
776  const int numTrajectoryPoints(static_cast<int>(particle->NumberTrajectoryPoints()));
777 
778  for (int nt = 0; nt < numTrajectoryPoints; ++nt) {
779  const double pos[3] = {particle->Vx(nt), particle->Vy(nt), particle->Vz(nt)};
780  geo::TPCID tpcID = theGeometry->FindTPCAtPosition(pos);
781 
782  if (!tpcID.isValid) continue;
783 
784  if (!(cstat == tpcID.Cryostat && tpc == tpcID.TPC)) continue;
785 
786  endT = nt;
787 
788  if (!foundStartPosition) {
789  startT = endT;
790  foundStartPosition = true;
791  }
792  }
793  }
794 
795  //------------------------------------------------------------------------------------------------------------------------------------------
796 
797  float
799  const art::Ptr<simb::MCParticle>& particle,
800  const int nt)
801  {
803  auto const clock_data = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(e);
804  auto const det_prop =
806 
807  unsigned int which_tpc(0);
808  unsigned int which_cstat(0);
809  double pos[3] = {particle->Vx(nt), particle->Vy(nt), particle->Vz(nt)};
810  theGeometry->PositionToTPC(pos, which_tpc, which_cstat);
811 
812  const float vtxT(particle->T(nt));
813  const float vtxTDC(clock_data.TPCG4Time2Tick(vtxT));
814  const float vtxTDC0(trigger_offset(clock_data));
815 
816  const geo::TPCGeo& theTpc = theGeometry->Cryostat(which_cstat).TPC(which_tpc);
817  const float driftDir((theTpc.DriftDirection() == geo::kNegX) ? +1.0 : -1.0);
818  return (driftDir * (vtxTDC - vtxTDC0) * det_prop.GetXTicksCoefficient());
819  }
820 
821  //------------------------------------------------------------------------------------------------------------------------------------------
822 
823  double
825  const Settings& settings,
826  const double hit_Charge,
827  const geo::View_t hit_View)
828  {
830 
831  // TODO: Unite this procedure with other calorimetry procedures under development
832  const double dQdX(hit_Charge / (theGeometry->WirePitch(hit_View))); // ADC/cm
833  const double dQdX_e(dQdX /
834  (detProp.ElectronsToADC() * settings.m_recombination_factor)); // e/cm
835  const double dEdX(settings.m_useBirksCorrection ?
836  detProp.BirksCorrection(dQdX_e) :
837  dQdX_e * 1000. / util::kGeVToElectrons); // MeV/cm
838  double mips(dEdX / settings.m_dEdX_mip);
839 
840  if (mips < 0.) mips = settings.m_mips_if_negative;
841 
842  if (mips > settings.m_mips_max) mips = settings.m_mips_max;
843 
844  return mips;
845  }
846 
847  //------------------------------------------------------------------------------------------------------------------------------------------
848 
849  void
851  {
852  // QGSP_BERT and EM standard physics list mappings
853  processMap["unknown"] = lar_content::MC_PROC_UNKNOWN;
854  processMap["primary"] = lar_content::MC_PROC_PRIMARY;
855  processMap["compt"] = lar_content::MC_PROC_COMPT;
856  processMap["phot"] = lar_content::MC_PROC_PHOT;
857  processMap["annihil"] = lar_content::MC_PROC_ANNIHIL;
858  processMap["eIoni"] = lar_content::MC_PROC_E_IONI;
859  processMap["eBrem"] = lar_content::MC_PROC_E_BREM;
860  processMap["conv"] = lar_content::MC_PROC_CONV;
861  processMap["muIoni"] = lar_content::MC_PROC_MU_IONI;
862  processMap["muMinusCaptureAtRest"] = lar_content::MC_PROC_MU_MINUS_CAPTURE_AT_REST;
863  processMap["neutronInelastic"] = lar_content::MC_PROC_NEUTRON_INELASTIC;
864  processMap["nCapture"] = lar_content::MC_PROC_N_CAPTURE;
865  processMap["hadElastic"] = lar_content::MC_PROC_HAD_ELASTIC;
866  processMap["Decay"] = lar_content::MC_PROC_DECAY;
867  processMap["CoulombScat"] = lar_content::MC_PROC_COULOMB_SCAT;
868  processMap["muBrems"] = lar_content::MC_PROC_MU_BREM;
869  processMap["muPairProd"] = lar_content::MC_PROC_MU_PAIR_PROD;
870  processMap["PhotonInelastic"] = lar_content::MC_PROC_PHOTON_INELASTIC;
871  processMap["hIoni"] = lar_content::MC_PROC_HAD_IONI;
872  processMap["protonInelastic"] = lar_content::MC_PROC_PROTON_INELASTIC;
873  processMap["pi+Inelastic"] = lar_content::MC_PROC_PI_PLUS_INELASTIC;
874  processMap["CHIPSNuclearCaptureAtRest"] = lar_content::MC_PROC_CHIPS_NUCLEAR_CAPTURE_AT_REST;
875  processMap["pi-Inelastic"] = lar_content::MC_PROC_PI_MINUS_INELASTIC;
876  processMap["Transportation"] = lar_content::MC_PROC_TRANSPORTATION;
877  processMap["Rayl"] = lar_content::MC_PROC_RAYLEIGH;
878  processMap["hBrems"] = lar_content::MC_PROC_HAD_BREM;
879  processMap["hPairProd"] = lar_content::MC_PROC_HAD_PAIR_PROD;
880  processMap["ionIoni"] = lar_content::MC_PROC_ION_IONI;
881  processMap["nKiller"] = lar_content::MC_PROC_NEUTRON_KILLER;
882  processMap["ionInelastic"] = lar_content::MC_PROC_ION_INELASTIC;
883  processMap["He3Inelastic"] = lar_content::MC_PROC_HE3_INELASTIC;
884  processMap["alphaInelastic"] = lar_content::MC_PROC_ALPHA_INELASTIC;
885  processMap["anti_He3Inelastic"] = lar_content::MC_PROC_ANTI_HE3_INELASTIC;
886  processMap["anti_alphaInelastic"] = lar_content::MC_PROC_ANTI_ALPHA_INELASTIC;
887  processMap["hFritiofCaptureAtRest"] = lar_content::MC_PROC_HAD_FRITIOF_CAPTURE_AT_REST;
888  processMap["anti_deuteronInelastic"] = lar_content::MC_PROC_ANTI_DEUTERON_INELASTIC;
889  processMap["anti_neutronInelastic"] = lar_content::MC_PROC_ANTI_NEUTRON_INELASTIC;
890  processMap["anti_protonInelastic"] = lar_content::MC_PROC_ANTI_PROTON_INELASTIC;
891  processMap["anti_tritonInelastic"] = lar_content::MC_PROC_ANTI_TRITON_INELASTIC;
892  processMap["dInelastic"] = lar_content::MC_PROC_DEUTERON_INELASTIC;
893  processMap["electronNuclear"] = lar_content::MC_PROC_ELECTRON_NUCLEAR;
894  processMap["photonNuclear"] = lar_content::MC_PROC_PHOTON_NUCLEAR;
895  processMap["kaon+Inelastic"] = lar_content::MC_PROC_KAON_PLUS_INELASTIC;
896  processMap["kaon-Inelastic"] = lar_content::MC_PROC_KAON_MINUS_INELASTIC;
897  processMap["hBertiniCaptureAtRest"] = lar_content::MC_PROC_HAD_BERTINI_CAPTURE_AT_REST;
898  processMap["lambdaInelastic"] = lar_content::MC_PROC_LAMBDA_INELASTIC;
899  processMap["muonNuclear"] = lar_content::MC_PROC_MU_NUCLEAR;
900  processMap["tInelastic"] = lar_content::MC_PROC_TRITON_INELASTIC;
901  processMap["primaryBackground"] = lar_content::MC_PROC_PRIMARY_BACKGROUND;
902  }
903 
904  //------------------------------------------------------------------------------------------------------------------------------------------
905  //------------------------------------------------------------------------------------------------------------------------------------------
906 
908  : m_pPrimaryPandora(nullptr)
909  , m_useHitWidths(true)
910  , m_useBirksCorrection(false)
911  , m_useActiveBoundingBox(false)
912  , m_uidOffset(100000000)
913  , m_hitCounterOffset(0)
914  , m_dx_cm(0.5)
915  , m_int_cm(84.)
916  , m_rad_cm(14.)
917  , m_dEdX_mip(2.)
918  , m_mips_max(50.)
919  , m_mips_if_negative(0.)
920  , m_mips_to_gev(3.5e-4)
921  , m_recombination_factor(0.63)
922  {}
923 
924 } // namespace lar_pandora
double E(const int i=0) const
Definition: MCParticle.h:233
virtual bool IsBad(raw::ChannelID_t channel) const =0
Returns whether the specified channel is bad in the current run.
simb::MCTruth TrackIdToMCTruth(int const id) const
unsigned int NumberTrajectoryPoints() const
Definition: MCParticle.h:218
Interface class for LArPandora producer modules, which reconstruct recob::PFParticles from recob::Hit...
int PdgCode() const
Definition: MCParticle.h:212
const simb::MCNeutrino & GetNeutrino() const
Definition: MCTruth.h:77
double Py(const int i=0) const
Definition: MCParticle.h:231
static void CreatePandoraMCParticles(const Settings &settings, const MCTruthToMCParticles &truthToParticles, const MCParticlesToMCTruth &particlesToTruth, const RawMCParticleVector &generatorMCParticleVector)
Create the Pandora MC particles from the MC particles.
static void CreatePandoraDetectorGaps(const Settings &settings, const LArDriftVolumeList &driftVolumeList, const LArDetectorGapList &listOfGaps)
Create pandora line gaps to cover dead regions between TPCs in a global drift volume approach...
WireGeo const & Wire(unsigned int iwire) const
Definition: PlaneGeo.cxx:506
enum geo::_plane_proj View_t
Enumerate the possible plane projections.
std::map< unsigned int, LArDriftVolume > LArDriftVolumeMap
Header file for the lar calo hit class.
geo::WireID WireID() const
Definition: Hit.h:233
static float GetTrueX0(const art::Event &evt, const art::Ptr< simb::MCParticle > &particle, const int nT)
Use detector and time services to get a true X offset for a given trajectory point.
int Mother() const
Definition: MCParticle.h:213
virtual geo::View_t TargetViewW(const geo::TPCID::TPCID_t tpc, const geo::CryostatID::CryostatID_t cstat) const =0
Map a LArSoft view to Pandora&#39;s W view.
std::map< art::Ptr< simb::MCParticle >, art::Ptr< simb::MCTruth > > MCParticlesToMCTruth
virtual PandoraApi::Geometry::LineGap::Parameters CreateLineGapParametersFromReadoutGaps(const geo::View_t view, const geo::TPCID::TPCID_t tpc, const geo::CryostatID::CryostatID_t cstat, const double firstXYZ[3], const double lastXYZ[3], const float halfWirePitch, const float xFirst, const float xLast, const pandora::Pandora *pPandora) const =0
Create the line gap parameters to give to the pandora API.
simb::Origin_t Origin() const
Definition: MCTruth.h:74
Empty interface to map pandora to specifics in the LArSoft geometry.
bool isValid
Whether this ID points to a valid element.
Definition: geo_types.h:211
Geometry information for a single TPC.
Definition: TPCGeo.h:38
enum simb::_ev_origin Origin_t
event origin types
double Px(const int i=0) const
Definition: MCParticle.h:230
std::vector< LArDriftVolume > LArDriftVolumeList
static void FindPrimaryParticles(const RawMCParticleVector &mcParticleVector, std::map< const simb::MCParticle, bool > &primaryMCParticleMap)
Find all primary MCParticles in a given vector of MCParticles.
const pandora::Pandora * m_pPrimaryPandora
CryostatID_t Cryostat
Index of cryostat.
Definition: geo_types.h:212
static unsigned int GetVolumeID(const LArDriftVolumeMap &driftVolumeMap, const unsigned int cstat, const unsigned int tpc)
Get drift volume ID from a specified cryostat/tpc pair.
float Integral() const
Integral under the calibrated signal waveform of the hit, in tick x ADC units.
Definition: Hit.h:224
geo::View_t View() const
View for the plane of the hit.
Definition: Hit.h:232
std::map< int, art::Ptr< recob::Hit > > IdToHitMap
Definition: ILArPandora.h:21
intermediate_table::const_iterator const_iterator
pandora::InputUInt m_larTPCVolumeId
The lar tpc volume id.
Definition: LArCaloHit.h:30
virtual geo::View_t TargetViewV(const geo::TPCID::TPCID_t tpc, const geo::CryostatID::CryostatID_t cstat) const =0
Map a LArSoft view to Pandora&#39;s V view.
uint8_t channel
Definition: CRTFragment.hh:201
std::unordered_map< std::string, int > processMap
Definition: AnaUtils.cxx:89
Drift towards negative X values.
Definition: geo_types.h:162
unsigned int Ncryostats() const
Returns the number of cryostats in the detector.
std::string Process() const
Definition: MCParticle.h:215
pandora::InputInt m_process
The process creating the particle.
Definition: LArMCParticle.h:86
geo::Length_t WirePitch(geo::PlaneID const &planeid) const
Returns the distance between two consecutive wires.
unsigned int Nwires(unsigned int p, unsigned int tpc=0, unsigned int cstat=0) const
Returns the total number of wires in the specified plane.
double dEdX(double KE, const simb::MCParticle *part)
art framework interface to geometry description
int TrackId() const
Definition: MCParticle.h:210
static bool IsPrimaryMCParticle(const art::Ptr< simb::MCParticle > &mcParticle, std::map< const simb::MCParticle, bool > &primaryMCParticleMap)
Check whether an MCParticle can be found in a given map.
geo::TPCGeo const & PositionToTPC(geo::Point_t const &point) const
Returns the TPC at specified location.
std::map< int, art::Ptr< simb::MCParticle > > MCParticleMap
std::map< art::Ptr< recob::Hit >, TrackIDEVector > HitsToTrackIDEs
virtual geo::View_t TargetViewU(const geo::TPCID::TPCID_t tpc, const geo::CryostatID::CryostatID_t cstat) const =0
Map a LArSoft view to Pandora&#39;s U view.
static unsigned int GetDaughterVolumeID(const LArDriftVolumeMap &driftVolumeMap, const unsigned int cstat, const unsigned int tpc)
Get daughter volume ID from a specified cryostat/tpc pair.
geo::TPCID FindTPCAtPosition(double const worldLoc[3]) const
Returns the ID of the TPC at specified location.
LAr calo hit parameters.
Definition: LArCaloHit.h:27
T abs(T value)
static double GetMips(const detinfo::DetectorPropertiesData &detProp, const Settings &settings, const double hit_Charge, const geo::View_t hit_View)
Convert charge in ADCs to approximate MIPs.
constexpr double kGeVToElectrons
23.6eV per ion pair, 1e9 eV/GeV
const double e
std::vector< simb::MCParticle > RawMCParticleVector
pandora::InputUInt m_daughterVolumeId
The daughter volume id.
Definition: LArCaloHit.h:31
virtual PandoraApi::Geometry::LineGap::Parameters CreateLineGapParametersFromDetectorGaps(const LArDetectorGap &gap) const =0
Create the line gap parameters to give to the pandora API.
std::map< art::Ptr< simb::MCTruth >, MCParticleVector > MCTruthToMCParticles
single particles thrown at the detector
Definition: MCTruth.h:26
static void CreatePandoraMCLinks2D(const Settings &settings, const HitMap &hitMap, const HitsToTrackIDEs &hitToParticleMap)
Create links between the 2D hits and Pandora MC particles.
Geometry information for a single wire plane.The plane is represented in the geometry by a solid whic...
Definition: PlaneGeo.h:82
double T(const int i=0) const
Definition: MCParticle.h:224
std::vector< art::Ptr< simb::MCParticle > > MCParticleVector
std::vector< sim::TrackIDE > TrackIDEVector
CryostatGeo const & Cryostat(geo::CryostatID const &cryoid) const
Returns the specified cryostat.
static void FillMCProcessMap(MCProcessMap &processMap)
Populate a map from MC process string to enumeration.
Class providing information about the quality of channels.
static int max(int a, int b)
The data type to uniquely identify a TPC.
Definition: geo_types.h:386
DriftDirection_t DriftDirection() const
Returns an enumerator value describing the drift direction.
Definition: TPCGeo.h:144
float PeakTimeMinusRMS(float sigmas=+1.) const
Definition: Hit.h:239
LArMCParticleFactory responsible for object creation.
Detector simulation of raw signals on wires.
static void CreatePandoraReadoutGaps(const Settings &settings, const LArDriftVolumeMap &driftVolumeMap)
Create pandora line gaps to cover any (continuous regions of) bad channels.
unsigned int NTPC(unsigned int cstat=0) const
Returns the total number of TPCs in the specified cryostat.
LAr mc particle parameters.
Definition: LArMCParticle.h:82
double Vx(const int i=0) const
Definition: MCParticle.h:221
raw::ChannelID_t PlaneWireToChannel(WireID const &wireid) const
Returns the ID of the TPC channel connected to the specified wire.
float PeakTime() const
Time of the signal peak, in tick units.
Definition: Hit.h:218
std::vector< art::Ptr< recob::Hit > > HitVector
Declaration of signal hit object.
static void CreatePandoraLArTPCs(const Settings &settings, const LArDriftVolumeList &driftVolumeList)
Create pandora LArTPCs to represent the different drift volumes in use.
LArPandoraDetectorType * GetDetectorType()
Factory class that returns the correct detector type interface.
Encapsulate the construction of a single detector plane.
const TPCGeo & TPC(unsigned int itpc) const
Return the itpc&#39;th TPC in the cryostat.
Definition: CryostatGeo.cxx:93
std::map< std::string, lar_content::MCProcess > MCProcessMap
std::vector< LArDetectorGap > LArDetectorGapList
Helper functions for providing inputs to pandora.
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
double BirksCorrection(double dQdX) const
dQ/dX in electrons/cm, returns dE/dX in MeV/cm.
pandora::InputInt m_nuanceCode
The nuance code.
Definition: LArMCParticle.h:85
E
Definition: 018_def.c:13
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
double Pz(const int i=0) const
Definition: MCParticle.h:232
Interface for experiment-specific channel quality info provider.
double Vz(const int i=0) const
Definition: MCParticle.h:223
int trigger_offset(DetectorClocksData const &data)
static void CreatePandoraHits2D(const art::Event &evt, const Settings &settings, const LArDriftVolumeMap &driftVolumeMap, const HitVector &hitVector, IdToHitMap &idToHitMap)
Create the Pandora 2D hits from the ART hits.
LArCaloHitFactory responsible for object creation.
Definition: LArCaloHit.h:110
TPCGeo const & TPC(unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified TPC.
drift volume class to hold properties of drift volume
PlaneGeo const & Plane(geo::View_t view) const
Return the plane in the tpc with View_t view.
Definition: TPCGeo.cxx:263
void GetCenter(double *xyz, double localz=0.0) const
Fills the world coordinate of a point on the wire.
Definition: WireGeo.cxx:73
bool NeutrinoSet() const
Definition: MCTruth.h:78
float PeakTimePlusRMS(float sigmas=+1.) const
Returns a time sigmas RMS away from the peak time.
Definition: Hit.h:236
unsigned int ChannelID_t
Type representing the ID of a readout channel.
Definition: RawTypes.h:28
TPCID_t TPC
Index of the TPC within its cryostat.
Definition: geo_types.h:406
Interface for experiment-specific service for channel quality info.
Collection of Physical constants used in LArSoft.
Event generator information.
Definition: MCNeutrino.h:18
Helper functions for extracting detector geometry for use in reconsruction.
Ionization energy from a Geant4 track.
Definition: SimChannel.h:25
double Vy(const int i=0) const
Definition: MCParticle.h:222
constexpr Point origin()
Returns a origin position with a point of the specified type.
Definition: geo_vectors.h:227
static void GetTrueStartAndEndPoints(const Settings &settings, const art::Ptr< simb::MCParticle > &particle, int &startT, int &endT)
Loop over MC trajectory points and identify start and end points within the detector.
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
Cosmic rays.
Definition: MCTruth.h:24
drift volume class to hold properties of drift volume
QTextStream & endl(QTextStream &s)
Encapsulate the construction of a single detector plane.