21void StripClusterProcessor::configure(
24 parameters.
get<std::string>(
"in_collection",
"FittedSiStripHits");
25 in_pass_ = parameters.
get<std::string>(
"in_pass",
"");
27 parameters.
get<std::string>(
"out_collection",
"StripMeasurements");
29 seed_threshold_ = parameters.
get<
double>(
"seed_threshold", 4.0);
30 neighbor_threshold_ = parameters.
get<
double>(
"neighbor_threshold", 3.0);
31 cluster_threshold_ = parameters.
get<
double>(
"cluster_threshold", 4.0);
32 mean_time_ns_ = parameters.
get<
double>(
"mean_time_ns", 0.0);
33 time_window_ns_ = parameters.
get<
double>(
"time_window_ns", -1.0);
34 neighbor_delta_t_ns_ = parameters.
get<
double>(
"neighbor_delta_t_ns", -1.0);
35 max_chi2_ndf_ = parameters.
get<
double>(
"max_chi2_ndf", -1.0);
36 daq_map_file_ = parameters.
get<std::string>(
"daq_map_file",
"");
41void StripClusterProcessor::onProcessStart() {
42 using namespace tracking::digitization;
44 clusterer_ = std::make_unique<tracking::digitization::StripClusterer>(
45 seed_threshold_, neighbor_threshold_, cluster_threshold_, NOISE_SIGMA_ADC,
46 mean_time_ns_, time_window_ns_, neighbor_delta_t_ns_, max_chi2_ndf_);
51 layer_n_strips_.clear();
52 if (!daq_map_file_.empty()) {
53 const auto map = TrackerDaqMap::fromJsonFile(daq_map_file_);
54 for (
const auto& [key, sensor] : map.sensors()) {
55 layer_n_strips_[sensor.layer_id_] = sensor.n_strips_;
57 ldmx_log(info) <<
"StripClusterProcessor loaded DAQ map from '"
58 << daq_map_file_ <<
"' (" << layer_n_strips_.size()
59 <<
" layers) for centre-strip offsets";
62 ldmx_log(info) <<
"StripClusterProcessor configured:" <<
" seed_thr="
63 << seed_threshold_ <<
" nbr_thr=" << neighbor_threshold_
64 <<
" cls_thr=" << cluster_threshold_
65 <<
" noise=" << NOISE_SIGMA_ADC <<
" ADC"
66 <<
" pitch=" << READOUT_PITCH_MM <<
" mm"
67 <<
" sigma_v=" << SIGMA_V_MM <<
" mm";
73 const auto& fitted_hits =
76 ldmx_log(debug) <<
"Clustering " << fitted_hits.size()
77 <<
" FittedSiStripHits";
82 std::map<int, std::vector<ldmx::FittedSiStripHit>> hits_by_layer;
83 for (
const auto& h : fitted_hits) {
84 hits_by_layer[h.getLayerID()].push_back(h);
90 std::vector<ldmx::Measurement> measurements;
92 for (
const auto& [layer_id, layer_hits] : hits_by_layer) {
93 auto hit_surface = geometry().getSurface(layer_id);
95 ldmx_log(warn) <<
"No surface found for layer_id=" << layer_id
96 <<
" — skipping " << layer_hits.size() <<
" hits";
101 std::map<int, const ldmx::FittedSiStripHit*> strip_hit_map;
102 for (
const auto& h : layer_hits) {
103 strip_hit_map[h.getStripID()] = &h;
106 const auto clusters = clusterer_->findClusters(layer_hits);
107 ldmx_log(debug) <<
" layer " << layer_id <<
": " << layer_hits.size()
108 <<
" hits → " << clusters.size() <<
" clusters";
110 for (
const auto& cl : clusters) {
119 using namespace tracking::digitization;
124 int n_strips = N_READOUT_STRIPS;
125 auto it_ns = layer_n_strips_.find(layer_id);
126 if (it_ns != layer_n_strips_.end()) n_strips = it_ns->second;
127 const int n_int = n_strips / 2;
128 const double offset =
static_cast<double>(n_int);
129 const double local_u = (cl.centroid_strip - offset) * READOUT_PITCH_MM;
135 switch (cl.n_strips) {
137 sigma_u = SENSE_PITCH_MM / std::sqrt(12.0);
140 sigma_u = SENSE_PITCH_MM / 5.0;
143 sigma_u = SENSE_PITCH_MM / 3.0;
146 sigma_u = SENSE_PITCH_MM / 2.0;
149 sigma_u = SENSE_PITCH_MM;
152 constexpr double local_v = 0.0;
157 Acts::Vector3 dummy_momentum;
158 const Acts::Vector3 global_pos = hit_surface->localToGlobal(
159 geometryContext(), Acts::Vector2(local_u, local_v), dummy_momentum);
167 static_cast<float>(local_v));
169 static_cast<float>(sigma_u * sigma_u),
170 static_cast<float>(tracking::digitization::SIGMA_V_MM *
171 tracking::digitization::SIGMA_V_MM));
173 static_cast<float>(global_pos[1]),
174 static_cast<float>(global_pos[2]));
175 meas.
setTime(
static_cast<float>(cl.time_ns));
185 const float reco_edep =
static_cast<float>(
186 cl.total_amplitude * ADC_ELECTRONS_PER_COUNT * ENERGY_PER_EHP_MEV);
192 std::unordered_set<int> seen_track_ids;
193 for (
const int strip : cl.strip_ids) {
194 auto it = strip_hit_map.find(strip);
195 if (it != strip_hit_map.end()) {
196 const int tid = it->second->getTrackID();
197 if (tid >= 0 && seen_track_ids.insert(tid).second) {
203 ldmx_log(trace) <<
" cluster: layer=" << layer_id
204 <<
" strips=" << cl.n_strips <<
" u=" << local_u <<
" mm"
205 <<
" sigma_u=" << sigma_u <<
" mm" <<
" t=" << cl.time_ns
206 <<
" ns" <<
" amp=" << cl.total_amplitude <<
" ADC"
207 <<
" n_track_ids=" << seen_track_ids.size();
209 measurements.push_back(meas);
213 ldmx_log(debug) <<
"Produced " << measurements.size() <<
" Measurements";
214 event.add(out_collection_, measurements);