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::map<int,float> scalesmap;
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  sscanf(scalename,"pt_clust_%d",&ipart);
214 
215  float scaleval;
216  const char *scalevalstr = XMLSimpleStr(attributes.getValue(iscale));
217  sscanf(scalevalstr,"%e",&scaleval);
218 
219  scalesmap[ipart] = scaleval;
220  }
221  }
222  xmlEventNodes.push_back(elem);
223  return;
224  } else if (mode == kInit) {
225  //skip unknown tags in init block as well
226  return;
227  } else if (mode != kNone) {
228  throw cms::Exception("InvalidFormat")
229  << "LHE file has invalid format" << std::endl;
230  }
231 
232  if (name == "header") {
233  if (!impl)
234  impl = DOMImplementationRegistry::getDOMImplementation(
235  XMLUniStr("Core"));
236  xmlHeader = impl->createDocument(0, qname, 0);
237  xmlNodes.resize(1);
238  xmlNodes[0] = xmlHeader->getDocumentElement();
239  mode = kHeader;
240  } if (name == "init") {
241  mode = kInit;
242  } else if (name == "event") {
243  if (!impl)
244  impl = DOMImplementationRegistry::getDOMImplementation(
245  XMLUniStr("Core"));
246  if(xmlEvent) xmlEvent->release();
247  xmlEvent = impl->createDocument(0, qname, 0);
248  weightsinevent.resize(0);
249  scalesmap.clear();
250 
251  npLO = -99;
252  npNLO = -99;
253  const XMLCh *npLOval = attributes.getValue(XMLString::transcode("npLO"));
254  if (npLOval) {
255  const char *npLOs = XMLSimpleStr(npLOval);
256  sscanf(npLOs,"%d",&npLO);
257  }
258  const XMLCh *npNLOval = attributes.getValue(XMLString::transcode("npNLO"));
259  if (npNLOval) {
260  const char *npNLOs = XMLSimpleStr(npNLOval);
261  sscanf(npNLOs,"%d",&npNLO);
262  }
263 
264  xmlEventNodes.resize(1);
265  xmlEventNodes[0] = xmlEvent->getDocumentElement();
266  mode = kEvent;
267  }
268 
269  if (mode == kNone)
270  throw cms::Exception("InvalidFormat")
271  << "LHE file has invalid format" << std::endl;
272 
273  buffer.clear();
274 }
275 
276 void LHEReader::XMLHandler::endElement(const XMLCh *const uri,
277  const XMLCh *const localname,
278  const XMLCh *const qname)
279 {
280  std::string name((const char*)XMLSimpleStr(qname));
281 
282  if (mode) {
283 
284  if (mode == kHeader && xmlNodes.size() > 1) {
285  xmlNodes.resize(xmlNodes.size() - 1);
286  return;
287  } else if (mode == kHeader) {
288  std::auto_ptr<DOMWriter> writer(
289  static_cast<DOMImplementationLS*>(
290  impl)->createDOMWriter());
291  writer->setEncoding(XMLUniStr("UTF-8"));
292 
293  for(DOMNode *node = xmlNodes[0]->getFirstChild();
294  node; node = node->getNextSibling()) {
295  XMLSimpleStr buffer(writer->writeToString(*node));
296 
298  const char *p, *q;
299  DOMElement *elem;
300 
301  switch(node->getNodeType()) {
302  case DOMNode::ELEMENT_NODE:
303  elem = static_cast<DOMElement*>(node);
304  type = (const char*)XMLSimpleStr(
305  elem->getTagName());
306  p = std::strchr((const char*)buffer,
307  '>') + 1;
308  q = std::strrchr(p, '<');
309  break;
310  case DOMNode::COMMENT_NODE:
311  type = "";
312  p = buffer + 4;
313  q = buffer + strlen(buffer) - 3;
314  break;
315  default:
316  type = "<>";
317  p = buffer +
318  std::strspn(buffer, " \t\r\n");
319  if (!*p)
320  continue;
321  q = p + strlen(p);
322  }
323  LHERunInfo::Header header(type);
324  fillHeader(header, p, q - p);
325  headers.push_back(header);
326  }
327 
328  xmlHeader->release();
329  xmlHeader = 0;
330  }
331  else if (name == "event" &&
332  mode == kEvent &&
333  xmlEventNodes.size() >= 1) { // handling of weights in LHE file
334  for(DOMNode *node = xmlEventNodes[0]->getFirstChild();
335  node; node = node->getNextSibling()) {
336  switch( node->getNodeType() ) {
337  case DOMNode::ELEMENT_NODE: // rwgt
338  for(DOMNode *rwgt = xmlEventNodes[1]->getFirstChild();
339  rwgt; rwgt = rwgt->getNextSibling()) {
340  DOMNode* attr = rwgt->getAttributes()->item(0);
341  XMLSimpleStr atname(attr->getNodeValue());
342  XMLSimpleStr weight(rwgt->getFirstChild()->getNodeValue());
343  switch( rwgt->getNodeType() ) {
344  case DOMNode::ELEMENT_NODE:
345  weightsinevent.push_back(std::make_pair((const char*)atname,
346  (const char*)weight));
347  break;
348  default:
349  break;
350  }
351  }
352  break;
353  case DOMNode::TEXT_NODE: // event information
354  {
355  XMLSimpleStr data(node->getNodeValue());
356  buffer.append(data);
357  }
358  break;
359  default:
360  break;
361  }
362  }
363  }
364  else if (mode == kEvent) {
365  //skip unknown tags
366  return;
367  }
368 
369  if (gotObject != kNone)
370  throw cms::Exception("InvalidState")
371  << "Unexpected pileup in"
372  " LHEReader::XMLHandler::endElement"
373  << std::endl;
374 
375  gotObject = mode;
376  mode = kNone;
377  }
378 }
379 
380 void LHEReader::XMLHandler::characters(const XMLCh *const data_,
381  const unsigned int length)
382 {
383  if (mode == kHeader) {
384  DOMText *text = xmlHeader->createTextNode(data_);
385  xmlNodes.back()->appendChild(text);
386  return;
387  }
388 
389  if (XMLSimpleStr::isAllSpaces(data_, length))
390  return;
391 
392  unsigned int offset = 0;
393  while(offset < length && XMLSimpleStr::isSpace(data_[offset]))
394  offset++;
395 
396  if( mode == kEvent ) {
397  DOMText *text = xmlEvent->createTextNode(data_+offset);
398  xmlEventNodes.back()->appendChild(text);
399  return;
400  }
401 
402  if (mode == kNone)
403  throw cms::Exception("InvalidFormat")
404  << "LHE file has invalid format" << std::endl;
405 
406  XMLSimpleStr data(data_ + offset);
407  buffer.append(data);
408 }
409 
410 void LHEReader::XMLHandler::comment(const XMLCh *const data_,
411  const unsigned int length)
412 {
413  if (mode == kHeader) {
414  DOMComment *comment = xmlHeader->createComment(data_);
415  xmlNodes.back()->appendChild(comment);
416  return;
417  }
418 
419  XMLSimpleStr data(data_);
420 
421  LHERunInfo::Header header;
422  fillHeader(header, data);
423  headers.push_back(header);
424 }
425 
427  fileURLs(params.getUntrackedParameter< std::vector<std::string> >("fileNames")),
428  strName(""),
429  firstEvent(params.getUntrackedParameter<unsigned int>("skipEvents", 0)),
430  maxEvents(params.getUntrackedParameter<int>("limitEvents", -1)),
431  curIndex(0), handler(new XMLHandler())
432 {
433 }
434 
435 LHEReader::LHEReader(const std::vector<std::string> &fileNames,
436  unsigned int firstEvent) :
437  fileURLs(fileNames), strName(""), firstEvent(firstEvent), maxEvents(-1),
438  curIndex(0), handler(new XMLHandler())
439 {
440 }
441 
443  unsigned int firstEvent) :
444  strName(inputs), firstEvent(firstEvent), maxEvents(-1),
445  curIndex(0), handler(new XMLHandler())
446 {
447 }
448 
450 {
451 }
452 
453  boost::shared_ptr<LHEEvent> LHEReader::next(bool* newFileOpened)
454  {
455  while(curDoc.get() || curIndex < fileURLs.size() || (fileURLs.size() == 0 && strName != "" ) ) {
456  if (!curDoc.get()) {
457  if ( fileURLs.size() > 0 ) {
458  logFileAction(" Initiating request to open LHE file ", fileURLs[curIndex]);
459  curSource.reset(new FileSource(fileURLs[curIndex]));
460  logFileAction(" Successfully opened LHE file ", fileURLs[curIndex]);
461  if ( newFileOpened != nullptr ) *newFileOpened = true;
462  ++curIndex;
463  } else if ( strName != "" ) {
464  curSource.reset(new StringSource(strName));
465  }
466  handler->reset();
467  curDoc.reset(curSource->createReader(*handler));
468  curRunInfo.reset();
469  }
470 
471  XMLHandler::Object event = handler->gotObject;
472  handler->gotObject = XMLHandler::kNone;
473 
474  std::istringstream data;
475  if (event != XMLHandler::kNone) {
476  data.str(handler->buffer);
477  handler->buffer.clear();
478  }
479 
480  switch(event) {
481  case XMLHandler::kNone:
482  if (!curDoc->parse()) {
483  curDoc.reset();
484  logFileAction(" Closed LHE file ", fileURLs[curIndex - 1]);
485  return boost::shared_ptr<LHEEvent>();
486  }
487  break;
488 
489  case XMLHandler::kHeader:
490  break;
491 
492  case XMLHandler::kInit:
493  curRunInfo.reset(new LHERunInfo(data));
494 
495  std::for_each(handler->headers.begin(),
496  handler->headers.end(),
497  boost::bind(&LHERunInfo::addHeader,
498  curRunInfo.get(), _1));
499  handler->headers.clear();
500  break;
501 
503  break;
504 
505  case XMLHandler::kEvent:
506  if (!curRunInfo.get())
507  throw cms::Exception("InvalidState")
508  << "Got LHE event without"
509  " initialization." << std::endl;
510 
511  if (firstEvent > 0) {
512  firstEvent--;
513  continue;
514  }
515 
516  if (maxEvents == 0)
517  return boost::shared_ptr<LHEEvent>();
518  else if (maxEvents > 0)
519  maxEvents--;
520 
521  boost::shared_ptr<LHEEvent> lheevent;
522  lheevent.reset(new LHEEvent(curRunInfo, data));
523  const XMLHandler::wgt_info& info = handler->weightsinevent;
524  for( size_t i=0; i< info.size(); ++i ) {
525  std::string snum = info[i].second.substr(0,info[i].second.size()-1);
526  double num = -1.0;
527  sscanf(snum.c_str(),"%le",&num);
528  lheevent->addWeight(gen::WeightsInfo(info[i].first,num));
529  }
530  lheevent->setNpLO(handler->npLO);
531  lheevent->setNpNLO(handler->npNLO);
532  //fill scales
533  if (handler->scalesmap.size()>0) {
534  std::vector<float> &scales = lheevent->scales();
535  scales = std::vector<float>(lheevent->getHEPEUP()->NUP, -1.);
536  for (const std::pair<int,float> &scale : handler->scalesmap) {
537  //index differs by one
538  scales[scale.first-1] = scale.second;
539  }
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)
std::map< int, float > scalesmap
Definition: LHEReader.cc:148
LHEReader(const edm::ParameterSet &params)
Definition: LHEReader.cc:426
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:276
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:410
void characters(const XMLCh *const data, const unsigned int length) override
Definition: LHEReader.cc:380
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:75
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:453
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:151
unsigned int curIndex
Definition: LHEReader.h:39
#define comment(par)
Definition: vmac.h:161