SND@LHC Software
Loading...
Searching...
No Matches
snd::analysis_tools Namespace Reference

Classes

class  ScifiPlane
 
class  USPlane
 

Functions

std::string GetGeoPath (int run_number, std::string csv_file_path="")
 
std::pair< Scifi *, MuFilter * > GetGeometry (const std::string &geometry_path)
 
std::pair< Scifi *, MuFilter * > GetGeometry (int run_number, const std::string &csv_file_path="")
 
std::vector< ScifiPlaneFillScifi (const Configuration &configuration, TClonesArray *sf_hits, Scifi *scifi_geometry)
 
std::vector< USPlaneFillUS (const Configuration &configuration, TClonesArray *mufi_hits, MuFilter *mufilter_geometry, bool use_small_sipms=false)
 
void getSciFiHitsPerStation (const TClonesArray *digiHits, std::vector< int > &horizontal_hits, std::vector< int > &vertical_hits)
 
int getTotalSciFiHits (std::vector< int > &horizontal_hits, std::vector< int > &vertical_hits)
 
int getTotalSciFiHits (const TClonesArray *digiHits)
 
std::vector< float > getFractionalHitsPerScifiPlane (std::vector< int > &horizontal_hits, std::vector< int > &vertical_hits)
 
std::vector< float > getFractionalHitsPerScifiPlane (const TClonesArray *digiHits)
 
int findScifiStation (std::vector< int > &horizontal_hits, std::vector< int > &vertical_hits, float threshold)
 
int findScifiStation (const TClonesArray *digiHits, float threshold)
 
float peakScifiTiming (const TClonesArray &digiHits, int bins, float min_x, float max_x, bool isMC=false)
 
std::unique_ptr< TClonesArray > getScifiHits (const TClonesArray &digiHits, int station, bool orientation)
 
std::unique_ptr< TClonesArray > selectScifiHits (const TClonesArray &digiHits, int station, bool orientation, int bins_x=52, float min_x=0.0, float max_x=26.0, float time_lower_range=1E9/(2 *ShipUnit::snd_freq/ShipUnit::hertz), float time_upper_range=1.2E9/(ShipUnit::snd_freq/ShipUnit::hertz), bool make_selection=true, bool isMC=false)
 
std::unique_ptr< TClonesArray > selectScifiHits (const TClonesArray &digiHits, int station, bool orientation, const std::map< std::string, float > &selection_parameters, bool make_selection=true, bool isMC=false)
 
std::unique_ptr< TClonesArray > filterScifiHits (const TClonesArray &digiHits, const std::map< std::string, float > &selection_parameters, int method=0, std::string setup="TI18", bool isMC=false)
 
std::unique_ptr< TClonesArray > filterScifiHits (const TClonesArray &digiHits, int method=0, std::string setup="TI18", bool isMC=false)
 
int calculateSiPMNumber (int reference_SiPM)
 
int densityScifi (int reference_SiPM, const TClonesArray &digiHits, int radius, int min_hit_density, bool min_check)
 
bool densityCheck (const TClonesArray &digiHits, int radius=64, int min_hit_density=36, int station=1, bool orientation=false)
 
int showerInteractionWall (const TClonesArray &digiHits, const std::map< std::string, float > &selection_parameters, int method=0, std::string setup="TI18")
 
int showerInteractionWall (const TClonesArray &digiHits, int method=0, std::string setup="TI18")
 
std::pair< double, double > findCentreOfGravityPerStation (const TClonesArray *digiHits, int station, Scifi *ScifiDet)
 
std::pair< std::vector< double >, std::vector< double > > hitPositionVectorsPerStation (const TClonesArray *digiHits, int station, Scifi *ScifiDet)
 
std::pair< double, double > hitDensityPerStation (const TClonesArray *digiHits, int station, Scifi *ScifiDet)
 
int GetScifiShowerStart (const std::vector< ScifiPlane > &scifi_planes)
 
int GetScifiShowerEnd (const std::vector< ScifiPlane > &scifi_planes)
 
int GetUSShowerStart (const std::vector< USPlane > &us_planes)
 
int GetUSShowerEnd (const std::vector< USPlane > &us_planes)
 
std::pair< ROOT::Math::XYZPoint, ROOT::Math::XYZVector > GetShowerInterceptAndDirection (const Configuration &configuration, const std::vector< ScifiPlane > &scifi_planes, const std::vector< USPlane > &us_planes)
 
std::pair< std::vector< ScifiPlane >, std::vector< USPlane > > GetShoweringPlanes (const std::vector< ScifiPlane > &scifi_planes, const std::vector< USPlane > &us_planes)
 
std::pair< double, double > GetSciFiSpatialAnisotropy (const std::vector< ScifiPlane > &scifi_planes, bool use_all_centroids=false)
 
double GetUSSpatialAnisotropy (const std::vector< USPlane > &us_planes, bool use_all_centroids=false)
 
std::unique_ptr< TChain > GetTChain (int run_number, int n_files=-1, const std::string &csv_file_path="")
 
std::unique_ptr< TChain > GetTChain (const std::string &file_name)
 
std::string GetDataBasePath (int run_number, std::string csv_file_path="")
 

Function Documentation

◆ calculateSiPMNumber()

int snd::analysis_tools::calculateSiPMNumber ( int  reference_SiPM)

Definition at line 381 of file sndSciFiTools.cxx.

382{
383
384 int ref_matAux = reference_SiPM % 100000;
385 int ref_mat = ref_matAux / 10000;
386 int ref_arrayAux = reference_SiPM % 10000;
387 int ref_array = ref_arrayAux / 1000;
388 int ref_channel = reference_SiPM % 1000;
389 int referenceChannel = ref_mat * 4 * 128 + ref_array * 128 + ref_channel;
390
391 return referenceChannel;
392}

◆ densityCheck()

bool snd::analysis_tools::densityCheck ( const TClonesArray &  digiHits,
int  radius = 64,
int  min_hit_density = 36,
int  station = 1,
bool  orientation = false 
)

