dotthz/
lib.rs

1//! Crate to load and save dotThz files in Rust.
2#![allow(dead_code)]
3#![deny(missing_docs)]
4#![deny(warnings)]
5
6mod dotthz;
7pub use dotthz::{DotthzFile, DotthzMetaData};
8
9#[cfg(test)]
10mod tests {
11    use super::*;
12    use dotthz::{DotthzFile, DotthzMetaData};
13    use hdf5::Dataset;
14    use ndarray::{array, Array2};
15    use std::path::PathBuf;
16    use tempfile::NamedTempFile;
17
18    fn assert_datasets_equal(
19        ds1: &Dataset,
20        ds2: &Dataset,
21    ) -> Result<(), Box<dyn std::error::Error>> {
22        let data1: Vec<f32> = ds1.read_raw()?;
23        let data2: Vec<f32> = ds2.read_raw()?;
24        assert_eq!(data1, data2, "Dataset contents differ");
25
26        let shape1 = ds1.shape();
27        let shape2 = ds2.shape();
28        assert_eq!(shape1, shape2, "Dataset shapes differ");
29
30        Ok(())
31    }
32
33    #[test]
34    fn test_copy_and_compare_dotthz_files() -> Result<(), Box<dyn std::error::Error>> {
35        for path in [
36            "test_files/PVDF_520um.thz",
37            "test_files/2_VariableTemperature.thz",
38            //   "test_files/image.thz",
39        ] {
40            // Path to an existing test HDF5 file (replace this with an actual test file path)
41            let original_file_path = PathBuf::from(path);
42
43            // Load data from the original file
44            let original_dotthz = DotthzFile::open(&original_file_path)?;
45
46            // Create a temporary file to save the copy
47            let temp_file = NamedTempFile::new()?;
48            let copy_file_path = temp_file.path().to_path_buf();
49
50            // Create the new temporary file
51            let mut output_dotthz = DotthzFile::create(&copy_file_path)?;
52
53            // Save the metadata to the new temporary file
54            let group_names = original_dotthz.get_group_names()?;
55            for group_name in group_names.iter() {
56                let group = original_dotthz.get_group(group_name)?;
57                let meta_data = original_dotthz.get_meta_data(&group.name())?;
58                output_dotthz.add_group(group_name, &meta_data)?;
59            }
60
61            // Save the data to the new temporary file
62            let group_names = output_dotthz.get_group_names()?;
63            for group_name in group_names.iter() {
64                for dataset_name in original_dotthz.get_dataset_names(group_name)? {
65                    let dataset = original_dotthz.get_dataset(group_name, &dataset_name)?;
66                    let data = dataset.read_dyn::<f32>()?;
67                    output_dotthz.add_dataset(group_name, &dataset_name, data.view())?;
68                }
69            }
70
71            // Load data from the new copy file
72            let copied_dotthz = DotthzFile::open(&copy_file_path)?;
73
74            for old_group in original_dotthz.get_groups()? {
75                let new_group = copied_dotthz.get_group(&old_group.name())?;
76                // Compare the original and copied metadata
77                assert_eq!(
78                    original_dotthz.get_meta_data(&old_group.name())?,
79                    copied_dotthz.get_meta_data(&new_group.name())?
80                );
81            }
82
83            let group_names = output_dotthz.get_group_names()?;
84            for group_name in group_names.iter() {
85                for dataset_name in output_dotthz.get_dataset_names(group_name)? {
86                    let old_dataset = original_dotthz.get_dataset(group_name, &dataset_name)?;
87                    let new_dataset = copied_dotthz.get_dataset(group_name, &dataset_name)?;
88
89                    // Compare the original and copied datasets
90                    assert_eq!(old_dataset.shape(), new_dataset.shape());
91                    assert_datasets_equal(&old_dataset, &new_dataset)?;
92                }
93            }
94        }
95
96        Ok(())
97    }
98
99    #[test]
100    fn test_dotthz_save_and_load() -> Result<(), Box<dyn std::error::Error>> {
101        // Create temporary file to act as virtual storage
102        let temp_file = NamedTempFile::new()?;
103        let path: PathBuf = temp_file.path().to_path_buf();
104
105        // Initialize test metadata and data
106        let meta_data = DotthzMetaData {
107            user: "Test User".to_string(),
108            email: "test@example.com".to_string(),
109            orcid: "0000-0001-2345-6789".to_string(),
110            institution: "Test Institute".to_string(),
111            description: "Test description".to_string(),
112            md: [("Thickness (mm)".to_string(), "0.52".to_string())]
113                .into_iter()
114                .collect(),
115            ds_description: vec!["ds1".to_string()],
116            version: "1.0".to_string(),
117            mode: "Test mode".to_string(),
118            instrument: "Test instrument".to_string(),
119            time: "12:34:56".to_string(),
120            date: "2024-11-08".to_string(),
121        };
122
123        // Initialize a dataset
124        let mut original_dotthz = DotthzFile::create(&path)?;
125        let group_name = "Measurement".to_string();
126        original_dotthz.add_group(&group_name, &meta_data)?;
127
128        let dataset_name = "test_dataset".to_string();
129        let dataset_data: Array2<f32> = array![[1.0, 2.0], [3.0, 4.0], [3.0, 4.0]];
130
131        original_dotthz.add_dataset(&group_name, &dataset_name, dataset_data.view())?;
132
133        // Load data from the new copy file
134        let copied_dotthz = DotthzFile::open(&path)?;
135
136        for (old_group, new_group) in original_dotthz
137            .get_groups()?
138            .iter()
139            .zip(copied_dotthz.get_groups()?.iter())
140        {
141            // Compare the original and copied metadata
142            assert_eq!(
143                original_dotthz.get_meta_data(&old_group.name())?,
144                copied_dotthz.get_meta_data(&new_group.name())?
145            );
146        }
147
148        let group_names = original_dotthz.get_group_names()?;
149        for group_name in group_names.iter() {
150            for dataset_name in original_dotthz.get_dataset_names(group_name)? {
151                let old_dataset = original_dotthz.get_dataset(group_name, &dataset_name)?;
152                let new_dataset = copied_dotthz.get_dataset(group_name, &dataset_name)?;
153
154                // Compare the original and copied datasets
155                assert_eq!(old_dataset.shape(), new_dataset.shape());
156                assert_datasets_equal(&old_dataset, &new_dataset)?;
157            }
158        }
159
160        Ok(())
161    }
162}