From ce373f4a734fdd9baf9bb9c12aaafeeded6706ce Mon Sep 17 00:00:00 2001 From: "Joe(y) Carpinelli" Date: Sat, 22 Jun 2024 08:49:13 -0600 Subject: [PATCH] Adds SPICEApplications.jl as subpackage (#26) --- .github/workflows/CI.yml | 17 +- docs/Project.toml | 1 + docs/make.jl | 3 +- docs/src/executables.md | 43 + lib/SPICEApplications/.gitignore | 30 + lib/SPICEApplications/Project.toml | 22 + lib/SPICEApplications/README.md | 33 + .../src/SPICEApplications.jl | 771 ++++++++++++++++++ lib/SPICEApplications/src/docstrings.jl | 15 + lib/SPICEApplications/test/runtests.jl | 2 + test/runtests.jl | 259 +++--- 11 files changed, 1063 insertions(+), 133 deletions(-) create mode 100644 docs/src/executables.md create mode 100644 lib/SPICEApplications/.gitignore create mode 100644 lib/SPICEApplications/Project.toml create mode 100644 lib/SPICEApplications/README.md create mode 100644 lib/SPICEApplications/src/SPICEApplications.jl create mode 100644 lib/SPICEApplications/src/docstrings.jl create mode 100644 lib/SPICEApplications/test/runtests.jl diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 3d91ce4..2ff0a38 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -6,7 +6,7 @@ on: push: branches: - main - tags: '*' + tags: "*" jobs: test: name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }} @@ -15,9 +15,12 @@ jobs: fail-fast: false matrix: version: - - '1.6' # Replace this with the minimum Julia version that your package supports. E.g. if your package requires Julia 1.5 or higher, change this to '1.5'. - - '1' # Leave this line unchanged. '1' will automatically expand to the latest stable 1.x release of Julia. - - 'nightly' + - "1.6" # Replace this with the minimum Julia version that your package supports. E.g. if your package requires Julia 1.5 or higher, change this to '1.5'. + - "1" # Leave this line unchanged. '1' will automatically expand to the latest stable 1.x release of Julia. + - "nightly" + package: + - SPICE + - SPICEApplications os: - ubuntu-latest - macos-latest @@ -42,6 +45,9 @@ jobs: ${{ runner.os }}- - uses: julia-actions/julia-buildpkg@v1 - uses: julia-actions/julia-runtest@v1 + with: + env: + GROUP: ${{ matrix.package}} - uses: julia-actions/julia-processcoverage@v1 - uses: codecov/codecov-action@v1 with: @@ -53,7 +59,7 @@ jobs: - uses: actions/checkout@v2 - uses: julia-actions/setup-julia@v1 with: - version: '1' + version: "1" - run: | julia --project=docs -e ' using Pkg @@ -68,4 +74,3 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }} - diff --git a/docs/Project.toml b/docs/Project.toml index 1a6d309..01d0ca9 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -1,5 +1,6 @@ [deps] Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" +SPICEApplications = "e12e0822-0612-48d4-a4bb-92984dd6b6ec" [compat] Documenter = "~0.27" diff --git a/docs/make.jl b/docs/make.jl index ae2a6ee..0734adf 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -1,4 +1,4 @@ -using Documenter, SPICE +using Documenter, SPICE, SPICEApplications makedocs( format = Documenter.HTML( @@ -9,6 +9,7 @@ makedocs( pages = [ "Home" => "index.md", "API" => "api.md", + "Executables" => "executables.md" ], doctest = false, ) diff --git a/docs/src/executables.md b/docs/src/executables.md new file mode 100644 index 0000000..f67ec65 --- /dev/null +++ b/docs/src/executables.md @@ -0,0 +1,43 @@ +# SPICEApplications.jl + +!!! note + The `SPICEApplications` module is not included within `SPICE`. To access + the functions documented on this page, install `SPICEApplications` using + Julia's package manager: `Pkg.install("SPICEApplications")`. + +The JPL SPICE Toolkit provides executables for interacting with SPICE kernels, such as +`mkspk`, `brief`, and others. `SPICEApplications.jl` provides idiomatic Julia +interfaces to these executables, which themselves are packaged by `CSPICE_jll.jl`. + +## Usage + +Each executable can be called through its corresponding function without +arguments, or programatically using function arguments. For example, the SPICE +Toolkit's `BRIEF` program prints the description of a provided kernel. When the +`brief` executable is called without arguments, it prints its "help" text; this +can be replicated by calling `SPICEApplications.brief()` without arguments. +Alternatively, you can pass the kernel that you want to inspect as a positional +argument: `brief(kernel_file)`. + +All SPICE Toolkit executables are documented within the [SPICE Toolkit Documentation](https://naif.jpl.nasa.gov/naif/utilities.html). + +```@repl +using SPICEApplications + +kernel = download("https://naif.jpl.nasa.gov/pub/naif/CASSINI/kernels/spk/000202R_SK_V1P32_V2P12.bsp") + +brief(kernel); +``` + +## Example + +For a concrete usage example, see how `SPICEApplications` is used to +[generate](https://github.com/cadojo/SPICEKernels.jl/blob/main/gen/make.jl) +docstrings for [`SPICEKernels.jl`](https://github.com/cadojo/SPICEKernels.jl). + +## Reference + +```@autodocs +Modules = [SPICEApplications] +Order = [:module, :type, :function, :constant] +``` \ No newline at end of file diff --git a/lib/SPICEApplications/.gitignore b/lib/SPICEApplications/.gitignore new file mode 100644 index 0000000..dd48bf4 --- /dev/null +++ b/lib/SPICEApplications/.gitignore @@ -0,0 +1,30 @@ +# Files generated by invoking Julia with --code-coverage +*.jl.cov +*.jl.*.cov + +# Files generated by invoking Julia with --track-allocation +*.jl.mem + +# System-specific files and directories generated by the BinaryProvider and BinDeps packages +# They contain absolute paths specific to the host computer, and so should not be committed +deps/deps.jl +deps/build.log +deps/downloads/ +deps/usr/ +deps/src/ + +# Build artifacts for creating documentation generated by the Documenter package +docs/build/ +docs/site/ + +# File generated by Pkg, the package manager, based on a corresponding Project.toml +# It records a fixed state of all packages used by the project. As such, it should not be +# committed for packages, but should be committed for applications that require a static +# environment. +Manifest.toml + +# MacOs file explorer artifacts should be ignored! +.DS_Store + +# As should .vscode! +.vscode diff --git a/lib/SPICEApplications/Project.toml b/lib/SPICEApplications/Project.toml new file mode 100644 index 0000000..4bd21e7 --- /dev/null +++ b/lib/SPICEApplications/Project.toml @@ -0,0 +1,22 @@ +name = "SPICEApplications" +uuid = "e12e0822-0612-48d4-a4bb-92984dd6b6ec" +authors = ["Joe Carpinelli "] +version = "1.0.0" + +[deps] +CSPICE_jll = "07f52509-e9d9-513c-a20d-3b911885bf96" +DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" + +[compat] +CSPICE_jll = "67" +DocStringExtensions = "0.9" +julia = "1" + +[extras] +DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" +Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" +SPICE = "5bab7191-041a-5c2e-a744-024b9c3a5062" +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[targets] +test = ["Test"] diff --git a/lib/SPICEApplications/README.md b/lib/SPICEApplications/README.md new file mode 100644 index 0000000..cd728d1 --- /dev/null +++ b/lib/SPICEApplications/README.md @@ -0,0 +1,33 @@ +[![Stable](https://img.shields.io/badge/docs-stable-blue.svg)](https://juliaastro.github.io/SPICE.jl/stable) +[![Dev](https://img.shields.io/badge/docs-dev-blue.svg)](https://juliaastro.github.io/SPICE.jl/dev) + +# `SPICEApplications` + +_Generate ephemeris kernel files using NASA JPL's `SPICEApplications` program, +all from within Julia!_ + +## Installation + +Choose one of the following two lines! + +```julia +import Pkg; Pkg.add("SPICEApplications"); +``` + +```julia +]add SPICEApplications # in Julia's REPL +``` + +## Documentation + +The documentation for `SPICEApplications.jl` is hosted within the `SPICE.jl` +[documentation](http://juliaastro.org/SPICE.jl/stable/executables). + +## Credits + +NASA JPL developed and maintains the +[NAIF SPICE Toolkit](https://naif.jpl.nasa.gov/naif/toolkit.html), including +`SPICEApplications`. Helge Eichhorn developed and maintains +[`SPICE.jl`](https://github.com/JuliaAstro/SPICE.jl), as well as the +[Julia wrappers](https://juliahub.com/ui/Packages/CSPICE_jll/XJqVo/67.0.0+0) +around the SPICE Toolkit. diff --git a/lib/SPICEApplications/src/SPICEApplications.jl b/lib/SPICEApplications/src/SPICEApplications.jl new file mode 100644 index 0000000..d9f9dd3 --- /dev/null +++ b/lib/SPICEApplications/src/SPICEApplications.jl @@ -0,0 +1,771 @@ +""" +Call all SPICE Utilities from within Julia! + +!!! warning + This package is not affiliated with or endorsed by NASA, JPL, Caltech, or any + other organization! This is an independently written package by an + astrodynamics hobbyist. + +# Extended help + +## README + +$(README) + +## License +$(LICENSE) + +## Exports +$(EXPORTS) + +## Imports +$(IMPORTS) +""" +module SPICEApplications + +export + brief, + chronos, + ckbrief, + commnt, + dskbrief, + dskexp, + frmdiff, + inspekt, + mkdsk, + mkspk, + msopck, + spacit, + spkdiff, + spkmerge, + tobin, + toxfr + +import CSPICE_jll + +using DocStringExtensions +include("docstrings.jl") + +""" +BRIEF is a command-line utility program that displays a contents and time coverage summary for one or more binary SPK or binary PCK files. + +# Extended Help + +!!! warning + All descriptions below were manually parsed from the commandline program's help/usage output. + +| Argument | Equivalent | Description | +| :--- | :--- | :--- | +| `tabular` | `-t` | Display summary in a tabular format | +| `single` | `-a` | Treat all files as a single file | +| `centers` | `-c` | Displays centers of motion/relative-to frames | +| `utc` | `-utc` | Display times in UTC calendar date format (needs LSK) | +| `utcdoy` | `-utcdoy` | Display times in UTC day-of-year format (needs LSK) | +| `etsec` | `-etsec` | Display times as ET seconds past J2000 | +| `sec` | `-sec` | Display times "rounded inward" to second | +| `min` | `-min` | Display times "rounded inward" to minute | +| `hour` | `-hour` | Display times "rounded inward" to hour | +| `day` | `-day` | Display times "rounded inward" to day | +| `bytime` | `-s` | Display summary sorted by start time for each body/frame | +| `bycoverage` | `-g` | Display summary grouped by coverage | +| `byid` | `-n` | Display bodies/frames using numeric id-codes | +| `byname` | `-o` | Display summary ordered by body/frame name | +| `body` | `-sb[bod]` | Display summary for body [bod] | +| `center` | `-sc[cen]` | Display summary for center of motion/relative-to frame [cen] | +| `at` | `-at [time]` | Display summary if coverage contains epoch [time] | +| `from` | `-from [beg]` | Display summary if coverage contains interval [beg]:[end] | +| `to` | `-to [end]` | Display summary if coverage contains interval [beg]:[end] | +| `listfile` | `-f [list]` | Summarize kernels listed in the [list] file | +| `help` | `-h` | Display help | +| `version` | `-v` | Display version| +""" +function brief( + file::AbstractString...; + tabular=false, single=false, centers=false, utc=false, utcdoy=false, etsec=false, + sec=false, min=false, hour=false, day=false, bytime=false, bycoverage=false, + byid=false, byname=false, body=nothing, center=nothing, at=nothing, from=nothing, + to=nothing, listfile=nothing, help=false, version=false, + stdout=stdout, stderr=stderr, stdin=stdin, append=false, wait=true, +) + args = String[] + tabular && push!(args, "-t") + single && push!(args, "-a") + centers && push!(args, "-c") + + utc && push!(args, "-utc") + utcdoy && push!(args, "-utcdoy") + etsec && push!(args, "-etsec") + sec && push!(args, "-sec") + min && push!(args, "-min") + hour && push!(args, "-hour") + day && push!(args, "-day") + + bytime && push!(args, "-s") + bycoverage && push!(args, "-g") + byid && push!(args, "-n") + byname && push!(args, "-o") + + !isnothing(body) && push!(args, "-sb$body") + !isnothing(center) && push!(args, "-sc$center") + !isnothing(at) && push!(args, "-at $at") + !isnothing(from) && push!(args, "-from $from") + !isnothing(to) && push!(args, "-to $to") + !isnothing(listfile) && push!(args, "-f $listfile") + + help && push!(args, "-h") + version && push!(args, "-v") + + args = join(args, " ") + files = join(file, " ") + cmd = `$(CSPICE_jll.brief()) $args $files` + + if wait + cmd = pipeline(cmd; stdout=stdout, stderr=stderr, stdin=stdin, append=append) + end + + result = run(cmd; wait=wait) + + return result +end + + +""" +CHRONOS is a command-line program that converts between several time systems and time formats. + +# Extended Help + +!!! warning + All descriptions below were manually parsed from the commandline program's help/usage output. + +| Argument | Equivalent | Description | +| :--- | :--- | :--- | +| `from` | `-FROM <"from" time system>` | "from" time system | +| `fromtype` | `-FROMTYPE <"from" time system type>` | "from" time system type| +| `to` | `-TO <"to" time system>` | "to" time system | +| `totype` | `-TOTYPE <"to" time system type>` | "to" time system type | +| `format` | `-FORMAT ` | output time format picture| +| `time` | `-TIME ` | intput time| +| `sc` | `-SC ` | sc ID| +| `center` | `-CENTER ` | cental body ID| +|`landingtime` | `-LANDINGTIME ` | UTC time of the landing | +| `sol1index` | `-SOL1INDEX ` | index of the first SOL | +| `nolabel` | `-NOLABEL` | | +| `trace` | `-TRACE` | | +| `help` | `-HELP` | display help | +| `usage` | `-USAGE` | display usage | +| `template` | `-TEMPLATE` | display setup file template | +""" +function chronos( + file::AbstractString...; + from=nothing, fromtype=nothing, to=nothing, totype=nothing, format=nothing, + time=nothing, sc=nothing, center=nothing, landingtime=nothing, sol1index=nothing, + nolabel=false, trace=false, help=false, usage=false, template=nothing, + stdout=stdout, stderr=stderr, stdin=stdin, append=false, wait=true, +) + args = String[] + + !isnothing(from) && push!(args, "-FROM $from") + !isnothing(fromtype) && push!(args, "-FROMTYPE $fromtype") + !isnothing(to) && push!(args, "-TO $to") + !isnothing(totype) && push!(args, "-TOTYPE $totype") + !isnothing(format) && push!(args, "-FORMAT $format") + !isnothing(time) && push!(args, "-TIME $time") + !isnothing(sc) && push!(args, "-sc $sc") + !isnothing(center) && push!(args, "-CENTER $center") + !isnothing(landingtime) && push!(args, "-LANDINGTIME $landingtime") + !isnothing(sol1index) && push!(args, "-SOL1INDEX $sol1index") + nolabel && push!(args, "-NOLABEL") + trace && push!(args, "-TRACE") + help && push!(args, "-HELP") + usage && push!(args, "-USAGE") + !isnothing(template) && push!(args, "-TEMPLATE $template") + + args = join(args, " ") + files = join(file, " ") + cmd = `$(CSPICE_jll.chronos()) $files $args` + + if wait + cmd = pipeline(cmd; stdout=stdout, stderr=stderr, stdin=stdin, append=append) + end + + result = run(cmd; wait=wait) + + return result +end + + +""" +CKBRIEF is a command-line utility program that displays a contents and time coverage summary for one or more binary CK files. + +# Extended Help + +!!! warning + All descriptions below were manually parsed from the commandline program's help/usage output. + +| Argument | Equivalent | Description | +| :--- | :--- | :--- | +| `dump` | `-dump` | display interpolation intervals boundaries | +| `boundaries` | `-nm` | display segment boundaries | +| `relframes` | `-rel` | display relative-to frames | +| `idframes` | `-n` | display frames associated with structure IDs | +| `tabular` | `-t` | display summary in a tabular format | +| `single` | `-a` | treat all files as a single file | +| `bycoverage` | `-g` | display summary grouped by coverage | +| `utc` | `-utc` | display times in UTC calendar date format | +| `utcdoy` | `-utcdoy` | display times in UTC day-of-year format | +| `sclk` | `-sclk` | display times as SCLK strings | +| `dpsclk` | `-dpsclk` | display times as SCLK ticks | +| `id` | `[ID]` | display summmary for structure with [ID] | +| `summarize` | `-f` | summarize kernels listed in the `[list]` file | +| `help` | `-h` | display help | +| `version` | `-v` | display version | +""" +function ckbrief( + file::AbstractString...; + dump=false, boundaries=false, relframes=false, idframes=false, tabular=false, + single=false, bycoverage=false, utc=false, utcdoy=false, sclk=false, dpsclk=false, + id=nothing, summarize=nothing, help=false, version=false, + stdout=stdout, stderr=stderr, stdin=stdin, append=false, wait=true, +) + args = String[] + + dump && push!(args, "-dump") + boundaries && push!(args, "-nm") + relframes && push!(args, "-rel") + idframes && push!(args, "-n") + tabular && push!(args, "-t") + single && push!(args, "-a") + bycoverage && push!(args, "-g") + utc && push!(args, "-utc") + utcdoy && push!(args, "-utcdoy") + sclk && push!(args, "-sclk") + dpsclk && push!(args , "-dpsclk") + + !isnothing(id) && push!(args, id) + !isnothing(summarize) && push!(args, "-f $summarize") + + help && push!(args, "-h") + version && push!(args, "-v") + + args = join(args, " ") + files = join(file, " ") + cmd = `$(CSPICE_jll.ckbrief()) $files $args` + + if wait + cmd = pipeline(cmd; stdout=stdout, stderr=stderr, stdin=stdin, append=append) + end + + result = run(cmd; wait=wait) + + return result +end + + +""" +COMMNT is a command-line program that reads, adds, extracts, or deletes comments from SPICE binary kernel files. + +# Extended Help + +!!! warning + All descriptions below were manually parsed from the commandline program's help/usage output. + +| Argument | Equivalent | Description | +| :--- | :--- | :--- | +| `add` | `-a` | add comments to binary kernel | +| `extract` | `-e` | extract comments from a binary kernel | +| `read` | `-r` | read the comments in a binary kernel | +| `delete` | `-d`| delete the comments from the binary kernel | +| `help` | `-h` | display the help message | +""" +function commnt( + kernelfile::Union{<:AbstractString,Nothing} = nothing, commentfile::Union{<:AbstractString,Nothing} = nothing; + add=false, extract=false, read=false, delete=false, help=false, + stdout=stdout, stderr=stderr, stdin=stdin, append=false, wait=true, +) + args = String[] + + add && push!(args, "-a") + extract && push!(args, "-e") + read && push!(args, "-r") + delete && push!(args, "-d") + help && push!(args, "-h") + + kernel = isnothing(kernelfile) ? "" : kernelfile + comment = isnothing(commentfile) ? "" : commentfile + + args = join(args, " ") + cmd = `$(CSPICE_jll.commnt()) $args $kernel $comment` + + if wait + cmd = pipeline(cmd; stdout=stdout, stderr=stderr, stdin=stdin, append=append) + end + + result = run(cmd; wait=wait) + + return result +end + + +""" +DSKBRIEF is a command-line utility program that displays a summary of the spatial coverage and additional attributes of one or more binary Digital Shape Kernel (DSK) files. + +# Extended Help + +!!! warning + All descriptions below were manually parsed from the commandline program's help/usage output. + +| Argument | Equivalent | Description | +| :--- | :--- | :--- | +| `single` | `-a` | treat all DSK files as a single file | +| `gaps` | `-gaps` | display coverage gaps (aplies only when `-a` is used) | +| `extended` | `-ext` | display extended summaries: these include data type, data class, and time bounds | +| `timebounds` | `-tg` | require segment time bounds to match when grouping segments | +| `full` | `-full` | display a detailed summary for each segment, including data-type-specific parameters | +| `sigdigs` | `-d ` | display `n` significant digits of floating point values | +| `version` | `-v` | display the version of the program | +| `help` | `-h` | display help text | +| `usage` | `-u` | display usage text | +""" +function dskbrief( + file::AbstractString...; + single=false, gaps=false, extended=false, timebounds=false, bysegment=false, + full=false, sigdigs=nothing, version=false, help=false, usage=false, + stdout=stdout, stderr=stderr, stdin=stdin, append=false, wait=true, +) + args = String[] + + single && push!(args, "-a") + gaps && push!(args, "-gaps") + extended && push!(args, "-ext") + timebounds && push!(args, "-tg") + bysegment && push!(args, "-tg") + full && push!(args, "-full") + + !isnothing(sigdigs) && push!(args, "-d $sigdigs") + version && push!(args, "-v") + help && push!(args, "-h") + usage && push!(args, "-u") + + args = join(args, " ") + files = join(file, " ") + cmd = `$(CSPICE_jll.dskbrief()) $args $files` + + if wait + cmd = pipeline(cmd; stdout=stdout, stderr=stderr, stdin=stdin, append=append) + end + + result = run(cmd; wait=wait) + + return result +end + + +""" +DSKEXP is a command-line program that exports data from DSK files to text files. + +# Extended Help + +!!! warning + All descriptions below were manually parsed from the commandline program's help/usage output. + +| Argument | Equivalent | Description | +| :--- | :--- | :--- | +| `dsk` | `-dsk ` | DSK kernel | +| `text` | `-text ` | output name | +| `format` | `-format ` | MKSDK format code/name | +| `precision` | `-prec <# of vertex mantissa digits (1:17)` | number of vertex mantissa digits | +""" +function dskexp( + ; dsk=nothing, text=nothing, format=nothing, precision=nothing, + stdout=stdout, stderr=stderr, stdin=stdin, append=false, wait=true, +) + args = String[] + + !isnothing(dsk) && push!(args, "-dsk $dsk") + !isnothing(text) && push!(args, "-text $text") + !isnothing(format) && push!(args, "-format $format") + !isnothing(precision) && push!(args, "-prec $precision") + + args = join(args, " ") + cmd = `$(CSPICE_jll.dskexp()) $args` + + if wait + cmd = pipeline(cmd; stdout=stdout, stderr=stderr, stdin=stdin, append=append) + end + + result = run(cmd; wait=wait) + + return result +end + + +""" +FRMDIFF is a program that samples orientation of a reference frame known to SPICE or computes differences between orientations of two reference frames known to SPICE, and either displays this orientation or these differences, or shows statistics about it or them. + +# Extended Help + +!!! warning + All descriptions below were manually parsed from the commandline program's help/usage output. + +| Argument | Equivalent | Description | +| :--- | :--- | :--- | +| `kernels` | `-k ` | supporting kernel(s) name(s)> | +| `from1` | `-f1 ` | first "from" frame, name or ID | +| `to1` | `-t1 ` | first "to" frame, name or ID | +| `frame1` | `-c1 ` | first frame for coverage look up, name or ID | +| `supporting_kernels1` | `-k1 ` | additional supporting kernel(s) for first file | +| `from2` | `-f2 ` | second "from" frame, name or ID | +| `to2` | `-t2 ` | second "to" frame, name or ID | +| `frame2` | `-c2 ` | second frame for coverage look up, name or ID | +| `supporting_kernels2` | `-k2 ` | additional supporting kernel(s) for second file | +| `angular` | `-a ` | compare angular velocities | +| `angularframe` | `-m ` | frame for angular velocities | +| `start` | `-b ` | interval start time | +| `stop` | `-e ` | interval stop time | +| `numpoints` | `-n ` | number of points | +| `timestep` | `-s