LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
larg4::MuNuclearSplittingProcessXSecBias Class Reference

#include "MuNuclearSplittingProcessXSecBias.h"

Inheritance diagram for larg4::MuNuclearSplittingProcessXSecBias:

Public Member Functions

 MuNuclearSplittingProcessXSecBias ()
 
 ~MuNuclearSplittingProcessXSecBias ()
 
void SetNSplit (G4int nTrx, G4int xB=0, G4double xFac=1)
 
void SetIsActive (G4bool doIt)
 
G4VParticleChange * PostStepDoIt (const G4Track &track, const G4Step &step)
 
G4VParticleChange * AlongStepDoIt (const G4Track &track, const G4Step &step)
 
virtual G4double AlongStepGetPhysicalInteractionLength (const G4Track &track, G4double previousStepSize, G4double currentMinimumStep, G4double &proposedSafety, G4GPILSelection *selection)
 
virtual G4double PostStepGetPhysicalInteractionLength (const G4Track &track, G4double previousStepSize, G4ForceCondition *condition)
 

Protected Member Functions

virtual void ResetNumberOfInteractionLengthLeft ()
 

Private Member Functions

G4double XBiasSurvivalProbability ()
 
G4double XBiasSecondaryWeight ()
 
G4double GetTotalNumberOfInteractionLengthTraversed ()
 

Private Attributes

G4int fNSplit
 
G4bool fActive
 
G4int xBiasMode
 
G4double eFactor
 
G4VParticleChange fParticleChange
 
G4double wc
 
G4double theInitialNumberOfInteractionLength
 

Detailed Description

Definition at line 24 of file MuNuclearSplittingProcessXSecBias.h.

Constructor & Destructor Documentation

larg4::MuNuclearSplittingProcessXSecBias::MuNuclearSplittingProcessXSecBias ( )
inline

Definition at line 27 of file MuNuclearSplittingProcessXSecBias.h.

27 {};
larg4::MuNuclearSplittingProcessXSecBias::~MuNuclearSplittingProcessXSecBias ( )
inline

Definition at line 28 of file MuNuclearSplittingProcessXSecBias.h.

28 {};

Member Function Documentation

G4VParticleChange * larg4::MuNuclearSplittingProcessXSecBias::AlongStepDoIt ( const G4Track &  track,
const G4Step &  step 
)

Definition at line 167 of file MuNuclearSplittingProcessXSecBias.cxx.

References eFactor, fParticleChange, w, x, xBiasMode, XBiasSecondaryWeight(), and XBiasSurvivalProbability().

Referenced by SetIsActive().

169  {
170 
171  wc = 1.0;
172 
173  if (xBiasMode == 2) {
174  /* I don't understand this. If I new it and Initialize(track) it works, but
175  it goes off and grinds through the event.
176  If I try to use pRegProcess->AlongStepDoIt() it crashes
177  at the GetParentWeight() just below.
178  */
179  G4VParticleChange* pC = new G4VParticleChange();
180  pC->Initialize(track);
181  //pC = pRegProcess->AlongStepDoIt( track, step);
182 
183  G4double nw = pC->GetParentWeight() * XBiasSecondaryWeight();
184  pC->ProposeParentWeight(nw);
185  for (G4int i = 0; i < pC->GetNumberOfSecondaries(); i++)
186  pC->GetSecondary(i)->SetWeight(nw);
187  //
188  if (G4UniformRand() < XBiasSurvivalProbability()) {
189  pC->SetNumberOfSecondaries(pC->GetNumberOfSecondaries() + 1);
190  G4ThreeVector mDirection = track.GetDynamicParticle()->GetMomentumDirection();
191  G4DynamicParticle* aD =
192  new G4DynamicParticle((track.GetDynamicParticle())->GetDefinition(),
193  G4LorentzVector(mDirection,
194  (track.GetDynamicParticle())->GetKineticEnergy() +
195  step.GetTotalEnergyDeposit()));
196  G4Track* secTrk =
197  new G4Track(aD,
198  track.GetGlobalTime(),
199  track.GetPosition()); // +step.GetDeltaTime(), ,+step.GetDeltaPosition()
200  secTrk->SetGoodForTrackingFlag(true);
201  pC->AddSecondary(secTrk); // Add the primary right back.
202  pC->GetSecondary(pC->GetNumberOfSecondaries() - 1)
203  ->SetWeight(XBiasSurvivalProbability() * track.GetWeight());
204  //pC->ProposeTrackStatus(fStopAndKill); // 8-June-2011-21:36 MDT, from Finland, I (EDC) added this. Seems right. Makes it go, anyway. Almost too fast.
205  }
206 
207  return pC;
208  }
209  else if (xBiasMode == 1) {
210  fParticleChange.Initialize(track);
211  G4double s = step.GetStepLength();
212  G4double x = pRegProcess->GetCurrentInteractionLength();
213  //fParticleChange = &(pRegProcess->AlongStepDoIt( track, step));
214  wc = exp(-(1. - eFactor) * s / x);
215  G4double w = wc * fParticleChange.GetParentWeight();
216  fParticleChange.SetParentWeightByProcess(false);
217  fParticleChange.ProposeParentWeight(w);
218  if (w > 100) {
219  // G4cout << " MNSPXSB.AlongStepDoit(): GPW is " << w/wc << " wc = " << wc << ", CIL = "<< x << G4endl;
220  }
221 
222  return &fParticleChange;
223  }
224 
225  if (xBiasMode != 1 && xBiasMode != 2) {
226  throw cet::exception("Incorrectly set Bias Mode. ")
227  << "Set XBiasMode to 0 or 1. " << xBiasMode << " not allowed!\n";
228  }
229  fParticleChange.Initialize(track);
230  return &fParticleChange;
231  }
Float_t x
Definition: compare.C:6
Float_t track
Definition: plot.C:35
Float_t w
Definition: plot.C:20
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
G4double larg4::MuNuclearSplittingProcessXSecBias::AlongStepGetPhysicalInteractionLength ( const G4Track &  track,
G4double  previousStepSize,
G4double  currentMinimumStep,
G4double &  proposedSafety,
G4GPILSelection *  selection 
)
virtual

