19 #include <boost/bind.hpp>
20 #include <boost/tokenizer.hpp>
41 typedef boost::escaped_list_separator<char> separator_type;
47 boost::tokenizer<separator_type> tokens(input,
separator);
50 std::vector<std::string> result;
51 copy_if(tokens.begin(), tokens.end(), std::back_inserter(result),
52 !boost::bind(&std::string::empty, _1));
63 JSINFO <<
" Initialzie TRENTo initial condition ";
66 using namespace trento;
67 using OptDesc = po::options_description;
68 using VecStr = std::vector<std::string>;
70 main_opts.add_options()(
75 [](
const VecStr &projectiles) {
76 if (projectiles.size() != 2)
77 throw po::required_option{
"projectile"};
79 "projectile symbols")(
"number-events", po::value<int>()->default_value(1),
83 po::positional_options_description positional_opts{};
84 positional_opts.add(
"projectile", 2).add(
"number-events", 1);
86 using VecPath = std::vector<fs::path>;
87 OptDesc general_opts{
"general options"};
88 general_opts.add_options()(
"help,h",
"show this help message and exit")(
89 "version",
"print version information and exit")(
90 "bibtex",
"print bibtex entry and exit")
92 (
"config-file,c", po::value<VecPath>()->value_name(
"FILE"),
93 "configuration file\n(can be passed multiple times)");
95 OptDesc output_opts{
"output options"};
96 output_opts.add_options()(
"quiet,q", po::bool_switch(),
97 "do not print event properties to stdout")(
98 "output,o", po::value<fs::path>()->value_name(
"PATH"),
99 "HDF5 file or directory for text files")(
100 "no-header", po::bool_switch(),
"do not write headers to text files");
102 OptDesc phys_opts{
"physical options"};
103 phys_opts.add_options()(
104 "reduced-thickness,p",
105 po::value<double>()->value_name(
"FLOAT")->default_value(0.,
"0"),
106 "reduced thickness parameter")(
108 po::value<double>()->value_name(
"FLOAT")->default_value(1.,
"1"),
109 "gamma fluctuation shape parameter")(
111 po::value<double>()->value_name(
"FLOAT")->default_value(.5,
"0.5"),
112 "Gaussian nucleon width [fm]")(
113 "nucleon-min-dist,d",
114 po::value<double>()->value_name(
"FLOAT")->default_value(0.,
"0"),
115 "minimum nucleon-nucleon distance [fm]")(
117 po::value<double>()->value_name(
"FLOAT")->default_value(1.,
"1."),
118 "rapidity mean coefficient")(
120 po::value<double>()->value_name(
"FLOAT")->default_value(3.,
"3."),
121 "rapidity std coefficient")(
123 po::value<double>()->value_name(
"FLOAT")->default_value(0.,
"0."),
124 "rapidity skew coefficient")(
125 "skew-type,r", po::value<int>()->value_name(
"INT")->default_value(1,
"1"),
126 "rapidity skew type: 1: relative, 2: absolute, other: no skew")(
128 po::value<double>()->value_name(
"FLOAT")->default_value(0.8,
"0.8"),
129 "<pt>/<mt> used in Jacobian")(
131 po::value<double>()->value_name(
"FLOAT")->default_value(1.,
"1"),
132 "normalization factor");
134 OptDesc coll_opts{
"collision options"};
135 coll_opts.add_options()(
137 po::value<double>()->value_name(
"FLOAT")->default_value(2760,
"2760"),
138 "collision beam energy sqrt(s) [GeV], initializes cross section")(
140 po::value<double>()->value_name(
"FLOAT")->default_value(-1,
"off"),
141 "manual inelastic nucleon-nucleon cross section sigma_NN [fm^2]")(
142 "b-min", po::value<double>()->value_name(
"FLOAT")->default_value(0.,
"0"),
143 "minimum impact parameter [fm]")(
145 po::value<double>()->value_name(
"FLOAT")->default_value(-1.,
"auto"),
146 "maximum impact parameter [fm]")(
147 "npart-min", po::value<int>()->value_name(
"INT")->default_value(0,
"0"),
148 "minimum Npart cut")(
"npart-max",
149 po::value<int>()->value_name(
"INT")->default_value(
150 std::numeric_limits<int>::max(),
"INT_MAX"),
151 "maximum Npart cut")(
152 "s-min", po::value<double>()->value_name(
"FLOAT")->default_value(0.,
"0"),
153 "minimum entropy cut")(
155 po::value<double>()->value_name(
"FLOAT")->default_value(
156 std::numeric_limits<double>::max(),
"DOUBLE_MAX"),
157 "maxmimum entropy cut")(
159 po::value<int64_t>()->value_name(
"INT")->default_value(-1,
"auto"),
161 "ncoll,b", po::bool_switch(),
162 "calculate # of binary collision and binary collision density");
164 OptDesc grid_opts{
"grid options"};
165 grid_opts.add_options()(
167 po::value<double>()->value_name(
"FLOAT")->default_value(10.,
"10.0"),
168 "xy max [fm]\n(transverse grid from -max to +max)")(
170 po::value<double>()->value_name(
"FLOAT")->default_value(0.2,
"0.2"),
171 "transverse step size [fm]")(
173 po::value<double>()->value_name(
"FLOAT")->default_value(0.0,
"0.0"),
174 "pseudorapidity max \n(eta grid from -max to +max)")(
176 po::value<double>()->value_name(
"FLOAT")->default_value(0.5,
"0.5"),
177 "pseudorapidity step size");
182 usage_opts.add(general_opts)
190 all_opts.add(usage_opts).add(main_opts);
194 "usage: trento [options] projectile projectile [number-events = 1]\n"};
196 "To operate in 3D mode, make sure --eta-max is nonzero.\n"};
199 auto phy_opts =
GetXMLElement({
"IS",
"Trento",
"PhysicsInputs"});
200 auto cut_opts =
GetXMLElement({
"IS",
"Trento",
"CutInputs"});
201 auto trans_opts =
GetXMLElement({
"IS",
"Trento",
"TransInputs"});
202 auto longi_opts =
GetXMLElement({
"IS",
"Trento",
"LongiInputs"});
211 JSINFO <<
"Random seed used for Trento " << random_seed;
215 double sqrts = std::atof(phy_opts->Attribute(
"sqrts"));
216 double cross_section = std::atof(phy_opts->Attribute(
"cross-section"));
217 double normalization = std::atof(phy_opts->Attribute(
"normalization"));
219 int cen_low = std::atoi(cut_opts->Attribute(
"centrality-low"));
220 int cen_high = std::atoi(cut_opts->Attribute(
"centrality-high"));
222 double p = std::atof(trans_opts->Attribute(
"reduced-thickness"));
223 double k = std::atof(trans_opts->Attribute(
"fluctuation"));
224 double w = std::atof(trans_opts->Attribute(
"nucleon-width"));
225 double d = std::atof(trans_opts->Attribute(
"nucleon-min-dist"));
227 double mean = std::atof(longi_opts->Attribute(
"mean-coeff"));
228 double var = std::atof(longi_opts->Attribute(
"std-coeff"));
229 double skew = std::atof(longi_opts->Attribute(
"skew-coeff"));
230 int skew_type = std::atof(longi_opts->Attribute(
"skew-type"));
231 double J = std::atof(longi_opts->Attribute(
"jacobian"));
234 +
" --random-seed " +
std::to_string(random_seed) +
" --cross-section " +
252 po::store(po::command_line_parser(tokenize(cmd_basic))
254 .positional(positional_opts)
259 if (cen_low == 0 && cen_high == 100) {
260 JSINFO <<
"TRENTo Minimum Biased Mode Generates 0-100(%) of nuclear "
261 "inelastic cross-section";
263 auto Ecut =
GenCenTab(
proj, targ, var_map_basic, cen_low, cen_high);
264 double Ehigh = Ecut.first * normalization;
265 double Elow = Ecut.second * normalization;
267 JSINFO <<
"The total energy density cut for centrality = [" << cen_low
268 <<
", " << cen_high <<
"] (%) is:";
269 JSINFO << Elow <<
"<dE/deta(eta=0)<" << Ehigh;
275 proj +
" " + targ +
" 1 " + options1 + options2 + options_cut;
280 .positional(positional_opts)
283 TrentoGen_ = std::make_shared<trento::Collider>(var_map);
298 if (cL < 0 || cL > 100 || cH < 0 || cH > 100 || cH < cL) {
299 JSWARN <<
"Wrong centrality cuts! To be terminated.";
306 double beamE = var_map[
"beam-energy"].as<
double>();
307 double xsection = var_map[
"cross-section"].as<
double>();
308 double pvalue = var_map[
"reduced-thickness"].as<
double>();
309 double fluct = var_map[
"fluctuation"].as<
double>();
310 double nuclw = var_map[
"nucleon-width"].as<
double>();
311 double dmin = var_map[
"nucleon-min-dist"].as<
double>();
313 std::sprintf(buffer,
"%s-%s-E-%1.0f-X-%1.2f-p-%1.2f-k-%1.2f-w-%1.2f-d-%1.2f",
314 proj.c_str(), targ.c_str(), beamE, xsection, pvalue, fluct,
317 JSINFO <<
"TRENTO centrality table header: " << header;
320 std::hash<std::string> hash_function;
321 size_t header_hash = hash_function(header);
322 JSINFO <<
"Hash tag for this header: " << header_hash;
324 std::system(
"mkdir -p ./trento_data");
326 std::sprintf(filename,
"./trento_data/%zu", header_hash);
328 std::ifstream
infile(filename);
333 JSINFO <<
"The required centrality table exists. Load the table.";
335 while (std::getline(infile, line)) {
336 if (line[0] !=
'#') {
337 std::istringstream iss(line);
338 iss >> buff1 >> buff2 >> Etab[
i];
344 JSINFO <<
"TRENTo is generating new centrality table for this new "
346 JSINFO <<
"It may take 10(s) to 1(min).";
350 auto event_records = another_collider.
all_records();
353 int nstep = std::ceil(event_records.size() / 100);
354 std::ofstream
fout(filename);
355 fout <<
"#\tproj\ttarj\tsqrts\tx\tp\tk\tw\td\n"
356 <<
"#\t" << proj <<
"\t" << targ <<
"\t" << beamE <<
"\t" << xsection
357 <<
"\t" << pvalue <<
"\t" << fluct <<
"\t" << nuclw <<
"\t" << dmin
359 <<
"#\tcen_L\tcen_H\tun-normalized total density\n";
361 for (
int i = 1;
i < 100;
i += 1) {
362 auto ee = event_records[
i * nstep];
363 fout <<
i - 1 <<
"\t" <<
i <<
"\t" << ee.mult << std::endl;
366 auto ee = event_records.back();
367 fout << 99 <<
"\t" << 100 <<
"\t" << ee.mult << std::endl;
371 JSINFO <<
"#########" << Etab[cL] <<
" " << Etab[cH];
372 return std::make_pair(Etab[cL], Etab[cH]);
376 JSINFO <<
" Exec TRENTo initial condition ";
379 JSINFO <<
" TRENTo event info: ";
385 info_.
ecc = tmp_event.eccentricity();
386 info_.
psi = tmp_event.participant_plane();
388 -
GetXMax() + tmp_event.mass_center_index().first * tmp_event.dxy();
390 -
GetYMax() + tmp_event.mass_center_index().second * tmp_event.dxy();
391 JSINFO <<
"b\tnpart\tncoll\tET\t(x-com, y-com) (fm)";
396 JSINFO <<
" Load TRENTo density and ncoll density to JETSCAPE memory ";
397 auto density_field = tmp_event.density_grid();
398 auto ncoll_field = tmp_event.TAB_grid();
399 JSINFO << density_field.num_elements() <<
" density elements";
400 for (
int i = 0;
i < density_field.num_elements();
i++) {
403 JSINFO << ncoll_field.num_elements() <<
" ncoll elements";
404 for (
int i = 0;
i < ncoll_field.num_elements();
i++) {
407 JSINFO <<
" TRENTO event generated and loaded ";
411 VERBOSE(2) <<
" : Finish creating initial condition ";