Definition at line 433 of file sndSciFiTools.cxx.

435{
436
437 if (digiHits.GetEntries() <= 0) {
438 return false;
439 }
440
441 if (radius <= 0) {
442 LOG(FATAL) << "Radius<=0. Please provide a radius bigger than 0.";
443 return false;
444 }
445
446 if (min_hit_density < 0) {
447 LOG(FATAL) << "Min_hit_density < 0. Please provide a min_hit_density >= 0.";
448 return false;
449 }
450
451 if (min_hit_density > 2 * radius) {
452 LOG(warning) << "Warning! Radius of density check does not allow for the required minimum density!";
453 return false;
454 }
455
456 // Creating a vector that stores the fired SiPM channels (should already be ordered but we sort
457 // afterwards to make sure)
458 std::vector<int> fired_channels{};
459
460 // Only fill the set with hits from the same station and with the same orientation as given in
461 // argument (false==horizontal and true==vertical)
462 for (auto *p : digiHits) {
463 auto *hit = dynamic_cast<sndScifiHit *>(p);
464 if (!validateHit(hit, station, orientation)) {
465 continue;
466 }
467 fired_channels.push_back(calculateSiPMNumber(hit->GetChannelID()));
468 }
469
470 int n_fired_channels = fired_channels.size();
471
472 if (n_fired_channels < min_hit_density) {
473 return false;
474 }
475
476 // Looping over the ordered hits, checking whether within an interval of "min_hit_density" the
477 // difference between the channel IDs is smaller than "radius". If so, then we have the required
478 // density. Else, we check the next combination until we meet the criterion, or end the loop,
479 // returning false
480 std::sort(fired_channels.begin(), fired_channels.end());
481 for (int i = 0; i < n_fired_channels - min_hit_density; i++) {
482
483 if (fired_channels[i + min_hit_density - 1] - fired_channels[i] <= radius * 2) {
484 return true;
485 }
486 }
487 return false;
488}
int i
Definition ShipAna.py:86
int calculateSiPMNumber(int reference_SiPM)
bool validateHit(sndScifiHit *aHit, int ref_station, bool ref_orientation)

◆ densityScifi()

int snd::analysis_tools::densityScifi ( int  reference_SiPM,
const TClonesArray &  digiHits,
int  radius,
int  min_hit_density,
bool  min_check 
)

Definition at line 394 of file sndSciFiTools.cxx.

396{
397
398 int hit_density = 0;
399
400 bool orientation = false;
401 if (int(reference_SiPM / 100000) % 10 == 1) {
402 orientation = true;
403 }
404 int ref_station = reference_SiPM / 1000000;
405 int referenceChannel = calculateSiPMNumber(reference_SiPM);
406
407 for (auto *p : digiHits) {
408 auto *hit = dynamic_cast<sndScifiHit *>(p);
409 if (!validateHit(hit, ref_station, orientation)) {
410 continue;
411 }
412 int hitChannel = calculateSiPMNumber(hit->GetChannelID());
413 if (radius == -1) {
414 hit_density++;
415 } else {
416 if (hitChannel > referenceChannel + radius) {
417 break;
418 }
419 if (abs(referenceChannel - hitChannel) <= radius) {
420 hit_density++;
421 }
422 }
423
424 if (min_check && (hit_density >= min_hit_density)) {
425 break;
426 }
427 }
428
429 return hit_density;
430}

◆ FillScifi()

std::vector< snd::analysis_tools::ScifiPlane > snd::analysis_tools::FillScifi ( const Configuration configuration,
TClonesArray *  sf_hits,
Scifi scifi_geometry 
)

Definition at line 14 of file sndPlaneTools.cxx.

15{
16
17 std::vector<snd::analysis_tools::ScifiPlane> scifi_planes;
18 int n_sf_hits{sf_hits->GetEntries()};
19
20 const int max_station = configuration.scifi_n_stations;
21 std::vector<std::vector<sndScifiHit*>> stations_hits(max_station);
22
23 for (int i{0}; i < n_sf_hits; ++i) {
24 auto hit = static_cast<sndScifiHit*>(sf_hits->At(i));
25 int station_id = hit->GetStation()-1;
26
27 if (station_id > -1 && station_id < max_station) {
28 stations_hits[station_id].push_back(hit);
29 }
30 else throw std::runtime_error{"Invalid SciFi station"};
31 }
32 for (int st{0}; st < max_station; ++st) {
33 scifi_planes.emplace_back(snd::analysis_tools::ScifiPlane(stations_hits[st], configuration, scifi_geometry, st+1));
34 }
35 return scifi_planes;
36}
Int_t GetStation()
Definition sndScifiHit.h:31

◆ FillUS()

std::vector< snd::analysis_tools::USPlane > snd::analysis_tools::FillUS ( const Configuration configuration,
TClonesArray *  mufi_hits,
MuFilter mufilter_geometry,
bool  use_small_sipms = false 
)

Definition at line 39 of file sndPlaneTools.cxx.

40{
41
42 std::vector<snd::analysis_tools::USPlane> us_planes;
43 int n_mufi_hits{mufi_hits->GetEntries()};
44
45 const int n_station = configuration.us_n_stations;
46 std::vector<std::vector<MuFilterHit*>> plane_hits(n_station);
47
48 for (int i{0}; i < n_mufi_hits; ++i) {
49 auto hit = static_cast<MuFilterHit*>(mufi_hits->At(i));
50 if (hit->GetSystem()!=2) continue;
51 int station_id = hit->GetPlane();
52 if (station_id > -1 && station_id < n_station) {
53 plane_hits[station_id].push_back(hit);
54 }
55 else throw std::runtime_error{"Invalid US plane"};
56 }
57 for (int st{0}; st < n_station; ++st) {
58 us_planes.emplace_back(snd::analysis_tools::USPlane(plane_hits[st], configuration, mufilter_geometry, st+1, use_small_sipms));
59 }
60 return us_planes;
61}
int GetPlane()
Definition MuFilterHit.h:42

