Skip to content

Commit 54e6f92

Browse files
committed
Add methods to write explicit skymap without building the BTreeMap
1 parent c0a0f8b commit 54e6f92

4 files changed

Lines changed: 97 additions & 10 deletions

File tree

src/nested/iter/sortedhash2hashcount.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -255,10 +255,10 @@ where
255255

256256
#[cfg(test)]
257257
mod tests {
258-
use super::*;
259-
use crate::depth;
260258
use std::iter;
261259

260+
use super::*;
261+
262262
#[test]
263263
fn test_count_iterators_ok() {
264264
// Test coutn from empty iterators

src/nested/map/fits/write.rs

Lines changed: 93 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,37 @@ where
9494
}
9595
write_final_padding(writer, n_elems * naxis1)
9696
}
97+
// Made for python wrapper
98+
pub fn write_explicit_skymap_fits_from_parts<R, K, V>(
99+
mut writer: R,
100+
depth: u8,
101+
n_elems: usize,
102+
it_keys: K,
103+
it_vals: V,
104+
) -> Result<(), FitsError>
105+
where
106+
R: Write,
107+
K: Iterator<Item = u64>,
108+
V: Iterator,
109+
V::Item: SkyMapValue,
110+
{
111+
let naxis1 = (<u64 as HHash>::FITS_NAXIS1 + V::Item::FITS_NAXIS1) as usize;
112+
write_explicit_skymap_fits_header_from_parts::<_, u64, V::Item>(&mut writer, depth, n_elems)?;
113+
let mut n = 0;
114+
for (h, v) in it_keys.zip(it_vals) {
115+
writer
116+
.write_all(h.to_be_bytes().as_ref())
117+
.and_then(|()| writer.write_all(v.to_be_bytes().as_ref()))?;
118+
n += 1;
119+
}
120+
if n != n_elems {
121+
return Err(FitsError::new_custom(format!(
122+
"Wrong number of HEALPix cells writen at depth {}. Expected: {}. Actual: {}.",
123+
depth, n_elems, n
124+
)));
125+
}
126+
write_final_padding(writer, n_elems * naxis1)
127+
}
97128

98129
/// Possible add blanks at the end of the FITS file to complete the last
99130
/// 2880 bytes block.
@@ -216,15 +247,12 @@ fn write_implicit_skymap_fits_header<R: Write, T: SkyMapValue>(
216247
writer.write_all(&header_block[..]).map_err(FitsError::Io)
217248
}
218249

