R3BROOT
R3B analysis software
Loading...
Searching...
No Matches
R3BNeulandPrimaryInteractionFinder.cxx
Go to the documentation of this file.
1/******************************************************************************
2 * Copyright (C) 2019 GSI Helmholtzzentrum für Schwerionenforschung GmbH *
3 * Copyright (C) 2019-2025 Members of R3B Collaboration *
4 * *
5 * This software is distributed under the terms of the *
6 * GNU General Public Licence (GPL) version 3, *
7 * copied verbatim in the file "LICENSE". *
8 * *
9 * In applying this license GSI does not waive the privileges and immunities *
10 * granted to it by virtue of its status as an Intergovernmental Organization *
11 * or submit itself to any jurisdiction. *
12 ******************************************************************************/
13
15#include "FairLogger.h"
16#include "R3BMCTrack.h"
17#include "R3BNeulandHit.h"
18#include "R3BNeulandPoint.h"
19#include "TFile.h"
20#include <FairRootManager.h>
21#include <FairTask.h>
22#include <RtypesCore.h>
23#include <TDirectory.h>
24#include <TH1.h>
25#include <TH2.h>
26#include <fairlogger/Logger.h>
27#include <map>
28#include <string_view>
29#include <vector>
30
31namespace
32{
33 constexpr auto NEUTRON_PID = 2112;
34 constexpr auto MIN_TOF_DEFAULT = 1e99;
35
36 auto IsPrimaryTrack(const R3BMCTrack& track) -> bool
37 {
38 // TODO: The test can be modified to rely on some other information,
39 // e.g. if the neutrons were created in a reaction in the target simulated with Geant
40 return track.GetMotherId() == -1 && track.GetPdgCode() == NEUTRON_PID;
41 }
42
43 // Map a hit to every point if possible (else -1)
44 auto MapPointsToHits(const std::vector<R3BNeulandPoint>& points, const std::vector<R3BNeulandHit>& hits)
45 -> std::map<const R3BNeulandPoint*, const R3BNeulandHit*>
46 {
47 auto point_to_hit_map = std::map<const R3BNeulandPoint*, const R3BNeulandHit*>{};
48 for (const auto& point : points)
49 {
50 point_to_hit_map[&point] = nullptr;
51 for (const auto& hit : hits)
52 {
53 if (point.GetPaddle() == hit.GetPaddle())
54 {
55 point_to_hit_map[&point] = &hit;
56 }
57 }
58 }
59 return point_to_hit_map;
60 };
61
62 // Map a primary track to every point if possible (else -1)
63 auto MapPointsToPrimaryTracks(const std::vector<R3BNeulandPoint>& points, const std::vector<R3BMCTrack>& tracks)
64 -> std::map<const R3BNeulandPoint*, const R3BMCTrack*>
65 {
66 std::map<const R3BNeulandPoint*, const R3BMCTrack*> point_to_track_map;
67 for (const auto& point : points)
68 {
69 point_to_track_map[&point] = nullptr;
70 auto iTrack = point.GetTrackID();
71 while (iTrack > -1)
72 {
73 const auto& track = tracks.at(iTrack);
74 if (IsPrimaryTrack(track))
75 {
76 point_to_track_map[&point] = &track;
77 break;
78 }
79 // Else, start tracing back:
80 iTrack = track.GetMotherId();
81 }
82 }
83 return point_to_track_map;
84 }
85
86 auto FindFirstPoint(const R3BMCTrack& track,
87 const std::map<const R3BNeulandPoint*, const R3BMCTrack*>& point_to_track_map)
88 -> const R3BNeulandPoint*
89 {
90 const R3BNeulandPoint* minPoint{ nullptr };
91 // Search for min ToF:
92 auto minToF = MIN_TOF_DEFAULT;
93
94 for (auto [map_point, map_track] : point_to_track_map)
95 {
96 // Only look at points traced back to this track:
97 if (map_track == &track)
98 {
99 const auto ToF = map_point->GetTime();
100 if (ToF < minToF)
101 {
102 minToF = ToF;
103 minPoint = map_point;
104 }
105 }
106 }
107 return minPoint;
108 }
109
110 auto FindFirstHit(const R3BMCTrack& track,
111 const std::map<const R3BNeulandPoint*, const R3BMCTrack*>& point_to_track_map,
112 const std::map<const R3BNeulandPoint*, const R3BNeulandHit*>& point_to_hit_map)
113 -> const R3BNeulandHit*
114 {
115 const R3BNeulandPoint* minHitPoint = nullptr;
116 // Search for min ToF:
117 double minHitToF = MIN_TOF_DEFAULT;
118
119 for (const auto [map_point, map_track] : point_to_track_map)
120 {
121 // Only look at points traced back to this track:
122 // AND where a hit is registered
123 if (map_track == &track && point_to_hit_map.find(map_point) != point_to_hit_map.end())
124 {
125 const auto ToF = map_point->GetTime();
126 if (ToF < minHitToF)
127 {
128 minHitToF = ToF;
129 minHitPoint = map_point;
130 }
131 }
132 }
133 return minHitPoint != nullptr ? point_to_hit_map.at(minHitPoint) : nullptr;
134 }
135
136} // namespace
137
138// NOLINTNEXTLINE: bugprone-easily-swappable-parameters
140 std::string_view hitsIn,
141 std::string_view pointsOut,
142 std::string_view hitsOut,
143 std::string_view tracksOut)
144 : FairTask("R3BNeulandPrimaryInteractionFinder")
145 , fTracksIn("MCTrack")
146 , fPointsIn(pointsIn)
147 , fHitsIn(hitsIn)
148 , fTracksOut(tracksOut)
149 , fPointsOut(pointsOut)
150 , fHitsOut(hitsOut)
151 , fhDistance(new TH1D("fhDistance", "Distance firstPoint to firstHit", 10000, 0, 1000))
152 , fhPointsVsHits(new TH2D("fhPointsVsHits", "Number of Primary Points vs Number of Primary Hits", 6, 0, 6, 6, 0, 6))
154 new TH2D("fhPointVsHitPaddle", "First Point Paddle vs First Hit Paddle", 3001, -1, 3000, 3001, -1, 3000))
155{
156 fhDistance->GetXaxis()->SetTitle("Distance [cm]");
157 fhPointsVsHits->GetXaxis()->SetTitle("# First Points");
158 fhPointsVsHits->GetYaxis()->SetTitle("# First Hits");
159 fhPointVsHitPaddle->GetXaxis()->SetTitle("First Point Paddle");
160 fhPointVsHitPaddle->GetYaxis()->SetTitle("First Hit Paddle");
161}
162
164{
165 fTracksIn.init();
166 fPointsIn.init();
167 fHitsIn.init();
168 fTracksOut.init();
169 fPointsOut.init();
170 fHitsOut.init();
171 return kSUCCESS;
172}
173
175{
176 const auto& tracks = fTracksIn.read();
177 const auto& points = fPointsIn.get();
178 const auto& hits = fHitsIn.get();
179 fTracksOut.clear();
180 fPointsOut.clear();
181 fHitsOut.clear();
182
183 const auto point_to_hit_map = MapPointsToHits(points, hits);
184 const auto point_to_track_map = MapPointsToPrimaryTracks(points, tracks);
185
186 if (FairLogger::GetLogger()->IsLogNeeded(fair::Severity::debug))
187 {
188 LOG(debug) << "R3BNeulandPrimaryInteractionFinder: Points without Hit in: ";
189 for (const auto [map_point, map_hit] : point_to_hit_map)
190 {
191 if (map_hit == nullptr)
192 {
193 const auto& point = map_point;
194 LOG(debug) << point->GetDetectorID() << ":" << tracks.at(point->GetTrackID()).GetPdgCode() << ":"
195 << point->GetLightYield() << ":" << point->GetEnergyLoss() << "\t";
196 }
197 }
198 }
199
200 for (const auto& track : tracks)
201 {
202 if (IsPrimaryTrack(track))
203 {
204 fTracksOut.get().push_back(track);
205
206 const auto* firstPoint = FindFirstPoint(track, point_to_track_map);
207 const auto* firstHit = FindFirstHit(track, point_to_track_map, point_to_hit_map);
208
209 if (firstPoint != nullptr)
210 {
211 fPointsOut.get().push_back(*firstPoint);
212 }
213
214 if (firstHit != nullptr)
215 {
216 // NOTE: This may add the same hit multiple times.
217 fHitsOut.get().push_back(*firstHit);
218 }
219
220 if ((firstHit != nullptr) && (firstPoint != nullptr))
221 {
222 fhDistance->Fill((firstPoint->GetPosition() - firstHit->GetPosition()).Mag());
223 }
224
225 fhPointVsHitPaddle->Fill((firstPoint != nullptr) ? firstPoint->GetPaddle() : -1,
226 (firstHit != nullptr) ? firstHit->GetPaddle() : -1);
227 }
228 }
229
230 fhPointsVsHits->Fill(static_cast<double>(fPointsOut.get().size()), static_cast<double>(fHitsOut.get().size()));
231}
232
234{
235 TDirectory* tmp = gDirectory;
236 FairRootManager::Instance()->GetOutFile()->cd();
237 gDirectory->mkdir("R3BNeulandPrimaryInteractionFinder");
238 gDirectory->cd("R3BNeulandPrimaryInteractionFinder");
239
240 fhDistance->Write();
241 fhPointsVsHits->Write();
242 fhPointVsHitPaddle->Write();
243
244 gDirectory = tmp;
245}
R3B::InputVectorConnector< R3BNeulandPoint > fPointsIn
R3BNeulandPrimaryInteractionFinder(std::string_view pointsIn="NeulandPoints", std::string_view hitsIn="NeulandHits", std::string_view pointsOut="NeulandPrimaryPoints", std::string_view hitsOut="NeulandPrimaryHits", std::string_view tracksOut="NeulandPrimaryTracks")
R3B::InputVectorConnector< R3BNeulandHit > fHitsIn
R3B::InputTCAConnector< R3BMCTrack > fTracksIn
R3B::OutputVectorConnector< R3BNeulandPoint > fPointsOut
R3B::OutputVectorConnector< R3BNeulandHit > fHitsOut
R3B::OutputVectorConnector< R3BMCTrack > fTracksOut