// Primary event void PrimaryGeneratorAction::GeneratePrimaries(G4Event* anEvent) { /* * To avoid dependence on Detector Construction we will get an envelope volume * from the G4LogicalVolumeStore * * Here we will be assuming our box is sitting in a world where the radiation flux * is coming from the -x direction. Thus we will have a uniform random start location * through the YZ plane */ G4double envSizeX = 0.; G4double envSizeYZ = 0.; if ( !EnvelopeBox ) { G4LogicalVolume* envLV = G4LogicalVolumeStore::GetInstance() -> GetVolume("World"); if ( envLV ) EnvelopeBox = dynamic_cast<G4Box*>( envLV -> GetSolid() ); } if ( EnvelopeBox ) { envSizeYZ = EnvelopeBox -> GetYHalfLength() *2.; envSizeX = EnvelopeBox -> GetXHalfLength() *2.; } else { G4ExceptionDescription msg; msg << "World volume of box shape is not found.\n"; msg << "Perhaps you have changed the geometry.\n"; msg << "\nWhere has the world gone?"; G4Exception("PrimaryGeneratorAction::GeneratePrimaries()","Mycode0001",JustWarning,msg); } // We won't use the outer 10% edge G4double size = 0.9; // Since we are starting in the -x direction and firing in the x direction we want the // particles to come uniformly out of the YZ plane G4double x0 = 0.5 * envSizeX; G4double y0 = size * envSizeYZ * (G4UniformRand() - 0.5); G4double z0 = size * envSizeYZ * (G4UniformRand() - 0.5); particleGun -> SetParticlePosition(G4ThreeVector(-x0,y0,z0)); //particleGun -> SetParticleMomentumDirection(G4ThreeVector(1.0,0.,0.)); // Pure x momentum particleGun -> GeneratePrimaryVertex(anEvent); // creates the initial momentum }
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); }