13 #include <TLorentzVector.h>
29 using namespace genie;
30 using namespace genie::constants;
34 double dq0,
double dq3,
double Enu,
double lmass,
35 double &tmu,
double &cost,
double &area)
37 tmu = Enu - dq0 - lmass;
45 double thisE = tmu + lmass;
46 double thisp = sqrt( thisE * thisE - lmass * lmass);
47 double numerator = Enu * Enu + thisp * thisp - dq3 * dq3;
48 double denominator = 2.0 * thisp * Enu;
49 if(denominator <= 0.0 ){
51 if(denominator < 0.0){
55 else cost = numerator / denominator;
57 if(TMath::Abs(numerator) > TMath::Abs(denominator)){
69 double areaElement = 0.0;
73 insqrt = Enu * Enu - 2.0 * Enu * dq0 + dq0 * dq0 - lmass * lmass;
74 numerator = dq3 / Enu;
75 if(insqrt < 0.0)areaElement=0.0;
76 else areaElement = numerator / TMath::Sqrt(insqrt);
83 double q0,
double q3,
double Enu,
double ml,
double& Tl,
double& costl)
93 double plsq = El * El - ml * ml;
99 double pl = TMath::Sqrt(plsq);
100 double numerator = Enu * Enu + pl * pl - q3 * q3;
101 double denominator = 2.0 * pl * Enu;
102 if(denominator <= 0.0) {
104 if(denominator < 0.0) {
109 costl = numerator / denominator;
112 if(TMath::Abs(numerator) > TMath::Abs(denominator)){
122 double Tl,
double costl,
double Enu,
double ml,
double& q0,
double& q3)
135 double pl = TMath::Sqrt(El * El - ml * ml);
136 double q3sq = pl * pl + Enu * Enu - 2.0 * pl * Enu * costl;
142 q3 = TMath::Sqrt(q3sq);
148 double dq0,
double dq3,
double Enu,
double ml)
153 insqrt = Enu * Enu - 2.0 * Enu * dq0 + dq0 * dq0 - ml * ml;
154 double numerator = dq3 / Enu;
159 area = numerator / TMath::Sqrt(insqrt);
175 int nearpdg = targetpdg;
179 nearpdg = targetpdg + 10000;
182 nearpdg = targetpdg - 10000;
188 if(NULL == partf || NULL == parti){
192 <<
"Can't get qvalue, nucleus " << targetpdg <<
" or " << nearpdg
193 <<
" is not in the table of nuclei in /data/evgen/pdg ";
197 double massf = partf->Mass();
198 double massi = parti->Mass();
205 return massf - massi;
209 int nupdg,
int targetpdg,
210 double Enu,
double Ml,
double Tl,
double costhl,
215 TLorentzVector v4lep;
216 TLorentzVector v4Nu(0,0,Enu,Enu);
219 double facconv = 0.0389391289e15;
221 double myQvalue = 0.0;
224 double sinthl = 1. - costhl * costhl;
225 if(sinthl < 0.0) sinthl = 0.0;
226 else sinthl = TMath::Sqrt(sinthl);
228 double Cosh = TMath::Cos(TMath::ACos(costhl)/2.);
229 double Sinh = TMath::Sin(TMath::ACos(costhl)/2.);
232 v4lep.SetE( Tl + Ml );
234 double q0 = v4Nu.E() - v4lep.E();
236 q0nucleus = q0 - myQvalue;
239 double pl = TMath::Sqrt(v4lep.E() * v4lep.E() - Ml * Ml);
240 double q3sq = pl * pl + Enu * Enu - 2.0 * pl * Enu * costhl;
241 double q3 = sqrt(q3sq);
246 double w1, w2, w3, w4, w5;
255 modkprime = std::sqrt(TMath::Power(v4lep.E(),2)-TMath::Power(Ml,2));
256 v4lep.SetX(modkprime*sinthl);
258 v4lep.SetZ(modkprime*costhl);
262 v4q.SetX(v4Nu.X() - v4lep.X());
263 v4q.SetY(v4Nu.Y() - v4lep.Y());
264 v4q.SetZ(v4Nu.Z() - v4lep.Z());
276 double W00 = (tensor_table->
tt(q0nucleus,q3)).real();
277 double W0Z = (tensor_table->
tz(q0nucleus,q3)).real();
278 double WXX = (tensor_table->
xx(q0nucleus,q3)).real();
279 double WXY = -1.0*(tensor_table->
xy(q0nucleus,q3)).imag();
280 double WZZ = (tensor_table->
zz(q0nucleus,q3)).real();
283 w2=(W00+WXX+(q0*q0/(v4q.Vect().Mag()*v4q.Vect().Mag())
285 -(2.*q0/v4q.Vect().Mag()*W0Z))/2.;
286 w3=WXY/v4q.Vect().Mag();
287 w4=(WZZ-WXX)/(2.*v4q.Vect().Mag()*v4q.Vect().Mag());
288 w5=(W0Z-(q0/v4q.Vect().Mag()*(WZZ-WXX)))/v4q.Vect().Mag();
293 if (nupdg < 0) w3 = -1. * w3;
296 double xw1 = w1*costhl;
297 double xw2 = w2/2.*costhl;
298 double xw3 = w3/2.*(v4lep.E()+modkprime-(v4lep.E()+v4Nu.E())*costhl);
299 double xw4 = w4/2.*(Ml*Ml*costhl+2.*v4lep.E()*(v4lep.E()+modkprime)*Sinh*Sinh);
300 double xw5 = w5*(v4lep.E()+modkprime)/2.;
301 part1 = xw1 - xw2 + xw3 + xw4 - xw5;
303 double yw1 = 2.*w1*Sinh*Sinh;
304 double yw2 = w2*Cosh*Cosh;
305 double yw3 = w3*(v4lep.E()+v4Nu.E())*Sinh*Sinh;
306 double yw4 = Ml*Ml*part1/(v4lep.E()*(v4lep.E()+modkprime));
307 part2 = yw1 + yw2 - yw3 + yw4;
309 xsec = modkprime*v4lep.E()*
kGF2*2./
kPi*part2*facconv;
311 if( ! (xsec >= 0.0) ){
318 if((Enu>1.15 && Enu<1.25) && (v4q.Vect().Mag()>0.615 && v4q.Vect().Mag()<0.625) && (q0<0.500 && q0>0.490))
320 <<
"Got xsec = " << xsec
321 <<
"\n " << part1 <<
" " << part2
322 <<
"\n w[] : " << w1 <<
", " << w2 <<
", " << w3 <<
", " << w4 <<
", " << w5
323 <<
"\n wtotd[] : " << wtotd[0] <<
", " << wtotd[1] <<
", " << wtotd[2] <<
", " << wtotd[3] <<
", " << wtotd[4]
324 <<
"\n vec " << v4q.Vect().Mag() <<
", " << q0 <<
", " << v4q.Px() <<
", " << v4q.Py() <<
", " << v4q.Pz()
325 <<
"\n v4qX " << v4Nu.X() <<
", " << v4lep.X() <<
", " << costhl <<
", " << sinthl <<
", " << modkprime
326 <<
"\n input " << Enu <<
", " << Ml <<
", " << Tl <<
", " <<costhl <<
", " << v4q.Vect().Mag() <<
", " << q0;
335 const Interaction& inter,
const double tolerance,
const double safety_factor,
336 const int max_n_layers )
346 if ( interaction->
ProcInfo().
IsEM() ) Q2min = genie::utils::kinematics
350 const double ProbeMass = interaction->
InitState().
Probe()->Mass();
351 const double LepMass = interaction->
FSPrimLepton()->Mass();
363 const double TMax = std::max( 0., Enu - LepMass );
364 double CurTMin = std::max( 0., TMax - Q0Max );
365 double CurTMax = TMax;
366 double CurQ2Min = Q2min;
369 double CurQ2Max = QMagMax * QMagMax;
380 double T_at_xsec_max = CurTMax;
381 double Q2_at_xsec_max = CurQ2Max;
382 double cur_max_xsec = -1.;
384 for (
int ilayer = 0; ilayer < max_n_layers; ++ilayer ) {
386 double last_layer_xsec_max = cur_max_xsec;
388 double T_increment = ( CurTMax - CurTMin ) / ( N_T - 1 );
389 double Q2_increment = ( CurQ2Max - CurQ2Min ) / ( N_Q2 - 1 );
392 for (
int iT = 0; iT < N_T; ++iT ) {
393 double T = CurTMin + iT * T_increment;
394 for (
int iQ2 = 0; iQ2 < N_Q2; ++iQ2 ) {
395 double Q2 = CurQ2Min + iQ2 * Q2_increment;
398 double Elep = T + LepMass;
399 double pnu = std::sqrt( std::max(0., Enu*Enu - ProbeMass*ProbeMass) );
400 double plep = std::sqrt( std::max(0., std::pow(T + LepMass, 2)
401 - LepMass*LepMass) );
403 double Costh = plep==0?0:( 2.*Enu*Elep - ProbeMass*ProbeMass - LepMass*LepMass
404 -
Q2 ) / ( 2. * pnu * plep );
406 Costh = std::min( std::max(-1., Costh), 1. );
417 if ( xsec > cur_max_xsec ) {
426 LOG(
"MEC",
pDEBUG) <<
"Layer " << ilayer <<
" has max xsec = "
427 << cur_max_xsec <<
" for T = " << T_at_xsec_max <<
", Q2 = "
433 CurTMin = std::max( 0., T_at_xsec_max - T_increment );
452 CurQ2Max = Q2_at_xsec_max + Q2_increment;
456 double improvement_factor = cur_max_xsec / last_layer_xsec_max;
457 if ( ilayer && std::abs(improvement_factor - 1.) < tolerance )
break;
466 double XSecMax = cur_max_xsec * safety_factor;
471 const double Enu,
const double LepMass,
const double Factor ) :
472 ROOT::Math::IBaseFunctionMultiDim(),
502 double costh = xin[1];
504 Kinematics * kinematics = fInteraction.KinePtr();
515 double xsec = fModel->XSec( &fInteraction,
kPSTlctl);
516 return fFactor * xsec;
520 ROOT::Math::IBaseFunctionMultiDim *
Cross Section Calculation Interface.
virtual std::complex< double > zz(double q0, double q_mag) const =0
The tensor element .
bool GetTlCostlFromq0q3(double q0, double q3, double Enu, double ml, double &Tl, double &costl)
virtual const HadronTensorI * GetTensor(int tensor_pdg, HadronTensorType_t type) const =0
double J(double q0, double q3, double Enu, double ml)
double Q2(const Interaction *const i)
Kinematics * KinePtr(void) const
double GetMaxXSecTlctl(const XSecAlgorithmI &xsec_model, const Interaction &inter, const double tolerance=0.01, const double safety_factor=1.2, const int max_n_layers=100)
Generated/set kinematical variables for an event.
TParticlePDG * Probe(void) const
Abstract interface for an object that computes the elements ( , , etc.) and structure functions ( ...
const double Q0LimitMaxXSec
enum genie::HadronTensorType HadronTensorType_t
static const double kMinQ2Limit
double Qvalue(int targetpdg, int nupdg)
Summary information for an interaction.
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
virtual std::complex< double > xy(double q0, double q_mag) const =0
The tensor element .
const Algorithm * GetAlgorithm(const AlgId &algid)
bool Getq0q3FromTlCostl(double Tl, double costl, double Enu, double ml, double &q0, double &q3)
unsigned int NDim(void) const
double DoEval(const double *xin) const
virtual std::complex< double > tz(double q0, double q_mag) const =0
The tensor element .
virtual double XSec(const Interaction *i, KinePhaseSpace_t k=kPSfE) const =0
Compute the cross section for the input interaction.
TParticlePDG * FSPrimLepton(void) const
final state primary lepton
d2Xsec_dTCosth(const XSecAlgorithmI *m, const Interaction &i, const double Enu, const double LepMass, const double Factor=1.)
void SetKV(KineVar_t kv, double value)
static PDGLibrary * Instance(void)
static AlgFactory * Instance()
ROOT::Math::IBaseFunctionMultiDim * Clone(void) const
const InitialState & InitState(void) const
const ProcessInfo & ProcInfo(void) const
Creates hadron tensor objects for use in cross section calculations.
const double QMagLimitMaxXSec
double GetTmuCostFromq0q3(double dq0, double dq3, double Enu, double lmass, double &tmu, double &cost, double &area)
TParticlePDG * Find(int pdgc, bool must_exist=true)
double OldTensorContraction(int nupdg, int targetpdg, double Enu, double Ml, double Tl, double costhl, int tensorpdg, genie::HadronTensorType_t tensor_type, char *tensor_model)
double ProbeE(RefFrame_t rf) const
virtual std::complex< double > tt(double q0, double q_mag) const =0
The tensor element .
static constexpr double m
Most commonly used PDG codes. A set of utility functions to handle PDG codes is provided in PDGUtils...
virtual std::complex< double > xx(double q0, double q_mag) const =0
The tensor element .