event_file_reader/
reader.rs

1use 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        // TODO: trim_ascii_start as soon as it's stable
19        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}