astro_rs/fits/
hdu_types.rs1use super::*;
4
5pub const TTYPE_KEYWORD: [u8; 8] = *b"TTYPE ";
7pub const TFORM_KEYWORD: [u8; 8] = *b"TFORM ";
9
10pub(crate) const DEFAULT_BITPIX_BYTES: [u8; 80] =
11 *b"BITPIX = 8 ";
12pub(crate) const DEFAULT_NAXIS_BYTES: [u8; 80] =
13 *b"NAXIS = 0 ";
14pub(crate) const DEFAULT_PCOUNT_BYTES: [u8; 80] =
15 *b"PCOUNT = 0 ";
16pub(crate) const DEFAULT_GCOUNT_BYTES: [u8; 80] =
17 *b"GCOUNT = 1 ";
18pub(crate) const DEFAULT_TFIELDS_BYTES: [u8; 80] =
19 *b"TFIELDS = 0 ";
20pub(crate) const DEFAULT_END_BYTES: [u8; 80] =
21 *b"END ";
22
23pub mod primary_hdu {
25 use super::*;
26
27 pub fn default() -> Hdu {
29 let simple_card = FitsHeaderCard::from(
30 *b"SIMPLE = T ",
31 );
32 let bitpix_card = FitsHeaderCard::from(DEFAULT_BITPIX_BYTES);
33 let naxis_card = FitsHeaderCard::from(DEFAULT_NAXIS_BYTES);
34 let end_card = FitsHeaderCard::from(DEFAULT_END_BYTES);
35 let header = FitsHeader {
36 cards: vec![simple_card, bitpix_card, naxis_card, end_card],
37 };
38
39 Hdu {
40 header,
41 ..Default::default()
42 }
43 }
44}
45
46pub mod ascii_table_hdu {
48 use super::*;
49
50 pub fn default() -> Hdu {
52 let xtension_card = FitsHeaderCard::from(
53 *b"XTENSION= 'TABLE ' ",
54 );
55 let bitpix_card = FitsHeaderCard::from(DEFAULT_BITPIX_BYTES);
56 let naxis_card = FitsHeaderCard::from(
57 *b"NAXIS = 2 ",
58 );
59 let naxis1_card = FitsHeaderCard::from(
60 *b"NAXIS1 = 0 ",
61 );
62 let naxis2_card = FitsHeaderCard::from(
63 *b"NAXIS2 = 0 ",
64 );
65 let pcount_card = FitsHeaderCard::from(DEFAULT_PCOUNT_BYTES);
66 let gcount_card = FitsHeaderCard::from(DEFAULT_GCOUNT_BYTES);
67 let tfields_card = FitsHeaderCard::from(DEFAULT_TFIELDS_BYTES);
68 let end_card = FitsHeaderCard::from(DEFAULT_END_BYTES);
69 let header = FitsHeader {
70 cards: vec![
71 xtension_card,
72 bitpix_card,
73 naxis_card,
74 naxis1_card,
75 naxis2_card,
76 pcount_card,
77 gcount_card,
78 tfields_card,
79 end_card,
80 ],
81 };
82
83 Hdu {
84 header,
85 ..Default::default()
86 }
87 }
88}
89
90pub mod image_hdu {
92 use super::*;
93
94 pub fn default() -> Hdu {
96 let xtension_card = FitsHeaderCard::from(
97 *b"XTENSION= 'IMAGE ' ",
98 );
99 let bitpix_card = FitsHeaderCard::from(DEFAULT_BITPIX_BYTES);
100 let naxis_card = FitsHeaderCard::from(DEFAULT_NAXIS_BYTES);
101 let pcount_card = FitsHeaderCard::from(DEFAULT_PCOUNT_BYTES);
102 let gcount_card = FitsHeaderCard::from(DEFAULT_GCOUNT_BYTES);
103 let end_card = FitsHeaderCard::from(DEFAULT_END_BYTES);
104 let header = FitsHeader {
105 cards: vec![
106 xtension_card,
107 bitpix_card,
108 naxis_card,
109 pcount_card,
110 gcount_card,
111 end_card,
112 ],
113 };
114
115 Hdu {
116 header,
117 ..Default::default()
118 }
119 }
120}
121
122pub mod binary_table_hdu {
124 use super::*;
125 use crate::fits::header_value::TForm;
126
127 pub fn default() -> Hdu {
129 let xtension_card = FitsHeaderCard::from(
130 *b"XTENSION= 'BINTABLE' ",
131 );
132 let bitpix_card = FitsHeaderCard::from(DEFAULT_BITPIX_BYTES);
133 let naxis_card = FitsHeaderCard::from(
134 *b"NAXIS = 2 ",
135 );
136 let naxis1_card = FitsHeaderCard::from(
137 *b"NAXIS1 = 0 ",
138 );
139 let naxis2_card = FitsHeaderCard::from(
140 *b"NAXIS2 = 0 ",
141 );
142 let pcount_card = FitsHeaderCard::from(DEFAULT_PCOUNT_BYTES);
143 let gcount_card = FitsHeaderCard::from(DEFAULT_GCOUNT_BYTES);
144 let tfields_card = FitsHeaderCard::from(DEFAULT_TFIELDS_BYTES);
145 let end_card = FitsHeaderCard::from(DEFAULT_END_BYTES);
146 let header = FitsHeader {
147 cards: vec![
148 xtension_card,
149 bitpix_card,
150 naxis_card,
151 naxis1_card,
152 naxis2_card,
153 pcount_card,
154 gcount_card,
155 tfields_card,
156 end_card,
157 ],
158 };
159
160 Hdu {
161 header,
162 ..Default::default()
163 }
164 }
165
166 pub fn column_by_name<T>(hdu: &mut Hdu, name: &str) -> Option<Vec<T>> {
168 let mut n = 1;
169 let mut column_start = 0;
170 let mut tform = None;
171 let mut naxis_keyword = NAXIS_KEYWORD;
172 naxis_keyword[5] = b'2';
173 let num_rows = *hdu
174 .header
175 .get_card(naxis_keyword)
176 .and_then(|card| card.get_value::<u32>().ok())
177 .unwrap_or_default() as usize;
178 naxis_keyword[5] = b'1';
179 let row_len = *hdu
180 .header
181 .get_card(naxis_keyword)
182 .and_then(|card| card.get_value::<u32>().ok())
183 .unwrap_or_default() as usize;
184 let mut tform_keyword = FitsHeaderKeyword::from(TFORM_KEYWORD);
185 let mut ttype_keyword = FitsHeaderKeyword::from(TTYPE_KEYWORD);
186 while n as usize <= num_rows {
187 tform_keyword.append_number(n);
188 if let Some(card) = hdu.header.get_card(tform_keyword) {
189 if let Ok(tform_value) = card.get_value::<TForm>() {
190 ttype_keyword.append_number(n);
191 if let Some(value) = hdu
192 .header
193 .get_card(ttype_keyword)
194 .and_then(|card| card.get_value::<String>().ok())
195 {
196 if value.eq_ignore_ascii_case(name) {
197 tform = Some(tform_value);
198 break;
199 }
200 }
201
202 column_start += tform_value.value();
203 }
204 n += 1;
205 } else {
206 break;
207 }
208 }
209 if let Some(tform) = tform {
210 return Some(*tform.create_column(hdu.data_raw(), column_start, row_len, num_rows));
211 }
212 None
213 }
214
215 pub fn column_by_index<T>(hdu: &mut Hdu, index: u16) -> Option<Vec<T>> {
218 let mut n = 1;
219 let mut column_start = 0;
220 let mut tform = None;
221 let mut naxis_keyword = NAXIS_KEYWORD;
222 naxis_keyword[5] = b'2';
223 let num_rows = *hdu
224 .header
225 .get_card(naxis_keyword)
226 .and_then(|card| card.get_value::<u32>().ok())
227 .unwrap_or_default() as usize;
228 if index as usize > num_rows {
229 return None;
230 }
231 naxis_keyword[5] = b'1';
232 let row_len = *hdu
233 .header
234 .get_card(naxis_keyword)
235 .and_then(|card| card.get_value::<u32>().ok())
236 .unwrap_or_default() as usize;
237 let mut tform_keyword = FitsHeaderKeyword::from(TFORM_KEYWORD);
238 while n <= index {
239 tform_keyword.append_number(n);
240 if let Some(card) = hdu.header.get_card(tform_keyword) {
241 if let Ok(value) = card.get_value::<TForm>() {
242 if n == index {
243 tform = Some(value);
244 } else {
245 column_start += value.value();
246 }
247 }
248 n += 1;
249 } else {
250 break;
251 }
252 }
253 if let Some(tform) = tform {
254 return Some(*tform.create_column(hdu.data_raw(), column_start, row_len, num_rows));
255 }
256 None
257 }
258}