ATLAS Offline Software
IDC_OverlayCommon.icc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 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 <string>
11 #include <typeinfo>
12 
13 
14 namespace Overlay
15 {
16 
17 template <class Datum, class Alg>
18 void mergeChannelData(Datum &/* baseDatum */,
19  const Datum &/* additionalDatum */,
20  const Alg* /* algorithm */)
21 {
22  throw std::logic_error("Merging of data on the same channel is not implemented for "
23  + std::string(typeid(Datum).name()));
24 }
25 
26 
27 template <bool usePool, typename Type, typename Collection, typename Alg>
28 void mergeCollectionsImpl(Collection *bkgCollection,
29  Collection *signalCollection,
30  Collection *outputCollection,
31  const Alg *algorithm,
32  DataPool<Type>* /*nothing*/)
33 {
34  if (bkgCollection->identify() != signalCollection->identify()) {
35  throw std::runtime_error("mergeCollections<>(): collection Id mismatch");
36  }
37 
38  typedef typename Collection::base_value_type Datum;
39  typedef typename Collection::size_type size_type;
40 
41  // Merge by copying ptrs from background and signal to output collection
42  size_type ibkg = 0, isig = 0;
43  while ((ibkg < bkgCollection->size()) || (isig < signalCollection->size())) {
44  // The Datum that goes to the output at the end of this step.
45  Datum *tmp{};
46 
47  if (isig == signalCollection->size()) {
48  // just copy the remaining background digits
49  bkgCollection->swapElement(ibkg++, nullptr, tmp);
50  } else if (ibkg == bkgCollection->size()) {
51  // just copy the remaining signal digits
52  signalCollection->swapElement(isig++, nullptr, tmp);
53  } else {
54  // Need to decide which one goes first.
55  // See comments in TRTDigitization.cxx about the assumption that id1<id2
56  // <=> hash1<hash2
57  if (signalCollection->at(isig)->identify() < bkgCollection->at(ibkg)->identify()) {
58  signalCollection->swapElement(isig++, nullptr, tmp);
59  } else if (bkgCollection->at(ibkg)->identify() < signalCollection->at(isig)->identify()) {
60  bkgCollection->swapElement(ibkg++, nullptr, tmp);
61  } else {
62  // The hits are on the same channel.
63  Datum *tmpBkg{};
64  bkgCollection->swapElement(ibkg++, nullptr, tmpBkg);
65  signalCollection->swapElement(isig++, nullptr, tmp);
66  Overlay::mergeChannelData(*tmp, *tmpBkg, algorithm);
67  if constexpr(!usePool){
68  //If we use a pool it owns the elements
69  delete tmpBkg;
70  }
71  }
72  }
73 
74  outputCollection->push_back(tmp);
75  } // <= while
76 }
77 
78 template <typename Collection, typename Alg>
79 void mergeCollections(Collection *bkgCollection, Collection *signalCollection,
80  Collection *outputCollection, const Alg *algorithm) {
81  return mergeCollectionsImpl<false, void>(
82  bkgCollection, signalCollection, outputCollection, algorithm, nullptr);
83 }
84 
85 template <typename Type, typename Collection, typename Alg>
86 void mergeCollections(Collection *bkgCollection, Collection *signalCollection,
87  Collection *outputCollection, const Alg *algorithm,
88  DataPool<Type> &dataItems) {
89  return mergeCollectionsImpl<true>(bkgCollection, signalCollection,
90  outputCollection, algorithm, &dataItems);
91 }
92 
93 } // namespace Overlay