From b66a3004b8f9462aeb0263dae52ee1e5f04b08f6 Mon Sep 17 00:00:00 2001 From: Peter McKeown Date: Fri, 8 Nov 2024 17:06:07 +0100 Subject: [PATCH 01/36] initial progress --- include/DDML/PolyhedraBarrelGeometry.h | 4 ++- scripts/ddsim_steer.py | 41 +++++++++++++++++++++++++- src/PolyhedraBarrelGeometry.cc | 14 +++++++++ 3 files changed, 57 insertions(+), 2 deletions(-) diff --git a/include/DDML/PolyhedraBarrelGeometry.h b/include/DDML/PolyhedraBarrelGeometry.h index ee08de2..8dbce2b 100644 --- a/include/DDML/PolyhedraBarrelGeometry.h +++ b/include/DDML/PolyhedraBarrelGeometry.h @@ -27,8 +27,10 @@ class PolyhedraBarrelGeometry : public GeometryInterface { /// declare the proerties needed for the plugin void declareProperties(dd4hep::sim::Geant4Action* plugin) { - plugin->declareProperty("Detector", this->m_detector); + plugin->declareProperty("isHadShower", m_isHadShower) plugin->declareProperty("Detector", this->m_detector); + plugin->declareProperty("HadDetector", this->m_HadDetector); plugin->declareProperty("Symmetry", this->m_nSymmetry); + plugin->declareProperty("HadSymmetry", this->m_nHadSymmetry); plugin->declareProperty("CorrectForAngles", this->m_correctForAngles); } diff --git a/scripts/ddsim_steer.py b/scripts/ddsim_steer.py index 94dec80..5a7ec2b 100644 --- a/scripts/ddsim_steer.py +++ b/scripts/ddsim_steer.py @@ -515,16 +515,28 @@ def LoadHdf5(kernel): BIBAE = True Two_Angle = True old_DD4hep = False ## use for DD4hep versions/commits before ~ Apr 21st 2023 + hadrons = True if ild == True: ml_barrel_name = "EcalBarrel" ml_barrel_symmetry = 8 ml_endcap_name = "EcalEndcap" + + ## For hadron shower fast simulation + ml_had_barrel_name = "HcalBarrel" + ml_had_barrel_symmetry = 8 + ml_had_endcap_name = "HcalEndcap" + else: ml_barrel_name = "ECalBarrel" ml_barrel_symmetry = 12 ml_endcap_name = "ECalEndcap" + ## For hadron shower fast simulation is needed + ml_had_barrel_name = "HCalBarrel" + ml_had_barrel_symmetry = 12 + ml_had_endcap_name = "HCalEndcap" + if BIBAE == True and Two_Angle == True: ml_file = "../models/photons-E5050A-theta9090A-phi9090-p1.hdf5" ml_model = ( @@ -533,6 +545,10 @@ def LoadHdf5(kernel): ml_model_1 = "LoadHDF5RegularGridTwoAngleBIBAEModelEndcap/EndcapModelTorch" ml_correct_angles = False + if hadrons == True: + ml_model_had = "LoadHDF5HadronPointCloudModelPolyhedraBarrel/BarrelModelTorch" + ml_correct_angles = False + from g4units import GeV, MeV # DO NOT REMOVE OR MOVE!!!!! (EXCLAMATION MARK) from DDG4 import DetectorConstruction, Geant4, PhysicsList @@ -557,6 +573,7 @@ def LoadHdf5(kernel): seq.adopt(sensitives) # ----------------- + ## EM in Barrel model = DetectorConstruction(kernel, str(ml_model)) ## # Mandatory model parameters @@ -579,6 +596,7 @@ def LoadHdf5(kernel): model.enableUI() seq.adopt(model) # ------------------- + ## EM in Endcap model1 = DetectorConstruction(kernel, str(ml_model_1)) ## # Mandatory model parameters @@ -599,12 +617,33 @@ def LoadHdf5(kernel): model1.enableUI() seq.adopt(model1) + + # ------------------- + ## Hadrons in Barrel + modelHad1 = DetectorConstruction(kernel, str()) + + ## # Mandatory model parameters + model.isHadShower = True + model.RegionName = "EcalBarrelRegion" ## hadron model triggers in ecal + model.Detector = ml_barrel_name + model.HadDetector = ml_had_barrel_name + model.Symmetry = ml_barrel_symmetry + model.HadSymmetry = ml_had_barrel_symmetry + model.Enable = True + model.CorrectForAngles = ml_correct_angles + # Energy boundaries are optional: Units are GeV + model.ApplicableParticles = {"pi+"} + model.Etrigger = {"pi+": 10.0 * GeV} # trigger on lower training threshold + model.FilePath = ml_file + # model.OptimizeFlag = 1 + # model.IntraOpNumThreads = 1 + # ------------------- # Now build the physics list: phys = kernel.physicsList() ph = PhysicsList(kernel, str("Geant4FastPhysics/FastPhysicsList")) - ph.EnabledParticles = ["e+", "e-", "gamma"] + ph.EnabledParticles = ["e+", "e-", "gamma", "pi+"] ph.BeVerbose = True ph.enableUI() phys.adopt(ph) diff --git a/src/PolyhedraBarrelGeometry.cc b/src/PolyhedraBarrelGeometry.cc index 9b2ef65..f7f4f6a 100644 --- a/src/PolyhedraBarrelGeometry.cc +++ b/src/PolyhedraBarrelGeometry.cc @@ -16,6 +16,12 @@ void PolyhedraBarrelGeometry::initialize() { auto det = theDetector.detector(m_detector); auto* cal = det.extension(); + // For hadronic shower simulation + if (m_isHadShower == true) { + auto det_had = theDetector.detector(m_HadDetector); + auto* cal_had = det_had.extension(); + } + if (cal) { for (auto l : cal->layers) { m_caloLayerDistances.push_back((l.distance + l.inner_thickness) / dd4hep::mm); @@ -23,6 +29,14 @@ void PolyhedraBarrelGeometry::initialize() { } else { std::cout << " ###### error: detector " << m_detector << " not found !" << std::endl; } + + if (m_isHadShower == true) { + if (cal_had) { + for (auto l_had : cal_had->layers) { + m_caloLayerDistances.push_back((l_had.distance + l_had.inner_thickness) / dd4hep::mm); + } + } + } } int PolyhedraBarrelGeometry::phiSector(G4ThreeVector const& position) const { From a58fd8adeae4032d2faffb1ab2ef4c8bed2c1bfe Mon Sep 17 00:00:00 2001 From: Peter McKeown Date: Tue, 19 Nov 2024 22:59:33 +0100 Subject: [PATCH 02/36] Loading and placement in ECAL successful, pending correct placement in HCAL --- include/DDML/PolyhedraBarrelGeometry.h | 6 +++++- scripts/ddsim_steer.py | 30 +++++++++++++++----------- scripts/test_onnx.mac | 6 +++--- src/CMakeLists.txt | 2 ++ src/LoadHdf5.cc | 21 +++++++++++++----- src/MLModelActions.cc | 16 ++++++++++++++ src/PolyhedraBarrelGeometry.cc | 12 +++++------ 7 files changed, 65 insertions(+), 28 deletions(-) diff --git a/include/DDML/PolyhedraBarrelGeometry.h b/include/DDML/PolyhedraBarrelGeometry.h index 8dbce2b..6a23c1b 100644 --- a/include/DDML/PolyhedraBarrelGeometry.h +++ b/include/DDML/PolyhedraBarrelGeometry.h @@ -27,7 +27,8 @@ class PolyhedraBarrelGeometry : public GeometryInterface { /// declare the proerties needed for the plugin void declareProperties(dd4hep::sim::Geant4Action* plugin) { - plugin->declareProperty("isHadShower", m_isHadShower) plugin->declareProperty("Detector", this->m_detector); + plugin->declareProperty("Detector", this->m_detector); + plugin->declareProperty("isHadShower", this->m_isHadShower); plugin->declareProperty("HadDetector", this->m_HadDetector); plugin->declareProperty("Symmetry", this->m_nSymmetry); plugin->declareProperty("HadSymmetry", this->m_nHadSymmetry); @@ -54,6 +55,9 @@ class PolyhedraBarrelGeometry : public GeometryInterface { std::string m_detector = {"EcalBarrel"}; int m_nSymmetry = 8; bool m_correctForAngles = false; + bool m_isHadShower = false; + std::string m_HadDetector = {"HcalBarrel"}; + int m_nHadSymmetry = m_nSymmetry; }; } // namespace ddml diff --git a/scripts/ddsim_steer.py b/scripts/ddsim_steer.py index 5a7ec2b..71b192e 100644 --- a/scripts/ddsim_steer.py +++ b/scripts/ddsim_steer.py @@ -546,7 +546,8 @@ def LoadHdf5(kernel): ml_correct_angles = False if hadrons == True: - ml_model_had = "LoadHDF5HadronPointCloudModelPolyhedraBarrel/BarrelModelTorch" + ml_model_had = "LoadHDF5PionCloudsPCHadronModelPolyhedraBarrel/BarrelModelTorch" + ml_had_file = "../models/PionClouds_50GeV_sp.h5" ml_correct_angles = False from g4units import GeV, MeV # DO NOT REMOVE OR MOVE!!!!! (EXCLAMATION MARK) @@ -620,24 +621,27 @@ def LoadHdf5(kernel): # ------------------- ## Hadrons in Barrel - modelHad1 = DetectorConstruction(kernel, str()) + modelHad1 = DetectorConstruction(kernel, str(ml_model_had)) ## # Mandatory model parameters - model.isHadShower = True - model.RegionName = "EcalBarrelRegion" ## hadron model triggers in ecal - model.Detector = ml_barrel_name - model.HadDetector = ml_had_barrel_name - model.Symmetry = ml_barrel_symmetry - model.HadSymmetry = ml_had_barrel_symmetry - model.Enable = True - model.CorrectForAngles = ml_correct_angles + modelHad1.isHadShower = True + modelHad1.RegionName = "EcalBarrelRegion" ## hadron model triggers in ecal + modelHad1.Detector = ml_barrel_name + modelHad1.HadDetector = ml_had_barrel_name + modelHad1.Symmetry = ml_barrel_symmetry + modelHad1.HadSymmetry = ml_had_barrel_symmetry + modelHad1.Enable = True + modelHad1.CorrectForAngles = ml_correct_angles # Energy boundaries are optional: Units are GeV - model.ApplicableParticles = {"pi+"} - model.Etrigger = {"pi+": 10.0 * GeV} # trigger on lower training threshold - model.FilePath = ml_file + modelHad1.ApplicableParticles = {"pi+"} + modelHad1.Etrigger = {"pi+": 10.0 * GeV} # trigger on lower training threshold + modelHad1.FilePath = ml_had_file # model.OptimizeFlag = 1 # model.IntraOpNumThreads = 1 + modelHad1.enableUI() + seq.adopt(modelHad1) + # ------------------- # Now build the physics list: diff --git a/scripts/test_onnx.mac b/scripts/test_onnx.mac index b7a22b4..10f6964 100644 --- a/scripts/test_onnx.mac +++ b/scripts/test_onnx.mac @@ -4,12 +4,12 @@ # --- the particle gun /gps/pos/centre 0 0 0 -/gps/particle gamma -#/gps/particle pi- +#/gps/particle gamma +/gps/particle pi+ /gps/energy 50 GeV # for SimpleCalo -/gps/direction -0.4152 1 0 #(pi/8 + pi/4) #1 0.414213562 0 #(pi/8) #-1 2.414213562 0 #(pi/8 + 1 deg) # 0.25 0.25 0.5 #0 0.5 0.655 # ( 37 deg in theta- most you can get in endcap from IP ) +/gps/direction 0 1 0 #-0.4152 1 0 #(pi/8 + pi/4) #1 0.414213562 0 #(pi/8) #-1 2.414213562 0 #(pi/8 + 1 deg) # 0.25 0.25 0.5 #0 0.5 0.655 # ( 37 deg in theta- most you can get in endcap from IP ) # phi barrel #1 0.414213562 0 #(pi/8) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b56fb29..2882c79 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -7,6 +7,7 @@ set(sources Par04ExampleVAE.cc RegularGridBIBAEModel.cc RegularGridTwoAngleBIBAEModel.cc + PionCloudsModel.cc OctogonalBarrelTrigger.cc EndcapTriggerTwoAngleBIBAE.cc CaloCloudsTwoAngleModel.cc @@ -82,6 +83,7 @@ set(headers ${PROJECT_SOURCE_DIR}/include/DDML/Par04ExampleVAE.h ${PROJECT_SOURCE_DIR}/include/DDML/RegularGridBIBAEModel.h ${PROJECT_SOURCE_DIR}/include/DDML/RegularGridTwoAngleBIBAEModel.h + ${PROJECT_SOURCE_DIR}/include/DDML/PionCloudsModel.h ${PROJECT_SOURCE_DIR}/include/DDML/PolyhedraBarrelGeometry.h ${PROJECT_SOURCE_DIR}/include/DDML/ModelInterface.h ${PROJECT_SOURCE_DIR}/include/DDML/InferenceInterface.h diff --git a/src/LoadHdf5.cc b/src/LoadHdf5.cc index 7bfebe1..2cb8360 100644 --- a/src/LoadHdf5.cc +++ b/src/LoadHdf5.cc @@ -19,7 +19,7 @@ void LoadHdf5::initialize() { // inputs and TensorDimVecs unused // Open dataset + dataspace - std::string datasetName = "layers"; + std::string datasetName = "spase_points"; //"layers"; H5::DataSet dataset = m_file.openDataSet(datasetName); dd4hep::printout(dd4hep::DEBUG, "LoadHdf5::initialize", "Accessed HDF5 dataset"); H5::DataSpace dataspace = dataset.getSpace(); @@ -39,10 +39,15 @@ void LoadHdf5::initialize() { m_dimsOut = dims_out; - assert(rank == 4); // assuming 4 dimensional input +// assert(rank == 4); // assuming 4 dimensional input // index 0: shower number // index 1, 2, 3: x, y, z cell number + assert(rank == 3); // assuming 3 dimensional PionCloud input + // index 0: shower number + // index 1: number of points + // index 2: 4 point dimensions (x, y, z, E) - currently in ILD coordinates + dd4hep::printout(dd4hep::DEBUG, "LoadHdf5::initialize", "Rank %i", rank); for (int i = 0, N = rank; i < N; ++i) { @@ -80,11 +85,17 @@ void LoadHdf5::runInference(const InputVecs&, const TensorDimVecs&, std::vector< } // select shower from library - std::vector shower(m_library.begin() + m_count * m_dimsOut[1] * m_dimsOut[2] * m_dimsOut[3], - m_library.begin() + (m_count + 1) * m_dimsOut[1] * m_dimsOut[2] * m_dimsOut[3]); + //std::vector shower(m_library.begin() + m_count * m_dimsOut[1] * m_dimsOut[2] * m_dimsOut[3], + // m_library.begin() + (m_count + 1) * m_dimsOut[1] * m_dimsOut[2] * m_dimsOut[3]); + + // select shower from library + std::vector shower(m_library.begin() + m_count * m_dimsOut[1] * m_dimsOut[2], + m_library.begin() + (m_count + 1) * m_dimsOut[1] * m_dimsOut[2]); // enforce length of shower - assert(shower.size() == m_dimsOut[1] * m_dimsOut[2] * m_dimsOut[3]); + //assert(shower.size() == m_dimsOut[1] * m_dimsOut[2] * m_dimsOut[3]); + + assert(shower.size() == m_dimsOut[1] * m_dimsOut[2]); // write output output = std::move(shower); diff --git a/src/MLModelActions.cc b/src/MLModelActions.cc index ab56dd1..5e88b6b 100644 --- a/src/MLModelActions.cc +++ b/src/MLModelActions.cc @@ -25,6 +25,7 @@ #include "DDML/RegularGridBIBAEModel.h" #include "DDML/RegularGridGANModel.h" #include "DDML/RegularGridTwoAngleBIBAEModel.h" +#include "DDML/PionCloudsModel.h" #include "DDML/TriggerInterface.h" namespace ddml { @@ -127,8 +128,21 @@ typedef FastMLShower< FastMLModel> // add ML trigger LoadHDF5RegularGridTwoAngleBIBAEModelEndcap; + +/// Load from HDF5 file- as an example for Hadron showers from PionClouds +// Barrel +typedef FastMLShower> // add ML trigger + LoadHDF5PionCloudsPCHadronModelPolyhedraBarrel; +// Endcap // ENDCAP IS CURRENTLY NOT IMPLEMENTED!!!! +typedef FastMLShower< + FastMLModel> // add ML trigger + LoadHDF5PionCloudsPCHadronModelEndcap; #endif + } // namespace ddml #include @@ -156,4 +170,6 @@ DECLARE_GEANT4ACTION_NS(ddml, L2LFlowsModelEndcapTorchModel) #ifdef DDML_USE_LOAD_HDF5 DECLARE_GEANT4ACTION_NS(ddml, LoadHDF5RegularGridTwoAngleBIBAEModelPolyhedraBarrel) DECLARE_GEANT4ACTION_NS(ddml, LoadHDF5RegularGridTwoAngleBIBAEModelEndcap) +DECLARE_GEANT4ACTION_NS(ddml, LoadHDF5PionCloudsPCHadronModelPolyhedraBarrel) +DECLARE_GEANT4ACTION_NS(ddml, LoadHDF5PionCloudsPCHadronModelEndcap) #endif diff --git a/src/PolyhedraBarrelGeometry.cc b/src/PolyhedraBarrelGeometry.cc index f7f4f6a..829ddb0 100644 --- a/src/PolyhedraBarrelGeometry.cc +++ b/src/PolyhedraBarrelGeometry.cc @@ -16,12 +16,6 @@ void PolyhedraBarrelGeometry::initialize() { auto det = theDetector.detector(m_detector); auto* cal = det.extension(); - // For hadronic shower simulation - if (m_isHadShower == true) { - auto det_had = theDetector.detector(m_HadDetector); - auto* cal_had = det_had.extension(); - } - if (cal) { for (auto l : cal->layers) { m_caloLayerDistances.push_back((l.distance + l.inner_thickness) / dd4hep::mm); @@ -30,12 +24,18 @@ void PolyhedraBarrelGeometry::initialize() { std::cout << " ###### error: detector " << m_detector << " not found !" << std::endl; } + // For hadronic shower simulation if (m_isHadShower == true) { + auto det_had = theDetector.detector(m_HadDetector); + auto* cal_had = det_had.extension(); if (cal_had) { for (auto l_had : cal_had->layers) { m_caloLayerDistances.push_back((l_had.distance + l_had.inner_thickness) / dd4hep::mm); } } + else { + std::cout << " ###### error: detector " << m_HadDetector << " not found !" << std::endl; + } } } From 424f0a4e75cc02df7831b8247075e568db6cf38a Mon Sep 17 00:00:00 2001 From: Peter McKeown Date: Mon, 17 Feb 2025 17:25:38 +0100 Subject: [PATCH 03/36] Working implmentation of hadron shower loading --- include/DDML/PionCloudsModel.h | 74 +++++++++++++ include/DDML/PolyhedraBarrelGeometry.h | 7 +- scripts/ddsim_steer.py | 4 +- scripts/test_onnx.mac | 4 +- src/Geant4FastHitMakerGlobal.cc | 7 ++ src/PionCloudsModel.cc | 142 +++++++++++++++++++++++++ src/PolyhedraBarrelGeometry.cc | 8 ++ 7 files changed, 242 insertions(+), 4 deletions(-) create mode 100644 include/DDML/PionCloudsModel.h create mode 100644 src/PionCloudsModel.cc diff --git a/include/DDML/PionCloudsModel.h b/include/DDML/PionCloudsModel.h new file mode 100644 index 0000000..0bb9bfc --- /dev/null +++ b/include/DDML/PionCloudsModel.h @@ -0,0 +1,74 @@ +#ifndef PionClouds_H +#define PionClouds_H + +#include "DDML/ModelInterface.h" +#include "DDML/FastMLShower.h" + + +namespace ddml { + +/** Class for running a point cloud based ML model for fast shower simulation. + * Assumes a cartesian (x,y) coordinates defining the calorimeter planes (layers) and z the depth + * of the calorimeter. + * + * Based on BiBAETwoAngleModel. + * + * Implemented here for the PionClouds model intended for hadron shower simulation (ECAL+HCAL). + * + * @author A.Korol, DESY + * @author P. McKeown, CERN + * @date Feb. 2025 + */ + + class PionCloudsModel : public ModelInterface { + + public: + PionCloudsModel() {} ; + + virtual ~PionCloudsModel(){}; + + /// declare the proerties needed for the plugin + void declareProperties(dd4hep::sim::Geant4Action* plugin) { + plugin->declareProperty("LatentVectorSize", this->m_latentSize); + } + + /** prepare the input vector and resize the output vector for this model + * based on the current FastTrack (e.g. extract kinetic energy and incident + * angles.) + */ + virtual void prepareInput(G4FastTrack const& aFastTrack, + G4ThreeVector const& localDir, + InputVecs& inputs, TensorDimVecs& tensDims, + std::vector& output ) ; + + + /** create a vector of spacepoints per layer interpreting the model output + */ + virtual void convertOutput(G4FastTrack const& aFastTrack, + G4ThreeVector const& localDir, + const std::vector& output, + std::vector& spacepoints ) ; + + + + private: + + /// model properties for plugin + // These grid sizes were used for the two angle BIBAE + int m_numPoints = 2600; + int m_latentSize = 3; // number of input features (energy, theta, phi) + int m_maxNumElements = m_numPoints*4; // number of space points in the output multiplied by 4 (x,y,z,energy) + int m_nLayer = 78; + + struct Vector3d{double x; double y; double z;}; + + Vector3d crossProduct(const Vector3d& v1, const Vector3d& v2); + + Vector3d normalize(const Vector3d& v); + + TensorDimVecs m_tensDims = {{1, 1}, {1, 1}, {1, 1}, {1, 3}}; + }; + +} // namespace ddml +#endif + diff --git a/include/DDML/PolyhedraBarrelGeometry.h b/include/DDML/PolyhedraBarrelGeometry.h index 6a23c1b..aa8cedb 100644 --- a/include/DDML/PolyhedraBarrelGeometry.h +++ b/include/DDML/PolyhedraBarrelGeometry.h @@ -12,6 +12,11 @@ namespace ddml { * * @author F.Gaede, DESY * @date Mar 2023 + * + * Addiional option included to support Hadronic shower simulation in ECAL + HCAL + * @author P. McKeown, CERN + * @date Feb 2025 + * */ class PolyhedraBarrelGeometry : public GeometryInterface { @@ -55,7 +60,7 @@ class PolyhedraBarrelGeometry : public GeometryInterface { std::string m_detector = {"EcalBarrel"}; int m_nSymmetry = 8; bool m_correctForAngles = false; - bool m_isHadShower = false; + bool m_isHadShower = true; std::string m_HadDetector = {"HcalBarrel"}; int m_nHadSymmetry = m_nSymmetry; }; diff --git a/scripts/ddsim_steer.py b/scripts/ddsim_steer.py index 71b192e..23450fb 100644 --- a/scripts/ddsim_steer.py +++ b/scripts/ddsim_steer.py @@ -574,6 +574,7 @@ def LoadHdf5(kernel): seq.adopt(sensitives) # ----------------- + ''' ## EM in Barrel model = DetectorConstruction(kernel, str(ml_model)) @@ -596,6 +597,7 @@ def LoadHdf5(kernel): model.enableUI() seq.adopt(model) + ''' # ------------------- ## EM in Endcap model1 = DetectorConstruction(kernel, str(ml_model_1)) @@ -625,7 +627,7 @@ def LoadHdf5(kernel): ## # Mandatory model parameters modelHad1.isHadShower = True - modelHad1.RegionName = "EcalBarrelRegion" ## hadron model triggers in ecal + modelHad1.RegionName = "EcalBarrelRegion" #or "HcalBarrelRegion" ## hadron model triggers in ecal modelHad1.Detector = ml_barrel_name modelHad1.HadDetector = ml_had_barrel_name modelHad1.Symmetry = ml_barrel_symmetry diff --git a/scripts/test_onnx.mac b/scripts/test_onnx.mac index 10f6964..3d5a716 100644 --- a/scripts/test_onnx.mac +++ b/scripts/test_onnx.mac @@ -3,7 +3,7 @@ # example script to run inference on a GAN w/ ONNX runtime # --- the particle gun -/gps/pos/centre 0 0 0 +/gps/pos/centre 30 180.48 0 #120 180.48 120 #30 180.48 0 #30 0 0 #/gps/particle gamma /gps/particle pi+ /gps/energy 50 GeV @@ -64,5 +64,5 @@ #/gps/direction 0.1 -0.8 .1 -/run/beamOn 10 #100 +/run/beamOn 2000 #100 diff --git a/src/Geant4FastHitMakerGlobal.cc b/src/Geant4FastHitMakerGlobal.cc index 9740761..bd7108f 100644 --- a/src/Geant4FastHitMakerGlobal.cc +++ b/src/Geant4FastHitMakerGlobal.cc @@ -48,6 +48,9 @@ Geant4FastHitMakerGlobal::~Geant4FastHitMakerGlobal() { //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... void Geant4FastHitMakerGlobal::make(const G4FastHit& aHit, const G4FastTrack& aTrack) { + + std::cout << "Geant4FastHitMakerGlobal::make - aHit.GetPosition().x() " << aHit.GetPosition().x() << " aHit.GetPosition().y() " << + aHit.GetPosition().y() << " aHit.GetPosition().z() " << aHit.GetPosition().z() << std::endl; // do not make empty deposit if (aHit.GetEnergy() <= 0) { return; @@ -80,9 +83,13 @@ void Geant4FastHitMakerGlobal::make(const G4FastHit& aHit, const G4FastTrack& aT G4VSensitiveDetector* sensitive; if (currentVolume != 0) { + //std::cout << "IN FULL Sim Sensitive Geant4FastHitMakerGlobal::make - aHit.GetPosition().x() " << aHit.GetPosition().x() << " aHit.GetPosition().y() " << + // aHit.GetPosition().y() << " aHit.GetPosition().z() " << aHit.GetPosition().z() << " Energy: " << aHit.GetEnergy() << std::endl; sensitive = currentVolume->GetLogicalVolume()->GetSensitiveDetector(); G4VFastSimSensitiveDetector* fastSimSensitive = dynamic_cast(sensitive); if (fastSimSensitive) { + std::cout << "IN FAST Sim Sensitive Geant4FastHitMakerGlobal::make - aHit.GetPosition().x() " << aHit.GetPosition().x() << " aHit.GetPosition().y() " << + aHit.GetPosition().y() << " aHit.GetPosition().z() " << aHit.GetPosition().z() << " Energy: " << aHit.GetEnergy() << std::endl; fastSimSensitive->Hit(&aHit, &aTrack, &m_touchableHandle); } else if (sensitive && currentVolume->GetLogicalVolume()->GetFastSimulationManager()) { G4cerr << "ERROR - Geant4FastHitMakerGlobal::make()" << G4endl << " It is required to derive from the " diff --git a/src/PionCloudsModel.cc b/src/PionCloudsModel.cc new file mode 100644 index 0000000..6b04e9e --- /dev/null +++ b/src/PionCloudsModel.cc @@ -0,0 +1,142 @@ +#include "DDML/PionCloudsModel.h" + +#include // for G4FastTrack + +//#include + +#define DEBUGPRINT 0 + +namespace ddml { + + void PionCloudsModel::prepareInput(G4FastTrack const& aFastTrack, + G4ThreeVector const& localDir, + InputVecs& inputs, TensorDimVecs& tensDims, + std::vector& output ) { + + tensDims = m_tensDims; + + G4double energy = aFastTrack.GetPrimaryTrack()->GetKineticEnergy(); + + G4ThreeVector direction = aFastTrack.GetPrimaryTrack()->GetMomentumDirection(); + G4RotationMatrix rotZ; + rotZ.rotateZ(M_PI / 2.); + G4RotationMatrix rotX; + rotX.rotateX(M_PI / 2.); + // this convention is used for the local coordinates in the dataset (model was trained in this convention) + // G4ThreeVector localDir_ = rotZ * (rotX * direction) ; + + G4ThreeVector localDir_ = localDir; + localDir_.setX(-1. * localDir_.x()); // *(-1) to align local to global convention in ddml + localDir_.setY(-1. * localDir_.y()); // *(-1) to align local to global convention in ddml + + dd4hep::printout(dd4hep::DEBUG, "PionCloudsModel::prepareInput", "DDML::localDir: (%f, %f, %f)", + localDir_.x(), localDir_.y(), localDir_.z()); + // std::cout << "PionClouds::localDir:" << "(" << localDir_.x() << "," << localDir_.y() << "," << localDir_.z() << ")" + // << std::endl; + + // compute local incident angles + double r = sqrt(localDir_.x() * localDir_.x() + localDir_.y() * localDir_.y() + localDir_.z() * localDir_.z()); + double theta = acos(localDir_.z() / r) / M_PI * 180.; + double phi = atan2(localDir_.y(), localDir_.x()) / M_PI * 180.; + + dd4hep::printout(dd4hep::DEBUG, "PionCloudsModel::prepareInput", "DDML::localDir: (%f, %f)", theta, phi); + // std::cout << "PionClouds::localDir:" << " theta = " << theta << " phi = " << phi << std::endl; + + // the input for the PionClouds is one energy and two angles (local Theta and Phi) + inputs.resize(m_latentSize); + + inputs[0].resize(1); // Energy + inputs[1].resize(1); // Theta + inputs[2].resize(1); // Phi + + // For now, assume batch size one, and just assign values + inputs[0][0] = energy / CLHEP::GeV; // E_vec[0]/100.; + inputs[1][0] = theta; // 89.*(M_PI/180.) ; //Theta_vec[0]/(90.*(M_PI/180.)); + inputs[2][0] = phi; + + // if (DEBUGPRINT) { + // std::cout << " Input_energy_tensor : " << inputs[0][0] << std::endl; + // std::cout << " Input_theta_tensor : " << inputs[1][0] << std::endl; + // std::cout << " Input_phi_tensor : " << inputs[2][0] << std::endl; + // } + + dd4hep::printout(dd4hep::DEBUG, "PionCloudsModel::prepareInput", "Input_energy_tensor : %f", inputs[0][0]); + dd4hep::printout(dd4hep::DEBUG, "PionCloudsModel::prepareInput", "Input_theta_tensor : %f", inputs[1][0]); + dd4hep::printout(dd4hep::DEBUG, "PionCloudsModel::prepareInput", "Input_phi_tensor : %f", inputs[2][0]); + + // ---- resize output vector + + output.assign(m_maxNumElements, 0); +} + + + + void PionCloudsModel::convertOutput(G4FastTrack const& aFastTrack, + G4ThreeVector const& localDir, + const std::vector& output, + std::vector& spacepoints ){ + + int nPoints = m_numPoints ; // number of points in shower + + dd4hep::printout(dd4hep::DEBUG, "PionCloudsModel::convertOutput", "m_numPoints : %i", m_numPoints); + + spacepoints.resize( m_nLayer ) ; + + int numSP = 0; + int layerNum = 0; + int numElements = 0; + for (int i = 0; i < m_nLayer; i++) { + numSP = output[i] + 1; + spacepoints[i].reserve(numSP); + numElements += output[i] * 4; + } + + std::cout << " PionCloudsModel::convertOutput DONE numElements, numElements = " << numElements << std::endl; + + /* + for (int i = m_nLayer; i < m_nLayer + numElements; i += 4) { + std::cout << " PionCloudsModel::convertOutput Layer Loop, i = " << i << std::endl; + std::cout << " PionCloudsModel::convertOutput Layer Loop, output[i] " << output[i] << std::endl; + std::cout << " PionCloudsModel::convertOutput Layer Loop, output[i+1] " << output[i] << std::endl; + std::cout << " PionCloudsModel::convertOutput Layer Loop, output[i+3] " << output[i] << std::endl; + ddml::SpacePoint sp( + output[i], // x // *(-1) to align local to global convention in ddml + output[i+1], // y // *(-1) to align local to global convention in ddml + 0., // z + output[i+3], // energy + 0. // time + ); + layerNum = output[i+2]; + std::cout << " PionCloudsModel::convertOutput Layer Loop, layerNum " << layerNum << std::endl; + spacepoints[layerNum].emplace_back( sp ) ; + */ + + + float reshaped[2600][4]; + + // Fill the 3D array using the flattened vector + size_t index = 0; + for (size_t j = 0; j < 2600; ++j) { + for (size_t k = 0; k < 4; ++k) { + reshaped[j][k] = output[index++]; + } + } + + for (int i = 0; i < nPoints; i++) { + ddml::SpacePoint sp( + reshaped[i][0]*1e3, // x // *(-1) to align local to global convention in ddml + reshaped[i][2]*1e3, // y // *(-1) to align local to global convention in ddml + 0., // z + reshaped[i][3], // energy + 0. // time + ); + layerNum = reshaped[i][1]; + std::cout << "PionCloudsModel::convertOutput - layerNum" << layerNum <layers) { m_caloLayerDistances.push_back((l.distance + l.inner_thickness) / dd4hep::mm); + std::cout << " ECAL Layer distances " << l.distance + l.inner_thickness << std::endl; } } else { std::cout << " ###### error: detector " << m_detector << " not found !" << std::endl; @@ -31,6 +32,7 @@ void PolyhedraBarrelGeometry::initialize() { if (cal_had) { for (auto l_had : cal_had->layers) { m_caloLayerDistances.push_back((l_had.distance + l_had.inner_thickness) / dd4hep::mm); + std::cout << " HCAL Layer distances " << l_had.distance + l_had.inner_thickness << std::endl; } } else { @@ -138,6 +140,8 @@ void PolyhedraBarrelGeometry::localToGlobal(G4FastTrack const& aFastTrack, int firstLayer = 0; int nLayer = m_caloLayerDistances.size(); + std::cout << " PolyhedraBarrelGeometry::localToGlobal nLayer " << nLayer << std::endl; + for (int l = 0; l < nLayer; ++l) { double r = m_caloLayerDistances[l]; firstLayer = l; @@ -181,6 +185,10 @@ void PolyhedraBarrelGeometry::localToGlobal(G4FastTrack const& aFastTrack, sp.X = global.x(); sp.Y = global.y(); sp.Z = global.z(); + + std::cout << " PolyhedraBarrelGeometry::localToGlobal - global.x() = " << global.x() << " global.y() = " << global.y() + << " global.z() " << global.z() << " Energy: " << sp.E << std::endl; + } } } From dc199587fed34864759333cf47b9c0acbd4ceef2 Mon Sep 17 00:00:00 2001 From: Peter McKeown Date: Wed, 19 Feb 2025 09:30:31 +0100 Subject: [PATCH 04/36] Add option to record information about MC particle entry into calorimter --- CMakeLists.txt | 2 + include/DDML/DDMLEventAction.h | 70 +++ include/DDML/DDMLRunAction.h | 39 ++ include/DDML/FastMLShower.h | 45 ++ scripts/ddsim_steer.py | 2 +- scripts/ddsim_steer_Record_Calo_entry.py | 656 +++++++++++++++++++++++ scripts/test_onnx.mac | 4 +- src/CMakeLists.txt | 16 + src/DDMLEventAction.cc | 58 ++ src/DDMLRunAction.cc | 94 ++++ src/PionCloudsModel.cc | 4 +- 11 files changed, 985 insertions(+), 5 deletions(-) create mode 100644 include/DDML/DDMLEventAction.h create mode 100644 include/DDML/DDMLRunAction.h create mode 100644 scripts/ddsim_steer_Record_Calo_entry.py create mode 100644 src/DDMLEventAction.cc create mode 100644 src/DDMLRunAction.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index d6dceb3..2b58d4b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,6 +58,8 @@ endif() option(INSTRUMENT_MODEL "Instrument the steps of the showerModel call" OFF) +option(RECORD_CALO_IMPACT "Record properties of particle that triggers modelShower call" OFF) + option(DOWNLOAD_MODELS "Download and install the models that are stored externally" ON) #--------------------------------------------------- diff --git a/include/DDML/DDMLEventAction.h b/include/DDML/DDMLEventAction.h new file mode 100644 index 0000000..1aa857c --- /dev/null +++ b/include/DDML/DDMLEventAction.h @@ -0,0 +1,70 @@ +#include // for G4int, G4double +#include // for vector +#include "G4UserEventAction.hh" // for G4UserEventAction +//#include "G4Timer.hh" // for G4Timer +class G4Event; +#include "DDG4/Geant4Handle.h" +#include "DDG4/Geant4Kernel.h" +#include "DDG4/Geant4EventAction.h" +#include "CLHEP/Units/SystemOfUnits.h" +#include "CLHEP/Units/PhysicalConstants.h" + + +namespace ddml { + +/** Event action for ddml. +* +* @author P. McKeown, CERN +* @date Feb 2025 +* +*/ + +class DDMLEventAction: public dd4hep::sim::Geant4EventAction{ +public: + /// Standard constructor with initializing arguments + DDMLEventAction(dd4hep::sim::Geant4Context* c, const std::string& n); + /// Default destructor + virtual ~DDMLEventAction(); + /// begin-of-event callback + inline virtual void begin(const G4Event*) override; + /// End-of-event callback + virtual void end(const G4Event*) override; + /// begin-of-run callback + void beginRun(const G4Run*); + /// End-of-run callback + void endRun(const G4Run*); + + //// Get and Set methods for Calo Face info + inline std::vector& GetCaloMC_PDG() {return m_CaloMCPDG;} + inline std::vector& GetCaloMC_E() {return m_CaloMCE;} + inline std::vector& GetCaloMC_PosX() {return m_CaloMCPosX;} + inline std::vector& GetCaloMC_PosY() {return m_CaloMCPosY;} + inline std::vector& GetCaloMC_PosZ() {return m_CaloMCPosZ;} + inline std::vector& GetCaloMC_DirX() {return m_CaloMCDirX;} + inline std::vector& GetCaloMC_DirY() {return m_CaloMCDirY;} + inline std::vector& GetCaloMC_DirZ() {return m_CaloMCDirZ;} + + // Set methods to push back vector + inline void SetElCaloMC_PDG(G4int aValue) {m_CaloMCPDG.push_back(aValue);} + inline void SetElCaloMC_E(G4double aValue) {m_CaloMCE.push_back(aValue);} + inline void SetElCaloMC_PosX(G4double aValue) {m_CaloMCPosX.push_back(aValue);} + inline void SetElCaloMC_PosY(G4double aValue) {m_CaloMCPosY.push_back(aValue);} + inline void SetElCaloMC_PosZ(G4double aValue) {m_CaloMCPosZ.push_back(aValue);} + inline void SetElCaloMC_DirX(G4double aValue) {m_CaloMCDirX.push_back(aValue);} + inline void SetElCaloMC_DirY(G4double aValue) {m_CaloMCDirY.push_back(aValue);} + inline void SetElCaloMC_DirZ(G4double aValue) {m_CaloMCDirZ.push_back(aValue);} + +private: + // Fast Sim Calo entrace particle properties to store in ntuple + std::vector m_CaloMCPDG; + std::vector m_CaloMCE; + std::vector m_CaloMCPosX; + std::vector m_CaloMCPosY; + std::vector m_CaloMCPosZ; + std::vector m_CaloMCDirX; + std::vector m_CaloMCDirY; + std::vector m_CaloMCDirZ; +}; + +} //namespace + diff --git a/include/DDML/DDMLRunAction.h b/include/DDML/DDMLRunAction.h new file mode 100644 index 0000000..49c5dc6 --- /dev/null +++ b/include/DDML/DDMLRunAction.h @@ -0,0 +1,39 @@ +#include // for GeV +#include // for G4String +#include // for G4ThreeVector +#include // for G4int +//#include "G4Timer.hh" // for G4Timer +class G4ParticleDefinition; +#include "DDG4/Geant4Handle.h" +#include "DDG4/Geant4Kernel.h" +#include "DDG4/Geant4RunAction.h" + + + +namespace ddml{ +/* Create analysis files in standard G4 manner +* +* @author P. McKeown +* @date Feb 2025 +* +*/ + +class DDMLRunAction: public dd4hep::sim::Geant4RunAction { + public: + DDMLRunAction() = delete; + /// Standard constructor with initializing arguments + DDMLRunAction(dd4hep::sim::Geant4Context* c, const std::string& n) ; + /// Default destructor + virtual ~DDMLRunAction() ; + /// begin-of-run callback + void begin(const G4Run*) override; + /// End-of-run callback + void end(const G4Run*) override; + /// begin-of-event callback + void beginEvent(const G4Event*) ; + /// End-of-event callback + void endEvent(const G4Event*) ; + +}; + +} // namespace \ No newline at end of file diff --git a/include/DDML/FastMLShower.h b/include/DDML/FastMLShower.h index e48a35a..0615eb2 100644 --- a/include/DDML/FastMLShower.h +++ b/include/DDML/FastMLShower.h @@ -14,6 +14,10 @@ #define DDML_INSTRUMENT_MODEL_SHOWER 0 #endif +#ifndef DDML_RECORD_CALO_IMPACT + #define DDML_RECORD_CALO_IMPACT 0 +#endif + #if DDML_INSTRUMENT_MODEL_SHOWER #include "podio/Frame.h" #include "podio/ROOTFrameWriter.h" @@ -35,6 +39,12 @@ inline auto run_void_member_timed(Obj& obj, MemberFunc func, Args&&... args) { } #endif +#if DDML_RECORD_CALO_IMPACT + //#include "G4EventManager.hh" + //#include "DDML/DDMLEventAction.h" + #include "G4AnalysisManager.hh" +#endif + namespace ddml { /** The templated base class for running fast shower simulation with ML. * The actual implementation is provided by the templated class @@ -144,6 +154,41 @@ class FastMLShower : public dd4hep::sim::Geant4FastSimShowerModel { podio::UserDataCollection nHits; #endif +#if DDML_RECORD_CALO_IMPACT + // Create analysis manager + G4AnalysisManager* analysisManager = G4AnalysisManager::Instance(); + + // Store information about particle impact on calorimter face from track + G4int PDG = track.GetPrimaryTrack()->GetParticleDefinition()->GetPDGEncoding(); + G4ThreeVector position = track.GetPrimaryTrack()->GetPosition(); + G4ThreeVector direction = track.GetPrimaryTrack()->GetMomentumDirection(); + + // Fill analysis manager + analysisManager->FillNtupleIColumn(1, 0, PDG); + analysisManager->FillNtupleDColumn(1, 1, energy); + analysisManager->FillNtupleDColumn(1, 2, position.x()); + analysisManager->FillNtupleDColumn(1, 3, position.y()); + analysisManager->FillNtupleDColumn(1, 4, position.z()); + analysisManager->FillNtupleDColumn(1, 5, direction.x()); + analysisManager->FillNtupleDColumn(1, 6, direction.y()); + analysisManager->FillNtupleDColumn(1, 7, direction.z()); + + analysisManager->AddNtupleRow(1); + + /* + DDMLEventAction* mEventAction = dynamic_cast(G4EventManager::GetEventManager()->GetUserEventAction()); + mEventAction->SetElCaloMC_PDG(PDG); + mEventAction->SetElCaloMC_E(energy); + mEventAction->SetElCaloMC_PosX(position.x()); + mEventAction->SetElCaloMC_PosY(position.y()); + mEventAction->SetElCaloMC_PosZ(position.z()); + mEventAction->SetElCaloMC_DirX(direction.x()); + mEventAction->SetElCaloMC_DirY(direction.y()); + mEventAction->SetElCaloMC_DirZ(direction.z()); + */ + +#endif + for (auto& invec : m_input) { invec.clear(); } diff --git a/scripts/ddsim_steer.py b/scripts/ddsim_steer.py index 23450fb..9c7f8a0 100644 --- a/scripts/ddsim_steer.py +++ b/scripts/ddsim_steer.py @@ -547,7 +547,7 @@ def LoadHdf5(kernel): if hadrons == True: ml_model_had = "LoadHDF5PionCloudsPCHadronModelPolyhedraBarrel/BarrelModelTorch" - ml_had_file = "../models/PionClouds_50GeV_sp.h5" + ml_had_file = "../models/PionClouds_50GeV_sp.h5" #"../models/PionClouds_50GeV_sp_scaled.h5" ml_correct_angles = False from g4units import GeV, MeV # DO NOT REMOVE OR MOVE!!!!! (EXCLAMATION MARK) diff --git a/scripts/ddsim_steer_Record_Calo_entry.py b/scripts/ddsim_steer_Record_Calo_entry.py new file mode 100644 index 0000000..6107367 --- /dev/null +++ b/scripts/ddsim_steer_Record_Calo_entry.py @@ -0,0 +1,656 @@ +###################################################################### +# +# standard steering file for ILD simulation +# +# +# +###################################################################### +from DDSim.DD4hepSimulation import DD4hepSimulation +import DDG4 +from g4units import m, mm, GeV, MeV, rad +import os + +SIM = DD4hepSimulation() + +## The compact XML file +SIM.compactFile = "" +## Lorentz boost for the crossing angle, in radian! +SIM.crossingAngleBoost = 7.0e-3 * rad +SIM.enableDetailedShowerMode = True +SIM.enableG4GPS = True +SIM.enableG4Gun = False +SIM.enableGun = False +## InputFiles for simulation .stdhep, .slcio, .HEPEvt, .hepevt, .hepmc, .pairs files are supported +SIM.inputFiles = [] +## Macro file to execute for runType 'run' or 'vis' +SIM.macroFile = "./test_onnx.mac" +## number of events to simulate, used in batch mode +SIM.numberOfEvents = 100 +## Outputfile from the simulation,only lcio output is supported +# SIM.outputFile = "dummyOutput_edm4hep.root" ##"dummyOutput.slcio" +SIM.outputFile = "dummyOutput.slcio" + +## Physics list to use in simulation +SIM.physicsList = None +## Verbosity use integers from 1(most) to 7(least) verbose +## or strings: VERBOSE, DEBUG, INFO, WARNING, ERROR, FATAL, ALWAYS +SIM.printLevel = "INFO" +## The type of action to do in this invocation +## batch: just simulate some events, needs numberOfEvents, and input file or gun +## vis: enable visualisation, run the macroFile if it is set +## run: run the macroFile and exit +## shell: enable interactive session +SIM.runType = "run" # "batch" +## Skip first N events when reading a file +SIM.skipNEvents = 0 +## Steering file to change default behaviour +SIM.steeringFile = None +## FourVector of translation for the Smearing of the Vertex position: x y z t +SIM.vertexOffset = [0.0, 0.0, 0.0, 0.0] +## FourVector of the Sigma for the Smearing of the Vertex position: x y z t +SIM.vertexSigma = [0.0, 0.0, 0.0, 0.0] + + +################################################################################ +## Action holding sensitive detector actions +## The default tracker and calorimeter actions can be set with +## +## >>> SIM = DD4hepSimulation() +## >>> SIM.action.tracker = ('Geant4TrackerWeightedAction', {'HitPositionCombination': 2, 'CollectSingleDeposits': False}) +## >>> SIM.action.calo = "Geant4CalorimeterAction" +## +## for specific subdetectors specific sensitive detectors can be set based on pattern matching +## +## >>> SIM = DD4hepSimulation() +## >>> SIM.action.mapActions['tpc'] = "TPCSDAction" +## +## and additional parameters for the sensitive detectors can be set when the map is given a tuple +## +## >>> SIM = DD4hepSimulation() +## >>> SIM.action.mapActions['ecal'] =( "CaloPreShowerSDAction", {"FirstLayerNumber": 1} ) +## +## +################################################################################ + +## set the default calorimeter action +SIM.action.calo = "Geant4ScintillatorCalorimeterAction" + +## create a map of patterns and actions to be applied to sensitive detectors +## example: SIM.action.mapActions['tpc'] = "TPCSDAction" +SIM.action.mapActions = {} + +SIM.action.mapActions["tpc"] = "TPCSDAction" + +## set the default tracker action +SIM.action.tracker = ( + "Geant4TrackerWeightedAction", + {"HitPositionCombination": 2, "CollectSingleDeposits": False}, +) + +### Configure Run actions +kernel = DDG4.Kernel() +run1 = DDG4.RunAction(kernel, 'DDMLRunAction/runaction') +kernel.registerGlobalAction(run1) +kernel.runAction().add(run1) +event1 = DDG4.EventAction(kernel, 'DDMLEventAction/eventaction') +kernel.registerGlobalAction(event1) +kernel.eventAction().add(event1) + +################################################################################ +## Configuration for the magnetic field (stepper) +################################################################################ +## --- used in v01-19-05 : +SIM.field.delta_chord = 1e-05 +SIM.field.delta_intersection = 1e-05 +SIM.field.delta_one_step = 0.5e-03 * mm +SIM.field.eps_max = 1e-04 +SIM.field.eps_min = 1e-05 +SIM.field.equation = "Mag_UsualEqRhs" +SIM.field.largest_step = 10.0 * m +SIM.field.min_chord_step = 1.0e-2 * mm +SIM.field.stepper = "HelixSimpleRunge" + +## --- default values in ddsim +##SIM.field.delta_chord = 0.25 +##SIM.field.delta_intersection = 0.001 +##SIM.field.delta_one_step = 0.01 +##SIM.field.eps_max = 0.001 +##SIM.field.eps_min = 5e-05 +##SIM.field.equation = "Mag_UsualEqRhs" +##SIM.field.largest_step = 10000.0 +##SIM.field.min_chord_step = 0.01 +##SIM.field.stepper = "G4ClassicalRK4" + +################################################################################ +## Configuration for sensitive detector filters +## +## Set the default filter for tracker or caliromter +## >>> SIM.filter.tracker = "edep1kev" +## >>> SIM.filter.calo = "" +## +## Assign a filter to a sensitive detector via pattern matching +## >>> SIM.filter.mapDetFilter['FTD'] = "edep1kev" +## +## Or more than one filter: +## >>> SIM.filter.mapDetFilter['FTD'] = ["edep1kev", "geantino"] +## +## Don't use the default filter or anything else: +## >>> SIM.filter.mapDetFilter['TPC'] = None ## or "" or [] +## +## Create a custom filter. The dictionary is used to instantiate the filter later on +## >>> SIM.filter.filters['edep3kev'] = dict(name="EnergyDepositMinimumCut/3keV", parameter={"Cut": 3.0*keV} ) +## +## +################################################################################ + +## default filter for calorimeter sensitive detectors; this is applied if no other filter is used for a calorimeter +SIM.filter.calo = "edep0" + +## list of filter objects: map between name and parameter dictionary +SIM.filter.filters = { + "edep0": {"parameter": {"Cut": 0.0}, "name": "EnergyDepositMinimumCut/Cut0"}, + "geantino": {"parameter": {}, "name": "GeantinoRejectFilter/GeantinoRejector"}, + "edep1kev": {"parameter": {"Cut": 0.001}, "name": "EnergyDepositMinimumCut"}, +} + +## a map between patterns and filter objects, using patterns to attach filters to sensitive detector +SIM.filter.mapDetFilter = {} + +SIM.filter.mapDetFilter["TPC"] = None + +## default filter for tracking sensitive detectors; this is applied if no other filter is used for a tracker +SIM.filter.tracker = "edep1kev" + + +################################################################################ +## Configuration for the GuineaPig InputFiles +################################################################################ + +## Set the number of pair particles to simulate per event. +## Only used if inputFile ends with ".pairs" +## If "-1" all particles will be simulated in a single event +## +SIM.guineapig.particlesPerEvent = "-1" + + +################################################################################ +## Configuration for the DDG4 ParticleGun +################################################################################ + +## direction of the particle gun, 3 vector +SIM.gun.direction = (0, 0, 1) + +## choose the distribution of the random direction for theta +## +## Options for random distributions: +## +## 'uniform' is the default distribution, flat in theta +## 'cos(theta)' is flat in cos(theta) +## 'eta', or 'pseudorapidity' is flat in pseudorapity +## 'ffbar' is distributed according to 1+cos^2(theta) +## +## Setting a distribution will set isotrop = True +## +SIM.gun.distribution = None +SIM.gun.energy = 10000.0 + +## isotropic distribution for the particle gun +## +## use the options phiMin, phiMax, thetaMin, and thetaMax to limit the range of randomly distributed directions +## if one of these options is not None the random distribution will be set to True and cannot be turned off! +## +SIM.gun.isotrop = False +SIM.gun.multiplicity = 1 +SIM.gun.particle = "mu-" +SIM.gun.phiMax = None + +## Minimal azimuthal angle for random distribution +SIM.gun.phiMin = None + +## position of the particle gun, 3 vector +SIM.gun.position = (0.0, 0.0, 0.0) +SIM.gun.thetaMax = None +SIM.gun.thetaMin = None + + +################################################################################ +## Configuration for the output levels of DDG4 components +################################################################################ + +## Output level for input sources +SIM.output.inputStage = 3 + +## Output level for Geant4 kernel +SIM.output.kernel = 3 + +## Output level for ParticleHandler +SIM.output.part = 3 + +## Output level for Random Number Generator setup +SIM.output.random = 6 + + +################################################################################ +## Configuration for the Particle Handler/ MCTruth treatment +################################################################################ + +## Enable lots of printout on simulated hits and MC-truth information +SIM.part.enableDetailedHitsAndParticleInfo = False + +## Keep all created particles +SIM.part.keepAllParticles = False + +## Minimal distance between particle vertex and endpoint of parent after +## which the vertexIsNotEndpointOfParent flag is set +## +SIM.part.minDistToParentVertex = 2.2e-14 + +## MinimalKineticEnergy to store particles created in the tracking region +SIM.part.minimalKineticEnergy = 1 * MeV + +## Printout at End of Tracking +SIM.part.printEndTracking = False + +## Printout at Start of Tracking +SIM.part.printStartTracking = False + +## List of processes to save, on command line give as whitespace separated string in quotation marks +SIM.part.saveProcesses = ["Decay"] + + +################################################################################ +## Configuration for the PhysicsList +################################################################################ +# this needs to be set to False if any standard physics list is used: +SIM.physics.decays = False +SIM.physics.list = "QGSP_BERT" # "FTFP_BERT" + +## location of particle.tbl file containing extra particles and their lifetime information +## +SIM.physics.pdgfile = os.path.join( + os.environ.get("DD4HEP"), "DDG4/examples/particle.tbl" +) + +## The global geant4 rangecut for secondary production +## +## Default is 0.7 mm as is the case in geant4 10 +## +## To disable this plugin and be absolutely sure to use the Geant4 default range cut use "None" +## +## Set printlevel to DEBUG to see a printout of all range cuts, +## but this only works if range cut is not "None" +## +SIM.physics.rangecut = 0.1 * mm + + +################################################################################ +## Properties for the random number generator +################################################################################ + +## If True, calculate random seed for each event based on eventID and runID +## allows reproducibility even when SkippingEvents +SIM.random.enableEventSeed = True #False +SIM.random.file = None +SIM.random.luxury = 1 +SIM.random.replace_gRandom = True +SIM.random.seed = 42 #None +SIM.random.type = None + +# --------------------------------------------- +# +# Configure ML inference +# +# --------------------------------------------- + + +def aiDance(kernel): + ild = True + par04 = True # False + old_DD4hep = False ## use for DD4hep versions/commits before ~ Apr 21st 2023 + + if ild == True: + ml_barrel_name = "EcalBarrel" + ml_barrel_symmetry = 8 + ml_endcap_name = "EcalEndcap" + else: + ml_barrel_name = "ECalBarrel" + ml_barrel_symmetry = 12 + ml_endcap_name = "ECalEndcap" + + if par04 == True: + ml_file = "../models/Generator.onnx" + ml_model = "Par04ExampleVAEPolyhedraBarrelONNXModel/ShowerModel" + ml_model1 = "Par04ExampleVAEEndcapONNXModel/ShowerModel" + else: + ml_file = "../models/francisca_gan.onnx" + ml_model = "RegularGridGANPolyhedraBarrelONNXModel/ShowerModel" + ml_model1 = "RegularGridGANEndcapONNXModel/ShowerModel" + + ml_correct_angles = True + + from g4units import GeV, MeV # DO NOT REMOVE OR MOVE!!!!! (EXCLAMATION MARK) + from DDG4 import DetectorConstruction, Geant4, PhysicsList + + geant4 = Geant4(kernel) + seq = geant4.detectorConstruction() + + if old_DD4hep: # this is now done in DD4hepSimulations.py, i.e. in ddsim + seq, act = geant4.addDetectorConstruction( + "Geant4DetectorGeometryConstruction/ConstructGeo" + ) + act.DebugMaterials = True + act.DebugElements = False + act.DebugVolumes = True + act.DebugShapes = True + # Apply sensitive detectors + sensitives = DetectorConstruction( + kernel, str("Geant4DetectorSensitivesConstruction/ConstructSD") + ) + sensitives.enableUI() + seq.adopt(sensitives) + + # ----------------- + model = DetectorConstruction(kernel, str(ml_model)) + + ## # Mandatory model parameters + model.RegionName = "EcalBarrelRegion" + model.Detector = ml_barrel_name + model.Symmetry = ml_barrel_symmetry + model.Enable = True + model.CorrectForAngles = ml_correct_angles + # Energy boundaries are optional: Units are GeV + model.ApplicableParticles = {"e+", "e-", "gamma"} + model.Etrigger = {"e+": 5.0 * GeV, "e-": 5.0 * GeV, "gamma": 5.0 * GeV} + model.ModelPath = ml_file + model.OptimizeFlag = 1 + + model.enableUI() + seq.adopt(model) + # ------------------- + model1 = DetectorConstruction(kernel, str(ml_model1)) + + ## # Mandatory model parameters + model1.RegionName = "EcalEndcapRegion" + model1.Detector = ml_endcap_name + model1.Enable = True + model1.CorrectForAngles = ml_correct_angles + # Energy boundaries are optional: Units are GeV + model1.ApplicableParticles = {"e+", "e-", "gamma"} + model1.Etrigger = {"e+": 5.0 * GeV, "e-": 5.0 * GeV, "gamma": 5.0 * GeV} + model1.ModelPath = ml_file + model.OptimizeFlag = 1 + + model1.enableUI() + seq.adopt(model1) + # ------------------- + + # Now build the physics list: + phys = kernel.physicsList() + ph = PhysicsList(kernel, str("Geant4FastPhysics/FastPhysicsList")) + ph.EnabledParticles = ["e+", "e-", "gamma"] + ph.BeVerbose = True + ph.enableUI() + phys.adopt(ph) + phys.dump() + + +def aiDanceTorch(kernel): + ild = True + BIBAE = True + Two_Angle = True #True + old_DD4hep = False ## use for DD4hep versions/commits before ~ Apr 21st 2023 + + if ild == True: + ml_barrel_name = "EcalBarrel" + ml_barrel_symmetry = 8 + ml_endcap_name = "EcalEndcap" + else: + ml_barrel_name = "ECalBarrel" + ml_barrel_symmetry = 12 + ml_endcap_name = "ECalEndcap" + + if BIBAE == True and Two_Angle == False: + ml_file = "../models/BIBAE_Full_PP_cut.pt" + ml_model = "RegularGridBIBAEPolyhedraBarrelTorchModel/BarrelModelTorch" + ml_model_1 = "RegularGridBIBAEEndcapTorchModel/EndcapModelTorch" + ml_correct_angles = False + elif BIBAE == True and Two_Angle == True: + ml_file = "../models/BIBAE_Two_Angle_Full_PP_cut.pt" + ml_model = ( + "RegularGridTwoAngleBIBAEModelPolyhedraBarrelTorchModel/BarrelModelTorch" + ) + ml_model_1 = "RegularGridTwoAngleBIBAEModelEndcapTorchModel/EndcapModelTorch" + ml_correct_angles = False + else: + ml_file = "../models/francisca_gan_jit.pt" + ml_model = "RegularGridGANPolyhedraBarrelTorchModel/BarrelModelTorch" + ml_model_1 = "RegularGridGANEndcapTorchModel/EndcapModelTorch" + ml_correct_angles = True + + from g4units import GeV, MeV # DO NOT REMOVE OR MOVE!!!!! (EXCLAMATION MARK) + from DDG4 import DetectorConstruction, Geant4, PhysicsList + + geant4 = Geant4(kernel) + + seq = geant4.detectorConstruction() + + if old_DD4hep: # this is now done in DD4hepSimulations.py, i.e. in ddsim + seq, act = geant4.addDetectorConstruction( + "Geant4DetectorGeometryConstruction/ConstructGeo" + ) + act.DebugMaterials = True + act.DebugElements = False + act.DebugVolumes = True + act.DebugShapes = True + + # Apply sensitive detectors + sensitives = DetectorConstruction( + kernel, str("Geant4DetectorSensitivesConstruction/ConstructSD") + ) + sensitives.enableUI() + seq.adopt(sensitives) + + # ----------------- + model = DetectorConstruction(kernel, str(ml_model)) + + ## # Mandatory model parameters + model.RegionName = "EcalBarrelRegion" + model.Detector = ml_barrel_name + model.Symmetry = ml_barrel_symmetry + model.Enable = True + model.CorrectForAngles = ml_correct_angles + # Energy boundaries are optional: Units are GeV + model.ApplicableParticles = {"e+", "e-", "gamma"} + model.Etrigger = { + "e+": 10.0 * GeV, + "e-": 10.0 * GeV, + "gamma": 10.0 * GeV, + } # trigger on lower training threshold + model.ModelPath = ml_file + model.OptimizeFlag = 1 + model.IntraOpNumThreads = 1 + + model.enableUI() + seq.adopt(model) + # ------------------- + model1 = DetectorConstruction(kernel, str(ml_model_1)) + + ## # Mandatory model parameters + model1.RegionName = "EcalEndcapRegion" + model1.Detector = ml_endcap_name + model1.Enable = True + model1.CorrectForAngles = ml_correct_angles + # Energy boundaries are optional: Units are GeV + model1.ApplicableParticles = {"e+", "e-", "gamma"} + model1.Etrigger = { + "e+": 10.0 * GeV, + "e-": 10.0 * GeV, + "gamma": 10.0 * GeV, + } # trigger on lower training threshold + model1.ModelPath = ml_file + model1.OptimizeFlag = 1 + model1.IntraOpNumThreads = 1 + + model1.enableUI() + seq.adopt(model1) + # ------------------- + + # Now build the physics list: + phys = kernel.physicsList() + ph = PhysicsList(kernel, str("Geant4FastPhysics/FastPhysicsList")) + ph.EnabledParticles = ["e+", "e-", "gamma"] + ph.BeVerbose = True + ph.enableUI() + phys.adopt(ph) + phys.dump() + + +def LoadHdf5(kernel): + ild = True + BIBAE = True + Two_Angle = True + old_DD4hep = False ## use for DD4hep versions/commits before ~ Apr 21st 2023 + hadrons = True + + if ild == True: + ml_barrel_name = "EcalBarrel" + ml_barrel_symmetry = 8 + ml_endcap_name = "EcalEndcap" + + ## For hadron shower fast simulation + ml_had_barrel_name = "HcalBarrel" + ml_had_barrel_symmetry = 8 + ml_had_endcap_name = "HcalEndcap" + + else: + ml_barrel_name = "ECalBarrel" + ml_barrel_symmetry = 12 + ml_endcap_name = "ECalEndcap" + + ## For hadron shower fast simulation is needed + ml_had_barrel_name = "HCalBarrel" + ml_had_barrel_symmetry = 12 + ml_had_endcap_name = "HCalEndcap" + + if BIBAE == True and Two_Angle == True: + ml_file = "../models/photons-E5050A-theta9090A-phi9090-p1.hdf5" + ml_model = ( + "LoadHDF5RegularGridTwoAngleBIBAEModelPolyhedraBarrel/BarrelModelTorch" + ) + ml_model_1 = "LoadHDF5RegularGridTwoAngleBIBAEModelEndcap/EndcapModelTorch" + ml_correct_angles = False + + if hadrons == True: + ml_model_had = "LoadHDF5PionCloudsPCHadronModelPolyhedraBarrel/BarrelModelTorch" + ml_had_file = "../models/PionClouds_50GeV_sp.h5" #"../models/PionClouds_50GeV_sp_scaled.h5" + ml_correct_angles = False + + from g4units import GeV, MeV # DO NOT REMOVE OR MOVE!!!!! (EXCLAMATION MARK) + from DDG4 import DetectorConstruction, Geant4, PhysicsList + + geant4 = Geant4(kernel) + + seq = geant4.detectorConstruction() + + if old_DD4hep: # this is now done in DD4hepSimulations.py, i.e. in ddsim + seq, act = geant4.addDetectorConstruction( + "Geant4DetectorGeometryConstruction/ConstructGeo" + ) + act.DebugMaterials = True + act.DebugElements = False + act.DebugVolumes = True + act.DebugShapes = True + + # Apply sensitive detectors + sensitives = DetectorConstruction( + kernel, str("Geant4DetectorSensitivesConstruction/ConstructSD") + ) + sensitives.enableUI() + seq.adopt(sensitives) + + # ----------------- + ''' + ## EM in Barrel + model = DetectorConstruction(kernel, str(ml_model)) + + ## # Mandatory model parameters + model.RegionName = "EcalBarrelRegion" + model.Detector = ml_barrel_name + model.Symmetry = ml_barrel_symmetry + model.Enable = True + model.CorrectForAngles = ml_correct_angles + # Energy boundaries are optional: Units are GeV + model.ApplicableParticles = {"e+", "e-", "gamma"} + model.Etrigger = { + "e+": 10.0 * GeV, + "e-": 10.0 * GeV, + "gamma": 10.0 * GeV, + } # trigger on lower training threshold + model.FilePath = ml_file + # model.OptimizeFlag = 1 + # model.IntraOpNumThreads = 1 + + model.enableUI() + seq.adopt(model) + ''' + # ------------------- + ## EM in Endcap + model1 = DetectorConstruction(kernel, str(ml_model_1)) + + ## # Mandatory model parameters + model1.RegionName = "EcalEndcapRegion" + model1.Detector = ml_endcap_name + model1.Enable = True + model1.CorrectForAngles = ml_correct_angles + # Energy boundaries are optional: Units are GeV + model1.ApplicableParticles = {"e+", "e-", "gamma"} + model1.Etrigger = { + "e+": 10.0 * GeV, + "e-": 10.0 * GeV, + "gamma": 10.0 * GeV, + } # trigger on lower training threshold + model1.FilePath = ml_file + # model1.OptimizeFlag = 1 + # model1.IntraOpNumThreads = 1 + + model1.enableUI() + seq.adopt(model1) + + # ------------------- + ## Hadrons in Barrel + modelHad1 = DetectorConstruction(kernel, str(ml_model_had)) + + ## # Mandatory model parameters + modelHad1.isHadShower = True + modelHad1.RegionName = "EcalBarrelRegion" #or "HcalBarrelRegion" ## hadron model triggers in ecal + modelHad1.Detector = ml_barrel_name + modelHad1.HadDetector = ml_had_barrel_name + modelHad1.Symmetry = ml_barrel_symmetry + modelHad1.HadSymmetry = ml_had_barrel_symmetry + modelHad1.Enable = True + modelHad1.CorrectForAngles = ml_correct_angles + # Energy boundaries are optional: Units are GeV + modelHad1.ApplicableParticles = {"pi+"} + modelHad1.Etrigger = {"pi+": 10.0 * GeV} # trigger on lower training threshold + modelHad1.FilePath = ml_had_file + # model.OptimizeFlag = 1 + # model.IntraOpNumThreads = 1 + + modelHad1.enableUI() + seq.adopt(modelHad1) + + # ------------------- + + # Now build the physics list: + phys = kernel.physicsList() + ph = PhysicsList(kernel, str("Geant4FastPhysics/FastPhysicsList")) + ph.EnabledParticles = ["e+", "e-", "gamma", "pi+"] + ph.BeVerbose = True + ph.enableUI() + phys.adopt(ph) + phys.dump() + + +#SIM.physics.setupUserPhysics( aiDance) +#SIM.physics.setupUserPhysics(aiDanceTorch) +SIM.physics.setupUserPhysics(LoadHdf5) diff --git a/scripts/test_onnx.mac b/scripts/test_onnx.mac index 3d5a716..4226261 100644 --- a/scripts/test_onnx.mac +++ b/scripts/test_onnx.mac @@ -3,7 +3,7 @@ # example script to run inference on a GAN w/ ONNX runtime # --- the particle gun -/gps/pos/centre 30 180.48 0 #120 180.48 120 #30 180.48 0 #30 0 0 +/gps/pos/centre 30 0 0 #30 180.48 0 #### this is ILD calo Face #120 180.48 120 #30 180.48 0 #30 0 0 #/gps/particle gamma /gps/particle pi+ /gps/energy 50 GeV @@ -64,5 +64,5 @@ #/gps/direction 0.1 -0.8 .1 -/run/beamOn 2000 #100 +/run/beamOn 100 #2000 #100 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2882c79..0a0114c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -35,6 +35,18 @@ if(INSTRUMENT_MODEL) ) endif() +if(RECORD_CALO_IMPACT) + target_sources(${PROJECT_NAME} PRIVATE + DDMLRunAction.cc + DDMLEventAction.cc + ) + target_compile_definitions(${PROJECT_NAME} PUBLIC + DDML_RECORD_CALO_IMPACT=1 + ) +endif() + + + if(OnnxRuntime_FOUND) target_sources(${PROJECT_NAME} PRIVATE ONNXInference.cc @@ -111,6 +123,10 @@ if(HDF5_FOUND) list(APPEND headers ${PROJECT_SOURCE_DIR}/include/DDML/LoadHdf5.h) endif() +if(RECORD_CALO_IMPACT) + list(APPEND headers ${PROJECT_SOURCE_DIR}/include/DDML/DDMLRunAction.h ${PROJECT_SOURCE_DIR}/include/DDML/DDMLEventAction.h) +endif() + #install(FILES # ${headers} # DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) diff --git a/src/DDMLEventAction.cc b/src/DDMLEventAction.cc new file mode 100644 index 0000000..7decd72 --- /dev/null +++ b/src/DDMLEventAction.cc @@ -0,0 +1,58 @@ +#include "DDML/DDMLEventAction.h" +#include "G4AnalysisManager.hh" +#include "DD4hep/InstanceCount.h" +#include "G4Event.hh" +#include "G4EventManager.hh" +#include "G4ThreeVector.hh" +#include "G4PrimaryVertex.hh" +#include "G4PrimaryParticle.hh" +#include "DDG4/Geant4Data.h" + +#define DEBUGPRINT 0 + +namespace ddml { + +DDMLEventAction::DDMLEventAction(dd4hep::sim::Geant4Context* c, const std::string& n): +Geant4EventAction(c,n) + { + dd4hep::InstanceCount::increment(this); + } + +/// Default destructor +DDMLEventAction::~DDMLEventAction() { + dd4hep::InstanceCount::decrement(this); + } + +void DDMLEventAction::begin(const G4Event*){} + +void DDMLEventAction::end(const G4Event*) { + // Get analysis manager + auto analysisManager = G4AnalysisManager::Instance(); + + // Retrieve information from primary vertex and primary particle + auto primaryVertex = + G4EventManager::GetEventManager()->GetConstCurrentEvent()->GetPrimaryVertex(); + G4ThreeVector primaryVertexPos = primaryVertex->GetPosition(); + auto primaryParticle = primaryVertex->GetPrimary(0); + G4double primaryEnergy = primaryParticle->GetTotalEnergy(); + G4ThreeVector primaryDirection = primaryParticle->GetMomentumDirection(); + G4int primaryPDG = primaryParticle->GetPDGcode(); + + // Fill analysis manager + analysisManager->FillNtupleIColumn(0, 0, primaryPDG); + analysisManager->FillNtupleDColumn(0, 1, primaryEnergy); + analysisManager->FillNtupleDColumn(0, 2, primaryVertexPos.x()); + analysisManager->FillNtupleDColumn(0, 3, primaryVertexPos.y()); + analysisManager->FillNtupleDColumn(0, 4, primaryVertexPos.z()); + analysisManager->FillNtupleDColumn(0, 5, primaryDirection.x()); + analysisManager->FillNtupleDColumn(0, 6, primaryDirection.y()); + analysisManager->FillNtupleDColumn(0, 7, primaryDirection.z()); + + analysisManager->AddNtupleRow(0); + +} + +} //namespace + +#include "DDG4/Factories.h" +DECLARE_GEANT4ACTION_NS(ddml, DDMLEventAction) diff --git a/src/DDMLRunAction.cc b/src/DDMLRunAction.cc new file mode 100644 index 0000000..c7cd807 --- /dev/null +++ b/src/DDMLRunAction.cc @@ -0,0 +1,94 @@ +#include "DDML/DDMLRunAction.h" +#include "DDML/DDMLEventAction.h" +#include "G4AnalysisManager.hh" +#include "G4EventManager.hh" +#include "DD4hep/InstanceCount.h" +#include "G4Run.hh" + +#define DEBUGPRINT 0 + +namespace ddml { + +/// Standard constructor with initializing arguments +DDMLRunAction::DDMLRunAction(dd4hep::sim::Geant4Context* c, const std::string& n): + Geant4RunAction(c, n) { + // Create analysis manager + G4AnalysisManager* analysisManager = G4AnalysisManager::Instance(); + analysisManager->SetDefaultFileType("root"); + + // Default filename, can be overriden with /analysis/setFileName + analysisManager->SetFileName("Output"); + dd4hep::InstanceCount::increment(this); +} + +/// Default destructor +DDMLRunAction::~DDMLRunAction() { + dd4hep::InstanceCount::decrement(this); +} + +/// begin-of-run callback +void DDMLRunAction::begin(const G4Run*) { + // Get analysis manager +G4AnalysisManager* analysisManager = G4AnalysisManager::Instance(); + +// Create directories +analysisManager->SetVerboseLevel(0); + +// Create ntuples +analysisManager->CreateNtuple("global", "Event data"); +analysisManager->CreateNtupleIColumn("MC_PDG"); +analysisManager->CreateNtupleDColumn("MC_Energy"); +analysisManager->CreateNtupleDColumn("MC_PosX"); +analysisManager->CreateNtupleDColumn("MC_PosY"); +analysisManager->CreateNtupleDColumn("MC_PosZ"); +analysisManager->CreateNtupleDColumn("MC_DirX"); +analysisManager->CreateNtupleDColumn("MC_DirY"); +analysisManager->CreateNtupleDColumn("MC_DirZ"); +analysisManager->FinishNtuple(); + +/* +DDMLEventAction* mEventAction = dynamic_cast(G4EventManager::GetEventManager()->GetUserEventAction()); +analysisManager->CreateNtuple("Fast Sim Info", "MC info at calo face"); +analysisManager->CreateNtupleIColumn("Calo_MC_PDG", mEventAction->GetCaloMC_PDG()); +analysisManager->CreateNtupleDColumn("Calo_MC_Energy", mEventAction->GetCaloMC_E()); +analysisManager->CreateNtupleDColumn("Calo_MC_PosX", mEventAction->GetCaloMC_PosX()); +analysisManager->CreateNtupleDColumn("Calo_MC_PosY", mEventAction->GetCaloMC_PosY()); +analysisManager->CreateNtupleDColumn("Calo_MC_PosZ", mEventAction->GetCaloMC_PosZ()); +analysisManager->CreateNtupleDColumn("Calo_MC_DirX", mEventAction->GetCaloMC_DirX()); +analysisManager->CreateNtupleDColumn("Calo_MC_DirY", mEventAction->GetCaloMC_DirY()); +analysisManager->CreateNtupleDColumn("Calo_MC_DirZ", mEventAction->GetCaloMC_DirZ()); +analysisManager->FinishNtuple(); +*/ + +analysisManager->CreateNtuple("Fast_Sim_Info", "MC info at calo face"); +analysisManager->CreateNtupleIColumn("Calo_MC_PDG"); +analysisManager->CreateNtupleDColumn("Calo_MC_Energy"); +analysisManager->CreateNtupleDColumn("Calo_MC_PosX"); +analysisManager->CreateNtupleDColumn("Calo_MC_PosY"); +analysisManager->CreateNtupleDColumn("Calo_MC_PosZ"); +analysisManager->CreateNtupleDColumn("Calo_MC_DirX"); +analysisManager->CreateNtupleDColumn("Calo_MC_DirY"); +analysisManager->CreateNtupleDColumn("Calo_MC_DirZ"); +analysisManager->FinishNtuple(); + + +analysisManager->CreateNtuple("run", "Run data"); +analysisManager->CreateNtupleDColumn("N"); +analysisManager->FinishNtuple(); + +analysisManager->OpenFile(); +} + +/// End-of-run callback +void DDMLRunAction::end(const G4Run* aRun){ + auto analysisManager = G4AnalysisManager::Instance(); + analysisManager->FillNtupleDColumn(2, 0, aRun->GetNumberOfEvent()); + analysisManager->AddNtupleRow(2); + analysisManager->Write(); + analysisManager->CloseFile(); +} + +} // namespace + +#include "DDG4/Factories.h" +DECLARE_GEANT4ACTION_NS(ddml, DDMLRunAction) \ No newline at end of file diff --git a/src/PionCloudsModel.cc b/src/PionCloudsModel.cc index 6b04e9e..0dbad53 100644 --- a/src/PionCloudsModel.cc +++ b/src/PionCloudsModel.cc @@ -124,8 +124,8 @@ namespace ddml { for (int i = 0; i < nPoints; i++) { ddml::SpacePoint sp( - reshaped[i][0]*1e3, // x // *(-1) to align local to global convention in ddml - reshaped[i][2]*1e3, // y // *(-1) to align local to global convention in ddml + reshaped[i][0], // x // *(-1) to align local to global convention in ddml + reshaped[i][2], // y // *(-1) to align local to global convention in ddml 0., // z reshaped[i][3], // energy 0. // time From 40d2356d70163f9bda69433a30af360246fadca9 Mon Sep 17 00:00:00 2001 From: Peter McKeown Date: Tue, 25 Feb 2025 11:24:47 +0100 Subject: [PATCH 05/36] Updates ready for obtaining calo entries --- include/DDML/PionCloudsModel.h | 2 +- scripts/ddsim_steer_Record_Calo_entry.py | 5 +- scripts/test_onnx.mac | 17 ++- src/Geant4FastHitMakerGlobal.cc | 8 +- src/LoadHdf5.cc | 2 +- src/PionCloudsModel.cc | 129 ++++++++++++----------- 6 files changed, 93 insertions(+), 70 deletions(-) diff --git a/include/DDML/PionCloudsModel.h b/include/DDML/PionCloudsModel.h index 0bb9bfc..111a602 100644 --- a/include/DDML/PionCloudsModel.h +++ b/include/DDML/PionCloudsModel.h @@ -55,7 +55,7 @@ namespace ddml { /// model properties for plugin // These grid sizes were used for the two angle BIBAE - int m_numPoints = 2600; + int m_numPoints = 2600; //4148; //2600; //number of points in the shower int m_latentSize = 3; // number of input features (energy, theta, phi) int m_maxNumElements = m_numPoints*4; // number of space points in the output multiplied by 4 (x,y,z,energy) int m_nLayer = 78; diff --git a/scripts/ddsim_steer_Record_Calo_entry.py b/scripts/ddsim_steer_Record_Calo_entry.py index 6107367..1f21c95 100644 --- a/scripts/ddsim_steer_Record_Calo_entry.py +++ b/scripts/ddsim_steer_Record_Calo_entry.py @@ -542,7 +542,8 @@ def LoadHdf5(kernel): if hadrons == True: ml_model_had = "LoadHDF5PionCloudsPCHadronModelPolyhedraBarrel/BarrelModelTorch" - ml_had_file = "../models/PionClouds_50GeV_sp.h5" #"../models/PionClouds_50GeV_sp_scaled.h5" + ml_had_file = "../models/PionClouds_50GeV_sp_scaled.h5" #"../models/gen_showers_for_reco_50GeV_2000.hdf5" + #"../models/gen_showers_50GeV_2000_Martina.hdf5" #"../models/PionClouds_50GeV_sp_scaled.h5" #"../models/PionClouds_50GeV_sp.h5" # ml_correct_angles = False from g4units import GeV, MeV # DO NOT REMOVE OR MOVE!!!!! (EXCLAMATION MARK) @@ -631,7 +632,7 @@ def LoadHdf5(kernel): modelHad1.CorrectForAngles = ml_correct_angles # Energy boundaries are optional: Units are GeV modelHad1.ApplicableParticles = {"pi+"} - modelHad1.Etrigger = {"pi+": 10.0 * GeV} # trigger on lower training threshold + modelHad1.Etrigger = {"pi+": 30.0 * GeV} #{"pi+": 10.0 * GeV} # trigger on lower training threshold modelHad1.FilePath = ml_had_file # model.OptimizeFlag = 1 # model.IntraOpNumThreads = 1 diff --git a/scripts/test_onnx.mac b/scripts/test_onnx.mac index 4226261..a748499 100644 --- a/scripts/test_onnx.mac +++ b/scripts/test_onnx.mac @@ -3,13 +3,24 @@ # example script to run inference on a GAN w/ ONNX runtime # --- the particle gun -/gps/pos/centre 30 0 0 #30 180.48 0 #### this is ILD calo Face #120 180.48 120 #30 180.48 0 #30 0 0 + +# At right side face (perpendicular to x=0) +#/gps/pos/centre 18.47 0 0 #0 180.47 150 #### this is ILD calo Face #120 180.48 120 #30 180.48 0 #30 0 0 +#30 0 0 + +#/gps/pos/centre 0 0 0 #0 180.47 150 #### this is ILD calo Face #120 180.48 120 #30 180.48 0 #30 0 0 +#30 0 0 #/gps/particle gamma + +# for SimpleCalo +#/gps/direction 1 0 0 #0 1 0 #-0.4152 1 0 #(pi/8 + pi/4) #1 0.414213562 0 #(pi/8) #-1 2.414213562 0 #(pi/8 + 1 deg) # 0.25 0.25 0.5 #0 0.5 0.655 # ( 37 deg in theta- most you can get in endcap from IP ) + /gps/particle pi+ /gps/energy 50 GeV -# for SimpleCalo -/gps/direction 0 1 0 #-0.4152 1 0 #(pi/8 + pi/4) #1 0.414213562 0 #(pi/8) #-1 2.414213562 0 #(pi/8 + 1 deg) # 0.25 0.25 0.5 #0 0.5 0.655 # ( 37 deg in theta- most you can get in endcap from IP ) +/gps/pos/centre -5 0 -15 +/gps/direction -0.037864591009775746 0.9992828792427412 0 # 90 deg imact for 50 GeV p+ + # phi barrel #1 0.414213562 0 #(pi/8) diff --git a/src/Geant4FastHitMakerGlobal.cc b/src/Geant4FastHitMakerGlobal.cc index bd7108f..2395447 100644 --- a/src/Geant4FastHitMakerGlobal.cc +++ b/src/Geant4FastHitMakerGlobal.cc @@ -49,8 +49,8 @@ Geant4FastHitMakerGlobal::~Geant4FastHitMakerGlobal() { void Geant4FastHitMakerGlobal::make(const G4FastHit& aHit, const G4FastTrack& aTrack) { - std::cout << "Geant4FastHitMakerGlobal::make - aHit.GetPosition().x() " << aHit.GetPosition().x() << " aHit.GetPosition().y() " << - aHit.GetPosition().y() << " aHit.GetPosition().z() " << aHit.GetPosition().z() << std::endl; + //std::cout << "Geant4FastHitMakerGlobal::make - aHit.GetPosition().x() " << aHit.GetPosition().x() << " aHit.GetPosition().y() " << + // aHit.GetPosition().y() << " aHit.GetPosition().z() " << aHit.GetPosition().z() << std::endl; // do not make empty deposit if (aHit.GetEnergy() <= 0) { return; @@ -88,8 +88,8 @@ void Geant4FastHitMakerGlobal::make(const G4FastHit& aHit, const G4FastTrack& aT sensitive = currentVolume->GetLogicalVolume()->GetSensitiveDetector(); G4VFastSimSensitiveDetector* fastSimSensitive = dynamic_cast(sensitive); if (fastSimSensitive) { - std::cout << "IN FAST Sim Sensitive Geant4FastHitMakerGlobal::make - aHit.GetPosition().x() " << aHit.GetPosition().x() << " aHit.GetPosition().y() " << - aHit.GetPosition().y() << " aHit.GetPosition().z() " << aHit.GetPosition().z() << " Energy: " << aHit.GetEnergy() << std::endl; + // std::cout << "IN FAST Sim Sensitive Geant4FastHitMakerGlobal::make - aHit.GetPosition().x() " << aHit.GetPosition().x() << " aHit.GetPosition().y() " << + // aHit.GetPosition().y() << " aHit.GetPosition().z() " << aHit.GetPosition().z() << " Energy: " << aHit.GetEnergy() << std::endl; fastSimSensitive->Hit(&aHit, &aTrack, &m_touchableHandle); } else if (sensitive && currentVolume->GetLogicalVolume()->GetFastSimulationManager()) { G4cerr << "ERROR - Geant4FastHitMakerGlobal::make()" << G4endl << " It is required to derive from the " diff --git a/src/LoadHdf5.cc b/src/LoadHdf5.cc index 2cb8360..5007782 100644 --- a/src/LoadHdf5.cc +++ b/src/LoadHdf5.cc @@ -19,7 +19,7 @@ void LoadHdf5::initialize() { // inputs and TensorDimVecs unused // Open dataset + dataspace - std::string datasetName = "spase_points"; //"layers"; + std::string datasetName = "spase_points"; //"events"; //"spase_points"; //"layers"; H5::DataSet dataset = m_file.openDataSet(datasetName); dd4hep::printout(dd4hep::DEBUG, "LoadHdf5::initialize", "Accessed HDF5 dataset"); H5::DataSpace dataspace = dataset.getSpace(); diff --git a/src/PionCloudsModel.cc b/src/PionCloudsModel.cc index 0dbad53..888afc2 100644 --- a/src/PionCloudsModel.cc +++ b/src/PionCloudsModel.cc @@ -70,73 +70,84 @@ namespace ddml { } - - void PionCloudsModel::convertOutput(G4FastTrack const& aFastTrack, - G4ThreeVector const& localDir, - const std::vector& output, - std::vector& spacepoints ){ - - int nPoints = m_numPoints ; // number of points in shower - - dd4hep::printout(dd4hep::DEBUG, "PionCloudsModel::convertOutput", "m_numPoints : %i", m_numPoints); +/* For array structure: (No. showers, dimensions(4), No. points) +void PionCloudsModel::convertOutput(G4FastTrack const& aFastTrack, + G4ThreeVector const& localDir, + const std::vector& output, + std::vector& spacepoints ){ - spacepoints.resize( m_nLayer ) ; + //int nPoints = m_numPoints ; // number of points in shower - int numSP = 0; int layerNum = 0; - int numElements = 0; - for (int i = 0; i < m_nLayer; i++) { - numSP = output[i] + 1; - spacepoints[i].reserve(numSP); - numElements += output[i] * 4; - } - std::cout << " PionCloudsModel::convertOutput DONE numElements, numElements = " << numElements << std::endl; - - /* - for (int i = m_nLayer; i < m_nLayer + numElements; i += 4) { - std::cout << " PionCloudsModel::convertOutput Layer Loop, i = " << i << std::endl; - std::cout << " PionCloudsModel::convertOutput Layer Loop, output[i] " << output[i] << std::endl; - std::cout << " PionCloudsModel::convertOutput Layer Loop, output[i+1] " << output[i] << std::endl; - std::cout << " PionCloudsModel::convertOutput Layer Loop, output[i+3] " << output[i] << std::endl; - ddml::SpacePoint sp( - output[i], // x // *(-1) to align local to global convention in ddml - output[i+1], // y // *(-1) to align local to global convention in ddml - 0., // z - output[i+3], // energy - 0. // time - ); - layerNum = output[i+2]; - std::cout << " PionCloudsModel::convertOutput Layer Loop, layerNum " << layerNum << std::endl; - spacepoints[layerNum].emplace_back( sp ) ; - */ - - - float reshaped[2600][4]; - - // Fill the 3D array using the flattened vector - size_t index = 0; - for (size_t j = 0; j < 2600; ++j) { - for (size_t k = 0; k < 4; ++k) { + /// This is too C-like - once model is concrete use std::vector + //float reshaped[m_numPoints][4]; + std::vector> reshaped(4, std::vector(m_numPoints)); + + // Fill the 3D array-like vector using the flattened vector + int index = 0; + for (int j = 0; j < 4; ++j) { + for (int k = 0; k < m_numPoints; ++k) { reshaped[j][k] = output[index++]; } } - for (int i = 0; i < nPoints; i++) { - ddml::SpacePoint sp( - reshaped[i][0], // x // *(-1) to align local to global convention in ddml - reshaped[i][2], // y // *(-1) to align local to global convention in ddml - 0., // z - reshaped[i][3], // energy - 0. // time - ); - layerNum = reshaped[i][1]; - std::cout << "PionCloudsModel::convertOutput - layerNum" << layerNum <& output, + std::vector& spacepoints ){ + + //int nPoints = m_numPoints ; // number of points in shower + + int layerNum = 0; + + /// This is too C-like - use std::vector + //float reshaped[m_numPoints][4]; + std::vector> reshaped(m_numPoints, std::vector(4)); + + // Fill the 3D array-like vector using the flattened vector + int index = 0; + for (int j = 0; j < m_numPoints; ++j) { + for (int k = 0; k < 4; ++k) { + reshaped[j][k] = output[index]; + index++; + } + } + + spacepoints.resize( m_nLayer ) ; + + for (int i = 0; i < m_numPoints; i++) { + ddml::SpacePoint sp( + reshaped[i][0], // x // *(-1) to align local to global convention in ddml + reshaped[i][2], // y // *(-1) to align local to global convention in ddml + 0., // z + reshaped[i][3], // energy + 0. // time + ); + layerNum = reshaped[i][1]; + //std::cout << "PionCloudsModel::convertOutput - layerNum" << layerNum < Date: Tue, 25 Feb 2025 14:31:08 +0100 Subject: [PATCH 06/36] Update incorrect naming in ONNX inference --- src/ONNXInference.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ONNXInference.cc b/src/ONNXInference.cc index 09e9c4a..261d7ae 100644 --- a/src/ONNXInference.cc +++ b/src/ONNXInference.cc @@ -56,7 +56,7 @@ void ONNXInference::initialize() { std::vector input_node_names(num_input_nodes); for (std::size_t i = 0; i < num_input_nodes; i++) { #if ORT_API_VERSION < 13 - const auto input_name = AllocatedStringPtr(fSession->GetInputName(i, allocator), allocDeleter).release(); + const auto input_name = AllocatedStringPtr(m_Session->GetInputName(i, allocator), allocDeleter).release(); #else const auto input_name = m_session->GetInputNameAllocated(i, allocator).release(); #endif @@ -87,7 +87,7 @@ void ONNXInference::initialize() { std::vector output_node_names(num_output_nodes); for (std::size_t i = 0; i < num_output_nodes; i++) { #if ORT_API_VERSION < 12 - const auto output_name = AllocatedStringPtr(fSession->GetOutputName(i, allocator), allocDeleter).release(); + const auto output_name = AllocatedStringPtr(m_Session->GetOutputName(i, allocator), allocDeleter).release(); #else const auto output_name = m_session->GetOutputNameAllocated(i, allocator).release(); #endif From a8372214592a046c67fd20632e36314e863c525f Mon Sep 17 00:00:00 2001 From: Peter McKeown Date: Tue, 25 Feb 2025 14:35:43 +0100 Subject: [PATCH 07/36] Correct capitalisation --- src/ONNXInference.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ONNXInference.cc b/src/ONNXInference.cc index 261d7ae..1f7b30e 100644 --- a/src/ONNXInference.cc +++ b/src/ONNXInference.cc @@ -56,7 +56,7 @@ void ONNXInference::initialize() { std::vector input_node_names(num_input_nodes); for (std::size_t i = 0; i < num_input_nodes; i++) { #if ORT_API_VERSION < 13 - const auto input_name = AllocatedStringPtr(m_Session->GetInputName(i, allocator), allocDeleter).release(); + const auto input_name = AllocatedStringPtr(m_session->GetInputName(i, allocator), allocDeleter).release(); #else const auto input_name = m_session->GetInputNameAllocated(i, allocator).release(); #endif @@ -87,7 +87,7 @@ void ONNXInference::initialize() { std::vector output_node_names(num_output_nodes); for (std::size_t i = 0; i < num_output_nodes; i++) { #if ORT_API_VERSION < 12 - const auto output_name = AllocatedStringPtr(m_Session->GetOutputName(i, allocator), allocDeleter).release(); + const auto output_name = AllocatedStringPtr(m_session->GetOutputName(i, allocator), allocDeleter).release(); #else const auto output_name = m_session->GetOutputNameAllocated(i, allocator).release(); #endif From a2546234d31432e6e25598ead89b8708f3d84e62 Mon Sep 17 00:00:00 2001 From: Peter McKeown Date: Tue, 25 Feb 2025 14:52:24 +0100 Subject: [PATCH 08/36] Hot fix type of m_dimsOut for older HDF5 versions --- include/DDML/LoadHdf5.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/DDML/LoadHdf5.h b/include/DDML/LoadHdf5.h index 74bdf02..7fdfd44 100644 --- a/include/DDML/LoadHdf5.h +++ b/include/DDML/LoadHdf5.h @@ -49,7 +49,8 @@ class LoadHdf5 : public InferenceInterface { std::vector m_library{}; // shower library dimensions - std::vector m_dimsOut{}; + std::vector m_dimsOut{}; // This is a hot fix for older HDF5 versions! + //std::vector m_dimsOut{}; // properties for plugin std::string m_filePath = {}; From d4d497d7533ba6fc3a6be643140fb5193d58a8da Mon Sep 17 00:00:00 2001 From: Peter McKeown Date: Thu, 8 May 2025 11:19:58 +0200 Subject: [PATCH 09/36] code clean up --- scripts/ddsim_steer.py | 2 +- src/DDMLRunAction.cc | 14 ----------- src/PionCloudsModel.cc | 55 ------------------------------------------ 3 files changed, 1 insertion(+), 70 deletions(-) diff --git a/scripts/ddsim_steer.py b/scripts/ddsim_steer.py index 9c7f8a0..6d24a50 100644 --- a/scripts/ddsim_steer.py +++ b/scripts/ddsim_steer.py @@ -547,7 +547,7 @@ def LoadHdf5(kernel): if hadrons == True: ml_model_had = "LoadHDF5PionCloudsPCHadronModelPolyhedraBarrel/BarrelModelTorch" - ml_had_file = "../models/PionClouds_50GeV_sp.h5" #"../models/PionClouds_50GeV_sp_scaled.h5" + ml_had_file = "../models/PionClouds_50GeV_sp.h5" ml_correct_angles = False from g4units import GeV, MeV # DO NOT REMOVE OR MOVE!!!!! (EXCLAMATION MARK) diff --git a/src/DDMLRunAction.cc b/src/DDMLRunAction.cc index c7cd807..60c92eb 100644 --- a/src/DDMLRunAction.cc +++ b/src/DDMLRunAction.cc @@ -46,20 +46,6 @@ analysisManager->CreateNtupleDColumn("MC_DirY"); analysisManager->CreateNtupleDColumn("MC_DirZ"); analysisManager->FinishNtuple(); -/* -DDMLEventAction* mEventAction = dynamic_cast(G4EventManager::GetEventManager()->GetUserEventAction()); -analysisManager->CreateNtuple("Fast Sim Info", "MC info at calo face"); -analysisManager->CreateNtupleIColumn("Calo_MC_PDG", mEventAction->GetCaloMC_PDG()); -analysisManager->CreateNtupleDColumn("Calo_MC_Energy", mEventAction->GetCaloMC_E()); -analysisManager->CreateNtupleDColumn("Calo_MC_PosX", mEventAction->GetCaloMC_PosX()); -analysisManager->CreateNtupleDColumn("Calo_MC_PosY", mEventAction->GetCaloMC_PosY()); -analysisManager->CreateNtupleDColumn("Calo_MC_PosZ", mEventAction->GetCaloMC_PosZ()); -analysisManager->CreateNtupleDColumn("Calo_MC_DirX", mEventAction->GetCaloMC_DirX()); -analysisManager->CreateNtupleDColumn("Calo_MC_DirY", mEventAction->GetCaloMC_DirY()); -analysisManager->CreateNtupleDColumn("Calo_MC_DirZ", mEventAction->GetCaloMC_DirZ()); -analysisManager->FinishNtuple(); -*/ - analysisManager->CreateNtuple("Fast_Sim_Info", "MC info at calo face"); analysisManager->CreateNtupleIColumn("Calo_MC_PDG"); analysisManager->CreateNtupleDColumn("Calo_MC_Energy"); diff --git a/src/PionCloudsModel.cc b/src/PionCloudsModel.cc index 888afc2..7604f3a 100644 --- a/src/PionCloudsModel.cc +++ b/src/PionCloudsModel.cc @@ -2,8 +2,6 @@ #include // for G4FastTrack -//#include - #define DEBUGPRINT 0 namespace ddml { @@ -31,8 +29,6 @@ namespace ddml { dd4hep::printout(dd4hep::DEBUG, "PionCloudsModel::prepareInput", "DDML::localDir: (%f, %f, %f)", localDir_.x(), localDir_.y(), localDir_.z()); - // std::cout << "PionClouds::localDir:" << "(" << localDir_.x() << "," << localDir_.y() << "," << localDir_.z() << ")" - // << std::endl; // compute local incident angles double r = sqrt(localDir_.x() * localDir_.x() + localDir_.y() * localDir_.y() + localDir_.z() * localDir_.z()); @@ -54,12 +50,6 @@ namespace ddml { inputs[1][0] = theta; // 89.*(M_PI/180.) ; //Theta_vec[0]/(90.*(M_PI/180.)); inputs[2][0] = phi; - // if (DEBUGPRINT) { - // std::cout << " Input_energy_tensor : " << inputs[0][0] << std::endl; - // std::cout << " Input_theta_tensor : " << inputs[1][0] << std::endl; - // std::cout << " Input_phi_tensor : " << inputs[2][0] << std::endl; - // } - dd4hep::printout(dd4hep::DEBUG, "PionCloudsModel::prepareInput", "Input_energy_tensor : %f", inputs[0][0]); dd4hep::printout(dd4hep::DEBUG, "PionCloudsModel::prepareInput", "Input_theta_tensor : %f", inputs[1][0]); dd4hep::printout(dd4hep::DEBUG, "PionCloudsModel::prepareInput", "Input_phi_tensor : %f", inputs[2][0]); @@ -70,46 +60,6 @@ namespace ddml { } -/* For array structure: (No. showers, dimensions(4), No. points) -void PionCloudsModel::convertOutput(G4FastTrack const& aFastTrack, - G4ThreeVector const& localDir, - const std::vector& output, - std::vector& spacepoints ){ - - //int nPoints = m_numPoints ; // number of points in shower - - int layerNum = 0; - - /// This is too C-like - once model is concrete use std::vector - //float reshaped[m_numPoints][4]; - std::vector> reshaped(4, std::vector(m_numPoints)); - - // Fill the 3D array-like vector using the flattened vector - int index = 0; - for (int j = 0; j < 4; ++j) { - for (int k = 0; k < m_numPoints; ++k) { - reshaped[j][k] = output[index++]; - } - } - - spacepoints.resize( m_nLayer ) ; - - for (int i = 0; i < m_numPoints; i++) { - ddml::SpacePoint sp( - reshaped[0][i], // x // *(-1) to align local to global convention in ddml - reshaped[2][i], // y // *(-1) to align local to global convention in ddml - 0., // z - reshaped[3][i], // energy - 0. // time - ); - layerNum = reshaped[1][i]; - spacepoints[layerNum].emplace_back( sp ) ; - } - } -} -*/ - - // For array structure: (No. showers, No. points, dimensions(4)) void PionCloudsModel::convertOutput(G4FastTrack const& aFastTrack, G4ThreeVector const& localDir, @@ -120,8 +70,6 @@ void PionCloudsModel::convertOutput(G4FastTrack const& aFastTrack, int layerNum = 0; - /// This is too C-like - use std::vector - //float reshaped[m_numPoints][4]; std::vector> reshaped(m_numPoints, std::vector(4)); // Fill the 3D array-like vector using the flattened vector @@ -144,9 +92,6 @@ void PionCloudsModel::convertOutput(G4FastTrack const& aFastTrack, 0. // time ); layerNum = reshaped[i][1]; - //std::cout << "PionCloudsModel::convertOutput - layerNum" << layerNum < Date: Fri, 14 Nov 2025 10:31:51 +0100 Subject: [PATCH 10/36] Add support for hadron shower simulation --- CMakeLists.txt | 2 - include/DDML/DDMLEventAction.h | 70 --- include/DDML/DDMLRunAction.h | 39 -- include/DDML/FastMLShower.h | 45 -- include/DDML/LoadHdf5.h | 3 +- scripts/ddsim_steer.py | 4 +- scripts/ddsim_steer_Record_Calo_entry.py | 657 ----------------------- scripts/test_onnx.mac | 2 +- src/CMakeLists.txt | 16 - src/DDMLEventAction.cc | 58 -- src/DDMLRunAction.cc | 80 --- 11 files changed, 4 insertions(+), 972 deletions(-) delete mode 100644 include/DDML/DDMLEventAction.h delete mode 100644 include/DDML/DDMLRunAction.h delete mode 100644 scripts/ddsim_steer_Record_Calo_entry.py delete mode 100644 src/DDMLEventAction.cc delete mode 100644 src/DDMLRunAction.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index d6567a9..2d887d0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,8 +58,6 @@ endif() option(INSTRUMENT_MODEL "Instrument the steps of the showerModel call" OFF) -option(RECORD_CALO_IMPACT "Record properties of particle that triggers modelShower call" OFF) - option(DOWNLOAD_MODELS "Download and install the models that are stored externally" ON) #--------------------------------------------------- diff --git a/include/DDML/DDMLEventAction.h b/include/DDML/DDMLEventAction.h deleted file mode 100644 index 1aa857c..0000000 --- a/include/DDML/DDMLEventAction.h +++ /dev/null @@ -1,70 +0,0 @@ -#include // for G4int, G4double -#include // for vector -#include "G4UserEventAction.hh" // for G4UserEventAction -//#include "G4Timer.hh" // for G4Timer -class G4Event; -#include "DDG4/Geant4Handle.h" -#include "DDG4/Geant4Kernel.h" -#include "DDG4/Geant4EventAction.h" -#include "CLHEP/Units/SystemOfUnits.h" -#include "CLHEP/Units/PhysicalConstants.h" - - -namespace ddml { - -/** Event action for ddml. -* -* @author P. McKeown, CERN -* @date Feb 2025 -* -*/ - -class DDMLEventAction: public dd4hep::sim::Geant4EventAction{ -public: - /// Standard constructor with initializing arguments - DDMLEventAction(dd4hep::sim::Geant4Context* c, const std::string& n); - /// Default destructor - virtual ~DDMLEventAction(); - /// begin-of-event callback - inline virtual void begin(const G4Event*) override; - /// End-of-event callback - virtual void end(const G4Event*) override; - /// begin-of-run callback - void beginRun(const G4Run*); - /// End-of-run callback - void endRun(const G4Run*); - - //// Get and Set methods for Calo Face info - inline std::vector& GetCaloMC_PDG() {return m_CaloMCPDG;} - inline std::vector& GetCaloMC_E() {return m_CaloMCE;} - inline std::vector& GetCaloMC_PosX() {return m_CaloMCPosX;} - inline std::vector& GetCaloMC_PosY() {return m_CaloMCPosY;} - inline std::vector& GetCaloMC_PosZ() {return m_CaloMCPosZ;} - inline std::vector& GetCaloMC_DirX() {return m_CaloMCDirX;} - inline std::vector& GetCaloMC_DirY() {return m_CaloMCDirY;} - inline std::vector& GetCaloMC_DirZ() {return m_CaloMCDirZ;} - - // Set methods to push back vector - inline void SetElCaloMC_PDG(G4int aValue) {m_CaloMCPDG.push_back(aValue);} - inline void SetElCaloMC_E(G4double aValue) {m_CaloMCE.push_back(aValue);} - inline void SetElCaloMC_PosX(G4double aValue) {m_CaloMCPosX.push_back(aValue);} - inline void SetElCaloMC_PosY(G4double aValue) {m_CaloMCPosY.push_back(aValue);} - inline void SetElCaloMC_PosZ(G4double aValue) {m_CaloMCPosZ.push_back(aValue);} - inline void SetElCaloMC_DirX(G4double aValue) {m_CaloMCDirX.push_back(aValue);} - inline void SetElCaloMC_DirY(G4double aValue) {m_CaloMCDirY.push_back(aValue);} - inline void SetElCaloMC_DirZ(G4double aValue) {m_CaloMCDirZ.push_back(aValue);} - -private: - // Fast Sim Calo entrace particle properties to store in ntuple - std::vector m_CaloMCPDG; - std::vector m_CaloMCE; - std::vector m_CaloMCPosX; - std::vector m_CaloMCPosY; - std::vector m_CaloMCPosZ; - std::vector m_CaloMCDirX; - std::vector m_CaloMCDirY; - std::vector m_CaloMCDirZ; -}; - -} //namespace - diff --git a/include/DDML/DDMLRunAction.h b/include/DDML/DDMLRunAction.h deleted file mode 100644 index 49c5dc6..0000000 --- a/include/DDML/DDMLRunAction.h +++ /dev/null @@ -1,39 +0,0 @@ -#include // for GeV -#include // for G4String -#include // for G4ThreeVector -#include // for G4int -//#include "G4Timer.hh" // for G4Timer -class G4ParticleDefinition; -#include "DDG4/Geant4Handle.h" -#include "DDG4/Geant4Kernel.h" -#include "DDG4/Geant4RunAction.h" - - - -namespace ddml{ -/* Create analysis files in standard G4 manner -* -* @author P. McKeown -* @date Feb 2025 -* -*/ - -class DDMLRunAction: public dd4hep::sim::Geant4RunAction { - public: - DDMLRunAction() = delete; - /// Standard constructor with initializing arguments - DDMLRunAction(dd4hep::sim::Geant4Context* c, const std::string& n) ; - /// Default destructor - virtual ~DDMLRunAction() ; - /// begin-of-run callback - void begin(const G4Run*) override; - /// End-of-run callback - void end(const G4Run*) override; - /// begin-of-event callback - void beginEvent(const G4Event*) ; - /// End-of-event callback - void endEvent(const G4Event*) ; - -}; - -} // namespace \ No newline at end of file diff --git a/include/DDML/FastMLShower.h b/include/DDML/FastMLShower.h index 0615eb2..e48a35a 100644 --- a/include/DDML/FastMLShower.h +++ b/include/DDML/FastMLShower.h @@ -14,10 +14,6 @@ #define DDML_INSTRUMENT_MODEL_SHOWER 0 #endif -#ifndef DDML_RECORD_CALO_IMPACT - #define DDML_RECORD_CALO_IMPACT 0 -#endif - #if DDML_INSTRUMENT_MODEL_SHOWER #include "podio/Frame.h" #include "podio/ROOTFrameWriter.h" @@ -39,12 +35,6 @@ inline auto run_void_member_timed(Obj& obj, MemberFunc func, Args&&... args) { } #endif -#if DDML_RECORD_CALO_IMPACT - //#include "G4EventManager.hh" - //#include "DDML/DDMLEventAction.h" - #include "G4AnalysisManager.hh" -#endif - namespace ddml { /** The templated base class for running fast shower simulation with ML. * The actual implementation is provided by the templated class @@ -154,41 +144,6 @@ class FastMLShower : public dd4hep::sim::Geant4FastSimShowerModel { podio::UserDataCollection nHits; #endif -#if DDML_RECORD_CALO_IMPACT - // Create analysis manager - G4AnalysisManager* analysisManager = G4AnalysisManager::Instance(); - - // Store information about particle impact on calorimter face from track - G4int PDG = track.GetPrimaryTrack()->GetParticleDefinition()->GetPDGEncoding(); - G4ThreeVector position = track.GetPrimaryTrack()->GetPosition(); - G4ThreeVector direction = track.GetPrimaryTrack()->GetMomentumDirection(); - - // Fill analysis manager - analysisManager->FillNtupleIColumn(1, 0, PDG); - analysisManager->FillNtupleDColumn(1, 1, energy); - analysisManager->FillNtupleDColumn(1, 2, position.x()); - analysisManager->FillNtupleDColumn(1, 3, position.y()); - analysisManager->FillNtupleDColumn(1, 4, position.z()); - analysisManager->FillNtupleDColumn(1, 5, direction.x()); - analysisManager->FillNtupleDColumn(1, 6, direction.y()); - analysisManager->FillNtupleDColumn(1, 7, direction.z()); - - analysisManager->AddNtupleRow(1); - - /* - DDMLEventAction* mEventAction = dynamic_cast(G4EventManager::GetEventManager()->GetUserEventAction()); - mEventAction->SetElCaloMC_PDG(PDG); - mEventAction->SetElCaloMC_E(energy); - mEventAction->SetElCaloMC_PosX(position.x()); - mEventAction->SetElCaloMC_PosY(position.y()); - mEventAction->SetElCaloMC_PosZ(position.z()); - mEventAction->SetElCaloMC_DirX(direction.x()); - mEventAction->SetElCaloMC_DirY(direction.y()); - mEventAction->SetElCaloMC_DirZ(direction.z()); - */ - -#endif - for (auto& invec : m_input) { invec.clear(); } diff --git a/include/DDML/LoadHdf5.h b/include/DDML/LoadHdf5.h index 7fdfd44..74bdf02 100644 --- a/include/DDML/LoadHdf5.h +++ b/include/DDML/LoadHdf5.h @@ -49,8 +49,7 @@ class LoadHdf5 : public InferenceInterface { std::vector m_library{}; // shower library dimensions - std::vector m_dimsOut{}; // This is a hot fix for older HDF5 versions! - //std::vector m_dimsOut{}; + std::vector m_dimsOut{}; // properties for plugin std::string m_filePath = {}; diff --git a/scripts/ddsim_steer.py b/scripts/ddsim_steer.py index 6d24a50..3b7b3b7 100644 --- a/scripts/ddsim_steer.py +++ b/scripts/ddsim_steer.py @@ -547,7 +547,7 @@ def LoadHdf5(kernel): if hadrons == True: ml_model_had = "LoadHDF5PionCloudsPCHadronModelPolyhedraBarrel/BarrelModelTorch" - ml_had_file = "../models/PionClouds_50GeV_sp.h5" + ml_had_file = "../models/PionClouds_50GeV_sp_scaled.h5" ml_correct_angles = False from g4units import GeV, MeV # DO NOT REMOVE OR MOVE!!!!! (EXCLAMATION MARK) @@ -658,4 +658,4 @@ def LoadHdf5(kernel): # SIM.physics.setupUserPhysics( aiDance) SIM.physics.setupUserPhysics(aiDanceTorch) -# SIM.physics.setupUserPhysics(LoadHdf5) +#SIM.physics.setupUserPhysics(LoadHdf5) diff --git a/scripts/ddsim_steer_Record_Calo_entry.py b/scripts/ddsim_steer_Record_Calo_entry.py deleted file mode 100644 index 1f21c95..0000000 --- a/scripts/ddsim_steer_Record_Calo_entry.py +++ /dev/null @@ -1,657 +0,0 @@ -###################################################################### -# -# standard steering file for ILD simulation -# -# -# -###################################################################### -from DDSim.DD4hepSimulation import DD4hepSimulation -import DDG4 -from g4units import m, mm, GeV, MeV, rad -import os - -SIM = DD4hepSimulation() - -## The compact XML file -SIM.compactFile = "" -## Lorentz boost for the crossing angle, in radian! -SIM.crossingAngleBoost = 7.0e-3 * rad -SIM.enableDetailedShowerMode = True -SIM.enableG4GPS = True -SIM.enableG4Gun = False -SIM.enableGun = False -## InputFiles for simulation .stdhep, .slcio, .HEPEvt, .hepevt, .hepmc, .pairs files are supported -SIM.inputFiles = [] -## Macro file to execute for runType 'run' or 'vis' -SIM.macroFile = "./test_onnx.mac" -## number of events to simulate, used in batch mode -SIM.numberOfEvents = 100 -## Outputfile from the simulation,only lcio output is supported -# SIM.outputFile = "dummyOutput_edm4hep.root" ##"dummyOutput.slcio" -SIM.outputFile = "dummyOutput.slcio" - -## Physics list to use in simulation -SIM.physicsList = None -## Verbosity use integers from 1(most) to 7(least) verbose -## or strings: VERBOSE, DEBUG, INFO, WARNING, ERROR, FATAL, ALWAYS -SIM.printLevel = "INFO" -## The type of action to do in this invocation -## batch: just simulate some events, needs numberOfEvents, and input file or gun -## vis: enable visualisation, run the macroFile if it is set -## run: run the macroFile and exit -## shell: enable interactive session -SIM.runType = "run" # "batch" -## Skip first N events when reading a file -SIM.skipNEvents = 0 -## Steering file to change default behaviour -SIM.steeringFile = None -## FourVector of translation for the Smearing of the Vertex position: x y z t -SIM.vertexOffset = [0.0, 0.0, 0.0, 0.0] -## FourVector of the Sigma for the Smearing of the Vertex position: x y z t -SIM.vertexSigma = [0.0, 0.0, 0.0, 0.0] - - -################################################################################ -## Action holding sensitive detector actions -## The default tracker and calorimeter actions can be set with -## -## >>> SIM = DD4hepSimulation() -## >>> SIM.action.tracker = ('Geant4TrackerWeightedAction', {'HitPositionCombination': 2, 'CollectSingleDeposits': False}) -## >>> SIM.action.calo = "Geant4CalorimeterAction" -## -## for specific subdetectors specific sensitive detectors can be set based on pattern matching -## -## >>> SIM = DD4hepSimulation() -## >>> SIM.action.mapActions['tpc'] = "TPCSDAction" -## -## and additional parameters for the sensitive detectors can be set when the map is given a tuple -## -## >>> SIM = DD4hepSimulation() -## >>> SIM.action.mapActions['ecal'] =( "CaloPreShowerSDAction", {"FirstLayerNumber": 1} ) -## -## -################################################################################ - -## set the default calorimeter action -SIM.action.calo = "Geant4ScintillatorCalorimeterAction" - -## create a map of patterns and actions to be applied to sensitive detectors -## example: SIM.action.mapActions['tpc'] = "TPCSDAction" -SIM.action.mapActions = {} - -SIM.action.mapActions["tpc"] = "TPCSDAction" - -## set the default tracker action -SIM.action.tracker = ( - "Geant4TrackerWeightedAction", - {"HitPositionCombination": 2, "CollectSingleDeposits": False}, -) - -### Configure Run actions -kernel = DDG4.Kernel() -run1 = DDG4.RunAction(kernel, 'DDMLRunAction/runaction') -kernel.registerGlobalAction(run1) -kernel.runAction().add(run1) -event1 = DDG4.EventAction(kernel, 'DDMLEventAction/eventaction') -kernel.registerGlobalAction(event1) -kernel.eventAction().add(event1) - -################################################################################ -## Configuration for the magnetic field (stepper) -################################################################################ -## --- used in v01-19-05 : -SIM.field.delta_chord = 1e-05 -SIM.field.delta_intersection = 1e-05 -SIM.field.delta_one_step = 0.5e-03 * mm -SIM.field.eps_max = 1e-04 -SIM.field.eps_min = 1e-05 -SIM.field.equation = "Mag_UsualEqRhs" -SIM.field.largest_step = 10.0 * m -SIM.field.min_chord_step = 1.0e-2 * mm -SIM.field.stepper = "HelixSimpleRunge" - -## --- default values in ddsim -##SIM.field.delta_chord = 0.25 -##SIM.field.delta_intersection = 0.001 -##SIM.field.delta_one_step = 0.01 -##SIM.field.eps_max = 0.001 -##SIM.field.eps_min = 5e-05 -##SIM.field.equation = "Mag_UsualEqRhs" -##SIM.field.largest_step = 10000.0 -##SIM.field.min_chord_step = 0.01 -##SIM.field.stepper = "G4ClassicalRK4" - -################################################################################ -## Configuration for sensitive detector filters -## -## Set the default filter for tracker or caliromter -## >>> SIM.filter.tracker = "edep1kev" -## >>> SIM.filter.calo = "" -## -## Assign a filter to a sensitive detector via pattern matching -## >>> SIM.filter.mapDetFilter['FTD'] = "edep1kev" -## -## Or more than one filter: -## >>> SIM.filter.mapDetFilter['FTD'] = ["edep1kev", "geantino"] -## -## Don't use the default filter or anything else: -## >>> SIM.filter.mapDetFilter['TPC'] = None ## or "" or [] -## -## Create a custom filter. The dictionary is used to instantiate the filter later on -## >>> SIM.filter.filters['edep3kev'] = dict(name="EnergyDepositMinimumCut/3keV", parameter={"Cut": 3.0*keV} ) -## -## -################################################################################ - -## default filter for calorimeter sensitive detectors; this is applied if no other filter is used for a calorimeter -SIM.filter.calo = "edep0" - -## list of filter objects: map between name and parameter dictionary -SIM.filter.filters = { - "edep0": {"parameter": {"Cut": 0.0}, "name": "EnergyDepositMinimumCut/Cut0"}, - "geantino": {"parameter": {}, "name": "GeantinoRejectFilter/GeantinoRejector"}, - "edep1kev": {"parameter": {"Cut": 0.001}, "name": "EnergyDepositMinimumCut"}, -} - -## a map between patterns and filter objects, using patterns to attach filters to sensitive detector -SIM.filter.mapDetFilter = {} - -SIM.filter.mapDetFilter["TPC"] = None - -## default filter for tracking sensitive detectors; this is applied if no other filter is used for a tracker -SIM.filter.tracker = "edep1kev" - - -################################################################################ -## Configuration for the GuineaPig InputFiles -################################################################################ - -## Set the number of pair particles to simulate per event. -## Only used if inputFile ends with ".pairs" -## If "-1" all particles will be simulated in a single event -## -SIM.guineapig.particlesPerEvent = "-1" - - -################################################################################ -## Configuration for the DDG4 ParticleGun -################################################################################ - -## direction of the particle gun, 3 vector -SIM.gun.direction = (0, 0, 1) - -## choose the distribution of the random direction for theta -## -## Options for random distributions: -## -## 'uniform' is the default distribution, flat in theta -## 'cos(theta)' is flat in cos(theta) -## 'eta', or 'pseudorapidity' is flat in pseudorapity -## 'ffbar' is distributed according to 1+cos^2(theta) -## -## Setting a distribution will set isotrop = True -## -SIM.gun.distribution = None -SIM.gun.energy = 10000.0 - -## isotropic distribution for the particle gun -## -## use the options phiMin, phiMax, thetaMin, and thetaMax to limit the range of randomly distributed directions -## if one of these options is not None the random distribution will be set to True and cannot be turned off! -## -SIM.gun.isotrop = False -SIM.gun.multiplicity = 1 -SIM.gun.particle = "mu-" -SIM.gun.phiMax = None - -## Minimal azimuthal angle for random distribution -SIM.gun.phiMin = None - -## position of the particle gun, 3 vector -SIM.gun.position = (0.0, 0.0, 0.0) -SIM.gun.thetaMax = None -SIM.gun.thetaMin = None - - -################################################################################ -## Configuration for the output levels of DDG4 components -################################################################################ - -## Output level for input sources -SIM.output.inputStage = 3 - -## Output level for Geant4 kernel -SIM.output.kernel = 3 - -## Output level for ParticleHandler -SIM.output.part = 3 - -## Output level for Random Number Generator setup -SIM.output.random = 6 - - -################################################################################ -## Configuration for the Particle Handler/ MCTruth treatment -################################################################################ - -## Enable lots of printout on simulated hits and MC-truth information -SIM.part.enableDetailedHitsAndParticleInfo = False - -## Keep all created particles -SIM.part.keepAllParticles = False - -## Minimal distance between particle vertex and endpoint of parent after -## which the vertexIsNotEndpointOfParent flag is set -## -SIM.part.minDistToParentVertex = 2.2e-14 - -## MinimalKineticEnergy to store particles created in the tracking region -SIM.part.minimalKineticEnergy = 1 * MeV - -## Printout at End of Tracking -SIM.part.printEndTracking = False - -## Printout at Start of Tracking -SIM.part.printStartTracking = False - -## List of processes to save, on command line give as whitespace separated string in quotation marks -SIM.part.saveProcesses = ["Decay"] - - -################################################################################ -## Configuration for the PhysicsList -################################################################################ -# this needs to be set to False if any standard physics list is used: -SIM.physics.decays = False -SIM.physics.list = "QGSP_BERT" # "FTFP_BERT" - -## location of particle.tbl file containing extra particles and their lifetime information -## -SIM.physics.pdgfile = os.path.join( - os.environ.get("DD4HEP"), "DDG4/examples/particle.tbl" -) - -## The global geant4 rangecut for secondary production -## -## Default is 0.7 mm as is the case in geant4 10 -## -## To disable this plugin and be absolutely sure to use the Geant4 default range cut use "None" -## -## Set printlevel to DEBUG to see a printout of all range cuts, -## but this only works if range cut is not "None" -## -SIM.physics.rangecut = 0.1 * mm - - -################################################################################ -## Properties for the random number generator -################################################################################ - -## If True, calculate random seed for each event based on eventID and runID -## allows reproducibility even when SkippingEvents -SIM.random.enableEventSeed = True #False -SIM.random.file = None -SIM.random.luxury = 1 -SIM.random.replace_gRandom = True -SIM.random.seed = 42 #None -SIM.random.type = None - -# --------------------------------------------- -# -# Configure ML inference -# -# --------------------------------------------- - - -def aiDance(kernel): - ild = True - par04 = True # False - old_DD4hep = False ## use for DD4hep versions/commits before ~ Apr 21st 2023 - - if ild == True: - ml_barrel_name = "EcalBarrel" - ml_barrel_symmetry = 8 - ml_endcap_name = "EcalEndcap" - else: - ml_barrel_name = "ECalBarrel" - ml_barrel_symmetry = 12 - ml_endcap_name = "ECalEndcap" - - if par04 == True: - ml_file = "../models/Generator.onnx" - ml_model = "Par04ExampleVAEPolyhedraBarrelONNXModel/ShowerModel" - ml_model1 = "Par04ExampleVAEEndcapONNXModel/ShowerModel" - else: - ml_file = "../models/francisca_gan.onnx" - ml_model = "RegularGridGANPolyhedraBarrelONNXModel/ShowerModel" - ml_model1 = "RegularGridGANEndcapONNXModel/ShowerModel" - - ml_correct_angles = True - - from g4units import GeV, MeV # DO NOT REMOVE OR MOVE!!!!! (EXCLAMATION MARK) - from DDG4 import DetectorConstruction, Geant4, PhysicsList - - geant4 = Geant4(kernel) - seq = geant4.detectorConstruction() - - if old_DD4hep: # this is now done in DD4hepSimulations.py, i.e. in ddsim - seq, act = geant4.addDetectorConstruction( - "Geant4DetectorGeometryConstruction/ConstructGeo" - ) - act.DebugMaterials = True - act.DebugElements = False - act.DebugVolumes = True - act.DebugShapes = True - # Apply sensitive detectors - sensitives = DetectorConstruction( - kernel, str("Geant4DetectorSensitivesConstruction/ConstructSD") - ) - sensitives.enableUI() - seq.adopt(sensitives) - - # ----------------- - model = DetectorConstruction(kernel, str(ml_model)) - - ## # Mandatory model parameters - model.RegionName = "EcalBarrelRegion" - model.Detector = ml_barrel_name - model.Symmetry = ml_barrel_symmetry - model.Enable = True - model.CorrectForAngles = ml_correct_angles - # Energy boundaries are optional: Units are GeV - model.ApplicableParticles = {"e+", "e-", "gamma"} - model.Etrigger = {"e+": 5.0 * GeV, "e-": 5.0 * GeV, "gamma": 5.0 * GeV} - model.ModelPath = ml_file - model.OptimizeFlag = 1 - - model.enableUI() - seq.adopt(model) - # ------------------- - model1 = DetectorConstruction(kernel, str(ml_model1)) - - ## # Mandatory model parameters - model1.RegionName = "EcalEndcapRegion" - model1.Detector = ml_endcap_name - model1.Enable = True - model1.CorrectForAngles = ml_correct_angles - # Energy boundaries are optional: Units are GeV - model1.ApplicableParticles = {"e+", "e-", "gamma"} - model1.Etrigger = {"e+": 5.0 * GeV, "e-": 5.0 * GeV, "gamma": 5.0 * GeV} - model1.ModelPath = ml_file - model.OptimizeFlag = 1 - - model1.enableUI() - seq.adopt(model1) - # ------------------- - - # Now build the physics list: - phys = kernel.physicsList() - ph = PhysicsList(kernel, str("Geant4FastPhysics/FastPhysicsList")) - ph.EnabledParticles = ["e+", "e-", "gamma"] - ph.BeVerbose = True - ph.enableUI() - phys.adopt(ph) - phys.dump() - - -def aiDanceTorch(kernel): - ild = True - BIBAE = True - Two_Angle = True #True - old_DD4hep = False ## use for DD4hep versions/commits before ~ Apr 21st 2023 - - if ild == True: - ml_barrel_name = "EcalBarrel" - ml_barrel_symmetry = 8 - ml_endcap_name = "EcalEndcap" - else: - ml_barrel_name = "ECalBarrel" - ml_barrel_symmetry = 12 - ml_endcap_name = "ECalEndcap" - - if BIBAE == True and Two_Angle == False: - ml_file = "../models/BIBAE_Full_PP_cut.pt" - ml_model = "RegularGridBIBAEPolyhedraBarrelTorchModel/BarrelModelTorch" - ml_model_1 = "RegularGridBIBAEEndcapTorchModel/EndcapModelTorch" - ml_correct_angles = False - elif BIBAE == True and Two_Angle == True: - ml_file = "../models/BIBAE_Two_Angle_Full_PP_cut.pt" - ml_model = ( - "RegularGridTwoAngleBIBAEModelPolyhedraBarrelTorchModel/BarrelModelTorch" - ) - ml_model_1 = "RegularGridTwoAngleBIBAEModelEndcapTorchModel/EndcapModelTorch" - ml_correct_angles = False - else: - ml_file = "../models/francisca_gan_jit.pt" - ml_model = "RegularGridGANPolyhedraBarrelTorchModel/BarrelModelTorch" - ml_model_1 = "RegularGridGANEndcapTorchModel/EndcapModelTorch" - ml_correct_angles = True - - from g4units import GeV, MeV # DO NOT REMOVE OR MOVE!!!!! (EXCLAMATION MARK) - from DDG4 import DetectorConstruction, Geant4, PhysicsList - - geant4 = Geant4(kernel) - - seq = geant4.detectorConstruction() - - if old_DD4hep: # this is now done in DD4hepSimulations.py, i.e. in ddsim - seq, act = geant4.addDetectorConstruction( - "Geant4DetectorGeometryConstruction/ConstructGeo" - ) - act.DebugMaterials = True - act.DebugElements = False - act.DebugVolumes = True - act.DebugShapes = True - - # Apply sensitive detectors - sensitives = DetectorConstruction( - kernel, str("Geant4DetectorSensitivesConstruction/ConstructSD") - ) - sensitives.enableUI() - seq.adopt(sensitives) - - # ----------------- - model = DetectorConstruction(kernel, str(ml_model)) - - ## # Mandatory model parameters - model.RegionName = "EcalBarrelRegion" - model.Detector = ml_barrel_name - model.Symmetry = ml_barrel_symmetry - model.Enable = True - model.CorrectForAngles = ml_correct_angles - # Energy boundaries are optional: Units are GeV - model.ApplicableParticles = {"e+", "e-", "gamma"} - model.Etrigger = { - "e+": 10.0 * GeV, - "e-": 10.0 * GeV, - "gamma": 10.0 * GeV, - } # trigger on lower training threshold - model.ModelPath = ml_file - model.OptimizeFlag = 1 - model.IntraOpNumThreads = 1 - - model.enableUI() - seq.adopt(model) - # ------------------- - model1 = DetectorConstruction(kernel, str(ml_model_1)) - - ## # Mandatory model parameters - model1.RegionName = "EcalEndcapRegion" - model1.Detector = ml_endcap_name - model1.Enable = True - model1.CorrectForAngles = ml_correct_angles - # Energy boundaries are optional: Units are GeV - model1.ApplicableParticles = {"e+", "e-", "gamma"} - model1.Etrigger = { - "e+": 10.0 * GeV, - "e-": 10.0 * GeV, - "gamma": 10.0 * GeV, - } # trigger on lower training threshold - model1.ModelPath = ml_file - model1.OptimizeFlag = 1 - model1.IntraOpNumThreads = 1 - - model1.enableUI() - seq.adopt(model1) - # ------------------- - - # Now build the physics list: - phys = kernel.physicsList() - ph = PhysicsList(kernel, str("Geant4FastPhysics/FastPhysicsList")) - ph.EnabledParticles = ["e+", "e-", "gamma"] - ph.BeVerbose = True - ph.enableUI() - phys.adopt(ph) - phys.dump() - - -def LoadHdf5(kernel): - ild = True - BIBAE = True - Two_Angle = True - old_DD4hep = False ## use for DD4hep versions/commits before ~ Apr 21st 2023 - hadrons = True - - if ild == True: - ml_barrel_name = "EcalBarrel" - ml_barrel_symmetry = 8 - ml_endcap_name = "EcalEndcap" - - ## For hadron shower fast simulation - ml_had_barrel_name = "HcalBarrel" - ml_had_barrel_symmetry = 8 - ml_had_endcap_name = "HcalEndcap" - - else: - ml_barrel_name = "ECalBarrel" - ml_barrel_symmetry = 12 - ml_endcap_name = "ECalEndcap" - - ## For hadron shower fast simulation is needed - ml_had_barrel_name = "HCalBarrel" - ml_had_barrel_symmetry = 12 - ml_had_endcap_name = "HCalEndcap" - - if BIBAE == True and Two_Angle == True: - ml_file = "../models/photons-E5050A-theta9090A-phi9090-p1.hdf5" - ml_model = ( - "LoadHDF5RegularGridTwoAngleBIBAEModelPolyhedraBarrel/BarrelModelTorch" - ) - ml_model_1 = "LoadHDF5RegularGridTwoAngleBIBAEModelEndcap/EndcapModelTorch" - ml_correct_angles = False - - if hadrons == True: - ml_model_had = "LoadHDF5PionCloudsPCHadronModelPolyhedraBarrel/BarrelModelTorch" - ml_had_file = "../models/PionClouds_50GeV_sp_scaled.h5" #"../models/gen_showers_for_reco_50GeV_2000.hdf5" - #"../models/gen_showers_50GeV_2000_Martina.hdf5" #"../models/PionClouds_50GeV_sp_scaled.h5" #"../models/PionClouds_50GeV_sp.h5" # - ml_correct_angles = False - - from g4units import GeV, MeV # DO NOT REMOVE OR MOVE!!!!! (EXCLAMATION MARK) - from DDG4 import DetectorConstruction, Geant4, PhysicsList - - geant4 = Geant4(kernel) - - seq = geant4.detectorConstruction() - - if old_DD4hep: # this is now done in DD4hepSimulations.py, i.e. in ddsim - seq, act = geant4.addDetectorConstruction( - "Geant4DetectorGeometryConstruction/ConstructGeo" - ) - act.DebugMaterials = True - act.DebugElements = False - act.DebugVolumes = True - act.DebugShapes = True - - # Apply sensitive detectors - sensitives = DetectorConstruction( - kernel, str("Geant4DetectorSensitivesConstruction/ConstructSD") - ) - sensitives.enableUI() - seq.adopt(sensitives) - - # ----------------- - ''' - ## EM in Barrel - model = DetectorConstruction(kernel, str(ml_model)) - - ## # Mandatory model parameters - model.RegionName = "EcalBarrelRegion" - model.Detector = ml_barrel_name - model.Symmetry = ml_barrel_symmetry - model.Enable = True - model.CorrectForAngles = ml_correct_angles - # Energy boundaries are optional: Units are GeV - model.ApplicableParticles = {"e+", "e-", "gamma"} - model.Etrigger = { - "e+": 10.0 * GeV, - "e-": 10.0 * GeV, - "gamma": 10.0 * GeV, - } # trigger on lower training threshold - model.FilePath = ml_file - # model.OptimizeFlag = 1 - # model.IntraOpNumThreads = 1 - - model.enableUI() - seq.adopt(model) - ''' - # ------------------- - ## EM in Endcap - model1 = DetectorConstruction(kernel, str(ml_model_1)) - - ## # Mandatory model parameters - model1.RegionName = "EcalEndcapRegion" - model1.Detector = ml_endcap_name - model1.Enable = True - model1.CorrectForAngles = ml_correct_angles - # Energy boundaries are optional: Units are GeV - model1.ApplicableParticles = {"e+", "e-", "gamma"} - model1.Etrigger = { - "e+": 10.0 * GeV, - "e-": 10.0 * GeV, - "gamma": 10.0 * GeV, - } # trigger on lower training threshold - model1.FilePath = ml_file - # model1.OptimizeFlag = 1 - # model1.IntraOpNumThreads = 1 - - model1.enableUI() - seq.adopt(model1) - - # ------------------- - ## Hadrons in Barrel - modelHad1 = DetectorConstruction(kernel, str(ml_model_had)) - - ## # Mandatory model parameters - modelHad1.isHadShower = True - modelHad1.RegionName = "EcalBarrelRegion" #or "HcalBarrelRegion" ## hadron model triggers in ecal - modelHad1.Detector = ml_barrel_name - modelHad1.HadDetector = ml_had_barrel_name - modelHad1.Symmetry = ml_barrel_symmetry - modelHad1.HadSymmetry = ml_had_barrel_symmetry - modelHad1.Enable = True - modelHad1.CorrectForAngles = ml_correct_angles - # Energy boundaries are optional: Units are GeV - modelHad1.ApplicableParticles = {"pi+"} - modelHad1.Etrigger = {"pi+": 30.0 * GeV} #{"pi+": 10.0 * GeV} # trigger on lower training threshold - modelHad1.FilePath = ml_had_file - # model.OptimizeFlag = 1 - # model.IntraOpNumThreads = 1 - - modelHad1.enableUI() - seq.adopt(modelHad1) - - # ------------------- - - # Now build the physics list: - phys = kernel.physicsList() - ph = PhysicsList(kernel, str("Geant4FastPhysics/FastPhysicsList")) - ph.EnabledParticles = ["e+", "e-", "gamma", "pi+"] - ph.BeVerbose = True - ph.enableUI() - phys.adopt(ph) - phys.dump() - - -#SIM.physics.setupUserPhysics( aiDance) -#SIM.physics.setupUserPhysics(aiDanceTorch) -SIM.physics.setupUserPhysics(LoadHdf5) diff --git a/scripts/test_onnx.mac b/scripts/test_onnx.mac index a748499..c1f4695 100644 --- a/scripts/test_onnx.mac +++ b/scripts/test_onnx.mac @@ -75,5 +75,5 @@ #/gps/direction 0.1 -0.8 .1 -/run/beamOn 100 #2000 #100 +/run/beamOn 2000 #100 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0a0114c..2882c79 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -35,18 +35,6 @@ if(INSTRUMENT_MODEL) ) endif() -if(RECORD_CALO_IMPACT) - target_sources(${PROJECT_NAME} PRIVATE - DDMLRunAction.cc - DDMLEventAction.cc - ) - target_compile_definitions(${PROJECT_NAME} PUBLIC - DDML_RECORD_CALO_IMPACT=1 - ) -endif() - - - if(OnnxRuntime_FOUND) target_sources(${PROJECT_NAME} PRIVATE ONNXInference.cc @@ -123,10 +111,6 @@ if(HDF5_FOUND) list(APPEND headers ${PROJECT_SOURCE_DIR}/include/DDML/LoadHdf5.h) endif() -if(RECORD_CALO_IMPACT) - list(APPEND headers ${PROJECT_SOURCE_DIR}/include/DDML/DDMLRunAction.h ${PROJECT_SOURCE_DIR}/include/DDML/DDMLEventAction.h) -endif() - #install(FILES # ${headers} # DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) diff --git a/src/DDMLEventAction.cc b/src/DDMLEventAction.cc deleted file mode 100644 index 7decd72..0000000 --- a/src/DDMLEventAction.cc +++ /dev/null @@ -1,58 +0,0 @@ -#include "DDML/DDMLEventAction.h" -#include "G4AnalysisManager.hh" -#include "DD4hep/InstanceCount.h" -#include "G4Event.hh" -#include "G4EventManager.hh" -#include "G4ThreeVector.hh" -#include "G4PrimaryVertex.hh" -#include "G4PrimaryParticle.hh" -#include "DDG4/Geant4Data.h" - -#define DEBUGPRINT 0 - -namespace ddml { - -DDMLEventAction::DDMLEventAction(dd4hep::sim::Geant4Context* c, const std::string& n): -Geant4EventAction(c,n) - { - dd4hep::InstanceCount::increment(this); - } - -/// Default destructor -DDMLEventAction::~DDMLEventAction() { - dd4hep::InstanceCount::decrement(this); - } - -void DDMLEventAction::begin(const G4Event*){} - -void DDMLEventAction::end(const G4Event*) { - // Get analysis manager - auto analysisManager = G4AnalysisManager::Instance(); - - // Retrieve information from primary vertex and primary particle - auto primaryVertex = - G4EventManager::GetEventManager()->GetConstCurrentEvent()->GetPrimaryVertex(); - G4ThreeVector primaryVertexPos = primaryVertex->GetPosition(); - auto primaryParticle = primaryVertex->GetPrimary(0); - G4double primaryEnergy = primaryParticle->GetTotalEnergy(); - G4ThreeVector primaryDirection = primaryParticle->GetMomentumDirection(); - G4int primaryPDG = primaryParticle->GetPDGcode(); - - // Fill analysis manager - analysisManager->FillNtupleIColumn(0, 0, primaryPDG); - analysisManager->FillNtupleDColumn(0, 1, primaryEnergy); - analysisManager->FillNtupleDColumn(0, 2, primaryVertexPos.x()); - analysisManager->FillNtupleDColumn(0, 3, primaryVertexPos.y()); - analysisManager->FillNtupleDColumn(0, 4, primaryVertexPos.z()); - analysisManager->FillNtupleDColumn(0, 5, primaryDirection.x()); - analysisManager->FillNtupleDColumn(0, 6, primaryDirection.y()); - analysisManager->FillNtupleDColumn(0, 7, primaryDirection.z()); - - analysisManager->AddNtupleRow(0); - -} - -} //namespace - -#include "DDG4/Factories.h" -DECLARE_GEANT4ACTION_NS(ddml, DDMLEventAction) diff --git a/src/DDMLRunAction.cc b/src/DDMLRunAction.cc deleted file mode 100644 index 60c92eb..0000000 --- a/src/DDMLRunAction.cc +++ /dev/null @@ -1,80 +0,0 @@ -#include "DDML/DDMLRunAction.h" -#include "DDML/DDMLEventAction.h" -#include "G4AnalysisManager.hh" -#include "G4EventManager.hh" -#include "DD4hep/InstanceCount.h" -#include "G4Run.hh" - -#define DEBUGPRINT 0 - -namespace ddml { - -/// Standard constructor with initializing arguments -DDMLRunAction::DDMLRunAction(dd4hep::sim::Geant4Context* c, const std::string& n): - Geant4RunAction(c, n) { - // Create analysis manager - G4AnalysisManager* analysisManager = G4AnalysisManager::Instance(); - analysisManager->SetDefaultFileType("root"); - - // Default filename, can be overriden with /analysis/setFileName - analysisManager->SetFileName("Output"); - dd4hep::InstanceCount::increment(this); -} - -/// Default destructor -DDMLRunAction::~DDMLRunAction() { - dd4hep::InstanceCount::decrement(this); -} - -/// begin-of-run callback -void DDMLRunAction::begin(const G4Run*) { - // Get analysis manager -G4AnalysisManager* analysisManager = G4AnalysisManager::Instance(); - -// Create directories -analysisManager->SetVerboseLevel(0); - -// Create ntuples -analysisManager->CreateNtuple("global", "Event data"); -analysisManager->CreateNtupleIColumn("MC_PDG"); -analysisManager->CreateNtupleDColumn("MC_Energy"); -analysisManager->CreateNtupleDColumn("MC_PosX"); -analysisManager->CreateNtupleDColumn("MC_PosY"); -analysisManager->CreateNtupleDColumn("MC_PosZ"); -analysisManager->CreateNtupleDColumn("MC_DirX"); -analysisManager->CreateNtupleDColumn("MC_DirY"); -analysisManager->CreateNtupleDColumn("MC_DirZ"); -analysisManager->FinishNtuple(); - -analysisManager->CreateNtuple("Fast_Sim_Info", "MC info at calo face"); -analysisManager->CreateNtupleIColumn("Calo_MC_PDG"); -analysisManager->CreateNtupleDColumn("Calo_MC_Energy"); -analysisManager->CreateNtupleDColumn("Calo_MC_PosX"); -analysisManager->CreateNtupleDColumn("Calo_MC_PosY"); -analysisManager->CreateNtupleDColumn("Calo_MC_PosZ"); -analysisManager->CreateNtupleDColumn("Calo_MC_DirX"); -analysisManager->CreateNtupleDColumn("Calo_MC_DirY"); -analysisManager->CreateNtupleDColumn("Calo_MC_DirZ"); -analysisManager->FinishNtuple(); - - -analysisManager->CreateNtuple("run", "Run data"); -analysisManager->CreateNtupleDColumn("N"); -analysisManager->FinishNtuple(); - -analysisManager->OpenFile(); -} - -/// End-of-run callback -void DDMLRunAction::end(const G4Run* aRun){ - auto analysisManager = G4AnalysisManager::Instance(); - analysisManager->FillNtupleDColumn(2, 0, aRun->GetNumberOfEvent()); - analysisManager->AddNtupleRow(2); - analysisManager->Write(); - analysisManager->CloseFile(); -} - -} // namespace - -#include "DDG4/Factories.h" -DECLARE_GEANT4ACTION_NS(ddml, DDMLRunAction) \ No newline at end of file From a7799db80fa87c97a54652c4ae418829d12d2154 Mon Sep 17 00:00:00 2001 From: Peter McKeown Date: Fri, 14 Nov 2025 10:40:40 +0100 Subject: [PATCH 11/36] Add support for hadron shower simulation --- include/DDML/PionCloudsModel.h | 87 ++++++++++++-------------- include/DDML/PolyhedraBarrelGeometry.h | 4 +- scripts/ddsim_steer.py | 12 ++-- src/Geant4FastHitMakerGlobal.cc | 20 +++--- src/LoadHdf5.cc | 8 +-- src/MLModelActions.cc | 14 ++--- src/PionCloudsModel.cc | 76 ++++++++++------------ src/PolyhedraBarrelGeometry.cc | 12 ++-- 8 files changed, 110 insertions(+), 123 deletions(-) diff --git a/include/DDML/PionCloudsModel.h b/include/DDML/PionCloudsModel.h index 111a602..9b30f2a 100644 --- a/include/DDML/PionCloudsModel.h +++ b/include/DDML/PionCloudsModel.h @@ -1,74 +1,67 @@ #ifndef PionClouds_H #define PionClouds_H -#include "DDML/ModelInterface.h" #include "DDML/FastMLShower.h" - +#include "DDML/ModelInterface.h" namespace ddml { /** Class for running a point cloud based ML model for fast shower simulation. * Assumes a cartesian (x,y) coordinates defining the calorimeter planes (layers) and z the depth * of the calorimeter. - * + * * Based on BiBAETwoAngleModel. - * - * Implemented here for the PionClouds model intended for hadron shower simulation (ECAL+HCAL). - * + * + * Implemented here for the PionClouds model intended for hadron shower simulation (ECAL+HCAL). + * * @author A.Korol, DESY * @author P. McKeown, CERN * @date Feb. 2025 */ - - class PionCloudsModel : public ModelInterface { - - public: - PionCloudsModel() {} ; - - virtual ~PionCloudsModel(){}; - - /// declare the proerties needed for the plugin - void declareProperties(dd4hep::sim::Geant4Action* plugin) { - plugin->declareProperty("LatentVectorSize", this->m_latentSize); - } - - /** prepare the input vector and resize the output vector for this model - * based on the current FastTrack (e.g. extract kinetic energy and incident - * angles.) - */ - virtual void prepareInput(G4FastTrack const& aFastTrack, - G4ThreeVector const& localDir, - InputVecs& inputs, TensorDimVecs& tensDims, - std::vector& output ) ; +class PionCloudsModel : public ModelInterface { +public: + PionCloudsModel(){}; - /** create a vector of spacepoints per layer interpreting the model output - */ - virtual void convertOutput(G4FastTrack const& aFastTrack, - G4ThreeVector const& localDir, - const std::vector& output, - std::vector& spacepoints ) ; + virtual ~PionCloudsModel(){}; + /// declare the proerties needed for the plugin + void declareProperties(dd4hep::sim::Geant4Action* plugin) { + plugin->declareProperty("LatentVectorSize", this->m_latentSize); + } - - private: + /** prepare the input vector and resize the output vector for this model + * based on the current FastTrack (e.g. extract kinetic energy and incident + * angles.) + */ + virtual void prepareInput(G4FastTrack const& aFastTrack, G4ThreeVector const& localDir, InputVecs& inputs, + TensorDimVecs& tensDims, std::vector& output); - /// model properties for plugin - // These grid sizes were used for the two angle BIBAE - int m_numPoints = 2600; //4148; //2600; //number of points in the shower - int m_latentSize = 3; // number of input features (energy, theta, phi) - int m_maxNumElements = m_numPoints*4; // number of space points in the output multiplied by 4 (x,y,z,energy) - int m_nLayer = 78; + /** create a vector of spacepoints per layer interpreting the model output + */ + virtual void convertOutput(G4FastTrack const& aFastTrack, G4ThreeVector const& localDir, + const std::vector& output, std::vector& spacepoints); - struct Vector3d{double x; double y; double z;}; +private: + /// model properties for plugin + // These grid sizes were used for the two angle BIBAE + int m_numPoints = 2600; // 4148; //2600; //number of points in the shower + int m_latentSize = 3; // number of input features (energy, theta, phi) + int m_maxNumElements = m_numPoints * 4; // number of space points in the output multiplied by 4 (x,y,z,energy) + int m_nLayer = 78; - Vector3d crossProduct(const Vector3d& v1, const Vector3d& v2); + struct Vector3d { + double x; + double y; + double z; + }; - Vector3d normalize(const Vector3d& v); + Vector3d crossProduct(const Vector3d& v1, const Vector3d& v2); - TensorDimVecs m_tensDims = {{1, 1}, {1, 1}, {1, 1}, {1, 3}}; - }; + Vector3d normalize(const Vector3d& v); + + TensorDimVecs m_tensDims = {{1, 1}, {1, 1}, {1, 1}, {1, 3}}; +}; } // namespace ddml #endif - diff --git a/include/DDML/PolyhedraBarrelGeometry.h b/include/DDML/PolyhedraBarrelGeometry.h index aa8cedb..a803fe1 100644 --- a/include/DDML/PolyhedraBarrelGeometry.h +++ b/include/DDML/PolyhedraBarrelGeometry.h @@ -12,11 +12,11 @@ namespace ddml { * * @author F.Gaede, DESY * @date Mar 2023 - * + * * Addiional option included to support Hadronic shower simulation in ECAL + HCAL * @author P. McKeown, CERN * @date Feb 2025 - * + * */ class PolyhedraBarrelGeometry : public GeometryInterface { diff --git a/scripts/ddsim_steer.py b/scripts/ddsim_steer.py index 3b7b3b7..287d3f7 100644 --- a/scripts/ddsim_steer.py +++ b/scripts/ddsim_steer.py @@ -547,7 +547,7 @@ def LoadHdf5(kernel): if hadrons == True: ml_model_had = "LoadHDF5PionCloudsPCHadronModelPolyhedraBarrel/BarrelModelTorch" - ml_had_file = "../models/PionClouds_50GeV_sp_scaled.h5" + ml_had_file = "../models/PionClouds_50GeV_sp_scaled.h5" ml_correct_angles = False from g4units import GeV, MeV # DO NOT REMOVE OR MOVE!!!!! (EXCLAMATION MARK) @@ -574,7 +574,7 @@ def LoadHdf5(kernel): seq.adopt(sensitives) # ----------------- - ''' + """ ## EM in Barrel model = DetectorConstruction(kernel, str(ml_model)) @@ -597,7 +597,7 @@ def LoadHdf5(kernel): model.enableUI() seq.adopt(model) - ''' + """ # ------------------- ## EM in Endcap model1 = DetectorConstruction(kernel, str(ml_model_1)) @@ -627,7 +627,9 @@ def LoadHdf5(kernel): ## # Mandatory model parameters modelHad1.isHadShower = True - modelHad1.RegionName = "EcalBarrelRegion" #or "HcalBarrelRegion" ## hadron model triggers in ecal + modelHad1.RegionName = ( + "EcalBarrelRegion" # or "HcalBarrelRegion" ## hadron model triggers in ecal + ) modelHad1.Detector = ml_barrel_name modelHad1.HadDetector = ml_had_barrel_name modelHad1.Symmetry = ml_barrel_symmetry @@ -658,4 +660,4 @@ def LoadHdf5(kernel): # SIM.physics.setupUserPhysics( aiDance) SIM.physics.setupUserPhysics(aiDanceTorch) -#SIM.physics.setupUserPhysics(LoadHdf5) +# SIM.physics.setupUserPhysics(LoadHdf5) diff --git a/src/Geant4FastHitMakerGlobal.cc b/src/Geant4FastHitMakerGlobal.cc index 2395447..445aa19 100644 --- a/src/Geant4FastHitMakerGlobal.cc +++ b/src/Geant4FastHitMakerGlobal.cc @@ -48,10 +48,10 @@ Geant4FastHitMakerGlobal::~Geant4FastHitMakerGlobal() { //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... void Geant4FastHitMakerGlobal::make(const G4FastHit& aHit, const G4FastTrack& aTrack) { - - //std::cout << "Geant4FastHitMakerGlobal::make - aHit.GetPosition().x() " << aHit.GetPosition().x() << " aHit.GetPosition().y() " << - // aHit.GetPosition().y() << " aHit.GetPosition().z() " << aHit.GetPosition().z() << std::endl; - // do not make empty deposit + // std::cout << "Geant4FastHitMakerGlobal::make - aHit.GetPosition().x() " << aHit.GetPosition().x() << " + // aHit.GetPosition().y() " << + // aHit.GetPosition().y() << " aHit.GetPosition().z() " << aHit.GetPosition().z() << std::endl; + // do not make empty deposit if (aHit.GetEnergy() <= 0) { return; } @@ -83,13 +83,17 @@ void Geant4FastHitMakerGlobal::make(const G4FastHit& aHit, const G4FastTrack& aT G4VSensitiveDetector* sensitive; if (currentVolume != 0) { - //std::cout << "IN FULL Sim Sensitive Geant4FastHitMakerGlobal::make - aHit.GetPosition().x() " << aHit.GetPosition().x() << " aHit.GetPosition().y() " << - // aHit.GetPosition().y() << " aHit.GetPosition().z() " << aHit.GetPosition().z() << " Energy: " << aHit.GetEnergy() << std::endl; + // std::cout << "IN FULL Sim Sensitive Geant4FastHitMakerGlobal::make - aHit.GetPosition().x() " << + // aHit.GetPosition().x() << " aHit.GetPosition().y() " << + // aHit.GetPosition().y() << " aHit.GetPosition().z() " << aHit.GetPosition().z() << " Energy: " << + // aHit.GetEnergy() << std::endl; sensitive = currentVolume->GetLogicalVolume()->GetSensitiveDetector(); G4VFastSimSensitiveDetector* fastSimSensitive = dynamic_cast(sensitive); if (fastSimSensitive) { - // std::cout << "IN FAST Sim Sensitive Geant4FastHitMakerGlobal::make - aHit.GetPosition().x() " << aHit.GetPosition().x() << " aHit.GetPosition().y() " << - // aHit.GetPosition().y() << " aHit.GetPosition().z() " << aHit.GetPosition().z() << " Energy: " << aHit.GetEnergy() << std::endl; + // std::cout << "IN FAST Sim Sensitive Geant4FastHitMakerGlobal::make - aHit.GetPosition().x() " << + // aHit.GetPosition().x() << " aHit.GetPosition().y() " << + // aHit.GetPosition().y() << " aHit.GetPosition().z() " << aHit.GetPosition().z() << " Energy: " << + // aHit.GetEnergy() << std::endl; fastSimSensitive->Hit(&aHit, &aTrack, &m_touchableHandle); } else if (sensitive && currentVolume->GetLogicalVolume()->GetFastSimulationManager()) { G4cerr << "ERROR - Geant4FastHitMakerGlobal::make()" << G4endl << " It is required to derive from the " diff --git a/src/LoadHdf5.cc b/src/LoadHdf5.cc index 5007782..c347f31 100644 --- a/src/LoadHdf5.cc +++ b/src/LoadHdf5.cc @@ -19,7 +19,7 @@ void LoadHdf5::initialize() { // inputs and TensorDimVecs unused // Open dataset + dataspace - std::string datasetName = "spase_points"; //"events"; //"spase_points"; //"layers"; + std::string datasetName = "spase_points"; //"events"; //"spase_points"; //"layers"; H5::DataSet dataset = m_file.openDataSet(datasetName); dd4hep::printout(dd4hep::DEBUG, "LoadHdf5::initialize", "Accessed HDF5 dataset"); H5::DataSpace dataspace = dataset.getSpace(); @@ -39,7 +39,7 @@ void LoadHdf5::initialize() { m_dimsOut = dims_out; -// assert(rank == 4); // assuming 4 dimensional input + // assert(rank == 4); // assuming 4 dimensional input // index 0: shower number // index 1, 2, 3: x, y, z cell number @@ -85,7 +85,7 @@ void LoadHdf5::runInference(const InputVecs&, const TensorDimVecs&, std::vector< } // select shower from library - //std::vector shower(m_library.begin() + m_count * m_dimsOut[1] * m_dimsOut[2] * m_dimsOut[3], + // std::vector shower(m_library.begin() + m_count * m_dimsOut[1] * m_dimsOut[2] * m_dimsOut[3], // m_library.begin() + (m_count + 1) * m_dimsOut[1] * m_dimsOut[2] * m_dimsOut[3]); // select shower from library @@ -93,7 +93,7 @@ void LoadHdf5::runInference(const InputVecs&, const TensorDimVecs&, std::vector< m_library.begin() + (m_count + 1) * m_dimsOut[1] * m_dimsOut[2]); // enforce length of shower - //assert(shower.size() == m_dimsOut[1] * m_dimsOut[2] * m_dimsOut[3]); + // assert(shower.size() == m_dimsOut[1] * m_dimsOut[2] * m_dimsOut[3]); assert(shower.size() == m_dimsOut[1] * m_dimsOut[2]); diff --git a/src/MLModelActions.cc b/src/MLModelActions.cc index 5e88b6b..c0ea2bf 100644 --- a/src/MLModelActions.cc +++ b/src/MLModelActions.cc @@ -21,11 +21,11 @@ #include "DDML/L2LFlowsModel.h" #include "DDML/OctogonalBarrelTrigger.h" #include "DDML/Par04ExampleVAE.h" +#include "DDML/PionCloudsModel.h" #include "DDML/PolyhedraBarrelGeometry.h" #include "DDML/RegularGridBIBAEModel.h" #include "DDML/RegularGridGANModel.h" #include "DDML/RegularGridTwoAngleBIBAEModel.h" -#include "DDML/PionCloudsModel.h" #include "DDML/TriggerInterface.h" namespace ddml { @@ -131,18 +131,16 @@ typedef FastMLShower< /// Load from HDF5 file- as an example for Hadron showers from PionClouds // Barrel -typedef FastMLShower> // add ML trigger +typedef FastMLShower< + FastMLModel> // add ML trigger LoadHDF5PionCloudsPCHadronModelPolyhedraBarrel; // Endcap // ENDCAP IS CURRENTLY NOT IMPLEMENTED!!!! -typedef FastMLShower< - FastMLModel> // add ML trigger +typedef FastMLShower> // add ML trigger LoadHDF5PionCloudsPCHadronModelEndcap; #endif - } // namespace ddml #include diff --git a/src/PionCloudsModel.cc b/src/PionCloudsModel.cc index 7604f3a..e08f27d 100644 --- a/src/PionCloudsModel.cc +++ b/src/PionCloudsModel.cc @@ -1,16 +1,13 @@ #include "DDML/PionCloudsModel.h" -#include // for G4FastTrack +#include // for G4FastTrack #define DEBUGPRINT 0 namespace ddml { - void PionCloudsModel::prepareInput(G4FastTrack const& aFastTrack, - G4ThreeVector const& localDir, - InputVecs& inputs, TensorDimVecs& tensDims, - std::vector& output ) { - +void PionCloudsModel::prepareInput(G4FastTrack const& aFastTrack, G4ThreeVector const& localDir, InputVecs& inputs, + TensorDimVecs& tensDims, std::vector& output) { tensDims = m_tensDims; G4double energy = aFastTrack.GetPrimaryTrack()->GetKineticEnergy(); @@ -27,8 +24,8 @@ namespace ddml { localDir_.setX(-1. * localDir_.x()); // *(-1) to align local to global convention in ddml localDir_.setY(-1. * localDir_.y()); // *(-1) to align local to global convention in ddml - dd4hep::printout(dd4hep::DEBUG, "PionCloudsModel::prepareInput", "DDML::localDir: (%f, %f, %f)", - localDir_.x(), localDir_.y(), localDir_.z()); + dd4hep::printout(dd4hep::DEBUG, "PionCloudsModel::prepareInput", "DDML::localDir: (%f, %f, %f)", localDir_.x(), + localDir_.y(), localDir_.z()); // compute local incident angles double r = sqrt(localDir_.x() * localDir_.x() + localDir_.y() * localDir_.y() + localDir_.z() * localDir_.z()); @@ -55,44 +52,39 @@ namespace ddml { dd4hep::printout(dd4hep::DEBUG, "PionCloudsModel::prepareInput", "Input_phi_tensor : %f", inputs[2][0]); // ---- resize output vector - + output.assign(m_maxNumElements, 0); } - // For array structure: (No. showers, No. points, dimensions(4)) -void PionCloudsModel::convertOutput(G4FastTrack const& aFastTrack, - G4ThreeVector const& localDir, - const std::vector& output, - std::vector& spacepoints ){ - - //int nPoints = m_numPoints ; // number of points in shower - - int layerNum = 0; - - std::vector> reshaped(m_numPoints, std::vector(4)); - - // Fill the 3D array-like vector using the flattened vector - int index = 0; - for (int j = 0; j < m_numPoints; ++j) { - for (int k = 0; k < 4; ++k) { - reshaped[j][k] = output[index]; - index++; - } - } - - spacepoints.resize( m_nLayer ) ; - - for (int i = 0; i < m_numPoints; i++) { - ddml::SpacePoint sp( - reshaped[i][0], // x // *(-1) to align local to global convention in ddml - reshaped[i][2], // y // *(-1) to align local to global convention in ddml - 0., // z - reshaped[i][3], // energy - 0. // time +void PionCloudsModel::convertOutput(G4FastTrack const& aFastTrack, G4ThreeVector const& localDir, + const std::vector& output, std::vector& spacepoints) { + // int nPoints = m_numPoints ; // number of points in shower + + int layerNum = 0; + + std::vector> reshaped(m_numPoints, std::vector(4)); + + // Fill the 3D array-like vector using the flattened vector + int index = 0; + for (int j = 0; j < m_numPoints; ++j) { + for (int k = 0; k < 4; ++k) { + reshaped[j][k] = output[index]; + index++; + } + } + + spacepoints.resize(m_nLayer); + + for (int i = 0; i < m_numPoints; i++) { + ddml::SpacePoint sp(reshaped[i][0], // x // *(-1) to align local to global convention in ddml + reshaped[i][2], // y // *(-1) to align local to global convention in ddml + 0., // z + reshaped[i][3], // energy + 0. // time ); layerNum = reshaped[i][1]; - spacepoints[layerNum].emplace_back( sp ) ; - } + spacepoints[layerNum].emplace_back(sp); } -} \ No newline at end of file +} +} // namespace ddml \ No newline at end of file diff --git a/src/PolyhedraBarrelGeometry.cc b/src/PolyhedraBarrelGeometry.cc index f05a35f..37717cc 100644 --- a/src/PolyhedraBarrelGeometry.cc +++ b/src/PolyhedraBarrelGeometry.cc @@ -27,15 +27,14 @@ void PolyhedraBarrelGeometry::initialize() { // For hadronic shower simulation if (m_isHadShower == true) { - auto det_had = theDetector.detector(m_HadDetector); - auto* cal_had = det_had.extension(); + auto det_had = theDetector.detector(m_HadDetector); + auto* cal_had = det_had.extension(); if (cal_had) { for (auto l_had : cal_had->layers) { m_caloLayerDistances.push_back((l_had.distance + l_had.inner_thickness) / dd4hep::mm); std::cout << " HCAL Layer distances " << l_had.distance + l_had.inner_thickness << std::endl; } - } - else { + } else { std::cout << " ###### error: detector " << m_HadDetector << " not found !" << std::endl; } } @@ -186,9 +185,8 @@ void PolyhedraBarrelGeometry::localToGlobal(G4FastTrack const& aFastTrack, sp.Y = global.y(); sp.Z = global.z(); - std::cout << " PolyhedraBarrelGeometry::localToGlobal - global.x() = " << global.x() << " global.y() = " << global.y() - << " global.z() " << global.z() << " Energy: " << sp.E << std::endl; - + std::cout << " PolyhedraBarrelGeometry::localToGlobal - global.x() = " << global.x() + << " global.y() = " << global.y() << " global.z() " << global.z() << " Energy: " << sp.E << std::endl; } } } From f63d6d6c5f535fbb656d84b7c810ccd4b7e80f4a Mon Sep 17 00:00:00 2001 From: Peter McKeown Date: Fri, 8 Nov 2024 17:06:07 +0100 Subject: [PATCH 12/36] initial progress --- include/DDML/PolyhedraBarrelGeometry.h | 4 ++- scripts/ddsim_steer.py | 41 +++++++++++++++++++++++++- src/PolyhedraBarrelGeometry.cc | 14 +++++++++ 3 files changed, 57 insertions(+), 2 deletions(-) diff --git a/include/DDML/PolyhedraBarrelGeometry.h b/include/DDML/PolyhedraBarrelGeometry.h index ee08de2..8dbce2b 100644 --- a/include/DDML/PolyhedraBarrelGeometry.h +++ b/include/DDML/PolyhedraBarrelGeometry.h @@ -27,8 +27,10 @@ class PolyhedraBarrelGeometry : public GeometryInterface { /// declare the proerties needed for the plugin void declareProperties(dd4hep::sim::Geant4Action* plugin) { - plugin->declareProperty("Detector", this->m_detector); + plugin->declareProperty("isHadShower", m_isHadShower) plugin->declareProperty("Detector", this->m_detector); + plugin->declareProperty("HadDetector", this->m_HadDetector); plugin->declareProperty("Symmetry", this->m_nSymmetry); + plugin->declareProperty("HadSymmetry", this->m_nHadSymmetry); plugin->declareProperty("CorrectForAngles", this->m_correctForAngles); } diff --git a/scripts/ddsim_steer.py b/scripts/ddsim_steer.py index 94dec80..5a7ec2b 100644 --- a/scripts/ddsim_steer.py +++ b/scripts/ddsim_steer.py @@ -515,16 +515,28 @@ def LoadHdf5(kernel): BIBAE = True Two_Angle = True old_DD4hep = False ## use for DD4hep versions/commits before ~ Apr 21st 2023 + hadrons = True if ild == True: ml_barrel_name = "EcalBarrel" ml_barrel_symmetry = 8 ml_endcap_name = "EcalEndcap" + + ## For hadron shower fast simulation + ml_had_barrel_name = "HcalBarrel" + ml_had_barrel_symmetry = 8 + ml_had_endcap_name = "HcalEndcap" + else: ml_barrel_name = "ECalBarrel" ml_barrel_symmetry = 12 ml_endcap_name = "ECalEndcap" + ## For hadron shower fast simulation is needed + ml_had_barrel_name = "HCalBarrel" + ml_had_barrel_symmetry = 12 + ml_had_endcap_name = "HCalEndcap" + if BIBAE == True and Two_Angle == True: ml_file = "../models/photons-E5050A-theta9090A-phi9090-p1.hdf5" ml_model = ( @@ -533,6 +545,10 @@ def LoadHdf5(kernel): ml_model_1 = "LoadHDF5RegularGridTwoAngleBIBAEModelEndcap/EndcapModelTorch" ml_correct_angles = False + if hadrons == True: + ml_model_had = "LoadHDF5HadronPointCloudModelPolyhedraBarrel/BarrelModelTorch" + ml_correct_angles = False + from g4units import GeV, MeV # DO NOT REMOVE OR MOVE!!!!! (EXCLAMATION MARK) from DDG4 import DetectorConstruction, Geant4, PhysicsList @@ -557,6 +573,7 @@ def LoadHdf5(kernel): seq.adopt(sensitives) # ----------------- + ## EM in Barrel model = DetectorConstruction(kernel, str(ml_model)) ## # Mandatory model parameters @@ -579,6 +596,7 @@ def LoadHdf5(kernel): model.enableUI() seq.adopt(model) # ------------------- + ## EM in Endcap model1 = DetectorConstruction(kernel, str(ml_model_1)) ## # Mandatory model parameters @@ -599,12 +617,33 @@ def LoadHdf5(kernel): model1.enableUI() seq.adopt(model1) + + # ------------------- + ## Hadrons in Barrel + modelHad1 = DetectorConstruction(kernel, str()) + + ## # Mandatory model parameters + model.isHadShower = True + model.RegionName = "EcalBarrelRegion" ## hadron model triggers in ecal + model.Detector = ml_barrel_name + model.HadDetector = ml_had_barrel_name + model.Symmetry = ml_barrel_symmetry + model.HadSymmetry = ml_had_barrel_symmetry + model.Enable = True + model.CorrectForAngles = ml_correct_angles + # Energy boundaries are optional: Units are GeV + model.ApplicableParticles = {"pi+"} + model.Etrigger = {"pi+": 10.0 * GeV} # trigger on lower training threshold + model.FilePath = ml_file + # model.OptimizeFlag = 1 + # model.IntraOpNumThreads = 1 + # ------------------- # Now build the physics list: phys = kernel.physicsList() ph = PhysicsList(kernel, str("Geant4FastPhysics/FastPhysicsList")) - ph.EnabledParticles = ["e+", "e-", "gamma"] + ph.EnabledParticles = ["e+", "e-", "gamma", "pi+"] ph.BeVerbose = True ph.enableUI() phys.adopt(ph) diff --git a/src/PolyhedraBarrelGeometry.cc b/src/PolyhedraBarrelGeometry.cc index 9b2ef65..f7f4f6a 100644 --- a/src/PolyhedraBarrelGeometry.cc +++ b/src/PolyhedraBarrelGeometry.cc @@ -16,6 +16,12 @@ void PolyhedraBarrelGeometry::initialize() { auto det = theDetector.detector(m_detector); auto* cal = det.extension(); + // For hadronic shower simulation + if (m_isHadShower == true) { + auto det_had = theDetector.detector(m_HadDetector); + auto* cal_had = det_had.extension(); + } + if (cal) { for (auto l : cal->layers) { m_caloLayerDistances.push_back((l.distance + l.inner_thickness) / dd4hep::mm); @@ -23,6 +29,14 @@ void PolyhedraBarrelGeometry::initialize() { } else { std::cout << " ###### error: detector " << m_detector << " not found !" << std::endl; } + + if (m_isHadShower == true) { + if (cal_had) { + for (auto l_had : cal_had->layers) { + m_caloLayerDistances.push_back((l_had.distance + l_had.inner_thickness) / dd4hep::mm); + } + } + } } int PolyhedraBarrelGeometry::phiSector(G4ThreeVector const& position) const { From 59ca43df90eaa32813060e2deaface4ab5f93e14 Mon Sep 17 00:00:00 2001 From: Peter McKeown Date: Tue, 19 Nov 2024 22:59:33 +0100 Subject: [PATCH 13/36] Loading and placement in ECAL successful, pending correct placement in HCAL --- include/DDML/PolyhedraBarrelGeometry.h | 6 +++++- scripts/ddsim_steer.py | 30 +++++++++++++++----------- scripts/test_onnx.mac | 6 +++--- src/CMakeLists.txt | 2 ++ src/LoadHdf5.cc | 21 +++++++++++++----- src/MLModelActions.cc | 16 ++++++++++++++ src/PolyhedraBarrelGeometry.cc | 12 +++++------ 7 files changed, 65 insertions(+), 28 deletions(-) diff --git a/include/DDML/PolyhedraBarrelGeometry.h b/include/DDML/PolyhedraBarrelGeometry.h index 8dbce2b..6a23c1b 100644 --- a/include/DDML/PolyhedraBarrelGeometry.h +++ b/include/DDML/PolyhedraBarrelGeometry.h @@ -27,7 +27,8 @@ class PolyhedraBarrelGeometry : public GeometryInterface { /// declare the proerties needed for the plugin void declareProperties(dd4hep::sim::Geant4Action* plugin) { - plugin->declareProperty("isHadShower", m_isHadShower) plugin->declareProperty("Detector", this->m_detector); + plugin->declareProperty("Detector", this->m_detector); + plugin->declareProperty("isHadShower", this->m_isHadShower); plugin->declareProperty("HadDetector", this->m_HadDetector); plugin->declareProperty("Symmetry", this->m_nSymmetry); plugin->declareProperty("HadSymmetry", this->m_nHadSymmetry); @@ -54,6 +55,9 @@ class PolyhedraBarrelGeometry : public GeometryInterface { std::string m_detector = {"EcalBarrel"}; int m_nSymmetry = 8; bool m_correctForAngles = false; + bool m_isHadShower = false; + std::string m_HadDetector = {"HcalBarrel"}; + int m_nHadSymmetry = m_nSymmetry; }; } // namespace ddml diff --git a/scripts/ddsim_steer.py b/scripts/ddsim_steer.py index 5a7ec2b..71b192e 100644 --- a/scripts/ddsim_steer.py +++ b/scripts/ddsim_steer.py @@ -546,7 +546,8 @@ def LoadHdf5(kernel): ml_correct_angles = False if hadrons == True: - ml_model_had = "LoadHDF5HadronPointCloudModelPolyhedraBarrel/BarrelModelTorch" + ml_model_had = "LoadHDF5PionCloudsPCHadronModelPolyhedraBarrel/BarrelModelTorch" + ml_had_file = "../models/PionClouds_50GeV_sp.h5" ml_correct_angles = False from g4units import GeV, MeV # DO NOT REMOVE OR MOVE!!!!! (EXCLAMATION MARK) @@ -620,24 +621,27 @@ def LoadHdf5(kernel): # ------------------- ## Hadrons in Barrel - modelHad1 = DetectorConstruction(kernel, str()) + modelHad1 = DetectorConstruction(kernel, str(ml_model_had)) ## # Mandatory model parameters - model.isHadShower = True - model.RegionName = "EcalBarrelRegion" ## hadron model triggers in ecal - model.Detector = ml_barrel_name - model.HadDetector = ml_had_barrel_name - model.Symmetry = ml_barrel_symmetry - model.HadSymmetry = ml_had_barrel_symmetry - model.Enable = True - model.CorrectForAngles = ml_correct_angles + modelHad1.isHadShower = True + modelHad1.RegionName = "EcalBarrelRegion" ## hadron model triggers in ecal + modelHad1.Detector = ml_barrel_name + modelHad1.HadDetector = ml_had_barrel_name + modelHad1.Symmetry = ml_barrel_symmetry + modelHad1.HadSymmetry = ml_had_barrel_symmetry + modelHad1.Enable = True + modelHad1.CorrectForAngles = ml_correct_angles # Energy boundaries are optional: Units are GeV - model.ApplicableParticles = {"pi+"} - model.Etrigger = {"pi+": 10.0 * GeV} # trigger on lower training threshold - model.FilePath = ml_file + modelHad1.ApplicableParticles = {"pi+"} + modelHad1.Etrigger = {"pi+": 10.0 * GeV} # trigger on lower training threshold + modelHad1.FilePath = ml_had_file # model.OptimizeFlag = 1 # model.IntraOpNumThreads = 1 + modelHad1.enableUI() + seq.adopt(modelHad1) + # ------------------- # Now build the physics list: diff --git a/scripts/test_onnx.mac b/scripts/test_onnx.mac index b7a22b4..10f6964 100644 --- a/scripts/test_onnx.mac +++ b/scripts/test_onnx.mac @@ -4,12 +4,12 @@ # --- the particle gun /gps/pos/centre 0 0 0 -/gps/particle gamma -#/gps/particle pi- +#/gps/particle gamma +/gps/particle pi+ /gps/energy 50 GeV # for SimpleCalo -/gps/direction -0.4152 1 0 #(pi/8 + pi/4) #1 0.414213562 0 #(pi/8) #-1 2.414213562 0 #(pi/8 + 1 deg) # 0.25 0.25 0.5 #0 0.5 0.655 # ( 37 deg in theta- most you can get in endcap from IP ) +/gps/direction 0 1 0 #-0.4152 1 0 #(pi/8 + pi/4) #1 0.414213562 0 #(pi/8) #-1 2.414213562 0 #(pi/8 + 1 deg) # 0.25 0.25 0.5 #0 0.5 0.655 # ( 37 deg in theta- most you can get in endcap from IP ) # phi barrel #1 0.414213562 0 #(pi/8) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b56fb29..2882c79 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -7,6 +7,7 @@ set(sources Par04ExampleVAE.cc RegularGridBIBAEModel.cc RegularGridTwoAngleBIBAEModel.cc + PionCloudsModel.cc OctogonalBarrelTrigger.cc EndcapTriggerTwoAngleBIBAE.cc CaloCloudsTwoAngleModel.cc @@ -82,6 +83,7 @@ set(headers ${PROJECT_SOURCE_DIR}/include/DDML/Par04ExampleVAE.h ${PROJECT_SOURCE_DIR}/include/DDML/RegularGridBIBAEModel.h ${PROJECT_SOURCE_DIR}/include/DDML/RegularGridTwoAngleBIBAEModel.h + ${PROJECT_SOURCE_DIR}/include/DDML/PionCloudsModel.h ${PROJECT_SOURCE_DIR}/include/DDML/PolyhedraBarrelGeometry.h ${PROJECT_SOURCE_DIR}/include/DDML/ModelInterface.h ${PROJECT_SOURCE_DIR}/include/DDML/InferenceInterface.h diff --git a/src/LoadHdf5.cc b/src/LoadHdf5.cc index 7bfebe1..2cb8360 100644 --- a/src/LoadHdf5.cc +++ b/src/LoadHdf5.cc @@ -19,7 +19,7 @@ void LoadHdf5::initialize() { // inputs and TensorDimVecs unused // Open dataset + dataspace - std::string datasetName = "layers"; + std::string datasetName = "spase_points"; //"layers"; H5::DataSet dataset = m_file.openDataSet(datasetName); dd4hep::printout(dd4hep::DEBUG, "LoadHdf5::initialize", "Accessed HDF5 dataset"); H5::DataSpace dataspace = dataset.getSpace(); @@ -39,10 +39,15 @@ void LoadHdf5::initialize() { m_dimsOut = dims_out; - assert(rank == 4); // assuming 4 dimensional input +// assert(rank == 4); // assuming 4 dimensional input // index 0: shower number // index 1, 2, 3: x, y, z cell number + assert(rank == 3); // assuming 3 dimensional PionCloud input + // index 0: shower number + // index 1: number of points + // index 2: 4 point dimensions (x, y, z, E) - currently in ILD coordinates + dd4hep::printout(dd4hep::DEBUG, "LoadHdf5::initialize", "Rank %i", rank); for (int i = 0, N = rank; i < N; ++i) { @@ -80,11 +85,17 @@ void LoadHdf5::runInference(const InputVecs&, const TensorDimVecs&, std::vector< } // select shower from library - std::vector shower(m_library.begin() + m_count * m_dimsOut[1] * m_dimsOut[2] * m_dimsOut[3], - m_library.begin() + (m_count + 1) * m_dimsOut[1] * m_dimsOut[2] * m_dimsOut[3]); + //std::vector shower(m_library.begin() + m_count * m_dimsOut[1] * m_dimsOut[2] * m_dimsOut[3], + // m_library.begin() + (m_count + 1) * m_dimsOut[1] * m_dimsOut[2] * m_dimsOut[3]); + + // select shower from library + std::vector shower(m_library.begin() + m_count * m_dimsOut[1] * m_dimsOut[2], + m_library.begin() + (m_count + 1) * m_dimsOut[1] * m_dimsOut[2]); // enforce length of shower - assert(shower.size() == m_dimsOut[1] * m_dimsOut[2] * m_dimsOut[3]); + //assert(shower.size() == m_dimsOut[1] * m_dimsOut[2] * m_dimsOut[3]); + + assert(shower.size() == m_dimsOut[1] * m_dimsOut[2]); // write output output = std::move(shower); diff --git a/src/MLModelActions.cc b/src/MLModelActions.cc index ab56dd1..5e88b6b 100644 --- a/src/MLModelActions.cc +++ b/src/MLModelActions.cc @@ -25,6 +25,7 @@ #include "DDML/RegularGridBIBAEModel.h" #include "DDML/RegularGridGANModel.h" #include "DDML/RegularGridTwoAngleBIBAEModel.h" +#include "DDML/PionCloudsModel.h" #include "DDML/TriggerInterface.h" namespace ddml { @@ -127,8 +128,21 @@ typedef FastMLShower< FastMLModel> // add ML trigger LoadHDF5RegularGridTwoAngleBIBAEModelEndcap; + +/// Load from HDF5 file- as an example for Hadron showers from PionClouds +// Barrel +typedef FastMLShower> // add ML trigger + LoadHDF5PionCloudsPCHadronModelPolyhedraBarrel; +// Endcap // ENDCAP IS CURRENTLY NOT IMPLEMENTED!!!! +typedef FastMLShower< + FastMLModel> // add ML trigger + LoadHDF5PionCloudsPCHadronModelEndcap; #endif + } // namespace ddml #include @@ -156,4 +170,6 @@ DECLARE_GEANT4ACTION_NS(ddml, L2LFlowsModelEndcapTorchModel) #ifdef DDML_USE_LOAD_HDF5 DECLARE_GEANT4ACTION_NS(ddml, LoadHDF5RegularGridTwoAngleBIBAEModelPolyhedraBarrel) DECLARE_GEANT4ACTION_NS(ddml, LoadHDF5RegularGridTwoAngleBIBAEModelEndcap) +DECLARE_GEANT4ACTION_NS(ddml, LoadHDF5PionCloudsPCHadronModelPolyhedraBarrel) +DECLARE_GEANT4ACTION_NS(ddml, LoadHDF5PionCloudsPCHadronModelEndcap) #endif diff --git a/src/PolyhedraBarrelGeometry.cc b/src/PolyhedraBarrelGeometry.cc index f7f4f6a..829ddb0 100644 --- a/src/PolyhedraBarrelGeometry.cc +++ b/src/PolyhedraBarrelGeometry.cc @@ -16,12 +16,6 @@ void PolyhedraBarrelGeometry::initialize() { auto det = theDetector.detector(m_detector); auto* cal = det.extension(); - // For hadronic shower simulation - if (m_isHadShower == true) { - auto det_had = theDetector.detector(m_HadDetector); - auto* cal_had = det_had.extension(); - } - if (cal) { for (auto l : cal->layers) { m_caloLayerDistances.push_back((l.distance + l.inner_thickness) / dd4hep::mm); @@ -30,12 +24,18 @@ void PolyhedraBarrelGeometry::initialize() { std::cout << " ###### error: detector " << m_detector << " not found !" << std::endl; } + // For hadronic shower simulation if (m_isHadShower == true) { + auto det_had = theDetector.detector(m_HadDetector); + auto* cal_had = det_had.extension(); if (cal_had) { for (auto l_had : cal_had->layers) { m_caloLayerDistances.push_back((l_had.distance + l_had.inner_thickness) / dd4hep::mm); } } + else { + std::cout << " ###### error: detector " << m_HadDetector << " not found !" << std::endl; + } } } From 422e53f985f9fa79beb112fe7c37a59ddb062c49 Mon Sep 17 00:00:00 2001 From: Peter McKeown Date: Mon, 17 Feb 2025 17:25:38 +0100 Subject: [PATCH 14/36] Working implmentation of hadron shower loading --- include/DDML/PionCloudsModel.h | 74 +++++++++++++ include/DDML/PolyhedraBarrelGeometry.h | 7 +- scripts/ddsim_steer.py | 4 +- scripts/test_onnx.mac | 4 +- src/Geant4FastHitMakerGlobal.cc | 7 ++ src/PionCloudsModel.cc | 142 +++++++++++++++++++++++++ src/PolyhedraBarrelGeometry.cc | 8 ++ 7 files changed, 242 insertions(+), 4 deletions(-) create mode 100644 include/DDML/PionCloudsModel.h create mode 100644 src/PionCloudsModel.cc diff --git a/include/DDML/PionCloudsModel.h b/include/DDML/PionCloudsModel.h new file mode 100644 index 0000000..0bb9bfc --- /dev/null +++ b/include/DDML/PionCloudsModel.h @@ -0,0 +1,74 @@ +#ifndef PionClouds_H +#define PionClouds_H + +#include "DDML/ModelInterface.h" +#include "DDML/FastMLShower.h" + + +namespace ddml { + +/** Class for running a point cloud based ML model for fast shower simulation. + * Assumes a cartesian (x,y) coordinates defining the calorimeter planes (layers) and z the depth + * of the calorimeter. + * + * Based on BiBAETwoAngleModel. + * + * Implemented here for the PionClouds model intended for hadron shower simulation (ECAL+HCAL). + * + * @author A.Korol, DESY + * @author P. McKeown, CERN + * @date Feb. 2025 + */ + + class PionCloudsModel : public ModelInterface { + + public: + PionCloudsModel() {} ; + + virtual ~PionCloudsModel(){}; + + /// declare the proerties needed for the plugin + void declareProperties(dd4hep::sim::Geant4Action* plugin) { + plugin->declareProperty("LatentVectorSize", this->m_latentSize); + } + + /** prepare the input vector and resize the output vector for this model + * based on the current FastTrack (e.g. extract kinetic energy and incident + * angles.) + */ + virtual void prepareInput(G4FastTrack const& aFastTrack, + G4ThreeVector const& localDir, + InputVecs& inputs, TensorDimVecs& tensDims, + std::vector& output ) ; + + + /** create a vector of spacepoints per layer interpreting the model output + */ + virtual void convertOutput(G4FastTrack const& aFastTrack, + G4ThreeVector const& localDir, + const std::vector& output, + std::vector& spacepoints ) ; + + + + private: + + /// model properties for plugin + // These grid sizes were used for the two angle BIBAE + int m_numPoints = 2600; + int m_latentSize = 3; // number of input features (energy, theta, phi) + int m_maxNumElements = m_numPoints*4; // number of space points in the output multiplied by 4 (x,y,z,energy) + int m_nLayer = 78; + + struct Vector3d{double x; double y; double z;}; + + Vector3d crossProduct(const Vector3d& v1, const Vector3d& v2); + + Vector3d normalize(const Vector3d& v); + + TensorDimVecs m_tensDims = {{1, 1}, {1, 1}, {1, 1}, {1, 3}}; + }; + +} // namespace ddml +#endif + diff --git a/include/DDML/PolyhedraBarrelGeometry.h b/include/DDML/PolyhedraBarrelGeometry.h index 6a23c1b..aa8cedb 100644 --- a/include/DDML/PolyhedraBarrelGeometry.h +++ b/include/DDML/PolyhedraBarrelGeometry.h @@ -12,6 +12,11 @@ namespace ddml { * * @author F.Gaede, DESY * @date Mar 2023 + * + * Addiional option included to support Hadronic shower simulation in ECAL + HCAL + * @author P. McKeown, CERN + * @date Feb 2025 + * */ class PolyhedraBarrelGeometry : public GeometryInterface { @@ -55,7 +60,7 @@ class PolyhedraBarrelGeometry : public GeometryInterface { std::string m_detector = {"EcalBarrel"}; int m_nSymmetry = 8; bool m_correctForAngles = false; - bool m_isHadShower = false; + bool m_isHadShower = true; std::string m_HadDetector = {"HcalBarrel"}; int m_nHadSymmetry = m_nSymmetry; }; diff --git a/scripts/ddsim_steer.py b/scripts/ddsim_steer.py index 71b192e..23450fb 100644 --- a/scripts/ddsim_steer.py +++ b/scripts/ddsim_steer.py @@ -574,6 +574,7 @@ def LoadHdf5(kernel): seq.adopt(sensitives) # ----------------- + ''' ## EM in Barrel model = DetectorConstruction(kernel, str(ml_model)) @@ -596,6 +597,7 @@ def LoadHdf5(kernel): model.enableUI() seq.adopt(model) + ''' # ------------------- ## EM in Endcap model1 = DetectorConstruction(kernel, str(ml_model_1)) @@ -625,7 +627,7 @@ def LoadHdf5(kernel): ## # Mandatory model parameters modelHad1.isHadShower = True - modelHad1.RegionName = "EcalBarrelRegion" ## hadron model triggers in ecal + modelHad1.RegionName = "EcalBarrelRegion" #or "HcalBarrelRegion" ## hadron model triggers in ecal modelHad1.Detector = ml_barrel_name modelHad1.HadDetector = ml_had_barrel_name modelHad1.Symmetry = ml_barrel_symmetry diff --git a/scripts/test_onnx.mac b/scripts/test_onnx.mac index 10f6964..3d5a716 100644 --- a/scripts/test_onnx.mac +++ b/scripts/test_onnx.mac @@ -3,7 +3,7 @@ # example script to run inference on a GAN w/ ONNX runtime # --- the particle gun -/gps/pos/centre 0 0 0 +/gps/pos/centre 30 180.48 0 #120 180.48 120 #30 180.48 0 #30 0 0 #/gps/particle gamma /gps/particle pi+ /gps/energy 50 GeV @@ -64,5 +64,5 @@ #/gps/direction 0.1 -0.8 .1 -/run/beamOn 10 #100 +/run/beamOn 2000 #100 diff --git a/src/Geant4FastHitMakerGlobal.cc b/src/Geant4FastHitMakerGlobal.cc index 9740761..bd7108f 100644 --- a/src/Geant4FastHitMakerGlobal.cc +++ b/src/Geant4FastHitMakerGlobal.cc @@ -48,6 +48,9 @@ Geant4FastHitMakerGlobal::~Geant4FastHitMakerGlobal() { //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... void Geant4FastHitMakerGlobal::make(const G4FastHit& aHit, const G4FastTrack& aTrack) { + + std::cout << "Geant4FastHitMakerGlobal::make - aHit.GetPosition().x() " << aHit.GetPosition().x() << " aHit.GetPosition().y() " << + aHit.GetPosition().y() << " aHit.GetPosition().z() " << aHit.GetPosition().z() << std::endl; // do not make empty deposit if (aHit.GetEnergy() <= 0) { return; @@ -80,9 +83,13 @@ void Geant4FastHitMakerGlobal::make(const G4FastHit& aHit, const G4FastTrack& aT G4VSensitiveDetector* sensitive; if (currentVolume != 0) { + //std::cout << "IN FULL Sim Sensitive Geant4FastHitMakerGlobal::make - aHit.GetPosition().x() " << aHit.GetPosition().x() << " aHit.GetPosition().y() " << + // aHit.GetPosition().y() << " aHit.GetPosition().z() " << aHit.GetPosition().z() << " Energy: " << aHit.GetEnergy() << std::endl; sensitive = currentVolume->GetLogicalVolume()->GetSensitiveDetector(); G4VFastSimSensitiveDetector* fastSimSensitive = dynamic_cast(sensitive); if (fastSimSensitive) { + std::cout << "IN FAST Sim Sensitive Geant4FastHitMakerGlobal::make - aHit.GetPosition().x() " << aHit.GetPosition().x() << " aHit.GetPosition().y() " << + aHit.GetPosition().y() << " aHit.GetPosition().z() " << aHit.GetPosition().z() << " Energy: " << aHit.GetEnergy() << std::endl; fastSimSensitive->Hit(&aHit, &aTrack, &m_touchableHandle); } else if (sensitive && currentVolume->GetLogicalVolume()->GetFastSimulationManager()) { G4cerr << "ERROR - Geant4FastHitMakerGlobal::make()" << G4endl << " It is required to derive from the " diff --git a/src/PionCloudsModel.cc b/src/PionCloudsModel.cc new file mode 100644 index 0000000..6b04e9e --- /dev/null +++ b/src/PionCloudsModel.cc @@ -0,0 +1,142 @@ +#include "DDML/PionCloudsModel.h" + +#include // for G4FastTrack + +//#include + +#define DEBUGPRINT 0 + +namespace ddml { + + void PionCloudsModel::prepareInput(G4FastTrack const& aFastTrack, + G4ThreeVector const& localDir, + InputVecs& inputs, TensorDimVecs& tensDims, + std::vector& output ) { + + tensDims = m_tensDims; + + G4double energy = aFastTrack.GetPrimaryTrack()->GetKineticEnergy(); + + G4ThreeVector direction = aFastTrack.GetPrimaryTrack()->GetMomentumDirection(); + G4RotationMatrix rotZ; + rotZ.rotateZ(M_PI / 2.); + G4RotationMatrix rotX; + rotX.rotateX(M_PI / 2.); + // this convention is used for the local coordinates in the dataset (model was trained in this convention) + // G4ThreeVector localDir_ = rotZ * (rotX * direction) ; + + G4ThreeVector localDir_ = localDir; + localDir_.setX(-1. * localDir_.x()); // *(-1) to align local to global convention in ddml + localDir_.setY(-1. * localDir_.y()); // *(-1) to align local to global convention in ddml + + dd4hep::printout(dd4hep::DEBUG, "PionCloudsModel::prepareInput", "DDML::localDir: (%f, %f, %f)", + localDir_.x(), localDir_.y(), localDir_.z()); + // std::cout << "PionClouds::localDir:" << "(" << localDir_.x() << "," << localDir_.y() << "," << localDir_.z() << ")" + // << std::endl; + + // compute local incident angles + double r = sqrt(localDir_.x() * localDir_.x() + localDir_.y() * localDir_.y() + localDir_.z() * localDir_.z()); + double theta = acos(localDir_.z() / r) / M_PI * 180.; + double phi = atan2(localDir_.y(), localDir_.x()) / M_PI * 180.; + + dd4hep::printout(dd4hep::DEBUG, "PionCloudsModel::prepareInput", "DDML::localDir: (%f, %f)", theta, phi); + // std::cout << "PionClouds::localDir:" << " theta = " << theta << " phi = " << phi << std::endl; + + // the input for the PionClouds is one energy and two angles (local Theta and Phi) + inputs.resize(m_latentSize); + + inputs[0].resize(1); // Energy + inputs[1].resize(1); // Theta + inputs[2].resize(1); // Phi + + // For now, assume batch size one, and just assign values + inputs[0][0] = energy / CLHEP::GeV; // E_vec[0]/100.; + inputs[1][0] = theta; // 89.*(M_PI/180.) ; //Theta_vec[0]/(90.*(M_PI/180.)); + inputs[2][0] = phi; + + // if (DEBUGPRINT) { + // std::cout << " Input_energy_tensor : " << inputs[0][0] << std::endl; + // std::cout << " Input_theta_tensor : " << inputs[1][0] << std::endl; + // std::cout << " Input_phi_tensor : " << inputs[2][0] << std::endl; + // } + + dd4hep::printout(dd4hep::DEBUG, "PionCloudsModel::prepareInput", "Input_energy_tensor : %f", inputs[0][0]); + dd4hep::printout(dd4hep::DEBUG, "PionCloudsModel::prepareInput", "Input_theta_tensor : %f", inputs[1][0]); + dd4hep::printout(dd4hep::DEBUG, "PionCloudsModel::prepareInput", "Input_phi_tensor : %f", inputs[2][0]); + + // ---- resize output vector + + output.assign(m_maxNumElements, 0); +} + + + + void PionCloudsModel::convertOutput(G4FastTrack const& aFastTrack, + G4ThreeVector const& localDir, + const std::vector& output, + std::vector& spacepoints ){ + + int nPoints = m_numPoints ; // number of points in shower + + dd4hep::printout(dd4hep::DEBUG, "PionCloudsModel::convertOutput", "m_numPoints : %i", m_numPoints); + + spacepoints.resize( m_nLayer ) ; + + int numSP = 0; + int layerNum = 0; + int numElements = 0; + for (int i = 0; i < m_nLayer; i++) { + numSP = output[i] + 1; + spacepoints[i].reserve(numSP); + numElements += output[i] * 4; + } + + std::cout << " PionCloudsModel::convertOutput DONE numElements, numElements = " << numElements << std::endl; + + /* + for (int i = m_nLayer; i < m_nLayer + numElements; i += 4) { + std::cout << " PionCloudsModel::convertOutput Layer Loop, i = " << i << std::endl; + std::cout << " PionCloudsModel::convertOutput Layer Loop, output[i] " << output[i] << std::endl; + std::cout << " PionCloudsModel::convertOutput Layer Loop, output[i+1] " << output[i] << std::endl; + std::cout << " PionCloudsModel::convertOutput Layer Loop, output[i+3] " << output[i] << std::endl; + ddml::SpacePoint sp( + output[i], // x // *(-1) to align local to global convention in ddml + output[i+1], // y // *(-1) to align local to global convention in ddml + 0., // z + output[i+3], // energy + 0. // time + ); + layerNum = output[i+2]; + std::cout << " PionCloudsModel::convertOutput Layer Loop, layerNum " << layerNum << std::endl; + spacepoints[layerNum].emplace_back( sp ) ; + */ + + + float reshaped[2600][4]; + + // Fill the 3D array using the flattened vector + size_t index = 0; + for (size_t j = 0; j < 2600; ++j) { + for (size_t k = 0; k < 4; ++k) { + reshaped[j][k] = output[index++]; + } + } + + for (int i = 0; i < nPoints; i++) { + ddml::SpacePoint sp( + reshaped[i][0]*1e3, // x // *(-1) to align local to global convention in ddml + reshaped[i][2]*1e3, // y // *(-1) to align local to global convention in ddml + 0., // z + reshaped[i][3], // energy + 0. // time + ); + layerNum = reshaped[i][1]; + std::cout << "PionCloudsModel::convertOutput - layerNum" << layerNum <layers) { m_caloLayerDistances.push_back((l.distance + l.inner_thickness) / dd4hep::mm); + std::cout << " ECAL Layer distances " << l.distance + l.inner_thickness << std::endl; } } else { std::cout << " ###### error: detector " << m_detector << " not found !" << std::endl; @@ -31,6 +32,7 @@ void PolyhedraBarrelGeometry::initialize() { if (cal_had) { for (auto l_had : cal_had->layers) { m_caloLayerDistances.push_back((l_had.distance + l_had.inner_thickness) / dd4hep::mm); + std::cout << " HCAL Layer distances " << l_had.distance + l_had.inner_thickness << std::endl; } } else { @@ -138,6 +140,8 @@ void PolyhedraBarrelGeometry::localToGlobal(G4FastTrack const& aFastTrack, int firstLayer = 0; int nLayer = m_caloLayerDistances.size(); + std::cout << " PolyhedraBarrelGeometry::localToGlobal nLayer " << nLayer << std::endl; + for (int l = 0; l < nLayer; ++l) { double r = m_caloLayerDistances[l]; firstLayer = l; @@ -181,6 +185,10 @@ void PolyhedraBarrelGeometry::localToGlobal(G4FastTrack const& aFastTrack, sp.X = global.x(); sp.Y = global.y(); sp.Z = global.z(); + + std::cout << " PolyhedraBarrelGeometry::localToGlobal - global.x() = " << global.x() << " global.y() = " << global.y() + << " global.z() " << global.z() << " Energy: " << sp.E << std::endl; + } } } From 4e5eb28d10f279b377a72c96f827618b09e0176e Mon Sep 17 00:00:00 2001 From: Peter McKeown Date: Wed, 19 Feb 2025 09:30:31 +0100 Subject: [PATCH 15/36] Add option to record information about MC particle entry into calorimter --- CMakeLists.txt | 2 + include/DDML/DDMLEventAction.h | 70 +++ include/DDML/DDMLRunAction.h | 39 ++ include/DDML/FastMLShower.h | 45 ++ scripts/ddsim_steer.py | 2 +- scripts/ddsim_steer_Record_Calo_entry.py | 656 +++++++++++++++++++++++ scripts/test_onnx.mac | 4 +- src/CMakeLists.txt | 16 + src/DDMLEventAction.cc | 58 ++ src/DDMLRunAction.cc | 94 ++++ src/PionCloudsModel.cc | 4 +- 11 files changed, 985 insertions(+), 5 deletions(-) create mode 100644 include/DDML/DDMLEventAction.h create mode 100644 include/DDML/DDMLRunAction.h create mode 100644 scripts/ddsim_steer_Record_Calo_entry.py create mode 100644 src/DDMLEventAction.cc create mode 100644 src/DDMLRunAction.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 2d887d0..d6567a9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,6 +58,8 @@ endif() option(INSTRUMENT_MODEL "Instrument the steps of the showerModel call" OFF) +option(RECORD_CALO_IMPACT "Record properties of particle that triggers modelShower call" OFF) + option(DOWNLOAD_MODELS "Download and install the models that are stored externally" ON) #--------------------------------------------------- diff --git a/include/DDML/DDMLEventAction.h b/include/DDML/DDMLEventAction.h new file mode 100644 index 0000000..1aa857c --- /dev/null +++ b/include/DDML/DDMLEventAction.h @@ -0,0 +1,70 @@ +#include // for G4int, G4double +#include // for vector +#include "G4UserEventAction.hh" // for G4UserEventAction +//#include "G4Timer.hh" // for G4Timer +class G4Event; +#include "DDG4/Geant4Handle.h" +#include "DDG4/Geant4Kernel.h" +#include "DDG4/Geant4EventAction.h" +#include "CLHEP/Units/SystemOfUnits.h" +#include "CLHEP/Units/PhysicalConstants.h" + + +namespace ddml { + +/** Event action for ddml. +* +* @author P. McKeown, CERN +* @date Feb 2025 +* +*/ + +class DDMLEventAction: public dd4hep::sim::Geant4EventAction{ +public: + /// Standard constructor with initializing arguments + DDMLEventAction(dd4hep::sim::Geant4Context* c, const std::string& n); + /// Default destructor + virtual ~DDMLEventAction(); + /// begin-of-event callback + inline virtual void begin(const G4Event*) override; + /// End-of-event callback + virtual void end(const G4Event*) override; + /// begin-of-run callback + void beginRun(const G4Run*); + /// End-of-run callback + void endRun(const G4Run*); + + //// Get and Set methods for Calo Face info + inline std::vector& GetCaloMC_PDG() {return m_CaloMCPDG;} + inline std::vector& GetCaloMC_E() {return m_CaloMCE;} + inline std::vector& GetCaloMC_PosX() {return m_CaloMCPosX;} + inline std::vector& GetCaloMC_PosY() {return m_CaloMCPosY;} + inline std::vector& GetCaloMC_PosZ() {return m_CaloMCPosZ;} + inline std::vector& GetCaloMC_DirX() {return m_CaloMCDirX;} + inline std::vector& GetCaloMC_DirY() {return m_CaloMCDirY;} + inline std::vector& GetCaloMC_DirZ() {return m_CaloMCDirZ;} + + // Set methods to push back vector + inline void SetElCaloMC_PDG(G4int aValue) {m_CaloMCPDG.push_back(aValue);} + inline void SetElCaloMC_E(G4double aValue) {m_CaloMCE.push_back(aValue);} + inline void SetElCaloMC_PosX(G4double aValue) {m_CaloMCPosX.push_back(aValue);} + inline void SetElCaloMC_PosY(G4double aValue) {m_CaloMCPosY.push_back(aValue);} + inline void SetElCaloMC_PosZ(G4double aValue) {m_CaloMCPosZ.push_back(aValue);} + inline void SetElCaloMC_DirX(G4double aValue) {m_CaloMCDirX.push_back(aValue);} + inline void SetElCaloMC_DirY(G4double aValue) {m_CaloMCDirY.push_back(aValue);} + inline void SetElCaloMC_DirZ(G4double aValue) {m_CaloMCDirZ.push_back(aValue);} + +private: + // Fast Sim Calo entrace particle properties to store in ntuple + std::vector m_CaloMCPDG; + std::vector m_CaloMCE; + std::vector m_CaloMCPosX; + std::vector m_CaloMCPosY; + std::vector m_CaloMCPosZ; + std::vector m_CaloMCDirX; + std::vector m_CaloMCDirY; + std::vector m_CaloMCDirZ; +}; + +} //namespace + diff --git a/include/DDML/DDMLRunAction.h b/include/DDML/DDMLRunAction.h new file mode 100644 index 0000000..49c5dc6 --- /dev/null +++ b/include/DDML/DDMLRunAction.h @@ -0,0 +1,39 @@ +#include // for GeV +#include // for G4String +#include // for G4ThreeVector +#include // for G4int +//#include "G4Timer.hh" // for G4Timer +class G4ParticleDefinition; +#include "DDG4/Geant4Handle.h" +#include "DDG4/Geant4Kernel.h" +#include "DDG4/Geant4RunAction.h" + + + +namespace ddml{ +/* Create analysis files in standard G4 manner +* +* @author P. McKeown +* @date Feb 2025 +* +*/ + +class DDMLRunAction: public dd4hep::sim::Geant4RunAction { + public: + DDMLRunAction() = delete; + /// Standard constructor with initializing arguments + DDMLRunAction(dd4hep::sim::Geant4Context* c, const std::string& n) ; + /// Default destructor + virtual ~DDMLRunAction() ; + /// begin-of-run callback + void begin(const G4Run*) override; + /// End-of-run callback + void end(const G4Run*) override; + /// begin-of-event callback + void beginEvent(const G4Event*) ; + /// End-of-event callback + void endEvent(const G4Event*) ; + +}; + +} // namespace \ No newline at end of file diff --git a/include/DDML/FastMLShower.h b/include/DDML/FastMLShower.h index e48a35a..0615eb2 100644 --- a/include/DDML/FastMLShower.h +++ b/include/DDML/FastMLShower.h @@ -14,6 +14,10 @@ #define DDML_INSTRUMENT_MODEL_SHOWER 0 #endif +#ifndef DDML_RECORD_CALO_IMPACT + #define DDML_RECORD_CALO_IMPACT 0 +#endif + #if DDML_INSTRUMENT_MODEL_SHOWER #include "podio/Frame.h" #include "podio/ROOTFrameWriter.h" @@ -35,6 +39,12 @@ inline auto run_void_member_timed(Obj& obj, MemberFunc func, Args&&... args) { } #endif +#if DDML_RECORD_CALO_IMPACT + //#include "G4EventManager.hh" + //#include "DDML/DDMLEventAction.h" + #include "G4AnalysisManager.hh" +#endif + namespace ddml { /** The templated base class for running fast shower simulation with ML. * The actual implementation is provided by the templated class @@ -144,6 +154,41 @@ class FastMLShower : public dd4hep::sim::Geant4FastSimShowerModel { podio::UserDataCollection nHits; #endif +#if DDML_RECORD_CALO_IMPACT + // Create analysis manager + G4AnalysisManager* analysisManager = G4AnalysisManager::Instance(); + + // Store information about particle impact on calorimter face from track + G4int PDG = track.GetPrimaryTrack()->GetParticleDefinition()->GetPDGEncoding(); + G4ThreeVector position = track.GetPrimaryTrack()->GetPosition(); + G4ThreeVector direction = track.GetPrimaryTrack()->GetMomentumDirection(); + + // Fill analysis manager + analysisManager->FillNtupleIColumn(1, 0, PDG); + analysisManager->FillNtupleDColumn(1, 1, energy); + analysisManager->FillNtupleDColumn(1, 2, position.x()); + analysisManager->FillNtupleDColumn(1, 3, position.y()); + analysisManager->FillNtupleDColumn(1, 4, position.z()); + analysisManager->FillNtupleDColumn(1, 5, direction.x()); + analysisManager->FillNtupleDColumn(1, 6, direction.y()); + analysisManager->FillNtupleDColumn(1, 7, direction.z()); + + analysisManager->AddNtupleRow(1); + + /* + DDMLEventAction* mEventAction = dynamic_cast(G4EventManager::GetEventManager()->GetUserEventAction()); + mEventAction->SetElCaloMC_PDG(PDG); + mEventAction->SetElCaloMC_E(energy); + mEventAction->SetElCaloMC_PosX(position.x()); + mEventAction->SetElCaloMC_PosY(position.y()); + mEventAction->SetElCaloMC_PosZ(position.z()); + mEventAction->SetElCaloMC_DirX(direction.x()); + mEventAction->SetElCaloMC_DirY(direction.y()); + mEventAction->SetElCaloMC_DirZ(direction.z()); + */ + +#endif + for (auto& invec : m_input) { invec.clear(); } diff --git a/scripts/ddsim_steer.py b/scripts/ddsim_steer.py index 23450fb..9c7f8a0 100644 --- a/scripts/ddsim_steer.py +++ b/scripts/ddsim_steer.py @@ -547,7 +547,7 @@ def LoadHdf5(kernel): if hadrons == True: ml_model_had = "LoadHDF5PionCloudsPCHadronModelPolyhedraBarrel/BarrelModelTorch" - ml_had_file = "../models/PionClouds_50GeV_sp.h5" + ml_had_file = "../models/PionClouds_50GeV_sp.h5" #"../models/PionClouds_50GeV_sp_scaled.h5" ml_correct_angles = False from g4units import GeV, MeV # DO NOT REMOVE OR MOVE!!!!! (EXCLAMATION MARK) diff --git a/scripts/ddsim_steer_Record_Calo_entry.py b/scripts/ddsim_steer_Record_Calo_entry.py new file mode 100644 index 0000000..6107367 --- /dev/null +++ b/scripts/ddsim_steer_Record_Calo_entry.py @@ -0,0 +1,656 @@ +###################################################################### +# +# standard steering file for ILD simulation +# +# +# +###################################################################### +from DDSim.DD4hepSimulation import DD4hepSimulation +import DDG4 +from g4units import m, mm, GeV, MeV, rad +import os + +SIM = DD4hepSimulation() + +## The compact XML file +SIM.compactFile = "" +## Lorentz boost for the crossing angle, in radian! +SIM.crossingAngleBoost = 7.0e-3 * rad +SIM.enableDetailedShowerMode = True +SIM.enableG4GPS = True +SIM.enableG4Gun = False +SIM.enableGun = False +## InputFiles for simulation .stdhep, .slcio, .HEPEvt, .hepevt, .hepmc, .pairs files are supported +SIM.inputFiles = [] +## Macro file to execute for runType 'run' or 'vis' +SIM.macroFile = "./test_onnx.mac" +## number of events to simulate, used in batch mode +SIM.numberOfEvents = 100 +## Outputfile from the simulation,only lcio output is supported +# SIM.outputFile = "dummyOutput_edm4hep.root" ##"dummyOutput.slcio" +SIM.outputFile = "dummyOutput.slcio" + +## Physics list to use in simulation +SIM.physicsList = None +## Verbosity use integers from 1(most) to 7(least) verbose +## or strings: VERBOSE, DEBUG, INFO, WARNING, ERROR, FATAL, ALWAYS +SIM.printLevel = "INFO" +## The type of action to do in this invocation +## batch: just simulate some events, needs numberOfEvents, and input file or gun +## vis: enable visualisation, run the macroFile if it is set +## run: run the macroFile and exit +## shell: enable interactive session +SIM.runType = "run" # "batch" +## Skip first N events when reading a file +SIM.skipNEvents = 0 +## Steering file to change default behaviour +SIM.steeringFile = None +## FourVector of translation for the Smearing of the Vertex position: x y z t +SIM.vertexOffset = [0.0, 0.0, 0.0, 0.0] +## FourVector of the Sigma for the Smearing of the Vertex position: x y z t +SIM.vertexSigma = [0.0, 0.0, 0.0, 0.0] + + +################################################################################ +## Action holding sensitive detector actions +## The default tracker and calorimeter actions can be set with +## +## >>> SIM = DD4hepSimulation() +## >>> SIM.action.tracker = ('Geant4TrackerWeightedAction', {'HitPositionCombination': 2, 'CollectSingleDeposits': False}) +## >>> SIM.action.calo = "Geant4CalorimeterAction" +## +## for specific subdetectors specific sensitive detectors can be set based on pattern matching +## +## >>> SIM = DD4hepSimulation() +## >>> SIM.action.mapActions['tpc'] = "TPCSDAction" +## +## and additional parameters for the sensitive detectors can be set when the map is given a tuple +## +## >>> SIM = DD4hepSimulation() +## >>> SIM.action.mapActions['ecal'] =( "CaloPreShowerSDAction", {"FirstLayerNumber": 1} ) +## +## +################################################################################ + +## set the default calorimeter action +SIM.action.calo = "Geant4ScintillatorCalorimeterAction" + +## create a map of patterns and actions to be applied to sensitive detectors +## example: SIM.action.mapActions['tpc'] = "TPCSDAction" +SIM.action.mapActions = {} + +SIM.action.mapActions["tpc"] = "TPCSDAction" + +## set the default tracker action +SIM.action.tracker = ( + "Geant4TrackerWeightedAction", + {"HitPositionCombination": 2, "CollectSingleDeposits": False}, +) + +### Configure Run actions +kernel = DDG4.Kernel() +run1 = DDG4.RunAction(kernel, 'DDMLRunAction/runaction') +kernel.registerGlobalAction(run1) +kernel.runAction().add(run1) +event1 = DDG4.EventAction(kernel, 'DDMLEventAction/eventaction') +kernel.registerGlobalAction(event1) +kernel.eventAction().add(event1) + +################################################################################ +## Configuration for the magnetic field (stepper) +################################################################################ +## --- used in v01-19-05 : +SIM.field.delta_chord = 1e-05 +SIM.field.delta_intersection = 1e-05 +SIM.field.delta_one_step = 0.5e-03 * mm +SIM.field.eps_max = 1e-04 +SIM.field.eps_min = 1e-05 +SIM.field.equation = "Mag_UsualEqRhs" +SIM.field.largest_step = 10.0 * m +SIM.field.min_chord_step = 1.0e-2 * mm +SIM.field.stepper = "HelixSimpleRunge" + +## --- default values in ddsim +##SIM.field.delta_chord = 0.25 +##SIM.field.delta_intersection = 0.001 +##SIM.field.delta_one_step = 0.01 +##SIM.field.eps_max = 0.001 +##SIM.field.eps_min = 5e-05 +##SIM.field.equation = "Mag_UsualEqRhs" +##SIM.field.largest_step = 10000.0 +##SIM.field.min_chord_step = 0.01 +##SIM.field.stepper = "G4ClassicalRK4" + +################################################################################ +## Configuration for sensitive detector filters +## +## Set the default filter for tracker or caliromter +## >>> SIM.filter.tracker = "edep1kev" +## >>> SIM.filter.calo = "" +## +## Assign a filter to a sensitive detector via pattern matching +## >>> SIM.filter.mapDetFilter['FTD'] = "edep1kev" +## +## Or more than one filter: +## >>> SIM.filter.mapDetFilter['FTD'] = ["edep1kev", "geantino"] +## +## Don't use the default filter or anything else: +## >>> SIM.filter.mapDetFilter['TPC'] = None ## or "" or [] +## +## Create a custom filter. The dictionary is used to instantiate the filter later on +## >>> SIM.filter.filters['edep3kev'] = dict(name="EnergyDepositMinimumCut/3keV", parameter={"Cut": 3.0*keV} ) +## +## +################################################################################ + +## default filter for calorimeter sensitive detectors; this is applied if no other filter is used for a calorimeter +SIM.filter.calo = "edep0" + +## list of filter objects: map between name and parameter dictionary +SIM.filter.filters = { + "edep0": {"parameter": {"Cut": 0.0}, "name": "EnergyDepositMinimumCut/Cut0"}, + "geantino": {"parameter": {}, "name": "GeantinoRejectFilter/GeantinoRejector"}, + "edep1kev": {"parameter": {"Cut": 0.001}, "name": "EnergyDepositMinimumCut"}, +} + +## a map between patterns and filter objects, using patterns to attach filters to sensitive detector +SIM.filter.mapDetFilter = {} + +SIM.filter.mapDetFilter["TPC"] = None + +## default filter for tracking sensitive detectors; this is applied if no other filter is used for a tracker +SIM.filter.tracker = "edep1kev" + + +################################################################################ +## Configuration for the GuineaPig InputFiles +################################################################################ + +## Set the number of pair particles to simulate per event. +## Only used if inputFile ends with ".pairs" +## If "-1" all particles will be simulated in a single event +## +SIM.guineapig.particlesPerEvent = "-1" + + +################################################################################ +## Configuration for the DDG4 ParticleGun +################################################################################ + +## direction of the particle gun, 3 vector +SIM.gun.direction = (0, 0, 1) + +## choose the distribution of the random direction for theta +## +## Options for random distributions: +## +## 'uniform' is the default distribution, flat in theta +## 'cos(theta)' is flat in cos(theta) +## 'eta', or 'pseudorapidity' is flat in pseudorapity +## 'ffbar' is distributed according to 1+cos^2(theta) +## +## Setting a distribution will set isotrop = True +## +SIM.gun.distribution = None +SIM.gun.energy = 10000.0 + +## isotropic distribution for the particle gun +## +## use the options phiMin, phiMax, thetaMin, and thetaMax to limit the range of randomly distributed directions +## if one of these options is not None the random distribution will be set to True and cannot be turned off! +## +SIM.gun.isotrop = False +SIM.gun.multiplicity = 1 +SIM.gun.particle = "mu-" +SIM.gun.phiMax = None + +## Minimal azimuthal angle for random distribution +SIM.gun.phiMin = None + +## position of the particle gun, 3 vector +SIM.gun.position = (0.0, 0.0, 0.0) +SIM.gun.thetaMax = None +SIM.gun.thetaMin = None + + +################################################################################ +## Configuration for the output levels of DDG4 components +################################################################################ + +## Output level for input sources +SIM.output.inputStage = 3 + +## Output level for Geant4 kernel +SIM.output.kernel = 3 + +## Output level for ParticleHandler +SIM.output.part = 3 + +## Output level for Random Number Generator setup +SIM.output.random = 6 + + +################################################################################ +## Configuration for the Particle Handler/ MCTruth treatment +################################################################################ + +## Enable lots of printout on simulated hits and MC-truth information +SIM.part.enableDetailedHitsAndParticleInfo = False + +## Keep all created particles +SIM.part.keepAllParticles = False + +## Minimal distance between particle vertex and endpoint of parent after +## which the vertexIsNotEndpointOfParent flag is set +## +SIM.part.minDistToParentVertex = 2.2e-14 + +## MinimalKineticEnergy to store particles created in the tracking region +SIM.part.minimalKineticEnergy = 1 * MeV + +## Printout at End of Tracking +SIM.part.printEndTracking = False + +## Printout at Start of Tracking +SIM.part.printStartTracking = False + +## List of processes to save, on command line give as whitespace separated string in quotation marks +SIM.part.saveProcesses = ["Decay"] + + +################################################################################ +## Configuration for the PhysicsList +################################################################################ +# this needs to be set to False if any standard physics list is used: +SIM.physics.decays = False +SIM.physics.list = "QGSP_BERT" # "FTFP_BERT" + +## location of particle.tbl file containing extra particles and their lifetime information +## +SIM.physics.pdgfile = os.path.join( + os.environ.get("DD4HEP"), "DDG4/examples/particle.tbl" +) + +## The global geant4 rangecut for secondary production +## +## Default is 0.7 mm as is the case in geant4 10 +## +## To disable this plugin and be absolutely sure to use the Geant4 default range cut use "None" +## +## Set printlevel to DEBUG to see a printout of all range cuts, +## but this only works if range cut is not "None" +## +SIM.physics.rangecut = 0.1 * mm + + +################################################################################ +## Properties for the random number generator +################################################################################ + +## If True, calculate random seed for each event based on eventID and runID +## allows reproducibility even when SkippingEvents +SIM.random.enableEventSeed = True #False +SIM.random.file = None +SIM.random.luxury = 1 +SIM.random.replace_gRandom = True +SIM.random.seed = 42 #None +SIM.random.type = None + +# --------------------------------------------- +# +# Configure ML inference +# +# --------------------------------------------- + + +def aiDance(kernel): + ild = True + par04 = True # False + old_DD4hep = False ## use for DD4hep versions/commits before ~ Apr 21st 2023 + + if ild == True: + ml_barrel_name = "EcalBarrel" + ml_barrel_symmetry = 8 + ml_endcap_name = "EcalEndcap" + else: + ml_barrel_name = "ECalBarrel" + ml_barrel_symmetry = 12 + ml_endcap_name = "ECalEndcap" + + if par04 == True: + ml_file = "../models/Generator.onnx" + ml_model = "Par04ExampleVAEPolyhedraBarrelONNXModel/ShowerModel" + ml_model1 = "Par04ExampleVAEEndcapONNXModel/ShowerModel" + else: + ml_file = "../models/francisca_gan.onnx" + ml_model = "RegularGridGANPolyhedraBarrelONNXModel/ShowerModel" + ml_model1 = "RegularGridGANEndcapONNXModel/ShowerModel" + + ml_correct_angles = True + + from g4units import GeV, MeV # DO NOT REMOVE OR MOVE!!!!! (EXCLAMATION MARK) + from DDG4 import DetectorConstruction, Geant4, PhysicsList + + geant4 = Geant4(kernel) + seq = geant4.detectorConstruction() + + if old_DD4hep: # this is now done in DD4hepSimulations.py, i.e. in ddsim + seq, act = geant4.addDetectorConstruction( + "Geant4DetectorGeometryConstruction/ConstructGeo" + ) + act.DebugMaterials = True + act.DebugElements = False + act.DebugVolumes = True + act.DebugShapes = True + # Apply sensitive detectors + sensitives = DetectorConstruction( + kernel, str("Geant4DetectorSensitivesConstruction/ConstructSD") + ) + sensitives.enableUI() + seq.adopt(sensitives) + + # ----------------- + model = DetectorConstruction(kernel, str(ml_model)) + + ## # Mandatory model parameters + model.RegionName = "EcalBarrelRegion" + model.Detector = ml_barrel_name + model.Symmetry = ml_barrel_symmetry + model.Enable = True + model.CorrectForAngles = ml_correct_angles + # Energy boundaries are optional: Units are GeV + model.ApplicableParticles = {"e+", "e-", "gamma"} + model.Etrigger = {"e+": 5.0 * GeV, "e-": 5.0 * GeV, "gamma": 5.0 * GeV} + model.ModelPath = ml_file + model.OptimizeFlag = 1 + + model.enableUI() + seq.adopt(model) + # ------------------- + model1 = DetectorConstruction(kernel, str(ml_model1)) + + ## # Mandatory model parameters + model1.RegionName = "EcalEndcapRegion" + model1.Detector = ml_endcap_name + model1.Enable = True + model1.CorrectForAngles = ml_correct_angles + # Energy boundaries are optional: Units are GeV + model1.ApplicableParticles = {"e+", "e-", "gamma"} + model1.Etrigger = {"e+": 5.0 * GeV, "e-": 5.0 * GeV, "gamma": 5.0 * GeV} + model1.ModelPath = ml_file + model.OptimizeFlag = 1 + + model1.enableUI() + seq.adopt(model1) + # ------------------- + + # Now build the physics list: + phys = kernel.physicsList() + ph = PhysicsList(kernel, str("Geant4FastPhysics/FastPhysicsList")) + ph.EnabledParticles = ["e+", "e-", "gamma"] + ph.BeVerbose = True + ph.enableUI() + phys.adopt(ph) + phys.dump() + + +def aiDanceTorch(kernel): + ild = True + BIBAE = True + Two_Angle = True #True + old_DD4hep = False ## use for DD4hep versions/commits before ~ Apr 21st 2023 + + if ild == True: + ml_barrel_name = "EcalBarrel" + ml_barrel_symmetry = 8 + ml_endcap_name = "EcalEndcap" + else: + ml_barrel_name = "ECalBarrel" + ml_barrel_symmetry = 12 + ml_endcap_name = "ECalEndcap" + + if BIBAE == True and Two_Angle == False: + ml_file = "../models/BIBAE_Full_PP_cut.pt" + ml_model = "RegularGridBIBAEPolyhedraBarrelTorchModel/BarrelModelTorch" + ml_model_1 = "RegularGridBIBAEEndcapTorchModel/EndcapModelTorch" + ml_correct_angles = False + elif BIBAE == True and Two_Angle == True: + ml_file = "../models/BIBAE_Two_Angle_Full_PP_cut.pt" + ml_model = ( + "RegularGridTwoAngleBIBAEModelPolyhedraBarrelTorchModel/BarrelModelTorch" + ) + ml_model_1 = "RegularGridTwoAngleBIBAEModelEndcapTorchModel/EndcapModelTorch" + ml_correct_angles = False + else: + ml_file = "../models/francisca_gan_jit.pt" + ml_model = "RegularGridGANPolyhedraBarrelTorchModel/BarrelModelTorch" + ml_model_1 = "RegularGridGANEndcapTorchModel/EndcapModelTorch" + ml_correct_angles = True + + from g4units import GeV, MeV # DO NOT REMOVE OR MOVE!!!!! (EXCLAMATION MARK) + from DDG4 import DetectorConstruction, Geant4, PhysicsList + + geant4 = Geant4(kernel) + + seq = geant4.detectorConstruction() + + if old_DD4hep: # this is now done in DD4hepSimulations.py, i.e. in ddsim + seq, act = geant4.addDetectorConstruction( + "Geant4DetectorGeometryConstruction/ConstructGeo" + ) + act.DebugMaterials = True + act.DebugElements = False + act.DebugVolumes = True + act.DebugShapes = True + + # Apply sensitive detectors + sensitives = DetectorConstruction( + kernel, str("Geant4DetectorSensitivesConstruction/ConstructSD") + ) + sensitives.enableUI() + seq.adopt(sensitives) + + # ----------------- + model = DetectorConstruction(kernel, str(ml_model)) + + ## # Mandatory model parameters + model.RegionName = "EcalBarrelRegion" + model.Detector = ml_barrel_name + model.Symmetry = ml_barrel_symmetry + model.Enable = True + model.CorrectForAngles = ml_correct_angles + # Energy boundaries are optional: Units are GeV + model.ApplicableParticles = {"e+", "e-", "gamma"} + model.Etrigger = { + "e+": 10.0 * GeV, + "e-": 10.0 * GeV, + "gamma": 10.0 * GeV, + } # trigger on lower training threshold + model.ModelPath = ml_file + model.OptimizeFlag = 1 + model.IntraOpNumThreads = 1 + + model.enableUI() + seq.adopt(model) + # ------------------- + model1 = DetectorConstruction(kernel, str(ml_model_1)) + + ## # Mandatory model parameters + model1.RegionName = "EcalEndcapRegion" + model1.Detector = ml_endcap_name + model1.Enable = True + model1.CorrectForAngles = ml_correct_angles + # Energy boundaries are optional: Units are GeV + model1.ApplicableParticles = {"e+", "e-", "gamma"} + model1.Etrigger = { + "e+": 10.0 * GeV, + "e-": 10.0 * GeV, + "gamma": 10.0 * GeV, + } # trigger on lower training threshold + model1.ModelPath = ml_file + model1.OptimizeFlag = 1 + model1.IntraOpNumThreads = 1 + + model1.enableUI() + seq.adopt(model1) + # ------------------- + + # Now build the physics list: + phys = kernel.physicsList() + ph = PhysicsList(kernel, str("Geant4FastPhysics/FastPhysicsList")) + ph.EnabledParticles = ["e+", "e-", "gamma"] + ph.BeVerbose = True + ph.enableUI() + phys.adopt(ph) + phys.dump() + + +def LoadHdf5(kernel): + ild = True + BIBAE = True + Two_Angle = True + old_DD4hep = False ## use for DD4hep versions/commits before ~ Apr 21st 2023 + hadrons = True + + if ild == True: + ml_barrel_name = "EcalBarrel" + ml_barrel_symmetry = 8 + ml_endcap_name = "EcalEndcap" + + ## For hadron shower fast simulation + ml_had_barrel_name = "HcalBarrel" + ml_had_barrel_symmetry = 8 + ml_had_endcap_name = "HcalEndcap" + + else: + ml_barrel_name = "ECalBarrel" + ml_barrel_symmetry = 12 + ml_endcap_name = "ECalEndcap" + + ## For hadron shower fast simulation is needed + ml_had_barrel_name = "HCalBarrel" + ml_had_barrel_symmetry = 12 + ml_had_endcap_name = "HCalEndcap" + + if BIBAE == True and Two_Angle == True: + ml_file = "../models/photons-E5050A-theta9090A-phi9090-p1.hdf5" + ml_model = ( + "LoadHDF5RegularGridTwoAngleBIBAEModelPolyhedraBarrel/BarrelModelTorch" + ) + ml_model_1 = "LoadHDF5RegularGridTwoAngleBIBAEModelEndcap/EndcapModelTorch" + ml_correct_angles = False + + if hadrons == True: + ml_model_had = "LoadHDF5PionCloudsPCHadronModelPolyhedraBarrel/BarrelModelTorch" + ml_had_file = "../models/PionClouds_50GeV_sp.h5" #"../models/PionClouds_50GeV_sp_scaled.h5" + ml_correct_angles = False + + from g4units import GeV, MeV # DO NOT REMOVE OR MOVE!!!!! (EXCLAMATION MARK) + from DDG4 import DetectorConstruction, Geant4, PhysicsList + + geant4 = Geant4(kernel) + + seq = geant4.detectorConstruction() + + if old_DD4hep: # this is now done in DD4hepSimulations.py, i.e. in ddsim + seq, act = geant4.addDetectorConstruction( + "Geant4DetectorGeometryConstruction/ConstructGeo" + ) + act.DebugMaterials = True + act.DebugElements = False + act.DebugVolumes = True + act.DebugShapes = True + + # Apply sensitive detectors + sensitives = DetectorConstruction( + kernel, str("Geant4DetectorSensitivesConstruction/ConstructSD") + ) + sensitives.enableUI() + seq.adopt(sensitives) + + # ----------------- + ''' + ## EM in Barrel + model = DetectorConstruction(kernel, str(ml_model)) + + ## # Mandatory model parameters + model.RegionName = "EcalBarrelRegion" + model.Detector = ml_barrel_name + model.Symmetry = ml_barrel_symmetry + model.Enable = True + model.CorrectForAngles = ml_correct_angles + # Energy boundaries are optional: Units are GeV + model.ApplicableParticles = {"e+", "e-", "gamma"} + model.Etrigger = { + "e+": 10.0 * GeV, + "e-": 10.0 * GeV, + "gamma": 10.0 * GeV, + } # trigger on lower training threshold + model.FilePath = ml_file + # model.OptimizeFlag = 1 + # model.IntraOpNumThreads = 1 + + model.enableUI() + seq.adopt(model) + ''' + # ------------------- + ## EM in Endcap + model1 = DetectorConstruction(kernel, str(ml_model_1)) + + ## # Mandatory model parameters + model1.RegionName = "EcalEndcapRegion" + model1.Detector = ml_endcap_name + model1.Enable = True + model1.CorrectForAngles = ml_correct_angles + # Energy boundaries are optional: Units are GeV + model1.ApplicableParticles = {"e+", "e-", "gamma"} + model1.Etrigger = { + "e+": 10.0 * GeV, + "e-": 10.0 * GeV, + "gamma": 10.0 * GeV, + } # trigger on lower training threshold + model1.FilePath = ml_file + # model1.OptimizeFlag = 1 + # model1.IntraOpNumThreads = 1 + + model1.enableUI() + seq.adopt(model1) + + # ------------------- + ## Hadrons in Barrel + modelHad1 = DetectorConstruction(kernel, str(ml_model_had)) + + ## # Mandatory model parameters + modelHad1.isHadShower = True + modelHad1.RegionName = "EcalBarrelRegion" #or "HcalBarrelRegion" ## hadron model triggers in ecal + modelHad1.Detector = ml_barrel_name + modelHad1.HadDetector = ml_had_barrel_name + modelHad1.Symmetry = ml_barrel_symmetry + modelHad1.HadSymmetry = ml_had_barrel_symmetry + modelHad1.Enable = True + modelHad1.CorrectForAngles = ml_correct_angles + # Energy boundaries are optional: Units are GeV + modelHad1.ApplicableParticles = {"pi+"} + modelHad1.Etrigger = {"pi+": 10.0 * GeV} # trigger on lower training threshold + modelHad1.FilePath = ml_had_file + # model.OptimizeFlag = 1 + # model.IntraOpNumThreads = 1 + + modelHad1.enableUI() + seq.adopt(modelHad1) + + # ------------------- + + # Now build the physics list: + phys = kernel.physicsList() + ph = PhysicsList(kernel, str("Geant4FastPhysics/FastPhysicsList")) + ph.EnabledParticles = ["e+", "e-", "gamma", "pi+"] + ph.BeVerbose = True + ph.enableUI() + phys.adopt(ph) + phys.dump() + + +#SIM.physics.setupUserPhysics( aiDance) +#SIM.physics.setupUserPhysics(aiDanceTorch) +SIM.physics.setupUserPhysics(LoadHdf5) diff --git a/scripts/test_onnx.mac b/scripts/test_onnx.mac index 3d5a716..4226261 100644 --- a/scripts/test_onnx.mac +++ b/scripts/test_onnx.mac @@ -3,7 +3,7 @@ # example script to run inference on a GAN w/ ONNX runtime # --- the particle gun -/gps/pos/centre 30 180.48 0 #120 180.48 120 #30 180.48 0 #30 0 0 +/gps/pos/centre 30 0 0 #30 180.48 0 #### this is ILD calo Face #120 180.48 120 #30 180.48 0 #30 0 0 #/gps/particle gamma /gps/particle pi+ /gps/energy 50 GeV @@ -64,5 +64,5 @@ #/gps/direction 0.1 -0.8 .1 -/run/beamOn 2000 #100 +/run/beamOn 100 #2000 #100 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2882c79..0a0114c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -35,6 +35,18 @@ if(INSTRUMENT_MODEL) ) endif() +if(RECORD_CALO_IMPACT) + target_sources(${PROJECT_NAME} PRIVATE + DDMLRunAction.cc + DDMLEventAction.cc + ) + target_compile_definitions(${PROJECT_NAME} PUBLIC + DDML_RECORD_CALO_IMPACT=1 + ) +endif() + + + if(OnnxRuntime_FOUND) target_sources(${PROJECT_NAME} PRIVATE ONNXInference.cc @@ -111,6 +123,10 @@ if(HDF5_FOUND) list(APPEND headers ${PROJECT_SOURCE_DIR}/include/DDML/LoadHdf5.h) endif() +if(RECORD_CALO_IMPACT) + list(APPEND headers ${PROJECT_SOURCE_DIR}/include/DDML/DDMLRunAction.h ${PROJECT_SOURCE_DIR}/include/DDML/DDMLEventAction.h) +endif() + #install(FILES # ${headers} # DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) diff --git a/src/DDMLEventAction.cc b/src/DDMLEventAction.cc new file mode 100644 index 0000000..7decd72 --- /dev/null +++ b/src/DDMLEventAction.cc @@ -0,0 +1,58 @@ +#include "DDML/DDMLEventAction.h" +#include "G4AnalysisManager.hh" +#include "DD4hep/InstanceCount.h" +#include "G4Event.hh" +#include "G4EventManager.hh" +#include "G4ThreeVector.hh" +#include "G4PrimaryVertex.hh" +#include "G4PrimaryParticle.hh" +#include "DDG4/Geant4Data.h" + +#define DEBUGPRINT 0 + +namespace ddml { + +DDMLEventAction::DDMLEventAction(dd4hep::sim::Geant4Context* c, const std::string& n): +Geant4EventAction(c,n) + { + dd4hep::InstanceCount::increment(this); + } + +/// Default destructor +DDMLEventAction::~DDMLEventAction() { + dd4hep::InstanceCount::decrement(this); + } + +void DDMLEventAction::begin(const G4Event*){} + +void DDMLEventAction::end(const G4Event*) { + // Get analysis manager + auto analysisManager = G4AnalysisManager::Instance(); + + // Retrieve information from primary vertex and primary particle + auto primaryVertex = + G4EventManager::GetEventManager()->GetConstCurrentEvent()->GetPrimaryVertex(); + G4ThreeVector primaryVertexPos = primaryVertex->GetPosition(); + auto primaryParticle = primaryVertex->GetPrimary(0); + G4double primaryEnergy = primaryParticle->GetTotalEnergy(); + G4ThreeVector primaryDirection = primaryParticle->GetMomentumDirection(); + G4int primaryPDG = primaryParticle->GetPDGcode(); + + // Fill analysis manager + analysisManager->FillNtupleIColumn(0, 0, primaryPDG); + analysisManager->FillNtupleDColumn(0, 1, primaryEnergy); + analysisManager->FillNtupleDColumn(0, 2, primaryVertexPos.x()); + analysisManager->FillNtupleDColumn(0, 3, primaryVertexPos.y()); + analysisManager->FillNtupleDColumn(0, 4, primaryVertexPos.z()); + analysisManager->FillNtupleDColumn(0, 5, primaryDirection.x()); + analysisManager->FillNtupleDColumn(0, 6, primaryDirection.y()); + analysisManager->FillNtupleDColumn(0, 7, primaryDirection.z()); + + analysisManager->AddNtupleRow(0); + +} + +} //namespace + +#include "DDG4/Factories.h" +DECLARE_GEANT4ACTION_NS(ddml, DDMLEventAction) diff --git a/src/DDMLRunAction.cc b/src/DDMLRunAction.cc new file mode 100644 index 0000000..c7cd807 --- /dev/null +++ b/src/DDMLRunAction.cc @@ -0,0 +1,94 @@ +#include "DDML/DDMLRunAction.h" +#include "DDML/DDMLEventAction.h" +#include "G4AnalysisManager.hh" +#include "G4EventManager.hh" +#include "DD4hep/InstanceCount.h" +#include "G4Run.hh" + +#define DEBUGPRINT 0 + +namespace ddml { + +/// Standard constructor with initializing arguments +DDMLRunAction::DDMLRunAction(dd4hep::sim::Geant4Context* c, const std::string& n): + Geant4RunAction(c, n) { + // Create analysis manager + G4AnalysisManager* analysisManager = G4AnalysisManager::Instance(); + analysisManager->SetDefaultFileType("root"); + + // Default filename, can be overriden with /analysis/setFileName + analysisManager->SetFileName("Output"); + dd4hep::InstanceCount::increment(this); +} + +/// Default destructor +DDMLRunAction::~DDMLRunAction() { + dd4hep::InstanceCount::decrement(this); +} + +/// begin-of-run callback +void DDMLRunAction::begin(const G4Run*) { + // Get analysis manager +G4AnalysisManager* analysisManager = G4AnalysisManager::Instance(); + +// Create directories +analysisManager->SetVerboseLevel(0); + +// Create ntuples +analysisManager->CreateNtuple("global", "Event data"); +analysisManager->CreateNtupleIColumn("MC_PDG"); +analysisManager->CreateNtupleDColumn("MC_Energy"); +analysisManager->CreateNtupleDColumn("MC_PosX"); +analysisManager->CreateNtupleDColumn("MC_PosY"); +analysisManager->CreateNtupleDColumn("MC_PosZ"); +analysisManager->CreateNtupleDColumn("MC_DirX"); +analysisManager->CreateNtupleDColumn("MC_DirY"); +analysisManager->CreateNtupleDColumn("MC_DirZ"); +analysisManager->FinishNtuple(); + +/* +DDMLEventAction* mEventAction = dynamic_cast(G4EventManager::GetEventManager()->GetUserEventAction()); +analysisManager->CreateNtuple("Fast Sim Info", "MC info at calo face"); +analysisManager->CreateNtupleIColumn("Calo_MC_PDG", mEventAction->GetCaloMC_PDG()); +analysisManager->CreateNtupleDColumn("Calo_MC_Energy", mEventAction->GetCaloMC_E()); +analysisManager->CreateNtupleDColumn("Calo_MC_PosX", mEventAction->GetCaloMC_PosX()); +analysisManager->CreateNtupleDColumn("Calo_MC_PosY", mEventAction->GetCaloMC_PosY()); +analysisManager->CreateNtupleDColumn("Calo_MC_PosZ", mEventAction->GetCaloMC_PosZ()); +analysisManager->CreateNtupleDColumn("Calo_MC_DirX", mEventAction->GetCaloMC_DirX()); +analysisManager->CreateNtupleDColumn("Calo_MC_DirY", mEventAction->GetCaloMC_DirY()); +analysisManager->CreateNtupleDColumn("Calo_MC_DirZ", mEventAction->GetCaloMC_DirZ()); +analysisManager->FinishNtuple(); +*/ + +analysisManager->CreateNtuple("Fast_Sim_Info", "MC info at calo face"); +analysisManager->CreateNtupleIColumn("Calo_MC_PDG"); +analysisManager->CreateNtupleDColumn("Calo_MC_Energy"); +analysisManager->CreateNtupleDColumn("Calo_MC_PosX"); +analysisManager->CreateNtupleDColumn("Calo_MC_PosY"); +analysisManager->CreateNtupleDColumn("Calo_MC_PosZ"); +analysisManager->CreateNtupleDColumn("Calo_MC_DirX"); +analysisManager->CreateNtupleDColumn("Calo_MC_DirY"); +analysisManager->CreateNtupleDColumn("Calo_MC_DirZ"); +analysisManager->FinishNtuple(); + + +analysisManager->CreateNtuple("run", "Run data"); +analysisManager->CreateNtupleDColumn("N"); +analysisManager->FinishNtuple(); + +analysisManager->OpenFile(); +} + +/// End-of-run callback +void DDMLRunAction::end(const G4Run* aRun){ + auto analysisManager = G4AnalysisManager::Instance(); + analysisManager->FillNtupleDColumn(2, 0, aRun->GetNumberOfEvent()); + analysisManager->AddNtupleRow(2); + analysisManager->Write(); + analysisManager->CloseFile(); +} + +} // namespace + +#include "DDG4/Factories.h" +DECLARE_GEANT4ACTION_NS(ddml, DDMLRunAction) \ No newline at end of file diff --git a/src/PionCloudsModel.cc b/src/PionCloudsModel.cc index 6b04e9e..0dbad53 100644 --- a/src/PionCloudsModel.cc +++ b/src/PionCloudsModel.cc @@ -124,8 +124,8 @@ namespace ddml { for (int i = 0; i < nPoints; i++) { ddml::SpacePoint sp( - reshaped[i][0]*1e3, // x // *(-1) to align local to global convention in ddml - reshaped[i][2]*1e3, // y // *(-1) to align local to global convention in ddml + reshaped[i][0], // x // *(-1) to align local to global convention in ddml + reshaped[i][2], // y // *(-1) to align local to global convention in ddml 0., // z reshaped[i][3], // energy 0. // time From 1334419ce70ba393034e56404606dc86dd25a301 Mon Sep 17 00:00:00 2001 From: Peter McKeown Date: Tue, 25 Feb 2025 11:24:47 +0100 Subject: [PATCH 16/36] Updates ready for obtaining calo entries --- include/DDML/PionCloudsModel.h | 2 +- scripts/ddsim_steer_Record_Calo_entry.py | 5 +- scripts/test_onnx.mac | 17 ++- src/Geant4FastHitMakerGlobal.cc | 8 +- src/LoadHdf5.cc | 2 +- src/PionCloudsModel.cc | 129 ++++++++++++----------- 6 files changed, 93 insertions(+), 70 deletions(-) diff --git a/include/DDML/PionCloudsModel.h b/include/DDML/PionCloudsModel.h index 0bb9bfc..111a602 100644 --- a/include/DDML/PionCloudsModel.h +++ b/include/DDML/PionCloudsModel.h @@ -55,7 +55,7 @@ namespace ddml { /// model properties for plugin // These grid sizes were used for the two angle BIBAE - int m_numPoints = 2600; + int m_numPoints = 2600; //4148; //2600; //number of points in the shower int m_latentSize = 3; // number of input features (energy, theta, phi) int m_maxNumElements = m_numPoints*4; // number of space points in the output multiplied by 4 (x,y,z,energy) int m_nLayer = 78; diff --git a/scripts/ddsim_steer_Record_Calo_entry.py b/scripts/ddsim_steer_Record_Calo_entry.py index 6107367..1f21c95 100644 --- a/scripts/ddsim_steer_Record_Calo_entry.py +++ b/scripts/ddsim_steer_Record_Calo_entry.py @@ -542,7 +542,8 @@ def LoadHdf5(kernel): if hadrons == True: ml_model_had = "LoadHDF5PionCloudsPCHadronModelPolyhedraBarrel/BarrelModelTorch" - ml_had_file = "../models/PionClouds_50GeV_sp.h5" #"../models/PionClouds_50GeV_sp_scaled.h5" + ml_had_file = "../models/PionClouds_50GeV_sp_scaled.h5" #"../models/gen_showers_for_reco_50GeV_2000.hdf5" + #"../models/gen_showers_50GeV_2000_Martina.hdf5" #"../models/PionClouds_50GeV_sp_scaled.h5" #"../models/PionClouds_50GeV_sp.h5" # ml_correct_angles = False from g4units import GeV, MeV # DO NOT REMOVE OR MOVE!!!!! (EXCLAMATION MARK) @@ -631,7 +632,7 @@ def LoadHdf5(kernel): modelHad1.CorrectForAngles = ml_correct_angles # Energy boundaries are optional: Units are GeV modelHad1.ApplicableParticles = {"pi+"} - modelHad1.Etrigger = {"pi+": 10.0 * GeV} # trigger on lower training threshold + modelHad1.Etrigger = {"pi+": 30.0 * GeV} #{"pi+": 10.0 * GeV} # trigger on lower training threshold modelHad1.FilePath = ml_had_file # model.OptimizeFlag = 1 # model.IntraOpNumThreads = 1 diff --git a/scripts/test_onnx.mac b/scripts/test_onnx.mac index 4226261..a748499 100644 --- a/scripts/test_onnx.mac +++ b/scripts/test_onnx.mac @@ -3,13 +3,24 @@ # example script to run inference on a GAN w/ ONNX runtime # --- the particle gun -/gps/pos/centre 30 0 0 #30 180.48 0 #### this is ILD calo Face #120 180.48 120 #30 180.48 0 #30 0 0 + +# At right side face (perpendicular to x=0) +#/gps/pos/centre 18.47 0 0 #0 180.47 150 #### this is ILD calo Face #120 180.48 120 #30 180.48 0 #30 0 0 +#30 0 0 + +#/gps/pos/centre 0 0 0 #0 180.47 150 #### this is ILD calo Face #120 180.48 120 #30 180.48 0 #30 0 0 +#30 0 0 #/gps/particle gamma + +# for SimpleCalo +#/gps/direction 1 0 0 #0 1 0 #-0.4152 1 0 #(pi/8 + pi/4) #1 0.414213562 0 #(pi/8) #-1 2.414213562 0 #(pi/8 + 1 deg) # 0.25 0.25 0.5 #0 0.5 0.655 # ( 37 deg in theta- most you can get in endcap from IP ) + /gps/particle pi+ /gps/energy 50 GeV -# for SimpleCalo -/gps/direction 0 1 0 #-0.4152 1 0 #(pi/8 + pi/4) #1 0.414213562 0 #(pi/8) #-1 2.414213562 0 #(pi/8 + 1 deg) # 0.25 0.25 0.5 #0 0.5 0.655 # ( 37 deg in theta- most you can get in endcap from IP ) +/gps/pos/centre -5 0 -15 +/gps/direction -0.037864591009775746 0.9992828792427412 0 # 90 deg imact for 50 GeV p+ + # phi barrel #1 0.414213562 0 #(pi/8) diff --git a/src/Geant4FastHitMakerGlobal.cc b/src/Geant4FastHitMakerGlobal.cc index bd7108f..2395447 100644 --- a/src/Geant4FastHitMakerGlobal.cc +++ b/src/Geant4FastHitMakerGlobal.cc @@ -49,8 +49,8 @@ Geant4FastHitMakerGlobal::~Geant4FastHitMakerGlobal() { void Geant4FastHitMakerGlobal::make(const G4FastHit& aHit, const G4FastTrack& aTrack) { - std::cout << "Geant4FastHitMakerGlobal::make - aHit.GetPosition().x() " << aHit.GetPosition().x() << " aHit.GetPosition().y() " << - aHit.GetPosition().y() << " aHit.GetPosition().z() " << aHit.GetPosition().z() << std::endl; + //std::cout << "Geant4FastHitMakerGlobal::make - aHit.GetPosition().x() " << aHit.GetPosition().x() << " aHit.GetPosition().y() " << + // aHit.GetPosition().y() << " aHit.GetPosition().z() " << aHit.GetPosition().z() << std::endl; // do not make empty deposit if (aHit.GetEnergy() <= 0) { return; @@ -88,8 +88,8 @@ void Geant4FastHitMakerGlobal::make(const G4FastHit& aHit, const G4FastTrack& aT sensitive = currentVolume->GetLogicalVolume()->GetSensitiveDetector(); G4VFastSimSensitiveDetector* fastSimSensitive = dynamic_cast(sensitive); if (fastSimSensitive) { - std::cout << "IN FAST Sim Sensitive Geant4FastHitMakerGlobal::make - aHit.GetPosition().x() " << aHit.GetPosition().x() << " aHit.GetPosition().y() " << - aHit.GetPosition().y() << " aHit.GetPosition().z() " << aHit.GetPosition().z() << " Energy: " << aHit.GetEnergy() << std::endl; + // std::cout << "IN FAST Sim Sensitive Geant4FastHitMakerGlobal::make - aHit.GetPosition().x() " << aHit.GetPosition().x() << " aHit.GetPosition().y() " << + // aHit.GetPosition().y() << " aHit.GetPosition().z() " << aHit.GetPosition().z() << " Energy: " << aHit.GetEnergy() << std::endl; fastSimSensitive->Hit(&aHit, &aTrack, &m_touchableHandle); } else if (sensitive && currentVolume->GetLogicalVolume()->GetFastSimulationManager()) { G4cerr << "ERROR - Geant4FastHitMakerGlobal::make()" << G4endl << " It is required to derive from the " diff --git a/src/LoadHdf5.cc b/src/LoadHdf5.cc index 2cb8360..5007782 100644 --- a/src/LoadHdf5.cc +++ b/src/LoadHdf5.cc @@ -19,7 +19,7 @@ void LoadHdf5::initialize() { // inputs and TensorDimVecs unused // Open dataset + dataspace - std::string datasetName = "spase_points"; //"layers"; + std::string datasetName = "spase_points"; //"events"; //"spase_points"; //"layers"; H5::DataSet dataset = m_file.openDataSet(datasetName); dd4hep::printout(dd4hep::DEBUG, "LoadHdf5::initialize", "Accessed HDF5 dataset"); H5::DataSpace dataspace = dataset.getSpace(); diff --git a/src/PionCloudsModel.cc b/src/PionCloudsModel.cc index 0dbad53..888afc2 100644 --- a/src/PionCloudsModel.cc +++ b/src/PionCloudsModel.cc @@ -70,73 +70,84 @@ namespace ddml { } - - void PionCloudsModel::convertOutput(G4FastTrack const& aFastTrack, - G4ThreeVector const& localDir, - const std::vector& output, - std::vector& spacepoints ){ - - int nPoints = m_numPoints ; // number of points in shower - - dd4hep::printout(dd4hep::DEBUG, "PionCloudsModel::convertOutput", "m_numPoints : %i", m_numPoints); +/* For array structure: (No. showers, dimensions(4), No. points) +void PionCloudsModel::convertOutput(G4FastTrack const& aFastTrack, + G4ThreeVector const& localDir, + const std::vector& output, + std::vector& spacepoints ){ - spacepoints.resize( m_nLayer ) ; + //int nPoints = m_numPoints ; // number of points in shower - int numSP = 0; int layerNum = 0; - int numElements = 0; - for (int i = 0; i < m_nLayer; i++) { - numSP = output[i] + 1; - spacepoints[i].reserve(numSP); - numElements += output[i] * 4; - } - std::cout << " PionCloudsModel::convertOutput DONE numElements, numElements = " << numElements << std::endl; - - /* - for (int i = m_nLayer; i < m_nLayer + numElements; i += 4) { - std::cout << " PionCloudsModel::convertOutput Layer Loop, i = " << i << std::endl; - std::cout << " PionCloudsModel::convertOutput Layer Loop, output[i] " << output[i] << std::endl; - std::cout << " PionCloudsModel::convertOutput Layer Loop, output[i+1] " << output[i] << std::endl; - std::cout << " PionCloudsModel::convertOutput Layer Loop, output[i+3] " << output[i] << std::endl; - ddml::SpacePoint sp( - output[i], // x // *(-1) to align local to global convention in ddml - output[i+1], // y // *(-1) to align local to global convention in ddml - 0., // z - output[i+3], // energy - 0. // time - ); - layerNum = output[i+2]; - std::cout << " PionCloudsModel::convertOutput Layer Loop, layerNum " << layerNum << std::endl; - spacepoints[layerNum].emplace_back( sp ) ; - */ - - - float reshaped[2600][4]; - - // Fill the 3D array using the flattened vector - size_t index = 0; - for (size_t j = 0; j < 2600; ++j) { - for (size_t k = 0; k < 4; ++k) { + /// This is too C-like - once model is concrete use std::vector + //float reshaped[m_numPoints][4]; + std::vector> reshaped(4, std::vector(m_numPoints)); + + // Fill the 3D array-like vector using the flattened vector + int index = 0; + for (int j = 0; j < 4; ++j) { + for (int k = 0; k < m_numPoints; ++k) { reshaped[j][k] = output[index++]; } } - for (int i = 0; i < nPoints; i++) { - ddml::SpacePoint sp( - reshaped[i][0], // x // *(-1) to align local to global convention in ddml - reshaped[i][2], // y // *(-1) to align local to global convention in ddml - 0., // z - reshaped[i][3], // energy - 0. // time - ); - layerNum = reshaped[i][1]; - std::cout << "PionCloudsModel::convertOutput - layerNum" << layerNum <& output, + std::vector& spacepoints ){ + + //int nPoints = m_numPoints ; // number of points in shower + + int layerNum = 0; + + /// This is too C-like - use std::vector + //float reshaped[m_numPoints][4]; + std::vector> reshaped(m_numPoints, std::vector(4)); + + // Fill the 3D array-like vector using the flattened vector + int index = 0; + for (int j = 0; j < m_numPoints; ++j) { + for (int k = 0; k < 4; ++k) { + reshaped[j][k] = output[index]; + index++; + } + } + + spacepoints.resize( m_nLayer ) ; + + for (int i = 0; i < m_numPoints; i++) { + ddml::SpacePoint sp( + reshaped[i][0], // x // *(-1) to align local to global convention in ddml + reshaped[i][2], // y // *(-1) to align local to global convention in ddml + 0., // z + reshaped[i][3], // energy + 0. // time + ); + layerNum = reshaped[i][1]; + //std::cout << "PionCloudsModel::convertOutput - layerNum" << layerNum < Date: Tue, 25 Feb 2025 14:31:08 +0100 Subject: [PATCH 17/36] Update incorrect naming in ONNX inference --- src/ONNXInference.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ONNXInference.cc b/src/ONNXInference.cc index 09e9c4a..261d7ae 100644 --- a/src/ONNXInference.cc +++ b/src/ONNXInference.cc @@ -56,7 +56,7 @@ void ONNXInference::initialize() { std::vector input_node_names(num_input_nodes); for (std::size_t i = 0; i < num_input_nodes; i++) { #if ORT_API_VERSION < 13 - const auto input_name = AllocatedStringPtr(fSession->GetInputName(i, allocator), allocDeleter).release(); + const auto input_name = AllocatedStringPtr(m_Session->GetInputName(i, allocator), allocDeleter).release(); #else const auto input_name = m_session->GetInputNameAllocated(i, allocator).release(); #endif @@ -87,7 +87,7 @@ void ONNXInference::initialize() { std::vector output_node_names(num_output_nodes); for (std::size_t i = 0; i < num_output_nodes; i++) { #if ORT_API_VERSION < 12 - const auto output_name = AllocatedStringPtr(fSession->GetOutputName(i, allocator), allocDeleter).release(); + const auto output_name = AllocatedStringPtr(m_Session->GetOutputName(i, allocator), allocDeleter).release(); #else const auto output_name = m_session->GetOutputNameAllocated(i, allocator).release(); #endif From d0a25af6ffb05da90b906152480f0055cce8dab6 Mon Sep 17 00:00:00 2001 From: Peter McKeown Date: Tue, 25 Feb 2025 14:35:43 +0100 Subject: [PATCH 18/36] Correct capitalisation --- src/ONNXInference.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ONNXInference.cc b/src/ONNXInference.cc index 261d7ae..1f7b30e 100644 --- a/src/ONNXInference.cc +++ b/src/ONNXInference.cc @@ -56,7 +56,7 @@ void ONNXInference::initialize() { std::vector input_node_names(num_input_nodes); for (std::size_t i = 0; i < num_input_nodes; i++) { #if ORT_API_VERSION < 13 - const auto input_name = AllocatedStringPtr(m_Session->GetInputName(i, allocator), allocDeleter).release(); + const auto input_name = AllocatedStringPtr(m_session->GetInputName(i, allocator), allocDeleter).release(); #else const auto input_name = m_session->GetInputNameAllocated(i, allocator).release(); #endif @@ -87,7 +87,7 @@ void ONNXInference::initialize() { std::vector output_node_names(num_output_nodes); for (std::size_t i = 0; i < num_output_nodes; i++) { #if ORT_API_VERSION < 12 - const auto output_name = AllocatedStringPtr(m_Session->GetOutputName(i, allocator), allocDeleter).release(); + const auto output_name = AllocatedStringPtr(m_session->GetOutputName(i, allocator), allocDeleter).release(); #else const auto output_name = m_session->GetOutputNameAllocated(i, allocator).release(); #endif From e422fa57908765ce8072f0b5e225eb14395ddbbe Mon Sep 17 00:00:00 2001 From: Peter McKeown Date: Tue, 25 Feb 2025 14:52:24 +0100 Subject: [PATCH 19/36] Hot fix type of m_dimsOut for older HDF5 versions --- include/DDML/LoadHdf5.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/DDML/LoadHdf5.h b/include/DDML/LoadHdf5.h index 74bdf02..7fdfd44 100644 --- a/include/DDML/LoadHdf5.h +++ b/include/DDML/LoadHdf5.h @@ -49,7 +49,8 @@ class LoadHdf5 : public InferenceInterface { std::vector m_library{}; // shower library dimensions - std::vector m_dimsOut{}; + std::vector m_dimsOut{}; // This is a hot fix for older HDF5 versions! + //std::vector m_dimsOut{}; // properties for plugin std::string m_filePath = {}; From c28a5176ee80d15c9f388c7c707d890a92dedf07 Mon Sep 17 00:00:00 2001 From: Peter McKeown Date: Thu, 8 May 2025 11:19:58 +0200 Subject: [PATCH 20/36] code clean up --- scripts/ddsim_steer.py | 2 +- src/DDMLRunAction.cc | 14 ----------- src/PionCloudsModel.cc | 55 ------------------------------------------ 3 files changed, 1 insertion(+), 70 deletions(-) diff --git a/scripts/ddsim_steer.py b/scripts/ddsim_steer.py index 9c7f8a0..6d24a50 100644 --- a/scripts/ddsim_steer.py +++ b/scripts/ddsim_steer.py @@ -547,7 +547,7 @@ def LoadHdf5(kernel): if hadrons == True: ml_model_had = "LoadHDF5PionCloudsPCHadronModelPolyhedraBarrel/BarrelModelTorch" - ml_had_file = "../models/PionClouds_50GeV_sp.h5" #"../models/PionClouds_50GeV_sp_scaled.h5" + ml_had_file = "../models/PionClouds_50GeV_sp.h5" ml_correct_angles = False from g4units import GeV, MeV # DO NOT REMOVE OR MOVE!!!!! (EXCLAMATION MARK) diff --git a/src/DDMLRunAction.cc b/src/DDMLRunAction.cc index c7cd807..60c92eb 100644 --- a/src/DDMLRunAction.cc +++ b/src/DDMLRunAction.cc @@ -46,20 +46,6 @@ analysisManager->CreateNtupleDColumn("MC_DirY"); analysisManager->CreateNtupleDColumn("MC_DirZ"); analysisManager->FinishNtuple(); -/* -DDMLEventAction* mEventAction = dynamic_cast(G4EventManager::GetEventManager()->GetUserEventAction()); -analysisManager->CreateNtuple("Fast Sim Info", "MC info at calo face"); -analysisManager->CreateNtupleIColumn("Calo_MC_PDG", mEventAction->GetCaloMC_PDG()); -analysisManager->CreateNtupleDColumn("Calo_MC_Energy", mEventAction->GetCaloMC_E()); -analysisManager->CreateNtupleDColumn("Calo_MC_PosX", mEventAction->GetCaloMC_PosX()); -analysisManager->CreateNtupleDColumn("Calo_MC_PosY", mEventAction->GetCaloMC_PosY()); -analysisManager->CreateNtupleDColumn("Calo_MC_PosZ", mEventAction->GetCaloMC_PosZ()); -analysisManager->CreateNtupleDColumn("Calo_MC_DirX", mEventAction->GetCaloMC_DirX()); -analysisManager->CreateNtupleDColumn("Calo_MC_DirY", mEventAction->GetCaloMC_DirY()); -analysisManager->CreateNtupleDColumn("Calo_MC_DirZ", mEventAction->GetCaloMC_DirZ()); -analysisManager->FinishNtuple(); -*/ - analysisManager->CreateNtuple("Fast_Sim_Info", "MC info at calo face"); analysisManager->CreateNtupleIColumn("Calo_MC_PDG"); analysisManager->CreateNtupleDColumn("Calo_MC_Energy"); diff --git a/src/PionCloudsModel.cc b/src/PionCloudsModel.cc index 888afc2..7604f3a 100644 --- a/src/PionCloudsModel.cc +++ b/src/PionCloudsModel.cc @@ -2,8 +2,6 @@ #include // for G4FastTrack -//#include - #define DEBUGPRINT 0 namespace ddml { @@ -31,8 +29,6 @@ namespace ddml { dd4hep::printout(dd4hep::DEBUG, "PionCloudsModel::prepareInput", "DDML::localDir: (%f, %f, %f)", localDir_.x(), localDir_.y(), localDir_.z()); - // std::cout << "PionClouds::localDir:" << "(" << localDir_.x() << "," << localDir_.y() << "," << localDir_.z() << ")" - // << std::endl; // compute local incident angles double r = sqrt(localDir_.x() * localDir_.x() + localDir_.y() * localDir_.y() + localDir_.z() * localDir_.z()); @@ -54,12 +50,6 @@ namespace ddml { inputs[1][0] = theta; // 89.*(M_PI/180.) ; //Theta_vec[0]/(90.*(M_PI/180.)); inputs[2][0] = phi; - // if (DEBUGPRINT) { - // std::cout << " Input_energy_tensor : " << inputs[0][0] << std::endl; - // std::cout << " Input_theta_tensor : " << inputs[1][0] << std::endl; - // std::cout << " Input_phi_tensor : " << inputs[2][0] << std::endl; - // } - dd4hep::printout(dd4hep::DEBUG, "PionCloudsModel::prepareInput", "Input_energy_tensor : %f", inputs[0][0]); dd4hep::printout(dd4hep::DEBUG, "PionCloudsModel::prepareInput", "Input_theta_tensor : %f", inputs[1][0]); dd4hep::printout(dd4hep::DEBUG, "PionCloudsModel::prepareInput", "Input_phi_tensor : %f", inputs[2][0]); @@ -70,46 +60,6 @@ namespace ddml { } -/* For array structure: (No. showers, dimensions(4), No. points) -void PionCloudsModel::convertOutput(G4FastTrack const& aFastTrack, - G4ThreeVector const& localDir, - const std::vector& output, - std::vector& spacepoints ){ - - //int nPoints = m_numPoints ; // number of points in shower - - int layerNum = 0; - - /// This is too C-like - once model is concrete use std::vector - //float reshaped[m_numPoints][4]; - std::vector> reshaped(4, std::vector(m_numPoints)); - - // Fill the 3D array-like vector using the flattened vector - int index = 0; - for (int j = 0; j < 4; ++j) { - for (int k = 0; k < m_numPoints; ++k) { - reshaped[j][k] = output[index++]; - } - } - - spacepoints.resize( m_nLayer ) ; - - for (int i = 0; i < m_numPoints; i++) { - ddml::SpacePoint sp( - reshaped[0][i], // x // *(-1) to align local to global convention in ddml - reshaped[2][i], // y // *(-1) to align local to global convention in ddml - 0., // z - reshaped[3][i], // energy - 0. // time - ); - layerNum = reshaped[1][i]; - spacepoints[layerNum].emplace_back( sp ) ; - } - } -} -*/ - - // For array structure: (No. showers, No. points, dimensions(4)) void PionCloudsModel::convertOutput(G4FastTrack const& aFastTrack, G4ThreeVector const& localDir, @@ -120,8 +70,6 @@ void PionCloudsModel::convertOutput(G4FastTrack const& aFastTrack, int layerNum = 0; - /// This is too C-like - use std::vector - //float reshaped[m_numPoints][4]; std::vector> reshaped(m_numPoints, std::vector(4)); // Fill the 3D array-like vector using the flattened vector @@ -144,9 +92,6 @@ void PionCloudsModel::convertOutput(G4FastTrack const& aFastTrack, 0. // time ); layerNum = reshaped[i][1]; - //std::cout << "PionCloudsModel::convertOutput - layerNum" << layerNum < Date: Fri, 14 Nov 2025 10:31:51 +0100 Subject: [PATCH 21/36] Add support for hadron shower simulation --- CMakeLists.txt | 2 - include/DDML/DDMLEventAction.h | 70 --- include/DDML/DDMLRunAction.h | 39 -- include/DDML/FastMLShower.h | 45 -- include/DDML/LoadHdf5.h | 3 +- scripts/ddsim_steer.py | 4 +- scripts/ddsim_steer_Record_Calo_entry.py | 657 ----------------------- scripts/test_onnx.mac | 2 +- src/CMakeLists.txt | 16 - src/DDMLEventAction.cc | 58 -- src/DDMLRunAction.cc | 80 --- 11 files changed, 4 insertions(+), 972 deletions(-) delete mode 100644 include/DDML/DDMLEventAction.h delete mode 100644 include/DDML/DDMLRunAction.h delete mode 100644 scripts/ddsim_steer_Record_Calo_entry.py delete mode 100644 src/DDMLEventAction.cc delete mode 100644 src/DDMLRunAction.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index d6567a9..2d887d0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,8 +58,6 @@ endif() option(INSTRUMENT_MODEL "Instrument the steps of the showerModel call" OFF) -option(RECORD_CALO_IMPACT "Record properties of particle that triggers modelShower call" OFF) - option(DOWNLOAD_MODELS "Download and install the models that are stored externally" ON) #--------------------------------------------------- diff --git a/include/DDML/DDMLEventAction.h b/include/DDML/DDMLEventAction.h deleted file mode 100644 index 1aa857c..0000000 --- a/include/DDML/DDMLEventAction.h +++ /dev/null @@ -1,70 +0,0 @@ -#include // for G4int, G4double -#include // for vector -#include "G4UserEventAction.hh" // for G4UserEventAction -//#include "G4Timer.hh" // for G4Timer -class G4Event; -#include "DDG4/Geant4Handle.h" -#include "DDG4/Geant4Kernel.h" -#include "DDG4/Geant4EventAction.h" -#include "CLHEP/Units/SystemOfUnits.h" -#include "CLHEP/Units/PhysicalConstants.h" - - -namespace ddml { - -/** Event action for ddml. -* -* @author P. McKeown, CERN -* @date Feb 2025 -* -*/ - -class DDMLEventAction: public dd4hep::sim::Geant4EventAction{ -public: - /// Standard constructor with initializing arguments - DDMLEventAction(dd4hep::sim::Geant4Context* c, const std::string& n); - /// Default destructor - virtual ~DDMLEventAction(); - /// begin-of-event callback - inline virtual void begin(const G4Event*) override; - /// End-of-event callback - virtual void end(const G4Event*) override; - /// begin-of-run callback - void beginRun(const G4Run*); - /// End-of-run callback - void endRun(const G4Run*); - - //// Get and Set methods for Calo Face info - inline std::vector& GetCaloMC_PDG() {return m_CaloMCPDG;} - inline std::vector& GetCaloMC_E() {return m_CaloMCE;} - inline std::vector& GetCaloMC_PosX() {return m_CaloMCPosX;} - inline std::vector& GetCaloMC_PosY() {return m_CaloMCPosY;} - inline std::vector& GetCaloMC_PosZ() {return m_CaloMCPosZ;} - inline std::vector& GetCaloMC_DirX() {return m_CaloMCDirX;} - inline std::vector& GetCaloMC_DirY() {return m_CaloMCDirY;} - inline std::vector& GetCaloMC_DirZ() {return m_CaloMCDirZ;} - - // Set methods to push back vector - inline void SetElCaloMC_PDG(G4int aValue) {m_CaloMCPDG.push_back(aValue);} - inline void SetElCaloMC_E(G4double aValue) {m_CaloMCE.push_back(aValue);} - inline void SetElCaloMC_PosX(G4double aValue) {m_CaloMCPosX.push_back(aValue);} - inline void SetElCaloMC_PosY(G4double aValue) {m_CaloMCPosY.push_back(aValue);} - inline void SetElCaloMC_PosZ(G4double aValue) {m_CaloMCPosZ.push_back(aValue);} - inline void SetElCaloMC_DirX(G4double aValue) {m_CaloMCDirX.push_back(aValue);} - inline void SetElCaloMC_DirY(G4double aValue) {m_CaloMCDirY.push_back(aValue);} - inline void SetElCaloMC_DirZ(G4double aValue) {m_CaloMCDirZ.push_back(aValue);} - -private: - // Fast Sim Calo entrace particle properties to store in ntuple - std::vector m_CaloMCPDG; - std::vector m_CaloMCE; - std::vector m_CaloMCPosX; - std::vector m_CaloMCPosY; - std::vector m_CaloMCPosZ; - std::vector m_CaloMCDirX; - std::vector m_CaloMCDirY; - std::vector m_CaloMCDirZ; -}; - -} //namespace - diff --git a/include/DDML/DDMLRunAction.h b/include/DDML/DDMLRunAction.h deleted file mode 100644 index 49c5dc6..0000000 --- a/include/DDML/DDMLRunAction.h +++ /dev/null @@ -1,39 +0,0 @@ -#include // for GeV -#include // for G4String -#include // for G4ThreeVector -#include // for G4int -//#include "G4Timer.hh" // for G4Timer -class G4ParticleDefinition; -#include "DDG4/Geant4Handle.h" -#include "DDG4/Geant4Kernel.h" -#include "DDG4/Geant4RunAction.h" - - - -namespace ddml{ -/* Create analysis files in standard G4 manner -* -* @author P. McKeown -* @date Feb 2025 -* -*/ - -class DDMLRunAction: public dd4hep::sim::Geant4RunAction { - public: - DDMLRunAction() = delete; - /// Standard constructor with initializing arguments - DDMLRunAction(dd4hep::sim::Geant4Context* c, const std::string& n) ; - /// Default destructor - virtual ~DDMLRunAction() ; - /// begin-of-run callback - void begin(const G4Run*) override; - /// End-of-run callback - void end(const G4Run*) override; - /// begin-of-event callback - void beginEvent(const G4Event*) ; - /// End-of-event callback - void endEvent(const G4Event*) ; - -}; - -} // namespace \ No newline at end of file diff --git a/include/DDML/FastMLShower.h b/include/DDML/FastMLShower.h index 0615eb2..e48a35a 100644 --- a/include/DDML/FastMLShower.h +++ b/include/DDML/FastMLShower.h @@ -14,10 +14,6 @@ #define DDML_INSTRUMENT_MODEL_SHOWER 0 #endif -#ifndef DDML_RECORD_CALO_IMPACT - #define DDML_RECORD_CALO_IMPACT 0 -#endif - #if DDML_INSTRUMENT_MODEL_SHOWER #include "podio/Frame.h" #include "podio/ROOTFrameWriter.h" @@ -39,12 +35,6 @@ inline auto run_void_member_timed(Obj& obj, MemberFunc func, Args&&... args) { } #endif -#if DDML_RECORD_CALO_IMPACT - //#include "G4EventManager.hh" - //#include "DDML/DDMLEventAction.h" - #include "G4AnalysisManager.hh" -#endif - namespace ddml { /** The templated base class for running fast shower simulation with ML. * The actual implementation is provided by the templated class @@ -154,41 +144,6 @@ class FastMLShower : public dd4hep::sim::Geant4FastSimShowerModel { podio::UserDataCollection nHits; #endif -#if DDML_RECORD_CALO_IMPACT - // Create analysis manager - G4AnalysisManager* analysisManager = G4AnalysisManager::Instance(); - - // Store information about particle impact on calorimter face from track - G4int PDG = track.GetPrimaryTrack()->GetParticleDefinition()->GetPDGEncoding(); - G4ThreeVector position = track.GetPrimaryTrack()->GetPosition(); - G4ThreeVector direction = track.GetPrimaryTrack()->GetMomentumDirection(); - - // Fill analysis manager - analysisManager->FillNtupleIColumn(1, 0, PDG); - analysisManager->FillNtupleDColumn(1, 1, energy); - analysisManager->FillNtupleDColumn(1, 2, position.x()); - analysisManager->FillNtupleDColumn(1, 3, position.y()); - analysisManager->FillNtupleDColumn(1, 4, position.z()); - analysisManager->FillNtupleDColumn(1, 5, direction.x()); - analysisManager->FillNtupleDColumn(1, 6, direction.y()); - analysisManager->FillNtupleDColumn(1, 7, direction.z()); - - analysisManager->AddNtupleRow(1); - - /* - DDMLEventAction* mEventAction = dynamic_cast(G4EventManager::GetEventManager()->GetUserEventAction()); - mEventAction->SetElCaloMC_PDG(PDG); - mEventAction->SetElCaloMC_E(energy); - mEventAction->SetElCaloMC_PosX(position.x()); - mEventAction->SetElCaloMC_PosY(position.y()); - mEventAction->SetElCaloMC_PosZ(position.z()); - mEventAction->SetElCaloMC_DirX(direction.x()); - mEventAction->SetElCaloMC_DirY(direction.y()); - mEventAction->SetElCaloMC_DirZ(direction.z()); - */ - -#endif - for (auto& invec : m_input) { invec.clear(); } diff --git a/include/DDML/LoadHdf5.h b/include/DDML/LoadHdf5.h index 7fdfd44..74bdf02 100644 --- a/include/DDML/LoadHdf5.h +++ b/include/DDML/LoadHdf5.h @@ -49,8 +49,7 @@ class LoadHdf5 : public InferenceInterface { std::vector m_library{}; // shower library dimensions - std::vector m_dimsOut{}; // This is a hot fix for older HDF5 versions! - //std::vector m_dimsOut{}; + std::vector m_dimsOut{}; // properties for plugin std::string m_filePath = {}; diff --git a/scripts/ddsim_steer.py b/scripts/ddsim_steer.py index 6d24a50..3b7b3b7 100644 --- a/scripts/ddsim_steer.py +++ b/scripts/ddsim_steer.py @@ -547,7 +547,7 @@ def LoadHdf5(kernel): if hadrons == True: ml_model_had = "LoadHDF5PionCloudsPCHadronModelPolyhedraBarrel/BarrelModelTorch" - ml_had_file = "../models/PionClouds_50GeV_sp.h5" + ml_had_file = "../models/PionClouds_50GeV_sp_scaled.h5" ml_correct_angles = False from g4units import GeV, MeV # DO NOT REMOVE OR MOVE!!!!! (EXCLAMATION MARK) @@ -658,4 +658,4 @@ def LoadHdf5(kernel): # SIM.physics.setupUserPhysics( aiDance) SIM.physics.setupUserPhysics(aiDanceTorch) -# SIM.physics.setupUserPhysics(LoadHdf5) +#SIM.physics.setupUserPhysics(LoadHdf5) diff --git a/scripts/ddsim_steer_Record_Calo_entry.py b/scripts/ddsim_steer_Record_Calo_entry.py deleted file mode 100644 index 1f21c95..0000000 --- a/scripts/ddsim_steer_Record_Calo_entry.py +++ /dev/null @@ -1,657 +0,0 @@ -###################################################################### -# -# standard steering file for ILD simulation -# -# -# -###################################################################### -from DDSim.DD4hepSimulation import DD4hepSimulation -import DDG4 -from g4units import m, mm, GeV, MeV, rad -import os - -SIM = DD4hepSimulation() - -## The compact XML file -SIM.compactFile = "" -## Lorentz boost for the crossing angle, in radian! -SIM.crossingAngleBoost = 7.0e-3 * rad -SIM.enableDetailedShowerMode = True -SIM.enableG4GPS = True -SIM.enableG4Gun = False -SIM.enableGun = False -## InputFiles for simulation .stdhep, .slcio, .HEPEvt, .hepevt, .hepmc, .pairs files are supported -SIM.inputFiles = [] -## Macro file to execute for runType 'run' or 'vis' -SIM.macroFile = "./test_onnx.mac" -## number of events to simulate, used in batch mode -SIM.numberOfEvents = 100 -## Outputfile from the simulation,only lcio output is supported -# SIM.outputFile = "dummyOutput_edm4hep.root" ##"dummyOutput.slcio" -SIM.outputFile = "dummyOutput.slcio" - -## Physics list to use in simulation -SIM.physicsList = None -## Verbosity use integers from 1(most) to 7(least) verbose -## or strings: VERBOSE, DEBUG, INFO, WARNING, ERROR, FATAL, ALWAYS -SIM.printLevel = "INFO" -## The type of action to do in this invocation -## batch: just simulate some events, needs numberOfEvents, and input file or gun -## vis: enable visualisation, run the macroFile if it is set -## run: run the macroFile and exit -## shell: enable interactive session -SIM.runType = "run" # "batch" -## Skip first N events when reading a file -SIM.skipNEvents = 0 -## Steering file to change default behaviour -SIM.steeringFile = None -## FourVector of translation for the Smearing of the Vertex position: x y z t -SIM.vertexOffset = [0.0, 0.0, 0.0, 0.0] -## FourVector of the Sigma for the Smearing of the Vertex position: x y z t -SIM.vertexSigma = [0.0, 0.0, 0.0, 0.0] - - -################################################################################ -## Action holding sensitive detector actions -## The default tracker and calorimeter actions can be set with -## -## >>> SIM = DD4hepSimulation() -## >>> SIM.action.tracker = ('Geant4TrackerWeightedAction', {'HitPositionCombination': 2, 'CollectSingleDeposits': False}) -## >>> SIM.action.calo = "Geant4CalorimeterAction" -## -## for specific subdetectors specific sensitive detectors can be set based on pattern matching -## -## >>> SIM = DD4hepSimulation() -## >>> SIM.action.mapActions['tpc'] = "TPCSDAction" -## -## and additional parameters for the sensitive detectors can be set when the map is given a tuple -## -## >>> SIM = DD4hepSimulation() -## >>> SIM.action.mapActions['ecal'] =( "CaloPreShowerSDAction", {"FirstLayerNumber": 1} ) -## -## -################################################################################ - -## set the default calorimeter action -SIM.action.calo = "Geant4ScintillatorCalorimeterAction" - -## create a map of patterns and actions to be applied to sensitive detectors -## example: SIM.action.mapActions['tpc'] = "TPCSDAction" -SIM.action.mapActions = {} - -SIM.action.mapActions["tpc"] = "TPCSDAction" - -## set the default tracker action -SIM.action.tracker = ( - "Geant4TrackerWeightedAction", - {"HitPositionCombination": 2, "CollectSingleDeposits": False}, -) - -### Configure Run actions -kernel = DDG4.Kernel() -run1 = DDG4.RunAction(kernel, 'DDMLRunAction/runaction') -kernel.registerGlobalAction(run1) -kernel.runAction().add(run1) -event1 = DDG4.EventAction(kernel, 'DDMLEventAction/eventaction') -kernel.registerGlobalAction(event1) -kernel.eventAction().add(event1) - -################################################################################ -## Configuration for the magnetic field (stepper) -################################################################################ -## --- used in v01-19-05 : -SIM.field.delta_chord = 1e-05 -SIM.field.delta_intersection = 1e-05 -SIM.field.delta_one_step = 0.5e-03 * mm -SIM.field.eps_max = 1e-04 -SIM.field.eps_min = 1e-05 -SIM.field.equation = "Mag_UsualEqRhs" -SIM.field.largest_step = 10.0 * m -SIM.field.min_chord_step = 1.0e-2 * mm -SIM.field.stepper = "HelixSimpleRunge" - -## --- default values in ddsim -##SIM.field.delta_chord = 0.25 -##SIM.field.delta_intersection = 0.001 -##SIM.field.delta_one_step = 0.01 -##SIM.field.eps_max = 0.001 -##SIM.field.eps_min = 5e-05 -##SIM.field.equation = "Mag_UsualEqRhs" -##SIM.field.largest_step = 10000.0 -##SIM.field.min_chord_step = 0.01 -##SIM.field.stepper = "G4ClassicalRK4" - -################################################################################ -## Configuration for sensitive detector filters -## -## Set the default filter for tracker or caliromter -## >>> SIM.filter.tracker = "edep1kev" -## >>> SIM.filter.calo = "" -## -## Assign a filter to a sensitive detector via pattern matching -## >>> SIM.filter.mapDetFilter['FTD'] = "edep1kev" -## -## Or more than one filter: -## >>> SIM.filter.mapDetFilter['FTD'] = ["edep1kev", "geantino"] -## -## Don't use the default filter or anything else: -## >>> SIM.filter.mapDetFilter['TPC'] = None ## or "" or [] -## -## Create a custom filter. The dictionary is used to instantiate the filter later on -## >>> SIM.filter.filters['edep3kev'] = dict(name="EnergyDepositMinimumCut/3keV", parameter={"Cut": 3.0*keV} ) -## -## -################################################################################ - -## default filter for calorimeter sensitive detectors; this is applied if no other filter is used for a calorimeter -SIM.filter.calo = "edep0" - -## list of filter objects: map between name and parameter dictionary -SIM.filter.filters = { - "edep0": {"parameter": {"Cut": 0.0}, "name": "EnergyDepositMinimumCut/Cut0"}, - "geantino": {"parameter": {}, "name": "GeantinoRejectFilter/GeantinoRejector"}, - "edep1kev": {"parameter": {"Cut": 0.001}, "name": "EnergyDepositMinimumCut"}, -} - -## a map between patterns and filter objects, using patterns to attach filters to sensitive detector -SIM.filter.mapDetFilter = {} - -SIM.filter.mapDetFilter["TPC"] = None - -## default filter for tracking sensitive detectors; this is applied if no other filter is used for a tracker -SIM.filter.tracker = "edep1kev" - - -################################################################################ -## Configuration for the GuineaPig InputFiles -################################################################################ - -## Set the number of pair particles to simulate per event. -## Only used if inputFile ends with ".pairs" -## If "-1" all particles will be simulated in a single event -## -SIM.guineapig.particlesPerEvent = "-1" - - -################################################################################ -## Configuration for the DDG4 ParticleGun -################################################################################ - -## direction of the particle gun, 3 vector -SIM.gun.direction = (0, 0, 1) - -## choose the distribution of the random direction for theta -## -## Options for random distributions: -## -## 'uniform' is the default distribution, flat in theta -## 'cos(theta)' is flat in cos(theta) -## 'eta', or 'pseudorapidity' is flat in pseudorapity -## 'ffbar' is distributed according to 1+cos^2(theta) -## -## Setting a distribution will set isotrop = True -## -SIM.gun.distribution = None -SIM.gun.energy = 10000.0 - -## isotropic distribution for the particle gun -## -## use the options phiMin, phiMax, thetaMin, and thetaMax to limit the range of randomly distributed directions -## if one of these options is not None the random distribution will be set to True and cannot be turned off! -## -SIM.gun.isotrop = False -SIM.gun.multiplicity = 1 -SIM.gun.particle = "mu-" -SIM.gun.phiMax = None - -## Minimal azimuthal angle for random distribution -SIM.gun.phiMin = None - -## position of the particle gun, 3 vector -SIM.gun.position = (0.0, 0.0, 0.0) -SIM.gun.thetaMax = None -SIM.gun.thetaMin = None - - -################################################################################ -## Configuration for the output levels of DDG4 components -################################################################################ - -## Output level for input sources -SIM.output.inputStage = 3 - -## Output level for Geant4 kernel -SIM.output.kernel = 3 - -## Output level for ParticleHandler -SIM.output.part = 3 - -## Output level for Random Number Generator setup -SIM.output.random = 6 - - -################################################################################ -## Configuration for the Particle Handler/ MCTruth treatment -################################################################################ - -## Enable lots of printout on simulated hits and MC-truth information -SIM.part.enableDetailedHitsAndParticleInfo = False - -## Keep all created particles -SIM.part.keepAllParticles = False - -## Minimal distance between particle vertex and endpoint of parent after -## which the vertexIsNotEndpointOfParent flag is set -## -SIM.part.minDistToParentVertex = 2.2e-14 - -## MinimalKineticEnergy to store particles created in the tracking region -SIM.part.minimalKineticEnergy = 1 * MeV - -## Printout at End of Tracking -SIM.part.printEndTracking = False - -## Printout at Start of Tracking -SIM.part.printStartTracking = False - -## List of processes to save, on command line give as whitespace separated string in quotation marks -SIM.part.saveProcesses = ["Decay"] - - -################################################################################ -## Configuration for the PhysicsList -################################################################################ -# this needs to be set to False if any standard physics list is used: -SIM.physics.decays = False -SIM.physics.list = "QGSP_BERT" # "FTFP_BERT" - -## location of particle.tbl file containing extra particles and their lifetime information -## -SIM.physics.pdgfile = os.path.join( - os.environ.get("DD4HEP"), "DDG4/examples/particle.tbl" -) - -## The global geant4 rangecut for secondary production -## -## Default is 0.7 mm as is the case in geant4 10 -## -## To disable this plugin and be absolutely sure to use the Geant4 default range cut use "None" -## -## Set printlevel to DEBUG to see a printout of all range cuts, -## but this only works if range cut is not "None" -## -SIM.physics.rangecut = 0.1 * mm - - -################################################################################ -## Properties for the random number generator -################################################################################ - -## If True, calculate random seed for each event based on eventID and runID -## allows reproducibility even when SkippingEvents -SIM.random.enableEventSeed = True #False -SIM.random.file = None -SIM.random.luxury = 1 -SIM.random.replace_gRandom = True -SIM.random.seed = 42 #None -SIM.random.type = None - -# --------------------------------------------- -# -# Configure ML inference -# -# --------------------------------------------- - - -def aiDance(kernel): - ild = True - par04 = True # False - old_DD4hep = False ## use for DD4hep versions/commits before ~ Apr 21st 2023 - - if ild == True: - ml_barrel_name = "EcalBarrel" - ml_barrel_symmetry = 8 - ml_endcap_name = "EcalEndcap" - else: - ml_barrel_name = "ECalBarrel" - ml_barrel_symmetry = 12 - ml_endcap_name = "ECalEndcap" - - if par04 == True: - ml_file = "../models/Generator.onnx" - ml_model = "Par04ExampleVAEPolyhedraBarrelONNXModel/ShowerModel" - ml_model1 = "Par04ExampleVAEEndcapONNXModel/ShowerModel" - else: - ml_file = "../models/francisca_gan.onnx" - ml_model = "RegularGridGANPolyhedraBarrelONNXModel/ShowerModel" - ml_model1 = "RegularGridGANEndcapONNXModel/ShowerModel" - - ml_correct_angles = True - - from g4units import GeV, MeV # DO NOT REMOVE OR MOVE!!!!! (EXCLAMATION MARK) - from DDG4 import DetectorConstruction, Geant4, PhysicsList - - geant4 = Geant4(kernel) - seq = geant4.detectorConstruction() - - if old_DD4hep: # this is now done in DD4hepSimulations.py, i.e. in ddsim - seq, act = geant4.addDetectorConstruction( - "Geant4DetectorGeometryConstruction/ConstructGeo" - ) - act.DebugMaterials = True - act.DebugElements = False - act.DebugVolumes = True - act.DebugShapes = True - # Apply sensitive detectors - sensitives = DetectorConstruction( - kernel, str("Geant4DetectorSensitivesConstruction/ConstructSD") - ) - sensitives.enableUI() - seq.adopt(sensitives) - - # ----------------- - model = DetectorConstruction(kernel, str(ml_model)) - - ## # Mandatory model parameters - model.RegionName = "EcalBarrelRegion" - model.Detector = ml_barrel_name - model.Symmetry = ml_barrel_symmetry - model.Enable = True - model.CorrectForAngles = ml_correct_angles - # Energy boundaries are optional: Units are GeV - model.ApplicableParticles = {"e+", "e-", "gamma"} - model.Etrigger = {"e+": 5.0 * GeV, "e-": 5.0 * GeV, "gamma": 5.0 * GeV} - model.ModelPath = ml_file - model.OptimizeFlag = 1 - - model.enableUI() - seq.adopt(model) - # ------------------- - model1 = DetectorConstruction(kernel, str(ml_model1)) - - ## # Mandatory model parameters - model1.RegionName = "EcalEndcapRegion" - model1.Detector = ml_endcap_name - model1.Enable = True - model1.CorrectForAngles = ml_correct_angles - # Energy boundaries are optional: Units are GeV - model1.ApplicableParticles = {"e+", "e-", "gamma"} - model1.Etrigger = {"e+": 5.0 * GeV, "e-": 5.0 * GeV, "gamma": 5.0 * GeV} - model1.ModelPath = ml_file - model.OptimizeFlag = 1 - - model1.enableUI() - seq.adopt(model1) - # ------------------- - - # Now build the physics list: - phys = kernel.physicsList() - ph = PhysicsList(kernel, str("Geant4FastPhysics/FastPhysicsList")) - ph.EnabledParticles = ["e+", "e-", "gamma"] - ph.BeVerbose = True - ph.enableUI() - phys.adopt(ph) - phys.dump() - - -def aiDanceTorch(kernel): - ild = True - BIBAE = True - Two_Angle = True #True - old_DD4hep = False ## use for DD4hep versions/commits before ~ Apr 21st 2023 - - if ild == True: - ml_barrel_name = "EcalBarrel" - ml_barrel_symmetry = 8 - ml_endcap_name = "EcalEndcap" - else: - ml_barrel_name = "ECalBarrel" - ml_barrel_symmetry = 12 - ml_endcap_name = "ECalEndcap" - - if BIBAE == True and Two_Angle == False: - ml_file = "../models/BIBAE_Full_PP_cut.pt" - ml_model = "RegularGridBIBAEPolyhedraBarrelTorchModel/BarrelModelTorch" - ml_model_1 = "RegularGridBIBAEEndcapTorchModel/EndcapModelTorch" - ml_correct_angles = False - elif BIBAE == True and Two_Angle == True: - ml_file = "../models/BIBAE_Two_Angle_Full_PP_cut.pt" - ml_model = ( - "RegularGridTwoAngleBIBAEModelPolyhedraBarrelTorchModel/BarrelModelTorch" - ) - ml_model_1 = "RegularGridTwoAngleBIBAEModelEndcapTorchModel/EndcapModelTorch" - ml_correct_angles = False - else: - ml_file = "../models/francisca_gan_jit.pt" - ml_model = "RegularGridGANPolyhedraBarrelTorchModel/BarrelModelTorch" - ml_model_1 = "RegularGridGANEndcapTorchModel/EndcapModelTorch" - ml_correct_angles = True - - from g4units import GeV, MeV # DO NOT REMOVE OR MOVE!!!!! (EXCLAMATION MARK) - from DDG4 import DetectorConstruction, Geant4, PhysicsList - - geant4 = Geant4(kernel) - - seq = geant4.detectorConstruction() - - if old_DD4hep: # this is now done in DD4hepSimulations.py, i.e. in ddsim - seq, act = geant4.addDetectorConstruction( - "Geant4DetectorGeometryConstruction/ConstructGeo" - ) - act.DebugMaterials = True - act.DebugElements = False - act.DebugVolumes = True - act.DebugShapes = True - - # Apply sensitive detectors - sensitives = DetectorConstruction( - kernel, str("Geant4DetectorSensitivesConstruction/ConstructSD") - ) - sensitives.enableUI() - seq.adopt(sensitives) - - # ----------------- - model = DetectorConstruction(kernel, str(ml_model)) - - ## # Mandatory model parameters - model.RegionName = "EcalBarrelRegion" - model.Detector = ml_barrel_name - model.Symmetry = ml_barrel_symmetry - model.Enable = True - model.CorrectForAngles = ml_correct_angles - # Energy boundaries are optional: Units are GeV - model.ApplicableParticles = {"e+", "e-", "gamma"} - model.Etrigger = { - "e+": 10.0 * GeV, - "e-": 10.0 * GeV, - "gamma": 10.0 * GeV, - } # trigger on lower training threshold - model.ModelPath = ml_file - model.OptimizeFlag = 1 - model.IntraOpNumThreads = 1 - - model.enableUI() - seq.adopt(model) - # ------------------- - model1 = DetectorConstruction(kernel, str(ml_model_1)) - - ## # Mandatory model parameters - model1.RegionName = "EcalEndcapRegion" - model1.Detector = ml_endcap_name - model1.Enable = True - model1.CorrectForAngles = ml_correct_angles - # Energy boundaries are optional: Units are GeV - model1.ApplicableParticles = {"e+", "e-", "gamma"} - model1.Etrigger = { - "e+": 10.0 * GeV, - "e-": 10.0 * GeV, - "gamma": 10.0 * GeV, - } # trigger on lower training threshold - model1.ModelPath = ml_file - model1.OptimizeFlag = 1 - model1.IntraOpNumThreads = 1 - - model1.enableUI() - seq.adopt(model1) - # ------------------- - - # Now build the physics list: - phys = kernel.physicsList() - ph = PhysicsList(kernel, str("Geant4FastPhysics/FastPhysicsList")) - ph.EnabledParticles = ["e+", "e-", "gamma"] - ph.BeVerbose = True - ph.enableUI() - phys.adopt(ph) - phys.dump() - - -def LoadHdf5(kernel): - ild = True - BIBAE = True - Two_Angle = True - old_DD4hep = False ## use for DD4hep versions/commits before ~ Apr 21st 2023 - hadrons = True - - if ild == True: - ml_barrel_name = "EcalBarrel" - ml_barrel_symmetry = 8 - ml_endcap_name = "EcalEndcap" - - ## For hadron shower fast simulation - ml_had_barrel_name = "HcalBarrel" - ml_had_barrel_symmetry = 8 - ml_had_endcap_name = "HcalEndcap" - - else: - ml_barrel_name = "ECalBarrel" - ml_barrel_symmetry = 12 - ml_endcap_name = "ECalEndcap" - - ## For hadron shower fast simulation is needed - ml_had_barrel_name = "HCalBarrel" - ml_had_barrel_symmetry = 12 - ml_had_endcap_name = "HCalEndcap" - - if BIBAE == True and Two_Angle == True: - ml_file = "../models/photons-E5050A-theta9090A-phi9090-p1.hdf5" - ml_model = ( - "LoadHDF5RegularGridTwoAngleBIBAEModelPolyhedraBarrel/BarrelModelTorch" - ) - ml_model_1 = "LoadHDF5RegularGridTwoAngleBIBAEModelEndcap/EndcapModelTorch" - ml_correct_angles = False - - if hadrons == True: - ml_model_had = "LoadHDF5PionCloudsPCHadronModelPolyhedraBarrel/BarrelModelTorch" - ml_had_file = "../models/PionClouds_50GeV_sp_scaled.h5" #"../models/gen_showers_for_reco_50GeV_2000.hdf5" - #"../models/gen_showers_50GeV_2000_Martina.hdf5" #"../models/PionClouds_50GeV_sp_scaled.h5" #"../models/PionClouds_50GeV_sp.h5" # - ml_correct_angles = False - - from g4units import GeV, MeV # DO NOT REMOVE OR MOVE!!!!! (EXCLAMATION MARK) - from DDG4 import DetectorConstruction, Geant4, PhysicsList - - geant4 = Geant4(kernel) - - seq = geant4.detectorConstruction() - - if old_DD4hep: # this is now done in DD4hepSimulations.py, i.e. in ddsim - seq, act = geant4.addDetectorConstruction( - "Geant4DetectorGeometryConstruction/ConstructGeo" - ) - act.DebugMaterials = True - act.DebugElements = False - act.DebugVolumes = True - act.DebugShapes = True - - # Apply sensitive detectors - sensitives = DetectorConstruction( - kernel, str("Geant4DetectorSensitivesConstruction/ConstructSD") - ) - sensitives.enableUI() - seq.adopt(sensitives) - - # ----------------- - ''' - ## EM in Barrel - model = DetectorConstruction(kernel, str(ml_model)) - - ## # Mandatory model parameters - model.RegionName = "EcalBarrelRegion" - model.Detector = ml_barrel_name - model.Symmetry = ml_barrel_symmetry - model.Enable = True - model.CorrectForAngles = ml_correct_angles - # Energy boundaries are optional: Units are GeV - model.ApplicableParticles = {"e+", "e-", "gamma"} - model.Etrigger = { - "e+": 10.0 * GeV, - "e-": 10.0 * GeV, - "gamma": 10.0 * GeV, - } # trigger on lower training threshold - model.FilePath = ml_file - # model.OptimizeFlag = 1 - # model.IntraOpNumThreads = 1 - - model.enableUI() - seq.adopt(model) - ''' - # ------------------- - ## EM in Endcap - model1 = DetectorConstruction(kernel, str(ml_model_1)) - - ## # Mandatory model parameters - model1.RegionName = "EcalEndcapRegion" - model1.Detector = ml_endcap_name - model1.Enable = True - model1.CorrectForAngles = ml_correct_angles - # Energy boundaries are optional: Units are GeV - model1.ApplicableParticles = {"e+", "e-", "gamma"} - model1.Etrigger = { - "e+": 10.0 * GeV, - "e-": 10.0 * GeV, - "gamma": 10.0 * GeV, - } # trigger on lower training threshold - model1.FilePath = ml_file - # model1.OptimizeFlag = 1 - # model1.IntraOpNumThreads = 1 - - model1.enableUI() - seq.adopt(model1) - - # ------------------- - ## Hadrons in Barrel - modelHad1 = DetectorConstruction(kernel, str(ml_model_had)) - - ## # Mandatory model parameters - modelHad1.isHadShower = True - modelHad1.RegionName = "EcalBarrelRegion" #or "HcalBarrelRegion" ## hadron model triggers in ecal - modelHad1.Detector = ml_barrel_name - modelHad1.HadDetector = ml_had_barrel_name - modelHad1.Symmetry = ml_barrel_symmetry - modelHad1.HadSymmetry = ml_had_barrel_symmetry - modelHad1.Enable = True - modelHad1.CorrectForAngles = ml_correct_angles - # Energy boundaries are optional: Units are GeV - modelHad1.ApplicableParticles = {"pi+"} - modelHad1.Etrigger = {"pi+": 30.0 * GeV} #{"pi+": 10.0 * GeV} # trigger on lower training threshold - modelHad1.FilePath = ml_had_file - # model.OptimizeFlag = 1 - # model.IntraOpNumThreads = 1 - - modelHad1.enableUI() - seq.adopt(modelHad1) - - # ------------------- - - # Now build the physics list: - phys = kernel.physicsList() - ph = PhysicsList(kernel, str("Geant4FastPhysics/FastPhysicsList")) - ph.EnabledParticles = ["e+", "e-", "gamma", "pi+"] - ph.BeVerbose = True - ph.enableUI() - phys.adopt(ph) - phys.dump() - - -#SIM.physics.setupUserPhysics( aiDance) -#SIM.physics.setupUserPhysics(aiDanceTorch) -SIM.physics.setupUserPhysics(LoadHdf5) diff --git a/scripts/test_onnx.mac b/scripts/test_onnx.mac index a748499..c1f4695 100644 --- a/scripts/test_onnx.mac +++ b/scripts/test_onnx.mac @@ -75,5 +75,5 @@ #/gps/direction 0.1 -0.8 .1 -/run/beamOn 100 #2000 #100 +/run/beamOn 2000 #100 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0a0114c..2882c79 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -35,18 +35,6 @@ if(INSTRUMENT_MODEL) ) endif() -if(RECORD_CALO_IMPACT) - target_sources(${PROJECT_NAME} PRIVATE - DDMLRunAction.cc - DDMLEventAction.cc - ) - target_compile_definitions(${PROJECT_NAME} PUBLIC - DDML_RECORD_CALO_IMPACT=1 - ) -endif() - - - if(OnnxRuntime_FOUND) target_sources(${PROJECT_NAME} PRIVATE ONNXInference.cc @@ -123,10 +111,6 @@ if(HDF5_FOUND) list(APPEND headers ${PROJECT_SOURCE_DIR}/include/DDML/LoadHdf5.h) endif() -if(RECORD_CALO_IMPACT) - list(APPEND headers ${PROJECT_SOURCE_DIR}/include/DDML/DDMLRunAction.h ${PROJECT_SOURCE_DIR}/include/DDML/DDMLEventAction.h) -endif() - #install(FILES # ${headers} # DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) diff --git a/src/DDMLEventAction.cc b/src/DDMLEventAction.cc deleted file mode 100644 index 7decd72..0000000 --- a/src/DDMLEventAction.cc +++ /dev/null @@ -1,58 +0,0 @@ -#include "DDML/DDMLEventAction.h" -#include "G4AnalysisManager.hh" -#include "DD4hep/InstanceCount.h" -#include "G4Event.hh" -#include "G4EventManager.hh" -#include "G4ThreeVector.hh" -#include "G4PrimaryVertex.hh" -#include "G4PrimaryParticle.hh" -#include "DDG4/Geant4Data.h" - -#define DEBUGPRINT 0 - -namespace ddml { - -DDMLEventAction::DDMLEventAction(dd4hep::sim::Geant4Context* c, const std::string& n): -Geant4EventAction(c,n) - { - dd4hep::InstanceCount::increment(this); - } - -/// Default destructor -DDMLEventAction::~DDMLEventAction() { - dd4hep::InstanceCount::decrement(this); - } - -void DDMLEventAction::begin(const G4Event*){} - -void DDMLEventAction::end(const G4Event*) { - // Get analysis manager - auto analysisManager = G4AnalysisManager::Instance(); - - // Retrieve information from primary vertex and primary particle - auto primaryVertex = - G4EventManager::GetEventManager()->GetConstCurrentEvent()->GetPrimaryVertex(); - G4ThreeVector primaryVertexPos = primaryVertex->GetPosition(); - auto primaryParticle = primaryVertex->GetPrimary(0); - G4double primaryEnergy = primaryParticle->GetTotalEnergy(); - G4ThreeVector primaryDirection = primaryParticle->GetMomentumDirection(); - G4int primaryPDG = primaryParticle->GetPDGcode(); - - // Fill analysis manager - analysisManager->FillNtupleIColumn(0, 0, primaryPDG); - analysisManager->FillNtupleDColumn(0, 1, primaryEnergy); - analysisManager->FillNtupleDColumn(0, 2, primaryVertexPos.x()); - analysisManager->FillNtupleDColumn(0, 3, primaryVertexPos.y()); - analysisManager->FillNtupleDColumn(0, 4, primaryVertexPos.z()); - analysisManager->FillNtupleDColumn(0, 5, primaryDirection.x()); - analysisManager->FillNtupleDColumn(0, 6, primaryDirection.y()); - analysisManager->FillNtupleDColumn(0, 7, primaryDirection.z()); - - analysisManager->AddNtupleRow(0); - -} - -} //namespace - -#include "DDG4/Factories.h" -DECLARE_GEANT4ACTION_NS(ddml, DDMLEventAction) diff --git a/src/DDMLRunAction.cc b/src/DDMLRunAction.cc deleted file mode 100644 index 60c92eb..0000000 --- a/src/DDMLRunAction.cc +++ /dev/null @@ -1,80 +0,0 @@ -#include "DDML/DDMLRunAction.h" -#include "DDML/DDMLEventAction.h" -#include "G4AnalysisManager.hh" -#include "G4EventManager.hh" -#include "DD4hep/InstanceCount.h" -#include "G4Run.hh" - -#define DEBUGPRINT 0 - -namespace ddml { - -/// Standard constructor with initializing arguments -DDMLRunAction::DDMLRunAction(dd4hep::sim::Geant4Context* c, const std::string& n): - Geant4RunAction(c, n) { - // Create analysis manager - G4AnalysisManager* analysisManager = G4AnalysisManager::Instance(); - analysisManager->SetDefaultFileType("root"); - - // Default filename, can be overriden with /analysis/setFileName - analysisManager->SetFileName("Output"); - dd4hep::InstanceCount::increment(this); -} - -/// Default destructor -DDMLRunAction::~DDMLRunAction() { - dd4hep::InstanceCount::decrement(this); -} - -/// begin-of-run callback -void DDMLRunAction::begin(const G4Run*) { - // Get analysis manager -G4AnalysisManager* analysisManager = G4AnalysisManager::Instance(); - -// Create directories -analysisManager->SetVerboseLevel(0); - -// Create ntuples -analysisManager->CreateNtuple("global", "Event data"); -analysisManager->CreateNtupleIColumn("MC_PDG"); -analysisManager->CreateNtupleDColumn("MC_Energy"); -analysisManager->CreateNtupleDColumn("MC_PosX"); -analysisManager->CreateNtupleDColumn("MC_PosY"); -analysisManager->CreateNtupleDColumn("MC_PosZ"); -analysisManager->CreateNtupleDColumn("MC_DirX"); -analysisManager->CreateNtupleDColumn("MC_DirY"); -analysisManager->CreateNtupleDColumn("MC_DirZ"); -analysisManager->FinishNtuple(); - -analysisManager->CreateNtuple("Fast_Sim_Info", "MC info at calo face"); -analysisManager->CreateNtupleIColumn("Calo_MC_PDG"); -analysisManager->CreateNtupleDColumn("Calo_MC_Energy"); -analysisManager->CreateNtupleDColumn("Calo_MC_PosX"); -analysisManager->CreateNtupleDColumn("Calo_MC_PosY"); -analysisManager->CreateNtupleDColumn("Calo_MC_PosZ"); -analysisManager->CreateNtupleDColumn("Calo_MC_DirX"); -analysisManager->CreateNtupleDColumn("Calo_MC_DirY"); -analysisManager->CreateNtupleDColumn("Calo_MC_DirZ"); -analysisManager->FinishNtuple(); - - -analysisManager->CreateNtuple("run", "Run data"); -analysisManager->CreateNtupleDColumn("N"); -analysisManager->FinishNtuple(); - -analysisManager->OpenFile(); -} - -/// End-of-run callback -void DDMLRunAction::end(const G4Run* aRun){ - auto analysisManager = G4AnalysisManager::Instance(); - analysisManager->FillNtupleDColumn(2, 0, aRun->GetNumberOfEvent()); - analysisManager->AddNtupleRow(2); - analysisManager->Write(); - analysisManager->CloseFile(); -} - -} // namespace - -#include "DDG4/Factories.h" -DECLARE_GEANT4ACTION_NS(ddml, DDMLRunAction) \ No newline at end of file From 9251bbe8d24ab2a4d807619c7e9391b2b1f01103 Mon Sep 17 00:00:00 2001 From: Peter McKeown Date: Fri, 14 Nov 2025 10:40:40 +0100 Subject: [PATCH 22/36] Add support for hadron shower simulation --- include/DDML/PionCloudsModel.h | 87 ++++++++++++-------------- include/DDML/PolyhedraBarrelGeometry.h | 4 +- scripts/ddsim_steer.py | 12 ++-- src/Geant4FastHitMakerGlobal.cc | 20 +++--- src/LoadHdf5.cc | 8 +-- src/MLModelActions.cc | 14 ++--- src/PionCloudsModel.cc | 76 ++++++++++------------ src/PolyhedraBarrelGeometry.cc | 12 ++-- 8 files changed, 110 insertions(+), 123 deletions(-) diff --git a/include/DDML/PionCloudsModel.h b/include/DDML/PionCloudsModel.h index 111a602..9b30f2a 100644 --- a/include/DDML/PionCloudsModel.h +++ b/include/DDML/PionCloudsModel.h @@ -1,74 +1,67 @@ #ifndef PionClouds_H #define PionClouds_H -#include "DDML/ModelInterface.h" #include "DDML/FastMLShower.h" - +#include "DDML/ModelInterface.h" namespace ddml { /** Class for running a point cloud based ML model for fast shower simulation. * Assumes a cartesian (x,y) coordinates defining the calorimeter planes (layers) and z the depth * of the calorimeter. - * + * * Based on BiBAETwoAngleModel. - * - * Implemented here for the PionClouds model intended for hadron shower simulation (ECAL+HCAL). - * + * + * Implemented here for the PionClouds model intended for hadron shower simulation (ECAL+HCAL). + * * @author A.Korol, DESY * @author P. McKeown, CERN * @date Feb. 2025 */ - - class PionCloudsModel : public ModelInterface { - - public: - PionCloudsModel() {} ; - - virtual ~PionCloudsModel(){}; - - /// declare the proerties needed for the plugin - void declareProperties(dd4hep::sim::Geant4Action* plugin) { - plugin->declareProperty("LatentVectorSize", this->m_latentSize); - } - - /** prepare the input vector and resize the output vector for this model - * based on the current FastTrack (e.g. extract kinetic energy and incident - * angles.) - */ - virtual void prepareInput(G4FastTrack const& aFastTrack, - G4ThreeVector const& localDir, - InputVecs& inputs, TensorDimVecs& tensDims, - std::vector& output ) ; +class PionCloudsModel : public ModelInterface { +public: + PionCloudsModel(){}; - /** create a vector of spacepoints per layer interpreting the model output - */ - virtual void convertOutput(G4FastTrack const& aFastTrack, - G4ThreeVector const& localDir, - const std::vector& output, - std::vector& spacepoints ) ; + virtual ~PionCloudsModel(){}; + /// declare the proerties needed for the plugin + void declareProperties(dd4hep::sim::Geant4Action* plugin) { + plugin->declareProperty("LatentVectorSize", this->m_latentSize); + } - - private: + /** prepare the input vector and resize the output vector for this model + * based on the current FastTrack (e.g. extract kinetic energy and incident + * angles.) + */ + virtual void prepareInput(G4FastTrack const& aFastTrack, G4ThreeVector const& localDir, InputVecs& inputs, + TensorDimVecs& tensDims, std::vector& output); - /// model properties for plugin - // These grid sizes were used for the two angle BIBAE - int m_numPoints = 2600; //4148; //2600; //number of points in the shower - int m_latentSize = 3; // number of input features (energy, theta, phi) - int m_maxNumElements = m_numPoints*4; // number of space points in the output multiplied by 4 (x,y,z,energy) - int m_nLayer = 78; + /** create a vector of spacepoints per layer interpreting the model output + */ + virtual void convertOutput(G4FastTrack const& aFastTrack, G4ThreeVector const& localDir, + const std::vector& output, std::vector& spacepoints); - struct Vector3d{double x; double y; double z;}; +private: + /// model properties for plugin + // These grid sizes were used for the two angle BIBAE + int m_numPoints = 2600; // 4148; //2600; //number of points in the shower + int m_latentSize = 3; // number of input features (energy, theta, phi) + int m_maxNumElements = m_numPoints * 4; // number of space points in the output multiplied by 4 (x,y,z,energy) + int m_nLayer = 78; - Vector3d crossProduct(const Vector3d& v1, const Vector3d& v2); + struct Vector3d { + double x; + double y; + double z; + }; - Vector3d normalize(const Vector3d& v); + Vector3d crossProduct(const Vector3d& v1, const Vector3d& v2); - TensorDimVecs m_tensDims = {{1, 1}, {1, 1}, {1, 1}, {1, 3}}; - }; + Vector3d normalize(const Vector3d& v); + + TensorDimVecs m_tensDims = {{1, 1}, {1, 1}, {1, 1}, {1, 3}}; +}; } // namespace ddml #endif - diff --git a/include/DDML/PolyhedraBarrelGeometry.h b/include/DDML/PolyhedraBarrelGeometry.h index aa8cedb..a803fe1 100644 --- a/include/DDML/PolyhedraBarrelGeometry.h +++ b/include/DDML/PolyhedraBarrelGeometry.h @@ -12,11 +12,11 @@ namespace ddml { * * @author F.Gaede, DESY * @date Mar 2023 - * + * * Addiional option included to support Hadronic shower simulation in ECAL + HCAL * @author P. McKeown, CERN * @date Feb 2025 - * + * */ class PolyhedraBarrelGeometry : public GeometryInterface { diff --git a/scripts/ddsim_steer.py b/scripts/ddsim_steer.py index 3b7b3b7..287d3f7 100644 --- a/scripts/ddsim_steer.py +++ b/scripts/ddsim_steer.py @@ -547,7 +547,7 @@ def LoadHdf5(kernel): if hadrons == True: ml_model_had = "LoadHDF5PionCloudsPCHadronModelPolyhedraBarrel/BarrelModelTorch" - ml_had_file = "../models/PionClouds_50GeV_sp_scaled.h5" + ml_had_file = "../models/PionClouds_50GeV_sp_scaled.h5" ml_correct_angles = False from g4units import GeV, MeV # DO NOT REMOVE OR MOVE!!!!! (EXCLAMATION MARK) @@ -574,7 +574,7 @@ def LoadHdf5(kernel): seq.adopt(sensitives) # ----------------- - ''' + """ ## EM in Barrel model = DetectorConstruction(kernel, str(ml_model)) @@ -597,7 +597,7 @@ def LoadHdf5(kernel): model.enableUI() seq.adopt(model) - ''' + """ # ------------------- ## EM in Endcap model1 = DetectorConstruction(kernel, str(ml_model_1)) @@ -627,7 +627,9 @@ def LoadHdf5(kernel): ## # Mandatory model parameters modelHad1.isHadShower = True - modelHad1.RegionName = "EcalBarrelRegion" #or "HcalBarrelRegion" ## hadron model triggers in ecal + modelHad1.RegionName = ( + "EcalBarrelRegion" # or "HcalBarrelRegion" ## hadron model triggers in ecal + ) modelHad1.Detector = ml_barrel_name modelHad1.HadDetector = ml_had_barrel_name modelHad1.Symmetry = ml_barrel_symmetry @@ -658,4 +660,4 @@ def LoadHdf5(kernel): # SIM.physics.setupUserPhysics( aiDance) SIM.physics.setupUserPhysics(aiDanceTorch) -#SIM.physics.setupUserPhysics(LoadHdf5) +# SIM.physics.setupUserPhysics(LoadHdf5) diff --git a/src/Geant4FastHitMakerGlobal.cc b/src/Geant4FastHitMakerGlobal.cc index 2395447..445aa19 100644 --- a/src/Geant4FastHitMakerGlobal.cc +++ b/src/Geant4FastHitMakerGlobal.cc @@ -48,10 +48,10 @@ Geant4FastHitMakerGlobal::~Geant4FastHitMakerGlobal() { //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... void Geant4FastHitMakerGlobal::make(const G4FastHit& aHit, const G4FastTrack& aTrack) { - - //std::cout << "Geant4FastHitMakerGlobal::make - aHit.GetPosition().x() " << aHit.GetPosition().x() << " aHit.GetPosition().y() " << - // aHit.GetPosition().y() << " aHit.GetPosition().z() " << aHit.GetPosition().z() << std::endl; - // do not make empty deposit + // std::cout << "Geant4FastHitMakerGlobal::make - aHit.GetPosition().x() " << aHit.GetPosition().x() << " + // aHit.GetPosition().y() " << + // aHit.GetPosition().y() << " aHit.GetPosition().z() " << aHit.GetPosition().z() << std::endl; + // do not make empty deposit if (aHit.GetEnergy() <= 0) { return; } @@ -83,13 +83,17 @@ void Geant4FastHitMakerGlobal::make(const G4FastHit& aHit, const G4FastTrack& aT G4VSensitiveDetector* sensitive; if (currentVolume != 0) { - //std::cout << "IN FULL Sim Sensitive Geant4FastHitMakerGlobal::make - aHit.GetPosition().x() " << aHit.GetPosition().x() << " aHit.GetPosition().y() " << - // aHit.GetPosition().y() << " aHit.GetPosition().z() " << aHit.GetPosition().z() << " Energy: " << aHit.GetEnergy() << std::endl; + // std::cout << "IN FULL Sim Sensitive Geant4FastHitMakerGlobal::make - aHit.GetPosition().x() " << + // aHit.GetPosition().x() << " aHit.GetPosition().y() " << + // aHit.GetPosition().y() << " aHit.GetPosition().z() " << aHit.GetPosition().z() << " Energy: " << + // aHit.GetEnergy() << std::endl; sensitive = currentVolume->GetLogicalVolume()->GetSensitiveDetector(); G4VFastSimSensitiveDetector* fastSimSensitive = dynamic_cast(sensitive); if (fastSimSensitive) { - // std::cout << "IN FAST Sim Sensitive Geant4FastHitMakerGlobal::make - aHit.GetPosition().x() " << aHit.GetPosition().x() << " aHit.GetPosition().y() " << - // aHit.GetPosition().y() << " aHit.GetPosition().z() " << aHit.GetPosition().z() << " Energy: " << aHit.GetEnergy() << std::endl; + // std::cout << "IN FAST Sim Sensitive Geant4FastHitMakerGlobal::make - aHit.GetPosition().x() " << + // aHit.GetPosition().x() << " aHit.GetPosition().y() " << + // aHit.GetPosition().y() << " aHit.GetPosition().z() " << aHit.GetPosition().z() << " Energy: " << + // aHit.GetEnergy() << std::endl; fastSimSensitive->Hit(&aHit, &aTrack, &m_touchableHandle); } else if (sensitive && currentVolume->GetLogicalVolume()->GetFastSimulationManager()) { G4cerr << "ERROR - Geant4FastHitMakerGlobal::make()" << G4endl << " It is required to derive from the " diff --git a/src/LoadHdf5.cc b/src/LoadHdf5.cc index 5007782..c347f31 100644 --- a/src/LoadHdf5.cc +++ b/src/LoadHdf5.cc @@ -19,7 +19,7 @@ void LoadHdf5::initialize() { // inputs and TensorDimVecs unused // Open dataset + dataspace - std::string datasetName = "spase_points"; //"events"; //"spase_points"; //"layers"; + std::string datasetName = "spase_points"; //"events"; //"spase_points"; //"layers"; H5::DataSet dataset = m_file.openDataSet(datasetName); dd4hep::printout(dd4hep::DEBUG, "LoadHdf5::initialize", "Accessed HDF5 dataset"); H5::DataSpace dataspace = dataset.getSpace(); @@ -39,7 +39,7 @@ void LoadHdf5::initialize() { m_dimsOut = dims_out; -// assert(rank == 4); // assuming 4 dimensional input + // assert(rank == 4); // assuming 4 dimensional input // index 0: shower number // index 1, 2, 3: x, y, z cell number @@ -85,7 +85,7 @@ void LoadHdf5::runInference(const InputVecs&, const TensorDimVecs&, std::vector< } // select shower from library - //std::vector shower(m_library.begin() + m_count * m_dimsOut[1] * m_dimsOut[2] * m_dimsOut[3], + // std::vector shower(m_library.begin() + m_count * m_dimsOut[1] * m_dimsOut[2] * m_dimsOut[3], // m_library.begin() + (m_count + 1) * m_dimsOut[1] * m_dimsOut[2] * m_dimsOut[3]); // select shower from library @@ -93,7 +93,7 @@ void LoadHdf5::runInference(const InputVecs&, const TensorDimVecs&, std::vector< m_library.begin() + (m_count + 1) * m_dimsOut[1] * m_dimsOut[2]); // enforce length of shower - //assert(shower.size() == m_dimsOut[1] * m_dimsOut[2] * m_dimsOut[3]); + // assert(shower.size() == m_dimsOut[1] * m_dimsOut[2] * m_dimsOut[3]); assert(shower.size() == m_dimsOut[1] * m_dimsOut[2]); diff --git a/src/MLModelActions.cc b/src/MLModelActions.cc index 5e88b6b..c0ea2bf 100644 --- a/src/MLModelActions.cc +++ b/src/MLModelActions.cc @@ -21,11 +21,11 @@ #include "DDML/L2LFlowsModel.h" #include "DDML/OctogonalBarrelTrigger.h" #include "DDML/Par04ExampleVAE.h" +#include "DDML/PionCloudsModel.h" #include "DDML/PolyhedraBarrelGeometry.h" #include "DDML/RegularGridBIBAEModel.h" #include "DDML/RegularGridGANModel.h" #include "DDML/RegularGridTwoAngleBIBAEModel.h" -#include "DDML/PionCloudsModel.h" #include "DDML/TriggerInterface.h" namespace ddml { @@ -131,18 +131,16 @@ typedef FastMLShower< /// Load from HDF5 file- as an example for Hadron showers from PionClouds // Barrel -typedef FastMLShower> // add ML trigger +typedef FastMLShower< + FastMLModel> // add ML trigger LoadHDF5PionCloudsPCHadronModelPolyhedraBarrel; // Endcap // ENDCAP IS CURRENTLY NOT IMPLEMENTED!!!! -typedef FastMLShower< - FastMLModel> // add ML trigger +typedef FastMLShower> // add ML trigger LoadHDF5PionCloudsPCHadronModelEndcap; #endif - } // namespace ddml #include diff --git a/src/PionCloudsModel.cc b/src/PionCloudsModel.cc index 7604f3a..e08f27d 100644 --- a/src/PionCloudsModel.cc +++ b/src/PionCloudsModel.cc @@ -1,16 +1,13 @@ #include "DDML/PionCloudsModel.h" -#include // for G4FastTrack +#include // for G4FastTrack #define DEBUGPRINT 0 namespace ddml { - void PionCloudsModel::prepareInput(G4FastTrack const& aFastTrack, - G4ThreeVector const& localDir, - InputVecs& inputs, TensorDimVecs& tensDims, - std::vector& output ) { - +void PionCloudsModel::prepareInput(G4FastTrack const& aFastTrack, G4ThreeVector const& localDir, InputVecs& inputs, + TensorDimVecs& tensDims, std::vector& output) { tensDims = m_tensDims; G4double energy = aFastTrack.GetPrimaryTrack()->GetKineticEnergy(); @@ -27,8 +24,8 @@ namespace ddml { localDir_.setX(-1. * localDir_.x()); // *(-1) to align local to global convention in ddml localDir_.setY(-1. * localDir_.y()); // *(-1) to align local to global convention in ddml - dd4hep::printout(dd4hep::DEBUG, "PionCloudsModel::prepareInput", "DDML::localDir: (%f, %f, %f)", - localDir_.x(), localDir_.y(), localDir_.z()); + dd4hep::printout(dd4hep::DEBUG, "PionCloudsModel::prepareInput", "DDML::localDir: (%f, %f, %f)", localDir_.x(), + localDir_.y(), localDir_.z()); // compute local incident angles double r = sqrt(localDir_.x() * localDir_.x() + localDir_.y() * localDir_.y() + localDir_.z() * localDir_.z()); @@ -55,44 +52,39 @@ namespace ddml { dd4hep::printout(dd4hep::DEBUG, "PionCloudsModel::prepareInput", "Input_phi_tensor : %f", inputs[2][0]); // ---- resize output vector - + output.assign(m_maxNumElements, 0); } - // For array structure: (No. showers, No. points, dimensions(4)) -void PionCloudsModel::convertOutput(G4FastTrack const& aFastTrack, - G4ThreeVector const& localDir, - const std::vector& output, - std::vector& spacepoints ){ - - //int nPoints = m_numPoints ; // number of points in shower - - int layerNum = 0; - - std::vector> reshaped(m_numPoints, std::vector(4)); - - // Fill the 3D array-like vector using the flattened vector - int index = 0; - for (int j = 0; j < m_numPoints; ++j) { - for (int k = 0; k < 4; ++k) { - reshaped[j][k] = output[index]; - index++; - } - } - - spacepoints.resize( m_nLayer ) ; - - for (int i = 0; i < m_numPoints; i++) { - ddml::SpacePoint sp( - reshaped[i][0], // x // *(-1) to align local to global convention in ddml - reshaped[i][2], // y // *(-1) to align local to global convention in ddml - 0., // z - reshaped[i][3], // energy - 0. // time +void PionCloudsModel::convertOutput(G4FastTrack const& aFastTrack, G4ThreeVector const& localDir, + const std::vector& output, std::vector& spacepoints) { + // int nPoints = m_numPoints ; // number of points in shower + + int layerNum = 0; + + std::vector> reshaped(m_numPoints, std::vector(4)); + + // Fill the 3D array-like vector using the flattened vector + int index = 0; + for (int j = 0; j < m_numPoints; ++j) { + for (int k = 0; k < 4; ++k) { + reshaped[j][k] = output[index]; + index++; + } + } + + spacepoints.resize(m_nLayer); + + for (int i = 0; i < m_numPoints; i++) { + ddml::SpacePoint sp(reshaped[i][0], // x // *(-1) to align local to global convention in ddml + reshaped[i][2], // y // *(-1) to align local to global convention in ddml + 0., // z + reshaped[i][3], // energy + 0. // time ); layerNum = reshaped[i][1]; - spacepoints[layerNum].emplace_back( sp ) ; - } + spacepoints[layerNum].emplace_back(sp); } -} \ No newline at end of file +} +} // namespace ddml \ No newline at end of file diff --git a/src/PolyhedraBarrelGeometry.cc b/src/PolyhedraBarrelGeometry.cc index f05a35f..37717cc 100644 --- a/src/PolyhedraBarrelGeometry.cc +++ b/src/PolyhedraBarrelGeometry.cc @@ -27,15 +27,14 @@ void PolyhedraBarrelGeometry::initialize() { // For hadronic shower simulation if (m_isHadShower == true) { - auto det_had = theDetector.detector(m_HadDetector); - auto* cal_had = det_had.extension(); + auto det_had = theDetector.detector(m_HadDetector); + auto* cal_had = det_had.extension(); if (cal_had) { for (auto l_had : cal_had->layers) { m_caloLayerDistances.push_back((l_had.distance + l_had.inner_thickness) / dd4hep::mm); std::cout << " HCAL Layer distances " << l_had.distance + l_had.inner_thickness << std::endl; } - } - else { + } else { std::cout << " ###### error: detector " << m_HadDetector << " not found !" << std::endl; } } @@ -186,9 +185,8 @@ void PolyhedraBarrelGeometry::localToGlobal(G4FastTrack const& aFastTrack, sp.Y = global.y(); sp.Z = global.z(); - std::cout << " PolyhedraBarrelGeometry::localToGlobal - global.x() = " << global.x() << " global.y() = " << global.y() - << " global.z() " << global.z() << " Energy: " << sp.E << std::endl; - + std::cout << " PolyhedraBarrelGeometry::localToGlobal - global.x() = " << global.x() + << " global.y() = " << global.y() << " global.z() " << global.z() << " Energy: " << sp.E << std::endl; } } } From 28e9767d8a1942b5b4fd0d1ba4f78d66ffaa60b3 Mon Sep 17 00:00:00 2001 From: peter-mckeown <74307317+peter-mckeown@users.noreply.github.com> Date: Thu, 20 Nov 2025 13:34:24 +0100 Subject: [PATCH 23/36] Update include/DDML/PionCloudsModel.h Co-authored-by: Thomas Madlener --- include/DDML/PionCloudsModel.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/DDML/PionCloudsModel.h b/include/DDML/PionCloudsModel.h index 9b30f2a..34c2adf 100644 --- a/include/DDML/PionCloudsModel.h +++ b/include/DDML/PionCloudsModel.h @@ -44,7 +44,6 @@ class PionCloudsModel : public ModelInterface { private: /// model properties for plugin - // These grid sizes were used for the two angle BIBAE int m_numPoints = 2600; // 4148; //2600; //number of points in the shower int m_latentSize = 3; // number of input features (energy, theta, phi) int m_maxNumElements = m_numPoints * 4; // number of space points in the output multiplied by 4 (x,y,z,energy) From 7de7d1b6d6b9c16ad97d71971d39b40b07e3c73b Mon Sep 17 00:00:00 2001 From: peter-mckeown <74307317+peter-mckeown@users.noreply.github.com> Date: Thu, 20 Nov 2025 13:56:48 +0100 Subject: [PATCH 24/36] Update include/DDML/PionCloudsModel.h Co-authored-by: Thomas Madlener --- include/DDML/PionCloudsModel.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/include/DDML/PionCloudsModel.h b/include/DDML/PionCloudsModel.h index 34c2adf..3b8bf58 100644 --- a/include/DDML/PionCloudsModel.h +++ b/include/DDML/PionCloudsModel.h @@ -49,11 +49,6 @@ class PionCloudsModel : public ModelInterface { int m_maxNumElements = m_numPoints * 4; // number of space points in the output multiplied by 4 (x,y,z,energy) int m_nLayer = 78; - struct Vector3d { - double x; - double y; - double z; - }; Vector3d crossProduct(const Vector3d& v1, const Vector3d& v2); From 415e1e6e7f824a88fd8861f6af971d20eeac2f10 Mon Sep 17 00:00:00 2001 From: peter-mckeown <74307317+peter-mckeown@users.noreply.github.com> Date: Thu, 20 Nov 2025 13:57:00 +0100 Subject: [PATCH 25/36] Update include/DDML/PionCloudsModel.h Co-authored-by: Thomas Madlener --- include/DDML/PionCloudsModel.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/DDML/PionCloudsModel.h b/include/DDML/PionCloudsModel.h index 3b8bf58..a132a8f 100644 --- a/include/DDML/PionCloudsModel.h +++ b/include/DDML/PionCloudsModel.h @@ -50,9 +50,6 @@ class PionCloudsModel : public ModelInterface { int m_nLayer = 78; - Vector3d crossProduct(const Vector3d& v1, const Vector3d& v2); - - Vector3d normalize(const Vector3d& v); TensorDimVecs m_tensDims = {{1, 1}, {1, 1}, {1, 1}, {1, 3}}; }; From 6ebc1c85fcffedad800d1ede3722de6ad61c0a20 Mon Sep 17 00:00:00 2001 From: Peter McKeown Date: Thu, 20 Nov 2025 14:32:36 +0100 Subject: [PATCH 26/36] fix clang-tidy pre-commit --- include/DDML/PolyhedraBarrelGeometry.h | 4 ++-- src/PionCloudsModel.cc | 2 +- src/PolyhedraBarrelGeometry.cc | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/DDML/PolyhedraBarrelGeometry.h b/include/DDML/PolyhedraBarrelGeometry.h index a803fe1..46b9cbc 100644 --- a/include/DDML/PolyhedraBarrelGeometry.h +++ b/include/DDML/PolyhedraBarrelGeometry.h @@ -34,7 +34,7 @@ class PolyhedraBarrelGeometry : public GeometryInterface { void declareProperties(dd4hep::sim::Geant4Action* plugin) { plugin->declareProperty("Detector", this->m_detector); plugin->declareProperty("isHadShower", this->m_isHadShower); - plugin->declareProperty("HadDetector", this->m_HadDetector); + plugin->declareProperty("HadDetector", this->m_hadDetector); plugin->declareProperty("Symmetry", this->m_nSymmetry); plugin->declareProperty("HadSymmetry", this->m_nHadSymmetry); plugin->declareProperty("CorrectForAngles", this->m_correctForAngles); @@ -61,7 +61,7 @@ class PolyhedraBarrelGeometry : public GeometryInterface { int m_nSymmetry = 8; bool m_correctForAngles = false; bool m_isHadShower = true; - std::string m_HadDetector = {"HcalBarrel"}; + std::string m_hadDetector = {"HcalBarrel"}; int m_nHadSymmetry = m_nSymmetry; }; diff --git a/src/PionCloudsModel.cc b/src/PionCloudsModel.cc index e08f27d..d71f744 100644 --- a/src/PionCloudsModel.cc +++ b/src/PionCloudsModel.cc @@ -57,7 +57,7 @@ void PionCloudsModel::prepareInput(G4FastTrack const& aFastTrack, G4ThreeVector } // For array structure: (No. showers, No. points, dimensions(4)) -void PionCloudsModel::convertOutput(G4FastTrack const& aFastTrack, G4ThreeVector const& localDir, +void PionCloudsModel::convertOutput(G4FastTrack const&, G4ThreeVector const&, const std::vector& output, std::vector& spacepoints) { // int nPoints = m_numPoints ; // number of points in shower diff --git a/src/PolyhedraBarrelGeometry.cc b/src/PolyhedraBarrelGeometry.cc index 37717cc..1336e5e 100644 --- a/src/PolyhedraBarrelGeometry.cc +++ b/src/PolyhedraBarrelGeometry.cc @@ -27,7 +27,7 @@ void PolyhedraBarrelGeometry::initialize() { // For hadronic shower simulation if (m_isHadShower == true) { - auto det_had = theDetector.detector(m_HadDetector); + auto det_had = theDetector.detector(m_hadDetector); auto* cal_had = det_had.extension(); if (cal_had) { for (auto l_had : cal_had->layers) { @@ -35,7 +35,7 @@ void PolyhedraBarrelGeometry::initialize() { std::cout << " HCAL Layer distances " << l_had.distance + l_had.inner_thickness << std::endl; } } else { - std::cout << " ###### error: detector " << m_HadDetector << " not found !" << std::endl; + std::cout << " ###### error: detector " << m_hadDetector << " not found !" << std::endl; } } } From 6cbd4e8b0d1430bbe0a3e67e04dd039ce7224454 Mon Sep 17 00:00:00 2001 From: Peter McKeown Date: Thu, 20 Nov 2025 16:16:04 +0100 Subject: [PATCH 27/36] remove some commented code --- src/Geant4FastHitMakerGlobal.cc | 17 ++--------------- src/LoadHdf5.cc | 4 ---- src/PionCloudsModel.cc | 3 --- 3 files changed, 2 insertions(+), 22 deletions(-) diff --git a/src/Geant4FastHitMakerGlobal.cc b/src/Geant4FastHitMakerGlobal.cc index 445aa19..57ed70a 100644 --- a/src/Geant4FastHitMakerGlobal.cc +++ b/src/Geant4FastHitMakerGlobal.cc @@ -48,10 +48,6 @@ Geant4FastHitMakerGlobal::~Geant4FastHitMakerGlobal() { //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... void Geant4FastHitMakerGlobal::make(const G4FastHit& aHit, const G4FastTrack& aTrack) { - // std::cout << "Geant4FastHitMakerGlobal::make - aHit.GetPosition().x() " << aHit.GetPosition().x() << " - // aHit.GetPosition().y() " << - // aHit.GetPosition().y() << " aHit.GetPosition().z() " << aHit.GetPosition().z() << std::endl; - // do not make empty deposit if (aHit.GetEnergy() <= 0) { return; } @@ -68,32 +64,23 @@ void Geant4FastHitMakerGlobal::make(const G4FastHit& aHit, const G4FastTrack& aT m_navigator->SetWorldVolume(worldWithSD); // use track global position m_navigator->LocateGlobalPointAndUpdateTouchable( - // aTrack.GetPrimaryTrack()->GetPosition(), aHit.GetPosition(), m_touchableHandle(), false); m_naviSetup = true; } else { // for further deposits use hit (local) position and local->global // transformation m_navigator->LocateGlobalPointAndUpdateTouchable( - // aTrack.GetInverseAffineTransformation()->TransformPoint( - // aHit.GetPosition()), aHit.GetPosition(), m_touchableHandle()); } G4VPhysicalVolume* currentVolume = m_touchableHandle()->GetVolume(); G4VSensitiveDetector* sensitive; if (currentVolume != 0) { - // std::cout << "IN FULL Sim Sensitive Geant4FastHitMakerGlobal::make - aHit.GetPosition().x() " << - // aHit.GetPosition().x() << " aHit.GetPosition().y() " << - // aHit.GetPosition().y() << " aHit.GetPosition().z() " << aHit.GetPosition().z() << " Energy: " << - // aHit.GetEnergy() << std::endl; + // In full sim sensitive detector sensitive = currentVolume->GetLogicalVolume()->GetSensitiveDetector(); G4VFastSimSensitiveDetector* fastSimSensitive = dynamic_cast(sensitive); if (fastSimSensitive) { - // std::cout << "IN FAST Sim Sensitive Geant4FastHitMakerGlobal::make - aHit.GetPosition().x() " << - // aHit.GetPosition().x() << " aHit.GetPosition().y() " << - // aHit.GetPosition().y() << " aHit.GetPosition().z() " << aHit.GetPosition().z() << " Energy: " << - // aHit.GetEnergy() << std::endl; + // In fast sim sensitive detector fastSimSensitive->Hit(&aHit, &aTrack, &m_touchableHandle); } else if (sensitive && currentVolume->GetLogicalVolume()->GetFastSimulationManager()) { G4cerr << "ERROR - Geant4FastHitMakerGlobal::make()" << G4endl << " It is required to derive from the " diff --git a/src/LoadHdf5.cc b/src/LoadHdf5.cc index c347f31..3eb0242 100644 --- a/src/LoadHdf5.cc +++ b/src/LoadHdf5.cc @@ -76,8 +76,6 @@ void LoadHdf5::runInference(const InputVecs&, const TensorDimVecs&, std::vector< m_isInitialized = true; } - // keep track of shower index in file - // LoadHdf5::incrementCounter(); // If counter exceeds number of showers in file, reset if (m_count > m_totalSize) { @@ -92,8 +90,6 @@ void LoadHdf5::runInference(const InputVecs&, const TensorDimVecs&, std::vector< std::vector shower(m_library.begin() + m_count * m_dimsOut[1] * m_dimsOut[2], m_library.begin() + (m_count + 1) * m_dimsOut[1] * m_dimsOut[2]); - // enforce length of shower - // assert(shower.size() == m_dimsOut[1] * m_dimsOut[2] * m_dimsOut[3]); assert(shower.size() == m_dimsOut[1] * m_dimsOut[2]); diff --git a/src/PionCloudsModel.cc b/src/PionCloudsModel.cc index d71f744..9e411f5 100644 --- a/src/PionCloudsModel.cc +++ b/src/PionCloudsModel.cc @@ -18,7 +18,6 @@ void PionCloudsModel::prepareInput(G4FastTrack const& aFastTrack, G4ThreeVector G4RotationMatrix rotX; rotX.rotateX(M_PI / 2.); // this convention is used for the local coordinates in the dataset (model was trained in this convention) - // G4ThreeVector localDir_ = rotZ * (rotX * direction) ; G4ThreeVector localDir_ = localDir; localDir_.setX(-1. * localDir_.x()); // *(-1) to align local to global convention in ddml @@ -33,7 +32,6 @@ void PionCloudsModel::prepareInput(G4FastTrack const& aFastTrack, G4ThreeVector double phi = atan2(localDir_.y(), localDir_.x()) / M_PI * 180.; dd4hep::printout(dd4hep::DEBUG, "PionCloudsModel::prepareInput", "DDML::localDir: (%f, %f)", theta, phi); - // std::cout << "PionClouds::localDir:" << " theta = " << theta << " phi = " << phi << std::endl; // the input for the PionClouds is one energy and two angles (local Theta and Phi) inputs.resize(m_latentSize); @@ -59,7 +57,6 @@ void PionCloudsModel::prepareInput(G4FastTrack const& aFastTrack, G4ThreeVector // For array structure: (No. showers, No. points, dimensions(4)) void PionCloudsModel::convertOutput(G4FastTrack const&, G4ThreeVector const&, const std::vector& output, std::vector& spacepoints) { - // int nPoints = m_numPoints ; // number of points in shower int layerNum = 0; From 18ac5c58321c9872b529c1f9123a8c913cc2a35a Mon Sep 17 00:00:00 2001 From: Peter McKeown Date: Thu, 20 Nov 2025 16:36:41 +0100 Subject: [PATCH 28/36] dynamically create shower library based on dimensions of loaded file --- include/DDML/LoadHdf5.h | 3 +++ src/LoadHdf5.cc | 38 ++++++++++++++++++++++---------------- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/include/DDML/LoadHdf5.h b/include/DDML/LoadHdf5.h index 74bdf02..e104b7a 100644 --- a/include/DDML/LoadHdf5.h +++ b/include/DDML/LoadHdf5.h @@ -51,6 +51,9 @@ class LoadHdf5 : public InferenceInterface { // shower library dimensions std::vector m_dimsOut{}; + // dimensions of shower library + int m_rank; + // properties for plugin std::string m_filePath = {}; diff --git a/src/LoadHdf5.cc b/src/LoadHdf5.cc index 3eb0242..e86a856 100644 --- a/src/LoadHdf5.cc +++ b/src/LoadHdf5.cc @@ -28,8 +28,8 @@ void LoadHdf5::initialize() { // bool H5::DataSpace::isSimple() const; // Get dimensions - int rank = dataspace.getSimpleExtentNdims(); - std::vector dims_out(rank); + m_rank = dataspace.getSimpleExtentNdims(); + std::vector dims_out(m_rank); dataspace.getSimpleExtentDims(dims_out.data(), nullptr); // Calculate the total number of elements @@ -39,18 +39,19 @@ void LoadHdf5::initialize() { m_dimsOut = dims_out; - // assert(rank == 4); // assuming 4 dimensional input + assert(m_rank == 3 || m_rank == 4); // ensure either 3 dimensional PionCloud input or 4 dimensional input + // if m_rank == 4 // index 0: shower number // index 1, 2, 3: x, y, z cell number - - assert(rank == 3); // assuming 3 dimensional PionCloud input + + // else if m_rank == 3 // index 0: shower number // index 1: number of points // index 2: 4 point dimensions (x, y, z, E) - currently in ILD coordinates - dd4hep::printout(dd4hep::DEBUG, "LoadHdf5::initialize", "Rank %i", rank); + dd4hep::printout(dd4hep::DEBUG, "LoadHdf5::initialize", "Rank %i", m_rank); - for (int i = 0, N = rank; i < N; ++i) { + for (int i = 0, N = m_rank; i < N; ++i) { dd4hep::printout(dd4hep::DEBUG, "LoadHdf5::initialize", "dimension %i: %lu", i, (unsigned long)(m_dimsOut[i])); } @@ -83,18 +84,23 @@ void LoadHdf5::runInference(const InputVecs&, const TensorDimVecs&, std::vector< } // select shower from library - // std::vector shower(m_library.begin() + m_count * m_dimsOut[1] * m_dimsOut[2] * m_dimsOut[3], - // m_library.begin() + (m_count + 1) * m_dimsOut[1] * m_dimsOut[2] * m_dimsOut[3]); + if (m_rank == 4) { + std::vector shower(m_library.begin() + m_count * m_dimsOut[1] * m_dimsOut[2] * m_dimsOut[3], + m_library.begin() + (m_count + 1) * m_dimsOut[1] * m_dimsOut[2] * m_dimsOut[3]); + assert(shower.size() == m_dimsOut[1] * m_dimsOut[2] * m_dimsOut[3]); - // select shower from library - std::vector shower(m_library.begin() + m_count * m_dimsOut[1] * m_dimsOut[2], + // write output + output = std::move(shower); + } + else if (m_rank == 3 ){ + std::vector shower(m_library.begin() + m_count * m_dimsOut[1] * m_dimsOut[2], m_library.begin() + (m_count + 1) * m_dimsOut[1] * m_dimsOut[2]); + assert(shower.size() == m_dimsOut[1] * m_dimsOut[2]); - - assert(shower.size() == m_dimsOut[1] * m_dimsOut[2]); - - // write output - output = std::move(shower); + // write output + output = std::move(shower); + } + else{throw std::runtime_error("Shower library does not have the correct dimensions!");} ++m_count; } From 60dd7c47be2bd85427115ee20b77054269c86283 Mon Sep 17 00:00:00 2001 From: Peter McKeown Date: Fri, 21 Nov 2025 14:55:28 +0100 Subject: [PATCH 29/36] Implement PionClouds convertOutput optimisation from code review --- include/DDML/PionCloudsModel.h | 1 + src/PionCloudsModel.cc | 41 +++++++++++++++------------------- 2 files changed, 19 insertions(+), 23 deletions(-) diff --git a/include/DDML/PionCloudsModel.h b/include/DDML/PionCloudsModel.h index a132a8f..d92068c 100644 --- a/include/DDML/PionCloudsModel.h +++ b/include/DDML/PionCloudsModel.h @@ -45,6 +45,7 @@ class PionCloudsModel : public ModelInterface { private: /// model properties for plugin int m_numPoints = 2600; // 4148; //2600; //number of points in the shower + size_t m_nDims = 4; // Number of dimensions int m_latentSize = 3; // number of input features (energy, theta, phi) int m_maxNumElements = m_numPoints * 4; // number of space points in the output multiplied by 4 (x,y,z,energy) int m_nLayer = 78; diff --git a/src/PionCloudsModel.cc b/src/PionCloudsModel.cc index 9e411f5..fde8004 100644 --- a/src/PionCloudsModel.cc +++ b/src/PionCloudsModel.cc @@ -1,6 +1,7 @@ #include "DDML/PionCloudsModel.h" #include // for G4FastTrack +#include #define DEBUGPRINT 0 @@ -57,31 +58,25 @@ void PionCloudsModel::prepareInput(G4FastTrack const& aFastTrack, G4ThreeVector // For array structure: (No. showers, No. points, dimensions(4)) void PionCloudsModel::convertOutput(G4FastTrack const&, G4ThreeVector const&, const std::vector& output, std::vector& spacepoints) { - + const int nPoints = output.size() / m_nDims; int layerNum = 0; - - std::vector> reshaped(m_numPoints, std::vector(4)); - - // Fill the 3D array-like vector using the flattened vector - int index = 0; - for (int j = 0; j < m_numPoints; ++j) { - for (int k = 0; k < 4; ++k) { - reshaped[j][k] = output[index]; - index++; - } - } - - spacepoints.resize(m_nLayer); - - for (int i = 0; i < m_numPoints; i++) { - ddml::SpacePoint sp(reshaped[i][0], // x // *(-1) to align local to global convention in ddml - reshaped[i][2], // y // *(-1) to align local to global convention in ddml - 0., // z - reshaped[i][3], // energy - 0. // time + // Reshape into intermediate representation + auto reshaped = + std::views::iota(0,nPoints) | + std::views::transform([&output](int i){ + return std::span{output.data() + i * 4, 4}; + }); + + spacepoints.resize(nPoints); + for (const auto& values : reshaped) { + ddml::SpacePoint sp(values[0], // x // *(-1) to align local to global convention in ddml + values[2], // y // *(-1) to align local to global convention in ddml + 0., // z + values[3], // energy + 0. // time ); - layerNum = reshaped[i][1]; + layerNum = int(values[1]); spacepoints[layerNum].emplace_back(sp); - } + } } } // namespace ddml \ No newline at end of file From ff75b2ce2c8973c147ce9d7e56ac919cdac0df1d Mon Sep 17 00:00:00 2001 From: Peter McKeown Date: Mon, 24 Nov 2025 17:36:12 +0100 Subject: [PATCH 30/36] use dd4hep logging facilities throughout code base --- src/EndcapGeometry.cc | 33 ++++-- src/Geant4FastHitMakerGlobal.cc | 9 ++ src/ONNXInference.cc | 53 ++++++--- src/Par04ExampleVAE.cc | 14 ++- src/PolyhedraBarrelGeometry.cc | 85 ++++++++++---- src/RegularGridBIBAEModel.cc | 23 ++-- src/RegularGridGANModel.cc | 13 ++- src/RegularGridTwoAngleBIBAEModel.cc | 165 ++++++++++++++++++--------- src/TorchInference.cc | 57 ++++++--- 9 files changed, 309 insertions(+), 143 deletions(-) diff --git a/src/EndcapGeometry.cc b/src/EndcapGeometry.cc index ccf5d3a..021f388 100644 --- a/src/EndcapGeometry.cc +++ b/src/EndcapGeometry.cc @@ -22,7 +22,10 @@ void EndcapGeometry::initialize() { } } else { - std::cout << " ###### error: detector " << m_detector << " not found !" << std::endl; + dd4hep::printout(dd4hep::ERROR, "EndcapGeometry::initialize", "Detector %s not found!", m_detector.c_str()); + /* REMOVE! + //std::cout << " ###### error: detector " << m_detector << " not found !" << std::endl; + */ } } @@ -41,13 +44,17 @@ G4ThreeVector EndcapGeometry::localDirection(G4FastTrack const& aFastTrack) cons localDir = {-direction.x(), direction.y(), -direction.z()}; } - if (DEBUGPRINT) { - G4double energy = aFastTrack.GetPrimaryTrack()->GetKineticEnergy(); + dd4hep::printout(dd4hep::DEBUG, "EndcapGeometry::localDirection", "pos0 = (%f, %f, %f) - dir = (%f, %f, %f) - E = %f" , + position.x(), position.y(), position.z(), direction.x(), direction.y(), direction.z(), aFastTrack.GetPrimaryTrack()->GetKineticEnergy()); + /* REMOVE! + //if (DEBUGPRINT) { + // G4double energy = aFastTrack.GetPrimaryTrack()->GetKineticEnergy(); - std::cout << " EndcapGeometry::localDirection " - << " pos0 = " << position << " - dir = " << direction << " - E = " - << " - localDir = " << localDir << energy << std::endl; - } + // std::cout << " EndcapGeometry::localDirection " + // << " pos0 = " << position << " - dir = " << direction << " - E = " + // << " - localDir = " << localDir << energy << std::endl; + //} + */ return localDir; } @@ -58,10 +65,14 @@ void EndcapGeometry::localToGlobal(G4FastTrack const& aFastTrack, std::vectorGetPosition(); G4ThreeVector direction = aFastTrack.GetPrimaryTrack()->GetMomentumDirection(); - if (DEBUGPRINT) { - std::cout << " EndcapGeometry::localToGlobal pos0 = " << position << " - dir = " << direction - << " - E = " << energy << std::endl; - } + dd4hep::printout(dd4hep::DEBUG, "EndcapGeometry::localToGlobal", "pos0 = (%f, %f, %f) - dir = (%f, %f, %f) - E = %f", + position.x(), position.y(), position.z(), direction.x(), direction.y(), direction.z(), energy); + /* REMOVE! + //if (DEBUGPRINT) { + // std::cout << " EndcapGeometry::localToGlobal pos0 = " << position << " - dir = " << direction + // << " - E = " << energy << std::endl; + //} + */ float signZ = (position.z() > 0. ? 1.0 : -1.0); diff --git a/src/Geant4FastHitMakerGlobal.cc b/src/Geant4FastHitMakerGlobal.cc index 57ed70a..956e439 100644 --- a/src/Geant4FastHitMakerGlobal.cc +++ b/src/Geant4FastHitMakerGlobal.cc @@ -48,6 +48,7 @@ Geant4FastHitMakerGlobal::~Geant4FastHitMakerGlobal() { //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... void Geant4FastHitMakerGlobal::make(const G4FastHit& aHit, const G4FastTrack& aTrack) { + // do not make empty deposit if (aHit.GetEnergy() <= 0) { return; } @@ -77,10 +78,18 @@ void Geant4FastHitMakerGlobal::make(const G4FastHit& aHit, const G4FastTrack& aT G4VSensitiveDetector* sensitive; if (currentVolume != 0) { // In full sim sensitive detector + //dd4hep::printout(dd4hep::DEBUG, "Geant4FastHitMakerGlobal::make", "In full sim sensitive: aHit.GetPosition() x: %f, y: %f, z: %f ", + // aHit.GetPosition().x(), aHit.GetPosition().y(), aHit.GetPosition().z()); + G4debug << "DEBUG - Geant4FastHitMakerGlobal::make- In full sim sensitive: aHit.GetPosition() x: " << aHit.GetPosition().x() << " y: " << + aHit.GetPosition().y() << " z: " << aHit.GetPosition().z() << G4endl; sensitive = currentVolume->GetLogicalVolume()->GetSensitiveDetector(); G4VFastSimSensitiveDetector* fastSimSensitive = dynamic_cast(sensitive); if (fastSimSensitive) { // In fast sim sensitive detector + //dd4hep::printout(dd4hep::DEBUG, "Geant4FastHitMakerGlobal::make", "In fast sim sensitive: aHit.GetPosition() x: %f, y: %f, z: %f ", + // aHit.GetPosition().x(), aHit.GetPosition().y(), aHit.GetPosition().z()); + G4debug << "DEBUG - Geant4FastHitMakerGlobal::make- In fast sim sensitive: aHit.GetPosition() x: " << aHit.GetPosition().x() << " y: " << + aHit.GetPosition().y() << " z: " << aHit.GetPosition().z() << G4endl; fastSimSensitive->Hit(&aHit, &aTrack, &m_touchableHandle); } else if (sensitive && currentVolume->GetLogicalVolume()->GetFastSimulationManager()) { G4cerr << "ERROR - Geant4FastHitMakerGlobal::make()" << G4endl << " It is required to derive from the " diff --git a/src/ONNXInference.cc b/src/ONNXInference.cc index 1f7b30e..040e3ed 100644 --- a/src/ONNXInference.cc +++ b/src/ONNXInference.cc @@ -60,25 +60,33 @@ void ONNXInference::initialize() { #else const auto input_name = m_session->GetInputNameAllocated(i, allocator).release(); #endif - - if (DEBUGPRINT) { - std::cout << " *** input_name : " << i << " = " << input_name << std::endl; - } + dd4hep::printout(dd4hep::DEBUG, "ONNXInference::initialize", "input_name : %i = %c", i, input_name); + /* REMOVE! + //if (DEBUGPRINT) { + // std::cout << " *** input_name : " << i << " = " << input_name << std::endl; + //} + */ m_inNames.push_back(input_name); input_node_names[i] = input_name; Ort::TypeInfo type_info = m_session->GetInputTypeInfo(i); auto tensor_info = type_info.GetTensorTypeAndShapeInfo(); input_node_dims = tensor_info.GetShape(); - if (DEBUGPRINT) { - std::cout << " *** input_node_dims : " << i << " = " << input_node_dims.size() << std::endl; - } + dd4hep::printout(dd4hep::DEBUG, "ONNXInference::initialize", "input_node_dims : %i = %i", i, input_node_dims.size()); + /* REMOVE! + //if (DEBUGPRINT) { + // std::cout << " *** input_node_dims : " << i << " = " << input_node_dims.size() << std::endl; + //} + */ for (std::size_t j = 0; j < input_node_dims.size(); j++) { if (input_node_dims[j] < 0) { input_node_dims[j] = 1; } - if (DEBUGPRINT) { - std::cout << " - dim " << j << " : " << input_node_dims[j] << std::endl; + dd4hep::printout(dd4hep::DEBUG, "ONNXInference::initialize", "dim %i : %i",j, input_node_dims[j] ); + /* + //if (DEBUGPRINT) { + // std::cout << " - dim " << j << " : " << input_node_dims[j] << std::endl; } + */ } } // output nodes @@ -93,22 +101,31 @@ void ONNXInference::initialize() { #endif m_outNames.push_back(output_name); output_node_names[i] = output_name; - if (DEBUGPRINT) { - std::cout << " *** output_name : " << i << " = " << output_name << std::endl; - } + dd4hep::printout(dd4hep::DEBUG, "ONNXInference::initialize", "output_name: %i = %c", i, output_name); + /* + //if (DEBUGPRINT) { + // std::cout << " *** output_name : " << i << " = " << output_name << std::endl; + //} + */ Ort::TypeInfo type_info = m_session->GetOutputTypeInfo(i); auto tensor_info = type_info.GetTensorTypeAndShapeInfo(); output_node_dims = tensor_info.GetShape(); - if (DEBUGPRINT) { - std::cout << " *** output_node_dims : " << i << " = " << output_node_dims.size() << std::endl; - } + dd4hep::printout(dd4hep::DEBUG, "ONNXInference::initialize", "output_node_dims : %i = %i", i, output_node_dims.size()); + /* + //if (DEBUGPRINT) { + // std::cout << " *** output_node_dims : " << i << " = " << output_node_dims.size() << std::endl; + //} + */ for (std::size_t j = 0; j < output_node_dims.size(); j++) { if (output_node_dims[j] < 0) { output_node_dims[j] = 1; } - if (DEBUGPRINT) { - std::cout << " - dim " << j << " : " << output_node_dims[j] << std::endl; - } + dd4hep::printout(dd4hep::DEBUG, "ONNXInference::initialize", "dim %i : %i", j, output_node_dims[j]); + /* + //if (DEBUGPRINT) { + // std::cout << " - dim " << j << " : " << output_node_dims[j] << std::endl; + //} + */ } } } diff --git a/src/Par04ExampleVAE.cc b/src/Par04ExampleVAE.cc index 5a6134c..f4fc5bd 100644 --- a/src/Par04ExampleVAE.cc +++ b/src/Par04ExampleVAE.cc @@ -21,11 +21,15 @@ void Par04ExampleVAE::prepareInput(G4FastTrack const& aFastTrack, G4ThreeVector // compute local incident angle double theta = acos(localDir.z()); - if (DEBUGPRINT) { - std::cout << " Par04ExampleVAE::prepareInput pos0 = " << position << " - dir = " << direction - << " - E = " << energy / CLHEP::GeV << " theta = " << theta * 180. / M_PI << std::endl; - } - + dd4hep::printout(dd4hep::DEBUG, "Par04ExampleVAE::prepareInput", "pos0 = (%f, %f, %f) - dir = (%f, %f, %f) - E = %f - theta = %f", + position.x(), position.y(), position.z(), direction.x(), direction.y(), direction.z(), + energy/ CLHEP::GeV, theta * 180. / M_PI); + /* + //if (DEBUGPRINT) { + // std::cout << " Par04ExampleVAE::prepareInput pos0 = " << position << " - dir = " << direction + // << " - E = " << energy / CLHEP::GeV << " theta = " << theta * 180. / M_PI << std::endl; + //} + */ // the input for this model is the latent space and the energy conditioning if (inputs.size() != 1) { diff --git a/src/PolyhedraBarrelGeometry.cc b/src/PolyhedraBarrelGeometry.cc index 1336e5e..91788d0 100644 --- a/src/PolyhedraBarrelGeometry.cc +++ b/src/PolyhedraBarrelGeometry.cc @@ -19,10 +19,16 @@ void PolyhedraBarrelGeometry::initialize() { if (cal) { for (auto l : cal->layers) { m_caloLayerDistances.push_back((l.distance + l.inner_thickness) / dd4hep::mm); - std::cout << " ECAL Layer distances " << l.distance + l.inner_thickness << std::endl; + dd4hep::printout(dd4hep::INFO, "PolyhedraBarrelGeometry::initialize", "ECAL Layer distances %f", l.distance + l.inner_thickness); + /*REMOVE! + //std::cout << " ECAL Layer distances " << l.distance + l.inner_thickness << std::endl; + */ } } else { - std::cout << " ###### error: detector " << m_detector << " not found !" << std::endl; + dd4hep::printout(dd4hep::ERROR, "PolyhedraBarrelGeometry::initialize", "Detector %s not found!", m_detector.c_str()); + /*REMOVE! + //std::cout << " ###### error: detector " << m_detector << " not found !" << std::endl; + */ } // For hadronic shower simulation @@ -32,10 +38,16 @@ void PolyhedraBarrelGeometry::initialize() { if (cal_had) { for (auto l_had : cal_had->layers) { m_caloLayerDistances.push_back((l_had.distance + l_had.inner_thickness) / dd4hep::mm); - std::cout << " HCAL Layer distances " << l_had.distance + l_had.inner_thickness << std::endl; + dd4hep::printout(dd4hep::INFO, "PolyhedraBarrelGeometry::initialize", "HCAL Layer distances %f", l_had.distance + l_had.inner_thickness); + /*REMOVE! + //std::cout << " HCAL Layer distances " << l_had.distance + l_had.inner_thickness << std::endl; + */ } } else { - std::cout << " ###### error: detector " << m_hadDetector << " not found !" << std::endl; + dd4hep::printout(dd4hep::ERROR, "PolyhedraBarrelGeometry::initialize", "Detector %s not found!", m_hadDetector.c_str()); + /*REMOVE! + //std::cout << " ###### error: detector " << m_hadDetector << " not found !" << std::endl; + */ } } } @@ -85,16 +97,23 @@ G4ThreeVector PolyhedraBarrelGeometry::localDirection(G4FastTrack const& aFastTr // the z-axis pointing into the calo G4ThreeVector localDir(-dirR.z(), dirR.y(), dirR.x()); - if (DEBUGPRINT) { - G4double energy = aFastTrack.GetPrimaryTrack()->GetKineticEnergy(); - - std::cout << " PolyhedraBarrelGeometry::localDirection - symmetry = " << m_nSymmetry << " pos0 = " << position - << " - dir = " << direction << " - E = " - << " - localDir = " << localDir << energy << std::endl; - std::cout << " PolyhedraBarrelGeometry::localDirection - phi = " - << atan2(localDir.y(), localDir.x()) / M_PI * 180. << " theta : " << acos(localDir.z()) / M_PI * 180. - << std::endl; + dd4hep::printout(dd4hep::DEBUG, "PolyhedraBarrelGeometry::localDirection", "symmetry = %i - pos0 = (%f, %f, %f) - dir = (%f, %f, %f) - E = %f - localDir = (%f, %f, %f)", + m_nSymmetry, position.x(), position.y(), position.z(), + direction.x(), direction.y(), direction.z(), aFastTrack.GetPrimaryTrack()->GetKineticEnergy(), localDir.x(), localDir.y(), localDir.z()); + dd4hep::printout(dd4hep::DEBUG, "PolyhedraBarrelGeometry::localDirection", "phi = %f - theta = %f", + atan2(localDir.y(), localDir.x()) / M_PI * 180., acos(localDir.z()) / M_PI * 180.); + /*REMOVE! + //if (DEBUGPRINT) { + // G4double energy = aFastTrack.GetPrimaryTrack()->GetKineticEnergy(); + + // std::cout << " PolyhedraBarrelGeometry::localDirection - symmetry = " << m_nSymmetry << " pos0 = " << position + // << " - dir = " << direction << " - E = " + // << " - localDir = " << localDir << energy << std::endl; + // std::cout << " PolyhedraBarrelGeometry::localDirection - phi = " + // << atan2(localDir.y(), localDir.x()) / M_PI * 180. << " theta : " << acos(localDir.z()) / M_PI * 180. + // << std::endl; } + */ return localDir; } @@ -106,12 +125,16 @@ void PolyhedraBarrelGeometry::localToGlobal(G4FastTrack const& aFastTrack, int phiSec = phiSector(position); - if (DEBUGPRINT) { - G4double energy = aFastTrack.GetPrimaryTrack()->GetKineticEnergy(); + dd4hep::printout(dd4hep::DEBUG, "PolyhedraBarrelGeometry::localToGlobal", "symmetry = %i - pos0= (%f, %f, %f) - dir = (%f, %f, %f) - E = %f", + m_nSymmetry, position.x(), position.y(), position.z(), direction.x(), direction.y(), direction.z(), aFastTrack.GetPrimaryTrack()->GetKineticEnergy()); + /*REMOVE! + //if (DEBUGPRINT) { + // G4double energy = aFastTrack.GetPrimaryTrack()->GetKineticEnergy(); - std::cout << " PolyhedraBarrelGeometry::localToGlobal - symmetry = " << m_nSymmetry << " pos0 = " << position - << " - dir = " << direction << " - E = " << energy << std::endl; - } + // std::cout << " PolyhedraBarrelGeometry::localToGlobal - symmetry = " << m_nSymmetry << " pos0 = " << position + // << " - dir = " << direction << " - E = " << energy << std::endl; + //} + */ // --- rotate position and direction to phi sector 0 (calo plane parallel to // y-axis at positive x ) @@ -129,17 +152,25 @@ void PolyhedraBarrelGeometry::localToGlobal(G4FastTrack const& aFastTrack, dirR = {1., 0., 0.}; // position layers w/ impact normal to the plane } - if (DEBUGPRINT) { - std::cout << " PolyhedraBarrelGeometry::localToGlobal - position " << position << " - direction " << direction - << " phiSec: " << phiSec << " posR " << posR << " dirR " << dirR << std::endl; - } + dd4hep::printout(dd4hep::DEBUG, "PolyhedraBarrelGeometry::localToGlobal", "pos0= (%f, %f, %f) - dir = (%f, %f, %f) - phiSec = %i - posR = (%f, %f, %f) - dirR = (%f, %f, %f)", + position.x(), position.y(), position.z(), direction.x(), direction.y(), direction.z(), + phiSec, posR.x(), posR.y(), posR.z(), dirR.x(), dirR.y(), dirR.z()); + /*REMOVE! + //if (DEBUGPRINT) { + // std::cout << " PolyhedraBarrelGeometry::localToGlobal - position " << position << " - direction " << direction + // << " phiSec: " << phiSec << " posR " << posR << " dirR " << dirR << std::endl; + //} + */ // find the first layer that will have signals as sometimes particles are // create in the calorimeter ! int firstLayer = 0; int nLayer = m_caloLayerDistances.size(); - std::cout << " PolyhedraBarrelGeometry::localToGlobal nLayer " << nLayer << std::endl; + dd4hep::printout(dd4hep::INFO, "PolyhedraBarrelGeometry::localToGlobal", "nLayer = %i", nLayer); + /*REMOVE! + //std::cout << " PolyhedraBarrelGeometry::localToGlobal nLayer " << nLayer << std::endl; + */ for (int l = 0; l < nLayer; ++l) { double r = m_caloLayerDistances[l]; @@ -185,8 +216,12 @@ void PolyhedraBarrelGeometry::localToGlobal(G4FastTrack const& aFastTrack, sp.Y = global.y(); sp.Z = global.z(); - std::cout << " PolyhedraBarrelGeometry::localToGlobal - global.x() = " << global.x() - << " global.y() = " << global.y() << " global.z() " << global.z() << " Energy: " << sp.E << std::endl; + dd4hep::printout(dd4hep::DEBUG, "PolyhedraBarrelGeometry::localToGlobal", "global.x() = %f, global.y() = %f, global.z() = %f", + global.x(), global.y(), global.z()); + /*REMOVE! + //std::cout << " PolyhedraBarrelGeometry::localToGlobal - global.x() = " << global.x() + // << " global.y() = " << global.y() << " global.z() " << global.z() << " Energy: " << sp.E << std::endl; + */ } } } diff --git a/src/RegularGridBIBAEModel.cc b/src/RegularGridBIBAEModel.cc index 13afc13..d05ed21 100644 --- a/src/RegularGridBIBAEModel.cc +++ b/src/RegularGridBIBAEModel.cc @@ -20,10 +20,15 @@ void RegularGridBIBAEModel::prepareInput(G4FastTrack const& aFastTrack, G4ThreeV // compute local incident angle double theta = acos(localDir.z()); - if (DEBUGPRINT) { - std::cout << " RegularGridBIBAEModel::prepareInput pos0 = " << position << " - dir = " << direction - << " - E = " << energy / CLHEP::GeV << " theta = " << theta << std::endl; - } + dd4hep::printout(dd4hep::DEBUG, "RegularGridBIBAEModel::prepareInput", "pos0 = (%f, %f, %f) - dir = (%f, %f, %f) - E = %f - theta = %f", + position.x(), position.y(), position.z(), direction.x(), direction.y(), direction.z(), + energy/ CLHEP::GeV, theta * 180. / M_PI); + /*REMOVE! + //if (DEBUGPRINT) { + // std::cout << " RegularGridBIBAEModel::prepareInput pos0 = " << position << " - dir = " << direction + // << " - E = " << energy / CLHEP::GeV << " theta = " << theta << std::endl; + //} + */ // the input for the BIB-AE is one energy and an angle (plus cond tensor) inputs.resize(m_latentSize); @@ -38,10 +43,12 @@ void RegularGridBIBAEModel::prepareInput(G4FastTrack const& aFastTrack, G4ThreeV inputs[2][0] = (inputs[0][0]) / 100.; inputs[2][1] = (inputs[1][0]) / (90. * (M_PI / 180.)); - if (DEBUGPRINT) { - std::cout << " Input_energy_tensor : " << inputs[0][0] * 100. << std::endl; - } - + dd4hep::printout(dd4hep::DEBUG, "RegularGridBIBAEModel::prepareInput", "Input_energy_tensor : %f", inputs[0][0] * 100.); + /*REMOVE! + //if (DEBUGPRINT) { + // std::cout << " Input_energy_tensor : " << inputs[0][0] * 100. << std::endl; + // } + */ // ---- resize output vector int outputSize = m_nCellsX * m_nCellsY * m_nCellsZ; diff --git a/src/RegularGridGANModel.cc b/src/RegularGridGANModel.cc index 5682868..827b7a0 100644 --- a/src/RegularGridGANModel.cc +++ b/src/RegularGridGANModel.cc @@ -22,10 +22,15 @@ void RegularGridGANModel::prepareInput(G4FastTrack const& aFastTrack, G4ThreeVec // conditioning variables, such as incident angles ... // for now assume simple GAN with 90 deg incident - if (DEBUGPRINT) { - std::cout << " RegularGridGANModel::prepareInput pos0 = " << position << " - dir = " << direction - << " - E = " << energy / CLHEP::GeV << std::endl; - } + dd4hep::printout(dd4hep::DEBUG, "RegularGridGANModel::prepareInput", "pos0 = (%f, %f, %f) - dir = (%f, %f, %f) - E = %f", + position.x(), position.y(), position.z(), direction.x(), direction.y(), direction.z(), + energy/ CLHEP::GeV); + /*REMOVE! + //if (DEBUGPRINT) { + // std::cout << " RegularGridGANModel::prepareInput pos0 = " << position << " - dir = " << direction + // << " - E = " << energy / CLHEP::GeV << std::endl; + //} + */ // the input for this model is the latent space and the energy conditioning diff --git a/src/RegularGridTwoAngleBIBAEModel.cc b/src/RegularGridTwoAngleBIBAEModel.cc index dcba618..455f19c 100644 --- a/src/RegularGridTwoAngleBIBAEModel.cc +++ b/src/RegularGridTwoAngleBIBAEModel.cc @@ -65,19 +65,29 @@ void RegularGridTwoAngleBIBAEModel::prepareInput(G4FastTrack const& aFastTrack, const auto [theta_cond, phi_cond] = getConditionAngles(localDir); - if (DEBUGPRINT) { - // compute local incident angles - double theta = acos(localDir.x()); - double phi = atan2(localDir.y(), localDir.x()); - - std::cout << " RegularGridTwoAngleBIBAEModel::prepareInput pos0 = " << position << " - dir = " << direction - << " - E = " << energy / CLHEP::GeV << " - local dir = " << localDir << " theta = " << theta - << " phi= " << phi << std::endl; - std::cout << " RegularGridTwoAngleBIBAEModel::prepareInput Cond, theta_cond = " << theta_cond << " / " - << theta_cond / M_PI * 180. << " phi_cond = " << phi_cond << " / " << phi_cond / M_PI * 180. - << " / Global phi " << direction.phi() << " / " << direction.phi() / M_PI * 180. << " / Global theta " - << direction.theta() << " / " << direction.theta() / M_PI * 180 << std::endl; + // compute local incident angles + double theta = acos(localDir.x()); + double phi = atan2(localDir.y(), localDir.x()); + dd4hep::printout(dd4hep::DEBUG, "RegularGridTwoAngleBIBAEModel::prepareInput", "pos0 = (%f, %f, %f) - dir = (%f, %f, %f) - E = %f - local dir =(%f, %f, %f) - theta = %f - phi=%f", + position.x(), position.y(), position.z(), direction.x(), direction.y(), direction.z(), + energy/ CLHEP::GeV, localDir.x(), localDir.y(), localDir.z(), theta, phi); + dd4hep::printout(dd4hep::DEBUG, "RegularGridTwoAngleBIBAEModel::prepareInput", "theta_cond = %f / %f - phi_cond = %f / %f - Global phi = %f / %f - Global theta = %f / %f", + theta_cond, theta_cond / M_PI * 180., phi_cond, phi_cond / M_PI * 180., direction.phi(), direction.phi() / M_PI * 180., direction.theta(), direction.theta() / M_PI * 180); + /*REMOVE! + //if (DEBUGPRINT) { + // // compute local incident angles + // double theta = acos(localDir.x()); + // double phi = atan2(localDir.y(), localDir.x()); + + // std::cout << " RegularGridTwoAngleBIBAEModel::prepareInput pos0 = " << position << " - dir = " << direction + // << " - E = " << energy / CLHEP::GeV << " - local dir = " << localDir << " theta = " << theta + // << " phi= " << phi << std::endl; + // std::cout << " RegularGridTwoAngleBIBAEModel::prepareInput Cond, theta_cond = " << theta_cond << " / " + // << theta_cond / M_PI * 180. << " phi_cond = " << phi_cond << " / " << phi_cond / M_PI * 180. + // << " / Global phi " << direction.phi() << " / " << direction.phi() / M_PI * 180. << " / Global theta " + // << direction.theta() << " / " << direction.theta() / M_PI * 180 << std::endl; } + */ // the input for the BIB-AE is one energy and two angles (plus cond tensor) inputs.resize(m_latentSize); @@ -95,14 +105,23 @@ void RegularGridTwoAngleBIBAEModel::prepareInput(G4FastTrack const& aFastTrack, inputs[3][1] = (inputs[1][0]) / (95. * (M_PI / 180.)); inputs[3][2] = (inputs[2][0]) / (95. * (M_PI / 180.)); - if (DEBUGPRINT) { - std::cout << " Input_energy_tensor : " << inputs[0][0] << std::endl; - std::cout << " Input_theta_tensor : " << inputs[1][0] << std::endl; - std::cout << " Input_phi_tensor : " << inputs[2][0] << std::endl; - std::cout << " Input_Flow_energy : " << inputs[3][0] << std::endl; - std::cout << " Input_Flow_theta : " << inputs[3][1] << std::endl; - std::cout << " Input_Flow_phi : " << inputs[3][2] << std::endl; - } + dd4hep::printout(dd4hep::DEBUG, "RegularGridTwoAngleBIBAEModel::prepareInput", "Input_energy_tensor : %f", inputs[0][0]); + dd4hep::printout(dd4hep::DEBUG, "RegularGridTwoAngleBIBAEModel::prepareInput", "Input_theta_tensor : %f", inputs[1][0]); + dd4hep::printout(dd4hep::DEBUG, "RegularGridTwoAngleBIBAEModel::prepareInput", "Input_phi_tensor : %f", inputs[2][0]); + dd4hep::printout(dd4hep::DEBUG, "RegularGridTwoAngleBIBAEModel::prepareInput", "Input_Flow_energy : %f", inputs[3][0]); + dd4hep::printout(dd4hep::DEBUG, "RegularGridTwoAngleBIBAEModel::prepareInput", "Input_Flow_theta : %f", inputs[3][1]); + dd4hep::printout(dd4hep::DEBUG, "RegularGridTwoAngleBIBAEModel::prepareInput", "Input_Flow_phi : %f", inputs[3][2]); + + /* + //if (DEBUGPRINT) { + // std::cout << " Input_energy_tensor : " << inputs[0][0] << std::endl; + // std::cout << " Input_theta_tensor : " << inputs[1][0] << std::endl; + // std::cout << " Input_phi_tensor : " << inputs[2][0] << std::endl; + // std::cout << " Input_Flow_energy : " << inputs[3][0] << std::endl; + // std::cout << " Input_Flow_theta : " << inputs[3][1] << std::endl; + // std::cout << " Input_Flow_phi : " << inputs[3][2] << std::endl; + //} + */ // ---- resize output vector @@ -232,11 +251,15 @@ std::vector RegularGridTwoAngleBIBAEModel::getIncidentCell(const double& double pos_X = intersect[0]; double pos_Y = intersect[2]; - if (DEBUGPRINT) { - std::cout << "X position of intersection: " << pos_X << std::endl; + dd4hep::printout(dd4hep::DEBUG,"RegularGridTwoAngleBIBAEModel::getIncidentCell", "X position of intersection: %f", pos_X); + dd4hep::printout(dd4hep::DEBUG,"RegularGridTwoAngleBIBAEModel::getIncidentCell", "Y position of intersection: %f", pos_Y); + /* + //if (DEBUGPRINT) { + // std::cout << "X position of intersection: " << pos_X << std::endl; - std::cout << "Y position of intersection: " << pos_Y << std::endl; - } + // std::cout << "Y position of intersection: " << pos_Y << std::endl; + //} + */ // equivalent of np.arange(-77, 78, 5.088333) std::vector binX; @@ -258,41 +281,57 @@ std::vector RegularGridTwoAngleBIBAEModel::getIncidentCell(const double& // binX.size() < binX.size()) { - if (DEBUGPRINT) { - std::cout << "RegularGridTwoAngleBIBAEModel::getIncidentCell incident " - "position not found in grid X!" - << std::endl; - } + dd4hep::printout(dd4hep::PrintLevel::WARNING,"RegularGridTwoAngleBIBAEModel::getIncidentCell", "Incident position not found in grid X!"); + /*REMOVE! + //if (DEBUGPRINT) { + // std::cout << "RegularGridTwoAngleBIBAEModel::getIncidentCell incident " + // "position not found in grid X!" + // << std::endl; + //} + */ } else if (binX[i] <= pos_X && pos_X < binX[i + 1]) { double frac = (pos_X - binX[i]) / 5.088333; if (frac < 0) { - std::cout << "RegularGridTwoAngleBIBAEModel::getIncidentCell incident " - "cell fraction wrong X!" - << std::endl; // has to be positive by construction! + dd4hep::printout(dd4hep::PrintLevel::WARNING,"RegularGridTwoAngleBIBAEModel::getIncidentCell", "Incident cell fraction wrong X!"); + /*REMOVE! + //std::cout << "RegularGridTwoAngleBIBAEModel::getIncidentCell incident " + // "cell fraction wrong X!" + // << std::endl; // has to be positive by construction! + */ } + /*REMOVE! // std::cout << "RegularGridTwoAngleBIBAEModel::getIncidentCell frac " << // frac << std::endl; + */ gridX = static_cast(i) + frac; - if (DEBUGPRINT) { - std::cout << "RegularGridTwoAngleBIBAEModel::getIncidentCell gridX " << gridX << std::endl; - } + dd4hep::printout(dd4hep::DEBUG,"RegularGridTwoAngleBIBAEModel::getIncidentCell", "gridX = %f", gridX); + /*REMOVE! + //if (DEBUGPRINT) { + // std::cout << "RegularGridTwoAngleBIBAEModel::getIncidentCell gridX " << gridX << std::endl; + //} + */ i = binX.size(); // break; + /*REMOVE // std::cout << "RegularGridTwoAngleBIBAEModel::getIncidentCell // break"< RegularGridTwoAngleBIBAEModel::getIncidentCell(const double& // Y for (size_t j = 0; j < binY.size(); ++j) { - if (DEBUGPRINT) { - std::cout << "RegularGridTwoAngleBIBAEModel::getIncidentCell binY[j]: " << binY[j] << " binY[j+1]: " - << " j: " << j << std::endl; - } + dd4hep::printout(dd4hep::DEBUG, "RegularGridTwoAngleBIBAEModel::getIncidentCell", "binY[j] = %f - binY[j+1] = %f - j = %i", + binY[j], binY[j+1], j); + /*REMOVE! + //if (DEBUGPRINT) { + // std::cout << "RegularGridTwoAngleBIBAEModel::getIncidentCell binY[j]: " << binY[j] << " binY[j+1]: " + // << " j: " << j << std::endl; + //} + */ if (j + 1 > binY.size()) { - if (DEBUGPRINT) { - std::cout << "RegularGridTwoAngleBIBAEModel::getIncidentCell incident " - "position not found in grid Y!" - << std::endl; - } + dd4hep::printout(dd4hep::PrintLevel::WARNING, "RegularGridTwoAngleBIBAEModel::getIncidentCell", "Incident position not found in grid Y!"); + /*REMOVE! + //if (DEBUGPRINT) { + // std::cout << "RegularGridTwoAngleBIBAEModel::getIncidentCell incident " + // "position not found in grid Y!" + // << std::endl; + //} + */ } @@ -318,16 +364,22 @@ std::vector RegularGridTwoAngleBIBAEModel::getIncidentCell(const double& double frac = (pos_Y - binY[j]) / 5.088333; if (frac < 0) { - std::cout << "RegularGridTwoAngleBIBAEModel::getIncidentCell incident " - "cell fraction wrong Y!" - << std::endl; // has to be positive by construction! + dd4hep::printout(dd4hep::PrintLevel::WARNING, "RegularGridTwoAngleBIBAEModel::getIncidentCell", "Incident cell fraction wrong Y!"); + /*REMOVE! + //std::cout << "RegularGridTwoAngleBIBAEModel::getIncidentCell incident " + // "cell fraction wrong Y!" + // << std::endl; // has to be positive by construction! + */ } gridY = static_cast(j) + frac; - if (DEBUGPRINT) { - std::cout << "RegularGridTwoAngleBIBAEModel::getIncidentCell gridY " << gridY << std::endl; - } + dd4hep::printout(dd4hep::DEBUG, "RegularGridTwoAngleBIBAEModel::getIncidentCell", "gridY: %f", gridY); + /*REMOVE! + //if (DEBUGPRINT) { + // std::cout << "RegularGridTwoAngleBIBAEModel::getIncidentCell gridY " << gridY << std::endl; + //} + */ j = binY.size(); // break; } @@ -338,7 +390,10 @@ std::vector RegularGridTwoAngleBIBAEModel::getIncidentCell(const double& grid_incident_point.push_back(gridX); grid_incident_point.push_back(gridY); - std::cout << "Done incident pos func " << std::endl; + dd4hep::printout(dd4hep::INFO, "RegularGridTwoAngleBIBAEModel::getIncidentCell", "Done incident pos func"); + /*REMOVE! + //std::cout << "Done incident pos func " << std::endl; + */ return grid_incident_point; } diff --git a/src/TorchInference.cc b/src/TorchInference.cc index ef0ea94..fd26295 100644 --- a/src/TorchInference.cc +++ b/src/TorchInference.cc @@ -45,24 +45,41 @@ void TorchInference::runInference(const InputVecs& inputs, const TensorDimVecs& m_isInitialized = true; } - if (DEBUGPRINT) { - std::cout << " ----- TorchInference::runInference \n" - << " # inputs = " << inputs.size() << " : "; + if (dd4hep::printLevel() <= dd4hep::DEBUG){ + dd4hep::printout(dd4hep::DEBUG, "TorchInference::runInference", " ----- TorchInference::runInference -----"); + dd4hep::printout(dd4hep::DEBUG, "TorchInference::runInference", "# inputs = %f : ", inputs.size() ); for (auto iv : inputs) { - std::cout << " " << iv.size() << ", "; + dd4hep::printout(dd4hep::DEBUG, "TorchInference::runInference", "%f, ", iv.size()); } - std::cout << std::endl; - - std::cout << " # dims = " << tensDims.size() << " : "; - + dd4hep::printout(dd4hep::DEBUG, "TorchInference::runInference", "# dims = %f :", tensDims.size()); + for (auto iv : tensDims) { - std::cout << " " << iv.size() << ", "; + dd4hep::printout(dd4hep::DEBUG, "TorchInference::runInference", "%f, ", iv.size()); } - - std::cout << std::endl; + } + /*REMOVE! + //if (DEBUGPRINT) { + // std::cout << " ----- TorchInference::runInference \n" + // << " # inputs = " << inputs.size() << " : "; + + // for (auto iv : inputs) { + // std::cout << " " << iv.size() << ", "; + // } + + // std::cout << std::endl; + + // std::cout << " # dims = " << tensDims.size() << " : "; + + // for (auto iv : tensDims) { + // std::cout << " " << iv.size() << ", "; + // } + + // std::cout << std::endl; + //} + */ assert(inputs.size() == tensDims.size()); @@ -72,16 +89,22 @@ void TorchInference::runInference(const InputVecs& inputs, const TensorDimVecs& torch::Tensor inTens = torch::tensor(inputs[i], m_options).view(tensDims[i]); tensors.emplace_back(inTens); - if (DEBUGPRINT) { - std::cout << " inTensor " << i << " : " << inTens << std::endl; - } + dd4hep::printout(dd4hep::DEBUG, "TorchInference::runInference", "inTensor %i: %f", i, inTens); + /*REMOVE + //if (DEBUGPRINT) { + // std::cout << " inTensor " << i << " : " << inTens << std::endl; + //} + */ } at::Tensor outTensor = m_jitModule.forward(tensors).toTensor(); //.contiguous(); - if (DEBUGPRINT) { - std::cout << " outTensor : " << outTensor << std::endl; - } + dd4hep::printout(dd4hep::DEBUG, "TorchInference::runInference", "outTensor : %f", outTensor); + /*REMOVE + //if (DEBUGPRINT) { + // std::cout << " outTensor : " << outTensor << std::endl; + //} + */ // torch.flatten(outTensor); // std::cout << "**" << outTensor << std::endl; From 076a0a040a56c6f8ea0497eb77a6a47e16bc80c0 Mon Sep 17 00:00:00 2001 From: Peter McKeown Date: Mon, 24 Nov 2025 17:49:59 +0100 Subject: [PATCH 31/36] Ensure that simulation still works for just em shower simulation --- include/DDML/PolyhedraBarrelGeometry.h | 2 +- scripts/ddsim_steer.py | 14 +++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/include/DDML/PolyhedraBarrelGeometry.h b/include/DDML/PolyhedraBarrelGeometry.h index 46b9cbc..d2eade0 100644 --- a/include/DDML/PolyhedraBarrelGeometry.h +++ b/include/DDML/PolyhedraBarrelGeometry.h @@ -60,7 +60,7 @@ class PolyhedraBarrelGeometry : public GeometryInterface { std::string m_detector = {"EcalBarrel"}; int m_nSymmetry = 8; bool m_correctForAngles = false; - bool m_isHadShower = true; + bool m_isHadShower; //= true; std::string m_hadDetector = {"HcalBarrel"}; int m_nHadSymmetry = m_nSymmetry; }; diff --git a/scripts/ddsim_steer.py b/scripts/ddsim_steer.py index 287d3f7..55fa286 100644 --- a/scripts/ddsim_steer.py +++ b/scripts/ddsim_steer.py @@ -394,16 +394,27 @@ def aiDanceTorch(kernel): CaloClouds = True L2LFlows = False old_DD4hep = False ## use for DD4hep versions/commits before ~ Apr 21st 2023 + hadrons=False if ild == True: ml_barrel_name = "EcalBarrel" ml_barrel_symmetry = 8 ml_endcap_name = "EcalEndcap" + + ## For hadron shower fast simulation + ml_had_barrel_name = "HcalBarrel" + ml_had_barrel_symmetry = 8 + ml_had_endcap_name = "HcalEndcap" else: ml_barrel_name = "ECalBarrel" ml_barrel_symmetry = 12 ml_endcap_name = "ECalEndcap" + ## For hadron shower fast simulation is needed + ml_had_barrel_name = "HCalBarrel" + ml_had_barrel_symmetry = 12 + ml_had_endcap_name = "HCalEndcap" + if BIBAE == True and Two_Angle == False: ml_file = "../models/BIBAE_Full_PP_cut.pt" ml_model = "RegularGridBIBAEPolyhedraBarrelTorchModel/BarrelModelTorch" @@ -459,6 +470,7 @@ def aiDanceTorch(kernel): model = DetectorConstruction(kernel, str(ml_model)) ## # Mandatory model parameters + model.isHadShower = False model.RegionName = "EcalBarrelRegion" model.Detector = ml_barrel_name model.Symmetry = ml_barrel_symmetry @@ -660,4 +672,4 @@ def LoadHdf5(kernel): # SIM.physics.setupUserPhysics( aiDance) SIM.physics.setupUserPhysics(aiDanceTorch) -# SIM.physics.setupUserPhysics(LoadHdf5) +#SIM.physics.setupUserPhysics(LoadHdf5) From 8bf4c0a55867f4e99caf38e1aceffde7b16e4818 Mon Sep 17 00:00:00 2001 From: Peter McKeown Date: Tue, 25 Nov 2025 11:05:46 +0100 Subject: [PATCH 32/36] Remove debug/warning cout printouts and use only dd4hep printout --- src/CaloCloudsTwoAngleModel.cc | 8 --- src/EndcapGeometry.cc | 18 ------- src/Geant4FastHitMakerGlobal.cc | 14 +++--- src/ONNXInference.cc | 33 ++----------- src/RegularGridBIBAEModel.cc | 12 +---- src/RegularGridGANModel.cc | 6 --- src/RegularGridTwoAngleBIBAEModel.cc | 74 ---------------------------- src/TorchInference.cc | 31 +----------- 8 files changed, 11 insertions(+), 185 deletions(-) diff --git a/src/CaloCloudsTwoAngleModel.cc b/src/CaloCloudsTwoAngleModel.cc index 4e18ae6..28c9f76 100644 --- a/src/CaloCloudsTwoAngleModel.cc +++ b/src/CaloCloudsTwoAngleModel.cc @@ -28,8 +28,6 @@ void CaloCloudsTwoAngleModel::prepareInput(G4FastTrack const& aFastTrack, G4Thre dd4hep::printout(dd4hep::DEBUG, "CaloCloudsTwoAngleModel::prepareInput", "DDML::localDir: (%f, %f, %f)", localDir_.x(), localDir_.y(), localDir_.z()); - // std::cout << "CaloClouds::localDir:" << "(" << localDir_.x() << "," << localDir_.y() << "," << localDir_.z() << ")" - // << std::endl; // compute local incident angles double r = sqrt(localDir_.x() * localDir_.x() + localDir_.y() * localDir_.y() + localDir_.z() * localDir_.z()); @@ -37,7 +35,6 @@ void CaloCloudsTwoAngleModel::prepareInput(G4FastTrack const& aFastTrack, G4Thre double phi = atan2(localDir_.y(), localDir_.x()) / M_PI * 180.; dd4hep::printout(dd4hep::DEBUG, "CaloCloudsTwoAngleModel::prepareInput", "DDML::localDir: (%f, %f)", theta, phi); - // std::cout << "CaloClouds::localDir:" << " theta = " << theta << " phi = " << phi << std::endl; // the input for the CaloCLouds is one energy and two angles (local Theta and Phi) inputs.resize(m_latentSize); @@ -51,11 +48,6 @@ void CaloCloudsTwoAngleModel::prepareInput(G4FastTrack const& aFastTrack, G4Thre inputs[1][0] = theta; // 89.*(M_PI/180.) ; //Theta_vec[0]/(90.*(M_PI/180.)); inputs[2][0] = phi; - // if (DEBUGPRINT) { - // std::cout << " Input_energy_tensor : " << inputs[0][0] << std::endl; - // std::cout << " Input_theta_tensor : " << inputs[1][0] << std::endl; - // std::cout << " Input_phi_tensor : " << inputs[2][0] << std::endl; - // } dd4hep::printout(dd4hep::DEBUG, "CaloCloudsTwoAngleModel::prepareInput", "Input_energy_tensor : %f", inputs[0][0]); dd4hep::printout(dd4hep::DEBUG, "CaloCloudsTwoAngleModel::prepareInput", "Input_theta_tensor : %f", inputs[1][0]); diff --git a/src/EndcapGeometry.cc b/src/EndcapGeometry.cc index 021f388..508685a 100644 --- a/src/EndcapGeometry.cc +++ b/src/EndcapGeometry.cc @@ -23,9 +23,6 @@ void EndcapGeometry::initialize() { } else { dd4hep::printout(dd4hep::ERROR, "EndcapGeometry::initialize", "Detector %s not found!", m_detector.c_str()); - /* REMOVE! - //std::cout << " ###### error: detector " << m_detector << " not found !" << std::endl; - */ } } @@ -46,15 +43,6 @@ G4ThreeVector EndcapGeometry::localDirection(G4FastTrack const& aFastTrack) cons dd4hep::printout(dd4hep::DEBUG, "EndcapGeometry::localDirection", "pos0 = (%f, %f, %f) - dir = (%f, %f, %f) - E = %f" , position.x(), position.y(), position.z(), direction.x(), direction.y(), direction.z(), aFastTrack.GetPrimaryTrack()->GetKineticEnergy()); - /* REMOVE! - //if (DEBUGPRINT) { - // G4double energy = aFastTrack.GetPrimaryTrack()->GetKineticEnergy(); - - // std::cout << " EndcapGeometry::localDirection " - // << " pos0 = " << position << " - dir = " << direction << " - E = " - // << " - localDir = " << localDir << energy << std::endl; - //} - */ return localDir; } @@ -67,12 +55,6 @@ void EndcapGeometry::localToGlobal(G4FastTrack const& aFastTrack, std::vector + Geant4FastHitMakerGlobal::Geant4FastHitMakerGlobal() { m_touchableHandle = new G4TouchableHistory(); m_navigator = new G4Navigator(); @@ -78,18 +80,14 @@ void Geant4FastHitMakerGlobal::make(const G4FastHit& aHit, const G4FastTrack& aT G4VSensitiveDetector* sensitive; if (currentVolume != 0) { // In full sim sensitive detector - //dd4hep::printout(dd4hep::DEBUG, "Geant4FastHitMakerGlobal::make", "In full sim sensitive: aHit.GetPosition() x: %f, y: %f, z: %f ", - // aHit.GetPosition().x(), aHit.GetPosition().y(), aHit.GetPosition().z()); - G4debug << "DEBUG - Geant4FastHitMakerGlobal::make- In full sim sensitive: aHit.GetPosition() x: " << aHit.GetPosition().x() << " y: " << - aHit.GetPosition().y() << " z: " << aHit.GetPosition().z() << G4endl; + dd4hep::printout(dd4hep::DEBUG, "Geant4FastHitMakerGlobal::make", "In full sim sensitive: aHit.GetPosition() x: %f, y: %f, z: %f ", + aHit.GetPosition().x(), aHit.GetPosition().y(), aHit.GetPosition().z()); sensitive = currentVolume->GetLogicalVolume()->GetSensitiveDetector(); G4VFastSimSensitiveDetector* fastSimSensitive = dynamic_cast(sensitive); if (fastSimSensitive) { // In fast sim sensitive detector - //dd4hep::printout(dd4hep::DEBUG, "Geant4FastHitMakerGlobal::make", "In fast sim sensitive: aHit.GetPosition() x: %f, y: %f, z: %f ", - // aHit.GetPosition().x(), aHit.GetPosition().y(), aHit.GetPosition().z()); - G4debug << "DEBUG - Geant4FastHitMakerGlobal::make- In fast sim sensitive: aHit.GetPosition() x: " << aHit.GetPosition().x() << " y: " << - aHit.GetPosition().y() << " z: " << aHit.GetPosition().z() << G4endl; + dd4hep::printout(dd4hep::DEBUG, "Geant4FastHitMakerGlobal::make", "In fast sim sensitive: aHit.GetPosition() x: %f, y: %f, z: %f ", + aHit.GetPosition().x(), aHit.GetPosition().y(), aHit.GetPosition().z()); fastSimSensitive->Hit(&aHit, &aTrack, &m_touchableHandle); } else if (sensitive && currentVolume->GetLogicalVolume()->GetFastSimulationManager()) { G4cerr << "ERROR - Geant4FastHitMakerGlobal::make()" << G4endl << " It is required to derive from the " diff --git a/src/ONNXInference.cc b/src/ONNXInference.cc index 040e3ed..093bdb3 100644 --- a/src/ONNXInference.cc +++ b/src/ONNXInference.cc @@ -61,32 +61,18 @@ void ONNXInference::initialize() { const auto input_name = m_session->GetInputNameAllocated(i, allocator).release(); #endif dd4hep::printout(dd4hep::DEBUG, "ONNXInference::initialize", "input_name : %i = %c", i, input_name); - /* REMOVE! - //if (DEBUGPRINT) { - // std::cout << " *** input_name : " << i << " = " << input_name << std::endl; - //} - */ m_inNames.push_back(input_name); input_node_names[i] = input_name; Ort::TypeInfo type_info = m_session->GetInputTypeInfo(i); auto tensor_info = type_info.GetTensorTypeAndShapeInfo(); input_node_dims = tensor_info.GetShape(); dd4hep::printout(dd4hep::DEBUG, "ONNXInference::initialize", "input_node_dims : %i = %i", i, input_node_dims.size()); - /* REMOVE! - //if (DEBUGPRINT) { - // std::cout << " *** input_node_dims : " << i << " = " << input_node_dims.size() << std::endl; - //} - */ + for (std::size_t j = 0; j < input_node_dims.size(); j++) { if (input_node_dims[j] < 0) { input_node_dims[j] = 1; } dd4hep::printout(dd4hep::DEBUG, "ONNXInference::initialize", "dim %i : %i",j, input_node_dims[j] ); - /* - //if (DEBUGPRINT) { - // std::cout << " - dim " << j << " : " << input_node_dims[j] << std::endl; - } - */ } } // output nodes @@ -102,30 +88,17 @@ void ONNXInference::initialize() { m_outNames.push_back(output_name); output_node_names[i] = output_name; dd4hep::printout(dd4hep::DEBUG, "ONNXInference::initialize", "output_name: %i = %c", i, output_name); - /* - //if (DEBUGPRINT) { - // std::cout << " *** output_name : " << i << " = " << output_name << std::endl; - //} - */ + Ort::TypeInfo type_info = m_session->GetOutputTypeInfo(i); auto tensor_info = type_info.GetTensorTypeAndShapeInfo(); output_node_dims = tensor_info.GetShape(); dd4hep::printout(dd4hep::DEBUG, "ONNXInference::initialize", "output_node_dims : %i = %i", i, output_node_dims.size()); - /* - //if (DEBUGPRINT) { - // std::cout << " *** output_node_dims : " << i << " = " << output_node_dims.size() << std::endl; - //} - */ + for (std::size_t j = 0; j < output_node_dims.size(); j++) { if (output_node_dims[j] < 0) { output_node_dims[j] = 1; } dd4hep::printout(dd4hep::DEBUG, "ONNXInference::initialize", "dim %i : %i", j, output_node_dims[j]); - /* - //if (DEBUGPRINT) { - // std::cout << " - dim " << j << " : " << output_node_dims[j] << std::endl; - //} - */ } } } diff --git a/src/RegularGridBIBAEModel.cc b/src/RegularGridBIBAEModel.cc index d05ed21..291bfc3 100644 --- a/src/RegularGridBIBAEModel.cc +++ b/src/RegularGridBIBAEModel.cc @@ -23,12 +23,6 @@ void RegularGridBIBAEModel::prepareInput(G4FastTrack const& aFastTrack, G4ThreeV dd4hep::printout(dd4hep::DEBUG, "RegularGridBIBAEModel::prepareInput", "pos0 = (%f, %f, %f) - dir = (%f, %f, %f) - E = %f - theta = %f", position.x(), position.y(), position.z(), direction.x(), direction.y(), direction.z(), energy/ CLHEP::GeV, theta * 180. / M_PI); - /*REMOVE! - //if (DEBUGPRINT) { - // std::cout << " RegularGridBIBAEModel::prepareInput pos0 = " << position << " - dir = " << direction - // << " - E = " << energy / CLHEP::GeV << " theta = " << theta << std::endl; - //} - */ // the input for the BIB-AE is one energy and an angle (plus cond tensor) inputs.resize(m_latentSize); @@ -44,11 +38,7 @@ void RegularGridBIBAEModel::prepareInput(G4FastTrack const& aFastTrack, G4ThreeV inputs[2][1] = (inputs[1][0]) / (90. * (M_PI / 180.)); dd4hep::printout(dd4hep::DEBUG, "RegularGridBIBAEModel::prepareInput", "Input_energy_tensor : %f", inputs[0][0] * 100.); - /*REMOVE! - //if (DEBUGPRINT) { - // std::cout << " Input_energy_tensor : " << inputs[0][0] * 100. << std::endl; - // } - */ + // ---- resize output vector int outputSize = m_nCellsX * m_nCellsY * m_nCellsZ; diff --git a/src/RegularGridGANModel.cc b/src/RegularGridGANModel.cc index 827b7a0..c3b8e15 100644 --- a/src/RegularGridGANModel.cc +++ b/src/RegularGridGANModel.cc @@ -25,12 +25,6 @@ void RegularGridGANModel::prepareInput(G4FastTrack const& aFastTrack, G4ThreeVec dd4hep::printout(dd4hep::DEBUG, "RegularGridGANModel::prepareInput", "pos0 = (%f, %f, %f) - dir = (%f, %f, %f) - E = %f", position.x(), position.y(), position.z(), direction.x(), direction.y(), direction.z(), energy/ CLHEP::GeV); - /*REMOVE! - //if (DEBUGPRINT) { - // std::cout << " RegularGridGANModel::prepareInput pos0 = " << position << " - dir = " << direction - // << " - E = " << energy / CLHEP::GeV << std::endl; - //} - */ // the input for this model is the latent space and the energy conditioning diff --git a/src/RegularGridTwoAngleBIBAEModel.cc b/src/RegularGridTwoAngleBIBAEModel.cc index 455f19c..b236909 100644 --- a/src/RegularGridTwoAngleBIBAEModel.cc +++ b/src/RegularGridTwoAngleBIBAEModel.cc @@ -73,21 +73,6 @@ void RegularGridTwoAngleBIBAEModel::prepareInput(G4FastTrack const& aFastTrack, energy/ CLHEP::GeV, localDir.x(), localDir.y(), localDir.z(), theta, phi); dd4hep::printout(dd4hep::DEBUG, "RegularGridTwoAngleBIBAEModel::prepareInput", "theta_cond = %f / %f - phi_cond = %f / %f - Global phi = %f / %f - Global theta = %f / %f", theta_cond, theta_cond / M_PI * 180., phi_cond, phi_cond / M_PI * 180., direction.phi(), direction.phi() / M_PI * 180., direction.theta(), direction.theta() / M_PI * 180); - /*REMOVE! - //if (DEBUGPRINT) { - // // compute local incident angles - // double theta = acos(localDir.x()); - // double phi = atan2(localDir.y(), localDir.x()); - - // std::cout << " RegularGridTwoAngleBIBAEModel::prepareInput pos0 = " << position << " - dir = " << direction - // << " - E = " << energy / CLHEP::GeV << " - local dir = " << localDir << " theta = " << theta - // << " phi= " << phi << std::endl; - // std::cout << " RegularGridTwoAngleBIBAEModel::prepareInput Cond, theta_cond = " << theta_cond << " / " - // << theta_cond / M_PI * 180. << " phi_cond = " << phi_cond << " / " << phi_cond / M_PI * 180. - // << " / Global phi " << direction.phi() << " / " << direction.phi() / M_PI * 180. << " / Global theta " - // << direction.theta() << " / " << direction.theta() / M_PI * 180 << std::endl; - } - */ // the input for the BIB-AE is one energy and two angles (plus cond tensor) inputs.resize(m_latentSize); @@ -282,22 +267,9 @@ std::vector RegularGridTwoAngleBIBAEModel::getIncidentCell(const double& for (size_t i = 0; i < binX.size(); ++i) { dd4hep::printout(dd4hep::DEBUG,"RegularGridTwoAngleBIBAEModel::getIncidentCell", "binX[i]: %f - binX[i+1]: %f - i: %i", binX[i], binX[i+1], i); - /*REMOVE! - //if (DEBUGPRINT) { - // std::cout << "RegularGridTwoAngleBIBAEModel::getIncidentCell binX[i]: " << binX[i] << " binX[i+1]: " - // << " i: " << i << std::endl; - //} - */ if (i + 1 > binX.size()) { dd4hep::printout(dd4hep::PrintLevel::WARNING,"RegularGridTwoAngleBIBAEModel::getIncidentCell", "Incident position not found in grid X!"); - /*REMOVE! - //if (DEBUGPRINT) { - // std::cout << "RegularGridTwoAngleBIBAEModel::getIncidentCell incident " - // "position not found in grid X!" - // << std::endl; - //} - */ } else if (binX[i] <= pos_X && pos_X < binX[i + 1]) { @@ -305,33 +277,14 @@ std::vector RegularGridTwoAngleBIBAEModel::getIncidentCell(const double& if (frac < 0) { dd4hep::printout(dd4hep::PrintLevel::WARNING,"RegularGridTwoAngleBIBAEModel::getIncidentCell", "Incident cell fraction wrong X!"); - /*REMOVE! - //std::cout << "RegularGridTwoAngleBIBAEModel::getIncidentCell incident " - // "cell fraction wrong X!" - // << std::endl; // has to be positive by construction! - */ } - /*REMOVE! - // std::cout << "RegularGridTwoAngleBIBAEModel::getIncidentCell frac " << - // frac << std::endl; - */ - gridX = static_cast(i) + frac; dd4hep::printout(dd4hep::DEBUG,"RegularGridTwoAngleBIBAEModel::getIncidentCell", "gridX = %f", gridX); - /*REMOVE! - //if (DEBUGPRINT) { - // std::cout << "RegularGridTwoAngleBIBAEModel::getIncidentCell gridX " << gridX << std::endl; - //} - */ i = binX.size(); // break; - /*REMOVE - // std::cout << "RegularGridTwoAngleBIBAEModel::getIncidentCell - // break"< RegularGridTwoAngleBIBAEModel::getIncidentCell(const double& for (size_t j = 0; j < binY.size(); ++j) { dd4hep::printout(dd4hep::DEBUG, "RegularGridTwoAngleBIBAEModel::getIncidentCell", "binY[j] = %f - binY[j+1] = %f - j = %i", binY[j], binY[j+1], j); - /*REMOVE! - //if (DEBUGPRINT) { - // std::cout << "RegularGridTwoAngleBIBAEModel::getIncidentCell binY[j]: " << binY[j] << " binY[j+1]: " - // << " j: " << j << std::endl; - //} - */ if (j + 1 > binY.size()) { dd4hep::printout(dd4hep::PrintLevel::WARNING, "RegularGridTwoAngleBIBAEModel::getIncidentCell", "Incident position not found in grid Y!"); - /*REMOVE! - //if (DEBUGPRINT) { - // std::cout << "RegularGridTwoAngleBIBAEModel::getIncidentCell incident " - // "position not found in grid Y!" - // << std::endl; - //} - */ - } else if (binY[j] <= pos_Y && pos_Y < binY[j + 1]) { @@ -365,21 +304,11 @@ std::vector RegularGridTwoAngleBIBAEModel::getIncidentCell(const double& if (frac < 0) { dd4hep::printout(dd4hep::PrintLevel::WARNING, "RegularGridTwoAngleBIBAEModel::getIncidentCell", "Incident cell fraction wrong Y!"); - /*REMOVE! - //std::cout << "RegularGridTwoAngleBIBAEModel::getIncidentCell incident " - // "cell fraction wrong Y!" - // << std::endl; // has to be positive by construction! - */ } gridY = static_cast(j) + frac; dd4hep::printout(dd4hep::DEBUG, "RegularGridTwoAngleBIBAEModel::getIncidentCell", "gridY: %f", gridY); - /*REMOVE! - //if (DEBUGPRINT) { - // std::cout << "RegularGridTwoAngleBIBAEModel::getIncidentCell gridY " << gridY << std::endl; - //} - */ j = binY.size(); // break; } @@ -391,9 +320,6 @@ std::vector RegularGridTwoAngleBIBAEModel::getIncidentCell(const double& grid_incident_point.push_back(gridY); dd4hep::printout(dd4hep::INFO, "RegularGridTwoAngleBIBAEModel::getIncidentCell", "Done incident pos func"); - /*REMOVE! - //std::cout << "Done incident pos func " << std::endl; - */ return grid_incident_point; } diff --git a/src/TorchInference.cc b/src/TorchInference.cc index fd26295..81b196d 100644 --- a/src/TorchInference.cc +++ b/src/TorchInference.cc @@ -60,26 +60,6 @@ void TorchInference::runInference(const InputVecs& inputs, const TensorDimVecs& } } - /*REMOVE! - //if (DEBUGPRINT) { - // std::cout << " ----- TorchInference::runInference \n" - // << " # inputs = " << inputs.size() << " : "; - - // for (auto iv : inputs) { - // std::cout << " " << iv.size() << ", "; - // } - - // std::cout << std::endl; - - // std::cout << " # dims = " << tensDims.size() << " : "; - - // for (auto iv : tensDims) { - // std::cout << " " << iv.size() << ", "; - // } - - // std::cout << std::endl; - //} - */ assert(inputs.size() == tensDims.size()); @@ -90,21 +70,12 @@ void TorchInference::runInference(const InputVecs& inputs, const TensorDimVecs& tensors.emplace_back(inTens); dd4hep::printout(dd4hep::DEBUG, "TorchInference::runInference", "inTensor %i: %f", i, inTens); - /*REMOVE - //if (DEBUGPRINT) { - // std::cout << " inTensor " << i << " : " << inTens << std::endl; - //} - */ + } at::Tensor outTensor = m_jitModule.forward(tensors).toTensor(); //.contiguous(); dd4hep::printout(dd4hep::DEBUG, "TorchInference::runInference", "outTensor : %f", outTensor); - /*REMOVE - //if (DEBUGPRINT) { - // std::cout << " outTensor : " << outTensor << std::endl; - //} - */ // torch.flatten(outTensor); // std::cout << "**" << outTensor << std::endl; From e7e74ccf71347cfdeebd336a9a07f314f396f317 Mon Sep 17 00:00:00 2001 From: Peter McKeown Date: Tue, 25 Nov 2025 11:12:33 +0100 Subject: [PATCH 33/36] format files for pre-commit --- include/DDML/PionCloudsModel.h | 2 -- src/CaloCloudsTwoAngleModel.cc | 1 - src/EndcapGeometry.cc | 9 ++--- src/Geant4FastHitMakerGlobal.cc | 16 ++++----- src/LoadHdf5.cc | 33 +++++++++--------- src/ONNXInference.cc | 10 +++--- src/Par04ExampleVAE.cc | 6 ++-- src/PionCloudsModel.cc | 24 ++++++------- src/PolyhedraBarrelGeometry.cc | 45 +++++++++++++++---------- src/RegularGridBIBAEModel.cc | 9 ++--- src/RegularGridGANModel.cc | 6 ++-- src/RegularGridTwoAngleBIBAEModel.cc | 50 +++++++++++++++++----------- src/TorchInference.cc | 8 ++--- 13 files changed, 118 insertions(+), 101 deletions(-) diff --git a/include/DDML/PionCloudsModel.h b/include/DDML/PionCloudsModel.h index d92068c..2b75731 100644 --- a/include/DDML/PionCloudsModel.h +++ b/include/DDML/PionCloudsModel.h @@ -50,8 +50,6 @@ class PionCloudsModel : public ModelInterface { int m_maxNumElements = m_numPoints * 4; // number of space points in the output multiplied by 4 (x,y,z,energy) int m_nLayer = 78; - - TensorDimVecs m_tensDims = {{1, 1}, {1, 1}, {1, 1}, {1, 3}}; }; diff --git a/src/CaloCloudsTwoAngleModel.cc b/src/CaloCloudsTwoAngleModel.cc index 28c9f76..a29110f 100644 --- a/src/CaloCloudsTwoAngleModel.cc +++ b/src/CaloCloudsTwoAngleModel.cc @@ -48,7 +48,6 @@ void CaloCloudsTwoAngleModel::prepareInput(G4FastTrack const& aFastTrack, G4Thre inputs[1][0] = theta; // 89.*(M_PI/180.) ; //Theta_vec[0]/(90.*(M_PI/180.)); inputs[2][0] = phi; - dd4hep::printout(dd4hep::DEBUG, "CaloCloudsTwoAngleModel::prepareInput", "Input_energy_tensor : %f", inputs[0][0]); dd4hep::printout(dd4hep::DEBUG, "CaloCloudsTwoAngleModel::prepareInput", "Input_theta_tensor : %f", inputs[1][0]); dd4hep::printout(dd4hep::DEBUG, "CaloCloudsTwoAngleModel::prepareInput", "Input_phi_tensor : %f", inputs[2][0]); diff --git a/src/EndcapGeometry.cc b/src/EndcapGeometry.cc index 508685a..470f91d 100644 --- a/src/EndcapGeometry.cc +++ b/src/EndcapGeometry.cc @@ -41,8 +41,9 @@ G4ThreeVector EndcapGeometry::localDirection(G4FastTrack const& aFastTrack) cons localDir = {-direction.x(), direction.y(), -direction.z()}; } - dd4hep::printout(dd4hep::DEBUG, "EndcapGeometry::localDirection", "pos0 = (%f, %f, %f) - dir = (%f, %f, %f) - E = %f" , - position.x(), position.y(), position.z(), direction.x(), direction.y(), direction.z(), aFastTrack.GetPrimaryTrack()->GetKineticEnergy()); + dd4hep::printout(dd4hep::DEBUG, "EndcapGeometry::localDirection", "pos0 = (%f, %f, %f) - dir = (%f, %f, %f) - E = %f", + position.x(), position.y(), position.z(), direction.x(), direction.y(), direction.z(), + aFastTrack.GetPrimaryTrack()->GetKineticEnergy()); return localDir; } @@ -53,8 +54,8 @@ void EndcapGeometry::localToGlobal(G4FastTrack const& aFastTrack, std::vectorGetPosition(); G4ThreeVector direction = aFastTrack.GetPrimaryTrack()->GetMomentumDirection(); - dd4hep::printout(dd4hep::DEBUG, "EndcapGeometry::localToGlobal", "pos0 = (%f, %f, %f) - dir = (%f, %f, %f) - E = %f", - position.x(), position.y(), position.z(), direction.x(), direction.y(), direction.z(), energy); + dd4hep::printout(dd4hep::DEBUG, "EndcapGeometry::localToGlobal", "pos0 = (%f, %f, %f) - dir = (%f, %f, %f) - E = %f", + position.x(), position.y(), position.z(), direction.x(), direction.y(), direction.z(), energy); float signZ = (position.z() > 0. ? 1.0 : -1.0); diff --git a/src/Geant4FastHitMakerGlobal.cc b/src/Geant4FastHitMakerGlobal.cc index cc0eef6..e4cbe94 100644 --- a/src/Geant4FastHitMakerGlobal.cc +++ b/src/Geant4FastHitMakerGlobal.cc @@ -66,28 +66,28 @@ void Geant4FastHitMakerGlobal::make(const G4FastHit& aHit, const G4FastTrack& aT } m_navigator->SetWorldVolume(worldWithSD); // use track global position - m_navigator->LocateGlobalPointAndUpdateTouchable( - aHit.GetPosition(), m_touchableHandle(), false); + m_navigator->LocateGlobalPointAndUpdateTouchable(aHit.GetPosition(), m_touchableHandle(), false); m_naviSetup = true; } else { // for further deposits use hit (local) position and local->global // transformation - m_navigator->LocateGlobalPointAndUpdateTouchable( - aHit.GetPosition(), m_touchableHandle()); + m_navigator->LocateGlobalPointAndUpdateTouchable(aHit.GetPosition(), m_touchableHandle()); } G4VPhysicalVolume* currentVolume = m_touchableHandle()->GetVolume(); G4VSensitiveDetector* sensitive; if (currentVolume != 0) { // In full sim sensitive detector - dd4hep::printout(dd4hep::DEBUG, "Geant4FastHitMakerGlobal::make", "In full sim sensitive: aHit.GetPosition() x: %f, y: %f, z: %f ", - aHit.GetPosition().x(), aHit.GetPosition().y(), aHit.GetPosition().z()); + dd4hep::printout(dd4hep::DEBUG, "Geant4FastHitMakerGlobal::make", + "In full sim sensitive: aHit.GetPosition() x: %f, y: %f, z: %f ", aHit.GetPosition().x(), + aHit.GetPosition().y(), aHit.GetPosition().z()); sensitive = currentVolume->GetLogicalVolume()->GetSensitiveDetector(); G4VFastSimSensitiveDetector* fastSimSensitive = dynamic_cast(sensitive); if (fastSimSensitive) { // In fast sim sensitive detector - dd4hep::printout(dd4hep::DEBUG, "Geant4FastHitMakerGlobal::make", "In fast sim sensitive: aHit.GetPosition() x: %f, y: %f, z: %f ", - aHit.GetPosition().x(), aHit.GetPosition().y(), aHit.GetPosition().z()); + dd4hep::printout(dd4hep::DEBUG, "Geant4FastHitMakerGlobal::make", + "In fast sim sensitive: aHit.GetPosition() x: %f, y: %f, z: %f ", aHit.GetPosition().x(), + aHit.GetPosition().y(), aHit.GetPosition().z()); fastSimSensitive->Hit(&aHit, &aTrack, &m_touchableHandle); } else if (sensitive && currentVolume->GetLogicalVolume()->GetFastSimulationManager()) { G4cerr << "ERROR - Geant4FastHitMakerGlobal::make()" << G4endl << " It is required to derive from the " diff --git a/src/LoadHdf5.cc b/src/LoadHdf5.cc index e86a856..1e27139 100644 --- a/src/LoadHdf5.cc +++ b/src/LoadHdf5.cc @@ -43,7 +43,7 @@ void LoadHdf5::initialize() { // if m_rank == 4 // index 0: shower number // index 1, 2, 3: x, y, z cell number - + // else if m_rank == 3 // index 0: shower number // index 1: number of points @@ -77,7 +77,6 @@ void LoadHdf5::runInference(const InputVecs&, const TensorDimVecs&, std::vector< m_isInitialized = true; } - // If counter exceeds number of showers in file, reset if (m_count > m_totalSize) { m_count = 0; @@ -85,22 +84,22 @@ void LoadHdf5::runInference(const InputVecs&, const TensorDimVecs&, std::vector< // select shower from library if (m_rank == 4) { - std::vector shower(m_library.begin() + m_count * m_dimsOut[1] * m_dimsOut[2] * m_dimsOut[3], - m_library.begin() + (m_count + 1) * m_dimsOut[1] * m_dimsOut[2] * m_dimsOut[3]); - assert(shower.size() == m_dimsOut[1] * m_dimsOut[2] * m_dimsOut[3]); - - // write output - output = std::move(shower); - } - else if (m_rank == 3 ){ - std::vector shower(m_library.begin() + m_count * m_dimsOut[1] * m_dimsOut[2], - m_library.begin() + (m_count + 1) * m_dimsOut[1] * m_dimsOut[2]); - assert(shower.size() == m_dimsOut[1] * m_dimsOut[2]); - - // write output - output = std::move(shower); + std::vector shower(m_library.begin() + m_count * m_dimsOut[1] * m_dimsOut[2] * m_dimsOut[3], + m_library.begin() + (m_count + 1) * m_dimsOut[1] * m_dimsOut[2] * m_dimsOut[3]); + assert(shower.size() == m_dimsOut[1] * m_dimsOut[2] * m_dimsOut[3]); + + // write output + output = std::move(shower); + } else if (m_rank == 3) { + std::vector shower(m_library.begin() + m_count * m_dimsOut[1] * m_dimsOut[2], + m_library.begin() + (m_count + 1) * m_dimsOut[1] * m_dimsOut[2]); + assert(shower.size() == m_dimsOut[1] * m_dimsOut[2]); + + // write output + output = std::move(shower); + } else { + throw std::runtime_error("Shower library does not have the correct dimensions!"); } - else{throw std::runtime_error("Shower library does not have the correct dimensions!");} ++m_count; } diff --git a/src/ONNXInference.cc b/src/ONNXInference.cc index 093bdb3..992b4ba 100644 --- a/src/ONNXInference.cc +++ b/src/ONNXInference.cc @@ -66,13 +66,14 @@ void ONNXInference::initialize() { Ort::TypeInfo type_info = m_session->GetInputTypeInfo(i); auto tensor_info = type_info.GetTensorTypeAndShapeInfo(); input_node_dims = tensor_info.GetShape(); - dd4hep::printout(dd4hep::DEBUG, "ONNXInference::initialize", "input_node_dims : %i = %i", i, input_node_dims.size()); - + dd4hep::printout(dd4hep::DEBUG, "ONNXInference::initialize", "input_node_dims : %i = %i", i, + input_node_dims.size()); + for (std::size_t j = 0; j < input_node_dims.size(); j++) { if (input_node_dims[j] < 0) { input_node_dims[j] = 1; } - dd4hep::printout(dd4hep::DEBUG, "ONNXInference::initialize", "dim %i : %i",j, input_node_dims[j] ); + dd4hep::printout(dd4hep::DEBUG, "ONNXInference::initialize", "dim %i : %i", j, input_node_dims[j]); } } // output nodes @@ -92,7 +93,8 @@ void ONNXInference::initialize() { Ort::TypeInfo type_info = m_session->GetOutputTypeInfo(i); auto tensor_info = type_info.GetTensorTypeAndShapeInfo(); output_node_dims = tensor_info.GetShape(); - dd4hep::printout(dd4hep::DEBUG, "ONNXInference::initialize", "output_node_dims : %i = %i", i, output_node_dims.size()); + dd4hep::printout(dd4hep::DEBUG, "ONNXInference::initialize", "output_node_dims : %i = %i", i, + output_node_dims.size()); for (std::size_t j = 0; j < output_node_dims.size(); j++) { if (output_node_dims[j] < 0) { diff --git a/src/Par04ExampleVAE.cc b/src/Par04ExampleVAE.cc index f4fc5bd..ded880a 100644 --- a/src/Par04ExampleVAE.cc +++ b/src/Par04ExampleVAE.cc @@ -21,9 +21,9 @@ void Par04ExampleVAE::prepareInput(G4FastTrack const& aFastTrack, G4ThreeVector // compute local incident angle double theta = acos(localDir.z()); - dd4hep::printout(dd4hep::DEBUG, "Par04ExampleVAE::prepareInput", "pos0 = (%f, %f, %f) - dir = (%f, %f, %f) - E = %f - theta = %f", - position.x(), position.y(), position.z(), direction.x(), direction.y(), direction.z(), - energy/ CLHEP::GeV, theta * 180. / M_PI); + dd4hep::printout(dd4hep::DEBUG, "Par04ExampleVAE::prepareInput", + "pos0 = (%f, %f, %f) - dir = (%f, %f, %f) - E = %f - theta = %f", position.x(), position.y(), + position.z(), direction.x(), direction.y(), direction.z(), energy / CLHEP::GeV, theta * 180. / M_PI); /* //if (DEBUGPRINT) { // std::cout << " Par04ExampleVAE::prepareInput pos0 = " << position << " - dir = " << direction diff --git a/src/PionCloudsModel.cc b/src/PionCloudsModel.cc index fde8004..a298ac7 100644 --- a/src/PionCloudsModel.cc +++ b/src/PionCloudsModel.cc @@ -56,27 +56,25 @@ void PionCloudsModel::prepareInput(G4FastTrack const& aFastTrack, G4ThreeVector } // For array structure: (No. showers, No. points, dimensions(4)) -void PionCloudsModel::convertOutput(G4FastTrack const&, G4ThreeVector const&, - const std::vector& output, std::vector& spacepoints) { +void PionCloudsModel::convertOutput(G4FastTrack const&, G4ThreeVector const&, const std::vector& output, + std::vector& spacepoints) { const int nPoints = output.size() / m_nDims; int layerNum = 0; // Reshape into intermediate representation - auto reshaped = - std::views::iota(0,nPoints) | - std::views::transform([&output](int i){ - return std::span{output.data() + i * 4, 4}; - }); - + auto reshaped = std::views::iota(0, nPoints) | std::views::transform([&output](int i) { + return std::span{output.data() + i * 4, 4}; + }); + spacepoints.resize(nPoints); for (const auto& values : reshaped) { ddml::SpacePoint sp(values[0], // x // *(-1) to align local to global convention in ddml - values[2], // y // *(-1) to align local to global convention in ddml - 0., // z - values[3], // energy - 0. // time + values[2], // y // *(-1) to align local to global convention in ddml + 0., // z + values[3], // energy + 0. // time ); layerNum = int(values[1]); spacepoints[layerNum].emplace_back(sp); - } + } } } // namespace ddml \ No newline at end of file diff --git a/src/PolyhedraBarrelGeometry.cc b/src/PolyhedraBarrelGeometry.cc index 91788d0..6c2c6b5 100644 --- a/src/PolyhedraBarrelGeometry.cc +++ b/src/PolyhedraBarrelGeometry.cc @@ -19,13 +19,15 @@ void PolyhedraBarrelGeometry::initialize() { if (cal) { for (auto l : cal->layers) { m_caloLayerDistances.push_back((l.distance + l.inner_thickness) / dd4hep::mm); - dd4hep::printout(dd4hep::INFO, "PolyhedraBarrelGeometry::initialize", "ECAL Layer distances %f", l.distance + l.inner_thickness); + dd4hep::printout(dd4hep::INFO, "PolyhedraBarrelGeometry::initialize", "ECAL Layer distances %f", + l.distance + l.inner_thickness); /*REMOVE! //std::cout << " ECAL Layer distances " << l.distance + l.inner_thickness << std::endl; */ } } else { - dd4hep::printout(dd4hep::ERROR, "PolyhedraBarrelGeometry::initialize", "Detector %s not found!", m_detector.c_str()); + dd4hep::printout(dd4hep::ERROR, "PolyhedraBarrelGeometry::initialize", "Detector %s not found!", + m_detector.c_str()); /*REMOVE! //std::cout << " ###### error: detector " << m_detector << " not found !" << std::endl; */ @@ -38,13 +40,15 @@ void PolyhedraBarrelGeometry::initialize() { if (cal_had) { for (auto l_had : cal_had->layers) { m_caloLayerDistances.push_back((l_had.distance + l_had.inner_thickness) / dd4hep::mm); - dd4hep::printout(dd4hep::INFO, "PolyhedraBarrelGeometry::initialize", "HCAL Layer distances %f", l_had.distance + l_had.inner_thickness); + dd4hep::printout(dd4hep::INFO, "PolyhedraBarrelGeometry::initialize", "HCAL Layer distances %f", + l_had.distance + l_had.inner_thickness); /*REMOVE! //std::cout << " HCAL Layer distances " << l_had.distance + l_had.inner_thickness << std::endl; - */ + */ } } else { - dd4hep::printout(dd4hep::ERROR, "PolyhedraBarrelGeometry::initialize", "Detector %s not found!", m_hadDetector.c_str()); + dd4hep::printout(dd4hep::ERROR, "PolyhedraBarrelGeometry::initialize", "Detector %s not found!", + m_hadDetector.c_str()); /*REMOVE! //std::cout << " ###### error: detector " << m_hadDetector << " not found !" << std::endl; */ @@ -97,11 +101,12 @@ G4ThreeVector PolyhedraBarrelGeometry::localDirection(G4FastTrack const& aFastTr // the z-axis pointing into the calo G4ThreeVector localDir(-dirR.z(), dirR.y(), dirR.x()); - dd4hep::printout(dd4hep::DEBUG, "PolyhedraBarrelGeometry::localDirection", "symmetry = %i - pos0 = (%f, %f, %f) - dir = (%f, %f, %f) - E = %f - localDir = (%f, %f, %f)", - m_nSymmetry, position.x(), position.y(), position.z(), - direction.x(), direction.y(), direction.z(), aFastTrack.GetPrimaryTrack()->GetKineticEnergy(), localDir.x(), localDir.y(), localDir.z()); - dd4hep::printout(dd4hep::DEBUG, "PolyhedraBarrelGeometry::localDirection", "phi = %f - theta = %f", - atan2(localDir.y(), localDir.x()) / M_PI * 180., acos(localDir.z()) / M_PI * 180.); + dd4hep::printout(dd4hep::DEBUG, "PolyhedraBarrelGeometry::localDirection", + "symmetry = %i - pos0 = (%f, %f, %f) - dir = (%f, %f, %f) - E = %f - localDir = (%f, %f, %f)", + m_nSymmetry, position.x(), position.y(), position.z(), direction.x(), direction.y(), direction.z(), + aFastTrack.GetPrimaryTrack()->GetKineticEnergy(), localDir.x(), localDir.y(), localDir.z()); + dd4hep::printout(dd4hep::DEBUG, "PolyhedraBarrelGeometry::localDirection", "phi = %f - theta = %f", + atan2(localDir.y(), localDir.x()) / M_PI * 180., acos(localDir.z()) / M_PI * 180.); /*REMOVE! //if (DEBUGPRINT) { // G4double energy = aFastTrack.GetPrimaryTrack()->GetKineticEnergy(); @@ -125,8 +130,10 @@ void PolyhedraBarrelGeometry::localToGlobal(G4FastTrack const& aFastTrack, int phiSec = phiSector(position); - dd4hep::printout(dd4hep::DEBUG, "PolyhedraBarrelGeometry::localToGlobal", "symmetry = %i - pos0= (%f, %f, %f) - dir = (%f, %f, %f) - E = %f", - m_nSymmetry, position.x(), position.y(), position.z(), direction.x(), direction.y(), direction.z(), aFastTrack.GetPrimaryTrack()->GetKineticEnergy()); + dd4hep::printout(dd4hep::DEBUG, "PolyhedraBarrelGeometry::localToGlobal", + "symmetry = %i - pos0= (%f, %f, %f) - dir = (%f, %f, %f) - E = %f", m_nSymmetry, position.x(), + position.y(), position.z(), direction.x(), direction.y(), direction.z(), + aFastTrack.GetPrimaryTrack()->GetKineticEnergy()); /*REMOVE! //if (DEBUGPRINT) { // G4double energy = aFastTrack.GetPrimaryTrack()->GetKineticEnergy(); @@ -152,9 +159,10 @@ void PolyhedraBarrelGeometry::localToGlobal(G4FastTrack const& aFastTrack, dirR = {1., 0., 0.}; // position layers w/ impact normal to the plane } - dd4hep::printout(dd4hep::DEBUG, "PolyhedraBarrelGeometry::localToGlobal", "pos0= (%f, %f, %f) - dir = (%f, %f, %f) - phiSec = %i - posR = (%f, %f, %f) - dirR = (%f, %f, %f)", - position.x(), position.y(), position.z(), direction.x(), direction.y(), direction.z(), - phiSec, posR.x(), posR.y(), posR.z(), dirR.x(), dirR.y(), dirR.z()); + dd4hep::printout(dd4hep::DEBUG, "PolyhedraBarrelGeometry::localToGlobal", + "pos0= (%f, %f, %f) - dir = (%f, %f, %f) - phiSec = %i - posR = (%f, %f, %f) - dirR = (%f, %f, %f)", + position.x(), position.y(), position.z(), direction.x(), direction.y(), direction.z(), phiSec, + posR.x(), posR.y(), posR.z(), dirR.x(), dirR.y(), dirR.z()); /*REMOVE! //if (DEBUGPRINT) { // std::cout << " PolyhedraBarrelGeometry::localToGlobal - position " << position << " - direction " << direction @@ -216,11 +224,12 @@ void PolyhedraBarrelGeometry::localToGlobal(G4FastTrack const& aFastTrack, sp.Y = global.y(); sp.Z = global.z(); - dd4hep::printout(dd4hep::DEBUG, "PolyhedraBarrelGeometry::localToGlobal", "global.x() = %f, global.y() = %f, global.z() = %f", - global.x(), global.y(), global.z()); + dd4hep::printout(dd4hep::DEBUG, "PolyhedraBarrelGeometry::localToGlobal", + "global.x() = %f, global.y() = %f, global.z() = %f", global.x(), global.y(), global.z()); /*REMOVE! //std::cout << " PolyhedraBarrelGeometry::localToGlobal - global.x() = " << global.x() - // << " global.y() = " << global.y() << " global.z() " << global.z() << " Energy: " << sp.E << std::endl; + // << " global.y() = " << global.y() << " global.z() " << global.z() << " Energy: " << sp.E << + std::endl; */ } } diff --git a/src/RegularGridBIBAEModel.cc b/src/RegularGridBIBAEModel.cc index 291bfc3..22607f0 100644 --- a/src/RegularGridBIBAEModel.cc +++ b/src/RegularGridBIBAEModel.cc @@ -20,9 +20,9 @@ void RegularGridBIBAEModel::prepareInput(G4FastTrack const& aFastTrack, G4ThreeV // compute local incident angle double theta = acos(localDir.z()); - dd4hep::printout(dd4hep::DEBUG, "RegularGridBIBAEModel::prepareInput", "pos0 = (%f, %f, %f) - dir = (%f, %f, %f) - E = %f - theta = %f", - position.x(), position.y(), position.z(), direction.x(), direction.y(), direction.z(), - energy/ CLHEP::GeV, theta * 180. / M_PI); + dd4hep::printout(dd4hep::DEBUG, "RegularGridBIBAEModel::prepareInput", + "pos0 = (%f, %f, %f) - dir = (%f, %f, %f) - E = %f - theta = %f", position.x(), position.y(), + position.z(), direction.x(), direction.y(), direction.z(), energy / CLHEP::GeV, theta * 180. / M_PI); // the input for the BIB-AE is one energy and an angle (plus cond tensor) inputs.resize(m_latentSize); @@ -37,7 +37,8 @@ void RegularGridBIBAEModel::prepareInput(G4FastTrack const& aFastTrack, G4ThreeV inputs[2][0] = (inputs[0][0]) / 100.; inputs[2][1] = (inputs[1][0]) / (90. * (M_PI / 180.)); - dd4hep::printout(dd4hep::DEBUG, "RegularGridBIBAEModel::prepareInput", "Input_energy_tensor : %f", inputs[0][0] * 100.); + dd4hep::printout(dd4hep::DEBUG, "RegularGridBIBAEModel::prepareInput", "Input_energy_tensor : %f", + inputs[0][0] * 100.); // ---- resize output vector diff --git a/src/RegularGridGANModel.cc b/src/RegularGridGANModel.cc index c3b8e15..9ce469c 100644 --- a/src/RegularGridGANModel.cc +++ b/src/RegularGridGANModel.cc @@ -22,9 +22,9 @@ void RegularGridGANModel::prepareInput(G4FastTrack const& aFastTrack, G4ThreeVec // conditioning variables, such as incident angles ... // for now assume simple GAN with 90 deg incident - dd4hep::printout(dd4hep::DEBUG, "RegularGridGANModel::prepareInput", "pos0 = (%f, %f, %f) - dir = (%f, %f, %f) - E = %f", - position.x(), position.y(), position.z(), direction.x(), direction.y(), direction.z(), - energy/ CLHEP::GeV); + dd4hep::printout(dd4hep::DEBUG, "RegularGridGANModel::prepareInput", + "pos0 = (%f, %f, %f) - dir = (%f, %f, %f) - E = %f", position.x(), position.y(), position.z(), + direction.x(), direction.y(), direction.z(), energy / CLHEP::GeV); // the input for this model is the latent space and the energy conditioning diff --git a/src/RegularGridTwoAngleBIBAEModel.cc b/src/RegularGridTwoAngleBIBAEModel.cc index b236909..b8888b1 100644 --- a/src/RegularGridTwoAngleBIBAEModel.cc +++ b/src/RegularGridTwoAngleBIBAEModel.cc @@ -68,11 +68,14 @@ void RegularGridTwoAngleBIBAEModel::prepareInput(G4FastTrack const& aFastTrack, // compute local incident angles double theta = acos(localDir.x()); double phi = atan2(localDir.y(), localDir.x()); - dd4hep::printout(dd4hep::DEBUG, "RegularGridTwoAngleBIBAEModel::prepareInput", "pos0 = (%f, %f, %f) - dir = (%f, %f, %f) - E = %f - local dir =(%f, %f, %f) - theta = %f - phi=%f", - position.x(), position.y(), position.z(), direction.x(), direction.y(), direction.z(), - energy/ CLHEP::GeV, localDir.x(), localDir.y(), localDir.z(), theta, phi); - dd4hep::printout(dd4hep::DEBUG, "RegularGridTwoAngleBIBAEModel::prepareInput", "theta_cond = %f / %f - phi_cond = %f / %f - Global phi = %f / %f - Global theta = %f / %f", - theta_cond, theta_cond / M_PI * 180., phi_cond, phi_cond / M_PI * 180., direction.phi(), direction.phi() / M_PI * 180., direction.theta(), direction.theta() / M_PI * 180); + dd4hep::printout(dd4hep::DEBUG, "RegularGridTwoAngleBIBAEModel::prepareInput", + "pos0 = (%f, %f, %f) - dir = (%f, %f, %f) - E = %f - local dir =(%f, %f, %f) - theta = %f - phi=%f", + position.x(), position.y(), position.z(), direction.x(), direction.y(), direction.z(), + energy / CLHEP::GeV, localDir.x(), localDir.y(), localDir.z(), theta, phi); + dd4hep::printout(dd4hep::DEBUG, "RegularGridTwoAngleBIBAEModel::prepareInput", + "theta_cond = %f / %f - phi_cond = %f / %f - Global phi = %f / %f - Global theta = %f / %f", + theta_cond, theta_cond / M_PI * 180., phi_cond, phi_cond / M_PI * 180., direction.phi(), + direction.phi() / M_PI * 180., direction.theta(), direction.theta() / M_PI * 180); // the input for the BIB-AE is one energy and two angles (plus cond tensor) inputs.resize(m_latentSize); @@ -90,10 +93,13 @@ void RegularGridTwoAngleBIBAEModel::prepareInput(G4FastTrack const& aFastTrack, inputs[3][1] = (inputs[1][0]) / (95. * (M_PI / 180.)); inputs[3][2] = (inputs[2][0]) / (95. * (M_PI / 180.)); - dd4hep::printout(dd4hep::DEBUG, "RegularGridTwoAngleBIBAEModel::prepareInput", "Input_energy_tensor : %f", inputs[0][0]); - dd4hep::printout(dd4hep::DEBUG, "RegularGridTwoAngleBIBAEModel::prepareInput", "Input_theta_tensor : %f", inputs[1][0]); + dd4hep::printout(dd4hep::DEBUG, "RegularGridTwoAngleBIBAEModel::prepareInput", "Input_energy_tensor : %f", + inputs[0][0]); + dd4hep::printout(dd4hep::DEBUG, "RegularGridTwoAngleBIBAEModel::prepareInput", "Input_theta_tensor : %f", + inputs[1][0]); dd4hep::printout(dd4hep::DEBUG, "RegularGridTwoAngleBIBAEModel::prepareInput", "Input_phi_tensor : %f", inputs[2][0]); - dd4hep::printout(dd4hep::DEBUG, "RegularGridTwoAngleBIBAEModel::prepareInput", "Input_Flow_energy : %f", inputs[3][0]); + dd4hep::printout(dd4hep::DEBUG, "RegularGridTwoAngleBIBAEModel::prepareInput", "Input_Flow_energy : %f", + inputs[3][0]); dd4hep::printout(dd4hep::DEBUG, "RegularGridTwoAngleBIBAEModel::prepareInput", "Input_Flow_theta : %f", inputs[3][1]); dd4hep::printout(dd4hep::DEBUG, "RegularGridTwoAngleBIBAEModel::prepareInput", "Input_Flow_phi : %f", inputs[3][2]); @@ -236,8 +242,10 @@ std::vector RegularGridTwoAngleBIBAEModel::getIncidentCell(const double& double pos_X = intersect[0]; double pos_Y = intersect[2]; - dd4hep::printout(dd4hep::DEBUG,"RegularGridTwoAngleBIBAEModel::getIncidentCell", "X position of intersection: %f", pos_X); - dd4hep::printout(dd4hep::DEBUG,"RegularGridTwoAngleBIBAEModel::getIncidentCell", "Y position of intersection: %f", pos_Y); + dd4hep::printout(dd4hep::DEBUG, "RegularGridTwoAngleBIBAEModel::getIncidentCell", "X position of intersection: %f", + pos_X); + dd4hep::printout(dd4hep::DEBUG, "RegularGridTwoAngleBIBAEModel::getIncidentCell", "Y position of intersection: %f", + pos_Y); /* //if (DEBUGPRINT) { // std::cout << "X position of intersection: " << pos_X << std::endl; @@ -266,25 +274,27 @@ std::vector RegularGridTwoAngleBIBAEModel::getIncidentCell(const double& // binX.size() < binX.size()) { - dd4hep::printout(dd4hep::PrintLevel::WARNING,"RegularGridTwoAngleBIBAEModel::getIncidentCell", "Incident position not found in grid X!"); + dd4hep::printout(dd4hep::PrintLevel::WARNING, "RegularGridTwoAngleBIBAEModel::getIncidentCell", + "Incident position not found in grid X!"); } else if (binX[i] <= pos_X && pos_X < binX[i + 1]) { double frac = (pos_X - binX[i]) / 5.088333; if (frac < 0) { - dd4hep::printout(dd4hep::PrintLevel::WARNING,"RegularGridTwoAngleBIBAEModel::getIncidentCell", "Incident cell fraction wrong X!"); + dd4hep::printout(dd4hep::PrintLevel::WARNING, "RegularGridTwoAngleBIBAEModel::getIncidentCell", + "Incident cell fraction wrong X!"); } gridX = static_cast(i) + frac; - dd4hep::printout(dd4hep::DEBUG,"RegularGridTwoAngleBIBAEModel::getIncidentCell", "gridX = %f", gridX); + dd4hep::printout(dd4hep::DEBUG, "RegularGridTwoAngleBIBAEModel::getIncidentCell", "gridX = %f", gridX); i = binX.size(); // break; - } } @@ -292,18 +302,20 @@ std::vector RegularGridTwoAngleBIBAEModel::getIncidentCell(const double& // Y for (size_t j = 0; j < binY.size(); ++j) { - dd4hep::printout(dd4hep::DEBUG, "RegularGridTwoAngleBIBAEModel::getIncidentCell", "binY[j] = %f - binY[j+1] = %f - j = %i", - binY[j], binY[j+1], j); + dd4hep::printout(dd4hep::DEBUG, "RegularGridTwoAngleBIBAEModel::getIncidentCell", + "binY[j] = %f - binY[j+1] = %f - j = %i", binY[j], binY[j + 1], j); if (j + 1 > binY.size()) { - dd4hep::printout(dd4hep::PrintLevel::WARNING, "RegularGridTwoAngleBIBAEModel::getIncidentCell", "Incident position not found in grid Y!"); + dd4hep::printout(dd4hep::PrintLevel::WARNING, "RegularGridTwoAngleBIBAEModel::getIncidentCell", + "Incident position not found in grid Y!"); } else if (binY[j] <= pos_Y && pos_Y < binY[j + 1]) { double frac = (pos_Y - binY[j]) / 5.088333; if (frac < 0) { - dd4hep::printout(dd4hep::PrintLevel::WARNING, "RegularGridTwoAngleBIBAEModel::getIncidentCell", "Incident cell fraction wrong Y!"); + dd4hep::printout(dd4hep::PrintLevel::WARNING, "RegularGridTwoAngleBIBAEModel::getIncidentCell", + "Incident cell fraction wrong Y!"); } gridY = static_cast(j) + frac; diff --git a/src/TorchInference.cc b/src/TorchInference.cc index 81b196d..588220f 100644 --- a/src/TorchInference.cc +++ b/src/TorchInference.cc @@ -45,20 +45,19 @@ void TorchInference::runInference(const InputVecs& inputs, const TensorDimVecs& m_isInitialized = true; } - if (dd4hep::printLevel() <= dd4hep::DEBUG){ + if (dd4hep::printLevel() <= dd4hep::DEBUG) { dd4hep::printout(dd4hep::DEBUG, "TorchInference::runInference", " ----- TorchInference::runInference -----"); - dd4hep::printout(dd4hep::DEBUG, "TorchInference::runInference", "# inputs = %f : ", inputs.size() ); + dd4hep::printout(dd4hep::DEBUG, "TorchInference::runInference", "# inputs = %f : ", inputs.size()); for (auto iv : inputs) { dd4hep::printout(dd4hep::DEBUG, "TorchInference::runInference", "%f, ", iv.size()); } dd4hep::printout(dd4hep::DEBUG, "TorchInference::runInference", "# dims = %f :", tensDims.size()); - + for (auto iv : tensDims) { dd4hep::printout(dd4hep::DEBUG, "TorchInference::runInference", "%f, ", iv.size()); } - } assert(inputs.size() == tensDims.size()); @@ -70,7 +69,6 @@ void TorchInference::runInference(const InputVecs& inputs, const TensorDimVecs& tensors.emplace_back(inTens); dd4hep::printout(dd4hep::DEBUG, "TorchInference::runInference", "inTensor %i: %f", i, inTens); - } at::Tensor outTensor = m_jitModule.forward(tensors).toTensor(); //.contiguous(); From f47fc8c67b55a6e498ba13f6879c33de416db9c4 Mon Sep 17 00:00:00 2001 From: Peter McKeown Date: Tue, 25 Nov 2025 11:28:39 +0100 Subject: [PATCH 34/36] remove remaining debug prints --- src/Par04ExampleVAE.cc | 7 +---- src/PolyhedraBarrelGeometry.cc | 46 ---------------------------- src/RegularGridTwoAngleBIBAEModel.cc | 18 ----------- 3 files changed, 1 insertion(+), 70 deletions(-) diff --git a/src/Par04ExampleVAE.cc b/src/Par04ExampleVAE.cc index ded880a..3adcf6f 100644 --- a/src/Par04ExampleVAE.cc +++ b/src/Par04ExampleVAE.cc @@ -24,12 +24,7 @@ void Par04ExampleVAE::prepareInput(G4FastTrack const& aFastTrack, G4ThreeVector dd4hep::printout(dd4hep::DEBUG, "Par04ExampleVAE::prepareInput", "pos0 = (%f, %f, %f) - dir = (%f, %f, %f) - E = %f - theta = %f", position.x(), position.y(), position.z(), direction.x(), direction.y(), direction.z(), energy / CLHEP::GeV, theta * 180. / M_PI); - /* - //if (DEBUGPRINT) { - // std::cout << " Par04ExampleVAE::prepareInput pos0 = " << position << " - dir = " << direction - // << " - E = " << energy / CLHEP::GeV << " theta = " << theta * 180. / M_PI << std::endl; - //} - */ + // the input for this model is the latent space and the energy conditioning if (inputs.size() != 1) { diff --git a/src/PolyhedraBarrelGeometry.cc b/src/PolyhedraBarrelGeometry.cc index 6c2c6b5..6e3ac25 100644 --- a/src/PolyhedraBarrelGeometry.cc +++ b/src/PolyhedraBarrelGeometry.cc @@ -21,16 +21,10 @@ void PolyhedraBarrelGeometry::initialize() { m_caloLayerDistances.push_back((l.distance + l.inner_thickness) / dd4hep::mm); dd4hep::printout(dd4hep::INFO, "PolyhedraBarrelGeometry::initialize", "ECAL Layer distances %f", l.distance + l.inner_thickness); - /*REMOVE! - //std::cout << " ECAL Layer distances " << l.distance + l.inner_thickness << std::endl; - */ } } else { dd4hep::printout(dd4hep::ERROR, "PolyhedraBarrelGeometry::initialize", "Detector %s not found!", m_detector.c_str()); - /*REMOVE! - //std::cout << " ###### error: detector " << m_detector << " not found !" << std::endl; - */ } // For hadronic shower simulation @@ -42,16 +36,10 @@ void PolyhedraBarrelGeometry::initialize() { m_caloLayerDistances.push_back((l_had.distance + l_had.inner_thickness) / dd4hep::mm); dd4hep::printout(dd4hep::INFO, "PolyhedraBarrelGeometry::initialize", "HCAL Layer distances %f", l_had.distance + l_had.inner_thickness); - /*REMOVE! - //std::cout << " HCAL Layer distances " << l_had.distance + l_had.inner_thickness << std::endl; - */ } } else { dd4hep::printout(dd4hep::ERROR, "PolyhedraBarrelGeometry::initialize", "Detector %s not found!", m_hadDetector.c_str()); - /*REMOVE! - //std::cout << " ###### error: detector " << m_hadDetector << " not found !" << std::endl; - */ } } } @@ -107,18 +95,6 @@ G4ThreeVector PolyhedraBarrelGeometry::localDirection(G4FastTrack const& aFastTr aFastTrack.GetPrimaryTrack()->GetKineticEnergy(), localDir.x(), localDir.y(), localDir.z()); dd4hep::printout(dd4hep::DEBUG, "PolyhedraBarrelGeometry::localDirection", "phi = %f - theta = %f", atan2(localDir.y(), localDir.x()) / M_PI * 180., acos(localDir.z()) / M_PI * 180.); - /*REMOVE! - //if (DEBUGPRINT) { - // G4double energy = aFastTrack.GetPrimaryTrack()->GetKineticEnergy(); - - // std::cout << " PolyhedraBarrelGeometry::localDirection - symmetry = " << m_nSymmetry << " pos0 = " << position - // << " - dir = " << direction << " - E = " - // << " - localDir = " << localDir << energy << std::endl; - // std::cout << " PolyhedraBarrelGeometry::localDirection - phi = " - // << atan2(localDir.y(), localDir.x()) / M_PI * 180. << " theta : " << acos(localDir.z()) / M_PI * 180. - // << std::endl; - } - */ return localDir; } @@ -134,14 +110,6 @@ void PolyhedraBarrelGeometry::localToGlobal(G4FastTrack const& aFastTrack, "symmetry = %i - pos0= (%f, %f, %f) - dir = (%f, %f, %f) - E = %f", m_nSymmetry, position.x(), position.y(), position.z(), direction.x(), direction.y(), direction.z(), aFastTrack.GetPrimaryTrack()->GetKineticEnergy()); - /*REMOVE! - //if (DEBUGPRINT) { - // G4double energy = aFastTrack.GetPrimaryTrack()->GetKineticEnergy(); - - // std::cout << " PolyhedraBarrelGeometry::localToGlobal - symmetry = " << m_nSymmetry << " pos0 = " << position - // << " - dir = " << direction << " - E = " << energy << std::endl; - //} - */ // --- rotate position and direction to phi sector 0 (calo plane parallel to // y-axis at positive x ) @@ -163,12 +131,6 @@ void PolyhedraBarrelGeometry::localToGlobal(G4FastTrack const& aFastTrack, "pos0= (%f, %f, %f) - dir = (%f, %f, %f) - phiSec = %i - posR = (%f, %f, %f) - dirR = (%f, %f, %f)", position.x(), position.y(), position.z(), direction.x(), direction.y(), direction.z(), phiSec, posR.x(), posR.y(), posR.z(), dirR.x(), dirR.y(), dirR.z()); - /*REMOVE! - //if (DEBUGPRINT) { - // std::cout << " PolyhedraBarrelGeometry::localToGlobal - position " << position << " - direction " << direction - // << " phiSec: " << phiSec << " posR " << posR << " dirR " << dirR << std::endl; - //} - */ // find the first layer that will have signals as sometimes particles are // create in the calorimeter ! @@ -176,9 +138,6 @@ void PolyhedraBarrelGeometry::localToGlobal(G4FastTrack const& aFastTrack, int nLayer = m_caloLayerDistances.size(); dd4hep::printout(dd4hep::INFO, "PolyhedraBarrelGeometry::localToGlobal", "nLayer = %i", nLayer); - /*REMOVE! - //std::cout << " PolyhedraBarrelGeometry::localToGlobal nLayer " << nLayer << std::endl; - */ for (int l = 0; l < nLayer; ++l) { double r = m_caloLayerDistances[l]; @@ -226,11 +185,6 @@ void PolyhedraBarrelGeometry::localToGlobal(G4FastTrack const& aFastTrack, dd4hep::printout(dd4hep::DEBUG, "PolyhedraBarrelGeometry::localToGlobal", "global.x() = %f, global.y() = %f, global.z() = %f", global.x(), global.y(), global.z()); - /*REMOVE! - //std::cout << " PolyhedraBarrelGeometry::localToGlobal - global.x() = " << global.x() - // << " global.y() = " << global.y() << " global.z() " << global.z() << " Energy: " << sp.E << - std::endl; - */ } } } diff --git a/src/RegularGridTwoAngleBIBAEModel.cc b/src/RegularGridTwoAngleBIBAEModel.cc index b8888b1..dbe8e02 100644 --- a/src/RegularGridTwoAngleBIBAEModel.cc +++ b/src/RegularGridTwoAngleBIBAEModel.cc @@ -103,17 +103,6 @@ void RegularGridTwoAngleBIBAEModel::prepareInput(G4FastTrack const& aFastTrack, dd4hep::printout(dd4hep::DEBUG, "RegularGridTwoAngleBIBAEModel::prepareInput", "Input_Flow_theta : %f", inputs[3][1]); dd4hep::printout(dd4hep::DEBUG, "RegularGridTwoAngleBIBAEModel::prepareInput", "Input_Flow_phi : %f", inputs[3][2]); - /* - //if (DEBUGPRINT) { - // std::cout << " Input_energy_tensor : " << inputs[0][0] << std::endl; - // std::cout << " Input_theta_tensor : " << inputs[1][0] << std::endl; - // std::cout << " Input_phi_tensor : " << inputs[2][0] << std::endl; - // std::cout << " Input_Flow_energy : " << inputs[3][0] << std::endl; - // std::cout << " Input_Flow_theta : " << inputs[3][1] << std::endl; - // std::cout << " Input_Flow_phi : " << inputs[3][2] << std::endl; - //} - */ - // ---- resize output vector int outputSize = m_nCellsX * m_nCellsY * m_nCellsZ; @@ -246,13 +235,6 @@ std::vector RegularGridTwoAngleBIBAEModel::getIncidentCell(const double& pos_X); dd4hep::printout(dd4hep::DEBUG, "RegularGridTwoAngleBIBAEModel::getIncidentCell", "Y position of intersection: %f", pos_Y); - /* - //if (DEBUGPRINT) { - // std::cout << "X position of intersection: " << pos_X << std::endl; - - // std::cout << "Y position of intersection: " << pos_Y << std::endl; - //} - */ // equivalent of np.arange(-77, 78, 5.088333) std::vector binX; From e963fa55a1c280b8b38134492488b5867262224d Mon Sep 17 00:00:00 2001 From: Peter McKeown Date: Tue, 25 Nov 2025 11:40:53 +0100 Subject: [PATCH 35/36] re-try formatting for pre-commit --- include/DDML/CaloCloudsTwoAngleModel.h | 4 ++-- include/DDML/EndcapGeometry.h | 2 +- include/DDML/EndcapTriggerTwoAngleBIBAE.h | 4 ++-- include/DDML/GeometryInterface.h | 2 +- include/DDML/InferenceInterface.h | 2 +- include/DDML/L2LFlowsModel.h | 2 +- include/DDML/ModelInterface.h | 2 +- include/DDML/ONNXInference.h | 2 +- include/DDML/OctogonalBarrelTrigger.h | 4 ++-- include/DDML/Par04ExampleVAE.h | 4 ++-- include/DDML/PionCloudsModel.h | 4 ++-- include/DDML/PolyhedraBarrelGeometry.h | 2 +- include/DDML/RegularGridBIBAEModel.h | 4 ++-- include/DDML/RegularGridGANModel.h | 4 ++-- include/DDML/RegularGridTwoAngleBIBAEModel.h | 4 ++-- include/DDML/TriggerInterface.h | 2 +- scripts/ddsim_steer.py | 4 ++-- src/PionCloudsModel.cc | 5 ++--- 18 files changed, 28 insertions(+), 29 deletions(-) diff --git a/include/DDML/CaloCloudsTwoAngleModel.h b/include/DDML/CaloCloudsTwoAngleModel.h index da4cb54..4cb5545 100644 --- a/include/DDML/CaloCloudsTwoAngleModel.h +++ b/include/DDML/CaloCloudsTwoAngleModel.h @@ -20,9 +20,9 @@ namespace ddml { class CaloCloudsTwoAngleModel : public ModelInterface { public: - CaloCloudsTwoAngleModel(){}; + CaloCloudsTwoAngleModel() {}; - virtual ~CaloCloudsTwoAngleModel(){}; + virtual ~CaloCloudsTwoAngleModel() {}; /// declare the proerties needed for the plugin void declareProperties(dd4hep::sim::Geant4Action* plugin) { diff --git a/include/DDML/EndcapGeometry.h b/include/DDML/EndcapGeometry.h index 716e4c3..7c4f99e 100644 --- a/include/DDML/EndcapGeometry.h +++ b/include/DDML/EndcapGeometry.h @@ -23,7 +23,7 @@ class EndcapGeometry : public GeometryInterface { /// initialize the plugin - after properties have been set void initialize(); - virtual ~EndcapGeometry(){}; + virtual ~EndcapGeometry() {}; /// declare the proerties needed for the plugin void declareProperties(dd4hep::sim::Geant4Action* plugin) { diff --git a/include/DDML/EndcapTriggerTwoAngleBIBAE.h b/include/DDML/EndcapTriggerTwoAngleBIBAE.h index fc741c0..bc45a74 100644 --- a/include/DDML/EndcapTriggerTwoAngleBIBAE.h +++ b/include/DDML/EndcapTriggerTwoAngleBIBAE.h @@ -18,9 +18,9 @@ namespace ddml { class EndcapTriggerTwoAngleBIBAE : public TriggerInterface { public: - EndcapTriggerTwoAngleBIBAE(){}; + EndcapTriggerTwoAngleBIBAE() {}; - virtual ~EndcapTriggerTwoAngleBIBAE(){}; + virtual ~EndcapTriggerTwoAngleBIBAE() {}; // check trigger diff --git a/include/DDML/GeometryInterface.h b/include/DDML/GeometryInterface.h index 7aa423f..e6e672f 100644 --- a/include/DDML/GeometryInterface.h +++ b/include/DDML/GeometryInterface.h @@ -22,7 +22,7 @@ namespace ddml { class GeometryInterface { public: - virtual ~GeometryInterface(){}; + virtual ~GeometryInterface() {}; /** compute local direction in coordinate system that has the z-axis pointing * into the calorimeter, normal to the layers diff --git a/include/DDML/InferenceInterface.h b/include/DDML/InferenceInterface.h index c5b4c07..028b908 100644 --- a/include/DDML/InferenceInterface.h +++ b/include/DDML/InferenceInterface.h @@ -16,7 +16,7 @@ namespace ddml { class InferenceInterface { public: - virtual ~InferenceInterface(){}; + virtual ~InferenceInterface() {}; /// run the inference model - based on input vector and resized outputvector virtual void runInference(const InputVecs& inputs, const TensorDimVecs& tensDims, std::vector& output) = 0; diff --git a/include/DDML/L2LFlowsModel.h b/include/DDML/L2LFlowsModel.h index ff738db..dc53785 100644 --- a/include/DDML/L2LFlowsModel.h +++ b/include/DDML/L2LFlowsModel.h @@ -18,7 +18,7 @@ namespace ddml { */ class L2LFlowsModel : public ModelInterface { public: - L2LFlowsModel(){}; + L2LFlowsModel() {}; virtual ~L2LFlowsModel() = default; diff --git a/include/DDML/ModelInterface.h b/include/DDML/ModelInterface.h index 12e1f11..b2c8557 100644 --- a/include/DDML/ModelInterface.h +++ b/include/DDML/ModelInterface.h @@ -19,7 +19,7 @@ namespace ddml { class ModelInterface { public: - virtual ~ModelInterface(){}; + virtual ~ModelInterface() {}; /** prepare the input vector and resize the output vector for this model * based on the current FastTrack (e.g. extract kinetic energy and incident diff --git a/include/DDML/ONNXInference.h b/include/DDML/ONNXInference.h index cb9452d..1d340e3 100644 --- a/include/DDML/ONNXInference.h +++ b/include/DDML/ONNXInference.h @@ -21,7 +21,7 @@ class ONNXInference : public InferenceInterface { public: ONNXInference(); - virtual ~ONNXInference(){}; + virtual ~ONNXInference() {}; /// declare the proerties needed for the plugin void declareProperties(dd4hep::sim::Geant4Action* plugin); diff --git a/include/DDML/OctogonalBarrelTrigger.h b/include/DDML/OctogonalBarrelTrigger.h index 6d9231c..c4ec4d4 100644 --- a/include/DDML/OctogonalBarrelTrigger.h +++ b/include/DDML/OctogonalBarrelTrigger.h @@ -18,9 +18,9 @@ namespace ddml { class OctogonalBarrelTrigger : public TriggerInterface { public: - OctogonalBarrelTrigger(){}; + OctogonalBarrelTrigger() {}; - virtual ~OctogonalBarrelTrigger(){}; + virtual ~OctogonalBarrelTrigger() {}; // check trigger diff --git a/include/DDML/Par04ExampleVAE.h b/include/DDML/Par04ExampleVAE.h index 24834eb..891ac11 100644 --- a/include/DDML/Par04ExampleVAE.h +++ b/include/DDML/Par04ExampleVAE.h @@ -16,9 +16,9 @@ namespace ddml { class Par04ExampleVAE : public ModelInterface { public: - Par04ExampleVAE(){}; + Par04ExampleVAE() {}; - virtual ~Par04ExampleVAE(){}; + virtual ~Par04ExampleVAE() {}; /// declare the proerties needed for the plugin void declareProperties(dd4hep::sim::Geant4Action* plugin) { diff --git a/include/DDML/PionCloudsModel.h b/include/DDML/PionCloudsModel.h index 2b75731..58264e6 100644 --- a/include/DDML/PionCloudsModel.h +++ b/include/DDML/PionCloudsModel.h @@ -21,9 +21,9 @@ namespace ddml { class PionCloudsModel : public ModelInterface { public: - PionCloudsModel(){}; + PionCloudsModel() {}; - virtual ~PionCloudsModel(){}; + virtual ~PionCloudsModel() {}; /// declare the proerties needed for the plugin void declareProperties(dd4hep::sim::Geant4Action* plugin) { diff --git a/include/DDML/PolyhedraBarrelGeometry.h b/include/DDML/PolyhedraBarrelGeometry.h index d2eade0..8ccb791 100644 --- a/include/DDML/PolyhedraBarrelGeometry.h +++ b/include/DDML/PolyhedraBarrelGeometry.h @@ -25,7 +25,7 @@ class PolyhedraBarrelGeometry : public GeometryInterface { initialize(); }; - virtual ~PolyhedraBarrelGeometry(){}; + virtual ~PolyhedraBarrelGeometry() {}; /// initialize the plugin - after properties have been set void initialize(); diff --git a/include/DDML/RegularGridBIBAEModel.h b/include/DDML/RegularGridBIBAEModel.h index 491a6c1..87a5e54 100644 --- a/include/DDML/RegularGridBIBAEModel.h +++ b/include/DDML/RegularGridBIBAEModel.h @@ -21,9 +21,9 @@ namespace ddml { class RegularGridBIBAEModel : public ModelInterface { public: - RegularGridBIBAEModel(){}; + RegularGridBIBAEModel() {}; - virtual ~RegularGridBIBAEModel(){}; + virtual ~RegularGridBIBAEModel() {}; /// declare the proerties needed for the plugin void declareProperties(dd4hep::sim::Geant4Action* plugin) { diff --git a/include/DDML/RegularGridGANModel.h b/include/DDML/RegularGridGANModel.h index 8e8cb34..6275850 100644 --- a/include/DDML/RegularGridGANModel.h +++ b/include/DDML/RegularGridGANModel.h @@ -16,9 +16,9 @@ namespace ddml { class RegularGridGANModel : public ModelInterface { public: - RegularGridGANModel(){}; + RegularGridGANModel() {}; - virtual ~RegularGridGANModel(){}; + virtual ~RegularGridGANModel() {}; /// declare the proerties needed for the plugin void declareProperties(dd4hep::sim::Geant4Action* plugin) { diff --git a/include/DDML/RegularGridTwoAngleBIBAEModel.h b/include/DDML/RegularGridTwoAngleBIBAEModel.h index 76540a3..6348b33 100644 --- a/include/DDML/RegularGridTwoAngleBIBAEModel.h +++ b/include/DDML/RegularGridTwoAngleBIBAEModel.h @@ -23,9 +23,9 @@ namespace ddml { class RegularGridTwoAngleBIBAEModel : public ModelInterface { public: - RegularGridTwoAngleBIBAEModel(){}; + RegularGridTwoAngleBIBAEModel() {}; - virtual ~RegularGridTwoAngleBIBAEModel(){}; + virtual ~RegularGridTwoAngleBIBAEModel() {}; /// declare the proerties needed for the plugin void declareProperties(dd4hep::sim::Geant4Action* plugin) { diff --git a/include/DDML/TriggerInterface.h b/include/DDML/TriggerInterface.h index 195f786..07fd43e 100644 --- a/include/DDML/TriggerInterface.h +++ b/include/DDML/TriggerInterface.h @@ -15,7 +15,7 @@ namespace ddml { class TriggerInterface { public: - virtual ~TriggerInterface(){}; + virtual ~TriggerInterface() {}; virtual bool check_trigger(const G4FastTrack&) = 0; }; diff --git a/scripts/ddsim_steer.py b/scripts/ddsim_steer.py index 55fa286..785d160 100644 --- a/scripts/ddsim_steer.py +++ b/scripts/ddsim_steer.py @@ -394,7 +394,7 @@ def aiDanceTorch(kernel): CaloClouds = True L2LFlows = False old_DD4hep = False ## use for DD4hep versions/commits before ~ Apr 21st 2023 - hadrons=False + hadrons = False if ild == True: ml_barrel_name = "EcalBarrel" @@ -672,4 +672,4 @@ def LoadHdf5(kernel): # SIM.physics.setupUserPhysics( aiDance) SIM.physics.setupUserPhysics(aiDanceTorch) -#SIM.physics.setupUserPhysics(LoadHdf5) +# SIM.physics.setupUserPhysics(LoadHdf5) diff --git a/src/PionCloudsModel.cc b/src/PionCloudsModel.cc index a298ac7..3f1c050 100644 --- a/src/PionCloudsModel.cc +++ b/src/PionCloudsModel.cc @@ -61,9 +61,8 @@ void PionCloudsModel::convertOutput(G4FastTrack const&, G4ThreeVector const&, co const int nPoints = output.size() / m_nDims; int layerNum = 0; // Reshape into intermediate representation - auto reshaped = std::views::iota(0, nPoints) | std::views::transform([&output](int i) { - return std::span{output.data() + i * 4, 4}; - }); + auto reshaped = std::views::iota(0, nPoints) | + std::views::transform([&output](int i) { return std::span{output.data() + i * 4, 4}; }); spacepoints.resize(nPoints); for (const auto& values : reshaped) { From 72c439bb0ce5d42389c1635eb87cd9272fb78aea Mon Sep 17 00:00:00 2001 From: Peter McKeown Date: Tue, 25 Nov 2025 14:04:28 +0100 Subject: [PATCH 36/36] Resolve clang-tidy errors --- include/DDML/PionCloudsModel.h | 2 +- src/TorchInference.cc | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/include/DDML/PionCloudsModel.h b/include/DDML/PionCloudsModel.h index 58264e6..1689549 100644 --- a/include/DDML/PionCloudsModel.h +++ b/include/DDML/PionCloudsModel.h @@ -48,7 +48,7 @@ class PionCloudsModel : public ModelInterface { size_t m_nDims = 4; // Number of dimensions int m_latentSize = 3; // number of input features (energy, theta, phi) int m_maxNumElements = m_numPoints * 4; // number of space points in the output multiplied by 4 (x,y,z,energy) - int m_nLayer = 78; + // number of layers for ILD is 78: int m_nLayer = 78; TensorDimVecs m_tensDims = {{1, 1}, {1, 1}, {1, 1}, {1, 3}}; }; diff --git a/src/TorchInference.cc b/src/TorchInference.cc index 588220f..1871172 100644 --- a/src/TorchInference.cc +++ b/src/TorchInference.cc @@ -68,12 +68,21 @@ void TorchInference::runInference(const InputVecs& inputs, const TensorDimVecs& torch::Tensor inTens = torch::tensor(inputs[i], m_options).view(tensDims[i]); tensors.emplace_back(inTens); - dd4hep::printout(dd4hep::DEBUG, "TorchInference::runInference", "inTensor %i: %f", i, inTens); + if (dd4hep::printLevel() <= dd4hep::DEBUG) { + torch::IntArrayRef sizes = inTens.sizes(); + for (unsigned iv = 0; iv < sizes.size(); ++iv) { + dd4hep::printout(dd4hep::DEBUG, "TorchInference::runInference", "inTens.size()[%i]: %i", iv, sizes[iv]); + } + } } at::Tensor outTensor = m_jitModule.forward(tensors).toTensor(); //.contiguous(); - - dd4hep::printout(dd4hep::DEBUG, "TorchInference::runInference", "outTensor : %f", outTensor); + if (dd4hep::printLevel() <= dd4hep::DEBUG) { + torch::IntArrayRef sizes_out = outTensor.sizes(); + for (unsigned iv = 0; iv < sizes_out.size(); ++iv) { + dd4hep::printout(dd4hep::DEBUG, "TorchInference::runInference", "outTensor.size()[%i]: %i", iv, sizes_out[iv]); + } + } // torch.flatten(outTensor); // std::cout << "**" << outTensor << std::endl;