All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Classes | Static Public Member Functions | Private Types | Static Private Member Functions | List of all members
lar_pandora::LArPandoraInput Class Reference

LArPandoraInput class. More...

#include <LArPandoraInput.h>

Classes

class  Settings
 Settings class. More...
 

Static Public Member Functions

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. More...
 
static void CreatePandoraLArTPCs (const Settings &settings, const LArDriftVolumeList &driftVolumeList)
 Create pandora LArTPCs to represent the different drift volumes in use. More...
 
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. More...
 
static void CreatePandoraReadoutGaps (const Settings &settings, const LArDriftVolumeMap &driftVolumeMap)
 Create pandora line gaps to cover any (continuous regions of) bad channels. More...
 
static void CreatePandoraMCParticles (const Settings &settings, const MCTruthToMCParticles &truthToParticles, const MCParticlesToMCTruth &particlesToTruth, const RawMCParticleVector &generatorMCParticleVector)
 Create the Pandora MC particles from the MC particles. More...
 
static void FindPrimaryParticles (const RawMCParticleVector &mcParticleVector, std::map< const simb::MCParticle, bool > &primaryMCParticleMap)
 Find all primary MCParticles in a given vector of MCParticles. More...
 
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. More...
 
static void CreatePandoraMCLinks2D (const Settings &settings, const HitMap &hitMap, const HitsToTrackIDEs &hitToParticleMap)
 Create links between the 2D hits and Pandora MC particles. More...
 

Private Types

typedef std::map< std::string,
lar_content::MCProcess
MCProcessMap
 

Static Private Member Functions

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. More...
 
static void GetTrueStartAndEndPoints (const unsigned int cstat, const unsigned int tpc, const art::Ptr< simb::MCParticle > &particle, int &startT, int &endT)
 Loop over MC trajectory points and identify start and end points within a given cryostat and TPC. More...
 
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. More...
 
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. More...
 
static void FillMCProcessMap (MCProcessMap &processMap)
 Populate a map from MC process string to enumeration. More...
 

Detailed Description

LArPandoraInput class.

Definition at line 27 of file LArPandoraInput.h.

Member Typedef Documentation

Definition at line 141 of file LArPandoraInput.h.

Member Function Documentation

void lar_pandora::LArPandoraInput::CreatePandoraDetectorGaps ( const Settings settings,
const LArDriftVolumeList driftVolumeList,
const LArDetectorGapList listOfGaps 
)
static

Create pandora line gaps to cover dead regions between TPCs in a global drift volume approach.

Parameters
settingsthe settings
driftVolumeListthe drift volume list
listOfGapsthe list of gaps

Definition at line 245 of file LArPandoraInput.cxx.

248  {
249  //ATTN - Unlike SP, DP detector gaps are not in the drift direction
250  art::ServiceHandle<geo::Geometry const> theGeometry;
251  LArPandoraDetectorType* detType(detector_functions::GetDetectorType());
252 
253  mf::LogDebug("LArPandora") << " *** LArPandoraInput::CreatePandoraDetectorGaps(...) *** "
254  << std::endl;
255 
256  if (!settings.m_pPrimaryPandora)
257  throw cet::exception("LArPandora")
258  << "CreatePandoraDetectorGaps - primary Pandora instance does not exist ";
259 
260  const pandora::Pandora* pPandora(settings.m_pPrimaryPandora);
261 
262  for (const LArDetectorGap& gap : listOfGaps) {
264 
265  try {
266  parameters = detType->CreateLineGapParametersFromDetectorGaps(gap);
267  }
268  catch (const pandora::StatusCodeException&) {
269  mf::LogWarning("LArPandora")
270  << "CreatePandoraDetectorGaps - invalid line gap parameter provided, all assigned values "
271  "must be finite, line gap omitted "
272  << std::endl;
273  continue;
274  }
275  try {
276  PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS,
277  !=,
278  PandoraApi::Geometry::LineGap::Create(*pPandora, parameters));
279  }
280  catch (const pandora::StatusCodeException&) {
281  mf::LogWarning("LArPandora") << "CreatePandoraDetectorGaps - unable to create line gap, "
282  "insufficient or invalid information supplied "
283  << std::endl;
284  continue;
285  }
286  }
287  }
fhicl::Table< sbnd::crt::CRTDetSimParams > Parameters
LArPandoraDetectorType * GetDetectorType()
Factory class that returns the correct detector type interface.
void lar_pandora::LArPandoraInput::CreatePandoraHits2D ( const art::Event &  evt,
const Settings settings,
const LArDriftVolumeMap driftVolumeMap,
const HitVector hitVector,
IdToHitMap idToHitMap 
)
static

Create the Pandora 2D hits from the ART hits.

Parameters
evtart event being processed
settingsthe settings
driftVolumeMapthe mapping from volume id to drift volume
hitsthe input list of ART hits for this event
idToHitMapto receive the mapping from Pandora hit ID to ART hit

Definition at line 45 of file LArPandoraInput.cxx.

