LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
MUSUN_module.cc
Go to the documentation of this file.
1 #ifndef EVGEN_MUSUN
143 #define EVGEN_MUSUN
144 
145 // C++ includes.
146 #include <cstdlib>
147 #include <fstream>
148 #include <stdio.h>
149 #include <iostream>
150 #include <sstream>
151 #include <string>
152 #include <cmath>
153 #include <memory>
154 #include <iterator>
155 #include <vector>
156 #include <utility>
157 #include <sys/stat.h>
158 #include <exception>
159 #include <map>
160 #include <vector>
161 #include <algorithm>
162 
163 // Framework includes
166 #include "fhiclcpp/ParameterSet.h"
174 #include "cetlib_except/exception.h"
175 
176 // art extensions
178 
179 // nutools includes
183 
184 // lar includes
187 
188 #include "TTree.h"
189 #include "TVector3.h"
190 #include "TDatabasePDG.h"
191 #include "TMath.h"
192 #include "TF2.h"
193 #include "TH1.h"
194 #include "TString.h"
195 #include "TFile.h"
196 #include "TAxis.h"
197 
198 #include "CLHEP/Random/RandFlat.h"
199 #include "CLHEP/Random/RandGaussQ.h"
200 
201 // for c2: NTPCs is no longer used
202 //const int NTPCs = 300;
203 
204 
205 namespace simb { class MCTruth; }
206 
207 namespace evgen {
208 
210  class MUSUN : public art::EDProducer {
211 
212  public:
213  explicit MUSUN(fhicl::ParameterSet const& pset);
214  virtual ~MUSUN();
215 
216  // This is called for each event.
217  void produce(art::Event& evt);
218  void beginJob();
219  void beginRun(art::Run& run);
220  void reconfigure(fhicl::ParameterSet const& p);
221  void endRun(art::Run& run);
222 
223  private:
224 
225  void SampleOne(unsigned int i, simb::MCTruth &mct);
226 
227  void initialization( double theta1, double theta2, double phi1, double phi2,
228  int figflag, double s_hor, double s_ver1, double s_ver2, double &FI );
229 
230  void sampling( double &E, double &theta, double &phi, double &dep );
231 
232 
233  static const int kGAUS = 1;
234 
235  int fPDG;
236  double fChargeRatio;
237 
238  std::string fInputDir;
239  std::string fInputFile1;
240  std::string fInputFile2;
241  std::string fInputFile3;
242 
243  double fCavernAngle;
244  double fRockDensity;
245 
249  double fEmin;
250  double fEmax;
251 
252  double fThetamin;
253  double fThetamax;
254  double fPhimin;
255  double fPhimax;
256 
257  int figflag;
258  double fXmin;
259  double fYmin;
260  double fZmin;
261  double fXmax;
262  double fYmax;
263  double fZmax;
264 
265  double fT0;
266  double fSigmaT;
267  int fTDist;
268 
269  //Define TFS histograms.....
270  /*
271  TH1D* hPDGCode;
272  TH1D* hPositionX;
273  TH1D* hPositionY;
274  TH1D* hPositionZ;
275  TH1D* hTime;
276  TH1D* hMomentumHigh;
277  TH1D* hMomentum;
278  TH1D* hEnergyHigh;
279  TH1D* hEnergy;
280  TH1D* hDepth;
281  TH1D* hDirCosineX;
282  TH1D* hDirCosineY;
283  TH1D* hDirCosineZ;
284  TH1D* hTheta;
285  TH1D* hPhi;
286  */
287  int PdgCode;
288  double Energy, phi, theta, dep, Time;
289  double Momentum, px0, py0, pz0;
290  double x0, y0, z0, cx, cy, cz;
291 
292  //Define some variables....
293  double FI = 0.;
294  double s_hor = 0.;
295  double s_ver1 = 0.;
296  double s_ver2 = 0.;
297 
298  double spmu[121][62][51];
299  double fnmu[32401];
300  double depth[360][91];
301  double fmu[360][91];
302  // for c2: e1 and e2 are unused
303  //double e1, e2, the1, the2, ph1, ph2;
304  double the1, the2, ph1, ph2;
305  double se = 0.;
306  double st = 0.;
307  double sp = 0.;
308  double sd = 0.;
309 
310  unsigned int NEvents = 0;
311 
312  // TTree
313  TTree* fTree;
314  /*
315  // TTree for CryoPos
316  TTree* fCryos;
317  int NumTPCs;
318  double TPCMinX[NTPCs];
319  double TPCMaxX[NTPCs];
320  double TPCMinY[NTPCs];
321  double TPCMaxY[NTPCs];
322  double TPCMinZ[NTPCs];
323  double TPCMaxZ[NTPCs];
324  double CryoSize[6];
325  double DetHall[6];
326  */
327  };
328 }
329 
330 namespace evgen{
331 
332  //____________________________________________________________________________
333  MUSUN::MUSUN(fhicl::ParameterSet const& pset)
334  {
335  this->reconfigure(pset);
336 
337  // create a default random engine; obtain the random seed from NuRandomService,
338  // unless overridden in configuration with key "Seed"
340  ->createEngine(*this, pset, "Seed");
341 
342  produces< std::vector<simb::MCTruth> >();
343  produces< sumdata::RunData, art::InRun >();
344  }
345  //____________________________________________________________________________
346  MUSUN::~MUSUN()
347  {
348  }
349 
351  // Reconfigure
353  void MUSUN::reconfigure(fhicl::ParameterSet const& p)
354  {
355  // do not put seed in reconfigure because we don't want to reset
356  // the seed midstream
357 
358  fPDG = p.get< int >("PDG");
359  fChargeRatio = p.get< double >("ChargeRatio");
360 
361  fInputDir = p.get< std::string >("InputDir");
362  fInputFile1 = p.get< std::string >("InputFile1");
363  fInputFile2 = p.get< std::string >("InputFile2");
364  fInputFile3 = p.get< std::string >("InputFile3");
365 
366  fCavernAngle = p.get< double >("CavernAngle");
367  fRockDensity = p.get< double >("RockDensity");
368 
369  fEmin = p.get< double >("Emin");
370  fEmax = p.get< double >("Emax");
371 
372  fThetamin = p.get< double >("Thetamin");
373  fThetamax = p.get< double >("Thetamax");
374 
375  fPhimin = p.get< double >("Phimin");
376  fPhimax = p.get< double >("Phimax");
377 
378  figflag = p.get<int >("igflag");
379  fXmin = p.get<double >("Xmin");
380  fYmin = p.get<double >("Ymin");
381  fZmin = p.get<double >("Zmin");
382  fXmax = p.get<double >("Xmax");
383  fYmax = p.get<double >("Ymax");
384  fZmax = p.get<double >("Zmax");
385 
386  fT0 = p.get< double >("T0");
387  fSigmaT = p.get< double >("SigmaT");
388  fTDist = p.get< int >("TDist");
389 
390  return;
391  }
393  // Begin Job
396  {
397  // Make the Histograms....
399  /*
400  hPDGCode = tfs->make<TH1D>("hPDGCode" ,"PDG Code" ,30 , -15 , 15 );
401  hPositionX = tfs->make<TH1D>("hPositionX" ,"Position (cm)" ,500, ( fXmin - 10 ), ( fXmax + 10 ) );
402  hPositionY = tfs->make<TH1D>("hPositionY" ,"Position (cm)" ,500, ( fYmin - 10 ), ( fYmax + 10 ) );
403  hPositionZ = tfs->make<TH1D>("hPositionZ" ,"Position (cm)" ,500, ( fZmin - 10 ), ( fZmax + 10 ) );
404  hTime = tfs->make<TH1D>("hTime" ,"Time (s)" ,500, 0 , 1e6 );
405  hMomentumHigh = tfs->make<TH1D>("hMomentumHigh","Momentum (GeV)",500, fEmin, fEmax );
406  hMomentum = tfs->make<TH1D>("hMomentum" ,"Momentum (GeV)",500, fEmin, fEmin+1e3 );
407  hEnergyHigh = tfs->make<TH1D>("hEnergyHigh" ,"Energy (GeV)" ,500, fEmin, fEmax );
408  hEnergy = tfs->make<TH1D>("hEnergy" ,"Energy (GeV)" ,500, fEmin, fEmin+1e3 );
409  hDepth = tfs->make<TH1D>("hDepth" ,"Depth (m)" ,800, 0 , 14000 );
410 
411  hDirCosineX = tfs->make<TH1D>("hDirCosineX","Normalised Direction cosine",500, -1, 1 );
412  hDirCosineY = tfs->make<TH1D>("hDirCosineY","Normalised Direction cosine",500, -1, 1 );
413  hDirCosineZ = tfs->make<TH1D>("hDirCosineZ","Normalised Direction cosine",500, -1, 1 );
414 
415  hTheta = tfs->make<TH1D>("hTheta" ,"Angle (degrees)",500, 0, 90 );
416  hPhi = tfs->make<TH1D>("hPhi" ,"Angle (degrees)",500, 0, 365 );
417  */
418  fTree = tfs->make<TTree>("Generator","analysis tree");
419  fTree->Branch("particleID",&PdgCode, "particleID/I");
420  fTree->Branch("energy" ,&Energy , "energy/D");
421  fTree->Branch("time" ,&Time , "Time/D" );
422  fTree->Branch("posX" ,&x0 , "posX/D" );
423  fTree->Branch("posY" ,&y0 , "posY/D" );
424  fTree->Branch("posZ" ,&z0 , "posZ/D" );
425  fTree->Branch("cosX" ,&cx , "cosX/D" );
426  fTree->Branch("cosY" ,&cy , "cosY/D" );
427  fTree->Branch("cosZ" ,&cz , "cosZ/D" );
428  fTree->Branch("theta" ,&theta , "theta/D" );
429  fTree->Branch("phi" ,&phi , "phi/D" );
430  fTree->Branch("depth" ,&dep , "dep/D" );
431  /*
432  fCryos = tfs->make<TTree>("CryoSizes","cryo tree");
433  fCryos->Branch("NumTPCs" , &NumTPCs , "NumTPCs/I" );
434  fCryos->Branch("TPCMinX" , &TPCMinX , "TPCMinX[NumTPCs]/D");
435  fCryos->Branch("TPCMaxX" , &TPCMaxX , "TPCMaxX[NumTPCs]/D");
436  fCryos->Branch("TPCMinY" , &TPCMinY , "TPCMinY[NumTPCs]/D");
437  fCryos->Branch("TPCMaxY" , &TPCMaxY , "TPCMaxY[NumTPCs]/D");
438  fCryos->Branch("TPCMinZ" , &TPCMinZ , "TPCMinZ[NumTPCs]/D");
439  fCryos->Branch("TPCMaxZ" , &TPCMaxZ , "TPCMaxZ[NumTPCs]/D");
440  fCryos->Branch("CryoSize", &CryoSize, "CryoSize[6]/D" );
441  fCryos->Branch("DetHall" , &DetHall , "DetHall[6]/D" );
442  */
443  }
444 
446  // Begin Run
448  void MUSUN::beginRun(art::Run& run)
449  {
450  // grab the geometry object to see what geometry we are using
452  std::unique_ptr<sumdata::RunData> runcol(new sumdata::RunData(geo->DetectorName()));
453 
454  // Check fcl parameters were set correctly
455  if ( fThetamax > 90.5 ) throw cet::exception("MUSUNGen") << "\nThetamax has to be less than " << M_PI/2 << ", but was entered as " << fThetamax << ", this causes an error so leaving program now...\n\n";
456  if ( fThetamin < 0 ) throw cet::exception("MUSUNGen") << "\nThetamin has to be more than 0, but was entered as " << fThetamin << ", this causes an error so leaving program now...\n\n";
457  if ( fThetamax < fThetamin ) throw cet::exception("MUSUNGen") << "\nMinimum angle is bigger than maximum angle....causes an error so leaving program now....\n\n";
458  if ( fPhimax > 360.5 ) throw cet::exception("MUSUNGen") << "\nPhimax has to be less than " << 2*M_PI << ", but was entered as " << fPhimax << ", this cause an error so leaving program now...\n\n";
459  if ( fPhimin < 0 ) throw cet::exception("MUSUNGen") << "\nPhimin has to be more than 0, but was entered as " << fPhimin << ", this causes an error so leaving program now...\n\n";
460  if ( fPhimax < fPhimin) throw cet::exception("MUSUNGen") << "\nMinimum angle is bigger than maximum angle....causes an error so leaving program now....\n\n";
461  if ( fEmax < fEmin ) throw cet::exception("MUSUNGen") << "\nMinimum energy is bigger than maximum energy....causes an error so leaving program now....\n\n";
462 
463 
464  run.put(std::move(runcol));
465 
466  // area of the horizontal plane of the parallelepiped
467  s_hor = (fZmax-fZmin)*(fXmax-fXmin);
468  // area of the vertical plane of the parallelepiped, perpendicular to z-axis
469  s_ver1 = (fXmax-fXmin)*(fYmax-fYmin);
470  // area of the vertical plane of the parallelepiped, perpendicular to x-axis
471  s_ver2 = (fZmax-fZmin)*(fYmax-fYmin);
472 
473  //std::cout << s_hor << " " << s_ver1 << " " << s_ver2 << std::endl;
474 
475  initialization(fThetamin,fThetamax,fPhimin,fPhimax,figflag,s_hor,s_ver1,s_ver2,FI );
476 
477  std::cout << "Material - SURF rock" << std::endl;
478  std::cout << "Density = " << fRockDensity << " g/cm^3" << std::endl;
479  std::cout << "Parameters for muon spectrum are from LVD best fit" << std::endl;
480  std::cout << "Muon energy range = " << fEmin << " - " << fEmax << " GeV" << std::endl;
481  std::cout << "Zenith angle range = " << fThetamin << " - " << fThetamax << " degrees" << std::endl;
482  std::cout << "Azimuthal angle range = " << fPhimin << " - " << fPhimax << " degrees" << std::endl;
483  std::cout << "Global intensity = " << FI << " (cm^2 s)^(-1) or s^(-1) (for muons on the surface)" << std::endl;
484  /*
485  NumTPCs = geo->NTPC(0);
486  std::cout << "There are " << NumTPCs << " in cryostat 0" << std::endl;
487  for (unsigned int c=0; c<geo->Ncryostats(); c++) {
488  const geo::CryostatGeo& cryostat=geo->Cryostat(c);
489  geo->CryostatBoundaries( CryoSize, 0 );
490  std::cout << "Cryo bounds " << CryoSize[0] << " "<< CryoSize[1] << " "<< CryoSize[2] << " "<< CryoSize[3] << " "<< CryoSize[4] << " "<< CryoSize[5] << std::endl;
491  for (unsigned int t=0; t<cryostat.NTPC(); t++) {
492  geo::TPCID id;
493  id.Cryostat=c;
494  id.TPC=t;
495  id.isValid=true;
496  const geo::TPCGeo& tpc=cryostat.TPC(id);
497  TPCMinX[t] = tpc.MinX();
498  TPCMaxX[t] = tpc.MaxX();
499  TPCMinY[t] = tpc.MinY();
500  TPCMaxY[t] = tpc.MaxY();
501  TPCMinZ[t] = tpc.MinZ();
502  TPCMaxZ[t] = tpc.MaxZ();
503  std::cout << t << "\t" << TPCMinX[t] << " " << TPCMaxX[t] << " " << TPCMinY[t] << " " << TPCMaxY[t] << " " << TPCMinZ[t] << " " << TPCMaxZ[t] << std::endl;
504  }
505  }
506  fCryos -> Fill();
507  */
508  return;
509  }
510 
512  // End Run
514  void MUSUN::endRun(art::Run& run)
515  {
516  std::cout << "\n\nNumber of muons = " << NEvents << std::endl;
517  std::cout << "Mean muon energy = " << se/NEvents << " GeV" << std::endl;
518  std::cout << "Mean zenith angle (theta) = " << st/NEvents << " degrees" << std::endl;
519  std::cout << "Mean azimuthal angle (phi)= " << sp/NEvents << " degrees" << std::endl;
520  std::cout << "Mean slant depth = " << sd/NEvents << " m w.e." << std::endl;
521  }
523  // Produce
525  void MUSUN::produce(art::Event& evt)
526  {
528  std::unique_ptr< std::vector<simb::MCTruth> > truthcol(new std::vector<simb::MCTruth>);
529 
530  simb::MCTruth truth;
532 
533  ++NEvents;
534  SampleOne(NEvents,truth);
535 
536  LOG_DEBUG("MUSUN") << truth;
537 
538  truthcol->push_back(truth);
539 
540  evt.put(std::move(truthcol));
541 
542  return;
543  }
545  // Sample One
547  // Draw the type, momentum and position of a single particle from the
548  // FCIHL description
549  void MUSUN::SampleOne(unsigned int i, simb::MCTruth &mct){
550 
551  // get the random number generator service and make some CLHEP generators
553  CLHEP::HepRandomEngine &engine = rng->getEngine();
554  CLHEP::RandFlat flat(engine);
555  CLHEP::RandGaussQ gauss(engine);
556 
557  Energy = 0;
558  theta = 0;
559  phi = 0;
560  dep = 0;
561  Time = 0;
562 
563  sampling( Energy, theta, phi, dep );
564 
565  theta = theta* M_PI/180;
566 
567  // changing the angle phi so z-axis is positioned along the long side
568  // of the cavern pointing at 14 deg from the North to the East.
569  // phi += (90. - 14.0);
570  // Want our co-ord rotation going from East to South.
571  phi += fCavernAngle;
572  if( phi >= 360. )
573  phi -= 360.;
574  if( phi < 0 )
575  phi += 360.;
576  phi *= M_PI / 180.;
577 
578  // set track id to -i as these are all primary particles and have id <= 0
579  int trackid = -1*(i+1);
580  std::string primary("primary");
581 
582  // Work out whether particle/antiparticle, and mass...
583  double m = 0.0;
584  PdgCode = fPDG;
585  double ChargeCheck = 1./ ( 1 + fChargeRatio );
586  double pdgfire = flat.fire();
587  if ( pdgfire < ChargeCheck ) PdgCode=-PdgCode;
588 
589  static TDatabasePDG pdgt;
590  TParticlePDG* pdgp = pdgt.GetParticle(PdgCode);
591  if (pdgp) m = pdgp->Mass();
592 
593  //std::cout << pdgfire << " " << ChargeCheck << " " << PdgCode << " " << m << std::endl;
594 
595  // Work out T0...
596  if(fTDist==kGAUS){
597  Time = gauss.fire(fT0, fSigmaT);
598  }
599  else {
600  Time = fT0 + fSigmaT*(2.0*flat.fire()-1.0);
601  }
602 
603  // The minus sign above is for y-axis pointing up, so the y-momentum
604  // is always pointing down
605  cx = -sin(theta)*sin(phi);
606  cy = -cos(theta);
607  cz = +sin(theta)*cos(phi);
608  Momentum = std::sqrt(Energy*Energy-m*m); // Get momentum
609  px0 = Momentum * cx;
610  py0 = Momentum * cy;
611  pz0 = Momentum * cz;
612  TLorentzVector pvec(px0, py0, pz0, Energy );
613 
614  // Muon coordinates
615  double sh1 = s_hor * cos(theta);
616  double sv1 = s_ver1 * sin(theta) * fabs(cos(phi));
617  double sv2 = s_ver2 * sin(theta) * fabs(sin(phi));
618  double ss = sh1 + sv1 + sv2;
619  double xfl1 = flat.fire();
620  if( xfl1 <= sh1/ss ) {
621  x0 = (fXmax - fXmin)*flat.fire() + fXmin;
622  y0 = fYmax;
623  z0 = (fZmax - fZmin)*flat.fire() + fZmin;
624  } else if( xfl1 <= (sh1+sv1)/ss ) {
625  x0 = (fXmax - fXmin)*flat.fire() + fXmin;
626  y0 = (fYmax - fYmin)*flat.fire() + fYmin;
627  if( cz >= 0 ) z0 = fZmax;
628  else z0 = fZmin;
629  } else {
630  if( cx >= 0 ) x0 = fXmin;
631  else x0 = fXmax;
632  y0 = (fYmax - fYmin)*flat.fire() + fYmin;
633  z0 = (fZmax - fZmin)*flat.fire() + fZmin;
634  }
635  // Make Lorentz vector for x and t....
636  TLorentzVector pos(x0, y0, z0, Time);
637 
638  // Parameters written to the file muons_surf_v2_test*.dat
639  // nmu - muon sequential number
640  // id_part - muon charge (10 - positive, 11 - negative )
641  // Energy - total muon energy in GeV assuming ultrarelativistic muons
642  // x0, y0, z0 - muon coordinates on the surface of parallelepiped
643  // specified above; x-axis and y-axis are pointing in the
644  // directions such that the angle phi (from the slant depth
645  // distribution files) is measured from x to y. z-axis is
646  // pointing upwards.
647  // cx, cy, cz - direction cosines.
648 
649  simb::MCParticle part(trackid, PdgCode, primary);
650  part.AddTrajectoryPoint(pos, pvec);
651 
652  mct.Add(part);
653 
654  theta = theta * 180/M_PI;
655  phi = phi * 180/M_PI;
656 
657  // Sum energies, angles, depth for average outputs.
658  se += Energy;
659  st += theta;
660  sp += phi;
661  sd += dep;
662 
663  // Fill Histograms.....
664  /*
665  hPDGCode ->Fill (PdgCode);
666  hPositionX ->Fill (x0);
667  hPositionY ->Fill (y0);
668  hPositionZ ->Fill (z0);
669  hTime ->Fill (Time);
670  hMomentumHigh ->Fill (Momentum);
671  hMomentum ->Fill (Momentum);
672  hEnergyHigh ->Fill (Energy);
673  hEnergy ->Fill (Energy);
674  hDepth ->Fill (dep);
675  hDirCosineX ->Fill (cx);
676  hDirCosineY ->Fill (cy);
677  hDirCosineZ ->Fill (cz);
678  hTheta ->Fill (theta);
679  hPhi ->Fill (phi);
680  */
681  /*
682  // Write event by event outsputs.....
683  std::cout << "Theta: " << theta << " Phi: " << phi << " Energy: " << Energy << " Momentum: " << Momentum << std::endl;
684  std::cout << "x: " << pos.X() << " y: " << pos.Y() << " z: " << pos.Z() << " time: " << pos.T() << std::endl;
685  std::cout << "Px: " << pvec.Px() << " Py: " << pvec.Py() << " Pz: " << pvec.Pz() << std::endl;
686  std::cout << "Normalised..." << cx << " " << cy << " " << cz << std::endl;
687  */
688  fTree->Fill();
689 
690  }
691 
693  // initialization
695  void MUSUN::initialization( double theta1, double theta2, double phi1, double phi2,
696  int figflag, double s_hor, double s_ver1, double s_ver2, double &FI )
697  {
698  //
699  // Read in the data files
700  //
701  int lineNumber = 0, index = 0;
702  char inputLine[10000];
703  std::string fROOTfile;
704 
705  for (int a=0;a<121;++a) for (int b=0;b<62;++b) for (int c=0;c<50;++c) spmu[a][b][c]=0;
706  for (int a=0;a<23401;++a) fnmu[a] = 0;
707  for (int a=0;a<360;++a) for (int b=0;b<91;++b) depth[a][b]= 0;
708  for (int a=0;a<360;++a) for (int b=0;b<91;++b) fmu[a][b] = 0;
709 
710  std::ostringstream File1LocStream;
711  File1LocStream << fInputDir << fInputFile1;
712  std::string File1Loc = File1LocStream. str();
713  cet::search_path sp1("FW_SEARCH_PATH");
714  if( sp1.find_file(fInputFile1, fROOTfile) ) File1Loc = fROOTfile;
715  std::ifstream file1( File1Loc.c_str(), std::ios::in );
716  if (!file1.good() ) throw cet::exception("MUSUNGen") << "\nFile1 " << fInputFile1 << " not found in FW_SEARCH_PATH or at " << fInputDir <<"\n\n";
717 
718  while( file1.good() ) {
719  //std::cout << "Looking at file 1...." << std::endl;
720  file1.getline( inputLine, 9999 );
721  char *token;
722  token = strtok( inputLine, " " );
723  while( token != NULL ) {
724  //std::cout << "While loop file 1..." << std::endl;
725  fmu[index][lineNumber] = atof( token );
726  token = strtok( NULL, " " );
727  index++;
728  if( index == 360 ) {
729  //std::cout << "If statement file 1..." << std::endl;
730  index = 0;
731  lineNumber++;
732  }
733  }
734  }
735  file1.close();
736 
737  std::ostringstream File2LocStream;
738  File2LocStream << fInputDir << fInputFile2;
739  std::string File2Loc = File2LocStream. str();
740  cet::search_path sp2("FW_SEARCH_PATH");
741  if( sp2.find_file(fInputFile2, fROOTfile) ) File2Loc = fROOTfile;
742  std::ifstream file2( File2Loc.c_str(), std::ios::binary|std::ios::in );
743  if (!file2.good() ) throw cet::exception("MUSUNGen") << "\nFile2 " << fInputFile2 << " not found in FW_SEARCH_PATH or at " << fInputDir <<"\n\n";
744 
745  int i1 = 0, i2 = 0, i3 = 0;
746  float readVal;
747  while( file2.good() ) {
748  //std::cout << "Looking at file 2...." << std::endl;
749  file2.read((char *)(&readVal), sizeof(float));
750  spmu[i1][i2][i3] = readVal;
751  i1++;
752  if( i1 == 121 ) {
753  //std::cout << "First if statement file 2..." << std::endl;
754  i2++;
755  i1 = 0;
756  }
757  if( i2 == 62 ) {
758  //std::cout << "Second if statement file 2..." << std::endl;
759  i3++;
760  i2 = 0;
761  }
762  }
763  file2.close();
764  for( int i=0; i<120; i++ )
765  for( int j=0; j<62; j++ )
766  for( int k=0; k<51; k++ )
767  spmu[i][j][k] = spmu[i+1][j][k];
768  spmu[1][1][0] = 0.000853544;
769  //std::cout << "Set spmu to some value..." << std::endl;
770 
771  std::ostringstream File3LocStream;
772  File3LocStream << fInputDir << fInputFile3;
773  std::string File3Loc = File3LocStream. str();
774  cet::search_path sp3("FW_SEARCH_PATH");
775  if( sp3.find_file(fInputFile3, fROOTfile) ) File3Loc = fROOTfile;
776  std::ifstream file3( File3Loc.c_str(), std::ios::in );
777  if (!file3.good() ) throw cet::exception("MUSUNGen") << "\nFile3 " << fInputFile3 << " not found in FW_SEARCH_PATH or at " << fInputDir <<"\n\n";
778 
779  lineNumber = index = 0;
780  while( file3.good() ) {
781  //std::cout << "Looking at file 3...." << std::endl;
782  file3.getline( inputLine, 9999 );
783  char *token;
784  token = strtok( inputLine, " " );
785  while( token != NULL ) {
786  //std::cout << "While loop file 3..." << std::endl;
787  depth[index][lineNumber] = atof( token );
788  token = strtok( NULL, " " );
789  index++;
790  if( index == 360 ) {
791  //std::cout << "If statement file 3..." << std::endl;
792  index = 0;
793  lineNumber++;
794  }
795  }
796  }
797  file3.close();
798 
799  //
800  // Set up variables
801  //
802 
803  the1 = theta1;
804  the2 = theta2;
805  // for c2: c1 and c2 are unused
806  //double c1 = cos(M_PI/180.*theta1);
807  //double c2 = cos(M_PI/180.*theta2);
808  ph1 = M_PI/180.*phi1;
809  ph2 = M_PI/180.*phi2;
810  // for c2: dph is unused
811  //double dph = ph2-ph1;
812 
813  int ipc = 1;
814  double theta = theta1;
815  double dc = 1.;
816  double sc = 0.;
817  int iteration = 0;
818  while( theta < theta2-dc/2. ) {
819  theta += dc/2.;
820  double theta0 = M_PI/180. * theta;
821  double cc = cos(theta0);
822  double ash = s_hor * cc;
823  double asv01 = s_ver1 * sqrt(1. - cc*cc);
824  double asv02 = s_ver2 * sqrt(1. - cc*cc);
825  int ic1 = (theta + 0.999);
826  int ic2 = ic1 + 1;
827  if( ic2 > 91 ) ic2 = 91;
828  if( ic1 < 1 ) ic1 = 1;
829  double phi = phi1;
830  double dp = 1.;
831 
832  while( phi < phi2-dp/2. ) {
833  phi += dp/2.;
834  // the long side of the cavern is pointing at 14 deg to the north:
835  // double phi0 = M_PI / 180. * (phi + 90. - 14);
836 
837  // Want our co-ord system going from East to South.
838  double phi0 = M_PI / 180. * (phi + fCavernAngle);
839 
840  double asv1 = asv01 * fabs(cos(phi0));
841  double asv2 = asv02 * fabs(sin(phi0));
842  double asv0 = ash + asv1 + asv2;
843  double fl = 1.;
844  if( figflag == 1 )
845  fl = asv0;
846  int ip1 = (phi + 0.999);
847  int ip2 = ip1 + 1;
848  if( ip2 > 360 ) ip2 = 1;
849  if( ip1 < 1 ) ip1 = 360;
850  double sp1 = 0.;
851 
852  for( int ii=0; ii<4; ii++ ) {
853  int iic = ii/2;
854  int iip = ii%2;
855  if(ip1==360 && (ii==1 || ii==3) ) iip = -359;
856  if( fmu[ip1+iip-1][ic1+iic-1] < 0 ) {
857  if ( pow(10.,fmu[ip1+iip-1][ic1+iic-1]) / 4 > 1e-6 ) {
858  std::cout << "Looking at fmu [ " << ip1 << " + " << iip << " - 1 (" << ip1+iip-1 << ") ] [ " << ic1 << " + " << iic << " - 1 ("<< ic1+iic-1 << ") ] ."
859  << "\nChanging sp1 from " << sp1 << " to " << sp1 + pow(10.,fmu[ip1+iip-1][ic1+iic-1]) / 4 << "..........." << sp1 << " + 10 ^ (" << fmu[ip1+iip-1][ic1+iic-1] << ") / 4 "
860  << std::endl;
861  }
862  sp1 = sp1 + pow(10.,fmu[ip1+iip-1][ic1+iic-1]) / 4;
863  }
864  }
865  /*
866  std::cout << iteration<< " time of new sc value! Theta " << theta << ", phi " << phi + dp / 2. << ", sc = " << sc + sp1 * fl * dp * M_PI / 180. * sin(theta0) * dc * M_PI / 180. << " = "
867  << sc << " + " << sp1 << " * " << fl << " * " << dp << " * " << M_PI/180 << " * sin(" << theta0 << ") * " << dc << " * " << M_PI/180 << ".....sin(theta)=" << sin(theta) << "\n"
868  << std::endl; */
869  sc = sc + sp1 * fl * dp * M_PI / 180. * sin(theta0) * dc * M_PI / 180.;
870  ++iteration;
871  ipc = ipc + 1;
872  fnmu[ipc-1] = sc;
873  phi = phi + dp / 2.;
874  }
875 
876  theta = theta + dc / 2.;
877  }
878  //std::cout << *FI << " = " << sc << std::endl;
879  FI = sc;
880  for( int ipc1 = 0; ipc1 < ipc; ipc1++ )
881  fnmu[ipc1] = fnmu[ipc1] / fnmu[ipc-1];
882  }
883 
884 
886  // sampling
888  void MUSUN::sampling( double &E, double &theta, double &phi, double &dep )
889  {
890  // get the random number generator service and make some CLHEP generators
892  CLHEP::HepRandomEngine &engine = rng->getEngine();
893  CLHEP::RandFlat flat(engine);
894  CLHEP::RandGaussQ gauss(engine);
895 
896  #if 0 // this code is disabled for good
897  double xfl = flat.fire();
898  int loIndex = 0, hiIndex = 32400;
899  int i = (loIndex+hiIndex)/2;
900  bool foundIndex = false;
901  if( xfl < fnmu[loIndex] ) {
902  i = loIndex;
903  foundIndex = true;
904  } else if ( xfl > fnmu[hiIndex] ) {
905  i = hiIndex;
906  foundIndex = true;
907  } else if ( xfl > fnmu[i-1] && xfl <= fnmu[i] )
908  foundIndex = true;
909  while( !foundIndex ) {
910  if( xfl < fnmu[i] )
911  hiIndex = i;
912  else
913  loIndex = i;
914  i = (loIndex + hiIndex)/2;
915 
916  if( xfl > fnmu[i-1] && xfl <= fnmu[i] )
917  foundIndex = true;
918  }
919  #else
920  double xfl = flat.fire();
921  int i = 0;
922  while ( xfl > fnmu[i] ) ++i;
923  #endif
924  int ic = (i-2)/360;
925  int ip = i-2-ic*360;
926 
927  xfl = flat.fire();
928  theta = the1 + ((double)ic+xfl);
929  xfl = flat.fire();
930  phi = ph1 + ((double)ip+xfl);
931  if ( phi > 360 ) phi = phi -360;
932  dep = depth[ip][ic] * fRockDensity;
933 
934  int ic1 = cos(M_PI/180.*theta) * 50.;
935  if( ic1 < 0 )
936  ic1 = 0;
937  if( ic1 > 50 )
938  ic1 = 50;
939  int ip1 = dep / 200. - 16;
940  if( ip1 < 0 )
941  ip1 = 0;
942  if( ip1 > 61 )
943  ip1 = 61;
944 
945  xfl = flat.fire();
946  #if 0
947  loIndex = 0, hiIndex = 120;
948  int j = (loIndex+hiIndex)/2;
949  foundIndex = false;
950  if( xfl < spmu[loIndex][ip1][ic1] ) {
951  j = loIndex;
952  foundIndex = true;
953  } else if ( xfl > spmu[hiIndex][ip1][ic1] ) {
954  j = hiIndex;
955  foundIndex = true;
956  } else if ( xfl > spmu[j-1][ip1][ic1] && xfl <= spmu[j][ip1][ic1] )
957  foundIndex = true;
958  while( !foundIndex ) {
959  if( xfl < spmu[j][ip1][ic1] )
960  hiIndex = j;
961  else
962  loIndex = j;
963  j = (loIndex + hiIndex)/2;
964 
965  if( xfl > spmu[j-1][ip1][ic1] && xfl <= spmu[j][ip1][ic1] )
966  foundIndex = true;
967  }
968  #else
969  int j = 0;
970  while ( xfl > spmu[j][ip1][ic1] ) ++j;
971  #endif
972 
973  double En1 = 0.05 * (j-1);
974  double En2 = 0.05 * (j);
975  E = pow(10.,En1 + (En2 - En1)*flat.fire());
976 
977  return;
978  }
979 
980 }//end namespace evgen
981 
982 namespace evgen{
983 
985 
986 }//end namespace evgen
987 
988 #endif
989 
double fEmax
Maximum Kinetic Energy (GeV)
double fZmax
Maximum Z position.
double fYmax
Maximum Y position.
double fCavernAngle
Angle of the detector from the North to the East.
void AddTrajectoryPoint(TLorentzVector const &position, TLorentzVector const &momentum)
Definition: MCParticle.h:261
Float_t E
Definition: plot.C:23
void SetOrigin(simb::Origin_t origin)
Definition: MCTruth.h:78
double fEmin
Minimum Kinetic Energy (GeV)
double fThetamin
Minimum theta.
std::string fInputDir
Input Directory.
Float_t ss
Definition: plot.C:23
art::ProductID put(std::unique_ptr< PROD > &&)
Definition: Run.h:148
Particle class.
void Add(simb::MCParticle &part)
Definition: MCTruth.h:77
double fT0
Central t position (ns) in world coordinates.
Definition: Run.h:30
int fTDist
How to distribute t (gaus, or uniform)
ProductID put(std::unique_ptr< PROD > &&product)
Definition: Event.h:102
double fRockDensity
base_engine_t & getEngine() const
int fPDG
PDG code of particles to generate.
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:42
void beginJob()
Definition: Breakpoints.cc:14
std::string DetectorName() const
Returns a string with the name of the detector, as configured.
double fPhimax
Maximum phi.
single particles thrown at the detector
Definition: MCTruth.h:24
T get(std::string const &key) const
Definition: ParameterSet.h:231
TString part[npart]
Definition: Style.C:32
std::string fInputFile3
Input File 3.
double fPhimin
Minimum phi.
double fChargeRatio
Charge ratio of particle / anti-particle.
std::string fInputFile2
Input File 2.
An art service to assist in the distribution of guaranteed unique seeds to all engines within an art ...
Framework includes.
int figflag
If want sampled from sphere or parallelepiped.
module to produce single or multiple specified particles in the detector
double fYmin
Minimum Y position.
T * make(ARGS...args) const
ifstream in
Definition: comparison.C:7
double fZmin
Minimum Z position.
double fSigmaT
Variation in t position (ns)
#define LOG_DEBUG(id)
double fThetamax
Maximum theta.
double fXmin
Minimum X position.
TCEvent evt
Definition: DataStructs.cxx:5
Event generator information.
Definition: MCTruth.h:30
Float_t e
Definition: plot.C:34
Namespace collecting geometry-related classes utilities.
Event Generation using GENIE, cosmics or single particles.
std::string fInputFile1
Input File 1.
art framework interface to geometry description
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
double fXmax
Maximum X position.