Definition at line 273 of file MuNuclearSplittingProcessXSecBias.cxx.

References eFactor, and xBiasMode.

Referenced by SetIsActive().

279  {
280  if (xBiasMode == 2) {
281  // I am pretty sure this mode does not work because MuNuclear doesn't interact
282  // AlongStep. Below often (always?) returns a negative number, which I have to
283  // swizzle.
284  G4double intLen;
285  intLen =
286  (1. / eFactor) * pRegProcess->AlongStepGetPhysicalInteractionLength(
287  track, previousStepSize, currentMinimumStep, proposedSafety, selection);
288  if (intLen < 0)
289  return currentMinimumStep;
290  else
291  return intLen;
292  }
293  else
294  return DBL_MAX;
295  }
Float_t track
Definition: plot.C:35
G4double larg4::MuNuclearSplittingProcessXSecBias::GetTotalNumberOfInteractionLengthTraversed ( )
private

Definition at line 251 of file MuNuclearSplittingProcessXSecBias.cxx.

References theInitialNumberOfInteractionLength.

Referenced by XBiasSecondaryWeight(), and XBiasSurvivalProbability().

252  {
253  return theInitialNumberOfInteractionLength - G4VProcess::theNumberOfInteractionLengthLeft;
254  }
G4VParticleChange * larg4::MuNuclearSplittingProcessXSecBias::PostStepDoIt ( const G4Track &  track,
const G4Step &  step 
)

Definition at line 42 of file MuNuclearSplittingProcessXSecBias.cxx.

References util::abs(), e, eFactor, fNSplit, x, xBiasMode, XBiasSecondaryWeight(), and XBiasSurvivalProbability().

Referenced by SetIsActive().

