IDNumberGen.h
Go to the documentation of this file.
1 // IDNumberGen.h
2 //
3 // Created by Leo Bellantoni on 2 Aug 2019.
4 // With lots of help from Paul Russo :)
5 //
6 // For implementing operator==() in Track, Vertex, Cluster classes -
7 // maybe in other ReconstructionDataProducts classes later
8 //
9 // Implemented as a thread-safe singleton using C++11 features esp std::atomic
10 //
11 // Put
12 // #include "IDNumberGen.h"
13 // in the header for your ReconstructionDataProducts class. Then put
14 // IDNumberGen::IDNumber fIDnumero;
15 // in the private part of the definition of said class; then put
16 // IDNumberGen::create(firstNumber);
17 // fIDnumero = IDNumberGen::create()->getNewOne();
18 // in its constructor. Be sure to do this also in the default constructor,
19 // which can be invoked by art. IDNumber is just a typedef to size_t.
20 // The firstNumber is just that; maybe you want to count tracks numbering
21 // from 100000, ECAL clusters from 300000 and vertices from 400000. Maybe you
22 // want to define the firstNumber as a static IDNumberGen::IDNumber const in the
23 // private section of the class definition. Probably you want firstNumber
24 // for lower level objects like a TPC cluster or a CaloHit to start with a higher
25 // value such as 100100000 or 100200000. If there is already an instance of a
26 // ReconstructionDataProducts class with the same fIDnumero as firstNumber,
27 // then you will have two objects out there with the same ID. They are probably
28 // of different classes, so the rest of your analysis code might well work.
29 //
30 // Then implement an operator==(const ...& rhs), an operator!=(const ...& rhs)
31 // and a IDNumber <T>::getIDNumber() as public in the reconstruction data
32 // products class <T>.
33 //
34 // Finally, we need to reset the counter at the start of every event.
35 // That requires an art::EDProducer module (e.g. EventInit_module.cc which is
36 // sequenced to be at the start of the trigger_path in the fcl file and which,
37 // in its produce method, has the line
38 // IDNumberGen::create()->newEventReset();
39 //
40 // Asute reader! You have noticed the suggestion that vertices be numbered
41 // from 400000 rather than 200000. The underlying assumption is that one
42 // makes all the instances of a given ReconstructionDataProducts class at
43 // once; e.g. the tracking module will make all the tracks, then the vertexer
44 // module makes all the vertices etc. That is, the only way to reset
45 // nextOneToMake is to create a new class in ReconstructionDataProducts with
46 // a new firstNumber. As of Apr 2020 however, we create some Tracks, create
47 // some Vertexes, and then in the track stitcher we go back and create some
48 // more Tracks. Because nextOneToMake is then somewhat over 200000, we have
49 // stitched tracks with numbers starting from 200000. So we number vertices
50 // from 400000.
51 //
52 
53 
54 #ifndef GAR_RECONSTRUCTIONDATAPRODUCTS_IDNumber_h
55 #define GAR_RECONSTRUCTIONDATAPRODUCTS_IDNumber_h
56 
57 
58 
59 #include <cstdlib>
60 #include <atomic>
61 #include <limits>
62 #include <set>
63 
64 
65 
66 namespace gar {
67  namespace rec {
68 
69 
70 
71  typedef size_t IDNumber;
72 
73 
74 
75  class IDNumberGen {
76  public:
77 
78  static IDNumberGen* create(IDNumber iniValue = std::numeric_limits<IDNumber>::max());
79  IDNumber getNewOne();
80  void newEventReset();
81 
82 
83 
84  // Copy constructors, assignment constructors don't happen in singletons!
85  // Here, the IDNumberGen isn't "in" the ReconstructionDataProducts class.
86  IDNumberGen(const IDNumberGen& arg) = delete; // Copy constructor
87  IDNumberGen(const IDNumberGen&& arg) = delete; // Move constructor
88  IDNumberGen& operator=(const IDNumberGen& arg) = delete; // Assignment operator
89  IDNumberGen& operator=(const IDNumberGen&& arg) = delete; // Move operator
90 
91 
92 
93  private:
94  // We told classes_def.xml to not make a dictionary for IDNumberGen
95  // otherwise the dictionary maker would insist these be public.
96  IDNumberGen();
97  ~IDNumberGen();
98 
99  static std::atomic<gar::rec::IDNumber> nextOneToMake;
100  static std::set<gar::rec::IDNumber> previousInitializers;
101  };
102 
103 
104 
105  } // rec
106 } // gar
107 
108 
109 #endif
rec
Definition: tracks.py:88
static std::atomic< gar::rec::IDNumber > nextOneToMake
Definition: IDNumberGen.h:99
IDNumberGen & operator=(const IDNumberGen &arg)=delete
static IDNumberGen * create(IDNumber iniValue=std::numeric_limits< IDNumber >::max())
Definition: IDNumberGen.cxx:18
static std::set< gar::rec::IDNumber > previousInitializers
Definition: IDNumberGen.h:100
static int max(int a, int b)
General GArSoft Utilities.
size_t IDNumber
Definition: IDNumberGen.h:71