Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

annih.cxx

Go to the documentation of this file.
00001 // -*- C++ -*-  $Id: annih.cxx,v 1.1 2000/09/01 20:20:17 burnett Exp $
00002 //
00003 // This file is part of Gismo 2
00004 //
00005 // file: annih.cpp
00006 // created 1-Dec-1991  T. Burnett
00007 
00008 // Contents -------------------------------------------------------
00009 //
00010 //  EGS:annih
00011 //
00012 // End -----------------------------------------------------------
00013 
00014 
00015 #include "EGS.h"
00016 #include "Random.h"
00017 #include <cmath>
00018 #include <algorithm>
00019 
00020 
00021 void EGS::annih()
00022 {
00023 
00024     //                                version 4.00  --  24 jul 1986/1400
00025     //******************************************************************
00026     //   gamma spectrum for two gamma in-flight positron annihilation.
00027     //   using scheme based on heitler's p269-27o formulae
00028     //   this routine should give the correct distribution, but more
00029     //   thought could be put into devising a faster scheme.  however,
00030     //   since positron annihilation in flight is relatively infrequent
00031     //   this may not be worthwhile.
00032     //******************************************************************
00033 
00034     // Modified to handle annihilation at rest (THB 4-jan-1991)
00035     double avip = this->e + (double)rm; //available energy of incident positron
00036     double a  = avip/rm,
00037           ai = 1.0/a,
00038           g  = a-1.0,
00039           t  = std::max(0.,g-1.0),
00040           p  = sqrt(a*t),
00041           ep0= 1.0/(a+p),
00042           ep;
00043 
00044     //   sample 1/ep from ep=ep0 to 1.0-ep0
00045     if( ::fabs(ep0-0.5) > 1e-5)
00046      for(;;)
00047      {   float rnno01= Random::flat();
00048         ep=ep0*exp(rnno01*log((1.0-ep0)/ep0));
00049         //   now decide whether to accept
00050         float rnno02= Random::flat();
00051         float rejf=1.0-ep+ai*ai*(2.0*g-1.0/ep);
00052         if (rnno02 <=rejf) break ;
00053      }
00054      else
00055        ep = ep0;
00056     //   this completes sampling of a distribution which is asymmetric
00057     //   about ep=1/2, but which when symmetrized is the symmetric
00058     //   annihilation distribution. pick ep in (1/2,1-ep0).
00059 
00060     if (ep>0.5) ep=1.0-ep;
00061 
00062     //   set up energies
00063     double pesg1 = avip*ep; //energy of secondary gamma 1
00064     double pesg2 = avip - pesg1;
00065 
00066     EGS& g1 = *this;        // alias for input particle
00067     EGS& g2 = *new EGS(this);
00068 
00069     g1.e = pesg1; g1.iq = 0;
00070     g2.e = pesg2; g2.iq = 0;
00071 
00072     //   set up gamma lab angles
00073     float phi = Random::flat(2.*M_PI);   // random phi to use for both
00074     float costh1, costh2;
00075 
00076     if (t<=0.)  // at rest
00077     {  costh1 = Random::flat(-1.,1.);
00078        costh2 = -costh1;
00079     }
00080     else
00081     {
00082        costh1 = std::min(1.0,(pesg1-rm)*p/t/pesg1);
00083        costh2 = std::min(1.0,(pesg2-rm)*p/t/pesg2);
00084     }
00085     g1.rotate(costh1, phi);
00086 
00087     g2.rotate(costh2, phi+M_PI);
00088 
00089 } //end of subroutine annih
00090 

Generated at Mon Nov 26 18:18:31 2001 by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000