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) {}
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 };
147 
148 static void attributesToDom(DOMElement *dom, const Attributes &attributes)
149 {
150  for(unsigned int i = 0; i < attributes.getLength(); i++) {
151  const XMLCh *name = attributes.getQName(i);
152  const XMLCh *value = attributes.getValue(i);
153 
154  dom->setAttribute(name, value);
155  }
156 }
157 
158 static void fillHeader(LHERunInfo::Header &header, const char *data,
159  int len = -1)
160 {
161  const char *end = len >= 0 ? (data + len) : 0;
162  while(*data && (!end || data < end)) {
163  std::size_t len = std::strcspn(data, "\r\n");
164  if (end && data + len > end)
165  len = end - data;
166  if (data[len] == '\r' && data[len + 1] == '\n')
167  len += 2;
168  else if (data[len])
169  len++;
170  header.addLine(std::string(data, len));
171  data += len;
172  }
173 }
174 
175 void LHEReader::XMLHandler::startElement(const XMLCh *const uri,
176  const XMLCh *const localname,
177  const XMLCh *const qname,
178  const Attributes &attributes)
179 {
180  std::string name((const char*)XMLSimpleStr(qname));
181 
182  if (!headerOk) {
183  if (name != "LesHouchesEvents")
184  throw cms::Exception("InvalidFormat")
185  << "LHE file has invalid header" << std::endl;
186  headerOk = true;
187  return;
188  }
189 
190  if (mode == kHeader) {
191  DOMElement *elem = xmlHeader->createElement(qname);
192  attributesToDom(elem, attributes);
193  xmlNodes.back()->appendChild(elem);
194  xmlNodes.push_back(elem);
195  return;
196  } else if ( mode == kEvent ) {
197  DOMElement *elem = xmlEvent->createElement(qname);
198  attributesToDom(elem, attributes);
199 
200  if( name == "rwgt" ) {
201  xmlEventNodes[0]->appendChild(elem);
202  } else if (name == "wgt") {
203  xmlEventNodes[1]->appendChild(elem);
204  }
205  xmlEventNodes.push_back(elem);
206  return;
207  } else if (mode != kNone) {
208  throw cms::Exception("InvalidFormat")
209  << "LHE file has invalid format" << std::endl;
210  }
211 
212  if (name == "header") {
213  if (!impl)
214  impl = DOMImplementationRegistry::getDOMImplementation(
215  XMLUniStr("Core"));
216  xmlHeader = impl->createDocument(0, qname, 0);
217  xmlNodes.resize(1);
218  xmlNodes[0] = xmlHeader->getDocumentElement();
219  mode = kHeader;
220  } if (name == "init") {
221  mode = kInit;
222  } else if (name == "event") {
223  if (!impl)
224  impl = DOMImplementationRegistry::getDOMImplementation(
225  XMLUniStr("Core"));
226  if(xmlEvent) xmlEvent->release();
227  xmlEvent = impl->createDocument(0, qname, 0);
228  weightsinevent.resize(0);
229  xmlEventNodes.resize(1);
230  xmlEventNodes[0] = xmlEvent->getDocumentElement();
231  mode = kEvent;
232  }
233 
234  if (mode == kNone)
235  throw cms::Exception("InvalidFormat")
236  << "LHE file has invalid format" << std::endl;
237 
238  buffer.clear();
239 }
240 
241 void LHEReader::XMLHandler::endElement(const XMLCh *const uri,
242  const XMLCh *const localname,
243  const XMLCh *const qname)
244 {
245  std::string name((const char*)XMLSimpleStr(qname));
246 
247  if (mode) {
248 
249  if (mode == kHeader && xmlNodes.size() > 1) {
250  xmlNodes.resize(xmlNodes.size() - 1);
251  return;
252  } else if (mode == kHeader) {
253  std::auto_ptr<DOMWriter> writer(
254  static_cast<DOMImplementationLS*>(
255  impl)->createDOMWriter());
256  writer->setEncoding(XMLUniStr("UTF-8"));
257 
258  for(DOMNode *node = xmlNodes[0]->getFirstChild();
259  node; node = node->getNextSibling()) {
260  XMLSimpleStr buffer(writer->writeToString(*node));
261 
263  const char *p, *q;
264  DOMElement *elem;
265 
266  switch(node->getNodeType()) {
267  case DOMNode::ELEMENT_NODE:
268  elem = static_cast<DOMElement*>(node);
269  type = (const char*)XMLSimpleStr(
270  elem->getTagName());
271  p = std::strchr((const char*)buffer,
272  '>') + 1;
273  q = std::strrchr(p, '<');
274  break;
275  case DOMNode::COMMENT_NODE:
276  type = "";
277  p = buffer + 4;
278  q = buffer + strlen(buffer) - 3;
279  break;
280  default:
281  type = "<>";
282  p = buffer +
283  std::strspn(buffer, " \t\r\n");
284  if (!*p)
285  continue;
286  q = p + strlen(p);
287  }
288  LHERunInfo::Header header(type);
289  fillHeader(header, p, q - p);
290  headers.push_back(header);
291  }
292 
293  xmlHeader->release();
294  xmlHeader = 0;
295  }
296 
297  if( name == "rwgt" && mode == kEvent ) return;
298  if( name == "wgt" && mode == kEvent ) return;
299 
300  if (name == "event" &&
301  mode == kEvent &&
302  xmlEventNodes.size() >= 1) { // handling of weights in LHE file
303  for(DOMNode *node = xmlEventNodes[0]->getFirstChild();
304  node; node = node->getNextSibling()) {
305  switch( node->getNodeType() ) {
306  case DOMNode::ELEMENT_NODE: // rwgt
307  for(DOMNode *rwgt = xmlEventNodes[1]->getFirstChild();
308  rwgt; rwgt = rwgt->getNextSibling()) {
309  DOMNode* attr = rwgt->getAttributes()->item(0);
310  XMLSimpleStr atname(attr->getNodeValue());
311  XMLSimpleStr weight(rwgt->getFirstChild()->getNodeValue());
312  switch( rwgt->getNodeType() ) {
313  case DOMNode::ELEMENT_NODE:
314  weightsinevent.push_back(std::make_pair((const char*)atname,
315  (const char*)weight));
316  break;
317  default:
318  break;
319  }
320  }
321  break;
322  case DOMNode::TEXT_NODE: // event information
323  {
324  XMLSimpleStr data(node->getNodeValue());
325  buffer.append(data);
326  }
327  break;
328  default:
329  break;
330  }
331  }
332  }
333 
334  if (gotObject != kNone)
335  throw cms::Exception("InvalidState")
336  << "Unexpected pileup in"
337  " LHEReader::XMLHandler::endElement"
338  << std::endl;
339 
340  gotObject = mode;
341  mode = kNone;
342  }
343 }
344 
345 void LHEReader::XMLHandler::characters(const XMLCh *const data_,
346  const unsigned int length)
347 {
348  if (mode == kHeader) {
349  DOMText *text = xmlHeader->createTextNode(data_);
350  xmlNodes.back()->appendChild(text);
351  return;
352  }
353 
354  if (XMLSimpleStr::isAllSpaces(data_, length))
355  return;
356 
357  unsigned int offset = 0;
358  while(offset < length && XMLSimpleStr::isSpace(data_[offset]))
359  offset++;
360 
361  if( mode == kEvent ) {
362  DOMText *text = xmlEvent->createTextNode(data_+offset);
363  xmlEventNodes.back()->appendChild(text);
364  return;
365  }
366 
367  if (mode == kNone)
368  throw cms::Exception("InvalidFormat")
369  << "LHE file has invalid format" << std::endl;
370 
371  XMLSimpleStr data(data_ + offset);
372  buffer.append(data);
373 }
374 
375 void LHEReader::XMLHandler::comment(const XMLCh *const data_,
376  const unsigned int length)
377 {
378  if (mode == kHeader) {
379  DOMComment *comment = xmlHeader->createComment(data_);
380  xmlNodes.back()->appendChild(comment);
381  return;
382  }
383 
384  XMLSimpleStr data(data_);
385 
386  LHERunInfo::Header header;
387  fillHeader(header, data);
388  headers.push_back(header);
389 }
390 
392  fileURLs(params.getUntrackedParameter< std::vector<std::string> >("fileNames")),
393  strName(""),
394  firstEvent(params.getUntrackedParameter<unsigned int>("skipEvents", 0)),
395  maxEvents(params.getUntrackedParameter<int>("limitEvents", -1)),
396  curIndex(0), handler(new XMLHandler())
397 {
398 }
399 
400 LHEReader::LHEReader(const std::vector<std::string> &fileNames,
401  unsigned int firstEvent) :
402  fileURLs(fileNames), strName(""), firstEvent(firstEvent), maxEvents(-1),
403  curIndex(0), handler(new XMLHandler())
404 {
405 }
406 
408  unsigned int firstEvent) :
409  strName(inputs), firstEvent(firstEvent), maxEvents(-1),
410  curIndex(0), handler(new XMLHandler())
411 {
412 }
413 
415 {
416 }
417 
418  boost::shared_ptr<LHEEvent> LHEReader::next(bool* newFileOpened)
419  {
420  while(curDoc.get() || curIndex < fileURLs.size() || (fileURLs.size() == 0 && strName != "" ) ) {
421  if (!curDoc.get()) {
422  if ( fileURLs.size() > 0 ) {
423  logFileAction(" Initiating request to open LHE file ", fileURLs[curIndex]);
424  curSource.reset(new FileSource(fileURLs[curIndex]));
425  logFileAction(" Successfully opened LHE file ", fileURLs[curIndex]);
426  if ( newFileOpened != nullptr ) *newFileOpened = true;
427  ++curIndex;
428  } else if ( strName != "" ) {
429  curSource.reset(new StringSource(strName));
430  }
431  handler->reset();
432  curDoc.reset(curSource->createReader(*handler));
433  curRunInfo.reset();
434  }
435 
436  XMLHandler::Object event = handler->gotObject;
437  handler->gotObject = XMLHandler::kNone;
438 
439  std::istringstream data;
440  if (event != XMLHandler::kNone) {
441  data.str(handler->buffer);
442  handler->buffer.clear();
443  }
444 
445  switch(event) {
446  case XMLHandler::kNone:
447  if (!curDoc->parse()) {
448  curDoc.reset();
449  logFileAction(" Closed LHE file ", fileURLs[curIndex - 1]);
450  }
451  break;
452 
453  case XMLHandler::kHeader:
454  break;
455 
456  case XMLHandler::kInit:
457  curRunInfo.reset(new LHERunInfo(data));
458 
459  std::for_each(handler->headers.begin(),
460  handler->headers.end(),
461  boost::bind(&LHERunInfo::addHeader,
462  curRunInfo.get(), _1));
463  handler->headers.clear();
464  break;
465 
467  break;
468 
469  case XMLHandler::kEvent:
470  if (!curRunInfo.get())
471  throw cms::Exception("InvalidState")
472  << "Got LHE event without"
473  " initialization." << std::endl;
474 
475  if (firstEvent > 0) {
476  firstEvent--;
477  continue;
478  }
479 
480  if (maxEvents == 0)
481  return boost::shared_ptr<LHEEvent>();
482  else if (maxEvents > 0)
483  maxEvents--;
484 
485  boost::shared_ptr<LHEEvent> lheevent;
486  lheevent.reset(new LHEEvent(curRunInfo, data));
487  const XMLHandler::wgt_info& info = handler->weightsinevent;
488  for( size_t i=0; i< info.size(); ++i ) {
489  std::string snum = info[i].second.substr(0,info[i].second.size()-1);
490  double num = -1.0;
491  sscanf(snum.c_str(),"%le",&num);
492  lheevent->addWeight(gen::WeightsInfo(info[i].first,num));
493  }
494  return lheevent;
495  }
496  }
497 
498  return boost::shared_ptr<LHEEvent>();
499  }
500 
501 } // namespace lhef
502 
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:391
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:158
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:241
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:375
void characters(const XMLCh *const data, const unsigned int length) override
Definition: LHEReader.cc:345
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
unsigned int offset(bool)
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
bool first
Definition: L1TdeRCT.cc:79
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:175
def qname
Definition: asciidump.py:315
boost::shared_ptr< LHEEvent > next(bool *newFileOpened=nullptr)
Definition: LHEReader.cc:418
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
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:148
unsigned int curIndex
Definition: LHEReader.h:39
#define comment(par)
Definition: vmac.h:161