ATLAS Offline Software
IDC_OverlayCommon.icc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 /// Generic overlaying code for Identifiable Containers.
6 
7 /// @author Tadej Novak
8 /// @author Andrei Gaponenko <agaponenko@lbl.gov>, 2006-2009
9 
10 #include <algorithm>
11 #include <string>
12 #include <typeinfo>
13 
14 
15 namespace Overlay
16 {
17 
18 template <class Datum, class Alg>
19 void mergeChannelData(Datum &/* baseDatum */,
20  const Datum &/* additionalDatum */,
21  const Alg* /* algorithm */)
22 {
23  throw std::logic_error("Merging of data on the same channel is not implemented for "
24  + std::string(typeid(Datum).name()));
25 }
26 
27 
28 template <bool sortCollections, bool usePool, typename Type, typename Collection, typename Alg>
29 void mergeCollectionsImpl(Collection *bkgCollection,
30  Collection *signalCollection,
31  Collection *outputCollection,
32  const Alg *algorithm,
33  DataPool<Type>* /*nothing*/)
34 {
35  if (bkgCollection->identify() != signalCollection->identify()) {
36  throw std::runtime_error("mergeCollections<>(): collection Id mismatch");
37  }
38 
39  typedef typename Collection::base_value_type Datum;
40  typedef typename Collection::size_type size_type;
41 
42  if constexpr(sortCollections) {
43  sortCollection(bkgCollection);
44  sortCollection(signalCollection);
45  }
46 
47  // Merge by copying ptrs from background and signal to output collection
48  size_type ibkg = 0, isig = 0;
49  while ((ibkg < bkgCollection->size()) || (isig < signalCollection->size())) {
50  // The Datum that goes to the output at the end of this step.
51  Datum *tmp{};
52 
53  if (isig == signalCollection->size()) {
54  // just copy the remaining background digits
55  bkgCollection->swapElement(ibkg++, nullptr, tmp);
56  } else if (ibkg == bkgCollection->size()) {
57  // just copy the remaining signal digits
58  signalCollection->swapElement(isig++, nullptr, tmp);
59  } else {
60  // Need to decide which one goes first.
61  // See comments in TRTDigitization.cxx about the assumption that id1<id2
62  // <=> hash1<hash2
63  if (signalCollection->at(isig)->identify() < bkgCollection->at(ibkg)->identify()) {
64  signalCollection->swapElement(isig++, nullptr, tmp);
65  } else if (bkgCollection->at(ibkg)->identify() < signalCollection->at(isig)->identify()) {
66  bkgCollection->swapElement(ibkg++, nullptr, tmp);
67  } else {
68  // The hits are on the same channel.
69  Datum *tmpBkg{};
70  bkgCollection->swapElement(ibkg++, nullptr, tmpBkg);
71  signalCollection->swapElement(isig++, nullptr, tmp);
72  Overlay::mergeChannelData(*tmp, *tmpBkg, algorithm);
73  if constexpr(!usePool){
74  //If we use a pool it owns the elements
75  delete tmpBkg;
76  }
77  }
78  }
79 
80  outputCollection->push_back(tmp);
81  } // <= while
82 
83  if constexpr(sortCollections) {
84  if (!std::is_sorted(outputCollection->begin(), outputCollection->end(), [](const Datum *a, const Datum *b) {
85  return a->identify() < b->identify();
86  })) {
87  algorithm->msg(MSG::ERROR) << "Output collection not sorted" << endmsg;
88  throw std::runtime_error("mergeCollections<>(): output collection not sorted");
89  }
90  }
91 }
92 
93 template <typename Collection, typename Alg>
94 void mergeCollections(Collection *bkgCollection, Collection *signalCollection,
95  Collection *outputCollection, const Alg *algorithm) {
96  return mergeCollectionsImpl<false, false, void>(
97  bkgCollection, signalCollection, outputCollection, algorithm, nullptr);
98 }
99 
100 template <typename Type, typename Collection, typename Alg>
101 void mergeCollections(Collection *bkgCollection, Collection *signalCollection,
102  Collection *outputCollection, const Alg *algorithm,
103  DataPool<Type> &dataItems) {
104  return mergeCollectionsImpl<false, true>(bkgCollection, signalCollection,
105  outputCollection, algorithm, &dataItems);
106 }
107 
108 template <typename Type, typename Collection, typename Alg>
109 void mergeSortedCollections(Collection *bkgCollection, Collection *signalCollection,
110  Collection *outputCollection, const Alg *algorithm,
111  DataPool<Type> &dataItems) {
112  return mergeCollectionsImpl<true, true>(bkgCollection, signalCollection,
113  outputCollection, algorithm, &dataItems);
114 }
115 
116 } // namespace Overlay