50  {
51  mf::LogDebug("LArPandora") << " *** LArPandoraInput::CreatePandoraHits2D(...) *** "
52  << std::endl;
53 
54  if (!settings.m_pPrimaryPandora)
55  throw cet::exception("LArPandora")
56  << "CreatePandoraHits2D - primary Pandora instance does not exist ";
57 
58  const pandora::Pandora* pPandora(settings.m_pPrimaryPandora);
59 
60  art::ServiceHandle<geo::Geometry const> theGeometry;
61  auto const detProp = art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(e);
62  LArPandoraDetectorType* detType(detector_functions::GetDetectorType());
63 
64  // Loop over ART hits
65  int hitCounter(settings.m_hitCounterOffset);
66 
67  lar_content::LArCaloHitFactory caloHitFactory;
68 
69  for (HitVector::const_iterator iter = hitVector.begin(), iterEnd = hitVector.end();
70  iter != iterEnd;
71  ++iter) {
72  const art::Ptr<recob::Hit> hit = *iter;
73  const geo::WireID hit_WireID(hit->WireID());
74 
75  // Get basic hit properties (view, time, charge)
76  const geo::View_t hit_View(hit->View());
77  const double hit_Charge(hit->Integral());
78  const double hit_Time(hit->PeakTime());
79  const double hit_TimeStart(hit->PeakTimeMinusRMS());
80  const double hit_TimeEnd(hit->PeakTimePlusRMS());
81 
82  // Get hit X coordinate and, if using a single global drift volume, remove any out-of-time hits here
83  const double xpos_cm(
84  detProp.ConvertTicksToX(hit_Time, hit_WireID.Plane, hit_WireID.TPC, hit_WireID.Cryostat));
85  const double dxpos_cm(
86  std::fabs(detProp.ConvertTicksToX(
87  hit_TimeEnd, hit_WireID.Plane, hit_WireID.TPC, hit_WireID.Cryostat) -
88  detProp.ConvertTicksToX(
89  hit_TimeStart, hit_WireID.Plane, hit_WireID.TPC, hit_WireID.Cryostat)));
90 
91  // Get hit Y and Z coordinates, based on central position of wire
92  double xyz[3];
93  theGeometry->Cryostat(hit_WireID.Cryostat)
94  .TPC(hit_WireID.TPC)
95  .Plane(hit_WireID.Plane)
96  .Wire(hit_WireID.Wire)
97  .GetCenter(xyz);
98  const double y0_cm(xyz[1]);
99  const double z0_cm(xyz[2]);
100 
101  // Get other hit properties here
102  const double wire_pitch_cm(theGeometry->WirePitch(hit_View)); // cm
103  const double mips(LArPandoraInput::GetMips(detProp, settings, hit_Charge, hit_View));
104 
105  // Create Pandora CaloHit
106  lar_content::LArCaloHitParameters caloHitParameters;
107 
108  try {
109  caloHitParameters.m_expectedDirection = pandora::CartesianVector(0., 0., 1.);
110  caloHitParameters.m_cellNormalVector = pandora::CartesianVector(0., 0., 1.);
111  caloHitParameters.m_cellSize0 = settings.m_dx_cm;
112  caloHitParameters.m_cellSize1 = (settings.m_useHitWidths ? dxpos_cm : settings.m_dx_cm);
113  caloHitParameters.m_cellThickness = wire_pitch_cm;
114  caloHitParameters.m_cellGeometry = pandora::RECTANGULAR;
115  caloHitParameters.m_time = 0.;
116  caloHitParameters.m_nCellRadiationLengths = settings.m_dx_cm / settings.m_rad_cm;
117  caloHitParameters.m_nCellInteractionLengths = settings.m_dx_cm / settings.m_int_cm;
118  caloHitParameters.m_isDigital = false;
119  caloHitParameters.m_hitRegion = pandora::SINGLE_REGION;
120  caloHitParameters.m_layer = 0;
121  caloHitParameters.m_isInOuterSamplingLayer = false;
122  caloHitParameters.m_inputEnergy = hit_Charge;
123  caloHitParameters.m_mipEquivalentEnergy = mips;
124  caloHitParameters.m_electromagneticEnergy = mips * settings.m_mips_to_gev;
125  caloHitParameters.m_hadronicEnergy = mips * settings.m_mips_to_gev;
126  caloHitParameters.m_pParentAddress = (void*)((intptr_t)(++hitCounter));
127  caloHitParameters.m_larTPCVolumeId =
128  LArPandoraGeometry::GetVolumeID(driftVolumeMap, hit_WireID.Cryostat, hit_WireID.TPC);
130  driftVolumeMap, hit_WireID.Cryostat, hit_WireID.TPC);
131 
132  if (hit_View == detType->TargetViewW(hit_WireID.TPC, hit_WireID.Cryostat)) {
133  caloHitParameters.m_hitType = pandora::TPC_VIEW_W;
134  const double wpos_cm(
135  pPandora->GetPlugins()->GetLArTransformationPlugin()->YZtoW(y0_cm, z0_cm));
136  caloHitParameters.m_positionVector = pandora::CartesianVector(xpos_cm, 0., wpos_cm);
137  }
138  else if (hit_View == detType->TargetViewU(hit_WireID.TPC, hit_WireID.Cryostat)) {
139  caloHitParameters.m_hitType = pandora::TPC_VIEW_U;
140  const double upos_cm(
141  pPandora->GetPlugins()->GetLArTransformationPlugin()->YZtoU(y0_cm, z0_cm));
142  caloHitParameters.m_positionVector = pandora::CartesianVector(xpos_cm, 0., upos_cm);
143  }
144  else if (hit_View == detType->TargetViewV(hit_WireID.TPC, hit_WireID.Cryostat)) {
145  caloHitParameters.m_hitType = pandora::TPC_VIEW_V;
146  const double vpos_cm(
147  pPandora->GetPlugins()->GetLArTransformationPlugin()->YZtoV(y0_cm, z0_cm));
148  caloHitParameters.m_positionVector = pandora::CartesianVector(xpos_cm, 0., vpos_cm);
149  }
150  else {
151  throw cet::exception("LArPandora")
152  << "CreatePandoraHits2D - this wire view not recognised (View=" << hit_View << ") ";
153  }
154  }
155  catch (const pandora::StatusCodeException&) {
156  mf::LogWarning("LArPandora")
157  << "CreatePandoraHits2D - invalid calo hit parameter provided, all assigned values must "
158  "be finite, calo hit omitted "
159  << std::endl;
160  continue;
161  }
162 
163  // Store the hit address
164  if (hitCounter >= settings.m_uidOffset)
165  throw cet::exception("LArPandora")
166  << "CreatePandoraHits2D - detected an excessive number of hits (" << hitCounter << ") ";
167 
168  idToHitMap[hitCounter] = hit;
169 
170  // Create the Pandora hit
171  try {
172  PANDORA_THROW_RESULT_IF(
173  pandora::STATUS_CODE_SUCCESS,
174  !=,
175  PandoraApi::CaloHit::Create(*pPandora, caloHitParameters, caloHitFactory));
176  }
177  catch (const pandora::StatusCodeException&) {
178  mf::LogWarning("LArPandora") << "CreatePandoraHits2D - unable to create calo hit, "
179  "insufficient or invalid information supplied "
180  << std::endl;
181  continue;
182  }
183  }
184  }
enum geo::_plane_proj View_t
Enumerate the possible plane projections.
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.
pandora::InputUInt m_larTPCVolumeId
The lar tpc volume id.
Definition: LArCaloHit.h:30
process_name hit
Definition: cheaterreco.fcl:51
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.
LAr calo hit parameters.
Definition: LArCaloHit.h:27
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.
pandora::InputUInt m_daughterVolumeId
The daughter volume id.
Definition: LArCaloHit.h:31
LArPandoraDetectorType * GetDetectorType()
Factory class that returns the correct detector type interface.
do i e
LArCaloHitFactory responsible for object creation.
Definition: LArCaloHit.h:110
auto const detProp
void lar_pandora::LArPandoraInput::CreatePandoraLArTPCs ( const Settings settings,
const LArDriftVolumeList driftVolumeList 
)
static

