hoomd_gsd/lib.rs
1// Copyright (c) 2024-2026 The Regents of the University of Michigan.
2// Part of hoomd-rs, released under the BSD 3-Clause License.
3
4#![doc(
5 html_favicon_url = "https://raw.githubusercontent.com/glotzerlab/hoomd-rs/7352214172a490cc716492e9724ff42720a0018a/doc/theme/favicon.svg"
6)]
7#![doc(
8 html_logo_url = "https://raw.githubusercontent.com/glotzerlab/hoomd-rs/7352214172a490cc716492e9724ff42720a0018a/doc/theme/favicon.svg"
9)]
10#![allow(
11 clippy::missing_inline_in_public_items,
12 reason = "GSD methods are not meant to be customized"
13)]
14
15//! Read and write GSD files.
16//!
17//! # GSD files
18//!
19//! A GSD file stores 2D arrays of integer and floating point types in named chunks
20//! that are associated with trajectory frames. The [GSD Python package] can read
21//! and write these files. `hoomd-gsd` implements GSD file I/O in native Rust.
22//!
23//! # HOOMD schema
24//!
25//! Use [`HoomdGsdFile`] to write to GSD files with the HOOMD schema that can
26//! be read by the [Ovito], [HOOMD-blue], the [GSD Python package], and other applications.
27//!
28//! [`HoomdGsdFile`]: hoomd::HoomdGsdFile
29//! [GSD Python package]: https://gsd.readthedocs.io
30//! [HOOMD-blue]: https://hoomd-blue.readthedocs.io
31//! [Ovito]: https://www.ovito.org
32//!
33//! Create a new GSD file with the hoomd schema:
34//!
35//! ```
36//! use hoomd_gsd::hoomd::HoomdGsdFile;
37//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
38//! # use tempfile::tempdir;
39//! # let tmp_dir = tempdir().expect("temp dir should be created");
40//! # let path = tmp_dir.path().join("test.gsd");
41//! // let path = "file.gsd";
42//! let hoomd_gsd_file = HoomdGsdFile::create(path)?;
43//! # Ok(())
44//! # }
45//! ```
46//!
47//! Call [`append_frame`] to add a new frame to file. Chain any number of method calls
48//! On the return value of [`append_frame`] to write those data chunks to the frame:
49//!
50//! ```
51//! use hoomd_gsd::hoomd::HoomdGsdFile;
52//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
53//! # use tempfile::tempdir;
54//! # let tmp_dir = tempdir().expect("temp dir should be created");
55//! # let path = tmp_dir.path().join("test.gsd");
56//! // let path = "file.gsd";
57//! let mut hoomd_gsd_file = HoomdGsdFile::create(path)?;
58//! hoomd_gsd_file
59//! .append_frame(1_000)?
60//! .configuration_box([100.0, 50.0, 80.0, 0.0, 0.0, 0.0])?
61//! .particles_position([[0.0, 1.0, 2.0].into(), [3.0, 6.0, 12.0].into()])?
62//! .end()?;
63//! # Ok(())
64//! # }
65//! ```
66//!
67//! See the [`Frame`] documentation for a complete list of data chunks that you can write.
68//!
69//! The file is automatically synchronized and closed when the [`HoomdGsdFile`] is dropped.
70//! Call [`open`] to open an existing file and append more frames:
71//!
72//! ```
73//! use hoomd_gsd::hoomd::HoomdGsdFile;
74//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
75//! # use tempfile::tempdir;
76//! # let tmp_dir = tempdir().expect("temp dir should be created");
77//! # let path = tmp_dir.path().join("test.gsd");
78//! // let path = "file.gsd";
79//! # HoomdGsdFile::create(&path)?;
80//! let mut hoomd_gsd_file = HoomdGsdFile::open(path)?;
81//! hoomd_gsd_file
82//! .append_frame(2000)?
83//! .configuration_box([105.0, 48.0, 72.0, 0.0, 0.0, 0.0])?
84//! .particles_position([
85//! [2.0, 3.0, -1.0].into(),
86//! [18.0, 4.0, -6.0].into(),
87//! ]);
88//! # Ok(())
89//! # }
90//! ```
91//!
92//! [`Frame`]: hoomd::Frame
93//! [`append_frame`]: hoomd::HoomdGsdFile::append_frame
94//! [`open`]: hoomd::HoomdGsdFile::open
95//!
96//! ## The file layer
97//!
98//! [`GsdFile`](file_layer::GsdFile) provides direct access to read and write GSD
99//! formatted files. Call [`create_new`](file_layer::GsdFile::create_new) to create
100//! a new GSD file:
101//!
102//! ```
103//! use hoomd_gsd::file_layer::GsdFile;
104//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
105//! # use tempfile::tempdir;
106//! # let tmp_dir = tempdir().expect("temp dir should be created");
107//! # let path = tmp_dir.path().join("test.gsd");
108//! // let path = "file.gsd";
109//! let mut gsd_file = GsdFile::create_new(path, "example", "hoomd", (1, 4))?;
110//! # Ok(())
111//! # }
112//! ```
113//!
114//! Add new arrays to the current frame with
115//! [`write_scalars`](file_layer::GsdFile::write_scalars) and
116//! [`write_arrays`](file_layer::GsdFile::write_arrays). You **must** end the frame
117//! with [`end_frame`](file_layer::GsdFile::end_frame) or no data will be written to
118//! the file!
119//! ```
120//! use hoomd_gsd::file_layer::GsdFile;
121//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
122//! # use tempfile::tempdir;
123//! # let tmp_dir = tempdir().expect("temp dir should be created");
124//! # let path = tmp_dir.path().join("test.gsd");
125//! let position = vec![[5.0_f32, 3.0, -4.0], [-2.0, 3.0, -6.0]];
126//!
127//! let mut gsd_file = GsdFile::create_new(path, "example", "hoomd", (1, 4))?;
128//! gsd_file.write_scalars("configuration/step", [100_000_u64])?;
129//! gsd_file.write_scalars(
130//! "configuration/box",
131//! [10.0_f32, 20.0, 15.0, 0.0, 0.0, 0.0],
132//! )?;
133//! gsd_file.write_arrays("particles/position", position.iter().copied())?;
134//! gsd_file.end_frame()?;
135//! # Ok(())
136//! # }
137//! ```
138//! Each array in the file in stored in a specific type. `write_scalars` and
139//! `write_arrays` automatically infer that type from the argument given.
140//!
141//! # Complete documentation
142//!
143//! `hoomd-gsd` is is a part of *hoomd-rs*. Read the [complete documentation]
144//! for more information.
145//!
146//! [complete documentation]: https://hoomd-rs.readthedocs.io
147
148pub mod file_layer;
149pub mod hoomd;