00001 #include <cstring>
00002 #include <sstream>
00003 #include <string>
00004 #include <vector>
00005 #include <memory>
00006 #include <map>
00007 #include <set>
00008
00009 #include <boost/shared_ptr.hpp>
00010 #include <boost/algorithm/string/classification.hpp>
00011 #include <boost/algorithm/string/split.hpp>
00012
00013 #include <HepMC/GenEvent.h>
00014 #include <HepMC/GenParticle.h>
00015 #include <HepMC/GenVertex.h>
00016 #include <HepMC/PdfInfo.h>
00017 #include <HepMC/HerwigWrapper6_4.h>
00018 #include <HepMC/HEPEVT_Wrapper.h>
00019 #include <HepMC/IO_HERWIG.h>
00020 #include "HepPID/ParticleIDTranslations.hh"
00021
00022 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00023
00024 #include "SimDataFormats/GeneratorProducts/interface/HepMCProduct.h"
00025 #include "SimDataFormats/GeneratorProducts/interface/GenRunInfoProduct.h"
00026
00027 #include "SimDataFormats/GeneratorProducts/interface/LesHouches.h"
00028 #include "SimDataFormats/GeneratorProducts/interface/LHECommonBlocks.h"
00029
00030 #include "GeneratorInterface/Core/interface/ParameterCollector.h"
00031 #include "GeneratorInterface/Core/interface/BaseHadronizer.h"
00032 #include "GeneratorInterface/Core/interface/GeneratorFilter.h"
00033 #include "GeneratorInterface/Core/interface/HadronizerFilter.h"
00034
00035 #include "GeneratorInterface/LHEInterface/interface/LHEEvent.h"
00036
00037 #include "GeneratorInterface/Herwig6Interface/interface/Herwig6Instance.h"
00038 #include "GeneratorInterface/Herwig6Interface/interface/herwig.h"
00039
00040 #include "DataFormats/Math/interface/LorentzVector.h"
00041
00042 extern "C" {
00043 void hwuidt_(int *iopt, int *ipdg, int *iwig, char nwig[8]);
00044 double hwualf_(int *mode, double* scale);
00045 double hwuaem_(double* scale);
00046 }
00047
00048
00049 namespace {
00050 static inline bool call_hwmsct()
00051 {
00052 int result;
00053 hwmsct(&result);
00054 return result;
00055 }
00056
00057 static int pdgToHerwig(int ipdg, char *nwig)
00058 {
00059 int iopt = 1;
00060 int iwig = 0;
00061 hwuidt_(&iopt, &ipdg, &iwig, nwig);
00062 return ipdg ? iwig : 0;
00063 }
00064
00065 static bool markStable(int pdgId)
00066 {
00067 char nwig[9] = " ";
00068 if (!pdgToHerwig(pdgId, nwig))
00069 return false;
00070 hwusta(nwig, 1);
00071 return true;
00072 }
00073 }
00074
00075 class Herwig6Hadronizer : public gen::BaseHadronizer,
00076 public gen::Herwig6Instance {
00077 public:
00078 Herwig6Hadronizer(const edm::ParameterSet ¶ms);
00079 ~Herwig6Hadronizer();
00080
00081 void setSLHAFromHeader(const std::vector<std::string> &lines);
00082 bool initialize(const lhef::HEPRUP *heprup);
00083
00084 bool readSettings( int );
00085
00086
00087
00088
00089 bool initializeForInternalPartons();
00090 bool initializeForExternalPartons() { return initializeForInternalPartons(); }
00091
00092 bool declareStableParticles( const std::vector<int> &pdgIds);
00093 bool declareSpecialSettings( const std::vector<std::string> );
00094
00095 void statistics();
00096
00097
00098 bool generatePartonsAndHadronize() { return hadronize(); }
00099 bool hadronize();
00100 bool decay();
00101 bool residualDecay();
00102 void finalizeEvent();
00103
00104 const char *classname() const { return "Herwig6Hadronizer"; }
00105
00106 private:
00107 void clear();
00108
00109 int pythiaStatusCode(const HepMC::GenParticle *p) const;
00110 void pythiaStatusCodes();
00111
00112 virtual void upInit();
00113 virtual void upEvnt();
00114
00115 HepMC::IO_HERWIG conv;
00116 bool needClear;
00117 bool externalPartons;
00118
00119 gen::ParameterCollector parameters;
00120 int herwigVerbosity;
00121 int hepmcVerbosity;
00122 int maxEventsToPrint;
00123 bool printCards;
00124 bool emulatePythiaStatusCodes;
00125 double comEnergy;
00126 bool useJimmy;
00127 bool doMPInteraction;
00128 int numTrials;
00129 bool fConvertToPDG;
00130
00131 bool readMCatNLOfile;
00132
00133 };
00134
00135 extern "C" {
00136 void hwwarn_(const char *method, int *id);
00137 void setherwpdf_(void);
00138 void mysetpdfpath_(const char *path);
00139 }
00140
00141 Herwig6Hadronizer::Herwig6Hadronizer(const edm::ParameterSet ¶ms) :
00142 BaseHadronizer(params),
00143 needClear(false),
00144 parameters(params.getParameter<edm::ParameterSet>("HerwigParameters")),
00145 herwigVerbosity(params.getUntrackedParameter<int>("herwigVerbosity", 0)),
00146 hepmcVerbosity(params.getUntrackedParameter<int>("hepmcVerbosity", 0)),
00147 maxEventsToPrint(params.getUntrackedParameter<int>("maxEventsToPrint", 0)),
00148 printCards(params.getUntrackedParameter<bool>("printCards", false)),
00149 emulatePythiaStatusCodes(params.getUntrackedParameter<bool>("emulatePythiaStatusCodes", false)),
00150 comEnergy(params.getParameter<double>("comEnergy")),
00151 useJimmy(params.getParameter<bool>("useJimmy")),
00152 doMPInteraction(params.getParameter<bool>("doMPInteraction")),
00153 numTrials(params.getUntrackedParameter<int>("numTrialsMPI", 100)),
00154 readMCatNLOfile(false)
00155 {
00156
00157 fConvertToPDG = false;
00158 if ( params.exists( "doPDGConvert" ) )
00159 fConvertToPDG = params.getParameter<bool>("doPDGConvert");
00160 }
00161
00162 Herwig6Hadronizer::~Herwig6Hadronizer()
00163 {
00164 clear();
00165 }
00166
00167 void Herwig6Hadronizer::clear()
00168 {
00169 if (!needClear)
00170 return;
00171
00172
00173 call(hwefin);
00174 if (useJimmy)
00175 call(jmefin);
00176
00177 needClear = false;
00178 }
00179
00180 void Herwig6Hadronizer::setSLHAFromHeader(
00181 const std::vector<std::string> &lines)
00182 {
00183 std::set<std::string> blocks;
00184 std::string block;
00185 for(std::vector<std::string>::const_iterator iter = lines.begin();
00186 iter != lines.end(); ++iter) {
00187 std::string line = *iter;
00188 std::transform(line.begin(), line.end(),
00189 line.begin(), (int(*)(int))std::toupper);
00190 std::string::size_type pos = line.find('#');
00191 if (pos != std::string::npos)
00192 line.resize(pos);
00193
00194 if (line.empty())
00195 continue;
00196
00197 if (!boost::algorithm::is_space()(line[0])) {
00198 std::vector<std::string> tokens;
00199 boost::split(tokens, line,
00200 boost::algorithm::is_space(),
00201 boost::token_compress_on);
00202 if (!tokens.size())
00203 continue;
00204 block.clear();
00205 if (tokens.size() < 2)
00206 continue;
00207 if (tokens[0] == "BLOCK")
00208 block = tokens[1];
00209 else if (tokens[0] == "DECAY")
00210 block = "DECAY";
00211
00212 if (block.empty())
00213 continue;
00214
00215 if (!blocks.count(block)) {
00216 blocks.insert(block);
00217 edm::LogWarning("Generator|Herwig6Hadronzier")
00218 << "Unsupported SLHA block \"" << block
00219 << "\". It will be ignored."
00220 << std::endl;
00221 }
00222 }
00223 }
00224 }
00225
00226 bool Herwig6Hadronizer:: readSettings( int key )
00227 {
00228
00229 clear();
00230 const lhef::HEPRUP* heprup = lheRunInfo()->getHEPRUP();
00231 externalPartons = ( heprup != 0 );
00232
00233 if ( key == 0 && externalPartons ) return false;
00234 if ( key > 0 && !externalPartons ) return false;
00235
00236 std::ostringstream info;
00237 info << "---------------------------------------------------\n";
00238 info << "Taking in settinsg for Herwig6Hadronizer for "
00239 << (externalPartons ? "external" : "internal") << " partons\n";
00240 info << "---------------------------------------------------\n";
00241
00242 info << " Herwig verbosity level = " << herwigVerbosity << "\n";
00243 info << " HepMC verbosity = " << hepmcVerbosity << "\n";
00244 info << " Number of events to be printed = " << maxEventsToPrint << "\n";
00245
00246
00247 hwudat();
00248
00249
00250 if (externalPartons) {
00251 hwproc.PBEAM1 = heprup->EBMUP.first;
00252 hwproc.PBEAM2 = heprup->EBMUP.second;
00253 pdgToHerwig(heprup->IDBMUP.first, hwbmch.PART1);
00254 pdgToHerwig(heprup->IDBMUP.second, hwbmch.PART2);
00255 }
00256 else
00257 {
00258 hwproc.PBEAM1 = 0.5 * comEnergy;
00259 hwproc.PBEAM2 = 0.5 * comEnergy;
00260 pdgToHerwig(2212, hwbmch.PART1);
00261 pdgToHerwig(2212, hwbmch.PART2);
00262 }
00263
00264 if (useJimmy)
00265 {
00266 info << " HERWIG will be using JIMMY for UE/MI.\n";
00267 jmparm.MSFLAG = 1;
00268 if (doMPInteraction)
00269 info << " JIMMY trying to generate multiple interactions.\n";
00270 }
00271
00272
00273
00274
00275 bool iprocFound=false;
00276
00277 for(gen::ParameterCollector::const_iterator line = parameters.begin();
00278 line != parameters.end(); ++line)
00279 {
00280 if(!strcmp((line->substr(0,5)).c_str(),"IPROC")) {
00281 if (!give(*line))
00282 throw edm::Exception(edm::errors::Configuration)
00283 << "Herwig 6 did not accept the following: \""
00284 << *line << "\"." << std::endl;
00285 else iprocFound=true;
00286 }
00287 }
00288
00289 if (!iprocFound && !externalPartons)
00290 throw edm::Exception(edm::errors::Configuration)
00291 << "You have to define the process with IPROC." << std::endl;
00292
00293
00294 call(hwigin);
00295
00296 hwevnt.MAXER = 100000000;
00297 hwpram.LWSUD = 0;
00298 hwdspn.LWDEC = 0;
00299
00300
00301 std::memset(hwprch.AUTPDF, ' ', sizeof hwprch.AUTPDF);
00302 for(unsigned int i = 0; i < 2; i++) {
00303 hwpram.MODPDF[i] = -111;
00304 std::memcpy(hwprch.AUTPDF[i], "HWLHAPDF", 8);
00305 }
00306
00307 hwevnt.MAXPR = maxEventsToPrint;
00308 hwpram.IPRINT = herwigVerbosity;
00309
00310
00311 if (printCards) {
00312 info << "\n";
00313 info << "------------------------------------\n";
00314 info << "Reading HERWIG parameters\n";
00315 info << "------------------------------------\n";
00316
00317 }
00318 for(gen::ParameterCollector::const_iterator line = parameters.begin();
00319 line != parameters.end(); ++line) {
00320 if (printCards)
00321 info << " " << *line << "\n";
00322 if (!give(*line))
00323 throw edm::Exception(edm::errors::Configuration)
00324 << "Herwig 6 did not accept the following: \""
00325 << *line << "\"." << std::endl;
00326 }
00327
00328 if (printCards)
00329 info << "\n";
00330
00331 if (externalPartons) {
00332 std::vector<std::string> slha =
00333 lheRunInfo()->findHeader("slha");
00334 if (!slha.empty())
00335 setSLHAFromHeader(slha);
00336 }
00337
00338 needClear = true;
00339
00340 std::pair<int, int> pdfs(-1, -1);
00341 if (externalPartons)
00342 pdfs = lheRunInfo()->pdfSetTranslation();
00343
00344 if (hwpram.MODPDF[0] != -111 || hwpram.MODPDF[1] != -111) {
00345 for(unsigned int i = 0; i < 2; i++)
00346 if (hwpram.MODPDF[i] == -111)
00347 hwpram.MODPDF[i] = -1;
00348
00349 if (pdfs.first != -1 || pdfs.second != -1)
00350 edm::LogError("Generator|Herwig6Hadronzier")
00351 << "Both external Les Houches event and "
00352 "config file specify a PDF set. "
00353 "User PDF will override external one."
00354 << std::endl;
00355
00356 pdfs.first = hwpram.MODPDF[0] != -111 ? hwpram.MODPDF[0] : -1;
00357 pdfs.second = hwpram.MODPDF[1] != -111 ? hwpram.MODPDF[1] : -1;
00358 }
00359
00360 hwpram.MODPDF[0] = pdfs.first;
00361 hwpram.MODPDF[1] = pdfs.second;
00362
00363 if (externalPartons)
00364 hwproc.IPROC = -1;
00365
00366 edm::LogInfo(info.str());
00367
00368 return true;
00369
00370 }
00371
00372 bool Herwig6Hadronizer::initializeForInternalPartons()
00373 {
00374
00375 if (useJimmy) call(jimmin);
00376
00377 call(hwuinc);
00378
00379
00380 call(hweini);
00381
00382 if (useJimmy) call(jminit);
00383
00384 return true;
00385
00386 }
00387
00388
00389 bool Herwig6Hadronizer::initialize(const lhef::HEPRUP *heprup)
00390 {
00391 clear();
00392
00393 externalPartons = (heprup != 0);
00394
00395 std::ostringstream info;
00396 info << "---------------------------------------------------\n";
00397 info << "Initializing Herwig6Hadronizer for "
00398 << (externalPartons ? "external" : "internal") << " partons\n";
00399 info << "---------------------------------------------------\n";
00400
00401 info << " Herwig verbosity level = " << herwigVerbosity << "\n";
00402 info << " HepMC verbosity = " << hepmcVerbosity << "\n";
00403 info << " Number of events to be printed = " << maxEventsToPrint << "\n";
00404
00405
00406 hwudat();
00407
00408
00409 if (externalPartons) {
00410 hwproc.PBEAM1 = heprup->EBMUP.first;
00411 hwproc.PBEAM2 = heprup->EBMUP.second;
00412 pdgToHerwig(heprup->IDBMUP.first, hwbmch.PART1);
00413 pdgToHerwig(heprup->IDBMUP.second, hwbmch.PART2);
00414 } else {
00415 hwproc.PBEAM1 = 0.5 * comEnergy;
00416 hwproc.PBEAM2 = 0.5 * comEnergy;
00417 pdgToHerwig(2212, hwbmch.PART1);
00418 pdgToHerwig(2212, hwbmch.PART2);
00419 }
00420
00421 if (useJimmy) {
00422 info << " HERWIG will be using JIMMY for UE/MI.\n";
00423 jmparm.MSFLAG = 1;
00424 if (doMPInteraction)
00425 info << " JIMMY trying to generate multiple interactions.\n";
00426 }
00427
00428
00429
00430 bool iprocFound=false;
00431
00432 for(gen::ParameterCollector::const_iterator line = parameters.begin();
00433 line != parameters.end(); ++line) {
00434 if(!strcmp((line->substr(0,5)).c_str(),"IPROC")) {
00435 if (!give(*line))
00436 throw edm::Exception(edm::errors::Configuration)
00437 << "Herwig 6 did not accept the following: \""
00438 << *line << "\"." << std::endl;
00439 else iprocFound=true;
00440 }
00441 }
00442
00443 if (!iprocFound && !externalPartons)
00444 throw edm::Exception(edm::errors::Configuration)
00445 << "You have to define the process with IPROC." << std::endl;
00446
00447
00448 call(hwigin);
00449 hwevnt.MAXER = 100000000;
00450 hwpram.LWSUD = 0;
00451 hwdspn.LWDEC = 0;
00452
00453
00454
00455
00456 std::memset(hwprch.AUTPDF, ' ', sizeof hwprch.AUTPDF);
00457 for(unsigned int i = 0; i < 2; i++) {
00458 hwpram.MODPDF[i] = -111;
00459 std::memcpy(hwprch.AUTPDF[i], "HWLHAPDF", 8);
00460 }
00461
00462 if (useJimmy)
00463 call(jimmin);
00464
00465 hwevnt.MAXPR = maxEventsToPrint;
00466 hwpram.IPRINT = herwigVerbosity;
00467
00468
00469 if (printCards) {
00470 info << "\n";
00471 info << "------------------------------------\n";
00472 info << "Reading HERWIG parameters\n";
00473 info << "------------------------------------\n";
00474
00475 }
00476 for(gen::ParameterCollector::const_iterator line = parameters.begin();
00477 line != parameters.end(); ++line) {
00478 if (printCards)
00479 info << " " << *line << "\n";
00480 if (!give(*line))
00481 throw edm::Exception(edm::errors::Configuration)
00482 << "Herwig 6 did not accept the following: \""
00483 << *line << "\"." << std::endl;
00484 }
00485
00486 if (printCards)
00487 info << "\n";
00488
00489 if (externalPartons) {
00490 std::vector<std::string> slha =
00491 lheRunInfo()->findHeader("slha");
00492 if (!slha.empty())
00493 setSLHAFromHeader(slha);
00494 }
00495
00496 needClear = true;
00497
00498 std::pair<int, int> pdfs(-1, -1);
00499 if (externalPartons)
00500 pdfs = lheRunInfo()->pdfSetTranslation();
00501
00502 if (hwpram.MODPDF[0] != -111 || hwpram.MODPDF[1] != -111) {
00503 for(unsigned int i = 0; i < 2; i++)
00504 if (hwpram.MODPDF[i] == -111)
00505 hwpram.MODPDF[i] = -1;
00506
00507 if (pdfs.first != -1 || pdfs.second != -1)
00508 edm::LogError("Generator|Herwig6Hadronzier")
00509 << "Both external Les Houches event and "
00510 "config file specify a PDF set. "
00511 "User PDF will override external one."
00512 << std::endl;
00513
00514 pdfs.first = hwpram.MODPDF[0] != -111 ? hwpram.MODPDF[0] : -1;
00515 pdfs.second = hwpram.MODPDF[1] != -111 ? hwpram.MODPDF[1] : -1;
00516 }
00517
00518 hwpram.MODPDF[0] = pdfs.first;
00519 hwpram.MODPDF[1] = pdfs.second;
00520
00521 if (externalPartons)
00522 hwproc.IPROC = -1;
00523
00524
00525 call(hwuinc);
00526 markStable(13);
00527 markStable(-13);
00528 markStable(3112);
00529 markStable(-3112);
00530 markStable(3222);
00531 markStable(-3222);
00532 markStable(3122);
00533 markStable(-3122);
00534 markStable(3312);
00535 markStable(-3312);
00536 markStable(3322);
00537 markStable(-3322);
00538 markStable(3334);
00539 markStable(-3334);
00540 markStable(211);
00541 markStable(-211);
00542 markStable(321);
00543 markStable(-321);
00544 markStable(310);
00545 markStable(130);
00546
00547
00548
00549
00550
00551 call(hweini);
00552
00553 if (useJimmy)
00554 call(jminit);
00555
00556 edm::LogInfo(info.str());
00557
00558 return true;
00559 }
00560
00561 bool Herwig6Hadronizer::declareStableParticles(const std::vector<int> &pdgIds)
00562 {
00563 markStable(13);
00564 markStable(-13);
00565 markStable(3112);
00566 markStable(-3112);
00567 markStable(3222);
00568 markStable(-3222);
00569 markStable(3122);
00570 markStable(-3122);
00571 markStable(3312);
00572 markStable(-3312);
00573 markStable(3322);
00574 markStable(-3322);
00575 markStable(3334);
00576 markStable(-3334);
00577 markStable(211);
00578 markStable(-211);
00579 markStable(321);
00580 markStable(-321);
00581 markStable(310);
00582 markStable(130);
00583
00584 for(std::vector<int>::const_iterator iter = pdgIds.begin();
00585 iter != pdgIds.end(); ++iter)
00586 if (!markStable(*iter))
00587 return false;
00588 return true;
00589 }
00590
00591 bool Herwig6Hadronizer::declareSpecialSettings( const std::vector<std::string> )
00592 {
00593 return true;
00594 }
00595
00596 void Herwig6Hadronizer::statistics()
00597 {
00598 if (!runInfo().internalXSec()) {
00599
00600
00601
00602
00603 double RNWGT = 1. / hwevnt.NWGTS;
00604 double AVWGT = hwevnt.WGTSUM * RNWGT;
00605
00606 double xsec = 1.0e3 * AVWGT;
00607
00608 runInfo().setInternalXSec(xsec);
00609 }
00610 }
00611
00612 bool Herwig6Hadronizer::hadronize()
00613 {
00614
00615
00616 InstanceWrapper wrapper(this);
00617
00618 event().reset();
00619
00620
00621
00622 hwuine();
00623
00624 if (callWithTimeout(10, hwepro)) {
00625
00626 int error = 199;
00627 hwwarn_("HWHGUP", &error);
00628 }
00629
00630 hwbgen();
00631
00632
00633 if (useJimmy && doMPInteraction && !hwevnt.IERROR && call_hwmsct()) {
00634 if (lheEvent()) lheEvent()->count(lhef::LHERunInfo::kKilled);
00635 return false;
00636 }
00637
00638 hwdhob();
00639 hwcfor();
00640 hwcdec();
00641
00642
00643 if (hwevnt.IERROR) {
00644 hwufne();
00645 if (lheEvent()) lheEvent()->count(lhef::LHERunInfo::kKilled);
00646 return false;
00647 }
00648
00649 if (lheEvent()) lheEvent()->count(lhef::LHERunInfo::kAccepted);
00650 return true;
00651 }
00652
00653 void Herwig6Hadronizer::finalizeEvent()
00654 {
00655 lhef::LHEEvent::fixHepMCEventTimeOrdering(event().get());
00656
00657 HepMC::PdfInfo pdfInfo;
00658 if(externalPartons) {
00659 lheEvent()->fillEventInfo( event().get() );
00660 lheEvent()->fillPdfInfo( &pdfInfo );
00661
00662
00663 if(event()->signal_process_id()==0)
00664 event()->set_signal_process_id( abs(hwproc.IPROC) );
00665
00666 }
00667
00668 HepMC::GenParticle* incomingParton = NULL;
00669 HepMC::GenParticle* targetParton = NULL;
00670
00671 HepMC::GenParticle* incomingProton = NULL;
00672 HepMC::GenParticle* targetProton = NULL;
00673
00674
00675 for(HepMC::GenEvent::particle_const_iterator it = event()->particles_begin();
00676 (it != event()->particles_end() && incomingParton==NULL); it++)
00677 if((*it)->status()==121) incomingParton = (*it);
00678
00679
00680 for(HepMC::GenEvent::particle_const_iterator it = event()->particles_begin();
00681 (it != event()->particles_end() && targetParton==NULL); it++)
00682 if((*it)->status()==122) targetParton = (*it);
00683
00684
00685 for(HepMC::GenEvent::particle_const_iterator it = event()->particles_begin();
00686 (it != event()->particles_end() && incomingProton==NULL); it++)
00687 if((*it)->status()==101 && (*it)->pdg_id()==2212) incomingProton = (*it);
00688
00689
00690 for(HepMC::GenEvent::particle_const_iterator it = event()->particles_begin();
00691 (it != event()->particles_end() && targetProton==NULL); it++)
00692 if((*it)->status()==102 && (*it)->pdg_id()==2212) targetProton = (*it);
00693
00694
00695 if( incomingParton && targetParton ) {
00696 math::XYZTLorentzVector totMomentum(0,0,0,0);
00697 totMomentum+=incomingParton->momentum();
00698 totMomentum+=targetParton->momentum();
00699 double evScale = totMomentum.mass();
00700 double evScale2 = evScale*evScale;
00701
00702
00703 int one=1;
00704 double alphaQCD=hwualf_(&one,&evScale);
00705 double alphaQED=hwuaem_(&evScale2);
00706
00707 if(!externalPartons || event()->event_scale() < 0) event()->set_event_scale(evScale);
00708 if(!externalPartons || event()->alphaQCD() < 0) event()->set_alphaQCD(alphaQCD);
00709 if(!externalPartons || event()->alphaQED() < 0) event()->set_alphaQED(alphaQED);
00710
00711 if(!externalPartons || pdfInfo.x1() < 0) {
00712
00713 pdfInfo.set_id1( incomingParton->pdg_id()==21 ? 0 : incomingParton->pdg_id());
00714 pdfInfo.set_id2( targetParton->pdg_id()==21 ? 0 : targetParton->pdg_id());
00715 if( incomingProton && targetProton ) {
00716 double x1 = incomingParton->momentum().pz()/incomingProton->momentum().pz();
00717 double x2 = targetParton->momentum().pz()/targetProton->momentum().pz();
00718 pdfInfo.set_x1(x1);
00719 pdfInfo.set_x2(x2);
00720 }
00721
00722 pdfInfo.set_scalePDF(evScale);
00723 }
00724
00725 if(!externalPartons || event()->signal_process_id() < 0) event()->set_signal_process_id( abs(hwproc.IPROC) );
00726 event()->set_pdf_info( pdfInfo );
00727 }
00728
00729
00730 if (lheRunInfo() != 0 && std::abs(lheRunInfo()->getHEPRUP()->IDWTUP) == 4)
00731
00732
00733 event()->weights().push_back( 1.0e3 * hwevnt.EVWGT );
00734 else
00735 event()->weights().push_back( hwevnt.EVWGT );
00736
00737
00738
00739 HepMC::GenParticle* finalParton = NULL;
00740 for(HepMC::GenEvent::particle_const_iterator it = event()->particles_begin();
00741 (it != event()->particles_end() && finalParton==NULL); it++)
00742 if((*it)->status()==123) finalParton = (*it);
00743
00744
00745
00746 eventInfo().reset(new GenEventInfoProduct(event().get()));
00747 if(finalParton) {
00748 double thisPt=finalParton->momentum().perp();
00749 eventInfo()->setBinningValues(std::vector<double>(1, thisPt));
00750 }
00751
00752
00753 if (emulatePythiaStatusCodes)
00754 pythiaStatusCodes();
00755
00756 }
00757
00758
00759 bool Herwig6Hadronizer::decay()
00760 {
00761
00762
00763 InstanceWrapper wrapper(this);
00764
00765 hwdhad();
00766 hwdhvy();
00767 hwmevt();
00768
00769 hwufne();
00770
00771 if (hwevnt.IERROR)
00772 return false;
00773
00774 event().reset(new HepMC::GenEvent);
00775 if (!conv.fill_next_event(event().get()))
00776 throw cms::Exception("Herwig6Error")
00777 << "HepMC Conversion problems in event." << std::endl;
00778
00779
00780 if ( fConvertToPDG ) {
00781 for ( HepMC::GenEvent::particle_iterator part = event()->particles_begin(); part != event()->particles_end(); ++part) {
00782 if ((*part)->pdg_id() != HepPID::translateHerwigtoPDT((*part)->pdg_id()))
00783 (*part)->set_pdg_id(HepPID::translateHerwigtoPDT((*part)->pdg_id()));
00784 }
00785 }
00786
00787 return true;
00788 }
00789
00790 bool Herwig6Hadronizer::residualDecay()
00791 {
00792 return true;
00793 }
00794
00795 void Herwig6Hadronizer::upInit()
00796 {
00797 lhef::CommonBlocks::fillHEPRUP(lheRunInfo()->getHEPRUP());
00798 heprup_.pdfgup[0] = heprup_.pdfgup[1] = -1;
00799 heprup_.pdfsup[0] = heprup_.pdfsup[1] = -1;
00800
00801
00802
00803 std::string mcnloHeader="herwig6header";
00804 std::vector<lhef::LHERunInfo::Header> headers=lheRunInfo()->getHeaders();
00805 for(std::vector<lhef::LHERunInfo::Header>::const_iterator hIter=headers.begin();hIter!=headers.end(); ++hIter) {
00806 if(hIter->tag()==mcnloHeader){
00807 readMCatNLOfile=true;
00808 for(lhef::LHERunInfo::Header::const_iterator lIter=hIter->begin(); lIter != hIter->end(); ++lIter) {
00809 if((lIter->c_str())[0]!='#' && (lIter->c_str())[0]!='\n') {
00810 if (!give(*lIter))
00811 throw edm::Exception(edm::errors::Configuration)
00812 << "Herwig 6 did not accept the following: \""
00813 << *lIter << "\"." << std::endl;
00814 }
00815 }
00816 }
00817 }
00818 }
00819
00820 void Herwig6Hadronizer::upEvnt()
00821 {
00822 lhef::CommonBlocks::fillHEPEUP(lheEvent()->getHEPEUP());
00823
00824
00825 if(readMCatNLOfile) {
00826 for(std::vector<std::string>::const_iterator iter=lheEvent()->getComments().begin();
00827 iter!=lheEvent()->getComments().end(); ++iter) {
00828 std::string toParse(iter->substr(1));
00829 if (!give(toParse))
00830 throw edm::Exception(edm::errors::Configuration)
00831 << "Herwig 6 did not accept the following: \""
00832 << toParse << "\"." << std::endl;
00833 }
00834 }
00835
00836 }
00837
00838 int Herwig6Hadronizer::pythiaStatusCode(const HepMC::GenParticle *p) const
00839 {
00840 int status = p->status();
00841
00842
00843 if (status == 3 && !p->end_vertex())
00844 return 2;
00845
00846 if (status >= 1 && status <= 3)
00847 return status;
00848
00849 if (!p->end_vertex())
00850 return 1;
00851
00852
00853
00854 int currentId = p->pdg_id();
00855 int orig = status;
00856 if (status == 123 || status == 124 ||
00857 status == 155 || status == 156 || status == 160 ||
00858 (status >= 195 && status <= 197)) {
00859 for(const HepMC::GenParticle *q = p;;) {
00860 const HepMC::GenVertex *vtx = q->end_vertex();
00861 if (!vtx)
00862 break;
00863
00864 HepMC::GenVertex::particles_out_const_iterator iter;
00865 for(iter = vtx->particles_out_const_begin();
00866 iter != vtx->particles_out_const_end(); ++iter)
00867 if ((*iter)->pdg_id() == currentId)
00868 break;
00869
00870 if (iter == vtx->particles_out_const_end())
00871 break;
00872
00873 q = *iter;
00874 if (q->status() == 3 ||
00875 ((status == 120 || status == 123 ||
00876 status == 124) && orig > 124))
00877 return 4;
00878 }
00879 }
00880
00881 int nesting = 0;
00882 for(;;) {
00883 if ((status >= 120 && status <= 122) || status == 3) {
00884
00885
00886 if (externalPartons)
00887 return ((orig >= 121 && orig <= 124) ||
00888 orig == 3) ? 3 : 4;
00889 else
00890 return (nesting ||
00891 (status != 3 && orig <= 124)) ? 3 : 4;
00892 }
00893
00894
00895
00896 if (!(status == 4 || status == 123 || status == 124 ||
00897 status == 155 || status == 156 || status == 160 ||
00898 (status >= 195 && status <= 197)))
00899 break;
00900
00901 const HepMC::GenVertex *vtx = p->production_vertex();
00902 if (!vtx || !vtx->particles_in_size())
00903 break;
00904
00905 p = *vtx->particles_in_const_begin();
00906 status = p->status();
00907
00908 int newId = p->pdg_id();
00909
00910 if (!newId)
00911 break;
00912
00913
00914 if (newId != currentId) {
00915 if (++nesting > 1 && externalPartons)
00916 break;
00917 currentId = newId;
00918 }
00919 }
00920
00921 return 2;
00922 }
00923
00924 void Herwig6Hadronizer::pythiaStatusCodes()
00925 {
00926 for(HepMC::GenEvent::particle_iterator iter =
00927 event()->particles_begin();
00928 iter != event()->particles_end(); iter++)
00929 (*iter)->set_status(pythiaStatusCode(*iter));
00930
00931 for(HepMC::GenEvent::particle_iterator iter =
00932 event()->particles_begin();
00933 iter != event()->particles_end(); iter++)
00934 if ((*iter)->status() == 4)
00935 (*iter)->set_status(2);
00936 }
00937
00938 #include "GeneratorInterface/ExternalDecays/interface/ExternalDecayDriver.h"
00939
00940 typedef edm::GeneratorFilter<Herwig6Hadronizer, gen::ExternalDecayDriver> Herwig6GeneratorFilter;
00941 DEFINE_FWK_MODULE(Herwig6GeneratorFilter);
00942
00943 typedef edm::HadronizerFilter<Herwig6Hadronizer, gen::ExternalDecayDriver> Herwig6HadronizerFilter;
00944 DEFINE_FWK_MODULE(Herwig6HadronizerFilter);