◆ filterScifiHits() [1/2]

std::unique_ptr< TClonesArray > snd::analysis_tools::filterScifiHits ( const TClonesArray &  digiHits,
const std::map< std::string, float > &  selection_parameters,
int  method = 0,
std::string  setup = "TI18",
bool  isMC = false 
)

Definition at line 308 of file sndSciFiTools.cxx.

311{
312 TClonesArray supportArray("sndScifiHit", 0);
313 auto filteredHits = std::make_unique<TClonesArray>("sndScifiHit", digiHits.GetEntries());
314 int filteredHitsIndex = 0;
315 int ScifiStations = 5;
316 if (setup == "H8") {
317 ScifiStations = 4;
318 } else {
319 LOG(info) << "\"TI18\" setup will be used by default, please provide \"H8\" for the Testbeam setup.";
320 }
321
322 TIter hitIterator(&supportArray);
323
324 if (method == 0) {
325
326 if ((selection_parameters.find("bins_x") == selection_parameters.end()) ||
327 (selection_parameters.find("min_x") == selection_parameters.end()) ||
328 (selection_parameters.find("max_x") == selection_parameters.end()) ||
329 (selection_parameters.find("time_lower_range") == selection_parameters.end())) {
330 LOG(FATAL) << "In order to use method 0 please provide the correct selection_parameters. Consider the default "
331 "= {{\"bins_x\", 52.}, {\"min_x\", 0.}, {\"max_x\", 26.}, {\"time_lower_range\", "
332 "1E9/(2*ShipUnit::snd_freq/ShipUnit::hertz)}, {\"time_upper_range\", "
333 "1.2E9/(ShipUnit::snd_freq/ShipUnit::hertz)}}";
334 }
335
336 // This is overwriting the previous arrays with the newest one
337 for (auto station : ROOT::MakeSeq(1, ScifiStations + 1)) {
338 for (auto orientation : {false, true}) {
339
340 auto supportArray_p = selectScifiHits(digiHits, station, orientation, selection_parameters, true, isMC);
341 for (auto *p : *supportArray_p) {
342 auto *hit = dynamic_cast<sndScifiHit *>(p);
343 if (hit->isValid()) {
344 new ((*filteredHits)[filteredHitsIndex++]) sndScifiHit(*hit);
345 }
346 }
347 }
348 }
349 } else {
350 LOG(error) << "Please provide a valid time filter method from:";
351 LOG(error) << "(0): Events within \\mp time_lower_range time_upper_range of the peak of the time distribution "
352 "for Scifi Hits within each station and orientation";
353 LOG(FATAL) << "selection_parameters = {bins_x, min_x, max_x, time_lower_range, time_upper_range}.";
354 }
355 return filteredHits;
356}
std::unique_ptr< TClonesArray > selectScifiHits(const TClonesArray &digiHits, int station, bool orientation, int bins_x=52, float min_x=0.0, float max_x=26.0, float time_lower_range=1E9/(2 *ShipUnit::snd_freq/ShipUnit::hertz), float time_upper_range=1.2E9/(ShipUnit::snd_freq/ShipUnit::hertz), bool make_selection=true, bool isMC=false)

◆ filterScifiHits() [2/2]

std::unique_ptr< TClonesArray > snd::analysis_tools::filterScifiHits ( const TClonesArray &  digiHits,
int  method = 0,
std::string  setup = "TI18",
bool  isMC = false 
)

Definition at line 359 of file sndSciFiTools.cxx.

360{
361
362 std::map<std::string, float> selection_parameters;
363
364 if (method == 0) {
365
366 selection_parameters["bins_x"] = 52.0;
367 selection_parameters["min_x"] = 0.0;
368 selection_parameters["max_x"] = 26.0;
369 selection_parameters["time_lower_range"] = 1E9 / (2 * ShipUnit::snd_freq / ShipUnit::hertz);
370 selection_parameters["time_upper_range"] = 1.2E9 / (ShipUnit::snd_freq / ShipUnit::hertz);
371
372 } else {
373 LOG(FATAL) << "Please use method=0. No other methods implemented so far.";
374 }
375
376 return filterScifiHits(digiHits, selection_parameters, method, setup, isMC);
377}

◆ findCentreOfGravityPerStation()

std::pair< double, double > snd::analysis_tools::findCentreOfGravityPerStation ( const TClonesArray *  digiHits,
int  station,
Scifi ScifiDet 
)

Definition at line 573 of file sndSciFiTools.cxx.

574{
575 if (!digiHits) {
576 LOG(ERROR) << "Error: digiHits is null in findCentreOfGravityPerStation";
577 }
578
579 auto [x_positions, y_positions] = snd::analysis_tools::hitPositionVectorsPerStation(digiHits, station, ScifiDet);
580
581 if (x_positions.empty()) {
582 LOG(ERROR) << "Error: No hits enter.";
583 }
584 double meanX = computeMean(x_positions);
585 if (y_positions.empty()) {
586 LOG(ERROR) << "Error: No hits enter.";
587 }
588 double meanY = computeMean(y_positions);
589 return {meanX, meanY};
590}
std::pair< std::vector< double >, std::vector< double > > hitPositionVectorsPerStation(const TClonesArray *digiHits, int station, Scifi *ScifiDet)
double computeMean(const std::vector< double > &values)

◆ findScifiStation() [1/2]

int snd::analysis_tools::findScifiStation ( const TClonesArray *  digiHits,
float  threshold 
)

Definition at line 96 of file sndSciFiTools.cxx.