Create pandora LArTPCs to represent the different drift volumes in use.

Parameters
settingsthe settings
driftVolumeListthe drift volume list

Definition at line 189 of file LArPandoraInput.cxx.

191  {
192  mf::LogDebug("LArPandora") << " *** LArPandoraInput::CreatePandoraLArTPCs(...) *** "
193  << std::endl;
194 
195  if (!settings.m_pPrimaryPandora)
196  throw cet::exception("LArPandora")
197  << "CreatePandoraDetectorGaps - primary Pandora instance does not exist ";
198 
199  const pandora::Pandora* pPandora(settings.m_pPrimaryPandora);
200 
201  for (const LArDriftVolume& driftVolume : driftVolumeList) {
203 
204  try {
205  parameters.m_larTPCVolumeId = driftVolume.GetVolumeID();
206  parameters.m_centerX = driftVolume.GetCenterX();
207  parameters.m_centerY = driftVolume.GetCenterY();
208  parameters.m_centerZ = driftVolume.GetCenterZ();
209  parameters.m_widthX = driftVolume.GetWidthX();
210  parameters.m_widthY = driftVolume.GetWidthY();
211  parameters.m_widthZ = driftVolume.GetWidthZ();
212  parameters.m_wirePitchU = driftVolume.GetWirePitchU();
213  parameters.m_wirePitchV = driftVolume.GetWirePitchV();
214  parameters.m_wirePitchW = driftVolume.GetWirePitchW();
215  parameters.m_wireAngleU = driftVolume.GetWireAngleU();
216  parameters.m_wireAngleV = driftVolume.GetWireAngleV();
217  parameters.m_wireAngleW = driftVolume.GetWireAngleW();
218  parameters.m_sigmaUVW = driftVolume.GetSigmaUVZ();
219  parameters.m_isDriftInPositiveX = driftVolume.IsPositiveDrift();
220  }
221  catch (const pandora::StatusCodeException&) {
222  mf::LogWarning("LArPandora") << "CreatePandoraLArTPCs - invalid tpc parameter provided, "
223  "all assigned values must be finite, tpc omitted "
224  << std::endl;
225  continue;
226  }
227 
228  try {
229  PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS,
230  !=,
231  PandoraApi::Geometry::LArTPC::Create(*pPandora, parameters));
232  }
233  catch (const pandora::StatusCodeException&) {
234  mf::LogWarning("LArPandora") << "CreatePandoraLArTPCs - unable to create tpc, insufficient "
235  "or invalid information supplied "
236  << std::endl;
237  continue;
238  }
239  }
240  }
fhicl::Table< sbnd::crt::CRTDetSimParams > Parameters
void lar_pandora::LArPandoraInput::CreatePandoraMCLinks2D ( const Settings settings,
const HitMap hitMap,
const HitsToTrackIDEs hitToParticleMap 
)
static

Create links between the 2D hits and Pandora MC particles.

Parameters
settingsthe settings
hitMapmapping from Pandora hit addresses to ART hits
hitToParticleMapmapping from each ART hit to its underlying G4 track ID

Definition at line 686 of file LArPandoraInput.cxx.

689  {
690  mf::LogDebug("LArPandora") << " *** LArPandoraInput::CreatePandoraMCLinks(...) *** "
691  << std::endl;
692 
693  if (!settings.m_pPrimaryPandora)
694  throw cet::exception("LArPandora")
695  << "CreatePandoraMCLinks2D - primary Pandora instance does not exist ";
696 
697  const pandora::Pandora* pPandora(settings.m_pPrimaryPandora);
698 
699  for (IdToHitMap::const_iterator iterI = idToHitMap.begin(), iterEndI = idToHitMap.end();
700  iterI != iterEndI;
701  ++iterI) {
702  const int hitID(iterI->first);
703  const art::Ptr<recob::Hit> hit(iterI->second);
704  // const geo::WireID hit_WireID(hit->WireID());
705 
706  // Get list of associated MC particles
707  HitsToTrackIDEs::const_iterator iterJ = hitToParticleMap.find(hit);
708 
709  if (hitToParticleMap.end() == iterJ) continue;
710 
711  const TrackIDEVector& trackCollection = iterJ->second;
712 
713  if (trackCollection.size() == 0)
714  throw cet::exception("LArPandora")
715  << "CreatePandoraMCLinks2D - found a hit without any associated MC truth information ";
716 
717  // Create links between hits and MC particles
718  for (unsigned int k = 0; k < trackCollection.size(); ++k) {
719  const sim::TrackIDE trackIDE(trackCollection.at(k));
720  const int trackID(std::abs(trackIDE.trackID)); // TODO: Find out why std::abs is needed
721  const float energyFrac(trackIDE.energyFrac);
722 
723  try {
724  PANDORA_THROW_RESULT_IF(
725  pandora::STATUS_CODE_SUCCESS,
726  !=,
727  PandoraApi::SetCaloHitToMCParticleRelationship(
728  *pPandora, (void*)((intptr_t)hitID), (void*)((intptr_t)trackID), energyFrac));
729  }
730  catch (const pandora::StatusCodeException&) {
731  mf::LogWarning("LArPandora") << "CreatePandoraMCLinks2D - unable to create calo hit to "
732  "mc particle relationship, invalid information supplied "
733  << std::endl;
734  continue;
735  }
736  }
737  }
738  }
process_name hit
Definition: cheaterreco.fcl:51
T abs(T value)
std::vector< sim::TrackIDE > TrackIDEVector
pdgs k
Definition: selectors.fcl:22
Ionization energy from a Geant4 track.
Definition: SimChannel.h:26
void lar_pandora::LArPandoraInput::CreatePandoraMCParticles ( const Settings settings,
const MCTruthToMCParticles truthToParticles,
const MCParticlesToMCTruth particlesToTruth,
const RawMCParticleVector generatorMCParticleVector 
)
static

