<br><br><br> .center[ #### Slides: https://veroandreo.github.io/grass_opengeohub2021/presentation.html <br><br> #### Repo: [
](https://github.com/veroandreo/grass_opengeohub2021) ] --- class: grass-slide, hide_logo, center ## Analyzing space-time satellite data for disease ecology applications with GRASS GIS and R #### Verónica Andreo .message-box-white[ <br> <img src="assets/img/banner_conicet_conae_letrasnegras.png" width="65%"> OpenGeoHub Summer School - September, 2021] --- layout: false ## About me .pull-left-wide[ - PhD in Biology and MSc in Remote Sensing and GIS - Researcher and lecturer at [Gulich Institute](https://ig.conae.unc.edu.ar/) from the [Argentinean Space Agency - CONAE](https://www.argentina.gob.ar/ciencia/conae), working on applications of RS & GIS for disease ecology - [GRASS GIS](https://grass.osgeo.org/) dev team and PSC Chair - [OSGeo](https://www.osgeo.org/) Charter member - [FOSS4G](https://2021.foss4g.org/) enthusiast and advocate] .pull-right-narrow[ .bio-img[![Vero profile pic](assets/img/vero_round_small.png)] https://veroandreo.gitlab.io/ ] --- class: grass-slide ## How is this session organized? .large[ - GRASS GIS basic intro - Temporal GRASS GIS basic intro - Demo session ] --- ## What GRASS? .pull-left-wide[ - **GRASS GIS** (Geographic Resources Analysis Support System), a FOSS suite used for geospatial data management and analysis, image processing, graphics and maps, spatial modeling, and visualization. - Originally developed by the U.S. Army Construction Engineering Research Laboratories for land management and environmental planning (1982-1995). - More history: https://grass.osgeo.org/about/history/] .pull-right-narrow[ ![GRASS 38 bday](assets/img/grass_38_bday.png)] --- class: grass-slide center A bit of (geek) GRASS GIS history... <iframe width="560" height="315" scrolling="no" src="//av.tib.eu/player/12963" frameborder="0" allowfullscreen></iframe> <br> .message-box-white[ In case you didn't notice, the video is narrated by William Shatner 🤓 🚀 ] --- class: grass-slide ## GRASS GIS general stuff - Free and open source, you can use, modify, improve, share - Strong user community, commercial support - Large amount of tools: 500+ [core modules](#modules), 300+ [addons](#addons) - GUI and CLI interfaces - Python API and libraries - new `grass.jupyter` library can be tried [online](https://mybinder.org/v2/gh/OSGeo/grass/c173461?urlpath=lab%2Ftree%2Fdoc%2Fnotebooks%2Fgrass_jupyter.ipynb) - Connection with R, QGIS, WPS, etc. - Different data types supported: [raster](https://grass.osgeo.org/grass-stable/manuals/rasterintro.html) (including [satellite imagery](https://grass.osgeo.org/grass-stable/manuals/imageryintro.html)), [3D raster or voxel](https://grass.osgeo.org/grass-stable/manuals/raster3dintro.html), [vector](https://grass.osgeo.org/grass-stable/manuals/vectorintro.html) and [space-time datasets](https://grass.osgeo.org/grass-stable/manuals/temporalintro.html) --- name: modules ###
More than [500 core modules](https://grass.osgeo.org/grass-stable/manuals/full_index.html)
| Prefix | Function class | Type of command | Example |--------------------------------------------------------------------- |:---------------- |:----------------------------------- |:------------------------------------------------------------------------------------------------------------------- | [g.\*](https://grass.osgeo.org/grass-stable/manuals/full_index.html#g) | general | general data management | [g.rename](https://grass.osgeo.org/grass-stable/manuals/g.rename.html): renames map | [d.\*](https://grass.osgeo.org/grass-stable/manuals/full_index.html#d) | display | graphical output | [d.rast](https://grass.osgeo.org/grass-stable/manuals/d.rast.html): display raster map | [r.\*](https://grass.osgeo.org/grass-stable/manuals/full_index.html#r) | raster | raster processing | [r.mapcalc](https://grass.osgeo.org/grass-stable/manuals/r.mapcalc.html): map algebra | [v.\*](https://grass.osgeo.org/grass-stable/manuals/full_index.html#r) | vector | vector processing | [v.clean](https://grass.osgeo.org/grass-stable/manuals/v.clean.html): topological cleaning | [i.\*](https://grass.osgeo.org/grass-stable/manuals/full_index.html#i) | imagery | imagery processing | [i.pca](https://grass.osgeo.org/grass-stable/manuals/i.pca.html): Principal Component Analysis | [r3.\*](https://grass.osgeo.org/grass-stable/manuals/full_index.html#r3) | voxel | 3D raster processing | [r3.stats](https://grass.osgeo.org/grass-stable/manuals/r3.stats.html): voxel statistics | [db.\*](https://grass.osgeo.org/grass-stable/manuals/full_index.html#db) | database | database management | [db.select](https://grass.osgeo.org/grass-stable/manuals/db.select.html): select value(s) from table | [ps.\*](https://grass.osgeo.org/grass-stable/manuals/full_index.html#ps) | postscript | PostScript map creation | [ps.map](https://grass.osgeo.org/grass-stable/manuals/ps.map.html): PostScript map creation | [t.\*](https://grass.osgeo.org/grass-stable/manuals/full_index.html#t) | temporal | space-time datasets | [t.rast.aggregate](https://grass.osgeo.org/grass-stable/manuals/t.rast.aggregate.html): raster time series aggregation --- class: grass-slide name: addons ##
More than [300 add-ons](https://grass.osgeo.org/grass-stable/manuals/addons/)
Plugins or **Add-ons** can be installed from a centralized [OSGeo repository](https://grass.osgeo.org/grass-stable/manuals/addons/) or from github (or similar repositories) using [g.extension](https://grass.osgeo.org/grass-stable/manuals/g.extension.html) command. ```bash # install extension from GRASS GIS Add-on repository g.extension extension=r.hants # install extension from github repository g.extension extension=r3.slice \ url=https://github.com/petrasovaa/r3.slice ``` --- ### Graphical User Interface (GUI) <center><img src="assets/img/GUI_description.png" width="870px"></center> --- ###
Command line <center><img src="assets/img/grass_command_line.png" width="65%"></center> --- ### GRASS +
through rgrass7 package We can use [R within a GRASS GIS session](https://grasswiki.osgeo.org/wiki/R_statistics/rgrass7#R_within_GRASS) or use [GRASS GIS within an R session](https://grasswiki.osgeo.org/wiki/R_statistics/rgrass7#GRASS_within_R) <center><img src="assets/img/RwithinGRASS_and_Rstudio_from_grass.png" width="75%"></center> --- class: grass-slide center # Temporal support in GRASS GIS: .black[TGRASS] --- ## The TGRASS framework .left[GRASS GIS was the first FOSS GIS that incorporated capabilities to *manage, analyze, process and visualize spatio-temporal data*, as well as the temporal relationships among time series.] - TGRASS is fully **based on metadata** and does not duplicate any dataset - **Snapshot** approach, i.e., adds time stamps to maps - A collection of time stamped maps (snapshots) of the same variable are called **space-time datasets** or STDS - Maps in a STDS can have different spatial and temporal extents --- class: grass-slide ## Space-time datasets - Space time raster datasets (**STRDS**) - Space time 3D raster datasets (**STR3DS**) - Space time vector datasets (**STVDS**) <br> > 📢 Upcoming GRASS 8 will support image collections by adding a band reference --- class: grass-slide .pull-right-narrow[ <img src="assets/img/temporal_modules.png" width="110%" align="center"> ] ## Temporal modules .pull-left-wide[ - **t.\***: General modules to handle STDS of all types - **t.rast.\***: Modules that deal with STRDS - **t.rast3d.\***: Modules that deal with STR3DS - **t.vect.\***: Modules that deal with STVDS ] --- layout: true ### Other TGRASS notions --- .pull-left[ - Time can be defined as **intervals** (start and end time) or **instances** (only start time) - Time can be **absolute** (e.g., 2017-04-06 22:39:49) or **relative** (e.g., 4 years, 90 days) - **Granularity** is the greatest common divisor of the temporal extents (and possible gaps) of all maps in the space-time cube ] .pull-right[ <img src="https://grass.osgeo.org/grass78/manuals/timeline_2D.jpg"> ] --- - **Topology** refers to temporal relations between time intervals in a STDS. .center[<img src="assets/img/temp_relation.png">] --- layout: false .left-column[ ### TGRASS: #### framework and workflow] .right-column[<img src="assets/img/tgrass_flowchart.png" width="91%">] --- class: grass-slide center hide_logo ## .black[Walk through space-time analysis for disease ecology with GRASS GIS and]
--- class: grass-slide ### Demo session overview > .center[Habitat suitability mapping for the Asian tiger mosquito in Northern Italy based on variables derived from daily LST data] .pull-left[ - **GRASS** - Import species records - Create random background points - Create different environmental layers from daily LST data ] .pull-right[ - **R** - Read data from GRASS into R - Model species distribution - Model evaluation - Visualization of results ] --- .footnote[Jarnevich et al. 2015. doi:[10.1016/j.ecoinf.2015.06.007](https://doi.org/10.1016/j.ecoinf.2015.06.007)] .center[<img src="assets/img/sdm_workflow_edited.png" width="72%">] --- ### Data for the session .pull-left[ - Records of *Aedes albopictus* (Asian tiger mosquito) in Northern Italy downloaded from [GBIF](https://www.gbif.org/) - Daily MODIS LST reconstructed by [mundialis](https://www.mundialis.de/en/) based on [Metz et al. 2017](https://www.mdpi.com/2072-4292/9/12/1333/htm) - 1 km spatial resolution - Converted to Celsius degrees ] .pull-right[ <img src="assets/img/aedes_albopictus.jpg" width="47%" align="right"> <br> <img src="assets/img/lst_north_italy_2014.png" width="78%" align="left"> ] --- ###
Get sample location, mosquito records and code
- Create a folder named `grassdata_ogh` - Download and unzip [eu_laea location with LST mapset](https://drive.google.com/file/d/1z1b2NLC4Z6yzz_57RddTdRRK_gUkd7fU/view?usp=sharing) and unzip within your `grassdata_ogh` folder - Download the asian tiger [mosquito occurrences](https://github.com/veroandreo/grass_opengeohub2021/raw/master/data/aedes_albopictus.gpkg) as `.gpkg` file - Download the [GRASS script](https://github.com/veroandreo/grass_opengeohub2021/raw/master/code/grass_R_disease_ecology_code.sh) - Download the [R script](https://github.com/veroandreo/grass_opengeohub2021/raw/master/code/grass_R_disease_ecology_code.r) The `grassdata_ogh` folder's tree should look like this: ``` grassdata_ogh/ └── eu_laea ├── italy_LST_daily └── PERMANENT ``` --- .left-column[ ## Let's start GRASS GIS! 😯 ### Fear not! ] .right-column[ .center[<img src="assets/img/start_grass.png" width="60%"> 📢 This start-up screen will be gone in GRASS 8 !! ] ] --- ## What was that? <a href="https://grass.osgeo.org/grass76/manuals/grass_database.html">GRASS database</a> .pull-left[ - The **GRASS DATABASE** (or "GISDBASE") is an existing directory containing all GRASS GIS LOCATIONs. - A **LOCATION** is defined by its coordinate system and geographical boundaries. - **MAPSET** is a subdirectory within Locations. In a **MAPSET** you can organize GIS maps thematically, geographically, by project, etc. - When GRASS GIS starts, it connects to `Database/Location/Mapset`: ] .pull-right[ <img src="assets/img/grass_database.png" width="950px"> .right[More info at [grass database](#grass-database-slide)] ] --- class: grass-slide center # Now we are ready to start # 🏃 --- #### Importing species records .panelset[ .panel[.panel-name[GRASS code] ```bash # Import records v.import input=aedes_albopictus.gpkg output=aedes_albopictus # List raster maps g.list type=raster r.colors map=lst_2014.150_avg color=celsius # Display records d.mon wx0 d.rast lst_2014.150_avg d.vect aedes_albopictus icon=basic/circle \ size=7 fill_color=black ``` ] .panel[.panel-name[Map] .center[<img src="assets/img/wx0_aedes_lst.png" width="570px">] ] ] .footnote[You can also get the occurrences directly from GBIF into GRASS. See this [extra slide](#gbif-example).] --- #### Creating random background points .panelset[ .panel[.panel-name[GRASS code] ```bash # Create buffer around Aedes albopictus records v.buffer input=aedes_albopictus output=aedes_buffer distance=2000 # Set computational region g.region -p raster=lst_2014.001_avg # Create a vector mask to limit background points r.mapcalc expression="MASK = if(lst_2014.001_avg, 1, null())" r.to.vect input=MASK output=vect_mask type=area # Subtract buffers from vector mask v.overlay ainput=vect_mask binput=aedes_buffer operator=xor output=mask_bg # Generate random background points v.random output=background_points npoints=1000 restrict=mask_bg seed=3749 ``` ] .panel[.panel-name[Map] .center[<img src="assets/img/points_aedes_background.png" width="600px">] ] ] .footnote[See extra slides for details about [*computational region*](#region) and [*masks*](#mask) in GRASS GIS.] --- #### Create daily LST STRDS .panelset[ .panel[.panel-name[GRASS code] ```bash # Create time series t.create type=strds temporaltype=absolute \ output=lst_daily title="Average Daily LST" \ description="Average daily LST in degree C - 2014-2018" # Get list of maps g.list type=raster pattern="lst_201*" output=list_lst.csv # Register maps in strds t.register -i input=lst_daily file=list_lst.csv \ increment="1 days" start="2014-01-01" # Get info about the strds t.info input=lst_daily ``` ] .panel[.panel-name[Output] .center[<img src="assets/img/t_info_output.png" width="50%">] ] ] .footnote[See [t.create](https://grass.osgeo.org/grass-stable/manuals/t.create.html) & [t.register](https://grass.osgeo.org/grass-stable/manuals/t.register.html)] --- ### Generate environmental variables from LST STRDS #### Long term monthly avg, min and max LST .panelset[ .panel[.panel-name[GRASS code] ```bash for i in $(seq -w 1 12) ; do t.rast.series input=lst_daily method=average \ where="strftime('%m', start_time)='${i}'" \ output=lst_average_${i} t.rast.series input=lst_daily method=minimum \ where="strftime('%m', start_time)='${i}'" \ output=lst_minimum_${i} t.rast.series input=lst_daily method=maximum \ where="strftime('%m', start_time)='${i}'" \ output=lst_maximum_${i} done ``` ] .panel[.panel-name[Windows cmd] ```vbscript FOR %i IN (01,02,03,04,05,06,07,08,09,10,11,12) DO ( t.rast.series input=lst_daily method=average where="strftime('%m', start_time)='%i'" output=lst_average_%i t.rast.series input=lst_daily method=minimum where="strftime('%m', start_time)='%i'" output=lst_minimum_%i t.rast.series input=lst_daily method=maximum where="strftime('%m', start_time)='%i'" output=lst_maximum_%i ) ``` ] .panel[.panel-name[Output] .center[<img src="assets/img/list_long_term_avg_lst.png" width="70%">] ] ] .footnote[See [t.rast.series](https://grass.osgeo.org/grass-stable/manuals/t.rast.series.html) manual for further details] --- #### Bioclimatic variables .panelset[ .panel[.panel-name[GRASS code] ```bash # Install extension g.extension extension=r.bioclim # Estimate temperature related bioclimatic variables r.bioclim \ tmin=$(g.list type=raster pattern="lst_minimum_??" separator=",") \ tmax=$(g.list type=raster pattern="lst_maximum_??" separator=",") \ tavg=$(g.list type=raster pattern="lst_average_??" separator=",") \ output=worldclim_ # List output maps g.list type=raster pattern="worldclim*" ``` ] .panel[.panel-name[Output] .center[<img src="assets/img/list_worldclim_lst.png" width="80%">] ] .panel[.panel-name[Map] .center[<img src="assets/img/bio1.png" width="50%">] ] ] .footnote[See [r.bioclim](https://grass.osgeo.org/grass-stable/manuals/addons/r.bioclim.html) manual for further details] --- #### Spring warming .panelset[ .panel[.panel-name[GRASS code] ```bash # Annual spring warming: slope(daily Tmean february-march-april) t.rast.aggregate input=lst_daily output=annual_spring_warming \ basename=spring_warming suffix=gran \ method=slope granularity="1 years" \ where="strftime('%m',start_time)='02' or \ strftime('%m',start_time)='03' or \ strftime('%m', start_time)='04'" # Average spring warming t.rast.series input=annual_spring_warming \ output=avg_spring_warming \ method=average ``` ] .panel[.panel-name[Map] .center[<img src="assets/img/spring_warming.png" width="50%">] ] ] .footnote[See [t.rast.aggregate](https://grass.osgeo.org/grass-stable/manuals/t.rast.aggregate.html) manual] --- #### Autumnal cooling .panelset[ .panel[.panel-name[GRASS code] ```bash # Annual autumnal cooling: slope(daily Tmean august-september-october) t.rast.aggregate input=lst_daily output=annual_autumnal_cooling \ basename=autumnal_cooling suffix=gran \ method=slope granularity="1 years" \ where="strftime('%m',start_time)='08' or \ strftime('%m',start_time)='09' or \ strftime('%m', start_time)='10'" # Average autumnal cooling t.rast.series input=annual_autumnal_cooling \ output=avg_autumnal_cooling \ method=average ``` ] .panel[.panel-name[Map] .center[<img src="assets/img/autumnal_cooling.png" width="51%">] ] ] --- #### Number of days with LSTmean >= 20 and <= 30 .panelset[ .panel[.panel-name[GRASS code] ```bash # Keep only pixels meeting the condition t.rast.algebra -n \ expression="tmean_higher20_lower30 = if(lst_daily >= 20.0 && lst_daily <= 30.0, 1, null())" \ basename=tmean_higher20_lower30 suffix=gran nproc=7 # Count how many times per year the condition is met t.rast.aggregate input=tmean_higher20_lower30 \ output=count_tmean_higher20_lower30 \ basename=tmean_higher20_lower30 suffix=gran \ method=count granularity="1 years" # Average number of days with LSTmean >= 20 and <= 30 t.rast.series input=count_tmean_higher20_lower30 \ output=avg_count_tmean_higher20_lower30 method=average ``` ] .panel[.panel-name[Map] .center[<img src="assets/img/count_days_higher20_lower30.png" width="50%">] ] ] .footnote[See [t.rast.algebra](https://grass.osgeo.org/grass-stable/manuals/t.rast.algebra.html) manual for further details] --- layout: true #### Number of consecutive days with LSTmean <= -2.0 --- ```bash # Create annual mask t.rast.aggregate input=lst_daily output=annual_mask \ basename=annual_mask suffix=gran \ granularity="1 year" method=count # Replace values by zero t.rast.mapcalc input=annual_mask output=annual_mask_0 \ expression="if(annual_mask, 0)" \ basename=annual_mask_0 # Calculate consecutive days with LST <= -2.0 t.rast.algebra \ expression="lower_m2_consec_days = annual_mask_0 {+,contains,l} \ if(lst_daily <= -2.0 && lst_daily[-1] <= -2.0 || \ lst_daily[1] <= -2.0 && lst_daily <= -2.0, 1, 0)" \ basename=lower_m2_ suffix=gran nproc=7 ``` --- ```bash # Inspect values t.rast.list input=lower_m2_consec_days \ columns=name,start_time,end_time,min,max # Median number of consecutive days with LST <= -2 t.rast.series input=lower_m2_consec_days \ output=median_lower_m2_consec_days method=median ``` --- .center[<img src="assets/img/median_days_lower_m2.png" width="60%">] --- layout: false class: grass-slide hide_logo center ## We have all these maps in GRASS, how do we connect with R now? # 😯 --- ## [**rgrass7**](https://cran.r-project.org/web/packages/rgrass7/index.html) - `initGRASS()`: starts a GRASS GIS session from R - `execGRASS()`: executes GRASS GIS commands - `gmeta()`: shows GRASS location metadata - `readVECT()` and `readRAST()`: read vector and raster maps from GRASS into *sf* or *sp* objects - `writeVECT()` and `writeRAST()`: write *sf* or *sp* objects into GRASS GIS database .footnote[📢 Volunteers needed!!] --- layout: true ### GRASS GIS and
can be used together in two ways: --- .pull-left[ A. Using [R within a GRASS GIS session](https://grasswiki.osgeo.org/wiki/R_statistics/rgrass7#R_within_GRASS), i.e. starting R (or RStudio) from GRASS terminal <br> - type `R` or `rstudio &` in the GRASS GIS terminal - load `rgrass7` library - use `readVECT()`, `readRAST()` to read data from GRASS into R - access GRASS GIS modules and database through `execGRASS()` - write data (back) to GRASS database with `writeVECT()` and `writeRAST()` ] .pull-right[ <img src="assets/img/grass_terminal_calling_R.png" width="87%"> ] --- .pull-left[ B. Using [GRASS GIS within an R session](https://grasswiki.osgeo.org/wiki/R_statistics/rgrass7#GRASS_within_R), i.e. we connect to GRASS GIS database from within R (or RStudio). <br> - we need to start GRASS GIS with `initGRASS()` - we access GRASS GIS modules through `execGRASS()` > Originally intended to apply GRASS functions on data outside GRASS DB; hence some prefer to create throw away locations ] .pull-right[ <img src="assets/img/grass_within_rstudio_session.png" width="100%"> ] --- layout: false class: grass-slide center hide_logo # Let's move to
--- #### Option B: Close GRASS, open Rstudio and run: .panelset[ .panel[.panel-name[R code] ```r library(rgrass7) # path to GRASS binaries (run `grass78 --config path`) myGRASS <- "/usr/lib64/grass78" # path to GRASS database myGISDbase <- "/home/veroandreo/grassdata_ogh/" # path to location myLocation <- "eu_laea" # path to mapset myMapset <- "italy_LST_daily" # start GRASS GIS from R initGRASS(gisBase = myGRASS, home = tempdir(), gisDbase = myGISDbase, location = myLocation, mapset = myMapset, override = TRUE) ``` ] .panel[.panel-name[Output] ``` ## gisdbase /home/veroandreo/grassdata_ogh/ ## location eu_laea ## mapset italy_LST_daily ## rows 438 ## columns 582 ## north 2666000 ## south 2228000 ## west 4053000 ## east 4635000 ## nsres 1000 ## ewres 1000 ## projection: ## PROJCS["ETRS89-extended / LAEA Europe", ## GEOGCS["ETRS89", ## DATUM["European_Terrestrial_Reference_System_1989", ## SPHEROID["GRS 1980",6378137,298.257222101, ## AUTHORITY["EPSG","7019"]], ## AUTHORITY["EPSG","6258"]], ## PRIMEM["Greenwich",0, ## AUTHORITY["EPSG","8901"]], ## UNIT["degree",0.0174532925199433, ## AUTHORITY["EPSG","9122"]], ## AUTHORITY["EPSG","4258"]], ## PROJECTION["Lambert_Azimuthal_Equal_Area"], ## PARAMETER["latitude_of_center",52], ## PARAMETER["longitude_of_center",10], ## PARAMETER["false_easting",4321000], ## PARAMETER["false_northing",3210000], ## UNIT["metre",1, ## AUTHORITY["EPSG","9001"]], ## AXIS["Northing",NORTH], ## AXIS["Easting",EAST], ## AUTHORITY["EPSG","3035"]] ``` ] ] --- #### Load other packages ```r library(raster) library(sf) library(mapview) library(biomod2) ``` --- #### Read vector data .panelset[ .panel[.panel-name[R code] ```r # Use sf for vectors use_sf() # Read vector layers Aa_pres <- readVECT("aedes_albopictus") background <- readVECT("background_points") ``` ```r # Quick visualization in mapview mapview(Aa_pres) + mapview(background, col.regions=NA, cex=2) ``` ] .panel[.panel-name[Map]
] ] --- layout: true #### Read raster data --- ```r # Use sp for rasters use_sp() # List rasters by pattern worldclim <- execGRASS("g.list", parameters = list(type = "raster", pattern = "worldclim*")) avg <- execGRASS("g.list", parameters = list(type = "raster", pattern = "avg*")) median <- execGRASS("g.list", parameters = list(type = "raster", pattern = "median*", exclude = "*[1-5]")) # Concatenate map lists to_import <- c(attributes(worldclim)$resOut, attributes(avg)$resOut, attributes(median)$resOut) # Read raster layers predictors <- list() for (i in to_import){ predictors[i] <- raster(readRAST(i)) } ``` --- ```r # Quick visualization in mapview mapview(predictors[['worldclim_bio01']]) + Aa_pres ```
--- layout: false #### Data preparation and formatting ```r # Response variable n_pres <- dim(Aa_pres)[1] n_backg <- dim(background)[1] spp_name <- 'Aedes.albopictus' pres <- rep(1, n_pres) backg <- rep(0, n_backg) myResp <- c(pres, backg) myRespXY <- rbind(st_coordinates(Aa_pres), st_coordinates(background)) # Explanatory variables myExpl <- raster::stack(predictors) names(myExpl) ``` --- #### Data preparation and formatting .panelset[ .panel[.panel-name[R code] ```r # Format data as required by biomod myBiomodData <- BIOMOD_FormatingData(resp.var = myResp, expl.var = myExpl, resp.xy = myRespXY, resp.name = spp_name) # Inspect data myBiomodData # Plot data plot(myBiomodData) ``` ] .panel[.panel-name[Output] ``` ## ## -=-=-=-=-=-=-=-=-=-=-=-=-=-= 'BIOMOD.formated.data' -=-=-=-=-=-=-=-=-=-=-=-=-=-= ## ## sp.name = Aedes.albopictus ## ## 83 presences, 1000 true absences and 0 undifined points in dataset ## ## ## 13 explanatory variables ## ## worldclim_bio01 worldclim_bio02 worldclim_bio03 worldclim_bio04 ## Min. :-62.0 Min. : 90.0 Min. :30.00 Min. :5259 ## 1st Qu.: 68.0 1st Qu.:123.0 1st Qu.:34.00 1st Qu.:7036 ## Median :127.0 Median :134.0 Median :36.00 Median :7644 ## Mean :105.5 Mean :138.1 Mean :37.64 Mean :7597 ## 3rd Qu.:148.0 3rd Qu.:152.0 3rd Qu.:41.00 3rd Qu.:8164 ## Max. :181.0 Max. :200.0 Max. :50.00 Max. :9423 ## worldclim_bio05 worldclim_bio06 worldclim_bio07 worldclim_bio10 ## Min. : 76.0 Min. :-298.00 Min. :262 Min. : 19.0 ## 1st Qu.:233.0 1st Qu.:-136.00 1st Qu.:343 1st Qu.:152.0 ## Median :292.0 Median : -73.00 Median :364 Median :210.0 ## Mean :275.8 Mean : -91.19 Mean :367 Mean :194.8 ## 3rd Qu.:318.0 3rd Qu.: -37.00 3rd Qu.:388 3rd Qu.:238.0 ## Max. :368.0 Max. : 28.00 Max. :463 Max. :282.0 ## worldclim_bio11 avg_autumnal_cooling avg_count_tmean_higher20_lower30 ## Min. :-154.0 Min. :-0.20541 Min. : 0.00 ## 1st Qu.: -22.0 1st Qu.:-0.16395 1st Qu.: 10.00 ## Median : 51.0 Median :-0.14662 Median : 74.80 ## Mean : 20.7 Mean :-0.14850 Mean : 66.97 ## 3rd Qu.: 64.0 3rd Qu.:-0.13162 3rd Qu.:117.20 ## Max. : 100.0 Max. :-0.09174 Max. :144.20 ## avg_spring_warming median_lower_m2_consec_days ## Min. :0.09004 Min. : 0.00 ## 1st Qu.:0.14585 1st Qu.: 0.00 ## Median :0.16640 Median : 2.00 ## Mean :0.16328 Mean : 36.23 ## 3rd Qu.:0.17820 3rd Qu.: 61.50 ## Max. :0.21660 Max. :237.00 ## ## -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= ``` ] .panel[.panel-name[Plot] <img src="presentation_files/figure-html/plot_data_object-1.png" width="72%" /> ] ] --- #### Set model(s) options .panelset[ .panel[.panel-name[R code] ```r # Set model options myBiomodOption <- BIOMOD_ModelingOptions( MAXENT.Phillips = list(path_to_maxent.jar = "/home/veroandreo/software/maxent/maxent.jar", maximumiterations = 200, lq2lqptthreshold = 100, l2lqthreshold = 100)) # Inspect all configs for MaxEnt myBiomodOption@MAXENT.Phillips ``` ] .panel[.panel-name[Output] ``` ## $path_to_maxent.jar ## [1] "/home/veroandreo/software/maxent" ## ## $memory_allocated ## [1] 512 ## ## $background_data_dir ## [1] "default" ## ## $maximumbackground ## [1] "default" ## ## $maximumiterations ## [1] 200 ## ## $visible ## [1] FALSE ## ## $linear ## [1] TRUE ## ## $quadratic ## [1] TRUE ## ## $product ## [1] TRUE ## ## $threshold ## [1] TRUE ## ## $hinge ## [1] TRUE ## ## $lq2lqptthreshold ## [1] 100 ## ## $l2lqthreshold ## [1] 100 ## ## $hingethreshold ## [1] 15 ## ## $beta_threshold ## [1] -1 ## ## $beta_categorical ## [1] -1 ## ## $beta_lqp ## [1] -1 ## ## $beta_hinge ## [1] -1 ## ## $betamultiplier ## [1] 1 ## ## $defaultprevalence ## [1] 0.5 ``` ] ] --- #### Run model ```r # Run model myBiomodModelOut <- BIOMOD_Modeling( myBiomodData, models = c('MAXENT.Phillips'), models.options = myBiomodOption, NbRunEval=5, DataSplit=80, VarImport=10, models.eval.meth = c('ROC','ACCURACY'), SaveObj = TRUE, rescal.all.models = FALSE, do.full.models = FALSE, modeling.id = paste(spp_name,"Habitat_Suitability",sep="_")) # Inspect the model myBiomodModelOut ``` --- #### Model evaluation .panelset[ .panel[.panel-name[R code] ```r # Extract evaluation data myBiomodModelEval <- get_evaluations(myBiomodModelOut) # Accuracy myBiomodModelEval["ACCURACY","Testing.data",,,] # ROC: Receiver-operator curve myBiomodModelEval["ROC","Testing.data",,,] # Save run with max ROC max_roc <- which.max(myBiomodModelEval["ROC","Testing.data",,,]) ``` ``` ## RUN1 RUN2 RUN3 RUN4 RUN5 ## 0.931 0.945 0.935 0.931 0.935 ## RUN1 RUN2 RUN3 RUN4 RUN5 ## 0.736 0.871 0.757 0.668 0.847 ``` ] .panel[.panel-name[Plot] <img src="presentation_files/figure-html/plot_model_eval-1.png" width="60%" /> ] ] --- #### Variable importance .panelset[ .panel[.panel-name[R code] ```r # Variable importance vi <- get_variables_importance(myBiomodModelOut) # Let's see the first part head(vi[1:13,1, ,], n = 10L) %>% knitr::kable(format = 'html') # ... and estimate the mean head(apply(vi, c(1,2), mean)) %>% knitr::kable(format = 'html') ``` ] .panel[.panel-name[Output 1] <table> <thead> <tr> <th style="text-align:left;"> </th> <th style="text-align:right;"> RUN1 </th> <th style="text-align:right;"> RUN2 </th> <th style="text-align:right;"> RUN3 </th> <th style="text-align:right;"> RUN4 </th> <th style="text-align:right;"> RUN5 </th> </tr> </thead> <tbody> <tr> <td style="text-align:left;"> worldclim_bio01 </td> <td style="text-align:right;"> 0.264 </td> <td style="text-align:right;"> 0.033 </td> <td style="text-align:right;"> 0.046 </td> <td style="text-align:right;"> 0.132 </td> <td style="text-align:right;"> 0.119 </td> </tr> <tr> <td style="text-align:left;"> worldclim_bio02 </td> <td style="text-align:right;"> 0.000 </td> <td style="text-align:right;"> 0.000 </td> <td style="text-align:right;"> 0.009 </td> <td style="text-align:right;"> 0.016 </td> <td style="text-align:right;"> 0.030 </td> </tr> <tr> <td style="text-align:left;"> worldclim_bio03 </td> <td style="text-align:right;"> 0.111 </td> <td style="text-align:right;"> 0.013 </td> <td style="text-align:right;"> 0.000 </td> <td style="text-align:right;"> 0.044 </td> <td style="text-align:right;"> 0.003 </td> </tr> <tr> <td style="text-align:left;"> worldclim_bio04 </td> <td style="text-align:right;"> 0.091 </td> <td style="text-align:right;"> 0.009 </td> <td style="text-align:right;"> 0.008 </td> <td style="text-align:right;"> 0.107 </td> <td style="text-align:right;"> 0.070 </td> </tr> <tr> <td style="text-align:left;"> worldclim_bio05 </td> <td style="text-align:right;"> 0.095 </td> <td style="text-align:right;"> 0.013 </td> <td style="text-align:right;"> 0.004 </td> <td style="text-align:right;"> 0.193 </td> <td style="text-align:right;"> 0.163 </td> </tr> <tr> <td style="text-align:left;"> worldclim_bio06 </td> <td style="text-align:right;"> 0.600 </td> <td style="text-align:right;"> 0.000 </td> <td style="text-align:right;"> 0.000 </td> <td style="text-align:right;"> 0.707 </td> <td style="text-align:right;"> 0.767 </td> </tr> <tr> <td style="text-align:left;"> worldclim_bio07 </td> <td style="text-align:right;"> 0.012 </td> <td style="text-align:right;"> 0.000 </td> <td style="text-align:right;"> 0.000 </td> <td style="text-align:right;"> 0.023 </td> <td style="text-align:right;"> 0.001 </td> </tr> <tr> <td style="text-align:left;"> worldclim_bio10 </td> <td style="text-align:right;"> 0.004 </td> <td style="text-align:right;"> 0.018 </td> <td style="text-align:right;"> 0.010 </td> <td style="text-align:right;"> 0.008 </td> <td style="text-align:right;"> 0.006 </td> </tr> <tr> <td style="text-align:left;"> worldclim_bio11 </td> <td style="text-align:right;"> 0.104 </td> <td style="text-align:right;"> 0.010 </td> <td style="text-align:right;"> 0.009 </td> <td style="text-align:right;"> 0.120 </td> <td style="text-align:right;"> 0.069 </td> </tr> <tr> <td style="text-align:left;"> avg_autumnal_cooling </td> <td style="text-align:right;"> 0.078 </td> <td style="text-align:right;"> 0.000 </td> <td style="text-align:right;"> 0.000 </td> <td style="text-align:right;"> 0.092 </td> <td style="text-align:right;"> 0.037 </td> </tr> </tbody> </table> ] .panel[.panel-name[Output 2] <table> <thead> <tr> <th style="text-align:left;"> </th> <th style="text-align:right;"> MAXENT.Phillips </th> </tr> </thead> <tbody> <tr> <td style="text-align:left;"> worldclim_bio01 </td> <td style="text-align:right;"> 0.1188 </td> </tr> <tr> <td style="text-align:left;"> worldclim_bio02 </td> <td style="text-align:right;"> 0.0110 </td> </tr> <tr> <td style="text-align:left;"> worldclim_bio03 </td> <td style="text-align:right;"> 0.0342 </td> </tr> <tr> <td style="text-align:left;"> worldclim_bio04 </td> <td style="text-align:right;"> 0.0570 </td> </tr> <tr> <td style="text-align:left;"> worldclim_bio05 </td> <td style="text-align:right;"> 0.0936 </td> </tr> <tr> <td style="text-align:left;"> worldclim_bio06 </td> <td style="text-align:right;"> 0.4148 </td> </tr> <tr> <td style="text-align:left;"> worldclim_bio07 </td> <td style="text-align:right;"> 0.0072 </td> </tr> <tr> <td style="text-align:left;"> worldclim_bio10 </td> <td style="text-align:right;"> 0.0092 </td> </tr> <tr> <td style="text-align:left;"> worldclim_bio11 </td> <td style="text-align:right;"> 0.0624 </td> </tr> <tr> <td style="text-align:left;"> avg_autumnal_cooling </td> <td style="text-align:right;"> 0.0414 </td> </tr> </tbody> </table> ] ] --- #### Response curves .panelset[ .panel[.panel-name[R code] ```r # Extract model of interest Aa_maxent <- BIOMOD_LoadModels(myBiomodModelOut, models = "MAXENT.Phillips") # Plot response curves resp_curves <- biomod2::response.plot2(models = Aa_maxent, Data = get_formal_data(myBiomodModelOut, "expl.var"), show.variables = get_formal_data(myBiomodModelOut, "expl.var.names"), do.bivariate = FALSE, fixed.var.metric = "median") ``` ] .panel[.panel-name[Plot] <img src="presentation_files/figure-html/unnamed-chunk-5-1.png" width="60%" /> ] ] --- #### Model predictions .panelset[ .panel[.panel-name[R code] ```r # Set parameters for model projection myBiomodProj <- BIOMOD_Projection( modeling.output = myBiomodModelOut, new.env = myExpl, proj.name = "current", selected.models = "all", compress = FALSE, build.clamping.mask = FALSE) # Obtain predictions mod_proj <- get_predictions(myBiomodProj) # Plot predicted model with highest ROC mapview(mod_proj[[max_roc]]) ``` ] .panel[.panel-name[Map]
] ] --- #### Optionally, write data back to GRASS GIS .panelset[ .panel[.panel-name[R code] ```r # Export only one layer g <- as(mod_proj[[max_roc]], 'SpatialGridDataFrame') writeRAST(g, "maxent_albopictus", flags = "overwrite") # Export all MaxEnt runs for(i in seq_along(1:length(mod_proj@layers))){ writeRAST(as(mod_proj[[i]], 'SpatialGridDataFrame'), paste0("maxent_albopictus_", i, sep=""), flags = "overwrite") } # Check it's there execGRASS("g.list", parameters = list(type = "raster", pattern = "maxent*")) ``` ] .panel[.panel-name[Output] ``` *## 0% 3% 6% 9% 12% 15% 18% 21% 24% 27% 30% 33% 36% 39% 42% 45% 48% 51% 54% 57% 60% 63% 66% 69% 72% 75% 78% 81% 84% 87% 90% 93% 96% 99% 100% *``` ``` *## 0% 3% 6% 9% 12% 15% 18% 21% 24% 27% 30% 33% 36% 39% 42% 45% 48% 51% 54% 57% 60% 63% 66% 69% 72% 75% 78% 81% 84% 87% 90% 93% 96% 99% 100% *## 0% 3% 6% 9% 12% 15% 18% 21% 24% 27% 30% 33% 36% 39% 42% 45% 48% 51% 54% 57% 60% 63% 66% 69% 72% 75% 78% 81% 84% 87% 90% 93% 96% 99% 100% *## 0% 3% 6% 9% 12% 15% 18% 21% 24% 27% 30% 33% 36% 39% 42% 45% 48% 51% 54% 57% 60% 63% 66% 69% 72% 75% 78% 81% 84% 87% 90% 93% 96% 99% 100% *## 0% 3% 6% 9% 12% 15% 18% 21% 24% 27% 30% 33% 36% 39% 42% 45% 48% 51% 54% 57% 60% 63% 66% 69% 72% 75% 78% 81% 84% 87% 90% 93% 96% 99% 100% *## 0% 3% 6% 9% 12% 15% 18% 21% 24% 27% 30% 33% 36% 39% 42% 45% 48% 51% 54% 57% 60% 63% 66% 69% 72% 75% 78% 81% 84% 87% 90% 93% 96% 99% 100% *``` ``` *## maxent_albopictus *## maxent_albopictus_1 *## maxent_albopictus_2 *## maxent_albopictus_3 *## maxent_albopictus_4 *## maxent_albopictus_5 *``` ] ] --- ### Disclaimer This is only a toy example and only the beginning... - other models to test - hyper-parameter tuning - variable selection and model selection - ensemble modeling - model validation with independent data - uncertainty: where we can predict with confidence - many other relevant packages: - [*dismo*](https://cran.r-project.org/web/packages/dismo/index.html), [*sdm*](https://cran.r-project.org/web/packages/sdm/index.html), [*SDMtune*](https://cran.r-project.org/web/packages/SDMtune/index.html), [*kuenm*](https://github.com/marlonecobos/kuenm), [*caret*](https://cran.r-project.org/web/packages/caret/index.html), [*CAST*](https://cran.r-project.org/web/packages/CAST/index.html), etc. --- class: center, middle <img src="assets/img/gummy-question.png" width="45%"> --- # 🆘 GRASS GIS HELP!!! - [g.manual](https://grass.osgeo.org/grass76/manuals/g.manual.html): in the main GUI under Help or just pressing *F1* - `--help` or `--h` flag after the module name in the terminal - [GRASS website](https://grass.osgeo.org/): rich [learn](https://grass.osgeo.org/learn/) section with links to videos, tutorials, courses, books, etc. - [GRASS wiki](https://grasswiki.osgeo.org/wiki/GRASS-Wiki): examples, explanations on particular modules or tasks, [tutorials](https://grasswiki.osgeo.org/wiki/Category:Tutorial), applications, etc. - grass-user mailing list: [subscribe](https://lists.osgeo.org/mailman/listinfo/grass-user) and post or check the [archives](https://lists.osgeo.org/pipermail/grass-user/) - Link to source code and history in each module manual page, eg., [t.rast.algebra](https://grass.osgeo.org/grass-stable/manuals/t.rast.algebra.html) .center[<img src="assets/img/source_code_link.png" width="650px">] --- ## 🔗 Other (very) useful links - [GRASS intro workshop held at NCSU](https://ncsu-osgeorel.github.io/grass-intro-workshop/) - [Unleash the power of GRASS GIS at US-IALE 2017](https://grasswiki.osgeo.org/wiki/Unleash_the_power_of_GRASS_GIS_at_US-IALE_2017) - [Temporal data processing wiki](https://grasswiki.osgeo.org/wiki/Temporal_data_processing) - [GRASS GIS and R for time series processing wiki](https://grasswiki.osgeo.org/wiki/Temporal_data_processing/GRASS_R_raster_time_series_processing) - [GRASS GIS temporal workshop at NCSU](http://ncsu-geoforall-lab.github.io/grass-temporal-workshop/) - [GRASS GIS course in Jena](https://training.gismentors.eu/grass-gis-workshop-jena/index.html) - [GRASS GIS course IRSAE](http://training.gismentors.eu/grass-gis-irsae-winter-course-2018/index.html) - [GRASS GIS course in Argentina](https://gitlab.com/veroandreo/curso-grass-gis-rioiv) --- ## 📖 GRASS and TGRASS References - Neteler, M., Mitasova, H. (2008): *Open Source GIS: A GRASS GIS Approach*. Third edition. ed. Springer, New York. [Book site](https://grassbook.org/) - Neteler, M., Bowman, M.H., Landa, M. and Metz, M. (2012): *GRASS GIS: a multi-purpose Open Source GIS*. Environmental Modelling & Software, 31: 124-130 [DOI](http://dx.doi.org/10.1016/j.envsoft.2011.11.014) - Gebbert, S., Pebesma, E. (2014). *A temporal GIS for field based environmental modeling*. Environmental Modelling & Software, 53, 1-12. [DOI](https://doi.org/10.1016/j.envsoft.2013.11.001) - Gebbert, S., Pebesma, E. (2017). *The GRASS GIS temporal framework*. International Journal of Geographical Information Science 31, 1273-1292. [DOI](http://dx.doi.org/10.1080/13658816.2017.1306862) - Gebbert, S., Leppelt, T. and Pebesma, E. (2019). *A Topology Based Spatio-Temporal Map Algebra for Big Data Analysis*. Data, 4, 86. [DOI](https://doi.org/10.3390/data4020086) --- class: center middle hide_logo <br> .large[See you at the international [FOSS4G](https://2021.foss4g.org/) by the end of the month! Have a look at the amazing list of [workshops](https://2021.foss4g.org/schedule/workhops.html) and [talks](https://2021.foss4g.org/schedule/full-schedule.html) offered and [register](https://registration.2021.foss4g.org/OSGeo/FOSS4G/)! ] <img src="https://registration.2021.foss4g.org/media/pub/thumbs/fccad5b3f7e82c69e51a33ac42bdd536.5000x120.png" width="35%"> --- class: center hide_logo # Thanks!! <img src="assets/img/vero_round_small.png" width="18%">
<a href="https://github.com/veroandreo/">veroandreo</a>
<a href="https://twitter.com/VeronicaAndreo">@VeronicaAndreo</a>
https://veroandreo.gitlab.io/ --- class: grass-slide middle center # Extra slides --- class: grass-slide, hide_logo, center # Different interfaces GRASS GIS offers different interfaces for the interaction between user and software. --- layout: true ### Graphical User Interface (GUI) --- .left-column[ GRASS 7+ ] .right-column[ <img src="assets/img/GUI_description.png" width="870px"> ] --- .left-column[ GRASS 8 ] .right-column[ <img src="https://grass.osgeo.org/images/news/grassgui8_first_infobar.png" width="950px"> ] --- .left-column[ GRASS 8+ Upcoming option to switch between multiple and single window interface ] .right-column[ <img src="assets/img/grass_single_window.png" width="950px"> ] --- layout: true ###
Python --- - 2 libraries delivered with GRASS GIS: **grass** and **pygrass**, that provide access to modules and internal C functions - 1 external library: [**grass-session**](https://github.com/zarch/grass-session) that can be installed with `pip` <center><img src="assets/img/simple_python_editor.png" width="63%"></center> --- ... write your Python script and run it from CLI or GUI: ```python #!/usr/bin/env python # simple example of pyGRASS usage: raster processing via modules approach from grass.pygrass.modules.shortcuts import general as g from grass.pygrass.modules.shortcuts import raster as r g.message("Filter elevation map by a threshold...") # set computational region input = 'elevation' g.region(raster=input) output = 'elev_100m' thresh = 100.0 r.mapcalc("%s = if(%s > %d, %s, null())" % (output, input, thresh, input), overwrite = True) r.colors(map=output, color="elevation") ``` --- ... or use GRASS and Python within Jupyter Lab/notebooks via **grass.jupyter**: a new library under development that will come with GRASS 8 .pull-left[.center[ <img src="assets/img/grass_jupyter.png" width="75%">]] .pull-right[ # 🤩 <br>Curious?? Try yourself [here](https://mybinder.org/v2/gh/OSGeo/grass/c173461?urlpath=lab%2Ftree%2Fdoc%2Fnotebooks%2Fgrass_jupyter.ipynb) ] --- layout: true ### QGIS --- .right-column[ <img src="assets/img/qgis_grass_plugin.png" width="99%"> ] .left-column[ [GRASS GIS plugin](https://docs.qgis.org/3.16/en/docs/user_manual/grass_integration/grass_integration.html) ] --- .right-column[ <img src="assets/img/qgis_processing.png" width="99%"> ] .left-column[ [Processing toolbox](https://docs.qgis.org/3.16/en/docs/user_manual/processing/toolbox.html) ] --- layout: false ### GRASS +
through rgrass7 package We can use [R within a GRASS GIS session](https://grasswiki.osgeo.org/wiki/R_statistics/rgrass7#R_within_GRASS) or use [GRASS GIS within an R session](https://grasswiki.osgeo.org/wiki/R_statistics/rgrass7#GRASS_within_R) <center><img src="assets/img/RwithinGRASS_and_Rstudio_from_grass.png" width="75%"></center> --- name: grass-database-slide ## Basic notions: <a href="https://grass.osgeo.org/grass76/manuals/grass_database.html">GRASS database</a> - **Why this structure?** - GRASS GIS has a *native format* for raster and vector data, therefore they must be *imported* or *linked* into a GRASS Location/Mapset. - **What are the advantages?** - GRASS DATABASE, LOCATIONs and MAPSETs are folders that *can be easily shared with other users*. - The GRASS DATABASE can be *local or remote*, and *special permissions* can be set to specific mapsets in a LOCATION. - All data in a LOCATION have necessarily the same CRS. --- name: gbif-example #### GBIF data can be queried and downloaded directly from GRASS ```bash # Set computational region g.region -p raster=lst_2014.001_avg # Install extension # requires pygbif: `pip install pygbif` g.extension extension=v.in.pygbif # Import data from GBIF v.in.pygbif output=aedes_albopictus \ taxa="Aedes albopictus" \ date_from="2014-01-01" \ date_to="2018-12-31" ``` .footnote[Check [v.in.pygbif](https://grass.osgeo.org/grass-stable/manuals/addons/v.in.pygbif.html) for further options, eg., `mask`] --- name: region ## [Computational region](https://grasswiki.osgeo.org/wiki/Computational_region) ![Show computational region](assets/img/region.png) --- ## [Computational region](https://grasswiki.osgeo.org/wiki/Computational_region) .pull-left[ The **computational region** is defined by the *bounding box and resolution* (for raster and 3D raster maps). It can be set and changed by means of [g.region](https://grass.osgeo.org/grass-stable/manuals/g.region.html) to the extent of a vector map, a raster map or manually to some area of interest (subset). *Output rasters* will have their extent and resolution equal to the current region. ] .pull-right[ - **Advantages** - Keep your results consistent - Avoid clipping maps prior to subarea analysis - Test an algorithm or computationally demanding process in small areas - Fine-tune the settings of a certain module - Run different processes in different areas ] --- name:mask ## MASK - Masks are set with [r.mask](https://grass.osgeo.org/grass76/manuals/r.mask.html) or creating a raster map called `MASK`. - Masks are virtual masks, they are only actually applied when reading raster maps - All cells that are *NULL* in the MASK map will be ignored (also all areas outside the computational region). - Vector maps can be also used as masks .center[ <img src="assets/img/masks.png" width="62%" > .small[a- Elevation raster and lakes vector maps. b- Only the raster data inside the masked area are used for further analysis. c- Inverse mask.] ] --- ### MASK examples ```bash # use vector as mask r.mask vector=lakes # use vector as mask, set inverse mask r.mask -i vector=lakes # mask categories of a raster map r.mask raster=landclass96 maskcats="5 thru 7" # create a raster named MASK r.mapcalc expression="MASK = if(elevation < 100, 1, null())" # remove mask r.mask -r ``` .footnote[Masks are only actually applied when reading a GRASS raster map, i.e., when used as input.] --- class: center bottom Slides created via the R packages: [xaringan](https://github.com/yihui/xaringan)<br> [xaringanExtra]()<br> [gadenbuie/xaringanthemer](https://github.com/gadenbuie/xaringanthemer)