R3BROOT
R3B analysis software
Loading...
Searching...
No Matches
CosmicMuon.h
Go to the documentation of this file.
1/******************************************************************************
2 * Copyright (C) 2019 GSI Helmholtzzentrum für Schwerionenforschung GmbH *
3 * Copyright (C) 2019-2024 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
14#pragma once
15#include "FairPrimaryGenerator.h"
16#include "RtypesCore.h"
17#include "TRandom.h"
18#include <FairGenerator.h>
19#include <Math/GenVector/Cartesian3D.h>
20#include <Math/GenVector/Polar3D.h>
21#include <Math/GenVector/PxPyPzE4D.h>
22#include <R3BIOConnector.h>
23#include <R3BNeulandCommon.h>
24#include <TRandom3.h>
25#include <cmath>
26#include <fmt/format.h>
27#include <memory>
28#include <utility>
29
30namespace R3B::Neuland
31{
32 struct AngleInfo
33 {
34 double sin_phi{};
35 double sin_theta{};
36 double cos_phi{};
37 double cos_theta{};
38 };
39
41 {
42 ROOT::Math::PxPyPzE4D<double> momentum;
43 ROOT::Math::Cartesian3D<double> position;
44
46 };
47
48 constexpr auto default_detector_size{ 200.0 };
49 constexpr auto default_PID{ 13 };
50
52 {
53 public:
59 virtual ~TrackGeneratorAbstract() = default;
60
61 virtual void set_detector_size(double detector_size) = 0;
62 virtual auto ReadEvent(FairPrimaryGenerator* prim_gen) -> bool = 0;
63 virtual void set_rd_engine(TRandom* user_rd_engine) = 0;
64 virtual void set_PID(int PID) = 0;
65 };
66
67 template <typename AngleDist, typename EnergyDist, typename PositionDist>
69 {
70 public:
71 TrackGeneratorImp(const AngleDist& angle_dist, const EnergyDist& energy_dist, const PositionDist& position_dist)
72 : angle_dist_{ angle_dist }
73 , energy_dist_{ energy_dist }
74 , position_dist_{ position_dist }
75 {
76 muon_track_output_.init();
77 }
78
79 void set_detector_size(double detector_size) override { detector_size_ = detector_size; }
80 void set_rd_engine(TRandom* user_rd_engine) override { rd_engine_ = user_rd_engine; }
81 void set_PID(int PID) override { PID_ = PID; }
82
83 private:
84 using MomentumPosition = std::pair<ROOT::Math::PxPyPzE4D<double>, ROOT::Math::Cartesian3D<double>>;
85 using Momentum = ROOT::Math::PxPyPzE4D<double>;
86 using AngleRadius = ROOT::Math::Polar3D<double>;
87 double detector_size_{ default_detector_size };
88 int PID_{ default_PID };
89
90 R3B::OutputVectorConnector<MuonTrackInfo> muon_track_output_{ "muon_track_info" };
91 AngleDist angle_dist_{};
92 EnergyDist energy_dist_{};
93 PositionDist position_dist_{};
94 TRandom* rd_engine_{ gRandom };
95
96 // Paula: which methods have to be virtual?
97 auto rd_num_gen_angles(const AngleDist& angle_dist) -> AngleRadius;
98 auto calculate_momentum_energy(const double& kinetic_energy, const AngleInfo& angle_info) -> Momentum;
99
100 auto calculate_external_position_momentum(const AngleDist& angle_dist,
101 const EnergyDist& energy_dist,
102 const PositionDist& position_dist) -> MomentumPosition;
103 auto ReadEvent(FairPrimaryGenerator* prim_gen) -> bool override
104 {
105 muon_track_output_.clear();
106 auto& muon_track = muon_track_output_.get().emplace_back();
107 auto momentum_position =
108 MomentumPosition{ calculate_external_position_momentum(angle_dist_, energy_dist_, position_dist_) };
109 muon_track.momentum = momentum_position.first;
110 muon_track.position = momentum_position.second;
111 prim_gen->AddTrack(PID_,
112 momentum_position.first.Px(),
113 momentum_position.first.Py(),
114 momentum_position.first.Pz(),
115 momentum_position.second.X(),
116 momentum_position.second.Y(),
117 momentum_position.second.Z());
118 return true;
119 };
120 };
121
122 template <typename AngleDist, typename EnergyDist, typename PositionDist>
123 auto TrackGeneratorImp<AngleDist, EnergyDist, PositionDist>::rd_num_gen_angles(const AngleDist& angle_dist)
124 -> AngleRadius
125 {
126 auto angles = AngleRadius{};
127 angles.SetPhi(rd_engine_->Uniform(0., 2 * M_PI));
128 // angles.SetTheta(0);
129 angles.SetTheta(angle_dist(rd_engine_));
130
131 return angles;
132 }
133
134 template <typename AngleDist, typename EnergyDist, typename PositionDist>
135 auto TrackGeneratorImp<AngleDist, EnergyDist, PositionDist>::calculate_momentum_energy(const double& kinetic_energy,
136 const AngleInfo& angle_info)
137 -> Momentum
138 {
139 auto total_energy = kinetic_energy + MUON_MASS;
140 auto momentum_energy = Momentum{ 0, 0, 0, total_energy };
141 momentum_energy.SetPx(kinetic_energy * angle_info.sin_theta * angle_info.cos_phi);
142 momentum_energy.SetPy(kinetic_energy * angle_info.cos_theta);
143 momentum_energy.SetPz(kinetic_energy * angle_info.sin_theta * angle_info.sin_phi);
144 return momentum_energy;
145 }
146
147 template <typename AngleDist, typename EnergyDist, typename PositionDist>
148 auto TrackGeneratorImp<AngleDist, EnergyDist, PositionDist>::calculate_external_position_momentum(
149 const AngleDist& angle_dist,
150 const EnergyDist& energy_dist,
151 const PositionDist& position_dist) -> MomentumPosition
152 {
153 auto const position = position_dist(rd_engine_);
154 // //cout looking for errors
155 // std::cout << "x Posistion: "<< position.X()<<"\n";
156 // std::cout << "y Posistion: "<< position.Y()<<"\n";
157 // std::cout << "z Posistion: "<< position.Z()<<"\n";
158 auto const angles = rd_num_gen_angles(angle_dist);
159 auto const energy = energy_dist(rd_engine_);
160
161 auto angle_info = AngleInfo{};
162 angle_info.sin_phi = std::sin(angles.Phi());
163 angle_info.cos_phi = std::cos(angles.Phi());
164 angle_info.sin_theta = std::sin(angles.Theta());
165 angle_info.cos_theta = std::cos(angles.Theta());
166
167 auto position_momentum = MomentumPosition{};
168
169 position_momentum.second.SetX(position.X() - angle_info.sin_theta * angle_info.cos_phi * detector_size_);
170 position_momentum.second.SetY(position.Y() - angle_info.cos_theta * detector_size_);
171 position_momentum.second.SetZ(position.Z() - angle_info.sin_theta * angle_info.sin_phi * detector_size_);
172 position_momentum.first = calculate_momentum_energy(energy, angle_info);
173
174 return position_momentum;
175 }
176
177 class TrackGenerator : public FairGenerator
178 {
179 public:
181 template <typename AngleDist, typename EnergyDist, typename PositionDist>
182 TrackGenerator(AngleDist angle_dist, EnergyDist energy_dist, PositionDist position_dist)
183 : ptr_{ std::make_unique<TrackGeneratorImp<AngleDist, EnergyDist, PositionDist>>(angle_dist,
184 energy_dist,
185 position_dist) }
186 {
187 }
188 void set_detector_size(double detector_size) { ptr_->set_detector_size(detector_size); }
189 void set_rd_engine(TRandom* user_rd_engine) { ptr_->set_rd_engine(user_rd_engine); }
190 void set_PID(int PID) { ptr_->set_PID(PID); }
191
192 auto get_ptr() -> TrackGeneratorAbstract* { return ptr_.get(); }
193
194 private:
195 std::unique_ptr<TrackGeneratorAbstract> ptr_;
196 auto ReadEvent(FairPrimaryGenerator* prim_gen) -> Bool_t override
197 {
198 ptr_->ReadEvent(prim_gen);
199 return true;
200 }
201
202 ClassDefOverride(TrackGenerator, 1); // NOLINT
203 };
204
205 template <typename AngleDist, typename EnergyDist, typename PositionDist>
206 auto CreateTrackGenerator(const AngleDist& angle_dist,
207 const EnergyDist& energy_dist,
208 const PositionDist& position_dist)
209 {
210 return std::make_unique<TrackGenerator>(angle_dist, energy_dist, position_dist);
211 }
212} // namespace R3B::Neuland
virtual void set_rd_engine(TRandom *user_rd_engine)=0
auto operator=(TrackGeneratorAbstract &&) -> TrackGeneratorAbstract &=default
TrackGeneratorAbstract(TrackGeneratorAbstract &&)=default
virtual void set_detector_size(double detector_size)=0
TrackGeneratorAbstract(const TrackGeneratorAbstract &)=default
auto operator=(const TrackGeneratorAbstract &) -> TrackGeneratorAbstract &=default
virtual auto ReadEvent(FairPrimaryGenerator *prim_gen) -> bool=0
virtual ~TrackGeneratorAbstract()=default
virtual void set_PID(int PID)=0
TrackGenerator(AngleDist angle_dist, EnergyDist energy_dist, PositionDist position_dist)
Definition CosmicMuon.h:182
void set_detector_size(double detector_size)
Definition CosmicMuon.h:188
auto ReadEvent(FairPrimaryGenerator *prim_gen) -> Bool_t override
Definition CosmicMuon.h:196
auto get_ptr() -> TrackGeneratorAbstract *
Definition CosmicMuon.h:192
void set_rd_engine(TRandom *user_rd_engine)
Definition CosmicMuon.h:189
void set_detector_size(double detector_size) override
Definition CosmicMuon.h:79
TrackGeneratorImp(const AngleDist &angle_dist, const EnergyDist &energy_dist, const PositionDist &position_dist)
Definition CosmicMuon.h:71
auto ReadEvent(FairPrimaryGenerator *prim_gen) -> bool override
Definition CosmicMuon.h:103
void set_PID(int PID) override
Definition CosmicMuon.h:81
void set_rd_engine(TRandom *user_rd_engine) override
Definition CosmicMuon.h:80
Simulation of NeuLAND Bar/Paddle.
constexpr auto default_PID
Definition CosmicMuon.h:49
constexpr auto default_detector_size
Definition CosmicMuon.h:48
constexpr auto MUON_MASS
auto CreateTrackGenerator(const AngleDist &angle_dist, const EnergyDist &energy_dist, const PositionDist &position_dist)
Definition CosmicMuon.h:206
OutputConnector< std::vector< ElementType > > OutputVectorConnector
ROOT::Math::PxPyPzE4D< double > momentum
Definition CosmicMuon.h:42
ClassDefNV(MuonTrackInfo, 1)
ROOT::Math::Cartesian3D< double > position
Definition CosmicMuon.h:43