event_file_reader/
reader.rs1use std::{fs::File, io::BufReader, path::Path};
2
3use audec::auto_decompress;
4use avery::Event;
5use thiserror::Error;
6
7pub struct EventFileReader(Box<dyn Iterator<Item = Result<Event, Error>>>);
8
9impl EventFileReader {
10 pub fn new<P: AsRef<Path>>(infile: P) -> Result<Self, Error> {
11 let file = File::open(infile.as_ref())?;
12 let mut input = auto_decompress(BufReader::new(file));
13 let buf = input.fill_buf()?;
14 #[cfg(feature = "ntuple")]
15 if buf.starts_with(b"root") {
16 return Ok(Self(Box::new(crate::ntuple::Reader::new(infile)?)));
17 }
18 let buf = trim_ascii_start(buf);
20 #[cfg(feature = "lhef")]
21 if buf.starts_with(b"<LesHouchesEvents") {
22 return Ok(Self(Box::new(crate::lhef::Reader::new(input)?)));
23 }
24 #[cfg(feature = "hepmc2")]
25 if buf.starts_with(b"HepMC") {
26 return Ok(Self(Box::new(crate::hepmc2::Reader::new(input)?)));
27 }
28 Err(Error::UnknownFormat)
29 }
30}
31
32impl Iterator for EventFileReader {
33 type Item = Result<Event, Error>;
34
35 fn next(&mut self) -> Option<Self::Item> {
36 self.0.next()
37 }
38}
39
40fn trim_ascii_start(buf: &[u8]) -> &[u8] {
41 if let Some(pos) = buf.iter().position(|b| !b.is_ascii_whitespace()) {
42 &buf[pos..]
43 } else {
44 &[]
45 }
46}
47
48#[derive(Debug, Error)]
49pub enum Error {
50 #[error("Failed to determine event file format")]
51 UnknownFormat,
52 #[error("I/O error")]
53 IO(#[from] std::io::Error),
54 #[cfg(feature = "lhef")]
55 #[error("LHEF error")]
56 Lhef(#[from] lhef::reader::ReadError),
57 #[cfg(feature = "hepmc2")]
58 #[error("HepMC2 error")]
59 HepMC2(#[from] hepmc2::reader::LineParseError),
60 #[cfg(feature = "ntuple")]
61 #[error("ntuple error")]
62 NTuple(#[from] ntuple::reader::ReadError),
63 #[cfg(feature = "ntuple")]
64 #[error("Failed to read from ROOT file")]
65 ConstructNTuple,
66}