PkgUtility.jl

A collection of utility functions used for Emerald Land model. The module used to be a sub-module of the under-developing Emerald Land model (not registered), and reusing the functions is more or less inconvenient as one would need to import the entire mega land model to use a very small tool. Therefore, I tease apart the functions that require minimum dependencies and move them to a new package. There are a number of submodules (and utility functions) for different purposes, and they are listed here in an alphabetical order.

ArtifactTools

Read and write toml and yaml files to use with GriddingMachine (and other general purposes)

PkgUtility.ArtifactTools.save_library!Function
save_library!(filename::String, data::Union{Dict, OrderedDict})
save_library!(data::Union{Dict, OrderedDict}, filename::String)

Save a Dict as a TOML or YAML file, given

  • filename File name of the library file
  • data Data to be saved
source

DistributedTools

Add and remove processors dynamically based on the maximum number of CPU cores and the requested number of threads. For example, if the requested number of threads exceeds the maximum CPU count, the maximum CPU wound be used; if the requested number of threads is fewer than existing workers, the extra ones would be removed.

PrettyDisplay

Display the information within an @info block (or @warn or @error), showing the time of the operation as well

PkgUtility.PrettyDisplay.pretty_display!Function

pretty_display!(msg::String, func_type::String)

Display the message based on the message level, given

  • msg message to display
  • func_type message level for displaying

Examples

    pretty_display!("This is an entire timed info message", "tinfo");
    pretty_display!("This is the first line of a set of timed info messages", "tinfo_pre");
    pretty_display!("This is the middle line of a set of timed info messages", "tinfo_mid");
    pretty_display!("This is the last line of a set of timed info messages", "tinfo_end");

pretty_display!(pvec::Vector{<:Pair})

Display the pairs in a pretty way, given

  • pvec Vector of pairs to display

Examples

    pvec = ["A" => "b", "d" => "A", "rr" => ["ra" => "rB", "rD" => "ra"]];
    pretty_display!(pvec);
source

RecursiveTools

Test and floating number type or if containing nan within a variable (number, vector, structure, etc) in a recursive manner

PkgUtility.RecursiveTools.FT_testFunction
FT_test(para::Array, FT)
FT_test(para::Number, FT)
FT_test(para::Union{Function, Module, String, Symbol}, FT)
FT_test(para::Any, FT)

Return true or false to determine if the FT is consistent, given

  • para Parameter to run FT control
  • FT Float type

If the testing variable is an array, the function will test if element type is float number:

  • If true, the function tests if the element type is the same as given FT
  • If false, the function tests each element recursively

The variable to test maybe a struct, but FT_test does not know the struct type name a priori. Thus, we try to read out the fields of the variable:

  • If succeeds, the function test the fields recursively
  • If fails, then do nothing
source
PkgUtility.RecursiveTools.NaN_testFunction
NaN_test(para::Array)
NaN_test(para::Number)
NaN_test(para::Union{Function, Module, String, Symbol})
NaN_test(para::Any)

Test if the variable is not NaN, given

  • para Parameter to test
source

Compare and synchronize a structure in a recursive manner

PkgUtility.RecursiveTools.compare_struct!Function
compare_struct!(struct1::ST, struct2::ST; approximation::Bool = true, first_element_array::Bool = true, show_diff_msg::Bool = true) where ST
compare_struct!(struct1::ST, struct2::ST, target::Symbol; first_element_array::Bool = true, show_diff_msg::Bool = true) where ST

Comparing two structs struct1 and struct2 recursively, given

  • struct1 The first struct to compare
  • struct2 The second struct to compare
  • approximation Whether to compare the numbers approximately
  • first_element_array Whether to compare the first element of an array only
  • show_diff_msg Whether to show the difference message
  • target The field to compare
source

TimeParser

Identify the month index with a known doy-of-year, or the range of doy-of-year of a known month

PkgUtility.TimeParser.month_doysFunction
month_doys(year::Int, month::Int)
month_doys(leapyear::Bool, month::Int)

Return the day of year, given

  • year Year
  • month Month
  • leapyear Whether the year is a leap year
source

Parse number and string to different formats

PkgUtility.TimeParser.parse_timestampFunction
parse_timestamp(timestamp::Union{Int,String}, in_format::String, out_format::String)
parse_timestamp(year::Int, doy::Int, out_format::String)
parse_timestamp(year::Int, doy::AbstractFloat, out_format::String)

Convert timestamp, given

  • timestamp Time stamp
  • in_format Format of timestamp, default is YYYYMMDD
  • out_format Output format, default is DOY
  • year Year (in this case, the function will convert year and day to timestamp first)
  • doy Day of year (typically 1-365, 1-366 for leap years)

The input format (string or integer) supports YYYYMMDD, YYYYMMDDhh, YYYYMMDDhhmm, YYYYMMDDhhmmss, and YYYYMMDDhhmmss.mmm, where the labels are

  • YYYY Year number
  • MM Month number
  • DD Day number
  • hh Hour number
  • mm Minute number
  • ss Second number
  • mmm Millisecond number

The supported outputs are

  • DATE A Dates.Date type variable
  • DATETIME A Dates.DateTime type variable
  • DOY A day of year integer
  • FDOY A day of year float

Examples

    time = parse_timestamp(20200130, "YYYYMMDD", "FDOY");
    time = parse_timestamp("20200130", "YYYYMMDD", "FDOY");
    time = parse_timestamp(2020, 100, "DOY");
    time = parse_timestamp(2020, 100.23435436, "DATETIME");
source