53 nFinal(0), totalMass(0.), massExcess(0.), weightMax(0.), nTrials(0) {;}
60 const std::vector<G4double>& masses,
61 std::vector<G4LorentzVector>& finalState) {
68 const G4int maxNumberOfLoops = 10000;
74 }
while ( (!
AcceptEvent()) && nTrials < maxNumberOfLoops );
75 if ( nTrials >= maxNumberOfLoops ) {
77 ed <<
" Failed sampling after maxNumberOfLoops attempts : forced exit" <<
G4endl;
87 nFinal = masses.size();
88 msum.resize(nFinal, 0.);
89 msq.resize(nFinal, 0.);
91 std::partial_sum(masses.begin(), masses.end(), msum.begin());
92 std::transform(masses.begin(), masses.end(), masses.begin(), msq.begin(),
93 std::multiplies<G4double>());
94 totalMass = msum.back();
95 massExcess = initialMass - totalMass;
100 G4cout <<
" totalMass " << totalMass <<
" massExcess " << massExcess
113 rndm.resize(nFinal-2,0.);
114 std::generate(rndm.begin(), rndm.end(), uniformRand);
115 std::sort(rndm.begin(), rndm.end());
124 const std::vector<G4double>& masses) {
130 meff.push_back(masses[0]);
131 for (
size_t i=1; i<nFinal-1; i++) {
132 meff.push_back(rndm[i-1]*massExcess + msum[i]);
135 meff.push_back(initialMass);
136 pd.push_back(
TwoBodyMomentum(meff[nFinal-1], meff[nFinal-2], masses[nFinal-1]));
153 for (
size_t i=1; i<nFinal; i++) {
154 weightMax *=
TwoBodyMomentum(massExcess+msum[i], msum[i-1], masses[i]);
166 return (std::accumulate(pd.begin(), pd.end(), 1./weightMax,
167 std::multiplies<G4double>()));
182 std::vector<G4LorentzVector>& finalState) {
185 finalState.resize(nFinal);
187 for (
size_t i=0; i<nFinal; i++) {
190 G4cout <<
" finalState[" << i <<
"] " << finalState[i] <<
G4endl;
198 const std::vector<G4double>& masses,
199 std::vector<G4LorentzVector>& finalState) {
204 finalState[i].setVectM(
G4ThreeVector(0.,pd[i],0.),masses[i]);
208 finalState[i].setVectM(
G4ThreeVector(0.,-pd[i-1],0.),masses[i]);
213 G4cout <<
" initialized Py " << -pd[i-1] <<
" phi " << phi
214 <<
" theta " << theta <<
G4endl;
219 esys = std::sqrt(pd[i]*pd[i]+meff[i]*meff[i]);
221 gamma = esys / meff[i];
224 G4cout <<
" esys " << esys <<
" beta " << beta <<
" gamma " << gamma
228 for (
size_t j=0; j<=i; j++) {
229 finalState[j].rotateZ(theta).rotateY(phi);
230 finalState[j].setY(gamma*(finalState[j].y() + beta*finalState[j].e()));
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
CLHEP::Hep3Vector G4ThreeVector
G4GLOB_DLL std::ostream G4cout
void GenerateMomenta(const std::vector< G4double > &masses, std::vector< G4LorentzVector > &finalState)
void Initialize(G4double initialMass, const std::vector< G4double > &masses)
G4double ComputeWeight() const
G4HadPhaseSpaceGenbod(G4int verbose=0)
void AccumulateFinalState(size_t i, const std::vector< G4double > &masses, std::vector< G4LorentzVector > &finalState)
virtual void GenerateMultiBody(G4double initialMass, const std::vector< G4double > &masses, std::vector< G4LorentzVector > &finalState)
G4bool AcceptEvent() const
void ComputeWeightScale(const std::vector< G4double > &masses)
void FillEnergySteps(G4double initialMass, const std::vector< G4double > &masses)
const G4String & GetName() const
void PrintVector(const std::vector< G4double > &v, const G4String &name, std::ostream &os) const
G4int GetVerboseLevel() const
G4double TwoBodyMomentum(G4double M0, G4double M1, G4double M2) const