75 G4VParticleChange* particleChange = pRegProcess->PostStepDoIt(track, step);
77 if (splittingFactor == 1)
78 {
return particleChange;}
80 G4double parentEk = track.GetKineticEnergy();
81 if (parentEk < 0.8*splittingThresholdEK)
82 {
return particleChange;}
84 G4int nSecondaries = particleChange->GetNumberOfSecondaries();
85 if (nSecondaries == 0)
86 {
return particleChange;}
89 if (excludeWeight1Particles && std::abs(track.GetWeight() - 1.0) > std::numeric_limits<double>::epsilon())
90 {
return particleChange;}
92 if (track.GetWeight() > muonSplittingExclusionWeight)
93 {
return particleChange;}
95 G4bool muonPresent =
false;
96 std::vector<G4int> secondaryPDGIDs;
97 for (G4int i = 0; i < nSecondaries; i++)
99 G4int secondaryPDGID = particleChange->GetSecondary(i)->GetDefinition()->GetPDGEncoding();
100 muonPresent = std::abs(secondaryPDGID) == 13 || muonPresent;
103 {
return particleChange;}
106 std::vector<G4Track*> originalSecondaries;
107 std::vector<G4Track*> originalMuons;
108 for (G4int i = 0; i < nSecondaries; i++)
110 G4Track* secondary = particleChange->GetSecondary(i);
111 if (std::abs(secondary->GetDefinition()->GetPDGEncoding()) != 13)
112 {originalSecondaries.push_back(secondary);}
114 {originalMuons.push_back(secondary);}
117 G4int nOriginalSecondaries = nSecondaries;
119 particleChange->Clear();
121 G4double spf2 = splitting->
Value(parentEk);
122 G4int thisTimeSplittingFactor =
static_cast<G4int
>(std::round(spf2));
126 G4int maxTrials = 10 * thisTimeSplittingFactor;
127 G4int nSuccessfulMuonSplits = 0;
129 std::vector<G4Track*> newMuons;
130 while (iTry < maxTrials && nSuccessfulMuonSplits < thisTimeSplittingFactor-1)
133 particleChange->Clear();
134 particleChange = pRegProcess->PostStepDoIt(track, step);
135 G4bool success =
false;
136 for (G4int i = 0; i < particleChange->GetNumberOfSecondaries(); i++)
138 G4Track* sec = particleChange->GetSecondary(i);
139 if (std::abs(sec->GetDefinition()->GetPDGEncoding()) == 13)
141 newMuons.push_back(sec);
147 particleChange->Clear();
149 {nSuccessfulMuonSplits++;}
152 particleChange->Clear();
153 particleChange->SetNumberOfSecondaries(nOriginalSecondaries +
static_cast<G4int
>(newMuons.size()));
155 G4bool originalSetSecondaryWeightByProcess = particleChange->IsSecondaryWeightSetByProcess();
156 particleChange->SetSecondaryWeightByProcess(
true);
157 if (nSuccessfulMuonSplits == 0)
159 for (
auto secondary : originalSecondaries)
160 {particleChange->AddSecondary(secondary);}
161 for (
auto muon : originalMuons)
162 {particleChange->AddSecondary(muon);}
163 return particleChange;
167 G4double weightFactor = 1.0 / (
static_cast<G4double
>(nSuccessfulMuonSplits) + 1.0);
169 for (
auto aSecondary : originalSecondaries)
170 {particleChange->AddSecondary(aSecondary);}
171 for (
auto originalMuon : originalMuons)
173 G4double existingWeight = originalMuon->GetWeight();
174 G4double newWeight = existingWeight * weightFactor;
175 originalMuon->SetWeight(newWeight);
176 particleChange->AddSecondary(originalMuon);
178 for (
auto newMuon : newMuons)
180 G4double existingWeight = newMuon->GetWeight();
181 G4double newWeight = existingWeight * weightFactor;
182 newMuon->SetWeight(newWeight);
183 particleChange->AddSecondary(newMuon);
189 particleChange->SetSecondaryWeightByProcess(originalSetSecondaryWeightByProcess);
192 return particleChange;