LArSoft  v09_90_00
Liquid Argon Software toolkit - https://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 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::MCProcessMCProcessMap
 

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 geo::TPCID &ref_tpcid, 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 29 of file LArPandoraInput.h.

Member Typedef Documentation

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

References lar_pandora::LArPandoraDetectorType::CreateLineGapParametersFromDetectorGaps(), lar_pandora::detector_functions::GetDetectorType(), and lar_pandora::LArPandoraInput::Settings::m_pPrimaryPandora.

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

241  {
242  //ATTN - Unlike SP, DP detector gaps are not in the drift direction
244  LArPandoraDetectorType* detType(detector_functions::GetDetectorType());
245 
246  mf::LogDebug("LArPandora") << " *** LArPandoraInput::CreatePandoraDetectorGaps(...) *** "
247  << std::endl;
248 
249  if (!settings.m_pPrimaryPandora)
250  throw cet::exception("LArPandora")
251  << "CreatePandoraDetectorGaps - primary Pandora instance does not exist ";
252 
253  const pandora::Pandora* pPandora(settings.m_pPrimaryPandora);
254 
255  for (const LArDetectorGap& gap : listOfGaps) {
256  PandoraApi::Geometry::LineGap::Parameters parameters;
257 
258  try {
259  parameters = detType->CreateLineGapParametersFromDetectorGaps(gap);
260  }
261  catch (const pandora::StatusCodeException&) {
262  mf::LogWarning("LArPandora")
263  << "CreatePandoraDetectorGaps - invalid line gap parameter provided, all assigned values "
264  "must be finite, line gap omitted "
265  << std::endl;
266  continue;
267  }
268  try {
269  PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS,
270  !=,
271  PandoraApi::Geometry::LineGap::Create(*pPandora, parameters));
272  }
273  catch (const pandora::StatusCodeException&) {
274  mf::LogWarning("LArPandora") << "CreatePandoraDetectorGaps - unable to create line gap, "
275  "insufficient or invalid information supplied "
276  << std::endl;
277  continue;
278  }
279  }
280  }
LArPandoraDetectorType * GetDetectorType()
Factory class that returns the correct detector type interface.
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 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.

