1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
/*!
Read and write `gro` files, pretty quickly.
A `gro` file (Gromos87) describes molecular structures in a plain-text format.
(See [the Gromacs manual][gro_man] or [the old pretty manual][gro_man_legacy].)
Note that, for now, only reading and writing of the classic fixed format is
supported. The additional precision reading mode is on the agenda.
_eightyseven_ can format the atoms section of a gro file in a parallel fashion,
with `WriteGro::write_par` and related methods.
This library comes with its own `Structure` type, which mirrors the information
that is stored in `gro` files. For `Structure`, the `ReadGro`, `WriteGro`, and
`WriteGroPar` traits are implemented. The reading and writing functionality
provided by these traits are provided as good default implementations, which
rely on a couple of easy to implement bridging functions. This makes
implementing the traits for custom types very easy.
Moreover, rather specialized readers that read only a subset of the atom line
fields can be implemented easily and efficiently by setting the flags of the
`ReadGro::PARSE_LIST` constant.
```
# use std::io;
# fn main() -> io::Result<()> {
use eightyseven::structure::Structure;
// Read the structure from a file.
use eightyseven::reader::ReadGro;
let mut structure = Structure::open_gro("tests/eq.gro")?;
println!(" title: {}", structure.title);
println!("natoms: {}", structure.natoms());
// Modify the structure.
// For example, center the structure such that the `BB` beads are centered.
let bb_positions = structure
.atoms
.iter()
.filter(|&atom| atom.atomname.as_str() == "BB")
.map(|atom| atom.position);
let bb_center = bb_positions.clone().sum::<glam::Vec3>() / bb_positions.count() as f32;
for atom in &mut structure.atoms {
atom.position -= bb_center;
}
// And write the structure.
use eightyseven::writer::WriteGro;
structure.save_gro("eq_offset.gro")?;
// Or, for fast writing of large files, format the atom section in parallel.
use eightyseven::writer::WriteGroPar;
structure.save_gro_par("eq_offset.gro")?;
// For both single-threaded and parallel formatting, generic writers exist as well.
// They can write to any type that implements `io::Write`.
structure.write_par(&mut std::io::empty())?;
# Ok(())
# }
```
[gro_man]: https://manual.gromacs.org/current/reference-manual/file-formats.html#gro
[gro_man_legacy]: https://manual.gromacs.org/archive/5.0.3/online/gro.html
By Marieke Westendorp, 2024.
<ma3ke.cyber@gmail.com>
*/
const GRO_INTEGER_LIMIT: u32 = 100000;