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  auto 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(std::move(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  bool skipEvent = false;
137  DOMImplementation *impl;
141  DOMDocument *xmlHeader;
142  DOMDocument *xmlEvent;
143  std::vector<DOMElement*> xmlNodes,xmlEventNodes;
144  bool headerOk;
145  std::vector<LHERunInfo::Header> headers;
147  int npLO;
148  int npNLO;
149  std::vector<float> scales;
150 };
151 
152 static void attributesToDom(DOMElement *dom, const Attributes &attributes)
153 {
154  for(unsigned int i = 0; i < attributes.getLength(); i++) {
155  const XMLCh *name = attributes.getQName(i);
156  const XMLCh *value = attributes.getValue(i);
157 
158  dom->setAttribute(name, value);
159  }
160 }
161 
162 static void fillHeader(LHERunInfo::Header &header, const char *data,
163  int len = -1)
164 {
165  const char *end = len >= 0 ? (data + len) : 0;
166  while(*data && (!end || data < end)) {
167  std::size_t len = std::strcspn(data, "\r\n");
168  if (end && data + len > end)
169  len = end - data;
170  if (data[len] == '\r' && data[len + 1] == '\n')
171  len += 2;
172  else if (data[len])
173  len++;
174  header.addLine(std::string(data, len));
175  data += len;
176  }
177 }
178 
179 void LHEReader::XMLHandler::startElement(const XMLCh *const uri,
180  const XMLCh *const localname,
181  const XMLCh *const qname,
182  const Attributes &attributes)
183 {
184  std::string name((const char*)XMLSimpleStr(qname));
185 
186  if (!headerOk) {
187  if (name != "LesHouchesEvents")
188  throw cms::Exception("InvalidFormat")
189  << "LHE file has invalid header" << std::endl;
190  headerOk = true;
191  return;
192  }
193 
194  if (mode == kHeader) {
195  DOMElement *elem = xmlHeader->createElement(qname);
196  attributesToDom(elem, attributes);
197  xmlNodes.back()->appendChild(elem);
198  xmlNodes.push_back(elem);
199  return;
200  } else if ( mode == kEvent ) {
201 
202  if (skipEvent) {return;}
203 
204  DOMElement *elem = xmlEvent->createElement(qname);
205  attributesToDom(elem, attributes);
206 
207  //TODO this is a hack (even more than the rest of this class)
208  if( name == "rwgt" ) {
209  xmlEventNodes[0]->appendChild(elem);
210  } else if (name == "wgt") {
211  xmlEventNodes[1]->appendChild(elem);
212  }
213  else if (name == "scales") {
214  for (XMLSize_t iscale=0; iscale<attributes.getLength(); ++iscale) {
215  int ipart = 0;
216  const char *scalename = XMLSimpleStr(attributes.getQName(iscale));
217  int nmatch = sscanf(scalename,"pt_clust_%d",&ipart);
218 
219  if (nmatch!=1) {
220  edm::LogError("Generator|LHEInterface")
221  << "invalid attribute in <scales> tag"
222  << std::endl;
223  }
224 
225  float scaleval;
226  const char *scalevalstr = XMLSimpleStr(attributes.getValue(iscale));
227  sscanf(scalevalstr,"%e",&scaleval);
228 
229  scales.push_back(scaleval);
230  }
231  }
232  xmlEventNodes.push_back(elem);
233  return;
234  } else if (mode == kInit) {
235  //skip unknown tags in init block as well
236  return;
237  } else if (mode != kNone) {
238  throw cms::Exception("InvalidFormat")
239  << "LHE file has invalid format" << std::endl;
240  }
241 
242  if (name == "header") {
243  if (!impl)
244  impl = DOMImplementationRegistry::getDOMImplementation(
245  XMLUniStr("Core"));
246  xmlHeader = impl->createDocument(0, qname, 0);
247  xmlNodes.resize(1);
248  xmlNodes[0] = xmlHeader->getDocumentElement();
249  mode = kHeader;
250  } if (name == "init") {
251  mode = kInit;
252  } else if (name == "event") {
253  if (!skipEvent)
254  {
255  if (!impl)
256  impl = DOMImplementationRegistry::getDOMImplementation(
257  XMLUniStr("Core"));
258  if(xmlEvent) xmlEvent->release();
259  xmlEvent = impl->createDocument(0, qname, 0);
260  weightsinevent.resize(0);
261  scales.clear();
262 
263  npLO = -99;
264  npNLO = -99;
265  const XMLCh *npLOval = attributes.getValue(XMLString::transcode("npLO"));
266  if (npLOval) {
267  const char *npLOs = XMLSimpleStr(npLOval);
268  sscanf(npLOs,"%d",&npLO);
269  }
270  const XMLCh *npNLOval = attributes.getValue(XMLString::transcode("npNLO"));
271  if (npNLOval) {
272  const char *npNLOs = XMLSimpleStr(npNLOval);
273  sscanf(npNLOs,"%d",&npNLO);
274  }
275 
276  xmlEventNodes.resize(1);
277  xmlEventNodes[0] = xmlEvent->getDocumentElement();
278  }
279  mode = kEvent;
280  }
281 
282  if (mode == kNone)
283  throw cms::Exception("InvalidFormat")
284  << "LHE file has invalid format" << std::endl;
285 
286  buffer.clear();
287 }
288 
289 void LHEReader::XMLHandler::endElement(const XMLCh *const uri,
290  const XMLCh *const localname,
291  const XMLCh *const qname)
292 {
293  std::string name((const char*)XMLSimpleStr(qname));
294 
295  if (mode) {
296 
297  if (mode == kHeader && xmlNodes.size() > 1) {
298  xmlNodes.resize(xmlNodes.size() - 1);
299  return;
300  } else if (mode == kHeader) {
301  std::auto_ptr<DOMWriter> writer(
302  static_cast<DOMImplementationLS*>(
303  impl)->createDOMWriter());
304  writer->setEncoding(XMLUniStr("UTF-8"));
305 
306  for(DOMNode *node = xmlNodes[0]->getFirstChild();
307  node; node = node->getNextSibling()) {
308  XMLSimpleStr buffer(writer->writeToString(*node));
309 
311  const char *p, *q;
312  DOMElement *elem;
313 
314  switch(node->getNodeType()) {
315  case DOMNode::ELEMENT_NODE:
316  elem = static_cast<DOMElement*>(node);
317  type = (const char*)XMLSimpleStr(
318  elem->getTagName());
319  p = std::strchr((const char*)buffer,
320  '>') + 1;
321  q = std::strrchr(p, '<');
322  break;
323  case DOMNode::COMMENT_NODE:
324  type = "";
325  p = buffer + 4;
326  q = buffer + strlen(buffer) - 3;
327  break;
328  default:
329  type = "<>";
330  p = buffer +
331  std::strspn(buffer, " \t\r\n");
332  if (!*p)
333  continue;
334  q = p + strlen(p);
335  }
336  LHERunInfo::Header header(type);
337  fillHeader(header, p, q - p);
338  headers.push_back(header);
339  }
340 
341  xmlHeader->release();
342  xmlHeader = 0;
343  }
344  else if (name == "event" &&
345  mode == kEvent &&
346  (skipEvent || (xmlEventNodes.size() >= 1))) { // handling of weights in LHE file
347 
348  if (skipEvent)
349  {
350  gotObject = mode;
351  mode = kNone;
352  return;
353  }
354 
355  for(DOMNode *node = xmlEventNodes[0]->getFirstChild();
356  node; node = node->getNextSibling()) {
357  switch( node->getNodeType() ) {
358  case DOMNode::ELEMENT_NODE: // rwgt
359  for(DOMNode *rwgt = xmlEventNodes[1]->getFirstChild();
360  rwgt; rwgt = rwgt->getNextSibling()) {
361  DOMNode* attr = rwgt->getAttributes()->item(0);
362  XMLSimpleStr atname(attr->getNodeValue());
363  XMLSimpleStr weight(rwgt->getFirstChild()->getNodeValue());
364  switch( rwgt->getNodeType() ) {
365  case DOMNode::ELEMENT_NODE:
366  weightsinevent.push_back(std::make_pair((const char*)atname,
367  (const char*)weight));
368  break;
369  default:
370  break;
371  }
372  }
373  break;
374  case DOMNode::TEXT_NODE: // event information
375  {
376  XMLSimpleStr data(node->getNodeValue());
377  buffer.append(data);
378  }
379  break;
380  default:
381  break;
382  }
383  }
384  }
385  else if (mode == kEvent) {
386  //skip unknown tags
387  return;
388  }
389 
390  if (gotObject != kNone)
391  throw cms::Exception("InvalidState")
392  << "Unexpected pileup in"
393  " LHEReader::XMLHandler::endElement"
394  << std::endl;
395 
396  gotObject = mode;
397  mode = kNone;
398  }
399 }
400 
401 void LHEReader::XMLHandler::characters(const XMLCh *const data_,
402  const unsigned int length)
403 {
404  if (mode == kHeader) {
405  DOMText *text = xmlHeader->createTextNode(data_);
406  xmlNodes.back()->appendChild(text);
407  return;
408  }
409 
410  if (XMLSimpleStr::isAllSpaces(data_, length))
411  return;
412 
413  unsigned int offset = 0;
414  while(offset < length && XMLSimpleStr::isSpace(data_[offset]))
415  offset++;
416 
417  if( mode == kEvent ) {
418  if (!skipEvent)
419  {
420  DOMText *text = xmlEvent->createTextNode(data_+offset);
421  xmlEventNodes.back()->appendChild(text);
422  }
423  return;
424  }
425 
426  if (mode == kNone)
427  throw cms::Exception("InvalidFormat")
428  << "LHE file has invalid format" << std::endl;
429 
430  XMLSimpleStr data(data_ + offset);
431  buffer.append(data);
432 }
433 
434 void LHEReader::XMLHandler::comment(const XMLCh *const data_,
435  const unsigned int length)
436 {
437  if (mode == kHeader) {
438  DOMComment *comment = xmlHeader->createComment(data_);
439  xmlNodes.back()->appendChild(comment);
440  return;
441  }
442 
443  XMLSimpleStr data(data_);
444 
445  LHERunInfo::Header header;
446  fillHeader(header, data);
447  headers.push_back(header);
448 }
449 
451  fileURLs(params.getUntrackedParameter< std::vector<std::string> >("fileNames")),
452  strName(""),
453  firstEvent(params.getUntrackedParameter<unsigned int>("skipEvents", 0)),
454  maxEvents(params.getUntrackedParameter<int>("limitEvents", -1)),
455  curIndex(0), handler(new XMLHandler())
456 {
457 }
458 
459 LHEReader::LHEReader(const std::vector<std::string> &fileNames,
460  unsigned int firstEvent) :
461  fileURLs(fileNames), strName(""), firstEvent(firstEvent), maxEvents(-1),
462  curIndex(0), handler(new XMLHandler())
463 {
464 }
465 
467  unsigned int firstEvent) :
468  strName(inputs), firstEvent(firstEvent), maxEvents(-1),
469  curIndex(0), handler(new XMLHandler())
470 {
471 }
472 
474 {
475 }
476 
477  boost::shared_ptr<LHEEvent> LHEReader::next(bool* newFileOpened)
478  {
479  while(curDoc.get() || curIndex < fileURLs.size() || (fileURLs.size() == 0 && strName != "" ) ) {
480  if (!curDoc.get()) {
481  if ( fileURLs.size() > 0 ) {
482  logFileAction(" Initiating request to open LHE file ", fileURLs[curIndex]);
483  curSource.reset(new FileSource(fileURLs[curIndex]));
484  logFileAction(" Successfully opened LHE file ", fileURLs[curIndex]);
485  if ( newFileOpened != nullptr ) *newFileOpened = true;
486  ++curIndex;
487  } else if ( strName != "" ) {
488  curSource.reset(new StringSource(strName));
489  }
490  handler->reset();
491  curDoc.reset(curSource->createReader(*handler));
492  curRunInfo.reset();
493  }
494  handler->skipEvent = firstEvent > 0;
495 
496  XMLHandler::Object event = handler->gotObject;
497  handler->gotObject = XMLHandler::kNone;
498 
499 
500  switch(event) {
501  case XMLHandler::kNone:
502  if (!curDoc->parse()) {
503  curDoc.reset();
504  logFileAction(" Closed LHE file ", fileURLs[curIndex - 1]);
505  return boost::shared_ptr<LHEEvent>();
506  }
507  break;
508 
509  case XMLHandler::kHeader:
510  break;
511 
512  case XMLHandler::kInit:
513  {
514  std::istringstream data;
515  data.str(handler->buffer);
516  handler->buffer.clear();
517 
518  curRunInfo.reset(new LHERunInfo(data));
519 
520  std::for_each(handler->headers.begin(),
521  handler->headers.end(),
522  boost::bind(&LHERunInfo::addHeader,
523  curRunInfo.get(), _1));
524  handler->headers.clear();
525  }
526  break;
527 
529  break;
530 
531  case XMLHandler::kEvent:
532  {
533  if (!curRunInfo.get())
534  throw cms::Exception("InvalidState")
535  << "Got LHE event without"
536  " initialization." << std::endl;
537 
538  if (firstEvent > 0) {
539  firstEvent--;
540  continue;
541  }
542 
543  if (maxEvents == 0)
544  return boost::shared_ptr<LHEEvent>();
545  else if (maxEvents > 0)
546  maxEvents--;
547 
548  std::istringstream data;
549  data.str(handler->buffer);
550  handler->buffer.clear();
551 
552  boost::shared_ptr<LHEEvent> lheevent;
553  lheevent.reset(new LHEEvent(curRunInfo, data));
554  const XMLHandler::wgt_info& info = handler->weightsinevent;
555  for( size_t i=0; i< info.size(); ++i ) {
556  double num = -1.0;
557  sscanf(info[i].second.c_str(),"%le",&num);
558  lheevent->addWeight(gen::WeightsInfo(info[i].first,num));
559  }
560  lheevent->setNpLO(handler->npLO);
561  lheevent->setNpNLO(handler->npNLO);
562  //fill scales
563  if (handler->scales.size()>0) {
564  lheevent->setScales(handler->scales);
565  }
566  return lheevent;
567  }
568  }
569  }
570 
571  return boost::shared_ptr<LHEEvent>();
572  }
573 
574 } // namespace lhef
575 
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:450
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:162
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:289
const wgt_info & weightInfo() const
Definition: LHEReader.cc:118
const std::vector< std::string > fileURLs
Definition: LHEReader.h:33
static bool isSpace(XMLCh ch)
Definition: XMLUtils.h:87
void comment(const XMLCh *const data, const unsigned int length) override
Definition: LHEReader.cc:434
void characters(const XMLCh *const data, const unsigned int length) override
Definition: LHEReader.cc:401
tuple node
Definition: Node.py:50
std::vector< LHERunInfo::Header > headers
Definition: LHEReader.cc:145
U second(std::pair< T, U > const &p)
boost::shared_ptr< LHERunInfo > curRunInfo
Definition: LHEReader.h:44
std::vector< DOMElement * > xmlEventNodes
Definition: LHEReader.cc:143
static const StorageFactory * get(void)
void addHeader(const Header &header)
Definition: LHERunInfo.h:63
std::auto_ptr< XMLHandler > handler
Definition: LHEReader.h:45
def move
Definition: eostools.py:510
void addLine(const std::string &line)
XMLCh * transcode(const T &fInput)
static bool isAllSpaces(const XMLCh *str, unsigned int length)
Definition: XMLUtils.h:83
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:143
DOMImplementation * impl
Definition: LHEReader.cc:137
void startElement(const XMLCh *const uri, const XMLCh *const localname, const XMLCh *const qname, const Attributes &attributes) override
Definition: LHEReader.cc:179
boost::shared_ptr< LHEEvent > next(bool *newFileOpened=nullptr)
Definition: LHEReader.cc:477
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:149
tuple fileNames
Definition: LaserDQM_cfg.py:34
volatile std::atomic< bool > shutdown_flag false
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:152
unsigned int curIndex
Definition: LHEReader.h:39
std::unique_ptr< Storage > open(const std::string &url, int mode=IOFlags::OpenRead) const
#define comment(par)
Definition: vmac.h:161