References geo::WireGeo::GetCenter(), lar_pandora::LArPandoraGeometry::GetDaughterVolumeID(), lar_pandora::detector_functions::GetDetectorType(), GetMips(), lar_pandora::LArPandoraGeometry::GetVolumeID(), recob::Hit::Integral(), lar_content::LArCaloHitParameters::m_daughterVolumeId, lar_pandora::LArPandoraInput::Settings::m_dx_cm, lar_pandora::LArPandoraInput::Settings::m_hitCounterOffset, 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(), lar_pandora::LArPandoraDetectorType::TargetViewU(), lar_pandora::LArPandoraDetectorType::TargetViewV(), lar_pandora::LArPandoraDetectorType::TargetViewW(), recob::Hit::View(), geo::GeometryCore::Wire(), recob::Hit::WireID(), and geo::GeometryCore::WirePitch().

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

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 
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  auto const xyz = theGeometry->Wire(hit_WireID).GetCenter();
93  const double y0_cm(xyz.Y());
94  const double z0_cm(xyz.Z());
95 
96  // Get other hit properties here
97  const double wire_pitch_cm(theGeometry->WirePitch(hit_View)); // cm
98  const double mips(LArPandoraInput::GetMips(detProp, settings, hit_Charge, hit_View));
99 
100  // Create Pandora CaloHit
101  lar_content::LArCaloHitParameters caloHitParameters;
102 
103  try {
104  caloHitParameters.m_expectedDirection = pandora::CartesianVector(0., 0., 1.);
105  caloHitParameters.m_cellNormalVector = pandora::CartesianVector(0., 0., 1.);
106  caloHitParameters.m_cellSize0 = settings.m_dx_cm;
107  caloHitParameters.m_cellSize1 = (settings.m_useHitWidths ? dxpos_cm : settings.m_dx_cm);
108  caloHitParameters.m_cellThickness = wire_pitch_cm;
109  caloHitParameters.m_cellGeometry = pandora::RECTANGULAR;
110  caloHitParameters.m_time = 0.;
111  caloHitParameters.m_nCellRadiationLengths = settings.m_dx_cm / settings.m_rad_cm;
112  caloHitParameters.m_nCellInteractionLengths = settings.m_dx_cm / settings.m_int_cm;
113  caloHitParameters.m_isDigital = false;
114  caloHitParameters.m_hitRegion = pandora::SINGLE_REGION;
115  caloHitParameters.m_layer = 0;
116  caloHitParameters.m_isInOuterSamplingLayer = false;
117  caloHitParameters.m_inputEnergy = hit_Charge;
118  caloHitParameters.m_mipEquivalentEnergy = mips;
119  caloHitParameters.m_electromagneticEnergy = mips * settings.m_mips_to_gev;
120  caloHitParameters.m_hadronicEnergy = mips * settings.m_mips_to_gev;
121  caloHitParameters.m_pParentAddress = (void*)((intptr_t)(++hitCounter));
122  caloHitParameters.m_larTPCVolumeId =
123  LArPandoraGeometry::GetVolumeID(driftVolumeMap, hit_WireID.Cryostat, hit_WireID.TPC);
125  driftVolumeMap, hit_WireID.Cryostat, hit_WireID.TPC);
126 
127  if (hit_View == detType->TargetViewW(hit_WireID.TPC, hit_WireID.Cryostat)) {
128  caloHitParameters.m_hitType = pandora::TPC_VIEW_W;
129  const double wpos_cm(
130  pPandora->GetPlugins()->GetLArTransformationPlugin()->YZtoW(y0_cm, z0_cm));
131  caloHitParameters.m_positionVector = pandora::CartesianVector(xpos_cm, 0., wpos_cm);
132  }
133  else if (hit_View == detType->TargetViewU(hit_WireID.TPC, hit_WireID.Cryostat)) {
134  caloHitParameters.m_hitType = pandora::TPC_VIEW_U;
135  const double upos_cm(
136  pPandora->GetPlugins()->GetLArTransformationPlugin()->YZtoU(y0_cm, z0_cm));
137  caloHitParameters.m_positionVector = pandora::CartesianVector(xpos_cm, 0., upos_cm);
138  }
139  else if (hit_View == detType->TargetViewV(hit_WireID.TPC, hit_WireID.Cryostat)) {
140  caloHitParameters.m_hitType = pandora::TPC_VIEW_V;
141  const double vpos_cm(
142  pPandora->GetPlugins()->GetLArTransformationPlugin()->YZtoV(y0_cm, z0_cm));
143  caloHitParameters.m_positionVector = pandora::CartesianVector(xpos_cm, 0., vpos_cm);
144  }
145  else {
146  throw cet::exception("LArPandora")
147  << "CreatePandoraHits2D - this wire view not recognised (View=" << hit_View << ") ";
148  }
149  }
150  catch (const pandora::StatusCodeException&) {
151  mf::LogWarning("LArPandora")
152  << "CreatePandoraHits2D - invalid calo hit parameter provided, all assigned values must "
153  "be finite, calo hit omitted "
154  << std::endl;
155  continue;
156  }
157 
158  // Store the hit address
159  if (hitCounter >= settings.m_uidOffset)
160  throw cet::exception("LArPandora")
161  << "CreatePandoraHits2D - detected an excessive number of hits (" << hitCounter << ") ";
162 
163  idToHitMap[hitCounter] = hit;
164 
165  // Create the Pandora hit
166  try {
167  PANDORA_THROW_RESULT_IF(
168  pandora::STATUS_CODE_SUCCESS,
169  !=,
170  PandoraApi::CaloHit::Create(*pPandora, caloHitParameters, caloHitFactory));
171  }
172  catch (const pandora::StatusCodeException&) {
173  mf::LogWarning("LArPandora") << "CreatePandoraHits2D - unable to create calo hit, "
174  "insufficient or invalid information supplied "
175  << std::endl;
176  continue;
177  }
178  }
179  }
Point_t const & GetCenter() const
Returns the world coordinate of the center of the wire [cm].
Definition: WireGeo.h:221
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.
float Integral() const
Integral under the calibrated signal waveform of the hit, in tick x ADC units.
Definition: Hit.h:244
geo::View_t View() const
View for the plane of the hit.
Definition: Hit.h:276
intermediate_table::const_iterator const_iterator
pandora::InputUInt m_larTPCVolumeId
The lar tpc volume id.
Definition: LArCaloHit.h:30
geo::WireID const & WireID() const
Initial tdc tick for hit.
Definition: Hit.h:280
WireGeo const & Wire(WireID const &wireid) const
Returns the specified wire.
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
float PeakTimeMinusRMS(float sigmas=+1.) const
Returns a time sigmas RMS away from the peak time.
Definition: Hit.h:290
Detector simulation of raw signals on wires.
float PeakTime() const
Time of the signal peak, in tick units.
Definition: Hit.h:220
LArPandoraDetectorType * GetDetectorType()
Factory class that returns the correct detector type interface.
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
LArCaloHitFactory responsible for object creation.
Definition: LArCaloHit.h:110
float PeakTimePlusRMS(float sigmas=+1.) const
Returns a time sigmas RMS away from the peak time.
Definition: Hit.h:285
Float_t e
Definition: plot.C:35
Length_t WirePitch(PlaneID const &planeid=plane_zero) const
Returns the distance between two consecutive wires.
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 183 of file LArPandoraInput.cxx.

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

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

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

