SugarKelp

Model of Saccharina latissima (sugar kelp) based on Broch and Slagstad, 2012

https://github.com/jagoosw/sugarkelp.jl

Science Score: 67.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
    Found CITATION.cff file
  • codemeta.json file
    Found codemeta.json file
  • .zenodo.json file
    Found .zenodo.json file
  • DOI references
    Found 1 DOI reference(s) in README
  • Academic publication links
    Links to: springer.com, zenodo.org
  • Committers with academic emails
  • Institutional organization owner
  • JOSS paper metadata
  • Scientific vocabulary similarity
    Low similarity (15.9%) to scientific vocabulary

Keywords

julia julia-language julia-library kelp model
Last synced: 6 months ago · JSON representation ·

Repository

Model of Saccharina latissima (sugar kelp) based on Broch and Slagstad, 2012

Basic Info
Statistics
  • Stars: 2
  • Watchers: 5
  • Forks: 2
  • Open Issues: 3
  • Releases: 3
Topics
julia julia-language julia-library kelp model
Created over 4 years ago · Last pushed over 1 year ago
Metadata Files
Readme License Citation

README.md

SugarKelp.jl

Logo [![DOI](https://zenodo.org/badge/383172934.svg)](https://zenodo.org/badge/latestdoi/383172934)[![Build Status](https://app.travis-ci.com/jagoosw/SugarKelp.jl.svg?branch=main)](https://app.travis-ci.com/jagoosw/SugarKelp.jl)[![codecov](https://codecov.io/gh/jagoosw/SugarKelp.jl/branch/main/graph/badge.svg?token=JG0D8UY2K8)](https://codecov.io/gh/jagoosw/SugarKelp.jl)[![pkgeval](https://juliahub.com/docs/SugarKelp/pkgeval.svg)](https://juliahub.com/ui/Packages/SugarKelp/Uh2dO)[![version](https://juliahub.com/docs/SugarKelp/version.svg)](https://juliahub.com/ui/Packages/SugarKelp/Uh2dO)

This model is now re-implemented in OceanBioME.jl where it can be coupled with biogeochemical and physics models. This version is no longer maintained and I recommend you use the OceanBioME version unless you only want to solve the kelp model equations with known environmental forcing.

Implementation of the Broch and Slagstad, 2012 model of the growth and composition of Saccharina latissima kelp.

The main way to solve a single frond is SugarKelp.solve and grids can be solved by SugarKelp.solvegrid.

Changes from the stated parameter values in the paper are detailed in changes.pdf.

This package is now available from the registry so can be installed by import Pkg;Pkg.add("SugarKelp"). Alternatively, you can install from this repo (which may be slightly updated) by import Pkg;Pkg.add("https://github.com/jagoosw/SugarKelp.jl").

Examples

Running a model

These examples for running the model both at a single point and on a grid can be found in examples.ipynb.

Example 1 - Single Point

julia using SugarKelp, Plots, Interpolations;pyplot();

Set initial conditions and parameters - ti - start day (days since January first) - needs to have the same date reference as the forcing data - nd - number of days to run for - lat - latitude as this effects the change in day length - a0,n0,c0 - initial area, nitrogen reserve and carbon reserve

julia t_i = 1.0;nd = 600;lat = 60 a_0 = 0.1;n_0 = 0.022;c_0 = 0.3;

Setting the forcing variables, these would normally be loaded from a data set but here will be generated - time - day corresponding to forcing data in days since January first (year is arbitrary). This must be a float rather than an integer or ODE solving library fails - temp - temperature in degrees C - no3 - nitrate concentration in mmol/m³ - irr - PAR irradiance in mol photons/m²/day - u - water velocity in m/s

```julia time = [1:2:800;]

temp = 6 * cos.((time .- 250) .* 2 .* pi ./ 365) .+ 8 no3 = (7 .* ((cos.(time .* 2 .* pi ./ 365) .+ 1) ./ 2).^3 .+ 0.1) ./ 1000 irr = 40 .* (sin.((time .+ 15) .* pi ./ 365).^10) .+ 1 u = repeat([0.15],400); ```

julia plot(layout=grid(1,3),size=(1000,250),legend=false) plot!(time,temp,ylabel="Temp (°C)",sp=1) plot!(time,no3,xlabel="Day",ylabel="Nitrate concentration (mmol/m³)",sp=2) plot!(time,irr,ylabel="PAR (mol photons/m²/day)",sp=3)

png

The forcing variables must be converted to interpolations for the kelp model to access them at arbitrary time

julia temp_itp=Interpolations.LinearInterpolation(time,temp) no3_itp=Interpolations.LinearInterpolation(time,no3) irr_itp=Interpolations.LinearInterpolation(time,irr) u_itp=Interpolations.LinearInterpolation(time,u);

Now the model can be run, the parameter must be passed as a NamedTuple and in this run the respiration model proposed in Broch, 2013 is being used

julia solution, results = SugarKelp.solve(t_i, nd, u_itp, temp_itp, irr_itp, no3_itp, lat, a_0, n_0, c_0, SugarKelp.broch2013params, 2);

Solutions contains the raw output of the ODE solver while results is refactored into a dataframe (this can optionally be turned off for an array to be returned)

julia results dataframe as a table that can't be rendered here

It is useful to convert the results into total carbon and nitrogen masses (rather than the reserves that the model returns), this requires some of the parameters.

julia total_carbon = results.area .* SugarKelp.broch2013params.K_A .* (results.carbon .+ SugarKelp.broch2013params.C_struct) total_nitrogen = results.area .* SugarKelp.broch2013params.K_A .* (results.nitrogen .+ SugarKelp.broch2013params.N_struct);

julia plot(layout=grid(1,3),size=(1000,250),legend=false) plot!(results.time,results.area,ylabel="Area/dm²",sp=1) plot!(results.time,total_carbon,xlabel="Day",ylabel="Total Carbon (gC)",sp=2) plot!(results.time,total_nitrogen,ylabel="Total Nitrogen (gN)",sp=3)

png

Example 2 - Grid

For a grid we must set initial conditions as with a single point

julia t_i = 1.0;nd = 300 a_0 = 0.1;n_0 = 0.022;c_0 = 0.3;

This time we will generate a 4d grid of input data for temp and no3 and 2d for nitrate. An additional variable needs to be generated, either a 3d diffuse attenuation coefficient or 4d light attenuation. In this example the latter is used. Again this would usually be loaded from a file. It is beneficial to define all of these as constants as it drastically speeds up on larger grids.

```julia const arrlon=[45:50;] const arrlat=[55:65;] const arrdep=[0:5:75;] const arrt = [0:2:310;]

const arrtemp = permutedims(repeat(6 * cos.((arrt .- 250) .* 2 .* pi ./ 365) .+ 8,1,length(arrlon),length(arrlat),length(arrdep)),(2,3,4,1)).*permutedims(repeat(arrlat./arrlat[1],1,length(arrlon),length(arrdep),length(arrt)),(2,1,3,4)) const arrno3 = permutedims(repeat((7 .* ((cos.(arrt .* 2 .* pi ./ 365) .+ 1) ./ 2).^3 .+ 0.1) ./ 1000,1,length(arrlon),length(arrlat),length(arrdep)),(2,3,4,1)).*repeat(arrlon./arrlon[1],1,length(arrlat),length(arrdep),length(arrt)) const arrirr = permutedims(repeat(40 .* (sin.((arrt .+ 15) .* pi ./ 365).^10) .+ 1,1,length(arrlon),length(arrlat)),(2,3,1)).*permutedims(repeat(arrlat./arrlat[1],1,length(arrlon),length(arrt)),(2,1,3)) const arrbeta = permutedims(repeat(reverse([0:1/(length(arrdep)-1):1;]),1,length(arrlon),length(arrlat),length(arrt)),(2,3,1,4)) const arru = permutedims(repeat([0.15],length(arrt),length(arrlon),length(arrlat),length(arrdep)),(2,3,4,1)); ```

These grids are directly fed to the grid solver, which returns an array. irr can have its own time provided as satellite products often do not have the same temporal resolution as models. Additionally, a fill value, in this case NaN, can be provided as they are often temporally sparse and need to be filtered.

This function automatically parallelised to however many threads you start Julia with

julia @time results = SugarKelp.solvegrid(t_i, nd, a_0, n_0, c_0, arr_lon, arr_lat, arr_dep, arr_t, arr_no3, arr_temp, arr_u, (arr_irr, arr_t, NaN), (nothing, nothing, nothing), arr_beta, SugarKelp.broch2013params, 2); ...

The output from this is an array with area/nitrogen reserve/carbon reserve/nitrate uptake in the first dimension, then lon,lat,dep,time in the others. We can extract the total carbon and nitrogen again:

julia total_carbon = results[1,:,:,:,:] .* K_A .* (results[3,:,:,:,:] .+ C_struct) total_nitrogen = results[1,:,:,:,:] .* K_A .* (results[2,:,:,:,:] .+ N_struct);

We could plot these for a couple of points as a comparison for above:

julia plot(layout=grid(1,3),size=(1000,300)) results_time=[0:nd;] for r=1:10 i,j,k=rand([1:length(arr_lon);]),rand([1:length(arr_lat);]),rand([1:length(arr_dep);]) plot!(results_time,results[1,i,j,k,:],sp=1,label="$(arr_lat[j])N, $(arr_lon[i])W, $(arr_dep[k])m") plot!(results_time,total_carbon[i,j,k,:],sp=2) plot!(results_time,total_nitrogen[i,j,k,:],sp=3) end plot!(ylabel="Area/dm²",sp=1,legend=:bottomright);plot!(sp=2,xlabel="Day",ylabel="Total Carbon (gC)",legend=false);plot!(sp=3,ylabel="Total Nitrogen (gN)",legend=false)

png

Or we could plot a heatmap of the surfaces:

julia hms=[ heatmap(arr_lon,arr_lat,total_carbon[:,:,1,end]',color=cgrad(:bamako, rev=true),colorbar_title="Total Carbon (gC)"), heatmap(arr_lon,arr_lat,total_nitrogen[:,:,1,end]',color=:lajolla,colorbar_title="Total Nitrogen (gN)"), heatmap(arr_lon,arr_lat,total_carbon[:,:,1,end]'./total_nitrogen[:,:,1,end]',color=cgrad(:lapaz, rev=true),colorbar_title="Carbon:Nitrogen ratio") ] plot!(hms...,layout=grid(1,3),size=(1000,200))

png

Documentation

Documentation can now be found here.

Owner

  • Name: Jago Strong-Wright
  • Login: jagoosw
  • Kind: user
  • Location: Cambridge, UK
  • Company: University of Cambridge

Ocean carbon, @OceanBioME

Citation (CITATION.cff)

# YAML 1.2
---
abstract: "Implementation of the Broch and Slagstad, 2012 model of the growth and composition of Saccharina latissima kelp."
authors: 
  -
    affiliation: "St John's College Cambridge, University of Cambridge"
    family-names: "Strong-Wright"
    given-names: Jago
cff-version: "1.1.0"
date-released: 2021-10-07
doi: "10.5281/zenodo.5554954"
license: MIT
message: "Please cite the following works when using this software."
repository-code: "https://github.com/jagoosw/SugarKelp.jl"
title: "SugarKelp.jl"
version: "v1.0"
...

GitHub Events

Total
Last Year

Committers

Last synced: over 1 year ago

All Time
  • Total Commits: 70
  • Total Committers: 1
  • Avg Commits per committer: 70.0
  • Development Distribution Score (DDS): 0.0
Past Year
  • Commits: 0
  • Committers: 0
  • Avg Commits per committer: 0.0
  • Development Distribution Score (DDS): 0.0
Top Committers
Name Email Commits
Jago j****w@p****m 70

Issues and Pull Requests

Last synced: 6 months ago

All Time
  • Total issues: 3
  • Total pull requests: 3
  • Average time to close issues: N/A
  • Average time to close pull requests: 17 minutes
  • Total issue authors: 1
  • Total pull request authors: 1
  • Average comments per issue: 0.33
  • Average comments per pull request: 0.0
  • Merged pull requests: 2
  • Bot issues: 0
  • Bot pull requests: 0
Past Year
  • Issues: 0
  • Pull requests: 0
  • Average time to close issues: N/A
  • Average time to close pull requests: N/A
  • Issue authors: 0
  • Pull request authors: 0
  • Average comments per issue: 0
  • Average comments per pull request: 0
  • Merged pull requests: 0
  • Bot issues: 0
  • Bot pull requests: 0
Top Authors
Issue Authors
  • jagoosw (3)
Pull Request Authors
  • jagoosw (3)
Top Labels
Issue Labels
Pull Request Labels

Packages

  • Total packages: 1
  • Total downloads:
    • julia 1 total
  • Total dependent packages: 0
  • Total dependent repositories: 0
  • Total versions: 2
juliahub.com: SugarKelp

Model of Saccharina latissima (sugar kelp) based on Broch and Slagstad, 2012

  • Versions: 2
  • Dependent Packages: 0
  • Dependent Repositories: 0
  • Downloads: 1 Total
Rankings
Dependent repos count: 9.9%
Average: 38.4%
Dependent packages count: 38.9%
Forks count: 40.4%
Stargazers count: 64.2%
Last synced: 6 months ago

Dependencies

.github/workflows/docs.yml actions
  • actions/checkout v2 composite
  • julia-actions/setup-julia latest composite
.github/workflows/tests.yml actions
  • actions/cache v1 composite
  • actions/checkout v2 composite
  • codecov/codecov-action v1 composite
  • julia-actions/julia-buildpkg v1 composite
  • julia-actions/julia-processcoverage v1 composite
  • julia-actions/julia-runtest v1 composite
  • julia-actions/setup-julia v1 composite