From 72127bad535e21f576aeedf5363791c5b326854e Mon Sep 17 00:00:00 2001 From: Deion Elgin Fellers <dfellers@lxplus724.cern.ch> Date: Fri, 30 Sep 2022 09:49:20 +0200 Subject: [PATCH 1/4] first pass at adding energy calibration code which accesses calibration variables from a COOL db --- Calorimeter/CaloRecAlgs/CMakeLists.txt | 2 +- .../CaloRecAlgs/python/CaloRecAlgsConfig.py | 7 + Calorimeter/CaloRecAlgs/src/CaloRecAlg.cxx | 152 +++++++++++++++++- Calorimeter/CaloRecAlgs/src/CaloRecAlg.h | 22 +++ Calorimeter/CaloRecTools/CMakeLists.txt | 27 ++++ .../CaloRecTools/ICaloReconstructionTool.h | 31 ++++ .../src/CaloReconstructionTool.cxx | 38 +++++ .../CaloRecTools/src/CaloReconstructionTool.h | 38 +++++ .../src/components/CaloRecTools_entries.cxx | 3 + .../Reconstruction/scripts/faser_reco.py | 8 +- 10 files changed, 322 insertions(+), 6 deletions(-) create mode 100644 Calorimeter/CaloRecTools/CMakeLists.txt create mode 100644 Calorimeter/CaloRecTools/CaloRecTools/ICaloReconstructionTool.h create mode 100644 Calorimeter/CaloRecTools/src/CaloReconstructionTool.cxx create mode 100644 Calorimeter/CaloRecTools/src/CaloReconstructionTool.h create mode 100644 Calorimeter/CaloRecTools/src/components/CaloRecTools_entries.cxx diff --git a/Calorimeter/CaloRecAlgs/CMakeLists.txt b/Calorimeter/CaloRecAlgs/CMakeLists.txt index 219db92a3..87ae6a06d 100644 --- a/Calorimeter/CaloRecAlgs/CMakeLists.txt +++ b/Calorimeter/CaloRecAlgs/CMakeLists.txt @@ -9,7 +9,7 @@ atlas_subdir( CaloRecAlgs ) atlas_add_component( CaloRecAlgs src/*.cxx src/*.h src/components/*.cxx - LINK_LIBRARIES AthenaBaseComps StoreGateLib xAODFaserCalorimeter xAODFaserWaveform) + LINK_LIBRARIES AthenaKernel GaudiKernel AthenaBaseComps AthenaPoolUtilities StoreGateLib xAODFaserCalorimeter xAODFaserWaveform) atlas_install_python_modules( python/*.py ) diff --git a/Calorimeter/CaloRecAlgs/python/CaloRecAlgsConfig.py b/Calorimeter/CaloRecAlgs/python/CaloRecAlgsConfig.py index 034bf08b5..ea3759ab2 100644 --- a/Calorimeter/CaloRecAlgs/python/CaloRecAlgsConfig.py +++ b/Calorimeter/CaloRecAlgs/python/CaloRecAlgsConfig.py @@ -4,6 +4,7 @@ Copyright (C) 2020 CERN for the benefit of the FASER collaboration """ from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator from AthenaConfiguration.ComponentFactory import CompFactory +from IOVDbSvc.IOVDbSvcConfig import addFolders from OutputStreamAthenaPool.OutputStreamConfig import OutputStreamCfg @@ -25,6 +26,12 @@ def CalorimeterReconstructionCfg(flags, **kwargs): #recoAlg.CalorimeterReconstructionTool = tool acc.addEventAlgo(recoAlg) + dbInstance = kwargs.get("dbInstance", "TRIGGER_OFL") # what should this be set to??? + + acc.merge(addFolders(flags, "/WAVE/Calibration/HV", dbInstance, className="CondAttrListCollection")) + acc.merge(addFolders(flags, "/WAVE/Calibration/HV_ref", dbInstance, className="CondAttrListCollection")) + acc.merge(addFolders(flags, "/WAVE/Calibration/MIP_charge_ref", dbInstance, className="CondAttrListCollection")) + return acc def CalorimeterReconstructionOutputCfg(flags, **kwargs): diff --git a/Calorimeter/CaloRecAlgs/src/CaloRecAlg.cxx b/Calorimeter/CaloRecAlgs/src/CaloRecAlg.cxx index 4b4d6f158..493fe87d3 100644 --- a/Calorimeter/CaloRecAlgs/src/CaloRecAlg.cxx +++ b/Calorimeter/CaloRecAlgs/src/CaloRecAlg.cxx @@ -22,6 +22,11 @@ CaloRecAlg::initialize() { // Set key to write container ATH_CHECK( m_caloHitContainerKey.initialize() ); + // Set key to read calibratiion variables from data base + ATH_CHECK( m_PMT_HV_ReadKey.initialize() ); + ATH_CHECK( m_PMT_HV_ref_ReadKey.initialize() ); + ATH_CHECK( m_MIPcharge_ref_ReadKey.initialize() ); + return StatusCode::SUCCESS; } @@ -68,6 +73,8 @@ CaloRecAlg::execute(const EventContext& ctx) const { // Reconstruct all waveforms //CHECK( m_recoTool->reconstructAll(*waveformHandle, clockptr, hitContainerHandle.ptr()) ); + ATH_MSG_DEBUG("DEION test" ); + // Find peak time (most significant hit) const xAOD::WaveformHit* peakHit = findPeakHit(*caloWaveHitHandle); if (peakHit == NULL) return StatusCode::SUCCESS; @@ -76,7 +83,16 @@ CaloRecAlg::execute(const EventContext& ctx) const { xAOD::CalorimeterHit* calo_hit = new xAOD::CalorimeterHit(); caloHitContainerHandle->push_back(calo_hit); - calo_hit->set_raw_energy(-1.); // Dummy value + calo_hit->set_raw_energy(peakHit->raw_integral()/50.0); // Dummy value + ATH_MSG_DEBUG("DEION, calo_hit filled with integral of '" << peakHit->raw_integral()/50.0 ); + + float PMT_hv = getHV(peakHit->channel()); + float PMT_hv_ref = getHV_ref(peakHit->channel()); + float MIPcharge_ref = getMIPcharge_ref(peakHit->channel()); + + ATH_MSG_DEBUG("DEION, calo_hit has HV of '" << PMT_hv ); + ATH_MSG_DEBUG("DEION, calo_hit has HV_ref of '" << PMT_hv_ref ); + ATH_MSG_DEBUG("DEION, calo_hit has MIP_charge_ref of '" << MIPcharge_ref ); // Find closest hits in time per channel std::map<int, const xAOD::WaveformHit*> hitMap; @@ -121,3 +137,137 @@ CaloRecAlg::findPeakHit(const xAOD::WaveformHitContainer& hitContainer) const { if (peakHit->status_bit(xAOD::WaveformStatus::THRESHOLD_FAILED)) return NULL; return peakHit; } + +//---------------------------------------------------------------------- +float CaloRecAlg::getHV(const EventContext& ctx, int channel) const { + + ATH_MSG_DEBUG("in getHV("<<channel<<")"); + + float HV=0.; + + // Read Cond Handle + SG::ReadCondHandle<CondAttrListCollection> readHandle{m_PMT_HV_ReadKey, ctx}; + const CondAttrListCollection* readCdo{*readHandle}; + if (readCdo==nullptr) { + ATH_MSG_FATAL("Null pointer to the read conditions object"); + return HV; + } + // Get the validitiy range + EventIDRange rangeW; + if (not readHandle.range(rangeW)) { + ATH_MSG_FATAL("Failed to retrieve validity range for " << readHandle.key()); + return HV; + } + ATH_MSG_DEBUG("Size of CondAttrListCollection " << readHandle.fullKey() << " readCdo->size()= " << readCdo->size()); + ATH_MSG_DEBUG("Range of input is " << rangeW); + + // Read offset for specific channel + const CondAttrListCollection::AttributeList& payload{readCdo->attributeList(channel)}; + + if (payload.exists("HV") and not payload["HV"].isNull()) { + HV = payload["HV"].data<float>(); + ATH_MSG_DEBUG("Found digitizer channel " << channel << ", HV as " << HV); + } else { + ATH_MSG_WARNING("No valid HV found for channel "<<channel<<"!"); + } + + return HV; + +} + +float CaloRecAlg::getHV(int channel) const { + const EventContext& ctx(Gaudi::Hive::currentContext()); + return CaloRecAlg::getHV(ctx, channel); +} + +//---------------------------------------------------------------------- +float CaloRecAlg::getHV_ref(const EventContext& ctx, int channel) const { + + ATH_MSG_DEBUG("in getHV_ref("<<channel<<")"); + + float HV_ref=0.; + + // Read Cond Handle + SG::ReadCondHandle<CondAttrListCollection> readHandle{m_PMT_HV_ref_ReadKey, ctx}; + const CondAttrListCollection* readCdo{*readHandle}; + if (readCdo==nullptr) { + ATH_MSG_FATAL("Null pointer to the read conditions object"); + return HV_ref; + } + // Get the validitiy range + EventIDRange rangeW; + if (not readHandle.range(rangeW)) { + ATH_MSG_FATAL("Failed to retrieve validity range for " << readHandle.key()); + return HV_ref; + } + ATH_MSG_DEBUG("Size of CondAttrListCollection " << readHandle.fullKey() << " readCdo->size()= " << readCdo->size()); + ATH_MSG_DEBUG("Range of input is " << rangeW); + + // Read offset for specific channel + const CondAttrListCollection::AttributeList& payload{readCdo->attributeList(channel)}; + + if (payload.exists("HV_ref") and not payload["HV_ref"].isNull()) { + HV_ref = payload["HV_ref"].data<float>(); + ATH_MSG_DEBUG("Found digitizer channel " << channel << ", HV_ref as " << HV_ref); + } else { + ATH_MSG_WARNING("No valid HV_ref found for channel "<<channel<<"!"); + } + + return HV_ref; + +} + +float CaloRecAlg::getHV_ref(int channel) const { + const EventContext& ctx(Gaudi::Hive::currentContext()); + return CaloRecAlg::getHV_ref(ctx, channel); +} + +//---------------------------------------------------------------------- +float CaloRecAlg::getMIPcharge_ref(const EventContext& ctx, int channel) const { + + ATH_MSG_DEBUG("in getMIPcharge_ref("<<channel<<")"); + + float MIP_charge_ref =0.; + + // Read Cond Handle + SG::ReadCondHandle<CondAttrListCollection> readHandle{m_MIPcharge_ref_ReadKey, ctx}; + const CondAttrListCollection* readCdo{*readHandle}; + if (readCdo==nullptr) { + ATH_MSG_FATAL("Null pointer to the read conditions object"); + return MIP_charge_ref; + } + // Get the validitiy range + EventIDRange rangeW; + if (not readHandle.range(rangeW)) { + ATH_MSG_FATAL("Failed to retrieve validity range for " << readHandle.key()); + return MIP_charge_ref; + } + ATH_MSG_DEBUG("Size of CondAttrListCollection " << readHandle.fullKey() << " readCdo->size()= " << readCdo->size()); + ATH_MSG_DEBUG("Range of input is " << rangeW); + + // Read offset for specific channel + const CondAttrListCollection::AttributeList& payload{readCdo->attributeList(channel)}; + + if (payload.exists("MIP_charge_ref") and not payload["MIP_charge_ref"].isNull()) { + MIP_charge_ref = payload["MIP_charge_ref"].data<float>(); + ATH_MSG_DEBUG("Found digitizer channel " << channel << ", MIP_charge_ref as " << MIP_charge_ref); + } else { + ATH_MSG_WARNING("No valid MIP_charge_ref found for channel "<<channel<<"!"); + } + + return MIP_charge_ref; + +} + +float CaloRecAlg::getMIPcharge_ref(int channel) const { + const EventContext& ctx(Gaudi::Hive::currentContext()); + return CaloRecAlg::getMIPcharge_ref(ctx, channel); +} + + + + +//---------------------------------------------------------------------- + + + diff --git a/Calorimeter/CaloRecAlgs/src/CaloRecAlg.h b/Calorimeter/CaloRecAlgs/src/CaloRecAlg.h index bd98e9afd..f68c84ed8 100644 --- a/Calorimeter/CaloRecAlgs/src/CaloRecAlg.h +++ b/Calorimeter/CaloRecAlgs/src/CaloRecAlg.h @@ -14,6 +14,10 @@ // Tool classes //#include "CaloRecTools/ICalorimeterReconstructionTool.h" +// Include Athena stuff for Conditions db reading +#include "AthenaPoolUtilities/CondAttrListCollection.h" +#include "StoreGate/ReadCondHandleKey.h" + // Handles #include "StoreGate/ReadHandleKey.h" #include "StoreGate/WriteHandleKey.h" @@ -21,6 +25,10 @@ // Gaudi #include "GaudiKernel/ServiceHandle.h" #include "GaudiKernel/ToolHandle.h" +#include "GaudiKernel/EventContext.h" +#include "GaudiKernel/ICondSvc.h" +#include "Gaudi/Property.h" + // STL #include <string> @@ -78,6 +86,20 @@ class CaloRecAlg : public AthReentrantAlgorithm { const xAOD::WaveformHit* findPeakHit(const xAOD::WaveformHitContainer& hitContainer) const; + virtual float getHV(const EventContext& ctx, int channel) const; + virtual float getHV(int channel) const; + + virtual float getHV_ref(const EventContext& ctx, int channel) const; + virtual float getHV_ref(int channel) const; + + virtual float getMIPcharge_ref(const EventContext& ctx, int channel) const; + virtual float getMIPcharge_ref(int channel) const; + + // Read Cond Handle + SG::ReadCondHandleKey<CondAttrListCollection> m_PMT_HV_ReadKey{this, "PMT_HV_ReadKey", "/WAVE/Calibration/HV", "Key of folder for PMT HV reading"}; + SG::ReadCondHandleKey<CondAttrListCollection> m_PMT_HV_ref_ReadKey{this, "PMT_HV_ref_ReadKey", "/WAVE/Calibration/HV_ref", "Key of folder for PMT HV at time of MIP calibration measurement"}; + SG::ReadCondHandleKey<CondAttrListCollection> m_MIPcharge_ref_ReadKey{this, "MIPcharge_ref_ReadKey", "/WAVE/Calibration/MIP_charge_ref", "Key of folder for MIPcharge calibration measurment"}; + }; #endif // CALORECALGS_CALORECALG_H diff --git a/Calorimeter/CaloRecTools/CMakeLists.txt b/Calorimeter/CaloRecTools/CMakeLists.txt new file mode 100644 index 000000000..36c9f1dcd --- /dev/null +++ b/Calorimeter/CaloRecTools/CMakeLists.txt @@ -0,0 +1,27 @@ +################################################################################ +# Package: WaveRecTools +################################################################################ + +# Declare the package name: +atlas_subdir( CaloRecTools ) + +# External dependencies: +find_package( ROOT ) + +# Component(s) in the package: +atlas_add_library( CaloRecToolsLib + CaloRecTools/*.h src/*.cxx src/*.h + PUBLIC_HEADERS CaloRecTools + PRIVATE_INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} + LINK_LIBRARIES AthenaBaseComps AthenaKernel GeoPrimitives Identifier + PRIVATE_LINK_LIBRARIES ${ROOT_LIBRARIES} + ) + +atlas_add_component( CaloRecTools + src/components/*.cxx + INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} + LINK_LIBRARIES ${ROOT_LIBRARIES} + AthenaBaseComps GaudiKernel + CaloRecToolsLib) + + diff --git a/Calorimeter/CaloRecTools/CaloRecTools/ICaloReconstructionTool.h b/Calorimeter/CaloRecTools/CaloRecTools/ICaloReconstructionTool.h new file mode 100644 index 000000000..d6decfbd0 --- /dev/null +++ b/Calorimeter/CaloRecTools/CaloRecTools/ICaloReconstructionTool.h @@ -0,0 +1,31 @@ +/* + Copyright (C) 2021 CERN for the benefit of the FASER collaboration +*/ + +/** + * @file ICaloReconstructionTool.h + * Header file for the ICaloReconstructionTool class + * @author Eric Torrence, 2021 + */ + + +#ifndef CALORECTOOLS_ICALOCONSTRUCTIONTOOL_H +#define CALORECTOOLS_ICALOCONSTRUCTIONTOOL_H + +// Base class +#include "GaudiKernel/IAlgTool.h" +#include "GaudiKernel/ToolHandle.h" + +///Interface for Calo reco algorithms +class ICaloReconstructionTool : virtual public IAlgTool +{ + public: + + // InterfaceID + DeclareInterfaceID(ICaloReconstructionTool, 1, 0); + + virtual ~ICaloReconstructionTool() = default; + +}; + +#endif // SCINTRECTOOLS_IWAVEFORMRECONSTRUCTIONTOOL_H diff --git a/Calorimeter/CaloRecTools/src/CaloReconstructionTool.cxx b/Calorimeter/CaloRecTools/src/CaloReconstructionTool.cxx new file mode 100644 index 000000000..438dd77f3 --- /dev/null +++ b/Calorimeter/CaloRecTools/src/CaloReconstructionTool.cxx @@ -0,0 +1,38 @@ +/* + Copyright (C) 2021 CERN for the benefit of the FASER collaboration +*/ + +/** + * @file CaloReconstructionTool.cxx + * Implementation file for the CaloReconstructionTool.cxx + * @ author E. Torrence, 2021 + **/ + +#include "CaloReconstructionTool.h" + +#include "TH1F.h" +#include "TF1.h" +#include "TFitResult.h" +#include "TFitResultPtr.h" +#include "TGraph.h" +#include "TError.h" + +#include <vector> +#include <tuple> +#include <math.h> + +// Constructor +CaloReconstructionTool::CaloReconstructionTool(const std::string& type, const std::string& name, const IInterface* parent) : + base_class(type, name, parent) +{ +} + +// Initialization +StatusCode +CaloReconstructionTool::initialize() { + ATH_MSG_INFO( name() << "::initalize()" ); + + return StatusCode::SUCCESS; +} + + diff --git a/Calorimeter/CaloRecTools/src/CaloReconstructionTool.h b/Calorimeter/CaloRecTools/src/CaloReconstructionTool.h new file mode 100644 index 000000000..55ea137ef --- /dev/null +++ b/Calorimeter/CaloRecTools/src/CaloReconstructionTool.h @@ -0,0 +1,38 @@ +/* + Copyright (C) 2021 CERN for the benefit of the FASER collaboration +*/ + +/** @file CaloReconstructionTool.h + * Header file for CaloReconstructionTool.h + * + */ +#ifndef CALORECTOOLS_CALORECONSTRUCTIONTOOL_H +#define CALORECTOOLS_CALORECONSTRUCTIONTOOL_H + +//Athena +#include "AthenaBaseComps/AthAlgTool.h" +#include "CaloRecTools/ICaloReconstructionTool.h" + +//Gaudi +#include "GaudiKernel/ToolHandle.h" + +//STL +#include <string> +#include <vector> + +class CaloReconstructionTool: public extends<AthAlgTool, ICaloReconstructionTool> { + public: + + /// Normal constructor for an AlgTool; 'properties' are also declared here + CaloReconstructionTool(const std::string& type, + const std::string& name, const IInterface* parent); + + /// Retrieve the necessary services in initialize + StatusCode initialize(); + + private: + + +}; + +#endif // CALORECTOOLS_CALOCONSTRUCTIONTOOL_H diff --git a/Calorimeter/CaloRecTools/src/components/CaloRecTools_entries.cxx b/Calorimeter/CaloRecTools/src/components/CaloRecTools_entries.cxx new file mode 100644 index 000000000..183a4878b --- /dev/null +++ b/Calorimeter/CaloRecTools/src/components/CaloRecTools_entries.cxx @@ -0,0 +1,3 @@ +#include "../CaloReconstructionTool.h" + +DECLARE_COMPONENT( CaloReconstructionTool ) diff --git a/Control/CalypsoExample/Reconstruction/scripts/faser_reco.py b/Control/CalypsoExample/Reconstruction/scripts/faser_reco.py index 4e233bf4f..8ebbc421c 100755 --- a/Control/CalypsoExample/Reconstruction/scripts/faser_reco.py +++ b/Control/CalypsoExample/Reconstruction/scripts/faser_reco.py @@ -181,8 +181,8 @@ from WaveRecAlgs.WaveRecAlgsConfig import WaveformReconstructionCfg acc.merge(WaveformReconstructionCfg(ConfigFlags)) # Not ready for primetime -# from CaloRecAlgs.CaloRecAlgsConfig import CalorimeterReconstructionCfg -# acc.merge(CalorimeterReconstructionCfg(ConfigFlags)) +from CaloRecAlgs.CaloRecAlgsConfig import CalorimeterReconstructionCfg +acc.merge(CalorimeterReconstructionCfg(ConfigFlags)) # Tracker clusters from TrackerPrepRawDataFormation.TrackerPrepRawDataFormationConfig import FaserSCT_ClusterizationCfg @@ -252,8 +252,8 @@ from WaveRecAlgs.WaveRecAlgsConfig import WaveformReconstructionOutputCfg acc.merge(WaveformReconstructionOutputCfg(ConfigFlags)) # Calorimeter reconstruction output -# from CaloRecAlgs.CaloRecAlgsConfig import CalorimeterReconstructionOutputCfg -# acc.merge(CalorimeterReconstructionOutputCfg(ConfigFlags)) +from CaloRecAlgs.CaloRecAlgsConfig import CalorimeterReconstructionOutputCfg +acc.merge(CalorimeterReconstructionOutputCfg(ConfigFlags)) # Check what we have print( "Writing out xAOD objects:" ) -- GitLab From 38734c8bbf318e8f02ac33e7aea44b1d52f5219c Mon Sep 17 00:00:00 2001 From: Deion Elgin Fellers <dfellers@lxplus727.cern.ch> Date: Thu, 3 Nov 2022 15:02:13 +0100 Subject: [PATCH 2/4] add calorimeter calibration package --- Calorimeter/CaloRecAlgs/CMakeLists.txt | 2 +- .../CaloRecAlgs/python/CaloRecAlgsConfig.py | 16 +- Calorimeter/CaloRecAlgs/src/CaloRecAlg.cxx | 249 +++++------------- Calorimeter/CaloRecAlgs/src/CaloRecAlg.h | 36 +-- Calorimeter/CaloRecTools/CMakeLists.txt | 11 +- .../CaloRecTools/CaloRecTools/ICaloRecTool.h | 45 ++++ .../CaloRecTools/ICaloReconstructionTool.h | 31 --- .../CaloRecTools/python/CaloRecToolConfig.py | 28 ++ Calorimeter/CaloRecTools/src/CaloRecTool.cxx | 195 ++++++++++++++ Calorimeter/CaloRecTools/src/CaloRecTool.h | 83 ++++++ .../src/CaloReconstructionTool.cxx | 38 --- .../CaloRecTools/src/CaloReconstructionTool.h | 38 --- .../src/components/CaloRecTools_entries.cxx | 4 +- .../Root/CalorimeterHitAuxContainer_v1.cxx | 8 +- .../Root/CalorimeterHit_v1.cxx | 32 +-- .../versions/CalorimeterHitAuxContainer_v1.h | 11 +- .../versions/CalorimeterHit_v1.h | 24 +- 17 files changed, 487 insertions(+), 364 deletions(-) create mode 100644 Calorimeter/CaloRecTools/CaloRecTools/ICaloRecTool.h delete mode 100644 Calorimeter/CaloRecTools/CaloRecTools/ICaloReconstructionTool.h create mode 100644 Calorimeter/CaloRecTools/python/CaloRecToolConfig.py create mode 100644 Calorimeter/CaloRecTools/src/CaloRecTool.cxx create mode 100644 Calorimeter/CaloRecTools/src/CaloRecTool.h delete mode 100644 Calorimeter/CaloRecTools/src/CaloReconstructionTool.cxx delete mode 100644 Calorimeter/CaloRecTools/src/CaloReconstructionTool.h diff --git a/Calorimeter/CaloRecAlgs/CMakeLists.txt b/Calorimeter/CaloRecAlgs/CMakeLists.txt index 87ae6a06d..75d9d09a2 100644 --- a/Calorimeter/CaloRecAlgs/CMakeLists.txt +++ b/Calorimeter/CaloRecAlgs/CMakeLists.txt @@ -9,7 +9,7 @@ atlas_subdir( CaloRecAlgs ) atlas_add_component( CaloRecAlgs src/*.cxx src/*.h src/components/*.cxx - LINK_LIBRARIES AthenaKernel GaudiKernel AthenaBaseComps AthenaPoolUtilities StoreGateLib xAODFaserCalorimeter xAODFaserWaveform) + LINK_LIBRARIES AthenaKernel GaudiKernel AthenaBaseComps AthenaPoolUtilities StoreGateLib xAODFaserCalorimeter xAODFaserWaveform CaloRecToolsLib) atlas_install_python_modules( python/*.py ) diff --git a/Calorimeter/CaloRecAlgs/python/CaloRecAlgsConfig.py b/Calorimeter/CaloRecAlgs/python/CaloRecAlgsConfig.py index ea3759ab2..83839b9cb 100644 --- a/Calorimeter/CaloRecAlgs/python/CaloRecAlgsConfig.py +++ b/Calorimeter/CaloRecAlgs/python/CaloRecAlgsConfig.py @@ -1,36 +1,30 @@ -""" Define methods used to instantiate configured Waveform reconstruction tools and algorithms +""" Define methods used to instantiate configured Calorimeter Calibration reconstruction tools and algorithms -Copyright (C) 2020 CERN for the benefit of the FASER collaboration +Copyright (C) 2022 CERN for the benefit of the FASER collaboration """ from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator from AthenaConfiguration.ComponentFactory import CompFactory from IOVDbSvc.IOVDbSvcConfig import addFolders - from OutputStreamAthenaPool.OutputStreamConfig import OutputStreamCfg -#CalorimeterReconstructionTool = CompFactory.CalorimeterReconstructionTool +from CaloRecTools.CaloRecToolConfig import CaloRecToolCfg # One stop shopping for normal FASER data def CalorimeterReconstructionCfg(flags, **kwargs): """ Return all algorithms and tools for Waveform reconstruction """ acc = ComponentAccumulator() - #tool = CalorimeterReconstructionTool(name="CaloRecTool", **kwargs) - kwargs.setdefault("CaloWaveHitContainerKey", "CaloWaveformHits") kwargs.setdefault("PreshowerWaveHitContainerKey", "PreshowerWaveformHits") kwargs.setdefault("CaloHitContainerKey", "CaloHits") - #kwargs.setdefault("CalorimeterReconstructionTool", tool) + kwargs.setdefault("PreshowerHitContainerKey", "PreshowerHits") recoAlg = CompFactory.CaloRecAlg("CaloRecAlg", **kwargs) - #recoAlg.CalorimeterReconstructionTool = tool acc.addEventAlgo(recoAlg) dbInstance = kwargs.get("dbInstance", "TRIGGER_OFL") # what should this be set to??? - acc.merge(addFolders(flags, "/WAVE/Calibration/HV", dbInstance, className="CondAttrListCollection")) - acc.merge(addFolders(flags, "/WAVE/Calibration/HV_ref", dbInstance, className="CondAttrListCollection")) - acc.merge(addFolders(flags, "/WAVE/Calibration/MIP_charge_ref", dbInstance, className="CondAttrListCollection")) + acc.merge(CaloRecToolCfg(flags)) return acc diff --git a/Calorimeter/CaloRecAlgs/src/CaloRecAlg.cxx b/Calorimeter/CaloRecAlgs/src/CaloRecAlg.cxx index 493fe87d3..f70993055 100644 --- a/Calorimeter/CaloRecAlgs/src/CaloRecAlg.cxx +++ b/Calorimeter/CaloRecAlgs/src/CaloRecAlg.cxx @@ -1,4 +1,5 @@ #include "CaloRecAlg.h" +#include <math.h> CaloRecAlg::CaloRecAlg(const std::string& name, ISvcLocator* pSvcLocator) @@ -6,13 +7,9 @@ CaloRecAlg::CaloRecAlg(const std::string& name, } -StatusCode -CaloRecAlg::initialize() { +StatusCode CaloRecAlg::initialize() { ATH_MSG_INFO(name() << "::initalize()" ); - // Initalize tools - //ATH_CHECK( m_recoTool.retrieve() ); - // Set key to read calo hits from ATH_CHECK( m_caloWaveHitContainerKey.initialize() ); @@ -21,24 +18,21 @@ CaloRecAlg::initialize() { // Set key to write container ATH_CHECK( m_caloHitContainerKey.initialize() ); + ATH_CHECK( m_preshowerHitContainerKey.initialize() ); - // Set key to read calibratiion variables from data base - ATH_CHECK( m_PMT_HV_ReadKey.initialize() ); - ATH_CHECK( m_PMT_HV_ref_ReadKey.initialize() ); - ATH_CHECK( m_MIPcharge_ref_ReadKey.initialize() ); + // Initalize tools + ATH_CHECK( m_recoCalibTool.retrieve() ); return StatusCode::SUCCESS; } - -StatusCode -CaloRecAlg::finalize() { +//---------------------------------------------------------------------- +StatusCode CaloRecAlg::finalize() { ATH_MSG_INFO(name() << "::finalize()"); return StatusCode::SUCCESS; } - -StatusCode -CaloRecAlg::execute(const EventContext& ctx) const { +//---------------------------------------------------------------------- +StatusCode CaloRecAlg::execute(const EventContext& ctx) const { ATH_MSG_DEBUG("Executing"); ATH_MSG_DEBUG("Run: " << ctx.eventID().run_number() @@ -68,206 +62,105 @@ CaloRecAlg::execute(const EventContext& ctx) const { ATH_CHECK( caloHitContainerHandle.record( std::make_unique<xAOD::CalorimeterHitContainer>(), std::make_unique<xAOD::CalorimeterHitAuxContainer>() ) ); + SG::WriteHandle<xAOD::CalorimeterHitContainer> preshowerHitContainerHandle(m_preshowerHitContainerKey, ctx); + ATH_CHECK( preshowerHitContainerHandle.record( std::make_unique<xAOD::CalorimeterHitContainer>(), + std::make_unique<xAOD::CalorimeterHitAuxContainer>() ) ); + ATH_MSG_DEBUG("WaveformsHitContainer '" << caloHitContainerHandle.name() << "' initialized"); + ATH_MSG_DEBUG("WaveformsHitContainer '" << preshowerHitContainerHandle.name() << "' initialized"); // Reconstruct all waveforms //CHECK( m_recoTool->reconstructAll(*waveformHandle, clockptr, hitContainerHandle.ptr()) ); ATH_MSG_DEBUG("DEION test" ); - // Find peak time (most significant hit) - const xAOD::WaveformHit* peakHit = findPeakHit(*caloWaveHitHandle); - if (peakHit == NULL) return StatusCode::SUCCESS; - - // Create a new calo hit - xAOD::CalorimeterHit* calo_hit = new xAOD::CalorimeterHit(); - caloHitContainerHandle->push_back(calo_hit); - - calo_hit->set_raw_energy(peakHit->raw_integral()/50.0); // Dummy value - ATH_MSG_DEBUG("DEION, calo_hit filled with integral of '" << peakHit->raw_integral()/50.0 ); - - float PMT_hv = getHV(peakHit->channel()); - float PMT_hv_ref = getHV_ref(peakHit->channel()); - float MIPcharge_ref = getMIPcharge_ref(peakHit->channel()); - - ATH_MSG_DEBUG("DEION, calo_hit has HV of '" << PMT_hv ); - ATH_MSG_DEBUG("DEION, calo_hit has HV_ref of '" << PMT_hv_ref ); - ATH_MSG_DEBUG("DEION, calo_hit has MIP_charge_ref of '" << MIPcharge_ref ); - - // Find closest hits in time per channel - std::map<int, const xAOD::WaveformHit*> hitMap; - for ( const auto& hit : *caloWaveHitHandle ) { - int channel = hit->channel(); - if (hitMap.count(channel) == 0) - hitMap[channel] = hit; - else { - if (abs(hitMap[channel]->localtime() - peakHit->localtime()) > - abs(hit->localtime() - peakHit->localtime())) - hitMap[channel] = hit; - } - } + for( const auto& hit : *caloWaveHitHandle ) { + if (hit->status_bit(xAOD::WaveformStatus::SECONDARY)) continue; - // For each hit found, insert these into the caloHit - // Clear before association - calo_hit->clearCaloWaveformLinks(); - for ( const auto& [chan, hit] : hitMap ) { - ATH_MSG_VERBOSE("Found hit " << *hit); - calo_hit->addCaloHit(caloWaveHitHandle.get(), hit); - } + // Create a new calo hit + xAOD::CalorimeterHit* calo_hit = new xAOD::CalorimeterHit(); + caloHitContainerHandle->push_back(calo_hit); - ATH_MSG_DEBUG("CaloHitContainer '" << caloHitContainerHandle.name() << "' filled with "<< caloHitContainerHandle->size() <<" items"); + ATH_MSG_DEBUG("calo_hit in channel " << hit->channel() ); - return StatusCode::SUCCESS; -} + float hit_charge = hit->integral()/50.0; // divide by 50 ohms to get charge + ATH_MSG_DEBUG("calo_hit filled has charge of " << hit_charge << " pC"); -const xAOD::WaveformHit* -CaloRecAlg::findPeakHit(const xAOD::WaveformHitContainer& hitContainer) const { + float HVgain_extrap = extrapolateHVgain(hit->channel()); + ATH_MSG_DEBUG("HV gain = " << HVgain_extrap ); - const xAOD::WaveformHit* peakHit = NULL; - for( const auto& hit : hitContainer ) { - if (peakHit == NULL) { - peakHit = hit; - } else { - if ( hit->peak() > peakHit->peak() ) peakHit = hit; - } - } + float MIPcharge_ref = m_recoCalibTool->getMIPcharge_ref(hit->channel()); + float hit_MIP = (hit_charge * HVgain_extrap) / MIPcharge_ref; + ATH_MSG_DEBUG("Edep in MIPs = " << hit_MIP ); - // Didn't find anything? - if (peakHit == NULL) return NULL; - if (peakHit->status_bit(xAOD::WaveformStatus::THRESHOLD_FAILED)) return NULL; - return peakHit; -} + float hit_Edep = hit_MIP * m_MIP_sim_Edep_calo; + ATH_MSG_DEBUG("Edep in GeV = " << hit_Edep ); -//---------------------------------------------------------------------- -float CaloRecAlg::getHV(const EventContext& ctx, int channel) const { + calo_hit->set_Edep(hit_Edep); // set calibrated Edep value - ATH_MSG_DEBUG("in getHV("<<channel<<")"); + float hit_raw_Edep = 0.0; + if (hit->integral() != 0.0) { // avoid possibility of division by zero error + float hit_raw_Edep = hit_Edep * (hit->raw_integral() / hit->integral()); + } + calo_hit->set_raw_Edep(hit_raw_Edep); // set calibrated Edep value - float HV=0.; + calo_hit->set_channel(hit->channel()); // set calibrated Edep value - // Read Cond Handle - SG::ReadCondHandle<CondAttrListCollection> readHandle{m_PMT_HV_ReadKey, ctx}; - const CondAttrListCollection* readCdo{*readHandle}; - if (readCdo==nullptr) { - ATH_MSG_FATAL("Null pointer to the read conditions object"); - return HV; - } - // Get the validitiy range - EventIDRange rangeW; - if (not readHandle.range(rangeW)) { - ATH_MSG_FATAL("Failed to retrieve validity range for " << readHandle.key()); - return HV; + calo_hit->clearWaveformLinks(); + calo_hit->addHit(caloWaveHitHandle.get(), hit); // create link to calo waveform hit } - ATH_MSG_DEBUG("Size of CondAttrListCollection " << readHandle.fullKey() << " readCdo->size()= " << readCdo->size()); - ATH_MSG_DEBUG("Range of input is " << rangeW); - // Read offset for specific channel - const CondAttrListCollection::AttributeList& payload{readCdo->attributeList(channel)}; + ATH_MSG_DEBUG("CaloHitContainer '" << caloHitContainerHandle.name() << "' filled with "<< caloHitContainerHandle->size() <<" items"); - if (payload.exists("HV") and not payload["HV"].isNull()) { - HV = payload["HV"].data<float>(); - ATH_MSG_DEBUG("Found digitizer channel " << channel << ", HV as " << HV); - } else { - ATH_MSG_WARNING("No valid HV found for channel "<<channel<<"!"); - } + for( const auto& hit : *preshowerWaveHitHandle ) { + if (hit->status_bit(xAOD::WaveformStatus::SECONDARY)) continue; - return HV; + // Create a new preshower hit + xAOD::CalorimeterHit* preshower_hit = new xAOD::CalorimeterHit(); + preshowerHitContainerHandle->push_back(preshower_hit); -} + ATH_MSG_DEBUG("preshower_hit in channel " << hit->channel() ); -float CaloRecAlg::getHV(int channel) const { - const EventContext& ctx(Gaudi::Hive::currentContext()); - return CaloRecAlg::getHV(ctx, channel); -} + float hit_charge = hit->integral()/50.0; // divide by 50 ohms to get charge + ATH_MSG_DEBUG("preshower_hit filled has charge of " << hit_charge << " pC"); -//---------------------------------------------------------------------- -float CaloRecAlg::getHV_ref(const EventContext& ctx, int channel) const { - - ATH_MSG_DEBUG("in getHV_ref("<<channel<<")"); + float MIPcharge_ref = m_recoCalibTool->getMIPcharge_ref(hit->channel()); + float hit_MIP = hit_charge / MIPcharge_ref; + ATH_MSG_DEBUG("Edep in MIPs = " << hit_MIP ); - float HV_ref=0.; + float hit_Edep = hit_MIP * m_MIP_sim_Edep_preshower; + ATH_MSG_DEBUG("Edep in GeV = " << hit_Edep ); - // Read Cond Handle - SG::ReadCondHandle<CondAttrListCollection> readHandle{m_PMT_HV_ref_ReadKey, ctx}; - const CondAttrListCollection* readCdo{*readHandle}; - if (readCdo==nullptr) { - ATH_MSG_FATAL("Null pointer to the read conditions object"); - return HV_ref; - } - // Get the validitiy range - EventIDRange rangeW; - if (not readHandle.range(rangeW)) { - ATH_MSG_FATAL("Failed to retrieve validity range for " << readHandle.key()); - return HV_ref; - } - ATH_MSG_DEBUG("Size of CondAttrListCollection " << readHandle.fullKey() << " readCdo->size()= " << readCdo->size()); - ATH_MSG_DEBUG("Range of input is " << rangeW); + preshower_hit->set_Edep(hit_Edep); // set calibrated Edep value - // Read offset for specific channel - const CondAttrListCollection::AttributeList& payload{readCdo->attributeList(channel)}; + float hit_raw_Edep = 0.0; + if (hit->integral() != 0.0) { // avoid possibility of division by zero error + float hit_raw_Edep = hit_Edep * (hit->raw_integral() / hit->integral()); + } + preshower_hit->set_raw_Edep(hit_raw_Edep); // set calibrated Edep value + + preshower_hit->set_channel(hit->channel()); // set calibrated Edep value - if (payload.exists("HV_ref") and not payload["HV_ref"].isNull()) { - HV_ref = payload["HV_ref"].data<float>(); - ATH_MSG_DEBUG("Found digitizer channel " << channel << ", HV_ref as " << HV_ref); - } else { - ATH_MSG_WARNING("No valid HV_ref found for channel "<<channel<<"!"); + preshower_hit->clearWaveformLinks(); + preshower_hit->addHit(preshowerWaveHitHandle.get(), hit); // create link to preshower waveform hit } - return HV_ref; + ATH_MSG_DEBUG("PreshowerHitContainer '" << preshowerHitContainerHandle.name() << "' filled with "<< preshowerHitContainerHandle->size() <<" items"); -} -float CaloRecAlg::getHV_ref(int channel) const { - const EventContext& ctx(Gaudi::Hive::currentContext()); - return CaloRecAlg::getHV_ref(ctx, channel); + return StatusCode::SUCCESS; } //---------------------------------------------------------------------- -float CaloRecAlg::getMIPcharge_ref(const EventContext& ctx, int channel) const { - - ATH_MSG_DEBUG("in getMIPcharge_ref("<<channel<<")"); - - float MIP_charge_ref =0.; - - // Read Cond Handle - SG::ReadCondHandle<CondAttrListCollection> readHandle{m_MIPcharge_ref_ReadKey, ctx}; - const CondAttrListCollection* readCdo{*readHandle}; - if (readCdo==nullptr) { - ATH_MSG_FATAL("Null pointer to the read conditions object"); - return MIP_charge_ref; - } - // Get the validitiy range - EventIDRange rangeW; - if (not readHandle.range(rangeW)) { - ATH_MSG_FATAL("Failed to retrieve validity range for " << readHandle.key()); - return MIP_charge_ref; - } - ATH_MSG_DEBUG("Size of CondAttrListCollection " << readHandle.fullKey() << " readCdo->size()= " << readCdo->size()); - ATH_MSG_DEBUG("Range of input is " << rangeW); +float CaloRecAlg::extrapolateHVgain(int channel) const { + float PMT_hv = m_recoCalibTool->getHV(channel); + float PMT_hv_ref = m_recoCalibTool->getHV_ref(channel); + TF1 gaincurve = m_recoCalibTool->get_PMT_HV_curve(channel); - // Read offset for specific channel - const CondAttrListCollection::AttributeList& payload{readCdo->attributeList(channel)}; - - if (payload.exists("MIP_charge_ref") and not payload["MIP_charge_ref"].isNull()) { - MIP_charge_ref = payload["MIP_charge_ref"].data<float>(); - ATH_MSG_DEBUG("Found digitizer channel " << channel << ", MIP_charge_ref as " << MIP_charge_ref); - } else { - ATH_MSG_WARNING("No valid MIP_charge_ref found for channel "<<channel<<"!"); - } - - return MIP_charge_ref; + float gaincurve_atHV = gaincurve.Eval(PMT_hv); + float gaincurve_atHVref = gaincurve.Eval(PMT_hv_ref); + return ( gaincurve_atHVref / gaincurve_atHV ) * pow( PMT_hv_ref / PMT_hv , 6.6); } - -float CaloRecAlg::getMIPcharge_ref(int channel) const { - const EventContext& ctx(Gaudi::Hive::currentContext()); - return CaloRecAlg::getMIPcharge_ref(ctx, channel); -} - - - - //---------------------------------------------------------------------- - - diff --git a/Calorimeter/CaloRecAlgs/src/CaloRecAlg.h b/Calorimeter/CaloRecAlgs/src/CaloRecAlg.h index f68c84ed8..cc705afcd 100644 --- a/Calorimeter/CaloRecAlgs/src/CaloRecAlg.h +++ b/Calorimeter/CaloRecAlgs/src/CaloRecAlg.h @@ -12,7 +12,7 @@ #include "xAODFaserCalorimeter/CalorimeterHitAuxContainer.h" // Tool classes -//#include "CaloRecTools/ICalorimeterReconstructionTool.h" +#include "CaloRecTools/ICaloRecTool.h" // Include Athena stuff for Conditions db reading #include "AthenaPoolUtilities/CondAttrListCollection.h" @@ -29,9 +29,12 @@ #include "GaudiKernel/ICondSvc.h" #include "Gaudi/Property.h" +// ROOT +#include "TF1.h" // STL #include <string> +#include <vector> class CaloRecAlg : public AthReentrantAlgorithm { @@ -59,46 +62,31 @@ class CaloRecAlg : public AthReentrantAlgorithm { /** * @name Reconstruction tool */ - //ToolHandle<ICalorimeterReconstructionTool> m_recoTool - //{this, "CalorimeterReconstructionTool", "CalorimeterReconstructionTool"}; + ToolHandle<ICaloRecTool> m_recoCalibTool {this, "CaloRecTool", "CaloRecTool"}; /** * @name Input raw waveform data using SG::ReadHandleKey */ //@{ - SG::ReadHandleKey<xAOD::WaveformHitContainer> m_caloWaveHitContainerKey - {this, "CaloWaveHitContainerKey", ""}; + SG::ReadHandleKey<xAOD::WaveformHitContainer> m_caloWaveHitContainerKey {this, "CaloWaveHitContainerKey", "CaloWaveformHits"}; //@} //@{ - SG::ReadHandleKey<xAOD::WaveformHitContainer> m_preshowerWaveHitContainerKey - {this, "PreshowerWaveHitContainerKey", ""}; + SG::ReadHandleKey<xAOD::WaveformHitContainer> m_preshowerWaveHitContainerKey {this, "PreshowerWaveHitContainerKey", "PreshowerWaveformHits"}; //@} /** * @name Output data using SG::WriteHandleKey */ //@{ - SG::WriteHandleKey<xAOD::CalorimeterHitContainer> m_caloHitContainerKey - {this, "CaloHitContainerKey", ""}; + SG::WriteHandleKey<xAOD::CalorimeterHitContainer> m_caloHitContainerKey {this, "CaloHitContainerKey", "CaloHits"}; + SG::WriteHandleKey<xAOD::CalorimeterHitContainer> m_preshowerHitContainerKey {this, "PreshowerHitContainerKey", "PreshowerHits"}; //@} - const xAOD::WaveformHit* - findPeakHit(const xAOD::WaveformHitContainer& hitContainer) const; + float extrapolateHVgain(int channel) const; - virtual float getHV(const EventContext& ctx, int channel) const; - virtual float getHV(int channel) const; - - virtual float getHV_ref(const EventContext& ctx, int channel) const; - virtual float getHV_ref(int channel) const; - - virtual float getMIPcharge_ref(const EventContext& ctx, int channel) const; - virtual float getMIPcharge_ref(int channel) const; - - // Read Cond Handle - SG::ReadCondHandleKey<CondAttrListCollection> m_PMT_HV_ReadKey{this, "PMT_HV_ReadKey", "/WAVE/Calibration/HV", "Key of folder for PMT HV reading"}; - SG::ReadCondHandleKey<CondAttrListCollection> m_PMT_HV_ref_ReadKey{this, "PMT_HV_ref_ReadKey", "/WAVE/Calibration/HV_ref", "Key of folder for PMT HV at time of MIP calibration measurement"}; - SG::ReadCondHandleKey<CondAttrListCollection> m_MIPcharge_ref_ReadKey{this, "MIPcharge_ref_ReadKey", "/WAVE/Calibration/MIP_charge_ref", "Key of folder for MIPcharge calibration measurment"}; + FloatProperty m_MIP_sim_Edep_calo {this, "MIP_sim_Edep_calo", 0.0585}; // MIP deposits 0.0585 GeV of energy in calo + FloatProperty m_MIP_sim_Edep_preshower {this, "MIP_sim_Edep_preshower", 0.004894}; // MIP deposits 0.004894 GeV of energy in a preshower layer }; diff --git a/Calorimeter/CaloRecTools/CMakeLists.txt b/Calorimeter/CaloRecTools/CMakeLists.txt index 36c9f1dcd..f0e9f07b5 100644 --- a/Calorimeter/CaloRecTools/CMakeLists.txt +++ b/Calorimeter/CaloRecTools/CMakeLists.txt @@ -1,5 +1,5 @@ ################################################################################ -# Package: WaveRecTools +# Package: CaloRecTools ################################################################################ # Declare the package name: @@ -13,15 +13,18 @@ atlas_add_library( CaloRecToolsLib CaloRecTools/*.h src/*.cxx src/*.h PUBLIC_HEADERS CaloRecTools PRIVATE_INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} - LINK_LIBRARIES AthenaBaseComps AthenaKernel GeoPrimitives Identifier + LINK_LIBRARIES AthenaBaseComps AthenaPoolUtilities AthenaKernel GaudiKernel PRIVATE_LINK_LIBRARIES ${ROOT_LIBRARIES} - ) + ) atlas_add_component( CaloRecTools src/components/*.cxx INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} LINK_LIBRARIES ${ROOT_LIBRARIES} - AthenaBaseComps GaudiKernel + AthenaBaseComps AthenaPoolUtilities AthenaKernel GaudiKernel CaloRecToolsLib) +# Install files from the package: +atlas_install_python_modules( python/*.py ) + diff --git a/Calorimeter/CaloRecTools/CaloRecTools/ICaloRecTool.h b/Calorimeter/CaloRecTools/CaloRecTools/ICaloRecTool.h new file mode 100644 index 000000000..feb141d91 --- /dev/null +++ b/Calorimeter/CaloRecTools/CaloRecTools/ICaloRecTool.h @@ -0,0 +1,45 @@ +/* + Copyright (C) 2022 CERN for the benefit of the FASER collaboration +*/ + +/** + * @file ICaloRecTool.h + * Header file for the ICaloRecTool class + * @author Deion Fellers, 2022 + */ + + +#ifndef CALORECTOOL_ICALORECTOOL_H +#define CALORECTOOL_ICALORECTOOL_H + +// Base class +#include "GaudiKernel/IAlgTool.h" +#include "GaudiKernel/ToolHandle.h" +#include "GaudiKernel/EventContext.h" + +#include "TF1.h" + +///Interface for Calo reco algorithms +class ICaloRecTool : virtual public IAlgTool +{ + public: + + // InterfaceID + DeclareInterfaceID(ICaloRecTool, 1, 0); + + virtual ~ICaloRecTool() = default; //!< Destructor + + // methods to return calibration database data + virtual float getHV(const EventContext& ctx, int channel) const = 0; + virtual float getHV(int channel) const = 0; + + virtual float getHV_ref(const EventContext& ctx, int channel) const = 0; + virtual float getHV_ref(int channel) const = 0; + + virtual float getMIPcharge_ref(const EventContext& ctx, int channel) const = 0; + virtual float getMIPcharge_ref(int channel) const = 0; + + virtual TF1 get_PMT_HV_curve(int channel) const = 0; +}; + +#endif // CALORECTOOL_ICALORECTOOL_H diff --git a/Calorimeter/CaloRecTools/CaloRecTools/ICaloReconstructionTool.h b/Calorimeter/CaloRecTools/CaloRecTools/ICaloReconstructionTool.h deleted file mode 100644 index d6decfbd0..000000000 --- a/Calorimeter/CaloRecTools/CaloRecTools/ICaloReconstructionTool.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - Copyright (C) 2021 CERN for the benefit of the FASER collaboration -*/ - -/** - * @file ICaloReconstructionTool.h - * Header file for the ICaloReconstructionTool class - * @author Eric Torrence, 2021 - */ - - -#ifndef CALORECTOOLS_ICALOCONSTRUCTIONTOOL_H -#define CALORECTOOLS_ICALOCONSTRUCTIONTOOL_H - -// Base class -#include "GaudiKernel/IAlgTool.h" -#include "GaudiKernel/ToolHandle.h" - -///Interface for Calo reco algorithms -class ICaloReconstructionTool : virtual public IAlgTool -{ - public: - - // InterfaceID - DeclareInterfaceID(ICaloReconstructionTool, 1, 0); - - virtual ~ICaloReconstructionTool() = default; - -}; - -#endif // SCINTRECTOOLS_IWAVEFORMRECONSTRUCTIONTOOL_H diff --git a/Calorimeter/CaloRecTools/python/CaloRecToolConfig.py b/Calorimeter/CaloRecTools/python/CaloRecToolConfig.py new file mode 100644 index 000000000..e87ac3658 --- /dev/null +++ b/Calorimeter/CaloRecTools/python/CaloRecToolConfig.py @@ -0,0 +1,28 @@ +""" Define methods to configure CaloRecTool + +Copyright (C) 2022 CERN for the benefit of the FASER collaboration +""" +from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator +from AthenaConfiguration.ComponentFactory import CompFactory +from IOVDbSvc.IOVDbSvcConfig import addFolders +CaloRecTool=CompFactory.CaloRecTool + + +def CaloRecToolCfg(flags, name="CaloRecTool", **kwargs): + """ Return configured ComponentAccumulator and tool for Calo Calibration + + CaloRecTool may be provided in kwargs + """ + + acc = ComponentAccumulator() + # tool = kwargs.get("CaloRecTool", CaloRecTool(flags)) + # Probably need to figure this out! + dbInstance = kwargs.get("dbInstance", "TRIGGER_OFL") + + acc.merge(addFolders(flags, "/WAVE/Calibration/HV", dbInstance, className="CondAttrListCollection")) + acc.merge(addFolders(flags, "/WAVE/Calibration/HV_ref", dbInstance, className="CondAttrListCollection")) + acc.merge(addFolders(flags, "/WAVE/Calibration/MIP_charge_ref", dbInstance, className="CondAttrListCollection")) + + return acc + + diff --git a/Calorimeter/CaloRecTools/src/CaloRecTool.cxx b/Calorimeter/CaloRecTools/src/CaloRecTool.cxx new file mode 100644 index 000000000..b7b491644 --- /dev/null +++ b/Calorimeter/CaloRecTools/src/CaloRecTool.cxx @@ -0,0 +1,195 @@ +/* + Copyright (C) 2022 CERN for the benefit of the FASER collaboration +*/ + +/** + * @file CaloRecTool.cxx + * Implementation file for the CaloRecTool.cxx + * @ author Deion Fellers, 2022 + **/ + +#include "CaloRecTool.h" + +// Constructor +CaloRecTool::CaloRecTool(const std::string& type, const std::string& name, const IInterface* parent) : + base_class(type, name, parent) +{ +} + +//-------------------------------------------------------------- +StatusCode +CaloRecTool::initialize() { + ATH_MSG_INFO( name() << "::initalize()" ); + + // Set keys to read calibratiion variables from data base + ATH_CHECK( m_PMT_HV_ReadKey.initialize() ); + ATH_CHECK( m_PMT_HV_ref_ReadKey.initialize() ); + ATH_CHECK( m_MIPcharge_ref_ReadKey.initialize() ); + + // access and store calo PMT HV gain curves + HVgaincurves_rootFile = TFile::Open("CaloGainCurves.root","read"); // open root file that has TF1 gain curves stored + + chan0_HVgaincurve_pntr = HVgaincurves_rootFile->Get<TF1>(m_chan0_HVgaincurve_name.value().c_str()); // make pointers to the gain curves + chan1_HVgaincurve_pntr = HVgaincurves_rootFile->Get<TF1>(m_chan1_HVgaincurve_name.value().c_str()); + chan2_HVgaincurve_pntr = HVgaincurves_rootFile->Get<TF1>(m_chan2_HVgaincurve_name.value().c_str()); + chan3_HVgaincurve_pntr = HVgaincurves_rootFile->Get<TF1>(m_chan3_HVgaincurve_name.value().c_str()); + + m_HVgainCurveMap[0] = *chan0_HVgaincurve_pntr; // store TF1 objects in an array mapped to the calo channel numbers + m_HVgainCurveMap[1] = *chan1_HVgaincurve_pntr; + m_HVgainCurveMap[2] = *chan2_HVgaincurve_pntr; + m_HVgainCurveMap[3] = *chan3_HVgaincurve_pntr; + + HVgaincurves_rootFile->Close(); // close the root file + + + return StatusCode::SUCCESS; +} + +//-------------------------------------------------------------- +StatusCode +CaloRecTool::finalize() { + // Print where you are + return StatusCode::SUCCESS; +} + +//-------------------------------------------------------------- +TF1 CaloRecTool::get_PMT_HV_curve(int channel) const { + if (channel <= 4) { + return m_HVgainCurveMap[channel]; + } else { + ATH_MSG_WARNING("channel "<<channel<<" is not <= 4 and thus not a calorimeter channel, so no HV gain-curve exists!"); + } + return TF1("default", "1.0", 0.0, 2000.0); +} + +//-------------------------------------------------------------- +float CaloRecTool::getHV(const EventContext& ctx, int channel) const { + + ATH_MSG_DEBUG("in getHV("<<channel<<")"); + + float HV=0.; + + // Read Cond Handle + SG::ReadCondHandle<CondAttrListCollection> readHandle{m_PMT_HV_ReadKey, ctx}; + const CondAttrListCollection* readCdo{*readHandle}; + if (readCdo==nullptr) { + ATH_MSG_FATAL("Null pointer to the read conditions object"); + return HV; + } + // Get the validitiy range + EventIDRange rangeW; + if (not readHandle.range(rangeW)) { + ATH_MSG_FATAL("Failed to retrieve validity range for " << readHandle.key()); + return HV; + } + ATH_MSG_DEBUG("Size of CondAttrListCollection " << readHandle.fullKey() << " readCdo->size()= " << readCdo->size()); + ATH_MSG_DEBUG("Range of input is " << rangeW); + + // Read offset for specific channel + const CondAttrListCollection::AttributeList& payload{readCdo->attributeList(channel)}; + + if (payload.exists("HV") and not payload["HV"].isNull()) { + HV = payload["HV"].data<float>(); + ATH_MSG_DEBUG("Found digitizer channel " << channel << ", HV as " << HV); + } else { + ATH_MSG_WARNING("No valid HV found for channel "<<channel<<"!"); + } + + return HV; + +} + +float CaloRecTool::getHV(int channel) const { + const EventContext& ctx(Gaudi::Hive::currentContext()); + return CaloRecTool::getHV(ctx, channel); +} + +//---------------------------------------------------------------------- +float CaloRecTool::getHV_ref(const EventContext& ctx, int channel) const { + + ATH_MSG_DEBUG("in getHV_ref("<<channel<<")"); + + float HV_ref=0.; + + // Read Cond Handle + SG::ReadCondHandle<CondAttrListCollection> readHandle{m_PMT_HV_ref_ReadKey, ctx}; + const CondAttrListCollection* readCdo{*readHandle}; + if (readCdo==nullptr) { + ATH_MSG_FATAL("Null pointer to the read conditions object"); + return HV_ref; + } + // Get the validitiy range + EventIDRange rangeW; + if (not readHandle.range(rangeW)) { + ATH_MSG_FATAL("Failed to retrieve validity range for " << readHandle.key()); + return HV_ref; + } + ATH_MSG_DEBUG("Size of CondAttrListCollection " << readHandle.fullKey() << " readCdo->size()= " << readCdo->size()); + ATH_MSG_DEBUG("Range of input is " << rangeW); + + // Read offset for specific channel + const CondAttrListCollection::AttributeList& payload{readCdo->attributeList(channel)}; + + if (payload.exists("HV_ref") and not payload["HV_ref"].isNull()) { + HV_ref = payload["HV_ref"].data<float>(); + ATH_MSG_DEBUG("Found digitizer channel " << channel << ", HV_ref as " << HV_ref); + } else { + ATH_MSG_WARNING("No valid HV_ref found for channel "<<channel<<"!"); + } + + return HV_ref; + +} + +float CaloRecTool::getHV_ref(int channel) const { + const EventContext& ctx(Gaudi::Hive::currentContext()); + return CaloRecTool::getHV_ref(ctx, channel); +} + +//---------------------------------------------------------------------- +float CaloRecTool::getMIPcharge_ref(const EventContext& ctx, int channel) const { + + ATH_MSG_DEBUG("in getMIPcharge_ref("<<channel<<")"); + + float MIP_charge_ref =0.; + + // Read Cond Handle + SG::ReadCondHandle<CondAttrListCollection> readHandle{m_MIPcharge_ref_ReadKey, ctx}; + const CondAttrListCollection* readCdo{*readHandle}; + if (readCdo==nullptr) { + ATH_MSG_FATAL("Null pointer to the read conditions object"); + return MIP_charge_ref; + } + // Get the validitiy range + EventIDRange rangeW; + if (not readHandle.range(rangeW)) { + ATH_MSG_FATAL("Failed to retrieve validity range for " << readHandle.key()); + return MIP_charge_ref; + } + ATH_MSG_DEBUG("Size of CondAttrListCollection " << readHandle.fullKey() << " readCdo->size()= " << readCdo->size()); + ATH_MSG_DEBUG("Range of input is " << rangeW); + + // Read offset for specific channel + const CondAttrListCollection::AttributeList& payload{readCdo->attributeList(channel)}; + + if (payload.exists("MIP_charge_ref") and not payload["MIP_charge_ref"].isNull()) { + MIP_charge_ref = payload["MIP_charge_ref"].data<float>(); + ATH_MSG_DEBUG("Found digitizer channel " << channel << ", MIP_charge_ref as " << MIP_charge_ref); + } else { + ATH_MSG_WARNING("No valid MIP_charge_ref found for channel "<<channel<<"!"); + } + + return MIP_charge_ref; + +} + +float CaloRecTool::getMIPcharge_ref(int channel) const { + const EventContext& ctx(Gaudi::Hive::currentContext()); + return CaloRecTool::getMIPcharge_ref(ctx, channel); +} + +//-------------------------------------------------------------- + + + + diff --git a/Calorimeter/CaloRecTools/src/CaloRecTool.h b/Calorimeter/CaloRecTools/src/CaloRecTool.h new file mode 100644 index 000000000..28a2221c1 --- /dev/null +++ b/Calorimeter/CaloRecTools/src/CaloRecTool.h @@ -0,0 +1,83 @@ +/* + Copyright (C) 2021 CERN for the benefit of the FASER collaboration +*/ + +/** @file CaloRecTool.h + * Header file for CaloRecTool.h + * + */ +#ifndef CALORECTOOLS_CALORECTOOL_H +#define CALORECTOOLS_CALORECTOOL_H + +// Include interface class +#include "AthenaBaseComps/AthAlgTool.h" +#include "CaloRecTools/ICaloRecTool.h" + +// Include Athena stuff +#include "AthenaPoolUtilities/CondAttrListCollection.h" +#include "StoreGate/ReadCondHandleKey.h" + +#include "GaudiKernel/ICondSvc.h" +#include "Gaudi/Property.h" + +// Include Gaudi classes +#include "GaudiKernel/ICondSvc.h" +#include "Gaudi/Property.h" +#include "GaudiKernel/EventContext.h" + +// Include ROOT classes +#include "TF1.h" +#include "TFile.h" + +#include <string> + +class CaloRecTool: public extends<AthAlgTool, ICaloRecTool> { + public: + + /// Normal constructor for an AlgTool; 'properties' are also declared here + CaloRecTool(const std::string& type, const std::string& name, const IInterface* parent); + + // Standard Gaudi functions + virtual StatusCode initialize() override; //!< Gaudi initialiser + virtual StatusCode finalize() override; //!< Gaudi finaliser + + // methods for returning calibration data + // Channels indexed by digitizer channel number + // HV is in Volts and MIPcharge is in pC + // + virtual float getHV(const EventContext& ctx, int channel) const override; + virtual float getHV(int channel) const override; + + virtual float getHV_ref(const EventContext& ctx, int channel) const override; + virtual float getHV_ref(int channel) const override; + + virtual float getMIPcharge_ref(const EventContext& ctx, int channel) const override; + virtual float getMIPcharge_ref(int channel) const override; + + // method for returning PMT HV calibration curves from root file + virtual TF1 get_PMT_HV_curve(int channel) const override; + + TFile* HVgaincurves_rootFile; + + TF1* chan0_HVgaincurve_pntr; + TF1* chan1_HVgaincurve_pntr; + TF1* chan2_HVgaincurve_pntr; + TF1* chan3_HVgaincurve_pntr; + + TF1 m_HVgainCurveMap[4]; + + private: + // properties that map channel name to PMT HV gain curves. PMt names found at https://twiki.cern.ch/twiki/bin/viewauth/FASER/CaloScintillator + StringProperty m_chan0_HVgaincurve_name{this, "Chan0HVgaincurve", "pol5_HV_Gain_Curve_PMT_LB8770"}; + StringProperty m_chan1_HVgaincurve_name{this, "Chan1HVgaincurve", "pol5_HV_Gain_Curve_PMT_LB8733"}; + StringProperty m_chan2_HVgaincurve_name{this, "Chan2HVgaincurve", "pol5_HV_Gain_Curve_PMT_LB8786"}; + StringProperty m_chan3_HVgaincurve_name{this, "Chan3HVgaincurve", "pol5_HV_Gain_Curve_PMT_LB8732"}; + + // Read Cond Handle + SG::ReadCondHandleKey<CondAttrListCollection> m_PMT_HV_ReadKey{this, "PMT_HV_ReadKey", "/WAVE/Calibration/HV", "Key of folder for PMT HV reading"}; + SG::ReadCondHandleKey<CondAttrListCollection> m_PMT_HV_ref_ReadKey{this, "PMT_HV_ref_ReadKey", "/WAVE/Calibration/HV_ref", "Key of folder for PMT HV at time of MIP calibration measurement"}; + SG::ReadCondHandleKey<CondAttrListCollection> m_MIPcharge_ref_ReadKey{this, "MIPcharge_ref_ReadKey", "/WAVE/Calibration/MIP_charge_ref", "Key of folder for MIPcharge calibration measurment"}; + +}; + +#endif // CALORECTOOLS_CALORECTOOL_H diff --git a/Calorimeter/CaloRecTools/src/CaloReconstructionTool.cxx b/Calorimeter/CaloRecTools/src/CaloReconstructionTool.cxx deleted file mode 100644 index 438dd77f3..000000000 --- a/Calorimeter/CaloRecTools/src/CaloReconstructionTool.cxx +++ /dev/null @@ -1,38 +0,0 @@ -/* - Copyright (C) 2021 CERN for the benefit of the FASER collaboration -*/ - -/** - * @file CaloReconstructionTool.cxx - * Implementation file for the CaloReconstructionTool.cxx - * @ author E. Torrence, 2021 - **/ - -#include "CaloReconstructionTool.h" - -#include "TH1F.h" -#include "TF1.h" -#include "TFitResult.h" -#include "TFitResultPtr.h" -#include "TGraph.h" -#include "TError.h" - -#include <vector> -#include <tuple> -#include <math.h> - -// Constructor -CaloReconstructionTool::CaloReconstructionTool(const std::string& type, const std::string& name, const IInterface* parent) : - base_class(type, name, parent) -{ -} - -// Initialization -StatusCode -CaloReconstructionTool::initialize() { - ATH_MSG_INFO( name() << "::initalize()" ); - - return StatusCode::SUCCESS; -} - - diff --git a/Calorimeter/CaloRecTools/src/CaloReconstructionTool.h b/Calorimeter/CaloRecTools/src/CaloReconstructionTool.h deleted file mode 100644 index 55ea137ef..000000000 --- a/Calorimeter/CaloRecTools/src/CaloReconstructionTool.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - Copyright (C) 2021 CERN for the benefit of the FASER collaboration -*/ - -/** @file CaloReconstructionTool.h - * Header file for CaloReconstructionTool.h - * - */ -#ifndef CALORECTOOLS_CALORECONSTRUCTIONTOOL_H -#define CALORECTOOLS_CALORECONSTRUCTIONTOOL_H - -//Athena -#include "AthenaBaseComps/AthAlgTool.h" -#include "CaloRecTools/ICaloReconstructionTool.h" - -//Gaudi -#include "GaudiKernel/ToolHandle.h" - -//STL -#include <string> -#include <vector> - -class CaloReconstructionTool: public extends<AthAlgTool, ICaloReconstructionTool> { - public: - - /// Normal constructor for an AlgTool; 'properties' are also declared here - CaloReconstructionTool(const std::string& type, - const std::string& name, const IInterface* parent); - - /// Retrieve the necessary services in initialize - StatusCode initialize(); - - private: - - -}; - -#endif // CALORECTOOLS_CALOCONSTRUCTIONTOOL_H diff --git a/Calorimeter/CaloRecTools/src/components/CaloRecTools_entries.cxx b/Calorimeter/CaloRecTools/src/components/CaloRecTools_entries.cxx index 183a4878b..c9c5438eb 100644 --- a/Calorimeter/CaloRecTools/src/components/CaloRecTools_entries.cxx +++ b/Calorimeter/CaloRecTools/src/components/CaloRecTools_entries.cxx @@ -1,3 +1,3 @@ -#include "../CaloReconstructionTool.h" +#include "../CaloRecTool.h" -DECLARE_COMPONENT( CaloReconstructionTool ) +DECLARE_COMPONENT( CaloRecTool ) diff --git a/xAOD/xAODFaserCalorimeter/Root/CalorimeterHitAuxContainer_v1.cxx b/xAOD/xAODFaserCalorimeter/Root/CalorimeterHitAuxContainer_v1.cxx index 6f6edf3e4..f73a83dd1 100644 --- a/xAOD/xAODFaserCalorimeter/Root/CalorimeterHitAuxContainer_v1.cxx +++ b/xAOD/xAODFaserCalorimeter/Root/CalorimeterHitAuxContainer_v1.cxx @@ -10,11 +10,11 @@ namespace xAOD { CalorimeterHitAuxContainer_v1::CalorimeterHitAuxContainer_v1() : AuxContainerBase() { - AUX_VARIABLE(localtime); - AUX_VARIABLE(bcid_time); - AUX_VARIABLE(raw_energy); + AUX_VARIABLE(channel); + AUX_VARIABLE(Edep); + AUX_VARIABLE(raw_Edep); - AUX_VARIABLE(caloLinks); + AUX_VARIABLE(WaveformLink); } } // namespace xAOD diff --git a/xAOD/xAODFaserCalorimeter/Root/CalorimeterHit_v1.cxx b/xAOD/xAODFaserCalorimeter/Root/CalorimeterHit_v1.cxx index 5e7a69ecc..f085cb0c9 100644 --- a/xAOD/xAODFaserCalorimeter/Root/CalorimeterHit_v1.cxx +++ b/xAOD/xAODFaserCalorimeter/Root/CalorimeterHit_v1.cxx @@ -13,41 +13,41 @@ namespace xAOD { CalorimeterHit_v1::CalorimeterHit_v1() : SG::AuxElement() { } - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( CalorimeterHit_v1, float, localtime, set_localtime ) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( CalorimeterHit_v1, unsigned int, channel, set_channel ) - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( CalorimeterHit_v1, float, bcidtime, set_bcidtime ) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( CalorimeterHit_v1, float, Edep, set_Edep ) - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( CalorimeterHit_v1, float, raw_energy, set_raw_energy ) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( CalorimeterHit_v1, float, raw_Edep, set_raw_Edep ) // setters and getters for the Calo WaveformHit links AUXSTORE_OBJECT_SETTER_AND_GETTER( CalorimeterHit_v1, CalorimeterHit_v1::WaveformHitLinks_t, - caloWaveformLinks, - setCaloWaveformLinks ) + WaveformLinks, + setWaveformLinks ) - static const SG::AuxElement::Accessor< CalorimeterHit_v1::WaveformHitLinks_t > caloHitAcc( "caloWaveformLinks" ); + static const SG::AuxElement::Accessor< CalorimeterHit_v1::WaveformHitLinks_t > HitAcc( "WaveformLinks" ); - const WaveformHit* CalorimeterHit_v1::caloHit( size_t i ) const { - return ( *caloHitAcc( *this )[ i ] ); + const WaveformHit* CalorimeterHit_v1::Hit( size_t i ) const { + return ( *HitAcc( *this )[ i ] ); } - size_t CalorimeterHit_v1::nCaloHits() const { - return caloHitAcc( *this ).size(); + size_t CalorimeterHit_v1::nHits() const { + return HitAcc( *this ).size(); } - void CalorimeterHit_v1::addCaloHit( const xAOD::WaveformHitContainer* pWaveformHitContainer, + void CalorimeterHit_v1::addHit( const xAOD::WaveformHitContainer* pWaveformHitContainer, const xAOD::WaveformHit* pWaveformHit) { ElementLink< xAOD::WaveformHitContainer > linkToWaveformHit; linkToWaveformHit.toContainedElement(*pWaveformHitContainer, pWaveformHit); - caloHitAcc( *this ).push_back( linkToWaveformHit ); + HitAcc( *this ).push_back( linkToWaveformHit ); return; } - void CalorimeterHit_v1::clearCaloWaveformLinks() { - caloHitAcc( *this ).clear(); + void CalorimeterHit_v1::clearWaveformLinks() { + HitAcc( *this ).clear(); return; } @@ -57,8 +57,8 @@ namespace xAOD { std::ostream& operator<<(std::ostream& s, const xAOD::CalorimeterHit_v1& hit) { s << "xAODCalorimeterHit:" - << " local time=" << hit.localtime() - << " raw_energy=" << hit.raw_energy() + << " channel = " << hit.channel() + << ", Edep = " << hit.Edep() << std::endl; return s; diff --git a/xAOD/xAODFaserCalorimeter/xAODFaserCalorimeter/versions/CalorimeterHitAuxContainer_v1.h b/xAOD/xAODFaserCalorimeter/xAODFaserCalorimeter/versions/CalorimeterHitAuxContainer_v1.h index 7e61261eb..41a89a032 100644 --- a/xAOD/xAODFaserCalorimeter/xAODFaserCalorimeter/versions/CalorimeterHitAuxContainer_v1.h +++ b/xAOD/xAODFaserCalorimeter/xAODFaserCalorimeter/versions/CalorimeterHitAuxContainer_v1.h @@ -29,13 +29,14 @@ namespace xAOD { private: /// @name Basic variables ///@ { - std::vector<float> localtime; - std::vector<float> bcid_time; - std::vector<float> raw_energy; + std::vector<unsigned int> channel; + std::vector<float> Edep; + std::vector<float> raw_Edep; typedef std::vector< ElementLink< WaveformHitContainer > > WaveformHitLink_t; - std::vector< WaveformHitLink_t > caloLinks; - std::vector< WaveformHitLink_t > preshowerLinks; + std::vector< WaveformHitLink_t > WaveformLink; + //std::vector< WaveformHitLink_t > caloLinks; + //std::vector< WaveformHitLink_t > preshowerLinks; ///@} diff --git a/xAOD/xAODFaserCalorimeter/xAODFaserCalorimeter/versions/CalorimeterHit_v1.h b/xAOD/xAODFaserCalorimeter/xAODFaserCalorimeter/versions/CalorimeterHit_v1.h index d9bb35047..fefc0d5ae 100644 --- a/xAOD/xAODFaserCalorimeter/xAODFaserCalorimeter/versions/CalorimeterHit_v1.h +++ b/xAOD/xAODFaserCalorimeter/xAODFaserCalorimeter/versions/CalorimeterHit_v1.h @@ -35,29 +35,29 @@ namespace xAOD { /// @{ /// Best results - float localtime() const; - void set_localtime(float value); + unsigned int channel() const; + void set_channel(unsigned int value); - float bcidtime() const; - void set_bcidtime(float value); + float Edep() const; + void set_Edep(float value); - float raw_energy() const; - void set_raw_energy(float value); + float raw_Edep() const; + void set_raw_Edep(float value); // Waveform Hits typedef std::vector< ElementLink< xAOD::WaveformHitContainer > > WaveformHitLinks_t; // Contributing Calorimeter Waveform Hits - const WaveformHitLinks_t& caloWaveformLinks() const; - void setCaloWaveformLinks( const WaveformHitLinks_t& caloWaveforms ); + const WaveformHitLinks_t& WaveformLinks() const; + void setWaveformLinks( const WaveformHitLinks_t& Waveforms ); // Remove all waveform hits - void clearCaloWaveformLinks(); + void clearWaveformLinks(); // Get the pointer to a given waveform hit - const WaveformHit* caloHit( size_t i ) const; + const WaveformHit* Hit( size_t i ) const; // Get the number of waveform hits - size_t nCaloHits() const; + size_t nHits() const; // Add a waveform hit - void addCaloHit( const xAOD::WaveformHitContainer*, const xAOD::WaveformHit*); + void addHit( const xAOD::WaveformHitContainer*, const xAOD::WaveformHit*); // // Contributing Preshower Waveform Hits // const WaveformHitLinks_t& preshowerWaveformLinks() const; -- GitLab From 47537d789e1a02d9be69bf38a02da1374525e5cb Mon Sep 17 00:00:00 2001 From: Deion Elgin Fellers <dfellers@lxplus751.cern.ch> Date: Wed, 9 Nov 2022 00:53:46 +0100 Subject: [PATCH 3/4] finalize calibration code for calo and preshower --- Calorimeter/CaloRecAlgs/src/CaloRecAlg.cxx | 64 +++++++++++--------- Calorimeter/CaloRecAlgs/src/CaloRecAlg.h | 6 +- Calorimeter/CaloRecTools/src/CaloRecTool.cxx | 2 +- Calorimeter/CaloRecTools/src/CaloRecTool.h | 3 + 4 files changed, 45 insertions(+), 30 deletions(-) diff --git a/Calorimeter/CaloRecAlgs/src/CaloRecAlg.cxx b/Calorimeter/CaloRecAlgs/src/CaloRecAlg.cxx index f70993055..12ddca3a4 100644 --- a/Calorimeter/CaloRecAlgs/src/CaloRecAlg.cxx +++ b/Calorimeter/CaloRecAlgs/src/CaloRecAlg.cxx @@ -69,11 +69,7 @@ StatusCode CaloRecAlg::execute(const EventContext& ctx) const { ATH_MSG_DEBUG("WaveformsHitContainer '" << caloHitContainerHandle.name() << "' initialized"); ATH_MSG_DEBUG("WaveformsHitContainer '" << preshowerHitContainerHandle.name() << "' initialized"); - // Reconstruct all waveforms - //CHECK( m_recoTool->reconstructAll(*waveformHandle, clockptr, hitContainerHandle.ptr()) ); - - ATH_MSG_DEBUG("DEION test" ); - + // Loop over calo hits and calibrate each primary hit for( const auto& hit : *caloWaveHitHandle ) { if (hit->status_bit(xAOD::WaveformStatus::SECONDARY)) continue; @@ -83,28 +79,35 @@ StatusCode CaloRecAlg::execute(const EventContext& ctx) const { ATH_MSG_DEBUG("calo_hit in channel " << hit->channel() ); - float hit_charge = hit->integral()/50.0; // divide by 50 ohms to get charge - ATH_MSG_DEBUG("calo_hit filled has charge of " << hit_charge << " pC"); + float MIPcharge_ref = m_recoCalibTool->getMIPcharge_ref(hit->channel()); // get reference MIP charge from database + + float hit_Edep = 0; + if (m_isMC) { + hit_Edep = hit->integral() / MIPcharge_ref; // MC MIPcharge_ref from database is really digitization scaling factors that take simulated Edep in MeV to mV*ns + ATH_MSG_DEBUG("isMC == True: calo hit Edep = " << hit_Edep << " MeV"); + } else { + float hit_charge = hit->integral()/50.0; // divide by 50 ohms to get charge + ATH_MSG_DEBUG("calo_hit filled has charge of " << hit_charge << " pC"); - float HVgain_extrap = extrapolateHVgain(hit->channel()); - ATH_MSG_DEBUG("HV gain = " << HVgain_extrap ); + float HVgain_extrap = extrapolateHVgain(hit->channel()); + ATH_MSG_DEBUG("HV gain = " << HVgain_extrap ); - float MIPcharge_ref = m_recoCalibTool->getMIPcharge_ref(hit->channel()); - float hit_MIP = (hit_charge * HVgain_extrap) / MIPcharge_ref; - ATH_MSG_DEBUG("Edep in MIPs = " << hit_MIP ); + float hit_MIP = (hit_charge * HVgain_extrap) / MIPcharge_ref; + ATH_MSG_DEBUG("Edep in MIPs = " << hit_MIP ); - float hit_Edep = hit_MIP * m_MIP_sim_Edep_calo; - ATH_MSG_DEBUG("Edep in GeV = " << hit_Edep ); + hit_Edep = hit_MIP * m_MIP_sim_Edep_calo; + ATH_MSG_DEBUG("Edep in MeV = " << hit_Edep ); + } calo_hit->set_Edep(hit_Edep); // set calibrated Edep value float hit_raw_Edep = 0.0; if (hit->integral() != 0.0) { // avoid possibility of division by zero error - float hit_raw_Edep = hit_Edep * (hit->raw_integral() / hit->integral()); + hit_raw_Edep = hit_Edep * (hit->raw_integral() / hit->integral()); } - calo_hit->set_raw_Edep(hit_raw_Edep); // set calibrated Edep value + calo_hit->set_raw_Edep(hit_raw_Edep); // set calibrated raw_Edep value - calo_hit->set_channel(hit->channel()); // set calibrated Edep value + calo_hit->set_channel(hit->channel()); // set channel number calo_hit->clearWaveformLinks(); calo_hit->addHit(caloWaveHitHandle.get(), hit); // create link to calo waveform hit @@ -121,25 +124,32 @@ StatusCode CaloRecAlg::execute(const EventContext& ctx) const { ATH_MSG_DEBUG("preshower_hit in channel " << hit->channel() ); - float hit_charge = hit->integral()/50.0; // divide by 50 ohms to get charge - ATH_MSG_DEBUG("preshower_hit filled has charge of " << hit_charge << " pC"); + float MIPcharge_ref = m_recoCalibTool->getMIPcharge_ref(hit->channel()); // get reference MIP charge from database + + float hit_Edep = 0; + if (m_isMC) { + hit_Edep = hit->integral() / MIPcharge_ref; // MC MIPcharge_ref from database is really digitization scaling factors that take simulated Edep in MeV to mV*ns + ATH_MSG_DEBUG("isMC == True: preshower hit Edep = " << hit_Edep << " MeV"); + } else { + float hit_charge = hit->integral()/50.0; // divide by 50 ohms to get charge + ATH_MSG_DEBUG("preshower_hit filled has charge of " << hit_charge << " pC"); - float MIPcharge_ref = m_recoCalibTool->getMIPcharge_ref(hit->channel()); - float hit_MIP = hit_charge / MIPcharge_ref; - ATH_MSG_DEBUG("Edep in MIPs = " << hit_MIP ); + float hit_MIP = hit_charge / MIPcharge_ref; + ATH_MSG_DEBUG("Edep in MIPs = " << hit_MIP ); - float hit_Edep = hit_MIP * m_MIP_sim_Edep_preshower; - ATH_MSG_DEBUG("Edep in GeV = " << hit_Edep ); + hit_Edep = hit_MIP * m_MIP_sim_Edep_preshower; + ATH_MSG_DEBUG("Edep in GeV = " << hit_Edep ); + } preshower_hit->set_Edep(hit_Edep); // set calibrated Edep value float hit_raw_Edep = 0.0; if (hit->integral() != 0.0) { // avoid possibility of division by zero error - float hit_raw_Edep = hit_Edep * (hit->raw_integral() / hit->integral()); + hit_raw_Edep = hit_Edep * (hit->raw_integral() / hit->integral()); } - preshower_hit->set_raw_Edep(hit_raw_Edep); // set calibrated Edep value + preshower_hit->set_raw_Edep(hit_raw_Edep); // set calibrated rsw_Edep value - preshower_hit->set_channel(hit->channel()); // set calibrated Edep value + preshower_hit->set_channel(hit->channel()); // set channel number preshower_hit->clearWaveformLinks(); preshower_hit->addHit(preshowerWaveHitHandle.get(), hit); // create link to preshower waveform hit diff --git a/Calorimeter/CaloRecAlgs/src/CaloRecAlg.h b/Calorimeter/CaloRecAlgs/src/CaloRecAlg.h index cc705afcd..c9ff4c514 100644 --- a/Calorimeter/CaloRecAlgs/src/CaloRecAlg.h +++ b/Calorimeter/CaloRecAlgs/src/CaloRecAlg.h @@ -85,8 +85,10 @@ class CaloRecAlg : public AthReentrantAlgorithm { float extrapolateHVgain(int channel) const; - FloatProperty m_MIP_sim_Edep_calo {this, "MIP_sim_Edep_calo", 0.0585}; // MIP deposits 0.0585 GeV of energy in calo - FloatProperty m_MIP_sim_Edep_preshower {this, "MIP_sim_Edep_preshower", 0.004894}; // MIP deposits 0.004894 GeV of energy in a preshower layer + FloatProperty m_MIP_sim_Edep_calo {this, "MIP_sim_Edep_calo", 58.5}; // MIP deposits 5.85 MeV of energy in calo + FloatProperty m_MIP_sim_Edep_preshower {this, "MIP_sim_Edep_preshower", 4.894}; // MIP deposits 4.894 MeV of energy in a preshower layer + + Gaudi::Property<bool> m_isMC {this, "isMC", false}; }; diff --git a/Calorimeter/CaloRecTools/src/CaloRecTool.cxx b/Calorimeter/CaloRecTools/src/CaloRecTool.cxx index b7b491644..a6bb42c51 100644 --- a/Calorimeter/CaloRecTools/src/CaloRecTool.cxx +++ b/Calorimeter/CaloRecTools/src/CaloRecTool.cxx @@ -27,7 +27,7 @@ CaloRecTool::initialize() { ATH_CHECK( m_MIPcharge_ref_ReadKey.initialize() ); // access and store calo PMT HV gain curves - HVgaincurves_rootFile = TFile::Open("CaloGainCurves.root","read"); // open root file that has TF1 gain curves stored + HVgaincurves_rootFile = TFile::Open(m_PMT_HV_Gain_Curve_file.value().c_str(),"read"); // open root file that has TF1 gain curves stored chan0_HVgaincurve_pntr = HVgaincurves_rootFile->Get<TF1>(m_chan0_HVgaincurve_name.value().c_str()); // make pointers to the gain curves chan1_HVgaincurve_pntr = HVgaincurves_rootFile->Get<TF1>(m_chan1_HVgaincurve_name.value().c_str()); diff --git a/Calorimeter/CaloRecTools/src/CaloRecTool.h b/Calorimeter/CaloRecTools/src/CaloRecTool.h index 28a2221c1..c6dc95181 100644 --- a/Calorimeter/CaloRecTools/src/CaloRecTool.h +++ b/Calorimeter/CaloRecTools/src/CaloRecTool.h @@ -67,6 +67,9 @@ class CaloRecTool: public extends<AthAlgTool, ICaloRecTool> { TF1 m_HVgainCurveMap[4]; private: + // Propert that points to the location of the root file which contains the HV gain curves for the calorimeter PMTs + StringProperty m_PMT_HV_Gain_Curve_file{this, "PMT_HV_Gain_Curve_file", "/cvmfs/faser.cern.ch/repo/sw/database/DBRelease/current/pmtgain/CaloGainCurves.root"}; + // properties that map channel name to PMT HV gain curves. PMt names found at https://twiki.cern.ch/twiki/bin/viewauth/FASER/CaloScintillator StringProperty m_chan0_HVgaincurve_name{this, "Chan0HVgaincurve", "pol5_HV_Gain_Curve_PMT_LB8770"}; StringProperty m_chan1_HVgaincurve_name{this, "Chan1HVgaincurve", "pol5_HV_Gain_Curve_PMT_LB8733"}; -- GitLab From f992d2a0406b2152e7a35e05a739224db98b2d82 Mon Sep 17 00:00:00 2001 From: Eric Torrence <eric.torrence@cern.ch> Date: Sat, 12 Nov 2022 01:56:29 +0100 Subject: [PATCH 4/4] Update faser_reco.py --- .../Reconstruction/scripts/faser_reco.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Control/CalypsoExample/Reconstruction/scripts/faser_reco.py b/Control/CalypsoExample/Reconstruction/scripts/faser_reco.py index 8ebbc421c..8a0b5a3cd 100755 --- a/Control/CalypsoExample/Reconstruction/scripts/faser_reco.py +++ b/Control/CalypsoExample/Reconstruction/scripts/faser_reco.py @@ -180,9 +180,13 @@ acc.merge(FaserGeometryCfg(ConfigFlags)) from WaveRecAlgs.WaveRecAlgsConfig import WaveformReconstructionCfg acc.merge(WaveformReconstructionCfg(ConfigFlags)) -# Not ready for primetime -from CaloRecAlgs.CaloRecAlgsConfig import CalorimeterReconstructionCfg -acc.merge(CalorimeterReconstructionCfg(ConfigFlags)) +# Calorimeter reconstruction +if args.isMC: + # Not ready for MC quite yet + pass +else: + from CaloRecAlgs.CaloRecAlgsConfig import CalorimeterReconstructionCfg + acc.merge(CalorimeterReconstructionCfg(ConfigFlags)) # Tracker clusters from TrackerPrepRawDataFormation.TrackerPrepRawDataFormationConfig import FaserSCT_ClusterizationCfg -- GitLab