From 0a0cf93a5f6d886835069bb957d7d51197d55cbd Mon Sep 17 00:00:00 2001 From: Katerina Kostova Date: Thu, 8 Aug 2024 15:02:26 +0200 Subject: [PATCH] Fix pre-commit --- k4GaudiPandora/include/DDBFieldPlugin.h | 42 +- k4GaudiPandora/include/DDCaloDigi.h | 633 ++++--- k4GaudiPandora/include/DDCaloHitCreator.h | 329 ++-- .../include/DDExternalClusteringAlgorithm.h | 62 +- k4GaudiPandora/include/DDGeometryCreator.h | 132 +- k4GaudiPandora/include/DDMCParticleCreator.h | 95 +- .../include/DDPandoraPFANewProcessor.h | 200 +-- k4GaudiPandora/include/DDPfoCreator.h | 195 ++- .../include/DDScintillatorPpdDigi.h | 56 +- k4GaudiPandora/include/DDTrackCreatorBase.h | 393 ++--- k4GaudiPandora/include/DDTrackCreatorCLIC.h | 104 +- k4GaudiPandora/include/DDTrackCreatorILD.h | 131 +- k4GaudiPandora/src/DDBFieldPlugin.cc | 53 +- k4GaudiPandora/src/DDCaloDigi.cc | 8 +- k4GaudiPandora/src/DDCaloHitCreator.cc | 1480 ++++++++--------- .../src/DDExternalClusteringAlgorithm.cc | 181 +- k4GaudiPandora/src/DDGeometryCreator.cc | 655 ++++---- k4GaudiPandora/src/DDMCParticleCreator.cc | 372 ++--- .../src/DDPandoraPFANewProcessor.cc | 1449 +++++++--------- k4GaudiPandora/src/DDPfoCreator.cc | 679 ++++---- k4GaudiPandora/src/DDScintillatorPpdDigi.cc | 104 +- k4GaudiPandora/src/DDSimpleMuonDigiOld.cc | 20 +- k4GaudiPandora/src/DDTrackCreatorBase.cc | 913 +++++----- k4GaudiPandora/src/DDTrackCreatorCLIC.cc | 892 +++++----- k4GaudiPandora/src/DDTrackCreatorILD.cc | 805 +++++---- 25 files changed, 5040 insertions(+), 4943 deletions(-) diff --git a/k4GaudiPandora/include/DDBFieldPlugin.h b/k4GaudiPandora/include/DDBFieldPlugin.h index 1857d23..b2c5254 100644 --- a/k4GaudiPandora/include/DDBFieldPlugin.h +++ b/k4GaudiPandora/include/DDBFieldPlugin.h @@ -1,36 +1,54 @@ +/* + * Copyright (c) 2020-2024 Key4hep-Project. + * + * This file is part of Key4hep. + * See https://key4hep.github.io/key4hep-doc/ for further info. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + /** * @file DDMarlinPandora/include/DDBFieldPlugin.h - * + * * @brief Header file for the BField plugin class. - * + * * $Log: $ */ #ifndef DDBFIELD_PLUGIN_H #define DDBFIELD_PLUGIN_H 1 -#include "Plugins/BFieldPlugin.h" #include "Objects/CartesianVector.h" +#include "Plugins/BFieldPlugin.h" -#include "DD4hep/Fields.h" #include "DD4hep/Detector.h" +#include "DD4hep/Fields.h" //------------------------------------------------------------------------------------------------------------------------------------------ /** * @brief DDBFieldPlugin class */ -class DDBFieldPlugin : public pandora::BFieldPlugin -{ +class DDBFieldPlugin : public pandora::BFieldPlugin { public: - DDBFieldPlugin(const dd4hep::Detector &detector); - float GetBField(const pandora::CartesianVector &positionVector) const; + DDBFieldPlugin(const dd4hep::Detector& detector); + float GetBField(const pandora::CartesianVector& positionVector) const; private: - pandora::StatusCode Initialize(); - pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle); + pandora::StatusCode Initialize(); + pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle); - dd4hep::OverlayedField m_field; ///< The field instance from DD4hep + dd4hep::OverlayedField m_field; ///< The field instance from DD4hep }; -#endif // #ifndef DDBFIELD_PLUGIN_H +#endif // #ifndef DDBFIELD_PLUGIN_H diff --git a/k4GaudiPandora/include/DDCaloDigi.h b/k4GaudiPandora/include/DDCaloDigi.h index a9b34dc..20a6173 100644 --- a/k4GaudiPandora/include/DDCaloDigi.h +++ b/k4GaudiPandora/include/DDCaloDigi.h @@ -1,29 +1,45 @@ +/* + * Copyright (c) 2020-2024 Key4hep-Project. + * + * This file is part of Key4hep. + * See https://key4hep.github.io/key4hep-doc/ for further info. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #ifndef DDCCALODIGI_H #define DDCCALODIGI_H 1 #include "Gaudi/Property.h" #include "GaudiAlg/Transformer.h" -#include "edm4hep/SimCalorimeterHitCollection.h" #include "edm4hep/CalorimeterHitCollection.h" #include "edm4hep/EventHeaderCollection.h" #include "edm4hep/MCRecoCaloAssociationCollection.h" +#include "edm4hep/SimCalorimeterHitCollection.h" #include "k4FWCore/BaseClass.h" #include "k4Interface/IGeoSvc.h" #include "k4Interface/IUniqueIDGenSvc.h" +#include "CLHEP/Random/MTwistEngine.h" #include "CalorimeterHitType.h" +#include "DDScintillatorPpdDigi.h" #include "TFile.h" #include "TH1.h" #include "TH2.h" -#include "DDScintillatorPpdDigi.h" -#include "CLHEP/Random/MTwistEngine.h" #include #include #include - - /** === DDCaloDigi Processor ===
* Simple calorimeter digitizer Processor.
* Ported from ILDCaloDigi to use DD4hep @@ -51,7 +67,7 @@ * a given sampling fraction.
* List of layer numbers terminating each section are given through
* processor parameters ECALLayers and HCALLayers
- * There is an option to perform digitization of
+ * There is an option to perform digitization of
* both ECAL and HCAL in a digital mode.
* Digital mode is activated by
* setting processor parameters
@@ -64,13 +80,13 @@ * Relations between CalorimeterHits and SimCalorimeterHits
* are held in the corresponding relation collection.
* The name of this relation collection is specified
- * via processor parameter RelationOutputCollection.
+ * via processor parameter RelationOutputCollection.
*

Input collections and prerequisites

* SimCalorimeterHit collections
*

Output

* CalorimeterHit collections for ECal and HCal.
* Collection of relations
- * between CalorimeterHits and SimCalorimeterHits.
+ * between CalorimeterHits and SimCalorimeterHits.
* For ECal Calorimeter hits the variable type is set to 0,
* whereas for HCal Calorimeter hits the type is set to 1
* @author A. Raspereza (DESY)
@@ -79,164 +95,267 @@ */ const int MAX_LAYERS = 200; -const int MAX_STAVES = 16; +const int MAX_STAVES = 16; -using retType = std::tuple< - std::map, - edm4hep::MCRecoCaloAssociationCollection>; //FIXME: Does this need to be a map as well??? +using retType = std::tuple, + edm4hep::MCRecoCaloAssociationCollection>; //FIXME: Does this need to be a map as well??? - -struct DDCaloDigi final - : k4FWCore :: MultiTransformer< - (const std::map, - const edm4hep::EventHeaderCollection&)> { +struct DDCaloDigi final : k4FWCore ::MultiTransformer << retType > + (const std::map, const edm4hep::EventHeaderCollection&) > +{ DDCaloDigi(const std::string& name, ISvcLocator* svcLoc); StatusCode initialize() override; StatusCode finalize() override; - std::tuple operator() - (const edm4hep::SimCalorimeterHitCollection& simCaloHits, - const edm4hep::EventHeaderCollection& headers) const override; - - - private: - - - Gaudi::Property _thresholdEcal{this, "ECALThreshold", {5.0e-5}, "Threshold for ECAL Hits in GeV"}; - Gaudi::Property _unitThresholdEcal{this, "ECALThresholdUnit", {"GeV"}, "Unit for ECAL Threshold. Can be \"GeV\", \"MIP\" or \"px\". MIP and px need properly set calibration constants"}; - Gaudi::Property _thresholdHcal{this, "HCALThreshold", {0.00004}, "Unit for ECAL Threshold. Can be \"GeV\", \"MIP\" or \"px\". MIP and px need properly set calibration constants"}; - Gaudi::Property _unitThresholdHcal{this, "HCALThresholdUnit", {"GeV"}, "Unit for HCAL Threshold. Can be \"GeV\", \"MIP\" or \"px\". MIP and px need properly set calibration constants"}; + std::tuple operator()( + const edm4hep::SimCalorimeterHitCollection& simCaloHits, + const edm4hep::EventHeaderCollection& headers) const override; + +private: + Gaudi::Property _thresholdEcal{this, "ECALThreshold", {5.0e-5}, "Threshold for ECAL Hits in GeV"}; + Gaudi::Property _unitThresholdEcal{ + this, + "ECALThresholdUnit", + {"GeV"}, + "Unit for ECAL Threshold. Can be \"GeV\", \"MIP\" or \"px\". MIP and px need properly set calibration constants"}; + Gaudi::Property _thresholdHcal{ + this, + "HCALThreshold", + {0.00004}, + "Unit for ECAL Threshold. Can be \"GeV\", \"MIP\" or \"px\". MIP and px need properly set calibration constants"}; + Gaudi::Property _unitThresholdHcal{ + this, + "HCALThresholdUnit", + {"GeV"}, + "Unit for HCAL Threshold. Can be \"GeV\", \"MIP\" or \"px\". MIP and px need properly set calibration constants"}; std::vector ecalLayers; ecalLayers.push_back(20); ecalLayers.push_back(100); Gaudi::Property> _ecalLayer{this, "ECALLayers", {ecalLayers}, "Index of ECal Layers"}; - std::vector hcalLayers; + std::vector hcalLayers; hcalLayers.push_back(100); Gaudi::Property> _hcalLayer{this, "ECALLayers", {hcalLayers}, "Index of HCal Layers"}; - std::vector calibrEcal; + std::vector calibrEcal; calibrEcal.push_back(40.91); calibrEcal.push_back(81.81); - Gaudi::Property> _calibrCoeffEcal{this, "CalibrECAL", {calibrEcal}, "Calibration coefficients for ECAL"}; + Gaudi::Property> _calibrCoeffEcal{ + this, "CalibrECAL", {calibrEcal}, "Calibration coefficients for ECAL"}; std::vector calibrHcalBarrel; calibrHcalBarrel.push_back(0.); - Gaudi::Property> _calibrCoeffHcalBarrel{this, "CalibrHCALBarrel", {calibrHcalBarrel}, "Calibration coefficients for Barrel HCAL"}; + Gaudi::Property> _calibrCoeffHcalBarrel{ + this, "CalibrHCALBarrel", {calibrHcalBarrel}, "Calibration coefficients for Barrel HCAL"}; std::vector calibrHcalEndCap; calibrHcalEndCap.push_back(0.); - Gaudi::Property> _calibrCoeffHcalEndCap{this, "CalibrHCALEndCap", {calibrHcalEndCap}, "Calibration coefficients for EndCap HCAL"}; + Gaudi::Property> _calibrCoeffHcalEndCap{ + this, "CalibrHCALEndCap", {calibrHcalEndCap}, "Calibration coefficients for EndCap HCAL"}; std::vector calibrHcalOther; calibrHcalOther.push_back(0.); - Gaudi::Property> _calibrCoeffHcalOther{this, "CalibrHCALOther", {calibrHcalOther}, "Calibration coefficients for Other HCAL"}; + Gaudi::Property> _calibrCoeffHcalOther{ + this, "CalibrHCALOther", {calibrHcalOther}, "Calibration coefficients for Other HCAL"}; Gaudi::Property _digitalEcal{this, "IfDigitalEcal", {0}, "Digital Ecal"}; - Gaudi::Property _mapsEcalCorrection{this, "MapsEcalCorrection", {0}, "Ecal correction for theta dependency of calibration for MAPS"}; + Gaudi::Property _mapsEcalCorrection{ + this, "MapsEcalCorrection", {0}, "Ecal correction for theta dependency of calibration for MAPS"}; Gaudi::Property _digitalHcal{this, "IfDigitalHcal", {0}, "Digital Hcal"}; - Gaudi::Property _ecalGapCorrection{this, "ECAconst float slop = 0.25; // (mm)LGapCorrection", {1}, "Correct for ECAL gaps"}; - Gaudi::Property _hcalGapCorrection{this, "HCALGapCorrection", {1}, "Correct for HCAL gaps"}; - Gaudi::Property _ecalEndcapCorrectionFactor{this, "ECALEndcapCorrectionFactor", {1.025}, "Energy correction for ECAL endcap"}; - Gaudi::Property _hcalEndcapCorrectionFactor{this, "HCALEndcapCorrectionFactor", {1.025}, "Energy correction for HCAL endcap"}; - Gaudi::Property _ecalGapCorrectionFactor{this, "ECALGapCorrectionFactor", {1.0}, "Factor applied to gap correction"}; - Gaudi::Property _ecalModuleGapCorrectionFactor{this, "ECALModuleGapCorrectionFactor", {0.5}, "Factor applied to module gap correction ECAL"}; - Gaudi::Property _hcalModuleGapCorrectionFactor{this, "HCALModuleGapCorrectionFactor", {0.5}, "Factor applied to module gap correction HCAL"}; + Gaudi::Property _ecalGapCorrection{ + this, "ECAconst float slop = 0.25; // (mm)LGapCorrection", {1}, "Correct for ECAL gaps"}; + Gaudi::Property _hcalGapCorrection{this, "HCALGapCorrection", {1}, "Correct for HCAL gaps"}; + Gaudi::Property _ecalEndcapCorrectionFactor{ + this, "ECALEndcapCorrectionFactor", {1.025}, "Energy correction for ECAL endcap"}; + Gaudi::Property _hcalEndcapCorrectionFactor{ + this, "HCALEndcapCorrectionFactor", {1.025}, "Energy correction for HCAL endcap"}; + Gaudi::Property _ecalGapCorrectionFactor{ + this, "ECALGapCorrectionFactor", {1.0}, "Factor applied to gap correction"}; + Gaudi::Property _ecalModuleGapCorrectionFactor{ + this, "ECALModuleGapCorrectionFactor", {0.5}, "Factor applied to module gap correction ECAL"}; + Gaudi::Property _hcalModuleGapCorrectionFactor{ + this, "HCALModuleGapCorrectionFactor", {0.5}, "Factor applied to module gap correction HCAL"}; Gaudi::Property _histograms{this, "Histograms", {0}, "Hit times histograms"}; Gaudi::Property _useEcalTiming{this, "UseEcalTiming", {0}, "Use ECAL hit times"}; - Gaudi::Property _ecalCorrectTimesForPropagation{this, "ECALCorrectTimesForPropagation", {0}, "Correct ECAL hit times for propagation: radial distance/c"}; + Gaudi::Property _ecalCorrectTimesForPropagation{ + this, "ECALCorrectTimesForPropagation", {0}, "Correct ECAL hit times for propagation: radial distance/c"}; Gaudi::Property _ecalTimeWindowMin{this, "ECALTimeWindowMin", {-10.0}, "ECAL Time Window minimum time in ns"}; - Gaudi::Property _ecalEndcapTimeWindowMax{this, "ECALEndcapTimeWindowMax", {100}, "ECAL Endcap Time Window maximum time in ns"}; - Gaudi::Property _ecalBarrelTimeWindowMax{this, "ECALBarrelTimeWindowMax", {100}, "ECAL Barrel Time Window maximum time in ns"}; - Gaudi::Property _ecalDeltaTimeHitResolution{this, "ECALDeltaTimeHitResolution", {10}, "ECAL Minimum Delta Time in ns for resolving two hits"}; - Gaudi::Property _ecalTimeResolution{this, "ECALTimeResolution", {10}, "ECAL Time Resolution used to smear hit times"}; - Gaudi::Property _ecalSimpleTimingCut{this, "ECALSimpleTimingCut", {true}, "Use simple time window cut on hit times? If false: use original hit-time clustering algorithm. If true: use time window defined by ECALBarrelTimeWindowMin and ECALBarrelTimeWindowMax"}; + Gaudi::Property _ecalEndcapTimeWindowMax{ + this, "ECALEndcapTimeWindowMax", {100}, "ECAL Endcap Time Window maximum time in ns"}; + Gaudi::Property _ecalBarrelTimeWindowMax{ + this, "ECALBarrelTimeWindowMax", {100}, "ECAL Barrel Time Window maximum time in ns"}; + Gaudi::Property _ecalDeltaTimeHitResolution{ + this, "ECALDeltaTimeHitResolution", {10}, "ECAL Minimum Delta Time in ns for resolving two hits"}; + Gaudi::Property _ecalTimeResolution{ + this, "ECALTimeResolution", {10}, "ECAL Time Resolution used to smear hit times"}; + Gaudi::Property _ecalSimpleTimingCut{ + this, + "ECALSimpleTimingCut", + {true}, + "Use simple time window cut on hit times? If false: use original hit-time clustering algorithm. If true: use " + "time window defined by ECALBarrelTimeWindowMin and ECALBarrelTimeWindowMax"}; Gaudi::Property _useHcalTiming{this, "UseHcalTiming", {1}, "Use HCAL hit times"}; - Gaudi::Property _hcalCorrectTimesForPropagation{this, "HCALCorrectTimesForPropagation", {0}, "Correct HCAL hit times for propagation: radial distance/c"}; + Gaudi::Property _hcalCorrectTimesForPropagation{ + this, "HCALCorrectTimesForPropagation", {0}, "Correct HCAL hit times for propagation: radial distance/c"}; Gaudi::Property _hcalTimeWindowMin{this, "HCALTimeWindowMin", {-10.0}, "HCAL Time Window minimum time in ns"}; - Gaudi::Property _hcalEndcapTimeWindowMax{this, "HCALEndcapTimeWindowMax", {100}, "HCAL Endcap Time Window maximum time in ns"}; - Gaudi::Property _hcalBarrelTimeWindowMax{this, "HCALBarrelTimeWindowMax", {100}, "HCAL Barrel Time Window maximum time in ns"}; - Gaudi::Property _hcalDeltaTimeHitResolution{this, "HCALDeltaTimeHitResolution", {10}, "HCAL Minimum Delta Time in ns for resolving two hits"}; - Gaudi::Property _hcalTimeResolution{this, "HCALTimeResolution", {10}, "HCAL Time Resolution used to smear hit times"}; - Gaudi::Property _hcalSimpleTimingCut{this, "HCALSimpleTimingCut", {true}, "Use simple time window cut on hit times? If false: use original hit-time clustering algorithm. If true: use time window defined by HCALBarrelTimeWindowMin and HCALBarrelTimeWindowMax"}; - Gaudi::Property _calibEcalMip{this, "CalibECALMIP", {1.0e-4}, "calibration to convert ECAL deposited energy to MIPs"}; - Gaudi::Property _applyEcalDigi{this, "ECAL_apply_realistic_digi", {0}, "apply realistic digitisation to ECAL hits? (0=none, 1=silicon, 2=scintillator)"}; - Gaudi::Property _ecal_PPD_pe_per_mip{this, "ECAL_PPD_PE_per_MIP", {7.0}, "# Photo-electrons per MIP (scintillator): used to poisson smear #PEs if >0"}; - Gaudi::Property _ecal_PPD_n_pixels{this, "ECAL_PPD_N_Pixels",{10000},"ECAL total number of MPPC/SiPM pixels for implementation of saturation effect"}; - Gaudi::Property _ecal_misCalibNpix{this, "ECAL_PPD_N_Pixels_uncertainty", {0.05}, "ECAL fractional uncertainty of effective total number of MPPC/SiPM pixels"}; - Gaudi::Property _misCalibEcal_uncorrel{this, "ECAL_miscalibration_uncorrel", {0.0}, "uncorrelated ECAL random gaussian miscalibration (as a fraction: 1.0 = 100%"}; - Gaudi::Property _misCalibEcal_uncorrel_keep{this, "ECAL_miscalibration_uncorrel_memorise", {false}, "store oncorrelated ECAL miscalbrations in memory? (WARNING: can take a lot of memory if used..."}; - Gaudi::Property _misCalibEcal_correl{this, "ECAL_miscalibration_correl", {0.0}, "correlated ECAL random gaussian miscalibration (as a fraction: 1.0 = 100%"}; - Gaudi::Property _deadCellFractionEcal{this, "ECAL_deadCellRate", {0.0}, "ECAL random dead cell fraction (as a fraction: 0->1)"}; - Gaudi::Property _deadCellEcal_keep{this, "ECAL_deadCell_memorise", {false}, "store dead ECAL cells in memory? (WARNING: can take a lot of memory if used..."}; - Gaudi::Property _strip_abs_length{this, "ECAL_strip_absorbtionLength", {1000000.0}, "length scale for absorbtion along scintillator strip (mm)"}; - Gaudi::Property _ecal_pixSpread{this, "ECAL_pixel_spread", {0.05}, "variation of mppc/sipm pixels capacitance in ECAL (as a fraction: 0.01=1%)"}; - Gaudi::Property _ecal_elec_noise{this, "ECAL_elec_noise_mips", {0.}, "typical electronics noise (ECAL, in MIP units)"}; - Gaudi::Property _ehEnergy{this, "energyPerEHpair", {3.6}, "energy required to create e-h pair in silicon (in eV)"}; - Gaudi::Property _ecalMaxDynMip{this, "ECAL_maxDynamicRange_MIP", {2500.}, "maximum of dynamic range for ECAL (in MIPs)"}; - Gaudi::Property _ecalStrip_default_nVirt{this, "StripEcal_default_nVirtualCells", {9}, "default number of virtual cells (used if not found in gear file)"}; - Gaudi::Property _ecal_deafult_layer_config{this, "ECAL_default_layerConfig", {"000000000000000"}, "default ECAL layer configuration (used if not found in gear file"}; - Gaudi::Property _calibHcalMip{this, "CalibHCALMIP", {1.0e-4}, "calibration to convert HCAL deposited energy to MIPs"}; - Gaudi::Property _applyHcalDigi{this, "HCAL_apply_realistic_digi", {0}, "apply realistic digitisation to HCAL hits? (0=none, 1=silicon, 2=scintillator)"}; - Gaudi::Property _hcal_PPD_pe_per_mip{this, "HCAL_PPD_PE_per_MIP", {7.0}, "# Photo-electrons per MIP (scintillator): used to poisson smear #PEs if >0"}; - Gaudi::Property _hcal_PPD_n_pixels{this, "HCAL_PPD_N_Pixels",{10000},"HCAL total number of MPPC/SiPM pixels for implementation of saturation effect"}; - Gaudi::Property _hcal_misCalibNpix{this, "HCAL_PPD_N_Pixels_uncertainty", {0.05}, "HCAL fractional uncertainty of effective total number of MPPC/SiPM pixels"}; - Gaudi::Property _misCalibHcal_uncorrel{this, "HCAL_miscalibration_uncorrel", {0.0}, "uncorrelated HCAL random gaussian miscalibration (as a fraction: 1.0 = 100%"}; - Gaudi::Property _misCalibHcal_uncorrel_keep{this, "HCAL_miscalibration_uncorrel_memorise", {false}, "store oncorrelated HCAL miscalbrations in memory? (WARNING: can take a lot of memory if used..."}; - Gaudi::Property _misCalibHcal_correl{this, "HCAL_miscalibration_correl", {0.0}, "correlated HCAL random gaussian miscalibration (as a fraction: 1.0 = 100%"}; - Gaudi::Property _deadCellFractionHcal{this, "HCAL_deadCellRate", {0.0}, "HCAL random dead cell fraction (as a fraction: 0->1)"}; - Gaudi::Property _deadCellHcal_keep{this, "HCAL_deadCell_memorise", {false}, "store dead HCAL cells in memory? (WARNING: can take a lot of memory if used..."}; - Gaudi::Property _hcal_pixSpread{this, "HCAL_pixel_spread", {0.05}, "variation of mppc/sipm pixels capacitance in HCAL (as a fraction: 0.01=1%)"}; - Gaudi::Property _hcal_elec_noise{this, "HCAL_elec_noise_mips", {0.}, "typical electronics noise (ECAL, in MIP units)"}; - Gaudi::Property _hcalMaxDynMip{this, "HCAL_maxDynamicRange_MIP", {2500.}, "maximum of dynamic range for HCAL (in MIPs)"}; + Gaudi::Property _hcalEndcapTimeWindowMax{ + this, "HCALEndcapTimeWindowMax", {100}, "HCAL Endcap Time Window maximum time in ns"}; + Gaudi::Property _hcalBarrelTimeWindowMax{ + this, "HCALBarrelTimeWindowMax", {100}, "HCAL Barrel Time Window maximum time in ns"}; + Gaudi::Property _hcalDeltaTimeHitResolution{ + this, "HCALDeltaTimeHitResolution", {10}, "HCAL Minimum Delta Time in ns for resolving two hits"}; + Gaudi::Property _hcalTimeResolution{ + this, "HCALTimeResolution", {10}, "HCAL Time Resolution used to smear hit times"}; + Gaudi::Property _hcalSimpleTimingCut{ + this, + "HCALSimpleTimingCut", + {true}, + "Use simple time window cut on hit times? If false: use original hit-time clustering algorithm. If true: use " + "time window defined by HCALBarrelTimeWindowMin and HCALBarrelTimeWindowMax"}; + Gaudi::Property _calibEcalMip{ + this, "CalibECALMIP", {1.0e-4}, "calibration to convert ECAL deposited energy to MIPs"}; + Gaudi::Property _applyEcalDigi{this, + "ECAL_apply_realistic_digi", + {0}, + "apply realistic digitisation to ECAL hits? (0=none, 1=silicon, 2=scintillator)"}; + Gaudi::Property _ecal_PPD_pe_per_mip{ + this, "ECAL_PPD_PE_per_MIP", {7.0}, "# Photo-electrons per MIP (scintillator): used to poisson smear #PEs if >0"}; + Gaudi::Property _ecal_PPD_n_pixels{ + this, + "ECAL_PPD_N_Pixels", + {10000}, + "ECAL total number of MPPC/SiPM pixels for implementation of saturation effect"}; + Gaudi::Property _ecal_misCalibNpix{ + this, + "ECAL_PPD_N_Pixels_uncertainty", + {0.05}, + "ECAL fractional uncertainty of effective total number of MPPC/SiPM pixels"}; + Gaudi::Property _misCalibEcal_uncorrel{ + this, + "ECAL_miscalibration_uncorrel", + {0.0}, + "uncorrelated ECAL random gaussian miscalibration (as a fraction: 1.0 = 100%"}; + Gaudi::Property _misCalibEcal_uncorrel_keep{ + this, + "ECAL_miscalibration_uncorrel_memorise", + {false}, + "store oncorrelated ECAL miscalbrations in memory? (WARNING: can take a lot of memory if used..."}; + Gaudi::Property _misCalibEcal_correl{ + this, + "ECAL_miscalibration_correl", + {0.0}, + "correlated ECAL random gaussian miscalibration (as a fraction: 1.0 = 100%"}; + Gaudi::Property _deadCellFractionEcal{ + this, "ECAL_deadCellRate", {0.0}, "ECAL random dead cell fraction (as a fraction: 0->1)"}; + Gaudi::Property _deadCellEcal_keep{ + this, + "ECAL_deadCell_memorise", + {false}, + "store dead ECAL cells in memory? (WARNING: can take a lot of memory if used..."}; + Gaudi::Property _strip_abs_length{ + this, "ECAL_strip_absorbtionLength", {1000000.0}, "length scale for absorbtion along scintillator strip (mm)"}; + Gaudi::Property _ecal_pixSpread{ + this, "ECAL_pixel_spread", {0.05}, "variation of mppc/sipm pixels capacitance in ECAL (as a fraction: 0.01=1%)"}; + Gaudi::Property _ecal_elec_noise{ + this, "ECAL_elec_noise_mips", {0.}, "typical electronics noise (ECAL, in MIP units)"}; + Gaudi::Property _ehEnergy{ + this, "energyPerEHpair", {3.6}, "energy required to create e-h pair in silicon (in eV)"}; + Gaudi::Property _ecalMaxDynMip{ + this, "ECAL_maxDynamicRange_MIP", {2500.}, "maximum of dynamic range for ECAL (in MIPs)"}; + Gaudi::Property _ecalStrip_default_nVirt{ + this, "StripEcal_default_nVirtualCells", {9}, "default number of virtual cells (used if not found in gear file)"}; + Gaudi::Property _ecal_deafult_layer_config{ + this, + "ECAL_default_layerConfig", + {"000000000000000"}, + "default ECAL layer configuration (used if not found in gear file"}; + Gaudi::Property _calibHcalMip{ + this, "CalibHCALMIP", {1.0e-4}, "calibration to convert HCAL deposited energy to MIPs"}; + Gaudi::Property _applyHcalDigi{this, + "HCAL_apply_realistic_digi", + {0}, + "apply realistic digitisation to HCAL hits? (0=none, 1=silicon, 2=scintillator)"}; + Gaudi::Property _hcal_PPD_pe_per_mip{ + this, "HCAL_PPD_PE_per_MIP", {7.0}, "# Photo-electrons per MIP (scintillator): used to poisson smear #PEs if >0"}; + Gaudi::Property _hcal_PPD_n_pixels{ + this, + "HCAL_PPD_N_Pixels", + {10000}, + "HCAL total number of MPPC/SiPM pixels for implementation of saturation effect"}; + Gaudi::Property _hcal_misCalibNpix{ + this, + "HCAL_PPD_N_Pixels_uncertainty", + {0.05}, + "HCAL fractional uncertainty of effective total number of MPPC/SiPM pixels"}; + Gaudi::Property _misCalibHcal_uncorrel{ + this, + "HCAL_miscalibration_uncorrel", + {0.0}, + "uncorrelated HCAL random gaussian miscalibration (as a fraction: 1.0 = 100%"}; + Gaudi::Property _misCalibHcal_uncorrel_keep{ + this, + "HCAL_miscalibration_uncorrel_memorise", + {false}, + "store oncorrelated HCAL miscalbrations in memory? (WARNING: can take a lot of memory if used..."}; + Gaudi::Property _misCalibHcal_correl{ + this, + "HCAL_miscalibration_correl", + {0.0}, + "correlated HCAL random gaussian miscalibration (as a fraction: 1.0 = 100%"}; + Gaudi::Property _deadCellFractionHcal{ + this, "HCAL_deadCellRate", {0.0}, "HCAL random dead cell fraction (as a fraction: 0->1)"}; + Gaudi::Property _deadCellHcal_keep{ + this, + "HCAL_deadCell_memorise", + {false}, + "store dead HCAL cells in memory? (WARNING: can take a lot of memory if used..."}; + Gaudi::Property _hcal_pixSpread{ + this, "HCAL_pixel_spread", {0.05}, "variation of mppc/sipm pixels capacitance in HCAL (as a fraction: 0.01=1%)"}; + Gaudi::Property _hcal_elec_noise{ + this, "HCAL_elec_noise_mips", {0.}, "typical electronics noise (ECAL, in MIP units)"}; + Gaudi::Property _hcalMaxDynMip{ + this, "HCAL_maxDynamicRange_MIP", {2500.}, "maximum of dynamic range for HCAL (in MIPs)"}; //Gaudi::Property _ecalStrip_default_nVirt{this, "StripEcal_default_nVirtualCells", {9}, "default number of virtual cells (used if not found in gear file)"}; //Gaudi::Property _ecal_deafult_layer_config{this, "ECAL_default_layerConfig", {"000000000000000"}, "default ECAL layer configuration (used if not found in gear file"}; - - - - const float slop = 0.25; // (mm) + const float slop = 0.25; // (mm) //DDCaloDigi() ; - // DDCaloDigi(const DDCaloDigi&) = delete; - // DDCaloDigi& operator=(const DDCaloDigi&) = delete; + // DDCaloDigi(const DDCaloDigi&) = delete; + // DDCaloDigi& operator=(const DDCaloDigi&) = delete; - virtual void fillECALGaps() ; - - float digitalHcalCalibCoeff(CHT::Layout,float energy ); + virtual void fillECALGaps(); - float analogueHcalCalibCoeff(CHT::Layout, int layer ); + float digitalHcalCalibCoeff(CHT::Layout, float energy); - float digitalEcalCalibCoeff(int layer ); + float analogueHcalCalibCoeff(CHT::Layout, int layer); - float analogueEcalCalibCoeff(int layer ); + float digitalEcalCalibCoeff(int layer); + float analogueEcalCalibCoeff(int layer); - float ecalEnergyDigi(float energy,int id); + float ecalEnergyDigi(float energy, int id); float ahcalEnergyDigi(float energy, int id); float siliconDigi(float energy); float scintillatorDigi(float energy, bool isEcal); - auto combineVirtualStripCells(auto col, bool isBarrel, int stripOrientation ); - - int getNumberOfVirtualCells(); - std::vector < std::pair > & getLayerConfig(); - void checkConsistency(std::string colName, int layer); - std::pair < int, int > getLayerProperties( std::string colName, int layer ); - int getStripOrientationFromColName( std::string colName ); + auto combineVirtualStripCells(auto col, bool isBarrel, int stripOrientation); + int getNumberOfVirtualCells(); + std::vector>& getLayerConfig(); + void checkConsistency(std::string colName, int layer); + std::pair getLayerProperties(std::string colName, int layer); + int getStripOrientationFromColName(std::string colName); int _nRun = 0; int _nEvt = 0; - - //LCFlagImpl _flag{}; - + //LCFlagImpl _flag{}; std::string _outputRelCollection = ""; - float _thresholdEcal = 5.0e-5; - std::string _unitThresholdEcal = "GeV"; + float _thresholdEcal = 5.0e-5; + std::string _unitThresholdEcal = "GeV"; std::vector _thresholdHcal{}; - std::string _unitThresholdHcal = "GeV"; + std::string _unitThresholdHcal = "GeV"; - int _digitalEcal = 0; + int _digitalEcal = 0; int _mapsEcalCorrection = 0; - int _digitalHcal = 0; + int _digitalHcal = 0; //bool _ECAL_stripHits; @@ -248,16 +367,16 @@ struct DDCaloDigi final std::vector _ecalLayers{}; std::vector _hcalLayers{}; - int _ecalGapCorrection = 1; - float _ecalGapCorrectionFactor = 1; + int _ecalGapCorrection = 1; + float _ecalGapCorrectionFactor = 1; float _ecalModuleGapCorrectionFactor = 0.5; - float _ecalEndcapCorrectionFactor = 1.025; - float _hcalEndcapCorrectionFactor = 1.025; - int _hcalGapCorrection = 1; + float _ecalEndcapCorrectionFactor = 1.025; + float _hcalEndcapCorrectionFactor = 1.025; + int _hcalGapCorrection = 1; float _hcalModuleGapCorrectionFactor = 0.5; std::vector _calHitsByStaveLayer[MAX_STAVES][MAX_LAYERS]; - std::vector _calHitsByStaveLayerModule[MAX_STAVES][MAX_LAYERS]; + std::vector _calHitsByStaveLayerModule[MAX_STAVES][MAX_LAYERS]; float _zOfEcalEndcap = 0.0; float _barrelPixelSizeT[MAX_LAYERS]; @@ -265,176 +384,158 @@ struct DDCaloDigi final float _endcapPixelSizeX[MAX_LAYERS]; float _endcapPixelSizeY[MAX_LAYERS]; float _barrelStaveDir[MAX_STAVES][2]; - - int _histograms = 0; + + int _histograms = 0; // timing - int _useEcalTiming = 0; + int _useEcalTiming = 0; int _ecalCorrectTimesForPropagation = 0; - float _ecalTimeWindowMin = -10.0; - float _ecalBarrelTimeWindowMax = 100.0; - float _ecalEndcapTimeWindowMax = 100.0; - float _ecalDeltaTimeHitResolution = 10.0; - float _ecalTimeResolution = 10.0; - bool _ecalSimpleTimingCut = true; - - int _useHcalTiming = 1; + float _ecalTimeWindowMin = -10.0; + float _ecalBarrelTimeWindowMax = 100.0; + float _ecalEndcapTimeWindowMax = 100.0; + float _ecalDeltaTimeHitResolution = 10.0; + float _ecalTimeResolution = 10.0; + bool _ecalSimpleTimingCut = true; + + int _useHcalTiming = 1; int _hcalCorrectTimesForPropagation = 0; - float _hcalTimeWindowMin = -10.0; - float _hcalBarrelTimeWindowMax = 100.0; - float _hcalEndcapTimeWindowMax = 100.0; - float _hcalDeltaTimeHitResolution = 10.0; - float _hcalTimeResolution = 10.0; - bool _hcalSimpleTimingCut = true; - + float _hcalTimeWindowMin = -10.0; + float _hcalBarrelTimeWindowMax = 100.0; + float _hcalEndcapTimeWindowMax = 100.0; + float _hcalDeltaTimeHitResolution = 10.0; + float _hcalTimeResolution = 10.0; + bool _hcalSimpleTimingCut = true; + std::unique_ptr _scEcalDigi{}; std::unique_ptr _scHcalDigi{}; - // parameters for extra ECAL digitization effects - float _calibEcalMip = 1.0e-4; // MIP calibration factor - int _applyEcalDigi = 0; // which realistic calib to apply - float _ecal_PPD_pe_per_mip = 7; // # photoelectrons/MIP for MPPC - int _ecal_PPD_n_pixels = 10000; // # pixels in MPPC - float _ehEnergy = 3.6; // energy to create e-h pair in silicon - float _ecal_misCalibNpix = 0.05; // miscalibration of # MPPC pixels + float _calibEcalMip = 1.0e-4; // MIP calibration factor + int _applyEcalDigi = 0; // which realistic calib to apply + float _ecal_PPD_pe_per_mip = 7; // # photoelectrons/MIP for MPPC + int _ecal_PPD_n_pixels = 10000; // # pixels in MPPC + float _ehEnergy = 3.6; // energy to create e-h pair in silicon + float _ecal_misCalibNpix = 0.05; // miscalibration of # MPPC pixels - float _misCalibEcal_uncorrel = 0.0; // general ECAL miscalibration (uncorrelated between channels) - bool _misCalibEcal_uncorrel_keep = false;// if true, use the same ECAL cell miscalibs in each event (requires more memory) - float _misCalibEcal_correl = 0.0; // general ECAL miscalibration (100% uncorrelated between channels) + float _misCalibEcal_uncorrel = 0.0; // general ECAL miscalibration (uncorrelated between channels) + bool _misCalibEcal_uncorrel_keep = + false; // if true, use the same ECAL cell miscalibs in each event (requires more memory) + float _misCalibEcal_correl = 0.0; // general ECAL miscalibration (100% uncorrelated between channels) - float _deadCellFractionEcal = 0.0; // fraction of random dead channels - bool _deadCellEcal_keep = false; // keep same cells dead between events? + float _deadCellFractionEcal = 0.0; // fraction of random dead channels + bool _deadCellEcal_keep = false; // keep same cells dead between events? float _strip_abs_length = 1000000; // absorption length along strip for non-uniformity modeling - float _ecal_pixSpread = 0.05; // relative spread of MPPC pixel signal - float _ecal_elec_noise = 0; // electronics noise (as fraction of MIP) - float _ecalMaxDynMip = 2500; // electronics dynamic range (in terms of MIPs) - int _ecalStrip_default_nVirt = 9; // # virtual cells used in Mokka simulation of strips (if available, this is taken from gear file) - std::string _ecal_deafult_layer_config ="000000000000000";// ECAL layer configuration (if available, this is taken from gear file) + float _ecal_pixSpread = 0.05; // relative spread of MPPC pixel signal + float _ecal_elec_noise = 0; // electronics noise (as fraction of MIP) + float _ecalMaxDynMip = 2500; // electronics dynamic range (in terms of MIPs) + int _ecalStrip_default_nVirt = + 9; // # virtual cells used in Mokka simulation of strips (if available, this is taken from gear file) + std::string _ecal_deafult_layer_config = + "000000000000000"; // ECAL layer configuration (if available, this is taken from gear file) // parameters for extra AHCAL digitization effects - float _calibHcalMip = 1.0e-4; // MIP calibration factor - int _applyHcalDigi = 0; // which realistic calib to apply - float _hcal_PPD_pe_per_mip = 10; // # photoelectrons/MIP for MPPC - int _hcal_PPD_n_pixels= 400; // # pixels in MPPC - float _hcal_misCalibNpix = 0.05; // miscalibration of # MPPC pixels - - float _misCalibHcal_uncorrel = 0.0; // general ECAL miscalibration (uncorrelated between channels) - bool _misCalibHcal_uncorrel_keep = false; // if true, use the same AHCAL cell miscalibs in each event (requires more memory) - float _misCalibHcal_correl = 0.0; // general ECAL miscalibration (100% uncorrelated between channels) - - float _deadCellFractionHcal = 0.0; // fraction of random dead channels - bool _deadCellHcal_keep = false; // keep same cells dead between events? - float _hcal_pixSpread = 0.0; // relative spread of MPPC pixel signal - float _hcal_elec_noise = 0.0; // electronics noise (as fraction of MIP) - float _hcalMaxDynMip = 200; // electronics dynamic range (in terms of MIPs) - - + float _calibHcalMip = 1.0e-4; // MIP calibration factor + int _applyHcalDigi = 0; // which realistic calib to apply + float _hcal_PPD_pe_per_mip = 10; // # photoelectrons/MIP for MPPC + int _hcal_PPD_n_pixels = 400; // # pixels in MPPC + float _hcal_misCalibNpix = 0.05; // miscalibration of # MPPC pixels + + float _misCalibHcal_uncorrel = 0.0; // general ECAL miscalibration (uncorrelated between channels) + bool _misCalibHcal_uncorrel_keep = + false; // if true, use the same AHCAL cell miscalibs in each event (requires more memory) + float _misCalibHcal_correl = 0.0; // general ECAL miscalibration (100% uncorrelated between channels) + + float _deadCellFractionHcal = 0.0; // fraction of random dead channels + bool _deadCellHcal_keep = false; // keep same cells dead between events? + float _hcal_pixSpread = 0.0; // relative spread of MPPC pixel signal + float _hcal_elec_noise = 0.0; // electronics noise (as fraction of MIP) + float _hcalMaxDynMip = 200; // electronics dynamic range (in terms of MIPs) // internal variables - std::vector < std::pair > _layerTypes {}; - int _strip_virt_cells = 999; - int _countWarnings = 0; - std::string _ecalLayout = ""; + std::vector> _layerTypes{}; + int _strip_virt_cells = 999; + int _countWarnings = 0; + std::string _ecalLayout = ""; float _event_correl_miscalib_ecal = 0.0; float _event_correl_miscalib_hcal = 0.0; - - CLHEP::MTwistEngine *_randomEngineDeadCellEcal = NULL; - CLHEP::MTwistEngine *_randomEngineDeadCellHcal = NULL; - - std::map < std::pair , float > _ECAL_cell_miscalibs{}; - std::map < std::pair , bool > _ECAL_cell_dead{}; - std::map < std::pair , float > _HCAL_cell_miscalibs{}; - std::map < std::pair , bool > _HCAL_cell_dead{}; - - enum { - SQUARE, - STRIP_ALIGN_ALONG_SLAB, - STRIP_ALIGN_ACROSS_SLAB, - SIECAL=0, - SCECAL - }; - - - TH1F* fEcal = NULL; - TH1F* fHcal = NULL; - TH1F* fEcalC = NULL; - TH1F* fHcalC = NULL; - TH1F* fEcalC1 = NULL; - TH1F* fHcalC1 = NULL; - TH1F* fEcalC2 = NULL; - TH1F* fHcalC2 = NULL; - TH2F* fHcalCvsE = NULL; - TH2F* fHcalLayer1 = NULL; - TH2F* fHcalLayer11 = NULL; - TH2F* fHcalLayer21 = NULL; - TH2F* fHcalLayer31 = NULL; - TH2F* fHcalLayer41 = NULL; - TH2F* fHcalLayer51 = NULL; - TH2F* fHcalLayer61 = NULL; - TH2F* fHcalLayer71 = NULL; - TH1F* fHcalRLayer1 = NULL; - TH1F* fHcalRLayer11 = NULL; - TH1F* fHcalRLayer21 = NULL; - TH1F* fHcalRLayer31 = NULL; - TH1F* fHcalRLayer41 = NULL; - TH1F* fHcalRLayer51 = NULL; - TH1F* fHcalRLayer61 = NULL; - TH1F* fHcalRLayer71 = NULL; + + CLHEP::MTwistEngine* _randomEngineDeadCellEcal = NULL; + CLHEP::MTwistEngine* _randomEngineDeadCellHcal = NULL; + + std::map, float> _ECAL_cell_miscalibs{}; + std::map, bool> _ECAL_cell_dead{}; + std::map, float> _HCAL_cell_miscalibs{}; + std::map, bool> _HCAL_cell_dead{}; + + enum { SQUARE, STRIP_ALIGN_ALONG_SLAB, STRIP_ALIGN_ACROSS_SLAB, SIECAL = 0, SCECAL }; + + TH1F* fEcal = NULL; + TH1F* fHcal = NULL; + TH1F* fEcalC = NULL; + TH1F* fHcalC = NULL; + TH1F* fEcalC1 = NULL; + TH1F* fHcalC1 = NULL; + TH1F* fEcalC2 = NULL; + TH1F* fHcalC2 = NULL; + TH2F* fHcalCvsE = NULL; + TH2F* fHcalLayer1 = NULL; + TH2F* fHcalLayer11 = NULL; + TH2F* fHcalLayer21 = NULL; + TH2F* fHcalLayer31 = NULL; + TH2F* fHcalLayer41 = NULL; + TH2F* fHcalLayer51 = NULL; + TH2F* fHcalLayer61 = NULL; + TH2F* fHcalLayer71 = NULL; + TH1F* fHcalRLayer1 = NULL; + TH1F* fHcalRLayer11 = NULL; + TH1F* fHcalRLayer21 = NULL; + TH1F* fHcalRLayer31 = NULL; + TH1F* fHcalRLayer41 = NULL; + TH1F* fHcalRLayer51 = NULL; + TH1F* fHcalRLayer61 = NULL; + TH1F* fHcalRLayer71 = NULL; TH1F* fHcalRLayerNorm = NULL; TH1F* fEcalRLayerNorm = NULL; - TH2F* fEcalLayer1 = NULL; - TH2F* fEcalLayer11 = NULL; - TH2F* fEcalLayer21 = NULL; - TH1F* fEcalRLayer1 = NULL; - TH1F* fEcalRLayer11 = NULL; - TH1F* fEcalRLayer21 = NULL; - -} ; + TH2F* fEcalLayer1 = NULL; + TH2F* fEcalLayer11 = NULL; + TH2F* fEcalLayer21 = NULL; + TH1F* fEcalRLayer1 = NULL; + TH1F* fEcalRLayer11 = NULL; + TH1F* fEcalRLayer21 = NULL; +}; DECLARE_COMPONENT(DDCaloDigi) #endif - - - - - - - - - // ecalCollections.push_back(std::string("EcalRingCollection")); - // std::vector _ecalCollections; // this is for silicon - // _ecalCollections.push_back(std::string("EcalBarrelCollection")); - // _ecalCollections.push_back(std::string("EcalEndcapCollection")); - //Gaudi::Property> _ecalCollections{this, "ECALCollections", {_ecalCollections}, "ECAL Collection Names"}; - - // std::vector _hcalCollections; - // _hcalCollections.push_back(std::string("HcalBarrelRegCollection")); - // _hcalCollections.push_back(std::string("HcalEndcapRingsCollection")); - // _hcalCollections.push_back(std::string("HcalEndcapsCollection")); - //Gaudi::Property> _hcalCollections{this, "HCALCollections", {_hcalCollections}, "HCAL Collection Names"}; - - // std::vector _outputEcalCollections{}; - // _outputEcalCollections.push_back(std::string("ECALBarrel")); - // _outputEcalCollections.push_back(std::string("ECALEndcap")); - // _outputEcalCollections.push_back(std::string("ECALOther")); - - // std::vector _outputHcalCollections{}; - // _outputHcalCollections.push_back(std::string("HCALBarrel")); - // _outputHcalCollections.push_back(std::string("HCALEndcap")); - // _outputHcalCollections.push_back(std::string("HCALOther")); - - // Gaudi::Property _outputEcalCollections[0]{this, "output_ECALCollections0", {"ECALBarrel"}, "ECAL Collection of real Hits in Barrel"}; - // Gaudi::Property _outputEcalCollections[1]{this, "output_ECALCollections1", {"ECALEndcap"}, "ECAL Collection of real Hits in EndCap"}; - // Gaudi::Property _outputEcalCollections[2]{this, "output_ECALCollections2", {"ECALOther"}, "ECAL Collection of real Hits other"}; - - // Gaudi::Property _outputHcalCollections[0]{this, "output_HCALCollections0", {"HCALBarrel"}, "HCAL Collection of real Hits in Barrel"}; - // Gaudi::Property _outputHcalCollections[1]{this, "output_HCALCollections1", {"HCALEndcap"}, "HCAL Collection of real Hits in EndCap"}; - // Gaudi::Property _outputHcalCollections[2]{this, "output_HCALCollections2", {"HCALOther"}, "HCAL Collection of real Hits other"}; - // Gaudi::Property _outputRelCollection{this, "RelationOutputCollection", {"RelationCaloHit"}, "CaloHit Relation Collection"}; - - +// std::vector _ecalCollections; // this is for silicon +// _ecalCollections.push_back(std::string("EcalBarrelCollection")); +// _ecalCollections.push_back(std::string("EcalEndcapCollection")); +//Gaudi::Property> _ecalCollections{this, "ECALCollections", {_ecalCollections}, "ECAL Collection Names"}; + +// std::vector _hcalCollections; +// _hcalCollections.push_back(std::string("HcalBarrelRegCollection")); +// _hcalCollections.push_back(std::string("HcalEndcapRingsCollection")); +// _hcalCollections.push_back(std::string("HcalEndcapsCollection")); +//Gaudi::Property> _hcalCollections{this, "HCALCollections", {_hcalCollections}, "HCAL Collection Names"}; + +// std::vector _outputEcalCollections{}; +// _outputEcalCollections.push_back(std::string("ECALBarrel")); +// _outputEcalCollections.push_back(std::string("ECALEndcap")); +// _outputEcalCollections.push_back(std::string("ECALOther")); + +// std::vector _outputHcalCollections{}; +// _outputHcalCollections.push_back(std::string("HCALBarrel")); +// _outputHcalCollections.push_back(std::string("HCALEndcap")); +// _outputHcalCollections.push_back(std::string("HCALOther")); + +// Gaudi::Property _outputEcalCollections[0]{this, "output_ECALCollections0", {"ECALBarrel"}, "ECAL Collection of real Hits in Barrel"}; +// Gaudi::Property _outputEcalCollections[1]{this, "output_ECALCollections1", {"ECALEndcap"}, "ECAL Collection of real Hits in EndCap"}; +// Gaudi::Property _outputEcalCollections[2]{this, "output_ECALCollections2", {"ECALOther"}, "ECAL Collection of real Hits other"}; + +// Gaudi::Property _outputHcalCollections[0]{this, "output_HCALCollections0", {"HCALBarrel"}, "HCAL Collection of real Hits in Barrel"}; +// Gaudi::Property _outputHcalCollections[1]{this, "output_HCALCollections1", {"HCALEndcap"}, "HCAL Collection of real Hits in EndCap"}; +// Gaudi::Property _outputHcalCollections[2]{this, "output_HCALCollections2", {"HCALOther"}, "HCAL Collection of real Hits other"}; +// Gaudi::Property _outputRelCollection{this, "RelationOutputCollection", {"RelationCaloHit"}, "CaloHit Relation Collection"}; diff --git a/k4GaudiPandora/include/DDCaloHitCreator.h b/k4GaudiPandora/include/DDCaloHitCreator.h index 7acd489..c0cc9e9 100644 --- a/k4GaudiPandora/include/DDCaloHitCreator.h +++ b/k4GaudiPandora/include/DDCaloHitCreator.h @@ -1,8 +1,27 @@ +/* + * Copyright (c) 2020-2024 Key4hep-Project. + * + * This file is part of Key4hep. + * See https://key4hep.github.io/key4hep-doc/ for further info. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + /** * @file DDMarlinPandora/include/DDCaloHitCreator.h - * + * * @brief Header file for the calo hit creator class. - * + * * $Log: $ */ @@ -16,199 +35,195 @@ #include "Api/PandoraApi.h" -#include -#include #include +#include +#include - - -typedef std::vector CalorimeterHitVector; +typedef std::vector CalorimeterHitVector; /** * @brief DDCaloHitCreator class */ -class DDCaloHitCreator -{ +class DDCaloHitCreator { public: - typedef std::vector StringVector; - typedef std::vector FloatVector; + typedef std::vector StringVector; + typedef std::vector FloatVector; - /** + /** * @brief Settings class */ - class Settings - { - public: - /** + class Settings { + public: + /** * @brief Default constructor */ - Settings(); - - StringVector m_eCalCaloHitCollections; ///< The ecal calorimeter hit collections - StringVector m_hCalCaloHitCollections; ///< The hcal calorimeter hit collections - StringVector m_lCalCaloHitCollections; ///< The lcal calorimeter hit collections - StringVector m_lHCalCaloHitCollections; ///< The lhcal calorimeter hit collections - StringVector m_muonCaloHitCollections; ///< The muon calorimeter hit collections - - //NN: Material properties variables removed; obtained from geometry - - float m_eCalToMip; ///< The calibration from deposited ECal energy to mip - float m_hCalToMip; ///< The calibration from deposited HCal energy to mip - float m_muonToMip; ///< The calibration from deposited Muon energy to mip - float m_eCalMipThreshold; ///< Threshold for creating calo hits in the ECal, units mip - float m_hCalMipThreshold; ///< Threshold for creating calo hits in the HCal, units mip - float m_muonMipThreshold; ///< Threshold for creating calo hits in the HCal, units mip - - float m_eCalToEMGeV; ///< The calibration from deposited ECal energy to EM energy - float m_eCalToHadGeVBarrel; ///< The calibration from deposited ECal barrel energy to hadronic energy - float m_eCalToHadGeVEndCap; ///< The calibration from deposited ECal endcap energy to hadronic energy - float m_hCalToEMGeV; ///< The calibration from deposited HCal energy to EM energy - float m_hCalToHadGeV; ///< The calibration from deposited HCal energy to hadronic energy - int m_muonDigitalHits; ///< Muon hits are treated as digital (energy from hit count) - float m_muonHitEnergy; ///< The energy for a digital muon calorimeter hit, units GeV - - float m_maxHCalHitHadronicEnergy; ///< The maximum hadronic energy allowed for a single hcal hit - int m_nOuterSamplingLayers; ///< Number of layers from edge for hit to be flagged as an outer layer hit - float m_layersFromEdgeMaxRearDistance; ///< Maximum number of layers from candidate outer layer hit to rear of detector - - int m_hCalEndCapInnerSymmetryOrder; ///< HCal end cap inner symmetry order (missing from ILD00 gear file) - float m_hCalEndCapInnerPhiCoordinate; ///< HCal end cap inner phi coordinate (missing from ILD00 gear file) - - // For Strip Splitting method and hybrid ECAL. - int m_stripSplittingOn; ///< To use SSA, this should be true (default is false) - int m_useEcalScLayers; ///< To use scintillator layers ~ hybrid ECAL, this should be true (default is false) - float m_eCalSiToMip; ///< The calibration from deposited Si-layer energy to mip - float m_eCalScToMip; ///< The calibration from deposited Sc-layer energy to mip - float m_eCalSiMipThreshold; ///< Threshold for creating calo hits in the Si-layers of ECAL, units mip - float m_eCalScMipThreshold; ///< Threshold for creating calo hits in the Sc-layers of ECAL, units mip - float m_eCalSiToEMGeV; ///< The calibration from deposited Si-layer energy to EM energy - float m_eCalScToEMGeV; ///< The calibration from deposited Sc-layer energy to EM energy - float m_eCalSiToHadGeVBarrel; ///< The calibration from deposited Si-layer energy on the enecaps to hadronic energy - float m_eCalScToHadGeVBarrel; ///< The calibration from deposited Sc-layer energy on the endcaps to hadronic energy - float m_eCalSiToHadGeVEndCap; ///< The calibration from deposited Si-layer energy on the enecaps to hadronic energy - float m_eCalScToHadGeVEndCap; ///< The calibration from deposited Sc-layer energy on the endcaps to hadronic energy - - - ///ADDED BY NIKIFOROS - //Note that names are not needed anymore since the detector elements can be accessed by type flags - //Nikiforos: Moved from main class - - float m_eCalBarrelOuterZ; ///< ECal barrel outer z coordinate - float m_hCalBarrelOuterZ; ///< HCal barrel outer z coordinate - float m_muonBarrelOuterZ; ///< Muon barrel outer z coordinate - float m_coilOuterR; ///< Coil outer r coordinate - - float m_eCalBarrelInnerPhi0; ///< ECal barrel inner phi0 coordinate - unsigned int m_eCalBarrelInnerSymmetry; ///< ECal barrel inner symmetry order - float m_hCalBarrelInnerPhi0; ///< HCal barrel inner phi0 coordinate - unsigned int m_hCalBarrelInnerSymmetry; ///< HCal barrel inner symmetry order - float m_muonBarrelInnerPhi0; ///< Muon barrel inner phi0 coordinate - unsigned int m_muonBarrelInnerSymmetry; ///< Muon barrel inner symmetry order - - float m_hCalEndCapOuterR; ///< HCal endcap outer r coordinate - float m_hCalEndCapOuterZ; ///< HCal endcap outer z coordinate - float m_hCalBarrelOuterR; ///< HCal barrel outer r coordinate - float m_hCalBarrelOuterPhi0; ///< HCal barrel outer phi0 coordinate - unsigned int m_hCalBarrelOuterSymmetry; ///< HCal barrel outer symmetry order - - public: - FloatVector m_eCalBarrelNormalVector; - FloatVector m_hCalBarrelNormalVector; - FloatVector m_muonBarrelNormalVector; - - - }; - - /** + Settings(); + + StringVector m_eCalCaloHitCollections; ///< The ecal calorimeter hit collections + StringVector m_hCalCaloHitCollections; ///< The hcal calorimeter hit collections + StringVector m_lCalCaloHitCollections; ///< The lcal calorimeter hit collections + StringVector m_lHCalCaloHitCollections; ///< The lhcal calorimeter hit collections + StringVector m_muonCaloHitCollections; ///< The muon calorimeter hit collections + + //NN: Material properties variables removed; obtained from geometry + + float m_eCalToMip; ///< The calibration from deposited ECal energy to mip + float m_hCalToMip; ///< The calibration from deposited HCal energy to mip + float m_muonToMip; ///< The calibration from deposited Muon energy to mip + float m_eCalMipThreshold; ///< Threshold for creating calo hits in the ECal, units mip + float m_hCalMipThreshold; ///< Threshold for creating calo hits in the HCal, units mip + float m_muonMipThreshold; ///< Threshold for creating calo hits in the HCal, units mip + + float m_eCalToEMGeV; ///< The calibration from deposited ECal energy to EM energy + float m_eCalToHadGeVBarrel; ///< The calibration from deposited ECal barrel energy to hadronic energy + float m_eCalToHadGeVEndCap; ///< The calibration from deposited ECal endcap energy to hadronic energy + float m_hCalToEMGeV; ///< The calibration from deposited HCal energy to EM energy + float m_hCalToHadGeV; ///< The calibration from deposited HCal energy to hadronic energy + int m_muonDigitalHits; ///< Muon hits are treated as digital (energy from hit count) + float m_muonHitEnergy; ///< The energy for a digital muon calorimeter hit, units GeV + + float m_maxHCalHitHadronicEnergy; ///< The maximum hadronic energy allowed for a single hcal hit + int m_nOuterSamplingLayers; ///< Number of layers from edge for hit to be flagged as an outer layer hit + float + m_layersFromEdgeMaxRearDistance; ///< Maximum number of layers from candidate outer layer hit to rear of detector + + int m_hCalEndCapInnerSymmetryOrder; ///< HCal end cap inner symmetry order (missing from ILD00 gear file) + float m_hCalEndCapInnerPhiCoordinate; ///< HCal end cap inner phi coordinate (missing from ILD00 gear file) + + // For Strip Splitting method and hybrid ECAL. + int m_stripSplittingOn; ///< To use SSA, this should be true (default is false) + int m_useEcalScLayers; ///< To use scintillator layers ~ hybrid ECAL, this should be true (default is false) + float m_eCalSiToMip; ///< The calibration from deposited Si-layer energy to mip + float m_eCalScToMip; ///< The calibration from deposited Sc-layer energy to mip + float m_eCalSiMipThreshold; ///< Threshold for creating calo hits in the Si-layers of ECAL, units mip + float m_eCalScMipThreshold; ///< Threshold for creating calo hits in the Sc-layers of ECAL, units mip + float m_eCalSiToEMGeV; ///< The calibration from deposited Si-layer energy to EM energy + float m_eCalScToEMGeV; ///< The calibration from deposited Sc-layer energy to EM energy + float m_eCalSiToHadGeVBarrel; ///< The calibration from deposited Si-layer energy on the enecaps to hadronic energy + float m_eCalScToHadGeVBarrel; ///< The calibration from deposited Sc-layer energy on the endcaps to hadronic energy + float m_eCalSiToHadGeVEndCap; ///< The calibration from deposited Si-layer energy on the enecaps to hadronic energy + float m_eCalScToHadGeVEndCap; ///< The calibration from deposited Sc-layer energy on the endcaps to hadronic energy + + ///ADDED BY NIKIFOROS + //Note that names are not needed anymore since the detector elements can be accessed by type flags + //Nikiforos: Moved from main class + + float m_eCalBarrelOuterZ; ///< ECal barrel outer z coordinate + float m_hCalBarrelOuterZ; ///< HCal barrel outer z coordinate + float m_muonBarrelOuterZ; ///< Muon barrel outer z coordinate + float m_coilOuterR; ///< Coil outer r coordinate + + float m_eCalBarrelInnerPhi0; ///< ECal barrel inner phi0 coordinate + unsigned int m_eCalBarrelInnerSymmetry; ///< ECal barrel inner symmetry order + float m_hCalBarrelInnerPhi0; ///< HCal barrel inner phi0 coordinate + unsigned int m_hCalBarrelInnerSymmetry; ///< HCal barrel inner symmetry order + float m_muonBarrelInnerPhi0; ///< Muon barrel inner phi0 coordinate + unsigned int m_muonBarrelInnerSymmetry; ///< Muon barrel inner symmetry order + + float m_hCalEndCapOuterR; ///< HCal endcap outer r coordinate + float m_hCalEndCapOuterZ; ///< HCal endcap outer z coordinate + float m_hCalBarrelOuterR; ///< HCal barrel outer r coordinate + float m_hCalBarrelOuterPhi0; ///< HCal barrel outer phi0 coordinate + unsigned int m_hCalBarrelOuterSymmetry; ///< HCal barrel outer symmetry order + + public: + FloatVector m_eCalBarrelNormalVector; + FloatVector m_hCalBarrelNormalVector; + FloatVector m_muonBarrelNormalVector; + }; + + /** * @brief Constructor - * + * * @param settings the creator settings * @param pPandora address of the relevant pandora instance */ - DDCaloHitCreator(const Settings &settings, const pandora::Pandora *const pPandora); + DDCaloHitCreator(const Settings& settings, const pandora::Pandora* const pPandora); - /** + /** * @brief Destructor */ - ~DDCaloHitCreator(); + ~DDCaloHitCreator(); - /** + /** * @brief Create calo hits - * + * * @param pLCEvent the lcio event - */ - pandora::StatusCode CreateCaloHits(const EVENT::LCEvent *const pLCEvent); + */ + pandora::StatusCode CreateCaloHits(const EVENT::LCEvent* const pLCEvent); - /** + /** * @brief Get the calorimeter hit vector - * + * * @return The calorimeter hit vector */ - const CalorimeterHitVector &GetCalorimeterHitVector() const; + const CalorimeterHitVector& GetCalorimeterHitVector() const; - /** + /** * @brief Reset the calo hit creator */ - void Reset(); + void Reset(); private: - /** + /** * @brief Create ecal calo hits - * + * * @param pLCEvent the lcio event */ - pandora::StatusCode CreateECalCaloHits(const EVENT::LCEvent *const pLCEvent); + pandora::StatusCode CreateECalCaloHits(const EVENT::LCEvent* const pLCEvent); - /** + /** * @brief Create hcal calo hits - * + * * @param pLCEvent the lcio event */ - pandora::StatusCode CreateHCalCaloHits(const EVENT::LCEvent *const pLCEvent); + pandora::StatusCode CreateHCalCaloHits(const EVENT::LCEvent* const pLCEvent); - /** + /** * @brief Create muon calo hits - * + * * @param pLCEvent the lcio event */ - pandora::StatusCode CreateMuonCaloHits(const EVENT::LCEvent *const pLCEvent); + pandora::StatusCode CreateMuonCaloHits(const EVENT::LCEvent* const pLCEvent); - /** + /** * @brief Create lcal calo hits - * + * * @param pLCEvent the lcio event - */ - pandora::StatusCode CreateLCalCaloHits(const EVENT::LCEvent *const pLCEvent); + */ + pandora::StatusCode CreateLCalCaloHits(const EVENT::LCEvent* const pLCEvent); - /** + /** * @brief Create lhcal calo hits - * + * * @param pLCEvent the lcio event */ - pandora::StatusCode CreateLHCalCaloHits(const EVENT::LCEvent *const pLCEvent); + pandora::StatusCode CreateLHCalCaloHits(const EVENT::LCEvent* const pLCEvent); - /** + /** * @brief Get common calo hit properties: position, parent address, input energy and time - * + * * @param pCaloHit the lcio calorimeter hit * @param caloHitParameters the calo hit parameters to populate */ - void GetCommonCaloHitProperties(const EVENT::CalorimeterHit *const pCaloHit, PandoraApi::CaloHit::Parameters &caloHitParameters) const; + void GetCommonCaloHitProperties(const EVENT::CalorimeterHit* const pCaloHit, + PandoraApi::CaloHit::Parameters& caloHitParameters) const; - /** + /** * @brief Get end cap specific calo hit properties: cell size, absorber radiation and interaction lengths, normal vector - * + * * @param pCaloHit the lcio calorimeter hit * @param layers the vector of layers from DDRec extensions * @param caloHitParameters the calo hit parameters to populate * @param absorberCorrection to receive the absorber thickness correction for the mip equivalent energy */ - void GetEndCapCaloHitProperties(const EVENT::CalorimeterHit *const pCaloHit, const std::vector &layers, - PandoraApi::CaloHit::Parameters &caloHitParameters, float &absorberCorrection) const; + void GetEndCapCaloHitProperties(const EVENT::CalorimeterHit* const pCaloHit, + const std::vector& layers, + PandoraApi::CaloHit::Parameters& caloHitParameters, float& absorberCorrection) const; - /** + /** * @brief Get barrel specific calo hit properties: cell size, absorber radiation and interaction lengths, normal vector - * + * * @param pCaloHit the lcio calorimeter hit * @param layers the vector of layers from DDRec extensions * @param barrelSymmetryOrder the barrel order of symmetry @@ -216,56 +231,48 @@ class DDCaloHitCreator * @param normalVector is the normalVector to the sensitive layers in local coordinates * @param absorberCorrection to receive the absorber thickness correction for the mip equivalent energy */ - void GetBarrelCaloHitProperties( const EVENT::CalorimeterHit *const pCaloHit, - const std::vector &layers, - unsigned int barrelSymmetryOrder, - PandoraApi::CaloHit::Parameters &caloHitParameters, - FloatVector const& normalVector, - float &absorberCorrection ) const; + void GetBarrelCaloHitProperties(const EVENT::CalorimeterHit* const pCaloHit, + const std::vector& layers, + unsigned int barrelSymmetryOrder, PandoraApi::CaloHit::Parameters& caloHitParameters, + FloatVector const& normalVector, float& absorberCorrection) const; - /** + /** * @brief Get number of active layers from position of a calo hit to the edge of the detector - * + * * @param pCaloHit the lcio calorimeter hit */ - int GetNLayersFromEdge(const EVENT::CalorimeterHit *const pCaloHit) const; + int GetNLayersFromEdge(const EVENT::CalorimeterHit* const pCaloHit) const; - /** + /** * @brief Get the maximum radius of a calo hit in a polygonal detector structure - * + * * @param pCaloHit the lcio calorimeter hit * @param symmetryOrder the symmetry order * @param phi0 the angular orientation - * + * * @return the maximum radius */ - float GetMaximumRadius(const EVENT::CalorimeterHit *const pCaloHit, const unsigned int symmetryOrder, const float phi0) const; - - const Settings m_settings; ///< The calo hit creator settings + float GetMaximumRadius(const EVENT::CalorimeterHit* const pCaloHit, const unsigned int symmetryOrder, + const float phi0) const; - const pandora::Pandora & m_pandora; ///< Reference to the pandora object to create calo hits + const Settings m_settings; ///< The calo hit creator settings - float m_hCalBarrelLayerThickness; ///< HCal barrel layer thickness - float m_hCalEndCapLayerThickness; ///< HCal endcap layer thickness + const pandora::Pandora& m_pandora; ///< Reference to the pandora object to create calo hits - CalorimeterHitVector m_calorimeterHitVector; ///< The calorimeter hit vector + float m_hCalBarrelLayerThickness; ///< HCal barrel layer thickness + float m_hCalEndCapLayerThickness; ///< HCal endcap layer thickness - dd4hep::VolumeManager m_volumeManager; ///< DD4hep volume manager + CalorimeterHitVector m_calorimeterHitVector; ///< The calorimeter hit vector + dd4hep::VolumeManager m_volumeManager; ///< DD4hep volume manager }; //------------------------------------------------------------------------------------------------------------------------------------------ -inline const CalorimeterHitVector &DDCaloHitCreator::GetCalorimeterHitVector() const -{ - return m_calorimeterHitVector; -} +inline const CalorimeterHitVector& DDCaloHitCreator::GetCalorimeterHitVector() const { return m_calorimeterHitVector; } //------------------------------------------------------------------------------------------------------------------------------------------ -inline void DDCaloHitCreator::Reset() -{ - m_calorimeterHitVector.clear(); -} +inline void DDCaloHitCreator::Reset() { m_calorimeterHitVector.clear(); } -#endif // #ifndef CALO_HIT_CREATOR_H +#endif // #ifndef CALO_HIT_CREATOR_H diff --git a/k4GaudiPandora/include/DDExternalClusteringAlgorithm.h b/k4GaudiPandora/include/DDExternalClusteringAlgorithm.h index 8037402..28fe9fd 100644 --- a/k4GaudiPandora/include/DDExternalClusteringAlgorithm.h +++ b/k4GaudiPandora/include/DDExternalClusteringAlgorithm.h @@ -1,8 +1,27 @@ +/* + * Copyright (c) 2020-2024 Key4hep-Project. + * + * This file is part of Key4hep. + * See https://key4hep.github.io/key4hep-doc/ for further info. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + /** * @file DDMarlinPandora/include/DDExternalClusteringAlgorithm.h - * + * * @brief Header file for the external clustering algorithm class. - * + * * $Log: $ */ #ifndef DDEXTERNALCLUSTERINGALGORITHM_H @@ -10,45 +29,44 @@ #include "Pandora/Algorithm.h" -namespace pandora { class CaloHit; } +namespace pandora { + class CaloHit; +} //------------------------------------------------------------------------------------------------------------------------------------------ /** * @brief DDExternalClusteringAlgorithm class */ -class DDExternalClusteringAlgorithm : public pandora::Algorithm -{ +class DDExternalClusteringAlgorithm : public pandora::Algorithm { public: - /** + /** * @brief Factory class for instantiating algorithm */ - class Factory : public pandora::AlgorithmFactory - { - public: - pandora::Algorithm *CreateAlgorithm() const; - }; + class Factory : public pandora::AlgorithmFactory { + public: + pandora::Algorithm* CreateAlgorithm() const; + }; - /** + /** * @brief Default constructor */ - DDExternalClusteringAlgorithm(); + DDExternalClusteringAlgorithm(); private: - pandora::StatusCode Run(); - pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle); + pandora::StatusCode Run(); + pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle); - typedef std::map ParentAddressToCaloHitMap; + typedef std::map ParentAddressToCaloHitMap; - std::string m_externalClusterCollectionName = ""; ///< The collection name for the external clusters - bool m_flagClustersAsPhotons = true; ///< Whether to automatically flag new clusters as fixed photons + std::string m_externalClusterCollectionName = ""; ///< The collection name for the external clusters + bool m_flagClustersAsPhotons = true; ///< Whether to automatically flag new clusters as fixed photons }; //------------------------------------------------------------------------------------------------------------------------------------------ -inline pandora::Algorithm *DDExternalClusteringAlgorithm::Factory::CreateAlgorithm() const -{ - return new DDExternalClusteringAlgorithm(); +inline pandora::Algorithm* DDExternalClusteringAlgorithm::Factory::CreateAlgorithm() const { + return new DDExternalClusteringAlgorithm(); } -#endif // #ifndef DDEXTERNALCLUSTERINGALGORITHM_H +#endif // #ifndef DDEXTERNALCLUSTERINGALGORITHM_H diff --git a/k4GaudiPandora/include/DDGeometryCreator.h b/k4GaudiPandora/include/DDGeometryCreator.h index 733a611..5f8c466 100644 --- a/k4GaudiPandora/include/DDGeometryCreator.h +++ b/k4GaudiPandora/include/DDGeometryCreator.h @@ -1,8 +1,27 @@ +/* + * Copyright (c) 2020-2024 Key4hep-Project. + * + * This file is part of Key4hep. + * See https://key4hep.github.io/key4hep-doc/ for further info. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + /** * @file DDMarlinPandora/include/DDGeometryCreator.h - * + * * @brief Header file for the geometry creator class. - * + * * $Log: $ */ @@ -18,107 +37,106 @@ /** * @brief DDGeometryCreator class */ -class DDGeometryCreator -{ +class DDGeometryCreator { public: - /** + /** * @brief Settings class */ - class Settings - { - public: - /** + class Settings { + public: + /** * @brief Default constructor */ - Settings(); - //NN: Material properties obtained from geometry; relevant variables removed - ///NN: Extra geometry variables removed since all accessible from DDRec - //NN: Detector names not needed anymore since accessible by type flags - ///Added by Nikiforos - bool m_createGaps; ///< Whether should create gaps - - - }; - - /** + Settings(); + //NN: Material properties obtained from geometry; relevant variables removed + ///NN: Extra geometry variables removed since all accessible from DDRec + //NN: Detector names not needed anymore since accessible by type flags + ///Added by Nikiforos + bool m_createGaps; ///< Whether should create gaps + }; + + /** * @brief Constructor - * + * * @param settings the creator settings * @param pPandora address of the relevant pandora instance */ - DDGeometryCreator(const Settings &settings, const pandora::Pandora *const pPandora); + DDGeometryCreator(const Settings& settings, const pandora::Pandora* const pPandora); - /** + /** * @brief Destructor */ - ~DDGeometryCreator(); + ~DDGeometryCreator(); - /** + /** * @brief Create geometry */ - pandora::StatusCode CreateGeometry() const; + pandora::StatusCode CreateGeometry() const; private: - typedef std::map SubDetectorTypeMap; - typedef std::map SubDetectorNameMap; + typedef std::map SubDetectorTypeMap; + typedef std::map SubDetectorNameMap; - /** + /** * @brief Set mandatory sub detector parameters - * + * * @param subDetectorTypeMap the sub detector type map */ - void SetMandatorySubDetectorParameters(SubDetectorTypeMap &subDetectorTypeMap) const; + void SetMandatorySubDetectorParameters(SubDetectorTypeMap& subDetectorTypeMap) const; - /** + /** * @brief Set additional sub detector parameters - * + * * @param subDetectorNameMap the sub detector name map (for smaller sub detectors, identified uniquely only by name) */ - void SetAdditionalSubDetectorParameters(SubDetectorNameMap &subDetectorNameMap) const; + void SetAdditionalSubDetectorParameters(SubDetectorNameMap& subDetectorNameMap) const; - /** + /** * @brief Set sub detector parameters to their gear default values - * + * * @param inputParameters input parameters, from gear * @param subDetectorName the sub detector name * @param subDetectorType the sub detector type * @param parameters the sub detector parameters */ - void SetDefaultSubDetectorParameters(const dd4hep::rec::LayeredCalorimeterData &inputParameters, const std::string &subDetectorName, - const pandora::SubDetectorType subDetectorType, PandoraApi::Geometry::SubDetector::Parameters ¶meters) const; + void SetDefaultSubDetectorParameters(const dd4hep::rec::LayeredCalorimeterData& inputParameters, + const std::string& subDetectorName, + const pandora::SubDetectorType subDetectorType, + PandoraApi::Geometry::SubDetector::Parameters& parameters) const; - /** + /** * @brief Set positions of gaps in ILD detector and add information missing from GEAR parameters file - * + * * @param subDetectorTypeMap the sub detector type map * @param subDetectorNameMap the sub detector name map (for smaller sub detectors, identified uniquely only by name) */ - pandora::StatusCode SetILDSpecificGeometry(SubDetectorTypeMap &subDetectorTypeMap, SubDetectorNameMap &subDetectorNameMap) const; + pandora::StatusCode SetILDSpecificGeometry(SubDetectorTypeMap& subDetectorTypeMap, + SubDetectorNameMap& subDetectorNameMap) const; - /** + /** * @brief Add information missing from GEAR parameters file for ILD SDHCAL detector - * + * * @param subDetectorTypeMap the sub detector type map */ - /** + /** * @brief Specify positions of hcal barrel box gaps - ILD specific */ - pandora::StatusCode CreateHCalBarrelBoxGaps() const; + pandora::StatusCode CreateHCalBarrelBoxGaps() const; - /** + /** * @brief Specify positions of hcal end cap box gaps - ILD specific */ - pandora::StatusCode CreateHCalEndCapBoxGaps() const; + pandora::StatusCode CreateHCalEndCapBoxGaps() const; - /** + /** * @brief Specify positions of hcal barrel concentric polygon gaps - ILD specific */ - pandora::StatusCode CreateHCalBarrelConcentricGaps() const; + pandora::StatusCode CreateHCalBarrelConcentricGaps() const; - /** + /** * @brief Create box gaps at regular positions on polygonal prism, oriented along main z axis - ILD specific - * + * * @param symmetryOrder the pandora geometry parameters * @param phi0 the phi coordinate * @param innerRadius the inner r coordinate @@ -128,11 +146,13 @@ class DDGeometryCreator * @param gapWidth the gap width * @param vertexOffset position offset for vertex that doesn't point back to origin of xy plane */ - pandora::StatusCode CreateRegularBoxGaps(unsigned int symmetryOrder, float phi0, float innerRadius, float outerRadius, float minZ, - float maxZ, float gapWidth, pandora::CartesianVector vertexOffset = pandora::CartesianVector(0, 0, 0)) const; + pandora::StatusCode CreateRegularBoxGaps(unsigned int symmetryOrder, float phi0, float innerRadius, float outerRadius, + float minZ, float maxZ, float gapWidth, + pandora::CartesianVector vertexOffset = pandora::CartesianVector(0, 0, + 0)) const; - const Settings m_settings; ///< The geometry creator settings - const pandora::Pandora &m_pPandora; ///< Address of the pandora object to create the geometry + const Settings m_settings; ///< The geometry creator settings + const pandora::Pandora& m_pPandora; ///< Address of the pandora object to create the geometry }; -#endif // #ifndef GEOMETRY_CREATOR_H +#endif // #ifndef GEOMETRY_CREATOR_H diff --git a/k4GaudiPandora/include/DDMCParticleCreator.h b/k4GaudiPandora/include/DDMCParticleCreator.h index cba5049..7b6df56 100644 --- a/k4GaudiPandora/include/DDMCParticleCreator.h +++ b/k4GaudiPandora/include/DDMCParticleCreator.h @@ -1,16 +1,35 @@ +/* + * Copyright (c) 2020-2024 Key4hep-Project. + * + * This file is part of Key4hep. + * See https://key4hep.github.io/key4hep-doc/ for further info. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + /** * @file DDMarlinPandora/include/DDMCParticleCreator.h - * + * * @brief Header file for the mc particle creator class. - * + * * $Log: $ */ #ifndef DDMCPARTICLECREATOR_H #define DDMCPARTICLECREATOR_H 1 -#include "edm4hep/MCParticle.h" #include "Api/PandoraApi.h" +#include "edm4hep/MCParticle.h" #include "DDCaloHitCreator.h" #include "DDTrackCreatorBase.h" @@ -18,71 +37,67 @@ * @brief DDMCParticleCreator class */ class CollectionMaps; -class DDMCParticleCreator -{ +class DDMCParticleCreator { public: - typedef std::vector StringVector; + typedef std::vector StringVector; - /** + /** * @brief Settings class */ - class Settings - { - public: - /** + class Settings { + public: + /** * @brief Default constructor */ - Settings(); + Settings(); - StringVector m_mcParticleCollections; ///< The mc particle collections - StringVector m_lcCaloHitRelationCollections; ///< The SimCaloHit to CaloHit particle relations - StringVector m_lcTrackRelationCollections; ///< The SimTrackerHit to TrackerHit particle relations - float m_bField; ///< m_bField - }; + StringVector m_mcParticleCollections; ///< The mc particle collections + StringVector m_lcCaloHitRelationCollections; ///< The SimCaloHit to CaloHit particle relations + StringVector m_lcTrackRelationCollections; ///< The SimTrackerHit to TrackerHit particle relations + float m_bField; ///< m_bField + }; - /** + /** * @brief Constructor - * + * * @param settings the creator settings * @param pPandora address of the relevant pandora instance */ - DDMCParticleCreator(const Settings &settings, const pandora::Pandora *const pPandora); + DDMCParticleCreator(const Settings& settings, const pandora::Pandora* const pPandora); - /** + /** * @brief Destructor */ - ~DDMCParticleCreator(); + ~DDMCParticleCreator(); - /** + /** * @brief Create MCParticles - * + * * @param pLCEvent the lcio event - */ - pandora::StatusCode CreateMCParticles(const CollectionMaps& collectionMaps ) const; + */ + pandora::StatusCode CreateMCParticles(const CollectionMaps& collectionMaps) const; - /** + /** * @brief Create Track to mc particle relationships * */ - pandora::StatusCode CreateTrackToMCParticleRelationships(const CollectionMaps& collectionMaps, const TrackVector &trackVector) const; + pandora::StatusCode CreateTrackToMCParticleRelationships(const CollectionMaps& collectionMaps, + const TrackVector& trackVector) const; - /** + /** * @brief Create calo hit to mc particle relationships * */ - pandora::StatusCode CreateCaloHitToMCParticleRelationships(const CollectionMaps& collectionMaps, const CalorimeterHitVector &calorimeterHitVector) const; + pandora::StatusCode CreateCaloHitToMCParticleRelationships(const CollectionMaps& collectionMaps, + const CalorimeterHitVector& calorimeterHitVector) const; private: - const Settings m_settings; ///< The mc particle creator settings - const pandora::Pandora &m_pandora; ///< Reference to the pandora object to create the mc particles - const float m_bField; ///< The bfield - std::map* m_id_pMC_map; + const Settings m_settings; ///< The mc particle creator settings + const pandora::Pandora& m_pandora; ///< Reference to the pandora object to create the mc particles + const float m_bField; ///< The bfield + std::map* m_id_pMC_map; }; -inline void MCParticleCreator::Reset() -{ - m_id_pMC_map->clear(); -} - +inline void MCParticleCreator::Reset() { m_id_pMC_map->clear(); } -#endif // #ifndef DDMCPARTICLECREATOR_H +#endif // #ifndef DDMCPARTICLECREATOR_H diff --git a/k4GaudiPandora/include/DDPandoraPFANewProcessor.h b/k4GaudiPandora/include/DDPandoraPFANewProcessor.h index b7b27f3..f18eee1 100644 --- a/k4GaudiPandora/include/DDPandoraPFANewProcessor.h +++ b/k4GaudiPandora/include/DDPandoraPFANewProcessor.h @@ -1,8 +1,27 @@ +/* + * Copyright (c) 2020-2024 Key4hep-Project. + * + * This file is part of Key4hep. + * See https://key4hep.github.io/key4hep-doc/ for further info. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + /** * @file DDMarlinPandora/include/DDPandoraPFANewProcessor.h - * + * * @brief Header file for the pandora pfa new processor class. - * + * * $Log: $ */ @@ -20,162 +39,155 @@ #include "DD4hep/DetType.h" #include "DD4hep/DetectorSelector.h" - -namespace pandora {class Pandora;} +namespace pandora { + class Pandora; +} //------------------------------------------------------------------------------------------------------------------------------------------ /** * @brief DDPandoraPFANewProcessor class */ -class DDPandoraPFANewProcessor : public marlin::Processor -{ +class DDPandoraPFANewProcessor : public marlin::Processor { public: - typedef std::vector FloatVector; - typedef std::vector StringVector; + typedef std::vector FloatVector; + typedef std::vector StringVector; - /** + /** * @brief Settings class */ - class Settings - { - public: - /** + class Settings { + public: + /** * @brief Default constructor */ - Settings(); - - std::string m_pandoraSettingsXmlFile = ""; ///< The pandora settings xml file - - float m_innerBField = 0.0; ///< The bfield in the main tracker, ecal and hcal, units Tesla - float m_muonBarrelBField = 0.0; ///< The bfield in the muon barrel, units Tesla - float m_muonEndCapBField = 0.0; ///< The bfield in the muon endcap, units Tesla - bool m_useDD4hepField = false; ///< Whether to use the DD4hep field map instead of the values above - - FloatVector m_inputEnergyCorrectionPoints{}; ///< The input energy points for non-linearity energy correction - FloatVector m_outputEnergyCorrectionPoints{}; ///< The output energy points for non-linearity energy correction - - // Software compensation parameters - FloatVector m_softCompParameters{}; - FloatVector m_softCompEnergyDensityBins{}; - float m_energyDensityFinalBin = 0.0; - float m_maxClusterEnergyToApplySoftComp = 100.0; - float m_minCleanHitEnergy = 0.5; - float m_minCleanHitEnergyFraction = 0.01; - float m_minCleanCorrectedHitEnergy = 0.1; - - - ///ADDED BY NIKIFOROS - //Detector names not needed anymore, accessed by det type flags - std::string m_trackCreatorName = ""; ///< The name of the DDTrackCreator implementation to use - - - }; + Settings(); - /** + std::string m_pandoraSettingsXmlFile = ""; ///< The pandora settings xml file + + float m_innerBField = 0.0; ///< The bfield in the main tracker, ecal and hcal, units Tesla + float m_muonBarrelBField = 0.0; ///< The bfield in the muon barrel, units Tesla + float m_muonEndCapBField = 0.0; ///< The bfield in the muon endcap, units Tesla + bool m_useDD4hepField = false; ///< Whether to use the DD4hep field map instead of the values above + + FloatVector m_inputEnergyCorrectionPoints{}; ///< The input energy points for non-linearity energy correction + FloatVector m_outputEnergyCorrectionPoints{}; ///< The output energy points for non-linearity energy correction + + // Software compensation parameters + FloatVector m_softCompParameters{}; + FloatVector m_softCompEnergyDensityBins{}; + float m_energyDensityFinalBin = 0.0; + float m_maxClusterEnergyToApplySoftComp = 100.0; + float m_minCleanHitEnergy = 0.5; + float m_minCleanHitEnergyFraction = 0.01; + float m_minCleanCorrectedHitEnergy = 0.1; + + ///ADDED BY NIKIFOROS + //Detector names not needed anymore, accessed by det type flags + std::string m_trackCreatorName = ""; ///< The name of the DDTrackCreator implementation to use + }; + + /** * @brief Default constructor */ - DDPandoraPFANewProcessor(); - DDPandoraPFANewProcessor(const DDPandoraPFANewProcessor&) = delete; - DDPandoraPFANewProcessor& operator=(const DDPandoraPFANewProcessor&) = delete; + DDPandoraPFANewProcessor(); + DDPandoraPFANewProcessor(const DDPandoraPFANewProcessor&) = delete; + DDPandoraPFANewProcessor& operator=(const DDPandoraPFANewProcessor&) = delete; - /** + /** * @brief Create new processor */ - virtual Processor *newProcessor(); + virtual Processor* newProcessor(); - /** + /** * @brief Initialize, called at startup */ - virtual void init(); + virtual void init(); - /** + /** * @brief Process run header * * @param pLCRunHeader the lc run header */ - virtual void processRunHeader(lcio::LCRunHeader *pLCRunHeader); + virtual void processRunHeader(lcio::LCRunHeader* pLCRunHeader); - /** + /** * @brief Process event, main entry point * * @param pLCEvent the lc event */ - virtual void processEvent(EVENT::LCEvent *pLCEvent); + virtual void processEvent(EVENT::LCEvent* pLCEvent); - /** + /** * @brief Checks for event * * @param pLCEvent the lc event */ - virtual void check(EVENT::LCEvent *pLCEvent); + virtual void check(EVENT::LCEvent* pLCEvent); - /** + /** * @brief End, called at shutdown */ - virtual void end(); + virtual void end(); - /** + /** * @brief Get address of the pandora instance - * + * * @return address of the pandora instance */ - const pandora::Pandora *GetPandora() const; + const pandora::Pandora* GetPandora() const; - /** + /** * @brief Get address of the current lcio event - * + * * @param pPandora address of the relevant pandora instance - * + * * @return address of the current lcio event */ - static const EVENT::LCEvent *GetCurrentEvent(const pandora::Pandora *const pPandora); + static const EVENT::LCEvent* GetCurrentEvent(const pandora::Pandora* const pPandora); private: - /** + /** * @brief Register user algorithm factories, energy correction functions and particle id functions, * insert user code here */ - pandora::StatusCode RegisterUserComponents() const; + pandora::StatusCode RegisterUserComponents() const; - /** + /** * @brief Process steering file parameters, insert user code here */ - void ProcessSteeringFile(); + void ProcessSteeringFile(); - /** + /** * @brief Copy some steering parameters between settings objects */ - void FinaliseSteeringParameters(); + void FinaliseSteeringParameters(); - /** + /** * @brief Reset the pandora pfa new processor */ - void Reset(); - - pandora::Pandora *m_pPandora = NULL; ///< Address of the pandora instance - DDCaloHitCreator *m_pCaloHitCreator = NULL; ///< The calo hit creator - DDGeometryCreator *m_pGeometryCreator = NULL; ///< The geometry creator - DDTrackCreatorBase *m_pTrackCreator = NULL; ///< The track creator - DDMCParticleCreator *m_pDDMCParticleCreator = NULL; ///< The mc particle creator - DDPfoCreator *m_pDDPfoCreator = NULL; ///< The pfo creator - - Settings m_settings{}; ///< The settings for the pandora pfa new processor - DDCaloHitCreator::Settings m_caloHitCreatorSettings{}; ///< The calo hit creator settings - DDGeometryCreator::Settings m_geometryCreatorSettings{}; ///< The geometry creator settings - DDMCParticleCreator::Settings m_mcParticleCreatorSettings{}; ///< The mc particle creator settings - DDTrackCreatorBase::Settings m_trackCreatorSettings{}; ///< The track creator settings - DDPfoCreator::Settings m_pfoCreatorSettings{}; ///< The pfo creator settings - - typedef std::map PandoraToLCEventMap; - static PandoraToLCEventMap m_pandoraToLCEventMap; ///< The pandora to lc event map + void Reset(); + + pandora::Pandora* m_pPandora = NULL; ///< Address of the pandora instance + DDCaloHitCreator* m_pCaloHitCreator = NULL; ///< The calo hit creator + DDGeometryCreator* m_pGeometryCreator = NULL; ///< The geometry creator + DDTrackCreatorBase* m_pTrackCreator = NULL; ///< The track creator + DDMCParticleCreator* m_pDDMCParticleCreator = NULL; ///< The mc particle creator + DDPfoCreator* m_pDDPfoCreator = NULL; ///< The pfo creator + + Settings m_settings{}; ///< The settings for the pandora pfa new processor + DDCaloHitCreator::Settings m_caloHitCreatorSettings{}; ///< The calo hit creator settings + DDGeometryCreator::Settings m_geometryCreatorSettings{}; ///< The geometry creator settings + DDMCParticleCreator::Settings m_mcParticleCreatorSettings{}; ///< The mc particle creator settings + DDTrackCreatorBase::Settings m_trackCreatorSettings{}; ///< The track creator settings + DDPfoCreator::Settings m_pfoCreatorSettings{}; ///< The pfo creator settings + + typedef std::map PandoraToLCEventMap; + static PandoraToLCEventMap m_pandoraToLCEventMap; ///< The pandora to lc event map }; //------------------------------------------------------------------------------------------------------------------------------------------ -inline marlin::Processor *DDPandoraPFANewProcessor::newProcessor() -{ - return new DDPandoraPFANewProcessor; -} +inline marlin::Processor* DDPandoraPFANewProcessor::newProcessor() { return new DDPandoraPFANewProcessor; } -#endif // #ifndef DDPANDORAPFANEWPROCESSOR_H +#endif // #ifndef DDPANDORAPFANEWPROCESSOR_H diff --git a/k4GaudiPandora/include/DDPfoCreator.h b/k4GaudiPandora/include/DDPfoCreator.h index 216993f..31d391d 100644 --- a/k4GaudiPandora/include/DDPfoCreator.h +++ b/k4GaudiPandora/include/DDPfoCreator.h @@ -1,8 +1,26 @@ +/* + * Copyright (c) 2020-2024 Key4hep-Project. + * + * This file is part of Key4hep. + * See https://key4hep.github.io/key4hep-doc/ for further info. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #ifndef DDPFO_CREATOR_H #define DDPFO_CREATOR_H 1 -#include "ClusterShapes.h" #include "Api/PandoraApi.h" +#include "ClusterShapes.h" class CollectionMaps; //------------------------------------------------------------------------------------------------------------------------------------------ @@ -10,75 +28,68 @@ class CollectionMaps; /** * @brief DDPfoCreator class */ -class DDPfoCreator -{ +class DDPfoCreator { public: - /** + /** * @brief Settings class */ - class Settings - { - public: - /** + class Settings { + public: + /** * @brief Default constructor */ - Settings(); - - std::string m_clusterCollectionName = ""; ///< The name of the cluster output collection - std::string m_pfoCollectionName = ""; ///< The name of the pfo output collection - std::string m_startVertexCollectionName = ""; ///< The name of the start vertex output collection - std::string m_startVertexAlgName = ""; ///< The name of the algorithm to fill the start vertex output collection - float m_emStochasticTerm = 0; ///< The stochastic term for EM shower energy resolution - float m_hadStochasticTerm = 0; ///< The stochastic term for Hadronic shower energy resolution - float m_emConstantTerm = 0; ///< The constant term for EM shower energy resolution - float m_hadConstantTerm = 0; ///< The constant term for Hadronic shower energy resolution - }; - - /** + Settings(); + + std::string m_clusterCollectionName = ""; ///< The name of the cluster output collection + std::string m_pfoCollectionName = ""; ///< The name of the pfo output collection + std::string m_startVertexCollectionName = ""; ///< The name of the start vertex output collection + std::string m_startVertexAlgName = ""; ///< The name of the algorithm to fill the start vertex output collection + float m_emStochasticTerm = 0; ///< The stochastic term for EM shower energy resolution + float m_hadStochasticTerm = 0; ///< The stochastic term for Hadronic shower energy resolution + float m_emConstantTerm = 0; ///< The constant term for EM shower energy resolution + float m_hadConstantTerm = 0; ///< The constant term for Hadronic shower energy resolution + }; + + /** * @brief Constructor - * + * * @param settings the creator settings * @param pPandora address of the relevant pandora instance */ - DDPfoCreator(const Settings &settings, const pandora::Pandora *const pPandora); + DDPfoCreator(const Settings& settings, const pandora::Pandora* const pPandora); - /** + /** * @brief Destructor */ - ~DDPfoCreator(); + ~DDPfoCreator(); - /** + /** * @brief Create particle flow objects - * - */ - pandora::StatusCode CreateParticleFlowObjects(CollectionMaps& collectionMaps, DataHandle& _pClusterCollection, DataHandle& _pReconstructedParticleCollection, DataHandle& _pStartVertexCollection); - - CollectionMaps* m_collectionMaps; + * + */ + pandora::StatusCode CreateParticleFlowObjects( + CollectionMaps& collectionMaps, DataHandle& _pClusterCollection, + DataHandle& _pReconstructedParticleCollection, + DataHandle& _pStartVertexCollection); + + CollectionMaps* m_collectionMaps; private: - /** + /** * @brief index for the subdetector */ - enum Index - { - ECAL_INDEX = 0, - HCAL_INDEX = 1, - YOKE_INDEX = 2, - LCAL_INDEX = 3, - LHCAL_INDEX = 4, - BCAL_INDEX = 5 - }; + enum Index { ECAL_INDEX = 0, HCAL_INDEX = 1, YOKE_INDEX = 2, LCAL_INDEX = 3, LHCAL_INDEX = 4, BCAL_INDEX = 5 }; - /** + /** * @brief initialise sub detector name strings - * + * * @param subDetectorNames to receive the list of sub detector names */ - void InitialiseSubDetectorNames(pandora::StringVector &subDetectorNames) const; + void InitialiseSubDetectorNames(pandora::StringVector& subDetectorNames) const; - /** + /** * @brief Set sub detector energies for a cluster - * + * * @param subDetectorNames the list of sub detector names * @param pLcioCluster the address of the lcio cluster to be set sub detector energies * @param pandoraCaloHitList the pandora calorimeter hit list @@ -87,24 +98,27 @@ class DDPfoCreator * @param hitY the vector to receive the y position of hits * @param hitZ the vector to receive the z position of hits */ - void SetClusterSubDetectorEnergies(const pandora::StringVector &subDetectorNames, edm4hep::Cluster *const pLcioCluster, - const pandora::CaloHitList &pandoraCaloHitList, pandora::FloatVector &hitE, pandora::FloatVector &hitX, pandora::FloatVector &hitY, - pandora::FloatVector &hitZ) const; + void SetClusterSubDetectorEnergies(const pandora::StringVector& subDetectorNames, + edm4hep::Cluster* const pLcioCluster, + const pandora::CaloHitList& pandoraCaloHitList, pandora::FloatVector& hitE, + pandora::FloatVector& hitX, pandora::FloatVector& hitY, + pandora::FloatVector& hitZ) const; - /** + /** * @brief Set cluster energies and errors - * + * * @param pPandoraPfo the address of the pandora pfo * @param pPandoraCluster the address of the pandora cluster * @param pLcioCluster the address of the lcio cluster to be set energies and erros * @param clusterCorrectEnergy a number to receive the cluster correct energy */ - void SetClusterEnergyAndError(const pandora::ParticleFlowObject *const pPandoraPfo, const pandora::Cluster *const pPandoraCluster, - edm4hep::Cluster *const pLcioCluster, float &clusterCorrectEnergy) const; + void SetClusterEnergyAndError(const pandora::ParticleFlowObject* const pPandoraPfo, + const pandora::Cluster* const pPandoraCluster, edm4hep::Cluster* const pLcioCluster, + float& clusterCorrectEnergy) const; - /** + /** * @brief Set cluster position, errors and other shape info, by calculating culster shape first - * + * * @param nHitsInCluster number of hits in cluster * @param hitE the vector of the energy of hits * @param hitX the vector of the x position of hits @@ -113,83 +127,90 @@ class DDPfoCreator * @param pLcioCluster the lcio cluster to be set positions and errors * @param clusterPosition a CartesianVector to receive the cluster position */ - void SetClusterPositionAndError(const unsigned int nHitsInCluster, pandora::FloatVector &hitE, pandora::FloatVector &hitX, - pandora::FloatVector &hitY, pandora::FloatVector &hitZ, edm4hep::Cluster *const pLcioCluster, pandora::CartesianVector &clusterPositionVec) const; + void SetClusterPositionAndError(const unsigned int nHitsInCluster, pandora::FloatVector& hitE, + pandora::FloatVector& hitX, pandora::FloatVector& hitY, pandora::FloatVector& hitZ, + edm4hep::Cluster* const pLcioCluster, + pandora::CartesianVector& clusterPositionVec) const; - /** + /** * @brief Calculate reference point for pfo with tracks - * + * * @param pPandoraPfo the address of the pandora pfo * @param referencePoint a CartesianVector to receive the reference point */ - pandora::StatusCode CalculateTrackBasedReferencePoint(const pandora::ParticleFlowObject *const pPandoraPfo, pandora::CartesianVector &referencePoint) const; + pandora::StatusCode CalculateTrackBasedReferencePoint(const pandora::ParticleFlowObject* const pPandoraPfo, + pandora::CartesianVector& referencePoint) const; - /** + /** * @brief Set reference point of the reconstructed particle - * + * * @param referencePoint a CartesianVector of the reference point * @param pReconstructedParticle the address of the reconstructed particle to be reference point */ - void SetRecoParticleReferencePoint(const pandora::CartesianVector &referencePoint, edm4hep::ReconstructedParticle *const pReconstructedParticle) const; + void SetRecoParticleReferencePoint(const pandora::CartesianVector& referencePoint, + edm4hep::ReconstructedParticle* const pReconstructedParticle) const; - /** + /** * @brief Add tracks to reconstructed particle - * + * * @param pPandoraPfo the address of the pandora pfo * @param pReconstructedParticle the address of the reconstructed particle to be added tracks */ - void AddTracksToRecoParticle(const pandora::ParticleFlowObject *const pPandoraPfo, edm4hep::ReconstructedParticle *const pReconstructedParticle) const; + void AddTracksToRecoParticle(const pandora::ParticleFlowObject* const pPandoraPfo, + edm4hep::ReconstructedParticle* const pReconstructedParticle) const; - /** + /** * @brief Set properties of reconstructed particle from pandora pfo - * - * @param pPandoraPfo the address of the pandora pfo + * + * @param pPandoraPfo the address of the pandora pfo * @param pReconstructedParticle the address of the reconstructed particle to be set properties */ - void SetRecoParticlePropertiesFromPFO(const pandora::ParticleFlowObject *const pPandoraPfo, edm4hep::ReconstructedParticle *const pReconstructedParticle) const; + void SetRecoParticlePropertiesFromPFO(const pandora::ParticleFlowObject* const pPandoraPfo, + edm4hep::ReconstructedParticle* const pReconstructedParticle) const; - /** + /** * @brief Whether parent and daughter tracks are associated with the same pfo * * @param pPandoraTrack the address of the pandora track * @param allTrackList list of all tracks associated with reconstructed particle - * + * * @return boolean */ - bool IsValidParentTrack(const pandora::Track *const pPandoraTrack, const pandora::TrackList &allTrackList) const; + bool IsValidParentTrack(const pandora::Track* const pPandoraTrack, const pandora::TrackList& allTrackList) const; - /** + /** * @brief Whether sibling tracks are associated with the same pfo * * @param pPandoraTrack the address of the pandora track * @param allTrackList list of all tracks associated with reconstructed particle - * + * * @return boolean */ - bool HasValidSiblingTrack(const pandora::Track *const pPandoraTrack, const pandora::TrackList &allTrackList) const; + bool HasValidSiblingTrack(const pandora::Track* const pPandoraTrack, const pandora::TrackList& allTrackList) const; - /** + /** * @brief Whether the track is the closest (of those associated with the same pfo) to the interaction point * * @param pPandoraTrack the address of the pandora track * @param allTrackList list of all tracks associated to reconstructed particle - * + * * @return boolean - */ - bool IsClosestTrackToIP(const pandora::Track *const pPandoraTrack, const pandora::TrackList &allTrackList) const; + */ + bool IsClosestTrackToIP(const pandora::Track* const pPandoraTrack, const pandora::TrackList& allTrackList) const; - /** - * @brief Whether at least one track sibling track is associated to the reconstructed particle + /** + * @brief Whether at least one track sibling track is associated to the reconstructed particle * * @param pPandoraTrack the address of the pandora track * @param allTrackList list of all tracks associated to reconstructed particle - * + * * @return boolean */ - bool AreAnyOtherSiblingsInList(const pandora::Track *const pPandoraTrack, const pandora::TrackList &allTrackList) const; + bool AreAnyOtherSiblingsInList(const pandora::Track* const pPandoraTrack, + const pandora::TrackList& allTrackList) const; - const Settings m_settings; ///< The pfo creator settings - const pandora::Pandora &m_pandora; ///< Reference to the pandora object from which to extract the pfos + const Settings m_settings; ///< The pfo creator settings + const pandora::Pandora& m_pandora; ///< Reference to the pandora object from which to extract the pfos }; -#endif // #ifndef DDPFO_CREATOR_H +#endif // #ifndef DDPFO_CREATOR_H diff --git a/k4GaudiPandora/include/DDScintillatorPpdDigi.h b/k4GaudiPandora/include/DDScintillatorPpdDigi.h index cf2ded1..0a9e851 100644 --- a/k4GaudiPandora/include/DDScintillatorPpdDigi.h +++ b/k4GaudiPandora/include/DDScintillatorPpdDigi.h @@ -1,48 +1,62 @@ +/* + * Copyright (c) 2020-2024 Key4hep-Project. + * + * This file is part of Key4hep. + * See https://key4hep.github.io/key4hep-doc/ for further info. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #ifndef _DDScintillatorPpdDigi_h_ #define _DDScintillatorPpdDigi_h_ class DDScintillatorPpdDigi { - - public: - +public: DDScintillatorPpdDigi(); - ~DDScintillatorPpdDigi(){} + ~DDScintillatorPpdDigi() {} // expected # photoelectrons / MIP - void setPEperMIP(float x) {_pe_per_mip=x;} + void setPEperMIP(float x) { _pe_per_mip = x; } // calibration factor from input hit energy to MIPs - void setCalibMIP(float x) {_calib_mip=x;} + void setCalibMIP(float x) { _calib_mip = x; } // #pixels of PPD - void setNPix(int x) {_npix=x;} + void setNPix(int x) { _npix = x; } // random miscalibration of total #pixels (as a fraction of pixel number: 0.05 = 5% miscalibration) - void setRandomMisCalibNPix(float x) {_misCalibNpix=x;} + void setRandomMisCalibNPix(float x) { _misCalibNpix = x; } // spread in pixel capacitance (as a fraction: 0.05 = 5% spread) - void setPixSpread(float x) {_pixSpread=x;} + void setPixSpread(float x) { _pixSpread = x; } // electronics noise (in MIP units) - void setElecNoise(float x) {_elecNoise=x;} + void setElecNoise(float x) { _elecNoise = x; } // electronics dynamic range (in MIP units) - void setElecRange(float x) {_elecMaxDynRange_MIP=x;} + void setElecRange(float x) { _elecMaxDynRange_MIP = x; } - float getDigitisedEnergy( float energy ); + float getDigitisedEnergy(float energy); void printParameters(); - private: - - float _pe_per_mip = -99; - float _calib_mip = -99; - float _npix = -99; - float _misCalibNpix = 0; - float _pixSpread = 0; - float _elecNoise = 0; +private: + float _pe_per_mip = -99; + float _calib_mip = -99; + float _npix = -99; + float _misCalibNpix = 0; + float _pixSpread = 0; + float _elecNoise = 0; float _elecMaxDynRange_MIP = 0; - }; #endif diff --git a/k4GaudiPandora/include/DDTrackCreatorBase.h b/k4GaudiPandora/include/DDTrackCreatorBase.h index 383e93d..15537e9 100644 --- a/k4GaudiPandora/include/DDTrackCreatorBase.h +++ b/k4GaudiPandora/include/DDTrackCreatorBase.h @@ -1,8 +1,27 @@ +/* + * Copyright (c) 2020-2024 Key4hep-Project. + * + * This file is part of Key4hep. + * See https://key4hep.github.io/key4hep-doc/ for further info. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + /** * @file DDMarlinPandora/include/DDTrackCreatorBase.h - * + * * @brief Header file for the track creator base class. - * + * * $Log: $ */ @@ -24,29 +43,28 @@ #include -typedef std::vector TrackVector; -typedef std::set TrackList; -typedef std::map TrackToPidMap; +typedef std::vector TrackVector; +typedef std::set TrackList; +typedef std::map TrackToPidMap; -namespace lc_content{ +namespace lc_content { class LCTrackParameters; class LCTrackFactory; -} -namespace MarlinTrk{ +} // namespace lc_content +namespace MarlinTrk { class IMarlinTrkSystem; } -inline IMPL::LCCollectionVec *newTrkCol(const std::string &name, EVENT::LCEvent *evt , bool isSubset) -{ - IMPL::LCCollectionVec* col = new IMPL::LCCollectionVec( EVENT::LCIO::TRACK ) ; +inline IMPL::LCCollectionVec* newTrkCol(const std::string& name, EVENT::LCEvent* evt, bool isSubset) { + IMPL::LCCollectionVec* col = new IMPL::LCCollectionVec(EVENT::LCIO::TRACK); - IMPL::LCFlagImpl hitFlag(0) ; - hitFlag.setBit( EVENT::LCIO::TRBIT_HITS ) ; - col->setFlag( hitFlag.getFlag() ) ; - evt->addCollection( col , name ) ; - col->setSubset( isSubset ) ; + IMPL::LCFlagImpl hitFlag(0); + hitFlag.setBit(EVENT::LCIO::TRBIT_HITS); + col->setFlag(hitFlag.getFlag()); + evt->addCollection(col, name); + col->setSubset(isSubset); - return col ; + return col; } //------------------------------------------------------------------------------------------------------------------------------------------ @@ -54,298 +72,283 @@ inline IMPL::LCCollectionVec *newTrkCol(const std::string &name, EVENT::LCEvent /** * @brief DDTrackCreatorBase class */ -class DDTrackCreatorBase -{ +class DDTrackCreatorBase { public: - typedef std::vector DoubleVector; - typedef std::vector StringVector; + typedef std::vector DoubleVector; + typedef std::vector StringVector; - /** + /** * @brief Settings class */ - class Settings - { - public: - /** + class Settings { + public: + /** * @brief Default constructor */ - Settings(); - - StringVector m_trackCollections; ///< The reconstructed track collections - StringVector m_kinkVertexCollections; ///< The kink vertex collections - StringVector m_prongVertexCollections; ///< The prong vertex collections - StringVector m_splitVertexCollections; ///< The split vertex collections - StringVector m_v0VertexCollections; ///< The v0 vertex collections - - StringVector m_prongSplitVertexCollections; ///< Concatenated list of prong and split vertex collections - int m_shouldFormTrackRelationships; ///< Whether to form pandora track relationships using v0 and kink info - - int m_minTrackHits; ///< Track quality cut: the minimum number of track hits - int m_minFtdTrackHits; ///< Track quality cut: the minimum number of FTD track hits for FTD only tracks - int m_maxTrackHits; ///< Track quality cut: the maximum number of track hits - - float m_d0TrackCut; ///< Track d0 cut used to determine whether track can be used to form pfo - float m_z0TrackCut; ///< Track z0 cut used to determine whether track can be used to form pfo - - int m_usingNonVertexTracks; ///< Whether can form pfos from tracks that don't start at vertex - int m_usingUnmatchedNonVertexTracks; ///< Whether can form pfos from unmatched tracks that don't start at vertex - int m_usingUnmatchedVertexTracks; ///< Whether can form pfos from unmatched tracks that start at vertex - float m_unmatchedVertexTrackMaxEnergy; ///< Maximum energy for unmatched vertex track - - float m_d0UnmatchedVertexTrackCut; ///< d0 cut used to determine whether unmatched vertex track can form pfo - float m_z0UnmatchedVertexTrackCut; ///< z0 cut used to determine whether unmatched vertex track can form pfo - float m_zCutForNonVertexTracks; ///< Non vtx track z cut to determine whether track can be used to form pfo - - int m_reachesECalNBarrelTrackerHits; ///< Minimum number of barrel tracker hits to consider track as reaching ecal - int m_reachesECalNFtdHits; ///< Minimum number of ftd hits to consider track as reaching ecal - float m_reachesECalBarrelTrackerOuterDistance; ///< Max distance from track to barrel tracker r max to id whether track reaches ecal - int m_reachesECalMinFtdLayer; ///< Min layer in Ftd for tracks to be considered to have reached decal - float m_reachesECalBarrelTrackerZMaxDistance; ///< Max distance from track to barrel tracker z max to id whether track reaches ecal - float m_reachesECalFtdZMaxDistance; ///< Max distance from track hit to ftd z position to identify ftd hits - float m_curvatureToMomentumFactor; ///< Constant relating track curvature in b field to momentum - - float m_minTrackECalDistanceFromIp; ///< Sanity check on separation between ip and track projected ecal position - float m_maxTrackSigmaPOverP; ///< Track fraction momentum error cut - float m_minMomentumForTrackHitChecks; ///< Min track momentum required to perform final quality checks on number of hits - - float m_maxBarrelTrackerInnerRDistance; ///< Track cut on distance from barrel tracker inner r to id whether track can form pfo - float m_minBarrelTrackerHitFractionOfExpected; ///< Minimum fraction of TPC hits compared to expected - int m_minFtdHitsForBarrelTrackerHitFraction; ///< Minimum number of FTD hits to ignore TPC hit fraction - float m_trackStateTolerance; ///< distance below tracker ecal radius the second trackstate in the ecal endcap is still passed to pandora - std::string m_trackingSystemName; ///< name of the tracking system used for getting new track states - - - ///Nikiforos: Moved from main class - - float m_bField; ///< The bfield - int m_eCalBarrelInnerSymmetry; ///< ECal barrel inner symmetry order - float m_eCalBarrelInnerPhi0; ///< ECal barrel inner phi 0 - float m_eCalBarrelInnerR; ///< ECal barrel inner radius - float m_eCalEndCapInnerZ; ///< ECal endcap inner z - - //Tracking Detector names not needed anymore, accessed by det type flag - - - }; - - /** + Settings(); + + StringVector m_trackCollections; ///< The reconstructed track collections + StringVector m_kinkVertexCollections; ///< The kink vertex collections + StringVector m_prongVertexCollections; ///< The prong vertex collections + StringVector m_splitVertexCollections; ///< The split vertex collections + StringVector m_v0VertexCollections; ///< The v0 vertex collections + + StringVector m_prongSplitVertexCollections; ///< Concatenated list of prong and split vertex collections + int m_shouldFormTrackRelationships; ///< Whether to form pandora track relationships using v0 and kink info + + int m_minTrackHits; ///< Track quality cut: the minimum number of track hits + int m_minFtdTrackHits; ///< Track quality cut: the minimum number of FTD track hits for FTD only tracks + int m_maxTrackHits; ///< Track quality cut: the maximum number of track hits + + float m_d0TrackCut; ///< Track d0 cut used to determine whether track can be used to form pfo + float m_z0TrackCut; ///< Track z0 cut used to determine whether track can be used to form pfo + + int m_usingNonVertexTracks; ///< Whether can form pfos from tracks that don't start at vertex + int m_usingUnmatchedNonVertexTracks; ///< Whether can form pfos from unmatched tracks that don't start at vertex + int m_usingUnmatchedVertexTracks; ///< Whether can form pfos from unmatched tracks that start at vertex + float m_unmatchedVertexTrackMaxEnergy; ///< Maximum energy for unmatched vertex track + + float m_d0UnmatchedVertexTrackCut; ///< d0 cut used to determine whether unmatched vertex track can form pfo + float m_z0UnmatchedVertexTrackCut; ///< z0 cut used to determine whether unmatched vertex track can form pfo + float m_zCutForNonVertexTracks; ///< Non vtx track z cut to determine whether track can be used to form pfo + + int m_reachesECalNBarrelTrackerHits; ///< Minimum number of barrel tracker hits to consider track as reaching ecal + int m_reachesECalNFtdHits; ///< Minimum number of ftd hits to consider track as reaching ecal + float + m_reachesECalBarrelTrackerOuterDistance; ///< Max distance from track to barrel tracker r max to id whether track reaches ecal + int m_reachesECalMinFtdLayer; ///< Min layer in Ftd for tracks to be considered to have reached decal + float + m_reachesECalBarrelTrackerZMaxDistance; ///< Max distance from track to barrel tracker z max to id whether track reaches ecal + float m_reachesECalFtdZMaxDistance; ///< Max distance from track hit to ftd z position to identify ftd hits + float m_curvatureToMomentumFactor; ///< Constant relating track curvature in b field to momentum + + float m_minTrackECalDistanceFromIp; ///< Sanity check on separation between ip and track projected ecal position + float m_maxTrackSigmaPOverP; ///< Track fraction momentum error cut + float + m_minMomentumForTrackHitChecks; ///< Min track momentum required to perform final quality checks on number of hits + + float + m_maxBarrelTrackerInnerRDistance; ///< Track cut on distance from barrel tracker inner r to id whether track can form pfo + float m_minBarrelTrackerHitFractionOfExpected; ///< Minimum fraction of TPC hits compared to expected + int m_minFtdHitsForBarrelTrackerHitFraction; ///< Minimum number of FTD hits to ignore TPC hit fraction + float + m_trackStateTolerance; ///< distance below tracker ecal radius the second trackstate in the ecal endcap is still passed to pandora + std::string m_trackingSystemName; ///< name of the tracking system used for getting new track states + + ///Nikiforos: Moved from main class + + float m_bField; ///< The bfield + int m_eCalBarrelInnerSymmetry; ///< ECal barrel inner symmetry order + float m_eCalBarrelInnerPhi0; ///< ECal barrel inner phi 0 + float m_eCalBarrelInnerR; ///< ECal barrel inner radius + float m_eCalEndCapInnerZ; ///< ECal endcap inner z + + //Tracking Detector names not needed anymore, accessed by det type flag + }; + + /** * @brief Constructor - * + * * @param settings the creator settings * @param pPandora address of the relevant pandora instance */ - DDTrackCreatorBase(const Settings &settings, const pandora::Pandora *const pPandora); + DDTrackCreatorBase(const Settings& settings, const pandora::Pandora* const pPandora); - /** + /** * @brief Destructor */ - virtual ~DDTrackCreatorBase(); + virtual ~DDTrackCreatorBase(); - /** + /** * @brief Create associations between tracks, V0s, kinks, etc - * + * * @param pLCEvent the lcio event */ - pandora::StatusCode CreateTrackAssociations(const EVENT::LCEvent *const pLCEvent); + pandora::StatusCode CreateTrackAssociations(const EVENT::LCEvent* const pLCEvent); - /** + /** * @brief Create tracks, insert user code here. Implement accordin to detector model - * + * * @param pLCEvent the lcio event */ - virtual pandora::StatusCode CreateTracks(EVENT::LCEvent *pLCEvent) = 0 ; + virtual pandora::StatusCode CreateTracks(EVENT::LCEvent* pLCEvent) = 0; - /** + /** * @brief Get the track vector - * + * * @return The track vector */ - const TrackVector &GetTrackVector() const; + const TrackVector& GetTrackVector() const; - - /** + /** * @brief Calculate possible second track state at the ECal Endcap * * @param track lcio track * @param trackParameters pandora LCTrackParameters */ - virtual void GetTrackStatesAtCalo( EVENT::Track *track, lc_content::LCTrackParameters& trackParameters); + virtual void GetTrackStatesAtCalo(EVENT::Track* track, lc_content::LCTrackParameters& trackParameters); - - /** + /** * @brief Reset the track creator */ - void Reset(); - - - + void Reset(); protected: - - - - - const Settings m_settings; ///< The track creator settings - const pandora::Pandora &m_pandora; ///< Reference to the pandora object to create tracks and track relationships - - - TrackVector m_trackVector; ///< The track vector - TrackList m_v0TrackList; ///< The list of v0 tracks - TrackList m_parentTrackList; ///< The list of parent tracks - TrackList m_daughterTrackList; ///< The list of daughter tracks - TrackToPidMap m_trackToPidMap; ///< The map from track addresses to particle ids, where set by kinks/V0s - float m_minimalTrackStateRadiusSquared; ///< minimal track state radius, derived value - std::shared_ptr m_trackingSystem={}; ///< Tracking system used for track states - std::shared_ptr m_encoder={}; ///< cell ID encoder - std::shared_ptr m_lcTrackFactory={}; ///< LCTrackFactor for creating LCTracks - - - ///Nikiforos: Need to implement following abstract functions according to detector model - - /** + const Settings m_settings; ///< The track creator settings + const pandora::Pandora& m_pandora; ///< Reference to the pandora object to create tracks and track relationships + + TrackVector m_trackVector; ///< The track vector + TrackList m_v0TrackList; ///< The list of v0 tracks + TrackList m_parentTrackList; ///< The list of parent tracks + TrackList m_daughterTrackList; ///< The list of daughter tracks + TrackToPidMap m_trackToPidMap; ///< The map from track addresses to particle ids, where set by kinks/V0s + float m_minimalTrackStateRadiusSquared; ///< minimal track state radius, derived value + std::shared_ptr m_trackingSystem = {}; ///< Tracking system used for track states + std::shared_ptr m_encoder = {}; ///< cell ID encoder + std::shared_ptr m_lcTrackFactory = {}; ///< LCTrackFactor for creating LCTracks + + ///Nikiforos: Need to implement following abstract functions according to detector model + + /** * @brief Whether track passes the quality cuts required in order to be used to form a pfo - * + * * @param pTrack the lcio track * @param trackParameters the track parameters - * + * * @return boolean */ - virtual bool PassesQualityCuts(const EVENT::Track *const pTrack, const PandoraApi::Track::Parameters &trackParameters) const = 0; - - /** + virtual bool PassesQualityCuts(const EVENT::Track* const pTrack, + const PandoraApi::Track::Parameters& trackParameters) const = 0; + + /** * @brief Decide whether track reaches the ecal surface - * + * * @param pTrack the lcio track * @param trackParameters the track parameters */ - virtual void TrackReachesECAL(const EVENT::Track *const pTrack, PandoraApi::Track::Parameters &trackParameters) const = 0 ; + virtual void TrackReachesECAL(const EVENT::Track* const pTrack, + PandoraApi::Track::Parameters& trackParameters) const = 0; - /** + /** * @brief Determine whether a track can be used to form a pfo under the following conditions: * 1) if the track proves to be associated with a cluster, OR * 2) if the track proves to have no cluster associations - * + * * @param pTrack the lcio track * @param trackParameters the track parameters */ - virtual void DefineTrackPfoUsage(const EVENT::Track *const pTrack, PandoraApi::Track::Parameters &trackParameters) const = 0; - - /** + virtual void DefineTrackPfoUsage(const EVENT::Track* const pTrack, + PandoraApi::Track::Parameters& trackParameters) const = 0; + + /** * @brief Extract kink information from specified lcio collections - * + * * @param pLCEvent the lcio event */ - pandora::StatusCode ExtractKinks(const EVENT::LCEvent *const pLCEvent); + pandora::StatusCode ExtractKinks(const EVENT::LCEvent* const pLCEvent); - /** + /** * @brief Extract prong and split information from specified lcio collections - * + * * @param pLCEvent the lcio event */ - pandora::StatusCode ExtractProngsAndSplits(const EVENT::LCEvent *const pLCEvent); + pandora::StatusCode ExtractProngsAndSplits(const EVENT::LCEvent* const pLCEvent); - /** + /** * @brief Extract v0 information from specified lcio collections - * + * * @param pLCEvent the lcio event */ - pandora::StatusCode ExtractV0s(const EVENT::LCEvent *const pLCEvent); + pandora::StatusCode ExtractV0s(const EVENT::LCEvent* const pLCEvent); - /** + /** * @brief Whether the track vertex conflicts with previously provided relationship information - * + * * @param trackVec the vector of tracks associated with the vertex */ - bool IsConflictingRelationship(const EVENT::TrackVec &trackVec) const; + bool IsConflictingRelationship(const EVENT::TrackVec& trackVec) const; - /** + /** * @brief Whether a track is a v0 track - * + * * @param pTrack the lcio track - * + * * @return boolean */ - bool IsV0(const EVENT::Track *const pTrack) const; + bool IsV0(const EVENT::Track* const pTrack) const; - /** + /** * @brief Whether a track is a parent track - * + * * @param pTrack the lcio track - * + * * @return boolean */ - bool IsParent(const EVENT::Track *const pTrack) const; + bool IsParent(const EVENT::Track* const pTrack) const; - /** + /** * @brief Whether a track is a daughter track - * + * * @param pTrack the lcio track - * + * * @return boolean */ - bool IsDaughter(const EVENT::Track *const pTrack) const; + bool IsDaughter(const EVENT::Track* const pTrack) const; - /** + /** * @brief Copy track states stored in lcio tracks to pandora track parameters - * + * * @param pTrack the lcio track * @param trackParameters the track parameters */ - void GetTrackStates(const EVENT::Track *const pTrack, PandoraApi::Track::Parameters &trackParameters) const; + void GetTrackStates(const EVENT::Track* const pTrack, PandoraApi::Track::Parameters& trackParameters) const; - /** + /** * @brief Copy track state from lcio track state instance to pandora input track state - * + * * @param pTrackState the lcio track state instance * @param inputTrackState the pandora input track state */ - void CopyTrackState(const EVENT::TrackState *const pTrackState, pandora::InputTrackState &inputTrackState) const; + void CopyTrackState(const EVENT::TrackState* const pTrackState, pandora::InputTrackState& inputTrackState) const; - /** + /** * @brief Obtain track time when it reaches ECAL - * + * * @param pTrack the lcio track */ - float CalculateTrackTimeAtCalorimeter(const EVENT::Track *const pTrack) const; + float CalculateTrackTimeAtCalorimeter(const EVENT::Track* const pTrack) const; }; //------------------------------------------------------------------------------------------------------------------------------------------ -inline const TrackVector &DDTrackCreatorBase::GetTrackVector() const -{ - return m_trackVector; -} +inline const TrackVector& DDTrackCreatorBase::GetTrackVector() const { return m_trackVector; } //------------------------------------------------------------------------------------------------------------------------------------------ -inline void DDTrackCreatorBase::Reset() -{ - m_trackVector.clear(); - m_v0TrackList.clear(); - m_parentTrackList.clear(); - m_daughterTrackList.clear(); - m_trackToPidMap.clear(); +inline void DDTrackCreatorBase::Reset() { + m_trackVector.clear(); + m_v0TrackList.clear(); + m_parentTrackList.clear(); + m_daughterTrackList.clear(); + m_trackToPidMap.clear(); } //------------------------------------------------------------------------------------------------------------------------------------------ -inline bool DDTrackCreatorBase::IsV0(const EVENT::Track *const pTrack) const -{ - return (m_v0TrackList.end() != m_v0TrackList.find(pTrack)); +inline bool DDTrackCreatorBase::IsV0(const EVENT::Track* const pTrack) const { + return (m_v0TrackList.end() != m_v0TrackList.find(pTrack)); } //------------------------------------------------------------------------------------------------------------------------------------------ -inline bool DDTrackCreatorBase::IsParent(const EVENT::Track *const pTrack) const -{ - return (m_parentTrackList.end() != m_parentTrackList.find(pTrack)); +inline bool DDTrackCreatorBase::IsParent(const EVENT::Track* const pTrack) const { + return (m_parentTrackList.end() != m_parentTrackList.find(pTrack)); } //------------------------------------------------------------------------------------------------------------------------------------------ -inline bool DDTrackCreatorBase::IsDaughter(const EVENT::Track *const pTrack) const -{ - return (m_daughterTrackList.end() != m_daughterTrackList.find(pTrack)); +inline bool DDTrackCreatorBase::IsDaughter(const EVENT::Track* const pTrack) const { + return (m_daughterTrackList.end() != m_daughterTrackList.find(pTrack)); } -#endif // #ifndef DDTRACK_CREATOR_BASE_H +#endif // #ifndef DDTRACK_CREATOR_BASE_H diff --git a/k4GaudiPandora/include/DDTrackCreatorCLIC.h b/k4GaudiPandora/include/DDTrackCreatorCLIC.h index ef9352a..5dabf29 100644 --- a/k4GaudiPandora/include/DDTrackCreatorCLIC.h +++ b/k4GaudiPandora/include/DDTrackCreatorCLIC.h @@ -1,8 +1,27 @@ +/* + * Copyright (c) 2020-2024 Key4hep-Project. + * + * This file is part of Key4hep. + * See https://key4hep.github.io/key4hep-doc/ for further info. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + /** * @file DDMarlinPandora/include/DDTrackCreatorCLIC.h - * + * * @brief Header file for the ILD implementation of the track creator class. - * + * * $Log: $ */ @@ -16,81 +35,74 @@ /** * @brief DDTrackCreatorCLIC class */ -class DDTrackCreatorCLIC : public DDTrackCreatorBase -{ +class DDTrackCreatorCLIC : public DDTrackCreatorBase { public: - - /** + /** * @brief Constructor - * + * * @param settings the creator settings * @param pPandora address of the relevant pandora instance */ - DDTrackCreatorCLIC(const Settings &settings, const pandora::Pandora *const pPandora); + DDTrackCreatorCLIC(const Settings& settings, const pandora::Pandora* const pPandora); - /** + /** * @brief Destructor */ - virtual ~DDTrackCreatorCLIC(); + virtual ~DDTrackCreatorCLIC(); - /** + /** * @brief Create tracks implementation, insert user code here. Detector specific - * + * * @param pLCEvent the lcio event */ - pandora::StatusCode CreateTracks(EVENT::LCEvent *pLCEvent); - + pandora::StatusCode CreateTracks(EVENT::LCEvent* pLCEvent); - protected: - + //Detector-specific configuration variables + float m_trackerInnerR; ///< Inner radius of the barrel tracker + float m_trackerOuterR; ///< Outer radius of the barrel tracker + float m_trackerZmax; ///< max extent of the tracker along z + float m_cosTracker; - //Detector-specific configuration variables - float m_trackerInnerR; ///< Inner radius of the barrel tracker - float m_trackerOuterR; ///< Outer radius of the barrel tracker - float m_trackerZmax; ///< max extent of the tracker along z - float m_cosTracker; - - DoubleVector m_endcapDiskInnerRadii; ///< List of endcapDisk inner radii - DoubleVector m_endcapDiskOuterRadii; ///< List of endcapDisk outer radii - DoubleVector m_endcapDiskZPositions; ///< List of endcapDisk z positions - unsigned int m_nEndcapDiskLayers; ///< Number of endcapDisk layers - unsigned int m_barrelTrackerLayers; ///< Number of barrel tracker layers + DoubleVector m_endcapDiskInnerRadii; ///< List of endcapDisk inner radii + DoubleVector m_endcapDiskOuterRadii; ///< List of endcapDisk outer radii + DoubleVector m_endcapDiskZPositions; ///< List of endcapDisk z positions + unsigned int m_nEndcapDiskLayers; ///< Number of endcapDisk layers + unsigned int m_barrelTrackerLayers; ///< Number of barrel tracker layers - float m_tanLambdaEndcapDisk; ///< Tan lambda for first endcapDisk layer - - /** + float m_tanLambdaEndcapDisk; ///< Tan lambda for first endcapDisk layer + + /** * @brief Whether track passes the quality cuts required in order to be used to form a pfo. Detector specific - * + * * @param pTrack the lcio track * @param trackParameters the track parameters - * + * * @return boolean */ - - virtual bool PassesQualityCuts(const EVENT::Track *const pTrack, const PandoraApi::Track::Parameters &trackParameters) const; - - /** + + virtual bool PassesQualityCuts(const EVENT::Track* const pTrack, + const PandoraApi::Track::Parameters& trackParameters) const; + + /** * @brief Decide whether track reaches the ecal surface. Detector specific - * + * * @param pTrack the lcio track * @param trackParameters the track parameters */ - virtual void TrackReachesECAL(const EVENT::Track *const pTrack, PandoraApi::Track::Parameters &trackParameters) const; - - /** + virtual void TrackReachesECAL(const EVENT::Track* const pTrack, PandoraApi::Track::Parameters& trackParameters) const; + + /** * @brief Determine whether a track can be used to form a pfo under the following conditions: * 1) if the track proves to be associated with a cluster, OR * 2) if the track proves to have no cluster associations * Detector specific - * + * * @param pTrack the lcio track * @param trackParameters the track parameters */ - virtual void DefineTrackPfoUsage(const EVENT::Track *const pTrack, PandoraApi::Track::Parameters &trackParameters) const; - + virtual void DefineTrackPfoUsage(const EVENT::Track* const pTrack, + PandoraApi::Track::Parameters& trackParameters) const; }; - - -#endif // #ifndef DDTRACK_CREATOR_CLIC_H +#endif // #ifndef DDTRACK_CREATOR_CLIC_H diff --git a/k4GaudiPandora/include/DDTrackCreatorILD.h b/k4GaudiPandora/include/DDTrackCreatorILD.h index 338166a..e98298c 100644 --- a/k4GaudiPandora/include/DDTrackCreatorILD.h +++ b/k4GaudiPandora/include/DDTrackCreatorILD.h @@ -1,8 +1,27 @@ +/* + * Copyright (c) 2020-2024 Key4hep-Project. + * + * This file is part of Key4hep. + * See https://key4hep.github.io/key4hep-doc/ for further info. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + /** * @file DDMarlinPandora/include/DDTrackCreatorILD.h - * + * * @brief Header file for the ILD implementation of the track creator class. - * + * * $Log: $ */ @@ -16,104 +35,94 @@ /** * @brief DDTrackCreatorILD class */ -class DDTrackCreatorILD : public DDTrackCreatorBase -{ +class DDTrackCreatorILD : public DDTrackCreatorBase { public: - - /** + /** * @brief Constructor - * + * * @param settings the creator settings * @param pPandora address of the relevant pandora instance */ - DDTrackCreatorILD(const Settings &settings, const pandora::Pandora *const pPandora); + DDTrackCreatorILD(const Settings& settings, const pandora::Pandora* const pPandora); - /** + /** * @brief Destructor */ - virtual ~DDTrackCreatorILD(); + virtual ~DDTrackCreatorILD(); - /** + /** * @brief Create tracks implementation, insert user code here. Detector specific - * + * * @param pLCEvent the lcio event */ - pandora::StatusCode CreateTracks(EVENT::LCEvent *pLCEvent); - + pandora::StatusCode CreateTracks(EVENT::LCEvent* pLCEvent); - protected: - - - //Detector-specific configuration variables - float m_cosTpc; ///< Cos(theta) value at end of tpc - float m_tpcInnerR; ///< The tpc inner radius - float m_tpcOuterR; ///< The tpc outer radius - unsigned int m_tpcMaxRow; ///< The tpc maximum row number - float m_tpcZmax; ///< The tpc maximum z coordinate - float m_tpcMembraneMaxZ; ///< Tpc membrane max z coordinate - - - DoubleVector m_ftdInnerRadii; ///< List of ftd inner radii - DoubleVector m_ftdOuterRadii; ///< List of ftd outer radii - DoubleVector m_ftdZPositions; ///< List of ftd z positions - unsigned int m_nFtdLayers; ///< Number of ftd layers - float m_tanLambdaFtd; ///< Tan lambda for first ftd layer - - float m_minEtdZPosition; ///< Min etd z position - float m_minSetRadius; ///< Min set radius - - - - /** + //Detector-specific configuration variables + float m_cosTpc; ///< Cos(theta) value at end of tpc + float m_tpcInnerR; ///< The tpc inner radius + float m_tpcOuterR; ///< The tpc outer radius + unsigned int m_tpcMaxRow; ///< The tpc maximum row number + float m_tpcZmax; ///< The tpc maximum z coordinate + float m_tpcMembraneMaxZ; ///< Tpc membrane max z coordinate + + DoubleVector m_ftdInnerRadii; ///< List of ftd inner radii + DoubleVector m_ftdOuterRadii; ///< List of ftd outer radii + DoubleVector m_ftdZPositions; ///< List of ftd z positions + unsigned int m_nFtdLayers; ///< Number of ftd layers + float m_tanLambdaFtd; ///< Tan lambda for first ftd layer + + float m_minEtdZPosition; ///< Min etd z position + float m_minSetRadius; ///< Min set radius + + /** * @brief Whether track passes the quality cuts required in order to be used to form a pfo. Detector specific - * + * * @param pTrack the lcio track * @param trackParameters the track parameters - * + * * @return boolean */ - - virtual bool PassesQualityCuts(const EVENT::Track *const pTrack, const PandoraApi::Track::Parameters &trackParameters) const; - /** + + virtual bool PassesQualityCuts(const EVENT::Track* const pTrack, + const PandoraApi::Track::Parameters& trackParameters) const; + /** * @brief Get number of hits in TPC of a track - * + * * @param pTrack the lcio track - * + * * @return number of hits in TPC of a track */ - int GetNTpcHits(const EVENT::Track *const pTrack) const; + int GetNTpcHits(const EVENT::Track* const pTrack) const; - /** + /** * @brief Get number of hits in FTD of a track - * + * * @param pTrack the lcio track - * + * * @return number of hits in FTDof a track */ - int GetNFtdHits(const EVENT::Track *const pTrack) const; + int GetNFtdHits(const EVENT::Track* const pTrack) const; - /** + /** * @brief Decide whether track reaches the ecal surface. Detector specific - * + * * @param pTrack the lcio track * @param trackParameters the track parameters */ - virtual void TrackReachesECAL(const EVENT::Track *const pTrack, PandoraApi::Track::Parameters &trackParameters) const; - - /** + virtual void TrackReachesECAL(const EVENT::Track* const pTrack, PandoraApi::Track::Parameters& trackParameters) const; + + /** * @brief Determine whether a track can be used to form a pfo under the following conditions: * 1) if the track proves to be associated with a cluster, OR * 2) if the track proves to have no cluster associations * Detector specific - * + * * @param pTrack the lcio track * @param trackParameters the track parameters */ - virtual void DefineTrackPfoUsage(const EVENT::Track *const pTrack, PandoraApi::Track::Parameters &trackParameters) const; - + virtual void DefineTrackPfoUsage(const EVENT::Track* const pTrack, + PandoraApi::Track::Parameters& trackParameters) const; }; - - -#endif // #ifndef DDTRACK_CREATOR_ILD_H +#endif // #ifndef DDTRACK_CREATOR_ILD_H diff --git a/k4GaudiPandora/src/DDBFieldPlugin.cc b/k4GaudiPandora/src/DDBFieldPlugin.cc index eaaa15b..e054ffb 100644 --- a/k4GaudiPandora/src/DDBFieldPlugin.cc +++ b/k4GaudiPandora/src/DDBFieldPlugin.cc @@ -1,8 +1,27 @@ +/* + * Copyright (c) 2020-2024 Key4hep-Project. + * + * This file is part of Key4hep. + * See https://key4hep.github.io/key4hep-doc/ for further info. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + /** * @file DDMarlinPandora/src/DDBFieldPlugin.cc - * + * * @brief Implementation of the geometry creator class. - * + * * $Log: $ */ @@ -12,33 +31,29 @@ #include "DD4hep/DD4hepUnits.h" -DDBFieldPlugin::DDBFieldPlugin(const dd4hep::Detector &detector) : - m_field(detector.field()) -{ - /* nop */ +DDBFieldPlugin::DDBFieldPlugin(const dd4hep::Detector& detector) : m_field(detector.field()) { /* nop */ } //------------------------------------------------------------------------------------------------------------------------------------------ -float DDBFieldPlugin::GetBField(const pandora::CartesianVector &positionVector) const -{ - double bfield[3] = {0.}; - m_field.magneticField({positionVector.GetX()*dd4hep::mm, positionVector.GetY()*dd4hep::mm, positionVector.GetZ()*dd4hep::mm}, bfield); - return bfield[2]/dd4hep::tesla; +float DDBFieldPlugin::GetBField(const pandora::CartesianVector& positionVector) const { + double bfield[3] = {0.}; + m_field.magneticField( + {positionVector.GetX() * dd4hep::mm, positionVector.GetY() * dd4hep::mm, positionVector.GetZ() * dd4hep::mm}, + bfield); + return bfield[2] / dd4hep::tesla; } //------------------------------------------------------------------------------------------------------------------------------------------ -pandora::StatusCode DDBFieldPlugin::Initialize() -{ - /* nop */ - return pandora::STATUS_CODE_SUCCESS; +pandora::StatusCode DDBFieldPlugin::Initialize() { + /* nop */ + return pandora::STATUS_CODE_SUCCESS; } //------------------------------------------------------------------------------------------------------------------------------------------ -pandora::StatusCode DDBFieldPlugin::ReadSettings(const pandora::TiXmlHandle /*xmlHandle*/) -{ - /* nop */ - return pandora::STATUS_CODE_SUCCESS; +pandora::StatusCode DDBFieldPlugin::ReadSettings(const pandora::TiXmlHandle /*xmlHandle*/) { + /* nop */ + return pandora::STATUS_CODE_SUCCESS; } diff --git a/k4GaudiPandora/src/DDCaloDigi.cc b/k4GaudiPandora/src/DDCaloDigi.cc index 3c5f44e..36d8b8a 100644 --- a/k4GaudiPandora/src/DDCaloDigi.cc +++ b/k4GaudiPandora/src/DDCaloDigi.cc @@ -39,12 +39,11 @@ #include "DD4hep/DetType.h" #include "DD4hep/Factories.h" #include "DDRec/DetectorData.h" -#include "DDRec/DetectorData.h" #include "DDRec/MaterialManager.h" using namespace std; -using namespace dd4hep ; -using namespace DDSegmentation ; +using namespace dd4hep; +using namespace DDSegmentation; // protect against rounding errors // will not find caps smaller than this @@ -55,7 +54,8 @@ const float slop = 0.25; // (mm) DECLARE_COMPONENT(DDCaloDigi) DDCaloDigi::DDCaloDigi(const std::string& aName, ISvcLocator* aSvcLoc) - : MultiTransformer(aName, aSvcLoc, + : MultiTransformer( + aName, aSvcLoc, { KeyValues("SimCaloHitCollections", {"SimCalorimeterHitCollection1", "SimCalorimeterHitCollection2", "SimCalorimeterHitCollection3"}), diff --git a/k4GaudiPandora/src/DDCaloHitCreator.cc b/k4GaudiPandora/src/DDCaloHitCreator.cc index 61b0500..8e509b4 100644 --- a/k4GaudiPandora/src/DDCaloHitCreator.cc +++ b/k4GaudiPandora/src/DDCaloHitCreator.cc @@ -1,8 +1,27 @@ +/* + * Copyright (c) 2020-2024 Key4hep-Project. + * + * This file is part of Key4hep. + * See https://key4hep.github.io/key4hep-doc/ for further info. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + /** * @file DDMarlinPandora/src/DDCaloHitCreator.cc - * + * * @brief Implementation of the calo hit creator class. - * + * * $Log: $ */ @@ -13,11 +32,10 @@ #include "UTIL/CellIDDecoder.h" - #include #include -#include #include +#include #include #include @@ -26,845 +44,799 @@ //forward declarations. See in DDPandoraPFANewProcessor.cc // dd4hep::rec::LayeredCalorimeterData * getExtension(std::string detectorName); -dd4hep::rec::LayeredCalorimeterData * getExtension(unsigned int includeFlag, unsigned int excludeFlag=0); +dd4hep::rec::LayeredCalorimeterData* getExtension(unsigned int includeFlag, unsigned int excludeFlag = 0); // double getCoilOuterR(); ///FIXME: HANDLE PROBLEM WHEN EXTENSION IS MISSING -DDCaloHitCreator::DDCaloHitCreator(const Settings &settings, const pandora::Pandora *const pPandora) : - m_settings(settings), - m_pandora(*pPandora), - m_hCalBarrelLayerThickness(0.f), - m_hCalEndCapLayerThickness(0.f), - m_calorimeterHitVector(0), - m_volumeManager() -{ - - const std::vector& barrelLayers= getExtension(( dd4hep::DetType::CALORIMETER | dd4hep::DetType::HADRONIC | dd4hep::DetType::BARREL), ( dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD ))->layers; - - const std::vector& endcapLayers= getExtension(( dd4hep::DetType::CALORIMETER | dd4hep::DetType::HADRONIC | dd4hep::DetType::ENDCAP), ( dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD ))->layers; - - ///Take thicknesses from last layer (was like that before with gear) - m_hCalEndCapLayerThickness =(endcapLayers.back().inner_thickness+endcapLayers.back().outer_thickness)/dd4hep::mm; - m_hCalBarrelLayerThickness =(barrelLayers.back().inner_thickness+barrelLayers.back().outer_thickness)/dd4hep::mm; - - if ((m_hCalEndCapLayerThickness < std::numeric_limits::epsilon()) || (m_hCalBarrelLayerThickness < std::numeric_limits::epsilon())) - throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER); - - dd4hep::Detector& theDetector = dd4hep::Detector::getInstance(); - m_volumeManager = theDetector.volumeManager(); - if( not m_volumeManager.isValid() ){ - theDetector.apply("DD4hepVolumeManager",0,0); - m_volumeManager = theDetector.volumeManager(); - } - +DDCaloHitCreator::DDCaloHitCreator(const Settings& settings, const pandora::Pandora* const pPandora) + : m_settings(settings), + m_pandora(*pPandora), + m_hCalBarrelLayerThickness(0.f), + m_hCalEndCapLayerThickness(0.f), + m_calorimeterHitVector(0), + m_volumeManager() { + const std::vector& barrelLayers = + getExtension((dd4hep::DetType::CALORIMETER | dd4hep::DetType::HADRONIC | dd4hep::DetType::BARREL), + (dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD)) + ->layers; + + const std::vector& endcapLayers = + getExtension((dd4hep::DetType::CALORIMETER | dd4hep::DetType::HADRONIC | dd4hep::DetType::ENDCAP), + (dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD)) + ->layers; + + ///Take thicknesses from last layer (was like that before with gear) + m_hCalEndCapLayerThickness = (endcapLayers.back().inner_thickness + endcapLayers.back().outer_thickness) / dd4hep::mm; + m_hCalBarrelLayerThickness = (barrelLayers.back().inner_thickness + barrelLayers.back().outer_thickness) / dd4hep::mm; + + if ((m_hCalEndCapLayerThickness < std::numeric_limits::epsilon()) || + (m_hCalBarrelLayerThickness < std::numeric_limits::epsilon())) + throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER); + + dd4hep::Detector& theDetector = dd4hep::Detector::getInstance(); + m_volumeManager = theDetector.volumeManager(); + if (not m_volumeManager.isValid()) { + theDetector.apply("DD4hepVolumeManager", 0, 0); + m_volumeManager = theDetector.volumeManager(); + } } //------------------------------------------------------------------------------------------------------------------------------------------ -DDCaloHitCreator::~DDCaloHitCreator() -{ -} +DDCaloHitCreator::~DDCaloHitCreator() {} //------------------------------------------------------------------------------------------------------------------------------------------ -pandora::StatusCode DDCaloHitCreator::CreateCaloHits(const EVENT::LCEvent *const pLCEvent) -{ - - //fg: there cannot be any reasonable default for this string - so we set it to sth. that will cause an exception in case - // the cellID encoding string is not in the collection: +pandora::StatusCode DDCaloHitCreator::CreateCaloHits(const EVENT::LCEvent* const pLCEvent) { + //fg: there cannot be any reasonable default for this string - so we set it to sth. that will cause an exception in case + // the cellID encoding string is not in the collection: UTIL::CellIDDecoder::setDefaultEncoding("undefined_cellID_encoding:100"); - - PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, this->CreateECalCaloHits(pLCEvent)); - PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, this->CreateHCalCaloHits(pLCEvent)); - PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, this->CreateMuonCaloHits(pLCEvent)); - PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, this->CreateLCalCaloHits(pLCEvent)); - PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, this->CreateLHCalCaloHits(pLCEvent)); - - return pandora::STATUS_CODE_SUCCESS; + + PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, this->CreateECalCaloHits(pLCEvent)); + PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, this->CreateHCalCaloHits(pLCEvent)); + PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, this->CreateMuonCaloHits(pLCEvent)); + PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, this->CreateLCalCaloHits(pLCEvent)); + PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, this->CreateLHCalCaloHits(pLCEvent)); + + return pandora::STATUS_CODE_SUCCESS; } //------------------------------------------------------------------------------------------------------------------------------------------ -pandora::StatusCode DDCaloHitCreator::CreateECalCaloHits(const EVENT::LCEvent *const pLCEvent) -{ - for (StringVector::const_iterator iter = m_settings.m_eCalCaloHitCollections.begin(), iterEnd = m_settings.m_eCalCaloHitCollections.end(); - iter != iterEnd; ++iter) - { - try - { - const EVENT::LCCollection *pCaloHitCollection = pLCEvent->getCollection(*iter); - const int nElements(pCaloHitCollection->getNumberOfElements()); - - if (0 == nElements) - continue; - - streamlog_out( DEBUG1 ) << "Creating " << *iter << " hits" << std::endl; - - const std::vector& barrelLayers= getExtension( ( dd4hep::DetType::CALORIMETER | dd4hep::DetType::ELECTROMAGNETIC | dd4hep::DetType::BARREL), ( dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD ) )->layers; - const std::vector& endcapLayers= getExtension( ( dd4hep::DetType::CALORIMETER | dd4hep::DetType::ELECTROMAGNETIC | dd4hep::DetType::ENDCAP), ( dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD ) )->layers; - - - UTIL::CellIDDecoder cellIdDecoder(pCaloHitCollection); - const std::string layerCodingString(pCaloHitCollection->getParameters().getStringVal(LCIO::CellIDEncoding)); - std::string layerCoding("layer"); - - for (int i = 0; i < nElements; ++i) - { - try - { - EVENT::CalorimeterHit *pCaloHit = dynamic_cast(pCaloHitCollection->getElementAt(i)); - - if (NULL == pCaloHit) - throw EVENT::Exception("Collection type mismatch"); - - float eCalToMip(m_settings.m_eCalToMip), eCalMipThreshold(m_settings.m_eCalMipThreshold), eCalToEMGeV(m_settings.m_eCalToEMGeV), - eCalToHadGeVBarrel(m_settings.m_eCalToHadGeVBarrel), eCalToHadGeVEndCap(m_settings.m_eCalToHadGeVEndCap); - - // Hybrid ECAL including pure ScECAL. - if (m_settings.m_useEcalScLayers) - { - std::string collectionName(*iter); - std::transform(collectionName.begin(), collectionName.end(), collectionName.begin(), ::tolower); - layerCoding = "layer"; - - if (collectionName.find("ecal", 0) == std::string::npos) - streamlog_out(MESSAGE) << "WARNING: mismatching hybrid Ecal collection name. " << collectionName << std::endl; - - if (collectionName.find("si", 0) != std::string::npos) - { - eCalToMip = m_settings.m_eCalSiToMip; - eCalMipThreshold = m_settings.m_eCalSiMipThreshold; - eCalToEMGeV = m_settings.m_eCalSiToEMGeV; - eCalToHadGeVBarrel = m_settings.m_eCalSiToHadGeVBarrel; - eCalToHadGeVEndCap = m_settings.m_eCalSiToHadGeVEndCap; - } - else if (collectionName.find("sc", 0) != std::string::npos) - { - eCalToMip = m_settings.m_eCalScToMip; - eCalMipThreshold = m_settings.m_eCalScMipThreshold; - eCalToEMGeV = m_settings.m_eCalScToEMGeV; - eCalToHadGeVBarrel = m_settings.m_eCalScToHadGeVBarrel; - eCalToHadGeVEndCap = m_settings.m_eCalScToHadGeVEndCap; - } - } - - PandoraApi::CaloHit::Parameters caloHitParameters; - caloHitParameters.m_hitType = pandora::ECAL; - caloHitParameters.m_isDigital = false; - caloHitParameters.m_layer = cellIdDecoder(pCaloHit)[layerCoding.c_str()]; - caloHitParameters.m_isInOuterSamplingLayer = false; - this->GetCommonCaloHitProperties(pCaloHit, caloHitParameters); - - float absorberCorrection(1.); - - //FIXME: Why is this used to get barrel or endcap??? use SystemID if available - if (std::fabs(pCaloHit->getPosition()[2]) < m_settings.m_eCalBarrelOuterZ) - { - - streamlog_out( DEBUG6 ) << "IDS " << *iter - << std::setw(15) << pCaloHit->getCellID0() - << std::setw(15) << pCaloHit->getPosition()[0] - << std::setw(15) << pCaloHit->getPosition()[1] - << std::setw(15) << pCaloHit->getPosition()[2] - << std::setw(5) << cellIdDecoder(pCaloHit)["system"] - << std::setw(5) << cellIdDecoder(pCaloHit)["module"] - << std::setw(5) << cellIdDecoder(pCaloHit)["stave"] - << std::setw(5) << cellIdDecoder(pCaloHit)["layer"] - << std::setw(5) << cellIdDecoder(pCaloHit)["x"] - << std::setw(5) << cellIdDecoder(pCaloHit)["y"] - << std::endl; - - this->GetBarrelCaloHitProperties(pCaloHit, barrelLayers, m_settings.m_eCalBarrelInnerSymmetry, caloHitParameters, m_settings.m_eCalBarrelNormalVector, absorberCorrection); - - caloHitParameters.m_hadronicEnergy = eCalToHadGeVBarrel * pCaloHit->getEnergy(); - } - else - { - this->GetEndCapCaloHitProperties(pCaloHit, endcapLayers, caloHitParameters, absorberCorrection); - caloHitParameters.m_hadronicEnergy = eCalToHadGeVEndCap * pCaloHit->getEnergy(); - } - - caloHitParameters.m_mipEquivalentEnergy = pCaloHit->getEnergy() * eCalToMip * absorberCorrection; - - if (caloHitParameters.m_mipEquivalentEnergy.Get() < eCalMipThreshold) - continue; - - caloHitParameters.m_electromagneticEnergy = eCalToEMGeV * pCaloHit->getEnergy(); - - // ATTN If using strip splitting, must correct cell sizes for use in PFA to minimum of strip width and strip length - if (m_settings.m_stripSplittingOn) - { - const float splitCellSize(std::min(caloHitParameters.m_cellSize0.Get(), caloHitParameters.m_cellSize1.Get())); - caloHitParameters.m_cellSize0 = splitCellSize; - caloHitParameters.m_cellSize1 = splitCellSize; - } - - PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::CaloHit::Create(m_pandora, caloHitParameters)); - m_calorimeterHitVector.push_back(pCaloHit); - - } - catch (pandora::StatusCodeException &statusCodeException) - { - streamlog_out(ERROR) << "Failed to extract ecal calo hit from " - << *iter << ": " - << statusCodeException.ToString() << std::endl; - } - catch (EVENT::Exception &exception) - { - streamlog_out(WARNING) << "Failed to extract ecal calo hit from " - << *iter << ": " - << exception.what() << std::endl; - } +pandora::StatusCode DDCaloHitCreator::CreateECalCaloHits(const EVENT::LCEvent* const pLCEvent) { + for (StringVector::const_iterator iter = m_settings.m_eCalCaloHitCollections.begin(), + iterEnd = m_settings.m_eCalCaloHitCollections.end(); + iter != iterEnd; ++iter) { + try { + const EVENT::LCCollection* pCaloHitCollection = pLCEvent->getCollection(*iter); + const int nElements(pCaloHitCollection->getNumberOfElements()); + + if (0 == nElements) + continue; + + streamlog_out(DEBUG1) << "Creating " << *iter << " hits" << std::endl; + + const std::vector& barrelLayers = + getExtension((dd4hep::DetType::CALORIMETER | dd4hep::DetType::ELECTROMAGNETIC | dd4hep::DetType::BARREL), + (dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD)) + ->layers; + const std::vector& endcapLayers = + getExtension((dd4hep::DetType::CALORIMETER | dd4hep::DetType::ELECTROMAGNETIC | dd4hep::DetType::ENDCAP), + (dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD)) + ->layers; + + UTIL::CellIDDecoder cellIdDecoder(pCaloHitCollection); + const std::string layerCodingString(pCaloHitCollection->getParameters().getStringVal(LCIO::CellIDEncoding)); + std::string layerCoding("layer"); + + for (int i = 0; i < nElements; ++i) { + try { + EVENT::CalorimeterHit* pCaloHit = dynamic_cast(pCaloHitCollection->getElementAt(i)); + + if (NULL == pCaloHit) + throw EVENT::Exception("Collection type mismatch"); + + float eCalToMip(m_settings.m_eCalToMip), eCalMipThreshold(m_settings.m_eCalMipThreshold), + eCalToEMGeV(m_settings.m_eCalToEMGeV), eCalToHadGeVBarrel(m_settings.m_eCalToHadGeVBarrel), + eCalToHadGeVEndCap(m_settings.m_eCalToHadGeVEndCap); + + // Hybrid ECAL including pure ScECAL. + if (m_settings.m_useEcalScLayers) { + std::string collectionName(*iter); + std::transform(collectionName.begin(), collectionName.end(), collectionName.begin(), ::tolower); + layerCoding = "layer"; + + if (collectionName.find("ecal", 0) == std::string::npos) + streamlog_out(MESSAGE) << "WARNING: mismatching hybrid Ecal collection name. " << collectionName + << std::endl; + + if (collectionName.find("si", 0) != std::string::npos) { + eCalToMip = m_settings.m_eCalSiToMip; + eCalMipThreshold = m_settings.m_eCalSiMipThreshold; + eCalToEMGeV = m_settings.m_eCalSiToEMGeV; + eCalToHadGeVBarrel = m_settings.m_eCalSiToHadGeVBarrel; + eCalToHadGeVEndCap = m_settings.m_eCalSiToHadGeVEndCap; + } else if (collectionName.find("sc", 0) != std::string::npos) { + eCalToMip = m_settings.m_eCalScToMip; + eCalMipThreshold = m_settings.m_eCalScMipThreshold; + eCalToEMGeV = m_settings.m_eCalScToEMGeV; + eCalToHadGeVBarrel = m_settings.m_eCalScToHadGeVBarrel; + eCalToHadGeVEndCap = m_settings.m_eCalScToHadGeVEndCap; } + } + + PandoraApi::CaloHit::Parameters caloHitParameters; + caloHitParameters.m_hitType = pandora::ECAL; + caloHitParameters.m_isDigital = false; + caloHitParameters.m_layer = cellIdDecoder(pCaloHit)[layerCoding.c_str()]; + caloHitParameters.m_isInOuterSamplingLayer = false; + this->GetCommonCaloHitProperties(pCaloHit, caloHitParameters); + + float absorberCorrection(1.); + + //FIXME: Why is this used to get barrel or endcap??? use SystemID if available + if (std::fabs(pCaloHit->getPosition()[2]) < m_settings.m_eCalBarrelOuterZ) { + streamlog_out(DEBUG6) << "IDS " << *iter << std::setw(15) << pCaloHit->getCellID0() << std::setw(15) + << pCaloHit->getPosition()[0] << std::setw(15) << pCaloHit->getPosition()[1] + << std::setw(15) << pCaloHit->getPosition()[2] << std::setw(5) + << cellIdDecoder(pCaloHit)["system"] << std::setw(5) + << cellIdDecoder(pCaloHit)["module"] << std::setw(5) + << cellIdDecoder(pCaloHit)["stave"] << std::setw(5) + << cellIdDecoder(pCaloHit)["layer"] << std::setw(5) << cellIdDecoder(pCaloHit)["x"] + << std::setw(5) << cellIdDecoder(pCaloHit)["y"] << std::endl; + + this->GetBarrelCaloHitProperties(pCaloHit, barrelLayers, m_settings.m_eCalBarrelInnerSymmetry, + caloHitParameters, m_settings.m_eCalBarrelNormalVector, + absorberCorrection); + + caloHitParameters.m_hadronicEnergy = eCalToHadGeVBarrel * pCaloHit->getEnergy(); + } else { + this->GetEndCapCaloHitProperties(pCaloHit, endcapLayers, caloHitParameters, absorberCorrection); + caloHitParameters.m_hadronicEnergy = eCalToHadGeVEndCap * pCaloHit->getEnergy(); + } + + caloHitParameters.m_mipEquivalentEnergy = pCaloHit->getEnergy() * eCalToMip * absorberCorrection; + + if (caloHitParameters.m_mipEquivalentEnergy.Get() < eCalMipThreshold) + continue; + + caloHitParameters.m_electromagneticEnergy = eCalToEMGeV * pCaloHit->getEnergy(); + + // ATTN If using strip splitting, must correct cell sizes for use in PFA to minimum of strip width and strip length + if (m_settings.m_stripSplittingOn) { + const float splitCellSize( + std::min(caloHitParameters.m_cellSize0.Get(), caloHitParameters.m_cellSize1.Get())); + caloHitParameters.m_cellSize0 = splitCellSize; + caloHitParameters.m_cellSize1 = splitCellSize; + } + + PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, + PandoraApi::CaloHit::Create(m_pandora, caloHitParameters)); + m_calorimeterHitVector.push_back(pCaloHit); + + } catch (pandora::StatusCodeException& statusCodeException) { + streamlog_out(ERROR) << "Failed to extract ecal calo hit from " << *iter << ": " + << statusCodeException.ToString() << std::endl; + } catch (EVENT::Exception& exception) { + streamlog_out(WARNING) << "Failed to extract ecal calo hit from " << *iter << ": " << exception.what() + << std::endl; } - catch (EVENT::Exception &exception) - { - streamlog_out(MESSAGE) << "Failed to extract ecal calo hit collection: " << *iter << ", " << exception.what() << std::endl; - } + } + } catch (EVENT::Exception& exception) { + streamlog_out(MESSAGE) << "Failed to extract ecal calo hit collection: " << *iter << ", " << exception.what() + << std::endl; } + } - return pandora::STATUS_CODE_SUCCESS; + return pandora::STATUS_CODE_SUCCESS; } //------------------------------------------------------------------------------------------------------------------------------------------ -pandora::StatusCode DDCaloHitCreator::CreateHCalCaloHits(const EVENT::LCEvent *const pLCEvent) -{ - for (StringVector::const_iterator iter = m_settings.m_hCalCaloHitCollections.begin(), iterEnd = m_settings.m_hCalCaloHitCollections.end(); - iter != iterEnd; ++iter) - { - try - { - const EVENT::LCCollection *pCaloHitCollection = pLCEvent->getCollection(*iter); - const int nElements(pCaloHitCollection->getNumberOfElements()); - UTIL::CellIDDecoder cellIdDecoder(pCaloHitCollection); - - if (0 == nElements) - continue; - - streamlog_out( DEBUG1 ) << "Creating " << *iter << " hits" << std::endl; - - const std::vector& barrelLayers= getExtension( ( dd4hep::DetType::CALORIMETER | dd4hep::DetType::HADRONIC | dd4hep::DetType::BARREL), ( dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD ) )->layers; - const std::vector& endcapLayers= getExtension( ( dd4hep::DetType::CALORIMETER | dd4hep::DetType::HADRONIC| dd4hep::DetType::ENDCAP), ( dd4hep::DetType::AUXILIARY ) | dd4hep::DetType::FORWARD )->layers; - - - - const std::string layerCoding("layer"); - - for (int i = 0; i < nElements; ++i) - { - try - { - EVENT::CalorimeterHit *pCaloHit = dynamic_cast(pCaloHitCollection->getElementAt(i)); - - if (NULL == pCaloHit) - throw EVENT::Exception("Collection type mismatch"); - - PandoraApi::CaloHit::Parameters caloHitParameters; - caloHitParameters.m_hitType = pandora::HCAL; - caloHitParameters.m_isDigital = false; - caloHitParameters.m_layer = cellIdDecoder(pCaloHit)[layerCoding.c_str()]; - caloHitParameters.m_isInOuterSamplingLayer = (this->GetNLayersFromEdge(pCaloHit) <= m_settings.m_nOuterSamplingLayers); - this->GetCommonCaloHitProperties(pCaloHit, caloHitParameters); - - float absorberCorrection(1.); - - if (std::fabs(pCaloHit->getPosition()[2]) < m_settings.m_hCalBarrelOuterZ) - { - - this->GetBarrelCaloHitProperties(pCaloHit, barrelLayers, m_settings.m_hCalBarrelInnerSymmetry, caloHitParameters, m_settings.m_hCalBarrelNormalVector, absorberCorrection); - } - else - { - this->GetEndCapCaloHitProperties(pCaloHit, endcapLayers, caloHitParameters, absorberCorrection); - } - - caloHitParameters.m_mipEquivalentEnergy = pCaloHit->getEnergy() * m_settings.m_hCalToMip * absorberCorrection; - - if (caloHitParameters.m_mipEquivalentEnergy.Get() < m_settings.m_hCalMipThreshold) - continue; - - caloHitParameters.m_hadronicEnergy = std::min(m_settings.m_hCalToHadGeV * pCaloHit->getEnergy(), m_settings.m_maxHCalHitHadronicEnergy); - caloHitParameters.m_electromagneticEnergy = m_settings.m_hCalToEMGeV * pCaloHit->getEnergy(); - - PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::CaloHit::Create(m_pandora, caloHitParameters)); - m_calorimeterHitVector.push_back(pCaloHit); - } - catch (pandora::StatusCodeException &statusCodeException) - { - streamlog_out(ERROR) << "Failed to extract hcal calo hit: " << statusCodeException.ToString() << std::endl; - } - catch (EVENT::Exception &exception) - { - streamlog_out(WARNING) << "Failed to extract hcal calo hit: " << exception.what() << std::endl; - } - } - } - catch (EVENT::Exception &exception) - { - streamlog_out(MESSAGE) << "Failed to extract hcal calo hit collection: " << *iter << ", " << exception.what() << std::endl; +pandora::StatusCode DDCaloHitCreator::CreateHCalCaloHits(const EVENT::LCEvent* const pLCEvent) { + for (StringVector::const_iterator iter = m_settings.m_hCalCaloHitCollections.begin(), + iterEnd = m_settings.m_hCalCaloHitCollections.end(); + iter != iterEnd; ++iter) { + try { + const EVENT::LCCollection* pCaloHitCollection = pLCEvent->getCollection(*iter); + const int nElements(pCaloHitCollection->getNumberOfElements()); + UTIL::CellIDDecoder cellIdDecoder(pCaloHitCollection); + + if (0 == nElements) + continue; + + streamlog_out(DEBUG1) << "Creating " << *iter << " hits" << std::endl; + + const std::vector& barrelLayers = + getExtension((dd4hep::DetType::CALORIMETER | dd4hep::DetType::HADRONIC | dd4hep::DetType::BARREL), + (dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD)) + ->layers; + const std::vector& endcapLayers = + getExtension((dd4hep::DetType::CALORIMETER | dd4hep::DetType::HADRONIC | dd4hep::DetType::ENDCAP), + (dd4hep::DetType::AUXILIARY) | dd4hep::DetType::FORWARD) + ->layers; + + const std::string layerCoding("layer"); + + for (int i = 0; i < nElements; ++i) { + try { + EVENT::CalorimeterHit* pCaloHit = dynamic_cast(pCaloHitCollection->getElementAt(i)); + + if (NULL == pCaloHit) + throw EVENT::Exception("Collection type mismatch"); + + PandoraApi::CaloHit::Parameters caloHitParameters; + caloHitParameters.m_hitType = pandora::HCAL; + caloHitParameters.m_isDigital = false; + caloHitParameters.m_layer = cellIdDecoder(pCaloHit)[layerCoding.c_str()]; + caloHitParameters.m_isInOuterSamplingLayer = + (this->GetNLayersFromEdge(pCaloHit) <= m_settings.m_nOuterSamplingLayers); + this->GetCommonCaloHitProperties(pCaloHit, caloHitParameters); + + float absorberCorrection(1.); + + if (std::fabs(pCaloHit->getPosition()[2]) < m_settings.m_hCalBarrelOuterZ) { + this->GetBarrelCaloHitProperties(pCaloHit, barrelLayers, m_settings.m_hCalBarrelInnerSymmetry, + caloHitParameters, m_settings.m_hCalBarrelNormalVector, + absorberCorrection); + } else { + this->GetEndCapCaloHitProperties(pCaloHit, endcapLayers, caloHitParameters, absorberCorrection); + } + + caloHitParameters.m_mipEquivalentEnergy = pCaloHit->getEnergy() * m_settings.m_hCalToMip * absorberCorrection; + + if (caloHitParameters.m_mipEquivalentEnergy.Get() < m_settings.m_hCalMipThreshold) + continue; + + caloHitParameters.m_hadronicEnergy = + std::min(m_settings.m_hCalToHadGeV * pCaloHit->getEnergy(), m_settings.m_maxHCalHitHadronicEnergy); + caloHitParameters.m_electromagneticEnergy = m_settings.m_hCalToEMGeV * pCaloHit->getEnergy(); + + PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, + PandoraApi::CaloHit::Create(m_pandora, caloHitParameters)); + m_calorimeterHitVector.push_back(pCaloHit); + } catch (pandora::StatusCodeException& statusCodeException) { + streamlog_out(ERROR) << "Failed to extract hcal calo hit: " << statusCodeException.ToString() << std::endl; + } catch (EVENT::Exception& exception) { + streamlog_out(WARNING) << "Failed to extract hcal calo hit: " << exception.what() << std::endl; } + } + } catch (EVENT::Exception& exception) { + streamlog_out(MESSAGE) << "Failed to extract hcal calo hit collection: " << *iter << ", " << exception.what() + << std::endl; } + } - return pandora::STATUS_CODE_SUCCESS; + return pandora::STATUS_CODE_SUCCESS; } //------------------------------------------------------------------------------------------------------------------------------------------ -pandora::StatusCode DDCaloHitCreator::CreateMuonCaloHits(const EVENT::LCEvent *const pLCEvent) -{ - for (StringVector::const_iterator iter = m_settings.m_muonCaloHitCollections.begin(), iterEnd = m_settings.m_muonCaloHitCollections.end(); - iter != iterEnd; ++iter) - { - try - { - const EVENT::LCCollection *pCaloHitCollection = pLCEvent->getCollection(*iter); - const int nElements(pCaloHitCollection->getNumberOfElements()); - - if (0 == nElements) - continue; - - streamlog_out( DEBUG1 ) << "Creating " << *iter << " hits" << std::endl; - - const std::vector& barrelLayers= getExtension(( dd4hep::DetType::CALORIMETER | dd4hep::DetType::MUON| dd4hep::DetType::BARREL), ( dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD ))->layers; - const std::vector& endcapLayers= getExtension(( dd4hep::DetType::CALORIMETER | dd4hep::DetType::MUON| dd4hep::DetType::ENDCAP), ( dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD ))->layers; - ///FIXME: WHAT ABOUT MORE MUON SYSTEMS? - // const std::vector& plugLayers= getExtension(( dd4hep::DetType::CALORIMETER | dd4hep::DetType::HADRONIC | dd4hep::DetType::AUXILIARY ))->layers; - UTIL::CellIDDecoder cellIdDecoder(pCaloHitCollection); - const std::string layerCodingString(pCaloHitCollection->getParameters().getStringVal(LCIO::CellIDEncoding)); - const std::string layerCoding("layer"); - - for (int i = 0; i < nElements; ++i) - { - try - { - EVENT::CalorimeterHit *pCaloHit = dynamic_cast(pCaloHitCollection->getElementAt(i)); - - if (NULL == pCaloHit) - throw EVENT::Exception("Collection type mismatch"); - - PandoraApi::CaloHit::Parameters caloHitParameters; - caloHitParameters.m_hitType = pandora::MUON; - caloHitParameters.m_layer = cellIdDecoder(pCaloHit)[layerCoding.c_str()]; - caloHitParameters.m_isInOuterSamplingLayer = true; - this->GetCommonCaloHitProperties(pCaloHit, caloHitParameters); - - const float radius(std::sqrt(pCaloHit->getPosition()[0] * pCaloHit->getPosition()[0] + - pCaloHit->getPosition()[1] * pCaloHit->getPosition()[1])); - - const bool isWithinCoil(radius < m_settings.m_coilOuterR); - const bool isInBarrelRegion(std::fabs(pCaloHit->getPosition()[2]) < m_settings.m_muonBarrelOuterZ); - - float absorberCorrection(1.); - - if (isInBarrelRegion && isWithinCoil) - { - std::cout<<"BIG WARNING: CANNOT HANDLE PLUG HITS (no plug in CLIC model), DO NOTHING!"<GetEndCapCaloHitProperties(pCaloHit, plugLayers, caloHitParameters, absorberCorrection); - } - else if (isInBarrelRegion) - { - - this->GetBarrelCaloHitProperties(pCaloHit, barrelLayers, m_settings.m_muonBarrelInnerSymmetry, caloHitParameters, m_settings.m_muonBarrelNormalVector, absorberCorrection); - } - else - { - this->GetEndCapCaloHitProperties(pCaloHit, endcapLayers, caloHitParameters, absorberCorrection); - } - - if (m_settings.m_muonDigitalHits > 0) - { - caloHitParameters.m_isDigital = true; - caloHitParameters.m_inputEnergy = m_settings.m_muonHitEnergy; - caloHitParameters.m_hadronicEnergy = m_settings.m_muonHitEnergy; - caloHitParameters.m_electromagneticEnergy = m_settings.m_muonHitEnergy; - caloHitParameters.m_mipEquivalentEnergy = 1.f; - } - else - { - caloHitParameters.m_isDigital = false; - caloHitParameters.m_inputEnergy = pCaloHit->getEnergy(); - caloHitParameters.m_hadronicEnergy = pCaloHit->getEnergy(); - caloHitParameters.m_electromagneticEnergy = pCaloHit->getEnergy(); - caloHitParameters.m_mipEquivalentEnergy = pCaloHit->getEnergy() * m_settings.m_muonToMip; - } - - PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::CaloHit::Create(m_pandora, caloHitParameters)); - m_calorimeterHitVector.push_back(pCaloHit); - } - catch (pandora::StatusCodeException &statusCodeException) - { - streamlog_out(ERROR) << "Failed to extract muon hit: " << statusCodeException.ToString() << std::endl; - } - catch (EVENT::Exception &exception) - { - streamlog_out(WARNING) << "Failed to extract muon hit: " << exception.what() << std::endl; - } - } - } - catch (EVENT::Exception &exception) - { - streamlog_out(MESSAGE) << "Failed to extract muon hit collection: " << *iter << ", " << exception.what() << std::endl; +pandora::StatusCode DDCaloHitCreator::CreateMuonCaloHits(const EVENT::LCEvent* const pLCEvent) { + for (StringVector::const_iterator iter = m_settings.m_muonCaloHitCollections.begin(), + iterEnd = m_settings.m_muonCaloHitCollections.end(); + iter != iterEnd; ++iter) { + try { + const EVENT::LCCollection* pCaloHitCollection = pLCEvent->getCollection(*iter); + const int nElements(pCaloHitCollection->getNumberOfElements()); + + if (0 == nElements) + continue; + + streamlog_out(DEBUG1) << "Creating " << *iter << " hits" << std::endl; + + const std::vector& barrelLayers = + getExtension((dd4hep::DetType::CALORIMETER | dd4hep::DetType::MUON | dd4hep::DetType::BARREL), + (dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD)) + ->layers; + const std::vector& endcapLayers = + getExtension((dd4hep::DetType::CALORIMETER | dd4hep::DetType::MUON | dd4hep::DetType::ENDCAP), + (dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD)) + ->layers; + ///FIXME: WHAT ABOUT MORE MUON SYSTEMS? + // const std::vector& plugLayers= getExtension(( dd4hep::DetType::CALORIMETER | dd4hep::DetType::HADRONIC | dd4hep::DetType::AUXILIARY ))->layers; + UTIL::CellIDDecoder cellIdDecoder(pCaloHitCollection); + const std::string layerCodingString(pCaloHitCollection->getParameters().getStringVal(LCIO::CellIDEncoding)); + const std::string layerCoding("layer"); + + for (int i = 0; i < nElements; ++i) { + try { + EVENT::CalorimeterHit* pCaloHit = dynamic_cast(pCaloHitCollection->getElementAt(i)); + + if (NULL == pCaloHit) + throw EVENT::Exception("Collection type mismatch"); + + PandoraApi::CaloHit::Parameters caloHitParameters; + caloHitParameters.m_hitType = pandora::MUON; + caloHitParameters.m_layer = cellIdDecoder(pCaloHit)[layerCoding.c_str()]; + caloHitParameters.m_isInOuterSamplingLayer = true; + this->GetCommonCaloHitProperties(pCaloHit, caloHitParameters); + + const float radius(std::sqrt(pCaloHit->getPosition()[0] * pCaloHit->getPosition()[0] + + pCaloHit->getPosition()[1] * pCaloHit->getPosition()[1])); + + const bool isWithinCoil(radius < m_settings.m_coilOuterR); + const bool isInBarrelRegion(std::fabs(pCaloHit->getPosition()[2]) < m_settings.m_muonBarrelOuterZ); + + float absorberCorrection(1.); + + if (isInBarrelRegion && isWithinCoil) { + std::cout << "BIG WARNING: CANNOT HANDLE PLUG HITS (no plug in CLIC model), DO NOTHING!" << std::endl; + // this->GetEndCapCaloHitProperties(pCaloHit, plugLayers, caloHitParameters, absorberCorrection); + } else if (isInBarrelRegion) { + this->GetBarrelCaloHitProperties(pCaloHit, barrelLayers, m_settings.m_muonBarrelInnerSymmetry, + caloHitParameters, m_settings.m_muonBarrelNormalVector, + absorberCorrection); + } else { + this->GetEndCapCaloHitProperties(pCaloHit, endcapLayers, caloHitParameters, absorberCorrection); + } + + if (m_settings.m_muonDigitalHits > 0) { + caloHitParameters.m_isDigital = true; + caloHitParameters.m_inputEnergy = m_settings.m_muonHitEnergy; + caloHitParameters.m_hadronicEnergy = m_settings.m_muonHitEnergy; + caloHitParameters.m_electromagneticEnergy = m_settings.m_muonHitEnergy; + caloHitParameters.m_mipEquivalentEnergy = 1.f; + } else { + caloHitParameters.m_isDigital = false; + caloHitParameters.m_inputEnergy = pCaloHit->getEnergy(); + caloHitParameters.m_hadronicEnergy = pCaloHit->getEnergy(); + caloHitParameters.m_electromagneticEnergy = pCaloHit->getEnergy(); + caloHitParameters.m_mipEquivalentEnergy = pCaloHit->getEnergy() * m_settings.m_muonToMip; + } + + PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, + PandoraApi::CaloHit::Create(m_pandora, caloHitParameters)); + m_calorimeterHitVector.push_back(pCaloHit); + } catch (pandora::StatusCodeException& statusCodeException) { + streamlog_out(ERROR) << "Failed to extract muon hit: " << statusCodeException.ToString() << std::endl; + } catch (EVENT::Exception& exception) { + streamlog_out(WARNING) << "Failed to extract muon hit: " << exception.what() << std::endl; } + } + } catch (EVENT::Exception& exception) { + streamlog_out(MESSAGE) << "Failed to extract muon hit collection: " << *iter << ", " << exception.what() + << std::endl; } + } - return pandora::STATUS_CODE_SUCCESS; + return pandora::STATUS_CODE_SUCCESS; } //------------------------------------------------------------------------------------------------------------------------------------------ -pandora::StatusCode DDCaloHitCreator::CreateLCalCaloHits(const EVENT::LCEvent *const pLCEvent) -{ - for (StringVector::const_iterator iter = m_settings.m_lCalCaloHitCollections.begin(), iterEnd = m_settings.m_lCalCaloHitCollections.end(); - iter != iterEnd; ++iter) - { - try - { - const EVENT::LCCollection *pCaloHitCollection = pLCEvent->getCollection(*iter); - const int nElements(pCaloHitCollection->getNumberOfElements()); - - if (0 == nElements) - continue; - - streamlog_out( DEBUG1 ) << "Creating " << *iter << " hits" << std::endl; - - ///FIXME: WHAT ABOUT OTHER ECALS? - const std::vector& endcapLayers= getExtension( dd4hep::DetType::CALORIMETER | dd4hep::DetType::ENDCAP | dd4hep::DetType::ELECTROMAGNETIC | dd4hep::DetType::FORWARD , dd4hep::DetType::AUXILIARY )->layers; - - - UTIL::CellIDDecoder cellIdDecoder(pCaloHitCollection); - const std::string layerCodingString(pCaloHitCollection->getParameters().getStringVal(LCIO::CellIDEncoding)); - const std::string layerCoding("layer"); - - for (int i = 0; i < nElements; ++i) - { - try - { - EVENT::CalorimeterHit *pCaloHit = dynamic_cast(pCaloHitCollection->getElementAt(i)); - - if (NULL == pCaloHit) - throw EVENT::Exception("Collection type mismatch"); - - PandoraApi::CaloHit::Parameters caloHitParameters; - caloHitParameters.m_hitType = pandora::ECAL; - caloHitParameters.m_isDigital = false; - caloHitParameters.m_layer = cellIdDecoder(pCaloHit)[layerCoding.c_str()]; - caloHitParameters.m_isInOuterSamplingLayer = false; - this->GetCommonCaloHitProperties(pCaloHit, caloHitParameters); - - float absorberCorrection(1.); - this->GetEndCapCaloHitProperties(pCaloHit, endcapLayers, caloHitParameters, absorberCorrection); - - caloHitParameters.m_mipEquivalentEnergy = pCaloHit->getEnergy() * m_settings.m_eCalToMip * absorberCorrection; - - if (caloHitParameters.m_mipEquivalentEnergy.Get() < m_settings.m_eCalMipThreshold) - continue; - - caloHitParameters.m_electromagneticEnergy = m_settings.m_eCalToEMGeV * pCaloHit->getEnergy(); - caloHitParameters.m_hadronicEnergy = m_settings.m_eCalToHadGeVEndCap * pCaloHit->getEnergy(); - - PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::CaloHit::Create(m_pandora, caloHitParameters)); - m_calorimeterHitVector.push_back(pCaloHit); - } - catch (pandora::StatusCodeException &statusCodeException) - { - streamlog_out(ERROR) << "Failed to extract lcal calo hit: " << statusCodeException.ToString() << std::endl; - } - catch (EVENT::Exception &exception) - { - streamlog_out(WARNING) << "Failed to extract lcal calo hit: " << exception.what() << std::endl; - } - } - } - catch (EVENT::Exception &exception) - { - streamlog_out(MESSAGE) << "Failed to extract lcal calo hit collection: " << *iter << ", " << exception.what() << std::endl; - } - } +pandora::StatusCode DDCaloHitCreator::CreateLCalCaloHits(const EVENT::LCEvent* const pLCEvent) { + for (StringVector::const_iterator iter = m_settings.m_lCalCaloHitCollections.begin(), + iterEnd = m_settings.m_lCalCaloHitCollections.end(); + iter != iterEnd; ++iter) { + try { + const EVENT::LCCollection* pCaloHitCollection = pLCEvent->getCollection(*iter); + const int nElements(pCaloHitCollection->getNumberOfElements()); - return pandora::STATUS_CODE_SUCCESS; -} + if (0 == nElements) + continue; -//------------------------------------------------------------------------------------------------------------------------------------------ + streamlog_out(DEBUG1) << "Creating " << *iter << " hits" << std::endl; -pandora::StatusCode DDCaloHitCreator::CreateLHCalCaloHits(const EVENT::LCEvent *const pLCEvent) -{ - for (StringVector::const_iterator iter = m_settings.m_lHCalCaloHitCollections.begin(), iterEnd = m_settings.m_lHCalCaloHitCollections.end(); - iter != iterEnd; ++iter) - { - try - { - const EVENT::LCCollection *pCaloHitCollection = pLCEvent->getCollection(*iter); - const int nElements(pCaloHitCollection->getNumberOfElements()); - - if (0 == nElements) - continue; - - streamlog_out( DEBUG1 ) << "Creating " << *iter << " hits" << std::endl; - - ///FIXME! WHAT ABOUT MORE HCALS? - const std::vector& endcapLayers= getExtension(dd4hep::DetType::CALORIMETER | dd4hep::DetType::ENDCAP | dd4hep::DetType::HADRONIC| dd4hep::DetType::FORWARD)->layers; - - UTIL::CellIDDecoder cellIdDecoder(pCaloHitCollection); - const std::string layerCodingString(pCaloHitCollection->getParameters().getStringVal(LCIO::CellIDEncoding)); - const std::string layerCoding("layer"); - - for (int i = 0; i < nElements; ++i) - { - try - { - EVENT::CalorimeterHit *pCaloHit = dynamic_cast(pCaloHitCollection->getElementAt(i)); - - if (NULL == pCaloHit) - throw EVENT::Exception("Collection type mismatch"); - - PandoraApi::CaloHit::Parameters caloHitParameters; - caloHitParameters.m_hitType = pandora::HCAL; - caloHitParameters.m_isDigital = false; - caloHitParameters.m_layer = cellIdDecoder(pCaloHit)[layerCoding.c_str()]; - caloHitParameters.m_isInOuterSamplingLayer = (this->GetNLayersFromEdge(pCaloHit) <= m_settings.m_nOuterSamplingLayers); - this->GetCommonCaloHitProperties(pCaloHit, caloHitParameters); - - float absorberCorrection(1.); - this->GetEndCapCaloHitProperties(pCaloHit, endcapLayers, caloHitParameters, absorberCorrection); - - caloHitParameters.m_mipEquivalentEnergy = pCaloHit->getEnergy() * m_settings.m_hCalToMip * absorberCorrection; - - if (caloHitParameters.m_mipEquivalentEnergy.Get() < m_settings.m_hCalMipThreshold) - continue; - - caloHitParameters.m_hadronicEnergy = std::min(m_settings.m_hCalToHadGeV * pCaloHit->getEnergy(), m_settings.m_maxHCalHitHadronicEnergy); - caloHitParameters.m_electromagneticEnergy = m_settings.m_hCalToEMGeV * pCaloHit->getEnergy(); - - PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::CaloHit::Create(m_pandora, caloHitParameters)); - m_calorimeterHitVector.push_back(pCaloHit); - } - catch (pandora::StatusCodeException &statusCodeException) - { - streamlog_out(ERROR) << "Failed to extract lhcal calo hit: " << statusCodeException.ToString() << std::endl; - } - catch (EVENT::Exception &exception) - { - streamlog_out(WARNING) << "Failed to extract lhcal calo hit: " << exception.what() << std::endl; - } - } - } - catch (EVENT::Exception &exception) - { - streamlog_out(MESSAGE) << "Failed to extract lhcal calo hit collection: " << *iter << ", " << exception.what() << std::endl; - } - } + ///FIXME: WHAT ABOUT OTHER ECALS? + const std::vector& endcapLayers = + getExtension(dd4hep::DetType::CALORIMETER | dd4hep::DetType::ENDCAP | dd4hep::DetType::ELECTROMAGNETIC | + dd4hep::DetType::FORWARD, + dd4hep::DetType::AUXILIARY) + ->layers; - return pandora::STATUS_CODE_SUCCESS; -} + UTIL::CellIDDecoder cellIdDecoder(pCaloHitCollection); + const std::string layerCodingString(pCaloHitCollection->getParameters().getStringVal(LCIO::CellIDEncoding)); + const std::string layerCoding("layer"); -//------------------------------------------------------------------------------------------------------------------------------------------ + for (int i = 0; i < nElements; ++i) { + try { + EVENT::CalorimeterHit* pCaloHit = dynamic_cast(pCaloHitCollection->getElementAt(i)); -void DDCaloHitCreator::GetCommonCaloHitProperties(const EVENT::CalorimeterHit *const pCaloHit, PandoraApi::CaloHit::Parameters &caloHitParameters) const -{ - const float *pCaloHitPosition(pCaloHit->getPosition()); - const pandora::CartesianVector positionVector(pCaloHitPosition[0], pCaloHitPosition[1], pCaloHitPosition[2]); - - caloHitParameters.m_cellGeometry = pandora::RECTANGULAR; - caloHitParameters.m_positionVector = positionVector; - caloHitParameters.m_expectedDirection = positionVector.GetUnitVector(); - caloHitParameters.m_pParentAddress = (void*)pCaloHit; - caloHitParameters.m_inputEnergy = pCaloHit->getEnergy(); - caloHitParameters.m_time = pCaloHit->getTime(); -} + if (NULL == pCaloHit) + throw EVENT::Exception("Collection type mismatch"); -//------------------------------------------------------------------------------------------------------------------------------------------ + PandoraApi::CaloHit::Parameters caloHitParameters; + caloHitParameters.m_hitType = pandora::ECAL; + caloHitParameters.m_isDigital = false; + caloHitParameters.m_layer = cellIdDecoder(pCaloHit)[layerCoding.c_str()]; + caloHitParameters.m_isInOuterSamplingLayer = false; + this->GetCommonCaloHitProperties(pCaloHit, caloHitParameters); -void DDCaloHitCreator::GetEndCapCaloHitProperties(const EVENT::CalorimeterHit *const pCaloHit, const std::vector &layers, - PandoraApi::CaloHit::Parameters &caloHitParameters, float &absorberCorrection) const -{ - caloHitParameters.m_hitRegion = pandora::ENDCAP; - - //FIXME! WHAT DO WE DO HERE? - const int physicalLayer(std::min(static_cast(caloHitParameters.m_layer.Get()), static_cast(layers.size()-1))); - caloHitParameters.m_cellSize0 = layers[physicalLayer].cellSize0/dd4hep::mm; - caloHitParameters.m_cellSize1 = layers[physicalLayer].cellSize1/dd4hep::mm; - - double thickness = (layers[physicalLayer].inner_thickness+layers[physicalLayer].sensitive_thickness/2.0)/dd4hep::mm; - double nRadLengths = layers[physicalLayer].inner_nRadiationLengths; - double nIntLengths = layers[physicalLayer].inner_nInteractionLengths; - double layerAbsorberThickness = (layers[physicalLayer].inner_thickness-layers[physicalLayer].sensitive_thickness/2.0)/dd4hep::mm; - - if(physicalLayer>0){ - thickness += (layers[physicalLayer-1].outer_thickness -layers[physicalLayer].sensitive_thickness/2.0)/dd4hep::mm; - nRadLengths += layers[physicalLayer-1].outer_nRadiationLengths; - nIntLengths += layers[physicalLayer-1].outer_nInteractionLengths; - layerAbsorberThickness += (layers[physicalLayer-1].outer_thickness -layers[physicalLayer].sensitive_thickness/2.0)/dd4hep::mm; + float absorberCorrection(1.); + this->GetEndCapCaloHitProperties(pCaloHit, endcapLayers, caloHitParameters, absorberCorrection); - } - - caloHitParameters.m_cellThickness = thickness; - caloHitParameters.m_nCellRadiationLengths = nRadLengths; - caloHitParameters.m_nCellInteractionLengths = nIntLengths; - - if (caloHitParameters.m_nCellRadiationLengths.Get() < std::numeric_limits::epsilon() || caloHitParameters.m_nCellInteractionLengths.Get() < std::numeric_limits::epsilon()) - { - streamlog_out(WARNING) << "CaloHitCreator::GetEndCapCaloHitProperties Calo hit has 0 radiation length or interaction length: \ - not creating a Pandora calo hit." << std::endl; - throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER); - } + caloHitParameters.m_mipEquivalentEnergy = pCaloHit->getEnergy() * m_settings.m_eCalToMip * absorberCorrection; - - //FIXME! do we need this? - absorberCorrection = 1.; - for (unsigned int i = 0, iMax = layers.size(); i < iMax; ++i) - { - float absorberThickness((layers[i].inner_thickness - layers[i].sensitive_thickness/2.0 )/dd4hep::mm); - - if (i>0) - absorberThickness += (layers[i-1].outer_thickness - layers[i-1].sensitive_thickness/2.0)/dd4hep::mm; - - if (absorberThickness < std::numeric_limits::epsilon()) + if (caloHitParameters.m_mipEquivalentEnergy.Get() < m_settings.m_eCalMipThreshold) continue; - if (layerAbsorberThickness > std::numeric_limits::epsilon()) - absorberCorrection = absorberThickness / layerAbsorberThickness; + caloHitParameters.m_electromagneticEnergy = m_settings.m_eCalToEMGeV * pCaloHit->getEnergy(); + caloHitParameters.m_hadronicEnergy = m_settings.m_eCalToHadGeVEndCap * pCaloHit->getEnergy(); - break; + PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, + PandoraApi::CaloHit::Create(m_pandora, caloHitParameters)); + m_calorimeterHitVector.push_back(pCaloHit); + } catch (pandora::StatusCodeException& statusCodeException) { + streamlog_out(ERROR) << "Failed to extract lcal calo hit: " << statusCodeException.ToString() << std::endl; + } catch (EVENT::Exception& exception) { + streamlog_out(WARNING) << "Failed to extract lcal calo hit: " << exception.what() << std::endl; + } + } + } catch (EVENT::Exception& exception) { + streamlog_out(MESSAGE) << "Failed to extract lcal calo hit collection: " << *iter << ", " << exception.what() + << std::endl; } + } - caloHitParameters.m_cellNormalVector = (pCaloHit->getPosition()[2] > 0) ? pandora::CartesianVector(0, 0, 1) : - pandora::CartesianVector(0, 0, -1); - -// streamlog_out(DEBUG) <<" GetEndCapCaloHitProperties: physLayer: "< &layers, - unsigned int barrelSymmetryOrder, - PandoraApi::CaloHit::Parameters &caloHitParameters, - FloatVector const& normalVector, - float &absorberCorrection ) const -{ - caloHitParameters.m_hitRegion = pandora::BARREL; - - //FIXME! WHAT DO WE DO HERE? - const int physicalLayer(std::min(static_cast(caloHitParameters.m_layer.Get()), static_cast(layers.size()-1))); - caloHitParameters.m_cellSize0 = layers[physicalLayer].cellSize0/dd4hep::mm; - caloHitParameters.m_cellSize1 = layers[physicalLayer].cellSize1/dd4hep::mm; - - double thickness = (layers[physicalLayer].inner_thickness+layers[physicalLayer].sensitive_thickness/2.0)/dd4hep::mm; - double nRadLengths = layers[physicalLayer].inner_nRadiationLengths; - double nIntLengths = layers[physicalLayer].inner_nInteractionLengths; - - double layerAbsorberThickness = (layers[physicalLayer].inner_thickness-layers[physicalLayer].sensitive_thickness/2.0)/dd4hep::mm; - if(physicalLayer>0){ - thickness += (layers[physicalLayer-1].outer_thickness -layers[physicalLayer].sensitive_thickness/2.0)/dd4hep::mm; - nRadLengths += layers[physicalLayer-1].outer_nRadiationLengths; - nIntLengths += layers[physicalLayer-1].outer_nInteractionLengths; - layerAbsorberThickness += (layers[physicalLayer-1].outer_thickness -layers[physicalLayer].sensitive_thickness/2.0)/dd4hep::mm; - } - - caloHitParameters.m_cellThickness = thickness; - caloHitParameters.m_nCellRadiationLengths = nRadLengths; - caloHitParameters.m_nCellInteractionLengths = nIntLengths; - - if (caloHitParameters.m_nCellRadiationLengths.Get() < std::numeric_limits::epsilon() || caloHitParameters.m_nCellInteractionLengths.Get() < std::numeric_limits::epsilon()) - { - streamlog_out(WARNING) << "CaloHitCreator::GetBarrelCaloHitProperties Calo hit has 0 radiation length or interaction length: \ - not creating a Pandora calo hit." << std::endl; - throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER); - } +pandora::StatusCode DDCaloHitCreator::CreateLHCalCaloHits(const EVENT::LCEvent* const pLCEvent) { + for (StringVector::const_iterator iter = m_settings.m_lHCalCaloHitCollections.begin(), + iterEnd = m_settings.m_lHCalCaloHitCollections.end(); + iter != iterEnd; ++iter) { + try { + const EVENT::LCCollection* pCaloHitCollection = pLCEvent->getCollection(*iter); + const int nElements(pCaloHitCollection->getNumberOfElements()); - //FIXME! do we need this? - absorberCorrection = 1.; - for (unsigned int i = 0, iMax = layers.size(); i < iMax; ++i) - { - float absorberThickness((layers[i].inner_thickness - layers[i].sensitive_thickness/2.0 )/dd4hep::mm); - - if (i>0) - absorberThickness += (layers[i-1].outer_thickness - layers[i-1].sensitive_thickness/2.0)/dd4hep::mm; + if (0 == nElements) + continue; - if (absorberThickness < std::numeric_limits::epsilon()) - continue; + streamlog_out(DEBUG1) << "Creating " << *iter << " hits" << std::endl; - if (layerAbsorberThickness > std::numeric_limits::epsilon()) - absorberCorrection = absorberThickness / layerAbsorberThickness; + ///FIXME! WHAT ABOUT MORE HCALS? + const std::vector& endcapLayers = + getExtension(dd4hep::DetType::CALORIMETER | dd4hep::DetType::ENDCAP | dd4hep::DetType::HADRONIC | + dd4hep::DetType::FORWARD) + ->layers; - break; - } + UTIL::CellIDDecoder cellIdDecoder(pCaloHitCollection); + const std::string layerCodingString(pCaloHitCollection->getParameters().getStringVal(LCIO::CellIDEncoding)); + const std::string layerCoding("layer"); - if (barrelSymmetryOrder > 2) - { - - if ( pCaloHit->getCellID0() != 0 ) { - - auto staveDetElement = m_volumeManager.lookupDetElement( pCaloHit->getCellID0() ); - dd4hep::Position local1(0.0, 0.0, 0.0); - dd4hep::Position local2(normalVector[0],normalVector[1],normalVector[2]); - dd4hep::Position global1(0.0, 0.0, 0.0); - dd4hep::Position global2(0.0, 0.0, 0.0); - staveDetElement.nominal().localToWorld( local1, global1 ); - staveDetElement.nominal().localToWorld( local2, global2 ); - dd4hep::Position normal( global2-global1 ); - - streamlog_out(DEBUG6) << " detelement: " << staveDetElement.name() - << " parent: " << staveDetElement.parent().name() - << " grandparent: " << staveDetElement.parent().parent().name() - << " cellID: " << pCaloHit->getCellID0() - << " PhiLoc:" << atan2( global1.y(), global1.x() )*180/M_PI - << " PhiNor:" << atan2( normal.y(), normal.x() )*180/M_PI - << " normal vector " - << std::setw(15) << normal.x() - << std::setw(15) << normal.y() - << std::setw(15) << normal.z() - << std::endl; - - caloHitParameters.m_cellNormalVector = pandora::CartesianVector( normal.x(), normal.y(), normal.z() ); - } else { - const double phi = atan2( pCaloHit->getPosition()[1], pCaloHit->getPosition()[0] ); - - streamlog_out( WARNING ) << "This hit does not have any cellIDs set, will use phi-direction for normal vector " - << " phi:" << std::setw(15) << phi*180/M_PI - << std::endl; - - caloHitParameters.m_cellNormalVector = pandora::CartesianVector( std::cos(phi), std::sin(phi) , 0.0 ); - } + for (int i = 0; i < nElements; ++i) { + try { + EVENT::CalorimeterHit* pCaloHit = dynamic_cast(pCaloHitCollection->getElementAt(i)); + if (NULL == pCaloHit) + throw EVENT::Exception("Collection type mismatch"); + PandoraApi::CaloHit::Parameters caloHitParameters; + caloHitParameters.m_hitType = pandora::HCAL; + caloHitParameters.m_isDigital = false; + caloHitParameters.m_layer = cellIdDecoder(pCaloHit)[layerCoding.c_str()]; + caloHitParameters.m_isInOuterSamplingLayer = + (this->GetNLayersFromEdge(pCaloHit) <= m_settings.m_nOuterSamplingLayers); + this->GetCommonCaloHitProperties(pCaloHit, caloHitParameters); + float absorberCorrection(1.); + this->GetEndCapCaloHitProperties(pCaloHit, endcapLayers, caloHitParameters, absorberCorrection); + + caloHitParameters.m_mipEquivalentEnergy = pCaloHit->getEnergy() * m_settings.m_hCalToMip * absorberCorrection; + + if (caloHitParameters.m_mipEquivalentEnergy.Get() < m_settings.m_hCalMipThreshold) + continue; + + caloHitParameters.m_hadronicEnergy = + std::min(m_settings.m_hCalToHadGeV * pCaloHit->getEnergy(), m_settings.m_maxHCalHitHadronicEnergy); + caloHitParameters.m_electromagneticEnergy = m_settings.m_hCalToEMGeV * pCaloHit->getEnergy(); + + PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, + PandoraApi::CaloHit::Create(m_pandora, caloHitParameters)); + m_calorimeterHitVector.push_back(pCaloHit); + } catch (pandora::StatusCodeException& statusCodeException) { + streamlog_out(ERROR) << "Failed to extract lhcal calo hit: " << statusCodeException.ToString() << std::endl; + } catch (EVENT::Exception& exception) { + streamlog_out(WARNING) << "Failed to extract lhcal calo hit: " << exception.what() << std::endl; + } + } + } catch (EVENT::Exception& exception) { + streamlog_out(MESSAGE) << "Failed to extract lhcal calo hit collection: " << *iter << ", " << exception.what() + << std::endl; } - else - { - const float *pCaloHitPosition( pCaloHit->getPosition() ); - const float phi = std::atan2( pCaloHitPosition[1], pCaloHitPosition[0] ); - caloHitParameters.m_cellNormalVector = pandora::CartesianVector(std::cos(phi), std::sin(phi), 0); - } - -// streamlog_out(DEBUG)<<" GetBarrelCaloHitProperties: physLayer: "<GetMaximumRadius(pCaloHit, m_settings.m_hCalBarrelOuterSymmetry, m_settings.m_hCalBarrelOuterPhi0)); - const float endCapMaximumRadius(this->GetMaximumRadius(pCaloHit, m_settings.m_hCalEndCapInnerSymmetryOrder, m_settings.m_hCalEndCapInnerPhiCoordinate)); - const float caloHitAbsZ(std::fabs(pCaloHit->getPosition()[2])); +void DDCaloHitCreator::GetCommonCaloHitProperties(const EVENT::CalorimeterHit* const pCaloHit, + PandoraApi::CaloHit::Parameters& caloHitParameters) const { + const float* pCaloHitPosition(pCaloHit->getPosition()); + const pandora::CartesianVector positionVector(pCaloHitPosition[0], pCaloHitPosition[1], pCaloHitPosition[2]); + + caloHitParameters.m_cellGeometry = pandora::RECTANGULAR; + caloHitParameters.m_positionVector = positionVector; + caloHitParameters.m_expectedDirection = positionVector.GetUnitVector(); + caloHitParameters.m_pParentAddress = (void*)pCaloHit; + caloHitParameters.m_inputEnergy = pCaloHit->getEnergy(); + caloHitParameters.m_time = pCaloHit->getTime(); +} - // Distance from radial outer - float radialDistanceToEdge(std::numeric_limits::max()); +//------------------------------------------------------------------------------------------------------------------------------------------ - if (caloHitAbsZ < m_settings.m_eCalBarrelOuterZ) - { - radialDistanceToEdge = (m_settings.m_hCalBarrelOuterR - barrelMaximumRadius) / m_hCalBarrelLayerThickness; - } - else - { - radialDistanceToEdge = (m_settings.m_hCalEndCapOuterR - endCapMaximumRadius) / m_hCalEndCapLayerThickness; - } +void DDCaloHitCreator::GetEndCapCaloHitProperties( + const EVENT::CalorimeterHit* const pCaloHit, + const std::vector& layers, + PandoraApi::CaloHit::Parameters& caloHitParameters, float& absorberCorrection) const { + caloHitParameters.m_hitRegion = pandora::ENDCAP; + + //FIXME! WHAT DO WE DO HERE? + const int physicalLayer( + std::min(static_cast(caloHitParameters.m_layer.Get()), static_cast(layers.size() - 1))); + caloHitParameters.m_cellSize0 = layers[physicalLayer].cellSize0 / dd4hep::mm; + caloHitParameters.m_cellSize1 = layers[physicalLayer].cellSize1 / dd4hep::mm; + + double thickness = + (layers[physicalLayer].inner_thickness + layers[physicalLayer].sensitive_thickness / 2.0) / dd4hep::mm; + double nRadLengths = layers[physicalLayer].inner_nRadiationLengths; + double nIntLengths = layers[physicalLayer].inner_nInteractionLengths; + double layerAbsorberThickness = + (layers[physicalLayer].inner_thickness - layers[physicalLayer].sensitive_thickness / 2.0) / dd4hep::mm; + + if (physicalLayer > 0) { + thickness += + (layers[physicalLayer - 1].outer_thickness - layers[physicalLayer].sensitive_thickness / 2.0) / dd4hep::mm; + nRadLengths += layers[physicalLayer - 1].outer_nRadiationLengths; + nIntLengths += layers[physicalLayer - 1].outer_nInteractionLengths; + layerAbsorberThickness += + (layers[physicalLayer - 1].outer_thickness - layers[physicalLayer].sensitive_thickness / 2.0) / dd4hep::mm; + } + + caloHitParameters.m_cellThickness = thickness; + caloHitParameters.m_nCellRadiationLengths = nRadLengths; + caloHitParameters.m_nCellInteractionLengths = nIntLengths; + + if (caloHitParameters.m_nCellRadiationLengths.Get() < std::numeric_limits::epsilon() || + caloHitParameters.m_nCellInteractionLengths.Get() < std::numeric_limits::epsilon()) { + streamlog_out(WARNING) + << "CaloHitCreator::GetEndCapCaloHitProperties Calo hit has 0 radiation length or interaction length: \ + not creating a Pandora calo hit." + << std::endl; + throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER); + } + + //FIXME! do we need this? + absorberCorrection = 1.; + for (unsigned int i = 0, iMax = layers.size(); i < iMax; ++i) { + float absorberThickness((layers[i].inner_thickness - layers[i].sensitive_thickness / 2.0) / dd4hep::mm); + + if (i > 0) + absorberThickness += (layers[i - 1].outer_thickness - layers[i - 1].sensitive_thickness / 2.0) / dd4hep::mm; + + if (absorberThickness < std::numeric_limits::epsilon()) + continue; + + if (layerAbsorberThickness > std::numeric_limits::epsilon()) + absorberCorrection = absorberThickness / layerAbsorberThickness; + + break; + } + + caloHitParameters.m_cellNormalVector = + (pCaloHit->getPosition()[2] > 0) ? pandora::CartesianVector(0, 0, 1) : pandora::CartesianVector(0, 0, -1); + + // streamlog_out(DEBUG) <<" GetEndCapCaloHitProperties: physLayer: "<::max()); +//------------------------------------------------------------------------------------------------------------------------------------------ - if (caloHitAbsZ >= m_settings.m_eCalBarrelOuterZ) - { - rearDistanceToEdge = (m_settings.m_hCalEndCapOuterZ - caloHitAbsZ) / m_hCalEndCapLayerThickness; +void DDCaloHitCreator::GetBarrelCaloHitProperties( + const EVENT::CalorimeterHit* const pCaloHit, + const std::vector& layers, unsigned int barrelSymmetryOrder, + PandoraApi::CaloHit::Parameters& caloHitParameters, FloatVector const& normalVector, + float& absorberCorrection) const { + caloHitParameters.m_hitRegion = pandora::BARREL; + + //FIXME! WHAT DO WE DO HERE? + const int physicalLayer( + std::min(static_cast(caloHitParameters.m_layer.Get()), static_cast(layers.size() - 1))); + caloHitParameters.m_cellSize0 = layers[physicalLayer].cellSize0 / dd4hep::mm; + caloHitParameters.m_cellSize1 = layers[physicalLayer].cellSize1 / dd4hep::mm; + + double thickness = + (layers[physicalLayer].inner_thickness + layers[physicalLayer].sensitive_thickness / 2.0) / dd4hep::mm; + double nRadLengths = layers[physicalLayer].inner_nRadiationLengths; + double nIntLengths = layers[physicalLayer].inner_nInteractionLengths; + + double layerAbsorberThickness = + (layers[physicalLayer].inner_thickness - layers[physicalLayer].sensitive_thickness / 2.0) / dd4hep::mm; + if (physicalLayer > 0) { + thickness += + (layers[physicalLayer - 1].outer_thickness - layers[physicalLayer].sensitive_thickness / 2.0) / dd4hep::mm; + nRadLengths += layers[physicalLayer - 1].outer_nRadiationLengths; + nIntLengths += layers[physicalLayer - 1].outer_nInteractionLengths; + layerAbsorberThickness += + (layers[physicalLayer - 1].outer_thickness - layers[physicalLayer].sensitive_thickness / 2.0) / dd4hep::mm; + } + + caloHitParameters.m_cellThickness = thickness; + caloHitParameters.m_nCellRadiationLengths = nRadLengths; + caloHitParameters.m_nCellInteractionLengths = nIntLengths; + + if (caloHitParameters.m_nCellRadiationLengths.Get() < std::numeric_limits::epsilon() || + caloHitParameters.m_nCellInteractionLengths.Get() < std::numeric_limits::epsilon()) { + streamlog_out(WARNING) + << "CaloHitCreator::GetBarrelCaloHitProperties Calo hit has 0 radiation length or interaction length: \ + not creating a Pandora calo hit." + << std::endl; + throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER); + } + + //FIXME! do we need this? + absorberCorrection = 1.; + for (unsigned int i = 0, iMax = layers.size(); i < iMax; ++i) { + float absorberThickness((layers[i].inner_thickness - layers[i].sensitive_thickness / 2.0) / dd4hep::mm); + + if (i > 0) + absorberThickness += (layers[i - 1].outer_thickness - layers[i - 1].sensitive_thickness / 2.0) / dd4hep::mm; + + if (absorberThickness < std::numeric_limits::epsilon()) + continue; + + if (layerAbsorberThickness > std::numeric_limits::epsilon()) + absorberCorrection = absorberThickness / layerAbsorberThickness; + + break; + } + + if (barrelSymmetryOrder > 2) { + if (pCaloHit->getCellID0() != 0) { + auto staveDetElement = m_volumeManager.lookupDetElement(pCaloHit->getCellID0()); + dd4hep::Position local1(0.0, 0.0, 0.0); + dd4hep::Position local2(normalVector[0], normalVector[1], normalVector[2]); + dd4hep::Position global1(0.0, 0.0, 0.0); + dd4hep::Position global2(0.0, 0.0, 0.0); + staveDetElement.nominal().localToWorld(local1, global1); + staveDetElement.nominal().localToWorld(local2, global2); + dd4hep::Position normal(global2 - global1); + + streamlog_out(DEBUG6) << " detelement: " << staveDetElement.name() + << " parent: " << staveDetElement.parent().name() + << " grandparent: " << staveDetElement.parent().parent().name() + << " cellID: " << pCaloHit->getCellID0() + << " PhiLoc:" << atan2(global1.y(), global1.x()) * 180 / M_PI + << " PhiNor:" << atan2(normal.y(), normal.x()) * 180 / M_PI << " normal vector " + << std::setw(15) << normal.x() << std::setw(15) << normal.y() << std::setw(15) << normal.z() + << std::endl; + + caloHitParameters.m_cellNormalVector = pandora::CartesianVector(normal.x(), normal.y(), normal.z()); + } else { + const double phi = atan2(pCaloHit->getPosition()[1], pCaloHit->getPosition()[0]); + + streamlog_out(WARNING) << "This hit does not have any cellIDs set, will use phi-direction for normal vector " + << " phi:" << std::setw(15) << phi * 180 / M_PI << std::endl; + + caloHitParameters.m_cellNormalVector = pandora::CartesianVector(std::cos(phi), std::sin(phi), 0.0); } - else - { - const float rearDistance((m_settings.m_eCalBarrelOuterZ - caloHitAbsZ) / m_hCalBarrelLayerThickness); - - if (rearDistance < m_settings.m_layersFromEdgeMaxRearDistance) - { - const float overlapDistance((m_settings.m_hCalEndCapOuterR - endCapMaximumRadius) / m_hCalEndCapLayerThickness); - rearDistanceToEdge = std::max(rearDistance, overlapDistance); - } + + } else { + const float* pCaloHitPosition(pCaloHit->getPosition()); + const float phi = std::atan2(pCaloHitPosition[1], pCaloHitPosition[0]); + caloHitParameters.m_cellNormalVector = pandora::CartesianVector(std::cos(phi), std::sin(phi), 0); + } + + // streamlog_out(DEBUG)<<" GetBarrelCaloHitProperties: physLayer: "<GetMaximumRadius(pCaloHit, m_settings.m_hCalBarrelOuterSymmetry, m_settings.m_hCalBarrelOuterPhi0)); + const float endCapMaximumRadius(this->GetMaximumRadius(pCaloHit, m_settings.m_hCalEndCapInnerSymmetryOrder, + m_settings.m_hCalEndCapInnerPhiCoordinate)); + const float caloHitAbsZ(std::fabs(pCaloHit->getPosition()[2])); + + // Distance from radial outer + float radialDistanceToEdge(std::numeric_limits::max()); + + if (caloHitAbsZ < m_settings.m_eCalBarrelOuterZ) { + radialDistanceToEdge = (m_settings.m_hCalBarrelOuterR - barrelMaximumRadius) / m_hCalBarrelLayerThickness; + } else { + radialDistanceToEdge = (m_settings.m_hCalEndCapOuterR - endCapMaximumRadius) / m_hCalEndCapLayerThickness; + } + + // Distance from rear of endcap outer + float rearDistanceToEdge(std::numeric_limits::max()); + + if (caloHitAbsZ >= m_settings.m_eCalBarrelOuterZ) { + rearDistanceToEdge = (m_settings.m_hCalEndCapOuterZ - caloHitAbsZ) / m_hCalEndCapLayerThickness; + } else { + const float rearDistance((m_settings.m_eCalBarrelOuterZ - caloHitAbsZ) / m_hCalBarrelLayerThickness); + + if (rearDistance < m_settings.m_layersFromEdgeMaxRearDistance) { + const float overlapDistance((m_settings.m_hCalEndCapOuterR - endCapMaximumRadius) / m_hCalEndCapLayerThickness); + rearDistanceToEdge = std::max(rearDistance, overlapDistance); } + } - return static_cast(std::min(radialDistanceToEdge, rearDistanceToEdge)); + return static_cast(std::min(radialDistanceToEdge, rearDistanceToEdge)); } //------------------------------------------------------------------------------------------------------------------------------------------ -float DDCaloHitCreator::GetMaximumRadius(const EVENT::CalorimeterHit *const pCaloHit, const unsigned int symmetryOrder, const float phi0) const -{ - const float *pCaloHitPosition(pCaloHit->getPosition()); +float DDCaloHitCreator::GetMaximumRadius(const EVENT::CalorimeterHit* const pCaloHit, const unsigned int symmetryOrder, + const float phi0) const { + const float* pCaloHitPosition(pCaloHit->getPosition()); - if (symmetryOrder <= 2) - return std::sqrt((pCaloHitPosition[0] * pCaloHitPosition[0]) + (pCaloHitPosition[1] * pCaloHitPosition[1])); + if (symmetryOrder <= 2) + return std::sqrt((pCaloHitPosition[0] * pCaloHitPosition[0]) + (pCaloHitPosition[1] * pCaloHitPosition[1])); - float maximumRadius(0.f); - const float twoPi(2.f * M_PI); + float maximumRadius(0.f); + const float twoPi(2.f * M_PI); - for (unsigned int i = 0; i < symmetryOrder; ++i) - { - const float phi = phi0 + i * twoPi / static_cast(symmetryOrder); - float radius = pCaloHitPosition[0] * std::cos(phi) + pCaloHitPosition[1] * std::sin(phi); + for (unsigned int i = 0; i < symmetryOrder; ++i) { + const float phi = phi0 + i * twoPi / static_cast(symmetryOrder); + float radius = pCaloHitPosition[0] * std::cos(phi) + pCaloHitPosition[1] * std::sin(phi); - if (radius > maximumRadius) - maximumRadius = radius; - } + if (radius > maximumRadius) + maximumRadius = radius; + } - return maximumRadius; + return maximumRadius; } //------------------------------------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------------------------------------ DDCaloHitCreator::Settings::Settings() - : m_eCalCaloHitCollections( StringVector() ), - m_hCalCaloHitCollections( StringVector() ), - m_lCalCaloHitCollections( StringVector() ), - m_lHCalCaloHitCollections( StringVector() ), - m_muonCaloHitCollections( StringVector() ), - m_eCalToMip(1.f), - m_hCalToMip(1.f), - m_muonToMip(1.f), - m_eCalMipThreshold(0.f), - m_hCalMipThreshold(0.f), - m_muonMipThreshold(0.f), - m_eCalToEMGeV(1.f), - m_eCalToHadGeVBarrel(1.f), - m_eCalToHadGeVEndCap(1.f), - m_hCalToEMGeV(1.f), - m_hCalToHadGeV(1.f), - m_muonDigitalHits(1), - m_muonHitEnergy(0.5f), - m_maxHCalHitHadronicEnergy(10000.f), - m_nOuterSamplingLayers(3), - m_layersFromEdgeMaxRearDistance(250.f), - m_hCalEndCapInnerSymmetryOrder(4), - m_hCalEndCapInnerPhiCoordinate(0.f), - m_stripSplittingOn(0), - m_useEcalScLayers(0), - m_eCalSiToMip(1.f), - m_eCalScToMip(1.f), - m_eCalSiMipThreshold(0.f), - m_eCalScMipThreshold(0.f), - m_eCalSiToEMGeV(1.f), - m_eCalScToEMGeV(1.f), - m_eCalSiToHadGeVBarrel(1.f), - m_eCalScToHadGeVBarrel(1.f), - m_eCalSiToHadGeVEndCap(1.f), - m_eCalScToHadGeVEndCap(1.f), - m_eCalBarrelOuterZ(0.f), - m_hCalBarrelOuterZ(0.f), - m_muonBarrelOuterZ(0.f), - m_coilOuterR(0.f), - m_eCalBarrelInnerPhi0(0.f), - m_eCalBarrelInnerSymmetry(0.f), - m_hCalBarrelInnerPhi0(0.f), - m_hCalBarrelInnerSymmetry(0.f), - m_muonBarrelInnerPhi0(0.f), - m_muonBarrelInnerSymmetry(0.f), - m_hCalEndCapOuterR(0.f), - m_hCalEndCapOuterZ(0.f), - m_hCalBarrelOuterR(0.f), - m_hCalBarrelOuterPhi0(0.f), - m_hCalBarrelOuterSymmetry(0.f), - m_eCalBarrelNormalVector({0.0, 0.0, 1.0}), - m_hCalBarrelNormalVector({0.0, 0.0, 1.0}), - m_muonBarrelNormalVector({0.0, 0.0, 1.0}) -{ -} + : m_eCalCaloHitCollections(StringVector()), + m_hCalCaloHitCollections(StringVector()), + m_lCalCaloHitCollections(StringVector()), + m_lHCalCaloHitCollections(StringVector()), + m_muonCaloHitCollections(StringVector()), + m_eCalToMip(1.f), + m_hCalToMip(1.f), + m_muonToMip(1.f), + m_eCalMipThreshold(0.f), + m_hCalMipThreshold(0.f), + m_muonMipThreshold(0.f), + m_eCalToEMGeV(1.f), + m_eCalToHadGeVBarrel(1.f), + m_eCalToHadGeVEndCap(1.f), + m_hCalToEMGeV(1.f), + m_hCalToHadGeV(1.f), + m_muonDigitalHits(1), + m_muonHitEnergy(0.5f), + m_maxHCalHitHadronicEnergy(10000.f), + m_nOuterSamplingLayers(3), + m_layersFromEdgeMaxRearDistance(250.f), + m_hCalEndCapInnerSymmetryOrder(4), + m_hCalEndCapInnerPhiCoordinate(0.f), + m_stripSplittingOn(0), + m_useEcalScLayers(0), + m_eCalSiToMip(1.f), + m_eCalScToMip(1.f), + m_eCalSiMipThreshold(0.f), + m_eCalScMipThreshold(0.f), + m_eCalSiToEMGeV(1.f), + m_eCalScToEMGeV(1.f), + m_eCalSiToHadGeVBarrel(1.f), + m_eCalScToHadGeVBarrel(1.f), + m_eCalSiToHadGeVEndCap(1.f), + m_eCalScToHadGeVEndCap(1.f), + m_eCalBarrelOuterZ(0.f), + m_hCalBarrelOuterZ(0.f), + m_muonBarrelOuterZ(0.f), + m_coilOuterR(0.f), + m_eCalBarrelInnerPhi0(0.f), + m_eCalBarrelInnerSymmetry(0.f), + m_hCalBarrelInnerPhi0(0.f), + m_hCalBarrelInnerSymmetry(0.f), + m_muonBarrelInnerPhi0(0.f), + m_muonBarrelInnerSymmetry(0.f), + m_hCalEndCapOuterR(0.f), + m_hCalEndCapOuterZ(0.f), + m_hCalBarrelOuterR(0.f), + m_hCalBarrelOuterPhi0(0.f), + m_hCalBarrelOuterSymmetry(0.f), + m_eCalBarrelNormalVector({0.0, 0.0, 1.0}), + m_hCalBarrelNormalVector({0.0, 0.0, 1.0}), + m_muonBarrelNormalVector({0.0, 0.0, 1.0}) {} diff --git a/k4GaudiPandora/src/DDExternalClusteringAlgorithm.cc b/k4GaudiPandora/src/DDExternalClusteringAlgorithm.cc index 16f6d06..a231487 100644 --- a/k4GaudiPandora/src/DDExternalClusteringAlgorithm.cc +++ b/k4GaudiPandora/src/DDExternalClusteringAlgorithm.cc @@ -1,14 +1,33 @@ +/* + * Copyright (c) 2020-2024 Key4hep-Project. + * + * This file is part of Key4hep. + * See https://key4hep.github.io/key4hep-doc/ for further info. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + /** * @file DDMarlinPandora/src/DDExternalClusteringAlgorithm.cc - * + * * @brief Implementation of the external clustering algorithm class. - * + * * $Log: $ */ +#include "EVENT/Cluster.h" #include "EVENT/LCCollection.h" #include "EVENT/LCEvent.h" -#include "EVENT/Cluster.h" #include "DDExternalClusteringAlgorithm.h" #include "DDPandoraPFANewProcessor.h" @@ -17,105 +36,95 @@ using namespace pandora; -DDExternalClusteringAlgorithm::DDExternalClusteringAlgorithm() : - m_flagClustersAsPhotons(true) -{ -} +DDExternalClusteringAlgorithm::DDExternalClusteringAlgorithm() : m_flagClustersAsPhotons(true) {} //------------------------------------------------------------------------------------------------------------------------------------------ -StatusCode DDExternalClusteringAlgorithm::Run() -{ - try - { - const CaloHitList *pCaloHitList = NULL; - PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetCurrentList(*this, pCaloHitList)); +StatusCode DDExternalClusteringAlgorithm::Run() { + try { + const CaloHitList* pCaloHitList = NULL; + PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetCurrentList(*this, pCaloHitList)); + + if (pCaloHitList->empty()) + return STATUS_CODE_SUCCESS; - if (pCaloHitList->empty()) - return STATUS_CODE_SUCCESS; + // Get external photon cluster collection + const EVENT::LCEvent* const pLCEvent(DDPandoraPFANewProcessor::GetCurrentEvent(&(this->GetPandora()))); + const EVENT::LCCollection* const pExternalClusterCollection = + pLCEvent->getCollection(m_externalClusterCollectionName); + const unsigned int nExternalClusters(pExternalClusterCollection->getNumberOfElements()); - // Get external photon cluster collection - const EVENT::LCEvent *const pLCEvent(DDPandoraPFANewProcessor::GetCurrentEvent(&(this->GetPandora()))); - const EVENT::LCCollection *const pExternalClusterCollection = pLCEvent->getCollection(m_externalClusterCollectionName); - const unsigned int nExternalClusters(pExternalClusterCollection->getNumberOfElements()); + if (0 == nExternalClusters) + return STATUS_CODE_SUCCESS; - if (0 == nExternalClusters) - return STATUS_CODE_SUCCESS; + // Populate pandora parent address to calo hit map + ParentAddressToCaloHitMap parentAddressToCaloHitMap; + + for (CaloHitList::const_iterator hitIter = pCaloHitList->begin(), hitIterEnd = pCaloHitList->end(); + hitIter != hitIterEnd; ++hitIter) { + const pandora::CaloHit* const pCaloHit = *hitIter; + parentAddressToCaloHitMap.insert(ParentAddressToCaloHitMap::value_type(pCaloHit->GetParentAddress(), pCaloHit)); + } - // Populate pandora parent address to calo hit map - ParentAddressToCaloHitMap parentAddressToCaloHitMap; + // Recreate external clusters within the pandora framework + for (unsigned int iCluster = 0; iCluster < nExternalClusters; ++iCluster) { + const EVENT::Cluster* const pExternalCluster = + dynamic_cast(pExternalClusterCollection->getElementAt(iCluster)); - for (CaloHitList::const_iterator hitIter = pCaloHitList->begin(), hitIterEnd = pCaloHitList->end(); hitIter != hitIterEnd; ++hitIter) - { - const pandora::CaloHit *const pCaloHit = *hitIter; - parentAddressToCaloHitMap.insert(ParentAddressToCaloHitMap::value_type(pCaloHit->GetParentAddress(), pCaloHit)); + if (NULL == pExternalCluster) + throw EVENT::Exception("Collection type mismatch"); + + const CalorimeterHitVec& calorimeterHitVec(pExternalCluster->getCalorimeterHits()); + + const pandora::Cluster* pPandoraCluster = NULL; + + for (CalorimeterHitVec::const_iterator iter = calorimeterHitVec.begin(), iterEnd = calorimeterHitVec.end(); + iter != iterEnd; ++iter) { + ParentAddressToCaloHitMap::const_iterator pandoraCaloHitIter = parentAddressToCaloHitMap.find(*iter); + + if (parentAddressToCaloHitMap.end() == pandoraCaloHitIter) { + continue; } - // Recreate external clusters within the pandora framework - for (unsigned int iCluster = 0; iCluster < nExternalClusters; ++iCluster) - { - const EVENT::Cluster *const pExternalCluster = dynamic_cast(pExternalClusterCollection->getElementAt(iCluster)); - - if (NULL == pExternalCluster) - throw EVENT::Exception("Collection type mismatch"); - - const CalorimeterHitVec &calorimeterHitVec(pExternalCluster->getCalorimeterHits()); - - const pandora::Cluster *pPandoraCluster = NULL; - - for (CalorimeterHitVec::const_iterator iter = calorimeterHitVec.begin(), iterEnd = calorimeterHitVec.end(); iter != iterEnd; ++iter) - { - ParentAddressToCaloHitMap::const_iterator pandoraCaloHitIter = parentAddressToCaloHitMap.find(*iter); - - if (parentAddressToCaloHitMap.end() == pandoraCaloHitIter) - { - continue; - } - - const pandora::CaloHit *const pPandoraCaloHit = pandoraCaloHitIter->second; - - if (NULL == pPandoraCluster) - { - PandoraContentApi::Cluster::Parameters parameters; - parameters.m_caloHitList.push_back(pPandoraCaloHit); - PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Cluster::Create(*this, parameters, pPandoraCluster)); - - if (m_flagClustersAsPhotons) - { - PandoraContentApi::Cluster::Metadata metadata; - metadata.m_particleId = PHOTON; - PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Cluster::AlterMetadata(*this, pPandoraCluster, metadata)); - } - } - else - { - PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::AddToCluster(*this, pPandoraCluster, pPandoraCaloHit)); - } - } + const pandora::CaloHit* const pPandoraCaloHit = pandoraCaloHitIter->second; + + if (NULL == pPandoraCluster) { + PandoraContentApi::Cluster::Parameters parameters; + parameters.m_caloHitList.push_back(pPandoraCaloHit); + PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, + PandoraContentApi::Cluster::Create(*this, parameters, pPandoraCluster)); + + if (m_flagClustersAsPhotons) { + PandoraContentApi::Cluster::Metadata metadata; + metadata.m_particleId = PHOTON; + PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, + PandoraContentApi::Cluster::AlterMetadata(*this, pPandoraCluster, metadata)); + } + } else { + PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, + PandoraContentApi::AddToCluster(*this, pPandoraCluster, pPandoraCaloHit)); } + } } - catch (StatusCodeException &statusCodeException) - { - return statusCodeException.GetStatusCode(); - } - catch (EVENT::Exception &exception) - { - std::cout << "DDExternalClusteringAlgorithm failure: " << exception.what() << std::endl; - return STATUS_CODE_FAILURE; - } - - return STATUS_CODE_SUCCESS; + } catch (StatusCodeException& statusCodeException) { + return statusCodeException.GetStatusCode(); + } catch (EVENT::Exception& exception) { + std::cout << "DDExternalClusteringAlgorithm failure: " << exception.what() << std::endl; + return STATUS_CODE_FAILURE; + } + + return STATUS_CODE_SUCCESS; } //------------------------------------------------------------------------------------------------------------------------------------------ -StatusCode DDExternalClusteringAlgorithm::ReadSettings(const TiXmlHandle xmlHandle) -{ - PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, - "ExternalClusterCollectionName", m_externalClusterCollectionName)); +StatusCode DDExternalClusteringAlgorithm::ReadSettings(const TiXmlHandle xmlHandle) { + PANDORA_RETURN_RESULT_IF( + STATUS_CODE_SUCCESS, !=, + XmlHelper::ReadValue(xmlHandle, "ExternalClusterCollectionName", m_externalClusterCollectionName)); - PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, - "FlagClustersAsPhotons", m_flagClustersAsPhotons)); + PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, + XmlHelper::ReadValue(xmlHandle, "FlagClustersAsPhotons", m_flagClustersAsPhotons)); - return STATUS_CODE_SUCCESS; + return STATUS_CODE_SUCCESS; } diff --git a/k4GaudiPandora/src/DDGeometryCreator.cc b/k4GaudiPandora/src/DDGeometryCreator.cc index 7cd6435..75423ad 100644 --- a/k4GaudiPandora/src/DDGeometryCreator.cc +++ b/k4GaudiPandora/src/DDGeometryCreator.cc @@ -1,8 +1,27 @@ +/* + * Copyright (c) 2020-2024 Key4hep-Project. + * + * This file is part of Key4hep. + * See https://key4hep.github.io/key4hep-doc/ for further info. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + /** * @file DDMarlinPandora/src/DDGeometryCreator.cc - * + * * @brief Implementation of the geometry creator class. - * + * * $Log: $ */ @@ -11,396 +30,416 @@ #include "DDGeometryCreator.h" -#include "DD4hep/Detector.h" #include "DD4hep/DD4hepUnits.h" -#include "DDRec/DetectorData.h" #include "DD4hep/DetType.h" +#include "DD4hep/Detector.h" #include "DD4hep/DetectorSelector.h" - +#include "DDRec/DetectorData.h" #include //Forward declarations. See DDPandoraPFANewProcessor.cc // dd4hep::rec::LayeredCalorimeterData * getExtension(std::string detectorName); -dd4hep::rec::LayeredCalorimeterData * getExtension(unsigned int includeFlag, unsigned int excludeFlag=0); +dd4hep::rec::LayeredCalorimeterData* getExtension(unsigned int includeFlag, unsigned int excludeFlag = 0); std::vector getTrackingRegionExtent(); - -DDGeometryCreator::DDGeometryCreator(const Settings &settings, const pandora::Pandora *const pPandora) : - m_settings(settings), - m_pPandora(*pPandora) -{ -} +DDGeometryCreator::DDGeometryCreator(const Settings& settings, const pandora::Pandora* const pPandora) + : m_settings(settings), m_pPandora(*pPandora) {} //------------------------------------------------------------------------------------------------------------------------------------------ -DDGeometryCreator::~DDGeometryCreator() -{ -} +DDGeometryCreator::~DDGeometryCreator() {} //------------------------------------------------------------------------------------------------------------------------------------------ -pandora::StatusCode DDGeometryCreator::CreateGeometry() const -{ - +pandora::StatusCode DDGeometryCreator::CreateGeometry() const { dd4hep::Detector& mainDetector = dd4hep::Detector::getInstance(); - - try - { - SubDetectorTypeMap subDetectorTypeMap; - this->SetMandatorySubDetectorParameters(subDetectorTypeMap); - SubDetectorNameMap subDetectorNameMap; - this->SetAdditionalSubDetectorParameters(subDetectorNameMap); + try { + SubDetectorTypeMap subDetectorTypeMap; + this->SetMandatorySubDetectorParameters(subDetectorTypeMap); + + SubDetectorNameMap subDetectorNameMap; + this->SetAdditionalSubDetectorParameters(subDetectorNameMap); - std::string detectorName = mainDetector.header().name(); + std::string detectorName = mainDetector.header().name(); - streamlog_out(DEBUG) << "Creating geometry for detector " << detectorName<< std::endl; - - //Before it was checking the detector name for the "ILD" substring - if (m_settings.m_createGaps) - this->SetILDSpecificGeometry(subDetectorTypeMap, subDetectorNameMap); + streamlog_out(DEBUG) << "Creating geometry for detector " << detectorName << std::endl; - for (SubDetectorTypeMap::const_iterator iter = subDetectorTypeMap.begin(), iterEnd = subDetectorTypeMap.end(); iter != iterEnd; ++iter) - PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::Geometry::SubDetector::Create(m_pPandora, iter->second)); + //Before it was checking the detector name for the "ILD" substring + if (m_settings.m_createGaps) + this->SetILDSpecificGeometry(subDetectorTypeMap, subDetectorNameMap); - for (SubDetectorNameMap::const_iterator iter = subDetectorNameMap.begin(), iterEnd = subDetectorNameMap.end(); iter != iterEnd; ++iter){ - streamlog_out(DEBUG) << "Creating geometry for additional subdetector " << iter->first<< std::endl; + for (SubDetectorTypeMap::const_iterator iter = subDetectorTypeMap.begin(), iterEnd = subDetectorTypeMap.end(); + iter != iterEnd; ++iter) + PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, + PandoraApi::Geometry::SubDetector::Create(m_pPandora, iter->second)); - PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::Geometry::SubDetector::Create(m_pPandora, iter->second)); - } - } - catch (std::exception &exception) - { - streamlog_out(ERROR) << "Failure in marlin pandora geometry creator, exception: " << exception.what() << std::endl; - throw exception; + for (SubDetectorNameMap::const_iterator iter = subDetectorNameMap.begin(), iterEnd = subDetectorNameMap.end(); + iter != iterEnd; ++iter) { + streamlog_out(DEBUG) << "Creating geometry for additional subdetector " << iter->first << std::endl; + + PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, + PandoraApi::Geometry::SubDetector::Create(m_pPandora, iter->second)); } + } catch (std::exception& exception) { + streamlog_out(ERROR) << "Failure in marlin pandora geometry creator, exception: " << exception.what() << std::endl; + throw exception; + } - return pandora::STATUS_CODE_SUCCESS; + return pandora::STATUS_CODE_SUCCESS; } //------------------------------------------------------------------------------------------------------------------------------------------ -void DDGeometryCreator::SetMandatorySubDetectorParameters(SubDetectorTypeMap &subDetectorTypeMap) const -{ - PandoraApi::Geometry::SubDetector::Parameters eCalBarrelParameters, eCalEndCapParameters, hCalBarrelParameters, hCalEndCapParameters, - muonBarrelParameters, muonEndCapParameters; - - this->SetDefaultSubDetectorParameters(*const_cast(getExtension( ( dd4hep::DetType::CALORIMETER | dd4hep::DetType::ELECTROMAGNETIC | dd4hep::DetType::BARREL), ( dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD ) )), "ECalBarrel", pandora::ECAL_BARREL, eCalBarrelParameters); - this->SetDefaultSubDetectorParameters(*const_cast(getExtension( ( dd4hep::DetType::CALORIMETER | dd4hep::DetType::ELECTROMAGNETIC | dd4hep::DetType::ENDCAP), ( dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD ) )), "ECalEndCap", pandora::ECAL_ENDCAP, eCalEndCapParameters); - this->SetDefaultSubDetectorParameters(*const_cast(getExtension( ( dd4hep::DetType::CALORIMETER | dd4hep::DetType::HADRONIC | dd4hep::DetType::BARREL), ( dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD ) )), "HCalBarrel", pandora::HCAL_BARREL, hCalBarrelParameters); - this->SetDefaultSubDetectorParameters(*const_cast(getExtension( ( dd4hep::DetType::CALORIMETER | dd4hep::DetType::HADRONIC | dd4hep::DetType::ENDCAP), ( dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD ) )), "HCalEndCap", pandora::HCAL_ENDCAP, hCalEndCapParameters); - this->SetDefaultSubDetectorParameters(*const_cast(getExtension( ( dd4hep::DetType::CALORIMETER | dd4hep::DetType::MUON | dd4hep::DetType::BARREL), ( dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD ) )), "MuonBarrel", pandora::MUON_BARREL, muonBarrelParameters); - this->SetDefaultSubDetectorParameters(*const_cast(getExtension( ( dd4hep::DetType::CALORIMETER | dd4hep::DetType::MUON | dd4hep::DetType::ENDCAP), ( dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD ) )), "MuonEndCap", pandora::MUON_ENDCAP, muonEndCapParameters); - - subDetectorTypeMap[pandora::ECAL_BARREL] = eCalBarrelParameters; - subDetectorTypeMap[pandora::ECAL_ENDCAP] = eCalEndCapParameters; - subDetectorTypeMap[pandora::HCAL_BARREL] = hCalBarrelParameters; - subDetectorTypeMap[pandora::HCAL_ENDCAP] = hCalEndCapParameters; - subDetectorTypeMap[pandora::MUON_BARREL] = muonBarrelParameters; - subDetectorTypeMap[pandora::MUON_ENDCAP] = muonEndCapParameters; - - PandoraApi::Geometry::SubDetector::Parameters trackerParameters; - - trackerParameters.m_subDetectorName = "Tracker"; - trackerParameters.m_subDetectorType = pandora::INNER_TRACKER; - trackerParameters.m_innerRCoordinate = getTrackingRegionExtent()[0]; - trackerParameters.m_innerZCoordinate = 0.f; - trackerParameters.m_innerPhiCoordinate = 0.f; - trackerParameters.m_innerSymmetryOrder = 0; - trackerParameters.m_outerRCoordinate = getTrackingRegionExtent()[1]; - trackerParameters.m_outerZCoordinate = getTrackingRegionExtent()[2]; - trackerParameters.m_outerPhiCoordinate = 0.f; - trackerParameters.m_outerSymmetryOrder = 0; - trackerParameters.m_isMirroredInZ = true; - trackerParameters.m_nLayers = 0; - subDetectorTypeMap[pandora::INNER_TRACKER] = trackerParameters; - - - ///FIXME:Implement a parameter for the Coil/Solenoid name - ///NOTE: Is this the way to go, or should we go with reco structure? - try{ - - PandoraApi::Geometry::SubDetector::Parameters coilParameters; - - const dd4hep::rec::LayeredCalorimeterData * coilExtension= getExtension( ( dd4hep::DetType::COIL ) ); - - - - coilParameters.m_subDetectorName = "Coil"; - coilParameters.m_subDetectorType = pandora::COIL; - coilParameters.m_innerRCoordinate = coilExtension->extent[0]/ dd4hep::mm; - coilParameters.m_innerZCoordinate = 0.f; - coilParameters.m_innerPhiCoordinate = 0.f; - coilParameters.m_innerSymmetryOrder = 0; - coilParameters.m_outerRCoordinate = coilExtension->extent[1]/ dd4hep::mm; - coilParameters.m_outerZCoordinate = coilExtension->extent[3]/ dd4hep::mm; - coilParameters.m_outerPhiCoordinate = 0.f; - coilParameters.m_outerSymmetryOrder = 0; - coilParameters.m_isMirroredInZ = true; - coilParameters.m_nLayers = 0; - subDetectorTypeMap[pandora::COIL] = coilParameters; - } catch ( std::exception & e ) { - - streamlog_out(ERROR) << "Failed to access COIL parameters: "<SetDefaultSubDetectorParameters( + *const_cast( + getExtension((dd4hep::DetType::CALORIMETER | dd4hep::DetType::ELECTROMAGNETIC | dd4hep::DetType::BARREL), + (dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD))), + "ECalBarrel", pandora::ECAL_BARREL, eCalBarrelParameters); + this->SetDefaultSubDetectorParameters( + *const_cast( + getExtension((dd4hep::DetType::CALORIMETER | dd4hep::DetType::ELECTROMAGNETIC | dd4hep::DetType::ENDCAP), + (dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD))), + "ECalEndCap", pandora::ECAL_ENDCAP, eCalEndCapParameters); + this->SetDefaultSubDetectorParameters( + *const_cast( + getExtension((dd4hep::DetType::CALORIMETER | dd4hep::DetType::HADRONIC | dd4hep::DetType::BARREL), + (dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD))), + "HCalBarrel", pandora::HCAL_BARREL, hCalBarrelParameters); + this->SetDefaultSubDetectorParameters( + *const_cast( + getExtension((dd4hep::DetType::CALORIMETER | dd4hep::DetType::HADRONIC | dd4hep::DetType::ENDCAP), + (dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD))), + "HCalEndCap", pandora::HCAL_ENDCAP, hCalEndCapParameters); + this->SetDefaultSubDetectorParameters( + *const_cast( + getExtension((dd4hep::DetType::CALORIMETER | dd4hep::DetType::MUON | dd4hep::DetType::BARREL), + (dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD))), + "MuonBarrel", pandora::MUON_BARREL, muonBarrelParameters); + this->SetDefaultSubDetectorParameters( + *const_cast( + getExtension((dd4hep::DetType::CALORIMETER | dd4hep::DetType::MUON | dd4hep::DetType::ENDCAP), + (dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD))), + "MuonEndCap", pandora::MUON_ENDCAP, muonEndCapParameters); + + subDetectorTypeMap[pandora::ECAL_BARREL] = eCalBarrelParameters; + subDetectorTypeMap[pandora::ECAL_ENDCAP] = eCalEndCapParameters; + subDetectorTypeMap[pandora::HCAL_BARREL] = hCalBarrelParameters; + subDetectorTypeMap[pandora::HCAL_ENDCAP] = hCalEndCapParameters; + subDetectorTypeMap[pandora::MUON_BARREL] = muonBarrelParameters; + subDetectorTypeMap[pandora::MUON_ENDCAP] = muonEndCapParameters; + + PandoraApi::Geometry::SubDetector::Parameters trackerParameters; + + trackerParameters.m_subDetectorName = "Tracker"; + trackerParameters.m_subDetectorType = pandora::INNER_TRACKER; + trackerParameters.m_innerRCoordinate = getTrackingRegionExtent()[0]; + trackerParameters.m_innerZCoordinate = 0.f; + trackerParameters.m_innerPhiCoordinate = 0.f; + trackerParameters.m_innerSymmetryOrder = 0; + trackerParameters.m_outerRCoordinate = getTrackingRegionExtent()[1]; + trackerParameters.m_outerZCoordinate = getTrackingRegionExtent()[2]; + trackerParameters.m_outerPhiCoordinate = 0.f; + trackerParameters.m_outerSymmetryOrder = 0; + trackerParameters.m_isMirroredInZ = true; + trackerParameters.m_nLayers = 0; + subDetectorTypeMap[pandora::INNER_TRACKER] = trackerParameters; + + ///FIXME:Implement a parameter for the Coil/Solenoid name + ///NOTE: Is this the way to go, or should we go with reco structure? + try { + PandoraApi::Geometry::SubDetector::Parameters coilParameters; + + const dd4hep::rec::LayeredCalorimeterData* coilExtension = getExtension((dd4hep::DetType::COIL)); + + coilParameters.m_subDetectorName = "Coil"; + coilParameters.m_subDetectorType = pandora::COIL; + coilParameters.m_innerRCoordinate = coilExtension->extent[0] / dd4hep::mm; + coilParameters.m_innerZCoordinate = 0.f; + coilParameters.m_innerPhiCoordinate = 0.f; + coilParameters.m_innerSymmetryOrder = 0; + coilParameters.m_outerRCoordinate = coilExtension->extent[1] / dd4hep::mm; + coilParameters.m_outerZCoordinate = coilExtension->extent[3] / dd4hep::mm; + coilParameters.m_outerPhiCoordinate = 0.f; + coilParameters.m_outerSymmetryOrder = 0; + coilParameters.m_isMirroredInZ = true; + coilParameters.m_nLayers = 0; + subDetectorTypeMap[pandora::COIL] = coilParameters; + } catch (std::exception& e) { + streamlog_out(ERROR) << "Failed to access COIL parameters: " << e.what() << std::endl; + } } //------------------------------------------------------------------------------------------------------------------------------------------ -void DDGeometryCreator::SetAdditionalSubDetectorParameters(SubDetectorNameMap &subDetectorNameMap) const -{ - - dd4hep::Detector & mainDetector = dd4hep::Detector::getInstance(); - const std::vector< dd4hep::DetElement>& theECalOtherDetectors = dd4hep::DetectorSelector(mainDetector).detectors(dd4hep::DetType::CALORIMETER | dd4hep::DetType::ELECTROMAGNETIC | dd4hep::DetType::AUXILIARY ) ; - for (std::vector< dd4hep::DetElement>::const_iterator iter = theECalOtherDetectors.begin(), iterEnd = theECalOtherDetectors.end();iter != iterEnd; ++iter){ - try - { - const dd4hep::DetElement& theDetector = *iter; - const dd4hep::rec::LayeredCalorimeterData * theExtension = theDetector.extension(); - - PandoraApi::Geometry::SubDetector::Parameters parameters; - this->SetDefaultSubDetectorParameters(*const_cast(theExtension),theDetector.name(), pandora::SUB_DETECTOR_OTHER, parameters); - subDetectorNameMap[parameters.m_subDetectorName.Get()] = parameters; - } - catch (std::runtime_error &exception) - { - streamlog_out(WARNING) << "Marlin pandora geometry creator during Other ECal construction: " << exception.what() << std::endl; +void DDGeometryCreator::SetAdditionalSubDetectorParameters(SubDetectorNameMap& subDetectorNameMap) const { + dd4hep::Detector& mainDetector = dd4hep::Detector::getInstance(); + const std::vector& theECalOtherDetectors = + dd4hep::DetectorSelector(mainDetector) + .detectors(dd4hep::DetType::CALORIMETER | dd4hep::DetType::ELECTROMAGNETIC | dd4hep::DetType::AUXILIARY); + for (std::vector::const_iterator iter = theECalOtherDetectors.begin(), + iterEnd = theECalOtherDetectors.end(); + iter != iterEnd; ++iter) { + try { + const dd4hep::DetElement& theDetector = *iter; + const dd4hep::rec::LayeredCalorimeterData* theExtension = + theDetector.extension(); + + PandoraApi::Geometry::SubDetector::Parameters parameters; + this->SetDefaultSubDetectorParameters(*const_cast(theExtension), + theDetector.name(), pandora::SUB_DETECTOR_OTHER, parameters); + subDetectorNameMap[parameters.m_subDetectorName.Get()] = parameters; + } catch (std::runtime_error& exception) { + streamlog_out(WARNING) << "Marlin pandora geometry creator during Other ECal construction: " << exception.what() + << std::endl; } } - - const std::vector< dd4hep::DetElement>& theHCalOtherDetectors = dd4hep::DetectorSelector(mainDetector).detectors(dd4hep::DetType::CALORIMETER | dd4hep::DetType::HADRONIC | dd4hep::DetType::AUXILIARY ) ; - for (std::vector< dd4hep::DetElement>::const_iterator iter = theHCalOtherDetectors.begin(), iterEnd = theHCalOtherDetectors.end();iter != iterEnd; ++iter){ - try - { - const dd4hep::DetElement& theDetector = *iter; - const dd4hep::rec::LayeredCalorimeterData * theExtension = theDetector.extension(); - - PandoraApi::Geometry::SubDetector::Parameters parameters; - this->SetDefaultSubDetectorParameters(*const_cast(theExtension),theDetector.name(), pandora::SUB_DETECTOR_OTHER, parameters); - subDetectorNameMap[parameters.m_subDetectorName.Get()] = parameters; - } - catch (std::runtime_error &exception) - { - streamlog_out(WARNING) << "Marlin pandora geometry creator during Other HCal construction: " << exception.what() << std::endl; + + const std::vector& theHCalOtherDetectors = + dd4hep::DetectorSelector(mainDetector) + .detectors(dd4hep::DetType::CALORIMETER | dd4hep::DetType::HADRONIC | dd4hep::DetType::AUXILIARY); + for (std::vector::const_iterator iter = theHCalOtherDetectors.begin(), + iterEnd = theHCalOtherDetectors.end(); + iter != iterEnd; ++iter) { + try { + const dd4hep::DetElement& theDetector = *iter; + const dd4hep::rec::LayeredCalorimeterData* theExtension = + theDetector.extension(); + + PandoraApi::Geometry::SubDetector::Parameters parameters; + this->SetDefaultSubDetectorParameters(*const_cast(theExtension), + theDetector.name(), pandora::SUB_DETECTOR_OTHER, parameters); + subDetectorNameMap[parameters.m_subDetectorName.Get()] = parameters; + } catch (std::runtime_error& exception) { + streamlog_out(WARNING) << "Marlin pandora geometry creator during Other HCal construction: " << exception.what() + << std::endl; } } - - const std::vector< dd4hep::DetElement>& theMuonOtherDetectors = dd4hep::DetectorSelector(mainDetector).detectors(dd4hep::DetType::CALORIMETER | dd4hep::DetType::MUON| dd4hep::DetType::AUXILIARY ) ; - for (std::vector< dd4hep::DetElement>::const_iterator iter = theMuonOtherDetectors.begin(), iterEnd = theMuonOtherDetectors.end();iter != iterEnd; ++iter){ - try - { - const dd4hep::DetElement& theDetector = *iter; - const dd4hep::rec::LayeredCalorimeterData * theExtension = theDetector.extension(); - - PandoraApi::Geometry::SubDetector::Parameters parameters; - this->SetDefaultSubDetectorParameters(*const_cast(theExtension),theDetector.name(), pandora::SUB_DETECTOR_OTHER, parameters); - subDetectorNameMap[parameters.m_subDetectorName.Get()] = parameters; - } - catch (std::runtime_error &exception) - { - streamlog_out(WARNING) << "Marlin pandora geometry creator during Other Muon construction: " << exception.what() << std::endl; + + const std::vector& theMuonOtherDetectors = + dd4hep::DetectorSelector(mainDetector) + .detectors(dd4hep::DetType::CALORIMETER | dd4hep::DetType::MUON | dd4hep::DetType::AUXILIARY); + for (std::vector::const_iterator iter = theMuonOtherDetectors.begin(), + iterEnd = theMuonOtherDetectors.end(); + iter != iterEnd; ++iter) { + try { + const dd4hep::DetElement& theDetector = *iter; + const dd4hep::rec::LayeredCalorimeterData* theExtension = + theDetector.extension(); + + PandoraApi::Geometry::SubDetector::Parameters parameters; + this->SetDefaultSubDetectorParameters(*const_cast(theExtension), + theDetector.name(), pandora::SUB_DETECTOR_OTHER, parameters); + subDetectorNameMap[parameters.m_subDetectorName.Get()] = parameters; + } catch (std::runtime_error& exception) { + streamlog_out(WARNING) << "Marlin pandora geometry creator during Other Muon construction: " << exception.what() + << std::endl; } } - } //------------------------------------------------------------------------------------------------------------------------------------------ -void DDGeometryCreator::SetDefaultSubDetectorParameters(const dd4hep::rec::LayeredCalorimeterData &inputParameters, const std::string &subDetectorName, - const pandora::SubDetectorType subDetectorType, PandoraApi::Geometry::SubDetector::Parameters ¶meters) const -{ - const std::vector& layers= inputParameters.layers; - - parameters.m_subDetectorName = subDetectorName; - parameters.m_subDetectorType = subDetectorType; - parameters.m_innerRCoordinate = inputParameters.extent[0]/dd4hep::mm; - parameters.m_innerZCoordinate = inputParameters.extent[2]/dd4hep::mm; - parameters.m_innerPhiCoordinate = inputParameters.inner_phi0/dd4hep::rad; - parameters.m_innerSymmetryOrder = inputParameters.inner_symmetry; - parameters.m_outerRCoordinate = inputParameters.extent[1]/dd4hep::mm; - parameters.m_outerZCoordinate = inputParameters.extent[3]/dd4hep::mm; - parameters.m_outerPhiCoordinate = inputParameters.outer_phi0/dd4hep::rad; - parameters.m_outerSymmetryOrder = inputParameters.outer_symmetry; - parameters.m_isMirroredInZ = true; - parameters.m_nLayers = layers.size(); - - for (size_t i = 0; i< layers.size(); i++) - { - const dd4hep::rec::LayeredCalorimeterStruct::Layer & theLayer = layers.at(i); - - PandoraApi::Geometry::LayerParameters layerParameters; - - double totalNumberOfRadLengths = theLayer.inner_nRadiationLengths; - double totalNumberOfIntLengths = theLayer.inner_nInteractionLengths; - - if(i>0){ - //Add the numbers from previous layer's outer side - totalNumberOfRadLengths += layers.at(i-1).outer_nRadiationLengths; - totalNumberOfIntLengths += layers.at(i-1).outer_nInteractionLengths; - - } - - layerParameters.m_closestDistanceToIp = (theLayer.distance+theLayer.inner_thickness)/dd4hep::mm; //Distance to center of sensitive element - layerParameters.m_nRadiationLengths = totalNumberOfRadLengths; - layerParameters.m_nInteractionLengths = totalNumberOfIntLengths; - - parameters.m_layerParametersVector.push_back(layerParameters); +void DDGeometryCreator::SetDefaultSubDetectorParameters( + const dd4hep::rec::LayeredCalorimeterData& inputParameters, const std::string& subDetectorName, + const pandora::SubDetectorType subDetectorType, PandoraApi::Geometry::SubDetector::Parameters& parameters) const { + const std::vector& layers = inputParameters.layers; + + parameters.m_subDetectorName = subDetectorName; + parameters.m_subDetectorType = subDetectorType; + parameters.m_innerRCoordinate = inputParameters.extent[0] / dd4hep::mm; + parameters.m_innerZCoordinate = inputParameters.extent[2] / dd4hep::mm; + parameters.m_innerPhiCoordinate = inputParameters.inner_phi0 / dd4hep::rad; + parameters.m_innerSymmetryOrder = inputParameters.inner_symmetry; + parameters.m_outerRCoordinate = inputParameters.extent[1] / dd4hep::mm; + parameters.m_outerZCoordinate = inputParameters.extent[3] / dd4hep::mm; + parameters.m_outerPhiCoordinate = inputParameters.outer_phi0 / dd4hep::rad; + parameters.m_outerSymmetryOrder = inputParameters.outer_symmetry; + parameters.m_isMirroredInZ = true; + parameters.m_nLayers = layers.size(); + + for (size_t i = 0; i < layers.size(); i++) { + const dd4hep::rec::LayeredCalorimeterStruct::Layer& theLayer = layers.at(i); + + PandoraApi::Geometry::LayerParameters layerParameters; + + double totalNumberOfRadLengths = theLayer.inner_nRadiationLengths; + double totalNumberOfIntLengths = theLayer.inner_nInteractionLengths; + + if (i > 0) { + //Add the numbers from previous layer's outer side + totalNumberOfRadLengths += layers.at(i - 1).outer_nRadiationLengths; + totalNumberOfIntLengths += layers.at(i - 1).outer_nInteractionLengths; } + + layerParameters.m_closestDistanceToIp = + (theLayer.distance + theLayer.inner_thickness) / dd4hep::mm; //Distance to center of sensitive element + layerParameters.m_nRadiationLengths = totalNumberOfRadLengths; + layerParameters.m_nInteractionLengths = totalNumberOfIntLengths; + + parameters.m_layerParametersVector.push_back(layerParameters); + } } //------------------------------------------------------------------------------------------------------------------------------------------ -pandora::StatusCode DDGeometryCreator::SetILDSpecificGeometry(SubDetectorTypeMap &/*subDetectorTypeMap*/, SubDetectorNameMap &/*subDetectorNameMap*/) const -{ - streamlog_out(DEBUG0) << " Building gaps in detector active material"<CreateHCalBarrelBoxGaps()); - PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, this->CreateHCalEndCapBoxGaps()); - PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, this->CreateHCalBarrelConcentricGaps()); +pandora::StatusCode DDGeometryCreator::SetILDSpecificGeometry(SubDetectorTypeMap& /*subDetectorTypeMap*/, + SubDetectorNameMap& /*subDetectorNameMap*/) const { + streamlog_out(DEBUG0) << " Building gaps in detector active material" << std::endl; + // Gaps in detector active material + PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, this->CreateHCalBarrelBoxGaps()); + PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, this->CreateHCalEndCapBoxGaps()); + PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, this->CreateHCalBarrelConcentricGaps()); - return pandora::STATUS_CODE_SUCCESS; + return pandora::STATUS_CODE_SUCCESS; } //------------------------------------------------------------------------------------------------------------------------------------------ +pandora::StatusCode DDGeometryCreator::CreateHCalBarrelBoxGaps() const { + dd4hep::Detector& mainDetector = dd4hep::Detector::getInstance(); + std::string detectorName = mainDetector.header().name(); + const dd4hep::rec::LayeredCalorimeterData* hCalBarrelParameters = + getExtension((dd4hep::DetType::CALORIMETER | dd4hep::DetType::HADRONIC | dd4hep::DetType::BARREL), + (dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD)); -pandora::StatusCode DDGeometryCreator::CreateHCalBarrelBoxGaps() const -{ - dd4hep::Detector& mainDetector = dd4hep::Detector::getInstance(); - - std::string detectorName = mainDetector.header().name(); - - const dd4hep::rec::LayeredCalorimeterData * hCalBarrelParameters = getExtension(( dd4hep::DetType::CALORIMETER | dd4hep::DetType::HADRONIC | dd4hep::DetType::BARREL), ( dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD )); + const unsigned int innerSymmetryOrder(hCalBarrelParameters->inner_symmetry); + const unsigned int outerSymmetryOrder(hCalBarrelParameters->outer_symmetry); - const unsigned int innerSymmetryOrder(hCalBarrelParameters->inner_symmetry); - const unsigned int outerSymmetryOrder(hCalBarrelParameters->outer_symmetry); - - if ((0 == innerSymmetryOrder) || (2 != outerSymmetryOrder / innerSymmetryOrder)) - { - streamlog_out(ERROR) << " Detector " << detectorName << " doesn't conform to expected ILD-specific geometry: innerSymmetryOrder : "<extent[0]/dd4hep::mm); - const float outerRadius(hCalBarrelParameters->extent[1]/dd4hep::mm); - const float outerZ(hCalBarrelParameters->extent[3]/dd4hep::mm); - const float inner_phi0(hCalBarrelParameters->inner_phi0/dd4hep::rad); + const float innerRadius(hCalBarrelParameters->extent[0] / dd4hep::mm); + const float outerRadius(hCalBarrelParameters->extent[1] / dd4hep::mm); + const float outerZ(hCalBarrelParameters->extent[3] / dd4hep::mm); + const float inner_phi0(hCalBarrelParameters->inner_phi0 / dd4hep::rad); - const float staveGap(hCalBarrelParameters->gap0/dd4hep::mm); - PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, this->CreateRegularBoxGaps(innerSymmetryOrder, inner_phi0, innerRadius, outerRadius, - -outerZ, outerZ, staveGap)); + const float staveGap(hCalBarrelParameters->gap0 / dd4hep::mm); + PANDORA_RETURN_RESULT_IF( + pandora::STATUS_CODE_SUCCESS, !=, + this->CreateRegularBoxGaps(innerSymmetryOrder, inner_phi0, innerRadius, outerRadius, -outerZ, outerZ, staveGap)); - const float outerPseudoPhi0(M_PI / static_cast(innerSymmetryOrder)); - const float cosOuterPseudoPhi0(std::cos(outerPseudoPhi0)); + const float outerPseudoPhi0(M_PI / static_cast(innerSymmetryOrder)); + const float cosOuterPseudoPhi0(std::cos(outerPseudoPhi0)); - if ((0 == outerPseudoPhi0) || (0.f == cosOuterPseudoPhi0)) - { - streamlog_out(ERROR) << " Detector " << detectorName << " doesn't conform to expected ILD-specific geometry" << std::endl; - return pandora::STATUS_CODE_INVALID_PARAMETER; - } + if ((0 == outerPseudoPhi0) || (0.f == cosOuterPseudoPhi0)) { + streamlog_out(ERROR) << " Detector " << detectorName << " doesn't conform to expected ILD-specific geometry" + << std::endl; + return pandora::STATUS_CODE_INVALID_PARAMETER; + } - const float middleStaveGap(hCalBarrelParameters->gap1/dd4hep::mm); + const float middleStaveGap(hCalBarrelParameters->gap1 / dd4hep::mm); - PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, this->CreateRegularBoxGaps(innerSymmetryOrder, outerPseudoPhi0, - innerRadius / cosOuterPseudoPhi0, outerRadius, -outerZ, outerZ, middleStaveGap)); + PANDORA_RETURN_RESULT_IF( + pandora::STATUS_CODE_SUCCESS, !=, + this->CreateRegularBoxGaps(innerSymmetryOrder, outerPseudoPhi0, innerRadius / cosOuterPseudoPhi0, outerRadius, + -outerZ, outerZ, middleStaveGap)); - return pandora::STATUS_CODE_SUCCESS; + return pandora::STATUS_CODE_SUCCESS; } //------------------------------------------------------------------------------------------------------------------------------------------ -pandora::StatusCode DDGeometryCreator::CreateHCalEndCapBoxGaps() const -{ - - - const dd4hep::rec::LayeredCalorimeterData * hCalEndCapParameters = getExtension(( dd4hep::DetType::CALORIMETER | dd4hep::DetType::HADRONIC | dd4hep::DetType::ENDCAP), ( dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD )); - - const float staveGap(hCalEndCapParameters->gap0/dd4hep::mm); - const float innerRadius(hCalEndCapParameters->extent[0]/dd4hep::mm); - const float outerRadius(hCalEndCapParameters->extent[1]/dd4hep::mm); - const float innerZ(hCalEndCapParameters->extent[2]/dd4hep::mm); - const float outerZ(hCalEndCapParameters->extent[3]/dd4hep::mm); - const unsigned int innerSymmetryOrder(hCalEndCapParameters->inner_symmetry); - const float inner_phi0(hCalEndCapParameters->inner_phi0/dd4hep::rad); - - PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, this->CreateRegularBoxGaps(innerSymmetryOrder, - inner_phi0, innerRadius, outerRadius, innerZ, outerZ, staveGap, - pandora::CartesianVector(-innerRadius, 0, 0))); - - PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, this->CreateRegularBoxGaps(innerSymmetryOrder, - inner_phi0, innerRadius, outerRadius, -outerZ, -innerZ, staveGap, - pandora::CartesianVector(innerRadius, 0, 0))); - - return pandora::STATUS_CODE_SUCCESS; +pandora::StatusCode DDGeometryCreator::CreateHCalEndCapBoxGaps() const { + const dd4hep::rec::LayeredCalorimeterData* hCalEndCapParameters = + getExtension((dd4hep::DetType::CALORIMETER | dd4hep::DetType::HADRONIC | dd4hep::DetType::ENDCAP), + (dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD)); + + const float staveGap(hCalEndCapParameters->gap0 / dd4hep::mm); + const float innerRadius(hCalEndCapParameters->extent[0] / dd4hep::mm); + const float outerRadius(hCalEndCapParameters->extent[1] / dd4hep::mm); + const float innerZ(hCalEndCapParameters->extent[2] / dd4hep::mm); + const float outerZ(hCalEndCapParameters->extent[3] / dd4hep::mm); + const unsigned int innerSymmetryOrder(hCalEndCapParameters->inner_symmetry); + const float inner_phi0(hCalEndCapParameters->inner_phi0 / dd4hep::rad); + + PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, + this->CreateRegularBoxGaps(innerSymmetryOrder, inner_phi0, innerRadius, outerRadius, innerZ, + outerZ, staveGap, pandora::CartesianVector(-innerRadius, 0, 0))); + + PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, + this->CreateRegularBoxGaps(innerSymmetryOrder, inner_phi0, innerRadius, outerRadius, -outerZ, + -innerZ, staveGap, pandora::CartesianVector(innerRadius, 0, 0))); + + return pandora::STATUS_CODE_SUCCESS; } //------------------------------------------------------------------------------------------------------------------------------------------ -pandora::StatusCode DDGeometryCreator::CreateHCalBarrelConcentricGaps() const -{ - - - const dd4hep::rec::LayeredCalorimeterData *hCalBarrelParameters = getExtension(( dd4hep::DetType::CALORIMETER | dd4hep::DetType::HADRONIC | dd4hep::DetType::BARREL), ( dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD )); - const float gapWidth(hCalBarrelParameters->gap0/dd4hep::mm); +pandora::StatusCode DDGeometryCreator::CreateHCalBarrelConcentricGaps() const { + const dd4hep::rec::LayeredCalorimeterData* hCalBarrelParameters = + getExtension((dd4hep::DetType::CALORIMETER | dd4hep::DetType::HADRONIC | dd4hep::DetType::BARREL), + (dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD)); + const float gapWidth(hCalBarrelParameters->gap0 / dd4hep::mm); - PandoraApi::Geometry::ConcentricGap::Parameters gapParameters; + PandoraApi::Geometry::ConcentricGap::Parameters gapParameters; - gapParameters.m_minZCoordinate = -0.5f * gapWidth; - gapParameters.m_maxZCoordinate = 0.5f * gapWidth; - gapParameters.m_innerRCoordinate = hCalBarrelParameters->extent[0]/dd4hep::mm; - gapParameters.m_innerPhiCoordinate = hCalBarrelParameters->inner_phi0/dd4hep::rad; - gapParameters.m_innerSymmetryOrder = hCalBarrelParameters->inner_symmetry; - gapParameters.m_outerRCoordinate = hCalBarrelParameters->extent[1]/dd4hep::mm; - gapParameters.m_outerPhiCoordinate = hCalBarrelParameters->outer_phi0/dd4hep::rad; - gapParameters.m_outerSymmetryOrder = hCalBarrelParameters->outer_symmetry; + gapParameters.m_minZCoordinate = -0.5f * gapWidth; + gapParameters.m_maxZCoordinate = 0.5f * gapWidth; + gapParameters.m_innerRCoordinate = hCalBarrelParameters->extent[0] / dd4hep::mm; + gapParameters.m_innerPhiCoordinate = hCalBarrelParameters->inner_phi0 / dd4hep::rad; + gapParameters.m_innerSymmetryOrder = hCalBarrelParameters->inner_symmetry; + gapParameters.m_outerRCoordinate = hCalBarrelParameters->extent[1] / dd4hep::mm; + gapParameters.m_outerPhiCoordinate = hCalBarrelParameters->outer_phi0 / dd4hep::rad; + gapParameters.m_outerSymmetryOrder = hCalBarrelParameters->outer_symmetry; - PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::Geometry::ConcentricGap::Create(m_pPandora, gapParameters)); + PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, + PandoraApi::Geometry::ConcentricGap::Create(m_pPandora, gapParameters)); - return pandora::STATUS_CODE_SUCCESS; + return pandora::STATUS_CODE_SUCCESS; } //------------------------------------------------------------------------------------------------------------------------------------------ -pandora::StatusCode DDGeometryCreator::CreateRegularBoxGaps(unsigned int symmetryOrder, float phi0, float innerRadius, float outerRadius, - float minZ, float maxZ, float gapWidth, pandora::CartesianVector vertexOffset) const -{ - const pandora::CartesianVector basicGapVertex(pandora::CartesianVector(-0.5f * gapWidth, innerRadius, minZ) + vertexOffset); - const pandora::CartesianVector basicSide1(gapWidth, 0, 0); - const pandora::CartesianVector basicSide2(0, outerRadius - innerRadius, 0); - const pandora::CartesianVector basicSide3(0, 0, maxZ - minZ); - - for (unsigned int i = 0; i < symmetryOrder; ++i) - { - const float phi = phi0 + (2. * M_PI * static_cast(i) / static_cast(symmetryOrder)); - const float sinPhi(std::sin(phi)); - const float cosPhi(std::cos(phi)); - - PandoraApi::Geometry::BoxGap::Parameters gapParameters; - - gapParameters.m_vertex = pandora::CartesianVector(cosPhi * basicGapVertex.GetX() + sinPhi * basicGapVertex.GetY(), - -sinPhi * basicGapVertex.GetX() + cosPhi * basicGapVertex.GetY(), basicGapVertex.GetZ()); - gapParameters.m_side1 = pandora::CartesianVector(cosPhi * basicSide1.GetX() + sinPhi * basicSide1.GetY(), - -sinPhi * basicSide1.GetX() + cosPhi * basicSide1.GetY(), basicSide1.GetZ()); - gapParameters.m_side2 = pandora::CartesianVector(cosPhi * basicSide2.GetX() + sinPhi * basicSide2.GetY(), - -sinPhi * basicSide2.GetX() + cosPhi * basicSide2.GetY(), basicSide2.GetZ()); - gapParameters.m_side3 = pandora::CartesianVector(cosPhi * basicSide3.GetX() + sinPhi * basicSide3.GetY(), - -sinPhi * basicSide3.GetX() + cosPhi * basicSide3.GetY(), basicSide3.GetZ()); - - PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::Geometry::BoxGap::Create(m_pPandora, gapParameters)); - } +pandora::StatusCode DDGeometryCreator::CreateRegularBoxGaps(unsigned int symmetryOrder, float phi0, float innerRadius, + float outerRadius, float minZ, float maxZ, float gapWidth, + pandora::CartesianVector vertexOffset) const { + const pandora::CartesianVector basicGapVertex(pandora::CartesianVector(-0.5f * gapWidth, innerRadius, minZ) + + vertexOffset); + const pandora::CartesianVector basicSide1(gapWidth, 0, 0); + const pandora::CartesianVector basicSide2(0, outerRadius - innerRadius, 0); + const pandora::CartesianVector basicSide3(0, 0, maxZ - minZ); + + for (unsigned int i = 0; i < symmetryOrder; ++i) { + const float phi = phi0 + (2. * M_PI * static_cast(i) / static_cast(symmetryOrder)); + const float sinPhi(std::sin(phi)); + const float cosPhi(std::cos(phi)); + + PandoraApi::Geometry::BoxGap::Parameters gapParameters; + + gapParameters.m_vertex = pandora::CartesianVector(cosPhi * basicGapVertex.GetX() + sinPhi * basicGapVertex.GetY(), + -sinPhi * basicGapVertex.GetX() + cosPhi * basicGapVertex.GetY(), + basicGapVertex.GetZ()); + gapParameters.m_side1 = + pandora::CartesianVector(cosPhi * basicSide1.GetX() + sinPhi * basicSide1.GetY(), + -sinPhi * basicSide1.GetX() + cosPhi * basicSide1.GetY(), basicSide1.GetZ()); + gapParameters.m_side2 = + pandora::CartesianVector(cosPhi * basicSide2.GetX() + sinPhi * basicSide2.GetY(), + -sinPhi * basicSide2.GetX() + cosPhi * basicSide2.GetY(), basicSide2.GetZ()); + gapParameters.m_side3 = + pandora::CartesianVector(cosPhi * basicSide3.GetX() + sinPhi * basicSide3.GetY(), + -sinPhi * basicSide3.GetX() + cosPhi * basicSide3.GetY(), basicSide3.GetZ()); + + PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, + PandoraApi::Geometry::BoxGap::Create(m_pPandora, gapParameters)); + } - return pandora::STATUS_CODE_SUCCESS; + return pandora::STATUS_CODE_SUCCESS; } //------------------------------------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------------------------------------ -DDGeometryCreator::Settings::Settings() : - m_createGaps(false) -{ -} +DDGeometryCreator::Settings::Settings() : m_createGaps(false) {} diff --git a/k4GaudiPandora/src/DDMCParticleCreator.cc b/k4GaudiPandora/src/DDMCParticleCreator.cc index b0d5b7d..40ea0e2 100644 --- a/k4GaudiPandora/src/DDMCParticleCreator.cc +++ b/k4GaudiPandora/src/DDMCParticleCreator.cc @@ -1,234 +1,234 @@ +/* + * Copyright (c) 2020-2024 Key4hep-Project. + * + * This file is part of Key4hep. + * See https://key4hep.github.io/key4hep-doc/ for further info. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + /** * @file DDMarlinPandora/src/DDMCParticleCreator.cc - * + * * @brief Implementation of the mc particle creator class. - * + * * $Log: $ */ #include "Gaudi/Property.h" #include "GaudiAlg/Transformer.h" // Define BaseClass_t +#include "edm4hep/CaloHitContribution.h" +#include "edm4hep/MCParticle.h" +#include "edm4hep/MCRecoCaloAssociation.h" +#include "edm4hep/MCRecoTrackerAssociation.h" +#include "edm4hep/SimCalorimeterHit.h" +#include "edm4hep/SimTrackerHit.h" +#include "edm4hep/Track.h" #include "k4FWCore/BaseClass.h" -#include "edm4hep/MCParticle.h" -#include "edm4hep/MCRecoCaloAssociation.h" -#include "edm4hep/SimCalorimeterHit.h" -#include "edm4hep/CaloHitContribution.h" -#include "edm4hep/Track.h" -#include "edm4hep/MCRecoTrackerAssociation.h" -#include "edm4hep/SimTrackerHit.h" -#include "PandoraPFAlg.h" #include "DDMCParticleCreator.h" +#include "PandoraPFAlg.h" #include //forward declarations. See in DDPandoraPFANewProcessor.cc double getFieldFromCompact(); - -DDMCParticleCreator::DDMCParticleCreator(const Settings &settings, const pandora::Pandora *const pPandora) : - m_settings(settings), - m_pandora(*pPandora), - m_bField(getFieldFromCompact()) -{ -} +DDMCParticleCreator::DDMCParticleCreator(const Settings& settings, const pandora::Pandora* const pPandora) + : m_settings(settings), m_pandora(*pPandora), m_bField(getFieldFromCompact()) {} //------------------------------------------------------------------------------------------------------------------------------------------ -DDMCParticleCreator::~DDMCParticleCreator() -{ -} +DDMCParticleCreator::~DDMCParticleCreator() {} //------------------------------------------------------------------------------------------------------------------------------------------ -pandora::StatusCode DDMCParticleCreator::CreateMCParticles(const EVENT::LCEvent *const pLCEvent) const -{ - for (StringVector::const_iterator iter = m_settings.m_mcParticleCollections.begin(), iterEnd = m_settings.m_mcParticleCollections.end(); - iter != iterEnd; ++iter) - { - try - { - const EVENT::LCCollection *pMCParticleCollection = pLCEvent->getCollection(*iter); - - for (int i = 0, iMax = pMCParticleCollection->getNumberOfElements(); i < iMax; ++i) - { - try - { - EVENT::MCParticle *pMcParticle = dynamic_cast(pMCParticleCollection->getElementAt(i)); - - if (NULL == pMcParticle) - throw EVENT::Exception("Collection type mismatch"); - - PandoraApi::MCParticle::Parameters mcParticleParameters; - mcParticleParameters.m_energy = pMcParticle->getEnergy(); - mcParticleParameters.m_particleId = pMcParticle->getPDG(); - mcParticleParameters.m_mcParticleType = pandora::MC_3D; - mcParticleParameters.m_pParentAddress = pMcParticle; - mcParticleParameters.m_momentum = pandora::CartesianVector(pMcParticle->getMomentum()[0], pMcParticle->getMomentum()[1], - pMcParticle->getMomentum()[2]); - mcParticleParameters.m_vertex = pandora::CartesianVector(pMcParticle->getVertex()[0], pMcParticle->getVertex()[1], - pMcParticle->getVertex()[2]); - mcParticleParameters.m_endpoint = pandora::CartesianVector(pMcParticle->getEndpoint()[0], pMcParticle->getEndpoint()[1], - pMcParticle->getEndpoint()[2]); - - PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::MCParticle::Create(m_pandora, mcParticleParameters)); - - // Create parent-daughter relationships - for(MCParticleVec::const_iterator itDaughter = pMcParticle->getDaughters().begin(), - itDaughterEnd = pMcParticle->getDaughters().end(); itDaughter != itDaughterEnd; ++itDaughter) - { - PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::SetMCParentDaughterRelationship(m_pandora, - pMcParticle, *itDaughter)); - } - } - catch (pandora::StatusCodeException &statusCodeException) - { - streamlog_out(ERROR) << "Failed to extract MCParticle: " << statusCodeException.ToString() << std::endl; - } - catch (EVENT::Exception &exception) - { - streamlog_out(WARNING) << "Failed to extract MCParticle: " << exception.what() << std::endl; - } - } - } - catch (EVENT::Exception &exception) - { - streamlog_out(DEBUG5) << "Failed to extract MCParticles collection: " << *iter << ", " << exception.what() << std::endl; +pandora::StatusCode DDMCParticleCreator::CreateMCParticles(const EVENT::LCEvent* const pLCEvent) const { + for (StringVector::const_iterator iter = m_settings.m_mcParticleCollections.begin(), + iterEnd = m_settings.m_mcParticleCollections.end(); + iter != iterEnd; ++iter) { + try { + const EVENT::LCCollection* pMCParticleCollection = pLCEvent->getCollection(*iter); + + for (int i = 0, iMax = pMCParticleCollection->getNumberOfElements(); i < iMax; ++i) { + try { + EVENT::MCParticle* pMcParticle = dynamic_cast(pMCParticleCollection->getElementAt(i)); + + if (NULL == pMcParticle) + throw EVENT::Exception("Collection type mismatch"); + + PandoraApi::MCParticle::Parameters mcParticleParameters; + mcParticleParameters.m_energy = pMcParticle->getEnergy(); + mcParticleParameters.m_particleId = pMcParticle->getPDG(); + mcParticleParameters.m_mcParticleType = pandora::MC_3D; + mcParticleParameters.m_pParentAddress = pMcParticle; + mcParticleParameters.m_momentum = pandora::CartesianVector( + pMcParticle->getMomentum()[0], pMcParticle->getMomentum()[1], pMcParticle->getMomentum()[2]); + mcParticleParameters.m_vertex = pandora::CartesianVector( + pMcParticle->getVertex()[0], pMcParticle->getVertex()[1], pMcParticle->getVertex()[2]); + mcParticleParameters.m_endpoint = pandora::CartesianVector( + pMcParticle->getEndpoint()[0], pMcParticle->getEndpoint()[1], pMcParticle->getEndpoint()[2]); + + PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, + PandoraApi::MCParticle::Create(m_pandora, mcParticleParameters)); + + // Create parent-daughter relationships + for (MCParticleVec::const_iterator itDaughter = pMcParticle->getDaughters().begin(), + itDaughterEnd = pMcParticle->getDaughters().end(); + itDaughter != itDaughterEnd; ++itDaughter) { + PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, + PandoraApi::SetMCParentDaughterRelationship(m_pandora, pMcParticle, *itDaughter)); + } + } catch (pandora::StatusCodeException& statusCodeException) { + streamlog_out(ERROR) << "Failed to extract MCParticle: " << statusCodeException.ToString() << std::endl; + } catch (EVENT::Exception& exception) { + streamlog_out(WARNING) << "Failed to extract MCParticle: " << exception.what() << std::endl; } + } + } catch (EVENT::Exception& exception) { + streamlog_out(DEBUG5) << "Failed to extract MCParticles collection: " << *iter << ", " << exception.what() + << std::endl; } + } - return pandora::STATUS_CODE_SUCCESS; + return pandora::STATUS_CODE_SUCCESS; } //------------------------------------------------------------------------------------------------------------------------------------------ -pandora::StatusCode DDMCParticleCreator::CreateTrackToMCParticleRelationships(const CollectionMaps& collectionMaps,const TrackVector &trackVector) const -{ - for (unsigned ik = 0; ik < trackVector.size(); ik++) - { - const edm4hep::Track *pTrack = trackVector.at(ik); - // Get reconstructed momentum at dca - const pandora::Helix helixFit(pTrack->getTrackStates(0).phi, pTrack->getTrackStates(0).D0, pTrack->getTrackStates(0).Z0, pTrack->getTrackStates(0).omega, pTrack->getTrackStates(0).tanLambda, m_bField); - const float recoMomentum(helixFit.GetMomentum().GetMagnitude()); - - // Use momentum magnitude to identify best mc particle - edm4hep::MCParticle *pBestMCParticle = NULL; - float bestDeltaMomentum(std::numeric_limits::max()); - try - { - - for (StringVector::const_iterator iter = m_settings.m_TrackRelationCollections.begin(), iterEnd = m_settings.m_TrackRelationCollections.end(); iter != iterEnd; ++iter) - { - if(collectionMaps.collectionMap_TrkRel.find(*iter) == collectionMaps.collectionMap_TrkRel.end()) continue; - const std::vector& pMCRecoTrackerAssociationCollection = (collectionMaps.collectionMap_TrkRel.find(*iter))->second; - for(unsigned ith=0 ; ithtrackerHits_size(); ith++) - { - for(unsigned ic=0; ic < pMCRecoTrackerAssociationCollection.size(); ic++) - { - if( pMCRecoTrackerAssociationCollection.at(ic).getRec().id() != pTrack->getTrackerHits(ith).id() ) continue; - const edm4hep::ConstSimTrackerHit pSimHit = pMCRecoTrackerAssociationCollection.at(ic).getSim(); - const edm4hep::ConstMCParticle ipa = pSimHit.getMCParticle(); - if( m_id_pMC_map->find(ipa.id()) == m_id_pMC_map->end() ) continue; - const float trueMomentum(pandora::CartesianVector(ipa.getMomentum()[0], ipa.getMomentum()[1], ipa.getMomentum()[2]).GetMagnitude()); - const float deltaMomentum(std::fabs(recoMomentum - trueMomentum)); - if (deltaMomentum < bestDeltaMomentum) - { - pBestMCParticle =const_cast((*m_id_pMC_map)[ipa.id()]); - bestDeltaMomentum = deltaMomentum; - } - } - } +pandora::StatusCode DDMCParticleCreator::CreateTrackToMCParticleRelationships(const CollectionMaps& collectionMaps, + const TrackVector& trackVector) const { + for (unsigned ik = 0; ik < trackVector.size(); ik++) { + const edm4hep::Track* pTrack = trackVector.at(ik); + // Get reconstructed momentum at dca + const pandora::Helix helixFit(pTrack->getTrackStates(0).phi, pTrack->getTrackStates(0).D0, + pTrack->getTrackStates(0).Z0, pTrack->getTrackStates(0).omega, + pTrack->getTrackStates(0).tanLambda, m_bField); + const float recoMomentum(helixFit.GetMomentum().GetMagnitude()); + + // Use momentum magnitude to identify best mc particle + edm4hep::MCParticle* pBestMCParticle = NULL; + float bestDeltaMomentum(std::numeric_limits::max()); + try { + for (StringVector::const_iterator iter = m_settings.m_TrackRelationCollections.begin(), + iterEnd = m_settings.m_TrackRelationCollections.end(); + iter != iterEnd; ++iter) { + if (collectionMaps.collectionMap_TrkRel.find(*iter) == collectionMaps.collectionMap_TrkRel.end()) + continue; + const std::vector& pMCRecoTrackerAssociationCollection = + (collectionMaps.collectionMap_TrkRel.find(*iter))->second; + for (unsigned ith = 0; ith < pTrack->trackerHits_size(); ith++) { + for (unsigned ic = 0; ic < pMCRecoTrackerAssociationCollection.size(); ic++) { + if (pMCRecoTrackerAssociationCollection.at(ic).getRec().id() != pTrack->getTrackerHits(ith).id()) + continue; + const edm4hep::ConstSimTrackerHit pSimHit = pMCRecoTrackerAssociationCollection.at(ic).getSim(); + const edm4hep::ConstMCParticle ipa = pSimHit.getMCParticle(); + if (m_id_pMC_map->find(ipa.id()) == m_id_pMC_map->end()) + continue; + const float trueMomentum( + pandora::CartesianVector(ipa.getMomentum()[0], ipa.getMomentum()[1], ipa.getMomentum()[2]) + .GetMagnitude()); + const float deltaMomentum(std::fabs(recoMomentum - trueMomentum)); + if (deltaMomentum < bestDeltaMomentum) { + pBestMCParticle = const_cast((*m_id_pMC_map)[ipa.id()]); + bestDeltaMomentum = deltaMomentum; } - - - if (NULL == pBestMCParticle)continue; - PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::SetTrackToMCParticleRelationship(m_pandora, pTrack, - pBestMCParticle)); - } - catch (pandora::StatusCodeException &statusCodeException) - { - streamlog_out(ERROR) << "Failed to extract track to mc particle relationship: " << statusCodeException.ToString() << std::endl; - } - catch (EVENT::Exception &exception) - { - streamlog_out(WARNING) << "Failed to extract track to mc particle relationship: " << exception.what() << std::endl; - } - - catch (EVENT::Exception &exception) - { - streamlog_out(DEBUG5) << "Failed to extract track to mc particle relationships collection: " << *iter << ", " << exception.what() << std::endl; + } } + } + + if (NULL == pBestMCParticle) + continue; + PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, + PandoraApi::SetTrackToMCParticleRelationship(m_pandora, pTrack, pBestMCParticle)); + } catch (pandora::StatusCodeException& statusCodeException) { + streamlog_out(ERROR) << "Failed to extract track to mc particle relationship: " << statusCodeException.ToString() + << std::endl; + } catch (EVENT::Exception& exception) { + streamlog_out(WARNING) << "Failed to extract track to mc particle relationship: " << exception.what() + << std::endl; } - return pandora::STATUS_CODE_SUCCESS; + catch (EVENT::Exception& exception) { + streamlog_out(DEBUG5) << "Failed to extract track to mc particle relationships collection: " << *iter << ", " + << exception.what() << std::endl; + } + } + + return pandora::STATUS_CODE_SUCCESS; } //------------------------------------------------------------------------------------------------------------------------------------------ -pandora::StatusCode DDMCParticleCreator::CreateCaloHitToMCParticleRelationships(const CollectionMaps& collectionMaps, const CalorimeterHitVector &calorimeterHitVector) const -{ - typedef std::map MCParticleToEnergyWeightMap; - MCParticleToEnergyWeightMap mcParticleToEnergyWeightMap; - - for (StringVector::const_iterator iter = m_settings.m_lcCaloHitRelationCollections.begin(), iterEnd = m_settings.m_lcCaloHitRelationCollections.end(); - iter != iterEnd; ++iter) - { - if(collectionMaps.collectionMap_CaloRel.find(*iter) == collectionMaps.collectionMap_CaloRel.end()) continue; - try - { - const std::vector& pMCRecoCaloAssociationCollection = (collectionMaps.collectionMap_CaloRel.find(*iter))->second; - - for (unsigned i_calo=0; i_calo < calorimeterHitVector.size(); i_calo++) - { - try - { - mcParticleToEnergyWeightMap.clear(); - - for (unsigned ic=0; ic < pMCRecoCaloAssociationCollection.size(); ic++) - { - if( pMCRecoCaloAssociationCollection.at(ic).getRec().id() != (*(calorimeterHitVector.at(i_calo))).id() ) continue; - const edm4hep::ConstSimCalorimeterHit pSimHit = pMCRecoCaloAssociationCollection.at(ic).getSim(); - for (int iCont = 0, iEnd = pSimHit.contributions_size(); iCont < iEnd; ++iCont) - { - edm4hep::ConstCaloHitContribution conb = pSimHit.getContributions(iCont); - const edm4hep::ConstMCParticle ipa = conb.getParticle(); - float ien = conb.getEnergy(); - if( m_id_pMC_map->find(ipa.id()) == m_id_pMC_map->end() ) continue; - const edm4hep::MCParticle * p_tmp = (*m_id_pMC_map)[ipa.id()]; - mcParticleToEnergyWeightMap[p_tmp] += ien; - } - } - - for (MCParticleToEnergyWeightMap::const_iterator mcParticleIter = mcParticleToEnergyWeightMap.begin(), - mcParticleIterEnd = mcParticleToEnergyWeightMap.end(); mcParticleIter != mcParticleIterEnd; ++mcParticleIter) - { - PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::SetCaloHitToMCParticleRelationship(m_pandora, - *caloHitIter, mcParticleIter->first, mcParticleIter->second)); - } - } - catch (pandora::StatusCodeException &statusCodeException) - { - streamlog_out(ERROR) << "Failed to extract calo hit to mc particle relationship: " << statusCodeException.ToString() << std::endl; - } - catch (...) - { - streamlog_out(WARNING) << "Failed to extract calo hit to mc particle relationship: " << exception.what() << std::endl; - } +pandora::StatusCode DDMCParticleCreator::CreateCaloHitToMCParticleRelationships( + const CollectionMaps& collectionMaps, const CalorimeterHitVector& calorimeterHitVector) const { + typedef std::map MCParticleToEnergyWeightMap; + MCParticleToEnergyWeightMap mcParticleToEnergyWeightMap; + + for (StringVector::const_iterator iter = m_settings.m_lcCaloHitRelationCollections.begin(), + iterEnd = m_settings.m_lcCaloHitRelationCollections.end(); + iter != iterEnd; ++iter) { + if (collectionMaps.collectionMap_CaloRel.find(*iter) == collectionMaps.collectionMap_CaloRel.end()) + continue; + try { + const std::vector& pMCRecoCaloAssociationCollection = + (collectionMaps.collectionMap_CaloRel.find(*iter))->second; + + for (unsigned i_calo = 0; i_calo < calorimeterHitVector.size(); i_calo++) { + try { + mcParticleToEnergyWeightMap.clear(); + + for (unsigned ic = 0; ic < pMCRecoCaloAssociationCollection.size(); ic++) { + if (pMCRecoCaloAssociationCollection.at(ic).getRec().id() != (*(calorimeterHitVector.at(i_calo))).id()) + continue; + const edm4hep::ConstSimCalorimeterHit pSimHit = pMCRecoCaloAssociationCollection.at(ic).getSim(); + for (int iCont = 0, iEnd = pSimHit.contributions_size(); iCont < iEnd; ++iCont) { + edm4hep::ConstCaloHitContribution conb = pSimHit.getContributions(iCont); + const edm4hep::ConstMCParticle ipa = conb.getParticle(); + float ien = conb.getEnergy(); + if (m_id_pMC_map->find(ipa.id()) == m_id_pMC_map->end()) + continue; + const edm4hep::MCParticle* p_tmp = (*m_id_pMC_map)[ipa.id()]; + mcParticleToEnergyWeightMap[p_tmp] += ien; } + } + + for (MCParticleToEnergyWeightMap::const_iterator mcParticleIter = mcParticleToEnergyWeightMap.begin(), + mcParticleIterEnd = mcParticleToEnergyWeightMap.end(); + mcParticleIter != mcParticleIterEnd; ++mcParticleIter) { + PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, + PandoraApi::SetCaloHitToMCParticleRelationship( + m_pandora, *caloHitIter, mcParticleIter->first, mcParticleIter->second)); + } + } catch (pandora::StatusCodeException& statusCodeException) { + streamlog_out(ERROR) << "Failed to extract calo hit to mc particle relationship: " + << statusCodeException.ToString() << std::endl; + } catch (...) { + streamlog_out(WARNING) << "Failed to extract calo hit to mc particle relationship: " << exception.what() + << std::endl; } - catch (...) - { - streamlog_out(DEBUG5) << "Failed to extract calo hit to mc particle relationships collection: " << *iter << ", " << exception.what() << std::endl; - } + } + } catch (...) { + streamlog_out(DEBUG5) << "Failed to extract calo hit to mc particle relationships collection: " << *iter << ", " + << exception.what() << std::endl; } + } - return pandora::STATUS_CODE_SUCCESS; + return pandora::STATUS_CODE_SUCCESS; } //------------------------------------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------------------------------------ -DDMCParticleCreator::Settings::Settings() -{ -} +DDMCParticleCreator::Settings::Settings() {} diff --git a/k4GaudiPandora/src/DDPandoraPFANewProcessor.cc b/k4GaudiPandora/src/DDPandoraPFANewProcessor.cc index 4b261a0..cbb7525 100644 --- a/k4GaudiPandora/src/DDPandoraPFANewProcessor.cc +++ b/k4GaudiPandora/src/DDPandoraPFANewProcessor.cc @@ -1,14 +1,32 @@ +/* + * Copyright (c) 2020-2024 Key4hep-Project. + * + * This file is part of Key4hep. + * See https://key4hep.github.io/key4hep-doc/ for further info. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + /** * @file DDMarlinPandora/src/DDPandoraPFANewProcessor.cc - * + * * @brief Implementation of the pandora pfa new processor class. - * + * * $Log: $ */ -#include "marlin/Global.h" #include "marlin/Exceptions.h" - +#include "marlin/Global.h" #include "Api/PandoraApi.h" @@ -18,36 +36,33 @@ #include "DDExternalClusteringAlgorithm.h" #include "DDPandoraPFANewProcessor.h" -#include "DD4hep/Detector.h" #include "DD4hep/DD4hepUnits.h" #include "DD4hep/DetType.h" -#include "DDRec/DetectorData.h" +#include "DD4hep/Detector.h" #include "DD4hep/DetectorSelector.h" +#include "DDRec/DetectorData.h" -#include "DDTrackCreatorILD.h" #include "DDTrackCreatorCLIC.h" +#include "DDTrackCreatorILD.h" #include "DDBFieldPlugin.h" - #include DDPandoraPFANewProcessor aDDPandoraPFANewProcessor; -double getFieldFromCompact(){ - +double getFieldFromCompact() { dd4hep::Detector& mainDetector = dd4hep::Detector::getInstance(); - const double position[3]={0,0,0}; // position to calculate magnetic field at (the origin in this case) - double magneticFieldVector[3]={0,0,0}; // initialise object to hold magnetic field - mainDetector.field().magneticField(position,magneticFieldVector); // get the magnetic field vector from DD4hep - - return magneticFieldVector[2]/dd4hep::tesla; // z component at (0,0,0) - + const double position[3] = {0, 0, 0}; // position to calculate magnetic field at (the origin in this case) + double magneticFieldVector[3] = {0, 0, 0}; // initialise object to hold magnetic field + mainDetector.field().magneticField(position, magneticFieldVector); // get the magnetic field vector from DD4hep + + return magneticFieldVector[2] / dd4hep::tesla; // z component at (0,0,0) } //Not needed anymore; to be removed // double getCoilOuterR(){ -// +// // try{ // dd4hep::Detector & mainDetector = dd4hep::Detector::getInstance(); // const std::vector< dd4hep::DetElement>& theDetectors = dd4hep::DetectorSelector(mainDetector).detectors( dd4hep::DetType::COIL ) ; @@ -55,898 +70,708 @@ double getFieldFromCompact(){ // dd4hep::Tube coilTube = dd4hep::Tube( theDetectors.at(0).volume().solid() ) ; // return coilTube->GetRmax()/ dd4hep::mm; // } catch ( std::exception & e ) { -// +// // streamlog_out(ERROR)<< "BIG WARNING! CANNOT GET EXTENSION FOR COIL: "<(); // // std::cout<< "DEBUG: in getExtension(\""<layers.size()<<" positions not shown. "<layers.size(); i++){ // // std::cout<layers[i].distance/dd4hep::mm<<" "; // // } // // std::cout<& theDetectors = dd4hep::DetectorSelector(mainDetector).detectors( includeFlag, excludeFlag ); - - - streamlog_out( DEBUG2 ) << " getExtension : includeFlag: " << dd4hep::DetType( includeFlag ) << " excludeFlag: " << dd4hep::DetType( excludeFlag ) - << " found : " << theDetectors.size() << " - first det: " << theDetectors.at(0).name() << std::endl ; - - if( theDetectors.size() != 1 ){ - - std::stringstream es ; - es << " getExtension: selection is not unique (or empty) includeFlag: " << dd4hep::DetType( includeFlag ) << " excludeFlag: " << dd4hep::DetType( excludeFlag ) - << " --- found detectors : " ; - for( unsigned i=0, N= theDetectors.size(); i& theDetectors = + dd4hep::DetectorSelector(mainDetector).detectors(includeFlag, excludeFlag); + + streamlog_out(DEBUG2) << " getExtension : includeFlag: " << dd4hep::DetType(includeFlag) + << " excludeFlag: " << dd4hep::DetType(excludeFlag) << " found : " << theDetectors.size() + << " - first det: " << theDetectors.at(0).name() << std::endl; + + if (theDetectors.size() != 1) { + std::stringstream es; + es << " getExtension: selection is not unique (or empty) includeFlag: " << dd4hep::DetType(includeFlag) + << " excludeFlag: " << dd4hep::DetType(excludeFlag) << " --- found detectors : "; + for (unsigned i = 0, N = theDetectors.size(); i < N; ++i) { + es << theDetectors.at(i).name() << ", "; } - throw std::runtime_error( es.str() ) ; + throw std::runtime_error(es.str()); } - + theExtension = theDetectors.at(0).extension(); - + return theExtension; } -std::vector getTrackingRegionExtent(){ - +std::vector getTrackingRegionExtent() { ///Rmin, Rmax, Zmax std::vector extent; - + extent.reserve(3); - - dd4hep::Detector & mainDetector = dd4hep::Detector::getInstance(); - - - - extent[0]=0.1; ///FIXME! CLIC-specific: Inner radius was set to 0 for SiD-type detectors - extent[1]=mainDetector.constantAsDouble("tracker_region_rmax")/dd4hep::mm; - extent[2]=mainDetector.constantAsDouble("tracker_region_zmax")/dd4hep::mm; + + dd4hep::Detector& mainDetector = dd4hep::Detector::getInstance(); + + extent[0] = 0.1; ///FIXME! CLIC-specific: Inner radius was set to 0 for SiD-type detectors + extent[1] = mainDetector.constantAsDouble("tracker_region_rmax") / dd4hep::mm; + extent[2] = mainDetector.constantAsDouble("tracker_region_zmax") / dd4hep::mm; return extent; - - } DDPandoraPFANewProcessor::PandoraToLCEventMap DDPandoraPFANewProcessor::m_pandoraToLCEventMap; //------------------------------------------------------------------------------------------------------------------------------------------ -DDPandoraPFANewProcessor::DDPandoraPFANewProcessor() : - Processor("DDPandoraPFANewProcessor") -{ - _description = "Pandora reconstructs clusters and particle flow objects"; - this->ProcessSteeringFile(); +DDPandoraPFANewProcessor::DDPandoraPFANewProcessor() : Processor("DDPandoraPFANewProcessor") { + _description = "Pandora reconstructs clusters and particle flow objects"; + this->ProcessSteeringFile(); } //------------------------------------------------------------------------------------------------------------------------------------------ -void DDPandoraPFANewProcessor::init() -{ - printParameters(); - try - { - streamlog_out(MESSAGE) << "DDPandoraPFANewProcessor - Init" << std::endl; - this->FinaliseSteeringParameters(); - - m_pPandora = new pandora::Pandora(); - m_pGeometryCreator = new DDGeometryCreator(m_geometryCreatorSettings, m_pPandora); - m_pCaloHitCreator = new DDCaloHitCreator(m_caloHitCreatorSettings, m_pPandora); - - - ///FIXME: IMPLEMENT FACTORY - if (m_settings.m_trackCreatorName == "DDTrackCreatorCLIC") - m_pTrackCreator = new DDTrackCreatorCLIC(m_trackCreatorSettings, m_pPandora); - else if (m_settings.m_trackCreatorName == "DDTrackCreatorILD") - m_pTrackCreator = new DDTrackCreatorILD(m_trackCreatorSettings, m_pPandora); - else - streamlog_out(ERROR) << "Unknown DDTrackCreator: "<RegisterUserComponents()); - PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, m_pGeometryCreator->CreateGeometry()); - PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::ReadSettings(*m_pPandora, m_settings.m_pandoraSettingsXmlFile)); - } - catch (pandora::StatusCodeException &statusCodeException) - { - streamlog_out(ERROR) << "Failed to initialize marlin pandora: " << statusCodeException.ToString() << std::endl; - throw statusCodeException; - } - catch (std::exception &exception) - { - streamlog_out(ERROR) << "Failed to initialize marlin pandora: std exception " << exception.what() << std::endl; - throw exception; - } - catch (...) - { - streamlog_out(ERROR) << "Failed to initialize marlin pandora: unrecognized exception" << std::endl; - throw; - } +void DDPandoraPFANewProcessor::init() { + printParameters(); + try { + streamlog_out(MESSAGE) << "DDPandoraPFANewProcessor - Init" << std::endl; + this->FinaliseSteeringParameters(); + + m_pPandora = new pandora::Pandora(); + m_pGeometryCreator = new DDGeometryCreator(m_geometryCreatorSettings, m_pPandora); + m_pCaloHitCreator = new DDCaloHitCreator(m_caloHitCreatorSettings, m_pPandora); + + ///FIXME: IMPLEMENT FACTORY + if (m_settings.m_trackCreatorName == "DDTrackCreatorCLIC") + m_pTrackCreator = new DDTrackCreatorCLIC(m_trackCreatorSettings, m_pPandora); + else if (m_settings.m_trackCreatorName == "DDTrackCreatorILD") + m_pTrackCreator = new DDTrackCreatorILD(m_trackCreatorSettings, m_pPandora); + else + streamlog_out(ERROR) << "Unknown DDTrackCreator: " << m_settings.m_trackCreatorName << std::endl; + + m_pDDMCParticleCreator = new DDMCParticleCreator(m_mcParticleCreatorSettings, m_pPandora); + m_pDDPfoCreator = new DDPfoCreator(m_pfoCreatorSettings, m_pPandora); + + PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, this->RegisterUserComponents()); + PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, m_pGeometryCreator->CreateGeometry()); + PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, + PandoraApi::ReadSettings(*m_pPandora, m_settings.m_pandoraSettingsXmlFile)); + } catch (pandora::StatusCodeException& statusCodeException) { + streamlog_out(ERROR) << "Failed to initialize marlin pandora: " << statusCodeException.ToString() << std::endl; + throw statusCodeException; + } catch (std::exception& exception) { + streamlog_out(ERROR) << "Failed to initialize marlin pandora: std exception " << exception.what() << std::endl; + throw exception; + } catch (...) { + streamlog_out(ERROR) << "Failed to initialize marlin pandora: unrecognized exception" << std::endl; + throw; + } } //------------------------------------------------------------------------------------------------------------------------------------------ -void DDPandoraPFANewProcessor::processRunHeader(LCRunHeader */*pLCRunHeader*/) -{ -} +void DDPandoraPFANewProcessor::processRunHeader(LCRunHeader* /*pLCRunHeader*/) {} //------------------------------------------------------------------------------------------------------------------------------------------ -void DDPandoraPFANewProcessor::processEvent(LCEvent *pLCEvent) -{ - try - { - streamlog_out(DEBUG) << "DDPandoraPFANewProcessor - Run " << std::endl; - (void) m_pandoraToLCEventMap.insert(PandoraToLCEventMap::value_type(m_pPandora, pLCEvent)); - - PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, m_pDDMCParticleCreator->CreateMCParticles(pLCEvent)); - PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, m_pTrackCreator->CreateTrackAssociations(pLCEvent)); - PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, m_pTrackCreator->CreateTracks(pLCEvent)); - PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, m_pDDMCParticleCreator->CreateTrackToMCParticleRelationships(pLCEvent, m_pTrackCreator->GetTrackVector())); - PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, m_pCaloHitCreator->CreateCaloHits(pLCEvent)); - PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, m_pDDMCParticleCreator->CreateCaloHitToMCParticleRelationships(pLCEvent, m_pCaloHitCreator->GetCalorimeterHitVector())); - - PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::ProcessEvent(*m_pPandora)); - PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, m_pDDPfoCreator->CreateParticleFlowObjects(pLCEvent)); - - PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::Reset(*m_pPandora)); - this->Reset(); - } - catch (pandora::StatusCodeException &statusCodeException) - { - streamlog_out(ERROR) << "Marlin pandora failed to process event: " << statusCodeException.ToString() << std::endl; - throw statusCodeException; - } - catch (EVENT::Exception &exception) - { - streamlog_out(ERROR) << "Marlin pandora failed to process event: lcio exception " << exception.what() << std::endl; - throw exception; - } - catch (std::exception &exception) - { - streamlog_out(ERROR) << "Marlin pandora failed to process event: std exception " << exception.what() << std::endl; - throw exception; - } - catch (...) - { - streamlog_out(ERROR) << "Marlin pandora failed to process event: unrecognized exception" << std::endl; - throw; - } +void DDPandoraPFANewProcessor::processEvent(LCEvent* pLCEvent) { + try { + streamlog_out(DEBUG) << "DDPandoraPFANewProcessor - Run " << std::endl; + (void)m_pandoraToLCEventMap.insert(PandoraToLCEventMap::value_type(m_pPandora, pLCEvent)); + + PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, m_pDDMCParticleCreator->CreateMCParticles(pLCEvent)); + PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, m_pTrackCreator->CreateTrackAssociations(pLCEvent)); + PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, m_pTrackCreator->CreateTracks(pLCEvent)); + PANDORA_THROW_RESULT_IF( + pandora::STATUS_CODE_SUCCESS, !=, + m_pDDMCParticleCreator->CreateTrackToMCParticleRelationships(pLCEvent, m_pTrackCreator->GetTrackVector())); + PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, m_pCaloHitCreator->CreateCaloHits(pLCEvent)); + PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, + m_pDDMCParticleCreator->CreateCaloHitToMCParticleRelationships( + pLCEvent, m_pCaloHitCreator->GetCalorimeterHitVector())); + + PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::ProcessEvent(*m_pPandora)); + PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, m_pDDPfoCreator->CreateParticleFlowObjects(pLCEvent)); + + PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::Reset(*m_pPandora)); + this->Reset(); + } catch (pandora::StatusCodeException& statusCodeException) { + streamlog_out(ERROR) << "Marlin pandora failed to process event: " << statusCodeException.ToString() << std::endl; + throw statusCodeException; + } catch (EVENT::Exception& exception) { + streamlog_out(ERROR) << "Marlin pandora failed to process event: lcio exception " << exception.what() << std::endl; + throw exception; + } catch (std::exception& exception) { + streamlog_out(ERROR) << "Marlin pandora failed to process event: std exception " << exception.what() << std::endl; + throw exception; + } catch (...) { + streamlog_out(ERROR) << "Marlin pandora failed to process event: unrecognized exception" << std::endl; + throw; + } } //------------------------------------------------------------------------------------------------------------------------------------------ -void DDPandoraPFANewProcessor::check(LCEvent */*pLCEvent*/) -{ - streamlog_out(DEBUG) << "DDPandoraPFANewProcessor - Check" << std::endl; +void DDPandoraPFANewProcessor::check(LCEvent* /*pLCEvent*/) { + streamlog_out(DEBUG) << "DDPandoraPFANewProcessor - Check" << std::endl; } //------------------------------------------------------------------------------------------------------------------------------------------ -void DDPandoraPFANewProcessor::end() -{ - delete m_pPandora; - delete m_pGeometryCreator; - delete m_pCaloHitCreator; - delete m_pTrackCreator; - delete m_pDDMCParticleCreator; - delete m_pDDPfoCreator; +void DDPandoraPFANewProcessor::end() { + delete m_pPandora; + delete m_pGeometryCreator; + delete m_pCaloHitCreator; + delete m_pTrackCreator; + delete m_pDDMCParticleCreator; + delete m_pDDPfoCreator; - streamlog_out(MESSAGE) << "DDPandoraPFANewProcessor - End" << std::endl; + streamlog_out(MESSAGE) << "DDPandoraPFANewProcessor - End" << std::endl; } //------------------------------------------------------------------------------------------------------------------------------------------ -const pandora::Pandora *DDPandoraPFANewProcessor::GetPandora() const -{ - if (NULL == m_pPandora) - throw pandora::StatusCodeException(pandora::STATUS_CODE_NOT_INITIALIZED); +const pandora::Pandora* DDPandoraPFANewProcessor::GetPandora() const { + if (NULL == m_pPandora) + throw pandora::StatusCodeException(pandora::STATUS_CODE_NOT_INITIALIZED); - return m_pPandora; + return m_pPandora; } //------------------------------------------------------------------------------------------------------------------------------------------ -const EVENT::LCEvent *DDPandoraPFANewProcessor::GetCurrentEvent(const pandora::Pandora *const pPandora) -{ - PandoraToLCEventMap::iterator iter = m_pandoraToLCEventMap.find(pPandora); +const EVENT::LCEvent* DDPandoraPFANewProcessor::GetCurrentEvent(const pandora::Pandora* const pPandora) { + PandoraToLCEventMap::iterator iter = m_pandoraToLCEventMap.find(pPandora); - if (m_pandoraToLCEventMap.end() == iter) - throw pandora::StatusCodeException(pandora::STATUS_CODE_NOT_FOUND); + if (m_pandoraToLCEventMap.end() == iter) + throw pandora::StatusCodeException(pandora::STATUS_CODE_NOT_FOUND); - return iter->second; + return iter->second; } //------------------------------------------------------------------------------------------------------------------------------------------ -pandora::StatusCode DDPandoraPFANewProcessor::RegisterUserComponents() const -{ - PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, LCContent::RegisterAlgorithms(*m_pPandora)); - PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, LCContent::RegisterBasicPlugins(*m_pPandora)); - - if(m_settings.m_useDD4hepField) - { - dd4hep::Detector& mainDetector = dd4hep::Detector::getInstance(); - - PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::SetBFieldPlugin(*m_pPandora, - new DDBFieldPlugin(mainDetector))); - } - else - { - PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, LCContent::RegisterBFieldPlugin(*m_pPandora, - m_settings.m_innerBField, m_settings.m_muonBarrelBField, m_settings.m_muonEndCapBField)); - } +pandora::StatusCode DDPandoraPFANewProcessor::RegisterUserComponents() const { + PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, LCContent::RegisterAlgorithms(*m_pPandora)); + PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, LCContent::RegisterBasicPlugins(*m_pPandora)); + + if (m_settings.m_useDD4hepField) { + dd4hep::Detector& mainDetector = dd4hep::Detector::getInstance(); + PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, + PandoraApi::SetBFieldPlugin(*m_pPandora, new DDBFieldPlugin(mainDetector))); + } else { + PANDORA_RETURN_RESULT_IF( + pandora::STATUS_CODE_SUCCESS, !=, + LCContent::RegisterBFieldPlugin(*m_pPandora, m_settings.m_innerBField, m_settings.m_muonBarrelBField, + m_settings.m_muonEndCapBField)); + } - PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, LCContent::RegisterNonLinearityEnergyCorrection(*m_pPandora, - "NonLinearity", pandora::HADRONIC, m_settings.m_inputEnergyCorrectionPoints, m_settings.m_outputEnergyCorrectionPoints)); - - PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::RegisterAlgorithmFactory(*m_pPandora, - "ExternalClustering", new DDExternalClusteringAlgorithm::Factory)); - - lc_content::LCSoftwareCompensationParameters softwareCompensationParameters; - softwareCompensationParameters.m_softCompParameters = m_settings.m_softCompParameters; - softwareCompensationParameters.m_softCompEnergyDensityBins = m_settings.m_softCompEnergyDensityBins; - softwareCompensationParameters.m_energyDensityFinalBin = m_settings.m_energyDensityFinalBin; - softwareCompensationParameters.m_maxClusterEnergyToApplySoftComp = m_settings.m_maxClusterEnergyToApplySoftComp; - softwareCompensationParameters.m_minCleanHitEnergy = m_settings.m_minCleanHitEnergy; - softwareCompensationParameters.m_minCleanHitEnergyFraction = m_settings.m_minCleanHitEnergyFraction; - softwareCompensationParameters.m_minCleanCorrectedHitEnergy = m_settings.m_minCleanCorrectedHitEnergy; - - PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, LCContent::RegisterSoftwareCompensationEnergyCorrection(*m_pPandora, - "SoftwareCompensation", softwareCompensationParameters)); - - return pandora::STATUS_CODE_SUCCESS; + PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, + LCContent::RegisterNonLinearityEnergyCorrection( + *m_pPandora, "NonLinearity", pandora::HADRONIC, m_settings.m_inputEnergyCorrectionPoints, + m_settings.m_outputEnergyCorrectionPoints)); + + PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, + PandoraApi::RegisterAlgorithmFactory(*m_pPandora, "ExternalClustering", + new DDExternalClusteringAlgorithm::Factory)); + + lc_content::LCSoftwareCompensationParameters softwareCompensationParameters; + softwareCompensationParameters.m_softCompParameters = m_settings.m_softCompParameters; + softwareCompensationParameters.m_softCompEnergyDensityBins = m_settings.m_softCompEnergyDensityBins; + softwareCompensationParameters.m_energyDensityFinalBin = m_settings.m_energyDensityFinalBin; + softwareCompensationParameters.m_maxClusterEnergyToApplySoftComp = m_settings.m_maxClusterEnergyToApplySoftComp; + softwareCompensationParameters.m_minCleanHitEnergy = m_settings.m_minCleanHitEnergy; + softwareCompensationParameters.m_minCleanHitEnergyFraction = m_settings.m_minCleanHitEnergyFraction; + softwareCompensationParameters.m_minCleanCorrectedHitEnergy = m_settings.m_minCleanCorrectedHitEnergy; + + PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, + LCContent::RegisterSoftwareCompensationEnergyCorrection(*m_pPandora, "SoftwareCompensation", + softwareCompensationParameters)); + + return pandora::STATUS_CODE_SUCCESS; } //------------------------------------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------------------------------------ -void DDPandoraPFANewProcessor::ProcessSteeringFile() -{ - registerProcessorParameter("PandoraSettingsXmlFile", - "The pandora settings xml file", - m_settings.m_pandoraSettingsXmlFile, - std::string()); - - // Input collections - registerInputCollections(LCIO::TRACK, - "TrackCollections", - "Names of the Track collections used for clustering", - m_trackCreatorSettings.m_trackCollections, - StringVector()); - - registerInputCollections(LCIO::VERTEX, - "KinkVertexCollections", - "Name of external kink Vertex collections", - m_trackCreatorSettings.m_kinkVertexCollections, - StringVector()); - - registerInputCollections(LCIO::VERTEX, - "ProngVertexCollections", - "Name of external prong Vertex collections", - m_trackCreatorSettings.m_prongVertexCollections, - StringVector()); - - registerInputCollections(LCIO::VERTEX, - "SplitVertexCollections", - "Name of external split Vertex collections", - m_trackCreatorSettings.m_splitVertexCollections, - StringVector()); - - registerInputCollections(LCIO::VERTEX, - "V0VertexCollections", - "Name of external V0 Vertex collections", - m_trackCreatorSettings.m_v0VertexCollections, - StringVector()); - - registerInputCollections(LCIO::CALORIMETERHIT, - "ECalCaloHitCollections", - "Name of the ECAL calo hit collections", - m_caloHitCreatorSettings.m_eCalCaloHitCollections, - StringVector()); - - registerInputCollections(LCIO::CALORIMETERHIT, - "HCalCaloHitCollections", - "Name of the HCAL calo hit collections", - m_caloHitCreatorSettings.m_hCalCaloHitCollections, - StringVector()); - - registerInputCollections(LCIO::CALORIMETERHIT, - "LCalCaloHitCollections", - "Name of the LCAL calo hit collections", - m_caloHitCreatorSettings.m_lCalCaloHitCollections, - StringVector()); - - registerInputCollections(LCIO::CALORIMETERHIT, - "LHCalCaloHitCollections", - "Name of the LHCAL calo hit collections", - m_caloHitCreatorSettings.m_lHCalCaloHitCollections, - StringVector()); - - registerInputCollections(LCIO::CALORIMETERHIT, - "MuonCaloHitCollections", - "Name of the muon calo hit collections", - m_caloHitCreatorSettings.m_muonCaloHitCollections, - StringVector()); - - registerInputCollections(LCIO::MCPARTICLE, - "MCParticleCollections", - "Name of mc particle collections", - m_mcParticleCreatorSettings.m_mcParticleCollections, - StringVector()); - - registerInputCollections(LCIO::LCRELATION, - "RelCaloHitCollections", - "SimCaloHit to CaloHit Relations Collection Name", - m_mcParticleCreatorSettings.m_lcCaloHitRelationCollections, - StringVector()); - - registerInputCollections(LCIO::LCRELATION, - "RelTrackCollections", - "Track to MCParticle Relations Collection Name", - m_mcParticleCreatorSettings.m_lcTrackRelationCollections, - StringVector()); - - registerProcessorParameter("CreateGaps", - "Decides whether to create gaps in the geometry (ILD-specific)", - m_geometryCreatorSettings.m_createGaps, - bool(true)); - - // Name of PFO collection written by MarlinPandora - registerOutputCollection(LCIO::CLUSTER, - "ClusterCollectionName", - "Cluster Collection Name", - m_pfoCreatorSettings.m_clusterCollectionName, - std::string("PandoraPFANewClusters")); - - registerOutputCollection(LCIO::RECONSTRUCTEDPARTICLE, - "PFOCollectionName", - "PFO Collection Name", - m_pfoCreatorSettings.m_pfoCollectionName, - std::string("PandoraPFANewPFOs")); - registerOutputCollection(LCIO::VERTEX, - "StartVertexCollectionName", - "Start Vertex Collection Name", - m_pfoCreatorSettings.m_startVertexCollectionName, - std::string("PandoraPFANewStartVertices")); - - registerProcessorParameter("StartVertexAlgorithmName", - "The algorithm name for filling start vertex", - m_pfoCreatorSettings.m_startVertexAlgName, - std::string("PandoraPFANew")); - - // Energy resolution parameters - registerProcessorParameter("EMStochasticTerm", - "The stochastic term for EM shower", - m_pfoCreatorSettings.m_emStochasticTerm, - float(0.17)); - - registerProcessorParameter("HadStochasticTerm", - "The stochastic term for Hadronic shower", - m_pfoCreatorSettings.m_hadStochasticTerm, - float(0.6)); - - registerProcessorParameter("EMConstantTerm", - "The constant term for EM shower", - m_pfoCreatorSettings.m_emConstantTerm, - float(0.01)); - - registerProcessorParameter("HadConstantTerm", - "The constant term for Hadronic shower", - m_pfoCreatorSettings.m_hadConstantTerm, - float(0.03)); - - // Calibration constants - registerProcessorParameter("ECalToMipCalibration", - "The calibration from deposited ECal energy to mip", - m_caloHitCreatorSettings.m_eCalToMip, - float(1.)); - - registerProcessorParameter("HCalToMipCalibration", - "The calibration from deposited HCal energy to mip", - m_caloHitCreatorSettings.m_hCalToMip, - float(1.)); - - registerProcessorParameter("ECalMipThreshold", - "Threshold for creating calo hits in the ECal, units mip", - m_caloHitCreatorSettings.m_eCalMipThreshold, - float(0.)); - - registerProcessorParameter("MuonToMipCalibration", - "The calibration from deposited Muon energy to mip", - m_caloHitCreatorSettings.m_muonToMip, - float(1.)); - - registerProcessorParameter("HCalMipThreshold", - "Threshold for creating calo hits in the HCal, units mip", - m_caloHitCreatorSettings.m_hCalMipThreshold, - float(0.)); - - registerProcessorParameter("ECalToEMGeVCalibration", - "The calibration from deposited ECal energy to EM energy", - m_caloHitCreatorSettings.m_eCalToEMGeV, - float(1.)); - - registerProcessorParameter("HCalToEMGeVCalibration", - "The calibration from deposited HCal energy to EM energy", - m_caloHitCreatorSettings.m_hCalToEMGeV, - float(1.)); - - registerProcessorParameter("ECalToHadGeVCalibrationEndCap", - "The calibration from deposited ECal energy to hadronic energy", - m_caloHitCreatorSettings.m_eCalToHadGeVEndCap, - float(1.)); - - registerProcessorParameter("ECalToHadGeVCalibrationBarrel", - "The calibration from deposited ECal energy to hadronic energy", - m_caloHitCreatorSettings.m_eCalToHadGeVBarrel, - float(1.)); - - registerProcessorParameter("HCalToHadGeVCalibration", - "The calibration from deposited HCal energy to hadronic energy", - m_caloHitCreatorSettings.m_hCalToHadGeV, - float(1.)); - - registerProcessorParameter("DigitalMuonHits", - "Treat muon hits as digital", - m_caloHitCreatorSettings.m_muonDigitalHits, - int(1)); - - registerProcessorParameter("MuonHitEnergy", - "The energy for a digital muon calorimeter hit, units GeV", - m_caloHitCreatorSettings.m_muonHitEnergy, - float(0.5)); - - registerProcessorParameter("MaxHCalHitHadronicEnergy", - "The maximum hadronic energy allowed for a single hcal hit", - m_caloHitCreatorSettings.m_maxHCalHitHadronicEnergy, - float(10000.)); - - registerProcessorParameter("NOuterSamplingLayers", - "Number of layers from edge for hit to be flagged as an outer layer hit", - m_caloHitCreatorSettings.m_nOuterSamplingLayers, - int(3)); - - registerProcessorParameter("LayersFromEdgeMaxRearDistance", - "Maximum number of layers from candidate outer layer hit to rear of detector", - m_caloHitCreatorSettings.m_layersFromEdgeMaxRearDistance, - float(250.f)); - - // B-field parameters - registerProcessorParameter("MuonBarrelBField", - "The bfield in the muon barrel, units Tesla", - m_settings.m_muonBarrelBField, - float(-1.5f)); - - registerProcessorParameter("MuonEndCapBField", - "The bfield in the muon endcap, units Tesla", - m_settings.m_muonEndCapBField, - float(0.01f)); - - registerProcessorParameter("UseDD4hepField", - "Whether to use the BField map from DD4hep", - m_settings.m_useDD4hepField, - false); - - // Track relationship parameters - registerProcessorParameter("ShouldFormTrackRelationships", - "Whether to form pandora track relationships using v0 and kink info", - m_trackCreatorSettings.m_shouldFormTrackRelationships, - int(1)); - - // Initial track hit specifications - registerProcessorParameter("MinTrackHits", - "Track quality cut: the minimum number of track hits", - m_trackCreatorSettings.m_minTrackHits, - int(5)); - - registerProcessorParameter("MinFtdTrackHits", - "Track quality cut: the minimum number of ftd track hits for ftd only tracks", - m_trackCreatorSettings.m_minFtdTrackHits, - int(0)); - - registerProcessorParameter("MaxTrackHits", - "Track quality cut: the maximum number of track hits", - m_trackCreatorSettings.m_maxTrackHits, - int(5000)); - - // Track PFO usage parameters - registerProcessorParameter("D0TrackCut", - "Track d0 cut used to determine whether track can be used to form pfo", - m_trackCreatorSettings.m_d0TrackCut, - float(50.)); - - registerProcessorParameter("Z0TrackCut", - "Track z0 cut used to determine whether track can be used to form pfo", - m_trackCreatorSettings.m_z0TrackCut, - float(50.)); - - registerProcessorParameter("UseNonVertexTracks", - "Whether can form pfos from tracks that don't start at vertex", - m_trackCreatorSettings.m_usingNonVertexTracks, - int(1)); - - registerProcessorParameter("UseUnmatchedNonVertexTracks", - "Whether can form pfos from unmatched tracks that don't start at vertex", - m_trackCreatorSettings.m_usingUnmatchedNonVertexTracks, - int(0)); - - registerProcessorParameter("UseUnmatchedVertexTracks", - "Whether can form pfos from unmatched tracks that start at vertex", - m_trackCreatorSettings.m_usingUnmatchedVertexTracks, - int(1)); - - registerProcessorParameter("UnmatchedVertexTrackMaxEnergy", - "Maximum energy for unmatched vertex track", - m_trackCreatorSettings.m_unmatchedVertexTrackMaxEnergy, - float(5.)); - - registerProcessorParameter("D0UnmatchedVertexTrackCut", - "d0 cut used to determine whether unmatched vertex track can form pfo", - m_trackCreatorSettings.m_d0UnmatchedVertexTrackCut, - float(5.)); - - registerProcessorParameter("Z0UnmatchedVertexTrackCut", - "z0 cut used to determine whether unmatched vertex track can form pfo", - m_trackCreatorSettings.m_z0UnmatchedVertexTrackCut, - float(5.)); - - registerProcessorParameter("ZCutForNonVertexTracks", - "Non vtx track z cut to determine whether track can be used to form pfo", - m_trackCreatorSettings.m_zCutForNonVertexTracks, - float(250.)); - - // Track "reaches ecal" parameters - registerProcessorParameter("ReachesECalNBarrelTrackerHits", - "Minimum number of BarrelTracker hits to consider track as reaching ecal", - m_trackCreatorSettings.m_reachesECalNBarrelTrackerHits, - int(11)); - - registerProcessorParameter("ReachesECalNFtdHits", - "Minimum number of ftd hits to consider track as reaching ecal", - m_trackCreatorSettings.m_reachesECalNFtdHits, - int(4)); - - registerProcessorParameter("ReachesECalBarrelTrackerOuterDistance", - "Max distance from track to BarrelTracker r max to id whether track reaches ecal", - m_trackCreatorSettings.m_reachesECalBarrelTrackerOuterDistance, - float(-100.)); - - registerProcessorParameter("ReachesECalMinFtdLayer", - "Min FTD layer for track to be considered to have reached ecal", - m_trackCreatorSettings.m_reachesECalMinFtdLayer, - int(9)); - - registerProcessorParameter("ReachesECalBarrelTrackerZMaxDistance", - "Max distance from track to BarrelTracker z max to id whether track reaches ecal", - m_trackCreatorSettings.m_reachesECalBarrelTrackerZMaxDistance, - float(-50.)); - - registerProcessorParameter("ReachesECalFtdZMaxDistance", - "Max distance from track hit to ftd z position to identify ftd hits", - m_trackCreatorSettings.m_reachesECalFtdZMaxDistance, - float(1.)); - - registerProcessorParameter("CurvatureToMomentumFactor", - "Constant relating track curvature in b field to momentum", - m_trackCreatorSettings.m_curvatureToMomentumFactor, - float(0.3 / 2000.)); - - registerProcessorParameter("MinTrackECalDistanceFromIp", - "Sanity check on separation between ip and track projected ecal position", - m_trackCreatorSettings.m_minTrackECalDistanceFromIp, - float(100.)); - - // Final track quality parameters - registerProcessorParameter("MaxTrackSigmaPOverP", - "Cut on fractional track momentum error", - m_trackCreatorSettings.m_maxTrackSigmaPOverP, - float(0.15)); - - registerProcessorParameter("MinMomentumForTrackHitChecks", - "Min track momentum required to perform final quality checks on number of hits", - m_trackCreatorSettings.m_minMomentumForTrackHitChecks, - float(1.)); - - registerProcessorParameter("MinBarrelTrackerHitFractionOfExpected", - "Cut on fractional of expected number of BarrelTracker hits", - m_trackCreatorSettings.m_minBarrelTrackerHitFractionOfExpected, - float(0.20)); - - registerProcessorParameter("MinFtdHitsForBarrelTrackerHitFraction", - "Cut on minimum number of FTD hits of BarrelTracker hit fraction to be applied", - m_trackCreatorSettings.m_minFtdHitsForBarrelTrackerHitFraction, - int(2)); - - registerProcessorParameter("MaxBarrelTrackerInnerRDistance", - "Track cut on distance from BarrelTracker inner r to id whether track can form pfo", - m_trackCreatorSettings.m_maxBarrelTrackerInnerRDistance, - float(50.)); - - registerProcessorParameter( "TrackStateTolerance", - "Distance of possible second track state in the ECal Endcap to the ECal barrel inner radius", - m_trackCreatorSettings.m_trackStateTolerance, - m_trackCreatorSettings.m_trackStateTolerance ); - - registerProcessorParameter( "TrackSystemName", - "Name of the track fitting system to be used (KalTest, DDKalTest, aidaTT, ... )", - m_trackCreatorSettings.m_trackingSystemName, - m_trackCreatorSettings.m_trackingSystemName ); - - // For Strip Splitting method and also for hybrid ECAL - registerProcessorParameter("StripSplittingOn", - "To use strip splitting algorithm, this should be true", - m_caloHitCreatorSettings.m_stripSplittingOn, - int(0)); - - // For Strip Splitting method and also for hybrid ECAL - registerProcessorParameter("UseEcalScLayers", - "To use scintillator layers ~ hybrid ECAL, this should be true", - m_caloHitCreatorSettings.m_useEcalScLayers, - int(0)); - - // Parameters for hybrid ECAL - // Energy to MIP for Si-layers and Sc-layers, respectively. - //Si - registerProcessorParameter("ECalSiToMipCalibration", - "The calibration from deposited Si-layer energy to mip", - m_caloHitCreatorSettings.m_eCalSiToMip, - float(1.)); - - //Sc - registerProcessorParameter("ECalScToMipCalibration", - "The calibration from deposited Sc-layer energy to mip", - m_caloHitCreatorSettings.m_eCalScToMip, - float(1.)); - - // MipThreshold for Si-layers and Sc-layers, respectively. - // Si - registerProcessorParameter("ECalSiMipThreshold", - "Threshold for creating calo hits in the Si-layers of ECAL, units mip", - m_caloHitCreatorSettings.m_eCalSiMipThreshold, - float(0.)); - - //Sc - registerProcessorParameter("ECalScMipThreshold", - "Threshold for creating calo hits in the Sc-layers of ECAL, units mip", - m_caloHitCreatorSettings.m_eCalScMipThreshold, - float(0.)); - - // EcalToEM for Si-layers and Sc-layers, respectively. - //Si - registerProcessorParameter("ECalSiToEMGeVCalibration", - "The calibration from deposited Si-layer energy to EM energy", - m_caloHitCreatorSettings.m_eCalSiToEMGeV, - float(1.)); - - //Sc - registerProcessorParameter("ECalScToEMGeVCalibration", - "The calibration from deposited Sc-layer energy to EM energy", - m_caloHitCreatorSettings.m_eCalScToEMGeV, - float(1.)); - - // EcalToHad for Si-layers and Sc-layers of the endcaps, respectively. - //Si - registerProcessorParameter("ECalSiToHadGeVCalibrationEndCap", - "The calibration from deposited Si-layer energy on the enecaps to hadronic energy", - m_caloHitCreatorSettings.m_eCalSiToHadGeVEndCap, - float(1.)); - - //Sc - registerProcessorParameter("ECalScToHadGeVCalibrationEndCap", - "The calibration from deposited Sc-layer energy on the endcaps to hadronic energy", - m_caloHitCreatorSettings.m_eCalScToHadGeVEndCap, - float(1.)); - - // EcalToHad for Si-layers and Sc-layers of the barrel, respectively. - //Si - registerProcessorParameter("ECalSiToHadGeVCalibrationBarrel", - "The calibration from deposited Si-layer energy on the barrel to hadronic energy", - m_caloHitCreatorSettings.m_eCalSiToHadGeVBarrel, - float(1.)); - - //Sc - registerProcessorParameter("ECalScToHadGeVCalibrationBarrel", - "The calibration from deposited Sc-layer energy to the barrel hadronic energy", - m_caloHitCreatorSettings.m_eCalScToHadGeVBarrel, - float(1.)); - - // Hadronic energy non-linearity correction - registerProcessorParameter("InputEnergyCorrectionPoints", - "The input energy points for hadronic energy correction", - m_settings.m_inputEnergyCorrectionPoints, - FloatVector()); - - registerProcessorParameter("OutputEnergyCorrectionPoints", - "The output energy points for hadronic energy correction", - m_settings.m_outputEnergyCorrectionPoints, - FloatVector()); - - - ///EXTRA PARAMETERS FROM NIKIFOROS - registerProcessorParameter("TrackCreatorName", - "The name of the DDTrackCreator implementation", - m_settings.m_trackCreatorName, - std::string("DDTrackCreatorCLIC")); - - registerProcessorParameter("ECalBarrelNormalVector", - "Normal vector for the ECal barrel sensitive layers in local coordinates", - m_caloHitCreatorSettings.m_eCalBarrelNormalVector, - std::vector({0.0, 0.0, 1.0})); - - registerProcessorParameter("HCalBarrelNormalVector", - "Normal vector for the HCal barrel sensitive layers in local coordinates", - m_caloHitCreatorSettings.m_hCalBarrelNormalVector, - std::vector({0.0, 0.0, 1.0})); - - registerProcessorParameter("YokeBarrelNormalVector", - "Normal vector for the muon barrel sensitive layers in local coordinates", - m_caloHitCreatorSettings.m_muonBarrelNormalVector, - std::vector({0.0, 0.0, 1.0})); - - // Re-use LCSoftwareCompensationParameters default values - lc_content::LCSoftwareCompensationParameters softwareCompensationParameters; - - registerProcessorParameter("SoftwareCompensationWeights", - "The 9 software compensation weights for Pandora energy correction", - m_settings.m_softCompParameters, - softwareCompensationParameters.m_softCompParameters); - - registerProcessorParameter("SoftwareCompensationEnergyDensityBins", - "The 10 software compensation density bins for Pandora energy correction", - m_settings.m_softCompEnergyDensityBins, - softwareCompensationParameters.m_softCompEnergyDensityBins); - - registerProcessorParameter("FinalEnergyDensityBin", - "The software compensation final energy density bins for Pandora energy correction", - m_settings.m_energyDensityFinalBin, - softwareCompensationParameters.m_energyDensityFinalBin); - - registerProcessorParameter("MaxClusterEnergyToApplySoftComp", - "The maximum hadronic energy to apply software compensation in Pandora energy correction", - m_settings.m_maxClusterEnergyToApplySoftComp, - softwareCompensationParameters.m_maxClusterEnergyToApplySoftComp); - - registerProcessorParameter("MinCleanHitEnergy", - "The minimum hit energy to apply ecal correction in Pandora energy correction", - m_settings.m_minCleanHitEnergy, - softwareCompensationParameters.m_minCleanHitEnergy); - - registerProcessorParameter("MinCleanHitEnergyFraction", - "The minimum hit energy fraction to apply ecal correction in Pandora energy correction", - m_settings.m_minCleanHitEnergyFraction, - softwareCompensationParameters.m_minCleanHitEnergyFraction); - - registerProcessorParameter("MinCleanCorrectedHitEnergy", - "The minimum correction to on ecal hit in Pandora energy correction", - m_settings.m_minCleanCorrectedHitEnergy, - softwareCompensationParameters.m_minCleanCorrectedHitEnergy); +void DDPandoraPFANewProcessor::ProcessSteeringFile() { + registerProcessorParameter("PandoraSettingsXmlFile", "The pandora settings xml file", + m_settings.m_pandoraSettingsXmlFile, std::string()); + + // Input collections + registerInputCollections(LCIO::TRACK, "TrackCollections", "Names of the Track collections used for clustering", + m_trackCreatorSettings.m_trackCollections, StringVector()); + + registerInputCollections(LCIO::VERTEX, "KinkVertexCollections", "Name of external kink Vertex collections", + m_trackCreatorSettings.m_kinkVertexCollections, StringVector()); + + registerInputCollections(LCIO::VERTEX, "ProngVertexCollections", "Name of external prong Vertex collections", + m_trackCreatorSettings.m_prongVertexCollections, StringVector()); + + registerInputCollections(LCIO::VERTEX, "SplitVertexCollections", "Name of external split Vertex collections", + m_trackCreatorSettings.m_splitVertexCollections, StringVector()); + + registerInputCollections(LCIO::VERTEX, "V0VertexCollections", "Name of external V0 Vertex collections", + m_trackCreatorSettings.m_v0VertexCollections, StringVector()); + + registerInputCollections(LCIO::CALORIMETERHIT, "ECalCaloHitCollections", "Name of the ECAL calo hit collections", + m_caloHitCreatorSettings.m_eCalCaloHitCollections, StringVector()); + + registerInputCollections(LCIO::CALORIMETERHIT, "HCalCaloHitCollections", "Name of the HCAL calo hit collections", + m_caloHitCreatorSettings.m_hCalCaloHitCollections, StringVector()); + + registerInputCollections(LCIO::CALORIMETERHIT, "LCalCaloHitCollections", "Name of the LCAL calo hit collections", + m_caloHitCreatorSettings.m_lCalCaloHitCollections, StringVector()); + + registerInputCollections(LCIO::CALORIMETERHIT, "LHCalCaloHitCollections", "Name of the LHCAL calo hit collections", + m_caloHitCreatorSettings.m_lHCalCaloHitCollections, StringVector()); + + registerInputCollections(LCIO::CALORIMETERHIT, "MuonCaloHitCollections", "Name of the muon calo hit collections", + m_caloHitCreatorSettings.m_muonCaloHitCollections, StringVector()); + + registerInputCollections(LCIO::MCPARTICLE, "MCParticleCollections", "Name of mc particle collections", + m_mcParticleCreatorSettings.m_mcParticleCollections, StringVector()); + + registerInputCollections(LCIO::LCRELATION, "RelCaloHitCollections", "SimCaloHit to CaloHit Relations Collection Name", + m_mcParticleCreatorSettings.m_lcCaloHitRelationCollections, StringVector()); + + registerInputCollections(LCIO::LCRELATION, "RelTrackCollections", "Track to MCParticle Relations Collection Name", + m_mcParticleCreatorSettings.m_lcTrackRelationCollections, StringVector()); + + registerProcessorParameter("CreateGaps", "Decides whether to create gaps in the geometry (ILD-specific)", + m_geometryCreatorSettings.m_createGaps, bool(true)); + + // Name of PFO collection written by MarlinPandora + registerOutputCollection(LCIO::CLUSTER, "ClusterCollectionName", "Cluster Collection Name", + m_pfoCreatorSettings.m_clusterCollectionName, std::string("PandoraPFANewClusters")); + + registerOutputCollection(LCIO::RECONSTRUCTEDPARTICLE, "PFOCollectionName", "PFO Collection Name", + m_pfoCreatorSettings.m_pfoCollectionName, std::string("PandoraPFANewPFOs")); + registerOutputCollection(LCIO::VERTEX, "StartVertexCollectionName", "Start Vertex Collection Name", + m_pfoCreatorSettings.m_startVertexCollectionName, std::string("PandoraPFANewStartVertices")); + + registerProcessorParameter("StartVertexAlgorithmName", "The algorithm name for filling start vertex", + m_pfoCreatorSettings.m_startVertexAlgName, std::string("PandoraPFANew")); + + // Energy resolution parameters + registerProcessorParameter("EMStochasticTerm", "The stochastic term for EM shower", + m_pfoCreatorSettings.m_emStochasticTerm, float(0.17)); + + registerProcessorParameter("HadStochasticTerm", "The stochastic term for Hadronic shower", + m_pfoCreatorSettings.m_hadStochasticTerm, float(0.6)); + + registerProcessorParameter("EMConstantTerm", "The constant term for EM shower", m_pfoCreatorSettings.m_emConstantTerm, + float(0.01)); + + registerProcessorParameter("HadConstantTerm", "The constant term for Hadronic shower", + m_pfoCreatorSettings.m_hadConstantTerm, float(0.03)); + + // Calibration constants + registerProcessorParameter("ECalToMipCalibration", "The calibration from deposited ECal energy to mip", + m_caloHitCreatorSettings.m_eCalToMip, float(1.)); + + registerProcessorParameter("HCalToMipCalibration", "The calibration from deposited HCal energy to mip", + m_caloHitCreatorSettings.m_hCalToMip, float(1.)); + + registerProcessorParameter("ECalMipThreshold", "Threshold for creating calo hits in the ECal, units mip", + m_caloHitCreatorSettings.m_eCalMipThreshold, float(0.)); + + registerProcessorParameter("MuonToMipCalibration", "The calibration from deposited Muon energy to mip", + m_caloHitCreatorSettings.m_muonToMip, float(1.)); + + registerProcessorParameter("HCalMipThreshold", "Threshold for creating calo hits in the HCal, units mip", + m_caloHitCreatorSettings.m_hCalMipThreshold, float(0.)); + + registerProcessorParameter("ECalToEMGeVCalibration", "The calibration from deposited ECal energy to EM energy", + m_caloHitCreatorSettings.m_eCalToEMGeV, float(1.)); + + registerProcessorParameter("HCalToEMGeVCalibration", "The calibration from deposited HCal energy to EM energy", + m_caloHitCreatorSettings.m_hCalToEMGeV, float(1.)); + + registerProcessorParameter("ECalToHadGeVCalibrationEndCap", + "The calibration from deposited ECal energy to hadronic energy", + m_caloHitCreatorSettings.m_eCalToHadGeVEndCap, float(1.)); + + registerProcessorParameter("ECalToHadGeVCalibrationBarrel", + "The calibration from deposited ECal energy to hadronic energy", + m_caloHitCreatorSettings.m_eCalToHadGeVBarrel, float(1.)); + + registerProcessorParameter("HCalToHadGeVCalibration", "The calibration from deposited HCal energy to hadronic energy", + m_caloHitCreatorSettings.m_hCalToHadGeV, float(1.)); + + registerProcessorParameter("DigitalMuonHits", "Treat muon hits as digital", + m_caloHitCreatorSettings.m_muonDigitalHits, int(1)); + + registerProcessorParameter("MuonHitEnergy", "The energy for a digital muon calorimeter hit, units GeV", + m_caloHitCreatorSettings.m_muonHitEnergy, float(0.5)); + + registerProcessorParameter("MaxHCalHitHadronicEnergy", "The maximum hadronic energy allowed for a single hcal hit", + m_caloHitCreatorSettings.m_maxHCalHitHadronicEnergy, float(10000.)); + + registerProcessorParameter("NOuterSamplingLayers", + "Number of layers from edge for hit to be flagged as an outer layer hit", + m_caloHitCreatorSettings.m_nOuterSamplingLayers, int(3)); + + registerProcessorParameter("LayersFromEdgeMaxRearDistance", + "Maximum number of layers from candidate outer layer hit to rear of detector", + m_caloHitCreatorSettings.m_layersFromEdgeMaxRearDistance, float(250.f)); + + // B-field parameters + registerProcessorParameter("MuonBarrelBField", "The bfield in the muon barrel, units Tesla", + m_settings.m_muonBarrelBField, float(-1.5f)); + + registerProcessorParameter("MuonEndCapBField", "The bfield in the muon endcap, units Tesla", + m_settings.m_muonEndCapBField, float(0.01f)); + + registerProcessorParameter("UseDD4hepField", "Whether to use the BField map from DD4hep", m_settings.m_useDD4hepField, + false); + + // Track relationship parameters + registerProcessorParameter("ShouldFormTrackRelationships", + "Whether to form pandora track relationships using v0 and kink info", + m_trackCreatorSettings.m_shouldFormTrackRelationships, int(1)); + + // Initial track hit specifications + registerProcessorParameter("MinTrackHits", "Track quality cut: the minimum number of track hits", + m_trackCreatorSettings.m_minTrackHits, int(5)); + + registerProcessorParameter("MinFtdTrackHits", + "Track quality cut: the minimum number of ftd track hits for ftd only tracks", + m_trackCreatorSettings.m_minFtdTrackHits, int(0)); + + registerProcessorParameter("MaxTrackHits", "Track quality cut: the maximum number of track hits", + m_trackCreatorSettings.m_maxTrackHits, int(5000)); + + // Track PFO usage parameters + registerProcessorParameter("D0TrackCut", "Track d0 cut used to determine whether track can be used to form pfo", + m_trackCreatorSettings.m_d0TrackCut, float(50.)); + + registerProcessorParameter("Z0TrackCut", "Track z0 cut used to determine whether track can be used to form pfo", + m_trackCreatorSettings.m_z0TrackCut, float(50.)); + + registerProcessorParameter("UseNonVertexTracks", "Whether can form pfos from tracks that don't start at vertex", + m_trackCreatorSettings.m_usingNonVertexTracks, int(1)); + + registerProcessorParameter("UseUnmatchedNonVertexTracks", + "Whether can form pfos from unmatched tracks that don't start at vertex", + m_trackCreatorSettings.m_usingUnmatchedNonVertexTracks, int(0)); + + registerProcessorParameter("UseUnmatchedVertexTracks", + "Whether can form pfos from unmatched tracks that start at vertex", + m_trackCreatorSettings.m_usingUnmatchedVertexTracks, int(1)); + + registerProcessorParameter("UnmatchedVertexTrackMaxEnergy", "Maximum energy for unmatched vertex track", + m_trackCreatorSettings.m_unmatchedVertexTrackMaxEnergy, float(5.)); + + registerProcessorParameter("D0UnmatchedVertexTrackCut", + "d0 cut used to determine whether unmatched vertex track can form pfo", + m_trackCreatorSettings.m_d0UnmatchedVertexTrackCut, float(5.)); + + registerProcessorParameter("Z0UnmatchedVertexTrackCut", + "z0 cut used to determine whether unmatched vertex track can form pfo", + m_trackCreatorSettings.m_z0UnmatchedVertexTrackCut, float(5.)); + + registerProcessorParameter("ZCutForNonVertexTracks", + "Non vtx track z cut to determine whether track can be used to form pfo", + m_trackCreatorSettings.m_zCutForNonVertexTracks, float(250.)); + + // Track "reaches ecal" parameters + registerProcessorParameter("ReachesECalNBarrelTrackerHits", + "Minimum number of BarrelTracker hits to consider track as reaching ecal", + m_trackCreatorSettings.m_reachesECalNBarrelTrackerHits, int(11)); + + registerProcessorParameter("ReachesECalNFtdHits", "Minimum number of ftd hits to consider track as reaching ecal", + m_trackCreatorSettings.m_reachesECalNFtdHits, int(4)); + + registerProcessorParameter("ReachesECalBarrelTrackerOuterDistance", + "Max distance from track to BarrelTracker r max to id whether track reaches ecal", + m_trackCreatorSettings.m_reachesECalBarrelTrackerOuterDistance, float(-100.)); + + registerProcessorParameter("ReachesECalMinFtdLayer", "Min FTD layer for track to be considered to have reached ecal", + m_trackCreatorSettings.m_reachesECalMinFtdLayer, int(9)); + + registerProcessorParameter("ReachesECalBarrelTrackerZMaxDistance", + "Max distance from track to BarrelTracker z max to id whether track reaches ecal", + m_trackCreatorSettings.m_reachesECalBarrelTrackerZMaxDistance, float(-50.)); + + registerProcessorParameter("ReachesECalFtdZMaxDistance", + "Max distance from track hit to ftd z position to identify ftd hits", + m_trackCreatorSettings.m_reachesECalFtdZMaxDistance, float(1.)); + + registerProcessorParameter("CurvatureToMomentumFactor", "Constant relating track curvature in b field to momentum", + m_trackCreatorSettings.m_curvatureToMomentumFactor, float(0.3 / 2000.)); + + registerProcessorParameter("MinTrackECalDistanceFromIp", + "Sanity check on separation between ip and track projected ecal position", + m_trackCreatorSettings.m_minTrackECalDistanceFromIp, float(100.)); + + // Final track quality parameters + registerProcessorParameter("MaxTrackSigmaPOverP", "Cut on fractional track momentum error", + m_trackCreatorSettings.m_maxTrackSigmaPOverP, float(0.15)); + + registerProcessorParameter("MinMomentumForTrackHitChecks", + "Min track momentum required to perform final quality checks on number of hits", + m_trackCreatorSettings.m_minMomentumForTrackHitChecks, float(1.)); + + registerProcessorParameter("MinBarrelTrackerHitFractionOfExpected", + "Cut on fractional of expected number of BarrelTracker hits", + m_trackCreatorSettings.m_minBarrelTrackerHitFractionOfExpected, float(0.20)); + + registerProcessorParameter("MinFtdHitsForBarrelTrackerHitFraction", + "Cut on minimum number of FTD hits of BarrelTracker hit fraction to be applied", + m_trackCreatorSettings.m_minFtdHitsForBarrelTrackerHitFraction, int(2)); + + registerProcessorParameter("MaxBarrelTrackerInnerRDistance", + "Track cut on distance from BarrelTracker inner r to id whether track can form pfo", + m_trackCreatorSettings.m_maxBarrelTrackerInnerRDistance, float(50.)); + + registerProcessorParameter( + "TrackStateTolerance", + "Distance of possible second track state in the ECal Endcap to the ECal barrel inner radius", + m_trackCreatorSettings.m_trackStateTolerance, m_trackCreatorSettings.m_trackStateTolerance); + + registerProcessorParameter("TrackSystemName", + "Name of the track fitting system to be used (KalTest, DDKalTest, aidaTT, ... )", + m_trackCreatorSettings.m_trackingSystemName, m_trackCreatorSettings.m_trackingSystemName); + + // For Strip Splitting method and also for hybrid ECAL + registerProcessorParameter("StripSplittingOn", "To use strip splitting algorithm, this should be true", + m_caloHitCreatorSettings.m_stripSplittingOn, int(0)); + + // For Strip Splitting method and also for hybrid ECAL + registerProcessorParameter("UseEcalScLayers", "To use scintillator layers ~ hybrid ECAL, this should be true", + m_caloHitCreatorSettings.m_useEcalScLayers, int(0)); + + // Parameters for hybrid ECAL + // Energy to MIP for Si-layers and Sc-layers, respectively. + //Si + registerProcessorParameter("ECalSiToMipCalibration", "The calibration from deposited Si-layer energy to mip", + m_caloHitCreatorSettings.m_eCalSiToMip, float(1.)); + + //Sc + registerProcessorParameter("ECalScToMipCalibration", "The calibration from deposited Sc-layer energy to mip", + m_caloHitCreatorSettings.m_eCalScToMip, float(1.)); + + // MipThreshold for Si-layers and Sc-layers, respectively. + // Si + registerProcessorParameter("ECalSiMipThreshold", + "Threshold for creating calo hits in the Si-layers of ECAL, units mip", + m_caloHitCreatorSettings.m_eCalSiMipThreshold, float(0.)); + + //Sc + registerProcessorParameter("ECalScMipThreshold", + "Threshold for creating calo hits in the Sc-layers of ECAL, units mip", + m_caloHitCreatorSettings.m_eCalScMipThreshold, float(0.)); + + // EcalToEM for Si-layers and Sc-layers, respectively. + //Si + registerProcessorParameter("ECalSiToEMGeVCalibration", "The calibration from deposited Si-layer energy to EM energy", + m_caloHitCreatorSettings.m_eCalSiToEMGeV, float(1.)); + + //Sc + registerProcessorParameter("ECalScToEMGeVCalibration", "The calibration from deposited Sc-layer energy to EM energy", + m_caloHitCreatorSettings.m_eCalScToEMGeV, float(1.)); + + // EcalToHad for Si-layers and Sc-layers of the endcaps, respectively. + //Si + registerProcessorParameter("ECalSiToHadGeVCalibrationEndCap", + "The calibration from deposited Si-layer energy on the enecaps to hadronic energy", + m_caloHitCreatorSettings.m_eCalSiToHadGeVEndCap, float(1.)); + + //Sc + registerProcessorParameter("ECalScToHadGeVCalibrationEndCap", + "The calibration from deposited Sc-layer energy on the endcaps to hadronic energy", + m_caloHitCreatorSettings.m_eCalScToHadGeVEndCap, float(1.)); + + // EcalToHad for Si-layers and Sc-layers of the barrel, respectively. + //Si + registerProcessorParameter("ECalSiToHadGeVCalibrationBarrel", + "The calibration from deposited Si-layer energy on the barrel to hadronic energy", + m_caloHitCreatorSettings.m_eCalSiToHadGeVBarrel, float(1.)); + + //Sc + registerProcessorParameter("ECalScToHadGeVCalibrationBarrel", + "The calibration from deposited Sc-layer energy to the barrel hadronic energy", + m_caloHitCreatorSettings.m_eCalScToHadGeVBarrel, float(1.)); + + // Hadronic energy non-linearity correction + registerProcessorParameter("InputEnergyCorrectionPoints", "The input energy points for hadronic energy correction", + m_settings.m_inputEnergyCorrectionPoints, FloatVector()); + + registerProcessorParameter("OutputEnergyCorrectionPoints", "The output energy points for hadronic energy correction", + m_settings.m_outputEnergyCorrectionPoints, FloatVector()); + + ///EXTRA PARAMETERS FROM NIKIFOROS + registerProcessorParameter("TrackCreatorName", "The name of the DDTrackCreator implementation", + m_settings.m_trackCreatorName, std::string("DDTrackCreatorCLIC")); + + registerProcessorParameter("ECalBarrelNormalVector", + "Normal vector for the ECal barrel sensitive layers in local coordinates", + m_caloHitCreatorSettings.m_eCalBarrelNormalVector, std::vector({0.0, 0.0, 1.0})); + + registerProcessorParameter("HCalBarrelNormalVector", + "Normal vector for the HCal barrel sensitive layers in local coordinates", + m_caloHitCreatorSettings.m_hCalBarrelNormalVector, std::vector({0.0, 0.0, 1.0})); + + registerProcessorParameter("YokeBarrelNormalVector", + "Normal vector for the muon barrel sensitive layers in local coordinates", + m_caloHitCreatorSettings.m_muonBarrelNormalVector, std::vector({0.0, 0.0, 1.0})); + + // Re-use LCSoftwareCompensationParameters default values + lc_content::LCSoftwareCompensationParameters softwareCompensationParameters; + + registerProcessorParameter("SoftwareCompensationWeights", + "The 9 software compensation weights for Pandora energy correction", + m_settings.m_softCompParameters, softwareCompensationParameters.m_softCompParameters); + + registerProcessorParameter("SoftwareCompensationEnergyDensityBins", + "The 10 software compensation density bins for Pandora energy correction", + m_settings.m_softCompEnergyDensityBins, + softwareCompensationParameters.m_softCompEnergyDensityBins); + + registerProcessorParameter( + "FinalEnergyDensityBin", "The software compensation final energy density bins for Pandora energy correction", + m_settings.m_energyDensityFinalBin, softwareCompensationParameters.m_energyDensityFinalBin); + + registerProcessorParameter("MaxClusterEnergyToApplySoftComp", + "The maximum hadronic energy to apply software compensation in Pandora energy correction", + m_settings.m_maxClusterEnergyToApplySoftComp, + softwareCompensationParameters.m_maxClusterEnergyToApplySoftComp); + + registerProcessorParameter("MinCleanHitEnergy", + "The minimum hit energy to apply ecal correction in Pandora energy correction", + m_settings.m_minCleanHitEnergy, softwareCompensationParameters.m_minCleanHitEnergy); + + registerProcessorParameter("MinCleanHitEnergyFraction", + "The minimum hit energy fraction to apply ecal correction in Pandora energy correction", + m_settings.m_minCleanHitEnergyFraction, + softwareCompensationParameters.m_minCleanHitEnergyFraction); + + registerProcessorParameter( + "MinCleanCorrectedHitEnergy", "The minimum correction to on ecal hit in Pandora energy correction", + m_settings.m_minCleanCorrectedHitEnergy, softwareCompensationParameters.m_minCleanCorrectedHitEnergy); } //------------------------------------------------------------------------------------------------------------------------------------------ -void DDPandoraPFANewProcessor::FinaliseSteeringParameters() -{ - // ATTN: This function seems to be necessary for operations that cannot easily be performed at construction of the processor, - // when the steering file is parsed e.g. the call to GEAR to get the inner bfield - m_trackCreatorSettings.m_prongSplitVertexCollections = m_trackCreatorSettings.m_prongVertexCollections; - m_trackCreatorSettings.m_prongSplitVertexCollections.insert(m_trackCreatorSettings.m_prongSplitVertexCollections.end(),m_trackCreatorSettings.m_splitVertexCollections.begin(),m_trackCreatorSettings.m_splitVertexCollections.end()); - - m_trackCreatorSettings.m_bField=getFieldFromCompact(); - - //Get ECal Barrel extension by type, ignore plugs and rings - const dd4hep::rec::LayeredCalorimeterData * eCalBarrelExtension= getExtension( ( dd4hep::DetType::CALORIMETER | dd4hep::DetType::ELECTROMAGNETIC | dd4hep::DetType::BARREL), - ( dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD ) ); - //Get ECal Endcap extension by type, ignore plugs and rings - const dd4hep::rec::LayeredCalorimeterData * eCalEndcapExtension= getExtension( ( dd4hep::DetType::CALORIMETER | dd4hep::DetType::ELECTROMAGNETIC | dd4hep::DetType::ENDCAP), - ( dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD ) ); - //Get HCal Barrel extension by type, ignore plugs and rings - const dd4hep::rec::LayeredCalorimeterData * hCalBarrelExtension= getExtension( ( dd4hep::DetType::CALORIMETER | dd4hep::DetType::HADRONIC | dd4hep::DetType::BARREL), - ( dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD ) ); - //Get HCal Endcap extension by type, ignore plugs and rings - const dd4hep::rec::LayeredCalorimeterData * hCalEndcapExtension= getExtension( ( dd4hep::DetType::CALORIMETER | dd4hep::DetType::HADRONIC | dd4hep::DetType::ENDCAP), - ( dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD ) ); - //Get Muon Barrel extension by type, ignore plugs and rings - const dd4hep::rec::LayeredCalorimeterData * muonBarrelExtension= getExtension( ( dd4hep::DetType::CALORIMETER | dd4hep::DetType::MUON | dd4hep::DetType::BARREL), - ( dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD ) ); - //fg: muon endcap is not used : - // //Get Muon Endcap extension by type, ignore plugs and rings - // const dd4hep::rec::LayeredCalorimeterData * muonEndcapExtension= getExtension( ( dd4hep::DetType::CALORIMETER | dd4hep::DetType::MUON | dd4hep::DetType::ENDCAP), ( dd4hep::DetType::AUXILIARY ) ); - - //Get COIL extension - const dd4hep::rec::LayeredCalorimeterData * coilExtension= getExtension( ( dd4hep::DetType::COIL ) ); - - - m_trackCreatorSettings.m_eCalBarrelInnerSymmetry = eCalBarrelExtension->inner_symmetry; - m_trackCreatorSettings.m_eCalBarrelInnerPhi0 = eCalBarrelExtension->inner_phi0/dd4hep::rad; - m_trackCreatorSettings.m_eCalBarrelInnerR = eCalBarrelExtension->extent[0]/dd4hep::mm; - m_trackCreatorSettings.m_eCalEndCapInnerZ = eCalEndcapExtension->extent[2]/dd4hep::mm; - - m_caloHitCreatorSettings.m_eCalBarrelOuterZ = eCalBarrelExtension->extent[3]/dd4hep::mm; - m_caloHitCreatorSettings.m_hCalBarrelOuterZ = hCalBarrelExtension->extent[3]/dd4hep::mm; - m_caloHitCreatorSettings.m_muonBarrelOuterZ = muonBarrelExtension->extent[3]/dd4hep::mm; - m_caloHitCreatorSettings.m_coilOuterR = coilExtension->extent[1]/dd4hep::mm; - m_caloHitCreatorSettings.m_eCalBarrelInnerPhi0 = eCalBarrelExtension->inner_phi0/dd4hep::rad; - m_caloHitCreatorSettings.m_eCalBarrelInnerSymmetry = eCalBarrelExtension->inner_symmetry; - m_caloHitCreatorSettings.m_hCalBarrelInnerPhi0 = hCalBarrelExtension->inner_phi0/dd4hep::rad; - m_caloHitCreatorSettings.m_hCalBarrelInnerSymmetry = hCalBarrelExtension->inner_symmetry; - m_caloHitCreatorSettings.m_muonBarrelInnerPhi0 = muonBarrelExtension->inner_phi0/dd4hep::rad; - m_caloHitCreatorSettings.m_muonBarrelInnerSymmetry = muonBarrelExtension->inner_symmetry; - m_caloHitCreatorSettings.m_hCalEndCapOuterR = hCalEndcapExtension->extent[1]/dd4hep::mm; - m_caloHitCreatorSettings.m_hCalEndCapOuterZ = hCalEndcapExtension->extent[3]/dd4hep::mm; - m_caloHitCreatorSettings.m_hCalBarrelOuterR = hCalBarrelExtension->extent[1]/dd4hep::mm; - m_caloHitCreatorSettings.m_hCalBarrelOuterPhi0 = hCalBarrelExtension->outer_phi0/dd4hep::rad; - m_caloHitCreatorSettings.m_hCalBarrelOuterSymmetry = hCalBarrelExtension->outer_symmetry; - m_caloHitCreatorSettings.m_hCalEndCapInnerSymmetryOrder = hCalEndcapExtension->inner_symmetry;; - m_caloHitCreatorSettings.m_hCalEndCapInnerPhiCoordinate = hCalEndcapExtension->inner_phi0/dd4hep::rad;; - - // Get the magnetic field - dd4hep::Detector& mainDetector = dd4hep::Detector::getInstance(); - const double position[3]={0,0,0}; // position to calculate magnetic field at (the origin in this case) - double magneticFieldVector[3]={0,0,0}; // initialise object to hold magnetic field - mainDetector.field().magneticField(position,magneticFieldVector); // get the magnetic field vector from DD4hep - - m_settings.m_innerBField = magneticFieldVector[2]/dd4hep::tesla; // z component at (0,0,0) +void DDPandoraPFANewProcessor::FinaliseSteeringParameters() { + // ATTN: This function seems to be necessary for operations that cannot easily be performed at construction of the processor, + // when the steering file is parsed e.g. the call to GEAR to get the inner bfield + m_trackCreatorSettings.m_prongSplitVertexCollections = m_trackCreatorSettings.m_prongVertexCollections; + m_trackCreatorSettings.m_prongSplitVertexCollections.insert( + m_trackCreatorSettings.m_prongSplitVertexCollections.end(), + m_trackCreatorSettings.m_splitVertexCollections.begin(), m_trackCreatorSettings.m_splitVertexCollections.end()); + + m_trackCreatorSettings.m_bField = getFieldFromCompact(); + + //Get ECal Barrel extension by type, ignore plugs and rings + const dd4hep::rec::LayeredCalorimeterData* eCalBarrelExtension = + getExtension((dd4hep::DetType::CALORIMETER | dd4hep::DetType::ELECTROMAGNETIC | dd4hep::DetType::BARREL), + (dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD)); + //Get ECal Endcap extension by type, ignore plugs and rings + const dd4hep::rec::LayeredCalorimeterData* eCalEndcapExtension = + getExtension((dd4hep::DetType::CALORIMETER | dd4hep::DetType::ELECTROMAGNETIC | dd4hep::DetType::ENDCAP), + (dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD)); + //Get HCal Barrel extension by type, ignore plugs and rings + const dd4hep::rec::LayeredCalorimeterData* hCalBarrelExtension = + getExtension((dd4hep::DetType::CALORIMETER | dd4hep::DetType::HADRONIC | dd4hep::DetType::BARREL), + (dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD)); + //Get HCal Endcap extension by type, ignore plugs and rings + const dd4hep::rec::LayeredCalorimeterData* hCalEndcapExtension = + getExtension((dd4hep::DetType::CALORIMETER | dd4hep::DetType::HADRONIC | dd4hep::DetType::ENDCAP), + (dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD)); + //Get Muon Barrel extension by type, ignore plugs and rings + const dd4hep::rec::LayeredCalorimeterData* muonBarrelExtension = + getExtension((dd4hep::DetType::CALORIMETER | dd4hep::DetType::MUON | dd4hep::DetType::BARREL), + (dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD)); + //fg: muon endcap is not used : + // //Get Muon Endcap extension by type, ignore plugs and rings + // const dd4hep::rec::LayeredCalorimeterData * muonEndcapExtension= getExtension( ( dd4hep::DetType::CALORIMETER | dd4hep::DetType::MUON | dd4hep::DetType::ENDCAP), ( dd4hep::DetType::AUXILIARY ) ); + + //Get COIL extension + const dd4hep::rec::LayeredCalorimeterData* coilExtension = getExtension((dd4hep::DetType::COIL)); + + m_trackCreatorSettings.m_eCalBarrelInnerSymmetry = eCalBarrelExtension->inner_symmetry; + m_trackCreatorSettings.m_eCalBarrelInnerPhi0 = eCalBarrelExtension->inner_phi0 / dd4hep::rad; + m_trackCreatorSettings.m_eCalBarrelInnerR = eCalBarrelExtension->extent[0] / dd4hep::mm; + m_trackCreatorSettings.m_eCalEndCapInnerZ = eCalEndcapExtension->extent[2] / dd4hep::mm; + + m_caloHitCreatorSettings.m_eCalBarrelOuterZ = eCalBarrelExtension->extent[3] / dd4hep::mm; + m_caloHitCreatorSettings.m_hCalBarrelOuterZ = hCalBarrelExtension->extent[3] / dd4hep::mm; + m_caloHitCreatorSettings.m_muonBarrelOuterZ = muonBarrelExtension->extent[3] / dd4hep::mm; + m_caloHitCreatorSettings.m_coilOuterR = coilExtension->extent[1] / dd4hep::mm; + m_caloHitCreatorSettings.m_eCalBarrelInnerPhi0 = eCalBarrelExtension->inner_phi0 / dd4hep::rad; + m_caloHitCreatorSettings.m_eCalBarrelInnerSymmetry = eCalBarrelExtension->inner_symmetry; + m_caloHitCreatorSettings.m_hCalBarrelInnerPhi0 = hCalBarrelExtension->inner_phi0 / dd4hep::rad; + m_caloHitCreatorSettings.m_hCalBarrelInnerSymmetry = hCalBarrelExtension->inner_symmetry; + m_caloHitCreatorSettings.m_muonBarrelInnerPhi0 = muonBarrelExtension->inner_phi0 / dd4hep::rad; + m_caloHitCreatorSettings.m_muonBarrelInnerSymmetry = muonBarrelExtension->inner_symmetry; + m_caloHitCreatorSettings.m_hCalEndCapOuterR = hCalEndcapExtension->extent[1] / dd4hep::mm; + m_caloHitCreatorSettings.m_hCalEndCapOuterZ = hCalEndcapExtension->extent[3] / dd4hep::mm; + m_caloHitCreatorSettings.m_hCalBarrelOuterR = hCalBarrelExtension->extent[1] / dd4hep::mm; + m_caloHitCreatorSettings.m_hCalBarrelOuterPhi0 = hCalBarrelExtension->outer_phi0 / dd4hep::rad; + m_caloHitCreatorSettings.m_hCalBarrelOuterSymmetry = hCalBarrelExtension->outer_symmetry; + m_caloHitCreatorSettings.m_hCalEndCapInnerSymmetryOrder = hCalEndcapExtension->inner_symmetry; + ; + m_caloHitCreatorSettings.m_hCalEndCapInnerPhiCoordinate = hCalEndcapExtension->inner_phi0 / dd4hep::rad; + ; + + // Get the magnetic field + dd4hep::Detector& mainDetector = dd4hep::Detector::getInstance(); + const double position[3] = {0, 0, 0}; // position to calculate magnetic field at (the origin in this case) + double magneticFieldVector[3] = {0, 0, 0}; // initialise object to hold magnetic field + mainDetector.field().magneticField(position, magneticFieldVector); // get the magnetic field vector from DD4hep + + m_settings.m_innerBField = magneticFieldVector[2] / dd4hep::tesla; // z component at (0,0,0) } //------------------------------------------------------------------------------------------------------------------------------------------ -void DDPandoraPFANewProcessor::Reset() -{ - m_pCaloHitCreator->Reset(); - m_pTrackCreator->Reset(); +void DDPandoraPFANewProcessor::Reset() { + m_pCaloHitCreator->Reset(); + m_pTrackCreator->Reset(); - PandoraToLCEventMap::iterator iter = m_pandoraToLCEventMap.find(m_pPandora); + PandoraToLCEventMap::iterator iter = m_pandoraToLCEventMap.find(m_pPandora); - if (m_pandoraToLCEventMap.end() == iter) - throw pandora::StatusCodeException(pandora::STATUS_CODE_FAILURE); + if (m_pandoraToLCEventMap.end() == iter) + throw pandora::StatusCodeException(pandora::STATUS_CODE_FAILURE); - m_pandoraToLCEventMap.erase(iter); + m_pandoraToLCEventMap.erase(iter); } //------------------------------------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------------------------------------ -DDPandoraPFANewProcessor::Settings::Settings() : - m_innerBField(3.5f), - m_muonBarrelBField(-1.5f), - m_muonEndCapBField(0.01f), - m_inputEnergyCorrectionPoints(0), - m_outputEnergyCorrectionPoints(0), - m_trackCreatorName("") +DDPandoraPFANewProcessor::Settings::Settings() + : m_innerBField(3.5f), + m_muonBarrelBField(-1.5f), + m_muonEndCapBField(0.01f), + m_inputEnergyCorrectionPoints(0), + m_outputEnergyCorrectionPoints(0), + m_trackCreatorName("") -{ -} +{} diff --git a/k4GaudiPandora/src/DDPfoCreator.cc b/k4GaudiPandora/src/DDPfoCreator.cc index 7643265..57a807a 100644 --- a/k4GaudiPandora/src/DDPfoCreator.cc +++ b/k4GaudiPandora/src/DDPfoCreator.cc @@ -1,28 +1,47 @@ +/* + * Copyright (c) 2020-2024 Key4hep-Project. + * + * This file is part of Key4hep. + * See https://key4hep.github.io/key4hep-doc/ for further info. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + /** * @file DDMarlinPandora/src/DDPfoCreator.cc - * + * * @brief Implementation of the pfo creator class. - * + * * $Log: $ */ #include "DDPfoCreator.h" -#include "k4FWCore/DataHandle.h" -#include "edm4hep/Vector3f.h" -#include "edm4hep/ClusterCollection.h" +#include "Api/PandoraApi.h" +#include "edm4hep/CalorimeterHit.h" +#include "edm4hep/CalorimeterHitCollection.h" #include "edm4hep/Cluster.h" -#include "edm4hep/ReconstructedParticleCollection.h" +#include "edm4hep/ClusterCollection.h" #include "edm4hep/ReconstructedParticle.h" -#include "edm4hep/VertexCollection.h" -#include "edm4hep/Vertex.h" -#include "edm4hep/TrackCollection.h" +#include "edm4hep/ReconstructedParticleCollection.h" #include "edm4hep/Track.h" -#include "edm4hep/CalorimeterHitCollection.h" -#include "edm4hep/CalorimeterHit.h" +#include "edm4hep/TrackCollection.h" +#include "edm4hep/Vector3f.h" +#include "edm4hep/Vertex.h" +#include "edm4hep/VertexCollection.h" +#include "k4FWCore/DataHandle.h" #include "marlin/Global.h" #include "marlin/Processor.h" -#include "Api/PandoraApi.h" #include "Objects/Cluster.h" #include "Objects/ParticleFlowObject.h" @@ -33,401 +52,401 @@ #include #include -DDPfoCreator::DDPfoCreator(const Settings &settings, const pandora::Pandora *const pPandora) : - m_settings(settings), - m_pandora(*pPandora) -{ -} +DDPfoCreator::DDPfoCreator(const Settings& settings, const pandora::Pandora* const pPandora) + : m_settings(settings), m_pandora(*pPandora) {} //------------------------------------------------------------------------------------------------------------------------------------------ -DDPfoCreator::~DDPfoCreator() -{ -} +DDPfoCreator::~DDPfoCreator() {} //------------------------------------------------------------------------------------------------------------------------------------------ +pandora::StatusCode DDPfoCreator::CreateParticleFlowObjects( + CollectionMaps& collectionMaps, DataHandle& _pClusterCollection, + DataHandle& _pReconstructedParticleCollection, + DataHandle& _pStartVertexCollection) { + m_collectionMaps = &collectionMaps; + edm4hep::ClusterCollection* pClusterCollection = _pClusterCollection.createAndPut(); + edm4hep::ReconstructedParticleCollection* pReconstructedParticleCollection = + _pReconstructedParticleCollection.createAndPut(); + edm4hep::VertexCollection* pStartVertexCollection = _pStartVertexCollection.createAndPut(); + + const pandora::PfoList* pPandoraPfoList = NULL; + PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::GetCurrentPfoList(m_pandora, pPandoraPfoList)); + + pandora::StringVector subDetectorNames; + this->InitialiseSubDetectorNames(subDetectorNames); + + pandora::StringVector subDetectorNames; + this->InitialiseSubDetectorNames(subDetectorNames); + pClusterCollection->parameters().setValues("ClusterSubdetectorNames", subDetectorNames); + + // Create lcio "reconstructed particles" from the pandora "particle flow objects" + for (pandora::PfoList::const_iterator pIter = pPandoraPfoList->begin(), pIterEnd = pPandoraPfoList->end(); + pIter != pIterEnd; ++pIter) { + const pandora::ParticleFlowObject* const pPandoraPfo(*pIter); + edm4hep::ReconstructedParticle pReconstructedParticle0 = pReconstructedParticleCollection->create(); + edm4hep::ReconstructedParticle* pReconstructedParticle = &pReconstructedParticle0; + + const bool hasTrack(!pPandoraPfo->GetTrackList().empty()); + const pandora::ClusterList& clusterList(pPandoraPfo->GetClusterList()); + + float clustersTotalEnergy(0.f); + pandora::CartesianVector referencePoint(0.f, 0.f, 0.f), clustersWeightedPosition(0.f, 0.f, 0.f); + for (pandora::ClusterList::const_iterator cIter = clusterList.begin(), cIterEnd = clusterList.end(); + cIter != cIterEnd; ++cIter) { + const pandora::Cluster* const pPandoraCluster(*cIter); + pandora::CaloHitList pandoraCaloHitList; + pPandoraCluster->GetOrderedCaloHitList().FillCaloHitList(pandoraCaloHitList); + pandoraCaloHitList.insert(pandoraCaloHitList.end(), pPandoraCluster->GetIsolatedCaloHitList().begin(), + pPandoraCluster->GetIsolatedCaloHitList().end()); + + pandora::FloatVector hitE, hitX, hitY, hitZ; + edm4hep::Cluster p_Cluster0 = pClusterCollection->create(); + edm4hep::Cluster* p_Cluster = &p_Cluster0; + this->SetClusterSubDetectorEnergies(subDetectorNames, p_Cluster, pandoraCaloHitList, hitE, hitX, hitY, hitZ); + + float clusterCorrectEnergy(0.f); + this->SetClusterEnergyAndError(pPandoraPfo, pPandoraCluster, p_Cluster, clusterCorrectEnergy); + + pandora::CartesianVector clusterPosition(0.f, 0.f, 0.f); + const unsigned int nHitsInCluster(pandoraCaloHitList.size()); + this->SetClusterPositionAndError(nHitsInCluster, hitE, hitX, hitY, hitZ, p_Cluster, clusterPosition); + + if (!hasTrack) { + clustersWeightedPosition += clusterPosition * clusterCorrectEnergy; + clustersTotalEnergy += clusterCorrectEnergy; + } + + edm4hep::ConstCluster p_ClusterCon = *p_Cluster; + pReconstructedParticle->addCluster(p_Cluster); + } -pandora::StatusCode DDPfoCreator::CreateParticleFlowObjects(CollectionMaps& collectionMaps, DataHandle& _pClusterCollection, DataHandle& _pReconstructedParticleCollection, DataHandle& _pStartVertexCollection) -{ - m_collectionMaps = &collectionMaps; - edm4hep::ClusterCollection* pClusterCollection = _pClusterCollection.createAndPut(); - edm4hep::ReconstructedParticleCollection* pReconstructedParticleCollection = _pReconstructedParticleCollection.createAndPut(); - edm4hep::VertexCollection* pStartVertexCollection = _pStartVertexCollection.createAndPut(); - - const pandora::PfoList *pPandoraPfoList = NULL; - PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::GetCurrentPfoList(m_pandora, pPandoraPfoList)); - - pandora::StringVector subDetectorNames; - this->InitialiseSubDetectorNames(subDetectorNames); - - pandora::StringVector subDetectorNames; - this->InitialiseSubDetectorNames(subDetectorNames); - pClusterCollection->parameters().setValues("ClusterSubdetectorNames", subDetectorNames); - - // Create lcio "reconstructed particles" from the pandora "particle flow objects" - for (pandora::PfoList::const_iterator pIter = pPandoraPfoList->begin(), pIterEnd = pPandoraPfoList->end(); pIter != pIterEnd; ++pIter) - { - const pandora::ParticleFlowObject *const pPandoraPfo(*pIter); - edm4hep::ReconstructedParticle pReconstructedParticle0 = pReconstructedParticleCollection->create(); - edm4hep::ReconstructedParticle* pReconstructedParticle = &pReconstructedParticle0; - - const bool hasTrack(!pPandoraPfo->GetTrackList().empty()); - const pandora::ClusterList &clusterList(pPandoraPfo->GetClusterList()); - - float clustersTotalEnergy(0.f); - pandora::CartesianVector referencePoint(0.f, 0.f, 0.f), clustersWeightedPosition(0.f, 0.f, 0.f); - for (pandora::ClusterList::const_iterator cIter = clusterList.begin(), cIterEnd = clusterList.end(); cIter != cIterEnd; ++cIter) - { - const pandora::Cluster *const pPandoraCluster(*cIter); - pandora::CaloHitList pandoraCaloHitList; - pPandoraCluster->GetOrderedCaloHitList().FillCaloHitList(pandoraCaloHitList); - pandoraCaloHitList.insert(pandoraCaloHitList.end(), pPandoraCluster->GetIsolatedCaloHitList().begin(), pPandoraCluster->GetIsolatedCaloHitList().end()); - - pandora::FloatVector hitE, hitX, hitY, hitZ; - edm4hep::Cluster p_Cluster0 = pClusterCollection->create(); - edm4hep::Cluster* p_Cluster = &p_Cluster0; - this->SetClusterSubDetectorEnergies(subDetectorNames, p_Cluster, pandoraCaloHitList, hitE, hitX, hitY, hitZ); - - float clusterCorrectEnergy(0.f); - this->SetClusterEnergyAndError(pPandoraPfo, pPandoraCluster, p_Cluster, clusterCorrectEnergy); - - pandora::CartesianVector clusterPosition(0.f, 0.f, 0.f); - const unsigned int nHitsInCluster(pandoraCaloHitList.size()); - this->SetClusterPositionAndError(nHitsInCluster, hitE, hitX, hitY, hitZ, p_Cluster, clusterPosition); - - if (!hasTrack) - { - clustersWeightedPosition += clusterPosition * clusterCorrectEnergy; - clustersTotalEnergy += clusterCorrectEnergy; - } - - edm4hep::ConstCluster p_ClusterCon = *p_Cluster; - pReconstructedParticle->addCluster(p_Cluster); - } - - if (!hasTrack) - { - if (clustersTotalEnergy < std::numeric_limits::epsilon()) - { - streamlog_out(WARNING) << "DDPfoCreator::CreateParticleFlowObjects: invalid cluster energy " << clustersTotalEnergy << std::endl; - throw pandora::StatusCodeException(pandora::STATUS_CODE_FAILURE); - } - else - { - referencePoint = clustersWeightedPosition * (1.f / clustersTotalEnergy); - } - } - else - { - PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, this->CalculateTrackBasedReferencePoint(pPandoraPfo, referencePoint)); - } - - this->SetRecoParticleReferencePoint(referencePoint, pReconstructedParticle); - this->AddTracksToRecoParticle(pPandoraPfo, pReconstructedParticle); - this->SetRecoParticlePropertiesFromPFO(pPandoraPfo, pReconstructedParticle); - pReconstructedParticleCollection->addElement(pReconstructedParticle); - - edm4hep::Vertex pStartVertex0 = pStartVertexCollection->create(); - edm4hep::Vertex* pStartVertex = &pStartVertex0; - pStartVertex->setAlgorithmType(0); - const float ref_value[3] = {referencePoint.GetX(),referencePoint.GetY(),referencePoint.GetZ()}; - pStartVertex->setPosition(edm4hep::Vector3f(ref_value)); - pStartVertex->setAssociatedParticle(*pReconstructedParticle); + if (!hasTrack) { + if (clustersTotalEnergy < std::numeric_limits::epsilon()) { + streamlog_out(WARNING) << "DDPfoCreator::CreateParticleFlowObjects: invalid cluster energy " + << clustersTotalEnergy << std::endl; + throw pandora::StatusCodeException(pandora::STATUS_CODE_FAILURE); + } else { + referencePoint = clustersWeightedPosition * (1.f / clustersTotalEnergy); + } + } else { + PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, + this->CalculateTrackBasedReferencePoint(pPandoraPfo, referencePoint)); } - return pandora::STATUS_CODE_SUCCESS; + this->SetRecoParticleReferencePoint(referencePoint, pReconstructedParticle); + this->AddTracksToRecoParticle(pPandoraPfo, pReconstructedParticle); + this->SetRecoParticlePropertiesFromPFO(pPandoraPfo, pReconstructedParticle); + pReconstructedParticleCollection->addElement(pReconstructedParticle); + + edm4hep::Vertex pStartVertex0 = pStartVertexCollection->create(); + edm4hep::Vertex* pStartVertex = &pStartVertex0; + pStartVertex->setAlgorithmType(0); + const float ref_value[3] = {referencePoint.GetX(), referencePoint.GetY(), referencePoint.GetZ()}; + pStartVertex->setPosition(edm4hep::Vector3f(ref_value)); + pStartVertex->setAssociatedParticle(*pReconstructedParticle); + } + + return pandora::STATUS_CODE_SUCCESS; } //------------------------------------------------------------------------------------------------------------------------------------------ -void DDPfoCreator::InitialiseSubDetectorNames(pandora::StringVector &subDetectorNames) const -{ - subDetectorNames.push_back("ecal"); - subDetectorNames.push_back("hcal"); - subDetectorNames.push_back("yoke"); - subDetectorNames.push_back("lcal"); - subDetectorNames.push_back("lhcal"); - subDetectorNames.push_back("bcal"); +void DDPfoCreator::InitialiseSubDetectorNames(pandora::StringVector& subDetectorNames) const { + subDetectorNames.push_back("ecal"); + subDetectorNames.push_back("hcal"); + subDetectorNames.push_back("yoke"); + subDetectorNames.push_back("lcal"); + subDetectorNames.push_back("lhcal"); + subDetectorNames.push_back("bcal"); } //------------------------------------------------------------------------------------------------------------------------------------------ -void DDPfoCreator::SetClusterSubDetectorEnergies(const pandora::StringVector &subDetectorNames, edm4hep::Cluster *const p_Cluster, - const pandora::CaloHitList &pandoraCaloHitList, pandora::FloatVector &hitE, pandora::FloatVector &hitX, pandora::FloatVector &hitY, - pandora::FloatVector &hitZ) const -{ - for (pandora::CaloHitList::const_iterator hIter = pandoraCaloHitList.begin(), hIterEnd = pandoraCaloHitList.end(); hIter != hIterEnd; ++hIter) - { - edm4hep::CalorimeterHit *const pCalorimeterHit0 = (edm4hep::CalorimeterHit*)(pPandoraCaloHit->GetParentAddress()); - const edm4hep::CalorimeterHit pCalorimeterHit = *pCalorimeterHit0; - - p_Cluster->addToHits(pCalorimeterHit); - - const float caloHitEnergy(pCalorimeterHit->getEnergy()); - hitE.push_back(caloHitEnergy); - hitX.push_back(pCalorimeterHit->getPosition()[0]); - hitY.push_back(pCalorimeterHit->getPosition()[1]); - hitZ.push_back(pCalorimeterHit->getPosition()[2]); - - std::vector &subDetectorEnergies = pLcioCluster->subdetectorEnergies(); - subDetectorEnergies.resize(subDetectorNames.size()); - - switch (CHT(pCalorimeterHit->getType()).caloID()) - { - case CHT::ecal: subDetectorEnergies[ECAL_INDEX ] += caloHitEnergy; break; - case CHT::hcal: subDetectorEnergies[HCAL_INDEX ] += caloHitEnergy; break; - case CHT::yoke: subDetectorEnergies[YOKE_INDEX ] += caloHitEnergy; break; - case CHT::lcal: subDetectorEnergies[LCAL_INDEX ] += caloHitEnergy; break; - case CHT::lhcal: subDetectorEnergies[LHCAL_INDEX] += caloHitEnergy; break; - case CHT::bcal: subDetectorEnergies[BCAL_INDEX ] += caloHitEnergy; break; - default: streamlog_out(WARNING) << "DDPfoCreator::SetClusterSubDetectorEnergies: no subdetector found for hit with type: " << pCalorimeterHit->getType() << std::endl; - } +void DDPfoCreator::SetClusterSubDetectorEnergies(const pandora::StringVector& subDetectorNames, + edm4hep::Cluster* const p_Cluster, + const pandora::CaloHitList& pandoraCaloHitList, + pandora::FloatVector& hitE, pandora::FloatVector& hitX, + pandora::FloatVector& hitY, pandora::FloatVector& hitZ) const { + for (pandora::CaloHitList::const_iterator hIter = pandoraCaloHitList.begin(), hIterEnd = pandoraCaloHitList.end(); + hIter != hIterEnd; ++hIter) { + edm4hep::CalorimeterHit* const pCalorimeterHit0 = (edm4hep::CalorimeterHit*)(pPandoraCaloHit->GetParentAddress()); + const edm4hep::CalorimeterHit pCalorimeterHit = *pCalorimeterHit0; + + p_Cluster->addToHits(pCalorimeterHit); + + const float caloHitEnergy(pCalorimeterHit->getEnergy()); + hitE.push_back(caloHitEnergy); + hitX.push_back(pCalorimeterHit->getPosition()[0]); + hitY.push_back(pCalorimeterHit->getPosition()[1]); + hitZ.push_back(pCalorimeterHit->getPosition()[2]); + + std::vector& subDetectorEnergies = pLcioCluster->subdetectorEnergies(); + subDetectorEnergies.resize(subDetectorNames.size()); + + switch (CHT(pCalorimeterHit->getType()).caloID()) { + case CHT::ecal: + subDetectorEnergies[ECAL_INDEX] += caloHitEnergy; + break; + case CHT::hcal: + subDetectorEnergies[HCAL_INDEX] += caloHitEnergy; + break; + case CHT::yoke: + subDetectorEnergies[YOKE_INDEX] += caloHitEnergy; + break; + case CHT::lcal: + subDetectorEnergies[LCAL_INDEX] += caloHitEnergy; + break; + case CHT::lhcal: + subDetectorEnergies[LHCAL_INDEX] += caloHitEnergy; + break; + case CHT::bcal: + subDetectorEnergies[BCAL_INDEX] += caloHitEnergy; + break; + default: + streamlog_out(WARNING) + << "DDPfoCreator::SetClusterSubDetectorEnergies: no subdetector found for hit with type: " + << pCalorimeterHit->getType() << std::endl; } + } } //------------------------------------------------------------------------------------------------------------------------------------------ -void DDPfoCreator::SetClusterEnergyAndError(const pandora::ParticleFlowObject *const pPandoraPfo, const pandora::Cluster *const pPandoraCluster, - edm4hep::Cluster *const pLcioCluster, float &clusterCorrectEnergy) const -{ - const bool isEmShower((pandora::PHOTON == pPandoraPfo->GetParticleId()) || (pandora::E_MINUS == std::abs(pPandoraPfo->GetParticleId()))); - clusterCorrectEnergy = (isEmShower ? pPandoraCluster->GetCorrectedElectromagneticEnergy(m_pandora) : pPandoraCluster->GetCorrectedHadronicEnergy(m_pandora)); - - if (clusterCorrectEnergy < std::numeric_limits::epsilon()) - throw pandora::StatusCodeException(pandora::STATUS_CODE_FAILURE); - - const float stochasticTerm(isEmShower ? m_settings.m_emStochasticTerm : m_settings.m_hadStochasticTerm); - const float constantTerm(isEmShower ? m_settings.m_emConstantTerm : m_settings.m_hadConstantTerm); - const float energyError(std::sqrt(stochasticTerm * stochasticTerm / clusterCorrectEnergy + constantTerm * constantTerm) * clusterCorrectEnergy); - - p_Cluster->setEnergy(clusterCorrectEnergy); - p_Cluster->setEnergyError(energyError); +void DDPfoCreator::SetClusterEnergyAndError(const pandora::ParticleFlowObject* const pPandoraPfo, + const pandora::Cluster* const pPandoraCluster, + edm4hep::Cluster* const pLcioCluster, float& clusterCorrectEnergy) const { + const bool isEmShower((pandora::PHOTON == pPandoraPfo->GetParticleId()) || + (pandora::E_MINUS == std::abs(pPandoraPfo->GetParticleId()))); + clusterCorrectEnergy = (isEmShower ? pPandoraCluster->GetCorrectedElectromagneticEnergy(m_pandora) + : pPandoraCluster->GetCorrectedHadronicEnergy(m_pandora)); + + if (clusterCorrectEnergy < std::numeric_limits::epsilon()) + throw pandora::StatusCodeException(pandora::STATUS_CODE_FAILURE); + + const float stochasticTerm(isEmShower ? m_settings.m_emStochasticTerm : m_settings.m_hadStochasticTerm); + const float constantTerm(isEmShower ? m_settings.m_emConstantTerm : m_settings.m_hadConstantTerm); + const float energyError( + std::sqrt(stochasticTerm * stochasticTerm / clusterCorrectEnergy + constantTerm * constantTerm) * + clusterCorrectEnergy); + + p_Cluster->setEnergy(clusterCorrectEnergy); + p_Cluster->setEnergyError(energyError); } //------------------------------------------------------------------------------------------------------------------------------------------ -void DDPfoCreator::SetClusterPositionAndError(const unsigned int nHitsInCluster, pandora::FloatVector &hitE, pandora::FloatVector &hitX, - pandora::FloatVector &hitY, pandora::FloatVector &hitZ, IMPL::edm4hep::Cluster *const pLcioCluster, pandora::CartesianVector &clusterPositionVec) const -{ - ClusterShapes *const pClusterShapes(new ClusterShapes(nHitsInCluster, hitE.data(), hitX.data(), hitY.data(), hitZ.data())); - - try - { - p_Cluster->setIPhi(std::atan2(pClusterShapes->getEigenVecInertia()[1], pClusterShapes->getEigenVecInertia()[0])); - p_Cluster->setITheta(std::acos(pClusterShapes->getEigenVecInertia()[2])); - p_Cluster->setPosition(pClusterShapes->getCentreOfGravity()); - //ATTN these two lines below would only compile with ilcsoft HEAD V2015-10-13 and above - //pLcioCluster->setPositionError(pClusterShapes->getCenterOfGravityErrors()); - //pLcioCluster->setDirectionError(pClusterShapes->getEigenVecInertiaErrors()); - clusterPositionVec.SetValues(pClusterShapes->getCentreOfGravity()[0], pClusterShapes->getCentreOfGravity()[1], pClusterShapes->getCentreOfGravity()[2]); - } - catch (...) - { - streamlog_out(WARNING) << "DDPfoCreator::SetClusterPositionAndError: unidentified exception caught." << std::endl; - } - - delete pClusterShapes; +void DDPfoCreator::SetClusterPositionAndError(const unsigned int nHitsInCluster, pandora::FloatVector& hitE, + pandora::FloatVector& hitX, pandora::FloatVector& hitY, + pandora::FloatVector& hitZ, IMPL::edm4hep::Cluster* const pLcioCluster, + pandora::CartesianVector& clusterPositionVec) const { + ClusterShapes* const pClusterShapes( + new ClusterShapes(nHitsInCluster, hitE.data(), hitX.data(), hitY.data(), hitZ.data())); + + try { + p_Cluster->setIPhi(std::atan2(pClusterShapes->getEigenVecInertia()[1], pClusterShapes->getEigenVecInertia()[0])); + p_Cluster->setITheta(std::acos(pClusterShapes->getEigenVecInertia()[2])); + p_Cluster->setPosition(pClusterShapes->getCentreOfGravity()); + //ATTN these two lines below would only compile with ilcsoft HEAD V2015-10-13 and above + //pLcioCluster->setPositionError(pClusterShapes->getCenterOfGravityErrors()); + //pLcioCluster->setDirectionError(pClusterShapes->getEigenVecInertiaErrors()); + clusterPositionVec.SetValues(pClusterShapes->getCentreOfGravity()[0], pClusterShapes->getCentreOfGravity()[1], + pClusterShapes->getCentreOfGravity()[2]); + } catch (...) { + streamlog_out(WARNING) << "DDPfoCreator::SetClusterPositionAndError: unidentified exception caught." << std::endl; + } + + delete pClusterShapes; } //------------------------------------------------------------------------------------------------------------------------------------------ -pandora::StatusCode DDPfoCreator::CalculateTrackBasedReferencePoint(const pandora::ParticleFlowObject *const pPandoraPfo, pandora::CartesianVector &referencePoint) const -{ - const pandora::TrackList &trackList(pPandoraPfo->GetTrackList()); - - float totalTrackMomentumAtDca(0.f), totalTrackMomentumAtStart(0.f); - pandora::CartesianVector referencePointAtDCAWeighted(0.f, 0.f, 0.f), referencePointAtStartWeighted(0.f, 0.f, 0.f); - - bool hasSiblings(false); - for (pandora::TrackList::const_iterator tIter = trackList.begin(), tIterEnd = trackList.end(); tIter != tIterEnd; ++tIter) - { - const pandora::Track *const pPandoraTrack(*tIter); - - if (!this->IsValidParentTrack(pPandoraTrack, trackList)) - continue; - - if (this->HasValidSiblingTrack(pPandoraTrack, trackList)) - { - // Presence of sibling tracks typically represents a conversion - const pandora::CartesianVector &trackStartPoint((pPandoraTrack->GetTrackStateAtStart()).GetPosition()); - const float trackStartMome m_clusterCollectionName(""), - m_pfoCollectionName(""), - m_startVertexCollectionName(""), - m_startVertexAlgName(""),ntum(((pPandoraTrack->GetTrackStateAtStart()).GetMomentum()).GetMagnitude()); - referencePointAtStartWeighted += trackStartPoint * trackStartMomentum; - totalTrackMomentumAtStart += trackStartMomentum; - hasSiblings = true; - } - else - { - const edm4hep::Track *const pLcioTrack0 = (edm4hep::Track*)(pPandoraTrack->GetParentAddress()); - const edm4hep::Track pLcioTrack = *pLcioTrack0; - - const float z0(pPandoraTrack->GetZ0()); - pandora::CartesianVector intersectionPoint(0.f, 0.f, 0.f); - - intersectionPoint.SetValues(pLcioTrack->getD0() * std::cos(pLcioTrack->getPhi()), pLcioTrack->getD0() * std::sin(pLcioTrack->getPhi()), z0); - const float trackMomentumAtDca((pPandoraTrack->GetMomentumAtDca()).GetMagnitude()); - referencePointAtDCAWeighted += intersectionPoint * trackMomentumAtDca; - totalTrackMomentumAtDca += trackMomentumAtDca; - } +pandora::StatusCode DDPfoCreator::CalculateTrackBasedReferencePoint( + const pandora::ParticleFlowObject* const pPandoraPfo, pandora::CartesianVector& referencePoint) const { + const pandora::TrackList& trackList(pPandoraPfo->GetTrackList()); + + float totalTrackMomentumAtDca(0.f), totalTrackMomentumAtStart(0.f); + pandora::CartesianVector referencePointAtDCAWeighted(0.f, 0.f, 0.f), referencePointAtStartWeighted(0.f, 0.f, 0.f); + + bool hasSiblings(false); + for (pandora::TrackList::const_iterator tIter = trackList.begin(), tIterEnd = trackList.end(); tIter != tIterEnd; + ++tIter) { + const pandora::Track* const pPandoraTrack(*tIter); + + if (!this->IsValidParentTrack(pPandoraTrack, trackList)) + continue; + + if (this->HasValidSiblingTrack(pPandoraTrack, trackList)) { + // Presence of sibling tracks typically represents a conversion + const pandora::CartesianVector& trackStartPoint((pPandoraTrack->GetTrackStateAtStart()).GetPosition()); + const float trackStartMome m_clusterCollectionName(""), m_pfoCollectionName(""), m_startVertexCollectionName(""), + m_startVertexAlgName(""), ntum(((pPandoraTrack->GetTrackStateAtStart()).GetMomentum()).GetMagnitude()); + referencePointAtStartWeighted += trackStartPoint * trackStartMomentum; + totalTrackMomentumAtStart += trackStartMomentum; + hasSiblings = true; + } else { + const edm4hep::Track* const pLcioTrack0 = (edm4hep::Track*)(pPandoraTrack->GetParentAddress()); + const edm4hep::Track pLcioTrack = *pLcioTrack0; + + const float z0(pPandoraTrack->GetZ0()); + pandora::CartesianVector intersectionPoint(0.f, 0.f, 0.f); + + intersectionPoint.SetValues(pLcioTrack->getD0() * std::cos(pLcioTrack->getPhi()), + pLcioTrack->getD0() * std::sin(pLcioTrack->getPhi()), z0); + const float trackMomentumAtDca((pPandoraTrack->GetMomentumAtDca()).GetMagnitude()); + referencePointAtDCAWeighted += intersectionPoint * trackMomentumAtDca; + totalTrackMomentumAtDca += trackMomentumAtDca; } - - if (hasSiblings) - { - if (totalTrackMomentumAtStart < std::numeric_limits::epsilon()) - { - streamlog_out(WARNING) << "DDPfoCreator::CalculateTrackBasedReferencePoint: invalid track momentum " << totalTrackMomentumAtStart << std::endl; - throw pandora::StatusCodeException(pandora::STATUS_CODE_FAILURE); - } - else - { - referencePoint = referencePointAtStartWeighted * (1.f / totalTrackMomentumAtStart); - } + } + + if (hasSiblings) { + if (totalTrackMomentumAtStart < std::numeric_limits::epsilon()) { + streamlog_out(WARNING) << "DDPfoCreator::CalculateTrackBasedReferencePoint: invalid track momentum " + << totalTrackMomentumAtStart << std::endl; + throw pandora::StatusCodeException(pandora::STATUS_CODE_FAILURE); + } else { + referencePoint = referencePointAtStartWeighted * (1.f / totalTrackMomentumAtStart); } - else - { - if (totalTrackMomentumAtDca < std::numeric_limits::epsilon()) - { - streamlog_out(WARNING) << "DDPfoCreator::CalculateTrackBasedReferencePoint: invalid track momentum " << totalTrackMomentumAtDca << std::endl; - throw pandora::StatusCodeException(pandora::STATUS_CODE_FAILURE); - } - else - { - referencePoint = referencePointAtDCAWeighted * (1.f / totalTrackMomentumAtDca); - } + } else { + if (totalTrackMomentumAtDca < std::numeric_limits::epsilon()) { + streamlog_out(WARNING) << "DDPfoCreator::CalculateTrackBasedReferencePoint: invalid track momentum " + << totalTrackMomentumAtDca << std::endl; + throw pandora::StatusCodeException(pandora::STATUS_CODE_FAILURE); + } else { + referencePoint = referencePointAtDCAWeighted * (1.f / totalTrackMomentumAtDca); } + } - return pandora::STATUS_CODE_SUCCESS; + return pandora::STATUS_CODE_SUCCESS; } //------------------------------------------------------------------------------------------------------------------------------------------ -bool DDPfoCreator::IsValidParentTrack(const pandora::Track *const pPandoraTrack, const pandora::TrackList &allTrackList) const -{ - const pandora::TrackList &parentTrackList(pPandoraTrack->GetParentList()); +bool DDPfoCreator::IsValidParentTrack(const pandora::Track* const pPandoraTrack, + const pandora::TrackList& allTrackList) const { + const pandora::TrackList& parentTrackList(pPandoraTrack->GetParentList()); - for (pandora::TrackList::const_iterator iter = parentTrackList.begin(), iterEnd = parentTrackList.end(); iter != iterEnd; ++iter) - { - if (allTrackList.end() != std::find(allTrackList.begin(), allTrackList.end(), *iter)) - continue; + for (pandora::TrackList::const_iterator iter = parentTrackList.begin(), iterEnd = parentTrackList.end(); + iter != iterEnd; ++iter) { + if (allTrackList.end() != std::find(allTrackList.begin(), allTrackList.end(), *iter)) + continue; - // ATTN This track must have a parent not in the all track list; still use it if it is the closest to the ip - streamlog_out(WARNING) << "DDPfoCreator::IsValidParentTrack: mismatch in track relationship information, use information as available " << std::endl; + // ATTN This track must have a parent not in the all track list; still use it if it is the closest to the ip + streamlog_out(WARNING) + << "DDPfoCreator::IsValidParentTrack: mismatch in track relationship information, use information as available " + << std::endl; - if (this->IsClosestTrackToIP(pPandoraTrack, allTrackList)) - return true; + if (this->IsClosestTrackToIP(pPandoraTrack, allTrackList)) + return true; - return false; - } + return false; + } - // Ideal case: All parents are associated to same pfo - return true; + // Ideal case: All parents are associated to same pfo + return true; } //------------------------------------------------------------------------------------------------------------------------------------------ -bool DDPfoCreator::HasValidSiblingTrack(const pandora::Track *const pPandoraTrack, const pandora::TrackList &allTrackList) const -{ - const pandora::TrackList &siblingTrackList(pPandoraTrack->GetSiblingList()); +bool DDPfoCreator::HasValidSiblingTrack(const pandora::Track* const pPandoraTrack, + const pandora::TrackList& allTrackList) const { + const pandora::TrackList& siblingTrackList(pPandoraTrack->GetSiblingList()); - for (pandora::TrackList::const_iterator iter = siblingTrackList.begin(), iterEnd = siblingTrackList.end(); iter != iterEnd; ++iter) - { - if (allTrackList.end() != std::find(allTrackList.begin(), allTrackList.end(), *iter)) - continue; + for (pandora::TrackList::const_iterator iter = siblingTrackList.begin(), iterEnd = siblingTrackList.end(); + iter != iterEnd; ++iter) { + if (allTrackList.end() != std::find(allTrackList.begin(), allTrackList.end(), *iter)) + continue; - // ATTN This track must have a sibling not in the all track list; still use it if it has a second sibling that is in the list - streamlog_out(WARNING) << "DDPfoCreator::HasValidSiblingTrack: mismatch in track relationship information, use information as available " << std::endl; + // ATTN This track must have a sibling not in the all track list; still use it if it has a second sibling that is in the list + streamlog_out(WARNING) << "DDPfoCreator::HasValidSiblingTrack: mismatch in track relationship information, use " + "information as available " + << std::endl; - if (this->AreAnyOtherSiblingsInList(pPandoraTrack, allTrackList)) - return true; + if (this->AreAnyOtherSiblingsInList(pPandoraTrack, allTrackList)) + return true; - return false; - } + return false; + } - // Ideal case: All siblings associated to same pfo - return true; + // Ideal case: All siblings associated to same pfo + return true; } //------------------------------------------------------------------------------------------------------------------------------------------ -bool DDPfoCreator::IsClosestTrackToIP(const pandora::Track *const pPandoraTrack, const pandora::TrackList &allTrackList) const -{ - const pandora::Track *pClosestTrack(NULL); - float closestTrackDisplacement(std::numeric_limits::max()); - - for (pandora::TrackList::const_iterator iter = allTrackList.begin(), iterEnd = allTrackList.end(); iter != iterEnd; ++iter) - { - const pandora::Track *const pTrack(*iter); - const float trialTrackDisplacement(pTrack->GetTrackStateAtStart().GetPosition().GetMagnitude()); - - if (trialTrackDisplacement < closestTrackDisplacement) - { - closestTrackDisplacement = trialTrackDisplacement; - pClosestTrack = pTrack; - } +bool DDPfoCreator::IsClosestTrackToIP(const pandora::Track* const pPandoraTrack, + const pandora::TrackList& allTrackList) const { + const pandora::Track* pClosestTrack(NULL); + float closestTrackDisplacement(std::numeric_limits::max()); + + for (pandora::TrackList::const_iterator iter = allTrackList.begin(), iterEnd = allTrackList.end(); iter != iterEnd; + ++iter) { + const pandora::Track* const pTrack(*iter); + const float trialTrackDisplacement(pTrack->GetTrackStateAtStart().GetPosition().GetMagnitude()); + + if (trialTrackDisplacement < closestTrackDisplacement) { + closestTrackDisplacement = trialTrackDisplacement; + pClosestTrack = pTrack; } + } - return (pPandoraTrack == pClosestTrack); + return (pPandoraTrack == pClosestTrack); } //------------------------------------------------------------------------------------------------------------------------------------------ -bool DDPfoCreator::AreAnyOtherSiblingsInList(const pandora::Track *const pPandoraTrack, const pandora::TrackList &allTrackList) const -{ - const pandora::TrackList &siblingTrackList(pPandoraTrack->GetSiblingList()); +bool DDPfoCreator::AreAnyOtherSiblingsInList(const pandora::Track* const pPandoraTrack, + const pandora::TrackList& allTrackList) const { + const pandora::TrackList& siblingTrackList(pPandoraTrack->GetSiblingList()); - for (pandora::TrackList::const_iterator iter = siblingTrackList.begin(), iterEnd = siblingTrackList.end(); iter != iterEnd; ++iter) - { - if (allTrackList.end() != std::find(allTrackList.begin(), allTrackList.end(), *iter)) - return true; - } + for (pandora::TrackList::const_iterator iter = siblingTrackList.begin(), iterEnd = siblingTrackList.end(); + iter != iterEnd; ++iter) { + if (allTrackList.end() != std::find(allTrackList.begin(), allTrackList.end(), *iter)) + return true; + } - return false; + return false; } //------------------------------------------------------------------------------------------------------------------------------------------ -void DDPfoCreator::SetRecoParticleReferencePoint(const pandora::CartesianVector &referencePoint, edm4hep::ReconstructedParticle *const pReconstructedParticle) const -{ - const float referencePointArray[3] = {referencePoint.GetX(), referencePoint.GetY(), referencePoint.GetZ()}; - pReconstructedParticle->setReferencePoint(referencePointArray); +void DDPfoCreator::SetRecoParticleReferencePoint(const pandora::CartesianVector& referencePoint, + edm4hep::ReconstructedParticle* const pReconstructedParticle) const { + const float referencePointArray[3] = {referencePoint.GetX(), referencePoint.GetY(), referencePoint.GetZ()}; + pReconstructedParticle->setReferencePoint(referencePointArray); } //------------------------------------------------------------------------------------------------------------------------------------------ -void DDPfoCreator::AddTracksToRecoParticle(const pandora::ParticleFlowObject *const pPandoraPfo, edm4hep::ReconstructedParticle *const pReconstructedParticle) const -{ - const pandora::TrackList &trackList(pPandoraPfo->GetTrackList()); - - for (pandora::TrackList::const_iterator tIter = trackList.begin(), tIterEnd = trackList.end(); tIter != tIterEnd; ++tIter) - { - const pandora::Track *const pTrack(*tIter); - const edm4hep::Track *const pLcioTrack0 = (edm4hep::Track*)(pTrack->GetParentAddress()); - const edm4hep::Track pLcioTrack = *pLcioTrack0; - pReconstructedParticle->addToTracks(pLcioTrack); - } +void DDPfoCreator::AddTracksToRecoParticle(const pandora::ParticleFlowObject* const pPandoraPfo, + edm4hep::ReconstructedParticle* const pReconstructedParticle) const { + const pandora::TrackList& trackList(pPandoraPfo->GetTrackList()); + + for (pandora::TrackList::const_iterator tIter = trackList.begin(), tIterEnd = trackList.end(); tIter != tIterEnd; + ++tIter) { + const pandora::Track* const pTrack(*tIter); + const edm4hep::Track* const pLcioTrack0 = (edm4hep::Track*)(pTrack->GetParentAddress()); + const edm4hep::Track pLcioTrack = *pLcioTrack0; + pReconstructedParticle->addToTracks(pLcioTrack); + } } //------------------------------------------------------------------------------------------------------------------------------------------ -void DDPfoCreator::SetRecoParticlePropertiesFromPFO(const pandora::ParticleFlowObject *const pPandoraPfo, edm4hep::ReconstructedParticle *const pReconstructedParticle) const -{ - const float momentum[3] = {pPandoraPfo->GetMomentum().GetX(), pPandoraPfo->GetMomentum().GetY(), pPandoraPfo->GetMomentum().GetZ()}; - pReconstructedParticle->setMomentum(momentum); - pReconstructedParticle->setEnergy(pPandoraPfo->GetEnergy()); - pReconstructedParticle->setMass(pPandoraPfo->GetMass()); - pReconstructedParticle->setCharge(pPandoraPfo->GetCharge()); - pReconstructedParticle->setType(pPandoraPfo->GetParticleId()); +void DDPfoCreator::SetRecoParticlePropertiesFromPFO( + const pandora::ParticleFlowObject* const pPandoraPfo, + edm4hep::ReconstructedParticle* const pReconstructedParticle) const { + const float momentum[3] = {pPandoraPfo->GetMomentum().GetX(), pPandoraPfo->GetMomentum().GetY(), + pPandoraPfo->GetMomentum().GetZ()}; + pReconstructedParticle->setMomentum(momentum); + pReconstructedParticle->setEnergy(pPandoraPfo->GetEnergy()); + pReconstructedParticle->setMass(pPandoraPfo->GetMass()); + pReconstructedParticle->setCharge(pPandoraPfo->GetCharge()); + pReconstructedParticle->setType(pPandoraPfo->GetParticleId()); } //------------------------------------------------------------------------------------------------------------------------------------------ -DDPfoCreator::Settings::Settings(): - m_emStochasticTerm(0.17f), - m_hadStochasticTerm(0.6f), - m_emConstantTerm(0.01f), - m_hadConstantTerm(0.03f) -{ -} +DDPfoCreator::Settings::Settings() + : m_emStochasticTerm(0.17f), m_hadStochasticTerm(0.6f), m_emConstantTerm(0.01f), m_hadConstantTerm(0.03f) {} diff --git a/k4GaudiPandora/src/DDScintillatorPpdDigi.cc b/k4GaudiPandora/src/DDScintillatorPpdDigi.cc index 63dd7a8..f2b778b 100644 --- a/k4GaudiPandora/src/DDScintillatorPpdDigi.cc +++ b/k4GaudiPandora/src/DDScintillatorPpdDigi.cc @@ -1,16 +1,34 @@ +/* + * Copyright (c) 2020-2024 Key4hep-Project. + * + * This file is part of Key4hep. + * See https://key4hep.github.io/key4hep-doc/ for further info. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #include "DDScintillatorPpdDigi.h" #include -#include "CLHEP/Random/RandPoisson.h" -#include "CLHEP/Random/RandGauss.h" -#include "CLHEP/Random/RandBinomial.h" #include +#include "CLHEP/Random/RandBinomial.h" +#include "CLHEP/Random/RandGauss.h" +#include "CLHEP/Random/RandPoisson.h" using std::cout; using std::endl; // this applies some extra digitisation to scintillator+PPD hits (PPD=SiPM, MPPC) // - poisson fluctuates the number of photo-electrons according to #PEs/MIP // - applies PPD saturation according to #pixels -// Daniel Jeans, Jan/Feb 2014. +// Daniel Jeans, Jan/Feb 2014. // (split off from ILDCaloDigi Aug'14.) DDScintillatorPpdDigi::DDScintillatorPpdDigi() {} @@ -18,30 +36,32 @@ DDScintillatorPpdDigi::DDScintillatorPpdDigi() {} void DDScintillatorPpdDigi::printParameters() { cout << "--------------------------------" << endl; cout << "DDScintillatorPpdDigi parameters" << endl; - cout << " pe_per_mip = " << _pe_per_mip << endl; - cout << " calib_mip = " << _calib_mip << endl; - cout << " npix = " << _npix << endl; - cout << " misCalibNpix = " << _misCalibNpix << endl; - cout << " pixSpread = " << _pixSpread << endl; - cout << " elecDynRange = " << _elecMaxDynRange_MIP << endl; - cout << " elecNoise = " << _elecNoise << endl; + cout << " pe_per_mip = " << _pe_per_mip << endl; + cout << " calib_mip = " << _calib_mip << endl; + cout << " npix = " << _npix << endl; + cout << " misCalibNpix = " << _misCalibNpix << endl; + cout << " pixSpread = " << _pixSpread << endl; + cout << " elecDynRange = " << _elecMaxDynRange_MIP << endl; + cout << " elecNoise = " << _elecNoise << endl; cout << "--------------------------------" << endl; return; } float DDScintillatorPpdDigi::getDigitisedEnergy(float energy) { - float correctedEnergy(energy); - if (_pe_per_mip<=0 || _calib_mip<=0 || _npix<=0) { - cout << "ERROR, crazy parameters for DDScintillatorPpdDigi: PE/MIP=" << _pe_per_mip << ", MIP calib=" << _calib_mip << ", #pixels=" << _npix << endl; - cout << "you must specify at least the #PE/MIP, MIP calibration, and #pixels for realistic scintillator digitisation!!" << endl; + if (_pe_per_mip <= 0 || _calib_mip <= 0 || _npix <= 0) { + cout << "ERROR, crazy parameters for DDScintillatorPpdDigi: PE/MIP=" << _pe_per_mip << ", MIP calib=" << _calib_mip + << ", #pixels=" << _npix << endl; + cout << "you must specify at least the #PE/MIP, MIP calibration, and #pixels for realistic scintillator " + "digitisation!!" + << endl; cout << "refusing to proceed!" << endl; assert(0); } // 1. convert energy to expected # photoelectrons (via MIPs) - float npe = _pe_per_mip*energy/_calib_mip; + float npe = _pe_per_mip * energy / _calib_mip; //oh: commented out Daniel's digitisation model. (npe -> poisson -> saturation -> stoykov smearing). // Stoykov smearing used with Gaussian shape for lack of better model. @@ -63,42 +83,40 @@ float DDScintillatorPpdDigi::getDigitisedEnergy(float energy) { npe += dpix; } */ - + //AHCAL TB style digitisation: npe -> saturation -> binomial smearing //shown to be mathematically equivalent to Daniel's model above, but slightly faster and automatically generates correct shape instead of Gaussian approximation - - if (_npix>0){ + + if (_npix > 0) { // apply average sipm saturation behaviour - npe = _npix*(1.0 - exp( -npe/_npix ) ); - + npe = _npix * (1.0 - exp(-npe / _npix)); + //apply binomial smearing - float p = npe/_npix; // fraction of hit pixels on SiPM - npe = CLHEP::RandBinomial::shoot(_npix, p); //npe now quantised to integer pixels + float p = npe / _npix; // fraction of hit pixels on SiPM + npe = CLHEP::RandBinomial::shoot(_npix, p); //npe now quantised to integer pixels } - - - - if (_pixSpread>0) { + + if (_pixSpread > 0) { // variations in pixel capacitance - npe *= CLHEP::RandGauss::shoot(1, _pixSpread/sqrt(npe) ); + npe *= CLHEP::RandGauss::shoot(1, _pixSpread / sqrt(npe)); } - if ( _elecMaxDynRange_MIP > 0 ) { + if (_elecMaxDynRange_MIP > 0) { // limited dynamic range of readout electronics // Daniel moved this here, before the unfolding of saturation (September 2015) - npe = std::min ( npe, _elecMaxDynRange_MIP*_pe_per_mip ); + npe = std::min(npe, _elecMaxDynRange_MIP * _pe_per_mip); } - if (_elecNoise>0) { + if (_elecNoise > 0) { // add electronics noise - npe += CLHEP::RandGauss::shoot(0, _elecNoise*_pe_per_mip); + npe += CLHEP::RandGauss::shoot(0, _elecNoise * _pe_per_mip); } - if (_npix>0) { + if (_npix > 0) { // 4. unfold the saturation // - miscalibration of npix - float smearedNpix = _misCalibNpix>0 ? _npix*CLHEP::RandGauss::shoot( 1.0, _misCalibNpix ) : _npix; - + float smearedNpix = _misCalibNpix > 0 ? _npix * CLHEP::RandGauss::shoot(1.0, _misCalibNpix) : _npix; + //oh: commented out daniel's implmentation of dealing with hits>smearedNpix. using linearisation of saturation-reconstruction for high amplitude hits instead. /* // - this is to deal with case when #pe is larger than #pixels (would mean taking log of negative number) @@ -107,19 +125,19 @@ float DDScintillatorPpdDigi::getDigitisedEnergy(float energy) { // - unfold saturation npe = -smearedNpix * std::log ( 1. - ( npe / smearedNpix ) ); */ - - const float r = 0.95; //this is the fraction of SiPM pixels fired above which a linear continuation of the saturation-reconstruction function is used. 0.95 of nPixel corresponds to a energy correction of factor ~3. - if (npe < r*smearedNpix){ //current hit below linearisation threshold, reconstruct energy normally: - npe = -smearedNpix * std::log ( 1. - ( npe / smearedNpix ) ); - } else { //current hit is aove linearisation threshold, reconstruct using linear continuation function: - npe = 1/(1-r)*(npe-r*smearedNpix)-smearedNpix*std::log(1-r); + const float r = + 0.95; //this is the fraction of SiPM pixels fired above which a linear continuation of the saturation-reconstruction function is used. 0.95 of nPixel corresponds to a energy correction of factor ~3. + + if (npe < r * smearedNpix) { //current hit below linearisation threshold, reconstruct energy normally: + npe = -smearedNpix * std::log(1. - (npe / smearedNpix)); + } else { //current hit is aove linearisation threshold, reconstruct using linear continuation function: + npe = 1 / (1 - r) * (npe - r * smearedNpix) - smearedNpix * std::log(1 - r); } } // convert back to energy - correctedEnergy = _calib_mip*npe/_pe_per_mip; + correctedEnergy = _calib_mip * npe / _pe_per_mip; return correctedEnergy; } - diff --git a/k4GaudiPandora/src/DDSimpleMuonDigiOld.cc b/k4GaudiPandora/src/DDSimpleMuonDigiOld.cc index c8299a8..769558a 100644 --- a/k4GaudiPandora/src/DDSimpleMuonDigiOld.cc +++ b/k4GaudiPandora/src/DDSimpleMuonDigiOld.cc @@ -1,4 +1,21 @@ -#include "DDSimpleMuonDigi.h" +/* + * Copyright (c) 2020-2024 Key4hep-Project. + * + * This file is part of Key4hep. + * See https://key4hep.github.io/key4hep-doc/ for further info. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #include #include #include @@ -8,6 +25,7 @@ #include #include #include +#include "DDSimpleMuonDigi.h" // #include // #include diff --git a/k4GaudiPandora/src/DDTrackCreatorBase.cc b/k4GaudiPandora/src/DDTrackCreatorBase.cc index bb06be8..1c03091 100644 --- a/k4GaudiPandora/src/DDTrackCreatorBase.cc +++ b/k4GaudiPandora/src/DDTrackCreatorBase.cc @@ -1,8 +1,27 @@ +/* + * Copyright (c) 2020-2024 Key4hep-Project. + * + * This file is part of Key4hep. + * See https://key4hep.github.io/key4hep-doc/ for further info. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + /** * @file DDMarlinPandora/src/DDTrackCreatorBase.cc - * + * * @brief Implementation of the track creator class. - * + * * $Log: $ */ @@ -15,15 +34,15 @@ #include "UTIL/ILDConf.h" #include "UTIL/Operators.h" +#include #include "DDTrackCreatorBase.h" #include "Pandora/PdgTable.h" -#include #include #include -#include "DD4hep/Detector.h" #include "DD4hep/DD4hepUnits.h" +#include "DD4hep/Detector.h" #include "DDRec/DetectorData.h" #include @@ -33,455 +52,420 @@ //forward declaration std::vector getTrackingRegionExtent(); -DDTrackCreatorBase::DDTrackCreatorBase(const Settings &settings, const pandora::Pandora *const pPandora) : - m_settings(settings), - m_pandora(*pPandora), - m_trackVector(0), - m_v0TrackList( TrackList() ), - m_parentTrackList( TrackList() ), - m_daughterTrackList( TrackList() ), - m_trackToPidMap( TrackToPidMap() ), - m_minimalTrackStateRadiusSquared( 0.f ) -{ - - const float ecalInnerR = settings.m_eCalBarrelInnerR; - const float tsTolerance = settings.m_trackStateTolerance; - m_minimalTrackStateRadiusSquared = (ecalInnerR-tsTolerance)*(ecalInnerR-tsTolerance); - //wrap in shared_ptr with a dummy destructor - m_trackingSystem = - std::shared_ptr( MarlinTrk::Factory::createMarlinTrkSystem(settings.m_trackingSystemName, - nullptr, ""), - [](MarlinTrk::IMarlinTrkSystem*){} ); - m_trackingSystem->init(); - m_encoder = std::make_shared( lcio::LCTrackerCellID::encoding_string() ); - m_lcTrackFactory = std::make_shared(); +DDTrackCreatorBase::DDTrackCreatorBase(const Settings& settings, const pandora::Pandora* const pPandora) + : m_settings(settings), + m_pandora(*pPandora), + m_trackVector(0), + m_v0TrackList(TrackList()), + m_parentTrackList(TrackList()), + m_daughterTrackList(TrackList()), + m_trackToPidMap(TrackToPidMap()), + m_minimalTrackStateRadiusSquared(0.f) { + const float ecalInnerR = settings.m_eCalBarrelInnerR; + const float tsTolerance = settings.m_trackStateTolerance; + m_minimalTrackStateRadiusSquared = (ecalInnerR - tsTolerance) * (ecalInnerR - tsTolerance); + //wrap in shared_ptr with a dummy destructor + m_trackingSystem = std::shared_ptr( + MarlinTrk::Factory::createMarlinTrkSystem(settings.m_trackingSystemName, nullptr, ""), + [](MarlinTrk::IMarlinTrkSystem*) {}); + m_trackingSystem->init(); + m_encoder = std::make_shared(lcio::LCTrackerCellID::encoding_string()); + m_lcTrackFactory = std::make_shared(); } //------------------------------------------------------------------------------------------------------------------------------------------ -DDTrackCreatorBase::~DDTrackCreatorBase() -{ -} +DDTrackCreatorBase::~DDTrackCreatorBase() {} //------------------------------------------------------------------------------------------------------------------------------------------ -pandora::StatusCode DDTrackCreatorBase::CreateTrackAssociations(const EVENT::LCEvent *const pLCEvent) -{ - PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, this->ExtractKinks(pLCEvent)); - PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, this->ExtractProngsAndSplits(pLCEvent)); - PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, this->ExtractV0s(pLCEvent)); +pandora::StatusCode DDTrackCreatorBase::CreateTrackAssociations(const EVENT::LCEvent* const pLCEvent) { + PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, this->ExtractKinks(pLCEvent)); + PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, this->ExtractProngsAndSplits(pLCEvent)); + PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, this->ExtractV0s(pLCEvent)); - return pandora::STATUS_CODE_SUCCESS; + return pandora::STATUS_CODE_SUCCESS; } //------------------------------------------------------------------------------------------------------------------------------------------ -pandora::StatusCode DDTrackCreatorBase::ExtractKinks(const EVENT::LCEvent *const pLCEvent) -{ - for (StringVector::const_iterator iter = m_settings.m_kinkVertexCollections.begin(), iterEnd = m_settings.m_kinkVertexCollections.end(); - iter != iterEnd; ++iter) - { - try - { - const EVENT::LCCollection *pKinkCollection = pLCEvent->getCollection(*iter); - - for (int i = 0, iMax = pKinkCollection->getNumberOfElements(); i < iMax; ++i) - { - try - { - EVENT::Vertex *pVertex = dynamic_cast(pKinkCollection->getElementAt(i)); - - if (NULL == pVertex) - throw EVENT::Exception("Collection type mismatch"); - - EVENT::ReconstructedParticle *pReconstructedParticle = pVertex->getAssociatedParticle(); - const EVENT::TrackVec &trackVec(pReconstructedParticle->getTracks()); - - if (this->IsConflictingRelationship(trackVec)) - continue; - - const int vertexPdgCode(pReconstructedParticle->getType()); - - // Extract the kink vertex information - for (unsigned int iTrack = 0, nTracks = trackVec.size(); iTrack < nTracks; ++iTrack) - { - EVENT::Track *pTrack = trackVec[iTrack]; - (0 == iTrack) ? m_parentTrackList.insert(pTrack) : m_daughterTrackList.insert(pTrack); - streamlog_out(DEBUG) << "KinkTrack " << iTrack << ", nHits " << pTrack->getTrackerHits().size() << std::endl; - - int trackPdgCode = pandora::UNKNOWN_PARTICLE_TYPE; - - if (0 == iTrack) - { - trackPdgCode = vertexPdgCode; - } - else - { - switch (vertexPdgCode) - { - case pandora::PI_PLUS : - case pandora::K_PLUS : - trackPdgCode = pandora::MU_PLUS; - break; - case pandora::PI_MINUS : - case pandora::K_MINUS : - trackPdgCode = pandora::MU_MINUS; - break; - case pandora::HYPERON_MINUS_BAR : - case pandora::SIGMA_PLUS : - trackPdgCode = pandora::PI_PLUS; - break; - case pandora::SIGMA_MINUS : - case pandora::HYPERON_MINUS : - trackPdgCode = pandora::PI_PLUS; - break; - default : - (pTrack->getOmega() > 0) ? trackPdgCode = pandora::PI_PLUS : trackPdgCode = pandora::PI_MINUS; - break; - } - } - - m_trackToPidMap.insert(TrackToPidMap::value_type(pTrack, trackPdgCode)); - - if (0 == m_settings.m_shouldFormTrackRelationships) - continue; - - // Make track parent-daughter relationships - if (0 == iTrack) - { - for (unsigned int jTrack = iTrack + 1; jTrack < nTracks; ++jTrack) - { - PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::SetTrackParentDaughterRelationship(m_pandora, - pTrack, trackVec[jTrack])); - } - } - - // Make track sibling relationships - else - { - for (unsigned int jTrack = iTrack + 1; jTrack < nTracks; ++jTrack) - { - PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::SetTrackSiblingRelationship(m_pandora, - pTrack, trackVec[jTrack])); - } - } - } - } - catch (EVENT::Exception &exception) - { - streamlog_out(WARNING) << "Failed to extract kink vertex: " << exception.what() << std::endl; - } +pandora::StatusCode DDTrackCreatorBase::ExtractKinks(const EVENT::LCEvent* const pLCEvent) { + for (StringVector::const_iterator iter = m_settings.m_kinkVertexCollections.begin(), + iterEnd = m_settings.m_kinkVertexCollections.end(); + iter != iterEnd; ++iter) { + try { + const EVENT::LCCollection* pKinkCollection = pLCEvent->getCollection(*iter); + + for (int i = 0, iMax = pKinkCollection->getNumberOfElements(); i < iMax; ++i) { + try { + EVENT::Vertex* pVertex = dynamic_cast(pKinkCollection->getElementAt(i)); + + if (NULL == pVertex) + throw EVENT::Exception("Collection type mismatch"); + + EVENT::ReconstructedParticle* pReconstructedParticle = pVertex->getAssociatedParticle(); + const EVENT::TrackVec& trackVec(pReconstructedParticle->getTracks()); + + if (this->IsConflictingRelationship(trackVec)) + continue; + + const int vertexPdgCode(pReconstructedParticle->getType()); + + // Extract the kink vertex information + for (unsigned int iTrack = 0, nTracks = trackVec.size(); iTrack < nTracks; ++iTrack) { + EVENT::Track* pTrack = trackVec[iTrack]; + (0 == iTrack) ? m_parentTrackList.insert(pTrack) : m_daughterTrackList.insert(pTrack); + streamlog_out(DEBUG) << "KinkTrack " << iTrack << ", nHits " << pTrack->getTrackerHits().size() + << std::endl; + + int trackPdgCode = pandora::UNKNOWN_PARTICLE_TYPE; + + if (0 == iTrack) { + trackPdgCode = vertexPdgCode; + } else { + switch (vertexPdgCode) { + case pandora::PI_PLUS: + case pandora::K_PLUS: + trackPdgCode = pandora::MU_PLUS; + break; + case pandora::PI_MINUS: + case pandora::K_MINUS: + trackPdgCode = pandora::MU_MINUS; + break; + case pandora::HYPERON_MINUS_BAR: + case pandora::SIGMA_PLUS: + trackPdgCode = pandora::PI_PLUS; + break; + case pandora::SIGMA_MINUS: + case pandora::HYPERON_MINUS: + trackPdgCode = pandora::PI_PLUS; + break; + default: + (pTrack->getOmega() > 0) ? trackPdgCode = pandora::PI_PLUS : trackPdgCode = pandora::PI_MINUS; + break; + } } + + m_trackToPidMap.insert(TrackToPidMap::value_type(pTrack, trackPdgCode)); + + if (0 == m_settings.m_shouldFormTrackRelationships) + continue; + + // Make track parent-daughter relationships + if (0 == iTrack) { + for (unsigned int jTrack = iTrack + 1; jTrack < nTracks; ++jTrack) { + PANDORA_RETURN_RESULT_IF( + pandora::STATUS_CODE_SUCCESS, !=, + PandoraApi::SetTrackParentDaughterRelationship(m_pandora, pTrack, trackVec[jTrack])); + } + } + + // Make track sibling relationships + else { + for (unsigned int jTrack = iTrack + 1; jTrack < nTracks; ++jTrack) { + PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, + PandoraApi::SetTrackSiblingRelationship(m_pandora, pTrack, trackVec[jTrack])); + } + } + } + } catch (EVENT::Exception& exception) { + streamlog_out(WARNING) << "Failed to extract kink vertex: " << exception.what() << std::endl; } - catch (EVENT::Exception &exception) - { - streamlog_out(DEBUG5) << "Failed to extract kink vertex collection: " << *iter << ", " << exception.what() << std::endl; - } + } + } catch (EVENT::Exception& exception) { + streamlog_out(DEBUG5) << "Failed to extract kink vertex collection: " << *iter << ", " << exception.what() + << std::endl; } + } - return pandora::STATUS_CODE_SUCCESS; + return pandora::STATUS_CODE_SUCCESS; } //------------------------------------------------------------------------------------------------------------------------------------------ -pandora::StatusCode DDTrackCreatorBase::ExtractProngsAndSplits(const EVENT::LCEvent *const pLCEvent) -{ - for (StringVector::const_iterator iter = m_settings.m_prongSplitVertexCollections.begin(), iterEnd = m_settings.m_prongSplitVertexCollections.end(); - iter != iterEnd; ++iter) - { - try - { - const EVENT::LCCollection *pProngOrSplitCollection = pLCEvent->getCollection(*iter); - - for (int i = 0, iMax = pProngOrSplitCollection->getNumberOfElements(); i < iMax; ++i) - { - try - { - EVENT::Vertex *pVertex = dynamic_cast(pProngOrSplitCollection->getElementAt(i)); - - if (NULL == pVertex) - throw EVENT::Exception("Collection type mismatch"); - - EVENT::ReconstructedParticle *pReconstructedParticle = pVertex->getAssociatedParticle(); - const EVENT::TrackVec &trackVec(pReconstructedParticle->getTracks()); - - if (this->IsConflictingRelationship(trackVec)) - continue; - - // Extract the prong/split vertex information - for (unsigned int iTrack = 0, nTracks = trackVec.size(); iTrack < nTracks; ++iTrack) - { - EVENT::Track *pTrack = trackVec[iTrack]; - (0 == iTrack) ? m_parentTrackList.insert(pTrack) : m_daughterTrackList.insert(pTrack); - streamlog_out(DEBUG) << "Prong or Split Track " << iTrack << ", nHits " << pTrack->getTrackerHits().size() << std::endl; - - if (0 == m_settings.m_shouldFormTrackRelationships) - continue; - - // Make track parent-daughter relationships - if (0 == iTrack) - { - for (unsigned int jTrack = iTrack + 1; jTrack < nTracks; ++jTrack) - { - PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::SetTrackParentDaughterRelationship(m_pandora, - pTrack, trackVec[jTrack])); - } - } - - // Make track sibling relationships - else - { - for (unsigned int jTrack = iTrack + 1; jTrack < nTracks; ++jTrack) - { - PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::SetTrackSiblingRelationship(m_pandora, - pTrack, trackVec[jTrack])); - } - } - } - } - catch (EVENT::Exception &exception) - { - streamlog_out(WARNING) << "Failed to extract prong/split vertex: " << exception.what() << std::endl; - } +pandora::StatusCode DDTrackCreatorBase::ExtractProngsAndSplits(const EVENT::LCEvent* const pLCEvent) { + for (StringVector::const_iterator iter = m_settings.m_prongSplitVertexCollections.begin(), + iterEnd = m_settings.m_prongSplitVertexCollections.end(); + iter != iterEnd; ++iter) { + try { + const EVENT::LCCollection* pProngOrSplitCollection = pLCEvent->getCollection(*iter); + + for (int i = 0, iMax = pProngOrSplitCollection->getNumberOfElements(); i < iMax; ++i) { + try { + EVENT::Vertex* pVertex = dynamic_cast(pProngOrSplitCollection->getElementAt(i)); + + if (NULL == pVertex) + throw EVENT::Exception("Collection type mismatch"); + + EVENT::ReconstructedParticle* pReconstructedParticle = pVertex->getAssociatedParticle(); + const EVENT::TrackVec& trackVec(pReconstructedParticle->getTracks()); + + if (this->IsConflictingRelationship(trackVec)) + continue; + + // Extract the prong/split vertex information + for (unsigned int iTrack = 0, nTracks = trackVec.size(); iTrack < nTracks; ++iTrack) { + EVENT::Track* pTrack = trackVec[iTrack]; + (0 == iTrack) ? m_parentTrackList.insert(pTrack) : m_daughterTrackList.insert(pTrack); + streamlog_out(DEBUG) << "Prong or Split Track " << iTrack << ", nHits " << pTrack->getTrackerHits().size() + << std::endl; + + if (0 == m_settings.m_shouldFormTrackRelationships) + continue; + + // Make track parent-daughter relationships + if (0 == iTrack) { + for (unsigned int jTrack = iTrack + 1; jTrack < nTracks; ++jTrack) { + PANDORA_RETURN_RESULT_IF( + pandora::STATUS_CODE_SUCCESS, !=, + PandoraApi::SetTrackParentDaughterRelationship(m_pandora, pTrack, trackVec[jTrack])); + } } + + // Make track sibling relationships + else { + for (unsigned int jTrack = iTrack + 1; jTrack < nTracks; ++jTrack) { + PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, + PandoraApi::SetTrackSiblingRelationship(m_pandora, pTrack, trackVec[jTrack])); + } + } + } + } catch (EVENT::Exception& exception) { + streamlog_out(WARNING) << "Failed to extract prong/split vertex: " << exception.what() << std::endl; } - catch (EVENT::Exception &exception) - { - streamlog_out(DEBUG5) << "Failed to extract prong/split vertex collection: " << *iter << ", " << exception.what() << std::endl; - } + } + } catch (EVENT::Exception& exception) { + streamlog_out(DEBUG5) << "Failed to extract prong/split vertex collection: " << *iter << ", " << exception.what() + << std::endl; } + } - return pandora::STATUS_CODE_SUCCESS; + return pandora::STATUS_CODE_SUCCESS; } //------------------------------------------------------------------------------------------------------------------------------------------ -pandora::StatusCode DDTrackCreatorBase::ExtractV0s(const EVENT::LCEvent *const pLCEvent) -{ - for (StringVector::const_iterator iter = m_settings.m_v0VertexCollections.begin(), iterEnd = m_settings.m_v0VertexCollections.end(); - iter != iterEnd; ++iter) - { - try - { - const EVENT::LCCollection *pV0Collection = pLCEvent->getCollection(*iter); - - for (int i = 0, iMax = pV0Collection->getNumberOfElements(); i < iMax; ++i) - { - try - { - EVENT::Vertex *pVertex = dynamic_cast(pV0Collection->getElementAt(i)); - - if (NULL == pVertex) - throw EVENT::Exception("Collection type mismatch"); - - EVENT::ReconstructedParticle *pReconstructedParticle = pVertex->getAssociatedParticle(); - const EVENT::TrackVec &trackVec(pReconstructedParticle->getTracks()); - - if (this->IsConflictingRelationship(trackVec)) - continue; - - // Extract the v0 vertex information - const int vertexPdgCode(pReconstructedParticle->getType()); - - for (unsigned int iTrack = 0, nTracks = trackVec.size(); iTrack < nTracks; ++iTrack) - { - EVENT::Track *pTrack = trackVec[iTrack]; - m_v0TrackList.insert(pTrack); - streamlog_out(DEBUG) << "V0Track " << iTrack << ", nHits " << pTrack->getTrackerHits().size() << std::endl; - - int trackPdgCode = pandora::UNKNOWN_PARTICLE_TYPE; - - switch (vertexPdgCode) - { - case pandora::PHOTON : - (pTrack->getOmega() > 0) ? trackPdgCode = pandora::E_PLUS : trackPdgCode = pandora::E_MINUS; - break; - case pandora::LAMBDA : - (pTrack->getOmega() > 0) ? trackPdgCode = pandora::PROTON : trackPdgCode = pandora::PI_MINUS; - break; - case pandora::LAMBDA_BAR : - (pTrack->getOmega() > 0) ? trackPdgCode = pandora::PI_PLUS : trackPdgCode = pandora::PROTON_BAR; - break; - case pandora::K_SHORT : - (pTrack->getOmega() > 0) ? trackPdgCode = pandora::PI_PLUS : trackPdgCode = pandora::PI_MINUS; - break; - default : - (pTrack->getOmega() > 0) ? trackPdgCode = pandora::PI_PLUS : trackPdgCode = pandora::PI_MINUS; - break; - } - - m_trackToPidMap.insert(TrackToPidMap::value_type(pTrack, trackPdgCode)); - - if (0 == m_settings.m_shouldFormTrackRelationships) - continue; - - // Make track sibling relationships - for (unsigned int jTrack = iTrack + 1; jTrack < nTracks; ++jTrack) - { - PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::SetTrackSiblingRelationship(m_pandora, - pTrack, trackVec[jTrack])); - } - } - } - catch (EVENT::Exception &exception) - { - streamlog_out(WARNING) << "Failed to extract v0 vertex: " << exception.what() << std::endl; - } +pandora::StatusCode DDTrackCreatorBase::ExtractV0s(const EVENT::LCEvent* const pLCEvent) { + for (StringVector::const_iterator iter = m_settings.m_v0VertexCollections.begin(), + iterEnd = m_settings.m_v0VertexCollections.end(); + iter != iterEnd; ++iter) { + try { + const EVENT::LCCollection* pV0Collection = pLCEvent->getCollection(*iter); + + for (int i = 0, iMax = pV0Collection->getNumberOfElements(); i < iMax; ++i) { + try { + EVENT::Vertex* pVertex = dynamic_cast(pV0Collection->getElementAt(i)); + + if (NULL == pVertex) + throw EVENT::Exception("Collection type mismatch"); + + EVENT::ReconstructedParticle* pReconstructedParticle = pVertex->getAssociatedParticle(); + const EVENT::TrackVec& trackVec(pReconstructedParticle->getTracks()); + + if (this->IsConflictingRelationship(trackVec)) + continue; + + // Extract the v0 vertex information + const int vertexPdgCode(pReconstructedParticle->getType()); + + for (unsigned int iTrack = 0, nTracks = trackVec.size(); iTrack < nTracks; ++iTrack) { + EVENT::Track* pTrack = trackVec[iTrack]; + m_v0TrackList.insert(pTrack); + streamlog_out(DEBUG) << "V0Track " << iTrack << ", nHits " << pTrack->getTrackerHits().size() << std::endl; + + int trackPdgCode = pandora::UNKNOWN_PARTICLE_TYPE; + + switch (vertexPdgCode) { + case pandora::PHOTON: + (pTrack->getOmega() > 0) ? trackPdgCode = pandora::E_PLUS : trackPdgCode = pandora::E_MINUS; + break; + case pandora::LAMBDA: + (pTrack->getOmega() > 0) ? trackPdgCode = pandora::PROTON : trackPdgCode = pandora::PI_MINUS; + break; + case pandora::LAMBDA_BAR: + (pTrack->getOmega() > 0) ? trackPdgCode = pandora::PI_PLUS : trackPdgCode = pandora::PROTON_BAR; + break; + case pandora::K_SHORT: + (pTrack->getOmega() > 0) ? trackPdgCode = pandora::PI_PLUS : trackPdgCode = pandora::PI_MINUS; + break; + default: + (pTrack->getOmega() > 0) ? trackPdgCode = pandora::PI_PLUS : trackPdgCode = pandora::PI_MINUS; + break; } + + m_trackToPidMap.insert(TrackToPidMap::value_type(pTrack, trackPdgCode)); + + if (0 == m_settings.m_shouldFormTrackRelationships) + continue; + + // Make track sibling relationships + for (unsigned int jTrack = iTrack + 1; jTrack < nTracks; ++jTrack) { + PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, + PandoraApi::SetTrackSiblingRelationship(m_pandora, pTrack, trackVec[jTrack])); + } + } + } catch (EVENT::Exception& exception) { + streamlog_out(WARNING) << "Failed to extract v0 vertex: " << exception.what() << std::endl; } - catch (EVENT::Exception &exception) - { - streamlog_out(DEBUG5) << "Failed to extract v0 vertex collection: " << *iter << ", " << exception.what() << std::endl; - } + } + } catch (EVENT::Exception& exception) { + streamlog_out(DEBUG5) << "Failed to extract v0 vertex collection: " << *iter << ", " << exception.what() + << std::endl; } + } - return pandora::STATUS_CODE_SUCCESS; + return pandora::STATUS_CODE_SUCCESS; } //------------------------------------------------------------------------------------------------------------------------------------------ -bool DDTrackCreatorBase::IsConflictingRelationship(const EVENT::TrackVec &trackVec) const -{ - for (unsigned int iTrack = 0, nTracks = trackVec.size(); iTrack < nTracks; ++iTrack) - { - EVENT::Track *pTrack = trackVec[iTrack]; +bool DDTrackCreatorBase::IsConflictingRelationship(const EVENT::TrackVec& trackVec) const { + for (unsigned int iTrack = 0, nTracks = trackVec.size(); iTrack < nTracks; ++iTrack) { + EVENT::Track* pTrack = trackVec[iTrack]; - if (this->IsDaughter(pTrack) || this->IsParent(pTrack) || this->IsV0(pTrack)) - return true; - } + if (this->IsDaughter(pTrack) || this->IsParent(pTrack) || this->IsV0(pTrack)) + return true; + } - return false; + return false; } - - //------------------------------------------------------------------------------------------------------------------------------------------ -void DDTrackCreatorBase::GetTrackStates(const EVENT::Track *const pTrack, PandoraApi::Track::Parameters &trackParameters) const -{ - const TrackState *pTrackState = pTrack->getTrackState(TrackState::AtIP); +void DDTrackCreatorBase::GetTrackStates(const EVENT::Track* const pTrack, + PandoraApi::Track::Parameters& trackParameters) const { + const TrackState* pTrackState = pTrack->getTrackState(TrackState::AtIP); - if (!pTrackState) - throw pandora::StatusCodeException(pandora::STATUS_CODE_NOT_INITIALIZED); + if (!pTrackState) + throw pandora::StatusCodeException(pandora::STATUS_CODE_NOT_INITIALIZED); - const double pt(m_settings.m_bField * 2.99792e-4 / std::fabs(pTrackState->getOmega())); - trackParameters.m_momentumAtDca = pandora::CartesianVector(std::cos(pTrackState->getPhi()), std::sin(pTrackState->getPhi()), pTrackState->getTanLambda()) * pt; + const double pt(m_settings.m_bField * 2.99792e-4 / std::fabs(pTrackState->getOmega())); + trackParameters.m_momentumAtDca = + pandora::CartesianVector(std::cos(pTrackState->getPhi()), std::sin(pTrackState->getPhi()), + pTrackState->getTanLambda()) * + pt; - this->CopyTrackState(pTrack->getTrackState(TrackState::AtFirstHit), trackParameters.m_trackStateAtStart); + this->CopyTrackState(pTrack->getTrackState(TrackState::AtFirstHit), trackParameters.m_trackStateAtStart); - //fg: curling TPC tracks have pointers to track segments stored -> need to get track states from last segment! - const EVENT::Track *pEndTrack = (pTrack->getTracks().empty() ? pTrack : pTrack->getTracks().back()); + //fg: curling TPC tracks have pointers to track segments stored -> need to get track states from last segment! + const EVENT::Track* pEndTrack = (pTrack->getTracks().empty() ? pTrack : pTrack->getTracks().back()); - this->CopyTrackState(pEndTrack->getTrackState(TrackState::AtLastHit), trackParameters.m_trackStateAtEnd); - this->CopyTrackState(pEndTrack->getTrackState(TrackState::AtCalorimeter), trackParameters.m_trackStateAtCalorimeter); + this->CopyTrackState(pEndTrack->getTrackState(TrackState::AtLastHit), trackParameters.m_trackStateAtEnd); + this->CopyTrackState(pEndTrack->getTrackState(TrackState::AtCalorimeter), trackParameters.m_trackStateAtCalorimeter); - trackParameters.m_isProjectedToEndCap = ((std::fabs(trackParameters.m_trackStateAtCalorimeter.Get().GetPosition().GetZ()) < m_settings.m_eCalEndCapInnerZ) ? false : true); + trackParameters.m_isProjectedToEndCap = + ((std::fabs(trackParameters.m_trackStateAtCalorimeter.Get().GetPosition().GetZ()) < m_settings.m_eCalEndCapInnerZ) + ? false + : true); - // Convert generic time (length from reference point to intersection, divided by momentum) into nanoseconds - const float minGenericTime(this->CalculateTrackTimeAtCalorimeter(pTrack)); - const float particleMass(trackParameters.m_mass.Get()); - const float particleEnergy(std::sqrt(particleMass * particleMass + trackParameters.m_momentumAtDca.Get().GetMagnitudeSquared())); - trackParameters.m_timeAtCalorimeter = minGenericTime * particleEnergy / 299.792f; + // Convert generic time (length from reference point to intersection, divided by momentum) into nanoseconds + const float minGenericTime(this->CalculateTrackTimeAtCalorimeter(pTrack)); + const float particleMass(trackParameters.m_mass.Get()); + const float particleEnergy( + std::sqrt(particleMass * particleMass + trackParameters.m_momentumAtDca.Get().GetMagnitudeSquared())); + trackParameters.m_timeAtCalorimeter = minGenericTime * particleEnergy / 299.792f; } //------------------------------------------------------------------------------------------------------------------------------------------ -void DDTrackCreatorBase::GetTrackStatesAtCalo( EVENT::Track *track, - lc_content::LCTrackParameters& trackParameters ){ - - if( not trackParameters.m_reachesCalorimeter.Get() ) { - streamlog_out(DEBUG5) << "Track does not reach the ECal" <getTrackState(TrackState::AtCalorimeter); - if( not trackAtCalo ) { - streamlog_out(DEBUG5) << "Track does not have a trackState at calorimeter" <getTrackState(TrackState::AtCalorimeter); + if (not trackAtCalo) { + streamlog_out(DEBUG5) << "Track does not have a trackState at calorimeter" << std::endl; + streamlog_out(DEBUG3) << toString(track) << std::endl; + return; } streamlog_out(DEBUG3) << "Original" << toString(trackAtCalo) << std::endl; const auto* tsPosition = trackAtCalo->getReferencePoint(); - if( std::fabs(tsPosition[2]) < getTrackingRegionExtent()[2] ) { - streamlog_out(DEBUG5) << "Original trackState is at Barrel" << std::endl; - pandora::InputTrackState pandoraTrackState; - this->CopyTrackState( trackAtCalo, pandoraTrackState ); - trackParameters.m_trackStates.push_back( pandoraTrackState ); - } else { // if track state is in endcap we do not repeat track state calculation, because the barrel cannot be hit - streamlog_out(DEBUG5) << "Original track state is at Endcap" << std::endl; - pandora::InputTrackState pandoraTrackState; - this->CopyTrackState( trackAtCalo, pandoraTrackState ); - trackParameters.m_trackStates.push_back( pandoraTrackState ); - return; + if (std::fabs(tsPosition[2]) < getTrackingRegionExtent()[2]) { + streamlog_out(DEBUG5) << "Original trackState is at Barrel" << std::endl; + pandora::InputTrackState pandoraTrackState; + this->CopyTrackState(trackAtCalo, pandoraTrackState); + trackParameters.m_trackStates.push_back(pandoraTrackState); + } else { // if track state is in endcap we do not repeat track state calculation, because the barrel cannot be hit + streamlog_out(DEBUG5) << "Original track state is at Endcap" << std::endl; + pandora::InputTrackState pandoraTrackState; + this->CopyTrackState(trackAtCalo, pandoraTrackState); + trackParameters.m_trackStates.push_back(pandoraTrackState); + return; } - auto marlintrk = std::unique_ptr(m_trackingSystem->createTrack()); - const EVENT::TrackerHitVec& trkHits = track->getTrackerHits(); - const int nHitsTrack = trkHits.size(); + auto marlintrk = std::unique_ptr(m_trackingSystem->createTrack()); + const EVENT::TrackerHitVec& trkHits = track->getTrackerHits(); + const int nHitsTrack = trkHits.size(); for (int iHit = 0; iHit < nHitsTrack; ++iHit) { - EVENT::TrackerHit* trkHit = trkHits[iHit] ; - if( UTIL::BitSet32( trkHit->getType() )[ UTIL::ILDTrkHitTypeBit::COMPOSITE_SPACEPOINT ] ){ //it is a composite spacepoint + EVENT::TrackerHit* trkHit = trkHits[iHit]; + if (UTIL::BitSet32( + trkHit->getType())[UTIL::ILDTrkHitTypeBit::COMPOSITE_SPACEPOINT]) { //it is a composite spacepoint //Split it up and add both hits to the MarlinTrk const EVENT::LCObjectVec& rawObjects = trkHit->getRawHits(); - for( unsigned k=0; k< rawObjects.size(); k++ ){ - EVENT::TrackerHit* rawHit = static_cast< EVENT::TrackerHit* >( rawObjects[k] ); - if( marlintrk->addHit( rawHit ) != MarlinTrk::IMarlinTrack::success ){ - streamlog_out(DEBUG4) << "DDTrackCreatorBase::GetTrackStatesAtCalo failed to add strip hit " << *rawHit << std::endl; - } + for (unsigned k = 0; k < rawObjects.size(); k++) { + EVENT::TrackerHit* rawHit = static_cast(rawObjects[k]); + if (marlintrk->addHit(rawHit) != MarlinTrk::IMarlinTrack::success) { + streamlog_out(DEBUG4) << "DDTrackCreatorBase::GetTrackStatesAtCalo failed to add strip hit " << *rawHit + << std::endl; + } } } else { - if( marlintrk->addHit(trkHits[iHit]) != MarlinTrk::IMarlinTrack::success ) - streamlog_out(DEBUG4) << "DDTrackCreatorBase::GetTrackStatesAtCalo failed to add tracker hit " << *trkHit<< std::endl; + if (marlintrk->addHit(trkHits[iHit]) != MarlinTrk::IMarlinTrack::success) + streamlog_out(DEBUG4) << "DDTrackCreatorBase::GetTrackStatesAtCalo failed to add tracker hit " << *trkHit + << std::endl; } } - bool tanL_is_positive = trackAtCalo->getTanLambda()>0; + bool tanL_is_positive = trackAtCalo->getTanLambda() > 0; auto trackState = TrackStateImpl(*trackAtCalo); - int return_error = marlintrk->initialise(trackState, m_settings.m_bField, MarlinTrk::IMarlinTrack::modeForward); - if (return_error != MarlinTrk::IMarlinTrack::success ) { - streamlog_out(DEBUG4) << "DDTrackCreatorBase::GetTrackStatesAtCalo failed to initialize track for endcap track : " << std::endl ; - return ; + int return_error = marlintrk->initialise(trackState, m_settings.m_bField, MarlinTrk::IMarlinTrack::modeForward); + if (return_error != MarlinTrk::IMarlinTrack::success) { + streamlog_out(DEBUG4) << "DDTrackCreatorBase::GetTrackStatesAtCalo failed to initialize track for endcap track : " + << std::endl; + return; } double chi2 = -DBL_MAX; - int ndf = 0; + int ndf = 0; TrackStateImpl trackStateAtCaloEndcap; unsigned ecal_endcap_face_ID = lcio::ILDDetID::ECAL_ENDCAP; - int detElementID = 0; + int detElementID = 0; m_encoder->reset(); // reset to 0 (*m_encoder)[lcio::LCTrackerCellID::subdet()] = ecal_endcap_face_ID; - (*m_encoder)[lcio::LCTrackerCellID::side()] = tanL_is_positive ? lcio::ILDDetID::fwd : lcio::ILDDetID::bwd; + (*m_encoder)[lcio::LCTrackerCellID::side()] = tanL_is_positive ? lcio::ILDDetID::fwd : lcio::ILDDetID::bwd; (*m_encoder)[lcio::LCTrackerCellID::layer()] = 0; - return_error = marlintrk->propagateToLayer(m_encoder->lowWord(), trackStateAtCaloEndcap, chi2, ndf, - detElementID, MarlinTrk::IMarlinTrack::modeForward ); - streamlog_out(DEBUG5) << "Found trackState at endcap? Error code: " << return_error << std::endl; - - if (return_error == MarlinTrk::IMarlinTrack::success ) { - streamlog_out(DEBUG3) << "Endcap" << toString(&trackStateAtCaloEndcap) << std::endl; - const auto* tsEP = trackStateAtCaloEndcap.getReferencePoint(); - const double radSquared = ( tsEP[0]*tsEP[0] + tsEP[1]*tsEP[1] ); - if( radSquared < m_minimalTrackStateRadiusSquared ) { - streamlog_out(DEBUG5) << "new track state is below tolerance radius" << std::endl; - return; - } - //for curling tracks the propagated track has the wrong z0 whereas it should be 0. really - if( std::abs( trackStateAtCaloEndcap.getZ0() ) > - std::abs( 2.*M_PI/trackStateAtCaloEndcap.getOmega() * trackStateAtCaloEndcap.getTanLambda() ) ){ - trackStateAtCaloEndcap.setZ0( 0. ); - } - streamlog_out(DEBUG5) << "new track state at endcap accepted" << std::endl; - pandora::InputTrackState pandoraAtEndcap; - this->CopyTrackState( &trackStateAtCaloEndcap, pandoraAtEndcap ); - trackParameters.m_trackStates.push_back( pandoraAtEndcap ); + return_error = marlintrk->propagateToLayer(m_encoder->lowWord(), trackStateAtCaloEndcap, chi2, ndf, detElementID, + MarlinTrk::IMarlinTrack::modeForward); + streamlog_out(DEBUG5) << "Found trackState at endcap? Error code: " << return_error << std::endl; + + if (return_error == MarlinTrk::IMarlinTrack::success) { + streamlog_out(DEBUG3) << "Endcap" << toString(&trackStateAtCaloEndcap) << std::endl; + const auto* tsEP = trackStateAtCaloEndcap.getReferencePoint(); + const double radSquared = (tsEP[0] * tsEP[0] + tsEP[1] * tsEP[1]); + if (radSquared < m_minimalTrackStateRadiusSquared) { + streamlog_out(DEBUG5) << "new track state is below tolerance radius" << std::endl; + return; + } + //for curling tracks the propagated track has the wrong z0 whereas it should be 0. really + if (std::abs(trackStateAtCaloEndcap.getZ0()) > + std::abs(2. * M_PI / trackStateAtCaloEndcap.getOmega() * trackStateAtCaloEndcap.getTanLambda())) { + trackStateAtCaloEndcap.setZ0(0.); + } + streamlog_out(DEBUG5) << "new track state at endcap accepted" << std::endl; + pandora::InputTrackState pandoraAtEndcap; + this->CopyTrackState(&trackStateAtCaloEndcap, pandoraAtEndcap); + trackParameters.m_trackStates.push_back(pandoraAtEndcap); } return; @@ -489,120 +473,115 @@ void DDTrackCreatorBase::GetTrackStatesAtCalo( EVENT::Track *track, //------------------------------------------------------------------------------------------------------------------------------------------ -float DDTrackCreatorBase::CalculateTrackTimeAtCalorimeter(const EVENT::Track *const pTrack) const -{ - const pandora::Helix helix(pTrack->getPhi(), pTrack->getD0(), pTrack->getZ0(), pTrack->getOmega(), pTrack->getTanLambda(), m_settings.m_bField); - const pandora::CartesianVector &referencePoint(helix.GetReferencePoint()); - - // First project to endcap - float minGenericTime(std::numeric_limits::max()); - - pandora::CartesianVector bestECalProjection(0.f, 0.f, 0.f); - const int signPz((helix.GetMomentum().GetZ() > 0.f) ? 1 : -1); - (void) helix.GetPointInZ(static_cast(signPz) * m_settings.m_eCalEndCapInnerZ, referencePoint, bestECalProjection, minGenericTime); - - // Then project to barrel surface(s) - pandora::CartesianVector barrelProjection(0.f, 0.f, 0.f); - if (m_settings.m_eCalBarrelInnerSymmetry > 0) - { - // Polygon - float twopi_n = 2. * M_PI / (static_cast(m_settings.m_eCalBarrelInnerSymmetry)); - - for (int i = 0; i < m_settings.m_eCalBarrelInnerSymmetry; ++i) - { - float genericTime(std::numeric_limits::max()); - const float phi(twopi_n * static_cast(i) + m_settings.m_eCalBarrelInnerPhi0); - - const pandora::StatusCode statusCode(helix.GetPointInXY(m_settings.m_eCalBarrelInnerR * std::cos(phi), m_settings.m_eCalBarrelInnerR * std::sin(phi), - std::cos(phi + 0.5 * M_PI), std::sin(phi + 0.5 * M_PI), referencePoint, barrelProjection, genericTime)); - - if ((pandora::STATUS_CODE_SUCCESS == statusCode) && (genericTime < minGenericTime)) - { - minGenericTime = genericTime; - bestECalProjection = barrelProjection; - } - } +float DDTrackCreatorBase::CalculateTrackTimeAtCalorimeter(const EVENT::Track* const pTrack) const { + const pandora::Helix helix(pTrack->getPhi(), pTrack->getD0(), pTrack->getZ0(), pTrack->getOmega(), + pTrack->getTanLambda(), m_settings.m_bField); + const pandora::CartesianVector& referencePoint(helix.GetReferencePoint()); + + // First project to endcap + float minGenericTime(std::numeric_limits::max()); + + pandora::CartesianVector bestECalProjection(0.f, 0.f, 0.f); + const int signPz((helix.GetMomentum().GetZ() > 0.f) ? 1 : -1); + (void)helix.GetPointInZ(static_cast(signPz) * m_settings.m_eCalEndCapInnerZ, referencePoint, + bestECalProjection, minGenericTime); + + // Then project to barrel surface(s) + pandora::CartesianVector barrelProjection(0.f, 0.f, 0.f); + if (m_settings.m_eCalBarrelInnerSymmetry > 0) { + // Polygon + float twopi_n = 2. * M_PI / (static_cast(m_settings.m_eCalBarrelInnerSymmetry)); + + for (int i = 0; i < m_settings.m_eCalBarrelInnerSymmetry; ++i) { + float genericTime(std::numeric_limits::max()); + const float phi(twopi_n * static_cast(i) + m_settings.m_eCalBarrelInnerPhi0); + + const pandora::StatusCode statusCode(helix.GetPointInXY( + m_settings.m_eCalBarrelInnerR * std::cos(phi), m_settings.m_eCalBarrelInnerR * std::sin(phi), + std::cos(phi + 0.5 * M_PI), std::sin(phi + 0.5 * M_PI), referencePoint, barrelProjection, genericTime)); + + if ((pandora::STATUS_CODE_SUCCESS == statusCode) && (genericTime < minGenericTime)) { + minGenericTime = genericTime; + bestECalProjection = barrelProjection; + } } - else - { - // Cylinder - float genericTime(std::numeric_limits::max()); - const pandora::StatusCode statusCode(helix.GetPointOnCircle(m_settings.m_eCalBarrelInnerR, referencePoint, barrelProjection, genericTime)); - - if ((pandora::STATUS_CODE_SUCCESS == statusCode) && (genericTime < minGenericTime)) - { - minGenericTime = genericTime; - bestECalProjection = barrelProjection; - } + } else { + // Cylinder + float genericTime(std::numeric_limits::max()); + const pandora::StatusCode statusCode( + helix.GetPointOnCircle(m_settings.m_eCalBarrelInnerR, referencePoint, barrelProjection, genericTime)); + + if ((pandora::STATUS_CODE_SUCCESS == statusCode) && (genericTime < minGenericTime)) { + minGenericTime = genericTime; + bestECalProjection = barrelProjection; } + } - if (bestECalProjection.GetMagnitudeSquared() < std::numeric_limits::epsilon()) - throw pandora::StatusCodeException(pandora::STATUS_CODE_NOT_INITIALIZED); + if (bestECalProjection.GetMagnitudeSquared() < std::numeric_limits::epsilon()) + throw pandora::StatusCodeException(pandora::STATUS_CODE_NOT_INITIALIZED); - return minGenericTime; + return minGenericTime; } //------------------------------------------------------------------------------------------------------------------------------------------ -void DDTrackCreatorBase::CopyTrackState(const TrackState *const pTrackState, pandora::InputTrackState &inputTrackState) const -{ - if (!pTrackState) - throw pandora::StatusCodeException(pandora::STATUS_CODE_NOT_INITIALIZED); +void DDTrackCreatorBase::CopyTrackState(const TrackState* const pTrackState, + pandora::InputTrackState& inputTrackState) const { + if (!pTrackState) + throw pandora::StatusCodeException(pandora::STATUS_CODE_NOT_INITIALIZED); - const double pt(m_settings.m_bField * 2.99792e-4 / std::fabs(pTrackState->getOmega())); + const double pt(m_settings.m_bField * 2.99792e-4 / std::fabs(pTrackState->getOmega())); - const double px(pt * std::cos(pTrackState->getPhi())); - const double py(pt * std::sin(pTrackState->getPhi())); - const double pz(pt * pTrackState->getTanLambda()); + const double px(pt * std::cos(pTrackState->getPhi())); + const double py(pt * std::sin(pTrackState->getPhi())); + const double pz(pt * pTrackState->getTanLambda()); - const double xs(pTrackState->getReferencePoint()[0]); - const double ys(pTrackState->getReferencePoint()[1]); - const double zs(pTrackState->getReferencePoint()[2]); + const double xs(pTrackState->getReferencePoint()[0]); + const double ys(pTrackState->getReferencePoint()[1]); + const double zs(pTrackState->getReferencePoint()[2]); - inputTrackState = pandora::TrackState(xs, ys, zs, px, py, pz); + inputTrackState = pandora::TrackState(xs, ys, zs, px, py, pz); } //------------------------------------------------------------------------------------------------------------------------------------------ -DDTrackCreatorBase::Settings::Settings() : - m_trackCollections( StringVector() ), - m_kinkVertexCollections( StringVector() ), - m_prongVertexCollections( StringVector() ), - m_splitVertexCollections( StringVector() ), - m_v0VertexCollections( StringVector() ), - m_prongSplitVertexCollections(StringVector()), - m_shouldFormTrackRelationships(1), - m_minTrackHits(5), - m_minFtdTrackHits(0), - m_maxTrackHits(5000.f), - m_d0TrackCut(50.f), - m_z0TrackCut(50.f), - m_usingNonVertexTracks(1), - m_usingUnmatchedNonVertexTracks(0), - m_usingUnmatchedVertexTracks(1), - m_unmatchedVertexTrackMaxEnergy(5.f), - m_d0UnmatchedVertexTrackCut(5.f), - m_z0UnmatchedVertexTrackCut(5.f), - m_zCutForNonVertexTracks(250.f), - m_reachesECalNBarrelTrackerHits(11), - m_reachesECalNFtdHits(4), - m_reachesECalBarrelTrackerOuterDistance(-100.f), - m_reachesECalMinFtdLayer(9), - m_reachesECalBarrelTrackerZMaxDistance(-50.f), - m_reachesECalFtdZMaxDistance(1.f), - m_curvatureToMomentumFactor(0.3f / 2000.f), - m_minTrackECalDistanceFromIp(100.f), - m_maxTrackSigmaPOverP(0.15f), - m_minMomentumForTrackHitChecks(1.f), - m_maxBarrelTrackerInnerRDistance(50.f), - m_minBarrelTrackerHitFractionOfExpected(0.2f), - m_minFtdHitsForBarrelTrackerHitFraction(2), - m_trackStateTolerance(0.f), - m_trackingSystemName("DDKalTest"), - m_bField(0.f), - m_eCalBarrelInnerSymmetry(0), - m_eCalBarrelInnerPhi0(0.f), - m_eCalBarrelInnerR(0.f), - m_eCalEndCapInnerZ(0.f) -{ -} +DDTrackCreatorBase::Settings::Settings() + : m_trackCollections(StringVector()), + m_kinkVertexCollections(StringVector()), + m_prongVertexCollections(StringVector()), + m_splitVertexCollections(StringVector()), + m_v0VertexCollections(StringVector()), + m_prongSplitVertexCollections(StringVector()), + m_shouldFormTrackRelationships(1), + m_minTrackHits(5), + m_minFtdTrackHits(0), + m_maxTrackHits(5000.f), + m_d0TrackCut(50.f), + m_z0TrackCut(50.f), + m_usingNonVertexTracks(1), + m_usingUnmatchedNonVertexTracks(0), + m_usingUnmatchedVertexTracks(1), + m_unmatchedVertexTrackMaxEnergy(5.f), + m_d0UnmatchedVertexTrackCut(5.f), + m_z0UnmatchedVertexTrackCut(5.f), + m_zCutForNonVertexTracks(250.f), + m_reachesECalNBarrelTrackerHits(11), + m_reachesECalNFtdHits(4), + m_reachesECalBarrelTrackerOuterDistance(-100.f), + m_reachesECalMinFtdLayer(9), + m_reachesECalBarrelTrackerZMaxDistance(-50.f), + m_reachesECalFtdZMaxDistance(1.f), + m_curvatureToMomentumFactor(0.3f / 2000.f), + m_minTrackECalDistanceFromIp(100.f), + m_maxTrackSigmaPOverP(0.15f), + m_minMomentumForTrackHitChecks(1.f), + m_maxBarrelTrackerInnerRDistance(50.f), + m_minBarrelTrackerHitFractionOfExpected(0.2f), + m_minFtdHitsForBarrelTrackerHitFraction(2), + m_trackStateTolerance(0.f), + m_trackingSystemName("DDKalTest"), + m_bField(0.f), + m_eCalBarrelInnerSymmetry(0), + m_eCalBarrelInnerPhi0(0.f), + m_eCalBarrelInnerR(0.f), + m_eCalEndCapInnerZ(0.f) {} diff --git a/k4GaudiPandora/src/DDTrackCreatorCLIC.cc b/k4GaudiPandora/src/DDTrackCreatorCLIC.cc index 1e2dbcb..ade41eb 100644 --- a/k4GaudiPandora/src/DDTrackCreatorCLIC.cc +++ b/k4GaudiPandora/src/DDTrackCreatorCLIC.cc @@ -1,8 +1,27 @@ +/* + * Copyright (c) 2020-2024 Key4hep-Project. + * + * This file is part of Key4hep. + * See https://key4hep.github.io/key4hep-doc/ for further info. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + /** * @file DDMarlinPandora/src/DDTrackCreatorCLIC.cc - * + * * @brief Implementation of the track creator class for a CLIC all silicon tracker. - * + * * $Log: $ */ @@ -17,14 +36,14 @@ #include "UTIL/ILDConf.h" #include "UTIL/Operators.h" -#include "Pandora/PdgTable.h" #include "LCObjects/LCTrack.h" +#include "Pandora/PdgTable.h" -#include "DD4hep/Detector.h" #include "DD4hep/DD4hepUnits.h" -#include "DDRec/DetectorData.h" #include "DD4hep/DetType.h" +#include "DD4hep/Detector.h" #include "DD4hep/DetectorSelector.h" +#include "DDRec/DetectorData.h" #include #include @@ -33,509 +52,476 @@ //forward declarations. See in DDPandoraPFANewProcessor.cc std::vector getTrackingRegionExtent(); -DDTrackCreatorCLIC::DDTrackCreatorCLIC(const Settings &settings, const pandora::Pandora *const pPandora) - : DDTrackCreatorBase(settings,pPandora), - m_trackerInnerR( 0.f ), - m_trackerOuterR( 0.f ), - m_trackerZmax( 0.f ), - m_cosTracker( 0.f ), - m_endcapDiskInnerRadii( DoubleVector() ), - m_endcapDiskOuterRadii( DoubleVector() ), - m_endcapDiskZPositions( DoubleVector() ), - m_nEndcapDiskLayers( 0 ), - m_barrelTrackerLayers( 0 ), - m_tanLambdaEndcapDisk( 0.f ) +DDTrackCreatorCLIC::DDTrackCreatorCLIC(const Settings& settings, const pandora::Pandora* const pPandora) + : DDTrackCreatorBase(settings, pPandora), + m_trackerInnerR(0.f), + m_trackerOuterR(0.f), + m_trackerZmax(0.f), + m_cosTracker(0.f), + m_endcapDiskInnerRadii(DoubleVector()), + m_endcapDiskOuterRadii(DoubleVector()), + m_endcapDiskZPositions(DoubleVector()), + m_nEndcapDiskLayers(0), + m_barrelTrackerLayers(0), + m_tanLambdaEndcapDisk(0.f) { - - m_trackerInnerR = getTrackingRegionExtent()[0]; - m_trackerOuterR = getTrackingRegionExtent()[1]; - m_trackerZmax = getTrackingRegionExtent()[2]; - - - ///FIXME: Probably need to be something relating to last disk inner radius - m_cosTracker = m_trackerZmax / std::sqrt(m_trackerZmax * m_trackerZmax + m_trackerInnerR * m_trackerInnerR); - - - dd4hep::Detector & mainDetector = dd4hep::Detector::getInstance(); - - //Maybe we need to veto the vertex? That was done in the ILD case - const std::vector< dd4hep::DetElement>& barrelDets = dd4hep::DetectorSelector(mainDetector).detectors( ( dd4hep::DetType::TRACKER | dd4hep::DetType::BARREL )) ; - - m_barrelTrackerLayers = 0; - for (std::vector< dd4hep::DetElement>::const_iterator iter = barrelDets.begin(), iterEnd = barrelDets.end();iter != iterEnd; ++iter){ - try - { - dd4hep::rec::ZPlanarData * theExtension = 0; - - const dd4hep::DetElement& theDetector = *iter; - theExtension = theDetector.extension(); - - unsigned int N = theExtension->layers.size(); - m_barrelTrackerLayers=m_barrelTrackerLayers+N; - - streamlog_out( DEBUG2 ) << " Adding layers for barrel tracker from DD4hep for "<< theDetector.name()<< "- n layers: " << N<< " sum up to now: "<(*iter).name()<<" : " << exception.what() << std::endl; - } - } - - m_nEndcapDiskLayers=0; - m_endcapDiskInnerRadii.clear(); - m_endcapDiskOuterRadii.clear(); - - //Instead of gear, loop over a provided list of forward (read: endcap) tracking detectors. For ILD this would be FTD - - const std::vector< dd4hep::DetElement>& endcapDets = dd4hep::DetectorSelector(mainDetector).detectors( ( dd4hep::DetType::TRACKER | dd4hep::DetType::ENDCAP )) ; - - for (std::vector< dd4hep::DetElement>::const_iterator iter = endcapDets.begin(), iterEnd = endcapDets.end();iter != iterEnd; ++iter){ - try - { - dd4hep::rec::ZDiskPetalsData * theExtension = 0; - - const dd4hep::DetElement& theDetector = *iter; - theExtension = theDetector.extension(); - - unsigned int N = theExtension->layers.size(); - - streamlog_out( DEBUG2 ) << " Filling FTD-like parameters from DD4hep for "<< theDetector.name()<< "- n layers: " << N<< std::endl; - - for(unsigned int i = 0; i < N; ++i) - { - - dd4hep::rec::ZDiskPetalsData::LayerLayout thisLayer = theExtension->layers[i]; - - // Create a disk to represent even number petals front side - //FIXME! VERIFY THAT TIS MAKES SENSE! - m_endcapDiskInnerRadii.push_back(thisLayer.distanceSensitive/dd4hep::mm); - m_endcapDiskOuterRadii.push_back(thisLayer.distanceSensitive/dd4hep::mm+thisLayer.lengthSensitive/dd4hep::mm); - - // Take the mean z position of the staggered petals - const double zpos(thisLayer.zPosition/dd4hep::mm); - m_endcapDiskZPositions.push_back(zpos); - - streamlog_out( DEBUG2 ) << " layer " << i << " - mean z position = " << zpos << std::endl; - } - - m_nEndcapDiskLayers = m_endcapDiskZPositions.size() ; - - } catch (std::runtime_error &exception){ - - streamlog_out(WARNING) << "DDTrackCreatorCLIC exception during Forward Tracking Disk parameter construction for detector "<(*iter).name()<<" : " << exception.what() << std::endl; - } - } - - - for (unsigned int iEndcapDiskLayer = 0; iEndcapDiskLayer < m_nEndcapDiskLayers; ++iEndcapDiskLayer) - { - if ((std::fabs(m_endcapDiskOuterRadii[iEndcapDiskLayer]) < std::numeric_limits::epsilon()) || - (std::fabs(m_endcapDiskInnerRadii[iEndcapDiskLayer]) < std::numeric_limits::epsilon())) - { - throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER); - } + m_trackerInnerR = getTrackingRegionExtent()[0]; + m_trackerOuterR = getTrackingRegionExtent()[1]; + m_trackerZmax = getTrackingRegionExtent()[2]; + + ///FIXME: Probably need to be something relating to last disk inner radius + m_cosTracker = m_trackerZmax / std::sqrt(m_trackerZmax * m_trackerZmax + m_trackerInnerR * m_trackerInnerR); + + dd4hep::Detector& mainDetector = dd4hep::Detector::getInstance(); + + //Maybe we need to veto the vertex? That was done in the ILD case + const std::vector& barrelDets = + dd4hep::DetectorSelector(mainDetector).detectors((dd4hep::DetType::TRACKER | dd4hep::DetType::BARREL)); + + m_barrelTrackerLayers = 0; + for (std::vector::const_iterator iter = barrelDets.begin(), iterEnd = barrelDets.end(); + iter != iterEnd; ++iter) { + try { + dd4hep::rec::ZPlanarData* theExtension = 0; + + const dd4hep::DetElement& theDetector = *iter; + theExtension = theDetector.extension(); + + unsigned int N = theExtension->layers.size(); + m_barrelTrackerLayers = m_barrelTrackerLayers + N; + + streamlog_out(DEBUG2) << " Adding layers for barrel tracker from DD4hep for " << theDetector.name() + << "- n layers: " << N << " sum up to now: " << m_barrelTrackerLayers << std::endl; + } catch (std::runtime_error& exception) { + streamlog_out(WARNING) << "DDTrackCreatorCLIC exception during Barrel Tracker layer sum for " + << const_cast(*iter).name() << " : " << exception.what() << std::endl; } + } - m_tanLambdaEndcapDisk = m_endcapDiskZPositions[0] / m_endcapDiskOuterRadii[0]; + m_nEndcapDiskLayers = 0; + m_endcapDiskInnerRadii.clear(); + m_endcapDiskOuterRadii.clear(); -} + //Instead of gear, loop over a provided list of forward (read: endcap) tracking detectors. For ILD this would be FTD -//------------------------------------------------------------------------------------------------------------------------------------------ + const std::vector& endcapDets = + dd4hep::DetectorSelector(mainDetector).detectors((dd4hep::DetType::TRACKER | dd4hep::DetType::ENDCAP)); -DDTrackCreatorCLIC::~DDTrackCreatorCLIC() -{ + for (std::vector::const_iterator iter = endcapDets.begin(), iterEnd = endcapDets.end(); + iter != iterEnd; ++iter) { + try { + dd4hep::rec::ZDiskPetalsData* theExtension = 0; + + const dd4hep::DetElement& theDetector = *iter; + theExtension = theDetector.extension(); + + unsigned int N = theExtension->layers.size(); + + streamlog_out(DEBUG2) << " Filling FTD-like parameters from DD4hep for " << theDetector.name() + << "- n layers: " << N << std::endl; + + for (unsigned int i = 0; i < N; ++i) { + dd4hep::rec::ZDiskPetalsData::LayerLayout thisLayer = theExtension->layers[i]; + + // Create a disk to represent even number petals front side + //FIXME! VERIFY THAT TIS MAKES SENSE! + m_endcapDiskInnerRadii.push_back(thisLayer.distanceSensitive / dd4hep::mm); + m_endcapDiskOuterRadii.push_back(thisLayer.distanceSensitive / dd4hep::mm + + thisLayer.lengthSensitive / dd4hep::mm); + + // Take the mean z position of the staggered petals + const double zpos(thisLayer.zPosition / dd4hep::mm); + m_endcapDiskZPositions.push_back(zpos); + + streamlog_out(DEBUG2) << " layer " << i << " - mean z position = " << zpos << std::endl; + } + + m_nEndcapDiskLayers = m_endcapDiskZPositions.size(); + + } catch (std::runtime_error& exception) { + streamlog_out(WARNING) + << "DDTrackCreatorCLIC exception during Forward Tracking Disk parameter construction for detector " + << const_cast(*iter).name() << " : " << exception.what() << std::endl; + } + } + + for (unsigned int iEndcapDiskLayer = 0; iEndcapDiskLayer < m_nEndcapDiskLayers; ++iEndcapDiskLayer) { + if ((std::fabs(m_endcapDiskOuterRadii[iEndcapDiskLayer]) < std::numeric_limits::epsilon()) || + (std::fabs(m_endcapDiskInnerRadii[iEndcapDiskLayer]) < std::numeric_limits::epsilon())) { + throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER); + } + } + + m_tanLambdaEndcapDisk = m_endcapDiskZPositions[0] / m_endcapDiskOuterRadii[0]; } //------------------------------------------------------------------------------------------------------------------------------------------ -pandora::StatusCode DDTrackCreatorCLIC::CreateTracks(EVENT::LCEvent *pLCEvent) -{ +DDTrackCreatorCLIC::~DDTrackCreatorCLIC() {} - for (StringVector::const_iterator iter = m_settings.m_trackCollections.begin(), iterEnd = m_settings.m_trackCollections.end(); - iter != iterEnd; ++iter) - { - try - { - const EVENT::LCCollection *pTrackCollection = pLCEvent->getCollection(*iter); - - - ///FIXME: Should really move to using surfaces - for (int i = 0, iMax = pTrackCollection->getNumberOfElements(); i < iMax; ++i) - { - EVENT::Track *pTrack = dynamic_cast(pTrackCollection->getElementAt(i)); - - if (NULL == pTrack) - throw EVENT::Exception("Collection type mismatch"); - - streamlog_out(DEBUG0)<<" Warning! Ignoring expected number of hits and other hit number cuts. Should eventually change!"<getTanLambda())); -// -// if (tanLambda > m_tanLambdaEndcapDisk) -// { -// int expectedEndcapDiskHits(0); -// -// for (unsigned int iEndcapDiskLayer = 0; iEndcapDiskLayer < m_nEndcapDiskLayers; ++iEndcapDiskLayer) -// { -// -// //FIXME: Does not take into account spiral endcap -// if ((tanLambda > m_endcapDiskZPositions[iEndcapDiskLayer] / m_endcapDiskOuterRadii[iEndcapDiskLayer]) && -// (tanLambda < m_endcapDiskZPositions[iEndcapDiskLayer] / m_endcapDiskInnerRadii[iEndcapDiskLayer])) -// { -// expectedEndcapDiskHits++; -// } -// } -// -// minTrackHits = std::max(m_settings.m_minEndcapDiskTrackHits, expectedEndcapDiskHits); -// -// streamlog_out(DEBUG0)<<"XXX minTrackHits: "<(pTrack->getTrackerHits().size())); -// -// if ((nTrackHits < minTrackHits) || (nTrackHits > m_settings.m_maxTrackHits)){ -// streamlog_out(DEBUG0)<<"XXX Dropping track due to nTrackHits= "<getD0(); - trackParameters.m_z0 = pTrack->getZ0(); - trackParameters.m_pParentAddress = pTrack; - - // By default, assume tracks are charged pions - const float signedCurvature(pTrack->getOmega()); - trackParameters.m_particleId = (signedCurvature > 0) ? pandora::PI_PLUS : pandora::PI_MINUS; - trackParameters.m_mass = pandora::PdgTable::GetParticleMass(pandora::PI_PLUS); - - // Use particle id information from V0 and Kink finders - TrackToPidMap::const_iterator trackPIDiter = m_trackToPidMap.find(pTrack); - - if(trackPIDiter != m_trackToPidMap.end()) - { - trackParameters.m_particleId = trackPIDiter->second; - trackParameters.m_mass = pandora::PdgTable::GetParticleMass(trackPIDiter->second); - } - - if (0.f != signedCurvature) - trackParameters.m_charge = static_cast(signedCurvature / std::fabs(signedCurvature)); - - - try - { - //FIXME: Should consider adding a try-catch block to check - //against cases where a track has invalid parameters like - //very small omega. Especially for omegaGetTrackStates(pTrack, trackParameters); - this->TrackReachesECAL(pTrack, trackParameters); - this->GetTrackStatesAtCalo(pTrack, trackParameters); - this->DefineTrackPfoUsage(pTrack, trackParameters); - - PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::Track::Create(m_pandora, trackParameters, *m_lcTrackFactory)); - m_trackVector.push_back(pTrack); - } - catch (pandora::StatusCodeException &statusCodeException) - { - streamlog_out(ERROR) << "Failed to extract a track: " << statusCodeException.ToString() << std::endl; - - streamlog_out( DEBUG3 ) << " failed track : " << *pTrack << std::endl ; - } - catch (EVENT::Exception &exception) - { - streamlog_out(WARNING) << "Failed to extract a vertex: " << exception.what() << std::endl; - } - } - - streamlog_out( DEBUG5 ) << "After treating collection : " << *iter<<" with "<getNumberOfElements()<<" tracks, the track vector size is "<< m_trackVector.size()<< std::endl ; +//------------------------------------------------------------------------------------------------------------------------------------------ +pandora::StatusCode DDTrackCreatorCLIC::CreateTracks(EVENT::LCEvent* pLCEvent) { + for (StringVector::const_iterator iter = m_settings.m_trackCollections.begin(), + iterEnd = m_settings.m_trackCollections.end(); + iter != iterEnd; ++iter) { + try { + const EVENT::LCCollection* pTrackCollection = pLCEvent->getCollection(*iter); + + ///FIXME: Should really move to using surfaces + for (int i = 0, iMax = pTrackCollection->getNumberOfElements(); i < iMax; ++i) { + EVENT::Track* pTrack = dynamic_cast(pTrackCollection->getElementAt(i)); + + if (NULL == pTrack) + throw EVENT::Exception("Collection type mismatch"); + + streamlog_out(DEBUG0) + << " Warning! Ignoring expected number of hits and other hit number cuts. Should eventually change!" + << std::endl; + + // int minTrackHits = m_settings.m_minTrackHits; + // const float tanLambda(std::fabs(pTrack->getTanLambda())); + // + // if (tanLambda > m_tanLambdaEndcapDisk) + // { + // int expectedEndcapDiskHits(0); + // + // for (unsigned int iEndcapDiskLayer = 0; iEndcapDiskLayer < m_nEndcapDiskLayers; ++iEndcapDiskLayer) + // { + // + // //FIXME: Does not take into account spiral endcap + // if ((tanLambda > m_endcapDiskZPositions[iEndcapDiskLayer] / m_endcapDiskOuterRadii[iEndcapDiskLayer]) && + // (tanLambda < m_endcapDiskZPositions[iEndcapDiskLayer] / m_endcapDiskInnerRadii[iEndcapDiskLayer])) + // { + // expectedEndcapDiskHits++; + // } + // } + // + // minTrackHits = std::max(m_settings.m_minEndcapDiskTrackHits, expectedEndcapDiskHits); + // + // streamlog_out(DEBUG0)<<"XXX minTrackHits: "<(pTrack->getTrackerHits().size())); + // + // if ((nTrackHits < minTrackHits) || (nTrackHits > m_settings.m_maxTrackHits)){ + // streamlog_out(DEBUG0)<<"XXX Dropping track due to nTrackHits= "<getD0(); + trackParameters.m_z0 = pTrack->getZ0(); + trackParameters.m_pParentAddress = pTrack; + + // By default, assume tracks are charged pions + const float signedCurvature(pTrack->getOmega()); + trackParameters.m_particleId = (signedCurvature > 0) ? pandora::PI_PLUS : pandora::PI_MINUS; + trackParameters.m_mass = pandora::PdgTable::GetParticleMass(pandora::PI_PLUS); + + // Use particle id information from V0 and Kink finders + TrackToPidMap::const_iterator trackPIDiter = m_trackToPidMap.find(pTrack); + + if (trackPIDiter != m_trackToPidMap.end()) { + trackParameters.m_particleId = trackPIDiter->second; + trackParameters.m_mass = pandora::PdgTable::GetParticleMass(trackPIDiter->second); } - catch (EVENT::Exception &exception) - { - streamlog_out(WARNING) << "Failed to extract track collection: " << *iter << ", " << exception.what() << std::endl; + + if (0.f != signedCurvature) + trackParameters.m_charge = static_cast(signedCurvature / std::fabs(signedCurvature)); + + try { + //FIXME: Should consider adding a try-catch block to check + //against cases where a track has invalid parameters like + //very small omega. Especially for omegaGetTrackStates(pTrack, trackParameters); + this->TrackReachesECAL(pTrack, trackParameters); + this->GetTrackStatesAtCalo(pTrack, trackParameters); + this->DefineTrackPfoUsage(pTrack, trackParameters); + + PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, + PandoraApi::Track::Create(m_pandora, trackParameters, *m_lcTrackFactory)); + m_trackVector.push_back(pTrack); + } catch (pandora::StatusCodeException& statusCodeException) { + streamlog_out(ERROR) << "Failed to extract a track: " << statusCodeException.ToString() << std::endl; + + streamlog_out(DEBUG3) << " failed track : " << *pTrack << std::endl; + } catch (EVENT::Exception& exception) { + streamlog_out(WARNING) << "Failed to extract a vertex: " << exception.what() << std::endl; } - - + } + + streamlog_out(DEBUG5) << "After treating collection : " << *iter << " with " + << pTrackCollection->getNumberOfElements() << " tracks, the track vector size is " + << m_trackVector.size() << std::endl; + + } catch (EVENT::Exception& exception) { + streamlog_out(WARNING) << "Failed to extract track collection: " << *iter << ", " << exception.what() + << std::endl; } + } - return pandora::STATUS_CODE_SUCCESS; + return pandora::STATUS_CODE_SUCCESS; } -bool DDTrackCreatorCLIC::PassesQualityCuts(const EVENT::Track *const pTrack, const PandoraApi::Track::Parameters &trackParameters) const -{ - - // First simple sanity checks - if (trackParameters.m_trackStateAtCalorimeter.Get().GetPosition().GetMagnitude() < m_settings.m_minTrackECalDistanceFromIp){ - streamlog_out(WARNING) << " Dropping track! Distance at ECAL: " << trackParameters.m_trackStateAtCalorimeter.Get().GetPosition().GetMagnitude()<getOmega() == 0.f) { + streamlog_out(ERROR) << "Track has Omega = 0 " << std::endl; + return false; + } + + // Check momentum uncertainty is reasonable to use track + const pandora::CartesianVector& momentumAtDca(trackParameters.m_momentumAtDca.Get()); + const float sigmaPOverP(std::sqrt(pTrack->getCovMatrix()[5]) / std::fabs(pTrack->getOmega())); + + if (sigmaPOverP > m_settings.m_maxTrackSigmaPOverP) { + streamlog_out(WARNING) << " Dropping track : " << momentumAtDca.GetMagnitude() << "+-" + << sigmaPOverP * (momentumAtDca.GetMagnitude()) << " chi2 = " << pTrack->getChi2() << " " + << pTrack->getNdf() << " from " << pTrack->getTrackerHits().size() << std::endl; + + streamlog_out(DEBUG3) << " track : " << *pTrack << std::endl; + return false; + } + + streamlog_out(DEBUG3) << " TEMPORARILY ACCEPT TRACK WITHOUT CUTS (should change!)" << *pTrack << std::endl; + return true; + + // Require reasonable number of Tracker hits + if (momentumAtDca.GetMagnitude() > m_settings.m_minMomentumForTrackHitChecks) { + const float pX(fabs(momentumAtDca.GetX())); + const float pY(fabs(momentumAtDca.GetY())); + const float pZ(fabs(momentumAtDca.GetZ())); + const float pT(std::sqrt(pX * pX + pY * pY)); + const float rInnermostHit(pTrack->getRadiusOfInnermostHit()); + + if ((0.f == pT) || (0.f == pZ) || (rInnermostHit == m_trackerOuterR)) { + streamlog_out(ERROR) << "Invalid track parameter, pT " << pT << ", pZ " << pZ << ", rInnermostHit " + << rInnermostHit << std::endl; + return false; } - if (pTrack->getOmega() == 0.f) - { - streamlog_out(ERROR) << "Track has Omega = 0 " << std::endl; - return false; + float nExpectedTrackerHits(0.); + + if (pZ < m_trackerZmax / m_trackerOuterR * pT) { + const float innerExpectedHitRadius(std::max(m_trackerInnerR, rInnermostHit)); + const float frac((m_trackerOuterR - innerExpectedHitRadius) / (m_trackerOuterR - m_trackerInnerR)); + nExpectedTrackerHits = m_barrelTrackerLayers * frac; } - // Check momentum uncertainty is reasonable to use track - const pandora::CartesianVector &momentumAtDca(trackParameters.m_momentumAtDca.Get()); - const float sigmaPOverP(std::sqrt(pTrack->getCovMatrix()[5]) / std::fabs(pTrack->getOmega())); + if ((pZ <= m_trackerZmax / m_trackerInnerR * pT) && (pZ >= m_trackerZmax / m_trackerOuterR * pT)) { + const float innerExpectedHitRadius(std::max(m_trackerInnerR, rInnermostHit)); + const float frac((m_trackerZmax * pT / pZ - innerExpectedHitRadius) / (m_trackerOuterR - innerExpectedHitRadius)); + nExpectedTrackerHits = frac * m_barrelTrackerLayers; + } - if (sigmaPOverP > m_settings.m_maxTrackSigmaPOverP) - { - streamlog_out(WARNING) << " Dropping track : " << momentumAtDca.GetMagnitude() << "+-" << sigmaPOverP * (momentumAtDca.GetMagnitude()) - << " chi2 = " << pTrack->getChi2() << " " << pTrack->getNdf() - << " from " << pTrack->getTrackerHits().size() << std::endl ; + const EVENT::IntVec& hitsBySubdetector(pTrack->getSubdetectorHitNumbers()); + + // ---- use hitsInFit : + //Use flags to access detectors and then access their ids to get hits in fit by ID + //(new way of storing hits in MarlinTrkUtils) + + //Initialize hits to 0 + int nBarrelTrackerHits = 0; + dd4hep::Detector& mainDetector = dd4hep::Detector::getInstance(); + const std::vector& barrelDets = + dd4hep::DetectorSelector(mainDetector).detectors((dd4hep::DetType::TRACKER | dd4hep::DetType::BARREL)); + for (std::vector::const_iterator iter = barrelDets.begin(), iterEnd = barrelDets.end(); + iter != iterEnd; ++iter) { + const dd4hep::DetElement& theDetector = *iter; + int detId = theDetector.id(); + nBarrelTrackerHits += hitsBySubdetector[2 * detId - 2]; //Offset is 2 for hits in fit + } - streamlog_out(DEBUG3) << " track : " << *pTrack - << std::endl; - return false; + int nEndcapTrackerHits = 0; + const std::vector& endcapDets = + dd4hep::DetectorSelector(mainDetector).detectors((dd4hep::DetType::TRACKER | dd4hep::DetType::ENDCAP)); + for (std::vector::const_iterator iter = endcapDets.begin(), iterEnd = endcapDets.end(); + iter != iterEnd; ++iter) { + const dd4hep::DetElement& theDetector = *iter; + int detId = theDetector.id(); + nEndcapTrackerHits += hitsBySubdetector[2 * detId - 2]; //Offset is 2 for hits in fit } - streamlog_out( DEBUG3 ) << " TEMPORARILY ACCEPT TRACK WITHOUT CUTS (should change!)" << *pTrack << std::endl ; - return true; - - // Require reasonable number of Tracker hits - if (momentumAtDca.GetMagnitude() > m_settings.m_minMomentumForTrackHitChecks) - { - const float pX(fabs(momentumAtDca.GetX())); - const float pY(fabs(momentumAtDca.GetY())); - const float pZ(fabs(momentumAtDca.GetZ())); - const float pT(std::sqrt(pX * pX + pY * pY)); - const float rInnermostHit(pTrack->getRadiusOfInnermostHit()); - - if ((0.f == pT) || (0.f == pZ) || (rInnermostHit == m_trackerOuterR)) - { - streamlog_out(ERROR) << "Invalid track parameter, pT " << pT << ", pZ " << pZ << ", rInnermostHit " << rInnermostHit << std::endl; - return false; - } + const int minTrackerHits = + static_cast(nExpectedTrackerHits * m_settings.m_minBarrelTrackerHitFractionOfExpected); - float nExpectedTrackerHits(0.); + if ((nBarrelTrackerHits < minTrackerHits) && + (nEndcapTrackerHits < m_settings.m_minFtdHitsForBarrelTrackerHitFraction)) { + streamlog_out(WARNING) << " Dropping track : " << momentumAtDca.GetMagnitude() + << " Number of Tracker hits = " << nBarrelTrackerHits << " < " << minTrackerHits + << " nendcapDisk = " << nEndcapTrackerHits << std::endl; - if (pZ < m_trackerZmax / m_trackerOuterR * pT) - { - const float innerExpectedHitRadius(std::max(m_trackerInnerR, rInnermostHit)); - const float frac((m_trackerOuterR - innerExpectedHitRadius) / (m_trackerOuterR - m_trackerInnerR)); - nExpectedTrackerHits = m_barrelTrackerLayers * frac; - } + streamlog_out(DEBUG3) << " track : " << *pTrack << std::endl; + return false; + } + } - if ((pZ <= m_trackerZmax / m_trackerInnerR * pT) && (pZ >= m_trackerZmax / m_trackerOuterR * pT)) - { - const float innerExpectedHitRadius(std::max(m_trackerInnerR, rInnermostHit)); - const float frac((m_trackerZmax * pT / pZ - innerExpectedHitRadius) / (m_trackerOuterR - innerExpectedHitRadius)); - nExpectedTrackerHits = frac * m_barrelTrackerLayers; - } + return true; +} +//------------------------------------------------------------------------------------------------------------------------------------------ +void DDTrackCreatorCLIC::DefineTrackPfoUsage(const EVENT::Track* const pTrack, + PandoraApi::Track::Parameters& trackParameters) const { + bool canFormPfo(false); + bool canFormClusterlessPfo(false); - const EVENT::IntVec &hitsBySubdetector(pTrack->getSubdetectorHitNumbers()); - - // ---- use hitsInFit : - //Use flags to access detectors and then access their ids to get hits in fit by ID - //(new way of storing hits in MarlinTrkUtils) - - //Initialize hits to 0 - int nBarrelTrackerHits = 0; - dd4hep::Detector & mainDetector = dd4hep::Detector::getInstance(); - const std::vector< dd4hep::DetElement>& barrelDets = dd4hep::DetectorSelector(mainDetector).detectors( ( dd4hep::DetType::TRACKER | dd4hep::DetType::BARREL )) ; - for (std::vector< dd4hep::DetElement>::const_iterator iter = barrelDets.begin(), iterEnd = barrelDets.end();iter != iterEnd; ++iter){ - const dd4hep::DetElement & theDetector = *iter; - int detId = theDetector.id(); - nBarrelTrackerHits+=hitsBySubdetector[2*detId-2]; //Offset is 2 for hits in fit - } - - int nEndcapTrackerHits = 0; - const std::vector< dd4hep::DetElement>& endcapDets = dd4hep::DetectorSelector(mainDetector).detectors( ( dd4hep::DetType::TRACKER | dd4hep::DetType::ENDCAP )) ; - for (std::vector< dd4hep::DetElement>::const_iterator iter = endcapDets.begin(), iterEnd = endcapDets.end();iter != iterEnd; ++iter){ - const dd4hep::DetElement& theDetector = *iter; - int detId = theDetector.id(); - nEndcapTrackerHits +=hitsBySubdetector[2*detId-2]; //Offset is 2 for hits in fit - } + if (trackParameters.m_reachesCalorimeter.Get() && !this->IsParent(pTrack)) { + const float d0(std::fabs(pTrack->getD0())), z0(std::fabs(pTrack->getZ0())); + + EVENT::TrackerHitVec trackerHitvec(pTrack->getTrackerHits()); + float rInner(std::numeric_limits::max()), zMin(std::numeric_limits::max()); - const int minTrackerHits = static_cast(nExpectedTrackerHits * m_settings.m_minBarrelTrackerHitFractionOfExpected); + for (EVENT::TrackerHitVec::const_iterator iter = trackerHitvec.begin(), iterEnd = trackerHitvec.end(); + iter != iterEnd; ++iter) { + const double* pPosition((*iter)->getPosition()); + const float x(pPosition[0]), y(pPosition[1]), absoluteZ(std::fabs(pPosition[2])); + const float r(std::sqrt(x * x + y * y)); - if ((nBarrelTrackerHits < minTrackerHits) && (nEndcapTrackerHits < m_settings.m_minFtdHitsForBarrelTrackerHitFraction)) - { - streamlog_out(WARNING) << " Dropping track : " << momentumAtDca.GetMagnitude() << " Number of Tracker hits = " << nBarrelTrackerHits - << " < " << minTrackerHits << " nendcapDisk = " << nEndcapTrackerHits << std::endl; + if (r < rInner) + rInner = r; - streamlog_out(DEBUG3) << " track : " << *pTrack - << std::endl; - return false; + if (absoluteZ < zMin) + zMin = absoluteZ; + } + + if (this->PassesQualityCuts(pTrack, trackParameters)) { + const pandora::CartesianVector& momentumAtDca(trackParameters.m_momentumAtDca.Get()); + const float pX(momentumAtDca.GetX()), pY(momentumAtDca.GetY()), pZ(momentumAtDca.GetZ()); + const float pT(std::sqrt(pX * pX + pY * pY)); + + const float zCutForNonVertexTracks(m_trackerInnerR * std::fabs(pZ / pT) + m_settings.m_zCutForNonVertexTracks); + const bool passRzQualityCuts((zMin < zCutForNonVertexTracks) && + (rInner < m_trackerInnerR + m_settings.m_maxBarrelTrackerInnerRDistance)); + + const bool isV0(this->IsV0(pTrack)); + const bool isDaughter(this->IsDaughter(pTrack)); + + // Decide whether track can be associated with a pandora cluster and used to form a charged PFO + if ((d0 < m_settings.m_d0TrackCut) && (z0 < m_settings.m_z0TrackCut) && + (rInner < m_trackerInnerR + m_settings.m_maxBarrelTrackerInnerRDistance)) { + canFormPfo = true; + } else if (passRzQualityCuts && (0 != m_settings.m_usingNonVertexTracks)) { + canFormPfo = true; + } else if (isV0 || isDaughter) { + canFormPfo = true; + } + + // Decide whether track can be used to form a charged PFO, even if track fails to be associated with a pandora cluster + const float particleMass(trackParameters.m_mass.Get()); + const float trackEnergy(std::sqrt(momentumAtDca.GetMagnitudeSquared() + particleMass * particleMass)); + + if ((0 != m_settings.m_usingUnmatchedVertexTracks) && + (trackEnergy < m_settings.m_unmatchedVertexTrackMaxEnergy)) { + if ((d0 < m_settings.m_d0UnmatchedVertexTrackCut) && (z0 < m_settings.m_z0UnmatchedVertexTrackCut) && + (rInner < m_trackerInnerR + m_settings.m_maxBarrelTrackerInnerRDistance)) { + canFormClusterlessPfo = true; + } else if (passRzQualityCuts && (0 != m_settings.m_usingNonVertexTracks) && + (0 != m_settings.m_usingUnmatchedNonVertexTracks)) { + canFormClusterlessPfo = true; + } else if (isV0 || isDaughter) { + canFormClusterlessPfo = true; } + } + } else if (this->IsDaughter(pTrack) || this->IsV0(pTrack)) { + streamlog_out(WARNING) << "Recovering daughter or v0 track " + << trackParameters.m_momentumAtDca.Get().GetMagnitude() << std::endl; + canFormPfo = true; } + } - return true; + trackParameters.m_canFormPfo = canFormPfo; + trackParameters.m_canFormClusterlessPfo = canFormClusterlessPfo; } //------------------------------------------------------------------------------------------------------------------------------------------ -void DDTrackCreatorCLIC::DefineTrackPfoUsage(const EVENT::Track *const pTrack, PandoraApi::Track::Parameters &trackParameters) const -{ - bool canFormPfo(false); - bool canFormClusterlessPfo(false); +void DDTrackCreatorCLIC::TrackReachesECAL(const EVENT::Track* const pTrack, + PandoraApi::Track::Parameters& trackParameters) const { + // Calculate hit position information + float hitZMin(std::numeric_limits::max()); + float hitZMax(-std::numeric_limits::max()); + float hitOuterR(-std::numeric_limits::max()); - if (trackParameters.m_reachesCalorimeter.Get() && !this->IsParent(pTrack)) - { - const float d0(std::fabs(pTrack->getD0())), z0(std::fabs(pTrack->getZ0())); + int nTrackerHits(0); + int nEndcapDiskHits(0); + int maxOccupiedEndcapDiskLayer(0); - EVENT::TrackerHitVec trackerHitvec(pTrack->getTrackerHits()); - float rInner(std::numeric_limits::max()), zMin(std::numeric_limits::max()); + const EVENT::TrackerHitVec& trackerHitVec(pTrack->getTrackerHits()); + const unsigned int nTrackHits(trackerHitVec.size()); - for (EVENT::TrackerHitVec::const_iterator iter = trackerHitvec.begin(), iterEnd = trackerHitvec.end(); iter != iterEnd; ++iter) - { - const double *pPosition((*iter)->getPosition()); - const float x(pPosition[0]), y(pPosition[1]), absoluteZ(std::fabs(pPosition[2])); - const float r(std::sqrt(x * x + y * y)); + for (unsigned int i = 0; i < nTrackHits; ++i) { + const float x(static_cast(trackerHitVec[i]->getPosition()[0])); + const float y(static_cast(trackerHitVec[i]->getPosition()[1])); + const float z(static_cast(trackerHitVec[i]->getPosition()[2])); + const float r(std::sqrt(x * x + y * y)); - if (r < rInner) - rInner = r; + if (z > hitZMax) + hitZMax = z; - if (absoluteZ < zMin) - zMin = absoluteZ; - } + if (z < hitZMin) + hitZMin = z; - if (this->PassesQualityCuts(pTrack, trackParameters)) - { - const pandora::CartesianVector &momentumAtDca(trackParameters.m_momentumAtDca.Get()); - const float pX(momentumAtDca.GetX()), pY(momentumAtDca.GetY()), pZ(momentumAtDca.GetZ()); - const float pT(std::sqrt(pX * pX + pY * pY)); - - const float zCutForNonVertexTracks(m_trackerInnerR * std::fabs(pZ / pT) + m_settings.m_zCutForNonVertexTracks); - const bool passRzQualityCuts((zMin < zCutForNonVertexTracks) && (rInner < m_trackerInnerR + m_settings.m_maxBarrelTrackerInnerRDistance)); - - const bool isV0(this->IsV0(pTrack)); - const bool isDaughter(this->IsDaughter(pTrack)); - - // Decide whether track can be associated with a pandora cluster and used to form a charged PFO - if ((d0 < m_settings.m_d0TrackCut) && (z0 < m_settings.m_z0TrackCut) && (rInner < m_trackerInnerR + m_settings.m_maxBarrelTrackerInnerRDistance)) - { - canFormPfo = true; - } - else if (passRzQualityCuts && (0 != m_settings.m_usingNonVertexTracks)) - { - canFormPfo = true; - } - else if (isV0 || isDaughter) - { - canFormPfo = true; - } - - // Decide whether track can be used to form a charged PFO, even if track fails to be associated with a pandora cluster - const float particleMass(trackParameters.m_mass.Get()); - const float trackEnergy(std::sqrt(momentumAtDca.GetMagnitudeSquared() + particleMass * particleMass)); - - if ((0 != m_settings.m_usingUnmatchedVertexTracks) && (trackEnergy < m_settings.m_unmatchedVertexTrackMaxEnergy)) - { - if ((d0 < m_settings.m_d0UnmatchedVertexTrackCut) && (z0 < m_settings.m_z0UnmatchedVertexTrackCut) && - (rInner < m_trackerInnerR + m_settings.m_maxBarrelTrackerInnerRDistance)) - { - canFormClusterlessPfo = true; - } - else if (passRzQualityCuts && (0 != m_settings.m_usingNonVertexTracks) && (0 != m_settings.m_usingUnmatchedNonVertexTracks)) - { - canFormClusterlessPfo = true; - } - else if (isV0 || isDaughter) - { - canFormClusterlessPfo = true; - } - } - } - else if (this->IsDaughter(pTrack) || this->IsV0(pTrack)) - { - streamlog_out(WARNING) << "Recovering daughter or v0 track " << trackParameters.m_momentumAtDca.Get().GetMagnitude() << std::endl; - canFormPfo = true; - } - } - - trackParameters.m_canFormPfo = canFormPfo; - trackParameters.m_canFormClusterlessPfo = canFormClusterlessPfo; -} + if (r > hitOuterR) + hitOuterR = r; -//------------------------------------------------------------------------------------------------------------------------------------------ + if ((r > m_trackerInnerR) && (r < m_trackerOuterR) && (std::fabs(z) <= m_trackerZmax)) { + nTrackerHits++; + continue; + } -void DDTrackCreatorCLIC::TrackReachesECAL(const EVENT::Track *const pTrack, PandoraApi::Track::Parameters &trackParameters) const -{ - // Calculate hit position information - float hitZMin(std::numeric_limits::max()); - float hitZMax(-std::numeric_limits::max()); - float hitOuterR(-std::numeric_limits::max()); - - int nTrackerHits(0); - int nEndcapDiskHits(0); - int maxOccupiedEndcapDiskLayer(0); - - const EVENT::TrackerHitVec &trackerHitVec(pTrack->getTrackerHits()); - const unsigned int nTrackHits(trackerHitVec.size()); - - for (unsigned int i = 0; i < nTrackHits; ++i) - { - const float x(static_cast(trackerHitVec[i]->getPosition()[0])); - const float y(static_cast(trackerHitVec[i]->getPosition()[1])); - const float z(static_cast(trackerHitVec[i]->getPosition()[2])); - const float r(std::sqrt(x * x + y * y)); - - if (z > hitZMax) - hitZMax = z; - - if (z < hitZMin) - hitZMin = z; - - if (r > hitOuterR) - hitOuterR = r; - - if ((r > m_trackerInnerR) && (r < m_trackerOuterR) && (std::fabs(z) <= m_trackerZmax)) - { - nTrackerHits++; - continue; - } + for (unsigned int j = 0; j < m_nEndcapDiskLayers; ++j) { + if ((r > m_endcapDiskInnerRadii[j]) && (r < m_endcapDiskOuterRadii[j]) && + (std::fabs(z) - m_settings.m_reachesECalFtdZMaxDistance < m_endcapDiskZPositions[j]) && + (std::fabs(z) + m_settings.m_reachesECalFtdZMaxDistance > m_endcapDiskZPositions[j])) { + if (static_cast(j) > maxOccupiedEndcapDiskLayer) + maxOccupiedEndcapDiskLayer = static_cast(j); - for (unsigned int j = 0; j < m_nEndcapDiskLayers; ++j) - { - if ((r > m_endcapDiskInnerRadii[j]) && (r < m_endcapDiskOuterRadii[j]) && - (std::fabs(z) - m_settings.m_reachesECalFtdZMaxDistance < m_endcapDiskZPositions[j]) && - (std::fabs(z) + m_settings.m_reachesECalFtdZMaxDistance > m_endcapDiskZPositions[j])) - { - if (static_cast(j) > maxOccupiedEndcapDiskLayer) - maxOccupiedEndcapDiskLayer = static_cast(j); - - nEndcapDiskHits++; - break; - } - } + nEndcapDiskHits++; + break; + } } - - // Require sufficient hits in barrel or endcap trackers, then compare extremal hit positions with tracker dimensions - if ((nTrackerHits >= m_settings.m_reachesECalNBarrelTrackerHits) || (nEndcapDiskHits >= m_settings.m_reachesECalNFtdHits)) - { - if ((hitOuterR - m_trackerOuterR > m_settings.m_reachesECalBarrelTrackerOuterDistance) || - (std::fabs(hitZMax) - m_trackerZmax > m_settings.m_reachesECalBarrelTrackerZMaxDistance) || - (std::fabs(hitZMin) - m_trackerZmax > m_settings.m_reachesECalBarrelTrackerZMaxDistance) || - (maxOccupiedEndcapDiskLayer >= m_settings.m_reachesECalMinFtdLayer)) - { - trackParameters.m_reachesCalorimeter = true; - return; - } + } + + // Require sufficient hits in barrel or endcap trackers, then compare extremal hit positions with tracker dimensions + if ((nTrackerHits >= m_settings.m_reachesECalNBarrelTrackerHits) || + (nEndcapDiskHits >= m_settings.m_reachesECalNFtdHits)) { + if ((hitOuterR - m_trackerOuterR > m_settings.m_reachesECalBarrelTrackerOuterDistance) || + (std::fabs(hitZMax) - m_trackerZmax > m_settings.m_reachesECalBarrelTrackerZMaxDistance) || + (std::fabs(hitZMin) - m_trackerZmax > m_settings.m_reachesECalBarrelTrackerZMaxDistance) || + (maxOccupiedEndcapDiskLayer >= m_settings.m_reachesECalMinFtdLayer)) { + trackParameters.m_reachesCalorimeter = true; + return; } + } - // If track is lowpt, it may curl up and end inside tpc inner radius - const pandora::CartesianVector &momentumAtDca(trackParameters.m_momentumAtDca.Get()); - const float cosAngleAtDca(std::fabs(momentumAtDca.GetZ()) / momentumAtDca.GetMagnitude()); - const float pX(momentumAtDca.GetX()), pY(momentumAtDca.GetY()); - const float pT(std::sqrt(pX * pX + pY * pY)); + // If track is lowpt, it may curl up and end inside tpc inner radius + const pandora::CartesianVector& momentumAtDca(trackParameters.m_momentumAtDca.Get()); + const float cosAngleAtDca(std::fabs(momentumAtDca.GetZ()) / momentumAtDca.GetMagnitude()); + const float pX(momentumAtDca.GetX()), pY(momentumAtDca.GetY()); + const float pT(std::sqrt(pX * pX + pY * pY)); - if ((cosAngleAtDca > m_cosTracker) || (pT < m_settings.m_curvatureToMomentumFactor * m_settings.m_bField * m_trackerOuterR)) - { - trackParameters.m_reachesCalorimeter = true; - return; - } + if ((cosAngleAtDca > m_cosTracker) || + (pT < m_settings.m_curvatureToMomentumFactor * m_settings.m_bField * m_trackerOuterR)) { + trackParameters.m_reachesCalorimeter = true; + return; + } - trackParameters.m_reachesCalorimeter = false; + trackParameters.m_reachesCalorimeter = false; } diff --git a/k4GaudiPandora/src/DDTrackCreatorILD.cc b/k4GaudiPandora/src/DDTrackCreatorILD.cc index 574c816..85e3029 100644 --- a/k4GaudiPandora/src/DDTrackCreatorILD.cc +++ b/k4GaudiPandora/src/DDTrackCreatorILD.cc @@ -1,8 +1,27 @@ +/* + * Copyright (c) 2020-2024 Key4hep-Project. + * + * This file is part of Key4hep. + * See https://key4hep.github.io/key4hep-doc/ for further info. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + /** * @file MarlinPandora/src/DDTrackCreatorILD.cc - * + * * @brief Implementation of the track creator class for ILD. - * + * * $Log: $ */ @@ -16,133 +35,126 @@ #include "UTIL/Operators.h" #include "DDTrackCreatorILD.h" -#include "Pandora/PdgTable.h" #include "LCObjects/LCTrack.h" +#include "Pandora/PdgTable.h" #include #include #include -#include "DD4hep/Detector.h" #include "DD4hep/DD4hepUnits.h" -#include "DDRec/DetectorData.h" #include "DD4hep/DetType.h" +#include "DD4hep/Detector.h" #include "DD4hep/DetectorSelector.h" +#include "DDRec/DetectorData.h" - -DDTrackCreatorILD::DDTrackCreatorILD(const Settings &settings, const pandora::Pandora *const pPandora) - : - DDTrackCreatorBase(settings,pPandora), - m_cosTpc( 0.f ), - m_tpcInnerR( 0.f ), - m_tpcOuterR( 0.f ), - m_tpcMaxRow( 0 ), - m_tpcZmax( 0.f ), - m_tpcMembraneMaxZ( 0.f ), - m_ftdInnerRadii( DoubleVector() ), - m_ftdOuterRadii( DoubleVector() ), - m_ftdZPositions( DoubleVector() ), - m_nFtdLayers( 0 ), - m_tanLambdaFtd( 0.f ), - m_minEtdZPosition( 0.f ), - m_minSetRadius( 0.f ) +DDTrackCreatorILD::DDTrackCreatorILD(const Settings& settings, const pandora::Pandora* const pPandora) + : DDTrackCreatorBase(settings, pPandora), + m_cosTpc(0.f), + m_tpcInnerR(0.f), + m_tpcOuterR(0.f), + m_tpcMaxRow(0), + m_tpcZmax(0.f), + m_tpcMembraneMaxZ(0.f), + m_ftdInnerRadii(DoubleVector()), + m_ftdOuterRadii(DoubleVector()), + m_ftdZPositions(DoubleVector()), + m_nFtdLayers(0), + m_tanLambdaFtd(0.f), + m_minEtdZPosition(0.f), + m_minSetRadius(0.f) { - - - m_nFtdLayers=0; + m_nFtdLayers = 0; m_ftdInnerRadii.clear(); m_ftdOuterRadii.clear(); - + //Instead of gear, loop over a provided list of forward (read: endcap) tracking detectors. For ILD this would be FTD ///FIXME: Should we use surfaces instead? - dd4hep::Detector & mainDetector = dd4hep::Detector::getInstance(); - const std::vector< dd4hep::DetElement>& endcapDets = dd4hep::DetectorSelector(mainDetector).detectors( ( dd4hep::DetType::TRACKER | dd4hep::DetType::ENDCAP )) ; - for (std::vector< dd4hep::DetElement>::const_iterator iter = endcapDets.begin(), iterEnd = endcapDets.end();iter != iterEnd; ++iter){ - try - { - dd4hep::rec::ZDiskPetalsData * theExtension = 0; - - const dd4hep::DetElement& theDetector = *iter; - theExtension = theDetector.extension(); - - unsigned int N = theExtension->layers.size(); - - streamlog_out( DEBUG2 ) << " Filling FTD-like parameters from DD4hep for "<< theDetector.name() << "- n layers: " << N<< std::endl; - - for(unsigned int i = 0; i < N; ++i) - { - - dd4hep::rec::ZDiskPetalsData::LayerLayout thisLayer = theExtension->layers[i]; - - // Create a disk to represent even number petals front side - //FIXME! VERIFY THAT TIS MAKES SENSE! - m_ftdInnerRadii.push_back(thisLayer.distanceSensitive/dd4hep::mm); - m_ftdOuterRadii.push_back(thisLayer.distanceSensitive/dd4hep::mm+thisLayer.lengthSensitive/dd4hep::mm); - - // Take the mean z position of the staggered petals - const double zpos(thisLayer.zPosition/dd4hep::mm); - m_ftdZPositions.push_back(zpos); - - streamlog_out( DEBUG2 ) << " layer " << i << " - mean z position = " << zpos << std::endl; - } - - m_nFtdLayers = m_ftdZPositions.size() ; - - } catch (std::runtime_error &exception){ - - streamlog_out(WARNING) << "DDTrackCreatorILD exception during Forward Tracking Disk parameter construction for detector "<(*iter).name()<<" : " << exception.what() << std::endl; + dd4hep::Detector& mainDetector = dd4hep::Detector::getInstance(); + const std::vector& endcapDets = + dd4hep::DetectorSelector(mainDetector).detectors((dd4hep::DetType::TRACKER | dd4hep::DetType::ENDCAP)); + for (std::vector::const_iterator iter = endcapDets.begin(), iterEnd = endcapDets.end(); + iter != iterEnd; ++iter) { + try { + dd4hep::rec::ZDiskPetalsData* theExtension = 0; + + const dd4hep::DetElement& theDetector = *iter; + theExtension = theDetector.extension(); + + unsigned int N = theExtension->layers.size(); + + streamlog_out(DEBUG2) << " Filling FTD-like parameters from DD4hep for " << theDetector.name() + << "- n layers: " << N << std::endl; + + for (unsigned int i = 0; i < N; ++i) { + dd4hep::rec::ZDiskPetalsData::LayerLayout thisLayer = theExtension->layers[i]; + + // Create a disk to represent even number petals front side + //FIXME! VERIFY THAT TIS MAKES SENSE! + m_ftdInnerRadii.push_back(thisLayer.distanceSensitive / dd4hep::mm); + m_ftdOuterRadii.push_back(thisLayer.distanceSensitive / dd4hep::mm + thisLayer.lengthSensitive / dd4hep::mm); + + // Take the mean z position of the staggered petals + const double zpos(thisLayer.zPosition / dd4hep::mm); + m_ftdZPositions.push_back(zpos); + + streamlog_out(DEBUG2) << " layer " << i << " - mean z position = " << zpos << std::endl; + } + + m_nFtdLayers = m_ftdZPositions.size(); + + } catch (std::runtime_error& exception) { + streamlog_out(WARNING) + << "DDTrackCreatorILD exception during Forward Tracking Disk parameter construction for detector " + << const_cast(*iter).name() << " : " << exception.what() << std::endl; } } - - try - { - dd4hep::rec::FixedPadSizeTPCData * theExtension = 0; - //Get the TPC, make sure not to get the vertex - const std::vector< dd4hep::DetElement>& tpcDets= dd4hep::DetectorSelector(mainDetector).detectors( ( dd4hep::DetType::TRACKER | dd4hep::DetType::BARREL | dd4hep::DetType::GASEOUS ), dd4hep::DetType::VERTEX) ; - - //There should only be one TPC - theExtension = tpcDets[0].extension(); - - m_tpcInnerR = theExtension->rMin/dd4hep::mm ; - m_tpcOuterR = theExtension->rMax/dd4hep::mm ; - m_tpcMaxRow = theExtension->maxRow; - m_tpcZmax = theExtension->zHalf/dd4hep::mm ; - - - //FIXME! Add to reco structrure and access - m_tpcMembraneMaxZ = 10; - std::cout<<"WARNING! DO NOT MASK! HANDLE m_tpcMembraneMaxZ (currently hardcoded to 10)!"<& tpcDets = + dd4hep::DetectorSelector(mainDetector) + .detectors((dd4hep::DetType::TRACKER | dd4hep::DetType::BARREL | dd4hep::DetType::GASEOUS), + dd4hep::DetType::VERTEX); + + //There should only be one TPC + theExtension = tpcDets[0].extension(); + + m_tpcInnerR = theExtension->rMin / dd4hep::mm; + m_tpcOuterR = theExtension->rMax / dd4hep::mm; + m_tpcMaxRow = theExtension->maxRow; + m_tpcZmax = theExtension->zHalf / dd4hep::mm; + + //FIXME! Add to reco structrure and access + m_tpcMembraneMaxZ = 10; + std::cout << "WARNING! DO NOT MASK! HANDLE m_tpcMembraneMaxZ (currently hardcoded to 10)!" << std::endl; + + } catch (std::runtime_error& exception) { + streamlog_out(WARNING) << "DDTrackCreatorILD exception during TPC parameter construction." << std::endl; } - - + // Check tpc parameters - if ((std::fabs(m_tpcZmax) < std::numeric_limits::epsilon()) || (std::fabs(m_tpcInnerR) < std::numeric_limits::epsilon()) - || (std::fabs(m_tpcOuterR - m_tpcInnerR) < std::numeric_limits::epsilon())) - { - throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER); - } + if ((std::fabs(m_tpcZmax) < std::numeric_limits::epsilon()) || + (std::fabs(m_tpcInnerR) < std::numeric_limits::epsilon()) || + (std::fabs(m_tpcOuterR - m_tpcInnerR) < std::numeric_limits::epsilon())) { + throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER); + } m_cosTpc = m_tpcZmax / std::sqrt(m_tpcZmax * m_tpcZmax + m_tpcInnerR * m_tpcInnerR); // Check ftd parameters - if ((0 == m_nFtdLayers) || (m_nFtdLayers != m_ftdInnerRadii.size()) || (m_nFtdLayers != m_ftdOuterRadii.size())) - { - throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER); - } + if ((0 == m_nFtdLayers) || (m_nFtdLayers != m_ftdInnerRadii.size()) || (m_nFtdLayers != m_ftdOuterRadii.size())) { + throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER); + } - for (unsigned int iFtdLayer = 0; iFtdLayer < m_nFtdLayers; ++iFtdLayer) - { - if ((std::fabs(m_ftdOuterRadii[iFtdLayer]) < std::numeric_limits::epsilon()) || - (std::fabs(m_ftdInnerRadii[iFtdLayer]) < std::numeric_limits::epsilon())) - { - throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER); - } + for (unsigned int iFtdLayer = 0; iFtdLayer < m_nFtdLayers; ++iFtdLayer) { + if ((std::fabs(m_ftdOuterRadii[iFtdLayer]) < std::numeric_limits::epsilon()) || + (std::fabs(m_ftdInnerRadii[iFtdLayer]) < std::numeric_limits::epsilon())) { + throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER); } + } m_tanLambdaFtd = m_ftdZPositions[0] / m_ftdOuterRadii[0]; @@ -151,18 +163,18 @@ DDTrackCreatorILD::DDTrackCreatorILD(const Settings &settings, const pandora::Pa //FIXME: THINK OF A UNIVERSAL WAY TO HANDLE EXISTENCE OF ADDITIONAL DETECTORS streamlog_out(WARNING) << " ETDLayerZ or SETLayerRadius parameters Not being handled!" << std::endl - << " -> both will be set to " << std::numeric_limits::quiet_NaN() << std::endl; + << " -> both will be set to " << std::numeric_limits::quiet_NaN() << std::endl; m_minEtdZPosition = std::numeric_limits::quiet_NaN(); - m_minSetRadius = std::numeric_limits::quiet_NaN(); - + m_minSetRadius = std::numeric_limits::quiet_NaN(); + // try // { // const DoubleVector &etdZPositions(marlin::Global::GEAR->getGearParameters("ETD").getDoubleVals("ETDLayerZ")); // const DoubleVector &setInnerRadii(marlin::Global::GEAR->getGearParameters("SET").getDoubleVals("SETLayerRadius")); - // + // // if (etdZPositions.empty() || setInnerRadii.empty()) // throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER); - // + // // m_minEtdZPosition = *(std::min_element(etdZPositions.begin(), etdZPositions.end())); // m_minSetRadius = *(std::min_element(setInnerRadii.begin(), setInnerRadii.end())); // } @@ -170,7 +182,7 @@ DDTrackCreatorILD::DDTrackCreatorILD(const Settings &settings, const pandora::Pa // { // streamlog_out(WARNING) << " ETDLayerZ or SETLayerRadius parameters missing from GEAR parameters!" << std::endl // << " -> both will be set to " << std::numeric_limits::quiet_NaN() << std::endl; - // + // // //fg: Set them to NAN, so that they cannot be used to set trackParameters.m_reachesCalorimeter = true; // m_minEtdZPosition = std::numeric_limits::quiet_NaN(); // m_minSetRadius = std::numeric_limits::quiet_NaN(); @@ -179,407 +191,362 @@ DDTrackCreatorILD::DDTrackCreatorILD(const Settings &settings, const pandora::Pa //------------------------------------------------------------------------------------------------------------------------------------------ -DDTrackCreatorILD::~DDTrackCreatorILD() -{ -} +DDTrackCreatorILD::~DDTrackCreatorILD() {} //------------------------------------------------------------------------------------------------------------------------------------------ -pandora::StatusCode DDTrackCreatorILD::CreateTracks(EVENT::LCEvent *pLCEvent) -{ - for (StringVector::const_iterator iter = m_settings.m_trackCollections.begin(), iterEnd = m_settings.m_trackCollections.end(); - iter != iterEnd; ++iter) - { - try - { - const EVENT::LCCollection *pTrackCollection = pLCEvent->getCollection(*iter); - - for (int i = 0, iMax = pTrackCollection->getNumberOfElements(); i < iMax; ++i) - { - EVENT::Track *pTrack = dynamic_cast(pTrackCollection->getElementAt(i)); - - if (NULL == pTrack) - throw EVENT::Exception("Collection type mismatch"); - - int minTrackHits = m_settings.m_minTrackHits; - const float tanLambda(std::fabs(pTrack->getTanLambda())); - - if (tanLambda > m_tanLambdaFtd) - { - int expectedFtdHits(0); - - for (unsigned int iFtdLayer = 0; iFtdLayer < m_nFtdLayers; ++iFtdLayer) - { - if ((tanLambda > m_ftdZPositions[iFtdLayer] / m_ftdOuterRadii[iFtdLayer]) && - (tanLambda < m_ftdZPositions[iFtdLayer] / m_ftdInnerRadii[iFtdLayer])) - { - expectedFtdHits++; - } - } - - minTrackHits = std::max(m_settings.m_minFtdTrackHits, expectedFtdHits); - } - - const int nTrackHits(static_cast(pTrack->getTrackerHits().size())); - - if ((nTrackHits < minTrackHits) || (nTrackHits > m_settings.m_maxTrackHits)) - continue; - - // Proceed to create the pandora track - lc_content::LCTrackParameters trackParameters; - trackParameters.m_d0 = pTrack->getD0(); - trackParameters.m_z0 = pTrack->getZ0(); - trackParameters.m_pParentAddress = pTrack; - - // By default, assume tracks are charged pions - const float signedCurvature(pTrack->getOmega()); - trackParameters.m_particleId = (signedCurvature > 0) ? pandora::PI_PLUS : pandora::PI_MINUS; - trackParameters.m_mass = pandora::PdgTable::GetParticleMass(pandora::PI_PLUS); - - // Use particle id information from V0 and Kink finders - TrackToPidMap::const_iterator trIter = m_trackToPidMap.find(pTrack); - - if(trIter != m_trackToPidMap.end()) { - trackParameters.m_particleId = trIter->second; - trackParameters.m_mass = pandora::PdgTable::GetParticleMass(trIter->second); - } - - if (std::numeric_limits::epsilon() < std::fabs(signedCurvature)) - trackParameters.m_charge = static_cast(signedCurvature / std::fabs(signedCurvature)); - - try //fg: include the next calls in the try block to catch tracks that are yet not fitted properly as ERROR and not exceptions - { - this->GetTrackStates(pTrack, trackParameters); - this->TrackReachesECAL(pTrack, trackParameters); - this->GetTrackStatesAtCalo(pTrack, trackParameters); - this->DefineTrackPfoUsage(pTrack, trackParameters); - - PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::Track::Create(m_pandora, trackParameters, *m_lcTrackFactory)); - m_trackVector.push_back(pTrack); - } - catch (pandora::StatusCodeException &statusCodeException) - { - streamlog_out(ERROR) << "Failed to extract a track: " << statusCodeException.ToString() << std::endl; - - streamlog_out( DEBUG5 ) << " failed track : " << *pTrack << std::endl ; - } - catch (EVENT::Exception &exception) - { - streamlog_out(WARNING) << "Failed to extract a vertex: " << exception.what() << std::endl; - } +pandora::StatusCode DDTrackCreatorILD::CreateTracks(EVENT::LCEvent* pLCEvent) { + for (StringVector::const_iterator iter = m_settings.m_trackCollections.begin(), + iterEnd = m_settings.m_trackCollections.end(); + iter != iterEnd; ++iter) { + try { + const EVENT::LCCollection* pTrackCollection = pLCEvent->getCollection(*iter); + + for (int i = 0, iMax = pTrackCollection->getNumberOfElements(); i < iMax; ++i) { + EVENT::Track* pTrack = dynamic_cast(pTrackCollection->getElementAt(i)); + + if (NULL == pTrack) + throw EVENT::Exception("Collection type mismatch"); + + int minTrackHits = m_settings.m_minTrackHits; + const float tanLambda(std::fabs(pTrack->getTanLambda())); + + if (tanLambda > m_tanLambdaFtd) { + int expectedFtdHits(0); + + for (unsigned int iFtdLayer = 0; iFtdLayer < m_nFtdLayers; ++iFtdLayer) { + if ((tanLambda > m_ftdZPositions[iFtdLayer] / m_ftdOuterRadii[iFtdLayer]) && + (tanLambda < m_ftdZPositions[iFtdLayer] / m_ftdInnerRadii[iFtdLayer])) { + expectedFtdHits++; } + } + + minTrackHits = std::max(m_settings.m_minFtdTrackHits, expectedFtdHits); } - catch (EVENT::Exception &exception) + + const int nTrackHits(static_cast(pTrack->getTrackerHits().size())); + + if ((nTrackHits < minTrackHits) || (nTrackHits > m_settings.m_maxTrackHits)) + continue; + + // Proceed to create the pandora track + lc_content::LCTrackParameters trackParameters; + trackParameters.m_d0 = pTrack->getD0(); + trackParameters.m_z0 = pTrack->getZ0(); + trackParameters.m_pParentAddress = pTrack; + + // By default, assume tracks are charged pions + const float signedCurvature(pTrack->getOmega()); + trackParameters.m_particleId = (signedCurvature > 0) ? pandora::PI_PLUS : pandora::PI_MINUS; + trackParameters.m_mass = pandora::PdgTable::GetParticleMass(pandora::PI_PLUS); + + // Use particle id information from V0 and Kink finders + TrackToPidMap::const_iterator trIter = m_trackToPidMap.find(pTrack); + + if (trIter != m_trackToPidMap.end()) { + trackParameters.m_particleId = trIter->second; + trackParameters.m_mass = pandora::PdgTable::GetParticleMass(trIter->second); + } + + if (std::numeric_limits::epsilon() < std::fabs(signedCurvature)) + trackParameters.m_charge = static_cast(signedCurvature / std::fabs(signedCurvature)); + + try //fg: include the next calls in the try block to catch tracks that are yet not fitted properly as ERROR and not exceptions { - streamlog_out(WARNING) << "Failed to extract track collection: " << *iter << ", " << exception.what() << std::endl; + this->GetTrackStates(pTrack, trackParameters); + this->TrackReachesECAL(pTrack, trackParameters); + this->GetTrackStatesAtCalo(pTrack, trackParameters); + this->DefineTrackPfoUsage(pTrack, trackParameters); + + PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, + PandoraApi::Track::Create(m_pandora, trackParameters, *m_lcTrackFactory)); + m_trackVector.push_back(pTrack); + } catch (pandora::StatusCodeException& statusCodeException) { + streamlog_out(ERROR) << "Failed to extract a track: " << statusCodeException.ToString() << std::endl; + + streamlog_out(DEBUG5) << " failed track : " << *pTrack << std::endl; + } catch (EVENT::Exception& exception) { + streamlog_out(WARNING) << "Failed to extract a vertex: " << exception.what() << std::endl; } + } + } catch (EVENT::Exception& exception) { + streamlog_out(WARNING) << "Failed to extract track collection: " << *iter << ", " << exception.what() + << std::endl; } + } return pandora::STATUS_CODE_SUCCESS; } -bool DDTrackCreatorILD::PassesQualityCuts(const EVENT::Track *const pTrack, const PandoraApi::Track::Parameters &trackParameters) const -{ +bool DDTrackCreatorILD::PassesQualityCuts(const EVENT::Track* const pTrack, + const PandoraApi::Track::Parameters& trackParameters) const { // First simple sanity checks - if (trackParameters.m_trackStateAtCalorimeter.Get().GetPosition().GetMagnitude() < m_settings.m_minTrackECalDistanceFromIp) + if (trackParameters.m_trackStateAtCalorimeter.Get().GetPosition().GetMagnitude() < + m_settings.m_minTrackECalDistanceFromIp) return false; - if (std::fabs(pTrack->getOmega()) < std::numeric_limits::epsilon()) - { - streamlog_out(ERROR) << "Track has Omega = 0 " << std::endl; - return false; - } - + if (std::fabs(pTrack->getOmega()) < std::numeric_limits::epsilon()) { + streamlog_out(ERROR) << "Track has Omega = 0 " << std::endl; + return false; + } - if( pTrack->getNdf() < 0 ){ - streamlog_out(ERROR) << "Track is unconstrained - ndf = " << pTrack->getNdf() << std::endl; + if (pTrack->getNdf() < 0) { + streamlog_out(ERROR) << "Track is unconstrained - ndf = " << pTrack->getNdf() << std::endl; return false; } // Check momentum uncertainty is reasonable to use track - const pandora::CartesianVector &momentumAtDca(trackParameters.m_momentumAtDca.Get()); - const float sigmaPOverP(std::sqrt(pTrack->getCovMatrix()[5]) / std::fabs(pTrack->getOmega())); + const pandora::CartesianVector& momentumAtDca(trackParameters.m_momentumAtDca.Get()); + const float sigmaPOverP(std::sqrt(pTrack->getCovMatrix()[5]) / std::fabs(pTrack->getOmega())); - if (sigmaPOverP > m_settings.m_maxTrackSigmaPOverP) - { - streamlog_out(WARNING) << " Dropping track : " << momentumAtDca.GetMagnitude() << "+-" << sigmaPOverP * (momentumAtDca.GetMagnitude()) - << " chi2 = " << pTrack->getChi2() << " " << pTrack->getNdf() - << " from " << pTrack->getTrackerHits().size() << std::endl ; + if (sigmaPOverP > m_settings.m_maxTrackSigmaPOverP) { + streamlog_out(WARNING) << " Dropping track : " << momentumAtDca.GetMagnitude() << "+-" + << sigmaPOverP * (momentumAtDca.GetMagnitude()) << " chi2 = " << pTrack->getChi2() << " " + << pTrack->getNdf() << " from " << pTrack->getTrackerHits().size() << std::endl; - streamlog_out(DEBUG5) << " track : " << *pTrack - << std::endl; + streamlog_out(DEBUG5) << " track : " << *pTrack << std::endl; + return false; + } + + // Require reasonable number of TPC hits + if (momentumAtDca.GetMagnitude() > m_settings.m_minMomentumForTrackHitChecks) { + const float pX(fabs(momentumAtDca.GetX())); + const float pY(fabs(momentumAtDca.GetY())); + const float pZ(fabs(momentumAtDca.GetZ())); + const float pT(std::sqrt(pX * pX + pY * pY)); + const float rInnermostHit(pTrack->getRadiusOfInnermostHit()); + + if ((std::numeric_limits::epsilon() > std::fabs(pT)) || + (std::numeric_limits::epsilon() > std::fabs(pZ)) || (rInnermostHit == m_tpcOuterR)) { + streamlog_out(ERROR) << "Invalid track parameter, pT " << pT << ", pZ " << pZ << ", rInnermostHit " + << rInnermostHit << std::endl; return false; } - // Require reasonable number of TPC hits - if (momentumAtDca.GetMagnitude() > m_settings.m_minMomentumForTrackHitChecks) - { - const float pX(fabs(momentumAtDca.GetX())); - const float pY(fabs(momentumAtDca.GetY())); - const float pZ(fabs(momentumAtDca.GetZ())); - const float pT(std::sqrt(pX * pX + pY * pY)); - const float rInnermostHit(pTrack->getRadiusOfInnermostHit()); - - if ((std::numeric_limits::epsilon() > std::fabs(pT)) || (std::numeric_limits::epsilon() > std::fabs(pZ)) || (rInnermostHit == m_tpcOuterR)) - { - streamlog_out(ERROR) << "Invalid track parameter, pT " << pT << ", pZ " << pZ << ", rInnermostHit " << rInnermostHit << std::endl; - return false; - } - - float nExpectedTpcHits(0.); + float nExpectedTpcHits(0.); - if (pZ < m_tpcZmax / m_tpcOuterR * pT) - { - const float innerExpectedHitRadius(std::max(m_tpcInnerR, rInnermostHit)); - const float frac((m_tpcOuterR - innerExpectedHitRadius) / (m_tpcOuterR - m_tpcInnerR)); - nExpectedTpcHits = m_tpcMaxRow * frac; - } + if (pZ < m_tpcZmax / m_tpcOuterR * pT) { + const float innerExpectedHitRadius(std::max(m_tpcInnerR, rInnermostHit)); + const float frac((m_tpcOuterR - innerExpectedHitRadius) / (m_tpcOuterR - m_tpcInnerR)); + nExpectedTpcHits = m_tpcMaxRow * frac; + } - if ((pZ <= m_tpcZmax / m_tpcInnerR * pT) && (pZ >= m_tpcZmax / m_tpcOuterR * pT)) - { - const float innerExpectedHitRadius(std::max(m_tpcInnerR, rInnermostHit)); - const float frac((m_tpcZmax * pT / pZ - innerExpectedHitRadius) / (m_tpcOuterR - innerExpectedHitRadius)); - nExpectedTpcHits = frac * m_tpcMaxRow; - } + if ((pZ <= m_tpcZmax / m_tpcInnerR * pT) && (pZ >= m_tpcZmax / m_tpcOuterR * pT)) { + const float innerExpectedHitRadius(std::max(m_tpcInnerR, rInnermostHit)); + const float frac((m_tpcZmax * pT / pZ - innerExpectedHitRadius) / (m_tpcOuterR - innerExpectedHitRadius)); + nExpectedTpcHits = frac * m_tpcMaxRow; + } - // TODO Get TPC membrane information from GEAR when available - if (std::fabs(pZ) / momentumAtDca.GetMagnitude() < m_tpcMembraneMaxZ / m_tpcInnerR) - nExpectedTpcHits = 0; + // TODO Get TPC membrane information from GEAR when available + if (std::fabs(pZ) / momentumAtDca.GetMagnitude() < m_tpcMembraneMaxZ / m_tpcInnerR) + nExpectedTpcHits = 0; - const int nTpcHits(this->GetNTpcHits(pTrack)); - const int nFtdHits(this->GetNFtdHits(pTrack)); + const int nTpcHits(this->GetNTpcHits(pTrack)); + const int nFtdHits(this->GetNFtdHits(pTrack)); - const int minTpcHits = static_cast(nExpectedTpcHits * m_settings.m_minBarrelTrackerHitFractionOfExpected); + const int minTpcHits = static_cast(nExpectedTpcHits * m_settings.m_minBarrelTrackerHitFractionOfExpected); - if ((nTpcHits < minTpcHits) && (nFtdHits < m_settings.m_minFtdHitsForBarrelTrackerHitFraction)) - { - streamlog_out(WARNING) << " Dropping track : " << momentumAtDca.GetMagnitude() << " Number of TPC hits = " << nTpcHits - << " < " << minTpcHits << " nftd = " << nFtdHits << std::endl; + if ((nTpcHits < minTpcHits) && (nFtdHits < m_settings.m_minFtdHitsForBarrelTrackerHitFraction)) { + streamlog_out(WARNING) << " Dropping track : " << momentumAtDca.GetMagnitude() + << " Number of TPC hits = " << nTpcHits << " < " << minTpcHits << " nftd = " << nFtdHits + << std::endl; - streamlog_out(DEBUG5) << " track : " << *pTrack - << std::endl; - return false; - } + streamlog_out(DEBUG5) << " track : " << *pTrack << std::endl; + return false; } + } return true; } //------------------------------------------------------------------------------------------------------------------------------------------ -void DDTrackCreatorILD::DefineTrackPfoUsage(const EVENT::Track *const pTrack, PandoraApi::Track::Parameters &trackParameters) const -{ +void DDTrackCreatorILD::DefineTrackPfoUsage(const EVENT::Track* const pTrack, + PandoraApi::Track::Parameters& trackParameters) const { bool canFormPfo(false); bool canFormClusterlessPfo(false); - if (trackParameters.m_reachesCalorimeter.Get() && !this->IsParent(pTrack)) - { - const float d0(std::fabs(pTrack->getD0())), z0(std::fabs(pTrack->getZ0())); + if (trackParameters.m_reachesCalorimeter.Get() && !this->IsParent(pTrack)) { + const float d0(std::fabs(pTrack->getD0())), z0(std::fabs(pTrack->getZ0())); - streamlog_out(DEBUG3) << " -- DefineTrackPfoUsage called for track : " << UTIL::lcshort( pTrack ) - << std::endl; + streamlog_out(DEBUG3) << " -- DefineTrackPfoUsage called for track : " << UTIL::lcshort(pTrack) << std::endl; - EVENT::TrackerHitVec trackerHitvec(pTrack->getTrackerHits()); - float rInner(std::numeric_limits::max()), zMin(std::numeric_limits::max()); + EVENT::TrackerHitVec trackerHitvec(pTrack->getTrackerHits()); + float rInner(std::numeric_limits::max()), zMin(std::numeric_limits::max()); - for (EVENT::TrackerHitVec::const_iterator iter = trackerHitvec.begin(), iterEnd = trackerHitvec.end(); iter != iterEnd; ++iter) - { - const double *pPosition((*iter)->getPosition()); - const float x(pPosition[0]), y(pPosition[1]), absoluteZ(std::fabs(pPosition[2])); - const float r(std::sqrt(x * x + y * y)); + for (EVENT::TrackerHitVec::const_iterator iter = trackerHitvec.begin(), iterEnd = trackerHitvec.end(); + iter != iterEnd; ++iter) { + const double* pPosition((*iter)->getPosition()); + const float x(pPosition[0]), y(pPosition[1]), absoluteZ(std::fabs(pPosition[2])); + const float r(std::sqrt(x * x + y * y)); - if (r < rInner) - rInner = r; + if (r < rInner) + rInner = r; - if (absoluteZ < zMin) - zMin = absoluteZ; - } - - if (this->PassesQualityCuts(pTrack, trackParameters)) - { - - const pandora::CartesianVector &momentumAtDca(trackParameters.m_momentumAtDca.Get()); - const float pX(momentumAtDca.GetX()), pY(momentumAtDca.GetY()), pZ(momentumAtDca.GetZ()); - const float pT(std::sqrt(pX * pX + pY * pY)); - - const float zCutForNonVertexTracks(m_tpcInnerR * std::fabs(pZ / pT) + m_settings.m_zCutForNonVertexTracks); - const bool passRzQualityCuts((zMin < zCutForNonVertexTracks) && (rInner < m_tpcInnerR + m_settings.m_maxBarrelTrackerInnerRDistance)); - - const bool isV0(this->IsV0(pTrack)); - const bool isDaughter(this->IsDaughter(pTrack)); - - streamlog_out(DEBUG3) << " -- track passed quality cuts and has : " - << " passRzQualityCuts " << passRzQualityCuts - << " isV0 " << isV0 - << " isDaughter " << isDaughter << std::endl ; - - // Decide whether track can be associated with a pandora cluster and used to form a charged PFO - if ((d0 < m_settings.m_d0TrackCut) && (z0 < m_settings.m_z0TrackCut) && (rInner < m_tpcInnerR + m_settings.m_maxBarrelTrackerInnerRDistance)) - { - canFormPfo = true; - } - else if (passRzQualityCuts && (0 != m_settings.m_usingNonVertexTracks)) - { - canFormPfo = true; - } - else if (isV0 || isDaughter) - { - canFormPfo = true; - } - - - // Decide whether track can be used to form a charged PFO, even if track fails to be associated with a pandora cluster - const float particleMass(trackParameters.m_mass.Get()); - const float trackEnergy(std::sqrt(momentumAtDca.GetMagnitudeSquared() + particleMass * particleMass)); - - if ((0 != m_settings.m_usingUnmatchedVertexTracks) && (trackEnergy < m_settings.m_unmatchedVertexTrackMaxEnergy)) - { - if ((d0 < m_settings.m_d0UnmatchedVertexTrackCut) && (z0 < m_settings.m_z0UnmatchedVertexTrackCut) && - (rInner < m_tpcInnerR + m_settings.m_maxBarrelTrackerInnerRDistance)) - { - canFormClusterlessPfo = true; - } - else if (passRzQualityCuts && (0 != m_settings.m_usingNonVertexTracks) && (0 != m_settings.m_usingUnmatchedNonVertexTracks)) - { - canFormClusterlessPfo = true; - } - else if (isV0 || isDaughter) - { - canFormClusterlessPfo = true; - } - } + if (absoluteZ < zMin) + zMin = absoluteZ; + } + if (this->PassesQualityCuts(pTrack, trackParameters)) { + const pandora::CartesianVector& momentumAtDca(trackParameters.m_momentumAtDca.Get()); + const float pX(momentumAtDca.GetX()), pY(momentumAtDca.GetY()), pZ(momentumAtDca.GetZ()); + const float pT(std::sqrt(pX * pX + pY * pY)); + + const float zCutForNonVertexTracks(m_tpcInnerR * std::fabs(pZ / pT) + m_settings.m_zCutForNonVertexTracks); + const bool passRzQualityCuts((zMin < zCutForNonVertexTracks) && + (rInner < m_tpcInnerR + m_settings.m_maxBarrelTrackerInnerRDistance)); + + const bool isV0(this->IsV0(pTrack)); + const bool isDaughter(this->IsDaughter(pTrack)); + + streamlog_out(DEBUG3) << " -- track passed quality cuts and has : " + << " passRzQualityCuts " << passRzQualityCuts << " isV0 " << isV0 << " isDaughter " + << isDaughter << std::endl; + + // Decide whether track can be associated with a pandora cluster and used to form a charged PFO + if ((d0 < m_settings.m_d0TrackCut) && (z0 < m_settings.m_z0TrackCut) && + (rInner < m_tpcInnerR + m_settings.m_maxBarrelTrackerInnerRDistance)) { + canFormPfo = true; + } else if (passRzQualityCuts && (0 != m_settings.m_usingNonVertexTracks)) { + canFormPfo = true; + } else if (isV0 || isDaughter) { + canFormPfo = true; + } + + // Decide whether track can be used to form a charged PFO, even if track fails to be associated with a pandora cluster + const float particleMass(trackParameters.m_mass.Get()); + const float trackEnergy(std::sqrt(momentumAtDca.GetMagnitudeSquared() + particleMass * particleMass)); + + if ((0 != m_settings.m_usingUnmatchedVertexTracks) && + (trackEnergy < m_settings.m_unmatchedVertexTrackMaxEnergy)) { + if ((d0 < m_settings.m_d0UnmatchedVertexTrackCut) && (z0 < m_settings.m_z0UnmatchedVertexTrackCut) && + (rInner < m_tpcInnerR + m_settings.m_maxBarrelTrackerInnerRDistance)) { + canFormClusterlessPfo = true; + } else if (passRzQualityCuts && (0 != m_settings.m_usingNonVertexTracks) && + (0 != m_settings.m_usingUnmatchedNonVertexTracks)) { + canFormClusterlessPfo = true; + } else if (isV0 || isDaughter) { + canFormClusterlessPfo = true; } - else if (this->IsDaughter(pTrack) || this->IsV0(pTrack)) - { - streamlog_out(WARNING) << "Recovering daughter or v0 track " << trackParameters.m_momentumAtDca.Get().GetMagnitude() << std::endl; - canFormPfo = true; - } - - streamlog_out(DEBUG3) << " -- track canFormPfo = " << canFormPfo << " - canFormClusterlessPfo = " << canFormClusterlessPfo << std::endl; + } + } else if (this->IsDaughter(pTrack) || this->IsV0(pTrack)) { + streamlog_out(WARNING) << "Recovering daughter or v0 track " + << trackParameters.m_momentumAtDca.Get().GetMagnitude() << std::endl; + canFormPfo = true; } - trackParameters.m_canFormPfo = canFormPfo; + streamlog_out(DEBUG3) << " -- track canFormPfo = " << canFormPfo + << " - canFormClusterlessPfo = " << canFormClusterlessPfo << std::endl; + } + + trackParameters.m_canFormPfo = canFormPfo; trackParameters.m_canFormClusterlessPfo = canFormClusterlessPfo; } //------------------------------------------------------------------------------------------------------------------------------------------ -void DDTrackCreatorILD::TrackReachesECAL(const EVENT::Track *const pTrack, PandoraApi::Track::Parameters &trackParameters) const -{ +void DDTrackCreatorILD::TrackReachesECAL(const EVENT::Track* const pTrack, + PandoraApi::Track::Parameters& trackParameters) const { //fg: return true for now - there are quality checks in DefineTrackPfoUsage() ... trackParameters.m_reachesCalorimeter = true; return; - + // at a later stage we could simply check if there is a valid track state at the calorimeter: // ... - - - - + // Calculate hit position information float hitZMin(std::numeric_limits::max()); float hitZMax(-std::numeric_limits::max()); float hitOuterR(-std::numeric_limits::max()); - + int maxOccupiedFtdLayer(0); - - const EVENT::TrackerHitVec &trackerHitVec(pTrack->getTrackerHits()); - const unsigned int nTrackHits(trackerHitVec.size()); - for (unsigned int i = 0; i < nTrackHits; ++i) - { - const float x(static_cast(trackerHitVec[i]->getPosition()[0])); - const float y(static_cast(trackerHitVec[i]->getPosition()[1])); - const float z(static_cast(trackerHitVec[i]->getPosition()[2])); - const float r(std::sqrt(x * x + y * y)); + const EVENT::TrackerHitVec& trackerHitVec(pTrack->getTrackerHits()); + const unsigned int nTrackHits(trackerHitVec.size()); - if (z > hitZMax) - hitZMax = z; + for (unsigned int i = 0; i < nTrackHits; ++i) { + const float x(static_cast(trackerHitVec[i]->getPosition()[0])); + const float y(static_cast(trackerHitVec[i]->getPosition()[1])); + const float z(static_cast(trackerHitVec[i]->getPosition()[2])); + const float r(std::sqrt(x * x + y * y)); - if (z < hitZMin) - hitZMin = z; + if (z > hitZMax) + hitZMax = z; - if (r > hitOuterR) - hitOuterR = r; + if (z < hitZMin) + hitZMin = z; - if ((r > m_tpcInnerR) && (r < m_tpcOuterR) && (std::fabs(z) <= m_tpcZmax)) - { - continue; - } + if (r > hitOuterR) + hitOuterR = r; - for (unsigned int j = 0; j < m_nFtdLayers; ++j) - { - if ((r > m_ftdInnerRadii[j]) && (r < m_ftdOuterRadii[j]) && - (std::fabs(z) - m_settings.m_reachesECalFtdZMaxDistance < m_ftdZPositions[j]) && - (std::fabs(z) + m_settings.m_reachesECalFtdZMaxDistance > m_ftdZPositions[j])) - { - if (static_cast(j) > maxOccupiedFtdLayer) - maxOccupiedFtdLayer = static_cast(j); - - break; - } - } + if ((r > m_tpcInnerR) && (r < m_tpcOuterR) && (std::fabs(z) <= m_tpcZmax)) { + continue; } - const int nTpcHits(this->GetNTpcHits(pTrack)); - const int nFtdHits(this->GetNFtdHits(pTrack)); - - // Look to see if there are hits in etd or set, implying track has reached edge of ecal - if ((hitOuterR > m_minSetRadius) || (hitZMax > m_minEtdZPosition)) - { - trackParameters.m_reachesCalorimeter = true; - return; - } + for (unsigned int j = 0; j < m_nFtdLayers; ++j) { + if ((r > m_ftdInnerRadii[j]) && (r < m_ftdOuterRadii[j]) && + (std::fabs(z) - m_settings.m_reachesECalFtdZMaxDistance < m_ftdZPositions[j]) && + (std::fabs(z) + m_settings.m_reachesECalFtdZMaxDistance > m_ftdZPositions[j])) { + if (static_cast(j) > maxOccupiedFtdLayer) + maxOccupiedFtdLayer = static_cast(j); - // Require sufficient hits in tpc or ftd, then compare extremal hit positions with tracker dimensions - if ((nTpcHits >= m_settings.m_reachesECalNBarrelTrackerHits) || (nFtdHits >= m_settings.m_reachesECalNFtdHits)) - { - if ((hitOuterR - m_tpcOuterR > m_settings.m_reachesECalBarrelTrackerOuterDistance) || - (std::fabs(hitZMax) - m_tpcZmax > m_settings.m_reachesECalBarrelTrackerZMaxDistance) || - (std::fabs(hitZMin) - m_tpcZmax > m_settings.m_reachesECalBarrelTrackerZMaxDistance) || - (maxOccupiedFtdLayer >= m_settings.m_reachesECalMinFtdLayer)) - { - trackParameters.m_reachesCalorimeter = true; - return; - } + break; + } } + } - // If track is lowpt, it may curl up and end inside tpc inner radius - const pandora::CartesianVector &momentumAtDca(trackParameters.m_momentumAtDca.Get()); - const float cosAngleAtDca(std::fabs(momentumAtDca.GetZ()) / momentumAtDca.GetMagnitude()); - const float pX(momentumAtDca.GetX()), pY(momentumAtDca.GetY()); - const float pT(std::sqrt(pX * pX + pY * pY)); + const int nTpcHits(this->GetNTpcHits(pTrack)); + const int nFtdHits(this->GetNFtdHits(pTrack)); + + // Look to see if there are hits in etd or set, implying track has reached edge of ecal + if ((hitOuterR > m_minSetRadius) || (hitZMax > m_minEtdZPosition)) { + trackParameters.m_reachesCalorimeter = true; + return; + } - if ((cosAngleAtDca > m_cosTpc) || (pT < m_settings.m_curvatureToMomentumFactor * m_settings.m_bField * m_tpcOuterR)) - { + // Require sufficient hits in tpc or ftd, then compare extremal hit positions with tracker dimensions + if ((nTpcHits >= m_settings.m_reachesECalNBarrelTrackerHits) || (nFtdHits >= m_settings.m_reachesECalNFtdHits)) { + if ((hitOuterR - m_tpcOuterR > m_settings.m_reachesECalBarrelTrackerOuterDistance) || + (std::fabs(hitZMax) - m_tpcZmax > m_settings.m_reachesECalBarrelTrackerZMaxDistance) || + (std::fabs(hitZMin) - m_tpcZmax > m_settings.m_reachesECalBarrelTrackerZMaxDistance) || + (maxOccupiedFtdLayer >= m_settings.m_reachesECalMinFtdLayer)) { trackParameters.m_reachesCalorimeter = true; return; } + } + + // If track is lowpt, it may curl up and end inside tpc inner radius + const pandora::CartesianVector& momentumAtDca(trackParameters.m_momentumAtDca.Get()); + const float cosAngleAtDca(std::fabs(momentumAtDca.GetZ()) / momentumAtDca.GetMagnitude()); + const float pX(momentumAtDca.GetX()), pY(momentumAtDca.GetY()); + const float pT(std::sqrt(pX * pX + pY * pY)); + + if ((cosAngleAtDca > m_cosTpc) || (pT < m_settings.m_curvatureToMomentumFactor * m_settings.m_bField * m_tpcOuterR)) { + trackParameters.m_reachesCalorimeter = true; + return; + } trackParameters.m_reachesCalorimeter = false; } -int DDTrackCreatorILD::GetNTpcHits(const EVENT::Track *const pTrack) const -{ - // ATTN - //According to FG: [ 2 * lcio::ILDDetID::TPC - 2 ] is the first number and it is supposed to - //be the number of hits in the fit and this is what should be used ! - // at least for DD4hep/DDSim +int DDTrackCreatorILD::GetNTpcHits(const EVENT::Track* const pTrack) const { + // ATTN + //According to FG: [ 2 * lcio::ILDDetID::TPC - 2 ] is the first number and it is supposed to + //be the number of hits in the fit and this is what should be used ! + // at least for DD4hep/DDSim - // ---- use hitsInFit : - return pTrack->getSubdetectorHitNumbers()[ 2 * lcio::ILDDetID::TPC - 2 ]; + // ---- use hitsInFit : + return pTrack->getSubdetectorHitNumbers()[2 * lcio::ILDDetID::TPC - 2]; } //------------------------------------------------------------------------------------------------------------------------------------------ -int DDTrackCreatorILD::GetNFtdHits(const EVENT::Track *const pTrack) const -{ - // ATTN - //see above - // ---- use hitsInFit : - return pTrack->getSubdetectorHitNumbers()[ 2 * lcio::ILDDetID::FTD - 2 ]; +int DDTrackCreatorILD::GetNFtdHits(const EVENT::Track* const pTrack) const { + // ATTN + //see above + // ---- use hitsInFit : + return pTrack->getSubdetectorHitNumbers()[2 * lcio::ILDDetID::FTD - 2]; } //