Skip to content

Commit b9583dd

Browse files
1-Bort-1claude
andcommitted
feat: save a log with its system definition and read it back
save_log(logger, system, name) writes the SystemDefinition into the log metadata under topology; definition(log) reads it from a loaded SysLog. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent fdc4531 commit b9583dd

5 files changed

Lines changed: 49 additions & 2 deletions

File tree

‎changelog.d/KiteModels.jl-322.md‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
### Added
2+
3+
- `save_log(logger, system, name)` saves a KiteUtils log with the `SystemDefinition` `system` in its metadata under `topology`, and `KiteGeometry.definition(log)` reads it back from a log `load_log` loaded.

‎docs/src/structure.md‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,18 @@ from_yaml
2727
to_yaml
2828
from_json
2929
to_json
30-
KiteGeometry.definition
3130
connectivity_sha
3231
```
3332

33+
## Logs
34+
35+
A KiteUtils log carries a system definition as JSON in its metadata under the key `topology`. Saving a log with the definition writes it there, and `KiteGeometry.definition` reads it back from the loaded log or from the string itself.
36+
37+
```@docs
38+
KiteGeometry.KiteUtils.save_log(::KiteGeometry.Logger, ::SystemDefinition)
39+
KiteGeometry.definition
40+
```
41+
3442
## SymbolicAWEModels' authoring YAML
3543

3644
SymbolicAWEModels authors a system in design coordinates: points at `pos_cad`, tethers by their segment count and stretched length, `variables` shared between rows, and `transforms` that turn the whole to an elevation, azimuth and heading. `load_authoring` converts that dialect into a placed `SystemDefinition`, so `structure_document` writes it as the full-form document. Values a row leaves out — segment material, every winch's gear ratio and drum radius — come from KiteUtils `Settings`. A `canopy_faces` table with the schema's own columns states each wing's canopy: a face's wing, and its corners by name or index. A filled cell that neither the loader nor the row's model reads is refused, as `load_structure` refuses one, naming the block and its columns, and so is a block it does not read that holds rows; a row's `idx`, where it has one, must be its position. A column a dict row leaves out is an unset cell, which a model field holds only where it admits `nothing`.

‎src/KiteGeometry.jl‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ for more information.
1515
module KiteGeometry
1616

1717
using JSON: JSON
18-
using KiteUtils: Settings, wrap2pi
18+
using KiteUtils: KiteUtils, Logger, Settings, SysLog, save_log, wrap2pi
1919
using LinearAlgebra: Diagonal, I, cross, dot, norm, normalize
2020
using OrderedCollections: OrderedDict, OrderedSet
2121
using SHA: sha256

‎src/document.jl‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,27 @@ The `SystemDefinition` in the JSON structure document a log carries under the ke
199199
"""
200200
definition(topology::AbstractString; strict=true) = from_json(topology; strict)
201201

202+
"""
203+
definition(log::SysLog; strict=true)
204+
205+
The `SystemDefinition` a log loaded by `load_log` carries under its metadata key
206+
`topology`.
207+
"""
208+
definition(log::SysLog; strict=true) = definition(log.metadata["topology"]; strict)
209+
210+
"""
211+
save_log(logger::Logger, system::SystemDefinition, name="sim_log", compress=true;
212+
metadata=Dict{String, String}(), kwargs...)
213+
214+
`save_log(logger, name, compress; metadata, kwargs...)` with `system` added to
215+
`metadata` as JSON under the key `topology`, which `KiteGeometry.definition` reads back.
216+
"""
217+
function KiteUtils.save_log(logger::Logger, system::SystemDefinition, name="sim_log",
218+
compress=true; metadata=Dict{String, String}(), kwargs...)
219+
metadata = merge(metadata, Dict("topology" => to_json(system)))
220+
return save_log(logger, name, compress; metadata, kwargs...)
221+
end
222+
202223
"""
203224
to_yaml(system::SystemDefinition)
204225

‎test/test-log.jl‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# SPDX-FileCopyrightText: 2026 Bart van de Lint
2+
# SPDX-License-Identifier: MIT
3+
4+
using KiteUtils: Logger, SysState, load_log, log!, save_log
5+
6+
@testset "a log saved with a system definition reads it back" begin
7+
system = load_structure(joinpath(@__DIR__, "data", "v3_beam_structure.yml"))
8+
logger = Logger(3, 2)
9+
log!(logger, SysState(3))
10+
path = mktempdir()
11+
save_log(logger, system, "topology"; path, metadata=Dict("note" => "kept"))
12+
log = load_log("topology"; path)
13+
@test structure_document(KiteGeometry.definition(log)) == structure_document(system)
14+
@test log.metadata["note"] == "kept"
15+
end

0 commit comments

Comments
 (0)