Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/electromagnetic/muons/src/G4RiGeAngularGenerator.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  1 //
  2 // ********************************************************************
  3 // * License and Disclaimer                                           *
  4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.                             *
 10 // *                                                                  *
 11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                                                  *
 18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // ********************************************************************
 25 //
 26 //
 27 // -------------------------------------------------------------------
 28 //
 29 // GEANT4 Class file
 30 //
 31 //
 32 // File name:     G4RiGeAngularGenerator
 33 //
 34 // Authors:       Girardo Depaola & Ricardo Pacheco
 35 // 
 36 // Creation date: 27 October 2024
 37 //
 38 // -------------------------------------------------------------------
 39 //
 40 
 41 #include "G4RiGeAngularGenerator.hh"
 42 #include "Randomize.hh"
 43 #include "G4Log.hh"
 44 #include "G4Exp.hh"
 45 #include <CLHEP/Units/PhysicalConstants.h>
 46 
 47 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 48 
 49 G4RiGeAngularGenerator::G4RiGeAngularGenerator()
 50   : G4VEmAngularDistribution("RiGeAngularGen")
 51 {}    
 52 
 53 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 54 
 55 G4ThreeVector& 
 56 G4RiGeAngularGenerator::SampleDirection(const G4DynamicParticle* dp,
 57                                         G4double gEnergy, G4int, 
 58                                         const G4Material*)
 59 {
 60   // Sample gamma angle (Z - axis along the parent particle).
 61   G4double cost = SampleCosTheta(dp->GetKineticEnergy(), gEnergy, 
 62                                  dp->GetDefinition()->GetPDGMass());
 63   G4double sint = std::sqrt((1.0 - cost)*(1.0 + cost));
 64   G4double phi  = CLHEP::twopi*G4UniformRand(); 
 65 
 66   fLocalDirection.set(sint*std::cos(phi), sint*std::sin(phi), cost);
 67   fLocalDirection.rotateUz(dp->GetMomentumDirection());
 68 
 69   return fLocalDirection;
 70 }
 71 
 72 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 73 
 74 G4double G4RiGeAngularGenerator::SampleCosTheta(G4double primKinEnergy, 
 75             G4double gEnergy,
 76             G4double mass)
 77 {
 78   G4double gam  = 1.0 + primKinEnergy/mass;
 79   G4double rmax = gam*CLHEP::halfpi*std::min(1.0, gam*mass/gEnergy - 1.0);
 80   G4double rmax2= rmax*rmax;
 81   G4double x = G4UniformRand()*rmax2/(1.0 + rmax2);
 82 
 83   return std::cos(std::sqrt(x/(1.0 - x))/gam);
 84 }
 85 
 86 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 87 
 88 G4LorentzVector
 89 G4RiGeAngularGenerator::Sample5DPairDirections(const G4DynamicParticle* dp,
 90                  G4ThreeVector& dirElectron,
 91                  G4ThreeVector& dirPositron,
 92                  const G4double gEnergy, const G4double q2, 
 93                  const G4double gMomentum,
 94                  const G4double muFinalMomentum,
 95                  const G4double muFinalEnergy,
 96                  const G4double* randNumbs,
 97                  const G4double* W)
 98 {
 99   G4double muEnergy = dp->GetKineticEnergy();
100   G4ThreeVector muMomentumVector = dp->GetMomentum();
101   G4double muMomentum = muMomentumVector.mag();
102   G4LorentzVector muFinalFourMomentum(muEnergy, muMomentumVector);
103   
104   // Electron mass
105   G4double eMass = CLHEP::electron_mass_c2;
106   G4double eMass2 = eMass*eMass;
107 
108   // Muon mass
109   G4double muMass = dp->GetDefinition()->GetPDGMass();
110   
111   G4double mint3 = 0.;
112   G4double maxt3 = CLHEP::pi;
113   G4double Cmin = std::cos(maxt3);
114   G4double Cmax = std::cos(mint3);
115 
116   if (randNumbs[7] < W[0]) {
117     G4double A1 = -(q2 - 2.*muEnergy*gEnergy);
118     G4double B1 = -(2.*gMomentum*muMomentum);
119     G4double tginterval = G4Log((A1 + B1)/(A1 - B1))/B1;
120     
121     G4double costg = (-A1 + (A1 - B1)*G4Exp(B1*tginterval*randNumbs[1]))/B1;
122     G4double sintg = std::sqrt((1.0 - costg)*(1.0 + costg));
123     G4double phig  = CLHEP::twopi*randNumbs[2];
124     G4double sinpg = std::sin(phig);
125     G4double cospg = std::cos(phig);  
126 
127     G4ThreeVector dirGamma;
128     dirGamma.set(sintg*cospg, sintg*sinpg, costg);
129     G4LorentzVector gFourMomentum(gEnergy, dirGamma*gMomentum);
130 
131     G4double Ap = muMomentum*muMomentum + muFinalMomentum*muFinalMomentum + gMomentum*gMomentum;
132     G4double A = Ap - 2.*muMomentum*gMomentum*costg;
133     G4double B = 2.*muFinalMomentum*gMomentum*sintg*cospg;
134     G4double C = 2.*muFinalMomentum*gMomentum*costg - 2.*muMomentum*muFinalMomentum;
135     G4double absB = std::abs(B);
136     G4double t1interval = (1./(A + C + absB*mint3) - 1./(A + C + absB*maxt3))/absB;
137     G4double t1 = (-(A + C) + 1./(1./(A + C + absB*mint3) - absB*t1interval*randNumbs[0]))/absB;
138     G4double sint1 = std::sin(t1);
139     G4double cost1 = std::cos(t1);
140 
141     G4ThreeVector dirMuon;
142     dirMuon.set(sint1, 0., cost1);
143 
144     G4double cost5 = -1. + 2.*randNumbs[6];
145     G4double phi5 = CLHEP::twopi*randNumbs[8];
146 
147     G4LorentzVector eFourMomentumMQ = eDP2(q2, eMass2, eMass2, cost5, phi5);
148     G4LorentzVector pFourMomentumMQ = pDP2(eMass2, eFourMomentumMQ);
149 
150     G4LorentzVector eFourMomentum = eFourMomentumMQ.boost(gFourMomentum.boostVector());
151     G4LorentzVector pFourMomentum = pFourMomentumMQ.boost(gFourMomentum.boostVector());
152 
153     dirElectron = eFourMomentum.vect().unit();
154     dirPositron = pFourMomentum.vect().unit();
155 
156     G4double phi = CLHEP::twopi*randNumbs[3];
157     PhiRotation(dirElectron, phi);
158     PhiRotation(dirPositron, phi);
159 
160   } else if (randNumbs[7] >= W[0] && randNumbs[7] < W[1]) {
161     G4double A3 = q2 + 2.*gEnergy*muFinalEnergy;
162     G4double B3 = -2.*gMomentum*muFinalMomentum;
163     
164     G4double tQ3interval = G4Log((A3 + B3)/(A3 - B3))/B3;
165     G4double tQMG = (-A3 + (A3 - B3)*G4Exp(B3*tQ3interval*randNumbs[0]))/B3;
166     G4double phiQP = CLHEP::twopi*randNumbs[2];
167     
168     G4double sintQ3 = std::sqrt(1. - tQMG*tQMG);
169     G4double cospQP = std::cos(phiQP);
170     G4double sinpQP = std::sin(phiQP);
171     
172     G4double Ap = muMomentum*muMomentum + muFinalMomentum*muFinalMomentum + gMomentum*gMomentum;
173     G4double A = Ap + 2.*muFinalMomentum*gMomentum*tQMG;
174     G4double B = -2.*muMomentum*gMomentum*sintQ3*cospQP;
175     G4double C = -2.*muMomentum*gMomentum*tQMG - 2.*muMomentum*muFinalMomentum; 
176 
177     G4double absB = std::abs(B);
178     G4double t3interval = (1./(A + C + absB*mint3) - 1./(A + C + absB*maxt3))/absB;
179     G4double t3 = (-(A + C) + 1./(1./(A + C + absB*mint3) - absB*t3interval*randNumbs[0]))/absB;
180     G4double sint3 = std::sin(t3);
181     G4double cost3 = std::cos(t3);
182 
183     G4double cost = -sint3*sintQ3*cospQP + cost3*tQMG;
184     G4double sint = std::sqrt((1. + cost)*(1. - cost));
185     G4double cosp = (sintQ3*cospQP*cost3 + sint3*tQMG)/sint;
186     G4double sinp = sintQ3*sinpQP/sint;
187     
188     G4ThreeVector dirGamma;
189     dirGamma.set(sint*cosp, sint*sinp, cost);
190     G4LorentzVector gFourMomentum(gEnergy, dirGamma*gMomentum);
191 
192     G4ThreeVector dirMuon;
193     dirMuon.set(sint3, 0., cost3);
194 
195     G4double cost5 = -1. + 2.*randNumbs[6];
196     G4double phi5 = CLHEP::twopi*randNumbs[8];
197 
198     G4LorentzVector eFourMomentumMQ = eDP2(q2, eMass2, eMass2, cost5, phi5);
199     G4LorentzVector pFourMomentumMQ = pDP2(eMass2, eFourMomentumMQ);
200 
201     G4LorentzVector eFourMomentum = eFourMomentumMQ.boost(gFourMomentum.boostVector());
202     G4LorentzVector pFourMomentum = pFourMomentumMQ.boost(gFourMomentum.boostVector());
203 
204     dirElectron = eFourMomentum.vect().unit();
205     dirPositron = pFourMomentum.vect().unit();
206 
207     G4double phi = CLHEP::twopi*randNumbs[3];
208     PhiRotation(dirElectron, phi);
209     PhiRotation(dirPositron, phi);
210 
211   } else if (randNumbs[7] >= W[1] && randNumbs[7] < W[2]) {
212     G4double phi3 = CLHEP::twopi*randNumbs[0];
213     G4double phi5 = CLHEP::twopi*randNumbs[1];
214     G4double phi6 = CLHEP::twopi*randNumbs[2];
215     G4double minmuFinalEnergy = muMass;
216     G4double muEnergyInterval = muEnergy - 2.*eMass - minmuFinalEnergy;
217     G4double muFEnergy = minmuFinalEnergy + muEnergyInterval*randNumbs[3];
218     
219     G4double mineEnergy = eMass;
220     G4double maxeEnergy = muEnergy - muFEnergy - eMass;
221     G4double eEnergyInterval = maxeEnergy - mineEnergy;
222     G4double eEnergy = mineEnergy + eEnergyInterval*randNumbs[4];
223     
224     G4double cosp3 = 1.;
225     G4double sinp3 = 0.;
226     G4double cosp5 = std::cos(phi5);
227     G4double sinp5 = std::sin(phi5);
228     G4double cosp6 = std::cos(phi6);
229     G4double sinp6 = std::sin(phi6);
230 
231     G4double muFMomentum = std::sqrt(muFEnergy*muFEnergy - muMass*muMass);
232     G4double eMomentum = std::sqrt(eEnergy*eEnergy - eMass*eMass);
233     G4double pEnergy = muEnergy - muFEnergy - eEnergy;
234     G4double pMomentum = std::sqrt(pEnergy*pEnergy - eMass*eMass);
235     
236     G4double A3 = -2.*muMass*muMass + 2.*muEnergy*muFinalEnergy;
237     G4double B3 = -2.*muMomentum*muFinalMomentum;
238     G4double cost3interval = G4Log((A3 + B3*Cmax)/(A3 + B3*Cmin))/B3;
239     G4double expanCost3r6 = G4Exp(B3*cost3interval*randNumbs[5]);
240     G4double cost3 = A3*(expanCost3r6 - 1.)/B3 + Cmin*expanCost3r6;
241     G4double sint3 = std::sqrt((1. - cost3)*(1. + cost3));
242     
243     G4ThreeVector muFinalMomentumVector(muFMomentum*sint3, 0., muFMomentum*cost3);
244 
245     G4LorentzVector muFourMomentum(muMomentum, muMomentumVector);
246     muFinalFourMomentum.set(muFEnergy, muFinalMomentumVector);
247     G4LorentzVector auxVec1 = muFourMomentum - muFinalFourMomentum;
248     G4double A5 = auxVec1.mag2() - 2.*eEnergy*(muEnergy - muFEnergy) +
249       2.*muMomentumVector[2]*eMomentum - 2.*muFMomentum*eMomentum*cost3;
250     G4double B5 = -2.*muFMomentum*eMomentum*(sint3*cosp3*cosp5 + sint3*sinp3*sinp5);
251     G4double absA5 = std::abs(A5);
252     G4double absB5 = std::abs(B5);
253     G4double mint5 = 0.;
254     G4double maxt5 = CLHEP::pi;
255     G4double t5interval = G4Log((absA5 + absB5*maxt5)/(absA5 + absB5*mint5))/absB5;
256     G4double argexp = absB5*t5interval*randNumbs[6] + G4Log(absA5 + absB5*mint5);
257     G4double t5 = -absA5/absB5 + G4Exp(argexp)/absB5;
258     G4double sint5 = std::sin(t5);
259     G4double cost5 = std::cos(t5);
260 
261     dirElectron.set(sint5*cosp5, sint5*sinp5, cost5);
262     G4ThreeVector eMomentumVector = eMomentum*dirElectron;
263 
264     G4ThreeVector auxVec2 = muMomentumVector - muFinalMomentumVector - eMomentumVector;
265     G4double p1mp3mp52 = auxVec2.dot(auxVec2);
266     G4double Bp = muFinalMomentum*(sint3*cosp3*cosp6 + sint3*sinp3*sinp6) +
267       eMomentum*(sint5*cosp5*cosp6 + sint5*sinp5*sinp6);
268     G4double Cp = -muMomentum + muFMomentum*cost3 + eMomentum*cost5;
269     G4double A6 = p1mp3mp52 + pMomentum*pMomentum;
270     G4double B6 = 2.*pMomentum*Bp;
271     G4double C6 = 2.*pMomentum*Cp;
272     G4double mint6 = 0.;
273     G4double maxt6 = CLHEP::pi;
274     G4double absA6C6 = std::abs(A6 + C6);
275     G4double absB6 = std::abs(B6);
276     G4double t6interval = (1./(absA6C6 + absB6*mint6) - 1./(absA6C6 + absB6*maxt6))/absB6;
277     G4double t6 = (-absA6C6 + 1./(1./(absA6C6 + absB6*mint6) - absB6*t6interval*randNumbs[8]))/absB6;
278     G4double sint6 = std::sin(t6);
279     G4double cost6 = std::cos(t6);
280     
281     dirPositron.set(sint6*cosp6, sint6*sinp6, cost6);
282     
283     PhiRotation(dirElectron, phi3);
284     PhiRotation(dirPositron, phi3);
285 
286   } else if (randNumbs[7] >= W[2]) {
287     G4double phi3 = CLHEP::twopi*randNumbs[0];
288     G4double phi6 = CLHEP::twopi*randNumbs[1];
289     G4double phi5 = CLHEP::twopi*randNumbs[2];
290     G4double minmuFinalEnergy = muMass;
291     G4double muFinalEnergyinterval = muEnergy - 2.*eMass - minmuFinalEnergy;
292     G4double muFEnergy = minmuFinalEnergy + muFinalEnergyinterval*randNumbs[3];
293     
294     G4double minpEnergy = eMass;
295     G4double maxpEnergy = muEnergy - muFEnergy - eMass;
296     G4double pEnergyinterval = maxpEnergy - minpEnergy;
297     G4double pEnergy = minpEnergy + pEnergyinterval*randNumbs[4];
298     
299     G4double cosp3 = 1.;
300     G4double sinp3 = 0.;
301     G4double cosp5 = std::cos(phi5);
302     G4double sinp5 = std::sin(phi5);
303     G4double cosp6 = std::cos(phi6);
304     G4double sinp6 = std::sin(phi6);
305 
306     G4double muFMomentum = std::sqrt(muFEnergy*muFEnergy - muMass*muMass);
307     G4double pMomentum = std::sqrt(pEnergy*pEnergy - eMass*eMass);
308     G4double eEnergy = muEnergy - muFEnergy - pEnergy;
309     G4double eMomentum = std::sqrt(eEnergy*eEnergy - eMass*eMass);
310     
311     G4double A3 = -2.*muMass*muMass + 2.*muEnergy*muFinalEnergy;
312     G4double B3 = -2.*muMomentum*muFMomentum;
313     G4double cost3interval = G4Log((A3 + B3*Cmax)/(A3 + B3*Cmin))/B3;
314     G4double expanCost3r6 = G4Exp(B3*cost3interval*randNumbs[5]);
315     G4double cost3 = A3*(expanCost3r6 - 1.)/B3 + Cmin*expanCost3r6;
316     G4double sint3 = std::sqrt((1. - cost3)*(1. + cost3));
317 
318     G4ThreeVector muFinalMomentumVector;
319     muFinalMomentumVector.set(muFMomentum*sint3*cosp3, muFMomentum*sint3*sinp3,
320             muFMomentum*cost3);
321 
322     G4LorentzVector muFourMomentum(muMomentum, muMomentumVector);
323     muFinalFourMomentum.set(muFEnergy, muFinalMomentumVector);
324     G4LorentzVector auxVec1 = muFourMomentum - muFinalFourMomentum;
325     G4double A6 = auxVec1.mag2() - 2.*pEnergy*(muEnergy - muFEnergy) +
326       2.*muMomentumVector[2]*pMomentum - 2.*muFMomentum*pMomentum*cost3;
327     G4double B6 = -2.*muFMomentum*pMomentum*(sint3*cosp3*cosp6 + sint3*sinp3*sinp6);
328     G4double absA6 = std::abs(A6);
329     G4double absB6 = std::abs(B6);
330     G4double mint6 = 0.;
331     G4double maxt6 = CLHEP::pi;
332     G4double t6interval = G4Log((absA6 + absB6*maxt6)/(absA6 + absB6*mint6))/absB6;
333     G4double argexp = absB6*t6interval*randNumbs[6] + G4Log(absA6 + absB6*mint6);
334     G4double t6 = -absA6/absB6 + G4Exp(argexp)/absB6;
335     G4double sint6 = std::sin(t6);
336     G4double cost6 = std::cos(t6);
337 
338     dirPositron.set(sint6*cosp6, sint6*sinp6, cost6);
339     G4ThreeVector pMomentumVector = pMomentum*dirPositron;
340 
341     G4ThreeVector auxVec2 = muMomentumVector - muFinalMomentumVector - pMomentumVector;
342     G4double p1mp3mp62 = auxVec2.dot(auxVec2);
343     G4double Bp = muFMomentum*(sint3*cosp3*cosp5 + sint3*sinp3*sinp5) +
344       pMomentum*(sint6*cosp6*cosp5 + sint6*sinp6*sinp5);
345     G4double Cp = -muMomentum + muFMomentum*cost3 + pMomentum*cost6;
346     G4double A5 = p1mp3mp62 + eMomentum*eMomentum;
347     G4double B5 = 2.*eMomentum*Bp;
348     G4double C5 = 2.*eMomentum*Cp;
349     G4double mint5 = 0.;
350     G4double maxt5 = CLHEP::pi;
351     G4double absA5C5 = std::abs(A5 + C5);
352     G4double absB5 = std::abs(B5);
353     G4double t5interval = (1./(absA5C5 + absB5*mint5) - 1./(absA5C5 + absB5*maxt5))/absB5;
354     G4double t5 = (-absA5C5 + 1./(1./(absA5C5 + absB5*mint5) - absB5*t5interval*randNumbs[8]))/absB5;
355     G4double sint5 = std::sin(t5);
356     G4double cost5 = std::cos(t5);
357 
358     dirElectron.set(sint5*cosp5, sint5*sinp5, cost5);
359 
360     PhiRotation(dirElectron, phi3);
361     PhiRotation(dirPositron, phi3);
362   }
363   return muFinalFourMomentum;
364 }
365 
366 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
367 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
368 
369 void G4RiGeAngularGenerator::PhiRotation(G4ThreeVector& dir, G4double phi)
370 {
371   G4double sinp = std::sin(phi);
372   G4double cosp = std::cos(phi);
373 
374   G4double newX = dir.x()*cosp + dir.y()*sinp;
375   G4double newY = -dir.x()*sinp + dir.y()*cosp;
376 
377   dir.setX(newX);
378   dir.setY(newY);
379 }
380 
381 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
382 
383 G4LorentzVector G4RiGeAngularGenerator::eDP2(G4double x1, G4double x2,
384                                              G4double x3, G4double x4,
385                                              G4double x5)
386 {
387   G4double sint = std::sqrt((1.0 - x4)*(1.0 + x4));
388   G4double cosp = std::cos(x5);
389   G4double sinp = std::sin(x5);
390 
391   G4double QJM2 = (x1 + x3 - x2)*(x1 + x3 - x2)/(4.*x1) - x3;
392 
393   if (QJM2 < 0.) {
394     QJM2 = 1.e-13;
395   }
396 
397   G4double QJM = std::sqrt(QJM2);
398   G4LorentzVector x6(std::sqrt(x2 + QJM2), QJM*sint*cosp, QJM*sint*sinp, QJM*x4);
399 
400   return x6;
401 } 
402   
403 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
404 
405 G4LorentzVector G4RiGeAngularGenerator::pDP2(G4double x3, const G4LorentzVector& x6)
406 {
407   G4LorentzVector x7(x3 + x6.vect().dot(x6.vect()), -x6.vect());
408   return x7;
409 } 
410   
411 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
412 
413 void G4RiGeAngularGenerator::PrintGeneratorInformation() const
414 {
415   G4cout << "\n" << G4endl;
416   G4cout << "Angular Generator by RiGe algorithm" << G4endl;
417 } 
418 
419 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
420