219-
fn write_explicit_skymap_fits_header<'a, R, S>(
220-
mut writer: R,
221-
skymap: &'a S,
222-
) -> Result<(), FitsError>
250+
fn write_explicit_skymap_fits_header<'a, R, S>(writer: R, skymap: &'a S) -> Result<(), FitsError>
223251
where
224252
R: Write,
225253
S: SkyMap<'a>,
226254
{
227-
let nside = nside(skymap.depth());
255+
/*let nside = nside(skymap.depth());
228256
let n_cells = skymap.len() as u64;
229257
230258
write_primary_hdu(&mut writer)?;
@@ -267,5 +295,65 @@ where
267295
);
268296
it.next().unwrap()[0..3].copy_from_slice(b"END");
269297
// Do write the header
298+
writer.write_all(&header_block[..]).map_err(FitsError::Io)*/
299+
write_explicit_skymap_fits_header_from_parts::<_, S::HashType, S::ValueType>(
300+
writer,
301+
skymap.depth(),
302+
skymap.len(),
303+
)
304+
}
305+
fn write_explicit_skymap_fits_header_from_parts<R, K, V>(
306+
mut writer: R,
307+
depth: u8,
308+
n_elems: usize,
309+
) -> Result<(), FitsError>
310+
where
311+
R: Write,
312+
K: HHash,
313+
V: SkyMapValue,
314+
{
315+
let nside = nside(depth);
316+
let n_cells = n_elems as u64;
317+
318+
write_primary_hdu(&mut writer)?;
319+
let mut header_block = [b' '; 2880];
320+
let mut it = header_block.chunks_mut(80);
321+
// Write BINTABLE specific keywords in the buffer
322+
it.next().unwrap()[0..20].copy_from_slice(b"XTENSION= 'BINTABLE'");
323+
it.next().unwrap()[0..30].copy_from_slice(b"BITPIX = 8");
324+
it.next().unwrap()[0..30].copy_from_slice(b"NAXIS = 2");
325+
write_uint_mandatory_keyword_record(
326+
it.next().unwrap(),
327+
b"NAXIS1 ",
328+
(K::FITS_NAXIS1 + V::FITS_NAXIS1) as u64,
329+
);
330+
write_uint_mandatory_keyword_record(it.next().unwrap(), b"NAXIS2 ", n_cells);
331+
it.next().unwrap()[0..30].copy_from_slice(b"PCOUNT = 0");
332+
it.next().unwrap()[0..30].copy_from_slice(b"GCOUNT = 1");
333+
it.next().unwrap()[0..30].copy_from_slice(b"TFIELDS = 2");
334+
it.next().unwrap()[0..20].copy_from_slice(b"TTYPE1 = 'PIXEL '");
335+
it.next().unwrap()[0..20].copy_from_slice(b"TTYPE2 = 'VALUE '");
336+
write_str_mandatory_keyword_record(it.next().unwrap(), b"TFORM1 ", K::FITS_TFORM);
337+
write_str_mandatory_keyword_record(it.next().unwrap(), b"TFORM2 ", V::FITS_TFORM);
338+
it.next().unwrap()[0..20].copy_from_slice(b"PIXTYPE = 'HEALPIX '");
339+
it.next().unwrap()[0..20].copy_from_slice(b"INDXSCHM= 'EXPLICIT'");
340+
it.next().unwrap()[0..20].copy_from_slice(b"ORDERING= 'NESTED '");
341+
it.next().unwrap()[0..20].copy_from_slice(b"COORDSYS= 'C '");
342+
it.next().unwrap()[0..20].copy_from_slice(b"EXTNAME = 'xtension'");
343+
write_uint_mandatory_keyword_record(it.next().unwrap(), b"NSIDE ", nside as u64);
344+
write_uint_mandatory_keyword_record(it.next().unwrap(), b"OBS_NPIX", n_cells);
345+
// it.next().unwrap()[0..28].copy_from_slice(b"CREATOR = 'CDS HEALPix Rust'");
346+
write_keyword_record(
347+
it.next().unwrap(),
348+
b"CREATOR ",
349+
format!(
350+
"'Rust crate {} {}'",
351+
env!("CARGO_PKG_NAME"),
352+
env!("CARGO_PKG_VERSION")
353+
)
354+
.as_str(),
355+
);
356+
it.next().unwrap()[0..3].copy_from_slice(b"END");
357+
// Do write the header
270358
writer.write_all(&header_block[..]).map_err(FitsError::Io)
271359
}

src/nested/map/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,6 @@ mod tests {
148148
fn test_read_skymap() {
149149
init_logger();
150150
let path = "test/resources/skymap/gaiadr3.nside64.densmap.fits";
151-
let skymap = SkyMapEnum::from_fits_file(path).unwrap();
151+
SkyMapEnum::from_fits_file(path).unwrap();
152152
}
153153
}

src/nested/mod.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5188,8 +5188,7 @@ mod tests {
51885188
#[test]
51895189
fn testok_cone_approx_bmoc_2() {
51905190
// From https://github.com/cds-astro/cds-healpix-rust/issues/21
5191-
let actual_res = cone_coverage_approx(1, 0.0, -0.3956593324046537, 0.00986851403158301);
5192-
5191+
//let actual_res = cone_coverage_approx(1, 0.0, -0.3956593324046537, 0.00986851403158301);
51935192
let actual_res = cone_coverage_approx(10, 0.0, 0.0, (5f64 / 3600.0).to_radians());
51945193
println!("@@@@@ FLAT VIEW");
51955194
for cell in actual_res.flat_iter() {

0 commit comments

Comments
 (0)