lhef/
lib.rs

1//! A library for interacting with files in the Les Houches Event File (LHEF) format.
2//!
3//! Lhef supports both reading and writing via the `Reader` and `Writer`
4//! structs. Information about the generator run is provided in a `HEPRUP`
5//! object and each event is stored in a `HEPEUP` object. These structs
6//! correspond to the Fortran common blocks of the same names in the
7//! [original proposal](https://arxiv.org/abs/hep-ph/0109068v1), but contain
8//! extra `info` fields corresponding to the "optional information"
9//! specified in the LHEF standard.
10//!
11//! As of now, only [version 1.0](https://arxiv.org/abs/hep-ph/0609017) of
12//! the LHEF format is fully supported. Files in [version
13//! 2.0](http://www.lpthe.jussieu.fr/LesHouches09Wiki/index.php/LHEF_for_Matching)
14//! and [3.0](https://phystev.cnrs.fr/wiki/2013:groups:tools:lhef3) are
15//! parsed exactly like for version 1.0. This means that the additional XML
16//! tags have to be extracted manually from the `info` fields of the
17//! `HEPRUP` and `HEPEUP` objects.
18//!
19//! # Examples
20//!
21//! ```rust,no_run
22//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
23//! use lhef::Reader;
24//! use std::fs::File;
25//! use std::io::BufReader;
26//!
27//! let input = BufReader::new(File::open("events.lhe")?);
28//!
29//! let mut reader = Reader::new(input)?;
30//!
31//! println!("Information in comment header:\n{}", reader.header());
32//! println!("Information in xml header:\n{:?}", reader.xml_header());
33//! println!("Generator run information:\n{:?}", reader.heprup());
34//!
35//! let event = reader.hepeup()?;
36//! if let Some(event) = event {
37//!     println!("Found an event: {:?}", event);
38//! }
39//! # Ok(())
40//! # }
41//! ```
42mod data;
43/// LHEF reader
44pub mod reader;
45/// Particle status codes
46pub mod status;
47mod syntax;
48/// LHEF writer
49pub mod writer;
50
51pub use crate::data::XmlAttr;
52pub use crate::data::XmlTree;
53pub use crate::data::HEPEUP;
54pub use crate::data::HEPRUP;
55pub use crate::reader::Reader;
56pub use crate::writer::Writer;
57
58#[cfg(test)]
59mod tests {
60    extern crate flate2;
61
62    use super::*;
63    use std::fs;
64    use std::io;
65    use tests::flate2::bufread::GzDecoder;
66
67    #[test]
68    fn test_read_write() {
69        let mut reader = {
70            let file =
71                fs::File::open("test_data/2j.lhe.gz").expect("file not found");
72            let reader =
73                io::BufReader::new(GzDecoder::new(io::BufReader::new(file)));
74            Reader::new(reader).unwrap()
75        };
76        let mut output = Vec::new();
77        let mut events = Vec::new();
78        {
79            let mut writer =
80                Writer::new(io::Cursor::new(&mut output), reader.version())
81                    .unwrap();
82            if let Some(header) = reader.xml_header() {
83                writer.xml_header(header).unwrap();
84            }
85            if !reader.header().is_empty() {
86                writer.header(reader.header()).unwrap();
87            }
88            writer.heprup(reader.heprup()).unwrap();
89            while let Some(event) = reader.hepeup().unwrap() {
90                writer.hepeup(&event).unwrap();
91                events.push(event);
92            }
93            writer.finish().unwrap();
94        }
95        let mut cmp_reader = Reader::new(io::Cursor::new(&output)).unwrap();
96        assert_eq!(cmp_reader.version(), reader.version());
97        assert_eq!(cmp_reader.header(), reader.header());
98        assert_eq!(cmp_reader.xml_header(), reader.xml_header());
99        assert_eq!(cmp_reader.heprup(), reader.heprup());
100        let mut cmp_events = Vec::new();
101        while let Some(event) = cmp_reader.hepeup().unwrap() {
102            cmp_events.push(event);
103        }
104        assert_eq!(cmp_events, events)
105    }
106}