ATLAS Offline Software
IDC_MultiHitOverlayCommon.icc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 // Ketevi A. Assamagan, 2009
6 
7 #include <Identifier/Identifier.h>
8 #include <Identifier/IdentifierHash.h>
9 
10 #include <set>
11 
12 namespace Overlay
13 {
14 
15 template <class Datum>
16 void mergeMultiHits(const std::vector<Datum *> &bkgHits,
17  const std::vector<Datum *> &signalHits,
18  std::vector<Datum *> &outputHits)
19 {
20  outputHits.clear();
21  outputHits.insert(outputHits.end(), bkgHits.begin(), bkgHits.end());
22  outputHits.insert(outputHits.end(), signalHits.begin(), signalHits.end());
23 }
24 
25 
26 
27 template <class Collection>
28 void mergeMultiHitCollections(Collection *bkgCollection,
29  Collection *signalCollection,
30  Collection *outputCollection)
31 {
32  typedef typename Collection::base_value_type Datum;
33  typedef typename Collection::size_type size_type;
34 
35  /** this is the set of the all the hits treated
36  when all is done, it should be the union of signal and background hits */
37  std::set<Identifier> ids;
38 
39  /** merge hits on the same channel */
40  size_type ibkg = 0;
41  while (ibkg < bkgCollection->size()) {
42  // collect all the background hits of a given Identifer id
43  std::vector<Datum *> vectBkg;
44  Datum *element = bkgCollection->at(ibkg);
45  if (!element) {
46  // element already processed, continue
47  ibkg++;
48  continue;
49  }
50 
51  // Identify the element and check if we already processed it
52  Identifier id = element->identify();
53  if (!ids.insert(id).second) {
54  // this Id already treated -> move on
55  ibkg++;
56  continue;
57  }
58 
59  // Swap out the element
60  Datum *tmpRdo{};
61  bkgCollection->swapElement(ibkg++, nullptr, tmpRdo);
62  vectBkg.push_back(tmpRdo);
63 
64  // Process the rest with the same Identifier id
65  for (size_type i = ibkg; i < bkgCollection->size(); i++) {
66  Datum *element = bkgCollection->at(i);
67  if (!element) // already processed, continue
68  continue;
69  if (element->identify() == id) {
70  // Swap out the element
71  Datum *tmpRdo{};
72  bkgCollection->swapElement(i, nullptr, tmpRdo);
73  vectBkg.push_back(tmpRdo);
74  }
75  }
76 
77  // Collect all the signal hits of the same Identifier id
78  std::vector<Datum *> vectSig;
79  for (size_type i = 0; i < signalCollection->size(); i++) {
80  Datum *element = signalCollection->at(i);
81  if (!element) // already processed, continue
82  continue;
83  if (element->identify() == id) {
84  Datum *tmpRdo{};
85  signalCollection->swapElement(i, nullptr, tmpRdo);
86  vectSig.push_back(tmpRdo);
87  }
88  }
89 
90  /** now we have vectBkg and vectSig for same Id channels,
91  call the multi hit overlay and save the merged hits */
92  if (!vectSig.empty()) { // no need to merge hits if signal not empty
93  std::vector<Datum *> vect;
94  Overlay::mergeMultiHits(vectBkg, vectSig, vect);
95  for (Datum *element : vect)
96  outputCollection->push_back(element);
97  } else { // copy directly background if signal is empty
98  for (Datum *element : vectBkg)
99  outputCollection->push_back(element);
100  }
101  }
102 
103  /** now there must be some hits in the signal collection that are not treated yet -
104  deal with those at this time. These should be the hit Ids that
105  are in the signal but not found in the background */
106  size_type isig = 0;
107  while (isig < signalCollection->size()) {
108  Datum *element = signalCollection->at(isig);
109  if (!element) {
110  // element already processed, continue
111  isig++;
112  continue;
113  }
114 
115  Identifier id = element->identify();
116  if (!ids.insert(id).second) {
117  // this Id already treated -> move on
118  isig++;
119  continue;
120  }
121 
122  Datum *tmpRdo{};
123  signalCollection->swapElement(isig++, 0, tmpRdo);
124  outputCollection->push_back(tmpRdo);
125  }
126 }
127 
128 } // namespace Overlay