Skip to content

Commit 3042035

Browse files
committed
small typos/nitpick fixes and coderabbit suggestions implemented
1 parent 616a9d8 commit 3042035

File tree

6 files changed

+64
-67
lines changed

6 files changed

+64
-67
lines changed

experiments/standalone/Snow/snowmip_simulation.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,14 @@ using DelimitedFiles
2222

2323
# Site-specific quantities
2424
# Error if no site argument is provided
25+
#=
2526
if length(ARGS) < 1
2627
@error("Please provide a site name as command line argument")
2728
else
2829
SITE_NAME = ARGS[1]
2930
end
31+
=#
32+
SITE_NAME = "cdp"
3033

3134
climaland_dir = pkgdir(ClimaLand)
3235

ext/neural_snow/ModelTools.jl

Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export make_model,
1313
save_predictive_model_weights,
1414
load_model_weights!,
1515
freeze_fixed_layers!,
16-
convert_model!
16+
convert_model
1717

1818
include("./WebTools.jl")
1919

@@ -165,19 +165,19 @@ paper_lower_bound(
165165

166166

167167
"""
168-
convert_model!(model, FT)
168+
convert_model(model, FT)
169169
Provides a utility funciton to set a model's float type by passing
170170
the type as an argument.
171171
"""
172-
function convert_model!(model, FT::Type{<:AbstractFloat})
172+
function convert_model(model, FT::Type{<:AbstractFloat})
173173
if FT == Float32
174174
model = Flux.f32(model)
175175
elseif FT == Float64
176176
model = Flux.f64(model)
177177
else
178178
error(
179179
"Conversion of Flux Chain weights to the desired float-type is not supported. Please implement the desired conversion
180-
in ModelTools.convert_model!() or a custom constructor for the desired type.",
180+
in ModelTools.convert_model() or a custom constructor for the desired type.",
181181
)
182182
end
183183
return model
@@ -258,7 +258,7 @@ function make_model(
258258
apply_upper = Dense(get_min, false, relu),
259259
sumlayer = MulLayer(final_mul),
260260
)
261-
return convert_model!(model, FT)
261+
return convert_model(model, FT)
262262
end
263263
end
264264

@@ -357,7 +357,7 @@ function make_model_paper(;
357357
apply_upper = Dense(get_min, false, relu),
358358
sumlayer = MulLayer(final_mul),
359359
)
360-
return convert_model!(model, FT)
360+
return convert_model(model, FT)
361361
end
362362
end
363363

@@ -378,10 +378,10 @@ of the predictive component by the constant `scale`.
378378
# Arguments
379379
- `model::Chain`: the neural model to be scaled.
380380
- `scale::Real`: the scaling parameter to return data to applicable units.
381-
- `dtype::Type`: Sets type, consistent with neural model. Default is `Float32`.
382381
"""
383-
function setoutscale!(model::Chain, scale::Real; dtype::Type = Float32)
384-
model[:apply_relus].weight[end, 3] = dtype(-1 * scale)
382+
function setoutscale!(model::Chain, scale::Real)
383+
FT = eltype(model[:apply_relus].weight)
384+
model[:apply_relus].weight[end, 3] = FT(-1 * scale)
385385
end
386386

387387

@@ -408,21 +408,16 @@ directly by the constant `scale`.
408408
- `model::Chain`: the neural model to be scaled.
409409
- `bound`::Symbol: specifies the upper or lower bound with :upper or :lower.
410410
- `scale::Real`: the scaling parameter to return data to applicable units.
411-
- `dtype::Type`: Sets type, consistent with neural model. Default is `Float32`.
412411
"""
413-
function setboundscale!(
414-
model::Chain,
415-
bound::Symbol,
416-
scale::Real;
417-
dtype::Type = Float32,
418-
)
412+
function setboundscale!(model::Chain, bound::Symbol, scale::Real;)
413+
FT = eltype(model[:apply_relus].weight)
419414
if bound == :upper
420-
model[:apply_relus].weight[1, 1] = dtype(1.0 * scale)
421-
model[:apply_relus].weight[2, 1] = dtype(-1.0 * scale)
422-
model[:apply_relus].weight[5, 1] = dtype(-1.0 * scale)
415+
model[:apply_relus].weight[1, 1] = FT(1.0 * scale)
416+
model[:apply_relus].weight[2, 1] = FT(-1.0 * scale)
417+
model[:apply_relus].weight[5, 1] = FT(-1.0 * scale)
423418
elseif bound == :lower
424-
model[:apply_relus].weight[3, 2] = dtype(1.0 * scale)
425-
model[:apply_relus].weight[4, 2] = dtype(-1.0 * scale)
419+
model[:apply_relus].weight[3, 2] = FT(1.0 * scale)
420+
model[:apply_relus].weight[4, 2] = FT(-1.0 * scale)
426421
else
427422
error("provided `bound` must be `:upper` or `:lower`.")
428423
end
@@ -439,10 +434,10 @@ a custom form of `setboundscale!()` to use with the custom model type made with
439434
# Arguments
440435
- `model::Chain`: the neural model to be used.
441436
- `dt::Real`: the number of seconds per timestep for usage.
442-
- `dtype::Type`: Sets type, consistent with neural model. Default is `Float32`.
443437
"""
444-
function settimescale!(model::Chain, dt::Real; dtype::Type = Float32)
445-
model[:apply_relus].weight[2, 2] = dtype(1.0 / dt)
438+
function settimescale!(model::Chain, dt::Real)
439+
FT = eltype(model[:apply_relus].weight)
440+
model[:apply_relus].weight[2, 2] = FT(1.0 / dt)
446441
end
447442

448443
"""
@@ -840,8 +835,12 @@ and in a way that is stable to changing versions of the Flux package.
840835
# Arguments
841836
- `path`::String: The filepath (or URL) from where to get the text file.
842837
- `model`: the model for which to load in the predictive parameters.
838+
- `FT` : Optional arg for passing the right Float type if not inferred from passed model.
843839
"""
844840
function load_model_weights!(filepath::String, model::Chain; FT = Float32)
841+
T =
842+
hasproperty(model.layers, :apply_relus) ?
843+
eltype(model[:apply_relus].weight) : FT
845844
data = Dict() # Dictionary to store the parsed data
846845
# Check if the filepath is a URL
847846
if startswith(filepath, "http://") || startswith(filepath, "https://")
@@ -869,7 +868,7 @@ function load_model_weights!(filepath::String, model::Chain; FT = Float32)
869868
elseif isnothing(current_name)
870869
current_name = line
871870
else
872-
push!(current_values, parse.(FT, split(line)))
871+
push!(current_values, parse.(T, split(line)))
873872
end
874873
end
875874
# Handle the last item (if file doesn't end with a blank line)

ext/neural_snow/WebTools.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using Downloads, DataFrames
1+
using Downloads, DataFrames, Dates
22
export read_webpage_body, df_from_url
33

44
const extension_dir_path = @__DIR__()

src/standalone/Snow/AndersonModel.jl

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,15 @@ Base.@kwdef struct Anderson1976{FT} <: AbstractDensityModel{FT}
2323
c3::FT = FT(0.005)
2424
c4::FT = FT(0.10)
2525
c5::FT = FT(0)
26-
cx::FT = FT(0.15)
27-
ρ_d::FT = FT(23.0)
26+
cx::FT = FT(23)
27+
ρ_d::FT = FT(0.15)
2828
end
2929

3030

3131
#Define the additional prognostic variables needed for using this parameterization:
32-
density_prog_vars(m::Anderson1976) =
33-
(:Z,)
34-
density_prog_types(m::Anderson1976{FT}) where {FT} =
35-
(FT,)
36-
density_prog_names(m::Anderson1976) =
37-
(:surface,)
32+
density_prog_vars(m::Anderson1976) = (:Z,)
33+
density_prog_types(m::Anderson1976{FT}) where {FT} = (FT,)
34+
density_prog_names(m::Anderson1976) = (:surface,)
3835

3936

4037
"""
@@ -116,7 +113,12 @@ Returns the change in snow depth (rate) given the current model state and the `A
116113
density paramterization, which estimates contributions from new snowfall, as well as compaction
117114
effects from the existing and newly fallen snow.
118115
"""
119-
function get_dzdt(density::Anderson1976{FT}, model::SnowModel{FT}, Y, p) where {FT}
116+
function get_dzdt(
117+
density::Anderson1976{FT},
118+
model::SnowModel{FT},
119+
Y,
120+
p,
121+
) where {FT}
120122
Δt_t = model.parameters.Δt / 3600 #in hours (when Δt in SnowParameters is ::FT instead of ::Period)
121123

122124
#Contribution from new snowfall: (uses parameterization of newsnow_temp, newsnow_density)
@@ -136,7 +138,8 @@ function get_dzdt(density::Anderson1976{FT}, model::SnowModel{FT}, Y, p) where {
136138
Δz = snowfall ./ ρ_newsnow
137139

138140
#Estimate resulting change from compaction effects of old snow (and the incoming snow on top):
139-
S_snowheight = swe_snow_area.(Y.snow.S, p.snow.snow_cover_fraction, Y.snow.Z)
141+
S_snowheight =
142+
swe_snow_area.(Y.snow.S, p.snow.snow_cover_fraction, Y.snow.Z)
140143
W_ice = (1 .- p.snow.q_l) .* S_snowheight #S_snowheight instead of Y.snow.S
141144
ρ_ice = W_ice ./ Y.snow.Z #unitless
142145
sliq = p.snow.q_l .* S_snowheight
@@ -150,6 +153,10 @@ function get_dzdt(density::Anderson1976{FT}, model::SnowModel{FT}, Y, p) where {
150153
end
151154

152155

156+
# Do we want to change the type assertion to ::Union{Anderson1976, NeuralDepthModel} in NeuralDepthModel
157+
# to avoid redundancy since the two are identical and use the same functionality, or is better to keep
158+
# them separate and visible with their own code file? I can always just comment this one out like I did
159+
# above/below with clip_dZdt() and swe_snow_area.
153160
"""
154161
update_density_and_depth!(ρ_snow, z_snow,density::Anderson1976, Y, p, params::SnowParameters,)
155162
@@ -210,19 +217,8 @@ end
210217
Updates all prognostic variables associated with density/depth given the current model state and the `Anderson1976`
211218
density paramterization.
212219
"""
213-
function update_density_prog!(
214-
density::Anderson1976,
215-
model::SnowModel,
216-
dY,
217-
Y,
218-
p,
219-
)
220-
dY.snow.Z .= get_dzdt(
221-
density,
222-
model,
223-
Y,
224-
p
225-
)
220+
function update_density_prog!(density::Anderson1976, model::SnowModel, dY, Y, p)
221+
dY.snow.Z .= get_dzdt(density, model, Y, p)
226222

227223
# Now we clip the tendency so that Z stays within approximately physical bounds.
228224
@. dY.snow.Z = clip_dZdt(

src/standalone/Snow/NeuralDepthModel.jl

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import ClimaLand.Snow:
88
density_prog_names,
99
update_density_and_depth!,
1010
update_density_prog!
11-
import ClimaLand.Parameters as LP
1211
using Thermodynamics
1312

1413
export NeuralDepthModel
@@ -33,7 +32,7 @@ end
3332
Retrieves the network weights for the snow depth model formulated in Charbonneau et. al., 2025,
3433
and stores/returns them within a dictionary to enable easy loading of the weights into the generated
3534
neural model.
36-
Note that because we are loading from a document of pre-trained weights,
35+
Note that because we are loading from an unchanging document of pre-trained weights,
3736
the weight sizes are hard-coded in the function below.
3837
3938
# Arguments
@@ -42,7 +41,7 @@ the weight sizes are hard-coded in the function below.
4241
function get_network_weights(FT::DataType)
4342
weightfile =
4443
readlines(ClimaLand.Artifacts.neural_depth_model_weights_path())
45-
@assert length(weightfile) == 56 "Might not be reading the right weight file, expected 56 lines and got $(length(weightfile))"
44+
@assert length(weightfile) == 56 "Artifact path might need updating, expected 56 lines and got $(length(weightfile))"
4645
data = Dict()
4746
data["SCALING"] = parse.(FT, split(weightfile[2], " "))
4847
data["l1_WEIGHT"] =
@@ -129,7 +128,7 @@ end
129128

130129

131130
"""
132-
setoutscale!(model, scale; dtype)
131+
setoutscale!(model, scale)
133132
Set the physical scaling parameter for model usage (i.e. rectifying scaling done on model input).
134133
This scaling constant is combined with a -1 factor that enforces the boundary for speed and memory purposes -
135134
for this reason, we do not recommend first `extracting`/storing the weight this function refers to,
@@ -140,24 +139,24 @@ of the predictive component by the constant `scale`.
140139
# Arguments
141140
- `model::Chain`: the neural model to be used.
142141
- `scale::Real`: the scaling parameter to return data to applicable units.
143-
- `dtype::Type`: Sets type, consistent with neural model. Default is `Float32`.
144142
"""
145-
function setoutscale!(model, scale::Real; dtype::Type = Float32)
146-
model[:apply_relus].weight[end, 3] = dtype(-1 * scale)
143+
function setoutscale!(model, scale::Real)
144+
FT = eltype(model[:apply_relus].weight)
145+
model[:apply_relus].weight[end, 3] = FT(-1 * scale)
147146
end
148147

149148

150149
"""
151-
settimescale!(model, dt; dtype)
150+
settimescale!(model, dt)
152151
Set the timescale parameter for model usage
153152
154153
# Arguments
155154
- `model::Chain`: the neural model to be used.
156155
- `dt::Real`: the number of seconds per timestep for usage.
157-
- `dtype::Type`: Sets type, consistent with neural model. Default is `Float32`.
158156
"""
159-
function settimescale!(model, dt::Real; dtype::Type = Float32)
160-
model[:apply_relus].weight[2, 2] = dtype(1.0 / dt)
157+
function settimescale!(model, dt::Real)
158+
FT = eltype(model[:apply_relus].weight)
159+
model[:apply_relus].weight[2, 2] = FT(1.0 / dt)
161160
end
162161

163162
"""
@@ -179,8 +178,8 @@ function get_znetwork(; FT = Float32)
179178
network[:pred].layers.layers[:l2].bias .= data["l2_BIAS"]
180179
network[:pred].layers.layers[:l3].weight .= data["l3_WEIGHT"]
181180
network[:pred].layers.layers[:l3].bias .= data["l3_BIAS"]
182-
setoutscale!(network, data["FINALSCALE"], dtype = FT)
183-
settimescale!(network, 86400, dtype = FT)
181+
setoutscale!(network, data["FINALSCALE"])
182+
settimescale!(network, 86400)
184183
return network
185184
end
186185

@@ -204,7 +203,7 @@ function NeuralDepthModel(
204203
usemodel = get_znetwork(FT = FT)
205204
weight = !isnothing(α) ? FT(α) : FT(2 / 86400)
206205
if !isnothing(Δt)
207-
settimescale!(usemodel, Δt, dtype = FT) #assumes Δt is provided in seconds
206+
settimescale!(usemodel, Δt) #assumes Δt is provided in seconds
208207
if (Δt > 43200) && isnothing(α)
209208
error("Please supply a weight for the
210209
exponential moving average, the
@@ -250,7 +249,7 @@ as the depth over the snow-covered portion and S is provided as the depth over t
250249
Used in computing the time derivative of snow depth.
251250
"""
252251
function swe_snow_area(S::FT, scf::FT, z::FT)::FT where {FT}
253-
min_scf = 0.05
252+
min_scf = 0.05 #placeholder until Katherine and Andy discuss how to implement this
254253
return min(z, S / max(scf, min_scf)) #double check if this is the formula Katherine wants? see clip_dzdt() too.
255254
end
256255

@@ -316,12 +315,12 @@ function clip_dZdt(
316315
scf::FT,
317316
Δt::FT,
318317
)::FT where {FT}
319-
min_scf = 0.05
318+
min_scf = 0.05 #placeholder until Katherine and Andy discuss this
320319
#Case if S is set to zero:
321320
if (S + dSdt * Δt) <= eps(FT)
322321
return -Z / Δt
323322
#Case if Z would have been set to Z < S:
324-
elseif (Z + dZdt * Δt) * max(scf, min_scf) < (S + dSdt * Δt)
323+
elseif (Z + dZdt * Δt) * max(scf, min_scf) < (S + dSdt * Δt) #technically, the scf used here should be the scf of the following timestep, so how to handle this?
325324
#more stable form for very small Z, S
326325
return ((dSdt * Δt + S) / max(scf, min_scf) - Z) / Δt
327326
else

test/standalone/Snow/tool_tests.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ if !isnothing(DataToolsExt)
258258
end
259259

260260
@test eltype(model[:pred].layers[:l1].weight) == Float32
261-
model64 = ModelTools.convert_model!(deepcopy(model), Float64)
261+
model64 = ModelTools.convert_model(deepcopy(model), Float64)
262262
@test eltype(model64[:pred].layers[:l1].weight) == Float64
263263
test_input = Matrix{Float32}(ones(nfeatures, 8))
264264
test_output = model(test_input)

0 commit comments

Comments
 (0)