LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
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 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...
 

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::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 Settings &settings, const double hit_Charge, const geo::View_t hit_View)
 Convert charge in ADCs to approximate MIPs. More...
 

Detailed Description

LArPandoraInput class.

Definition at line 22 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 213 of file LArPandoraInput.cxx.

References lar_pandora::LArPandoraInput::Settings::m_pPrimaryPandora, and max.

Referenced by lar_pandora::LArPandora::beginJob().

214 {
215  mf::LogDebug("LArPandora") << " *** LArPandoraInput::CreatePandoraDetectorGaps(...) *** " << std::endl;
216 
217  if (!settings.m_pPrimaryPandora)
218  throw cet::exception("LArPandora") << "CreatePandoraDetectorGaps - primary Pandora instance does not exist ";
219 
220  const pandora::Pandora *pPandora(settings.m_pPrimaryPandora);
221 
222  for (const LArDetectorGap &gap : listOfGaps)
223  {
224  PandoraApi::Geometry::LineGap::Parameters parameters;
225 
226  try
227  {
228  parameters.m_lineGapType = pandora::TPC_DRIFT_GAP;
229  parameters.m_lineStartX = gap.GetX1();
230  parameters.m_lineEndX = gap.GetX2();
231  parameters.m_lineStartZ = -std::numeric_limits<float>::max();
232  parameters.m_lineEndZ = std::numeric_limits<float>::max();
233  }
234  catch (const pandora::StatusCodeException &)
235  {
236  mf::LogWarning("LArPandora") << "CreatePandoraDetectorGaps - invalid line gap parameter provided, all assigned values must be finite, line gap omitted " << std::endl;
237  continue;
238  }
239 
240  try
241  {
242  PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::Geometry::LineGap::Create(*pPandora, parameters));
243  }
244  catch (const pandora::StatusCodeException &)
245  {
246  mf::LogWarning("LArPandora") << "CreatePandoraDetectorGaps - unable to create line gap, insufficient or invalid information supplied " << std::endl;
247  continue;
248  }
249  }
250 }
Int_t max
Definition: plot.C:27
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
void lar_pandora::LArPandoraInput::CreatePandoraHits2D ( const Settings settings,
const LArDriftVolumeMap driftVolumeMap,
const HitVector hitVector,
IdToHitMap idToHitMap 
)
static

Create the Pandora 2D hits from the ART hits.

Parameters
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 41 of file LArPandoraInput.cxx.

References geo::GeometryCore::Cryostat(), geo::WireGeo::GetCenter(), lar_pandora::LArPandoraGeometry::GetGlobalView(), GetMips(), lar_pandora::LArPandoraGeometry::GetVolumeID(), recob::Hit::Integral(), geo::kU, geo::kV, geo::kW, lar_pandora::LArPandoraInput::Settings::m_dx_cm, lar_pandora::LArPandoraInput::Settings::m_int_cm, lar_content::LArCaloHitParameters::m_larTPCVolumeId, lar_pandora::LArPandoraInput::Settings::m_mips_to_gev, lar_pandora::LArPandoraInput::Settings::m_pPrimaryPandora, lar_pandora::LArPandoraInput::Settings::m_rad_cm, lar_pandora::LArPandoraInput::Settings::m_uidOffset, lar_pandora::LArPandoraInput::Settings::m_useHitWidths, recob::Hit::PeakTime(), recob::Hit::PeakTimeMinusRMS(), recob::Hit::PeakTimePlusRMS(), geo::TPCGeo::Plane(), geo::CryostatGeo::TPC(), recob::Hit::View(), geo::PlaneGeo::Wire(), recob::Hit::WireID(), and geo::GeometryCore::WirePitch().

Referenced by lar_pandora::LArPandora::CreatePandoraInput().

