Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SmashWrapper.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file SmashWrapper.cc
1 /*******************************************************************************
2  * Copyright (c) The JETSCAPE Collaboration, 2018
3  *
4  * Modular, task-based framework for simulating all aspects of heavy-ion collisions
5  *
6  * For the list of contributors see AUTHORS.
7  *
8  * Report issues at https://github.com/JETSCAPE/JETSCAPE/issues
9  *
10  * or via email to bugs.jetscape@gmail.com
11  *
12  * Distributed under the GNU General Public License 3.0 (GPLv3 or later).
13  * See COPYING for details.
14  ******************************************************************************/
15 // -----------------------------------------
16 // This is a wrapper for SMASH hadronic afterburner with the JETSCAPE framework
17 // -----------------------------------------
18 
19 #include "SmashWrapper.h"
20 
21 #include "smash/particles.h"
22 #include "smash/library.h"
23 
24 #include <string>
25 #include <filesystem>
26 
27 using namespace Jetscape;
28 
29 // Register the module with the base class
31 
33 
35  JSINFO << "SMASH: picking SMASH-specific configuration from xml file";
36  std::string smash_config_file =
37  GetXMLElementText({"Afterburner", "SMASH", "SMASH_config_file"});
38  std::string smash_hadron_list =
39  GetXMLElementText({"Afterburner", "SMASH", "SMASH_particles_file"});
40  std::string smash_decays_list =
41  GetXMLElementText({"Afterburner", "SMASH", "SMASH_decaymodes_file"});
42 
43  // do not store tabulation, which is achieved by an empty tabulations path
44  std::string tabulations_path("");
45 
46  auto config = smash::setup_config_and_logging(smash_config_file,
47  smash_hadron_list,
48  smash_decays_list);
49 
50  // Take care of the random seed. This will make SMASH results reproducible.
51  auto random_seed = (*GetMt19937Generator())();
52  config.set_value({"General","Randomseed"}, random_seed);
53 
54  // Read in the rest of configuration
55  end_time_ = GetXMLElementDouble({"Afterburner", "SMASH", "end_time"});
56  config.set_value({"General","End_Time"}, end_time_);
57 
58  JSINFO << "End time until which SMASH propagates is " << end_time_ << " fm/c";
59  only_final_decays_ =
60  GetXMLElementInt({"Afterburner", "SMASH", "only_decays"});
61  if (only_final_decays_) {
62  JSINFO << "SMASH will only perform resonance decays, no propagation";
63  }
64 
65  const std::string smash_version(SMASH_VERSION);
66  smash::initialize_particles_decays_and_tabulations(config, smash_version,
67  tabulations_path);
68 
69  JSINFO << "Seting up SMASH Experiment object";
70  // output path is just dummy here, because no output from SMASH is foreseen
71  std::filesystem::path output_path("./smash_output");
72  smash_experiment_ =
73  make_shared<smash::Experiment<AfterburnerModus>>(config, output_path);
74  JSINFO << "Finish initializing SMASH";
75 }
76 
78  AfterburnerModus *modus = smash_experiment_->modus();
79  // This is necessary to correctly handle indices of particle sets from hydro.
80  // Every hydro event creates a new structure like jetscape_hadrons_
81  // with as many events in it as one has samples per hydro
82  modus->reset_event_numbering();
83  modus->jetscape_hadrons_ = GatherAfterburnerHadrons();
84  const int n_events = modus->jetscape_hadrons_.size();
85  JSINFO << "SMASH: obtained " << n_events << " events from particlization";
86  // SMASH within JETSCAPE only works with one (the first) ensemble
87  smash::Particles *smash_particles = smash_experiment_->first_ensemble();
88  for (unsigned int i = 0; i < n_events; i++) {
89  JSINFO << "Event " << i << " SMASH starts with "
90  << modus->jetscape_hadrons_[i].size() << " particles.";
91  smash_experiment_->initialize_new_event();
92  if (!only_final_decays_) {
93  smash_experiment_->run_time_evolution(end_time_);
94  }
95  smash_experiment_->do_final_decays();
96  smash_experiment_->final_output();
97  smash_particles_to_JS_hadrons(*smash_particles,
98  modus->jetscape_hadrons_[i]);
99  JSINFO << modus->jetscape_hadrons_[i].size() << " hadrons from SMASH.";
100  smash_experiment_->increase_event_number();
101  }
102 }
103 
104 void SmashWrapper::WriteTask(weak_ptr<JetScapeWriter> w) {
105  JSINFO << "SMASH hadronic afterburner printout";
106  auto f = w.lock();
107  if (!f) {
108  return;
109  }
110  AfterburnerModus *modus = smash_experiment_->modus();
111  f->WriteComment("JetScape module: " + GetId());
112  for (const auto &event : modus->jetscape_hadrons_) {
113  int i = -1;
114  for (const auto hadron : event) {
115  f->WriteWhiteSpace("[" + to_string(++i) + "] H");
116  f->Write(hadron);
117  }
118  }
119 }
120 
122  const std::vector<shared_ptr<Hadron>> &JS_hadrons,
123  smash::Particles &smash_particles) {
124  smash_particles.reset();
125  for (const auto JS_hadron : JS_hadrons) {
126  const FourVector p = JS_hadron->p_in();
127  const FourVector r = JS_hadron->x_in();
128  const double mass = JS_hadron->restmass();
129  smash::PdgCode pdgcode = smash::PdgCode::from_decimal(JS_hadron->pid());
130  this->try_create_particle(smash_particles, pdgcode, r.t(), r.x(), r.y(),
131  r.z(), mass, JS_hadron->e(), JS_hadron->px(),
132  JS_hadron->py(), JS_hadron->pz());
133  }
134 }
135 
137  const smash::Particles &smash_particles,
138  std::vector<shared_ptr<Hadron>> &JS_hadrons) {
139  JS_hadrons.clear();
140  for (const auto &particle : smash_particles) {
141  const int hadron_label = 0;
142  const int hadron_status = 27;
143  const int hadron_id = particle.pdgcode().get_decimal();
144  smash::FourVector p = particle.momentum(), r = particle.position();
145  const FourVector hadron_p(p.x1(), p.x2(), p.x3(), p.x0()),
146  hadron_r(r.x1(), r.x2(), r.x3(), r.x0());
147  const double hadron_mass = p.abs();
148  JS_hadrons.push_back(make_shared<Hadron>(hadron_label, hadron_id,
149  hadron_status, hadron_p, hadron_r,
150  hadron_mass));
151  }
152 }