00001
00002
00003
00004
00005 #include "BaseApp.h"
00006 #include "SlabWorld.h"
00007 #include "SmplStat.h"
00008
00009 #include "gismo/Interactor.h"
00010 #include "geometry/Box.h"
00011 #include "gismo/EGSInteractor.h"
00012 #include "gismo/GheishaInteractor.h"
00013
00014 # include <iomanip>
00015
00016 #ifdef _MSC_VER
00017 using namespace std;
00018 #endif
00019
00020 const char* particleName= "gamma";
00021 const char* materialName= "Pb";
00022 unsigned long numberOfEvents= 10;
00023 float pBeam = 2.0f;
00024 float cut = 0.00001f;
00025 float thick = 10000.0f;
00026
00027 SampleStatistic energyStat;
00028
00029 void WARNING(const char * text)
00030 { cerr << "WARNING: " << text << '\n';}
00031 void FATAL(const char * text){
00032 cerr << "FATAL error: " <<text << '\n';
00033 cerr << "use parameter \"help\" for instructions\n";
00034 exit(-1);}
00035
00036 const char* help=
00037 "Help for the test program shower:\n\n"
00038 " shower [[[[particleName] materialName] eventCount] pBeam]keCutOff]\n\n"
00039 "where:\n"
00040 " particleName [default gamma] is the name of a particle to interact:\n"
00041 " (\"decay list\" for a list)\n"
00042 " materialName [Al] the name of a PEGS4 material file, e.g. Al.mat\n"
00043 " eventCount [10] number of events to generate\n"
00044 " pBeam [2.0 GeV] the beam momentum\n"
00045 " keCutOff [.00001 GeV] the kinetic energy cutoff\n";
00046
00047 class ShowerDetector : public Detector
00048 {
00049 public:
00050 ShowerDetector():Detector(){}
00051 void score(MCParticle*);
00052 void clear(){e_dedx = 0; e_gamma = 0; e_nucl = 0; e_neutr = 0; e_stop=0;}
00053 static int evtNum;
00054 static float e_dedx;
00055 static float e_gamma;
00056 static float e_nucl;
00057 static float e_neutr;
00058 static float e_stop;
00059 private:
00060 int mult;
00061
00062 };
00063 int ShowerDetector::evtNum = 0;
00064 float ShowerDetector::e_dedx=0;
00065 float ShowerDetector::e_gamma=0;
00066 float ShowerDetector::e_nucl=0;
00067 float ShowerDetector::e_neutr=0;
00068 float ShowerDetector::e_stop=0;
00069
00070 #include "gismo/PDT.h"
00071 void ShowerDetector::score( MCParticle *p)
00072 {
00073 static long gammaId = -1;
00074 static long eplusId, eminusId, pId, nId, deutrId, tritnId, alphaId, nueId, numId;
00075
00076 if(gammaId == -1) {
00077 PDT *thePDT = GParticle::thePDT();
00078 gammaId = (thePDT->lookUp("gamma"))->idCode();
00079 eplusId = (thePDT->lookUp("e+"))->idCode();
00080 eminusId= (thePDT->lookUp("e-"))->idCode();
00081 nueId = (thePDT->lookUp("nu_e"))->idCode();
00082 numId = (thePDT->lookUp("nu_mu"))->idCode();
00083 pId = (thePDT->lookUp("p"))->idCode();
00084 nId = (thePDT->lookUp("n"))->idCode();
00085 deutrId = (thePDT->lookUp("deutron"))->idCode();
00086 tritnId = (thePDT->lookUp("triton"))->idCode();
00087 alphaId = (thePDT->lookUp("alpha"))->idCode();
00088 }
00089 long trackId = p->idCode();
00090 int numProd = p->numChildren();
00091
00092
00093 if(trackId == nueId || trackId == numId) {
00094 e_neutr += p->e();
00095 return;
00096 }
00097
00098
00099 if( p->charge()) e_dedx += p->energyLoss();
00100
00101
00102 if(p->status() == MCParticle::STOPPED) {
00103 if(trackId == nId ) e_stop += p->e() - p->mass();
00104 else if(trackId != pId && trackId != deutrId &&
00105 trackId != tritnId && trackId != alphaId &&
00106 trackId != eminusId && trackId != eplusId)
00107 e_stop += p->e();
00108 }
00109
00110 if(trackId == gammaId) {
00111 if(p->status() == MCParticle::INTERACTED && numProd == 1) {
00112 GParticle *kid = p->child(0);
00113 e_gamma += p->e() - (kid->e() - kid->mass());
00114 }
00115 }
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125 if(trackId != eplusId && trackId != eminusId && trackId != gammaId
00126 && p->status() == MCParticle::INTERACTED) {
00127
00128 if(trackId == pId || trackId == nId ||
00129 trackId == deutrId || trackId == tritnId ||
00130 trackId == alphaId ) e_nucl += p->e() - p->mass();
00131 else e_nucl += p->e();
00132
00133 for(int i=0; i<numProd; i++) {
00134 GParticle *prod = p->child(i);
00135 if(!prod) break;
00136
00137 long prodId = prod->idCode();
00138 if(prodId == pId || prodId == nId ||
00139 prodId == deutrId || prodId == tritnId ||
00140 prodId == alphaId ) e_nucl -= prod->e() - prod->mass();
00141 else e_nucl -= prod->e();
00142 }
00143 }
00144 return;
00145 }
00146
00147
00148
00149 class ShowerTest : public BaseApp
00150 {
00151 public:
00152 void endEvent();
00153 void init(ostream& =cout);
00154 void last(ostream& = cout);
00155
00156 };
00157
00158 void ShowerTest::init(ostream& cout)
00159 {
00160 Material::addPath("../PEGS4:.");
00161
00162
00163
00164 setBeam(particleName, Vector(0,0,pBeam), Point(0,0,thick/2));
00165
00166
00167 SlabWorld* w = new SlabWorld;
00168 setWorld(w);
00169 w->addSlab(thick,materialName,new ShowerDetector());
00170
00171
00172
00173 MCParticle p(particleName);
00174 p.setMomentum(Vector(0,0,pBeam));
00175 Medium med(0,new Box(1,1,1),materialName);
00176 Material& mat = med.material();
00177
00178
00179 cout << "\tGismo Showering test\n";
00180 cout << "particle: " << particleName
00181 << "\n momentum\t" << p.pTot() << " GeV "
00182 << "\n E\t" << p.e() << " GeV"
00183 << "\n KE\t" << p.e()-p.mass() << " GeV"
00184 ;
00185 Material::printAll(cout);
00186 cout << "\nmaterial: " << materialName
00187 << "\n Rad length\t" << mat.radiationLength() << '\n'
00188 ;
00189 Interactor& itr = *p.interactor();
00190 float ecutMin = itr.ecut(&p,&med) - p.mass();
00191 if(med.kECutOff() > ecutMin) ecutMin = med.kECutOff();
00192 cout << "Interactions performed by the class \"" << itr.className() <<'"'
00193 << "\n Int length\t" << itr.interactionLength(&p,&med) << " cm"
00194 << "\n maxStep\t" << itr.maxStepSize(&p,&med) << " cm"
00195 << "\n k.e.cutOff\t" << ecutMin << " GeV"
00196 ;
00197
00198 cout << "\n\nbegin run for "<< numberOfEvents<< " events "<< '\n';
00199 cout << "\n\n\t\t Energy Audit Table \n";
00200 cout << "Evt.No. \tdE/dX \tGamma \tNeutrino \tNuclear \tStopped \tTotal \n";
00201 }
00202 void ShowerTest::endEvent()
00203 {
00204 ShowerDetector::evtNum++;
00205
00206 float e_tot = ShowerDetector::e_dedx + ShowerDetector::e_gamma +
00207 ShowerDetector::e_neutr + ShowerDetector::e_nucl +
00208 ShowerDetector::e_stop;
00209
00210 energyStat += e_tot;
00211 int old_flags = cout.flags(ios::fixed);
00212 int old_precision = cout.precision(3);
00213 cout << setw(5) << ShowerDetector::evtNum
00214 << setw(16) << ShowerDetector::e_dedx
00215 << setw(16) << ShowerDetector::e_gamma
00216 << setw(16) << ShowerDetector::e_neutr
00217 << setw(16) << ShowerDetector::e_nucl
00218 << setw(16) << ShowerDetector::e_stop
00219 << setw(16) << e_tot << endl;
00220 cout.flush();
00221 cout.flags(old_flags);
00222 cout.precision(old_precision);
00223
00224 }
00225 void ShowerTest::last(ostream& cout)
00226 {
00227 if( energyStat.samples()>0)
00228 {
00229 cout << "\nenergy: \tmean = "<< energyStat.mean() << '\n'
00230 << "\t\trms = "<< energyStat.stdDev()
00231 <<'\n';
00232 cout.flush();
00233 }
00234 }
00235
00236
00237 int main(int argc, char* argv[])
00238 {
00239
00240 if( argc>1 ) particleName = argv[1];
00241 if( strcmp(particleName, "help")==0 ) {cout << help; return 0;}
00242 if( argc>2 ) materialName = argv[2];
00243 if( argc>3 ) numberOfEvents = atoi(argv[3]);
00244 if( argc>4 ) pBeam = atof(argv[4]);
00245 if( argc>5 ) cut = atof(argv[5]);
00246
00247 ShowerTest tester;
00248 tester.addInteractor(new EGSInteractor("electromagnetic") );
00249 #ifndef NOGHEISHA
00250 tester.addInteractor(new GheishaInteractor("hadronic") );
00251 #endif
00252 tester.init();
00253 tester.world().setKECutOff(cut);
00254
00255 tester.run(numberOfEvents);
00256 tester.last();
00257
00258
00259 return 0;
00260 }
00261
00262