// 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
}
Example #2
0
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);
}