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 
10 #include <boost/bind.hpp>
11 
12 #include <xercesc/sax2/Attributes.hpp>
13 #include <xercesc/dom/DOM.hpp>
14 
19 
23 
27 
28 #include "XMLUtils.h"
29 
30 XERCES_CPP_NAMESPACE_USE
31 
32 namespace lhef {
33 
34  static void logFileAction(char const* msg, std::string const& fileName) {
35  edm::LogAbsolute("fileAction") << std::setprecision(0) << edm::TimeOfDay() << msg << fileName;
37  }
38 
39 
41  public:
42  Source() {}
43  virtual ~Source() {}
45 };
46 
48  public:
49  FileSource(const std::string &fileURL)
50  {
51  Storage *storage =
52  StorageFactory::get()->open(fileURL,
54 
55  if (!storage)
56  throw cms::Exception("FileOpenError")
57  << "Could not open LHE file \""
58  << fileURL << "\" for reading"
59  << std::endl;
60 
61  fileStream.reset(new StorageWrap(storage));
62  }
63 
65 
67  { return new XMLDocument(fileStream, handler); }
68 
69  private:
70  std::auto_ptr<StorageWrap> fileStream;
71 };
72 
74  public:
76  {
77  if (inputs == "")
78  throw cms::Exception("StreamOpenError")
79  << "Empty LHE file string name \""
80  << std::endl;
81 
82  std::stringstream * tmpis = new std::stringstream(inputs);
83  fileStream.reset(tmpis);
84  }
85 
87 
89  { return new XMLDocument(fileStream, handler); }
90 
91  private:
92  std::auto_ptr<std::istream> fileStream;
93 };
94 
96  public:
98  impl(0), gotObject(kNone), mode(kNone),
99  xmlHeader(0), headerOk(false) {}
101  { if (xmlHeader) xmlHeader->release(); }
102 
103  enum Object {
104  kNone = 0,
109  };
110 
111  void reset() { headerOk = false; }
112 
113  protected:
114  void startElement(const XMLCh *const uri,
115  const XMLCh *const localname,
116  const XMLCh *const qname,
117  const Attributes &attributes);
118 
119  void endElement(const XMLCh *const uri,
120  const XMLCh *const localname,
121  const XMLCh *const qname);
122 
123  void characters(const XMLCh *const data, const unsigned int length);
124  void comment(const XMLCh *const data, const unsigned int length);
125 
126  private:
127  friend class LHEReader;
128 
129  DOMImplementation *impl;
133  DOMDocument *xmlHeader;
134  std::vector<DOMElement*> xmlNodes;
135  bool headerOk;
136  std::vector<LHERunInfo::Header> headers;
137 };
138 
139 static void attributesToDom(DOMElement *dom, const Attributes &attributes)
140 {
141  for(unsigned int i = 0; i < attributes.getLength(); i++) {
142  const XMLCh *name = attributes.getQName(i);
143  const XMLCh *value = attributes.getValue(i);
144 
145  dom->setAttribute(name, value);
146  }
147 }
148 
149 static void fillHeader(LHERunInfo::Header &header, const char *data,
150  int len = -1)
151 {
152  const char *end = len >= 0 ? (data + len) : 0;
153  while(*data && (!end || data < end)) {
154  std::size_t len = std::strcspn(data, "\r\n");
155  if (end && data + len > end)
156  len = end - data;
157  if (data[len] == '\r' && data[len + 1] == '\n')
158  len += 2;
159  else if (data[len])
160  len++;
161  header.addLine(std::string(data, len));
162  data += len;
163  }
164 }
165 
166 void LHEReader::XMLHandler::startElement(const XMLCh *const uri,
167  const XMLCh *const localname,
168  const XMLCh *const qname,
169  const Attributes &attributes)
170 {
171  std::string name((const char*)XMLSimpleStr(qname));
172 
173  if (!headerOk) {
174  if (name != "LesHouchesEvents")
175  throw cms::Exception("InvalidFormat")
176  << "LHE file has invalid header" << std::endl;
177  headerOk = true;
178  return;
179  }
180 
181  if (mode == kHeader) {
182  DOMElement *elem = xmlHeader->createElement(qname);
183  attributesToDom(elem, attributes);
184  xmlNodes.back()->appendChild(elem);
185  xmlNodes.push_back(elem);
186  return;
187  } else if (mode != kNone)
188  throw cms::Exception("InvalidFormat")
189  << "LHE file has invalid format" << std::endl;
190 
191  if (name == "header") {
192  if (!impl)
193  impl = DOMImplementationRegistry::getDOMImplementation(
194  XMLUniStr("Core"));
195  xmlHeader = impl->createDocument(0, qname, 0);
196  xmlNodes.resize(1);
197  xmlNodes[0] = xmlHeader->getDocumentElement();
198  mode = kHeader;
199  } if (name == "init")
200  mode = kInit;
201  else if (name == "event")
202  mode = kEvent;
203 
204  if (mode == kNone)
205  throw cms::Exception("InvalidFormat")
206  << "LHE file has invalid format" << std::endl;
207 
208  buffer.clear();
209 }
210 
211 void LHEReader::XMLHandler::endElement(const XMLCh *const uri,
212  const XMLCh *const localname,
213  const XMLCh *const qname)
214 {
215  if (mode) {
216  if (mode == kHeader && xmlNodes.size() > 1) {
217  xmlNodes.resize(xmlNodes.size() - 1);
218  return;
219  } else if (mode == kHeader) {
220  std::auto_ptr<DOMWriter> writer(
221  static_cast<DOMImplementationLS*>(
222  impl)->createDOMWriter());
223  writer->setEncoding(XMLUniStr("UTF-8"));
224 
225  for(DOMNode *node = xmlNodes[0]->getFirstChild();
226  node; node = node->getNextSibling()) {
227  XMLSimpleStr buffer(
228  writer->writeToString(*node));
229 
231  const char *p, *q;
232  DOMElement *elem;
233 
234  switch(node->getNodeType()) {
235  case DOMNode::ELEMENT_NODE:
236  elem = static_cast<DOMElement*>(node);
237  type = (const char*)XMLSimpleStr(
238  elem->getTagName());
239  p = std::strchr((const char*)buffer,
240  '>') + 1;
241  q = std::strrchr(p, '<');
242  break;
243  case DOMNode::COMMENT_NODE:
244  type = "";
245  p = buffer + 4;
246  q = buffer + strlen(buffer) - 3;
247  break;
248  default:
249  type = "<>";
250  p = buffer +
251  std::strspn(buffer, " \t\r\n");
252  if (!*p)
253  continue;
254  q = p + strlen(p);
255  }
256 
257  LHERunInfo::Header header(type);
258  fillHeader(header, p, q - p);
259  headers.push_back(header);
260  }
261 
262  xmlHeader->release();
263  xmlHeader = 0;
264  }
265 
266  if (gotObject != kNone)
267  throw cms::Exception("InvalidState")
268  << "Unexpected pileup in"
269  " LHEReader::XMLHandler::endElement"
270  << std::endl;
271 
272  gotObject = mode;
273  mode = kNone;
274  }
275 }
276 
277 void LHEReader::XMLHandler::characters(const XMLCh *const data_,
278  const unsigned int length)
279 {
280  if (mode == kHeader) {
281  DOMText *text = xmlHeader->createTextNode(data_);
282  xmlNodes.back()->appendChild(text);
283  return;
284  }
285 
286  if (XMLSimpleStr::isAllSpaces(data_, length))
287  return;
288 
289  unsigned int offset = 0;
290  while(offset < length && XMLSimpleStr::isSpace(data_[offset]))
291  offset++;
292 
293  XMLSimpleStr data(data_ + offset);
294 
295  if (mode == kNone)
296  throw cms::Exception("InvalidFormat")
297  << "LHE file has invalid format" << std::endl;
298 
299  buffer.append(data);
300 }
301 
302 void LHEReader::XMLHandler::comment(const XMLCh *const data_,
303  const unsigned int length)
304 {
305  if (mode == kHeader) {
306  DOMComment *comment = xmlHeader->createComment(data_);
307  xmlNodes.back()->appendChild(comment);
308  return;
309  }
310 
311  XMLSimpleStr data(data_);
312 
313  LHERunInfo::Header header;
314  fillHeader(header, data);
315  headers.push_back(header);
316 }
317 
319  fileURLs(params.getUntrackedParameter< std::vector<std::string> >("fileNames")),
320  strName(""),
321  firstEvent(params.getUntrackedParameter<unsigned int>("skipEvents", 0)),
322  maxEvents(params.getUntrackedParameter<int>("limitEvents", -1)),
323  curIndex(0), handler(new XMLHandler())
324 {
325 }
326 
327 LHEReader::LHEReader(const std::vector<std::string> &fileNames,
328  unsigned int firstEvent) :
329  fileURLs(fileNames), strName(""), firstEvent(firstEvent), maxEvents(-1),
330  curIndex(0), handler(new XMLHandler())
331 {
332 }
333 
335  unsigned int firstEvent) :
336  strName(inputs), firstEvent(firstEvent), maxEvents(-1),
337  curIndex(0), handler(new XMLHandler())
338 {
339 }
340 
342 {
343 }
344 
345  boost::shared_ptr<LHEEvent> LHEReader::next(bool* newFileOpened)
346  {
347 
348  while(curDoc.get() || curIndex < fileURLs.size() || (fileURLs.size() == 0 && strName != "" ) ) {
349  if (!curDoc.get()) {
350  if ( fileURLs.size() > 0 ) {
351  logFileAction(" Initiating request to open LHE file ", fileURLs[curIndex]);
352  curSource.reset(new FileSource(fileURLs[curIndex]));
353  logFileAction(" Successfully opened LHE file ", fileURLs[curIndex]);
354  if ( newFileOpened != nullptr ) *newFileOpened = true;
355  ++curIndex;
356  } else if ( strName != "" ) {
357  curSource.reset(new StringSource(strName));
358  }
359  handler->reset();
360  curDoc.reset(curSource->createReader(*handler));
361  curRunInfo.reset();
362  }
363 
364  XMLHandler::Object event = handler->gotObject;
365  handler->gotObject = XMLHandler::kNone;
366 
367  std::istringstream data;
368  if (event != XMLHandler::kNone) {
369  data.str(handler->buffer);
370  handler->buffer.clear();
371  }
372 
373  switch(event) {
374  case XMLHandler::kNone:
375  if (!curDoc->parse()) {
376  curDoc.reset();
377  logFileAction(" Closed LHE file ", fileURLs[curIndex - 1]);
378  }
379  break;
380 
381  case XMLHandler::kHeader:
382  break;
383 
384  case XMLHandler::kInit:
385  curRunInfo.reset(new LHERunInfo(data));
386 
387  std::for_each(handler->headers.begin(),
388  handler->headers.end(),
389  boost::bind(&LHERunInfo::addHeader,
390  curRunInfo.get(), _1));
391  handler->headers.clear();
392  break;
393 
395  break;
396 
397  case XMLHandler::kEvent:
398  if (!curRunInfo.get())
399  throw cms::Exception("InvalidState")
400  << "Got LHE event without"
401  " initialization." << std::endl;
402 
403  if (firstEvent > 0) {
404  firstEvent--;
405  continue;
406  }
407 
408  if (maxEvents == 0)
409  return boost::shared_ptr<LHEEvent>();
410  else if (maxEvents > 0)
411  maxEvents--;
412 
413  return boost::shared_ptr<LHEEvent>(
414  new LHEEvent(curRunInfo, data));
415  }
416  }
417 
418  return boost::shared_ptr<LHEEvent>();
419  }
420 
421 } // namespace lhef
422 
type
Definition: HCALResponse.h:21
int i
Definition: DBlmapReader.cc:9
LHEReader(const edm::ParameterSet &params)
Definition: LHEReader.cc:318
static void logFileAction(char const *msg, std::string const &fileName)
Definition: LHEReader.cc:34
static void fillHeader(LHERunInfo::Header &header, const char *data, int len=-1)
Definition: LHEReader.cc:149
void FlushMessageLog()
StringSource(const std::string &inputs)
Definition: LHEReader.cc:75
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:166
const std::vector< std::string > fileURLs
Definition: LHEReader.h:33
static bool isSpace(XMLCh ch)
Definition: XMLUtils.h:86
tuple node
Definition: Node.py:50
std::vector< LHERunInfo::Header > headers
Definition: LHEReader.cc:136
static StorageFactory * get(void)
boost::shared_ptr< LHERunInfo > curRunInfo
Definition: LHEReader.h:43
void addHeader(const Header &header)
Definition: LHERunInfo.h:63
std::auto_ptr< XMLHandler > handler
Definition: LHEReader.h:44
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
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
void endElement(const XMLCh *const uri, const XMLCh *const localname, const XMLCh *const qname)
Definition: LHEReader.cc:211
std::vector< DOMElement * > xmlNodes
Definition: LHEReader.cc:134
DOMImplementation * impl
Definition: LHEReader.cc:129
def qname
Definition: asciidump.py:315
boost::shared_ptr< LHEEvent > next(bool *newFileOpened=nullptr)
Definition: LHEReader.cc:345
void characters(const XMLCh *const data, const unsigned int length)
Definition: LHEReader.cc:277
std::auto_ptr< XMLDocument > curDoc
Definition: LHEReader.h:42
std::auto_ptr< StorageWrap > fileStream
Definition: LHEReader.cc:70
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:302
tuple fileNames
Definition: LaserDQM_cfg.py:34
std::auto_ptr< Source > curSource
Definition: LHEReader.h:41
std::auto_ptr< std::istream > fileStream
Definition: LHEReader.cc:92
FileSource(const std::string &fileURL)
Definition: LHEReader.cc:49
XMLDocument * createReader(XMLDocument::Handler &handler)
Definition: LHEReader.cc:66
static void attributesToDom(DOMElement *dom, const Attributes &attributes)
Definition: LHEReader.cc:139
unsigned int curIndex
Definition: LHEReader.h:39
XMLDocument * createReader(XMLDocument::Handler &handler)
Definition: LHEReader.cc:88
#define comment(par)
Definition: vmac.h:162