| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

In This Package:

GtInverseBeta.cc

Go to the documentation of this file.
00001 #include "GtInverseBeta.h"
00002 #include "KRLInverseBeta.hh"
00003 #include "KRLReactorFlux.hh"
00004 #include "GaudiKernel/IRndmGenSvc.h"
00005 
00006 #include "HepMC/GenVertex.h"
00007 #include "HepMC/GenEvent.h"
00008 #include "CLHEP/Units/SystemOfUnits.h"
00009 #include <CLHEP/Units/PhysicalConstants.h>
00010 #include <TROOT.h>
00011 #include <TRandom.h>
00012 #include <sstream>
00013 
00014 using namespace std;
00015 using namespace CLHEP;
00016 
00017 Double_t inverse_beta_prob(Double_t* x, Double_t* par)
00018 {
00019   Double_t engInMeV = x[0];
00020   Double_t cosThEL = x[1];
00021   Double_t prob;
00022   //do NOT need to multiply by the jacobian sin(theta) here!
00023 
00024   KRLReactorFlux gReactorFlux;
00025   KRLInverseBeta gInverseBeta;
00026   prob = gReactorFlux.Flux(engInMeV)
00027     *gInverseBeta.DSigDCosTh(engInMeV, cosThEL);
00028   //prob = gReactorFlux->Flux(engInMeV)*gInverseBeta->SigmaTot(engInMeV);
00029   return prob;
00030 }
00031 
00032 
00033 GtInverseBeta::GtInverseBeta(const std::string& type,
00034                              const std::string& name, 
00035                              const IInterface* parent)
00036   : GaudiTool(type,name,parent)
00037 {
00038   declareInterface<IHepMCEventMutator>(this);
00039   
00040   declareProperty("NeutrinoAngle", m_neutrino_angle_in_deg=0, 
00041                   "neutrino angle in degree");
00042   declareProperty("PositronOnly",m_positron_only=0,"Only positron");
00043   declareProperty("NeutronOnly",m_neutron_only=0,"Only neutron");
00044 }
00045 
00046 GtInverseBeta::~GtInverseBeta()
00047 {
00048 }
00049 
00050 HepMC::GenParticle* GtInverseBeta::make_particle(Hep3Vector& vect, 
00051                                                  double mass, int pid)
00052 {
00053   double energy = sqrt(vect.mag2()+mass*mass);
00054   HepMC::FourVector fourmom(vect.x()/MeV,vect.y()/MeV,vect.z()/MeV,
00055                             energy/MeV);
00056   //the new GenParticle will be deleted by GenVertex destructor
00057   return new HepMC::GenParticle(fourmom,pid,1/*=status*/);
00058 }
00059 
00060 StatusCode GtInverseBeta::mutate(HepMC::GenEvent& event)
00061 {
00062   //  gReactorFlux = new KRLReactorFlux(); // defaults to Petr's fit
00063   //  gInverseBeta = new KRLInverseBeta();  
00064     
00065   Hep3Vector pNeutrino; //incoming neutrino momentum
00066   Hep3Vector pPositron, pNeutron; // the e+ and n momentum vectors. Unit GeV/c
00067   
00068   GenerateInverseBetaPrimaries(funcInvBetaProb, m_neutrino_angle_in_deg,
00069                                pNeutrino, 
00070                                pPositron, pNeutron);
00071   
00072   //the new GenVertex will be deleted by GenEvent destructor
00073   HepMC::GenVertex* vertex = new HepMC::GenVertex(HepMC::FourVector(0,0,0,0));
00074   event.add_vertex(vertex);
00075   event.set_signal_process_vertex(vertex);
00076   
00077   int pid = 0;
00078   HepMC::GenParticle* particle1 = 0;
00079   HepMC::GenParticle* particle2 = 0;
00080   if(!m_positron_only && !m_neutron_only){
00081     pid = -11;
00082     particle1 = make_particle(pPositron, electron_mass_c2, pid);
00083     vertex->add_particle_out(particle1);
00084     
00085     pid = 2112;
00086     particle2 = make_particle(pNeutron, neutron_mass_c2, pid);
00087     vertex->add_particle_out(particle2);
00088   }  
00089   else if(m_positron_only){
00090     pid = -11;
00091     particle1 = make_particle(pPositron, electron_mass_c2, pid);
00092     vertex->add_particle_out(particle1);
00093   }
00094   else if(m_neutron_only){
00095     pid = 2112;
00096     particle1 = make_particle(pPositron, neutron_mass_c2, pid);
00097     vertex->add_particle_out(particle1);
00098   }
00099   
00100   int mo_pid = -12;
00101   HepMC::FourVector fourmom(pNeutrino.x()/MeV,pNeutrino.y()/MeV,
00102                               pNeutrino.z()/MeV,pNeutrino.mag()/MeV);
00103   HepMC::GenParticle* particle_in = 
00104     new HepMC::GenParticle(fourmom, mo_pid, 2);
00105   // Save mother particle as info particle (default status=2)
00106   vertex->add_particle_in(particle_in);
00107   
00108   return StatusCode::SUCCESS;
00109 }
00110 
00111 void GtInverseBeta::GenerateInverseBetaPrimaries(TF2* invBetaProb, 
00112                                                  const double nu_angle_wrt_y_in_deg,
00113                                                  Hep3Vector& pnu,
00114                                                  Hep3Vector& p1, Hep3Vector& p2)
00115 {
00116   //now create a TF2 object to calculate the reaction probability
00117   //given the neutrino energy and the inverse beta probability
00118   //x: eNu in MeV
00119   //y: cos(th_e)
00120 //  TF2 *invBetaProb = new TF2("InvBeta",inverse_beta_prob,
00121 //                               0.01,60.0,-1.,1., 0); //"0" parameters
00122 //  //set the bins on x and y to help generate pseudo random numbers
00123 //  //according to the reaction probabilities
00124 //  invBetaProb->SetNpx(1000);//energy
00125 //  invBetaProb->SetNpy(100);//costh
00126 
00127   //generate neutrino energy and outgoing electron cos angle
00128   // djaffe: 12may09 modified to avoid rare case when e+ energy
00129   //        is returned as identically zero which indicates that below-threshold
00130   //        production according to KRLInverseBeta.
00131   Double_t aEngNu(0), aCosThEl(0);
00132   Double_t Ee(0);
00133   while ( Ee == 0 ){
00134     invBetaProb->GetRandom2(aEngNu, aCosThEl);
00135     
00136     //cout<<aEngNu<<" : "<<acos(aCosThEl)*360./M_2PI<<endl;
00137     
00138     //at this point, assume the incident nu momentum along z
00139     
00140     //calculate positron energy in MeV
00141     //    Ee = gInverseBeta->Ee1(aEngNu, aCosThEl);
00142     KRLInverseBeta gInverseBeta;
00143     Ee = gInverseBeta.Ee1(aEngNu, aCosThEl);
00144 
00145   }
00146   //generate positron phi angle
00147   Double_t aPhiEl = gRandom->Uniform(0.,2.0*M_PI);
00148   Double_t kMe = electron_mass_c2/MeV;
00149   Double_t Pe = sqrt(Ee*Ee-kMe*kMe);
00150   p1.setRThetaPhi(Pe*MeV, acos(aCosThEl), aPhiEl);
00151   
00152   //now use the 3-momentum conservation to set neutron recoil 
00153   //momentum
00154   pnu.setRThetaPhi(aEngNu*MeV,0,0);
00155   p2 = pnu-p1;
00156   
00157   //now make the vector rotation. first rotate around x by 90 degrees
00158   //so that +z axis is now +y axis
00159   pnu.rotateX(M_PI/2.);
00160   p1.rotateX(M_PI/2.);
00161   p2.rotateX(M_PI/2.);
00162   
00163   //if nu_angle_wrt_y is non-zero, rotate again
00164   if(nu_angle_wrt_y_in_deg!=0) {
00165     pnu.rotateX(2*M_PI/360.*nu_angle_wrt_y_in_deg);
00166     p1.rotateX(2*M_PI/360.*nu_angle_wrt_y_in_deg);
00167     p2.rotateX(2*M_PI/360.*nu_angle_wrt_y_in_deg);  
00168   }
00169 
00170   return;
00171 }
00172 
00173 StatusCode GtInverseBeta::initialize()
00174 {
00175   static int count = 0;
00176   count++;
00177   char itoa[100];
00178   sprintf(itoa,"%i",count);
00179 
00180   string filename("InvBeta");
00181   filename.append(itoa);  
00182   funcInvBetaProb = new TF2(filename.c_str(),inverse_beta_prob,
00183                             0.01,60.0,-1.,1., 0); //"0" parameters
00184   //set the bins on x and y to help generate pseudo random numbers
00185   //according to the reaction probabilities
00186   funcInvBetaProb->SetNpx(1000);//energy
00187   funcInvBetaProb->SetNpy(100);//costh
00188 
00189   return StatusCode::SUCCESS;
00190 }
00191 
00192 StatusCode GtInverseBeta::finalize()
00193 {
00194   delete funcInvBetaProb;
00195 
00196   return StatusCode::SUCCESS;
00197 }
00198 
| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

Generated on Mon Apr 11 21:05:44 2011 for InvBetaDecay by doxygen 1.4.7