44  {
45 
46  G4VParticleChange* pChange = pRegProcess->PostStepDoIt(track, step);
47  pChange->SetVerboseLevel(0);
48  pChange->SetSecondaryWeightByProcess(true);
49 
50  G4double secWeight = 1.0;
51  if (fNSplit >= 1) secWeight = 1.0 / fNSplit;
52  std::vector<G4Track*> secondaries; // Secondary store
53 
54  G4double nw = 1.0;
55  // Let's go bias the underlying xsection.
56  if (xBiasMode == 1) {
57  G4double s = step.GetStepLength();
58  G4double x = pRegProcess->GetCurrentInteractionLength();
59  nw = pChange->GetParentWeight();
60  // need to undo the change made to the parent track in
61  // most recent step (1/wc).
62  // It seems to be possible to get here w.o. first having hit the
63  // AlongStep Method that initialied wc. So protect against division y 0.
64  if (wc < 1.0e-10) wc = 1.0;
65  nw *= 1 / wc * (1. - exp(-s / x)) / (1 - exp(-eFactor * s / x));
66  G4cout << " MNSPXSB.PostStepDoit(): original wt = " << pChange->GetParentWeight()
67  << " eF = " << eFactor << G4endl;
68  G4cout << " MNSPXSB.PostStepDoit(): New weight = " << nw << " wc = " << wc << " s= " << s
69  << " x = " << x << G4endl;
70  ((G4ParticleChange*)pChange)->ProposeParentWeight(nw);
71  }
72  else if (xBiasMode == 2) {
73  nw = pChange->GetParentWeight() * XBiasSecondaryWeight();
74  ((G4ParticleChange*)pChange)->ProposeParentWeight(nw);
75  // for (G4int i = 0; i < pChange->GetNumberOfSecondaries(); i++)
76  //pChange->GetSecondary(i)->SetWeight(nw);
77  if (G4UniformRand() <
78  XBiasSurvivalProbability()) { // need to add the primary back in to balance the weight
79  // the position of the extra track should be moved to the next volume, but I don't know how yet.
80  // need to change number of secondary first before adding an additional track
81  pChange->SetNumberOfSecondaries(pChange->GetNumberOfSecondaries() + 1);
82  G4ThreeVector mDirection = track.GetDynamicParticle()->GetMomentumDirection();
83  G4DynamicParticle* aD =
84  new G4DynamicParticle((track.GetDynamicParticle())->GetDefinition(),
85  G4LorentzVector(mDirection,
86  (track.GetDynamicParticle())->GetKineticEnergy() +
87  step.GetTotalEnergyDeposit()));
88  G4Track* secTrk = new G4Track(aD, step.GetDeltaTime(), step.GetDeltaPosition());
89  pChange->AddSecondary(secTrk);
90  pChange->GetSecondary(pChange->GetNumberOfSecondaries() - 1)
91  ->SetWeight(XBiasSurvivalProbability() * track.GetWeight());
92  }
93  else {
94  nw = track.GetWeight();
95  pChange->ProposeParentWeight(nw);
96  }
97  }
98 
99  secWeight = secWeight * nw;
100 
101  // Loop over PostStepDoIt method to generate multiple secondaries.
102  // The point is for each value of ii up to Nsplit we want to re-toss
103  // all secondaries for the muNucl process. Each toss gives back numSec
104  // secondaries, which will be a different sample of species/momenta each time.
105  G4VParticleChange* particleChange = new G4VParticleChange();
106 
107  for (unsigned int ii = 0; ii < (unsigned int)fNSplit; ii++) {
108  particleChange = pRegProcess->PostStepDoIt(track, step);
109  if (!particleChange)
110  throw std::runtime_error(
111  "MuNuclearSplittingProcessXSecBias::PostStepDoIt(): no particle change");
112  G4int j(0);
113  G4int numSec(particleChange->GetNumberOfSecondaries());
114  // Don't change weight of last secondary. It's the just-added primary in this mode.
115  for (j = 0; j < numSec; j++) {
116  G4Track* newSec = new G4Track(*(particleChange->GetSecondary(j)));
117  G4String pdgstr = newSec->GetParticleDefinition()->GetParticleName();
118  //G4double ke = newSec->GetKineticEnergy()/GeV;
119  G4int pdg = newSec->GetParticleDefinition()->GetPDGEncoding();
120  if (abs(pdg) == 310 || abs(pdg) == 311 || abs(pdg) == 3122 || abs(pdg) == 2112) {
121  // std::cout << "MuNuclSplProc: Creating " << pdgstr << " of Kinetic Energy " << ke << " GeV. numSec is " << j << std::endl;
122 
123  if (pdg == G4KaonZeroShort::KaonZeroShort()->GetPDGEncoding() && G4UniformRand() < 0.50) {
124  pdg = G4KaonZeroLong::KaonZeroLong()->GetPDGEncoding();
125  pdgstr = G4KaonZeroLong::KaonZeroLong()->GetParticleName();
126  G4LorentzVector pK0L(
127  newSec->GetMomentum(),
128  TMath::Sqrt(TMath::Power(G4KaonZeroLong::KaonZeroLong()->GetPDGMass(), 2) +
129  TMath::Power(newSec->GetMomentum().mag(), 2)));
130  G4DynamicParticle* newK0L = new G4DynamicParticle(G4KaonZeroLong::KaonZeroLong(), pK0L);
131 
132  G4Track* newSecK0L = new G4Track(newK0L, track.GetGlobalTime(), track.GetPosition());
133  secondaries.push_back(newSecK0L);
134  }
135  else {
136  secondaries.push_back(newSec);
137  }
138  }
139  }
140  }
141 
142  pChange->SetNumberOfSecondaries(secondaries.size());
143  pChange->SetSecondaryWeightByProcess(true);
144  //pChange->ProposeTrackStatus(fStopAndKill); // End of the story for this muon.
145 
146  //int numSecAdd = secondaries.size();
147  std::vector<G4Track*>::iterator iter = secondaries.begin(); // Add all secondaries
148  while (iter != secondaries.end()) {
149  G4Track* myTrack = *iter;
150  G4String pdgstr = myTrack->GetParticleDefinition()->GetParticleName();
151  G4double ke = myTrack->GetKineticEnergy() / CLHEP::GeV;
152  G4int pdg = myTrack->GetParticleDefinition()->GetPDGEncoding();
153  if (abs(pdg) == 130 || abs(pdg) == 310 || abs(pdg) == 311 || abs(pdg) == 3122 ||
154  abs(pdg) == 2112) {
155  if (pdg != 2112)
156  std::cout << "MuNuclSplXSB(): Adding " << pdgstr << " of Kinetic Energy and weight " << ke
157  << " GeV and " << secWeight << "." << std::endl;
158 
159  myTrack->SetWeight(secWeight);
160  pChange->AddSecondary(myTrack);
161  }
162  iter++;
163  }
164  return pChange;
165  }
Float_t x
Definition: compare.C:6
intermediate_table::iterator iterator
constexpr auto abs(T v)
Returns the absolute value of the argument.
Float_t e
Definition: plot.C:35
Float_t track
Definition: plot.C:35
G4double larg4::MuNuclearSplittingProcessXSecBias::PostStepGetPhysicalInteractionLength ( const G4Track &  track,
G4double  previousStepSize,
G4ForceCondition *  condition 
)
virtual

