23 #include <TDatabasePDG.h>
24 #include <TParticlePDG.h>
32 const double chargedPionMass =
33 TDatabasePDG::Instance()->GetParticle(211)->Mass();
40 double computeW2FromXQ2M(
double x,
double Q2,
double m) {
42 return std::pow(m, 2.) + (1. - x) * Q2 / x;
50 double bounded(
double x,
double minimum,
double maximum) {
51 return std::max(minimum, std::min(x, maximum));
65 struct EnergyFromMomentumAndId :
public std::unary_function<const Particle*,
67 double operator()(
const Particle* p)
const {
72 double energy(p->
GetE());
78 TParticlePDG* pdg = p->
Id().
Info();
80 if (pdg && p->
Id() != 0) {
85 mass = chargedPionMass;
88 energy = sqrt(pow(p->
GetP(), 2.) + pow(mass, 2.));
105 class MeasuredParticle {
109 throw std::invalid_argument(
"MeasuredParticle given NULL pointer");
111 ParticleMC* measured =
new ParticleMC;
113 measured->SetId(CalculateId(particle));
115 TParticlePDG* pdg = measured->Id().Info();
117 measured->SetM(pdg->Mass());
119 std::pair<double, double> ep =
120 CalculateEnergyMomentum(particle, pdg->Mass());
121 TLorentzVector vec(0., 0., ep.second, ep.first);
123 vec.SetPhi(particle->
GetPhi());
124 measured->Set4Vector(vec);
135 TParticlePDG* pdg = particle->
Id().
Info();
137 if (pdg && particle->
Id() != 0) {
139 }
else if (particle->
GetP() > 0.) {
162 static std::pair<double, double> CalculateEnergyMomentum(
165 int id = CalculateId(particle);
166 TParticlePDG* pdg = TDatabasePDG::Instance()->GetParticle(
id);
176 std::pair<double, double> ep(0., 0.);
177 if (particle->
GetP() > 0.) {
178 ep.first = sqrt(pow(particle->
GetP(), 2.) + pow(mass, 2.));
179 ep.second = particle->
GetP();
180 }
else if (particle->
GetE() > 0.) {
181 ep.first = particle->
GetE();
182 ep.second = sqrt(pow(particle->
GetE(), 2.) - pow(mass, 2.));
193 struct EnergyMomentum4Vector :
public std::unary_function<const Particle*,
195 TLorentzVector operator()(
const Particle* p)
const {
201 ep.SetE(EnergyFromMomentumAndId()(p));
210 struct EMinusPz :
public std::unary_function<const Particle*, double> {
211 double operator()(
const Particle* p)
const {
212 TLorentzVector fourMomentum(0., 0., 0., 0.);
214 fourMomentum = EnergyMomentum4Vector()(p);
216 return fourMomentum.E() - fourMomentum.Pz();
233 double Q2,
double W2)
260 std::auto_ptr<const VirtualParticle> scattered(
261 MeasuredParticle::Create(
mBeams.at(3)));
265 if (scattered->GetTheta() > 0. && scattered->GetP() > 0.) {
266 const TLorentzVector& l =
mBeams.at(0)->Get4Vector();
267 const TLorentzVector& h =
mBeams.at(1)->Get4Vector();
271 double Q2 = 2. * l.E() * scattered->GetE() *
272 (1. + cos(scattered->GetTheta()));
273 kin->
mQ2 = std::max(0., Q2);
276 double gamma =
mBeams.at(1)->GetE() /
mBeams.at(1)->GetM();
277 double beta =
mBeams.at(1)->GetP() /
mBeams.at(1)->GetE();
278 double ELeptonInNucl = gamma * (l.P() - beta * l.Pz());
279 double ELeptonOutNucl = gamma *
280 (scattered->GetP() - beta * scattered->GetPz());
281 kin->
mNu = std::max(0., ELeptonInNucl - ELeptonOutNucl);
286 const TLorentzVector q = l - scattered->Get4Vector();
287 double y = (q.Dot(h)) / (l.Dot(h));
288 kin->
mY = bounded(y, 0., 1.);
290 double cme = (l + h).M2();
291 double x = kin->
mQ2 / kin->
mY / cme;
292 kin->
mX = bounded(x, 0., 1.);
293 kin->
mW2 = computeW2FromXQ2M(kin->
mX, kin->
mQ2, h.M());
296 catch(std::invalid_argument& except) {
298 std::cerr <<
"No lepton for kinematic calculations" << std::endl;
307 typedef std::vector<const VirtualParticle*>::iterator Iter;
322 std::vector<const erhic::VirtualParticle*>
final;
326 std::transform(
final.begin(),
final.end(), std::back_inserter(
mParticles),
327 std::ptr_fun(&MeasuredParticle::Create));
338 kin->
mW2 = computeW2FromXQ2M(kin->
mX, kin->
mQ2,
350 if (hadron && lepton) {
354 std::back_inserter(E),
356 const double sumEh = std::accumulate(E.begin(), E.end(), 0.);
358 std::list<double> pz;
360 std::back_inserter(pz),
362 const double sumPzh = std::accumulate(pz.begin(), pz.end(), 0.);
366 y = (hadron->
GetE() * sumEh -
367 hadron->
GetPz() * sumPzh -
368 pow(hadron->
GetM(), 2.)) /
372 return bounded(y, 0., 1.);
385 std::list<double> px;
388 std::back_inserter(px),
391 std::list<double> py;
394 std::back_inserter(py),
396 double sumPx = std::accumulate(px.begin(), px.end(), 0.);
397 double sumPy = std::accumulate(py.begin(), py.end(), 0.);
400 Q2 = (pow(sumPx, 2.) + pow(sumPy, 2.)) / (1. - y);
403 return std::max(0., Q2);
414 if (hadron && lepton) {
422 return bounded(x, 0., 1.);
429 typedef std::vector<const VirtualParticle*>::iterator Iter;
444 std::vector<const erhic::VirtualParticle*>
final;
448 std::transform(
final.begin(),
final.end(), std::back_inserter(
mParticles),
449 std::ptr_fun(&MeasuredParticle::Create));
462 kin->
mW2 = computeW2FromXQ2M(kin->
mX, kin->
mQ2,
481 std::list<TLorentzVector> hadrons;
484 std::back_inserter(hadrons),
486 TLorentzVector h = std::accumulate(hadrons.begin(),
488 TLorentzVector(0., 0., 0., 0.));
489 mAngle = 2. * TMath::ATan((h.E() - h.Pz()) / h.Pt());
500 double theta = scattered->
GetTheta();
502 double denominator = tan(theta / 2.) + tan(gamma / 2.);
503 if (denominator > 0.) {
504 y = tan(gamma / 2.) / denominator;
508 return bounded(y, 0., 1.);
517 if (lepton && scattered) {
518 double theta = scattered->
GetTheta();
520 double denominator = tan(theta / 2.) + tan(gamma / 2.);
521 if (denominator > 0.) {
522 Q2 = 4. * pow(lepton->
GetE(), 2.) / tan(theta / 2.) / denominator;
526 return std::max(0., Q2);
535 if (lepton && hadron) {
538 if (s > 0. && y > 0.) {
543 return bounded(x, 0., 1.);