Serialises a list of result records to analysis.json, analysis.csv, and
manifest.json under output_dir and returns a grayleafspot_run object.
Usage
write_grayleafspot_results(
results,
output_dir,
engine = "python-local",
engine_model = "packaged-python-pipeline",
run_name = NULL
)Arguments
- results
A list of per-image result records (as produced by the Python pipeline or
analyze_grayleafspot_image()).- output_dir
Character. Directory to write outputs into (created if absent).
- engine
Character. Engine label stored in the manifest.
- engine_model
Character. Engine-model label stored in the manifest.
- run_name
Optional character. Human-readable run name for the manifest.
Examples
run <- example_grayleafspot_results()
write_grayleafspot_results(run$raw_results, tempdir(), run_name = "demo")
#> $run
#> $run$id
#> [1] "demo"
#>
#> $run$engine
#> [1] "python-local"
#>
#> $run$engineModel
#> [1] "packaged-python-pipeline"
#>
#> $run$createdAt
#> [1] "2026-06-09T00:41:54Z"
#>
#> $run$outputDir
#> [1] "/tmp/Rtmp8FI5om"
#>
#> $run$analysisJson
#> [1] "/tmp/Rtmp8FI5om/analysis.json"
#>
#> $run$analysisCsv
#> [1] "/tmp/Rtmp8FI5om/analysis.csv"
#>
#>
#> $results
#> # A tibble: 2 × 30
#> id filename day area_mm2 radius_mm diameter_mm perimeter_mm circularity
#> <chr> <chr> <int> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 demo-1 demo_day… 1 12 1.95 3.9 8 0.8
#> 2 demo-2 demo_day… 2 18 2.39 4.78 9.1 0.77
#> # ℹ 22 more variables: eccentricity <dbl>, edge_roughness <dbl>,
#> # contrast <dbl>, correlation <dbl>, energy <dbl>, homogeneity <dbl>,
#> # entropy <dbl>, center_edge_delta <dbl>, density_index <dbl>, core <dbl>,
#> # middle <dbl>, outer <dbl>, crack_count <int>, crack_length_mm <dbl>,
#> # crack_coverage_pct <dbl>, proportional_crack_coverage_pct <dbl>,
#> # radial_velocity_mm_per_day <dbl>, area_growth_rate_mm2_per_day <dbl>,
#> # relative_growth_rate_per_day <dbl>, radial_acceleration <dbl>, …
#>
#> $raw_results
#> $raw_results[[1]]
#> $raw_results[[1]]$id
#> [1] "demo-1"
#>
#> $raw_results[[1]]$filename
#> [1] "demo_day1.png"
#>
#> $raw_results[[1]]$day
#> [1] 1
#>
#> $raw_results[[1]]$pixelToMm
#> [1] 0.1
#>
#> $raw_results[[1]]$morphology
#> $raw_results[[1]]$morphology$areaMm2
#> [1] 12
#>
#> $raw_results[[1]]$morphology$equivalentRadiusMm
#> [1] 1.95
#>
#> $raw_results[[1]]$morphology$diameterMm
#> [1] 3.9
#>
#> $raw_results[[1]]$morphology$perimeterMm
#> [1] 8
#>
#> $raw_results[[1]]$morphology$circularity
#> [1] 0.8
#>
#> $raw_results[[1]]$morphology$eccentricity
#> [1] 0.2
#>
#> $raw_results[[1]]$morphology$edgeRoughness
#> [1] 0.1
#>
#>
#> $raw_results[[1]]$texture
#> $raw_results[[1]]$texture$contrast
#> [1] 0.2
#>
#> $raw_results[[1]]$texture$correlation
#> [1] 0.1
#>
#> $raw_results[[1]]$texture$energy
#> [1] 0.3
#>
#> $raw_results[[1]]$texture$homogeneity
#> [1] 0.4
#>
#> $raw_results[[1]]$texture$entropy
#> [1] 1.2
#>
#> $raw_results[[1]]$texture$centerToEdgeDelta
#> [1] 0.05
#>
#> $raw_results[[1]]$texture$densityIndex
#> [1] 0.8
#>
#> $raw_results[[1]]$texture$radialZonation
#> $raw_results[[1]]$texture$radialZonation$core
#> [1] 0.1
#>
#> $raw_results[[1]]$texture$radialZonation$middle
#> [1] 0.2
#>
#> $raw_results[[1]]$texture$radialZonation$outer
#> [1] 0.3
#>
#>
#>
#> $raw_results[[1]]$cracks
#> $raw_results[[1]]$cracks$count
#> [1] 0
#>
#> $raw_results[[1]]$cracks$totalLengthMm
#> [1] 0
#>
#> $raw_results[[1]]$cracks$coveragePct
#> [1] 0
#>
#> $raw_results[[1]]$cracks$proportionalCoveragePct
#> [1] 0
#>
#> $raw_results[[1]]$cracks$internalBandSummary
#> [1] "Example data only."
#>
#>
#> $raw_results[[1]]$kinematics
#> $raw_results[[1]]$kinematics$radialVelocity
#> [1] 0
#>
#> $raw_results[[1]]$kinematics$areaGrowthRate
#> [1] 0
#>
#> $raw_results[[1]]$kinematics$relativeGrowthRate
#> [1] 0
#>
#> $raw_results[[1]]$kinematics$radialAcceleration
#> [1] 0
#>
#>
#> $raw_results[[1]]$qcStatus
#> [1] "pass"
#>
#> $raw_results[[1]]$qcNotes
#> [1] "ok"
#>
#> $raw_results[[1]]$rawAnalysis
#> $raw_results[[1]]$rawAnalysis$radial_profile
#> $raw_results[[1]]$rawAnalysis$radial_profile$radiusFraction
#> $raw_results[[1]]$rawAnalysis$radial_profile$radiusFraction[[1]]
#> [1] 0
#>
#> $raw_results[[1]]$rawAnalysis$radial_profile$radiusFraction[[2]]
#> [1] 1
#>
#>
#> $raw_results[[1]]$rawAnalysis$radial_profile$radiusMm
#> $raw_results[[1]]$rawAnalysis$radial_profile$radiusMm[[1]]
#> [1] 0
#>
#> $raw_results[[1]]$rawAnalysis$radial_profile$radiusMm[[2]]
#> [1] 1.95
#>
#>
#> $raw_results[[1]]$rawAnalysis$radial_profile$meanIntensity
#> $raw_results[[1]]$rawAnalysis$radial_profile$meanIntensity[[1]]
#> [1] 0.2
#>
#> $raw_results[[1]]$rawAnalysis$radial_profile$meanIntensity[[2]]
#> [1] 0.8
#>
#>
#> $raw_results[[1]]$rawAnalysis$radial_profile$ringSpacingMm
#> [1] 0.2
#>
#> $raw_results[[1]]$rawAnalysis$radial_profile$centerToEdgeDelta
#> [1] 0.05
#>
#> $raw_results[[1]]$rawAnalysis$radial_profile$densityIndex
#> [1] 0.8
#>
#>
#>
#>
#> $raw_results[[2]]
#> $raw_results[[2]]$id
#> [1] "demo-2"
#>
#> $raw_results[[2]]$filename
#> [1] "demo_day2.png"
#>
#> $raw_results[[2]]$day
#> [1] 2
#>
#> $raw_results[[2]]$pixelToMm
#> [1] 0.1
#>
#> $raw_results[[2]]$morphology
#> $raw_results[[2]]$morphology$areaMm2
#> [1] 18
#>
#> $raw_results[[2]]$morphology$equivalentRadiusMm
#> [1] 2.39
#>
#> $raw_results[[2]]$morphology$diameterMm
#> [1] 4.78
#>
#> $raw_results[[2]]$morphology$perimeterMm
#> [1] 9.1
#>
#> $raw_results[[2]]$morphology$circularity
#> [1] 0.77
#>
#> $raw_results[[2]]$morphology$eccentricity
#> [1] 0.22
#>
#> $raw_results[[2]]$morphology$edgeRoughness
#> [1] 0.12
#>
#>
#> $raw_results[[2]]$texture
#> $raw_results[[2]]$texture$contrast
#> [1] 0.24
#>
#> $raw_results[[2]]$texture$correlation
#> [1] 0.11
#>
#> $raw_results[[2]]$texture$energy
#> [1] 0.33
#>
#> $raw_results[[2]]$texture$homogeneity
#> [1] 0.42
#>
#> $raw_results[[2]]$texture$entropy
#> [1] 1.1
#>
#> $raw_results[[2]]$texture$centerToEdgeDelta
#> [1] 0.06
#>
#> $raw_results[[2]]$texture$densityIndex
#> [1] 0.81
#>
#> $raw_results[[2]]$texture$radialZonation
#> $raw_results[[2]]$texture$radialZonation$core
#> [1] 0.11
#>
#> $raw_results[[2]]$texture$radialZonation$middle
#> [1] 0.21
#>
#> $raw_results[[2]]$texture$radialZonation$outer
#> [1] 0.31
#>
#>
#>
#> $raw_results[[2]]$cracks
#> $raw_results[[2]]$cracks$count
#> [1] 1
#>
#> $raw_results[[2]]$cracks$totalLengthMm
#> [1] 0.2
#>
#> $raw_results[[2]]$cracks$coveragePct
#> [1] 2.5
#>
#> $raw_results[[2]]$cracks$proportionalCoveragePct
#> [1] 2.5
#>
#> $raw_results[[2]]$cracks$internalBandSummary
#> [1] "Example data only."
#>
#>
#> $raw_results[[2]]$kinematics
#> $raw_results[[2]]$kinematics$radialVelocity
#> [1] 0.44
#>
#> $raw_results[[2]]$kinematics$areaGrowthRate
#> [1] 6
#>
#> $raw_results[[2]]$kinematics$relativeGrowthRate
#> [1] 0.4
#>
#> $raw_results[[2]]$kinematics$radialAcceleration
#> [1] 0.44
#>
#>
#> $raw_results[[2]]$qcStatus
#> [1] "pass"
#>
#> $raw_results[[2]]$qcNotes
#> [1] "ok"
#>
#> $raw_results[[2]]$rawAnalysis
#> $raw_results[[2]]$rawAnalysis$radial_profile
#> $raw_results[[2]]$rawAnalysis$radial_profile$radiusFraction
#> $raw_results[[2]]$rawAnalysis$radial_profile$radiusFraction[[1]]
#> [1] 0
#>
#> $raw_results[[2]]$rawAnalysis$radial_profile$radiusFraction[[2]]
#> [1] 1
#>
#>
#> $raw_results[[2]]$rawAnalysis$radial_profile$radiusMm
#> $raw_results[[2]]$rawAnalysis$radial_profile$radiusMm[[1]]
#> [1] 0
#>
#> $raw_results[[2]]$rawAnalysis$radial_profile$radiusMm[[2]]
#> [1] 2.39
#>
#>
#> $raw_results[[2]]$rawAnalysis$radial_profile$meanIntensity
#> $raw_results[[2]]$rawAnalysis$radial_profile$meanIntensity[[1]]
#> [1] 0.22
#>
#> $raw_results[[2]]$rawAnalysis$radial_profile$meanIntensity[[2]]
#> [1] 0.79
#>
#>
#> $raw_results[[2]]$rawAnalysis$radial_profile$ringSpacingMm
#> [1] 0.2
#>
#> $raw_results[[2]]$rawAnalysis$radial_profile$centerToEdgeDelta
#> [1] 0.06
#>
#> $raw_results[[2]]$rawAnalysis$radial_profile$densityIndex
#> [1] 0.81
#>
#>
#>
#>
#>
#> attr(,"class")
#> [1] "grayleafspot_run"
