Package: paraml
paraml (Param YAML)paraml is a parameter definition language and parser - all in yaml.Table of ContentsNote:README internal links only work onGitHubMotivationGetting StartedInstallationRunning paramlParameter DefinitionRequired KeysTypesUsing ClassesMotivationparaml is a spinoff fromTITAN, an agent based model.  We have many parameters in that model, many of which are not used in a given run. paraml addresses the following pain points we had:Parameters often weren't formally defined/described anywhere - some had comments, some were hopefully named idiomatically. This caused issues onboarding new people to using the model.Parameters were statically defined/hard coded, but often we wanted them to be dynamic.Parameters needed to be filled out/defined by non-technical researchers - shouldn't need to know how to code to create a parameter file.Parameters need to have specific validation (e.g. a probability should be between 0 and 1, onlyaorbare expected values for parametery), this was typically a run time failure - sometimes silent, sometimes explosive.If a user isn't using a feature of the model, they shouldn't have to worry about/carry around its parameters.Reproducibility of the run is key - must be able to re-run the model with the same params.We needed to be able to create common settings which described a specific world the model runs in and let users use those, but also override parameters as they needed for their run of the model.How paraml addresses these:Parameter definitions require defaultsCan add descriptions of parameters inlineA small type system allows validation of params, as well as flexibility to define interfaces for paramsParameter files only need to fill in what they want different from the defaultsCan save off the fully computed params, which can then be re-used at a later dateCan layer different parameter files, allowing more complex defaults and re-use of common scenariosGetting StartedInstallationpip install paramlRunning paramlThe entrypoint for running paraml isparaml.create_params.  This takes the parameter definitions, parameter files, and some options and returns a dictionary of the validated and computed parameters.Args:def_path: A yaml file or directory of yaml files containing the parameter definitions (seeParameter Definition).*param_paths: The remaining args are interpreted as parameter files.  They will be merged in order (last merged value prevails).out_path: Optional, if passed, save the computed parameters as a yaml to this location.error_on_unused: Optional, ifTruethrow an exception if there are parameters inparam_pathsthat do not have a corresponding definition in thedef_pathdefinitions.Returns:A dictionary representing the parsed parameters.Example usage:fromparamlimportcreate_paramsdef_path="my/params/dir"# directory of the params definition filesbase_params="base/params.yaml"# file location of the first paramssetting_param="settings/my_setting"# directory of the second params filesintervention_params="intervention/params"# directory of the third params filesout_path="./params.yml"# location to save computed params toparams=create_params(def_path,base_params,setting_params,intervention_params,out_path=out_path,error_on_unused=True# if parameters are passed, but don't exist in the definition file, error)Parameter DefinitionThe parameter definition language (PDL) provides expressions for defining input types, creation of types for the target application, and simple validation of input values.  The PDL itself is YAML and can be defined either in one file or a directory of yaml files. There can be multiple root keys in the parameter definition to namespace parameters by topic, and parameter definitions can be deeply nested for further organization of the params.  Only theclasseskey at the root of the definitions has special meaning (seeUsing Classes).An example params definition:# classes is a special parameter key that allows the params defined as sub-keys
# to be used in definitions for other sections
classes:
  animals:
    type: definition
    description: Animals included in model
    fields:
      goes:
        type: any
        description: What noise does the animal make?
        default: oink
      is_mammal:
        type: boolean
        description: Is this animal a mammal
        default: false
      friends_with:
        type: keys
        description: What animals does this animal befriend
    default:
      cat:
        goes: meow
        is_mammal: true
        friends_with:
          - cat
          - dog
      dog:
        goes: woof
        is_mammal: true
        friends_with:
          - dog
          - turtle
          - cat
      turtle:
        goes: gurgle
        friends_with:
          - dog
          - turtle
  locations:
    type: array
    description: Where do the animals live?
    default:
      - barn
      - ocean
    values:
      - barn
      - ocean
      - sky
      - woods

# demographics is another root-level parameter, which facets off of the values in classes
# then has parameter definitions for each of those combinations
demographics:
  type: sub-dict
  description: "Parameters controlling population class level probabilities and behaviors"
  keys:
    - animals
    - locations
  default:
    num:
      type: int
      default: 0
      description: Number of animals of this type at this location
    prob_happy:
      type: float
      default: 1.0
      description: Probability an animal is happy
      min: 0.0
      max: 1.0
    flag: # parameter definitions can be nested in intermediate keys to group related items
      color:
        type: enum
        default: blue
        description: What's the color is the flag of this animal/location combo
        values:
          - blue
          - indigo
          - cyan
      name:
        type: any
        default: animal land
        description: What is the name of this animal/location combo's flag