97{
98 std::vector<int> horizontal_hits = std::vector<int>(5);
99 std::vector<int> vertical_hits = std::vector<int>(5);
100
101 getSciFiHitsPerStation(digiHits, horizontal_hits, vertical_hits);
102
103 return findScifiStation(horizontal_hits, vertical_hits, threshold);
104}
int findScifiStation(std::vector< int > &horizontal_hits, std::vector< int > &vertical_hits, float threshold)
void getSciFiHitsPerStation(const TClonesArray *digiHits, std::vector< int > &horizontal_hits, std::vector< int > &vertical_hits)

◆ findScifiStation() [2/2]

int snd::analysis_tools::findScifiStation ( std::vector< int > &  horizontal_hits,
std::vector< int > &  vertical_hits,
float  threshold 
)

Definition at line 80 of file sndSciFiTools.cxx.

82{
83
84 std::vector<float> frac = getFractionalHitsPerScifiPlane(horizontal_hits, vertical_hits);
85
86 std::vector<float> frac_sum = std::vector<float>(frac.size());
87
88 std::partial_sum(frac.begin(), frac.end(), frac_sum.begin());
89
90 std::vector<float>::iterator station =
91 std::find_if(frac_sum.begin(), frac_sum.end(), [&threshold](const auto &f) { return f > threshold; });
92
93 return station - frac_sum.begin() + 1;
94}
std::vector< float > getFractionalHitsPerScifiPlane(std::vector< int > &horizontal_hits, std::vector< int > &vertical_hits)

◆ GetDataBasePath()

std::string snd::analysis_tools::GetDataBasePath ( int  run_number,
std::string  csv_file_path = "" 
)

Definition at line 13 of file sndTchainGetter.cxx.

13 {
14 if (csv_file_path.empty()) {
15 csv_file_path = std::string(getenv("SNDSW_ROOT")) + "/analysis/tools/data_paths.csv";
16 }
17 std::ifstream file(csv_file_path);
18 if (!file.is_open()) {
19 throw std::runtime_error("Could not open CSV file: " + csv_file_path);
20 }
21
22 std::string line;
23 std::getline(file, line); // skip header
24
25 while (std::getline(file, line)) {
26 std::istringstream ss(line);
27 std::string token;
28
29 std::getline(ss, token, ',');
30 int min_run = std::stoi(token);
31
32 std::getline(ss, token, ',');
33 int max_run = std::stoi(token);
34
35 std::getline(ss, token);
36 std::string path = token;
37
38 if (run_number >= min_run && run_number <= max_run) {
39 return path;
40 }
41 }
42 throw std::runtime_error("Run number not found in CSV mapping.");
43}

◆ getFractionalHitsPerScifiPlane() [1/2]

std::vector< float > snd::analysis_tools::getFractionalHitsPerScifiPlane ( const TClonesArray *  digiHits)

Definition at line 70 of file sndSciFiTools.cxx.

71{
72 std::vector<int> horizontal_hits = std::vector<int>(5);
73 std::vector<int> vertical_hits = std::vector<int>(5);
74
75 getSciFiHitsPerStation(digiHits, horizontal_hits, vertical_hits);
76
77 return getFractionalHitsPerScifiPlane(horizontal_hits, vertical_hits);
78}

◆ getFractionalHitsPerScifiPlane() [2/2]

std::vector< float > snd::analysis_tools::getFractionalHitsPerScifiPlane ( std::vector< int > &  horizontal_hits,
std::vector< int > &  vertical_hits 
)

Definition at line 56 of file sndSciFiTools.cxx.

57{
58
59 int total_hits = getTotalSciFiHits(horizontal_hits, vertical_hits);
60
61 std::vector<float> fractional_hits_per_station = std::vector<float>(horizontal_hits.size());
62
63 std::transform(horizontal_hits.begin(), horizontal_hits.end(), vertical_hits.begin(),
64 fractional_hits_per_station.begin(),
65 [&total_hits](const auto &hor, const auto &ver) { return ((float)hor + ver) / total_hits; });
66
67 return fractional_hits_per_station;
68}
int getTotalSciFiHits(std::vector< int > &horizontal_hits, std::vector< int > &vertical_hits)

◆ GetGeometry() [1/2]

std::pair< Scifi *, MuFilter * > snd::analysis_tools::GetGeometry ( const std::string &  geometry_path)

Definition at line 49 of file sndGeometryGetter.cxx.

50{
51 TPython::Exec("import SndlhcGeo");
52 TPython::Exec(("SndlhcGeo.GeoInterface('" + geometry_path + "')").c_str());
53
54 // Init detectors
55 Scifi *scifi = new Scifi("Scifi", kTRUE);
56 MuFilter *mufilter = new MuFilter("MuFilter", kTRUE);
57
58 // Retrieve the detectors from ROOT's global list
59 scifi = dynamic_cast<Scifi *>(gROOT->GetListOfGlobals()->FindObject("Scifi"));
60 mufilter = dynamic_cast<MuFilter *>(gROOT->GetListOfGlobals()->FindObject("MuFilter"));
61
62 return std::make_pair(scifi, mufilter);
63}
Definition Scifi.h:20

◆ GetGeometry() [2/2]

std::pair< Scifi *, MuFilter * > snd::analysis_tools::GetGeometry ( int  run_number,
const std::string &  csv_file_path = "" 
)

Definition at line 66 of file sndGeometryGetter.cxx.

67{
68 std::string geometry_path = GetGeoPath(run_number, csv_file_path);
69
70 return GetGeometry(geometry_path);
71}
std::string GetGeoPath(int run_number, std::string csv_file_path="")
std::pair< Scifi *, MuFilter * > GetGeometry(const std::string &geometry_path)

◆ GetGeoPath()

std::string snd::analysis_tools::GetGeoPath ( int  run_number,
std::string  csv_file_path = "" 
)

Definition at line 15 of file sndGeometryGetter.cxx.

