diff --git a/Event/EventOverlay/IDC_OverlayBase/CMakeLists.txt b/Event/EventOverlay/IDC_OverlayBase/CMakeLists.txt index 99c2cc620c69a811a9a22a2771145f565002283b..f17f9b0b758ccbee2c5649da439b9b6fcc16bcd2 100644 --- a/Event/EventOverlay/IDC_OverlayBase/CMakeLists.txt +++ b/Event/EventOverlay/IDC_OverlayBase/CMakeLists.txt @@ -7,13 +7,10 @@ atlas_subdir( IDC_OverlayBase ) # Declare the package's dependencies: atlas_depends_on_subdirs( PUBLIC - Control/AthenaBaseComps - Control/AthContainers DetectorDescription/Identifier Event/EventOverlay/OverlayAlgBase ) # Component(s) in the package: atlas_add_library( IDC_OverlayBase PUBLIC_HEADERS IDC_OverlayBase - LINK_LIBRARIES AthenaBaseComps AthContainers Identifier OverlayAlgBase ) - + LINK_LIBRARIES Identifier OverlayAlgBase ) diff --git a/Event/EventOverlay/IDC_OverlayBase/IDC_OverlayBase/IDC_OverlayBase.h b/Event/EventOverlay/IDC_OverlayBase/IDC_OverlayBase/IDC_OverlayBase.h index ad713366ef142121eff1536f3441c319fc1f389f..ec933f9e5958d38b2ae1d8901b50bc37aeed660b 100644 --- a/Event/EventOverlay/IDC_OverlayBase/IDC_OverlayBase/IDC_OverlayBase.h +++ b/Event/EventOverlay/IDC_OverlayBase/IDC_OverlayBase/IDC_OverlayBase.h @@ -10,79 +10,29 @@ * Common base class and generic overlaying code for boolean-like hits. * Factored out from InDetOverlay. * + * @author Tadej Novak * @author Andrei Gaponenko <agaponenko@lbl.gov>, 2006-2009 - * */ #ifndef IDC_OVERLAYBASE_H #define IDC_OVERLAYBASE_H -#include <string> - -#include "OverlayAlgBase/OverlayAlgBase.h" -#include "IDC_OverlayBase/IDC_OverlayCommon.h" -#include "IDC_OverlayBase/IDC_OverlayHelpers.h" - -class IDC_OverlayBase; - -namespace Overlay { - - /** - * Merging of hits on the same channel. Modifies the first argument by adding data from the second.. - * Implementations can assume that the arguments have the same Id. (That is, correspond to the same readout channel.) - * - * A generic implementation of this template is provided in this package, - * but subdetectors can provide specializations suitable for their RDO type. - * A simple example of providing a specialization is in InDetOverlay.cxx (for TRT_RDORawData). - * A more elaborate implementation can be found e.g. in MdtOverlay.cxx - * - * Note that a declaration of a specialized template must occur before it is used - * by overlayContainer()/mergeCollections() [typically from the execute() method of your algorithm]. - */ - template<class Datum> void mergeChannelData(Datum& r1, const Datum& r2, IDC_OverlayBase* parent); - - /** - * Adds data and mc from the second collection to the output one merging where necessary. - * After this data and mc collections stay unchanged and output collection contains all information - * - * A generic implementation in the .icc file can be overriden by a - * specialization, see above. - */ +#include <OverlayAlgBase/OverlayAlgBase.h> - template<class Collection> void mergeCollectionsNew(Collection *mc_coll, Collection *data_coll, Collection *out_coll, IDC_OverlayBase* parent); -} - - -class IDC_OverlayBase : public OverlayAlgBase { +class IDC_OverlayBase : public OverlayAlgBase +{ public: - IDC_OverlayBase(const std::string &name, ISvcLocator *pSvcLocator) - : OverlayAlgBase(name, pSvcLocator) - {} - - /** - * Transfers all collections from the first and second arguments to the output the first merging where necessary. - */ - template<class IDC_Container> void overlayContainer(const IDC_Container* data, const IDC_Container* mc, IDC_Container* out ) { - Overlay::overlayContainer(data, mc, out, this); - } - - template<class IDC_Container> void overlayContainerNew(const IDC_Container* data, const IDC_Container* mc, IDC_Container* out ) { - Overlay::overlayContainerNew(data, mc, out, this); - } - - template<class IDC_Container> std::string shortPrint(const IDC_Container *container, unsigned numprint = 25) { - return Overlay::debugPrint(container, numprint); - } + : OverlayAlgBase(name, pSvcLocator) {} - /** - * Adds data and mc from the second collection to the output one merging where necessary. - * After this data and mc collections stay unchanged and output collection contains all information - */ - template<class Collection> void mergeCollections(Collection *mc_coll, Collection *data_coll, Collection *out_coll); +protected: + template <class IDC_Container> + StatusCode overlayContainer(const IDC_Container *bkgContainer, + const IDC_Container *signalContainer, + IDC_Container *outputContainer); }; #include "IDC_OverlayBase/IDC_OverlayBase.icc" -#endif/*IDC_OVERLAYBASE_H*/ +#endif diff --git a/Event/EventOverlay/IDC_OverlayBase/IDC_OverlayBase/IDC_OverlayBase.icc b/Event/EventOverlay/IDC_OverlayBase/IDC_OverlayBase/IDC_OverlayBase.icc index 711db40f69f1452f37554c7d48f2549aa4dcf7fb..dc932208f9524fcb40f14f51e39208571deee394 100644 --- a/Event/EventOverlay/IDC_OverlayBase/IDC_OverlayBase/IDC_OverlayBase.icc +++ b/Event/EventOverlay/IDC_OverlayBase/IDC_OverlayBase/IDC_OverlayBase.icc @@ -1,172 +1,107 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration */ -// Generic overlaying code for boolean-like hits. -// Factored out from InDetOverlay. -// -// Andrei Gaponenko <agaponenko@lbl.gov>, 2006-2009 +/// @author Tadej Novak +/// @author Andrei Gaponenko <agaponenko@lbl.gov>, 2006-2009 -#include "Identifier/Identifier.h" -#include "Identifier/IdentifierHash.h" +#include <Identifier/Identifier.h> +#include <Identifier/IdentifierHash.h> -#include "AthenaBaseComps/AthMsgStreamMacros.h" +#include "IDC_OverlayCommon.h" -#include "AthContainers/DataVector.h" - -#include <sstream> -#include <typeinfo> +template <class IDC_Container> +StatusCode IDC_OverlayBase::overlayContainer(const IDC_Container *bkgContainer, + const IDC_Container *signalContainer, + IDC_Container *outputContainer) +{ + ATH_MSG_DEBUG("overlayContainer<>() begin"); -namespace Overlay { - - //================================================================ - template<class Datum> - void mergeChannelData(Datum& /*r1*/, const Datum& /*r2*/, IDC_OverlayBase* parent) { - // this is the default implementation. - // We do not touch the data here, just print a warning. - static bool first_time = true; - if(first_time) { - first_time = false; - parent->msg(MSG::WARNING)<<"Overlay::mergeChannelData(): Merging of hits on the same channel is not implemented for " - <<typeid(Datum).name() - <<endmsg; - } - } + typedef typename IDC_Container::base_value_type Collection; + // Get all the hashes for the signal container + const std::vector<IdentifierHash> signalHashes = signalContainer->GetAllCurrentHashes(); - //================================================================ - template<class Collection> - void mergeCollectionsNew(Collection *mc_coll, Collection *data_coll, Collection *out_coll, IDC_OverlayBase *parent) { - - if(mc_coll->identify() != data_coll->identify()) { - std::ostringstream os; - os<<"mergeCollectionsNew<generic>(): collection Id mismatch"; - parent->msg(MSG::FATAL)<<os.str()<<endmsg; - throw std::runtime_error(os.str()); - } + // There are some use cases where background is empty + if (!bkgContainer) { + // Only loop through the signal collections and copy them over + for (const IdentifierHash &hashId : signalHashes) { + // Copy the signal collection + std::unique_ptr<Collection> signalCollection = Overlay::copyCollection(hashId, signalContainer->indexFindPtr(hashId)); - const Identifier idColl = mc_coll->identify(); - - // ---------------------------------------------------------------- - // debug - static bool first_time = true; - if(first_time) { - first_time = false; - parent->msg(MSG::INFO)<<"IDC_OverlayBase::mergeCollectionsNew(): " - <<"generic code is called for " - <<typeid(*mc_coll).name() - <<endmsg; - } - - // ---------------------------------------------------------------- - - //DataVector<typename Collection::base_value_type> data(data_coll->identifyHash()); - Collection data(data_coll->identifyHash()); - data.setIdentifier(idColl); - data_coll->swap(data); - - //DataVector<typename Collection::base_value_type> mc(mc_coll->identifyHash()); - Collection mc(mc_coll->identifyHash()); - mc.setIdentifier(idColl); - mc_coll->swap(mc); - - //################################################################ - // Merge by copying ptrs from data and mc to mc_coll - - typename Collection::size_type idata = 0; - typename Collection::size_type imc = 0; - - while( (idata < data.size()) || (imc < mc.size())) { - - // The RDO that goes to the output at the end of this step. - typename Collection::base_value_type *p_rdo(0); - - if(imc == mc.size()) { - // just copy the remaining data inputs - data.swapElement(idata++, 0, p_rdo); - } - else if(idata == data.size()) { - //just copy the remaining MC digits - mc.swapElement(imc++, 0, p_rdo); - } - else { - // Need to decide which one goes first. - // See comments in TRTDigitization.cxx about the assumption that id1<id2 <=> hash1<hash2 - if( mc[imc]->identify() < data[idata]->identify() ) { - mc.swapElement(imc++, 0, p_rdo); - } - else if(data[idata]->identify() < mc[imc]->identify()) { - data.swapElement(idata++, 0, p_rdo); - } - else { - // The hits are on the same channel. - typename Collection::base_value_type *p2(0); - data.swapElement(idata++, 0, p2); - mc.swapElement(imc++, 0, p_rdo); - Overlay::mergeChannelData(*p_rdo, *p2, parent); - delete p2; - } + if (outputContainer->addCollection(signalCollection.get(), hashId).isFailure()) { + ATH_MSG_ERROR("Adding signal Collection with hashId " << hashId << " failed"); + return StatusCode::FAILURE; + } else { + signalCollection.release(); } + } - out_coll->push_back(p_rdo); - } // <= while + return StatusCode::SUCCESS; } -} // namespace Overlay - - -//================================================================ -template<class Collection> -void IDC_OverlayBase::mergeCollections(Collection *mc_coll, - Collection *data_coll, - Collection *out_coll) -{ - DataVector<typename Collection::base_value_type> data; - data_coll->swap(data); - - DataVector<typename Collection::base_value_type> mc; - mc_coll->swap(mc); + // Get all the hashes for the background container + const std::vector<IdentifierHash> bkgHashes = bkgContainer->GetAllCurrentHashes(); - //################################################################ - // Merge by copying ptrs from data and mc to mc_coll - - typename Collection::size_type idata = 0; - typename Collection::size_type imc = 0; - - while( (idata < data.size()) || (imc < mc.size())) { - - // The RDO that goes to the output at the end of this step. - typename Collection::base_value_type *p_rdo(0); - - if(idata == data.size()) { - // just copy the remaining MC inputs - mc.swapElement(imc++, 0, p_rdo); - } - else if(imc == mc.size()) { - //just copy the remaining data digits - data.swapElement(idata++, 0, p_rdo); - } - else { - // Need to decide which one goes first. - // See comments in TRTDigitization.cxx about the assumption that id1<id2 <=> hash1<hash2 - if( data[idata]->identify() < mc[imc]->identify() ) { - data.swapElement(idata++, 0, p_rdo); + // The MC signal container should typically be smaller than bkgContainer, + // because the latter contains all the noise, minimum bias and pile up. + // Thus we firstly iterate over signal hashes and store them in a map. + std::map<IdentifierHash, bool> overlapMap; + for (const IdentifierHash &hashId : signalHashes) { + overlapMap.emplace(hashId, false); + } + + // Now loop through the background hashes and copy unique ones over + for (const IdentifierHash &hashId : bkgHashes) { + auto search = overlapMap.find(hashId); + if (search == overlapMap.end()) { + // Copy the background collection + std::unique_ptr<Collection> bkgCollection = Overlay::copyCollection(hashId, bkgContainer->indexFindPtr(hashId)); + + if (outputContainer->addCollection(bkgCollection.get(), hashId).isFailure()) { + ATH_MSG_ERROR("Adding background Collection with hashId " << hashId << " failed"); + return StatusCode::FAILURE; + } else { + bkgCollection.release(); } - else if(mc[imc]->identify() < data[idata]->identify()) { - mc.swapElement(imc++, 0, p_rdo); + } else { + // Flip the overlap flag + search->second = true; + } + } + + // Finally loop through the map and process the signal and overlay if + // necessary + for (const auto &[hashId, overlap] : overlapMap) { + // Copy the signal collection + std::unique_ptr<Collection> signalCollection = Overlay::copyCollection(hashId, signalContainer->indexFindPtr(hashId)); + + if (overlap) { // Do overlay + // Create the output collection, only works for Inner Detector + auto outputCollection = std::make_unique<Collection>(hashId); + outputCollection->setIdentifier(signalCollection->identify()); + // Copy the background collection + std::unique_ptr<Collection> bkgCollection = Overlay::copyCollection(hashId, bkgContainer->indexFindPtr(hashId)); + + // Merge collections + Overlay::mergeCollections(bkgCollection.get(), signalCollection.get(), outputCollection.get(), this); + + if (outputContainer->addCollection(outputCollection.get(), hashId).isFailure()) { + ATH_MSG_ERROR("Adding overlaid Collection with hashId " << hashId << " failed"); + return StatusCode::FAILURE; + } else { + outputCollection.release(); } - else { - // The hits are on the same channel. - typename Collection::base_value_type *p2(0); - data.swapElement(idata++, 0, p2); - mc.swapElement(imc++, 0, p_rdo); - Overlay::mergeChannelData(*p_rdo, *p2, this); - delete p2; + } else { // Only write signal out + if (outputContainer->addCollection(signalCollection.get(), hashId).isFailure()) { + ATH_MSG_ERROR("Adding signal Collection with hashId " << hashId << " failed"); + return StatusCode::FAILURE; + } else { + signalCollection.release(); } } + } - out_coll->push_back(p_rdo); - } // <= while + return StatusCode::SUCCESS; } - diff --git a/Event/EventOverlay/IDC_OverlayBase/IDC_OverlayBase/IDC_OverlayCommon.h b/Event/EventOverlay/IDC_OverlayBase/IDC_OverlayBase/IDC_OverlayCommon.h index fe26915711d82ca200549c14676081028fa2c214..f2913969b8808e50df5d5b8a96aaf01966c45a7f 100644 --- a/Event/EventOverlay/IDC_OverlayBase/IDC_OverlayBase/IDC_OverlayCommon.h +++ b/Event/EventOverlay/IDC_OverlayBase/IDC_OverlayBase/IDC_OverlayCommon.h @@ -2,46 +2,46 @@ Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration */ -// Dear emacs, this is -*-c++-*- +// Dear emacs, this is -*-c++-*- /** * @file - * + * * Overlaying of Identifiable Containers. Functions common to the * single-hit-per-readout-channel-in-an-event case and the * possible-multiple-hits-on-a-channel case are declared in this file. * + * @author Tadej Novak * @author Andrei Gaponenko <agaponenko@lbl.gov>, 2009 - * */ #ifndef IDC_OVERLAYCOMMON_H #define IDC_OVERLAYCOMMON_H -#include <string> - -#include "OverlayAlgBase/OverlayAlgBase.h" - -class IDC_OverlayBase; +#include <memory> -namespace Overlay { +#include <Identifier/IdentifierHash.h> - template<class Collection> void copyCollection(const Collection *input_coll, Collection *copy_coll); +namespace Overlay +{ - //Forward decl for compiling ... - template<class Collection> void mergeCollectionsNew(Collection*, Collection*, Collection*, IDC_OverlayBase*); +template <class Collection> +std::unique_ptr<Collection> copyCollection(const IdentifierHash &hashId, + const Collection *collection); - /** - * Transfers all collection from the second argument the first merging where necessary. - * After this call the "data" container contains all information, and the "mc" - * container is empty. - */ - template<class IDC_Container, class OvlAlg> void overlayContainer(const IDC_Container* data, const IDC_Container* mc, IDC_Container* out, OvlAlg *parent); +template<class Datum, class Alg> +void mergeChannelData(Datum &baseDatum, + const Datum &additionalDatum, + Alg *algorithm); - template<class IDC_Container, class OvlAlg> void overlayContainerNew(const IDC_Container* dataContainer, const IDC_Container* mcContainer, IDC_Container* outputContainer, OvlAlg *parent); +template <class Collection, class Alg> +void mergeCollections(Collection *bkgCollection, + Collection *signalCollection, + Collection *outputCollection, + Alg *algorithm); -} +} // namespace Overlay #include "IDC_OverlayBase/IDC_OverlayCommon.icc" -#endif/*IDC_OVERLAYCOMMON_H*/ +#endif diff --git a/Event/EventOverlay/IDC_OverlayBase/IDC_OverlayBase/IDC_OverlayCommon.icc b/Event/EventOverlay/IDC_OverlayBase/IDC_OverlayBase/IDC_OverlayCommon.icc index c5741622d528fc51ce8b4d384f922c75ec858ed6..5aaf601297fbe2ca3f6bbcacd8ea4b4511664e3a 100644 --- a/Event/EventOverlay/IDC_OverlayBase/IDC_OverlayBase/IDC_OverlayCommon.icc +++ b/Event/EventOverlay/IDC_OverlayBase/IDC_OverlayBase/IDC_OverlayCommon.icc @@ -2,172 +2,73 @@ Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration */ -// Generic overlaying code for Identifiable Containers. -// -// Andrei Gaponenko <agaponenko@lbl.gov>, 2006-2009 +/// Generic overlaying code for Identifiable Containers. -#include "Identifier/Identifier.h" -#include "Identifier/IdentifierHash.h" +/// @author Tadej Novak +/// @author Andrei Gaponenko <agaponenko@lbl.gov>, 2006-2009 -#include "StoreGate/ReadHandle.h" -#include "StoreGate/WriteHandle.h" - +#include <string> +#include <typeinfo> -#include "AthenaBaseComps/AthMsgStreamMacros.h" -#include "AthContainers/DataVector.h" +namespace Overlay +{ -#include <sstream> +template <class Datum, class Alg> +void mergeChannelData(Datum &/* baseDatum */, + const Datum &/* additionalDatum */, + Alg */* algorithm */) +{ + throw std::logic_error("Merging of data on the same channel is not implemented for " + + std::string(typeid(Datum).name())); +} -namespace Overlay { - //================================================================ - template<class IDC_Container, class OvlAlg> - void overlayContainerNew(const IDC_Container *dataContainer, - const IDC_Container *mcContainer, - IDC_Container *outputContainer, - OvlAlg *parent) - { - typedef typename IDC_Container::base_value_type Collection; - std::cout<<"start overlayContainer"<<std::endl; - if(parent->msgLvl(MSG::DEBUG)) { parent->msg(MSG::DEBUG)<<"overlayContainerNew<>() begin"<<endmsg; } - - //There are some use cases where this is empty - if(dataContainer != nullptr){ - /** Add data from the data container to the output one */ - typename IDC_Container::const_iterator p_data = dataContainer->begin(); - typename IDC_Container::const_iterator p_data_end = dataContainer->end(); - - for(; p_data != p_data_end; ++p_data) { - IdentifierHash hashId = p_data.hashId(); - auto coll_data = std::make_unique<Collection>(hashId); - copyCollection(*p_data,coll_data.get()); - - if ( outputContainer->addCollection(coll_data.release(), p_data.hashId()).isFailure() ) { - parent->msg(MSG::WARNING) <<"add data Collection failed for output "<< p_data.hashId ()<<endmsg; //" collectionNo "<<collectionNo<<endmsg; - } - } - } - - /** Add data from the ovl container to the output one */ - typename IDC_Container::const_iterator p_ovl = mcContainer->begin(); - typename IDC_Container::const_iterator p_ovl_end = mcContainer->end(); - - for(; p_ovl != p_ovl_end; ++p_ovl) { - - IdentifierHash coll_id = p_ovl.hashId();//(*p_ovl)->identify(); - auto coll_ovl = std::make_unique<Collection>(coll_id); - copyCollection(*p_ovl,coll_ovl.get()); - - /** The newly created stuff will go to the output EventStore SG */ - auto coll_out = std::make_unique<Collection>(coll_id); - coll_out->setIdentifier((*p_ovl)->identify()); - - /** Look for the same ID in the main StoreGate EventStore */ - typename IDC_Container::const_iterator q = outputContainer->indexFind( coll_id ); - if( q != outputContainer->end() ) { - /**Need to merge the collections - Retrieve q */ - std::unique_ptr <Collection> coll_data ((Collection *) *q); - mergeCollectionsNew(coll_data.get(),coll_ovl.get(),coll_out.get(),parent); - - outputContainer->removeCollection(p_ovl.hashId()); - if (outputContainer->addCollection(coll_out.release(), p_ovl.hashId()).isFailure() ) { - parent->msg(MSG::WARNING) << "overlay addCollection failed " << endmsg; - } - } - else { - /** Copy the complete collection from ovl to output, - hopefully preserving the "most derived" type of its raw data */ - if ( outputContainer->addCollection(coll_ovl.release(), coll_id).isFailure() ) { - parent->msg(MSG::WARNING) << "add mc Collection failed " << endmsg; - } - } - } +template <class Collection, class Alg> +void mergeCollections(Collection *bkgCollection, + Collection *signalCollection, + Collection *outputCollection, + Alg *algorithm) +{ + if (bkgCollection->identify() != signalCollection->identify()) { + throw std::runtime_error("mergeCollections<>(): collection Id mismatch"); } - - //================================================================ - template<class IDC_Container, class OvlAlg> - void overlayContainer(const IDC_Container *dataContainer, - const IDC_Container *mcContainer, - IDC_Container *outputContainer, - OvlAlg *parent) - { - typedef typename IDC_Container::base_value_type Collection; - typedef typename Collection::base_value_type Datum; - - if(parent->msgLvl(MSG::DEBUG)) { parent->msg(MSG::DEBUG)<<"overlayContainer<>() begin"<<endmsg; } - - // The MC signal container should typically be smaller than - // dataContainer, because the latter contains all the noise, - // min bias and pile up. Thus we firstly copy data collection to the - // output and then merge with MC inputs. - - /** Add data from the data container to the output one */ - typename IDC_Container::const_iterator p_data = dataContainer->begin(); - typename IDC_Container::const_iterator p_data_end = dataContainer->end(); - - for(; p_data != p_data_end; ++p_data) { - IdentifierHash hashId = p_data.hashId(); - Identifier ident = p_data->identify(); - auto coll_data = std::make_unique<Collection>(ident, hashId); - - typename Collection::const_iterator firstData = p_data->begin(); - typename Collection::const_iterator lastData = p_data->end(); - for (; firstData != lastData; ++firstData) { - Datum* newData = new Datum (*(dynamic_cast<const Datum*>(*firstData))); - coll_data->push_back(newData); - } - - if ( outputContainer->addCollection(coll_data.release(), p_data.hashId()).isFailure() ) { - parent->msg(MSG::WARNING) <<"add data Collection failed for output "<< p_data.hashId()<<endmsg; + typedef typename Collection::base_value_type Datum; + typedef typename Collection::size_type size_type; + + // Merge by copying ptrs from background and signal to output collection + size_type ibkg = 0, isig = 0; + while ((ibkg < bkgCollection->size()) || (isig < signalCollection->size())) { + // The Datum that goes to the output at the end of this step. + Datum *tmp{}; + + if (isig == signalCollection->size()) { + // just copy the remaining background digits + bkgCollection->swapElement(ibkg++, nullptr, tmp); + } else if (ibkg == bkgCollection->size()) { + // just copy the remaining signal digits + signalCollection->swapElement(isig++, nullptr, tmp); + } else { + // Need to decide which one goes first. + // See comments in TRTDigitization.cxx about the assumption that id1<id2 + // <=> hash1<hash2 + if (signalCollection->at(isig)->identify() < bkgCollection->at(ibkg)->identify()) { + signalCollection->swapElement(isig++, nullptr, tmp); + } else if (bkgCollection->at(ibkg)->identify() < signalCollection->at(isig)->identify()) { + bkgCollection->swapElement(ibkg++, nullptr, tmp); + } else { + // The hits are on the same channel. + Datum *tmpBkg{}; + bkgCollection->swapElement(ibkg++, nullptr, tmpBkg); + signalCollection->swapElement(isig++, nullptr, tmp); + Overlay::mergeChannelData(*tmp, *tmpBkg, algorithm); + delete tmpBkg; } - } + } - /** Add data from the ovl container to the output one */ - typename IDC_Container::const_iterator p_ovl = mcContainer->begin(); - typename IDC_Container::const_iterator p_ovl_end = mcContainer->end(); - - for(; p_ovl != p_ovl_end; ++p_ovl) { - IdentifierHash coll_id = p_ovl.hashId();//(*p_ovl)->identify(); - Identifier elemId = p_ovl->identify(); - auto coll_ovl = std::make_unique<Collection>(elemId, coll_id); - - typename Collection::const_iterator firstData = p_ovl->begin(); - typename Collection::const_iterator lastData = p_ovl->end(); - for (; firstData != lastData; ++firstData) { - Datum* newData = new Datum (*(dynamic_cast<const Datum*>(*firstData))); - coll_ovl->push_back(newData); - } - - /** The newly created stuff will go to the output EventStore SG */ - auto coll_out = std::make_unique<Collection>(elemId, coll_id); - - /** Look for the same ID in the main StoreGate EventStore */ - typename IDC_Container::const_iterator q = outputContainer->indexFind(coll_id); - if( q != outputContainer->end() ) { - /** Need to merge the collections - Retrieve q */ - - std::unique_ptr <Collection> coll_data ((Collection *) *q); - parent->mergeCollections(coll_data.get(),coll_ovl.get(),coll_out.get()); - - outputContainer->removeCollection(p_ovl.hashId()); - if (outputContainer->addCollection(coll_out.release(), p_ovl.hashId()).isFailure() ) { - parent->msg(MSG::WARNING) << "overlay addCollection failed " << endmsg; - } - } - else { - /** Copy the complete collection from ovl to output, - hopefully preserving the "most derived" type of its raw data */ - if ( outputContainer->addCollection(coll_ovl.release(), coll_id).isFailure() ) { - parent->msg(MSG::WARNING) << "add mc Collection failed " << endmsg; - } - } - } - } + outputCollection->push_back(tmp); + } // <= while +} } // namespace Overlay - -//================================================================ diff --git a/InnerDetector/InDetRawAlgs/InDetOverlay/src/PixelOverlay.cxx b/InnerDetector/InDetRawAlgs/InDetOverlay/src/PixelOverlay.cxx index 2e53492529d2e5f113d6a3674930a9bf08348ddc..106215eecf669aaafb6e3e7991c16b59b970fea5 100644 --- a/InnerDetector/InDetRawAlgs/InDetOverlay/src/PixelOverlay.cxx +++ b/InnerDetector/InDetRawAlgs/InDetOverlay/src/PixelOverlay.cxx @@ -11,21 +11,31 @@ namespace Overlay { + // Specialize mergeChannelData() for the Pixel + template <> + void mergeChannelData(PixelRDORawData &/* baseDatum */, + const PixelRDORawData &/* additionalDatum */, + IDC_OverlayBase *algorithm) + { + algorithm->msg(MSG::WARNING) << "Overlay::mergeChannelData<PixelRDORawData>(): " + << "Merging of data on the same channel is not implemented for PixelRDORawData" << endmsg; + } + // Specialize copyCollection() for the Pixel template<> - void copyCollection(const InDetRawDataCollection<PixelRDORawData> *input_coll, - InDetRawDataCollection<PixelRDORawData> *copy_coll) + std::unique_ptr<PixelRDO_Collection> copyCollection(const IdentifierHash &hashId, + const PixelRDO_Collection *collection) { - copy_coll->setIdentifier(input_coll->identify()); - InDetRawDataCollection<PixelRDORawData>::const_iterator firstData = input_coll->begin(); - InDetRawDataCollection<PixelRDORawData>::const_iterator lastData = input_coll->end(); - for ( ; firstData != lastData; ++firstData) - { - const Identifier ident = (*firstData)->identify(); - const unsigned int word = (*firstData)->getWord(); - Pixel1RawData *newData = new Pixel1RawData(ident, word); - copy_coll->push_back(newData); + auto outputCollection = std::make_unique<PixelRDO_Collection>(hashId); + outputCollection->setIdentifier(collection->identify()); + + for (const PixelRDORawData *existingDatum : *collection) { + // Owned by the collection + auto *datumCopy = new Pixel1RawData(existingDatum->identify(), existingDatum->getWord()); + outputCollection->push_back(datumCopy); } + + return outputCollection; } } // namespace Overlay @@ -86,13 +96,14 @@ StatusCode PixelOverlay::execute() // Creating output RDO container SG::WriteHandle<PixelRDO_Container> outputContainer(m_outputKey); ATH_CHECK(outputContainer.record(std::make_unique<PixelRDO_Container>(signalContainer->size()))); + if (!outputContainer.isValid()) { + ATH_MSG_ERROR("Could not record output Pixel RDO container " << outputContainer.name() << " to store " << outputContainer.store()); + return StatusCode::FAILURE; + } ATH_MSG_DEBUG("Recorded output Pixel RDO container " << outputContainer.name() << " in store " << outputContainer.store()); - if (outputContainer.isValid()) { - overlayContainerNew(bkgContainerPtr, signalContainer.cptr(), outputContainer.ptr()); - - ATH_MSG_DEBUG("Pixel Result = " << Overlay::debugPrint(outputContainer.ptr())); - } + ATH_CHECK(overlayContainer(bkgContainerPtr, signalContainer.cptr(), outputContainer.ptr())); + ATH_MSG_DEBUG("Pixel Result = " << Overlay::debugPrint(outputContainer.ptr())); ATH_MSG_DEBUG("execute() end"); return StatusCode::SUCCESS; diff --git a/InnerDetector/InDetRawAlgs/InDetOverlay/src/SCTOverlay.cxx b/InnerDetector/InDetRawAlgs/InDetOverlay/src/SCTOverlay.cxx index 23d205751588fcb219d2b97c3462b32d9eceaaa4..a239f2d055af0ed0093188364b85be39faa8d9bb 100644 --- a/InnerDetector/InDetRawAlgs/InDetOverlay/src/SCTOverlay.cxx +++ b/InnerDetector/InDetRawAlgs/InDetOverlay/src/SCTOverlay.cxx @@ -14,46 +14,35 @@ namespace Overlay { // Specialize copyCollection() for the SCT template<> - void copyCollection(const InDetRawDataCollection<SCT_RDORawData> *input_coll, - InDetRawDataCollection<SCT_RDORawData> *copy_coll) - { - copy_coll->setIdentifier(input_coll->identify()); - InDetRawDataCollection<SCT_RDORawData>::const_iterator firstData = input_coll->begin(); - InDetRawDataCollection<SCT_RDORawData>::const_iterator lastData = input_coll->end(); - for ( ; firstData != lastData; ++firstData) - { - const Identifier ident = (*firstData)->identify(); - const unsigned int word = (*firstData)->getWord(); - const SCT3_RawData* oldData = dynamic_cast<const SCT3_RawData*>(*firstData); - std::vector<int> errorHit=oldData->getErrorCondensedHit(); - SCT3_RawData *newData=new SCT3_RawData(ident, word, &errorHit); - copy_coll->push_back(newData); + std::unique_ptr<SCT_RDO_Collection> copyCollection(const IdentifierHash &hashId, + const SCT_RDO_Collection *collection) + { + auto outputCollection = std::make_unique<SCT_RDO_Collection>(hashId); + outputCollection->setIdentifier(collection->identify()); + + for (const SCT_RDORawData *existingDatum : *collection) { + auto *oldDatum = dynamic_cast<const SCT3_RawData *>(existingDatum); + // Owned by the collection + auto *datumCopy = new SCT3_RawData(oldDatum->identify(), + oldDatum->getWord(), + &oldDatum->getErrorCondensedHit()); + outputCollection->push_back(datumCopy); } + + return outputCollection; } - // Specialize mergeCollectionsNew() for the SCT - template<> void mergeCollectionsNew(InDetRawDataCollection<SCT_RDORawData> *bkgCollection, - InDetRawDataCollection<SCT_RDORawData> *signalCollection, - InDetRawDataCollection<SCT_RDORawData> *outputCollection, - IDC_OverlayBase *tmp) + // Specialize mergeCollections() for the SCT + template<> + void mergeCollections(SCT_RDO_Collection *bkgCollection, + SCT_RDO_Collection *signalCollection, + SCT_RDO_Collection *outputCollection, + IDC_OverlayBase *algorithm) { // We want to use the SCT_ID helper provided by SCTOverlay, thus the constraint - SCTOverlay *parent = dynamic_cast<SCTOverlay*>(tmp); + SCTOverlay *parent = dynamic_cast<SCTOverlay *>(algorithm); if (!parent) { - std::ostringstream os; - os << "mergeCollectionsNew<SCT_RDORawData>() called by a wrong parent algorithm? Must be SCTOverlay."; - throw std::runtime_error(os.str()); - } - - // ---------------------------------------------------------------- - // debug - static bool first_time = true; - if (first_time) { - first_time = false; - parent->msg(MSG::INFO) << "SCTOverlay::mergeCollectionsNew(): " - << " SCT specific code is called for " - << typeid(*bkgCollection).name() - << endmsg; + throw std::runtime_error("mergeCollections<SCT_RDORawData>() called by a wrong parent algorithm? Must be SCTOverlay."); } // ---------------------------------------------------------------- @@ -74,39 +63,25 @@ namespace Overlay // // http://alxr.usatlas.bnl.gov/lxr/source/atlas/InnerDetector/InDetRecTools/SiClusterizationTool/src/SCT_ClusteringTool.cxx - - // ---------------------------------------------------------------- if (bkgCollection->identify() != signalCollection->identify()) { - std::ostringstream os; - os << "mergeCollectionsNew<SCT_RDORawData>(): collection Id mismatch"; - parent->msg(MSG::FATAL) << os.str() << endmsg; - throw std::runtime_error(os.str()); + throw std::runtime_error("mergeCollections<SCT_RDO_Collection>(): collection Id mismatch"); } const Identifier idColl = parent->get_sct_id()->wafer_id(signalCollection->identifyHash()); - // Empty the input collections and move RDOs to local vectors. - InDetRawDataCollection<SCT_RDORawData> bkg(bkgCollection->identifyHash()); - bkg.setIdentifier(idColl); - bkgCollection->swap(bkg); - - InDetRawDataCollection<SCT_RDORawData> sig(signalCollection->identifyHash()); - sig.setIdentifier(idColl); - signalCollection->swap(sig); - // Strip hit timing information for Next, Current, Previous and Any BCs // Prepare one more strip to create the last one. The additional strip has no hits. std::bitset<SCTOverlay::NumberOfStrips+1> stripInfo[SCTOverlay::NumberOfBitSets]; // Process background and signal in the wafer for (unsigned source = SCTOverlay::BkgSource; source < SCTOverlay::NumberOfSources; source++) { - InDetRawDataCollection<SCT_RDORawData>::const_iterator rdo; - InDetRawDataCollection<SCT_RDORawData>::const_iterator rdoEnd; + SCT_RDO_Collection::const_iterator rdo; + SCT_RDO_Collection::const_iterator rdoEnd; if (source == SCTOverlay::BkgSource) { // background - rdo = bkg.begin(); - rdoEnd = bkg.end(); + rdo = bkgCollection->begin(); + rdoEnd = bkgCollection->end(); } else { // signal - rdo = sig.begin(); - rdoEnd = sig.end(); + rdo = signalCollection->begin(); + rdoEnd = signalCollection->end(); } // Loop over all RDOs in the wafer for (; rdo!=rdoEnd; ++rdo) { @@ -114,7 +89,7 @@ namespace Overlay if (!rdo3) { std::ostringstream os; const auto& elt = **rdo; - os << "mergeCollectionNew<SCT_RDORawData>(): wrong datum format. Only SCT3_RawData are produced by SCT_RodDecoder and supported by overlay." + os << "mergeCollection<SCT_RDO_Collection>(): wrong datum format. Only SCT3_RawData are produced by SCT_RodDecoder and supported by overlay." << "For the supplied datum typeid(datum).name() = " << typeid(elt).name(); throw std::runtime_error(os.str()); } @@ -175,7 +150,7 @@ namespace Overlay } } } - } // mergeCollectionsNew() + } // mergeCollections() } // namespace Overlay @@ -241,13 +216,14 @@ StatusCode SCTOverlay::execute() // Creating output RDO container SG::WriteHandle<SCT_RDO_Container> outputContainer(m_outputKey); ATH_CHECK(outputContainer.record(std::make_unique<SCT_RDO_Container>(signalContainer->size()))); + if (!outputContainer.isValid()) { + ATH_MSG_ERROR("Could not record output SCT RDO container " << outputContainer.name() << " to store " << outputContainer.store()); + return StatusCode::FAILURE; + } ATH_MSG_DEBUG("Recorded output SCT RDO container " << outputContainer.name() << " in store " << outputContainer.store()); - if (outputContainer.isValid()) { - overlayContainerNew(bkgContainerPtr, signalContainer.cptr(), outputContainer.ptr()); - - ATH_MSG_DEBUG("SCT Result = " << Overlay::debugPrint(outputContainer.ptr(), 50)); - } + ATH_CHECK(overlayContainer(bkgContainerPtr, signalContainer.cptr(), outputContainer.ptr())); + ATH_MSG_DEBUG("SCT Result = " << Overlay::debugPrint(outputContainer.ptr(), 50)); ATH_MSG_DEBUG("execute() end"); return StatusCode::SUCCESS; diff --git a/InnerDetector/InDetRawAlgs/InDetOverlay/src/TRTOverlay.cxx b/InnerDetector/InDetRawAlgs/InDetOverlay/src/TRTOverlay.cxx index 4e15da8f192e79371390116d15a7d85f028634e6..38d74e08d097b5f77b836f48dd90d4d453ce98f8 100644 --- a/InnerDetector/InDetRawAlgs/InDetOverlay/src/TRTOverlay.cxx +++ b/InnerDetector/InDetRawAlgs/InDetOverlay/src/TRTOverlay.cxx @@ -22,20 +22,10 @@ namespace Overlay { // Specialize mergeChannelData() for the TRT - template<> void mergeChannelData(TRT_RDORawData &r1, const TRT_RDORawData &r2, IDC_OverlayBase *parent) + template<> void mergeChannelData(TRT_RDORawData &r1, + const TRT_RDORawData &r2, + TRTOverlay *) { - - // ---------------------------------------------------------------- - // debug - static bool first_time = true; - if (first_time) { - first_time = false; - parent->msg(MSG::INFO) << "Overlay::mergeChannelData(): " - << "TRT specific code is called for " - << typeid(TRT_RDORawData).name() - << endmsg; - } - // ---------------------------------------------------------------- // FIXME: That should really be a call to r1.merge(r2); @@ -49,18 +39,24 @@ namespace Overlay } // mergeChannelData() // Specialize copyCollection() for the TRT - template<> void copyCollection(const InDetRawDataCollection<TRT_RDORawData> *input_coll, InDetRawDataCollection<TRT_RDORawData> *copy_coll) + template<> + std::unique_ptr<TRT_RDO_Collection> copyCollection(const IdentifierHash &hashId, + const TRT_RDO_Collection *collection) { - copy_coll->setIdentifier(input_coll->identify()); - InDetRawDataCollection<TRT_RDORawData>::const_iterator firstData = input_coll->begin(); - InDetRawDataCollection<TRT_RDORawData>::const_iterator lastData = input_coll->end(); - for ( ; firstData != lastData; ++firstData) - { - const Identifier ident = (*firstData)->identify(); - const unsigned int word = (*firstData)->getWord(); - TRT_LoLumRawData *newData = new TRT_LoLumRawData(ident, word); - copy_coll->push_back(newData); + auto outputCollection = std::make_unique<TRT_RDO_Collection>(hashId); + if (!collection) { + return outputCollection; } + + outputCollection->setIdentifier(collection->identify()); + + for (const TRT_RDORawData *existingDatum : *collection) { + // Owned by the collection + auto *datumCopy = new TRT_LoLumRawData(existingDatum->identify(), existingDatum->getWord()); + outputCollection->push_back(datumCopy); + } + + return outputCollection; } } // namespace Overlay @@ -166,7 +162,7 @@ StatusCode TRTOverlay::execute() { //Merge containers overlayTRTContainers(bkgContainerPtr, signalContainer.cptr(), outputContainer.ptr(), occupancy, *signalSDOContainer); } else { - overlayContainerNew(bkgContainerPtr, signalContainer.cptr(), outputContainer.ptr()); + ATH_CHECK(overlayContainer(bkgContainerPtr, signalContainer.cptr(), outputContainer.ptr())); } ATH_MSG_DEBUG("TRT Result = " << Overlay::debugPrint(outputContainer.ptr())); @@ -189,8 +185,7 @@ void TRTOverlay::overlayTRTContainers(const TRT_RDO_Container *bkgContainer, for(; p_bkg != p_bkg_end; ++p_bkg) { IdentifierHash hashId = p_bkg.hashId(); - auto coll_bkg = std::make_unique<TRT_RDO_Collection>(hashId); - Overlay::copyCollection(*p_bkg, coll_bkg.get()); + auto coll_bkg = Overlay::copyCollection(hashId, *p_bkg); if (outputContainer->addCollection(coll_bkg.release(), p_bkg.hashId() ).isFailure()) { ATH_MSG_WARNING("add background Collection failed for output " << p_bkg.hashId()); @@ -209,8 +204,7 @@ void TRTOverlay::overlayTRTContainers(const TRT_RDO_Container *bkgContainer, for (; p_signal != p_signal_end; ++p_signal) { IdentifierHash coll_id = p_signal.hashId(); - auto coll_signal = std::make_unique<TRT_RDO_Collection>(coll_id); - Overlay::copyCollection( *p_signal, coll_signal.get() ) ; + auto coll_signal = Overlay::copyCollection( coll_id, *p_signal ) ; /** The newly created stuff will go to the output EventStore SG */ auto coll_out = std::make_unique<TRT_RDO_Collection>(coll_id); diff --git a/InnerDetector/InDetRawAlgs/InDetOverlay/test/PixelOverlay_test.cxx b/InnerDetector/InDetRawAlgs/InDetOverlay/test/PixelOverlay_test.cxx index 91161d7edb11ca2d4e7af5b3b9fade0ab8f6e236..1a42456d21099378e2d8ed4bf6779ac75149ce0f 100644 --- a/InnerDetector/InDetRawAlgs/InDetOverlay/test/PixelOverlay_test.cxx +++ b/InnerDetector/InDetRawAlgs/InDetOverlay/test/PixelOverlay_test.cxx @@ -378,8 +378,8 @@ namespace OverlayTesting { ASSERT_TRUE( outputCollection->size()==1 ); const PixelRDORawData* outputDigit1 = outputCollection->at(0); ASSERT_TRUE( outputDigit1!=nullptr ); - ASSERT_TRUE( outputDigit1->getToT()==bkgToT ); // Bkg RDO taken in case of matching Identifiers - ASSERT_TRUE( outputDigit1->getBCID()==bkgBCID-1 ); // Bkg RDO taken in case of matching Identifiers + ASSERT_TRUE( outputDigit1->getToT()==sigToT ); // Signal RDO taken in case of matching Identifiers + ASSERT_TRUE( outputDigit1->getBCID()==sigBCID-1 ); // Signal RDO taken in case of matching Identifiers } TEST_F(PixelOverlay_test, two_RDOs_with_matching_id_bkg_first) { @@ -424,8 +424,8 @@ namespace OverlayTesting { ASSERT_TRUE( outputCollection->size()==1 ); const PixelRDORawData* outputDigit1 = outputCollection->at(0); ASSERT_TRUE( outputDigit1!=nullptr ); - ASSERT_TRUE( outputDigit1->getToT()==bkgToT ); // Bkg RDO taken in case of matching Identifiers - ASSERT_TRUE( outputDigit1->getBCID()==bkgBCID-1 ); // Bkg RDO taken in case of matching Identifiers + ASSERT_TRUE( outputDigit1->getToT()==sigToT ); // Signal RDO taken in case of matching Identifiers + ASSERT_TRUE( outputDigit1->getBCID()==sigBCID-1 ); // Signal RDO taken in case of matching Identifiers } TEST_F(PixelOverlay_test, containers_with_matching_collections_one_different_RDO_each_v2) { diff --git a/MuonSpectrometer/MuonOverlay/MdtOverlay/MdtOverlay/MdtOverlay.h b/MuonSpectrometer/MuonOverlay/MdtOverlay/MdtOverlay/MdtOverlay.h index 5c9753beec3abc952282b7cd04eabfb4d7bfbbe9..b5909d1cc3214046ce75697141bd2d4e69abac5e 100644 --- a/MuonSpectrometer/MuonOverlay/MdtOverlay/MdtOverlay/MdtOverlay.h +++ b/MuonSpectrometer/MuonOverlay/MdtOverlay/MdtOverlay/MdtOverlay.h @@ -7,9 +7,7 @@ // Overlaying MdtDigits from two different events for MDT subdetectors. // // Andrei Gaponenko <agaponenko@lbl.gov>, 2006, 2007 - // Ketevi A. Assamagan <ketevi@bnl.gov>, March 2008 - // Piyali Banerjee <Piyali.Banerjee@cern.ch>, March 2011 #ifndef MDTOVERLAY_H @@ -17,35 +15,27 @@ #include <string> -#include "MuonOverlayBase/MuonOverlayBase.h" -#include "MuonDigitContainer/MdtDigitContainer.h" - -class MdtOverlay : public MuonOverlayBase { +#include <MuonOverlayBase/IDC_MuonOverlayBase.h> +#include <MuonDigitContainer/MdtDigitContainer.h> +class MdtOverlay : public IDC_MuonOverlayBase +{ public: - MdtOverlay(const std::string &name,ISvcLocator *pSvcLocator); - /** Framework implemenrtation for the event loop */ - virtual StatusCode overlayInitialize(); - virtual StatusCode overlayExecute(); - virtual StatusCode overlayFinalize(); + virtual StatusCode initialize() override final; + virtual StatusCode execute() override final; - float adcIntegrationWindow() const { return m_adcIntegrationWindow; } + float adcIntegrationWindow() const { return m_adcIntegrationWindow.value(); } private: - // ---------------------------------------------------------------- - - // jO controllable properties. - // "Main" containers are read, have data from "overlay" containers added, - // and written out with the original SG keys. - SG::ReadHandleKey<MdtDigitContainer> m_mainInputDigitKey{this,"MainInputDigitKey","OriginalEvent_SG+MDT_DIGITS","ReadHandleKey for Main Input MdtDigitContainer"}; - SG::ReadHandleKey<MdtDigitContainer> m_overlayInputDigitKey{this,"OverlayInputDigitKey","BkgEvent_0_SG+MDT_DIGITS","ReadHandleKey for Overlay Input MdtDigitContainer"}; - SG::WriteHandleKey<MdtDigitContainer> m_outputDigitKey{this,"OutputDigitKey","StoreGateSvc+MDT_DIGITS","WriteHandleKey for Output MdtDigitContainer"}; - - float m_adcIntegrationWindow{20.0}; // in ns - bool m_clean_overlay_data{false}; - bool m_clean_overlay_signal{false}; + SG::ReadHandleKey<MdtDigitContainer> m_bkgInputKey{this, "BkgInputKey", "OriginalEvent_SG+MDT_DIGITS", "ReadHandleKey for Background Input MdtDigitContainer"}; + SG::ReadHandleKey<MdtDigitContainer> m_signalInputKey{this, "SignalInputKey", "BkgEvent_0_SG+MDT_DIGITS", "ReadHandleKey for Signal Input MdtDigitContainer"}; + SG::WriteHandleKey<MdtDigitContainer> m_outputKey{this, "OutputKey", "StoreGateSvc+MDT_DIGITS", "WriteHandleKey for Output MdtDigitContainer"}; + + BooleanProperty m_includeBkg { this, "includeBkg", true, "Include Background RDO Container" }; + FloatProperty m_adcIntegrationWindow { this, "IntegrationWindow", 20.0, "ADC Integration Window" }; + }; #endif/* MDTOVERLAY_H */ diff --git a/MuonSpectrometer/MuonOverlay/MdtOverlay/python/MdtOverlayConfig.py b/MuonSpectrometer/MuonOverlay/MdtOverlay/python/MdtOverlayConfig.py index ed8d3fd6983a7290eacaddce2e62219bfa0d5419..4a83973ea5d4b084d1da90613623836196d3d3fe 100644 --- a/MuonSpectrometer/MuonOverlay/MdtOverlay/python/MdtOverlayConfig.py +++ b/MuonSpectrometer/MuonOverlay/MdtOverlay/python/MdtOverlayConfig.py @@ -1,13 +1,14 @@ -# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration from AthenaCommon import CfgMgr def getMdtOverlay(name="MdtOverlay", **kwargs): from OverlayCommonAlgs.OverlayFlags import overlayFlags - kwargs.setdefault("MainInputDigitKey",overlayFlags.dataStore()+"+MDT_DIGITS") - kwargs.setdefault("OverlayInputDigitKey",overlayFlags.evtStore()+"+MDT_DIGITS") - kwargs.setdefault("OutputDigitKey",overlayFlags.outputStore()+"+MDT_DIGITS") + + kwargs.setdefault("BkgInputKey", overlayFlags.dataStore() + "+MDT_DIGITS") + kwargs.setdefault("SignalInputKey", overlayFlags.evtStore() + "+MDT_DIGITS") + kwargs.setdefault("OutputKey", overlayFlags.outputStore() + "+MDT_DIGITS") + kwargs.setdefault("IntegrationWindow", 20) # in ns - kwargs.setdefault("MCStore",overlayFlags.evtStore()) - kwargs.setdefault("DataStore", overlayFlags.dataStore()) + return CfgMgr.MdtOverlay(name, **kwargs) diff --git a/MuonSpectrometer/MuonOverlay/MdtOverlay/src/MdtOverlay.cxx b/MuonSpectrometer/MuonOverlay/MdtOverlay/src/MdtOverlay.cxx index 68d1317bac2d4045e22fcd1cf3fdb60343a76e49..44806dc8a710f314ef44570fbe3e6cd796aa3e55 100644 --- a/MuonSpectrometer/MuonOverlay/MdtOverlay/src/MdtOverlay.cxx +++ b/MuonSpectrometer/MuonOverlay/MdtOverlay/src/MdtOverlay.cxx @@ -3,162 +3,132 @@ */ // Andrei Gaponenko <agaponenko@lbl.gov>, 2006, 2007 - // Ketevi A. Assamagan <ketevi@bnl.gov>, March 2008 - // Piyali Banerjee <Piyali.Banerjee@cern.ch>, March 2011 -#include "MdtOverlay/MdtOverlay.h" +#include <MdtOverlay/MdtOverlay.h> -#include "StoreGate/StoreGateSvc.h" -#include "StoreGate/DataHandle.h" -#include "StoreGate/ReadHandle.h" -#include "StoreGate/WriteHandle.h" +#include <StoreGate/ReadHandle.h> +#include <StoreGate/WriteHandle.h> -#include "MuonDigitContainer/MdtDigitContainer.h" +#include <IDC_OverlayBase/IDC_OverlayHelpers.h> -#include <iostream> -#include <typeinfo> -#include <stdexcept> //================================================================ -namespace Overlay { +namespace Overlay +{ /** template specialization function to add 2 MDT Digits - basically the operator+= * A declaration of the specialization must happen before the template is used from * the overlayContainer() method. So we just put this implementation at the beginning * of this file. */ - template<> void mergeChannelData(MdtDigit& mainDigit, const MdtDigit& ovlDigit, IDC_OverlayBase *baseParent) { - MdtOverlay* parent = dynamic_cast<MdtOverlay*>(baseParent); - if(!parent) { - throw std::runtime_error("Overlay::mergeChannelData<MdtDigit>(): ERROR: calling alg is not MdtOverlay."); + template<> + void mergeChannelData(MdtDigit& signalDigit, + const MdtDigit& bkgDigit, + IDC_MuonOverlayBase *algorithm) + { + // We want to use the integration window provided by MdtOverlay, thus the constraint + MdtOverlay *parent = dynamic_cast<MdtOverlay *>(algorithm); + if (!parent) { + throw std::runtime_error("mergeChannelData<MdtDigit>() called by a wrong parent algorithm? Must be MdtOverlay."); } - // ---------------------------------------------------------------- - // confirm that the specialization is being used by printing out... - static bool first_time = true; - if(first_time) { - first_time = false; - parent->msg(MSG::INFO)<<"Overlay::mergeChannelData<MdtDigit>(): " - <<"MDT specific code is called for " - <<typeid(MdtDigit).name() - <<endmsg; - } + int sig_tdc = signalDigit.tdc(); + int bkg_tdc = bkgDigit.tdc(); - // ---------------------------------------------------------------- - // the real merging happens here - int main_tdc = mainDigit.tdc(); - int ovl_tdc = ovlDigit.tdc(); - - /** background masks Physics hit - no correction to the ADC - FIXME: Probably should return the maksed hit as well */ - if ( abs(main_tdc-ovl_tdc) > parent->adcIntegrationWindow() && main_tdc < ovl_tdc ) { - // do nothing - keep mainDigit. + /** signal masks the background - no correction to the ADC + FIXME: Probably should return the masked hit as well */ + if ( abs(sig_tdc - bkg_tdc) > parent->adcIntegrationWindow() && sig_tdc < bkg_tdc ) { + // do nothing - keep baseDigit. } /** Physics hit masks the background hit - no correct to the AOD FIXME: Probably should return the masked hit as well */ - else if ( abs(main_tdc-ovl_tdc) > parent->adcIntegrationWindow() && main_tdc > ovl_tdc ) { - // Use ovlDigit as the final answer - mainDigit = ovlDigit; + else if ( abs(sig_tdc - bkg_tdc) > parent->adcIntegrationWindow() && sig_tdc > bkg_tdc ) { + // Use the background digit as the final answer + signalDigit = bkgDigit; } /** the 2 hits overlap withing the ADC integration window the ADC will add partially the TDC is from the first hit that crosses the threshold FIXME: how to add partially for correct - for now just add the ADD total */ - else if ( abs(main_tdc-ovl_tdc) < parent->adcIntegrationWindow() ) { - int tdc = std::min( mainDigit.tdc(), ovlDigit.tdc() ); - int adc = mainDigit.adc() + ovlDigit.adc(); - mainDigit = MdtDigit(mainDigit.identify(), tdc, adc ); + else if ( abs(sig_tdc - bkg_tdc) < parent->adcIntegrationWindow() ) { + int tdc = std::min( signalDigit.tdc(), bkgDigit.tdc() ); + int adc = signalDigit.adc() + bkgDigit.adc(); + signalDigit = MdtDigit(signalDigit.identify(), tdc, adc); } } +} // namespace Overlay -} //================================================================ -MdtOverlay::MdtOverlay(const std::string &name, ISvcLocator *pSvcLocator) : - MuonOverlayBase(name, pSvcLocator) +MdtOverlay::MdtOverlay(const std::string &name, ISvcLocator *pSvcLocator) + : IDC_MuonOverlayBase(name, pSvcLocator) { - - /** modifiable properties in job options */ - declareProperty("IntegrationWindow", m_adcIntegrationWindow); // in ns - declareProperty("CleanOverlayData", m_clean_overlay_data);//clean out the overlay data before doing overlay, so you only get MC hits in the output overlay - declareProperty("CleanOverlaySignal", m_clean_overlay_signal);//clean out the signal MC before doing overlay } //================================================================ -StatusCode MdtOverlay::overlayInitialize() +StatusCode MdtOverlay::initialize() { - ATH_MSG_INFO("MdtOverlay initialized"); + ATH_MSG_DEBUG("Initializing..."); - ATH_CHECK(m_mainInputDigitKey.initialize()); - ATH_MSG_VERBOSE("Initialized ReadHandleKey: " << m_mainInputDigitKey ); - ATH_CHECK(m_overlayInputDigitKey.initialize()); - ATH_MSG_VERBOSE("Initialized ReadHandleKey: " << m_overlayInputDigitKey ); - ATH_CHECK(m_outputDigitKey.initialize()); - ATH_MSG_VERBOSE("Initialized WriteHandleKey: " << m_outputDigitKey ); + if (!m_includeBkg) { + ATH_MSG_DEBUG("Disabling use of background RDOs..."); + ATH_CHECK( m_bkgInputKey.assign("") ); + } - return StatusCode::SUCCESS; -} + // Check and initialize keys + ATH_CHECK( m_bkgInputKey.initialize(!m_bkgInputKey.key().empty()) ); + ATH_MSG_VERBOSE("Initialized ReadHandleKey: " << m_bkgInputKey ); + ATH_CHECK(m_signalInputKey.initialize()); + ATH_MSG_VERBOSE("Initialized ReadHandleKey: " << m_signalInputKey ); + ATH_CHECK(m_outputKey.initialize()); + ATH_MSG_VERBOSE("Initialized WriteHandleKey: " << m_outputKey ); -//================================================================ -StatusCode MdtOverlay::overlayFinalize() -{ - ATH_MSG_INFO("MdtOverlay finalized"); return StatusCode::SUCCESS; } //================================================================ -StatusCode MdtOverlay::overlayExecute() { - ATH_MSG_DEBUG("MdtOverlay::execute() begin"); +StatusCode MdtOverlay::execute() { + ATH_MSG_DEBUG("execute() begin"); - //---------------------------------------------------------------- - ATH_MSG_VERBOSE("Retrieving data input MDT container"); - SG::ReadHandle<MdtDigitContainer> dataContainer (m_mainInputDigitKey); - if (!dataContainer.isValid()) { - ATH_MSG_ERROR("Could not get data MDT container " << dataContainer.name() << " from store " << dataContainer.store()); - return StatusCode::FAILURE; + const MdtDigitContainer *bkgContainerPtr = nullptr; + if (m_includeBkg) { + SG::ReadHandle<MdtDigitContainer> bkgContainer (m_bkgInputKey); + if (!bkgContainer.isValid()) { + ATH_MSG_ERROR("Could not get background MDT container " << bkgContainer.name() << " from store " << bkgContainer.store()); + return StatusCode::FAILURE; + } + bkgContainerPtr = bkgContainer.cptr(); + + ATH_MSG_DEBUG("Found background MdtDigitContainer called " << bkgContainer.name() << " in store " << bkgContainer.store()); + ATH_MSG_DEBUG("MDT Background = " << Overlay::debugPrint(bkgContainer.cptr())); + ATH_MSG_VERBOSE("MDT background has digit_size " << bkgContainer->digit_size()); } - ATH_MSG_DEBUG("Found data MdtDigitContainer called " << dataContainer.name() << " in store " << dataContainer.store()); - ATH_MSG_INFO("MDT Data = "<<shortPrint(dataContainer.cptr())); - ATH_MSG_VERBOSE("Retrieving MC input MDT container"); - SG::ReadHandle<MdtDigitContainer> mcContainer(m_overlayInputDigitKey); - if(!mcContainer.isValid() ) { - ATH_MSG_ERROR("Could not get overlay MDT container " << mcContainer.name() << " from store " << mcContainer.store()); + SG::ReadHandle<MdtDigitContainer> signalContainer(m_signalInputKey); + if(!signalContainer.isValid() ) { + ATH_MSG_ERROR("Could not get signal MDT container " << signalContainer.name() << " from store " << signalContainer.store()); + return StatusCode::FAILURE; + } + ATH_MSG_DEBUG("Found signal MdtDigitContainer called " << signalContainer.name() << " in store " << signalContainer.store()); + ATH_MSG_DEBUG("MDT Signal = " << Overlay::debugPrint(signalContainer.cptr())); + ATH_MSG_VERBOSE("MDT signal has digit_size " << signalContainer->digit_size()); + + SG::WriteHandle<MdtDigitContainer> outputContainer(m_outputKey); + ATH_CHECK(outputContainer.record(std::make_unique<MdtDigitContainer>(signalContainer->size()))); + if (!outputContainer.isValid()) { + ATH_MSG_ERROR("Could not record output MdtDigitContainer called " << outputContainer.name() << " to store " << outputContainer.store()); return StatusCode::FAILURE; } - ATH_MSG_DEBUG("Found overlay MdtDigitContainer called " << mcContainer.name() << " in store " << mcContainer.store()); - ATH_MSG_INFO("MDT MC = "<<shortPrint(mcContainer.cptr())); - - ATH_MSG_VERBOSE("MDT data has digit_size "<<dataContainer->digit_size()); - - ATH_MSG_VERBOSE("MDT signal data has digit_size "<<mcContainer->digit_size()); - - SG::WriteHandle<MdtDigitContainer> outputContainer(m_outputDigitKey); - ATH_CHECK(outputContainer.record(std::make_unique<MdtDigitContainer>(dataContainer->size()))); ATH_MSG_DEBUG("Recorded output MdtDigitContainer called " << outputContainer.name() << " in store " << outputContainer.store()); - if(dataContainer.isValid() && mcContainer.isValid() && outputContainer.isValid()) { - if(!m_clean_overlay_data && !m_clean_overlay_signal){ - //Do the actual overlay - this->overlayContainer(dataContainer.cptr(), mcContainer.cptr(), outputContainer.ptr()); - } - else if (m_clean_overlay_data) { - MdtDigitContainer nobkg(0); - this->overlayContainer(&nobkg , mcContainer.cptr() , outputContainer.ptr()); - } - else if (m_clean_overlay_signal) { - MdtDigitContainer nomc(0); - this->overlayContainer(dataContainer.cptr(), &nomc , outputContainer.ptr()); - } - } - ATH_MSG_INFO("MDT Result = "<<shortPrint(outputContainer.cptr())); + // Do the actual overlay + ATH_CHECK(overlayContainer(bkgContainerPtr, signalContainer.cptr(), outputContainer.ptr())); + ATH_MSG_DEBUG("MDT Result = " << Overlay::debugPrint(outputContainer.cptr())); - //---------------------------------------------------------------- - ATH_MSG_DEBUG("MdtOverlay::execute() end"); + + ATH_MSG_DEBUG("execute() end"); return StatusCode::SUCCESS; } - -//================================================================ diff --git a/MuonSpectrometer/MuonOverlay/MdtOverlay/test/MdtOverlay_test.cxx b/MuonSpectrometer/MuonOverlay/MdtOverlay/test/MdtOverlay_test.cxx index 8f26e331ad52e2045177cee6b70eef21b4658794..60838f8adb3fceb70528b652523800c4821850be 100644 --- a/MuonSpectrometer/MuonOverlay/MdtOverlay/test/MdtOverlay_test.cxx +++ b/MuonSpectrometer/MuonOverlay/MdtOverlay/test/MdtOverlay_test.cxx @@ -53,11 +53,11 @@ namespace OverlayTesting { std::string inputSigPropertyValue = "'StoreGateSvc+MDT_DIGITS_SIG'"; std::string inputBkgPropertyValue = "'StoreGateSvc+MDT_DIGITS_BKG'"; std::string outputPropertyValue = "'StoreGateSvc+MDT_DIGITS'"; - ASSERT_TRUE( m_alg->setProperty( "MainInputDigitKey", inputSigPropertyValue).isSuccess() ); - ASSERT_TRUE( m_alg->setProperty( "OverlayInputDigitKey", inputBkgPropertyValue).isSuccess() ); - ASSERT_TRUE( m_alg->setProperty( "OutputDigitKey", outputPropertyValue).isSuccess() ); - ASSERT_TRUE( m_alg->overlayInitialize().isSuccess() ); - ASSERT_TRUE( m_alg->overlayExecute().isFailure() ); //inputs don't exist + ASSERT_TRUE( m_alg->setProperty( "BkgInputKey", inputBkgPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "SignalInputKey", inputSigPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "OutputKey", outputPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->initialize().isSuccess() ); + ASSERT_TRUE( m_alg->execute().isFailure() ); //inputs don't exist } TEST_F(MdtOverlay_test, empty_containers_alg_execute) { @@ -71,11 +71,11 @@ namespace OverlayTesting { std::string inputSigPropertyValue = "'StoreGateSvc+MDT_DIGITS_SIG'"; std::string inputBkgPropertyValue = "'StoreGateSvc+MDT_DIGITS_BKG'"; std::string outputPropertyValue = "'StoreGateSvc+MDT_DIGITS'"; - ASSERT_TRUE( m_alg->setProperty( "MainInputDigitKey", inputSigPropertyValue).isSuccess() ); - ASSERT_TRUE( m_alg->setProperty( "OverlayInputDigitKey", inputBkgPropertyValue).isSuccess() ); - ASSERT_TRUE( m_alg->setProperty( "OutputDigitKey", outputPropertyValue).isSuccess() ); - ASSERT_TRUE( m_alg->overlayInitialize().isSuccess() ); - ASSERT_TRUE( m_alg->overlayExecute().isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "BkgInputKey", inputBkgPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "SignalInputKey", inputSigPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "OutputKey", outputPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->initialize().isSuccess() ); + ASSERT_TRUE( m_alg->execute().isSuccess() ); } TEST_F(MdtOverlay_test, containers_with_matching_empty_collections) { @@ -97,11 +97,11 @@ namespace OverlayTesting { std::string inputSigPropertyValue = "'StoreGateSvc+MDT_DIGITS_SIG1'"; std::string inputBkgPropertyValue = "'StoreGateSvc+MDT_DIGITS_BKG1'"; std::string outputPropertyValue = "'StoreGateSvc+MDT_DIGITS1'"; - ASSERT_TRUE( m_alg->setProperty( "MainInputDigitKey", inputSigPropertyValue).isSuccess() ); - ASSERT_TRUE( m_alg->setProperty( "OverlayInputDigitKey", inputBkgPropertyValue).isSuccess() ); - ASSERT_TRUE( m_alg->setProperty( "OutputDigitKey", outputPropertyValue).isSuccess() ); - ASSERT_TRUE( m_alg->overlayInitialize().isSuccess() ); - ASSERT_TRUE( m_alg->overlayExecute().isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "BkgInputKey", inputBkgPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "SignalInputKey", inputSigPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "OutputKey", outputPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->initialize().isSuccess() ); + ASSERT_TRUE( m_alg->execute().isSuccess() ); // check output makes sense SG::ReadHandle<MdtDigitContainer> outputDataHandle{"StoreGateSvc+MDT_DIGITS1"}; ASSERT_TRUE( outputDataHandle.isValid() ); @@ -129,11 +129,11 @@ namespace OverlayTesting { std::string inputSigPropertyValue = "'StoreGateSvc+MDT_DIGITS_SIG2'"; std::string inputBkgPropertyValue = "'StoreGateSvc+MDT_DIGITS_BKG2'"; std::string outputPropertyValue = "'StoreGateSvc+MDT_DIGITS2'"; - ASSERT_TRUE( m_alg->setProperty( "MainInputDigitKey", inputSigPropertyValue).isSuccess() ); - ASSERT_TRUE( m_alg->setProperty( "OverlayInputDigitKey", inputBkgPropertyValue).isSuccess() ); - ASSERT_TRUE( m_alg->setProperty( "OutputDigitKey", outputPropertyValue).isSuccess() ); - ASSERT_TRUE( m_alg->overlayInitialize().isSuccess() ); - ASSERT_TRUE( m_alg->overlayExecute().isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "BkgInputKey", inputBkgPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "SignalInputKey", inputSigPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "OutputKey", outputPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->initialize().isSuccess() ); + ASSERT_TRUE( m_alg->execute().isSuccess() ); // check output makes sense SG::ReadHandle<MdtDigitContainer> outputDataHandle{"StoreGateSvc+MDT_DIGITS2"}; ASSERT_TRUE( outputDataHandle.isValid() ); @@ -169,11 +169,11 @@ namespace OverlayTesting { std::string inputSigPropertyValue = "'StoreGateSvc+MDT_DIGITS_SIG3'"; std::string inputBkgPropertyValue = "'StoreGateSvc+MDT_DIGITS_BKG3'"; std::string outputPropertyValue = "'StoreGateSvc+MDT_DIGITS3'"; - ASSERT_TRUE( m_alg->setProperty( "MainInputDigitKey", inputSigPropertyValue).isSuccess() ); - ASSERT_TRUE( m_alg->setProperty( "OverlayInputDigitKey", inputBkgPropertyValue).isSuccess() ); - ASSERT_TRUE( m_alg->setProperty( "OutputDigitKey", outputPropertyValue).isSuccess() ); - ASSERT_TRUE( m_alg->overlayInitialize().isSuccess() ); - ASSERT_TRUE( m_alg->overlayExecute().isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "BkgInputKey", inputBkgPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "SignalInputKey", inputSigPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "OutputKey", outputPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->initialize().isSuccess() ); + ASSERT_TRUE( m_alg->execute().isSuccess() ); // check output makes sense SG::ReadHandle<MdtDigitContainer> outputDataHandle{"StoreGateSvc+MDT_DIGITS3"}; ASSERT_TRUE( outputDataHandle.isValid() ); @@ -216,11 +216,11 @@ namespace OverlayTesting { std::string inputSigPropertyValue = "'StoreGateSvc+MDT_DIGITS_SIG4'"; std::string inputBkgPropertyValue = "'StoreGateSvc+MDT_DIGITS_BKG4'"; std::string outputPropertyValue = "'StoreGateSvc+MDT_DIGITS4'"; - ASSERT_TRUE( m_alg->setProperty( "MainInputDigitKey", inputSigPropertyValue).isSuccess() ); - ASSERT_TRUE( m_alg->setProperty( "OverlayInputDigitKey", inputBkgPropertyValue).isSuccess() ); - ASSERT_TRUE( m_alg->setProperty( "OutputDigitKey", outputPropertyValue).isSuccess() ); - ASSERT_TRUE( m_alg->overlayInitialize().isSuccess() ); - ASSERT_TRUE( m_alg->overlayExecute().isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "BkgInputKey", inputBkgPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "SignalInputKey", inputSigPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "OutputKey", outputPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->initialize().isSuccess() ); + ASSERT_TRUE( m_alg->execute().isSuccess() ); // check output makes sense SG::ReadHandle<MdtDigitContainer> outputDataHandle{"StoreGateSvc+MDT_DIGITS4"}; ASSERT_TRUE( outputDataHandle.isValid() ); @@ -271,11 +271,11 @@ namespace OverlayTesting { std::string inputSigPropertyValue = "'StoreGateSvc+MDT_DIGITS_SIG5'"; std::string inputBkgPropertyValue = "'StoreGateSvc+MDT_DIGITS_BKG5'"; std::string outputPropertyValue = "'StoreGateSvc+MDT_DIGITS5'"; - ASSERT_TRUE( m_alg->setProperty( "MainInputDigitKey", inputSigPropertyValue).isSuccess() ); - ASSERT_TRUE( m_alg->setProperty( "OverlayInputDigitKey", inputBkgPropertyValue).isSuccess() ); - ASSERT_TRUE( m_alg->setProperty( "OutputDigitKey", outputPropertyValue).isSuccess() ); - ASSERT_TRUE( m_alg->overlayInitialize().isSuccess() ); - ASSERT_TRUE( m_alg->overlayExecute().isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "BkgInputKey", inputBkgPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "SignalInputKey", inputSigPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "OutputKey", outputPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->initialize().isSuccess() ); + ASSERT_TRUE( m_alg->execute().isSuccess() ); // check output makes sense SG::ReadHandle<MdtDigitContainer> outputDataHandle{"StoreGateSvc+MDT_DIGITS5"}; ASSERT_TRUE( outputDataHandle.isValid() ); @@ -323,11 +323,11 @@ namespace OverlayTesting { std::string inputSigPropertyValue = "'StoreGateSvc+MDT_DIGITS_SIG6'"; std::string inputBkgPropertyValue = "'StoreGateSvc+MDT_DIGITS_BKG6'"; std::string outputPropertyValue = "'StoreGateSvc+MDT_DIGITS6'"; - ASSERT_TRUE( m_alg->setProperty( "MainInputDigitKey", inputSigPropertyValue).isSuccess() ); - ASSERT_TRUE( m_alg->setProperty( "OverlayInputDigitKey", inputBkgPropertyValue).isSuccess() ); - ASSERT_TRUE( m_alg->setProperty( "OutputDigitKey", outputPropertyValue).isSuccess() ); - ASSERT_TRUE( m_alg->overlayInitialize().isSuccess() ); - ASSERT_TRUE( m_alg->overlayExecute().isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "BkgInputKey", inputBkgPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "SignalInputKey", inputSigPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "OutputKey", outputPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->initialize().isSuccess() ); + ASSERT_TRUE( m_alg->execute().isSuccess() ); // check output makes sense SG::ReadHandle<MdtDigitContainer> outputDataHandle{"StoreGateSvc+MDT_DIGITS6"}; ASSERT_TRUE( outputDataHandle.isValid() ); @@ -370,11 +370,11 @@ namespace OverlayTesting { std::string inputSigPropertyValue = "'StoreGateSvc+MDT_DIGITS_SIG7'"; std::string inputBkgPropertyValue = "'StoreGateSvc+MDT_DIGITS_BKG7'"; std::string outputPropertyValue = "'StoreGateSvc+MDT_DIGITS7'"; - ASSERT_TRUE( m_alg->setProperty( "MainInputDigitKey", inputSigPropertyValue).isSuccess() ); - ASSERT_TRUE( m_alg->setProperty( "OverlayInputDigitKey", inputBkgPropertyValue).isSuccess() ); - ASSERT_TRUE( m_alg->setProperty( "OutputDigitKey", outputPropertyValue).isSuccess() ); - ASSERT_TRUE( m_alg->overlayInitialize().isSuccess() ); - ASSERT_TRUE( m_alg->overlayExecute().isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "BkgInputKey", inputBkgPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "SignalInputKey", inputSigPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "OutputKey", outputPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->initialize().isSuccess() ); + ASSERT_TRUE( m_alg->execute().isSuccess() ); // check output makes sense SG::ReadHandle<MdtDigitContainer> outputDataHandle{"StoreGateSvc+MDT_DIGITS7"}; ASSERT_TRUE( outputDataHandle.isValid() ); @@ -417,11 +417,11 @@ namespace OverlayTesting { std::string inputSigPropertyValue = "'StoreGateSvc+MDT_DIGITS_SIG8'"; std::string inputBkgPropertyValue = "'StoreGateSvc+MDT_DIGITS_BKG8'"; std::string outputPropertyValue = "'StoreGateSvc+MDT_DIGITS8'"; - ASSERT_TRUE( m_alg->setProperty( "MainInputDigitKey", inputSigPropertyValue).isSuccess() ); - ASSERT_TRUE( m_alg->setProperty( "OverlayInputDigitKey", inputBkgPropertyValue).isSuccess() ); - ASSERT_TRUE( m_alg->setProperty( "OutputDigitKey", outputPropertyValue).isSuccess() ); - ASSERT_TRUE( m_alg->overlayInitialize().isSuccess() ); - ASSERT_TRUE( m_alg->overlayExecute().isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "BkgInputKey", inputBkgPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "SignalInputKey", inputSigPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "OutputKey", outputPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->initialize().isSuccess() ); + ASSERT_TRUE( m_alg->execute().isSuccess() ); // check output makes sense SG::ReadHandle<MdtDigitContainer> outputDataHandle{"StoreGateSvc+MDT_DIGITS8"}; ASSERT_TRUE( outputDataHandle.isValid() ); diff --git a/MuonSpectrometer/MuonOverlay/MuonOverlayBase/CMakeLists.txt b/MuonSpectrometer/MuonOverlay/MuonOverlayBase/CMakeLists.txt index cbcce39fb69dbd050e6985a59df53f2e63af4bcf..ad4acd746af6c4d603f6566521352b2593662350 100644 --- a/MuonSpectrometer/MuonOverlay/MuonOverlayBase/CMakeLists.txt +++ b/MuonSpectrometer/MuonOverlay/MuonOverlayBase/CMakeLists.txt @@ -7,16 +7,9 @@ atlas_subdir( MuonOverlayBase ) # Declare the package's dependencies: atlas_depends_on_subdirs( PUBLIC - Control/AthenaBaseComps - Control/AthContainers - Control/StoreGate - DetectorDescription/Identifier - Event/EventOverlay/IDC_OverlayBase - Event/EventOverlay/OverlayAlgBase - GaudiKernel ) + Event/EventOverlay/IDC_OverlayBase ) # Component(s) in the package: atlas_add_library( MuonOverlayBase PUBLIC_HEADERS MuonOverlayBase - LINK_LIBRARIES AthenaBaseComps AthContainers Identifier IDC_OverlayBase OverlayAlgBase GaudiKernel StoreGateLib SGtests ) - + LINK_LIBRARIES IDC_OverlayBase ) diff --git a/MuonSpectrometer/MuonOverlay/MuonOverlayBase/MuonOverlayBase/IDC_MuonOverlayBase.h b/MuonSpectrometer/MuonOverlay/MuonOverlayBase/MuonOverlayBase/IDC_MuonOverlayBase.h index 27986c5a8e8e287a1485bb7fa17c46fcc090c9e0..0c8d02681eb79321de88c00398b59bacb6c47ebc 100644 --- a/MuonSpectrometer/MuonOverlay/MuonOverlayBase/MuonOverlayBase/IDC_MuonOverlayBase.h +++ b/MuonSpectrometer/MuonOverlay/MuonOverlayBase/MuonOverlayBase/IDC_MuonOverlayBase.h @@ -20,6 +20,7 @@ #define IDC_MUONOVERLAYCOMMON_H #include <AthenaBaseComps/AthAlgorithm.h> +#include <Identifier/IdentifierHash.h> class IDC_MuonOverlayBase : public AthAlgorithm diff --git a/MuonSpectrometer/MuonOverlay/MuonOverlayBase/MuonOverlayBase/IDC_MuonOverlayBase.icc b/MuonSpectrometer/MuonOverlay/MuonOverlayBase/MuonOverlayBase/IDC_MuonOverlayBase.icc index 72b9504d7943da41bd7d696cf9b838d1787276c6..dbbb840edd239e6429fb60fed26815552149def1 100644 --- a/MuonSpectrometer/MuonOverlay/MuonOverlayBase/MuonOverlayBase/IDC_MuonOverlayBase.icc +++ b/MuonSpectrometer/MuonOverlay/MuonOverlayBase/MuonOverlayBase/IDC_MuonOverlayBase.icc @@ -7,9 +7,9 @@ // Andrei Gaponenko <agaponenko@lbl.gov>, 2006-2009 #include <Identifier/Identifier.h> -#include <Identifier/IdentifierHash.h> -#include "IDC_MultiHitOverlayCommon.h" +#include <IDC_OverlayBase/IDC_OverlayCommon.h> +#include <MuonOverlayBase/IDC_MultiHitOverlayCommon.h> template <class Collection> @@ -38,14 +38,33 @@ StatusCode IDC_MuonOverlayBase::overlayContainerBase(const IDC_Container *bkgCon bool isMultiHitCollection) { typedef typename IDC_Container::base_value_type Collection; - typedef typename Collection::base_value_type Datum; ATH_MSG_DEBUG("overlayContainer<>() begin"); - // Get all the hashes for both signal and background container - const std::vector<IdentifierHash> bkgHashes = bkgContainer->GetAllCurrentHashes(); + // Get all the hashes for the signal container const std::vector<IdentifierHash> signalHashes = signalContainer->GetAllCurrentHashes(); + // There are some use cases where background is empty + if (!bkgContainer) { + // Only loop through the signal collections and copy them over + for (const IdentifierHash &hashId : signalHashes) { + // Copy the signal collection + std::unique_ptr<Collection> signalCollection = copyCollection(hashId, signalContainer->indexFindPtr(hashId)); + + if (outputContainer->addCollection(signalCollection.get(), hashId).isFailure()) { + ATH_MSG_ERROR("Adding signal Collection with hashId " << hashId << " failed"); + return StatusCode::FAILURE; + } else { + signalCollection.release(); + } + } + + return StatusCode::SUCCESS; + } + + // Get all the hashes for the background container + const std::vector<IdentifierHash> bkgHashes = bkgContainer->GetAllCurrentHashes(); + // The MC signal container should typically be smaller than bkgContainer, // because the latter contains all the noise, minimum bias and pile up. // Thus we firstly iterate over signal hashes and store them in a map. @@ -89,11 +108,9 @@ StatusCode IDC_MuonOverlayBase::overlayContainerBase(const IDC_Container *bkgCon if (isMultiHitCollection) { Overlay::mergeMultiHitCollections(bkgCollection.get(), signalCollection.get(), outputCollection.get()); } else { - // TODO: single-hit case not used at the moment - // Overlay::mergeCollections(bkgCollection.get(), signalCollection.get(), outputCollection.get()); + Overlay::mergeCollections(bkgCollection.get(), signalCollection.get(), outputCollection.get(), this); } - outputContainer->removeCollection(hashId); if (outputContainer->addCollection(outputCollection.get(), hashId).isFailure()) { ATH_MSG_ERROR("Adding overlaid Collection with hashId " << hashId << " failed"); return StatusCode::FAILURE; diff --git a/MuonSpectrometer/MuonOverlay/MuonOverlayBase/MuonOverlayBase/MuonOverlayBase.h b/MuonSpectrometer/MuonOverlay/MuonOverlayBase/MuonOverlayBase/MuonOverlayBase.h deleted file mode 100644 index 697ebb5ec3279a357a6ee867ee61486ca483e230..0000000000000000000000000000000000000000 --- a/MuonSpectrometer/MuonOverlay/MuonOverlayBase/MuonOverlayBase/MuonOverlayBase.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration -*/ - -// Dear emacs, this is -*-c++-*- - -// Generic overlaying code for boolean-like hits. -// Factored out from InDetOverlay. -// -// Andrei Gaponenko <agaponenko@lbl.gov>, 2006-2008 - -// Ketevi A. Assamagan <ketevi@bnl.gov>, March 2008 - -// Piyali Banerjee <Piyali.Banerjee@cern.ch>, March 2011 - -#ifndef MUONOVERLAYBASE_H -#define MUONOVERLAYBASE_H - -#include <string> -#include "IDC_OverlayBase/IDC_OverlayBase.h" - -class ISvcLocator; -class StoreGateSvc; - -class MuonOverlayBase : public IDC_OverlayBase { -public: - - MuonOverlayBase(const std::string &name, ISvcLocator *pSvcLocator) - : IDC_OverlayBase(name, pSvcLocator) {} - -}; - -#endif /* MUONOVERLAYBASE_H */ diff --git a/MuonSpectrometer/MuonOverlay/MuonOverlayBase/MuonOverlayBase/MuonOverlayBase.icc b/MuonSpectrometer/MuonOverlay/MuonOverlayBase/MuonOverlayBase/MuonOverlayBase.icc deleted file mode 100644 index 79036b3d749c16108b6f70930d4770a786526ae3..0000000000000000000000000000000000000000 --- a/MuonSpectrometer/MuonOverlay/MuonOverlayBase/MuonOverlayBase/MuonOverlayBase.icc +++ /dev/null @@ -1,52 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -// Generic overlaying code for Muon Digits -// Factored out from InDetOverlay. -// -// Andrei Gaponenko <agaponenko@lbl.gov>, 2006-2008 - -// Ketevi A. Assamagan <ketevi@bnl.gov>, March 2008 - -// Piyali Banerjee <Piyali.Banerjee@cern.ch>, March 2011 - -#include "GaudiKernel/MsgStream.h" -#include "StoreGate/StoreGateSvc.h" -#include <memory> - -//================================================================ - -template<class TypeToBeCopied, class Datum> -TypeToBeCopied* MuonOverlayBase::copyMuonDigitContainer(const TypeToBeCopied* oldObject) -{ - - typedef typename TypeToBeCopied::base_value_type Collection; - const std::string templateClassName = typeid(TypeToBeCopied).name(); - - if (oldObject == 0) { - ATH_MSG_WARNING("copyMuonDigitContainer<"<<templateClassName<<">(): oldObject is a NULL pointer"); - return 0; - } - - TypeToBeCopied *newObject = 0; - - newObject = new TypeToBeCopied (oldObject->size()); - typename TypeToBeCopied::const_iterator iFirst = oldObject->begin(); - typename TypeToBeCopied::const_iterator iLast = oldObject->end(); - for (; iFirst != iLast; ++iFirst ) { - Collection *element = new Collection ((*iFirst)->identify(), (*iFirst)->identifierHash()); - typename TypeToBeCopied::base_value_type::const_iterator firstData = (*iFirst)->begin(); - typename TypeToBeCopied::base_value_type::const_iterator lastData = (*iFirst)->end(); - for (; firstData != lastData; ++firstData) { - Datum * newData = new Datum (*(dynamic_cast<const Datum*>(*firstData))); - element->push_back(newData); - } - if ( newObject->addCollection ( element, (*iFirst)->identifierHash() ).isFailure() ) { - ATH_MSG_WARNING("copyMuonDigitCongtainer<"<<templateClassName<<">(): problem adding collection with "<<"hash="<<(*iFirst)->identifierHash() ); - } - } - - return newObject; - -}