3 #include "Api/PandoraApi.h" 5 #include "Objects/Cluster.h" 6 #include "Objects/ParticleFlowObject.h" 7 #include "Objects/Track.h" 9 #include "Pandora/PdgTable.h" 18 namespace gar_pandora {
21 : m_settings(settings),
23 m_rotation(*pRotation)
40 const pandora::PfoList *pPandoraPfoList = NULL;
41 PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::GetCurrentPfoList(
m_pandora, pPandoraPfoList));
48 const pandora::ParticleFlowObject *
const pPandoraPfo(*pIter);
51 const bool hasTrack(!pPandoraPfo->GetTrackList().empty());
52 const pandora::ClusterList &clusterList(pPandoraPfo->GetClusterList());
54 float clustersTotalEnergy(0.
f);
55 pandora::CartesianVector referencePoint(0.
f, 0.
f, 0.
f), clustersWeightedPosition(0.
f, 0.
f, 0.
f);
59 const pandora::Cluster *
const pPandoraCluster(*cIter);
60 pandora::CaloHitList pandoraCaloHitList;
61 pPandoraCluster->GetOrderedCaloHitList().FillCaloHitList(pandoraCaloHitList);
62 pandoraCaloHitList.insert(pandoraCaloHitList.end(), pPandoraCluster->GetIsolatedCaloHitList().begin(), pPandoraCluster->GetIsolatedCaloHitList().end());
68 float clusterCorrectEnergy(0.
f);
71 pandora::CartesianVector clusterPosition(0.
f, 0.
f, 0.
f);
72 const unsigned int nHitsInCluster(pandoraCaloHitList.size());
77 clustersWeightedPosition += clusterPosition * clusterCorrectEnergy;
78 clustersTotalEnergy += clusterCorrectEnergy;
82 <<
"Adding cluster " << &pCluster
83 <<
" with energy " << pCluster.
Energy();
85 outputClusters->emplace_back(pCluster);
90 if (clustersTotalEnergy < std::numeric_limits<float>::epsilon())
93 <<
"invalid cluster energy " << clustersTotalEnergy;
94 throw pandora::StatusCodeException(pandora::STATUS_CODE_FAILURE);
98 referencePoint = clustersWeightedPosition * (1.f / clustersTotalEnergy);
111 <<
"Adding PFO " << &pReconstructedParticle
112 <<
" with energy " << pReconstructedParticle.
Energy()
113 <<
" , mass " << pReconstructedParticle.
Mass();
118 if (pReconstructedParticle.
Energy() < -1000)
120 <<
" Negative energy. Message should not be printed. " <<
m_rotation.
kAxisX;
122 outputParticles->emplace_back(pReconstructedParticle);
128 return pandora::STATUS_CODE_SUCCESS;
135 subDetectorNames.push_back(
"ecal");
144 const pandora::CaloHit *
const pPandoraCaloHit(*hIter);
147 MF_LOG_DEBUG(
"PfoCreator::SetClusterSubDetectorEnergies")
148 <<
" hit " << pCalorimeterHit
149 <<
" energy " << pCalorimeterHit->
Energy()
150 <<
" position x " << pCalorimeterHit->
Position()[0]
151 <<
" y " << pCalorimeterHit->
Position()[1]
152 <<
" z " << pCalorimeterHit->
Position()[2];
154 const float caloHitEnergy(pCalorimeterHit->
Energy());
155 hitE.push_back(caloHitEnergy);
156 hitX.push_back(pCalorimeterHit->
Position()[0]);
157 hitY.push_back(pCalorimeterHit->
Position()[1]);
158 hitZ.push_back(pCalorimeterHit->
Position()[2]);
166 const bool isEmShower((
pandora::PHOTON == pPandoraPfo->GetParticleId()) || (pandora::E_MINUS ==
std::abs(pPandoraPfo->GetParticleId())));
167 clusterCorrectEnergy = (isEmShower ? pPandoraCluster->GetCorrectedElectromagneticEnergy(
m_pandora) : pPandoraCluster->GetCorrectedHadronicEnergy(
m_pandora));
169 if (clusterCorrectEnergy < std::numeric_limits<float>::epsilon())
170 throw pandora::StatusCodeException(pandora::STATUS_CODE_FAILURE);
174 const float energyError(std::sqrt(stochasticTerm * stochasticTerm / clusterCorrectEnergy + constantTerm * constantTerm) * clusterCorrectEnergy);
176 pCluster.
setEnergy(clusterCorrectEnergy);
184 util::ClusterShapes pClusterShapes(nHitsInCluster, hitE.data(), hitX.data(), hitY.data(), hitZ.data());
188 pCluster.
setIPhi(std::atan2(pClusterShapes.getEigenVecInertia()[1], pClusterShapes.getEigenVecInertia()[0]));
189 pCluster.
setITheta(std::acos(pClusterShapes.getEigenVecInertia()[2]));
190 pCluster.
setPosition(pClusterShapes.getCenterOfGravity());
193 clusterPositionVec.SetValues(pClusterShapes.getCenterOfGravity()[0], pClusterShapes.getCenterOfGravity()[1], pClusterShapes.getCenterOfGravity()[2]);
198 <<
"unidentified exception caught.";
208 float totalTrackMomentumAtDca(0.
f), totalTrackMomentumAtStart(0.
f);
209 pandora::CartesianVector referencePointAtDCAWeighted(0.
f, 0.
f, 0.
f), referencePointAtStartWeighted(0.
f, 0.
f, 0.
f);
211 bool hasSiblings(
false);
222 const pandora::CartesianVector &trackStartPoint((pPandoraTrack->GetTrackStateAtStart()).GetPosition());
223 const float trackStartMomentum(((pPandoraTrack->GetTrackStateAtStart()).GetMomentum()).GetMagnitude());
224 referencePointAtStartWeighted += trackStartPoint * trackStartMomentum;
225 totalTrackMomentumAtStart += trackStartMomentum;
243 if (totalTrackMomentumAtStart < std::numeric_limits<float>::epsilon())
246 <<
"invalid track momentum " << totalTrackMomentumAtStart;
247 throw pandora::StatusCodeException(pandora::STATUS_CODE_FAILURE);
251 referencePoint = referencePointAtStartWeighted * (1.f / totalTrackMomentumAtStart);
256 if (totalTrackMomentumAtDca < std::numeric_limits<float>::epsilon())
259 <<
"invalid track momentum " << totalTrackMomentumAtDca;
260 throw pandora::StatusCodeException(pandora::STATUS_CODE_FAILURE);
264 referencePoint = referencePointAtDCAWeighted * (1.f / totalTrackMomentumAtDca);
268 return pandora::STATUS_CODE_SUCCESS;
279 if (allTrackList.end() != std::find(allTrackList.begin(), allTrackList.end(), *iter))
284 <<
"mismatch in track relationship information, use information as available ";
302 if (allTrackList.end() != std::find(allTrackList.begin(), allTrackList.end(), *iter))
306 MF_LOG_WARNING(
"PfoCreator::HasValidSiblingTrack") <<
"mismatch in track relationship information, use information as available ";
327 const float trialTrackDisplacement(pTrack->GetTrackStateAtStart().GetPosition().GetMagnitude());
329 if (trialTrackDisplacement < closestTrackDisplacement)
331 closestTrackDisplacement = trialTrackDisplacement;
332 pClosestTrack = pTrack;
336 return (pPandoraTrack == pClosestTrack);
347 if (allTrackList.end() != std::find(allTrackList.begin(), allTrackList.end(), *iter))
358 const float referencePointArray[3] = {referencePoint.GetX(), referencePoint.GetY(), referencePoint.GetZ()};
359 pReconstructedParticle.
setPosition(referencePointArray);
379 const float momentum[3] = {pPandoraPfo->GetMomentum().GetX(), pPandoraPfo->GetMomentum().GetY(), pPandoraPfo->GetMomentum().GetZ()};
381 pReconstructedParticle.
setEnergy(pPandoraPfo->GetEnergy());
382 pReconstructedParticle.
setMass(pPandoraPfo->GetMass());
383 pReconstructedParticle.
setCharge(pPandoraPfo->GetCharge());
384 pReconstructedParticle.
setType(pPandoraPfo->GetParticleId());
390 m_emStochasticTerm(0.17
f),
391 m_emConstantTerm(0.01
f),
392 m_hadStochasticTerm(0.30
f),
393 m_hadConstantTerm(0.01
f)
void SetRecoParticleReferencePoint(const pandora::CartesianVector &referencePoint, gar::rec::PFParticle &pReconstructedParticle) const
Set reference point of the reconstructed particle.
bool AreAnyOtherSiblingsInList(const pandora::Track *const pPandoraTrack, const pandora::TrackList &allTrackList) const
Whether at least one track sibling track is associated to the reconstructed particle.
bool IsClosestTrackToIP(const pandora::Track *const pPandoraTrack, const pandora::TrackList &allTrackList) const
Whether the track is the closest (of those associated with the same pfo) to the interaction point...
std::unique_ptr< std::vector< rec::PFParticle > > PFParticleCollection
pandora::StatusCode CalculateTrackBasedReferencePoint(const pandora::ParticleFlowObject *const pPandoraPfo, pandora::CartesianVector &referencePoint) const
Calculate reference point for pfo with tracks.
float m_hadConstantTerm
The constant term for HAD shower energy resolution.
bool IsValidParentTrack(const pandora::Track *const pPandoraTrack, const pandora::TrackList &allTrackList) const
Whether parent and daughter tracks are associated with the same pfo.
void SetClusterEnergyAndError(const pandora::ParticleFlowObject *const pPandoraPfo, const pandora::Cluster *const pPandoraCluster, gar::rec::Cluster &pCluster, float &clusterCorrectEnergy) const
Set cluster energies and errors.
PfoCreator(const Settings &settings, const pandora::Pandora *const pPandora, const RotationTransformation *const pRotation)
void setEnergy(float energy)
std::set< const gar::rec::Track * > TrackList
float m_hadStochasticTerm
The stochastic term for HAD shower energy resolution.
void setEnergyError(float energy_error)
const pandora::Pandora & m_pandora
Reference to the pandora object from which to extract the pfos.
const RotationTransformation & m_rotation
void setEnergy(float energy)
float m_emConstantTerm
The constant term for EM shower energy resolution.
void setPosition(const float *position)
void SetRecoParticlePropertiesFromPFO(const pandora::ParticleFlowObject *const pPandoraPfo, gar::rec::PFParticle &pReconstructedParticle) const
Set properties of reconstructed particle from pandora pfo.
bool HasValidSiblingTrack(const pandora::Track *const pPandoraTrack, const pandora::TrackList &allTrackList) const
Whether sibling tracks are associated with the same pfo.
ProductID put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
static int max(int a, int b)
void SetClusterSubDetectorEnergies(const pandora::StringVector &subDetectorNames, const pandora::CaloHitList &pandoraCaloHitList, pandora::FloatVector &hitE, pandora::FloatVector &hitX, pandora::FloatVector &hitY, pandora::FloatVector &hitZ) const
Set sub detector energies for a cluster.
float m_emStochasticTerm
The stochastic term for EM shower energy resolution.
void SetClusterPositionAndError(const unsigned int nHitsInCluster, pandora::FloatVector &hitE, pandora::FloatVector &hitX, pandora::FloatVector &hitY, pandora::FloatVector &hitZ, gar::rec::Cluster &pCluster, pandora::CartesianVector &clusterPositionVec) const
Set cluster position, errors and other shape info, by calculating culster shape first.
General GArSoft Utilities.
const float * Position() const
void setMomentum(const float mom[3])
void setITheta(float theta)
void InitialiseSubDetectorNames(pandora::StringVector &subDetectorNames) const
initialise sub detector name strings
void AddTracksToRecoParticle(const pandora::ParticleFlowObject *const pPandoraPfo, gar::rec::PFParticle &pReconstructedParticle) const
Add tracks to reconstructed particle.
pandora::StatusCode CreateParticleFlowObjects(art::Event &pEvent)
std::vector< string > StringVector
void setPosition(const float pos[3])
void setCharge(float charge)
std::unique_ptr< std::vector< rec::Cluster > > ClusterCollection
TrackCollectionProxyElement< TrackCollProxy > Track
Proxy to an element of a proxy collection of recob::Track objects.
Dft::FloatVector FloatVector
#define MF_LOG_WARNING(category)
def momentum(x1, x2, x3, scale=1.)
const Settings m_settings
The pfo creator settings.