16{
17 if (csv_file_path.empty()) {
18 csv_file_path = std::string(getenv("SNDSW_ROOT")) + "/analysis/tools/geo_paths.csv";
19 }
20 std::ifstream file(csv_file_path);
21 if (!file.is_open()) {
22 throw std::runtime_error("Could not open CSV file: " + csv_file_path);
23 }
24
25 std::string line;
26 std::getline(file, line); // skip header
27
28 while (std::getline(file, line)) {
29 std::istringstream ss(line);
30 std::string token;
31
32 std::getline(ss, token, ',');
33 int min_run = std::stoi(token);
34
35 std::getline(ss, token, ',');
36 int max_run = std::stoi(token);
37
38 std::getline(ss, token);
39 std::string path = token;
40
41 if (run_number >= min_run && run_number <= max_run) {
42 return path;
43 }
44 }
45 throw std::runtime_error("Run number not found in CSV mapping.");
46}

◆ getScifiHits()

std::unique_ptr< TClonesArray > snd::analysis_tools::getScifiHits ( const TClonesArray &  digiHits,
int  station,
bool  orientation 
)

Definition at line 171 of file sndSciFiTools.cxx.

172{
173
174 auto selectedHits = std::make_unique<TClonesArray>("sndScifiHit");
175
176 int i = 0;
177 for (auto *p : digiHits) {
178 auto *hit = dynamic_cast<sndScifiHit *>(p);
179 if (!validateHit(hit, station, orientation)) {
180 continue;
181 }
182 new ((*selectedHits)[i++]) sndScifiHit(*hit);
183 }
184
185 return selectedHits;
186}

◆ getSciFiHitsPerStation()

void snd::analysis_tools::getSciFiHitsPerStation ( const TClonesArray *  digiHits,
std::vector< int > &  horizontal_hits,
std::vector< int > &  vertical_hits 
)

Definition at line 15 of file sndSciFiTools.cxx.

17{
18
19 // Clear hits per plane vectors
20 std::fill(horizontal_hits.begin(), horizontal_hits.end(), 0);
21 std::fill(vertical_hits.begin(), vertical_hits.end(), 0);
22
23 // Add valid hits to hits per plane vectors
24 sndScifiHit *hit;
25 TIter hitIterator(digiHits);
26
27 while ((hit = dynamic_cast<sndScifiHit *>(hitIterator.Next()))) {
28 if (hit->isValid()) {
29 int station = hit->GetStation();
30 if (hit->isVertical()) {
31 vertical_hits[station - 1]++;
32 } else {
33 horizontal_hits[station - 1]++;
34 }
35 }
36 }
37}
bool isValid() const
Definition sndScifiHit.h:30
bool isVertical()
Definition sndScifiHit.h:32

◆ GetScifiShowerEnd()

int snd::analysis_tools::GetScifiShowerEnd ( const std::vector< ScifiPlane > &  scifi_planes)

◆ GetScifiShowerStart()

int snd::analysis_tools::GetScifiShowerStart ( const std::vector< ScifiPlane > &  scifi_planes)

◆ GetSciFiSpatialAnisotropy()

std::pair< double, double > snd::analysis_tools::GetSciFiSpatialAnisotropy ( const std::vector< ScifiPlane > &  scifi_planes,
bool  use_all_centroids = false 
)

Definition at line 209 of file sndShowerTools.cxx.

210{
211 std::vector<double> x, y, zx, zy;
212 for (auto &p : scifi_planes) {
213 // Add measurements per projection and in the respective coordinate vectors
214 if (use_all_centroids == false) {
215 for (auto &hit : p.GetHits()) {
216 if (hit.is_x) {
217 x.push_back(hit.x);
218 zx.push_back(hit.z);
219 } else {
220 y.push_back(hit.y);
221 zy.push_back(hit.z);
222 }
223 }
224 } else {
225 auto centroid = p.GetCentroid();
226 // Check that centroid is valid
227 if (!std::isnan(centroid.Z())) {
228 if (!std::isnan(centroid.X())) {
229 x.push_back(centroid.X());
230 zx.push_back(centroid.Z());
231 }
232 if (!std::isnan(centroid.Y())) {
233 y.push_back(centroid.Y());
234 zy.push_back(centroid.Z());
235 }
236 }
237 }
238 }
239
240 // Need at least 3 measurements
241 if (x.size() < 2 || y.size() < 2 || zx.size() < 2 || zy.size() < 2) {
242 return {1., 1.};
243 }
244 double lambda1, lambda2;
245 std::tie(lambda1, lambda2) = PCA(x, zx);
246 double anisotropy_xz = (lambda1 > 0) ? 1.0 - lambda2 / lambda1 : 0.0;
247 std::tie(lambda1, lambda2) = PCA(y, zy);
248 double anisotropy_yz = (lambda1 > 0) ? 1.0 - lambda2 / lambda1 : 0.0;
249 return {anisotropy_xz, anisotropy_yz};
250}
std::pair< double, double > PCA(const std::vector< double > &u, const std::vector< double > &z)

◆ GetShoweringPlanes()

std::pair< std::vector< ScifiPlane >, std::vector< USPlane > > snd::analysis_tools::GetShoweringPlanes ( const std::vector< ScifiPlane > &  scifi_planes,
const std::vector< USPlane > &  us_planes 
)

◆ GetShowerInterceptAndDirection()

std::pair< ROOT::Math::XYZPoint, ROOT::Math::XYZVector > snd::analysis_tools::GetShowerInterceptAndDirection ( const Configuration configuration,
const std::vector< ScifiPlane > &  scifi_planes,
const std::vector< USPlane > &  us_planes 
)

◆ GetTChain() [1/2]

std::unique_ptr< TChain > snd::analysis_tools::GetTChain ( const std::string &  file_name)

Definition at line 59 of file sndTchainGetter.cxx.

59 {
60 auto tchain = std::make_unique<TChain>("rawConv");
61 tchain->Add(file_name.c_str());
62 return tchain;
63}

◆ GetTChain() [2/2]

std::unique_ptr< TChain > snd::analysis_tools::GetTChain ( int  run_number,
int  n_files = -1,
const std::string &  csv_file_path = "" 
)

