Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //
- // ********************************************************************
- // * 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. *
- // ********************************************************************
- //
- /// \file electromagnetic/TestEm11/src/Run.cc
- /// \brief Implementation of the Run class
- //
- // $Id: Run.cc 71376 2013-06-14 07:44:50Z maire $
- //
- //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
- //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
- #include "Run.hh"
- #include "DetectorConstruction.hh"
- #include "PrimaryGeneratorAction.hh"
- #include "G4EmCalculator.hh"
- #include "G4SystemOfUnits.hh"
- #include "G4UnitsTable.hh"
- #include "G4HCofThisEvent.hh"
- #include "G4Step.hh"
- #include "G4ThreeVector.hh"
- #include "G4ios.hh"
- #include "G4SDManager.hh"
- #include "G4VSensitiveDetector.hh"
- #include "G4THitsMap.hh"
- #include <iomanip>
- //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
- Run::Run(DetectorConstruction* det)
- : G4Run(),
- fDetector(det),
- fParticle(0), fEkin(0.)
- {
- fEnergyDeposit = fEnergyDeposit2 = 0.;
- fTrakLenCharged = fTrakLenCharged2 = 0.;
- fTrakLenNeutral = fTrakLenNeutral2 = 0.;
- fNbStepsCharged = fNbStepsCharged2 = 0.;
- fNbStepsNeutral = fNbStepsNeutral2 = 0.;
- fMscProjecTheta = fMscProjecTheta2 = 0.;
- fMscThetaCentral = 0.;
- fNbGamma = fNbElect = fNbPosit = 0;
- fTransmit[0] = fTransmit[1] = fReflect[0] = fReflect[1] = 0;
- fMscEntryCentral = 0;
- fEnergyLeak[0] = fEnergyLeak[1] = fEnergyLeak2[0] = fEnergyLeak2[1] = 0.;
- hitsCollID = -1;
- /// gerando o vetor de energias discretas
- energia_maxima=30;
- tamanho = 10000; /// 100 = duas casas deciamis
- tamanho_vetor = int(tamanho); /// calcula o tamanho do vetor
- /// pegando tres n decimais do valor da energia onde tamanho = 10^n
- energias_disc.assign (tamanho_vetor,0.000); /// cria o vetor e preenche com zeros
- energias_continuo.assign (tamanho_vetor,0.0000);
- //Calibra_vetores_energia( energias_disc , energias_continuo , energia_maxima);
- //// chamando a colecao com o nome correto
- G4SDManager * SDman = G4SDManager::GetSDMpointer();
- if(hitsCollID<0){
- G4String colNam;
- hitsCollID = SDman->GetCollectionID(colNam="SD");
- }
- }
- //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
- Run::~Run()
- { }
- //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
- void Run::SetPrimary(G4ParticleDefinition* particle, G4double energy)
- {
- fParticle = particle;
- fEkin = energy;
- //compute theta0
- fMscThetaCentral = 3*ComputeMscHighland();
- }
- //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
- void Run::Merge(const G4Run* run)
- {
- const Run* localRun = static_cast<const Run*>(run);
- // pass information about primary particle
- fParticle = localRun->fParticle;
- fEkin = localRun->fEkin;
- fMscThetaCentral = localRun->fMscThetaCentral;
- // accumulate sums
- //
- fEnergyDeposit += localRun->fEnergyDeposit;
- fEnergyDeposit2 += localRun->fEnergyDeposit2;
- fTrakLenCharged += localRun->fTrakLenCharged;
- fTrakLenCharged2 += localRun->fTrakLenCharged2;
- fTrakLenNeutral += localRun->fTrakLenNeutral;
- fTrakLenNeutral2 += localRun->fTrakLenNeutral2;
- fNbStepsCharged += localRun->fNbStepsCharged;
- fNbStepsCharged2 += localRun->fNbStepsCharged2;
- fNbStepsNeutral += localRun->fNbStepsNeutral;
- fNbStepsNeutral2 += localRun->fNbStepsNeutral2;
- fNbGamma += localRun->fNbGamma;
- fNbElect += localRun->fNbElect;
- fNbPosit += localRun->fNbPosit;
- fTransmit[0] += localRun->fTransmit[0];
- fTransmit[1] += localRun->fTransmit[1];
- fReflect[0] += localRun->fReflect[0];
- fReflect[1] += localRun->fReflect[1];
- fMscEntryCentral += localRun->fMscEntryCentral;
- fEnergyLeak[0] += localRun->fEnergyLeak[0];
- fEnergyLeak[1] += localRun->fEnergyLeak[1];
- fEnergyLeak2[0] += localRun->fEnergyLeak2[0];
- fEnergyLeak2[1] += localRun->fEnergyLeak2[1];
- G4cout<< " Rodando o Merge " << G4endl;
- /// unindo os resultados de cada thread no master energias_disc pertence ao master
- G4cout << " Unindo os resultados das threads no master " << G4endl;
- for (unsigned int i = 0 ; i < localRun->energias_disc.size() ; i++ )
- {
- energias_disc[i] += localRun->energias_disc.at(i);
- }
- G4cout << " Criando o vetor continuo no master " << G4endl;
- RealizaConvolucao(energias_disc);
- G4Run::Merge(run);
- }
- std::vector<double> Run::detector_efficiency(int Z,double thickness, int Z_window,double window_thick, double Emin, double &Emax, int &spectrum_size)
- {
- int i;
- double density,density1,density_air=0.00120479,attenuation, attenuation_window,attenuation_air,energy, air_thickness;
- XRayInit();
- std::vector <double> spectrum_saida ;
- air_thickness=1.0; /// em cm
- Emax = energia_maxima ; /// le Emax do arquivo (primeira linha do arquivo)
- if (Emax == 0 ) G4cout << " Erro na energia maxima " << G4endl;
- spectrum_size = energias_continuo.size(); /// define o numero de linhas como o tamanho do espectro
- // G4cout << spectrum_size << G4endl;
- density=2.33;
- density1=1.848;
- double calculos(0.0);
- /// problemas aqui
- for (i=0;i<spectrum_size;i++)
- {
- energy=Emin +(Emax-Emin)*i/spectrum_size;
- if (energy>0.0) {
- attenuation=CS_Total(Z, energy); /// atenuacao do
- attenuation_window=CS_Total(Z_window, energy);
- attenuation_air=0.755267*CS_Total(7, energy)+0.231781*CS_Total(8, energy)+ 0.012827*CS_Total(18, energy)+0.000124*CS_Total(6, energy);
- /// calcula um novo espectro usando os dados da densidade do ar, atenua��o do ar
- /// e largura da janela
- calculos = energias_disc.at(i) *(1.0-exp(-attenuation*thickness*density)) *exp(-attenuation_window*window_thick*density1 -attenuation_air*air_thickness*density_air);
- spectrum_saida.push_back(calculos);
- }
- else
- {
- spectrum_saida.push_back(0.0);
- }
- }
- /// imprime o espectro da eficiencia
- std::ofstream imprime_arq;
- imprime_arq.open("eficiencia");
- for (i=0;i<spectrum_saida.size();i++)
- {
- imprime_arq << (Emin +(Emax-Emin)*i/spectrum_size) << " " << spectrum_saida.at(i) << std::endl;
- }
- imprime_arq.close();
- /// retronarna o espectro da eficiencia
- return spectrum_saida;
- }
- int Run::detector_convolution_SDD(std::vector<double> spectrum_eff, char *spectrum_out, double Emin, double Emax, int spectrum_size)
- {
- std::ofstream saida;
- int i,j;
- double sigma_var;
- double factor;
- double E;
- int conv_lenght=60; /// ?
- std::vector <double> conv_nucleus , spectrum_conv ;
- //conv_nucleus=(double *)calloc(conv_lenght,sizeof(double));
- //spectrum_conv=(double *)calloc(spectrum_size,sizeof(double));
- conv_nucleus.assign(conv_lenght,0.0);/// zerando
- spectrum_conv.assign(spectrum_size,0.0);/// zerando
- for (i=0;i<energias_continuo.size();i++) spectrum_conv[i]=0.0;
- for (i=0;i<spectrum_eff.size();i++)
- {
- sigma_var=sqrt(125.0*125.0-120*120.0+2440.0*i*0.03)/2.3548/30;
- factor=1.0/sigma_var/sqrt(2.0*M_PI);
- for (j=0;j<conv_lenght;j++) conv_nucleus[j]=factor*exp(-1.0*j*j/(2.0*sigma_var*sigma_var));
- for (j=-conv_lenght;j<conv_lenght;j++)
- if ( ((i+j)>=0) && ((i+j)<spectrum_size))
- spectrum_conv[i+j]+=spectrum_eff.at(i)*conv_nucleus[abs(j)];
- }
- /// escreve o espectro continuo
- saida.open(spectrum_out, std::ofstream::out);
- for (i=0;i<spectrum_size;i++)
- {
- E = Emin +(Emax-Emin)*i/spectrum_size;
- ///cout << E << " " << spectrum_conv[i] << endl;
- saida << E << " " << spectrum_conv[i] << std::endl;
- }
- saida.close();
- return 0;
- }
- void Run::RealizaConvolucao(std::vector<int> energias_disc)
- {
- ////////////////////////
- /// inicio da convolucao
- /////////////////////////
- char *nome_espectro_saida ;
- nome_espectro_saida = new char[8];
- nome_espectro_saida="en_cont.out";
- int spectrum_size= energias_disc.size();
- double Emin=0, Emax=energia_maxima;
- std::vector<double> spectrum_eff;
- int tamvet = energias_disc.size();
- ///Material do Detector 14 = Silicio , Espessura do detector , Material da Janela 4= Berilio,
- // Espessura da janela = 0 pois o programa já considera a janela de berilio na simulaçao
- spectrum_eff= detector_efficiency(14, 0.05, 4, 0.0, Emin, Emax, spectrum_size);
- detector_convolution_SDD(spectrum_eff, nome_espectro_saida, Emin, Emax, spectrum_size );
- /////////
- // fim da convolucao arquivo nome_espectro_saida escrito
- ////////
- }
- //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
- void Run::PrintSummary()
- {
- // compute mean and rms
- //
- G4int TotNbofEvents = numberOfEvent;
- if (TotNbofEvents == 0) return;
- G4double EnergyBalance = fEnergyDeposit + fEnergyLeak[0] + fEnergyLeak[1];
- EnergyBalance /= TotNbofEvents;
- fEnergyDeposit /= TotNbofEvents; fEnergyDeposit2 /= TotNbofEvents;
- G4double rmsEdep = fEnergyDeposit2 - fEnergyDeposit*fEnergyDeposit;
- if (rmsEdep>0.) rmsEdep = std::sqrt(rmsEdep/TotNbofEvents);
- else rmsEdep = 0.;
- fTrakLenCharged /= TotNbofEvents; fTrakLenCharged2 /= TotNbofEvents;
- G4double rmsTLCh = fTrakLenCharged2 - fTrakLenCharged*fTrakLenCharged;
- if (rmsTLCh>0.) rmsTLCh = std::sqrt(rmsTLCh/TotNbofEvents);
- else rmsTLCh = 0.;
- fTrakLenNeutral /= TotNbofEvents; fTrakLenNeutral2 /= TotNbofEvents;
- G4double rmsTLNe = fTrakLenNeutral2 - fTrakLenNeutral*fTrakLenNeutral;
- if (rmsTLNe>0.) rmsTLNe = std::sqrt(rmsTLNe/TotNbofEvents);
- else rmsTLNe = 0.;
- fNbStepsCharged /= TotNbofEvents; fNbStepsCharged2 /= TotNbofEvents;
- G4double rmsStCh = fNbStepsCharged2 - fNbStepsCharged*fNbStepsCharged;
- if (rmsStCh>0.) rmsStCh = std::sqrt(rmsTLCh/TotNbofEvents);
- else rmsStCh = 0.;
- fNbStepsNeutral /= TotNbofEvents; fNbStepsNeutral2 /= TotNbofEvents;
- G4double rmsStNe = fNbStepsNeutral2 - fNbStepsNeutral*fNbStepsNeutral;
- if (rmsStNe>0.) rmsStNe = std::sqrt(rmsTLCh/TotNbofEvents);
- else rmsStNe = 0.;
- G4double Gamma = (G4double)fNbGamma/TotNbofEvents;
- G4double Elect = (G4double)fNbElect/TotNbofEvents;
- G4double Posit = (G4double)fNbPosit/TotNbofEvents;
- G4double transmit[2];
- transmit[0] = 100.*fTransmit[0]/TotNbofEvents;
- transmit[1] = 100.*fTransmit[1]/TotNbofEvents;
- G4double reflect[2];
- reflect[0] = 100.*fReflect[0]/TotNbofEvents;
- reflect[1] = 100.*fReflect[1]/TotNbofEvents;
- G4double rmsMsc = 0., tailMsc = 0.;
- if (fMscEntryCentral > 0) {
- fMscProjecTheta /= fMscEntryCentral; fMscProjecTheta2 /= fMscEntryCentral;
- rmsMsc = fMscProjecTheta2 - fMscProjecTheta*fMscProjecTheta;
- if (rmsMsc > 0.) { rmsMsc = std::sqrt(rmsMsc); }
- if(fTransmit[1] > 0.0) {
- tailMsc = 100.- (100.*fMscEntryCentral)/(2*fTransmit[1]);
- }
- }
- fEnergyLeak[0] /= TotNbofEvents; fEnergyLeak2[0] /= TotNbofEvents;
- G4double rmsEl0 = fEnergyLeak2[0] - fEnergyLeak[0]*fEnergyLeak[0];
- if (rmsEl0>0.) rmsEl0 = std::sqrt(rmsEl0/TotNbofEvents);
- else rmsEl0 = 0.;
- fEnergyLeak[1] /= TotNbofEvents; fEnergyLeak2[1] /= TotNbofEvents;
- G4double rmsEl1 = fEnergyLeak2[1] - fEnergyLeak[1]*fEnergyLeak[1];
- if (rmsEl1>0.) rmsEl1 = std::sqrt(rmsEl1/TotNbofEvents);
- else rmsEl1 = 0.;
- //Stopping Power from input Table.
- //
- G4Material* material = fDetector->GetSubstratoMaterial();
- G4double length = fDetector->GetSubstratoThickness();
- G4double density = material->GetDensity();
- G4String partName = fParticle->GetParticleName();
- G4EmCalculator emCalculator;
- G4double dEdxTable = 0., dEdxFull = 0.;
- if (fParticle->GetPDGCharge()!= 0.) {
- dEdxTable = emCalculator.GetDEDX(fEkin,fParticle,material);
- dEdxFull = emCalculator.ComputeTotalDEDX(fEkin,fParticle,material);
- }
- G4double stopTable = dEdxTable/density;
- G4double stopFull = dEdxFull /density;
- //Stopping Power from simulation.
- //
- G4double meandEdx = fEnergyDeposit/length;
- G4double stopPower = meandEdx/density;
- G4cout << "\n ======================== run summary ======================\n";
- G4int prec = G4cout.precision(3);
- G4cout << "\n The run was " << TotNbofEvents << " " << partName << " of "
- << G4BestUnit(fEkin,"Energy") << " through "
- << G4BestUnit(length,"Length") << " of "
- << material->GetName() << " (density: "
- << G4BestUnit(density,"Volumic Mass") << ")" << G4endl;
- G4cout.precision(4);
- G4cout << "\n Total energy deposit in absorber per event = "
- << G4BestUnit(fEnergyDeposit,"Energy") << " +- "
- << G4BestUnit(rmsEdep, "Energy")
- << G4endl;
- G4cout << "\n -----> Mean dE/dx = " << meandEdx/(MeV/cm) << " MeV/cm"
- << "\t(" << stopPower/(MeV*cm2/g) << " MeV*cm2/g)"
- << G4endl;
- G4cout << "\n From formulas :" << G4endl;
- G4cout << " restricted dEdx = " << dEdxTable/(MeV/cm) << " MeV/cm"
- << "\t(" << stopTable/(MeV*cm2/g) << " MeV*cm2/g)"
- << G4endl;
- G4cout << " full dEdx = " << dEdxFull/(MeV/cm) << " MeV/cm"
- << "\t(" << stopFull/(MeV*cm2/g) << " MeV*cm2/g)"
- << G4endl;
- G4cout << "\n Leakage : primary = "
- << G4BestUnit(fEnergyLeak[0],"Energy") << " +- "
- << G4BestUnit(rmsEl0, "Energy")
- << " secondaries = "
- << G4BestUnit(fEnergyLeak[1],"Energy") << " +- "
- << G4BestUnit(rmsEl1, "Energy")
- << G4endl;
- G4cout << " Energy balance : edep + eleak = "
- << G4BestUnit(EnergyBalance,"Energy")
- << G4endl;
- G4cout << "\n Total track length (charged) in absorber per event = "
- << G4BestUnit(fTrakLenCharged,"Length") << " +- "
- << G4BestUnit(rmsTLCh, "Length") << G4endl;
- G4cout << " Total track length (neutral) in absorber per event = "
- << G4BestUnit(fTrakLenNeutral,"Length") << " +- "
- << G4BestUnit(rmsTLNe, "Length") << G4endl;
- G4cout << "\n Number of steps (charged) in absorber per event = "
- << fNbStepsCharged << " +- " << rmsStCh << G4endl;
- G4cout << " Number of steps (neutral) in absorber per event = "
- << fNbStepsNeutral << " +- " << rmsStNe << G4endl;
- G4cout << "\n Number of secondaries per event : Gammas = " << Gamma
- << "; electrons = " << Elect
- << "; positrons = " << Posit << G4endl;
- G4cout << "\n Number of events with the primary particle transmitted = "
- << transmit[1] << " %" << G4endl;
- G4cout << " Number of events with at least 1 particle transmitted "
- << "(same charge as primary) = " << transmit[0] << " %" << G4endl;
- G4cout << "\n Number of events with the primary particle reflected = "
- << reflect[1] << " %" << G4endl;
- G4cout << " Number of events with at least 1 particle reflected "
- << "(same charge as primary) = " << reflect[0] << " %" << G4endl;
- // compute width of the Gaussian central part of the MultipleScattering
- //
- G4cout << "\n MultipleScattering:"
- << "\n rms proj angle of transmit primary particle = "
- << rmsMsc/mrad << " mrad (central part only)" << G4endl;
- G4cout << " computed theta0 (Highland formula) = "
- << ComputeMscHighland()/mrad << " mrad" << G4endl;
- G4cout << " central part defined as +- "
- << fMscThetaCentral/mrad << " mrad; "
- << " Tail ratio = " << tailMsc << " %" << G4endl;
- // reset default precision
- G4cout.precision(prec);
- }
- //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
- G4double Run::ComputeMscHighland()
- {
- //compute the width of the Gaussian central part of the MultipleScattering
- //projected angular distribution.
- //Eur. Phys. Jour. C15 (2000) page 166, formule 23.9
- G4double t = (fDetector->GetSubstratoThickness())
- /(fDetector->GetSubstratoMaterial()->GetRadlen());
- if (t < DBL_MIN) return 0.;
- G4double T = fEkin;
- G4double M = fParticle->GetPDGMass();
- G4double z = std::abs(fParticle->GetPDGCharge()/eplus);
- G4double bpc = T*(T+2*M)/(T+M);
- G4double teta0 = 13.6*MeV*z*std::sqrt(t)*(1.+0.038*std::log(t))/bpc;
- return teta0;
- }
- double Run::Calibracao(int _pos , int Emin , int Emax , int spectrum_size )const
- {
- return (Emin + ((Emax-Emin)*_pos)/ (spectrum_size*1.0)) ;
- //return (_pos*6.40/630);
- }
- //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
- //Method to be overwritten by the user for recording events in this (thread-local) run.
- // este metodo é chamado em todos os eventos mesmo quando nao há colisao
- void Run::RecordEvent(const G4Event* evt)
- {
- /// Mostra os resultados
- G4HCofThisEvent * HCE = evt->GetHCofThisEvent();
- DetectorHitsCollection* HC = 0;
- if(HCE)
- {
- HC = (DetectorHitsCollection*)(HCE->GetHC(hitsCollID));
- }
- if ( HC )
- {
- int n_hit = HC->entries();
- for ( int i = 0 ; i < n_hit; i++)
- {
- //G4ThreeVector position = (*HC)[i]->GetPos();
- G4double energy = (*HC)[i]->GetEdep();
- //G4cout << "---- Hit # " << i << G4endl;
- //if (energy<10)
- {
- // G4cout<< energy<<G4endl;
- }
- G4double energyant , energydep;
- //G4cout<< "Valor real " << energy ;
- for (unsigned int j=1;j<(energias_disc.size()-1); j ++)
- {
- energyant = Calibracao(j-1,0,energia_maxima,energias_disc.size());
- energydep = Calibracao(j+1,0,energia_maxima,energias_disc.size());
- if (energyant<=energy && energydep>=energy)
- {
- energias_disc[j]+=1;
- //G4cout<< " Incluido no canal " << j << " de energia " << Calibracao(j,0,30,energias_disc.size()) << G4endl ;
- }
- }
- // posicao_no_vetor = G4int (ceil(energy/CLHEP::MeV*tamanho)); /// prob
- // energias_disc[posicao_no_vetor]+=1;
- //// MELHORAR !!! aqui o a energia da particula deve
- /// acrescentar uma unidade no vetor en_continua
- /// deve-se olhar para o vetor en_continua
- /// buscar a posicao mais proxima a energia de colisao no detector
- /// e adicionar uma unidade a energia de colisao noa eh discreta !!
- //posicao_no_vetor = G4int (ceil(energy/CLHEP::MeV*tamanho)); /// problemas !
- //posicao_no_vetor = G4int (ceil(energy/CLHEP::MeV*tamanho)); /// problemas !
- //G4cout << " Position " << position/CLHEP::mm << " [cm] " << " Energy " << energy/CLHEP::MeV << " [keV] " <<G4endl;
- //energias_disc[posicao_no_vetor]+=1;
- }
- }
- G4Run::RecordEvent(evt);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement