Skip to content
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 99 additions & 12 deletions src/algorithms/calorimetry/CalorimeterClusterRecoCoG.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
* Author: Chao Peng (ANL), 09/27/2020
*/

#include <DD4hep/IDDescriptor.h>
#include <DD4hep/Readout.h>
#include <DDSegmentation/BitFieldCoder.h>
#include <Evaluator/DD4hepUnits.h>
#include <boost/algorithm/string/join.hpp>
#include <boost/range/adaptor/map.hpp>
Expand All @@ -27,17 +30,31 @@
#include <limits>
#include <map>
#include <optional>
#include <stdexcept>
#include <tuple>
#include <vector>

#include "CalorimeterClusterRecoCoG.h"
#include "algorithms/calorimetry/CalorimeterClusterRecoCoG.h"
#include "algorithms/calorimetry/CalorimeterClusterRecoCoGConfig.h"

namespace eicrecon {

using namespace dd4hep;

void CalorimeterClusterRecoCoG::init() {

// (Re)acquire detector and, if configured, IDDescriptor for system-aware behavior
m_detector = algorithms::GeoSvc::instance().detector();
if (!m_detector) {
error("Failed to get detector from GeoSvc");
throw std::runtime_error("Detector not available");
}

if (!m_cfg.readout.empty()) {
m_idSpec = m_detector->readout(m_cfg.readout).idSpec();
} else {
warning("No readout configured; system-aware ScFi/Imaging weighting is disabled.");
}
// select weighting method
std::string ew = m_cfg.energyWeight;
// make it case-insensitive
Expand Down Expand Up @@ -92,6 +109,24 @@ void CalorimeterClusterRecoCoG::process(const CalorimeterClusterRecoCoG::Input&
}
}

// System ID from cell ID

static const int SYSID_SCIFI = 105;
static const int SYSID_IMAGING = 101;

inline int getSystemID(const edm4eic::CalorimeterHit& hit, const dd4hep::IDDescriptor& m_idSpec) {
static thread_local const auto* sys_field = m_idSpec.field("system");
return sys_field->value(hit.getCellID());
}
Comment on lines +117 to +120
Comment on lines +117 to +120

inline bool isSciFiHit(const edm4eic::CalorimeterHit& hit, const dd4hep::IDDescriptor& m_idSpec) {
return getSystemID(hit, m_idSpec) == SYSID_SCIFI;
}

inline bool isImagingHit(const edm4eic::CalorimeterHit& hit, const dd4hep::IDDescriptor& m_idSpec) {
return getSystemID(hit, m_idSpec) == SYSID_IMAGING;
}

std::optional<edm4eic::MutableCluster>
CalorimeterClusterRecoCoG::reconstruct(const edm4eic::ProtoCluster& pcl) const {
edm4eic::MutableCluster cl;
Expand All @@ -111,19 +146,54 @@ CalorimeterClusterRecoCoG::reconstruct(const edm4eic::ProtoCluster& pcl) const {
float maxHitEta = std::numeric_limits<float>::min();
auto time = 0;
auto timeError = 0;

bool hasSciFi = false;
bool hasImaging = false;

for (const auto& hit : pcl.getHits()) {
if (isSciFiHit(hit, m_idSpec)) {
hasSciFi = true;
}
if (isImagingHit(hit, m_idSpec)) {
hasImaging = true;
}
}

bool specialMode = hasSciFi && hasImaging;

Comment on lines +150 to +163
// -----------------------------------------------------------------------------------
// ScFi hit alone contributes to energy weight & for Img hit energy weight = 0
// -----------------------------------------------------------------------------------

for (unsigned i = 0; i < pcl.getHits().size(); ++i) {

const auto& hit = pcl.getHits()[i];
const auto weight = pcl.getWeights()[i];
debug("hit energy = {} hit weight: {}", hit.getEnergy(), weight);
auto energy = hit.getEnergy() * weight;

float energy = 0.0f;

if (specialMode) {

if (isSciFiHit(hit, m_idSpec)) {
energy = hit.getEnergy() * weight;
} else if (isImagingHit(hit, m_idSpec)) {
energy = 0.0f; // Imaging has no energy weight contribution
}
} else {
energy = hit.getEnergy() * weight;
}

totalE += energy;
time += (hit.getTime() - time) * energy / totalE;

Comment on lines +185 to +188
cl.addToHits(hit);
cl.addToHitContributions(energy);
const float eta = edm4hep::utils::eta(hit.getPosition());
minHitEta = std::min(eta, minHitEta);
maxHitEta = std::max(eta, maxHitEta);

float eta = edm4hep::utils::eta(hit.getPosition());
minHitEta = std::min(minHitEta, eta);
maxHitEta = std::max(maxHitEta, eta);
}

cl.setEnergy(totalE / m_cfg.sampFrac);
cl.setEnergyError(0.);
cl.setTime(time);
Expand All @@ -142,13 +212,30 @@ CalorimeterClusterRecoCoG::reconstruct(const edm4eic::ProtoCluster& pcl) const {
}
}

// --------------------------------------------------------------------------------------
// Imaging hit alone contributes to Position weight & for ScFi hit position weight = 0
// --------------------------------------------------------------------------------------
for (unsigned i = 0; i < pcl.getHits().size(); ++i) {
const auto& hit = pcl.getHits()[i];
const auto weight = pcl.getWeights()[i];
// _DBG_<<" -- weight = " << weight << " E=" << hit.getEnergy() << " totalE=" <<totalE << " log(E/totalE)=" << std::log(hit.getEnergy()/totalE) << std::endl;
float w = weightFunc(hit.getEnergy() * weight, totalE, logWeightBase, 0);
tw += w;
v = v + (hit.getPosition() * w);
const auto& hit = pcl.getHits()[i];
float w = 0.0f;

if (specialMode) {

if (isImagingHit(hit, m_idSpec)) {
const auto weight = pcl.getWeights()[i];
w = weightFunc(hit.getEnergy() * weight, totalE, logWeightBase, 0);
} else if (isSciFiHit(hit, m_idSpec)) {
w = 0.0f; // ScFi has no position weight
}

tw += w;
v = v + hit.getPosition() * w;
} else {
const auto weight = pcl.getWeights()[i];
float w = weightFunc(hit.getEnergy() * weight, totalE, logWeightBase, 0);
tw += w;
v = v + (hit.getPosition() * w);
}
}
if (tw == 0.) {
warning("zero total weights encountered, you may want to adjust your weighting parameter.");
Expand Down
8 changes: 8 additions & 0 deletions src/algorithms/calorimetry/CalorimeterClusterRecoCoG.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@

#pragma once

#include <DD4hep/Detector.h>
#include <DD4hep/IDDescriptor.h>
#include <algorithms/algorithm.h>
#include <algorithms/geo.h>
#include <edm4eic/ClusterCollection.h>
#include <edm4eic/MCRecoCalorimeterHitAssociationCollection.h>
#include <edm4eic/MCRecoCalorimeterHitLinkCollection.h>
Expand All @@ -23,6 +26,7 @@
#include <algorithm>
#include <cmath>
#include <functional>
#include <gsl/pointers>
#include <map>
#include <memory>
#include <optional>
Expand Down Expand Up @@ -81,6 +85,10 @@ class CalorimeterClusterRecoCoG : public CalorimeterClusterRecoCoGAlgorithm,
private:
std::function<double(double, double, double, int)> weightFunc;

// Pointer to the geometry service
dd4hep::IDDescriptor m_idSpec;
const dd4hep::Detector* m_detector{algorithms::GeoSvc::instance().detector()};

private:
std::optional<edm4eic::MutableCluster> reconstruct(const edm4eic::ProtoCluster& pcl) const;
void associate(const edm4eic::Cluster& cl,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
namespace eicrecon {

struct CalorimeterClusterRecoCoGConfig {

std::string readout = "";
std::string energyWeight;

double sampFrac = 1.;
Expand Down
Loading
Loading