59 G4cout <<
"AFP_TDSensitiveDetector::ProcessHits" << G4endl;
65 int nParticleEncoding=-1;
66 float fKineticEnergy=0.0;
67 float fEnergyDeposit=0.0;
68 float fWaveLength=0.0;
75 float fGlobalTime=0.0;
83 G4Track* pTrack = pStep->GetTrack();
84 G4ParticleDefinition* pParticleDefinition = pTrack->GetDefinition();
85 G4StepPoint* pPreStepPoint = pStep->GetPreStepPoint();
86 G4StepPoint* pPostStepPoint = pStep->GetPostStepPoint();
87 G4ThreeVector PreStepPointPos = pPreStepPoint->GetPosition();
88 G4ThreeVector PostStepPointPos = pPostStepPoint->GetPosition();
90 nTrackID=pTrack->GetTrackID();
91 fKineticEnergy = pPreStepPoint->GetKineticEnergy();
92 fEnergyDeposit = pStep->GetTotalEnergyDeposit();
94 fPreStepX = PreStepPointPos.x();
95 fPreStepY = PreStepPointPos.y();
96 fPreStepZ = PreStepPointPos.z();
97 fPostStepX = PostStepPointPos.x();
98 fPostStepY = PostStepPointPos.y();
99 fPostStepZ = PostStepPointPos.z();
100 nParticleEncoding = pParticleDefinition->GetPDGEncoding();
101 fGlobalTime = pStep->GetPreStepPoint()->GetGlobalTime()/CLHEP::picosecond;
104 G4TouchableHandle touch1 = pPreStepPoint->GetTouchableHandle();
105 G4VPhysicalVolume* volume = touch1->GetVolume();
106 G4String VolumeName = volume->GetName();
114 G4cout <<
"hit volume name is " << VolumeName << G4endl;
116 G4cout <<
"global, x_pre: " << fPreStepX <<
", y_pre: " << fPreStepY <<
", z_pre: " << fPreStepZ << G4endl;
117 G4cout <<
"global, x_post: " << fPostStepX <<
", y_post: " << fPostStepY <<
", z_post: " << fPostStepZ << G4endl;
122 memset(&szbuff[0],0,
sizeof(szbuff));
123 strncpy(szbuff,VolumeName.data(),
sizeof(szbuff));
124 szbuff[
sizeof(szbuff)-1] =
'\0';
125 ppv1=strchr(szbuff,
'[');
126 ppv2=strchr(szbuff,
']');
128 G4cout <<
"ERROR: Invalid format of volume name " << VolumeName << G4endl;
133 nStationID=10*(szbuff[3]-0x30)+(szbuff[4]-0x30);
134 nDetectorID=atoi(ppv1+1);
174#if G4VERSION_NUMBER < 1100
175 if ( (VolumeName.contains(
"TDQuarticBarVacBorder")) && pParticleDefinition->GetPDGCharge() !=0 )
177 if ( (G4StrUtil::contains(VolumeName,
"TDQuarticBarVacBorder")) && pParticleDefinition->GetPDGCharge() !=0 )
180 nQuarticID=szbuff[7]-0x30;
192#if G4VERSION_NUMBER < 1100
193 if ( (bRes=VolumeName.contains(
"TDQuarticBar[")) )
195 if ( (bRes=G4StrUtil::contains(VolumeName,
"TDQuarticBar[")) )
198 nQuarticID=szbuff[7]-0x30;
201 if (
m_HitColl->HasReachedLimit(nStationID, nQuarticID, nDetectorID))
return 1;
204 const G4TouchableHistory* myTouch =
static_cast<const G4TouchableHistory*
>(pPreStepPoint->GetTouchable());
208 const G4AffineTransform transformation = myTouch->GetHistory()->GetTopTransform();
209 G4ThreeVector PreStepPointPos2 = transformation.TransformPoint(PreStepPointPos);
210 G4ThreeVector PostStepPointPos2 = transformation.TransformPoint(PostStepPointPos);
212 G4String shape( myTouch->GetSolid()->GetEntityType() );
214 G4ThreeVector normpX( 1., 0., 0.);
215 G4ThreeVector normnX(-1., 0., 0.);
216 G4ThreeVector normpY( 0., 1., 0.);
217 G4ThreeVector normnY( 0.,-1., 0.);
218 G4ThreeVector normpZ( 0., 0., 1.);
219 G4ThreeVector normnZ( 0., 0.,-1.);
232 G4double PreProtonX = PreStepPointPos2.x();
233 G4double PreProtonY = PreStepPointPos2.y();
234 G4double PreProtonZ = PreStepPointPos2.z();
236 G4double PostProtonX = PostStepPointPos2.x();
237 G4double PostProtonY = PostStepPointPos2.y();
238 G4double PostProtonZ = PostStepPointPos2.z();
240 G4ThreeVector p0 = pStep->GetDeltaPosition().unit();
242 G4Material* mat = pStep->GetTrack()->GetMaterial();
243 G4MaterialPropertiesTable *matPropTable = mat->GetMaterialPropertiesTable();
245 G4MaterialPropertyVector* Rind = matPropTable->GetProperty(
"RINDEX");
247 G4MaterialPropertyVector* Alen = matPropTable->GetProperty(
"ABSLENGTH");
249 const G4double
charge = pParticleDefinition->GetPDGCharge();
250 const G4double beta = (pPreStepPoint->GetBeta() + pPostStepPoint->GetBeta()) / 2.;
251 G4double BetaInverse = 1. / beta;
255#if G4VERSION_NUMBER < 1100
256 G4double Pmin = Rind->GetMinLowEdgeEnergy();
258 G4double Pmax = Rind->GetMaxLowEdgeEnergy();
260 G4double Pmin = Rind->GetMinEnergy();
261 G4double Pmax = Rind->GetMaxEnergy();
263 G4double dp = Pmax - Pmin;
265 G4double maxCosTheta = BetaInverse / Rind->GetMinValue();
266 G4double maxSin2Theta = (1.0 - maxCosTheta) * (1.0 + maxCosTheta);
269 G4double meanRI = .5*(Rind->GetMinValue() + Rind->GetMaxValue());
272 G4double MeanNumberOfPhotons = 370.*(
charge/CLHEP::eplus)*(
charge/CLHEP::eplus)* (1.0 - 1.0/(beta * meanRI * beta * meanRI)) / (CLHEP::cm*CLHEP::eV);
273 if (MeanNumberOfPhotons <= 0.0)
return 1;
275 G4double step_length = pStep->GetStepLength();
277 MeanNumberOfPhotons = MeanNumberOfPhotons * step_length * dp;
278 G4int NumPhotons = (G4int) G4Poisson( MeanNumberOfPhotons );
279 if (NumPhotons <= 0)
return 1;
282 G4int NumPhotonsCuts=0;
283 for (G4int
I = 0;
I < NumPhotons;
I++) {
286 G4double sampledEnergy, sampledRI;
287 G4double cosTheta, sin2Theta;
291 rand = G4UniformRand();
292 sampledEnergy = Pmin + rand * dp;
294 sampledRI = Rind->Value(sampledEnergy);
295 cosTheta = BetaInverse / sampledRI;
297 sin2Theta = (1.0 - cosTheta)*(1.0 + cosTheta);
298 rand = G4UniformRand();
300 }
while (rand * maxSin2Theta > sin2Theta);
303 rand = G4UniformRand();
305 G4double sinPhi = sin(
phi);
306 G4double cosPhi = cos(
phi);
311 G4double sinTheta = sqrt(sin2Theta);
312 G4double px = sinTheta*cosPhi;
313 G4double py = sinTheta*sinPhi;
314 G4double pz = cosTheta;
315 G4ParticleMomentum photonMomentum(px, py, pz);
316 photonMomentum.rotateUz(p0);
318 G4double PX = photonMomentum.getX();
319 G4double PY = photonMomentum.getY();
320 G4double PZ = photonMomentum.getZ();
324 G4double PYp = PY/sqrt(PX*PX+PY*PY+PZ*PZ);
325 G4double PZp = PZ/sqrt(PX*PX+PY*PY+PZ*PZ);
327 G4double PYt = PY/sqrt(PY*PY+PZ*PZ);
328 G4double PZt = PZ/sqrt(PY*PY+PZ*PZ);
331 cosPhi = (PYp*PYt + PZp*PZt);
332 if (nStationID == 0) cosTheta = ( -PYt*sin(48.*CLHEP::deg) + PZt*cos(48.*CLHEP::deg) );
333 else cosTheta = ( -PYt*sin(48.*CLHEP::deg) - PZt*cos(48.*CLHEP::deg) );
336 G4double cosThetaC = sqrt(1.-1./sampledRI/sampledRI);
337 if (sqrt(1.-cosPhi*cosPhi)>cosThetaC)
continue;
338 if (sqrt(1.-cosTheta*cosTheta)*cosPhi>cosThetaC)
continue;
341 rand = G4UniformRand();
342 G4double PhotonX = PreProtonX + (PostProtonX-PreProtonX)*rand;
343 G4double PhotonY = PreProtonY + (PostProtonY-PreProtonY)*rand;
344 G4double PhotonZ = PreProtonZ + (PostProtonZ-PreProtonZ)*rand;
345 G4ThreeVector PhotonPos(PhotonX,PhotonY,PhotonZ);
346 G4double PhotonR = sqrt( (PreProtonX-PhotonX)*(PreProtonX-PhotonX) + (PreProtonY-PhotonY)*(PreProtonY-PhotonY) + (PreProtonZ-PhotonZ)*(PreProtonZ-PhotonZ) );
352 Y0 =
static_cast<G4ReflectedSolid *
>(myTouch->GetSolid())->DistanceToOut(PhotonPos, normnY);
353 Y0 = Y0/cosTheta/cosPhi;
364 float Pabs = 1. - exp( - Y0/Alen->Value(sampledEnergy) );
365 rand = G4UniformRand();
366 if (Pabs>rand)
continue;
369 rand = G4UniformRand();
375 float fGlobalTime2 = fGlobalTime;
376 fGlobalTime2 += ( PhotonR * BetaInverse / CLHEP::c_light )/CLHEP::picosecond;
381 if (sampledEnergy > (Pmin+.5*dp)) EdndE = (sampledRI - Rind->Value(sampledEnergy-0.0001*CLHEP::eV))/0.0001*sampledEnergy/CLHEP::eV;
383 else EdndE = (Rind->Value(sampledEnergy+0.0001*CLHEP::eV) - sampledRI)/0.0001*sampledEnergy/CLHEP::eV;
384 fGlobalTime2 += ( (sampledRI + EdndE)* Y0 * BetaInverse / CLHEP::c_light )/CLHEP::picosecond;
388 G4cout <<
"FastCher EdndE: " << EdndE << G4endl;
390 fWaveLength = 2.*
M_PI*CLHEP::hbarc/sampledEnergy/(CLHEP::MeV*CLHEP::nm);
393 if (
m_HitColl->HasReachedLimit(nStationID, nQuarticID, nDetectorID))
return 1;
395 int nSensitiveElementID=-1;
396 if(nQuarticID==0) { nSensitiveElementID=1; }
397 else if(nQuarticID==1) { nSensitiveElementID=3; }
399 m_HitColl->Emplace(
m_nHitID,nTrackID,nParticleEncoding,fKineticEnergy,fEnergyDeposit,
400 fWaveLength,PhotonX,PhotonY,PhotonZ,(PhotonX+PX),(PhotonY+PY),(PhotonZ+PZ),
401 fGlobalTime2,nStationID,nDetectorID,nSensitiveElementID);
402 m_HitColl->CountHit(nStationID, nQuarticID, nDetectorID);
406 G4cout <<
"FastCher number of photons: " << NumPhotonsCuts << G4endl;