Create the Pandora MC particles from the MC particles.

Parameters
settingsthe settings
truthToParticlesmapping from MC truth to MC particles
particlesToTruthmapping from MC particles to MC truth

Definition at line 397 of file LArPandoraInput.cxx.

401  {
402  mf::LogDebug("LArPandora") << " *** LArPandoraInput::CreatePandoraMCParticles(...) *** "
403  << std::endl;
404  art::ServiceHandle<cheat::ParticleInventoryService const> particleInventoryService;
405 
406  if (!settings.m_pPrimaryPandora)
407  throw cet::exception("LArPandora")
408  << "CreatePandoraMCParticles - primary Pandora instance does not exist ";
409 
410  const pandora::Pandora* pPandora(settings.m_pPrimaryPandora);
411 
412  // Make indexed list of MC particles
413  MCParticleMap particleMap;
414 
415  for (MCParticlesToMCTruth::const_iterator iter = particleToTruthMap.begin(),
416  iterEnd = particleToTruthMap.end();
417  iter != iterEnd;
418  ++iter) {
419  const art::Ptr<simb::MCParticle> particle = iter->first;
420  particleMap[particle->TrackId()] = particle;
421  }
422 
423  // Loop over MC truth objects
424  int neutrinoCounter(0);
425 
426  lar_content::LArMCParticleFactory mcParticleFactory;
427 
428  for (MCTruthToMCParticles::const_iterator iter1 = truthToParticleMap.begin(),
429  iterEnd1 = truthToParticleMap.end();
430  iter1 != iterEnd1;
431  ++iter1) {
432  const art::Ptr<simb::MCTruth> truth = iter1->first;
433 
434  if (truth->NeutrinoSet()) {
435  const simb::MCNeutrino neutrino(truth->GetNeutrino());
436  ++neutrinoCounter;
437 
438  if (neutrinoCounter >= settings.m_uidOffset)
439  throw cet::exception("LArPandora")
440  << "CreatePandoraMCParticles - detected an excessive number of mc neutrinos ("
441  << neutrinoCounter << ")";
442 
443  const int neutrinoID(neutrinoCounter + 9 * settings.m_uidOffset);
444 
445  // Create Pandora 3D MC Particle
446  lar_content::LArMCParticleParameters mcParticleParameters;
447 
448  try {
449  mcParticleParameters.m_nuanceCode = neutrino.InteractionType();
450  mcParticleParameters.m_process = lar_content::MC_PROC_INCIDENT_NU;
451  mcParticleParameters.m_energy = neutrino.Nu().E();
452  mcParticleParameters.m_momentum =
453  pandora::CartesianVector(neutrino.Nu().Px(), neutrino.Nu().Py(), neutrino.Nu().Pz());
454  mcParticleParameters.m_vertex =
455  pandora::CartesianVector(neutrino.Nu().Vx(), neutrino.Nu().Vy(), neutrino.Nu().Vz());
456  mcParticleParameters.m_endpoint =
457  pandora::CartesianVector(neutrino.Nu().Vx(), neutrino.Nu().Vy(), neutrino.Nu().Vz());
458  mcParticleParameters.m_particleId = neutrino.Nu().PdgCode();
459  mcParticleParameters.m_mcParticleType = pandora::MC_3D;
460  mcParticleParameters.m_pParentAddress = (void*)((intptr_t)neutrinoID);
461  }
462  catch (const pandora::StatusCodeException&) {
463  mf::LogWarning("LArPandora")
464  << "CreatePandoraMCParticles - invalid mc neutrino parameter provided, all assigned "
465  "values must be finite, mc neutrino omitted "
466  << std::endl;
467  continue;
468  }
469 
470  try {
471  PANDORA_THROW_RESULT_IF(
472  pandora::STATUS_CODE_SUCCESS,
473  !=,
474  PandoraApi::MCParticle::Create(*pPandora, mcParticleParameters, mcParticleFactory));
475  }
476  catch (const pandora::StatusCodeException&) {
477  mf::LogWarning("LArPandora") << "CreatePandoraMCParticles - unable to create mc "
478  "neutrino, insufficient or invalid information supplied "
479  << std::endl;
480  continue;
481  }
482 
483  // Loop over associated particles
484  const MCParticleVector& particleVector = iter1->second;
485 
486  for (MCParticleVector::const_iterator iter2 = particleVector.begin(),
487  iterEnd2 = particleVector.end();
488  iter2 != iterEnd2;
489  ++iter2) {
490  const art::Ptr<simb::MCParticle> particle = *iter2;
491  const int trackID(particle->TrackId());
492 
493  // Mother/Daughter Links
494  if (particle->Mother() == 0) {
495  try {
496  PANDORA_THROW_RESULT_IF(
497  pandora::STATUS_CODE_SUCCESS,
498  !=,
499  PandoraApi::SetMCParentDaughterRelationship(
500  *pPandora, (void*)((intptr_t)neutrinoID), (void*)((intptr_t)trackID)));
501  }
502  catch (const pandora::StatusCodeException&) {
503  mf::LogWarning("LArPandora") << "CreatePandoraMCParticles - unable to create mc "
504  "particle relationship, invalid information supplied "
505  << std::endl;
506  continue;
507  }
508  }
509  }
510  }
511  }
512 
513  mf::LogDebug("LArPandora") << " Number of Pandora neutrinos: " << neutrinoCounter
514  << std::endl;
515 
516  // Loop over G4 particles
517  int particleCounter(0);
518 
519  // Find Primary Generator Particles
520  std::map<const simb::MCParticle, bool> primaryGeneratorMCParticleMap;
521  LArPandoraInput::FindPrimaryParticles(generatorMCParticleVector, primaryGeneratorMCParticleMap);
522 
523  for (MCParticleMap::const_iterator iterI = particleMap.begin(), iterEndI = particleMap.end();
524  iterI != iterEndI;
525  ++iterI) {
526  const art::Ptr<simb::MCParticle> particle = iterI->second;
527 
528  if (particle->TrackId() != iterI->first)
529  throw cet::exception("LArPandora") << "CreatePandoraMCParticles - mc truth information "
530  "appears to be scrambled in this event";
531 
532  if (particle->TrackId() >= settings.m_uidOffset)
533  throw cet::exception("LArPandora")
534  << "CreatePandoraMCParticles - detected an excessive number of MC particles ("
535  << particle->TrackId() << ")";
536 
537  ++particleCounter;
538 
539  // Find start and end trajectory points
540  int firstT(-1), lastT(-1);
541  LArPandoraInput::GetTrueStartAndEndPoints(settings, particle, firstT, lastT);
542 
543  if (firstT < 0 && lastT < 0) {
544  firstT = 0;
545  lastT = 0;
546  }
547 
548  // Lookup position and kinematics at start and end points
549  const float vtxX(particle->Vx(firstT));
550  const float vtxY(particle->Vy(firstT));
551  const float vtxZ(particle->Vz(firstT));
552 
553  const float endX(particle->Vx(lastT));
554  const float endY(particle->Vy(lastT));
555  const float endZ(particle->Vz(lastT));
556 
557  const float pX(particle->Px(firstT));
558  const float pY(particle->Py(firstT));
559  const float pZ(particle->Pz(firstT));
560  const float E(particle->E(firstT));
561 
562  // Find the source of the mc particle
563  int nuanceCode(0);
564  const int trackID(particle->TrackId());
565  const simb::Origin_t origin(particleInventoryService->TrackIdToMCTruth(trackID).Origin());
566 
567  if (LArPandoraInput::IsPrimaryMCParticle(particle, primaryGeneratorMCParticleMap)) {
568  nuanceCode = 2001;
569  }
570  else if (simb::kCosmicRay == origin) {
571  nuanceCode = 3000;
572  }
573  else if (simb::kSingleParticle == origin) {
574  nuanceCode = 2000;
575  }
576 
577  // Create 3D Pandora MC Particle
578  lar_content::LArMCParticleParameters mcParticleParameters;
579 
580  try {
581  MCProcessMap processMap;
582  FillMCProcessMap(processMap);
583  mcParticleParameters.m_nuanceCode = nuanceCode;
584  if (processMap.find(particle->Process()) != processMap.end()) {
585  mcParticleParameters.m_process = processMap[particle->Process()];
586  }
587  else {
588  mcParticleParameters.m_process = lar_content::MC_PROC_UNKNOWN;
589  mf::LogWarning("LArPandora")
590  << "CreatePandoraMCParticles - found an unknown process" << std::endl;
591  }
592  mcParticleParameters.m_energy = E;
593  mcParticleParameters.m_particleId = particle->PdgCode();
594  mcParticleParameters.m_momentum = pandora::CartesianVector(pX, pY, pZ);
595  mcParticleParameters.m_vertex = pandora::CartesianVector(vtxX, vtxY, vtxZ);
596  mcParticleParameters.m_endpoint = pandora::CartesianVector(endX, endY, endZ);
597  mcParticleParameters.m_mcParticleType = pandora::MC_3D;
598  mcParticleParameters.m_pParentAddress = (void*)((intptr_t)particle->TrackId());
599  }
600  catch (const pandora::StatusCodeException&) {
601  mf::LogWarning("LArPandora")
602  << "CreatePandoraMCParticles - invalid mc particle parameter provided, all assigned "
603  "values must be finite, mc particle omitted "
604  << std::endl;
605  continue;
606  }
607 
608  try {
609  PANDORA_THROW_RESULT_IF(
610  pandora::STATUS_CODE_SUCCESS,
611  !=,
612  PandoraApi::MCParticle::Create(*pPandora, mcParticleParameters, mcParticleFactory));
613  }
614  catch (const pandora::StatusCodeException&) {
615  mf::LogWarning("LArPandora") << "CreatePandoraMCParticles - unable to create mc particle, "
616  "insufficient or invalid information supplied "
617  << std::endl;
618  continue;
619  }
620 
621  // Create Mother/Daughter Links between 3D MC Particles
622  const int id_mother(particle->Mother());
623  MCParticleMap::const_iterator iterJ = particleMap.find(id_mother);
624 
625  if (iterJ != particleMap.end()) {
626  try {
627  PANDORA_THROW_RESULT_IF(
628  pandora::STATUS_CODE_SUCCESS,
629  !=,
630  PandoraApi::SetMCParentDaughterRelationship(
631  *pPandora, (void*)((intptr_t)id_mother), (void*)((intptr_t)particle->TrackId())));
632  }
633  catch (const pandora::StatusCodeException&) {
634  mf::LogWarning("LArPandora") << "CreatePandoraMCParticles - Unable to create mc particle "
635  "relationship, invalid information supplied "
636  << std::endl;
637  continue;
638  }
639  }
640  }
641 
642  mf::LogDebug("LArPandora") << "Number of mc particles: " << particleCounter << std::endl;
643  }
static void FindPrimaryParticles(const RawMCParticleVector &mcParticleVector, std::map< const simb::MCParticle, bool > &primaryMCParticleMap)
Find all primary MCParticles in a given vector of MCParticles.
process_name E
pandora::InputInt m_process
The process creating the particle.
Definition: LArMCParticle.h:86
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.
std::map< int, art::Ptr< simb::MCParticle > > MCParticleMap
std::vector< art::Ptr< simb::MCParticle > > MCParticleVector
const Cut kCosmicRay
static void FillMCProcessMap(MCProcessMap &processMap)
Populate a map from MC process string to enumeration.
LArMCParticleFactory responsible for object creation.
LAr mc particle parameters.
Definition: LArMCParticle.h:82
std::map< std::string, lar_content::MCProcess > MCProcessMap
pandora::InputInt m_nuanceCode
The nuance code.
Definition: LArMCParticle.h:85
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.
void lar_pandora::LArPandoraInput::CreatePandoraReadoutGaps ( const Settings settings,
const LArDriftVolumeMap driftVolumeMap 
)
static

