File indexing completed on 2024-11-16 09:02:09
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include "eicsmear/erhic/ParticleMC.h"
0011
0012 #include <iostream>
0013 #include <limits>
0014 #include <sstream>
0015 #include <stdexcept>
0016 #include <string>
0017
0018 #include <TLorentzRotation.h>
0019 #include <TParticlePDG.h>
0020 #include <TRotation.h>
0021
0022 #include "eicsmear/erhic/EventBase.h"
0023 #include "eicsmear/functions.h"
0024
0025 namespace {
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035 TLorentzRotation computeBoost(const TLorentzVector& rest,
0036 const TLorentzVector* z) {
0037 TLorentzRotation toRest(-(rest.BoostVector()));
0038 if (z) {
0039 TRotation rotate;
0040 TLorentzVector boostedZ(*z);
0041 boostedZ *= toRest;
0042 rotate.SetZAxis(boostedZ.Vect());
0043
0044
0045 rotate = rotate.Inverse();
0046 toRest.Transform(rotate);
0047 }
0048 return toRest;
0049 }
0050
0051 }
0052
0053 namespace erhic {
0054
0055 ParticleMCbase::ParticleMCbase()
0056 : I(0)
0057 , KS(0)
0058 , id(0)
0059 , orig(0)
0060 , orig1(0)
0061 , daughter(0)
0062 , ldaughter(0)
0063 , px(0.)
0064 , py(0.)
0065 , pz(0.)
0066 , E(0.)
0067 , m(0.)
0068 , pt(0.)
0069 , xv(0.)
0070 , yv(0.)
0071 , zv(0.)
0072 , parentId(std::numeric_limits<Int_t>::min())
0073 , p(0.)
0074 , theta(0.)
0075 , phi(0.)
0076 , rapidity(0.)
0077 , eta(0.)
0078 , z(0.)
0079 , xFeynman(0.)
0080 , thetaGamma(0.)
0081 , ptVsGamma(0.)
0082 , thetaGammaHCM(0.)
0083 , ptVsGammaHCM(0.)
0084 , phiPrf(0.)
0085 {
0086 }
0087
0088 ParticleMC::ParticleMC(const std::string &line, bool eAflag): ParticleMCbase(), eA(0)
0089 {
0090
0091 if (!line.empty()) {
0092 static std::stringstream ss;
0093 ss.str("");
0094 ss.clear();
0095 ss << line;
0096 if (eAflag) {
0097 eA = new ParticleMCeA();
0098
0099 ss >>
0100
0101 I >> KS >> id >> orig1 >> orig >> daughter >> ldaughter >>
0102 px >> py >> pz >> E >> m >> xv >> yv >> zv
0103
0104 >> eA->massNum >> eA->charge >> eA->NoBam;
0105
0106
0107 } else {
0108 ss >>
0109 I >> KS >> id >> orig >> daughter >> ldaughter >>
0110 px >> py >> pz >> E >> m >> xv >> yv >> zv;
0111 orig1 = 0;
0112 }
0113
0114
0115 if (ss.fail() || !ss.eof()) {
0116 throw std::runtime_error("Bad particle input: " + line);
0117 }
0118 ComputeDerivedQuantities();
0119 }
0120 }
0121
0122 ParticleMC::~ParticleMC()
0123 {
0124 if (eA) delete eA;
0125 }
0126
0127
0128 void ParticleMCbase::Print(Option_t* ) const {
0129 std::cout << I << '\t' << KS << '\t' << id << '\t' << orig << '\t' <<
0130 daughter << '\t' << ldaughter << '\t' << px << '\t' << py << '\t' << pz
0131 << '\t' << E << '\t' << m << '\t' << xv << '\t' << yv << '\t' << zv <<
0132 std::endl;
0133 }
0134
0135 void ParticleMCbase::ComputeDerivedQuantities() {
0136
0137 pt = sqrt(pow(px, 2.) + pow(py, 2.));
0138 p = sqrt(pow(pt, 2.) + pow(pz, 2.));
0139
0140 Double_t Epluspz = E + pz;
0141 Double_t Eminuspz = E - pz;
0142 Double_t Ppluspz = p + pz;
0143 Double_t Pminuspz = p - pz;
0144 if (Eminuspz <= 0.0 || Pminuspz == 0.0 ||
0145 Ppluspz == 0.0 || Epluspz <= 0.0) {
0146
0147 rapidity = -19.;
0148 eta = -19.;
0149 } else {
0150 rapidity = 0.5 * log(Epluspz / Eminuspz);
0151 eta = 0.5 * log(Ppluspz / Pminuspz);
0152 }
0153 theta = atan2(pt, pz);
0154 phi = TVector2::Phi_0_2pi(atan2(py, px));
0155 }
0156
0157 void ParticleMCbase::ComputeEventDependentQuantities(EventMC& event) {
0158 try {
0159
0160 const TLorentzVector& hadron = event.BeamHadron()->Get4Vector();
0161 const TLorentzVector& lepton = event.ScatteredLepton()->Get4Vector();
0162
0163
0164
0165 const TLorentzVector boson = event.BeamLepton()->Get4Vector() - lepton;
0166
0167
0168
0169 z = hadron.Dot(Get4Vector()) / hadron.Dot(boson);
0170
0171
0172
0173 TLorentzRotation toHadronRest = computeBoost(hadron, &boson);
0174
0175
0176 TLorentzVector p = (Get4Vector() *= toHadronRest);
0177 thetaGamma = p.Theta();
0178 ptVsGamma = p.Pt();
0179
0180
0181 TLorentzVector bosonPrf = (TLorentzVector(boson) *= toHadronRest);
0182 TLorentzVector leptonPrf = (TLorentzVector(lepton) *= toHadronRest);
0183 phiPrf = computeHermesPhiH(p, leptonPrf, bosonPrf);
0184
0185
0186
0187 TLorentzRotation boost = computeBoost(boson + hadron, &boson);
0188 xFeynman = 2. * (Get4Vector() *= boost).Pz() / sqrt(event.GetW2());
0189
0190 thetaGammaHCM = (Get4Vector() *= boost).Theta();
0191 ptVsGammaHCM = (Get4Vector() *= boost).Pt();
0192
0193
0194
0195
0196
0197
0198 if (event.GetNTracks() > unsigned(orig - 1)) {
0199 parentId = event.GetTrack(orig - 1)->Id();
0200 }
0201 }
0202 catch(std::exception& e) {
0203 std::cerr <<
0204 "Exception in Particle::ComputeEventDependentQuantities: " <<
0205 e.what() << std::endl;
0206 }
0207 }
0208
0209 TLorentzVector ParticleMCbase::Get4Vector() const {
0210 return TLorentzVector(px, py, pz, E);
0211 }
0212
0213 const EventMC* ParticleMCbase::GetEvent() const {
0214 return static_cast<EventMC*>(event.GetObject());
0215 }
0216
0217 const ParticleMC* ParticleMC::GetChild(UShort_t u) const {
0218
0219
0220 if (!GetEvent()) {
0221 return NULL;
0222 }
0223
0224 unsigned idx = daughter + u;
0225 if (daughter < 1 ||
0226 u >= GetNChildren()) {
0227 return NULL;
0228 }
0229 --idx;
0230 const ParticleMC* p(NULL);
0231
0232 if (idx < GetEvent()->GetNTracks()) {
0233 p = GetEvent()->GetTrack(idx);
0234 }
0235 return p;
0236 }
0237
0238 const ParticleMC* ParticleMC::GetParent() const {
0239
0240
0241 const ParticleMC* p(NULL);
0242 if (GetEvent()) {
0243 if (GetEvent()->GetNTracks() >= GetParentIndex()) {
0244 p = GetEvent()->GetTrack(GetParentIndex() - 1);
0245 }
0246 }
0247 return p;
0248 }
0249
0250 Bool_t ParticleMC::HasChild(Int_t pdg) const {
0251 for (UInt_t i(0); i < GetNChildren(); ++i) {
0252 if (!GetChild(i)) {
0253 continue;
0254 }
0255 if (pdg == GetChild(i)->Id()) {
0256 return true;
0257 }
0258 }
0259 return false;
0260 }
0261
0262 TLorentzVector ParticleMCbase::Get4VectorInHadronBosonFrame() const {
0263 double p_(0.), e_(0.), px_(ptVsGammaHCM), py_(0.), pz_(0.);
0264
0265
0266
0267 if (thetaGammaHCM > 1.e-6) {
0268 p_ = ptVsGammaHCM / sin(thetaGammaHCM);
0269 }
0270
0271 if (!(m < 0.)) {
0272 e_ = sqrt(pow(p_, 2.) + pow(m, 2.));
0273 } else {
0274 e_ = sqrt(pow(p_, 2.) - pow(m, 2.));
0275 if (TMath::IsNaN(e_)) {
0276 e_ = 0.;
0277 }
0278 }
0279
0280
0281 if (thetaGammaHCM > 1.e-6) {
0282 pz_ = ptVsGammaHCM / tan(thetaGammaHCM);
0283 }
0284
0285 if (phiPrf > -100.) {
0286 px_ = ptVsGammaHCM * cos(phiPrf);
0287 py_ = ptVsGammaHCM * sin(phiPrf);
0288 }
0289
0290
0291
0292
0293
0294
0295
0296 if (m < 0. && GetEvent()) {
0297 if (GetEvent()->ExchangeBoson()) {
0298
0299
0300
0301 if (GetEvent()->ExchangeBoson()->GetIndex() == GetIndex()) {
0302
0303 e_ = GetEvent()->GetNu();
0304
0305 p_ = sqrt(pow(e_, 2.) + pow(m, 2.));
0306 pz_ = p_ * cos(thetaGammaHCM);
0307 }
0308 }
0309 }
0310 return TLorentzVector(px_, py_, pz_, e_);
0311 }
0312
0313 void ParticleMCbase::SetEvent(EventMC* e) {
0314 event = e;
0315 }
0316
0317 void ParticleMCbase::Set4Vector(const TLorentzVector& v) {
0318 E = v.Energy();
0319 px = v.Px();
0320 py = v.Py();
0321 pz = v.Pz();
0322 m = v.M();
0323 ComputeDerivedQuantities();
0324
0325
0326 EventMC* ev = static_cast<EventMC*>(event.GetObject());
0327 if (ev) {
0328 ComputeEventDependentQuantities(*ev);
0329 }
0330 }
0331
0332 void ParticleMCbase::SetVertex(const TVector3& v) {
0333 xv = v.X();
0334 yv = v.Y();
0335 zv = v.Z();
0336 }
0337 }