use crate::datasets::gcat;
#[pyclass(name = "GCATSatcatRecord", from_py_object)]
#[derive(Clone)]
struct PyGCATSatcatRecord {
inner: gcat::GCATSatcatRecord,
}
#[pymethods]
impl PyGCATSatcatRecord {
#[getter]
fn jcat(&self) -> &str {
&self.inner.jcat
}
#[getter]
fn satcat(&self) -> Option<&str> {
self.inner.satcat.as_deref()
}
#[getter]
fn launch_tag(&self) -> Option<&str> {
self.inner.launch_tag.as_deref()
}
#[getter]
fn piece(&self) -> Option<&str> {
self.inner.piece.as_deref()
}
#[getter]
fn object_type(&self) -> Option<&str> {
self.inner.object_type.as_deref()
}
#[getter]
fn name(&self) -> Option<&str> {
self.inner.name.as_deref()
}
#[getter]
fn pl_name(&self) -> Option<&str> {
self.inner.pl_name.as_deref()
}
#[getter]
fn ldate(&self) -> Option<&str> {
self.inner.ldate.as_deref()
}
#[getter]
fn parent(&self) -> Option<&str> {
self.inner.parent.as_deref()
}
#[getter]
fn sdate(&self) -> Option<&str> {
self.inner.sdate.as_deref()
}
#[getter]
fn primary(&self) -> Option<&str> {
self.inner.primary.as_deref()
}
#[getter]
fn ddate(&self) -> Option<&str> {
self.inner.ddate.as_deref()
}
#[getter]
fn status(&self) -> Option<&str> {
self.inner.status.as_deref()
}
#[getter]
fn dest(&self) -> Option<&str> {
self.inner.dest.as_deref()
}
#[getter]
fn owner(&self) -> Option<&str> {
self.inner.owner.as_deref()
}
#[getter]
fn state(&self) -> Option<&str> {
self.inner.state.as_deref()
}
#[getter]
fn manufacturer(&self) -> Option<&str> {
self.inner.manufacturer.as_deref()
}
#[getter]
fn bus(&self) -> Option<&str> {
self.inner.bus.as_deref()
}
#[getter]
fn motor(&self) -> Option<&str> {
self.inner.motor.as_deref()
}
#[getter]
fn mass(&self) -> Option<f64> {
self.inner.mass
}
#[getter]
fn mass_flag(&self) -> Option<&str> {
self.inner.mass_flag.as_deref()
}
#[getter]
fn dry_mass(&self) -> Option<f64> {
self.inner.dry_mass
}
#[getter]
fn dry_flag(&self) -> Option<&str> {
self.inner.dry_flag.as_deref()
}
#[getter]
fn tot_mass(&self) -> Option<f64> {
self.inner.tot_mass
}
#[getter]
fn tot_flag(&self) -> Option<&str> {
self.inner.tot_flag.as_deref()
}
#[getter]
fn length(&self) -> Option<f64> {
self.inner.length
}
#[getter]
fn length_flag(&self) -> Option<&str> {
self.inner.length_flag.as_deref()
}
#[getter]
fn diameter(&self) -> Option<f64> {
self.inner.diameter
}
#[getter]
fn diameter_flag(&self) -> Option<&str> {
self.inner.diameter_flag.as_deref()
}
#[getter]
fn span(&self) -> Option<f64> {
self.inner.span
}
#[getter]
fn span_flag(&self) -> Option<&str> {
self.inner.span_flag.as_deref()
}
#[getter]
fn shape(&self) -> Option<&str> {
self.inner.shape.as_deref()
}
#[getter]
fn odate(&self) -> Option<&str> {
self.inner.odate.as_deref()
}
#[getter]
fn perigee(&self) -> Option<f64> {
self.inner.perigee
}
#[getter]
fn perigee_flag(&self) -> Option<&str> {
self.inner.perigee_flag.as_deref()
}
#[getter]
fn apogee(&self) -> Option<f64> {
self.inner.apogee
}
#[getter]
fn apogee_flag(&self) -> Option<&str> {
self.inner.apogee_flag.as_deref()
}
#[getter]
fn inc(&self) -> Option<f64> {
self.inner.inc
}
#[getter]
fn inc_flag(&self) -> Option<&str> {
self.inner.inc_flag.as_deref()
}
#[getter]
fn op_orbit(&self) -> Option<&str> {
self.inner.op_orbit.as_deref()
}
#[getter]
fn oqual(&self) -> Option<&str> {
self.inner.oqual.as_deref()
}
#[getter]
fn alt_names(&self) -> Option<&str> {
self.inner.alt_names.as_deref()
}
fn __repr__(&self) -> String {
format!(
"GCATSatcatRecord(jcat='{}', satcat={}, name={})",
self.inner.jcat,
self.inner
.satcat
.as_ref()
.map(|s| format!("'{}'", s))
.unwrap_or_else(|| "None".to_string()),
self.inner
.name
.as_ref()
.map(|s| format!("'{}'", s))
.unwrap_or_else(|| "None".to_string()),
)
}
}
#[pyclass(name = "GCATPsatcatRecord", from_py_object)]
#[derive(Clone)]
struct PyGCATPsatcatRecord {
inner: gcat::GCATPsatcatRecord,
}
#[pymethods]
impl PyGCATPsatcatRecord {
#[getter]
fn jcat(&self) -> &str {
&self.inner.jcat
}
#[getter]
fn piece(&self) -> Option<&str> {
self.inner.piece.as_deref()
}
#[getter]
fn name(&self) -> Option<&str> {
self.inner.name.as_deref()
}
#[getter]
fn ldate(&self) -> Option<&str> {
self.inner.ldate.as_deref()
}
#[getter]
fn tlast(&self) -> Option<&str> {
self.inner.tlast.as_deref()
}
#[getter]
fn top(&self) -> Option<&str> {
self.inner.top.as_deref()
}
#[getter]
fn tdate(&self) -> Option<&str> {
self.inner.tdate.as_deref()
}
#[getter]
fn tf(&self) -> Option<&str> {
self.inner.tf.as_deref()
}
#[getter]
fn program(&self) -> Option<&str> {
self.inner.program.as_deref()
}
#[getter]
fn plane(&self) -> Option<&str> {
self.inner.plane.as_deref()
}
#[getter]
fn att(&self) -> Option<&str> {
self.inner.att.as_deref()
}
#[getter]
fn mvr(&self) -> Option<&str> {
self.inner.mvr.as_deref()
}
#[getter(class_)]
fn class(&self) -> Option<&str> {
self.inner.class.as_deref()
}
#[getter]
fn category(&self) -> Option<&str> {
self.inner.category.as_deref()
}
#[getter]
fn result(&self) -> Option<&str> {
self.inner.result.as_deref()
}
#[getter]
fn control(&self) -> Option<&str> {
self.inner.control.as_deref()
}
#[getter]
fn discipline(&self) -> Option<&str> {
self.inner.discipline.as_deref()
}
#[getter]
fn un_state(&self) -> Option<&str> {
self.inner.un_state.as_deref()
}
#[getter]
fn un_reg(&self) -> Option<&str> {
self.inner.un_reg.as_deref()
}
#[getter]
fn un_period(&self) -> Option<f64> {
self.inner.un_period
}
#[getter]
fn un_perigee(&self) -> Option<f64> {
self.inner.un_perigee
}
#[getter]
fn un_apogee(&self) -> Option<f64> {
self.inner.un_apogee
}
#[getter]
fn un_inc(&self) -> Option<f64> {
self.inner.un_inc
}
#[getter]
fn disp_epoch(&self) -> Option<&str> {
self.inner.disp_epoch.as_deref()
}
#[getter]
fn disp_peri(&self) -> Option<f64> {
self.inner.disp_peri
}
#[getter]
fn disp_apo(&self) -> Option<f64> {
self.inner.disp_apo
}
#[getter]
fn disp_inc(&self) -> Option<f64> {
self.inner.disp_inc
}
#[getter]
fn comment(&self) -> Option<&str> {
self.inner.comment.as_deref()
}
fn __repr__(&self) -> String {
format!(
"GCATPsatcatRecord(jcat='{}', name={})",
self.inner.jcat,
self.inner
.name
.as_ref()
.map(|s| format!("'{}'", s))
.unwrap_or_else(|| "None".to_string()),
)
}
}
#[pyclass(name = "GCATSatcat")]
struct PyGCATSatcat {
inner: gcat::GCATSatcat,
}
#[pymethods]
impl PyGCATSatcat {
fn __len__(&self) -> usize {
self.inner.len()
}
fn __repr__(&self) -> String {
format!("GCATSatcat({} records)", self.inner.len())
}
fn get_by_jcat(&self, jcat: &str) -> Option<PyGCATSatcatRecord> {
self.inner.get_by_jcat(jcat).map(|r| PyGCATSatcatRecord {
inner: r.clone(),
})
}
fn get_by_satcat(&self, satcat_num: &str) -> Option<PyGCATSatcatRecord> {
self.inner
.get_by_satcat(satcat_num)
.map(|r| PyGCATSatcatRecord {
inner: r.clone(),
})
}
fn search_by_name(&self, pattern: &str) -> PyGCATSatcat {
PyGCATSatcat {
inner: self.inner.search_by_name(pattern),
}
}
fn filter_by_type(&self, object_type: &str) -> PyGCATSatcat {
PyGCATSatcat {
inner: self.inner.filter_by_type(object_type),
}
}
fn filter_by_owner(&self, owner: &str) -> PyGCATSatcat {
PyGCATSatcat {
inner: self.inner.filter_by_owner(owner),
}
}
fn filter_by_state(&self, state: &str) -> PyGCATSatcat {
PyGCATSatcat {
inner: self.inner.filter_by_state(state),
}
}
fn filter_by_status(&self, status: &str) -> PyGCATSatcat {
PyGCATSatcat {
inner: self.inner.filter_by_status(status),
}
}
fn filter_by_perigee_range(&self, min_km: f64, max_km: f64) -> PyGCATSatcat {
PyGCATSatcat {
inner: self.inner.filter_by_perigee_range(min_km, max_km),
}
}
fn filter_by_apogee_range(&self, min_km: f64, max_km: f64) -> PyGCATSatcat {
PyGCATSatcat {
inner: self.inner.filter_by_apogee_range(min_km, max_km),
}
}
fn filter_by_inc_range(&self, min_deg: f64, max_deg: f64) -> PyGCATSatcat {
PyGCATSatcat {
inner: self.inner.filter_by_inc_range(min_deg, max_deg),
}
}
fn to_dataframe(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
let polars = py.import("polars")?;
let records = self.inner.records();
macro_rules! str_list {
($field:ident) => {{
let list = PyList::empty(py);
for r in records {
list.append(r.$field.as_deref())?;
}
list
}};
}
macro_rules! f64_list {
($field:ident) => {{
let list = PyList::empty(py);
for r in records {
list.append(r.$field)?;
}
list
}};
}
let jcat_list = PyList::empty(py);
for r in records {
jcat_list.append(&r.jcat)?;
}
let data_dict = PyDict::new(py);
data_dict.set_item("jcat", jcat_list)?;
data_dict.set_item("satcat", str_list!(satcat))?;
data_dict.set_item("launch_tag", str_list!(launch_tag))?;
data_dict.set_item("piece", str_list!(piece))?;
data_dict.set_item("object_type", str_list!(object_type))?;
data_dict.set_item("name", str_list!(name))?;
data_dict.set_item("pl_name", str_list!(pl_name))?;
data_dict.set_item("ldate", str_list!(ldate))?;
data_dict.set_item("parent", str_list!(parent))?;
data_dict.set_item("sdate", str_list!(sdate))?;
data_dict.set_item("primary", str_list!(primary))?;
data_dict.set_item("ddate", str_list!(ddate))?;
data_dict.set_item("status", str_list!(status))?;
data_dict.set_item("dest", str_list!(dest))?;
data_dict.set_item("owner", str_list!(owner))?;
data_dict.set_item("state", str_list!(state))?;
data_dict.set_item("manufacturer", str_list!(manufacturer))?;
data_dict.set_item("bus", str_list!(bus))?;
data_dict.set_item("motor", str_list!(motor))?;
data_dict.set_item("mass", f64_list!(mass))?;
data_dict.set_item("mass_flag", str_list!(mass_flag))?;
data_dict.set_item("dry_mass", f64_list!(dry_mass))?;
data_dict.set_item("dry_flag", str_list!(dry_flag))?;
data_dict.set_item("tot_mass", f64_list!(tot_mass))?;
data_dict.set_item("tot_flag", str_list!(tot_flag))?;
data_dict.set_item("length", f64_list!(length))?;
data_dict.set_item("length_flag", str_list!(length_flag))?;
data_dict.set_item("diameter", f64_list!(diameter))?;
data_dict.set_item("diameter_flag", str_list!(diameter_flag))?;
data_dict.set_item("span", f64_list!(span))?;
data_dict.set_item("span_flag", str_list!(span_flag))?;
data_dict.set_item("shape", str_list!(shape))?;
data_dict.set_item("odate", str_list!(odate))?;
data_dict.set_item("perigee", f64_list!(perigee))?;
data_dict.set_item("perigee_flag", str_list!(perigee_flag))?;
data_dict.set_item("apogee", f64_list!(apogee))?;
data_dict.set_item("apogee_flag", str_list!(apogee_flag))?;
data_dict.set_item("inc", f64_list!(inc))?;
data_dict.set_item("inc_flag", str_list!(inc_flag))?;
data_dict.set_item("op_orbit", str_list!(op_orbit))?;
data_dict.set_item("oqual", str_list!(oqual))?;
data_dict.set_item("alt_names", str_list!(alt_names))?;
let df = polars.call_method1("DataFrame", (data_dict,))?;
Ok(df.unbind())
}
fn records(&self) -> Vec<PyGCATSatcatRecord> {
self.inner
.records()
.iter()
.map(|r| PyGCATSatcatRecord {
inner: r.clone(),
})
.collect()
}
}
#[pyclass(name = "GCATPsatcat")]
struct PyGCATPsatcat {
inner: gcat::GCATPsatcat,
}
#[pymethods]
impl PyGCATPsatcat {
fn __len__(&self) -> usize {
self.inner.len()
}
fn __repr__(&self) -> String {
format!("GCATPsatcat({} records)", self.inner.len())
}
fn get_by_jcat(&self, jcat: &str) -> Option<PyGCATPsatcatRecord> {
self.inner
.get_by_jcat(jcat)
.map(|r| PyGCATPsatcatRecord {
inner: r.clone(),
})
}
fn search_by_name(&self, pattern: &str) -> PyGCATPsatcat {
PyGCATPsatcat {
inner: self.inner.search_by_name(pattern),
}
}
fn filter_by_category(&self, category: &str) -> PyGCATPsatcat {
PyGCATPsatcat {
inner: self.inner.filter_by_category(category),
}
}
#[pyo3(name = "filter_by_class")]
fn filter_by_class(&self, class_: &str) -> PyGCATPsatcat {
PyGCATPsatcat {
inner: self.inner.filter_by_class(class_),
}
}
fn filter_by_result(&self, result: &str) -> PyGCATPsatcat {
PyGCATPsatcat {
inner: self.inner.filter_by_result(result),
}
}
fn filter_active(&self) -> PyGCATPsatcat {
PyGCATPsatcat {
inner: self.inner.filter_active(),
}
}
fn to_dataframe(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
let polars = py.import("polars")?;
let records = self.inner.records();
macro_rules! str_list {
($field:ident) => {{
let list = PyList::empty(py);
for r in records {
list.append(r.$field.as_deref())?;
}
list
}};
}
macro_rules! f64_list {
($field:ident) => {{
let list = PyList::empty(py);
for r in records {
list.append(r.$field)?;
}
list
}};
}
let jcat_list = PyList::empty(py);
for r in records {
jcat_list.append(&r.jcat)?;
}
let data_dict = PyDict::new(py);
data_dict.set_item("jcat", jcat_list)?;
data_dict.set_item("piece", str_list!(piece))?;
data_dict.set_item("name", str_list!(name))?;
data_dict.set_item("ldate", str_list!(ldate))?;
data_dict.set_item("tlast", str_list!(tlast))?;
data_dict.set_item("top", str_list!(top))?;
data_dict.set_item("tdate", str_list!(tdate))?;
data_dict.set_item("tf", str_list!(tf))?;
data_dict.set_item("program", str_list!(program))?;
data_dict.set_item("plane", str_list!(plane))?;
data_dict.set_item("att", str_list!(att))?;
data_dict.set_item("mvr", str_list!(mvr))?;
data_dict.set_item("class", str_list!(class))?;
data_dict.set_item("category", str_list!(category))?;
data_dict.set_item("result", str_list!(result))?;
data_dict.set_item("control", str_list!(control))?;
data_dict.set_item("discipline", str_list!(discipline))?;
data_dict.set_item("un_state", str_list!(un_state))?;
data_dict.set_item("un_reg", str_list!(un_reg))?;
data_dict.set_item("un_period", f64_list!(un_period))?;
data_dict.set_item("un_perigee", f64_list!(un_perigee))?;
data_dict.set_item("un_apogee", f64_list!(un_apogee))?;
data_dict.set_item("un_inc", f64_list!(un_inc))?;
data_dict.set_item("disp_epoch", str_list!(disp_epoch))?;
data_dict.set_item("disp_peri", f64_list!(disp_peri))?;
data_dict.set_item("disp_apo", f64_list!(disp_apo))?;
data_dict.set_item("disp_inc", f64_list!(disp_inc))?;
data_dict.set_item("comment", str_list!(comment))?;
let df = polars.call_method1("DataFrame", (data_dict,))?;
Ok(df.unbind())
}
fn records(&self) -> Vec<PyGCATPsatcatRecord> {
self.inner
.records()
.iter()
.map(|r| PyGCATPsatcatRecord {
inner: r.clone(),
})
.collect()
}
}
#[pyfunction]
#[pyo3(name = "gcat_get_satcat", signature = (cache_max_age=None))]
fn py_gcat_get_satcat(cache_max_age: Option<f64>) -> PyResult<PyGCATSatcat> {
let catalog = gcat::get_satcat(cache_max_age)?;
Ok(PyGCATSatcat { inner: catalog })
}
#[pyfunction]
#[pyo3(name = "gcat_get_psatcat", signature = (cache_max_age=None))]
fn py_gcat_get_psatcat(cache_max_age: Option<f64>) -> PyResult<PyGCATPsatcat> {
let catalog = gcat::get_psatcat(cache_max_age)?;
Ok(PyGCATPsatcat { inner: catalog })
}