157 #include <sys/stat.h> 174 #include "cetlib_except/exception.h" 189 #include "TVector3.h" 190 #include "TDatabasePDG.h" 198 #include "CLHEP/Random/RandFlat.h" 199 #include "CLHEP/Random/RandGaussQ.h" 205 namespace simb {
class MCTruth; }
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 );
230 void sampling(
double &
E,
double &theta,
double &phi,
double &dep );
233 static const int kGAUS = 1;
288 double Energy, phi, theta, dep,
Time;
289 double Momentum, px0, py0,
pz0;
290 double x0, y0,
z0, cx, cy, cz;
298 double spmu[121][62][51];
300 double depth[360][91];
310 unsigned int NEvents = 0;
335 this->reconfigure(pset);
340 ->createEngine(*
this, pset,
"Seed");
342 produces< std::vector<simb::MCTruth> >();
343 produces< sumdata::RunData, art::InRun >();
358 fPDG = p.
get<
int >(
"PDG");
359 fChargeRatio = p.
get<
double >(
"ChargeRatio");
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");
366 fCavernAngle = p.
get<
double >(
"CavernAngle");
367 fRockDensity = p.
get<
double >(
"RockDensity");
369 fEmin = p.
get<
double >(
"Emin");
370 fEmax = p.
get<
double >(
"Emax");
372 fThetamin = p.
get<
double >(
"Thetamin");
373 fThetamax = p.
get<
double >(
"Thetamax");
375 fPhimin = p.
get<
double >(
"Phimin");
376 fPhimax = p.
get<
double >(
"Phimax");
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");
386 fT0 = p.
get<
double >(
"T0");
387 fSigmaT = p.
get<
double >(
"SigmaT");
388 fTDist = p.
get<
int >(
"TDist");
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" );
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";
464 run.
put(std::move(runcol));
467 s_hor = (fZmax-fZmin)*(fXmax-fXmin);
469 s_ver1 = (fXmax-fXmin)*(fYmax-fYmin);
471 s_ver2 = (fZmax-fZmin)*(fYmax-fYmin);
475 initialization(fThetamin,fThetamax,fPhimin,fPhimax,figflag,s_hor,s_ver1,s_ver2,FI );
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;
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;
528 std::unique_ptr< std::vector<simb::MCTruth> > truthcol(
new std::vector<simb::MCTruth>);
534 SampleOne(NEvents,truth);
538 truthcol->push_back(truth);
540 evt.
put(std::move(truthcol));
553 CLHEP::HepRandomEngine &engine = rng->
getEngine();
554 CLHEP::RandFlat flat(engine);
555 CLHEP::RandGaussQ gauss(engine);
563 sampling( Energy, theta, phi, dep );
565 theta = theta* M_PI/180;
579 int trackid = -1*(i+1);
580 std::string primary(
"primary");
585 double ChargeCheck = 1./ ( 1 + fChargeRatio );
586 double pdgfire = flat.fire();
587 if ( pdgfire < ChargeCheck ) PdgCode=-PdgCode;
589 static TDatabasePDG pdgt;
590 TParticlePDG* pdgp = pdgt.GetParticle(PdgCode);
591 if (pdgp) m = pdgp->Mass();
597 Time = gauss.fire(fT0, fSigmaT);
600 Time = fT0 + fSigmaT*(2.0*flat.fire()-1.0);
605 cx = -sin(theta)*sin(phi);
607 cz = +sin(theta)*cos(phi);
608 Momentum = std::sqrt(Energy*Energy-m*m);
612 TLorentzVector pvec(px0, py0, pz0, Energy );
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;
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;
630 if( cx >= 0 ) x0 = fXmin;
632 y0 = (fYmax - fYmin)*flat.fire() + fYmin;
633 z0 = (fZmax - fZmin)*flat.fire() + fZmin;
636 TLorentzVector pos(x0, y0, z0, Time);
654 theta = theta * 180/M_PI;
655 phi = phi * 180/M_PI;
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 )
701 int lineNumber = 0, index = 0;
702 char inputLine[10000];
703 std::string fROOTfile;
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;
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;
716 if (!file1.good() )
throw cet::exception(
"MUSUNGen") <<
"\nFile1 " << fInputFile1 <<
" not found in FW_SEARCH_PATH or at " << fInputDir <<
"\n\n";
718 while( file1.good() ) {
720 file1.getline( inputLine, 9999 );
722 token = strtok( inputLine,
" " );
723 while( token != NULL ) {
725 fmu[index][lineNumber] = atof( token );
726 token = strtok( NULL,
" " );
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";
745 int i1 = 0, i2 = 0, i3 = 0;
747 while( file2.good() ) {
749 file2.read((
char *)(&readVal),
sizeof(
float));
750 spmu[i1][i2][i3] = readVal;
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;
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;
777 if (!file3.good() )
throw cet::exception(
"MUSUNGen") <<
"\nFile3 " << fInputFile3 <<
" not found in FW_SEARCH_PATH or at " << fInputDir <<
"\n\n";
779 lineNumber = index = 0;
780 while( file3.good() ) {
782 file3.getline( inputLine, 9999 );
784 token = strtok( inputLine,
" " );
785 while( token != NULL ) {
787 depth[index][lineNumber] = atof( token );
788 token = strtok( NULL,
" " );
808 ph1 = M_PI/180.*phi1;
809 ph2 = M_PI/180.*phi2;
814 double theta = theta1;
818 while( theta < theta2-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);
827 if( ic2 > 91 ) ic2 = 91;
828 if( ic1 < 1 ) ic1 = 1;
832 while( phi < phi2-dp/2. ) {
838 double phi0 = M_PI / 180. * (phi + fCavernAngle);
840 double asv1 = asv01 * fabs(cos(phi0));
841 double asv2 = asv02 * fabs(sin(phi0));
842 double asv0 = ash + asv1 + asv2;
846 int ip1 = (phi + 0.999);
848 if( ip2 > 360 ) ip2 = 1;
849 if( ip1 < 1 ) ip1 = 360;
852 for(
int ii=0; ii<4; ii++ ) {
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 > 1
e-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 " 862 sp1 = sp1 + pow(10.,fmu[ip1+iip-1][ic1+iic-1]) / 4;
869 sc = sc + sp1 * fl * dp * M_PI / 180. * sin(theta0) * dc * M_PI / 180.;
876 theta = theta + dc / 2.;
880 for(
int ipc1 = 0; ipc1 < ipc; ipc1++ )
881 fnmu[ipc1] = fnmu[ipc1] / fnmu[ipc-1];
888 void MUSUN::sampling(
double &
E,
double &theta,
double &phi,
double &dep )
892 CLHEP::HepRandomEngine &engine = rng->
getEngine();
893 CLHEP::RandFlat flat(engine);
894 CLHEP::RandGaussQ gauss(engine);
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] ) {
904 }
else if ( xfl > fnmu[hiIndex] ) {
907 }
else if ( xfl > fnmu[i-1] && xfl <= fnmu[i] )
909 while( !foundIndex ) {
914 i = (loIndex + hiIndex)/2;
916 if( xfl > fnmu[i-1] && xfl <= fnmu[i] )
920 double xfl = flat.fire();
922 while ( xfl > fnmu[i] ) ++i;
928 theta = the1 + ((double)ic+xfl);
930 phi = ph1 + ((double)ip+xfl);
931 if ( phi > 360 ) phi = phi -360;
932 dep = depth[ip][ic] * fRockDensity;
934 int ic1 = cos(M_PI/180.*theta) * 50.;
939 int ip1 = dep / 200. - 16;
947 loIndex = 0, hiIndex = 120;
948 int j = (loIndex+hiIndex)/2;
950 if( xfl < spmu[loIndex][ip1][ic1] ) {
953 }
else if ( xfl > spmu[hiIndex][ip1][ic1] ) {
956 }
else if ( xfl > spmu[j-1][ip1][ic1] && xfl <= spmu[j][ip1][ic1] )
958 while( !foundIndex ) {
959 if( xfl < spmu[j][ip1][ic1] )
963 j = (loIndex + hiIndex)/2;
965 if( xfl > spmu[j-1][ip1][ic1] && xfl <= spmu[j][ip1][ic1] )
970 while ( xfl > spmu[j][ip1][ic1] ) ++j;
973 double En1 = 0.05 * (j-1);
974 double En2 = 0.05 * (j);
975 E = pow(10.,En1 + (En2 - En1)*flat.fire());
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)
void SetOrigin(simb::Origin_t origin)
double fEmin
Minimum Kinetic Energy (GeV)
double fThetamin
Minimum theta.
std::string fInputDir
Input Directory.
art::ProductID put(std::unique_ptr< PROD > &&)
void Add(simb::MCParticle &part)
double fT0
Central t position (ns) in world coordinates.
int fTDist
How to distribute t (gaus, or uniform)
ProductID put(std::unique_ptr< PROD > &&product)
base_engine_t & getEngine() const
int fPDG
PDG code of particles to generate.
#define DEFINE_ART_MODULE(klass)
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
T get(std::string const &key) const
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 ...
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
double fZmin
Minimum Z position.
double fSigmaT
Variation in t position (ns)
double fThetamax
Maximum theta.
double fXmin
Minimum X position.
Event generator information.
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
double fXmax
Maximum X position.