22void StripClusterProcessor::configure(
25 parameters.
get<std::string>(
"in_collection",
"FittedSiStripHits");
26 in_pass_ = parameters.
get<std::string>(
"in_pass",
"");
28 parameters.
get<std::string>(
"out_collection",
"StripMeasurements");
30 seed_threshold_ = parameters.
get<
double>(
"seed_threshold", 4.0);
31 neighbor_threshold_ = parameters.
get<
double>(
"neighbor_threshold", 3.0);
32 cluster_threshold_ = parameters.
get<
double>(
"cluster_threshold", 4.0);
33 mean_time_ns_ = parameters.
get<
double>(
"mean_time_ns", 0.0);
34 time_window_ns_ = parameters.
get<
double>(
"time_window_ns", -1.0);
35 neighbor_delta_t_ns_ = parameters.
get<
double>(
"neighbor_delta_t_ns", -1.0);
36 max_chi2_ndf_ = parameters.
get<
double>(
"max_chi2_ndf", -1.0);
37 daq_map_file_ = parameters.
get<std::string>(
"daq_map_file",
"");
42void StripClusterProcessor::onProcessStart() {
43 using namespace tracking::digitization;
45 clusterer_ = std::make_unique<tracking::digitization::StripClusterer>(
46 seed_threshold_, neighbor_threshold_, cluster_threshold_, NOISE_SIGMA_ADC,
47 mean_time_ns_, time_window_ns_, neighbor_delta_t_ns_, max_chi2_ndf_);
52 layer_n_strips_.clear();
53 if (!daq_map_file_.empty()) {
54 const auto map = TrackerDaqMap::fromJsonFile(daq_map_file_);
55 for (
const auto& [key, sensor] : map.sensors()) {
56 layer_n_strips_[sensor.layer_id_] = sensor.n_strips_;
58 ldmx_log(info) <<
"StripClusterProcessor loaded DAQ map from '"
59 << daq_map_file_ <<
"' (" << layer_n_strips_.size()
60 <<
" layers) for centre-strip offsets";
63 ldmx_log(info) <<
"StripClusterProcessor configured:" <<
" seed_thr="
64 << seed_threshold_ <<
" nbr_thr=" << neighbor_threshold_
65 <<
" cls_thr=" << cluster_threshold_
66 <<
" noise=" << NOISE_SIGMA_ADC <<
" ADC"
67 <<
" pitch=" << READOUT_PITCH_MM <<
" mm"
68 <<
" sigma_v=" << SIGMA_V_MM <<
" mm";
74 const auto& fitted_hits =
77 ldmx_log(debug) <<
"Clustering " << fitted_hits.size()
78 <<
" FittedSiStripHits";
83 std::map<int, std::vector<ldmx::FittedSiStripHit>> hits_by_layer;
84 for (
const auto& h : fitted_hits) {
85 hits_by_layer[h.getLayerID()].push_back(h);
91 std::vector<ldmx::Measurement> measurements;
93 for (
const auto& [layer_id, layer_hits] : hits_by_layer) {
94 auto hit_surface = geometry().getSurface(layer_id);
96 ldmx_log(warn) <<
"No surface found for layer_id=" << layer_id
97 <<
" — skipping " << layer_hits.size() <<
" hits";
102 std::map<int, const ldmx::FittedSiStripHit*> strip_hit_map;
103 for (
const auto& h : layer_hits) {
104 strip_hit_map[h.getStripID()] = &h;
107 const auto clusters = clusterer_->findClusters(layer_hits);
108 ldmx_log(debug) <<
" layer " << layer_id <<
": " << layer_hits.size()
109 <<
" hits → " << clusters.size() <<
" clusters";
111 for (
const auto& cl : clusters) {
120 using namespace tracking::digitization;
125 int n_strips = N_READOUT_STRIPS;
126 auto it_ns = layer_n_strips_.find(layer_id);
127 if (it_ns != layer_n_strips_.end()) n_strips = it_ns->second;
128 const int n_int = n_strips / 2;
129 const double offset =
static_cast<double>(n_int);
130 const double local_u = (cl.centroid_strip - offset) * READOUT_PITCH_MM;
136 switch (cl.n_strips) {
138 sigma_u = SENSE_PITCH_MM / std::sqrt(12.0);
141 sigma_u = SENSE_PITCH_MM / 5.0;
144 sigma_u = SENSE_PITCH_MM / 3.0;
147 sigma_u = SENSE_PITCH_MM / 2.0;
150 sigma_u = SENSE_PITCH_MM;
153 constexpr double local_v = 0.0;
158 Acts::Vector3 dummy_momentum;
159 const Acts::Vector3 global_pos = hit_surface->localToGlobal(
160 geometryContext(), Acts::Vector2(local_u, local_v), dummy_momentum);
168 static_cast<float>(local_v));
170 static_cast<float>(sigma_u * sigma_u),
171 static_cast<float>(tracking::digitization::SIGMA_V_MM *
172 tracking::digitization::SIGMA_V_MM));
174 static_cast<float>(global_pos[1]),
175 static_cast<float>(global_pos[2]));
176 meas.
setTime(
static_cast<float>(cl.time_ns));
186 const float reco_edep =
static_cast<float>(
187 cl.total_amplitude * ADC_ELECTRONS_PER_COUNT * ENERGY_PER_EHP_MEV);
193 std::unordered_set<int> seen_track_ids;
194 for (
const int strip : cl.strip_ids) {
195 auto it = strip_hit_map.find(strip);
196 if (it != strip_hit_map.end()) {
197 const int tid = it->second->getTrackID();
198 if (tid >= 0 && seen_track_ids.insert(tid).second) {
204 ldmx_log(trace) <<
" cluster: layer=" << layer_id
205 <<
" strips=" << cl.n_strips <<
" u=" << local_u <<
" mm"
206 <<
" sigma_u=" << sigma_u <<
" mm" <<
" t=" << cl.time_ns
207 <<
" ns" <<
" amp=" << cl.total_amplitude <<
" ADC"
208 <<
" n_track_ids=" << seen_track_ids.size();
210 measurements.push_back(meas);
214 ldmx_log(debug) <<
"Produced " << measurements.size() <<
" Measurements";
215 event.add(out_collection_, measurements);