Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

shower.cxx

Go to the documentation of this file.
00001 // Simple test of showering
00002 //
00003 //  Try to contain a gamma ray in a very large medium
00004 // $Id: shower.cxx,v 1.2 2001/10/06 14:18:53 burnett Exp $
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;  // default number of events
00023 float           pBeam =         2.0f; //2.0;  // initial momentem
00024 float           cut   =         0.00001f; //2.0;  // k.e. cutOff
00025 float           thick =         10000.0f;  // thickness of slab
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;   // event counter
00054  static float e_dedx;   // de/dx energy deposited
00055  static float e_gamma;  // gamma energy (interacted or stopped)
00056  static float e_nucl;   // nuclear energy (interacted)
00057  static float e_neutr;  // neutrino energy (not rejestered)
00058  static float e_stop;   // stopped particle energy (not rejestered)
00059 private:
00060  int mult;     // count no of hits in this event
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 // Get the energy loss due neutrino's which leave
00093   if(trackId == nueId || trackId == numId) {
00094       e_neutr += p->e();
00095       return;
00096    }
00097 
00098 // Get the energy loss due to ionization (dE/dX).
00099    if( p->charge())  e_dedx += p->energyLoss();
00100 
00101 // Get the energy loss due to stopped particles (mostly masses)
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 // Get the energy loss due to gamma's which  stop via photo-electric.
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 // If its a interacting hadron correct for nuclear fragments. The correction is
00119 // done by adding the kinetic energy of the incomming paritcle to the energy loss
00120 // and then subtracting the energy (or kinetic energy in the case of p or n) of all
00121 // daughters recognized by gismo.
00122 // NOTE: remove this code whennuclear fragmenets are tracked by gismo
00123 // Deutrons, tritons, and alphas now tracked... wba 15-june-95
00124 
00125     if(trackId != eplusId && trackId != eminusId && trackId != gammaId
00126        && p->status() == MCParticle::INTERACTED) { // Must be hadronic
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();  // override virtual base class
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         // start the particle in the middle of the layer
00164         setBeam(particleName, Vector(0,0,pBeam), Point(0,0,thick/2));
00165 
00166         // define the geometry
00167         SlabWorld* w = new SlabWorld;
00168         setWorld(w);
00169         w->addSlab(thick,materialName,new ShowerDetector());
00170 
00171 
00172         // create particle and medium just to print out parameters
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 

Generated at Wed Nov 21 12:20:26 2001 by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000