Create pandora line gaps to cover any (continuous regions of) bad channels.

Parameters
settingsthe settings
driftVolumeMapthe mapping from volume id to drift volume

Definition at line 292 of file LArPandoraInput.cxx.

294  {
295  mf::LogDebug("LArPandora") << " *** LArPandoraInput::CreatePandoraReadoutGaps(...) *** "
296  << std::endl;
297 
298  if (!settings.m_pPrimaryPandora)
299  throw cet::exception("LArPandora")
300  << "CreatePandoraReadoutGaps - primary Pandora instance does not exist ";
301 
302  const pandora::Pandora* pPandora(settings.m_pPrimaryPandora);
303 
304  art::ServiceHandle<geo::Geometry const> theGeometry;
305  const lariov::ChannelStatusProvider& channelStatus(
306  art::ServiceHandle<lariov::ChannelStatusService const>()->GetProvider());
307 
308  LArPandoraDetectorType* detType(detector_functions::GetDetectorType());
309 
310  for (unsigned int icstat = 0; icstat < theGeometry->Ncryostats(); ++icstat) {
311  for (unsigned int itpc = 0; itpc < theGeometry->NTPC(icstat); ++itpc) {
312  const geo::TPCGeo& TPC(theGeometry->TPC(itpc));
313 
314  for (unsigned int iplane = 0; iplane < TPC.Nplanes(); ++iplane) {
315  const geo::PlaneGeo& plane(TPC.Plane(iplane));
316  const float halfWirePitch(0.5f * theGeometry->WirePitch(plane.View()));
317  const unsigned int nWires(theGeometry->Nwires(plane.ID()));
318 
319  int firstBadWire(-1), lastBadWire(-1);
320 
321  for (unsigned int iwire = 0; iwire < nWires; ++iwire) {
322  const raw::ChannelID_t channel(
323  theGeometry->PlaneWireToChannel(iplane, iwire, itpc, icstat));
324  const bool isBadChannel(channelStatus.IsBad(channel));
325  const bool isLastWire(nWires == (iwire + 1));
326 
327  if (isBadChannel && (firstBadWire < 0)) firstBadWire = iwire;
328 
329  if (isBadChannel || isLastWire) lastBadWire = iwire;
330 
331  if (isBadChannel && !isLastWire) continue;
332 
333  if ((firstBadWire < 0) || (lastBadWire < 0)) continue;
334 
335  double firstXYZ[3], lastXYZ[3];
336  theGeometry->Cryostat(icstat)
337  .TPC(itpc)
338  .Plane(iplane)
339  .Wire(firstBadWire)
340  .GetCenter(firstXYZ);
341  theGeometry->Cryostat(icstat)
342  .TPC(itpc)
343  .Plane(iplane)
344  .Wire(lastBadWire)
345  .GetCenter(lastXYZ);
346 
347  firstBadWire = -1;
348  lastBadWire = -1;
349 
351 
352  try {
353  float xFirst(-std::numeric_limits<float>::max());
354  float xLast(std::numeric_limits<float>::max());
355 
356  const unsigned int volumeId(
357  LArPandoraGeometry::GetVolumeID(driftVolumeMap, icstat, itpc));
358  LArDriftVolumeMap::const_iterator volumeIter(driftVolumeMap.find(volumeId));
359 
360  if (driftVolumeMap.end() != volumeIter) {
361  xFirst = volumeIter->second.GetCenterX() - 0.5f * volumeIter->second.GetWidthX();
362  xLast = volumeIter->second.GetCenterX() + 0.5f * volumeIter->second.GetWidthX();
363  }
364 
365  const geo::View_t iview = plane.View();
366  parameters = detType->CreateLineGapParametersFromReadoutGaps(
367  iview, itpc, icstat, firstXYZ, lastXYZ, halfWirePitch, xFirst, xLast, pPandora);
368  }
369  catch (const pandora::StatusCodeException&) {
370  mf::LogWarning("LArPandora")
371  << "CreatePandoraReadoutGaps - invalid line gap parameter provided, all assigned "
372  "values must be finite, line gap omitted "
373  << std::endl;
374  continue;
375  }
376 
377  try {
378  PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS,
379  !=,
380  PandoraApi::Geometry::LineGap::Create(*pPandora, parameters));
381  }
382  catch (const pandora::StatusCodeException&) {
383  mf::LogWarning("LArPandora") << "CreatePandoraReadoutGaps - unable to create line "
384  "gap, insufficient or invalid information supplied "
385  << std::endl;
386  continue;
387  }
388  }
389  }
390  }
391  }
392  }
enum geo::_plane_proj View_t
Enumerate the possible plane projections.
Geometry information for a single TPC.
Definition: TPCGeo.h:38
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.
BEGIN_PROLOG TPC
Geometry information for a single wire plane.The plane is represented in the geometry by a solid whic...
Definition: PlaneGeo.h:82
Class providing information about the quality of channels.
fhicl::Table< sbnd::crt::CRTDetSimParams > Parameters
LArPandoraDetectorType * GetDetectorType()
Factory class that returns the correct detector type interface.
unsigned int ChannelID_t
Type representing the ID of a readout channel.
Definition: RawTypes.h:28
void lar_pandora::LArPandoraInput::FillMCProcessMap ( MCProcessMap processMap)
staticprivate