Definition at line 45 of file sndTchainGetter.cxx.

45 {
46 std::string base_folder = GetDataBasePath(run_number, csv_file_path);
47 auto tchain = std::make_unique<TChain>("rawConv");
48 if (n_files == -1) {
49 tchain->Add(Form("%srun_%06d/sndsw_raw-*", base_folder.c_str(), run_number));
50 }
51 else {
52 for (int i = 0; i<n_files; ++i){
53 tchain->Add(Form("%srun_%06d/sndsw_raw-%04d.root", base_folder.c_str(), run_number, i));
54 }
55 }
56 return tchain;
57};
std::string GetDataBasePath(int run_number, std::string csv_file_path="")

◆ getTotalSciFiHits() [1/2]

int snd::analysis_tools::getTotalSciFiHits ( const TClonesArray *  digiHits)

Definition at line 45 of file sndSciFiTools.cxx.

46{
47 std::vector<int> horizontal_hits = std::vector<int>(5);
48 std::vector<int> vertical_hits = std::vector<int>(5);
49
50 getSciFiHitsPerStation(digiHits, horizontal_hits, vertical_hits);
51
52 return getTotalSciFiHits(horizontal_hits, vertical_hits);
53}

◆ getTotalSciFiHits() [2/2]

int snd::analysis_tools::getTotalSciFiHits ( std::vector< int > &  horizontal_hits,
std::vector< int > &  vertical_hits 
)

Definition at line 39 of file sndSciFiTools.cxx.

40{
41 return std::accumulate(horizontal_hits.begin(), horizontal_hits.end(),
42 std::accumulate(vertical_hits.begin(), vertical_hits.end(), 0));
43}

◆ GetUSShowerEnd()

int snd::analysis_tools::GetUSShowerEnd ( const std::vector< USPlane > &  us_planes)

◆ GetUSShowerStart()

int snd::analysis_tools::GetUSShowerStart ( const std::vector< USPlane > &  us_planes)

◆ GetUSSpatialAnisotropy()

double snd::analysis_tools::GetUSSpatialAnisotropy ( const std::vector< USPlane > &  us_planes,
bool  use_all_centroids = false 
)

Definition at line 252 of file sndShowerTools.cxx.

253{
254 std::vector<double> y, zy;
255 for (auto &p : us_planes) {
256 // Add measurements per projection and in the respective coordinate vectors
257 if (use_all_centroids == false) {
258 for (auto &hit : p.GetHits()) {
259 y.push_back(hit.y);
260 zy.push_back(hit.z);
261 }
262 } else {
263 auto centroid = p.GetCentroid();
264 // Check that centroid is valid
265 if (!(std::isnan(centroid.Z()) || std::isnan(centroid.Y()))) {
266 y.push_back(centroid.Y());
267 zy.push_back(centroid.Z());
268 }
269 }
270 }
271
272 // Need at least 3 measurements
273 if (y.size() < 2 || zy.size() < 2) {
274 return 1.;
275 }
276 double lambda1, lambda2;
277 std::tie(lambda1, lambda2) = PCA(y, zy);
278 return (lambda1 > 0) ? 1.0 - lambda2 / lambda1 : 0.0;
279}

◆ hitDensityPerStation()

std::pair< double, double > snd::analysis_tools::hitDensityPerStation ( const TClonesArray *  digiHits,
int  station,
Scifi ScifiDet 
)

Definition at line 706 of file sndSciFiTools.cxx.

706 {
707 /*
708 This function returns the hit density which is described as the summation of the hit weights
709 where a hit weigth is the number of neighbouring hits within 1 cm postion (default width)
710 arguments: hit position vector : vector ontaining the positions of the hits in a specific SciFi station
711 returns: the sum of the weights of the hits in the vector
712 If the vector is empty, it returns 0.
713 If the sum of weights is 0, it returns 0.
714 */
715 std::pair<std::vector<double>, std::vector<double>> hit_position_vec = hitPositionVectorsPerStation(digiHits, station, ScifiDet);
716 std::vector<double> hit_position_x = hit_position_vec.first; // Assuming we are interested in X positions
717 std::vector<double> hit_position_y = hit_position_vec.second; // Assuming we are interested in Y positions
718
719 if (hit_position_x.size()==0 && hit_position_y.size()==0) {
720 LOG(INFO)<< "Warning: The hit position vector is empty." << std::endl;
721 return {0.0,0.0}; // Check if the vector is empty
722 }
723
724 double sum_weights_x = hitWeightComputation(hit_position_x);
725 double sum_weights_y = hitWeightComputation(hit_position_y);
726
727 return {sum_weights_x, sum_weights_y};
728}
double hitWeightComputation(std::vector< double > hit_position)

◆ hitPositionVectorsPerStation()

std::pair< std::vector< double >, std::vector< double > > snd::analysis_tools::hitPositionVectorsPerStation ( const TClonesArray *  digiHits,
int  station,
Scifi ScifiDet 
)

Definition at line 592 of file sndSciFiTools.cxx.

592 {
593 /*This function returns the hit vector position for the digiHits in both orientations
594 Arguments:
595 digiHits: A TClonesArray containing the hits in the SciFi detector.
596 station: The station number for which to retrieve the hit positions.
597 ScifiDet: A pointer to the Scifi detector object to retrieve SiPM positions.
598 Returns:
599 A pair of vectors containing the x and y positions of the hits in the specified station.
600 If no hits are found, it returns empty vectors and logs an error message.
601 */
602
603 if (!digiHits) {
604 LOG(ERROR) << "Error: digiHits is null";
605 }
606 std::vector<double> x_positions;
607 std::vector<double> y_positions;
608
609 TVector3 A, B;
610 for (auto* hit : ROOT::RRangeCast<sndScifiHit*, false, decltype(*digiHits)>(*digiHits)) {
611 if (!hit || !hit->isValid()) {
612 continue;
613 }
614 if (hit->GetStation() != station) {
615 continue;
616 }
617 ScifiDet->GetSiPMPosition(hit->GetDetectorID(), A, B);
618 if (hit->isVertical()) {
619 x_positions.push_back((A.X() + B.X()) * 0.5);
620 }
621 else {
622 y_positions.push_back((A.Y() + B.Y()) * 0.5);
623 }
624 }
625 if (x_positions.empty()) {
626 LOG(ERROR) << "Error: No hits enter.";
627 }
628 if (y_positions.empty()) {
629 LOG(ERROR) << "Error: No hits enter.";
630 }
631 return {x_positions, y_positions};
632}
void GetSiPMPosition(Int_t SiPMChan, TVector3 &A, TVector3 &B)
Definition Scifi.cxx:727

◆ peakScifiTiming()

float snd::analysis_tools::peakScifiTiming ( const TClonesArray &  digiHits,
int  bins,
float  min_x,
float  max_x,
bool  isMC = false 
)

Definition at line 127 of file sndSciFiTools.cxx.

128{
129
130 if (digiHits.GetEntries() <= 0) {
131 LOG(warning) << "digiHits has no valid SciFi Hits and as such no maximum for the timing distribution.";
132 return -1.;
133 }
134
135 TH1F ScifiTiming("Timing", "Scifi Timing", bins, min_x, max_x);
136
137 Scifi *ScifiDet = dynamic_cast<Scifi*> (gROOT->GetListOfGlobals()->FindObject("Scifi") );
138 auto* first_hit = static_cast<sndScifiHit*>(digiHits[0]);
139 int refStation = first_hit->GetStation();
140 bool refOrientation = first_hit->isVertical();
141 float hitTime = -1.0;
142 float timeConversion = 1.;
143 if (!isMC) {
144 timeConversion = 1E9 / (ShipUnit::snd_freq / ShipUnit::hertz);
145 }
146
147 for (auto *p : digiHits) {
148 auto *hit = dynamic_cast<sndScifiHit *>(p);
149 if (!validateHit(hit, refStation, refOrientation)) {
150 continue;
151 }
152 hitTime = hit->GetTime() * timeConversion;
153 if (!isMC){
154 int id_hit = hit ->GetDetectorID();
155 hitTime = ScifiDet->GetCorrectedTime(id_hit, hitTime, 0);
156 }
157 if (hitTime < min_x || hitTime > max_x) {
158 continue;
159 }
160 ScifiTiming.Fill(hitTime);
161 hitTime = -1.0;
162 }
163
164 float peakTiming = (ScifiTiming.GetMaximumBin() - 0.5) * (max_x - min_x) / bins + min_x;
165
166 return peakTiming;
167}
Double_t GetCorrectedTime(Int_t fDetectorID, Double_t rawTime, Double_t L)
Definition Scifi.cxx:614
Float_t GetTime(Int_t nChannel=0)
Definition SndlhcHit.cxx:32

◆ selectScifiHits() [1/2]

std::unique_ptr< TClonesArray > snd::analysis_tools::selectScifiHits ( const TClonesArray &  digiHits,
int  station,
bool  orientation,
const std::map< std::string, float > &  selection_parameters,
bool  make_selection = true,
bool  isMC = false 
)

Definition at line 278 of file sndSciFiTools.cxx.

281{
282
283 if ((selection_parameters.find("bins_x") == selection_parameters.end()) ||
284 (selection_parameters.find("min_x") == selection_parameters.end()) ||
285 (selection_parameters.find("max_x") == selection_parameters.end()) ||
286 (selection_parameters.find("time_lower_range") == selection_parameters.end())) {
287 LOG(FATAL) << "In order to use method 0 please provide the correct selection_parameters. Consider the default = "
288 "{{\"bins_x\", 52.}, {\"min_x\", 0.}, {\"max_x\", 26.}, {\"time_lower_range\", "
289 "1E9/(2*ShipUnit::snd_freq/ShipUnit::hertz))}, {\"time_upper_range\", "
290 "2E9/(ShipUnit::snd_freq/ShipUnit::hertz)}}";
291 }
292
293 float time_upper_range = -1.;
294
295 if (selection_parameters.find("time_upper_range") == selection_parameters.end()) {
296 time_upper_range = selection_parameters.at("time_lower_range");
297 } else {
298 time_upper_range = selection_parameters.at("time_upper_range");
299 }
300
301 return selectScifiHits(digiHits, station, orientation, int(selection_parameters.at("bins_x")),
302 selection_parameters.at("min_x"), selection_parameters.at("max_x"),
303 selection_parameters.at("time_lower_range"), time_upper_range, make_selection,
304 isMC);
305}

◆ selectScifiHits() [2/2]

std::unique_ptr< TClonesArray > snd::analysis_tools::selectScifiHits ( const TClonesArray &  digiHits,
int  station,
bool  orientation,
int  bins_x = 52,
float  min_x = 0.0,
float  max_x = 26.0,
float  time_lower_range = 1E9/(2*ShipUnit::snd_freq/ShipUnit::hertz),
float  time_upper_range = 1.2E9/(ShipUnit::snd_freq/ShipUnit::hertz),
bool  make_selection = true,
bool  isMC = false 
)

Definition at line 195 of file sndSciFiTools.cxx.

