Skip to content
Snippets Groups Projects
Select Git revision
  • 3edf3236b507688d2c0d2c7c429d08b8c1636092
  • master default protected
  • development
  • fix-missing-weatherdata
  • fix-eichsfeld-weather
  • marco-development
  • marco/dev-aquacrop
  • precompile-statements
  • precompile-tools
  • tmp-faster-loading
  • skylark
  • testsuite
  • code-review
  • v0.7.0
  • v0.6.1
  • v0.6.0
  • v0.5.5
  • v0.5.4
  • v0.5.3
  • v0.5.2
  • v0.2
  • v0.3.0
  • v0.4.1
  • v0.5
24 results

ecologicaldata.jl

  • Daniel Vedder's avatar
    xo30xoqa authored
    In the process of validation here...
    3edf3236
    History
    Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    ecologicaldata.jl 6.29 KiB
    ### Persefone.jl - a model of agricultural landscapes and ecosystems in Europe.
    ###
    ### This file includes the functions for collecting ecological output data, which
    ### are then passed on to the `core/output.jl`.
    ###
    
    """
        initecologicaldata()
    
    Create output files for each data group collected by the nature model.
    """
    function initecologicaldata(model::SimulationModel)
        newdataoutput!(model, "populations", ["Date", "Species", "Abundance"],
                       @param(nature.popoutfreq), savepopulationdata, populationtrends)
        newdataoutput!(model, "individuals", ["Date","ID","X","Y","Species","Sex","Age"],
                       @param(nature.indoutfreq), saveindividualdata, visualisemap)
        newdataoutput!(model, "mortality", ["Date", "Species", "Cause"], @param(nature.popoutfreq))
        initskylarkdata(model)
        initmarbledwhitedata(model)
    end
    
    """
        savepopulationdata(model)
    
    Return a data table (to be printed to `populations.csv`), giving the current
    date and population size for each animal species. May be called never, daily,
    monthly, yearly, or at the end of a simulation, depending on the parameter
    `nature.popoutfreq`.
    """
    function savepopulationdata(model::SimulationModel)
        pops = Dict{String,Int}(s=>0 for s = @param(nature.targetspecies))
        for a in model.animals
            isnothing(a) && continue
            pops[speciesof(a)] += 1
        end
        for m in model.migrants
            pops[speciesof(m.first)] += 1
        end
        data = []
        for p in keys(pops)
            push!(data, [model.date, p, pops[p]])
        end
        data
    end
    
    """
        saveindividualdata(model)
    
    Return a data table (to be printed to `individuals.csv`), listing all
    properties of all animal individuals in the model. May be called never, daily,
    monthly, yearly, or at the end of a simulation, depending on the parameter
    `nature.indoutfreq`. WARNING: Produces very big files!
    """
    function saveindividualdata(model::SimulationModel)
        data = []
        for a in model.animals
            isnothing(a) && continue
            push!(data, [model.date,a.id,a.pos[1],a.pos[2],speciesof(a),a.sex,a.age])
        end
        for m in model.migrants
            push!(data, [model.date, m[1].id, -1, -1, speciesof(m[1]), m[1].sex, m[1].age])
        end
        data
    end
    
    
    ## SKYLARK DATA OUTPUT
    
    function initskylarkdata(model::SimulationModel)
        newdataoutput!(model, "skylark_abundance",
                       ["Date", "TotalAbundance", "Mating", "Breeding",
                        "Nonbreeding", "Juvenile", "Migrants"],
                       @param(nature.popoutfreq), skylarkabundance, skylarkpopulation)
        # newdataoutput!(model, "skylark_territories", ["Date", "ID", "X", "Y"],
        #                skylarkterritories, "monthly") #TODO add plotting function
        newdataoutput!(model, "skylark_breeding",
                       ["Date", "Female", "Male", "X", "Y", "Landcover", "Crop", "Territory"],
                       @param(nature.popoutfreq), nothing, skylarkstats)
    end
    
    """
        skylarkabundance(model)
    
    Save skylark abundance data, including total abundance and demographic data
    (abundances of breeding/non-breeding/juvenile/migrated individuals).
    """
    function skylarkabundance(model::SimulationModel)
        pops = Dict{String,Int}("TotalAbundance" => 0, "Mating" => 0, "Breeding" => 0,
                                "Nonbreeding" => 0, "Juvenile" => 0, "Migrants" => 0)
        for a in model.animals
            (isnothing(a) || speciesof(a) != "Skylark") && continue
            pops["TotalAbundance"] += 1
            if a.phase == nonbreeding
                pops["Nonbreeding"] += 1
            elseif a.phase in (territorysearch, matesearch) || (a.phase == occupation && a.mate == -1)
                pops["Mating"] += 1
            else
                pops["Breeding"] += 1
            end
            if a.sex == female && a.clutch > 0
                pops["TotalAbundance"] += a.clutch
                pops["Juvenile"] += a.clutch
            end
        end
        for m in model.migrants
            if speciesof(m.first) == "Skylark"
                pops["TotalAbundance"] += 1
                pops["Migrants"] += 1
            end
        end
        return [[model.date, pops["TotalAbundance"], pops["Mating"], pops["Breeding"],
                 pops["Nonbreeding"], pops["Juvenile"], pops["Migrants"]]]
    end
    
    """
        skylarkterritories(model)
    
    Return a list of all coordinates occupied by a skylark territory, and the ID of the individual
    holding the territory. WARNING: produces very big files.
    """
    function skylarkterritories(model::SimulationModel)
        #TODO is there a way of outputting this that takes less space? For example as a landscape-size
        # matrix where each position is the ID of the individual occupying this pixel?
        data = []
        for a in model.animals
            (isnothing(a) || a.sex != male || speciesof(a) != "Skylark" || a.phase != occupation) && continue
            for pos in a.territory
                push!(data, [model.date, a.id, pos[1], pos[2]])
            end
        end
        data
    end
    
    ## MARBLED WHITE DATA OUTPUT
    
    function initmarbledwhitedata(model::SimulationModel)
        newdataoutput!(model, "marbledwhite_abundance",
                       ["Date", "TotalAbundance", "Eggs", "Larvae", "Pupae", "Adults"],
                       @param(nature.popoutfreq), marbledwhiteabundance, marbledwhitepopulation)
        newdataoutput!(model, "marbledwhite_lifestats",
                       ["ID", "Year", "Fecundity", "Population density",
                        "Displacement", "Unmanaged grassland", "Extensive grassland",
                        "Fallow", "Intensive grassland", "Arable", "Other"],
                       @param(nature.popoutfreq), nothing, marbledwhitelifestats)
    end
    
    """
        marbledwhiteabundance(model)
    
    Save marbledwhite abundance data, including total abundance and demographic data
    (abundances of breeding/non-breeding/juvenile/migrated individuals).
    """
    function marbledwhiteabundance(model::SimulationModel)
        pops = Dict{String,Int}("TotalAbundance" => 0, "Eggs" => 0, "Larvae" => 0,
                                "Pupae" => 0, "Adults" => 0)
        for a in model.animals
            (isnothing(a) || speciesof(a) != "MarbledWhite") && continue
            pops["TotalAbundance"] += 1
            if a.phase == egg
                pops["Eggs"] += 1
            elseif a.phase == larva
                pops["Larvae"] += 1
            elseif a.phase == pupa
                pops["Pupae"] += 1
            else
                pops["Adults"] += 1
            end
        end
        return [[model.date, pops["TotalAbundance"], pops["Eggs"], pops["Larvae"],
                 pops["Pupae"], pops["Adults"]]]
    end