Populate a map from MC process string to enumeration.

Parameters
processMapthe output map from MC process string to enumeration

Definition at line 852 of file LArPandoraInput.cxx.

853  {
854  // QGSP_BERT and EM standard physics list mappings
855  processMap["unknown"] = lar_content::MC_PROC_UNKNOWN;
856  processMap["primary"] = lar_content::MC_PROC_PRIMARY;
857  processMap["compt"] = lar_content::MC_PROC_COMPT;
858  processMap["phot"] = lar_content::MC_PROC_PHOT;
859  processMap["annihil"] = lar_content::MC_PROC_ANNIHIL;
860  processMap["eIoni"] = lar_content::MC_PROC_E_IONI;
861  processMap["eBrem"] = lar_content::MC_PROC_E_BREM;
862  processMap["conv"] = lar_content::MC_PROC_CONV;
863  processMap["muIoni"] = lar_content::MC_PROC_MU_IONI;
864  processMap["muMinusCaptureAtRest"] = lar_content::MC_PROC_MU_MINUS_CAPTURE_AT_REST;
865  processMap["neutronInelastic"] = lar_content::MC_PROC_NEUTRON_INELASTIC;
866  processMap["nCapture"] = lar_content::MC_PROC_N_CAPTURE;
867  processMap["hadElastic"] = lar_content::MC_PROC_HAD_ELASTIC;
868  processMap["Decay"] = lar_content::MC_PROC_DECAY;
869  processMap["CoulombScat"] = lar_content::MC_PROC_COULOMB_SCAT;
870  processMap["muBrems"] = lar_content::MC_PROC_MU_BREM;
871  processMap["muPairProd"] = lar_content::MC_PROC_MU_PAIR_PROD;
872  processMap["PhotonInelastic"] = lar_content::MC_PROC_PHOTON_INELASTIC;
873  processMap["hIoni"] = lar_content::MC_PROC_HAD_IONI;
874  processMap["protonInelastic"] = lar_content::MC_PROC_PROTON_INELASTIC;
875  processMap["pi+Inelastic"] = lar_content::MC_PROC_PI_PLUS_INELASTIC;
876  processMap["CHIPSNuclearCaptureAtRest"] = lar_content::MC_PROC_CHIPS_NUCLEAR_CAPTURE_AT_REST;
877  processMap["pi-Inelastic"] = lar_content::MC_PROC_PI_MINUS_INELASTIC;
878  processMap["Transportation"] = lar_content::MC_PROC_TRANSPORTATION;
879  processMap["Rayl"] = lar_content::MC_PROC_RAYLEIGH;
880  processMap["hBrems"] = lar_content::MC_PROC_HAD_BREM;
881  processMap["hPairProd"] = lar_content::MC_PROC_HAD_PAIR_PROD;
882  processMap["ionIoni"] = lar_content::MC_PROC_ION_IONI;
883  processMap["nKiller"] = lar_content::MC_PROC_NEUTRON_KILLER;
884  processMap["ionInelastic"] = lar_content::MC_PROC_ION_INELASTIC;
885  processMap["He3Inelastic"] = lar_content::MC_PROC_HE3_INELASTIC;
886  processMap["alphaInelastic"] = lar_content::MC_PROC_ALPHA_INELASTIC;
887  processMap["anti_He3Inelastic"] = lar_content::MC_PROC_ANTI_HE3_INELASTIC;
888  processMap["anti_alphaInelastic"] = lar_content::MC_PROC_ANTI_ALPHA_INELASTIC;
889  processMap["hFritiofCaptureAtRest"] = lar_content::MC_PROC_HAD_FRITIOF_CAPTURE_AT_REST;
890  processMap["anti_deuteronInelastic"] = lar_content::MC_PROC_ANTI_DEUTERON_INELASTIC;
891  processMap["anti_neutronInelastic"] = lar_content::MC_PROC_ANTI_NEUTRON_INELASTIC;
892  processMap["anti_protonInelastic"] = lar_content::MC_PROC_ANTI_PROTON_INELASTIC;
893  processMap["anti_tritonInelastic"] = lar_content::MC_PROC_ANTI_TRITON_INELASTIC;
894  processMap["dInelastic"] = lar_content::MC_PROC_DEUTERON_INELASTIC;
895  processMap["electronNuclear"] = lar_content::MC_PROC_ELECTRON_NUCLEAR;
896  processMap["photonNuclear"] = lar_content::MC_PROC_PHOTON_NUCLEAR;
897  processMap["kaon+Inelastic"] = lar_content::MC_PROC_KAON_PLUS_INELASTIC;
898  processMap["kaon-Inelastic"] = lar_content::MC_PROC_KAON_MINUS_INELASTIC;
899  processMap["hBertiniCaptureAtRest"] = lar_content::MC_PROC_HAD_BERTINI_CAPTURE_AT_REST;
900  processMap["lambdaInelastic"] = lar_content::MC_PROC_LAMBDA_INELASTIC;
901  processMap["muonNuclear"] = lar_content::MC_PROC_MU_NUCLEAR;
902  processMap["tInelastic"] = lar_content::MC_PROC_TRITON_INELASTIC;
903  processMap["primaryBackground"] = lar_content::MC_PROC_PRIMARY_BACKGROUND;
904  }
void lar_pandora::LArPandoraInput::FindPrimaryParticles ( const RawMCParticleVector mcParticleVector,
std::map< const simb::MCParticle, bool > &  primaryMCParticleMap 
)
static

