2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
5 // Generic overlaying code for Muon Identifiable Containers.
7 // Andrei Gaponenko <agaponenko@lbl.gov>, 2006-2009
9 #include <Identifier/Identifier.h>
11 #include <IDC_OverlayBase/IDC_OverlayCommon.h>
12 #include <MuonOverlayBase/IDC_MultiHitOverlayCommon.h>
15 template <class Collection>
16 std::unique_ptr<Collection> IDC_MuonOverlayBase::copyCollection(const IdentifierHash &hashId,
17 const Collection *collection) const
19 typedef typename Collection::base_value_type Datum;
21 auto outputCollection = std::make_unique<Collection>(collection->identify(), hashId);
23 for (const Datum *existingDatum : *collection) {
24 // Owned by the collection
25 Datum *datumCopy = new Datum(*existingDatum);
26 outputCollection->push_back(datumCopy);
29 return outputCollection;
34 template <class IDC_Container>
35 StatusCode IDC_MuonOverlayBase::overlayContainerBase(const IDC_Container *bkgContainer,
36 const IDC_Container *signalContainer,
37 IDC_Container *outputContainer,
38 bool isMultiHitCollection) const
40 typedef typename IDC_Container::base_value_type Collection;
42 ATH_MSG_DEBUG("overlayContainer<>() begin");
44 // There are some use cases where background is empty
46 // Only loop through the signal collections and copy them over
47 for (const auto &[hashId, ptr] : signalContainer->GetAllHashPtrPair()) {
48 // Copy the signal collection
49 std::unique_ptr<Collection> signalCollection = copyCollection(hashId, ptr);
51 if (outputContainer->addCollection(signalCollection.get(), hashId).isFailure()) {
52 ATH_MSG_ERROR("Adding signal Collection with hashId " << hashId << " failed");
53 return StatusCode::FAILURE;
55 (void)signalCollection.release();
59 return StatusCode::SUCCESS;
62 // The MC signal container should typically be smaller than bkgContainer,
63 // because the latter contains all the noise, minimum bias and pile up.
64 // Thus we firstly iterate over signal hashes and store them in a map.
65 std::vector < std::pair<IdentifierHash, bool> > overlapMap;
66 overlapMap.reserve(signalContainer->numberOfCollections());
67 for (const auto &[hashId, ptr] : signalContainer->GetAllHashPtrPair()) {
68 overlapMap.emplace_back(hashId, false);
71 // Now loop through the background hashes and copy unique ones over
72 for (const auto &[hashId, ptr] : bkgContainer->GetAllHashPtrPair()) {
73 auto search = std::lower_bound( overlapMap.begin(), overlapMap.end(), hashId,
74 [](const std::pair<IdentifierHash, bool> &lhs, IdentifierHash rhs) -> bool { return lhs.first < rhs; } );
75 if (search == overlapMap.end() || search->first != hashId) {
76 // Copy the background collection
77 std::unique_ptr<Collection> bkgCollection = copyCollection(hashId, bkgContainer->indexFindPtr(hashId));
79 if (outputContainer->addCollection(bkgCollection.get(), hashId).isFailure()) {
80 ATH_MSG_ERROR("Adding background Collection with hashId " << hashId << " failed");
81 return StatusCode::FAILURE;
83 (void)bkgCollection.release();
86 // Flip the overlap flag
87 search->second = true;
91 // Finally loop through the map and process the signal and overlay if
93 for (const auto &[hashId, overlap] : overlapMap) {
94 // Copy the signal collection
95 std::unique_ptr<Collection> signalCollection = copyCollection(hashId, signalContainer->indexFindPtr(hashId));
97 if (overlap) { // Do overlay
98 // Create the output collection
99 auto outputCollection = std::make_unique<Collection>(signalCollection->identify(), hashId);
100 // Copy the background collection
101 std::unique_ptr<Collection> bkgCollection = copyCollection(hashId, bkgContainer->indexFindPtr(hashId));
104 if (isMultiHitCollection) {
105 Overlay::mergeMultiHitCollections(bkgCollection.get(), signalCollection.get(), outputCollection.get());
107 Overlay::mergeCollections(bkgCollection.get(), signalCollection.get(), outputCollection.get(), this);
110 if (outputContainer->addCollection(outputCollection.get(), hashId).isFailure()) {
111 ATH_MSG_ERROR("Adding overlaid Collection with hashId " << hashId << " failed");
112 return StatusCode::FAILURE;
114 outputCollection.release();
116 } else { // Only write signal out
117 if (outputContainer->addCollection(signalCollection.get(), hashId).isFailure()) {
118 ATH_MSG_ERROR("Adding signal Collection with hashId " << hashId << " failed");
119 return StatusCode::FAILURE;
121 (void)signalCollection.release();
126 return StatusCode::SUCCESS;