100#include "TRestTrack2DAnalysisProcess.h"
105bool sortByValueDescending(
const std::pair<int, Double_t>& a,
const std::pair<int, Double_t>& b) {
106 return a.second > b.second;
111TRestTrack2DAnalysisProcess::TRestTrack2DAnalysisProcess() {
Initialize(); }
113TRestTrack2DAnalysisProcess::TRestTrack2DAnalysisProcess(
const char* configFilename) {
120TRestTrack2DAnalysisProcess::~TRestTrack2DAnalysisProcess() {
delete fTrackEvent; }
122void TRestTrack2DAnalysisProcess::LoadDefaultConfig() { SetTitle(
"Default config"); }
131void TRestTrack2DAnalysisProcess::LoadConfig(
const string& configFilename,
const string& name) {
145 Double_t XZ_TotalEnergyX;
146 Double_t YZ_TotalEnergyY;
154 map<int, Double_t> XZ_EnergyX;
155 map<int, Double_t> YZ_EnergyY;
158 map<int, int> XZ_NHitsX;
159 map<int, int> YZ_NHitsY;
162 map<int, Double_t> XZ_SigmaX;
163 map<int, Double_t> XZ_SigmaZ;
164 map<int, Double_t> YZ_SigmaY;
165 map<int, Double_t> YZ_SigmaZ;
167 map<int, Double_t> XZ_YZ_SigmaXYBalance;
168 map<int, Double_t> XZ_YZ_SigmaZBalance;
170 map<int, Double_t> XZ_SkewZ;
171 map<int, Double_t> YZ_SkewZ;
174 map<int, Double_t> XZ_GaussSigmaX;
175 map<int, Double_t> XZ_GaussSigmaZ;
176 map<int, Double_t> YZ_GaussSigmaY;
177 map<int, Double_t> YZ_GaussSigmaZ;
179 map<int, Double_t> XZ_YZ_GaussSigmaXYBalance;
180 map<int, Double_t> XZ_YZ_GaussSigmaZBalance;
183 map<int, Double_t> XZ_LengthX;
184 map<int, Double_t> YZ_LengthY;
186 map<int, Double_t> XZ_VolumeX;
187 map<int, Double_t> YZ_VolumeY;
189 map<int, Double_t> XZ_MeanX;
190 map<int, Double_t> XZ_MeanZ;
191 map<int, Double_t> YZ_MeanY;
192 map<int, Double_t> YZ_MeanZ;
195 Double_t XZ_FirstSecondTracksDistanceXZ;
196 Double_t YZ_FirstSecondTracksDistanceYZ;
199 Double_t MaxTrack_XZ_YZ_SigmaZ;
200 Double_t MaxTrack_XZ_YZ_GaussSigmaZ;
201 Double_t MaxTrack_XZ_YZ_SkewXY;
202 Double_t MaxTrack_XZ_YZ_SkewZ;
208 NTracksX = fTrackEvent->GetNumberOfTracks(
"X");
209 NTracksY = fTrackEvent->GetNumberOfTracks(
"Y");
212 for (
int tck = 0; tck < fTrackEvent->GetNumberOfTracks(); tck++) {
213 if (!fTrackEvent->isTopLevel(tck))
continue;
218 XZ_NHitsX[t->GetTrackID()] = t->GetNumberOfHits();
219 XZ_EnergyX[t->GetTrackID()] = t->GetTrackEnergy();
220 XZ_SigmaX[t->GetTrackID()] = t->GetHits()->
GetSigmaX();
221 XZ_SigmaZ[t->GetTrackID()] = t->GetHits()->
GetSigmaZ2();
224 XZ_LengthX[t->GetTrackID()] = t->GetLength();
225 XZ_VolumeX[t->GetTrackID()] = t->GetVolume();
226 XZ_MeanX[t->GetTrackID()] = t->GetMeanPosition().X();
227 XZ_MeanZ[t->GetTrackID()] = t->GetMeanPosition().Z();
228 XZ_SkewZ[t->GetTrackID()] = t->GetHits()->
GetSkewZ();
230 YZ_NHitsY[t->GetTrackID()] = 0;
231 YZ_EnergyY[t->GetTrackID()] = 0;
232 YZ_SigmaY[t->GetTrackID()] = 0;
233 YZ_SigmaZ[t->GetTrackID()] = 0;
234 YZ_GaussSigmaY[t->GetTrackID()] = 0;
235 YZ_GaussSigmaZ[t->GetTrackID()] = 0;
236 YZ_LengthY[t->GetTrackID()] = 0;
237 YZ_VolumeY[t->GetTrackID()] = 0;
238 YZ_MeanY[t->GetTrackID()] = 0;
239 YZ_MeanZ[t->GetTrackID()] = 0;
240 YZ_SkewZ[t->GetTrackID()] = 0;
241 }
else if (t->isYZ()) {
242 XZ_NHitsX[t->GetTrackID()] = 0;
243 XZ_EnergyX[t->GetTrackID()] = 0;
244 XZ_SigmaX[t->GetTrackID()] = 0;
245 XZ_SigmaZ[t->GetTrackID()] = 0;
246 XZ_GaussSigmaX[t->GetTrackID()] = 0;
247 XZ_GaussSigmaZ[t->GetTrackID()] = 0;
248 XZ_LengthX[t->GetTrackID()] = 0;
249 XZ_VolumeX[t->GetTrackID()] = 0;
250 XZ_MeanX[t->GetTrackID()] = 0;
251 XZ_MeanZ[t->GetTrackID()] = 0;
252 XZ_SkewZ[t->GetTrackID()] = 0;
254 YZ_NHitsY[t->GetTrackID()] = t->GetNumberOfHits();
255 YZ_EnergyY[t->GetTrackID()] = t->GetTrackEnergy();
256 YZ_SigmaY[t->GetTrackID()] = t->GetHits()->
GetSigmaY();
257 YZ_SigmaZ[t->GetTrackID()] = t->GetHits()->
GetSigmaZ2();
260 YZ_LengthY[t->GetTrackID()] = t->GetLength();
261 YZ_VolumeY[t->GetTrackID()] = t->GetVolume();
262 YZ_MeanY[t->GetTrackID()] = t->GetMeanPosition().Y();
263 YZ_MeanZ[t->GetTrackID()] = t->GetMeanPosition().Z();
264 YZ_SkewZ[t->GetTrackID()] = t->GetHits()->
GetSkewZ();
266 XZ_EnergyX[t->GetTrackID()] = 0;
267 XZ_SigmaX[t->GetTrackID()] = 0;
268 XZ_SigmaZ[t->GetTrackID()] = 0;
269 XZ_GaussSigmaX[t->GetTrackID()] = 0;
270 XZ_GaussSigmaZ[t->GetTrackID()] = 0;
271 XZ_LengthX[t->GetTrackID()] = 0;
272 XZ_VolumeX[t->GetTrackID()] = 0;
273 XZ_MeanX[t->GetTrackID()] = 0;
274 XZ_MeanZ[t->GetTrackID()] = 0;
275 XZ_SkewZ[t->GetTrackID()] = 0;
277 YZ_EnergyY[t->GetTrackID()] = 0;
278 YZ_SigmaY[t->GetTrackID()] = 0;
279 YZ_SigmaZ[t->GetTrackID()] = 0;
280 YZ_GaussSigmaY[t->GetTrackID()] = 0;
281 YZ_GaussSigmaZ[t->GetTrackID()] = 0;
282 YZ_LengthY[t->GetTrackID()] = 0;
283 YZ_VolumeY[t->GetTrackID()] = 0;
284 YZ_MeanY[t->GetTrackID()] = 0;
285 YZ_MeanZ[t->GetTrackID()] = 0;
286 YZ_SkewZ[t->GetTrackID()] = 0;
291 vector<pair<int, Double_t>> energiesX;
292 vector<pair<int, Double_t>> energiesY;
295 map<int, Double_t>::iterator it;
296 for (it = XZ_EnergyX.begin(); it != XZ_EnergyX.end(); it++) {
297 energiesX.emplace_back(it->first, it->second);
299 for (it = YZ_EnergyY.begin(); it != YZ_EnergyY.end(); it++) {
300 energiesY.emplace_back(it->first, it->second);
304 sort(energiesX.begin(), energiesX.end(), sortByValueDescending);
305 sort(energiesY.begin(), energiesY.end(), sortByValueDescending);
308 for (
int i = 0; i < min(NTracksX, NTracksY); i++) {
309 XZ_YZ_SigmaXYBalance[i] = (XZ_SigmaX[energiesX[i].first] - YZ_SigmaY[energiesY[i].first]) /
310 (XZ_SigmaX[energiesX[i].first] + YZ_SigmaY[energiesY[i].first]);
311 XZ_YZ_SigmaZBalance[i] = (XZ_SigmaZ[energiesX[i].first] - YZ_SigmaZ[energiesY[i].first]) /
312 (XZ_SigmaZ[energiesX[i].first] + YZ_SigmaZ[energiesY[i].first]);
313 XZ_YZ_GaussSigmaXYBalance[i] =
314 (XZ_GaussSigmaX[energiesX[i].first] - YZ_GaussSigmaY[energiesY[i].first]) /
315 (XZ_GaussSigmaX[energiesX[i].first] + YZ_GaussSigmaY[energiesY[i].first]);
316 XZ_YZ_GaussSigmaZBalance[i] =
317 (XZ_GaussSigmaZ[energiesX[i].first] - YZ_GaussSigmaZ[energiesY[i].first]) /
318 (XZ_GaussSigmaZ[energiesX[i].first] + YZ_GaussSigmaZ[energiesY[i].first]);
322 if (fTrackEvent->GetNumberOfTracks() > 1) {
323 Double_t dXz = 0, dxZ = 0, dYz = 0, dyZ = 0;
325 dXz = abs(XZ_MeanX[energiesX[0].first] - XZ_MeanX[energiesX[1].first]);
326 dxZ = abs(XZ_MeanZ[energiesX[0].first] - XZ_MeanZ[energiesX[1].first]);
328 dYz = abs(YZ_MeanY[energiesY[0].first] - YZ_MeanY[energiesY[1].first]);
329 dyZ = abs(YZ_MeanZ[energiesY[0].first] - YZ_MeanZ[energiesY[1].first]);
331 XZ_FirstSecondTracksDistanceXZ = TMath::Sqrt(dXz * dXz + dxZ * dxZ);
332 YZ_FirstSecondTracksDistanceYZ = TMath::Sqrt(dYz * dYz + dyZ * dyZ);
334 XZ_FirstSecondTracksDistanceXZ = 0;
335 YZ_FirstSecondTracksDistanceYZ = 0;
342 for (
auto pair : energiesX) {
343 XZ_TotalEnergyX += pair.second;
345 for (
auto pair : energiesY) {
346 YZ_TotalEnergyY += pair.second;
353 if (fTrackEvent->GetMaxEnergyTrack(
"X")) hitsXZ = fTrackEvent->GetMaxEnergyTrack(
"X")->GetHits();
354 if (fTrackEvent->GetMaxEnergyTrack(
"Y")) hitsYZ = fTrackEvent->GetMaxEnergyTrack(
"Y")->GetHits();
356 auto hitsBoth = {hitsXZ, hitsYZ};
358 for (
auto arg : hitsBoth) {
359 if (arg ==
nullptr) {
362 for (
int n = 0; n < int(arg->GetNumberOfHits()); n++) {
364 Double_t eDep = arg->GetEnergy(n);
365 Double_t x = arg->GetX(n);
366 Double_t y = arg->GetY(n);
367 Double_t z = arg->GetZ(n);
368 auto time = arg->GetTime(n);
369 auto type = arg->GetType(n);
371 hits.
AddHit({x, y, z}, eDep, time, type);
377 MaxTrack_XZ_YZ_SkewXY = hits.
GetSkewXY();
378 MaxTrack_XZ_YZ_SkewZ = hits.
GetSkewZ();
425 bool hasNonZeroEnergyX = !energiesX.empty() && energiesX[0].second != 0;
426 bool hasNonZeroEnergyY = !energiesY.empty() && energiesY[0].second != 0;
430 if (hasNonZeroEnergyX) {
431 int energiesX0FirstKey =
461 if (hasNonZeroEnergyY) {
462 int energiesY0FirstKey = energiesY[0].first;
491 if (!energiesX.empty() && !energiesY.empty()) {
492 Double_t energiesX0SecondKey = energiesX[0].second;
493 Double_t energiesY0SecondKey = energiesY[0].second;
495 SetObservableValue(
"MaxTrack_XZ_YZ_Energy", energiesX0SecondKey + energiesY0SecondKey);
497 (energiesX0SecondKey + energiesY0SecondKey) / fTrackEvent->GetEnergy());
498 SetObservableValue(
"MaxTrack_XZ_YZ_EnergyBalanceXY", (energiesX0SecondKey - energiesY0SecondKey) /
499 (energiesX0SecondKey + energiesY0SecondKey));
509 SetObservableValue(
"MaxTrack_XZ_YZ_GaussSigmaXYBalance", XZ_YZ_GaussSigmaXYBalance[0]);
515 bool hasNonZeroSecondMaxEnergyX = energiesX.size() > 1 && energiesX[1].second != 0;
516 bool hasNonZeroSecondMaxEnergyY = energiesY.size() > 1 && energiesY[1].second != 0;
521 if (hasNonZeroSecondMaxEnergyX) {
522 int energiesX1FirstKey =
529 SetObservableValue(
"SecondMaxTrack_XZ_GaussSigmaX", XZ_GaussSigmaX[energiesX1FirstKey]);
530 SetObservableValue(
"SecondMaxTrack_XZ_GaussSigmaZ", XZ_GaussSigmaZ[energiesX1FirstKey]);
552 if (hasNonZeroSecondMaxEnergyY) {
553 int energiesY1FirstKey = energiesY[1].first;
559 SetObservableValue(
"SecondMaxTrack_YZ_GaussSigmaY", YZ_GaussSigmaY[energiesY1FirstKey]);
560 SetObservableValue(
"SecondMaxTrack_YZ_GaussSigmaZ", YZ_GaussSigmaZ[energiesY1FirstKey]);
582 SetObservableValue(
"SecondMaxTrack_XZ_YZ_GaussSigmaXYBalance", XZ_YZ_GaussSigmaXYBalance[1]);
583 SetObservableValue(
"SecondMaxTrack_XZ_YZ_GaussSigmaZBalance", XZ_YZ_GaussSigmaZBalance[1]);
585 SetObservableValue(
"SecondMaxTrack_XZ_YZ_OK", hasNonZeroSecondMaxEnergyX && hasNonZeroSecondMaxEnergyY);
587 if (energiesY.size() > 1 && energiesX.size() > 1) {
588 Double_t energiesX1SecondKey = energiesX[1].second;
589 Double_t energiesY1SecondKey = energiesY[1].second;
591 if (fTrackEvent->GetNumberOfTracks() > 2) {
592 SetObservableValue(
"SecondMaxTrack_XZ_YZ_Energy", energiesX1SecondKey + energiesY1SecondKey);
594 (energiesX1SecondKey + energiesY1SecondKey) / fTrackEvent->GetEnergy());
596 "SecondMaxTrack_XZ_YZ_EnergyBalanceXY",
597 (energiesX1SecondKey - energiesY1SecondKey) / (energiesX1SecondKey + energiesY1SecondKey));
613 TMath::Sqrt(XZ_FirstSecondTracksDistanceXZ * XZ_FirstSecondTracksDistanceXZ +
614 YZ_FirstSecondTracksDistanceYZ * YZ_FirstSecondTracksDistanceYZ));
void SetObservableValue(const std::string &name, const T &value)
Set observable value for AnalysisTree.
A base class for any REST event.
It saves a 3-coordinate position and an energy for each punctual deposition.
Double_t GetSkewXY() const
It returns the 2-dimensional skewness on the XY-plane which is a measure of the hits distribution asy...
Double_t GetGaussSigmaX(Double_t error=150.0, Int_t nHitsMin=100000)
It computes the gaussian sigma in the X-coordinate. It adds a hit to the right and a hit to the left,...
Double_t GetSigmaX() const
It calculates the hits standard deviation in the X-coordinate.
Double_t GetGaussSigmaZ(Double_t error=150.0, Int_t nHitsMin=100000)
It computes the gaussian sigma in the Z-coordinate. It adds a hit to the right and a hit to the left,...
void AddHit(const TVector3 &position, Double_t energy, Double_t time=0, REST_HitType type=XYZ)
Adds a new hit to the list of hits using a TVector3.
Double_t GetGaussSigmaY(Double_t error=150.0, Int_t nHitsMin=100000)
It computes the gaussian sigma in the Y-coordinate. It adds a hit to the right and a hit to the left,...
Double_t GetSigmaZ2() const
It returns the hits distribution variance on the Z-axis.
Double_t GetSkewZ() const
It returns the hits distribution skewness, or asymmetry on the Z-axis.
Double_t GetSigmaY() const
It calculates the hits standard deviation in the Y-coordinate.
An analysis REST process to extract valuable information from Track type of data.
TRestEvent * ProcessEvent(TRestEvent *inputEvent) override
Process one event.
void InitFromConfigFile() override
To make settings from rml file. This method must be implemented in the derived class.
void InitProcess() override
To be executed at the beginning of the run (outside event loop)
void EndProcess() override
To be executed at the end of the run (outside event loop)
void Initialize() override
Making default settings.