2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
5 /// Generic overlaying code for Identifiable Containers.
7 /// @author Tadej Novak
8 /// @author Andrei Gaponenko <agaponenko@lbl.gov>, 2006-2009
18 template <class Datum, class Alg>
19 void mergeChannelData(Datum &/* baseDatum */,
20 const Datum &/* additionalDatum */,
21 const Alg* /* algorithm */)
23 throw std::logic_error("Merging of data on the same channel is not implemented for "
24 + std::string(typeid(Datum).name()));
28 template <bool sortCollections, bool usePool, typename Type, typename Collection, typename Alg>
29 void mergeCollectionsImpl(Collection *bkgCollection,
30 Collection *signalCollection,
31 Collection *outputCollection,
33 DataPool<Type>* /*nothing*/)
35 if (bkgCollection->identify() != signalCollection->identify()) {
36 throw std::runtime_error("mergeCollections<>(): collection Id mismatch");
39 typedef typename Collection::base_value_type Datum;
40 typedef typename Collection::size_type size_type;
42 if constexpr(sortCollections) {
43 sortCollection(bkgCollection);
44 sortCollection(signalCollection);
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.
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);
60 // Need to decide which one goes first.
61 // See comments in TRTDigitization.cxx about the assumption that id1<id2
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);
68 // The hits are on the same channel.
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
80 outputCollection->push_back(tmp);
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();
87 algorithm->msg(MSG::ERROR) << "Output collection not sorted" << endmsg;
88 throw std::runtime_error("mergeCollections<>(): output collection not sorted");
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);
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);
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);
116 } // namespace Overlay