2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
5 /// @author Tadej Novak
6 /// @author Christos Anastopoulos DataPool strategy
7 /// @author Andrei Gaponenko <agaponenko@lbl.gov>, 2006-2009
9 #include <Identifier/Identifier.h>
10 #include <Identifier/IdentifierHash.h>
12 #include "AthContainers/OwnershipPolicy.h"
14 #include "IDC_OverlayCommon.h"
16 template <bool usePool, typename Type, typename IDC_Container>
17 StatusCode IDC_OverlayBase::overlayContainerImpl(
18 const IDC_Container *bkgContainer,
19 const IDC_Container *signalContainer,
20 IDC_Container *outputContainer,
21 DataPool<Type> *dataItems) const
24 ATH_MSG_DEBUG("overlayContainer<>() begin");
25 typedef typename IDC_Container::base_value_type Collection;
27 // There are some use cases where background is empty
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);
36 signalCollection = Overlay::copyCollection(hashId, ptr);
38 if (outputContainer->addCollection(signalCollection.get(), hashId).isFailure()) {
39 ATH_MSG_ERROR("Adding signal Collection with hashId " << hashId << " failed");
40 return StatusCode::FAILURE;
42 (void)signalCollection.release();
46 return StatusCode::SUCCESS;
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);
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);
69 bkgCollection = Overlay::copyCollection(hashId, ptr);
71 if (outputContainer->addCollection(bkgCollection.get(), hashId).isFailure()) {
72 ATH_MSG_ERROR("Adding background Collection with hashId " << hashId << " failed");
73 return StatusCode::FAILURE;
75 (void)bkgCollection.release();
78 // Flip the overlap flag
79 search->second = true;
83 // Finally loop through the map and process the signal and overlay if
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);
92 signalCollection = Overlay::copyCollection(
93 hashId, signalContainer->indexFindPtr(hashId));
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);
104 // Copy the background collection
106 std::unique_ptr<Collection> bkgCollection = nullptr;
107 if constexpr (usePool) {
108 bkgCollection = Overlay::copyCollection(
109 hashId, bkgContainer->indexFindPtr(hashId), *dataItems);
110 Overlay::mergeCollections(bkgCollection.get(), signalCollection.get(),
111 outputCollection.get(), this, *dataItems);
114 Overlay::copyCollection(hashId, bkgContainer->indexFindPtr(hashId));
115 Overlay::mergeCollections(bkgCollection.get(), signalCollection.get(),
116 outputCollection.get(), this);
118 if (outputContainer->addCollection(outputCollection.get(), hashId).isFailure()) {
119 ATH_MSG_ERROR("Adding overlaid Collection with hashId " << hashId << " failed");
120 return StatusCode::FAILURE;
122 outputCollection.release();
124 } else { // Only write signal out
125 if (outputContainer->addCollection(signalCollection.get(), hashId).isFailure()) {
126 ATH_MSG_ERROR("Adding signal Collection with hashId " << hashId << " failed");
127 return StatusCode::FAILURE;
129 (void)signalCollection.release();
133 return StatusCode::SUCCESS;
136 template <typename IDC_Container>
137 StatusCode IDC_OverlayBase::overlayContainer(const IDC_Container *bkgContainer,
138 const IDC_Container *signalContainer,
139 IDC_Container *outputContainer) const
141 return overlayContainerImpl<false, void>(
142 bkgContainer, signalContainer, outputContainer, nullptr);
145 template <typename IDC_Container, typename Type>
146 StatusCode IDC_OverlayBase::overlayContainer(const IDC_Container *bkgContainer,
147 const IDC_Container *signalContainer,
148 IDC_Container *outputContainer,
149 DataPool<Type>& dataItems) const
151 return overlayContainerImpl<true>(bkgContainer,signalContainer,outputContainer,&dataItems);