25 : fInData(nullptr), fOutData(nullptr), fOutReacData(nullptr), srim(nullptr) {
26 RegisterInputCollection(
"InputCollection",
"input branch (collection) name",
fInputColName, TString(
"input"));
27 RegisterOutputCollection(
"OutputCollection",
"output branch (collection) name",
fOutputColName,
28 TString(
"reaction_particles"));
29 RegisterOutputCollection(
"OutputReactionCollection",
"output branch (collection) name",
fOutputReacColName,
34 RegisterProcessorParameter(
"BeamNucleus",
"beam nucleus (Z, A)",
fBeamNucleus, init_i_vec);
35 RegisterProcessorParameter(
"BeamEnergy",
"initial beam energy used for initializing TSrim object",
39 RegisterProcessorParameter(
"TargetIsGas",
"Bool, target is targer or not",
fTargetIsGas,
false);
40 RegisterProcessorParameter(
"TargetName",
"name of target material",
fTargetName, TString(
""));
41 RegisterProcessorParameter(
"TargetMassNum",
"Target mass number",
fTargetMassNum, 0);
42 RegisterProcessorParameter(
"TargetAtomicNum",
"Target atomic number",
fTargetAtmNum, 0);
43 RegisterProcessorParameter(
"TargetThickness",
"Target mass",
fTargetThickness, 0.0);
44 RegisterProcessorParameter(
"TargetPressure",
"Target presure",
fTargetPressure, 0.0);
47 DoubleVec_t init_d_vec;
48 RegisterProcessorParameter(
"DecayParticleNum",
"reaction particle number",
fDecayNum, 1);
49 RegisterProcessorParameter(
"ReactionMassNum",
"reaction particles mass number",
fReacMassNum, init_i_vec);
50 RegisterProcessorParameter(
"ReactionAtomicNum",
"reaction particles atomic number",
fReacAtmNum, init_i_vec);
51 RegisterProcessorParameter(
"ExciteLevel",
"energy level for id=0 nucleus",
fExciteLevel, init_d_vec);
52 RegisterProcessorParameter(
"CrossSectionPath",
"path to the cross section data file",
fCSDataPath, TString(
""));
53 RegisterProcessorParameter(
"CrossSectionType",
54 "energy format, 0: LAB energy like TALYS, 1: LAB at inverse kinematics, 2: Ecm",
fCSType, 0);
131 if ((*fInData)->GetEntriesFast() != 1) {
132 SetStateError(
"input branch entry is not 1");
140 TLorentzVector target_vec(0., 0., 0., target_mass);
143 Double_t beam_energy = Data->
GetEnergy();
158 Double_t beam_energy_new = 0.0;
167 Double_t reac_posz = 0.0;
169 reac_posz = reac_distance * TMath::Cos(Data->
GetTrack().GetA()) * TMath::Cos(Data->
GetTrack().GetB());
171 Double_t reac_posx = Data->
GetTrack().GetX(reac_posz);
172 Double_t reac_posy = Data->
GetTrack().GetY(reac_posz);
177 Double_t duration_beam = 0.0;
179 duration_beam += reac_distance / (TMath::Sqrt(1.0 - TMath::Power(beam_mass / beam_vec.E(), 2.0)) *
c);
182 DoubleVec_t reac_masses;
183 for (Int_t iPart = 0; iPart <
fDecayNum; iPart++) {
186 reac_masses.emplace_back(mass);
189 TLorentzVector compound_vec = beam_vec + target_vec;
192 TVector3 beta_vec = compound_vec.BoostVector();
193 beam_vec.Boost(-beta_vec);
194 target_vec.Boost(-beta_vec);
195 Double_t energy_cm = (beam_vec.E() - beam_vec.M()) + (target_vec.E() - target_mass);
198 compound_vec *= 0.001;
200 for (
decltype(reac_masses.size()) i = 0; i < reac_masses.size(); i++) {
201 GeVMass.emplace_back(reac_masses[i] * 0.001);
204 Bool_t isOkay =
event.SetDecay(compound_vec,
fDecayNum, GeVMass.data());
206 std::cerr <<
"forbidden kinematics" << std::endl;
210 Double_t theta_cm = 0.0;
211 for (Int_t iPart = 0; iPart <
fDecayNum; ++iPart) {
212 TLorentzVector reac_vec = *
event.GetDecay(iPart);
217 outData->SetID(iPart);
221 outData->
SetTrack(reac_posx, reac_posy, reac_posz, TMath::ATan(reac_vec.Px() / reac_vec.Pz()),
222 TMath::ATan(reac_vec.Py() / reac_vec.Pz()));
225 outData->
SetEnergy(reac_vec.E() - reac_masses[iPart]);
228 outData->
AddTime(duration_beam);
231 Double_t first_energy = reac_vec.E() - reac_masses[iPart];
232 if (first_energy > 0.01) {
234 if (out_thickness < 0.0) {
237 TLorentzVector out_vec =
242 outData->
SetEnergy(out_vec.E() - reac_masses[iPart]);
255 reac_vec.Boost(-beta_vec);
264 outReacData->SetID(0);
268 outReacData->
SetXYZ(reac_posx, reac_posy, reac_posz);
276 auto get_range = [&](Double_t e) {
285 auto dedx = [&](Double_t e) {
286 const Double_t h = 0.1;
287 Double_t dxde = (get_range(e + h) - get_range(e)) / h;
291 auto gr_density_func =
new TGraph();
293 Double_t xmin = 0.0, xmax = 0.0;
294 Bool_t is_exist = std::filesystem::exists(
fCSDataPath.Data());
296 Info(
"Init",
"no input cross section file, use uniform energy distribution");
297 for (
auto e = 0.0; e <
fBeamEnergy * 1.5; e += 0.5) {
298 Double_t range = get_range(e);
299 gr_density_func->SetPoint(index, range, dedx(e));
308 Info(
"Init",
"get cross section file: %s",
fCSDataPath.Data());
309 Double_t ene_factor = 0.0;
318 SetStateError(
"CrossSectionType should be 0, 1 or 2");
323 std::regex commentRegex(
"#.*");
324 while (std::getline(fin, line)) {
325 if (line.empty() || line[0] ==
'#') {
328 line = std::regex_replace(line, commentRegex,
"");
330 std::vector<TString> values;
331 TString line_copy = line;
332 while (line_copy.Contains(
' ')) {
333 Int_t index = line_copy.First(
' ');
334 TString line_val, line_remain;
335 line_val = line_copy(0, index);
336 line_remain = line_copy(index + 1, line_copy.Length());
337 line_copy = line_remain;
338 if (line_val ==
"") {
341 values.emplace_back(line_val);
343 Double_t e = ene_factor * values[0].Atof();
344 Double_t cs = values[1].Atof() / ene_factor;
345 Double_t range = get_range(e);
346 gr_density_func->SetPoint(index, range, cs * dedx(e));
355 auto f =
new TF1(
"f", [&](
double *x,
double *p) {
return p[0] * gr_density_func->Eval(x[0],
nullptr,
"S"); }, xmin, xmax, 1);
356 f->SetParameter(0, 1.0);
358 Info(
"Init",
"suppressing the error message in this initialization process");
359 Info(
"Init",
"please wait for a moment...");
362 __attribute__((unused))
auto *_dev_null = std::freopen(
"/dev/null",
"w", stderr);
364 Double_t x_step = (xmax - xmin) / 1000.0;
365 for (
auto x = xmin; x < xmax; x += x_step) {
370 __attribute__((unused))
auto *_dev_tty = std::freopen(
"/dev/tty",
"w", stderr);
372 Info(
"Init",
"total cross section (arbitrary unit or mb)");
393 ((vec.E() - eloss) * (vec.E() - eloss) - vec.M() * vec.M()) / (vec.E() * vec.E() - vec.M() * vec.M());
394 factor = TMath::Sqrt(factor);
395 TLorentzVector new_vec(factor * vec.Px(), factor * vec.Py(), factor * vec.Pz(), vec.E() - eloss);
ClassImp(TNBodyReactionProcessor)
particle information class
TString fOutputReacColName
Double_t fTargetThickness
TGraph * gr_generating_func
IntVec_t fBeamNucleus
used only initialization at TSrim object
~TNBodyReactionProcessor() override
TLorentzVector GetLossEnergyVector(TLorentzVector vec, Double_t eloss)
void InitGeneratingFunc(void)
TClonesArray * fOutReacData
Double_t GetRandomReactionDistance(Double_t range)
void Init(TEventCollection *col) override
TGraph * gr_generating_func_inv
void SetTrack(Double_t x, Double_t y, Double_t z, Double_t a, Double_t b)
void SetMassNumber(Int_t val)
TLorentzVector GetLorentzVector() const
void SetLorentzVector(Double_t x, Double_t y, Double_t z, Double_t t)
void SetThetaCM(Double_t val)
void SetCurrentZ(Double_t val)
void SetPhiCM(Double_t val)
void AddTime(Double_t val)
Double_t GetEnergy() const
void SetCharge(Int_t val)
void SetAtomicNumber(Int_t val)
void SetEnergy(Double_t val)