References util::abs(), and lar_pandora::LArPandoraInput::Settings::m_pPrimaryPandora.

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

664  {
665  mf::LogDebug("LArPandora") << " *** LArPandoraInput::CreatePandoraMCLinks(...) *** "
666  << std::endl;
667 
668  if (!settings.m_pPrimaryPandora)
669  throw cet::exception("LArPandora")
670  << "CreatePandoraMCLinks2D - primary Pandora instance does not exist ";
671 
672  const pandora::Pandora* pPandora(settings.m_pPrimaryPandora);
673 
674  for (IdToHitMap::const_iterator iterI = idToHitMap.begin(), iterEndI = idToHitMap.end();
675  iterI != iterEndI;
676  ++iterI) {
677  const int hitID(iterI->first);
678  const art::Ptr<recob::Hit> hit(iterI->second);
679  // const geo::WireID hit_WireID(hit->WireID());
680 
681  // Get list of associated MC particles
682  HitsToTrackIDEs::const_iterator iterJ = hitToParticleMap.find(hit);
683 
684  if (hitToParticleMap.end() == iterJ) continue;
685 
686  const TrackIDEVector& trackCollection = iterJ->second;
687 
688  if (trackCollection.size() == 0)
689  throw cet::exception("LArPandora")
690  << "CreatePandoraMCLinks2D - found a hit without any associated MC truth information ";
691 
692  // Create links between hits and MC particles
693  for (unsigned int k = 0; k < trackCollection.size(); ++k) {
694  const sim::TrackIDE trackIDE(trackCollection.at(k));
695  const int trackID(std::abs(trackIDE.trackID)); // TODO: Find out why std::abs is needed
696  const float energyFrac(trackIDE.energyFrac);
697 
698  try {
699  PANDORA_THROW_RESULT_IF(
700  pandora::STATUS_CODE_SUCCESS,
701  !=,
702  PandoraApi::SetCaloHitToMCParticleRelationship(
703  *pPandora, (void*)((intptr_t)hitID), (void*)((intptr_t)trackID), energyFrac));
704  }
705  catch (const pandora::StatusCodeException&) {
706  mf::LogWarning("LArPandora") << "CreatePandoraMCLinks2D - unable to create calo hit to "
707  "mc particle relationship, invalid information supplied "
708  << std::endl;
709  continue;
710  }
711  }
712  }
713  }
constexpr auto abs(T v)
Returns the absolute value of the argument.
intermediate_table::const_iterator const_iterator
std::vector< sim::TrackIDE > TrackIDEVector
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:26
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 373 of file LArPandoraInput.cxx.

