12次发布
0.2.11 | 2024年7月19日 |
---|---|
0.2.10 | 2024年7月18日 |
0.2.9 | 2023年5月22日 |
0.2.7 | 2023年4月25日 |
0.1.1 | 2023年1月4日 |
#42 in 科学
369 每月下载量
在 wcs 中使用
150KB
3K SLoC
使用nom编写的纯Rust编写的FITS读取器
此crate正在开发中,它最初是为了读取fits HiPS瓦片而发起的,即由hipsgen生成的。
此FITS解析器仅支持图像数据(不支持表格),并且不了解WCS解析。对于WCS解析,请参阅wcsrs。此解析器能够解析扩展HDUs。ASCII表格和二进制表格尚未正确解析,只能检索其数据块的列表字节,但不对它进行解释/解析。
待办事项列表
- 支持单类型数据块(即图像类型数据)
- 单个HDU解析,头和数据单元
- 支持大FITS文件解析,可能无法放入内存(迭代器使用)
- 异步读取(实验性和未测试)
- 保留CARD注释
- 支持数据表(每列可以具有特定的类型)
- 支持多个HDU,FITS扩展(进行中,仅解析头)
- WCS解析,请参阅wcsrs
示例
对于可放入内存的文件
use fitsrs::{
fits::Fits,
hdu::{
data::InMemData,
extension::XtensionHDU
}
};
use std::fs::File;
use std::io::Cursor;
let mut f = File::open("samples/fits.gsfc.nasa.gov/EUVE.fits").unwrap();
let mut buf = Vec::new();
f.read_to_end(&mut buf).unwrap();
let mut reader = Cursor::new(&buf[..]);
let Fits { hdu } = Fits::from_reader(&mut reader).unwrap();
// Access the HDU extensions
let mut hdu_ext = hdu.next();
while let Ok(Some(hdu)) = hdu_ext {
match &hdu {
XtensionHDU::Image(xhdu) => {
let xtension = xhdu.get_header().get_xtension();
let naxis1 = *xtension.get_naxisn(1).unwrap() as usize;
let naxis2 = *xtension.get_naxisn(2).unwrap() as usize;
let num_pixels = naxis2 * naxis1;
match xhdu.get_data() {
InMemData::U8(mem) => assert_eq!(num_pixels, mem.len()),
InMemData::I16(mem) => assert_eq!(num_pixels, mem.len()),
InMemData::I32(mem) => assert_eq!(num_pixels, mem.len()),
InMemData::I64(mem) => assert_eq!(num_pixels, mem.len()),
InMemData::F32(mem) => assert_eq!(num_pixels, mem.len()),
InMemData::F64(mem) => assert_eq!(num_pixels, mem.len()),
}
},
XtensionHDU::BinTable(xhdu) => {
let num_bytes = xhdu.get_header()
.get_xtension()
.get_num_bytes_data_block();
match xhdu.get_data() {
InMemData::U8(mem) => assert_eq!(num_bytes as usize, mem.len()),
_ => unreachable!()
}
},
XtensionHDU::AsciiTable(xhdu) => {
let num_bytes = xhdu.get_header()
.get_xtension()
.get_num_bytes_data_block();
match xhdu.get_data() {
InMemData::U8(mem) => assert_eq!(num_bytes as usize, mem.len()),
_ => unreachable!()
}
},
}
hdu_ext = hdu.next();
}
对于可能无法放入内存的文件
use fitsrs::{
fits::Fits,
hdu::{
data::iter,
extension::XtensionHDU
}
};
use std::fs::File;
use std::io::{BufReader, Read};
let f = File::open("samples/fits.gsfc.nasa.gov/EUVE.fits").unwrap();
let mut reader = BufReader::new(f);
let Fits { hdu } = Fits::from_reader(&mut reader).unwrap();
let mut hdu_ext = hdu.next();
while let Ok(Some(mut xhdu)) = hdu_ext {
match &mut xhdu {
XtensionHDU::Image(xhdu) => {
let xtension = xhdu.get_header().get_xtension();
let naxis1 = *xtension.get_naxisn(1).unwrap();
let naxis2 = *xtension.get_naxisn(2).unwrap();
let num_pixels = (naxis2 * naxis1) as usize;
match xhdu.get_data_mut() {
iter::Data::U8(it) => {
let data = it.collect::<Vec<_>>();
assert_eq!(num_pixels, data.len())
},
iter::Data::I16(it) => {
let data = it.collect::<Vec<_>>();
assert_eq!(num_pixels, data.len())
},
iter::Data::I32(it) => {
let data = it.collect::<Vec<_>>();
assert_eq!(num_pixels, data.len())
},
iter::Data::I64(it) => {
let data = it.collect::<Vec<_>>();
assert_eq!(num_pixels, data.len())
},
iter::Data::F32(it) => {
let data = it.collect::<Vec<_>>();
assert_eq!(num_pixels, data.len())
},
iter::Data::F64(it) => {
let data = it.collect::<Vec<_>>();
assert_eq!(num_pixels, data.len())
},
}
},
XtensionHDU::BinTable(xhdu) => {
let num_bytes = xhdu.get_header()
.get_xtension()
.get_num_bytes_data_block();
let it_bytes = xhdu.get_data_mut();
let data = it_bytes.collect::<Vec<_>>();
assert_eq!(num_bytes as usize, data.len());
},
XtensionHDU::AsciiTable(xhdu) => {
let num_bytes = xhdu.get_header()
.get_xtension()
.get_num_bytes_data_block();
let it_bytes = xhdu.get_data_mut();
let data = it_bytes.collect::<Vec<_>>();
assert_eq!(num_bytes as usize, data.len());
},
}
hdu_ext = xhdu.next();
}
对于异步输入读取器
use fitsrs::{
fits::AsyncFits,
hdu::{
data::stream,
extension::AsyncXtensionHDU
}
};
// reader needs to implement futures::io::AsyncRead
let AsyncFits { hdu } = AsyncFits::from_reader(&mut reader).await.unwrap();
let mut hdu_ext = hdu.next().await;
while let Ok(Some(mut xhdu)) = hdu_ext {
match &mut xhdu {
AsyncXtensionHDU::Image(xhdu) => {
let xtension = xhdu.get_header().get_xtension();
let naxis1 = *xtension.get_naxisn(1).unwrap() as usize;
let naxis2 = *xtension.get_naxisn(2).unwrap() as usize;
let num_pixels = naxis2 * naxis1;
match xhdu.get_data_mut() {
stream::Data::U8(st) => {
let data = st.collect::<Vec<_>>().await;
assert_eq!(num_pixels, data.len())
},
stream::Data::I16(st) => {
let data = st.collect::<Vec<_>>().await;
assert_eq!(num_pixels, data.len())
},
stream::Data::I32(st) => {
let data = st.collect::<Vec<_>>().await;
assert_eq!(num_pixels, data.len())
},
stream::Data::I64(st) => {
let data = st.collect::<Vec<_>>().await;
assert_eq!(num_pixels, data.len())
},
stream::Data::F32(st) => {
let data = st.collect::<Vec<_>>().await;
assert_eq!(num_pixels, data.len())
},
stream::Data::F64(st) => {
let data = st.collect::<Vec<_>>().await;
assert_eq!(num_pixels, data.len())
},
}
},
AsyncXtensionHDU::BinTable(xhdu) => {
let num_bytes = xhdu.get_header()
.get_xtension()
.get_num_bytes_data_block();
let it_bytes = xhdu.get_data_mut();
let data = it_bytes.collect::<Vec<_>>().await;
assert_eq!(num_bytes as usize, data.len());
},
AsyncXtensionHDU::AsciiTable(xhdu) => {
let num_bytes = xhdu.get_header()
.get_xtension()
.get_num_bytes_data_block();
let it_bytes = xhdu.get_data_mut();
let data = it_bytes.collect::<Vec<_>>().await;
assert_eq!(num_bytes as usize, data.len());
},
}
hdu_ext = xhdu.next().await;
}
依赖项
~2.2–3.5MB
~69K SLoC