// // ******************************************************************** // * License and Disclaimer * // * * // * The Geant4 software is copyright of the Copyright Holders of * // * the Geant4 Collaboration. It is provided under the terms and * // * conditions of the Geant4 Software License, included in the file * // * LICENSE and available at http://cern.ch/geant4/license . These * // * include a list of copyright holders. * // * * // * Neither the authors of this software system, nor their employing * // * institutes,nor the agencies providing financial support for this * // * work make any representation or warranty, express or implied, * // * regarding this software system or assume any liability for its * // * use. Please see the license in the file LICENSE and URL above * // * for the full disclaimer and the limitation of liability. * // * * // * This code implementation is the result of the scientific and * // * technical work of the GEANT4 collaboration. * // * By using, copying, modifying or distributing the software (or * // * any work based on the software) you agree to acknowledge its * // * use in resulting scientific publications, and indicate your * // * acceptance of all terms of the Geant4 Software license. * // ******************************************************************** // // // $Id: G4ComplexTest.cc,v 1.21 2006/06/29 19:43:49 gunter Exp $ // GEANT4 tag $Name: geant4-09-03-cand-01 $ // // ------------------------------------------------------------------- // GEANT 4 class file --- Copyright CERN 1998 // CERN Geneva Switzerland // // // File name: G4ComplexTest // This test provide AlongStepDoIt and PostStepDoIt // tests for electromagnetic processes. The input // data have to be describe in ASCII file // // Author: V.Ivanchenko on base of Maria Grazia Pia tests // // Creation date: 8 May 2001 // // Modifications: // // ------------------------------------------------------------------- #include "globals.hh" #include "G4ios.hh" #include #include #include "G4ProductionCuts.hh" #include "G4ProductionCutsTable.hh" #include "G4Material.hh" #include "G4MaterialCutsCouple.hh" #include "G4VContinuousDiscreteProcess.hh" #include "G4ProcessManager.hh" #include "G4LowEnergyIonisation.hh" #include "G4LowEnergyBremsstrahlung.hh" #include "G4LowEnergyCompton.hh" #include "G4LowEnergyGammaConversion.hh" #include "G4LowEnergyPhotoElectric.hh" #include "G4LowEnergyRayleigh.hh" #include "G4hLowEnergyIonisation.hh" #include "G4eIonisation.hh" #include "G4eBremsstrahlung.hh" #include "G4ComptonScattering.hh" #include "G4GammaConversion.hh" #include "G4PhotoElectricEffect.hh" #include "G4eplusAnnihilation.hh" #include "G4MuIonisation.hh" #include "G4MuBremsstrahlung.hh" #include "G4MuPairProduction.hh" #include "G4hIonisation.hh" #include "G4MultipleScattering.hh" #include "G4EnergyLossTables.hh" #include "G4ParticleChange.hh" #include "G4ParticleChange.hh" #include "G4DynamicParticle.hh" #include "G4AntiProton.hh" #include "G4Proton.hh" #include "G4Electron.hh" #include "G4Positron.hh" #include "G4Gamma.hh" #include "G4Box.hh" #include "G4PVPlacement.hh" #include "G4VPhysicalVolume.hh" #include "G4LogicalVolume.hh" #include "G4RunManager.hh" #include "G4Step.hh" #include "G4GRSVolume.hh" #include "G4UnitsTable.hh" // New Histogramming (from AIDA and Anaphe): #include // for the auto_ptr(T> #include "AIDA/AIDA.h" #include "G4Timer.hh" int main(int argc,char** argv) { // ------------------------------------------------------------------- // Setup G4int nEvt = 100; G4int nPart =-1; G4String nameMat = "Si"; G4int nProcess = 0; G4bool usepaw = false; G4bool postDo = true; G4bool lowE = true; G4int verbose = 0; G4double gEnergy = 0.1*MeV; G4String hFile = ""; G4double theStep = 1.0*micrometer; G4double range = 1.0*micrometer; G4double cutG = 1.0*micrometer; G4double cutE = 1.0*micrometer; G4Material* material = 0; G4String name[6] = {"Ionisation", "Bremsstrahlung", "Compton", "GammaConversion", "PhotoElectric", "Raylaigh"}; G4cout.setf( ios::scientific, ios::floatfield ); // ------------------------------------------------------------------- // Control on input if(argc < 2) { G4cout << "Input file is not specified! Exit" << G4endl; exit(1); } ifstream* fin = new ifstream(); string fname = argv[1]; fin->open(fname.c_str()); if( !fin->is_open()) { G4cout << "Input file <" << fname << "> does not exist! Exit" << G4endl; exit(1); } // ------------------------------------------------------------------- //--------- Materials definition --------- G4Material* m; m = new G4Material("Be", 4., 9.01*g/mole, 1.848*g/cm3); m = new G4Material("Graphite",6., 12.00*g/mole, 2.265*g/cm3 ); m = new G4Material("Al", 13., 26.98*g/mole, 2.7 *g/cm3); m = new G4Material("Si", 14., 28.055*g/mole, 2.33*g/cm3); m = new G4Material("LAr", 18., 39.95*g/mole, 1.393*g/cm3); m = new G4Material("Fe", 26., 55.85*g/mole, 7.87*g/cm3); m = new G4Material("Cu", 29., 63.55*g/mole, 8.96*g/cm3); m = new G4Material("W", 74., 183.85*g/mole, 19.30*g/cm3); m = new G4Material("Pb", 82., 207.19*g/mole, 11.35*g/cm3); m = new G4Material("U", 92., 238.03*g/mole, 18.95*g/cm3); G4Element* H = new G4Element ("Hydrogen", "H", 1. , 1.01*g/mole); G4Element* O = new G4Element ("Oxygen" , "O", 8. , 16.00*g/mole); G4Element* C = new G4Element ("Carbon" , "C", 6. , 12.00*g/mole); G4Element* Cs = new G4Element ("Cesium" , "Cs", 55. , 132.905*g/mole); G4Element* I = new G4Element ("Iodide" , "I", 53. , 126.9044*g/mole); m = new G4Material("O2", 8., 16.00*g/mole, 1.1*g/cm3); m = new G4Material ("Water" , 1.*g/cm3, 2); m->AddElement(H,2); m->AddElement(O,1); m = new G4Material ("Ethane" , 0.4241*g/cm3, 2); m->AddElement(H,6); m->AddElement(C,2); m = new G4Material ("CsI" , 4.53*g/cm3, 2); m->AddElement(Cs,1); m->AddElement(I,1); const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable(); G4int nMaterials = G4Material::GetNumberOfMaterials(); G4cout << "Available materials are: " << G4endl; G4int mat; for (mat = 0; mat < nMaterials; mat++) { G4cout << mat << ") " << (*theMaterialTable)[mat]->GetName() << G4endl; } material = (*theMaterialTable)[0]; G4cout << "Available processes are: " << G4endl; for (mat = 0; mat < 6; mat++) { G4cout << mat << ") " << name[mat] << G4endl; } // Particle definitions G4ParticleDefinition* gamma = G4Gamma::GammaDefinition(); G4ParticleDefinition* electron = G4Electron::ElectronDefinition(); G4ParticleDefinition* positron = G4Positron::PositronDefinition(); G4ParticleDefinition* proton = G4Proton::ProtonDefinition(); G4ParticleDefinition* antiproton = G4AntiProton::AntiProtonDefinition(); G4ParticleDefinition* part = gamma; // Geometry G4double initX = 0.; G4double initY = 0.; G4double initZ = 1.; G4double dimX = 100.0*cm; G4double dimY = 100.0*cm; G4double dimZ = 100.0*cm; G4Box* sFrame = new G4Box ("Box",dimX, dimY, dimZ); G4LogicalVolume* lFrame = new G4LogicalVolume(sFrame,material,"Box",0,0,0); G4PVPlacement* pFrame = new G4PVPlacement(0,G4ThreeVector(),"Box", lFrame,0,false,0); G4RunManager* rm = new G4RunManager(); G4cout << "World is defined " << G4endl; rm->GeometryHasBeenModified(); rm->DefineWorldVolume(pFrame); // ------------------------------------------------------------------- // ---- Read input file G4cout << "Available commands are: " << G4endl; G4cout << "#events" << G4endl; G4cout << "#particle" << G4endl; G4cout << "#energy(MeV)" << G4endl; G4cout << "#cutG(mm)" << G4endl; G4cout << "#cutE(mm)" << G4endl; G4cout << "#range(mm)" << G4endl; G4cout << "#step(mm)" << G4endl; G4cout << "#material" << G4endl; G4cout << "#process" << G4endl; G4cout << "#domain" << G4endl; G4cout << "#test" << G4endl; G4cout << "#paw" << G4endl; G4cout << "#verbose" << G4endl; G4cout << "#run" << G4endl; G4cout << "#exit" << G4endl; G4cout << pFrame << G4endl; G4ProcessManager *elecManager, *positManager, *gammaManager, *protManager, *aprotManager; elecManager = new G4ProcessManager(electron); electron->SetProcessManager(elecManager); positManager = new G4ProcessManager(positron); positron->SetProcessManager(positManager); gammaManager = new G4ProcessManager(gamma); gamma->SetProcessManager(gammaManager); protManager = new G4ProcessManager(proton); proton->SetProcessManager(protManager); aprotManager = new G4ProcessManager(antiproton); antiproton->SetProcessManager(aprotManager); G4eIonisation* elecSTion = 0; G4eBremsstrahlung* elecSTbr = 0; G4LowEnergyIonisation* elecLEion = 0; G4LowEnergyBremsstrahlung* elecLEbr = 0; G4bool ionis = true; string line, line1; G4bool end = true; for(G4int run=0; run<100; run++) { do { (*fin) >> line; G4cout << "Next line " << line << G4endl; if(line == "#events") { (*fin) >> nEvt; if(nEvt < 1) nEvt = 1; } else if(line == "#particle") { (*fin) >> nPart; } else if(line == "#energy(MeV)") { (*fin) >> gEnergy; gEnergy *= MeV; } else if(line == "#cutG(mm)") { (*fin) >> cutG; cutG *= mm; } else if(line == "#cutE(mm)") { (*fin) >> cutE; cutE *= mm; } else if(line == "#range(mm)") { (*fin) >> range; range *= mm; } else if(line == "#step(mm)") { (*fin) >> theStep; theStep *= mm; } else if(line == "#material") { (*fin) >> nameMat; } else if(line == "#process") { (*fin) >> nProcess; } else if(line == "#domain") { (*fin) >> line1; if(line1 == "lowenergy") {lowE = true;} else {lowE = false;} } else if(line == "#test") { (*fin) >> line1; if(line1 == "PostStep") {postDo = true;} else {postDo = false;} } else if(line == "#paw") { usepaw = true; (*fin) >> hFile; } else if(line == "#run") { break; } else if(line == "#verbose") { (*fin) >> verbose; } else if(line == "#exit") { end = false; break; } } while(end); if(!end) break; G4cout << "###### Start new run # " << run << " #####" << G4endl; if(nPart == 0) { part = gamma; } else if(nPart == 1) { part = electron; } else if(nPart == 2) { part = positron; } else if(nPart == 3) { part = proton; } else if(nPart == 4) { part = antiproton; } else { G4cout << "Particle #" << nPart << " is absent in the list of particles: Exit" << G4endl; break; } if(nProcess < 0 || nProcess > 5) { G4cout << "Process #" << nProcess << " is absent in the list of processes: Exit" << G4endl; break; } for (mat = 0; mat < nMaterials; mat++) { material = (*theMaterialTable)[mat]; if(nameMat == material->GetName()) break; } G4cout << "The particle: " << part->GetParticleName() << G4endl; G4cout << "The energy: " << gEnergy/MeV << " MeV" << G4endl; G4cout << "The material: " << material->GetName() << G4endl; G4cout << "The cut on e-:" << cutE/mm << " mm" << G4endl; G4cout << "The cut on g: " << cutG/mm << " mm" << G4endl; G4cout << "The step: " << theStep/mm << " mm" << G4endl; if(postDo && lowE) { G4cout << "Test of PostStepDoIt for " << name[nProcess] << " for lowenergy" << G4endl; } else if(postDo && !lowE) { G4cout << "Test of PostStepDoIt for " << name[nProcess] << " for standard" << G4endl; } else if(!postDo && !lowE) { G4cout << "Test of AlongStepDoIt for " << name[nProcess] << " for standard" << G4endl; } else if(!postDo && lowE) { G4cout << "Test of AlongStepDoIt for " << name[nProcess] << " for lowenergy" << G4endl; } // ------------------------------------------------------------------- // ---- HBOOK initialization // Creating the analysis factory std::auto_ptr< AIDA::IAnalysisFactory > af( AIDA_createAnalysisFactory() ); // Creating the tree factory std::auto_ptr< AIDA::ITreeFactory > tf( af->createTreeFactory() ); // Creating a tree mapped to a new hbook file. std::auto_ptr< AIDA::ITree > tree( tf->create( hFile,"hbook" ,false,false ) ); G4cout << "Tree store : " << tree->storeName() << G4endl; // Creating a tuple factory, whose tuples will be handled by the tree // std::auto_ptr< AIDA::ITupleFactory > tpf( af->createTupleFactory( *tree ) ); AIDA::IHistogram1D* hist[4]; //AIDA::ITuple* ntuple1 = 0; //AIDA::ITuple* ntuple2 = 0; if(usepaw) { // ---- primary ntuple ------ // If using Anaphe HBOOK implementation, there is a limitation on the length of the // variable names in a ntuple //ntuple1 = tpf->create( "100", "Primary", "float ekin, dedx" ); //ntuple2 = tpf->create( "101", "Secondary", "float ekin, dedx" ); // Creating a histogram factory, whose histograms will be handled by the tree std::auto_ptr< AIDA::IHistogramFactory > hf( af->createHistogramFactory( *tree ) ); // Creating an 1-dimensional histogram in the root directory of the tree hist[0] = hf->createHistogram1D("11","Kinetic Energy (T/T0)", 50,0.,1.0); hist[1] = hf->createHistogram1D("12","Momentum (MeV/c)", 50,0.,gEnergy*0.1/MeV); hist[2] = hf->createHistogram1D("13","Number of secondaries", 20,-0.5,19.5); hist[3] = hf->createHistogram1D("14","Energy deposition (MeV)", 50,0.,gEnergy*0.1/MeV); G4cout<< "Histograms is initialised" << G4endl; } G4Timer* timer = new G4Timer(); timer->Start(); G4ProductionCutsTable* cutsTable = G4ProductionCutsTable::GetProductionCutsTable(); G4ProductionCuts* cuts = cutsTable->GetDefaultProductionCuts(); cuts->SetProductionCut(cutG, 0); cuts->SetProductionCut(cutE, 1); cuts->SetProductionCut(cutE, 2); G4cout << "Cuts are defined " << G4endl; cutsTable->UpdateCoupleTable(); (G4ProductionCutsTable::GetProductionCutsTable())->DumpCouples(); const G4MaterialCutsCouple* theCouple = cutsTable->GetMaterialCutsCouple(material,cuts); // Processes G4VDiscreteProcess* dProcess; G4VContinuousDiscreteProcess* cdProcess; dProcess = 0; cdProcess = 0; G4cout << "Start BuildPhysicsTable" << G4endl;; if(lowE) { if(ionis) { elecLEion = new G4LowEnergyIonisation(); elecLEbr = new G4LowEnergyBremsstrahlung(); elecManager->AddProcess(elecLEion); elecManager->AddProcess(elecLEbr); elecLEion->BuildPhysicsTable(*electron); elecLEbr->BuildPhysicsTable(*electron); ionis = false; } if(nPart == 0) { if(nProcess == 2) dProcess = new G4LowEnergyCompton(); if(nProcess == 3) dProcess = new G4LowEnergyGammaConversion(); if(nProcess == 4) dProcess = new G4LowEnergyPhotoElectric(); if(nProcess == 5) dProcess = new G4LowEnergyRayleigh(); if(dProcess) { gammaManager->AddProcess(dProcess); dProcess->BuildPhysicsTable(*gamma); } } else if(nPart == 1) { if(nProcess == 0) cdProcess = elecLEion; if(nProcess == 1) cdProcess = elecLEbr; } else if(nPart == 3) { if(nProcess == 0) { cdProcess = new G4hLowEnergyIonisation(); protManager->AddProcess(cdProcess); cdProcess->BuildPhysicsTable(*proton); } } else if(nPart == 4) { if(nProcess == 0) { cdProcess = new G4hLowEnergyIonisation(); aprotManager->AddProcess(cdProcess); cdProcess->BuildPhysicsTable(*antiproton); } } } else { if(ionis) { elecSTion = new G4eIonisation(); elecSTbr = new G4eBremsstrahlung(); elecManager->AddProcess(elecSTion); elecManager->AddProcess(elecSTbr); elecSTion->BuildPhysicsTable(*electron); elecSTbr->BuildPhysicsTable(*electron); ionis = false; } if(nPart == 0) { if(nProcess == 2) dProcess = new G4ComptonScattering(); if(nProcess == 3) dProcess = new G4GammaConversion(); if(nProcess == 4) dProcess = new G4PhotoElectricEffect(); if(dProcess) { gammaManager->AddProcess(dProcess); dProcess->BuildPhysicsTable(*gamma); } } else if(nPart == 1) { if(nProcess == 0) cdProcess = elecSTion; if(nProcess == 1) cdProcess = elecSTbr; } else if(nPart == 2) { G4eIonisation* pSTion = new G4eIonisation(); G4eBremsstrahlung* pSTbr = new G4eBremsstrahlung(); if(nProcess == 0) cdProcess = pSTion; if(nProcess == 1) cdProcess = pSTbr; } else if(nPart == 3) { if(nProcess == 0) { cdProcess = new G4hIonisation(); protManager->AddProcess(cdProcess); cdProcess->BuildPhysicsTable(*proton); } } else if(nPart == 4) { if(nProcess == 0) { cdProcess = new G4hIonisation(); aprotManager->AddProcess(cdProcess); cdProcess->BuildPhysicsTable(*antiproton); } } } G4cout << "Physics tables are built" << G4endl;; timer->Stop(); G4cout << " " << *timer << G4endl; delete timer; // Control on processes if(postDo && !dProcess && !cdProcess) { G4cout << "Discret Process is not found out! Exit" << G4endl; break; } if(!postDo && !cdProcess) { G4cout << "Continues Discret Process is not found out! Exit" << G4endl; break; } // Create a DynamicParticle G4ParticleMomentum gDir(initX,initY,initZ); G4DynamicParticle dParticle(part,gDir,gEnergy); // Track G4ThreeVector aPosition(0.,0.,0.); G4double aTime = 0. ; G4Track* gTrack; gTrack = new G4Track(&dParticle,aTime,aPosition); // Step G4Step* step; step = new G4Step(); step->SetTrack(gTrack); G4StepPoint *aPoint, *bPoint; aPoint = new G4StepPoint(); aPoint->SetPosition(aPosition); aPoint->SetMaterial(material); aPoint->SetMaterialCutsCouple(theCouple); G4double safety = 10000.*cm; aPoint->SetSafety(safety); step->SetPreStepPoint(aPoint); bPoint = aPoint; G4ThreeVector bPosition(0.,0.,theStep); bPoint->SetPosition(bPosition); step->SetPostStepPoint(bPoint); step->SetStepLength(theStep); // --------- Test the DoIt G4int nElectrons = 0; G4int nPositrons = 0; G4int nPhotons = 0; G4double rmax = 0.0; G4double de = 0.0; G4double de2 = 0.0; G4cout << "dProcess= " << dProcess << " cdProcess= " << cdProcess; if(dProcess) G4cout << " name= " << dProcess->GetProcessName() << G4endl; if(cdProcess) G4cout << " name= " << cdProcess->GetProcessName() << G4endl; timer = new G4Timer(); timer->Start(); for (G4int iter=0; iterSetStep(step); if(verbose) { G4cout << "Iteration = " << iter << " - Step Length = " << step->GetStepLength()/mm << " mm " << G4endl; } G4VParticleChange* dummy = 0; if(postDo) { if(dProcess) dummy = dProcess->PostStepDoIt(*gTrack, *step); if(cdProcess) { dummy = cdProcess->PostStepDoIt(*gTrack, *step); } } else { dummy = cdProcess->AlongStepDoIt(*gTrack, *step); } G4ParticleChange* particleChange = (G4ParticleChange*) dummy; // Primary physical quantities G4double energyChange = particleChange->GetEnergyChange(); G4double deltaE = gEnergy - energyChange ; G4double dedx = deltaE / (step->GetStepLength()); G4ThreeVector change = particleChange->CalcMomentum(energyChange, *(particleChange->GetMomentumChange()), part->GetPDGMass()); G4double pxChange = change.x(); G4double pyChange = change.y(); G4double pzChange = change.z(); if(verbose) { G4cout << "---- Primary after the step ---- " << G4endl; G4cout << "---- Energy: " << energyChange/MeV << " MeV, " << "(px,py,pz): (" << pxChange/MeV << "," << pyChange/MeV << "," << pzChange/MeV << ") MeV" << G4endl; G4cout << "---- Energy loss (dE) = " << deltaE/keV << " keV;" << "Stopping power (dE/dx)=" << dedx*mm/keV << " keV/mm" << "; rmax(mm)= " << rmax << G4endl; } // Primary G4int nsec = particleChange->GetNumberOfSecondaries(); /* if(ntuple1) { ntuple1->column("epri", gEnergy/MeV); ntuple1->column("efin", energyChange/MeV); ntuple1->column("dedx", dedx*mm/MeV); ntuple1->column("nsec", nsec); ntuple1->column("nele", nElectrons); ntuple1->column("npho", nPhotons); ntuple1->dumpData(); } */ de += deltaE; de2 += deltaE*deltaE; // Secondaries physical quantities if(usepaw) { hist[2]->fill((float)nsec, (float)1.0); hist[3]->fill((float)(particleChange->GetLocalEnergyDeposit()/MeV), (float)1.0); } for (G4int i = 0; iGetSecondary(i) ; G4double e = finalParticle->GetTotalEnergy(); G4double eKin = finalParticle->GetKineticEnergy(); G4double px = (finalParticle->GetMomentum()).x(); G4double py = (finalParticle->GetMomentum()).y(); G4double pz = (finalParticle->GetMomentum()).z(); //G4double theta= (finalParticle->GetMomentum()).theta(); G4double p = std::sqrt(px*px + py*py + pz*pz); if (eKin > gEnergy) { G4cout << "WARNING: eFinal > eInit in event #" << iter << G4endl; } G4String partName = finalParticle->GetDefinition()->GetParticleName(); if(verbose) { G4cout << "==== Final " << partName << " " << "E= " << e/MeV << " MeV, " << "eKin: " << eKin/MeV << " MeV, " << "(px,py,pz): (" << px/MeV << "," << py/MeV << "," << pz/MeV << ") MeV," << " p= " << p << " MeV" << G4endl; } if(usepaw) { hist[0]->fill((float)(eKin/gEnergy), (float)1.0); hist[1]->fill((float)(p/MeV), (float)1.0); } G4int partType = 0; if (partName == "e-") { partType = 1; nElectrons++; } else if (partName == "e+") { partType = 2; nPositrons++; } else if (partName == "gamma") { partType = 0; nPhotons++; } // Fill the secondaries ntuple /* if(ntuple2) { ntuple2->column("eprimary",gEnergy); ntuple2->column("px", px); ntuple2->column("py", py); ntuple2->column("pz", pz); ntuple2->column("p", p); ntuple2->column("e", e); ntuple2->column("theta", theta); ntuple2->column("ekin", eKin); ntuple2->column("type", partType); ntuple2->dumpData(); } */ delete particleChange->GetSecondary(i); } particleChange->Clear(); } G4cout << "###### Statistics:" << G4endl; G4cout << "Average number of secondary electrons= " << (G4double)nElectrons/(G4double)nEvt << G4endl; G4cout << "Average number of secondary positrons= " << (G4double)nPositrons/(G4double)nEvt << G4endl; G4cout << "Average number of secondary photons= " << (G4double)nPhotons/(G4double)nEvt << G4endl; G4double x = de/(G4double)nEvt; G4double y = de2/(G4double)nEvt - x*x; if(0.0 < y) y = std::sqrt(y); G4cout << "Average energy deposition(MeV)= " << x/MeV << " +- " << y/MeV << G4endl; timer->Stop(); G4cout << " " << *timer << G4endl; delete timer; if(usepaw) { tree->commit(); std::cout << "Closing the tree..." << std::endl; tree->close(); G4cout << "# hbook is writed" << G4endl; } G4cout << "###### End of run # " << run << " ######" << G4endl; } while(end); G4cout << "###### End of test #####" << G4endl; }