openslide/properties/
mod.rs

1//! Properties from various slides
2//!
3
4mod openslide;
5mod tiff;
6mod aperio;
7//mod hamamatsu;
8
9use std::collections::HashMap;
10
11use self::openslide::LevelProperties;
12
13/// This struct defines an inferface to the various properties of the various formats.
14///
15/// These properties are also available as a `HashMap<String, String>` which can be obtained with
16/// the `OpenSlide::get_properties()` method. However, this way of interacting with the property
17/// values is not ideal, hence this struct. Motivation:
18///
19///   - Get the values with fitting types in stead of Strings, ready to be used straight away.
20///   - Every property is easier to document.
21///   - More convenient naming (arguable).
22///
23/// Many formats implements openslide properties (`openslide.<property>` in the HashMap returned by
24/// the `OpenSlide::get_properties()` method), and many formats also implements some Tiff
25/// properties (`openslide.<property>` in the HashMap returned by the `OpenSlide::get_properties()`
26/// method). Then there are properties that are unique to each format (it may be the same
27/// properties, but with different naming conventions etc.). This interface gives the programmer
28/// access to all (known) properties (if some exists and are not implemented here, this is a bug).
29/// If some property does not exist for some slide, the method for this property returns `None`.
30/// What properties that are available to each slide is somewhat arbitrary (or, at least unknown to
31/// the author of this library per now), so in order to discover available properties, you can
32/// print the result of the `OpenSlide::get_properties()` method, or use the
33/// `Properties::print_available()` method (recommended).
34///
35#[derive(Clone, Debug)]
36pub struct Properties {
37    openslide_properties: openslide::OpenSlide,
38    tiff_properties: tiff::Tiff,
39    aperio_properties: aperio::Aperio,
40}
41
42impl Properties {
43
44    /// Initialises a new `Properties` struct.
45    ///
46    /// This is done by submitting a property_map, which is obtained from the
47    /// `OpenSlide::get_properties()` method, but this is abstracted away from the user, and
48    /// happens automatically when defining an `OpenSlide` struct.
49    pub fn new(property_map: &HashMap<String, String>) -> Self {
50        let mut tiff_properties = tiff::Tiff::default();
51        // Openslide properties requires special treatement because we need to find out how many
52        // levels there are in the initialization.
53        let mut openslide_properties = openslide::OpenSlide::new(property_map);
54        let mut aperio_properties = aperio::Aperio::default();
55
56        for (key, value) in property_map {
57            let parent = key.split('.').nth(0);
58            match parent {
59                Some("openslide") => openslide_properties.parse_property_name(key, value),
60                Some("tiff") => tiff_properties.parse_property_name(key, value),
61                Some("aperio") => aperio_properties.parse_property_name(key, value),
62                _ => println!("Could not parse {}", key),
63            }
64        }
65
66        Properties {
67            tiff_properties: tiff_properties,
68            openslide_properties: openslide_properties,
69            aperio_properties: aperio_properties,
70        }
71    }
72
73    /// Print available properties (key, value) (where the value is not `None`).
74    ///
75    /// # OpenSlide properties
76    pub fn print_available(&self) {
77        self.openslide_properties.print_available();
78        self.tiff_properties.print_available();
79        self.aperio_properties.print_available();
80    }
81
82    // Openslide properties (the markdown header is on the method above)
83
84    /// Slide vendor
85    pub fn vendor(&self) -> Option<String> {
86        self.openslide_properties.vendor.clone()
87    }
88
89    /// Quickhash 1
90    pub fn quickhash_1(&self) -> Option<String> {
91        self.openslide_properties.quickhash_1.clone()
92    }
93
94    /// Micrometer (microns) per pixel in the x direction.
95    pub fn mpp_x(&self) -> Option<f32> {
96        // TODO: Replace x / y direction with horisontal / vertical in documentation
97        self.openslide_properties.mpp_x
98    }
99
100    /// Micrometer (microns) per pixel in the y direction.
101    pub fn mpp_y(&self) -> Option<f32> {
102        // TODO: Replace x / y direction with horisontal / vertical in documentation
103        self.openslide_properties.mpp_y
104    }
105
106    /// Objective power
107    pub fn objective_power(&self) -> Option<u32> {
108        self.openslide_properties.objective_power
109    }
110
111    /// Comment
112    pub fn comment(&self) -> Option<String> {
113        self.openslide_properties.comment.clone()
114    }
115
116    /// Number of zoom levels
117    pub fn level_count(&self) -> Option<u32> {
118        self.openslide_properties.level_count
119    }
120
121    /// Vector of level-dependent properties. The position in the returned vector corresponds to
122    /// the zoom level.
123    ///
124    /// # Tiff properties
125    pub fn levels(&self) -> Option<Vec<LevelProperties>> {
126        self.openslide_properties.levels.clone()
127    }
128
129    // Tiff properties (the markdown header is on the method above)
130
131    pub fn image_description(&self) -> Option<String> {
132        self.tiff_properties.image_description.clone()
133    }
134
135    pub fn software(&self) -> Option<String> {
136        self.tiff_properties.software.clone()
137    }
138
139    /// Model name
140    pub fn model(&self) -> Option<String> {
141        self.tiff_properties.model.clone()
142    }
143
144    pub fn date_time(&self) -> Option<String> {
145        self.tiff_properties.date_time.clone()
146    }
147
148    pub fn make(&self) -> Option<String> {
149        self.tiff_properties.make.clone()
150    }
151
152    /// Resolution in the x direction
153    pub fn x_resolution(&self) -> Option<f32> {
154        // TODO: Replace x / y direction with horisontal / vertical in documentation
155        self.tiff_properties.x_resolution
156    }
157
158    /// Resolution in the y direction
159    pub fn y_resolution(&self) -> Option<f32> {
160        // TODO: Replace x / y direction with horisontal / vertical in documentation
161        self.tiff_properties.y_resolution
162    }
163
164    /// Resolution unit (e.g. centimeter or inch)
165    ///
166    /// # Aperio properties
167    pub fn resolution_unit(&self) -> Option<String> {
168        self.tiff_properties.resolution_unit.clone()
169    }
170
171    // Aperio properties (the markdown header is on the method above)
172
173    /// Slide filename
174    pub fn filename(&self) -> Option<String> {
175        self.aperio_properties.filename.clone()
176    }
177
178    /// Slide image id
179    pub fn image_id(&self) -> Option<String> {
180        self.aperio_properties.image_id.clone()
181    }
182
183    /// ScanScope id
184    pub fn scan_scope_id(&self) -> Option<String> {
185        self.aperio_properties.scan_scope_id.clone()
186    }
187
188    /// Date of creation (mm/dd/yy)
189    pub fn date(&self) -> Option<String> {
190        // TODO: Change this to a rust date type
191        self.aperio_properties.date.clone()
192    }
193
194    /// Time of creation (hh:mm:ss)
195    pub fn time(&self) -> Option<String> {
196        // TODO: Change this to a rust time type
197        self.aperio_properties.time.clone()
198    }
199
200    /// User
201    pub fn user(&self) -> Option<String> {
202        self.aperio_properties.user.clone()
203    }
204
205    /// ICC profile
206    pub fn icc_profile(&self) -> Option<String> {
207        self.aperio_properties.icc_profile.clone()
208    }
209
210    /// Parmset
211    pub fn parmset(&self) -> Option<String> {
212        self.aperio_properties.parmset.clone()
213    }
214
215    /// Slide height
216    pub fn original_height(&self) -> Option<u32> {
217        self.aperio_properties.original_height
218    }
219
220    /// Slide width
221    pub fn original_width(&self) -> Option<u32> {
222        self.aperio_properties.original_height
223    }
224
225    pub fn top(&self) -> Option<f32> {
226        self.aperio_properties.top
227    }
228
229    pub fn left(&self) -> Option<f32> {
230        self.aperio_properties.left
231    }
232
233    /// Micrometer per pixel
234    pub fn mpp(&self) -> Option<f32> {
235        self.aperio_properties.mpp
236    }
237
238    /// Line camera skew
239    pub fn line_camera_skew(&self) -> Option<f32> {
240        self.aperio_properties.line_camera_skew
241    }
242
243    /// Line area offset in horizontal(?) direction
244    pub fn line_area_x_offset(&self) -> Option<f32> {
245        self.aperio_properties.line_area_x_offset
246    }
247
248    /// Line area offset in vertical(?) direction
249    pub fn line_area_y_offset(&self) -> Option<f32> {
250        self.aperio_properties.line_area_y_offset
251    }
252
253    /// Focus offset
254    pub fn focus_offset(&self) -> Option<f32> {
255        self.aperio_properties.focus_offset
256    }
257
258    pub fn app_mag(&self) -> Option<u32> {
259        self.aperio_properties.app_mag
260    }
261
262    /// Scan stripe width
263    pub fn stripe_width(&self) -> Option<u32> {
264        self.aperio_properties.stripe_width
265    }
266
267    pub fn filtered(&self) -> Option<u32> {
268        self.aperio_properties.filtered
269    }
270}