23 #include <TDatabasePDG.h>
24 #include <TParticlePDG.h>
33 const double chargedPionMass =
34 TDatabasePDG::Instance()->GetParticle(211)->Mass();
41 double computeW2FromXQ2M(
double x,
double Q2,
double m) {
43 return std::pow(m, 2.) + (1. -
x) * Q2 / x;
51 double bounded(
double x,
double minimum,
double maximum) {
61 std::cerr <<
"Warning in Kinematics, bounded(): x (or y) = " << x
62 <<
" is outside [" << minimum <<
"," << maximum <<
"]" << std::endl;
63 std::cerr <<
"To disable this warning, set erhic::DisKinematics::BoundaryWarning=false;" << std::endl;
80 typedef std::vector<const VirtualParticle*>::iterator VirtPartIter;
81 typedef std::vector<const VirtualParticle*>::const_iterator cVirtPartIter;
83 class MeasuredParticle {
87 throw std::invalid_argument(
"MeasuredParticle given NULL pointer");
89 ParticleMC* measured =
new ParticleMC;
91 measured->SetId(CalculateId(particle));
93 TParticlePDG*
pdg = measured->Id().Info();
95 measured->SetM(pdg->Mass());
97 std::pair<double, double> ep =
98 CalculateEnergyMomentum(particle, pdg->Mass());
99 TLorentzVector vec(0., 0., ep.second, ep.first);
101 vec.SetPhi(particle->
GetPhi());
102 measured->Set4Vector(vec);
113 TParticlePDG* pdg = particle->
Id().
Info();
115 if (pdg && particle->
Id() != 0) {
117 }
else if (particle->
GetP() > 0.) {
140 static std::pair<double, double> CalculateEnergyMomentum(
143 int id = CalculateId(particle);
144 TParticlePDG* pdg = TDatabasePDG::Instance()->GetParticle(
id);
154 std::pair<double, double> ep(0., 0.);
155 if (particle->
GetP() > 0.) {
156 ep.first = sqrt(pow(particle->
GetP(), 2.) + pow(
mass, 2.));
157 ep.second = particle->
GetP();
158 }
else if (particle->
GetE() > 0.) {
159 ep.first = particle->
GetE();
162 auto E = particle->
GetE();
164 ep.second = sqrt(pow(E, 2.) - pow(
mass, 2.));
186 double Q2,
double W2)
213 std::unique_ptr<const VirtualParticle> scattered( MeasuredParticle::Create(
mBeams.at(3)));
217 if (scattered->GetTheta() > 0. && scattered->GetP() > 0.) {
218 const TLorentzVector& l =
mBeams.at(0)->Get4Vector();
219 const TLorentzVector&
h =
mBeams.at(1)->Get4Vector();
224 double Q2 = 2. * ( l.E() * scattered->GetE() + scattered->GetP()*l.P()*
cos(scattered->GetTheta()) - l.M2()*l.M2() );
229 double beta =
mBeams.at(1)->GetP() /
mBeams.at(1)->GetE();
230 double ELeptonInNucl = gamma * (l.P() - beta * l.Pz());
231 double ELeptonOutNucl = gamma *
232 (scattered->GetP() - beta * scattered->GetPz());
233 kin->
mNu =
std::max(0., ELeptonInNucl - ELeptonOutNucl);
238 const TLorentzVector q = l - scattered->Get4Vector();
239 const double ldoth = l.Dot(h);
240 double y = q.Dot(h) / ldoth ;
242 kin->
mY = bounded(y, 0., 1.);
248 if ( y>0 &&
std::abs(ldoth) > 0) x = kin->
mQ2 / 2 / y / ldoth;
250 kin->
mX = bounded(x, 0., 1.);
251 kin->
mW2 = computeW2FromXQ2M(kin->
mX, kin->
mQ2, h.M());
256 catch(std::invalid_argument& except) {
258 std::cerr <<
"No lepton for kinematic calculations" << std::endl;
282 std::vector<const erhic::VirtualParticle*>
final;
291 for (VirtPartIter
it =
final.begin() ;
it !=
final.end(); ++
it){
292 mParticles.push_back ( MeasuredParticle::Create ( *
it ) );
304 kin->
mW2 = computeW2FromXQ2M(kin->
mX, kin->
mQ2,
316 if (hadron && lepton) {
318 std::vector<double> E;
320 E.push_back ( (*it)->GetE() );
322 const double sumEh = std::accumulate(E.begin(), E.end(), 0.);
325 std::vector<double> pz;
327 pz.push_back ( (*it)->GetPz() );
329 const double sumPzh = std::accumulate(pz.begin(), pz.end(), 0.);
335 y = (hadron->
GetE() * sumEh -
336 hadron->
GetPz() * sumPzh -
337 pow(hadron->
GetM(), 2.)) /
363 std::vector<double> px;
365 px.push_back ( (*it)->GetPx() );
369 std::vector<double> py;
371 py.push_back ( (*it)->GetPy() );
374 double sumPx = std::accumulate(px.begin(), px.end(), 0.);
375 double sumPy = std::accumulate(py.begin(), py.end(), 0.);
378 Q2 = (pow(sumPx, 2.) + pow(sumPy, 2.)) / (1. - y);
392 if (hadron && lepton) {
405 return bounded(x, 0., 100.);
412 typedef std::vector<const VirtualParticle*>::iterator Iter;
428 std::vector<const erhic::VirtualParticle*>
final;
432 for (VirtPartIter
it =
final.begin() ;
it !=
final.end(); ++
it){
433 mParticles.push_back ( MeasuredParticle::Create ( *
it ) );
465 std::vector<TLorentzVector> hadrons;
471 hadrons.push_back ( (*it)->Get4Vector() );
473 TLorentzVector
h = std::accumulate(hadrons.begin(),
475 TLorentzVector(0., 0., 0., 0.));
476 mAngle = 2. * TMath::ATan((h.E() - h.Pz()) / h.Pt());
489 double denominator = tan(theta / 2.) + tan(gamma / 2.);
490 if (denominator > 0.) {
491 y = tan(gamma / 2.) / denominator;
495 return bounded(y, 0., 1.);
504 if (lepton && scattered) {
507 double denominator = tan(theta / 2.) + tan(gamma / 2.);
509 if (denominator > 0. ) {
510 Q2 = 4. * pow(lepton->
GetE(), 2.) / tan(theta / 2.) / denominator;
523 if (lepton && hadron) {
526 if (s > 0. && y > 0.) {
531 return bounded(x, 0., 1.);