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