Definition at line 256 of file MuNuclearSplittingProcessXSecBias.cxx.

References eFactor, and xBiasMode.

Referenced by SetIsActive().

260  {
261  // I believe this is the money line for the whole thing. By shrinking the
262  // interaction length in MuNuclear's process, it's more likely that
263  // this process will be chosen in the competition among processes.
264  if (xBiasMode) {
265  G4double psgPIL = (1. / eFactor) * pRegProcess->PostStepGetPhysicalInteractionLength(
266  track, previousStepSize, condition);
267  return psgPIL;
268  }
269 
270  return pRegProcess->PostStepGetPhysicalInteractionLength(track, previousStepSize, condition);
271  }
Float_t track
Definition: plot.C:35
virtual void larg4::MuNuclearSplittingProcessXSecBias::ResetNumberOfInteractionLengthLeft ( )
inlineprotectedvirtual

Definition at line 51 of file MuNuclearSplittingProcessXSecBias.h.

References theInitialNumberOfInteractionLength.

52  {
53  G4VProcess::theNumberOfInteractionLengthLeft = -std::log(G4UniformRand());
54  theInitialNumberOfInteractionLength = G4VProcess::theNumberOfInteractionLengthLeft;
55  }
void larg4::MuNuclearSplittingProcessXSecBias::SetIsActive ( G4bool  doIt)
inline
void larg4::MuNuclearSplittingProcessXSecBias::SetNSplit ( G4int  nTrx,
G4int  xB = 0,
G4double  xFac = 1 
)
inline
G4double larg4::MuNuclearSplittingProcessXSecBias::XBiasSecondaryWeight ( )
private

Definition at line 243 of file MuNuclearSplittingProcessXSecBias.cxx.

References eFactor, and GetTotalNumberOfInteractionLengthTraversed().

Referenced by AlongStepDoIt(), and PostStepDoIt().

244  {
245  G4double result = 0;
246  G4double nLTraversed = GetTotalNumberOfInteractionLengthTraversed();
247  result = 1. / eFactor * std::exp(-nLTraversed / eFactor * (1 - 1. / eFactor));
248  return result;
249  }
G4double larg4::MuNuclearSplittingProcessXSecBias::XBiasSurvivalProbability ( )
private

Definition at line 233 of file MuNuclearSplittingProcessXSecBias.cxx.

References eFactor, and GetTotalNumberOfInteractionLengthTraversed().

Referenced by AlongStepDoIt(), and PostStepDoIt().

234  {
235  G4double result = 0;
236  G4double nLTraversed = GetTotalNumberOfInteractionLengthTraversed();
237  G4double biasedProbability = 1. - std::exp(-nLTraversed);
238  G4double realProbability = 1 - std::exp(-nLTraversed / eFactor);
239  result = (biasedProbability - realProbability) / biasedProbability;
240  return result;
241  }

Member Data Documentation

G4bool larg4::MuNuclearSplittingProcessXSecBias::fActive
private

Definition at line 60 of file MuNuclearSplittingProcessXSecBias.h.

Referenced by SetIsActive().

G4int larg4::MuNuclearSplittingProcessXSecBias::fNSplit
private

Definition at line 59 of file MuNuclearSplittingProcessXSecBias.h.

Referenced by PostStepDoIt(), and SetNSplit().

G4VParticleChange larg4::MuNuclearSplittingProcessXSecBias::fParticleChange
private

Definition at line 64 of file MuNuclearSplittingProcessXSecBias.h.

Referenced by AlongStepDoIt().

G4double larg4::MuNuclearSplittingProcessXSecBias::theInitialNumberOfInteractionLength
private
G4double larg4::MuNuclearSplittingProcessXSecBias::wc
private

Definition at line 66 of file MuNuclearSplittingProcessXSecBias.h.

G4int larg4::MuNuclearSplittingProcessXSecBias::xBiasMode
private

The documentation for this class was generated from the following files: