SND@LHC Software
Loading...
Searching...
No Matches
sndUSPlane.cxx
Go to the documentation of this file.
1#include "sndUSPlane.h"
2
3#include <cmath>
4#include <stdexcept>
5#include <algorithm>
6#include <vector>
7
8#include "TVector3.h"
9#include "MuFilter.h"
10#include "MuFilterHit.h"
11#include "ShipUnit.h"
12
13snd::analysis_tools::USPlane::USPlane(std::vector<MuFilterHit*> snd_hits, const Configuration &configuration, MuFilter *muon_filter_geometry, int station, bool use_small_sipms) : configuration_(configuration), centroid_(std::nan(""), std::nan(""), std::nan("")), centroid_error_(std::nan(""), std::nan(""),std::nan("")), station_(station)
14{
15 for ( auto mu_hit : snd_hits)
16 {
17 TVector3 A, B;
18 int detectorID = mu_hit->GetDetectorID();
19 muon_filter_geometry->GetPosition(detectorID, A, B);
20 for (int i{0}; i < 16; ++i)
21 {
22 if (mu_hit->isMasked(i) || mu_hit->GetSignal(i) < -990.) continue;
23 USHit hit;
24 hit.bar = static_cast<int>(detectorID % 1000);
25 hit.channel_index = 16 * hit.bar + i;
26 hit.is_large = !mu_hit->isShort(i);
27 hit.is_right = i > 7 ? true : false;
28
29 if (!hit.is_large && !use_small_sipms)
30 {
31 hit.timestamp = std::nan("");
32 hit.qdc = std::nan("");
33 hit.x = std::nan("");
34 hit.y = std::nan("");
35 hit.z = std::nan("");
36 }
37 else
38 {
39 hit.timestamp = configuration_.is_mc ? mu_hit->GetTime(i) / ShipUnit::snd_TDC2ns : mu_hit->GetTime(i);
40 hit.qdc = mu_hit->GetSignal(i);
41 // use the left and right measurements to calculate the x coordinate along the bar
42 float tmp_x = mu_hit->GetImpactXpos(true, true, false, configuration_.is_mc);
43 hit.x = (tmp_x < -990.) ? std::nan("") : A.X() - tmp_x;
44 hit.y = A.Y();
45 hit.z = A.Z();
46 }
47 hits_.push_back(hit);
48 }
49 }
50}
51
53{
54 // select large SiPM channels with positive qdc
55 std::vector<USHit> cleaned_hits = hits_;
56
57 cleaned_hits.erase(std::remove_if(cleaned_hits.begin(), cleaned_hits.end(),
58 [&](auto &hit)
59 { return (hit.qdc <= 0 || hit.is_large == false || std::isnan(hit.x)); }),
60 cleaned_hits.end());
61
62 // min number of hit in the plane to attempt to find a centroid
63 if (static_cast<int>(cleaned_hits.size()) < configuration_.us_min_n_hits_for_centroid)
64 {
65 return;
66 }
67
68 // weigthed sum calculated per plane
69 double weighted_sum_x{0.0}, weighted_sum_y{0.0}, weighted_sum_z{0.0};
70 double total_qdc_positive{0.0}, sum_qdc2_positive{0.0};
71 // loop over hits in the plane
72 for (const auto &hit : cleaned_hits)
73 {
74 weighted_sum_x += hit.x * hit.qdc;
75 weighted_sum_y += hit.y * hit.qdc;
76 weighted_sum_z += hit.z * hit.qdc;
77 total_qdc_positive += hit.qdc;
78 sum_qdc2_positive += hit.qdc*hit.qdc;
79 }
80 weighted_sum_x /= total_qdc_positive;
81 weighted_sum_y /= total_qdc_positive;
82 weighted_sum_z /= total_qdc_positive;
83 centroid_.SetXYZ(weighted_sum_x, weighted_sum_y, weighted_sum_z);
84 auto qdc_error_scaler = sqrt(sum_qdc2_positive)/total_qdc_positive;
85 centroid_error_.SetXYZ(configuration_.us_centroid_error_x*qdc_error_scaler,
86 configuration_.us_centroid_error_y*qdc_error_scaler,
87 configuration_.us_centroid_error_z*qdc_error_scaler);
88}
89
91{
92 sl_pair<double> totQdc{0.0, 0.0};
93 for (const auto &hit : hits_)
94 {
95 if (hit.is_large)
96 totQdc.large += hit.qdc;
97 else
98 totQdc.small += hit.qdc;
99 }
100 return totQdc;
101}
102
104{
105 sl_pair<double> tot_energy{0.0, 0.0};
106 sl_pair<double> tot_qdc = GetTotQdc();
107
108 tot_energy.large = tot_qdc.large *configuration_.us_qdc_to_gev;
109 tot_energy.small = tot_qdc.small *configuration_.us_qdc_to_gev;
110
111 return tot_energy;
112}
113
114
116{
117 rl_pair<double> side_qdc{0.0, 0.0};
118 for (const auto &hit : hits_)
119 {
120 if (hit.is_large)
121 {
122 if (hit.is_right)
123 side_qdc.right += hit.qdc;
124 else
125 side_qdc.left += hit.qdc;
126 }
127 }
128 return side_qdc;
129}
130
132{
133 rl_pair<double> bar_qdc{0.0, 0.0};
134 for (const auto &hit : hits_)
135 {
136 if (hit.bar != bar_to_compute)
137 continue;
138 else
139 {
140 if (hit.is_large)
141 {
142 if (hit.is_right)
143 bar_qdc.right += hit.qdc;
144 else
145 bar_qdc.left += hit.qdc;
146 }
147 }
148 }
149 return bar_qdc;
150}
151
153{
154 sl_pair<int> bar_hit{0, 0};
155 for (const auto &hit : hits_)
156 {
157 if (hit.bar != bar_to_compute)
158 continue;
159 else
160 {
161 if (hit.is_large)
162
163 bar_hit.large++;
164 else
165 bar_hit.small++;
166
167 }
168 }
169 return bar_hit;
170}
171
172void snd::analysis_tools::USPlane::TimeFilter(double min_timestamp, double max_timestamp)
173{
174 hits_.erase(std::remove_if(hits_.begin(), hits_.end(),
175 [&](auto &hit)
176 { return hit.timestamp < min_timestamp || hit.timestamp > max_timestamp; }),
177 hits_.end());
178}
179
181{
182 sl_pair<int> counts{0, 0};
183 counts.large = std::count_if(hits_.begin(), hits_.end(), [](auto &hit)
184 { return hit.is_large; });
185 counts.small = static_cast<int>(hits_.size()) - counts.large;
186
187 return counts;
188}
189
191{
192 int count{0};
193 for (int bar{0}; bar < configuration_.us_bar_per_station; ++bar) {
194 if (GetBarNHits(bar).large > configuration_.us_min_hit_on_bar) count++;
195 }
196 return count;
197}
198
200{
201 LOGF(INFO, "USHit ch_idx :%d\tposition: (%f,%f,%f)\ttime: %f\tqdc: %f\tbar: %d\tis_right: %d\tis_large: %d", channel_index, x, y, z, timestamp, qdc, bar, is_right, is_large);
202}
void GetPosition(Int_t id, TVector3 &vLeft, TVector3 &vRight)
Definition MuFilter.cxx:639
const rl_pair< double > GetBarQdc(int bar_to_compute) const
const sl_pair< int > GetBarNHits(int bar_to_compute) const
const rl_pair< double > GetSideQdc() const
const sl_pair< int > GetNHits() const
USPlane(std::vector< MuFilterHit * > snd_hits, const Configuration &configuration, MuFilter *muon_filter_geometry, int station, bool use_small_sipms=false)
const int GetNHitBars() const
std::vector< USHit > hits_
Definition sndUSPlane.h:72
const sl_pair< double > GetTotQdc() const
const sl_pair< double > GetTotEnergy() const
void TimeFilter(double min_timestamp, double max_timestamp)