From 7354cc10328e84ab91f3282c36da08a445f5b967 Mon Sep 17 00:00:00 2001 From: Dmitry Kalinkin Date: Thu, 3 Aug 2023 18:31:09 -0400 Subject: [PATCH] algorithms/calorimetry/CalorimeterIslandCluster: pass PODIO collections instead of std::vector (#791) Follow up to #741 --- .../calorimetry/CalorimeterIslandCluster.cc | 110 +++++--- .../calorimetry/CalorimeterIslandCluster.h | 162 +++-------- ...luster_factory_B0ECalIslandProtoClusters.h | 11 +- ...ster_factory_EcalBarrelScFiProtoClusters.h | 11 +- ...er_factory_HcalBarrelIslandProtoClusters.h | 11 +- ...r_factory_EcalEndcapNIslandProtoClusters.h | 11 +- ...r_factory_HcalEndcapNIslandProtoClusters.h | 11 +- ...ory_EcalEndcapPInsertIslandProtoClusters.h | 11 +- ...r_factory_EcalEndcapPIslandProtoClusters.h | 11 +- ...ory_HcalEndcapPInsertIslandProtoClusters.h | 11 +- ...r_factory_HcalEndcapPIslandProtoClusters.h | 11 +- ...luster_factory_LFHCALIslandProtoClusters.h | 11 +- ..._factory_EcalLumiSpecIslandProtoClusters.h | 11 +- ...uster_factory_ZDCEcalIslandProtoClusters.h | 11 +- .../calorimetry_CalorimeterIslandCluster.cc | 262 +++++++++--------- 15 files changed, 295 insertions(+), 371 deletions(-) diff --git a/src/algorithms/calorimetry/CalorimeterIslandCluster.cc b/src/algorithms/calorimetry/CalorimeterIslandCluster.cc index fa5df917af..70d29a50f2 100644 --- a/src/algorithms/calorimetry/CalorimeterIslandCluster.cc +++ b/src/algorithms/calorimetry/CalorimeterIslandCluster.cc @@ -1,8 +1,8 @@ -// Copyright 2022, David Lawrence -// Subject to the terms in the LICENSE file found in the top-level directory. -// -// Sections Copyright (C) 2023 Chao Peng, Wouter Deconinck, Sylvester Joosten, Dmitry Kalinkin -// under SPDX-License-Identifier: LGPL-3.0-or-later +// Copyright (C) 2022, 2023 Chao Peng, Wouter Deconinck, Sylvester Joosten, Dmitry Kalinkin, David Lawrence +// SPDX-License-Identifier: LGPL-3.0-or-later + +#include +#include #include "CalorimeterIslandCluster.h" @@ -20,19 +20,51 @@ using namespace edm4eic; -// -// This algorithm converted from: -// -// https://eicweb.phy.anl.gov/EIC/juggler/-/blob/master/JugDigi/src/components/CalorimeterHitDigi.cpp -// -// TODO: -// - Array type configuration parameters are not yet supported in JANA (needs to be added) -// - Random number service needs to bew resolved (on global scale) -// - It is possible standard running of this with Gaudi relied on a number of parameters -// being set in the config. If that is the case, they should be moved into the default -// values here. This needs to be confirmed. +static double Phi_mpi_pi(double phi) { + return std::remainder(phi, 2 * M_PI); +} +static edm4hep::Vector2f localDistXY(const CaloHit &h1, const CaloHit &h2) { + const auto delta =h1.getLocal() - h2.getLocal(); + return {delta.x, delta.y}; +} +static edm4hep::Vector2f localDistXZ(const CaloHit &h1, const CaloHit &h2) { + const auto delta = h1.getLocal() - h2.getLocal(); + return {delta.x, delta.z}; +} +static edm4hep::Vector2f localDistYZ(const CaloHit &h1, const CaloHit &h2) { + const auto delta = h1.getLocal() - h2.getLocal(); + return {delta.y, delta.z}; +} +static edm4hep::Vector2f dimScaledLocalDistXY(const CaloHit &h1, const CaloHit &h2) { + const auto delta = h1.getLocal() - h2.getLocal(); + const auto dimsum = h1.getDimension() + h2.getDimension(); + + return {2 * delta.x / dimsum.x, 2 * delta.y / dimsum.y}; +} +static edm4hep::Vector2f globalDistRPhi(const CaloHit &h1, const CaloHit &h2) { + using vector_type = decltype(edm4hep::Vector2f::a); + return { + static_cast( + edm4eic::magnitude(h1.getPosition()) - edm4eic::magnitude(h2.getPosition()) + ), + static_cast( + Phi_mpi_pi(edm4eic::angleAzimuthal(h1.getPosition()) - edm4eic::angleAzimuthal(h2.getPosition())) + ) + }; +} +static edm4hep::Vector2f globalDistEtaPhi(const CaloHit &h1, const CaloHit &h2) { + using vector_type = decltype(edm4hep::Vector2f::a); + return { + static_cast( + edm4eic::eta(h1.getPosition()) - edm4eic::eta(h2.getPosition()) + ), + static_cast( + Phi_mpi_pi(edm4eic::angleAzimuthal(h1.getPosition()) - edm4eic::angleAzimuthal(h2.getPosition())) + ) + }; +} //------------------------ // AlgorithmInit @@ -59,7 +91,7 @@ void CalorimeterIslandCluster::AlgorithmInit(std::shared_ptr& lo m_log=logger; static std::map, std::vector>> + std::tuple, std::vector>> distMethods{ {"localDistXY", {localDistXY, {dd4hep::mm, dd4hep::mm}}}, {"localDistXZ", {localDistXZ, {dd4hep::mm, dd4hep::mm}}}, {"localDistYZ", {localDistYZ, {dd4hep::mm, dd4hep::mm}}}, {"dimScaledLocalDistXY", {dimScaledLocalDistXY, {1., 1.}}}, @@ -111,15 +143,15 @@ void CalorimeterIslandCluster::AlgorithmInit(std::shared_ptr& lo m_log->error("readoutClass is not provided, it is needed to know the fields in readout ids"); } m_idSpec = m_geoSvc->detector()->readout(m_readout).idSpec(); - is_neighbour = [this](const CaloHit* h1, const CaloHit* h2) { + is_neighbour = [this](const CaloHit &h1, const CaloHit &h2) { dd4hep::tools::Evaluator::Object evaluator; for(const auto &p : m_idSpec.fields()) { const std::string &name = p.first; const dd4hep::IDDescriptor::Field* field = p.second; - evaluator.setVariable((name + "_1").c_str(), field->value(h1->getCellID())); - evaluator.setVariable((name + "_2").c_str(), field->value(h2->getCellID())); - m_log->trace("setVariable(\"{}_1\", {});", name, field->value(h1->getCellID())); - m_log->trace("setVariable(\"{}_2\", {});", name, field->value(h2->getCellID())); + evaluator.setVariable((name + "_1").c_str(), field->value(h1.getCellID())); + evaluator.setVariable((name + "_2").c_str(), field->value(h2.getCellID())); + m_log->trace("setVariable(\"{}_1\", {});", name, field->value(h1.getCellID())); + m_log->trace("setVariable(\"{}_2\", {});", name, field->value(h2.getCellID())); } dd4hep::tools::Evaluator::Object::EvalStatus eval = evaluator.evaluate(u_adjacencyMatrix.c_str()); if (eval.status()) { @@ -139,16 +171,16 @@ void CalorimeterIslandCluster::AlgorithmInit(std::shared_ptr& lo if (set_dist_method(uprop)) { method_found = true; - is_neighbour = [this](const CaloHit* h1, const CaloHit* h2) { + is_neighbour = [this](const CaloHit &h1, const CaloHit &h2) { // in the same sector - if (h1->getSector() == h2->getSector()) { + if (h1.getSector() == h2.getSector()) { auto dist = hitsDist(h1, h2); return (fabs(dist.a) <= neighbourDist[0]) && (fabs(dist.b) <= neighbourDist[1]); // different sector, local coordinates do not work, using global coordinates } else { // sector may have rotation (barrel), so z is included // (EDM4hep units are mm, so convert sectorDist to mm) - return (edm4eic::magnitude(h1->getPosition() - h2->getPosition()) <= m_sectorDist / dd4hep::mm); + return (edm4eic::magnitude(h1.getPosition() - h2.getPosition()) <= m_sectorDist / dd4hep::mm); } }; @@ -184,33 +216,21 @@ void CalorimeterIslandCluster::AlgorithmInit(std::shared_ptr& lo // AlgorithmChangeRun //------------------------ void CalorimeterIslandCluster::AlgorithmChangeRun() { - /// This is automatically run before Process, when a new run number is seen - /// Usually we update our calibration constants by asking a JService - /// to give us the latest data for this run number } //------------------------ // AlgorithmProcess //------------------------ -void CalorimeterIslandCluster::AlgorithmProcess() { -// input collections - //const auto& hits = event - // Create output collections - //auto& proto = *(m_outputProtoCollection.createAndPut()); - +std::unique_ptr CalorimeterIslandCluster::AlgorithmProcess(const edm4eic::CalorimeterHitCollection &hits) { // group neighboring hits - std::vector>> groups; - - //FIXME: protocluster collection to this? - std::vector proto; + std::vector> groups; std::vector visits(hits.size(), false); - //TODO: use the right logger for (size_t i = 0; i < hits.size(); ++i) { { const auto& hit = hits[i]; - m_log->debug("hit {:d}: energy = {:.4f} MeV, local = ({:.4f}, {:.4f}) mm, global=({:.4f}, {:.4f}, {:.4f}) mm", i, hit->getEnergy() * 1000., hit->getLocal().x, hit->getLocal().y, hit->getPosition().x, hit->getPosition().y, hit->getPosition().z); + m_log->debug("hit {:d}: energy = {:.4f} MeV, local = ({:.4f}, {:.4f}) mm, global=({:.4f}, {:.4f}, {:.4f}) mm", i, hit.getEnergy() * 1000., hit.getLocal().x, hit.getLocal().y, hit.getPosition().x, hit.getPosition().y, hit.getPosition().z); } // already in a group if (visits[i]) { @@ -218,19 +238,21 @@ void CalorimeterIslandCluster::AlgorithmProcess() { } groups.emplace_back(); // create a new group, and group all the neighboring hits - dfs_group(groups.back(), i, hits, visits); + dfs_group(hits, groups.back(), i, visits); } + auto protoClusters = std::make_unique(); + for (auto& group : groups) { if (group.empty()) { continue; } - auto maxima = find_maxima(group, !m_splitCluster); - split_group(group, maxima, protoClusters); + auto maxima = find_maxima(hits, group, !m_splitCluster); + split_group(hits, group, maxima, protoClusters.get()); m_log->debug("hits in a group: {}, local maxima: {}", group.size(), maxima.size()); } - return; + return protoClusters; } diff --git a/src/algorithms/calorimetry/CalorimeterIslandCluster.h b/src/algorithms/calorimetry/CalorimeterIslandCluster.h index d778fb84d6..5194df2617 100644 --- a/src/algorithms/calorimetry/CalorimeterIslandCluster.h +++ b/src/algorithms/calorimetry/CalorimeterIslandCluster.h @@ -1,100 +1,32 @@ -// Copyright 2022, Thomas Britton -// Subject to the terms in the LICENSE file found in the top-level directory. -// -// Sections Copyright (C) 2022 Chao Peng, Wouter Deconinck, Sylvester Joosten -// under SPDX-License-Identifier: LGPL-3.0-or-later +// Copyright (C) 2022, 2023 Chao Peng, Wouter Deconinck, Sylvester Joosten, Thomas Britton +// SPDX-License-Identifier: LGPL-3.0-or-later #pragma once #include +#include #include "services/geometry/dd4hep/JDD4hep_service.h" -//#include "services/randomgenerator/randomGenerator.h" + #include #include -#include -#include -#include +#include #include -#include -#include +#include #include using CaloHit = edm4eic::CalorimeterHit; -static double Phi_mpi_pi(double phi) { - return std::remainder(phi, 2 * M_PI); -} - -//TODO:Reconcile edm4hep::Vector2f and edm4eic::Vector3f especially with regards to the operators and sign convention -static edm4hep::Vector2f localDistXY(const CaloHit *h1, const CaloHit *h2) { - //edm4eic::Vector3f h1_pos=geo_converter->position(h1.getCellID()); - //edm4eic::Vector3f h2_pos=geo_converter->position(h2.getCellID()); - const auto delta =h1->getLocal() - h2->getLocal(); - return {delta.x, delta.y}; - //const auto deltax = h1.getLocal()[0] - h2.getLocal()[0]; - //const auto deltay = h1.getLocal()[1] - h2.getLocal()[1]; - //return {delta.x, delta.y,0}; - //return {deltax,deltay}; -} -static edm4hep::Vector2f localDistXZ(const CaloHit *h1, const CaloHit *h2) { - const auto delta = h1->getLocal() - h2->getLocal(); - //const auto deltax = h1.getLocal()[0] - h2.getLocal()[0]; - //const auto deltaz = h1.getLocal()[2] - h2.getLocal()[2]; - return {delta.x, delta.z}; -} -static edm4hep::Vector2f localDistYZ(const CaloHit *h1, const CaloHit *h2) { - const auto delta = h1->getLocal() - h2->getLocal(); - //const auto deltay = h1.getLocal()[1] - h2.getLocal()[1]; - //const auto deltaz = h1.getLocal()[2] - h2.getLocal()[2]; - return {delta.y, delta.z}; -} -static edm4hep::Vector2f dimScaledLocalDistXY(const CaloHit *h1, const CaloHit *h2) { - const auto delta = h1->getLocal() - h2->getLocal(); - //const auto deltax = h1.getLocal()[0] - h2.getLocal()[0]; - //const auto deltay = h1.getLocal()[1] - h2.getLocal()[1]; - - const auto dimsum = h1->getDimension() + h2->getDimension(); - //const auto dimsumx = h1.getDimension()[0] + h2.getDimension()[0]; - //const auto dimsumy = h1.getDimension()[1] + h2.getDimension()[1]; - - return {2 * delta.x / dimsum.x, 2 * delta.y / dimsum.y}; -} -static edm4hep::Vector2f globalDistRPhi(const CaloHit *h1, const CaloHit *h2) { - using vector_type = decltype(edm4hep::Vector2f::a); - return { - static_cast( - edm4eic::magnitude(h1->getPosition()) - edm4eic::magnitude(h2->getPosition()) - ), - static_cast( - Phi_mpi_pi(edm4eic::angleAzimuthal(h1->getPosition()) - edm4eic::angleAzimuthal(h2->getPosition())) - ) - }; -} -static edm4hep::Vector2f globalDistEtaPhi(const CaloHit *h1, - const CaloHit *h2) { - using vector_type = decltype(edm4hep::Vector2f::a); - return { - static_cast( - edm4eic::eta(h1->getPosition()) - edm4eic::eta(h2->getPosition()) - ), - static_cast( - Phi_mpi_pi(edm4eic::angleAzimuthal(h1->getPosition()) - edm4eic::angleAzimuthal(h2->getPosition())) - ) - }; -} - class CalorimeterIslandCluster { // Insert any member variables here public: CalorimeterIslandCluster() = default; - virtual ~CalorimeterIslandCluster(){} // better to use smart pointer? - virtual void AlgorithmInit(std::shared_ptr& logger); - virtual void AlgorithmChangeRun() ; - virtual void AlgorithmProcess() ; + void AlgorithmInit(std::shared_ptr& logger); + void AlgorithmChangeRun(); + std::unique_ptr AlgorithmProcess(const edm4eic::CalorimeterHitCollection &hits); //-------- Configuration Parameters ------------ //instantiate new spdlog logger @@ -116,18 +48,18 @@ class CalorimeterIslandCluster { std::vector u_globalDistEtaPhi;//{this, "globalDistEtaPhi", {}}; std::vector u_dimScaledLocalDistXY;//{this, "dimScaledLocalDistXY", {1.8, 1.8}}; // neighbor checking function - std::function hitsDist; + std::function hitsDist; bool m_splitCluster = false; double m_minClusterHitEdep; double m_minClusterCenterEdep; std::string u_transverseEnergyProfileMetric; - std::function transverseEnergyProfileMetric; + std::function transverseEnergyProfileMetric; double u_transverseEnergyProfileScale; double transverseEnergyProfileScaleUnits; // helper function to group hits - std::function is_neighbour; + std::function is_neighbour; // unitless counterparts of the input parameters std::array neighbourDist; @@ -143,74 +75,68 @@ class CalorimeterIslandCluster { //Rndm::Numbers m_normDist; uint64_t id_mask, ref_mask; - // inputs/outputs - std::vector hits; - std::vector protoClusters; - private: std::default_random_engine generator; // TODO: need something more appropriate here std::normal_distribution m_normDist; // defaults to mean=0, sigma=1 // grouping function with Depth-First Search //TODO: confirm grouping without calohitcollection - void dfs_group(std::vector>& group, int idx, - std::vector hits, std::vector& visits) const { + void dfs_group(const edm4eic::CalorimeterHitCollection &hits, std::set &group, std::size_t idx, std::vector &visits) const { // not a qualified hit to particpate clustering, stop here - if (hits[idx]->getEnergy() < m_minClusterHitEdep) { + if (hits[idx].getEnergy() < m_minClusterHitEdep) { visits[idx] = true; return; } - group.emplace_back(idx, hits[idx]); + group.insert(idx); visits[idx] = true; for (size_t i = 0; i < hits.size(); ++i) { if (visits[i] || !is_neighbour(hits[idx], hits[i])) { continue; } - dfs_group(group, i, hits, visits); + dfs_group(hits, group, i, visits); } } // find local maxima that above a certain threshold - std::vector find_maxima(const std::vector>& group, - bool global = false) const { - std::vector maxima; + std::vector find_maxima(const edm4eic::CalorimeterHitCollection &hits, const std::set &group, bool global = false) const { + std::vector maxima; if (group.empty()) { return maxima; } if (global) { - int mpos = 0; - for (size_t i = 0; i < group.size(); ++i) { - if (group[mpos].second->getEnergy() < group[i].second->getEnergy()) { - mpos = i; + std::size_t mpos = *group.begin(); + for (auto idx : group) { + if (hits[mpos].getEnergy() < hits[idx].getEnergy()) { + mpos = idx; } } - if (group[mpos].second->getEnergy() >= m_minClusterCenterEdep) { - maxima.push_back(group[mpos].second); + if (hits[mpos].getEnergy() >= m_minClusterCenterEdep) { + maxima.push_back(mpos); } return maxima; } - for (const auto& [idx, hit] : group) { + for (std::size_t idx1 : group) { // not a qualified center - if (hit->getEnergy() < m_minClusterCenterEdep) { + if (hits[idx1].getEnergy() < m_minClusterCenterEdep) { continue; } bool maximum = true; - for (const auto& [idx2, hit2] : group) { - if (*hit == *hit2) { + for (std::size_t idx2 : group) { + if (idx1 == idx2) { continue; } - if (is_neighbour(hit, hit2) && (hit2->getEnergy() > hit->getEnergy())) { + if (is_neighbour(hits[idx1], hits[idx2]) && (hits[idx2].getEnergy() > hits[idx1].getEnergy())) { maximum = false; break; } } if (maximum) { - maxima.push_back(hit); + maxima.push_back(idx1); } } @@ -229,20 +155,17 @@ class CalorimeterIslandCluster { // split a group of hits according to the local maxima //TODO: confirm protoclustering without protoclustercollection - void split_group(std::vector>& group, const std::vector& maxima, - - std::vector& proto) const { + void split_group(const edm4eic::CalorimeterHitCollection &hits, std::set& group, const std::vector& maxima, edm4eic::ProtoClusterCollection *protoClusters) const { // special cases if (maxima.empty()) { m_log->debug("No maxima found, not building any clusters"); return; } else if (maxima.size() == 1) { - edm4eic::MutableProtoCluster pcl; - for (auto& [idx, hit] : group) { - pcl.addToHits(*hit); + edm4eic::MutableProtoCluster pcl = protoClusters->create(); + for (std::size_t idx : group) { + pcl.addToHits(hits[idx]); pcl.addToWeights(1.); } - proto.push_back(new edm4eic::ProtoCluster(pcl)); // TODO: Should we be using clone() here? m_log->debug("A single maximum found, added one ProtoCluster"); @@ -254,16 +177,15 @@ class CalorimeterIslandCluster { std::vector weights(maxima.size(), 1.); std::vector pcls; for (size_t k = 0; k < maxima.size(); ++k) { - pcls.emplace_back(); + pcls.push_back(protoClusters->create()); } - size_t i = 0; - for (const auto& [idx, hit] : group) { + for (std::size_t idx : group) { size_t j = 0; // calculate weights for local maxima - for (const auto& chit : maxima) { - double energy = chit->getEnergy(); - double dist = edm4eic::magnitude(transverseEnergyProfileMetric(chit, hit)); + for (std::size_t cidx : maxima) { + double energy = hits[cidx].getEnergy(); + double dist = edm4eic::magnitude(transverseEnergyProfileMetric(hits[cidx], hits[idx])); weights[j] = std::exp(-dist * transverseEnergyProfileScaleUnits / u_transverseEnergyProfileScale) * energy; j += 1; } @@ -285,13 +207,9 @@ class CalorimeterIslandCluster { if (weight <= 1e-6) { continue; } - pcls[k].addToHits(*hit); + pcls[k].addToHits(hits[idx]); pcls[k].addToWeights(weight); } - i += 1; - } - for (auto& pcl : pcls) { - proto.push_back(new edm4eic::ProtoCluster(pcl)); // TODO: Should we be using clone() here? } m_log->debug("Multiple ({}) maxima found, added a ProtoClusters for each maximum", maxima.size()); } diff --git a/src/detectors/B0ECAL/ProtoCluster_factory_B0ECalIslandProtoClusters.h b/src/detectors/B0ECAL/ProtoCluster_factory_B0ECalIslandProtoClusters.h index 95e0942536..c5fc462ccd 100644 --- a/src/detectors/B0ECAL/ProtoCluster_factory_B0ECalIslandProtoClusters.h +++ b/src/detectors/B0ECAL/ProtoCluster_factory_B0ECalIslandProtoClusters.h @@ -81,14 +81,13 @@ class ProtoCluster_factory_B0ECalIslandProtoClusters : public JChainFactoryT &event) override{ - // Prefill inputs - hits = event->Get(GetInputTags()[0]); + // Get input collection + auto hits_coll = static_cast(event->GetCollectionBase(GetInputTags()[0])); // Call Process for generic algorithm - AlgorithmProcess(); + auto protoclust_coll = AlgorithmProcess(*hits_coll); - // Hand owner of algorithm objects over to JANA - Set(protoClusters); - protoClusters.clear(); // not really needed, but better to not leave dangling pointers around + // Hand algorithm objects over to JANA + SetCollection(std::move(protoclust_coll)); } }; diff --git a/src/detectors/BEMC/ProtoCluster_factory_EcalBarrelScFiProtoClusters.h b/src/detectors/BEMC/ProtoCluster_factory_EcalBarrelScFiProtoClusters.h index 09bc135ff8..8b0aee0c95 100644 --- a/src/detectors/BEMC/ProtoCluster_factory_EcalBarrelScFiProtoClusters.h +++ b/src/detectors/BEMC/ProtoCluster_factory_EcalBarrelScFiProtoClusters.h @@ -77,14 +77,13 @@ class ProtoCluster_factory_EcalBarrelScFiProtoClusters : public JChainFactoryT &event) override{ - // Prefill inputs - hits = event->Get(GetInputTags()[0]); + // Get input collection + auto hits_coll = static_cast(event->GetCollectionBase(GetInputTags()[0])); // Call Process for generic algorithm - AlgorithmProcess(); + auto protoclust_coll = AlgorithmProcess(*hits_coll); - // Hand owner of algorithm objects over to JANA - Set(protoClusters); - protoClusters.clear(); // not really needed, but better to not leave dangling pointers around + // Hand algorithm objects over to JANA + SetCollection(std::move(protoclust_coll)); } }; diff --git a/src/detectors/BHCAL/ProtoCluster_factory_HcalBarrelIslandProtoClusters.h b/src/detectors/BHCAL/ProtoCluster_factory_HcalBarrelIslandProtoClusters.h index ca66c6b694..afe654b7be 100644 --- a/src/detectors/BHCAL/ProtoCluster_factory_HcalBarrelIslandProtoClusters.h +++ b/src/detectors/BHCAL/ProtoCluster_factory_HcalBarrelIslandProtoClusters.h @@ -93,14 +93,13 @@ class ProtoCluster_factory_HcalBarrelIslandProtoClusters : public JChainFactoryT //------------------------------------------ // Process void Process(const std::shared_ptr &event) override{ - // Prefill inputs - hits = event->Get(GetInputTags()[0]); + // Get input collection + auto hits_coll = static_cast(event->GetCollectionBase(GetInputTags()[0])); // Call Process for generic algorithm - AlgorithmProcess(); + auto protoclust_coll = AlgorithmProcess(*hits_coll); - // Hand owner of algorithm objects over to JANA - Set(protoClusters); - protoClusters.clear(); // not really needed, but better to not leave dangling pointers around + // Hand algorithm objects over to JANA + SetCollection(std::move(protoclust_coll)); } }; diff --git a/src/detectors/EEMC/ProtoCluster_factory_EcalEndcapNIslandProtoClusters.h b/src/detectors/EEMC/ProtoCluster_factory_EcalEndcapNIslandProtoClusters.h index 5ef547f591..4a865725b0 100644 --- a/src/detectors/EEMC/ProtoCluster_factory_EcalEndcapNIslandProtoClusters.h +++ b/src/detectors/EEMC/ProtoCluster_factory_EcalEndcapNIslandProtoClusters.h @@ -81,14 +81,13 @@ class ProtoCluster_factory_EcalEndcapNIslandProtoClusters : public JChainFactory //------------------------------------------ // Process void Process(const std::shared_ptr &event) override{ - // Prefill inputs - hits = event->Get(GetInputTags()[0]); + // Get input collection + auto hits_coll = static_cast(event->GetCollectionBase(GetInputTags()[0])); // Call Process for generic algorithm - AlgorithmProcess(); + auto protoclust_coll = AlgorithmProcess(*hits_coll); - // Hand owner of algorithm objects over to JANA - Set(protoClusters); - protoClusters.clear(); // not really needed, but better to not leave dangling pointers around + // Hand algorithm objects over to JANA + SetCollection(std::move(protoclust_coll)); } }; diff --git a/src/detectors/EHCAL/ProtoCluster_factory_HcalEndcapNIslandProtoClusters.h b/src/detectors/EHCAL/ProtoCluster_factory_HcalEndcapNIslandProtoClusters.h index e2121fe820..3a8362fea0 100644 --- a/src/detectors/EHCAL/ProtoCluster_factory_HcalEndcapNIslandProtoClusters.h +++ b/src/detectors/EHCAL/ProtoCluster_factory_HcalEndcapNIslandProtoClusters.h @@ -81,14 +81,13 @@ class ProtoCluster_factory_HcalEndcapNIslandProtoClusters : public JChainFactory //------------------------------------------ // Process void Process(const std::shared_ptr &event) override{ - // Prefill inputs - hits = event->Get(GetInputTags()[0]); + // Get input collection + auto hits_coll = static_cast(event->GetCollectionBase(GetInputTags()[0])); // Call Process for generic algorithm - AlgorithmProcess(); + auto protoclust_coll = AlgorithmProcess(*hits_coll); - // Hand owner of algorithm objects over to JANA - Set(protoClusters); - protoClusters.clear(); // not really needed, but better to not leave dangling pointers around + // Hand algorithm objects over to JANA + SetCollection(std::move(protoclust_coll)); } }; diff --git a/src/detectors/FEMC/ProtoCluster_factory_EcalEndcapPInsertIslandProtoClusters.h b/src/detectors/FEMC/ProtoCluster_factory_EcalEndcapPInsertIslandProtoClusters.h index 657ff04f72..af9c9ceec3 100644 --- a/src/detectors/FEMC/ProtoCluster_factory_EcalEndcapPInsertIslandProtoClusters.h +++ b/src/detectors/FEMC/ProtoCluster_factory_EcalEndcapPInsertIslandProtoClusters.h @@ -81,14 +81,13 @@ class ProtoCluster_factory_EcalEndcapPInsertIslandProtoClusters : public JChainF //------------------------------------------ // Process void Process(const std::shared_ptr &event) override{ - // Prefill inputs - hits = event->Get(GetInputTags()[0]); + // Get input collection + auto hits_coll = static_cast(event->GetCollectionBase(GetInputTags()[0])); // Call Process for generic algorithm - AlgorithmProcess(); + auto protoclust_coll = AlgorithmProcess(*hits_coll); - // Hand owner of algorithm objects over to JANA - Set(protoClusters); - protoClusters.clear(); // not really needed, but better to not leave dangling pointers around + // Hand algorithm objects over to JANA + SetCollection(std::move(protoclust_coll)); } }; diff --git a/src/detectors/FEMC/ProtoCluster_factory_EcalEndcapPIslandProtoClusters.h b/src/detectors/FEMC/ProtoCluster_factory_EcalEndcapPIslandProtoClusters.h index 38d56d9922..a4dcbd069d 100644 --- a/src/detectors/FEMC/ProtoCluster_factory_EcalEndcapPIslandProtoClusters.h +++ b/src/detectors/FEMC/ProtoCluster_factory_EcalEndcapPIslandProtoClusters.h @@ -81,14 +81,13 @@ class ProtoCluster_factory_EcalEndcapPIslandProtoClusters : public JChainFactory //------------------------------------------ // Process void Process(const std::shared_ptr &event) override{ - // Prefill inputs - hits = event->Get(GetInputTags()[0]); + // Get input collection + auto hits_coll = static_cast(event->GetCollectionBase(GetInputTags()[0])); // Call Process for generic algorithm - AlgorithmProcess(); + auto protoclust_coll = AlgorithmProcess(*hits_coll); - // Hand owner of algorithm objects over to JANA - Set(protoClusters); - protoClusters.clear(); // not really needed, but better to not leave dangling pointers around + // Hand algorithm objects over to JANA + SetCollection(std::move(protoclust_coll)); } }; diff --git a/src/detectors/FHCAL/ProtoCluster_factory_HcalEndcapPInsertIslandProtoClusters.h b/src/detectors/FHCAL/ProtoCluster_factory_HcalEndcapPInsertIslandProtoClusters.h index d3b8a27402..16f6374aff 100644 --- a/src/detectors/FHCAL/ProtoCluster_factory_HcalEndcapPInsertIslandProtoClusters.h +++ b/src/detectors/FHCAL/ProtoCluster_factory_HcalEndcapPInsertIslandProtoClusters.h @@ -81,14 +81,13 @@ class ProtoCluster_factory_HcalEndcapPInsertIslandProtoClusters : public JChainF //------------------------------------------ // Process void Process(const std::shared_ptr &event) override{ - // Prefill inputs - hits = event->Get(GetInputTags()[0]); + // Get input collection + auto hits_coll = static_cast(event->GetCollectionBase(GetInputTags()[0])); // Call Process for generic algorithm - AlgorithmProcess(); + auto protoclust_coll = AlgorithmProcess(*hits_coll); - // Hand owner of algorithm objects over to JANA - Set(protoClusters); - protoClusters.clear(); // not really needed, but better to not leave dangling pointers around + // Hand algorithm objects over to JANA + SetCollection(std::move(protoclust_coll)); } }; diff --git a/src/detectors/FHCAL/ProtoCluster_factory_HcalEndcapPIslandProtoClusters.h b/src/detectors/FHCAL/ProtoCluster_factory_HcalEndcapPIslandProtoClusters.h index 5d4d15f4ad..4dd8796493 100644 --- a/src/detectors/FHCAL/ProtoCluster_factory_HcalEndcapPIslandProtoClusters.h +++ b/src/detectors/FHCAL/ProtoCluster_factory_HcalEndcapPIslandProtoClusters.h @@ -81,14 +81,13 @@ class ProtoCluster_factory_HcalEndcapPIslandProtoClusters : public JChainFactory //------------------------------------------ // Process void Process(const std::shared_ptr &event) override{ - // Prefill inputs - hits = event->Get(GetInputTags()[0]); + // Get input collection + auto hits_coll = static_cast(event->GetCollectionBase(GetInputTags()[0])); // Call Process for generic algorithm - AlgorithmProcess(); + auto protoclust_coll = AlgorithmProcess(*hits_coll); - // Hand owner of algorithm objects over to JANA - Set(protoClusters); - protoClusters.clear(); // not really needed, but better to not leave dangling pointers around + // Hand algorithm objects over to JANA + SetCollection(std::move(protoclust_coll)); } }; diff --git a/src/detectors/FHCAL/ProtoCluster_factory_LFHCALIslandProtoClusters.h b/src/detectors/FHCAL/ProtoCluster_factory_LFHCALIslandProtoClusters.h index a6ab80bd48..ef9684de6b 100644 --- a/src/detectors/FHCAL/ProtoCluster_factory_LFHCALIslandProtoClusters.h +++ b/src/detectors/FHCAL/ProtoCluster_factory_LFHCALIslandProtoClusters.h @@ -106,15 +106,14 @@ class ProtoCluster_factory_LFHCALIslandProtoClusters : public JChainFactoryT &event) override{ - // Prefill inputs - hits = event->Get(GetInputTags()[0]); + // Get input collection + auto hits_coll = static_cast(event->GetCollectionBase(GetInputTags()[0])); // Call Process for generic algorithm - AlgorithmProcess(); + auto protoclust_coll = AlgorithmProcess(*hits_coll); - // Hand owner of algorithm objects over to JANA - Set(protoClusters); - protoClusters.clear(); // not really needed, but better to not leave dangling pointers around + // Hand algorithm objects over to JANA + SetCollection(std::move(protoclust_coll)); } }; diff --git a/src/detectors/LUMISPECCAL/ProtoCluster_factory_EcalLumiSpecIslandProtoClusters.h b/src/detectors/LUMISPECCAL/ProtoCluster_factory_EcalLumiSpecIslandProtoClusters.h index d92ed62d45..9ccd9be10e 100644 --- a/src/detectors/LUMISPECCAL/ProtoCluster_factory_EcalLumiSpecIslandProtoClusters.h +++ b/src/detectors/LUMISPECCAL/ProtoCluster_factory_EcalLumiSpecIslandProtoClusters.h @@ -81,14 +81,13 @@ class ProtoCluster_factory_EcalLumiSpecIslandProtoClusters : public JChainFactor //------------------------------------------ // Process void Process(const std::shared_ptr &event) override{ - // Prefill inputs - hits = event->Get(GetInputTags()[0]); + // Get input collection + auto hits_coll = static_cast(event->GetCollectionBase(GetInputTags()[0])); // Call Process for generic algorithm - AlgorithmProcess(); + auto protoclust_coll = AlgorithmProcess(*hits_coll); - // Hand owner of algorithm objects over to JANA - Set(protoClusters); - protoClusters.clear(); // not really needed, but better to not leave dangling pointers around + // Hand algorithm objects over to JANA + SetCollection(std::move(protoclust_coll)); } }; diff --git a/src/detectors/ZDC/ProtoCluster_factory_ZDCEcalIslandProtoClusters.h b/src/detectors/ZDC/ProtoCluster_factory_ZDCEcalIslandProtoClusters.h index 378179dd1a..a214ea852d 100644 --- a/src/detectors/ZDC/ProtoCluster_factory_ZDCEcalIslandProtoClusters.h +++ b/src/detectors/ZDC/ProtoCluster_factory_ZDCEcalIslandProtoClusters.h @@ -83,14 +83,13 @@ class ProtoCluster_factory_ZDCEcalIslandProtoClusters : public JChainFactoryT &event) override{ - // Prefill inputs - hits = event->Get(GetInputTags()[0]); + // Get input collection + auto hits_coll = static_cast(event->GetCollectionBase(GetInputTags()[0])); // Call Process for generic algorithm - AlgorithmProcess(); + auto protoclust_coll = AlgorithmProcess(*hits_coll); - // Hand owner of algorithm objects over to JANA - Set(protoClusters); - protoClusters.clear(); // not really needed, but better to not leave dangling pointers around + // Hand algorithm objects over to JANA + SetCollection(std::move(protoclust_coll)); } }; diff --git a/src/tests/algorithms_test/calorimetry_CalorimeterIslandCluster.cc b/src/tests/algorithms_test/calorimetry_CalorimeterIslandCluster.cc index 64808e8308..1c3743389d 100644 --- a/src/tests/algorithms_test/calorimetry_CalorimeterIslandCluster.cc +++ b/src/tests/algorithms_test/calorimetry_CalorimeterIslandCluster.cc @@ -26,169 +26,165 @@ TEST_CASE( "the clustering algorithm runs", "[CalorimeterIslandCluster]" ) { algo.AlgorithmChangeRun(); SECTION( "on a single cell" ) { - algo.hits = { - new edm4eic::CalorimeterHit( - 0, // std::uint64_t cellID, - 5.0, // float energy, - 0.0, // float energyError, - 0.0, // float time, - 0.0, // float timeError, - {0.0, 0.0, 0.0}, // edm4hep::Vector3f position, - {0.0, 0.0, 0.0}, // edm4hep::Vector3f dimension, - 0, // std::int32_t sector, - 0, // std::int32_t layer, - {0.0, 0.0, 0.0} // edm4hep::Vector3f local - ) - }; - algo.AlgorithmProcess(); - - REQUIRE( algo.protoClusters.size() == 1 ); - REQUIRE( algo.protoClusters[0]->hits_size() == 1 ); - REQUIRE( algo.protoClusters[0]->weights_size() == 1 ); - } - - SECTION( "on two separated cells" ) { - algo.hits = { - new edm4eic::CalorimeterHit( - 0, // std::uint64_t cellID, - 5.0, // float energy, - 0.0, // float energyError, - 0.0, // float time, - 0.0, // float timeError, - {0.0, 0.0, 0.0}, // edm4hep::Vector3f position, - {1.0, 1.0, 0.0}, // edm4hep::Vector3f dimension, - 0, // std::int32_t sector, - 0, // std::int32_t layer, - {0.0, 0.0, 0.0} // edm4hep::Vector3f local - ), - new edm4eic::CalorimeterHit( - 1, // std::uint64_t cellID, - 6.0, // float energy, - 0.0, // float energyError, - 0.0, // float time, - 0.0, // float timeError, - {0.0, 0.0, 0.0}, // edm4hep::Vector3f position, - {1.0, 1.0, 0.0}, // edm4hep::Vector3f dimension, - 0, // std::int32_t sector, - 0, // std::int32_t layer, - {1.1 /* mm */, 1.1 /* mm */, 0.0} // edm4hep::Vector3f local - ) - }; - algo.AlgorithmProcess(); - - REQUIRE( algo.protoClusters.size() == 2 ); - REQUIRE( algo.protoClusters[0]->hits_size() == 1 ); - REQUIRE( algo.protoClusters[0]->weights_size() == 1 ); - REQUIRE( algo.protoClusters[1]->hits_size() == 1 ); - REQUIRE( algo.protoClusters[1]->weights_size() == 1 ); - } - - SECTION( "on two adjacent cells" ) { - algo.hits = { - new edm4eic::CalorimeterHit( - 0, // std::uint64_t cellID, - 5.0, // float energy, - 0.0, // float energyError, - 0.0, // float time, - 0.0, // float timeError, - {0.0, 0.0, 0.0}, // edm4hep::Vector3f position, - {1.0, 1.0, 0.0}, // edm4hep::Vector3f dimension, - 0, // std::int32_t sector, - 0, // std::int32_t layer, - {0.0, 0.0, 0.0} // edm4hep::Vector3f local - ), - new edm4eic::CalorimeterHit( - 1, // std::uint64_t cellID, - 6.0, // float energy, - 0.0, // float energyError, - 0.0, // float time, - 0.0, // float timeError, - {0.0, 0.0, 0.0}, // edm4hep::Vector3f position, - {1.0, 1.0, 0.0}, // edm4hep::Vector3f dimension, - 0, // std::int32_t sector, - 0, // std::int32_t layer, - {0.9 /* mm */, 0.9 /* mm */, 0.0} // edm4hep::Vector3f local - ) - }; - algo.AlgorithmProcess(); - - REQUIRE( algo.protoClusters.size() == 1 ); - REQUIRE( algo.protoClusters[0]->hits_size() == 2 ); - REQUIRE( algo.protoClusters[0]->weights_size() == 2 ); - } - } + edm4eic::CalorimeterHitCollection hits_coll; + hits_coll.create( + 0, // std::uint64_t cellID, + 5.0, // float energy, + 0.0, // float energyError, + 0.0, // float time, + 0.0, // float timeError, + edm4hep::Vector3f(0.0, 0.0, 0.0), // edm4hep::Vector3f position, + edm4hep::Vector3f(0.0, 0.0, 0.0), // edm4hep::Vector3f dimension, + 0, // std::int32_t sector, + 0, // std::int32_t layer, + edm4hep::Vector3f(0.0, 0.0, 0.0) // edm4hep::Vector3f local + ); + auto protoclust_coll = algo.AlgorithmProcess(hits_coll); - SECTION( "run on three adjacent cells" ) { - SECTION( "with splitting" ) { - algo.m_splitCluster = true; - algo.u_transverseEnergyProfileMetric = "localDistXY"; - algo.u_transverseEnergyProfileScale = std::numeric_limits::infinity(); - } - SECTION( "without splitting" ) { - algo.m_splitCluster = false; + REQUIRE( (*protoclust_coll).size() == 1 ); + REQUIRE( (*protoclust_coll)[0].hits_size() == 1 ); + REQUIRE( (*protoclust_coll)[0].weights_size() == 1 ); } - algo.u_localDistXY = {1 * dd4hep::mm, 1 * dd4hep::mm}; - algo.AlgorithmInit(logger); - algo.AlgorithmChangeRun(); - algo.hits = { - new edm4eic::CalorimeterHit( + SECTION( "on two separated cells" ) { + edm4eic::CalorimeterHitCollection hits_coll; + hits_coll.create( 0, // std::uint64_t cellID, 5.0, // float energy, 0.0, // float energyError, 0.0, // float time, 0.0, // float timeError, - {0.0, 0.0, 0.0}, // edm4hep::Vector3f position, - {1.0, 1.0, 0.0}, // edm4hep::Vector3f dimension, + edm4hep::Vector3f(0.0, 0.0, 0.0), // edm4hep::Vector3f position, + edm4hep::Vector3f(1.0, 1.0, 0.0), // edm4hep::Vector3f dimension, 0, // std::int32_t sector, 0, // std::int32_t layer, - {0.0, 0.0, 0.0} // edm4hep::Vector3f local - ), - new edm4eic::CalorimeterHit( + edm4hep::Vector3f(0.0, 0.0, 0.0) // edm4hep::Vector3f local + ); + hits_coll.create( 1, // std::uint64_t cellID, - 1.0, // float energy, + 6.0, // float energy, 0.0, // float energyError, 0.0, // float time, 0.0, // float timeError, - {0.0, 0.0, 0.0}, // edm4hep::Vector3f position, - {1.0, 1.0, 0.0}, // edm4hep::Vector3f dimension, + edm4hep::Vector3f(0.0, 0.0, 0.0), // edm4hep::Vector3f position, + edm4hep::Vector3f(1.0, 1.0, 0.0), // edm4hep::Vector3f dimension, 0, // std::int32_t sector, 0, // std::int32_t layer, - {0.9 /* mm */, 0.9 /* mm */, 0.0} // edm4hep::Vector3f local - ), - new edm4eic::CalorimeterHit( + edm4hep::Vector3f(1.1 /* mm */, 1.1 /* mm */, 0.0) // edm4hep::Vector3f local + ); + auto protoclust_coll = algo.AlgorithmProcess(hits_coll); + + REQUIRE( (*protoclust_coll).size() == 2 ); + REQUIRE( (*protoclust_coll)[0].hits_size() == 1 ); + REQUIRE( (*protoclust_coll)[0].weights_size() == 1 ); + REQUIRE( (*protoclust_coll)[1].hits_size() == 1 ); + REQUIRE( (*protoclust_coll)[1].weights_size() == 1 ); + } + + SECTION( "on two adjacent cells" ) { + edm4eic::CalorimeterHitCollection hits_coll; + hits_coll.create( + 0, // std::uint64_t cellID, + 5.0, // float energy, + 0.0, // float energyError, + 0.0, // float time, + 0.0, // float timeError, + edm4hep::Vector3f(0.0, 0.0, 0.0), // edm4hep::Vector3f position, + edm4hep::Vector3f(1.0, 1.0, 0.0), // edm4hep::Vector3f dimension, + 0, // std::int32_t sector, + 0, // std::int32_t layer, + edm4hep::Vector3f(0.0, 0.0, 0.0) // edm4hep::Vector3f local + ); + hits_coll.create( 1, // std::uint64_t cellID, 6.0, // float energy, 0.0, // float energyError, 0.0, // float time, 0.0, // float timeError, - {0.0, 0.0, 0.0}, // edm4hep::Vector3f position, - {1.0, 1.0, 0.0}, // edm4hep::Vector3f dimension, + edm4hep::Vector3f(0.0, 0.0, 0.0), // edm4hep::Vector3f position, + edm4hep::Vector3f(1.0, 1.0, 0.0), // edm4hep::Vector3f dimension, 0, // std::int32_t sector, 0, // std::int32_t layer, - {1.8 /* mm */, 1.8 /* mm */, 0.0} // edm4hep::Vector3f local - ) - }; - algo.AlgorithmProcess(); + edm4hep::Vector3f(0.9 /* mm */, 0.9 /* mm */, 0.0) // edm4hep::Vector3f local + ); + auto protoclust_coll = algo.AlgorithmProcess(hits_coll); + + REQUIRE( (*protoclust_coll).size() == 1 ); + REQUIRE( (*protoclust_coll)[0].hits_size() == 2 ); + REQUIRE( (*protoclust_coll)[0].weights_size() == 2 ); + } + } + + SECTION( "run on three adjacent cells" ) { + SECTION( "with splitting" ) { + algo.m_splitCluster = true; + algo.u_transverseEnergyProfileMetric = "localDistXY"; + algo.u_transverseEnergyProfileScale = std::numeric_limits::infinity(); + } + SECTION( "without splitting" ) { + algo.m_splitCluster = false; + } + algo.u_localDistXY = {1 * dd4hep::mm, 1 * dd4hep::mm}; + algo.AlgorithmInit(logger); + algo.AlgorithmChangeRun(); + + edm4eic::CalorimeterHitCollection hits_coll; + hits_coll.create( + 0, // std::uint64_t cellID, + 5.0, // float energy, + 0.0, // float energyError, + 0.0, // float time, + 0.0, // float timeError, + edm4hep::Vector3f(0.0, 0.0, 0.0), // edm4hep::Vector3f position, + edm4hep::Vector3f(1.0, 1.0, 0.0), // edm4hep::Vector3f dimension, + 0, // std::int32_t sector, + 0, // std::int32_t layer, + edm4hep::Vector3f(0.0, 0.0, 0.0) // edm4hep::Vector3f local + ); + hits_coll.create( + 1, // std::uint64_t cellID, + 1.0, // float energy, + 0.0, // float energyError, + 0.0, // float time, + 0.0, // float timeError, + edm4hep::Vector3f(0.0, 0.0, 0.0), // edm4hep::Vector3f position, + edm4hep::Vector3f(1.0, 1.0, 0.0), // edm4hep::Vector3f dimension, + 0, // std::int32_t sector, + 0, // std::int32_t layer, + edm4hep::Vector3f(0.9 /* mm */, 0.9 /* mm */, 0.0) // edm4hep::Vector3f local + ); + hits_coll.create( + 1, // std::uint64_t cellID, + 6.0, // float energy, + 0.0, // float energyError, + 0.0, // float time, + 0.0, // float timeError, + edm4hep::Vector3f(0.0, 0.0, 0.0), // edm4hep::Vector3f position, + edm4hep::Vector3f(1.0, 1.0, 0.0), // edm4hep::Vector3f dimension, + 0, // std::int32_t sector, + 0, // std::int32_t layer, + edm4hep::Vector3f(1.8 /* mm */, 1.8 /* mm */, 0.0) // edm4hep::Vector3f local + ); + auto protoclust_coll = algo.AlgorithmProcess(hits_coll); if (algo.m_splitCluster) { - REQUIRE( algo.protoClusters.size() == 2 ); - REQUIRE( algo.protoClusters[0]->hits_size() == 3 ); - REQUIRE( algo.protoClusters[0]->weights_size() == 3 ); - for (double weight : algo.protoClusters[0]->getWeights()) { - double energy_fraction = algo.hits[0]->getEnergy() / (algo.hits[0]->getEnergy() + algo.hits[2]->getEnergy()); + REQUIRE( (*protoclust_coll).size() == 2 ); + REQUIRE( (*protoclust_coll)[0].hits_size() == 3 ); + REQUIRE( (*protoclust_coll)[0].weights_size() == 3 ); + for (double weight : (*protoclust_coll)[0].getWeights()) { + double energy_fraction = hits_coll[0].getEnergy() / (hits_coll[0].getEnergy() + hits_coll[2].getEnergy()); REQUIRE_THAT( weight, Catch::Matchers::WithinAbs(energy_fraction, 1e-5) ); } - REQUIRE( algo.protoClusters[1]->hits_size() == 3 ); - REQUIRE( algo.protoClusters[1]->weights_size() == 3 ); - for (double weight : algo.protoClusters[1]->getWeights()) { - double energy_fraction = algo.hits[2]->getEnergy() / (algo.hits[0]->getEnergy() + algo.hits[2]->getEnergy()); + REQUIRE( (*protoclust_coll)[1].hits_size() == 3 ); + REQUIRE( (*protoclust_coll)[1].weights_size() == 3 ); + for (double weight : (*protoclust_coll)[1].getWeights()) { + double energy_fraction = hits_coll[2].getEnergy() / (hits_coll[0].getEnergy() + hits_coll[2].getEnergy()); REQUIRE_THAT( weight, Catch::Matchers::WithinAbs(energy_fraction, 1e-5) ); } } else { - REQUIRE( algo.protoClusters.size() == 1 ); - REQUIRE( algo.protoClusters[0]->hits_size() == 3 ); - REQUIRE( algo.protoClusters[0]->weights_size() == 3 ); + REQUIRE( (*protoclust_coll).size() == 1 ); + REQUIRE( (*protoclust_coll)[0].hits_size() == 3 ); + REQUIRE( (*protoclust_coll)[0].weights_size() == 3 ); } } }