Skip to content

Commit 45fb97d

Browse files
Packagecompile (#53) close #52
* package compiler seems to have worked * fixing inclusion of transitive dependencies * small addition * adapting package compiler to testdata artifact and adapting a bit more here and there - rewritten all tests to use @testitem - reverting to using [extras]/[targets] instead of test/Project.toml because this works better with @testitem in that dependencies from main do not need to be duplicated - rerun just precompilestatements * improving justfile
1 parent e853686 commit 45fb97d

13 files changed

+1547
-123
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@
55
/docs/build/
66
Manifest.toml
77
tmp/
8+
/packagecompiler/app
9+
/packagecompiler/app.backup

Project.toml

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ version = "1.0.0-DEV"
66
[deps]
77
ArchGDAL = "c9ce4bd3-c3d5-55b8-8973-c0e20141b8c3"
88
ArgParse = "c7e460c6-2fb9-53a9-8c5b-16f535851c63"
9-
CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0"
109
ConstructionBase = "187b0558-2788-49d3-abe0-74a17ed4e7c9"
1110
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
1211
DimensionalData = "0703355e-b756-11e9-17c0-8b28908087d0"
@@ -26,12 +25,15 @@ LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
2625
LoggingExtras = "e6f89c97-d47a-5376-807f-9c37f3926c36"
2726
Missings = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28"
2827
NetCDF = "30363a11-5582-574a-97bb-aa9a979735b9"
28+
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
29+
2930
Proj = "c94c279d-25a6-4763-9509-64d165bea63e"
3031
Rasters = "a3a2b9e3-a471-40c9-b274-f788e487c689"
3132
RecurrenceAnalysis = "639c3291-70d9-5ea2-8c5b-839eba1ee399"
3233
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
3334
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
3435
StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
36+
TestItems = "1c621080-faea-4a02-84b6-bbd5e436b8fe"
3537
TimeseriesSurrogates = "c804724b-8c18-5caa-8579-6025a0767c70"
3638
UnicodePlots = "b8865327-cd53-5732-bb35-84acbb429228"
3739
YAXArrayBase = "90b8fcef-0c2d-428d-9c56-5f86629e9d14"
@@ -41,7 +43,6 @@ Zarr = "0a941bbe-ad1d-11e8-39d9-ab76183a1d99"
4143
[compat]
4244
ArchGDAL = "0.10"
4345
ArgParse = "1"
44-
CairoMakie = "0.12"
4546
ConstructionBase = "1"
4647
DimensionalData = "0.29"
4748
DiskArrayTools = "0.1"
@@ -54,18 +55,30 @@ GDAL = "1"
5455
GeoFormatTypes = "0.4"
5556
Glob = "1"
5657
KML = "0.2"
57-
LinearAlgebra = "1.10.0, 1.11.0"
58+
LinearAlgebra = "1.10"
5859
LoggingExtras = "1"
5960
Missings = "1"
6061
NetCDF = "0.12"
6162
Proj = "1"
6263
Rasters = "0.12,0.13"
6364
RecurrenceAnalysis = "2"
64-
Statistics = "1"
65+
Statistics = "1.10"
66+
TestItems = "1.0.0"
6567
TimeseriesSurrogates = "2"
6668
UnicodePlots = "3"
6769
YAXArrayBase = "0.6, 0.7"
6870
YAXArrays = "0.5"
6971
Zarr = "0.9"
7072
julia = "1.10"
7173

74+
[extras]
75+
AllocCheck = "9b6a8646-10ed-4001-bbdc-1d2f46dfbb1a"
76+
BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
77+
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
78+
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
79+
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
80+
TestItemRunner = "f8b46487-2199-4994-9208-9a1283c18c0a"
81+
82+
83+
[targets]
84+
test = ["Test", "TestItemRunner", "Pkg", "Random", "AllocCheck", "BenchmarkTools"]

justfile

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
default:
2+
just --list
3+
4+
# create precompile statements used for `just packagecompile`
5+
precompilestatements:
6+
julia --project -e 'import Pkg; Pkg.test(julia_args=`--trace-compile=packagecompiler/precompile_statements.jl`)'
7+
8+
# build an app at `packagecompiler/app/RQADeforestation` with PackageCompiler.jl
9+
packagecompile:
10+
#!/usr/bin/env -S julia --project=packagecompiler
11+
using PackageCompiler
12+
if isdir("packagecompiler/app")
13+
rm("packagecompiler/app.backup", recursive=true, force=true)
14+
mv("packagecompiler/app", "packagecompiler/app.backup")
15+
end
16+
PackageCompiler.create_app(".", "packagecompiler/app";
17+
precompile_statements_file="packagecompiler/precompile_statements.jl",
18+
# see https://github.com/JuliaLang/PackageCompiler.jl/issues/994
19+
include_lazy_artifacts=true,
20+
# or try the following, which may work because IntelOpenMP and MKL may actually not be needed
21+
# include_transitive_dependencies=false,
22+
)
23+
# lets have an easy check whether this actually worked
24+
touch("packagecompiler/app/done")
25+
26+
# test the app `packagecompiler/app/RQADeforestation` with testdata, writing data to `test/tmp/apptestdata`
27+
testapp:
28+
#!/usr/bin/env bash
29+
cd test
30+
indir="tmp/apptestdata/in"
31+
outdir="tmp/apptestdata/out.zarr"
32+
julia --project -e '
33+
import Pkg: Artifacts.@artifact_str, ensure_artifact_installed
34+
ensure_artifact_installed("rqatestdata", "Artifacts.toml")
35+
testdatapath = joinpath(artifact"rqatestdata", "RQADeforestationTestData-1.0")
36+
testdir = dirname(ARGS[1])
37+
rm(testdir, recursive=true, force=true)
38+
mkpath(testdir)
39+
cp(testdatapath, ARGS[1])
40+
' -- "$indir"
41+
../packagecompiler/app/bin/RQADeforestation --tile E051N018T3 --continent EU --in-dir "$indir" --out-dir "$outdir"

packagecompiler/Project.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[deps]
2+
PackageCompiler = "9b87118b-4619-50d2-8e1e-99f35a4d4d9d"

packagecompiler/precompile_statements.jl

Lines changed: 1260 additions & 0 deletions
Large diffs are not rendered by default.

src/RQADeforestation.jl

Lines changed: 3 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -7,70 +7,15 @@ using YAXArrays
77
using Zarr
88
using Distributed: myid
99
using NetCDF
10+
using TestItems
1011

1112
export gdalcube, rqatrend
1213

14+
include("metrics.jl")
1315
include("auxil.jl")
1416
include("rqatrend.jl")
1517
include("analysis.jl") # TODO what is still needed from analysis now that rqatrend is in its own file?
1618
include("timestats.jl")
17-
18-
19-
function main(tiles=["E048N018T3"]; pol="VH", orbit="*", thresh=3.0)
20-
indir = "/eodc/products/eodc.eu/S1_CSAR_IWGRDH/SIG0/"
21-
continent = "EU"
22-
folders = ["V01R01", "V0M2R4", "V1M0R1", "V1M1R1", "V1M1R2"]
23-
corruptedfiles = "corrupted_tiles.txt"
24-
# TODO save the corrupt files to a txt for investigation
25-
for tilefolder in tiles
26-
27-
filenamelist = [glob("$(sub)/*$(continent)*20M/$(tilefolder)/*$(pol)_$(orbit)*.tif", indir) for sub in folders]
28-
29-
allfilenames = collect(Iterators.flatten(filenamelist))
30-
31-
32-
relorbits = unique([split(basename(x), "_")[5][2:end] for x in allfilenames])
33-
@show relorbits
34-
for relorbit in relorbits
35-
for y in [2018, 2019, 2020, 2021, 2022, 2023]
36-
37-
filenames = allfilenames[findall(contains("$(relorbit)_E"), allfilenames)]
38-
@time cube = gdalcube(filenames)
39-
40-
path = joinpath(YAXDefaults.workdir[], "$(tilefolder)_rqatrend_$(pol)_$(relorbit)_thresh_$(thresh)_year_$(y)")
41-
@show path
42-
ispath(path * ".done") && continue
43-
ispath(path * "_zerotimesteps.done") && continue
44-
45-
tcube = cube[Time=Date(y - 1, 7, 1) .. Date(y + 1, 7, 1)]
46-
@show size(cube)
47-
@show size(tcube)
48-
if size(tcube, Ti) == 0
49-
touch(path * "_zerotimesteps.done")
50-
continue
51-
end
52-
try
53-
@time rqatrend(tcube; thresh, outpath=path * ".zarr", overwrite=true)
54-
catch e
55-
56-
if e.captured.ex isa ArchGDAL.GDAL.GDALError
57-
println("Found GDALError:")
58-
println(e.captured.ex.msg)
59-
continue
60-
else
61-
rethrow(e)
62-
end
63-
end
64-
#=@everywhere begin
65-
fname = "$(VERSION)_$(getpid())_$(time_ns()).heapsnapshot"
66-
Profile.take_heap_snapshot(fname;streaming=true)
67-
end
68-
=#
69-
70-
touch(path * ".done")
71-
end
72-
end
73-
end
74-
end
19+
include("main.jl")
7520

7621
end

src/auxil.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,9 @@ function gdalcube(filenames::AbstractVector{<:AbstractString})
120120
stacked_gdbs = diskstack(all_gdbs)
121121
attrs = copy(gdb.attrs)
122122
#attrs["add_offset"] = Float16(attrs["add_offset"])
123-
attrs["scale_factor"] = Float16(attrs["scale_factor"])
123+
if haskey(attrs, "scale_factor")
124+
attrs["scale_factor"] = Float16(attrs["scale_factor"])
125+
end
124126
all_cfs = CFDiskArray(stacked_gdbs, attrs)
125127
return YAXArray((onecube.axes..., taxis), all_cfs, onecube.properties)
126128
#datasetgroups = [datasets[group] for group in groupinds]

src/main.jl

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
using ArgParse
2+
using YAXArrays: YAXDefaults
3+
4+
const argparsesettings = ArgParseSettings()
5+
@add_arg_table! argparsesettings begin
6+
"--threshold", "-t"
7+
help = "Threshold for the recurrence matrix computation"
8+
default = 3.0
9+
10+
"--polarisation", "-p"
11+
help = "Polarisation that should be stacked"
12+
default = "VH"
13+
14+
"--years", "--year", "-y"
15+
help = "Year in which the RQA Trend should be detected.
16+
We take a buffer of six month before and after the year to end up with two years of data."
17+
default = [2018, 2019, 2020, 2021, 2022, 2023]
18+
nargs = '+'
19+
arg_type = Int
20+
21+
"--orbit", "-o"
22+
help = "One of: Orbit number, 'A' for ascending, 'D' for descending, '*' for all orbits"
23+
default = "*"
24+
25+
"--out-dir", "-d"
26+
help = "Path to output zarr dataset"
27+
default = "out.zarr"
28+
dest_name = "outdir"
29+
30+
"--in-dir"
31+
help = "Path to input"
32+
required = true
33+
dest_name = "indir"
34+
35+
"--continent"
36+
help = "continent code for the tile to be processed"
37+
required = true
38+
39+
"--tiles", "--tile"
40+
help = "Tile id to be processed"
41+
required = true
42+
nargs = '+'
43+
arg_type = String
44+
45+
"--folders", "--folder"
46+
help = "subfolders taken into account"
47+
default = ["V01R01", "V0M2R4", "V1M0R1", "V1M1R1", "V1M1R2"]
48+
arg_type = String
49+
nargs = '*'
50+
end
51+
52+
53+
function julia_main()::Cint
54+
main(; Dict(Symbol(k) => v for (k, v) in parse_args(argparsesettings))...)
55+
return 0
56+
end
57+
58+
59+
function main(;
60+
tiles::Vector{String},
61+
continent::String,
62+
indir::String,
63+
outdir="out.zarr",
64+
years=[2018, 2019, 2020, 2021, 2022, 2023],
65+
polarisation="VH",
66+
orbit="*",
67+
threshold=3.0,
68+
folders=["V01R01", "V0M2R4", "V1M0R1", "V1M1R1", "V1M1R2"]
69+
)
70+
if isdir(indir) && isempty(indir)
71+
error("Input directory $indir must not be empty")
72+
end
73+
if isdir(outdir)
74+
@warn "Resume from existing output directory"
75+
else
76+
mkdir(outdir)
77+
@info "Write output to $outdir"
78+
end
79+
YAXDefaults.workdir[] = outdir
80+
81+
corruptedfiles = "corrupted_tiles.txt"
82+
# TODO save the corrupt files to a txt for investigation
83+
for tilefolder in tiles
84+
85+
filenamelist = [glob("$(sub)/*$(continent)*20M/$(tilefolder)/*$(polarisation)_$(orbit)*.tif", indir) for sub in folders]
86+
allfilenames = collect(Iterators.flatten(filenamelist))
87+
@show allfilenames
88+
89+
relorbits = unique([split(basename(x), "_")[5][2:end] for x in allfilenames])
90+
@show relorbits
91+
for relorbit in relorbits
92+
for y in years
93+
94+
filenames = allfilenames[findall(contains("$(relorbit)_E"), allfilenames)]
95+
@time cube = gdalcube(filenames)
96+
97+
path = joinpath(YAXDefaults.workdir[], "$(tilefolder)_rqatrend_$(polarisation)_$(relorbit)_thresh_$(threshold)_year_$(y)")
98+
@show path
99+
ispath(path * ".done") && continue
100+
ispath(path * "_zerotimesteps.done") && continue
101+
102+
tcube = cube[Time=Date(y - 1, 7, 1) .. Date(y + 1, 7, 1)]
103+
@show size(cube)
104+
@show size(tcube)
105+
if size(tcube, 3) == 0
106+
touch(path * "_zerotimesteps.done")
107+
continue
108+
end
109+
try
110+
@time rqatrend(tcube; thresh=threshold, outpath=path * ".zarr", overwrite=true)
111+
catch e
112+
113+
if hasproperty(e, :captured) && e.captured.ex isa ArchGDAL.GDAL.GDALError
114+
println("Found GDALError:")
115+
println(e.captured.ex.msg)
116+
continue
117+
else
118+
rethrow(e)
119+
end
120+
end
121+
#=@everywhere begin
122+
fname = "$(VERSION)_$(getpid())_$(time_ns()).heapsnapshot"
123+
Profile.take_heap_snapshot(fname;streaming=true)
124+
end
125+
=#
126+
touch(path * ".done")
127+
end
128+
end
129+
end
130+
end

src/metrics.jl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import Distances
2+
struct CheckedEuclidean <: Distances.UnionMinkowskiMetric end
3+
4+
@inline (dist::CheckedEuclidean)(a, b) = Distances._evaluate(dist, a, b, Distances.parameters(dist))
5+
@inline Distances.eval_op(::CheckedEuclidean, ai::Number, bi::Number) = abs(ai - bi)
6+
@inline Distances.eval_op(::CheckedEuclidean, ai::Integer, bi::Integer) = Base.Checked.abs(Base.Checked.checked_sub(ai, bi))
7+
Distances.eval_end(::CheckedEuclidean, s) = s
8+
9+
10+
@testitem "CheckedEuclidean" begin
11+
# this nested using seems necesarry because of using test/Project.toml
12+
using Distances
13+
@test evaluate(RQADeforestation.CheckedEuclidean(), 2, 5) == evaluate(Euclidean(), 2, 5)
14+
end

0 commit comments

Comments
 (0)