42 {
43  mf::LogDebug("LArPandora") << " *** LArPandoraInput::CreatePandoraHits2D(...) *** " << std::endl;
44 
45  if (!settings.m_pPrimaryPandora)
46  throw cet::exception("LArPandora") << "CreatePandoraHits2D - primary Pandora instance does not exist ";
47 
48  const pandora::Pandora *pPandora(settings.m_pPrimaryPandora);
49 
51  auto const* theDetector = lar::providerFrom<detinfo::DetectorPropertiesService>();
52 
53  // Loop over ART hits
54  int hitCounter(0);
55 
56  lar_content::LArCaloHitFactory caloHitFactory;
57 
58  for (HitVector::const_iterator iter = hitVector.begin(), iterEnd = hitVector.end(); iter != iterEnd; ++iter)
59  {
60  const art::Ptr<recob::Hit> hit = *iter;
61  const geo::WireID hit_WireID(hit->WireID());
62 
63  // Get basic hit properties (view, time, charge)
64  const geo::View_t hit_View(hit->View());
65  const double hit_Charge(hit->Integral());
66  const double hit_Time(hit->PeakTime());
67  const double hit_TimeStart(hit->PeakTimeMinusRMS());
68  const double hit_TimeEnd(hit->PeakTimePlusRMS());
69 
70  // Get hit X coordinate and, if using a single global drift volume, remove any out-of-time hits here
71  const double xpos_cm(theDetector->ConvertTicksToX(hit_Time, hit_WireID.Plane, hit_WireID.TPC, hit_WireID.Cryostat));
72  const double dxpos_cm(std::fabs(theDetector->ConvertTicksToX(hit_TimeEnd, hit_WireID.Plane, hit_WireID.TPC, hit_WireID.Cryostat) -
73  theDetector->ConvertTicksToX(hit_TimeStart, hit_WireID.Plane, hit_WireID.TPC, hit_WireID.Cryostat)));
74 
75  // Get hit Y and Z coordinates, based on central position of wire
76  double xyz[3];
77  theGeometry->Cryostat(hit_WireID.Cryostat).TPC(hit_WireID.TPC).Plane(hit_WireID.Plane).Wire(hit_WireID.Wire).GetCenter(xyz);
78  const double y0_cm(xyz[1]);
79  const double z0_cm(xyz[2]);
80 
81  // Get other hit properties here
82  const double wire_pitch_cm(theGeometry->WirePitch(hit_View)); // cm
83  const double mips(LArPandoraInput::GetMips(settings, hit_Charge, hit_View));
84 
85  // Create Pandora CaloHit
86  lar_content::LArCaloHitParameters caloHitParameters;
87 
88  try
89  {
90  caloHitParameters.m_expectedDirection = pandora::CartesianVector(0., 0., 1.);
91  caloHitParameters.m_cellNormalVector = pandora::CartesianVector(0., 0., 1.);
92  caloHitParameters.m_cellSize0 = settings.m_dx_cm;
93  caloHitParameters.m_cellSize1 = (settings.m_useHitWidths ? dxpos_cm : settings.m_dx_cm);
94  caloHitParameters.m_cellThickness = wire_pitch_cm;
95  caloHitParameters.m_cellGeometry = pandora::RECTANGULAR;
96  caloHitParameters.m_time = 0.;
97  caloHitParameters.m_nCellRadiationLengths = settings.m_dx_cm / settings.m_rad_cm;
98  caloHitParameters.m_nCellInteractionLengths = settings.m_dx_cm / settings.m_int_cm;
99  caloHitParameters.m_isDigital = false;
100  caloHitParameters.m_hitRegion = pandora::SINGLE_REGION;
101  caloHitParameters.m_layer = 0;
102  caloHitParameters.m_isInOuterSamplingLayer = false;
103  caloHitParameters.m_inputEnergy = hit_Charge;
104  caloHitParameters.m_mipEquivalentEnergy = mips;
105  caloHitParameters.m_electromagneticEnergy = mips * settings.m_mips_to_gev;
106  caloHitParameters.m_hadronicEnergy = mips * settings.m_mips_to_gev;
107  caloHitParameters.m_pParentAddress = (void*)((intptr_t)(++hitCounter));
108  caloHitParameters.m_larTPCVolumeId = LArPandoraGeometry::GetVolumeID(driftVolumeMap, hit_WireID.Cryostat, hit_WireID.TPC);
109 
110  const geo::View_t pandora_View(LArPandoraGeometry::GetGlobalView(hit_WireID.Cryostat, hit_WireID.TPC, hit_View));
111 
112  if (pandora_View == geo::kW)
113  {
114  caloHitParameters.m_hitType = pandora::TPC_VIEW_W;
115  const double wpos_cm(pPandora->GetPlugins()->GetLArTransformationPlugin()->YZtoW(y0_cm, z0_cm));
116  caloHitParameters.m_positionVector = pandora::CartesianVector(xpos_cm, 0., wpos_cm);
117  }
118  else if(pandora_View == geo::kU)
119  {
120  caloHitParameters.m_hitType = pandora::TPC_VIEW_U;
121  const double upos_cm(pPandora->GetPlugins()->GetLArTransformationPlugin()->YZtoU(y0_cm, z0_cm));
122  caloHitParameters.m_positionVector = pandora::CartesianVector(xpos_cm, 0., upos_cm);
123  }
124  else if(pandora_View == geo::kV)
125  {
126  caloHitParameters.m_hitType = pandora::TPC_VIEW_V;
127  const double vpos_cm(pPandora->GetPlugins()->GetLArTransformationPlugin()->YZtoV(y0_cm, z0_cm));
128  caloHitParameters.m_positionVector = pandora::CartesianVector(xpos_cm, 0., vpos_cm);
129  }
130  else
131  {
132  throw cet::exception("LArPandora") << "CreatePandoraHits2D - this wire view not recognised (View=" << hit_View << ") ";
133  }
134  }
135  catch (const pandora::StatusCodeException &)
136  {
137  mf::LogWarning("LArPandora") << "CreatePandoraHits2D - invalid calo hit parameter provided, all assigned values must be finite, calo hit omitted " << std::endl;
138  continue;
139  }
140 
141  // Store the hit address
142  if (hitCounter >= settings.m_uidOffset)
143  throw cet::exception("LArPandora") << "CreatePandoraHits2D - detected an excessive number of hits (" << hitCounter << ") ";
144 
145  idToHitMap[hitCounter] = hit;
146 
147  // Create the Pandora hit
148  try
149  {
150  PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::CaloHit::Create(*pPandora, caloHitParameters, caloHitFactory));
151  }
152  catch (const pandora::StatusCodeException &)
153  {
154  mf::LogWarning("LArPandora") << "CreatePandoraHits2D - unable to create calo hit, insufficient or invalid information supplied " << std::endl;
155  continue;
156  }
157  }
158 }
static geo::View_t GetGlobalView(const unsigned int cstat, const unsigned int tpc, const geo::View_t hit_View)
Convert to global coordinate system.
static double GetMips(const Settings &settings, const double hit_Charge, const geo::View_t hit_View)
Convert charge in ADCs to approximate MIPs.
WireGeo const & Wire(unsigned int iwire) const
Definition: PlaneGeo.cxx:506
enum geo::_plane_proj View_t
Enumerate the possible plane projections.
Planes which measure V.
Definition: geo_types.h:77
geo::WireID WireID() const
Initial tdc tick for hit.
Definition: Hit.h:234
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:225
geo::View_t View() const
View for the plane of the hit.
Definition: Hit.h:233
pandora::InputUInt m_larTPCVolumeId
The lar tpc volume id.
Definition: LArCaloHit.h:30
geo::Length_t WirePitch(geo::PlaneID const &planeid) const
Returns the distance between two consecutive wires.
LAr calo hit parameters.
Definition: LArCaloHit.h:27
Planes which measure U.
Definition: geo_types.h:76
intermediate_table::const_iterator const_iterator
CryostatGeo const & Cryostat(geo::CryostatID const &cryoid) const
Returns the specified cryostat.
float PeakTimeMinusRMS(float sigmas=+1.) const
Returns a time sigmas RMS away from the peak time.
Definition: Hit.h:240
Detector simulation of raw signals on wires.
float PeakTime() const
Time of the signal peak, in tick units.
Definition: Hit.h:219
const TPCGeo & TPC(unsigned int itpc) const
Return the itpc&#39;th TPC in the cryostat.
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
LArCaloHitFactory responsible for object creation.
Definition: LArCaloHit.h:64
Planes which measure W (third view for Bo, MicroBooNE, etc).
Definition: geo_types.h:78
PlaneGeo const & Plane(geo::View_t view) const
Return the plane in the tpc with View_t view.
Definition: TPCGeo.cxx:299
void GetCenter(double *xyz, double localz=0.0) const
Fills the world coordinate of a point on the wire.
Definition: WireGeo.cxx:68
float PeakTimePlusRMS(float sigmas=+1.) const
Returns a time sigmas RMS away from the peak time.
Definition: Hit.h:237
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
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 162 of file LArPandoraInput.cxx.

