commit - dd2afcad8fb31f92714d78933a8e2aa88a22de0a
commit + 317d1626dbee8cb5405c42c07d09cc722d639559
blob - 3551e035c0c25b9e2ed68a0e0e8f69b18c3086cd
blob + 70e27c1d50ac3da7b1a8b13ae5150a30c547b7f6
--- .gitignore
+++ .gitignore
.vscode/
result
result-*
+
+# docs/ — build output and DocumenterVitepress's own Node/Vitepress
+# tooling, plus the two source pages generated at build time from
+# README.md/INVESTIGATION_LOG.md (see docs/make.jl) — never hand-edited,
+# so never committed either.
+docs/build/
+docs/node_modules/
+docs/package-lock.json
+docs/.vitepress/cache/
+docs/.vitepress/dist/
+docs/src/.vitepress/cache/
+docs/src/.vitepress/dist/
+docs/src/index.md
+docs/src/investigation-log.md
blob - /dev/null
blob + 9294c16f190dac3d153086b18a4f6abd5f430f1a (mode 644)
--- /dev/null
+++ .github/workflows/Documenter.yml
+# Builds docs/ (Documenter.jl + DocumenterVitepress.jl) and deploys it to
+# the gh-pages branch. Mirrors DocumenterVitepress.jl's own workflow
+# (github.com/LuxDL/DocumenterVitepress.jl/.github/workflows/Documenter.yml) —
+# julia-docdeploy handles the Julia side (Pkg.develop the package into
+# docs/, instantiate, run docs/make.jl); DocumenterVitepress bootstraps
+# its own Node/Vitepress toolchain, no separate setup-node step needed.
+name: Documenter
+
+on:
+ push:
+ branches:
+ - main
+ tags: ['*']
+ pull_request:
+ workflow_dispatch:
+
+# Needed for deploydocs to push to gh-pages and for GitHub Pages deployment.
+permissions:
+ contents: write
+ pages: write
+ id-token: write
+ statuses: write
+
+# One deploy at a time; let an in-progress deploy finish rather than
+# cancelling it mid-push.
+concurrency:
+ group: pages
+ cancel-in-progress: false
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ - name: Setup Julia
+ uses: julia-actions/setup-julia@v2
+ with:
+ version: '1.10'
+ - name: Load Julia packages from cache
+ id: julia-cache
+ uses: julia-actions/cache@v2
+ - name: Build and deploy docs
+ uses: julia-actions/julia-docdeploy@v1
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # authenticates the push to gh-pages
+ DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }} # only needed if GITHUB_TOKEN push is restricted; see README.md
+ JULIA_DEBUG: "Documenter"
+ - name: Save Julia depot cache on cancel or failure
+ if: cancelled() || failure()
+ uses: actions/cache/save@v4
+ with:
+ path: ${{ steps.julia-cache.outputs.cache-paths }}
+ key: ${{ steps.julia-cache.outputs.cache-key }}
blob - 21a81c867be7bc24fc6b742b60d8623c241535e1
blob + 12d9eb0e2b6e99e1bc4c2b3c654d6b6d34c99d6b
--- INVESTIGATION_LOG.md
+++ INVESTIGATION_LOG.md
claim built on those numbers was rewritten against the corrected
measurements rather than left standing.
-## What was actually driving the ~10% photometric-scale mismatch, once flux was measured correctly
+## What was actually driving the ~10 percent photometric-scale mismatch, once flux was measured correctly
With flux measured correctly, `photometric_scale`'s ensemble ratio against
each frame's own `MAGZP` zeropoint still disagreed by 9-13% — but now
blob - c2cd7f2d371d9490ac8ba54a4d61056171942ed6
blob + 7ba634c95babb8347b5a571869a28e2e80bbf93c
--- README.md
+++ README.md
nix develop
```
+## Documentation
+
+The full API reference (every exported function's docstring, organized by
+pipeline stage) plus this README and `INVESTIGATION_LOG.md` are built into
+a static site with [Documenter.jl](https://github.com/JuliaDocs/Documenter.jl)
+and [DocumenterVitepress.jl](https://github.com/LuxDL/DocumenterVitepress.jl).
+`docs/make.jl` copies `README.md`/`INVESTIGATION_LOG.md` into `docs/src/`
+at build time (not committed — see `.gitignore`), so the site can't drift
+out of sync with them.
+
+To build locally:
+
+```
+julia --project=docs docs/make.jl
+```
+
+`.github/workflows/Documenter.yml` builds and deploys to the `gh-pages`
+branch on every push to `main` (and on tags), via GitHub's own
+`GITHUB_TOKEN` — no extra setup needed unless the repository's branch
+protection rules block Actions from pushing to `gh-pages`, in which case
+add a `DOCUMENTER_KEY` secret (an SSH deploy key with write access; see
+[Documenter.jl's hosting docs](https://documenter.juliadocs.org/stable/man/hosting/)
+for how to generate one) — the workflow already reads it if present.
+
## Dependencies
- [FITSIO.jl](https://github.com/JuliaAstro/FITSIO.jl) — FITS I/O
blob - /dev/null
blob + 786ff5301199a081a8d89784fe18fb61cbce2f1d (mode 644)
--- /dev/null
+++ docs/Project.toml
+[deps]
+AsteroidPipeline = "1001636e-a0d1-496e-b23d-cef10bc3cdca"
+Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
+DocumenterVitepress = "4710194d-e776-4893-9690-8d956a29c365"
+
+[compat]
+Documenter = "1.17.0"
+DocumenterVitepress = "0.3.5"
blob - /dev/null
blob + 72455561ca3ff6ff2568cf6fcaa5aad5d5af895d (mode 644)
--- /dev/null
+++ docs/make.jl
+using AsteroidPipeline
+using Documenter
+using DocumenterVitepress
+
+# README.md and INVESTIGATION_LOG.md are the actual source of truth for
+# the project's purpose, status, and real-data findings (see
+# INVESTIGATION_LOG.md itself for why they're kept separate). Copied here
+# at build time, not committed under docs/src (see .gitignore), so the
+# docs site can never drift out of sync with them.
+const REPO_ROOT = joinpath(@__DIR__, "..")
+
+index_content = read(joinpath(REPO_ROOT, "README.md"), String)
+index_content = replace(index_content, "(INVESTIGATION_LOG.md)" => "(investigation-log.md)")
+write(joinpath(@__DIR__, "src", "index.md"), index_content)
+
+cp(joinpath(REPO_ROOT, "INVESTIGATION_LOG.md"), joinpath(@__DIR__, "src", "investigation-log.md"); force=true)
+
+DocMeta.setdocmeta!(AsteroidPipeline, :DocTestSetup, :(using AsteroidPipeline); recursive=true)
+
+makedocs(;
+ modules=[AsteroidPipeline],
+ authors="Alejandro",
+ sitename="AsteroidPipeline.jl",
+ # Needed explicitly (not just inside `format=`): this repo has no git
+ # remote configured yet, and Documenter's own "edit this page" source
+ # links can't be auto-detected from one that doesn't exist.
+ repo="github.com/ale-bnes/AsteroidPipeline.jl.git",
+ format=DocumenterVitepress.MarkdownVitepress(;
+ repo="github.com/ale-bnes/AsteroidPipeline.jl",
+ devbranch="main",
+ devurl="dev",
+ ),
+ pages=[
+ "Home" => "index.md",
+ "Investigation Log" => "investigation-log.md",
+ "API Reference" => [
+ "Detection & Linking" => "api/detection.md",
+ "Variable Stars" => "api/variables.md",
+ "Astrometry & Plate-Solving" => "api/astrometry.md",
+ "Cross-Matching" => "api/crossmatch.md",
+ "Reference & ZOGY Differencing" => "api/reference-zogy.md",
+ "Pipeline" => "api/pipeline.md",
+ "Rotation Period" => "api/rotation.md",
+ ],
+ ],
+)
+
+DocumenterVitepress.deploydocs(;
+ repo="github.com/ale-bnes/AsteroidPipeline.jl",
+ target=joinpath(@__DIR__, "build"),
+ branch="gh-pages",
+ devbranch="main",
+ push_preview=true,
+)
blob - /dev/null
blob + 640afe66e56b83972bcf1da8a65d6858fd064049 (mode 644)
--- /dev/null
+++ docs/src/api/astrometry.md
+# Astrometry & Plate-Solving
+
+Pixel-to-sky calibration via WCS (`load_wcs`, `pix_to_sky`,
+`astrometric_calibrate`), and `plate_solve` as a fallback for frames with
+no WCS in their header at all (via the nova.astrometry.net API).
+
+```@autodocs
+Modules = [AsteroidPipeline]
+Pages = ["astrometry.jl", "platesolve.jl"]
+```
blob - /dev/null
blob + 78906448c7d52b40c4cfaa18234516047fdd39ee (mode 644)
--- /dev/null
+++ docs/src/api/crossmatch.md
+# Cross-Matching
+
+Separating known objects from candidates that warrant human verification,
+against SkyBoT, VSX, and SIMBAD (`crossmatch_catalog`).
+
+```@autodocs
+Modules = [AsteroidPipeline]
+Pages = ["crossmatch.jl"]
+```
blob - /dev/null
blob + 2b5fc4220f1caedf2ebecd2e69cbef403066a2b8 (mode 644)
--- /dev/null
+++ docs/src/api/detection.md
+# Detection & Linking
+
+Per-frame point-source detection (`detect_sources`) and cross-frame
+linear-motion matching into asteroid candidate tracklets
+(`link_candidates`).
+
+```@autodocs
+Modules = [AsteroidPipeline]
+Pages = ["detection.jl", "linking.jl"]
+```
blob - /dev/null
blob + 1f88b3f7749db0517404076d809fc8c915a13614 (mode 644)
--- /dev/null
+++ docs/src/api/pipeline.md
+# Pipeline
+
+`run_pipeline` and `search_field`, the end-to-end entry points that wire
+detection, (optional) ZOGY differencing, linking, variable-source search,
+and astrometric calibration together over a sequence of FITS frames.
+
+```@autodocs
+Modules = [AsteroidPipeline]
+Pages = ["pipeline.jl"]
+```
blob - /dev/null
blob + 00c5e7699d9f3101a62011a49f086c7ae944191e (mode 644)
--- /dev/null
+++ docs/src/api/reference-zogy.md
+# Reference & ZOGY Differencing
+
+Building a deep static-sky reference stack (`build_reference`,
+`load_frame`), estimating a frame's point-spread function empirically or
+via an analytic Moffat fallback (`estimate_psf`, `fit_moffat_psf`), and
+ZOGY proper image subtraction (`zogy_subtract`).
+
+```@autodocs
+Modules = [AsteroidPipeline]
+Pages = ["reference.jl", "psf.jl", "zogy.jl"]
+```
blob - /dev/null
blob + ebd5011c6331f7a53e870b32032ebed813ccd661 (mode 644)
--- /dev/null
+++ docs/src/api/rotation.md
+# Rotation Period
+
+Forced-position light-curve photometry for a confirmed discovery
+(`light_curve`) and Lomb-Scargle period recovery over it
+(`recover_rotation_period`).
+
+```@autodocs
+Modules = [AsteroidPipeline]
+Pages = ["rotation.jl"]
+```
blob - /dev/null
blob + 1c9948b2d83364486fdce97332402cf3bcfff5ea (mode 644)
--- /dev/null
+++ docs/src/api/variables.md
+# Variable Stars
+
+Stationary, flux-varying source detection (`find_variable_sources`) and
+its supporting statistics — as opposed to `link_candidates`'s
+moving-object search.
+
+```@autodocs
+Modules = [AsteroidPipeline]
+Pages = ["variables.jl"]
+```
blob - 0f489f8392a022fd9bc05c6626a77f7ebc863844
blob + de5e6dd7d28330402e4c877c95ccd2e1c5318e93
--- src/crossmatch.jl
+++ src/crossmatch.jl
Run `query` (an ADQL string) as a synchronous TAP query against `url`,
returning the CSV response parsed by `CSV.File`. Shared by
-[`_crossmatch_simbad`](@ref) and [`_crossmatch_vsx`](@ref).
+`_crossmatch_simbad` and `_crossmatch_vsx`.
"""
function _tap_query(url::AbstractString, query::AbstractString)
body = HTTP.Form(Dict(
An ADQL synchronous cone-search query: rows of `table` within
`radius_deg` of `(ra, dec)`, plus a `distance_arcsec` column (via ADQL's
`DISTANCE`, in degrees, converted here) — shared by
-[`_crossmatch_simbad`](@ref) and [`_crossmatch_vsx`](@ref), which differ
+`_crossmatch_simbad` and `_crossmatch_vsx`, which differ
only in `select`/`table`/coordinate column names.
"""
function _cds_cone_query(select::AbstractString, table::AbstractString,
blob - 4d8cfca4f0661ef0bd38dfe55e8d8f49e7cc2ed6
blob + 93f5d32acb2f1ed32e0fbb759bddb2b112f37574
--- src/rotation.jl
+++ src/rotation.jl
follow-up sequence, `ra`/`dec` need to be recomputed per frame from an
ephemeris — not done here.
-Background/noise come from [`estimate_background`](@ref) as in
-[`detect_sources`](@ref); `flux_err` is `Photometry.photometry`'s
+Background/noise come from `Photometry.Background.estimate_background`
+as in [`detect_sources`](@ref); `flux_err` is `Photometry.photometry`'s
propagated aperture error from a uniform per-pixel `noise`, not a full
per-pixel variance map.