Find all primary MCParticles in a given vector of MCParticles.

Parameters
mcParticleVectorvector of all MCParticles to consider
primaryMCParticleMapmap containing primary MCParticles and bool indicating whether particle has been accounted for

Definition at line 648 of file LArPandoraInput.cxx.

651  {
652  for (const simb::MCParticle& mcParticle : mcParticleVector) {
653  if ("primary" == mcParticle.Process()) {
654  primaryMCParticleMap.emplace(std::make_pair(mcParticle, false));
655  }
656  }
657  }
double lar_pandora::LArPandoraInput::GetMips ( const detinfo::DetectorPropertiesData detProp,
const Settings settings,
const double  hit_Charge,
const geo::View_t  hit_View 
)
staticprivate

Convert charge in ADCs to approximate MIPs.

Parameters
settingsthe settings
hit_Chargethe input charge
hit_Viewthe input view number

Definition at line 826 of file LArPandoraInput.cxx.

830  {
831  art::ServiceHandle<geo::Geometry const> theGeometry;
832 
833  // TODO: Unite this procedure with other calorimetry procedures under development
834  const double dQdX(hit_Charge / (theGeometry->WirePitch(hit_View))); // ADC/cm
835  const double dQdX_e(dQdX /
836  (detProp.ElectronsToADC() * settings.m_recombination_factor)); // e/cm
837  const double dEdX(settings.m_useBirksCorrection ?
838  detProp.BirksCorrection(dQdX_e) :
839  dQdX_e * 1000. / util::kGeVToElectrons); // MeV/cm
840  double mips(dEdX / settings.m_dEdX_mip);
841 
842  if (mips < 0.) mips = settings.m_mips_if_negative;
843 
844  if (mips > settings.m_mips_max) mips = settings.m_mips_max;
845 
846  return mips;
847  }
constexpr double kGeVToElectrons
23.6eV per ion pair, 1e9 eV/GeV
double BirksCorrection(double dQdX) const
dQ/dX in electrons/cm, returns dE/dX in MeV/cm.
void lar_pandora::LArPandoraInput::GetTrueStartAndEndPoints ( const Settings settings,
const art::Ptr< simb::MCParticle > &  particle,
int &  startT,
int &  endT 
)
staticprivate

