All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TextFileGen_module.cc
Go to the documentation of this file.
1 /**
2  * @file TextFileGen_module.cc
3  * @brief Producer generating Monte Carlo truth record in LArSoft format from a text file
4  * @date Mon Apr 8 09:20:02 2013
5  * @author Brian Rebel
6  */
7 /**
8  * @class evgen::TextFileGen
9  *
10  * This module assumes that the input file has the hepevt format for
11  * each event to be simulated. See
12  *
13  * http://cepa.fnal.gov/psm/simulation/mcgen/lund/pythia_manual/pythia6.3/pythia6301/node39.html
14  *
15  * for details on the format. In brief each event contains at least two
16  * lines. The first line contains two entries, the event number (which is
17  * ignored in ART/LArSoft) and the number of particles in the event. Each
18  * following line containes 15 entries to describe each particle. The entries
19  * are:
20  *
21  * 1. status code (should be set to 1 for any particle to be tracked, others
22  * won't be tracked)
23  * 2. the pdg code for the particle
24  * 3. the entry of the first mother for this particle in the event,
25  * 0 means no mother
26  * 4. the entry of the second mother for this particle in the event,
27  * 0 means no mother
28  * 5. the entry of the first daughter for this particle in the event,
29  * 0 means no daughter
30  * 6. the entry of the second daughter for this particle in the event,
31  * 0 means no daughter
32  * 7. x component of the particle momentum
33  * 8. y component of the particle momentum
34  * 9. z component of the particle momentum
35  * 10. energy of the particle
36  * 11. mass of the particle
37  * 12. x position of the particle initial position
38  * 13. y position of the particle initial position
39  * 14. z position of the particle initial position
40  * 15. time of the particle production
41  *
42  * For example, if you want to simulate a single muon with a 5 GeV energy
43  * moving only in the z direction, the entry would be
44  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
45  * 0 1
46  * 1 13 0 0 0 0 0. 0. 1.0 5.0011 0.105 1.0 1.0 1.0 0.0
47  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
48  * There are some assumptions that go into using this format that may not
49  * be obvious. The first is that only particles with status code = 1
50  * are tracked in the LArSoft/Geant4 combination making the mother daughter
51  * relations somewhat irrelevant. That also means that you should let
52  * Geant4 handle any decays.
53  *
54  * The units in LArSoft are cm for distances and ns for time.
55  * The use of `TLorentzVector` below does not imply space and time have the same units
56  * (do not use `TLorentzVector::Boost()`).
57  */
58 #include <string>
59 #include <fstream>
60 #include <memory>
61 #include <utility>
62 
63 #include "art/Framework/Core/EDProducer.h"
64 #include "art/Framework/Core/ModuleMacros.h"
65 #include "art/Framework/Principal/Event.h"
66 #include "art/Framework/Principal/Run.h"
67 #include "art/Framework/Services/Registry/ServiceHandle.h"
68 #include "fhiclcpp/ParameterSet.h"
69 #include "cetlib_except/exception.h"
70 #include "messagefacility/MessageLogger/MessageLogger.h"
71 
72 #include "TLorentzVector.h"
73 
76 #include "nusimdata/SimulationBase/MCTruth.h"
77 #include "nusimdata/SimulationBase/MCParticle.h"
78 
79 namespace evgen {
80  class TextFileGen;
81 }
82 
83 class evgen::TextFileGen : public art::EDProducer {
84 public:
85  explicit TextFileGen(fhicl::ParameterSet const & p);
86 
87  void produce(art::Event & e) override;
88  void beginJob() override;
89  void beginRun(art::Run & run) override;
90 
91 private:
92 
93  std::pair<unsigned, unsigned> readEventInfo(std::istream& is);
94  simb::MCTruth readNextHepEvt();
95  unsigned long int fOffset;
96  std::ifstream* fInputFile;
97  std::string fInputFileName; ///< Name of text file containing events to simulate
98  double fMoveY; ///< Project particles to a new y plane.
99 };
100 
101 //------------------------------------------------------------------------------
102 evgen::TextFileGen::TextFileGen(fhicl::ParameterSet const & p)
103  : EDProducer{p}
104  , fOffset{p.get<unsigned long int>("Offset")}
105  , fInputFile(0)
106  , fInputFileName{p.get<std::string>("InputFileName")}
107  , fMoveY{p.get<double>("MoveY", -1e9)}
108 {
109  if (fMoveY>-1e8){
110  mf::LogWarning("TextFileGen")<<"Particles will be moved to a new plane y = "<<fMoveY<<" cm.\n";
111  }
112 
113  produces< std::vector<simb::MCTruth> >();
114  produces< sumdata::RunData, art::InRun >();
115 
116 
117 }
118 
119 //------------------------------------------------------------------------------
121 {
122  fInputFile = new std::ifstream(fInputFileName.c_str());
123 
124  // check that the file is a good one
125  if( !fInputFile->good() )
126  throw cet::exception("TextFileGen") << "input text file "
127  << fInputFileName
128  << " cannot be read.\n";
129 
130 
131  for (unsigned i = 0; i != fOffset; ++i) {
132  auto const [eventNo, nparticles] = readEventInfo(*fInputFile);
133  for (unsigned p = 0; p != nparticles; ++p) {
134  constexpr auto all_chars_until = std::numeric_limits<unsigned>::max();
135  fInputFile->ignore(all_chars_until, '\n');
136  }
137  }
138 
139 
140 }
141 
142 //------------------------------------------------------------------------------
143 void evgen::TextFileGen::beginRun(art::Run& run)
144 {
145  art::ServiceHandle<geo::Geometry const> geo;
146  run.put(std::make_unique<sumdata::RunData>(geo->DetectorName()));
147  }
148 
149 //------------------------------------------------------------------------------
150 void evgen::TextFileGen::produce(art::Event & e)
151 {
152  // check that the file is still good
153  if( !fInputFile->good() )
154  throw cet::exception("TextFileGen") << "input text file "
155  << fInputFileName
156  << " cannot be read in produce().\n";
157 
158 
159 
160 
161 //Now, read the Event to be used.
162 
163 
164 
165 // check that the file is still good
166  if( !fInputFile->good() )
167  throw cet::exception("TextFileGen") << "input text file "
168  << fInputFileName
169  << " cannot be read in produce().\n";
170  auto truthcol = std::make_unique<std::vector<simb::MCTruth>>();
171  truthcol->push_back(readNextHepEvt());
172 
173 
174  e.put(std::move(truthcol));
175 }
176 
177 
178 
179 
181 {
182 
183  // declare the variables for reading in the event record
184  int status = 0;
185  int pdg = 0;
186  int firstMother = 0;
187  int secondMother = 0;
188  int firstDaughter = 0;
189  int secondDaughter = 0;
190  double xMomentum = 0.;
191  double yMomentum = 0.;
192  double zMomentum = 0.;
193  double energy = 0.;
194  double mass = 0.;
195  double xPosition = 0.;
196  double yPosition = 0.;
197  double zPosition = 0.;
198  double time = 0.;
199 
200 
201 
202  // read in line to get event number and number of particles
203  std::string oneLine;
204  std::istringstream inputLine;
205  simb::MCTruth nextEvent;
206  auto const [eventNo, nParticles] = readEventInfo(*fInputFile);
207 
208 
209 
210  // now read in all the lines for the particles
211  // in this interaction. only particles with
212  // status = 1 get tracked in Geant4.
213  for(unsigned short i = 0; i < nParticles; ++i){
214  std::getline(*fInputFile, oneLine);
215  inputLine.clear();
216  inputLine.str(oneLine);
217 
218  inputLine >> status >> pdg
219  >> firstMother >> secondMother >> firstDaughter >> secondDaughter
220  >> xMomentum >> yMomentum >> zMomentum >> energy >> mass
221  >> xPosition >> yPosition >> zPosition >> time;
222 
223 
224 
225  //Project the particle to a new y plane
226  if (fMoveY>-1e8){
227  double totmom = sqrt(pow(xMomentum,2)+pow(yMomentum,2)+pow(zMomentum,2));
228  double kx = xMomentum/totmom;
229  double ky = yMomentum/totmom;
230  double kz = zMomentum/totmom;
231  if (ky){
232  double l = (fMoveY-yPosition)/ky;
233  xPosition += kx*l;
234  yPosition += ky*l;
235  zPosition += kz*l;
236  }
237  }
238 
239  TLorentzVector pos(xPosition, yPosition, zPosition, time);
240  TLorentzVector mom(xMomentum, yMomentum, zMomentum, energy);
241 
242  simb::MCParticle part(i, pdg, "primary", firstMother, mass, status);
243  part.AddTrajectoryPoint(pos, mom);
244 
245  nextEvent.Add(part);
246 
247  } // end loop on particles.
248 
249 return nextEvent;
250 }
251 
252 
253 
254 std::pair<unsigned, unsigned> evgen::TextFileGen::readEventInfo(std::istream& iss)
255 {
256  std::string line;
257  getline(iss, line);
258  std::istringstream buffer{line};
259 
260  // Parse read line for the event number and particles per event
261  unsigned event, nparticles;
262  buffer >> event >> nparticles;
263  return {event, nparticles};
264 }
265 
266 
267 
268 
269 
270 
271 
272 
273 DEFINE_ART_MODULE(evgen::TextFileGen)
std::pair< unsigned, unsigned > readEventInfo(std::istream &is)
var pdg
Definition: selectors.fcl:14
unsigned long int fOffset
pdgs p
Definition: selectors.fcl:22
void produce(art::Event &e) override
std::string fInputFileName
Name of text file containing events to simulate.
std::ifstream * fInputFile
void beginJob() override
void beginRun(art::Run &run) override
TextFileGen(fhicl::ParameterSet const &p)
float mass
Definition: dedx.py:47
do i e
simb::MCTruth readNextHepEvt()
double fMoveY
Project particles to a new y plane.
art framework interface to geometry description