{"id":37064906,"url":"https://github.com/b612-asteroid-institute/precovery","last_synced_at":"2026-01-14T07:35:34.133Z","repository":{"id":40521594,"uuid":"414402801","full_name":"B612-Asteroid-Institute/precovery","owner":"B612-Asteroid-Institute","description":"Fast precovery of small body observations at scale","archived":false,"fork":false,"pushed_at":"2024-12-09T15:59:33.000Z","size":3314,"stargazers_count":7,"open_issues_count":9,"forks_count":2,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-12-06T02:45:58.010Z","etag":null,"topics":["asteroids","comets","python","solar-system"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/B612-Asteroid-Institute.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2021-10-06T23:33:35.000Z","updated_at":"2025-09-19T21:54:09.000Z","dependencies_parsed_at":"2024-02-19T18:13:05.110Z","dependency_job_id":"44e3c763-73d1-4265-bef2-c024b9925ee2","html_url":"https://github.com/B612-Asteroid-Institute/precovery","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/B612-Asteroid-Institute/precovery","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/B612-Asteroid-Institute%2Fprecovery","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/B612-Asteroid-Institute%2Fprecovery/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/B612-Asteroid-Institute%2Fprecovery/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/B612-Asteroid-Institute%2Fprecovery/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/B612-Asteroid-Institute","download_url":"https://codeload.github.com/B612-Asteroid-Institute/precovery/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/B612-Asteroid-Institute%2Fprecovery/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28413431,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T05:26:33.345Z","status":"ssl_error","status_checked_at":"2026-01-14T05:21:57.251Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asteroids","comets","python","solar-system"],"created_at":"2026-01-14T07:35:33.495Z","updated_at":"2026-01-14T07:35:34.113Z","avatar_url":"https://github.com/B612-Asteroid-Institute.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# precovery: fast asteroid precovery at scale\n#### A Python package by the Asteroid Institute, a program of the B612 Foundation\n[![Python 3.7+](https://img.shields.io/badge/Python-3.7%2B-blue)](https://img.shields.io/badge/Python-3.7%2B-blue)\n[![License](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)\n[![DOI](https://zenodo.org/badge/414402801.svg)](https://zenodo.org/badge/latestdoi/414402801)  \n[![Python Package with conda](https://github.com/B612-Asteroid-Institute/precovery/actions/workflows/python-package-conda.yml/badge.svg)](https://github.com/B612-Asteroid-Institute/precovery/actions/workflows/python-package-conda.yml)\n[![Publish Python Package to conda](https://github.com/B612-Asteroid-Institute/precovery/actions/workflows/python-publish-conda.yml/badge.svg)](https://github.com/B612-Asteroid-Institute/precovery/actions/workflows/python-publish-conda.yml)  \n[![Anaconda-Server Badge](https://anaconda.org/asteroid-institute/precovery/badges/version.svg)](https://anaconda.org/asteroid-institute/precovery)\n[![Anaconda-Server Badge](https://anaconda.org/asteroid-institute/precovery/badges/platforms.svg)](https://anaconda.org/asteroid-institute/precovery)\n[![Anaconda-Server Badge](https://anaconda.org/asteroid-institute/precovery/badges/downloads.svg)](https://anaconda.org/asteroid-institute/precovery)  \n\n## Installation\n\n### Conda\n\nTo get the latest released version and install it into a conda environment:  \n`conda install -c asteroid-institute precovery`  \n\n### Source\n\nTo install the bleeding edge source code, clone this repository and then:  \n\n`pip install .`  \n\n#### healpy\n\n`healpy` is available on PyPI, but as of version 1.16.2, only x86_64 wheels are published.\nFor developers using Apple M1 Macbooks, these wheels won't be runnable.\n\nAlternative wheels are therefore currently available on a [B612 fork](https://github.com/B612-Asteroid-Institute/healpy).\n`aarch64` linux wheels can be found here: https://github.com/B612-Asteroid-Institute/healpy/releases/tag/1.16.2\n\nThose wheels can be downloaded and directly pip-installed for developers using Docker containers on M1 Macbooks.\nSee the `Dockerfile` for example.\n\n## Developer Setup\n\nThis project uses [pre-commit](https://pre-commit.com/) to run linters and code formatters.\n\npre-commit sets the versions of these code analysis tools, and serves as an entrypoint for running them.\n\n### pre-commit installation\n\npre-commit is installed automatically inside the Docker container.\n\nIf you're developing on your local machine without Docker, install it\nusing either `pip install pre-commit` or `conda install -c conda-forge\npre-commit`. Then, install the hooks with `pre-commit install-hooks`,\nrun from the root of this repository. This will install all the\nlinters and tools in an isolated environment.\n\n### Running pre-commit\nThere are two ways you may choose to run pre-commit. You can run it\nmanually, or you can run it automatically before every commit.\n\npre-commit generally only checks files that you have changed. It does\nthis by comparing against git. This means that `pre-commit` will\n**only** check files you have staged (ones you have `git add`-ed). It\nwill check the staged versions of those files.\n\n#### Running pre-commit manually\n\nRun `pre-commit run` to run linters against any files that you have\nchanged.\n\nRun `pre-commit run --all-files` to run linters against all files in\nthe entire repository.\n\nIf you use a docker container for all development, you can use\n`docker-compose run precovery pre-commit run [--all-files]` to run\nwithin the container.\n\n#### Running pre-commit automatically before every commit\n\nRun `pre-commit install` to set up git hooks. These will block any\ncommits if your changes don't pass the lint tests.\n\nSometimes, you might not pass lint but need to commit anyway. If you\nhave automatic pre-commit enabled, this can get in the way.\n\nYou can disable all checks by using `git commit --no-verify`. You can\ndisable a single check by using a `SKIP` environment variable. For\nexample, to disable the `mypy` checks, use `SKIP=mypy git commit`.\n\nYou can skip multiple linters by passing a comma-separated list. For\nexample, `SKIP=mypy,black,flake8 git commit`.\n\nThe values you pass to SKIP are the pre-commit hook IDs. These can be\nfound in `.pre-commit-config.yaml`.\n\n\n## Observation Schema\n### Input CSV\n\n`precovery` expects a specific set of columns to be able to index observations into a search\nefficient format. Input files should be sorted by ascending time.\n\n|Name|Unit|Type|Description|\n|---|---|---|---|\n| obs_id | None | str | Unique observation ID for the observation |\n| exposure_id | None | str | Exposure or Image ID from which observation was measured |\n| mjd | days | float | MJD of the observation in UTC[^1] |\n| ra  | degree | float | Right Ascension (J2000) |\n| dec  | degree | float | Declination (J2000) |\n| ra_sigma  | degree | float | 1-sigma uncertainty in Right Ascension (Optional)[^2] |\n| dec_sigma  | degree | float | 1-sigma uncertainty in Declination (Optional)[^2] |\n| mag  | None | float | Photometric magnitude measured for observation |\n| mag_sigma  | None | float | 1-sigma uncertainty in photometric magnitude (Optional)[^2]|\n| filter | None | str | Filter/bandpass in which the observation was made |\n| exposure_mjd_start | days | float | Start MJD of the exposure in UTC |\n| exposure_mjd_mid | days | float | Midpoint MJD of the exposure in UTC |\n| exposure_duration | seconds | float | The length of the exposure |\n| observatory_code | None | str | MPC observatory code for the observatory/observing program |\n\n\n## Precovery Results\n\nPrecovery returns observations that lie within the angular tolerance of the predicted location of an\ninput orbit propagated and mapped to the indexed observations. These observations are termed `PrecoveryCandidates`.\nOptionally, precovery can also return `FrameCandidates` which are frames where the orbit intersected the Healpix-mapped exposure\nfor a specific dataset but no observations were found within the angular tolerance.\nIn this case, quantities specific to individual observations will be returned as\n NaNs (mjd, ra_deg, dec_sigma_arcsec, ra_sigma_arcsec, mag, mag_sigma, observation_id, delta_ra_arcsec, delta_dec_arcsec, distance_arcsec), with the remaining quantities that define the Healpix-mapped\n exposure returned as normal.\n\n|Name|Unit|Type|Description|NaN When?|\n|---|---|---|---|---|\n| mjd | days | float | MJD of the observation in UTC[^1] | FrameCandidates |  \n| ra_deg  | degree | float | Right Ascension (J2000) | FrameCandidates |  \n| dec_deg  | degree | float | Declination (J2000) | FrameCandidates |  \n| ra_sigma_arcsec  | arcsecond | float | 1-sigma uncertainty in Right Ascension | FrameCandidates,  Missing In Source Observations[^3] |  \n| dec_sigma_arcsec  | arcsecond | float | 1-sigma uncertainty in Declination | FrameCandidates,  Missing In Source Observations[^3]|  \n| mag  | None | float | Photometric magnitude measured for observation | FrameCandidates |  \n| mag_sigma  | None | float | 1-sigma uncertainty in photometric magnitude | FrameCandidates,  Missing In Source Observations[^3]|  \n| filter | None | str | Filter/bandpass in which the observation was made | No |  \n| obscode | None | str | MPC observatory code for the observatory/observing program | No |  \n| exposure_id | None | str | Exposure or Image ID from which observation was measured | No |  \n| exposure_mjd_start | days | float | Start MJD of the exposure in UTC | No |  \n| exposure_mjd_mid | days | float | Midpoint MJD of the exposure in UTC | No |  \n| exposure_duration | seconds | float | The length of the exposure | No |  \n| observation_id | None | str |Unique observation ID for the observation | FrameCandidates |  \n| healpix_id | None | int | ID of the HEALPixel onto which the exposure was mapped | No |  \n| pred_ra_deg  | degree | float | Predicted Right Ascension (J2000) of the object at the time of the observation | No |  \n| pred_dec_deg  | degree | float | Predicted Declination (J2000) of the object at the time of the observation | No |  \n| pred_vra_degpday  | degree / day| float | Predicted velocity in Right Ascension (J2000) of the object at the time of the observation | No |  \n| pred_vdec_degpday  | degree /day | float | Predicted velocity in Declination (J2000) of the object at the time of the observation | No |  \n| delta_ra_arcsec  | arcsecond | float | Difference between predicted and observed Right Ascension (predicted - observed) | FrameCandidates |  \n| delta_dec_arcsec  | arcsecond | float | Difference between predicted and observed Declination (predicted - observed) | FrameCandidates |  \n| distance_arcsec  | arcsecond | float | Angular offset between the predicted location of the object and the obervation | FrameCandidates |  \n| dataset_id  | None | str | Dataset ID from where the observation was precovered | No |  \n\nFootnotes:  \n[^1]: The time at which the observation is reported may be different than the exposure midpoint time to account for effects such as shutter motion.  \n[^2]: Quantities that are optional should be serialized as empty strings with the columns still defined in the input CSVs.  \nWhen using pandas to serialize dataframes, NaN values are automatically stored as empty strings.  \n[^3]: May be NaN if they were undefined in the source observations.  \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fb612-asteroid-institute%2Fprecovery","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fb612-asteroid-institute%2Fprecovery","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fb612-asteroid-institute%2Fprecovery/lists"}