# neighbors is another root-level parameter
neighbors:
  type: definition
  description: Definition of an edge (relationship) between two locations
  fields:
    location_1:
      type: enum
      default: barn
      class: locations
    location_2:
      type: enum
      default: sky
      class: locations
    distance:
      type: float
      default: 0
      min: 0
  default:
    edge_default:
      location_1: barn
      location_2: sky
      distance: 1000An example of parameters for the definition aboveclasses:
  animals:
    pig: # doesn't need a `goes` key as the default is oink and that is appropriate
      is_mammal: true
      friends_with:
        - pig
    fish: # fish don't need to specify `is_mammal` as false as that is the default
      goes: glugglug
      friends_with:
        - fish
    wolf:
      goes: ooooooooo
      is_mammal: true
      friends_with:
        - pig
  locations:
    - ocean
    - woods
    - barn

# the calculated params will fill in the default values for combinations of
# animals/colors/parameters that aren't specified below
demographics:
  pig:
    barn:
      num: 20
      flag:
        color: cyan
        name: piney porcines
  wolf:
    woods:
      num: 1
      prob_happy: 0.8
      flag:
        name: running solo
  fish:
    ocean:
      num: 1000001
      prob_happy: 0.4
      flag:
        color: indigo
        name: cool school

# we're defining a edges in a graph in this example, the names are labels for human readability only
neighbors:
  woodsy_barn:
    location_1: woods
    location_2: barn
    distance: 1
  woodsy_ocean:
    location_1: woods
    location_2: ocean
    distance: 3
  barn_ocean:
    location_1: barn
    location_2: ocean
    distance: 4Parameters are defined as key value pairs (typically nested).  There are some reserved keys that allow for definition of a parameter item, but otherwise a key in the parameter definition is interpreted as an expected key in the parameters.The reserved keys used for defining parameters are:typedefaultdescriptionminmaxvaluesfieldsSpecifically, if thedefaultkey is present in a yaml object, then that object will be interpreted as a parameter definition.  The other keys are used in that definitionFor example, in the belowtypeis used as a parameter key, which is allowed (though perhaps not encouraged for readability reasons) asdefaultis not a key at the same level oftype.  The second usage oftypeis interpreted as the definition oftype(the key) being anint.a:
  type:
    type: int
    default: 0
    description: the type of aclassesis also reserved as a root key (seeusing classesbelow)Required KeysEvery parameter item must have thetype, anddefaultkeys (descriptionhighly encouraged, but not required).SeeTypesfor more information on the types and how they interact with the other keys.Thedefaultkey should be a valid value given the rest of the definition.  Thedefaultkey can include parameter definitions within it.  This is common withsub-dictparam definitions.Thedescriptionis a free text field to provide context for the parameter item.  This can also be used to generate documentation (no automated support at this time - seeTITAN's params appas an example).TypesThetypeof a parameter definition dictates which other fields are required/used when parsing the definition.The types supported by paraml are:intfloatbooleanarrayenumanybinsub-dictdefinitionintThe value of the parameter is expected to be an integer.Required keys:NoneOptional keys:min- the minimum value (inclusive) this parameter can takemax- the maximum value (inclusive) this parameter can takeExample definition:fav_num:
  type: int
  default: 12
  description: a is your favorite 3-or-fewer-digit number
  min: -999
  max: 999Example usage:fav_num: 13floatThe value of the parameter is expected to be a floating point numberRequired keys:NoneOptional keys:min- the minimum value (inclusive) this parameter can takemax- the maximum value (inclusive) this parameter can takeExample definition:heads_prob:
  type: float
  default: 0.5
  description: the probability heads is flipped
  min: 0.0
  max: 1.0Example usage:heads_prob: 0.75booleanThe value of the parameter is expected to be a true/false valueRequired keys:NoneOptional keys:NoneExample definition:use_feature:
  type: boolean
  description: whether or not to use this feature
  default: falseExample usage:use_feature: truearrayThe value of the parameter is expected to be an array of values selected from the defined list.Required keys:values- either a list of strings that the parameter can take, or the name of a class whose values can be usedOptional keys:NoneExample definition:locations:
  type: array
  description: Where do the animals go?
  default:
    - barn
    - ocean
  values:
    - barn
    - ocean
    - sky
    - woodsExample usage:locations:
  - sky
  - oceanenumThe value of the parameter is expected to be a single value selected from the defined list.Required keys:values- either a list of strings that the parameter can take, or the name of a class whose values can be usedOptional keys:NoneExample definition:classes:
  my_classes:
    type: array
    description: which class my params has
    default:
      - a
      - b
    values:
      - a
      - b
      - c

affected_class:
  type: enum
  default: a
  description: which class is affected by this feature
  values: my_classesExample usage:my_classes:
  - b
  - c

affected_class: canyThe value of the parameter can take on any value and will not be validated.Required keys:NoneOptional keys:NoneExample definition:name:
  type: any
  description: what is your name?
  default: your name hereExample usage:name: paramlbinBinned (integer) keys with set value fields.Required keys:fields- parameter definitions for each required field in the binned items.  Because the sub-fields of a bin are required, no default can be provided.Optional keys:NoneExample definition:bins:
  type: bin
  description: "Binned probabilities of frequencies"
  fields:
    prob:
      type: float
      min: 0.0
      max: 1.0
    min:
      type: int
      min: 0
    max:
      type: int
      min: 0
  default:
    1:
      prob: 0.585
      min: 1
      max: 6
    2:
      prob: 0.701
      min: 7
      max: 12
    3:
      prob: 0.822
      min: 13
      max: 24Example usage:bins:
  1:
    prob: 0.5
    min: 0
    max: 10
  2:
    prob: 0.9
    min: 11
    max: 20sub-dictBuild a set of params for each key combination listed.  Requires use ofclassesroot key.  The default should contain parameter definition items.  Can facet on up to two classes.Required keys:keys- which params under theclassesroot key should be sub-dicted off ofOptional keys:NoneExample definition:classes:
  my_classes:
    type: array
    description: which class my params has
    default:
      - a
      - b
    values:
      - a
      - b
      - c

demographics:
  type: sub-dict
  description: parameters defining characteristics of each class
  keys:
    - my_classes
  default:
    num:
      type: int
      default: 0
      description: number of agents in the classExample usage:demographics:
  a:
    num: 10
  b:
    num: 20definitionDefine an item with the given interface.Required keys:fields- the fields defining the interface for each defined item.  Each field is a param definition item.Optional keys:NoneExample definition:animals:
  type: definition
  description: Animals included in model
  fields:
    goes:
      type: any
      description: What noise does the animal make?
      default: oink
    is_mammal:
      type: boolean
      description: Is this animal a mammal
      default: false
    friends_with:
      type: keys
      desciption: What animals does this animal befriend
  default:
    cat:
      goes: meow
      is_mammal: true
      friends_with:
        - cat
        - dog
    dog:
      goes: woof
      is_mammal: true
      friends_with:
        - dog
        - catExample usage:animals:
  sheep:
    goes: bah
    is_mammal: true
  pig:
    is_mammal: true
  fish:
    goes: glugglugUsing ClassesTheclasseskey as a root key of the parameter definitions takes on special meaning.  The parameters chosen in this section can be used to determine acceptable values in other sections of the params (viaenumandarraytypes), or to determine what params need to be created (viasub-dicttype).Example class as value:classes:
  animals:
    type: definition
    description: Animals included in model
    fields:
      goes:
        type: any
        description: What noise does the animal make?
        default: oink
      is_mammal:
        type: boolean
        description: Is this animal a mammal
        default: false
    default:
      cat:
        goes: meow
        is_mammal: true
      sheep:
        goes: baaaah
        is_mammal: true
  month:
    type: definition
    fields:
      mean_temp:
        type: float
        description: average temperature in °F
    default:
      april:
        mean_temp: 45.6

shearing:
  month:
    type: enum
    description: what season to shear animals
    class: month # This enum will only allow a value from the "month" class
    default: april
  to_shear:
    type: array
    description: which animals need to be sheared
    class: animal
    default:
      - sheepExample usage of class as value:classes:
  animals:
    sheep:
      goes: baaaah
      is_mammal: true
    cat:
      goes: meow
      is_mammal: true
    llama:
      goes: spits
      is_mammal: true
## we will only be using "april," which is the default month, so no definition needed!
shearing:
  month: april
  to_shear:
    - sheep
    - llama