CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
LHEReader.cc
Go to the documentation of this file.
1 #include <algorithm>
2 #include <iomanip>
3 #include <iostream>
4 #include <sstream>
5 #include <fstream>
6 #include <cstring>
7 #include <string>
8 #include <vector>
9 #include <cstdio>
10 
11 #include <boost/bind.hpp>
12 
13 #include <xercesc/sax2/Attributes.hpp>
14 #include <xercesc/dom/DOM.hpp>
15 
20 
24 
28 
29 #include "XMLUtils.h"
30 
31 #include "boost/lexical_cast.hpp"
32 
33 XERCES_CPP_NAMESPACE_USE
34 
35 namespace lhef {
36 
37  static void logFileAction(char const* msg, std::string const& fileName) {
38  edm::LogAbsolute("fileAction") << std::setprecision(0) << edm::TimeOfDay() << msg << fileName;
40  }
41 
42 
44  public:
45  Source() {}
46  virtual ~Source() {}
48 };
49 
51  public:
52  FileSource(const std::string &fileURL)
53  {
54  Storage *storage =
55  StorageFactory::get()->open(fileURL,
57 
58  if (!storage)
59  throw cms::Exception("FileOpenError")
60  << "Could not open LHE file \""
61  << fileURL << "\" for reading"
62  << std::endl;
63 
64  fileStream.reset(new StorageWrap(storage));
65  }
66 
68 
70  { return new XMLDocument(fileStream, handler); }
71 
72  private:
73  std::auto_ptr<StorageWrap> fileStream;
74 };
75 
77  public:
79  {
80  if (inputs == "")
81  throw cms::Exception("StreamOpenError")
82  << "Empty LHE file string name \""
83  << std::endl;
84 
85  std::stringstream * tmpis = new std::stringstream(inputs);
86  fileStream.reset(tmpis);
87  }
88 
90 
92  { return new XMLDocument(fileStream, handler); }
93 
94  private:
95  std::auto_ptr<std::istream> fileStream;
96 };
97 
99  public:
100  typedef std::vector<std::pair<std::string,std::string> > wgt_info;
102  impl(0), gotObject(kNone), mode(kNone),
103  xmlHeader(0), xmlEvent(0), headerOk(false), npLO(-99), npNLO(-99) {}
105  { if (xmlHeader) xmlHeader->release();
106  if (xmlEvent) xmlEvent->release(); }
107 
108  enum Object {
109  kNone = 0,
114  };
115 
116  void reset() { headerOk = false; weightsinevent.clear();}
117 
118  const wgt_info& weightInfo() const {return weightsinevent;}
119 
120  protected:
121  void startElement(const XMLCh *const uri,
122  const XMLCh *const localname,
123  const XMLCh *const qname,
124  const Attributes &attributes) override;
125 
126  void endElement(const XMLCh *const uri,
127  const XMLCh *const localname,
128  const XMLCh *const qname) override;
129 
130  void characters(const XMLCh *const data, const unsigned int length) override;
131  void comment(const XMLCh *const data, const unsigned int length) override;
132 
133  private:
134  friend class LHEReader;
135 
136  DOMImplementation *impl;
140  DOMDocument *xmlHeader;
141  DOMDocument *xmlEvent;
142  std::vector<DOMElement*> xmlNodes,xmlEventNodes;
143  bool headerOk;
144  std::vector<LHERunInfo::Header> headers;
146  int npLO;
147  int npNLO;
148  std::vector<float> scales;
149 };
150 
151 static void attributesToDom(DOMElement *dom, const Attributes &attributes)
152 {
153  for(unsigned int i = 0; i < attributes.getLength(); i++) {
154  const XMLCh *name = attributes.getQName(i);
155  const XMLCh *value = attributes.getValue(i);
156 
157  dom->setAttribute(name, value);
158  }
159 }
160 
161 static void fillHeader(LHERunInfo::Header &header, const char *data,
162  int len = -1)
163 {
164  const char *end = len >= 0 ? (data + len) : 0;
165  while(*data && (!end || data < end)) {
166  std::size_t len = std::strcspn(data, "\r\n");
167  if (end && data + len > end)
168  len = end - data;
169  if (data[len] == '\r' && data[len + 1] == '\n')
170  len += 2;
171  else if (data[len])
172  len++;
173  header.addLine(std::string(data, len));
174  data += len;
175  }
176 }
177 
178 void LHEReader::XMLHandler::startElement(const XMLCh *const uri,
179  const XMLCh *const localname,
180  const XMLCh *const qname,
181  const Attributes &attributes)
182 {
183  std::string name((const char*)XMLSimpleStr(qname));
184 
185  if (!headerOk) {
186  if (name != "LesHouchesEvents")
187  throw cms::Exception("InvalidFormat")
188  << "LHE file has invalid header" << std::endl;
189  headerOk = true;
190  return;
191  }
192 
193  if (mode == kHeader) {
194  DOMElement *elem = xmlHeader->createElement(qname);
195  attributesToDom(elem, attributes);
196  xmlNodes.back()->appendChild(elem);
197  xmlNodes.push_back(elem);
198  return;
199  } else if ( mode == kEvent ) {
200  DOMElement *elem = xmlEvent->createElement(qname);
201  attributesToDom(elem, attributes);
202 
203  //TODO this is a hack (even more than the rest of this class)
204  if( name == "rwgt" ) {
205  xmlEventNodes[0]->appendChild(elem);
206  } else if (name == "wgt") {
207  xmlEventNodes[1]->appendChild(elem);
208  }
209  else if (name == "scales") {
210  for (XMLSize_t iscale=0; iscale<attributes.getLength(); ++iscale) {
211  int ipart = 0;
212  const char *scalename = XMLSimpleStr(attributes.getQName(iscale));
213  int nmatch = sscanf(scalename,"pt_clust_%d",&ipart);
214 
215  if (nmatch!=1) {
216  edm::LogError("Generator|LHEInterface")
217  << "invalid attribute in <scales> tag"
218  << std::endl;
219  }
220 
221  float scaleval;
222  const char *scalevalstr = XMLSimpleStr(attributes.getValue(iscale));
223  sscanf(scalevalstr,"%e",&scaleval);
224 
225  scales.push_back(scaleval);
226  }
227  }
228  xmlEventNodes.push_back(elem);
229  return;
230  } else if (mode == kInit) {
231  //skip unknown tags in init block as well
232  return;
233  } else if (mode != kNone) {
234  throw cms::Exception("InvalidFormat")
235  << "LHE file has invalid format" << std::endl;
236  }
237 
238  if (name == "header") {
239  if (!impl)
240  impl = DOMImplementationRegistry::getDOMImplementation(
241  XMLUniStr("Core"));
242  xmlHeader = impl->createDocument(0, qname, 0);
243  xmlNodes.resize(1);
244  xmlNodes[0] = xmlHeader->getDocumentElement();
245  mode = kHeader;
246  } if (name == "init") {
247  mode = kInit;
248  } else if (name == "event") {
249  if (!impl)
250  impl = DOMImplementationRegistry::getDOMImplementation(
251  XMLUniStr("Core"));
252  if(xmlEvent) xmlEvent->release();
253  xmlEvent = impl->createDocument(0, qname, 0);
254  weightsinevent.resize(0);
255  scales.clear();
256 
257  npLO = -99;
258  npNLO = -99;
259  const XMLCh *npLOval = attributes.getValue(XMLString::transcode("npLO"));
260  if (npLOval) {
261  const char *npLOs = XMLSimpleStr(npLOval);
262  sscanf(npLOs,"%d",&npLO);
263  }
264  const XMLCh *npNLOval = attributes.getValue(XMLString::transcode("npNLO"));
265  if (npNLOval) {
266  const char *npNLOs = XMLSimpleStr(npNLOval);
267  sscanf(npNLOs,"%d",&npNLO);
268  }
269 
270  xmlEventNodes.resize(1);
271  xmlEventNodes[0] = xmlEvent->getDocumentElement();
272  mode = kEvent;
273  }
274 
275  if (mode == kNone)
276  throw cms::Exception("InvalidFormat")
277  << "LHE file has invalid format" << std::endl;
278 
279  buffer.clear();
280 }
281 
282 void LHEReader::XMLHandler::endElement(const XMLCh *const uri,
283  const XMLCh *const localname,
284  const XMLCh *const qname)
285 {
286  std::string name((const char*)XMLSimpleStr(qname));
287 
288  if (mode) {
289 
290  if (mode == kHeader && xmlNodes.size() > 1) {
291  xmlNodes.resize(xmlNodes.size() - 1);
292  return;
293  } else if (mode == kHeader) {
294  std::auto_ptr<DOMWriter> writer(
295  static_cast<DOMImplementationLS*>(
296  impl)->createDOMWriter());
297  writer->setEncoding(XMLUniStr("UTF-8"));
298 
299  for(DOMNode *node = xmlNodes[0]->getFirstChild();
300  node; node = node->getNextSibling()) {
301  XMLSimpleStr buffer(writer->writeToString(*node));
302 
304  const char *p, *q;
305  DOMElement *elem;
306 
307  switch(node->getNodeType()) {
308  case DOMNode::ELEMENT_NODE:
309  elem = static_cast<DOMElement*>(node);
310  type = (const char*)XMLSimpleStr(
311  elem->getTagName());
312  p = std::strchr((const char*)buffer,
313  '>') + 1;
314  q = std::strrchr(p, '<');
315  break;
316  case DOMNode::COMMENT_NODE:
317  type = "";
318  p = buffer + 4;
319  q = buffer + strlen(buffer) - 3;
320  break;
321  default:
322  type = "<>";
323  p = buffer +
324  std::strspn(buffer, " \t\r\n");
325  if (!*p)
326  continue;
327  q = p + strlen(p);
328  }
329  LHERunInfo::Header header(type);
330  fillHeader(header, p, q - p);
331  headers.push_back(header);
332  }
333 
334  xmlHeader->release();
335  xmlHeader = 0;
336  }
337  else if (name == "event" &&
338  mode == kEvent &&
339  xmlEventNodes.size() >= 1) { // handling of weights in LHE file
340  for(DOMNode *node = xmlEventNodes[0]->getFirstChild();
341  node; node = node->getNextSibling()) {
342  switch( node->getNodeType() ) {
343  case DOMNode::ELEMENT_NODE: // rwgt
344  for(DOMNode *rwgt = xmlEventNodes[1]->getFirstChild();
345  rwgt; rwgt = rwgt->getNextSibling()) {
346  DOMNode* attr = rwgt->getAttributes()->item(0);
347  XMLSimpleStr atname(attr->getNodeValue());
348  XMLSimpleStr weight(rwgt->getFirstChild()->getNodeValue());
349  switch( rwgt->getNodeType() ) {
350  case DOMNode::ELEMENT_NODE:
351  weightsinevent.push_back(std::make_pair((const char*)atname,
352  (const char*)weight));
353  break;
354  default:
355  break;
356  }
357  }
358  break;
359  case DOMNode::TEXT_NODE: // event information
360  {
361  XMLSimpleStr data(node->getNodeValue());
362  buffer.append(data);
363  }
364  break;
365  default:
366  break;
367  }
368  }
369  }
370  else if (mode == kEvent) {
371  //skip unknown tags
372  return;
373  }
374 
375  if (gotObject != kNone)
376  throw cms::Exception("InvalidState")
377  << "Unexpected pileup in"
378  " LHEReader::XMLHandler::endElement"
379  << std::endl;
380 
381  gotObject = mode;
382  mode = kNone;
383  }
384 }
385 
386 void LHEReader::XMLHandler::characters(const XMLCh *const data_,
387  const unsigned int length)
388 {
389  if (mode == kHeader) {
390  DOMText *text = xmlHeader->createTextNode(data_);
391  xmlNodes.back()->appendChild(text);
392  return;
393  }
394 
395  if (XMLSimpleStr::isAllSpaces(data_, length))
396  return;
397 
398  unsigned int offset = 0;
399  while(offset < length && XMLSimpleStr::isSpace(data_[offset]))
400  offset++;
401 
402  if( mode == kEvent ) {
403  DOMText *text = xmlEvent->createTextNode(data_+offset);
404  xmlEventNodes.back()->appendChild(text);
405  return;
406  }
407 
408  if (mode == kNone)
409  throw cms::Exception("InvalidFormat")
410  << "LHE file has invalid format" << std::endl;
411 
412  XMLSimpleStr data(data_ + offset);
413  buffer.append(data);
414 }
415 
416 void LHEReader::XMLHandler::comment(const XMLCh *const data_,
417  const unsigned int length)
418 {
419  if (mode == kHeader) {
420  DOMComment *comment = xmlHeader->createComment(data_);
421  xmlNodes.back()->appendChild(comment);
422  return;
423  }
424 
425  XMLSimpleStr data(data_);
426 
427  LHERunInfo::Header header;
428  fillHeader(header, data);
429  headers.push_back(header);
430 }
431 
433  fileURLs(params.getUntrackedParameter< std::vector<std::string> >("fileNames")),
434  strName(""),
435  firstEvent(params.getUntrackedParameter<unsigned int>("skipEvents", 0)),
436  maxEvents(params.getUntrackedParameter<int>("limitEvents", -1)),
437  curIndex(0), handler(new XMLHandler())
438 {
439 }
440 
441 LHEReader::LHEReader(const std::vector<std::string> &fileNames,
442  unsigned int firstEvent) :
443  fileURLs(fileNames), strName(""), firstEvent(firstEvent), maxEvents(-1),
444  curIndex(0), handler(new XMLHandler())
445 {
446 }
447 
449  unsigned int firstEvent) :
450  strName(inputs), firstEvent(firstEvent), maxEvents(-1),
451  curIndex(0), handler(new XMLHandler())
452 {
453 }
454 
456 {
457 }
458 
459  boost::shared_ptr<LHEEvent> LHEReader::next(bool* newFileOpened)
460  {
461  while(curDoc.get() || curIndex < fileURLs.size() || (fileURLs.size() == 0 && strName != "" ) ) {
462  if (!curDoc.get()) {
463  if ( fileURLs.size() > 0 ) {
464  logFileAction(" Initiating request to open LHE file ", fileURLs[curIndex]);
465  curSource.reset(new FileSource(fileURLs[curIndex]));
466  logFileAction(" Successfully opened LHE file ", fileURLs[curIndex]);
467  if ( newFileOpened != nullptr ) *newFileOpened = true;
468  ++curIndex;
469  } else if ( strName != "" ) {
470  curSource.reset(new StringSource(strName));
471  }
472  handler->reset();
473  curDoc.reset(curSource->createReader(*handler));
474  curRunInfo.reset();
475  }
476 
477  XMLHandler::Object event = handler->gotObject;
478  handler->gotObject = XMLHandler::kNone;
479 
480  std::istringstream data;
481  if (event != XMLHandler::kNone) {
482  data.str(handler->buffer);
483  handler->buffer.clear();
484  }
485 
486  switch(event) {
487  case XMLHandler::kNone:
488  if (!curDoc->parse()) {
489  curDoc.reset();
490  logFileAction(" Closed LHE file ", fileURLs[curIndex - 1]);
491  return boost::shared_ptr<LHEEvent>();
492  }
493  break;
494 
495  case XMLHandler::kHeader:
496  break;
497 
498  case XMLHandler::kInit:
499  curRunInfo.reset(new LHERunInfo(data));
500 
501  std::for_each(handler->headers.begin(),
502  handler->headers.end(),
503  boost::bind(&LHERunInfo::addHeader,
504  curRunInfo.get(), _1));
505  handler->headers.clear();
506  break;
507 
509  break;
510 
511  case XMLHandler::kEvent:
512  if (!curRunInfo.get())
513  throw cms::Exception("InvalidState")
514  << "Got LHE event without"
515  " initialization." << std::endl;
516 
517  if (firstEvent > 0) {
518  firstEvent--;
519  continue;
520  }
521 
522  if (maxEvents == 0)
523  return boost::shared_ptr<LHEEvent>();
524  else if (maxEvents > 0)
525  maxEvents--;
526 
527  boost::shared_ptr<LHEEvent> lheevent;
528  lheevent.reset(new LHEEvent(curRunInfo, data));
529  const XMLHandler::wgt_info& info = handler->weightsinevent;
530  for( size_t i=0; i< info.size(); ++i ) {
531  double num = -1.0;
532  sscanf(info[i].second.c_str(),"%le",&num);
533  lheevent->addWeight(gen::WeightsInfo(info[i].first,num));
534  }
535  lheevent->setNpLO(handler->npLO);
536  lheevent->setNpNLO(handler->npNLO);
537  //fill scales
538  if (handler->scales.size()>0) {
539  lheevent->setScales(handler->scales);
540  }
541  return lheevent;
542  }
543  }
544 
545  return boost::shared_ptr<LHEEvent>();
546  }
547 
548 } // namespace lhef
549 
type
Definition: HCALResponse.h:21
int i
Definition: DBlmapReader.cc:9
XMLDocument * createReader(XMLDocument::Handler &handler) override
Definition: LHEReader.cc:69
static const TGPicture * info(bool iBackgroundIsBlack)
LHEReader(const edm::ParameterSet &params)
Definition: LHEReader.cc:432
static void logFileAction(char const *msg, std::string const &fileName)
Definition: LHEReader.cc:37
static void fillHeader(LHERunInfo::Header &header, const char *data, int len=-1)
Definition: LHEReader.cc:161
void FlushMessageLog()
StringSource(const std::string &inputs)
Definition: LHEReader.cc:78
void endElement(const XMLCh *const uri, const XMLCh *const localname, const XMLCh *const qname) override
Definition: LHEReader.cc:282
const wgt_info & weightInfo() const
Definition: LHEReader.cc:118
Storage * open(const std::string &url, int mode=IOFlags::OpenRead)
const std::vector< std::string > fileURLs
Definition: LHEReader.h:33
static bool isSpace(XMLCh ch)
Definition: XMLUtils.h:86
void comment(const XMLCh *const data, const unsigned int length) override
Definition: LHEReader.cc:416
void characters(const XMLCh *const data, const unsigned int length) override
Definition: LHEReader.cc:386
tuple node
Definition: Node.py:50
std::vector< LHERunInfo::Header > headers
Definition: LHEReader.cc:144
U second(std::pair< T, U > const &p)
static StorageFactory * get(void)
boost::shared_ptr< LHERunInfo > curRunInfo
Definition: LHEReader.h:44
std::vector< DOMElement * > xmlEventNodes
Definition: LHEReader.cc:142
void addHeader(const Header &header)
Definition: LHERunInfo.h:63
std::auto_ptr< XMLHandler > handler
Definition: LHEReader.h:45
list attributes
Definition: asciidump.py:415
void addLine(const std::string &line)
static bool isAllSpaces(const XMLCh *str, unsigned int length)
Definition: XMLUtils.h:82
const std::string strName
Definition: LHEReader.h:36
std::vector< std::pair< std::string, std::string > > wgt_info
Definition: LHEReader.cc:100
tuple text
Definition: runonSM.py:42
#define end
Definition: vmac.h:37
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< DOMElement * > xmlNodes
Definition: LHEReader.cc:142
DOMImplementation * impl
Definition: LHEReader.cc:136
tuple attr
Definition: asciidump.py:432
void startElement(const XMLCh *const uri, const XMLCh *const localname, const XMLCh *const qname, const Attributes &attributes) override
Definition: LHEReader.cc:178
def qname
Definition: asciidump.py:315
boost::shared_ptr< LHEEvent > next(bool *newFileOpened=nullptr)
Definition: LHEReader.cc:459
XMLDocument * createReader(XMLDocument::Handler &handler) override
Definition: LHEReader.cc:91
std::auto_ptr< XMLDocument > curDoc
Definition: LHEReader.h:43
std::auto_ptr< StorageWrap > fileStream
Definition: LHEReader.cc:73
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:82
virtual XMLDocument * createReader(XMLDocument::Handler &handler)=0
unsigned int firstEvent
Definition: LHEReader.h:37
std::vector< float > scales
Definition: LHEReader.cc:148
tuple fileNames
Definition: LaserDQM_cfg.py:34
volatile std::atomic< bool > shutdown_flag false
int weight
Definition: histoStyle.py:50
std::auto_ptr< Source > curSource
Definition: LHEReader.h:42
std::auto_ptr< std::istream > fileStream
Definition: LHEReader.cc:95
FileSource(const std::string &fileURL)
Definition: LHEReader.cc:52
static void attributesToDom(DOMElement *dom, const Attributes &attributes)
Definition: LHEReader.cc:151
unsigned int curIndex
Definition: LHEReader.h:39
#define comment(par)
Definition: vmac.h:161