Skip to main content

atfits_rs/
pixel.rs

1//! Pixel precision and monomorphic cfitsio section I/O.
2use fitsio::FitsFile;
3
4use crate::error::Result;
5
6/// Pixel precision a cube is read/written in, derived from FITS `BITPIX`.
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub enum PixelType {
9    F32,
10    F64,
11}
12
13impl PixelType {
14    /// `-64` → f64; everything else (`-32` and integer BITPIX) → f32, matching
15    /// the working precision of the original tools.
16    pub fn from_bitpix(bitpix: i64) -> Self {
17        if bitpix == -64 {
18            PixelType::F64
19        } else {
20            PixelType::F32
21        }
22    }
23}
24
25/// Pixel element types a plane can be streamed in: `f32` or `f64`.
26///
27/// Bundles the cfitsio section read/write so a streaming pipeline can be generic
28/// over precision while keeping the cfitsio calls monomorphic.
29pub trait CubeElem: Copy + Send + Sync + 'static {
30    /// FITS `BITPIX` written for this element type.
31    const BITPIX: i64;
32    fn read_full(fptr: &mut FitsFile) -> Result<Vec<Self>>;
33    fn read_section(fptr: &mut FitsFile, start: usize, end: usize) -> Result<Vec<Self>>;
34    fn write_section(fptr: &mut FitsFile, start: usize, end: usize, data: &[Self]) -> Result<()>;
35}
36
37macro_rules! impl_cube_elem {
38    ($t:ty, $bitpix:expr) => {
39        impl CubeElem for $t {
40            const BITPIX: i64 = $bitpix;
41            fn read_full(fptr: &mut FitsFile) -> Result<Vec<Self>> {
42                let hdu = fptr.primary_hdu()?;
43                Ok(hdu.read_image(fptr)?)
44            }
45            fn read_section(fptr: &mut FitsFile, start: usize, end: usize) -> Result<Vec<Self>> {
46                let hdu = fptr.primary_hdu()?;
47                Ok(hdu.read_section(fptr, start, end)?)
48            }
49            fn write_section(
50                fptr: &mut FitsFile,
51                start: usize,
52                end: usize,
53                data: &[Self],
54            ) -> Result<()> {
55                let hdu = fptr.primary_hdu()?;
56                hdu.write_section(fptr, start, end, data)?;
57                Ok(())
58            }
59        }
60    };
61}
62impl_cube_elem!(f32, -32);
63impl_cube_elem!(f64, -64);