38 std::string(tracking::digitization::PULSE_SHAPE_NAME),
39 tracking::digitization::PEAKING_TIME_NS,
40 tracking::digitization::SECOND_TIME_CONST_NS);
45 struct TriggerSamples {
46 uint16_t apv_trigger_;
47 std::vector<short> samples_;
51 uint8_t hybrid_id_{0};
53 std::vector<TriggerSamples> triggers_;
57 std::map<uint32_t, ChannelInfo> channel_map;
59 for (
const auto& hit : hits) {
60 const float noise = peds.noise(hit.getFebId(), hit.getHybridId(),
61 hit.getApvId(), hit.getChannel());
62 if (noise <= 0)
continue;
64 const int16_t pchannel =
69 auto& ch = channel_map[key];
71 ch.hybrid_id_ = hit.getHybridId();
72 ch.feb_id_ = hit.getFebId();
73 ch.triggers_.push_back({hit.getApvTrigger(), hit.getSamples()});
76 std::vector<ldmx::SiStripWaveform> waveforms;
78 for (
auto& [key, ch] : channel_map) {
80 std::sort(ch.triggers_.begin(), ch.triggers_.end(),
81 [](
const TriggerSamples& a,
const TriggerSamples& b) {
82 return a.apv_trigger_ < b.apv_trigger_;
86 std::vector<short> samples;
87 samples.reserve(ch.triggers_.size() *
89 for (
const auto& trig : ch.triggers_) {
90 for (
short s : trig.samples_) samples.push_back(s);
93 if (samples.empty())
continue;
97 for (
short s : samples)
103 int max_streak = 0, cur_streak = 0;
104 for (
short s : samples) {
106 max_streak = std::max(max_streak, ++cur_streak);
114 uint8_t n_trig =
static_cast<uint8_t
>(
115 std::min(
static_cast<int>(ch.triggers_.size()), 255));
121 const int n_samples =
static_cast<int>(samples.size());
122 const double t_scan_max =
123 n_samples * tracking::digitization::SAMPLING_INTERVAL_NS;
127 tracking::digitization::SAMPLING_INTERVAL_NS,
130 -50.0, t_scan_max, 1.0);
131 const auto fit = fitter.
fit(samples);
135 ldmx_log(trace) <<
"fit feb=" <<
static_cast<int>(ch.feb_id_)
136 <<
" hyb=" <<
static_cast<int>(ch.hybrid_id_)
137 <<
" pch=" << pchannel <<
" nsamp=" << n_samples
138 <<
" noise=" << ch.noise_
139 <<
" -> converged=" << (fit.converged ?
"yes" :
"no")
140 <<
" amp=" << fit.amplitude <<
" t0=" << fit.t0 <<
"ns"
141 <<
" chi2/ndf=" << fit.chi2 <<
"/" << fit.ndf <<
" ("
142 << (fit.ndf > 0 ? fit.chi2 / fit.ndf : 0.0) <<
")";
144 waveforms.emplace_back(std::move(samples), pchannel, ch.hybrid_id_,
146 waveforms.back().setFitResult(
147 static_cast<float>(fit.amplitude),
static_cast<float>(fit.t0),
148 static_cast<float>(fit.chi2), fit.ndf, fit.converged);
151 ldmx_log(debug) <<
"Built " << waveforms.size()
157 for (
const auto& wf : waveforms) {
158 ldmx_log(trace) << wf;
161 event.add(output_collection_, waveforms);
constexpr uint32_t groupKey(uint8_t feb, uint8_t hybrid, int16_t pchannel)
Pack (feb, hybrid, pchannel) into a single 32-bit waveform-grouping key.
constexpr int16_t pchannel(uint8_t apv_id, uint8_t channel)
Convert an (APV id, APV channel) pair into the physical strip number (pchannel) within a hybrid,...