References E, simb::MCParticle::E(), FillMCProcessMap(), FindPrimaryParticles(), simb::MCTruth::GetNeutrino(), GetTrueStartAndEndPoints(), IsPrimaryMCParticle(), simb::kCosmicRay, simb::kSingleParticle, lar_content::LArMCParticleParameters::m_nuanceCode, lar_pandora::LArPandoraInput::Settings::m_pPrimaryPandora, lar_content::LArMCParticleParameters::m_process, lar_pandora::LArPandoraInput::Settings::m_uidOffset, lar_content::MC_PROC_INCIDENT_NU, lar_content::MC_PROC_UNKNOWN, simb::MCParticle::Mother(), simb::MCTruth::NeutrinoSet(), simb::MCTruth::Origin(), geo::origin(), simb::MCParticle::PdgCode(), simb::MCParticle::Process(), 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().

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

References lar_pandora::LArPandoraDetectorType::CreateLineGapParametersFromReadoutGaps(), f, lar_pandora::detector_functions::GetDetectorType(), lar_pandora::LArPandoraGeometry::GetVolumeID(), geo::GeometryCore::Iterate(), lar_pandora::LArPandoraInput::Settings::m_pPrimaryPandora, geo::GeometryCore::Nwires(), geo::GeometryCore::PlaneWireToChannel(), and geo::GeometryCore::WirePitch().

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

286  {
287  mf::LogDebug("LArPandora") << " *** LArPandoraInput::CreatePandoraReadoutGaps(...) *** "
288  << std::endl;
289 
290  if (!settings.m_pPrimaryPandora)
291  throw cet::exception("LArPandora")
292  << "CreatePandoraReadoutGaps - primary Pandora instance does not exist ";
293 
294  const pandora::Pandora* pPandora(settings.m_pPrimaryPandora);
295 
297  const lariov::ChannelStatusProvider& channelStatus(
299 
300  LArPandoraDetectorType* detType(detector_functions::GetDetectorType());
301 
302  for (auto const& plane : theGeometry->Iterate<geo::PlaneGeo>()) {
303  const float halfWirePitch(0.5f * theGeometry->WirePitch(plane.View()));
304  const unsigned int nWires(theGeometry->Nwires(plane.ID()));
305 
306  int firstBadWire(-1), lastBadWire(-1);
307 
308  for (unsigned int iwire = 0; iwire < nWires; ++iwire) {
309  const raw::ChannelID_t channel(
310  theGeometry->PlaneWireToChannel(geo::WireID{plane.ID(), iwire}));
311  const bool isBadChannel(channelStatus.IsBad(channel));
312  const bool isLastWire(nWires == (iwire + 1));
313 
314  if (isBadChannel && (firstBadWire < 0)) firstBadWire = iwire;
315 
316  if (isBadChannel || isLastWire) lastBadWire = iwire;
317 
318  if (isBadChannel && !isLastWire) continue;
319 
320  if ((firstBadWire < 0) || (lastBadWire < 0)) continue;
321 
322  auto const firstXYZ = plane.Wire(firstBadWire).GetCenter();
323  auto const lastXYZ = plane.Wire(lastBadWire).GetCenter();
324 
325  firstBadWire = -1;
326  lastBadWire = -1;
327 
328  PandoraApi::Geometry::LineGap::Parameters parameters;
329 
330  try {
331  float xFirst(-std::numeric_limits<float>::max());
332  float xLast(std::numeric_limits<float>::max());
333 
334  auto const [icstat, itpc] = std::make_pair(plane.ID().Cryostat, plane.ID().TPC);
335  const unsigned int volumeId(
336  LArPandoraGeometry::GetVolumeID(driftVolumeMap, icstat, itpc));
337  LArDriftVolumeMap::const_iterator volumeIter(driftVolumeMap.find(volumeId));
338 
339  if (driftVolumeMap.end() != volumeIter) {
340  xFirst = volumeIter->second.GetCenterX() - 0.5f * volumeIter->second.GetWidthX();
341  xLast = volumeIter->second.GetCenterX() + 0.5f * volumeIter->second.GetWidthX();
342  }
343 
344  const geo::View_t iview = plane.View();
345  parameters = detType->CreateLineGapParametersFromReadoutGaps(
346  iview, itpc, icstat, firstXYZ, lastXYZ, halfWirePitch, xFirst, xLast, pPandora);
347  }
348  catch (const pandora::StatusCodeException&) {
349  mf::LogWarning("LArPandora")
350  << "CreatePandoraReadoutGaps - invalid line gap parameter provided, all assigned "
351  "values must be finite, line gap omitted "
352  << std::endl;
353  continue;
354  }
355 
356  try {
357  PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS,
358  !=,
359  PandoraApi::Geometry::LineGap::Create(*pPandora, parameters));
360  }
361  catch (const pandora::StatusCodeException&) {
362  mf::LogWarning("LArPandora") << "CreatePandoraReadoutGaps - unable to create line "
363  "gap, insufficient or invalid information supplied "
364  << std::endl;
365  continue;
366  }
367  }
368  }
369  }
details::range_type< T > Iterate() const
Initializes the specified ID with the ID of the first cryostat.
Definition: GeometryCore.h:541
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.
intermediate_table::const_iterator const_iterator
TFile f
Definition: plotHisto.C:6
Geometry information for a single wire plane.The plane is represented in the geometry by a solid whic...
Definition: PlaneGeo.h:78
raw::ChannelID_t PlaneWireToChannel(WireID const &wireid) const
Returns the ID of the TPC channel connected to the specified wire.
LArPandoraDetectorType * GetDetectorType()
Factory class that returns the correct detector type interface.
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
unsigned int Nwires(PlaneID const &planeid) const
Returns the total number of wires in the specified plane.
unsigned int ChannelID_t
Type representing the ID of a readout channel.
Definition: RawTypes.h:28
Length_t WirePitch(PlaneID const &planeid=plane_zero) const
Returns the distance between two consecutive wires.
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
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 817 of file LArPandoraInput.cxx.

