ATLAS Offline Software
Loading...
Searching...
No Matches
IDC_OverlayBase.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/// @author Tadej Novak
6/// @author Christos Anastopoulos DataPool strategy
7/// @author Andrei Gaponenko <agaponenko@lbl.gov>, 2006-2009
8
9#include <Identifier/Identifier.h>
10#include <Identifier/IdentifierHash.h>
11
12#include "AthContainers/OwnershipPolicy.h"
13
14#include "IDC_OverlayCommon.h"
15
16template <bool sortCollections, bool usePool, typename Type, typename IDC_Container>
17StatusCode IDC_OverlayBase::overlayContainerImpl(
18 const IDC_Container *bkgContainer,
19 const IDC_Container *signalContainer,
20 IDC_Container *outputContainer,
21 DataPool<Type> *dataItems) const
22{
23
24 ATH_MSG_DEBUG("overlayContainer<>() begin");
25 typedef typename IDC_Container::base_value_type Collection;
26
27 // There are some use cases where background is empty
28 if (!bkgContainer) {
29 // Only loop through the signal collections and copy them over
30 for (const auto &[hashId, ptr] : signalContainer->GetAllHashPtrPair()) {
31 // Copy the signal collection
32 std::unique_ptr<Collection> signalCollection = nullptr;
33 if constexpr (usePool){
34 signalCollection = Overlay::copyCollection(hashId, ptr, *dataItems);
35 } else {
36 signalCollection = Overlay::copyCollection(hashId, ptr);
37 }
38 if (outputContainer->addCollection(signalCollection.get(), hashId).isFailure()) {
39 ATH_MSG_ERROR("Adding signal Collection with hashId " << hashId << " failed");
40 return StatusCode::FAILURE;
41 } else {
42 (void)signalCollection.release();
43 }
44 }
45
46 return StatusCode::SUCCESS;
47 }
48
49
50 // The MC signal container should typically be smaller than bkgContainer,
51 // because the latter contains all the noise, minimum bias and pile up.
52 // Thus we firstly iterate over signal hashes and store them in a map.
53 std::vector < std::pair<IdentifierHash, bool> > overlapMap;
54 overlapMap.reserve(signalContainer->numberOfCollections());
55 for (const auto &[hashId, ptr] : signalContainer->GetAllHashPtrPair()) {
56 overlapMap.emplace_back(hashId, false);
57 }
58
59 // Now loop through the background hashes and copy unique ones over
60 for (const auto &[hashId, ptr] : bkgContainer->GetAllHashPtrPair()) {
61 auto search = std::lower_bound( overlapMap.begin(), overlapMap.end(), hashId,
62 [](const std::pair<IdentifierHash, bool> &lhs, IdentifierHash rhs) -> bool { return lhs.first < rhs; } );
63 if (search == overlapMap.end() || search->first != hashId) {
64 // Copy the background collection
65 std::unique_ptr<Collection> bkgCollection = nullptr;
66 if constexpr (usePool) {
67 bkgCollection = Overlay::copyCollection(hashId, ptr, *dataItems);
68 } else {
69 bkgCollection = Overlay::copyCollection(hashId, ptr);
70 }
71 if (outputContainer->addCollection(bkgCollection.get(), hashId).isFailure()) {
72 ATH_MSG_ERROR("Adding background Collection with hashId " << hashId << " failed");
73 return StatusCode::FAILURE;
74 } else {
75 (void)bkgCollection.release();
76 }
77 } else {
78 // Flip the overlap flag
79 search->second = true;
80 }
81 }
82
83 // Finally loop through the map and process the signal and overlay if
84 // necessary
85 for (const auto &[hashId, overlap] : overlapMap) {
86 // Copy the signal collection
87 std::unique_ptr<Collection> signalCollection = nullptr;
88 if constexpr (usePool) {
89 signalCollection = Overlay::copyCollection(
90 hashId, signalContainer->indexFindPtr(hashId), *dataItems);
91 } else {
92 signalCollection = Overlay::copyCollection(
93 hashId, signalContainer->indexFindPtr(hashId));
94 }
95
96 if (overlap) { // Do overlay
97 // Create the output collection, only works for Inner Detector
98 auto outputCollection = std::make_unique<Collection>(hashId);
99 outputCollection->setIdentifier(signalCollection->identify());
100 if constexpr (usePool) {
101 // if we use pool the output is also to go to the pool
102 outputCollection->clear(SG::VIEW_ELEMENTS);
103 }
104 // Copy the background collection
105 // Merge collections
106 std::unique_ptr<Collection> bkgCollection = nullptr;
107 if constexpr (usePool) {
108 bkgCollection = Overlay::copyCollection(
109 hashId, bkgContainer->indexFindPtr(hashId), *dataItems);
110 if constexpr (sortCollections) {
111 Overlay::mergeSortedCollections(bkgCollection.get(), signalCollection.get(),
112 outputCollection.get(), this, *dataItems);
113 } else {
114 Overlay::mergeCollections(bkgCollection.get(), signalCollection.get(),
115 outputCollection.get(), this, *dataItems);
116 }
117 } else {
118 bkgCollection =
119 Overlay::copyCollection(hashId, bkgContainer->indexFindPtr(hashId));
120 Overlay::mergeCollections(bkgCollection.get(), signalCollection.get(),
121 outputCollection.get(), this);
122 }
123 if (outputContainer->addCollection(outputCollection.get(), hashId).isFailure()) {
124 ATH_MSG_ERROR("Adding overlaid Collection with hashId " << hashId << " failed");
125 return StatusCode::FAILURE;
126 } else {
127 outputCollection.release();
128 }
129 } else { // Only write signal out
130 if (outputContainer->addCollection(signalCollection.get(), hashId).isFailure()) {
131 ATH_MSG_ERROR("Adding signal Collection with hashId " << hashId << " failed");
132 return StatusCode::FAILURE;
133 } else {
134 (void)signalCollection.release();
135 }
136 }
137 }
138 return StatusCode::SUCCESS;
139}
140
141template <typename IDC_Container>
142StatusCode IDC_OverlayBase::overlayContainer(const IDC_Container *bkgContainer,
143 const IDC_Container *signalContainer,
144 IDC_Container *outputContainer) const
145{
146 return overlayContainerImpl<false, false, void>(
147 bkgContainer, signalContainer, outputContainer, nullptr);
148}
149
150template <typename IDC_Container, typename Type>
151StatusCode IDC_OverlayBase::overlayContainer(const IDC_Container *bkgContainer,
152 const IDC_Container *signalContainer,
153 IDC_Container *outputContainer,
154 DataPool<Type>& dataItems) const
155{
156 return overlayContainerImpl<false, true>(
157 bkgContainer, signalContainer, outputContainer, &dataItems);
158}
159
160template <typename IDC_Container, typename Type>
161StatusCode IDC_OverlayBase::overlayContainerWithSorting(const IDC_Container *bkgContainer,
162 const IDC_Container *signalContainer,
163 IDC_Container *outputContainer,
164 DataPool<Type>& dataItems) const
165{
166 return overlayContainerImpl<true, true>(
167 bkgContainer, signalContainer, outputContainer, &dataItems);
168}