200{
201
202 if (bins_x < 1) {
203 LOG(FATAL) << "bins_x in selection_parameters cannot be <1. Consider using the default value of 52 instead.";
204 }
205 if (min_x > max_x) {
206 LOG(warning) << "In selection_parameters min_x > max_x. Values will be swapped.";
207 float aux_float = min_x;
208 min_x = max_x;
209 max_x = aux_float;
210 }
211 if (min_x < 0.0) {
212 LOG(warning) << "In selection_parameters min_x < 0.0. Consider using the default value of 0.0.";
213 }
214 if (max_x < 0.0) {
215 LOG(FATAL) << "In selection_parameters max_x < 0.0. Consider using the default value of 26.0.";
216 }
217 if (time_lower_range <= 0.0) {
218 LOG(FATAL) << "In selection_parameters time_lower_range <= 0.0. Value should always be positive, in ns.";
219 }
220 if (time_upper_range <= 0.0) {
221 LOG(FATAL) << "In selection_parameters time_upper_range <= 0.0. Value should always be positive, in ns.";
222 }
223
224 auto filteredHits = std::make_unique<TClonesArray>("sndScifiHit", digiHits.GetEntries());
225
226 float peakTiming = -1.0;
227
228 float timeConversion = 1.;
229 if (!isMC) {
230 timeConversion = 1E9 / (ShipUnit::snd_freq / ShipUnit::hertz);
231 }
232
233 if (make_selection) {
234
235 auto selectedHits = getScifiHits(digiHits, station, orientation);
236
237 peakTiming = peakScifiTiming(*selectedHits, bins_x, min_x, max_x, isMC);
238
239 int i = 0;
240 for (auto *p : *selectedHits) {
241 auto *hit = dynamic_cast<sndScifiHit *>(p);
242 if (!validateHit(hit, station, orientation)) {
243 continue;
244 }
245 if ((peakTiming - time_lower_range > hit->GetTime() * timeConversion) ||
246 (hit->GetTime() * timeConversion > peakTiming + time_upper_range)) {
247 continue;
248 }
249 new ((*filteredHits)[i++]) sndScifiHit(*hit);
250 }
251
252 } else {
253 // Does not create selectedHits and just uses digiHits (not unique_ptr)
254
255 peakTiming = peakScifiTiming(digiHits, bins_x, min_x, max_x, isMC);
256
257 int i = 0;
258 for (auto *p : digiHits) {
259 auto *hit = dynamic_cast<sndScifiHit *>(p);
260 if (!validateHit(hit, station, orientation)) {
261 continue;
262 }
263 if ((peakTiming - time_lower_range > hit->GetTime() * timeConversion) ||
264 (hit->GetTime() * timeConversion > peakTiming + time_upper_range)) {
265 continue;
266 }
267 new ((*filteredHits)[i++]) sndScifiHit(*hit);
268 }
269 }
270
271 return filteredHits;
272}
float peakScifiTiming(const TClonesArray &digiHits, int bins, float min_x, float max_x, bool isMC=false)
std::unique_ptr< TClonesArray > getScifiHits(const TClonesArray &digiHits, int station, bool orientation)

◆ showerInteractionWall() [1/2]

int snd::analysis_tools::showerInteractionWall ( const TClonesArray &  digiHits,
const std::map< std::string, float > &  selection_parameters,
int  method = 0,
std::string  setup = "TI18" 
)

Definition at line 496 of file sndSciFiTools.cxx.

499{
500
501 int totalScifiStations = 5;
502 if (setup == "H8") {
503 totalScifiStations = 4;
504 } else {
505 LOG(info) << "\"TI18\" setup will be used by default, please provide \"H8\" for the Testbeam setup.";
506 }
507
508 // There is always 1 more Scifi Station than a target block. As such, showerStart == totalScifiStations
509 // means that the shower did not start developing in the target, before the last Scifi Station
510 int showerStart = totalScifiStations;
511
512 if (method == 0) {
513
514 if ((selection_parameters.find("radius") == selection_parameters.end()) ||
515 (selection_parameters.find("min_hit_density") == selection_parameters.end())) {
516 LOG(FATAL)
517 << "Argument of select_parameters is incorrect. Please provide a map with the arguments \"radius\" and "
518 "\"min_hit_density\". Consider using the default values of {{\"radius\",64}, {\"min_hit_density\",36}}.";
519 }
520
521 for (int scifiStation = 1; scifiStation <= totalScifiStations; scifiStation++) {
522
523 // For each ScifiStation we check whether we see clusters with the desired parameters
524 // By default, we require passing the check on both the horizontal and vertical mats
525 // In case selection_parameters["orientation"] was provided, we set the NOT CHOSEN orientation
526 // as true by default, so as to only need to pass the chosen orientation check
527 bool horizontalCheck = false;
528 bool verticalCheck = false;
529 if (selection_parameters.find("orientation") != selection_parameters.end()) {
530 if (int(selection_parameters.at("orientation")) == 0) {
531 verticalCheck = true;
532 }
533 if (int(selection_parameters.at("orientation")) == 1) {
534 horizontalCheck = true;
535 }
536 }
537 horizontalCheck = (densityCheck(digiHits, int(selection_parameters.at("radius")),
538 int(selection_parameters.at("min_hit_density")), scifiStation, false) ||
539 horizontalCheck);
540 verticalCheck = (densityCheck(digiHits, int(selection_parameters.at("radius")),
541 int(selection_parameters.at("min_hit_density")), scifiStation, true) ||
542 verticalCheck);
543 if ((horizontalCheck) && (verticalCheck)) {
544 showerStart = scifiStation - 1;
545 return showerStart;
546 }
547 }
548 }
549
550 return showerStart;
551}
bool densityCheck(const TClonesArray &digiHits, int radius=64, int min_hit_density=36, int station=1, bool orientation=false)

◆ showerInteractionWall() [2/2]

int snd::analysis_tools::showerInteractionWall ( const TClonesArray &  digiHits,
int  method = 0,
std::string  setup = "TI18" 
)

Definition at line 553 of file sndSciFiTools.cxx.

554{
555
556 if (method != 0) {
557 LOG(FATAL) << "Please use method=0. No other methods implemented so far.";
558 }
559
560 std::map<std::string, float> selection_parameters = {{"radius", 64.}, {"min_hit_density", 36.}};
561
562 return showerInteractionWall(digiHits, selection_parameters, method, setup);
563}
int showerInteractionWall(const TClonesArray &digiHits, const std::map< std::string, float > &selection_parameters, int method=0, std::string setup="TI18")