References lar_content::MC_PROC_ALPHA_INELASTIC, lar_content::MC_PROC_ANNIHIL, lar_content::MC_PROC_ANTI_ALPHA_INELASTIC, lar_content::MC_PROC_ANTI_DEUTERON_INELASTIC, lar_content::MC_PROC_ANTI_HE3_INELASTIC, lar_content::MC_PROC_ANTI_NEUTRON_INELASTIC, lar_content::MC_PROC_ANTI_PROTON_INELASTIC, lar_content::MC_PROC_ANTI_TRITON_INELASTIC, lar_content::MC_PROC_CHIPS_NUCLEAR_CAPTURE_AT_REST, lar_content::MC_PROC_COMPT, lar_content::MC_PROC_CONV, lar_content::MC_PROC_COULOMB_SCAT, lar_content::MC_PROC_DECAY, lar_content::MC_PROC_DEUTERON_INELASTIC, lar_content::MC_PROC_E_BREM, lar_content::MC_PROC_E_IONI, lar_content::MC_PROC_ELECTRON_NUCLEAR, lar_content::MC_PROC_HAD_BERTINI_CAPTURE_AT_REST, lar_content::MC_PROC_HAD_BREM, lar_content::MC_PROC_HAD_ELASTIC, lar_content::MC_PROC_HAD_FRITIOF_CAPTURE_AT_REST, lar_content::MC_PROC_HAD_IONI, lar_content::MC_PROC_HAD_PAIR_PROD, lar_content::MC_PROC_HE3_INELASTIC, lar_content::MC_PROC_ION_INELASTIC, lar_content::MC_PROC_ION_IONI, lar_content::MC_PROC_KAON_MINUS_INELASTIC, lar_content::MC_PROC_KAON_PLUS_INELASTIC, lar_content::MC_PROC_LAMBDA_INELASTIC, lar_content::MC_PROC_MU_BREM, lar_content::MC_PROC_MU_IONI, lar_content::MC_PROC_MU_MINUS_CAPTURE_AT_REST, lar_content::MC_PROC_MU_NUCLEAR, lar_content::MC_PROC_MU_PAIR_PROD, lar_content::MC_PROC_N_CAPTURE, lar_content::MC_PROC_NEUTRON_INELASTIC, lar_content::MC_PROC_NEUTRON_KILLER, lar_content::MC_PROC_PHOT, lar_content::MC_PROC_PHOTON_INELASTIC, lar_content::MC_PROC_PHOTON_NUCLEAR, lar_content::MC_PROC_PI_MINUS_INELASTIC, lar_content::MC_PROC_PI_PLUS_INELASTIC, lar_content::MC_PROC_PRIMARY, lar_content::MC_PROC_PRIMARY_BACKGROUND, lar_content::MC_PROC_PROTON_INELASTIC, lar_content::MC_PROC_RAYLEIGH, lar_content::MC_PROC_TRANSPORTATION, lar_content::MC_PROC_TRITON_INELASTIC, and lar_content::MC_PROC_UNKNOWN.

