// 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; }
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; }