CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
AlpgenSource.cc
Go to the documentation of this file.
1 #include <iostream>
2 #include <iomanip>
3 #include <sstream>
4 #include <fstream>
5 #include <string>
6 #include <memory>
7 #include <cmath>
8 
9 #include <boost/algorithm/string/classification.hpp>
10 #include <boost/algorithm/string/split.hpp>
11 
20 
25 
28 
30 public:
32  AlpgenSource(const edm::ParameterSet &params,
33  const edm::InputSourceDescription &desc);
34 
36  virtual ~AlpgenSource();
37 
38 private:
39  virtual bool produce(edm::Event &event);
40  virtual void beginRun(edm::Run &run);
41 
43  template<typename T>
46  template<typename T>
47  T getParameter(AlpgenHeader::Parameter index, const T &defValue) const;
48 
52  const std::string &comment) const;
53 
57  unsigned int processID() const;
58 
60  bool readAlpgenEvent(lhef::HEPEUP &hepeup);
61 
63  std::string fileName_;
64 
66  std::auto_ptr<std::ifstream> inputFile_;
67 
69  unsigned long skipEvents_;
70 
72  unsigned long nEvent_;
73 
78 
80  std::string extraHeaderFileName_;
81 
83  std::string extraHeaderName_;
84 
89 };
90 
92  const edm::InputSourceDescription &desc) :
93  edm::ExternalInputSource(params, desc, false),
94  skipEvents_(params.getUntrackedParameter<unsigned int>("skipEvents", 0)),
95  nEvent_(0), lheAlpgenUnwParHeader("AlpgenUnwParFile"),
96  extraHeaderFileName_(params.getUntrackedParameter<std::string>("extraHeaderFileName","")),
97  extraHeaderName_(params.getUntrackedParameter<std::string>("extraHeaderName","")),
98  writeAlpgenWgtFile(params.getUntrackedParameter<bool>("writeAlpgenWgtFile", true)),
99  writeAlpgenParFile(params.getUntrackedParameter<bool>("writeAlpgenParFile", true)),
100  writeExtraHeader(params.getUntrackedParameter<bool>("writeExtraHeader", false))
101 {
102  std::vector<std::string> allFileNames = fileNames();
103 
104  // Only one filename
105  if (allFileNames.size() != 1)
106  throw cms::Exception("Generator|AlpgenInterface")
107  << "AlpgenSource needs exactly one file specified "
108  "for now." << std::endl;
109 
110  fileName_ = allFileNames[0];
111 
112  // Strip the "file:" prefix
113  if (fileName_.find("file:") != 0)
114  throw cms::Exception("Generator|AlpgenInterface") << "AlpgenSource only supports the file: scheme "
115  "for now." << std::endl;
116  fileName_.erase(0, 5);
117 
118  // Open the _unw.par file to store additional
119  // informations in the LHERunInfoProduct
120  std::ifstream reader((fileName_ + "_unw.par").c_str());
121  if (!reader.good())
122  throw cms::Exception("Generator|AlpgenInterface")
123  << "AlpgenSource was unable to open the file \""
124  << fileName_ << "_unw.par\"." << std::endl;
125 
126  // A full copy of the _unw.par file in the LHE header.
127  char buffer[256];
128  while(reader.getline(buffer, sizeof buffer))
129  lheAlpgenUnwParHeader.addLine(std::string(buffer) + "\n");
130 
131  // Parse that header to setup an Alpgen header,
132  // which will be used in the production itself.
135  throw cms::Exception("Generator|AlpgenInterface")
136  << "AlpgenSource was unable to parse the Alpgen "
137  << "unweighted parameter file." << std::endl;
138 
139  // Declare the products.
140  produces<LHERunInfoProduct, edm::InRun>();
141  produces<LHEEventProduct>();
142 }
143 
145 {
146 }
147 
149  const std::string &comment) const
150 {
151  std::ostringstream ss;
152  ss << std::setw(9) << pdgId << " " << std::scientific
153  << std::setprecision(9) << header.masses[mass] << " # "
154  << comment << std::endl;
155  return ss.str();
156 }
157 
159 {
160  // At this point, the lheUnwParHeader has the full contents of the _unw.par
161  // file. So we can get the HEPRUP information from the LHE header itself.
162  lhef::HEPRUP heprup;
163 
164  // Get basic run information.
165  // Beam identity.
166  heprup.IDBMUP.first = 2212;
167  switch(getParameter<int>(AlpgenHeader::ih2)) {
168  case 1:
169  heprup.IDBMUP.second = 2212;
170  break;
171  case -1:
172  heprup.IDBMUP.second = -2212;
173  break;
174  default:
175  throw cms::Exception("Generator|AlpgenInterface")
176  << "AlpgenSource was unable to understand the ih2 "
177  << "parameter." << std::endl;
178  }
179 
180  // Beam energy.
181  heprup.EBMUP.second = heprup.EBMUP.first =
182  getParameter<double>(AlpgenHeader::ebeam);
183 
184  // PDF info. Initially, Alpgen doesn't fill it.
185  heprup.PDFGUP.first = -1;
186  heprup.PDFGUP.second = -1;
187  heprup.PDFSUP.first = -1;
188  heprup.PDFSUP.second = -1;
189 
190  // Unweighted events.
191  heprup.IDWTUP = 3;
192 
193  // Only one process.
194  heprup.resize(1);
195 
196  // Cross section and error.
197  heprup.XSECUP[0] = header.xsec;
198  heprup.XERRUP[0] = header.xsecErr;
199 
200  // Maximum weight.
201  heprup.XMAXUP[0] = header.xsec;
202 
203  // Process code for Pythia.
204  heprup.LPRUP[0] = processID();
205 
206  // Comments on top.
208  comments.addLine("\n");
209  comments.addLine("\tExtracted by AlpgenInterface\n");
210 
211  // Add SLHA header containing particle masses from Alpgen.
212  // Pythia6Hadronisation will feed the masses to Pythia automatically.
213  LHERunInfoProduct::Header slha("slha");
214  slha.addLine("\n# SLHA header containing masses from Alpgen\n");
215  slha.addLine("Block MASS # Mass spectrum (kinematic masses)\n");
216  slha.addLine("# PDG Mass\n");
217  slha.addLine(slhaMassLine(4, AlpgenHeader::mc, "charm pole mass"));
218  slha.addLine(slhaMassLine(5, AlpgenHeader::mb, "bottom pole mass"));
219  slha.addLine(slhaMassLine(6, AlpgenHeader::mt, "top pole mass"));
220  slha.addLine(slhaMassLine(23, AlpgenHeader::mz, "Z mass"));
221  slha.addLine(slhaMassLine(24, AlpgenHeader::mw, "W mass"));
222  slha.addLine(slhaMassLine(25, AlpgenHeader::mh, "H mass"));
223 
224  char buffer[512];
225 
226  // We also add the information on weighted events.
227  LHERunInfoProduct::Header lheAlpgenWgtHeader("AlpgenWgtFile");
228  if (writeAlpgenWgtFile) {
229  std::ifstream wgtascii((fileName_+".wgt").c_str());
230  while(wgtascii.getline(buffer,512)) {
231  lheAlpgenWgtHeader.addLine(std::string(buffer) + "\n");
232  }
233  }
234 
235  LHERunInfoProduct::Header lheAlpgenParHeader("AlpgenParFile");
236  if (writeAlpgenParFile) {
237  std::ifstream parascii((fileName_+".par").c_str());
238  while(parascii.getline(buffer,512)) {
239  lheAlpgenParHeader.addLine(std::string(buffer) + "\n");
240  }
241  }
242 
243  // If requested by the user, we also add any specific header provided.
244  // Nota bene: the header is put in the LHERunInfoProduct AS IT WAS GIVEN.
245  // That means NO CROSS-CHECKS WHATSOEVER. Use with care.
246  LHERunInfoProduct::Header extraHeader(extraHeaderName_.c_str());
247  if(writeExtraHeader) {
248  std::ifstream extraascii(extraHeaderFileName_.c_str());
249  while(extraascii.getline(buffer,512)) {
250  extraHeader.addLine(std::string(buffer) + "\n");
251  }
252  }
253 
254  // Build the final Run info object. Backwards-compatible order.
255  std::auto_ptr<LHERunInfoProduct> runInfo(new LHERunInfoProduct(heprup));
256  runInfo->addHeader(comments);
257  runInfo->addHeader(lheAlpgenUnwParHeader);
258  if (writeAlpgenWgtFile)
259  runInfo->addHeader(lheAlpgenWgtHeader);
260  if (writeAlpgenParFile)
261  runInfo->addHeader(lheAlpgenParHeader);
262  runInfo->addHeader(slha);
263  if(writeExtraHeader)
264  runInfo->addHeader(extraHeader);
265  run.put(runInfo);
266 
267  // Open the .unw file in the heap, and set the global pointer to it.
268  inputFile_.reset(new std::ifstream((fileName_ + ".unw").c_str()));
269  if (!inputFile_->good())
270  throw cms::Exception("Generator|AlpgenInterface")
271  << "AlpgenSource was unable to open the file \""
272  << fileName_ << ".unw\"." << std::endl;
273 
274 }
275 
276 template<typename T>
278 {
279  std::map<AlpgenHeader::Parameter, double>::const_iterator pos =
280  header.params.find(index);
281  if (pos == header.params.end())
282  throw cms::Exception("Generator|AlpgenInterface")
283  << "Requested Alpgen parameter \""
284  << AlpgenHeader::parameterName(index) << "\" "
285  "not found in Alpgen parameter file." << std::endl;
286 
287  return T(pos->second);
288 }
289 
290 template<typename T>
292  const T &defValue) const
293 {
294  std::map<AlpgenHeader::Parameter, double>::const_iterator pos =
295  header.params.find(index);
296  if (pos == header.params.end())
297  return defValue;
298  else
299  return T(pos->second);
300 }
301 
302 unsigned int AlpgenSource::processID() const
303 {
304  // return 661; // The original, old thing.
305  // digits #XYZ: X = ihrd, Y = ihvy, Z = njets
306  return header.ihrd * 100 +
307  getParameter<unsigned int>(AlpgenHeader::ihvy, 0) * 10 +
308  getParameter<unsigned int>(AlpgenHeader::njets, 0);
309 }
310 
312 {
313  char buffer[512];
314  double dummy;
315  int nPart;
316  double sWgtRes;
317  double sQ;
318 
319  inputFile_->getline(buffer, sizeof buffer);
320  if (!inputFile_->good())
321  return false;
322 
323  std::istringstream ls(buffer);
324 
325  // Event number and process don't matter (or do they?)
326  ls >> dummy >> dummy;
327 
328  // Number of particles in the record, sample's average weight and Q scale
329  ls >> nPart >> sWgtRes >> sQ;
330 
331  if (ls.bad() || nPart < 1 || nPart > 1000)
332  return false;
333 
334  // Make room for the particles listed in the Alpgen file
335  hepeup.resize(nPart);
336 
337  // Scales, weights and process ID.
338  hepeup.SCALUP = sQ;
339  hepeup.XWGTUP = sWgtRes;
340  hepeup.IDPRUP = processID();
341 
342  // Incoming lines
343  for(int i = 0; i != 2; ++i) {
344  inputFile_->getline(buffer, sizeof buffer);
345  std::istringstream ls(buffer);
346  int flavour; ls >> flavour;
347  int colour1; ls >> colour1;
348  int colour2; ls >> colour2;
349  double zMomentum; ls >> zMomentum;
350 
351  if (inputFile_->bad())
352  return false;
353 
354  // Setting the HEPEUP of the incoming lines.
355  hepeup.IDUP[i] = flavour;
356  hepeup.ISTUP[i] = -1;
357  hepeup.MOTHUP[i].first = 0;
358  hepeup.MOTHUP[i].second = 0;
359  hepeup.PUP[i][0] = 0.;
360  hepeup.PUP[i][1] = 0.;
361  hepeup.PUP[i][2] = zMomentum;
362  hepeup.PUP[i][3] = std::fabs(zMomentum);
363  hepeup.PUP[i][4] = 0.;
364  if (colour1) colour1 += 500;
365  if (colour2) colour2 += 500;
366  hepeup.ICOLUP[i].first = colour1;
367  hepeup.ICOLUP[i].second = colour2;
368  }
369 
370  // Outgoing lines
371  for(int i = 2; i != nPart; ++i) {
372  inputFile_->getline(buffer, sizeof buffer);
373  std::istringstream ls(buffer);
374  int flavour; ls >> flavour;
375  int colour1; ls >> colour1;
376  int colour2; ls >> colour2;
377  double px, py, pz, mass;
378  ls >> px >> py >> pz >> mass;
379  double energy = std::sqrt(px*px + py*py + pz*pz + mass*mass);
380 
381  if (inputFile_->bad())
382  return false;
383 
384  // Setting the HEPEUP of the outgoing lines.
385  hepeup.IDUP[i] = flavour;
386  hepeup.ISTUP[i] = 1;
387  hepeup.MOTHUP[i].first = 1;
388  hepeup.MOTHUP[i].second = 2;
389  hepeup.PUP[i][0] = px;
390  hepeup.PUP[i][1] = py;
391  hepeup.PUP[i][2] = pz;
392  hepeup.PUP[i][3] = energy;
393  hepeup.PUP[i][4] = mass;
394  if (colour1) colour1 += 500;
395  if (colour2) colour2 += 500;
396  hepeup.ICOLUP[i].first = colour1;
397  hepeup.ICOLUP[i].second = colour2;
398  }
399 
400  return true;
401 }
402 
404 {
405  // The LHE Event Record
406  lhef::HEPEUP hepeup;
407 
408  // Read the .unw file until it is over.
409  for(;;) {
410  if (!readAlpgenEvent(hepeup)) {
411  if (inputFile_->eof())
412  return false;
413 
414  throw cms::Exception("Generator|AlpgenInterface")
415  << "AlpgenSource is not able read event no. "
416  << nEvent_ << std::endl;
417  }
418 
419  nEvent_++;
420  if (skipEvents_ > 0)
421  skipEvents_--;
422  else
423  break;
424  }
425 
426  // Here are the Alpgen routines for filling up the rest
427  // of the LHE Event Record. The .unw file has the information
428  // in a compressed way, e.g. it doesn't list the W boson -
429  // one has to reconstruct it from the e nu pair.
430 
431  switch(header.ihrd) {
432  case 1:
433  case 2:
434  case 3:
435  case 4:
436  case 10:
437  case 14:
438  case 15:
439  alpgen::fixEventWZ(hepeup);
440  break;
441  case 5:
443  break;
444  case 6:
445  alpgen::fixEventTTbar(hepeup);
446  break;
447  case 8:
449  break;
450  case 13:
453  break;
454  case 7:
455  case 9:
456  case 11:
457  case 12:
458  case 16:
459  // No fixes needed.
460  break;
461 
462  default:
463  throw cms::Exception("Generator|AlpgenInterface")
464  << "Unrecognized IHRD process code" << std::endl;
465  }
466 
467  // Create the LHEEventProduct and put it into the Event.
468  std::auto_ptr<LHEEventProduct> lheEvent(new LHEEventProduct(hepeup));
469  event.put(lheEvent);
470 
471  return true;
472 }
473 
int i
Definition: DBlmapReader.cc:9
virtual ~AlpgenSource()
Destructor.
void resize(int nrup)
Definition: LesHouches.h:52
std::map< Parameter, double > params
Definition: AlpgenHeader.h:67
AlpgenSource(const edm::ParameterSet &params, const edm::InputSourceDescription &desc)
Constructor.
Definition: AlpgenSource.cc:91
virtual void beginRun(edm::Run &run)
bool parse(const std::vector< std::string >::const_iterator &begin, const std::vector< std::string >::const_iterator &end)
Definition: AlpgenHeader.cc:67
std::pair< double, double > EBMUP
Definition: LesHouches.h:78
AlpgenHeader header
Alpgen _unw.par file as an AlpgenHeader.
Definition: AlpgenSource.cc:77
std::pair< int, int > IDBMUP
Definition: LesHouches.h:73
virtual bool produce(edm::Event &event)
static std::string parameterName(Parameter index)
const_iterator end() const
bool writeAlpgenParFile
Definition: AlpgenSource.cc:87
bool writeExtraHeader
Definition: AlpgenSource.cc:88
unsigned long nEvent_
Number of events.
Definition: AlpgenSource.cc:72
unsigned long skipEvents_
Number of events to skip.
Definition: AlpgenSource.cc:69
std::pair< int, int > PDFGUP
Definition: LesHouches.h:84
bool writeAlpgenWgtFile
configuration flags
Definition: AlpgenSource.cc:86
void fixEventWZ(lhef::HEPEUP &hepeup)
Fixes Event Record for ihrd = 1,2,3,4,10,14,15.
std::vector< std::pair< int, int > > MOTHUP
Definition: LesHouches.h:236
LHERunInfoProduct::Header lheAlpgenUnwParHeader
Alpgen _unw.par file as a LHE header.
Definition: AlpgenSource.cc:75
void fixEventMultiBoson(lhef::HEPEUP &hepeup)
Fixes Event Record for ihrd = 5.
#define DEFINE_FWK_INPUT_SOURCE(type)
void fixEventHiggsTTbar(lhef::HEPEUP &hepeup)
Fixes Event Record for ihrd = 8.
void resize(int nup)
Definition: LesHouches.h:161
std::string extraHeaderFileName_
Name of the extra header file.
Definition: AlpgenSource.cc:80
T sqrt(T t)
Definition: SSEVec.h:46
std::vector< FiveVector > PUP
Definition: LesHouches.h:248
void addLine(const std::string &line)
std::vector< int > ISTUP
Definition: LesHouches.h:230
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger but the state exists so we define the behavior If all triggers are the negative crieriion will lead to accepting the event(this again matches the behavior of"!*"before the partial wildcard feature was incorporated).The per-event"cost"of each negative criterion with multiple relevant triggers is about the same as!*was in the past
std::vector< int > IDUP
Definition: LesHouches.h:225
std::vector< double > XERRUP
Definition: LesHouches.h:114
std::string fileName_
Name of the input file.
Definition: AlpgenSource.cc:63
std::vector< double > XMAXUP
Definition: LesHouches.h:119
TString nPart(Int_t part, TString string, TString delimit=";", Bool_t removerest=true)
std::string slhaMassLine(int pdgId, AlpgenHeader::Masses mass, const std::string &comment) const
std::string extraHeaderName_
Name given to the extra header.
Definition: AlpgenSource.cc:83
void fixEventSingleTop(lhef::HEPEUP &hepeup, double mb, int itopprc)
Fixes Event Record for ihrd = 13.
std::pair< int, int > PDFSUP
Definition: LesHouches.h:90
unsigned int ihrd
Definition: AlpgenHeader.h:68
T getParameter(AlpgenHeader::Parameter index) const
Function to get parameter by name from AlpgenHeader.
tuple mass
Definition: scaleCards.py:27
std::auto_ptr< std::ifstream > inputFile_
Pointer to the input file.
Definition: AlpgenSource.cc:66
double xsecErr
Definition: AlpgenHeader.h:70
void put(std::auto_ptr< PROD > product)
Put a new product.
Definition: Run.h:81
void fixEventTTbar(lhef::HEPEUP &hepeup)
Fixes Event Record for ihrd = 6.
std::vector< double > XSECUP
Definition: LesHouches.h:108
long double T
std::vector< std::string > const & fileNames() const
int flavour(const Candidate &part)
Definition: pdgIdUtils.h:31
double XWGTUP
Definition: LesHouches.h:196
double masses[MASS_MAX]
Definition: AlpgenHeader.h:73
bool readAlpgenEvent(lhef::HEPEUP &hepeup)
Read an event and put it into the HEPEUP.
std::vector< std::pair< int, int > > ICOLUP
Definition: LesHouches.h:242
const_iterator begin() const
Definition: Run.h:33
std::vector< int > LPRUP
Definition: LesHouches.h:124
double SCALUP
Definition: LesHouches.h:210
unsigned int processID() const
#define comment(par)
Definition: vmac.h:162