From a54eee1e2d0b620ccec874e6f99a349d1fbf85d2 Mon Sep 17 00:00:00 2001 From: Chao <cpeng@anl.gov> Date: Sun, 27 Sep 2020 17:44:03 -0500 Subject: [PATCH] separate reconstruction from clustering --- JugReco/CMakeLists.txt | 1 + .../components/CalorimeterIslandCluster.cpp | 38 ++------ JugReco/src/components/CrystalEndcapsReco.cpp | 86 +++++++++++++++++++ .../options/example_crystalendcapsreco.py | 11 ++- 4 files changed, 103 insertions(+), 33 deletions(-) create mode 100644 JugReco/src/components/CrystalEndcapsReco.cpp diff --git a/JugReco/CMakeLists.txt b/JugReco/CMakeLists.txt index 9bed9225..29500669 100644 --- a/JugReco/CMakeLists.txt +++ b/JugReco/CMakeLists.txt @@ -35,6 +35,7 @@ gaudi_add_module(JugRecoPlugins src/components/TrackParamTruthInit.cpp src/components/ParticlesFromTrackFit.cpp src/components/CalorimeterIslandCluster.cpp + src/components/CrystalEndcapsReco.cpp LINK_LIBRARIES GaudiAlgLib GaudiKernel JugBase ROOT NPDet::DD4podIO EICD::eicd DDRec Acts) target_compile_options(JugRecoPlugins PRIVATE -Wno-suggest-override) diff --git a/JugReco/src/components/CalorimeterIslandCluster.cpp b/JugReco/src/components/CalorimeterIslandCluster.cpp index 778d0c2e..8d716a1e 100644 --- a/JugReco/src/components/CalorimeterIslandCluster.cpp +++ b/JugReco/src/components/CalorimeterIslandCluster.cpp @@ -1,6 +1,6 @@ /* * Island Clustering Algorithm for Calorimeter Blocks - * 1. group all the adjacent modules with the energy deposit above <minModuleEdep> + * 1. group all the adjacent modules * 2. split the groups between their local maxima with the energy deposit above <minClusterCenterEdep> * 3. reconstruct the clustrers * @@ -29,7 +29,6 @@ // Event Model related classes #include "eicd/CalorimeterHitCollection.h" -#include "eicd/RawCalorimeterHitCollection.h" #include "eicd/ClusterCollection.h" using namespace Gaudi::Units; @@ -38,10 +37,10 @@ namespace Jug::Reco { class CalorimeterIslandCluster : public GaudiAlgorithm { public: - Gaudi::Property<double> m_minModuleEdep{this, "minModuleEdep", 0.5*MeV}; + Gaudi::Property<double> m_groupRange{this, "groupRange", 1.8}; Gaudi::Property<double> m_minClusterCenterEdep{this, "minClusterCenterEdep", 50.0*MeV}; Gaudi::Property<double> m_logWeightThres{this, "logWeightThres", 4.2}; - DataHandle<eic::RawCalorimeterHitCollection> + DataHandle<eic::CalorimeterHitCollection> m_inputHitCollection{"inputHitCollection", Gaudi::DataHandle::Reader, this}; DataHandle<eic::ClusterCollection> m_outputClusterCollection{"outputClusterCollection", Gaudi::DataHandle::Writer, this}; @@ -73,26 +72,10 @@ public: StatusCode execute() override { // input collections - const auto &rawhits = *m_inputHitCollection.get(); + const auto &hits = *m_inputHitCollection.get(); // Create output collections auto &clusters = *m_outputClusterCollection.createAndPut(); - info() << "we have " << rawhits.size() << " raw hits" << endmsg; - - // energy time reconstruction - eic::CalorimeterHitCollection hits; - for (auto &rh : rawhits) { - float energy = rh.amplitude()/100.*MeV; - if (energy >= m_minModuleEdep) { - float time = rh.timeStamp(); - auto pos = m_geoSvc->cellIDPositionConverter()->position(rh.cellID0()); - hits.push_back(eic::CalorimeterHit{ - rh.cellID0(), rh.cellID1(), energy, time, {pos.X(), pos.Y(), pos.Z()}, 0 - }); - } - } - info() << "we have " << hits.size() << " hits" << endmsg; - // group neighboring hits std::vector<bool> visits(hits.size(), false); eic::ClusterCollection groups; @@ -136,12 +119,12 @@ private: // info() << std::abs(pos1.x - pos2.x) << ", " << (dim1[0] + dim2[0])/2. << ", " // << std::abs(pos1.y - pos2.y) << ", " << (dim1[1] + dim2[1])/2. << endmsg; - return (std::abs(pos1.x - pos2.x) <= (dim1[0] + dim2[0])/1.3) && - (std::abs(pos1.y - pos2.y) <= (dim1[1] + dim2[1])/1.3); + return (std::abs(pos1.x - pos2.x) <= (dim1[0] + dim2[0])/2.*m_groupRange) && + (std::abs(pos1.y - pos2.y) <= (dim1[1] + dim2[1])/2.*m_groupRange); } // grouping function with Depth-First Search - void dfs_group(eic::Cluster group, int idx, eic::CalorimeterHitCollection &hits, std::vector<bool> &visits) + void dfs_group(eic::Cluster group, int idx, const eic::CalorimeterHitCollection &hits, std::vector<bool> &visits) { auto hit = hits[idx]; group.addhits(hit); @@ -203,12 +186,7 @@ private: if (maxima.hits_size() == 0) { return scoll; } else if (maxima.hits_size() == 1) { - auto cl = clusters.create(); - for (auto hit : group.hits()) { - auto shit = hit.clone(); - cl.addhits(shit); - scoll.push_back(shit); - } + clusters.push_back(group.clone()); return scoll; } diff --git a/JugReco/src/components/CrystalEndcapsReco.cpp b/JugReco/src/components/CrystalEndcapsReco.cpp new file mode 100644 index 00000000..8e152e85 --- /dev/null +++ b/JugReco/src/components/CrystalEndcapsReco.cpp @@ -0,0 +1,86 @@ +#include <algorithm> + +#include "Gaudi/Property.h" +#include "GaudiAlg/GaudiAlgorithm.h" +#include "GaudiKernel/ToolHandle.h" +#include "GaudiAlg/Transformer.h" +#include "GaudiAlg/GaudiTool.h" +#include "GaudiKernel/RndmGenerators.h" +#include "GaudiKernel/PhysicalConstants.h" + +#include "DDRec/CellIDPositionConverter.h" +#include "DDRec/SurfaceManager.h" +#include "DDRec/Surface.h" + +// FCCSW +#include "JugBase/DataHandle.h" +#include "JugBase/IGeoSvc.h" + +// Event Model related classes +#include "eicd/CalorimeterHitCollection.h" +#include "eicd/RawCalorimeterHitCollection.h" + +using namespace Gaudi::Units; + +namespace Jug::Reco { +class CrystalEndcapsReco : public GaudiAlgorithm +{ +public: + Gaudi::Property<double> m_minModuleEdep{this, "minModuleEdep", 0.5*MeV}; + DataHandle<eic::RawCalorimeterHitCollection> + m_inputHitCollection{"inputHitCollection", Gaudi::DataHandle::Reader, this}; + DataHandle<eic::CalorimeterHitCollection> + m_outputHitCollection{"outputHitCollection", Gaudi::DataHandle::Writer, this}; + /// Pointer to the geometry service + SmartIF<IGeoSvc> m_geoSvc; + + // ill-formed: using GaudiAlgorithm::GaudiAlgorithm; + CrystalEndcapsReco(const std::string& name, ISvcLocator* svcLoc) + : GaudiAlgorithm(name, svcLoc) + { + declareProperty("inputHitCollection", m_inputHitCollection, ""); + declareProperty("outputHitCollection", m_outputHitCollection, ""); + } + + StatusCode initialize() override + { + if (GaudiAlgorithm::initialize().isFailure()) { + return StatusCode::FAILURE; + } + m_geoSvc = service("GeoSvc"); + if (!m_geoSvc) { + error() << "Unable to locate Geometry Service. " + << "Make sure you have GeoSvc and SimSvc in the right order in the configuration." << endmsg; + return StatusCode::FAILURE; + } + return StatusCode::SUCCESS; + } + + StatusCode execute() override + { + // input collections + const auto &rawhits = *m_inputHitCollection.get(); + // Create output collections + auto &hits = *m_outputHitCollection.createAndPut(); + + // energy time reconstruction + for (auto &rh : rawhits) { + float energy = rh.amplitude()/100.*MeV; + if (energy >= m_minModuleEdep) { + float time = rh.timeStamp(); + auto pos = m_geoSvc->cellIDPositionConverter()->position(rh.cellID0()); + hits.push_back(eic::CalorimeterHit{ + rh.cellID0(), rh.cellID1(), energy, time, {pos.X(), pos.Y(), pos.Z()}, 0 + }); + } + } + + return StatusCode::SUCCESS; + } +}; + +DECLARE_COMPONENT(CrystalEndcapsReco) + +} // namespace Jug::Reco + + diff --git a/JugReco/tests/options/example_crystalendcapsreco.py b/JugReco/tests/options/example_crystalendcapsreco.py index e091016a..2ab6ff0e 100644 --- a/JugReco/tests/options/example_crystalendcapsreco.py +++ b/JugReco/tests/options/example_crystalendcapsreco.py @@ -2,23 +2,28 @@ from Gaudi.Configuration import * from GaudiKernel.DataObjectHandleBase import DataObjectHandleBase from Configurables import ApplicationMgr, EICDataSvc, PodioOutput, GeoSvc +from GaudiKernel import SystemOfUnits as units geo_service = GeoSvc("GeoSvc", detectors=["../NPDet/src/GenericDetectors/calorimeters/compact/Crystal_example.xml"]) podioevent = EICDataSvc("EventDataSvc", inputs=["output_emcal_electrons_npsim.root"], OutputLevel=DEBUG) from Configurables import PodioInput -from Configurables import Jug__Reco__CalorimeterIslandCluster as IslandCluster from Configurables import Jug__Digi__CrystalEndcapsDigi as CrystalEndcapsDigi +from Configurables import Jug__Reco__CrystalEndcapsReco as CrystalEndcapsReco +from Configurables import Jug__Reco__CalorimeterIslandCluster as IslandCluster podioinput = PodioInput("PodioReader", collections=["mcparticles","EcalHits"], OutputLevel=DEBUG) emcaldigi = CrystalEndcapsDigi(inputHitCollection="EcalHits", outputHitCollection="RawDigiEcalHits") -emcalcluster = IslandCluster(inputHitCollection="RawDigiEcalHits", outputClusterCollection="EcalClusters") +emcalreco = CrystalEndcapsReco(inputHitCollection="RawDigiEcalHits", outputHitCollection="RecoEcalHits", + minModuleEdep=1.0*units.MeV) +emcalcluster = IslandCluster(inputHitCollection="RecoEcalHits", outputClusterCollection="EcalClusters", + minClusterCenterEdep=30*units.MeV, groupRange=2.0) out = PodioOutput("out", filename="reco_emcal_electrons_npsim.root") out.outputCommands = ["keep EcalClusters"] ApplicationMgr( - TopAlg = [podioinput, emcaldigi, emcalcluster, out], + TopAlg = [podioinput, emcaldigi, emcalreco, emcalcluster, out], EvtSel = 'NONE', EvtMax = 100, ExtSvc = [podioevent], -- GitLab