Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • andesai/calypso
  • sazhang/calypso
  • yuxu/calypso
  • wfilali/calypso
  • bewilson/calypso
  • ovaldesm/calypso
  • xai/calypso
  • ymaruya/calypso
  • anburger/calypso
  • seley/calypso
  • sudatta/calypso
  • notarann/calypso
  • hhjelm/calypso
  • tarai/calypso
  • lmccoy/calypso
  • agarabag/calypso
  • fneuhaus/calypso
  • vlian/calypso
  • yechou/calypso
  • vlian/calypso-official
  • fasermc/calypso
  • schsu/calypso
  • maprim/calypso
  • cantel/calypso
  • jwspence/calypso
  • diwang/calypso
  • ccavanag/calypso
  • gwilliam/calypso
  • asalman/calypso
  • toinada/calypso
  • jboyd/calypso
  • abarkley/calypso
  • yafik/calypso
  • cpandini/calypso
  • tboeckh/calypso
  • sshively/calypso
  • keli/calypso
  • dfellers/calypso
  • torrence/calypso
  • coccaro/calypso
  • dcasper/calypso
  • faser/calypso
42 results
Show changes
Showing
with 278 additions and 273 deletions
#include "CaloWaveformDigiAlg.h"
#include "Identifier/Identifier.h"
#include "FaserCaloSimEvent/CaloHitIdHelper.h"
#include "CaloReadoutGeometry/EcalDetectorManager.h"
#include "CaloReadoutGeometry/CaloDetectorElement.h"
#include "GaudiKernel/PhysicalConstants.h"
#include <map>
#include <utility>
#include <cmath>
......@@ -30,11 +33,12 @@ CaloWaveformDigiAlg::initialize() {
// Set key to write container
ATH_CHECK( m_waveformContainerKey.initialize() );
// Set up helper
ATH_CHECK(detStore()->retrieve(m_ecalID, "EcalID"));
// Need to set this on first event
m_kernel = 0;
// And print out our timing simulation
if (m_advancedTiming) {
ATH_MSG_INFO("Using improved digitization timing");
} else {
ATH_MSG_INFO("Using simple digitization timing");
}
return StatusCode::SUCCESS;
}
......@@ -43,9 +47,6 @@ StatusCode
CaloWaveformDigiAlg::finalize() {
ATH_MSG_INFO(name() << "::finalize()");
if (m_kernel)
delete m_kernel;
return StatusCode::SUCCESS;
}
......@@ -71,100 +72,44 @@ CaloWaveformDigiAlg::execute(const EventContext& ctx) const {
return StatusCode::SUCCESS;
}
if (!m_kernel) {
ATH_MSG_INFO(name() << ": initialize waveform digitization kernel");
ATH_MSG_INFO(" Norm: " << m_digiCondTool->cb_norm(ctx));
ATH_MSG_INFO(" Mean: " << m_digiCondTool->cb_mean(ctx));
ATH_MSG_INFO(" Sigma: " << m_digiCondTool->cb_sigma(ctx));
ATH_MSG_INFO(" Alpha: " << m_digiCondTool->cb_alpha(ctx));
ATH_MSG_INFO(" N: " << m_digiCondTool->cb_n(ctx));
// Set up waveform shape
m_kernel = new TF1("PDF", "[4] * ROOT::Math::crystalball_pdf(x, [0],[1],[2],[3])", 0, 1200);
m_kernel->SetParameter(0, m_digiCondTool->cb_alpha(ctx));
m_kernel->SetParameter(1, m_digiCondTool->cb_n(ctx));
m_kernel->SetParameter(2, m_digiCondTool->cb_sigma(ctx));
m_kernel->SetParameter(3, m_digiCondTool->cb_mean(ctx));
m_kernel->SetParameter(4, m_digiCondTool->cb_norm(ctx));
// Pre-evaluate time kernel for each bin
m_timekernel = m_digiTool->evaluate_timekernel(m_kernel);
// Also save the baseline parameters
m_base_mean = m_digiCondTool->base_mean(ctx);
m_base_rms = m_digiCondTool->base_rms(ctx);
}
// Create structure to store pulse for each channel
std::map<Identifier, std::vector<uint16_t>> waveforms = m_digiTool->create_waveform_map(m_ecalID);
// Sum energy for each channel (i.e. identifier)
std::map<unsigned int, float> esum;
for (const auto& hit : *caloHitHandle) {
esum[hit.identify()] += hit.energyLoss();
}
// Loop over time samples
for (const auto& tk : m_timekernel) {
std::map<unsigned int, float> counts;
// Convolve hit energy with evaluated kernel and sum for each hit id (i.e. channel)
//for (const auto& hit : *caloHitHandle) {
// counts[hit.identify()] += tk * hit.energyLoss();
//}
// Convolve summed energy with evaluated kernel for each hit id (i.e. channel)
for (const auto& e : esum) {
counts[e.first] = tk * e.second;
}
// Subtract count from basleine and add result to correct waveform vector
for (const auto& c : counts) {
std::map<Identifier, std::vector<uint16_t>> waveforms;
waveforms.clear();
float baseline = m_digiTool->generate_baseline(m_base_mean, m_base_rms);
int value = std::round(baseline - c.second);
if (m_first) {
m_first = false;
if (value < 0) {
ATH_MSG_WARNING("Found pulse " << c.second << " larger than baseline " << c.first);
value = 0; // Protect against scaling signal above baseline
}
// Convert hit id to Identifier and store
Identifier id = CaloHitIdHelper::GetHelper()->getIdentifier(c.first);
waveforms[id].push_back(value);
}
// Write kernel parameters
ATH_MSG_INFO(name() << ": initialize waveform digitization kernel");
ATH_MSG_INFO(" Norm: " << m_digiCondTool->cb_norm());
ATH_MSG_INFO(" Mean: " << m_digiCondTool->cb_mean());
ATH_MSG_INFO(" Sigma: " << m_digiCondTool->cb_sigma());
ATH_MSG_INFO(" Alpha: " << m_digiCondTool->cb_alpha());
ATH_MSG_INFO(" N: " << m_digiCondTool->cb_n());
}
// This is a bit of a hack to make sure all waveforms have
// at least baseline entries. Should really add this to the
// logic above
for (const auto& w : waveforms) {
if (w.second.size() > 0) continue;
// Waveform was empty, fill with baseline
int channel = m_mappingTool->getChannelMapping(w.first);
ATH_MSG_DEBUG("Writing baseline into empty waveform in channel "<< channel);
int i = m_digiTool->nsamples();
while(i--) { // Use while to avoid unused variable warning with for
int baseline = m_digiTool->generate_baseline(m_base_mean, m_base_rms);
waveforms[w.first].push_back(baseline);
}
// Try our new tool instead
if (m_advancedTiming) {
waveforms = m_digiTool->generate_calo_timing_waveforms(ctx, m_digiCondTool, caloHitHandle.get());
} else {
waveforms = m_digiTool->generate_calo_waveforms(ctx, m_digiCondTool, caloHitHandle.get());
}
//m_chrono->chronoStop("Digit");
//m_chrono->chronoStart("Write");
// Loop over wavefrom vectors to make and store waveform
unsigned int nsamples = m_digiTool->nsamples();
unsigned int digitizer_samples = m_digiTool->digitizer_samples();
for (const auto& w : waveforms) {
RawWaveform* wfm = new RawWaveform();
RawWaveform* wfm = new RawWaveform();
wfm->setWaveform(0, w.second);
wfm->setIdentifier(w.first);
wfm->setChannel(m_mappingTool->getChannelMapping(w.first));
wfm->setSamples(nsamples);
wfm->setSamples(digitizer_samples);
// Don't write out waveforms with no channel defined
// Causes problems in downstream reco (not known in cable map
int channel = m_mappingTool->getChannelMapping(w.first);
if (channel < 0) {
ATH_MSG_DEBUG("Skipping waveform with unknown channel!");
continue;
}
wfm->setChannel(channel);
waveformContainerHandle->push_back(wfm);
}
......@@ -172,5 +117,9 @@ CaloWaveformDigiAlg::execute(const EventContext& ctx) const {
ATH_MSG_DEBUG("WaveformsHitContainer " << waveformContainerHandle.name() << "' filled with "<< waveformContainerHandle->size() <<" items");
// Cleanup
waveforms.clear();
return StatusCode::SUCCESS;
}
......@@ -21,12 +21,6 @@
#include "GaudiKernel/ServiceHandle.h"
#include "GaudiKernel/ToolHandle.h"
// Helpers
#include "FaserCaloIdentifier/EcalID.h"
// ROOT
#include "TF1.h"
// STL
#include <string>
#include <vector>
......@@ -45,6 +39,10 @@ class CaloWaveformDigiAlg: public AthReentrantAlgorithm {
virtual StatusCode finalize() override;
//@}
//
// Simulate detailed timing of waveforms
BooleanProperty m_advancedTiming{this, "AdvancedTiming", true};
private:
/** @name Disallow default instantiation, copy, assignment */
......@@ -54,49 +52,38 @@ class CaloWaveformDigiAlg: public AthReentrantAlgorithm {
CaloWaveformDigiAlg &operator=(const CaloWaveformDigiAlg&) = delete;
//@}
// We use these a lot, so read them once from the conditions tool
mutable float m_base_mean;
mutable float m_base_rms;
/** Kernel PDF and evaluated values **/
// Mark these mutable, as they must be changed on first event...
//@{
mutable TF1* m_kernel;
mutable std::vector<float> m_timekernel;
//@}
/// Detector ID helper
const EcalID* m_ecalID{nullptr};
/**
* @name Digitisation tool
*/
//@{
ToolHandle<IWaveformDigitisationTool> m_digiTool
{this, "WaveformDigitisationTool", "WaveformDigitisationTool"};
//@}
/**
* @name Mapping tool
*/
//@{
ToolHandle<IWaveformCableMappingTool> m_mappingTool
{this, "WaveformCableMappingTool", "WaveformCableMappingTool"};
//@}
/**
* @name Digitization parameters tool
*/
//@{
ToolHandle<IWaveformDigiConditionsTool> m_digiCondTool
{this, "DigiConditionsTool", "CaloDigiConditionsTool"};
//@}
/**
* @name Input HITS using SG::ReadHandleKey
*/
//@{
SG::ReadHandleKey<CaloHitCollection> m_caloHitContainerKey
{this, "CaloHitContainerKey", ""};
//@}
/**
* @name Output data using SG::WriteHandleKey
*/
......@@ -105,6 +92,7 @@ class CaloWaveformDigiAlg: public AthReentrantAlgorithm {
{this, "WaveformContainerKey", ""};
//@}
mutable bool m_first {true};
};
......
......@@ -5,23 +5,19 @@
# Declare the package name:
atlas_subdir( FaserCaloSimEventAthenaPool )
# External dependencies:
find_package( ROOT COMPONENTS Core Tree MathCore Hist RIO pthread )
# Component(s) in the package:
atlas_add_poolcnv_library( FaserCaloSimEventAthenaPoolPoolCnv
src/*.cxx
src/*.h src/*.cxx
FILES FaserCaloSimEvent/CaloHitCollection.h
INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
LINK_LIBRARIES ${ROOT_LIBRARIES} AthenaPoolCnvSvcLib AthenaPoolUtilities AtlasSealCLHEP GaudiKernel FaserCaloSimEventTPCnv FaserCaloSimEvent )
LINK_LIBRARIES AthenaPoolCnvSvcLib AthenaPoolUtilities GaudiKernel FaserCaloSimEventTPCnv FaserCaloSimEvent )
atlas_add_dictionary( FaserCaloSimEventAthenaPoolCnvDict
FaserCaloSimEventAthenaPool/CaloSimEventAthenaPoolCnvDict.h
FaserCaloSimEventAthenaPool/selection.xml
INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
LINK_LIBRARIES ${ROOT_LIBRARIES} AthenaPoolCnvSvcLib AthenaPoolUtilities AtlasSealCLHEP GaudiKernel FaserCaloSimEventTPCnv FaserCaloSimEvent )
# atlas_add_dictionary( FaserCaloSimEventAthenaPoolCnvDict
# FaserCaloSimEventAthenaPool/CaloSimEventAthenaPoolCnvDict.h
# FaserCaloSimEventAthenaPool/selection.xml
# INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
# LINK_LIBRARIES ${ROOT_LIBRARIES} AthenaPoolCnvSvcLib AthenaPoolUtilities AtlasSealCLHEP GaudiKernel FaserCaloSimEventTPCnv FaserCaloSimEvent )
# Install files from the package:
atlas_install_headers( FaserCaloSimEventAthenaPool )
# atlas_install_headers( FaserCaloSimEventAthenaPool )
#atlas_install_joboptions( share/*.py )
......@@ -7,20 +7,17 @@ atlas_subdir( FaserCaloSimEventTPCnv )
# External dependencies:
find_package( CLHEP )
find_package( ROOT COMPONENTS Core Tree MathCore Hist RIO pthread )
# Component(s) in the package:
atlas_add_library( FaserCaloSimEventTPCnv
src/CaloHits/*.cxx
PUBLIC_HEADERS FaserCaloSimEventTPCnv
PRIVATE_INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} ${CLHEP_INCLUDE_DIRS}
PRIVATE_INCLUDE_DIRS ${CLHEP_INCLUDE_DIRS}
PRIVATE_DEFINITIONS ${CLHEP_DEFINITIONS}
LINK_LIBRARIES GaudiKernel GeneratorObjectsTPCnv FaserCaloSimEvent AthenaPoolCnvSvcLib StoreGateLib SGtests
PRIVATE_LINK_LIBRARIES ${ROOT_LIBRARIES} ${CLHEP_LIBRARIES} TestTools Identifier )
LINK_LIBRARIES GeneratorObjectsTPCnv FaserCaloSimEvent AthenaPoolCnvSvcLib
PRIVATE_LINK_LIBRARIES ${CLHEP_LIBRARIES} AthenaKernel GaudiKernel GeneratorObjects Identifier StoreGateLib)
atlas_add_dictionary( FaserCaloSimEventTPCnvDict
FaserCaloSimEventTPCnv/CaloSimEventTPCnvDict.h
FaserCaloSimEventTPCnv/selection.xml
INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} ${CLHEP_INCLUDE_DIRS}
LINK_LIBRARIES ${ROOT_LIBRARIES} ${CLHEP_LIBRARIES} AthenaPoolCnvSvcLib GaudiKernel GeneratorObjectsTPCnv FaserCaloSimEvent TestTools StoreGateLib SGtests Identifier FaserCaloSimEventTPCnv AthenaKernel)
LINK_LIBRARIES FaserCaloSimEventTPCnv)
......@@ -329,7 +329,7 @@ void CaloHitCollectionCnv_p1::persToTrans(const CaloHitCollection_p1* persCont,
HepGeom::Point3D<double> endThis( endLast + r );
HepMcParticleLink::PositionFlag flag = HepMcParticleLink::IS_INDEX;
HepMcParticleLink::PositionFlag flag = HepMcParticleLink::IS_EVENTNUM;
if (persCont->m_mcEvtIndex[idxBC] == 0) {
flag = HepMcParticleLink::IS_POSITION;
}
......
......@@ -321,7 +321,7 @@ void CaloHitCollectionCnv_p1a::persToTrans(const CaloHitCollection_p1a* persCont
HepGeom::Point3D<double> endThis( endLast + r );
HepMcParticleLink::PositionFlag flag = HepMcParticleLink::IS_INDEX;
HepMcParticleLink::PositionFlag flag = HepMcParticleLink::IS_EVENTNUM;
if (persCont->m_mcEvtIndex[idxBC] == 0) {
flag = HepMcParticleLink::IS_POSITION;
}
......
......@@ -9,14 +9,33 @@ atlas_subdir( EcalG4_SD )
find_package( CLHEP )
find_package( Geant4 )
find_package( XercesC )
find_package( GeoModel COMPONENTS GeoModelKernel GeoModelRead GeoModelDBManager )
# Component(s) in the package:
atlas_add_component( EcalG4_SD
src/*.cxx
src/components/*.cxx
INCLUDE_DIRS ${GEANT4_INCLUDE_DIRS} ${XERCESC_INCLUDE_DIRS} ${CLHEP_INCLUDE_DIRS}
LINK_LIBRARIES ${GEANT4_LIBRARIES} ${XERCESC_LIBRARIES} ${CLHEP_LIBRARIES} StoreGateLib SGtests GaudiKernel FaserCaloSimEvent G4AtlasToolsLib FaserMCTruth )
atlas_add_library( EcalG4_SDLib
src/*.cxx
OBJECT
NO_PUBLIC_HEADERS
INCLUDE_DIRS ${XERCESC_INCLUDE_DIRS} ${CLHEP_INCLUDE_DIRS} ${GEANT4_INCLUDE_DIRS} ${GEOMODEL_INCLUDE_DIRS}
LINK_LIBRARIES ${XERCESC_LIBRARIES} ${CLHEP_LIBRARIES} ${GEANT4_LIBRARIES} ${GEOMODEL_LIBRARIES} G4AtlasToolsLib FaserCaloSimEvent FaserMCTruth StoreGateLib GeoModelInterfaces GeoPrimitives )
atlas_add_library( EcalG4_SD
src/components/*.cxx
OBJECT
NO_PUBLIC_HEADERS
PRIVATE_LINK_LIBRARIES EcalG4_SDLib )
# atlas_add_component( EcalG4_SD
# src/*.cxx
# src/components/*.cxx
# INCLUDE_DIRS ${GEANT4_INCLUDE_DIRS} ${XERCESC_INCLUDE_DIRS} ${CLHEP_INCLUDE_DIRS}
# LINK_LIBRARIES ${GEANT4_LIBRARIES} ${XERCESC_LIBRARIES} ${CLHEP_LIBRARIES} StoreGateLib SGtests GaudiKernel FaserCaloSimEvent G4AtlasToolsLib FaserMCTruth )
# Install files from the package:
atlas_install_python_modules( python/*.py )
......@@ -280,9 +280,9 @@ inline double EcalSensorSD::localNonUniformity (double x, double y) const
// Local uniformity is product of x and y sine-like functions
// The Amplitude of the sin-like function is a function of x and y
// Deion: changed LHCb's parametrization by adding the (- A_local) at the end in order to center the correction on zero
if ( A_local > lowTolerance )
correction += A_local / 2. * ( 1. - cos( 2. * CLHEP::pi * (x-x0)/d ) ) *
( 1. - cos( 2. * CLHEP::pi * (y-y0)/d ) ) ;
correction += A_local / 2. * ( 1. - cos( 2. * CLHEP::pi * (x-x0)/d ) ) * ( 1. - cos( 2. * CLHEP::pi * (y-y0)/d ) ) - A_local ;
double rX(0.) , rY(0.) , hCell(0.) ;
......
......@@ -21,7 +21,7 @@ EcalSensorSDTool::EcalSensorSDTool(const std::string& type, const std::string& n
, m_birk_c1 ( 0.013 * CLHEP::g/CLHEP::MeV/CLHEP::cm2 ) // 1st coef. of Birk's
, m_birk_c2 ( 9.6E-6 * CLHEP::g*CLHEP::g/CLHEP::MeV/CLHEP::MeV/CLHEP::cm2/CLHEP::cm2 ) // 2nd coef. of Birk's law
, m_birk_c1correction ( 0.57142857) //correction of c1 for 2e charged part.
, m_a_local_outer_ecal ( 0. )
, m_a_local_outer_ecal ( 0.05 ) // sinusoidal non uniformity amplitude
, m_a_global_outer_ecal ( 0.03 ) // global non uniformity amplitude
, m_a_reflection_height ( 0.09 ) // reflection on the edges - height
, m_a_reflection_width ( 6. * CLHEP::mm ) // reflection on the edges - width
......
""" Define methods used to instantiate configured Calorimeter Calibration reconstruction tools and algorithms
"""
Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
Copyright (C) 2022 CERN for the benefit of the FASER collaboration
Define methods used to instantiate configured Calorimeter Calibration reconstruction tools and algorithms
"""
from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
from AthenaConfiguration.ComponentFactory import CompFactory
from IOVDbSvc.IOVDbSvcConfig import addFolders
#from IOVDbSvc.IOVDbSvcConfig import addFolders
from OutputStreamAthenaPool.OutputStreamConfig import OutputStreamCfg
from CaloRecTools.CaloRecToolConfig import CaloRecToolCfg
......@@ -15,8 +18,11 @@ def CalorimeterReconstructionCfg(flags, **kwargs):
acc = ComponentAccumulator()
kwargs.setdefault("CaloWaveHitContainerKey", "CaloWaveformHits")
kwargs.setdefault("Calo2WaveHitContainerKey", "Calo2WaveformHits")
kwargs.setdefault("PreshowerWaveHitContainerKey", "PreshowerWaveformHits")
kwargs.setdefault("CaloHitContainerKey", "CaloHits")
kwargs.setdefault("Calo2HitContainerKey", "Calo2Hits")
kwargs.setdefault("PreshowerHitContainerKey", "PreshowerHits")
acc.merge(CaloRecToolCfg(flags, **kwargs))
......@@ -34,7 +40,7 @@ def CalorimeterReconstructionOutputCfg(flags, **kwargs):
"xAOD::CalorimeterHitContainer#*"
, "xAOD::CalorimeterHitAuxContainer#*"
]
acc.merge(OutputStreamCfg(flags, "xAOD", ItemList))
acc.merge(OutputStreamCfg(flags, "xAOD", ItemList, disableEventTag=True))
# ostream = acc.getEventAlgo("OutputStreamRDO")
# ostream.TakeItemsFromInput = True # Don't know what this does
return acc
......
......@@ -12,23 +12,19 @@ StatusCode CaloRecAlg::initialize() {
// Set key to read calo hits from
ATH_CHECK( m_caloWaveHitContainerKey.initialize() );
ATH_CHECK( m_calo2WaveHitContainerKey.initialize() );
// Set key to read preshower hits from
ATH_CHECK( m_preshowerWaveHitContainerKey.initialize() );
// Set key to write container
ATH_CHECK( m_caloHitContainerKey.initialize() );
ATH_CHECK( m_calo2HitContainerKey.initialize() );
ATH_CHECK( m_preshowerHitContainerKey.initialize() );
// Initalize tools
ATH_CHECK( m_recoCalibTool.retrieve() );
// Store calibrattiion factos in a vector for ease of access
m_EM_mu_Map[0] = m_calo_ch0_EM_mu;
m_EM_mu_Map[1] = m_calo_ch1_EM_mu;
m_EM_mu_Map[2] = m_calo_ch2_EM_mu;
m_EM_mu_Map[3] = m_calo_ch3_EM_mu;
return StatusCode::SUCCESS;
}
//----------------------------------------------------------------------
......@@ -54,6 +50,8 @@ StatusCode CaloRecAlg::execute(const EventContext& ctx) const {
ATH_MSG_DEBUG("Calorimeter Waveform Hit container found with zero length!");
}
SG::ReadHandle<xAOD::WaveformHitContainer> calo2WaveHitHandle(m_calo2WaveHitContainerKey, ctx);
SG::ReadHandle<xAOD::WaveformHitContainer> preshowerWaveHitHandle(m_preshowerWaveHitContainerKey, ctx);
ATH_CHECK( preshowerWaveHitHandle.isValid() );
......@@ -63,116 +61,67 @@ StatusCode CaloRecAlg::execute(const EventContext& ctx) const {
ATH_MSG_DEBUG("Preshower Waveform Hit container found with zero length!");
}
// Find the output waveform container
// Only correct gain in real data
bool correct_gain = !m_isMC;
// Reconstruct calorimeter hits
SG::WriteHandle<xAOD::CalorimeterHitContainer> caloHitContainerHandle(m_caloHitContainerKey, ctx);
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");
// Loop over calo hits and calibrate each primary hit
for( const auto& hit : *caloWaveHitHandle ) {
if (hit->status_bit(xAOD::WaveformStatus::SECONDARY)) continue;
// Create a new calo hit
xAOD::CalorimeterHit* calo_hit = new xAOD::CalorimeterHit();
caloHitContainerHandle->push_back(calo_hit);
ATH_MSG_DEBUG("calo_hit in channel " << hit->channel() );
float MIPcharge_ref = m_recoCalibTool->getMIPcharge_ref(hit->channel()); // get reference MIP charge from database
float charge = hit->integral()/50.0; // divide by 50 ohms to get charge
ATH_MSG_DEBUG("calo_hit filled has charge of " << charge << " pC");
float gainRatio = 1.0;
if (!m_isMC) { // MC already has correct MIP charge stored in MIPcharge_ref, so only need to to HV extrapolation with reral data
gainRatio = extrapolateHVgain(hit->channel());
}
ATH_MSG_DEBUG("HV gain ratio = " << gainRatio );
float Nmip = (charge * gainRatio) / MIPcharge_ref;
ATH_MSG_DEBUG("Nmip = " << Nmip );
calo_hit->set_Nmip(Nmip); // set Nmip value
float E_dep = Nmip * m_MIP_sim_Edep_calo;
ATH_MSG_DEBUG("E_dep in MeV = " << E_dep );
calo_hit->set_E_dep(E_dep); // set calibrated E_dep value
float E_EM = Nmip * m_EM_mu_Map[hit->channel()];
ATH_MSG_DEBUG("Em E in MeV = " << E_EM );
calo_hit->set_E_EM(E_EM); // set calibrated E_EM value
float fit_to_raw_ratio = 1.0;
if (hit->integral() != 0.0) { // avoid possibility of division by zero error
fit_to_raw_ratio = hit->raw_integral() / hit->integral();
}
calo_hit->set_fit_to_raw_ratio(fit_to_raw_ratio); // set fit-to-raw-ratio that can be used to take any of the calibrated values to what they would be if we used the raw integral instead of the fit integral
calo_hit->set_channel(hit->channel()); // set channel number
calo_hit->clearWaveformLinks();
calo_hit->addHit(caloWaveHitHandle.get(), hit); // create link to calo waveform hit
calo_hit->addHit(caloWaveHitHandle.get(), hit);
m_recoCalibTool->reconstruct(ctx, calo_hit, correct_gain);
}
ATH_MSG_DEBUG("CaloHitContainer '" << caloHitContainerHandle.name() << "' filled with "<< caloHitContainerHandle->size() <<" items");
// Reconstruct preshower hits
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 '" << preshowerHitContainerHandle.name() << "' initialized");
for( const auto& hit : *preshowerWaveHitHandle ) {
if (hit->status_bit(xAOD::WaveformStatus::SECONDARY)) continue;
xAOD::CalorimeterHit* calo_hit = new xAOD::CalorimeterHit();
preshowerHitContainerHandle->push_back(calo_hit);
calo_hit->addHit(preshowerWaveHitHandle.get(), hit);
m_recoCalibTool->reconstruct(ctx, calo_hit, correct_gain=false);
}
ATH_MSG_DEBUG("PreshowerHitContainer '" << preshowerHitContainerHandle.name() << "' filled with "<< preshowerHitContainerHandle->size() <<" items");
// High-gain calo isn't guaranteed to exist
if ( calo2WaveHitHandle.isValid() ) {
ATH_MSG_DEBUG("Found ReadHandle for WaveformHitContainer " << m_calo2WaveHitContainerKey);
// 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 MIPcharge_ref = m_recoCalibTool->getMIPcharge_ref(hit->channel()); // get reference MIP charge from database
float charge = hit->integral()/50.0; // divide by 50 ohms to get charge
ATH_MSG_DEBUG("preshower_hit filled has charge of " << charge << " pC");
float Nmip = charge / MIPcharge_ref;
ATH_MSG_DEBUG("Nmip = " << Nmip );
preshower_hit->set_Nmip(Nmip); // set Nmip value
float E_dep = Nmip * m_MIP_sim_Edep_preshower;
ATH_MSG_DEBUG("E_dep in GeV = " << E_dep );
preshower_hit->set_E_dep(E_dep); // set calibrated E_dep value
if (calo2WaveHitHandle->size() == 0) {
ATH_MSG_DEBUG("Calorimeter 2 Waveform Hit container found with zero length!");
}
float fit_to_raw_ratio = 1.0;
if (hit->integral() != 0.0) { // avoid possibility of division by zero error
fit_to_raw_ratio = hit->raw_integral() / hit->integral();
// Reconstruct high-gain calorimeter hits
SG::WriteHandle<xAOD::CalorimeterHitContainer> calo2HitContainerHandle(m_calo2HitContainerKey, ctx);
ATH_CHECK( calo2HitContainerHandle.record( std::make_unique<xAOD::CalorimeterHitContainer>(),
std::make_unique<xAOD::CalorimeterHitAuxContainer>() ) );
ATH_MSG_DEBUG("WaveformsHitContainer '" << calo2HitContainerHandle.name() << "' initialized");
for( const auto& hit : *calo2WaveHitHandle ) {
if (hit->status_bit(xAOD::WaveformStatus::SECONDARY)) continue;
xAOD::CalorimeterHit* calo_hit = new xAOD::CalorimeterHit();
calo2HitContainerHandle->push_back(calo_hit);
calo_hit->addHit(calo2WaveHitHandle.get(), hit);
m_recoCalibTool->reconstruct(ctx, calo_hit, correct_gain=false);
}
preshower_hit->set_fit_to_raw_ratio(fit_to_raw_ratio); // set fit-to-raw-ratio that can be used to take any of the calibrated values to what they would be if we used the raw integral instead of the fit integral
ATH_MSG_DEBUG("Calo2HitContainer '" << calo2HitContainerHandle.name() << "' filled with "<< calo2HitContainerHandle->size() <<" items");
preshower_hit->set_channel(hit->channel()); // set channel number
preshower_hit->clearWaveformLinks();
preshower_hit->addHit(preshowerWaveHitHandle.get(), hit); // create link to preshower waveform hit
} else {
ATH_MSG_DEBUG("No ReadHandle for WaveformHitContainer " << m_calo2WaveHitContainerKey);
}
ATH_MSG_DEBUG("PreshowerHitContainer '" << preshowerHitContainerHandle.name() << "' filled with "<< preshowerHitContainerHandle->size() <<" items");
return StatusCode::SUCCESS;
}
//----------------------------------------------------------------------
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);
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);
}
//----------------------------------------------------------------------
......@@ -71,6 +71,10 @@ class CaloRecAlg : public AthReentrantAlgorithm {
SG::ReadHandleKey<xAOD::WaveformHitContainer> m_caloWaveHitContainerKey {this, "CaloWaveHitContainerKey", "CaloWaveformHits"};
//@}
//@{
SG::ReadHandleKey<xAOD::WaveformHitContainer> m_calo2WaveHitContainerKey {this, "Calo2WaveHitContainerKey", "Calo2WaveformHits"};
//@}
//@{
SG::ReadHandleKey<xAOD::WaveformHitContainer> m_preshowerWaveHitContainerKey {this, "PreshowerWaveHitContainerKey", "PreshowerWaveformHits"};
//@}
......@@ -80,21 +84,10 @@ class CaloRecAlg : public AthReentrantAlgorithm {
*/
//@{
SG::WriteHandleKey<xAOD::CalorimeterHitContainer> m_caloHitContainerKey {this, "CaloHitContainerKey", "CaloHits"};
SG::WriteHandleKey<xAOD::CalorimeterHitContainer> m_calo2HitContainerKey {this, "Calo2HitContainerKey", "Calo2Hits"};
SG::WriteHandleKey<xAOD::CalorimeterHitContainer> m_preshowerHitContainerKey {this, "PreshowerHitContainerKey", "PreshowerHits"};
//@}
float extrapolateHVgain(int channel) const;
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
FloatProperty m_calo_ch0_EM_mu {this, "m_calo_ch0_EM_mu", 330.0}; // factor used to do rough calibration of calo ch0 to EM energy: 0.33 GeV or 330 MeV
FloatProperty m_calo_ch1_EM_mu {this, "m_calo_ch1_EM_mu", 330.0}; // factor used to do rough calibration of calo ch1 to EM energy: 0.33 GeV or 330 MeV
FloatProperty m_calo_ch2_EM_mu {this, "m_calo_ch2_EM_mu", 330.0}; // factor used to do rough calibration of calo ch2 to EM energy: 0.33 GeV or 330 MeV
FloatProperty m_calo_ch3_EM_mu {this, "m_calo_ch3_EM_mu", 330.0}; // factor used to do rough calibration of calo ch3 to EM energy: 0.33 GeV or 330 MeV
float m_EM_mu_Map[4]; // vector that holds EM_mu calibration factors for calo channels
Gaudi::Property<bool> m_isMC {this, "isMC", false};
};
......
......@@ -13,7 +13,8 @@ atlas_add_library( CaloRecToolsLib
CaloRecTools/*.h src/*.cxx src/*.h
PUBLIC_HEADERS CaloRecTools
PRIVATE_INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
LINK_LIBRARIES AthenaBaseComps AthenaPoolUtilities AthenaKernel GaudiKernel
LINK_LIBRARIES xAODFaserWaveform xAODFaserCalorimeter
AthenaBaseComps AthenaPoolUtilities AthenaKernel GaudiKernel
PRIVATE_LINK_LIBRARIES ${ROOT_LIBRARIES}
)
......
......@@ -17,6 +17,10 @@
#include "GaudiKernel/ToolHandle.h"
#include "GaudiKernel/EventContext.h"
// Data Classes
// #include "xAODFaserWaveform/WaveformHit.h"
#include "xAODFaserCalorimeter/CalorimeterHit.h"
#include "TF1.h"
///Interface for Calo reco algorithms
......@@ -40,6 +44,11 @@ class ICaloRecTool : virtual public IAlgTool
virtual float getMIPcharge_ref(int channel) const = 0;
virtual TF1 get_PMT_HV_curve(int channel) const = 0;
// Reconstruct one waveform hit and put the resulting Calorimeter hit in the container
virtual void reconstruct(const EventContext& ctx,
xAOD::CalorimeterHit* hit,
bool correct_gain) const = 0;
};
#endif // CALORECTOOL_ICALORECTOOL_H
......@@ -40,6 +40,29 @@ CaloRecTool::initialize() {
HVgaincurves_rootFile->Close(); // close the root file
// These should be in DB, but just hardcode this for now
m_MIP_sim_Edep[0] = m_MIP_sim_Edep_calo.value();
m_MIP_sim_Edep[1] = m_MIP_sim_Edep_calo.value();
m_MIP_sim_Edep[2] = m_MIP_sim_Edep_calo.value();
m_MIP_sim_Edep[3] = m_MIP_sim_Edep_calo.value();
m_MIP_sim_Edep[12] = m_MIP_sim_Edep_preshower.value();
m_MIP_sim_Edep[13] = m_MIP_sim_Edep_preshower.value();
m_MIP_sim_Edep[16] = m_MIP_sim_Edep_calo2.value();
m_MIP_sim_Edep[17] = m_MIP_sim_Edep_calo2.value();
m_MIP_sim_Edep[18] = m_MIP_sim_Edep_calo2.value();
m_MIP_sim_Edep[19] = m_MIP_sim_Edep_calo2.value();
m_EM_mu_Map[0] = m_calo_EM_mu.value();
m_EM_mu_Map[1] = m_calo_EM_mu.value();
m_EM_mu_Map[2] = m_calo_EM_mu.value();
m_EM_mu_Map[3] = m_calo_EM_mu.value();
m_EM_mu_Map[16] = m_calo_EM_mu.value();
m_EM_mu_Map[17] = m_calo_EM_mu.value();
m_EM_mu_Map[18] = m_calo_EM_mu.value();
m_EM_mu_Map[19] = m_calo_EM_mu.value();
return StatusCode::SUCCESS;
}
......@@ -150,7 +173,7 @@ float CaloRecTool::getMIPcharge_ref(const EventContext& ctx, int channel) const
ATH_MSG_DEBUG("in getMIPcharge_ref("<<channel<<")");
float MIP_charge_ref =0.;
float MIP_charge_ref =1.; // Default for no calibration parameters
// Read Cond Handle
SG::ReadCondHandle<CondAttrListCollection> readHandle{m_MIP_ref_ReadKey, ctx};
......@@ -187,8 +210,63 @@ float CaloRecTool::getMIPcharge_ref(int channel) const {
return CaloRecTool::getMIPcharge_ref(ctx, channel);
}
//----------------------------------------------------------------------
float CaloRecTool::extrapolateHVgain(const EventContext& ctx, int channel) const {
float PMT_hv = getHV(ctx, channel);
float PMT_hv_ref = getHV_ref(ctx, channel);
TF1 gaincurve = get_PMT_HV_curve(channel);
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);
}
//--------------------------------------------------------------
//----------------------------------------------------------------------
// Reconstruct one waveform hit
//xAOD::CalorimeterHit*
void
CaloRecTool::reconstruct(const EventContext& ctx,
xAOD::CalorimeterHit* calo_hit,
bool correct_gain=false) const {
// Get the waveform hit attached to this calo hit
const xAOD::WaveformHit* wave_hit = calo_hit->Hit(0);
ATH_MSG_DEBUG("calo_hit in channel " << wave_hit->channel() );
float MIPcharge_ref = getMIPcharge_ref(ctx, wave_hit->channel()); // get reference MIP charge from database
float charge = wave_hit->integral()/50.0; // divide by 50 ohms to get charge
ATH_MSG_DEBUG("calo_hit filled has charge of " << charge << " pC");
float gainRatio = 1.0;
if (correct_gain) { // MC already has correct MIP charge stored in MIPcharge_ref, so only need to to HV extrapolation with reral data
gainRatio = extrapolateHVgain(ctx, wave_hit->channel());
}
ATH_MSG_DEBUG("HV gain ratio = " << gainRatio );
float Nmip = (charge * gainRatio) / MIPcharge_ref;
ATH_MSG_DEBUG("Nmip = " << Nmip );
calo_hit->set_Nmip(Nmip); // set Nmip value
float E_dep = Nmip * m_MIP_sim_Edep[wave_hit->channel()];
ATH_MSG_DEBUG("E_dep in MeV = " << E_dep );
calo_hit->set_E_dep(E_dep); // set calibrated E_dep value
float E_EM = Nmip * m_EM_mu_Map[wave_hit->channel()];
ATH_MSG_DEBUG("Em E in MeV = " << E_EM );
calo_hit->set_E_EM(E_EM); // set calibrated E_EM value
float fit_to_raw_ratio = 1.0;
if (wave_hit->integral() != 0.0) { // avoid possibility of division by zero error
fit_to_raw_ratio = wave_hit->raw_integral() / wave_hit->integral();
}
calo_hit->set_fit_to_raw_ratio(fit_to_raw_ratio); // set fit-to-raw-ratio that can be used to take any of the calibrated values to what they would be if we used the raw integral instead of the fit integral
}
......@@ -25,6 +25,10 @@
#include "Gaudi/Property.h"
#include "GaudiKernel/EventContext.h"
// Data Classes
#include "xAODFaserWaveform/WaveformHit.h"
#include "xAODFaserCalorimeter/CalorimeterHit.h"
// Include ROOT classes
#include "TF1.h"
#include "TFile.h"
......@@ -57,6 +61,11 @@ class CaloRecTool: public extends<AthAlgTool, ICaloRecTool> {
// method for returning PMT HV calibration curves from root file
virtual TF1 get_PMT_HV_curve(int channel) const override;
// Reconstruct one waveform hit and put the resulting Calorimeter hit in the container
virtual void reconstruct(const EventContext& ctx,
xAOD::CalorimeterHit* hit,
bool correct_gain) const override;
TFile* HVgaincurves_rootFile;
TF1* chan0_HVgaincurve_pntr;
......@@ -80,6 +89,18 @@ class CaloRecTool: public extends<AthAlgTool, ICaloRecTool> {
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_MIP_ref_ReadKey{this, "MIP_ref_ReadKey", "/WAVE/Calibration/MIP_ref", "Key of folder for MIP charge calibration measurment, also stores PMT HV used to measure the reference MIP charge"};
// Could also put these in DB, but just hardcode them for now
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_calo2 {this, "MIP_sim_Edep_calo2", 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
FloatProperty m_calo_EM_mu {this, "m_calo_EM_mu", 330.0}; // factor used to do rough calibration of calo to EM energy: 0.33 GeV or 330 MeV
float m_MIP_sim_Edep[32]; // vector that holds Edep factors for calo and preshower
float m_EM_mu_Map[32]; // vector that holds EM_mu calibration factors for calo channels
float extrapolateHVgain(const EventContext& ctx, int channel) const;
};
#endif // CALORECTOOLS_CALORECTOOL_H
......@@ -69,7 +69,7 @@ public:
CaloHit();
// Destructor:
virtual ~CaloHit();
virtual ~CaloHit() = default;
//move assignment defaulted
CaloHit & operator = (CaloHit &&) = default;
......@@ -77,6 +77,8 @@ public:
CaloHit & operator = (const CaloHit &) = default;
//copy c'tor defaulted
CaloHit(const CaloHit &) = default;
//move c'tor defaulted
CaloHit(CaloHit &&) noexcept = default;
///////////////////////////////////////////////////////////////////
// Const methods:
......
......@@ -22,9 +22,6 @@ CaloHit::CaloHit( ) :
}
CaloHit::~CaloHit() {}
// Constructor
CaloHit::CaloHit(const HepGeom::Point3D<double> &localStartPosition,
const HepGeom::Point3D<double> &localEndPosition,
......
# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
from AthenaConfiguration.AllConfigFlags import ConfigFlags as athenaConfigFlags
from AthenaConfiguration.AllConfigFlags import initConfigFlags as athenaConfigFlags
# from AthenaConfiguration.AllConfigFlags import GetFileMD
# from AthenaConfiguration.AthConfigFlags import AthConfigFlags
# from AthenaCommon.SystemOfUnits import TeV
......@@ -30,7 +30,7 @@ def _addFlagsCategory (acf, name, generator, modName = None):
def _createCfgFlags():
# acf=AthConfigFlags()
fcf = athenaConfigFlags
fcf = athenaConfigFlags()
fcf.Input.Files = ["_CALYPSO_GENERIC_INPUTFILE_NAME_",] # former global.InputFiles
# acf.addFlag('Input.SecondaryFiles', []) # secondary input files for DoubleEventSelector
......@@ -197,19 +197,19 @@ def _createCfgFlags():
return fcf
ConfigFlags=_createCfgFlags()
del _createCfgFlags
def initConfigFlags():
fcf = _createCfgFlags()
return fcf
if __name__=="__main__":
import sys
flags = initConfigFlags()
if len(sys.argv)>1:
ConfigFlags.Input.Files = sys.argv[1:]
flags.Input.Files = sys.argv[1:]
else:
ConfigFlags.Input.Files = [ "/cvmfs/atlas-nightlies.cern.ch/repo/data/data-art/CommonInputs/data16_13TeV.00311321.physics_Main.recon.AOD.r9264/AOD.11038520._000001.pool.root.1",]
flags.Input.Files = [ "/cvmfs/atlas-nightlies.cern.ch/repo/data/data-art/CommonInputs/data16_13TeV.00311321.physics_Main.recon.AOD.r9264/AOD.11038520._000001.pool.root.1",]
ConfigFlags.loadAllDynamicFlags()
ConfigFlags.initAll()
ConfigFlags.dump()
flags.loadAllDynamicFlags()
flags.initAll()
flags.dump()