Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

CRYGen.cxx

Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 #include "EventGenerator/Cosmics/CRYGen.h"
00009 #include <cmath>
00010 #include <iostream>
00011 // CRY include files
00012 #include "CRYSetup.h"
00013 #include "CRYParticle.h"
00014 #include "CRYGenerator.h"
00015 // ROOT include files
00016 #include "TRandom.h"
00017 // NOvA include files
00018 #include "EventGenerator/evgen.h"
00019 #include "Geometry/geo.h"
00020 #include "RawData/DAQHeader.h"
00021 #include "Simulation/MCTruth.h"
00022 using namespace evgen;
00023 
00024 //......................................................................
00025 
00029 static double gsUniformRandom() 
00030 {
00031   return gRandom->Uniform();
00032 }
00033 
00034 //......................................................................
00035 
00036 CRYGen::CRYGen(int idet, int runno) :
00037   fGeom(geo::Geometry::Instance(runno, idet))
00038 {
00039   // Apply an energy threshold to avoid extremely long lists of
00040   // irrelevant particles
00041   fEthresh = 50.0E-3; // GeV
00042 
00043   // By default, sample for 30 usec, 10 usec before spill, 20 usec
00044   // after
00045   fSampleTime =  30.0E-6;
00046   fToffset    = -10.0E-6;
00047 
00048   // Construct the CRY generator
00049   std::string config("date 1-1-2014 "
00050                      "returnGammas 1 "
00051                      "returnElectrons 1 "
00052                      "returnMuons 1 "
00053                      "returnPions 1 "
00054                      "returnNeutrons 1 "
00055                      "returnProtons 1 ");
00056   
00057   if (idet == rawdata::kIPND) {
00058     config += 
00059       "latitude 41.8 "
00060       "altitude 0 "
00061       "subboxLength 50 ";
00062   }
00063   if (idet == rawdata::kNear)  {
00064     config += 
00065       "latitude 41.8 "
00066       "altitude 0 "
00067       "subboxLength 300 ";
00068   }
00069   if (idet == rawdata::kFar) {
00070     config += 
00071       "latitude 48.3 "
00072       "altitude 0 "
00073       "subboxLength 300 ";
00074   }
00075 
00076   // Find the pointer to the CRY data tables
00077   std::string crydatadir(getenv("CRYDATADIR"));
00078 
00079   // Construct the event generator object
00080   fSetup = new CRYSetup(config, crydatadir);
00081   fSetup->setRandomFunction(gsUniformRandom);
00082   
00083   fGen = new CRYGenerator(fSetup);
00084   fEvt = new std::vector<CRYParticle*>;
00085 }
00086 
00087 //......................................................................
00088 
00089 void CRYGen::Sample(sim::MCTruth& mctruth, double* w)
00090 {
00091   double tstart;        // Generator time at start of sample
00092   TDatabasePDG pdgdata; // Database of PDG information
00093 
00094   tstart = fGen->timeSimulated();
00095   while (1) {
00096     fEvt->clear();
00097     fGen->genEvent(fEvt);
00098     
00099     mctruth.Clear();
00100     for (unsigned int i=0; i<fEvt->size(); ++i) {
00101       CRYParticle* cryp = (*fEvt)[i];
00102       
00103       // Pull out the PDG code
00104       int pdg = cryp->PDGid();
00105 
00106       // Get the energies of the particles
00107       double ke = cryp->ke()*1.0E-3; // MeV to GeV conversion
00108       if (ke<fEthresh) continue;
00109 
00110       double m    = pdgdata.GetParticle(pdg)->Mass(); // In GeV
00111       double etot = ke + m;
00112       double ptot = etot*etot-m*m;
00113       if (ptot>0.0) ptot = sqrt(ptot);
00114       else          ptot = 0.0;
00115       
00116       // Sort out the momentum components. Remember that the NOvA
00117       // frame has y up and z along the beam. So uvw -> zxy
00118       double px = ptot * cryp->v();
00119       double py = ptot * cryp->w();
00120       double pz = ptot * cryp->u();
00121       
00122       // Particle start position. CRY distributes uniformly in x-y
00123       // plane at fixed z, where z is the vertical direction. This
00124       // requires some offsets and rotations to put the particles at
00125       // the surface in the NOvA geometry as well as some rotations
00126       // since the NOvA coordinate frame has y up and z along the
00127       // beam.
00128       double vx = cryp->y()*100.0;
00129       double vy = cryp->z()*100.0 + fGeom.SurfaceY();
00130       double vz = cryp->x()*100.0 + 0.5*fGeom.DetLength();
00131       double t  = cryp->t()-tstart + fToffset; // seconds
00132 
00133       // Project backward to edge of world volume
00134       double xyz[3]  = { vx,  vy,  vz};
00135       double xyzo[3];
00136       double dxyz[3] = {-px, -py, -pz};
00137       double x1, x2;
00138       double y1, y2;
00139       double z1, z2;
00140       fGeom.WorldBox(&x1, &x2, &y1, &y2, &z1, &z2);
00141       geo::ProjectToBoxEdge(xyz, dxyz, x1, x2, y1, y2, z1, z2, xyzo);
00142       vx = xyzo[0];
00143       vy = xyzo[1];
00144       vz = xyzo[2];
00145       
00146       // Boiler plate...
00147       int istatus    =  1;
00148       int imother1   = kCosmicRayGenerator;
00149       int imother2   = kCosmicRayGenerator;
00150       int idaughter1 = -1;
00151       int idaughter2 = -1;
00152       
00153       // Push the particle onto the stack
00154       TParticle p(pdg,
00155                   istatus,
00156                   imother1, imother2,
00157                   idaughter1, idaughter2,
00158                   px, py, pz,
00159                   etot,
00160                   vx, vy, vz, t);
00161       mctruth.Add(p);
00162     } // Loop on particles in event
00163     
00164     // Check if we're done with this time sample
00165     if (fGen->timeSimulated()-tstart > fSampleTime) break;
00166     
00167   } // Loop on events simulated
00168 
00169   // Check if this time slice passes selection criteria
00170   // TODO
00171   if (w) *w = 1.0;
00172 }

Generated on Mon Dec 1 02:35:17 2008 for NOvA Offline by  doxygen 1.3.9.1