diff --git a/pipelines/SDM/BRT_julia_sdm.json b/pipelines/SDM/BRT_julia_sdm.json new file mode 100644 index 00000000..2237c026 --- /dev/null +++ b/pipelines/SDM/BRT_julia_sdm.json @@ -0,0 +1,624 @@ +{ + "nodes": [ + { + "id": "0", + "type": "io", + "position": { + "x": 892.926148028543, + "y": 359.3674249062675 + }, + "data": { + "descriptionFile": "data>loadFromStac.yml" + } + }, + { + "id": "1", + "type": "io", + "position": { + "x": 906.9895403393837, + "y": 76.25361041097028 + }, + "data": { + "descriptionFile": "data>pyLoadObservations>pyLoadObservations.yml" + } + }, + { + "id": "2", + "type": "constant", + "position": { + "x": 368.86119022111507, + "y": 142.04267028927177 + }, + "dragHandle": ".dragHandle", + "data": { + "type": "text", + "value": "https://io.biodiversite-quebec.ca/stac/" + } + }, + { + "id": "3", + "type": "constant", + "position": { + "x": 313.1962041962512, + "y": 257.3975828418341 + }, + "dragHandle": ".dragHandle", + "data": { + "type": "float[]", + "value": [ + "-86.748047", + "33.724340", + "-52.207031", + "63.273182" + ] + } + }, + { + "id": "4", + "type": "constant", + "position": { + "x": 254.62676356703406, + "y": 370.36734296317206 + }, + "dragHandle": ".dragHandle", + "data": { + "type": "text", + "value": "EPSG:4326" + } + }, + { + "id": "13", + "type": "io", + "position": { + "x": 1458.5472678652434, + "y": 515.8899053001562 + }, + "data": { + "descriptionFile": "SDM>julia_sdms>pcaLayers.yml" + } + }, + { + "id": "15", + "type": "output", + "position": { + "x": 2033.5593979778441, + "y": 585.8910696961975 + }, + "data": { + "label": "Output" + } + }, + { + "id": "16", + "type": "constant", + "position": { + "x": 231.39999389648438, + "y": 418.8999938964844 + }, + "dragHandle": ".dragHandle", + "data": { + "type": "float", + "value": 0.008 + } + }, + { + "id": "18", + "type": "io", + "position": { + "x": 888.3999938964844, + "y": 668.8999938964844 + }, + "data": { + "descriptionFile": "data>loadFromStac.yml" + } + }, + { + "id": "19", + "type": "constant", + "position": { + "x": 389.3999938964844, + "y": 675.8999938964844 + }, + "dragHandle": ".dragHandle", + "data": { + "type": "text[]", + "value": [ + "esacci-lc|esacci-lc-2020" + ] + } + }, + { + "id": "20", + "type": "constant", + "position": { + "x": 371.3999938964844, + "y": 609.8999938964844 + }, + "dragHandle": ".dragHandle", + "data": { + "type": "text", + "value": "https://io.biodiversite-quebec.ca/stac/" + } + }, + { + "id": "21", + "type": "io", + "position": { + "x": 1928.3999938964844, + "y": 217.89999389648438 + }, + "data": { + "descriptionFile": "filtering>cleanCoordinates.yml" + } + }, + { + "id": "22", + "type": "io", + "position": { + "x": 2195.3999938964844, + "y": 369.8999938964844 + }, + "data": { + "descriptionFile": "SDM>julia_sdms>generateBackground.yml" + } + }, + { + "id": "24", + "type": "io", + "position": { + "x": 2735.3999938964844, + "y": 402.8999938964844 + }, + "data": { + "descriptionFile": "SDM>julia_sdms>fitBRT.yml" + } + }, + { + "id": "25", + "type": "output", + "position": { + "x": 3179.3999938964844, + "y": 397.8999938964844 + }, + "data": { + "label": "Output" + } + }, + { + "id": "26", + "type": "output", + "position": { + "x": 3185.3999938964844, + "y": 438.8999938964844 + }, + "data": { + "label": "Output" + } + }, + { + "id": "27", + "type": "output", + "position": { + "x": 3195.3999938964844, + "y": 485.8999938964844 + }, + "data": { + "label": "Output" + } + }, + { + "id": "28", + "type": "constant", + "position": { + "x": 1604.3844157896422, + "y": -83.59950590983343 + }, + "dragHandle": ".dragHandle", + "data": { + "type": "text[]", + "value": [ + "equal", + "zeros", + "duplicates", + "same_pixel", + "seas", + "urban", + "gbif" + ] + } + }, + { + "id": "29", + "type": "constant", + "position": { + "x": 1585.6031762103437, + "y": 62.60748756512288 + }, + "dragHandle": ".dragHandle", + "data": { + "type": "float", + "value": 0.8 + } + }, + { + "id": "30", + "type": "constant", + "position": { + "x": 589.2832121887816, + "y": 83.84679123817233 + }, + "dragHandle": ".dragHandle", + "data": { + "type": "text[]", + "value": [ + "Acer saccharum" + ] + } + }, + { + "id": "31", + "type": "constant", + "position": { + "x": 588.3999938964844, + "y": 32.899993896484375 + }, + "dragHandle": ".dragHandle", + "data": { + "type": "options", + "value": "gbif_api", + "options": [ + "gbif_pc", + "gbif_api" + ] + } + }, + { + "id": "32", + "type": "constant", + "position": { + "x": 89.39999389648438, + "y": 478.8999938964844 + }, + "dragHandle": ".dragHandle", + "data": { + "type": "text[]", + "value": [ + "chelsa-clim|bio1", + "chelsa-clim|bio2", + "chelsa-clim|bio3", + "chelsa-clim|bio4", + "chelsa-clim|bio5", + "chelsa-clim|bio6", + "chelsa-clim|bio7", + "chelsa-clim|bio8", + "chelsa-clim|bio9", + "chelsa-clim|bio10", + "chelsa-clim|bio11", + "chelsa-clim|bio12", + "chelsa-clim|bio13", + "chelsa-clim|bio14", + "chelsa-clim|bio15", + "chelsa-clim|bio16", + "chelsa-clim|bio17", + "chelsa-clim|bio18", + "chelsa-clim|bio19" + ] + } + }, + { + "id": "33", + "type": "output", + "position": { + "x": 2379.6499938964844, + "y": 122 + }, + "data": { + "label": "Output" + } + }, + { + "id": "34", + "type": "output", + "position": { + "x": 1371.6499938964844, + "y": 725 + }, + "data": { + "label": "Output" + } + } + ], + "edges": [ + { + "source": "2", + "sourceHandle": null, + "target": "0", + "targetHandle": "stac_url", + "id": "reactflow__edge-2-0stac_url" + }, + { + "source": "3", + "sourceHandle": null, + "target": "0", + "targetHandle": "bbox", + "id": "reactflow__edge-3-0bbox" + }, + { + "source": "3", + "sourceHandle": null, + "target": "1", + "targetHandle": "bbox", + "id": "reactflow__edge-3-1bbox" + }, + { + "source": "4", + "sourceHandle": null, + "target": "0", + "targetHandle": "proj", + "id": "reactflow__edge-4-0proj" + }, + { + "source": "4", + "sourceHandle": null, + "target": "1", + "targetHandle": "proj", + "id": "reactflow__edge-4-1proj" + }, + { + "source": "0", + "sourceHandle": "rasters", + "target": "13", + "targetHandle": "layers", + "id": "reactflow__edge-0rasters-13layers" + }, + { + "source": "13", + "sourceHandle": "predictors", + "target": "15", + "targetHandle": null, + "id": "reactflow__edge-13predictors-15" + }, + { + "source": "16", + "sourceHandle": null, + "target": "0", + "targetHandle": "spatial_res", + "id": "reactflow__edge-16-0spatial_res" + }, + { + "source": "19", + "sourceHandle": null, + "target": "18", + "targetHandle": "collections_items", + "id": "reactflow__edge-19-18collections_items" + }, + { + "source": "20", + "sourceHandle": null, + "target": "18", + "targetHandle": "stac_url", + "id": "reactflow__edge-20-18stac_url" + }, + { + "source": "4", + "sourceHandle": null, + "target": "18", + "targetHandle": "proj", + "id": "reactflow__edge-4-18proj" + }, + { + "source": "3", + "sourceHandle": null, + "target": "18", + "targetHandle": "bbox", + "id": "reactflow__edge-3-18bbox" + }, + { + "source": "16", + "sourceHandle": null, + "target": "18", + "targetHandle": "spatial_res", + "id": "reactflow__edge-16-18spatial_res" + }, + { + "source": "18", + "sourceHandle": "rasters", + "target": "13", + "targetHandle": "mask", + "id": "reactflow__edge-18rasters-13mask" + }, + { + "source": "1", + "sourceHandle": "observations_file", + "target": "21", + "targetHandle": "presence", + "id": "reactflow__edge-1observations_file-21presence" + }, + { + "source": "13", + "sourceHandle": "predictors", + "target": "21", + "targetHandle": "predictors", + "id": "reactflow__edge-13predictors-21predictors" + }, + { + "source": "13", + "sourceHandle": "predictors", + "target": "22", + "targetHandle": "predictors", + "id": "reactflow__edge-13predictors-22predictors" + }, + { + "source": "21", + "sourceHandle": "clean_presence", + "target": "22", + "targetHandle": "presence", + "id": "reactflow__edge-21clean_presence-22presence" + }, + { + "source": "22", + "sourceHandle": "background", + "target": "24", + "targetHandle": "background", + "id": "reactflow__edge-22background-24background" + }, + { + "source": "21", + "sourceHandle": "clean_presence", + "target": "24", + "targetHandle": "occurrence", + "id": "reactflow__edge-21clean_presence-24occurrence" + }, + { + "source": "13", + "sourceHandle": "predictors", + "target": "24", + "targetHandle": "predictors", + "id": "reactflow__edge-13predictors-24predictors" + }, + { + "source": "24", + "sourceHandle": "sdm", + "target": "25", + "targetHandle": null, + "id": "reactflow__edge-24sdm-25" + }, + { + "source": "24", + "sourceHandle": "sdm_uncertainty", + "target": "26", + "targetHandle": null, + "id": "reactflow__edge-24sdm_uncertainty-26" + }, + { + "source": "24", + "sourceHandle": "fit_stats", + "target": "27", + "targetHandle": null, + "id": "reactflow__edge-24fit_stats-27" + }, + { + "source": "28", + "sourceHandle": null, + "target": "21", + "targetHandle": "tests", + "id": "reactflow__edge-28-21tests" + }, + { + "source": "29", + "sourceHandle": null, + "target": "21", + "targetHandle": "env_threshold", + "id": "reactflow__edge-29-21env_threshold" + }, + { + "source": "30", + "sourceHandle": null, + "target": "1", + "targetHandle": "taxa", + "id": "reactflow__edge-30-1taxa" + }, + { + "source": "31", + "sourceHandle": null, + "target": "1", + "targetHandle": "data_source", + "id": "reactflow__edge-31-1data_source" + }, + { + "source": "32", + "sourceHandle": null, + "target": "0", + "targetHandle": "collections_items", + "id": "reactflow__edge-32-0collections_items" + }, + { + "source": "21", + "sourceHandle": "clean_presence", + "target": "33", + "targetHandle": null, + "id": "reactflow__edge-21clean_presence-33" + }, + { + "source": "18", + "sourceHandle": "rasters", + "target": "34", + "targetHandle": null, + "id": "reactflow__edge-18rasters-34" + } + ], + "inputs": { + "data>loadFromStac.yml@0|weight_matrix_with_ids": { + "description": "Weight matrix used for Bon optimization. Vector of strings, collection name followed by '|' followed by item id, followed by weights. Cannot be used if collection_items is set.", + "label": "Weight matrix with ids", + "type": "text", + "example": "layer, current, change\nGBSTAC|chelsa-clim|bio1, 0.7, 0.6\nGBSTAC|chelsa-clim|bio2, 0.3, 0.4\n" + }, + "data>loadFromStac.yml@0|mask": { + "description": "Shapefile, used to mask the output rasters", + "label": "mask", + "type": "application/dbf" + }, + "data>pyLoadObservations>pyLoadObservations.yml@1|min_year": { + "description": "Min year observations wanted", + "label": "minimum year", + "type": "int", + "example": 2010 + }, + "data>pyLoadObservations>pyLoadObservations.yml@1|max_year": { + "description": "Max year observations wanted", + "label": "maximum year", + "type": "int", + "example": 2020 + }, + "data>loadFromStac.yml@18|weight_matrix_with_ids": { + "description": "Weight matrix used for Bon optimization. Vector of strings, collection name followed by '|' followed by item id, followed by weights. Cannot be used if collection_items is set.", + "label": "Weight matrix with ids", + "type": "text", + "example": "layer, current, change\nGBSTAC|chelsa-clim|bio1, 0.7, 0.6\nGBSTAC|chelsa-clim|bio2, 0.3, 0.4\n" + }, + "data>loadFromStac.yml@18|mask": { + "description": "Shapefile, used to mask the output rasters", + "label": "mask", + "type": "application/dbf" + }, + "SDM>julia_sdms>generateBackground.yml@22|buffer_distance": { + "description": "the minimum distance between any presence and any pseudoabsence in meters", + "label": "buffer_distance", + "type": "int", + "example": 50000 + } + }, + "outputs": { + "SDM>julia_sdms>pcaLayers.yml@13|predictors": { + "description": "raster", + "label": "predictors", + "type": "image/tiff;application=geotiff[]" + }, + "SDM>julia_sdms>fitBRT.yml@24|sdm": { + "description": "map of predicted occurrence probability", + "label": "sdm", + "type": "image/tiff;application=geotiff" + }, + "SDM>julia_sdms>fitBRT.yml@24|sdm_uncertainty": { + "description": "map of relative uncertainty", + "label": "sdm uncertainty", + "type": "image/tiff;application=geotiff" + }, + "SDM>julia_sdms>fitBRT.yml@24|fit_stats": { + "description": "JSON of model fit stats and threshold", + "label": "fit_stats", + "type": "text/json" + }, + "filtering>cleanCoordinates.yml@21|clean_presence": { + "description": "Dataframe, table with clean presence points.", + "label": "clean presences", + "type": "text/tab-separated-values" + }, + "data>loadFromStac.yml@18|rasters": { + "description": "array of output raster paths", + "label": "rasters", + "type": "image/tiff;application=geotiff[]" + } + } + } \ No newline at end of file diff --git a/pipelines/SDM/BRT_julia_viewer.json b/pipelines/SDM/BRT_julia_viewer.json new file mode 100644 index 00000000..d69ace81 --- /dev/null +++ b/pipelines/SDM/BRT_julia_viewer.json @@ -0,0 +1,720 @@ +{ + "nodes": [ + { + "id": "0", + "type": "io", + "position": { + "x": 892.926148028543, + "y": 359.3674249062675 + }, + "data": { + "descriptionFile": "data>loadFromStac.yml" + } + }, + { + "id": "1", + "type": "io", + "position": { + "x": 906.9895403393837, + "y": 76.25361041097028 + }, + "data": { + "descriptionFile": "data>pyLoadObservations>pyLoadObservations.yml" + } + }, + { + "id": "2", + "type": "constant", + "position": { + "x": 368.86119022111507, + "y": 142.04267028927177 + }, + "dragHandle": ".dragHandle", + "data": { + "type": "text", + "value": "https://io.biodiversite-quebec.ca/stac/" + } + }, + { + "id": "3", + "type": "userInput", + "position": { + "x": 313.1962041962512, + "y": 257.3975828418341 + }, + "dragHandle": ".dragHandle", + "data": { + "type": "float[]", + "value": ["-86.748047", "33.724340", "-52.207031", "63.273182"] + } + }, + { + "id": "4", + "type": "constant", + "position": { + "x": 254.62676356703406, + "y": 370.36734296317206 + }, + "dragHandle": ".dragHandle", + "data": { + "type": "text", + "value": "EPSG:4326" + } + }, + { + "id": "13", + "type": "io", + "position": { + "x": 1458.5472678652434, + "y": 515.8899053001562 + }, + "data": { + "descriptionFile": "SDM>julia_sdms>pcaLayers.yml" + } + }, + { + "id": "15", + "type": "output", + "position": { + "x": 2033.5593979778441, + "y": 585.8910696961975 + }, + "data": { + "label": "Output" + } + }, + { + "id": "16", + "type": "constant", + "position": { + "x": 231.39999389648438, + "y": 418.8999938964844 + }, + "dragHandle": ".dragHandle", + "data": { + "type": "float", + "value": 0.008 + } + }, + { + "id": "18", + "type": "io", + "position": { + "x": 888.3999938964844, + "y": 668.8999938964844 + }, + "data": { + "descriptionFile": "data>loadFromStac.yml" + } + }, + { + "id": "19", + "type": "constant", + "position": { + "x": 389.3999938964844, + "y": 675.8999938964844 + }, + "dragHandle": ".dragHandle", + "data": { + "type": "text[]", + "value": ["esacci-lc|esacci-lc-2020"] + } + }, + { + "id": "20", + "type": "constant", + "position": { + "x": 371.3999938964844, + "y": 609.8999938964844 + }, + "dragHandle": ".dragHandle", + "data": { + "type": "text", + "value": "https://io.biodiversite-quebec.ca/stac/" + } + }, + { + "id": "21", + "type": "io", + "position": { + "x": 1928.3999938964844, + "y": 217.89999389648438 + }, + "data": { + "descriptionFile": "filtering>cleanCoordinates.yml" + } + }, + { + "id": "22", + "type": "io", + "position": { + "x": 2195.3999938964844, + "y": 369.8999938964844 + }, + "data": { + "descriptionFile": "SDM>julia_sdms>generateBackground.yml" + } + }, + { + "id": "24", + "type": "io", + "position": { + "x": 2735.3999938964844, + "y": 402.8999938964844 + }, + "data": { + "descriptionFile": "SDM>julia_sdms>fitBRT.yml" + } + }, + { + "id": "25", + "type": "output", + "position": { + "x": 3179.3999938964844, + "y": 397.8999938964844 + }, + "data": { + "label": "Output" + } + }, + { + "id": "26", + "type": "output", + "position": { + "x": 3185.3999938964844, + "y": 438.8999938964844 + }, + "data": { + "label": "Output" + } + }, + { + "id": "27", + "type": "output", + "position": { + "x": 3195.3999938964844, + "y": 485.8999938964844 + }, + "data": { + "label": "Output" + } + }, + { + "id": "28", + "type": "constant", + "position": { + "x": 1604.3844157896422, + "y": -83.59950590983343 + }, + "dragHandle": ".dragHandle", + "data": { + "type": "text[]", + "value": [ + "equal", + "zeros", + "duplicates", + "same_pixel", + "seas", + "urban", + "gbif" + ] + } + }, + { + "id": "29", + "type": "constant", + "position": { + "x": 1585.6031762103437, + "y": 62.60748756512288 + }, + "dragHandle": ".dragHandle", + "data": { + "type": "float", + "value": 0.8 + } + }, + { + "id": "30", + "type": "userInput", + "position": { + "x": 589.2832121887816, + "y": 83.84679123817233 + }, + "dragHandle": ".dragHandle", + "data": { + "type": "text[]", + "value": ["Acer saccharum"] + } + }, + { + "id": "31", + "type": "constant", + "position": { + "x": 588.3999938964844, + "y": 32.899993896484375 + }, + "dragHandle": ".dragHandle", + "data": { + "type": "options", + "value": "gbif_api", + "options": ["gbif_pc", "gbif_api"] + } + }, + { + "id": "32", + "type": "userInput", + "position": { + "x": 89.39999389648438, + "y": 478.8999938964844 + }, + "dragHandle": ".dragHandle", + "data": { + "type": "text[]", + "value": [ + "chelsa-clim|bio1", + "chelsa-clim|bio2", + "chelsa-clim|bio3", + "chelsa-clim|bio4", + "chelsa-clim|bio5", + "chelsa-clim|bio6", + "chelsa-clim|bio7", + "chelsa-clim|bio8", + "chelsa-clim|bio9", + "chelsa-clim|bio10", + "chelsa-clim|bio11", + "chelsa-clim|bio12", + "chelsa-clim|bio13", + "chelsa-clim|bio14", + "chelsa-clim|bio15", + "chelsa-clim|bio16", + "chelsa-clim|bio17", + "chelsa-clim|bio18", + "chelsa-clim|bio19" + ] + } + }, + { + "id": "33", + "type": "output", + "position": { + "x": 2379.6499938964844, + "y": 122 + }, + "data": { + "label": "Output" + } + }, + { + "id": "34", + "type": "output", + "position": { + "x": 1444.1260034160307, + "y": 729.9415461036054 + }, + "data": { + "label": "Output" + } + }, + { + "id": "35", + "type": "constant", + "position": { + "x": 536.9888109468682, + "y": 704.4499002160003 + }, + "dragHandle": ".dragHandle", + "data": { + "type": "text", + "value": "layer, current, change\nGBSTAC|chelsa-clim|bio1, 0.7, 0.6\nGBSTAC|chelsa-clim|bio2, 0.3, 0.4\n" + } + }, + { + "id": "36", + "type": "constant", + "position": { + "x": 542.5677856122697, + "y": 396.2115499525608 + }, + "dragHandle": ".dragHandle", + "data": { + "type": "text", + "value": "layer, current, change\nGBSTAC|chelsa-clim|bio1, 0.7, 0.6\nGBSTAC|chelsa-clim|bio2, 0.3, 0.4\n" + } + }, + { + "id": "37", + "type": "output", + "position": { + "x": 1328.5098721252748, + "y": 895.8373517186589 + }, + "data": { + "label": "Output" + } + }, + { + "id": "38", + "type": "output", + "position": { + "x": 1504.2802457138919, + "y": 294.44054742414664 + }, + "data": { + "label": "Output" + } + } + ], + "edges": [ + { + "source": "2", + "sourceHandle": null, + "target": "0", + "targetHandle": "stac_url", + "id": "reactflow__edge-2-0stac_url" + }, + { + "source": "3", + "sourceHandle": null, + "target": "0", + "targetHandle": "bbox", + "id": "reactflow__edge-3-0bbox" + }, + { + "source": "3", + "sourceHandle": null, + "target": "1", + "targetHandle": "bbox", + "id": "reactflow__edge-3-1bbox" + }, + { + "source": "4", + "sourceHandle": null, + "target": "0", + "targetHandle": "proj", + "id": "reactflow__edge-4-0proj" + }, + { + "source": "4", + "sourceHandle": null, + "target": "1", + "targetHandle": "proj", + "id": "reactflow__edge-4-1proj" + }, + { + "source": "0", + "sourceHandle": "rasters", + "target": "13", + "targetHandle": "layers", + "id": "reactflow__edge-0rasters-13layers" + }, + { + "source": "13", + "sourceHandle": "predictors", + "target": "15", + "targetHandle": null, + "id": "reactflow__edge-13predictors-15" + }, + { + "source": "16", + "sourceHandle": null, + "target": "0", + "targetHandle": "spatial_res", + "id": "reactflow__edge-16-0spatial_res" + }, + { + "source": "19", + "sourceHandle": null, + "target": "18", + "targetHandle": "collections_items", + "id": "reactflow__edge-19-18collections_items" + }, + { + "source": "20", + "sourceHandle": null, + "target": "18", + "targetHandle": "stac_url", + "id": "reactflow__edge-20-18stac_url" + }, + { + "source": "4", + "sourceHandle": null, + "target": "18", + "targetHandle": "proj", + "id": "reactflow__edge-4-18proj" + }, + { + "source": "3", + "sourceHandle": null, + "target": "18", + "targetHandle": "bbox", + "id": "reactflow__edge-3-18bbox" + }, + { + "source": "16", + "sourceHandle": null, + "target": "18", + "targetHandle": "spatial_res", + "id": "reactflow__edge-16-18spatial_res" + }, + { + "source": "18", + "sourceHandle": "rasters", + "target": "13", + "targetHandle": "mask", + "id": "reactflow__edge-18rasters-13mask" + }, + { + "source": "1", + "sourceHandle": "observations_file", + "target": "21", + "targetHandle": "presence", + "id": "reactflow__edge-1observations_file-21presence" + }, + { + "source": "13", + "sourceHandle": "predictors", + "target": "21", + "targetHandle": "predictors", + "id": "reactflow__edge-13predictors-21predictors" + }, + { + "source": "13", + "sourceHandle": "predictors", + "target": "22", + "targetHandle": "predictors", + "id": "reactflow__edge-13predictors-22predictors" + }, + { + "source": "21", + "sourceHandle": "clean_presence", + "target": "22", + "targetHandle": "presence", + "id": "reactflow__edge-21clean_presence-22presence" + }, + { + "source": "22", + "sourceHandle": "background", + "target": "24", + "targetHandle": "background", + "id": "reactflow__edge-22background-24background" + }, + { + "source": "21", + "sourceHandle": "clean_presence", + "target": "24", + "targetHandle": "occurrence", + "id": "reactflow__edge-21clean_presence-24occurrence" + }, + { + "source": "13", + "sourceHandle": "predictors", + "target": "24", + "targetHandle": "predictors", + "id": "reactflow__edge-13predictors-24predictors" + }, + { + "source": "24", + "sourceHandle": "sdm", + "target": "25", + "targetHandle": null, + "id": "reactflow__edge-24sdm-25" + }, + { + "source": "24", + "sourceHandle": "sdm_uncertainty", + "target": "26", + "targetHandle": null, + "id": "reactflow__edge-24sdm_uncertainty-26" + }, + { + "source": "24", + "sourceHandle": "fit_stats", + "target": "27", + "targetHandle": null, + "id": "reactflow__edge-24fit_stats-27" + }, + { + "source": "28", + "sourceHandle": null, + "target": "21", + "targetHandle": "tests", + "id": "reactflow__edge-28-21tests" + }, + { + "source": "29", + "sourceHandle": null, + "target": "21", + "targetHandle": "env_threshold", + "id": "reactflow__edge-29-21env_threshold" + }, + { + "source": "30", + "sourceHandle": null, + "target": "1", + "targetHandle": "taxa", + "id": "reactflow__edge-30-1taxa" + }, + { + "source": "31", + "sourceHandle": null, + "target": "1", + "targetHandle": "data_source", + "id": "reactflow__edge-31-1data_source" + }, + { + "source": "32", + "sourceHandle": null, + "target": "0", + "targetHandle": "collections_items", + "id": "reactflow__edge-32-0collections_items" + }, + { + "source": "21", + "sourceHandle": "clean_presence", + "target": "33", + "targetHandle": null, + "id": "reactflow__edge-21clean_presence-33" + }, + { + "source": "18", + "sourceHandle": "rasters", + "target": "34", + "targetHandle": null, + "id": "reactflow__edge-18rasters-34" + }, + { + "source": "35", + "sourceHandle": null, + "target": "18", + "targetHandle": "weight_matrix_with_ids", + "id": "reactflow__edge-35-18weight_matrix_with_ids" + }, + { + "source": "36", + "sourceHandle": null, + "target": "0", + "targetHandle": "weight_matrix_with_ids", + "id": "reactflow__edge-36-0weight_matrix_with_ids" + }, + { + "source": "30", + "sourceHandle": null, + "target": "37", + "targetHandle": null, + "id": "reactflow__edge-30-37" + }, + { + "source": "1", + "sourceHandle": "total_records", + "target": "38", + "targetHandle": null, + "id": "reactflow__edge-1total_records-38" + } + ], + "inputs": { + "data>loadFromStac.yml@0|mask": { + "description": "Shapefile, used to mask the output rasters", + "label": "mask", + "type": "application/dbf" + }, + "data>pyLoadObservations>pyLoadObservations.yml@1|min_year": { + "description": "Min year observations wanted", + "label": "minimum year", + "type": "int", + "example": 2010 + }, + "data>pyLoadObservations>pyLoadObservations.yml@1|max_year": { + "description": "Max year observations wanted", + "label": "maximum year", + "type": "int", + "example": 2020 + }, + "pipeline@3": { + "label": "bbox", + "description": "Vector of float, bbox coordinates of the extent in the order xmin, ymin, xmax, ymax", + "type": "float[]", + "example": [-2316297, -1971146, 1015207, 1511916] + }, + "data>loadFromStac.yml@18|mask": { + "description": "Shapefile, used to mask the output rasters", + "label": "mask", + "type": "application/dbf" + }, + "SDM>julia_sdms>generateBackground.yml@22|buffer_distance": { + "description": "the minimum distance between any presence and any pseudoabsence in meters", + "label": "buffer_distance", + "type": "int", + "example": 50000 + }, + "pipeline@30": { + "label": "Taxa list", + "description": "Array of taxa values", + "type": "text[]", + "example": ["Acer saccharum", "Bubo scandiacus"] + }, + "pipeline@32": { + "label": "collections_items", + "description": "Vector of strings, collection name followed by '|' followed by item id", + "type": "text[]", + "example": ["chelsa-clim|bio1", "chelsa-clim|bio2"] + } + }, + "outputs": { + "SDM>julia_sdms>pcaLayers.yml@13|predictors": { + "description": "Environmental layers used as predictors in model fitting", + "label": "Environmental predictors", + "type": "image/tiff;application=geotiff[]" + }, + "SDM>julia_sdms>fitBRT.yml@24|sdm": { + "description": "Map of predicted occurrence probability for selected species using Booster Regression Trees", + "label": "Predictions", + "type": "image/tiff;application=geotiff" + }, + "SDM>julia_sdms>fitBRT.yml@24|sdm_uncertainty": { + "description": "Map of relative uncertainty of predictions", + "label": "Spatial uncertainty", + "type": "image/tiff;application=geotiff" + }, + "SDM>julia_sdms>fitBRT.yml@24|fit_stats": { + "description": "Model fit statistics and threshold", + "label": "Fit statistics", + "type": "text/json" + }, + "filtering>cleanCoordinates.yml@21|clean_presence": { + "description": "Dataframe, table with clean presence points from GBIF for selected species", + "label": "Presences", + "type": "text/tab-separated-values" + }, + "data>loadFromStac.yml@18|rasters": { + "description": "Land cover layer used for masking non terrestrial pixels", + "label": "Land cover map", + "type": "image/tiff;application=geotiff[]" + }, + "pipeline@30": { + "label": "Species name", + "description": "Species for which the distribution model is generated" + }, + "data>pyLoadObservations>pyLoadObservations.yml@1|total_records": { + "description": "Total number of GBIF occurrences in csv file", + "label": "Total number of occurrences", + "type": "int", + "example": 1234 + } + }, + "metadata": { + "name": "Species Distribution Modelling with Boosted Regression Trees", + "description": "This pipeline performs species distribution modeling for a given species and region from GBIF data with Boosted Regression Trees in the Julia programming language.", + "author": [ + { + "name": "Michael Catchen", + "identifier": "https://orcid.org/0000-0002-6506-6487" + }, + { + "name": "Thimothé Poisoit", + "identifier": "https://orcid.org/0000-0002-0735-5184" + } + ], + "license": "MIT", + "external_link": "https://github.com/GEO-BON/biab-2.0/tree/mdc/julia_brt" + } +} diff --git a/scripts/SDM/julia_sdms/fitBRT.jl b/scripts/SDM/julia_sdms/fitBRT.jl new file mode 100644 index 00000000..13786172 --- /dev/null +++ b/scripts/SDM/julia_sdms/fitBRT.jl @@ -0,0 +1,171 @@ +using JSON +using CSV +using DataFrames +using EvoTrees +using StatsBase +using SpeciesDistributionToolkit + +include("./shared.jl") + +function get_features_and_labels(presences, absences, climate_layers) + presences = mask(presences, climate_layers[begin]) + absences = mask(absences, climate_layers[begin]) + coord_presence = keys(replace(presences, false => nothing)) + coord_absence = keys(replace(absences, false => nothing)) + coord = vcat(coord_presence, coord_absence) + + X = hcat([layer[coord] for layer in climate_layers]...) + y = vcat(fill(1.0, length(coord_presence)), fill(0.0, length(coord_absence))) + return X, y, coord +end + +function layers_to_matrix!(climate_layers, mat, land_idx) + for (i, idx) in enumerate(land_idx) + for l in eachindex(climate_layers) + mat[l, i] = climate_layers[l].grid[idx] + end + end +end + +function compute_fit_stats_and_cutoff(distribution, coords, y) + cutoff = LinRange(extrema(distribution)..., 500) + coords = convert(Vector{typeof(coords[begin])}, coords) + idx = findall(!isnothing, coords) + I = [SimpleSDMLayers._point_to_cartesian(distribution, c) for c in coords][idx] + + obs = y .> 0 + + tp = zeros(Float64, length(cutoff)) + fp = zeros(Float64, length(cutoff)) + tn = zeros(Float64, length(cutoff)) + fn = zeros(Float64, length(cutoff)) + + for (i, c) in enumerate(cutoff) + prd = [distribution.grid[i] >= c for i in I] + tp[i] = sum(prd .& obs) + tn[i] = sum(.!(prd) .& (.!obs)) + fp[i] = sum(prd .& (.!obs)) + fn[i] = sum(.!(prd) .& obs) + end + + tpr = tp ./ (tp .+ fn) + fpr = fp ./ (fp .+ tn) + J = (tp ./ (tp .+ fn)) + (tn ./ (tn .+ fp)) .- 1.0 + + roc_dx = [reverse(fpr)[i] - reverse(fpr)[i - 1] for i in 2:length(fpr)] + roc_dy = [reverse(tpr)[i] + reverse(tpr)[i - 1] for i in 2:length(tpr)] + ROCAUC = sum(roc_dx .* (roc_dy ./ 2.0)) + + thr_index = last(findmax(J)) + τ = cutoff[thr_index] + + return Dict(:rocauc => ROCAUC, :threshold => τ, :J => J[last(findmax(J))]) +end + + +function test_train_split(X, y, proportion=0.7) + train_size = floor(Int, proportion * length(y)) + Itrain = StatsBase.sample(1:length(y), train_size; replace=false) + Itest = setdiff(1:length(y), Itrain) + Xtrain, Xtest = X[Itrain, :], X[Itest, :] + Ytrain, Ytest = y[Itrain], y[Itest] + return Xtrain, Ytrain, Xtest, Ytest +end + +function predict_single_sdm(model, layers) + + land_idx = findall(!isnothing, layers[begin].grid) + + mat = zeros(Float32, length(layers), length(land_idx)) + + # Handle nothings here + layers_to_matrix!(layers, mat, land_idx) + + pred = EvoTrees.predict(model, mat') + + distribution = SimpleSDMPredictor( + zeros(Float32, size(layers[begin])); + SpeciesDistributionToolkit.boundingbox(layers[begin])... + ) + distribution.grid[land_idx] = pred[:, 1] + + uncertainty = SimpleSDMPredictor(zeros(Float32, size(layers[begin])); SpeciesDistributionToolkit.boundingbox(layers[begin])...) + uncertainty.grid[land_idx] = pred[:, 2] + + rescale(distribution, (0, 1)), rescale(uncertainty, (0, 1)) +end + +function main() + runtime_dir = ARGS[1] + inputs = read_inputs_dict(runtime_dir) + predictor_paths = inputs["predictors"] + occurrence_path = inputs["occurrence"] + pseudoabs_path = inputs["background"] + + predictors = SimpleSDMPredictor.(predictor_paths) + + occurrence = CSV.read(occurrence_path, DataFrame, delim="\t") + occurrence_layer = create_occurrence_layer(similar(predictors[1]), occurrence) + + pseudoabsences = CSV.read(pseudoabs_path, DataFrame, delim="\t") + pseudoabs_layer = create_occurrence_layer(similar(predictors[1]), pseudoabsences) + #pseudoabs_layer = create_occurrence_layer(similar(predictors[1]), pseudoabs_df) + + X, y, p_and_a_coords = get_features_and_labels(occurrence_layer, pseudoabs_layer, predictors) + + Xtrain, Ytrain, Xtest, Ytest = test_train_split(X, y) + + brt = EvoTreeGaussian(; + loss = :gaussian, + metric = :gaussian, + nrounds = 100, + nbins = 100, + λ = 0.0, + γ = 0.0, + η = 0.1, + max_depth = 7, + min_weight = 1.0, + rowsample = 0.5, + colsample = 1.0, + ) + + + model = fit_evotree( + brt; + x_train=Xtrain, + y_train=Ytrain, + x_eval=Xtest, + y_eval=Ytest + ) + + prediction, uncertainty = predict_single_sdm(model, predictors) + + fit_dict = compute_fit_stats_and_cutoff(prediction, p_and_a_coords, y) + τ = fit_dict[:threshold] + + # Set below threshold to 0 + prediction.grid[findall(x -> x < τ, prediction.grid)] .= 0 + + sdm_path = joinpath(runtime_dir, "sdm.tif") + SpeciesDistributionToolkit.save(sdm_path, prediction) + uncertainty_path = joinpath(runtime_dir, "uncertainty.tif") + SpeciesDistributionToolkit.save(uncertainty_path, uncertainty) + + + fit_stats_path = joinpath(runtime_dir, "fit_stats.json") + open(fit_stats_path, "w") do f + write(f, JSON.json(fit_dict)) + end + + output_json_path = joinpath(runtime_dir, "output.json") + open(output_json_path, "w") do f + write(f, JSON.json(Dict( + :sdm => sdm_path, + :uncertainty => uncertainty_path, + :fit_stats => fit_stats_path + ))) + end + +end + +main() \ No newline at end of file diff --git a/scripts/SDM/julia_sdms/fitBRT.yml b/scripts/SDM/julia_sdms/fitBRT.yml new file mode 100644 index 00000000..52076a2c --- /dev/null +++ b/scripts/SDM/julia_sdms/fitBRT.yml @@ -0,0 +1,35 @@ +script: fitBRT.jl +name: BRT +description: "This script creates an SDM and uncertainty map based on using Boosted Regression Trees (BRTs) using the package SpeciesDistributionToolkit.jl and EvoTrees.jl" +author: + - name: Michael D. Catchen + identifier: https://orcid.org/0000-0002-6506-6487 +inputs: + occurrence: + label: occurrence coordinate dataframe + description: Dataframe, presence data. + type: text/tab-separated-values + example: "/output/data/getObservations/9f7d1cc148464cd0517e01c67af0ab5b/obs_data.tsv" + background: + label: background + description: Dataframe, background data. + type: text/tab-separated-values + example: "/output/SDM/julia_sdms/generateBackground/f69fe7abd1711e193bb4f8aef51c74cc/background.csv" + predictors: + label: predictors + description: layer names (predictors) as a list + type: image/tiff;application=geotiff[] + example: ["/output/data/loadFromStac/ea82148a2926d97acf85cea61a110194/bio1_242b2b01561981-01-01.tif","/output/data/loadFromStac/ea82148a2926d97acf85cea61a110194/bio2_243a4e7f541981-01-01.tif"] +outputs: + sdm: + label: sdm + description: map of predicted occurrence probability + type: image/tiff;application=geotiff + sdm_uncertainty: + label: sdm uncertainty + description: map of relative uncertainty + type: image/tiff;application=geotiff + fit_stats: + label: fit_stats + description: JSON of model fit stats and threshold + type: text/json diff --git a/scripts/SDM/julia_sdms/generateBackground.jl b/scripts/SDM/julia_sdms/generateBackground.jl new file mode 100644 index 00000000..8ac3c683 --- /dev/null +++ b/scripts/SDM/julia_sdms/generateBackground.jl @@ -0,0 +1,35 @@ +using JSON +using CSV +using DataFrames +using SpeciesDistributionToolkit + +include("./shared.jl") + +function main() + runtime_dir = ARGS[1] + inputs = read_inputs_dict(runtime_dir) + + predictor_paths = inputs["predictors"] + occurrence_path = inputs["presence"] + buffer_distance = inputs["buffer_distance"] / 1000 # div by 1000 to convert to km + + predictors = SimpleSDMPredictor.(predictor_paths) + + occurrence = CSV.read(occurrence_path, DataFrame, delim="\t") + occurrence_layer = create_occurrence_layer(similar(predictors[1]), occurrence) + + buffer = pseudoabsencemask(WithinRadius, occurrence_layer; distance = buffer_distance) + absences = SpeciesDistributionToolkit.sample(.!buffer, floor(Int, 0.5sum(occurrence_layer))) + + abs_coords = findall(absences) + pseudoabs_df = DataFrame(lon=[c[1] for c in abs_coords], lat=[c[2] for c in abs_coords]) + CSV.write("$runtime_dir/background.tsv", pseudoabs_df, delim="\t") + + output_json_path = joinpath(runtime_dir, "output.json") + open(output_json_path, "w") do f + write(f, JSON.json(Dict(:background=>"$runtime_dir/background.tsv"))) + end +end + +main() + diff --git a/scripts/SDM/julia_sdms/generateBackground.yml b/scripts/SDM/julia_sdms/generateBackground.yml new file mode 100644 index 00000000..d73d41ad --- /dev/null +++ b/scripts/SDM/julia_sdms/generateBackground.yml @@ -0,0 +1,28 @@ +script: generateBackground.jl +name: Generate Background +description: "This script creates a set of pseudoabsences/background points." +author: + - name: Michael D. Catchen + identifier: https://orcid.org/0000-0002-6506-6487 +inputs: + presence: + label: presence + description: Dataframe, presence data. + type: text/tab-separated-values + example: "/output/data/getObservations/9f7d1cc148464cd0517e01c67af0ab5b/obs_data.tsv" + predictors: + label: predictors + description: layer names (predictors) as a list + type: image/tiff;application=geotiff[] + example: ["/output/data/loadFromStac/ea82148a2926d97acf85cea61a110194/bio1_242b2b01561981-01-01.tif","/output/data/loadFromStac/ea82148a2926d97acf85cea61a110194/bio2_243a4e7f541981-01-01.tif"] + buffer_distance: + label: buffer_distance + description: the minimum distance between any presence and any pseudoabsence in meters + type: int + example: 50000 +outputs: + background: + label: background + description: TSV file containing with the coordinates background points. + type: text/tab-separated-values + diff --git a/scripts/SDM/julia_sdms/loadCHELSA.jl b/scripts/SDM/julia_sdms/loadCHELSA.jl new file mode 100644 index 00000000..5ce3de05 --- /dev/null +++ b/scripts/SDM/julia_sdms/loadCHELSA.jl @@ -0,0 +1,92 @@ +using SpeciesDistributionToolkit +using JSON +using CSV +using MultivariateStats +using StatsBase +using DataFrames + +include("./shared.jl") + +const PROVIDER = RasterData(CHELSA2, BioClim) + +function convert_layers_to_features_matrix(layers) + I = findall(!isnothing, layers[1].grid) + data_matrix = zeros(Float32, length(layers), length(I)) + for (i,l) in enumerate(layers) + x = Float32.(vec(l.grid[I])) + z = StatsBase.fit(ZScoreTransform, x) + data_matrix[i,:] .= StatsBase.transform(z, x) + end + data_matrix +end + +function fill_layer!(empty_layer, vec) + m = reshape(vec, size(empty_layer)) + for j in eachindex(empty_layer.grid) + empty_layer.grid[j] = m[j] + end +end + +function pca_data_matrix(data_matrix) + pca = MultivariateStats.fit(PCA, data_matrix) + MultivariateStats.transform(pca, data_matrix) +end + +function make_pca_layers(layers) + pca_mat = pca_data_matrix(convert_layers_to_features_matrix(layers)) + pca_layers = [convert(Float32, similar(layers[begin])) for l in 1:size(pca_mat, 1)] + for (i,pca_layer) in enumerate(pca_layers) + fill_layer!(pca_layer, pca_mat[i,:]) + end + pca_layers +end + +function write_outputs(runtime_dir, layers) + predictor_paths = [] + + for (i,l) in enumerate(layers) + outpath = joinpath(runtime_dir, "predictor$i.tif") + push!(predictor_paths, outpath) + SpeciesDistributionToolkit.save(outpath, l) + end + + output_json_path = joinpath(runtime_dir, "output.json") + open(output_json_path, "w") do f + write(f, JSON.json(Dict(:predictors=>predictor_paths))) + end +end + +function main() + runtime_dir = ARGS[1] + inputs = read_inputs_dict(runtime_dir) + + bbox = inputs["bbox"] + pca_input = inputs["pca"] + layer_nums = inputs["layer_numbers"] + layer_names = ["BIO$i" for i in layer_nums] + + bbox = (left=bbox[1], bottom=bbox[2], right=bbox[3], top=bbox[4]) + @info bbox + + layers = [] + for l in layer_names + success = false + ct = 1 + while !success + try + a = convert(Float32, SimpleSDMPredictor(PROVIDER; layer=l, bbox...)) + success = true + push!(layers, a) + catch + @info "Errored on $l on attempt $ct. Almost certainly a network error on CHELSA's side. Trying again..." + ct += 1 + end + end + end + + layers = pca_input ? make_pca_layers(layers) : layers + + write_outputs(runtime_dir, layers) +end + +main() \ No newline at end of file diff --git a/scripts/SDM/julia_sdms/loadCHELSA.yml b/scripts/SDM/julia_sdms/loadCHELSA.yml new file mode 100644 index 00000000..9fc58603 --- /dev/null +++ b/scripts/SDM/julia_sdms/loadCHELSA.yml @@ -0,0 +1,27 @@ +script: loadCHELSA.jl +name: Load CHELSA +description: "This script creates an SDM and uncertainty map based on using Boosted Regression Trees (BRTs) using the package SpeciesDistributionToolkit.jl and EvoTrees.jl" +author: + - name: Michael D. Catchen + identifier: https://orcid.org/0000-0002-6506-6487 +inputs: + bbox: + label: bbox + description: Vector of float, bbox coordinates of the extent in the order xmin, ymin, xmax, ymax in coordinates + type: float[] + example: [-86.75, 33.72,-52.21,63.27] + pca: + label: pca layers + description: Boolean, whether to PCA predictor layers or not + type: boolean + example: True + layer_numbers: + label: CHELSA layer numbers + description: the CHELSA layers to use + type: int[] + example: [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19] +outputs: + predictors: + label: predictors + description: raster, predictors + type: image/tiff;application=geotiff[] diff --git a/scripts/SDM/julia_sdms/pcaLayers.jl b/scripts/SDM/julia_sdms/pcaLayers.jl new file mode 100644 index 00000000..7ebea5ab --- /dev/null +++ b/scripts/SDM/julia_sdms/pcaLayers.jl @@ -0,0 +1,80 @@ +using SpeciesDistributionToolkit +using JSON +using CSV +using MultivariateStats +using StatsBase +using DataFrames + +include("./shared.jl") + +function convert_layers_to_features_matrix(layers) + I = findall(!isnothing, layers[1].grid) + data_matrix = zeros(Float32, length(layers), length(I)) + for (i,l) in enumerate(layers) + x = Float32.(vec(l.grid[I])) + z = StatsBase.fit(ZScoreTransform, x) + data_matrix[i,:] .= StatsBase.transform(z, x) + end + data_matrix +end + +function fill_layer!(empty_layer, vec, land_idx) + for (i, idx) in enumerate(land_idx) + empty_layer.grid[idx] = vec[i] + end +end + +function pca_data_matrix(data_matrix) + pca = MultivariateStats.fit(PCA, data_matrix) + MultivariateStats.transform(pca, data_matrix) +end + +function make_pca_layers(layers, land_idx) + pca_mat = pca_data_matrix(convert_layers_to_features_matrix(layers)) + pca_layers = [convert(Float32, similar(layers[begin])) for l in 1:size(pca_mat, 1)] + + for (i,pca_layer) in enumerate(pca_layers) + fill_layer!(pca_layer, pca_mat[i,:], land_idx) + end + pca_layers +end + +function write_outputs(runtime_dir, layers) + predictor_paths = [] + + for (i,l) in enumerate(layers) + outpath = joinpath(runtime_dir, "predictor$i.tif") + push!(predictor_paths, outpath) + SpeciesDistributionToolkit.save(outpath, l) + end + + output_json_path = joinpath(runtime_dir, "output.json") + open(output_json_path, "w") do f + write(f, JSON.json(Dict(:predictors=>predictor_paths))) + end +end + +function main() + runtime_dir = ARGS[1] + inputs = read_inputs_dict(runtime_dir) + + layer_paths = inputs["layers"] + landcover_path = inputs["mask"] + + lc = SimpleSDMPredictor(joinpath(runtime_dir, landcover_path)) + + OPEN_WATER_LABEL = 210 + water_idx = findall(isequal(OPEN_WATER_LABEL), lc.grid) + land_idx = findall(!isequal(OPEN_WATER_LABEL), lc.grid) + + + layers = [SimpleSDMPredictor(joinpath(runtime_dir, layer_path)) for layer_path in layer_paths] + + for l in layers + l.grid[water_idx] .= nothing + end + + write_outputs(runtime_dir, make_pca_layers(layers, land_idx)) +end + +main() \ No newline at end of file diff --git a/scripts/SDM/julia_sdms/pcaLayers.yml b/scripts/SDM/julia_sdms/pcaLayers.yml new file mode 100644 index 00000000..5f02c9d8 --- /dev/null +++ b/scripts/SDM/julia_sdms/pcaLayers.yml @@ -0,0 +1,22 @@ +script: pcaLayers.jl +name: PCA Layers +description: "PCAs the layers" +author: + - name: Michael D. Catchen + identifier: https://orcid.org/0000-0002-6506-6487 +inputs: + layers: + label: Paths to layers + description: paths to the layers to use + type: image/tiff;application=geotiff[] + example: ["/output/data/loadLandCover/9cbf6206cd62b38e0ccc6392559f488e/y2010_class210.tif", "/output/data/loadLandCover/9cbf6206cd62b38e0ccc6392559f488e/y2010_class220.tif"] + mask: + label: Mask + description: raster mask + type: image/tiff;application=geotiff[] + example: "/output/data/loadLandCover/9cbf6206cd62b38e0ccc6392559f488e/y2010_class210.tif" +outputs: + predictors: + label: predictors + description: raster + type: image/tiff;application=geotiff[] diff --git a/scripts/SDM/julia_sdms/shared.jl b/scripts/SDM/julia_sdms/shared.jl new file mode 100644 index 00000000..a4c88419 --- /dev/null +++ b/scripts/SDM/julia_sdms/shared.jl @@ -0,0 +1,15 @@ +function read_inputs_dict(runtime_dir) + filepath = joinpath(runtime_dir, "input.json") + output_dir = joinpath(runtime_dir, "data/") + isdir(output_dir) || mkdir(output_dir) + return JSON.parsefile(filepath) +end + +function create_occurrence_layer(layer, occurrence) + layer.grid .= 0 + for r in eachrow(occurrence) + long, lat = r["lon"], r["lat"] + layer[long,lat] = 1 + end + convert(Bool, layer) +end \ No newline at end of file diff --git a/scripts/data/loadLandCover.yml b/scripts/data/loadLandCover.yml index 34752be5..5470b6a1 100644 --- a/scripts/data/loadLandCover.yml +++ b/scripts/data/loadLandCover.yml @@ -32,8 +32,8 @@ inputs: spatial_res: label: spatial resolution of the input description: spatial resolution of the input in meters (must be multiple of output spatialr resolution) - type: int - example: 250 + type: float + example: 250.0 prop_res: label: spatial resolution for the output in meters description: Integer, if proportion is TRUE, resolution to calculate the proportion from