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}