References lar_pandora::LArPandoraInput::Settings::m_pPrimaryPandora.

Referenced by lar_pandora::LArPandora::beginJob().

163 {
164  mf::LogDebug("LArPandora") << " *** LArPandoraInput::CreatePandoraLArTPCs(...) *** " << std::endl;
165 
166  if (!settings.m_pPrimaryPandora)
167  throw cet::exception("LArPandora") << "CreatePandoraDetectorGaps - primary Pandora instance does not exist ";
168 
169  const pandora::Pandora *pPandora(settings.m_pPrimaryPandora);
170 
171  for (const LArDriftVolume &driftVolume : driftVolumeList)
172  {
173  PandoraApi::Geometry::LArTPC::Parameters parameters;
174 
175  try
176  {
177  parameters.m_larTPCVolumeId = driftVolume.GetVolumeID();
178  parameters.m_centerX = driftVolume.GetCenterX();
179  parameters.m_centerY = driftVolume.GetCenterY();
180  parameters.m_centerZ = driftVolume.GetCenterZ();
181  parameters.m_widthX = driftVolume.GetWidthX();
182  parameters.m_widthY = driftVolume.GetWidthY();
183  parameters.m_widthZ = driftVolume.GetWidthZ();
184  parameters.m_wirePitchU = driftVolume.GetWirePitchU();
185  parameters.m_wirePitchV = driftVolume.GetWirePitchV();
186  parameters.m_wirePitchW = driftVolume.GetWirePitchW();
187  parameters.m_wireAngleU = driftVolume.GetWireAngleU();
188  parameters.m_wireAngleV = driftVolume.GetWireAngleV();
189  parameters.m_wireAngleW = driftVolume.GetWireAngleW();
190  parameters.m_sigmaUVW = driftVolume.GetSigmaUVZ();
191  parameters.m_isDriftInPositiveX = driftVolume.IsPositiveDrift();
192  }
193  catch (const pandora::StatusCodeException &)
194  {
195  mf::LogWarning("LArPandora") << "CreatePandoraLArTPCs - invalid tpc parameter provided, all assigned values must be finite, tpc omitted " << std::endl;
196  continue;
197  }
198 
199  try
200  {
201  PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::Geometry::LArTPC::Create(*pPandora, parameters));
202  }
203  catch (const pandora::StatusCodeException &)
204  {
205  mf::LogWarning("LArPandora") << "CreatePandoraLArTPCs - unable to create tpc, insufficient or invalid information supplied " << std::endl;
206  continue;
207  }
208  }
209 }
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
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 620 of file LArPandoraInput.cxx.

References lar_pandora::LArPandoraInput::Settings::m_pPrimaryPandora.

Referenced by lar_pandora::LArPandora::CreatePandoraInput().

621 {
622  mf::LogDebug("LArPandora") << " *** LArPandoraInput::CreatePandoraMCLinks(...) *** " << std::endl;
623 
624  if (!settings.m_pPrimaryPandora)
625  throw cet::exception("LArPandora") << "CreatePandoraMCLinks2D - primary Pandora instance does not exist ";
626 
627  const pandora::Pandora *pPandora(settings.m_pPrimaryPandora);
628 
629  for (IdToHitMap::const_iterator iterI = idToHitMap.begin(), iterEndI = idToHitMap.end(); iterI != iterEndI ; ++iterI)
630  {
631  const int hitID(iterI->first);
632  const art::Ptr<recob::Hit> hit(iterI->second);
633  // const geo::WireID hit_WireID(hit->WireID());
634 
635  // Get list of associated MC particles
636  HitsToTrackIDEs::const_iterator iterJ = hitToParticleMap.find(hit);
637 
638  if (hitToParticleMap.end() == iterJ)
639  continue;
640 
641  const TrackIDEVector &trackCollection = iterJ->second;
642 
643  if (trackCollection.size() == 0)
644  throw cet::exception("LArPandora") << "CreatePandoraMCLinks2D - found a hit without any associated MC truth information ";
645 
646  // Create links between hits and MC particles
647  for (unsigned int k = 0; k < trackCollection.size(); ++k)
648  {
649  const sim::TrackIDE trackIDE(trackCollection.at(k));
650  const int trackID(std::abs(trackIDE.trackID)); // TODO: Find out why std::abs is needed
651  const float energyFrac(trackIDE.energyFrac);
652 
653  try
654  {
655  PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::SetCaloHitToMCParticleRelationship(*pPandora,
656  (void*)((intptr_t)hitID), (void*)((intptr_t)trackID), energyFrac));
657  }
658  catch (const pandora::StatusCodeException &)
659  {
660  mf::LogWarning("LArPandora") << "CreatePandoraMCLinks2D - unable to create calo hit to mc particle relationship, invalid information supplied " << std::endl;
661  continue;
662  }
663  }
664  }
665 }
std::vector< sim::TrackIDE > TrackIDEVector
intermediate_table::const_iterator const_iterator
Detector simulation of raw signals on wires.
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
Ionization energy from a Geant4 track.
Definition: SimChannel.h:28
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
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 374 of file LArPandoraInput.cxx.