Referenced by CreatePandoraMCParticles().

818  {
819  // QGSP_BERT and EM standard physics list mappings
820  processMap["unknown"] = lar_content::MC_PROC_UNKNOWN;
821  processMap["primary"] = lar_content::MC_PROC_PRIMARY;
822  processMap["compt"] = lar_content::MC_PROC_COMPT;
823  processMap["phot"] = lar_content::MC_PROC_PHOT;
824  processMap["annihil"] = lar_content::MC_PROC_ANNIHIL;
825  processMap["eIoni"] = lar_content::MC_PROC_E_IONI;
826  processMap["eBrem"] = lar_content::MC_PROC_E_BREM;
827  processMap["conv"] = lar_content::MC_PROC_CONV;
828  processMap["muIoni"] = lar_content::MC_PROC_MU_IONI;
829  processMap["muMinusCaptureAtRest"] = lar_content::MC_PROC_MU_MINUS_CAPTURE_AT_REST;
830  processMap["neutronInelastic"] = lar_content::MC_PROC_NEUTRON_INELASTIC;
831  processMap["nCapture"] = lar_content::MC_PROC_N_CAPTURE;
832  processMap["hadElastic"] = lar_content::MC_PROC_HAD_ELASTIC;
833  processMap["Decay"] = lar_content::MC_PROC_DECAY;
834  processMap["CoulombScat"] = lar_content::MC_PROC_COULOMB_SCAT;
835  processMap["muBrems"] = lar_content::MC_PROC_MU_BREM;
836  processMap["muPairProd"] = lar_content::MC_PROC_MU_PAIR_PROD;
837  processMap["PhotonInelastic"] = lar_content::MC_PROC_PHOTON_INELASTIC;
838  processMap["hIoni"] = lar_content::MC_PROC_HAD_IONI;
839  processMap["protonInelastic"] = lar_content::MC_PROC_PROTON_INELASTIC;
840  processMap["pi+Inelastic"] = lar_content::MC_PROC_PI_PLUS_INELASTIC;
841  processMap["CHIPSNuclearCaptureAtRest"] = lar_content::MC_PROC_CHIPS_NUCLEAR_CAPTURE_AT_REST;
842  processMap["pi-Inelastic"] = lar_content::MC_PROC_PI_MINUS_INELASTIC;
843  processMap["Transportation"] = lar_content::MC_PROC_TRANSPORTATION;
844  processMap["Rayl"] = lar_content::MC_PROC_RAYLEIGH;
845  processMap["hBrems"] = lar_content::MC_PROC_HAD_BREM;
846  processMap["hPairProd"] = lar_content::MC_PROC_HAD_PAIR_PROD;
847  processMap["ionIoni"] = lar_content::MC_PROC_ION_IONI;
848  processMap["nKiller"] = lar_content::MC_PROC_NEUTRON_KILLER;
849  processMap["ionInelastic"] = lar_content::MC_PROC_ION_INELASTIC;
850  processMap["He3Inelastic"] = lar_content::MC_PROC_HE3_INELASTIC;
851  processMap["alphaInelastic"] = lar_content::MC_PROC_ALPHA_INELASTIC;
852  processMap["anti_He3Inelastic"] = lar_content::MC_PROC_ANTI_HE3_INELASTIC;
853  processMap["anti_alphaInelastic"] = lar_content::MC_PROC_ANTI_ALPHA_INELASTIC;
854  processMap["hFritiofCaptureAtRest"] = lar_content::MC_PROC_HAD_FRITIOF_CAPTURE_AT_REST;
855  processMap["anti_deuteronInelastic"] = lar_content::MC_PROC_ANTI_DEUTERON_INELASTIC;
856  processMap["anti_neutronInelastic"] = lar_content::MC_PROC_ANTI_NEUTRON_INELASTIC;
857  processMap["anti_protonInelastic"] = lar_content::MC_PROC_ANTI_PROTON_INELASTIC;
858  processMap["anti_tritonInelastic"] = lar_content::MC_PROC_ANTI_TRITON_INELASTIC;
859  processMap["dInelastic"] = lar_content::MC_PROC_DEUTERON_INELASTIC;
860  processMap["electronNuclear"] = lar_content::MC_PROC_ELECTRON_NUCLEAR;
861  processMap["photonNuclear"] = lar_content::MC_PROC_PHOTON_NUCLEAR;
862  processMap["kaon+Inelastic"] = lar_content::MC_PROC_KAON_PLUS_INELASTIC;
863  processMap["kaon-Inelastic"] = lar_content::MC_PROC_KAON_MINUS_INELASTIC;
864  processMap["hBertiniCaptureAtRest"] = lar_content::MC_PROC_HAD_BERTINI_CAPTURE_AT_REST;
865  processMap["lambdaInelastic"] = lar_content::MC_PROC_LAMBDA_INELASTIC;
866  processMap["muonNuclear"] = lar_content::MC_PROC_MU_NUCLEAR;
867  processMap["tInelastic"] = lar_content::MC_PROC_TRITON_INELASTIC;
868  processMap["primaryBackground"] = lar_content::MC_PROC_PRIMARY_BACKGROUND;
869  }
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 624 of file LArPandoraInput.cxx.

