All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MCTruthParticleList.h
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 /// \file MCTruthParticleList.h
3 /// \brief Particle list in DetSim contains Monte Carlo particle information.
4 ///
5 /// \version $Id: MCTruthParticleList.h,v 1.13 2010/05/13 16:12:20 seligman Exp $
6 /// \author seligman@nevis.columbia.edu
7 ////////////////////////////////////////////////////////////////////////
8 ///
9 /// ********************************************************************
10 /// *** This class has been lifted from nutools and modified so that it
11 /// *** does NOT take ownwership of the MCParticles that are added to it
12 /// *** so we can avoid duplicating them
13 /// ********************************************************************
14 ///
15 /// A container for particles generated during an event simulation.
16 /// It acts like a map<int,Particle*> but with additional features:
17 ///
18 /// - A method Cut(double) that will remove all particles with energy
19 /// less than the argument.
20 ///
21 /// - Methods TrackId(int) and Particle(int) for those who are unfamiliar with the
22 /// concepts associated with STL maps:
23 /// truth::MCTruthParticleList* MCTruthParticleList = // ...;
24 /// int numberOfParticles = MCTruthParticleList->size();
25 /// for (int i=0; i<numberOfParticles; ++i)
26 /// {
27 /// int trackID = MCTruthParticleList->TrackId(i);
28 /// simb::MCParticle* particle = MCTruthParticleList->Particle(i);
29 /// }
30 /// The STL equivalent to the above statements (more efficient):
31 /// truth::MCTruthParticleList* MCTruthParticleList = // ...;
32 /// for ( auto i = MCTruthParticleList->begin();
33 /// i != MCTruthParticleList->end(); ++i )
34 /// {
35 /// const simb::MCParticle* particle = (*i).second;
36 /// int trackID = particle->TrackId(); // or...
37 /// int trackID = (*i).first;
38 /// }
39 /// or, more compact:
40 /// truth::MCTruthParticleList* MCTruthParticleList = // ...;
41 /// for ( const auto& i: *MCTruthParticleList)
42 /// {
43 /// const simb::MCParticle* particle = i.second;
44 /// int trackID = particle->TrackId(); // or...
45 /// int trackID = i.first;
46 /// }
47 /// If looping over all the particles, do prefer the second and third forms,
48 /// since the first one is unacceptably inefficient for large events.
49 ///
50 /// - Methods to access the list of primary particles in the event:
51 /// truth::MCTruthParticleList MCTruthParticleList = // ...;
52 /// int numberOfPrimaries = MCTruthParticleList->NumberOfPrimaries();
53 /// for ( int i = 0; i != numberOfPrimaries; ++i )
54 /// {
55 /// simb::MCParticle* particle = MCTruthParticleList->Primary(i);
56 /// ...
57 /// }
58 /// There's also a simple test:
59 /// int trackID = // ...;
60 /// if ( MCTruthParticleList->IsPrimary(trackID) ) {...}
61 ///
62 /// (Aside: note that MCTruthParticleList[i] does NOT give you the "i-th"
63 /// particle in the list; it gives you the particle whose trackID
64 /// is "i".)
65 /// Also this form becomes unacceptably inefficient when looping over all the
66 /// particles in a crowded event: prefer to do a bit more of typing as:
67 /// truth::MCTruthParticleList* MCTruthParticleList = // ...;
68 /// for ( const auto& i: *MCTruthParticleList)
69 /// {
70 /// int trackID = i.first;
71 /// if (!MCTruthParticleList->IsPrimary(trackID)) continue;
72 /// const simb::MCParticle* primary = i.second;
73 /// // ...
74 /// }
75 ///
76 ///
77 ///
78 
79 /// - A method EveId(int) to determine the "eve ID" (or ultimate
80 /// mother) for a given particle. For more information, including how
81 /// to supply your own eve ID calculation, see
82 /// Simulation/EveIdCalculator.h and Simulation/EmEveIdCalculator.h.
83 
84 /// - Two MCTruthParticleLists can be merged, which may be useful for
85 /// modeling overlays:
86 /// truth::MCTruthParticleList a,b;
87 /// a.Add(b);
88 /// There's also an operator+ that does the same thing:
89 /// truth::MCTruthParticleList c = a + b;
90 /// WARNING! If the track IDs of the two lists overlapped, then
91 /// the results would be garbage. Therefore, the track IDs of the
92 /// second operand are adjusted when the two lists are merged (without
93 /// actually changing the IDs in that second list). Don't rely
94 /// on the track IDs remaining unchanged!
95 ///
96 /// - The previous procedure requires that the track IDs for an entire
97 /// list be adjust by a fixed offset. In case this functionality is
98 /// useful for cases other than merging lists, it's been made
99 /// available via Add(int) and operator+(int) methods:
100 /// truth::MCTruthParticleList a,b,combinedAB;
101 /// truth::MCTruthParticleList c = b + 10000000; // add 1000000 to all the track IDs in list b
102 /// combinedAB = a + c;
103 ///
104 /// - If you use the clear() or erase() methods, the list will also
105 /// delete the underlying Particle*. (This means that if you use
106 /// insert() or Add() to add a particle to the list, the
107 /// MCTruthParticleList will take over management of it. Don't delete the
108 /// pointer yourself!)
109 ///
110 /// - Print() and operator<< methods for ROOT display and ease of
111 /// debugging.
112 
113 #ifndef SIM_MCTruthParticleList_H
114 #define SIM_MCTruthParticleList_H
115 
116 #include "nusimdata/SimulationBase/MCParticle.h"
117 
118 #include <memory>
119 #include <ostream>
120 #include <map>
121 #include <cstdlib> // std::abs()
122 
123 namespace truth {
124 
125 // Forward declarations.
126 class MCTruthEveIdCalculator;
127 
129 {
130 public:
131  // Some type definitions to make life easier, and to help "hide"
132  // the implementation details. (If you're not familiar with STL,
133  // you can ignore these definitions.)
134  typedef std::map<int,const simb::MCParticle*> list_type;
135  typedef list_type::key_type key_type;
136  typedef list_type::mapped_type mapped_type;
137  typedef list_type::value_type value_type;
138  typedef list_type::iterator iterator;
139  typedef list_type::const_iterator const_iterator;
140  typedef list_type::reverse_iterator reverse_iterator;
141  typedef list_type::const_reverse_iterator const_reverse_iterator;
142  typedef list_type::size_type size_type;
143  typedef list_type::difference_type difference_type;
144  typedef list_type::key_compare key_compare;
145  typedef list_type::allocator_type allocator_type;
146 
147  // Standard constructor, let compiler default the detector
149  virtual ~MCTruthParticleList();
150 
151 private:
153  int parentID = 0;
154 
155  archived_info_type() = default;
156 
157  archived_info_type(int pid): parentID(pid) {}
158  archived_info_type(simb::MCParticle const& part)
159  : parentID(part.Mother())
160  {}
161  archived_info_type(simb::MCParticle const* part)
162  : parentID(part->Mother())
163  {}
164 
165  int Mother() const { return parentID; }
166 
167  friend std::ostream& operator<<
168  ( std::ostream& output, const MCTruthParticleList::archived_info_type& );
169  }; // archived_info_type
170 
171 
172  typedef std::set< int > primaries_type;
173  typedef std::map<int, archived_info_type> archive_type;
174  typedef primaries_type::iterator primaries_iterator;
175  typedef primaries_type::const_iterator primaries_const_iterator;
176 
177  list_type m_MCTruthParticleList; ///< Sorted list of particles in the event
178  primaries_type m_primaries; ///< Sorted list of the track IDs of
179  ///< primary particles.
180  archive_type m_archive; ///< archive of the particles no longer among us
181 
182  //----------------------------------------------------------------------------
183  // variable for eve ID calculator. We're using an unique_ptr,
184  // so when this object is eventually deleted (at the end of the job)
185  // it will delete the underlying pointer.
186  mutable std::unique_ptr<MCTruthEveIdCalculator> m_eveIdCalculator;
187 
188 #ifndef __GCCXML__
189 
190 public:
191 
192  // Because this list contains pointers, we have to provide the
193  // copy and assignment constructors.
194  // MCTruthParticleList( const MCTruthParticleList& rhs );
195  // MCTruthParticleList& operator=( const MCTruthParticleList& rhs );
196 
197  // you know what? let's make it UNCOPIABLE instead!
198  // The cost of copying this buauty is such that we don't want it
199  // to happen unless really requested (copy())
200  MCTruthParticleList( const MCTruthParticleList& rhs ) = delete;
201  MCTruthParticleList& operator=( const MCTruthParticleList& rhs ) = delete;
202  MCTruthParticleList( MCTruthParticleList&& rhs ) = default;
204 
205  /// Returns a copy of this object
207 
208  // The methods advertised above:
209 
210  // Apply an energy threshold cut to the particles in the list,
211  // removing all those that fall below the cut. (Be careful if
212  // you're playing with voxels; this method does not change the
213  // contents of a LArVoxelList.)
214  void Cut( const double& );
215 
216  const key_type& TrackId( const size_type ) const;
217  mapped_type const& Particle( const size_type ) const;
218  mapped_type Particle( const size_type );
219 
220  /// Returns whether we have this particle, live (with full information)
221  bool HasParticle( int trackID ) const
222  {
223  auto iParticle = find(trackID);
224  return (iParticle != end()) && (iParticle->second != nullptr);
225  }
226 
227  /// Returns whether we have had this particle, archived or live
228  bool KnownParticle( int trackID ) const { return find(trackID) != end(); }
229 
230  bool IsPrimary( int trackID ) const;
231  int NumberOfPrimaries() const;
232 
233  std::vector<const simb::MCParticle*> GetPrimaries() const;
234 
235  const simb::MCParticle* Primary( const int ) const;
236 
237  // Standard STL methods, to make this class look like an STL map.
238  // Again, if you don't know STL, you can just ignore these
239  // methods.
240  iterator begin();
241  const_iterator begin() const;
242  iterator end();
243  const_iterator end() const;
248 
249  size_type size() const;
250  bool empty() const;
251  void swap( MCTruthParticleList& other );
252 
253  iterator find(const key_type& key);
254  const_iterator find(const key_type& key) const;
255  iterator upper_bound(const key_type& key);
256  const_iterator upper_bound(const key_type& key) const;
257  iterator lower_bound(const key_type& key);
258  const_iterator lower_bound(const key_type& key) const;
259 
260  // Be careful when using operator[] here! It takes the track ID as the argument:
261  // truth::MCTruthParticleList partList;
262  // const sim::Particle* = partList[3];
263  // The above line means the particle with trackID==3, NOT the third
264  // particle in the list! Use partList.Particle(3) if you want to
265  // get the particles by index number instead of track ID.
266  // Note that this only works in a const context. Use the insert()
267  // or Add() methods to add a new particle to the list.
268  mapped_type const& operator[]( const key_type& key ) const;
269  // This non-const version of operator[] does NOT permit you to insert
270  // Particles into the list. Use Add() or insert() for that.
272  mapped_type at(const key_type& key);
273  mapped_type const& at(const key_type& key) const;
274 
275  /// Extracts the key from the specified value
276  key_type key(mapped_type const& part) const;
277 
278  // These two methods do the same thing:
279  // - Add the Particle to the list, using the track ID as the key.
280  // - Update the list of primary particles as needed.
281  // Note that when you insert a Particle* into a MCTruthParticleList, it
282  // takes over management of the pointer. Don't delete it yourself!
283  void insert( const simb::MCParticle* value );
284  void Add( const simb::MCParticle* value );
285 
286  /// Removes the particle from the list, keeping minimal info of it
287  void Archive( const key_type& key );
288  void Archive( const mapped_type& key );
289 
290  /// This function seeks for the exact key, not its absolute value
291  int GetMotherOf( const key_type& key ) const;
292 
293  void clear();
294  size_type erase( const key_type& key );
296 
297  friend std::ostream& operator<< ( std::ostream& output, const MCTruthParticleList& );
298  friend std::ostream& operator<<
299  ( std::ostream& output, const MCTruthParticleList::archived_info_type& );
300 
301  // Methods associated with the eve ID calculation.
302  // Calculate the eve ID.
303  int EveId ( const int trackID ) const;
304  // Set a pointer to a different eve ID calculation. The name
305  // begins with "Adopt" because it accepts control of the ponters;
306  // do NOT delete the pointer yourself if you use this method.
308 
309 #endif
310  };
311 }
312 
313 #ifndef __GCCXML__
314 
316 inline truth::MCTruthParticleList::const_iterator truth::MCTruthParticleList::begin() const { return m_MCTruthParticleList.begin(); }
317 inline truth::MCTruthParticleList::iterator truth::MCTruthParticleList::end() { return m_MCTruthParticleList.end(); }
318 inline truth::MCTruthParticleList::const_iterator truth::MCTruthParticleList::end() const { return m_MCTruthParticleList.end(); }
319 inline truth::MCTruthParticleList::reverse_iterator truth::MCTruthParticleList::rbegin() { return m_MCTruthParticleList.rbegin(); }
320 inline truth::MCTruthParticleList::const_reverse_iterator truth::MCTruthParticleList::rbegin() const { return m_MCTruthParticleList.rbegin(); }
322 inline truth::MCTruthParticleList::const_reverse_iterator truth::MCTruthParticleList::rend() const { return m_MCTruthParticleList.rend(); }
323 inline truth::MCTruthParticleList::size_type truth::MCTruthParticleList::size() const { return m_MCTruthParticleList.size(); }
324 inline bool truth::MCTruthParticleList::empty() const { return m_MCTruthParticleList.empty(); }
325 inline void truth::MCTruthParticleList::Add(const simb::MCParticle* value) { insert(value); }
327 { m_MCTruthParticleList.swap( other.m_MCTruthParticleList ); m_archive.swap( other.m_archive ); m_primaries.swap( other.m_primaries); }
329 { return m_MCTruthParticleList.find(abs(key)); }
331 { return m_MCTruthParticleList.find(abs(key)); }
333 { return m_MCTruthParticleList.upper_bound(abs(key)); }
335 { return m_MCTruthParticleList.upper_bound(abs(key)); }
337 { return m_MCTruthParticleList.lower_bound(abs(key)); }
339 { return m_MCTruthParticleList.lower_bound(abs(key)); }
341 { return m_MCTruthParticleList.at(std::abs(key)); }
343 { return m_MCTruthParticleList.at(std::abs(key)); }
345 { return at(key); }
347 { return at(key); }
348 inline truth::MCTruthParticleList::key_type truth::MCTruthParticleList::key(mapped_type const& part) const { return part->TrackId(); }
349 
350 
351 #endif
352 
353 
354 #endif // SIM_MCTruthParticleList_H
void swap(MCTruthParticleList &other)
std::vector< const simb::MCParticle * > GetPrimaries() const
list_type::const_iterator const_iterator
void Archive(const key_type &key)
Removes the particle from the list, keeping minimal info of it.
int GetMotherOf(const key_type &key) const
This function seeks for the exact key, not its absolute value.
list_type::reverse_iterator reverse_iterator
primaries_type::const_iterator primaries_const_iterator
MCTruthParticleList MakeCopy() const
Returns a copy of this object.
list_type::size_type size_type
const simb::MCParticle * Primary(const int) const
list_type m_MCTruthParticleList
Sorted list of particles in the event.
iterator upper_bound(const key_type &key)
list_type::const_reverse_iterator const_reverse_iterator
MCTruthParticleList & operator=(const MCTruthParticleList &rhs)=delete
key_type key(mapped_type const &part) const
Extracts the key from the specified value.
list_type::difference_type difference_type
archive_type m_archive
archive of the particles no longer among us
int EveId(const int trackID) const
friend std::ostream & operator<<(std::ostream &output, const MCTruthParticleList &)
list_type::value_type value_type
T abs(T value)
mapped_type const & operator[](const key_type &key) const
std::unique_ptr< MCTruthEveIdCalculator > m_eveIdCalculator
mapped_type const & Particle(const size_type) const
void AdoptEveIdCalculator(MCTruthEveIdCalculator *) const
list_type::mapped_type mapped_type
list_type::key_compare key_compare
iterator find(const key_type &key)
primaries_type::iterator primaries_iterator
void Add(const simb::MCParticle *value)
std::map< int, const simb::MCParticle * > list_type
void insert(const simb::MCParticle *value)
iterator lower_bound(const key_type &key)
size_type erase(const key_type &key)
BEGIN_PROLOG sequence::SlidingWindowTriggerPatternsOppositeWindows END_PROLOG simSlidingORM6O6 effSlidingORW output
list_type::allocator_type allocator_type
mapped_type at(const key_type &key)
std::map< int, archived_info_type > archive_type
temporary value
const key_type & TrackId(const size_type) const
bool IsPrimary(int trackID) const
bool HasParticle(int trackID) const
Returns whether we have this particle, live (with full information)
bool KnownParticle(int trackID) const
Returns whether we have had this particle, archived or live.