Version: SMASH-1.5
rootoutput.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (c) 2014-2018
4  * SMASH Team
5  *
6  * GNU General Public License (GPLv3 or later)
7  *
8  */
9 
10 #include "smash/rootoutput.h"
11 #include "TFile.h"
12 #include "TTree.h"
13 #include "smash/action.h"
14 #include "smash/clock.h"
16 #include "smash/particles.h"
17 
18 namespace smash {
19 
79 RootOutput::RootOutput(const bf::path &path, const std::string &name,
80  const OutputParameters &out_par)
81  : OutputInterface(name),
82  filename_(path / (name + ".root")),
83  write_collisions_(name == "Collisions" || name == "Dileptons" ||
84  name == "Photons"),
85  write_particles_(name == "Particles"),
86  particles_only_final_(out_par.part_only_final),
87  autosave_frequency_(1000) {
88  const auto &log = logger<LogArea::Output>();
89  if (out_par.part_extended || out_par.coll_extended) {
90  log.warn() << "Creating Root output: There is no extended Root format.";
91  }
93  filename_unfinished_ += ".unfinished";
95  make_unique<TFile>(filename_unfinished_.native().c_str(), "NEW");
96  init_trees();
97 }
98 
100  if (write_particles_) {
101  particles_tree_ = new TTree("particles", "particles");
102 
103  particles_tree_->Branch("npart", &npart, "npart/I");
104  particles_tree_->Branch("impact_b", &impact_b, "impact_b/D");
105  particles_tree_->Branch("ev", &ev, "ev/I");
106  particles_tree_->Branch("tcounter", &tcounter, "tcounter/I");
107 
108  particles_tree_->Branch("pdgcode", &pdgcode[0], "pdgcode[npart]/I");
109 
110  particles_tree_->Branch("p0", &p0[0], "p0[npart]/D");
111  particles_tree_->Branch("px", &px[0], "px[npart]/D");
112  particles_tree_->Branch("py", &py[0], "py[npart]/D");
113  particles_tree_->Branch("pz", &pz[0], "pz[npart]/D");
114 
115  particles_tree_->Branch("t", &t[0], "t[npart]/D");
116  particles_tree_->Branch("x", &x[0], "x[npart]/D");
117  particles_tree_->Branch("y", &y[0], "y[npart]/D");
118  particles_tree_->Branch("z", &z[0], "z[npart]/D");
119  }
120 
121  if (write_collisions_) {
122  collisions_tree_ = new TTree("collisions", "collisions");
123 
124  collisions_tree_->Branch("nin", &nin, "nin/I");
125  collisions_tree_->Branch("nout", &nout, "nout/I");
126  collisions_tree_->Branch("npart", &npart, "npart/I");
127  collisions_tree_->Branch("ev", &ev, "ev/I");
128  collisions_tree_->Branch("weight", &wgt, "weight/D");
129  collisions_tree_->Branch("partial_weight", &par_wgt, "partial_weight/D");
130 
131  collisions_tree_->Branch("pdgcode", &pdgcode[0], "pdgcode[npart]/I");
132 
133  collisions_tree_->Branch("p0", &p0[0], "p0[npart]/D");
134  collisions_tree_->Branch("px", &px[0], "px[npart]/D");
135  collisions_tree_->Branch("py", &py[0], "py[npart]/D");
136  collisions_tree_->Branch("pz", &pz[0], "pz[npart]/D");
137 
138  collisions_tree_->Branch("t", &t[0], "t[npart]/D");
139  collisions_tree_->Branch("x", &x[0], "x[npart]/D");
140  collisions_tree_->Branch("y", &y[0], "y[npart]/D");
141  collisions_tree_->Branch("z", &z[0], "z[npart]/D");
142  }
143 }
144 
150  // kOverwrite option prevents from writing extra TKey objects into root file
151  root_out_file_->Write("", TObject::kOverwrite);
152  root_out_file_->Close();
153  bf::rename(filename_unfinished_, filename_);
154 }
155 
156 void RootOutput::at_eventstart(const Particles &particles,
157  const int event_number) {
158  // save event number
159  current_event_ = event_number;
160 
162  output_counter_ = 0;
163  // This is to have only one output of positive impact parameter per event
164  impact_b = -1.0;
165  particles_to_tree(particles);
166  output_counter_++;
167  }
168 }
169 
170 void RootOutput::at_intermediate_time(const Particles &particles, const Clock &,
171  const DensityParameters &) {
173  particles_to_tree(particles);
174  output_counter_++;
175  }
176 }
177 
178 void RootOutput::at_eventend(const Particles &particles,
179  const int /*event_number*/,
180  double impact_parameter) {
181  impact_b = impact_parameter;
182  if (write_particles_) {
183  particles_to_tree(particles);
184  }
185  /* Forced regular dump from operational memory to disk. Very demanding!
186  * If program crashes written data will NOT be lost. */
188  if (write_particles_) {
189  particles_tree_->AutoSave("SaveSelf");
190  }
191  if (write_collisions_) {
192  collisions_tree_->AutoSave("SaveSelf");
193  }
194  }
195 }
196 
198  const double /*density*/) {
199  if (write_collisions_) {
201  action.get_total_weight(), action.get_partial_weight());
202  }
203 }
204 
205 void RootOutput::particles_to_tree(const Particles &particles) {
206  int i = 0;
207 
209  ev = current_event_;
210 
211  for (const auto &p : particles) {
212  // Buffer full - flush to tree, else fill with particles
213  if (i >= max_buffer_size_) {
215  i = 0;
216  particles_tree_->Fill();
217  } else {
218  t[i] = p.position().x0();
219  x[i] = p.position().x1();
220  y[i] = p.position().x2();
221  z[i] = p.position().x3();
222 
223  p0[i] = p.momentum().x0();
224  px[i] = p.momentum().x1();
225  py[i] = p.momentum().x2();
226  pz[i] = p.momentum().x3();
227 
228  pdgcode[i] = p.pdgcode().get_decimal();
229 
230  i++;
231  }
232  }
233  // Flush rest to tree
234  if (i > 0) {
235  npart = i;
236  particles_tree_->Fill();
237  }
238 }
239 
240 void RootOutput::collisions_to_tree(const ParticleList &incoming,
241  const ParticleList &outgoing,
242  const double weight,
243  const double partial_weight) {
244  ev = current_event_;
245  nin = incoming.size();
246  nout = outgoing.size();
247  npart = nin + nout;
248  wgt = weight;
249  par_wgt = partial_weight;
250 
251  int i = 0;
252 
253  /* It is assumed that nin + nout < max_buffer_size_
254  * This is true for any possible reaction for current buffer size: 10000
255  * But if one wants initial/final particles written to collisions
256  * then implementation should be updated. */
257 
258  for (const auto &p : incoming) {
259  t[i] = p.position().x0();
260  x[i] = p.position().x1();
261  y[i] = p.position().x2();
262  z[i] = p.position().x3();
263 
264  p0[i] = p.momentum().x0();
265  px[i] = p.momentum().x1();
266  py[i] = p.momentum().x2();
267  pz[i] = p.momentum().x3();
268 
269  pdgcode[i] = p.pdgcode().get_decimal();
270 
271  i++;
272  }
273 
274  for (const auto &p : outgoing) {
275  t[i] = p.position().x0();
276  x[i] = p.position().x1();
277  y[i] = p.position().x2();
278  z[i] = p.position().x3();
279 
280  p0[i] = p.momentum().x0();
281  px[i] = p.momentum().x1();
282  py[i] = p.momentum().x2();
283  pz[i] = p.momentum().x3();
284 
285  pdgcode[i] = p.pdgcode().get_decimal();
286 
287  i++;
288  }
289 
290  collisions_tree_->Fill();
291 }
292 } // namespace smash
const bf::path filename_
Filename of output.
Definition: rootoutput.h:144
A class to pre-calculate and store parameters relevant for density calculation.
Definition: density.h:103
int nout
Buffer for filling TTree. See class documentation for definitions.
Definition: rootoutput.h:190
int current_event_
Number of current event.
Definition: rootoutput.h:181
~RootOutput()
Destructor.
Definition: rootoutput.cc:149
bool write_particles_
Option to write particles tree.
Definition: rootoutput.h:198
std::array< double, max_buffer_size_ > py
Buffer for filling TTree. See class documentation for definitions.
Definition: rootoutput.h:188
std::unique_ptr< TFile > root_out_file_
Pointer to root output file.
Definition: rootoutput.h:148
void at_eventstart(const Particles &particles, const int event_number) override
update event number and writes intermediate particles to a tree.
Definition: rootoutput.cc:156
bool part_extended
Extended format for particles output.
std::array< double, max_buffer_size_ > x
Buffer for filling TTree. See class documentation for definitions.
Definition: rootoutput.h:188
int npart
Buffer for filling TTree. See class documentation for definitions.
Definition: rootoutput.h:190
std::array< double, max_buffer_size_ > p0
Buffer for filling TTree. See class documentation for definitions.
Definition: rootoutput.h:188
virtual double get_partial_weight() const =0
Return the specific weight for the chosen outgoing channel, which is mainly used for the partial weig...
TTree * particles_tree_
TTree for particles output.
Definition: rootoutput.h:155
void init_trees()
Basic initialization routine, creating the TTree objects for particles and collisions.
Definition: rootoutput.cc:99
int nin
Buffer for filling TTree. See class documentation for definitions.
Definition: rootoutput.h:190
void at_eventend(const Particles &particles, const int event_number, double impact_parameter) override
update event number and impact parameter, and writes intermediate particles to a tree.
Definition: rootoutput.cc:178
void at_intermediate_time(const Particles &particles, const Clock &clock, const DensityParameters &dens_param) override
Writes intermediate particles to a tree defined by treename, if it is allowed (i.e., particles_only_final_ is false).
Definition: rootoutput.cc:170
void collisions_to_tree(const ParticleList &incoming, const ParticleList &outgoing, const double weight, const double partial_weight)
Writes collisions to a tree defined by treename.
Definition: rootoutput.cc:240
const ParticleList & outgoing_particles() const
Get the list of particles that resulted from the action.
Definition: action.h:244
std::array< double, max_buffer_size_ > t
Buffer for filling TTree. See class documentation for definitions.
Definition: rootoutput.h:188
RootOutput(const bf::path &path, const std::string &name, const OutputParameters &out_par)
Construct ROOT output.
Definition: rootoutput.cc:79
const ParticleList & incoming_particles() const
Get the list of particles that go into the action.
Definition: action.cc:58
int output_counter_
Number of output in a given event.
Definition: rootoutput.h:179
bool coll_extended
Extended format for collisions output.
std::array< double, max_buffer_size_ > z
Buffer for filling TTree. See class documentation for definitions.
Definition: rootoutput.h:188
Helper structure for Experiment to hold output options and parameters.
Clock tracks the time in the simulation.
Definition: clock.h:75
Action is the base class for a generic process that takes a number of incoming particles and transfor...
Definition: action.h:34
virtual double get_total_weight() const =0
Return the total weight value, which is mainly used for the weight output entry.
std::array< double, max_buffer_size_ > y
Buffer for filling TTree. See class documentation for definitions.
Definition: rootoutput.h:188
bool write_collisions_
Option to write collisions tree.
Definition: rootoutput.h:195
std::array< double, max_buffer_size_ > px
Buffer for filling TTree. See class documentation for definitions.
Definition: rootoutput.h:188
double wgt
Buffer for filling TTree. See class documentation for definitions.
Definition: rootoutput.h:191
bf::path filename_unfinished_
Filename of output as long as simulation is still running.
Definition: rootoutput.h:146
void at_interaction(const Action &action, const double density) override
Writes collisions to a tree defined by treename.
Definition: rootoutput.cc:197
double impact_b
Buffer for filling TTree. See class documentation for definitions.
Definition: rootoutput.h:191
constexpr int p
Proton.
TTree * collisions_tree_
TTree for collision output.
Definition: rootoutput.h:162
void particles_to_tree(const Particles &particles)
Writes particles to a tree defined by treename.
Definition: rootoutput.cc:205
int tcounter
Buffer for filling TTree. See class documentation for definitions.
Definition: rootoutput.h:190
bool particles_only_final_
Print only final particles in the event, no intermediate output.
Definition: rootoutput.h:201
The Particles class abstracts the storage and manipulation of particles.
Definition: particles.h:33
int ev
Buffer for filling TTree. See class documentation for definitions.
Definition: rootoutput.h:190
std::array< double, max_buffer_size_ > pz
Buffer for filling TTree. See class documentation for definitions.
Definition: rootoutput.h:188
std::array< int, max_buffer_size_ > pdgcode
Buffer for filling TTree. See class documentation for definitions.
Definition: rootoutput.h:189
int autosave_frequency_
Root file cannot be read if it was not properly closed and finalized.
Definition: rootoutput.h:212
Abstraction of generic output.
static const int max_buffer_size_
Maximal buffer size.
Definition: rootoutput.h:184
Definition: action.h:24
double par_wgt
Buffer for filling TTree. See class documentation for definitions.
Definition: rootoutput.h:191