1use std::path::Path;
3
4use fitsio::FitsFile;
5
6use crate::error::{AtfitsError, Result};
7
8#[derive(Debug, Clone)]
11pub struct HeaderGeom {
12 pub naxis: usize,
13 pub dims: Vec<usize>,
15 pub bitpix: i64,
16}
17
18impl HeaderGeom {
19 pub fn read(path: &Path) -> Result<Self> {
21 let mut fptr = FitsFile::open(path.to_string_lossy().as_ref())?;
22 let hdu = fptr.primary_hdu()?;
23 let naxis: i64 = hdu.read_key(&mut fptr, "NAXIS")?;
24 let bitpix: i64 = hdu.read_key(&mut fptr, "BITPIX")?;
25 let mut dims = Vec::with_capacity(naxis as usize);
26 for i in 1..=naxis {
27 let n: i64 = hdu.read_key(&mut fptr, &format!("NAXIS{i}"))?;
28 dims.push(n as usize);
29 }
30 Ok(Self {
31 naxis: naxis as usize,
32 dims,
33 bitpix,
34 })
35 }
36
37 pub fn is_2d(&self) -> bool {
39 self.naxis == 2
40 }
41
42 pub fn plane_len(&self) -> usize {
44 self.dims.first().copied().unwrap_or(1) * self.dims.get(1).copied().unwrap_or(1)
45 }
46}
47
48#[derive(Debug, Clone)]
50pub struct TargetAxis {
51 pub fits_idx: usize,
53 pub array_idx: usize,
55 pub ctype: String,
56 pub crpix: f64,
57 pub crval: f64,
58 pub cdelt: f64,
59 pub cunit: Option<String>,
60}
61
62pub fn find_target_axis(path: &Path, name: &str) -> Result<TargetAxis> {
66 let mut fptr = FitsFile::open(path.to_string_lossy().as_ref())?;
67 let hdu = fptr.primary_hdu()?;
68 let naxis: i64 = hdu.read_key(&mut fptr, "NAXIS")?;
69
70 for axis in 1..=naxis {
71 let ctype: String = match hdu.read_key(&mut fptr, &format!("CTYPE{axis}")) {
72 Ok(c) => c,
73 Err(_) => continue,
74 };
75 if ctype.contains(name) {
76 let crpix: f64 = hdu
77 .read_key(&mut fptr, &format!("CRPIX{axis}"))
78 .unwrap_or(1.0);
79 let crval: f64 = hdu
80 .read_key(&mut fptr, &format!("CRVAL{axis}"))
81 .unwrap_or(0.0);
82 let cdelt: f64 = hdu
83 .read_key(&mut fptr, &format!("CDELT{axis}"))
84 .unwrap_or(1.0);
85 let cunit: Option<String> = hdu.read_key(&mut fptr, &format!("CUNIT{axis}")).ok();
86 return Ok(TargetAxis {
87 fits_idx: axis as usize,
88 array_idx: (naxis - axis) as usize,
89 ctype,
90 crpix,
91 crval,
92 cdelt,
93 cunit,
94 });
95 }
96 }
97 Err(AtfitsError::TargetAxisMissing(format!(
98 "No {name} axis found in WCS of {}",
99 path.display()
100 )))
101}