Pandora
Pandora source code navigator
Loading...
Searching...
No Matches
MCManager.cc
Go to the documentation of this file.
1
10
11#include "Objects/MCParticle.h"
12
14#include "Pandora/Pandora.h"
17#include "Pandora/PdgTable.h"
18
19#include <algorithm>
20
21namespace pandora
22{
23
24MCManager::MCManager(const Pandora *const pPandora) :
26 m_selectedListName("Selected")
27{
28 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->CreateInitialLists());
29}
30
31//------------------------------------------------------------------------------------------------------------------------------------------
32
34{
35 (void) this->EraseAllContent();
36}
37
38//------------------------------------------------------------------------------------------------------------------------------------------
39
42{
43 pMCParticle = nullptr;
44
45 try
46 {
47 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, factory.Create(parameters, pMCParticle));
48
49 NameToListMap::iterator inputIter = m_nameToListMap.find(m_inputListName);
50
51 if (!pMCParticle || (m_nameToListMap.end() == inputIter))
52 throw StatusCodeException(STATUS_CODE_FAILURE);
53
54 if (!m_uidToMCParticleMap.insert(UidToMCParticleMap::value_type(pMCParticle->GetUid(), pMCParticle)).second)
55 throw StatusCodeException(STATUS_CODE_ALREADY_PRESENT);
56
57 inputIter->second->push_back(pMCParticle);
58 return STATUS_CODE_SUCCESS;
59 }
60 catch (StatusCodeException &statusCodeException)
61 {
62 std::cout << "Failed to create mc particle: " << statusCodeException.ToString() << std::endl;
63 delete pMCParticle;
64 pMCParticle = nullptr;
65 return statusCodeException.GetStatusCode();
66 }
67}
68
69//------------------------------------------------------------------------------------------------------------------------------------------
70
80
81//------------------------------------------------------------------------------------------------------------------------------------------
82
84{
85 m_parentDaughterRelationMap.insert(MCParticleRelationMap::value_type(parentUid, daughterUid));
86
87 return STATUS_CODE_SUCCESS;
88}
89
90//------------------------------------------------------------------------------------------------------------------------------------------
91
93{
94 NameToListMap::const_iterator inputIter = m_nameToListMap.find(m_inputListName);
95
96 if (m_nameToListMap.end() == inputIter)
97 return STATUS_CODE_FAILURE;
98
99 for (const MCParticle *const pMCParticle : *inputIter->second)
100 {
101 MCParticleSet mcPfoSet;
102
103 if (pMCParticle->IsRootParticle())
104 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->ApplyPfoSelectionRules(pMCParticle, mcPfoSet));
105 }
106
107 return STATUS_CODE_SUCCESS;
108}
109
110//------------------------------------------------------------------------------------------------------------------------------------------
111
113{
114 // Check for presence of input list and remove any existing selected list
115 NameToListMap::const_iterator inputIter = m_nameToListMap.find(m_inputListName);
116
117 if (m_nameToListMap.end() == inputIter)
118 return STATUS_CODE_FAILURE;
119
120 NameToListMap::iterator selectedIter = m_nameToListMap.find(m_selectedListName);
121
122 if (m_nameToListMap.end() != selectedIter)
123 {
124 ObjectList *const pObjectList(selectedIter->second);
125 selectedIter = m_nameToListMap.erase(selectedIter);
126 delete pObjectList;
127 }
128
129 // Strip down mc particles and relationships to just those of pfo targets, if specified
130 const bool shouldCollapseMCParticlesToPfoTarget(m_pPandora->GetSettings()->ShouldCollapseMCParticlesToPfoTarget());
131
132 MCParticleList selectedMCPfoList;
133
134 for (const MCParticle *const pMCParticle : *inputIter->second)
135 {
136 const bool isPfoTarget(pMCParticle->IsPfoTarget());
137
138 if (!isPfoTarget && shouldCollapseMCParticlesToPfoTarget)
139 {
140 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->RemoveMCParticleRelationships(pMCParticle));
141 }
142
143 if (isPfoTarget || !shouldCollapseMCParticlesToPfoTarget)
144 {
145 selectedMCPfoList.push_back(pMCParticle);
146 }
147 }
148
149 // Save selected pfo target list
150 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->SaveList(m_selectedListName, selectedMCPfoList));
152
153 return STATUS_CODE_SUCCESS;
154}
155
156//------------------------------------------------------------------------------------------------------------------------------------------
157
159{
160 const float selectionRadius(m_pPandora->GetSettings()->GetMCPfoSelectionRadius());
161 const float selectionMomentum(m_pPandora->GetSettings()->GetMCPfoSelectionMomentum());
162 const float selectionEnergyCutOffProtonsNeutrons(m_pPandora->GetSettings()->GetMCPfoSelectionLowEnergyNeutronProtonCutOff());
163
164 const int particleId(pMCParticle->GetParticleId());
165
166 // ATTN: Don't take particles from previously used decay chains; could happen because mc particles can have multiple parents.
167 if (!mcPfoSet.count(pMCParticle) &&
168 (pMCParticle->GetOuterRadius() > selectionRadius) &&
169 (pMCParticle->GetInnerRadius() <= selectionRadius) &&
170 (pMCParticle->GetMomentum().GetMagnitude() > selectionMomentum) &&
171 !((particleId == PROTON || particleId == NEUTRON) && (pMCParticle->GetEnergy() < selectionEnergyCutOffProtonsNeutrons)))
172 {
173 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->SetPfoTargetInTree(pMCParticle, pMCParticle, true));
174 mcPfoSet.insert(pMCParticle);
175 }
176 else
177 {
178 for (const MCParticle *const pDaughterMCParticle : pMCParticle->GetDaughterList())
179 {
180 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->ApplyPfoSelectionRules(pDaughterMCParticle, mcPfoSet));
181 }
182 }
183
184 return STATUS_CODE_SUCCESS;
185}
186
187//------------------------------------------------------------------------------------------------------------------------------------------
188
189StatusCode MCManager::SetPfoTargetInTree(const MCParticle *const pMCParticle, const MCParticle *const pPfoTarget, bool onlyDaughters) const
190{
191 if (pMCParticle->IsPfoTargetSet())
192 return STATUS_CODE_SUCCESS;
193
194 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->Modifiable(pMCParticle)->SetPfoTarget(pPfoTarget));
195
196 for (const MCParticle *const pDaughterMCParticle : pMCParticle->GetDaughterList())
197 {
198 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->SetPfoTargetInTree(pDaughterMCParticle, pPfoTarget));
199 }
200
201 if (!onlyDaughters)
202 {
203 for (const MCParticle *const pParentMCParticle : pMCParticle->GetParentList())
204 {
205 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->SetPfoTargetInTree(pParentMCParticle, pPfoTarget));
206 }
207 }
208
209 return STATUS_CODE_SUCCESS;
210}
211
212//------------------------------------------------------------------------------------------------------------------------------------------
213
215{
216 if (m_parentDaughterRelationMap.empty())
217 return STATUS_CODE_SUCCESS;
218
219 const MCParticleList *pInputList(nullptr);
220 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->GetList(m_inputListName, pInputList));
221
222 for (const MCParticle *const pParentMCParticle : *pInputList)
223 {
224 const auto range(m_parentDaughterRelationMap.equal_range(pParentMCParticle->GetUid()));
225
226 MCParticleList daughterList;
227 for (MCParticleRelationMap::const_iterator relIter = range.first; relIter != range.second; ++relIter)
228 {
229 UidToMCParticleMap::const_iterator daughterIter = m_uidToMCParticleMap.find(relIter->second);
230
231 if ((m_uidToMCParticleMap.end() != daughterIter) && (daughterList.end() == std::find(daughterList.begin(), daughterList.end(), daughterIter->second)))
232 daughterList.push_back(daughterIter->second);
233 }
234 daughterList.sort(PointerLessThan<MCParticle>());
235
236 for (const MCParticle *const pDaughterMCParticle : daughterList)
237 {
238 const StatusCode firstStatusCode(this->Modifiable(pParentMCParticle)->AddDaughter(pDaughterMCParticle));
239 const StatusCode secondStatusCode(this->Modifiable(pDaughterMCParticle)->AddParent(pParentMCParticle));
240
241 if (firstStatusCode != secondStatusCode)
242 return STATUS_CODE_FAILURE;
243
244 if ((firstStatusCode != STATUS_CODE_SUCCESS) && (firstStatusCode != STATUS_CODE_ALREADY_PRESENT))
245 return firstStatusCode;
246 }
247 }
248
249 return STATUS_CODE_SUCCESS;
250}
251
252//------------------------------------------------------------------------------------------------------------------------------------------
253
255{
256 NameToListMap::const_iterator inputIter = m_nameToListMap.find(m_inputListName);
257
258 if (m_nameToListMap.end() == inputIter)
259 return STATUS_CODE_FAILURE;
260
261 for (const MCParticle *const pMCParticle : *inputIter->second)
262 this->RemoveMCParticleRelationships(pMCParticle);
263
264 m_uidToMCParticleMap.clear();
268
269 return STATUS_CODE_SUCCESS;
270}
271
272//------------------------------------------------------------------------------------------------------------------------------------------
273
275{
276 const MCParticleList parentList(pMCParticle->GetParentList());
277
278 for (const MCParticle *const pParentMCParticle : parentList)
279 {
280 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->Modifiable(pParentMCParticle)->RemoveDaughter(pMCParticle));
281 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->Modifiable(pMCParticle)->RemoveParent(pParentMCParticle));
282 }
283
284 const MCParticleList daughterList(pMCParticle->GetDaughterList());
285
286 for (const MCParticle *const pDaughterMCParticle : daughterList)
287 {
288 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->Modifiable(pDaughterMCParticle)->RemoveParent(pMCParticle));
289 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->Modifiable(pMCParticle)->RemoveDaughter(pDaughterMCParticle));
290 }
291
292 return this->Modifiable(pMCParticle)->RemovePfoTarget();
293}
294
295//------------------------------------------------------------------------------------------------------------------------------------------
296
297StatusCode MCManager::SetUidToMCParticleRelationship(const Uid objectUid, const Uid mcParticleUid, const float mcParticleWeight,
298 ObjectRelationMap &objectRelationMap) const
299{
300 const bool useSingleMCParticleAssociation(m_pPandora->GetSettings()->UseSingleMCParticleAssociation());
301 ObjectRelationMap::iterator iter = objectRelationMap.find(objectUid);
302
303 if (objectRelationMap.end() != iter)
304 {
305 UidToWeightMap &uidToWeightMap(iter->second);
306
307 if (useSingleMCParticleAssociation && (mcParticleWeight < uidToWeightMap.begin()->second))
308 return STATUS_CODE_SUCCESS;
309
310 if (useSingleMCParticleAssociation)
311 uidToWeightMap.clear();
312
313 uidToWeightMap[mcParticleUid] += mcParticleWeight;
314 }
315 else
316 {
317 UidToWeightMap uidToWeightMap;
318
319 if (!uidToWeightMap.insert(UidToWeightMap::value_type(mcParticleUid, mcParticleWeight)).second)
320 return STATUS_CODE_FAILURE;
321
322 if (!objectRelationMap.insert(ObjectRelationMap::value_type(objectUid, uidToWeightMap)).second)
323 return STATUS_CODE_FAILURE;
324 }
325
326 return STATUS_CODE_SUCCESS;
327}
328
329//------------------------------------------------------------------------------------------------------------------------------------------
330
331StatusCode MCManager::CreateUidToPfoTargetsMap(UidToMCParticleWeightMap &uidToMCParticleWeightMap, const ObjectRelationMap &objectRelationMap) const
332{
333 if (m_uidToMCParticleMap.empty())
334 return STATUS_CODE_SUCCESS;
335
336 const bool collapseToPfoTarget(m_pPandora->GetSettings()->ShouldCollapseMCParticlesToPfoTarget());
337
338 for (const ObjectRelationMap::value_type &relationEntry : objectRelationMap)
339 {
340 MCParticleSet mcParticleSet;
341
342 for (const UidToWeightMap::value_type &weightEntry : relationEntry.second)
343 {
344 UidToMCParticleMap::const_iterator mcParticleIter = m_uidToMCParticleMap.find(weightEntry.first);
345
346 if (m_uidToMCParticleMap.end() != mcParticleIter)
347 mcParticleSet.insert(mcParticleIter->second);
348 }
349
350 if (mcParticleSet.empty())
351 continue;
352
353 MCParticleList mcParticleList(mcParticleSet.begin(), mcParticleSet.end());
354 mcParticleList.sort(PointerLessThan<MCParticle>());
355 MCParticleWeightMap &mcParticleWeightMap(uidToMCParticleWeightMap[relationEntry.first]);
356
357 for (const MCParticle *const pMCParticle : mcParticleList)
358 {
359 const float mcParticleWeight(relationEntry.second.at(pMCParticle->GetUid()));
360 const MCParticle *const pTargetMCParticle(!collapseToPfoTarget ? pMCParticle : pMCParticle->m_pPfoTarget);
361
362 if (!pTargetMCParticle)
363 continue;
364
365 mcParticleWeightMap[pTargetMCParticle] += mcParticleWeight;
366 }
367 }
368
369 return STATUS_CODE_SUCCESS;
370}
371
372} // namespace pandora
Header file for the mc particle manager class.
Header file for the mc particle class.
Header file for the object factory class.
Header file for the pandora class.
Header file defining relevant internal typedefs, sort and string conversion functions.
Header file for the pandora settings class.
#define PANDORA_THROW_RESULT_IF(StatusCode1, Operator, Command)
Definition StatusCodes.h:43
#define PANDORA_RETURN_RESULT_IF(StatusCode1, Operator, Command)
Definition StatusCodes.h:19
@ NEUTRON
Definition Validation.h:213
float GetMagnitude() const
Get the magnitude.
InputObjectManager class.
Manager< MCParticle >::ObjectList ObjectList
virtual StatusCode CreateInitialLists()
Create initial lists.
virtual StatusCode SaveList(const std::string &listName, const ObjectList &objectList)
Save a list of objects in a list with a specified name; create new list if required.
virtual StatusCode EraseAllContent()
Erase all manager content.
const std::string m_inputListName
The name of the input list.
StatusCode SetPfoTargetInTree(const MCParticle *const pMCParticle, const MCParticle *const pPfoTarget, bool onlyDaughters=false) const
Set pfo target for a mc tree.
Definition MCManager.cc:189
StatusCode RemoveMCParticleRelationships(const MCParticle *const pMCParticle) const
Remove all parent/daughter particle links from a mc particle and from its (previously) linked particl...
Definition MCManager.cc:274
StatusCode SetMCParentDaughterRelationship(const Uid parentUid, const Uid daughterUid)
Set mc particle relationship.
Definition MCManager.cc:83
StatusCode Create(const object_creation::MCParticle::Parameters &parameters, const MCParticle *&pMCParticle, const ObjectFactory< object_creation::MCParticle::Parameters, object_creation::MCParticle::Object > &factory)
Create a mc particle.
Definition MCManager.cc:40
StatusCode RemoveAllMCParticleRelationships()
Remove all mc particle associations that have been registered with the mc manager.
Definition MCManager.cc:254
std::unordered_map< Uid, float > UidToWeightMap
Definition MCManager.h:137
StatusCode CreateUidToPfoTargetsMap(UidToMCParticleWeightMap &uidToMCParticleWeightMap, const ObjectRelationMap &objectRelationMap) const
Create a map relating an object (calo hit or track) uid to mc pfo targets.
Definition MCManager.cc:331
MCParticleRelationMap m_parentDaughterRelationMap
The mc particle parent-daughter relation map.
Definition MCManager.h:163
ObjectRelationMap m_caloHitToMCParticleMap
The calo hit to mc particle relation map.
Definition MCManager.h:164
StatusCode SelectPfoTargets()
Select pfo targets.
Definition MCManager.cc:112
MCManager(const Pandora *const pPandora)
Constructor.
Definition MCManager.cc:24
std::unordered_map< Uid, UidToWeightMap > ObjectRelationMap
Definition MCManager.h:138
StatusCode ApplyPfoSelectionRules(const MCParticle *const mcRootParticle, MCParticleSet &mcPfoSet) const
Apply mc pfo selection rules.
Definition MCManager.cc:158
StatusCode IdentifyPfoTargets()
Identify pfo targets.
Definition MCManager.cc:92
StatusCode AddMCParticleRelationships() const
Apply mc particle associations (parent-daughter) that have been registered with the mc manager.
Definition MCManager.cc:214
UidToMCParticleMap m_uidToMCParticleMap
The uid to mc particle map.
Definition MCManager.h:162
~MCManager()
Destructor.
Definition MCManager.cc:33
StatusCode EraseAllContent()
Erase all mc manager content.
Definition MCManager.cc:71
const std::string m_selectedListName
The name of the selected list.
Definition MCManager.h:160
StatusCode SetUidToMCParticleRelationship(const Uid objectUid, const Uid mcParticleUid, const float mcParticleWeight, ObjectRelationMap &objectRelationMap) const
Set an object (e.g. calo hit or track) to mc particle relationship.
Definition MCManager.cc:297
ObjectRelationMap m_trackToMCParticleMap
The track to mc particle relation map.
Definition MCManager.h:165
MCParticle class.
Definition MCParticle.h:26
Uid GetUid() const
Get the mc particle unique identifier.
Definition MCParticle.h:236
float GetEnergy() const
Get energy of mc particle, units GeV.
Definition MCParticle.h:243
const MCParticleList & GetDaughterList() const
Get list of daughters of mc particle.
Definition MCParticle.h:306
const CartesianVector & GetMomentum() const
Get momentum of mc particle, units GeV.
Definition MCParticle.h:250
bool IsPfoTargetSet() const
Whether the pfo target been set.
Definition MCParticle.h:229
float GetInnerRadius() const
Get inner radius of mc particle, units mm.
Definition MCParticle.h:271
float GetOuterRadius() const
Get outer radius of mc particle, units mm.
Definition MCParticle.h:278
const MCParticleList & GetParentList() const
Get list of parents of mc particle.
Definition MCParticle.h:299
int GetParticleId() const
Get the PDG code of the mc particle.
Definition MCParticle.h:285
std::string m_currentListName
The name of the current list.
Definition Manager.h:181
virtual T * Modifiable(const T *const pT) const
Access a modifiable object, when provided with address to const object.
Definition Manager.cc:288
const Pandora *const m_pPandora
The associated pandora object.
Definition Manager.h:173
NameToListMap m_nameToListMap
The name to list map.
Definition Manager.h:178
virtual StatusCode GetList(const std::string &listName, const ObjectList *&pObjectList) const
Get a list.
Definition Manager.cc:34
ObjectFactory class responsible for extended pandora object creation.
virtual StatusCode Create(const Parameters &parameters, const Object *&pObject) const =0
Create an object with the given parameters.
Pandora class.
Definition Pandora.h:40
const PandoraSettings * GetSettings() const
Get the pandora settings instance.
Definition Pandora.cc:182
float GetMCPfoSelectionLowEnergyNeutronProtonCutOff() const
Get the low energy cut-off for selection of protons/neutrons as mc pfos.
bool ShouldCollapseMCParticlesToPfoTarget() const
Whether to collapse mc particle decay chains down to just the pfo target.
bool UseSingleMCParticleAssociation() const
Whether to allow only single mc particle association to objects (largest weight)
float GetMCPfoSelectionMomentum() const
Get the momentum magnitude used to select the pfo target from a mc particle decay chain,...
float GetMCPfoSelectionRadius() const
Get the radius used to select the pfo target from a mc particle decay chain, units mm.
Enable ordering of pointers based on properties of target objects.
StatusCodeException class.
std::string ToString() const
Get status code as a string.
StatusCode GetStatusCode() const
Get status code.
std::unordered_set< const MCParticle * > MCParticleSet
MANAGED_CONTAINER< const MCParticle * > MCParticleList
std::unordered_map< const MCParticle *, float > MCParticleWeightMap
const void * Uid
StatusCode
The StatusCode enum.
std::unordered_map< Uid, MCParticleWeightMap > UidToMCParticleWeightMap