diff --git a/inc/TRestTrack3DAnalysisProcess.h b/inc/TRestTrack3DAnalysisProcess.h new file mode 100644 index 0000000..237e242 --- /dev/null +++ b/inc/TRestTrack3DAnalysisProcess.h @@ -0,0 +1,71 @@ +/************************************************************************* + * This file is part of the REST software framework. * + * * + * Copyright (C) 2016 GIFNA/TREX (University of Zaragoza) * + * For more information see http://gifna.unizar.es/trex * + * * + * REST is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * REST is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have a copy of the GNU General Public License along with * + * REST in $REST_PATH/LICENSE. * + * If not, see http://www.gnu.org/licenses/. * + * For the list of contributors see $REST_PATH/CREDITS. * + *************************************************************************/ + +#ifndef RestCore_TRestTrack3DAnalysisProcess +#define RestCore_TRestTrack3DAnalysisProcess + +#include + +#include "TRestEventProcess.h" + +//! An analysis REST process to extract valuable information from Track type of data. +class TRestTrack3DAnalysisProcess : public TRestEventProcess { + private: + TRestTrackEvent* fTrackEvent; //! + + void InitFromConfigFile() override; + + void Initialize() override; + + void LoadDefaultConfig(); + + protected: + public: + RESTValue GetInputEvent() const override { return fTrackEvent; } + RESTValue GetOutputEvent() const override { return fTrackEvent; } + + void InitProcess() override; + TRestEvent* ProcessEvent(TRestEvent* inputEvent) override; + void EndProcess() override; + + void LoadConfig(const std::string& configFilename, const std::string& name = ""); + + void PrintMetadata() override { + BeginPrintProcess(); + + ///////// Metadata //////// + + EndPrintProcess(); + } + + const char* GetProcessName() const override { return "trackAnalysis"; } + + // Constructor + TRestTrack3DAnalysisProcess(); + TRestTrack3DAnalysisProcess(const char* configFilename); + // Destructor + ~TRestTrack3DAnalysisProcess(); + + ClassDefOverride(TRestTrack3DAnalysisProcess, 1); // Template for a REST "event process" class inherited + // from TRestEventProcess +}; +#endif diff --git a/src/TRestTrack2DAnalysisProcess.cxx b/src/TRestTrack2DAnalysisProcess.cxx index b791139..a194731 100644 --- a/src/TRestTrack2DAnalysisProcess.cxx +++ b/src/TRestTrack2DAnalysisProcess.cxx @@ -33,18 +33,21 @@ /// "TotalEnergy", fTrackEvent->GetEnergy()); /// "XZ_TotalEnergyX", Energy in all XZ tracks /// "YZ_TotalEnergyY", Energy in all YZ tracks -/// "XZ_YZ_MaxTrackEnergy", energiesX[0].second + energiesY[0].second (first traks in XZ and YZ are added) +/// "XZ_YZ_MaxTrackEnergy", energiesX[0].second + energiesY[0].second (first tracks in XZ and YZ are added) /// "XZ_YZ_MaxTrackEnergyPercentage", Percentage of first track (XZ YZ added) energy from total energy /// "XZ_YZ_MaxTrackEnergyBalanceXY", Energy balance between X and Y in first track -/// "XZ_YZ_SecondMaxTrackEnergy", energiesX[0].second + energiesY[0].second (first traks in XZ and YZ are -/// added) "XZ_YZ_SecondMaxTrackEnergyPercentage", Percentage of first track (XZ YZ added) energy from total -/// energy "XZ_YZ_SecondMaxTrackEnergyBalanceXY", Energy balance between X and Y in first track +/// "XZ_YZ_SecondMaxTrackEnergy", energiesX[1].second + energiesY[1].second (second tracks in XZ and YZ are +/// added) +/// "XZ_YZ_SecondMaxTrackEnergyPercentage", Percentage of second track (XZ YZ added) energy from total +/// energy +/// "XZ_YZ_SecondMaxTrackEnergyBalanceXY", Energy balance between X and Y in first track /// /// "XZ_FirstSecondTracksDistanceXZ", Distance in XZ plane of mean positions of first two XZ tracks /// "YZ_FirstSecondTracksDistanceYZ", Distance in YZ plane of mean positions of first two YZ tracks /// "XZ_YZ_FirstSecondTracksDistanceSum", Root of squared sum of previous two /// /// Map observables, there are the same observables for first and second tracks. +/// MaxTrack_... and SecondMaxTrack_... /// Map observables have values for each track of each observable. /// If XZ observable in a YZ track -> = 0 and viceversa. /// @@ -76,6 +79,7 @@ /// SetObservableValue("Map_XZ_YZ_GaussSigmaZBalance", XZ_YZ_GaussSigmaZBalance); /// /// +/// ///______________________________________________________________________________ /// /// RESTsoft - Software for Rare Event Searches with TPCs @@ -312,16 +316,21 @@ TRestEvent* TRestTrack2DAnalysisProcess::ProcessEvent(TRestEvent* inputEvent) { } /// Distance between first two tracks - Double_t dXz = 0, dxZ = 0, dYz = 0, dyZ = 0; + if (fTrackEvent->GetNumberOfTracks() > 1) { + Double_t dXz = 0, dxZ = 0, dYz = 0, dyZ = 0; - dXz = abs(XZ_MeanX[energiesX[0].first] - XZ_MeanX[energiesX[1].first]); - dxZ = abs(XZ_MeanZ[energiesX[0].first] - XZ_MeanZ[energiesX[1].first]); + dXz = abs(XZ_MeanX[energiesX[0].first] - XZ_MeanX[energiesX[1].first]); + dxZ = abs(XZ_MeanZ[energiesX[0].first] - XZ_MeanZ[energiesX[1].first]); - dYz = abs(YZ_MeanY[energiesY[0].first] - YZ_MeanY[energiesY[1].first]); - dyZ = abs(YZ_MeanZ[energiesY[0].first] - YZ_MeanZ[energiesY[1].first]); + dYz = abs(YZ_MeanY[energiesY[0].first] - YZ_MeanY[energiesY[1].first]); + dyZ = abs(YZ_MeanZ[energiesY[0].first] - YZ_MeanZ[energiesY[1].first]); - XZ_FirstSecondTracksDistanceXZ = TMath::Sqrt(dXz * dXz + dxZ * dxZ); - YZ_FirstSecondTracksDistanceYZ = TMath::Sqrt(dYz * dYz + dyZ * dyZ); + XZ_FirstSecondTracksDistanceXZ = TMath::Sqrt(dXz * dXz + dxZ * dxZ); + YZ_FirstSecondTracksDistanceYZ = TMath::Sqrt(dYz * dYz + dyZ * dyZ); + } else { + XZ_FirstSecondTracksDistanceXZ = 0; + YZ_FirstSecondTracksDistanceYZ = 0; + } /// Energy observables XZ_TotalEnergyX = 0; @@ -376,6 +385,7 @@ TRestEvent* TRestTrack2DAnalysisProcess::ProcessEvent(TRestEvent* inputEvent) { SetObservableValue("YZ_TotalEnergyY", YZ_TotalEnergyY); // --- Map observables --- // + SetObservableValue("Map_XZ_NHitsX", XZ_NHitsX); SetObservableValue("Map_XZ_EnergyX", XZ_EnergyX); SetObservableValue("Map_XZ_SigmaX", XZ_SigmaX); SetObservableValue("Map_XZ_SigmaZ", XZ_SigmaZ); @@ -387,6 +397,7 @@ TRestEvent* TRestTrack2DAnalysisProcess::ProcessEvent(TRestEvent* inputEvent) { SetObservableValue("Map_XZ_MeanZ", XZ_MeanZ); SetObservableValue("Map_XZ_SkewZ", XZ_SkewZ); + SetObservableValue("Map_YZ_NHitsY", YZ_NHitsY); SetObservableValue("Map_YZ_EnergyY", YZ_EnergyY); SetObservableValue("Map_YZ_SigmaY", YZ_SigmaY); SetObservableValue("Map_YZ_SigmaZ", YZ_SigmaZ); @@ -404,6 +415,7 @@ TRestEvent* TRestTrack2DAnalysisProcess::ProcessEvent(TRestEvent* inputEvent) { SetObservableValue("Map_XZ_YZ_GaussSigmaZBalance", XZ_YZ_GaussSigmaZBalance); // --- Max track observables --- // + SetObservableValue("MaxTrack_XZ_NHitsX", XZ_NHitsX[energiesX[0].first]); SetObservableValue("MaxTrack_XZ_EnergyX", XZ_EnergyX[energiesX[0].first]); SetObservableValue("MaxTrack_XZ_SigmaX", XZ_SigmaX[energiesX[0].first]); SetObservableValue("MaxTrack_XZ_SigmaZ", XZ_SigmaZ[energiesX[0].first]); @@ -415,6 +427,7 @@ TRestEvent* TRestTrack2DAnalysisProcess::ProcessEvent(TRestEvent* inputEvent) { SetObservableValue("MaxTrack_XZ_MeanZ", XZ_MeanZ[energiesX[0].first]); SetObservableValue("MaxTrack_XZ_SkewZ", XZ_SkewZ[energiesX[0].first]); + SetObservableValue("MaxTrack_YZ_NHitsY", YZ_NHitsY[energiesY[0].first]); SetObservableValue("MaxTrack_YZ_EnergyY", YZ_EnergyY[energiesY[0].first]); SetObservableValue("MaxTrack_YZ_SigmaY", YZ_SigmaY[energiesY[0].first]); SetObservableValue("MaxTrack_YZ_SigmaZ", YZ_SigmaZ[energiesY[0].first]); @@ -438,6 +451,7 @@ TRestEvent* TRestTrack2DAnalysisProcess::ProcessEvent(TRestEvent* inputEvent) { (energiesX[0].second + energiesY[0].second)); // --- Second max track observables --- // + SetObservableValue("SecondMaxTrack_XZ_NHitsX", XZ_NHitsX[energiesX[1].first]); SetObservableValue("SecondMaxTrack_XZ_EnergyX", XZ_EnergyX[energiesX[1].first]); SetObservableValue("SecondMaxTrack_XZ_SigmaX", XZ_SigmaX[energiesX[1].first]); SetObservableValue("SecondMaxTrack_XZ_SigmaZ", XZ_SigmaZ[energiesX[1].first]); @@ -449,6 +463,7 @@ TRestEvent* TRestTrack2DAnalysisProcess::ProcessEvent(TRestEvent* inputEvent) { SetObservableValue("SecondMaxTrack_XZ_MeanZ", XZ_MeanZ[energiesX[1].first]); SetObservableValue("SecondMaxTrack_XZ_SkewZ", XZ_SkewZ[energiesX[1].first]); + SetObservableValue("SecondMaxTrack_YZ_NHitsY", YZ_NHitsY[energiesY[1].first]); SetObservableValue("SecondMaxTrack_YZ_EnergyY", YZ_EnergyY[energiesY[1].first]); SetObservableValue("SecondMaxTrack_YZ_SigmaY", YZ_SigmaY[energiesY[1].first]); SetObservableValue("SecondMaxTrack_YZ_SigmaZ", YZ_SigmaZ[energiesY[1].first]); @@ -467,12 +482,18 @@ TRestEvent* TRestTrack2DAnalysisProcess::ProcessEvent(TRestEvent* inputEvent) { SetObservableValue("SecondMaxTrack_XZ_YZ_GaussSigmaZBalance", XZ_YZ_GaussSigmaZBalance[energiesY[1].first]); - SetObservableValue("SecondMaxTrack_XZ_YZ_Energy", energiesX[1].second + energiesY[1].second); - SetObservableValue("SecondMaxTrack_XZ_YZ_EnergyPercentage", - (energiesX[1].second + energiesY[1].second) / fTrackEvent->GetEnergy()); - SetObservableValue( - "SecondMaxTrack_XZ_YZ_EnergyBalanceXY", - (energiesX[1].second - energiesY[1].second) / (energiesX[1].second + energiesY[1].second)); + if (fTrackEvent->GetNumberOfTracks() > 1) { + SetObservableValue("SecondMaxTrack_XZ_YZ_Energy", energiesX[1].second + energiesY[1].second); + SetObservableValue("SecondMaxTrack_XZ_YZ_EnergyPercentage", + (energiesX[1].second + energiesY[1].second) / fTrackEvent->GetEnergy()); + SetObservableValue( + "SecondMaxTrack_XZ_YZ_EnergyBalanceXY", + (energiesX[1].second - energiesY[1].second) / (energiesX[1].second + energiesY[1].second)); + } else { + SetObservableValue("SecondMaxTrack_XZ_YZ_Energy", 0); + SetObservableValue("SecondMaxTrack_XZ_YZ_EnergyPercentage", 0); + SetObservableValue("SecondMaxTrack_XZ_YZ_EnergyBalanceXY", 0); + } // --- Distance obsevables between first two tracks --- // SetObservableValue("XZ_FirstSecondTracksDistanceXZ", XZ_FirstSecondTracksDistanceXZ); diff --git a/src/TRestTrack3DAnalysisProcess.cxx b/src/TRestTrack3DAnalysisProcess.cxx new file mode 100644 index 0000000..6b2153d --- /dev/null +++ b/src/TRestTrack3DAnalysisProcess.cxx @@ -0,0 +1,303 @@ +/************************************************************************* + * This file is part of the REST software framework. * + * * + * Copyright (C) 2016 GIFNA/TREX (University of Zaragoza) * + * For more information see http://gifna.unizar.es/trex * + * * + * REST is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * REST is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have a copy of the GNU General Public License along with * + * REST in $REST_PATH/LICENSE. * + * If not, see http://www.gnu.org/licenses/. * + * For the list of contributors see $REST_PATH/CREDITS. * + *************************************************************************/ + +///////////////////////////////////////////////////////////////////////////// +/// +/// Analysis process for 3D tracks, XYZ. +/// For other types of tracks all observables are 0. +/// +/// ### Observables +/// "NTracks", fTrackEvent->GetNumberOfTracks()); +/// "TotalEnergy", fTrackEvent->GetEnergy()); +/// "XYZ_MaxTrackEnergyPercentage", Percentage of first track energy from total energy +/// "XYZ_SecondMaxTrackEnergyPercentage", Percentage of second track energy from total energy +/// "XYZ_FirstSecondTracksDistance", Distance in XYZ of mean positions of first two XYZ tracks +/// +/// Map observables, there are the same observables for first and second tracks. +/// MaxTrack_... and SecondMaxTrack_... +/// Map observables have values for each track of each observable. +/// Only for XYZ tracks, if not = 0 +/// +/// SetObservableValue("Map_XYZ_NHits", XYZ_NHits); +/// SetObservableValue("Map_XYZ_Energy", XYZ_Energy); +/// SetObservableValue("Map_XYZ_SigmaX", XYZ_SigmaX); +/// SetObservableValue("Map_XYZ_SigmaY", XYZ_SigmaY); +/// SetObservableValue("Map_XYZ_SigmaZ", XYZ_SigmaZ); +/// SetObservableValue("Map_XYZ_GaussSigmaX", XYZ_GaussSigmaX); +/// SetObservableValue("Map_XYZ_GaussSigmaY", XYZ_GaussSigmaY); +/// SetObservableValue("Map_XYZ_GaussSigmaZ", XYZ_GaussSigmaZ); +/// SetObservableValue("Map_XYZ_Length", XYZ_Length); +/// SetObservableValue("Map_XYZ_Volume", XYZ_Volume); +/// SetObservableValue("Map_XYZ_MeanX", XYZ_MeanX); +/// SetObservableValue("Map_XYZ_MeanY", XYZ_MeanY); +/// SetObservableValue("Map_XYZ_MeanZ", XYZ_MeanZ); +/// SetObservableValue("Map_XYZ_SkewXY", XYZ_SkewXY); +/// SetObservableValue("Map_XYZ_SkewZ", XYZ_SkewZ); +/// +/// +/// +///______________________________________________________________________________ +/// +/// RESTsoft - Software for Rare Event Searches with TPCs +/// +/// History of developments: +/// +/// 2024-March: Analysis for 3D tracks (XYZ) +/// David Diez Ibanez +/// +/// +/// \class TRestTrack3DAnalysisProcess +/// \author David Diez Ibanez +/// +///______________________________________________________________________________ +/// +///////////////////////////////////////////////////////////////////////////// + +#include "TRestTrack3DAnalysisProcess.h" +using namespace std; + +// Comparator function for sorting in descending order +bool sortByValueDescending3D(const std::pair& a, const std::pair& b) { + return a.second > b.second; // Change to < for ascending order +} + +ClassImp(TRestTrack3DAnalysisProcess); + +TRestTrack3DAnalysisProcess::TRestTrack3DAnalysisProcess() { Initialize(); } + +TRestTrack3DAnalysisProcess::TRestTrack3DAnalysisProcess(const char* configFilename) { + Initialize(); + if (LoadConfigFromFile(configFilename)) LoadDefaultConfig(); +} + +TRestTrack3DAnalysisProcess::~TRestTrack3DAnalysisProcess() { delete fTrackEvent; } + +void TRestTrack3DAnalysisProcess::LoadDefaultConfig() { SetTitle("Default config"); } + +void TRestTrack3DAnalysisProcess::Initialize() { + SetSectionName(this->ClassName()); + SetLibraryVersion(LIBRARY_VERSION); + + fTrackEvent = new TRestTrackEvent(); +} + +void TRestTrack3DAnalysisProcess::LoadConfig(const string& configFilename, const string& name) { + if (LoadConfigFromFile(configFilename, name)) LoadDefaultConfig(); +} + +void TRestTrack3DAnalysisProcess::InitProcess() {} + +TRestEvent* TRestTrack3DAnalysisProcess::ProcessEvent(TRestEvent* inputEvent) { + fTrackEvent = (TRestTrackEvent*)inputEvent; + + /// -------------------------------------------------- /// + /// ------------------ OBSERVABLES ------------------- /// + /// -------------------------------------------------- /// + + //// ------ MAP OBSERVABLES ------ //// + /// Energy per track + map XYZ_Energy; + + /// Number of hits in the track + map XYZ_NHits; + + /// Standard deviation observables + map XYZ_SigmaX; + map XYZ_SigmaY; + map XYZ_SigmaZ; + + /// Skew observables + map XYZ_SkewXY; + map XYZ_SkewZ; + + /// Gauss sigma observables + map XYZ_GaussSigmaX; + map XYZ_GaussSigmaY; + map XYZ_GaussSigmaZ; + + /// Espacial measuremets + map XYZ_Length; + + map XYZ_Volume; + + map XYZ_MeanX; + map XYZ_MeanY; + map XYZ_MeanZ; + + /// Distance between biggest two tracks in energy + Double_t XYZ_FirstSecondTracksDistance; + + /// ---------------------------------------------------------- /// + /// ------------------ COMPUTE OBSERVABLES ------------------- /// + /// ---------------------------------------------------------- /// + + /// Map oservables + for (int tck = 0; tck < fTrackEvent->GetNumberOfTracks(); tck++) { + if (!fTrackEvent->isTopLevel(tck)) continue; + + TRestTrack* t = fTrackEvent->GetTrack(tck); + + if (t->isXYZ()) { + XYZ_NHits[t->GetTrackID()] = t->GetNumberOfHits(); + XYZ_Energy[t->GetTrackID()] = t->GetTrackEnergy(); + XYZ_SigmaX[t->GetTrackID()] = t->GetHits()->GetSigmaX(); + XYZ_SigmaY[t->GetTrackID()] = t->GetHits()->GetSigmaY(); + XYZ_SigmaZ[t->GetTrackID()] = t->GetHits()->GetSigmaZ2(); + XYZ_GaussSigmaX[t->GetTrackID()] = t->GetHits()->GetGaussSigmaX(); + XYZ_GaussSigmaY[t->GetTrackID()] = t->GetHits()->GetGaussSigmaY(); + XYZ_GaussSigmaZ[t->GetTrackID()] = t->GetHits()->GetGaussSigmaZ(); + XYZ_Length[t->GetTrackID()] = t->GetLength(); + XYZ_Volume[t->GetTrackID()] = t->GetVolume(); + XYZ_MeanX[t->GetTrackID()] = t->GetMeanPosition().X(); + XYZ_MeanY[t->GetTrackID()] = t->GetMeanPosition().Y(); + XYZ_MeanZ[t->GetTrackID()] = t->GetMeanPosition().Z(); + XYZ_SkewXY[t->GetTrackID()] = t->GetHits()->GetSkewXY(); + XYZ_SkewZ[t->GetTrackID()] = t->GetHits()->GetSkewZ(); + } else { + XYZ_NHits[t->GetTrackID()] = 0; + XYZ_Energy[t->GetTrackID()] = 0; + XYZ_SigmaX[t->GetTrackID()] = 0; + XYZ_SigmaY[t->GetTrackID()] = 0; + XYZ_SigmaZ[t->GetTrackID()] = 0; + XYZ_GaussSigmaX[t->GetTrackID()] = 0; + XYZ_GaussSigmaY[t->GetTrackID()] = 0; + XYZ_GaussSigmaZ[t->GetTrackID()] = 0; + XYZ_Length[t->GetTrackID()] = 0; + XYZ_Volume[t->GetTrackID()] = 0; + XYZ_MeanX[t->GetTrackID()] = 0; + XYZ_MeanY[t->GetTrackID()] = 0; + XYZ_MeanZ[t->GetTrackID()] = 0; + XYZ_SkewXY[t->GetTrackID()] = 0; + XYZ_SkewZ[t->GetTrackID()] = 0; + } + } + + /// Sort tracks by energy /// + vector> energies; + + /// From map to vector + map::iterator it; + for (it = XYZ_Energy.begin(); it != XYZ_Energy.end(); it++) { + energies.push_back(make_pair(it->first, it->second)); + } + + /// Sort the vector by decreasing order of its pair's second value + sort(energies.begin(), energies.end(), sortByValueDescending3D); + + /// Distance between first two tracks + if (fTrackEvent->GetNumberOfTracks() > 1) { + Double_t dX = 0, dY = 0, dZ = 0; + + dX = abs(XYZ_MeanX[energies[0].first] - XYZ_MeanX[energies[1].first]); + dY = abs(XYZ_MeanY[energies[0].first] - XYZ_MeanY[energies[1].first]); + dZ = abs(XYZ_MeanZ[energies[0].first] - XYZ_MeanZ[energies[1].first]); + + XYZ_FirstSecondTracksDistance = TMath::Sqrt(dX * dX + dY * dY + dZ * dZ); + } else { + XYZ_FirstSecondTracksDistance = 0; + } + + /// ------------------------------------------------------------- /// + /// ------------------ SET OBSERVABLES VALUES ------------------- /// + /// ------------------------------------------------------------- /// + + // --- Number of tracks and energy --- // + SetObservableValue("NTracks", fTrackEvent->GetNumberOfTracks()); + SetObservableValue("TotalEnergy", fTrackEvent->GetEnergy()); + + // --- Map observables --- // + SetObservableValue("Map_XYZ_NHits", XYZ_NHits); + SetObservableValue("Map_XYZ_Energy", XYZ_Energy); + SetObservableValue("Map_XYZ_SigmaX", XYZ_SigmaX); + SetObservableValue("Map_XYZ_SigmaY", XYZ_SigmaY); + SetObservableValue("Map_XYZ_SigmaZ", XYZ_SigmaZ); + SetObservableValue("Map_XYZ_GaussSigmaX", XYZ_GaussSigmaX); + SetObservableValue("Map_XYZ_GaussSigmaY", XYZ_GaussSigmaY); + SetObservableValue("Map_XYZ_GaussSigmaZ", XYZ_GaussSigmaZ); + SetObservableValue("Map_XYZ_Length", XYZ_Length); + SetObservableValue("Map_XYZ_Volume", XYZ_Volume); + SetObservableValue("Map_XYZ_MeanX", XYZ_MeanX); + SetObservableValue("Map_XYZ_MeanY", XYZ_MeanY); + SetObservableValue("Map_XYZ_MeanZ", XYZ_MeanZ); + SetObservableValue("Map_XYZ_SkewXY", XYZ_SkewXY); + SetObservableValue("Map_XYZ_SkewZ", XYZ_SkewZ); + + // --- Max track observables --- // + SetObservableValue("MaxTrack_XYZ_NHits", XYZ_NHits[energies[0].first]); + SetObservableValue("MaxTrack_XYZ_Energy", XYZ_Energy[energies[0].first]); + SetObservableValue("MaxTrack_XYZ_SigmaX", XYZ_SigmaX[energies[0].first]); + SetObservableValue("MaxTrack_XYZ_SigmaY", XYZ_SigmaY[energies[0].first]); + SetObservableValue("MaxTrack_XYZ_SigmaZ", XYZ_SigmaZ[energies[0].first]); + SetObservableValue("MaxTrack_XYZ_GaussSigmaX", XYZ_GaussSigmaX[energies[0].first]); + SetObservableValue("MaxTrack_XYZ_GaussSigmaY", XYZ_GaussSigmaY[energies[0].first]); + SetObservableValue("MaxTrack_XYZ_GaussSigmaZ", XYZ_GaussSigmaZ[energies[0].first]); + SetObservableValue("MaxTrack_XYZ_Length", XYZ_Length[energies[0].first]); + SetObservableValue("MaxTrack_XYZ_Volume", XYZ_Volume[energies[0].first]); + SetObservableValue("MaxTrack_XYZ_MeanX", XYZ_MeanX[energies[0].first]); + SetObservableValue("MaxTrack_XYZ_MeanY", XYZ_MeanY[energies[0].first]); + SetObservableValue("MaxTrack_XYZ_MeanZ", XYZ_MeanZ[energies[0].first]); + SetObservableValue("MaxTrack_XYZ_SkewZ", XYZ_SkewXY[energies[0].first]); + SetObservableValue("MaxTrack_XYZ_SkewZ", XYZ_SkewZ[energies[0].first]); + + SetObservableValue("MaxTrack_XYZ_MaxTrackEnergyPercentage", + (energies[0].second) / fTrackEvent->GetEnergy()); + + // --- Second max track observables --- // + SetObservableValue("SecondMaxTrack_XYZ_NHits", XYZ_NHits[energies[1].first]); + SetObservableValue("SecondMaxTrack_XYZ_Energy", XYZ_Energy[energies[1].first]); + SetObservableValue("SecondMaxTrack_XYZ_SigmaX", XYZ_SigmaX[energies[1].first]); + SetObservableValue("SecondMaxTrack_XYZ_SigmaY", XYZ_SigmaY[energies[1].first]); + SetObservableValue("SecondMaxTrack_XYZ_SigmaZ", XYZ_SigmaZ[energies[1].first]); + SetObservableValue("SecondMaxTrack_XYZ_GaussSigmaX", XYZ_GaussSigmaX[energies[1].first]); + SetObservableValue("SecondMaxTrack_XYZ_GaussSigmaY", XYZ_GaussSigmaY[energies[1].first]); + SetObservableValue("SecondMaxTrack_XYZ_GaussSigmaZ", XYZ_GaussSigmaZ[energies[1].first]); + SetObservableValue("SecondMaxTrack_XYZ_Length", XYZ_Length[energies[1].first]); + SetObservableValue("SecondMaxTrack_XYZ_Volume", XYZ_Volume[energies[1].first]); + SetObservableValue("SecondMaxTrack_XYZ_MeanX", XYZ_MeanX[energies[1].first]); + SetObservableValue("SecondMaxTrack_XYZ_MeanY", XYZ_MeanY[energies[1].first]); + SetObservableValue("SecondMaxTrack_XYZ_MeanZ", XYZ_MeanZ[energies[1].first]); + SetObservableValue("SecondMaxTrack_XYZ_SkewZ", XYZ_SkewXY[energies[1].first]); + SetObservableValue("SecondMaxTrack_XYZ_SkewZ", XYZ_SkewZ[energies[1].first]); + + if (fTrackEvent->GetNumberOfTracks() > 1) { + SetObservableValue("SecondMaxTrack_XYZ_MaxTrackEnergyPercentage", + (energies[1].second) / fTrackEvent->GetEnergy()); + } else { + SetObservableValue("SecondMaxTrack_XYZ_MaxTrackEnergyPercentage", 0); + } + + // --- Distance obsevables between first two tracks --- // + SetObservableValue("XYZ_FirstSecondTracksDistance", XYZ_FirstSecondTracksDistance); + + return fTrackEvent; +} + +void TRestTrack3DAnalysisProcess::EndProcess() { + // Function to be executed once at the end of the process + // (after all events have been processed) + + // Start by calling the EndProcess function of the abstract class. + // Comment this if you don't want it. + // TRestEventProcess::EndProcess(); +} + +void TRestTrack3DAnalysisProcess::InitFromConfigFile() {}