76 G4VParticleChange* particleChange = pRegProcess->PostStepDoIt(track, step);
78 if (splittingFactor == 1)
79 {
return particleChange;}
81 G4double parentEk = track.GetKineticEnergy();
82 if (parentEk < 0.8*splittingThresholdEK)
83 {
return particleChange;}
85 G4int nSecondaries = particleChange->GetNumberOfSecondaries();
86 if (nSecondaries == 0)
87 {
return particleChange;}
90 if (excludeWeight1Particles && std::abs(track.GetWeight() - 1.0) > std::numeric_limits<double>::epsilon())
91 {
return particleChange;}
93 if (track.GetWeight() > muonSplittingExclusionWeight)
94 {
return particleChange;}
96 G4bool muonPresent =
false;
97 std::vector<G4int> secondaryPDGIDs;
98 for (G4int i = 0; i < nSecondaries; i++)
100 G4int secondaryPDGID = particleChange->GetSecondary(i)->GetDefinition()->GetPDGEncoding();
101 muonPresent = std::abs(secondaryPDGID) == 13 || muonPresent;
104 {
return particleChange;}
107 std::vector<G4Track*> originalSecondaries;
108 std::vector<G4Track*> originalMuons;
109 for (G4int i = 0; i < nSecondaries; i++)
111 G4Track* secondary = particleChange->GetSecondary(i);
112 if (std::abs(secondary->GetDefinition()->GetPDGEncoding()) != 13)
113 {originalSecondaries.push_back(secondary);}
115 {originalMuons.push_back(secondary);}
118 G4int nOriginalSecondaries = nSecondaries;
120 particleChange->Clear();
122 G4double spf2 = splitting->
Value(parentEk);
123 G4int thisTimeSplittingFactor =
static_cast<G4int
>(std::round(spf2));
127 G4int maxTrials = 10 * thisTimeSplittingFactor;
128 G4int nSuccessfulMuonSplits = 0;
130 std::vector<G4Track*> newMuons;
131 while (iTry < maxTrials && nSuccessfulMuonSplits < thisTimeSplittingFactor-1)
134 particleChange->Clear();
135 particleChange = pRegProcess->PostStepDoIt(track, step);
136 G4bool success =
false;
137 for (G4int i = 0; i < particleChange->GetNumberOfSecondaries(); i++)
139 G4Track* sec = particleChange->GetSecondary(i);
140 if (std::abs(sec->GetDefinition()->GetPDGEncoding()) == 13)
142 newMuons.push_back(sec);
148 particleChange->Clear();
150 {nSuccessfulMuonSplits++;}
153 particleChange->Clear();
154 particleChange->SetNumberOfSecondaries(nOriginalSecondaries +
static_cast<G4int
>(newMuons.size()));
156 G4bool originalSetSecondaryWeightByProcess = particleChange->IsSecondaryWeightSetByProcess();
157 particleChange->SetSecondaryWeightByProcess(
true);
158 if (nSuccessfulMuonSplits == 0)
160 for (
auto secondary : originalSecondaries)
161 {particleChange->AddSecondary(secondary);}
162 for (
auto muon : originalMuons)
163 {particleChange->AddSecondary(muon);}
164 return particleChange;
168 G4double weightFactor = 1.0 / (
static_cast<G4double
>(nSuccessfulMuonSplits) + 1.0);
170 for (
auto aSecondary : originalSecondaries)
171 {particleChange->AddSecondary(aSecondary);}
172 for (
auto originalMuon : originalMuons)
174 G4double existingWeight = originalMuon->GetWeight();
175 G4double newWeight = existingWeight * weightFactor;
176 originalMuon->SetWeight(newWeight);
177 particleChange->AddSecondary(originalMuon);
179 for (
auto newMuon : newMuons)
181 G4double existingWeight = newMuon->GetWeight();
182 G4double newWeight = existingWeight * weightFactor;
183 newMuon->SetWeight(newWeight);
184 particleChange->AddSecondary(newMuon);
190 particleChange->SetSecondaryWeightByProcess(originalSetSecondaryWeightByProcess);
193 return particleChange;