References E, simb::MCParticle::E(), FindPrimaryParticles(), simb::MCTruth::GetNeutrino(), GetTrueStartAndEndPoints(), IsPrimaryMCParticle(), simb::kCosmicRay, simb::kSingleParticle, lar_content::LArMCParticleParameters::m_nuanceCode, lar_pandora::LArPandoraInput::Settings::m_pPrimaryPandora, lar_pandora::LArPandoraInput::Settings::m_uidOffset, simb::MCParticle::Mother(), simb::MCTruth::NeutrinoSet(), simb::MCTruth::Origin(), geo::origin(), simb::MCParticle::PdgCode(), simb::MCParticle::Px(), simb::MCParticle::Py(), simb::MCParticle::Pz(), simb::MCParticle::TrackId(), cheat::ParticleInventoryService::TrackIdToMCTruth(), simb::MCParticle::Vx(), simb::MCParticle::Vy(), and simb::MCParticle::Vz().

Referenced by lar_pandora::LArPandora::CreatePandoraInput().

376 {
377  mf::LogDebug("LArPandora") << " *** LArPandoraInput::CreatePandoraMCParticles(...) *** " << std::endl;
379 
380  if (!settings.m_pPrimaryPandora)
381  throw cet::exception("LArPandora") << "CreatePandoraMCParticles - primary Pandora instance does not exist ";
382 
383  const pandora::Pandora *pPandora(settings.m_pPrimaryPandora);
384 
385  // Make indexed list of MC particles
386  MCParticleMap particleMap;
387 
388  for (MCParticlesToMCTruth::const_iterator iter = particleToTruthMap.begin(), iterEnd = particleToTruthMap.end(); iter != iterEnd; ++iter)
389  {
390  const art::Ptr<simb::MCParticle> particle = iter->first;
391  particleMap[particle->TrackId()] = particle;
392  }
393 
394  // Loop over MC truth objects
395  int neutrinoCounter(0);
396 
397  lar_content::LArMCParticleFactory mcParticleFactory;
398 
399  for (MCTruthToMCParticles::const_iterator iter1 = truthToParticleMap.begin(), iterEnd1 = truthToParticleMap.end(); iter1 != iterEnd1; ++iter1)
400  {
401  const art::Ptr<simb::MCTruth> truth = iter1->first;
402 
403  if (truth->NeutrinoSet())
404  {
405  const simb::MCNeutrino neutrino(truth->GetNeutrino());
406  ++neutrinoCounter;
407 
408  if (neutrinoCounter >= settings.m_uidOffset)
409  throw cet::exception("LArPandora") << "CreatePandoraMCParticles - detected an excessive number of mc neutrinos (" << neutrinoCounter << ")";
410 
411  const int neutrinoID(neutrinoCounter + 9 * settings.m_uidOffset);
412 
413  // Create Pandora 3D MC Particle
414  lar_content::LArMCParticleParameters mcParticleParameters;
415 
416  try
417  {
418  mcParticleParameters.m_nuanceCode = neutrino.InteractionType();
419  mcParticleParameters.m_energy = neutrino.Nu().E();
420  mcParticleParameters.m_momentum = pandora::CartesianVector(neutrino.Nu().Px(), neutrino.Nu().Py(), neutrino.Nu().Pz());
421  mcParticleParameters.m_vertex = pandora::CartesianVector(neutrino.Nu().Vx(), neutrino.Nu().Vy(), neutrino.Nu().Vz());
422  mcParticleParameters.m_endpoint = pandora::CartesianVector(neutrino.Nu().Vx(), neutrino.Nu().Vy(), neutrino.Nu().Vz());
423  mcParticleParameters.m_particleId = neutrino.Nu().PdgCode();
424  mcParticleParameters.m_mcParticleType = pandora::MC_3D;
425  mcParticleParameters.m_pParentAddress = (void*)((intptr_t)neutrinoID);
426  }
427  catch (const pandora::StatusCodeException &)
428  {
429  mf::LogWarning("LArPandora") << "CreatePandoraMCParticles - invalid mc neutrino parameter provided, all assigned values must be finite, mc neutrino omitted " << std::endl;
430  continue;
431  }
432 
433  try
434  {
435  PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::MCParticle::Create(*pPandora, mcParticleParameters, mcParticleFactory));
436  }
437  catch (const pandora::StatusCodeException &)
438  {
439  mf::LogWarning("LArPandora") << "CreatePandoraMCParticles - unable to create mc neutrino, insufficient or invalid information supplied " << std::endl;
440  continue;
441  }
442 
443  // Loop over associated particles
444  const MCParticleVector &particleVector = iter1->second;
445 
446  for (MCParticleVector::const_iterator iter2 = particleVector.begin(), iterEnd2 = particleVector.end(); iter2 != iterEnd2; ++iter2)
447  {
448  const art::Ptr<simb::MCParticle> particle = *iter2;
449  const int trackID(particle->TrackId());
450 
451  // Mother/Daughter Links
452  if (particle->Mother() == 0)
453  {
454  try
455  {
456  PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::SetMCParentDaughterRelationship(*pPandora,
457  (void*)((intptr_t)neutrinoID), (void*)((intptr_t)trackID)));
458  }
459  catch (const pandora::StatusCodeException &)
460  {
461  mf::LogWarning("LArPandora") << "CreatePandoraMCParticles - unable to create mc particle relationship, invalid information supplied " << std::endl;
462  continue;
463  }
464  }
465  }
466  }
467  }
468 
469  mf::LogDebug("LArPandora") << " Number of Pandora neutrinos: " << neutrinoCounter << std::endl;
470 
471  // Loop over G4 particles
472  int particleCounter(0);
473 
474  // Find Primary Generator Particles
475  std::map<const simb::MCParticle, bool> primaryGeneratorMCParticleMap;
476  LArPandoraInput::FindPrimaryParticles(generatorMCParticleVector, primaryGeneratorMCParticleMap);
477 
478  for (MCParticleMap::const_iterator iterI = particleMap.begin(), iterEndI = particleMap.end(); iterI != iterEndI; ++iterI)
479  {
480  const art::Ptr<simb::MCParticle> particle = iterI->second;
481 
482  if (particle->TrackId() != iterI->first)
483  throw cet::exception("LArPandora") << "CreatePandoraMCParticles - mc truth information appears to be scrambled in this event";
484 
485  if (particle->TrackId() >= settings.m_uidOffset)
486  throw cet::exception("LArPandora") << "CreatePandoraMCParticles - detected an excessive number of MC particles (" << particle->TrackId() << ")";
487 
488  ++particleCounter;
489 
490  // Find start and end trajectory points
491  int firstT(-1), lastT(-1);
492  LArPandoraInput::GetTrueStartAndEndPoints(settings, particle, firstT, lastT);
493 
494  if (firstT < 0 && lastT < 0)
495  {
496  firstT = 0; lastT = 0;
497  }
498 
499  // Lookup position and kinematics at start and end points
500  const float vtxX(particle->Vx(firstT));
501  const float vtxY(particle->Vy(firstT));
502  const float vtxZ(particle->Vz(firstT));
503 
504  const float endX(particle->Vx(lastT));
505  const float endY(particle->Vy(lastT));
506  const float endZ(particle->Vz(lastT));
507 
508  const float pX(particle->Px(firstT));
509  const float pY(particle->Py(firstT));
510  const float pZ(particle->Pz(firstT));
511  const float E(particle->E(firstT));
512 
513  // Find the source of the mc particle
514  int nuanceCode(0);
515  const int trackID(particle->TrackId());
516  const simb::Origin_t origin(particleInventoryService->TrackIdToMCTruth(trackID).Origin());
517 
518  if (LArPandoraInput::IsPrimaryMCParticle(particle, primaryGeneratorMCParticleMap))
519  {
520  nuanceCode = 2001;
521  }
522  else if (simb::kCosmicRay == origin)
523  {
524  nuanceCode = 3000;
525  }
526  else if (simb::kSingleParticle == origin)
527  {
528  nuanceCode = 2000;
529  }
530 
531  // Create 3D Pandora MC Particle
532  lar_content::LArMCParticleParameters mcParticleParameters;
533 
534  try
535  {
536  mcParticleParameters.m_nuanceCode = nuanceCode;
537  mcParticleParameters.m_energy = E;
538  mcParticleParameters.m_particleId = particle->PdgCode();
539  mcParticleParameters.m_momentum = pandora::CartesianVector(pX, pY, pZ);
540  mcParticleParameters.m_vertex = pandora::CartesianVector(vtxX, vtxY, vtxZ);
541  mcParticleParameters.m_endpoint = pandora::CartesianVector(endX, endY, endZ);
542  mcParticleParameters.m_mcParticleType = pandora::MC_3D;
543  mcParticleParameters.m_pParentAddress = (void*)((intptr_t)particle->TrackId());
544  }
545  catch (const pandora::StatusCodeException &)
546  {
547  mf::LogWarning("LArPandora") << "CreatePandoraMCParticles - invalid mc particle parameter provided, all assigned values must be finite, mc particle omitted " << std::endl;
548  continue;
549  }
550 
551  try
552  {
553  PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::MCParticle::Create(*pPandora, mcParticleParameters, mcParticleFactory));
554  }
555  catch (const pandora::StatusCodeException &)
556  {
557  mf::LogWarning("LArPandora") << "CreatePandoraMCParticles - unable to create mc particle, insufficient or invalid information supplied " << std::endl;
558  continue;
559  }
560 
561  // Create Mother/Daughter Links between 3D MC Particles
562  const int id_mother(particle->Mother());
563  MCParticleMap::const_iterator iterJ = particleMap.find(id_mother);
564 
565  if (iterJ != particleMap.end())
566  {
567  try
568  {
569  PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::SetMCParentDaughterRelationship(*pPandora,
570  (void*)((intptr_t)id_mother), (void*)((intptr_t)particle->TrackId())));
571  }
572  catch (const pandora::StatusCodeException &)
573  {
574  mf::LogWarning("LArPandora") << "CreatePandoraMCParticles - Unable to create mc particle relationship, invalid information supplied " << std::endl;
575  continue;
576  }
577  }
578  }
579 
580  mf::LogDebug("LArPandora") << "Number of mc particles: " << particleCounter << std::endl;
581 }
double E(const int i=0) const
Definition: MCParticle.h:237
int PdgCode() const
Definition: MCParticle.h:216
const simb::MCNeutrino & GetNeutrino() const
Definition: MCTruth.h:74
double Py(const int i=0) const
Definition: MCParticle.h:235
Float_t E
Definition: plot.C:23
int Mother() const
Definition: MCParticle.h:217
simb::Origin_t Origin() const
Definition: MCTruth.h:71
enum simb::_ev_origin Origin_t
event origin types
double Px(const int i=0) const
Definition: MCParticle.h:234
static void FindPrimaryParticles(const RawMCParticleVector &mcParticleVector, std::map< const simb::MCParticle, bool > &primaryMCParticleMap)
Find all primary MCParticles in a given vector of MCParticles.
std::map< int, art::Ptr< simb::MCParticle > > MCParticleMap
std::vector< art::Ptr< simb::MCParticle > > MCParticleVector
int TrackId() const
Definition: MCParticle.h:214
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.
simb::MCTruth TrackIdToMCTruth(int const &id)
intermediate_table::const_iterator const_iterator
single particles thrown at the detector
Definition: MCTruth.h:24
LArMCParticleFactory responsible for object creation.
Definition: LArMCParticle.h:64
LAr mc particle parameters.
Definition: LArMCParticle.h:27
double Vx(const int i=0) const
Definition: MCParticle.h:225
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
pandora::InputInt m_nuanceCode
The nuance code.
Definition: LArMCParticle.h:30
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
double Pz(const int i=0) const
Definition: MCParticle.h:236
double Vz(const int i=0) const
Definition: MCParticle.h:227
bool NeutrinoSet() const
Definition: MCTruth.h:75
Event generator information.
Definition: MCNeutrino.h:18
Definition: fwd.h:25
double Vy(const int i=0) const
Definition: MCParticle.h:226
constexpr Point origin()
Returns a origin position with a point of the specified type.
Definition: geo_vectors.h:230
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:22
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 254 of file LArPandoraInput.cxx.

