diff --git a/PhysicsAnalysis/RingerSelectorTools/CMakeLists.txt b/PhysicsAnalysis/RingerSelectorTools/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..fa033d66128487c4a1f5ee0a814b27882cda6801 --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/CMakeLists.txt @@ -0,0 +1,55 @@ +################################################################################ +# Package: RingerSelectorTools +################################################################################ + +# Declare the package name: +atlas_subdir( RingerSelectorTools ) + +# Declare the package's dependencies: +atlas_depends_on_subdirs( PUBLIC + Control/AthToolSupport/AsgTools + Control/AthenaKernel + Control/CxxUtils + Event/xAOD/xAODCaloRings + Event/xAOD/xAODEgamma + Event/xAOD/xAODTracking + PhysicsAnalysis/AnalysisCommon/PATCore + PhysicsAnalysis/ElectronPhotonID/ElectronPhotonSelectorTools + PRIVATE + Control/AthContainers + Event/xAOD/xAODBase + GaudiKernel + Tools/PathResolver + Tracking/TrkEvent/TrkTrackSummary ) + +# External dependencies: +find_package( Boost COMPONENTS filesystem thread system ) +find_package( ROOT COMPONENTS Core Tree MathCore Hist RIO pthread ) + +# tag ROOTBasicLibs was not recognized in automatic conversion in cmt2cmake + +# Component(s) in the package: +atlas_add_library( RingerSelectorToolsLib + Root/*.cxx + Root/procedures/*.cxx + Root/tools/*.cxx + PUBLIC_HEADERS RingerSelectorTools + INCLUDE_DIRS ${Boost_INCLUDE_DIRS} ${ROOT_INCLUDE_DIRS} + LINK_LIBRARIES ${Boost_LIBRARIES} ${ROOT_LIBRARIES} AsgTools AthenaKernel CxxUtils xAODCaloRings xAODEgamma xAODTracking PATCoreLib ElectronPhotonSelectorToolsLib + PRIVATE_LINK_LIBRARIES AthContainers xAODBase GaudiKernel PathResolver TrkTrackSummary ) + +atlas_add_component( RingerSelectorTools + src/components/*.cxx + INCLUDE_DIRS ${Boost_INCLUDE_DIRS} ${ROOT_INCLUDE_DIRS} + LINK_LIBRARIES ${Boost_LIBRARIES} ${ROOT_LIBRARIES} AsgTools AthenaKernel CxxUtils xAODCaloRings xAODEgamma xAODTracking PATCoreLib ElectronPhotonSelectorToolsLib AthContainers xAODBase GaudiKernel PathResolver TrkTrackSummary RingerSelectorToolsLib ) + +atlas_add_dictionary( RingerSelectorToolsDict + RingerSelectorTools/RingerSelectorToolsDict.h + RingerSelectorTools/selection.xml + INCLUDE_DIRS ${Boost_INCLUDE_DIRS} ${ROOT_INCLUDE_DIRS} + LINK_LIBRARIES ${Boost_LIBRARIES} ${ROOT_LIBRARIES} AsgTools AthenaKernel CxxUtils xAODCaloRings xAODEgamma xAODTracking PATCoreLib ElectronPhotonSelectorToolsLib AthContainers xAODBase GaudiKernel PathResolver TrkTrackSummary RingerSelectorToolsLib ) + +# Install files from the package: +atlas_install_python_modules( python/*.py ) +atlas_install_data( data/test ) + diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/AsgElectronRingerSelector.h b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/AsgElectronRingerSelector.h new file mode 100644 index 0000000000000000000000000000000000000000..3fe36544a830abcbd8b833075039b0913897eb90 --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/AsgElectronRingerSelector.h @@ -0,0 +1,449 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: AsgElectronRingerSelector.h 704615 2015-10-29 18:50:12Z wsfreund $ +#ifndef RINGERSELECTORTOOLS_ASGELECTRONCALORINGERSELECTOR_H +#define RINGERSELECTORTOOLS_ASGELECTRONCALORINGERSELECTOR_H + +// STL includes: +#include <string> + +// ROOT includes: +#include <TFile.h> + +#ifndef RINGER_STANDALONE +// Athena includes +#include "PATCore/TAccept.h" +#include "PATCore/TResult.h" +#include "AsgTools/AsgMetadataTool.h" +#include "AsgTools/ToolHandle.h" +#include "ElectronPhotonSelectorTools/IAsgElectronIsEMSelector.h" + +// xAOD includes: +#include "xAODCaloRings/CaloRingsContainer.h" // needed for caloRingsReader_t +#include "xAODCaloRings/RingSetConfContainerFwd.h" + +// Local includes: +#include "RingerSelectorTools/IAsgElectronRingerSelector.h" +#include "RingerSelectorTools/ElectronTAccept.h" +#include "RingerSelectorTools/procedures/RingerProcedureWrapper.h" +#include "RingerSelectorTools/tools/TrackPatternsHolder.h" +#include "RingerSelectorTools/tools/RingerCommonSelector.h" +#include "RingerSelectorTools/tools/cxx/mutable.h" +#include "RingerSelectorTools/tools/cxx/final.h" +#include "RingerSelectorTools/tools/cxx/override.h" + +namespace Ringer { + +/* + * TODO List: + * - Add metadata on xAOD file with the AsgSelector configuration. + */ + +/** + * @class AsgElectronRingerSelector + * @brief Electron selector using Ringer patterns to apply discrimination + * + * @author Werner Spolidoro Freund <wsfreund@cern.ch> + * + * Based on AsgElectronIsEMSelector by Jovan Mitrevski (UCSC) + * and Karsten Koeneke (CERN) + * + * and Metadata implementation based on xAODConfigTool by + * Attila Krasznahorkay + * + **/ +class AsgElectronRingerSelector : public asg::AsgMetadataTool, + virtual public IAsgElectronRingerSelector +{ + + public: + /** + * @class IOConfStruct + * @brief Configuration structure for parameters in file + **/ + struct IOConfStruct { + bool useTrackPat; + bool useRawTrackPat; + //bool useCalStdPat; + //bool useRawCalStdPat(false), + bool useCaloCommittee; + bool useBLOutliers; + bool usePIXOutliers; + bool useSCTOutliers; + bool useTRTOutliers; + bool useTRTXenonHits; + + IOConfStruct(); + }; + + // Use ASG_TOOL macro for 2 interface base classes. + ASG_TOOL_CLASS2(AsgElectronRingerSelector, + IAsgElectronRingerSelector, + IAsgSelectionTool) + + public: + + /** Standard constructor */ + AsgElectronRingerSelector(std::string myname); + + /** Standard destructor */ + virtual ~AsgElectronRingerSelector(); + + /** Gaudi Service Interface method implementations */ + virtual StatusCode initialize(); + + /** Gaudi Service Interface method implementations */ + virtual StatusCode finalize(); + + /// Main methods for IAsgSelectionTool interface + ///@{ + /** + * @brief Set the discrimination configuration file + **/ + void setDiscrFile( const std::string path ); + + /** + * @brief Set the threshold configuration file + **/ + void setThresFile( const std::string path ); + + /** + * @brief Set the threshold configuration file + **/ + void setCutMask( const unsigned int cutMask ); + + /** + * @brief Set the CutIDSelector to be used + **/ + void setCutIDSelector( IAsgElectronIsEMSelector *cutID ); + + /** + * @brief Set the RingSetConfContainer (MetaData) key + **/ + void setRSMetaName( const std::string name ); + + /** + * @brief Set whether to cache the meta data and assume it will be the same + * through all the analysis. + **/ + void setCacheMetaData( bool flag ); + + /** + * @brief This method will bypass accept to xAOD::Electron if it is possible. + **/ + const Root::TAccept& accept( const xAOD::IParticle* part ) const; + + /** + * @brief Identification procedure is done in this method + **/ + const Root::TAccept& accept( const xAOD::Electron* part ) const; + + /** + * @brief Identification procedure is done in this method + **/ + const Root::TAccept& accept( const xAOD::Egamma* eg ) const; + + /** + * @brief Accept using Electron reference + **/ + const Root::TAccept& accept( const xAOD::Electron& part ) const; + /** + * @brief Accept using IParticle reference + **/ + const Root::TAccept& accept( const xAOD::IParticle& part ) const; + + /** + * @brief Identification procedure is done in this method + **/ + const Root::TAccept& accept( const xAOD::Egamma& eg ) const; + + /** + * @brief Method to get the plain TAccept for the last particle. + **/ + const Root::TAccept& getTAccept() const; + + /** Method to get output space representation */ + const std::vector<float>& getOutputSpace() const; + + /** + * @brief Main execute method + **/ + StatusCode execute(const xAOD::Electron* eg) const; + + /** + * @brief Execute without tracking information, potentially used by trigger. + **/ + StatusCode execute(const xAOD::Egamma* eg) const; + + /** + * @brief Retrieve configuration on file + **/ + static void retrieveFileConf(const char* fileName, + IOConfStruct &fileConf); + + /** + * @brief Write configuration on file + **/ + static void writeConf(const char* fileName, + IOConfStruct &fileConf); + + /** + * @brief Print file configuration + **/ + static void printConf( IOConfStruct &fileConf, + MsgStream *msg, MSG::Level lvl = MSG::DEBUG); + ///@} + + protected: + + /** + * @brief Update metadata information held + */ + StatusCode beginInputFile(); + + /** + * @brief Called when entering a new event + * + * NOTE: This doesn't do anything for now + **/ + StatusCode beginEvent(); + + + private: + + /// @name AsgElectronRingerSelector props (python configurables): + /// @{ + + /// @brief Conf file in which we will retrieve the discrimination chain + std::string m_discrFileName; + + /// @brief Conf file in which we will retrieve the threshold values + std::string m_thresFileName; + + /// @brief The CutID Tool Handle to run track (if required by config file) + ToolHandle<IAsgElectronIsEMSelector> m_cutIDSelector; + + /// @brief The unsigned mask from which we will set m_cutsToUse (IsEM) + unsigned m_cutsMask; + + /// @brief RingSetConfContainer key in the MetaData StoreGate + std::string m_rsMetaName; + + /// @brief Whether to cache metadata configuration or not + bool m_cacheMetaData; + /// @} + + /// @name AsgElectronRingerSelector props (non-python configurables): + /// @{ + /// @brief The discriminator chain collection + IDiscrWrapperCollection m_discrWrapperCol; + + /// @brief The discriminator chain collection + IThresWrapper *m_thresWrapper; + + /// @brief The Ringer Common Selector which will be run by this AsgSelector: + RingerCommonSelector *m_ringSelCommon; + + /// @brief Hold the track patterns: + ATH_RINGER_MUTABLE TrackPatternsHolder *m_trackPat; + + /// @brief The particles CaloRings decorations reader + xAOD::caloRingsReader_t* m_ringsELReader; + + /// @brief Last particle decision bitmask (the inverse of the IsEM) + ATH_RINGER_MUTABLE Root::TAccept m_partDecMsk; + + /// @brief Last particle accept bitmask (already applying the m_cutsToUse) + ATH_RINGER_MUTABLE Root::TAccept m_accept; + + /// @brief Which subset of decisions to use + ElectronTAccept::bitMskWord m_cutsToUse; + + /// Whether to use CutID track decision + bool m_useCutIDDecision; + + /// Flag to whether metadata is cached or not + bool m_metaDataCached; + + /// Hold pointer into the CaloRingsConfContainer + const xAOD::RingSetConfContainer* m_rsConfCont; + + /// Hold the raw configuration collection: + xAOD::RingSetConf::RawConfCollection m_rawConfCol; + + /// Cache if configuration info is on inputData + bool m_metaIsOnOutput; + /// @} + + /// Private methods: + /// @{ + + /** + * @brief Read the configuration file + **/ + StatusCode readConfigFiles(); + + /** + * @brief Register decision bitmask word + **/ + StatusCode registerDecisionBitMask(); + + /** + * Set TAccept value + **/ + void fillTAccept() const; + /// @} +}; + +#else // RINGER_STANDALONE is defined +class AsgElectronRingerSelector +{ + public: + /** + * @class IOConfStruct + * @brief Configuration structure for parameters in file + **/ + struct IOConfStruct { + bool useTrackPat; + bool useRawTrackPat; + //bool useCalStdPat; + //bool useRawCalStdPat(false), + bool useCaloCommittee; + bool useBLOutliers; + bool usePIXOutliers; + bool useSCTOutliers; + bool useTRTOutliers; + bool useTRTXenonHits; + + IOConfStruct(); + }; + + /** + * @brief Retrieve configuration on file + **/ + static void retrieveFileConf(IOConfStruct &fileConf); + + /** + * @brief Write configuration on file + **/ + static void writeConf(TFile *file, + IOConfStruct &fileConf); + + /** + * @brief Print file configuration + **/ + static void printConf( IOConfStruct &fileConf, + MsgStream *msg, MSG::Level lvl = MSG::DEBUG); +}; +#endif // ifndef RINGER_STANDALONE + +// Inline methods: +//============================================================================= +inline +AsgElectronRingerSelector::IOConfStruct::IOConfStruct() + : useTrackPat(false), + useRawTrackPat(false), + //useCalStdPat, + //useRawCalStdPat(false), + useCaloCommittee(false), + useBLOutliers(false), + usePIXOutliers(false), + useSCTOutliers(false), + useTRTOutliers(false), + useTRTXenonHits(false){;} + + +#ifndef RINGER_STANDALONE + +//============================================================================= +inline +void AsgElectronRingerSelector::setDiscrFile( const std::string path ) +{ + m_discrFileName = path; +} + +//============================================================================= +inline +void AsgElectronRingerSelector::setThresFile( const std::string path ) +{ + m_thresFileName = path; +} + +//============================================================================= +inline +void AsgElectronRingerSelector::setCutMask( const unsigned int cutMask ) +{ + m_cutsMask = cutMask; +} + +//============================================================================= +inline +void AsgElectronRingerSelector::setCutIDSelector( + IAsgElectronIsEMSelector *cutID ) +{ + m_cutIDSelector = ToolHandle<IAsgElectronIsEMSelector>(cutID); +} + +//============================================================================= +inline +void AsgElectronRingerSelector::setRSMetaName( const std::string name ) +{ + m_rsMetaName = name; +} + +//============================================================================= +inline +void AsgElectronRingerSelector::setCacheMetaData( bool flag ) +{ + m_cacheMetaData = flag; +} + +//============================================================================= +inline +const Root::TAccept& AsgElectronRingerSelector::accept( + const xAOD::Electron& part ) const +{ + return accept (&part); +} + +//============================================================================= +inline +const Root::TAccept& AsgElectronRingerSelector::accept( + const xAOD::IParticle& part ) const +{ + return accept (&part); +} + +//============================================================================= +inline +const Root::TAccept& AsgElectronRingerSelector::accept( + const xAOD::Egamma& part ) const +{ + return accept (&part); +} + +//============================================================================= +inline +const Root::TAccept& AsgElectronRingerSelector::getTAccept() const +{ + return m_accept; +} + +//============================================================================= +inline +const std::vector<float>& AsgElectronRingerSelector::getOutputSpace() const +{ + if ( m_ringSelCommon ){ + return m_ringSelCommon->getOutputSpace(); + } else { + throw std::runtime_error(std::string("Cannot return outut space " + "because RingerCommonSelector was not yet allocated.")); + } +} + +} // namespace Ringer +#endif // RINGER_STANDALONE + +#endif // RINGERSELECTORTOOLS_ASGELECTRONCALORINGERSELECTOR_H diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/ElectronTAccept.h b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/ElectronTAccept.h new file mode 100644 index 0000000000000000000000000000000000000000..f39b3c19f2e77d47a4e3cd085911aed846b9c407 --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/ElectronTAccept.h @@ -0,0 +1,152 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: ElectronTAccept.h 670599 2015-05-28 14:15:35Z wsfreund $ +#ifndef RINGER_STANDALONE + +#ifndef RINGERSELECTORTOOLS_ELECTRONTACCEPT_H +#define RINGERSELECTORTOOLS_ELECTRONTACCEPT_H + +// Athena includes: +#include "PATCore/TAccept.h" + +// Local includes: +#include "RingerSelectorTools/RingerSelectorToolsDefs.h" + +namespace Ringer { + +class BitdefElectron_v1; + +/** + * @class ElectronTAccept_v1 + * @brief Get electron defined TAccept and its masks. + **/ +class ElectronTAccept_v1 { + public: + /** + * @brief Bit mask word used + * + * FIXME: Ask m_nBits to be encapsulated and a similar typedef like this to + * be within TAccept + **/ + typedef std::bitset<m_nBits> bitMskWord; + + // Grant access to m_accept for BitdefElectron_v1 + friend class BitdefElectron_v1; + + /// Main methods + /// @{ + /** + * @brief Retrieve copy of the ElectronTAccept_v1 template + **/ + static unsigned int getAppliedCutMsk(const Requirement cut, + bool withCutIDTrack = false); + /** + * @brief Retrieve copy of the ElectronTAccept_v1 template + **/ + static Root::TAccept retrieveTAcceptTemplate(){ return m_accept;} + /// @} + + + /// Auxiliar methods + /// @{ + /** + * @brief Reset mask so that it doesn't apply any cut (IsEM mask): + **/ + static void resetMsk(bitMskWord& word); + /** + * @brief Add loose applied cuts to bitmask (IsEM mask): + **/ + static void addLooseAppliedCuts(bitMskWord& word); + /** + * @brief Add medium applied cuts to bitmask (IsEM mask): + **/ + static void addMediumAppliedCuts(bitMskWord& word); + /** + * @brief Add tight applied cuts bitmask (IsEM mask): + **/ + static void addTightAppliedCuts(bitMskWord& word); + /** + * @brief Add CutID Track applied cuts to bitmask (IsEM mask): + **/ + static void addCutIDTrackAppliedCuts(bitMskWord& word); + /// @} + + private: + /** + * @brief Standard ctor (ensure abstract class). + **/ + ElectronTAccept_v1(); + + /// The TAccept: + static Root::TAccept m_accept; +}; + +/** + * @class BitdefElectron_v1 + * @brief Define electron bits (v1) + **/ +class BitdefElectron_v1 { +/* + * NOTE: + * + * Should new implementation inherit from this? That is, new bits + * can only be defined for positions that weren't yet defined: + * + * Example: + * + * \code + * class BitdefElectron_v2 : public BitdefElectron_v2 + * { + * static const int NewBit; + * } + * + * \endcode + */ + + public: + /// The decision position set to true when no error occurs: + static const int NoErrorBit; + /// Whether CutID was run: + static const int ExecCutID; + /// The decision position of the CutID: + static const int CutIDDec; + /// The decision position of the Ringer algorithm's discrimation chain: + static const int RingerChainDec; + + /// Number of bits: + static unsigned NUsedBits() { return m_nUsedBits; } + + private: + /** + * @brief Declare bit to ElectronTAccept_v1 word + **/ + static int declareBit( + const char* cutName, + const char* cutDescr) + { + int bit = ElectronTAccept_v1::m_accept.addCut(cutName,cutDescr); + ++m_nUsedBits; + return bit; + } + + static unsigned m_nUsedBits; + + /** + * @brief Standard ctor (ensure abstract class). + **/ + BitdefElectron_v1(); +}; + +// Definition of the current Electron TAccept version: +typedef ElectronTAccept_v1 ElectronTAccept; +// And the Electron Bitdef as well: +typedef BitdefElectron_v1 BitdefElectron; + +} // namespace Ringer + +#endif // RINGERSELECTORTOOLS_ELECTRONTACCEPT_H + + +#endif // RINGER_STANDALONE diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/IAsgElectronRingerSelector.h b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/IAsgElectronRingerSelector.h new file mode 100644 index 0000000000000000000000000000000000000000..5e120f38ac53adf7bf0eca4f974d3f85a38c916e --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/IAsgElectronRingerSelector.h @@ -0,0 +1,95 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: IAsgElectronRingerSelector.h 704615 2015-10-29 18:50:12Z wsfreund $ +#ifndef RINGERSELECTORTOOLS_IASGELECTRONRINGERSELECTOR_H +#define RINGERSELECTORTOOLS_IASGELECTRONRINGERSELECTOR_H + +/** + * @class IAsgElectronRingerSelector + * @brief Interface to select electrons using Ringer information + * + * @author Werner Freund <wsfreund@cern.ch> + * @date Nov 2014 + * + **/ + +// STL includes +#include<vector> + +// Include the interfaces +#include "PATCore/IAsgSelectionTool.h" + +// Include the return object and the underlying ROOT tool +#include "PATCore/TAccept.h" + +// Forward declarations: +#include "xAODEgamma/EgammaFwd.h" +#include "xAODEgamma/ElectronFwd.h" + +class IAsgElectronIsEMSelector; + +class IAsgElectronRingerSelector : virtual public IAsgSelectionTool +{ + + ASG_TOOL_INTERFACE(IAsgElectronRingerSelector) + + public: + + /** Virtual Destructor */ + virtual ~IAsgElectronRingerSelector() {}; + + /** The main accept method: using the generic interface */ + virtual const Root::TAccept& accept( const xAOD::IParticle* part ) const = 0; + + /** The main accept method: the actual cuts are applied here */ + virtual const Root::TAccept& accept( const xAOD::Electron* part ) const = 0; + + /** The main accept method: using the generic interface */ + virtual const Root::TAccept& accept( const xAOD::IParticle& part ) const = 0; + + /** The main accept method: the actual cuts are applied here */ + virtual const Root::TAccept& accept( const xAOD::Electron& part ) const = 0; + + /** The basic Ringer selector tool execution */ + virtual StatusCode execute(const xAOD::Electron* eg) const = 0; + + /** The Ringer selector tool execution for HLT */ + virtual StatusCode execute(const xAOD::Egamma* eg) const = 0; + + /** Get last executed TAccept answer */ + virtual const Root::TAccept& getTAccept() const = 0; + + /** Get last executed TResult value */ + virtual const std::vector<float>& getOutputSpace() const = 0; + + /** + * @brief Set the discrimination configuration file + **/ + virtual void setDiscrFile( const std::string path ) = 0; + + /** + * @brief Set the threshold configuration file + **/ + virtual void setThresFile( const std::string path ) = 0; + + /** + * @brief Set the threshold configuration file + **/ + virtual void setCutMask( const unsigned int cutMask ) = 0; + + /** + * @brief Set the CutIDSelector to be used + **/ + virtual void setCutIDSelector( IAsgElectronIsEMSelector *cutID ) = 0; + + /** + * @brief Set the RingSetConfContainer (MetaData) key + **/ + virtual void setRSMetaName( const std::string name ) = 0; + +}; + + +#endif // RINGERSELECTORTOOLS_IASGELECTRONRINGERSELECTOR_H diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/RingerSelectorToolsDefs.h b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/RingerSelectorToolsDefs.h new file mode 100644 index 0000000000000000000000000000000000000000..710261eee5c495175125c23080f8a8b781649e3e --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/RingerSelectorToolsDefs.h @@ -0,0 +1,190 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: RingerSelectorToolsDefs.h 704615 2015-10-29 18:50:12Z wsfreund $ +#ifndef RINGERSELECTORTOOLS_RINGERSELECTORTOOLSDEFS_H +#define RINGERSELECTORTOOLS_RINGERSELECTORTOOLSDEFS_H + +/** + * + * WARNING: Do not change the order of the enumerations for backward files + * compatibility!! + * + * This means that if a new value is needed, add it to the end (before the Nxxx + * enumeration) of the enumeration, instead of adding it to any place in the + * enumeration. + * + * After adding a enumeration type, also add it to the methods in the + * RingerSelectorToolsDefs.cxx file. + * + **/ + +/** + * @brief Namespace dedicated for Ringer utilities + **/ +namespace Ringer { + + +/** + * @brief the possible procedure longitudinal segmentation types. + * + * - NoSegmentation stands for a unique representation for all data. This may + * mean that the procedure: + * + * o is not applied for a pattern segment; + * + * o has a specialized implemented approach that works in distinct depths of + * the segmented information. + * + * o cannot be applied in a segmentation approach. This is the case whenever + * the procedure is not applied in the first layer or if the procedure is + * the application of a threshold. In another words, only the first + * PreProcessor and the first discriminator may have access to segmented + * information, the later only if its pre-processing chain does not affect + * the output segmentation. + * + * - TrackCalSegmentation will segmentate track (if information + * available) from calorimeter. + * + * - TrackCalPatTypeSegmentation will segmentate track (if information + * available) from calorimeter, the latter also being segmented between the + * standard calorimeter patterns and rings. + * + * - TrackCalJointSections will segmentate track (if information available) + * from calorimeter. Besides, the calorimeter information will be segmentated + * through CalJointSections (see xAODCaloRings/CaloRingsDefs.h). + * + * - TrackCalJointLayers will segmentate track (if information available) from + * calorimeter. Besides, the calorimeter information will be segmentated + * through CalJointLayers (see xAODCaloRings/CaloRingsDefs.h). + * + * If adding a new value on this enumeration, add it to the numberOfSegments + * function on RingerSelectorToolsDefs.cxx + **/ +enum SegmentationType { + NoSegmentation = 0, + TrackCalSegmentation, + TrackCalPatTypeSegmentation, + TrackCalJointSections, + TrackCalJointLayers, + NSegmentations +}; + +/** + * @brief Specify eta position dependency + * + * This specifies whether the discriminator will operate only for a small + * (bin) eta region or will operate for the full analysis region (generally the + * ATLAS precision region). + * + **/ +enum EtaDependency { + EtaIndependent = 0, + EtaDependent, + NEtaDependencies +}; + +/** + * @brief Specify et position dependency + * + * This specifies whether the discriminator will operate only for a small + * (bin) Et region or will operate for the full analysis region (generally the + * ATLAS precision region). + * + **/ +enum EtDependency { + EtIndependent = 0, + EtDependent, + NEtDependencies +}; + +/** + * @brief the cut requirement + **/ +enum Requirement { + Loose_CutID_Pd = 0, // Same detection probability as CutID Loose + Medium_CutID_Pd, // Same detection probability as CutID Medium + Tight_CutID_Pd, // Same detection probability as CutID Tight + Loose_CutID_Pf, // Same false alarm probability as CutID Loose + Medium_CutID_Pf, // Same false alarm probability as CutID Medium + Tight_CutID_Pf, // Same false alarm probability as CutID Tight + Loose_LH_Pd, // Same detection probability as LH Loose + Medium_LH_Pd, // Same detection probability as LH Medium + Tight_LH_Pd, // Same detection probability as LH Tight + Loose_LH_Pf, // Same false alarm probability as LH Loose + Medium_LH_Pf, // Same false alarm probability as LH Medium + Tight_LH_Pf, // Same false alarm probability as LH Tight + Medium_MaxSP, // Maximum SP-product + Loose, // Same as LooseCutIDPd + Medium, // Same as MediumSP + Tight, // Same as TightCutIDPf + NoCut, // Run to retrieve discriminators output, but no cut is applied + NRequirements // Number of Requirements available +}; + +/** + * Return number of segments for segment of type @name e. + **/ +unsigned numberOfSegments(const SegmentationType e); + +/** + * Return Ringer enumeration of type T identifying string type: + **/ +template<typename T> +T getType(const char* cStr); + +/** + * Specialization for SegmentationType + **/ +template<> +SegmentationType getType(const char* cStr); + +/** + * Specialization for EtaDependency + **/ +template<> +EtaDependency getType(const char* cStr); + +/** + * Specialization for EtDependency + **/ +template<> +EtDependency getType(const char* cStr); + +/** + * Specialization for Requirement + **/ +template<> +Requirement getType(const char* cStr); + +// Explicit instantiate the templates functions to avoid multiple definition +template SegmentationType getType(const char *); +template EtaDependency getType(const char *); +template EtDependency getType(const char *); +template Requirement getType(const char *); + +/** + * Transform enumeration types to string + **/ +const char* toStr(SegmentationType e); + +/** + * Transform enumeration types to string + **/ +const char* toStr(EtaDependency e); + +/** + * Transform enumeration types to string + **/ +const char* toStr(EtDependency e); + +/** + * Transform enumeration types to string + **/ +const char* toStr(Requirement e); + +} // namespace Ringer + +#endif // RINGERSELECTORTOOLS_RINGERSELECTORTOOLSDEFS_H + diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/RingerSelectorToolsDict.h b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/RingerSelectorToolsDict.h new file mode 100644 index 0000000000000000000000000000000000000000..e2d3d0b983a24ce37fb63ba8ecc7e10046bd0415 --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/RingerSelectorToolsDict.h @@ -0,0 +1,134 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: RingerSelectorToolsDict.h 704615 2015-10-29 18:50:12Z wsfreund $ +#ifndef RINGERSELECTORTOOLS_RINGERSELECTORTOOLSDICT_H +#define RINGERSELECTORTOOLS_RINGERSELECTORTOOLSDICT_H + +#include <vector> + +#include "RingerSelectorTools/RingerSelectorToolsDefs.h" + +#include "RingerSelectorTools/tools/cxx/RingerUseNewCppFeatures.h" + +// These are only available if we are not in a standalone environment. +#ifndef RINGER_STANDALONE +#include "RingerSelectorTools/tools/RingerCommonSelector.h" +#include "RingerSelectorTools/AsgElectronRingerSelector.h" +#endif + +#include "RingerSelectorTools/tools/RedirectMsgStream.h" + +#include "RingerSelectorTools/tools/VariableDependency.h" +#include "RingerSelectorTools/tools/RingerIOVarDepObj.h" +#include "RingerSelectorTools/tools/IOHelperFcns.h" + +#include "RingerSelectorTools/procedures/IRingerProcedure.h" +#include "RingerSelectorTools/procedures/Types.h" + +#include "RingerSelectorTools/procedures/RingerProcedureWrapper.h" + +#include "RingerSelectorTools/procedures/Normalizations.h" +#include "RingerSelectorTools/procedures/NeuralNetwork.h" +#include "RingerSelectorTools/procedures/Thresholds.h" + +/* +#define RINGER_DECLARE_VARDEP_T(name, inst_name) \ + name< Ringer::EtaDependent , Ringer::EtDependent > inst_name ## _etaDep_etDep; \ + name< Ringer::EtaDependent , Ringer::EtIndependent > inst_name ## _etaDep_etIndep; \ + name< Ringer::EtaIndependent , Ringer::EtDependent > inst_name ## _etaIndep_etDep; \ + name< Ringer::EtaIndependent , Ringer::EtIndependent > inst_name ## _etaIndep_etIndep; +*/ + +#define _RINGER_DECLARE_WRAPPER_T_WITH_SEG_TYPE_(type, segType, inst_name) \ + Ringer::RingerProcedureWrapper< type, Ringer::EtaDependent, Ringer::EtDependent, segType > inst_name ## _etaDep_etDep; \ + Ringer::RingerProcedureWrapper< type, Ringer::EtaIndependent, Ringer::EtDependent, segType > inst_name ## _etaIndep_etDep; \ + Ringer::RingerProcedureWrapper< type, Ringer::EtaDependent, Ringer::EtIndependent, segType > inst_name ## _etaDep_etIndep; \ + Ringer::RingerProcedureWrapper< type, Ringer::EtaIndependent, Ringer::EtIndependent, segType > inst_name ## _etaIndep_etIndep; + +#define RINGER_DECLARE_ONLYALLCALO_WRAPPER_T(type, inst_name) \ + _RINGER_DECLARE_WRAPPER_T_WITH_SEG_TYPE_(type, Ringer::NoSegmentation, inst_name ## _allCalo ) + +#define RINGER_DECLARE_ALLSEGTYPES_WRAPPER_T(type, inst_name) \ + _RINGER_DECLARE_WRAPPER_T_WITH_SEG_TYPE_(type, Ringer::NoSegmentation, inst_name ## _allCalo ) \ + _RINGER_DECLARE_WRAPPER_T_WITH_SEG_TYPE_(type, Ringer::TrackCalSegmentation, inst_name ## _trackCalSeg ) \ + /*_RINGER_DECLARE_WRAPPER_T_WITH_SEG_TYPE_(type, Ringer::TrackCalPatTypeSegmentation, inst_name ## _trackCalSeg )*/ \ + _RINGER_DECLARE_WRAPPER_T_WITH_SEG_TYPE_(type, Ringer::TrackCalJointSections, inst_name ## _jSec ) \ + _RINGER_DECLARE_WRAPPER_T_WITH_SEG_TYPE_(type, Ringer::TrackCalJointLayers, inst_name ## _jLay ) + +template void Ringer::IOHelperFcns::readVar<Ringer::EtaDependency,unsigned>(TDirectory*, const char*, Ringer::EtaDependency&); +template void Ringer::IOHelperFcns::readVar<Ringer::EtDependency,unsigned>(TDirectory*, const char*, Ringer::EtDependency&); +template void Ringer::IOHelperFcns::readVar<Ringer::SegmentationType,unsigned>(TDirectory*, const char*, Ringer::SegmentationType&); +template void Ringer::IOHelperFcns::readVar<Ringer::PreProcessing::Type::PreProcessorTypes,unsigned>(TDirectory*, const char*, Ringer::PreProcessing::Type::PreProcessorTypes&); +template void Ringer::IOHelperFcns::readVar<Ringer::Discrimination::Type::DiscriminatorTypes,unsigned>(TDirectory*, const char*, Ringer::Discrimination::Type::DiscriminatorTypes&); +template void Ringer::IOHelperFcns::readVar<Ringer::Discrimination::Type::ThresholdTypes,unsigned>(TDirectory*, const char*, Ringer::Discrimination::Type::ThresholdTypes&); +template void Ringer::IOHelperFcns::readVar(TDirectory*, const char*, unsigned&); +template void Ringer::IOHelperFcns::readVar(TDirectory*, const char*, float&); +//-------------- For now, we also include the write variable methods +template void Ringer::IOHelperFcns::writeVar<const Ringer::EtaDependency,const unsigned>(TDirectory*, const char*, const Ringer::EtaDependency&); +template void Ringer::IOHelperFcns::writeVar<const Ringer::EtDependency,const unsigned>(TDirectory*, const char*, const Ringer::EtDependency&); +template void Ringer::IOHelperFcns::writeVar<const Ringer::SegmentationType,const unsigned>(TDirectory*, const char*, const Ringer::SegmentationType&); +template void Ringer::IOHelperFcns::writeVar<const Ringer::PreProcessing::Type::PreProcessorTypes,const unsigned>(TDirectory*, const char*, const Ringer::PreProcessing::Type::PreProcessorTypes&); +template void Ringer::IOHelperFcns::writeVar<const Ringer::Discrimination::Type::DiscriminatorTypes,const unsigned>(TDirectory*, const char*, const Ringer::Discrimination::Type::DiscriminatorTypes&); +template void Ringer::IOHelperFcns::writeVar<const Ringer::Discrimination::Type::ThresholdTypes,const unsigned>(TDirectory*, const char*, const Ringer::Discrimination::Type::ThresholdTypes&); +template void Ringer::IOHelperFcns::writeVar(TDirectory*, const char*, unsigned&); +template void Ringer::IOHelperFcns::writeVar(TDirectory*, const char*, float&); +//--------------------------------------------------------------------- + +namespace RingerSelectorToolsDict { + +struct dict { + + //std::vector<long long> m_vecLongLong; + //std::vector<unsigned long long> m_vecULongLong; + //std::vector<unsigned long> m_vecULong; + //std::vector<Ringer::EtaDependency> m_vecEtaDep; + std::vector<Ringer::PreProcessing::Norm::Norm1VarDep*> m_vecNorm1; + std::vector<std::vector<Ringer::PreProcessing::Norm::Norm1VarDep*> > m_vecVecNorm1; + + std::vector<Ringer::Discrimination::NNFeedForwardVarDep*> m_vecNN; + std::vector<std::vector<Ringer::Discrimination::NNFeedForwardVarDep*> > m_vecVecNN; + + //Ringer::RingerProcedureWrapper<Ringer::PreProcessing::Norm1VarDep, + // Ringer::EtaIndependent, + // Ringer::EtIndependent, + // Ringer::NoSegmentation> discrDummy; + + /// Wrappers + /// @{ + // Add all interface wrappers: + RINGER_DECLARE_ALLSEGTYPES_WRAPPER_T(Ringer::PreProcessing::IPreProcessorVarDep, iwrap_ipp) + RINGER_DECLARE_ALLSEGTYPES_WRAPPER_T(Ringer::Discrimination::IDiscriminatorVarDep, iwrap_idiscr) + //RINGER_DECLARE_ONLYALLCALO_WRAPPER_T(Ringer::Discrimination::IThresholdVarDep, iwrap_ithres) + // Now we add some the specialized procedure wrappers: + // Norm1: + RINGER_DECLARE_ONLYALLCALO_WRAPPER_T(Ringer::PreProcessing::Norm::Norm1VarDep, norm1) + // NNFeedForward: + RINGER_DECLARE_ONLYALLCALO_WRAPPER_T(Ringer::Discrimination::NNFeedForwardVarDep, nnff) + // UniqueThreshold + RINGER_DECLARE_ONLYALLCALO_WRAPPER_T(Ringer::Discrimination::UniqueThresholdVarDep, uniqueThres) + /// @} + +}; + +} // private namespace + + +#ifdef G__DICTIONARY // ROOT6 dictionary compilation +#if ROOT_VERSION_CODE >= ROOT_VERSION(6,0,0) +// MN: pull in the Ringer enums and variables for ROOT6 on dictionary library loading +#include "TInterpreter.h" +namespace Ringer { + struct DeclareHeader { + DeclareHeader() { + gInterpreter->Declare("#include \"RingerSelectorTools/RingerSelectorToolsDefs.h\""); + gInterpreter->Declare("#include \"RingerSelectorTools/procedures/Types.h\""); + gInterpreter->Declare("#include \"RingerSelectorTools/tools/IOHelperFcns.h\""); + } + } declareHeader; +} +#endif +#endif + +#endif // RINGERSELECTORTOOLS_RINGERSELECTORTOOLSDICT_H diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/procedures/IRingerProcedure.h b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/procedures/IRingerProcedure.h new file mode 100644 index 0000000000000000000000000000000000000000..d3fad5933140e73723f6935bc23a3b594646d0a7 --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/procedures/IRingerProcedure.h @@ -0,0 +1,402 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: IRingerProcedure.h 694257 2015-09-10 22:45:27Z wsfreund $ +#ifndef RINGERSELECTORTOOLS_PROCEDURES_IPROCEDURE_H +#define RINGERSELECTORTOOLS_PROCEDURES_IPROCEDURE_H + +// STL includes: +#include <vector> + +// Root includes: +#include <TDirectory.h> +//#include <TClass.h> + +// Local includes: +#include "RingerSelectorTools/tools/VariableDependency.h" +#include "RingerSelectorTools/tools/IRedirectMsgStream.h" +#include "RingerSelectorTools/tools/cxx/StaticAssert.h" +#include "RingerSelectorTools/tools/cxx/is_base_of.h" +#include "RingerSelectorTools/tools/cxx/conditional.h" +#include "RingerSelectorTools/tools/cxx/enable_if.h" + +#ifndef INCLUDE_HEADER_ONLY +#define INCLUDE_HEADER_ONLY +#endif // INCLUDE_HEADER_ONLY +#include "RingerSelectorTools/procedures/Types.h" +#undef INCLUDE_HEADER_ONLY + +/** + * Define ringer interface default methods + * + * It defines static template member type, that can be used to retrieve + * procedure type as an enumeration type. In order for this to work, make sure + * to add the enumeration value on Types.h file and add it properly to the + * conversion string<->enumeration function in the Types.cxx file. + * + * Beware that it changes scope inside class to public. + * + **/ +#define RINGER_DEFINE_INTERFACE(self) \ + \ + public: \ + \ + template <typename T = const char*> \ + static T procType(); \ + \ + virtual const char* name() const = 0; \ + \ + virtual void print(MSG::Level lvl) const = 0; + +/** + * Define Ringer interface procedure type methods. + **/ +#define RINGER_DEFINE_INTERFACE_DEFAULT_METHODS(self) \ + \ + template<> \ + inline \ + const char* self::procType() \ + { \ + return #self; \ + } \ + \ + template<> \ + inline \ + Ringer::RingerProcedureType<self>::procEnum_t self::procType() \ + { \ + return Ringer::getType< \ + Ringer::RingerProcedureType<self>::procEnum_t>(#self); \ + } + +#define __RINGER_DEFINE_PROCEDURE_STANDARD_METHODS__(self) \ + \ + virtual const char* name() const \ + ATH_RINGER_OVERRIDE; + +/** + * Use this macro when procedure has member properties + **/ +#define RINGER_DEFINE_PROCEDURE(self) \ + \ + public: \ + __RINGER_DEFINE_PROCEDURE_STANDARD_METHODS__(self) \ + \ + virtual void print(MSG::Level lvl) const \ + ATH_RINGER_OVERRIDE; + +/** + * Use this macro when procedure hasn't member properties + **/ +#define RINGER_DEFINE_NOMEMBER_PROCEDURE(self) \ + \ + public: \ + __RINGER_DEFINE_PROCEDURE_STANDARD_METHODS__(self) \ + \ + virtual void print(MSG::Level lvl) const \ + ATH_RINGER_OVERRIDE \ + { \ + if ( !this->isStreamAvailable() ) { \ + std::cerr << "Cannot print " << this->name() << ", stream unavailable" \ + << std::endl; \ + } \ + if ( this->level() > lvl ) { \ + return; \ + } \ + ATH_MSG_LVL(lvl, "Procedure hasn't any property."); \ + } +/// @} + +/** + * This macro should be defined for every Ringer Procedure defined after the + * class is defined, within same scope and translation unit where it is + * defined. + * + * You will have to define the procedure print method yourself. + **/ +#define RINGER_DEFINE_PROCEDURE_DEFAULT_METHODS(self) \ + \ + /*RINGER_DEFINE_INTERFACE_DEFAULT_METHODS(self)*/ \ + \ + inline \ + const char* self::name() const \ + { \ + return this->procType<const char*>(); \ + } + + + +/** + * @brief Namespace dedicated for Ringer utilities + **/ +namespace Ringer { + +// Declare interface base for all Ringer procedure types: +// +/** + * @class IRingerProcedure + * @brief The base interface for all Ringer procedures. + * + * Note: Every Ringer Procedure redirects message stream + **/ +class IRingerProcedure : virtual public IRedirectMsgStream { + public: + /** + * @brief Write Ringer procedure to configuration directory + **/ + virtual void write(TDirectory *configDir, const char*idxStr = "") + const = 0; + + /** Ensures virtual dtor for all inherited classes */ + virtual ~IRingerProcedure(){;} + + protected: + + /** Define it as a Root TObjebt, disable I/O */ + //ClassDef(IRingerProcedure,0) +}; + +// Forward declare base procedure types: +namespace PreProcessing { + class IPreProcessor; + class IPreProcessorVarDep; +} + +namespace Discrimination { + class IDiscriminator; + class IDiscriminatorVarDep; + class IThreshold; + class IThresholdVarDep; +} + +/** + * @class RingerProcedureType + * @brief Check Ringer Procedure type. + * + * Only available to this translation unit. + * + * - Use RingerProcedure<Procedure>::is_pre_processor to get if procedure is + * of pre-processing type + * + * - Use RingerProcedure<Procedure>::is_discriminator to get if procedure is + * of discriminator type + * + * - Use RingerProcedure<Procedure>::is_threshold to get if procedure is + * of threshold type + **/ +template<typename procedure_t > +struct RingerProcedureType { + + RINGER_STATIC_ASSERT( (Ringer::is_base_of<IRingerProcedure,procedure_t>::value), + "Requested to check Ringer procedure type from class that is not a IRingerProcedure."); + + // Determine which procedure type it is: +#if RINGER_USE_NEW_CPP_FEATURES || defined(FORCE_RINGER_PROCEDURE_TYPE_CONST_EXPR) + static constexpr bool is_pre_processor = + Ringer::is_base_of<PreProcessing::IPreProcessor,procedure_t>::value; + static constexpr bool is_discriminator = + Ringer::is_base_of<Discrimination::IDiscriminator,procedure_t>::value; + static constexpr bool is_threshold = + Ringer::is_base_of<Discrimination::IThreshold,procedure_t>::value; + + RINGER_STATIC_ASSERT( ( is_pre_processor || is_discriminator || is_threshold ), + "Couldn't find a procedure type."); + + // Determine which enumType it should have been declared + typedef typename Ringer::conditional< is_pre_processor, + preProcEnum_t, // true, it is_pre_processor + typename Ringer::conditional< is_discriminator, + discrEnum_t, // true, it is discriminator + thresEnum_t >::type >::type procEnum_t; + + // Boolean to determine whether this procedure inherits from VariableDependency + static constexpr bool inherits_from_var_dep = Ringer::is_base_of< VariableDependency, + procedure_t>::value; + + // Determine which interface this Ringer procedure inherits from + typedef typename Ringer::conditional< is_pre_processor, + // true, it is_pre_processor + typename Ringer::conditional< inherits_from_var_dep, + PreProcessing::IPreProcessorVarDep, PreProcessing::IPreProcessor>::type, + // not pre_processor, check if is_discriminator + typename Ringer::conditional< is_discriminator, + // true, it is_discriminator + typename Ringer::conditional< inherits_from_var_dep, + Discrimination::IDiscriminatorVarDep, Discrimination::IDiscriminator>::type, + // otherwise it has to be threshold + typename Ringer::conditional< inherits_from_var_dep, + Discrimination::IThresholdVarDep, Discrimination::IThreshold>::type + >::type + >::type baseInterface_t; + +#else + static const bool is_pre_processor; + static const bool is_discriminator; + static const bool is_threshold; +#endif +}; + +/** + * @brief RingerProcedureType specialization to ensure that procedure_t is not + * a pointer + **/ +template<typename procedure_t > +struct RingerProcedureType<procedure_t*> : public RingerProcedureType<procedure_t>{ }; + +/** + * @brief Namespace dedicated for Ringer pre-processing utilities + **/ +namespace PreProcessing { + +/** + * @brief PreProcessing interface to be inherited by PreProcessing procedures. + **/ +class IPreProcessor : virtual public IRingerProcedure +{ + + RINGER_DEFINE_INTERFACE( IPreProcessor ) + + protected: + /** Note: https://sft.its.cern.ch/jira/browse/CFHEP-87 */ + IPreProcessor& operator=(IPreProcessor&&); + public: + /** + * @brief Execute transform @name inputSpace to a new space representation. + **/ + virtual void execute(std::vector<float> &inputSpace) const = 0; + + /** Define it as a Root TObjebt, disable I/O */ + //ClassDef(IPreProcessor,0) +}; + +/** + * @brief PreProcessor interface to be used by Ringer Wrapper. + **/ +class IPreProcessorVarDep : public virtual VariableDependency, + public virtual IPreProcessor +{ + + RINGER_DEFINE_INTERFACE( IPreProcessorVarDep ) + + protected: + /** Note: https://sft.its.cern.ch/jira/browse/CFHEP-87 */ + IPreProcessorVarDep& operator=(IPreProcessorVarDep&&); + public: + //IPreProcessorVarDep(){;} + + // This is needed for parsing wrapper + static IPreProcessorVarDep* read(TDirectory *){ return nullptr;} + + /** Define it as a Root TObjebt, disable I/O */ + //ClassDef(IPreProcessorVarDep,0) +}; + +} // namespace PreProcessor + +/** + * @brief Namespace dedicated for Ringer Discrimination utilities + **/ +namespace Discrimination { + +/** + * @brief Discriminator interface to be inherited by discrimination procedures. + **/ +class IDiscriminator : virtual public IRingerProcedure +{ + + RINGER_DEFINE_INTERFACE( IDiscriminator ) + + protected: + /** Note: https://sft.its.cern.ch/jira/browse/CFHEP-87 */ + IDiscriminator& operator=(IDiscriminator&&); + public: + virtual void execute(const std::vector<float> &input, + std::vector<float> &output) const = 0; + + /** Define it as a Root TObjebt, disable I/O */ + //ClassDef(IDiscriminator,0) +}; + +/** + * @brief Discriminator interface to be used by Ringer Wrapper. + **/ +class IDiscriminatorVarDep : public virtual VariableDependency, + public virtual IDiscriminator +{ + + RINGER_DEFINE_INTERFACE( IDiscriminatorVarDep ) + + protected: + /** Note: https://sft.its.cern.ch/jira/browse/CFHEP-87 */ + IDiscriminatorVarDep& operator=(IDiscriminatorVarDep&&); + public: + //IDiscriminatorVarDep(){;} + + // This prototype is needed for parsing wrapper + static IDiscriminatorVarDep* read(TDirectory *){ return nullptr;} + + /** Define it as a Root TObjebt, disable I/O */ + //ClassDef(IDiscriminatorVarDep,0) +}; + +/** + * @brief Threshold interface to be inherited by thresholding procedures. + **/ +class IThreshold : virtual public IRingerProcedure +{ + + RINGER_DEFINE_INTERFACE( IThreshold ) + + protected: + /** Note: https://sft.its.cern.ch/jira/browse/CFHEP-87 */ + IThreshold& operator=(IThreshold&&); + public: + /** + * @brief Execute threshold for input and retrieve throw output. + **/ + virtual void execute(const std::vector<float> &input, + std::vector<bool> &output) const = 0; + + /** Define it as a Root TObjebt, disable I/O */ + //ClassDef(IThreshold,0) +}; + +/** + * @brief Threshold interface to be used by Ringer Wrapper. + **/ +class IThresholdVarDep : public virtual VariableDependency, + public virtual IThreshold +{ + + RINGER_DEFINE_INTERFACE( IThresholdVarDep ) + + protected: + /** Note: https://sft.its.cern.ch/jira/browse/CFHEP-87 */ + IThresholdVarDep& operator=(IThresholdVarDep&&); + public: + //IThresholdVarDep(){;} + + // This prototype is needed for parsing wrapper + static IThresholdVarDep* read(TDirectory *){ return nullptr;} + + /** Define it as a Root TObjebt, disable I/O */ + //ClassDef(IThresholdVarDep,0) +}; + +} // namespace Discrimination + +// Declare procedure type member functions +namespace PreProcessing { +RINGER_DEFINE_INTERFACE_DEFAULT_METHODS( IPreProcessor ) +RINGER_DEFINE_INTERFACE_DEFAULT_METHODS( IPreProcessorVarDep ) +} // namespace PreProcessing +namespace Discrimination { +RINGER_DEFINE_INTERFACE_DEFAULT_METHODS( IThreshold ) +RINGER_DEFINE_INTERFACE_DEFAULT_METHODS( IThresholdVarDep ) +RINGER_DEFINE_INTERFACE_DEFAULT_METHODS( IDiscriminator ) +RINGER_DEFINE_INTERFACE_DEFAULT_METHODS( IDiscriminatorVarDep ) +} // namespace Discrimination + +} // namespace Ringer + +#endif // RINGERSELECTORTOOLS_PROCEDURES_IPROCEDURE_H diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/procedures/NeuralNetwork.h b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/procedures/NeuralNetwork.h new file mode 100644 index 0000000000000000000000000000000000000000..632faf5fcbc2b8b94f3308943561381e695445a1 --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/procedures/NeuralNetwork.h @@ -0,0 +1,150 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: NeuralNetwork.h 693248 2015-09-04 17:52:57Z wsfreund $ +#ifndef RINGERSELECTORTOOLS_PROCEDURES_NEURALNETWORK_H +#define RINGERSELECTORTOOLS_PROCEDURES_NEURALNETWORK_H + +//#undef NDEBUG + +// STL includes: +#include <vector> + +// Local includes: +#include "RingerSelectorTools/procedures/IRingerProcedure.h" + +// Local tool includes: +#include "RingerSelectorTools/tools/RingerIOVarDepObj.h" +#include "RingerSelectorTools/tools/RedirectMsgStream.h" +#include "RingerSelectorTools/tools/cxx/final.h" +#include "RingerSelectorTools/tools/cxx/override.h" + +namespace Ringer { + + +namespace Discrimination { + +/** + * @class NNFeedForward + * @brief Provides Neural Network FeedForward + * + * @author: Dhiana Deva Cavalcanti Rocha <dhiana.deva@gmail.com> (LPS/UFRJ) + * @author: Werner S. Freund <wsfreund@cern.ch> (LPS/UFRJ) + * (revised implementation) + * + * @date: Jan 2015 + **/ +class NNFeedForward : virtual public IDiscriminator, + public RedirectMsgStream +{ + + RINGER_IO_VARDEP_BASE( NNFeedForward ) + + public: + /** + * @brief Main ctor + **/ + NNFeedForward(const std::vector<unsigned int> &nodes, + const std::vector<float> &weights, + const std::vector<float> &bias); + + NNFeedForward(): m_nLayers(0), + m_wM(nullptr), + m_bM(nullptr), + m_mM(nullptr){;} + /** + * @brief Propagates input through neural network + **/ + virtual void execute(const std::vector<float> &input, + std::vector<float> &output) const ATH_RINGER_OVERRIDE ATH_RINGER_FINAL; + + void changeArchiteture(const std::vector<unsigned int> &nodes, + const std::vector<float> &weights, + const std::vector<float> &bias); + + /** + * @brief Main dtor + **/ + ~NNFeedForward(); + + protected: + /** + * Release bias memory + **/ + void releaseBias(); + + /** + * Release weights memory + **/ + void releaseWeights(); + + /** + * Release multiplication matrix memory + **/ + void releaseMMatrix(); + + /** + * Get m_wM and m_bM on std::vector unique dimension representation: + **/ + void getWeigthsAndBias(std::vector<float> &weights, + std::vector<float> &bias) const; + + private: + + /// @brief Neural network nodes size description + std::vector<unsigned int> m_nodes; + /// @brief Neural network number of layers + size_t m_nLayers; + /// @brief Neural network weights + float ***m_wM; + /// @brief Neural network bias + float **m_bM; + /// @brief Temporary multiplication matrix + float **m_mM; + + /** Define it as a Root TObjebt, disable I/O */ + //ClassDef(NNFeedForward,0) +}; + +RINGER_DEFINE_PROCEDURE_DEFAULT_METHODS( NNFeedForward ) + +/** + * @class NNFeedForwardVarDep + * @brief Provides Neural Network FeedForward mechanism. + * + * @author: Werner S. Freund <wsfreund@cern.ch> (LPS/UFRJ) + * @author: Dhiana Deva Cavalcanti Rocha <dhiana.deva@gmail.com> (LPS/UFRJ) + * + * @date: Jan 2015 + **/ +class NNFeedForwardVarDep : virtual public IDiscriminatorVarDep, + public RingerIOVarDepObj < NNFeedForwardVarDep >, + public NNFeedForward +{ + + RINGER_IO_VARDEP_OBJ(NNFeedForwardVarDep, NNFeedForward) + + public: + + /** + * Main ctor + **/ + NNFeedForwardVarDep(const std::vector<unsigned int> &nodes, + const std::vector<float> &weights, + const std::vector<float> &bias): + NNFeedForward(nodes,weights,bias){;} + + /** + * Empty ctor + **/ + NNFeedForwardVarDep(){;} + + /** Define it as a Root TObjebt, set version 1 */ + //ClassDef(NNFeedForwardVarDep,1) +}; + +} // namespace Discrimination +} // namespace Ringer + +#endif // RINGERSELECTORTOOLS_NEURALNETWORK_H diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/procedures/Normalizations.h b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/procedures/Normalizations.h new file mode 100644 index 0000000000000000000000000000000000000000..c2ddafc05389206035b4d0768d277c7bcfda2864 --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/procedures/Normalizations.h @@ -0,0 +1,428 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: Normalizations.h 704615 2015-10-29 18:50:12Z wsfreund $ +#ifndef RINGERSELECTORTOOLS_PROCEDURES_NORMALIZATIONS_H +#define RINGERSELECTORTOOLS_PROCEDURES_NORMALIZATIONS_H + +//#undef NDEBUG + +// STL includes: +#include <vector> +#include <stdexcept> +#include <string> +#include <cmath> +#include <iostream> + +// Gaudi includes: +#if !defined(XAOD_STANDALONE) && !defined(RINGER_STANDALONE) +# include "GaudiKernel/SystemOfUnits.h" +#endif + + +// Local includes: +#include "RingerSelectorTools/procedures/IRingerProcedure.h" +#include "RingerSelectorTools/tools/RingerIOVarDepObj.h" +#include "RingerSelectorTools/tools/VariableDependency.h" +#include "RingerSelectorTools/tools/RedirectMsgStream.h" +#include "RingerSelectorTools/tools/cxx/final.h" +#include "RingerSelectorTools/tools/cxx/override.h" + +/** + * @brief Namespace dedicated for Ringer utilities + **/ +namespace Ringer +{ + +/** +* @brief Namespace dedicated for Ringer pre-processing utilities +**/ +namespace PreProcessing +{ + +/** + * @brief Namespace dedicated for Ringer normalization utilities + **/ +namespace Norm { + +/// Normalization base classes: +/// @{ +class Norm1 : virtual public IPreProcessor, + public RedirectMsgStream +{ + + RINGER_IO_VARDEP_BASE_NOMEMBER( Norm1 ) + + private: + Norm1(Norm1&&); + + public: + Norm1(){;} + + virtual void execute(std::vector<float> &inputSpace) const ATH_RINGER_FINAL + ATH_RINGER_OVERRIDE; + + /** Define it as a Root TObjebt, disable I/O */ + //ClassDef(Norm1,1) +}; + +RINGER_DEFINE_PROCEDURE_DEFAULT_METHODS( Norm1 ) + +class Norm2 : public virtual IPreProcessor, + public RedirectMsgStream +{ + + RINGER_IO_VARDEP_BASE_NOMEMBER( Norm2 ) + + private: + Norm2(Norm2&&); + + public: + Norm2(){;} + + virtual void execute(std::vector<float> &inputSpace) const ATH_RINGER_FINAL + ATH_RINGER_OVERRIDE; + + /** Define it as a Root TObjebt, disable I/O */ + //ClassDef(Norm2,0) +}; + +RINGER_DEFINE_PROCEDURE_DEFAULT_METHODS( Norm2 ) + +class Sqrt : public virtual IPreProcessor, + public RedirectMsgStream +{ + + RINGER_IO_VARDEP_BASE_NOMEMBER( Sqrt ) + + private: + Sqrt(Sqrt&&); + + public: + Sqrt(){}; + + virtual void execute(std::vector<float> &inputSpace) const ATH_RINGER_FINAL + ATH_RINGER_OVERRIDE; + + /** Define it as a Root TObjebt, disable I/O */ + //ClassDef(Sqrt,0) +}; + +RINGER_DEFINE_PROCEDURE_DEFAULT_METHODS( Sqrt ) + +class ConstantValue : public virtual IPreProcessor, + public RedirectMsgStream +{ + + RINGER_IO_VARDEP_BASE( ConstantValue ) + + private: + ConstantValue(ConstantValue&&); + /// Inverse value of the constant value normalization + float m_constantInv; + + public: + + ConstantValue() + : m_constantInv(1){;} + ConstantValue( + const float constantValue) + : m_constantInv(1/constantValue) + { + if (!m_constantInv) { + throw std::runtime_error( + std::string("Initialized ConstantValueVarDep norm with zero constant")); + } + } + + virtual void execute(std::vector<float> &inputSpace) const ATH_RINGER_FINAL + ATH_RINGER_OVERRIDE; + + /** Define it as a Root TObjebt, disable I/O */ + //ClassDef(ConstantValue,0) +}; + +RINGER_DEFINE_PROCEDURE_DEFAULT_METHODS( ConstantValue ) + +class Sequential : public virtual IPreProcessor, + public RedirectMsgStream +{ + RINGER_IO_VARDEP_BASE( Sequential ) + + private: + Sequential(Sequential&&); + /// @brief The stop energy threshold for increasing noise + float m_stopEnergy; + /// @brief The energy threshold for choosing + float m_energyThres; + + public: + + Sequential() + : m_stopEnergy(0), + m_energyThres(0){;} + + Sequential( + const float stopEnergy, + const float energyThres) + : m_stopEnergy(stopEnergy), + m_energyThres(energyThres){;} + + virtual void execute(std::vector<float> &inputSpace) const ATH_RINGER_FINAL + ATH_RINGER_OVERRIDE; + + /** Define it as a Root TObjebt, disable I/O */ + //ClassDef(Sequential,0) +}; + +RINGER_DEFINE_PROCEDURE_DEFAULT_METHODS( Sequential ) + +class Spherization : public virtual IPreProcessor, + public RedirectMsgStream +{ + RINGER_IO_VARDEP_BASE( Spherization ) + + private: + Spherization(Spherization&&); + /// @brief The training sample data mean + std::vector<float> m_deslocation; + /// @brief The inverse of the training sample data standard deviation + std::vector<float> m_normInv; + /// Input dimension (transient variable) + size_t m_dim; + public: + + Spherization() + : m_dim(0){;} + + Spherization( + const std::vector<float> &dataMean, + const std::vector<float> &dataStd); + + virtual void execute(std::vector<float> &inputSpace) const ATH_RINGER_FINAL + ATH_RINGER_OVERRIDE; + + /** Define it as a Root TObjebt, disable I/O */ + //ClassDef(Spherization,0) +}; + +RINGER_DEFINE_PROCEDURE_DEFAULT_METHODS( Spherization ) + +class MinMax : public virtual IPreProcessor, + public RedirectMsgStream +{ + RINGER_IO_VARDEP_BASE( MinMax ) + + private: + MinMax(MinMax&&); + /// @brief The training sample data min + std::vector<float> m_deslocation; + /// @brief The inverse of sample delta(max,min) + std::vector<float> m_normInv; + /// Input dimension (transient variable) + size_t m_dim; + public: + MinMax() + : m_dim(0){;} + + MinMax( + const std::vector<float> min, + const std::vector<float> max); + public: + + virtual void execute(std::vector<float> &inputSpace) const ATH_RINGER_FINAL + ATH_RINGER_OVERRIDE; + + /** Define it as a Root TObjebt, disable I/O */ + //ClassDef(MinMax,0) +}; + +RINGER_DEFINE_PROCEDURE_DEFAULT_METHODS( MinMax ) +/// @} + +/// @ Usable normalizations: +/// @{ +/** + * @brief Use norm-1 as rings normalization factor + **/ +class Norm1VarDep : virtual public IPreProcessorVarDep, + public RingerIOVarDepObj < Norm1VarDep >, + public Norm1 +{ + RINGER_IO_VARDEP_OBJ(Norm1VarDep, Norm1) + + public: + + Norm1VarDep(){;} + + /** Define it as a Root TObjebt, set version 1 */ + //ClassDef(Norm1VarDep,1) +}; + +/** + * @brief Use norm-2 as rings normalization factor + **/ +class Norm2VarDep : virtual public IPreProcessorVarDep, + public RingerIOVarDepObj < Norm2VarDep >, + public Norm2 +{ + + RINGER_IO_VARDEP_OBJ(Norm2VarDep, Norm2) + + public: + + Norm2VarDep(){;} + + /** Define it as a Root TObjebt, set version 1 */ + //ClassDef(Norm2VarDep,1) +}; + +/** + * @brief Use SqrtVarDep of norm-1 as rings normalization factor + **/ +class SqrtVarDep : virtual public IPreProcessorVarDep, + public RingerIOVarDepObj < SqrtVarDep >, + public Sqrt +{ + + RINGER_IO_VARDEP_OBJ(SqrtVarDep, Sqrt) + + public: + + SqrtVarDep(){;} + + /** Define it as a Root TObjebt, set version 1 */ + //ClassDef(SqrtVarDep,1) +}; + +/** + * @brief Use constant value as rings normalization factor + **/ +class ConstantValueVarDep : virtual public IPreProcessorVarDep, + public RingerIOVarDepObj < ConstantValueVarDep >, + public ConstantValue +{ + + RINGER_IO_VARDEP_OBJ(ConstantValueVarDep, ConstantValue) + + public: + + ConstantValueVarDep(){;} + + ConstantValueVarDep(const float constantValue) + : ConstantValue(constantValue){;} + + /** Define it as a Root TObjebt, set version 1 */ + //ClassDef(ConstantValueVarDep,1) +}; + +/** + * @brief Scale rings energy to GeV + **/ +class MevToGevVarDep: virtual public IPreProcessorVarDep, + public RingerIOVarDepObj < MevToGevVarDep >, + public ConstantValue +{ + + RINGER_IO_VARDEP_OBJ(MevToGevVarDep, ConstantValue) + + public: + + // Normalization is the inverse of the Units transformation (MeV -> GeV) +#if !defined(XAOD_STANDALONE) && !defined(RINGER_STANDALONE) + MevToGevVarDep() + : ConstantValue( (Gaudi::Units::GeV) / (Gaudi::Units::MeV) ){;} +#else // We suppose that we are working with MeV as reference unit. + MevToGevVarDep() + : ConstantValue( 1000 / 1 ){;} +#endif + + /** Define it as a Root TObjebt, set version 1 */ + //ClassDef(MevToGevVarDep,1) +}; + +/** + * @brief Use sequential normalization. + * + * For more information check: + * + * https://svnweb.cern.ch/trac/atlasoff/browser/Trigger/TrigHypothesis/TrigMultiVarHypo/trunk/TrigMultiVarHypo/TrigRingerNeuralFex.h#L140 + **/ +class SequentialVarDep : virtual public IPreProcessorVarDep, + public RingerIOVarDepObj < SequentialVarDep >, + public Sequential +{ + + RINGER_IO_VARDEP_OBJ(SequentialVarDep, Sequential) + + public: + + SequentialVarDep(){;} + + SequentialVarDep( + const float stopEnergy, + const float energyThres): + Sequential(stopEnergy,energyThres){;} + + /** Define it as a Root TObjebt, set version 1 */ + //ClassDef(SequentialVarDep,1) +}; + +/** + * @brief Normalize data to have zero mean and unitary standard deviation. + **/ +class SpherizationVarDep : virtual public IPreProcessorVarDep, + public RingerIOVarDepObj < SpherizationVarDep >, + public Spherization +{ + + RINGER_IO_VARDEP_OBJ(SpherizationVarDep, Spherization) + + public: + + SpherizationVarDep(){;} + + SpherizationVarDep( + const std::vector<float> &dataMean, + const std::vector<float> &dataStd): + Spherization(dataMean,dataStd){;} + + /** Define it as a Root TObjebt, set version 1 */ + //ClassDef(SpherizationVarDep,1) +}; + +/** + * @brief Normalize data to be bounded within [-1,1] range. + **/ +class MinMaxVarDep : virtual public IPreProcessorVarDep, + public RingerIOVarDepObj < MinMaxVarDep >, + public MinMax +{ + RINGER_IO_VARDEP_OBJ(MinMaxVarDep, MinMax) + + public: + + MinMaxVarDep(){;} + + MinMaxVarDep( + const std::vector<float> &min, + const std::vector<float> &max): + MinMax(min,max){;} + + /** Define it as a Root TObjebt, set version 1 */ + //ClassDef(MinMaxVarDep,1) +}; +/// @} + +} // Norm namespace; +} // Pre-processing namespace; +} // Ringer namespace + + +#endif // RINGERSELECTORTOOLS_PROCEDURES_NORMALIZATIONS_H + +// Include inline and template declarations: +#ifndef INCLUDE_HEADER_ONLY // Protect against circular includes +#include "Normalizations.icc" +#endif // INCLUDE_HEADER_ONLY diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/procedures/Normalizations.icc b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/procedures/Normalizations.icc new file mode 100644 index 0000000000000000000000000000000000000000..8e0db0f305c9b496f7364dcd2b8807aac3cba1fe --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/procedures/Normalizations.icc @@ -0,0 +1,245 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: Normalizations.icc 667905 2015-05-18 19:07:55Z wsfreund $ +#ifndef RINGERSELECTORTOOLS_NORMALIZATIONS_ICC +#define RINGERSELECTORTOOLS_NORMALIZATIONS_ICC + +#include "Normalizations.h" +#include <cmath> +#include <limits> + +/** + * @brief Namespace dedicated for Ringer utilities + **/ +namespace Ringer +{ + +/** +* @brief Namespace dedicated for Ringer pre-processing utilities +**/ +namespace PreProcessing +{ + +/** + * @brief Namespace dedicated for Ringer normalization utilities + **/ +namespace Norm { + +/** + * @brief Helper functions: + **/ +namespace { + +// ============================================================================= +inline +float getMax( std::vector<float> &inputSpace ) { + float max = std::numeric_limits<float>::min(); + for ( std::vector<float>::const_iterator itr = inputSpace.begin(); + itr != inputSpace.end(); + ++itr){ + if (std::abs(*itr) > max) { + max = *itr; + } + } + return std::abs(max); +} + +// ============================================================================= +inline +float getNorm( std::vector<float> &inputSpace ){ + float norm = 0; + for ( std::vector<float>::const_iterator itr = inputSpace.begin(); + itr != inputSpace.end(); + ++itr){ + norm += *itr; + } + return std::abs(norm); +} + +// ============================================================================= +inline +float getNorm( std::vector<float> &inputSpace, const unsigned int p ){ + if ( p == 1) return getNorm(inputSpace); + float norm = 0; + for ( std::vector<float>::const_iterator itr = inputSpace.begin(); + itr != inputSpace.end(); + ++itr){ + norm += std::pow(*itr,p); + } + return std::abs(std::pow(norm,1/p)); +} + +// ============================================================================= +inline +void applyNorm( std::vector<float> &inputSpace, const float norm ){ + if (!norm) return; + float invNorm = 1/norm; + for ( std::vector<float>::iterator itr = inputSpace.begin(); + itr != inputSpace.end(); + ++itr){ + *itr *= invNorm; + } +} + +// ============================================================================= +inline +void applyInvNorm( std::vector<float> &inputSpace, const float invNorm ){ + for ( std::vector<float>::iterator itr = inputSpace.begin(); + itr != inputSpace.end(); + ++itr){ + *itr *= invNorm; + } +} + +// ============================================================================= +inline +void applyInvNorm( std::vector<float> &inputSpace, + const std::vector<float> &invNorm ) +{ + std::vector<float>::const_iterator itr2 = invNorm.begin(); + for ( std::vector<float>::iterator itr = inputSpace.begin(); + itr != inputSpace.end(); + ++itr, ++itr2) + { + *itr *= *itr2; + } +} + +// ============================================================================= +inline +void applyDeslocation( std::vector<float> &inputSpace, const float deslocation ) +{ + for ( std::vector<float>::iterator itr = inputSpace.begin(); + itr != inputSpace.end(); + ++itr) + { + *itr += deslocation; + } +} + +// ============================================================================= +inline +void applyDeslocation( std::vector<float> &inputSpace, + const std::vector<float> deslocation ) +{ + std::vector<float>::const_iterator itr2 = deslocation.begin(); + for ( std::vector<float>::iterator itr = inputSpace.begin(); + itr != inputSpace.end(); + ++itr, ++itr2) + { + *itr += *itr2; + } +} + +} // Private namespace + +/// Normalization interfaces: +/// @{ +// ============================================================================= +inline +void Norm1::execute(std::vector<float> &inputSpace) const { +#ifndef NDEBUG + ATH_MSG_DEBUG("Applying Norm1. Input space is: " << inputSpace); +#endif + float norm1 = getNorm(inputSpace,1); +#ifndef NDEBUG + ATH_MSG_DEBUG("Normalization factor is " << norm1 ); +#endif + applyNorm(inputSpace,norm1); +#ifndef NDEBUG + ATH_MSG_DEBUG("Pattern space is: " << inputSpace); +#endif +} + +// ============================================================================= +inline +void Norm2::execute(std::vector<float> &inputSpace) const { +#ifndef NDEBUG + ATH_MSG_DEBUG("Applying Norm2. Input space is: " << inputSpace); +#endif + float norm2 = getNorm(inputSpace,2); +#ifndef NDEBUG + ATH_MSG_DEBUG("Normalization factor is " << norm2 ); +#endif + applyNorm(inputSpace,norm2); +#ifndef NDEBUG + ATH_MSG_DEBUG("Pattern space is: " << inputSpace); +#endif +} + +// ============================================================================= +inline +void Sqrt::execute(std::vector<float> &inputSpace) const { +#ifndef NDEBUG + ATH_MSG_DEBUG("Applying Sqrt. Input space is: " << inputSpace); +#endif + float sqrtNorm = std::sqrt(std::fabs(getNorm(inputSpace,1))); +#ifndef NDEBUG + ATH_MSG_DEBUG("Normalization factor is " << sqrtNorm ); +#endif + applyNorm(inputSpace,sqrtNorm); +#ifndef NDEBUG + ATH_MSG_DEBUG("Pattern space is: " << inputSpace); +#endif +} + +// ============================================================================= +inline +void ConstantValue::execute(std::vector<float> &inputSpace) const { +#ifndef NDEBUG + ATH_MSG_DEBUG("Applying ConstantValue(Value: " << 1/m_constantInv + << "). Input space is: " << inputSpace); +#endif + applyInvNorm(inputSpace,m_constantInv); +#ifndef NDEBUG + ATH_MSG_DEBUG("Pattern space is: " << inputSpace); +#endif +} + +// ============================================================================= +inline +void Spherization::execute(std::vector<float> &inputSpace) const { +#ifndef NDEBUG + ATH_MSG_DEBUG("Applying Spherization. Input space is: " << inputSpace); +#endif + if ( inputSpace.size() != m_dim ){ + throw std::runtime_error(std::string( "Input size (") + + std::to_string(inputSpace.size()) + ") does not match " + " this pre-processing inputSpace dimension size(" + + std::to_string(m_dim) + "."); + } + applyDeslocation(inputSpace,m_deslocation); + applyInvNorm(inputSpace,m_normInv); +#ifndef NDEBUG + ATH_MSG_DEBUG("Pattern space is: " << inputSpace); +#endif +} + +// ============================================================================= +inline +void MinMax::execute(std::vector<float> &inputSpace) const { +#ifndef NDEBUG + ATH_MSG_DEBUG("Applying MinMax. Input space is: " << inputSpace); +#endif + if ( inputSpace.size() != m_dim ){ + throw std::runtime_error(std::string( "Input size (") + + std::to_string(inputSpace.size()) + ") does not match " + " this pre-processing inputSpace dimension size(" + + std::to_string(m_dim) + "."); + } + applyDeslocation(inputSpace,m_deslocation); + applyInvNorm(inputSpace,m_normInv); +#ifndef NDEBUG + ATH_MSG_DEBUG("Pattern space is: " << inputSpace); +#endif +} +/// @} + +} // namespace Norm +} // namespace Discrimination +} // namespace Ringer + +#endif // RINGERSELECTORTOOLS_NORMALIZATIONS_ICC +// vim: filetype=cpp : diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/procedures/RingerDiscriminatorWrapper.h b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/procedures/RingerDiscriminatorWrapper.h new file mode 100644 index 0000000000000000000000000000000000000000..04b2efa3622daf63cad4f7587354b4c96076c319 --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/procedures/RingerDiscriminatorWrapper.h @@ -0,0 +1,402 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: RingerDiscriminatorWrapper.h 713528 2015-12-09 08:58:44Z wsfreund $ +#ifndef RINGERSELECTORTOOLS_PROCEDURES_RINGERDISCRIMINATIONWRAPPER_H +#define RINGERSELECTORTOOLS_PROCEDURES_RINGERDISCRIMINATIONWRAPPER_H + +#define RINGER_PROCEDURE_INCLUDE +#include "RingerProcedureWrapper.h" +#undef RINGER_PROCEDURE_INCLUDE + +//#undef NDEBUG + +#define RINGER_DISCRIMINATOR_WRAPPER_INCLUDE +// We are also dependent on the PreProcessorWrapper, but we want only to define +// the collection for now: +#include "RingerPreProcessorWrapper.h" +#undef RINGER_DISCRIMINATOR_WRAPPER_INCLUDE + +/** + * @brief Namespace dedicated for Ringer utilities + **/ +namespace Ringer { + +/** + * @class IRingerProcedureWrapper + * @brief Specialization for Discriminator procedure. + **/ +template<> +class IRingerProcedureWrapper< Discrimination::IDiscriminator > : + virtual public IRedirectMsgStream, + virtual public IRingerProcedureWrapperBase +{ + public: + /** + * @brief Collection type of Discriminators Wrappers. + **/ + typedef typename std::vector< IRingerProcedureWrapper* > WrapperCollection; + + /// Main methods: + ///@{ +#ifndef RINGER_STANDALONE + /** + * @brief Apply discriminator to obtain its output representation + * + * This method will pass the information within xAOD::CaloRings and + * xAOD::TrackParticle to the pre-processors (if any) and + * afterwards feed the classifier. If any pointer if set to null, then it + * won't pass it into the classifier. Make sure to feed classifier with + * the same information it was adjusted to work with. + **/ + virtual void execute( + const DepVarStruct &depVar, + const xAOD::CaloRings *clrings, + const TrackPatternsHolder *trackPat, + std::vector<float> &output) const = 0; + + /** + * @brief Set the holden CaloRings raw configuration collection. + **/ + virtual void setRawConfCol( + const xAOD::RingSetConf::RawConfCollection *crRawConfCol) = 0; + + /** + * @brief Get the holden CaloRings raw configuration collection. + **/ + virtual void getRawConfCol( + const xAOD::RingSetConf::RawConfCollection *&crRawConfCol) const = 0; + + /** + * @brief Get segmentation type for this pre-processing + **/ + virtual SegmentationType getSegType() const = 0; + +#endif + + /** + * @brief Apply discriminator to obtain its output representation + * + * This method will pass @name input information to the + * pre-processors (if any) and afterwards feed the classifier. + * + * This overload is only available if SegmentationType is set to + * NoSegmentation (there is no section/layer segmentation + * information available on this method). + **/ + virtual void execute( + const DepVarStruct &depVar, + const std::vector<float> &input, + std::vector<float> &output) const = 0; + ///@} + + /** + * @brief Returns this wrapper name + **/ + virtual const char* name() const ATH_RINGER_FINAL ATH_RINGER_OVERRIDE { + return wrapName; + } + +#if RINGER_USE_NEW_CPP_FEATURES + static constexpr const char* wrapName = "RingerDiscriminatorWrapper"; +#else + static const char* wrapName; +#endif + + /** + * @brief Returns whether it has Pre-Processing Collection Wrapper. + **/ + virtual bool hasPP() const = 0; + + /** + * @brief Write all wrappers on discrWrapperCol to TDirectory + **/ + static void writeCol(const WrapperCollection &discrWrapperCol, + const char *fileName); + + /** + * @brief Read all discriminator on file at the path and append them to + * IPreProcWrapperCollection + **/ + static void read(WrapperCollection &discrWrapperCol, + const char* fileName); + + protected: + + IRingerProcedureWrapper(){;} + +}; + +/** + * @brief Facilitate access into Discrimination Wrappers. + **/ +typedef IRingerProcedureWrapper< Discrimination::IDiscriminator > + IDiscrWrapper; + +/** + * @brief Facilitate access into Discrimination Wrappers. + **/ +typedef IDiscrWrapper::WrapperCollection IDiscrWrapperCollection; + +/** + * @class RingerProcedureWrapper + * @brief Specialization for Discriminator procedure. + **/ +template < class procedure_t, + /*EtaDependency*/int etaDependency, + /*EtDependency*/int etDependency, + /*SegmentationType*/int segType> +class RingerProcedureWrapper< + procedure_t, + etaDependency, + etDependency, + segType, + false, // isPreProcessor + true, // isDiscriminator + false> : // isThreshold + public IDiscrWrapper, + public RedirectMsgStream +{ + RINGER_STATIC_ASSERT( + (Ringer::is_base_of<VariableDependency,procedure_t>::value), + "RingerProcedureWrapper procedure_t type must have IVariableDependecy inheritance."); + public: + /// RingerProcedureWrapper for Discrimination procedures typedefs: + ///@{ + /** + * @brief typedef to base wrapper + **/ + //typedef typename RingerProcedureWrapper::template + // IRingerProcedureWrapper< Discrimination::IDiscriminator > + // wrapper_t; + + /** + * @brief typedef to the Ringer Interface variable dependency collection + * + * Collection Dimension: [segType][etBin][etaBin]: + * + **/ + typedef typename std::vector< + std::vector < + std::vector < procedure_t* > > + > DiscrDepProcCollection; + ///@} + + /// Ctors: + ///@{ + /** + * @brief Build RProc Wrapper with no pre-processor + **/ + RingerProcedureWrapper( + const DiscrDepProcCollection &discrDepCol): + m_ppWrapperCol(IPreProcWrapperCollection(0)), + m_discrCol(discrDepCol), + m_discr(nullptr), + m_rsRawConfCol(nullptr), + m_nRings(0) + { + checkDiscrCol(); + } + + /** + * @brief Build RProc Wrapper with all functionallities + **/ + RingerProcedureWrapper( + const IPreProcWrapperCollection &ppCol, + const DiscrDepProcCollection &discrDepCol): + m_ppWrapperCol(ppCol), + m_discrCol(discrDepCol), + m_discr(nullptr), + m_rsRawConfCol(nullptr), + m_nRings(0) + { + checkPPWrapperCol(); + checkDiscrCol(); + } + ///@} + + /// Main methods: + ///@{ +#ifndef RINGER_STANDALONE + /** + * @brief Apply discriminator to obtain its output representation + * + * This method will pass the information within xAOD::CaloRings and + * xAOD::TrackParticle to the pre-processors (if any) and + * afterwards feed the classifier. If any pointer if set to null, then it + * won't pass it into the classifier. Make sure to feed classifier with + * the same information it was adjusted to work with. + **/ + virtual void execute( + const DepVarStruct &depVar, + const xAOD::CaloRings *clrings, + const TrackPatternsHolder *trackPat, + std::vector<float> &output) const ATH_RINGER_OVERRIDE ATH_RINGER_FINAL; +#endif + + /** + * @brief Apply discriminator to obtain its output representation + * + * This method will pass @name input information to the + * pre-processors (if any) and afterwards feed the classifier. + * + * This overload is only available if SegmentationType is set to + * NoSegmentation (there is no section/layer segmentation + * information available on this method). + **/ + virtual void execute( + const DepVarStruct &depVar, + const std::vector<float> &input, + std::vector<float> &output) const ATH_RINGER_OVERRIDE ATH_RINGER_FINAL; + ///@} + + /// Other utilities: + ///@{ +#ifndef RINGER_STANDALONE + /** + * @brief Set the holden CaloRings raw configuration collection. + **/ + virtual void setRawConfCol( + const xAOD::RingSetConf::RawConfCollection *crRawConfCol) + ATH_RINGER_FINAL ATH_RINGER_OVERRIDE + { + for ( auto &ppWrapper : m_ppWrapperCol ) { + ppWrapper->setRawConfCol( crRawConfCol ); + } + m_rsRawConfCol = crRawConfCol; + m_nRings = xAOD::RingSetConf::totalNumberOfRings( *crRawConfCol ); + } + + /** + * @brief Get the holden CaloRings raw configuration collection. + **/ + virtual void getRawConfCol( + const xAOD::RingSetConf::RawConfCollection *&crRawConfCol) const + ATH_RINGER_FINAL ATH_RINGER_OVERRIDE + { + crRawConfCol = m_rsRawConfCol; + } +#endif + + /** + * @brief Get segmentation type for this pre-processor + **/ + virtual SegmentationType getSegType() const + ATH_RINGER_FINAL ATH_RINGER_OVERRIDE + { + return static_cast<SegmentationType>(segType); + } + + + /** + * @brief Returns whether holden interface collection is empty. + **/ + virtual bool empty() const ATH_RINGER_OVERRIDE { return m_discrCol.empty();} + + /** + * @brief Returns whether it has pre-processing Collection Wrapper. + **/ + virtual bool hasPP() const ATH_RINGER_OVERRIDE { return !m_ppWrapperCol.empty();} + + /** + * @brief Overloads the setMsgStream from RedirectMsgStream. + **/ + virtual void setMsgStream(MsgStream *msg) const ATH_RINGER_OVERRIDE; + + /** + * @brief Write collection to TDirectory + **/ + void write(TDirectory *baseDir, const char *idxStr = "") const + ATH_RINGER_OVERRIDE ATH_RINGER_FINAL; + + /** + * @brief Returns eta dependecy for this wrapper + **/ + EtaDependency etaDep() const + ATH_RINGER_OVERRIDE ATH_RINGER_FINAL + { + return static_cast<EtaDependency>(etaDependency); + } + + /** + * @brief Returns et dependecy for this wrapper + **/ + EtDependency etDep() const + ATH_RINGER_OVERRIDE ATH_RINGER_FINAL + { + return static_cast<EtDependency>(etDependency); + } + + /** + * @brief Release all holden pointer memory + **/ + void releaseMemory() ATH_RINGER_OVERRIDE ATH_RINGER_FINAL; + + /** + * @brief Get full wrapper name, static method + **/ + static std::string staticFullName(); + + /** + * @brief Print wrapper content + **/ + void print(MSG::Level lvl = MSG::DEBUG) const ATH_RINGER_OVERRIDE + ATH_RINGER_FINAL; + + /** + * @brief Get full wrapper name + **/ + std::string fullName() const ATH_RINGER_OVERRIDE ATH_RINGER_FINAL; + + /** + * @brief Read collection from TDirectory + **/ + static RingerProcedureWrapper* read(TDirectory *configDir, + unsigned version); + ///@} + + private: + /// Private methods + ///@{ + /** + * @brief Check if input PP Wrapper collection is in good status + * (Throws otherwise) + **/ + void checkPPWrapperCol(); + /** + * @brief Check if discriminators interface collection is in good status + * (Throws otherwise) + **/ + void checkDiscrCol(); + ///@} + + /// Properties + ///@{ + /// @brief Discriminator preprocessing collection routines + const IPreProcWrapperCollection m_ppWrapperCol; + /// @brief holden discriminator collection: + DiscrDepProcCollection m_discrCol; + /// @brief hold pointer to first collection position: + procedure_t *m_discr; + + +#ifndef RINGER_STANDALONE + /// @brief contains a pointer into the CaloRings configuration + const xAOD::RingSetConf::RawConfCollection *m_rsRawConfCol; + /// @short contains the total number of rings in the vectorized + /// representation + unsigned m_nRings; +#endif + ///@} + +}; + +} // namespace Ringer + +#endif // RINGERSELECTORTOOLS_PROCEDURES_RINGERDISCRIMINATIONWRAPPER_H + +#ifndef INCLUDE_HEADER_ONLY // Use to avoid circular includes +#include "RingerDiscriminatorWrapper.icc" +#endif // INCLUDE_HEADER_ONLY + diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/procedures/RingerDiscriminatorWrapper.icc b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/procedures/RingerDiscriminatorWrapper.icc new file mode 100644 index 0000000000000000000000000000000000000000..82f6f8c9ae9ae4c5a2cf47ce650f17a3a7587831 --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/procedures/RingerDiscriminatorWrapper.icc @@ -0,0 +1,825 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: RingerDiscriminatorWrapper.icc 713528 2015-12-09 08:58:44Z wsfreund $ +#ifndef RINGERSELECTORTOOLS_PROCEDURES_RINGERDISCRIMINATIONWRAPPER_ICC +#define RINGERSELECTORTOOLS_PROCEDURES_RINGERDISCRIMINATIONWRAPPER_ICC + +#include "RingerDiscriminatorWrapper.h" +#include "RingerProcedureWrapper.icc" + +#include "RingerSelectorTools/procedures/Normalizations.h" +#include "RingerSelectorTools/procedures/NeuralNetwork.h" + +namespace Ringer { + +namespace WrapperHelperFcns { + +/** + * Return the discriminator on dirObj of ppType + **/ +inline +Discrimination::IDiscriminatorVarDep* getDiscr(discrEnum_t discrType, + TDirectory *dirObj ) +{ + using namespace Discrimination; + // For the interface case, we will have to create each pre-processing + // depending on the information written on ppType: + switch ( discrType ) + { + case discrEnum_t::NNFeedForward: + { + return NNFeedForwardVarDep::read( dirObj ); + break; + } + default: + { + throw std::runtime_error( std::string("Cannot read discriminator of ") + + "type: " + toStr(discrType) ); + } + } +} +} // WrapperHelperFcns + +// Import Wrapper Helper functions +using namespace WrapperHelperFcns; + +// ============================================================================= +// ----------------------------------------- +// RingerProcedureWrapper for Discriminators +// ----------------------------------------- +// ============================================================================= + +// ============================================================================= +template < + class procedure_t, + /*EtaDependency*/int etaDependency, + /*EtDependency*/int etDependency, + /*SegmentationType*/int segType +> +void RingerProcedureWrapper< + procedure_t, + etaDependency, + etDependency, + segType, + false, // isPreProcessor + true, // isDiscriminator + false> // isThreshold +::releaseMemory() +{ + for ( size_t ppColIdx = 0; ppColIdx < m_ppWrapperCol.size(); ++ppColIdx){ + if (m_ppWrapperCol[ppColIdx]){ + m_ppWrapperCol[ppColIdx]->releaseMemory(); + } + } + for ( size_t segIdx = 0; segIdx < m_discrCol.size() ; ++segIdx){ + for ( size_t etIdx = 0; etIdx < m_discrCol[segIdx].size() ; ++etIdx){ + for ( size_t etaIdx = 0; etaIdx < m_discrCol[segIdx][etIdx].size(); + ++etaIdx) + { + delete m_discrCol[segIdx][etIdx][etaIdx]; + } + } + } + m_discrCol.clear(); + m_discr = nullptr; +} + +// ============================================================================= +template < + class procedure_t, + /*EtaDependency*/int etaDependency, + /*EtDependency*/int etDependency, + /*SegmentationType*/int segType +> +void RingerProcedureWrapper< + procedure_t, + etaDependency, + etDependency, + segType, + false, // isPreProcessor + true, // isDiscriminator + false> // isThreshold +::execute( + const DepVarStruct &depVar, + const xAOD::CaloRings *clrings, + const TrackPatternsHolder *trackPat, + std::vector<float> &output) const +{ +#ifndef NDEBUG + ATH_MSG_DEBUG("Applying first discrimination layer discriminators."); +#endif + + // Clear any previous output: + output.clear(); + + // We will put pre-processing results into this vector: + std::vector<float> transformVec; + +#ifndef NDEBUG + ATH_MSG_DEBUG( "Allocating space on transformVec of size " << + (((clrings)?(m_nRings):0) + + ((trackPat)?TrackPatternsHolder::numberOfPatterns():0))); +#endif + + // We grant it enougth space to handle worst case: + transformVec.reserve( + (clrings)?(m_nRings):(0 + + ((trackPat)?TrackPatternsHolder::numberOfPatterns():0)) + ); + + std::vector<float> input = transformVec; + + if ( m_ppWrapperCol.empty() ) { + // Otherwise simply push-back information: + if (clrings){ + clrings->exportRingsTo(transformVec); + } + if (trackPat){ + trackPat->exportPatternsTo(transformVec); + } + } else { + // FIXME: This does not work with multiple normalizations, we need to + // change this to something where the pre-processor will keep the + // segmentation information that it will receive and where should it divide + // it. + + // If pre-processing available execute it: + for ( size_t ppIdx = 0; ppIdx < m_ppWrapperCol.size(); ++ppIdx ){ + m_ppWrapperCol[ppIdx]->applyPreProcessing( + depVar, + clrings, + trackPat, + transformVec); + } + } + + // Initialize eta and et indexes: + size_t etaIdx(0), etIdx(0); + // Get the correct idx to be applied: + if (etaDependency) { + etaIdx = findEtaBin(depVar.eta, m_discrCol[0]); + } + if (etDependency) { + etIdx = findEtBin(depVar.et, m_discrCol[0]); + } + + size_t cDiscr = 0; + + switch(segType){ + case SegmentationType::NoSegmentation: + { +#ifndef NDEBUG + ATH_MSG_VERBOSE("Applying NonSegmented" + " discriminator at etaIdx (" << etaIdx << ") and etIdx (" + << etIdx << ")."); +#endif + input = transformVec; + // Apply discrimination to all transformed space: + m_discrCol[cDiscr++][etaIdx][etIdx]->execute(input,output); + break; + } + case SegmentationType::TrackCalSegmentation: + { +#ifndef NDEBUG + ATH_MSG_VERBOSE("Applying Track/Cal segmented" + " discriminators at etaIdx (" << etaIdx << ") and etIdx (" + << etIdx << ")."); +#endif + if (clrings){ + // Apply discrimination to CaloRings as one: + getCaloSegmentFromTransformVec( m_nRings, + transformVec, + input); + + executeSegmentedDiscr( + input, + m_discrCol[cDiscr++][etaIdx][etIdx], + output); + } else { + cDiscr += 1; + } + if (trackPat){ + // Apply discrimination to Track separated: + getTrackSegmentFromTransformVec( + // If the CaloRings is available, then we have to increase the + // start index to jump all Calorimeter representations: + (clrings)?(m_nRings):0, + transformVec, + input); + + executeSegmentedDiscr( + input, + m_discrCol[cDiscr++][etaIdx][etIdx], + output); + } else { + cDiscr += 1; + } + break; + } + case SegmentationType::TrackCalPatTypeSegmentation: + { + // TODO Implement this if it is going to be used: + throw std::runtime_error(std::string("There is no implementation method " + "for ") + toStr(static_cast<SegmentationType>(segType)) ); + } + case SegmentationType::TrackCalJointSections: + { +#ifndef NDEBUG + ATH_MSG_VERBOSE("Applying Track/Cal-JointSections segmented" + " discriminators at etaIdx (" << etaIdx << ") and etIdx (" + << etIdx << ")."); +#endif + if (clrings){ + // Apply discrimination to each CalJointSection: + while ( cDiscr < static_cast<size_t>( + CalJointSection::NJointSections) ) + { + getCaloSegmentFromTransformVec( + *m_rsRawConfCol, + static_cast<CalJointSection>(cDiscr), + transformVec, + input); + + executeSegmentedDiscr( + input, + m_discrCol[cDiscr++][etaIdx][etIdx], + output); + } + } else { + cDiscr += static_cast<size_t>(CalJointSection::NJointSections); + } + if (trackPat) { + // Apply discrimination to Track separated: + getTrackSegmentFromTransformVec( + (clrings)?(m_nRings):0, + transformVec, + input); + + executeSegmentedDiscr( + input, + m_discrCol[cDiscr++][etaIdx][etIdx], + output); + } else { + cDiscr += 1; + } + break; + } + case SegmentationType::TrackCalJointLayers: + { +#ifndef NDEBUG + ATH_MSG_VERBOSE("Applying Track/Cal-JointLayers segmented" + " discriminators at etaIdx (" << etaIdx << ") and etIdx (" + << etIdx << ")."); +#endif + if (clrings){ + // Apply discrimination to each CalJointLayer: + while ( cDiscr < static_cast<size_t>( + CalJointLayer::NJointLayers) ) + { + getCaloSegmentFromTransformVec( + *m_rsRawConfCol, + static_cast<CalJointLayer>(cDiscr), + transformVec, + input); + + executeSegmentedDiscr( + input, + m_discrCol[cDiscr++][etaIdx][etIdx], + output); + } + } else { + cDiscr += static_cast<size_t>(CalJointLayer::NJointLayers); + } + if (trackPat){ + // Apply discrimination to Track separated: + getTrackSegmentFromTransformVec( + (clrings)?(m_nRings):0, + transformVec, + input); + + executeSegmentedDiscr( + input, + m_discrCol[cDiscr++][etaIdx][etIdx], + output); + } else { + cDiscr += 1; + } + break; + } + } + return; +} + +// ============================================================================= +template < + class procedure_t, + /*EtaDependency*/int etaDependency, + /*EtDependency*/int etDependency, + /*SegmentationType*/int segType +> +void RingerProcedureWrapper< + procedure_t, + etaDependency, + etDependency, + segType, + false, // isPreProcessor + true, // isDiscriminator + false> // isThreshold +::execute( + const DepVarStruct &depVar, + const std::vector<float> &input, + std::vector<float> &output) const +{ +#ifndef NDEBUG + ATH_MSG_DEBUG("Applying internal discrimination layer discriminators."); +#endif + + // This method only applies for segType NoSegmentation. + ensureNoSegmentationOnlyFcn(static_cast<SegmentationType>(segType)); + + // Copy input: + std::vector<float> inputCopy = input; + // First, execute pp wrapper collection: + for ( size_t ppIdx = 0; ppIdx < m_ppWrapperCol.size(); ++ppIdx ){ + m_ppWrapperCol[ppIdx]->applyPreProcessing(depVar,inputCopy); + } + + if (!etaDependency && !etDependency){ + m_discr->execute(inputCopy,output); + return; + } + + // Initialize eta and et indexes: + size_t etaIdx(0), etIdx(0); + + // Get the correct idx to be applied: + if (etaDependency){ + etaIdx = findEtaBin(depVar.eta, m_discrCol[0]); + } + if (etDependency){ + etIdx = findEtBin(depVar.et, m_discrCol[0]); + } + + // Apply it: + m_discrCol[0][etaIdx][etIdx]->execute(inputCopy,output); +} + +// ============================================================================= +template < + class procedure_t, + /*EtaDependency*/int etaDependency, + /*EtDependency*/int etDependency, + /*SegmentationType*/int segType +> +void RingerProcedureWrapper< + procedure_t, + etaDependency, + etDependency, + segType, + false, // isPreProcessor + true, // isDiscriminator + false> // isThreshold +::checkPPWrapperCol(){ + if (m_ppWrapperCol.empty()){ + throw std::runtime_error(std::string( + "Attempted to start Discriminator Wrapper with" + " PreProcessing Wrapper collection that is empty.\n" + "In this case, do not input PreProcessing" + " Wrapper collection in Discriminator" + " Wrapper construction.")); + + } + for ( size_t ppWrapperIdx = 0; ppWrapperIdx < m_ppWrapperCol.size(); + ++ppWrapperIdx ){ + if( !m_ppWrapperCol[ppWrapperIdx] || + m_ppWrapperCol[ppWrapperIdx]->empty() ){ + throw std::runtime_error(std::string( + "Attempted to start Discriminator Wrapper with" + " PreProcessing Wrapper collection with" + " empty PreProcessing Wrapper.")); + } + } +} + +// ============================================================================= +template < + class procedure_t, + /*EtaDependency*/int etaDependency, + /*EtDependency*/int etDependency, + /*SegmentationType*/int segType +> +void RingerProcedureWrapper< + procedure_t, + etaDependency, + etDependency, + segType, + false, // isPreProcessor + true, // isDiscriminator + false> // isThreshold +::checkDiscrCol(){ + try { + checkCollection(m_discrCol, + static_cast<EtaDependency>(etaDependency), + static_cast<EtDependency>(etDependency)); + if (segType && m_discrCol.size() < 2 ){ + throw std::runtime_error(std::string("Cannot allocate dependency vector " + "with size lesser than one when using segmentation dependency.")); + } + } catch ( const std::runtime_error &e ) { + throw std::runtime_error(std::string("Couldn't initialize RingerDiscriminationWrapper collection due to: ") + + e.what() ); + } +} + +// ============================================================================= +template < + class procedure_t, + /*EtaDependency*/int etaDependency, + /*EtDependency*/int etDependency, + /*SegmentationType*/int segType +> +void RingerProcedureWrapper< + procedure_t, + etaDependency, + etDependency, + segType, + false, // isPreProcessor + true, // isDiscriminator + false> // isThreshold +::setMsgStream(MsgStream *msg) const { + // The pre-processors wrapper collection: + for ( size_t ppWrapperIdx = 0; ppWrapperIdx < m_ppWrapperCol.size(); ++ppWrapperIdx ){ + if ( m_ppWrapperCol[ppWrapperIdx] ) { + m_ppWrapperCol[ppWrapperIdx]->setMsgStream(msg); + } + } + // The discrimination collection: + setCollectionMsgStream(msg,m_discrCol); + // Set the wrapper message stream: + this->RedirectMsgStream::setMsgStream(msg); +} + +// ============================================================================= +template < + class procedure_t, + /*EtaDependency*/int etaDependency, + /*EtDependency*/int etDependency, + /*SegmentationType*/int segType +> +std::string RingerProcedureWrapper< + procedure_t, + etaDependency, + etDependency, + segType, + false, // isPreProcessor + true, // isDiscriminator + false> // isThreshold +::staticFullName() { + typedef typename RingerProcedureType<procedure_t>::procEnum_t procEnum_t; + std::stringstream ss; + ss << "RingerProcedureWrapper<" + << toStr(procedure_t::template procType<procEnum_t>() ) + << ((Ringer::is_same<procedure_t, + Discrimination::IDiscriminatorVarDep>::value)?",": + "(VarDep),") + << toStr(static_cast<EtaDependency>(etaDependency)) << "," + << toStr(static_cast<EtDependency>(etDependency)) << "," + << toStr(static_cast<SegmentationType>(segType)) << ">"; + return ss.str(); +} + +// ============================================================================= +template < + class procedure_t, + /*EtaDependency*/int etaDependency, + /*EtDependency*/int etDependency, + /*SegmentationType*/int segType +> +std::string RingerProcedureWrapper< + procedure_t, + etaDependency, + etDependency, + segType, + false, // isPreProcessor + true, // isDiscriminator + false> // isThreshold +::fullName() const { + return staticFullName(); +} + +// ============================================================================= +template < + class procedure_t, + /*EtaDependency*/int etaDependency, + /*EtDependency*/int etDependency, + /*SegmentationType*/int segType +> +void RingerProcedureWrapper< + procedure_t, + etaDependency, + etDependency, + segType, + false, // isPreProcessor + true, // isDiscriminator + false> // isThreshold +::print(MSG::Level lvl) const +{ + if ( this->isStreamAvailable() ) { + if ( this->level() > lvl ){ + // Don't waste time to print nothing. + return; + } + this->msg() << lvl << " -------- Printing PreProcesorWrappers -------- " + << endreq; + // Print pre-processing collection: + for ( size_t ppWrapIdx = 0; ppWrapIdx < m_ppWrapperCol.size(); ++ppWrapIdx ) + { + this->msg() << lvl << "PreProcessingWrapper" + << IOHelperFcns::makeIdxStr(ppWrapIdx) << endreq; + m_ppWrapperCol[ppWrapIdx]->print( lvl ); + } + this->msg() << lvl << " --- Finished printing PreProcessorWrappers --- " + << endreq; + // Print discriminators + std::vector<unsigned> posVec(3); + for ( size_t segIdx = 0; segIdx < m_discrCol.size() ; ++segIdx){ + posVec[0] = segIdx; + for ( size_t etIdx = 0; etIdx < m_discrCol[segIdx].size() ; ++etIdx){ + posVec[1] = etIdx; + for ( size_t etaIdx = 0; etaIdx < m_discrCol[segIdx][etIdx].size(); + ++etaIdx) + { + posVec[2] = etaIdx; + this->msg() << lvl << m_discrCol[segIdx][etIdx][etaIdx]->name() << + IOHelperFcns::makeIdxStr(posVec) << " configuration:" << endreq; + m_discrCol[segIdx][etIdx][etaIdx]->print(lvl); + } + } + } + } else { + std::cerr << "Stream is not available, cannot print " << fullName() << "." + << std::endl; + } +} + +// ============================================================================= +template < + class procedure_t, + /*EtaDependency*/int etaDependency, + /*EtDependency*/int etDependency, + /*SegmentationType*/int segType +> +void RingerProcedureWrapper< + procedure_t, + etaDependency, + etDependency, + segType, + false, // isPreProcessor + true, // isDiscriminator + false> // isThreshold +::write(TDirectory *baseDir, const char *idxStr) const +{ + + // ----------- Template basics ---------- + // Create configuration directory + TDirectory *configDir = IOHelperFcns::makeDir(baseDir, + (std::string(name()) + idxStr).c_str() ); + + // Write basic template information: + discrEnum_t discrType = procedure_t::template procType<discrEnum_t>(); + SegmentationType fileSegType = static_cast<SegmentationType>(segType); + EtaDependency fileEtaDep = static_cast<EtaDependency>(etaDependency); + EtDependency fileEtDep = static_cast<EtDependency>(etDependency); + // FIXME Why do I need to use const? Unfortunately if I don't use so, the + // compiler won't accept static_casting from discr_Enum_t to unsigned int: + // some issue with reference casting. + IOHelperFcns::writeVar<const discrEnum_t, const unsigned int>( configDir, + "discrType", + discrType); + IOHelperFcns::writeVar<const SegmentationType, const unsigned int>( configDir, + "segType", + fileSegType); + IOHelperFcns::writeVar<const EtaDependency, const unsigned int>( configDir, + "etaDependency", + fileEtaDep); + IOHelperFcns::writeVar<const EtDependency, const unsigned int>( configDir, + "etDependency", + fileEtDep); + + // ----------- Pre-processing chain ---------- + // Write flag whether there is pre-processing chain for this discriminator: + IPreProcWrapper::writeCol(m_ppWrapperCol, configDir); + + // ------------ Discriminators: --------------- + // Write size information: + unsigned discrSegDepSize = m_discrCol.size(); + unsigned discrEtDepSize = m_discrCol[0].size(); + unsigned discrEtaDepSize = m_discrCol[0][0].size(); + IOHelperFcns::writeVar( configDir, "discrSegDepSize" , discrSegDepSize ); + IOHelperFcns::writeVar( configDir, "discrEtDepSize" , discrEtDepSize ); + IOHelperFcns::writeVar( configDir, "discrEtaDepSize" , discrEtaDepSize ); + // Write Discriminator collection + std::vector<unsigned int> discrCount(3); + for (size_t segIdx = 0; + segIdx < m_discrCol.size(); + ++segIdx) + { + discrCount[0] = segIdx; + for (size_t etIdx = 0; + etIdx < m_discrCol[segIdx].size(); + ++etIdx) + { + discrCount[1] = etIdx; + for (size_t etaIdx = 0; + etaIdx < m_discrCol[segIdx][etIdx].size(); + ++etaIdx) + { + discrCount[2] = etaIdx; + m_discrCol[segIdx][etIdx][etaIdx]->write( + configDir, + IOHelperFcns::makeIdxStr(discrCount).c_str()); + } + } + } +} + +// ============================================================================= +template < + class procedure_t, + /*EtaDependency*/int etaDependency, + /*EtDependency*/int etDependency, + /*SegmentationType*/int segType +> +RingerProcedureWrapper<procedure_t, + etaDependency, + etDependency, + segType, + false, + true, + false> * +RingerProcedureWrapper< + procedure_t, + etaDependency, + etDependency, + segType, + false, // isPreProcessor + true, // isDiscriminator + false> // isThreshold +::read(TDirectory *configDir, unsigned version) +{ + + using namespace Discrimination; + + IOHelperFcns::checkDir(configDir); + + // ----------- Pre-processing chain ---------- + // Create empty preprocessing wrapper collection: + IPreProcWrapperCollection ppWrapperCol; + + //ATH_MSG_DEBUG("Reading Discrimination Wrapper of type \"" + // << ppType.Data() + // << "\" named \"" << configDir->GetName() + // << "\" and dependency : [" + // << toStr(segType) << "," + // << toStr(etaDependency) << "," + // << toStr(etDependency) << "]"); + + // Check if this discriminator has pre-processing: + bool hasPP(false); + IOHelperFcns::readVar( configDir, "hasPP", hasPP ); + + // Fill preprocessing wrapper collection + if (hasPP) { + IPreProcWrapper::read( ppWrapperCol, configDir, version ); + } else { + //ATH_MSG_VERBOSE("This Discrimination Wrapper hasn't pre-processors."); + } + + // ----------- Discriminators: ---------- + // Read discrimination collection size: + unsigned discrSegDepSize(0), + discrEtDepSize(0), + discrEtaDepSize(0); + IOHelperFcns::readVar( configDir, "discrSegDepSize", discrSegDepSize ); + IOHelperFcns::readVar( configDir, "discrEtDepSize" , discrEtDepSize ); + IOHelperFcns::readVar( configDir, "discrEtaDepSize", discrEtaDepSize ); + + // Allocate discriminator collection with size specified on file + DiscrDepProcCollection discrCol( discrSegDepSize, + std::vector< std::vector< procedure_t*> >( + discrEtDepSize, std::vector< procedure_t*>( + discrEtaDepSize, nullptr ))); + + // Allocate index position retriever: + std::vector<unsigned int> discrIdxVec(3); + + // Retrieve dir list and loop on it: + std::shared_ptr<THashList> list(nullptr); + if ( !( list = IOHelperFcns::getDirList(configDir) ) ) { + std::runtime_error(std::string("Couldn't retrieve directory " + "list from wrapper folder")); + } + + TIter iter( list.get() ); + while ( TDirectory* dirObj = static_cast<TDirectory*>(iter()) ) { + + const char* folderName = dirObj->GetName(); + + //ATH_MSG_VERBOSE("Scanning directory " << folderName ); + + // Filter pre-processing wrapper dirs: + if ( IOHelperFcns::startsWith( IRingerProcedureWrapper< + PreProcessing::IPreProcessor>::wrapName, folderName) ) + { + // Ok, we don't need to scan this directory, we've handled it before. + //ATH_MSG_VERBOSE("Directory is PreProcessorWrapper, continuing.." ); + continue; + } + // Get information about the discriminator on the folder: + discrEnum_t discrType; + EtaDependency fileEtaDep; + EtDependency fileEtDep; + try { + IOHelperFcns::readVar<discrEnum_t, unsigned int>(dirObj, + "procType", + discrType); + IOHelperFcns::readVar<EtaDependency, unsigned int>(dirObj, + "etaDependency", + fileEtaDep); + IOHelperFcns::readVar<EtDependency, unsigned int>(dirObj, + "etDependency", + fileEtDep); + } catch (const std::runtime_error &e){ + throw std::runtime_error(std::string("Couldn't get discriminator type " + "while") + "reading folder: " + folderName + ". Reason: " + + e.what() ); + } + // Check if holden information dependency information is ok: + if ( fileEtaDep != etaDependency ){ + throw std::runtime_error(std::string("Folder \"") + folderName + "\" is " + + toStr(fileEtaDep) + " whereas Wrapper is " + toStr(static_cast<EtaDependency>(etaDependency)) + "."); + } + if ( fileEtDep != etDependency ){ + throw std::runtime_error(std::string("Folder \"") + folderName + "\" is " + + toStr(fileEtDep) + " whereas Wrapper is " + toStr(static_cast<EtDependency>(etDependency)) + "."); + } + // Retrieve position indexes where we shall retrieve this discriminator + IOHelperFcns::getIdxVecFromStr( folderName, discrIdxVec ); + + // Check if everything is ok on indexes retrived: + if ( discrIdxVec.size() < 3 || + discrIdxVec[0] >= discrSegDepSize || + discrIdxVec[1] >= discrEtDepSize || + discrIdxVec[2] >= discrEtaDepSize ) + { + throw std::runtime_error(std::string("There is something wrong with ") + + "folder idxStr: " + folderName + ". Got idxStr " + + IOHelperFcns::makeIdxStr(discrIdxVec) + ". Maximum discrimination " + "collection size is : " + std::to_string(discrSegDepSize) + "," + + std::to_string(discrEtDepSize) + "," + std::to_string(discrEtaDepSize)); + } + + // Get a reference to the pointer (done only to reduce typing): + procedure_t *&thisDiscr = discrCol[discrIdxVec[0]] + [discrIdxVec[1]] + [discrIdxVec[2]]; + + // Check which procedure_t this discrimination wrapper holds. + if ( Ringer::is_same<procedure_t, IDiscriminatorVarDep >::value ) + { + // If the procedure_t is not the Discriminator interface, code will + // never get here. We only use the interpret cast so that the compiler + // doesn't complain about type casting. + thisDiscr = reinterpret_cast<procedure_t*>( getDiscr(discrType, dirObj) ); + } else { + // Here it's easier, we already know the type that is written in the file, + // so all we need to do is loop over it and retrieve the discriminator. + discrEnum_t wrapperDiscrType = procedure_t::template procType<discrEnum_t>(); + if ( discrType != wrapperDiscrType ){ + throw std::runtime_error( std::string("There is a discriminator of type ") + + toStr(discrType) + " whereas this wrapper can only hold discriminators " + "of type " + toStr(wrapperDiscrType)); + } + thisDiscr = procedure_t::read( dirObj ); + } + // ATH_MSG_VERBOSE("Successfully read directory " << folderName); + } + + // Create Discrimination wrapper: + RingerProcedureWrapper *newWrapper = nullptr; + if (ppWrapperCol.empty()) { + newWrapper = new RingerProcedureWrapper(discrCol); + } else { + newWrapper = new RingerProcedureWrapper(ppWrapperCol, discrCol); + } + + return newWrapper; + +} +/// @} + +} // Namespace Ringer + +#endif // RINGERSELECTORTOOLS_PROCEDURES_RINGERDISCRIMINATIONWRAPPER_ICC diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/procedures/RingerPreProcessorWrapper.h b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/procedures/RingerPreProcessorWrapper.h new file mode 100644 index 0000000000000000000000000000000000000000..9bf329a30624b659f5b4f4a361401559e0f0a466 --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/procedures/RingerPreProcessorWrapper.h @@ -0,0 +1,343 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: RingerPreProcessorWrapper.h 704615 2015-10-29 18:50:12Z wsfreund $ +#ifndef RINGERSELECTORTOOLS_PROCEDURES_RINGERPREPROCESSORWRAPPER_H +#define RINGERSELECTORTOOLS_PROCEDURES_RINGERPREPROCESSORWRAPPER_H + +#define RINGER_PROCEDURE_INCLUDE +#include "RingerProcedureWrapper.h" +#undef RINGER_PROCEDURE_INCLUDE + +//#undef NDEBUG + +/** + * @brief Namespace dedicated for Ringer utilities + **/ +namespace Ringer { + +/** + * @class IRingerProcedureWrapper + * @brief Specialization for PreProcessor procedure. + **/ +template<> +class IRingerProcedureWrapper< PreProcessing::IPreProcessor > : + virtual public IRedirectMsgStream, + virtual public IRingerProcedureWrapperBase +{ + public: + /** + * @brief Collection type of PreProcessor Wrappers. + **/ + typedef typename std::vector< IRingerProcedureWrapper* > WrapperCollection; + +#ifndef RINGER_STANDALONE + /** + * @brief Apply PP to transform input space into a new representation + * + * This method will pass the information within xAOD::CaloRings and + * xAOD::TrackParticle to the pre-processors. If any pointer if set to + * null, then it won't pass this information. Make sure to feed + * pre-processors with the same information it was adjusted to work with. + **/ + virtual void applyPreProcessing( + const DepVarStruct &depVar, + const xAOD::CaloRings *clrings, + const TrackPatternsHolder *trackPat, + std::vector<float> &transformVec) const = 0; + + /** + * @brief Set the holden CaloRings raw configuration collection. + **/ + virtual void setRawConfCol( + const xAOD::RingSetConf::RawConfCollection *crRawConfCol) = 0; + + /** + * @brief Get the holden CaloRings raw configuration collection. + **/ + virtual void getRawConfCol( + const xAOD::RingSetConf::RawConfCollection *&crRawConfCol) const = 0; + + /** + * @brief Get segmentation type for this pre-processing + **/ + virtual SegmentationType getSegType() const = 0; +#endif + + /** + * @brief Apply PP to transform input space into a new representation. + * + * This method directly uses transformVec as input and transforms it into + * the new representation. + **/ + virtual void applyPreProcessing( + const DepVarStruct &depVar, + std::vector<float> &transformVec) const = 0; + + /** + * @brief Returns this wrapper name + **/ + virtual const char* name() const ATH_RINGER_FINAL ATH_RINGER_OVERRIDE { + return wrapName; + } + + /** + * @brief Write all wrappers on ppWrapperCol to TDirectory + **/ + static void writeCol(const WrapperCollection &ppWrapperCol, + TDirectory *configDir); + + /** + * @brief Read all pre-processing on configDir and append them to + * IPreProcWrapperCollection + **/ + static void read(WrapperCollection &ppWrapperCol, + TDirectory *configDir, + unsigned version); + +#if RINGER_USE_NEW_CPP_FEATURES + static constexpr const char* wrapName = "RingerPreProcessorWrapper"; +#else + static const char* wrapName; +#endif + + /** Ensure virtual destructor */ + virtual ~IRingerProcedureWrapper(){;} + + protected: + IRingerProcedureWrapper(){;} + +}; + +/** + * @brief Facilitate access into Threshold Wrappers. + **/ +typedef IRingerProcedureWrapper< PreProcessing::IPreProcessor > IPreProcWrapper; +/** + * @brief Facilitate access into Threshold Wrappers collection. + **/ +typedef IPreProcWrapper::WrapperCollection IPreProcWrapperCollection; + +/** + * @class RingerProcedureWrapper + * @brief Specialization for PreProcessing procedure. + **/ +template < class procedure_t, + /*EtaDependency*/int etaDependency, + /*EtDependency*/int etDependency, + /*SegmentationType*/int segType> +class RingerProcedureWrapper< + procedure_t, + etaDependency, + etDependency, + segType, + true, // isPreProcessor + false, // isDiscriminator + false> : // isThreshold + public IPreProcWrapper, + public RedirectMsgStream +{ + RINGER_STATIC_ASSERT( + (Ringer::is_base_of<VariableDependency,procedure_t>::value), + "RingerProcedureWrapper procedure_t type must have IVariableDependecy inheritance."); + public: + /// RingerProcedureWrapper for Threshold procedures typedefs: + ///@{ + /** + * @brief typedef to the Ringer Interface variable dependency collection + * + * Vector Dimension: [segType][etBin][etaBin]: + **/ + typedef typename std::vector < + std::vector < + std::vector < procedure_t* > > + > PPDepProcCollection; + ///@} + + /// Ctors: + ///@{ + /** + * @brief Build RProc Wrapper + **/ + RingerProcedureWrapper( + const PPDepProcCollection &ppDepCol): + m_ppCol(ppDepCol), + m_pp(nullptr), + m_rsRawConfCol(nullptr), + m_nRings(0) + { + checkPPCol(); + m_pp = m_ppCol[0][0][0]; + } + ///@} + + /// Main Methods: + ///@{ +#ifndef RINGER_STANDALONE + /** + * @brief Apply PP to transform input space into a new representation + * + * This method will pass the information within xAOD::CaloRings and + * xAOD::TrackParticle to the pre-processors. If any pointer if set to + * null, then it won't pass this information. Make sure to feed + * pre-processors with the same information it was adjusted to work with. + **/ + virtual void applyPreProcessing( + const DepVarStruct &depVar, + const xAOD::CaloRings *clrings, + const TrackPatternsHolder *trackPat, + std::vector<float> &transformVec) const ATH_RINGER_FINAL ATH_RINGER_OVERRIDE; + +#endif + + /** + * @brief Apply PP to transform input space into a new representation. + * + * This method directly uses transformVec as input and transforms it into + * the new representation. + **/ + virtual void applyPreProcessing( + const DepVarStruct &depVar, + std::vector<float> &transformVec) const ATH_RINGER_FINAL ATH_RINGER_OVERRIDE; + /// @} + + /// Other utilities + /// @{ +#ifndef RINGER_STANDALONE + /** + * @brief Set the holden CaloRings raw configuration collection. + **/ + virtual void setRawConfCol( + const xAOD::RingSetConf::RawConfCollection *crRawConfCol) + ATH_RINGER_FINAL ATH_RINGER_OVERRIDE + { + m_rsRawConfCol = crRawConfCol; + m_nRings = xAOD::RingSetConf::totalNumberOfRings( *crRawConfCol ); + } + + /** + * @brief Get the holden CaloRings raw configuration collection. + **/ + virtual void getRawConfCol( + const xAOD::RingSetConf::RawConfCollection *&crRawConfCol) const + ATH_RINGER_FINAL ATH_RINGER_OVERRIDE + { + crRawConfCol = m_rsRawConfCol; + } +#endif + + /** + * @brief Get segmentation type for this pre-processor + **/ + virtual SegmentationType getSegType() const + ATH_RINGER_FINAL ATH_RINGER_OVERRIDE + { + return static_cast<SegmentationType>(segType); + } + + /** + * @brief Returns whether holden interface collection is empty. + **/ + virtual bool empty() const ATH_RINGER_FINAL ATH_RINGER_OVERRIDE + { + return m_ppCol.empty(); + } + + /** + * @brief Returns eta dependecy for this wrapper + **/ + EtaDependency etaDep() const + ATH_RINGER_OVERRIDE ATH_RINGER_FINAL + { + return static_cast<EtaDependency>(etaDependency); + } + + /** + * @brief Returns et dependecy for this wrapper + **/ + EtDependency etDep() const + ATH_RINGER_OVERRIDE ATH_RINGER_FINAL + { + return static_cast<EtDependency>(etDependency); + } + + /** + * @brief Release all holden pointer memory + **/ + void releaseMemory() ATH_RINGER_OVERRIDE ATH_RINGER_FINAL; + + + /** + * @brief Overloads the setMsgStream from RedirectMsgStream. + **/ + virtual void setMsgStream(MsgStream *msg) const ATH_RINGER_OVERRIDE + ATH_RINGER_FINAL; + + /** + * @brief Get full wrapper name, static method + **/ + static std::string staticFullName(); + + /** + * @brief Get full wrapper name + **/ + std::string fullName() const ATH_RINGER_OVERRIDE ATH_RINGER_FINAL; + + /** + * @brief Print wrapper content + **/ + void print(MSG::Level lvl = MSG::DEBUG) const ATH_RINGER_OVERRIDE + ATH_RINGER_FINAL; + + /** + * @brief Write collection to TDirectory + **/ + void write(TDirectory *baseDir, const char *idxStr = "") const + ATH_RINGER_OVERRIDE ATH_RINGER_FINAL; + + /** + * @brief Read collection from TDirectory + **/ + static RingerProcedureWrapper* read(TDirectory *configDir, + unsigned version); + ///@} + + private: + /// Private Methods: + ///@{ + /** + * @brief Check if pre-processing interface collection is in good status + * (Throws otherwise) + **/ + void checkPPCol(); + ///@} + + /// Private Properties: + ///@{ + /// @brief holden pre-processing collection: + PPDepProcCollection m_ppCol; + /// Hold pointer to the first position on the collection + procedure_t *m_pp; + +#ifndef RINGER_STANDALONE + /// @brief contains a pointer into the CaloRings configuration: + const xAOD::RingSetConf::RawConfCollection *m_rsRawConfCol; + /// @short contains the total number of rings in the vectorized + /// representation + unsigned m_nRings; +#endif + ///@} + +}; + +} // namespace Ringer + +#endif // RINGERSELECTORTOOLS_PROCEDURES_RINGERPREPROCESSORWRAPPER_H + +#ifndef INCLUDE_HEADER_ONLY // Use to avoid circular includes +#ifndef RINGER_DISCRIMINATOR_WRAPPER_INCLUDE +#include "RingerPreProcessorWrapper.icc" +#endif // RINGER_DISCRIMINATOR_WRAPPER_INCLUDE +#endif // INCLUDE_HEADER_ONLY + diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/procedures/RingerPreProcessorWrapper.icc b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/procedures/RingerPreProcessorWrapper.icc new file mode 100644 index 0000000000000000000000000000000000000000..8defdbe1a618aefbd1fb0e1803c97e497c87f81c --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/procedures/RingerPreProcessorWrapper.icc @@ -0,0 +1,709 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: RingerPreProcessorWrapper.icc 704615 2015-10-29 18:50:12Z wsfreund $ +#ifndef RINGERSELECTORTOOLS_PROCEDURES_RINGERPREPROCESSORWRAPPER_ICC +#define RINGERSELECTORTOOLS_PROCEDURES_RINGERPREPROCESSORWRAPPER_ICC + +#include "RingerPreProcessorWrapper.h" +#include "RingerProcedureWrapper.icc" + +#include "Normalizations.h" + +#include "RingerSelectorTools/RingerSelectorToolsDefs.h" + +#undef NDEBUG + +namespace Ringer { + +namespace WrapperHelperFcns { + +/** + * Return the pre-processing on dirObj of ppType + **/ +inline +PreProcessing::IPreProcessorVarDep* getPP(preProcEnum_t ppType, + TDirectory *dirObj ) +{ + using namespace PreProcessing; + // For the interface case, we will have to create each pre-processing + // depending on the information written on ppType: + switch ( ppType ) + { + case preProcEnum_t::Norm1: + { + return Norm::Norm1VarDep::read( dirObj ); + break; + } + case preProcEnum_t::Norm2: + { + return Norm::Norm2VarDep::read( dirObj ); + break; + } + case preProcEnum_t::Sqrt: + { + return Norm::SqrtVarDep::read( dirObj ); + break; + } + case preProcEnum_t::ConstantValue: + { + return Norm::ConstantValueVarDep::read( dirObj ); + break; + } + case preProcEnum_t::Sequential: + { + return Norm::SequentialVarDep::read( dirObj ); + break; + } + case preProcEnum_t::Spherization: + { + return Norm::SpherizationVarDep::read( dirObj ); + break; + } + case preProcEnum_t::MinMax: + { + return Norm::MinMaxVarDep::read( dirObj ); + break; + } + default: + { + throw std::runtime_error( std::string("Cannot read preprocessor of ") + + "type: " + toStr(ppType) ); + } + } +} +} // private namespace + + +// Import Wrapper Helper functions +using namespace WrapperHelperFcns; + +// ============================================================================= +// ---------------------------------------- +// RingerProcedureWrapper for PreProcessors +// ---------------------------------------- +// ============================================================================= + +// ============================================================================= +template < + class procedure_t, + /*EtaDependency*/int etaDependency, + /*EtDependency*/int etDependency, + /*SegmentationType*/int segType +> +void RingerProcedureWrapper< + procedure_t, + etaDependency, + etDependency, + segType, + true, // isPreProcessor + false, // isDiscriminator + false> // isThreshold +::releaseMemory() +{ + for ( size_t segIdx = 0; segIdx < m_ppCol.size() ; ++segIdx){ + for ( size_t etIdx = 0; etIdx < m_ppCol[segIdx].size() ; ++etIdx){ + for ( size_t etaIdx = 0; etaIdx < m_ppCol[segIdx][etIdx].size(); + ++etaIdx) + { + delete m_ppCol[segIdx][etIdx][etaIdx]; + } + } + } + m_ppCol.clear(); + m_pp = nullptr; +} + +// ============================================================================= +template < + class procedure_t, + /*EtaDependency*/int etaDependency, + /*EtDependency*/int etDependency, + /*SegmentationType*/int segType +> +void RingerProcedureWrapper< + procedure_t, + etaDependency, + etDependency, + segType, + true, + false, + false > +::applyPreProcessing( + const DepVarStruct &depVar, + std::vector<float> &transformVec) const +{ +#ifndef NDEBUG + ATH_MSG_DEBUG("Applying internal layer pre-processing."); +#endif + + // This method only applies for segType NoSegmentation. + ensureNoSegmentationOnlyFcn(static_cast<SegmentationType>(segType)); + + // If not dependent, simply run for the first position in the vector: + if ( !etaDependency && !etDependency ){ + m_pp->execute(transformVec); + return; + } + + // Initialize eta and et indexes: + size_t etaIdx(0), etIdx(0); + // Get the correct pp to be applied: + if (etaDependency == EtaDependency::EtaDependent){ + etaIdx = findEtaBin(depVar.eta, m_ppCol[0]); + } + + if (etDependency == EtDependency::EtDependent){ + etIdx = findEtBin(depVar.et, m_ppCol[0]); + } + +#ifndef NDEBUG + ATH_MSG_VERBOSE("Applying pre-processing at etaIdx (" + << etaIdx << ") and etIdx (" << etIdx << ")."); +#endif + + // Apply it: + m_ppCol[0][etIdx][etaIdx]->execute(transformVec); +} + +// ============================================================================= +template < + class procedure_t, + /*EtaDependency*/int etaDependency, + /*EtDependency*/int etDependency, + /*SegmentationType*/int segType +> +void RingerProcedureWrapper< + procedure_t, + etaDependency, + etDependency, + segType, + true, + false, + false > +::applyPreProcessing( + const DepVarStruct &depVar, + const xAOD::CaloRings *clrings, + const TrackPatternsHolder *trackPat, + std::vector<float> &transformVec) const +{ + +#ifndef NDEBUG + ATH_MSG_DEBUG("Applying first discrimination layer pre-processing."); +#endif + + // Erase any previous information + transformVec.clear(); + + // Initialize eta and et indexes: + size_t etaIdx(0), etIdx(0); + // Get the correct idx to be applied: + if ( etaDependency == EtaDependency::EtaDependent ) { + etaIdx = findEtaBin(depVar.eta, m_ppCol[0]); + } + if ( etDependency == EtDependency::EtDependent ) { + etIdx = findEtBin(depVar.et, m_ppCol[0]); + } + size_t cPreProc = 0; + + switch(segType){ + case SegmentationType::NoSegmentation: + { +#ifndef NDEBUG + ATH_MSG_VERBOSE("Applying NonSegmented pre-processing at etaIdx (" + << etaIdx << ") and etIdx (" << etIdx << ")."); +#endif + if (clrings){ + clrings->exportRingsTo(transformVec); + } + if (trackPat){ + trackPat->exportPatternsTo(transformVec); + } + // Apply pre-processing to all transformVec: + m_ppCol[cPreProc++][etaIdx][etIdx]->execute(transformVec); + break; + } + case SegmentationType::TrackCalSegmentation: + { +#ifndef NDEBUG + ATH_MSG_VERBOSE("Applying Track/Cal segmented pre-processing " + " at etaIdx (" << etaIdx << ") and etIdx (" + << etIdx << ")."); +#endif + if (clrings){ + // Apply pre-processing to CaloRings as one: + clrings->exportRingsTo(transformVec); + executeSegmentedPP( + transformVec, + m_ppCol[cPreProc++][etaIdx][etIdx], + transformVec); + } else { + cPreProc += 1; + } + if (trackPat){ + transformVec.clear(); + // Apply pre-processing to track patterns separated: + trackPat->exportPatternsTo(transformVec); + executeSegmentedPP( + transformVec, + m_ppCol[cPreProc++][etaIdx][etIdx], + transformVec); + } else { + cPreProc += 1; + } + break; + } + case SegmentationType::TrackCalPatTypeSegmentation: + { + // TODO Implement this if it is going to be used: + throw std::runtime_error(std::string("There is no implementation method " + "for ") + toStr(static_cast<SegmentationType>(segType)) ); + } + case SegmentationType::TrackCalJointSections: + { +#ifndef NDEBUG + ATH_MSG_VERBOSE("Applying Track/Cal-JointSections segmented" + " pre-processing at etaIdx (" << etaIdx << ") and etIdx (" + << etIdx << ")."); +#endif + if (clrings){ + // Apply pre-processing to each CalJointSection: + while ( cPreProc < static_cast<size_t>( + CalJointSection::NJointSections) ) + { + transformVec.clear(); + clrings->exportRingsTo( transformVec, + *m_rsRawConfCol, + static_cast<CalJointSection>(cPreProc)); + + executeSegmentedPP( + transformVec, + m_ppCol[cPreProc++][etaIdx][etIdx], + transformVec); + } + } else { + cPreProc += static_cast<size_t>(CalJointSection::NJointSections); + } + if (trackPat){ + transformVec.clear(); + // Apply pre-processing to track patterns separated: + trackPat->exportPatternsTo(transformVec); + executeSegmentedPP( + transformVec, + m_ppCol[cPreProc++][etaIdx][etIdx], + transformVec); + } else { + cPreProc += 1; + } + break; + } + case SegmentationType::TrackCalJointLayers: + { +#ifndef NDEBUG + ATH_MSG_VERBOSE("Applying Track/Cal-JointLayers segmented" + " pre-processing at etaIdx (" << etaIdx << ") and etIdx (" + << etIdx << ")."); +#endif + if (clrings){ + // Apply pre-processing to each CalJointLayer: + while ( cPreProc < static_cast<size_t>( + CalJointLayer::NJointLayers) ) + { + transformVec.clear(); + clrings->exportRingsTo( + transformVec, + *m_rsRawConfCol, + static_cast<CalJointLayer>(cPreProc)); + + executeSegmentedPP( + transformVec, + m_ppCol[cPreProc++][etaIdx][etIdx], + transformVec); + } + } else { + cPreProc += static_cast<size_t>(CalJointLayer::NJointLayers); + } + if (trackPat){ + transformVec.clear(); + // Apply pre-processing to track Patterns separated: + trackPat->exportPatternsTo(transformVec); + executeSegmentedPP( + transformVec, + m_ppCol[cPreProc++][etaIdx][etIdx], + transformVec); + } else { + cPreProc += 1; + } + break; + } + default: + { + throw std::runtime_error(std::string("There is no implementation method " + "for ") + toStr(static_cast<SegmentationType>(segType)) ); + } + } + return; +} + +// ============================================================================= +template < + class procedure_t, + /*EtaDependency*/int etaDependency, + /*EtDependency*/int etDependency, + /*SegmentationType*/int segType +> +void RingerProcedureWrapper< + procedure_t, + etaDependency, + etDependency, + segType, + true, // isPreProcessor + false, // isDiscriminator + false> // isThreshold +::checkPPCol(){ + try { + checkCollection(m_ppCol, + static_cast<EtaDependency>(etaDependency), + static_cast<EtDependency>(etDependency)); + if ( m_ppCol.size() != numberOfSegments(static_cast<SegmentationType>(segType))){ + throw std::runtime_error(std::string("Cannot allocate segment ") + + "dependent vector of type " + toStr(static_cast<SegmentationType>(segType)) + " with size " + "different from " + std::to_string(numberOfSegments(static_cast<SegmentationType>(segType))) + + ". Current size is " + std::to_string(m_ppCol.size()) + "."); + } + } catch ( const std::runtime_error &e ) { + throw std::runtime_error(std::string("Couldn't initialize RingerPreProcessorWrapper due to: ") + + e.what() ); + } +} + +// ============================================================================= +template < + class procedure_t, + /*EtaDependency*/int etaDependency, + /*EtDependency*/int etDependency, + /*SegmentationType*/int segType +> +void RingerProcedureWrapper< + procedure_t, + etaDependency, + etDependency, + segType, + true, // isPreProcessing + false, // isDiscriminator + false> // isThreshold +::setMsgStream(MsgStream *msg) const { + // Propagate this stream into collection: + setCollectionMsgStream(msg,m_ppCol); + // Set stream to self + this->RedirectMsgStream::setMsgStream(msg); +} + +// ============================================================================= +template < + class procedure_t, + /*EtaDependency*/int etaDependency, + /*EtDependency*/int etDependency, + /*SegmentationType*/int segType +> +std::string RingerProcedureWrapper< + procedure_t, + etaDependency, + etDependency, + segType, + true, // isPreProcessor + false, // isDiscriminator + false> // isThreshold +::staticFullName() { + typedef typename RingerProcedureType<procedure_t>::procEnum_t procEnum_t; + std::stringstream ss; + ss << "RingerProcedureWrapper<" + << toStr(procedure_t::template procType<procEnum_t>() ) + << ((Ringer::is_same<procedure_t, + PreProcessing::IPreProcessorVarDep>::value)?",":"(VarDep),") + << toStr(static_cast<EtaDependency>(etaDependency)) << "," + << toStr(static_cast<EtDependency>(etDependency)) << "," + << toStr(static_cast<SegmentationType>(segType)) << ">"; + return ss.str(); +} + +// ============================================================================= +template < + class procedure_t, + /*EtaDependency*/int etaDependency, + /*EtDependency*/int etDependency, + /*SegmentationType*/int segType +> +std::string RingerProcedureWrapper< + procedure_t, + etaDependency, + etDependency, + segType, + true, // isPreProcessor + false, // isDiscriminator + false> // isThreshold +::fullName() const { + return staticFullName(); +} + +// ============================================================================= +template < + class procedure_t, + /*EtaDependency*/int etaDependency, + /*EtDependency*/int etDependency, + /*SegmentationType*/int segType +> +void RingerProcedureWrapper< + procedure_t, + etaDependency, + etDependency, + segType, + true, // isPreProcessor + false, // isDiscriminator + false> // isThreshold +::print(MSG::Level lvl) const +{ + if ( this->isStreamAvailable() ) { + if ( this->level() > lvl ){ + // Don't waste time print nothing. + return; + } + std::vector<unsigned> posVec(3); + this->msg() << lvl << fullName() << " contents: "<< endreq; + for ( size_t segIdx = 0; segIdx < m_ppCol.size() ; ++segIdx){ + posVec[0] = segIdx; + for ( size_t etIdx = 0; etIdx < m_ppCol[segIdx].size() ; ++etIdx){ + posVec[1] = etIdx; + for ( size_t etaIdx = 0; etaIdx < m_ppCol[segIdx][etIdx].size(); + ++etaIdx) + { + posVec[2] = etaIdx; + this->msg() << lvl << m_ppCol[segIdx][etIdx][etaIdx]->name() << + IOHelperFcns::makeIdxStr(posVec) << " configuration:" << endreq; + m_ppCol[segIdx][etIdx][etaIdx]->print(lvl); + } + } + } + } else { + std::cerr << "Stream is not available, cannot print " << + fullName() << "." << std::endl; + } +} + +// ============================================================================= +template < + class procedure_t, + /*EtaDependency*/int etaDependency, + /*EtDependency*/int etDependency, + /*SegmentationType*/int segType +> +void RingerProcedureWrapper< + procedure_t, + etaDependency, + etDependency, + segType, + true, // isPreProcessor + false, // isDiscriminator + false> // isThreshold +::write(TDirectory *baseDir, const char *idxStr) const +{ + // ----------- Template basics ---------- + // Create configuration directory + TDirectory *configDir = IOHelperFcns::makeDir(baseDir, + (std::string(this->name()) + idxStr).c_str() ); + + // Write basic template information: + preProcEnum_t ppType = procedure_t::template procType<preProcEnum_t>(); + SegmentationType fileSegType = static_cast<SegmentationType>(segType); + EtaDependency fileEtaDep = static_cast<EtaDependency>(etaDependency); + EtDependency fileEtDep = static_cast<EtDependency>(etDependency); + // FIXME Why do I need to use const? Unfortunately if I don't use so, the + // compiler won't accept static_casting from discr_Enum_t to unsigned int: + // some issue with reference casting. + IOHelperFcns::writeVar<const preProcEnum_t, const unsigned int>( configDir, + "ppType", + ppType); + IOHelperFcns::writeVar<const SegmentationType, const unsigned int>( configDir, + "segType", + fileSegType); + IOHelperFcns::writeVar<const EtaDependency, const unsigned int>( configDir, + "etaDependency", + fileEtaDep); + IOHelperFcns::writeVar<const EtDependency, const unsigned int>( configDir, + "etDependency", + fileEtDep); + + // Write size information: + unsigned ppSegDepSize = m_ppCol.size(); + unsigned ppEtDepSize = m_ppCol[0].size(); + unsigned ppEtaDepSize = m_ppCol[0][0].size(); + IOHelperFcns::writeVar( configDir, "ppSegDepSize" , ppSegDepSize ); + IOHelperFcns::writeVar( configDir, "ppEtDepSize" , ppEtDepSize ); + IOHelperFcns::writeVar( configDir, "ppEtaDepSize" , ppEtaDepSize ); + + // Write PreProcessors Collection + std::vector<unsigned int> ppCount(3); + for (size_t segIdx = 0; + segIdx < m_ppCol.size(); + ++segIdx) + { + ppCount[0] = segIdx; + for (size_t etIdx = 0; + etIdx < m_ppCol[segIdx].size(); + ++etIdx) + { + ppCount[1] = etIdx; + for (size_t etaIdx = 0; + etaIdx < m_ppCol[segIdx][etIdx].size(); + ++etaIdx) + { + ppCount[2] = etaIdx; + m_ppCol[segIdx][etIdx][etaIdx]->write( + configDir, + IOHelperFcns::makeIdxStr(ppCount).c_str()); + } + } + } +} + + +// ============================================================================= +template < + class procedure_t, + /*EtaDependency*/int etaDependency, + /*EtDependency*/int etDependency, + /*SegmentationType*/int segType +> +RingerProcedureWrapper<procedure_t, + etaDependency, + etDependency, + segType, + true, + false, + false> * +RingerProcedureWrapper< + procedure_t, + etaDependency, + etDependency, + segType, + true, // isPreProcessor + false, // isDiscriminator + false> // isThreshold +::read(TDirectory *configDir, unsigned /*version*/) +{ + using namespace PreProcessing; + + IOHelperFcns::checkDir(configDir); + + // ----------- PreProcesings: ---------- + // Read pre-processing collection size: + unsigned ppSegDepSize(0), + ppEtDepSize(0), + ppEtaDepSize(0); + IOHelperFcns::readVar( configDir, "ppSegDepSize", ppSegDepSize ); + IOHelperFcns::readVar( configDir, "ppEtDepSize" , ppEtDepSize ); + IOHelperFcns::readVar( configDir, "ppEtaDepSize", ppEtaDepSize ); + + // Allocate pre-processing collection with size specified on file + PPDepProcCollection ppCol( ppSegDepSize, + std::vector< std::vector< procedure_t*> >( + ppEtDepSize, std::vector< procedure_t*>( + ppEtaDepSize, nullptr ))); + + // Allocate index position retriever: + std::vector<unsigned int> ppIdxVec(3); + + // Retrieve dir list and loop on it: + std::shared_ptr<THashList> list(nullptr); + if ( !( list = IOHelperFcns::getDirList(configDir) ) ) { + std::runtime_error(std::string("Couldn't retrieve directory " + "list from wrapper folder")); + } + + TIter iter( list.get() ); + while ( TDirectory* dirObj = static_cast<TDirectory*>(iter()) ) { + + const char* folderName = dirObj->GetName(); + + //ATH_MSG_VERBOSE("Scanning directory " << folderName ); + + // Get information about the pre-processing on the folder: + preProcEnum_t ppType; + EtaDependency fileEtaDep; + EtDependency fileEtDep; + try { + IOHelperFcns::readVar<preProcEnum_t, unsigned int>(dirObj, + "procType", + ppType); + IOHelperFcns::readVar<EtaDependency, unsigned int>(dirObj, + "etaDependency", + fileEtaDep); + IOHelperFcns::readVar<EtDependency, unsigned int>(dirObj, + "etDependency", + fileEtDep); + } catch (const std::runtime_error &e){ + throw std::runtime_error(std::string("Couldn't get pre-processing type " + "while") + "reading folder: " + folderName + ". Reason: " + + e.what() ); + } + // Check if holden information dependency information is ok: + if ( fileEtaDep != etaDependency ){ + throw std::runtime_error(std::string("Folder \"") + folderName + "\" is " + + toStr(fileEtaDep) + " whereas Wrapper is " + toStr(static_cast<EtaDependency>(etaDependency)) + "."); + } + if ( fileEtDep != etDependency ){ + throw std::runtime_error(std::string("Folder \"") + folderName + "\" is " + + toStr(fileEtDep) + " whereas Wrapper is " + toStr(static_cast<EtDependency>(etDependency)) + "."); + } + // Retrieve position indexes where we shall retrieve this pre-processing + IOHelperFcns::getIdxVecFromStr( folderName, ppIdxVec ); + + // Check if everything is ok on indexes retrived: + if ( ppIdxVec.size() < 3 || + ppIdxVec[0] >= ppSegDepSize || + ppIdxVec[1] >= ppEtDepSize || + ppIdxVec[2] >= ppEtaDepSize ) + { + throw std::runtime_error(std::string("There is something wrong with ") + + "folder idxStr: " + folderName + ". Got idxStr " + + IOHelperFcns::makeIdxStr(ppIdxVec) + ". Maximum pre-processing " + "collection size is : " + std::to_string(ppSegDepSize) + "," + + std::to_string(ppEtDepSize) + "," + std::to_string(ppEtaDepSize)); + } + + // Get a reference to the pointer (only used to reduce typing): + procedure_t *&thisPP = ppCol[ppIdxVec[0]] + [ppIdxVec[1]] + [ppIdxVec[2]]; + + // Check which procedure_t this pre-processing wrapper holds. + if ( Ringer::is_same<procedure_t, IPreProcessorVarDep >::value ) + { + // If the procedure_t is not the PreProcessor interface, code will + // never get here. We only use the interpret cast so that the compiler + // doesn't complain about type casting. + thisPP = reinterpret_cast<procedure_t*>( getPP(ppType, dirObj) ); + } else { + // Here it's easier, we already know the type that is written in the file, + // so all we need to do is loop over it and retrieve the discriminator. + preProcEnum_t wrapperPPType = procedure_t::template procType<preProcEnum_t>(); + if ( ppType != wrapperPPType ){ + throw std::runtime_error( std::string("There is a pre-processing of type ") + + toStr(ppType) + " whereas this wrapper can only hold pre-processings " + "of type " + toStr(wrapperPPType)); + } + thisPP = procedure_t::read( dirObj ); + } + // ATH_MSG_VERBOSE("Successfully read directory " << folderName); + } + + // Create and return PreProcessors wrapper: + return new RingerProcedureWrapper(ppCol); + +} + + +} // Namespace Ringer + +#endif // RINGERSELECTORTOOLS_PROCEDURES_RINGERPREPROCESSORWRAPPER_ICC diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/procedures/RingerProcedureWrapper.h b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/procedures/RingerProcedureWrapper.h new file mode 100644 index 0000000000000000000000000000000000000000..271ad2d05aea6789d320058d74a5dee13e7714c7 --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/procedures/RingerProcedureWrapper.h @@ -0,0 +1,192 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: RingerProcedureWrapper.h 704615 2015-10-29 18:50:12Z wsfreund $ +#ifndef RINGERSELECTORTOOLS_PROCEDURES_RINGERPROCEDUREWRAPPER_H +#define RINGERSELECTORTOOLS_PROCEDURES_RINGERPROCEDUREWRAPPER_H + +// STL includes: +#include <vector> + +#ifndef RINGER_STANDALONE +// xAOD includes: +# include "xAODCaloRings/CaloRings.h" +# include "xAODCaloRings/RingSetConf.h" +# include "xAODTracking/TrackParticleFwd.h" +#endif + +// Local includes: +#include "RingerSelectorTools/RingerSelectorToolsDefs.h" +#include "RingerSelectorTools/procedures/IRingerProcedure.h" +#include "RingerSelectorTools/tools/VariableDependency.h" +#include "RingerSelectorTools/tools/TrackPatternsHolder.h" +#include "RingerSelectorTools/tools/RedirectMsgStream.h" +#include "RingerSelectorTools/tools/cxx/final.h" +#include "RingerSelectorTools/tools/cxx/override.h" +#include "RingerSelectorTools/tools/cxx/is_same.h" +#include "RingerSelectorTools/tools/cxx/StaticAssert.h" +#include "RingerSelectorTools/tools/cxx/RingerUseNewCppFeatures.h" + +#ifndef INCLUDE_HEADER_ONLY // Avoid circular includes +#define INCLUDE_HEADER_ONLY +#endif // INCLUDE_HEADER_ONLY +#include "RingerSelectorTools/procedures/Types.h" +#undef INCLUDE_HEADER_ONLY + +/* + * TODO List + * + * - Maybe we want to put PreProcessor Wrapper into the RingerCommonSelector + * and add to the Discriminator Wrapper a post-processing wrapper. This would + * make implementation much more flexible. + * + * - We also need to deal with the pattern space segmentation being different + * from input space, previous topic would help this to be implemented, but we + * also would need to add the segmentation representation into the Discrimators. + * This means that we might want to change the configuration classes into + * segmentation representation, which is what really we need. + * + * - The PreProcessings can be propagated into a Processing space, to merge it + * with the PostProcessings. They might be applied as both, that is, they + * will inherit from both interfaces, and we might want to apply the direct + * transformation, but also the inverse transformation (if it exists), that + * would lead the transform space into the original space. + * + * - Check why decoration cannot be read within root file using kBranchAccess. + * + * - The RingerProcedureWrapper can be divided into base templates to have its + * members created only for those cases where it is dependent. For instance, + * the collection shouldn't be dependent on seg, eta and et, but only on + * procedure_t template. This is also true for some methods, that shouldn't + * be created dependent on segment information, or even eta/et dependency. + */ + +/* + * FIXME List: + * + * - Can't apply more than one PreProcessing Wrapper when on the first + * discrimination layer. + * + */ + +namespace Ringer { + +/** + * @class IRingerProcedureWrapperBase + * @brief Used as base for all IRingerProcedureWrapper template specializations + **/ +class IRingerProcedureWrapperBase { + public: + /** + * @brief Returns whether holden interface collection is empty. + **/ + virtual bool empty() const = 0; + + /** + * @brief Write collection to TDirectory + **/ + virtual void write(TDirectory *baseDir, const char *idxStr = "") const = 0; + + /** + * @brief Retrieve RingerProcedureWrapper name + **/ + virtual const char* name() const = 0; + + /** + * @brief Returns eta dependecy for this wrapper + **/ + virtual EtaDependency etaDep() const = 0; + + /** + * @brief Returns et dependecy for this wrapper + **/ + virtual EtDependency etDep() const = 0; + + /** + * @brief Release all pointed memory holden by wrapper + **/ + virtual void releaseMemory() = 0; + + /** + * @brief Get full wrapper name + **/ + virtual std::string fullName() const = 0; + + /** + * @brief Print wrapper content + **/ + virtual void print(MSG::Level lvl = MSG::DEBUG) const = 0; + + /** + * Ensure virtual destructor + **/ + virtual ~IRingerProcedureWrapperBase(){;} + +}; + +/** + * Reduce verbosity + **/ +typedef IRingerProcedureWrapperBase IProcWrapperBase; + +/** + * Collection of interface base + **/ +typedef std::vector<IProcWrapperBase> IProcWrapperBaseCollection; + +/** + * @class IRingerProcedureWrapper + * @brief Primary Template for Ringer Interface Wrapper (not implemented) + * + * We implement specializations for each Ringer procedure type + **/ +template< typename procedure_t > +class IRingerProcedureWrapper; + +/** + * @class ProcedureHolder + * @brief Hold procedure dependent procedure vector + * + * TODO Implement this + **/ +//template<typename procedure_t> +//class ProcedureHolder; + + +/** + * @class RingerProcedureWrapper + * @brief Primary Template for Ringer Interface Wrapper (not implemented). + * + * There is a bool template for determining the procedure specialization type: + * it must not be explicitely declared. + * + * We implement specializations for each procedure type on dedicated files. + **/ +template < + class procedure_t, + /*EtaDependency*/int etaDependency = EtaIndependent, + /*EtDependency*/int etDependency = EtIndependent, + /*SegmentationType*/int segType = NoSegmentation, + // Below template parameters are not supposed to be set directly by user: + bool isPreProcessor = RingerProcedureType< procedure_t >::is_pre_processor, + bool isDiscriminator = RingerProcedureType< procedure_t >::is_discriminator, + bool isThreshold = RingerProcedureType< procedure_t >::is_threshold +> +class RingerProcedureWrapper; + +} // namespace Ringer + +#endif // RINGERSELECTORTOOLS_PROCEDURES_RINGERPROCEDUREWRAPPER_H + +#ifndef INCLUDE_HEADER_ONLY // Use to avoid circular includes +#ifndef RINGER_PROCEDURE_INCLUDE // When included a specialized procedure type +// in place of RingerProcedureWrapper it is needed to do this because +// the procedure wrapper undefines INCLUDE_HEADER_ONLY macro when including +// Types.h. This can be avoided if we don't force including all other procedure +// types wrappers, but it is wanted to make sure that when a procedure type wrapper +// is included, every other procedure is also included so that the template +// specializations are always available independent on how you include it. +#include "RingerProcedureWrapper.icc" +#endif // RINGER_PROCEDURE_INCLUDE +#endif // INCLUDE_HEADER_ONLY diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/procedures/RingerProcedureWrapper.icc b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/procedures/RingerProcedureWrapper.icc new file mode 100644 index 0000000000000000000000000000000000000000..08dce1e518cefa1a87659c8e11b787a9908cd13c --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/procedures/RingerProcedureWrapper.icc @@ -0,0 +1,441 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: RingerProcedureWrapper.icc 689837 2015-08-17 17:22:12Z wsfreund $ +#ifndef RINGERSELECTORTOOLS_PROCEDURES_RINGERPROCEDUREWRAPPER_ICC +#define RINGERSELECTORTOOLS_PROCEDURES_RINGERPROCEDUREWRAPPER_ICC + +#undef NDEBUG + +// STL includes: +#include <vector> +#include <stdexcept> + +// Local includes: +#include "RingerProcedureWrapper.h" +#include "RingerSelectorTools/RingerSelectorToolsDefs.h" +#include "RingerSelectorTools/tools/VariableDependency.h" +#include "RingerSelectorTools/tools/TrackPatternsHolder.h" +#include "RingerSelectorTools/tools/IOHelperFcns.h" + +/** + * @brief Namespace dedicated for Ringer utilities + **/ +namespace Ringer { + +namespace WrapperHelperFcns { + +// ============================================================================= +/** + * @brief Returns eta bin number which is within region. + * + * Vector Dimension: [etBin][etaBin]: + **/ +template<class vecType> +size_t findEtaBin( const float eta, + const typename std::vector< std::vector < + vecType* + > + > &varDepCol ) +{ + std::vector< vecType* > firstRow = varDepCol[0]; + for (size_t idx = 0; idx < firstRow.size(); ++idx){ + if (firstRow[idx]->isWithinEtaRange(eta)){ + return idx; + } + } + throw std::runtime_error(std::string( "eta ") + + std::to_string(eta) + " is not inside Ringer Procedure range."); +} + +// ============================================================================= +/** + * @brief Returns Et bin number which is within region. + * + * Vector Dimension: [etBin][etaBin]: + **/ +template<class vecType> +size_t findEtBin( const float et, + const std::vector< + std::vector < + vecType* + > + > &varDepCol ) +{ + for (size_t idx = 0; idx < varDepCol.size(); ++idx){ + if ( varDepCol[idx][0]->isWithinEtRange(et) ){ + return idx; + } + } + throw std::runtime_error(std::string( "Et ") + + std::to_string(et) + " is not inside Ringer Procedure range."); +} + +// ============================================================================= +template < typename vecType > +void checkCollection( const std::vector< std::vector<vecType*> > &vec, + EtaDependency etaDependency, EtDependency etDependency ) +{ + if (vec.empty()){ + throw std::runtime_error(std::string( + "Dependency collection cannot be empty.")); + } + if ( !static_cast<bool>(etDependency) && (vec.size() != 1) ) { + throw std::runtime_error(std::string( + "Cannot have EtIndependent vector with size different from unit.")); + } + for ( size_t etIdx = 0; etIdx < vec.size() ; ++etIdx){ + size_t etaSize = vec[etIdx].size(); + if ( !etaSize ){ + throw std::runtime_error(std::string( + "Dependency collection cannot have an empty vector.")); + } + if ( !static_cast<bool>(etaDependency) && (etaSize != 1) ) { + throw std::runtime_error(std::string( + "Cannot have EtaIndependent vector with size " + "different from unit.")); + } + for ( size_t etaIdx = 0; etaIdx < etaSize; ++etaIdx){ + if( !vec[etIdx][etaIdx] ){ + throw std::runtime_error(std::string( + "Dependency collection holden object is invalid.")); + } + if ( etaDependency != vec[etIdx][etaIdx]->etaDep() ){ + if ( etDependency != vec[etIdx][etaIdx]->etDep() ){ + throw std::runtime_error(std::string( + "Wrong eta and Et dependency. EtaDependency should be ") + + toStr(etaDependency) + " and is " + + toStr(vec[etIdx][etaIdx]->etaDep()) + ", as well as EtDependency " + "should be " + toStr(etDependency) + " and is " + + toStr(vec[etIdx][etaIdx]->etDep()) + "." ); + } else { + throw std::runtime_error(std::string( + "Wrong eta dependency. EtaDependency should be ") + + toStr(etaDependency) + " and is " + + toStr(vec[etIdx][etaIdx]->etaDep()) + "." ); + } + } + if ( etDependency != vec[etIdx][etaIdx]->etDep() ){ + throw std::runtime_error(std::string( + "Wrong Et dependency. EtDependency should be ") + + toStr(etDependency) + " and is " + + toStr(vec[etIdx][etaIdx]->etDep()) + "." ); + } + } + } +} + +// ============================================================================= +template < typename vecType > +void checkCollection( + const std::vector< std::vector< std::vector<vecType*> > > &vec, + EtaDependency etaDependency, EtDependency etDependency) +{ + if (vec.empty()){ + throw std::runtime_error(std::string( + "Dependency collection cannot be empty.")); + } + for ( size_t segIdx = 0; segIdx < vec.size(); ++segIdx){ + size_t etSize = vec[segIdx].size(); + if (!etSize){ + throw std::runtime_error(std::string( + "Dependency collection cannot have an" + " empty vector<vector>.")); + } + checkCollection(vec[segIdx], etaDependency, etDependency); + } +} + +// ============================================================================= +template < typename vecType > +void setCollectionMsgStream( + MsgStream *stream, + const std::vector< std::vector<vecType*> > &vec ) +{ + for ( size_t etIdx = 0; etIdx < vec.size() ; ++etIdx){ + size_t etaSize = vec[etIdx].size(); + for ( size_t etaIdx = 0; etaIdx < etaSize; ++etaIdx){ + vec[etIdx][etaIdx]->setMsgStream(stream); + } + } +} + +// ============================================================================= +template < typename vecType > +void setCollectionMsgStream( + MsgStream *stream, + const std::vector< std::vector< std::vector<vecType*> > > &vec ) +{ + for ( size_t segIdx = 0; segIdx < vec.size(); ++segIdx) { + setCollectionMsgStream(stream,vec[segIdx]); + } +} + +// ============================================================================= +/** + * @brief Ensure that segType is NoSegmentation, otherwise throws runtime_error + **/ +inline +void ensureNoSegmentationOnlyFcn(const SegmentationType segType) +{ + // XXX This shouldn't be a runtime_error, but it seems I would need to + // implement a RingerProcedureWrapper for each segType (check if this + // hypothesis is true), which would demand more time that I afford. + if (segType != SegmentationType::NoSegmentation ){ + throw std::runtime_error(std::string( + "Cannot use this method for other" + " SegmentationType then NoSegmentation.")); + } +} + +// ============================================================================= +/** + * @brief Insert toBeCopied vector values to newHolder end + **/ +inline +void insertVecToVecEnd( + const std::vector<float> &toBeCopied, + std::vector<float> &newHolder) +{ + newHolder.insert(newHolder.end(), toBeCopied.begin(), toBeCopied.end()); +} + +// ============================================================================= +/** + * @brief Execute segmented pre-processor unified routine + **/ +inline +void executeSegmentedPP( + std::vector<float> &input, + const PreProcessing::IPreProcessor *proc, + std::vector<float> &transformVec) +{ + // Transform input: + proc->execute(input); + // Concatenate it to global transformation vector: + insertVecToVecEnd(input, transformVec); + // Clear input vector: + input.clear(); +} + +// ============================================================================= +/** + * @brief Execute segmented discriminator unified routine + **/ +inline +void executeSegmentedDiscr( + std::vector<float> &input, + const Discrimination::IDiscriminator *discr, + std::vector<float> &output) +{ + // Get this procedure output into another vector: + std::vector<float> localOutput; + localOutput.reserve(output.capacity()); + // Execute on it: + discr->execute(input,localOutput); + // Concatenate it to global output vec: + insertVecToVecEnd(localOutput, output); + // Clear input vector: + input.clear(); +} + +// ============================================================================= +/** + * @brief Get Calorimeter segment from transformVec + **/ +inline +void getCaloSegmentFromTransformVec( + const unsigned nRings, + const std::vector<float> &transformVec, + std::vector<float> &transformVecSegment) +{ + transformVecSegment.clear(); + for ( size_t idx = 0; idx < nRings; ++idx ) + { + transformVecSegment.push_back(transformVec[idx]); + } +} + +// ============================================================================= +/** + * @brief Get Calorimeter segment from transformVec + **/ +template<typename segment_t> +inline +void getCaloSegmentFromTransformVec( + const xAOD::RingSetConf::RawConfCollection &rawConfCol, + const segment_t segment, + const std::vector<float> &transformVec, + std::vector<float> &transformVecSegment) +{ + + transformVecSegment.clear(); + + // Get the start and end indexes from the required segment: + unsigned startIdx(0), endIdx(0); + xAOD::RingSetConf::getEdges(rawConfCol,segment,startIdx,endIdx); + + for (unsigned idx = startIdx; idx < endIdx; ++idx ) { + transformVecSegment.push_back(transformVec[idx]); + } +} + +// ============================================================================= +/** + * @brief Get Track segment from transformVec + **/ +inline +void getTrackSegmentFromTransformVec( + const unsigned nRings, + const std::vector<float> &transformVec, + std::vector<float> &transformVecSegment) +{ + transformVecSegment.clear(); + for ( size_t idx = nRings; idx < transformVec.size(); ++idx ) { + transformVecSegment.push_back(transformVec[idx]); + } +} + + +// ============================================================================= +/** + * These macros can be used if we want to declare a specific type wrapper, so + * that it can have it dedicated compiled code. Although its wrapper calling + * method will be determined during runtime (it is holded though its + * interface), it will have its code specifically compiled for this type. This + * means that it execute its collection methods through statically determined + * methods are can also benefit of inline methods. + * + * However, it shouldn't be used for every type created, as it will increase + * compile time and library size. + * + * Besides, there is no garantee that there will be speed gain or that it won't + * be negligible. + * + * If you use the READ_ALL_DEP_WRAPPER macro, it will declare all possible + * dependent types for that class: you should pass this wrapper the variables + * that are read on the file. + * + * Instead using the READ_ALL_DEP_WRAPPER, when you need to declare only one + * specific template type for reading, you can otherwise use READ_WRAPPER. In + * this case, the passing parameters are not variables, but rather the template + * values. + * + * If you want to declare all eta/et dependent cases for a procedure type, + * you can use the READ_ETA_ET_DEP_WRAPPER, where it defines for the etaDep and + * etDep variables all possible variations. The segType however must be a + * value determined at compile time. + * + * Otherwise you want to declare segment dependent cases, which are not eta/et + * dependent, use READ_SEG_DEP_WRAPPER inserting segType as the variable and + * eta/et as compile time values, such as EtaIndependent and EtIndependent. + **/ +#define READ_WRAPPER(vec, wrapType, segType, etaDep, etDep, configDir, version) \ + vec.push_back( Ringer::RingerProcedureWrapper<wrapType, \ + etaDep, etDep, segType >::read(configDir,version) ); + +// ============================================================================= +#define READ_ETA_DEP_WRAPPER(vec, wrapType, segType, etaDep, etDep, \ + configDir, version) \ + switch( etaDep ) \ + { \ + case Ringer::EtaDependent: \ + READ_WRAPPER(vec, wrapType, segType, Ringer::EtaDependent, etDep, \ + configDir, version) \ + break; \ + case Ringer::EtaIndependent: \ + READ_WRAPPER(vec, wrapType, segType, Ringer::EtaIndependent, etDep, \ + configDir, version) \ + break; \ + default: \ + throw std::runtime_error(std::string("Unknown Eta dependency.")); \ + } + +// ============================================================================= +#define READ_SEG_DEP_WRAPPER(vec, wrapType, segType, etaDep, etDep, configDir, \ + version) \ + switch( segType ) \ + { \ + case Ringer::NoSegmentation: \ + READ_WRAPPER(vec, wrapType, Ringer::NoSegmentation, etaDep, etDep, \ + configDir, version) \ + break; \ + case Ringer::TrackCalPatTypeSegmentation: \ + READ_WRAPPER(vec, wrapType, Ringer::TrackCalPatTypeSegmentation, etaDep, \ + etDep, configDir, version) \ + break; \ + case Ringer::TrackCalSegmentation: \ + READ_WRAPPER(vec, wrapType, Ringer::TrackCalSegmentation, etaDep, etDep, \ + configDir, version) \ + break; \ + case Ringer::TrackCalJointLayers: \ + READ_ETA_ET_DEP_WRAPPER(vec, wrapType, Ringer::TrackCalJointLayers, \ + etaDep, etDep, configDir, version) \ + break; \ + case Ringer::TrackCalJointSections: \ + READ_ETA_ET_DEP_WRAPPER(vec, wrapType, Ringer::TrackCalJointSections, \ + etaDep, etDep, configDir, version) \ + default: \ + throw std::runtime_error(std::string("Unknown segmentation type")); \ + } + +// ============================================================================= +#define READ_ETA_ET_DEP_WRAPPER(vec, wrapType, segType, etaDep, etDep, \ + configDir, version) \ + switch( etDep ) \ + { \ + case Ringer::EtDependent: \ + READ_ETA_DEP_WRAPPER(vec, wrapType, segType, etaDep, Ringer::EtDependent,\ + configDir, version) \ + break; \ + case Ringer::EtIndependent: \ + READ_ETA_DEP_WRAPPER(vec, wrapType, segType, etaDep, \ + Ringer::EtIndependent, configDir, version) \ + break; \ + default: \ + throw std::runtime_error(std::string("Unknown Et dependency.")); \ + } + +// ============================================================================= +#define READ_ALL_DEP_WRAPPER(vec, wrapType, segType, etaDep, etDep, \ + configDir, version ) \ + switch( segType ) \ + { \ + case Ringer::NoSegmentation: \ + READ_ETA_ET_DEP_WRAPPER(vec, wrapType, Ringer::NoSegmentation, etaDep, \ + etDep, configDir, version ) \ + break; \ + case Ringer::TrackCalPatTypeSegmentation: \ + READ_ETA_ET_DEP_WRAPPER(vec, wrapType, \ + Ringer::TrackCalPatTypeSegmentation, \ + etaDep, etDep, configDir, version ) \ + break; \ + case Ringer::TrackCalSegmentation: \ + READ_ETA_ET_DEP_WRAPPER(vec, wrapType, \ + Ringer::TrackCalSegmentation, etaDep, \ + etDep, configDir, version ) \ + break; \ + case Ringer::TrackCalJointLayers: \ + READ_ETA_ET_DEP_WRAPPER(vec, wrapType, \ + Ringer::TrackCalJointLayers, etaDep, \ + etDep, configDir, version) \ + break; \ + case Ringer::TrackCalJointSections: \ + READ_ETA_ET_DEP_WRAPPER(vec, wrapType, \ + Ringer::TrackCalJointSections, etaDep, \ + etDep, configDir, version) \ + default: \ + throw std::runtime_error(std::string("Unknown segmentation type")); \ + } + + +} // WrapperUtils namespace + +} // Ringer namespace + +#include "RingerSelectorTools/procedures/RingerPreProcessorWrapper.icc" +#include "RingerSelectorTools/procedures/RingerDiscriminatorWrapper.icc" +#include "RingerSelectorTools/procedures/RingerThresholdWrapper.icc" + +#endif // RINGERSELECTORTOOLS_PROCEDURES_RINGERPROCEDUREWRAPPER_ICC diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/procedures/RingerThresholdWrapper.h b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/procedures/RingerThresholdWrapper.h new file mode 100644 index 0000000000000000000000000000000000000000..fbe3ebba815732aec5b321f276f3fb4b6ef5754e --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/procedures/RingerThresholdWrapper.h @@ -0,0 +1,241 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: RingerThresholdWrapper.h 704615 2015-10-29 18:50:12Z wsfreund $ +#ifndef RINGERSELECTORTOOLS_PROCEDURES_RINGERTHRESHOLDWRAPPER_H +#define RINGERSELECTORTOOLS_PROCEDURES_RINGERTHRESHOLDWRAPPER_H + +#define RINGER_PROCEDURE_INCLUDE +#include "RingerProcedureWrapper.h" +#undef RINGER_PROCEDURE_INCLUDE + +//#undef NDEBUG + +/** + * @brief Namespace dedicated for Ringer utilities + **/ +namespace Ringer { + +/** + * @class IRingerProcedureWrapper + * @brief Specialization for Threshold procedure. + **/ +template<> +class IRingerProcedureWrapper< Discrimination::IThreshold > : + virtual public IRedirectMsgStream, + virtual public IRingerProcedureWrapperBase +{ + public: + /** + * @brief Collection type of PreProcessor Wrappers. + **/ + typedef typename std::vector< IRingerProcedureWrapper* > WrapperCollection; + + /** + * @brief Apply threshold to obtain a decision. + **/ + virtual void getOutput( + const DepVarStruct &depVar, + const std::vector<float> &discrOutput, + std::vector<bool> &decision) const = 0; + + /** + * @brief Returns whether holden interface collection is empty. + **/ + virtual bool empty() const ATH_RINGER_OVERRIDE = 0; + + /** + * @brief Returns this wrapper name + **/ + virtual const char* name() const ATH_RINGER_FINAL ATH_RINGER_OVERRIDE { + return wrapName; + } + +#if RINGER_USE_NEW_CPP_FEATURES + static constexpr const char* wrapName = "RingerThresholdWrapper"; +#else + static const char* wrapName; +#endif + + /** Ensure virtual destructor */ + virtual ~IRingerProcedureWrapper(){;} + + /** + * Write wrapper to file. + **/ + static void writeWrapper(const IRingerProcedureWrapper *thresWrapper, + const char *fileName); + + /** + * Read wrapper from file. + **/ + static void read(IRingerProcedureWrapper *&thresWrapper, + const char* fileName); + + protected: + IRingerProcedureWrapper(){;} + +}; + +/** + * @brief Facilitate access into Threshold Wrappers. + **/ +typedef IRingerProcedureWrapper< Discrimination::IThreshold > IThresWrapper; +/** + * @brief Facilitate access into Threshold Wrappers collection. + **/ +typedef IThresWrapper::WrapperCollection IThresWrapperCollection; + +/** + * @class RingerProcedureWrapper + * @brief Specialization for Threshold procedure. + **/ +template < class procedure_t, + /*EtaDependency*/int etaDependency, + /*EtDependency*/int etDependency> +class RingerProcedureWrapper< + procedure_t, + etaDependency, + etDependency, + SegmentationType::NoSegmentation, // Threshold is always unique for + // all layers, as it is applied for the discriminator output space. + false, // isPreProcessor + false, // isDiscriminator + true> : // isThreshold + public IThresWrapper, + public RedirectMsgStream +{ + RINGER_STATIC_ASSERT( + (Ringer::is_base_of<VariableDependency,procedure_t>::value), + "RingerProcedureWrapper procedure_t type must have IVariableDependecy inheritance."); + public: + /// RingerProcedureWrapper for Threshold procedures typedefs: + ///@{ + /** + * @brief typedef to the Ringer Interface variable dependency collection + * + * Collection Dimension: [etBin][etaBin]: + * + **/ + typedef typename std::vector < + std::vector < procedure_t* > + > ThresDepProcCollection; + ///@} + + /// Ctors: + ///@{ + /** + * @brief Build RProc Wrapper + **/ + RingerProcedureWrapper( + const ThresDepProcCollection &thresDepCol): + m_thresCol(thresDepCol) + { + checkThresCol(); + m_thres = m_thresCol[0][0]; + } + ///@} + + /// Main methods: + /// @{ + /** + * @brief Apply threshold to obtain a decision. + **/ + virtual void getOutput( + const DepVarStruct &depVar, + const std::vector<float> &discrOutput, + std::vector<bool> &decision) const ATH_RINGER_OVERRIDE; + /// @} + + + /// Other utilities + /// @{ + /** + * @brief Returns whether holden interface collection is empty. + **/ + virtual bool empty() const ATH_RINGER_OVERRIDE { return m_thresCol.empty();} + + /** + * @brief Overloads the setMsgStream from RedirectMsgStream. + **/ + virtual void setMsgStream(MsgStream *msg) const ATH_RINGER_OVERRIDE; + + /** + * @brief Release all holden pointer memory + **/ + void releaseMemory() ATH_RINGER_OVERRIDE ATH_RINGER_FINAL; + + /** + * @brief Returns eta dependecy for this wrapper + **/ + EtaDependency etaDep() const + ATH_RINGER_OVERRIDE ATH_RINGER_FINAL + { + return static_cast<EtaDependency>(etaDependency); + } + + /** + * @brief Returns et dependecy for this wrapper + **/ + EtDependency etDep() const + ATH_RINGER_OVERRIDE ATH_RINGER_FINAL + { + return static_cast<EtDependency>(etDependency); + } + + /** + * @brief Get full wrapper name, static method + **/ + static std::string staticFullName(); + + /** + * @brief Get full wrapper name + **/ + std::string fullName() const ATH_RINGER_OVERRIDE ATH_RINGER_FINAL; + + /** + * @brief Print wrapper content + **/ + void print(MSG::Level lvl = MSG::DEBUG) const ATH_RINGER_OVERRIDE ATH_RINGER_FINAL; + + /** + * @brief Write wrapper to TDirectory + **/ + void write(TDirectory *baseDir, const char *idxStr = "") const + ATH_RINGER_OVERRIDE ATH_RINGER_FINAL; + + /** + * @brief Read wrapper from TDirectory + **/ + static RingerProcedureWrapper* read(TDirectory *configDir, + unsigned version); + ///@} + + private: + /// Private Methods: + ///@{ + /** + * @brief Check if threshold interface collection is in good status + * (Throws otherwise) + **/ + void checkThresCol(); + ///@} + + /// Private Properties: + ///@{ + /// @brief holden threshold collection: + ThresDepProcCollection m_thresCol; + /// @brief Hold pointer to first threshold from collection + /// Used when it has no variable dependency. + procedure_t* m_thres; + ///@} +}; + +} // namespace Ringer + +#endif // RINGERSELECTORTOOLS_PROCEDURES_RINGERTHRESHOLDWRAPPER_H + +#ifndef INCLUDE_HEADER_ONLY // Use to avoid circular includes +#include "RingerThresholdWrapper.icc" +#endif // INCLUDE_HEADER_ONLY diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/procedures/RingerThresholdWrapper.icc b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/procedures/RingerThresholdWrapper.icc new file mode 100644 index 0000000000000000000000000000000000000000..8628d7ae0a277efa811c00e587a7ce6a1fa0a25e --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/procedures/RingerThresholdWrapper.icc @@ -0,0 +1,456 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: RingerThresholdWrapper.icc 704615 2015-10-29 18:50:12Z wsfreund $ +#ifndef RINGERSELECTORTOOLS_PROCEDURES_RINGERTHRESHOLDWRAPPER_ICC +#define RINGERSELECTORTOOLS_PROCEDURES_RINGERTHRESHOLDWRAPPER_ICC + +#include "RingerThresholdWrapper.h" +#include "RingerProcedureWrapper.icc" + +#include "RingerSelectorTools/tools/cxx/is_same.h" + +#include "RingerSelectorTools/procedures/Thresholds.h" + +namespace Ringer { + +namespace WrapperHelperFcns { + +/** + * Return the threshold on dirObj of thresType + **/ +inline +Discrimination::IThresholdVarDep* getThres(thresEnum_t thresType, + TDirectory *dirObj ) +{ + using namespace Discrimination; + // For the interface case, we will have to create each threshold + // depending on the information written on thresType: + switch ( thresType ) + { + case thresEnum_t::UniqueThreshold: + { + return UniqueThresholdVarDep::read( dirObj ); + break; + } + default: + { + throw std::runtime_error( std::string("Cannot read threshold of ") + + "type: " + toStr(thresType) ); + } + } +} +} // private namespace + + +// Import Wrapper Helper functions +using namespace WrapperHelperFcns; + +// ============================================================================= +// ------------------------------------- +// RingerProcedureWrapper for Thresholds +// ------------------------------------- +// ============================================================================= + +/**/ + +// ============================================================================= +template < + class procedure_t, + /*EtaDependency*/int etaDependency, + /*EtDependency*/int etDependency +> +void RingerProcedureWrapper< + procedure_t, + etaDependency, + etDependency, + SegmentationType::NoSegmentation, + false, + false, + true > +::releaseMemory() +{ + for ( size_t etIdx = 0; etIdx < m_thresCol.size() ; ++etIdx){ + for ( size_t etaIdx = 0; etaIdx < m_thresCol[etIdx].size(); ++etaIdx) + { + delete m_thresCol[etIdx][etaIdx]; + } + } + m_thresCol.clear(); + m_thres = nullptr; +} + +// ============================================================================= +template < + class procedure_t, + /*EtaDependency*/int etaDependency, + /*EtDependency*/int etDependency +> +void RingerProcedureWrapper< + procedure_t, + etaDependency, + etDependency, + SegmentationType::NoSegmentation, + false, + false, + true > +::getOutput( + const DepVarStruct &depVar, + const std::vector<float> &discrOutput, + std::vector<bool> &decision) const +{ +#ifndef NDEBUG + ATH_MSG_DEBUG("Running getOutput."); +#endif + + // If no dependency, simply use threshold and return + if ( !etaDependency && !etDependency ){ + m_thres->execute(discrOutput,decision); + return; + } + + // Initialize eta and et indexes: + size_t etaIdx(0), etIdx(0); + // Get the correct pp to be applied: + if (etaDependency){ + etaIdx = findEtaBin(depVar.eta, m_thresCol); + } + if (etDependency){ + etIdx = findEtBin(depVar.et, m_thresCol); + } +#ifndef NDEBUG + ATH_MSG_VERBOSE("Applying threshold at etaIdx (" << + etaIdx << ") and etIdx (" << etIdx << ")."); +#endif + // Apply it: + m_thresCol[etIdx][etaIdx]->execute(discrOutput,decision); +} + +// ============================================================================= +template < + class procedure_t, + /*EtaDependency*/int etaDependency, + /*EtDependency*/int etDependency +> +void RingerProcedureWrapper< + procedure_t, + etaDependency, + etDependency, + SegmentationType::NoSegmentation, + false, // isPreProcessor + false, // isDiscriminator + true> // isThreshold +::checkThresCol(){ + try { + checkCollection(m_thresCol, + static_cast<EtaDependency>(etaDependency), + static_cast<EtDependency>(etDependency)); + } catch ( const std::runtime_error &e ) { + throw std::runtime_error(std::string("Couldn't initialize RingerThresholdWrapper due to: ") + + e.what() ); + } +} + +// ============================================================================= +template < + class procedure_t, + /*EtaDependency*/int etaDependency, + /*EtDependency*/int etDependency +> +void RingerProcedureWrapper< + procedure_t, + etaDependency, + etDependency, + SegmentationType::NoSegmentation, + false, // isPreProcessor + false, // isDiscriminator + true> // isThreshold +::setMsgStream(MsgStream *msg) const { + // Propagate this stream into collection: + setCollectionMsgStream(msg,m_thresCol); + // Set stream to self + this->RedirectMsgStream::setMsgStream(msg); +} + +// ============================================================================= +template < + class procedure_t, + /*EtaDependency*/int etaDependency, + /*EtDependency*/int etDependency +> +std::string RingerProcedureWrapper< + procedure_t, + etaDependency, + etDependency, + SegmentationType::NoSegmentation, + false, // isPreProcessor + false, // isDiscriminator + true> // isThreshold +::staticFullName() { + typedef typename RingerProcedureType<procedure_t>::procEnum_t procEnum_t; + std::stringstream ss; + ss << "RingerProcedureWrapper<" + << toStr(procedure_t::template procType<procEnum_t>() ) + << ((Ringer::is_same<procedure_t,Discrimination::IThresholdVarDep>::value)?",":"(VarDep),") + << toStr(static_cast<EtaDependency>(etaDependency)) << "," + << toStr(static_cast<EtDependency>(etDependency)) << "," + << toStr(NoSegmentation) << ">"; + return ss.str(); +} + +// ============================================================================= +template < + class procedure_t, + /*EtaDependency*/int etaDependency, + /*EtDependency*/int etDependency +> +std::string RingerProcedureWrapper< + procedure_t, + etaDependency, + etDependency, + SegmentationType::NoSegmentation, + false, // isPreProcessor + false, // isDiscriminator + true> // isThreshold +::fullName() const { + return staticFullName(); +} + +// ============================================================================= +template < + class procedure_t, + /*EtaDependency*/int etaDependency, + /*EtDependency*/int etDependency +> +void RingerProcedureWrapper< + procedure_t, + etaDependency, + etDependency, + SegmentationType::NoSegmentation, + false, // isPreProcessor + false, // isDiscriminator + true> // isThreshold +::print(MSG::Level lvl) const +{ + if ( this->isStreamAvailable() ) { + if ( this->level() > lvl ){ + // Dont waste time printing nothing + return; + } + this->msg() << lvl << fullName() << " contents: "<< endreq; + std::vector<unsigned> posVec(2); + for ( unsigned etIdx = 0; etIdx < m_thresCol.size() ; ++etIdx){ + posVec[0] = etIdx; + for ( unsigned etaIdx = 0; etaIdx < m_thresCol[etIdx].size(); ++etaIdx) + { + posVec[1] = etaIdx; + this->msg() << lvl << m_thresCol[etIdx][etaIdx]->name() << + IOHelperFcns::makeIdxStr(posVec) << " configuration:" << endreq; + m_thresCol[etIdx][etaIdx]->print(lvl); + } + } + } else { + std::cerr << "Stream is not available, cannot print " << + fullName() << "." << std::endl; + } +} + +// ============================================================================= +template < + class procedure_t, + /*EtaDependency*/int etaDependency, + /*EtDependency*/int etDependency +> +void RingerProcedureWrapper< + procedure_t, + etaDependency, + etDependency, + SegmentationType::NoSegmentation, + false, // isPreProcessor + false, // isDiscriminator + true> // isThreshold +::write(TDirectory *baseDir, const char *idxStr) const +{ + // ----------- Template basics ---------- + // Create configuration directory + TDirectory *configDir = IOHelperFcns::makeDir(baseDir, + (std::string(this->name()) + idxStr).c_str() ); + + // Write basic template information: + thresEnum_t thresType = procedure_t::template procType<thresEnum_t>(); + EtaDependency fileEtaDep = static_cast<EtaDependency>(etaDependency); + EtDependency fileEtDep = static_cast<EtDependency>(etDependency); + // FIXME Why do I need to use const? Unfortunately if I don't use so, the + // compiler won't accept static_casting from discr_Enum_t to unsigned int: + // some issue with reference casting. + IOHelperFcns::writeVar<const thresEnum_t, const unsigned int>( configDir, + "thresType", + thresType); + IOHelperFcns::writeVar<const EtaDependency, const unsigned int>( configDir, + "etaDependency", + fileEtaDep); + IOHelperFcns::writeVar<const EtDependency, const unsigned int>( configDir, + "etDependency", + fileEtDep); + + // Write size information: + unsigned thresEtDepSize = m_thresCol.size(); + unsigned thresEtaDepSize = m_thresCol[0].size(); + IOHelperFcns::writeVar( configDir, "thresEtDepSize" , thresEtDepSize ); + IOHelperFcns::writeVar( configDir, "thresEtaDepSize" , thresEtaDepSize ); + + // Write Threshold collection + std::vector<unsigned int> thresCount(2); + for (size_t etIdx = 0; + etIdx < m_thresCol.size(); + ++etIdx) + { + thresCount[0] = etIdx; + for (size_t etaIdx = 0; + etaIdx < m_thresCol[etIdx].size(); + ++etaIdx) + { + thresCount[1] = etaIdx; + m_thresCol[etIdx][etaIdx]->write( + configDir, + IOHelperFcns::makeIdxStr(thresCount).c_str()); + } + } +} + +// ============================================================================= +template < + class procedure_t, + /*EtaDependency*/int etaDependency, + /*EtDependency*/int etDependency +> +RingerProcedureWrapper< + procedure_t, + etaDependency, + etDependency, + SegmentationType::NoSegmentation, + false, + false, + true> * +RingerProcedureWrapper< + procedure_t, + etaDependency, + etDependency, + SegmentationType::NoSegmentation, + false, // isPreProcessor + false, // isDiscriminator + true> // isThreshold +::read(TDirectory *configDir, unsigned /*version*/) +{ + using namespace Discrimination; + + IOHelperFcns::checkDir(configDir); + + // ----------- PreProcesings: ---------- + // Read pre-processing collection size: + unsigned thresEtDepSize(0), + thresEtaDepSize(0); + IOHelperFcns::readVar( configDir, "thresEtDepSize" , thresEtDepSize ); + IOHelperFcns::readVar( configDir, "thresEtaDepSize", thresEtaDepSize ); + + // Allocate pre-processing collection with size specified on file + ThresDepProcCollection thresCol( thresEtDepSize, + std::vector< procedure_t*>( + thresEtaDepSize, nullptr )); + + // Allocate index position retriever: + std::vector<unsigned int> thresIdxVec(2); + + // Retrieve dir list and loop on it: + std::shared_ptr<THashList> list(nullptr); + if ( !( list = IOHelperFcns::getDirList(configDir) ) ) { + std::runtime_error(std::string("Couldn't retrieve directory " + "list from wrapper folder")); + } + + TIter iter( list.get() ); + while ( TDirectory* dirObj = static_cast<TDirectory*>(iter()) ) { + + const char* folderName = dirObj->GetName(); + + //ATH_MSG_VERBOSE("Scanning directory " << folderName ); + + // Get information about the pre-processing on the folder: + thresEnum_t thresType; + EtaDependency fileEtaDep; + EtDependency fileEtDep; + try { + IOHelperFcns::readVar<thresEnum_t, unsigned int>(dirObj, + "procType", + thresType); + IOHelperFcns::readVar<EtaDependency, unsigned int>(dirObj, + "etaDependency", + fileEtaDep); + IOHelperFcns::readVar<EtDependency, unsigned int>(dirObj, + "etDependency", + fileEtDep); + } catch (const std::runtime_error &e){ + throw std::runtime_error(std::string("Couldn't get threshold type " + "while") + " reading folder: " + folderName + ". Reason: " + + e.what() ); + } + // Check if holden information dependency information is ok: + if ( fileEtaDep != etaDependency ){ + throw std::runtime_error(std::string("Folder \"") + folderName + "\" is " + + toStr(fileEtaDep) + " whereas Wrapper is " + toStr(static_cast<EtaDependency>(etaDependency)) + "."); + } + if ( fileEtDep != etDependency ){ + throw std::runtime_error(std::string("Folder \"") + folderName + "\" is " + + toStr(fileEtDep) + " whereas Wrapper is " + toStr(static_cast<EtDependency>(etDependency)) + "."); + } + // Retrieve position indexes where we shall retrieve this pre-processing + IOHelperFcns::getIdxVecFromStr( folderName, thresIdxVec ); + + // Check if everything is ok on indexes retrived: + if ( thresIdxVec.size() < 2 || + thresIdxVec[0] >= thresEtDepSize || + thresIdxVec[1] >= thresEtaDepSize ) + { + throw std::runtime_error(std::string("There is something wrong with ") + + "folder idxStr: " + folderName + ". Got idxStr " + + IOHelperFcns::makeIdxStr(thresIdxVec) + ". Maximum threshold " + "collection size is : " + std::to_string(thresEtDepSize) + "," + + std::to_string(thresEtaDepSize)); + } + + // Get a reference to the pointer (only used to reduce typing): + procedure_t *&thisThres = thresCol[thresIdxVec[0]] + [thresIdxVec[1]]; + + // Check which procedure_t this pre-processing wrapper holds. + if ( Ringer::is_same<procedure_t, IThresholdVarDep >::value ) + { + // If the procedure_t is not the PreProcessor interface, code will + // never get here. We only use the interpret cast so that the compiler + // doesn't complain about type casting. + thisThres = reinterpret_cast<procedure_t*>( getThres(thresType, dirObj) ); + // FIXME New compiler version complains to use static_cast, but would it compile on + // older versions? + } else { + // Here it's easier, we already know the type that is written in the file, + // so all we need to do is loop over it and retrieve the discriminator. + thresEnum_t wrapperThresType = procedure_t::template procType<thresEnum_t>(); + if ( thresType != wrapperThresType ){ + throw std::runtime_error( std::string("There is a pre-processing of type ") + + toStr(thresType) + " whereas this wrapper can only hold pre-processings " + "of type " + toStr(wrapperThresType)); + } + thisThres = procedure_t::read( dirObj ); + } + // ATH_MSG_VERBOSE("Successfully read directory " << folderName); + } + + // Create and return PreProcessors wrapper: + return new RingerProcedureWrapper(thresCol); + +} + +} // Namespace Ringer + +#endif // RINGERSELECTORTOOLS_PROCEDURES_RINGERTHRESHOLDWRAPPER_ICC diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/procedures/Thresholds.h b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/procedures/Thresholds.h new file mode 100644 index 0000000000000000000000000000000000000000..ecec51676cc0c94cee8a5dc46c9f57caec3303dd --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/procedures/Thresholds.h @@ -0,0 +1,99 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: Thresholds.h 694257 2015-09-10 22:45:27Z wsfreund $ +#ifndef RINGERSELECTORTOOLS_PROCEDURES_THRESHOLDS_H +#define RINGERSELECTORTOOLS_PROCEDURES_THRESHOLDS_H + +//#undef NDEBUG + +// STL includes: +#include <vector> + +// Local includes: +#include "RingerSelectorTools/RingerSelectorToolsDefs.h" +#include "RingerSelectorTools/procedures/IRingerProcedure.h" + +// Local tools: +#include "RingerSelectorTools/tools/RingerIOVarDepObj.h" +#include "RingerSelectorTools/tools/VariableDependency.h" +#include "RingerSelectorTools/tools/RedirectMsgStream.h" +#include "RingerSelectorTools/tools/cxx/final.h" +#include "RingerSelectorTools/tools/cxx/override.h" + +/** + * @brief Namespace dedicated for Ringer utilities + **/ +namespace Ringer { + +/** + * @brief Namespace dedicated for Ringer Discrimination utilities + **/ +namespace Discrimination { + +/// Threshold interfaces +/// @{ +class UniqueThreshold : virtual public IThreshold, + public RedirectMsgStream +{ + + RINGER_IO_VARDEP_BASE(UniqueThreshold) + + private: + float m_threshold; + protected: + UniqueThreshold(const float threshold):m_threshold(threshold){;} + public: + + UniqueThreshold(): + m_threshold(0){;} + + /** Execute threshold */ + virtual void execute(const std::vector<float> &input, + std::vector<bool> &output) const ATH_RINGER_OVERRIDE ATH_RINGER_FINAL; + + /** Ensure virtual dtor */ + virtual ~UniqueThreshold(){;} + /** Define it as a Root TObjebt, disable I/O */ + //ClassDef(UniqueThreshold,0) +}; + +RINGER_DEFINE_PROCEDURE_DEFAULT_METHODS( UniqueThreshold ) + +/// @} + + +/** + * @brief Unique threshold + **/ +class UniqueThresholdVarDep : virtual public IThresholdVarDep, + public RingerIOVarDepObj < UniqueThresholdVarDep >, + public UniqueThreshold +{ + RINGER_IO_VARDEP_OBJ(UniqueThresholdVarDep, UniqueThreshold) + public: + + /** Default ctor (needed by ClassDef) */ + UniqueThresholdVarDep(){;} + + /** Obj ctor */ + UniqueThresholdVarDep(const float threshold): + UniqueThreshold(threshold){;} + + /** Ensure virtual dtor */ + virtual ~UniqueThresholdVarDep(){;} + + /** Define it as a Root TObjebt, set version 1 */ + //ClassDef(UniqueThresholdVarDep,1) +}; + +} // namespace Discrimination +} // namespace Ringer + +#endif // RINGERSELECTORTOOLS_PROCEDURES_THRESHOLDS_H + +#ifndef INCLUDE_HEADER_ONLY // Use to avoid circular includes +#include "Thresholds.icc" +#endif // INCLUDE_HEADER_ONLY + diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/procedures/Thresholds.icc b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/procedures/Thresholds.icc new file mode 100644 index 0000000000000000000000000000000000000000..066183aa581c64042a013e2b8a57177f6d4c66a5 --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/procedures/Thresholds.icc @@ -0,0 +1,50 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: Thresholds.icc 667905 2015-05-18 19:07:55Z wsfreund $ +#ifndef RINGERSELECTORTOOLS_PROCEDURES_THRESHOLDS_ICC +#define RINGERSELECTORTOOLS_PROCEDURES_THRESHOLDS_ICC + +#include "Thresholds.h" + +/** + * @brief Namespace dedicated for Ringer utilities + **/ +namespace Ringer { + +/** + * @brief Namespace dedicated for Ringer Discrimination utilities + **/ +namespace Discrimination { + +// ============================================================================= +inline +void UniqueThreshold::execute(const std::vector<float> &input, + std::vector<bool> &output) const +{ +#ifndef NDEBUG + ATH_MSG_DEBUG("Applying UniqueThreshold (Value: " << m_threshold + << "). Output space is: " << input); +#endif + output.clear(); + if ( input.empty() ) { + throw std::runtime_error( + std::string("Entered UniqueDimThreshold.execute" + " with input.size() == 0")); + } + output.push_back( input[0] > m_threshold ); +#ifndef NDEBUG + std::ios_base::fmtflags flags = std::cout.flags(); + ATH_MSG_DEBUG("Decision is: " << output); + // reset previous cout flags + std::cout.flags(flags); +#endif +} + +} // namespace Discrimination +} // namespace Ringer + +#endif // RINGERSELECTORTOOLS_PROCEDURES_THRESHOLDS_ICC + +// vim: filetype=cpp : diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/procedures/Types.h b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/procedures/Types.h new file mode 100644 index 0000000000000000000000000000000000000000..6054ef8210bd6d5ec422704fa9d6bfb9e2229fa0 --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/procedures/Types.h @@ -0,0 +1,113 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: Types.h 667905 2015-05-18 19:07:55Z wsfreund $ +#ifndef RINGERSELECTORTOOLS_TOOLS_PROCEDURES_TYPES_H +#define RINGERSELECTORTOOLS_TOOLS_PROCEDURES_TYPES_H + +// STL includes: +#include <string> +#include <stdexcept> + +/** + * + * WARNING: Do not change the order of the enumerations for backward files + * compatibility!! + * + * This means that if a new value is needed, add it to the end of the + * enumeration, instead adding it to any place in the enumeration. + * + * Every time a Ringer Procedure is created, it is needed to add it in this + * file: this is necessary to IO. Otherwise it won't even compile. + * + * After adding a enumeration type, also add it to the methods in the + * Types.cxx file. + * + **/ + +namespace Ringer { + +namespace PreProcessing { +namespace Type { + +enum PreProcessorTypes { + IPreProcessorVarDep, + IPreProcessor, + Norm1, + Norm2, + Sqrt, + ConstantValue, + Sequential, + Spherization, + MinMax +}; +} // namespace Type +} // namespace PreProcessing + +namespace Discrimination { +namespace Type { + +enum DiscriminatorTypes { + IDiscriminatorVarDep, + IDiscriminator, + NNFeedForward +}; + +enum ThresholdTypes { + IThresholdVarDep, + IThreshold, + UniqueThreshold +}; +} // namespace Type +} // namespace Discrimination + +// We are at Ringer namespace again + +typedef PreProcessing::Type::PreProcessorTypes preProcEnum_t; +typedef Discrimination::Type::DiscriminatorTypes discrEnum_t; +typedef Discrimination::Type::ThresholdTypes thresEnum_t; + +/** + * Return Ringer enumeration of type T identifying string type: + **/ +template<typename T> +T getType(const char* cStr); + +/** + * Specialization for PreProcessorTypes: + **/ +template<> +preProcEnum_t getType(const char* cStr); + +/** + * Specialization for DiscriminatorTypes: + **/ +template<> +discrEnum_t getType(const char* cStr); + +/** + * Specialization for ThresholdTypes: + **/ +template<> +thresEnum_t getType(const char* cStr); + +/** + * Transform enumeration types to string + **/ +const char* toStr(preProcEnum_t e); + +/** + * Transform enumeration types to string + **/ +const char* toStr(discrEnum_t e); + +/** + * Transform enumeration types to string + **/ +const char* toStr(thresEnum_t t); + +} // namespace Ringer + +#endif // RINGERSELECTORTOOLS_TOOLS_PROCEDURES_TYPES_H + diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/selection.xml b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/selection.xml new file mode 100644 index 0000000000000000000000000000000000000000..036e6a829f796ce7377e3376f5c6c9d6c5d57318 --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/selection.xml @@ -0,0 +1,71 @@ +<lcgdict> + + <!-- Needed for adding logging capabilities on python (?)--> + <!-- Redirect MsgStream dictionary: --> + <!-- + <class name="Ringer::RedirectMsgStream"> + <field name="m_msg" transient="true" /> + </class> + --> + + <class class="Ringer::VariableDependency" /> + + <!-- The multi-tool and some configurables --> + <class name="Ringer::AsgElectronRingerSelector" /> + <class pattern="Ringer::ElectronTAccept*" /> + <class pattern="Ringer::BitdefElectron*" /> + + <!-- The procedures --> + <class name="Ringer::PreProcessing::Norm::Norm1VarDep" /> + <class name="Ringer::Discrimination::NNFeedForwardVarDep" /> + <class name="Ringer::Discrimination::UniqueThresholdVarDep" /> + + <!-- The wrapper templates --> + <class name="Ringer::IPreProcWrapper" /> + <class name="Ringer::IPreProcWrapperCollection" /> + <class name="Ringer::IDiscrWrapper" /> + <class name="Ringer::IDiscrWrapperCollection" /> + <class name="Ringer::IThresWrapper" /> + <class pattern="Ringer::RingerProcedureWrapper<*" /> + <!-- Include the templated Ringer vectors--> + <class pattern="std::vector<Ringer::*" /> + <class pattern="std::vector<std::vector<Ringer::*" /> + + <!-- Add every enum/fnc within Ringer namespace --> + <enum pattern="Ringer::*"/> + <function pattern="Ringer::*"/> + + <!-- <class pattern="Ringer::*" /> --> + + <!-- Remove extra Root catch-ups by above patterns that we dont want --> + <exclusion> + <class pattern="*ROOTDict::*" /> + <class pattern="*boost_static_assert_typedef*" /> + <class pattern="Ringer::is_base_of*" /> + <class pattern="Ringer::is_same*" /> + <enum name="Ringer::CalJointSection" /> + <enum name="Ringer::CalJointLayer" /> + <function pattern="Ringer::PreProcessing*"/> + <function pattern="Ringer::WrapperHelperFcns*"/> + <class pattern="*bitMskWord*" /> + </exclusion> + + <!-- + <class name="std::vector<long long>"/> + <class name="std::vector<unsigned long long>"/> + <class name="std::vector<unsigned long>"/> + <class name="std::vector<Ringer::EtaDependency>"/> + --> + + <!-- Pool read xAOD::CaloRings_v1 --> + <!-- Take a look at https://root.cern.ch/root/html532/io/DataModelEvolution.html + <read sourceClass="xAOD::CaloRings_v1" version="[1-]" + targetClass="xAOD::CaloRings_v1" source="" + target="m_isRingSetCached" > + <![CDATA[ + m_isRingSetCached = false; + ]]> + </read> + --> + +</lcgdict> diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/DeclareBit.h b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/DeclareBit.h new file mode 100644 index 0000000000000000000000000000000000000000..a031f6c30f5ea33732eb2e5cce353b7090490241 --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/DeclareBit.h @@ -0,0 +1,94 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: DeclareBit.h 693573 2015-09-07 19:15:49Z wsfreund $ +#ifndef RINGER_STANDALONE + +#ifndef RINGERSELECTORTOOLS_TOOLS_DECLARE_BIT_H +#define RINGERSELECTORTOOLS_TOOLS_DECLARE_BIT_H + +#include <utility> + +#include "RingerSelectorTools/tools/cxx/StaticAssert.h" +#include "RingerSelectorTools/tools/cxx/stringify.h" + +/** + * @brief Static counter. + * + * Made by David Krauss, used with author concent. + * + * Counts up to 64, taken from http://stackoverflow.com/a/6174263/1162884 + **/ +/// @{ +#define COUNTER_READ_CRUMB( TAG, RANK, ACC ) \ + counter_crumb( TAG(), constant_index< RANK >(), constant_index< ACC >() ) + +#define COUNTER_READ( TAG ) \ + COUNTER_READ_CRUMB( TAG, 1, \ + COUNTER_READ_CRUMB( TAG, 2, \ + COUNTER_READ_CRUMB( TAG, 4, \ + COUNTER_READ_CRUMB( TAG, 8, \ + COUNTER_READ_CRUMB( TAG, 16, \ + COUNTER_READ_CRUMB( TAG, 32, \ + COUNTER_READ_CRUMB( TAG, 64, 0 ) ) ) ) ) ) ) + +/** + * Increment tagged macro + **/ +#define COUNTER_INC( TAG ) \ +constant_index< COUNTER_READ( TAG ) + 1 > \ +constexpr counter_crumb( TAG, \ + constant_index< ( COUNTER_READ( TAG ) + 1 ) & ~ COUNTER_READ( TAG ) >, \ + constant_index< ( COUNTER_READ( TAG ) + 1 ) & COUNTER_READ( TAG ) > ) \ +{ \ + return {}; \ +} + +template< std::size_t n > +struct constant_index : std::integral_constant< std::size_t, n > {}; + +// ============================================================================= +template< typename id, std::size_t rank, std::size_t acc > +constexpr constant_index< acc > counter_crumb( id, + constant_index< rank >, + constant_index< acc > ) +{ + return {}; +} /* found by ADL via constant_index */ + +/** + * Define counter which will be used by counter_read and counter_inc macros + **/ +#define DEFINE_COUNTER( counter ) \ +struct counter {}; + +/** + * Makes counter_crumb fcn available at the namespace. + **/ +#define COUNTER_LINK_NAMESPACE using ::counter_crumb; +/// @} + +/** + * This macro is used to declare a TAccept bit with name and decription. + * The fourth parameter is a static counter defined using above macros. + * Make sure to make the namespace linked with the counter fcn by using + * COUNTER_LINK_NAMESPACE inside the namespace. + **/ +#define DECLARE_BIT( bitmask, name, description, bit_counter) \ + const int Ringer::bitmask::name = \ + Ringer::bitmask::declareBit( \ + #name, \ + description \ + ); \ + \ + RINGER_STATIC_ASSERT( ( COUNTER_READ( bit_counter ) <= 32), \ + "Bit " STRINGIFY(name) " couldn't be added to bitmask " \ + STRINGIFY(bitmask) ": " STRINGIFY(bitmask) \ + " ran out of bits!!"); \ + \ + COUNTER_INC( bit_counter ) + +#endif // RINGERSELECTORTOOLS_TOOLS_DECLARE_BIT_H + +#endif // RINGER_STANDALONE diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/Exceptions.h b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/Exceptions.h new file mode 100644 index 0000000000000000000000000000000000000000..e1398773e00b8d121fab4796288350dbd5a3b851 --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/Exceptions.h @@ -0,0 +1,87 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: Exceptions.h 667905 2015-05-18 19:07:55Z wsfreund $ +#ifndef RINGERSELECTORTOOLS_TOOLS_EXCEPTIONS_H +#define RINGERSELECTORTOOLS_TOOLS_EXCEPTIONS_H + +// STL includes: +#include <stdexcept> +#include <string> + +#ifndef INCLUDE_HEADER_ONLY +#define INCLUDE_HEADER_ONLY // Avoid circular includes +#endif + +// Local includes: +#include "RingerSelectorTools/RingerSelectorToolsDefs.h" +#include "RingerSelectorTools/procedures/Types.h" +#undef INCLUDE_HEADER_ONLY + +namespace Ringer { + +namespace Exceptions { + +/** + * Exception telling user to implement type on this file + **/ +class no_such_type : public std::runtime_error { + public: + + no_such_type(const char* scope, std::string type = "", + std::string file = ""): + std::runtime_error(std::string("Could not recognize ") + + scope + " :" + type + ". If it should be " + "available, add it to file " + file){;} + + no_such_type(preProcEnum_t p, + std::string file = ""): + std::runtime_error(std::string("Could not recognize " + "PreProcessorTypes(") + std::to_string(int(p)) + + "). Make sure to add it to file " + file + + " and also add it to getType and toStr functions."){;} + + no_such_type(discrEnum_t d, + std::string file = ""): + std::runtime_error(std::string("Could not recognize " + "DiscriminatorTypes(") + std::to_string(int(d)) + + "). Make sure to add it to file " + file + " and also " + "add it to getType and toStr functions."){;} + + no_such_type(thresEnum_t t, + std::string file = ""): + std::runtime_error(std::string("Could not recognize " + "ThresholdTypes(") + std::to_string(int(t)) + + "). Make sure to add it to file " + file + + " and also add it to getType and toStr functions."){;} + + no_such_type(SegmentationType e, std::string file = ""): + std::runtime_error(std::string("Could not recognize " + "EtaDependency(") + std::to_string(int(e)) + + "). Make sure to add it to file " + file + + " and also add it to getType and toStr functions."){;} + + no_such_type(EtaDependency e, std::string file = ""): + std::runtime_error(std::string("Could not recognize " + "EtaDependency(") + std::to_string(int(e)) + + "). Make sure to add it to file " + file + + " and also add it to getType and toStr functions."){;} + + no_such_type(EtDependency e, std::string file = ""): + std::runtime_error(std::string("Could not recognize " + "EtDependency(") + std::to_string(int(e)) + + "). Make sure to add it to file " + file + + " and also add it to getType and toStr functions."){;} + + no_such_type(Requirement e, std::string file = ""): + std::runtime_error(std::string("Could not recognize " + "Requirement(") + std::to_string(int(e)) + + "). Make sure to add it to file " + file + + " and also add it to getType and toStr functions."){;} +}; + +} // namespace Exceptions +} // namespace Ringer + +#endif // RINGERSELECTORTOOLS_TOOLS_EXCEPTIONS_H diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/IOHelperFcns.h b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/IOHelperFcns.h new file mode 100644 index 0000000000000000000000000000000000000000..fe9617d0a5c38c3ac3e88c17bbebd42f57cd955d --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/IOHelperFcns.h @@ -0,0 +1,171 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: IOHelperFcns.h 679254 2015-06-30 12:54:50Z wsfreund $ +#ifndef RINGERSELECTORTOOLS_TOOLS_IOHELPERFCNS_H +#define RINGERSELECTORTOOLS_TOOLS_IOHELPERFCNS_H + +// STL includes: +#include <stdexcept> +#include <string> +#include <memory> + +// ROOT includes: +#include <TFile.h> +#include <TList.h> +#include <THashList.h> + +#ifndef INCLUDE_HEADER_ONLY // Avoid circular includes +#define INCLUDE_HEADER_ONLY +#endif +#include "RingerSelectorTools/RingerSelectorToolsDefs.h" +#undef INCLUDE_HEADER_ONLY + +namespace Ringer { + +namespace IOHelperFcns { + +/** + * @brief Set varDest to varName key pointer inside TDirectory dir + **/ +template <typename ReadingType, typename WrittenType = ReadingType > +void readVar(TDirectory* dir, const char* varName, ReadingType& varDest); + +/** + * @brief Write var with name varName at directory dir, raises otherwise. + * + * It cannot write non-scalar C objects, such as float[] and so on. Use + * std::vector<> otherwise. It also needs the root dictionary available + * for the type being writen. Some std::vector types available are: + * + * std::vector<float> + * std::vector<double> + * std::vector<unsigned int> + * + * But their long counterparts seem not possible to be written. + * + * For enumeration types, convert them into integers and when reading, convert + * them back, i.e.: + * + * --- Writing --- + * EtaDependency etaDependency = EtaIndependent; + * writeVar< EtaDependecy, unsigned int>(dir, "etaDep", etaDependency); + * + * --- Reading --- + * EtaDependency etaDependency; + * readVar< EtaDependency, unsigned int>(dir, "etaDep", etaDependency); + **/ +template <typename InputType, typename WrittenType = InputType > +void writeVar(TDirectory* dir, const char* varName, InputType& var); + +/** + * @brief Make index string from index + * + * If vector contains indexes [1], for instance, then returning string will + * be "@(1)". + * + **/ +std::string makeIdxStr(unsigned int idxV); + +/** + * @brief Make index string from index vector + * + * If vector contains indexes [1,2], for instance, then returning string will + * be "@(1,2)". + * + **/ +std::string makeIdxStr(std::vector<unsigned int> &idxV); + +/** + * @brief Fill vector with indexes contained in string made with makeIdxStr. + * + * Throws runtime_error if string does not contains string formated as created + * by makeIdxStr or if it cannot retrieve n-th index. + **/ +void getIdxVecFromStr(const char* cstr, std::vector<unsigned int> &n); + +/** + * @brief Get n-th index from string containing makeIdxStr. + * + * Throws runtime_error if string does not contains string formated as created + * by makeIdxStr or if it cannot retrieve n-th index. + **/ +unsigned int getIdxFromStr(const char* cstr, unsigned int n); + +/** + * @brief Returns package version as unsigned + * + * Remove package name and '-' from string, keep only package version + * as RingerSelectorTools-10-11-12 would lead into version 101112. + * + * NOTE: This means that a package cannot have any version number higher + * than 99. + **/ +unsigned version(); + +/** + * @brief Check if cStr starts with string cStrStart. + **/ +bool startsWith(const char *cStrStart, const char *cStr); + +/** + * @brief Check if TFile is correctly opened. + **/ +void checkFile(const TFile& file); + +/** + * @brief Check if TFile is exists. + **/ +bool fileExist(const char* fileName); + +/** + * @brief Delete file + **/ +int deleteFile(const char* fileName); + +/** + * @brief Check if directory is not pointing into void. + * + * Throws runtime_error otherwise error occurred + **/ +void checkDir(TDirectory* baseDir); + +/** + * @brief Write package version to directory + **/ +void writeVersion(TDirectory* dir); + +/** + * @brief Creates directory in baseDir with given name. + * + * Throws runtime_error if error occurred. It also adds to created directory + * the package version in which it was created. This can be written using the + * getWrittenVersion function. + **/ +TDirectory *makeDir(TDirectory* baseDir, const char *name); + +/** + * @brief Retrieve TList with directories on directory dir. + **/ +std::shared_ptr<THashList> getDirList(TDirectory* dir); + +/** + * @brief Gets package written version + * + * It returns the package version in which this directory was written, + * otherwise it throws runtime_error. + * + **/ +unsigned getWrittenVersion(TDirectory *configDir); + +} // namespace IOHelperFcns + +} // namespace Ringer + +#endif // RINGERSELECTORTOOLS_TOOLS_IOHELPERFCNS_H + +#ifndef INCLUDE_HEADER_ONLY // Use to avoid circular includes +#include "IOHelperFcns.icc" +#endif // INCLUDE_HEADER_ONLY + diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/IOHelperFcns.icc b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/IOHelperFcns.icc new file mode 100644 index 0000000000000000000000000000000000000000..2690e4360077548ae2f3246a88e33d289fd216ce --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/IOHelperFcns.icc @@ -0,0 +1,109 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: IOHelperFcns.icc 694257 2015-09-10 22:45:27Z wsfreund $ +#ifndef RINGERSELECTORTOOLS_TOOLS_IOHELPERFCNS_ICC +#define RINGERSELECTORTOOLS_TOOLS_IOHELPERFCNS_ICC + +// STL includes: +#include <vector> +#include <stdexcept> +#include <string> +#include <iostream> + +// ROOT includes: +#include <TFile.h> +#include <TError.h> + +// Local includes: +#include "IOHelperFcns.h" +#include "RingerSelectorTools/tools/cxx/remove_cv.h" +#include "RingerSelectorTools/tools/cxx/decay.h" + +namespace Ringer { + +namespace IOHelperFcns { + +// ============================================================================= +template <typename ReadingType, typename WrittenType > +void readVar(TDirectory* dir, const char* varName, ReadingType& varDest) +{ + + checkDir(dir); + + if ( dir->FindObjectAny( varName ) != nullptr ) { + WrittenType* reader = nullptr; + dir->GetObject( varName, reader ); + if ( reader != nullptr ){ + // Make raw copy to varDest + varDest = static_cast<ReadingType>(*reader); + } else { + throw std::runtime_error(std::string("Retrieved null pointer while ") + + "trying to read " + varName + " at directory named " + + dir->GetName() + "."); + } + } else if ( dir->FindObjectAny( (std::string(varName) + "__Vec__").c_str() ) + != nullptr ) + { + // Remove constant and reference types + std::vector< typename Ringer::decay< + typename Ringer::remove_cv<WrittenType>::type >::type + >* reader = nullptr; + dir->GetObject( (std::string(varName) + "__Vec__" ).c_str(), reader ); + if ( reader != nullptr ){ + if ( reader->size() != 1 ){ + throw std::runtime_error(std::string("Seems that the variable was saved using " + "the std::vector type. However, its size is different from 1, " + "which indicates that something went wrong.")); + } + // Make raw copy to varDest + varDest = static_cast<ReadingType>((*reader)[0]); + } else { + throw std::runtime_error(std::string("Retrieved null pointer while ") + + "trying to read " + varName + "__Vec__ at directory named " + + dir->GetName() + "."); + } + } else { + throw std::runtime_error( std::string("Cannot find ") + + varName + " at directory named " + + dir->GetName() + "." ); + } +} + +// ============================================================================= +template <typename InputType, typename WrittenType > +void writeVar(TDirectory* dir, const char* varName, InputType& var) +{ + // This workaround is just because gcc seems not to be able of creating + // std::vector<const type>, so we remove const and reference types. + typedef typename Ringer::decay< + typename Ringer::remove_cv<WrittenType>::type + >::type NonConstWrittenType; + // Create the non constant variable to write: + NonConstWrittenType &writtenVar = const_cast<NonConstWrittenType&>( + static_cast<WrittenType&>(var)); + // Check if directory is in good status + checkDir(dir); + Int_t prevMessageLevel = gErrorIgnoreLevel; + gErrorIgnoreLevel = kBreak; + // Try to write variable directly: + if ( !dir->WriteObject( &writtenVar, varName ) ){ + gErrorIgnoreLevel = prevMessageLevel; + // It didn't work, so attempt to write it using std::vector + std::vector< NonConstWrittenType > vec(1, writtenVar); + if ( !dir->WriteObject( &vec, (std::string(varName) + "__Vec__").c_str() ) ) + { + dir->ls(); + throw std::runtime_error(std::string("Couldn't write variable ") + + varName ); + } + } + gErrorIgnoreLevel = prevMessageLevel; +} + +} // namespace IOHelperFcns + +} // namespace Ringer + +#endif // RINGERSELECTORTOOLS_TOOLS_IOHELPERFCNS_ICC diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/IRedirectMsgStream.h b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/IRedirectMsgStream.h new file mode 100644 index 0000000000000000000000000000000000000000..65a1ec01ca5cf934daff1b96c310a92f26dbe4f9 --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/IRedirectMsgStream.h @@ -0,0 +1,163 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: IRedirectMsgStream.h 693573 2015-09-07 19:15:49Z wsfreund $ +#ifndef RINGERSELECTORTOOLS_TOOLS_IREDIRECTMSGSTREAM_H +#define RINGERSELECTORTOOLS_TOOLS_IREDIRECTMSGSTREAM_H + +// We make these declarations here because we can't forward declare enums +// without C++11 enum class. +#if !defined(RINGER_STANDALONE) +// Asg includes: +# include "AsgTools/MsgStream.h" +# include "AsgTools/MsgStreamMacros.h" +# include "xAODCaloRings/tools/PrintHelperFcns.h" +//#pragma message "ASGTOOL or ASGTOOL_STANDALONE" +#else +# include <iostream> +typedef std::ostream MsgStream; +namespace MSG { + + // Keep it simple + // FIXME This needs to be tested + enum Level { + NIL = 0, + VERBOSE, + DEBUG, + INFO, + WARNING, + ERROR, + FATAL, + ALWAYS, + NUM_LEVELS + } + + /** + * This is just a workaround for simulating the MsgStream when on standalone + * environment. + **/ + static Level currentLevel = INFO; + + /** + * Display message level: + **/ + std::ostream& operator<<(std::ostream &stream, const Level lvl){ + switch (lvl){ + case VERBOSE: + return stream << "VERBOSE: "; + break; + case DEBUG: + return stream << "DEBUG: "; + break; + case INFO: + return stream << "INFO: "; + break; + case WARNING: + return stream << "WARNING: "; + break; + case ERROR: + return stream << "ERROR: "; + break; + case FATAL: + return stream << "FATAL: "; + break; + otherwise: + return stream; + } + } +} + +# define ATH_MSG_LVL( lvl, xmsg) \ + do { \ + if ( msgLvl(lvl) ) { \ + msg(lvl) << xmsg << std::endl; \ + } \ + } while( 0 ) + +# define ATH_MSG_VERBOSE(xmsg) \ + ATH_MSG_LVL( MSG::VERBOSE, xmsg ) + +# define ATH_MSG_DEBUG(xmsg) \ + ATH_MSG_LVL( MSG::DEBUG, xmsg ) + +# define ATH_MSG_INFO(xmsg) \ + ATH_MSG_LVL( MSG::INFO, xmsg ) + +# define ATH_MSG_WARNING(xmsg) \ + ATH_MSG_LVL( MSG::WARNING, xmsg ) + +# define ATH_MSG_ERROR(xmsg) \ + ATH_MSG_LVL( MSG::ERROR, xmsg ) + +# define ATH_MSG_FATAL(xmsg) \ + ATH_MSG_LVL( MSG::FATAL, xmsg ) + +#define ATH_MSG_LVL_DISP_VAR( lvl, var) \ + do { \ + if ( msgLvl(lvl) ) { \ + msg << #var << ":" << var << endl; \ + } \ + } while (0) + +// ============================================================================= +/// Helper operator for printing the contents of vectors (ostream) +template <typename T> +std::ostream& operator<< ( std::ostream& out, const std::vector< T >& vec ) +{ + // A little prefix: + out << "["; + // Print the contents: + for( size_t i = 0; i < vec.size(); ++i ) { + out << vec[ i ]; + if( i < vec.size() - 1 ) { + out << ", "; + } + } + // A little postfix: + out << "]"; + // Return the stream: + return out; +} + +// ============================================================================= +/// Helper operator for printing the contents of vector pointers (ostream) +template <typename T> +std::ostream& operator<< ( std::ostream& out, const std::vector< T >* vec) +{ + return out.operator<<(*vec); +} +#endif // Environment selection + +namespace Ringer { +/** + * @class IRedirectMsgStream + * @brief Interface for RedirectMsgStream + **/ +class IRedirectMsgStream { + public: + /// Methods: + /// @{ + /// Check whether stream is available + virtual bool isStreamAvailable() const = 0; + + /// Returns MsgSteam with its current level + virtual MsgStream& msg() const = 0; + + /// Returns MsgSteam with its current level + /// It is const member function because m_msg member will be mutable + virtual void setMsgStream(MsgStream *msg) const = 0; + + /// Set msg level + virtual bool msgLvl(MSG::Level level) const = 0; + /// Returns m_msg, otherwise returns + virtual MsgStream& msg(MSG::Level level) const = 0; + + virtual ~IRedirectMsgStream(){;} + /// @} +}; + +} // namespace Ringer + + +#endif // RINGERSELECTORTOOLS_TOOLS_IREDIRECTMSGSTREAM_H diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/RedirectMsgStream.h b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/RedirectMsgStream.h new file mode 100644 index 0000000000000000000000000000000000000000..5b3fe5617627a00a95ce1ae86e230cd8628ce335 --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/RedirectMsgStream.h @@ -0,0 +1,148 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: RedirectMsgStream.h 704615 2015-10-29 18:50:12Z wsfreund $ +#ifndef RINGERSELECTORTOOLS_TOOLS_REDIRECTMSGSTREAM_H +#define RINGERSELECTORTOOLS_TOOLS_REDIRECTMSGSTREAM_H + +#include <string> +#include <stdexcept> + +// Local includes: +#include "RingerSelectorTools/tools/IRedirectMsgStream.h" +#include "RingerSelectorTools/tools/cxx/mutable.h" +#include "RingerSelectorTools/tools/cxx/RingerUseNewCppFeatures.h" + +namespace Ringer { +/** + * @class RedirectMsgStream + * @brief Redirect Msg Stream to calling AsgSelector + * + * We do this so that we can display messages as if we were AsgSelector + * with our algorithms. + * + * If we are not running using a AsgSelector, use ostream otherwise. + **/ +class RedirectMsgStream : virtual public IRedirectMsgStream { + public: + /// Methods: + /// @{ + /// Check whether stream is available + bool isStreamAvailable() const { + return m_msg != nullptr; + } + + /// Returns MsgSteam with its current level + void setMsgStream(MsgStream *msg) const { +#if RINGER_USE_NEW_CPP_FEATURES + m_msg = msg; +#else + const_cast<RedirectMsgStream*>(this)->m_msg = msg; +#endif + } + /// Check if message level is enabled + bool msgLvl(MSG::Level level) const { +#if !defined(RINGER_STANDALONE) + if ( isStreamAvailable() ) { + return m_msg->level() <= level; + } + return false; +#else + return MSG::currentLevel <= level; +#endif + } + + /// Get msg level + MSG::Level level() const { +#if !defined(RINGER_STANDALONE) + if ( isStreamAvailable() ) + return m_msg->level(); + else + throw std::runtime_error(std::string("Stream not available")); +#else + return MSG::currentLevel; +#endif + } + + protected: + /// Ctors: + /// @{ + /** + * @brief Redirects output as if it run by Asg selector. + * + * When no MsgStream available, build one if on Asg environment, + * otherwise use std::cout. + **/ + RedirectMsgStream(MsgStream *msg): + m_msg(msg){;} + /** + * @brief Redirects output as if it run by Asg selector. + * + * When no MsgStream available, build one if on Asg environment, + * otherwise use std::cout. + **/ + RedirectMsgStream(): + m_msg(nullptr){;} + /// @} + ~RedirectMsgStream(){;} + + /// Properties: + /// @{ + /// The re-directed message stream from AsgSelector + ATH_RINGER_MUTABLE MsgStream *m_msg; + /// @} + +#if !defined(RINGER_STANDALONE) + /// Returns MsgSteam with its current level + MsgStream& msg() const { + if ( isStreamAvailable() ) { + return (*m_msg); + } else { + throw std::runtime_error(std::string( + "Cannot display message, MsgStream not set." + " Make sure to use setMsgStream(MsgStream*) method.")); + } + } + + /// Returns MsgStream and set its level + MsgStream& msg(MSG::Level level) const { + if ( isStreamAvailable() ) { +#if !defined(XAOD_ANALYSIS) && !defined(XAOD_STANDALONE) + return m_msg->report(level); +#else + return (*m_msg) << level; +#endif + } else { + throw std::runtime_error(std::string( + "Cannot display message, MsgStream not set." + " Make sure to use setMsgStream(MsgStream*) method.")); + } + } + +#else + /// Returns MsgSteam with its current level + MsgStream& msg() const { + if ( isStreamAvailable() ) { + return (*m_msg); + } else { + return std::cout; + } + } + + /// Returns m_msg, otherwise returns + MsgStream& msg(MSG::Level level) const { + if ( isStreamAvailable() ) { + return (*m_msg) << level; + } else { + return std::cout << level; + } + } +#endif + /// @} + +}; + +} // namespace Ringer + +#endif diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/RingerCommonSelector.h b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/RingerCommonSelector.h new file mode 100644 index 0000000000000000000000000000000000000000..f7e22c464aa7b48de04efb5e6872e57e70dc178b --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/RingerCommonSelector.h @@ -0,0 +1,118 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: RingerCommonSelector.h 668868 2015-05-20 20:26:18Z wsfreund $ +#ifndef RINGERSELECTORTOOLS_TOOLS_RINGERCOMMONSELECTOR_H +#define RINGERSELECTORTOOLS_TOOLS_RINGERCOMMONSELECTOR_H + +// Local includes: +#include "RingerSelectorTools/procedures/RingerProcedureWrapper.icc" +#include "RingerSelectorTools/tools/VariableDependency.h" + +// STL includes: +#include <vector> + +// xAOD includes: +#include "xAODCaloRings/CaloRingsFwd.h" +#include "xAODTracking/TrackParticleFwd.h" + +// ROOT includes: +#include "PATCore/TAccept.h" + +namespace Ringer { + +/** + * + * @class RingerCommonSelecto + * + **/ +class RingerCommonSelector : public RedirectMsgStream +{ + + public: + /** + * @brief Main ctor + **/ + RingerCommonSelector( + const Ringer::IDiscrWrapperCollection *discrWrapperCol, + const Ringer::IThresWrapper *thresWrapper, + Root::TAccept *partDecMsk, + const bool useTrackPat, + const bool useRawTrackPat, + const bool useCaloCommittee); + + /** + * @brief Clear output space representation + **/ + void clear(); + + /** + * @brief Execute Ringer common selector + **/ + StatusCode execute( + const DepVarStruct &depVar, + const xAOD::CaloRings* clRings, + const TrackPatternsHolder *trackPat); + + /** + * @brief Get output space + **/ + const std::vector<float> &getOutputSpace() const; + + private: + + /// Properties to be given by AsgSelector: + /// @{ + const Ringer::IDiscrWrapperCollection *m_discrWrapperCol; + const Ringer::IThresWrapper *m_thresWrapper; + Root::TAccept *m_partDecMsk; + const bool m_useTrackPat; + const bool m_useRawTrackPat; + const bool m_useCaloCommittee; + /// @} + + /// Local properties: + /// @{ + /// Pointer to firlastst discrimination layer + const IDiscrWrapper *m_fstDiscrLayer; + /// Pointer to last discrimination layer + const IDiscrWrapper *m_lastDiscrLayer; + /// The discrimination wrapper collection size + size_t m_discrWrapperColSize; + /// Hold discriminators input + std::vector<float> m_input; + /// Hold discriminators output + std::vector<float> m_output; + /// Hold decision + std::vector<bool> m_decVec; + /** + * @brief Hold track discriminator output + * + * This vector will be used only in the following special occasion: + * - It is wanted to feed the last classifier with the output from the track + * classifier. In this case, we need + **/ + std::vector<float> m_trackDiscr_output; + /// Flag if discrimination approach is non segmented + bool m_nonSegmentedDiscr; + /// @} + +}; + +//============================================================================== +inline +void RingerCommonSelector::clear(){ + m_output.clear(); +} + +//============================================================================== +inline +const std::vector<float>& RingerCommonSelector::getOutputSpace() const { + return m_output; +} + +} // namespace Ringer + + +#endif // RINGERSELECTORTOOLS_TOOLS_RINGERCOMMONSELECTOR_H diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/RingerIOVarDepObj.h b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/RingerIOVarDepObj.h new file mode 100644 index 0000000000000000000000000000000000000000..f81032c4eaa1518ee9dd5a3d06d23ad33af44715 --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/RingerIOVarDepObj.h @@ -0,0 +1,236 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: RingerIOVarDepObj.h 704615 2015-10-29 18:50:12Z wsfreund $ +#ifndef RINGERSELECTORTOOLS_TOOLS_RINGERIOVARDEPOBJ_H +#define RINGERSELECTORTOOLS_TOOLS_RINGERIOVARDEPOBJ_H + +// STL includes: +#include <string> + +// Root includes: +#include <TFile.h> + +// Local includes: +#include "RingerSelectorTools/RingerSelectorToolsDefs.h" +#include "RingerSelectorTools/procedures/IRingerProcedure.h" +#include "RingerSelectorTools/tools/VariableDependency.h" +#include "RingerSelectorTools/tools/cxx/StaticAssert.h" +#include "RingerSelectorTools/tools/cxx/constexpr.h" +#include "RingerSelectorTools/tools/cxx/is_base_of.h" +#include "RingerSelectorTools/tools/cxx/override.h" +#include "RingerSelectorTools/tools/cxx/mutable.h" +#include "RingerSelectorTools/tools/cxx/final.h" + +/** + * @brief Create RingerIOVarDepObj base object prototype methods + * + * Every time you create a class that use this mechanism, make sure to add it + * to "RingerSelectorTools/procedures/Types.h" + * + * + * When you create a class that implements a RingerProcedure and it will be a + * writable object, then this object must have defined this macro and + * implement the read and write methods as: + * + * file NewProcedure.h: + * /code + * class NewProcedure: virtual public IDiscriminator + * // or virtual public IPreProcessor + * // or virtual public IThreshold + * { + * // Given as example + * float m_var; + * + * RINGER_IO_VARDEP_BASE( NewProcedure ) + * // ... + * } + * + * RINGER_DEFINE_PROCTYPE_MEMBER_FCN( NewProcedure ) + * + * } // namespace Ringer + * /endcode + * + * file NewProcedure.cxx + * /code + * namespace Ringer { + * + * void NewProcedure::read(NewProcedure* newObj, + * TDirectory *configDir, + * unsigned version ) + * { + * IOHelperFcns::readVar( configDir, "var", newObj->m_var ); + * } + * + * void NewProcedure::write(TDirectory *configDir) const + * { + * IOHelperFcns::writeVar(configDir, "var", m_var ); + * } + * + * void NewProcedure::print(MSG::Level lvl) const + * { + * if ( !this->isStreamAvailable() ) { + * std::cerr << "Cannot print NewProcedure, stream unavailable" + * << std::endl; + * } + * if ( this->level() > lvl ) { + * return; + * } + * msg() << lvl << this->name() << " configuration:" << endreq; + * msg() << lvl << "var:" << m_var << endreq; + * } + * + * } // namespace Ringer + * /endcode + * + * If the procedure has no variable, it can use the + * RINGER_IO_VARDEP_BASE_NOMEMBER macro instead. + * + * The previous structure will need also to implement the VariableDependency + * class, which will inherit from the RingerIOVarDepObj using the + * RINGER_IO_VARDEP_OBJ macro described next. + * + * /code + * class NewProcedureVarDep : virtual public IDiscriminatorVarDep, + * public RingerIOVarDepObj<NewProcedureVarDep>, + * public NewProcedure + * { + * RINGER_IO_VARDEP_OBJ(NewProcedureVarDep, NewProcedure) + * // ... + * } + * /endcode + **/ + +#define RINGER_IO_VARDEP_BASE(self) \ + public: \ + \ + RINGER_DEFINE_PROCEDURE(self) \ + \ + static void read(self *newObj, \ + TDirectory *configDir, \ + unsigned version ); \ + \ + virtual void write(TDirectory *configDir, const char* idxStr = "") \ + const ATH_RINGER_OVERRIDE; + +/** + * @brief Same as RINGER_IO_VARDEP_BASE, but when class has no member + **/ +#define RINGER_IO_VARDEP_BASE_NOMEMBER(self) \ + public: \ + \ + RINGER_DEFINE_NOMEMBER_PROCEDURE(self) \ + \ + static void read(self *, \ + TDirectory *, \ + unsigned ) {;} \ + \ + virtual void write(TDirectory *, const char*) const \ + ATH_RINGER_OVERRIDE {;} + +/** + * @brief Add necessary information to RingerIOVarDepObj + * + * When declaring the new procedure variable dependent object, you will need to + * add this macro adding to add its base type where you used the + * RINGER_IO_VARDEP_BASE macro. + * + * + **/ +#define RINGER_IO_VARDEP_OBJ(self, base) \ + \ + public: \ + typedef base base_t; \ + \ + using base::procType; \ + \ + virtual const char* name() const \ + ATH_RINGER_OVERRIDE ATH_RINGER_FINAL \ + { \ + return this->RingerIOVarDepObj<self>::name(); \ + } \ + \ + void print(MSG::Level lvl) const \ + ATH_RINGER_OVERRIDE ATH_RINGER_FINAL \ + { \ + this->base_t::print(lvl); \ + } \ + \ + virtual void write(TDirectory *baseDir, const char* idxStr = "") const \ + ATH_RINGER_OVERRIDE ATH_RINGER_FINAL \ + { \ + this->RingerIOVarDepObj<self>::write(baseDir, idxStr); \ + } \ + \ + static self* read(TDirectory *configDir){ \ + return RingerIOVarDepObj<self>::read(configDir); \ + } \ + \ + typedef typename Ringer::template RingerProcedureType<base>:: \ + baseInterface_t baseInterface_t; \ + \ + using baseInterface_t::procType; + +namespace Ringer { + +/** + * @class RingerIOVarDepObj + * @brief Objects that can be recorded/read into/from configuration files. + * + * Use CRTP mechanism so that we can force static read method to be + * implemented. + * + * The CRTP class will automatically inherit from BaseProcedure and + * VariableDependency, the late using etaDependency and etDependency given + * values. + * + * It also implements the final version of the IRingerProcedure write pure + * virtual method, which will call both VariableDependency and + * the BaseProcedure write methods. It also make sure that the configuration + * directory written to Root will be named as: + * + * "BaseProcedure::type()[VariableDependency::type()]" + * + **/ +template < class CRTP > +class RingerIOVarDepObj : virtual public VariableDependency +{ + + public: + /** + * Typedef to CRTP type: + **/ + //typedef CRTP crtp_t; + + // Make sure we initialize the variable dependency + RingerIOVarDepObj():VariableDependency(){;} + + /** + * Retrieve name for this RingerIOVarDepObj + **/ + const char* name() const; + + /** + * @brief Read Ringer procedure from configuration dir + **/ + static CRTP* read(TDirectory *configDir); + + /** + * @brief Write Ringer procedure to configuration directory + **/ + void write(TDirectory *baseDir, const char* idxStr="") + const; + + private: + ATH_RINGER_MUTABLE std::string m_name; + +}; + +} // namespace Ringer + +#endif // RINGERSELECTORTOOLS_TOOLS_RINGERIOVARDEPOBJ_H + +#ifndef INCLUDE_HEADER_ONLY // Use to avoid circular includes +#include "RingerIOVarDepObj.icc" +#endif // INCLUDE_HEADER_ONLY diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/RingerIOVarDepObj.icc b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/RingerIOVarDepObj.icc new file mode 100644 index 0000000000000000000000000000000000000000..df48ddd2448a69b7c810ffae32d8603930446a8c --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/RingerIOVarDepObj.icc @@ -0,0 +1,76 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: RingerIOVarDepObj.icc 667905 2015-05-18 19:07:55Z wsfreund $ +#ifndef RINGERSELECTORTOOLS_TOOLS_RINGERIOVARDEPOBJ_ICC +#define RINGERSELECTORTOOLS_TOOLS_RINGERIOVARDEPOBJ_ICC + +// STL includes: +#include <sstream> +#include <cctype> + +// Root includes: +#include <TFile.h> + +// Local includes: +#include "RingerSelectorTools/tools/RingerIOVarDepObj.h" +#include "RingerSelectorTools/tools/IOHelperFcns.icc" + +namespace Ringer { + +// ============================================================================= +template < class CRTP > +const char* RingerIOVarDepObj<CRTP>::name() const +{ + const_cast<std::string&>(m_name) = std::string(CRTP::base_t::procType()) + + this->VariableDependency::type(); + return m_name.c_str(); +} + +// ============================================================================= +template < class CRTP > +CRTP* RingerIOVarDepObj<CRTP>::read(TDirectory *configDir) +{ + CRTP* crtp = new CRTP; + try { + unsigned v = IOHelperFcns::getWrittenVersion(configDir); + CRTP::base_t::read(crtp, configDir, v ); + VariableDependency::read(crtp, configDir, v ); + return crtp; + } catch ( const std::runtime_error &e){ + std::cerr << "Couldn't read object of type " + << CRTP::base_t::procType() + << ". Reason: " << e.what() << std::endl; + delete crtp; + return nullptr; + } +} + +// ============================================================================= +template < class CRTP > +void RingerIOVarDepObj<CRTP>::write(TDirectory *baseDir, const char *idxStr) + const +{ + typedef typename CRTP::base_t base_t; + typedef typename RingerProcedureType<base_t>::procEnum_t + procEnum_t; + // Create directory where we will add all configurable information: + TDirectory* configDir = IOHelperFcns::makeDir( baseDir, + (std::string(this->name()) + std::string(idxStr) ).c_str() ); + // Write object version: + unsigned v = IOHelperFcns::version(); + IOHelperFcns::writeVar( configDir, "writtenOnPkgVersion", v ); + // Write object type: + procEnum_t procType = base_t::template procType<procEnum_t>(); + IOHelperFcns::writeVar< const procEnum_t, const unsigned int>( configDir, + "procType", + procType ); + // Now write BaseProcedure and VariableDependency information on it: + static_cast<const CRTP*>(this)->base_t::write(configDir, idxStr); + static_cast<const VariableDependency*>(this)->writeDepInfo(configDir); +} + +} // namespace Ringer + +#endif // RINGERSELECTORTOOLS_TOOLS_RINGERIOVARDEPOBJ_ICC diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/TrackPatternsHolder.h b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/TrackPatternsHolder.h new file mode 100644 index 0000000000000000000000000000000000000000..57b1d02b36901844d65c1d6f30211d9e9d14e2df --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/TrackPatternsHolder.h @@ -0,0 +1,220 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: TrackPatternsHolder.h 689837 2015-08-17 17:22:12Z wsfreund $ +#ifndef RINGERSELECTORTOOLS_TOOLS_TRACKPATTERNSHOLDER_H +#define RINGERSELECTORTOOLS_TOOLS_TRACKPATTERNSHOLDER_H + +#include "RingerSelectorTools/tools/cxx/RingerUseNewCppFeatures.h" + +// STL includes: +#include <vector> +#include <cstddef> +#if RINGER_USE_NEW_CPP_FEATURES +#include <array> +#endif + +// xAOD framework includes: +#include "xAODTracking/TrackParticleFwd.h" +#include "xAODEgamma/ElectronFwd.h" + +// Local includes: +#include "RingerSelectorTools/tools/VariableDependency.h" +#include "RingerSelectorTools/tools/RedirectMsgStream.h" + +namespace Ringer { + +/** + * @class TrackPatterns + * @brief Hold Ringer Track needed patterns. + * + * This class will extract the Ringer needed Track patterns from TrackParticle + * and Electron (if available). It is used afterwards to extract this patterns + * into the containers (std::vector<float>) used by the classifiers. + **/ +class TrackPatternsHolder : public RedirectMsgStream { + + public: + + /** + * @brief Standard ctor: + **/ + TrackPatternsHolder( + const bool useBLOutliers, + const bool usePIXOutliers, + const bool useSCTOutliers, + const bool useTRTOutliers, + const bool useTRTXenonHits): + m_useBLOutliers(useBLOutliers), + m_usePIXOutliers(usePIXOutliers), + m_useSCTOutliers(useSCTOutliers), + m_useTRTOutliers(useTRTOutliers), + m_useTRTXenonHits(useTRTXenonHits), + m_nBL(0), + m_nBLOutliers(0), + m_nPi(0), + m_nPiOutliers(0), + m_nSCT(0), + m_nSCTOutliers(0), + m_nTRThigh(0), + m_nTRThighOutliers(0), + m_nTRT(0), + m_nTRTOutliers(0), + m_nTRTXenonHits(0), + m_expectHitInBLayer(0), + m_trackd0(0), + m_deltaeta(0), + m_deltaphi(0), + m_ep(0), + m_energy(0), + m_eta(0){;} + + /** + * @brief Extrack Track Patterns from Particles + **/ + void extractPatternsFrom( + const xAOD::TrackParticle *track, + const xAOD::Electron *el ); + + /** + * @brief Export Track Patterns to @name vec end + * + * We apply transformations on the raw patterns extracted to obtain the + * true patterns applied. This method must be called after + * extrackPatternsFrom method is called. + **/ + void exportPatternsTo( std::vector<float> &vec ) const; + + /** + * @brief Export the number of patterns that will be exported to vector. + **/ + static size_t numberOfPatterns(); + + private: + + /// Private properties (configuration): + ///@{ + /// Flag whether to use B-layer outliers: + const bool m_useBLOutliers; + /// Flag whether to use Pixel outliers: + const bool m_usePIXOutliers; + /// Flag whether to use SCT outliers: + const bool m_useSCTOutliers; + /// Flag whether to use TRT outliers: + const bool m_useTRTOutliers; + /// Flag whether to use TRT Xenon hits: + const bool m_useTRTXenonHits; + ///@} + + /// Private Properties: + ///@{ + /// Number of B-Layer hits: + uint8_t m_nBL; + /// Number of B-Layer outliers: + uint8_t m_nBLOutliers; + /// Number of Pixel hits: + uint8_t m_nPi; + /// Number of Pixel outliers: + uint8_t m_nPiOutliers; + /// Number of SCT hits: + uint8_t m_nSCT; + /// Number of SCT outliers: + uint8_t m_nSCTOutliers; + /// Number of TRT high threshold hits: + uint8_t m_nTRThigh; + /// Number of TRT high threshold outliers: + uint8_t m_nTRThighOutliers; + /// Number of TRT hits: + uint8_t m_nTRT; + /// Number of TRT outliers: + uint8_t m_nTRTOutliers; + /// Number of TRT Xenon hits: + uint8_t m_nTRTXenonHits; + /// Whether to expect hit in BLayer: + uint8_t m_expectHitInBLayer; + /// Track transverse impact param: + float m_trackd0; + /// Track Calo deltaEta: + float m_deltaeta; + /// Track Calo deltaPhi: + float m_deltaphi; + /// Track Calo e/p: + double m_ep; + + /// Cluster energy: + double m_energy; + /// Cluster eta: + double m_eta; + ///@} + + /// Static properties: + ///@{ + /// Coefficients to aproximate Number of TRT hits: + ///@{ +#if RINGER_USE_NEW_CPP_FEATURES + static constexpr double m_a0 = 33.14; + static constexpr double m_b0 = -129.1; + static constexpr double m_c0 = 1455.; + static constexpr double m_a1 = 29.42; + static constexpr double m_b1 = 27.93; + static constexpr double m_c1 = -89.96; + static constexpr double m_d1 = 91.51; + static constexpr double m_a2 = 196.3; + static constexpr double m_b2 = -403.; + static constexpr double m_c2 = 230.2; + static constexpr double m_a3 = -10.59; + static constexpr double m_b3 = 37.29; + static constexpr double m_a4 = -640.9; + static constexpr double m_b4 = 1323.; + static constexpr double m_c4 = -851.8; + static constexpr double m_d4 = 180.8; + static constexpr double m_a5 = 159.8; + static constexpr double m_b5 = -70.9; + static constexpr std::array<float,6> m_cutBinEta_TRT{{ + 0.1, 0.625, 1.07, 1.304, 1.752, 2.0 + }}; +#else + static const double m_a0; + static const double m_b0; + static const double m_c0; + static const double m_a1; + static const double m_b1; + static const double m_c1; + static const double m_d1; + static const double m_a2; + static const double m_b2; + static const double m_c2; + static const double m_a3; + static const double m_b3; + static const double m_a4; + static const double m_b4; + static const double m_c4; + static const double m_d4; + static const double m_a5; + static const double m_b5; + static const std::vector<float> m_cutBinEta_TRT; +#endif + ///@} + ///@} + + /// Private Methods: + ///@{ + /** Reset all values */ + void resetValues(); + /** get Track TRT variables */ + void getTRTVar(double &rTRT, double &estHitsTRT) const; + ///@} + +}; + +//============================================================================== +inline +size_t TrackPatternsHolder::numberOfPatterns() +{ + return 10; +} + +} // namespace Ringer + +#endif // RINGERSELECTORTOOLS_TOOLS_TRACKPATTERNSHOLDER_H diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/VariableDependency.h b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/VariableDependency.h new file mode 100644 index 0000000000000000000000000000000000000000..cfbb6538d63b3f945ff2b9787819cd2472d49a2f --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/VariableDependency.h @@ -0,0 +1,256 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: VariableDependency.h 704615 2015-10-29 18:50:12Z wsfreund $ +#ifndef RINGERSELECTORTOOLS_TOOLS_VARIABLEDEPENDENCY_H +#define RINGERSELECTORTOOLS_TOOLS_VARIABLEDEPENDENCY_H + +// STL includes: +#include <stdexcept> +#include <cmath> +#include <sstream> +#include <iostream> + +// ROOT includes: +#include <TDirectory.h> + +// Local includes: +#include "RingerSelectorTools/RingerSelectorToolsDefs.h" +#include "RingerSelectorTools/tools/cxx/constexpr.h" +#include "RingerSelectorTools/tools/cxx/final.h" +#include "RingerSelectorTools/tools/cxx/override.h" +#include "RingerSelectorTools/tools/cxx/mutable.h" + + +/** + * @brief Namespace dedicated for Ringer utilities + **/ +namespace Ringer { + +/** + * @struct Eta, Et + * @brief Dependency variable structure. + * + * Holds all possible dependent variables values. + **/ +struct DepVarStruct { + const float eta; + const float et; + DepVarStruct(const float eta, const float et): + eta(eta), + et(et){;} +}; + +//class IVariableDependency +//{ +// public: +// /** +// * Check if depVar is within this procedure range +// **/ +// virtual bool isWithinRange(const DepVarStruct &depVar) const = 0; +// +// /** +// * Check if eta is within this procedure eta range +// **/ +// virtual bool isWithinEtaRange(const float eta) const = 0; +// +// /** +// * Set this procedure to be eta dependent: +// **/ +// virtual void setEtaDep(const float etaMin, const float etaMax) = 0; +// +// /** +// * Check if et is within this procedure et range +// **/ +// virtual bool isWithinEtRange(const float et) const = 0; +// +// /** +// * Set this procedure to be et dependent: +// **/ +// virtual void setEtDep(const float etMin, const float etMax) = 0; +// +// /** +// * Set this procedure to be et, eta dependent: +// **/ +// virtual void setEtaEtDep(const float etaMin, const float etaMax, +// const float etMin, const float etMax) = 0; +// +// virtual ~IVariableDependency(){;} +//}; + +/** + * @class VariableDependency + * @brief Interface for possible Eta and Et variable dependency. + **/ +class VariableDependency /*: virtual public IVariableDependency*/ +{ + public: + + /** + * Ctor for independent + **/ + VariableDependency() + : m_etaDependency(EtaDependency::EtaIndependent), + m_etDependency(EtDependency::EtIndependent), + m_etaMin(0), m_etaMax(0), + m_etMin(0), m_etMax(0), + m_type{""}{;} + + /** + * Ctor for eta dependent case + **/ + VariableDependency(const float etaMin, const float etaMax, + EtaDependency etaDependency) + : m_etaDependency(etaDependency), + m_etDependency(EtDependency::EtIndependent), + m_etaMin(etaMin), + m_etaMax(etaMax), + m_etMin(0), + m_etMax(0), + m_type{""}{;} + + /** + * Ctor for et dependent case + **/ + VariableDependency(const float etMin, const float etMax, + EtDependency etDependency) + : m_etaDependency(EtaDependency::EtaIndependent), + m_etDependency(etDependency), + m_etMin(etMin), + m_etMax(etMax), + m_type{""}{;} + + /** + * Ctor for et/eta dependent case + **/ + VariableDependency(const float etaMin, const float etaMax, + const float etMin, const float etMax) + : m_etaDependency(EtaDependency::EtaDependent), + m_etDependency(EtDependency::EtDependent), + m_etaMin(etaMin), + m_etaMax(etaMax), + m_etMin(etMin), + m_etMax(etMax), + m_type{""}{;} + + /** + * Check if depVar is within this procedure range + **/ + bool isWithinRange(const DepVarStruct &depVar) const /*ATH_RINGER_OVERRIDE + ATH_RINGER_FINAL*/; + + /** + * Check if eta is within this procedure range + **/ + bool isWithinEtaRange(const float eta) const /*ATH_RINGER_OVERRIDE + ATH_RINGER_FINAL*/; + + /** + * Returns whether it is et dependent + **/ + EtaDependency etaDep() const /*ATH_RINGER_OVERRIDE ATH_RINGER_FINAL*/; + + /** + * Get eta min + **/ + float etaMin() const /*ATH_RINGER_OVERRIDE ATH_RINGER_FINAL*/; + + /** + * Get eta max + **/ + float etaMax() const /*ATH_RINGER_OVERRIDE ATH_RINGER_FINAL*/; + + /** + * Get et min + **/ + float etMin() const /*ATH_RINGER_OVERRIDE ATH_RINGER_FINAL*/; + + /** + * Get et max + **/ + float etMax() const /*ATH_RINGER_OVERRIDE ATH_RINGER_FINAL*/; + + /** + * Set this procedure to be eta dependent: + **/ + void setEtaDep(const float etaMin, const float etaMax) /*ATH_RINGER_OVERRIDE + ATH_RINGER_FINAL*/; + + /** + * Check if et is within this procedure et range + **/ + bool isWithinEtRange(const float et) const /*ATH_RINGER_OVERRIDE + ATH_RINGER_FINAL*/; + + /** + * Returns whether it is et dependent + **/ + EtDependency etDep() const /*ATH_RINGER_OVERRIDE ATH_RINGER_FINAL*/; + + /** + * Set this procedure to be et dependent + **/ + void setEtDep(const float etMin, const float etMax) /*ATH_RINGER_OVERRIDE + ATH_RINGER_FINAL*/; + + /** + * Set this procedure to be et dependent + **/ + void setEtaEtDep(const float etaMin, const float etaMax, + const float etMin, const float etMax) /*ATH_RINGER_OVERRIDE + ATH_RINGER_FINAL*/; + + /** + * Return this variable dependency string + * + * This is not a virtual method. + **/ + const char* type() const; + + /** + * Read variable dependency from directory + **/ + static void read(VariableDependency *varDep, + TDirectory *configDir, + unsigned writtenVersion); + + /** + * Write variable dependency to directory + * + * This is not a virtual method. + **/ + void writeDepInfo(TDirectory *configDir) const; + + /** + * Ensure virtual destruction (needed if creating dictionary from this + * class) + **/ + virtual ~VariableDependency(){;} + + private: + + /// Whether there is eta dependency + EtaDependency m_etaDependency; + /// Whether there is et dependency + EtDependency m_etDependency; + + /// Eta bounded region where RingerProcedure may be applied + float m_etaMin, m_etaMax; + + /// Et bounded region where RingerProcedure may be applied + float m_etMin, m_etMax; + + /// The string holder for type: + ATH_RINGER_MUTABLE std::string m_type; + +}; + +} // namespace Ringer + +#endif // RINGERSELECTORTOOLS_TOOLS_VARIABLEDEPENDENCY_H + +#ifndef INCLUDE_HEADER_ONLY // Use to avoid circular includes +#include "VariableDependency.icc" +#endif // INCLUDE_HEADER_ONLY + diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/VariableDependency.icc b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/VariableDependency.icc new file mode 100644 index 0000000000000000000000000000000000000000..17997c3bdc9ad10bf9d863dcb3af6deef98d8186 --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/VariableDependency.icc @@ -0,0 +1,113 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: VariableDependency.icc 689837 2015-08-17 17:22:12Z wsfreund $ +#ifndef RINGERSELECTORTOOLS_TOOLS_VARIABLEDEPENDENCY_ICC +#define RINGERSELECTORTOOLS_TOOLS_VARIABLEDEPENDENCY_ICC + +// Local includes: +#include "RingerSelectorTools/tools/VariableDependency.h" + +namespace Ringer { + +// ============================================================================= +inline +bool VariableDependency::isWithinRange(const DepVarStruct &depVar) const +{ + return isWithinEtaRange(depVar.eta) && isWithinEtRange(depVar.et); +} + +// ============================================================================= +inline +bool VariableDependency::isWithinEtaRange(const float eta) const +{ + if ( static_cast<bool>(m_etaDependency) ){ + const float eta_abs = std::abs(eta); + return ( (eta_abs >= m_etaMin) && (eta_abs < m_etaMax) ); + } else { + return true; + } +} + +// ============================================================================= +inline +EtaDependency VariableDependency::etaDep() const { + return m_etaDependency; +} + +// ============================================================================= +inline +float VariableDependency::etaMin() const +{ + return m_etaMin; +} + +// ============================================================================= +inline +float VariableDependency::etaMax() const +{ + return m_etaMax; +} + +// ============================================================================= +inline +void VariableDependency::setEtaDep(const float etaMin, const float etaMax) +{ + m_etaDependency = EtaDependency::EtaDependent; + m_etaMin = etaMin; + m_etaMax = etaMax; +} + +// ============================================================================= +inline +bool VariableDependency::isWithinEtRange(const float et) const +{ + if ( static_cast<bool>(m_etDependency) ) { + return ( (et >= m_etMin) && (et < m_etMax) ); + } else { + return true; + } +} + +// ============================================================================= +inline +EtDependency VariableDependency::etDep() const { + return m_etDependency; +} + +// ============================================================================= +inline +float VariableDependency::etMin() const +{ + return m_etMin; +} + +// ============================================================================= +inline +float VariableDependency::etMax() const +{ + return m_etMax; +} + +// ============================================================================= +inline +void VariableDependency::setEtDep(const float etMin, const float etMax) +{ + m_etDependency = EtDependency::EtDependent; + m_etMin = etMin; + m_etMax = etMax; +} + +// ============================================================================= +inline +void VariableDependency::setEtaEtDep(const float etaMin, const float etaMax, + const float etMin, const float etMax) +{ + setEtaDep(etaMin,etaMax); + setEtDep(etMin,etMax); +} + +} // namespace Ringer + +#endif // RINGERSELECTORTOOLS_TOOLS_VARIABLEDEPENDENCY_ICC diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/RingerUseNewCppFeatures.h b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/RingerUseNewCppFeatures.h new file mode 100644 index 0000000000000000000000000000000000000000..81dba98859292e6fc9dd5c0648363bd61e5ab8fe --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/RingerUseNewCppFeatures.h @@ -0,0 +1,19 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: RingerUseNewCppFeatures.h 693573 2015-09-07 19:15:49Z wsfreund $ +#ifndef RINGERSELECTORTOOLS_TOOLS_CXX_RINGERUSENEWCPPFEATURES_H +#define RINGERSELECTORTOOLS_TOOLS_CXX_RINGERUSENEWCPPFEATURES_H + +#include "RVersion.h" + +#ifndef RINGER_STANDALONE +#include "xAODCaloRings/tools/cxx/RingerUseNewCppFeatures.h" +#define FORCE_RINGER_PROCEDURE_TYPE_CONST_EXPR +#else +# define RINGER_USE_NEW_CPP_FEATURES ((__cplusplus >= 201100) && \ + (ROOT_VERSION_CODE >= ROOT_VERSION(6,0,0)) ) +#endif + +#endif // RINGERSELECTORTOOLS_TOOLS_CXX_RINGERUSENEWCPPFEATURES_H diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/StaticAssert.h b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/StaticAssert.h new file mode 100644 index 0000000000000000000000000000000000000000..e1fb4d090f47d5f3ee72e58426fba662dc83dfa5 --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/StaticAssert.h @@ -0,0 +1,21 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: StaticAssert.h 667905 2015-05-18 19:07:55Z wsfreund $ +#ifndef RINGERSELECTORTOOLS_TOOLS_CXX_STATICASSERT_H +#define RINGERSELECTORTOOLS_TOOLS_CXX_STATICASSERT_H + +#include "RingerUseNewCppFeatures.h" + +#undef RINGER_STATIC_ASSERT + +#if RINGER_USE_NEW_CPP_FEATURES +#include<type_traits> +#define RINGER_STATIC_ASSERT(cond,msg) static_assert(cond,msg) +#else +#include "boost/static_assert.hpp" +#define RINGER_STATIC_ASSERT(cond,msg) BOOST_STATIC_ASSERT_MSG(cond,msg) +#endif + +#endif // RINGERSELECTORTOOLS_TOOLS_CXX_STATICASSERT_H diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/add_lvalue_reference.h b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/add_lvalue_reference.h new file mode 100644 index 0000000000000000000000000000000000000000..03ac3f3df94de715ba25bf762411b1c507bff52e --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/add_lvalue_reference.h @@ -0,0 +1,26 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: add_lvalue_reference.h 667905 2015-05-18 19:07:55Z wsfreund $ +#ifndef RINGERSELECTORTOOLS_TOOLS_CXX_ADD_LVALUE_REFERENCE_H +#define RINGERSELECTORTOOLS_TOOLS_CXX_ADD_LVALUE_REFERENCE_H + +#include "RingerUseNewCppFeatures.h" + +#if RINGER_USE_NEW_CPP_FEATURES +#include<type_traits> +namespace Ringer { +using std::add_lvalue_reference; +} // namespace Ringer +#else +#include "boost/type_traits/add_lvalue_reference.hpp" +namespace Ringer { +template < class T> +class add_lvalue_reference : public boost::add_lvalue_reference<T>{}; +} // namespace Ringer +#endif + +#endif // RINGERSELECTORTOOLS_TOOLS_CXX_ADD_LVALUE_REFERENCE_H + + diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/conditional.h b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/conditional.h new file mode 100644 index 0000000000000000000000000000000000000000..ff0ff7b866062db968217b09961d2e1698c73bd4 --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/conditional.h @@ -0,0 +1,25 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: conditional.h 667905 2015-05-18 19:07:55Z wsfreund $ +#ifndef RINGERSELECTORTOOLS_TOOLS_CXX_CONDITIONAL_H +#define RINGERSELECTORTOOLS_TOOLS_CXX_CONDITIONAL_H + +#include "RingerUseNewCppFeatures.h" + +#if RINGER_USE_NEW_CPP_FEATURES +#include<type_traits> +namespace Ringer { +using std::conditional; +} // namespace Ringer +#else +#include "boost/type_traits/conditional.hpp" +namespace Ringer { +template<bool Cond, class T, class F> +class conditional : public boost::conditional<Cond,T,F> {}; +} // namespace Ringer +#endif + +#endif // RINGERSELECTORTOOLS_TOOLS_CXX_CONDITIONAL_H + diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/constexpr.h b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/constexpr.h new file mode 100644 index 0000000000000000000000000000000000000000..113f728ba6e7df2b981f5d1bac667b5786a7b361 --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/constexpr.h @@ -0,0 +1,22 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: constexpr.h 667905 2015-05-18 19:07:55Z wsfreund $ +#ifndef RINGERSELECTORTOOLS_TOOLS_CXX_CONSTEXPR_H +#define RINGERSELECTORTOOLS_TOOLS_CXX_CONSTEXPR_H + +#include "RingerUseNewCppFeatures.h" + +#undef ATH_RINGER_CONSTEXPR + +//CxxUtils for final +#if RINGER_USE_NEW_CPP_FEATURES +# define ATH_RINGER_CONSTEXPR constexpr +#else +# define ATH_RINGER_CONSTEXPR +#endif + + +#endif // RINGERSELECTORTOOLS_TOOLS_CXX_CONSTEXPR_H + diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/decay.h b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/decay.h new file mode 100644 index 0000000000000000000000000000000000000000..0f44edd84d9dd32888ef43bb6607aef9cdcfc0ed --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/decay.h @@ -0,0 +1,25 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: decay.h 667905 2015-05-18 19:07:55Z wsfreund $ +#ifndef RINGERSELECTORTOOLS_TOOLS_CXX_DECAY_H +#define RINGERSELECTORTOOLS_TOOLS_CXX_DECAY_H + +#include "RingerUseNewCppFeatures.h" + +#if RINGER_USE_NEW_CPP_FEATURES +#include<type_traits> +namespace Ringer { +using std::decay; +} // namespace Ringer +#else +#include "boost/type_traits/decay.hpp" +namespace Ringer { +template < class T > +class decay : public boost::decay<T>{}; +} // namespace Ringer +#endif + +#endif // RINGERSELECTORTOOLS_TOOLS_CXX_DECAY_H + diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/enable_if.h b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/enable_if.h new file mode 100644 index 0000000000000000000000000000000000000000..2615acdf56bca479b360e9131fa83bac18720816 --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/enable_if.h @@ -0,0 +1,27 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: enable_if.h 693383 2015-09-06 22:08:55Z wsfreund $ +#ifndef RINGERSELECTORTOOLS_TOOLS_CXX_ENABLE_IF_H +#define RINGERSELECTORTOOLS_TOOLS_CXX_ENABLE_IF_H + +#include "RingerUseNewCppFeatures.h" + + +#if RINGER_USE_NEW_CPP_FEATURES +#include<type_traits> +namespace Ringer { +using std::enable_if; +} // namespace Ringer +#else +#include "CxxUtils/enable_if.h" +namespace Ringer { +template<bool Cond, class T = void> +class enable_if : public enable_if<Cond,T> {}; +} // namespace Ringer +#endif + +#endif // RINGERSELECTORTOOLS_TOOLS_CXX_ENABLE_IF_H + + diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/errorcheck.h b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/errorcheck.h new file mode 100644 index 0000000000000000000000000000000000000000..1db42200890d100e8382309bb35d110e9e2bc57b --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/errorcheck.h @@ -0,0 +1,26 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef RINGERSELECTORTOOLS_TOOLS_CXX_ERRORCHECK_H +#define RINGERSELECTORTOOLS_TOOLS_CXX_ERRORCHECK_H + +#if !defined(RINGER_STANDALONE) && !defined(XAOD_STANDALONE) +# include "AthenaKernel/errorcheck.h" +#else +# ifndef XAOD_STANDALONE +# include <TError.h> // Include ::Error from root +# endif +# define PLACE_INFO __FILE__ +# define CHECK( ARG ) \ + do { \ + const bool result = ARG; \ + if( ! result ) { \ + ::Error( PLACE_INFO, "Failed to execute: \"%s\"", \ + #ARG ); \ + return 1; \ + } \ + } while( false ) +#endif + +#endif // RINGERSELECTORTOOLS_TOOLS_CXX_ERRORCHECK_H diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/final.h b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/final.h new file mode 100644 index 0000000000000000000000000000000000000000..0a5b8e32361da699da69f268a653b01a08309fab --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/final.h @@ -0,0 +1,21 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: final.h 667905 2015-05-18 19:07:55Z wsfreund $ +#ifndef RINGERSELECTORTOOLS_TOOLS_CXX_FINAL_H +#define RINGERSELECTORTOOLS_TOOLS_CXX_FINAL_H + +#include "RingerUseNewCppFeatures.h" + +#undef ATH_RINGER_FINAL + +//CxxUtils for final +#if RINGER_USE_NEW_CPP_FEATURES +# define ATH_RINGER_FINAL final +#else +# define ATH_RINGER_FINAL +#endif + + +#endif // RINGERSELECTORTOOLS_TOOLS_CXX_FINAL_H diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/is_base_of.h b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/is_base_of.h new file mode 100644 index 0000000000000000000000000000000000000000..deb2f648ae7df6a0bfceb4aa88df8e201eaece53 --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/is_base_of.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: is_base_of.h 667905 2015-05-18 19:07:55Z wsfreund $ +#ifndef RINGERSELECTORTOOLS_TOOLS_CXX_ISBASEOF_H +#define RINGERSELECTORTOOLS_TOOLS_CXX_ISBASEOF_H + +#include "RingerUseNewCppFeatures.h" + +#if RINGER_USE_NEW_CPP_FEATURES +#include<type_traits> +namespace Ringer { +using std::is_base_of; +} // namespace Ringer +#else +#include "boost/type_traits/is_base_of.hpp" +namespace Ringer { +template<class Base, class Derived> +class is_base_of : public boost::is_base_of<Base,Derived> {}; +} // namespace Ringer +#endif + +#endif // RINGERSELECTORTOOLS_TOOLS_CXX_ISBASEOF_H diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/is_enum.h b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/is_enum.h new file mode 100644 index 0000000000000000000000000000000000000000..4fad7cf45fd3fe90daddbef1be279ae79c763ae9 --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/is_enum.h @@ -0,0 +1,26 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: is_enum.h 667905 2015-05-18 19:07:55Z wsfreund $ +#ifndef RINGERSELECTORTOOLS_TOOLS_CXX_IS_ENUM_H +#define RINGERSELECTORTOOLS_TOOLS_CXX_IS_ENUM_H + +#include "RingerUseNewCppFeatures.h" + +#if RINGER_USE_NEW_CPP_FEATURES +#include<type_traits> +namespace Ringer { +using std::is_enum; +} // namespace Ringer +#else +#include "boost/type_traits/is_enum.hpp" +namespace Ringer { +template < class T> +class is_enum : public boost::is_enum<T>{}; +} // namespace Ringer +#endif + +#endif // RINGERSELECTORTOOLS_TOOLS_CXX_IS_ENUM_H + + diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/is_same.h b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/is_same.h new file mode 100644 index 0000000000000000000000000000000000000000..e08c454a2a342bf150a656df566f544de87d5889 --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/is_same.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: is_same.h 693383 2015-09-06 22:08:55Z wsfreund $ +#ifndef RINGERSELECTORTOOLS_TOOLS_CXX_ISSAME_H +#define RINGERSELECTORTOOLS_TOOLS_CXX_ISSAME_H + +#include "RingerUseNewCppFeatures.h" + +#if RINGER_USE_NEW_CPP_FEATURES +#include<type_traits> +namespace Ringer { +using std::is_same; +} // namespace Ringer +#else +#include "boost/type_traits/is_base_of.hpp" +namespace Ringer { +template < class T, class U> +class is_same : public boost::is_same<T,U>{}; +} // namespace Ringer +#endif + +#endif // RINGERSELECTORTOOLS_TOOLS_CXX_ISSAME_H diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/mutable.h b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/mutable.h new file mode 100644 index 0000000000000000000000000000000000000000..f0a261fd87c1346bc5d58770fb7b1f143b0bf538 --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/mutable.h @@ -0,0 +1,21 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: mutable.h 667905 2015-05-18 19:07:55Z wsfreund $ +#ifndef RINGERSELECTORTOOLS_TOOLS_CXX_MUTABLE_H +#define RINGERSELECTORTOOLS_TOOLS_CXX_MUTABLE_H + +#include "RingerUseNewCppFeatures.h" + +#ifndef RINGER_STANDALONE +#include "xAODCaloRings/tools/cxx/mutable.h" +#else +#if RINGER_USE_NEW_CPP_FEATURES +# define ATH_RINGER_MUTABLE mutable +#else +# define ATH_RINGER_MUTABLE +#endif +#endif + +#endif // RINGERSELECTORTOOLS_TOOLS_CXX_MUTABLE_H diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/override.h b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/override.h new file mode 100644 index 0000000000000000000000000000000000000000..be29b538df486b2afb9b4d2ccb788a9264f5f000 --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/override.h @@ -0,0 +1,20 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: override.h 667905 2015-05-18 19:07:55Z wsfreund $ +#ifndef RINGERSELECTORTOOLS_TOOLS_CXX_OVERRIDE_H +#define RINGERSELECTORTOOLS_TOOLS_CXX_OVERRIDE_H + +#include "RingerUseNewCppFeatures.h" + +#undef ATH_RINGER_OVERRIDE + +//CxxUtils for override +#if RINGER_USE_NEW_CPP_FEATURES +# define ATH_RINGER_OVERRIDE override +#else +# define ATH_RINGER_OVERRIDE +#endif + +#endif // RINGERSELECTORTOOLS_TOOLS_CXX_OVERRIDE_H diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/remove_cv.h b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/remove_cv.h new file mode 100644 index 0000000000000000000000000000000000000000..3edd406bfd70d173498c6d9e1f99cb440159a54f --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/remove_cv.h @@ -0,0 +1,25 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: remove_cv.h 667905 2015-05-18 19:07:55Z wsfreund $ +#ifndef RINGERSELECTORTOOLS_TOOLS_CXX_REMOVE_CV_H +#define RINGERSELECTORTOOLS_TOOLS_CXX_REMOVE_CV_H + +#include "RingerUseNewCppFeatures.h" + +#if RINGER_USE_NEW_CPP_FEATURES +#include<type_traits> +namespace Ringer { +using std::remove_cv; +} // namespace Ringer +#else +#include "boost/type_traits/remove_cv.hpp" +namespace Ringer { +template < class T> +class remove_cv : public boost::remove_cv<T>{}; +} // namespace Ringer +#endif + +#endif // RINGERSELECTORTOOLS_TOOLS_CXX_REMOVE_CV_H + diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/remove_pointer.h b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/remove_pointer.h new file mode 100644 index 0000000000000000000000000000000000000000..1367fc9205c14518fc5c1606307693c8107ded38 --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/remove_pointer.h @@ -0,0 +1,26 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: remove_pointer.h 667905 2015-05-18 19:07:55Z wsfreund $ +#ifndef RINGERSELECTORTOOLS_TOOLS_CXX_REMOVE_POINTER_H +#define RINGERSELECTORTOOLS_TOOLS_CXX_REMOVE_POINTER_H + +#include "RingerUseNewCppFeatures.h" + +#if RINGER_USE_NEW_CPP_FEATURES +#include<type_traits> +namespace Ringer { +using std::remove_pointer; +} // namespace Ringer +#else +#include "boost/type_traits/remove_pointer.hpp" +namespace Ringer { +template < class T> +class remove_pointer : public boost::remove_pointer<T>{}; +} // namespace Ringer +#endif + +#endif // RINGERSELECTORTOOLS_TOOLS_CXX_REMOVE_POINTER_H + + diff --git a/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/stringify.h b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/stringify.h new file mode 100644 index 0000000000000000000000000000000000000000..b7668d004991dd4f9b1c3a41f1e6646414352181 --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/RingerSelectorTools/tools/cxx/stringify.h @@ -0,0 +1,14 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef RINGERSELECTORTOOLS_TOOLS_CXX_STRINGIZE_H +#define RINGERSELECTORTOOLS_TOOLS_CXX_STRINGIZE_H + +// Simple stringify macro +#define __STRINGIFY(x) #x +#define STRINGIFY(x) __STRINGIFY(x) +#define __PASTE(x,y) x##y +#define PASTE(x) __PASTE(x,y) + +#endif // RINGERSELECTORTOOLS_TOOLS_CXX_STRINGIZE_H diff --git a/PhysicsAnalysis/RingerSelectorTools/Root/AsgElectronRingerSelector.cxx b/PhysicsAnalysis/RingerSelectorTools/Root/AsgElectronRingerSelector.cxx new file mode 100644 index 0000000000000000000000000000000000000000..ecfcef500ad65281fe253c00639ec5f912ddf003 --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/Root/AsgElectronRingerSelector.cxx @@ -0,0 +1,833 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: AsgElectronRingerSelector.cxx 713528 2015-12-09 08:58:44Z wsfreund $ +// STL includes: +#include <string> +#include <stdexcept> +#include <iostream> +#include <limits> +#include <iostream> + +#ifndef RINGER_STANDALONE +// Athena framework includes: +# include "AsgTools/AsgTool.h" +# include "PATCore/TAccept.h" +# include "PathResolver/PathResolver.h" +# include "AthContainers/exceptions.h" + +// xAOD includes: +# include "xAODBase/IParticle.h" +# include "xAODCaloRings/CaloRingsContainer.h" +# include "xAODCaloRings/CaloRingsAuxContainer.h" +# include "xAODCaloRings/RingSetConfContainer.h" +# include "xAODCaloRings/RingSetConfAuxContainer.h" // always include aux container +# include "xAODCaloRings/CaloRingsDefs.h" +# include "xAODCaloRings/tools/getCaloRingsDecorator.h" +# include "xAODCaloRings/RingSetConf.h" +# include "xAODTracking/TrackParticle.h" +# include "xAODEgamma/Electron.h" +#endif // ndef RINGER_STANDALONE + +// Local includes: +#include "RingerSelectorTools/AsgElectronRingerSelector.h" +#include "RingerSelectorTools/ElectronTAccept.h" +#include "RingerSelectorTools/tools/IOHelperFcns.h" +#include "RingerSelectorTools/tools/TrackPatternsHolder.h" +#include "RingerSelectorTools/tools/IRedirectMsgStream.h" +#include "RingerSelectorTools/tools/cxx/RingerUseNewCppFeatures.h" +#include "RingerSelectorTools/tools/cxx/errorcheck.h" + +// Root framework includes: +#include <TFile.h> + +/* + * TODO List: + * + * - We need to change getTAccept logic so that it works exactly for egamma + * particle, and then checks if particle is electron. If true, gets track + * information and feed it into the RingerCommonSelector. + */ + +namespace Ringer { + +#ifndef RINGER_STANDALONE + +namespace { + +//============================================================================== +/** + * @brief Get cluster 2EM layer eta and et variables + * + * NOTE: It isn't being used for now. + **/ +//inline +//void getCluster2EMEtaEt( +// const xAOD::CaloCluster *cluster, +// float &eta2, +// float &et) +//{ +// eta2 = std::fabs(cluster->etaBE(2)); +// // We need to hold the dependence variable within this structure: +// const double energy = cluster->e(); +// if ( eta2 < 999.) { +// const double cosheta = std::cosh(eta2); +// et = (cosheta != 0.) ? energy /cosheta : 0.; +// } +//} + +//============================================================================== +/** + * @brief Check if decision bit is to be used + **/ +//inline +//bool isDecToBeUsed( +// const int bitIntHolder, +// const Ringer::ElectronTAccept::bitMskWord &decsToUse) +//{ +// return decsToUse.test(bitIntHolder); +//} + +} // End of private namespace + + +//============================================================================== +// Standard constructor +//============================================================================== +AsgElectronRingerSelector::AsgElectronRingerSelector(std::string asgToolName) : + AsgMetadataTool(asgToolName), + m_thresWrapper(nullptr), + m_ringSelCommon(nullptr), + m_trackPat(nullptr), + m_partDecMsk(Ringer::ElectronTAccept::retrieveTAcceptTemplate()), + m_accept(Ringer::ElectronTAccept::retrieveTAcceptTemplate()), + m_useCutIDDecision(false), + m_metaDataCached(false), + m_rsConfCont(nullptr), + m_metaIsOnOutput(false) // Check first input +{ + + declareProperty("DiscriminationFileName", m_discrFileName="", + "The configuration file in which we will retrieve the " + "discrimination chain."); + + declareProperty("ThresholdFileName", m_thresFileName="", + "The configuration file in which we will retrieve the " + ""); + + declareProperty("CutsMask", m_cutsMask, + "The required cuts to apply (IsEM Mask)"); + + declareProperty("CutIDSelector", m_cutIDSelector, + "The CutID Tool Handle to run track (if required by discrimation " + "configuration file)"); + + declareProperty("RingSetConfContainerName", m_rsMetaName, + "The RingSetConfContainer key in the MetaData StoreGate"); + + declareProperty("CacheConfData",m_cacheMetaData = true, + "Whether to cache metadata configuration or not"); + + m_ringsELReader = xAOD::getCaloRingsReader(); + +} + +//============================================================================== +// Standard destructor +//============================================================================== +AsgElectronRingerSelector::~AsgElectronRingerSelector() +{ + // Release discriminator wrapper collection memory: + for ( size_t discrColIdx = 0; + discrColIdx < m_discrWrapperCol.size(); + ++discrColIdx ) + { + if (m_discrWrapperCol[discrColIdx]) { + m_discrWrapperCol[discrColIdx]->releaseMemory(); + } + } + + // Release memory from threshold wrapper: + if ( m_thresWrapper ){ + m_thresWrapper->releaseMemory(); + delete m_thresWrapper; + } + + delete m_ringSelCommon; + delete m_trackPat; +} + +//============================================================================== +// finalize method (called by destructor) +//============================================================================== +StatusCode AsgElectronRingerSelector::finalize() +{ + return StatusCode::SUCCESS; +} + + + +//============================================================================== +// Athena initialize method +//============================================================================== +StatusCode AsgElectronRingerSelector::initialize() +{ + // Set the unsigned mask into the bitset + m_cutsToUse = ElectronTAccept::bitMskWord(m_cutsMask); + + ATH_MSG_DEBUG("Cut mask was set to: " << m_cutsToUse.to_string()); + + // Set our configuration: + CHECK( readConfigFiles() ); + + return StatusCode::SUCCESS; +} + +//============================================================================== +StatusCode AsgElectronRingerSelector::readConfigFiles() +{ + + // Use colaboration tool to find true path for file: + std::string discrFileName = PathResolverFindCalibFile( m_discrFileName ); + std::string thresFileName = PathResolverFindCalibFile( m_thresFileName ); + + if( discrFileName.empty() ) { + ATH_MSG_ERROR("Discrimination chain configuration file is not " + "available."); + return StatusCode::FAILURE; + } + + if( thresFileName.empty() ) { + ATH_MSG_ERROR("Threshold configuration file is not " + "available."); + return StatusCode::FAILURE; + } + + // Read discrimination wrapper collection + IDiscrWrapper::read(m_discrWrapperCol, discrFileName.c_str() ); + + ATH_MSG_INFO( "Using DiscriminationFile: " << discrFileName.c_str()); + + // Set message stream and print configuration: + for ( unsigned discrIdx = 0; + discrIdx < m_discrWrapperCol.size(); + ++discrIdx) + { + m_discrWrapperCol[discrIdx]->setMsgStream( &(this->msg())); + m_discrWrapperCol[discrIdx]->print(); + } + + // Get configuration for discrimination information flow + IOConfStruct fileConf; + retrieveFileConf( discrFileName.c_str(), fileConf ); + printConf( fileConf, &(this->msg()) ); + + // Read discrimination wrapper collection + IThresWrapper::read(m_thresWrapper, thresFileName.c_str() ); + + ATH_MSG_INFO( "Using ThresholdFile: " << thresFileName.c_str()); + + // Set message stream and print configuration: + m_thresWrapper->setMsgStream( &(this->msg() )); + m_thresWrapper->print(); + + // Create our discrimination chain selector: + m_ringSelCommon = new Ringer::RingerCommonSelector( + &m_discrWrapperCol, + m_thresWrapper, + &m_partDecMsk, + fileConf.useTrackPat, + fileConf.useRawTrackPat, + fileConf.useCaloCommittee); + + // Set RingerCommonSelector message stream: + m_ringSelCommon->setMsgStream( &(this->msg()) ); + + // Update discrimination wrapper CaloRings configuration + if ( !m_rawConfCol.empty() ){ + for ( auto &discrWrapper : m_discrWrapperCol ) { + discrWrapper->setRawConfCol( &m_rawConfCol ); + } + xAOD::RingSetConf::print( m_rawConfCol, msg() ); + } + + // See if we are using CutID selector and retrieve it if so: + if (m_useCutIDDecision) { + if ( m_cutIDSelector.retrieve().isFailure() ) { + ATH_MSG_FATAL( "Could not get tool: " << m_cutIDSelector ); + return StatusCode::FAILURE; + } + } + + // Create track pattern and make it redirect its stream as if it + // was AsgElectronRingerSelector: + m_trackPat = new Ringer::TrackPatternsHolder( + fileConf.useBLOutliers, + fileConf.usePIXOutliers, + fileConf.useSCTOutliers, + fileConf.useTRTOutliers, + fileConf.useTRTXenonHits); + + m_trackPat->setMsgStream( &(this->msg()) ); + + return StatusCode::SUCCESS; + +} + +//============================================================================= +const Root::TAccept& AsgElectronRingerSelector::accept( + const xAOD::IParticle* part ) const +{ + ATH_MSG_DEBUG("Entering accept( const IParticle* part )"); + + const xAOD::Electron* el = 0; + if( part->type()==xAOD::Type::Electron ){ + el = static_cast<const xAOD::Electron*> (part); + } else { + ATH_MSG_ERROR("AsgElectronRingerSelector::could not convert argument to accept"); + } + + return accept(el); +} + + +// ============================================================================= +const Root::TAccept& AsgElectronRingerSelector::accept( + const xAOD::Electron* el) const +{ + ATH_MSG_DEBUG("Entering accept( const xAOD::Electron* el)"); + + StatusCode sc = execute(el); + + if (sc.isFailure()) { + ATH_MSG_ERROR("Error while on particle AsgSelector execution."); + } + + return m_accept; +} + + +// ============================================================================= +const Root::TAccept& AsgElectronRingerSelector::accept( + const xAOD::Egamma* eg ) const +{ + ATH_MSG_DEBUG("Entering accept( const xAOD::Egamma* part )"); + + StatusCode sc = execute(eg); + + if (sc.isFailure()) { + ATH_MSG_ERROR("Error while on particle AsgSelector execution."); + } + + return m_accept; +} + + +// ============================================================================= +StatusCode AsgElectronRingerSelector::execute( + const xAOD::Electron* el) const +{ + + ATH_MSG_DEBUG("Entering execute(const xAOD::Electron* el...)"); + +#if RINGER_USE_NEW_CPP_FEATURES + // In this case, we only do this to have a more harmonic code: + Root::TAccept &partDecMsk_ref = m_partDecMsk; + TrackPatternsHolder *trackPat_ref = m_trackPat; +#else + // Well, since we do not have mutable properties, we need to do this ugly + // things... + Root::TAccept &partDecMsk_ref = + const_cast<Root::TAccept&>(m_partDecMsk); + TrackPatternsHolder *trackPat_ref = + const_cast<TrackPatternsHolder*>(m_trackPat); +#endif + + // Clear particle decision mask and previous result (set everything as if it + // was passed), prepare to refill it: + partDecMsk_ref.clear(); + + m_ringSelCommon->clear(); + + // No error occurred so far, flag it: + partDecMsk_ref.setCutResult( + BitdefElectron::NoErrorBit, + true); + + // Set if it was requested to execute CutID: + partDecMsk_ref.setCutResult( + BitdefElectron::ExecCutID, + m_useCutIDDecision ); + + if (!el){ + ATH_MSG_ERROR("Invalid electron pointer."); + + partDecMsk_ref.setCutResult( + BitdefElectron::NoErrorBit, + false); + + return StatusCode::FAILURE; + } + + // First, check if we can retrieve decoration: + const xAOD::CaloRingsLinks *caloRingsLinks(nullptr); + try { + caloRingsLinks = &(m_ringsELReader->operator()(*el)); + } catch ( const std::exception &e) { + ATH_MSG_ERROR("Couldn't retrieve CaloRingsLinks. Reason: " + << e.what()); + } + + if ( caloRingsLinks->empty() ){ + + ATH_MSG_ERROR("Particle does not have CaloRings decoratorion."); + + partDecMsk_ref.setCutResult( + BitdefElectron::NoErrorBit, + false); + + return StatusCode::FAILURE; + } + + // FIXME The indexing should be an enum, previous test should ensure that the + // size is large enought to access index. + if ( !caloRingsLinks->at(0).isValid() ){ + ATH_MSG_DEBUG("Ignoring candidate with invalid ElementLink."); + + partDecMsk_ref.setCutResult( + BitdefElectron::NoErrorBit, + false); + + return StatusCode::SUCCESS; + } + + + // For now, we are using only the first cluster + const xAOD::CaloRings *clrings = *(caloRingsLinks->at(0)); + + // Check if everything is ok with CaloRings ElementLink vector: + if (caloRingsLinks->empty() || !(clrings) ){ + + ATH_MSG_ERROR("There isn't CaloRings Decoration available" + " for input particle." ); + + partDecMsk_ref.setCutResult( + BitdefElectron::NoErrorBit, + false ); + + return StatusCode::FAILURE; + } + + // Get track information: + const xAOD::TrackParticle *track = el->trackParticle(); + + // Fill track pattern holder with new information: + trackPat_ref->extractPatternsFrom( track, el ); + + // Put cluster calibrated eta/et into DepVarStruct: + const xAOD::CaloCluster *cluster = el->caloCluster(); + const DepVarStruct depVar( cluster->eta(), + cluster->et() ); + + // We head now into the RingerChain execution: + try { + // Execute Ringer Selector Common: + if ( m_ringSelCommon->execute( + depVar, + clrings, + trackPat_ref).isFailure() ) + { + + ATH_MSG_ERROR("Error while executing " + "RingerCommonSelector."); + + partDecMsk_ref.setCutResult( + BitdefElectron::NoErrorBit, + false); + + } + } catch (const std::exception &e ) { + + ATH_MSG_ERROR("Error while executing " + "RingerCommonSelector. Reason: " << e.what() ); + + partDecMsk_ref.setCutResult( + BitdefElectron::NoErrorBit, + false); + + } + + // Add the CutID track decision bit (if requested): + if ( m_useCutIDDecision ) { + try { + partDecMsk_ref.setCutResult( + BitdefElectron::CutIDDec, + static_cast<bool>(m_cutIDSelector->accept(el)) ); + + } catch ( const std::exception &e ) { + + ATH_MSG_ERROR("Error while executing " + "AsgElectronRingerSelector. Reason:" << e.what() ); + + partDecMsk_ref.setCutResult( + BitdefElectron::NoErrorBit, + false ); + + partDecMsk_ref.setCutResult( + BitdefElectron::CutIDDec , + false ); + + } + } else { + + // If we do not run it, set track decision to true: + partDecMsk_ref.setCutResult( + BitdefElectron::CutIDDec , + true ); + + } + + // We have finished, then fill decision mask: + fillTAccept(); + + // Check if an error occurred, and flag it: + if ( partDecMsk_ref.getCutResult( + BitdefElectron::NoErrorBit ) ) + { + return StatusCode::SUCCESS; + } else { + return StatusCode::FAILURE; + } +} + +//============================================================================== +StatusCode AsgElectronRingerSelector::execute(const xAOD::Egamma* eg) const +{ + ATH_MSG_DEBUG("entering execute(const xAOD::Egamma* eg...)"); + + if (eg){ + //size_t cDiscr = 0; + } else { + ATH_MSG_ERROR("Egamma pointer is null."); + return StatusCode::FAILURE; + } + + return StatusCode::SUCCESS; +} + +//============================================================================= +// Fill the m_accept from the m_partDecMsk mask using the m_cutsToUse +//============================================================================= +void AsgElectronRingerSelector::fillTAccept() const +{ +#if RINGER_USE_NEW_CPP_FEATURES + // In this case, we only do this to have a more harmonic code: + Root::TAccept &accept_ref = m_accept; +#else + // Well, since we do not have mutable properties, we need to do this ugly + // things... + Root::TAccept &accept_ref = const_cast<Root::TAccept&>(m_accept); +#endif + for (unsigned bit = 0; bit < BitdefElectron::NUsedBits(); ++bit ){ + // m_partDec mask is set to true if passed cut. + // m_cutsToUse is set to true if cut is to be used. + accept_ref.setCutResult( bit, + (m_partDecMsk.getCutResult(bit)) || !m_cutsToUse[bit] ); + } +} + +//============================================================================== +StatusCode AsgElectronRingerSelector::beginInputFile() +{ + + // Tell the user what's happening: + ATH_MSG_DEBUG( "Entered new file, checking if it is needed to " + "update metadata information."); + + if ( m_cacheMetaData && m_metaDataCached ) { + ATH_MSG_DEBUG( "Metadata is already cached." ); + return StatusCode::SUCCESS; + } + + // Read the metadata object: + m_rsConfCont = nullptr; + + bool failedToRetrieveInInput(false); + + // First we try to obtain configuration on the inputMetaStore. If this does + // not work, we try to obtain it on the outputMetaStore. +#if !defined(XAOD_STANDALONE) && !defined(XAOD_ANALYSIS) + if ( !m_metaIsOnOutput && ( ( m_rsConfCont = inputMetaStore()-> + tryConstRetrieve< xAOD::RingSetConfContainer >( m_rsMetaName ) ) + == nullptr ) ) + { + if ( !m_metaIsOnOutput ) { + failedToRetrieveInInput = true; + ATH_MSG_DEBUG("Couldn't retrieve on inputMetaStore, will " + "try to retrieve from outputMetaStore."); + } + } else { + ATH_MSG_DEBUG("Retrieved meta from inputMetaStore."); + } +#else + if ( !m_metaIsOnOutput && + inputMetaStore()->retrieve( m_rsConfCont, m_rsMetaName ) ) + { + if ( !m_metaIsOnOutput ) { + failedToRetrieveInInput = true; + ATH_MSG_DEBUG("Couldn't retrieve on inputMetaStore, will " + "try to retrieve from outputMetaStore."); + } + } else { + ATH_MSG_DEBUG("Retrieved meta from inputMetaStore."); + } +#endif + + // We also attempt to retrieve on outputMetaStore if inputMetaStore failed: + if ( ( m_metaIsOnOutput || failedToRetrieveInInput ) && + outputMetaStore()->retrieve( m_rsConfCont, m_rsMetaName ).isFailure()) + { + // FIXME: This should be done by manually setting the metadata information + // if it is not set (if manually set, do not attempt to retrieve on the + // metadata store). + ATH_MSG_WARNING( "Couldn't retrieve rings configuration on both " + "inputMetaStore and outputMetaStore. Setting default value, " + "(which might be wrong)." ); + m_rawConfCol.clear(); + m_rawConfCol = { + {8, + std::vector<CaloSampling::CaloSample>(), 0., 0., 0., 0., + Ringer::CalJointLayer::PS, + Ringer::CalJointSection::EM, + false, false, + 0, 8, + 0, 88}, + {64, + std::vector<CaloSampling::CaloSample>(), 0., 0., 0., 0., + Ringer::CalJointLayer::EM1, + Ringer::CalJointSection::EM, + false, false, + 8, 72, + 0, 88}, + {8, + std::vector<CaloSampling::CaloSample>(), 0., 0., 0., 0., + Ringer::CalJointLayer::EM2, + Ringer::CalJointSection::EM, + false, false, + 72, 80, + 0, 88}, + {8, + std::vector<CaloSampling::CaloSample>(), 0., 0., 0., 0., + Ringer::CalJointLayer::EM3, + Ringer::CalJointSection::EM, + false, false, + 80, 88, + 0, 88}, + {4, + std::vector<CaloSampling::CaloSample>(), 0., 0., 0., 0., + Ringer::CalJointLayer::HAD1, + Ringer::CalJointSection::HAD, + false, false, + 88, 92, + 88, 100}, + {4, + std::vector<CaloSampling::CaloSample>(), 0., 0., 0., 0., + Ringer::CalJointLayer::HAD2, + Ringer::CalJointSection::HAD, + false, false, + 92, 96, + 88, 100}, + {4, + std::vector<CaloSampling::CaloSample>(), 0., 0., 0., 0., + Ringer::CalJointLayer::HAD3, + Ringer::CalJointSection::HAD, + false, false, + 96, 100, + 88, 100} }; + for ( auto &discrWrapper : m_discrWrapperCol ) { + discrWrapper->setRawConfCol( &m_rawConfCol ); + } + xAOD::RingSetConf::print( m_rawConfCol, msg() ); + m_metaDataCached = true; + } else { + // Flag that meta is on outputMeta rather than the input + if ( failedToRetrieveInInput ){ + m_metaIsOnOutput = true; + ATH_MSG_DEBUG("Retrieved meta from outputMetaStore."); + } + } + + ATH_MSG_DEBUG("Successfully retrieved store, " + "trying to get RawConfiguration Collection."); + + // A little sanity check: + if( !m_rsConfCont || m_rsConfCont->empty() ) { + ATH_MSG_ERROR( "Metadata " << m_rsMetaName << " is not available on file." ); + return StatusCode::FAILURE; + } + + // Retrieve the raw configuration: + xAOD::RingSetConf::getRawConfCol( m_rawConfCol, m_rsConfCont ); + + // Sign that it can be cached, if we want to cache it for the whole run: + m_metaDataCached = true; + + // Pass its pointer into each wrapper in the discrimination chain: + for ( auto &discrWrapper : m_discrWrapperCol ) { + discrWrapper->setRawConfCol( &m_rawConfCol ); + } + xAOD::RingSetConf::print( m_rawConfCol, msg() ); + + ATH_MSG_DEBUG( "Successfully retrieve configuration info."); + + return StatusCode::SUCCESS; +} + +//============================================================================== +StatusCode AsgElectronRingerSelector::beginEvent(){ + // This doesn't do anything for now, return gracefully: + return StatusCode::SUCCESS; +} + +#endif // RINGER_STANDALONE + +// ============================================================================= +void AsgElectronRingerSelector::retrieveFileConf(const char *fileName, + IOConfStruct &fileConf) +{ + // Try to open file and check if nothing wrong happened: + TFile file(fileName, "READ"); + IOHelperFcns::checkFile( file ); + + TDirectory* configDir = file.GetDirectory(""); + + // When start using a version that this properties MUST be defined + // in the file, change the max to the version value and implement + // the else routine where it does throw. + if ( IOHelperFcns::getWrittenVersion(configDir) + < std::numeric_limits<unsigned int>::max() ) + { + try { + IOHelperFcns::readVar( configDir, + "useTrackPat", + fileConf.useTrackPat ); + } catch( std::runtime_error & ){;} + try { + IOHelperFcns::readVar( configDir, + "useRawTrackPat", + fileConf.useRawTrackPat ); + } catch( std::runtime_error & ){;} + //try { + // IOHelperFcns::readVar( configDir, + // "useRawCalStdPat", + // fileConf.useRawCalStdPat ); + //} catch( std::runtime_error & ){;} + //try { + // IOHelperFcns::readVar( configDir, + // "useCalStdPat", + // fileConf.useCaloCommittee ); + //} catch( std::runtime_error & ){;} + try { + IOHelperFcns::readVar( configDir, + "useCaloCommittee", + fileConf.useCaloCommittee ); + } catch( std::runtime_error & ){;} + try { + IOHelperFcns::readVar( configDir, + "useBLOutliers", + fileConf.useBLOutliers ); + } catch( std::runtime_error & ){;} + try { + IOHelperFcns::readVar( configDir, + "usePIXOutliers", + fileConf.usePIXOutliers ); + } catch( std::runtime_error & ){;} + try { + IOHelperFcns::readVar( configDir, + "useSCTOutliers", + fileConf.useSCTOutliers ); + } catch( std::runtime_error & ){;} + try { + IOHelperFcns::readVar( configDir, + "useTRTOutliers", + fileConf.useTRTOutliers ); + } catch( std::runtime_error & ){;} + try { + IOHelperFcns::readVar( configDir, + "useTRTXenonHits", + fileConf.useTRTXenonHits ); + } catch( std::runtime_error & ){;} + } /* else if */ + + file.Close(); + return; +} + +// ============================================================================= +void AsgElectronRingerSelector::writeConf(const char* fileName, + IOConfStruct &fileConf) +{ + // Try to open file and check if nothing wrong happened: + TFile file(fileName, "UPDATE"); + IOHelperFcns::checkFile( file ); + + TDirectory* configDir = file.GetDirectory(""); + + IOHelperFcns::writeVar( configDir, + "useTrackPat", + fileConf.useTrackPat ); + IOHelperFcns::writeVar( configDir, + "useRawTrackPat", + fileConf.useRawTrackPat ); + //IOHelperFcns::writeVar( configDir, + // "useRawCalStdPat", + // fileConf.useRawCalStdPat ); + //IOHelperFcns::writeVar( configDir, + // "useCalStdPat", + // fileConf.useCaloCommittee ); + IOHelperFcns::writeVar( configDir, + "useCaloCommittee", + fileConf.useCaloCommittee ); + IOHelperFcns::writeVar( configDir, + "useBLOutliers", + fileConf.useBLOutliers ); + IOHelperFcns::writeVar( configDir, + "usePIXOutliers", + fileConf.usePIXOutliers ); + IOHelperFcns::writeVar( configDir, + "useSCTOutliers", + fileConf.useSCTOutliers ); + IOHelperFcns::writeVar( configDir, + "useTRTOutliers", + fileConf.useTRTOutliers ); + IOHelperFcns::writeVar( configDir, + "useTRTXenonHits", + fileConf.useTRTXenonHits ); + file.Close(); +} + +// ============================================================================= +void AsgElectronRingerSelector::printConf( IOConfStruct &fileConf, + MsgStream *msg, MSG::Level lvl) +{ + if ( msg && msg->level() <= lvl ){ + auto flags = static_cast<std::ios_base::fmtflags>(msg->flags()); + (*msg) << lvl << "File configuration is: " << endreq; + (*msg) << lvl << std::boolalpha << "useTrackPat: " << fileConf.useTrackPat + << " | useRawTrackPat: " << fileConf.useRawTrackPat + << " | useCaloCommittee: " << fileConf.useCaloCommittee + << " | useBLOutliers: " << fileConf.useBLOutliers + << " | usePIXOutliers: " << fileConf.usePIXOutliers + << " | useSCTOutliers: " << fileConf.useSCTOutliers + << " | useTRTOutliers: " << fileConf.useTRTOutliers + << " | useTRTXenonHits: " << fileConf.useTRTXenonHits + << endreq; + // reset previous cout flags + msg->flags(flags); + } +} + + +} // namespace Ringer + diff --git a/PhysicsAnalysis/RingerSelectorTools/Root/ElectronTAccept.cxx b/PhysicsAnalysis/RingerSelectorTools/Root/ElectronTAccept.cxx new file mode 100644 index 0000000000000000000000000000000000000000..196f6f67181fd824dda29973c11eb86f0f059ac5 --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/Root/ElectronTAccept.cxx @@ -0,0 +1,137 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: ElectronTAccept.cxx 704615 2015-10-29 18:50:12Z wsfreund $ +#ifndef RINGER_STANDALONE + +#include "RingerSelectorTools/ElectronTAccept.h" + +#include "RingerSelectorTools/tools/DeclareBit.h" + +namespace Ringer { + +// link this namespace to the static counter +COUNTER_LINK_NAMESPACE + +// This is the counter which will check if we ran out of bits +DEFINE_COUNTER( ElectronNBits ) + +// ============================================================================= +/// Define the ElectronTAcceptHolder_v1 holden TAccept: +Root::TAccept ElectronTAccept_v1::m_accept("ElectronDecisionMask"); + +// ============================================================================= +// Define the bit counter: +unsigned BitdefElectron_v1::m_nUsedBits = 0; + +// ============================================================================= +/// Bit set to true when no error occurs: +DECLARE_BIT(BitdefElectron_v1, NoErrorBit, + "Bit destinated to flag error occurrance.", + ElectronNBits ) + +// ============================================================================= +// Bit to flag whether track CutID was run: +DECLARE_BIT(BitdefElectron_v1, ExecCutID, + "Flag whether executed Ringer holden CutID algorithm.", + ElectronNBits ) + +// ============================================================================= +/// The decision position of the CutID: +DECLARE_BIT(BitdefElectron_v1, CutIDDec, + "Ringer holden CutID algorithm decision.", + ElectronNBits ) + +// ============================================================================= +/// The decision position of the Ringer algorithm's discrimation chain: +DECLARE_BIT(BitdefElectron_v1, RingerChainDec, + "Ringer algorithm discrimation chain decision." , + ElectronNBits ) + +// ============================================================================= +unsigned int ElectronTAccept_v1::getAppliedCutMsk( const Requirement cut, + bool withCutIDTrack) +{ + // Create an empty word: + ElectronTAccept_v1::bitMskWord word(0); + + switch (cut) { + case Requirement::Loose_CutID_Pd: + case Requirement::Loose_CutID_Pf: + case Requirement::Loose_LH_Pd: + case Requirement::Loose_LH_Pf: + case Requirement::Loose: + // Add for all loose configuration their cuts applied: + ElectronTAccept_v1::addLooseAppliedCuts(word); + break; + case Requirement::Medium_CutID_Pd: + case Requirement::Medium_CutID_Pf: + case Requirement::Medium_LH_Pd: + case Requirement::Medium_LH_Pf: + case Requirement::Medium_MaxSP: + case Requirement::Medium: + // Add for all medium configuration their cuts applied: + ElectronTAccept_v1::addMediumAppliedCuts(word); + break; + case Requirement::Tight_CutID_Pf: + case Requirement::Tight_CutID_Pd: + case Requirement::Tight_LH_Pf: + case Requirement::Tight_LH_Pd: + case Requirement::Tight: + // Add for all tight configuration their cuts applied: + ElectronTAccept_v1::addTightAppliedCuts(word); + break; + case Requirement::NoCut: + // Just for safity, reset mask bits: + ElectronTAccept_v1::resetMsk(word); + break; + default: + throw std::runtime_error(std::string("Unknown required cut.")); + } + // If we requested to add track cuts, add them: + if (withCutIDTrack) { + ElectronTAccept_v1::addCutIDTrackAppliedCuts(word); + } + return word.to_ulong(); +} + +// ============================================================================= +void ElectronTAccept_v1::resetMsk(bitMskWord& word) +{ + word.reset(); +} + +// ============================================================================= +void ElectronTAccept_v1::addLooseAppliedCuts(bitMskWord& word) +{ + word.set(BitdefElectron_v1::NoErrorBit); + word.set(BitdefElectron_v1::RingerChainDec); +} + +// ============================================================================= +void ElectronTAccept_v1::addMediumAppliedCuts(bitMskWord& word) +{ + word.set(BitdefElectron_v1::NoErrorBit); + word.set(BitdefElectron_v1::RingerChainDec); +} + +// ============================================================================= +void ElectronTAccept_v1::addTightAppliedCuts(bitMskWord& word) +{ + word.set(BitdefElectron_v1::NoErrorBit); + word.set(BitdefElectron_v1::RingerChainDec); +} + +// ============================================================================= +void ElectronTAccept_v1::addCutIDTrackAppliedCuts( + bitMskWord& word) +{ + word.set(BitdefElectron_v1::ExecCutID); + word.set(BitdefElectron_v1::CutIDDec); +} + +} // namespace Ringer + +#endif + diff --git a/PhysicsAnalysis/RingerSelectorTools/Root/RingerSelectorToolsDefs.cxx b/PhysicsAnalysis/RingerSelectorTools/Root/RingerSelectorToolsDefs.cxx new file mode 100644 index 0000000000000000000000000000000000000000..9fffa79d3571d8a8ac19dda9070ed444580011b7 --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/Root/RingerSelectorToolsDefs.cxx @@ -0,0 +1,234 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: RingerSelectorToolsDefs.cxx 670599 2015-05-28 14:15:35Z wsfreund $ +#include "RingerSelectorTools/RingerSelectorToolsDefs.h" + +#ifndef RINGER_STANDALONE +#include "xAODCaloRings/CaloRingsDefs.h" +#endif + +// Local includes: +#include "RingerSelectorTools/tools/Exceptions.h" + +namespace Ringer { + +// ============================================================================= +unsigned numberOfSegments(const SegmentationType e) +{ + switch (e){ + case SegmentationType::NoSegmentation: + return 1; + break; + case SegmentationType::TrackCalSegmentation: + return numberOfSegments(SegmentationType::NoSegmentation) + 1; + break; + case SegmentationType::TrackCalPatTypeSegmentation: + return numberOfSegments(SegmentationType::TrackCalSegmentation) + 1; + break; + case SegmentationType::TrackCalJointSections: + return numberOfSegments(TrackCalPatTypeSegmentation) - 1 + +#ifdef RINGER_STANDALONE + 2; +#else + CalJointSection::NJointSections; +#endif + break; + case SegmentationType::TrackCalJointLayers: + return numberOfSegments(TrackCalPatTypeSegmentation) - 1 + +#ifdef RINGER_STANDALONE + 7; +#else + CalJointLayer::NJointLayers; +#endif + break; + default: + throw std::runtime_error(std::string("Could not recognize ") + + "SegmentationType(" + std::to_string(int(e)) + + ") to numberOfSegments method on RingerSelectorToolsDefs.cxx" + " file."); + } +} + +// ============================================================================= +template<> +SegmentationType getType(const char* cStr) +{ + std::string strType(cStr); + if (strType=="NoSegmentation"){ + return NoSegmentation; + } else if ( strType=="TrackCalSegmentation" ){ + return TrackCalSegmentation; + } else if ( strType=="TrackCalPatTypeSegmentation" ){ + return TrackCalPatTypeSegmentation; + } else if ( strType=="TrackCalJointSections" ){ + return TrackCalJointSections; + } else if ( strType == "TrackCalJointLayers" ){ + return TrackCalJointLayers; + } else { + throw Exceptions::no_such_type("SegmentationType",strType, + "RingerSelectorToolsDefs"); + } +} + +// ============================================================================= +template<> +EtaDependency getType(const char* cStr) +{ + std::string strType(cStr); + if (strType=="EtaIndependent"){ + return EtaIndependent; + } else if ( strType=="EtaDependent" ){ + return EtaDependent; + } else { + throw Exceptions::no_such_type("EtaDependency",strType, + "RingerSelectorToolsDefs"); + } +} + +// ============================================================================= +template<> +EtDependency getType(const char* cStr) +{ + std::string strType(cStr); + if (strType=="EtIndependent"){ + return EtIndependent; + } else if ( strType=="EtDependent" ){ + return EtDependent; + } else { + throw Exceptions::no_such_type("EtDependency",strType, + "RingerSelectorToolsDefs"); + } +} +// ============================================================================= +template<> +Requirement getType(const char* cStr) +{ + std::string strType(cStr); + if ( strType=="Loose" ) { + return Loose; + } else if ( strType=="Medium" ) { + return Medium; + } else if ( strType=="Tight" ) { + return Tight; + } else if (strType=="Loose_CutID_Pd"){ + return Loose_CutID_Pd; + } else if ( strType=="Medium_CutID_Pd" ) { + return Medium_CutID_Pd; + } else if ( strType=="Tight_CutID_Pd" ) { + return Tight_CutID_Pd; + } else if (strType=="Loose_CutID_Pd"){ + return Loose_CutID_Pf; + } else if ( strType=="Medium_CutID_Pf" ) { + return Medium_CutID_Pf; + } else if ( strType=="Tight_CutID_Pf" ) { + return Tight_CutID_Pf; + } else if ( strType=="Medium_MaxSP" ) { + return Medium_MaxSP; + } else if ( strType=="NoCut" ) { + return NoCut; + } else { + throw Exceptions::no_such_type("Requirement",strType, + "RingerSelectorToolsDefs"); + } +} + +// ============================================================================= +const char* toStr(SegmentationType e) +{ + switch (e){ + case SegmentationType::NoSegmentation: + return "NoSegmentation"; + break; + case SegmentationType::TrackCalSegmentation: + return "TrackCalSegmentation"; + break; + case SegmentationType::TrackCalPatTypeSegmentation: + return "TrackCalPatTypeSegmentation"; + break; + case SegmentationType::TrackCalJointSections: + return "TrackCalJointSections"; + break; + case SegmentationType::TrackCalJointLayers: + return "TrackCalJointLayers"; + break; + default: + throw Exceptions::no_such_type(e, "RingerSelectorToolsDefs"); + } +} + +// ============================================================================= +const char* toStr(EtaDependency e) +{ + switch (e){ + case EtaDependency::EtaDependent: + return "EtaDependent"; + break; + case EtaDependency::EtaIndependent: + return "EtaIndependent"; + break; + default: + throw Exceptions::no_such_type(e, "RingerSelectorToolsDefs"); + } +} + +// ============================================================================= +const char* toStr(EtDependency e) +{ + switch (e){ + case EtDependency::EtDependent: + return "EtDependent"; + break; + case EtDependency::EtIndependent: + return "EtIndependent"; + break; + default: + throw Exceptions::no_such_type(e, "RingerSelectorToolsDefs"); + } +} + +// ============================================================================= +const char* toStr(Requirement e) +{ + switch (e){ + case Requirement::Loose: + return "Loose"; + break; + case Requirement::Medium: + return "Medium"; + break; + case Requirement::Tight: + return "Tight"; + break; + case Requirement::Loose_CutID_Pd: + return "Loose_CutID_Pd"; + break; + case Requirement::Medium_CutID_Pd: + return "Medium_CutID_Pd"; + break; + case Requirement::Tight_CutID_Pd: + return "Tight_CutID_Pd"; + break; + case Requirement::Loose_CutID_Pf: + return "Loose_CutID_Pf"; + break; + case Requirement::Medium_CutID_Pf: + return "Medium_CutID_Pf"; + break; + case Requirement::Tight_CutID_Pf: + return "Tight_CutID_Pf"; + break; + case Requirement::Medium_MaxSP: + return "Medium_MaxSP"; + break; + case Requirement::NoCut: + return "NoCut"; + break; + default: + throw Exceptions::no_such_type(e, "RingerSelectorToolsDefs"); + } +} + +} // namespace Ringer + diff --git a/PhysicsAnalysis/RingerSelectorTools/Root/procedures/IRingerProcedure.cxx b/PhysicsAnalysis/RingerSelectorTools/Root/procedures/IRingerProcedure.cxx new file mode 100644 index 0000000000000000000000000000000000000000..aad7b97deaa8d5242bd049b2b47ad135e5245e65 --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/Root/procedures/IRingerProcedure.cxx @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: IRingerProcedure.cxx 667905 2015-05-18 19:07:55Z wsfreund $ +#include "RingerSelectorTools/procedures/IRingerProcedure.h" + +#if !(RINGER_USE_NEW_CPP_FEATURES || defined(FORCE_RINGER_PROCEDURE_TYPE_CONST_EXPR)) +template< typename procedure_t > +const bool RingerProcedureType<procedure_t>::is_pre_processor = + Ringer::is_base_of<PreProcessing::IPreProcessor,procedure_t>::value; + +template< typename procedure_t > +const bool RingerProcedureType<procedure_t>::is_discriminator = + Ringer::is_base_of<Discrimination::IDiscriminator,procedure_t>::value; + +template< typename procedure_t > +const bool RingerProcedureType<procedure_t>::is_threshold = + Ringer::is_base_of<Discrimination::IThreshold,procedure_t>::value; +#endif + + + + diff --git a/PhysicsAnalysis/RingerSelectorTools/Root/procedures/NeuralNetwork.cxx b/PhysicsAnalysis/RingerSelectorTools/Root/procedures/NeuralNetwork.cxx new file mode 100644 index 0000000000000000000000000000000000000000..e17cb5d5c5b6272ce6faa980bab7197c60ebee7d --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/Root/procedures/NeuralNetwork.cxx @@ -0,0 +1,284 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: NeuralNetwork.cxx 704615 2015-10-29 18:50:12Z wsfreund $ +#include "RingerSelectorTools/procedures/NeuralNetwork.h" + +// STL includes: +#include <vector> +#include <cmath> +#include <exception> +#include <algorithm> + +//#undef NDEBUG + +//#include <boost/python/stl_iterator.hpp> + +namespace Ringer { + +//template< typename T > +//inline +//std::vector< T > to_std_vector( const boost::python::object& iterable ) +//{ +// return std::vector< T >( boost::python::stl_input_iterator< T >( iterable ), +// boost::python::stl_input_iterator< T >( ) ); +//} + +namespace Discrimination { + +// ============================================================================= +NNFeedForward::NNFeedForward( + const std::vector<unsigned int> &n, + const std::vector<float> &w, + const std::vector<float> &b) + : m_wM(nullptr), + m_bM(nullptr), + m_mM(nullptr) +{ + changeArchiteture(n,w,b); +} + + +// ============================================================================= +// void NNFeedForward::changeArchiteture( +// boost::python::list &n, +// boost::python::list &w, +// boost::python::list &b) +// { +// changeArchiteture(to_std_vector<unsigned int>(n), +// to_std_vector<float>(w), +// to_std_vector<float>(b)); +// } + +// ============================================================================= +void NNFeedForward::changeArchiteture( + const std::vector<unsigned int> &n, + const std::vector<float> &w, + const std::vector<float> &b) +{ + + if ( n.empty() ) { + throw std::invalid_argument( + std::string("Invalid node argument (empty).")); + } + //Verifying weight vector size + unsigned int wSize=0; + for (unsigned int k=0; k<n.size()-1; ++k) { + wSize+=n[k]*n[k+1]; + } + if (wSize != w.size() || !w.size() ) { + throw std::invalid_argument( + std::string("Invalid weight argument.")); + } + //Verifying bias vector size + unsigned int bSize=0; + for (unsigned int k=1; k<n.size(); ++k) { + bSize+=n[k]; + } + if(bSize != b.size() || !b.size() ) { + throw std::invalid_argument( + std::string("Invalid bias argument.")); + } + + // Configuration is ok, copy it: + m_nodes = n; + m_nLayers = n.size(); + + // Release possible older architeture: + releaseWeights(); + releaseBias(); + releaseMMatrix(); + + //First weight dimension + m_wM = new float **[m_nLayers-1]; //number of layers excluding input + //First bias dimension + m_bM = new float *[m_nLayers-1]; //number of layers excluding input + //First multiplication dimension + m_mM = new float *[m_nLayers]; //number of layers including input + + for (unsigned int l = 0; l<m_nLayers; ++l){ + m_mM[l] = new float[n[l]]; //number of m_nodes in current layer + } + std::vector<float>::const_iterator itrB = b.begin(); + std::vector<float>::const_iterator itrW = w.begin(); + for (unsigned int l = 0; l < m_nLayers-1; ++l){ + //Second and last dimension of m_bM + m_bM[l] = new float[n[l+1]]; //number of m_nodes in next layer + //Second dimension of m_wM + m_wM[l] = new float*[n[l+1]]; //number of m_nodes in next layer + for (unsigned int i=0; i<n[l+1]; i++){ + //Third and last dimension of m_wM + m_wM[l][i]=new float [n[l]]; //number of m_nodes in current layer + //Populating bias matrix + m_bM[l][i]=(*itrB++); + //Populating weight matrix + for (unsigned int j=0; j<n[l]; j++){ + m_wM[l][i][j]=(*itrW++); + } + } + //Populating multiplication matrix so that starting sum equals zero + for (unsigned int i=0; i<n[l]; i++){ + m_mM[l][i]=0; + } + } +} + +// ============================================================================= +void NNFeedForward::releaseBias(){ + if (m_bM){ + for (unsigned int l=0; l<m_nodes.size()-1; ++l){ + delete[] m_bM[l]; //Deletes array of values at second dimension of m_bM + } + } + delete[] m_bM; //Deletes array of pointers at first dimension of m_bM + m_bM = nullptr; +} + +// ============================================================================= +void NNFeedForward::releaseWeights(){ + if (m_wM){ + for (unsigned int l=0; l<m_nodes.size()-1; ++l){ + if (m_wM[l]){ + for (unsigned int i=0; i<m_nodes[l+1]; ++i){ + delete[] m_wM[l][i]; //Deletes array of values at third dimension of m_wM + } + } + delete[] m_wM[l]; // Deletes array of pointers at second dimension of m_wM + } + } + delete[] m_wM; //Deletes array of pointers at first dimension of m_wM + m_wM = nullptr; +} + +// ============================================================================= +void NNFeedForward::releaseMMatrix(){ + if(m_mM){ + for (unsigned int l=0; l<m_nodes.size(); ++l){ + delete[] m_mM[l]; //Deletes array of values at second dimension of m_mM + } + } + delete[] m_mM; //Deletes array of pointers at first dimension of m_mM + m_mM = nullptr; +} + + +// ============================================================================= +NNFeedForward::~NNFeedForward() +{ + releaseWeights(); + releaseBias(); + releaseMMatrix(); +} + +// ============================================================================= +void NNFeedForward::execute( + const std::vector<float> &input, + std::vector<float> &output) const +{ +#ifndef NDEBUG + ATH_MSG_DEBUG("Applying NNFeedForward. Pattern space is: " << input); +#endif + if ( input.size() != m_nodes[0] ){ + throw std::runtime_error(std::string("Pattern space size (") + + std::to_string(input.size()) + ") fed to discriminator is " + "not compatible with this discriminator pattern space size (" + + std::to_string(m_nodes[0]) + "."); + } + // Copy vector to input layer: + for(unsigned int i=0; i<input.size();i++){ + m_mM[0][i]=input[i]; + } + // Propagate: + for(unsigned int l=0; l<m_nodes.size()-1;l++){ + for(unsigned int k=0; k<m_nodes[l+1]; k++){ + m_mM[l+1][k]=m_bM[l][k]; + for (unsigned int j=0;j<m_nodes[l]; j++){ + m_mM[l+1][k]+=m_mM[l][j]*m_wM[l][k][j]; + } + m_mM[l+1][k]=tanh(m_mM[l+1][k]); + } + } + + // Resize output to hold new entries + output.clear(); + + // Insert result at output vector: + output.insert( output.begin(), + m_mM[m_nLayers-1], + m_mM[m_nLayers-1] + m_nodes[m_nLayers-1] + ); + +#ifndef NDEBUG + ATH_MSG_DEBUG("Output space is: " << output); +#endif +} + +// ============================================================================= +void NNFeedForward::getWeigthsAndBias(std::vector<float> &weights, + std::vector<float> &bias) const +{ + weights.clear(); + bias.clear(); + for ( size_t cLayer = 0; cLayer < m_nLayers - 1; ++cLayer ){ + unsigned nCurLayer = m_nodes[cLayer]; + unsigned nNextLayer = m_nodes[cLayer+1]; + for ( unsigned cNextLayer = 0; cNextLayer < nNextLayer; ++cNextLayer ){ + float *weight_ptr = m_wM[cLayer][cNextLayer]; + std::copy( weight_ptr , weight_ptr + nCurLayer, back_inserter(weights)); + } + float *bias_ptr = m_bM[cLayer]; + std::copy(bias_ptr, bias_ptr + nNextLayer, back_inserter(bias)); + } +} + + +// ============================================================================= +void NNFeedForward::print(MSG::Level lvl) const +{ + if ( !this->isStreamAvailable() ) { + std::cerr << "Cannot print " << this->name() << ", stream unavailable" + << std::endl; + } + if ( this->level() > lvl ) { + return; + } + std::vector<float> weights, bias; + getWeigthsAndBias(weights, bias); + msg() << lvl << "Nodes: " << m_nodes << endreq; + msg() << static_cast<MSG::Level>((lvl>MSG::VERBOSE)?(lvl-1):(lvl)) + << "Vectorized Weights: " << weights << endreq; + msg() << static_cast<MSG::Level>((lvl>MSG::VERBOSE)?(lvl-1):(lvl)) + << "Vectorized Bias: " << bias << endreq; +} + +// ============================================================================= +void NNFeedForward::read(NNFeedForward *newObj, + TDirectory *configDir, + unsigned /*version*/ ) +{ + std::vector<unsigned int> nodes; + std::vector<float> weights, bias; + IOHelperFcns::readVar(configDir, "nodes", nodes); + IOHelperFcns::readVar(configDir, "weights", weights); + IOHelperFcns::readVar(configDir, "bias", bias); + newObj->changeArchiteture(nodes,weights,bias); +} + +// ============================================================================= +void NNFeedForward::write(TDirectory *configDir, const char *) const +{ + if ( m_nLayers && m_wM && m_bM ){ + std::vector<float> weights, bias; + getWeigthsAndBias(weights, bias); + IOHelperFcns::writeVar(configDir, "nodes", m_nodes ); + IOHelperFcns::writeVar(configDir, "weights", weights ); + IOHelperFcns::writeVar(configDir, "bias", bias ); + } else { + std::runtime_error(std::string("Cannot write configuration from empty" + " (or with pointers not allocated) neural network.")); + } +} + +} // namespace Discrimination +} // namespace Ringer diff --git a/PhysicsAnalysis/RingerSelectorTools/Root/procedures/Normalizations.cxx b/PhysicsAnalysis/RingerSelectorTools/Root/procedures/Normalizations.cxx new file mode 100644 index 0000000000000000000000000000000000000000..264cffc03a4f9b035178edf79e22fc158cbfed18 --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/Root/procedures/Normalizations.cxx @@ -0,0 +1,293 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: Normalizations.cxx 667905 2015-05-18 19:07:55Z wsfreund $ +#include "RingerSelectorTools/procedures/Normalizations.icc" + +#include <algorithm> + +/** + * @brief Namespace dedicated for Ringer utilities + **/ +namespace Ringer +{ + +/** +* @brief Namespace dedicated for Ringer pre-processing utilities +**/ +namespace PreProcessing +{ + +/** + * @brief Namespace dedicated for Ringer normalization utilities + **/ +namespace Norm { + +/** + * @brief Helper functions: + **/ +namespace { +// ============================================================================= +inline +void applySequentialNorm( std::vector<float> &inputSpace, + const float norm, + const float stopEnergy ) +{ + bool fixed = false; + float curNorm = norm; + for ( std::vector<float>::iterator itr = inputSpace.begin(); + itr != inputSpace.end(); + ++itr){ + if ( curNorm < stopEnergy ){ + fixed = true; + } + if ( fixed ) { // Do not increase noise description: + curNorm = norm; + } else { + *itr /= curNorm; + curNorm -= *itr; + } + } + + if (!norm) return; + + float invNorm = 1/norm; + for ( std::vector<float>::iterator itr = inputSpace.begin(); + itr != inputSpace.end(); + ++itr){ + *itr *= invNorm; + } +} + +// ============================================================================= +struct minus { + float operator()(float in) { + return -in; + } +}; + + +// ============================================================================= +struct invert { + float operator()(float in) { + if(in){ + return 1/in; + } else { + throw std::runtime_error("Attempt to invert zero"); + } + } +}; + +} // Private namespace + +// ============================================================================= +void ConstantValue::print(MSG::Level lvl) const +{ + if ( !this->isStreamAvailable() ) { + std::cerr << "Cannot print " << this->name() << ", stream unavailable" + << std::endl; + } + if ( this->level() > lvl ) { + return; + } + msg() << lvl << "Constant normalization: " << 1/m_constantInv << endreq; +} + +// ============================================================================= +void ConstantValue::read(ConstantValue *newObj, + TDirectory *configDir, + unsigned /*version*/ ) +{ + IOHelperFcns::readVar(configDir, "constantInv", newObj->m_constantInv); +} + +// ============================================================================= +void ConstantValue::write(TDirectory *configDir, const char *) const +{ + IOHelperFcns::writeVar(configDir, "constantInv", m_constantInv ); +} + +// ============================================================================= +void Sequential::print(MSG::Level lvl) const +{ + if ( !this->isStreamAvailable() ) { + std::cerr << "Cannot print " << this->name() << ", stream unavailable" + << std::endl; + } + if ( this->level() > lvl ) { + return; + } + msg() << lvl << "stopEnergy: " << m_stopEnergy << endreq; + msg() << lvl << "energyThres: " << m_energyThres << endreq; +} + +// ============================================================================= +void Sequential::read(Sequential *newObj, + TDirectory *configDir, + unsigned /*version*/ ) +{ + IOHelperFcns::readVar(configDir, "stopEnergy", newObj->m_stopEnergy); + IOHelperFcns::readVar(configDir, "energyThres", newObj->m_energyThres); +} + +// ============================================================================= +void Sequential::write(TDirectory *configDir, const char *) const +{ + IOHelperFcns::writeVar(configDir, "stopEnergy", m_stopEnergy ); + IOHelperFcns::writeVar(configDir, "energyThres", m_energyThres ); +} + +// ============================================================================= +void Sequential::execute(std::vector<float> &inputSpace) const { +#ifndef NDEBUG + ATH_MSG_DEBUG("Applying sequential. Input space is: " << inputSpace); +#endif + float norm1 = getNorm(inputSpace,1); + if ( norm1 < m_stopEnergy ) { + float max = getMax(inputSpace); + // If normalization value is very low, do not normalize: + if ( norm1 < m_energyThres || max < m_energyThres ) return; + // Otherwise normalize with the greater norm value: + if ( norm1 < max ){ + applyNorm(inputSpace,max); + } else { + applyNorm(inputSpace,norm1); + } + } else { + // Otherwise use sequential normalization: + applySequentialNorm( inputSpace, norm1, m_stopEnergy ); + } +#ifndef NDEBUG + ATH_MSG_DEBUG("Pattern space is: " << inputSpace); +#endif +} + +// ============================================================================= +void Spherization::print(MSG::Level lvl) const +{ + if ( !this->isStreamAvailable() ) { + std::cerr << "Cannot print " << this->name() << ", stream unavailable" + << std::endl; + } + if ( this->level() > lvl ) { + return; + } + msg() << lvl << "deslocation: " << m_deslocation << endreq; + msg() << lvl << "normInv: " << m_normInv << endreq; +} + +// ============================================================================= +void Spherization::read(Spherization *newObj, + TDirectory *configDir, + unsigned /*version*/ ) +{ + IOHelperFcns::readVar(configDir, "deslocation", newObj->m_deslocation ); + IOHelperFcns::readVar(configDir, "normInv", newObj->m_normInv ); + newObj->m_dim = newObj->m_deslocation.size(); +} + +// ============================================================================= +void Spherization::write(TDirectory *configDir, const char *) const +{ + IOHelperFcns::writeVar(configDir, "deslocation", m_deslocation ); + IOHelperFcns::writeVar(configDir, "normInv", m_normInv ); +} + +// ============================================================================= +Spherization::Spherization( + const std::vector<float> &dataMean, + const std::vector<float> &dataStd) + : m_dim(dataMean.size()) +{ + if ( dataMean.empty() || dataStd.empty() ){ + throw std::runtime_error(std::string("Either DataMean or DataStd " + "vectors have no dimension.") ); + } + if ( dataMean.size() != dataStd.size() ){ + throw std::runtime_error(std::string("DataMean and DataStd vectors do " + "no have same dimension.")); + } + m_deslocation.resize(m_dim); + m_normInv.resize(m_dim); + try { + std::transform( dataMean.begin(), + dataMean.end(), + m_deslocation.begin(), + minus() ); + + std::transform( dataStd.begin(), + dataStd.end(), + m_normInv.begin(), + invert() ); + } catch ( const std::runtime_error & ){ + throw std::runtime_error(std::string("Attempted to create Spherization " + "with null standard deviation")); + } +} + + +// ============================================================================= +void MinMax::print(MSG::Level lvl) const +{ + if ( !this->isStreamAvailable() ) { + std::cerr << "Cannot print " << this->name() << ", stream unavailable" + << std::endl; + } + if ( this->level() > lvl ) { + return; + } + msg() << lvl << "deslocation: " << m_deslocation << endreq; + msg() << lvl << "normInv: " << m_normInv << endreq; +} + +// ============================================================================= +void MinMax::read(MinMax *newObj, + TDirectory *configDir, + unsigned /*version*/ ) +{ + IOHelperFcns::readVar(configDir, "deslocation", newObj->m_deslocation ); + IOHelperFcns::readVar(configDir, "normInv", newObj->m_normInv ); + newObj->m_dim = newObj->m_deslocation.size(); +} + +// ============================================================================= +void MinMax::write(TDirectory *configDir, const char* ) const +{ + IOHelperFcns::writeVar(configDir, "deslocation", m_deslocation ); + IOHelperFcns::writeVar(configDir, "normInv", m_normInv ); +} + +// ============================================================================= +MinMax::MinMax( + const std::vector<float> min, + const std::vector<float> max) + : m_dim(min.size()) +{ + if ( min.empty() || max.empty() ){ + throw std::runtime_error(std::string("Either Min or max vectors have no " + "dimension.")); + } + if ( min.size() != max.size() ){ + throw std::runtime_error(std::string("Min and max vectors do no have same " + "dimension.")); + } + + m_deslocation.reserve(m_dim); + m_normInv.reserve(m_dim); + + for (size_t idx = 0; idx < m_dim; ++idx ) { + m_deslocation.push_back(-((max[idx]+min[idx])/2)); + m_normInv.push_back(2/(max[idx]-min[idx])); + if (!m_normInv[idx]) { + throw std::runtime_error( + std::string("MinMax should have different minimum and maximum " + "values.")); + } + } +} + +} // namespace Norm +} // namespace PreProcessing +} // namespace Ringer + diff --git a/PhysicsAnalysis/RingerSelectorTools/Root/procedures/RingerDiscriminatorWrapper.cxx b/PhysicsAnalysis/RingerSelectorTools/Root/procedures/RingerDiscriminatorWrapper.cxx new file mode 100644 index 0000000000000000000000000000000000000000..ad3d14b9090f2b8c798c4cd5b9f7e03a67d399ca --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/Root/procedures/RingerDiscriminatorWrapper.cxx @@ -0,0 +1,134 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: RingerDiscriminatorWrapper.cxx 670599 2015-05-28 14:15:35Z wsfreund $ +#include "RingerSelectorTools/procedures/RingerDiscriminatorWrapper.h" + +namespace Ringer { +#if !(RINGER_USE_NEW_CPP_FEATURES) +const char* IDiscrWrapper::wrapName = "RingerDiscriminatorWrapper"; +#else +constexpr const char* IDiscrWrapper::wrapName; +#endif + +// ============================================================================= +void IDiscrWrapper::writeCol(const IDiscrWrapperCollection &discrWrapperCol, + const char *fileName) +{ + TFile wrapperFile(fileName, "UPDATE"); + IOHelperFcns::checkFile( wrapperFile ); + + TDirectory* configDir = wrapperFile.GetDirectory(""); + + // Add package version to directory + IOHelperFcns::writeVersion(configDir); + + // Write discrimination wrappers: + unsigned discrWrapperSize = discrWrapperCol.size(); + IOHelperFcns::writeVar( configDir, "discrWrapperSize", discrWrapperSize ); + for (size_t discrIdx = 0; discrIdx < discrWrapperSize; ++discrIdx ) { + // Write wrapper on the file: + discrWrapperCol[discrIdx]->write(configDir, + IOHelperFcns::makeIdxStr(discrIdx).c_str()); + } + + // Write and close file + wrapperFile.Write(); + wrapperFile.Close(); +} + +// ============================================================================= +void IDiscrWrapper::read(IDiscrWrapperCollection &discrWrapperCol, + const char* fileName) +{ + // Try to open file and check if nothing wrong happened: + TFile wrapperFile(fileName, "READ"); + IOHelperFcns::checkFile( wrapperFile ); + TDirectory* configDir = wrapperFile.GetDirectory(""); + + // Get written version: + unsigned version = IOHelperFcns::getWrittenVersion( configDir ); + + // Get its size: + unsigned discrWrapperSize(0); + IOHelperFcns::readVar( configDir, "discrWrapperSize", discrWrapperSize ); + + // Cycle through discrimination collection and fill it: + for ( unsigned counter = 0; counter < discrWrapperSize; ++counter) { + std::string folderName = IDiscrWrapper::wrapName + + IOHelperFcns::makeIdxStr(counter); + + //ATH_MSG_DEBUG("Reading Discriminatior Wrapper on folder \"" + // << folderName << "\"" ); + TDirectory *discrDir = configDir->GetDirectory(folderName.c_str()); + if ( discrDir == nullptr || discrDir == configDir ) + { + throw std::runtime_error(std::string("Could not find directory \"") + + folderName + "\" containing Discriminatior Wrapper" + "information."); + } + // Get basic preprocessing wrapper information: + discrEnum_t discrType; + EtaDependency fileEtaDep; + EtDependency fileEtDep; + SegmentationType fileSegType; + IOHelperFcns::readVar<discrEnum_t, unsigned int>( discrDir, + "discrType", + discrType); + IOHelperFcns::readVar<SegmentationType, unsigned int>( discrDir, + "segType", + fileSegType); + IOHelperFcns::readVar<EtaDependency, unsigned int>( discrDir, + "etaDependency", + fileEtaDep); + IOHelperFcns::readVar<EtDependency, unsigned int>( discrDir, + "etDependency", + fileEtDep); + //ATH_MSG_DEBUG("It's type is " << toStr(discrType) << " and dependency is :[" + // << toStr(fileSegType) << "," + // << toStr(fileEtaDep) << "," + // << toStr(fileEtDep) << "]"); + // Create wrapper and append it to collection. Here we make some checks + // whether the wrapper preprocessing type is not IDiscriminatorVarDep. + // For some cases, we have some template specializations. + switch ( discrType ) + { + case Discrimination::Type::NNFeedForward: + { + // We create discrimination wrapper specialized for each segmentation + // type for the NeuralNetwork, which is one discriminator that we shall + // use frequently. + READ_ALL_DEP_WRAPPER(discrWrapperCol, + Discrimination::NNFeedForwardVarDep, + fileSegType, + fileEtaDep, + fileEtDep, + discrDir, + version) + break; + } + default: + { + //ATH_MSG_DEBUG("Using interface for Discriminatior Wrapper on folder \"" + // << folderName << "\" and type \"" << discrType.Data() "\"" ); + /* + * In this case, there is no dedicated wrapper for the collection, + * we use the interface then: + */ + READ_ALL_DEP_WRAPPER(discrWrapperCol, + Discrimination::IDiscriminatorVarDep, + fileSegType, + fileEtaDep, + fileEtDep, + discrDir, + version) + } + } + } + + // We already got all the information on the file, we can close it: + wrapperFile.Close(); +} + +} // namespace Ringer diff --git a/PhysicsAnalysis/RingerSelectorTools/Root/procedures/RingerPreProcessorWrapper.cxx b/PhysicsAnalysis/RingerSelectorTools/Root/procedures/RingerPreProcessorWrapper.cxx new file mode 100644 index 0000000000000000000000000000000000000000..2927f974e73888dd50ba55168c3afe5258aebe9a --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/Root/procedures/RingerPreProcessorWrapper.cxx @@ -0,0 +1,135 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: RingerPreProcessorWrapper.cxx 670599 2015-05-28 14:15:35Z wsfreund $ +#include "RingerSelectorTools/procedures/RingerPreProcessorWrapper.h" + +namespace Ringer { +#if !(RINGER_USE_NEW_CPP_FEATURES) +const char* IPreProcWrapper::wrapName = "RingerPreProcessorWrapper"; +#else +constexpr const char* IPreProcWrapper::wrapName; +#endif + +// ============================================================================= +void IPreProcWrapper::writeCol(const IPreProcWrapperCollection &ppWrapperCol, + TDirectory *configDir) +{ + bool hasPP = !( ppWrapperCol.empty() ); + IOHelperFcns::writeVar( configDir, "hasPP", hasPP ); + // Write pre-processing wrappers: + if (hasPP){ + // Write pre-processing + unsigned ppWrapperSize = ppWrapperCol.size(); + IOHelperFcns::writeVar( configDir, "ppWrapperSize", ppWrapperSize ); + for (size_t ppIdx = 0; ppIdx < ppWrapperSize; ++ppIdx ) { + ppWrapperCol[ppIdx]->write(configDir, + IOHelperFcns::makeIdxStr(ppIdx).c_str()); + } + } +} + +// ============================================================================= +void IPreProcWrapper::read(IPreProcWrapperCollection &ppWrapperCol, + TDirectory *configDir, + unsigned version) +{ + + // Get its size: + unsigned ppWrapperSize(0); + IOHelperFcns::readVar( configDir, "ppWrapperSize", ppWrapperSize ); + + // Cycle through pp collection and fill it: + for ( unsigned counter = 0; counter < ppWrapperSize; ++counter) { + std::string folderName = IPreProcWrapper::wrapName + + IOHelperFcns::makeIdxStr(counter); + + //ATH_MSG_DEBUG("Reading PreProcessing Wrapper on folder \"" + // << folderName << "\"" ); + TDirectory *ppDir = configDir->GetDirectory(folderName.c_str()); + if ( ppDir == nullptr || ppDir == configDir ) + { + throw std::runtime_error(std::string("Could not find directory \"") + + folderName + "\" containing PreProcessing Wrapper" + "information."); + } + // Get basic preprocessing wrapper information: + preProcEnum_t ppType; + EtaDependency fileEtaDep; + EtDependency fileEtDep; + SegmentationType fileSegType; + IOHelperFcns::readVar<preProcEnum_t, unsigned int>( ppDir, + "ppType", + ppType); + IOHelperFcns::readVar<SegmentationType, unsigned int>( ppDir, + "segType", + fileSegType); + IOHelperFcns::readVar<EtaDependency, unsigned int>( ppDir, + "etaDependency", + fileEtaDep); + IOHelperFcns::readVar<EtDependency, unsigned int>( ppDir, + "etDependency", + fileEtDep); + //ATH_MSG_DEBUG("It's type is " << toStr(ppType) << " and dependency is :[" + // << toStr(fileSegType) << "," + // << toStr(fileEtaDep) << "," + // << toStr(fileEtDep) << "]"); + // Create wrapper and append it to collection. Here we make some checks + // whether the wrapper preprocessing type is not IDiscriminatorVarDep. + // For some cases, we have some template specializations. + switch ( ppType ) + { + case PreProcessing::Type::Norm1: + { + if (fileEtaDep || fileEtDep) { + throw std::runtime_error(std::string("Cannot have Norm1 Preprocessor " + "Wrapper eta/et depedent")); + } + // We create pre-processing wrapper specialized for each segmentation + // type for the norm1, which is one normalization that we shall use + // frequently. On the other hand, as it hasn't parameters, it makes + // no sense for it to be variable dependent: + READ_SEG_DEP_WRAPPER(ppWrapperCol, + PreProcessing::Norm::Norm1VarDep, + fileSegType, + EtaIndependent, + EtIndependent, + ppDir, + version) + break; + } + //case PreProcessing::Norm::Type::Spherization: + //{ + // // We might want to uncomment this if we want to use spherization + // // as a normalization procedure: + // + // READ_ALL_DEP_WRAPPER(ppWrapperCol, + // PreProcessing::Norm::SpherizationVarDep, + // fileSegType, + // fileEtaDep, + // fileEtDep, + // ppDir, + // version) + //} + default: + { + //ATH_MSG_DEBUG("Using interface for PreProcessing Wrapper on folder \"" + // << folderName << "\" and type \"" << ppType.Data() "\"" ); + /* + * In this case, there is no dedicated wrapper for the collection, + * we use the interface then: + */ + READ_ALL_DEP_WRAPPER(ppWrapperCol, + PreProcessing::IPreProcessorVarDep, + fileSegType, + fileEtaDep, + fileEtDep, + ppDir, + version) + } + } + } +} + +} // namespace Ringer diff --git a/PhysicsAnalysis/RingerSelectorTools/Root/procedures/RingerThresholdWrapper.cxx b/PhysicsAnalysis/RingerSelectorTools/Root/procedures/RingerThresholdWrapper.cxx new file mode 100644 index 0000000000000000000000000000000000000000..a95d089eb64e595d71241a8b09c2221a650bbb13 --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/Root/procedures/RingerThresholdWrapper.cxx @@ -0,0 +1,121 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: RingerThresholdWrapper.cxx 670599 2015-05-28 14:15:35Z wsfreund $ +#include "RingerSelectorTools/procedures/RingerThresholdWrapper.h" + +namespace Ringer { +#if !(RINGER_USE_NEW_CPP_FEATURES) +const char* IThresWrapper::wrapName = "RingerThresholdWrapper"; +#else +constexpr const char* IThresWrapper::wrapName; +#endif + +// ============================================================================= +void IThresWrapper::writeWrapper(const IThresWrapper *thresWrapper, + const char *fileName) +{ + TFile wrapperFile(fileName, "UPDATE"); + IOHelperFcns::checkFile( wrapperFile ); + TDirectory* configDir = wrapperFile.GetDirectory(""); + + // Add package version to directory + IOHelperFcns::writeVersion(configDir); + + // Write threshold wrapper-processing wrappers: + thresWrapper->write(configDir, IOHelperFcns::makeIdxStr(0).c_str()); + + // Write and close file + wrapperFile.Write(); + wrapperFile.Close(); +} + +// ============================================================================= +void IThresWrapper::read(IThresWrapper *&thresWrapper, + const char* fileName) +{ + // Try to open file and check if nothing wrong happened: + TFile wrapperFile(fileName, "READ"); + IOHelperFcns::checkFile( wrapperFile ); + TDirectory* configDir = wrapperFile.GetDirectory(""); + + // Get written version: + unsigned version = IOHelperFcns::getWrittenVersion( configDir ); + + std::string folderName = IThresWrapper::wrapName + + IOHelperFcns::makeIdxStr(0); + + //ATH_MSG_DEBUG("Reading Discriminatior Wrapper on folder \"" + // << folderName << "\"" ); + TDirectory *thresDir = configDir->GetDirectory(folderName.c_str()); + if ( thresDir == nullptr || thresDir == configDir ) + { + throw std::runtime_error(std::string("Could not find directory \"") + + folderName + "\" containing Discriminatior Wrapper" + "information."); + } + + // We create a dummy collection just to use it on the macro + IThresWrapperCollection thresWrapperCol; + + // Get basic preprocessing wrapper information: + thresEnum_t thresType; + EtaDependency fileEtaDep; + EtDependency fileEtDep; + IOHelperFcns::readVar<thresEnum_t, unsigned int>( thresDir, + "thresType", + thresType); + IOHelperFcns::readVar<EtaDependency, unsigned int>( thresDir, + "etaDependency", + fileEtaDep); + IOHelperFcns::readVar<EtDependency, unsigned int>( thresDir, + "etDependency", + fileEtDep); + //ATH_MSG_DEBUG("It's type is " << toStr(thresType) << " and dependency is :[" + // << toStr(fileEtaDep) << "," + // << toStr(fileEtDep) << "]"); + // Create wrapper. Here we make some checks whether the wrapper preprocessing + // type is not IThresholdVarDep. For some cases, we have some template + // specializations. + switch ( thresType ) + { + case Discrimination::Type::UniqueThreshold: + { + // We create a specialized unique threshold for the UniqueThreshold + // configuration: + READ_ETA_ET_DEP_WRAPPER(thresWrapperCol, + Discrimination::UniqueThresholdVarDep, + NoSegmentation, + fileEtaDep, + fileEtDep, + thresDir, + version) + break; + } + default: + { + //ATH_MSG_DEBUG("Using interface for Discriminatior Wrapper on folder \"" + // << folderName << "\" and type \"" << thresType.Data() "\"" ); + /* + * In this case, there is no dedicated wrapper for the collection, + * we use the interface then: + */ + READ_ETA_ET_DEP_WRAPPER(thresWrapperCol, + Discrimination::IThresholdVarDep, + NoSegmentation, + fileEtaDep, + fileEtDep, + thresDir, + version) + } + } + + // Set pointer to memory address from the read thres wrapper. + thresWrapper = thresWrapperCol[0]; + + // We already got all the information on the file, we can close it: + wrapperFile.Close(); +} + +} // namespace Ringer diff --git a/PhysicsAnalysis/RingerSelectorTools/Root/procedures/Thresholds.cxx b/PhysicsAnalysis/RingerSelectorTools/Root/procedures/Thresholds.cxx new file mode 100644 index 0000000000000000000000000000000000000000..4ed06b408cfdfa24e303bb08a4a9fc594cdd404b --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/Root/procedures/Thresholds.cxx @@ -0,0 +1,41 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: Thresholds.cxx 667905 2015-05-18 19:07:55Z wsfreund $ +#include "RingerSelectorTools/procedures/Thresholds.icc" + +namespace Ringer { + +namespace Discrimination { + +// ============================================================================= +void UniqueThreshold::print(MSG::Level lvl) const +{ + if ( !this->isStreamAvailable() ) { + std::cerr << "Cannot print " << this->name() << ", stream unavailable" + << std::endl; + } + if ( this->level() > lvl ) { + return; + } + msg() << lvl << "Threshold: " << m_threshold << endreq; +} + +// ============================================================================= +void UniqueThreshold::read(UniqueThreshold *newObj, + TDirectory *configDir, + unsigned /*version*/ ) +{ + IOHelperFcns::readVar(configDir, "threshold", newObj->m_threshold); +} + +// ============================================================================= +void UniqueThreshold::write(TDirectory *configDir, const char *) const +{ + IOHelperFcns::writeVar(configDir, "threshold", m_threshold ); +} + +} // namespace Discrimination + +} // namespace Ringer diff --git a/PhysicsAnalysis/RingerSelectorTools/Root/procedures/Types.cxx b/PhysicsAnalysis/RingerSelectorTools/Root/procedures/Types.cxx new file mode 100644 index 0000000000000000000000000000000000000000..2672bbe8f1f9a25a85c40b411bdac7cd43293a1d --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/Root/procedures/Types.cxx @@ -0,0 +1,147 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: Types.cxx 667905 2015-05-18 19:07:55Z wsfreund $ +#include "RingerSelectorTools/procedures/Types.h" + +#include "RingerSelectorTools/procedures/Normalizations.h" +#include "RingerSelectorTools/procedures/NeuralNetwork.h" +#include "RingerSelectorTools/procedures/Thresholds.h" + +#include "RingerSelectorTools/tools/Exceptions.h" + +namespace Ringer { + +// ============================================================================= +template<> +preProcEnum_t getType(const char* cStr){ + using namespace PreProcessing; + std::string strType(cStr); + if ( strType == IPreProcessorVarDep::procType() ){ + return preProcEnum_t::IPreProcessorVarDep; + } else if ( strType == Norm::Norm1::procType() ){ + return preProcEnum_t::Norm1; + } else if ( strType == Norm::Norm2::procType() ){ + return preProcEnum_t::Norm2; + } else if ( strType == Norm::Sqrt::procType() ){ + return preProcEnum_t::Sqrt; + } else if ( strType == Norm::ConstantValue::procType() ){ + return preProcEnum_t::ConstantValue; + } else if ( strType == Norm::Sequential::procType() ){ + return preProcEnum_t::Sequential; + } else if ( strType == Norm::Spherization::procType() ){ + return preProcEnum_t::Spherization; + } else if ( strType == Norm::MinMax::procType() ){ + return preProcEnum_t::MinMax; + } else if ( strType == IPreProcessor::procType() ){ + return preProcEnum_t::IPreProcessor; + } else { + throw Exceptions::no_such_type("PreProcessorType",strType,"Types"); + } +} + +// ============================================================================= +template<> +discrEnum_t getType(const char* cStr){ + using namespace Discrimination; + std::string strType(cStr); + if ( strType == IDiscriminatorVarDep::procType() ){ + return discrEnum_t::IDiscriminatorVarDep; + } else if ( strType == NNFeedForward::procType() ){ + return discrEnum_t::NNFeedForward; + } else if ( strType == IDiscriminator::procType() ){ + return discrEnum_t::IDiscriminator; + } else { + throw Exceptions::no_such_type("DiscriminatorType",strType,"Types"); + } +} + +// ============================================================================= +template<> +thresEnum_t getType(const char* cStr){ + using namespace Discrimination; + std::string strType(cStr); + if ( strType == IThresholdVarDep::procType() ){ + return thresEnum_t::IThresholdVarDep; + } else if ( strType == UniqueThreshold::procType() ){ + return thresEnum_t::UniqueThreshold; + } else if ( strType == IDiscriminator::procType() ){ + return thresEnum_t::IThreshold; + } else { + throw Exceptions::no_such_type("ThresholdType",strType,"Types"); + } +} +// ============================================================================= +const char* toStr(preProcEnum_t e){ + using namespace PreProcessing; + switch (e){ + case preProcEnum_t::IPreProcessorVarDep: + return IPreProcessorVarDep::procType(); + break; + case preProcEnum_t::Norm1: + return Norm::Norm1::procType(); + break; + case preProcEnum_t::Norm2: + return Norm::Norm2::procType(); + break; + case preProcEnum_t::Sqrt: + return Norm::Sqrt::procType(); + break; + case preProcEnum_t::ConstantValue: + return Norm::ConstantValue::procType(); + break; + case preProcEnum_t::Sequential: + return Norm::Sequential::procType(); + break; + case preProcEnum_t::Spherization: + return Norm::Spherization::procType(); + break; + case preProcEnum_t::MinMax: + return Norm::MinMax::procType(); + break; + case preProcEnum_t::IPreProcessor: + return IPreProcessor::procType(); + break; + default: + throw Exceptions::no_such_type(e,"Types"); + } +} + +// ============================================================================= +const char* toStr(discrEnum_t e){ + using namespace Discrimination; + switch (e){ + case discrEnum_t::IDiscriminatorVarDep: + return IDiscriminatorVarDep::procType(); + break; + case discrEnum_t::NNFeedForward: + return NNFeedForward::procType(); + break; + case discrEnum_t::IDiscriminator: + return IDiscriminator::procType(); + break; + default: + throw Exceptions::no_such_type(e,"Types"); + } +} + +// ============================================================================= +const char* toStr(thresEnum_t t){ + using namespace Discrimination; + switch (t){ + case thresEnum_t::IThresholdVarDep: + return IThresholdVarDep::procType(); + break; + case thresEnum_t::UniqueThreshold: + return UniqueThreshold::procType(); + break; + case thresEnum_t::IThreshold: + return IThreshold::procType(); + break; + default: + throw Exceptions::no_such_type(t,"Types"); + } +} + +} // namespace Ringer diff --git a/PhysicsAnalysis/RingerSelectorTools/Root/tools/IOHelperFcns.cxx b/PhysicsAnalysis/RingerSelectorTools/Root/tools/IOHelperFcns.cxx new file mode 100644 index 0000000000000000000000000000000000000000..b7afffee288ea5987d3aad8b3d1f19c492f79b30 --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/Root/tools/IOHelperFcns.cxx @@ -0,0 +1,246 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: IOHelperFcns.cxx 693573 2015-09-07 19:15:49Z wsfreund $ +#include "RingerSelectorTools/tools/IOHelperFcns.icc" + +// STL includes: +#include <stdexcept> +#include <string> +#include <sstream> +#include <algorithm> +#include <functional> +#include <locale> +#include <memory> + +// ROOT includes: +#include <TClass.h> +#include <TSystem.h> + +namespace Ringer { namespace IOHelperFcns { + +namespace { + +// ============================================================================= +/** + * @brief Fctor for checking if string is digit or comma + **/ +//struct is_digit_or_comma { +// bool operator ()(int c){ +// if ( std::isdigit(c) || c != ',' ){ +// return true; +// } else { +// return false; +// } +// } +//}; + +// ============================================================================= +/** + * @brief Filter index string from + **/ +std::string& filterIdxStr(std::string &str) +{ + std::string oldStr = str; + // Check if string is in correct format: + bool isCorrectFormat = true; + std::stringstream ss(str); + // We want to discard everything until @ + std::getline ( ss, str, '@' ); + std::getline ( ss, str, '@' ); + if ( str.empty() || str.front() != '(' || str.back() != ')'){ + isCorrectFormat = false; + } + // Strip first and last charater + str = str.substr(1, str.size()-2 ); + if ( str.find_first_not_of( "0123456789," ) != std::string::npos ){ + isCorrectFormat = false; + } + if ( !isCorrectFormat ){ + throw std::runtime_error(std::string("Could not extract index string " + "from ") + oldStr ); + } + // Ok, it is on correct format: + return str; +} +} //private namespace + +// ============================================================================= +std::string makeIdxStr(unsigned int idxV) +{ + std::stringstream ss; + ss << "@(" << idxV << ")"; + return ss.str(); +} + +// ============================================================================= +std::string makeIdxStr(std::vector<unsigned int> &idxV) +{ + std::stringstream ss; + ss << "@("; + for ( size_t count = 0; count < idxV.size(); ++count ){ + ss << idxV[count]; + if ( count + 1 < idxV.size() ) { + ss << ","; + } + } + ss << ")"; + return ss.str(); +} + +// ============================================================================= +void getIdxVecFromStr(const char* cstr, std::vector<unsigned int> &vec) +{ + // Clear vector so that we can fill it with idx array + vec.clear(); + // Retrieve idxStr from cstr and prepare to loop over indexes + std::string str(cstr); + std::stringstream ss(filterIdxStr(str)); + // Fill vector + while ( ss.good() ) { + std::getline(ss,str,','); + vec.push_back(std::stoul(str)); + } +} + +// ============================================================================= +unsigned int getIdxFromStr(const char* cstr, unsigned int n) +{ + std::string str(cstr); + std::stringstream ss(filterIdxStr(str)); + // Ignore any number until we get into our requested index: + for ( size_t counter = 0; counter < n ; ++counter ){ + std::getline(ss,str,','); + } + return std::stoul(str); +} + +// ============================================================================= +bool startsWith(const char *cStrStart, const char *cStr) +{ + std::string strStart(cStrStart); + std::string str(cStr); + if(str.substr(0, strStart.size()) == strStart) { + return true; + } + return false; +} + +// ============================================================================= +unsigned version() +{ + +#ifndef PACKAGE_VERSION +# error "PACKAGE_VERSION macro is undefined." +#endif + + std::string versionStr = PACKAGE_VERSION; + + versionStr.erase(std::remove_if( versionStr.begin(), + versionStr.end(), + std::not1( std::ptr_fun<int,int>( std::isdigit ) ) ), + versionStr.end()); + + return std::stoul(versionStr); +} + +// ============================================================================= +void checkFile(const TFile& file){ + if (file.IsZombie()){ + throw std::runtime_error(std::string("TFile \"") + + file.GetName() + "\"is not in good status"); + } +} + +// ============================================================================= +bool fileExist(const char* fileName) { + Int_t prevMessageLevel = gErrorIgnoreLevel; + gErrorIgnoreLevel = kBreak; + TFile file(fileName); + gErrorIgnoreLevel = prevMessageLevel; + try { + file.IsZombie(); + return true; + } catch (const std::runtime_error &e){ + return false; + } +} + +// ============================================================================= +int deleteFile(const char* fileName) +{ + if (fileExist(fileName)){ + return gSystem->Exec((std::string("rm ") + fileName).c_str() ); + } else { + return -1; + } +} + +// ============================================================================= +void checkDir(TDirectory *dir) +{ + if (dir == nullptr) + { + throw std::runtime_error(std::string("TDirectory points to void.")); + } +} + +// ============================================================================= +void writeVersion(TDirectory* dir) +{ + // Add package version in which we have written this configurable + unsigned v = version(); + IOHelperFcns::writeVar(dir, "writtenOnPkgVersion", v ); +} + +// ============================================================================= +TDirectory *makeDir(TDirectory* baseDir, const char *name) +{ + checkDir(baseDir); + TDirectory* newDir = baseDir->mkdir(name); + try { + checkDir(newDir); + } catch ( std::runtime_error & ) { + throw std::runtime_error(std::string("Could not create a directory " + "on directory named ") + baseDir->GetName() ); + } + writeVersion(newDir); + return newDir; +} + +// ============================================================================= +std::shared_ptr<THashList> getDirList(TDirectory* dir) +{ + checkDir(dir); + THashList* list = static_cast<THashList*>(dir->GetList()); + if ( list->IsEmpty() ) { + return nullptr; + } + // Create new list + std::shared_ptr<THashList> dirList( + new THashList( dir->GetListOfKeys()->GetSize() ) ); + // Push only directories to list: + TIter iter(list); + while ( TDirectory *dir = static_cast<TDirectory*>(iter()) ){ + //if ( dir->IsA() == TDirectoryFile::Class() ) {} + if ( dir->InheritsFrom(TDirectory::Class()) ) { + dirList->Add(dir); + } + } + return dirList; +} + +// ============================================================================= +unsigned getWrittenVersion(TDirectory *configDir) +{ + unsigned writtenVersion(0); + readVar(configDir, "writtenOnPkgVersion", writtenVersion); + return writtenVersion; +} + +} // namespace IOHelperFcns + +} // namespace Ringer + + diff --git a/PhysicsAnalysis/RingerSelectorTools/Root/tools/RingerCommonSelector.cxx b/PhysicsAnalysis/RingerSelectorTools/Root/tools/RingerCommonSelector.cxx new file mode 100644 index 0000000000000000000000000000000000000000..35bdb69fc6d9674b3f4991b051f9308cebab5966 --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/Root/tools/RingerCommonSelector.cxx @@ -0,0 +1,209 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: RingerCommonSelector.cxx 668868 2015-05-20 20:26:18Z wsfreund $ +#ifndef RINGER_STANDALONE + +//#undef NDEBUG + +// Local includes: +#include "RingerSelectorTools/ElectronTAccept.h" +#include "RingerSelectorTools/tools/RingerCommonSelector.h" +#include "RingerSelectorTools/tools/VariableDependency.h" +#include "RingerSelectorTools/procedures/RingerProcedureWrapper.icc" + +// STL includes: +#include <vector> + +// xAOD includes: +#include "xAODCaloRings/CaloRings.h" +#include "xAODTracking/TrackParticle.h" + +namespace Ringer { + +//============================================================================== +RingerCommonSelector::RingerCommonSelector( + const Ringer::IDiscrWrapperCollection *discrWrapperCol, + const Ringer::IThresWrapper *thresWrapper, + Root::TAccept *partDecMsk, + const bool useTrackPat, + const bool useRawTrackPat, + const bool useCaloCommittee) + : m_discrWrapperCol(discrWrapperCol), + m_thresWrapper(thresWrapper), + m_partDecMsk(partDecMsk), + m_useTrackPat(useTrackPat), + m_useRawTrackPat(useRawTrackPat), + m_useCaloCommittee(useCaloCommittee), + m_fstDiscrLayer(0), + m_lastDiscrLayer(0) +{ + if ( !m_discrWrapperCol ) { + throw std::runtime_error("Cannot create RingerCommonSelector" + "without discrimination wrapper collection."); + } + + if ( !m_thresWrapper ) { + throw std::runtime_error("Cannot create RingerCommonSelector" + "without threshold wrapper."); + } + + if ( !m_partDecMsk ) { + throw std::runtime_error("Cannot create RingerCommonSelector" + "without a decision mask."); + } + + m_discrWrapperColSize = discrWrapperCol->size(); + + m_fstDiscrLayer = (*m_discrWrapperCol)[0]; + m_lastDiscrLayer = (*m_discrWrapperCol)[ m_discrWrapperColSize - 1 ]; + + m_nonSegmentedDiscr = m_fstDiscrLayer->getSegType() == + SegmentationType::NoSegmentation; +} + +//============================================================================== +StatusCode RingerCommonSelector::execute( + const DepVarStruct &depVar, + const xAOD::CaloRings* clRings, + const TrackPatternsHolder* trackPat) +{ + ATH_MSG_DEBUG( "Starting executing RingerCommonSelector."); + + if ( !m_discrWrapperColSize ){ + ATH_MSG_ERROR("Cannot run with empty discrimination " + "wrapper collection."); + return StatusCode::FAILURE; + } + + if ( m_useTrackPat || m_useRawTrackPat ) { +#ifndef NDEBUG + ATH_MSG_DEBUG( "Using track information."); +#endif + if (!trackPat){ + ATH_MSG_ERROR("Requested to add track patterns, " + "but it isn't available."); + return StatusCode::FAILURE; + } + + // We now check if we want to add run discriminator specialized for track + // patterns: + const TrackPatternsHolder *localTrackPat = 0; + if ( !m_useRawTrackPat ) { + localTrackPat = trackPat; + } + + if ( m_useCaloCommittee && !m_useRawTrackPat && !m_nonSegmentedDiscr ) + { +#ifndef NDEBUG + ATH_MSG_DEBUG( "Using CaloCommite with nonSegmented discriminator."); +#endif + // If we are doing calorimeter committee and have a discriminator + // specialized for the track patterns, we need to distinguish the calorimeter + // output from the track discriminator output, thus we execute the + // discrimination layer two times, one for each type of input and get the + // output space representation within two vectors: + m_fstDiscrLayer->execute( depVar, + clRings, + nullptr, + m_output); + m_fstDiscrLayer->execute( depVar, + nullptr, + localTrackPat, + m_trackDiscr_output); + } else { +#ifndef NDEBUG + ATH_MSG_DEBUG( "Not using CaloCommitee or using without segmented " + "discriminator or using raw pattern."); +#endif + // Otherwise we simply propagate + m_fstDiscrLayer->execute( depVar, clRings, localTrackPat, m_output); + } + } else { +#ifndef NDEBUG + ATH_MSG_DEBUG( "Not using track information. Propagating first layer."); +#endif + // Do not input track patterns into discrimination layer: + m_fstDiscrLayer->execute( depVar, clRings, nullptr, m_output ); + } + + // Check if we have more than one discrimination layer: + if ( m_discrWrapperColSize > 1 ){ + + // If we are using raw track pattern and haven't a dedicated committee for + // the Calorimeter information, then we add the raw track pattern into the next + // classification layer input space: + if ( m_useRawTrackPat && !m_useCaloCommittee ) { + trackPat->exportPatternsTo(m_input); + } + + // Set input to be same as last layer output, so that we can continue + // applying our chain: + m_input = m_output; + + // If we have intermediary layers: + if ( m_discrWrapperColSize > 2 ){ + // We use the output from first discrimination layer to work with the + // sequential layers (except the last): + for (size_t discrIdx = 1; discrIdx < m_discrWrapperColSize - 1; + ++discrIdx ){ + + (*m_discrWrapperCol)[discrIdx]->execute( + depVar, + m_input, + m_output ); + // Set input to be same as last layer output, so that we can continue + // applying our chain: + m_input = m_output; + } + } + + // If we did calorimeter only committee, then we need to add track + // information to last discrimination layer: + if ( m_useCaloCommittee ) { + // We check if we want to add raw track information to the last + // discrimination layer input: + if ( m_useRawTrackPat ) { + trackPat->exportPatternsTo( m_input ); + } else { + // otherwise we need to add track discrimination output, executed by + // first layer into the last layer input space: + // Copy trackDiscr output to input space: + m_input.insert( m_input.end(), + m_trackDiscr_output.begin(), + m_trackDiscr_output.end()); + } + } + + // Apply our last discriminator + m_lastDiscrLayer->execute( + depVar, + m_input, + m_output); +#ifndef NDEBUG + ATH_MSG_DEBUG("Final output space is :" << m_output); +#endif + } + + // With the discrimination chain applied, we now move into obtaining its + // decision: + m_thresWrapper->getOutput(depVar, m_output, m_decVec); + + if ( m_decVec.empty() ){ + ATH_MSG_ERROR("There was no decision returned " + "by discrimination chain."); + return StatusCode::FAILURE; + } + + // Save discrimination into particle decision mask. We only use the first + // decision vector output: + m_partDecMsk->setCutResult( BitdefElectron_v1::RingerChainDec, m_decVec[0] ); + + return StatusCode::SUCCESS; + +} + +} // Namespace Ringer + +#endif // RINGER_STANDALONE diff --git a/PhysicsAnalysis/RingerSelectorTools/Root/tools/TrackPatternsHolder.cxx b/PhysicsAnalysis/RingerSelectorTools/Root/tools/TrackPatternsHolder.cxx new file mode 100644 index 0000000000000000000000000000000000000000..667ce5ba25aa3b2256f4fb2a34880f288a3c2f1a --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/Root/tools/TrackPatternsHolder.cxx @@ -0,0 +1,268 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: TrackPatternsHolder.cxx 693573 2015-09-07 19:15:49Z wsfreund $ +#ifndef RINGER_STANDALONE +// Local includes: +#include "RingerSelectorTools/tools/TrackPatternsHolder.h" +#include "RingerSelectorTools/tools/cxx/RingerUseNewCppFeatures.h" + +// STL includes: +#include <cmath> + + +// xAOD includes: +# include "xAODTracking/TrackParticle.h" +# include "xAODEgamma/EgammaEnums.h" +# include "xAODEgamma/Electron.h" + +#if !defined(XAOD_STANDALONE) && !defined(RINGER_STANDALONE) +# include "TrkTrackSummary/TrackSummary.h" +#else +// XXX This tool should be implemented in AsgTool enviroment... +namespace Trk { +namespace TrackSummary { +const int SummaryTypeNotSet = -1; +} // namespace TrackSummary; +} // namespace Trk +#endif + +namespace Ringer { + +#if !(RINGER_USE_NEW_CPP_FEATURES) +namespace { +float cutBinEta_TRT[] = {0.1, 0.625, 1.07, 1.304, 1.752, 2.0}; +} // private namespace +const double TrackPatternsHolder::m_a0 = 33.14; +const double TrackPatternsHolder::m_b0 = -129.1; +const double TrackPatternsHolder::m_c0 = 1455.; +const double TrackPatternsHolder::m_a1 = 29.42; +const double TrackPatternsHolder::m_b1 = 27.93; +const double TrackPatternsHolder::m_c1 = -89.96; +const double TrackPatternsHolder::m_d1 = 91.51; +const double TrackPatternsHolder::m_a2 = 196.3; +const double TrackPatternsHolder::m_b2 = -403.; +const double TrackPatternsHolder::m_c2 = 230.2; +const double TrackPatternsHolder::m_a3 = -10.59; +const double TrackPatternsHolder::m_b3 = 37.29; +const double TrackPatternsHolder::m_a4 = -640.9; +const double TrackPatternsHolder::m_b4 = 1323.; +const double TrackPatternsHolder::m_c4 = -851.8; +const double TrackPatternsHolder::m_d4 = 180.8; +const double TrackPatternsHolder::m_a5 = 159.8; +const double TrackPatternsHolder::m_b5 = -70.9; +const std::vector<float> TrackPatternsHolder::m_cutBinEta_TRT = + std::vector<float>(cutBinEta_TRT, cutBinEta_TRT + sizeof(cutBinEta_TRT) / sizeof(float)); +#else +constexpr std::array<float,6> TrackPatternsHolder::m_cutBinEta_TRT; +#endif + +// ============================================================================= +void TrackPatternsHolder::resetValues() +{ + m_nBL = 0; + m_nBLOutliers = 0; + m_nPi = 0; + m_nPiOutliers = 0; + m_nSCT = 0; + m_nSCTOutliers = 0; + m_nTRThigh = 0; + m_nTRThighOutliers = 0; + m_nTRT = 0; + m_nTRTOutliers = 0; + m_nTRTXenonHits = 0; + m_expectHitInBLayer = true; + m_trackd0 = 0; + m_deltaeta = 0; + m_deltaphi = 0; + m_ep = 0; + + m_energy = 0; + m_eta = 0; +} + +// ============================================================================= +void TrackPatternsHolder::extractPatternsFrom( + const xAOD::TrackParticle *track, + const xAOD::Electron *el) +{ + + // Reset values to default: + resetValues(); + + // Get cluster energy: + m_energy = el->caloCluster()->e(); + m_eta = std::fabs(el->caloCluster()->eta()); + + bool allFound = true; + + allFound = allFound && track->summaryValue(m_nBL, xAOD::numberOfBLayerHits); + if (m_useBLOutliers) { + allFound = allFound && track->summaryValue(m_nBLOutliers, xAOD::numberOfBLayerOutliers); + } + allFound = allFound && track->summaryValue(m_nPi, xAOD::numberOfPixelHits); + if (m_usePIXOutliers){ + allFound = allFound && track->summaryValue(m_nPiOutliers, xAOD::numberOfPixelOutliers); + } + allFound = allFound && track->summaryValue(m_nSCT, xAOD::numberOfSCTHits); + if (m_useSCTOutliers){ + allFound = allFound && track->summaryValue(m_nSCTOutliers, xAOD::numberOfSCTOutliers); + } + allFound = allFound && track->summaryValue(m_nTRThigh, xAOD::numberOfTRTHighThresholdHits); + if (m_useTRTOutliers){ + allFound = allFound && track->summaryValue(m_nTRThighOutliers, xAOD::numberOfTRTHighThresholdOutliers); + } + allFound = allFound && track->summaryValue(m_nTRT, xAOD::numberOfTRTHits); + allFound = allFound && track->summaryValue(m_nTRTOutliers, xAOD::numberOfTRTOutliers); + if (m_useTRTXenonHits){ + allFound = allFound && track->summaryValue(m_nTRTXenonHits, xAOD::numberOfTRTXenonHits); + } + allFound = allFound && track->summaryValue(m_expectHitInBLayer, xAOD::expectBLayerHit); + + m_trackd0 = fabsf(track->d0()); + + allFound = allFound && el->trackCaloMatchValue(m_deltaeta, xAOD::EgammaParameters::deltaEta1); + allFound = allFound && el->trackCaloMatchValue(m_deltaphi, xAOD::EgammaParameters::deltaPhi2); + + m_ep = m_energy * fabs(track->qOverP()); + + if (!allFound) { + // if object is bad then use the bit for "bad eta" + ATH_MSG_WARNING("Have some variables missing."); + } + +} + +// ============================================================================= +void TrackPatternsHolder::exportPatternsTo(std::vector<float> &vec) const +{ + + // Copy originals: + uint8_t nBL = m_nBL; + uint8_t nPi = m_nPi; + uint8_t nSi = m_nPi + m_nSCT; + + // Add outliers: + if (m_useBLOutliers) { + nBL += m_nBLOutliers; + } + + if (m_usePIXOutliers) { + nPi += m_nPiOutliers; + nSi += m_nPiOutliers; + } + + if (m_useSCTOutliers) { + nSi += m_nSCTOutliers; + } + + // Track quality cuts (CutID only dependent on eta) + //@{ + // egammaPID::TrackBlayer_Electron (CutID uses min + // value cut and check if modules was alive) + vec.push_back(nBL); // Pattern 0 + + // We, instead, put it as a pattern + vec.push_back(m_expectHitInBLayer); // Pattern 1 + + // egammaPID::TrackPixel_Electron (CutID uses min value cut) + vec.push_back(nPi); // Pattern 2 + + // egammaPID::TrackSi_Electron (CutID uses min value cut) + vec.push_back(nSi); // Pattern 3 + + // egammaPID::TrackA0_Electron || egammaPID::TrackA0Tight_Electron (CutID + // uses max value cut) + vec.push_back(m_trackd0); // Pattern 4 + //@} + + // CutID dependent on eta & et + //@{ + // egammaPID::TrackMatchEta_Electron (CutID uses max value cut) + vec.push_back(m_deltaeta); // Pattern 5 + + // egammaPID::TrackMatchPhi_Electron (CutID uses min & max value cuts) + vec.push_back(m_deltaphi); // Pattern 6 + + // egammaPID::TrackMatchEoverP_Electron (CutID uses min & max value cuts) + vec.push_back(m_ep); // Pattern 7 + //@} + + // Use of Transition Radiation Tracker + //@{ + double rTRT(0); + double trt_estimated_hits(0); + getTRTVar(rTRT,trt_estimated_hits); + + // egammaPID::TrackTRTratio(90)_Electron (CutID min value): + vec.push_back(rTRT); // Pattern 8 + + // egammaPID::TrackTRThits_Electron (CutID min value) + vec.push_back(trt_estimated_hits); // Pattern 9 + // @} +} + +// ============================================================================= +void TrackPatternsHolder::getTRTVar(double &rTRT, double &estHitsTRT) const +{ + int nTRTTotal(0); + if (m_useTRTOutliers) { + if (m_useTRTXenonHits /*&& + (static_cast<int>(m_nTRTXenonHits) != + Trk::TrackSummary::SummaryTypeNotSet)*/) //<- is it always true ? + { + nTRTTotal= m_nTRTXenonHits; + } else { + nTRTTotal = m_nTRT+m_nTRTOutliers; + } + rTRT = (nTRTTotal) > 0 ? + ((double) (m_nTRThigh+m_nTRThighOutliers)/(nTRTTotal) ) : 0.; + } else { + rTRT = (m_nTRT) > 0 ? ((double) (m_nTRThigh)/(m_nTRT) ) : 0.; + nTRTTotal = m_nTRT; + } + // FIXME Why isn't this in a function available anywhere else? + estHitsTRT = -1; + int ibin_eta_TRT = -1; + for (unsigned int ibinEta=0;ibinEta<m_cutBinEta_TRT.size();ibinEta++) { + if ( ibinEta == 0 ){ + if ( m_eta < m_cutBinEta_TRT[ibinEta] ) { + ibin_eta_TRT = ibinEta; + } + } else { + if ( m_eta >= m_cutBinEta_TRT[ibinEta-1] && + m_eta < m_cutBinEta_TRT[ibinEta] ) { + ibin_eta_TRT = ibinEta; + } + } + } + switch (ibin_eta_TRT) { + case 0: + estHitsTRT = nTRTTotal - + (m_a0 + m_b0*m_eta + m_c0*m_eta*m_eta); + break; + case 1: + estHitsTRT = nTRTTotal - + (m_a1 + m_b1*m_eta + m_c1*m_eta*m_eta + m_d1*m_eta*m_eta*m_eta); + break; + case 2: + estHitsTRT = nTRTTotal - + (m_a2 + m_b2*m_eta + m_c2*m_eta*m_eta) ; + break; + case 3: + estHitsTRT = nTRTTotal - (m_a3 + m_b3*m_eta); + break; + case 4: + estHitsTRT = nTRTTotal - + (m_a4 + m_b4*m_eta + m_c4*m_eta*m_eta + m_d4*m_eta*m_eta*m_eta); + break; + case 5: + estHitsTRT = nTRTTotal - (m_a5 + m_b5*m_eta); + } +} + + +} // namespace Ringer + +#endif // RINGER_STANDALONE diff --git a/PhysicsAnalysis/RingerSelectorTools/Root/tools/VariableDependency.cxx b/PhysicsAnalysis/RingerSelectorTools/Root/tools/VariableDependency.cxx new file mode 100644 index 0000000000000000000000000000000000000000..791b25df4fb3c8cd85fc29c4e5235d6693738b19 --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/Root/tools/VariableDependency.cxx @@ -0,0 +1,72 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: VariableDependency.cxx 667899 2015-05-18 18:37:25Z wsfreund $ +#include "RingerSelectorTools/tools/VariableDependency.h" + +#include "RingerSelectorTools/tools/IOHelperFcns.icc" + +namespace Ringer { + +// ============================================================================= +const char* VariableDependency::type() const +{ + std::stringstream depVar; + depVar.precision(2); + if (m_etaDependency){ + if (m_etDependency){ + depVar << "[" << m_etaMin << "<=eta<" << m_etaMax << ", " + << m_etMin << "<=Et<" << m_etMax << "]"; + } else { + depVar << "[" << m_etaMin << "<=eta<" << m_etaMax << "]"; + } + } else { + if (m_etDependency){ + depVar << "[" << m_etMin << "<=Et<" << m_etMax << "]"; + } else { + return "[eta, Et Independent]"; + } + } + const_cast<std::string&>(m_type) = depVar.str(); + return m_type.c_str(); +} + +// ============================================================================= +void VariableDependency::read(VariableDependency *varDep, + TDirectory *configDir, + unsigned /*writtenVersion*/) +{ + // Read unsigned int and transform it to EtDependency: + IOHelperFcns::readVar<EtaDependency, unsigned int>(configDir, + "etaDependency", + varDep->m_etaDependency ); + // Read unsigned int and transform it to EtDependency: + IOHelperFcns::readVar<EtDependency, unsigned int>(configDir, + "etDependency", + varDep->m_etDependency ); + IOHelperFcns::readVar(configDir, "etaMin", varDep->m_etaMin ); + IOHelperFcns::readVar(configDir, "etaMax", varDep->m_etaMax ); + IOHelperFcns::readVar(configDir, "etMin", varDep->m_etMin ); + IOHelperFcns::readVar(configDir, "etMax", varDep->m_etMax ); +} + +// ============================================================================= +void VariableDependency::writeDepInfo(TDirectory *configDir) const +{ + // Write EtaDependency enumeration as unsigned int: + IOHelperFcns::writeVar< const EtaDependency, const unsigned int>( configDir, + "etaDependency", + m_etaDependency ); + // Write EtDependency enumeration as unsigned int: + IOHelperFcns::writeVar< const EtDependency, const unsigned int>( configDir, + "etDependency", + m_etDependency ); + IOHelperFcns::writeVar(configDir, "etaMin", m_etaMin ); + IOHelperFcns::writeVar(configDir, "etaMax", m_etaMax ); + IOHelperFcns::writeVar(configDir, "etMin", m_etMin ); + IOHelperFcns::writeVar(configDir, "etMax", m_etMax ); +} + +} // namespace Ringer + diff --git a/PhysicsAnalysis/RingerSelectorTools/cmt/Makefile.RootCore b/PhysicsAnalysis/RingerSelectorTools/cmt/Makefile.RootCore new file mode 100644 index 0000000000000000000000000000000000000000..de3ae64ea5c658ec2a4b24d5c40ede410e5b24c7 --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/cmt/Makefile.RootCore @@ -0,0 +1,29 @@ +# this makefile also gets parsed by shell scripts +# therefore it does not support full make syntax and features +# edit with care + +# Don't make inline comments, they are not supported. + +# for full documentation check: +# https://twiki.cern.ch/twiki/bin/viewauth/Atlas/RootCore#Package_Makefile + +PACKAGE = RingerSelectorTools +PACKAGE_PRELOAD = +# This will be set automatically, do not add anything in this field. If it is +# needed, change precompile.RootCore line that writes this place: +PACKAGE_CXXFLAGS = -DASGTOOL_STANDALONE -DPACKAGE_VERSION=\"RingerSelectorTools-00-00-01\" +PACKAGE_OBJFLAGS = +PACKAGE_LDFLAGS = +PACKAGE_BINFLAGS = +PACKAGE_LIBFLAGS = +PACKAGE_DEP = PATCore AsgTools xAODBase xAODCore xAODEgamma xAODCaloRings xAODPrimitives PathResolver xAODCaloEvent ElectronPhotonSelectorTools xAODTracking +PACKAGE_TRYDEP = +PACKAGE_CLEAN = +PACKAGE_NOGRID = +PACKAGE_PEDANTIC = 1 +PACKAGE_NOOPT = 0 +PACKAGE_NOCC = 0 +PACKAGE_REFLEX = 1 + +include $(ROOTCOREDIR)/Makefile-common + diff --git a/PhysicsAnalysis/RingerSelectorTools/cmt/precompile.RootCore b/PhysicsAnalysis/RingerSelectorTools/cmt/precompile.RootCore new file mode 100755 index 0000000000000000000000000000000000000000..a83ed6d131479f7eb072c4d74f6ae89003cf7ce6 --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/cmt/precompile.RootCore @@ -0,0 +1,39 @@ +#!/bin/sh + +MAKEFILE=Makefile.RootCore +VERSIONFILE=version.cmt +ROOTCORE_REDIRECT_BASE=MoreFilesForYou-RootCore- + +# Check if root version is greater than 6.00/00 +#ROOT_VERSION_TEXT=`root-config --version` +#ROOT_VERSION_TEXT=${ROOT_VERSION_TEXT//./} +#ROOT_VERSION_TEXT=${ROOT_VERSION_TEXT//\//} +#if test "$ROOT_VERSION_TEXT" -gt "60000" +#then +# ROOT_GE_6_00=-DROOT_GE_6_00 +#else +# ROOT_GE_6_00= +#fi + +# Change our Makefile to add dependent information: +$ROOTCOREDIR/scripts/set_field.sh $MAKEFILE \ + PACKAGE_CXXFLAGS "-DASGTOOL_STANDALONE -DPACKAGE_VERSION=\\\\\"`cat $VERSIONFILE`\\\\\"" + +# Create RootCore file redirection for sources (done only to keep multifolder +# architeture) +cd ../Root/ +for dir in * +do + if test -d $dir + then + for file in `find $dir -type f -not -path "*/.*/*" -exec echo "{}" \;` + do + ROOTCORE_REDIRECT_FILE=`echo "${ROOTCORE_REDIRECT_BASE}${file//\//-}"` + if test ! -e $ROOTCORE_REDIRECT_FILE + then + ln -s $file $ROOTCORE_REDIRECT_FILE + fi + done + fi +done +cd - >> /dev/null diff --git a/PhysicsAnalysis/RingerSelectorTools/cmt/requirements b/PhysicsAnalysis/RingerSelectorTools/cmt/requirements new file mode 100644 index 0000000000000000000000000000000000000000..c3a2a1e23efe9a20bd8f0cb97007efc441761c50 --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/cmt/requirements @@ -0,0 +1,106 @@ +package RingerSelectorTools + +author Werner S. Freund <wsfreund@cern.ch> + +use AtlasPolicy AtlasPolicy-* +use AthenaKernel AthenaKernel-* Control +use AtlasROOT AtlasROOT-* External + +use PATCore PATCore-* PhysicsAnalysis/AnalysisCommon +use AsgTools AsgTools-* Control/AthToolSupport +use xAODEgamma xAODEgamma-* Event/xAOD +use xAODCaloRings xAODCaloRings-* Event/xAOD +use xAODTracking xAODTracking-* Event/xAOD +use_unless tag=ROOT_GE_6_00 \ + pkg=AtlasBoost ver=AtlasBoost-* root=External +use_unless tag=ROOT_GE_6_00 \ + pkg=CxxUtils ver=CxxUtils-* root=Control + +use ElectronPhotonSelectorTools ElectronPhotonSelectorTools-* PhysicsAnalysis/ElectronPhotonID + +private + +use GaudiInterface GaudiInterface-* External +use PathResolver PathResolver-* Tools +use AthContainers AthContainers-* Control + +use xAODBase xAODBase-* Event/xAOD +use TrkTrackSummary TrkTrackSummary-* Tracking/TrkEvent +end_private + +# Adds Core,Cint,Tree,pthread,MathCore,Hist Root libs +apply_tag ROOTBasicLibs + +branches RingerSelectorTools python src Root share data + +# Create a dual-use library (we exclude file that may be created by RootCore to +# keep source files with multi-folder architeture) +apply_pattern dual_use_library \ + files="*.cxx ../Root/*.cxx ../Root/procedures/*.cxx ../Root/tools/*.cxx -x=../Root/MoreFilesForYou-RootCore-*" + +# install our python modules +apply_pattern declare_python_modules files="*.py" + +# install the ROOT files (in the data/ directory) +apply_pattern declare_calib files="../data/*.root ../data/test" + +# For reflex dictionary generation +use AtlasReflex AtlasReflex-* External -no_auto_imports +apply_pattern lcgdict dict=RingerSelectorTools \ + selectionfile=selection.xml \ + headerfiles="..\/RingerSelectorTools/RingerSelectorToolsDict.h" + +# Add binary ringerSel_readTest using testRead.cxx +#application ringerSel_testRead ../util/testRead.cxx +#macro_append ringerSel_testRead_dependencies RingerSelectorToolsLib + +# Add binary ringerSel_writeTest using writeRead.cxx +#application ringerSel_testWrite ../util/testWrite.cxx +#macro_append ringerSel_testWrite_dependencies RingerSelectorToolsLib + + +###################### Code Graveyard ########################## + +#use AtlasPyROOT AtlasPyROOT-* External +#use xAODCaloEvent xAODCaloEvent-* Event/xAOD +#use xAODEventInfo xAODEventInfo-* Event/xAOD + +# Adds MathMore,Minuit,Minuit2,Matrix,Physics,HistPainter,Rint +#apply_tag ROOTMathLibs +# For more ROOT options, take a look here http://acode-browser.usatlas.bnl.gov/lxr/source/atlas/External/AtlasROOT/cmt/requirements + +#macro use_AtlasBoost "AtlasBoost AtlasBoost-* External" \ +# ROOT_GE_6_00 "" +#use $(use_AtlasBoost) +#macro use_CxxUtils "CxxUtils CxxUtils-* External" \ +# ROOT_GE_6_00 "" +#use $(use_CxxUtils) + +#macro_append ringerSel_testReadlinkopts "-lRingerSelectorToolsLib -lAtlasSTLAddReflexDict -lGaudiAlg " + +#private +## Python bindings: +#macro_append Boost_linkopts " $(Boost_linkopts_python) " +#macro_append pyringerselectortools_util_pp_cppflags " -Wno-unused " +#end_private + + +# This could be added by asg tool requirements, so that we don't need to do it ourselves. +#private +# Uncomment these to run on debug mode for this package only: +#macro cppdebugflags '$(cppdebugflags_s)' +#macro_remove componentshr_linkopts "-Wl,-s" +#macro_remove AtlasCxxPolicy_pp_cppflags "-DNDEBUG" +#macro_remove AtlasCxxPolicy_pp_cppflags "-O2" +#macro_append AtlasCxxPolicy_pp_cppflags " -g " +#end_private + +#pattern declare_python_package \ +# apply_pattern generic_declare_for_link kind=python_package \ +# files='-s=../python <pyth_package>/*.py' prefix=python/<pyth_package> name=<name> ; \ +# private ; \ +# macro_append <package>_python_init_dependencies " install_<name>python_package " ; \ +# end_private +# +#declare_python_package pyth_package="RingerSelectorTools" + diff --git a/PhysicsAnalysis/RingerSelectorTools/python/ConfiguredAsgElectronRingerSelector.py b/PhysicsAnalysis/RingerSelectorTools/python/ConfiguredAsgElectronRingerSelector.py new file mode 100644 index 0000000000000000000000000000000000000000..35b0fa03b2c92f01b99fb97d7547857eef879750 --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/python/ConfiguredAsgElectronRingerSelector.py @@ -0,0 +1,43 @@ +# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + +##============================================================================= +## Name: ConfiguredAsgElectronRingerSelector +## +## Author: Karsten Koeneke (CERN), Jovan Mitrevski (UCSC) +## Created: Dec. 2011 +## +## Description: Apply the default configurations for the AsgPhotonIsEMSelector, +## but allow for overwriting them with user-defined values. +## +##============================================================================= + +from RingerSelectorTools.ElectronRingerSelectorMapping import ElectronRingerMap + +def ConfiguredAsgElectronRingerSelector( quality, menu, cutIDConfDict = None, **kwargs ): + """ + Configure the AsgElectronRingerSelector with the quality cuts + and allow for setting its configurable properties through + cutIDConfDict and kwargs arguments. + + Use cutIDConfDict argument to set the properties from the CutIDSelector. + It can also be set directly by setting the property CutIDSelector through + kwargs. Beware not to set them together, as setting CutIDSelector + through kwargs will overwrite cutIDConfDict configurations and, thus, it + will be the only configuration used for the job. + """ + try: + RingerSelectorConfigurable = ElectronRingerMap[(quality, menu)] + + if cutIDConfDict is None: + cutIDConfDict = {} + # Configure it + ringerSelectorTool = RingerSelectorConfigurable(cutIDConfDict = cutIDConfDict, + **kwargs) + return ringerSelectorTool + except KeyError: + from AthenaCommon.Logging import logging + import traceback + mlog = logging.getLogger( 'ConfiguredAsgElectronRingerSelector.py' ) + mlog.error("There is no such configuration available:\n %s", traceback.format_exc()) + raise + diff --git a/PhysicsAnalysis/RingerSelectorTools/python/ElectronRingerSelectorDefs.py b/PhysicsAnalysis/RingerSelectorTools/python/ElectronRingerSelectorDefs.py new file mode 100644 index 0000000000000000000000000000000000000000..419379535a90544294833987050de302468b7442 --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/python/ElectronRingerSelectorDefs.py @@ -0,0 +1,147 @@ +# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + +from AthenaCommon.Logging import logging +mlog = logging.getLogger( 'ElectronRingerSelectorDefs.py' ) + +from AthenaCommon.Configurable import Configurable + +# Import from Ringer utilities: +try: + import cppyy +except ImportError: + import PyCintex as cppyy + +try : + cppyy.loadDictionary('RingerSelectorToolsDict') +except RuntimeError, e: + mlog.error("Could not load RingerSelectorTools dictionary from cppyy.") + raise RuntimeError(e) + +from ROOT import Ringer +from ROOT.Ringer import ElectronTAccept_v1 +from RingerSelectorTools.RingerSelectorToolsConf import Ringer__AsgElectronRingerSelector +from CaloRingerAlgs.CaloRingerKeys import outputElectronRingSetsConfKey + +# Import from CutID utilities: +try : + cppyy.loadDictionary('ElectronPhotonSelectorToolsDict') +except RuntimeError, e: + mlog.error("Could not load ElectronPhotonSelectorTools dictionary from cppyy.") + raise RuntimeError(e) +from ROOT import egammaPID +from ElectronPhotonSelectorTools.ElectronIsEMSelectorMapping import electronPIDmenu +from ElectronPhotonSelectorTools.ConfiguredAsgElectronIsEMSelectors \ + import ConfiguredAsgElectronIsEMSelector + +def removeClusterCutsFromIsEMMask(CutIDIsEMMask): + "Remove egammaPID Electron Calorimeter cuts from isEM" + CutIDIsEMMask = CutIDIsEMMask & (~egammaPID.CALO_ELECTRON) + +class BaseElectronSelectorConf ( Ringer__AsgElectronRingerSelector ): + def _setDefault(self,attrName, default, **kwargs): + "Overwrites AsgElectronRingerSelector default to new default value." + if not kwargs.has_key(attrName): + setattr(self, attrName, default) + + def _setCutIDSelector(self,defaultName,quality,menu,**kwargs): + """ + Set the AsgElectronRingerSelector CutIDSelector to default or to the configuration + available in the kwargs + """ + removeMask = False + if not kwargs.has_key("cutIDConfDict") and not kwargs.has_key("CutIDSelector"): + removeMask = True + if not kwargs.has_key("CutIDSelector"): + CutIDSelectorTool = ConfiguredAsgElectronIsEMSelector(defaultName, \ + quality, \ + menu, \ + **kwargs.pop("cutIDConfDict",{})) + from AthenaCommon.AppMgr import ToolSvc + ToolSvc += CutIDSelectorTool + self.CutIDSelector = CutIDSelectorTool + else: + self.CutIDSelector = kwargs.pop("CutIDSelector") + if removeMask: + removeClusterCutsFromIsEMMask(self.CutIDSelector.isEMMask) + + def __init__(self, name, **kwargs): + Ringer__AsgElectronRingerSelector.__init__(self,name,**kwargs) + self._setDefault("RingSetConfContainerName", + outputElectronRingSetsConfKey(), + **kwargs) + self._setDefault("CacheConfData", True, **kwargs) + self._setDefault("useCutIDTrack", False, **kwargs) + + +class ElectronRingerSelectorTestLoose( BaseElectronSelectorConf ): + def __init__(self, name = "ElectronRingerSelector_TestLoose", **kwargs): + BaseElectronSelectorConf.__init__(self,name,**kwargs) + self._setDefault("DiscriminationFileName", + "RingerSelectorTools/TestMenu_20150605_v1/ElectronRingerOfflineDiscrLoose.root", + **kwargs) + self._setDefault("ThresholdFileName", + "RingerSelectorTools/TestMenu_20150605_v1/ElectronRingerOfflineThresLoose.root", + **kwargs) + self._setDefault("CutsMask", + ElectronTAccept_v1.getAppliedCutMsk(Ringer.Loose, + kwargs.get("useCutIDTrack",False)), + **kwargs) + self._setCutIDSelector("LooseRingerIsEMSelector",\ + egammaPID.ElectronIDLoosePP, \ + electronPIDmenu.menuDC14, **kwargs) + +class ElectronRingerSelectorTestMedium( BaseElectronSelectorConf ): + def __init__(self, name = "ElectronRingerSelector_TestMedium", **kwargs): + BaseElectronSelectorConf.__init__(self,name,**kwargs) + self._setDefault("DiscriminationFileName", + "RingerSelectorTools/TestMenu_20150605_v1/ElectronRingerOfflineDiscrMedium.root", + **kwargs) + self._setDefault("ThresholdFileName", + "RingerSelectorTools/TestMenu_20150605_v1/ElectronRingerOfflineThresMedium.root", + **kwargs) + self._setDefault("CutsMask", + ElectronTAccept_v1.getAppliedCutMsk(Ringer.Medium, + kwargs.get("useCutIDTrack",False)), + **kwargs) + self._setCutIDSelector("MediumRingerIsEMSelector", \ + egammaPID.ElectronIDMediumPP, \ + electronPIDmenu.menuDC14, \ + **kwargs) + +class ElectronRingerSelectorTestTight( BaseElectronSelectorConf ): + def __init__(self, name = "ElectronRingerSelector_TestTight", **kwargs): + BaseElectronSelectorConf.__init__(self,name,**kwargs) + self._setDefault("DiscriminationFileName", + "RingerSelectorTools/TestMenu_20150605_v1/ElectronRingerOfflineDiscrTight.root", + **kwargs) + self._setDefault("ThresholdFileName", + "RingerSelectorTools/TestMenu_20150605_v1/ElectronRingerOfflineThresTight.root", + **kwargs) + self._setDefault("CutsMask", + ElectronTAccept_v1.getAppliedCutMsk(Ringer.Tight, + kwargs.get("useCutIDTrack",False)), + **kwargs) + self._setCutIDSelector("TightRingerIsEMSelector", \ + egammaPID.ElectronIDTightPP, \ + electronPIDmenu.menuDC14, **kwargs) + +class ElectronRingerSelectorTestNoCut( BaseElectronSelectorConf ): + def __init__(self, name = "ElectronRingerSelector_TestNoCut", **kwargs): + # FIXME This doesn't work, for now... + BaseElectronSelectorConf.__init__(self,name,**kwargs) + self._setDefault("DiscriminationFileName", + "RingerSelectorTools/TestMenu_20150605_v1/ElectronRingerOfflineDiscrMedium.root", + **kwargs) + self._setDefault("ThresholdFileName", + "RingerSelectorTools/TestMenu_20150605_v1/ElectronRingerOfflineThresMedium.root", + **kwargs) + self._setDefault("CutsMask", + ElectronTAccept_v1.getAppliedCutMsk(Ringer.NoCut, + kwargs.get("useCutIDTrack",False)), + **kwargs) + self._setCutIDSelector("NoCutRingerIsEMSelector", \ + egammaPID.ElectronIDNoCut, \ + electronPIDmenu.menuDC14, \ + **kwargs) + + diff --git a/PhysicsAnalysis/RingerSelectorTools/python/ElectronRingerSelectorMapping.py b/PhysicsAnalysis/RingerSelectorTools/python/ElectronRingerSelectorMapping.py new file mode 100644 index 0000000000000000000000000000000000000000..2e31789f6f8a629e6fdf6d3b6d995354eb95df90 --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/python/ElectronRingerSelectorMapping.py @@ -0,0 +1,64 @@ +# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + +##============================================================================= +## Name: ElectronRingerSelectorMapping.py +## +## Author: Werner Spolidoro Freund (LPS/UFRJ) +## Created: Mar 2015 +## +## Description: Retrieve selector from mask mapping +##============================================================================= + +try: + import cppyy +except ImportError: + import PyCintex as cppyy + +try : + cppyy.loadDictionary('RingerSelectorToolsDict') +except RuntimeError, e: + from AthenaCommon.Logging import logging + mlog = logging.getLogger( 'ElectronRingerSelectorMapping.py' ) + mlog.error("Could not load RingerSelectorTools dictionary from cppyy.") + raise RuntimeError(e) + +from ElectronPhotonSelectorTools.ElectronIsEMSelectorMapping import electronPIDmenu + +# Import from Ringer selector tools dictionary: +from ROOT import Ringer + +from RingerSelectorTools.ElectronRingerSelectorDefs import * + +class electronRingerPIDmenu (electronPIDmenu): + testMenu = 999 + +##################################################################################################### +## Requirements defined are: ## +## (see RingerSelectorToolsDefs.h) ## +##################################################################################################### +## Loose_CutID_Pd || Same detection probability as CutID Loose ## +## Medium_CutID_Pd || Same detection probability as CutID Medium ## +## Tight_CutID_Pd || Same detection probability as CutID Tight ## +## Loose_CutID_Pf || Same false alarm probability as CutID Loose ## +## Medium_CutID_Pf || Same false alarm probability as CutID Medium ## +## Tight_CutID_Pf || Same false alarm probability as CutID Tight ## +## Loose_LH_Pd, || Same detection probability as LH Loose ## +## Medium_LH_Pd, || Same detection probability as LH Medium ## +## Tight_LH_Pd, || Same detection probability as LH Tight ## +## Loose_LH_Pf, || Same false alarm probability as LH Loose ## +## Medium_LH_Pf, || Same false alarm probability as LH Medium ## +## Tight_LH_Pf, || Same false alarm probability as LH Tight ## +## Medium-MaxSP || Maximum SP-product ## +## Loose || Same as LooseCutIDPd ## +## Medium || Same as Medium-MaxSP ## +## Tight || Same as TightCutIDPfa ## +## NoCut || Run to retrieve discriminators outputs, but no cut is applied ## +##################################################################################################### +##################################################################################################### + +ElectronRingerMap = { + (Ringer.Loose, electronRingerPIDmenu.testMenu): ElectronRingerSelectorTestLoose, + (Ringer.Medium, electronRingerPIDmenu.testMenu): ElectronRingerSelectorTestMedium, + (Ringer.Tight, electronRingerPIDmenu.testMenu): ElectronRingerSelectorTestTight, + (Ringer.NoCut, electronRingerPIDmenu.testMenu): ElectronRingerSelectorTestNoCut, + } diff --git a/PhysicsAnalysis/RingerSelectorTools/src/components/RingerSelectorTools_entries.cxx b/PhysicsAnalysis/RingerSelectorTools/src/components/RingerSelectorTools_entries.cxx new file mode 100644 index 0000000000000000000000000000000000000000..ba0e7d590115e3f4874bd4e25e27e7ae9db55c1f --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/src/components/RingerSelectorTools_entries.cxx @@ -0,0 +1,13 @@ +#include "GaudiKernel/DeclareFactoryEntries.h" + +#include "RingerSelectorTools/AsgElectronRingerSelector.h" + +using namespace Ringer; + +DECLARE_TOOL_FACTORY( AsgElectronRingerSelector ) +//DECLARE_TOOL_FACTORY( AsgPhotonRingerSelector ) + +DECLARE_FACTORY_ENTRIES( RingerSelectorTools ){ + DECLARE_ALGTOOL( AsgElectronRingerSelector ) + //DECLARE_ALGTOOL( AsgPhotonRingerSelector ) +} diff --git a/PhysicsAnalysis/RingerSelectorTools/src/components/RingerSelectorTools_load.cxx b/PhysicsAnalysis/RingerSelectorTools/src/components/RingerSelectorTools_load.cxx new file mode 100644 index 0000000000000000000000000000000000000000..88559f54226337af09164f343e141b2b75ece222 --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/src/components/RingerSelectorTools_load.cxx @@ -0,0 +1,2 @@ +#include "GaudiKernel/LoadFactoryEntries.h" +LOAD_FACTORY_ENTRIES(RingerSelectorTools) diff --git a/PhysicsAnalysis/RingerSelectorTools/util/testRead.cxx b/PhysicsAnalysis/RingerSelectorTools/util/testRead.cxx new file mode 100644 index 0000000000000000000000000000000000000000..51f9acf50696b3db6f7d889279640019feb3c98e --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/util/testRead.cxx @@ -0,0 +1,664 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: testRead.cxx 693573 2015-09-07 19:15:49Z wsfreund $ +/** + * In this executable we want to test if wrappers can be sucessfully read. + * + * This will attempt to read the files written using testWrite. + **/ + +// STL includes: +#include <iostream> +#include <limits> + +// Root includes: +#include <TFile.h> +#include <THashList.h> + +// Gaudi includes: +#if !defined(RINGER_STANDALONE) && !defined(XAOD_STANDALONE) +# include "GaudiKernel/SystemOfUnits.h" +using namespace Gaudi::Units; +// We just do this ugly thing so that we can have a message stream +// FIXME How can I create a dummy message stream? +#define protected public +#define private public +# include "RingerSelectorTools/AsgElectronRingerSelector.h" +#undef protected +#undef private +Ringer::AsgElectronRingerSelector __AsgRingerSel__("testRead"); +MsgStream &msg = __AsgRingerSel__.msg(); +#else +#include "RingerSelectorTools/AsgElectronRingerSelector.h" +#include "AsgTools/MsgStream.h" +MsgStream msg("testRead"); +#endif + +#define BREAKER \ + "================================================================================" + +// Local includes: +#include "RingerSelectorTools/procedures/RingerProcedureWrapper.h" +#include "RingerSelectorTools/procedures/Normalizations.h" +#include "RingerSelectorTools/procedures/NeuralNetwork.h" +#include "RingerSelectorTools/procedures/Thresholds.h" +#include "RingerSelectorTools/tools/IOHelperFcns.h" +#include "RingerSelectorTools/tools/cxx/remove_pointer.h" + +using namespace Ringer; + +/** + * Read first wrapper on file with type wrapper_t + **/ +template< class wrapper_t > +void readWrapperFromFile(wrapper_t *&wrapper, const char* fileName); + +/** + * Read wrapper collection at file named fileName with base wrapper type + * wrapperBase_t + **/ +template<typename wrapperBase_t> +void readCollectionFromFile(const char* fileName); + +template<> +void readCollectionFromFile<IThresWrapper>(const char* fileName); + +int main(){ + + // Change message level and greet user + msg.setLevel(MSG::DEBUG); + + msg << MSG::INFO << BREAKER << endreq; + msg << MSG::INFO << "Reading discriminator using interface " + "without using normalization." << endreq; + msg << MSG::INFO << BREAKER << endreq; + + // ---------------------------------------------------------------------------- + // Read simple discriminator using interface (without using normalization) + // ---------------------------------------------------------------------------- + // Read "basicWrapperWrong" using correct template + RingerProcedureWrapper<Discrimination::IDiscriminatorVarDep, + EtaIndependent, + EtIndependent, + NoSegmentation > *basicWrapper(nullptr); + readWrapperFromFile< + typename Ringer::remove_pointer<decltype(basicWrapper)>::type + >( basicWrapper, "basicWrapper.root" ); + msg << MSG::INFO << BREAKER << endreq; + + // Read as "basicEtaDepWrapper" using correct template + RingerProcedureWrapper<Discrimination::IDiscriminatorVarDep, + EtaDependent, + EtIndependent, + NoSegmentation > *basicEtaDepWrapper(nullptr); + readWrapperFromFile< + typename Ringer::remove_pointer<decltype(basicEtaDepWrapper)>::type + >( basicEtaDepWrapper, "basicEtaDepWrapper.root"); + msg << MSG::INFO << BREAKER << endreq; + + // Read "basicEtDepWrapper" using correct template + RingerProcedureWrapper<Discrimination::IDiscriminatorVarDep, + EtaIndependent, + EtDependent, + NoSegmentation > *basicEtDepWrapper(nullptr); + readWrapperFromFile< + typename Ringer::remove_pointer<decltype(basicEtDepWrapper)>::type + >( basicEtDepWrapper, "basicEtDepWrapper.root"); + msg << MSG::INFO << BREAKER << endreq; + + // Read "basicEtaEtDepWrapper.root" using correct template + RingerProcedureWrapper<Discrimination::IDiscriminatorVarDep, + EtaDependent, + EtDependent, + NoSegmentation > *basicEtaEtDepWrapper(nullptr); + readWrapperFromFile< + typename Ringer::remove_pointer<decltype(basicEtaEtDepWrapper)>::type + >( basicEtaEtDepWrapper, "basicEtaEtDepWrapper.root"); + // -------------------------- END --- END --- END ----------------------------- + + msg.setLevel(MSG::ERROR); + + msg << MSG::INFO << BREAKER << endreq; + msg << MSG::INFO << "Reading discriminator with wrong types!" << endreq; + msg << MSG::INFO << BREAKER << endreq; + // ---------------------------------------------------------------------------- + // Read simple discriminator using interface with WRONG types + // ---------------------------------------------------------------------------- + RingerProcedureWrapper<Discrimination::IDiscriminatorVarDep, + EtaDependent, + EtDependent, + NoSegmentation > *basicWrapperWrong(nullptr); + readWrapperFromFile< + typename Ringer::remove_pointer<decltype(basicWrapperWrong)>::type + >( basicWrapperWrong, "basicWrapper.root" ); + msg << MSG::INFO << BREAKER << endreq; + + // Read as "basicEtaDepWrapperWrong" using wrong template + RingerProcedureWrapper<Discrimination::IDiscriminatorVarDep, + EtaIndependent, + EtIndependent, + NoSegmentation > *basicEtaDepWrapperWrong(nullptr); + readWrapperFromFile< + typename Ringer::remove_pointer<decltype(basicEtaDepWrapperWrong)>::type + >( basicEtaDepWrapperWrong, "basicEtaDepWrapper.root"); + msg << MSG::INFO << BREAKER << endreq; + + // Read "basicEtDepWrapperWrong" using wrong template + RingerProcedureWrapper<Discrimination::IDiscriminatorVarDep, + EtaIndependent, + EtIndependent, + NoSegmentation > *basicEtDepWrapperWrong(nullptr); + readWrapperFromFile< + typename Ringer::remove_pointer<decltype(basicEtDepWrapperWrong)>::type + >( basicEtDepWrapperWrong, "basicEtDepWrapper.root"); + msg << MSG::INFO << BREAKER << endreq; + + // Read "basicEtaEtDepWrapperWrong.root" using wrong template + RingerProcedureWrapper<Discrimination::IDiscriminatorVarDep, + EtaDependent, + EtDependent, + TrackCalJointLayers > *basicEtaEtDepWrapperWrong(nullptr); + readWrapperFromFile< + typename Ringer::remove_pointer<decltype(basicEtaEtDepWrapperWrong)>::type + >( basicEtaEtDepWrapperWrong, "basicEtaEtDepWrapper.root"); + // -------------------------- END --- END --- END ----------------------------- + msg.setLevel(MSG::DEBUG); + + msg << MSG::INFO << BREAKER << endreq; + msg << MSG::INFO << "Reading pre-processings!" << endreq; + msg << MSG::INFO << BREAKER << endreq; + // ---------------------------------------------------------------------------- + // Start testing pre-processings + // ---------------------------------------------------------------------------- + // Read "basicPPWrapper.root" + RingerProcedureWrapper<PreProcessing::IPreProcessorVarDep, + EtaIndependent, + EtIndependent, + NoSegmentation > *basicPPWrapper(nullptr); + readWrapperFromFile< + typename Ringer::remove_pointer<decltype(basicPPWrapper)>::type + >( basicPPWrapper, "basicPPWrapper.root"); + msg << MSG::INFO << BREAKER << endreq; + + // Read "basicEtaDepPPWrapper.root" + RingerProcedureWrapper<PreProcessing::IPreProcessorVarDep, + EtaDependent, + EtIndependent, + NoSegmentation > *basicEtaDepPPWrapper(nullptr); + readWrapperFromFile< + typename Ringer::remove_pointer<decltype(basicEtaDepPPWrapper)>::type + >( basicEtaDepPPWrapper, "basicEtaDepPPWrapper.root"); + msg << MSG::INFO << BREAKER << endreq; + + // Read "basicEtDepPPWrapper.root" + RingerProcedureWrapper<PreProcessing::IPreProcessorVarDep, + EtaIndependent, + EtDependent, + NoSegmentation > *basicEtDepPPWrapper(nullptr); + readWrapperFromFile< + typename Ringer::remove_pointer<decltype(basicEtDepPPWrapper)>::type + >( basicEtDepPPWrapper, "basicEtDepPPWrapper.root"); + msg << MSG::INFO << BREAKER << endreq; + + // Read "basicEtEtaDepPPWrapper.root" + RingerProcedureWrapper<PreProcessing::IPreProcessorVarDep, + EtaDependent, + EtDependent, + NoSegmentation > *basicEtEtaDepPPWrapper(nullptr); + readWrapperFromFile< + typename Ringer::remove_pointer<decltype(basicEtEtaDepPPWrapper)>::type + >( basicEtEtaDepPPWrapper, "basicEtEtaDepPPWrapper.root"); + msg << MSG::INFO << BREAKER << endreq; + + // Read "basicEtEtaTrackCalDepPPWrapper.root" + RingerProcedureWrapper<PreProcessing::IPreProcessorVarDep, + EtaDependent, + EtDependent, + TrackCalSegmentation > *basicEtEtaTrackCalDepPPWrapper(nullptr); + readWrapperFromFile< + typename Ringer::remove_pointer<decltype(basicEtEtaTrackCalDepPPWrapper)>::type + >( basicEtEtaTrackCalDepPPWrapper, "basicEtEtaTrackCalDepPPWrapper.root"); + msg << MSG::INFO << BREAKER << endreq; + + // Read "basicEtEtaTrackCalPatTypeDepPPWrapper.root" + RingerProcedureWrapper<PreProcessing::IPreProcessorVarDep, + EtaDependent, + EtDependent, + TrackCalPatTypeSegmentation > *basicEtEtaTrackCalPatTypeDepPPWrapper(nullptr); + readWrapperFromFile< + typename Ringer::remove_pointer<decltype(basicEtEtaTrackCalPatTypeDepPPWrapper)>::type + >( basicEtEtaTrackCalPatTypeDepPPWrapper, "basicEtEtaTrackCalPatTypeDepPPWrapper.root"); + msg << MSG::INFO << BREAKER << endreq; + + // Read "basicEtaEtSectionDepPPWrapper.root" + RingerProcedureWrapper<PreProcessing::IPreProcessorVarDep, + EtaDependent, + EtDependent, + TrackCalJointSections > *basicEtaEtSectionDepPPWrapper(nullptr); + readWrapperFromFile< + typename Ringer::remove_pointer<decltype(basicEtaEtSectionDepPPWrapper)>::type + >( basicEtaEtSectionDepPPWrapper, "basicEtaEtSectionDepPPWrapper.root"); + msg << MSG::INFO << BREAKER << endreq; + + // Read "basicEtaEtLayerDepPPWrapper.root" + RingerProcedureWrapper<PreProcessing::IPreProcessorVarDep, + EtaDependent, + EtDependent, + TrackCalJointLayers > *basicEtaEtLayerDepPPWrapper(nullptr); + readWrapperFromFile< + typename Ringer::remove_pointer<decltype(basicEtaEtLayerDepPPWrapper)>::type + >( basicEtaEtLayerDepPPWrapper, "basicEtaEtLayerDepPPWrapper.root"); + msg << MSG::INFO << BREAKER << endreq; + + // Read "basicNorm1Wrapper.root" + RingerProcedureWrapper<PreProcessing::IPreProcessorVarDep, + EtaIndependent, + EtIndependent, + NoSegmentation > *basicNorm1Wrapper(nullptr); + readWrapperFromFile< + typename Ringer::remove_pointer<decltype(basicNorm1Wrapper)>::type + >( basicNorm1Wrapper, "basicNorm1Wrapper.root"); + msg << MSG::INFO << BREAKER << endreq; + + // Read "basicNorm1Wrapper.root" + RingerProcedureWrapper<PreProcessing::Norm::Norm1VarDep, + EtaDependent, + EtDependent, + TrackCalJointLayers > *basicLayerDepNorm1Wrapper(nullptr); + readWrapperFromFile< + typename Ringer::remove_pointer<decltype(basicLayerDepNorm1Wrapper)>::type + >( basicLayerDepNorm1Wrapper, "basicLayerDepNorm1Wrapper.root"); + msg << MSG::INFO << BREAKER << endreq; + + // Read "basicNorm2Wrapper.root" + RingerProcedureWrapper<PreProcessing::Norm::Norm2VarDep, + EtaIndependent, + EtIndependent, + TrackCalJointLayers > *basicNorm2Wrapper(nullptr); + readWrapperFromFile< + typename Ringer::remove_pointer<decltype(basicNorm2Wrapper)>::type + >( basicNorm2Wrapper, "basicNorm2Wrapper.root"); + msg << MSG::INFO << BREAKER << endreq; + + // Read "basicSqrtWrapper.root" + RingerProcedureWrapper<PreProcessing::Norm::SqrtVarDep, + EtaIndependent, + EtIndependent, + NoSegmentation > *basicSqrtWrapper(nullptr); + readWrapperFromFile< + typename Ringer::remove_pointer<decltype(basicSqrtWrapper)>::type + >( basicSqrtWrapper, "basicSqrtWrapper.root"); + msg << MSG::INFO << BREAKER << endreq; + + // Read "basicConstantValueWrapper.root" + RingerProcedureWrapper<PreProcessing::Norm::ConstantValueVarDep, + EtaIndependent, + EtIndependent, + NoSegmentation > *basicConstantValueWrapper(nullptr); + readWrapperFromFile< + typename Ringer::remove_pointer<decltype(basicConstantValueWrapper)>::type + >( basicConstantValueWrapper, "basicConstantValueWrapper.root"); + msg << MSG::INFO << BREAKER << endreq; + + // Read "basicMevToGevWrapper.root" + RingerProcedureWrapper<PreProcessing::Norm::MevToGevVarDep, + EtaIndependent, + EtIndependent, + NoSegmentation > *basicMevToGevWrapper(nullptr); + readWrapperFromFile< + typename Ringer::remove_pointer<decltype(basicMevToGevWrapper)>::type + >( basicMevToGevWrapper, "basicMevToGevWrapper.root"); + msg << MSG::INFO << BREAKER << endreq; + + // Read "basicSequentialWrapper.root" + RingerProcedureWrapper<PreProcessing::Norm::SequentialVarDep, + EtaIndependent, + EtIndependent, + NoSegmentation > *basicSequentialWrapper(nullptr); + readWrapperFromFile< + typename Ringer::remove_pointer<decltype(basicSequentialWrapper)>::type + >( basicSequentialWrapper, "basicSequentialWrapper.root"); + msg << MSG::INFO << BREAKER << endreq; + + // Read "basicSpherizationWrapper.root" + RingerProcedureWrapper<PreProcessing::Norm::SpherizationVarDep, + EtaIndependent, + EtIndependent, + NoSegmentation > *basicSpherizationWrapper(nullptr); + readWrapperFromFile< + typename Ringer::remove_pointer<decltype(basicSpherizationWrapper)>::type + >( basicSpherizationWrapper, "basicSpherizationWrapper.root"); + msg << MSG::INFO << BREAKER << endreq; + + // Read "basicMinMaxWrapper.root" + RingerProcedureWrapper<PreProcessing::Norm::MinMaxVarDep, + EtaIndependent, + EtIndependent, + NoSegmentation > *basicMinMaxWrapper(nullptr); + readWrapperFromFile< + typename Ringer::remove_pointer<decltype(basicMinMaxWrapper)>::type + >( basicMinMaxWrapper, "basicMinMaxWrapper.root"); + msg << MSG::INFO << BREAKER << endreq; + // -------------------------- END --- END --- END ----------------------------- + + msg << MSG::INFO << BREAKER << endreq; + msg << MSG::INFO << "Reading discriminators with pre-processings!" << endreq; + msg << MSG::INFO << BREAKER << endreq; + + // ---------------------------------------------------------------------------- + // Read discriminators with pre-processings + // ---------------------------------------------------------------------------- + // Read "randomNorm1PPDiscrWrapper.root" + RingerProcedureWrapper<Discrimination::IDiscriminatorVarDep, + EtaDependent, + EtDependent, + NoSegmentation > *randomNorm1PPDiscrWrapper(nullptr); + readWrapperFromFile< + typename Ringer::remove_pointer<decltype(randomNorm1PPDiscrWrapper)>::type + >( randomNorm1PPDiscrWrapper, "randomNorm1PPDiscrWrapper.root"); + msg << MSG::INFO << BREAKER << endreq; + + // Read "randomNorm1PPDiscrWrapper.root" + RingerProcedureWrapper<Discrimination::IDiscriminatorVarDep, + EtaDependent, + EtDependent, + NoSegmentation > *randomDepPPrandomDepPPDiscrWrapper(nullptr); + readWrapperFromFile< + typename Ringer::remove_pointer<decltype(randomDepPPrandomDepPPDiscrWrapper)>::type + >( randomDepPPrandomDepPPDiscrWrapper, "randomDepPPrandomDepPPDiscrWrapper.root"); + msg << MSG::INFO << BREAKER << endreq; + // ---------------------------------------------------------------------------- + + msg << MSG::INFO << BREAKER << endreq; + msg << MSG::INFO << "Reading segmented discriminator PP wrappers:" << endreq; + msg << MSG::INFO << BREAKER << endreq; + + // ---------------------------------------------------------------------------- + // Read segmented discriminators with pre-processings + // ---------------------------------------------------------------------------- + // Read "randomDepPPrandomDepPPDiscrSegmentedWrapper.root" + RingerProcedureWrapper<Discrimination::IDiscriminatorVarDep, + EtaDependent, + EtDependent, + TrackCalJointLayers > *randomDepPPrandomDepPPDiscrSegmentedWrapper(nullptr); + readWrapperFromFile< + typename Ringer::remove_pointer<decltype(randomDepPPrandomDepPPDiscrSegmentedWrapper)>::type + >( randomDepPPrandomDepPPDiscrSegmentedWrapper, "randomDepPPrandomDepPPDiscrSegmentedWrapper.root"); + // -------------------------- END --- END --- END ----------------------------- + + msg << MSG::INFO << BREAKER << endreq; + msg << MSG::INFO << "Reading specialized discriminator:" << endreq; + msg << MSG::INFO << BREAKER << endreq; + + // ---------------------------------------------------------------------------- + // Read specialized discriminator wrapper with no pre-processings + // ---------------------------------------------------------------------------- + // Read "NNWrapper.root" + RingerProcedureWrapper<Discrimination::NNFeedForwardVarDep, + EtaIndependent, + EtIndependent, + NoSegmentation > *NNWrapper(nullptr); + readWrapperFromFile< + typename Ringer::remove_pointer<decltype(NNWrapper)>::type + >( NNWrapper, "NNWrapper.root"); + msg << MSG::INFO << BREAKER << endreq; + + // Read "NNWrapper.root" + RingerProcedureWrapper<Discrimination::NNFeedForwardVarDep, + EtaDependent, + EtDependent, + TrackCalJointLayers > *FullDepNNWrapper(nullptr); + readWrapperFromFile< + typename Ringer::remove_pointer<decltype(FullDepNNWrapper)>::type + >( FullDepNNWrapper, "FullDepNNWrapper.root"); + // -------------------------- END --- END --- END ----------------------------- + + msg << MSG::INFO << BREAKER << endreq; + msg << MSG::INFO << "Reading specialized discriminator with PP wrappers:" << endreq; + msg << MSG::INFO << BREAKER << endreq; + + // ---------------------------------------------------------------------------- + // Read specialized discriminator wrapper with specialized pre-processings + // ---------------------------------------------------------------------------- + // Read "Norm1NNWrapper.root" + RingerProcedureWrapper<Discrimination::NNFeedForwardVarDep, + EtaIndependent, + EtIndependent, + NoSegmentation > *Norm1NNWrapper(nullptr); + readWrapperFromFile< + typename Ringer::remove_pointer<decltype(Norm1NNWrapper)>::type + >( Norm1NNWrapper, "Norm1NNWrapper.root"); + msg << MSG::INFO << BREAKER << endreq; + + // Read "Norm1Norm1FullDepNNWrapper.root" + RingerProcedureWrapper<Discrimination::NNFeedForwardVarDep, + EtaDependent, + EtDependent, + TrackCalJointLayers > *Norm1Norm1FullDepNNWrapper(nullptr); + readWrapperFromFile< + typename Ringer::remove_pointer<decltype(Norm1Norm1FullDepNNWrapper)>::type + >( Norm1Norm1FullDepNNWrapper, "Norm1Norm1FullDepNNWrapper.root"); + // -------------------------- END --- END --- END ----------------------------- + + msg << MSG::INFO << BREAKER << endreq; + msg << MSG::INFO << "Reading threshold wrappers:" << endreq; + msg << MSG::INFO << BREAKER << endreq; + + // ---------------------------------------------------------------------------- + // Read thresholds + // ---------------------------------------------------------------------------- + // Read "basicThres.root" + RingerProcedureWrapper<Discrimination::IThresholdVarDep, + EtaIndependent, + EtIndependent > *basicThres(nullptr); + readWrapperFromFile< + typename Ringer::remove_pointer<decltype(basicThres)>::type + >( basicThres, "basicThres.root"); + msg << MSG::INFO << BREAKER << endreq; + + // Read "basicEtaDepThres.root" + RingerProcedureWrapper<Discrimination::IThresholdVarDep, + EtaDependent, + EtIndependent > *basicEtaDepThres(nullptr); + readWrapperFromFile< + typename Ringer::remove_pointer<decltype(basicEtaDepThres)>::type + >( basicEtaDepThres, "basicEtaDepThres.root"); + msg << MSG::INFO << BREAKER << endreq; + + // Read "basicEtDepThres.root" + RingerProcedureWrapper<Discrimination::IThresholdVarDep, + EtaIndependent, + EtDependent > *basicEtDepThres(nullptr); + readWrapperFromFile< + typename Ringer::remove_pointer<decltype(basicEtDepThres)>::type + >( basicEtDepThres, "basicEtDepThres.root"); + msg << MSG::INFO << BREAKER << endreq; + + // Read "basicEtaEtDepThres.root" + RingerProcedureWrapper<Discrimination::IThresholdVarDep, + EtaDependent, + EtDependent > *basicEtaEtDepThres(nullptr); + readWrapperFromFile< + typename Ringer::remove_pointer<decltype(basicEtaEtDepThres)>::type + >( basicEtaEtDepThres, "basicEtaEtDepThres.root"); + // -------------------------- END --- END --- END ----------------------------- + + msg << MSG::INFO << BREAKER << endreq; + msg << MSG::INFO << "Reading specialized threshold wrappers:" << endreq; + msg << MSG::INFO << BREAKER << endreq; + + // ---------------------------------------------------------------------------- + // Read speaclized thresholds + // ---------------------------------------------------------------------------- + // Read "uniqueThres.root" + RingerProcedureWrapper<Discrimination::UniqueThresholdVarDep, + EtaIndependent, + EtIndependent > *uniqueThres(nullptr); + readWrapperFromFile< + typename Ringer::remove_pointer<decltype(uniqueThres)>::type + >( uniqueThres, "uniqueThres.root"); + msg << MSG::INFO << BREAKER << endreq; + + // Read "uniqueEtaDepThres.root" + RingerProcedureWrapper<Discrimination::UniqueThresholdVarDep, + EtaDependent, + EtIndependent > *uniqueEtaDepThres(nullptr); + readWrapperFromFile< + typename Ringer::remove_pointer<decltype(uniqueEtaDepThres)>::type + >( uniqueEtaDepThres, "uniqueEtaDepThres.root"); + msg << MSG::INFO << BREAKER << endreq; + + // Read "uniqueEtDepThres.root" + RingerProcedureWrapper<Discrimination::UniqueThresholdVarDep, + EtaIndependent, + EtDependent > *uniqueEtDepThres(nullptr); + readWrapperFromFile< + typename Ringer::remove_pointer<decltype(uniqueEtDepThres)>::type + >( uniqueEtDepThres, "uniqueEtDepThres.root"); + msg << MSG::INFO << BREAKER << endreq; + + // Read "uniqueEtaEtDepThres.root" + RingerProcedureWrapper<Discrimination::UniqueThresholdVarDep, + EtaDependent, + EtDependent > *uniqueEtaEtDepThres(nullptr); + readWrapperFromFile< + typename Ringer::remove_pointer<decltype(uniqueEtaEtDepThres)>::type + >( uniqueEtaEtDepThres, "uniqueEtaEtDepThres.root"); + // -------------------------- END --- END --- END ----------------------------- + + + msg << MSG::INFO << BREAKER << endreq; + msg << MSG::INFO << "Special reading" << endreq; + msg << MSG::INFO << BREAKER << endreq; + + // ---------------------------------------------------------------------------- + // Test reading multiple wrappers + // ---------------------------------------------------------------------------- + readCollectionFromFile<IDiscrWrapper>("Norm1NNWrapper.root"); + msg << MSG::INFO << BREAKER << endreq; + readCollectionFromFile<IDiscrWrapper>("Norm1Norm1FullDepNNWrapper.root"); + msg << MSG::INFO << BREAKER << endreq; + readCollectionFromFile<IThresWrapper>("uniqueEtaEtDepThres.root"); + // -------------------------- END --- END --- END ----------------------------- + + msg << MSG::INFO << BREAKER << endreq; + msg << MSG::INFO << "Finished!" << endreq; + msg << MSG::INFO << BREAKER << endreq; + + return 0; +} + +// ============================================================================= +template< class wrapper_t > +void readWrapperFromFile(wrapper_t *&wrapper, const char* fileName) +{ + + msg << MSG::INFO << "Reading wrapper: " << wrapper_t::staticFullName() + << ", at file named: " << fileName << endreq; + + // Read file and bring everything to memory: + TFile wrapperFile(fileName, "READ"); + wrapperFile.ReadAll(); + TDirectory *baseDir = wrapperFile.GetDirectory(""); + + std::shared_ptr<THashList> wrapperDirList(nullptr); + if ( !( wrapperDirList = IOHelperFcns::getDirList(baseDir) ) ) { + throw std::runtime_error(std::string("There are no directories available")); + } + + msg << MSG::INFO << "Number(s) of folder(s) within this TFile is " + << wrapperDirList->GetSize() + << endreq; + + try { + + TIter iter( wrapperDirList.get() ); + TDirectory* wrapperDir(nullptr); + + bool foundDir = false; + + while ( (wrapperDir = static_cast<TDirectoryFile*>(iter())) ){ + if ( wrapperDir->GetName() == + ( std::string(wrapper_t::wrapName) + + IOHelperFcns::makeIdxStr(0) ) ) + { + msg << MSG::INFO << "Found directory named " + << wrapperDir->GetName() << endreq; + foundDir = true; + break; + } + } + + if ( !foundDir ){ + throw std::runtime_error(std::string("Couldn't find the wrapper directory")); + } + + wrapper = wrapper_t::read(wrapperDir,IOHelperFcns::version()); + + if (wrapper == nullptr){ + throw std::runtime_error(std::string("Returned void pointer.")); + } + + // Use dummy message stream: + wrapper->setMsgStream(&msg); + + msg << MSG::INFO << "Printing wrapper " << endreq; + + // to print wrapper information: + wrapper->print(); + + } catch ( const std::runtime_error &e){ + msg << MSG::ERROR << "Couldn't read due to error: " + << e.what() << endreq; + } + + // Close file + wrapperFile.Close(); +} + +// ============================================================================= +template<typename wrapperBase_t> +void readCollectionFromFile(const char* fileName) +{ + + msg << MSG::INFO << "Reading file: " << fileName << endreq; + + // Get wrapper collection and read it: + typename wrapperBase_t::WrapperCollection col; + wrapperBase_t::read( col, fileName ); + + unsigned counter(0); + for ( auto *wrapper : col ) { + if (wrapper){ + msg << MSG::INFO << "Printing wrapper " << wrapper->fullName() + << " at position " << IOHelperFcns::makeIdxStr(counter++) << endreq; + wrapper->setMsgStream(&msg);wrapper->print(); + } else { + msg << MSG::ERROR << "Couldn't print wrapper on file " << fileName << endreq; + } + } + + msg << MSG::INFO << "File configuration: " << endreq; + AsgElectronRingerSelector::IOConfStruct ioConf; + AsgElectronRingerSelector::retrieveFileConf( fileName, ioConf ); + AsgElectronRingerSelector::printConf(ioConf, &msg); +} + +// ============================================================================= +template<> +void readCollectionFromFile<IThresWrapper>(const char* fileName) +{ + + msg << MSG::INFO << "Reading file: " << fileName << endreq; + + // Get wrapper collection and read it: + IThresWrapper *wrapper; + IThresWrapper::read( wrapper, fileName ); + if (wrapper) {wrapper->setMsgStream(&msg); wrapper->print();} + else msg << MSG::ERROR << "Couldn't print wrapper on file " << fileName << endreq; +} + + + diff --git a/PhysicsAnalysis/RingerSelectorTools/util/testWrite.cxx b/PhysicsAnalysis/RingerSelectorTools/util/testWrite.cxx new file mode 100644 index 0000000000000000000000000000000000000000..454b59609c86ca8eb52de92557679db0b765a92c --- /dev/null +++ b/PhysicsAnalysis/RingerSelectorTools/util/testWrite.cxx @@ -0,0 +1,1442 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: testWrite.cxx 694257 2015-09-10 22:45:27Z wsfreund $ +/** + * In this executable we want to test if wrappers can be sucessfully written. + * + * For that we will create different wrapper types and write them into different + * files. Afterwards, it is needed to run testRead on the same path that + * testWrite was run and check if the information written is correct. + * + **/ + +// STL includes: +#include <iostream> +#include <limits> +#include <type_traits> + +// Root includes: +#include <TFile.h> + +// Gaudi includes: +#if !defined(RINGER_STANDALONE) && !defined(XAOD_STANDALONE) +# include "GaudiKernel/SystemOfUnits.h" +using namespace Gaudi::Units; +// We just do this ugly thing so that we can have a message stream +// FIXME How can I create a dummy message stream without doing this? +#define protected public +#define private public +# include "RingerSelectorTools/AsgElectronRingerSelector.h" +#undef protected +#undef private +Ringer::AsgElectronRingerSelector __AsgRingerSel__("testWrite"); +MsgStream &msg = __AsgRingerSel__.msg(); +#else +#include "RingerSelectorTools/AsgElectronRingerSelector.h" +#include "AsgTools/MsgStream.h" +MsgStream msg("testWrite"); +#endif + +#define BREAKER \ + "================================================================================" + +// Local includes: +#include "RingerSelectorTools/procedures/RingerProcedureWrapper.h" +#include "RingerSelectorTools/procedures/Normalizations.h" +#include "RingerSelectorTools/procedures/NeuralNetwork.h" +#include "RingerSelectorTools/procedures/Thresholds.h" +#include "RingerSelectorTools/tools/IOHelperFcns.h" +#include "RingerSelectorTools/tools/TrackPatternsHolder.h" + +using namespace Ringer; + +/** + * Method dedicated for testing pre-processing wrapper creation + **/ +template< + typename procedure_t, + EtaDependency etaDependency, + EtDependency etDependency, + SegmentationType segType +> +IPreProcWrapper* createPPWrapper(const char *fileName, + const std::vector<float> &etaDepBounderies = {0, 2.5}, + const std::vector<float> &etDepBounderies + = {0, std::numeric_limits<float>::infinity()} + ); + + +/** + * PP factory with segType, eta and et dependency + **/ +template<typename procedure_t> +procedure_t* ppFactoryEtaEtDep(SegmentationType cSegType, + unsigned segIdx, + float etaMin, float etaMax, + float etMin, float etMax, + MSG::Level lvl); + +/** + * PP factory with segType and eta dependency + **/ +template<typename procedure_t> +procedure_t* ppFactoryEtaDep(SegmentationType cSegType, + unsigned segIdx, + float etaMin, float etaMax, + MSG::Level lvl); + +/** + * PP factory with segType and et dependency + **/ +template<typename procedure_t> +procedure_t* ppFactoryEtDep(SegmentationType cSegType, + unsigned segIdx, + float etMin, float etMax, + MSG::Level lvl); + +/** + * PP factory with segType dependency + **/ +template<typename procedure_t> +procedure_t* ppFactoryDep(SegmentationType cSegType, + unsigned segIdx = 0, + MSG::Level lvl = MSG::INFO); + +/** + * PP random factory + **/ +PreProcessing::IPreProcessorVarDep* createRandomPP( + SegmentationType cSegType, + unsigned segIdx = 0, + MSG::Level lvl = MSG::INFO); + +/** + * Create PP of t + **/ +template<typename procedure_t> +procedure_t* createPP( + SegmentationType cSegType, + unsigned segIdx = 0, + MSG::Level lvl = MSG::INFO); + +/** + * Method dedicated for testing discriminator wrapper creation + **/ +template< + typename procedure_t, + EtaDependency etaDependency, + EtDependency etDependency, + SegmentationType segType +> +void createDiscrWrapper(const char* fileName, + const IPreProcWrapperCollection* ppWrapper = nullptr, + const std::vector<float> &etaDepBounderies = {0, 2.5}, + const std::vector<float> &etDepBounderies = + {0, std::numeric_limits<float>::infinity()} + ); + +/** + * @brief Write wrapper to file + **/ +void writeWrapperOnFile(const IProcWrapperBase &wrapper, + const char* fileName, MSG::Level); + +/** + * Creates eta/et independent neural network + * + * If goodStatus = false, returns a dummy neural network which always returns 0 + * as output for an pattern space of dimension size of 100. + * + * An old MC12 Zee x JF14 neural network is created otherwise. + **/ +template<bool goodStatus = true> +Discrimination::NNFeedForwardVarDep* createNN(SegmentationType cSegType, + unsigned segIdx); + +/** + * Creates eta dependent, et independent neural network + **/ +template<bool goodStatus = true> +Discrimination::NNFeedForwardVarDep* createEtaDepNN(SegmentationType cSegType, + unsigned segIdx, + float etaMin, float etaMax); + +/** + * Creates eta independent, et dependent neural network + **/ +template<bool goodStatus = true> +Discrimination::NNFeedForwardVarDep* createEtDepNN( + SegmentationType cSegType, + unsigned segIdx, + float etMin, float etMax); + +/** + * Creates eta dependent, et dependent neural network + **/ +template<bool goodStatus = true> +Discrimination::NNFeedForwardVarDep* createEtaEtDepNN( + SegmentationType cSegType, + unsigned segIdx, + float etaMin, float etaMax, + float etMin, float etMax); + +/** + * Method dedicated for testing threshold wrapper creation + **/ +template< + typename procedure_t, + EtaDependency etaDependency, + EtDependency etDependency +> +void createThresWrapper(const char* fileName, + const std::vector<float> &etaDepBounderies = {0, 2.5}, + const std::vector<float> &etDepBounderies = + {0, std::numeric_limits<float>::infinity()}, + float thresValue = 0 + ); + +Discrimination::UniqueThresholdVarDep* createThres(float thresValue); +Discrimination::UniqueThresholdVarDep* createEtaDepThres(float etaMin, float etaMax, + float thresValue); +Discrimination::UniqueThresholdVarDep* createEtDepThres(float etMin, float etMax, + float thresValue); +Discrimination::UniqueThresholdVarDep* createEtaEtDepThres( + float etaMin, float etaMax, + float etMin, float etMax, + float thresValue); + +std::vector< std::vector<unsigned> > segmentationEntries = +{ + { 100 }, + { 100, (unsigned)(TrackPatternsHolder::numberOfPatterns()) }, + { 100, (unsigned)(TrackPatternsHolder::numberOfPatterns()), 10 }, + { 88, 12, (unsigned)(TrackPatternsHolder::numberOfPatterns()), 10 }, + { 8, 64, 8, 8, 4, 4, 4, (unsigned)(TrackPatternsHolder::numberOfPatterns()), 10 } +}; + +// ============================================================================= +int main( /*int argc, char* argv[]*/){ + +#if !defined(XAOD_STANDALONE) && !defined(RINGER_STANDALONE) + const float GeVf = GeV; +#endif + + msg.setLevel(MSG::DEBUG); + + // Eta and Et dependency bounderies: + const std::vector<float> etaIndepBounderies = {0, 2.5}; + const std::vector<float> etaDepBounderies = + {0, .1, .6, 1.15, 1.37, 1.52, 1.81, 2.01, 2.37, 2.47, 2.5}; + + const std::vector<float> etIndepBounderies = {0, std::numeric_limits<float>::infinity()}; + const std::vector<float> etDepBounderies = +#if !defined(XAOD_STANDALONE) && !defined(RINGER_STANDALONE) + {0, 5*GeVf, 10*GeVf, 15*GeVf, 20*GeVf, 30*GeVf, 40*GeVf, 50*GeVf, 60*GeVf, 70*GeVf, 80*GeVf, //} +#else + {0, 5*1e3, 10*1e3, 15*1e3, 20*1e3, 30*1e3, 40*1e3, 50*1e3, 60*1e3, 70*1e3, 80*1e3, +#endif + std::numeric_limits<float>::infinity()}; + + msg << MSG::INFO << BREAKER << endreq; + msg << MSG::INFO << "Testing simple discriminator wrappers:" << endreq; + msg << MSG::INFO << BREAKER << endreq; + + // ---------------------------------------------------------------------------- + // Write simple discriminator using interface (without using normalization) + // ---------------------------------------------------------------------------- + // Create independent and non segmented wrapper. + // Test it allocating all possible permutations of eta/et dependency. + // No pre-processings available. + // Write it as "basicWrapper" + createDiscrWrapper<Discrimination::IDiscriminatorVarDep, + EtaIndependent, + EtIndependent, + NoSegmentation >("basicWrapper.root"); + msg << MSG::INFO << BREAKER << endreq; + + // Create eta dependent and non segmented wrapper. + // Test it allocating all possible permutations of eta/et dependency. + // No pre-processings available. + // Write it as "basicEtaDepWrapper" + createDiscrWrapper<Discrimination::IDiscriminatorVarDep, + EtaDependent, + EtIndependent, + NoSegmentation >("basicEtaDepWrapper.root", + nullptr, + etaDepBounderies); + msg << MSG::INFO << BREAKER << endreq; + + // Create Et dependent and non segmented wrapper. + // Test it allocating all possible permutations of eta/et dependency. + // No pre-processings available. + // Write it as "basicEtDepWrapper" + createDiscrWrapper<Discrimination::IDiscriminatorVarDep, + EtaIndependent, + EtDependent, + NoSegmentation >("basicEtDepWrapper.root", + nullptr, + etaIndepBounderies, + etDepBounderies); + msg << MSG::INFO << BREAKER << endreq; + + // Create eta, Et dependent and non segmented wrapper. + // Test it allocating all possible permutations of eta/et dependency. + // No pre-processings available. + // Write it as "basicEtDepWrapper" + createDiscrWrapper<Discrimination::IDiscriminatorVarDep, + EtaDependent, + EtDependent, + NoSegmentation >("basicEtaEtDepWrapper.root", + nullptr, + etaDepBounderies, + etDepBounderies); + + // Turn off the messages: + msg.setLevel(MSG::ERROR); + msg << MSG::INFO << BREAKER << endreq; + msg << MSG::INFO << "Testing creation of badly configured wrappers:" << endreq; + msg << MSG::INFO << BREAKER << endreq; + // -------------------------- END --- END --- END ----------------------------- + + // ---------------------------------------------------------------------------- + // This block shoudln't work + // ---------------------------------------------------------------------------- + // Create independent and non segmented wrapper. + // Test it allocating all possible permutations of eta/et dependency. + // No pre-processings available. + // It shouldn't be written because its eta size is different from unit. + createDiscrWrapper<Discrimination::IDiscriminatorVarDep, + EtaIndependent, + EtIndependent, + NoSegmentation >("shouldntWrite.root", + nullptr, + etaDepBounderies); + msg << MSG::INFO << BREAKER << endreq; + + // Create independent and non segmented wrapper. + // Test it allocating all possible permutations of eta/et dependency. + // No pre-processings available. + // It shouldn't be written because its eta size is different from unit. + createDiscrWrapper<Discrimination::IDiscriminatorVarDep, + EtaIndependent, + EtIndependent, + NoSegmentation >("shouldntWrite.root", + nullptr, + etaIndepBounderies, + etDepBounderies); + msg.setLevel(MSG::DEBUG); + msg << MSG::INFO << BREAKER << endreq; + msg << MSG::INFO << "Creating PP wrappers:" << endreq; + msg << MSG::INFO << BREAKER << endreq; + // ---------------------------------------------------------------------------- + + // ---------------------------------------------------------------------------- + // Start testing pre-processings + // ---------------------------------------------------------------------------- + // Create eta, Et dependent and non segmented pp wrapper. + // Test it allocating all possible permutations of seg/eta/et dependency. + // No pre-processings available. + // Write it as "basicPPWrapper" + auto *basicPPWrapper = createPPWrapper<PreProcessing::IPreProcessorVarDep, + EtaIndependent, + EtIndependent, + NoSegmentation >("basicPPWrapper.root"); + msg << MSG::INFO << BREAKER << endreq; + + auto *basicEtaDepPPWrapper = createPPWrapper<PreProcessing::IPreProcessorVarDep, + EtaDependent, + EtIndependent, + NoSegmentation >("basicEtaDepPPWrapper.root", + etaDepBounderies); + if (basicEtaDepPPWrapper) basicEtaDepPPWrapper->releaseMemory(); + delete basicEtaDepPPWrapper; + msg << MSG::INFO << BREAKER << endreq; + + auto *basicEtDepPPWrapper = createPPWrapper<PreProcessing::IPreProcessorVarDep, + EtaIndependent, + EtDependent, + NoSegmentation >("basicEtDepPPWrapper.root", + etaIndepBounderies, + etDepBounderies); + if (basicEtDepPPWrapper) basicEtDepPPWrapper->releaseMemory(); + delete basicEtDepPPWrapper; + msg << MSG::INFO << BREAKER << endreq; + + auto *basicEtaEtDepPPWrapper = createPPWrapper<PreProcessing::IPreProcessorVarDep, + EtaDependent, + EtDependent, + NoSegmentation >("basicEtEtaDepPPWrapper.root", + etaDepBounderies, + etDepBounderies); + if (basicEtaEtDepPPWrapper) basicEtaEtDepPPWrapper->releaseMemory(); + delete basicEtaEtDepPPWrapper; + msg << MSG::INFO << BREAKER << endreq; + + auto *basicEtaEtTrackCalDepPPWrapper = createPPWrapper<PreProcessing::IPreProcessorVarDep, + EtaDependent, + EtDependent, + TrackCalSegmentation >("basicEtEtaTrackCalDepPPWrapper.root", + etaDepBounderies, + etDepBounderies); + if (basicEtaEtTrackCalDepPPWrapper) basicEtaEtTrackCalDepPPWrapper->releaseMemory(); + delete basicEtaEtTrackCalDepPPWrapper; + msg << MSG::INFO << BREAKER << endreq; + + auto *basicEtaEtTrackCalPatTypeDepPPWrapper = createPPWrapper<PreProcessing::IPreProcessorVarDep, + EtaDependent, + EtDependent, + TrackCalPatTypeSegmentation >("basicEtEtaTrackCalPatTypeDepPPWrapper.root", + etaDepBounderies, + etDepBounderies); + if (basicEtaEtTrackCalDepPPWrapper) basicEtaEtTrackCalPatTypeDepPPWrapper->releaseMemory(); + delete basicEtaEtTrackCalPatTypeDepPPWrapper; + msg << MSG::INFO << BREAKER << endreq; + + auto *basicEtaEtSectionDepPPWrapper = createPPWrapper<PreProcessing::IPreProcessorVarDep, + EtaDependent, + EtDependent, + TrackCalJointSections >("basicEtaEtSectionDepPPWrapper.root", + etaDepBounderies, + etDepBounderies); + if (basicEtaEtSectionDepPPWrapper) basicEtaEtSectionDepPPWrapper->releaseMemory(); + delete basicEtaEtSectionDepPPWrapper; + msg << MSG::INFO << BREAKER << endreq; + + auto *basicEtaEtLayerDepPPWrapper = createPPWrapper<PreProcessing::IPreProcessorVarDep, + EtaDependent, + EtDependent, + TrackCalJointLayers >("basicEtaEtLayerDepPPWrapper.root", + etaDepBounderies, + etDepBounderies); + msg << MSG::INFO << BREAKER << endreq; + + auto *basicNorm1Wrapper = createPPWrapper<PreProcessing::Norm::Norm1VarDep, + EtaIndependent, + EtIndependent, + NoSegmentation >("basicNorm1Wrapper.root"); + msg << MSG::INFO << BREAKER << endreq; + + auto *basicLayerDepNorm1Wrapper = createPPWrapper<PreProcessing::Norm::Norm1VarDep, + EtaIndependent, + EtIndependent, + TrackCalJointLayers >("basicLayerDepNorm1Wrapper.root"); + msg << MSG::INFO << BREAKER << endreq; + + auto *basicNorm2Wrapper = createPPWrapper<PreProcessing::Norm::Norm2VarDep, + EtaIndependent, + EtIndependent, + TrackCalJointLayers >("basicNorm2Wrapper.root"); + if (basicNorm2Wrapper) basicNorm2Wrapper->releaseMemory(); + delete basicNorm2Wrapper; + msg << MSG::INFO << BREAKER << endreq; + + auto *basicSqrtWrapper = createPPWrapper<PreProcessing::Norm::SqrtVarDep, + EtaIndependent, + EtIndependent, + NoSegmentation >("basicSqrtWrapper.root"); + if (basicSqrtWrapper) basicSqrtWrapper->releaseMemory(); + delete basicSqrtWrapper; + msg << MSG::INFO << BREAKER << endreq; + + auto *basicConstantValueWrapper = createPPWrapper<PreProcessing::Norm::ConstantValueVarDep, + EtaIndependent, + EtIndependent, + NoSegmentation >("basicConstantValueWrapper.root"); + if (basicConstantValueWrapper) basicConstantValueWrapper->releaseMemory(); + delete basicConstantValueWrapper; + msg << MSG::INFO << BREAKER << endreq; + + auto *basicMevToGevWrapper = createPPWrapper<PreProcessing::Norm::MevToGevVarDep, + EtaIndependent, + EtIndependent, + NoSegmentation >("basicMevToGevWrapper.root"); + if (basicMevToGevWrapper) basicMevToGevWrapper->releaseMemory(); + delete basicMevToGevWrapper; + msg << MSG::INFO << BREAKER << endreq; + + auto *basicSequentialWrapper = createPPWrapper<PreProcessing::Norm::SequentialVarDep, + EtaIndependent, + EtIndependent, + NoSegmentation >("basicSequentialWrapper.root"); + if (basicSequentialWrapper) basicSequentialWrapper->releaseMemory(); + delete basicSequentialWrapper; + msg << MSG::INFO << BREAKER << endreq; + + auto *basicSpherizationWrapper = createPPWrapper<PreProcessing::Norm::SpherizationVarDep, + EtaIndependent, + EtIndependent, + NoSegmentation >("basicSpherizationWrapper.root"); + if (basicSpherizationWrapper) basicSpherizationWrapper->releaseMemory(); + delete basicSpherizationWrapper; + msg << MSG::INFO << BREAKER << endreq; + + auto *basicMinMaxWrapper = createPPWrapper<PreProcessing::Norm::MinMaxVarDep, + EtaIndependent, + EtIndependent, + NoSegmentation >("basicMinMaxWrapper.root"); + if (basicMinMaxWrapper) basicMinMaxWrapper->releaseMemory(); + delete basicMinMaxWrapper; + // -------------------------- END --- END --- END ----------------------------- + + msg << MSG::INFO << BREAKER << endreq; + msg << MSG::INFO << "Creating discriminator with PP wrappers:" << endreq; + msg << MSG::INFO << BREAKER << endreq; + + // ---------------------------------------------------------------------------- + // Write discriminators with pre-processings + // ---------------------------------------------------------------------------- + // Create Eta, Et dependent and non segmented wrapper. + // Test it allocating all possible permutations of eta/et dependency. + // PP available {Unspecialized Norm1}. + // Write it as "randomNorm1DiscrWrapper.root" + IPreProcWrapperCollection randomNorm1PP = {basicPPWrapper}; + createDiscrWrapper<Discrimination::IDiscriminatorVarDep, + EtaDependent, + EtDependent, + NoSegmentation >("randomNorm1PPDiscrWrapper.root", + &randomNorm1PP, + etaDepBounderies, + etDepBounderies); + msg << MSG::INFO << BREAKER << endreq; + + // Create Eta, Et dependent and non segmented wrapper. + // Test it allocating all possible permutations of eta/et dependency. + // PP available {Unspecialized}. + // Write it as "randomDepPPrandomDepPP" + IPreProcWrapperCollection randomDepPPrandomDepPP = { + basicEtaEtLayerDepPPWrapper, basicEtaEtLayerDepPPWrapper + }; + createDiscrWrapper<Discrimination::IDiscriminatorVarDep, + EtaDependent, + EtDependent, + NoSegmentation >("randomDepPPrandomDepPPDiscrWrapper.root", + &randomDepPPrandomDepPP, + etaDepBounderies, + etDepBounderies); + // ---------------------------------------------------------------------------- + + msg << MSG::INFO << BREAKER << endreq; + msg << MSG::INFO << "Creating segmented discriminator with PP wrappers:" << endreq; + msg << MSG::INFO << BREAKER << endreq; + + // ---------------------------------------------------------------------------- + // Write segmented discriminators with pre-processings + // ---------------------------------------------------------------------------- + // Create Eta, Et dependent and segmented wrapper. + // Test it allocating all possible permutations of eta/et dependency. + // PP available {Unspecialized Unspecialized}. + // Write it as "randomDepPPrandomDepPPDiscrSegmentedWrapper" + createDiscrWrapper<Discrimination::IDiscriminatorVarDep, + EtaDependent, + EtDependent, + TrackCalJointLayers >("randomDepPPrandomDepPPDiscrSegmentedWrapper.root", + &randomDepPPrandomDepPP, + etaDepBounderies, + etDepBounderies); + msg << MSG::INFO << BREAKER << endreq; + // -------------------------- END --- END --- END ----------------------------- + + msg << MSG::INFO << BREAKER << endreq; + msg << MSG::INFO << "Creating specialized discriminator:" << endreq; + msg << MSG::INFO << BREAKER << endreq; + + // ---------------------------------------------------------------------------- + // Write specialized discriminator wrapper with no pre-processings + // ---------------------------------------------------------------------------- + createDiscrWrapper<Discrimination::NNFeedForwardVarDep, + EtaIndependent, + EtIndependent, + NoSegmentation >("NNWrapper.root"); + msg << MSG::INFO << BREAKER << endreq; + + createDiscrWrapper<Discrimination::NNFeedForwardVarDep, + EtaDependent, + EtDependent, + TrackCalJointLayers >("FullDepNNWrapper.root", + {}, + etaDepBounderies, + etDepBounderies); + // -------------------------- END --- END --- END ----------------------------- + + msg << MSG::INFO << BREAKER << endreq; + msg << MSG::INFO << "Creating specialized discriminator with PP wrappers:" << endreq; + msg << MSG::INFO << BREAKER << endreq; + + // ---------------------------------------------------------------------------- + // Write specialized discriminator wrapper with specialized pre-processings + // ---------------------------------------------------------------------------- + IPreProcWrapperCollection basicNorm1WrapperVec = {basicNorm1Wrapper}; + createDiscrWrapper<Discrimination::NNFeedForwardVarDep, + EtaIndependent, + EtIndependent, + NoSegmentation >("Norm1NNWrapper.root", &basicNorm1WrapperVec); + msg << MSG::INFO << BREAKER << endreq; + + IPreProcWrapperCollection fullDepWrapperVec0 = {basicLayerDepNorm1Wrapper}; + createDiscrWrapper<Discrimination::NNFeedForwardVarDep, + EtaDependent, + EtDependent, + TrackCalJointLayers >("Norm1FullDepNNWrapper.root", + &fullDepWrapperVec0, + etaDepBounderies, + etDepBounderies); + msg << MSG::INFO << BREAKER << endreq; + + IPreProcWrapperCollection fullDepWrapperVec = {basicLayerDepNorm1Wrapper, basicLayerDepNorm1Wrapper}; + createDiscrWrapper<Discrimination::NNFeedForwardVarDep, + EtaDependent, + EtDependent, + TrackCalJointLayers >("Norm1Norm1FullDepNNWrapper.root", + &fullDepWrapperVec, + etaDepBounderies, + etDepBounderies); + // -------------------------- END --- END --- END ----------------------------- + + msg << MSG::INFO << BREAKER << endreq; + msg << MSG::INFO << "Creating thresholds:" << endreq; + msg << MSG::INFO << BREAKER << endreq; + + // ---------------------------------------------------------------------------- + // Write thresholds + // ---------------------------------------------------------------------------- + createThresWrapper<Discrimination::IThresholdVarDep, + EtaIndependent, + EtIndependent >("basicThres.root"); + msg << MSG::INFO << BREAKER << endreq; + + createThresWrapper<Discrimination::IThresholdVarDep, + EtaDependent, + EtIndependent >("basicEtaDepThres.root", + etaDepBounderies); + msg << MSG::INFO << BREAKER << endreq; + + createThresWrapper<Discrimination::IThresholdVarDep, + EtaIndependent, + EtDependent >("basicEtDepThres.root", + etaIndepBounderies, + etDepBounderies); + msg << MSG::INFO << BREAKER << endreq; + + createThresWrapper<Discrimination::IThresholdVarDep, + EtaDependent, + EtDependent >("basicEtaEtDepThres.root", + etaDepBounderies, + etDepBounderies); + // -------------------------- END --- END --- END ----------------------------- + + msg << MSG::INFO << BREAKER << endreq; + msg << MSG::INFO << "Creating specialized thresholds:" << endreq; + msg << MSG::INFO << BREAKER << endreq; + + // ---------------------------------------------------------------------------- + // Write specialized thresholds + // ---------------------------------------------------------------------------- + createThresWrapper<Discrimination::UniqueThresholdVarDep, + EtaIndependent, + EtIndependent >("uniqueThres.root"); + msg << MSG::INFO << BREAKER << endreq; + + createThresWrapper<Discrimination::UniqueThresholdVarDep, + EtaDependent, + EtIndependent >("uniqueEtaDepThres.root", + etaDepBounderies); + msg << MSG::INFO << BREAKER << endreq; + + createThresWrapper<Discrimination::UniqueThresholdVarDep, + EtaIndependent, + EtDependent >("uniqueEtDepThres.root", + etaIndepBounderies, + etDepBounderies); + msg << MSG::INFO << BREAKER << endreq; + + createThresWrapper<Discrimination::UniqueThresholdVarDep, + EtaDependent, + EtDependent >("uniqueEtaEtDepThres.root", + etaDepBounderies, + etDepBounderies); + // -------------------------- END --- END --- END ----------------------------- + + + // ---------------------------------------------------------------------------- + // Creating test discrimination wrappers: + // ---------------------------------------------------------------------------- + createDiscrWrapper<Discrimination::NNFeedForwardVarDep, + EtaIndependent, + EtIndependent, + NoSegmentation >("ElectronRingerDiscrTestLoose.root", &basicNorm1WrapperVec); + msg << MSG::INFO << BREAKER << endreq; + + createDiscrWrapper<Discrimination::NNFeedForwardVarDep, + EtaIndependent, + EtIndependent, + NoSegmentation >("ElectronRingerDiscrTestMedium.root", &basicNorm1WrapperVec); + msg << MSG::INFO << BREAKER << endreq; + + createDiscrWrapper<Discrimination::NNFeedForwardVarDep, + EtaIndependent, + EtIndependent, + NoSegmentation >("ElectronRingerDiscrTestTight.root", &basicNorm1WrapperVec); + msg << MSG::INFO << BREAKER << endreq; + // -------------------------- END --- END --- END ----------------------------- + + // ---------------------------------------------------------------------------- + // Creating test threshold wrappers: + // ---------------------------------------------------------------------------- + createThresWrapper<Discrimination::UniqueThresholdVarDep, + EtaIndependent, + EtIndependent >("ElectronRingerThresTestLoose.root", + etaIndepBounderies, + etIndepBounderies, + 0.948 ); + msg << MSG::INFO << BREAKER << endreq; + + createThresWrapper<Discrimination::UniqueThresholdVarDep, + EtaIndependent, + EtIndependent >("ElectronRingerThresTestMedium.root", + etaIndepBounderies, + etIndepBounderies, + 0.2644 ); + msg << MSG::INFO << BREAKER << endreq; + + createThresWrapper<Discrimination::UniqueThresholdVarDep, + EtaIndependent, + EtIndependent >("ElectronRingerThresTestTight.root", + etaIndepBounderies, + etIndepBounderies, + 0.2826 ); + // -------------------------- END --- END --- END ----------------------------- + + msg << MSG::INFO << BREAKER << endreq; + msg << MSG::INFO << "Finished!" << endreq; + msg << MSG::INFO << BREAKER << endreq; + + return 0; +} + +// ============================================================================= +void writeWrapperOnFile(const IProcWrapperBase &wrapper, const char* fileName, + MSG::Level lvl) +{ + msg << lvl << "Writing to file!" << endreq; + + TFile wrapperFile(fileName, "RECREATE"); + auto wrapperDir = wrapperFile.GetDirectory(""); + + // Write wrapper on the file: + wrapper.write(wrapperDir, IOHelperFcns::makeIdxStr(0).c_str()); + + if ( msg.level() <= lvl ){ + wrapperDir->ls(); + } + + // Write and close file + wrapperFile.Write(); + wrapperFile.Close(); +} + +// ============================================================================= +template< + typename procedure_t, + EtaDependency etaDependency, + EtDependency etDependency, + SegmentationType segType +> +IPreProcWrapper* createPPWrapper(const char *fileName, + const std::vector<float> &etaDepBounderies, + const std::vector<float> &etDepBounderies) +{ + // Typedef to make things easier + typedef RingerProcedureWrapper<procedure_t, + etaDependency, + etDependency, + segType> wrapper_t; + + typedef typename RingerProcedureType<procedure_t>::procEnum_t procEnum_t; + + msg << MSG::INFO << "Attempting to create a RingerProcedureWrapper<" + << toStr(procedure_t::template procType<procEnum_t>() ) + << ((std::is_same<procedure_t,PreProcessing::IPreProcessorVarDep>::value)?",":"(VarDep),") + << toStr(etaDependency) << "," + << toStr(etDependency) << "," + << toStr(segType) << "> with file name: " << fileName << "." << endreq; + + unsigned etaDepProc = etaDepBounderies.size() - 1; + unsigned etDepProc = etDepBounderies.size() - 1; + + IPreProcWrapper *ret(nullptr); + + // Loop over variable dependencies + for ( unsigned uSegType = NoSegmentation; + uSegType < NSegmentations; + ++uSegType ) + { + SegmentationType cSegType = static_cast<SegmentationType>(uSegType); + //if ( segType == SegmentationType::TrackCalPatTypeSegmentation ) { + // continue; + //} + for ( unsigned uEtaDep = EtaIndependent; uEtaDep <= EtaDependent; ++uEtaDep ){ + EtaDependency etaDep = static_cast<EtaDependency>(uEtaDep); + for ( unsigned uEtDep = EtIndependent; uEtDep <= EtDependent; ++uEtDep ){ + EtDependency etDep = static_cast<EtDependency>(uEtDep); + + // Change message level accondingly if we are creating correct wrapper + // type + MSG::Level lvl(MSG::VERBOSE); + if ( cSegType == segType && + etaDep == etaDependency && + etDep == etDependency ) + { + lvl = MSG::INFO; + } + + + // The collection holder + typename wrapper_t::PPDepProcCollection ppCol( + numberOfSegments(cSegType), + std::vector< std::vector<procedure_t*> >( + etDepProc, std::vector<procedure_t*>(etaDepProc, + nullptr))); + + // Fill collection + for ( unsigned segDepIdx = 0; segDepIdx < numberOfSegments(cSegType); ++segDepIdx ){ + for ( unsigned etDepIdx = 0; etDepIdx < etDepProc; ++etDepIdx){ + // Get et bounderies: + float etMin(etDepBounderies[etDepIdx]), + etMax(etDepBounderies[etDepIdx+1]); + for ( unsigned etaDepIdx = 0; etaDepIdx < etaDepProc; ++etaDepIdx){ + // Get eta bounderies: + float etaMin(etaDepBounderies[etaDepIdx]), + etaMax(etaDepBounderies[etaDepIdx+1]); + + + // Fill collection: + if (etaDep) { + if (etDep) { + ppCol[segDepIdx][etDepIdx][etaDepIdx] = + ppFactoryEtaEtDep<procedure_t>(cSegType, + segDepIdx, + etaMin, + etaMax, + etMin, + etMax, + MSG::VERBOSE); + } else { + ppCol[segDepIdx][etDepIdx][etaDepIdx] = + ppFactoryEtaDep<procedure_t>(cSegType, + segDepIdx, + etaMin, + etaMax, + MSG::VERBOSE); + } + } else { + if (etDep) { + ppCol[segDepIdx][etDepIdx][etaDepIdx] = + ppFactoryEtDep<procedure_t>(cSegType, + segDepIdx, + etMin, + etMax, + MSG::VERBOSE); + } else { + ppCol[segDepIdx][etDepIdx][etaDepIdx] = + ppFactoryDep<procedure_t>(cSegType, + segDepIdx, + MSG::VERBOSE); + } + } + } + } + } // Finished looping and filling collection + + // Attempt to create a wrapper with filled collection: + try { + + msg << lvl << "Attempting to create wrapper with (" + << toStr(segType) << "," << toStr(etaDep) << "," << toStr(etDep) + << ") pre-processing" << endreq; + + //msg << lvl << ppCol << endreq; + + // Create wrapper: + auto wrapper = new wrapper_t(ppCol); + // Use dummy message stream: + wrapper->setMsgStream(&msg); + // Print wrapper: + wrapper->print(MSG::DEBUG); + + // If it succeed, write it into file: + writeWrapperOnFile(*wrapper, fileName, MSG::VERBOSE); + //IPreProcWrapperCollection ppWrapperCol = {wrapper}; + //IPreProcWrapper::writeCol( ppWrapperCol, fileName ); + + // We do not release memory for the wrapper, it will be given as a + // return parameter. + ret = wrapper; + + msg << lvl << "Succeed!" << endreq; + + } catch (const std::runtime_error &e) { + + msg << MSG::VERBOSE << "Couldn't create wrapper. Reason: " + << e.what() << endreq; + + // Release collection memory + for ( unsigned segDepIdx = 0; segDepIdx < numberOfSegments(cSegType); ++segDepIdx ){ + for ( unsigned etDepIdx = 0; etDepIdx < etDepProc; ++etDepIdx){ + for ( unsigned etaDepIdx = 0; etaDepIdx < etaDepProc; ++etaDepIdx){ + delete ppCol[segDepIdx][etDepIdx][etaDepIdx]; + ppCol[segDepIdx][etDepIdx][etaDepIdx] = nullptr; + } + } + } + } // Finished creating wrapper and handling possible errors + + } + } + } // Finished looping over segType/eta/et. + return ret; +} + +// ============================================================================= +template<typename procedure_t> +procedure_t* ppFactoryEtaEtDep(SegmentationType cSegType, + unsigned segIdx, + float etaMin, float etaMax, + float etMin, float etMax, + MSG::Level lvl) +{ + procedure_t* pp(nullptr); + if ( std::is_same<procedure_t,PreProcessing::IPreProcessorVarDep>::value ) + { + pp = reinterpret_cast<procedure_t*>(createRandomPP(cSegType, segIdx, lvl)); + } else { + pp = createPP<procedure_t>( cSegType, segIdx, lvl ); + } + pp->setEtaEtDep(etaMin, etaMax, etMin, etMax); + return pp; +} + +// ============================================================================= +template<typename procedure_t> +procedure_t* ppFactoryEtaDep(SegmentationType cSegType, + unsigned segIdx, + float etaMin, float etaMax, + MSG::Level lvl) +{ + procedure_t* pp(nullptr); + if ( std::is_same<procedure_t,PreProcessing::IPreProcessorVarDep>::value ) + { + pp = reinterpret_cast<procedure_t*>(createRandomPP(cSegType, segIdx, lvl)); + } else { + pp = createPP<procedure_t>( cSegType, segIdx, lvl ); + } + pp->setEtaDep(etaMin, etaMax); + return pp; +} + +// ============================================================================= +template<typename procedure_t> +procedure_t* ppFactoryEtDep(SegmentationType cSegType, + unsigned segIdx, + float etMin, float etMax, + MSG::Level lvl) +{ + procedure_t* pp(nullptr); + if ( std::is_same<procedure_t,PreProcessing::IPreProcessorVarDep>::value ) + { + pp = reinterpret_cast<procedure_t*>(createRandomPP(cSegType, segIdx, lvl)); + } else { + pp = createPP<procedure_t>( cSegType, segIdx, lvl ); + } + pp->setEtDep(etMin, etMax); + return pp; +} + +// ============================================================================= +template<typename procedure_t> +procedure_t* ppFactoryDep(SegmentationType cSegType, + unsigned segIdx, + MSG::Level lvl) +{ + if ( std::is_same<procedure_t,PreProcessing::IPreProcessorVarDep>::value ) + { + return reinterpret_cast<procedure_t*>(createRandomPP( cSegType, segIdx, lvl)); + } else { + return createPP<procedure_t>( cSegType, segIdx, lvl ); + } +} + +// ============================================================================= +PreProcessing::IPreProcessorVarDep* createRandomPP(SegmentationType cSegType, + unsigned segIdx, + MSG::Level lvl) +{ + static unsigned sequenceLoop = 0; + switch ( static_cast<PreProcessing::Type::PreProcessorTypes>(2+((sequenceLoop++)%7)) ) { + case PreProcessing::Type::Norm1: + msg << lvl << "Creating Norm1" << endreq; + return new PreProcessing::Norm::Norm1VarDep; + break; + case PreProcessing::Type::Norm2: + msg << lvl << "Creating Norm2" << endreq; + return new PreProcessing::Norm::Norm2VarDep; + break; + case PreProcessing::Type::Sqrt: + msg << lvl << "Creating Sqrt" << endreq; + return new PreProcessing::Norm::SqrtVarDep; + break; + case PreProcessing::Type::ConstantValue: + msg << lvl << "Creating ConstantValue" << endreq; + return new PreProcessing::Norm::ConstantValueVarDep(987); + break; + case PreProcessing::Type::Sequential: + msg << lvl << "Creating Sequential" << endreq; + return new PreProcessing::Norm::SequentialVarDep(100,.001); + break; + case PreProcessing::Type::Spherization: + { + msg << lvl << "Creating Spherization" << endreq; + auto std = new PreProcessing::Norm::SpherizationVarDep( + std::vector<float>( segmentationEntries[cSegType][segIdx], 21 ), + std::vector<float>( segmentationEntries[cSegType][segIdx], 61 ) + ); + return std; + break; + } + case PreProcessing::Type::MinMax: + { + msg << lvl << "Creating MinMax" << endreq; + auto minMax = new PreProcessing::Norm::MinMaxVarDep( + std::vector<float>( segmentationEntries[cSegType][segIdx], 11 ), + std::vector<float>( segmentationEntries[cSegType][segIdx], 92 ) + ); + return minMax; + break; + } + default: + throw std::runtime_error(std::string( "Couldn't create pre-processing." )); + } +} + +// ============================================================================= +template<typename procedure_t> +procedure_t* createPP(SegmentationType cSegType, unsigned segIdx, + MSG::Level /*lvl*/) +{ + if ( Ringer::is_same<procedure_t,PreProcessing::Norm::Norm1VarDep>::value ){ + return reinterpret_cast<procedure_t*>(new PreProcessing::Norm::Norm1VarDep); + } else if ( Ringer::is_same<procedure_t,PreProcessing::Norm::Norm2VarDep>::value ) { + return reinterpret_cast<procedure_t*>(new PreProcessing::Norm::Norm2VarDep); + } else if ( Ringer::is_same<procedure_t,PreProcessing::Norm::SqrtVarDep>::value ) { + return reinterpret_cast<procedure_t*>(new PreProcessing::Norm::SqrtVarDep); + } else if ( Ringer::is_same<procedure_t,PreProcessing::Norm::ConstantValueVarDep>::value ) { + return reinterpret_cast<procedure_t*>(new PreProcessing::Norm::ConstantValueVarDep(123)); + } else if ( Ringer::is_same<procedure_t,PreProcessing::Norm::MevToGevVarDep>::value ) { + return reinterpret_cast<procedure_t*>(new PreProcessing::Norm::MevToGevVarDep); + } else if ( Ringer::is_same<procedure_t,PreProcessing::Norm::SequentialVarDep>::value ) { + auto seq = new PreProcessing::Norm::SequentialVarDep(100,.001); + return reinterpret_cast<procedure_t*>(seq); + } else if ( Ringer::is_same<procedure_t,PreProcessing::Norm::SpherizationVarDep>::value ) { + auto std = new PreProcessing::Norm::SpherizationVarDep( + std::vector<float>( segmentationEntries[cSegType][segIdx], 21 ), + std::vector<float>( segmentationEntries[cSegType][segIdx], 61 ) + ); + return reinterpret_cast<procedure_t*>(std); + } else if ( Ringer::is_same<procedure_t,PreProcessing::Norm::MinMaxVarDep>::value ) { + auto minMax = new PreProcessing::Norm::MinMaxVarDep( + std::vector<float>( segmentationEntries[cSegType][segIdx], 11 ), + std::vector<float>( segmentationEntries[cSegType][segIdx], 92 ) + ); + return reinterpret_cast<procedure_t*>(minMax); + } else { + throw std::runtime_error(std::string("Unknown pre-processing type.")); + } +} + +// ============================================================================= +template< + typename procedure_t, + EtaDependency etaDependency, + EtDependency etDependency, + SegmentationType segType +> +void createDiscrWrapper(const char *fileName, + const IPreProcWrapperCollection* ppWrapperCol, + const std::vector<float> &etaDepBounderies, + const std::vector<float> &etDepBounderies) +{ + // Typedef to make things easier + typedef RingerProcedureWrapper<procedure_t, + etaDependency, + etDependency, + segType> wrapper_t; + + typedef typename RingerProcedureType<procedure_t>::procEnum_t procEnum_t; + + msg << MSG::INFO << "Attempting to create a RingerProcedureWrapper<" + << toStr(procedure_t::template procType<procEnum_t>() ) + << ((Ringer::is_same<procedure_t,Discrimination::IDiscriminatorVarDep>::value)?",":"(VarDep),") + << toStr(etaDependency) << "," + << toStr(etDependency) << "," + << toStr(segType) << "> with file name: " << fileName << "." << endreq; + + unsigned etaDepProc = etaDepBounderies.size() - 1; + unsigned etDepProc = etDepBounderies.size() - 1; + + // Loop over variable dependencies + for ( unsigned uEtaDep = EtaIndependent; uEtaDep <= EtaDependent; ++uEtaDep ){ + for ( unsigned uEtDep = EtIndependent; uEtDep <= EtDependent; ++uEtDep ){ + // The enumerations + EtaDependency etaDep = static_cast<EtaDependency>(uEtaDep); + EtDependency etDep = static_cast<EtDependency>(uEtDep); + + // Change message level accondingly if we are creating correct wrapper + // type + MSG::Level lvl(MSG::VERBOSE); + if ( etaDep == etaDependency && + etDep == etDependency ) + { + lvl = MSG::INFO; + } + + // The collection holder + typename wrapper_t::DiscrDepProcCollection discrCol(numberOfSegments(segType), + std::vector< std::vector<procedure_t*> >( + etDepProc, std::vector<procedure_t*>(etaDepProc, + nullptr))); + + // Fill collection + for ( unsigned segDepIdx = 0; segDepIdx < numberOfSegments(segType); ++segDepIdx ){ + for ( unsigned etDepIdx = 0; etDepIdx < etDepProc; ++etDepIdx){ + // Get et bounderies: + float etMin(etDepBounderies[etDepIdx]), + etMax(etDepBounderies[etDepIdx+1]); + for ( unsigned etaDepIdx = 0; etaDepIdx < etaDepProc; ++etaDepIdx){ + // Get eta bounderies: + float etaMin(etaDepBounderies[etaDepIdx]), + etaMax(etaDepBounderies[etaDepIdx+1]); + + // Fill collection: + if (etaDep) { + if (etDep) { + discrCol[segDepIdx][etDepIdx][etaDepIdx] = createEtaEtDepNN( + segType, segDepIdx, + etaMin, + etaMax, + etMin, + etMax); + } else { + discrCol[segDepIdx][etDepIdx][etaDepIdx] = createEtaDepNN( + segType, segDepIdx, + etaMin, + etaMax); + } + } else { + if (etDep) { + discrCol[segDepIdx][etDepIdx][etaDepIdx] = createEtDepNN( + segType, segDepIdx, + etMin, + etMax); + } else { + discrCol[segDepIdx][etDepIdx][etaDepIdx] = createNN(segType, segDepIdx); + } + } + } + } + } // Finished looping and filling collection + + // Attempt to create a wrapper with filled collection: + try { + + msg << lvl << "Attempting to create wrapper with (" + << toStr(etaDep) << "," << toStr(etDep) << ") discriminator" + << endreq; + + wrapper_t* wrapper(nullptr); + // Create wrapper: + if ( !ppWrapperCol || ppWrapperCol->empty() ){ + wrapper = new wrapper_t(discrCol); + } else { + wrapper = new wrapper_t(*ppWrapperCol, discrCol); + } + // Use dummy message stream: + wrapper->setMsgStream(&msg); + // Print wrapper: + wrapper->print(MSG::DEBUG); + + // Delete file if it already exists: + IOHelperFcns::deleteFile( fileName ); + + // Create IDiscrWrapperCollection and write it: + //writeWrapperOnFile(*wrapper, fileName, MSG::VERBOSE); + IDiscrWrapperCollection discrWrapperCol = {wrapper}; + IDiscrWrapper::writeCol(discrWrapperCol, fileName); + + // Add file io information: + AsgElectronRingerSelector::IOConfStruct ioConf; + ioConf.useBLOutliers = true; + AsgElectronRingerSelector::writeConf( fileName, ioConf ); + AsgElectronRingerSelector::printConf(ioConf, &msg ); + + // Release wrapper memory: + //wrapper->releaseMemory(); + //delete wrapper; + + msg << lvl << "Succeed!" << endreq; + + } catch (const std::runtime_error &e) { + + msg << MSG::VERBOSE << "Couldn't create wrapper. Reason: " + << e.what() << endreq; + + // Release collection memory + for ( unsigned segDepIdx = 0; segDepIdx < numberOfSegments(segType); ++segDepIdx ){ + for ( unsigned etDepIdx = 0; etDepIdx < etDepProc; ++etDepIdx){ + for ( unsigned etaDepIdx = 0; etaDepIdx < etaDepProc; ++etaDepIdx){ + delete discrCol[segDepIdx][etDepIdx][etaDepIdx]; + discrCol[segDepIdx][etDepIdx][etaDepIdx] = nullptr; + } + } + } + } // Finished creating wrapper and handling possible errors + + } + } // Finished looping over eta/et. +} + +// ============================================================================= +template<bool goodStatus> +Discrimination::NNFeedForwardVarDep* createNN(SegmentationType cSegType, + unsigned segIdx) +{ + if ( goodStatus ){ + switch (cSegType) + { + case SegmentationType::NoSegmentation: + { + std::vector<unsigned int> nodes = {100,16,1}; + std::vector<float> weights = {0.028688,-0.062593,-0.110670,-0.109672,-0.224397,-0.113062,0.039054,-0.529236,-2.888686,-0.605837,-0.994450,0.006954,-0.056765,-0.031750,-0.503685,-0.494298,-0.221056,0.400392,-0.531358,-0.629313,0.089911,-1.007010,-0.629093,-0.716350,-0.273729,-0.826810,-0.214472,-0.975512,-0.396733,-0.003727,-0.276535,-0.056521,0.186771,-0.077535,-0.058493,-0.245285,-0.982163,-0.797398,-0.073127,-0.115995,-0.007802,-1.154354,-0.132477,-0.594071,0.124951,-0.115163,-0.164945,-0.095116,-0.324021,-0.066871,-0.051343,-0.719736,-0.064108,0.144933,-0.404720,-0.052662,-0.203778,-0.495595,0.025789,-0.115119,-0.153406,-1.088269,-1.284559,0.007588,-0.376025,-0.218487,-0.014306,0.037344,-0.159262,0.033259,-0.300734,-0.328634,-1.224337,0.318360,-0.545602,0.263710,-0.034113,-0.121256,-0.271094,-0.406514,0.282135,0.078523,0.364275,-0.856901,-0.442518,-0.008571,-0.030869,0.089742,-1.372179,0.552057,-0.457882,-0.200123,-1.674263,-0.621302,-0.498098,-0.299907,-1.576183,0.046803,-0.091531,-0.096722,1.568295,0.231312,-0.640472,-3.136615,-2.410643,-13.031759,33.412286,-8.683243,1.475885,0.969468,0.017705,0.295497,0.938570,-0.365949,-1.487067,-1.581031,-7.219507,-5.611233,-2.667463,-3.709057,-0.538870,-0.711813,0.433348,-0.594230,-0.844310,-1.288160,-0.741892,-1.830146,-0.325822,-1.631410,-1.751475,-1.720901,-0.898951,-13.288799,-1.933127,-3.081192,-6.221801,-1.104714,-3.841797,-3.328604,-5.193892,-0.808612,-0.796501,-0.288802,7.600919,-0.329103,-2.054659,-0.080070,-7.080676,-0.922352,-4.327209,-3.596929,-1.918411,-3.564654,3.974327,-2.244009,-4.969694,-8.027518,-6.920259,-8.452600,-2.703256,-6.863256,-3.882042,-6.151130,-26.816965,-94.151225,-14.878026,-9.943644,-37.491924,-46.556123,-1.433659,-2.125969,0.698555,1.188699,-1.000490,-0.471744,-0.684885,-4.686223,11.678164,-9.628196,12.210666,-2.342332,-1.902629,-1.247211,-1.661623,-1.388010,-1.868174,-1.932632,-1.209638,2.603166,0.492622,1.332110,-1.645321,1.261750,-4.505736,0.740274,-0.668193,-0.267155,0.334967,3.742837,0.740339,-0.073527,-0.324355,-0.064818,-0.051392,0.094401,0.154956,-0.067873,0.440951,0.138248,-0.572323,-0.010880,-0.047062,-0.180201,-0.479383,-0.188006,-0.424571,-0.457951,-0.638549,-0.298774,-0.708894,-0.359068,-0.192183,-1.064735,-0.140763,-0.518375,0.131144,-0.282072,-0.277306,-0.393560,0.307943,-0.087220,-0.106205,-0.135257,-0.082795,-0.240611,-0.450951,-0.439167,-0.101002,-0.123107,-0.063369,-0.086694,-0.493826,0.086611,0.178572,-0.215764,-0.120014,0.351601,-0.273922,0.485342,-0.132585,0.111573,-0.076256,0.067623,-0.109474,0.206897,-0.093580,-0.016174,0.008848,-0.061735,0.014456,-0.013979,-0.631338,0.191005,-0.191373,-0.267904,0.389943,0.057172,-0.028360,-0.138402,-0.162590,-0.098487,-0.271238,-0.218225,0.084942,-0.490171,-0.076231,-0.104584,-0.075355,-0.206857,1.956858,1.263630,-1.606997,0.258611,-0.221201,-0.126122,0.055639,-0.052784,0.267501,-0.976859,0.077316,-0.236870,-1.100098,-0.340871,0.266472,-0.033575,-1.106904,-0.048352,-0.034147,-0.027628,-0.907428,-0.114443,0.639170,-5.046371,2.117636,12.534221,4.109699,1.002582,-6.121682,-1.300009,0.000709,0.001165,-0.206458,0.354377,-3.450948,3.458475,17.388021,19.380078,5.190390,4.633401,9.791459,1.829216,29.071445,2.496838,3.528770,5.186754,1.097003,1.898567,1.687048,1.712853,18.696546,2.422834,2.972473,1.986865,1.978833,2.538006,8.025286,10.573317,16.791273,3.481498,3.077972,1.144574,0.829633,5.784941,3.109096,7.093387,53.518546,45.052680,9.139784,13.222146,2.750695,3.407295,6.188783,3.406966,-23.018505,2.266498,5.030206,8.614132,5.835313,5.992136,7.205853,6.317150,0.141573,7.108026,-93.605318,-111.675271,2.469222,2.625255,1.189963,0.092941,1.280597,0.471347,-0.712683,-0.367087,0.920240,-0.766278,0.996182,10.240765,8.472205,8.538664,0.794154,3.866253,2.359055,2.030608,1.149638,2.585729,2.002529,1.638214,1.052308,-1.465720,-1.196036,-3.249994,1.560568,-20.990768,0.155179,-1.015941,0.794045,-0.179825,-19.952022,1.910052,1.051576,0.060563,0.031857,0.070955,0.007167,0.378318,0.023833,0.649955,4.275588,0.027542,0.627095,-0.024055,0.048692,0.653087,-0.136869,0.853252,0.711888,0.746423,0.917728,1.660293,0.943031,0.591943,-0.978663,1.058206,0.267564,-0.642447,0.024186,0.398969,-0.004766,0.372238,0.077377,-0.042264,0.054782,0.081330,0.037063,0.236487,0.187889,-0.077143,-0.182055,-0.012978,-0.179301,-0.157928,0.005376,-0.020677,5.841787,0.412119,0.708508,0.070569,-0.645499,-0.112014,0.125128,0.024352,0.703745,0.062582,0.280714,0.045282,0.155499,0.189150,0.299881,0.054184,-0.049919,0.111692,0.026760,0.135167,0.270543,0.148473,-0.015246,-0.100352,0.165556,0.170405,0.228728,0.319828,0.835729,-0.198271,0.439356,-0.002287,0.066184,0.327133,0.233683,0.278432,-3.083528,-1.286595,1.464285,0.698704,0.024064,0.079657,0.007752,0.066683,0.711628,-0.769123,0.203221,0.116553,0.573138,0.035675,-0.406918,0.183639,-1.605187,-0.058066,0.070112,0.147746,-2.392498,-2.745882,1.263215,0.181240,0.343909,-3.675908,4.112136,0.180781,-4.340636,-2.242731,-2.255890,-2.695255,-1.605709,0.047641,-0.994458,5.288881,3.168465,4.077442,1.480216,1.922621,-1.683723,1.113707,0.608307,1.749436,1.209098,3.086876,0.551001,-1.049812,0.239036,-1.736003,-1.371147,29.087469,0.396884,1.155119,4.757856,-0.492357,-2.349446,0.096400,-3.124810,0.448417,0.128918,0.592998,0.331566,0.300982,0.001730,0.269922,-3.360424,-15.594998,-0.537339,9.110059,-2.362906,-1.938478,-1.143943,-0.152321,-2.628727,-0.891215,-1.643069,-4.414059,-10.897783,-6.394373,0.097377,-11.008657,-2.151860,-11.556536,-16.268739,-31.602494,-11.505709,-1.876816,-6.329613,1.669843,0.571898,-2.337885,-1.365757,-0.944771,0.970493,-0.442543,0.995064,-3.749592,-5.691184,-4.139481,-0.788088,4.890539,2.398736,2.532407,1.881680,1.500637,0.623273,-30.264643,9.645718,10.514421,8.475971,0.121070,2.874658,4.640818,1.437012,1.848824,-2.715429,-0.324435,0.844252,6.818916,2.389538,0.107453,0.263178,4.235293,0.609985,1.110795,0.093694,-1.311855,2.269984,5.058177,1.137608,1.277659,-0.033944,-0.164212,-2.001901,-7.228751,-1.036251,1.976840,-2.504326,4.353166,-1.511555,-1.452743,-0.663433,-0.976442,-0.693744,0.198484,-0.407872,-0.506523,-0.590362,4.043677,6.314065,0.126364,-0.194009,-16.236056,4.068819,1.224119,1.543314,-0.128289,1.302668,1.465868,1.603645,-0.031988,0.175951,0.158367,0.120493,-0.004462,7.682568,0.469458,-0.000680,-7.551085,0.606771,0.200480,1.057136,0.555353,4.748190,0.039710,0.263192,0.593023,3.582425,1.947296,0.517452,-0.076818,0.682754,0.357066,0.075757,-0.007521,0.317154,1.510008,0.580695,5.009438,0.728683,-0.267382,2.371758,0.446246,-0.167985,-7.106345,-0.097237,3.584461,4.274035,4.095569,-1.738810,-6.914329,-3.810478,1.208624,1.140845,2.095668,0.575353,0.626909,-2.226223,-2.056425,-1.312785,-1.551202,-2.271757,-0.504885,-0.277969,-0.431348,2.347458,-0.027946,-0.392081,-0.388553,8.689883,4.189324,-0.862448,-5.671942,-1.845137,9.754921,-10.775090,72.349025,6.208780,6.869102,0.123899,0.383385,0.675272,-0.332477,-0.960122,-31.058836,-7.949740,-3.758648,7.108799,11.528299,8.149853,-0.615473,-0.439979,-0.677038,-0.723783,29.196677,-0.859601,-1.499570,-0.576167,-1.667575,-1.829887,-1.398700,-0.515988,41.517160,0.713953,30.545081,-6.188533,-7.091922,-9.414879,-1.904592,-7.658521,-2.284183,-7.772925,21.863106,20.947830,-1.751241,13.477022,-7.682248,-8.168043,-20.637880,10.466483,0.089507,-5.340472,-3.344616,-8.410060,-2.282409,-6.121732,-6.918085,-6.073172,-11.025504,-8.407571,-6.208835,-4.529416,-5.678833,-5.714158,-1.018523,19.611186,-2.653425,-1.897749,-3.690523,0.166875,-0.394813,0.722076,-0.189588,-0.930066,0.943887,-0.845358,-5.028208,-4.240671,-15.165471,-0.622049,-3.294203,1.575702,3.755827,-1.110502,-1.434140,-1.507328,-12.166484,2.660743,2.035036,0.891480,2.444064,-2.451179,-1.473334,0.802695,-0.310561,0.390210,0.371984,-15.530832,1.328315,-6.511445,-1.310474,1.158307,20.504969,0.870710,1.396723,0.227466,-1.831463,-2.830913,-5.143690,-0.271427,-0.426230,-0.240882,-0.115466,0.874429,1.650408,4.967956,1.912887,2.400235,1.008770,2.862430,1.166314,0.933473,2.330710,2.444949,1.830853,1.049244,2.607336,2.804982,3.107458,3.294002,3.170131,13.693583,76.926670,3.845448,23.346861,9.812383,2.391273,10.606641,1.963476,2.967598,1.526888,0.866287,4.209006,18.102486,0.533338,1.445390,0.872831,0.853834,0.273607,1.321337,0.123892,0.412314,0.355130,-4.645920,0.283349,-6.881706,0.901227,-4.195997,0.916571,-0.388821,0.565599,1.117080,0.812389,5.323900,1.317251,0.320280,0.308174,-26.829184,1.149731,1.275011,2.000144,-1.470072,-0.767747,0.202361,-1.587088,1.155752,1.098314,1.257929,-3.200987,0.668693,4.033012,0.999027,-1.208894,1.632769,1.014471,0.723843,2.399647,-2.593154,-9.382237,1.349194,-0.021662,-3.713423,-1.746662,-6.558139,-1.554877,-2.434262,1.989675,0.249551,-2.443816,-3.779906,-2.636414,-1.277373,-4.628381,-0.505515,-3.990376,-11.436412,-2.227947,-2.823871,-6.863975,-1.281835,-3.663759,-0.310102,0.149827,2.020108,2.642968,1.497769,3.041259,2.015148,1.067337,-0.013860,0.981229,0.631989,1.125228,0.752725,-1.872923,0.565742,0.566382,0.054049,0.409526,-0.925388,-0.245978,-0.132565,-0.171097,-3.199698,2.047109,-2.335864,-0.230441,-3.463833,-2.292295,-0.984754,-0.119444,-0.079340,-1.964507,-0.163262,-0.044391,-3.299204,-1.317512,-1.653288,-360.611655,-0.792871,-1.526987,-5.112393,-0.545486,-8.757870,-0.044763,0.033397,-1.166951,-3.586482,-3.397790,-0.226581,-0.680198,-0.470130,-0.421405,-3.563391,-0.720706,0.001545,-2.030093,-3.074116,-0.915965,-2.567866,0.300819,-2.735884,-2.183676,4.409152,0.644427,-0.628248,-3.267413,-3.548809,-4.949955,3.555070,8.891552,3.580243,1.056337,-1.324928,-1.612563,-0.576405,-0.681977,2.571778,1.858078,1.474100,0.776536,3.534101,0.802548,-0.213475,0.434609,-4.311330,-1.056947,0.292802,-0.536683,-9.690235,-3.111939,-0.113073,5.260060,0.512237,1.040290,34.479682,2.148753,-3.126262,-2.802152,-0.047654,-0.012042,1.508002,5.959009,1.083541,1.424925,-1.638421,-3.557558,-1.322984,4.979366,2.018343,1.150012,1.216431,-0.280425,2.333079,1.243301,0.841088,1.886149,1.498563,1.629537,3.290616,1.685732,2.013451,0.862097,1.742377,-25.609594,1.644792,4.482274,-18.463892,1.851310,0.167115,-0.404057,0.565838,4.045443,1.878586,0.753386,-16.788055,0.126791,-10.594349,3.300475,-0.634618,0.747863,7.905016,3.666997,31.245129,3.526583,9.021474,8.262771,10.631880,-3.141672,4.410128,6.165324,12.481022,5.635590,8.770696,8.735834,10.870203,3.874316,21.608977,4.526612,1.156461,1.276455,-0.976077,-0.288614,1.000854,0.298251,0.383862,0.127455,-10.489012,-1.725379,-7.637858,9.150683,2.160111,1.407201,1.326115,1.018763,2.385681,1.744191,1.730315,7.003605,-10.912519,4.530976,3.405832,13.760234,-1.191210,-1.174960,0.549645,0.459820,3.840778,12.674068,-2.126857,-3.227273,0.883224,5.710771,2.435913,-63.068527,3.723472,10.381427,-6.550155,-5.879445,-0.212391,-0.055838,-0.030079,0.349785,0.068710,3.085991,5.712933,5.268697,4.278224,2.301436,0.565240,0.997076,0.590336,0.721163,0.832828,1.161940,0.703974,1.480778,0.505237,1.669236,1.958621,1.691473,0.893302,19.534316,1.782585,1.056738,-3.575074,16.543404,26.596598,24.057324,6.166616,11.768488,2.438942,0.139397,2.026144,3.923045,8.086570,7.847441,5.052775,3.426013,3.642981,2.268567,-0.649373,3.161143,7.047121,2.205177,5.594592,-61.189816,8.415619,8.300800,-2.673700,-2.996654,5.218760,-23.693685,-2.322776,8.623765,4.627958,3.368395,46.500027,5.639402,-8.165272,0.796185,-0.706099,0.135805,0.868030,0.306016,0.789311,7.124334,4.242289,9.727023,0.681696,3.756994,3.622855,1.035487,1.025518,1.451887,1.854145,53.213359,-1.431522,-0.091550,-1.656084,-29.300245,1.570393,-0.978860,-1.027790,0.540321,-0.337222,-0.445398,5.875282,-1.581966,-2.580338,-0.264537,1.197146,-1.569363,-1.206515,-4.797875,-4.215951,8.528007,-6.191259,-2.189876,-2.501495,-0.966387,-1.200414,-1.520622,1.784751,3.031218,2.192351,1.142476,3.948292,1.763238,1.458057,1.396658,0.608675,1.724458,1.444704,-0.337446,0.570233,-0.657234,0.994609,-1.613324,-1.018631,9.949645,0.400291,0.977540,2.793460,9.773625,-2.396520,-2.783999,-2.708673,0.222687,-0.809978,0.368899,0.299932,-0.449218,0.185562,-0.459102,19.015891,-5.459218,-5.169562,-2.773216,-2.557959,-1.678736,-1.842239,-2.521119,-2.590653,-1.349186,-6.084066,13.539631,-2.590764,-6.882887,-4.029900,-1.488305,-4.217717,-0.591442,-4.848400,-2.261591,-1.905966,0.042691,-46.258913,-34.478861,-0.503401,-0.420428,-2.167570,-0.846137,0.870438,-2.407570,0.566669,-4.854715,12.200811,-2.699115,2.800773,7.892013,12.472750,0.180263,1.710783,0.879254,-2.253537,-2.573041,23.346808,6.059341,2.580303,14.766641,5.840801,4.124855,2.460706,1.147568,-1.740196,-0.196835,0.446965,-4.702591,1.964575,-0.052577,0.050285,-0.335195,0.303068,-0.149456,0.085326,-0.495100,1.934900,1.936413,1.653900,0.018581,-0.061852,-0.204984,-1.333097,-1.018476,-0.999683,-1.024398,-2.082589,-1.729892,-1.682701,-1.436921,-0.425914,0.474230,-0.613048,2.100885,-0.575348,-0.652350,0.685484,0.915968,0.304119,33.087667,22.601027,-0.104921,-0.177293,0.234389,0.198040,-0.238190,0.024597,-0.234056,2.822241,0.004142,-0.021054,-1.552198,0.397562,0.077244,-0.810139,0.196844,0.939802,-0.136742,0.592149,-0.255330,0.163302,0.318883,-0.064531,0.062070,0.694546,0.209702,-0.010243,-0.073304,0.410424,0.204043,0.361079,-0.055767,-0.101269,-0.050839,0.051487,0.718138,0.694693,0.435695,-0.256583,1.158518,1.995850,0.439841,-6.203604,-0.985698,-0.155184,0.593911,2.482176,0.946247,-8.436521,2.401151,1.810159,-1.035090,1.092773,0.036518,0.601562,0.147424,-1.833577,-0.126662,-0.374717,0.021811,-1.851743,2.796177,7.877599,0.255243,1.929069,0.112273,1.512485,-0.092995,2.856183,2.717226,-2.437687,29.901422,-2.085927,-19.040682,7.366650,-6.152353,2.929612,2.416426,0.020353,0.695380,-1.096458,-0.048956,-4.537238,-1.349666,-1.191487,-4.125253,-1.868902,-0.829698,0.339131,-0.988083,-0.657337,-1.539595,-0.878505,0.020183,-0.606991,-6.575499,-1.118187,-5.901197,-1.902425,-1.830654,-0.680334,-5.982117,-0.672636,-0.566174,0.880422,-0.227259,16.390507,16.269985,0.259872,-0.607438,-0.343732,-0.055939,-0.167441,-0.216072,-0.726638,-1.074767,-0.762545,0.036361,-1.061878,-0.472379,0.016452,-0.140865,10.090679,-0.235577,-0.524869,0.212008,-0.585822,7.323222,-0.135613,0.180593,-0.011106,-0.042434,-12.922468,-1.085171,-0.292372,-0.325988,-1.179218,-1.970896,-16.414723,0.919156,1.402566,2.696173,-0.709757,1.263208,-4.311061,-1.912170,0.871238,3.954405,-0.151088,-1.171526,-4.635838,-1.823951,-1.739963,-1.850814,-0.681339,-4.348577,6.466663,-1.359048,-2.297508,0.873118,-2.400759,-1.233752,-11.830300,-4.348966,0.058590,-0.093309,-0.269750,-0.034210,2.940893,0.216562,-0.620224,-5.364289,2.643353,-14.314586,0.580299,-7.502483,3.299922,3.749239,0.036450,2.614238,2.437889,-0.351271,-1.562823,-1.413144,-5.498119,-3.459754,0.428530,-0.058354,-0.386101,-0.304795,-0.544952,-1.530170,-0.663988,-0.703933,-0.727071,-1.581068,-0.311638,-1.667302,-1.823642,-1.680038,1.580470,177.705612,-1.861632,6.898606,1.315608,-1.085525,-5.474480,-1.913068,-1.113184,-0.820879,-0.721986,-0.105046,0.573232,-0.567043,-0.447164,-1.654838,-6.803239,-0.794338,-4.504619,-2.908429,-4.093875,-3.466304,-3.426859,-2.315266,-5.298508,-10.366847,-17.253376,-8.906028,-8.385869,-6.196990,-2.296948,-5.304315,-18.097126,-25.213401,1.869964,-2.902289,-1.899073,-1.705180,-1.426860,-2.510971,0.838146,0.526502,-0.782129,0.808493,-0.845322,-12.005751,-18.375311,-9.925110,-1.189432,-1.891818,-5.313697,-1.043915,-1.121079,-1.301175,-2.109128,-2.104007,2.245467,0.933534,-3.669234,0.044000,-3.064914,-3.341542,-2.857548,-0.249489,-0.592423,-0.582685,0.247260,7.506503,1.967544,0.566159,0.832930,-0.418475,-0.390811,-0.564865,0.433205,0.504496,-0.647795,-0.236603,-0.652715,-0.487510,-0.544541,0.332621,0.466587,0.523348}; + std::vector<float> bias = {-350.736300,1.530207,-9.805541,-1.676745,6.448848,-0.185940,-0.834116,1.642355,-0.557261,0.211599,-1.207916,-1.731354,-0.243328,-0.166474,0.338915,1.356859,-0.370182}; + return new Discrimination::NNFeedForwardVarDep(nodes,weights,bias); + } + default: + { + std::vector<unsigned int> nodes = {segmentationEntries[cSegType][segIdx],1}; + std::vector<float> weights(segmentationEntries[cSegType][segIdx],.01); + std::vector<float> bias={0}; + return new Discrimination::NNFeedForwardVarDep(nodes, weights, bias); + } + } + } else { + std::vector<unsigned int> nodes = {100,1}; + std::vector<float> weights(100,1); + std::vector<float> bias={0}; + return new Discrimination::NNFeedForwardVarDep(nodes, weights, bias); + } +} + +// ============================================================================= +template<bool goodStatus> +Discrimination::NNFeedForwardVarDep* createEtaDepNN( + SegmentationType cSegType, + unsigned segIdx, + float etaMin, float etaMax) +{ + Discrimination::NNFeedForwardVarDep* nn = createNN(cSegType, segIdx); + nn->setEtaDep(etaMin, etaMax); + return nn; +} + +// ============================================================================= +template<bool goodStatus> +Discrimination::NNFeedForwardVarDep* createEtDepNN( + SegmentationType cSegType, + unsigned segIdx, + float etMin, float etMax) +{ + Discrimination::NNFeedForwardVarDep* nn = createNN(cSegType, segIdx); + nn->setEtDep(etMin, etMax); + return nn; +} + +// ============================================================================= +template<bool goodStatus> +Discrimination::NNFeedForwardVarDep* createEtaEtDepNN(SegmentationType cSegType, + unsigned segIdx, + float etaMin, float etaMax, + float etMin, float etMax) +{ + Discrimination::NNFeedForwardVarDep* nn = createNN(cSegType, segIdx); + nn->setEtaEtDep(etaMin, etaMax, etMin, etMax); + return nn; +} + +// ============================================================================= +template< + typename procedure_t, + EtaDependency etaDependency, + EtDependency etDependency +> +void createThresWrapper(const char* fileName, + const std::vector<float> &etaDepBounderies, + const std::vector<float> &etDepBounderies, + float thresValue) +{ + // Typedef to make things easier + typedef RingerProcedureWrapper<procedure_t, + etaDependency, + etDependency> wrapper_t; + + typedef typename RingerProcedureType<procedure_t>::procEnum_t procEnum_t; + + msg << MSG::INFO << "Attempting to create a RingerProcedureWrapper<" + << toStr(procedure_t::template procType<procEnum_t>() ) + << ((Ringer::is_same<procedure_t,Discrimination::IThresholdVarDep>::value)?",":"(VarDep),") + << toStr(etaDependency) << "," + << toStr(etDependency) << "> with file name: " << fileName << "." << endreq; + + unsigned etaDepProc = etaDepBounderies.size() - 1; + unsigned etDepProc = etDepBounderies.size() - 1; + + // Loop over variable dependencies + for ( unsigned uEtaDep = EtaIndependent; uEtaDep <= EtaDependent; ++uEtaDep ){ + for ( unsigned uEtDep = EtIndependent; uEtDep <= EtDependent; ++uEtDep ){ + // The enumerations + EtaDependency etaDep = static_cast<EtaDependency>(uEtaDep); + EtDependency etDep = static_cast<EtDependency>(uEtDep); + + // Change message level accondingly if we are creating correct wrapper + // type + MSG::Level lvl(MSG::VERBOSE); + if ( etaDep == etaDependency && + etDep == etDependency ) + { + lvl = MSG::INFO; + } + + // The collection holder + typename wrapper_t::ThresDepProcCollection thresCol( etDepProc, + std::vector<procedure_t*>(etaDepProc, nullptr)); + + // Fill collection + for ( unsigned etDepIdx = 0; etDepIdx < etDepProc; ++etDepIdx){ + // Get et bounderies: + float etMin(etDepBounderies[etDepIdx]), + etMax(etDepBounderies[etDepIdx+1]); + for ( unsigned etaDepIdx = 0; etaDepIdx < etaDepProc; ++etaDepIdx){ + // Get eta bounderies: + float etaMin(etaDepBounderies[etaDepIdx]), + etaMax(etaDepBounderies[etaDepIdx+1]); + + // Fill collection: + if (etaDep) { + if (etDep) { + thresCol[etDepIdx][etaDepIdx] = createEtaEtDepThres( + etaMin, + etaMax, + etMin, + etMax, + thresValue); + } else { + thresCol[etDepIdx][etaDepIdx] = createEtaDepThres( + etaMin, + etaMax, + thresValue); + } + } else { + if (etDep) { + thresCol[etDepIdx][etaDepIdx] = createEtDepThres( + etMin, + etMax, + thresValue); + } else { + thresCol[etDepIdx][etaDepIdx] = createThres(thresValue); + } + } + } + } // Finished looping and filling collection + + // Attempt to create a wrapper with filled collection: + try { + + msg << lvl << "Attempting to create wrapper with (" + << toStr(etaDep) << "," << toStr(etDep) << ") discriminator" + << endreq; + + // Create wrapper: + auto wrapper = new wrapper_t(thresCol); + + // Use dummy message stream: + wrapper->setMsgStream(&msg); + // Print wrapper: + wrapper->print(MSG::DEBUG); + + // Delete file if it already exists: + IOHelperFcns::deleteFile( fileName ); + + // If it succeed, write it into file: + //writeWrapperOnFile(*wrapper, fileName, MSG::VERBOSE); + IThresWrapper::writeWrapper(wrapper, fileName); + + // Release wrapper memory: + //wrapper->releaseMemory(); + //delete wrapper; + + msg << lvl << "Succeed!" << endreq; + + } catch (const std::runtime_error &e) { + + msg << MSG::VERBOSE << "Couldn't create wrapper. Reason: " + << e.what() << endreq; + + // Release collection memory + for ( unsigned etDepIdx = 0; etDepIdx < etDepProc; ++etDepIdx){ + for ( unsigned etaDepIdx = 0; etaDepIdx < etaDepProc; ++etaDepIdx){ + delete thresCol[etDepIdx][etaDepIdx]; + thresCol[etDepIdx][etaDepIdx] = nullptr; + } + } + } // Finished creating wrapper and handling possible errors + + } + } // Finished looping over eta/et. +} + + +// ============================================================================= +Discrimination::UniqueThresholdVarDep* createThres(float thresValue) +{ + return new Discrimination::UniqueThresholdVarDep(thresValue); +} + +// ============================================================================= +Discrimination::UniqueThresholdVarDep* createEtaDepThres( + float etaMin, float etaMax, + float thresValue) +{ + Discrimination::UniqueThresholdVarDep* thres = createThres(thresValue); + thres->setEtaDep(etaMin, etaMax); + return thres; +} + +// ============================================================================= +Discrimination::UniqueThresholdVarDep* createEtDepThres( + float etMin, float etMax, + float thresValue) +{ + Discrimination::UniqueThresholdVarDep* thres = createThres(thresValue); + thres->setEtDep(etMin, etMax); + return thres; +} + +// ============================================================================= +Discrimination::UniqueThresholdVarDep* createEtaEtDepThres( + float etaMin, float etaMax, + float etMin, float etMax, + float thresValue) +{ + Discrimination::UniqueThresholdVarDep* thres = createThres(thresValue); + thres->setEtaEtDep(etaMin, etaMax, etMin, etMax); + return thres; +}