20#include "InitUtils.hpp"
22#include <TDirectory.h>
29#include <TSystemDirectory.h>
39#ifndef MUSIC_TALYS_BIN
40#define MUSIC_TALYS_BIN ""
47const Double_t kEcmStep = 0.25;
48const Double_t kEcmMargin = 1.0;
52TGraph *ReadResidual(
const TString &path, Double_t cm_per_lab) {
53 std::ifstream in(path.Data());
56 std::vector<Double_t> e, xs;
58 while (std::getline(in, line)) {
59 if (line.empty() || line[0] ==
'#')
61 std::istringstream ss(line);
62 Double_t el = 0.0, s = 0.0;
65 e.push_back(el * cm_per_lab);
70 return new TGraph(Int_t(e.size()), &e[0], &xs[0]);
75Int_t RunModel(
const TalysModel &model,
const TString &work,
76 const TString &talys,
const TString &energies,
77 Double_t cm_per_lab, TDirectory *dir) {
79 gSystem->mkdir(work, kTRUE);
83 input +=
"projectile a\n";
85 input += Form(
"mass %d\n", X.
BEAM_A);
86 input +=
"energy energies\n";
87 for (Int_t k = 0; k < Int_t(model.
keywords.size()); k++)
90 std::ofstream en((work +
"/energies").Data());
92 std::ofstream inp((work +
"/talys.inp").Data());
95 for (Int_t k = 0; k < Int_t(model.
keywords.size()); k++)
96 std::cout <<
" " << model.
keywords[k] << std::endl;
97 const TString cmd = Form(
"cd '%s' && '%s' < talys.inp > talys.out 2>&1",
98 work.Data(), talys.Data());
99 if (std::system(cmd.Data()) != 0) {
100 std::cerr <<
"talys-xs: TALYS failed; see " << work <<
"/talys.out"
106 TNamed(
"label", model.
label.Data()).Write();
107 TNamed(
"input", input.Data()).Write();
109 TSystemDirectory sd(
"work", work);
110 TList *files = sd.GetListOfFiles();
111 for (TIter it(files); TObject *o = it();) {
112 const TString name = o->GetName();
114 if (!name.EndsWith(
".tot") || sscanf(name.Data(),
"rp%3d%3d", &z, &a) != 2)
116 TGraph *g = ReadResidual(work +
"/" + name, cm_per_lab);
119 g->SetName(Form(
"rp%03d%03d", z, a));
120 g->SetTitle(Form(
"Z=%d A=%d residual production;E_{c.m.} [MeV];#sigma "
134 InitUtils::SetROOTPreferences(PlotSaveFormat::kPNG,
140 std::cerr <<
"talys-xs: this dataset's CROSS_SECTION_CONFIG needs BEAM_A, "
141 "BEAM_Z, BEAM_ELEMENT, BEAM_SIM_FILE and at least one "
146 const Char_t *env = gSystem->Getenv(
"TALYS_BIN");
147 TString talys = (env && env[0] !=
'\0') ? TString(env) :
MUSIC_TALYS_BIN;
155 Double_t e_strip0 = 0.0;
157 std::cerr <<
"talys-xs: cannot read the simulated beam at "
164 const Double_t lab_per_cm =
169 Double_t e_lo = TMath::Max(
175 for (Int_t c = 0; c < Int_t(X.
CHANNELS.size()); c++)
176 for (Int_t k = 0; k < Int_t(X.
CHANNELS[c].reference_xs.size()); k++) {
177 e_lo = TMath::Min(e_lo, X.
CHANNELS[c].reference_xs[k][0] - kEcmMargin);
178 e_hi = TMath::Max(e_hi, X.
CHANNELS[c].reference_xs[k][0] + kEcmMargin);
180 const Double_t ecm_lo =
181 kEcmStep * std::floor(TMath::Max(kEcmStep, e_lo) / kEcmStep);
182 const Double_t ecm_hi = kEcmStep * std::ceil(e_hi / kEcmStep);
184 for (Double_t ecm = ecm_lo; ecm <= ecm_hi + 1.0e-9; ecm += kEcmStep)
185 energies += Form(
"%.4f\n", ecm * lab_per_cm);
190 const TString out_path = talys_dir +
"/talys_xs.root";
191 gSystem->mkdir(talys_dir, kTRUE);
192 TFile out(out_path,
"RECREATE");
193 if (out.IsZombie()) {
194 std::cerr <<
"talys-xs: cannot write " << out_path << std::endl;
197 TNamed(
"talys", talys.Data()).Write();
199 << ecm_lo <<
".." << ecm_hi <<
" MeV (strips " << X.
XS_STRIP_MIN
201 <<
" model(s), " << talys << std::endl;
202 for (Int_t m = 0; m < Int_t(X.
TALYS_MODELS.size()); m++) {
204 std::cout <<
" m" << m <<
": " << model.
label << std::endl;
205 TDirectory *dir = out.mkdir(Form(
"m%d", m));
206 const Int_t n = RunModel(model, talys_dir + Form(
"/work/m%d", m), talys,
207 energies, 1.0 / lab_per_cm, dir);
210 std::cerr <<
"talys-xs: no residual-production files for "
211 << model.
label << std::endl;
214 std::cout <<
" " << n <<
" residual channels" << std::endl;
217 std::cout <<
"talys-xs: -> " << out_path << std::endl;
The dataset configuration, and how it is layered.
Int_t TargetGasA(TargetGas gas)
Mass number of the target nucleus in a fill gas.
static TString DatasetName()
The dataset's isotope name, e.g.
static TString ResultsDir()
Absolute path to the directory receiving generated output.
Double_t LabAtStrip(const Double_t *dE, Double_t e_strip0, Int_t reac)
Lab energy entering a given strip.
Bool_t Profile(const TString &path, Double_t *dE, Double_t &e_strip0)
Read the per-strip energy loss profile from a beam simulation.
Double_t CmFraction()
Centre-of-mass energy fraction for this dataset's reaction.
TString SimPath()
Path to the dataset's beam simulation file.
const DatasetConfig & cfg
The active dataset's configuration, flat block.
What the cross section needs about the experiment rather than the analysis.
Int_t XS_STRIP_MIN
Reaction strips to report a cross section for.
TString BEAM_SIM_FILE
Simulated unreacted beam, read for the energy at each strip.
Int_t BEAM_A
Beam mass number, for the lab-to-centre-of-mass conversion; its Z and element symbol name it to a rea...
std::vector< TalysModel > TALYS_MODELS
Hauser-Feshbach predictions from TALYS.
std::vector< CrossSectionChannel > CHANNELS
The reaction channels measured on this dataset.
One TALYS model variant to compare against.
TString label
Legend label for this model's curve.
std::vector< TString > keywords
TALYS keywords selecting the variant.