LBNEPerfectFocusProcess.cc
Go to the documentation of this file.
1 //
2 // For perfect focusing. The OO way. (Will probably end-up
3 // increase tracking time for everybody..Hoefully not too much ..)
4 //
7 #include "G4ios.hh"
9 #include "LBNERunManager.hh"
10 
12  ;
13 }
15 ;
16 }
17 LBNEPerfectFocusProcess::LBNEPerfectFocusProcess(const G4String &aName, G4ProcessType aType):
18 G4VDiscreteProcess(aName, aType)
19  {
20  enablePostStepDoIt = true;
21  const G4RunManager *pRunManager = G4RunManager::GetRunManager();
22  const LBNEDetectorConstruction *LBNEDetCr = reinterpret_cast<const LBNEDetectorConstruction*>(pRunManager->GetUserDetectorConstruction());
24  const double rr = LBNEDetCr->GetRCoordOutOfTarget();
25  fRCoordOutOfTargetSq = rr*rr;
26  fParticleChange = 0;
27 // std::cerr << " LBNEPerfectFocusProcess::LBNEPerfectFocusProcess, got here! fZCoordForPerfectFocusing = "
28 // << fZCoordForPerfectFocusing << " And quit " << std::endl; exit(2);
29 }
31 //
32 // Define the change of direction as Post step, if not already done for this track.
33 // The new particle will be considered as a secondary, preserving the particle ancestry for the dk2nu Ntuple.
34 //
35 
36 LBNEPerfectFocusParticleChange* LBNEPerfectFocusProcess::PostStepDoIt (const G4Track &aTrack, const G4Step &stepData) {
37 
38 
39  delete fParticleChange; // start by deleting the previous instance of the particle change..
40  fParticleChange = 0;
41  const G4DynamicParticle *pDef = aTrack.GetDynamicParticle();
42  const int pId = pDef->GetDefinition()->GetPDGEncoding();
43  if ((std::abs(pId) != 211) && (std::abs(pId) !=321)) return 0; // Should not occur
44  const double totalP = pDef->GetTotalMomentum();
45  const LBNETrackInformation *oldTrInfo = reinterpret_cast<const LBNETrackInformation*>(aTrack.GetUserInformation());
46  if (oldTrInfo->GetPFFlag() == 1) return 0;
47 
48  // Now stack it's replacement. Define it as a secondary.
49  //
50  LBNETrackInformation *newTrInfo = new LBNETrackInformation();
51  newTrInfo->SetDecayCode(oldTrInfo->GetDecayCode());
52  newTrInfo->SetTgen(oldTrInfo->GetTgen());
53  newTrInfo->SetNImpWt(oldTrInfo->GetNImpWt());
54  G4ThreeVector aNewPos(stepData.GetPostStepPoint()->GetPosition());
55  //
56  // Displace the track radially and in Z to avoid having it going through the perfect focusing again.
57  //
58  aNewPos[2] += 1.*CLHEP::mm;
59  const double phi = std::atan2(aNewPos[1], aNewPos[0]);
60  aNewPos[0] += std::cos(phi)*1.*CLHEP::mm;
61  aNewPos[1] += std::sin(phi)*1.*CLHEP::mm;
62  newTrInfo->SetPFFlag(1);
63  newTrInfo->SetDecayCode(oldTrInfo->GetDecayCode());
64  newTrInfo->SetTgen(oldTrInfo->GetTgen());
65  newTrInfo->SetNImpWt(oldTrInfo->GetNImpWt());
66  //
67  G4ThreeVector aNewP(0., 0., totalP);
68  G4DynamicParticle *aNewPart = new G4DynamicParticle(pDef->GetDefinition(), aNewP);
69  G4Track *aNewTrack = new G4Track(aNewPart, aTrack.GetLocalTime(), aNewPos);
70 // aNewTrack->SetUserInformation(newTrInfo); // It will get lost, G4 tracking Kernel does not bother to copy the User information.
71 // So, we coCLHEP::mment this out... Sad...
72  delete newTrInfo;
73  //
75  fParticleChange->AddSecondary(aNewTrack);
76  fParticleChange->ProposeTrackStatus( fStopAndKill );
77  // Check the flag..
78  //
79 // std::cerr << " LBNEPerfectFocusProcess::PostStepDoIt .. Total P " << totalP
80 // << " Position " << aNewPos << " old Tr ID " << aTrack.GetTrackID()
81 // << " New Id " << aNewTrack->GetTrackID()
82 // << " zAttrigger " << fZAtTrigger << " rAttrigger " << std::sqrt(fRAtTriggerSq) << std::endl;
83 // const LBNETrackInformation *newTrInfoCheck = reinterpret_cast<const LBNETrackInformation*>(aNewTrack->GetUserInformation());
84 // std::cerr << " Pointer for Tr User Info " << newTrInfoCheck << " New track PFFlag " << newTrInfoCheck->GetPFFlag() << std::endl;
85  return fParticleChange;
86 
87 }
88 
89 //
90 // Not actually called
91 //
92 G4double LBNEPerfectFocusProcess::PostStepGetPhysicalInteractionLength (const G4Track &aTrack, G4double previousStepSize,
93  G4ForceCondition *condition)
94 {
95 // std::cerr << " LBNEPerfectFocusProcess::GetPhysicalInteractionLength, at " << aTrack.GetPosition() << std::endl;
96  *condition = NotForced;
97  return this->GetFreePath(aTrack, previousStepSize);
98 }
99 
100 G4double LBNEPerfectFocusProcess::GetMeanFreePath(const G4Track &aTrack, G4double previousStepSize, G4ForceCondition* aCond) {
101 // std::cerr << " LBNEPerfectFocusProcess::GetMeanFreePath, at " << aTrack.GetPosition() << std::endl;
102  *aCond = NotForced;
103  return this->GetFreePath(aTrack, previousStepSize);
104 }
105 
106 
107 
108 G4double LBNEPerfectFocusProcess::GetFreePath(const G4Track &aTrack, G4double previousStepSize) {
109 
110  // In this context, we have no use for this 2nd parameter in the argument call.
111  // However, one can not change the interface, G4VDiscreteProcess OO design.. We use to flag a crazy
112  // value to avoid a compiler warning. (and burn some CPU cyvle, but it's good for the Grid economy.
113  // Paul Lebrun, Feb. 2015
114 
115  if (previousStepSize < -999999) std::cerr << " LBNEPerfectFocusProcess::GetFreePath, crazy prev step size.. " << std::endl;
116 // const LBNETrackInformation *oldTrInfo = reinterpret_cast<const LBNETrackInformation*>(aTrack.GetUserInformation());
117 // if (previousStepSize < 1.0e-4) return previousStepSize;
118 // std::cerr << " LBNEPerfectFocusProcess::GetMeanFreePath, got here! flag = " << oldTrInfo->GetPFFlag() << std::endl;
119 // if (oldTrInfo->GetPFFlag() == 1) return 1.0e103; // we are done, the change of direction already occured. DOes not currently work!!!
120  if (fZCoordForPerfectFocusing < 0. ) {
121  const G4ThreeVector posT = aTrack.GetPosition();
122  const double radSq= posT[0]*posT[0] + posT[1]*posT[1];
123  if ((std::abs(radSq - fRCoordOutOfTargetSq) < 0.5*CLHEP::mm) && (posT[2] < 5000.*CLHEP::mm)) {
124  // it is unlikely that we will ever have a target longer than 5 meters
125  fRAtTriggerSq = radSq;
126  fZAtTrigger = posT[2];
127 // std::cerr << " LBNEPerfectFocusProcess::GetMeanFreePath, at crit. radius " << std::sqrt(rAtTriggerSq) << std::endl;
128  return 1.0e-5*CLHEP::mm;
129  } else {
130  return 1.0e103;
131  }
132  } else {
133  if(aTrack.GetPosition()[2] > fZCoordForPerfectFocusing && (fZStart < fZCoordForPerfectFocusing)) {
134  // If the track has been created downstream of fZCoordForPerfectFocusing, via an other process, mean free path inf.
135  fZAtTrigger = aTrack.GetPosition()[2];
136 // std::cerr << " LBNEPerfectFocusProcess::GetMeanFreePath, At Z " << zAtTrigger << std::endl;
137  return 0.00001;
138  } else {
139  return 1.0e103;
140  }
141  }
142 }
143 
144 G4bool LBNEPerfectFocusProcess::IsApplicable(const G4ParticleDefinition &pDef) {
145  int pid = pDef.GetPDGEncoding();
146  if (std::abs(pid) == 211) return true;
147  if (std::abs(pid) == 321) return true;
148  return false;
149 }
150 
152 // const LBNETrackInformation *oldTrInfo = reinterpret_cast<const LBNETrackInformation*>(aTrack->GetUserInformation());
153 // std::cerr << " LBNEPerfectFocusProcess::StartTracking, id " << aTrack->GetTrackID()
154 // << " at " << aTrack->GetPosition() << " fRCoordOutOfTargetSq " << fRCoordOutOfTargetSq << std::endl;
155  fZAtTrigger = -1.0e103;
156  const G4ThreeVector posT = aTrack->GetPosition();
157  fZStart = posT[2];
158  fRAtTriggerSq = posT[0]*posT[0] + posT[1]*posT[1];
159 
160 // exit(2);
161 }
LBNEPerfectFocusProcess(const G4String &aName="pFocus", G4ProcessType aType=fGeneral)
T abs(T value)
void SetNImpWt(G4double nimpweight)
void StartTracking(G4Track *aTrack)
void SetDecayCode(G4int decaycode)
bool IsApplicable(const G4ParticleDefinition &)
G4double PostStepGetPhysicalInteractionLength(const G4Track &track, G4double previousStepSize, G4ForceCondition *condition)
double GetFreePath(const G4Track &track, G4double previousStepSize)
G4double GetNImpWt() const
void SetTgen(G4int tgeneration)
LBNEPerfectFocusParticleChange * PostStepDoIt(const G4Track &track, const G4Step &stepData)
LBNEPerfectFocusParticleChange * fParticleChange
G4double GetMeanFreePath(const G4Track &, G4double, G4ForceCondition *)
QTextStream & endl(QTextStream &s)