R3BROOT
R3B analysis software
Loading...
Searching...
No Matches
R3BNeulandClusterMon.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 "ElasticScattering.h"
16#include "FairLogger.h"
17#include "FairRootManager.h"
18#include "R3BNeulandCluster.h"
19#include "TClonesArray.h"
20#include "TDirectory.h"
21#include "TH1D.h"
22#include "TH2D.h"
23#include "TH3D.h"
24#include <FairTask.h>
25#include <Rtypes.h>
26#include <RtypesCore.h>
27#include <TFile.h>
28#include <TH1.h>
29#include <TString.h>
30#include <algorithm>
31#include <cmath>
32#include <cstdlib>
33#include <fairlogger/Logger.h>
34#include <numeric>
35#include <utility>
36
37namespace
38{
39 constexpr double rad2deg = 180. / 3.141592653589793238463;
40
41 inline auto GetTheta(const R3BNeulandCluster& cluster) -> double
42 {
43 const auto direction = cluster.GetLastHit().GetPosition() - cluster.GetFirstHit().GetPosition();
44 const auto degree = std::acos(direction.Y() / direction.Mag()) * rad2deg;
45 // Not sure, but Kondos Theta is -90:90
46 static constexpr auto retate_angle = 90.;
47 return degree - retate_angle;
48 }
49} // namespace
50
51R3BNeulandClusterMon::R3BNeulandClusterMon(TString input, TString output, const Option_t* option)
52 : FairTask("R3B NeuLAND NeulandCluster Monitor")
53 , fNeulandClusters(input)
54 , fOutput(std::move(output))
55 , fBeta(0.793) // 600 Mev?
56{
57 LOG(info) << "Using R3B NeuLAND NeulandCluster Monitor";
58
59 TString opt = option;
60 opt.ToUpper();
61
62 if (opt.Contains("3DTRACK"))
63 {
64 fIs3DTrackEnabled = true;
65 LOG(info) << "... with 3D track visualization";
66 }
67 else
68 {
69 fIs3DTrackEnabled = false;
70 }
71}
72
74{
75 fNeulandClusters.init();
76
77 FairRootManager* ioman = FairRootManager::Instance();
78 if (!ioman)
79 {
80 LOG(fatal) << "R3BNeulandClusterMon::Init: No FairRootManager";
81 return kFATAL;
82 }
83
85 {
86 // XYZ -> ZXY (side view)
87 fh3 = new TH3D("hClusters", "hClusters", 60, 1400, 1700, 50, -125, 125, 50, -125, 125);
88 fh3->SetTitle("NeuLAND Clusters");
89 fh3->GetXaxis()->SetTitle("Z");
90 fh3->GetYaxis()->SetTitle("X");
91 fh3->GetZaxis()->SetTitle("Y");
92
93 ioman->Register(fOutput, "Cluster TH3Ds in NeuLAND", fh3, kTRUE);
94 }
95
96 TH1::AddDirectory(kFALSE);
97
98 fhClusters = new TH1D("nClusters", "Number of clusters in one event", 100, 0, 100);
99 fhClusterSize = new TH1D("ClusterSize", "Number of Digis for each Cluster", 100, 0, 100);
100 fhClusterEnergy = new TH1D("ClusterEnergy", "Energy for each Cluster", 2000, 0., 2000.);
102 new TH2D("ClusterEnergyVSSize", "Energy for each Cluster vs Cluster Size", 2000, 0., 2000., 100, 0., 100.);
103 fhClusterTime = new TH1D("ClusterTime", "Time for each Cluster", 5000, 0., 500.);
104 fhClusterEToF = new TH1D("ClusterEToF", "Cluster EToF", 2000, 0, 2000);
105 fhClusterRValue = new TH1D("ClusterRValue", "Log Cluster R Value", 20000, -10, 1);
106
108 new TH2D("ClusterSizeVSEToF", "Number of Digis for each Cluster vs EToF", 100, 0, 100, 2000, 0, 2000);
110 new TH2D("ClusterEnergyVSEToF", "Energy for each Cluster vs EToF", 2000, 0., 2000., 2000, 0, 2000);
111 fhClusterEnergyVSSizeVSEToF = new TH3D("ClusterEnergyVSSizeVSEToF",
112 "Energy for each Cluster vs Cluster Size vs EToF",
113 1000,
114 0.,
115 1000.,
116 100,
117 0.,
118 100.,
119 1200,
120 0,
121 1200.);
122
123 fhENFromScatterVSEToF = new TH2D("ENFromScatterVSEToF", "ENFromScatterVSEToF", 1000, 0, 1000, 1000, 0, 1000);
124
126 new TH2D("ClusterNumberEtot", "Number of Clusters vs. Total Energy", 200, 0, 2000, 50, 0, 50);
127 fhClusterNumberVSEnergy->GetXaxis()->SetTitle("Total energy [MeV]");
128 fhClusterNumberVSEnergy->GetYaxis()->SetTitle("Number of Clusters");
129
131 new TH2D("ClusterEToFVSEnergy", "Cluster E_{ToF} vs. Cluster Energy", 100, 0, 1000, 100, 0, 1000);
132 fhClusterEToFVSEnergy->GetXaxis()->SetTitle("Cluster E_{ToF} [MeV]");
133 fhClusterEToFVSEnergy->GetYaxis()->SetTitle("Cluster E [MeV]");
134
135 fhClusterEToFVSTime = new TH2D("ClusterEToFVSTime", "Cluster E_{ToF} vs. Cluster Time", 100, 0, 1000, 500, 0, 500);
136 fhClusterEToFVSTime->GetXaxis()->SetTitle("Cluster E_{ToF} [MeV]");
137 fhClusterEToFVSTime->GetYaxis()->SetTitle("Cluster t [ns]");
138
139 fhClusterEVSTime = new TH2D("ClusterEVSTime", "Cluster E vs. Cluster Time", 250, 0, 250, 500, 0, 250);
140 fhClusterEVSTime->GetXaxis()->SetTitle("Cluster E [MeV]");
141 fhClusterEVSTime->GetYaxis()->SetTitle("Cluster t [ns]");
142
144 "ClusterLastMinusFirstDigiMagVSEnergy", "ClusterLastMinusFirstDigiMagVSEnergy", 101, 0, 100, 60, 0, 600);
145
147 new TH2D("ClusterForemostMinusCentroidVSEnergy",
148 "Distance between Foremost Digi and Energy Centroid vs Cluster Energy",
149 101,
150 0,
151 100,
152 60,
153 0,
154 600);
155 fhClusterForemostMinusCentroidVSEnergy->GetXaxis()->SetTitle("|#vec{r_{z_{min}}}-#vec{r_{EC}}| [cm]");
156 fhClusterForemostMinusCentroidVSEnergy->GetYaxis()->SetTitle("Cluster Energy [MeV]");
157
159 new TH2D("ClusterForemostMinusMaxEnergyDigiPosVSEnergy",
160 "Distance between Foremost Digi and Max Energy Digi vs Cluster Energy",
161 101,
162 0,
163 100,
164 60,
165 0,
166 600);
167 fhClusterForemostMinusMaxEnergyDigiPosVSEnergy->GetXaxis()->SetTitle("|#vec{r_{z_{min}}}-#vec{r_{E_{max}}}| [cm]");
168 fhClusterForemostMinusMaxEnergyDigiPosVSEnergy->GetYaxis()->SetTitle("Cluster Energy [MeV]");
169
171 new TH2D("ClusterCentroidMinusFirstDigiPosVSEnergy",
172 "Distance between Cluster Energy Centroid and First Hit vs Cluster Energy",
173 101,
174 0,
175 100,
176 60,
177 0,
178 600);
179 fhClusterCentroidMinusFirstDigiPosVSEnergy->GetXaxis()->SetTitle("|#vec{r_{EC}}-#vec{r_{t_{min}}}| [cm]");
180 fhClusterCentroidMinusFirstDigiPosVSEnergy->GetYaxis()->SetTitle("Cluster Energy [MeV]");
181
183 new TH2D("ClusterMaxEnergyDigiMinusFirstDigiPosVSEnergy",
184 "Distance between Max Energy Digi and First Digi vs Cluster Energy",
185 101,
186 0,
187 100,
188 60,
189 0,
190 600);
191 fhClusterMaxEnergyDigiMinusFirstDigiPosVSEnergy->GetXaxis()->SetTitle("|#vec{r_{E_{max}}}-#vec{r_{t_{min}}}| [cm]");
192 fhClusterMaxEnergyDigiMinusFirstDigiPosVSEnergy->GetYaxis()->SetTitle("Cluster Energy [MeV]");
193
195 new TH2D("ClusterMaxEnergyDigiMinusCentroidVSEnergy",
196 "Distance between Max Energy Digi and Energy Centroid vs Cluster Energy",
197 101,
198 0,
199 100,
200 60,
201 0,
202 600);
203 fhClusterMaxEnergyDigiMinusCentroidVSEnergy->GetXaxis()->SetTitle("|#vec{r_{E_{max}}}-#vec{r_{EC}}| [cm]");
204 fhClusterMaxEnergyDigiMinusCentroidVSEnergy->GetYaxis()->SetTitle("Cluster Energy [MeV]");
205
207 new TH2D("ClusterEnergyMomentVSEnergy", "Cluster Energy Moment VS Energy", 100, 0, 100, 60, 0, 600);
208 fhClusterEnergyMomentVSEnergy->GetXaxis()->SetTitle("|#vec{EM}| [cm]");
209 fhClusterEnergyMomentVSEnergy->GetYaxis()->SetTitle("Cluster Energy [MeV]");
210
211 fhClusterEnergyMoment = new TH1D("ClusterEnergyMoment", "Cluster Energy Moment", 100, 0, 100);
213 new TH1D("ClusterMaxEnergyDigiMinusFirstDigiMag", "ClusterMaxEnergyDigiMinusFirstDigiMag", 100, 0, 1000);
214
216 new TH2D("ClusterEnergyMomentVSClusterSize", "Cluster Energy Moment VS Cluster Size", 100, 0, 100, 30, 0, 30);
217
218 fhEToFVSEelastic = new TH2D("EToFVSEelastic", "EToFVSEelastic", 50, 0, 1000, 50, 10, 1000);
219 fhScatteredNEnergyVSAngle = new TH2D("ScatteredNEnergyVSAngle", "ScatteredNEnergyVSAngle", 50, 0, 1000, 50, 0, 3.2);
220 fhScatteredNEnergyVSEdep = new TH2D("ScatteredNEnergyVSEdep", "ScatteredNEnergyVSEdep", 100, 0, 1000, 100, 0, 1000);
221
223 new TH2D("ScatterAngleVSRecoilAngle", "ScatterAngleVSRecoilAngle", 50, 0, 3.2, 50, 0, 3.2);
224
225 fhSumAngleVSRatioErecoEtof = new TH2D("SumAngleVSRatioErecoEtof", "SumAngleVSRatioErecoEtof", 50, 0, 3.2, 50, 0, 2);
227 new TH2D("ClusterEnergyVSScatteredRecoilAngle", "ClusterEnergyVSScatteredRecoilAngle", 50, 0, 1000, 50, 0, 3.2);
229 "ClusterEnergyVSScatteredNeutronAngle", "ClusterEnergyVSScatteredNeutronAngle", 50, 0, 1000, 50, 0, 3.2);
230
231 fhElasticTargetMass = new TH2D("ElasticTargetMass", "ElasticTargetMass", 200, -50000, 50000, 100, 0, 1000);
232
233 /*fhtheh = new TH2D("theh", "", 100, 0, 1000, 100, 0, 2000);
234 ediff = new TH2D("ediff", "Reconstructed Proton Energy VS Measured Cluster Energy", 100, 0, 300, 100, 0, 300);
235 ediff->GetXaxis()->SetTitle("E_{p'}");
236 ediff->GetYaxis()->SetTitle("E_{cluster}");
237
238 etheta = new TH2D("etheta", "", 100, 0, 1000, 100, -1, 1);
239
240 fhProtonTrack*/
241
242 fhZ = new TH1D("Z", "Z", 5000, 0., 5000.);
243 fhZVSEToF = new TH2D("ZVSEToF", "Z vs EToF", 4000, 1000, 5000, 2000, 0, 2000);
244 fhDistFromCenter = new TH1D("DistFromCenter", "DistFromCenter", 500, 0., 500.);
245 fhDistFromCenterVSEToF = new TH2D("DistFromCenterVSEToF", "DistFromCenter vs EToF", 500, 0, 500, 2000, 0, 2000);
246
247 fhDeltaT = new TH1D("fhDeltaT", "T_{Last Digi} - T_{First Digi}", 1000, 0, 100);
249 new TH1D("fhForemostMinusFirstDigiTime", "T_{Foremost} - T_{First Digi}", 1000, -10, 10);
250
251 fhThetaEDigi = new TH2D("fhThetaEDigi", "fhThetaEDigi", 1000, -500, 500, 400, 0, 400);
252 fhThetaEDigiCosTheta = new TH2D("fhThetaEDigiCosTheta", "fhThetaEDigiCosTheta", 1000, -500, 500, 400, 0, 400);
253
254 hT = new TH1D("hT", "Cluster Digi Delta T", 3000, 0., 15.);
255 hTNeigh = new TH1D("hTNeigh", "Cluster Digi Neigh Delta T", 3000, 0., 15.);
256
257 return kSUCCESS;
258}
259
261{
264 std::remove_if(fNeulandClustersBuffer.begin(),
266 [&](R3BNeulandCluster& cluster) { return !(fClusterFilters.IsValid(&cluster)); }),
268
269 const auto nClusters = fNeulandClustersBuffer.size();
270
272 {
273 fh3->Reset("ICES");
274 for (const auto& cluster : fNeulandClustersBuffer)
275 {
276 const auto start = cluster.GetFirstHit().GetPosition();
277 // XYZ -> ZXY (side view)
278 fh3->Fill(start.Z(), start.X(), start.Y(), cluster.GetE());
279 }
280 }
281
282 const Double_t etot =
283 std::accumulate(fNeulandClustersBuffer.begin(),
285 0.,
286 [](Double_t sum, const R3BNeulandCluster& cluster) { return sum + cluster.GetE(); });
287
288 fhClusterNumberVSEnergy->Fill(etot, nClusters);
289
290 fhClusters->Fill(nClusters);
291 for (const auto& cluster : fNeulandClustersBuffer)
292 {
293 fhClusterTime->Fill(cluster.GetT());
294 fhClusterSize->Fill(cluster.GetSize());
295 fhClusterEnergy->Fill(cluster.GetE());
296 fhClusterRValue->Fill(std::log10(cluster.GetRCluster(fBeta)));
297 fhClusterEnergyVSSize->Fill(cluster.GetE(), cluster.GetSize());
298 fhClusterEToF->Fill(cluster.GetFirstHit().GetEToF());
299 fhClusterEToFVSEnergy->Fill(cluster.GetFirstHit().GetEToF(), cluster.GetE());
300 fhClusterEToFVSTime->Fill(cluster.GetFirstHit().GetEToF(), cluster.GetT());
301 fhClusterEVSTime->Fill(cluster.GetFirstHit().GetE(), cluster.GetT());
302
303 fhClusterEnergyVSEToF->Fill(cluster.GetE(), cluster.GetFirstHit().GetEToF());
304 fhClusterSizeVSEToF->Fill(cluster.GetSize(), cluster.GetFirstHit().GetEToF());
305 fhClusterEnergyVSSizeVSEToF->Fill(cluster.GetE(), cluster.GetSize(), cluster.GetFirstHit().GetEToF());
306 if (cluster.GetSize() > 2)
307 {
309 (cluster.GetForemostHit().GetPosition() - cluster.GetEnergyCentroid()).Mag(), cluster.GetE());
310
312 (cluster.GetForemostHit().GetPosition() - cluster.GetMaxEnergyHit().GetPosition()).Mag(),
313 cluster.GetE());
314
316 (cluster.GetEnergyCentroid() - cluster.GetFirstHit().GetPosition()).Mag(), cluster.GetE());
317
319 (cluster.GetMaxEnergyHit().GetPosition() - cluster.GetFirstHit().GetPosition()).Mag(), cluster.GetE());
321 (cluster.GetMaxEnergyHit().GetPosition() - cluster.GetEnergyCentroid()).Mag(), cluster.GetE());
322 fhClusterEnergyMomentVSEnergy->Fill(cluster.GetEnergyMoment(), cluster.GetE());
324
326 (cluster.GetLastHit().GetPosition() - cluster.GetFirstHit().GetPosition()).Mag(), cluster.GetE());
327
328 fhClusterEnergyMoment->Fill(cluster.GetEnergyMoment());
330 (cluster.GetMaxEnergyHit().GetPosition() - cluster.GetFirstHit().GetPosition()).Mag());
331 }
332
333 fhZ->Fill(cluster.GetFirstHit().GetPosition().Z());
334 fhZVSEToF->Fill(cluster.GetFirstHit().GetPosition().Z(), cluster.GetEToF());
335 fhDistFromCenter->Fill(std::sqrt(std::pow(cluster.GetFirstHit().GetPosition().X(), 2) +
336 std::pow(cluster.GetFirstHit().GetPosition().Y(), 2)));
337 fhDistFromCenterVSEToF->Fill(std::sqrt(std::pow(cluster.GetFirstHit().GetPosition().X(), 2) +
338 std::pow(cluster.GetFirstHit().GetPosition().Y(), 2)),
339 cluster.GetEToF());
340 fhDeltaT->Fill(cluster.GetLastHit().GetT() - cluster.GetFirstHit().GetT());
341
342 fhForemostMinusFirstDigiTime->Fill(cluster.GetForemostHit().GetT() - cluster.GetFirstHit().GetT());
343
344 if (cluster.GetSize() > 4)
345 {
346 const auto theta = GetTheta(cluster);
347 for (const auto& digi : cluster.GetHits())
348 {
349 fhThetaEDigi->Fill(theta, digi.GetE());
350 fhThetaEDigiCosTheta->Fill(theta, digi.GetE() * std::cos(theta / rad2deg));
351 }
352 }
353 }
354
355 std::sort(fNeulandClustersBuffer.begin(),
357 [](const R3BNeulandCluster& left, const R3BNeulandCluster& right) { return left.GetT() < right.GetT(); });
358
359 for (const auto& cluster : fNeulandClustersBuffer)
360 {
361 if (cluster.GetSize() >= 3)
362 {
364
366 std::acos(Neuland::RecoilScatteringAngle(cluster)));
367 }
368 }
369
370 for (auto ita = fNeulandClustersBuffer.cbegin(); ita != fNeulandClustersBuffer.cend(); ita++)
371 {
372 for (auto itb = ita + 1; itb != fNeulandClustersBuffer.cend(); itb++)
373 {
374
376 std::acos(Neuland::ScatteredNeutronAngle(*ita, *itb)));
377
378 fhScatteredNEnergyVSEdep->Fill(Neuland::ScatteredNeutronEnergy(*ita, *itb), (*ita).GetE());
379
380 const Double_t EelasticHeavy = Neuland::NeutronEnergyFromElasticScattering(*ita, *itb, 11000);
381 fhEToFVSEelastic->Fill((*ita).GetFirstHit().GetEToF(), EelasticHeavy);
382 // const Double_t EelasticProton = Neuland::NeutronEnergyFromElasticScattering(*ita, *itb, 1000);
383 // fhEToFVSEelastic->Fill((*ita)->GetFirstHit().GetEToF(), EelasticProton);
384
385 if (Neuland::ScatteredNeutronEnergy(*ita, *itb) > 10.)
386 {
387 fhElasticTargetMass->Fill(Neuland::ElasticScatteringTargetMass(*ita, *itb), (*ita).GetE());
388 fhClusterEnergyVSScatteredNeutronAngle->Fill((*ita).GetE(),
389 std::acos(Neuland::ScatteredNeutronAngle(*ita, *itb)));
390
391 if ((*ita).GetSize() >= 3)
392 {
394 std::acos(Neuland::RecoilScatteringAngle(*ita)));
396 std::acos(Neuland::ScatteredNeutronAngle(*ita, *itb)) +
397 std::acos(Neuland::RecoilScatteringAngle(*ita)),
398 Neuland::NeutronEnergyFromElasticProtonScattering(*ita) / (*ita).GetFirstHit().GetEToF());
399 }
400 }
401 }
402 }
403
404 for (const auto& cluster : fNeulandClustersBuffer)
405 {
406 const auto& digis = cluster.GetHits();
407 for (auto it1 = digis.begin(); it1 != digis.end(); it1++)
408 {
409 for (auto it2 = it1 + 1; it2 != digis.end(); it2++)
410 {
411 if (std::abs(it1->GetPosition().X() - it2->GetPosition().X()) < 7.5 &&
412 std::abs(it1->GetPosition().Y() - it2->GetPosition().Y()) < 7.5 &&
413 std::abs(it1->GetPosition().Z() - it2->GetPosition().Z()) < 7.5)
414 {
415 hTNeigh->Fill(std::abs(it1->GetT() - it2->GetT()));
416 }
417 hT->Fill(std::abs(it1->GetT() - it2->GetT()));
418 }
419 }
420 }
421}
422
424{
425 TDirectory* tmp = gDirectory;
426 FairRootManager::Instance()->GetOutFile()->cd();
427
428 gDirectory->mkdir(fOutput);
429 gDirectory->cd(fOutput);
430
431 fhClusters->Write();
432 fhClusterSize->Write();
433 fhClusterEnergyVSSize->Write();
434 fhClusterEnergy->Write();
435 fhClusterRValue->Write();
436 fhClusterTime->Write();
438 fhClusterEToF->Write();
439 fhClusterEToFVSEnergy->Write();
440 fhClusterEToFVSTime->Write();
441 fhElasticTargetMass->Write();
442
443 fhClusterSizeVSEToF->Write();
444 fhClusterEnergyVSEToF->Write();
445 // fhClusterEnergyVSSizeVSEToF->Write();
446
454 fhClusterEVSTime->Write();
455 fhClusterEnergyMoment->Write();
458
459 fhENFromScatterVSEToF->Write();
460
461 fhEToFVSEelastic->Write();
468
469 fhZ->Write();
470 fhZVSEToF->Write();
471 fhDistFromCenter->Write();
472 fhDistFromCenterVSEToF->Write();
473 fhDeltaT->Write();
475
476 fhThetaEDigi->Write();
477 fhThetaEDigiCosTheta->Write();
478
479 hT->Write();
480 hTNeigh->Write();
481
482 gDirectory = tmp;
483}
484
ClassImp(R3B::Neuland::Cal2HitPar)
Double_t GetTheta(const R3BMCTrack *mcTrack)
Double_t GetE() const
R3BNeulandHit GetFirstHit() const
TVector3 GetEnergyCentroid() const
Double_t GetRCluster(Double_t beta) const
Size_t GetSize() const
R3BNeulandHit GetMaxEnergyHit() const
Double_t GetT() const
Double_t GetEToF() const
const std::vector< R3BNeulandHit > & GetHits() const
Double_t GetEnergyMoment() const
R3BNeulandHit GetLastHit() const
R3BNeulandHit GetForemostHit() const
TH2D * fhClusterMaxEnergyDigiMinusFirstDigiPosVSEnergy
void Exec(Option_t *) override
TH2D * fhClusterForemostMinusMaxEnergyDigiPosVSEnergy
TH2D * fhClusterCentroidMinusFirstDigiPosVSEnergy
std::vector< R3BNeulandCluster > fNeulandClustersBuffer
R3B::InputVectorConnector< R3BNeulandCluster > fNeulandClusters
TH2D * fhClusterMaxEnergyDigiMinusCentroidVSEnergy
R3BNeulandClusterMon(TString input="NeulandClusters", TString output="NeulandClusterMon", const Option_t *option="")
auto Init() -> InitStatus override
auto NeutronEnergyFromElasticProtonScattering(const R3BNeulandCluster &cluster) -> double
auto ElasticScatteringTargetMass(const R3BNeulandCluster &first, const R3BNeulandCluster &second) -> double
auto NeutronEnergyFromElasticScattering(const R3BNeulandCluster &first, const R3BNeulandCluster &second, double target_mass) -> double
Calculate neutron kinetic energy from the elastic scattering.
auto ScatteredNeutronEnergy(const R3BNeulandCluster &first, const R3BNeulandCluster &second) -> double
Calculate neutron kinetic energy from the scattering.
auto ScatteredNeutronAngle(const R3BNeulandCluster &first, const R3BNeulandCluster &second) -> double
Calculate the scattering angle of the neutron.
auto RecoilScatteringAngle(const R3BNeulandCluster &cluster) -> double
auto GetT() const -> double
auto GetPosition() const -> TVector3
auto GetEToF(double mass=NEUTRON_MASS_MEV) const -> double
auto GetE() const -> double