63 #include "TRestTrackLinearizationProcess.h"
65 #include "TRestTrackReductionProcess.h"
85 SetSectionName(this->ClassName());
86 SetLibraryVersion(LIBRARY_VERSION);
88 fTrackEvent =
nullptr;
103 for (
int t = 0; t < fTrackEvent->GetNumberOfTracks(); t++)
104 fOutTrackEvent->AddTrack(fTrackEvent->GetTrack(t));
106 for (
int t = 0; t < fTrackEvent->GetNumberOfTracks(); t++) {
107 if (fTrackEvent->GetLevel(t) > 1)
continue;
112 GetHitsProjection(hits, fMaxNodes, vHits);
113 if (vHits.GetNumberOfHits() == 0)
continue;
115 RESTDebug <<
"Adding track " << RESTendl;
118 newTrack.SetTrackID(fOutTrackEvent->GetNumberOfTracks() + 1);
119 newTrack.SetParentID(track->GetTrackID());
120 newTrack.SetVolumeHits(vHits);
122 RESTDebug <<
"Is XZ " << newTrack.isXZ() <<
" Is YZ " << newTrack.isYZ() << RESTendl;
124 fOutTrackEvent->AddTrack(&newTrack);
127 RESTDebug <<
"NTracks X " << fOutTrackEvent->GetNumberOfTracks(
"X") <<
" Y "
128 << fOutTrackEvent->GetNumberOfTracks(
"Y") <<
" " << fOutTrackEvent->GetNumberOfTracks(
"X")
131 fOutTrackEvent->SetLevels();
132 return fOutTrackEvent;
143 const int nHits = hits->GetNumberOfHits();
144 const REST_HitType hType = hits->GetType(0);
147 RESTDebug <<
"NHits " << nHits <<
" hits Type " << hType << RESTendl;
150 auto cl = GetBestNodes(hits->GetX(), hits->GetZ(), hits->GetEnergyVector(), nodes);
151 for (
const auto& [xy, z] : cl) {
152 vHits.AddHit(xy, hits->GetY(0), z, 0, 0, hType, 0, 0, 0);
154 }
else if (hType == YZ) {
155 auto cl = GetBestNodes(hits->GetY(), hits->GetZ(), hits->GetEnergyVector(), nodes);
156 for (
const auto& [xy, z] : cl) {
157 vHits.AddHit(hits->GetX(0), xy, z, 0, 0, hType, 0, 0, 0);
159 }
else if (hType == XY) {
160 auto cl = GetBestNodes(hits->GetX(), hits->GetY(), hits->GetEnergyVector(), nodes);
161 for (
const auto& [xy, z] : cl) {
162 vHits.AddHit(xy, z, hits->GetZ(0), 0, 0, hType, 0, 0, 0);
165 RESTWarning <<
"Track linearization not implemented for XYZ tracks" << RESTendl;
169 TRestVolumeHits::kMeansClustering(hits, vHits, 1);
172 for (
unsigned int i = 0; i < vHits.GetNumberOfHits(); i++)
173 RESTDebug << i <<
" " << vHits.GetX(i) <<
" " << vHits.GetY(i) <<
" " << vHits.GetZ(i) <<
" "
174 << vHits.GetType(i) << RESTendl;
184 const std::vector<Float_t>& fXY,
const std::vector<Float_t>& fZ,
const std::vector<Float_t>& fEn,
186 const int nHits = fXY.size();
188 const double max[2] = {TMath::MaxElement(fXY.size(), fXY.data()),
189 TMath::MaxElement(fZ.size(), fZ.data())};
190 const double min[2] = {TMath::MinElement(fXY.size(), fXY.data()),
191 TMath::MinElement(fZ.size(), fZ.data())};
194 for (
const auto& en : fEn) totEn += en;
196 RESTDebug <<
"Max " << max[0] <<
" " << max[1] << RESTendl;
197 RESTDebug <<
"Min " << min[0] <<
" " << min[1] << RESTendl;
201 const int hitAvg = std::round(totEn / (
double)nHits / 10.);
203 for (
int h = 0; h < nHits; h++) {
204 double en = fEn.at(h);
205 for (
int e = 0; e < en; e += hitAvg) {
206 gr[0].SetPoint(c, fXY.at(h), fZ.at(h));
207 gr[1].SetPoint(c, fZ.at(h), fXY.at(h));
212 RESTDebug <<
"Points graph " << c <<
" Hits " << nHits << RESTendl;
219 std::string fitOpt =
"";
222 for (
int l = 0; l < 2; l++) {
223 TF1 f1(
"f1",
"[0] * x + [1]", min[l], max[l]);
224 gr[l].Fit(&f1, fitOpt.c_str());
225 double fitGoodness = f1.GetChisquare();
228 bestFit = fitGoodness;
229 slope = f1.GetParameter(0);
230 intercept = f1.GetParameter(1);
232 }
else if (fitGoodness < bestFit) {
233 bestFit = fitGoodness;
235 slope = f1.GetParameter(0);
236 intercept = f1.GetParameter(1);
240 RESTDebug <<
"Best fit " << bestFit <<
" " << bestIndex << RESTendl;
241 RESTDebug <<
"Slope " << slope <<
" Intercept " << intercept << RESTendl;
243 std::vector<std::pair<double, double>> cluster(nodes);
244 for (
int i = 0; i < nodes; i++) {
245 double first = min[bestIndex] + ((double)i) * (max[bestIndex] - min[bestIndex]) / (
double)(nodes - 1);
246 double second = first * slope + intercept;
248 cluster[i] = std::make_pair(first, second);
250 cluster[i] = std::make_pair(second, first);
A base class for any REST event.
@ REST_Debug
+show the defined debug messages
A process to perform track linearization.
std::vector< std::pair< double, double > > GetBestNodes(const std::vector< Float_t > &fXY, const std::vector< Float_t > &fZ, const std::vector< Float_t > &fEn, const int &nodes)
This function performs a linear fit to the volumehits of the track weighthed by the energy of the hit...
void EndProcess() override
Function to include required actions after all events have been processed.
~TRestTrackLinearizationProcess()
Default destructor.
void Initialize() override
Function to initialize input/output event members and define the section name.
void GetHitsProjection(TRestVolumeHits *hits, const int &nodes, TRestVolumeHits &vHits)
This function performs the track linearization towards a given number of nodes the nodes are extracte...
TRestTrackLinearizationProcess()
Default constructor.
void InitProcess() override
Process initialization. Nothing to do here.
TRestEvent * ProcessEvent(TRestEvent *inputEvent) override
The main processing event function.
void RemoveHits()
It removes all hits inside the class.