Referenced by CreatePandoraMCParticles().

627  {
628  for (const simb::MCParticle& mcParticle : mcParticleVector) {
629  if ("primary" == mcParticle.Process()) {
630  primaryMCParticleMap.emplace(std::make_pair(mcParticle, false));
631  }
632  }
633  }
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 792 of file LArPandoraInput.cxx.

References detinfo::DetectorPropertiesData::BirksCorrection(), detinfo::DetectorPropertiesData::ElectronsToADC(), 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().

796  {
798 
799  // TODO: Unite this procedure with other calorimetry procedures under development
800  const double dQdX(hit_Charge / (theGeometry->WirePitch(hit_View))); // ADC/cm
801  const double dQdX_e(dQdX /
802  (detProp.ElectronsToADC() * settings.m_recombination_factor)); // e/cm
803  const double dEdX(settings.m_useBirksCorrection ?
804  detProp.BirksCorrection(dQdX_e) :
805  dQdX_e * 1000. / util::kGeVToElectrons); // MeV/cm
806  double mips(dEdX / settings.m_dEdX_mip);
807 
808  if (mips < 0.) mips = settings.m_mips_if_negative;
809 
810  if (mips > settings.m_mips_max) mips = settings.m_mips_max;
811 
812  return mips;
813  }
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.
Length_t WirePitch(PlaneID const &planeid=plane_zero) const
Returns the distance between two consecutive wires.
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 717 of file LArPandoraInput.cxx.

References geo::GeometryCore::Iterate().

Referenced by CreatePandoraMCParticles().

721  {
723  firstT = -1;
724  lastT = -1;
725 
726  for (auto const& tpcid : theGeometry->Iterate<geo::TPCID>()) {
727  int thisfirstT(-1), thislastT(-1);
728  LArPandoraInput::GetTrueStartAndEndPoints(tpcid, particle, thisfirstT, thislastT);
729 
730  if (thisfirstT < 0) continue;
731 
732  if (firstT < 0 || thisfirstT < firstT) firstT = thisfirstT;
733 
734  if (lastT < 0 || thislastT > lastT) lastT = thislastT;
735  }
736  }
details::range_type< T > Iterate() const
Initializes the specified ID with the ID of the first cryostat.
Definition: GeometryCore.h:541
The data type to uniquely identify a TPC.
Definition: geo_types.h:381
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 geo::TPCID ref_tpcid,
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 740 of file LArPandoraInput.cxx.

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

