Beispiel #1
0
// 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;
}
Beispiel #2
0
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;
}