2 #include "nug4/MagneticFieldServices/MagneticFieldService.h" 4 #include "canvas/Persistency/Common/FindManyP.h" 5 #include "canvas/Persistency/Common/FindOneP.h" 7 #include "CoreUtils/ServiceUtil.h" 13 #include "MCCheater/BackTracker.h" 15 #include "Pandora/PdgTable.h" 21 namespace gar_pandora {
24 : m_settings(settings),
26 m_rotation(*pRotation)
28 fGeo = gar::providerFrom<geo::GeometryGAr>();
29 auto const *magFieldService = gar::providerFrom<mag::MagneticFieldService>();
30 G4ThreeVector zerovec(0, 0, 0);
31 G4ThreeVector magfield = magFieldService->FieldAtPoint(zerovec);
52 PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, this->
CreateMCParticles());
54 return pandora::STATUS_CODE_SUCCESS;
65 particleMap[particle->
TrackId()] = particle;
68 int neutrinoCounter(0);
77 const pandora::CartesianVector
momentum(neutrino.Nu().Px(), neutrino.Nu().Py(), neutrino.Nu().Pz());
85 PandoraApi::MCParticle::Parameters mcParticleParameters;
86 mcParticleParameters.m_energy = neutrino.Nu().E();
87 mcParticleParameters.m_momentum = newmomentum;
88 mcParticleParameters.m_vertex = newvertex;
89 mcParticleParameters.m_endpoint = newendpoint;
90 mcParticleParameters.m_particleId = neutrino.Nu().PdgCode();
91 mcParticleParameters.m_mcParticleType = pandora::MC_3D;
92 mcParticleParameters.m_pParentAddress = &neutrino;
94 PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::MCParticle::Create(
m_pandora, mcParticleParameters));
102 if (particle->
Mother() == 0)
106 PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::SetMCParentDaughterRelationship(
m_pandora, &neutrino, particle.
get()));
108 catch (
const pandora::StatusCodeException &)
110 MF_LOG_WARNING(
"MCParticleCreator") <<
"CreatePandoraMCParticles - unable to create mc particle relationship, invalid information supplied " <<
std::endl;
118 MF_LOG_DEBUG(
"MCParticleCreator") <<
" Number of Pandora neutrinos: " << neutrinoCounter <<
std::endl;
125 const pandora::CartesianVector
momentum(pMcParticle->
Px(), pMcParticle->
Py(), pMcParticle->
Pz());
133 PandoraApi::MCParticle::Parameters mcParticleParameters;
134 mcParticleParameters.m_energy = pMcParticle->
E();
135 mcParticleParameters.m_particleId = pMcParticle->
PdgCode();
136 mcParticleParameters.m_mcParticleType = pandora::MC_3D;
137 mcParticleParameters.m_pParentAddress = pMcParticle.
get();
138 mcParticleParameters.m_momentum = newmomentum;
139 mcParticleParameters.m_vertex = newvertex;
140 mcParticleParameters.m_endpoint = newendpoint;
142 MF_LOG_DEBUG(
"MCParticleCreator") <<
" Adding MC Particle with parameters " 143 <<
" mcParticleParameters.m_energy = " << mcParticleParameters.m_energy.Get()
144 <<
" mcParticleParameters.m_particleId = " << mcParticleParameters.m_particleId.Get()
145 <<
" mcParticleParameters.m_mcParticleType = " << mcParticleParameters.m_mcParticleType.Get()
146 <<
" mcParticleParameters.m_pParentAddress = " << mcParticleParameters.m_pParentAddress.Get()
147 <<
" mcParticleParameters.m_momentum = " << mcParticleParameters.m_momentum.Get()
148 <<
" mcParticleParameters.m_vertex = " << mcParticleParameters.m_vertex.Get()
149 <<
" mcParticleParameters.m_endpoint = " << mcParticleParameters.m_endpoint.Get();
154 <<
" Creating mc particle " << pMcParticle.
get()
155 <<
" of pdg " << pMcParticle->
PdgCode()
156 <<
" with TrackID " << pMcParticle->
TrackId()
157 <<
" and energy " << pMcParticle->
E() <<
" GeV";
159 PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::MCParticle::Create(
m_pandora, mcParticleParameters));
162 const int id_mother(pMcParticle->
Mother());
164 if (iterJ != particleMap.end())
169 <<
" Adding daughter relation " << iterJ->second.get()
170 <<
" to mc particle " << pMcParticle.
get();
172 PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::SetMCParentDaughterRelationship(
m_pandora, iterJ->second.get(), pMcParticle.
get()));
174 catch (
const pandora::StatusCodeException &)
176 MF_LOG_WARNING(
"MCParticleCreator") <<
"CreatePandoraMCParticles - Unable to create mc particle relationship, invalid information supplied " <<
std::endl;
181 catch (
const pandora::StatusCodeException &)
188 return pandora::STATUS_CODE_SUCCESS;
199 particleMap[particle->
TrackId()] = particle;
202 for(
auto const& itr : trackVector )
209 const float omega = trackParams[2] /
CLHEP::cm;
210 const float d0 = std::sqrt(trackParams[0]*trackParams[0] + trackParams[1]*trackParams[1]) *
CLHEP::cm;
213 const pandora::Helix helixFit(trackParams[3], d0, z0, omega, std::tan(trackParams[4]),
m_bField);
214 const float recoMomentum(helixFit.GetMomentum().GetMagnitude());
225 if (
nullptr == pMCParticle)
228 const pandora::CartesianVector
momentum(pMCParticle->
Px(), pMCParticle->
Py(), pMCParticle->
Pz());
230 const float trueMomentum(newmomentum.GetMagnitude());
232 const float deltaMomentum(std::fabs(recoMomentum - trueMomentum));
234 if (deltaMomentum < bestDeltaMomentum)
236 pBestMCParticle = pMCParticle;
237 bestDeltaMomentum = deltaMomentum;
241 if (
nullptr == pBestMCParticle)
244 MF_LOG_DEBUG(
"MCParticleCreator::CreateTrackToMCParticleRelationships")
245 <<
"Found MCParticle " << pBestMCParticle
246 <<
" associated to track " << pTrack
247 <<
" with best delta momentum " << bestDeltaMomentum;
249 PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::SetTrackToMCParticleRelationship(
m_pandora, pTrack, pBestMCParticle));
251 catch (pandora::StatusCodeException &statusCodeException)
253 MF_LOG_ERROR(
"MCParticleCreator::CreateTrackToMCParticleRelationships")
254 <<
"Failed to extract track to mc particle relationship: " << statusCodeException.ToString();
258 return pandora::STATUS_CODE_SUCCESS;
266 std::map< eveLoc, std::vector< art::Ptr<gar::rec::CaloHit> > > eveCaloHitMap;
272 particleMap[particle->
TrackId()] = particle;
276 for(
auto const& itr : calorimeterHitVector )
281 for(
size_t ieve = 0; ieve < eveides.size(); ieve++) {
282 MF_LOG_DEBUG(
"MCParticleCreator::CreateCaloHitToMCParticleRelationships")
283 <<
" Found eveID " << eveides[ieve].trackID
284 <<
" associated to art hit " << itr;
286 if(eveides[ieve].energyFrac < 0.1)
continue;
288 eveLoc el(eveides[ieve].trackID);
289 eveCaloHitMap[el].push_back(itr);
293 for(
auto const &hitMapItr : eveCaloHitMap)
295 MF_LOG_DEBUG(
"MCParticleCreator::CreateCaloHitToMCParticleRelationships")
296 <<
" Trying to find mcp associated to eveID " << hitMapItr.first.GetEveID();
300 if(
nullptr == part ) {
301 MF_LOG_WARNING(
"MCParticleCreator::CreateCaloHitToMCParticleRelationships")
302 <<
"Cannot find MCParticle for eveid: " << hitMapItr.first.GetEveID();
307 const int trackID = part->
TrackId();
314 if (
nullptr == pMCParticleCalo)
316 if (trackID != pMCParticleCalo->
TrackId())
321 if (
nullptr == pMCPrimary)
324 for(
auto const& itr : hitMapItr.second)
329 PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::SetCaloHitToMCParticleRelationship(
m_pandora, hit, pMCPrimary, hit->
Energy()));
331 catch (
const pandora::StatusCodeException &)
333 MF_LOG_WARNING(
"MCParticleCreator") <<
"CreateCaloHitToMCParticleRelationships - unable to create calo hit to mc particle relationship, invalid information supplied " <<
std::endl;
340 return pandora::STATUS_CODE_SUCCESS;
351 return pandora::STATUS_CODE_NOT_FOUND;
354 MF_LOG_DEBUG(
"MCParticleCreator") <<
" Found: " << theParticles->size() <<
" MC particles " <<
std::endl;
356 for (
unsigned int i = 0; i < theParticles->size(); ++i)
359 particleVector.push_back(particle);
362 return pandora::STATUS_CODE_SUCCESS;
369 auto mcTruthBlocks = pEvent.
getHandle< std::vector<simb::MCTruth> >(
label);
373 return pandora::STATUS_CODE_NOT_FOUND;
376 MF_LOG_DEBUG(
"MCParticleCreator") <<
" Found: " << mcTruthBlocks->size() <<
" MC truth blocks " <<
std::endl;
378 if (mcTruthBlocks->size() != 1)
379 throw cet::exception(
"MCParticleCreator") <<
" PandoraCollector::CollectGeneratorMCParticles --- Unexpected number of MC truth blocks ";
382 for (
int i = 0; i < mcTruth->
NParticles(); ++i)
387 return pandora::STATUS_CODE_SUCCESS;
398 return pandora::STATUS_CODE_NOT_FOUND;
401 MF_LOG_DEBUG(
"MCParticleCreator") <<
" Found: " << theParticles->size() <<
" MC particles " <<
std::endl;
403 art::FindOneP<simb::MCTruth> theTruthAssns(theParticles, pEvent, label);
405 for (
unsigned int i = 0, iEnd = theParticles->size(); i < iEnd; ++i)
409 truthToParticles[truth].push_back(particle);
410 particlesToTruth[particle] = truth;
413 return pandora::STATUS_CODE_SUCCESS;
423 int trackID(inputParticle->
TrackId());
428 if (particleMap.end() == pIter)
432 mcVector.push_back(particle);
434 trackID = particle->
Mother();
438 for (MCParticleVector::const_reverse_iterator iter = mcVector.rbegin(), iterEnd = mcVector.rend(); iter != iterEnd; ++iter)
443 return nextParticle.
get();
470 : m_geantModuleLabel(
"" ),
471 m_generatorModuleLabel(
"" )
static constexpr double cm
double E(const int i=0) const
std::vector< CalIDE > CaloHitToCalIDEs(art::Ptr< rec::CaloHit > const &hit) const
std::string m_geantModuleLabel
The geant4 label.
pandora::StatusCode CollectMCParticles(const art::Event &pEvent, const std::string &label, MCParticleVector &particleVector)
std::vector< art::Ptr< gar::rec::CaloHit > > CalorimeterHitVector
const simb::MCNeutrino & GetNeutrino() const
double Py(const int i=0) const
const RotationTransformation & m_rotation
Handle< PROD > getHandle(SelectorBase const &) const
std::string m_generatorModuleLabel
The generator label.
float m_bField
The bfield.
MCParticleVector artMCParticleVector
double Px(const int i=0) const
const pandora::Pandora & m_pandora
Reference to the pandora object to create the mc particles.
#define MF_LOG_ERROR(category)
static const simb::MCParticle * GetFinalStateMCParticle(const MCParticleMap &particleMap, const simb::MCParticle *inputParticle)
std::vector< art::Ptr< simb::MCParticle > > MCParticleVector
const geo::GeometryCore * fGeo
MCTruthToMCParticles artMCTruthToMCParticles
MCParticleCreator(const Settings &settings, const pandora::Pandora *const pPandora, const RotationTransformation *const pRotation)
std::vector< simb::MCParticle > RawMCParticleVector
MCParticlesToMCTruth artMCParticlesToMCTruth
pandora::StatusCode CreateCaloHitToMCParticleRelationships(const CalorimeterHitVector &calorimeterHitVector) const
pandora::StatusCode CollectGeneratorMCParticles(const art::Event &pEvent, const std::string &label, RawMCParticleVector &particleVector)
simb::MCParticle * TrackIDToParticle(int const &id) const
const float * TrackParEnd() const
static int max(int a, int b)
const float * End() const
std::map< int, art::Ptr< simb::MCParticle > > MCParticleMap
Detector simulation of raw signals on wires.
const simb::MCParticle & GetParticle(int i) const
std::map< art::Ptr< simb::MCParticle >, art::Ptr< simb::MCTruth > > MCParticlesToMCTruth
General GArSoft Utilities.
double Vx(const int i=0) const
pandora::StatusCode CreateTrackToMCParticleRelationships(const TrackVector &trackVector) const
double Pz(const int i=0) const
std::map< art::Ptr< simb::MCTruth >, MCParticleVector > MCTruthToMCParticles
double Vz(const int i=0) const
std::vector< art::Ptr< gar::rec::Track > > TrackVector
RawMCParticleVector generatorArtMCParticleVector
pandora::StatusCode CreateMCParticles() const
const Settings m_settings
The mc particle creator settings.
#define MF_LOG_WARNING(category)
def momentum(x1, x2, x3, scale=1.)
Event generator information.
double Vy(const int i=0) const
cet::coded_exception< error, detail::translate > exception
QTextStream & endl(QTextStream &s)
static bool IsVisible(const art::Ptr< simb::MCParticle > particle)