8#include "TClonesArray.h"
10#include "ROOT/TSeq.hxx"
13 std::vector<int> &vertical_hits)
17 std::fill(horizontal_hits.begin(), horizontal_hits.end(), 0);
18 std::fill(vertical_hits.begin(), vertical_hits.end(), 0);
22 TIter hitIterator(digiHits);
24 while (hit =
dynamic_cast<sndScifiHit *
>(hitIterator.Next())) {
28 vertical_hits[station - 1]++;
30 horizontal_hits[station - 1]++;
38 return std::accumulate(horizontal_hits.begin(), horizontal_hits.end(),
39 std::accumulate(vertical_hits.begin(), vertical_hits.end(), 0));
44 std::vector<int> horizontal_hits = std::vector<int>(5);
45 std::vector<int> vertical_hits = std::vector<int>(5);
58 std::vector<float> fractional_hits_per_station = std::vector<float>(horizontal_hits.size());
60 std::transform(horizontal_hits.begin(), horizontal_hits.end(), vertical_hits.begin(),
61 fractional_hits_per_station.begin(),
62 [&total_hits](
const auto &hor,
const auto &ver) { return ((float)hor + ver) / total_hits; });
64 return fractional_hits_per_station;
69 std::vector<int> horizontal_hits = std::vector<int>(5);
70 std::vector<int> vertical_hits = std::vector<int>(5);
83 std::vector<float> frac_sum = std::vector<float>(frac.size());
85 std::partial_sum(frac.begin(), frac.end(), frac_sum.begin());
87 std::vector<float>::iterator station =
88 std::find_if(frac_sum.begin(), frac_sum.end(), [&threshold](
const auto &f) { return f > threshold; });
90 return station - frac_sum.begin() + 1;
95 std::vector<int> horizontal_hits = std::vector<int>(5);
96 std::vector<int> vertical_hits = std::vector<int>(5);
127 if (digiHits.GetEntries() <= 0) {
128 LOG(warning) <<
"digiHits has no valid SciFi Hits and as such no maximum for the timing distribution.";
132 TH1F ScifiTiming(
"Timing",
"Scifi Timing", bins, min_x, max_x);
134 int refStation = ((
sndScifiHit *)digiHits.At(0))->GetStation();
135 bool refOrientation = ((
sndScifiHit *)digiHits.At(0))->isVertical();
136 float hitTime = -1.0;
138 for (
auto *p : digiHits) {
140 if (!
validateHit(hit, refStation, refOrientation)) {
143 hitTime = hit->
GetTime() * 1E9 / (ShipUnit::snd_freq / ShipUnit::hertz);
144 if (hitTime < min_x || hitTime > max_x) {
147 ScifiTiming.Fill(hitTime);
151 float peakTiming = (ScifiTiming.GetMaximumBin() - 0.5) * (max_x - min_x) / bins + min_x;
157std::unique_ptr<TClonesArray>
161 auto selectedHits = std::make_unique<TClonesArray>(
"sndScifiHit");
164 for (
auto *p : digiHits) {
183 bool orientation,
int bins_x,
float min_x,
184 float max_x,
float time_lower_range,
185 float time_upper_range,
bool make_selection)
189 LOG(FATAL) <<
"bins_x in selection_parameters cannot be <1. Consider using the default value of 52 instead.";
192 LOG(warning) <<
"In selection_parameters min_x > max_x. Values will be swapped.";
193 float aux_float = min_x;
198 LOG(warning) <<
"In selection_parameters min_x < 0.0. Consider using the default value of 0.0.";
201 LOG(FATAL) <<
"In selection_parameters max_x < 0.0. Consider using the default value of 26.0.";
203 if (time_lower_range <= 0.0) {
204 LOG(FATAL) <<
"In selection_parameters time_lower_range <= 0.0. Value should always be positive, in ns.";
206 if (time_upper_range <= 0.0) {
207 LOG(FATAL) <<
"In selection_parameters time_upper_range <= 0.0. Value should always be positive, in ns.";
210 auto filteredHits = std::make_unique<TClonesArray>(
"sndScifiHit", digiHits.GetEntries());
212 float peakTiming = -1.0;
214 if (make_selection) {
216 auto selectedHits =
getScifiHits(digiHits, station, orientation);
221 for (
auto *p : *selectedHits) {
226 if ((peakTiming - time_lower_range > hit->GetTime() * 1E9 / (ShipUnit::snd_freq / ShipUnit::hertz)) ||
227 (hit->GetTime() * 1E9 / (ShipUnit::snd_freq / ShipUnit::hertz) > peakTiming + time_upper_range)) {
239 for (
auto *p : digiHits) {
244 if ((peakTiming - time_lower_range > hit->GetTime() * 1E9 / (ShipUnit::snd_freq / ShipUnit::hertz)) ||
245 (hit->GetTime() * 1E9 / (ShipUnit::snd_freq / ShipUnit::hertz) > peakTiming + time_upper_range)) {
258std::unique_ptr<TClonesArray>
260 const std::map<std::string, float> &selection_parameters,
bool make_selection)
263 if ((selection_parameters.find(
"bins_x") == selection_parameters.end()) ||
264 (selection_parameters.find(
"min_x") == selection_parameters.end()) ||
265 (selection_parameters.find(
"max_x") == selection_parameters.end()) ||
266 (selection_parameters.find(
"time_lower_range") == selection_parameters.end())) {
267 LOG(FATAL) <<
"In order to use method 0 please provide the correct selection_parameters. Consider the default = "
268 "{{\"bins_x\", 52.}, {\"min_x\", 0.}, {\"max_x\", 26.}, {\"time_lower_range\", "
269 "1E9/(2*ShipUnit::snd_freq/ShipUnit::hertz))}, {\"time_upper_range\", "
270 "2E9/(ShipUnit::snd_freq/ShipUnit::hertz)}}";
273 float time_upper_range = -1.;
275 if (selection_parameters.find(
"time_upper_range") == selection_parameters.end()) {
276 time_upper_range = selection_parameters.at(
"time_lower_range");
278 time_upper_range = selection_parameters.at(
"time_upper_range");
281 return selectScifiHits(digiHits, station, orientation,
int(selection_parameters.at(
"bins_x")),
282 selection_parameters.at(
"min_x"), selection_parameters.at(
"max_x"),
283 selection_parameters.at(
"time_lower_range"), time_upper_range, make_selection);
286std::unique_ptr<TClonesArray>
288 const std::map<std::string, float> &selection_parameters,
int method,
291 TClonesArray supportArray(
"sndScifiHit", 0);
292 auto filteredHits = std::make_unique<TClonesArray>(
"sndScifiHit", digiHits.GetEntries());
293 int filteredHitsIndex = 0;
294 int ScifiStations = 5;
298 LOG(info) <<
"\"TI18\" setup will be used by default, please provide \"H8\" for the Testbeam setup.";
302 TIter hitIterator(&supportArray);
306 if ((selection_parameters.find(
"bins_x") == selection_parameters.end()) ||
307 (selection_parameters.find(
"min_x") == selection_parameters.end()) ||
308 (selection_parameters.find(
"max_x") == selection_parameters.end()) ||
309 (selection_parameters.find(
"time_lower_range") == selection_parameters.end())) {
310 LOG(FATAL) <<
"In order to use method 0 please provide the correct selection_parameters. Consider the default "
311 "= {{\"bins_x\", 52.}, {\"min_x\", 0.}, {\"max_x\", 26.}, {\"time_lower_range\", "
312 "1E9/(2*ShipUnit::snd_freq/ShipUnit::hertz)}, {\"time_upper_range\", "
313 "2E9/(ShipUnit::snd_freq/ShipUnit::hertz)}}";
317 for (
auto station : ROOT::MakeSeq(1, ScifiStations + 1)) {
318 for (
auto orientation : {
false,
true}) {
320 auto supportArray =
selectScifiHits(digiHits, station, orientation, selection_parameters,
true);
321 for (
auto *p : *supportArray) {
324 new ((*filteredHits)[filteredHitsIndex++])
sndScifiHit(*hit);
330 LOG(error) <<
"Please provide a valid time filter method from:";
331 LOG(error) <<
"(0): Events within \\mp time_lower_range time_upper_range of the peak of the time distribution "
332 "for Scifi Hits within each station and orientation";
333 LOG(FATAL) <<
"selection_parameters = {bins_x, min_x, max_x, time_lower_range, time_upper_range}.";
338std::unique_ptr<TClonesArray>
342 std::map<std::string, float> selection_parameters;
346 selection_parameters[
"bins_x"] = 52.0;
347 selection_parameters[
"min_x"] = 0.0;
348 selection_parameters[
"max_x"] = 26.0;
349 selection_parameters[
"time_lower_range"] = 1E9 / (2 * ShipUnit::snd_freq / ShipUnit::hertz);
350 selection_parameters[
"time_upper_range"] = 2E9 / (ShipUnit::snd_freq / ShipUnit::hertz);
353 LOG(FATAL) <<
"Please use method=0. No other methods implemented so far.";
364 int ref_matAux = reference_SiPM % 100000;
365 int ref_mat = ref_matAux / 10000;
366 int ref_arrayAux = reference_SiPM % 10000;
367 int ref_array = ref_arrayAux / 1000;
368 int ref_channel = reference_SiPM % 1000;
369 int referenceChannel = ref_mat * 4 * 128 + ref_array * 128 + ref_channel;
371 return referenceChannel;
380 bool orientation =
false;
381 if (
int(reference_SiPM / 100000) % 10 == 1) {
384 int ref_station = reference_SiPM / 1000000;
387 for (
auto *p : digiHits) {
396 if (hitChannel > referenceChannel + radius) {
399 if (abs(referenceChannel - hitChannel) <= radius) {
404 if (min_check && (hit_density >= min_hit_density)) {
417 if (digiHits.GetEntries() <= 0) {
422 LOG(FATAL) <<
"Radius<=0. Please provide a radius bigger than 0.";
426 if (min_hit_density < 0) {
427 LOG(FATAL) <<
"Min_hit_density < 0. Please provide a min_hit_density >= 0.";
431 if (min_hit_density > 2 * radius) {
432 LOG(warning) <<
"Warning! Radius of density check does not allow for the required minimum density!";
438 std::vector<int> fired_channels{};
442 for (
auto *p : digiHits) {
450 int n_fired_channels = fired_channels.size();
452 if (n_fired_channels < min_hit_density) {
460 std::sort(fired_channels.begin(), fired_channels.end());
461 for (
int i = 0; i < n_fired_channels - min_hit_density; i++) {
463 if (fired_channels[i + min_hit_density - 1] - fired_channels[i] <= radius * 2) {
477 const std::map<std::string, float> &selection_parameters,
int method,
481 int totalScifiStations = 5;
483 totalScifiStations = 4;
485 LOG(info) <<
"\"TI18\" setup will be used by default, please provide \"H8\" for the Testbeam setup.";
490 int showerStart = totalScifiStations;
494 if ((selection_parameters.find(
"radius") == selection_parameters.end()) ||
495 (selection_parameters.find(
"min_hit_density") == selection_parameters.end())) {
497 <<
"Argument of select_parameters is incorrect. Please provide a map with the arguments \"radius\" and "
498 "\"min_hit_density\". Consider using the default values of {{\"radius\",64}, {\"min_hit_density\",36}}.";
501 for (
int scifiStation = 1; scifiStation <= totalScifiStations; scifiStation++) {
507 bool horizontalCheck =
false;
508 bool verticalCheck =
false;
509 if (selection_parameters.find(
"orientation") != selection_parameters.end()) {
510 if (
int(selection_parameters.at(
"orientation")) == 0) {
511 verticalCheck =
true;
513 if (
int(selection_parameters.at(
"orientation")) == 1) {
514 horizontalCheck =
true;
517 horizontalCheck = (
densityCheck(digiHits,
int(selection_parameters.at(
"radius")),
518 int(selection_parameters.at(
"min_hit_density")), scifiStation,
false) ||
520 verticalCheck = (
densityCheck(digiHits,
int(selection_parameters.at(
"radius")),
521 int(selection_parameters.at(
"min_hit_density")), scifiStation,
true) ||
523 if ((horizontalCheck) && (verticalCheck)) {
524 showerStart = scifiStation - 1;
537 LOG(FATAL) <<
"Please use method=0. No other methods implemented so far.";
540 std::map<std::string, float> selection_parameters = {{
"radius", 64.}, {
"min_hit_density", 36.}};
Float_t GetTime(Int_t nChannel=0)