// Process hits. G4bool base_SD::ProcessHits( G4Step * step, G4TouchableHistory * /*ROhist*/ ) { MCDetectorHit hit; hit.Edep=step->GetTotalEnergyDeposit(); G4StepPoint * prestep = step->GetPreStepPoint(); G4StepPoint * poststep = step->GetPostStepPoint(); G4TouchableHandle touchable = prestep->GetTouchableHandle(); hit.id=touchable->GetCopyNumber(); if (hit.id>=2000) { plugin->debug(0,"Hit id is too large... bailing out \n"); exit(-1); } G4Track * track = step->GetTrack(); hit.time = prestep->GetGlobalTime(); hit.track = track->GetTrackID(); // Get the true world and local coordinate positions. G4ThreeVector trueworld = ( prestep->GetPosition() + poststep->GetPosition() ) / 2.0; // If this first time store transformation and inverse. if( !transformValid[hit.id] ) { if (WorldtoLocal.size()<hit.id+1) //too small { WorldtoLocal.resize(hit.id+1); LocaltoWorld.resize(hit.id+1); } WorldtoLocal[hit.id] = touchable->GetHistory()->GetTopTransform(); LocaltoWorld[hit.id] = WorldtoLocal[hit.id].Inverse(); transformValid[hit.id] = true; } G4ThreeVector Tmp = WorldtoLocal[hit.id].TransformPoint(trueworld); hit.world=TVector3(trueworld.x(),trueworld.y(),trueworld.z()); hit.local=TVector3(Tmp.x(),Tmp.y(),Tmp.z()); // find average momentum G4ThreeVector mom=0.5*(prestep->GetMomentum()+poststep->GetMomentum()); hit.fourmomentum.SetXYZM(mom.x()/MeV,mom.y()/MeV,mom.z()/MeV,prestep->GetMass()/MeV); mom=WorldtoLocal[hit.id].TransformAxis(mom); hit.localmomentum=TVector3(mom.x(),mom.y(),mom.z()); data->hits.push_back(hit); return true; }
G4double RichG4Cerenkov::PostStepGetPhysicalInteractionLength(const G4Track& aTrack, G4double, G4ForceCondition* condition) { // Get the current radiator and skip the rich part if it is not rich const G4Material* aMaterial = aTrack.GetMaterial(); const G4Material &material=*aMaterial; if(!(material.GetName()==aerogel_name) && !(material.GetName()==naf_name)) return G4Cerenkov::PostStepGetPhysicalInteractionLength(aTrack,0,condition); const G4Step &aStep=*aTrack.GetStep(); G4StepPoint* pPostStepPoint = aStep.GetPostStepPoint(); G4ThreeVector p0 = aStep.GetDeltaPosition().unit(); G4ThreeVector x0 = pPostStepPoint->GetPosition(); const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle(); const G4double charge = aParticle->GetDefinition()->GetPDGCharge(); const G4double beta = aParticle->GetTotalMomentum()/aParticle->GetTotalEnergy(); *condition=NotForced; G4double MeanNumberOfPhotons = GetAverageNumberOfPhotons(charge,beta,0.1,x0,p0); if(MeanNumberOfPhotons==0) return DBL_MAX; *condition=StronglyForced; if(fMaxPhotons<=0) return 800.0/MeanNumberOfPhotons; return fMaxPhotons/MeanNumberOfPhotons; }
void SteppingAction::UserSteppingAction(const G4Step* step) { G4bool skipStepping = false; //set true if only SD is needed if ( skipStepping )return; G4Track* track = step->GetTrack(); G4String postVol = "NIL"; G4String preVol = "NIL"; G4String partName = "NIL"; G4int pdgCode = -999; G4String proc = "NIL"; G4double time = -1; G4String postProc = "NIL"; G4String preProc = "NIL"; G4String trackProc = "NIL"; G4String trkNextVol = "NIL"; G4double preKE = 0; if(step->GetPostStepPoint()->GetPhysicalVolume()) postVol = step->GetPostStepPoint()->GetPhysicalVolume()->GetName(); //step->GetPostStepPoint()->GetTouchableHandle()->GetVolume()->GetName(); if(step->GetPreStepPoint()->GetPhysicalVolume()) preVol = step->GetPreStepPoint()->GetPhysicalVolume()->GetName(); if(track->GetDynamicParticle()->GetDefinition()) // GetParticleDefinition { partName = track->GetDynamicParticle()->GetDefinition()->GetParticleName(); } if(step->GetPreStepPoint()) { preKE = step->GetPreStepPoint()->GetKineticEnergy(); } G4bool skipVolume = true; if(skipVolume) { if(!(postVol=="SNSDetectorCsI"|| postVol=="DetPolyShield"|| postVol=="DetLeadShield" ||preVol=="SNSDetectorCsI"|| preVol=="DetPolyShield"|| preVol=="DetLeadShield" )) return; if( postVol != "SNSDetectorCsI" && partName !="neutron" ) return; //skip if not neutron in other volumes } if(step->GetTotalEnergyDeposit()<0.1*keV && partName !="neutron") return; G4bool skipParticles = true; // all particles ? if(skipParticles && step->GetTrack()->GetDynamicParticle()->GetDefinition()) { if( partName == "nu_e"|| partName =="nu_mu"|| partName == "anti_nu_mu" ||partName == "anti_nu_e" || partName == "mu+" || partName =="pi+" || partName =="pi-") // skipped previously e- e+, gamma return; } Analysis* man = Analysis::GetInstance(); G4StepPoint* pre = step->GetPreStepPoint(); if(step->GetPostStepPoint()->GetProcessDefinedStep()) proc = step->GetPostStepPoint()->GetProcessDefinedStep()->GetProcessName(); if(step->GetPostStepPoint()) time = track->GetGlobalTime(); //step->GetPostStepPoint()->GetGlobalTime();// if(track->GetDynamicParticle()->GetDefinition()) // GetParticleDefinition { pdgCode = track->GetDynamicParticle()->GetDefinition()->GetPDGEncoding(); } if( step->GetPostStepPoint()->GetProcessDefinedStep()) postProc = step->GetPostStepPoint()->GetProcessDefinedStep()->GetProcessName(); if( step->GetPreStepPoint()->GetProcessDefinedStep()) preProc = step->GetPreStepPoint()->GetProcessDefinedStep()->GetProcessName(); if(track->GetCreatorProcess()) trackProc = track->GetCreatorProcess()->GetProcessName(); G4double kCarTolerance = G4GeometryTolerance::GetInstance()->GetSurfaceTolerance(); //############################################ //In SNS Detector G4bool snsDetectorCsI = true; // detector G4bool verbDetCsIInfo = false; //text output G4int volumeID = -1; if( snsDetectorCsI && (postVol=="SNSDetectorCsI" || postVol=="DetPolyShield" || postVol=="DetLeadShield") )// && partName == "neutron")) { //if( !(partName == "gamma"|| partName == "e-")) //{ G4double trackKE = track->GetKineticEnergy(); G4int stepNum = track->GetCurrentStepNumber(); G4int evtid = G4RunManager::GetRunManager()->GetCurrentEvent()->GetEventID(); G4int trackid = track->GetTrackID(); G4int parentID = track->GetParentID(); G4double xx = track->GetPosition().x(); //trackpos= postpos G4double yy = track->GetPosition().y(); G4double zz = track->GetPosition().z(); G4double postX = step->GetPostStepPoint()->GetPosition().x(); G4double postY = step->GetPostStepPoint()->GetPosition().y(); G4double postZ = step->GetPostStepPoint()->GetPosition().z(); G4double weight = track->GetWeight() ;//step->GetPreStepPoint()->GetWeight(); G4double eDep =0; if(partName == "neutron")// && step->GetPostStepPoint()->GetStepStatus()==fGeomBoundary ) {//fGeomBoundary =1, from G4StepStatus.hh. use poststep, not pre if(postVol=="SNSDetectorCsI" && preVol != "SNSDetectorCsI" ) volumeID = 1; else if( postVol == "DetLeadShield" && !(preVol == "SNSDetectorCsI" || preVol == "DetLeadShield")) volumeID = 2; else if( postVol == "DetPolyShield"&& !(preVol == "SNSDetectorCsI" || preVol == "DetPolyShield" || preVol == "DetLeadShield"))volumeID = 3; //else if( postVol == "DetWaterShield"&& !(preVol == "SNSDetectorCsI" // || preVol == "DetLeadShield" ||preVol == "DetPolyShield" ))volumeID = 4; //else if( preVol == "MonolithSteelCyl")volumeID = 5;//NOTE //xx = (aTrack->GetVertexPosition()).x(); //yy = (aTrack->GetVertexPosition()).y(); //zz = (aTrack->GetVertexPosition()).z(); G4double preX = step->GetPreStepPoint()->GetPosition().x(); G4double preY = step->GetPreStepPoint()->GetPosition().y(); G4double preZ = step->GetPreStepPoint()->GetPosition().z(); //pass without interaction if(step->GetPostStepPoint()->GetStepStatus()==fGeomBoundary && preVol == "DetLeadShield" && postVol == "DetLeadShield") { volumeID = 1; G4cout << " Passed vol1 ...... " << G4endl; } if(track->GetNextVolume() == 0) volumeID = 0; if(volumeID > -1) man->FillSNSneutronFlux(volumeID, preKE/MeV , trackKE/MeV, pdgCode, weight, xx/m, yy/m, zz/m, evtid, trackid, parentID, stepNum, time/microsecond); if(verbDetCsIInfo && volumeID > -1) { G4cout << " NFLUX " << std::setprecision(3) << preKE/MeV << " preKE(mev):postKE " << std::setprecision(3) << trackKE/MeV << " " << partName << " eDep " << std::setprecision(3) << eDep/MeV << " mev|pre:post " << preVol << " " << postVol << " volID "<< volumeID << " " << weight << " wt|evt:track:step " << evtid << " "<< trackid << " " << stepNum << " " << preProc << " preproc|postproc " << postProc << " " << track->GetCreatorProcess()->GetProcessName() << " create_proc|in " << track->GetLogicalVolumeAtVertex()->GetName() << " withKE "<< track->GetVertexKineticEnergy()/MeV //<< " track_xyz_m " << std::setprecision(3) << xx/m << " " << std::setprecision(3) //<< yy/m << " " << std::setprecision(3) << zz/m << " post_xyz_m " << std::setprecision(3) << postX/m << " " << std::setprecision(3) << postY/m << " " << std::setprecision(3) << postZ/m << " pre_xyz_m " << std::setprecision(3) << preX/m << " " << std::setprecision(3) << preY/m << " " << std::setprecision(3) << preZ/m << " postStatus " << step->GetPostStepPoint()->GetStepStatus() << G4endl; } G4bool shieldSteps = false; if( shieldSteps && (postVol== "DetPolyShield"|| postVol=="DetLeadShield" || postVol=="SNSDetectorCsI" ) && postVol != preVol ) { G4cout << " ShieldN " << std::setprecision(3) << preKE/MeV << " preKE(mev):postKE " << std::setprecision(3) << trackKE/MeV << " " << partName << " eDep " << std::setprecision(3) << eDep/MeV << " mev|pre:post " << preVol << " " << postVol << " volID "<< volumeID << " " << weight << " wt|evt:track:step " << evtid << " "<< trackid << " " << stepNum << " " << preProc << " preproc|postproc " << postProc << " " << track->GetCreatorProcess()->GetProcessName() << " create_proc|in " << track->GetLogicalVolumeAtVertex()->GetName() << " withKE "<< track->GetVertexKineticEnergy()/MeV << " xyz_m " << std::setprecision(3) << postX/m << " " << std::setprecision(3) << postY/m << " " << std::setprecision(3) << postZ/m << " postStatus " << step->GetPostStepPoint()->GetStepStatus() << G4endl; } }//nuetron nFlux vol //Detections eDep = step->GetTotalEnergyDeposit(); if(postVol=="SNSDetectorCsI") { man->FillSNSDetection(eDep/MeV, preKE/MeV , trackKE/MeV, pdgCode, weight, postX/m, postY/m, postZ/m, evtid, trackid, parentID, stepNum, time/microsecond); //proc, vol if(verbDetCsIInfo) { G4cout << " Det " << std::setprecision(3) << preKE/MeV << " preKE(mev):postKE " << std::setprecision(3) << trackKE/MeV << " " << partName << " eDep " << std::setprecision(3) << eDep/MeV << " mev|pre:post " << preVol << " " << postVol << " volID "<< volumeID << " " << weight << " wt|evt:track:step " << evtid << " "<< trackid << " " << stepNum << " " << preProc << " preproc|postproc " << postProc << " " << track->GetCreatorProcess()->GetProcessName() << " create_proc:in " << track->GetLogicalVolumeAtVertex()->GetName() << " withKE "<< track->GetVertexKineticEnergy()/MeV << " post_xyz_m " << std::setprecision(3) << postX/m << " " << std::setprecision(3) << postY/m << " " << std::setprecision(3) << postZ/m << " postStatus " << step->GetPostStepPoint()->GetStepStatus() << G4endl; } }//if CsI }//if vol det //############################################### //NFLUX at BasementLayer G4bool nFluxBaseLayer = true; if(nFluxBaseLayer && partName == "neutron" && preVol == "BasementIn" && postVol == "BasementLayer") { G4double trackKE = track->GetKineticEnergy(); G4int evtid = G4RunManager::GetRunManager()->GetCurrentEvent()->GetEventID(); G4int trackid = track->GetTrackID(); G4double xx = track->GetPosition().x(); //trackpos= postpos G4double yy = track->GetPosition().y(); G4double zz = track->GetPosition().z(); G4double weight = track->GetWeight() ; G4cout << " BaseFLUX " << std::setprecision(3) << trackKE/MeV << " " << weight << " " << partName << " "<< preVol << " " << postVol << " " << preProc << " " << postProc << " " << evtid << " " << trackid << track->GetCreatorProcess()->GetProcessName() << " cr_pr|in " << track->GetLogicalVolumeAtVertex()->GetName() << " KE "<< track->GetVertexKineticEnergy()/MeV << " xyz_m " << std::setprecision(3) << xx/m << " " << std::setprecision(3) << yy/m << " " << std::setprecision(3) << zz/m << " st " << step->GetPostStepPoint()->GetStepStatus() << G4endl; } ////############################################ //NEUTRONS FLUX at Target and MonolithSteel G4bool HgNflux = false; if(HgNflux && partName =="neutron") { if(postVol != "HgTarget" && preVol == "HgTarget" ) G4cout << "NFLUX_HgTargetOUT " << partName << " preKE "<< std::setprecision(3) << preKE/MeV << " " << preVol << " pre:post " << postVol << G4endl; if(preVol != "HgTarget" && postVol == "HgTarget" ) G4cout << "NFLUX_HgTargetIN " << partName << " preKE "<< std::setprecision(3) << preKE/MeV << " " << preVol << " pre:post " << postVol << G4endl; } G4bool monoNflux = false; if(monoNflux && partName =="neutron") { G4double monOuterRad = 5.*m; G4double monTopZ = 8.*m; G4double monBotZ = -4.5*m; if(postVol != "MonolithSteelCyl" && preVol == "MonolithSteelCyl" ) { G4double radius = std::sqrt((track->GetPosition().x()) * (track->GetPosition().x()) + (track->GetPosition().y()) * (track->GetPosition().y()) ); G4double prerad = std::sqrt((step->GetPreStepPoint()->GetPosition().x()) * (step->GetPreStepPoint()->GetPosition().x()) + (step->GetPreStepPoint()->GetPosition().y()) * (step->GetPreStepPoint()->GetPosition().y()) ); G4double postrad = std::sqrt((step->GetPostStepPoint()->GetPosition().x()) * (step->GetPostStepPoint()->GetPosition().x()) + (step->GetPostStepPoint()->GetPosition().y()) * (step->GetPostStepPoint()->GetPosition().y()) ); G4double zpos = step->GetPostStepPoint()->GetPosition().z(); if(radius > monOuterRad - kCarTolerance || (zpos > monTopZ-kCarTolerance || zpos < monBotZ+kCarTolerance) ) { G4cout << "NFLUX_monoOUT " << partName << " preKE " << std::setprecision(3)<< preKE/MeV << " postKE " << std::setprecision(3) << step->GetPostStepPoint()->GetKineticEnergy() << " "<< preVol<< " pre:post " << postVol << " trackrad " << radius << " prerad " << prerad << " postrad " << postrad << " stat.pre:post " << step->GetPreStepPoint()->GetStepStatus() << " " << step->GetPostStepPoint()->GetStepStatus() << " postxyz " << std::setprecision(3) << step->GetPostStepPoint()->GetPosition().x() << " " << std::setprecision(3) << step->GetPostStepPoint()->GetPosition().y() << " " << std::setprecision(3) << step->GetPostStepPoint()->GetPosition().z() << " prexyz " << std::setprecision(3) << step->GetPreStepPoint()->GetPosition().x() << " " << std::setprecision(3) << step->GetPreStepPoint()->GetPosition().y() << " " << std::setprecision(3) << step->GetPreStepPoint()->GetPosition().z() << G4endl; } } } //####################################### //COUNT NEUTRONS produced by proton G4bool verbNeutCount = false; if(verbNeutCount) { static G4int numNeutPerEvt = 0; static G4int staticEvtId = 0; static G4int beamSec = 0; G4double neutronsKE = 0; G4int numNthisStep = 0; G4String thisSecPart = ""; G4String thisProc = ""; G4bool pFlag = true; G4bool isBeamProt = (track->GetParentID()==0) ? true:false; //if(track->GetParentID() == 0)//parent is primary proton //{ const std::vector<const G4Track*>* secVec=step->GetSecondaryInCurrentStep(); //G4int thisPDG = (*secVec)[secN]->GetDynamicParticle()->GetPDGcode(); if(postVol == "HgTarget") { for(size_t secN = 0; secN < secVec->size(); secN++) { thisSecPart = (*secVec)[secN]->GetDynamicParticle()->GetDefinition()->GetParticleName(); if(thisSecPart == "neutron"|| thisSecPart == "proton") { if(pFlag) { G4cout << "particle: "<<partName << " ke(mev) "<< std::setprecision(2) << preKE/MeV << " Nsec " << secVec->size() << " postVol " << postVol ; if(isBeamProt){ G4cout << " :primary ";} G4cout << G4endl; pFlag = false; } const G4VProcess* creator = (*secVec)[secN]->GetCreatorProcess(); if(creator) thisProc = creator->GetProcessName(); G4double keThisN = (*secVec)[secN]->GetDynamicParticle()->GetKineticEnergy(); G4cout << " \t sec: " << thisSecPart<< " ke: " << std::setprecision(2) << keThisN/MeV << " " << thisProc; if(isBeamProt){ G4cout << " \t firstImpact "; } G4cout << G4endl; if(thisSecPart == "neutron") { numNthisStep++; if(isBeamProt)beamSec++; neutronsKE = neutronsKE + keThisN; } }//n //else G4cout <<"other : " << thisSecPart << G4endl; }//for }//if Target // }//primary G4int thisEvtId = G4RunManager::GetRunManager()->GetCurrentEvent()->GetEventID(); if(thisEvtId == staticEvtId) numNeutPerEvt += numNthisStep; else { if(numNeutPerEvt>0 ) G4cout << "####Evt " << thisEvtId <<" numN " << numNeutPerEvt << " firstImpact " << beamSec << G4endl; numNeutPerEvt = numNthisStep; beamSec = 0;//only first time needed } staticEvtId = thisEvtId; }//if countN //########## End of Neutron Count //NEUTRONS FLUX escaping to outofWorld G4bool nFluxOutOfWorld = false; if(nFluxOutOfWorld) { static G4String preVolStatic = ""; static G4double preX = -1; static G4double preY = -1; static G4double preZ = -1; static G4double prePx = -1; static G4double prePy = -1; static G4double prePz = -1; static G4double preKe = -1; static G4bool preExists = false; if(track->GetCurrentStepNumber() <=1) preExists = false; preVolStatic = preVol; G4bool verb2 = false; if(verb2) { if(track->GetNextVolume()) G4cout << "# " << track->GetCurrentStepNumber() << postVol << " " << track->GetVolume()->GetName() //<< " preVol " << preVol //<< " pos: " << track->GetPosition().x() //present or post //<< " " << track->GetPosition().y() //<< " " << track->GetPosition().z() << " prexist " << preExists << G4endl; } G4bool takeIt = (track->GetCurrentStepNumber() ==0 && track->GetTrackID()==1) ? false:true; if( preVolStatic== "SNSTargetDetector") takeIt = false; if( preVolStatic== "World") takeIt = false; if( takeIt && pre && pdgCode==2112 && ( postVol=="SNSTargetDetector"|| postVol=="World"|| postVol=="OutOfWorld" ) ) { preExists = true; preX = pre->GetPosition().x(); preY = pre->GetPosition().y(); preZ = pre->GetPosition().z(); // track->GetPosition().z() prePx = pre->GetMomentumDirection().x();//track->GetMomentumDirection().x() prePy = pre->GetMomentumDirection().y(); prePz = pre->GetMomentumDirection().z(); preKe = pre->GetKineticEnergy(); } //TODO reset when out of scope if( track->GetNextVolume() == 0 || postVol =="OutOfWorld" || postVol=="World" ) { if(preExists && pdgCode ==2112 ) //neutron { RunAction::CountParticles(); G4bool verb = false; if(verb) { G4cout //<< " :PART: " << " " << partName << " " << preVolStatic << " " << preX << " " << preY << " " << preZ << " current " << track->GetPosition().x() << " " << track->GetPosition().y() << " " << track->GetPosition().z() << " Mom: " << prePx << " " << prePy << " " << prePz << " ke " << preKe/MeV //<< " time " << track->GetGlobalTime() //<< " :proc: " << postProc //<< " :prestKE: " << pre->GetKineticEnergy()/MeV //<< " :poststKE: " << pre->GetKineticEnergy()/MeV //<< " trackL " << track->GetTrackLength() //<< " stepL " << track->GetStepLength() //VERTEX (,where this track was created) information //<< " MeV.VertMom: " << track->GetVertexMomentumDirection().x() //<< " " << track->GetVertexMomentumDirection().y() //<< " " << track->GetVertexMomentumDirection().z() //<< "ke " << track->GetVertexKineticEnergy()/MeV //<< " "<< track->GetLogicalVolumeAtVertex()->GetName() //<< " VertPOS: "<< track->GetVertexPosition().x() //<< " "<< track->GetVertexPosition().y() //<< " "<< track->GetVertexPosition().z() //<< " "<< track->GetCreatorProcess()->GetProcessName() //NOTE: check before //<< " model "<< track->GetCreatorModelName() << G4endl; } //if verb //fill in root file man->FillSNSneutronFlux(0, preKE/MeV, preKe/MeV, pdgCode, 0, track->GetPosition().x()/m, track->GetPosition().y()/m, track->GetPosition().z()/m, 0, 0, 0, 0, 0);//, prePx, prePy, prePz ); } } } //END of FIND NEUTRONS escaping to outofWorld //############################################## //SCINTILLATOR DETECTOR analysis process // G4bool verbScint = false; //set verbScint if secondary size>0 //if( step->GetSecondaryInCurrentStep()->size() ) verbScint=true; if(verbScint) { G4ParticleDefinition* particleType = track->GetDefinition(); G4double edep = step->GetTotalEnergyDeposit()/MeV; G4StepPoint* preStep = step->GetPreStepPoint(); G4StepPoint* postStep = step->GetPostStepPoint(); //NOTE prestep and postep may not exist in some cases ! //const G4VProcess* postDefStep = postStep->GetProcessDefinedStep(); G4cout << " eDep " << std::setprecision(4) << edep; if( postProc) { G4cout << " post:" << postProc << " "; }else { G4cout << " postproc: NONE ";} if( preProc) { G4cout << " pre:" << preProc << " "; }else { G4cout << " preproc: NONE ";} if(trackProc){ G4cout<< " trackProc:" <<trackProc << " "; }else { G4cout << " trackProc: NONE ";} //if(step->GetTrack()->GetParentID()==0) //fpSteppingManager available only in SteppingAction class G4TrackVector* fSecondary=fpSteppingManager->GetfSecondary(); G4int nSecThisStep = fpSteppingManager->GetfN2ndariesAtRestDoIt() + fpSteppingManager->GetfN2ndariesAlongStepDoIt() + fpSteppingManager->GetfN2ndariesPostStepDoIt(); //const std::vector<const G4Track*>* fSecondary=step->GetSecondaryInCurrentStep(); size_t secSize = fSecondary->size();// total of all steaps so far. //if( secSize > 0) G4cout << "secSize: " << secSize-nSecThisStep ; G4double totalKE = 0; G4double totalEn = track->GetTotalEnergy(); // track->GetDynamicParticle()->GetTotalEnergy(); if(postStep) totalKE = postStep->GetKineticEnergy(); size_t nOptPhot = 0; G4bool printPhot = true; if( nSecThisStep>0 ) //nSecThisStep = that of this step { for(size_t lp1 = secSize-nSecThisStep; lp1 < secSize; lp1++) { //(*fSecondary)[lp1]->GetDynamicParticle()->GetKineticEnergy(); //GetTotalEnergy(); // G4String secPart = (*fSecondary)[lp1]->GetDefinition()->GetParticleName(); // if(secPart =="neutron" || secPart == "proton" || secPart == "deutron" // ||secPart == "alpha" || secPart == "gamma" || secPart=="e-"||secPart=="e+") // { totalKE = totalKE + (*fSecondary)[lp1]-> GetDynamicParticle()->GetKineticEnergy(); totalEn = totalEn + (*fSecondary)[lp1]->GetTotalEnergy(); // } //if(postProc ~ /neutronInelastic|nCapture/ ) // G4cout<< " part: " << (*fSecondary)[lp1]->GetDefinition()->GetParticleName() // << " KE: " << (*fSecondary)[lp1]->GetDynamicParticle()->GetKineticEnergy() // << G4endl; //optical photon if(particleType == G4OpticalPhoton::Definition()) { nOptPhot++; if(printPhot) { G4cout << " Op.photon "; const G4VProcess* creator=(*fSecondary)[lp1]->GetCreatorProcess(); if(creator) { G4cout<<" sec.proc: "<< creator->GetProcessName(); printPhot= false; } G4cout << " " << G4endl; }//print }//if phot }//for }//if secSize G4cout<<" nOptPhot: "<< G4endl; G4bool verb4 = false; if(verb4) { G4double preTotE = -1; if(preStep) { preKE = preStep->GetKineticEnergy()/MeV ; preTotE = preStep->GetTotalEnergy()/MeV; } G4double postKE = -1, postTotE = -1; if(postStep) { postKE = postStep->GetKineticEnergy()/MeV; postTotE = postStep->GetTotalEnergy()/MeV; } G4cout << partName << " trackID: " << track->GetTrackID() << " :prestKE: " << std::setprecision(4)<< preKE << " :poststKE: " << std::setprecision(4) << postKE << " :preTotEn: " << std::setprecision(4)<< preTotE << " :postTotEn: " << std::setprecision(4)<< postTotE //<< " :TotEn: " << std::setprecision(4) << totalEn/MeV //<< " :totalKE: " << std::setprecision(4) << totalKE/MeV << " :trackKE: " << std::setprecision(4) << track->GetKineticEnergy() /MeV << " :eDep: " << std::setprecision(4) << edep << " :-deltaE: " << std::setprecision(4)<< -step->GetDeltaEnergy()/MeV //<< " :-deltaE-edep: "<< std::setprecision(4)<< -step->GetDeltaEnergy()/MeV-edep //<< " :niel: " << std::setprecision(4)<< step->GetNonIonizingEnergyDeposit()/MeV //<< " :proc: "<< postStep->GetProcessDefinedStep()->GetProcessName() << G4endl; } if( nSecThisStep>0 ) G4cout<<" EndProcSearchKeyWord "<< G4endl; //don't delete this, just comment it }//verbose //#################################### }//end of userSteppingAction
G4VParticleChange* RichG4Cerenkov::PostStepDoIt(const G4Track& aTrack, const G4Step& aStep){ // Do not do RICH stuff // return G4Cerenkov::PostStepDoIt(aTrack,aStep); // Get the current point G4Material &material=*aTrack.GetMaterial(); if(!(material.GetName()==aerogel_name) && !(material.GetName()==naf_name)) return G4Cerenkov::PostStepDoIt(aTrack,aStep); // This is a RICH radiator, use the tools already available to compute everything // Copy and paste of original G4Cerenkov class aParticleChange.Initialize(aTrack); const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle(); const G4Material* aMaterial = aTrack.GetMaterial(); G4StepPoint* pPreStepPoint = aStep.GetPreStepPoint(); G4StepPoint* pPostStepPoint = aStep.GetPostStepPoint(); if(!aParticle || !aMaterial || !pPreStepPoint || !pPostStepPoint)return pParticleChange; G4ThreeVector x0 = pPreStepPoint->GetPosition(); G4ThreeVector p0 = aStep.GetDeltaPosition().unit(); G4double t0 = pPreStepPoint->GetGlobalTime(); G4MaterialPropertiesTable* aMaterialPropertiesTable = aMaterial->GetMaterialPropertiesTable(); if (!aMaterialPropertiesTable) return pParticleChange; const G4MaterialPropertyVector* Rindex = aMaterialPropertiesTable->GetProperty("RINDEX"); if (!Rindex) return pParticleChange; // particle charge const G4double charge = aParticle->GetDefinition()->GetPDGCharge(); // particle beta const G4double beta = (pPreStepPoint ->GetBeta() + pPostStepPoint->GetBeta())/2.; G4double step_length = aStep.GetStepLength(); G4double MeanNumberOfPhotons=GetAverageNumberOfPhotons(charge,beta,step_length/cm,x0,p0); // Copy and paste from the original function if (MeanNumberOfPhotons <= 0.0) { // return unchanged particle and no secondaries aParticleChange.SetNumberOfSecondaries(0); return pParticleChange; } MeanNumberOfPhotons *= step_length; G4int NumPhotons = (G4int) G4Poisson(MeanNumberOfPhotons); if (NumPhotons <= 0) { // return unchanged particle and no secondaries aParticleChange.SetNumberOfSecondaries(0); return pParticleChange; } //////////////////////////////////////////////////////////////// aParticleChange.SetNumberOfSecondaries(NumPhotons); if (fTrackSecondariesFirst) { if (aTrack.GetTrackStatus() == fAlive ) aParticleChange.ProposeTrackStatus(fSuspend); } //////////////////////////////////////////////////////////////// G4double BetaInverse = 1./beta; for (G4int i = 0; i < NumPhotons; i++) { G4double sampledEnergy, sampledRI; G4double cosTheta, sin2Theta; geant _RINDEX; geant _p; _p=getmomentum_(&_RINDEX); // _p is in GeV/c, _RINDEX is the refractive index for this guy sampledEnergy=_p*GeV; // energy in G4 units sampledRI=_RINDEX; cosTheta = BetaInverse / sampledRI; sin2Theta = (1.0 - cosTheta)*(1.0 + cosTheta); // Generate random position of photon on cone surface // defined by Theta G4double rand = G4UniformRand(); G4double phi = twopi*rand; G4double sinPhi = sin(phi); G4double cosPhi = cos(phi); // calculate x,y, and z components of photon energy // (in coord system with primary particle direction // aligned with the z axis) G4double sinTheta = sqrt(sin2Theta); G4double px = sinTheta*cosPhi; G4double py = sinTheta*sinPhi; G4double pz = cosTheta; // Create photon momentum direction vector // The momentum direction is still with respect // to the coordinate system where the primary // particle direction is aligned with the z axis G4ParticleMomentum photonMomentum(px, py, pz); // Rotate momentum direction back to global reference // system photonMomentum.rotateUz(p0); // Determine polarization of new photon G4double sx = cosTheta*cosPhi; G4double sy = cosTheta*sinPhi; G4double sz = -sinTheta; G4ThreeVector photonPolarization(sx, sy, sz); // Rotate back to original coord system photonPolarization.rotateUz(p0); // Generate a new photon: G4DynamicParticle* aCerenkovPhoton = new G4DynamicParticle(G4OpticalPhoton::OpticalPhoton(), photonMomentum); aCerenkovPhoton->SetPolarization (photonPolarization.x(), photonPolarization.y(), photonPolarization.z()); aCerenkovPhoton->SetKineticEnergy(sampledEnergy); rand = G4UniformRand(); G4double delta=rand*aStep.GetStepLength(); G4double deltaTime = delta / ((pPreStepPoint->GetVelocity()+ pPostStepPoint->GetVelocity())/2.); G4double aSecondaryTime = t0 + deltaTime; G4ThreeVector aSecondaryPosition = x0 + rand * aStep.GetDeltaPosition(); G4Track* aSecondaryTrack = new G4Track(aCerenkovPhoton,aSecondaryTime,aSecondaryPosition); aSecondaryTrack->SetTouchableHandle(aStep.GetPreStepPoint()->GetTouchableHandle()); aSecondaryTrack->SetParentID(aTrack.GetTrackID()); aParticleChange.AddSecondary(aSecondaryTrack); } if (verboseLevel>0) { G4cout << "\n Exiting from RichG4Cerenkov::DoIt -- NumberOfSecondaries = " << aParticleChange.GetNumberOfSecondaries() << G4endl; } return pParticleChange; }
G4VParticleChange* RichG4OpBoundaryProcess::PostStepDoIt(const G4Track& aTrack, const G4Step& aStep) { // I do not know where these guys come, but I kill them explicitly if(isnan(aTrack.GetPosition()[0]) || isnan(aTrack.GetMomentum()[0])){ aParticleChange.ProposeTrackStatus(fStopAndKill); return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep); } // Initialization aParticleChange.Initialize(aTrack); // Get the properties of the particle const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle(); G4double thePhotonMomentum = aParticle->GetTotalMomentum(); G4StepPoint* pPreStepPoint = aStep.GetPreStepPoint(); G4StepPoint* pPostStepPoint = aStep.GetPostStepPoint(); if(isnan(pPreStepPoint->GetPosition()[0])){ aParticleChange.ProposeTrackStatus(fStopAndKill); return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep); } if (pPostStepPoint->GetStepStatus() != fGeomBoundary){ return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep); } if (aTrack.GetStepLength()<=1e-7){ return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep); } G4Material *Material1 = pPreStepPoint -> GetMaterial(); G4Material *Material2 = pPostStepPoint -> GetMaterial(); // Follow the standard path if not RICH radiator to vacuum transition if(!(Material1->GetName()==aerogel_name)) return G4OpBoundaryProcess::PostStepDoIt(aTrack,aStep); // return TOFG4OpBoundaryProcess::PostStepDoIt(aTrack,aStep); if(Material2->GetName()==aerogel_name) return G4OpBoundaryProcess::PostStepDoIt(aTrack,aStep); // return TOFG4OpBoundaryProcess::PostStepDoIt(aTrack,aStep); if(!Material1->GetMaterialPropertiesTable() || !Material2->GetMaterialPropertiesTable()){ aParticleChange.ProposeTrackStatus(fStopAndKill); return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep); } OldMomentum = aParticle->GetMomentumDirection(); OldPolarization = aParticle->GetPolarization(); // Get the normal of the surface G4ThreeVector theGlobalPoint = pPostStepPoint->GetPosition(); G4Navigator* theNavigator = G4TransportationManager::GetTransportationManager()-> GetNavigatorForTracking(); G4ThreeVector theLocalPoint = theNavigator-> GetGlobalToLocalTransform(). TransformPoint(theGlobalPoint); G4ThreeVector theLocalNormal; // Normal points back into volume G4bool valid; theLocalNormal = theNavigator->GetLocalExitNormal(&valid); if (valid) { theLocalNormal = -theLocalNormal; } else { aParticleChange.ProposeTrackStatus(fStopAndKill); return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep); G4cerr << " RichG4OpBoundaryProcess/PostStepDoIt(): " << " The Navigator reports that it returned an invalid normal" << G4endl; G4Exception("RichG4OpBoundaryProcess::PostStepDoIt", "Invalid Surface Normal", EventMustBeAborted, "Geometry must return valid surface normal"); // return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep); } theGlobalNormal = theNavigator->GetLocalToGlobalTransform(). TransformAxis(theLocalNormal); if (OldMomentum * theGlobalNormal > 0.0) { theGlobalNormal = -theGlobalNormal; } // Get the refractive index G4ThreeVector position = aTrack.GetPosition(); const G4double cvpwl=1.2398E-6; G4double wavelength=cvpwl/thePhotonMomentum*GeV; Rindex1=RichRadiatorTileManager::get_refractive_index(position[0]/cm,position[1]/cm,wavelength); G4MaterialPropertyVector* Rindex = Material2->GetMaterialPropertiesTable()->GetProperty("RINDEX"); if(!Rindex){ aParticleChange.ProposeTrackStatus(fStopAndKill); return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep); } #if G4VERSION_NUMBER >945 Rindex2 = Rindex->Value(thePhotonMomentum); #else Rindex2 = Rindex->GetProperty(thePhotonMomentum); #endif // SKIP photons exiting through the lateral sides of the tiles if(std::abs(theGlobalNormal[2])<1e-6){ cout <<" g4rich::abs "<<std::abs(theGlobalNormal[2])<<" "<<abs(theGlobalNormal[2])<<" "<<theGlobalNormal[2]<<endl; return G4OpBoundaryProcess::PostStepDoIt(aTrack,aStep); } // if(abs(theGlobalNormal[2])<1e-6) return TOFG4OpBoundaryProcess::PostStepDoIt(aTrack,aStep); DielectricDielectric(); // return G4OpBoundaryProcess::PostStepDoIt(aTrack, aStep); //CJD this solves the f*****g problem NewMomentum = NewMomentum.unit(); NewPolarization = NewPolarization.unit(); if(Material1->GetName()==aerogel_name){ // Simple parameterization to get the right number of p.e. if(G4UniformRand()<RICHDB::scatloss){ aParticleChange.ProposeTrackStatus(fStopAndKill); return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep); } // Forward scattering if(G4UniformRand()<RICHDB::scatprob){ // Aerogel scattering effect double phi=2*M_PI*G4UniformRand(); double theta=sqrt(-2*log(G4UniformRand()))*RICHDB::scatang; // Build the vector G4ThreeVector direction(sin(theta)*cos(phi),sin(theta)*sin(phi),cos(theta)); direction.rotateUz(NewMomentum); NewMomentum=direction.unit(); } } aParticleChange.ProposeMomentumDirection(NewMomentum); aParticleChange.ProposePolarization(NewPolarization); return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep); }