14snd::analysis_tools::ScifiPlane::ScifiPlane(TClonesArray *snd_hits,
snd::Configuration configuration,
Scifi *scifi_geometry,
int index_begin,
int index_end,
int station) : configuration_(configuration), centroid_(std::nan(
""), std::nan(
""), std::nan(
"")), centroid_error_(std::nan(
""), std::nan(
""), std::nan(
"")), station_(station)
16 if (index_begin > index_end)
18 throw std::runtime_error{
"Begin index > end index"};
21 for (
int i{index_begin}; i < index_end; ++i)
23 auto snd_hit =
static_cast<sndScifiHit *
>(snd_hits->At(i));
25 hit.
channel_index = 512 * snd_hit->GetMat() + 64 * snd_hit->GetTofpetID(0) + 63 - snd_hit->Getchannel(0);
27 hit.
qdc = snd_hit->GetSignal(0);
28 hit.
is_x = snd_hit->isVertical();
31 int detectorID = snd_hit->GetDetectorID();
60 if (configuration_.scifi_min_hits_in_window > configuration_.scifi_shower_window_width)
62 throw std::runtime_error{
"min_hits > window_width"};
66 is_hit.
x.resize(configuration_.scifi_n_channels_per_plane, 0);
67 is_hit.
y.resize(configuration_.scifi_n_channels_per_plane, 0);
69 for (
auto &hit : hits_)
71 (hit.is_x ? is_hit.
x : is_hit.
y)[hit.channel_index] = 1;
74 auto density = [&](std::vector<int> &hit_arr)
79 for (
int i{0}; i < configuration_.scifi_shower_window_width; ++i)
84 if (count >= configuration_.scifi_min_hits_in_window)
88 for (
int i = configuration_.scifi_shower_window_width; i < configuration_.scifi_n_channels_per_plane; ++i)
90 count += hit_arr[i] - hit_arr[i - configuration_.scifi_shower_window_width];
91 if (count >= configuration_.scifi_min_hits_in_window)
98 return density(is_hit.
x) && density(is_hit.
y);
103 std::vector<double> pos_x(configuration_.scifi_n_channels_per_plane, std::nan(
""));
104 std::vector<double> pos_y(configuration_.scifi_n_channels_per_plane, std::nan(
""));
106 for (
auto &hit : hits_)
112 pos_x[hit.channel_index] = hit.x;
116 pos_y[hit.channel_index] = hit.y;
121 auto largest_cluster = [&](
const std::vector<double> &positions)
123 int n = positions.size();
125 int best_start = -1, best_end = -1, best_size = 0;
126 int start = -1, gap_count = 0, size = 0;
129 for (
int i = 0; i < n; ++i)
131 if (!std::isnan(positions[i]))
141 if (gap_count > max_gap)
143 if (size > best_size)
146 best_end = i - gap_count;
162 if (size > best_size)
170 if (best_start == -1 || best_end == -1)
175 for (
int i = best_start; i <= best_end; ++i)
177 if (!std::isnan(positions[i]))
184 return (count > 0) ? sum / count : std::nan(
"");
187 double cluster_x = largest_cluster(pos_x);
188 double cluster_y = largest_cluster(pos_y);
189 if (!(std::isnan(cluster_x) || std::isnan(cluster_y))) {
190 return TVector3(cluster_x, cluster_y, hits_[0].z);
192 return TVector3(std::nan(
""), std::nan(
""), std::nan(
""));
219 centroid_.SetXYZ(0, 0, 0);
222 std::vector<ScifiHit> cleaned_hits = hits_;
224 cleaned_hits.erase(std::remove_if(cleaned_hits.begin(), cleaned_hits.end(),
226 { return hit.qdc <= 0; }),
228 int counts_x = std::count_if(cleaned_hits.begin(), cleaned_hits.end(), [](
auto &hit)
229 { return hit.is_x; });
230 int counts_y = cleaned_hits.size()-counts_x;
231 if (counts_x < configuration_.scifi_min_n_hits_for_centroid && counts_y < configuration_.scifi_min_n_hits_for_centroid ) {
232 centroid_.SetXYZ(std::nan(
""), std::nan(
""), std::nan(
""));
236 for (
auto &hit : cleaned_hits)
242 centroid_.SetX(centroid_.X() + hit.x * hit.qdc);
243 tot_qdc_x += hit.qdc;
247 centroid_.SetY(centroid_.Y() + hit.y * hit.qdc);
248 tot_qdc_y += hit.qdc;
251 centroid_.SetZ(centroid_.Z() + hit.z * hit.qdc);
254 centroid_.SetXYZ((tot_qdc_x > 0) ? centroid_.X() / tot_qdc_x : std::nan(
""), (tot_qdc_y > 0) ? centroid_.Y() / tot_qdc_y : std::nan(
""), (tot_qdc_x+tot_qdc_y > 0) ? centroid_.Z() / (tot_qdc_x+tot_qdc_y) : std::nan(
""));
255 centroid_error_.SetXYZ(configuration_.scifi_centroid_error_x, configuration_.scifi_centroid_error_y, configuration_.scifi_centroid_error_z);
261 qdc_sum.
x = std::accumulate(hits_.begin(), hits_.end(), 0.0, [&](
double current_sum,
auto &hit)
262 { return (hit.is_x && (hit.qdc > 0 || !only_positive)) ? (current_sum + hit.qdc) : current_sum; });
263 qdc_sum.y = std::accumulate(hits_.begin(), hits_.end(), 0.0, [&](
double current_sum,
auto &hit)
264 { return (!hit.is_x && (hit.qdc > 0 || !only_positive)) ? (current_sum + hit.qdc) : current_sum; });