Loop over MC trajectory points and identify start and end points within the detector.

Parameters
settingsthe settings
particlethe true particle
startTthe first trajectory point in the detector
endTthe last trajectory point in the detector

Definition at line 743 of file LArPandoraInput.cxx.

747  {
748  art::ServiceHandle<geo::Geometry const> theGeometry;
749  firstT = -1;
750  lastT = -1;
751 
752  for (unsigned int icstat = 0; icstat < theGeometry->Ncryostats(); ++icstat) {
753  for (unsigned int itpc = 0; itpc < theGeometry->NTPC(icstat); ++itpc) {
754  int thisfirstT(-1), thislastT(-1);
755  LArPandoraInput::GetTrueStartAndEndPoints(icstat, itpc, particle, thisfirstT, thislastT);
756 
757  if (thisfirstT < 0) continue;
758 
759  if (firstT < 0 || thisfirstT < firstT) firstT = thisfirstT;
760 
761  if (lastT < 0 || thislastT > lastT) lastT = thislastT;
762  }
763  }
764  }
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.
void lar_pandora::LArPandoraInput::GetTrueStartAndEndPoints ( const unsigned int  cstat,
const unsigned int  tpc,
const art::Ptr< simb::MCParticle > &  particle,
int &  startT,
int &  endT 
)
staticprivate

Loop over MC trajectory points and identify start and end points within a given cryostat and TPC.

Parameters
cstatthe cryostat
tpcthe TPC
particlethe true particle
startTthe first trajectory point in the detector
endTthe last trajectory point in the detector

Definition at line 769 of file LArPandoraInput.cxx.

774  {
775  art::ServiceHandle<geo::Geometry const> theGeometry;
776 
777  bool foundStartPosition(false);
778  const int numTrajectoryPoints(static_cast<int>(particle->NumberTrajectoryPoints()));
779 
780  for (int nt = 0; nt < numTrajectoryPoints; ++nt) {
781  const double pos[3] = {particle->Vx(nt), particle->Vy(nt), particle->Vz(nt)};
782  geo::TPCID tpcID = theGeometry->FindTPCAtPosition(pos);
783 
784  if (!tpcID.isValid) continue;
785 
786  if (!(cstat == tpcID.Cryostat && tpc == tpcID.TPC)) continue;
787 
788  endT = nt;
789 
790  if (!foundStartPosition) {
791  startT = endT;
792  foundStartPosition = true;
793  }
794  }
795  }
bool isValid
Whether this ID points to a valid element.
Definition: geo_types.h:211
CryostatID_t Cryostat
Index of cryostat.
Definition: geo_types.h:212
The data type to uniquely identify a TPC.
Definition: geo_types.h:386
TPCID_t TPC
Index of the TPC within its cryostat.
Definition: geo_types.h:406
float lar_pandora::LArPandoraInput::GetTrueX0 ( const art::Event &  evt,
const art::Ptr< simb::MCParticle > &  particle,
const int  nT 
)
staticprivate

Use detector and time services to get a true X offset for a given trajectory point.

Parameters
evtevent currently being processing by art
particlethe true particle
nTthe trajectory point

Definition at line 800 of file LArPandoraInput.cxx.

803  {
804  art::ServiceHandle<geo::Geometry const> theGeometry;
805  auto const clock_data = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(e);
806  auto const det_prop =
807  art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(e, clock_data);
808 
809  unsigned int which_tpc(0);
810  unsigned int which_cstat(0);
811  double pos[3] = {particle->Vx(nt), particle->Vy(nt), particle->Vz(nt)};
812  theGeometry->PositionToTPC(pos, which_tpc, which_cstat);
813 
814  const float vtxT(particle->T(nt));
815  const float vtxTDC(clock_data.TPCG4Time2Tick(vtxT));
816  const float vtxTDC0(trigger_offset(clock_data));
817 
818  const geo::TPCGeo& theTpc = theGeometry->Cryostat(which_cstat).TPC(which_tpc);
819  const float driftDir((theTpc.DriftDirection() == geo::kNegX) ? +1.0 : -1.0);
820  return (driftDir * (vtxTDC - vtxTDC0) * det_prop.GetXTicksCoefficient());
821  }
Geometry information for a single TPC.
Definition: TPCGeo.h:38
Drift towards negative X values.
Definition: geo_types.h:162
DriftDirection_t DriftDirection() const
Returns an enumerator value describing the drift direction.
Definition: TPCGeo.h:144
do i e
int trigger_offset(DetectorClocksData const &data)
bool lar_pandora::LArPandoraInput::IsPrimaryMCParticle ( const art::Ptr< simb::MCParticle > &  mcParticle,
std::map< const simb::MCParticle, bool > &  primaryMCParticleMap 
)
static

Check whether an MCParticle can be found in a given map.

Parameters
mcParticletarget MCParticle
primaryMCParticleMapmap containing primary MCParticles and bool indicating whether particle has been accounted for

Definition at line 662 of file LArPandoraInput.cxx.

664  {
665  for (auto& mcParticleIter : primaryMCParticleMap) {
666  if (!mcParticleIter.second) {
667  const simb::MCParticle primaryMCParticle(mcParticleIter.first);
668 
669  if (std::fabs(primaryMCParticle.Px() - mcParticle->Px()) <
670  std::numeric_limits<double>::epsilon() &&
671  std::fabs(primaryMCParticle.Py() - mcParticle->Py()) <
672  std::numeric_limits<double>::epsilon() &&
673  std::fabs(primaryMCParticle.Pz() - mcParticle->Pz()) <
674  std::numeric_limits<double>::epsilon()) {
675  mcParticleIter.second = true;
676  return true;
677  }
678  }
679  }
680  return false;
681  }

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