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
00023
00024 KRLReactorFlux gReactorFlux;
00025 KRLInverseBeta gInverseBeta;
00026 prob = gReactorFlux.Flux(engInMeV)
00027 *gInverseBeta.DSigDCosTh(engInMeV, cosThEL);
00028
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
00057 return new HepMC::GenParticle(fourmom,pid,1);
00058 }
00059
00060 StatusCode GtInverseBeta::mutate(HepMC::GenEvent& event)
00061 {
00062
00063
00064
00065 Hep3Vector pNeutrino;
00066 Hep3Vector pPositron, pNeutron;
00067
00068 GenerateInverseBetaPrimaries(funcInvBetaProb, m_neutrino_angle_in_deg,
00069 pNeutrino,
00070 pPositron, pNeutron);
00071
00072
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
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
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131 Double_t aEngNu(0), aCosThEl(0);
00132 Double_t Ee(0);
00133 while ( Ee == 0 ){
00134 invBetaProb->GetRandom2(aEngNu, aCosThEl);
00135
00136
00137
00138
00139
00140
00141
00142 KRLInverseBeta gInverseBeta;
00143 Ee = gInverseBeta.Ee1(aEngNu, aCosThEl);
00144
00145 }
00146
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
00153
00154 pnu.setRThetaPhi(aEngNu*MeV,0,0);
00155 p2 = pnu-p1;
00156
00157
00158
00159 pnu.rotateX(M_PI/2.);
00160 p1.rotateX(M_PI/2.);
00161 p2.rotateX(M_PI/2.);
00162
00163
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);
00184
00185
00186 funcInvBetaProb->SetNpx(1000);
00187 funcInvBetaProb->SetNpy(100);
00188
00189 return StatusCode::SUCCESS;
00190 }
00191
00192 StatusCode GtInverseBeta::finalize()
00193 {
00194 delete funcInvBetaProb;
00195
00196 return StatusCode::SUCCESS;
00197 }
00198