References geo::GeometryCore::Cryostat(), f, geo::WireGeo::GetCenter(), lar_pandora::LArPandoraGeometry::GetGlobalView(), lar_pandora::LArPandoraGeometry::GetVolumeID(), geo::kU, geo::kV, geo::kW, lar_pandora::LArPandoraInput::Settings::m_pPrimaryPandora, max, min, geo::GeometryCore::Ncryostats(), geo::GeometryCore::NTPC(), geo::GeometryCore::Nwires(), geo::TPCGeo::Plane(), geo::GeometryCore::PlaneWireToChannel(), geo::CryostatGeo::TPC(), geo::GeometryCore::TPC(), geo::PlaneGeo::Wire(), and geo::GeometryCore::WirePitch().

Referenced by lar_pandora::LArPandora::CreatePandoraInput().

255 {
256  mf::LogDebug("LArPandora") << " *** LArPandoraInput::CreatePandoraReadoutGaps(...) *** " << std::endl;
257 
258  if (!settings.m_pPrimaryPandora)
259  throw cet::exception("LArPandora") << "CreatePandoraReadoutGaps - primary Pandora instance does not exist ";
260 
261  const pandora::Pandora *pPandora(settings.m_pPrimaryPandora);
262 
264  const lariov::ChannelStatusProvider &channelStatus(art::ServiceHandle<lariov::ChannelStatusService>()->GetProvider());
265 
266  for (unsigned int icstat = 0; icstat < theGeometry->Ncryostats(); ++icstat)
267  {
268  for (unsigned int itpc = 0; itpc < theGeometry->NTPC(icstat); ++itpc)
269  {
270  const geo::TPCGeo &TPC(theGeometry->TPC(itpc));
271 
272  for (unsigned int iplane = 0; iplane < TPC.Nplanes(); ++iplane)
273  {
274  const geo::PlaneGeo &plane(TPC.Plane(iplane));
275  const float halfWirePitch(0.5f * theGeometry->WirePitch(plane.View()));
276  const unsigned int nWires(theGeometry->Nwires(geo::PlaneID(icstat, itpc, plane.View())));
277 
278  int firstBadWire(-1), lastBadWire(-1);
279 
280  for (unsigned int iwire = 0; iwire < nWires; ++iwire)
281  {
282  const raw::ChannelID_t channel(theGeometry->PlaneWireToChannel(plane.View(), iwire, itpc, icstat));
283  const bool isBadChannel(channelStatus.IsBad(channel));
284  const bool isLastWire(nWires == (iwire + 1));
285 
286  if (isBadChannel && (firstBadWire < 0))
287  firstBadWire = iwire;
288 
289  if (isBadChannel || isLastWire)
290  lastBadWire = iwire;
291 
292  if (isBadChannel && !isLastWire)
293  continue;
294 
295  if ((firstBadWire < 0) || (lastBadWire < 0))
296  continue;
297 
298  double firstXYZ[3], lastXYZ[3];
299  theGeometry->Cryostat(icstat).TPC(itpc).Plane(iplane).Wire(firstBadWire).GetCenter(firstXYZ);
300  theGeometry->Cryostat(icstat).TPC(itpc).Plane(iplane).Wire(lastBadWire).GetCenter(lastXYZ);
301 
302  firstBadWire = -1; lastBadWire = -1;
303 
304  PandoraApi::Geometry::LineGap::Parameters parameters;
305 
306  try
307  {
308  parameters.m_lineStartX = -std::numeric_limits<float>::max();
309  parameters.m_lineEndX = std::numeric_limits<float>::max();
310 
311  const unsigned int volumeId(LArPandoraGeometry::GetVolumeID(driftVolumeMap, icstat, itpc));
312  LArDriftVolumeMap::const_iterator volumeIter(driftVolumeMap.find(volumeId));
313 
314  if (driftVolumeMap.end() != volumeIter)
315  {
316  parameters.m_lineStartX = volumeIter->second.GetCenterX() - 0.5f * volumeIter->second.GetWidthX();
317  parameters.m_lineEndX = volumeIter->second.GetCenterX() + 0.5f * volumeIter->second.GetWidthX();
318  }
319 
320  const geo::View_t iview = (geo::View_t)iplane;
321  const geo::View_t pandoraView(LArPandoraGeometry::GetGlobalView(icstat, itpc, iview));
322 
323  if (pandoraView == geo::kW)
324  {
325  const float firstW(firstXYZ[2]);
326  const float lastW(lastXYZ[2]);
327 
328  parameters.m_lineGapType = pandora::TPC_WIRE_GAP_VIEW_W;
329  parameters.m_lineStartZ = std::min(firstW, lastW) - halfWirePitch;
330  parameters.m_lineEndZ = std::max(firstW, lastW) + halfWirePitch;
331  }
332  else if (pandoraView == geo::kU)
333  {
334  const float firstU(pPandora->GetPlugins()->GetLArTransformationPlugin()->YZtoU(firstXYZ[1], firstXYZ[2]));
335  const float lastU(pPandora->GetPlugins()->GetLArTransformationPlugin()->YZtoU(lastXYZ[1], lastXYZ[2]));
336 
337  parameters.m_lineGapType = pandora::TPC_WIRE_GAP_VIEW_U;
338  parameters.m_lineStartZ = std::min(firstU, lastU) - halfWirePitch;
339  parameters.m_lineEndZ = std::max(firstU, lastU) + halfWirePitch;
340  }
341  else if (pandoraView == geo::kV)
342  {
343  const float firstV(pPandora->GetPlugins()->GetLArTransformationPlugin()->YZtoV(firstXYZ[1], firstXYZ[2]));
344  const float lastV(pPandora->GetPlugins()->GetLArTransformationPlugin()->YZtoV(lastXYZ[1], lastXYZ[2]));
345 
346  parameters.m_lineGapType = pandora::TPC_WIRE_GAP_VIEW_V;
347  parameters.m_lineStartZ = std::min(firstV, lastV) - halfWirePitch;
348  parameters.m_lineEndZ = std::max(firstV, lastV) + halfWirePitch;
349  }
350  }
351  catch (const pandora::StatusCodeException &)
352  {
353  mf::LogWarning("LArPandora") << "CreatePandoraReadoutGaps - invalid line gap parameter provided, all assigned values must be finite, line gap omitted " << std::endl;
354  continue;
355  }
356 
357  try
358  {
359  PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::Geometry::LineGap::Create(*pPandora, parameters));
360  }
361  catch (const pandora::StatusCodeException &)
362  {
363  mf::LogWarning("LArPandora") << "CreatePandoraReadoutGaps - unable to create line gap, insufficient or invalid information supplied " << std::endl;
364  continue;
365  }
366  }
367  }
368  }
369  }
370 }
static geo::View_t GetGlobalView(const unsigned int cstat, const unsigned int tpc, const geo::View_t hit_View)
Convert to global coordinate system.
WireGeo const & Wire(unsigned int iwire) const
Definition: PlaneGeo.cxx:506
enum geo::_plane_proj View_t
Enumerate the possible plane projections.
Planes which measure V.
Definition: geo_types.h:77
The data type to uniquely identify a Plane.
Definition: geo_types.h:250
Geometry information for a single TPC.
Definition: TPCGeo.h:37
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.
unsigned int Ncryostats() const
Returns the number of cryostats in the detector.
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.
TFile f
Definition: plotHisto.C:6
Planes which measure U.
Definition: geo_types.h:76
Int_t max
Definition: plot.C:27
intermediate_table::const_iterator const_iterator
Geometry information for a single wire plane.The plane is represented in the geometry by a solid whic...
Definition: PlaneGeo.h:78
CryostatGeo const & Cryostat(geo::CryostatID const &cryoid) const
Returns the specified cryostat.
unsigned int NTPC(unsigned int cstat=0) const
Returns the total number of TPCs in the specified cryostat.
raw::ChannelID_t PlaneWireToChannel(WireID const &wireid) const
Returns the ID of the TPC channel connected to the specified wire.
const TPCGeo & TPC(unsigned int itpc) const
Return the itpc&#39;th TPC in the cryostat.
Int_t min
Definition: plot.C:26
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
TPCGeo const & TPC(unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified TPC.
Planes which measure W (third view for Bo, MicroBooNE, etc).
Definition: geo_types.h:78
PlaneGeo const & Plane(geo::View_t view) const
Return the plane in the tpc with View_t view.
Definition: TPCGeo.cxx:299
void GetCenter(double *xyz, double localz=0.0) const
Fills the world coordinate of a point on the wire.
Definition: WireGeo.cxx:68
unsigned int ChannelID_t
Type representing the ID of a readout channel.
Definition: RawTypes.h:27
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
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 585 of file LArPandoraInput.cxx.

Referenced by CreatePandoraMCParticles().

586 {
587  for (const simb::MCParticle &mcParticle : mcParticleVector)
588  {
589  if ("primary" == mcParticle.Process())
590  {
591  primaryMCParticleMap.emplace(std::make_pair(mcParticle, false));
592  }
593  }
594 }
double lar_pandora::LArPandoraInput::GetMips ( 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 748 of file LArPandoraInput.cxx.

References util::kGeVToElectrons, lar_pandora::LArPandoraInput::Settings::m_dEdX_mip, lar_pandora::LArPandoraInput::Settings::m_mips_if_negative, lar_pandora::LArPandoraInput::Settings::m_mips_max, lar_pandora::LArPandoraInput::Settings::m_recombination_factor, lar_pandora::LArPandoraInput::Settings::m_useBirksCorrection, and geo::GeometryCore::WirePitch().

Referenced by CreatePandoraHits2D().

749 {
751  auto const* theDetector = lar::providerFrom<detinfo::DetectorPropertiesService>();
752 
753  // TODO: Unite this procedure with other calorimetry procedures under development
754  const double dQdX(hit_Charge / (theGeometry->WirePitch(hit_View))); // ADC/cm
755  const double dQdX_e(dQdX / (theDetector->ElectronsToADC() * settings.m_recombination_factor)); // e/cm
756  const double dEdX(settings.m_useBirksCorrection ? theDetector->BirksCorrection(dQdX_e) : dQdX_e * 1000. / util::kGeVToElectrons); // MeV/cm
757  double mips(dEdX / settings.m_dEdX_mip);
758 
759  if (mips < 0.)
760  mips = settings.m_mips_if_negative;
761 
762  if (mips > settings.m_mips_max)
763  mips = settings.m_mips_max;
764 
765  return mips;
766 }
geo::Length_t WirePitch(geo::PlaneID const &planeid) const
Returns the distance between two consecutive wires.
constexpr double kGeVToElectrons
23.6eV per ion pair, 1e9 eV/GeV
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 669 of file LArPandoraInput.cxx.

References geo::GeometryCore::Ncryostats(), and geo::GeometryCore::NTPC().

Referenced by CreatePandoraMCParticles().

670 {
672  firstT = -1; lastT = -1;
673 
674  for (unsigned int icstat = 0; icstat < theGeometry->Ncryostats(); ++icstat)
675  {
676  for (unsigned int itpc = 0; itpc < theGeometry->NTPC(icstat); ++itpc)
677  {
678  int thisfirstT(-1), thislastT(-1);
679  LArPandoraInput::GetTrueStartAndEndPoints(icstat, itpc, particle, thisfirstT, thislastT);
680 
681  if (thisfirstT < 0)
682  continue;
683 
684  if (firstT < 0 || thisfirstT < firstT)
685  firstT = thisfirstT;
686 
687  if (lastT < 0 || thislastT > lastT)
688  lastT = thislastT;
689  }
690  }
691 }
unsigned int Ncryostats() const
Returns the number of cryostats in the detector.
unsigned int NTPC(unsigned int cstat=0) const
Returns the total number of TPCs in the specified cryostat.
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 695 of file LArPandoraInput.cxx.

References geo::CryostatID::Cryostat, geo::GeometryCore::FindTPCAtPosition(), geo::CryostatID::isValid, simb::MCParticle::NumberTrajectoryPoints(), geo::TPCID::TPC, simb::MCParticle::Vx(), simb::MCParticle::Vy(), and simb::MCParticle::Vz().

697 {
699 
700  bool foundStartPosition(false);
701  const int numTrajectoryPoints(static_cast<int>(particle->NumberTrajectoryPoints()));
702 
703  for (int nt = 0; nt < numTrajectoryPoints; ++nt)
704  {
705  const double pos[3] = {particle->Vx(nt), particle->Vy(nt), particle->Vz(nt)};
706  geo::TPCID tpcID = theGeometry->FindTPCAtPosition(pos);
707 
708  if (!tpcID.isValid)
709  continue;
710 
711  if (!(cstat == tpcID.Cryostat && tpc == tpcID.TPC))
712  continue;
713 
714  endT = nt;
715 
716  if (!foundStartPosition)
717  {
718  startT = endT;
719  foundStartPosition = true;
720  }
721  }
722 }
unsigned int NumberTrajectoryPoints() const
Definition: MCParticle.h:222
bool isValid
Whether this ID points to a valid element.
Definition: geo_types.h:129
CryostatID_t Cryostat
Index of cryostat.
Definition: geo_types.h:130
geo::TPCID FindTPCAtPosition(double const worldLoc[3]) const
Returns the ID of the TPC at specified location.
The data type to uniquely identify a TPC.
Definition: geo_types.h:195
double Vx(const int i=0) const
Definition: MCParticle.h:225
double Vz(const int i=0) const
Definition: MCParticle.h:227
TPCID_t TPC
Index of the TPC within its cryostat.
Definition: geo_types.h:203
double Vy(const int i=0) const
Definition: MCParticle.h:226
float lar_pandora::LArPandoraInput::GetTrueX0 ( 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
particlethe true particle
nTthe trajectory point

Definition at line 726 of file LArPandoraInput.cxx.

References geo::GeometryCore::Cryostat(), geo::kNegX, geo::GeometryCore::PositionToTPC(), simb::MCParticle::T(), geo::CryostatGeo::TPC(), simb::MCParticle::Vx(), simb::MCParticle::Vy(), and simb::MCParticle::Vz().

727 {
729  auto const* theTime = lar::providerFrom<detinfo::DetectorClocksService>();
730  auto const* theDetector = lar::providerFrom<detinfo::DetectorPropertiesService>();
731 
732  unsigned int which_tpc(0);
733  unsigned int which_cstat(0);
734  double pos[3] = {particle->Vx(nt), particle->Vy(nt), particle->Vz(nt)};
735  theGeometry->PositionToTPC(pos, which_tpc, which_cstat);
736 
737  const float vtxT(particle->T(nt));
738  const float vtxTDC(theTime->TPCG4Time2Tick(vtxT));
739  const float vtxTDC0(theDetector->TriggerOffset());
740 
741  const geo::TPCGeo &theTpc = theGeometry->Cryostat(which_cstat).TPC(which_tpc);
742  const float driftDir((theTpc.DriftDirection() == geo::kNegX) ? +1.0 :-1.0);
743  return (driftDir * (vtxTDC - vtxTDC0) * theDetector->GetXTicksCoefficient());
744 }
Geometry information for a single TPC.
Definition: TPCGeo.h:37
Drift towards negative X values.
Definition: geo_types.h:109
geo::TPCGeo const & PositionToTPC(geo::Point_t const &point) const
Returns the TPC at specified location.
double T(const int i=0) const
Definition: MCParticle.h:228
CryostatGeo const & Cryostat(geo::CryostatID const &cryoid) const
Returns the specified cryostat.
double Vx(const int i=0) const
Definition: MCParticle.h:225
const TPCGeo & TPC(unsigned int itpc) const
Return the itpc&#39;th TPC in the cryostat.
double Vz(const int i=0) const
Definition: MCParticle.h:227
double Vy(const int i=0) const
Definition: MCParticle.h:226
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 598 of file LArPandoraInput.cxx.

References simb::MCParticle::Px(), simb::MCParticle::Py(), and simb::MCParticle::Pz().

Referenced by CreatePandoraMCParticles().

599 {
600  for (auto &mcParticleIter : primaryMCParticleMap)
601  {
602  if (!mcParticleIter.second)
603  {
604  const simb::MCParticle primaryMCParticle(mcParticleIter.first);
605 
606  if (std::fabs(primaryMCParticle.Px() - mcParticle->Px()) < std::numeric_limits<double>::epsilon() &&
607  std::fabs(primaryMCParticle.Py() - mcParticle->Py()) < std::numeric_limits<double>::epsilon() &&
608  std::fabs(primaryMCParticle.Pz() - mcParticle->Pz()) < std::numeric_limits<double>::epsilon())
609  {
610  mcParticleIter.second = true;
611  return true;
612  }
613  }
614  }
615  return false;
616 }
double Py(const int i=0) const
Definition: MCParticle.h:235
double Px(const int i=0) const
Definition: MCParticle.h:234
double Pz(const int i=0) const
Definition: MCParticle.h:236

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