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

mscat.cxx

Go to the documentation of this file.
00001 /*
00002         test multiple scattering and  SlabWorld
00003  $Id: mscat.cxx,v 1.2 2001/10/06 14:18:53 burnett Exp $
00004 
00005 */
00006 
00007 #include "BaseApp.h"
00008 #include "SlabWorld.h"
00009 #include "SmplStat.h"
00010 #include "gismo/Units.h"
00011 #include "geometry/CoordTransform.h"
00012 #include "gismo/EGSInteractor.h"
00013 #include "gismo/GheishaInteractor.h"
00014 
00015 
00016 #include <iomanip>
00017 SampleStatistic thetaSquared;
00018 SampleStatistic energyLoss;
00019 SampleStatistic multiplicity;
00020 SampleStatistic energyDeposited;
00021 
00022 unsigned long numberOfEvents=1000;  // default number of events
00023 unsigned long number=0;
00024 float   pBeam = 2.0;  // initial momentem
00025 float   thickness = 1.0;  // thickness of slab
00026 const char* materialName = "Al";
00027 const char* particleName = "mu+";
00028 float   incidentAngle=0.;
00029 
00030 Vector pinit(0,0,pBeam);
00031 
00032 float   sigmaMS;            // expected projected MS sigma
00033 float   expectedEloss; //
00034 float   initialEnergy;
00035 //ofstream fout("/annih.out");  //temp
00036 
00037 using namespace std;
00038 
00039 template<class T> inline T sqr(T x){return x*x;}
00040 
00041 void WARNING(const char * text){cerr << "WARNING: " << text << '\n';}
00042 void FATAL(const char * text){
00043    cerr << "FATAL error: " <<text << '\n'; 
00044    cerr << "type help for instructions\n";
00045    exit(-1);}
00046 
00047 const char* help=
00048 "Help for the gismo test program mscat:\n\n"
00049 "   mscat [[[[particleName] materialName] eventCount] pBeam ] materialsize]\n\n"
00050 "where:\n"
00051 "   particleName [mu+] is the name of a particle to interact:\n"
00052 "                 (\"decay list\" for a list)\n"
00053 "   materialName [Al] the name of a PEGS4 material file, e.g. Al.mat\n"
00054 "   eventCount   [1] number of events to generate\n"
00055 "   pBeam        [2.0 GeV] the beam momentum\n"
00056 "   thickness    [1.0 cm] the amount of material\n";
00057 
00058 
00059 
00060 //-------------------------------------------------------
00061 // Detector class that measures the particles emerging from the target
00062 class Spectrometer : public Detector
00063 {
00064 public:
00065     Spectrometer():Detector(){}
00066     void score(MCParticle*);
00067     void clear(){mult=0; m_edep=0;}
00068     void generateResponse(){};
00069 private:
00070     int mult;     // count no of hits in this event
00071     float m_edep;   // cumulative deposited energy
00072 };
00073 
00074 void Spectrometer::score( MCParticle *p)
00075 {
00076   if( p->charge()==0 || p->pTot()==0 ) return;
00077   multiplicity += ++mult;
00078   float deltaE = initialEnergy - p->e();
00079   m_edep += deltaE;
00080 
00081   if( mult > 1 ) return;       // only use first particle
00082 
00083   double theta = pinit.dot(*p)/p->momentum().mag()/pBeam;
00084   theta = theta>=1? 0 : acos(theta);
00085   thetaSquared += sqr(theta);
00086 
00087   energyLoss += deltaE;
00088 
00089 }
00090 
00091 //-------------------------------------------------------
00092 // Detector class to instrument the target
00093 class Calorimeter: public Detector // this to accumulate energy in the slab
00094 {
00095 public:
00096     Calorimeter():Detector(){}
00097     void score(MCParticle* p){
00098         m_e += p->energyLoss(); 
00099         ++m_n;
00100     }
00101     void clear(){ m_n=0; m_e=0;}
00102     void generateResponse(){ 
00103         energyDeposited += m_e;
00104     }
00105 private:
00106     float m_e;
00107     int m_n;
00108 };
00109 
00110 
00111 //-------------------------------------------------------
00112 
00113 
00114 class TestApp :  public BaseApp
00115 {
00116   public:
00117    void endEvent()
00118    { if( eventNumber%10==0 )
00119         //              fout << eventNumber << ' ';
00120                 number++;  // so global is accessible
00121      //fout << *generator;
00122    }
00123    void init(ostream& =cout);
00124    void last(ostream& = cout);
00125 };
00126 
00127 void TestApp::init(ostream& cout)
00128 {
00129 
00130         // define the "beam"
00131         pinit.rotateY(incidentAngle);
00132         setBeam(particleName, pinit, Point(0,0,-1));
00133 
00134         // define the geometry
00135         SlabWorld* w = new SlabWorld;
00136         setWorld(w);
00137         w->addSlab(thickness,materialName,new Calorimeter );
00138         w->addSlab(0.1f,"vacuum",new Spectrometer() );
00139 
00140 
00141         // calculate expected multiple scattering sigma and eloss
00142         GParticle p(particleName);
00143         p.setMomentum(pinit);
00144         initialEnergy = p.e();
00145         double ptotal = p.pTot();
00146         double beta   = ptotal/initialEnergy;
00147         double eta      = ptotal/p.mass();
00148 
00149         Material& mat = *Material::hatch(materialName);
00150         double X0 = mat.radiationLength();
00151         double step = thickness/p.cosTheta();
00152         double x = step/X0;
00153 
00154         expectedEloss = step * mat.dedx(beta,eta) * sqr(p.charge());
00155 
00156         sigmaMS = Units::fromMeV(13.6f)
00157                 * sqr(p.charge()) * sqrt(x) * (1.+ 0.038*log(x))
00158                   /(beta* ptotal);
00159 
00160         cout << "\n\tSimple gismo scattering test";
00161         cout << "\n\t============================\n";
00162         static int wd=25;
00163         cout <<        std::setw(wd) << "particle: " << particleName 
00164                 << '\n' << std::setw(wd) << "momentum: " << ptotal << " GeV"
00165                 << '\n' << std::setw(wd) << "KE: " << (p.e()-p.mass()) << " GeV"
00166                 << '\n' << std::setw(wd) << "incident angle: " << incidentAngle 
00167                 << '\n' << std::setw(wd) << "material: " << materialName
00168                 << '\n' << std::setw(wd) << "thickness: " <<thickness << " cm"
00169                 << '\n' << std::setw(wd) << "Radiation length: " << X0 
00170                 << '\n' << std::setw(wd) << "expected m.s. sigma: " << sigmaMS 
00171                 << '\n' << std::setw(wd) << "expected E loss: " << expectedEloss*1e3 <<" MeV"
00172 //              << '\n' << std::setw(wd) << "Interactions performed by: "<< p.interactor()->className()
00173 
00174                 << ", which is "<< expectedEloss*1e3/step/mat.density() <<" MeV/g\n";
00175         cout << "\nbegin run for "<< numberOfEvents<<" events\n";
00176 }
00177 void TestApp::last(ostream& cout)
00178 {
00179    const int width=45;
00180    if( thetaSquared.samples()>0)
00181    {
00182         cout << std::setw(width) << "Mean square angular deviation / expected: "
00183         << thetaSquared.mean() / (2*sqr(sigmaMS))
00184         << " +/- " << thetaSquared.stdDev()
00185             /sqrt((double)thetaSquared.samples())
00186                          /(2*sqr(sigmaMS))
00187         << '\n';
00188         cout <<  std::setw(width) <<"Average  energy loss / expected: "
00189         << energyLoss.mean() / expectedEloss
00190         << " +/- " << energyLoss.stdDev()
00191             / sqrt((double)energyLoss.samples())/expectedEloss
00192         << '\n';
00193         cout <<  std::setw(width) << "energy loss fraction fluctuation: " 
00194              <<  energyLoss.stdDev()/energyLoss.mean() <<'\n';
00195     }
00196         cout << std::setw(width) <<"Average Multiplicity emerging: " << multiplicity.mean() << '\n';
00197         cout << std::setw(width) <<"Mean Energy Deposited: " << energyDeposited.mean()*1e3 
00198              << " MeV, or "<< energyDeposited.mean()*1e6/thickness*1e-4 << " keV/um"<<'\n';
00199         cout << std::setw(width) << "Energy dep. fractional rms: "
00200              <<  energyDeposited.stdDev()/energyDeposited.mean() <<'\n';
00201 }
00202 
00203 //-------------------------------------------------------
00204 int main(int argc,  char* argv[])
00205 {
00206 
00207   if( argc>1 ){
00208      particleName=argv[1];
00209      if( strcmp(particleName, "help")==0 ) {
00210         cout << help;
00211         return 0;
00212      }
00213   }
00214   if( argc>2 ) materialName=argv[2];
00215   if( argc>3 ) numberOfEvents =  atoi(argv[3]); 
00216   if( argc>4 ) {pBeam = atof(argv[4]); pinit=Vector(0,0,pBeam);}
00217   if( argc>5 ) {thickness = atof(argv[5]);}
00218   
00219   TestApp tester;
00220 
00221   tester.addInteractor(new EGSInteractor("electromagnetic") );
00222   tester.addInteractor(new GheishaInteractor("hadronic"));
00223 
00224   tester.init();
00225   tester.run(numberOfEvents);
00226   tester.last();
00227   return 0;
00228 }
00229 
00230 
00231 

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