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