00001 #include <iostream>
00002 #include <iomanip>
00003 #include <sstream>
00004 #include <fstream>
00005 #include <string>
00006 #include <memory>
00007 #include <cmath>
00008
00009 #include <boost/algorithm/string/classification.hpp>
00010 #include <boost/algorithm/string/split.hpp>
00011
00012 #include "FWCore/Framework/interface/Event.h"
00013 #include "FWCore/Framework/interface/Run.h"
00014 #include "FWCore/Framework/interface/MakerMacros.h"
00015 #include "FWCore/Framework/interface/InputSourceMacros.h"
00016 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00017 #include "FWCore/Utilities/interface/Exception.h"
00018 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00019 #include "FWCore/Sources/interface/ExternalInputSource.h"
00020
00021 #include "SimDataFormats/GeneratorProducts/interface/LesHouches.h"
00022 #include "SimDataFormats/GeneratorProducts/interface/LHECommonBlocks.h"
00023 #include "SimDataFormats/GeneratorProducts/interface/LHERunInfoProduct.h"
00024 #include "SimDataFormats/GeneratorProducts/interface/LHEEventProduct.h"
00025
00026 #include "GeneratorInterface/AlpgenInterface/interface/AlpgenHeader.h"
00027 #include "GeneratorInterface/AlpgenInterface/interface/AlpgenEventRecordFixes.h"
00028
00029 class AlpgenSource : public edm::ExternalInputSource {
00030 public:
00032 AlpgenSource(const edm::ParameterSet ¶ms,
00033 const edm::InputSourceDescription &desc);
00034
00036 virtual ~AlpgenSource();
00037
00038 private:
00039 virtual bool produce(edm::Event &event);
00040 virtual void beginRun(edm::Run &run);
00041
00043 template<typename T>
00044 T getParameter(AlpgenHeader::Parameter index) const;
00046 template<typename T>
00047 T getParameter(AlpgenHeader::Parameter index, const T &defValue) const;
00048
00051 std::string slhaMassLine(int pdgId, AlpgenHeader::Masses mass,
00052 const std::string &comment) const;
00053
00057 unsigned int processID() const;
00058
00060 bool readAlpgenEvent(lhef::HEPEUP &hepeup);
00061
00063 std::string fileName_;
00064
00066 std::auto_ptr<std::ifstream> inputFile_;
00067
00069 unsigned long skipEvents_;
00070
00072 unsigned long nEvent_;
00073
00075 LHERunInfoProduct::Header lheAlpgenUnwParHeader;
00077 AlpgenHeader header;
00078
00080 std::string extraHeaderFileName_;
00081
00083 std::string extraHeaderName_;
00084
00086 bool writeAlpgenWgtFile;
00087 bool writeAlpgenParFile;
00088 bool writeExtraHeader;
00089 };
00090
00091 AlpgenSource::AlpgenSource(const edm::ParameterSet ¶ms,
00092 const edm::InputSourceDescription &desc) :
00093 edm::ExternalInputSource(params, desc, false),
00094 skipEvents_(params.getUntrackedParameter<unsigned int>("skipEvents", 0)),
00095 nEvent_(0), lheAlpgenUnwParHeader("AlpgenUnwParFile"),
00096 extraHeaderFileName_(params.getUntrackedParameter<std::string>("extraHeaderFileName","")),
00097 extraHeaderName_(params.getUntrackedParameter<std::string>("extraHeaderName","")),
00098 writeAlpgenWgtFile(params.getUntrackedParameter<bool>("writeAlpgenWgtFile", true)),
00099 writeAlpgenParFile(params.getUntrackedParameter<bool>("writeAlpgenParFile", true)),
00100 writeExtraHeader(params.getUntrackedParameter<bool>("writeExtraHeader", false))
00101 {
00102 std::vector<std::string> allFileNames = fileNames();
00103
00104
00105 if (allFileNames.size() != 1)
00106 throw cms::Exception("Generator|AlpgenInterface")
00107 << "AlpgenSource needs exactly one file specified "
00108 "for now." << std::endl;
00109
00110 fileName_ = allFileNames[0];
00111
00112
00113 if (fileName_.find("file:") != 0)
00114 throw cms::Exception("Generator|AlpgenInterface") << "AlpgenSource only supports the file: scheme "
00115 "for now." << std::endl;
00116 fileName_.erase(0, 5);
00117
00118
00119
00120 std::ifstream reader((fileName_ + "_unw.par").c_str());
00121 if (!reader.good())
00122 throw cms::Exception("Generator|AlpgenInterface")
00123 << "AlpgenSource was unable to open the file \""
00124 << fileName_ << "_unw.par\"." << std::endl;
00125
00126
00127 char buffer[256];
00128 while(reader.getline(buffer, sizeof buffer))
00129 lheAlpgenUnwParHeader.addLine(std::string(buffer) + "\n");
00130
00131
00132
00133 if (!header.parse(lheAlpgenUnwParHeader.begin(),
00134 lheAlpgenUnwParHeader.end()))
00135 throw cms::Exception("Generator|AlpgenInterface")
00136 << "AlpgenSource was unable to parse the Alpgen "
00137 << "unweighted parameter file." << std::endl;
00138
00139
00140 produces<LHERunInfoProduct, edm::InRun>();
00141 produces<LHEEventProduct>();
00142 }
00143
00144 AlpgenSource::~AlpgenSource()
00145 {
00146 }
00147
00148 std::string AlpgenSource::slhaMassLine(int pdgId, AlpgenHeader::Masses mass,
00149 const std::string &comment) const
00150 {
00151 std::ostringstream ss;
00152 ss << std::setw(9) << pdgId << " " << std::scientific
00153 << std::setprecision(9) << header.masses[mass] << " # "
00154 << comment << std::endl;
00155 return ss.str();
00156 }
00157
00158 void AlpgenSource::beginRun(edm::Run &run)
00159 {
00160
00161
00162 lhef::HEPRUP heprup;
00163
00164
00165
00166 heprup.IDBMUP.first = 2212;
00167 switch(getParameter<int>(AlpgenHeader::ih2)) {
00168 case 1:
00169 heprup.IDBMUP.second = 2212;
00170 break;
00171 case -1:
00172 heprup.IDBMUP.second = -2212;
00173 break;
00174 default:
00175 throw cms::Exception("Generator|AlpgenInterface")
00176 << "AlpgenSource was unable to understand the ih2 "
00177 << "parameter." << std::endl;
00178 }
00179
00180
00181 heprup.EBMUP.second = heprup.EBMUP.first =
00182 getParameter<double>(AlpgenHeader::ebeam);
00183
00184
00185 heprup.PDFGUP.first = -1;
00186 heprup.PDFGUP.second = -1;
00187 heprup.PDFSUP.first = -1;
00188 heprup.PDFSUP.second = -1;
00189
00190
00191 heprup.IDWTUP = 3;
00192
00193
00194 heprup.resize(1);
00195
00196
00197 heprup.XSECUP[0] = header.xsec;
00198 heprup.XERRUP[0] = header.xsecErr;
00199
00200
00201 heprup.XMAXUP[0] = header.xsec;
00202
00203
00204 heprup.LPRUP[0] = processID();
00205
00206
00207 LHERunInfoProduct::Header comments;
00208 comments.addLine("\n");
00209 comments.addLine("\tExtracted by AlpgenInterface\n");
00210
00211
00212
00213 LHERunInfoProduct::Header slha("slha");
00214 slha.addLine("\n# SLHA header containing masses from Alpgen\n");
00215 slha.addLine("Block MASS # Mass spectrum (kinematic masses)\n");
00216 slha.addLine("# PDG Mass\n");
00217 slha.addLine(slhaMassLine(4, AlpgenHeader::mc, "charm pole mass"));
00218 slha.addLine(slhaMassLine(5, AlpgenHeader::mb, "bottom pole mass"));
00219 slha.addLine(slhaMassLine(6, AlpgenHeader::mt, "top pole mass"));
00220 slha.addLine(slhaMassLine(23, AlpgenHeader::mz, "Z mass"));
00221 slha.addLine(slhaMassLine(24, AlpgenHeader::mw, "W mass"));
00222 slha.addLine(slhaMassLine(25, AlpgenHeader::mh, "H mass"));
00223
00224 char buffer[512];
00225
00226
00227 LHERunInfoProduct::Header lheAlpgenWgtHeader("AlpgenWgtFile");
00228 if (writeAlpgenWgtFile) {
00229 std::ifstream wgtascii((fileName_+".wgt").c_str());
00230 while(wgtascii.getline(buffer,512)) {
00231 lheAlpgenWgtHeader.addLine(std::string(buffer) + "\n");
00232 }
00233 }
00234
00235 LHERunInfoProduct::Header lheAlpgenParHeader("AlpgenParFile");
00236 if (writeAlpgenParFile) {
00237 std::ifstream parascii((fileName_+".par").c_str());
00238 while(parascii.getline(buffer,512)) {
00239 lheAlpgenParHeader.addLine(std::string(buffer) + "\n");
00240 }
00241 }
00242
00243
00244
00245
00246 LHERunInfoProduct::Header extraHeader(extraHeaderName_.c_str());
00247 if(writeExtraHeader) {
00248 std::ifstream extraascii(extraHeaderFileName_.c_str());
00249 while(extraascii.getline(buffer,512)) {
00250 extraHeader.addLine(std::string(buffer) + "\n");
00251 }
00252 }
00253
00254
00255 std::auto_ptr<LHERunInfoProduct> runInfo(new LHERunInfoProduct(heprup));
00256 runInfo->addHeader(comments);
00257 runInfo->addHeader(lheAlpgenUnwParHeader);
00258 if (writeAlpgenWgtFile)
00259 runInfo->addHeader(lheAlpgenWgtHeader);
00260 if (writeAlpgenParFile)
00261 runInfo->addHeader(lheAlpgenParHeader);
00262 runInfo->addHeader(slha);
00263 if(writeExtraHeader)
00264 runInfo->addHeader(extraHeader);
00265 run.put(runInfo);
00266
00267
00268 inputFile_.reset(new std::ifstream((fileName_ + ".unw").c_str()));
00269 if (!inputFile_->good())
00270 throw cms::Exception("Generator|AlpgenInterface")
00271 << "AlpgenSource was unable to open the file \""
00272 << fileName_ << ".unw\"." << std::endl;
00273
00274 }
00275
00276 template<typename T>
00277 T AlpgenSource::getParameter(AlpgenHeader::Parameter index) const
00278 {
00279 std::map<AlpgenHeader::Parameter, double>::const_iterator pos =
00280 header.params.find(index);
00281 if (pos == header.params.end())
00282 throw cms::Exception("Generator|AlpgenInterface")
00283 << "Requested Alpgen parameter \""
00284 << AlpgenHeader::parameterName(index) << "\" "
00285 "not found in Alpgen parameter file." << std::endl;
00286
00287 return T(pos->second);
00288 }
00289
00290 template<typename T>
00291 T AlpgenSource::getParameter(AlpgenHeader::Parameter index,
00292 const T &defValue) const
00293 {
00294 std::map<AlpgenHeader::Parameter, double>::const_iterator pos =
00295 header.params.find(index);
00296 if (pos == header.params.end())
00297 return defValue;
00298 else
00299 return T(pos->second);
00300 }
00301
00302 unsigned int AlpgenSource::processID() const
00303 {
00304
00305
00306 return header.ihrd * 100 +
00307 getParameter<unsigned int>(AlpgenHeader::ihvy, 0) * 10 +
00308 getParameter<unsigned int>(AlpgenHeader::njets, 0);
00309 }
00310
00311 bool AlpgenSource::readAlpgenEvent(lhef::HEPEUP &hepeup)
00312 {
00313 char buffer[512];
00314 double dummy;
00315 int nPart;
00316 double sWgtRes;
00317 double sQ;
00318
00319 inputFile_->getline(buffer, sizeof buffer);
00320 if (!inputFile_->good())
00321 return false;
00322
00323 std::istringstream ls(buffer);
00324
00325
00326 ls >> dummy >> dummy;
00327
00328
00329 ls >> nPart >> sWgtRes >> sQ;
00330
00331 if (ls.bad() || nPart < 1 || nPart > 1000)
00332 return false;
00333
00334
00335 hepeup.resize(nPart);
00336
00337
00338 hepeup.SCALUP = sQ;
00339 hepeup.XWGTUP = sWgtRes;
00340 hepeup.IDPRUP = processID();
00341
00342
00343 for(int i = 0; i != 2; ++i) {
00344 inputFile_->getline(buffer, sizeof buffer);
00345 std::istringstream ls(buffer);
00346 int flavour; ls >> flavour;
00347 int colour1; ls >> colour1;
00348 int colour2; ls >> colour2;
00349 double zMomentum; ls >> zMomentum;
00350
00351 if (inputFile_->bad())
00352 return false;
00353
00354
00355 hepeup.IDUP[i] = flavour;
00356 hepeup.ISTUP[i] = -1;
00357 hepeup.MOTHUP[i].first = 0;
00358 hepeup.MOTHUP[i].second = 0;
00359 hepeup.PUP[i][0] = 0.;
00360 hepeup.PUP[i][1] = 0.;
00361 hepeup.PUP[i][2] = zMomentum;
00362 hepeup.PUP[i][3] = std::fabs(zMomentum);
00363 hepeup.PUP[i][4] = 0.;
00364 if (colour1) colour1 += 500;
00365 if (colour2) colour2 += 500;
00366 hepeup.ICOLUP[i].first = colour1;
00367 hepeup.ICOLUP[i].second = colour2;
00368 }
00369
00370
00371 for(int i = 2; i != nPart; ++i) {
00372 inputFile_->getline(buffer, sizeof buffer);
00373 std::istringstream ls(buffer);
00374 int flavour; ls >> flavour;
00375 int colour1; ls >> colour1;
00376 int colour2; ls >> colour2;
00377 double px, py, pz, mass;
00378 ls >> px >> py >> pz >> mass;
00379 double energy = std::sqrt(px*px + py*py + pz*pz + mass*mass);
00380
00381 if (inputFile_->bad())
00382 return false;
00383
00384
00385 hepeup.IDUP[i] = flavour;
00386 hepeup.ISTUP[i] = 1;
00387 hepeup.MOTHUP[i].first = 1;
00388 hepeup.MOTHUP[i].second = 2;
00389 hepeup.PUP[i][0] = px;
00390 hepeup.PUP[i][1] = py;
00391 hepeup.PUP[i][2] = pz;
00392 hepeup.PUP[i][3] = energy;
00393 hepeup.PUP[i][4] = mass;
00394 if (colour1) colour1 += 500;
00395 if (colour2) colour2 += 500;
00396 hepeup.ICOLUP[i].first = colour1;
00397 hepeup.ICOLUP[i].second = colour2;
00398 }
00399
00400 return true;
00401 }
00402
00403 bool AlpgenSource::produce(edm::Event &event)
00404 {
00405
00406 lhef::HEPEUP hepeup;
00407
00408
00409 for(;;) {
00410 if (!readAlpgenEvent(hepeup)) {
00411 if (inputFile_->eof())
00412 return false;
00413
00414 throw cms::Exception("Generator|AlpgenInterface")
00415 << "AlpgenSource is not able read event no. "
00416 << nEvent_ << std::endl;
00417 }
00418
00419 nEvent_++;
00420 if (skipEvents_ > 0)
00421 skipEvents_--;
00422 else
00423 break;
00424 }
00425
00426
00427
00428
00429
00430
00431 switch(header.ihrd) {
00432 case 1:
00433 case 2:
00434 case 3:
00435 case 4:
00436 case 10:
00437 case 14:
00438 case 15:
00439 alpgen::fixEventWZ(hepeup);
00440 break;
00441 case 5:
00442 alpgen::fixEventMultiBoson(hepeup);
00443 break;
00444 case 6:
00445 alpgen::fixEventTTbar(hepeup);
00446 break;
00447 case 8:
00448 alpgen::fixEventHiggsTTbar(hepeup);
00449 break;
00450 case 13:
00451 alpgen::fixEventSingleTop(hepeup, header.masses[AlpgenHeader::mb],
00452 int(header.params[AlpgenHeader::itopprc]));
00453 break;
00454 case 7:
00455 case 9:
00456 case 11:
00457 case 12:
00458 case 16:
00459
00460 break;
00461
00462 default:
00463 throw cms::Exception("Generator|AlpgenInterface")
00464 << "Unrecognized IHRD process code" << std::endl;
00465 }
00466
00467
00468 std::auto_ptr<LHEEventProduct> lheEvent(new LHEEventProduct(hepeup));
00469 event.put(lheEvent);
00470
00471 return true;
00472 }
00473
00474 DEFINE_FWK_INPUT_SOURCE(AlpgenSource);