ATLAS Offline Software
Loading...
Searching...
No Matches
IDC_OverlayBase.icc
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 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 //coverity[RESOURCE_LEAK]
43 (void)signalCollection.release();
44 }
45 }
46
47 return StatusCode::SUCCESS;
48 }
49
50
51 // The MC signal container should typically be smaller than bkgContainer,
52 // because the latter contains all the noise, minimum bias and pile up.
53 // Thus we firstly iterate over signal hashes and store them in a map.
54 std::vector < std::pair<IdentifierHash, bool> > overlapMap;
55 overlapMap.reserve(signalContainer->numberOfCollections());
56 for (const auto &[hashId, ptr] : signalContainer->GetAllHashPtrPair()) {
57 overlapMap.emplace_back(hashId, false);
58 }
59
60 // Now loop through the background hashes and copy unique ones over
61 for (const auto &[hashId, ptr] : bkgContainer->GetAllHashPtrPair()) {
62 auto search = std::lower_bound( overlapMap.begin(), overlapMap.end(), hashId,
63 [](const std::pair<IdentifierHash, bool> &lhs, IdentifierHash rhs) -> bool { return lhs.first < rhs; } );
64 if (search == overlapMap.end() || search->first != hashId) {
65 // Copy the background collection
66 std::unique_ptr<Collection> bkgCollection = nullptr;
67 if constexpr (usePool) {
68 bkgCollection = Overlay::copyCollection(hashId, ptr, *dataItems);
69 } else {
70 bkgCollection = Overlay::copyCollection(hashId, ptr);
71 }
72 if (outputContainer->addCollection(bkgCollection.get(), hashId).isFailure()) {
73 ATH_MSG_ERROR("Adding background Collection with hashId " << hashId << " failed");
74 return StatusCode::FAILURE;
75 } else {
76 //coverity[RESOURCE_LEAK]
77 (void)bkgCollection.release();
78 }
79 } else {
80 // Flip the overlap flag
81 search->second = true;
82 }
83 }
84
85 // Finally loop through the map and process the signal and overlay if
86 // necessary
87 for (const auto &[hashId, overlap] : overlapMap) {
88 // Copy the signal collection
89 std::unique_ptr<Collection> signalCollection = nullptr;
90 if constexpr (usePool) {
91 signalCollection = Overlay::copyCollection(
92 hashId, signalContainer->indexFindPtr(hashId), *dataItems);
93 } else {
94 signalCollection = Overlay::copyCollection(
95 hashId, signalContainer->indexFindPtr(hashId));
96 }
97
98 if (overlap) { // Do overlay
99 // Create the output collection, only works for Inner Detector
100 auto outputCollection = std::make_unique<Collection>(hashId);
101 outputCollection->setIdentifier(signalCollection->identify());
102 if constexpr (usePool) {
103 // if we use pool the output is also to go to the pool
104 outputCollection->clear(SG::VIEW_ELEMENTS);
105 }
106 // Copy the background collection
107 // Merge collections
108 std::unique_ptr<Collection> bkgCollection = nullptr;
109 if constexpr (usePool) {
110 bkgCollection = Overlay::copyCollection(
111 hashId, bkgContainer->indexFindPtr(hashId), *dataItems);
112 if constexpr (sortCollections) {
113 Overlay::mergeSortedCollections(bkgCollection.get(), signalCollection.get(),
114 outputCollection.get(), this, *dataItems);
115 } else {
116 Overlay::mergeCollections(bkgCollection.get(), signalCollection.get(),
117 outputCollection.get(), this, *dataItems);
118 }
119 } else {
120 bkgCollection =
121 Overlay::copyCollection(hashId, bkgContainer->indexFindPtr(hashId));
122 Overlay::mergeCollections(bkgCollection.get(), signalCollection.get(),
123 outputCollection.get(), this);
124 }
125 if (outputContainer->addCollection(outputCollection.get(), hashId).isFailure()) {
126 ATH_MSG_ERROR("Adding overlaid Collection with hashId " << hashId << " failed");
127 return StatusCode::FAILURE;
128 } else {
129 //coverity[RESOURCE_LEAK]
130 std::ignore = outputCollection.release();
131 }
132 } else { // Only write signal out
133 if (outputContainer->addCollection(signalCollection.get(), hashId).isFailure()) {
134 ATH_MSG_ERROR("Adding signal Collection with hashId " << hashId << " failed");
135 return StatusCode::FAILURE;
136 } else {
137 //coverity[RESOURCE_LEAK]
138 (void)signalCollection.release();
139 }
140 }
141 }
142 return StatusCode::SUCCESS;
143}
144
145template <typename IDC_Container>
146StatusCode IDC_OverlayBase::overlayContainer(const IDC_Container *bkgContainer,
147 const IDC_Container *signalContainer,
148 IDC_Container *outputContainer) const
149{
150 return overlayContainerImpl<false, false, void>(
151 bkgContainer, signalContainer, outputContainer, nullptr);
152}
153
154template <typename IDC_Container, typename Type>
155StatusCode IDC_OverlayBase::overlayContainer(const IDC_Container *bkgContainer,
156 const IDC_Container *signalContainer,
157 IDC_Container *outputContainer,
158 DataPool<Type>& dataItems) const
159{
160 return overlayContainerImpl<false, true>(
161 bkgContainer, signalContainer, outputContainer, &dataItems);
162}
163
164template <typename IDC_Container, typename Type>
165StatusCode IDC_OverlayBase::overlayContainerWithSorting(const IDC_Container *bkgContainer,
166 const IDC_Container *signalContainer,
167 IDC_Container *outputContainer,
168 DataPool<Type>& dataItems) const
169{
170 return overlayContainerImpl<true, true>(
171 bkgContainer, signalContainer, outputContainer, &dataItems);
172}