Skip to main content

arcsec_core/catalog/
mod.rs

1//! Star catalogue readers: ASTAP `.1476`/`.290`/`.001` databases and
2//! Astrometry.net index files, plus the sky tilings used to find the right files.
3
4pub mod anet;
5pub mod areas;
6pub mod areas_290;
7pub mod format_001;
8pub mod format_1476;
9
10pub use anet::{AnetIndex, AnetIndexEntry, AnetStar, load_anet_index, peek_anet_scale};
11pub use areas::{DEC_BOUNDARIES_1476, area_and_boundaries_1476, filename_1476, find_areas_1476};
12pub use areas_290::{DEC_BOUNDARIES_290, area_nr_290, filename_290, find_areas_290};
13pub use format_001::read_001_file;
14pub use format_1476::{
15    CatalogLayout, CatalogStar, catalog_present, detect_layout, for_each_star_in_dec_band,
16    read_area_file, read_catalog_stars,
17};
18
19/// The star density, in stars per square degree, that the database `db_name` is
20/// built to, or `None` if it is not known.
21///
22/// ASTAP's databases are density-limited: every tile holds the brightest Gaia stars
23/// up to a fixed number per square degree, and ASTAP reads that number from the
24/// name, two digits times 100 (`d80` 8000, `d50` 5000, `d20` 2000, `d05`, `v05` and
25/// `g05` 500, `v50` 5000). The exceptions are the old 17/18 databases, which were
26/// magnitude-limited (no figure), and `w08`, whose digits are its magnitude limit,
27/// 8: its single all-sky file holds 41 265 stars, one per square degree.
28///
29/// A field can hold no more catalogue stars than this density times its area, so
30/// detecting more image stars than that only adds patterns that cannot match.
31#[must_use]
32pub fn database_density(db_name: &str) -> Option<f64> {
33    let name = db_name.to_ascii_lowercase();
34    if name == "w08" {
35        return Some(1.0);
36    }
37    let n: u32 = name.get(1..3)?.parse().ok()?;
38    match n {
39        0 | 17 | 18 => None,
40        n => Some(f64::from(n) * 100.0),
41    }
42}
43
44#[cfg(test)]
45mod density_tests {
46    use super::database_density;
47
48    #[test]
49    fn densities_follow_the_database_names() {
50        for (name, want) in [
51            ("d80", Some(8000.0)),
52            ("D50", Some(5000.0)),
53            ("d20", Some(2000.0)),
54            ("d05", Some(500.0)),
55            ("v50", Some(5000.0)),
56            ("v05", Some(500.0)),
57            ("g05", Some(500.0)),
58            ("w08", Some(1.0)),
59            ("t50", Some(5000.0)),
60            ("v17", None),
61            ("g18", None),
62            ("x", None),
63            ("", None),
64            ("dxx", None),
65        ] {
66            assert_eq!(database_density(name), want, "{name}");
67        }
68    }
69}