9 #include "G4Version.hh"
10 #include "G4TouchableHistory.hh"
13 #include "G4ParticleDefinition.hh"
14 #include "G4StepPoint.hh"
15 #include "G4ThreeVector.hh"
16 #include "G4Poisson.hh"
17 #include "G4VSolid.hh"
18 #include "G4ReflectedSolid.hh"
19 #include "G4Material.hh"
20 #include "G4MaterialPropertyVector.hh"
29 : G4VSensitiveDetector(
name )
32 , m_nNumberOfTDSimHits(0)
33 , m_HitColl(hitCollectionName)
35 for(
int i=0;
i < 4;
i++){
36 for(
int j=0; j < 32; j++){
47 for(
int i=0;
i < 4;
i++)
49 for(
int j=0; j < 32; j++)
69 G4cout <<
"AFP_TDSensitiveDetector::ProcessHits" << G4endl;
75 int nParticleEncoding=-1;
76 float fKineticEnergy=0.0;
77 float fEnergyDeposit=0.0;
78 float fWaveLength=0.0;
85 float fGlobalTime=0.0;
93 G4Track* pTrack = pStep->GetTrack();
94 G4ParticleDefinition* pParticleDefinition = pTrack->GetDefinition();
95 G4StepPoint* pPreStepPoint = pStep->GetPreStepPoint();
96 G4StepPoint* pPostStepPoint = pStep->GetPostStepPoint();
97 G4ThreeVector PreStepPointPos = pPreStepPoint->GetPosition();
98 G4ThreeVector PostStepPointPos = pPostStepPoint->GetPosition();
100 nTrackID=pTrack->GetTrackID();
101 fKineticEnergy = pPreStepPoint->GetKineticEnergy();
102 fEnergyDeposit = pStep->GetTotalEnergyDeposit();
104 fPreStepX = PreStepPointPos.x();
105 fPreStepY = PreStepPointPos.y();
106 fPreStepZ = PreStepPointPos.z();
107 fPostStepX = PostStepPointPos.x();
108 fPostStepY = PostStepPointPos.y();
109 fPostStepZ = PostStepPointPos.z();
110 nParticleEncoding = pParticleDefinition->GetPDGEncoding();
114 G4TouchableHandle touch1 = pPreStepPoint->GetTouchableHandle();
115 G4VPhysicalVolume* volume = touch1->GetVolume();
116 G4String VolumeName = volume->GetName();
124 G4cout <<
"hit volume name is " << VolumeName << G4endl;
126 G4cout <<
"global, x_pre: " << fPreStepX <<
", y_pre: " << fPreStepY <<
", z_pre: " << fPreStepZ << G4endl;
127 G4cout <<
"global, x_post: " << fPostStepX <<
", y_post: " << fPostStepY <<
", z_post: " << fPostStepZ << G4endl;
132 memset(&szbuff[0],0,
sizeof(szbuff));
133 strncpy(szbuff,VolumeName.data(),
sizeof(szbuff));
134 szbuff[
sizeof(szbuff)-1] =
'\0';
135 ppv1=strchr(szbuff,
'[');
136 ppv2=strchr(szbuff,
']');
138 G4cout <<
"ERROR: Invalid format of volume name " << VolumeName << G4endl;
143 nStationID=10*(szbuff[3]-0x30)+(szbuff[4]-0x30);
144 nDetectorID=
atoi(ppv1+1);
186 #if G4VERSION_NUMBER < 1100
187 if ( (VolumeName.contains(
"TDQuarticBarVacBorder")) && pParticleDefinition->GetPDGCharge() !=0 )
189 if ( (
G4StrUtil::contains(VolumeName,
"TDQuarticBarVacBorder")) && pParticleDefinition->GetPDGCharge() !=0 )
192 nQuarticID=szbuff[7]-0x30;
205 #if G4VERSION_NUMBER < 1100
206 if ( (bRes=VolumeName.contains(
"TDQuarticBar[")) )
211 nQuarticID=szbuff[7]-0x30;
220 const G4TouchableHistory* myTouch =
static_cast<const G4TouchableHistory*
>(pPreStepPoint->GetTouchable());
224 const G4AffineTransform transformation = myTouch->GetHistory()->GetTopTransform();
225 G4ThreeVector PreStepPointPos2 = transformation.TransformPoint(PreStepPointPos);
226 G4ThreeVector PostStepPointPos2 = transformation.TransformPoint(PostStepPointPos);
228 G4String shape( myTouch->GetSolid()->GetEntityType() );
230 G4ThreeVector normpX( 1., 0., 0.);
231 G4ThreeVector normnX(-1., 0., 0.);
232 G4ThreeVector normpY( 0., 1., 0.);
233 G4ThreeVector normnY( 0.,-1., 0.);
234 G4ThreeVector normpZ( 0., 0., 1.);
235 G4ThreeVector normnZ( 0., 0.,-1.);
248 G4double PreProtonX = PreStepPointPos2.x();
249 G4double PreProtonY = PreStepPointPos2.y();
250 G4double PreProtonZ = PreStepPointPos2.z();
252 G4double PostProtonX = PostStepPointPos2.x();
253 G4double PostProtonY = PostStepPointPos2.y();
254 G4double PostProtonZ = PostStepPointPos2.z();
256 G4ThreeVector
p0 = pStep->GetDeltaPosition().unit();
258 G4Material*
mat = pStep->GetTrack()->GetMaterial();
259 G4MaterialPropertiesTable *matPropTable =
mat->GetMaterialPropertiesTable();
261 G4MaterialPropertyVector* Rind = matPropTable->GetProperty(
"RINDEX");
263 G4MaterialPropertyVector* Alen = matPropTable->GetProperty(
"ABSLENGTH");
265 const G4double
charge = pParticleDefinition->GetPDGCharge();
266 const G4double
beta = (pPreStepPoint->GetBeta() + pPostStepPoint->GetBeta()) / 2.;
267 G4double BetaInverse = 1. /
beta;
271 #if G4VERSION_NUMBER < 1100
272 G4double Pmin = Rind->GetMinLowEdgeEnergy();
274 G4double Pmax = Rind->GetMaxLowEdgeEnergy();
276 G4double Pmin = Rind->GetMinEnergy();
277 G4double Pmax = Rind->GetMaxEnergy();
279 G4double
dp = Pmax - Pmin;
281 G4double maxCosTheta = BetaInverse / Rind->GetMinValue();
282 G4double maxSin2Theta = (1.0 - maxCosTheta) * (1.0 + maxCosTheta);
285 G4double meanRI = .5*(Rind->GetMinValue() + Rind->GetMaxValue());
289 if (MeanNumberOfPhotons <= 0.0)
return 1;
291 G4double step_length = pStep->GetStepLength();
293 MeanNumberOfPhotons = MeanNumberOfPhotons * step_length *
dp;
294 G4int NumPhotons = (G4int) G4Poisson( MeanNumberOfPhotons );
295 if (NumPhotons <= 0)
return 1;
298 G4int NumPhotonsCuts=0;
299 for (G4int
I = 0;
I < NumPhotons;
I++) {
302 G4double sampledEnergy, sampledRI;
303 G4double cosTheta, sin2Theta;
307 rand = G4UniformRand();
308 sampledEnergy = Pmin +
rand *
dp;
310 sampledRI = Rind->Value(sampledEnergy);
311 cosTheta = BetaInverse / sampledRI;
313 sin2Theta = (1.0 - cosTheta)*(1.0 + cosTheta);
314 rand = G4UniformRand();
316 }
while (
rand * maxSin2Theta > sin2Theta);
319 rand = G4UniformRand();
321 G4double sinPhi =
sin(
phi);
322 G4double cosPhi =
cos(
phi);
327 G4double sinTheta = sqrt(sin2Theta);
328 G4double
px = sinTheta*cosPhi;
329 G4double
py = sinTheta*sinPhi;
330 G4double
pz = cosTheta;
331 G4ParticleMomentum photonMomentum(
px,
py,
pz);
332 photonMomentum.rotateUz(
p0);
334 G4double PX = photonMomentum.getX();
335 G4double PY = photonMomentum.getY();
336 G4double PZ = photonMomentum.getZ();
340 G4double PYp = PY/sqrt(PX*PX+PY*PY+PZ*PZ);
341 G4double PZp = PZ/sqrt(PX*PX+PY*PY+PZ*PZ);
343 G4double PYt = PY/sqrt(PY*PY+PZ*PZ);
344 G4double PZt = PZ/sqrt(PY*PY+PZ*PZ);
347 cosPhi = (PYp*PYt + PZp*PZt);
352 G4double cosThetaC = sqrt(1.-1./sampledRI/sampledRI);
353 if (sqrt(1.-cosPhi*cosPhi)>cosThetaC)
continue;
354 if (sqrt(1.-cosTheta*cosTheta)*cosPhi>cosThetaC)
continue;
357 rand = G4UniformRand();
358 G4double PhotonX = PreProtonX + (PostProtonX-PreProtonX)*
rand;
359 G4double PhotonY = PreProtonY + (PostProtonY-PreProtonY)*
rand;
360 G4double PhotonZ = PreProtonZ + (PostProtonZ-PreProtonZ)*
rand;
361 G4ThreeVector PhotonPos(PhotonX,PhotonY,PhotonZ);
362 G4double PhotonR = sqrt( (PreProtonX-PhotonX)*(PreProtonX-PhotonX) + (PreProtonY-PhotonY)*(PreProtonY-PhotonY) + (PreProtonZ-PhotonZ)*(PreProtonZ-PhotonZ) );
368 Y0 = ((G4ReflectedSolid *)(myTouch->GetSolid()))->DistanceToOut(PhotonPos, normnY);
369 Y0 = Y0/cosTheta/cosPhi;
380 float Pabs = 1. -
exp( - Y0/Alen->Value(sampledEnergy) );
381 rand = G4UniformRand();
382 if (Pabs>
rand)
continue;
385 rand = G4UniformRand();
391 float fGlobalTime2 = fGlobalTime;
397 if (sampledEnergy > (Pmin+.5*
dp)) EdndE = (sampledRI - Rind->Value(sampledEnergy-0.0001*
CLHEP::eV))/0.0001*sampledEnergy/
CLHEP::eV;
399 else EdndE = (Rind->Value(sampledEnergy+0.0001*
CLHEP::eV) - sampledRI)/0.0001*sampledEnergy/
CLHEP::eV;
404 G4cout <<
"FastCher EdndE: " << EdndE << G4endl;
414 int nSensitiveElementID=-1;
415 if(nQuarticID==0) { nSensitiveElementID=1; }
416 else if(nQuarticID==1) { nSensitiveElementID=3; }
418 m_HitColl->Emplace(
m_nHitID,nTrackID,nParticleEncoding,fKineticEnergy,fEnergyDeposit,
419 fWaveLength,PhotonX,PhotonY,PhotonZ,(PhotonX+PX),(PhotonY+PY),(PhotonZ+PZ),
420 fGlobalTime2,nStationID,nDetectorID,nSensitiveElementID);
424 else if(nStationID==0 && nQuarticID==1)
m_nNOfTDSimHits[1][nDetectorID]++;
425 else if(nStationID==3 && nQuarticID==0)
m_nNOfTDSimHits[2][nDetectorID]++;
426 else if(nStationID==3 && nQuarticID==1)
m_nNOfTDSimHits[3][nDetectorID]++;
430 G4cout <<
"FastCher number of photons: " << NumPhotonsCuts << G4endl;
443 G4cout <<
"AFP_TDSensitiveDetector::EndOfAthenaEvent: Total number of hits in TD: " <<
m_nNumberOfTDSimHits << G4endl;
444 G4cout <<
"AFP_TDSensitiveDetector::EndOfAthenaEvent: *************************************************************" << G4endl;
449 for(
int i=0;
i < 4;
i++){
450 for(
int j=0; j < 32; j++){