File indexing completed on 2024-04-06 12:13:48
0001
0002
0003
0004
0005
0006
0007 #include <TLorentzVector.h>
0008 #include <TMath.h>
0009 #include <TVector3.h>
0010
0011 #include "GeneratorInterface/Hydjet2Interface/interface/Hydjet2Hadronizer.h"
0012 #include <cmath>
0013 #include <fstream>
0014 #include <iostream>
0015
0016 #include "FWCore/Concurrency/interface/SharedResourceNames.h"
0017 #include "FWCore/Framework/interface/Event.h"
0018 #include "FWCore/Framework/interface/Run.h"
0019 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0020 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0021 #include "FWCore/Utilities/interface/EDMException.h"
0022
0023 #include "GeneratorInterface/Pythia6Interface/interface/Pythia6Declarations.h"
0024 #include "GeneratorInterface/Pythia6Interface/interface/Pythia6Service.h"
0025
0026 #include "HepMC/GenEvent.h"
0027 #include "HepMC/HeavyIon.h"
0028 #include "HepMC/IO_HEPEVT.h"
0029 #include "HepMC/PythiaWrapper6_4.h"
0030 #include "HepMC/SimpleVector.h"
0031
0032 #include "SimDataFormats/GeneratorProducts/interface/GenEventInfoProduct.h"
0033 #include "SimDataFormats/GeneratorProducts/interface/GenRunInfoProduct.h"
0034 #include "SimDataFormats/GeneratorProducts/interface/HepMCProduct.h"
0035 #include "SimDataFormats/HiGenData/interface/GenHIEvent.h"
0036
0037 CLHEP::HepRandomEngine *hjRandomEngine;
0038
0039 using namespace edm;
0040 using namespace std;
0041 using namespace gen;
0042
0043 int Hydjet2Hadronizer::convertStatusForComponents(int sta, int typ, int pySta) {
0044 int st = -1;
0045 if (typ == 0)
0046 st = 2 - sta;
0047 else if (typ == 1)
0048 st = convertStatus(pySta);
0049
0050 if (st == -1)
0051 throw cms::Exception("ConvertStatus") << "Wrong status code!" << endl;
0052
0053 if (separateHydjetComponents_) {
0054 if (st == 1 && typ == 0)
0055 return 6;
0056 if (st == 1 && typ == 1)
0057 return 7;
0058 if (st == 2 && typ == 0)
0059 return 16;
0060 if (st == 2 && typ == 1)
0061 return 17;
0062 }
0063 return st;
0064 }
0065
0066 int Hydjet2Hadronizer::convertStatus(int st) {
0067 if (st <= 0)
0068 return 0;
0069 if (st <= 10)
0070 return 1;
0071 if (st <= 20)
0072 return 2;
0073 if (st <= 30)
0074 return 3;
0075 else
0076 return -1;
0077 }
0078
0079 const std::vector<std::string> Hydjet2Hadronizer::theSharedResources = {edm::SharedResourceNames::kPythia6};
0080
0081
0082 Hydjet2Hadronizer::Hydjet2Hadronizer(const edm::ParameterSet &pset, edm::ConsumesCollector &&iC)
0083 : BaseHadronizer(pset),
0084 rotate_(pset.getParameter<bool>("rotateEventPlane")),
0085 evt(nullptr),
0086 nsub_(0),
0087 nhard_(0),
0088 nsoft_(0),
0089 phi0_(0.),
0090 sinphi0_(0.),
0091 cosphi0_(1.),
0092 fVertex_(nullptr),
0093 pythia6Service_(new Pythia6Service(pset))
0094
0095 {
0096 fParams.doPrintInfo = false;
0097 fParams.allowEmptyEvent = false;
0098 fParams.fNevnt = 0;
0099 fParams.femb = pset.getParameter<int>("embeddingMode");
0100 fParams.fSqrtS = pset.getParameter<double>("fSqrtS");
0101 fParams.fAw = pset.getParameter<double>("fAw");
0102 fParams.fIfb = pset.getParameter<int>(
0103 "fIfb");
0104 fParams.fBmin = pset.getParameter<double>("fBmin");
0105 fParams.fBmax = pset.getParameter<double>("fBmax");
0106 fParams.fBfix = pset.getParameter<double>("fBfix");
0107 fParams.fT = pset.getParameter<double>("fT");
0108 fParams.fMuB = pset.getParameter<double>("fMuB");
0109 fParams.fMuS = pset.getParameter<double>("fMuS");
0110 fParams.fMuC = pset.getParameter<double>(
0111 "fMuC");
0112 fParams.fMuI3 = pset.getParameter<double>("fMuI3");
0113 fParams.fThFO = pset.getParameter<double>("fThFO");
0114 fParams.fMu_th_pip =
0115 pset.getParameter<double>("fMu_th_pip");
0116 fParams.fTau = pset.getParameter<double>(
0117 "fTau");
0118 fParams.fSigmaTau = pset.getParameter<double>(
0119 "fSigmaTau");
0120 fParams.fR = pset.getParameter<double>(
0121 "fR");
0122 fParams.fYlmax =
0123 pset.getParameter<double>("fYlmax");
0124 fParams.fUmax = pset.getParameter<double>(
0125 "fUmax");
0126 fParams.frhou2 = pset.getParameter<double>("fRhou2");
0127 fParams.frhou3 = pset.getParameter<double>("fRhou3");
0128 fParams.frhou4 = pset.getParameter<double>("fRhou4");
0129 fParams.fDelta =
0130 pset.getParameter<double>("fDelta");
0131 fParams.fEpsilon =
0132 pset.getParameter<double>("fEpsilon");
0133 fParams.fv2 = pset.getParameter<double>("fKeps2");
0134 fParams.fv3 = pset.getParameter<double>("fKeps3");
0135 fParams.fIfDeltaEpsilon = pset.getParameter<double>(
0136 "fIfDeltaEpsilon");
0137 fParams.fDecay =
0138 pset.getParameter<int>("fDecay");
0139 fParams.fWeakDecay = pset.getParameter<double>(
0140 "fWeakDecay");
0141 fParams.fEtaType = pset.getParameter<double>(
0142 "fEtaType");
0143 fParams.fTMuType = pset.getParameter<double>(
0144 "fTMuType");
0145 fParams.fCorrS = pset.getParameter<double>(
0146 "fCorrS");
0147 fParams.fCharmProd = pset.getParameter<int>(
0148 "fCharmProd");
0149 fParams.fCorrC = pset.getParameter<double>(
0150 "fCorrC");
0151 fParams.fNhsel = pset.getParameter<int>(
0152 "fNhsel");
0153 fParams.fPyhist = pset.getParameter<int>(
0154 "fPyhist");
0155 fParams.fIshad = pset.getParameter<int>(
0156 "fIshad");
0157 fParams.fPtmin =
0158 pset.getParameter<double>("fPtmin");
0159 fParams.fT0 = pset.getParameter<double>(
0160 "fT0");
0161 fParams.fTau0 = pset.getParameter<double>("fTau0");
0162 fParams.fNf = pset.getParameter<int>("fNf");
0163 fParams.fIenglu = pset.getParameter<int>(
0164 "fIenglu");
0165 fParams.fIanglu = pset.getParameter<int>(
0166 "fIanglu");
0167
0168 edm::FileInPath f1("externals/hydjet2/particles.data");
0169 strcpy(fParams.partDat, (f1.fullPath()).c_str());
0170
0171 edm::FileInPath f2("externals/hydjet2/tabledecay.txt");
0172 strcpy(fParams.tabDecay, (f2.fullPath()).c_str());
0173
0174 fParams.fPythiaTune = false;
0175
0176 if (pset.exists("signalVtx"))
0177 signalVtx_ = pset.getUntrackedParameter<std::vector<double>>("signalVtx");
0178
0179 if (signalVtx_.size() == 4) {
0180 if (!fVertex_)
0181 fVertex_ = new HepMC::FourVector();
0182 LogDebug("EventSignalVertex") << "Setting event signal vertex "
0183 << " x = " << signalVtx_.at(0) << " y = " << signalVtx_.at(1)
0184 << " z= " << signalVtx_.at(2) << " t = " << signalVtx_.at(3) << endl;
0185 fVertex_->set(signalVtx_.at(0), signalVtx_.at(1), signalVtx_.at(2), signalVtx_.at(3));
0186 }
0187
0188
0189
0190 pythiaPylistVerbosity_ = pset.getUntrackedParameter<int>("pythiaPylistVerbosity", 0);
0191 LogDebug("PYLISTverbosity") << "Pythia PYLIST verbosity level = " << pythiaPylistVerbosity_;
0192
0193 maxEventsToPrint_ = pset.getUntrackedParameter<int>("maxEventsToPrint", 0);
0194 LogDebug("Events2Print") << "Number of events to be printed = " << maxEventsToPrint_;
0195 if (fParams.femb == 1) {
0196 fParams.fIfb = 0;
0197 src_ = iC.consumes<CrossingFrame<edm::HepMCProduct>>(
0198 pset.getUntrackedParameter<edm::InputTag>("backgroundLabel", edm::InputTag("mix", "generatorSmeared")));
0199 }
0200
0201 separateHydjetComponents_ = pset.getUntrackedParameter<bool>("separateHydjetComponents", false);
0202 }
0203
0204 Hydjet2Hadronizer::~Hydjet2Hadronizer() {
0205 call_pystat(1);
0206 delete pythia6Service_;
0207 }
0208
0209
0210 void Hydjet2Hadronizer::doSetRandomEngine(CLHEP::HepRandomEngine *v) {
0211 pythia6Service_->setRandomEngine(v);
0212 hjRandomEngine = v;
0213 }
0214
0215
0216 bool Hydjet2Hadronizer::readSettings(int) {
0217 Pythia6Service::InstanceWrapper guard(pythia6Service_);
0218 pythia6Service_->setGeneralParams();
0219
0220 fParams.fSeed = hjRandomEngine->CLHEP::HepRandomEngine::getSeed();
0221 LogInfo("Hydjet2Hadronizer|GenSeed") << "Seed for random number generation: "
0222 << hjRandomEngine->CLHEP::HepRandomEngine::getSeed();
0223
0224 return kTRUE;
0225 }
0226
0227
0228 bool Hydjet2Hadronizer::initializeForInternalPartons() {
0229 Pythia6Service::InstanceWrapper guard(pythia6Service_);
0230
0231
0232 const double ra = nuclear_radius();
0233 LogInfo("Hydjet2Hadronizer|RAScaling") << "Nuclear radius(RA) = " << ra;
0234 fParams.fBmin /= ra;
0235 fParams.fBmax /= ra;
0236 fParams.fBfix /= ra;
0237
0238 hj2 = new Hydjet2(fParams);
0239
0240 return kTRUE;
0241 }
0242
0243
0244 bool Hydjet2Hadronizer::generatePartonsAndHadronize() {
0245 Pythia6Service::InstanceWrapper guard(pythia6Service_);
0246
0247
0248 if (fParams.femb == 1) {
0249 const edm::Event &e = getEDMEvent();
0250 HepMC::GenVertex *genvtx = nullptr;
0251 const HepMC::GenEvent *inev = nullptr;
0252 Handle<CrossingFrame<HepMCProduct>> cf;
0253 e.getByToken(src_, cf);
0254 MixCollection<HepMCProduct> mix(cf.product());
0255 if (mix.size() < 1) {
0256 throw cms::Exception("MatchVtx") << "Mixing has " << mix.size() << " sub-events, should have been at least 1"
0257 << endl;
0258 }
0259 const HepMCProduct &bkg = mix.getObject(0);
0260 if (!(bkg.isVtxGenApplied())) {
0261 throw cms::Exception("MatchVtx") << "Input background does not have smeared vertex!" << endl;
0262 } else {
0263 inev = bkg.GetEvent();
0264 }
0265
0266 genvtx = inev->signal_process_vertex();
0267
0268 if (!genvtx)
0269 throw cms::Exception("MatchVtx") << "Input background does not have signal process vertex!" << endl;
0270
0271 double aX, aY, aZ, aT;
0272
0273 aX = genvtx->position().x();
0274 aY = genvtx->position().y();
0275 aZ = genvtx->position().z();
0276 aT = genvtx->position().t();
0277
0278 if (!fVertex_) {
0279 fVertex_ = new HepMC::FourVector();
0280 }
0281 LogInfo("MatchVtx") << " setting vertex "
0282 << " aX " << aX << " aY " << aY << " aZ " << aZ << " aT " << aT << endl;
0283 fVertex_->set(aX, aY, aZ, aT);
0284
0285 const HepMC::HeavyIon *hi = inev->heavy_ion();
0286
0287 if (hi) {
0288 fParams.fBfix = (hi->impact_parameter()) / nuclear_radius();
0289 phi0_ = hi->event_plane_angle();
0290 sinphi0_ = sin(phi0_);
0291 cosphi0_ = cos(phi0_);
0292 } else {
0293 LogWarning("EventEmbedding") << "Background event does not have heavy ion record!";
0294 }
0295
0296 } else if (rotate_)
0297 rotateEvtPlane();
0298
0299 nsoft_ = 0;
0300 nhard_ = 0;
0301
0302
0303 int ntry = 0;
0304
0305 while (nsoft_ == 0 && nhard_ == 0) {
0306 if (ntry > 100) {
0307 LogError("Hydjet2EmptyEvent") << "##### HYDJET2: No Particles generated, Number of tries =" << ntry;
0308
0309
0310 std::ostringstream sstr;
0311 sstr << "Hydjet2HadronizerProducer: No particles generated after " << ntry << " tries.\n";
0312 edm::Exception except(edm::errors::EventCorruption, sstr.str());
0313 throw except;
0314 } else {
0315 hj2->GenerateEvent(fParams.fBfix);
0316
0317 if (hj2->IsEmpty()) {
0318 continue;
0319 }
0320
0321 nsoft_ = hj2->GetNhyd();
0322 nsub_ = hj2->GetNjet();
0323 nhard_ = hj2->GetNpyt();
0324
0325
0326 ++ntry;
0327 }
0328 }
0329
0330 if (ev == 0) {
0331 Sigin = hj2->GetSigin();
0332 Sigjet = hj2->GetSigjet();
0333 }
0334 ev = true;
0335
0336 if (fParams.fNhsel < 3)
0337 nsub_++;
0338
0339
0340 std::unique_ptr<HepMC::GenEvent> evt = std::make_unique<HepMC::GenEvent>();
0341 std::unique_ptr<edm::HepMCProduct> HepMCEvt = std::make_unique<edm::HepMCProduct>();
0342
0343 if (nhard_ > 0 || nsoft_ > 0)
0344 get_particles(evt.get());
0345
0346 evt->set_signal_process_id(pypars.msti[0]);
0347 evt->set_event_scale(pypars.pari[16]);
0348 add_heavy_ion_rec(evt.get());
0349
0350 if (fVertex_) {
0351
0352
0353 HepMCEvt = std::make_unique<edm::HepMCProduct>(evt.get());
0354 HepMCEvt->applyVtxGen(fVertex_);
0355 evt = std::make_unique<HepMC::GenEvent>(*HepMCEvt->GetEvent());
0356 }
0357
0358 HepMC::HEPEVT_Wrapper::check_hepevt_consistency();
0359 LogDebug("HEPEVT_info") << "Ev numb: " << HepMC::HEPEVT_Wrapper::event_number()
0360 << " Entries number: " << HepMC::HEPEVT_Wrapper::number_entries() << " Max. entries "
0361 << HepMC::HEPEVT_Wrapper::max_number_entries() << std::endl;
0362
0363 event() = std::move(evt);
0364 return kTRUE;
0365 }
0366
0367
0368 bool Hydjet2Hadronizer::declareStableParticles(const std::vector<int> &_pdg) {
0369 std::vector<int> pdg = _pdg;
0370 for (size_t i = 0; i < pdg.size(); i++) {
0371 int pyCode = pycomp_(pdg[i]);
0372 std::ostringstream pyCard;
0373 pyCard << "MDCY(" << pyCode << ",1)=0";
0374 std::cout << pyCard.str() << std::endl;
0375 call_pygive(pyCard.str());
0376 }
0377 return true;
0378 }
0379
0380 bool Hydjet2Hadronizer::hadronize() { return false; }
0381 bool Hydjet2Hadronizer::decay() { return true; }
0382 bool Hydjet2Hadronizer::residualDecay() { return true; }
0383 void Hydjet2Hadronizer::finalizeEvent() {}
0384 void Hydjet2Hadronizer::statistics() {}
0385 const char *Hydjet2Hadronizer::classname() const { return "gen::Hydjet2Hadronizer"; }
0386
0387
0388 void Hydjet2Hadronizer::rotateEvtPlane() {
0389 const double pi = 3.14159265358979;
0390 phi0_ = 2. * pi * gen::pyr_(nullptr) - pi;
0391 sinphi0_ = sin(phi0_);
0392 cosphi0_ = cos(phi0_);
0393 }
0394
0395
0396 bool Hydjet2Hadronizer::get_particles(HepMC::GenEvent *evt) {
0397 LogDebug("Hydjet2") << " Number of sub events " << nsub_;
0398 LogDebug("Hydjet2") << " Number of hard events " << hj2->GetNjet();
0399 LogDebug("Hydjet2") << " Number of hard particles " << nhard_;
0400 LogDebug("Hydjet2") << " Number of soft particles " << nsoft_;
0401 LogDebug("Hydjet2") << " nhard_ + nsoft_ = " << nhard_ + nsoft_ << " Ntot = " << hj2->GetNtot() << endl;
0402
0403 int ihy = 0;
0404 int isub_l = -1;
0405 int stab = 0;
0406
0407 vector<HepMC::GenParticle *> particle(hj2->GetNtot());
0408 HepMC::GenVertex *sub_vertices = nullptr;
0409
0410 while (ihy < hj2->GetNtot()) {
0411 if ((hj2->GetiJet().at(ihy)) != isub_l) {
0412 sub_vertices = new HepMC::GenVertex(HepMC::FourVector(0, 0, 0, 0), hj2->GetiJet().at(ihy));
0413 evt->add_vertex(sub_vertices);
0414 if (!evt->signal_process_vertex())
0415 evt->set_signal_process_vertex(sub_vertices);
0416 isub_l = hj2->GetiJet().at(ihy);
0417 }
0418
0419 if ((convertStatusForComponents(
0420 (hj2->GetFinal()).at(ihy), (hj2->GetType()).at(ihy), (hj2->GetPythiaStatus().at(ihy)))) == 1)
0421 stab++;
0422 LogDebug("Hydjet2_array") << ihy << " MULTin ev.:" << hj2->GetNtot() << " SubEv.#" << hj2->GetiJet().at(ihy)
0423 << " Part #" << ihy + 1 << ", PDG: " << hj2->GetPdg().at(ihy) << " (st. "
0424 << convertStatus(hj2->GetPythiaStatus().at(ihy))
0425 << ") mother=" << hj2->GetMotherIndex().at(ihy) + 1 << ", childs ("
0426 << hj2->GetFirstDaughterIndex().at(ihy) + 1 << "-"
0427 << hj2->GetLastDaughterIndex().at(ihy) + 1 << "), vtx (" << hj2->GetX().at(ihy) << ","
0428 << hj2->GetY().at(ihy) << "," << hj2->GetZ().at(ihy) << ") " << std::endl;
0429
0430 if ((hj2->GetMotherIndex().at(ihy)) <= 0) {
0431 particle.at(ihy) = build_hyjet2(ihy, ihy + 1);
0432 if (!sub_vertices)
0433 LogError("Hydjet2_array") << "##### HYDJET2: Vertex not initialized!";
0434 else
0435 sub_vertices->add_particle_out(particle.at(ihy));
0436 LogDebug("Hydjet2_array") << " ---> " << ihy + 1 << std::endl;
0437 } else {
0438 particle.at(ihy) = build_hyjet2(ihy, ihy + 1);
0439 int mid = hj2->GetMotherIndex().at(ihy);
0440
0441 while (((mid + 1) < ihy) && (std::abs(hj2->GetPdg().at(mid)) < 100) &&
0442 ((hj2->GetFirstDaughterIndex().at(mid + 1)) <= ihy)) {
0443 mid++;
0444 LogDebug("Hydjet2_array") << "======== MID changed to " << mid
0445 << " ======== PDG(mid) = " << hj2->GetPdg().at(mid) << std::endl;
0446 }
0447
0448 if (std::abs(hj2->GetPdg().at(mid)) < 100) {
0449 mid = hj2->GetMotherIndex().at(ihy);
0450 LogDebug("Hydjet2_array") << "======== MID changed BACK to " << mid
0451 << " ======== PDG(mid) = " << hj2->GetPdg().at(mid) << std::endl;
0452 }
0453
0454 HepMC::GenParticle *mother = particle.at(mid);
0455 HepMC::GenVertex *prod_vertex = mother->end_vertex();
0456
0457 if (!prod_vertex) {
0458 prod_vertex = build_hyjet2_vertex(ihy, (hj2->GetiJet().at(ihy)));
0459 prod_vertex->add_particle_in(mother);
0460 LogDebug("Hydjet2_array") << " <--- " << mid + 1 << std::endl;
0461 evt->add_vertex(prod_vertex);
0462 }
0463 prod_vertex->add_particle_out(particle.at(ihy));
0464 LogDebug("Hydjet2_array") << " ---" << mid + 1 << "---> " << ihy + 1 << std::endl;
0465 }
0466 ihy++;
0467 }
0468
0469 LogDebug("Hydjet2_array") << " MULTin ev.:" << hj2->GetNtot() << ", last index: " << ihy - 1
0470 << ", stable particles: " << stab << std::endl;
0471 return kTRUE;
0472 }
0473
0474
0475 HepMC::GenParticle *Hydjet2Hadronizer::build_hyjet2(int index, int barcode) {
0476
0477 double px0 = (hj2->GetPx()).at(index);
0478 double py0 = (hj2->GetPy()).at(index);
0479
0480 double px = px0 * cosphi0_ - py0 * sinphi0_;
0481 double py = py0 * cosphi0_ + px0 * sinphi0_;
0482
0483 HepMC::GenParticle *p = new HepMC::GenParticle(
0484 HepMC::FourVector(px,
0485 py,
0486 (hj2->GetPz()).at(index),
0487 (hj2->GetE()).at(index)),
0488 (hj2->GetPdg()).at(index),
0489 convertStatusForComponents(
0490 (hj2->GetFinal()).at(index), (hj2->GetType()).at(index), (hj2->GetPythiaStatus()).at(index))
0491 );
0492
0493 p->suggest_barcode(barcode);
0494 return p;
0495 }
0496
0497
0498 HepMC::GenVertex *Hydjet2Hadronizer::build_hyjet2_vertex(int i, int id) {
0499
0500 double x0 = (hj2->GetX()).at(i);
0501 double y0 = (hj2->GetY()).at(i);
0502
0503
0504 const double fm_to_mm = 1e-12;
0505 double x = fm_to_mm * (x0 * cosphi0_ - y0 * sinphi0_);
0506 double y = fm_to_mm * (y0 * cosphi0_ + x0 * sinphi0_);
0507 double z = fm_to_mm * (hj2->GetZ()).at(i);
0508 double t = fm_to_mm * (hj2->GetT()).at(i);
0509
0510 HepMC::GenVertex *vertex = new HepMC::GenVertex(HepMC::FourVector(x, y, z, t), id);
0511
0512 return vertex;
0513 }
0514
0515
0516 void Hydjet2Hadronizer::add_heavy_ion_rec(HepMC::GenEvent *evt) {
0517
0518 int nproj = static_cast<int>((hj2->GetNpart()) / 2);
0519 int ntarg = static_cast<int>((hj2->GetNpart()) - nproj);
0520
0521 HepMC::HeavyIon *hi = new HepMC::HeavyIon(nsub_,
0522 nproj,
0523 ntarg,
0524 hj2->GetNbcol(),
0525 0,
0526 0,
0527 0,
0528 0,
0529 0,
0530 hj2->GetBgen() * nuclear_radius(),
0531 phi0_,
0532 hj2->GetPsiv3(),
0533 Sigin
0534 );
0535
0536 evt->set_heavy_ion(*hi);
0537 delete hi;
0538 }