744  {
746 
747  bool foundStartPosition(false);
748  const int numTrajectoryPoints(static_cast<int>(particle->NumberTrajectoryPoints()));
749 
750  for (int nt = 0; nt < numTrajectoryPoints; ++nt) {
751  const geo::Point_t pos{particle->Vx(nt), particle->Vy(nt), particle->Vz(nt)};
752  geo::TPCID tpcID = theGeometry->FindTPCAtPosition(pos);
753 
754  if (!tpcID.isValid) continue;
755 
756  if (tpcID != ref_tpcid) continue;
757 
758  endT = nt;
759 
760  if (!foundStartPosition) {
761  startT = endT;
762  foundStartPosition = true;
763  }
764  }
765  }
unsigned int NumberTrajectoryPoints() const
Definition: MCParticle.h:219
bool isValid
Whether this ID points to a valid element.
Definition: geo_types.h:210
TPCID FindTPCAtPosition(Point_t const &point) const
Returns the ID of the TPC at specified location.
The data type to uniquely identify a TPC.
Definition: geo_types.h:381
double Vx(const int i=0) const
Definition: MCParticle.h:222
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
Definition: geo_vectors.h:180
double Vz(const int i=0) const
Definition: MCParticle.h:224
double Vy(const int i=0) const
Definition: MCParticle.h:223
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 769 of file LArPandoraInput.cxx.

References geo::TPCGeo::DriftDirection(), geo::kNegX, geo::GeometryCore::PositionToTPCID(), simb::MCParticle::T(), geo::GeometryCore::TPC(), detinfo::trigger_offset(), simb::MCParticle::Vx(), simb::MCParticle::Vy(), and simb::MCParticle::Vz().

772  {
774  auto const clock_data = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(e);
775  auto const det_prop =
777 
778  geo::Point_t const pos{particle->Vx(nt), particle->Vy(nt), particle->Vz(nt)};
779  auto const tpcID = theGeometry->PositionToTPCID(pos);
780 
781  const float vtxT(particle->T(nt));
782  const float vtxTDC(clock_data.TPCG4Time2Tick(vtxT));
783  const float vtxTDC0(trigger_offset(clock_data));
784 
785  const geo::TPCGeo& theTpc = theGeometry->TPC(tpcID);
786  const float driftDir((theTpc.DriftDirection() == geo::kNegX) ? +1.0 : -1.0);
787  return (driftDir * (vtxTDC - vtxTDC0) * det_prop.GetXTicksCoefficient());
788  }
Geometry information for a single TPC.
Definition: TPCGeo.h:36
Drift towards negative X values.
Definition: geo_types.h:167
TPCGeo const & TPC(TPCID const &tpcid=tpc_zero) const
Returns the specified TPC.
Definition: GeometryCore.h:722
double T(const int i=0) const
Definition: MCParticle.h:225
DriftDirection_t DriftDirection() const
Returns an enumerator value describing the drift direction.
Definition: TPCGeo.h:121
double Vx(const int i=0) const
Definition: MCParticle.h:222
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
Definition: geo_vectors.h:180
double Vz(const int i=0) const
Definition: MCParticle.h:224
int trigger_offset(DetectorClocksData const &data)
Float_t e
Definition: plot.C:35
TPCID PositionToTPCID(Point_t const &point) const
Returns the ID of the TPC at specified location.
double Vy(const int i=0) const
Definition: MCParticle.h:223
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 637 of file LArPandoraInput.cxx.

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

Referenced by CreatePandoraMCParticles().

640  {
641  for (auto& mcParticleIter : primaryMCParticleMap) {
642  if (!mcParticleIter.second) {
643  const simb::MCParticle primaryMCParticle(mcParticleIter.first);
644 
645  if (std::fabs(primaryMCParticle.Px() - mcParticle->Px()) <
646  std::numeric_limits<double>::epsilon() &&
647  std::fabs(primaryMCParticle.Py() - mcParticle->Py()) <
648  std::numeric_limits<double>::epsilon() &&
649  std::fabs(primaryMCParticle.Pz() - mcParticle->Pz()) <
650  std::numeric_limits<double>::epsilon()) {
651  mcParticleIter.second = true;
652  return true;
653  }
654  }
655  }
656  return false;
657  }
double Py(const int i=0) const
Definition: MCParticle.h:232
double Px(const int i=0) const
Definition: MCParticle.h:231
double Pz(const int i=0) const
Definition: MCParticle.h:233

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