DataGen311_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // Class: DataGen311
3 // Module Type: producer
4 // File: DataGen311_module.cc
5 //
6 // Get input list of selected reco track, generates primary MCParticles
7 // matching each of them
8 ////////////////////////////////////////////////////////////////////////
9 
10 // ROOT includes
11 #include "TRandom3.h"
12 #include "TDatabasePDG.h"
13 #include "TString.h"
14 #include "TSystem.h" //need BaseName and DirName
15 #include "TFile.h"
16 #include "TH2D.h"
17 #include "TTree.h"
18 #include "TVector3.h"
19 #include "TLorentzVector.h"
20 
21 // Framework includes
24 #include "fhiclcpp/ParameterSet.h"
25 #include "fhiclcpp/types/Name.h"
26 #include "fhiclcpp/types/Comment.h"
27 #include "fhiclcpp/types/Atom.h"
32 #include "art_root_io/TFileService.h"
33 #include "art_root_io/TFileDirectory.h"
36 #include "cetlib_except/exception.h"
37 
38 // nutools includes
41 #include "nugen/EventGeneratorBase/evgenbase.h"
42 
43 // lar includes
46 #include "TDatabasePDG.h"
47 
48 #include <stdio.h>
49 #include <iostream>
50 #include <fstream>
51 #include <string>
52 
53 class DataGen311;
54 
55 namespace evgendp{
56 
57  //----------------------------------------------------------------------------
58 
59  class Track{
60  //holds track input seetings from file
61 
62  public:
63 
64  Track();
65  ~Track();
66 
67  TLorentzVector getPosition();
68  TLorentzVector getMomentum();
69 
70  int run;
71  int subrun;
72  int event;
73  int trackID;
74  int pdg;
75  double m;
76  //double theta;
77  //double phi;
81  double length;
82  double startX;
83  double startY;
84  double startZ;
85  //double mom;
86  double energy;
87 
88  }; //end class Track
89 
91 
92  }
94 
95  TLorentzVector Track::getPosition(){
96  TLorentzVector position(startX, startY, startZ, 0);
97  return position;
98  }
99 
100  TLorentzVector Track::getMomentum(){
101  static TDatabasePDG pdgt;
102  TParticlePDG* pdgp = pdgt.GetParticle(pdg);
103  if (pdgp) m = pdgp->Mass();
104 
105  double mom = sqrt( energy*energy - m*m );
106  double momX = mom*startDirectionX;
107  double momY = mom*startDirectionY;
108  double momZ = mom*startDirectionZ;
109 
110  TLorentzVector momentum( momX, momY, momZ, energy );
111  return momentum;
112  }
113 
114  //----------------------------------------------------------------------------
115 
116  class DataGen311 : public art::EDProducer {
117 
118  public:
119 
120  struct Config {
121  //holds configuration settings from the fcl
122 
123  using Name = fhicl::Name;
125 
126  fhicl::Atom<int> EventsToProcess{
127  Name("EventsToProcess"),
128  Comment("Number of events to process")
129  };
130 
131  fhicl::Atom<int> StartEvent{
132  Name("StartEvent"),
133  Comment("First event to process")
134  };
135 
137  Name("PDG"),
138  Comment("Particle PDG code")
139  };
140 
141  fhicl::Atom<bool> GetEnergyFromCORSIKA{
142  Name("GetEnergyFromCORSIKA"),
143  Comment("true: read particle energy from CORSIKA histograms as a fucntion of azimuth angle")
144  };
145 
146  fhicl::Atom<double> UniformEnergyMin{
147  Name("UniformEnergyMin"),
148  Comment("Minimum particle energy")
149  };
150 
151  fhicl::Atom<double> UniformEnergyMax{
152  Name("UniformEnergyMax"),
153  Comment("Maximum particle energy")
154  };
155 
157  Name("TrackFile"),
158  Comment("Track list")
159  };
160 
162  Name("HistFile"),
163  Comment("CORSIKA histogram file")
164  };
165  }; //end struct Config
166 
168 
169  explicit DataGen311(Parameters const& config);
170 
171  DataGen311(DataGen311 const &) = delete;
172  DataGen311(DataGen311 &&) = delete;
173  DataGen311 & operator = (DataGen311 const &) = delete;
174  DataGen311 & operator = (DataGen311 &&) = delete;
175 
176  // Required functions.
177  void produce(art::Event & e) override;
178 
179  void beginJob() override;
180 
183  int fPDG;
189 
190  std::map< int, std::vector< Track*> > fEventTrackMap;
191 
192  };
193 
194 }//end namespace
195 
196 ////////////////////////////////////////////////////////////////////////////////
197 
199  : EDProducer{config},
200  fEventsToProcess (config().EventsToProcess()),
201  fStartEvent (config().StartEvent()),
202  fPDG (config().PDG()),
203  fGetEnergyFromCORSIKA (config().GetEnergyFromCORSIKA()),
204  fUniformEnergyMin (config().UniformEnergyMin()),
205  fUniformEnergyMax (config().UniformEnergyMax()),
206  fTrackFile (config().TrackFile()),
207  fHistFile (config().HistFile())
208 {
209  produces< std::vector<simb::MCTruth> >();
210  produces< sumdata::RunData, art::InRun >();
211 }
212 
213 ////////////////////////////////////////////////////////////////////////////////
214 
215 
216 
218 
219  //Random number generator for particle energy
220  gRandom = new TRandom3();
221 
222  //read the files and store the information on the map
223  std::ifstream trackfile;
224  trackfile.open( fTrackFile );
225  if( !trackfile.is_open() )
226  throw cet::exception("DataGen311") << "Can't open file " << fTrackFile <<"\n";
227 
228  TFile *chistfile = new TFile(fHistFile.c_str());
229  if( chistfile->IsOpen() == kFALSE )
230  throw cet::exception("DataGen311") << "Can't open file " << fHistFile <<"\n";
231 
232  std::stringstream hetss;
233  hetss << "hEnergyTheta" << fPDG;
234  TH2D *hEnergyTheta = (TH2D*)chistfile->Get(hetss.str().c_str());
235 
236  int eventBefore=0;
237  int eventCounter=0;
238  int trackCounter=0, skippedTrackCounter=0;
240  std::getline(trackfile, line); // Skip header
241  while(std::getline( trackfile, line )){
242  std::stringstream sstream(line);
243 
244  int eventID = 9999999;
245  sstream >> eventID;
246  if (eventID < fStartEvent) {
247  continue;
248  } else if (eventID >= fStartEvent+fEventsToProcess) {
249  break;
250  }
251 
252  Track *track = new Track();
253  sstream >> track->run >> track->subrun >> track->event >> track->trackID >> track->startDirectionX >> track->startDirectionY >> track->startDirectionZ >> track->length >> track->startX >> track->startY >> track->startZ;
254  track->pdg = fPDG;
255  trackCounter++;
256 
257  // Start direction components might not be perfectly normalized
258  double sdirmag = sqrt(track->startDirectionX*track->startDirectionX + track->startDirectionY*track->startDirectionY + track->startDirectionZ*track->startDirectionZ);
259  track->startDirectionX /= sdirmag;
260  track->startDirectionY /= sdirmag;
261  track->startDirectionZ /= sdirmag;
262 
263 
265  {
266  // Theta from +X to -X
267  double theta = acos(track->startDirectionX);
268 
269  int biny = hEnergyTheta->GetYaxis()->FindBin(theta);
270  TH1D *hEnergyAtTheta = hEnergyTheta->ProjectionX("", biny, biny);
271 
272  if( hEnergyAtTheta->GetEntries() < 1 ){
273  skippedTrackCounter++;
274  delete track;
275  continue;
276  }
277 
278  track->energy = hEnergyAtTheta->GetRandom();
279  }
280  else if(fUniformEnergyMin == fUniformEnergyMax) //get energy from .fcl parameter
281  {
282  track->energy = fUniformEnergyMin;
283  }
284  else //get energy from .fcl parameter
285  {
286  track->energy = gRandom->Uniform(fUniformEnergyMin, fUniformEnergyMax);
287  }
288 
289  if( track->event != eventBefore ){
290  eventBefore = track->event;
291  eventCounter++;
292  }
293 
294  //push back in map
295  fEventTrackMap[eventCounter].push_back(track);
296  }
297 
298  trackfile.close();
299 
300  //initialize randomn number seed for
301 
302 }
303 
304 ////////////////////////////////////////////////////////////////////////////////
305 
307  std::unique_ptr< std::vector<simb::MCTruth> > truthcol(new std::vector<simb::MCTruth>);
308 
309  simb::MCTruth truth;
311 
312  //read the particle map and create the particle
313  int trackCtr=0;
314  for(Track* track : fEventTrackMap[e.id().event()] ){
315 
316  simb::MCParticle particle( trackCtr, track->pdg ,"primary",-200, track->m , 1 );
317  particle.AddTrajectoryPoint( track->getPosition() , track->getMomentum() );
318 
319  truth.Add(particle);
320 
321  trackCtr++;
322  }
323 
324  truthcol->push_back(truth);
325  e.put(std::move(truthcol));
326 
327 }
328 
void AddTrajectoryPoint(TLorentzVector const &position, TLorentzVector const &momentum)
Definition: MCParticle.h:257
TLorentzVector getPosition()
void SetOrigin(simb::Origin_t origin)
Definition: MCTruth.h:82
std::string string
Definition: nybbler.cc:12
ChannelGroupService::Name Name
Particle class.
art framework interface to geometry description
const uint PDG
Definition: qregexp.cpp:140
const double e
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
void beginJob()
Definition: Breakpoints.cc:14
static Config * config
Definition: config.cpp:1054
def move(depos, offset)
Definition: depos.py:107
ProductID put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
Definition: DataViewImpl.h:686
std::map< int, std::vector< Track * > > fEventTrackMap
void Add(simb::MCParticle const &part)
Definition: MCTruth.h:80
#define Comment
void line(double t, double *p, double &x, double &y, double &z)
EventNumber_t event() const
Definition: EventID.h:116
void beginJob() override
TrackCollectionProxyElement< TrackCollProxy > Track
Proxy to an element of a proxy collection of recob::Track objects.
Definition: Track.h:1036
Event generator information.
Definition: MCTruth.h:32
def momentum(x1, x2, x3, scale=1.)
TLorentzVector getMomentum()
DataGen311(Parameters const &config)
void produce(art::Event &e) override
EventID id() const
Definition: Event.cc:34
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
Cosmic rays.
Definition: MCTruth.h:24