Abstract

The U.S. Army Corps of Engineers (USACE) engages in a large variety of decisions affecting ecological outcomes such as ecosystem restoration of oyster reefs, environmental flows for imperiled fishes, and bird breeding grounds impacted by dredge material management. A common approach to ecological modeling of environmental impacts and benefits is based on the quantity and quality of habitats. No standard modeling platform exists for computing outcomes from these “index” models, and users often develop ad hoc spreadsheet models. Here, we present a generic, flexible, error-checked index modeling platform applicable Nationwide, which we refer to as the “ecorest” modeling framework. Four modules compose this framework. First, model parameters are compiled as a data set and associated metadata for 349 habitat suitability models developed by the U.S. Fish and Wildlife Service. Second, functions are presented for conducting habitat suitability analyses for both the models described above as well as generic user-specified model parameterizations. Third, a suite of decision support tools are presented for conducting cost-effectiveness and incremental cost analyses. These three modules are all contained within an open source modeling package for the R Statistical Software Language called ecorest. This modeling platform seeks to standardize availability and application of index models within the USACE.

Author Headnotes:

  • Corresponding Author: Darixa D. Hernandez-Abrams, U.S. Army Engineer Research and Development Center (ERDC), Environmental Laboratory (EL), Vicksburg, M.S.,
  • This report provides an overview of development of an ecological modeling platform for USACE model certification. Model source code has been previously reviewed and released as the ecorest “package” by the Comprehensive R Archive Network (CRAN). This report will simultaneously undergo peer review as an ERDC Technical Report.
  • All analyses are conducted in the (ACE-IT approved) R Statistical Software.
  • Color schemes may seem non-traditional (i.e., non-rainbow arrays), but colors were chosen for maximum understanding by color deficient audiences. Nationwide, approximately 8% of men and 0.5% of women exhibit some form of color deficiency. In USACE, supervisors (GS-13 or higher) are ~74% male and ~26% female, which results in a 6% chance of a team member exhibiting color-blindness (1 out of 17). Among USACE decision makers, army officers (O4 or higher) are ~85% male and ~15% female, which results in a 7% chance of a team member exhibiting color-blindness (1 out of 15). Specifically, ecorest uses viridis color schemes.

1. Background

Across all business lines, the U.S. Army Corps of Engineers (USACE) engages in a large variety of decisions that affect a multitude of ecological outcomes (e.g., ecosystem restoration of oyster reefs, environmental flows for imperiled fishes, and bird breeding grounds impacted by dredge material management). While numerous aquatic, riparian, and terrestrial analytical tools exist, ecological models typically have not been easily accessible or in the most usable form for field practitioners and often require significant data and modeling expertise to effectively employ. However, ecological models must be used to quantify environmental impacts and benefits throughout the project life-cycle (i.e., planning, engineering, construction, operations, and maintenance phases).

A common approach to ecological modeling of environmental impacts and benefits is based on quantity and quality of habitat. These “index” models (Swannack et al. 2012) were originally developed for species-specific applications (e.g., slider turtles), but the general approach has also been adapted to guilds (e.g., salmonids), communities (e.g., floodplain vegetation), and ecosystem processes (e.g., the Hydrogeomorphic Method). No standard platform exists for computing outcomes from index models, and users often develop ad hoc spreadsheet models, which are highly prone to numerical errors (McKay 2009). The common quantity-quality structure of index models provides an opportunity to develop a consistent, error-checked index modeling calculator adaptable to a variety of applications across the Corps of Engineers.

Furthermore, ecological modeling often seeks to inform trade-offs between a monetary assessment of social benefits or costs (e.g., restoration investment cost or economic damages avoided) and a non-monetary assessment of environmental benefits and costs (e.g., habitat gains of restoration or impact to an imperiled taxon’s habitat). Cost-effectiveness and incremental cost analyses (CEICA) provide a useful set of techniques for comparing non-monetary and monetary costs and benefits of management actions (Robinson et al. 1995). CEICA is commonly applied in planning and designing ecosystem restoration projects and is often coupled with index models to inform management decisions.

1.1 Problem Statement

This document describes a set of computational tools for assessing ecological outcomes with index models and informing trade-offs between monetary and non-monetary outcomes. The following topics guided the scope of this analysis:

  • Model Purpose: Ad hoc development of index models is leading to significant USACE investments in computational tool development, user learning, model review, and certification. This platform seeks to provide an error-checked, computationally accurate tool for assessing ecological outcomes with index models. Furthermore, the platform should also provide seamless integration of decision support tools to avoid potential errors associated with data transfer between separate ecological and decision models.
  • Target Application: This toolkit is intended primarily for USACE ecosystem restoration planning; however, index models are also often applied for impact assessment, compensatory mitigation, and wetland regulatory issues.
  • Target Users: The primary audience for these tools is USACE planners, biologists, and engineers involved in ecosystem restoration projects or environmental evaluations.
  • Model Engine: This document addresses the development of computational engines for index models and decision support tools, both of which are developed as the ecorest “package” for broad distribution via the R statistical software language. The R-package may be accessed through the (ACE-IT approved) R freeware and associated user-interfaces such as RStudio.
  • Modular Design: All model capabilities are developed as separate databases and functions, which can be accessed independently. For instance, the toolkit is intended to provide “one stop shopping” for USACE restoration planning needs by integrating index and decision support models. However, users may also use non-index models (e.g., population demography models via popbio) to examine other ecological outcomes in the decision modules. Likewise, users could compute index model outcomes without using decision support tools.

Ultimately, the overarching objective of this model is to develop a technically sound and computationally accurate suite of tools for assessing ecosystem impacts in restoration project planning or habitat assessments with index models, which are easily accessible for use by USACE planners, biologists, and engineers. This report describes the development of a suite of modeling tools called ecorest. While developed for ecosystem restoration applications, the tools may be applied in a variety of other contexts including impact assessment and non-restoration cost-benefit analysis.

1.2. Model Development Process

Models were developed following a general ecological modeling process, which incorporates conceptualization, quantification, evaluation, application, and communication phases (Grant and Swannack 2008). Tools were conceptualized based on common approaches to index modeling. Generic functions were then developed to quantify index model and decision support outcomes, which were “packed” for use in the R Statistical Software. Models are then evaluated relative to their numerical accuracy and usability. Finally, application and communication of models is demonstrated through a series of appendices with step-by-step instructional guides and example applications on USACE restoration studies.

Models were iteratively developed and checked. Functions were initially developed and tested by the authors and other ERDC Environmental Laboratory staff. Models were then expanded and generalized in the form of the ecorest R-package, which was subsequently reviewed and posted online via the Comprehensive R Archive Network (CRAN). All versions of the final ecorest package were then formally tested against known verified model outcomes, and example applications were developed for demonstration purposes.

This report is organized around the modeling process followed. Each section describes the technical basis of index-based models, along with their execution in ecorest. Report appendices provide additional information about models such as formal testing, user guides, and numerous example applications. This document is intended to provide documentation of the model’s technical details, use, and relevant information for USACE model certification (EC 1105-2-412, PB 2013-02).

2. Conceptualization

The ecorest platform synthesizes two major analytical approaches within a single numerical framework. First, index models are a common ecological modeling approach used in assessing impacts and benefits of environmental management actions. Second, cost-effectiveness and incremental cost analysis (CEICA) are decision support tools for informing decisions involving non-commensurate metrics such as non-monetary ecological outcomes and monetary costs. Finally, the ecorest modeling platform provides a computational workflow for uniting these analyses to inform ecosystem restoration decision-making. The following sections review the conceptual foundation for each of these topics separately.

2.1. Index-Based Ecological Models

Ecological models have become common tools for informing decisions related to the management of complex ecological processes. Models span the breadth of their potential ecological management applications such as seafood harvest limits, transport of nutrients into freshwaters, bioaccumulation of contaminants, management of imperiled taxa, and wetland impact assessment. In addition to diverse outcomes, ecological models often take on a variety of theoretical constructs ranging from theoretical, analytical models to statistical correlations of variables to agent-based simulations of animal movement (see Swannack et al. 2012 for a review of ecological model types). The diversity of ecological endpoints and model constructs has led to a wide array of tools applicable to ecosystem management and restoration.

Index models are a family of techniques commonly applied in planning ecosystem restoration projects. Briefly, index models quantitatively translate multiple features or processes into a relative assessment of habitat suitability for a given organism or a relative assessment of ecosystem condition (Tirpak et al. 2009, Swannack et al. 2012). More specifically, index models combine assessments of habitat or ecosystem quality and quantity into an overarching metric for assessing the relative condition of a site (e.g., a “habitat unit” or “functional capacity unit”). Quantity is commonly expressed as a metric of area such as acres or hectares; however, other metrics may be appropriate to specific applications such as river length or lake volume. Quality is then assessed by identifying key variables correlated with habitat or ecosystem condition. Each variable is then translated into a suitability index curve, which transforms dimensional quantities such as flow velocity into dimensionless values of quality (0 to 1 where 0 is unsuitable/low condition and 1 is suitable/ideal condition). Multiple suitability curves are then combined through various equational forms into an overarching assessment of habitat quality (e.g., a “habitat suitability index” or “functional capacity index”).

Index models may be derived from a variety of methods and resources. Like all models, many index model developers have emphasized that these algorithms simplify complex ecosystems, and thus, these tools should be considered adaptable hypotheses rather than mechanistic, cause-effect relationships. The value of index models lies in their utility for quantitatively comparing the relative merits of alternative management actions and testing hypotheses. The following represent the most common sources of index models applied to USACE ecosystem restoration projects:

  • U.S. Fish and Wildlife Service (USFWS) Habitat Suitability Index (HSI) Models: The HSI approach quantitatively relates the potential for species presence to habitat characteristics. Species have complex relationships with their environment, and HSI models provide a simple method for characterizing the potential for habitat to support target species across a landscape. The USFWS led the development of 500+ HSI models in the 1970-1980s to support environmental management decisions nationwide (https://www.nwrc.usgs.gov/wdb/pub/hsi/hsiindex.htm). The quantitative relationships between species and habitat were generally based on a combination of literature, field studies, and expert opinion, and the reports are colloquially referred to as the “blue books” because of the blue covers binding the original publications.
  • Hydrogeomorphic Method (HGM) of Wetland Assessment: Similarly, the HGM approach is a common technique for rapidly assessing wetland function. The HGM methodology for model development is thoroughly documented (Brinson 1993, Smith et al. 1995), and models are available for 30+ wetland types nationwide (https://wetlands.el.erdc.dren.mil/guidebooks.cfm).
  • Literature-Based Index Models: Index models also appear within the peer-reviewed and grey literature in a variety of formats. Some of the original HSI models have been subsequently adapted to local conditions or updated as new data became available (e.g., the bluegill model by Stuber et al. 1982 was adapted by Palesh and Anderson 1990). Models also appear in the peer-reviewed literature as new data become available, such as a recent revision to oyster suitability models which expands the breadth of applicability (Swannack et al. 2014).
  • Project- or Objective-Centric Index Models: Specific restoration projects may build models unique to a set of project objectives (McKay et al. 2019), which can evolve as a project proceeds from preliminary screening to detailed alternatives analysis (e.g., McKay et al. 2018ab). More recently, Carrillo et al. (2020) proposed a Toolkit for interActive Modeling (TAM), which facilitates development of index models in real-time for mediated modeling workshop settings (Herman et al. 2019).

2.2. Cost-Effectiveness and Incremental Cost Analysis (CEICA)

The USACE ecosystem restoration mission was first authorized in the Water Resources Development Act of 1986 with the stated purpose “…to restore significant structure, function and dynamic processes that have been degraded” (USACE 1999, ER 1165-2-501). Given this goal, USACE programs emphasize ecological outcomes (as opposed to social or economic outcomes). Generally, ecological resources may be quantified in a variety of ways ranging from habitat suitability for a focal taxon (e.g., an endangered species) to changes in physical processes (e.g., sediment delivery from geomorphic change) to changes in biological processes (e.g., carbon uptake and storage). In other USACE business lines (e.g., navigation), costs and benefits of actions are compared in monetary terms, and the benefit-cost ratio serves as a crucial decision metric. However, outputs of restoration are typically not monetized, and a different set of methods are required to inform restoration decision-making and address the issue of “Is ecosystem restoration worth the Federal investment?” In particular, cost-effectiveness and incremental cost analyses provide techniques for comparing non-monetary ecological benefits relative to monetary costs of restoration actions (Robinson et al. 1995).

Cost-effectiveness and incremental cost analyses (CEICA) are analytical tools for assessing the relative benefits and costs of ecosystem restoration actions and informing decisions. Benefits and costs are assessed prior to these analyses using ecological models (e.g., index models) and cost engineering methods, respectively. CEICA may then be conducted at the site scale to compare alternatives at a single location (e.g., no action vs. dam removal vs. fish ladder) or at the system scale to compare relative merits of multiple sites (e.g., no sites vs. Site-A only vs. Site-B only vs. Site-A and Site-B). Within the USACE, the Institute of Water Resources has provided a toolkit for conducting CEICA, the IWR Planning Suite (http://www.iwr.usace.army.mil/Missions/Economics/IWR-Planning-Suite/).

Cost-effectiveness analysis provides a mechanism for examining the efficiency of alternative actions. For any given level of investment, the agency wants to identify the plan with the highest return-on-investment (i.e., the most environmental benefits), and for any given level of environmental benefits, the agency wants a plan with the lowest cost. An “efficiency frontier” identifies all plans that efficiently provide benefits on a per cost basis (i.e., cost-effective plans). These “non-dominated” alternatives compose the Pareto-optimal frontier.

Incremental cost analysis is conducted on the set of cost-effective plans. This technique sequentially compares each plan to all higher cost plans to reveal changes in unit cost as output levels increase and eliminates plans that do not efficiently provide benefits on a per unit cost basis. Specifically, this analysis examines the slope of the cost-effectiveness frontier to isolate how the incremental unit cost ($/unit) increases as the magnitude of environmental benefit increases. Incremental cost analysis is ultimately intended to inform decision-makers about the consequences of increasing unit cost when increasing benefits (i.e., each unit becomes more expensive). Plans emerging from incremental cost analysis efficiently accomplish the objective relative to unit costs and are typically referred to as “best buys.” Importantly, all “best buys” are cost-effective, but all cost-effective plans are not best buys.

2.3. ecorest Model Workflow

Conceptual models provide a useful mechanism for many aspects of ecosystem restoration projects such as increasing understanding about a subject, identifying restoration alternatives, and facilitating dialog among team members (Fischenich 2008, USACE 2011). However, conceptual models also inform the development of quantitative ecological models and can document the general workflow of models (Grant and Swannack 2008, Swannack et al. 2012). Here, a conceptual model is presented to describe the general workflow of the ecorest computational platform. A stepwise conceptual model development process (Fischenich 2008) was used to develop the model workflow (Table 1), and Figure 1 summarizes the general flow of logic guiding the development of ecorest.

Figure 1. Conceptual workflow of the ecorest index and decision support modeling toolkit.
Figure 1. Conceptual workflow of the ecorest index and decision support modeling toolkit.

3. Quantification

In the quantification step, the conceptual ecological model is converted into explicit equations, parameter definitions, and a numerical procedure for computation (Grant and Swannack 2008). This section describes the theoretical basis for ecorest, the approach used to compile the toolkit and the associated functions.

ecorest contains three categories of datasets and analytical functions designed to support ecosystem restoration decision-making, with an emphasis on U.S. Army Corps of Engineers applications. First, a common data structure was developed for index models, data were compiled for existing habitat suitability index (HSI) models, and a Toolkit for interActive Modeling (TAM) was developed to facilitate development of new index models (Carrillo et al. 2019). Second, an engine was developed for computing index models with functions for both generic model evaluation outputs (e.g., suitability curve visualization and sensitivity analysis) and application-specific outputs (e.g., forecasts of with and without project conditions). Third, a series of functions were developed to conduct cost-effectiveness and incremental cost analyses (CEICA), which can be applied to index model outputs or any other trade-off between benefits and costs. These three topics are synthesized into a R-package (McKay, Hernandez-Abrams, and Cushway 2026) and will be the focus of this report.

R is a free, open-source language and software environment for statistical computing and graphics maintained by the R Core Team and supported by the R Foundation (R Core Team, 2024). R supports reproducible, script-based workflows and is extended through “packages,” which bundle functions, documentation, and (when applicable) datasets into a standardized structure that can be installed and executed consistently across operating systems.

The ecorest package page is distributed through the Comprehensive R Archive Network (CRAN), the primary public repository for R packages. CRAN maintains repository policies and uses automated checks (including installation and “R CMD check” style testing) to evaluate package structure, documentation, dependencies, and runnable examples across platforms. Packages are routinely re-checked over time as R and dependencies change, and maintainers may be required to address issues to remain compliant, while non-compliant packages may be archived. See the ecorest package page for details.

3.1. USFWS Habitat Suitability Model Data

The ecorest package includes a compiled library of USFWS HSI models implemented in a standardized digital format to improve accessibility, reduce transcription error, and support repeatable computations. The data structures presented in Section 3.1 store the curve breakpoints and coding conventions needed to reconstruct published suitability relationships, while model metadata document model details (e.g., geographic range, scientific name), intended application context, and citation information. Together, these datasets provide the inputs required for the index model calculations described in Section 3.2.

HSI$modelname

HSImodels$modelname is a list of data frames that contains 349 U.S. Fish and Wildlife Service Habitat suitability index (HSI) models approved for USACE use by the Ecosystem Planning Center of Expertise (ECO-PCX). Each data frame contains independent variables and associated habitat suitability indices (ranging from zero to one). Data represent known breakpoints in curves, and linear extrapolation is used to define values between breakpoints. Categorical input variables are coded as letters. A comprehensive list of all models is included in Appendix B. Variable names often required abbreviation, and all nomenclature is also summarized in Appendix B. Table 2 provides an example of one such HSI model designed for the Barred Owl (Strix varia) (Allen 1987). All models can be called with their corresponding model name using HSImodels$modelname (e.g., HSImodels$barredowl).

Table 2. Example of USFWS Habitat Suitability Model Data for the Barred Owl (Strix varia) (Allen 1987).
num.trees.mtoe51cm.dbh.0.4ha num.trees.mtoe51cm.dbh.0.4ha.SIV avg.dbh.overstory.trees.cm avg.dbh.overstory.trees.SIV can.cov.overstory.trees.pct can.cov.overstory.trees.SIV
0 0.1 0 0 0 0
2 1.0 13 0 20 0
4 1.0 51 1 60 1
NA NA NA NA 100 1

HSImetadata

HSImetadata is a data frame that contains metadata for 349 U.S. Fish and Wildlife Service Habitat suitability index (HSI) models, such as model names, references, input parameters, and model equations. Table 3 provides a full list of all fields contained within HSImetadata along with an example for the Barred Owl model (Allen 1987).

Table 3. Example of model information embedded within HSImetadata(): Barred Owl (Allen 1987).
Description HSImetadata Field Barred Owl Model Value
Model name model barredowl
Model specifications submodel NA
Scientific nomenclature of modeled taxa species Strix varia
Geographic range of organism geography NA
Type of habitat ecosystem Floodplain, Fresh Wetland
Citation of original model documentation Allen, AW. 1987. Habitat suitability index models: barred owl. U.S. Fish Wild. Serv. Biol. Rep. 82(10.143). 17 pp.
Conditions under which model may be applied note NA
Link to original individual model source website https://ecolibrary.sec.usace.army.mil/resource/8f4b3c1b-00c6-421b-d9cb-d50ee1066cab
Suitability index values for each organism-specific condition SIV1 num.trees.mtoe51cm.dbh.0.4ha.SIV
Suitability index values for each organism-specific condition SIV1B NA
Suitability index values for each organism-specific condition SIV2 avg.dbh.overstory.trees.SIV
Suitability index values for each organism-specific condition SIV2B NA
Suitability index values for each organism-specific condition SIV3 can.cov.overstory.trees.SIV
Suitability index values for each organism-specific condition SIV3B NA
Suitability index values for each organism-specific condition SIV4 NA
Suitability index values for each organism-specific condition SIV4B NA
Suitability index values for each organism-specific condition SIV5 NA
Suitability index values for each organism-specific condition SIV5B NA
Suitability index values for each organism-specific condition SIV6 NA
Suitability index values for each organism-specific condition SIV6B NA
Suitability index values for each organism-specific condition SIV7 NA
Suitability index values for each organism-specific condition SIV7B NA
Suitability index values for each organism-specific condition SIV8 NA
Suitability index values for each organism-specific condition SIV8B NA
Suitability index values for each organism-specific condition SIV9 NA
Suitability index values for each organism-specific condition SIV10 NA
Suitability index values for each organism-specific condition SIV11 NA
Suitability index values for each organism-specific condition SIV12 NA
Suitability index values for each organism-specific condition SIV13 NA
Suitability index values for each organism-specific condition SIV14 NA
Suitability index values for each organism-specific condition SIV15 NA
Suitability index values for each organism-specific condition SIV15B NA
Suitability index values for each organism-specific condition SIV16 NA
Suitability index values for each organism-specific condition SIV16B NA
Suitability index values for each organism-specific condition SIV17 NA
Suitability index values for each organism-specific condition SIV18 NA
Suitability index values for each organism-specific condition SIV19 NA
Suitability index values for each organism-specific condition SIV20 NA
Suitability index values for each organism-specific condition SIV21 NA
Suitability index values for each organism-specific condition SIV22 NA
Food component equation CF NA
Food/reproduction component equation CRF NA
Roosting-nesting component equation CRN NA
Cover component equation CC NA
Cover-roosting component equation CCRO NA
Cover-reproduction-food component equation CCRF NA
Cover-food component equation CCF NA
Cover-food shrub component equation CCSF NA
Cover-food herbaceous component equation CCHF NA
Winter food component equation CWF NA
Summer food component equation CSF NA
Fall food component equation CFF NA
Water component equation CW NA
Cover-breeding component equation CCB NA
Brood component equation CB NA
Nest component equation CN NA
Nest-brood-cover component equation CNBC NA
Cover nesting component equation CCN NA
Pair habitat component equation CP NA
Water quality component equation CWQ NA
Reproduction component equation CR ((SIV1*SIV2)^(1/2))*SIV3
Cover reproduction component equation CCR NA
Disturbance component equation CD NA
Other component equation COT NA
Larval component equation CL NA
Embryo and larval component equation CEL NA
Embryo component equation CE NA
Juvenile component equation CJ NA
Fry component equation CFr NA
Spawning component equation CS NA
Adult component equation CA NA
Island component equation CI NA
Interspersion component equation CIN NA
Non-island component equation CNI NA
Winter cover food component equation CWFC NA
Summer food brood component equation CFBS NA
Fall spring winter food component equation CFSWF NA
Spring food component equation CSPF NA
Winter cover component equation CWC NA
Fall to spring cover component equation CCFS NA
Substrate-suspended solids component equation CSS NA
Topography component equation CT NA
Temperature component equation CTe NA
Juvenile adult component equation CJA NA
Composite HSI model equation in R syntax Eqtn CR

3.2. Index Model Computational Engine

The index model computational engine in ecorest is implemented as a modular workflow that separates (1) representation and visualization of suitability relationships, (2) calculation of suitability indices from project inputs from USFWS models (Section 3.1) or user-specified models, (3) calculation of suitability indices into an overall HSI score using documented combination rules, and (4) conversion of HSI to habitat units using habitat quantity and HSI scores. This modular structure promotes computational transparency, supports verification against known outcomes, and allows functions to be used independently when only part of the workflow is needed.

HSIplotter

The HSIplotter function plots suitability index curves relative to HSI model input parameters.

Inputs include:

  • SI: a matrix or data frame of suitability curves ordered as parameter breakpoints and associated suitability indices for each parameter with appropriate column names.
  • figure.name: output figure file name structured as “filename.jpeg”.

The HSIplotter function returns a multi-panel *.jpeg figure showing all suitability curves included in a model (e.g., Figure 2).

HSIplotter
## function (SI, figure.name) 
## {
##     warning("U.S. Army Corps of Engineers users must have approval from the National Ecosystem \n  Planning Center of Expertise (Eco-PCX) prior to application of a new model.")
##     oldpar <- par("mfrow", "mgp", "mar")
##     on.exit(par(oldpar))
##     nSI <- length(colnames(SI))/2
##     if (any(unlist(lapply(SI, function(x) {
##         if (is.numeric(x)) is.infinite(x) else FALSE
##     })))) {
##         stop("Suitability Index values cannot be infinite", call. = FALSE)
##     }
##     even_cols <- seq(2, ncol(SI), by = 2)
##     if (any(SI[, even_cols] < 0 | SI[, even_cols] > 1, na.rm = TRUE)) {
##         stop("Suitability Index values must be between 0 and 1.", 
##             call. = FALSE)
##     }
##     SI.cont <- c()
##     for (i in 1:nSI) {
##         SI.cont[i] <- is.numeric(SI[1, 2 * i - 1])
##     }
##     jpeg(filename = figure.name, units = "in", width = 12, height = 4 * 
##         ceiling(nSI/3), res = 400)
##     par(mfrow = c(ceiling(nSI/3), 3), mgp = c(2, 0.5, 0), mar = c(3.5, 
##         3.5, 3, 1))
##     for (i in 1:nSI) {
##         if (SI.cont[i] == TRUE) {
##             plot(SI[, 2 * i - 1], SI[, 2 * i], pch = 19, col = "black", 
##                 xlab = colnames(SI)[2 * i - 1], ylab = "Suitability Index", 
##                 ylim = c(0, 1))
##             lines(SI[, 2 * i - 1], SI[, 2 * i], lwd = 2, col = "black")
##             box()
##         }
##         else {
##             barplot(SI[, 2 * i], names.arg = SI[, 2 * i - 1], 
##                 col = "black", xlab = colnames(SI)[2 * i - 1], 
##                 ylab = "Suitability Index", ylim = c(0, 1))
##             box()
##         }
##     }
##     invisible(dev.off())
## }
## <bytecode: 0x0000018f13a18660>
## <environment: namespace:ecorest>
HSIplotter(HSImodels$barredowl, "Fig02.BarredOwl.jpeg")
Figure 2. Example output from HSIplotter() for the Barred Owl HSI model (Allen 1987).
Figure 2. Example output from HSIplotter() for the Barred Owl HSI model (Allen 1987).

SIcalc(SI, input.proj)

The SIcalc function computes suitability indices given a set of suitability curves and project-specific inputs. Suitability indices may be computed based on either linear interpolation (for continuous variables) or a look-up method (for categorical variables).

Inputs include:

  • SI: a matrix or data frame of suitability curves ordered as parameter breakpoints and associated suitability indices for each parameter with appropriate column names.
  • input.proj: a numeric or categorical vector of application-specific input parameters associated with the suitability curve data from SI. Excluded variables should be entered as ‘NA.’

The SIcalc function returns a named vector of suitability index values between zero and one corresponding to the given user inputs.

SIcalc
## function (SI, input.proj) 
## {
##     input.proj <- unlist(input.proj, use.names = FALSE)
##     warning("U.S. Army Corps of Engineers users must have approval from the National Ecosystem Planning Center of Expertise (Eco-PCX) prior to application of a new model.", 
##         call. = FALSE)
##     nSI <- ncol(SI)/2
##     if (length(input.proj) != nSI) {
##         stop("Number of inputs does not equal number of SI values.", 
##             call. = FALSE)
##     }
##     even_cols <- seq(2, ncol(SI), by = 2)
##     if (any(SI[, even_cols] < 0 | SI[, even_cols] > 1, na.rm = TRUE)) {
##         stop("Suitability index values in SI must be between 0 and 1.", 
##             call. = FALSE)
##     }
##     if (any(is.infinite(suppressWarnings(as.numeric(input.proj))), 
##         na.rm = TRUE) || any(as.character(input.proj) %in% c("Inf", 
##         "-Inf"), na.rm = TRUE)) {
##         stop("input.proj contains infinite values (Inf or -Inf), which are not allowed.", 
##             call. = FALSE)
##     }
##     SI.out <- rep(NA_real_, nSI)
##     capped_any <- FALSE
##     for (i in 1:nSI) {
##         xcol <- SI[, 2 * i - 1]
##         ycol <- SI[, 2 * i]
##         x <- input.proj[i]
##         if (all(is.na(xcol)) && all(is.na(ycol))) {
##             SI.out[i] <- NA
##             next
##         }
##         if (is.na(x) || identical(as.character(x), "NA")) {
##             SI.out[i] <- NA
##             next
##         }
##         xcol_num <- suppressWarnings(as.numeric(as.character(xcol)))
##         ycol_num <- suppressWarnings(as.numeric(as.character(ycol)))
##         x_num <- suppressWarnings(as.numeric(as.character(x)))
##         is_cont <- any(!is.na(xcol_num))
##         if (is_cont) {
##             keep <- !is.na(xcol_num) & !is.na(ycol_num)
##             min_x <- min(xcol_num[keep], na.rm = TRUE)
##             max_x <- max(xcol_num[keep], na.rm = TRUE)
##             if (is.na(x_num)) {
##                 stop(paste0("Input for variable ", i, " must be numeric for a continuous suitability curve."), 
##                   call. = FALSE)
##             }
##             if (x_num < min_x || x_num > max_x) {
##                 capped_any <- TRUE
##             }
##             SI.out[i] <- approx(x = xcol_num[keep], y = ycol_num[keep], 
##                 xout = x_num, method = "linear", rule = 2, ties = "ordered")$y
##         }
##         else {
##             allowed <- unique(as.character(xcol))
##             allowed <- allowed[!is.na(allowed)]
##             if (!(as.character(x) %in% allowed)) {
##                 stop("Values in input.proj must fall within the ranges provided in SI.", 
##                   call. = FALSE)
##             }
##             idx <- which(as.character(xcol) == as.character(x))
##             if (length(idx) == 0) {
##                 stop(paste0("No categorical match found for variable ", 
##                   i, " with input value: ", as.character(x)), 
##                   call. = FALSE)
##             }
##             SI.out[i] <- suppressWarnings(as.numeric(as.character(ycol[idx[1]])))
##         }
##     }
##     names(SI.out) <- paste0("SIV", seq_len(nSI))
##     if (capped_any) {
##         warning("Numeric values outside the suitability curve range were capped at the nearest minimum or maximum breakpoint.", 
##             call. = FALSE)
##     }
##     return(SI.out)
## }
## <bytecode: 0x0000018f13eacf20>
## <environment: namespace:ecorest>

HSIarimean(x)

The HSIarimean function uses an arithmetic mean equation to combine suitability indices into an overarching habitat suitability index.

Inputs include:

  • x: a vector, matrix, or data frame of suitability indices ranging from zero to one.

The HSIarimean function returns a value of habitat quality between zero and one (ignoring NA values). Note that new models developed using the HSIarimean function must undergo certification by ECO-PCX prior to USACE use.

HSIarimean
## function (x) 
## {
##     warning("U.S. Army Corps of Engineers users must have approval from the National Ecosystem \n  Planning Center of Expertise (Eco-PCX) prior to application of a new model.")
##     x = unlist(x)
##     if (any(is.infinite(x) | !is.numeric(x))) {
##         stop("Non-NA inputs must be finite numeric values.")
##     }
##     if (any(x < 0 | x > 1, na.rm = TRUE)) {
##         stop("Suitability indices must be between 0 and 1.", 
##             call. = FALSE)
##     }
##     HSI <- mean(x, na.rm = TRUE)
##     if (HSI < 0 | HSI > 1) {
##         stop("Habitat suitability index is not numeric or is not within 0 to 1 range.", 
##             call. = FALSE)
##     }
##     else {
##         HSIout <- HSI
##     }
##     return(HSIout)
## }
## <bytecode: 0x0000018f1429f620>
## <environment: namespace:ecorest>

HSIwarimean(x, w)

The HSIwarimean function uses a weighted arithmetic mean equation to combine suitability indices into an overarching habitat suitability index.

Inputs include:

  • x: a vector, matrix, or data frame of suitability indices ranging from zero to one.
  • w: a vector, matrix, or data frame of weights ranging from zero to one (must sum to one).

The HSIwarimean function returns a value of habitat quality between zero and one (ignoring NA values). Note that new models developed using the HSIwarimean function must undergo certification by ECO-PCX prior to USACE use.

HSIwarimean
## function (x, w) 
## {
##     warning("U.S. Army Corps of Engineers users must have approval from the National Ecosystem \n  Planning Center of Expertise (Eco-PCX) prior to application of a new model\n  or weighting system.")
##     x = unlist(x)
##     w = unlist(w)
##     if (sum(!is.na(x)) != sum(!is.na(w))) {
##         stop("Number of non-NA weights does not equal number of non-NA suitability indices.", 
##             call. = FALSE)
##     }
##     if (any(is.infinite(x) | !is.numeric(x) | is.infinite(w) | 
##         !is.numeric(w))) {
##         stop("Non-NA inputs must be finite numeric values.")
##     }
##     if (any(x < 0 | x > 1, na.rm = TRUE)) {
##         stop("Suitability indices must be between 0 and 1.", 
##             call. = FALSE)
##     }
##     if (any(w < 0, na.rm = TRUE)) {
##         stop("Weights cannot be negative.", call. = FALSE)
##     }
##     if (abs(sum(w, na.rm = T) - 1) > 1e-08) {
##         stop("The sum of non-NA weights must equal 1.", call. = FALSE)
##     }
##     wmean <- sum(x * w, na.rm = TRUE)
##     if (wmean < 0 | wmean > 1) {
##         stop("Habitat suitability index is not numeric or is not within 0 to 1 range.", 
##             call. = FALSE)
##     }
##     return(wmean)
## }
## <bytecode: 0x0000018f1459dea8>
## <environment: namespace:ecorest>

HSIgeomean(x)

The HSIgeomean function uses a geometric mean equation to combine suitability indices into an overarching habitat suitability index.

Inputs include:

  • x: a vector, matrix, or data frame of suitability indices ranging from zero to one.

The HSIgeomean function returns a value of habitat quality between zero and one (ignoring NA values). Note that new models developed using the HSIgeomean function must undergo certification by ECO-PCX prior to USACE use.

HSIgeomean
## function (x) 
## {
##     warning("U.S. Army Corps of Engineers users must have approval from the National Ecosystem \n  Planning Center of Expertise (Eco-PCX) prior to application of a new model.")
##     x = unlist(x)
##     if (any(is.infinite(x) | !is.numeric(x))) {
##         stop("Non-NA inputs must be finite numeric values.")
##     }
##     if (any(x < 0 | x > 1, na.rm = TRUE)) {
##         stop("Suitability indices must be between 0 and 1.", 
##             call. = FALSE)
##     }
##     HSI <- prod(x, na.rm = TRUE)^(1/length(which(is.na(x) != 
##         TRUE)))
##     if (HSI < 0 | HSI > 1) {
##         stop("Habitat suitability index is not numeric or is not within 0 to 1 range.", 
##             call. = FALSE)
##     }
##     else {
##         HSIout <- HSI
##     }
##     return(HSIout)
## }
## <bytecode: 0x0000018f148a7bd0>
## <environment: namespace:ecorest>

HSImin(x)

The HSImin function calculates the minimum of a given set of suitability indices to determine an overarching habitat suitability index.

Inputs include:

  • x: a vector, matrix, or data frame of suitability indices ranging from zero to one.

The HSImin function returns a value of habitat quality between zero and one (ignoring NA values). Note that new models developed using the HSImin function must undergo certification by ECO-PCX prior to USACE use.

HSImin
## function (x) 
## {
##     warning("U.S. Army Corps of Engineers users must have approval from the National Ecosystem \n  Planning Center of Expertise (Eco-PCX) prior to application of a new model.")
##     x = unlist(x)
##     if (any(is.infinite(x) | !is.numeric(x))) {
##         stop("Non-NA inputs must be finite numeric values.")
##     }
##     if (any(x < 0 | x > 1, na.rm = TRUE)) {
##         stop("Suitability indices must be between 0 and 1.", 
##             call. = FALSE)
##     }
##     HSI <- min(x, na.rm = TRUE)
##     if (HSI < 0 | HSI > 1) {
##         stop("Habitat suitability index is not numeric or is not within 0 to 1 range.", 
##             call. = FALSE)
##     }
##     else {
##         HSIout <- HSI
##     }
##     return(HSIout)
## }
## <bytecode: 0x0000018f1a22d2a0>
## <environment: namespace:ecorest>

HSIeqtn(HSImodelname, SIV, HSImetadata, exclude)

The HSIeqtn function computes a habitat suitability index based on equations specified in USFWS habitat suitability models contained within ecorest via HSImodels and HSImetadata. Habitat suitability indices represent an overall assessment of habitat quality from combining individual suitability indices for multiple independent variables. The function computes an overall habitat suitability index. This function only applies to built-in index models described in Section 3.1.

Inputs include:

  • HSImodelname: a character string in quotations that must match an existing model name in HSImetadata.
  • SIV: a named vector, matrix, or data frame of suitability index values ranging from zero to one used in the model specified in HSImodelname. Names must correspond exactly with SIV names (e.g., “SIV1”, “SIV1B”, “SIV2”, etc.)
  • HSImetadata: a data frame of HSI model metadata stored in the ecorest package.
  • exclude: a vector of character strings specifying components to be excluded from calculations. See HSImetadata for a list of available model components. Non-NULL ‘exclude’ inputs are only applicable to models that explicitly provide instructions for use in the note column of HSImetadata.

The HSIeqtn function returns a numeric estimate of habitat quality between zero and one. Predefined USFWS models contained in ecorest are certified for USACE use by ECO-PCX.

HSIeqtn
## function (HSImodelname, SIV, HSImetadata, exclude = NULL) 
## {
##     SIV <- unlist(SIV, use.names = TRUE)
##     model.loc <- which(HSImetadata$model == HSImodelname)
##     if (length(model.loc) == 0) {
##         stop("HSImodelname was not found in HSImetadata.", call. = FALSE)
##     }
##     if (is.null(names(SIV))) {
##         stop("SIV must be a named vector, matrix, or data frame (e.g., c('SIV1' = 1, 'SIV2' = 1, 'SIV3' = 1))")
##     }
##     SIV.name.gen <- names(which(colSums(!is.na(HSImetadata[model.loc, 
##         9:40])) > 0))
##     if (!identical(names(SIV), SIV.name.gen)) {
##         removed = names(SIV)[!(names(SIV) %in% SIV.name.gen)]
##         SIV = SIV[SIV.name.gen]
##         warning(paste0("The following variables were removed from the HSI calculation: ", 
##             paste(removed, collapse = ", ")), call. = FALSE)
##     }
##     SIV.num <- suppressWarnings(as.numeric(SIV))
##     if (any(is.na(SIV.num) & !is.na(SIV))) {
##         stop("Non-NA SIV inputs must be numeric values.", call. = FALSE)
##     }
##     if (any(is.infinite(SIV.num[!is.na(SIV.num)]))) {
##         stop("Non-NA SIV inputs must be finite numeric values.", 
##             call. = FALSE)
##     }
##     SIV <- SIV.num
##     if (any(SIV < 0 | SIV > 1, na.rm = TRUE)) {
##         stop("Suitability index values (SIVs) must be between 0 and 1.", 
##             call. = FALSE)
##     }
##     var.name <- c(SIV.name.gen, "CF", "CRF", "CRN", "CC", "CCRO", 
##         "CCRF", "CCF", "CCSF", "CCHF", "CWF", "CSF", "CFF", "CW", 
##         "CCB", "CB", "CN", "CNBC", "CCN", "CP", "CWQ", "CR", 
##         "CCR", "CD", "COT", "CL", "CEL", "CE", "CJ", "CFr", "CS", 
##         "CA", "CI", "CIN", "CNI", "CWFC", "CFBS", "CFSWF", "CSPF", 
##         "CWC", "CCFS", "CSS", "CT", "CTe", "CJA", "Eqtn")
##     HSI <- vector("list", length = length(var.name))
##     names(HSI) <- var.name
##     HSI$CF <- parse(text = paste(HSImetadata$CF[model.loc]))
##     HSI$CRF <- parse(text = paste(HSImetadata$CRF[model.loc]))
##     HSI$CRN <- parse(text = paste(HSImetadata$CRN[model.loc]))
##     HSI$CC <- parse(text = paste(HSImetadata$CC[model.loc]))
##     HSI$CCRO <- parse(text = paste(HSImetadata$CCRO[model.loc]))
##     HSI$CCRF <- parse(text = paste(HSImetadata$CCRF[model.loc]))
##     HSI$CCF <- parse(text = paste(HSImetadata$CCF[model.loc]))
##     HSI$CCSF <- parse(text = paste(HSImetadata$CCSF[model.loc]))
##     HSI$CCHF <- parse(text = paste(HSImetadata$CCHF[model.loc]))
##     HSI$CWF <- parse(text = paste(HSImetadata$CWF[model.loc]))
##     HSI$CSF <- parse(text = paste(HSImetadata$CSF[model.loc]))
##     HSI$CFF <- parse(text = paste(HSImetadata$CFF[model.loc]))
##     HSI$CW <- parse(text = paste(HSImetadata$CW[model.loc]))
##     HSI$CCB <- parse(text = paste(HSImetadata$CCB[model.loc]))
##     HSI$CB <- parse(text = paste(HSImetadata$CB[model.loc]))
##     HSI$CN <- parse(text = paste(HSImetadata$CN[model.loc]))
##     HSI$CNBC <- parse(text = paste(HSImetadata$CNBC[model.loc]))
##     HSI$CCN <- parse(text = paste(HSImetadata$CCN[model.loc]))
##     HSI$CP <- parse(text = paste(HSImetadata$CP[model.loc]))
##     HSI$CWQ <- parse(text = paste(HSImetadata$CWQ[model.loc]))
##     HSI$CR <- parse(text = paste(HSImetadata$CR[model.loc]))
##     HSI$CCR <- parse(text = paste(HSImetadata$CCR[model.loc]))
##     HSI$CD <- parse(text = paste(HSImetadata$CD[model.loc]))
##     HSI$COT <- parse(text = paste(HSImetadata$COT[model.loc]))
##     HSI$CL <- parse(text = paste(HSImetadata$CL[model.loc]))
##     HSI$CEL <- parse(text = paste(HSImetadata$CEL[model.loc]))
##     HSI$CE <- parse(text = paste(HSImetadata$CE[model.loc]))
##     HSI$CJ <- parse(text = paste(HSImetadata$CJ[model.loc]))
##     HSI$CFr <- parse(text = paste(HSImetadata$CFr[model.loc]))
##     HSI$CS <- parse(text = paste(HSImetadata$CS[model.loc]))
##     HSI$CA <- parse(text = paste(HSImetadata$CA[model.loc]))
##     HSI$CI <- parse(text = paste(HSImetadata$CI[model.loc]))
##     HSI$CIN <- parse(text = paste(HSImetadata$CIN[model.loc]))
##     HSI$CNI <- parse(text = paste(HSImetadata$CNI[model.loc]))
##     HSI$CWFC <- parse(text = paste(HSImetadata$CWFC[model.loc]))
##     HSI$CFBS <- parse(text = paste(HSImetadata$CFBS[model.loc]))
##     HSI$CFSWF <- parse(text = paste(HSImetadata$CFSWF[model.loc]))
##     HSI$CSPF <- parse(text = paste(HSImetadata$CSPF[model.loc]))
##     HSI$CWC <- parse(text = paste(HSImetadata$CWC[model.loc]))
##     HSI$CCFS <- parse(text = paste(HSImetadata$CCFS[model.loc]))
##     HSI$CSS <- parse(text = paste(HSImetadata$CSS[model.loc]))
##     HSI$CT <- parse(text = paste(HSImetadata$CT[model.loc]))
##     HSI$CTe <- parse(text = paste(HSImetadata$CTe[model.loc]))
##     HSI$CJA <- parse(text = paste(HSImetadata$CJA[model.loc]))
##     HSI$Eqtn <- parse(text = paste(HSImetadata$Eqtn[model.loc]))
##     if (is.null(exclude) == FALSE) {
##         for (c in 1:length(exclude)) {
##             HSI[[which(names(HSI) == exclude[c])]] <- parse(text = paste(NA))
##         }
##     }
##     HSI[SIV.name.gen] <- as.list(SIV)
##     HSI.out <- HSI
##     j <- length(SIV.name.gen)
##     HSI.out[[j + 1]] <- with(HSI, eval(HSI$CF))
##     HSI.out[[j + 2]] <- with(HSI, eval(HSI$CRF))
##     HSI.out[[j + 3]] <- with(HSI, eval(HSI$CRN))
##     HSI.out[[j + 4]] <- with(HSI, eval(HSI$CC))
##     HSI.out[[j + 5]] <- with(HSI, eval(HSI$CCRO))
##     HSI.out[[j + 6]] <- with(HSI, eval(HSI$CCRF))
##     HSI.out[[j + 7]] <- with(HSI, eval(HSI$CCF))
##     HSI.out[[j + 8]] <- with(HSI, eval(HSI$CCSF))
##     HSI.out[[j + 9]] <- with(HSI, eval(HSI$CCHF))
##     HSI.out[[j + 10]] <- with(HSI, eval(HSI$CWF))
##     HSI.out[[j + 11]] <- with(HSI, eval(HSI$CSF))
##     HSI.out[[j + 12]] <- with(HSI, eval(HSI$CFF))
##     HSI.out[[j + 13]] <- with(HSI, eval(HSI$CW))
##     HSI.out[[j + 14]] <- with(HSI, eval(HSI$CCB))
##     HSI.out[[j + 15]] <- with(HSI, eval(HSI$CB))
##     HSI.out[[j + 16]] <- with(HSI, eval(HSI$CN))
##     HSI.out[[j + 17]] <- with(HSI, eval(HSI$CNBC))
##     HSI.out[[j + 18]] <- with(HSI, eval(HSI$CCN))
##     HSI.out[[j + 19]] <- with(HSI, eval(HSI$CP))
##     HSI.out[[j + 20]] <- with(HSI, eval(HSI$CWQ))
##     HSI.out[[j + 21]] <- with(HSI, eval(HSI$CR))
##     HSI.out[[j + 22]] <- with(HSI, eval(HSI$CCR))
##     HSI.out[[j + 23]] <- with(HSI, eval(HSI$CD))
##     HSI.out[[j + 24]] <- with(HSI, eval(HSI$COT))
##     HSI.out[[j + 25]] <- with(HSI, eval(HSI$CL))
##     HSI.out[[j + 26]] <- with(HSI, eval(HSI$CEL))
##     HSI.out[[j + 27]] <- with(HSI, eval(HSI$CE))
##     HSI.out[[j + 28]] <- with(HSI, eval(HSI$CJ))
##     HSI.out[[j + 29]] <- with(HSI, eval(HSI$CFr))
##     HSI.out[[j + 30]] <- with(HSI, eval(HSI$CS))
##     HSI.out[[j + 31]] <- with(HSI, eval(HSI$CA))
##     HSI.out[[j + 32]] <- with(HSI, eval(HSI$CI))
##     HSI.out[[j + 33]] <- with(HSI, eval(HSI$CIN))
##     HSI.out[[j + 34]] <- with(HSI, eval(HSI$CNI))
##     HSI.out[[j + 35]] <- with(HSI, eval(HSI$CWFC))
##     HSI.out[[j + 36]] <- with(HSI, eval(HSI$CFBS))
##     HSI.out[[j + 37]] <- with(HSI, eval(HSI$CFSWF))
##     HSI.out[[j + 38]] <- with(HSI, eval(HSI$CSPF))
##     HSI.out[[j + 39]] <- with(HSI, eval(HSI$CWC))
##     HSI.out[[j + 40]] <- with(HSI, eval(HSI$CCFS))
##     HSI.out[[j + 41]] <- with(HSI, eval(HSI$CSS))
##     HSI.out[[j + 42]] <- with(HSI, eval(HSI$CT))
##     HSI.out[[j + 43]] <- with(HSI, eval(HSI$CTe))
##     HSI.out[[j + 44]] <- with(HSI, eval(HSI$CJA))
##     HSI.out[[j + 45]] <- with(HSI.out, eval(HSI.out$Eqtn))
##     HSI.out2 <- HSI.out[which(!is.na(HSI.out))]
##     HSI.out3 <- data.frame(HSI.out2)
##     if (length(SIV.name.gen) != length(SIV)) {
##         stop("SIV length does not match expected number of inputs.", 
##             call. = FALSE)
##     }
##     else if (!is.numeric(HSI.out3$Eqtn)) {
##         stop("Invalid HSI score. Please check SIV inputs.", call. = FALSE)
##     }
##     else {
##         HSI.out4 <- HSI.out3$Eqtn
##     }
##     return(HSI.out4)
## }
## <bytecode: 0x0000018f193213f0>
## <environment: namespace:ecorest>

HUcalc(SI.out, habitat.quantity, HSIfunc, …)

The HUcalc function computes habitat units given a set of suitability indices ranging from zero to one, a habitat suitability index equation, and habitat quantity.

Inputs include:

  • SI.out: a vector, matrix, or data frame of application-specific suitability indices between zero and one, which can be produced from SIcalc or other functions.
  • habitat.quantity: a numeric value of habitat size associated with these suitability indices (i.e., length, area, or volume).
  • HSIfunc: a function used to combine suitability indices into a composite habitat suitability index (HSI score) (e.g., ecorest functions like HSIarimean or HSIgeomean or functions outside ecorest like max or mean).
  • ...: optional arguments to HSIfunc.

The HUcalc function returns a vector of habitat quality, habitat quantity, and index units (quantity times quality).

HUcalc
## function (SI.out, habitat.quantity, HSIfunc, ...) 
## {
##     warning("U.S. Army Corps of Engineers users must have approval from the National Ecosystem \n  Planning Center of Expertise (Eco-PCX) prior to application of a new model.")
##     SI.out = unlist(SI.out)
##     habitat.quantity = unlist(habitat.quantity)
##     HU.out <- as.data.frame(matrix(NA, nrow = 1, ncol = 3))
##     colnames(HU.out) <- c("Quality", "Quantity", "IndexUnits")
##     if (any(is.infinite(SI.out) | !is.numeric(SI.out))) {
##         stop("Non-NA inputs must be finite numeric values.")
##     }
##     if (any(SI.out < 0 | SI.out > 1, na.rm = TRUE)) {
##         stop("Suitability indices in SI.out must be between 0 and 1.", 
##             call. = FALSE)
##     }
##     if (habitat.quantity < 0 | !is.numeric(habitat.quantity) | 
##         is.infinite(habitat.quantity)) {
##         stop("Habitat quantity must be a finite positive number.", 
##             call. = FALSE)
##     }
##     HU.out$Quality <- HSIfunc(SI.out, ...)
##     HU.out$Quantity <- habitat.quantity
##     HU.out$IndexUnits <- HU.out$Quality * HU.out$Quantity
##     return(HU.out)
## }
## <bytecode: 0x0000018f17e37e38>
## <environment: namespace:ecorest>

3.3. Decision-Support Engine

This section documents the decision support functions in ecorest used to compare restoration alternatives when benefits are non-monetary and costs are monetary (or otherwise expressed in different units). The functions implement standard cost-effectiveness and incremental cost analysis concepts by (1) converting time-varying outcomes to time-averaged metrics when needed, (2) identifying cost-effective alternatives that form the efficient frontier, (3) evaluating incremental trade-offs along that frontier to identify “best buys,” and (4) producing standardized tabular and graphical summaries for interpretation and reporting.

annualizer(timevec, benefits)

The annualizer function computes time-averaged quantities based on linear interpolation.

Inputs include:

  • timevec: a numeric vector, matrix, or data frame of time intervals.
  • benefits: a numeric vector, matrix, or data frame of ecological output values for a single condition (e.g., future with project) to be interpolated.

The annualizer function returns a time-averaged value over the specified time horizon.

annualizer
## function (timevec, benefits) 
## {
##     timevec = unlist(timevec)
##     benefits = unlist(benefits)
##     if (length(timevec) != length(benefits)) {
##         stop("Number of time points does not equal number of benefit values.", 
##             call. = FALSE)
##     }
##     if (length(timevec) != length(benefits)) {
##         stop("Lengths of `timevec` and `benefits` must match.", 
##             call. = FALSE)
##     }
##     if (any(is.infinite(benefits[!is.na(benefits)]))) {
##         stop("`benefits` must contain only finite numeric values.", 
##             call. = FALSE)
##     }
##     if (any(is.infinite(timevec[!is.na(timevec)]))) {
##         stop("`timevec` must contain only finite numeric values.", 
##             call. = FALSE)
##     }
##     if (any(benefits < 0, na.rm = TRUE)) {
##         stop("`benefits` must be non-negative.", call. = FALSE)
##     }
##     if (any(timevec < 0, na.rm = TRUE)) {
##         stop("`timevec` must be non-negative.", call. = FALSE)
##     }
##     if (!is.numeric(benefits) || !is.numeric(timevec)) {
##         stop("`benefits` and `timevec` must be numeric vectors.", 
##             call. = FALSE)
##     }
##     if (any(duplicated(timevec))) {
##         stop("Duplicate time intervals detected.", call. = FALSE)
##     }
##     if (!identical(timevec, sort(timevec))) {
##         ord <- order(timevec)
##         warning("`timevec` was not in ascending order, so `timevec` and `benefits` were reordered together by time.", 
##             call. = FALSE)
##         timevec <- timevec[ord]
##         benefits <- benefits[ord]
##     }
##     ntime <- length(timevec)
##     time.intervals <- timevec[-1] - timevec[-ntime]
##     area.rec <- time.intervals * apply(cbind(benefits[-ntime], 
##         benefits[-1]), 1, min)
##     area.tri <- 0.5 * time.intervals * abs(benefits[-ntime] - 
##         benefits[-1])
##     benefits.avgann <- sum(area.rec + area.tri)/(max(timevec) - 
##         min(timevec))
##     return(benefits.avgann)
## }
## <bytecode: 0x0000018f1aca39d8>
## <environment: namespace:ecorest>

CEfinder(benefit, cost)

The CEfinder function returns cost-effectiveness analysis for a particular set of alternatives.

Inputs include:

  • benefit: a vector, matrix, or data frame of restoration benefits. Typically, these are time-averaged ecological outcomes (e.g., average annual habitat units). Often, project benefits are best presented as the “lift” associated with a restoration action (i.e., the benefits of an alternative minus the benefits of a “no action” plan).
  • cost: a vector, matrix, or data frame of restoration costs. Typically, these are monetary costs associated with a given restoration action such as project first cost or annualized economic cost. Notably, these functions are agnostic to units, so costs could also be non-monetary such as lost political capital or social costs of each alternative.

The CEfinder function returns a numeric vector identifying each plan as cost-effective (1) or non-cost-effective (0). The cost-effective actions comprise the Pareto frontier of non-dominated alternatives at a given level of cost or benefit.

CEfinder
## function (benefit, cost) 
## {
##     benefit = unlist(benefit)
##     cost = unlist(cost)
##     if (any(is.infinite(benefit))) {
##         stop("`benefit` must contain only finite numeric values.", 
##             call. = FALSE)
##     }
##     if (any(is.infinite(cost))) {
##         stop("`cost` must contain only finite numeric values.", 
##             call. = FALSE)
##     }
##     if (any(benefit < 0, na.rm = TRUE)) {
##         stop("`benefit` must be non-negative.", call. = FALSE)
##     }
##     if (any(cost < 0, na.rm = TRUE)) {
##         stop("`cost` must be non-negative.", call. = FALSE)
##     }
##     if (!is.numeric(benefit) || !is.numeric(cost)) {
##         stop("`benefit` and `cost` must be numeric vectors.", 
##             call. = FALSE)
##     }
##     if (any(is.na(cost)) || any(is.na(benefit))) {
##         stop("`benefit` and `cost` cannot be NA.", call. = FALSE)
##     }
##     if (length(benefit) == length(cost)) {
##         CE <- c()
##         for (i in 1:length(benefit)) {
##             bigben <- which(benefit >= benefit[i])
##             CE[i] <- ifelse(length(which(cost[bigben] <= cost[i])) == 
##                 1, 1, 0)
##         }
##     }
##     else {
##         stop("Number of non-NA benefits does not equal number of non-NA costs.", 
##             call. = FALSE)
##     }
##     return(CE)
## }
## <bytecode: 0x0000018f13112580>
## <environment: namespace:ecorest>

BBfinder(benefit, cost, CE)

The BBfinder function examines the slope of the cost-effectiveness frontier to isolate how unit cost (cost/benefit) increases with increasing environmental benefit. Restoration actions with the lowest slope of unit cost are considered “best buys.”

Inputs include:

  • benefit: a vector, matrix, or data frame of restoration benefits. Typically, these are time-averaged ecological outcomes (e.g., average annual habitat units). Often, project benefits are best presented as the “lift” associated with a restoration action (i.e., the benefits of an alternative minus the benefits of a “no action” plan).
  • cost: a vector, matrix, or data frame of restoration costs. Typically, these are monetary costs associated with a given restoration action such as project first cost or annualized economic cost. Notably, these functions are agnostic to units, so costs could also be non-monetary values such as lost political capital or social costs of each alternative.
  • CE: a numeric vector, matrix, or data frame of zeroes and ones indicating whether a plan is cost-effective (1) or non-cost-effective (0). CE can be derived from CEfinder.

The BBfinder function returns a list with summaries of all restoration actions as well as best buy plans only.

BBfinder
## function (benefit, cost, CE) 
## {
##     benefit = unlist(benefit)
##     cost = unlist(cost)
##     CE = unlist(CE)
##     if (length(benefit) != length(cost) || length(benefit) != 
##         length(CE)) {
##         stop("Lengths of `benefit`, `cost`, and `CE` must match (one value per plan).", 
##             call. = FALSE)
##     }
##     if (any(!is.finite(benefit[!is.na(benefit)]))) {
##         stop("`benefit` must contain only finite numeric values.", 
##             call. = FALSE)
##     }
##     if (any(!is.finite(cost[!is.na(cost)]))) {
##         stop("`cost` must contain only finite numeric values.", 
##             call. = FALSE)
##     }
##     if (any(benefit < 0, na.rm = TRUE)) {
##         stop("`benefit` must be non-negative.", call. = FALSE)
##     }
##     if (any(cost < 0, na.rm = TRUE)) {
##         stop("`cost` must be non-negative.", call. = FALSE)
##     }
##     if (any(!CE %in% c(0, 1), na.rm = TRUE)) {
##         stop("`cost` must be non-negative.", call. = FALSE)
##     }
##     if (!is.numeric(benefit) || !is.numeric(cost) || !is.numeric(CE)) {
##         stop("`benefit`, `cost`, and `CE` must be numeric vectors.", 
##             call. = FALSE)
##     }
##     if (any(is.na(cost)) || any(is.na(benefit)) || any(is.na(CE))) {
##         stop("`benefit`, `cost`, and `CE` cannot be NA.", call. = FALSE)
##     }
##     ben.CE <- benefit[which(CE == 1)]
##     cost.CE <- cost[which(CE == 1)]
##     nCE <- length(ben.CE)
##     if (nCE == 1) {
##         idx <- which(CE == 1)[1]
##         BB.loc <- rep(0, length(benefit))
##         BB.loc[idx] <- 1
##         BB.out <- list()
##         BB.out[[1]] <- cbind(benefit, cost, CE, BB.loc)
##         colnames(BB.out[[1]]) <- c("benefit", "cost", "CE", "BB")
##         BB.out[[2]] <- cbind(benefit[idx], cost[idx], 0)
##         colnames(BB.out[[2]]) <- c("benefit", "cost", "inccost")
##         return(BB.out)
##     }
##     ben.CE2 <- ben.CE[order(cost.CE)]
##     cost.CE2 <- cost.CE[order(cost.CE)]
##     dup_benefit <- duplicated(ben.CE2)
##     dominated_dup <- dup_benefit & (cost.CE2 > ave(cost.CE2, 
##         ben.CE2, FUN = min))
##     if (any(dominated_dup)) {
##         warning("Duplicate benefit values among cost-effective plans with higher costs detected. ", 
##             "Incremental costs are undefined when benefit differences are zero; ", 
##             "retaining the lowest-cost plan for each benefit level.", 
##             call. = FALSE)
##         keep <- !dup_benefit
##         ben.CE2 <- ben.CE2[keep]
##         cost.CE2 <- cost.CE2[keep]
##         nCE <- length(ben.CE2)
##     }
##     if (nCE == 1) {
##         idx <- which(benefit == ben.CE2[1] & cost == cost.CE2[1] & 
##             CE == 1)[1]
##         BB.loc <- rep(0, length(benefit))
##         BB.loc[idx] <- 1
##         BB.out <- list()
##         BB.out[[1]] <- cbind(benefit, cost, CE, BB.loc)
##         colnames(BB.out[[1]]) <- c("benefit", "cost", "CE", "BB")
##         BB.out[[2]] <- cbind(benefit[idx], cost[idx], 0)
##         colnames(BB.out[[2]]) <- c("benefit", "cost", "inccost")
##         return(BB.out)
##     }
##     BB <- c(1)
##     for (i in 1:nCE) {
##         ce.bentemp <- ben.CE2[-1:-BB[i]]
##         ce.costtemp <- cost.CE2[-1:-BB[i]]
##         inccost <- (ce.costtemp - cost.CE2[BB[i]])/(ce.bentemp - 
##             ben.CE2[BB[i]])
##         BB[i + 1] <- which(inccost == min(inccost, na.rm = TRUE))[1] + 
##             BB[i]
##         if (BB[i + 1] >= nCE) {
##             break
##         }
##     }
##     nBB <- length(BB)
##     ben.BB <- ben.CE2[BB]
##     cost.BB <- cost.CE2[BB]
##     inccost.BB <- (cost.BB[-1] - cost.BB[-nBB])/(ben.BB[-1] - 
##         ben.BB[-nBB])
##     BB.find <- c()
##     for (i in 1:nBB) {
##         BB.find[i] <- which(benefit == ben.BB[i] & cost == cost.BB[i])[1]
##     }
##     BB.loc <- rep_len(0, length.out = length(benefit))
##     BB.loc[BB.find] <- 1
##     BB.out <- list()
##     BB.out[[1]] <- cbind(benefit, cost, CE, BB.loc)
##     colnames(BB.out[[1]]) <- c("benefit", "cost", "CE", "BB")
##     BB.out[[2]] <- cbind(ben.BB, cost.BB, c(0, inccost.BB))
##     colnames(BB.out[[2]]) <- c("benefit", "cost", "inccost")
##     return(BB.out)
## }
## <bytecode: 0x0000018f133b6f90>
## <environment: namespace:ecorest>

CEICAplotter(altnames, benefit, cost, CE, BB, figure.name)

The CEICAplotter function plots summary outputs of Cost-effective Incremental Cost Analysis (CEICA) in *.jpeg format.

Inputs include:

  • altnames: a numeric or character vector, matrix, or data frame of unique restoration action identifiers.
  • benefit: a vector, matrix, or data frame of restoration benefits. Typically, these are time-averaged ecological outcomes (e.g., average annual habitat units). Often, project benefits are best presented as the “lift” associated with a restoration action (i.e., the benefits of an alternative minus the benefits of a “no action” plan).
  • cost: a vector, matrix, or data frame of restoration costs. Typically, these are monetary costs associated with a given restoration action such as project first cost or annualized economic cost. Notably, these functions are agnostic to units, so costs could also be non-monetary values such as lost political capital or social costs of each alternative.
  • CE: a numeric vector, matrix, or data frame of zeroes and ones indicating whether a plan is cost-effective (1) or non-cost-effective (0). CE can be derived from CEfinder.
  • BB: a numeric vector, matrix, or data frame of zeroes and ones indicating whether a plan is a best buy (1) or not (0). BB can be derived by isolating select outputs from BBfinder.
  • figure.name: an output figure file name structured as “filename.jpeg”.

The CEICAplotter function returns a multi-panel *.jpeg figure summarizing cost-effectiveness and incremental cost analyses.

CEICAplotter
## function (altnames, benefit, cost, CE, BB, figure.name) 
## {
##     altnames = unlist(altnames)
##     benefit = unlist(benefit)
##     cost = unlist(cost)
##     CE = unlist(CE)
##     BB = unlist(BB)
##     oldpar <- par("mfrow", "mgp", "mar")
##     on.exit(par(oldpar))
##     nalt <- length(altnames)
##     nCE <- sum(CE)
##     nBB <- sum(BB)
##     ben.CE <- benefit[which(CE == 1)]
##     cost.CE <- cost[which(CE == 1)]
##     ben.CE.order <- ben.CE[order(cost.CE)]
##     cost.CE.order <- cost.CE[order(cost.CE)]
##     ben.BB <- benefit[which(BB == 1)]
##     cost.BB <- cost[which(BB == 1)]
##     ben.BB.order <- ben.BB[order(cost.BB)]
##     cost.BB.order <- cost.BB[order(cost.BB)]
##     inccost.BB <- (cost.BB.order[-1] - cost.BB.order[-nBB])/(ben.BB.order[-1] - 
##         ben.BB.order[-nBB])
##     CEICA.col <- viridis(nBB)
##     leg.name <- c()
##     for (i in 1:nBB) {
##         leg.name[i] <- altnames[which(benefit == ben.BB.order[i] & 
##             cost == cost.BB.order[i])]
##     }
##     jpeg(filename = figure.name, units = "in", width = 12, height = 6, 
##         res = 400)
##     par(mfrow = c(1, 2), mgp = c(2, 0.5, 0), mar = c(3.5, 3.5, 
##         3, 1))
##     plot(c(0, 1), c(0, 1), type = "n", xlim = range(benefit), 
##         ylim = range(cost), axes = FALSE, xlab = "Ecological Benefit", 
##         ylab = "Cost", main = "(A) Cost-Effectiveness Analysis")
##     grid()
##     box()
##     axis(1)
##     axis(2, at = axTicks(2), labels = prettyNum(axTicks(2), big.mark = ",", 
##         scientific = FALSE), las = 0, cex.axis = 0.75, tick = TRUE)
##     points(benefit, cost, pch = 1, cex = 0.8, col = "black")
##     lines(ben.CE.order, cost.CE.order, lwd = 2)
##     points(ben.CE.order, cost.CE.order, pch = 19, cex = 1, col = "black")
##     points(ben.BB.order, cost.BB.order, pch = 1, lwd = 3, cex = 3, 
##         col = CEICA.col)
##     legend("topleft", legend = c("All Plans", "Cost-Effective Frontier", 
##         "Best Buys"), lwd = c(NA, 2, NA), pch = c(1, 19, 1), 
##         pt.cex = c(0.8, 1, 3), col = c("black", "black", viridis(1)), 
##         bg = "white")
##     plot(c(0, 1), c(0, 1), type = "n", xlim = range(ben.BB), 
##         ylim = c(0, max(inccost.BB)), axes = FALSE, xlab = "Ecological Benefit", 
##         ylab = "Incremental Cost per Benefit (cost/unit)", main = "(B) Incremental Cost Analysis")
##     box()
##     axis(1)
##     axis(2, at = axTicks(2), labels = prettyNum(axTicks(2), big.mark = ",", 
##         scientific = FALSE), las = 0, cex.axis = 0.75, tick = TRUE)
##     for (i in 1:(nBB - 1)) {
##         xtemp <- c(ben.BB.order[i], ben.BB.order[i + 1], ben.BB.order[i + 
##             1], ben.BB.order[i])
##         ytemp <- c(0, 0, inccost.BB[i], inccost.BB[i])
##         polygon(xtemp, ytemp, col = CEICA.col[i + 1], border = "black")
##     }
##     legend("topleft", legend = leg.name[-1], fill = CEICA.col[-1], 
##         bg = "white")
##     invisible(dev.off())
## }
## <bytecode: 0x0000018f1365b820>
## <environment: namespace:ecorest>

4. Evaluation

Ecological models typically rely on multiple variables or ecological processes, and in many cases present a variety of ecological outcomes. Models can quickly become complex system representations with many components, inputs, assumptions, and modules. Model evaluation is the process for ensuring that numerical tools are scientifically defensible and transparently developed. Evaluation is often referred to as verification or validation, but it in fact includes a family of methods ranging from peer-review to model testing to error checking (Schmolke et al. 2010). In this more general sense, evaluation should include the following (Grant and Swannack 2008): (1) assessing the reasonableness of model structure, (2) assessing functional relationships and verifying code, (3) evaluating model behavior relative to expected patterns, (4) comparing outcomes to empirical data, if possible, and (5) analyzing uncertainty in predictions. The USACE has established an ecological model certification process to ensure that planning models are sound and functional. These generally consist of evaluating tools relative to the three following categories: system quality, technical quality, and usability (EC 1105-2-412).

4.1. System Quality

To confirm proper functionality, the ecorest package was rigorously assessed and peer-reviewed to ensure computational and numerical accuracy. System quality was assessed following best practices from McKay et al. (2022).

4.1.1 Quality Assurance

Workflow planning and consistency: The ecorest package was designed with a common workflow to ensure that HSI models were implemented clearly and consistently. All models were coded with consistent formatting in HSImetadata and HSImodels, and naming conventions were implemented to ensure clarity when reviewing model parameters (Appendix B).

Team-based coding: Version 1.0.0 of ecorest was designed jointly by S.K. McKay and D.D. Hernandez-Abrams using team-based coding. Following package implementation, K.C. Cushway conducted a thorough review of model structure and accuracy by revisiting the model documentation from the USFWS for every HSI model in ecorest to identify potential errors and ensure code accuracy. Model updates or improvements are implemented in versions 2.0.0 - 2.0.3.

Error reporting: To communicate issues to users and reviewers, functions in ecorest were designed to generate error messages in the event of incorrect inputs or user errors. Common error messages in ecorest include ‘incorrect number of input’ errors, ‘out of range’ errors, and errors regarding incorrect formatting.

Examples of some error messages associated with various ecorest functions:

x <- c(0.2, 0.6, 1.4)

# Produce an error if a user enters unequal number of weights and suitability indices in HSIwarimean

tryCatch({
  if (any(x < 0 | x > 1, na.rm = TRUE)) {
    stop("Suitability indices must be between 0 and 1.", call. = FALSE)
  }
}, error = function(e) {
  message("Error: ", e$message)
})
## Error: Suitability indices must be between 0 and 1.
# Produce an error if duplicate time intervals are detected in annualizer
timevec <- c(0, 1, 2, 2, 3)

tryCatch({
  if (any(duplicated(timevec))) {
    dup_times <- unique(timevec[duplicated(timevec)])
    stop(
      paste0("Duplicate time intervals detected: ", paste(dup_times, collapse = ", "), "."),
      call. = FALSE
    )
  }
}, error = function(e) {
  message("Error: ", e$message)
})
## Error: Duplicate time intervals detected: 2.

Documentation: Comprehensive documentation of functions in ecorest was auto-generated by R during publication and can be accessed at https://cran.r-project.org/web/packages/ecorest/ecorest.pdf. Documentation includes descriptions of each function, their arguments and outputs, relevant references in the literature, and example applications. In addition, the authors documented all changes made to the package during error checking, including the nature of the changes, the reasoning for updates, and confirmation of implementation.

4.1.2 Quality Control

Interim code checking: During model integration into R, code functionality was checked periodically for each HSI model to ensure that models were operational, implemented correctly, and performed as expected. In addition, all models with USFWS documentation that included test data sets (n = 152 of 349) were verified for accuracy using all available test data (Appendix C). In cases where HSIeqtn outputs did not match USFWS outputs, models were independently verified to determine whether mismatches were due to rounding errors, coding issues in ecorest, or probable errors in USWFS documentation.

Formal model testing: Prior to release of ecorest version 2.0.3, every function in the package was tested to determine whether strategically selected inputs resulted in expected outcomes (Appendix C). For functions that require mathematical calculations, expected (i.e., correct) inputs, inputs with NA values, and invalid inputs were tested to ensure that functions properly handled both error messages and correct outputs. Where applicable, functions were also tested to ensure that inputs with mismatched lengths resulted in an error message. Each function was tested between 300 and 9999 times, depending on inputs (Appendix C).

4.1.3 Model updates: peer review and version control

R packages published and maintained on CRAN undergo automated reviews prior to initial package release and every package update to ensure that they are functional and compatible with multiple versions of R software, and that dependencies or reverse dependencies remain functional (Wickham and Bryan 2023). Every initial R package submission is subject to both this automated review and an additional human review to ensure that it meets the CRAN standards for quality assurance (Wickham and Bryan 2023). Version 1.0.0 of ecorest passed the automated and human reviews at initial submission, and automated reviews for updates to version 2.0.0 - 2.0.3. The newest version of ecorest, v2.0.3, is currently available on CRAN at https://cran.r-project.org/web/packages/ecorest/index.html, and older versions are archived on CRAN at https://cran.r-project.org/src/contrib/Archive/ecorest/.

4.2. Technical Quality

All blue-book HSI models included in ecorest are literature-based and grounded in expert opinion. To further assess each model’s technical quality, a sensitivity and uncertainty analysis was performed (Cushway et al., in press). Results of each analysis are summarized in PDF format at https://github.com/EcoModTeam/ecorest-sensitivity-and-uncertainty, but users interested in evaluating model technical quality may consider running their own sensitivity and uncertainty analysis using the process outlined in Appendix D, as the current analysis was generalized for all models and made relatively broad assumptions about parameter and output probability distributions.

4.3. Usability

The functions in ecorest are designed to be user-friendly and are meant to simplify the application process for both HSI and CEICA analyses. R software is ACE-IT approved and both freely and publicly available, making ecorest widely accessible to users from a variety of backgrounds. Source-code is available for all package functions and version-controlled archives are available on CRAN for users interested in accessing older versions of the package.

Formatting: To aid in user application and interpretation, ecorest was designed using consistent formatting and naming conventions (Appendix B-2). Both input and output formatting are consistent across models.

Training availability: For users unfamiliar with R software, a central repository for ecological modeling in R is currently in development at https://usace-wrises.github.io/USACE.EcoMod.Training/index.html. This resource provides basic training for R usage and includes several chapters on applying and using functions included in the ecorest package. Examples for how to apply ecorest are also available in Appendix E.

Technical support: Help text for every function in ecorest can be accessed in R software using the format ?functionname or help(functionname) (e.g., ?HSIeqtn or help(HSIeqtn)). Help text includes definitions for input and output values, useful references, and example applications to guide the user in proper application of functions. In addition, documentation for every function in the ecorest package was auto-generated by R during package submission and can be accessed at: https://cran.r-project.org/web/packages/ecorest/ecorest.pdf. Contact information for the package maintainer (S.K. McKay) is accessible at https://cran.r-project.org/web/packages/ecorest/index.html and can be used to request clarification not provided by package documentation or to report bugs or errors.

Example of help text for HSIeqtn:

R: Computes Habitat Suitability Index based on Model-Specified...
HSIeqtnR Documentation

Computes Habitat Suitability Index based on Model-Specified Equation

Description

HSIeqtn computes a habitat suitability index based on equations specified in U.S. Fish and Wildlife Service habitat suitability models contained within ecorest via HSImodels and HSImetadata. Habitat suitability indices represent an overall assessment of habitat quality from combining individual suitability indices for multiple independent variables. The function computes an overall habitat suitability index. Note that models compatible with HSIeqtn are certified for use by the U.S. Army Corps of Engineers by the National Ecosystem Planning Center of Expertise (Eco-PCX).

Usage

HSIeqtn(HSImodelname, SIV, HSImetadata, exclude = NULL)

Arguments

HSImodelname

a character string in quotations that must match an existing model name in HSImetadata.

SIV

a named vector, dataframe, or matrix of suitability index values ranging from 0 to 1 used in the model specified in HSImodelname. Names must correspond exactly with SIV names (e.g., "SIV1", "SIV1B", "SIV2", etc.)

HSImetadata

a data frame of HSI model metadata within the ecorest package.

exclude

a vector of character strings specifying components to be excluded from calculations. Non-NULL 'exclude' inputs are only applicable to models that explicitly provide instructions for use in the note column of HSImetadata.

Value

A numeric value between zero and one representing the composite habitat suitability index score.

References

US Fish and Wildlife Service. (1980). Habitat as a basis for environmental assessment. Ecological Services Manual, 101.

US Fish and Wildlife Service. (1980). Habitat Evaluation Procedures (HEP). Ecological Services Manual, 102.

US Fish and Wildlife Service. (1981). Standards for the Development of Habitat Suitability Index Models. Ecological Services Manual, 103.

Examples


#Compute patch quality for the Barred Owl model (no components)
#Allen A.W. 1982. Habitat Suitability Index Models: Barred owl. FWS/OBS 82/10.143.
#U.S. Fish and Wildlife Service. https://pubs.er.usgs.gov/publication/fwsobs82_10_143.
#Suitability indices relate to density of large trees (SIV1), 
#mean diameter of overstory trees (SIV2), and percent canopy cover of overstory (SIV3).
HSIeqtn("barredowl", c("SIV1" = 1, "SIV2" = 1, "SIV3" = 1), 
HSImetadata) #c(1,1,1) should result in 1.00
HSIeqtn("barredowl", c("SIV1" = 0.5, "SIV2" = 1, "SIV3" = 1), 
HSImetadata) #c(0.5,1,1) should result in 0.707
HSIeqtn("barredowl", c("SIV1" = 0, "SIV2" = 1, "SIV3" = 1), 
HSImetadata) #c(0,1,1) should result in 0.00

#Compute patch quality for the Juvenile Alewife model (two components)
#Pardue, G.B. 1983. Habitat Suitability index models: alewife and blueback herring.
#U.S. Dept. Int. Fish Wildl. Serv. FWS/OBS-82/10.58. 22pp.
#Suitability indices relate to zooplankton density, salinity, and water temperature
HSIeqtn("alewifeJuv", c("SIV1" = NA, "SIV2" = NA, 
                        "SIV3" = 1, "SIV4" = 1, "SIV5" = 1), HSImetadata) #should result in 1.00
HSIeqtn("alewifeJuv", c("SIV1" = NA, "SIV2" = NA, 
                        "SIV3" = 0.5, "SIV4" = 1, "SIV5" = 1), HSImetadata) # should result in 0.50
HSIeqtn("alewifeJuv", c("SIV1" = NA, "SIV2" = NA, 
                        "SIV3" = 0, "SIV4" = 1, "SIV5" = 1), HSImetadata) # should result in 0.00

#Compute patch quality for Cutthroat trout model for lacustrine habitats (7 components)
#with spawning and lacustrine habitat and with only lacustrine habitat (i.e., 
#embryo component is excluded).
#Hickman, T., and R.F. Raleigh. 1982. Habitat suitability index models: 
#Cutthroat trout. U.S.D.I. Fish and Wildlife Service. FWS/OBS-82/10.5. 38 pp.
#Suitability indices relate to temperature during the warmest period of the year,
#maximum temperature during embryo development, minimum dissolved oxygen during
#the late growing season, average velocity over spawning areas, average size 
#of substrate in spawning areas, annual maximal or minimal pH, and percent fines
#in the spawning area.
#should result in 1
HSIeqtn("cutthroatLacGenLtoe15C", c("SIV1" = 1, "SIV2" = 1, "SIV3" = 1, 
                                    "SIV5" = 1, "SIV7" = 1, "SIV13" = 1, 
                                    "SIV16" = 1), HSImetadata) 
                                    
#should result in 0
HSIeqtn("cutthroatLacGenLtoe15C", c("SIV1" = 0.5, "SIV2" = 1, "SIV3" = 0.5, 
                                    "SIV5" = 0, "SIV7" = 1, "SIV13" = 1, 
                                    "SIV16" = 1), HSImetadata) 
                                    
#should result in 0.63
HSIeqtn("cutthroatLacGenLtoe15C", c("SIV1" = 1, "SIV2" = NA, "SIV3" = 0.5, 
                                    "SIV5" = NA, "SIV7" = NA, "SIV13" = 0.5, 
                                    "SIV16" = NA), HSImetadata, exclude=c("CE")) 

USACE compliance: Models included in HSImodels and HSImetadata are certified for USACE application by ECO-PCX. However, the HSImin, HSIarimean, HSIwarimean, and HSIgeomean functions are meant to assist users in easily applying and conducting analyses for models that are not included in HSImodels and HSImetadata. Unless otherwise specified by a project team, models implemented using these functions are not certified for use and will need additional approvals from ECO-PCX prior to application.

5. Application

This section provides short examples illustrating how each function can be applied. These examples are intended to demonstrate basic use and typical inputs rather than full restoration analyses. Appendix E includes integrated examples showing how multiple functions can be used together to support ecosystem restoration decisions.

  1. HSIplotter() is used to visualize suitability curves for an existing or user-specified model. This can help users inspect model structure, confirm variable ranges, and communicate how habitat variables are translated into suitability index values.
HSIplotter(HSImodels$barredowl, "barredowl_curves2.jpeg")
## Warning in HSIplotter(HSImodels$barredowl, "barredowl_curves2.jpeg"): U.S. Army Corps of Engineers users must have approval from the National Ecosystem 
##   Planning Center of Expertise (Eco-PCX) prior to application of a new model.
Figure 3. Suitability index curves for the Barred Owl (Strix varia) (Allen 1987).
Figure 3. Suitability index curves for the Barred Owl (Strix varia) (Allen 1987).
  1. SIcalc() calculates suitability index values for a set of habitat variables using the suitability curves for a given model. Inputs may include continuous variables, categorical variables, or NA values for excluded variables.
input.demo <- c(4, 51, 40)
SIcalc(HSImodels$barredowl, input.demo)
## Warning: U.S. Army Corps of Engineers users must have approval from the
## National Ecosystem Planning Center of Expertise (Eco-PCX) prior to application
## of a new model.
## SIV1 SIV2 SIV3 
##  1.0  1.0  0.5
  1. HSIeqtn() combines suitability index values into a single habitat suitability index using the model-specific equation stored in HSImetadata.These equations correspond to existing USFWS “blue book” HSI models that have been approved for USACE use.
HSIeqtn("barredowl", c("SIV1" = 1, "SIV2" = 1, "SIV3" = 1), HSImetadata)
## [1] 1
  1. HUcalc() converts habitat quality into habitat units by combining an HSI score with habitat quantity, such as acres.
HUcalc(
  SI.out = c(0.8, 0.9, 1.0),
  habitat.quantity = 150,
  HSIfunc = HSIgeomean
)
## Warning in HUcalc(SI.out = c(0.8, 0.9, 1), habitat.quantity = 150, HSIfunc = HSIgeomean): U.S. Army Corps of Engineers users must have approval from the National Ecosystem 
##   Planning Center of Expertise (Eco-PCX) prior to application of a new model.
## Warning in HSIfunc(SI.out, ...): U.S. Army Corps of Engineers users must have approval from the National Ecosystem 
##   Planning Center of Expertise (Eco-PCX) prior to application of a new model.
##     Quality Quantity IndexUnits
## 1 0.8962809      150   134.4421
  1. HSIarimean() takes the arithmetic mean of user inputs, which allows higher suitability scores to compensate for lower scores. Although this function provides general methods for aggregating suitability index values, USACE applications should use only models that have received appropriate Eco-PCX review and approval.
HSIarimean(c(0.5, 0.3, 0.7))
## Warning in HSIarimean(c(0.5, 0.3, 0.7)): U.S. Army Corps of Engineers users must have approval from the National Ecosystem 
##   Planning Center of Expertise (Eco-PCX) prior to application of a new model.
## [1] 0.5
  1. HSIwarimean() takes the weighted arithmetic mean of user inputs according to user-provided weights that sum to one. This allows users to emphasize the importance of certain environmental conditions for overall habitat suitability.Although this function provides general methods for aggregating suitability index values, USACE applications should use only models that have received appropriate Eco-PCX review and approval.
HSIwarimean(x = c(0.3, 0.7, 1), w = c(0.3, 0.3, 0.4))
## Warning in HSIwarimean(x = c(0.3, 0.7, 1), w = c(0.3, 0.3, 0.4)): U.S. Army Corps of Engineers users must have approval from the National Ecosystem 
##   Planning Center of Expertise (Eco-PCX) prior to application of a new model
##   or weighting system.
## [1] 0.7
  1. HSIgeomean() takes the geometric mean of user inputs, which ensures that one completely unsuitable environmental condition will result in unsuitable habitat for a species.Although this function provides general methods for aggregating suitability index values, USACE applications should use only models that have received appropriate Eco-PCX review and approval.
HSIgeomean(c(0, 0.2, 1))
## Warning in HSIgeomean(c(0, 0.2, 1)): U.S. Army Corps of Engineers users must have approval from the National Ecosystem 
##   Planning Center of Expertise (Eco-PCX) prior to application of a new model.
## [1] 0
  1. HSImin() takes a limiting factor approach, such that the overall HSI score is equal to the lowest suitability index.Although this function provides general methods for aggregating suitability index values, USACE applications should use only models that have received appropriate Eco-PCX review and approval.
HSImin(c(0.4, 0.3, 0.8))
## Warning in HSImin(c(0.4, 0.3, 0.8)): U.S. Army Corps of Engineers users must have approval from the National Ecosystem 
##   Planning Center of Expertise (Eco-PCX) prior to application of a new model.
## [1] 0.3
  1. annualizer() converts time-varying ecological outputs into an average annual value over a specified time horizon. This is especially useful for restoration benefits that change through time.
timevec <- c(0, 10, 20, 30)
benefits <- c(100, 120, 150, 160)

annualizer(timevec, benefits)
## [1] 133.3333
  1. CEfinder() identifies which alternatives are cost-effective based on ecological benefits and costs.
benefit <- c(10, 20, 25, 30)
cost <- c(1.0, 2.5, 4.0, 6.0)

CEfinder(benefit, cost)
## [1] 1 1 1 1
  1. BBfinder() uses the results of CEfinder() to identify best-buy alternatives through incremental cost analysis. Considerations for Application.
benefit <- c(10, 20, 25, 30)
cost <- c(1.0, 7.0, 6.0, 8.0)

CE.out <- CEfinder(benefit, cost)
BB.out <-BBfinder(benefit, cost, CE.out)
  1. CEICAplotter() creates a summary plot showing all alternatives, the cost-effectiveness frontier, and the best-buy alternatives.
altnames <- c("Alt A", "Alt B", "Alt C", "Alt D")

CEICAplotter(
  altnames,
  benefit,
  cost,
  CE.out,
  BB.out[[1]][, 4],
  "ceica_example.jpeg"
)
Figure 4. Example output from CEICAplotter.
Figure 4. Example output from CEICAplotter.


Together, these functions support a general workflow in which habitat variables are translated into suitability index values, combined into habitat suitability scores, scaled to habitat units, and then used to compare restoration alternatives through CEICA. Individual functions may be applied independently, but they are often most useful when used together in a structured restoration planning workflow.

Application of these models requires careful attention to their intended scope, assumptions, and limitations. Key considerations include geographic relevance, system type, conceptual model boundaries, and numerical constraints. Many of the USFWS “blue book” models were developed for particular species, habitat types, regions, or environmental gradients. Users should also evaluate whether the modeled variables adequately represent the ecological processes of interest and recognize that important drivers may be omitted from a given model. In some cases, models may not account for temporal variability, landscape connectivity, disturbance regimes, management constraints, or interactions among habitat features that influence restoration outcomes. Numerical limits are also important, as model inputs and suitability curves are typically valid only within specified ranges and may produce misleading results if extrapolated beyond those bounds. As a result, these models should not be treated as complete representations of system behavior, but rather as structured decision-support tools with defined limits. Prior to application, users should assess model sensitivity and conduct uncertainty analysis to understand how assumptions, parameter choices, and input variability influence outputs. This is especially important when model results are used to compare alternatives or support restoration planning decisions.

For U.S. Army Corps of Engineers users, application of a new model also requires prior approval from the National Ecosystem Planning Center of Expertise (Eco-PCX).

6. Summary

ecorest provides a standardized and flexible platform for applying index-based ecological models and decision-support tools in ecosystem restoration planning and related environmental analyses. The package compiles a large library of USFWS HSI models, provides functions for calculating suitability indices, habitat suitability indices, and habitat units, and integrates cost-effectiveness and incremental cost analyses within the same workflow. Together, these tools support consistent, transparent, and reproducible comparison of ecological conditions and restoration alternatives. While ecorest improves accessibility and reduces the need for ad hoc spreadsheet-based approaches, model results remain dependent on the assumptions, intended scope, and input limits of the underlying models. Accordingly, users should apply these tools with attention to model context, uncertainty, and appropriate communication of results.

Acknowledgements

Funding: EMRRP and ANSRP’s focus on Next Generation Ecological Modeling.

Ideas and collaboration: Nate Richards, Tyler Keys, Christina Saltus, Brook Herman, Carra Carrillo, Iris Foxfoot, Colton Shaw

References

Allen, A.W. 1987. Habitat suitability index models: barred owl. U.S. Fish Wild. Serv. Biol. Rep. 82(10.143). 17 pp

Brinson M.M. 1993. A hydrogeomorphic classification for wetlands. Technical Report WRP-DE-4. Vicksburg, MS: U.S. Army Engineer Waterway Experiment Station.

Carrillo C., McKay S.K., and Swannack T.M. 2022. Ecological Model Development: Toolkit for interActive Modeling (TAM). ERDC TN-EMRRP-SR-90. U.S. Army Engineer Research and Development Center, Vicksburg, Mississippi.

Cushway, K.C., Shaw, C., McKay, S.K., and Swannack, T.M. In press. Sensitivity and uncertainty in habitat suitability modeling: guidance and pitfalls for ecological applications. Environmental Software and Modelling, 106984.

Fischenich J.C. 2008. The application of conceptual models to ecosystem restoration. ERDC TN-EBA-TN-08-1. U.S. Army Engineer Research and Development Center, Vicksburg, Mississippi.

Grant W.E. and Swannack T.M. 2008. Ecological modeling: A common-sense approach to theory and practice. Malden, MA: Blackwell Publishing.

Herman B.D., McKay S.K., Altman S., Richards N.S., Reif M., Piercy C.D., and Swannack T.M. 2019. Unpacking the black box: Demystifying ecological models through mediated modeling and hands-on learning. Frontiers in Environmental Science, 7 (122), doi: 10.3389/fenvs.2019.00122.

Hijmans R.J. and Ghosh A. 2019. Spatial data analysis with R. https://rspatial.org/.

McKay S.K. 2009. Reducing spreadsheet errors. ERDC TN-EMRRP-EBA-03. U.S. Army Engineer Research and Development Center, Vicksburg, Mississippi.

McKay, S. Kyle, Darixa D. Hernandez-Abrams, and Kiara C. Cushway. 2026. ecorest: Conducts Analyses Informing Ecosystem Restoration Decisions. R package, version 2.0.2. Comprehensive R Archive Network (CRAN). https://CRAN.R-project.org/package=ecorest

McKay S.K., Pruitt B.A., Zettle B., Hallberg N., Hughes C., Annaert A., Ladart M., and McDonald J. 2018a. Proctor Creek Ecological Model (PCEM): Phase 1-Site screening. ERDC/EL TR-18-11. U.S. Army Engineer Research and Development Center, Vicksburg, Mississippi.

McKay S.K., Pruitt B.A., Zettle B.A., Hallberg N., Moody V., Annaert A., Ladart M., Hayden M., and McDonald J. 2018b. Proctor Creek Ecological Model (PCEM): Phase 2-Benefits analysis. ERDC/EL TR-18-11. U.S. Army Engineer Research and Development Center, Vicksburg, Mississippi.

McKay S.K., Richards N., and Swannack T.M. 2019. Aligning ecological model development with restoration project planning. ERDC EMRRP-SR-89. U.S. Army Engineer Research and Development Center, Vicksburg, Mississippi.

McKay, S.K., Richards, N., and Swannack T.M. 2022. Ecological model development: evaluation of system quality. ERDC/TN EMRRP-EBA-26. U.S. Army Engineer Research and Development Center, Vicksburg, Mississippi.

McMahin, TE, JW Terrell, and PC Nelson. 1984. Habitat suitability information: Walleye. U.S. Fish Wildl. Serv. FWS/OBS-82/10.56. 43 pp.

Murray, Elizabeth O., Darixa D. Hernandez-Abrams, and Todd M. Swannack. 2021. Development of Tidal Habitats and Resilience Evaluation Model (THREM) for Evaluation of Ecosystem Alternatives. Internal model documentation. U.S. Army Corps of Engineers.

Palesh G. and Anderson D. 1990. Modification of the habitat suitability index model for the bluegill (Lepomis macrochirus) for winter conditions for the Upper Mississippi River backwater habitats.

R Core Team. 2024. R: A language and environment for statistical computing. R Foundation for Statistical Computing, Vienna, Austria. URL https://www.R-project.org/.

Robinson R. Hansen W., and Orth K. 1995. Evaluation of environmental investments procedures manual interim: Cost effectiveness and incremental cost analyses. IWR Report 95-R-1. Institute for Water Resources, U.S. Army Corps of Engineers, Alexandria, Virginia.

Smith R.D., Ammann A., Bartoldus C., and Brinson M.M. 1995. An approach for assessing wetland functions using hydrogeomorphic classification, reference wetlands, and functional indices. Technical Report WRP-DE-9. Vicksburg, MS: Army Engineer Waterways Experiment Station.

Stuber R.J., Gebhart G., and Maughan O.E. 1982. Habitat suitability index models: Bluegill. U.S.D.I. Fish and Wildlife Service. FWS/OBS-82/10.8. 26 pp.

Swannack T.M., Fischenich J.C., and Tazik D.J. 2012. Ecological modeling guide for ecosystem restoration and management. ERDC/EL TR-12-18. Vicksburg, MS: U.S. Army Engineer Research and Development Center.

Swannack T.M., Reif M., and Soniat T.M. 2014. A robust, spatially explicit model for identifying oyster restoration sites: Case studies on the Atlantic and Gulf Coasts. Journal of Shellfish Research, 33 (2), 395-408.

Tirpak J.M., Jones Farrand D., Thompson F.R., Twedt D.J., Baxter C.K., Fitzgerald J.A., and Uihlein W.B. 2009. Assessing ecoregional scale habitat suitability index models for priority landbirds. The Journal of Wildlife Management 73:1307-1315.

U.S. Army Corps of Engineers (USACE). 1999. Civil Works Ecosystem Restoration Policy. ER 1165-2-501. U.S. Army Corps of Engineers, Washington, D.C.

USACE. 2000. Planning Guidance Notebook. ER-1105-2-100. U.S. Army Corps of Engineers, Washington, D.C.

USACE. 2011. Assuring quality of planning models. EC-1105-2-412. Washington, DC. U.S. Army Corps of Engineers.

USACE. 2014. Appendix C: Environment. EC-11-2-206. Headquarters, USACE, Washington, D.C.

US Fish and Wildlife Service. 1980a. Habitat as a basis for environmental assessment. Ecological Services Manual, 101.

US Fish and Wildlife Service. 1980b. Habitat Evaluation Procedures (HEP). Ecological Services Manual, 102.

US Fish and Wildlife Service. 1981. Standards for the Development of Habitat Suitability Index Models. Ecological Services Manual, 103.

Wickham, H. and Bryan, J. 2023. R packages: organize, test, document, and share your code. 2nd edition. O’Reilly Media , Sebastopol CA, uSA.

Appendix A: Glossary and Acronyms

  • CEICA: Cost-Effective Incremental Cost Analysis
  • Eco-PCX: U.S. Army Corps of Engineers’ ecosystem restoration planning center of expertise.
  • ecorest: R-package for conducting analyses informing ecosystem restoration decisions as described in this document.
  • ERDC: U.S. Army Engineer Research and Development Center.
  • FWOP: Future WithOut Project Conditions.
  • R: Statistical software language used to program ecorest (R Core Team 2019).
  • THREM: Tidal Habitats and Resilience Evaluation Model
  • USACE: U.S. Army Corps of Engineers.
  • USFWS: U.S. Fish and Wildlife Service.

Appendix B: USFWS Habitat Suitability Models included in ecorest

Table B-1. USFWS Habitat Suitability Index models included in ecorest.
Model Name Taxa Documentation Website link
alewifeJuv Alosa pseudoharengus Pardue, GB. 1983. Habitat suitability index models: alewife and blueback herring. U.S. Dept. Int. Fish Wildl. Serv. FWS/OBS-82/10.58. 22pp. pdf
alewifeJuvAndSAEL Alosa pseudoharengus Pardue, GB. 1983. Habitat suitability index models: alewife and blueback herring. U.S. Dept. Int. Fish Wildl. Serv. FWS/OBS-82/10.58. 22pp. pdf
alewifeSAEL Alosa pseudoharengus Pardue, GB. 1983. Habitat suitability index models: alewife and blueback herring. U.S. Dept. Int. Fish Wildl. Serv. FWS/OBS-82/10.58. 22pp. pdf
americanalligatorNontidal Alligator mississippiensis Newsom, JD, T Joanen, and RJ Howard. 1987. Habitat suitability index models: American alligator. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.136). 14 pp. pdf
americanalligatorTidal Alligator mississippiensis Newsom, JD, T Joanen, and RJ Howard. 1987. Habitat suitability index models: American alligator. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.136). 14 pp. pdf
americanblackduckWinteringEVegWetland Anas rubripes Lewis, JC, and RL Garrison. 1984. Habitat suitability index models: American black duck (wintering). U.S. Fish Wildl. Serv. FWS/OBS-82/10.68. 16 pp. pdf
americanblackduckWinteringNCapeCod Anas rubripes Lewis, JC, and RL Garrison. 1984. Habitat suitability index models: American black duck (wintering). U.S. Fish Wildl. Serv. FWS/OBS-82/10.68. 16 pp. pdf
americanblackduckWinteringSCapeCod Anas rubripes Lewis, JC, and RL Garrison. 1984. Habitat suitability index models: American black duck (wintering). U.S. Fish Wildl. Serv. FWS/OBS-82/10.68. 16 pp. pdf
americancoot Fulica americana Allen, AW. 1985. Habitat suitability index models: American coot. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.115). 17 pp. pdf
americaneiderBreeding Somateria mollissima dresseri Blumton, AK, RB Owen Jr, and WB Krohn. 1988. Habitat suitability index models: American eider (breeding). U.S. Fish Wildl. Serv. Biol. Rep. 82(10.149). 24 pp. pdf
americanoysterGulfofMexModifier Crassostrea virginica Cake Jr, EW. 1983. Habitat suitability index models: Gulf of Mexico American oyster. U.S. Dept. Int. Fish Wildl. Serv. FWS/OBS-82/10.f57. 37 pp. pdf
americanoysterGulfofMexTypical Crassostrea virginica Cake Jr, EW. 1983. Habitat suitability index models: Gulf of Mexico American oyster. U.S. Dept. Int. Fish Wildl. Serv. FWS/OBS-82/10.f57. 37 pp. pdf
americanshadEstu Alosa sapidissima Stier, DJ, and JH Crance. 1985. Habitat suitability index models and instream flow suitability curves: American shad. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.88) 34 pp. pdf
americanshadRiv Alosa sapidissima Stier, DJ, and JH Crance. 1985. Habitat suitability index models and instream flow suitability curves: American shad. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.88) 34 pp. pdf
americanwoodcockWinteringForestedDry Scolopax minor Cade, BS. 1985. Habitat suitability index models: American woodcock (wintering). U.S. Fish Wildl. Serv. Biol. Rep. 82(10.105) 23 pp. pdf
americanwoodcockWinteringForestedMoist Scolopax minor Cade, BS. 1985. Habitat suitability index models: American woodcock (wintering). U.S. Fish Wildl. Serv. Biol. Rep. 82(10.105) 23 pp. pdf
americanwoodcockWinteringForestedWet Scolopax minor Cade, BS. 1985. Habitat suitability index models: American woodcock (wintering). U.S. Fish Wildl. Serv. Biol. Rep. 82(10.105) 23 pp. pdf
americanwoodcockWinteringShrubDry Scolopax minor Cade, BS. 1985. Habitat suitability index models: American woodcock (wintering). U.S. Fish Wildl. Serv. Biol. Rep. 82(10.105) 23 pp. pdf
americanwoodcockWinteringShrubMoist Scolopax minor Cade, BS. 1985. Habitat suitability index models: American woodcock (wintering). U.S. Fish Wildl. Serv. Biol. Rep. 82(10.105) 23 pp. pdf
americanwoodcockWinteringShrubWet Scolopax minor Cade, BS. 1985. Habitat suitability index models: American woodcock (wintering). U.S. Fish Wildl. Serv. Biol. Rep. 82(10.105) 23 pp. pdf
arcticgrayling Thymallus arcticus Hubert, WA, RS Helzner, LA Lee, and PC Nelson. 1985. Habitat suitability index models and instream flow suitability curves: Arctic grayling riverine populations. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.110). 34 pp pdf
atlanticcroakerLATideLt0.5m Micropogonias undulatus Diaz, RJ, and CP Onuf. 1985. Habitat suitability index models: juvenile Atlantic croaker (revised). U.S. Fish Wildl. Serv. Biol. Rep. 82(10.98). 23 pp. pdf
atlanticcroakerLATideMt0.5m Micropogonias undulatus Diaz, RJ, and CP Onuf. 1985. Habitat suitability index models: juvenile Atlantic croaker (revised). U.S. Fish Wildl. Serv. Biol. Rep. 82(10.98). 23 pp. pdf
atlanticcroakerOtherTideLt0.5m Micropogonias undulatus Diaz, RJ, and CP Onuf. 1985. Habitat suitability index models: juvenile Atlantic croaker (revised). U.S. Fish Wildl. Serv. Biol. Rep. 82(10.98). 23 pp. pdf
atlanticcroakerOtherTideMt0.5m Micropogonias undulatus Diaz, RJ, and CP Onuf. 1985. Habitat suitability index models: juvenile Atlantic croaker (revised). U.S. Fish Wildl. Serv. Biol. Rep. 82(10.98). 23 pp. pdf
atlanticcroakerWetlandLATideLt0.5m Micropogonias undulatus Diaz, RJ, and CP Onuf. 1985. Habitat suitability index models: juvenile Atlantic croaker (revised). U.S. Fish Wildl. Serv. Biol. Rep. 82(10.98). 23 pp. pdf
atlanticcroakerWetlandLATideMt0.5m Micropogonias undulatus Diaz, RJ, and CP Onuf. 1985. Habitat suitability index models: juvenile Atlantic croaker (revised). U.S. Fish Wildl. Serv. Biol. Rep. 82(10.98). 23 pp. pdf
atlanticcroakerWetlandOtherTideLt0.5m Micropogonias undulatus Diaz, RJ, and CP Onuf. 1985. Habitat suitability index models: juvenile Atlantic croaker (revised). U.S. Fish Wildl. Serv. Biol. Rep. 82(10.98). 23 pp. pdf
atlanticcroakerWetlandOtherTideMt0.5m Micropogonias undulatus Diaz, RJ, and CP Onuf. 1985. Habitat suitability index models: juvenile Atlantic croaker (revised). U.S. Fish Wildl. Serv. Biol. Rep. 82(10.98). 23 pp. pdf
bairdssparrow Ammodramus bairdii Sousa, PJ, and WN McDonal. 1983. Habitat suitability index models: Baird’s sparrow. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.44. 12 pp. pdf
baldeagleBreeding Haliaeetus leucocephalus Peterson, A. 1986. Habitat suitability index models: Bald eagle (breeding season). U.S. Fish Wildl. Serv. Biol. Rep. 82(10.126). 25 pp. pdf
barredowl Strix varia Allen, AW. 1987. Habitat suitability index models: barred owl. U.S. Fish Wild. Serv. Biol. Rep. 82(10.143). 17 pp. pdf
beaverLacAreaLt8ha Castor canadensis Allen, AW. 1982. Habitat suitability index models: Beaver. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.30. 20 pp pdf
beaverLacAreaMtoe8ha Castor canadensis Allen, AW. 1982. Habitat suitability index models: Beaver. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.30. 20 pp pdf
beaverPalu Castor canadensis Allen, AW. 1982. Habitat suitability index models: Beaver. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.30. 20 pp pdf
beaverRiv Castor canadensis Allen, AW. 1982. Habitat suitability index models: Beaver. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.30. 20 pp pdf
beltedkingfisherLenticConstWave Ceryle alcyon Prose, BL. 1985. Habitat suitability index models: Belted kingfisher. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.87). 22 pp. pdf
beltedkingfisherLenticNoConstWave Ceryle alcyon Prose, BL. 1985. Habitat suitability index models: Belted kingfisher. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.87). 22 pp. pdf
beltedkingfisherLotic Ceryle alcyon Prose, BL. 1985. Habitat suitability index models: Belted kingfisher. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.87). 22 pp. pdf
bigmouthbuffaloLacNoSal Ictiobus cyprinellus Edwards, EA. 1983. Habitat suitability index models: Bigmouth buffalo. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10/34. 23 pp. pdf
bigmouthbuffaloLacSal Ictiobus cyprinellus Edwards, EA. 1983. Habitat suitability index models: Bigmouth buffalo. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10/34. 23 pp. pdf
bigmouthbuffaloRivNoSal Ictiobus cyprinellus Edwards, EA. 1983. Habitat suitability index models: Bigmouth buffalo. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10/34. 23 pp. pdf
bigmouthbuffaloRivSal Ictiobus cyprinellus Edwards, EA. 1983. Habitat suitability index models: Bigmouth buffalo. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10/34. 23 pp. pdf
blackbear Ursus americanus Rogers, LL, and AW Allen. 1987. Habitat suitability index models: black bear, Upper Great Lakes Region. U.S. Fish Wildl. Serv. Biol. Rep. 82(10/144). 54 pp. pdf
blackbelliedwhistlingduck Dendrocygna autumnalis McKenzie, PM, and PJ Zwank. 1988. Habitat suitability index models: black-bellied whistling-duck (breeding). U.S. Fish Wildl. Serv. Biol. Rep. 82(10.150). 22 pp pdf
blackbrant Branta bernicla nigricans Schroeder, RL. 1984. Habitat suitabilitly index models: Black brant. U.S. Fish Wildl. Serv. FWS/OBS-82/10.63. 11 pp. pdf
blackbullheadLac Ictalurus melas Stuber, RJ. 1982. Habitat suitability index models: Black bullhead. U.S. Dept. int. Fish Wildl. Serv. FWS/OBS-82/10.14. 25 pp. pdf
blackbullheadRiv Ictalurus melas Stuber, RJ. 1982. Habitat suitability index models: Black bullhead. U.S. Dept. int. Fish Wildl. Serv. FWS/OBS-82/10.14. 25 pp. pdf
blackcappedchickadeeFoodCanH Poecile atricapillus Schroeder, RL. 1983. Habitat suitability index models: Black-capped chickadee. FWS/OBS-82/10.37. U.S. Fish and Wildlife Service. pdf
blackcappedchickadeeFoodCanVol Poecile atricapillus Schroeder, RL. 1983. Habitat suitability index models: Black-capped chickadee. FWS/OBS-82/10.37. U.S. Fish and Wildlife Service. pdf
blackcrappieLacNoSal Pomoxis nigromaculatus Edwards, EA., DA. Krieger, M Bacteller, and OE Maughan. 1982. Habitat suitability index models: Black crappie. U.S.D.I. Fish and Wildlife Service. FWS/OBS-82/10.6. 25 pp. pdf
blackcrappieLacSal Pomoxis nigromaculatus Edwards, EA, DA Krieger, M Bacteller, and OE Maughan. 1982. Habitat suitability index models: Black crappie. U.S.D.I. Fish and Wildlife Service. FWS/OBS-82/10.6. 25 pp. pdf
blackcrappieRivNoSal Pomoxis nigromaculatus Edwards, EA, DA Krieger, M Bacteller, and OE Maughan. 1982. Habitat suitability index models: Black crappie. U.S.D.I. Fish and Wildlife Service. FWS/OBS-82/10.6. 25 pp. pdf
blackcrappieRivSal Pomoxis nigromaculatus Edwards, EA, DA Krieger, M Bacteller, and OE Maughan. 1982. Habitat suitability index models: Black crappie. U.S.D.I. Fish and Wildlife Service. FWS/OBS-82/10.6. 25 pp. pdf
blacknosedaceLac Rhinichthys atratulus Trial, JG, JG Stanley, M Batcheller, G Gebhart, OE Maughan, and PC Nelson. 1983. Habitat suitability information: Blacknose dace. US Department of Interior, Fish and Wildlife Service. FWS/OBS-82/10.41. 28 pp. pdf
blacknosedaceRiv Rhinichthys atratulus Trial, JG, JG Stanley, M Batcheller, G Gebhart, OE Maughan, and PC Nelson. 1983. Habitat suitability information: Blacknose dace. US Department of Interior, Fish and Wildlife Service. FWS/OBS-82/10.41. 28 pp. pdf
blackshoulderedkite Elanus caeruleus Faanes, CA, and RJ Howard. 1987. Habitat suitability index models: black-shouldered kite. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.130). 13 pp. pdf
blacktailedprairiedog Cynomys ludovicianus Clippinger, NW. 1989. Habitat suitability index models: Black-tailed prairie dog. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.156). 21 pp. pdf
bluegillLac Lepomis macrochirus Stuber, RJ, G Gebhart, and OE Maughan. 1982. Habitat Suitability Index Models: Bluegill. USFWS Report FWS/OBS-82/10.8. 26pp. pdf
bluegillRiv Lepomis macrochirus Stuber, RJ, G Gebhart, and OE Maughan. 1982. Habitat Suitability Index Models: Bluegill. USFWS Report FWS/OBS-82/10.8. 26pp. pdf
bluegrouse Dendragapus obscurus Schroeder, RL. 1984. Habitat suitability index models: Blue grouse. U.S. Fish Wildl. Servo FWS/OBS-82/10.81. 19 pp. pdf
blueherringJuv Alosa aestivalis Pardue, GB. 1983. Habitat suitability index models: alewife and blueback herring. U.S. Dept. Int. Fish Wildl. Serv. FWS/OBS-82/10.58. 22pp. pdf
blueherringJuvAndSAEL Alosa aestivalis Pardue, GB. 1983. Habitat suitability index models: alewife and blueback herring. U.S. Dept. Int. Fish Wildl. Serv. FWS/OBS-82/10.58. 22pp. pdf
blueherringSAEL Alosa aestivalis Pardue, GB. 1983. Habitat suitability index models: alewife and blueback herring. U.S. Dept. Int. Fish Wildl. Serv. FWS/OBS-82/10.58. 22pp. pdf
bluewingedtealBreeding Spatula discors Sousa, PJ. 1985. Habitat suitability index models: Blue-winged teal (breeding). U.S. Fish Wildl. Serv. Biol. Rep. 82(10.114). 36 pp. pdf
bobcatLt4ha Felis rufus Boyle, KA, and TT Fendley. 1987. Habitat suitability index models: bobcat. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.147). 16 pp. pdf
bobcatMtoe4ha Felis rufus Boyle, KA, and TT Fendley. 1987. Habitat suitability index models: bobcat. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.147). 16 pp. pdf
brewerssparrow Spizella breweri Short, HL. 1984. Habitat suitability index models: Brewer’s sparrow. U.S. Fish Wildl. Serv. FWS/OBS-82 pdf
brooktroutLacAllLtoe15C Salvelinus fontinalis Raleigh, RF. 1982. Habitat suitability index models: Brook trout. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.24. 42 pp. pdf
brooktroutLacAllMt15C Salvelinus fontinalis Raleigh, RF. 1982. Habitat suitability index models: Brook trout. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.24. 42 pp. pdf
brooktroutRivAllLtoe15CLtoe5mEC Salvelinus fontinalis Raleigh, RF. 1982. Habitat suitability index models: Brook trout. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.24. 42 pp. pdf
brooktroutRivAllLtoe15CMt5mEC Salvelinus fontinalis Raleigh, RF. 1982. Habitat suitability index models: Brook trout. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.24. 42 pp. pdf
brooktroutRivAllMt15CLtoe5mEC Salvelinus fontinalis Raleigh, RF. 1982. Habitat suitability index models: Brook trout. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.24. 42 pp. pdf
brooktroutRivAllMt15CMt5mEC Salvelinus fontinalis Raleigh, RF. 1982. Habitat suitability index models: Brook trout. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.24. 42 pp. pdf
brownshrimpNGulfofMex Penaeus aztecus Turner, RE, and MS Brody. 1983 Habitat suitability index models : northern Gulf of Mexico brown shrimp and white shrimp. U.S. Dept. of Int. Fish Wildl. Serv , FWS/OBS-82/l0.54. 24 pp. pdf
brownthrasher Toxostoma rufum Cade, BS. 1986. Habitat suitability index models: Brown thrasher. U.S. Fish Wild. Serv. Biol. Rep. 82(10.118). 14 pp. pdf
browntroutCompLtoe10C Salmo trutta Raleigh, RF, LD Zuckerman, and PC Nelson. 1986. Habitat suitability index models and instream flow suitability curves: Brown trout, revised. US Fish and Wildlife Service. 82(10.124) 65 pp pdf
browntroutCompMt10C Salmo trutta Raleigh, RF, LD Zuckerman, and PC Nelson. 1986. Habitat suitability index models and instream flow suitability curves: Brown trout, revised. US Fish and Wildlife Service. 82(10.124) 65 pp pdf
browntroutLimitLtoe10C Salmo trutta Raleigh, RF, LD Zuckerman, and PC Nelson. 1986. Habitat suitability index models and instream flow suitability curves: Brown trout, revised. US Fish and Wildlife Service. 82(10.124) 65 pp pdf
browntroutLimitMt10C Salmo trutta Raleigh, RF, LD Zuckerman, and PC Nelson. 1986. Habitat suitability index models and instream flow suitability curves: Brown trout, revised. US Fish and Wildlife Service. 82(10.124) 65 pp pdf
bullfrog Rana catesbeiana Graves, BM, and SH Anderson. 1987. Habitat suitability index models: bullfrog. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.138). 22 pp. pdf
cactuswren Campylorhynchus brunneicapillus Short, HL. 1985. Habitat suitability index models: Cactus wren. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.96). 15 pp. pdf
canvasbackBreeding Aythya valisineria Schroeder, RL. 1984. Habitat suitability index models: Canvasback (breeding habitat). U.S. Fish Wildl. Serv. FWS/OBS-82/10.82. 16 pp. pdf
channelcatfishLac Ictalurus punctatus McMahon, TE., and JW Terrell. 1982. Habitat suitability index models: Channel catfish. U.S.D.I. Fish and Wildlife Service. FWS/OBS-82/10.2. 29 pp. pdf
channelcatfishRiv Ictalurus punctatus McMahon, TE, and JW Terrell. 1982. Habitat suitability index models: Channel catfish. U.S.D.I. Fish and Wildlife Service. FWS/OBS-82/10.2. 29 pp. pdf
chinooksalmonComp5to10CSand Oncorhynchus tshawytscha Raleigh, RF, WJ Miller, and PC Nelson. 1986. Habitat suitability index models and instream flow suitability curves: chinook salmon. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.122). 64 pp. pdf
chinooksalmonComp5to10CSilt Oncorhynchus tshawytscha Raleigh, RF, WJ Miller, and PC Nelson. 1986. Habitat suitability index models and instream flow suitability curves: chinook salmon. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.122). 64 pp. pdf
chinooksalmonCompLtoe5CSand Oncorhynchus tshawytscha Raleigh, RF, WJ Miller, and PC Nelson. 1986. Habitat suitability index models and instream flow suitability curves: chinook salmon. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.122). 64 pp. pdf
chinooksalmonCompLtoe5CSilt Oncorhynchus tshawytscha Raleigh, RF, WJ Miller, and PC Nelson. 1986. Habitat suitability index models and instream flow suitability curves: chinook salmon. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.122). 64 pp. pdf
chinooksalmonCompMt10CSand Oncorhynchus tshawytscha Raleigh, RF, WJ Miller, and PC Nelson. 1986. Habitat suitability index models and instream flow suitability curves: chinook salmon. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.122). 64 pp. pdf
chinooksalmonCompMt10CSilt Oncorhynchus tshawytscha Raleigh, RF, WJ Miller, and PC Nelson. 1986. Habitat suitability index models and instream flow suitability curves: chinook salmon. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.122). 64 pp. pdf
chinooksalmonLimit5to10CSand Oncorhynchus tshawytscha Raleigh, RF, WJ Miller, and PC Nelson. 1986. Habitat suitability index models and instream flow suitability curves: chinook salmon. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.122). 64 pp. pdf
chinooksalmonLimit5to10CSilt Oncorhynchus tshawytscha Raleigh, RF, WJ Miller, and PC Nelson. 1986. Habitat suitability index models and instream flow suitability curves: chinook salmon. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.122). 64 pp. pdf
chinooksalmonLimitLtoe5CSand Oncorhynchus tshawytscha Raleigh, RF, WJ Miller, and PC Nelson. 1986. Habitat suitability index models and instream flow suitability curves: chinook salmon. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.122). 64 pp. pdf
chinooksalmonLimitLtoe5CSilt Oncorhynchus tshawytscha Raleigh, RF, WJ Miller, and PC Nelson. 1986. Habitat suitability index models and instream flow suitability curves: chinook salmon. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.122). 64 pp. pdf
chinooksalmonLimitMt10CSand Oncorhynchus tshawytscha Raleigh, RF, WJ Miller, and PC Nelson. 1986. Habitat suitability index models and instream flow suitability curves: chinook salmon. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.122). 64 pp. pdf
chinooksalmonLimitMt10CSilt Oncorhynchus tshawytscha Raleigh, RF, WJ Miller, and PC Nelson. 1986. Habitat suitability index models and instream flow suitability curves: chinook salmon. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.122). 64 pp. pdf
chumsalmonAlevin Oncorhynchus keta Hale, SS, TE McMahon, and PC Nelson. 1985. Habitat suitability index models and instream flow suitability curves: Chum salmon. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.108). 48 pp. pdf
chumsalmonEyedEmb Oncorhynchus keta Hale, SS, TE McMahon, and PC Nelson. 1985. Habitat suitability index models and instream flow suitability curves: Chum salmon. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.108). 48 pp. pdf
clapperrail Rallus longirostris Lewis, JC, and RL Garrison. 1983. Habitat suitability index models: clapper rail. U. S. Dept. Int. Fish Wildl. Servo FWSjOBS-82jl0.51. 15 pp. pdf
cohosalmonSpringSummerSeaMig Oncorhynchus kisutch McMahon, TE. 1983. Habitat suitability index models: Coho salmon. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.49. 29 pp pdf
cohosalmonWinterRearing Oncorhynchus kisutch McMahon, TE. 1983. Habitat suitability index models: Coho salmon. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.49. 29 pp pdf
commoncarpLacNoSal Cyprinus carpio Edwards, EA, and KA Twomey. 1982. Habitat suitability index models: Common carp. U.S. Dept. Int. Fish Wildl. Serv. FWS/OBS-82/10.12. 27 pp. pdf
commoncarpLacSal Cyprinus carpio Edwards, EA, and KA Twomey. 1982. Habitat suitability index models: Common carp. U.S. Dept. Int. Fish Wildl. Serv. FWS/OBS-82/10.12. 27 pp. pdf
commoncarpRivNoSal Cyprinus carpio Edwards, EA, and KA Twomey. 1982. Habitat suitability index models: Common carp. U.S. Dept. Int. Fish Wildl. Serv. FWS/OBS-82/10.12. 27 pp. pdf
commoncarpRivSal Cyprinus carpio Edwards, EA, and KA Twomey. 1982. Habitat suitability index models: Common carp. U.S. Dept. Int. Fish Wildl. Serv. FWS/OBS-82/10.12. 27 pp. pdf
commonshinerLac Luxilus cornutus Trial, JG, CS Wade, JG Stanley, and PC Nelson. 1983. Habitat suitability information: Common shiner. US Fish and Wildlife Service. FWS/OBS-82/10.40. 22pp. pdf
commonshinerRiv Luxilus cornutus Trial, JG, CS Wade, JG Stanley, and PC Nelson. 1983. Habitat suitability information: Common shiner. US Fish and Wildlife Service. FWS/OBS-82/10.40. 22pp. pdf
creekchubRivLargerStrmDistMt5km Semotilus atromaculatus McMahon, TE. 1982. Habitat suitability index models: Creek chub. U.S.D.I. Fish and Wildlife Service. FWS/OBS-82/10.4 23 pp. pdf
creekchubRivLargerStrmDistWithin5km Semotilus atromaculatus McMahon, TE. 1982. Habitat suitability index models: Creek chub. U.S.D.I. Fish and Wildlife Service. FWS/OBS-82/10.4 23 pp. pdf
cutthroatLacGenLtoe15C Oncorhynchus clarkii Hickman, T, and RF Raleigh. 1982. Habitat suitability index models: Cutthroat trout. U.S.D.I. Fish and Wildlife Service. FWS/OBS-82/10.5. 38 pp. pdf
cutthroatLacGenMt15C Oncorhynchus clarkii Hickman, T, and RF Raleigh. 1982. Habitat suitability index models: Cutthroat trout. U.S.D.I. Fish and Wildlife Service. FWS/OBS-82/10.5. 38 pp. pdf
cutthroatLacLahontanLtoe15C Oncorhynchus clarkii Hickman, T, and RF Raleigh. 1982. Habitat suitability index models: Cutthroat trout. U.S.D.I. Fish and Wildlife Service. FWS/OBS-82/10.5. 38 pp. pdf
cutthroatLacLahontanMt15C Oncorhynchus clarkii Hickman, T, and RF Raleigh. 1982. Habitat suitability index models: Cutthroat trout. U.S.D.I. Fish and Wildlife Service. FWS/OBS-82/10.5. 38 pp. pdf
cutthroatRivGenLtoe15CLtoe5m Oncorhynchus clarkii Hickman, T, and RF Raleigh. 1982. Habitat suitability index models: Cutthroat trout. U.S.D.I. Fish and Wildlife Service. FWS/OBS-82/10.5. 38 pp. pdf
cutthroatRivGenLtoe15CMt5m Oncorhynchus clarkii Hickman, T, and RF Raleigh. 1982. Habitat suitability index models: Cutthroat trout. U.S.D.I. Fish and Wildlife Service. FWS/OBS-82/10.5. 38 pp. pdf
cutthroatRivGenMt15CLtoe5m Oncorhynchus clarkii Hickman, T, and RF Raleigh. 1982. Habitat suitability index models: Cutthroat trout. U.S.D.I. Fish and Wildlife Service. FWS/OBS-82/10.5. 38 pp. pdf
cutthroatRivGenMt15CMt5m Oncorhynchus clarkii Hickman, T, and RF Raleigh. 1982. Habitat suitability index models: Cutthroat trout. U.S.D.I. Fish and Wildlife Service. FWS/OBS-82/10.5. 38 pp. pdf
cutthroatRivLahontanLtoe15CLtoe5m Oncorhynchus clarkii Hickman, T, and RF Raleigh. 1982. Habitat suitability index models: Cutthroat trout. U.S.D.I. Fish and Wildlife Service. FWS/OBS-82/10.5. 38 pp. pdf
cutthroatRivLahontanLtoe15CMt5m Oncorhynchus clarkii Hickman, T, and RF Raleigh. 1982. Habitat suitability index models: Cutthroat trout. U.S.D.I. Fish and Wildlife Service. FWS/OBS-82/10.5. 38 pp. pdf
cutthroatRivLahontanMt15CLtoe5m Oncorhynchus clarkii Hickman, T, and RF Raleigh. 1982. Habitat suitability index models: Cutthroat trout. U.S.D.I. Fish and Wildlife Service. FWS/OBS-82/10.5. 38 pp. pdf
cutthroatRivLahontanMt15CMt5m Oncorhynchus clarkii Hickman, T, and RF Raleigh. 1982. Habitat suitability index models: Cutthroat trout. U.S.D.I. Fish and Wildlife Service. FWS/OBS-82/10.5. 38 pp. pdf
diamondbackterrapinNesting Malaclemys terrapin Palmer, WM, and CL Cordes. 1988. Habitat suitability index models: Diamondback terrapin (nesting)–Atlantic coast. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.151). 18 pp. pdf
downywoodpecker Picoides pubescens Schroeder, RL. 1982. Habitat suitability index models: Downy woodpecker. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.38. 10 pp. pdf
easternbrownpelican Pelecanus occidentalis carolinensis Hingtgen, TM, R Mulholland, and AV Zale. 1985. Habitat suitability index models: eastern brown pelican. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.90). 20 pp. pdf
easterncottontail Sylvilagus floridanus Allen, AW. 1984. Habitat suitability index models: Eastern cottontail. U.S. Fish Wildl. Serv. FWS/OBS-82/10.66. 23 pp. pdf
easternmeadowlark Sturnella magna Schroeder, RL, and PJ Sousa. 1982. Habitat suitability index models: Eastern meadowlark. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.29. 9 pp. pdf
easternwildturkeyCroplandHerb Meleagris gallopavo sylvestris Schroeder, RL. 1985. Habitat suitability index models: Eastern wild turkey. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.106). 33 pp. pdf
easternwildturkeyCroplandShrub Meleagris gallopavo sylvestris Schroeder, RL. 1985. Habitat suitability index models: Eastern wild turkey. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.106). 33 pp. pdf
easternwildturkeyForestHardDBH25.4cm Meleagris gallopavo sylvestris Schroeder, RL. 1985. Habitat suitability index models: Eastern wild turkey. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.106). 33 pp. pdf
easternwildturkeyForestHardDBH27.9cm Meleagris gallopavo sylvestris Schroeder, RL. 1985. Habitat suitability index models: Eastern wild turkey. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.106). 33 pp. pdf
easternwildturkeyForestHardDBH30.5cm Meleagris gallopavo sylvestris Schroeder, RL. 1985. Habitat suitability index models: Eastern wild turkey. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.106). 33 pp. pdf
easternwildturkeyForestHardDBH33.0cm Meleagris gallopavo sylvestris Schroeder, RL. 1985. Habitat suitability index models: Eastern wild turkey. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.106). 33 pp. pdf
easternwildturkeyForestHardDBH35.6cm Meleagris gallopavo sylvestris Schroeder, RL. 1985. Habitat suitability index models: Eastern wild turkey. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.106). 33 pp. pdf
easternwildturkeyForestHardDBH38.1cm Meleagris gallopavo sylvestris Schroeder, RL. 1985. Habitat suitability index models: Eastern wild turkey. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.106). 33 pp. pdf
easternwildturkeyHerb Meleagris gallopavo sylvestris Schroeder, RL. 1985. Habitat suitability index models: Eastern wild turkey. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.106). 33 pp. pdf
easternwildturkeyShrub Meleagris gallopavo sylvestris Schroeder, RL. 1985. Habitat suitability index models: Eastern wild turkey. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.106). 33 pp. pdf
englishsoleJuv Parophrys vetulus Toole, CL, RA Barnhart, and CP Onuf. 1987. Habitat suitability index models: juvenile English sole. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.133). 27 pp. pdf
englishsoleJuvImpactAlt Parophrys vetulus Toole, CL, RA Barnhart, and CP Onuf. 1987. Habitat suitability index models: juvenile English sole. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.133). 27 pp. pdf
fallfishLac Semotilus corporalis Trial, JG, CS Wade, JG Stanley, and PC Nelson. 1983. Habitat suitability information: Fallfish. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.48. 15 pp. pdf
fallfishRivNoSpwn Semotilus corporalis Trial, JG, CS Wade, JG Stanley, and PC Nelson. 1983. Habitat suitability information: Fallfish. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.48. 15 pp. pdf
fallfishRivSpwn Semotilus corporalis Trial, JG, CS Wade, JG Stanley, and PC Nelson. 1983. Habitat suitability information: Fallfish. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.48. 15 pp. pdf
ferruginoushawkCrop Buteo regalis Jasikoff, TM. 1982. Habitat suitability index models: Ferruginous hawk. U.S.D.I. Fish and Wildlife Service. FWS/OBS-82/10.10. 18 pp. pdf
ferruginoushawkHerbAndShrub Buteo regalis Jasikoff, TM. 1982. Habitat suitability index models: Ferruginous hawk. U.S.D.I. Fish and Wildlife Service. FWS/OBS-82/10.10. 18 pp. pdf
fieldsparrow Spizella pusilla Sousa, PJ. 1983. Habitat suitability index models: Field sparrow. U.S. Fish Wildl. Serv. FWS/OBS-82/10.62. 14 pp. pdf
fisherWinterCov Pekania pennanti Allen, AW. 1983. Habitat suitability index models: Fisher. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.45. 19 pp pdf
flatheadcatfishMacro Pylodictis olivaris Lee, LA, and JW Terrell. 1987. Habitat suitability index models: Flathead catfish. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.152). 39pp. pdf
flounderGulf Paralichthys albigutta Enge, KM, and R Mulholland. 1985. Habitat suitability index models: southern and gulf flounders. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.92). 25 pp pdf
flounderSouthern Paralichthys albigutta Enge, KM, and R Mulholland. 1985. Habitat suitability index models: southern and gulf flounders. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.92). 25 pp pdf
forstersternBreeding Sterna forsteri Martin, RP, and PJ Zwank. 1987. Habitat suitability index models: Forster’s tern (breeding)–Gulf and Atlantic coasts. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.131). 21 pp. pdf
foxsquirrel Sciurus niger Allen, AW. 1982. Habitat suitability index models: fox squirrel. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.18. 11 pp. pdf
gadwallBreeding Anas strepera Sousa, PJ. 1985. Habitat suitability index models: Gadwall (breeding). U.S. Fish Wildl. Serv. Biol. Rep. 82(10.100). 35 pp. pdf
gizzardshadLacNoTributaries Dorosoma cepedianum Williamson, KL, and PC Nelson. 1985. Habitat suitability index models and instream flow suitability curves: Gizzard shad. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.112). 33 pp. pdf
gizzardshadLacSpwnTributaries Dorosoma cepedianum Williamson, KL, and PC Nelson. 1985. Habitat suitability index models and instream flow suitability curves: Gizzard shad. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.112). 33 pp. pdf
graypartridge Perdix perdix Allen, AW. 1984. Habitat suitability index models: Gray partridge. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.73). 23 pp. pdf
graysquirrel Sciurus carolinensis Allen, AW. 1987. Habitat suitability index models: gray squirrel, revised. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.135). 16 pp. [First printed as: FWS/OBS-82/10.19. July 1982.] pdf
greatblueheron Ardea herodias Short, HL, and RJ Cooper. 1985. Habitat suitability index models: Great blue heron. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.99). 23 pp. pdf
greategretFeeding Ardea alba Chapman, BR, and RJ Howard. 1984. Habitat suitability index models: great egret. U.S. Fish Wildl. Serv. FWS/OBS-82/10.78. 23 pp. pdf
greategretNestingIsland Ardea alba Chapman, BR, and RJ Howard. 1984. Habitat suitability index models: great egret. U.S. Fish Wildl. Serv. FWS/OBS-82/10.78. 23 pp. pdf
greategretNestingNonisland Ardea alba Chapman, BR, and RJ Howard. 1984. Habitat suitability index models: great egret. U.S. Fish Wildl. Serv. FWS/OBS-82/10.78. 23 pp. pdf
greaterprairiechickenHarvested Tympanuchus cupido pinnatus Prose, BL. 1985. Habitat suitability index models: Greater prairie-chicken (multiple levels of resolution). U.S. Fish Wildl. Serv. Biiol. Rep. 82(10.102). 33 pp. pdf
greaterprairiechickenUnharvested Tympanuchus cupido pinnatus Prose, BL. 1985. Habitat suitability index models: Greater prairie-chicken (multiple levels of resolution). U.S. Fish Wildl. Serv. Biiol. Rep. 82(10.102). 33 pp. pdf
greatersandhillcraneLt200ha Grus canadensis tabida Armbruster, MJ. 1987. Habitat suitability index models: greater sandhill crane. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.140). 26 pp pdf
greatersandhillcraneMtoe200ha Grus canadensis tabida Armbruster, MJ. 1987. Habitat suitability index models: greater sandhill crane. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.140). 26 pp pdf
greaterwhitefrontedgooseWinteringWetland Anser albinfrons Kaminski, RM. 1986. Habitat suitability index models: greater white-fronted goose (wintering). U.S. Fish Wildl. Serv. Biol. Rep. 82(10.116). 14 pp. pdf
greensunfishLac Lepomis cyanellus Stuber, RJ, G Gebhart, and OE Maughan. 1982. Habitat suitability index models: Green sunfish. U.S. Dept. Int. Fish Wildl. Serv. FWS/OBS-82/10.15. 28 pp pdf
greensunfishRiv Lepomis cyanellus Stuber, RJ, G Gebhart, and OE Maughan. 1982. Habitat suitability index models: Green sunfish. U.S. Dept. Int. Fish Wildl. Serv. FWS/OBS-82/10.15. 28 pp pdf
greensunfishRivSal Lepomis cyanellus Stuber, RJ, G Gebhart, and OE Maughan. 1982. Habitat suitability index models: Green sunfish. U.S. Dept. Int. Fish Wildl. Serv. FWS/OBS-82/10.15. 28 pp pdf
gulfmenhadenEstuary Brevoortia patronus Christmas, JY, JT McBee, RS Waller, and FC Scutter III. 1982. Habitat suitability index models: Gulf menhaden. U.S. Dept. Int. Fish Wildl. Serv. FWS/OBS-82/10.23. 23 pp. pdf
gulfmenhadenMarine Brevoortia patronus Christmas, JY, JT McBee, RS Waller, and FC Scutter III. 1982. Habitat suitability index models: Gulf menhaden. U.S. Dept. Int. Fish Wildl. Serv. FWS/OBS-82/10.23. 23 pp. pdf
hairywoodpecker Dryobates villosus Sousa, PJ. 1987. Habitat suitability index models: hairy woodpecker. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.146). 19 pp. pdf
hardclam Mercenaria campechiensis and Mercenaria mercenaria Mulholland, R. 1984. Habitat suitability index models: hard clam. U.S. Fish Wildl. Serv. FWS/OBS-82/10.77. 21 pp pdf
inlandsilversideNoZooplankton Menidia beryllina Weinstein, MP. 1986. Habitat suitability index models: Inland silverside. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.120). 25 pp. pdf
inlandsilversideZooplankton Menidia beryllina Weinstein, MP. 1986. Habitat suitability index models: Inland silverside. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.120). 25 pp. pdf
laketroutReproducingLakes Salvelinus namaycush Marcus, MD, WA Hubert, and SH Anderson. 1984. Habitat suitability index models: Lake trout (Exclusive of the Great Lakes). U.S. Fish Wildl. Serv. FWS/OBS-82/10.84. 12 pp. pdf
laketroutReproducingRes Salvelinus namaycush Marcus, MD, WA Hubert, and SH Anderson. 1984. Habitat suitability index models: Lake trout (Exclusive of the Great Lakes). U.S. Fish Wildl. Serv. FWS/OBS-82/10.84. 12 pp. pdf
laketroutStocked Salvelinus namaycush Marcus, MD, WA Hubert, and SH Anderson. 1984. Habitat suitability index models: Lake trout (Exclusive of the Great Lakes). U.S. Fish Wildl. Serv. FWS/OBS-82/10.84. 12 pp. pdf
largemouthbassLacN Micropterus salmoides Stuber, RJ, G Gebhart, and OE Maughan. 1982. Habitat suitability index models: Largemouth bass. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.16. 32 pp. pdf
largemouthbassLacS Micropterus salmoides Stuber, RJ, G Gebhart, and OE Maughan. 1982. Habitat suitability index models: Largemouth bass. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.16. 32 pp. pdf
largemouthbassRivGrad Micropterus salmoides Stuber, RJ, G Gebhart, and OE Maughan. 1982. Habitat suitability index models: Largemouth bass. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.16. 32 pp. pdf
largemouthbassRivVel Micropterus salmoides Stuber, RJ, G Gebhart, and OE Maughan. 1982. Habitat suitability index models: Largemouth bass. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.16. 32 pp. pdf
larkbunting Calamospiza melanocorys Finch, DM, SH Anderson, and WA Hubert. 1987. Habitat suitability index models: lark bunting. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.137). 16 pp. pdf
laughinggull Leucophaeus atricilla Zale, AV, and R Mulholland. 1985. Habitat suitability index models: laughing gull. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.94). 23 pp. pdf
leastternVegCovLt15OrMt25pct Sterna antillarum Carreker, RG. 1985. Habitat suitability index models: Least tern. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.103). 29 pp. pdf
leastternVegCovMtoe15OrLtoe25pct Sterna antillarum Carreker, RG. 1985. Habitat suitability index models: Least tern. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.103). 29 pp. pdf
lesserscaupBreeding Aythya affinis Allen, AW. 1986. Habitat suitability index models: Lesser scaup (breeding). U.S. Fish Wildl. Serv. Biol. Rep. 82(10.117). 16 pp. pdf
lesserscaupWintering Aythya affinis Mulholland, R. 1985. Habitat suitability index models: lesser scaup (wintering). U.S. Fish Wildl. Serv. Biol. Rep. 82(10.91). 15 pp. pdf
lessersnowgooseWintering Anser caerulescens Leslie, JC, and PJ Zwank. 1985. Habitat suitability index models: lesser snow goose (wintering). U.S. Fish Wildl. Serv. Biol. Rep. 82(10.97). 16 pp. pdf
lewiswoodpeckerSummerDeciduousDesertic Melanerpes lewis Sousa, PJ. 1982. Habitat suitability index models: Lewis’s woodpecker. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.32. 14 pp. pdf
lewiswoodpeckerSummerEvergreen Melanerpes lewis Sousa, PJ. 1982. Habitat suitability index models: Lewis’s woodpecker. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.32. 14 pp. pdf
lewiswoodpeckerWinterCropland Melanerpes lewis Sousa, PJ. 1982. Habitat suitability index models: Lewis’s woodpecker. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.32. 14 pp. pdf
lewiswoodpeckerWinterNotEForC Melanerpes lewis Sousa, PJ. 1982. Habitat suitability index models: Lewis’s woodpecker. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.32. 14 pp. pdf
lewiswoodpeckerYearRoundDeciduousDesertic Melanerpes lewis Sousa, PJ. 1982. Habitat suitability index models: Lewis’s woodpecker. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.32. 14 pp. pdf
lewiswoodpeckerYearRoundEvergreen Melanerpes lewis Sousa, PJ. 1982. Habitat suitability index models: Lewis’s woodpecker. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.32. 14 pp. pdf
littleneckclam Protothaca staminea Rodnick, K, and HW Li. 1983. Habitat suitability index models: littleneck clam. U.S. Dept. Int. Fish Wildl. Serv. FWS/OBS-82/10.59. 15 pp. pdf
longnosedaceLac Rhinichthys cataractae Edwards, EA, H Li, and CB Schreck. 1983. Habitat suitability index models: Longnose dace. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.33. 13 pp. pdf
longnosedaceRiv Rhinichthys cataractae Edwards, EA, H Li, and CB Schreck. 1983. Habitat suitability index models: Longnose dace. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.33. 13 pp. pdf
longnosesuckerLac Catostomus catostomus Edwards, EA. 1983. Habitat suitability index models: Longnose sucker. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/1-.35. 21 pp. pdf
longnosesuckerRiv Catostomus catostomus Edwards, EA. 1983. Habitat suitability index models: Longnose sucker. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/1-.35. 21 pp. pdf
mallardCroplandCorn Anas platyrhynchos Allen, AW. 1986. Habitat suitablity index models: mallard (winter habitat, Lower Mississippi Valley). U.S. Fish Wildl. Serv. Biol. Rep. 82(10.132). 37 pp. pdf
mallardCroplandOtherCrops Anas platyrhynchos Allen, AW. 1986. Habitat suitablity index models: mallard (winter habitat, Lower Mississippi Valley). U.S. Fish Wildl. Serv. Biol. Rep. 82(10.132). 37 pp. pdf
mallardCroplandSoy Anas platyrhynchos Allen, AW. 1986. Habitat suitablity index models: mallard (winter habitat, Lower Mississippi Valley). U.S. Fish Wildl. Serv. Biol. Rep. 82(10.132). 37 pp. pdf
mallardForestedPaluWetlands Anas platyrhynchos Allen, AW. 1986. Habitat suitablity index models: mallard (winter habitat, Lower Mississippi Valley). U.S. Fish Wildl. Serv. Biol. Rep. 82(10.132). 37 pp. pdf
mallardNonforestedPaluLacRiv Anas platyrhynchos Allen, AW. 1986. Habitat suitablity index models: mallard (winter habitat, Lower Mississippi Valley). U.S. Fish Wildl. Serv. Biol. Rep. 82(10.132). 37 pp. pdf
marshwren Cistothorus palustris Gutzwiller, KJ, and SH Anderson. 1987. Habitat suitability index models: marsh wren. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.139). 13 pp. pdf
marten Martes americana Allen, AW. 1982. Habitat suitability index models: Marten. U.S.D.I. Fish and Wildlife Service. FWS/OBS-82/10.11. 9 pp. pdf
minkPaluEmergHerb Mustela vison Allen, AW. 1986. Habitat suitability index models: mink, revised. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.127). 23 pp. [First printed as: FWS/OBS-82/10.61, October 1983.] pdf
minkPaluForestedOrShrubLess405ha Mustela vison Allen, AW. 1986. Habitat suitability index models: mink, revised. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.127). 23 pp. [First printed as: FWS/OBS-82/10.61, October 1983.] pdf
minkPaluForestedOrShrubMore405ha Mustela vison Allen, AW. 1986. Habitat suitability index models: mink, revised. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.127). 23 pp. [First printed as: FWS/OBS-82/10.61, October 1983.] pdf
minkRivLac Mustela vison Allen, AW. 1986. Habitat suitability index models: mink, revised. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.127). 23 pp. [First printed as: FWS/OBS-82/10.61, October 1983.] pdf
mooseLakeSupModelII Alces alces Allen, AW, PA Jordan, and JW Terrell. 1987. Habitat suitability index models: moose, Lake Superior region. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.155). 47 pp. pdf
mottledduckAny Anas fulvigula maculosa Rorabaugh, JE, and PJ Zwank. 1983. Habitat suitability index models: mottled duck. U.S. Dept. Int. Fish Wildl. Service FWS/OBS-82/10.5226 pp. pdf
mottledduckBrood Anas fulvigula maculosa Rorabaugh, JE, and PJ Zwank. 1983. Habitat suitability index models: mottled duck. U.S. Dept. Int. Fish Wildl. Service FWS/OBS-82/10.5226 pp. pdf
mottledduckNesting Anas fulvigula maculosa Rorabaugh, JE, and PJ Zwank. 1983. Habitat suitability index models: mottled duck. U.S. Dept. Int. Fish Wildl. Service FWS/OBS-82/10.5226 pp. pdf
muskellungeLargeLakeSpwnVegCurveA Esox masquinongy Cook, MF, and RC Solomon. 1987. Habitat suitability index models: Muskellunge. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.148). 33 pp. pdf
muskellungeLargeLakeSpwnVegCurveB Esox masquinongy Cook, MF, and RC Solomon. 1987. Habitat suitability index models: Muskellunge. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.148). 33 pp. pdf
muskellungeLargeLakeSpwnVegCurveC Esox masquinongy Cook, MF, and RC Solomon. 1987. Habitat suitability index models: Muskellunge. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.148). 33 pp. pdf
muskellungeLargeLakeSpwnVegCurveD Esox masquinongy Cook, MF, and RC Solomon. 1987. Habitat suitability index models: Muskellunge. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.148). 33 pp. pdf
muskellungeSmallLakeSpwnVegCurveA Esox masquinongy Cook, MF, and RC Solomon. 1987. Habitat suitability index models: Muskellunge. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.148). 33 pp. pdf
muskellungeSmallLakeSpwnVegCurveB Esox masquinongy Cook, MF, and RC Solomon. 1987. Habitat suitability index models: Muskellunge. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.148). 33 pp. pdf
muskellungeSmallLakeSpwnVegCurveC Esox masquinongy Cook, MF, and RC Solomon. 1987. Habitat suitability index models: Muskellunge. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.148). 33 pp. pdf
muskellungeSmallLakeSpwnVegCurveD Esox masquinongy Cook, MF, and RC Solomon. 1987. Habitat suitability index models: Muskellunge. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.148). 33 pp. pdf
muskratEstu Ondatra zibethicus Allen, AW, and RD Hoffman. 1984. Habitat suitability index models: Muskrat. U.S. Fish Wildl. Serv. FWS/OBS-82/10.46. 27 pp. pdf
muskratHW Ondatra zibethicus Allen, AW, and RD Hoffman. 1984. Habitat suitability index models: Muskrat. U.S. Fish Wildl. Serv. FWS/OBS-82/10.46. 27 pp. pdf
muskratRiv Ondatra zibethicus Allen, AW, and RD Hoffman. 1984. Habitat suitability index models: Muskrat. U.S. Fish Wildl. Serv. FWS/OBS-82/10.46. 27 pp. pdf
northernbobwhiteCroplands Colinus virginianus Schroeder, RL. 1985. Habitat suitability index models: Northern bobwhite. U.S. Fish Wildl. Serv. Biol. Rep. 82 (10.104). 32 pp. pdf
northernbobwhiteDbh25.4cm Colinus virginianus Schroeder, RL. 1985. Habitat suitability index models: Northern bobwhite. U.S. Fish Wildl. Serv. Biol. Rep. 82 (10.104). 32 pp. pdf
northernbobwhiteDbh27.9cm Colinus virginianus Schroeder, RL. 1985. Habitat suitability index models: Northern bobwhite. U.S. Fish Wildl. Serv. Biol. Rep. 82 (10.104). 32 pp. pdf
northernbobwhiteDbh30.5cm Colinus virginianus Schroeder, RL. 1985. Habitat suitability index models: Northern bobwhite. U.S. Fish Wildl. Serv. Biol. Rep. 82 (10.104). 32 pp. pdf
northernbobwhiteDbh33.0cm Colinus virginianus Schroeder, RL. 1985. Habitat suitability index models: Northern bobwhite. U.S. Fish Wildl. Serv. Biol. Rep. 82 (10.104). 32 pp. pdf
northernbobwhiteDbh35.6cm Colinus virginianus Schroeder, RL. 1985. Habitat suitability index models: Northern bobwhite. U.S. Fish Wildl. Serv. Biol. Rep. 82 (10.104). 32 pp. pdf
northernbobwhiteDbh38.1cm Colinus virginianus Schroeder, RL. 1985. Habitat suitability index models: Northern bobwhite. U.S. Fish Wildl. Serv. Biol. Rep. 82 (10.104). 32 pp. pdf
northernbobwhiteShrub Colinus virginianus Schroeder, RL. 1985. Habitat suitability index models: Northern bobwhite. U.S. Fish Wildl. Serv. Biol. Rep. 82 (10.104). 32 pp. pdf
northernpikeLacVegA Esox lucius Inskip, PD. 1982. Habitat suitability index models: Northern pike. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.17. 40 pp. pdf
northernpikeLacVegB Esox lucius Inskip, PD. 1982. Habitat suitability index models: Northern pike. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.17. 40 pp. pdf
northernpikeLacVegC Esox lucius Inskip, PD. 1982. Habitat suitability index models: Northern pike. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.17. 40 pp. pdf
northernpikeLacVegD Esox lucius Inskip, PD. 1982. Habitat suitability index models: Northern pike. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.17. 40 pp. pdf
northernpikeRivVegA Esox lucius Inskip, PD. 1982. Habitat suitability index models: Northern pike. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.17. 40 pp. pdf
northernpikeRivVegB Esox lucius Inskip, PD. 1982. Habitat suitability index models: Northern pike. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.17. 40 pp. pdf
northernpikeRivVegC Esox lucius Inskip, PD. 1982. Habitat suitability index models: Northern pike. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.17. 40 pp. pdf
northernpikeRivVegD Esox lucius Inskip, PD. 1982. Habitat suitability index models: Northern pike. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.17. 40 pp. pdf
northernpintail Anas acuta Suchy, WJ, and SH Anderson. 1987. Habitat suitability index models: northern pintail. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.145) 23 pp. pdf
northernpintailWinteringGulfCoastPaluLacEstuLtoe5ppt Anas acuta Howard, RJ, and HA Kantrud. 1986. Habitat suitability index models: northern pintail (gulf coast wintering). U.S. Fish Wildl. Serv. Biol. Rep. 82(10.121). 16 pp. pdf
northernpintailWinteringGulfPaluLacEstuMt5ppt Anas acuta Howard, RJ, and HA Kantrud. 1986. Habitat suitability index models: northern pintail (gulf coast wintering). U.S. Fish Wildl. Serv. Biol. Rep. 82(10.121). 16 pp. pdf
ospreyLac Pandion haliaetus Vana-Miller, SL. 1987. Habitat suitability index models: osprey. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.154). 46 pp. pdf
ospreyRiv Pandion haliaetus Vana-Miller, SL. 1987. Habitat suitability index models: osprey. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.154). 46 pp. pdf
paddlefishAdSummerandWinterHab Polyodon spathula Hubert, WA, SH Anderson, PD Southhall, and JH Crance. 1984. Habitat suitability index models and instream flow suitability curves: Paddlefish. U.S. Fish Wildl. Serv. FWS/OBS-82/10.80. 32 pp. pdf
paddlefishSpwnHab Polyodon spathula Hubert, WA, SH Anderson, PD Southhall, and JH Crance. 1984. Habitat suitability index models and instream flow suitability curves: Paddlefish. U.S. Fish Wildl. Serv. FWS/OBS-82/10.80. 32 pp. pdf
pileatedwoodpeckerE Dryocopus pileatus Schroeder, RL. 1982. Habitat suitability index models: Pileated woodpecker. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.39. 15 pp. pdf
pileatedwoodpeckerW Dryocopus pileatus Schroeder, RL. 1982. Habitat suitability index models: Pileated woodpecker. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.39. 15 pp. pdf
pinewarbler Setophaga pinus Schroeder, RL. 1982. Habitat suitability index models: pine warbler. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.28. 8 pp. pdf
pinksalmonLimit Oncorhynchus gorbuscha Raleigh, RF, and PC Nelson. 1985. Habitat suitability index models and instream flow suitability curves: Pink salmon. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.109). 36 pp. pdf
pinkshrimpEmergAndSeagrassVeg Farfantepenaeus duorarum Mulholland, R. 1984. Habitat suitability index models: pink shrimp. U.S. Fish Wildl. Serv. FWS/OBS-82/10.76. 17 pp. pdf
pinkshrimpEmergVeg Farfantepenaeus duorarum Mulholland, R. 1984. Habitat suitability index models: pink shrimp. U.S. Fish Wildl. Serv. FWS/OBS-82/10.76. 17 pp. pdf
pinkshrimpSeagrassVeg Farfantepenaeus duorarum Mulholland, R. 1984. Habitat suitability index models: pink shrimp. U.S. Fish Wildl. Serv. FWS/OBS-82/10.76. 17 pp. pdf
plainssharptailedgrouse Tympanuchus phasianellus jamesi Prose, BL. 1987. Habitat suitability index models: plains sharp-tailed grouse. U.S. Fish Wilsl. Serv. Biol. Rep. 82(10.142). 31 pp. pdf
pronghorn Antilocapra americana Allen, AW, JG Cook, and MJ Armbruster. 1984. Habitat suitability index models: Pronghorn. U.S. Fish Wildl. Serv. FWS/OBS-82/10. 65. 22 pp. pdf
rainbowtroutLac Oncorhynchus mykiss Raleigh, RF, T Hickman, RC Solomon, and PC Nelson. 1984. Habitat suitability information: Rainbow trout. U.S. Fish Wildl. Serv. FWS/OBS-82/10.60. 64 pp. pdf
rainbowtroutRiv Oncorhynchus mykiss Raleigh, RF, T Hickman, RC Solomon, and PC Nelson. 1984. Habitat suitability information: Rainbow trout. U.S. Fish Wildl. Serv. FWS/OBS-82/10.60. 64 pp. pdf
redbreastsunfishLacN Lepomis auritus Aho, JM, CS Anderson, and JW Terrell. 1986. Habitat suitability index models and instream flow suitability curves: redbreast sunfish. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.119). 23 pp pdf
redbreastsunfishLacS Lepomis auritus Aho, JM, CS Anderson, and JW Terrell. 1986. Habitat suitability index models and instream flow suitability curves: redbreast sunfish. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.119). 23 pp pdf
redbreastsunfishPalu Lepomis auritus Aho, JM, CS Anderson, and JW Terrell. 1986. Habitat suitability index models and instream flow suitability curves: redbreast sunfish. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.119). 23 pp pdf
redbreastsunfishRiv Lepomis auritus Aho, JM, CS Anderson, and JW Terrell. 1986. Habitat suitability index models and instream flow suitability curves: redbreast sunfish. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.119). 23 pp pdf
reddrumLarvJuvEstuLittleSubmVeg Sciaenops ocellatus Buckley, J. 1984. Habitat suitability index models: larval and juvenile red drum. U.S. Fish Wildl. Serv. FWS/OBS-82/10.74. 15 pp. pdf
reddrumLarvJuvEstuSubmVeg Sciaenops ocellatus Buckley, J. 1984. Habitat suitability index models: larval and juvenile red drum. U.S. Fish Wildl. Serv. FWS/OBS-82/10.74. 15 pp. pdf
redearsunfishLac Lepomis microlophus Twomey, KA, G Gebhart, OE Maughan, and PC Nelson. 1984. Habitat suitability index models and instream flow suitability curves: Redear sunfish. U.S. Fish Wildl. Serv. FWS/OBS-82/10.79. 29 pp. pdf
redearsunfishRiv Lepomis microlophus Twomey, KA, G Gebhart, OE Maughan, and PC Nelson. 1984. Habitat suitability index models and instream flow suitability curves: Redear sunfish. U.S. Fish Wildl. Serv. FWS/OBS-82/10.79. 29 pp. pdf
redheadWinteringWtrAvailable Aythya americana Howard, RJ, and HA Kantrud. 1983. Habitat suitability index models: redhead (wintering). U.S. Dept. Int. Fish Wildl. Serv. FWS/OBS-82/10.53. 14 pp pdf
redheadWinteringWtrNotAvailable Aythya americana Howard, RJ, and HA Kantrud. 1983. Habitat suitability index models: redhead (wintering). U.S. Dept. Int. Fish Wildl. Serv. FWS/OBS-82/10.53. 14 pp pdf
redkingcrabJuv1to4 Paralithodes camtschaticus Jewett, SC, and CP Onuf. 1988. Habitat suitability index models: red king crab. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.153). 34 pp. pdf
redkingcrabJuv4PlusandAd Paralithodes camtschaticus Jewett, SC, and CP Onuf. 1988. Habitat suitability index models: red king crab. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.153). 34 pp. pdf
redkingcrabLarv Paralithodes camtschaticus Jewett, SC, and CP Onuf. 1988. Habitat suitability index models: red king crab. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.153). 34 pp. pdf
redkingcrabYoungofYrJuv Paralithodes camtschaticus Jewett, SC, and CP Onuf. 1988. Habitat suitability index models: red king crab. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.153). 34 pp. pdf
redspottednewtAquatic150m Notophthalmus viridescens viridescens Sousa, PJ. 1985. Habitat suitability index models: Red-spotted newt. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.111). 18 pp. pdf
redspottednewtAquaticEntire Notophthalmus viridescens viridescens Sousa, PJ. 1985. Habitat suitability index models: Red-spotted newt. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.111). 18 pp. pdf
redspottednewtTerrestrial Notophthalmus viridescens viridescens Sousa, PJ. 1985. Habitat suitability index models: Red-spotted newt. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.111). 18 pp. pdf
redwingedblackbirdA Agelaius phoeniceus Short, HL. 1985. Habitat suitability index models: Red-winged blackbird. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.95). 20 pp. pdf
redwingedblackbirdB Agelaius phoeniceus Short, HL. 1985. Habitat suitability index models: Red-winged blackbird. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.95). 20 pp. pdf
redwingedblackbirdC Agelaius phoeniceus Short, HL. 1985. Habitat suitability index models: Red-winged blackbird. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.95). 20 pp. pdf
roseatespoonbillIslandFuture Platalea ajaja Lewis, JC. 1983. Habitat suitabililty index models: roseate spoonbill. U.S. Dept. Int. Fish. Wildl. Serv. FWS/OBS-82/10.50. 16 pp. pdf
roseatespoonbillIslandPresent Platalea ajaja Lewis, JC. 1983. Habitat suitabililty index models: roseate spoonbill. U.S. Dept. Int. Fish. Wildl. Serv. FWS/OBS-82/10.50. 16 pp. pdf
roseatespoonbillMainlandFuture Platalea ajaja Lewis, JC. 1983. Habitat suitabililty index models: roseate spoonbill. U.S. Dept. Int. Fish. Wildl. Serv. FWS/OBS-82/10.50. 16 pp. pdf
roseatespoonbillMainlandPresent Platalea ajaja Lewis, JC. 1983. Habitat suitabililty index models: roseate spoonbill. U.S. Dept. Int. Fish. Wildl. Serv. FWS/OBS-82/10.50. 16 pp. pdf
ruffedgrouse Bonasa umbellus Cade, BS, and PJ Sousa. 1985. Habitat suitability index models: Ruffed grouse. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.86). 31 pp. pdf
shortnosesturgeon Acipenser brevirostrum Crance, JH. 1986. Habitat suitability index models and instream flow suitability curves: Shortnose sturgeon. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.129). 31 pp. pdf
sliderturtle Trachemys scripta Morreale, SJ, and JW Gibbons. 1986. Habitat suitability index models: Slider turtle. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.125). 14 pp. pdf
sloughdarterLac Etheostoma gracile Edwards, EA, M Bacteller, and OE Maughan. 1982. Habitat suitability index models: Slough darter. U.S.D.I. Fish and Wildlife Service. FWS/OBS-82/10.9. 13 pp. pdf
sloughdarterRiv Etheostoma gracile Edwards, EA, M Bacteller, and OE Maughan. 1982. Habitat suitability index models: Slough darter. U.S.D.I. Fish and Wildlife Service. FWS/OBS-82/10.9. 13 pp. pdf
smallmouthbassLac Micropterus dolomieu Edwards, EA, G Gebhart, and OE Maughan. 1983. Habitat suitability information: Smallmouth bass. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.36. 47 pp. pdf
smallmouthbassRiv Micropterus dolomieu Edwards, EA, G Gebhart, and OE Maughan. 1983. Habitat suitability information: Smallmouth bass. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.36. 47 pp. pdf
smallmouthbuffaloLac Ictiobus bubalus Edwards, EA, and K Twomey. 1982. Habitat suitability index models: Smallmouth buffalo. U.S. Dept. Int. Fish Wildl. Serv. FWS/OBS-82/10.13. 28 pp. pdf
smallmouthbuffaloRiv Ictiobus bubalus Edwards, EA, and K Twomey. 1982. Habitat suitability index models: Smallmouth buffalo. U.S. Dept. Int. Fish Wildl. Serv. FWS/OBS-82/10.13. 28 pp. pdf
snappingturtle Chelydra serpentina Graves, BM, and SH Anderson. 1987. Habitat suitability index models: snapping turtle. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.141). 18 pp. pdf
snowshoehareForageBiomass Lepus americanus Carreker, RG. 1985. Habitat suitability index models: Snowshoe hare. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.101). 21 pp. pdf
snowshoehareForageVisual Lepus americanus Carreker, RG. 1985. Habitat suitability index models: Snowshoe hare. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.101). 21 pp. pdf
southernkingfishEstu Menticirrhus americanus Sikora, WB, and JP Sikora. 1982. Habitat suitability index models: Southern kingfish. U.S. Dept. Int. Fish Wildl. Serv. FWS/OBS-82/10.31. 22 pp. pdf
southernkingfishMarine Menticirrhus americanus Sikora, WB, and JP Sikora. 1982. Habitat suitability index models: Southern kingfish. U.S. Dept. Int. Fish Wildl. Serv. FWS/OBS-82/10.31. 22 pp. pdf
southernredbackedvole Clethrionomys gapperi Allen, AW. 1983. Habitat suitability index models: Southern red-backed vole (Western United States). U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.42. 14 pp. pdf
spotJuv Leiostomus xanthurus Stickney, RR, and ML Cuenco. 1982. Habitat suitability index models: Juvenile spot. U.S. Dept. Int. Fish Wildl. Serv. FWS/OBS-82/10.20. 12 pp. pdf
spottedbassLac Micropterus punctulatus McMahon, TE, G Gebhart, OE Maughan, and PC Nelson. 1984. Habitat suitability index models and instream flow suitability curves: Spotted bass. U.S. Fish Wildl. Serv. FWS/OBS-82/10.72. 41 pp. pdf
spottedbassRiv Micropterus punctulatus McMahon, TE, G Gebhart, OE Maughan, and PC Nelson. 1984. Habitat suitability index models and instream flow suitability curves: Spotted bass. U.S. Fish Wildl. Serv. FWS/OBS-82/10.72. 41 pp. pdf
spottedowl Strix occidentalis Laymon, SA, H Salwasser, and RH Barrett. 1985. Habitat suitability index models: Spotted owl. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.113) 14 pp. pdf
spottedseatrout Cynoscion nebulosus Kostecki, PT. 1984. Habitat suitability index models: spotted seatrout. U.S.Fish Wildl. Serv. FWS/OBS-82/10.75. 22 pp. pdf
steelheadtroutRiv Oncorhynchus mykiss Raleigh, RF, T Hickman, RC Solomon, and PC Nelson. 1984. Habitat suitability information: Rainbow trout. U.S. Fish Wildl. Serv. FWS/OBS-82/10.60. 64 pp. pdf
stripedbassCoastal Morone saxatilis Bain, MB, and JL Bain. 1982. Habitat suitability index models: Coastal stocks of striped bass. U.S. Fish and Wildlife Service, Office of Biological Services, Washington, D.C. FWS/OBS-82/10.1. 29 pp. pdf
stripedbassInlandLacAd Morone saxatilis Crance, JH. 1984. Habitat suitability index models and instream flow suitability curves: Inland stocks of striped bass. U.S. Fish Wildl. Serv. FWS/OBS-82/10.85. 63 pp. pdf
stripedbassInlandLacJuv Morone saxatilis Crance, JH. 1984. Habitat suitability index models and instream flow suitability curves: Inland stocks of striped bass. U.S. Fish Wildl. Serv. FWS/OBS-82/10.85. 63 pp. pdf
stripedbassInlandLacLarv Morone saxatilis Crance, JH. 1984. Habitat suitability index models and instream flow suitability curves: Inland stocks of striped bass. U.S. Fish Wildl. Serv. FWS/OBS-82/10.85. 63 pp. pdf
stripedbassInlandRiv Morone saxatilis Crance, JH. 1984. Habitat suitability index models and instream flow suitability curves: Inland stocks of striped bass. U.S. Fish Wildl. Serv. FWS/OBS-82/10.85. 63 pp. pdf
swamprabbitForestedWetland Sylvilagus aquaticus Allen, AW. 1985. Habitat suitability index models: Swamp rabbit. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.107). 20 pp. pdf
swamprabbitHerbWetland Sylvilagus aquaticus Allen, AW. 1985. Habitat suitability index models: Swamp rabbit. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.107). 20 pp. pdf
swamprabbitShrubForestedWetland Sylvilagus aquaticus Allen, AW. 1985. Habitat suitability index models: Swamp rabbit. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.107). 20 pp. pdf
veeryNonWetland Catharus fuscescens Sousa, PJ. 1982. Habitat suitability index models: Veery. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.22. 12 pp. pdf
veeryWetland Catharus fuscescens Sousa, PJ. 1982. Habitat suitability index models: Veery. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.22. 12 pp. pdf
walleyeLacSecchiLtoe3.4m Sander vitreus McMahin, TE, JW Terrell, and PC Nelson. 1984. Habitat suitability information: Walleye. U.S. Fish Wildl. Serv. FWS/OBS-82/10.56. 43 pp. pdf
walleyeLacSecchiMt3.4m Sander vitreus McMahin, TE, JW Terrell, and PC Nelson. 1984. Habitat suitability information: Walleye. U.S. Fish Wildl. Serv. FWS/OBS-82/10.56. 43 pp. pdf
walleyeRivSecchiLtoe3.4m Sander vitreus McMahin, TE, JW Terrell, and PC Nelson. 1984. Habitat suitability information: Walleye. U.S. Fish Wildl. Serv. FWS/OBS-82/10.56. 43 pp. pdf
walleyeRivSecchiMt3.4m Sander vitreus McMahin, TE, JW Terrell, and PC Nelson. 1984. Habitat suitability information: Walleye. U.S. Fish Wildl. Serv. FWS/OBS-82/10.56. 43 pp. pdf
warmouthLac Lepomis gulosus McMahon, TE, G Gebhart, OE Maughan, and PC Nelson. 1984. Habitat suitability index models and instream flow suitability curves: Warmouth. U.S. Fish Wildl. Serv. FWS/OBS-82/10.67. 21 pp. pdf
warmouthRiv Lepomis gulosus McMahon, TE, G Gebhart, OE Maughan, and PC Nelson. 1984. Habitat suitability index models and instream flow suitability curves: Warmouth. U.S. Fish Wildl. Serv. FWS/OBS-82/10.67. 21 pp. pdf
westerngrebe Aechmophorus occidentalis Short, HL 1984. Habitat suitability index models: Western grebe. U.S. Fish Wildl. Serv. FWS/OBS-82/10.69. 20 pp. pdf
whitebassLacCurveASubsIndex Morone chrysops Hamilton, K, and PC Nelson. 1984. Habitat suitability index models and instream flow suitability index curves: White bass. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.89). 35 pp. pdf
whitebassLacCurveBSubsIndex Morone chrysops Hamilton, K, and PC Nelson. 1984. Habitat suitability index models and instream flow suitability index curves: White bass. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.89). 35 pp. pdf
whitebassLacCurveCSubsIndex Morone chrysops Hamilton, K, and PC Nelson. 1984. Habitat suitability index models and instream flow suitability index curves: White bass. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.89). 35 pp. pdf
whitebassLacTribCurveASubsIndex Morone chrysops Hamilton, K, and PC Nelson. 1984. Habitat suitability index models and instream flow suitability index curves: White bass. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.89). 35 pp. pdf
whitebassLacTribCurveBSubsIndex Morone chrysops Hamilton, K, and PC Nelson. 1984. Habitat suitability index models and instream flow suitability index curves: White bass. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.89). 35 pp. pdf
whitebassLacTribCurveCSubsIndex Morone chrysops Hamilton, K, and PC Nelson. 1984. Habitat suitability index models and instream flow suitability index curves: White bass. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.89). 35 pp. pdf
whitebassRivCurveASubsIndex Morone chrysops Hamilton, K, and PC Nelson. 1984. Habitat suitability index models and instream flow suitability index curves: White bass. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.89). 35 pp. pdf
whitebassRivCurveBSubsIndex Morone chrysops Hamilton, K, and PC Nelson. 1984. Habitat suitability index models and instream flow suitability index curves: White bass. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.89). 35 pp. pdf
whitebassRivCurveCSubsIndex Morone chrysops Hamilton, K, and PC Nelson. 1984. Habitat suitability index models and instream flow suitability index curves: White bass. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.89). 35 pp. pdf
whitecrappieLac Pomoxis annularis Edwards, EA, DA Krieger, G Gebhart, and OE Maughan. 1982. Habitat suitability index models: White crappie. U.S.D.I. Fish and Wildlife Service. FWS/OBS-82/10.7. 22 pp. pdf
whitecrappieRiv Pomoxis annularis Edwards, EA, DA Krieger, G Gebhart, and OE Maughan. 1982. Habitat suitability index models: White crappie. U.S.D.I. Fish and Wildlife Service. FWS/OBS-82/10.7. 22 pp. pdf
whiteibisIsland Eudocimus albus Hingtgen, TM, R Mulholland, and RW Repenning. 1985. Habitat suitability index models: white ibis. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.93) 18 pp. pdf
whiteibisWetland Eudocimus albus Hingtgen, TM, R Mulholland, and RW Repenning. 1985. Habitat suitability index models: white ibis. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.93) 18 pp. pdf
whiteshrimpNGulfofMex Farfantepenaeus aztecus Turner, RE, and MS Brody. 1983. Habitat suitability index models : northern Gulf of Mexico brown shrimp and white shrimp. U.S. Dept. of Int. Fish Wildl. Serv , FWS/OBS-82/l0.54. 24 pp. pdf
whitesuckerLacSpwnInletStrm Catostomus commersonii Twomey, KA, KL Williamson, and PC Nelson. 1984. Habitat suitability index models and instream flow suitability curves: White sucker. U.S. Fish Wildl. Serv. FWS/OBS-82/10.64. 56 pp. pdf
whitesuckerLacSpwnLake Catostomus commersonii Twomey, KA, KL Williamson, and PC Nelson. 1984. Habitat suitability index models and instream flow suitability curves: White sucker. U.S. Fish Wildl. Serv. FWS/OBS-82/10.64. 56 pp. pdf
whitesuckerLacSpwnLakeDrawMtoe2m Catostomus commersonii Twomey, KA, KL Williamson, and PC Nelson. 1984. Habitat suitability index models and instream flow suitability curves: White sucker. U.S. Fish Wildl. Serv. FWS/OBS-82/10.64. 56 pp. pdf
whitesuckerLacSpwnLakeDrawMtoe5m Catostomus commersonii Twomey, KA, KL Williamson, and PC Nelson. 1984. Habitat suitability index models and instream flow suitability curves: White sucker. U.S. Fish Wildl. Serv. FWS/OBS-82/10.64. 56 pp. pdf
whitesuckerRiv Catostomus commersonii Twomey, KA, KL Williamson, and PC Nelson. 1984. Habitat suitability index models and instream flow suitability curves: White sucker. U.S. Fish Wildl. Serv. FWS/OBS-82/10.64. 56 pp. pdf
whitetaileddeerModelII Odocoileus virginianus Short, HL. 1986. Habitat suitability index models: White-tailed deer in the Gulf of Mexico and South Atlantic coastal plains. U.S. Fish Wildl. Serv. Biol. Rep. 82(10.123). 36 pp. pdf
williamsonssapsucker Sphyrapicus thyroideus Sousa, PJ. 1983. Habitat suitability index models: Williamson’s sapsucker. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.47. 13 pp. pdf
woodduckBreeding Aix sponsa Sousa, PJ, and AH Farmer. 1983. Habitat suitability index models: Wood duck. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.43. 27 pp. pdf
woodduckWinter Aix sponsa Sousa, PJ, and AH Farmer. 1983. Habitat suitability index models: Wood duck. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.43. 27 pp. pdf
woodduckYear Aix sponsa Sousa, PJ, and AH Farmer. 1983. Habitat suitability index models: Wood duck. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.43. 27 pp. pdf
yellowheadedblackbird Xanthocephalus xanthocephalus Schroeder, RL. 1982. Habitat suitability index models: yellow-headed blackbird. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.26. 12 pp. pdf
yellowperchLac Perca flavescens Krieger, DA, JW Terrell, and PC Nelson. 1983. Habitat suitability information: Yellow perch. U.S. Fish Wildl. Serv. FWS/OBS-82/10.55. 37 pp. pdf
yellowperchRiv Perca flavescens Krieger, DA, JW Terrell, and PC Nelson. 1983. Habitat suitability information: Yellow perch. U.S. Fish Wildl. Serv. FWS/OBS-82/10.55. 37 pp. pdf
yellowwarbler Setophaga petechia Schroeder, RL. 1982. Habitat suitability index models: Yellow warbler. U.S. Dept. Int., Fish Wildl. Serv. FWS/OBS-82/10.27. 7 pp. pdf
Table B-2. Standardized variable naming convention used in defining USFWS HSI models.
Abbreviation Definition
abund abundance
ad adult
aq aquatic
avg mean
C Deg. C.
can canopy
cmps cm/sec
comp composition
cov cover or covered
curr current
d depth
decid decidous
dev development
dis discharge
dist distance
DO Dissolved Oxygen
DS Dissolved Solids
e embryo
env environment
gs ground surface
h height
hab habitat
herb herbaceous
juv juvenile
kgpha kg/ha
l length
lac lacustrine
larv larvae/larval
lbspacre lbs/acre
litt littoral
lt <
ltoe ?
m meters
max Max
max maximum
mgpl mg/l
mgpreypm3 mg-prey/m^3
min Min
mpkm m/km
mth monthly
num number
pct %
perm permanent
pl pool(s)
pop population
rfl riffle(s)
sa surface area
sal salinity
spwn spawning
sqm m^2
stand standing
strm stream
subm submerged
subs substrate
suit suitable
turb turbidity
veg vegetative or vegatation
vel velocity
w width
wtr water

Appendix C: Model Testing Records

Table C-1. Testing records for HSI models in ecorest. Of the 349 models in ecorest, 152 had USFWS documentaion that included example datasets for testing.
Model Testing.notes
alewifeJuv No data available
alewifeJuvAndSAEL No data available
alewifeSAEL No data available
americanalligatorNontidal Tested with dataset 1 and 3
americanalligatorTidal Tested with dataset 2
americanblackduckWinteringEVegWetland Tested with dataset 3
americanblackduckWinteringNCapeCod Tested with dataset 1
americanblackduckWinteringSCapeCod Tested with dataset 2
americancoot No data available
americaneiderBreeding Tested with datasets 1-3
americanoysterGulfofMexModifier Tested with datasets 1-5
americanoysterGulfofMexTypical Tested with datasets 1-5
americanshadEstu Tested with datasets 1-4
americanshadRiv Tested with datasets 1-4
americanwoodcockWinteringForestedDry No data available
americanwoodcockWinteringForestedMoist No data available
americanwoodcockWinteringForestedWet No data available
americanwoodcockWinteringShrubDry No data available
americanwoodcockWinteringShrubMoist No data available
americanwoodcockWinteringShrubWet No data available
arcticgrayling Tested with datasets 1-3
atlanticcroakerLATideLt0.5m Checked with provided dataset
atlanticcroakerLATideMt0.5m Checked with provided dataset
atlanticcroakerOtherTideLt0.5m Checked with provided dataset
atlanticcroakerOtherTideMt0.5m Checked with provided dataset
atlanticcroakerWetlandLATideLt0.5m No data available
atlanticcroakerWetlandLATideMt0.5m No data available
atlanticcroakerWetlandOtherTideLt0.5m No data available
atlanticcroakerWetlandOtherTideMt0.5m No data available
bairdssparrow No data available
baldeagleBreeding No data available
barredowl No data available
beaverLacAreaLt8ha No data available
beaverLacAreaMtoe8ha No data available
beaverPalu No data available
beaverRiv No data available
beltedkingfishLenticConstWave No data available
beltedkingfishLenticNoConstWave No data available
beltedkingfishLotic No data available
bigmouthbuffaloLacNoSal Tested with datasets 1-3; CCF of dataset 2 is incorrect (should be 0.52) and CCF and CR appear wrong in dataset 3 in literature example
bigmouthbuffaloLacSal No data available
bigmouthbuffaloRivNoSal Tested with datasets 1-3; CR of dataset 3 is incorrect (should be 0.3)
bigmouthbuffaloRivSal No data available
blackbear No data available
blackbelliedwhistlingduck Tested with datasets 1-3
blackbrant No data available
blackbullheadLac Tested with 3 datasets, Dataset 1 seems to have incorrect CC value in documentation but model matches results for other datasets
blackbullheadRiv Checked with datasets 1, 2, and 3; seems correct but authors rounded weirdly so numbers were a little different
blackcappedchickadeeFoodCanH No data available
blackcappedchickadeeFoodCanVol No data available
blackcrappieLacNoSal CR is slightly off in dataset 2 and 3; independently verify
blackcrappieLacSal CR is slightly off in dataset 2 and 3; independently verify
blackcrappieRivNoSal Tested with datasets 1-3; table includes SIV14 but does not seem to use it in calculations
blackcrappieRivSal SIV14 says lacustrine only, but there is an option to include SIV14 in the riverine model
blacknosedaceLac Tested with datasets 1-3
blacknosedaceRiv Tested with datasets 1-3; might be good to have someone test removing life stages?
blackshoulderedkite Results do not match example data because equation is different to account for area weighting
blacktailedprairiedog No data available
bluegillLac Tested with datasets 1, 2, and 3; CWQ for dataset 2 is off by a little- independently verify
bluegillRiv Tested with datasets 1, 2, and 3: Dataset 1, CWQ should be 0.4 because SIV8=0.4? Possible error in documentation?
bluegrouse No data available
blueherringJuv No data available
blueherringJuvandSAEL No data available
blueherringSAEL No data available
bluewingedtealBreeding No data available
bobcatLt4ha No data available
bobcatMtoe4ha No data available
brewerssparrow No data available
brooktroutLacAllLtoe15C No data available
brooktroutLacAllMt15C No data available
brooktroutRivAllLtoe15CLtoe5mEC Tested with dataset 1 all components
brooktroutRivAllLtoe15CMt5mEC No data available
brooktroutRivAllMt15CLtoe5mEC Tested with dataset 2 all components
brooktroutRivAllMt15CMt5mEC No data available
brownshrimpNGulfMex Tested with datasets 1-4
brownthrasher No data available
browntroutCompLtoe10C Tested with sample dataset; CFr value is incorrect, but typo in documentation; CA adjusted is also wrong, but the documentation says limited by SIV3, which is not included in CA?
browntroutCompMt10C Tested with sample dataset; CFr value is incorrect, but typo in documentation; CE produces 0.7 because it IS SIV3 limited, typo in documentation?
browntroutLimitLtoe10C Tested with sample dataset; CFr value is incorrect, but typo in documentation
browntroutLimitMt10C Tested with sample dataset; CFr value is incorrect, but typo in documentation
bullfrog No data available
cactuswren No data available
canvasbackBreeding No data available
channelcatfishLac Tested with datasets 1-3; all correct except CC for dataset 3 is off by a very small amount
channelcatfishRiv Tested with datasets 1-3; CR is slightly off for all three datasets; have someone check equation independently
chinooksalmonComp5to10CSand Tested with Dataset 1; CE is wrong but probably typo because SIV12=0.6?
chinooksalmonComp5to10CSilt Tested with Dataset 1; CE is wrong but probably typo because SIV12=0.6?
chinooksalmonCompLtoe5CSand Tested with Dataset 1; CE is wrong but probably typo because SIV12=0.6?
chinooksalmonCompLtoe5CSilt Tested with Dataset 1; CE is wrong but probably typo because SIV12=0.6?
chinooksalmonCompMt10CSand Tested with Dataset 1; CE is wrong but probably typo because SIV12=0.6?
chinooksalmonCompMt10CSilt Tested with Dataset 1; CE is wrong but probably typo because SIV12=0.6?
chinooksalmonLimit5to10CSand Tested with Dataset 1
chinooksalmonLimit5to10CSilt Tested with Dataset 1
chinooksalmonLimitLtoe5CSand Tested with Dataset 1
chinooksalmonLimitLtoe5CSilt Tested with Dataset 1
chinooksalmonLimitMt10CSand Tested with Dataset 1
chinooksalmonLimitMt10CSilt Tested with Dataset 1
chumsalmonAlevin No data available
chumsalmonEyedEmb No data available
clapperrail Checked with datasets 1-3
cohosalmonSpringSummerSeaMig No data available
cohosalmonWinterRearing No data available
commoncarpLacNoSal HSI scores for dataset 1 and 3 in docs are incorrect (#1 uses a value of 0.7 for COT in the final equation rather than 0.4, and #3 neglects to account for SIV12 being <=0.4); Storage ratio graph from documentation is much smoother, but no actual breakpoints are provided
commoncarpLacSal HSI scores for dataset 1 and 3 in docs are incorrect (#1 uses a value of 0.7 for COT in the final equation rather than 0.4, and #3 neglects to account for SIV12 being <=0.4); Storage ratio graph from documentation is much smoother, but no actual breakpoints are provided
commoncarpRivNoSal No data available
commoncarpRivSal No data available
commonshinerLac Tested with datasets 1-3
commonshinerRiv Tested with datasets 1-3
creekchubRivLargerStrmDistMt5km Tested with datasets 1-2; CC incorrect for dataset 2, may be typo; recheck; Example data in dataset 3 does not align with what is shown on the graph for SIV1
creekchubRivLargerStrmDistWithin5km Tested with dataset 3; HSI is incorrect because authors did not account for full equation being smaller than CR; recheck
cutthroatLacGenLtoe15C No data available
cutthroatLacGenMt15C No data available
cutthroatLacLahontanLtoe15C No data available
cutthroatLacLahontanMt15C No data available
cutthroatRivGenLtoe15CLtoe5m Tested with datasets 1-3; HSI is incorrect for Dataset 1, but should be 0.95 because CA<final equation, so error in documentation; Dataset 2, CJ and COT are wrong, but can’t find error and HSI is wrong but again should be equal to CA; Dataset 3, CJ in documentation is incorrect (should be 0.3 since SIV15<=0.4); Final HSI should also be 0.3; COT is also wrong, but unsure why
cutthroatRivGenLtoe15CMt5m Tested with datasets 1-3; HSI is incorrect for Dataset 1, but should be 0.95 because CA<final equation, so error in documentation; Dataset 2, CJ and COT are wrong, but can’t find error and HSI is wrong but again should be equal to CA; Dataset 3, CJ in documentation is incorrect (should be 0.3 since SIV15<=0.4); Final HSI should also be 0.3; COT is also wrong, but unsure why
cutthroatRivGenMt15CLtoe5m Tested with datasets 1-3; HSI is incorrect for Dataset 1, but should be 0.95 because CA<final equation, so error in documentation; Dataset 2, CJ and COT are wrong, but can’t find error and HSI is wrong but again should be equal to CA; Dataset 3, CJ in documentation is incorrect (should be 0.3 since SIV15<=0.4); Final HSI should also be 0.3; COT is also wrong, but unsure why
cutthroatRivGenMt15CMt5m Tested with datasets 1-3; HSI is incorrect for Dataset 1, but should be 0.95 because CA<final equation, so error in documentation; Dataset 2, CJ and COT are wrong, but can’t find error and HSI is wrong but again should be equal to CA; Dataset 3, CJ in documentation is incorrect (should be 0.3 since SIV15<=0.4); Final HSI should also be 0.3; COT is also wrong, but unsure why
cutthroatRivLahontanLtoe15CLtoe5m Tested with datasets 1-3; HSI is incorrect for Dataset 1, but should be 0.95 because CA<final equation, so error in documentation; Dataset 2, CJ and COT are wrong, but can’t find error and HSI is wrong but again should be equal to CA; Dataset 3, CJ in documentation is incorrect (should be 0.3 since SIV15<=0.4); Final HSI should also be 0.3; COT is also wrong, but unsure why
cutthroatRivLahontanLtoe15CMt5m Tested with datasets 1-3; HSI is incorrect for Dataset 1, but should be 0.95 because CA<final equation, so error in documentation; Dataset 2, CJ and COT are wrong, but can’t find error and HSI is wrong but again should be equal to CA; Dataset 3, CJ in documentation is incorrect (should be 0.3 since SIV15<=0.4); Final HSI should also be 0.3; COT is also wrong, but unsure why
cutthroatRivLahontanMt15CLtoe5m Tested with datasets 1-3; HSI is incorrect for Dataset 1, but should be 0.95 because CA<final equation, so error in documentation; Dataset 2, CJ and COT are wrong, but can’t find error and HSI is wrong but again should be equal to CA; Dataset 3, CJ in documentation is incorrect (should be 0.3 since SIV15<=0.4); Final HSI should also be 0.3; COT is also wrong, but unsure why
cutthroatRivLahontanMt15CMt5m Tested with datasets 1-3; HSI is incorrect for Dataset 1, but should be 0.95 because CA<final equation, so error in documentation; Dataset 2, CJ and COT are wrong, but can’t find error and HSI is wrong but again should be equal to CA; Dataset 3, CJ in documentation is incorrect (should be 0.3 since SIV15<=0.4); Final HSI should also be 0.3; COT is also wrong, but unsure why
diamondbackterrapinNesting Tested with datasets 1-3
downywoodpecker No data available
easternbrownpelican Tested with example datasets
easterncottontail No data available
easternmeadowlark No data available
easternwildturkeyCroplandHerb No data available
easternwildturkeyCroplandShrub No data available
easternwildturkeyForestHardDBH25.4cm No data available
easternwildturkeyForestHardDBH27.9cm No data available
easternwildturkeyForestHardDBH30.5cm No data available
easternwildturkeyForestHardDBH33.0cm No data available
easternwildturkeyForestHardDBH35.6cm No data available
easternwildturkeyForestHardDBH38.1cm No data available
easternwildturkeyHerb No data available
easternwildturkeyShrub No data available
englishsoleJuv Tested with datasets 1-2
englishsoleJuvImpactAlt Tested with dataset 3
fallfishLac Tested with datasets 1 and 2
fallfishRivNoSpwn No data available
fallfishRivSpwn Tested with datasets 1 and 2
ferruginoushawkCrop No data available
ferruginoushawkHerbAndShrub No data available
fieldsparrow No data available
fisherWinterCov No data available
flatheadcatfishMacro No data available
flounderGulf Tested with datasets 1-3
flounderSouthern Tested with datasets 1-4
forstersternBreeding Tested with datasets 1-3
foxsquirrel No data available
gadwallBreeding No data available
gizzardshadLacNoTributaries No data available
gizzardshadLacSpwnTributaries No data available
graypartridge No data available
graysquirrel No data available
greatblueheron No data available
greategretFeeding Tested with dataset 1
greategretNestingIsland Tested with dataset 2
greategretNestingNonisland Tested with dataset 3
greaterprairiechickenHarvested No data available
greaterprairiechickenUnharvested No data available
greatersandhillcraneLt200ha No data available
greatersandhillcraneMtoe200ha No data available
greaterwhitefrontedgooseWinteringWetland Tested with datasets 1-3
greensunfishLac Tested with datasets 1-3; CWQ is slightly off for dataset 1; recheck; no test of data that does not include salinity
greensunfishRiv Tested with datasets 1-3; CWQ and HSI are slighlty higher than reported values for dataset three, re-check
greensunfishRivSal No data available
gulfmenhadenEstuary Tested with datasets 1-5
gulfmenhadenMarine Tested with datasets 1-5
hairywoodpecker No data available
hardclam Tested with datasets 1-3
inlandsilversideNoZooplankton tested with Point Judith data
inlandsilversideZooplankton Tested with datasets 1-2
laketroutReproducingLakes No data available
laketroutReproducingRes No data available
laketroutStocked No data available
largemouthbassLacN Tested with datasets 1-3; Components and HSIs slightly different for all datasets, but maybe just rounding?; recheck
largemouthbassLacS Tested with datasets 1-3; Components and HSIs slightly different for all datasets, but maybe just rounding?; recheck
largemouthbassRivGrad Added model; Tested with datasets 1-3; Components and HSIs slightly different for all datasets, but maybe just rounding?; recheck
largemouthbassRivVel Sample data does not include SIV19 and SIV21
larkbunting No data available
laughinggull Tested with dataset 1-3
leastternVegCovLt15OrMt25pct No data available
leastternVegCovMtoe15OrLtoe25pct No data available
lesserscaupBreeding No data available
lesserscaupWintering tested with datasets 1-3
lessersnowgooseWintering Tested with datasets 1-3
lewiswoodpeckerSummerDeciduousDesertic No data available
lewiswoodpeckerSummerEvergreen No data available
lewiswoodpeckerWinterCropland No data available
lewiswoodpeckerWinterNotEForC No data available
lewiswoodpeckerYearRoundDeciduousDesertic No data available
lewiswoodpeckerYearRoundEvergreen No data available
littleneckclam Tested with dataset 1
longnosedaceLac Tested with datasets 1-3
longnosedaceRiv Tested with datasets 1-3
longnosesuckerLac Tested with datasets 1-3; CJA for dataset 2 should be 0.7 because SIV13=0.7 (mistake in doc); assumed SIV8 graph started at 0 based on sample data
longnosesuckerRiv Tested with datasets 1-3
mallardCroplandCorn No data available
mallardCroplandOtherCrops No data available
mallardCroplandSoy No data available
mallardForestedPaluWetlands No data available
mallardNonforestedPaluLacRiv No data available
marshwren No data available
marten No data available
minkPaluEmergHerb No data available
minkPaluForestedOrShrubLess405ha No data available
minkPaluForestedOrShrubMore405ha No data available
minkRivLac No data available
mooseLakeSupModelII No data available
mottledduckAny Tested with dataset 1
mottledduckBrood Tested with dataset 3
mottledduckNesting Tested with dataset 2 and SIV7 from dataset 1
muskellungeLargeLakeSpwnVegCurveA No data available
muskellungeLargeLakeSpwnVegCurveB No data available
muskellungeLargeLakeSpwnVegCurveC No data available
muskellungeLargeLakeSpwnVegCurveD No data available
muskellungeSmallLakeSpwnVegCurveA No data available
muskellungeSmallLakeSpwnVegCurveB No data available
muskellungeSmallLakeSpwnVegCurveC No data available
muskellungeSmallLakeSpwnVegCurveD No data available
muskratEstu No data available
muskratHW No data available
muskratRiv No data available
northernbobwhiteCroplands No data available
northernbobwhiteDbh25.4cm No data available
northernbobwhiteDbh27.9cm No data available
northernbobwhiteDbh30.5cm No data available
northernbobwhiteDbh33.0cm No data available
northernbobwhiteDbh35.6cm No data available
northernbobwhiteDbh38.1cm No data available
northernbobwhiteShrub No data available
northernpikeLacVegA No data available
northernpikeLacVegB No data available
northernpikeLacVegC No data available
northernpikeLacVegD No data available
northernpikeRivVegA No data available
northernpikeRivVegB No data available
northernpikeRivVegC No data available
northernpikeRivVegD No data available
northernpintail No data available
northernpintailWinteringGulfCoastPaluLacEstuLtoe5ppt Tested with dataset 1; NAs not allowed
northernpintailWinteringGulfPaluLacEstuMt5ppt Tested with datasets 2 and 3
ospreyLac No data available
ospreyRiv No data available
paddlefishAdSummerandWinterHab Tested with datasets 1-4
paddlefishSpwnHab Tested with datasets 1-4
pileatedwoodpeckerE No data available
pileatedwoodpeckerW No data available
pinewarbler No data available
pinksalmonLimit Tested with dataset 1; add compensatory model if keeping brook trout compensatory?; SIV7 graph doesn’t seem to match info in text exactly
pinkshrimpEmergAndSeagrassVeg Tested with dataset 3, although SIV2 values don’t make sense but give correct answer
pinkshrimpEmergVeg Checked with Datasets 1,2, and 3
pinkshrimpSeagrassVeg Checked with Datasets 1,2, and 3
plainssharptailedgrouse No data available
pronghorn No data available
RainbowtroutLac No data available
rainbowtroutRiv Tested with datasets 1-3; COT is slightly off for datasets 1 and 2, but probably rounding error
redbreastsunfishLacN No data available
redbreastsunfishLacS No data available
redbreastsunfishPalu No data available
redbreastsunfishRiv No data available
reddrumLarvJuvEstuLittleSubmVeg Tested with datasets 1-3 from Table 3
reddrumLarvJuvEstuSubmVeg Tested with datasets 1-3
redearsunfishLac No data available
redearsunfishRiv No data available
redheadWinteringWtrAvailable Tested with datasets 1 and 2
redheadWinteringWtrNotAvailable Tested with dataset 3
redkingcrabJuv1to4 Tested with datasets 1-3
redkingcrabJuv4PlusandAd Tested with datasets 1-3
redkingcrabLarv Tested with datasets 1-3
redkingcrabYoungofYrJuv Tested with datasets 1-3
redspottednewtAquatic150m No data available
redspottednewtAquaticEntire No data available
redspottednewtTerrestrial No data available
redwingedblackbirdA No data available
redwingedblackbirdB No data available
redwingedblackbirdC No data available
roseatespoonbillIslandFuture No data available
roseatespoonbillIslandPresent Checked with datasets 1 and 2
roseatespoonbillMainlandFuture No data available
roseatespoonbillMainlandPresent Checked with dataset 3
ruffedgrouse No data available
shortnosesturgeon Checked with datasets 1-3
sliderturtle No data available
sloughdarterLac Checked with datasets 1-3
sloughdarterRiv Checked with datasets 1-3; COT and HSI are incorrect for dataset 1, but this is likely a typo (0.02 vs. 0.2); Dataset 2 HSI is wrong, but this is a mistake because CWQ<=0.4, so should be 0.4; recheck
smallmouthbassLac Tested with datasets 1-3; Dataset 2 produces incorrect values for CWQ and CR, recheck; CR may be rounding error
smallmouthbassRiv Tested with datasets 1-3
smallmouthbuffaloLac Tested with datasets 1-3; have someone else check format of CWQ equation; dataset 3 CWQ and HSI are wrong but typo because SIV8 is 0.3 so both should be 0.3, not 0.41
smallmouthbuffaloRiv Tested with datasets 1-3; have someone else check format of CWQ equation; dataset 3 HSI is slightly off but may be a rounding error
snappingturtle No data available
snowshoehareForageBiomass No data available
snowshoehareForageVisual No data available
southernkingfishEstu Tested with datasets 2 and 3
southernkingfishMarine No data available
southernredbackedvole No data available
spotJuv Tested with datasets 1, 2, and 3
spottedbassLac No data available
spottedbassRiv No data available
spottedowl No data available
spottedseatrout Tested on datasets 1-4
steelheadtroutRiv No data available
stripedbassCoastal Tested with datasets 1-4
stripedbassInlandLacAd Tested with datasets 1-3
stripedbassInlandLacJuv Tested with datasets 1-3
stripedbassInlandLacLarv Tested with datasets 1-3
stripedbassInlandRiv Tested with datasets 1-3
swamprabbitForestedWetland No data available
swamprabbitHerbWetland No data available
swamprabbitShrubForestedWetland No data available
veeryNonWetland No data available
veeryWetland No data available
walleyeLacSecchiLtoe3.4m No data available
walleyeLacSecchiMt3.4m No data available
walleyeRivSecchiLtoe3.4m No data available
walleyeRivSecchiMt3.4m No data available
warmouthLac No data available
warmouthRiv No data available
westerngrebe No data available
whitebassLacCurveASubsIndex Tested with datasets 1-3
whitebassLacCurveBSubsIndex Tested with datasets 1-3
whitebassLacCurveCSubsIndex Tested with datasets 1-3
whitebassLacTribCurveASubsIndex Tested with datasets 1-3
whitebassLacTribCurveBSubsIndex Tested with datasets 1-3
whitebassLacTribCurveCSubsIndex Tested with datasets 1-3
whitebassRivCurveASubsIndex Tested with datasets 1-3; dataset 3 produces incorrect CF and COT values, but these appear to be typos in the documentation; recheck
whitebassRivCurveBSubsIndex Tested with datasets 1-3; dataset 3 produces incorrect CF and COT values, but these appear to be typos in the documentation; recheck
whitebassRivCurveCSubsIndex Tested with datasets 1-3; dataset 3 produces incorrect CF and COT values, but these appear to be typos in the documentation; recheck
whitecrappieLac Tested with datasets 1-3 w/out salinity; dataset 3 slightly off but likely rounding error
whitecrappieRiv Tested with datasets 1-3 w/out salinity; dataset 3 slightly off but likely rounding error
whiteibisIsland Tested with datasets 1 and 3
whiteibisWetland Tested with dataset 2
whiteshrimpNGulfofMex Tested with datasets 1-4
whitesuckerLacSpwnInletStrm No data available
whitesuckerLacSpwnLake Tested with datasets 1-3
whitesuckerLacSpwnLakeDrawMtoe2m No data available
whitesuckerLacSpwnLakeDrawMtoe5m No data available
whitesuckerRiv Tested with dataset 1-3; could be tested with data from table 3 as well
whitetaileddeerModelII Tested with three datasets
williamsonssapsucker No data available
woodduckBreeding No data available
woodduckWinter No data available
woodduckYear No data available
yellowheadedblackbird No data available
yellowperchLac Tested 2 datasets
yellowperchRiv No data available
yellowwarbler No data available

Code used to evaluate ecorest functions

## # The purpose of this script is to test the functionality of ecorest functions to ensure they are working as expected
## # Authors: Kiara Cushway
## # Date: January 14th, 2026
## 
## ## Clear workspace
## rm(list = ls()) ## remove stored files and objects
## gc(T) ## garbage collection
## graphics.off() ## Turn off graphics
## 
## ## Load library
## library(ecorest)
## library(backports)
## library(stringr)
## library(viridis)
## 
## ################################################################################
## 
## # HSI functions
## 
## ## Set seed for repeatability
## set.seed(342)
## 
## ## Create a function to test HSI-based functions in ecorest
## HSI_tester = function(function_name, test_type = 'expected', iterations = 9999) {
##   passes = 0 # set number of passes to zero initially
##   ## Make sure the function name is correct
##   if (!function_name %in% c('HSImin', 'HSIarimean', 'HSIgeomean', 'HSIwarimean')) {
##     stop("Error: invalid function name. Please enter one of the following: 'HSImin', 'HSIarimean', 'HSIgeomean', 'HSIwarimean'.", call. = F)
##   }
##   ## Make sure the test_type is correct
##   if (!test_type %in% c('NA', 'invalid', 'expected', 'invalid_weights', 'invalid_num_weights', 'dataframe')) {
##     stop("Error: invalid test type. Please enter one of the following: 'NA', 'invalid', 'expected', 'invalid_weights', 'invalid_num_weights', 'dataframe'.", call. = F)
##   }
##   ## Make sure weighting is only compatible with HSIwarimean
##   if (!function_name %in% 'HSIwarimean' & test_type %in% c('invalid_weights', 'invalid_num_weights')) {
##     stop("Error: Invalid weights and invalid number of weights can only be tested with the HSIwarimean function.", call. = F)
##   }
##   ## Run specified number of iterations to test model
##   for (i in 1:iterations) {
##     num_inputs = sample(3:20, 1) # randomly generate number of inputs between 2 and 20
##     input_vals = runif(n = num_inputs, min = 0, max = 1) # randomly generate specified number of input values
##     num_NA = 0 # specify no NA values
##     invalid = 0 # specify no invalid values
##     ## If the test is testing inputs including NA values, randomly replace some values with NA
##     if (test_type == 'NA') {
##       num_NA = sample(1:(num_inputs - 2), 1) # randomly select number of NA values to be included
##       input_vals[sample(length(input_vals), num_NA)] = NA # randomly replace some values with NA
##     } else if (test_type == 'invalid') {
##       # Inputs < 0 or > 1
##         num_invalid = sample(1:(num_inputs - 2), 1) # randomly select number of invalid inputs to be included  
##         invalid_type = sample(1:3, 1)
##         if (invalid_type == 1) {
##         invalid = sample(
##           runif(1000, -10.4, 10.4) |> (\(x) x[x < 0 | x > 1])(),
##           size = num_invalid,
##           replace = TRUE
##         ) # randomly generate invalid values
##         } else if (invalid_type == 2) {
##           # Infinite inputs
##           invalid = rep(Inf, num_invalid)
##         } else if (invalid_type == 3) {
##           # Character inputs
##           invalid = sample(letters, num_invalid)
##         }
##         
##         input_vals[sample(length(input_vals), num_invalid)] = invalid 
##     } else if (test_type == 'dataframe') {
##       input_vals = data.frame(input_vals)
##     }
##     ## If the function being tested is HSImin, test limiting factor equation
##     if (function_name == 'HSImin') {
##       HSI = suppressWarnings(try(HSImin(input_vals), silent = T)) # calculate HSI
##       ## Compare HSImin result with minimum value equation
##       if (isTRUE(all.equal(HSI, min(input_vals, na.rm = T)))) {
##         passes = passes + 1 # if values match, test passes
##       } 
##     } 
##     ## If the function being tested is HSIarimean, compare arithmetic mean equation
##     else if (function_name == 'HSIarimean') {
##       HSI = suppressWarnings(try(HSIarimean(input_vals), silent = T)) # calculate HSI
##       ## Compare HSIarimean to arithmetic mean output
##       if (all(is.numeric(as.matrix(input_vals)))) {
##         if (isTRUE(all.equal(HSI, suppressWarnings(sum(input_vals, na.rm = T) / (num_inputs - num_NA))))) {
##           passes = passes + 1 # if values match, test passes
##         }
##       }
##     } 
##     ## If the function being tested is HSIgeomean, compare to geometric mean equation
##     else if (function_name == 'HSIgeomean') {
##       HSI = suppressWarnings(try(HSIgeomean(input_vals), silent = T)) # calculate HSI
##       ## Compare HSIgeomean to geometric mean equation
##       if (all(is.numeric(as.matrix(input_vals)))) {
##         if (isTRUE(all.equal(HSI, (prod(input_vals, na.rm = TRUE) ^ (1 / (num_inputs - num_NA)))))) {
##           passes = passes + 1 # if values match, test passes
##         } 
##       }
##     
##     }
##     ## If the function being tested is HSIwarimean, compare to weighted arithmetic mean
##     else if (function_name == 'HSIwarimean') {
##       weights_raw = runif(num_inputs) # randomly generate weights
##       ## If testing invalid weights, leave weights as raw so they don't add to one
##       if (test_type == 'invalid_weights') {
##         weights = weights_raw
##       } 
##       ## If testing incorrect number of weights, randomly add between 1 and 5 extra weights
##       else if (test_type == 'invalid_num_weights') {
##         weights = c(weights_raw, runif(sample(1:5, 1), min = 0, max = 1)) # add extra weights
##         weights = weights / sum(weights) # normalize to sum to one
##         weights[length(weights)] <- weights[length(weights)] + (1 - sum(weights)) # ensure that values sum to one
##       } 
##       ## If testing expected or NA values, calculate weights normally
##       else {
##         weights <- weights_raw
##         
##         weights[is.na(input_vals)] <- NA
##         
##         weights <- weights / sum(weights, na.rm = TRUE)
##         
##         weights[max(which(!is.na(weights)))] <-
##           weights[max(which(!is.na(weights)))] + (1 - sum(weights, na.rm = TRUE))
## 
##       }
##       if (test_type == 'dataframe') {
##         df = data.frame(input_vals = input_vals, weights = weights)
##         HSI = suppressWarnings(try(HSIwarimean(df$input_vals, df$weights), silent = T)) # calculate HSI
##         ## Compare HSIwarimean to weighted arithmetic mean
##         if (all(is.numeric(as.matrix(df$input_vals)))) {
##           if (isTRUE(all.equal(HSI, suppressWarnings(sum(df$input_vals * df$weights, na.rm = TRUE)), tolerance = 1e-12))) {
##             passes = passes + 1 # if values match, test passes
##           }
##         }
##       } else {
##         HSI = suppressWarnings(try(HSIwarimean(input_vals, weights), silent = T)) # calculate HSI
##         ## Compare HSIwarimean to weighted arithmetic mean
##         if (all(is.numeric(as.matrix(input_vals)))) {
##           if (isTRUE(all.equal(HSI, suppressWarnings(sum(input_vals * weights, na.rm = TRUE)), tolerance = 1e-12))) {
##             passes = passes + 1 # if values match, test passes
##           }
##         }
##       }
##     } 
##   }
##   # Pass rate
##   if (test_type %in% c('expected', 'NA', 'dataframe')) {
##   return(passes / iterations * 100) # if results should be valid, return the pass rate
##   } else {
##     return((iterations - passes) / iterations *100) # if results should be errors, return the fail rate
##   }
## }
## 
## ## Apply function
## HSI_tester('HSImin', 'expected', 9999)
## HSI_tester('HSImin', 'NA', 9999)
## HSI_tester('HSImin', 'invalid', 9999)
## HSI_tester('HSImin', 'dataframe', 9999)
## 
## HSI_tester('HSIarimean', 'expected', 9999)
## HSI_tester('HSIarimean', 'NA', 9999)
## HSI_tester('HSIarimean', 'invalid', 9999)
## HSI_tester('HSIarimean', 'dataframe', 9999)
## 
## HSI_tester('HSIgeomean', 'expected', 9999)
## HSI_tester('HSIgeomean', 'NA', 9999)
## HSI_tester('HSIgeomean', 'invalid', 9999)
## HSI_tester('HSIgeomean', 'dataframe', 9999)
## 
## HSI_tester('HSIwarimean', 'expected', 9999)
## HSI_tester('HSIwarimean', 'NA', 9999)
## HSI_tester('HSIwarimean', 'invalid', 9999)
## HSI_tester('HSIwarimean', 'invalid_weights', 9999)
## HSI_tester('HSIwarimean', 'invalid_num_weights', 9999)
## HSI_tester('HSIwarimean', 'dataframe', 9999)
## 
## ################################################################################
## 
## # HSIeqtn
## HSIeqtn_tester = function(test_type = 'expected', iterations = 100){
##   passes = 0 # set initial pass rate to zero
##   count_NA = 0 # set number of NA columns to zero
##   num_invalid = 0 # set number of invalid inputs to zero
##   num_extra = 0 # set number of extra values to zero
##   exclude = NULL
##   ## Make sure the test_type is correct
##   if (!test_type %in% c('expected', 'exclude', 'invalid_name', 'invalid_SIV', 'wrong_num_SIV', 'dataframe')) {
##     stop("Error: invalid test type. Please enter one of the following: 'expected', 'exclude', 'invalid_name', 'invalid_SIV', 'wrong_num_SIV', 'dataframe'.", call. = F)
##   }
## 
##   ## For each model in HSImetadata, run the test 'iterations' number of times
##    for (model in HSImetadata$model) {
##      for (i in 1:iterations) {
##        curves = data.frame(HSImodels[[model]]) # store curve breakpoints in data frame
##        for (col in 1:length(curves)) {
##          if (all(is.na(curves[,col])) == TRUE){
##            count_NA = count_NA + 1 # identify and count columns with only NA values (i.e., not used in that model)
##          } 
##        }
##        num_SIV = (ncol(curves) - count_NA)/2 # calculate the number of input variables
##        input_vals = runif(num_SIV, 0, 1) # generate random test input from a uniform distribution between 0 and 1
##        model.loc <- which(HSImetadata$model == model) # Find the location of the model in HSImetadata
##        names(input_vals) = names(which(colSums(!is.na(HSImetadata[model.loc, 9:40])) > 0))
##        ## If the test is for an invalid HSImodelname:
##        if (test_type == 'invalid_name') {
##          new_letters = str_flatten(sample(letters, 3)) # randomly choose three letters to tack on to the model name
##          model = paste0(model, new_letters) # paste the model and letter together
##        }
##        ## If the test is for an invalid SIV value:
##        else if (test_type == 'invalid_SIV') {
##          # Inputs < 0 or > 1
##          num_invalid = ifelse(num_SIV > 2, sample(1:(num_SIV - 2), 1), 1) # randomly select number of invalid inputs to be included  
##          invalid_type = sample(1:3, 1)
##          if (invalid_type == 1) {
##            invalid = sample(
##              runif(1000, -10.4, 10.4) |> (\(x) x[x < 0 | x > 1])(),
##              size = num_invalid,
##              replace = TRUE
##            ) # randomly generate invalid values
##          } else if (invalid_type == 2) {
##            # Infinite inputs
##            invalid = rep(Inf, num_invalid)
##          } else if (invalid_type == 3) {
##            # Character inputs
##            invalid = sample(letters, num_invalid)
##          }
##          
##          input_vals[sample(length(input_vals), num_invalid)] = invalid 
##        } 
##        ## If the test is for the wrong number of SIV values:
##        else if (test_type == 'wrong_num_SIV') {
##          num_extra = sample(1:20, 1) # randomly decide how many extra SIV values to include (between 1 and 20)
##          extra_labels = paste0("SIV", 24:(24 + num_extra - 1))
##          extra_SIV = runif(num_extra, min = 0, max = 1) # sample num_extra random values between zero and one
##          input_vals = append(input_vals, extra_SIV)
##          names(input_vals)[(num_SIV + 1):(num_SIV + num_extra)] = extra_labels
##        } else if (test_type == 'dataframe') {
##          input_vals = data.frame(t(input_vals))
##        }
##        HSI = suppressWarnings(try(HSIeqtn(model, input_vals, HSImetadata, exclude), silent = TRUE)) # calculate overall HSI if possible
##        if (HSI >= 0 & HSI <= 1) {
##          passes = passes + 1
##          #print(model)
##          #print(input_vals)
##          #print(HSImetadata[HSImetadata$model == model, 'Eqtn'])
##        }
##        count_NA = 0 # Reset count_NA to zero
##        num_SIV = 0 # Reset num_SIV to zero
##        if (test_type == 'invalid_name') {
##        model = substr(model, 1, nchar(model) - 3)
##        }
##      } 
##    }
##   # Pass rate
##   if (test_type %in% c('expected', 'NA', 'dataframe', 'wrong_num_SIV')) {
##     return(passes / (iterations * 349) * 100) # if results should be valid, return the pass rate
##   } else {
##     return(((iterations * 349) - passes) / (iterations * 349) * 100) # if results should be errors, return the fail rate
##   }
## }
## 
## HSIeqtn_tester('expected', 100)
## HSIeqtn_tester('invalid_name', 100)
## HSIeqtn_tester('invalid_SIV', 100)
## HSIeqtn_tester('wrong_num_SIV', 100)
## HSIeqtn_tester('dataframe', 100)
## 
## ################################################################################
## 
## # SIcalc
## 
## SIcalc_tester = function(test_type, iterations) {
##   passes = 0
##   tests_run = 0
##   count_NA = 0
##   num_SIV = 0
##   input = c()
##   
##   if (!test_type %in% c('manual', 'invalid', 'parameter_NA', 'HSImodels',
##                         'mismatched_inputs', 'one_row_df', 'minmax_caps')) {
##     stop(
##       "Error: invalid test type. Please enter one of the following: 'manual', 'invalid', 'parameter_NA', 'HSImodels', 'mismatched_inputs', 'one_row_df', 'minmax_caps'.",
##       call. = FALSE
##     )
##   }
##   
##   if (test_type == 'HSImodels') {
##     for (model in HSImetadata$model) {
##       for (i in 1:iterations) {
##         input = c()
##         count_NA = 0
##         curves = HSImodels[[model]]
##         
##         for (col in 1:length(curves)) {
##           if (all(is.na(curves[, col])) == TRUE) {
##             count_NA = count_NA + 1
##           }
##           if (col %% 2 != 0) {
##             n_rows = sum(!is.na(curves[, col]))
##             input = c(input, as.character(sample(curves[1:n_rows, col], 1, FALSE)))
##           }
##         }
##         
##         SIs = suppressWarnings(try(SIcalc(curves, input), silent = TRUE))
##         
##         if (!inherits(SIs, "try-error") && all(SIs >= 0 & SIs <= 1 | is.na(SIs))) {
##           passes = passes + 1
##         }
##       }
##     }
##     
##   } else {
##     for (test in 1:iterations) {
##       input = c()
##       model = c()
##       num_vars = sample(1:10, 1)
##       var_names = paste0('var_', 1:num_vars)
##       siv_names = paste0('var_', 1:num_vars, '.SIV')
##       var_is_cat = c()
##       
##       for (var in 1:num_vars) {
##         num_SIV = sample(2:15, 1)
##         cat = sample(0:1, 1)
##         var_is_cat[var] = cat
##         
##         if (cat == 1) {
##           categories = letters[1:num_SIV]
##         } else {
##           categories = as.numeric(sort(sample(0:1000, num_SIV)))
##         }
##         
##         SIVs = runif(num_SIV, min = 0, max = 1)
##         SIVs = c(SIVs, rep(NA, 15 - num_SIV))
##         categories = c(categories, rep(NA, 15 - num_SIV))
##         model = cbind(model, categories, SIVs)
##       }
##       
##       colnames(model) = c(rbind(var_names, siv_names))
##       model = data.frame(model, stringsAsFactors = FALSE)
##       model = model[rowSums(is.na(model)) < ncol(model), ]
##       
##       model[] <- lapply(model, function(x) {
##         num <- suppressWarnings(as.numeric(x))
##         if (all(is.na(x) | !is.na(num))) {
##           num
##         } else {
##           x
##         }
##       })
##       
##       if (test_type == 'parameter_NA') {
##         odd_indices = seq(1, length(model), by = 2)
##         na_col = sample(odd_indices, 1)
##         model[, na_col:(na_col + 1)] = NA
##       }
##       
##       for (col in 1:length(model)) {
##         if (col %% 2 != 0) {
##           if (all(is.na(model[, col]))) {
##             input = append(input, NA)
##           } else if (is.numeric(model[, col])) {
##             min_val = min(model[, col], na.rm = TRUE)
##             max_val = max(model[, col], na.rm = TRUE)
##             input = append(input, runif(1, min = min_val, max = max_val))
##           } else {
##             min_val = min(match(model[, col], letters), na.rm = TRUE)
##             max_val = max(match(model[, col], letters), na.rm = TRUE)
##             input = append(input, letters[sample(min_val:max_val, 1)])
##           }
##         }
##       }
##       
##       if (test_type == 'invalid') {
##         inv_input = sample(1:length(input), 1)
##         invalid_type = sample(1:3, 1)
##         
##         if (invalid_type == 1) {
##           if (input[inv_input] %in% letters) {
##             input[inv_input] = letters[sample(16:26, 1)]
##           } else {
##             input[inv_input] = letters[sample(1:26, 1)]
##           }
##         } else if (invalid_type == 2) {
##           if (input[inv_input] %in% letters) {
##             input[inv_input] = sample(c(1500, -1500), 1)
##           } else {
##             input[inv_input] = letters[sample(1:26, 1)]
##           }
##         } else {
##           input[inv_input] = Inf
##         }
##       }
##       
##       if (test_type == 'minmax_caps') {
##         continuous_vars <- which(var_is_cat == 0)
##         
##         if (length(continuous_vars) == 0) {
##           next
##         }
##         
##         chosen_var <- sample(continuous_vars, 1)
##         cap_col <- 2 * chosen_var - 1
##         input_index <- chosen_var
##         
##         x_num <- suppressWarnings(as.numeric(as.character(model[, cap_col])))
##         x_num <- x_num[!is.na(x_num)]
##         
##         if (length(x_num) == 0) {
##           next
##         }
##         
##         tests_run = tests_run + 1
##         
##         min_val <- min(x_num)
##         max_val <- max(x_num)
##         
##         if (sample(c(TRUE, FALSE), 1)) {
##           input[input_index] <- min_val - runif(1, 1, 100)
##         } else {
##           input[input_index] <- max_val + runif(1, 1, 100)
##         }
##       }
##       
##       if (test_type == 'mismatched_inputs') {
##         num_extra = sample(1:20, 1)
##         input = append(input, sample(0:1000, num_extra))
##       }
##       
##       if (test_type == 'one_row_df') {
##         input <- as.data.frame(as.list(input), stringsAsFactors = FALSE)
##       }
##       
##       SIs = suppressWarnings(try(SIcalc(model, input), silent = TRUE))
##       
##       if (!inherits(SIs, "try-error") && all(SIs >= 0 & SIs <= 1 | is.na(SIs))) {
##         passes = passes + 1
##       }
##     }
##   }
##   
##   if (test_type == 'HSImodels') {
##     return(passes / (iterations * 349) * 100)
##   } else if (test_type %in% c('manual', 'parameter_NA', 'one_row_df')) {
##     return(passes / iterations * 100)
##   } else if (test_type == 'minmax_caps') {
##     return(passes / tests_run * 100)
##   } else {
##     return((iterations - passes) / iterations * 100)
##   }
## }
## 
## SIcalc_tester('HSImodels', 100)
## SIcalc_tester('manual', 9999)
## SIcalc_tester('parameter_NA', 9999)
## SIcalc_tester('invalid', 9999) #now tests only wrong categorical inputs
## SIcalc_tester('mismatched_inputs', 9999) 
## SIcalc_tester('one_row_df', 9999)
## SIcalc_tester('minmax_caps', 9999)
## ################################################################################
## 
## # HUcalc
## 
## HUcalc_tester = function(test_type, iterations) {
##   passes = 0 # set initial passes to zero
##   
##   # Make sure test_types are correct
##   if (!test_type %in% c('expected', 'invalid', 'NA', 'invalid_area', 'dataframe')) {
##     stop("Error: invalid test type. Please enter one of the following: 'NA', 'expected', 'invalid', 'invalid_area', 'dataframe'.", call. = F)
##   }
##   
##   functions = c('HSIarimean', 'HSIgeomean', 'HSImin', 'HSIwarimean', 'mean', 'max', 'min') # functions to use
##   
##   for (i in 1:iterations) {
##     inputs = c() # reset inputs
##     num_SIV = sample(2:20, 1) # randomly select a number of inputs
##     inputs = runif(num_SIV, min = 0, max = 1) # randomly generate inputs
##     area = sample(1:500, 1) # randomly generate area
##     use = sample(1:7, 1)
##     if (test_type == 'NA') {
##       num_NA = sample(1:(num_SIV - 1), 1)
##       inputs[sample(length(inputs), num_NA)] = NA # randomly replace some values with NA
##     } else if (test_type == 'invalid') {
##       num_invalid = sample(1:num_SIV, 1) # randomly decide number of invalid
##       type_invalid = sample(1:3, 1) # randomly determine the type of invalid input
##       if (type_invalid == 1) {
##         invalid = sample(
##           runif(1000, -10.4, 10.4) |> (\(x) x[x < 0 | x > 1])(),
##           size = num_invalid,
##           replace = TRUE
##         ) # randomly generate invalid values
##       } else if (type_invalid == 2) {
##         invalid = sample(letters, num_invalid)
##       } else {
##         invalid = rep(Inf, num_invalid)
##       }
##     
##       inputs[sample(length(inputs), num_invalid)] = invalid 
##     } else if (test_type == 'invalid_area') {
##         invalid_type = sample(1:3, 1)
##         if (invalid_type == 1) {
##           area = sample(-1000:-0.01, 1)
##         } else if (invalid_type == 2) {
##           area = sample(letters, 1)
##         } else {
##           area = Inf
##         }
##     } else if (test_type == 'dataframe') {
##       inputs = data.frame(inputs)
##     }
##     if (functions[use] == 'HSIwarimean') {
##       weights_raw = runif(num_SIV) # randomly generate weights
##       
##       weights <- weights_raw
##       
##       weights[is.na(inputs)] <- NA
##       
##       weights <- weights / sum(weights, na.rm = TRUE)
##       
##       weights[max(which(!is.na(weights)))] <-
##         weights[max(which(!is.na(weights)))] + (1 - sum(weights, na.rm = TRUE))
##       
##       hu = suppressWarnings(try(HUcalc(inputs, area, eval(parse(text = functions[use])), weights), silent = T))
##     } else {
##       hu = suppressWarnings(try(HUcalc(inputs, area, eval(parse(text = functions[use]))), silent = T))
##     }
##     if (!inherits(hu, 'try-error') & is.data.frame(hu)) {
##       passes = passes + 1
##     } 
##   }
##   # Pass rate
##   if (test_type %in% c('expected', 'NA', 'dataframe')) {
##     return(passes / iterations * 100) # if results should be valid, return the pass rate
##   } else {
##     return((iterations - passes) / iterations * 100) # if results should be errors, return the fail rate
##   }
## }
## 
## HUcalc_tester('expected', 9999)
## HUcalc_tester('NA', 9999)
## HUcalc_tester('invalid', 9999)
## HUcalc_tester('invalid_area', 9999)
## HUcalc_tester('dataframe', 9999)
## 
## ################################################################################
## 
## # HSIplotter
## 
## HSIplotter_tester = function(test_type, iterations = 349) {
##   # Make sure test_type is correct
##   if (!test_type %in% c('blue-book', 'manual', 'invalid')) {
##     stop("Invalid test type. Please enter one of the following: 'blue-book', 'manual', 'invalid'.", call. = F)
##   }
##   
##   # If testing blue book models:
##   if (test_type == 'blue-book') {
##     if(!dir.exists('Bluebook_tests')) {
##       dir.create("Bluebook_tests")
##     }
##     for (i in 1:nrow(HSImetadata)) {
##       mod=HSImodels[i]
##       name=names(mod[1])
##       model <- get(name,mod)
##       try(HSIplotter(model, paste(getwd(), '/Bluebook_tests', '/', name, sep = "",".png")))
##     }
##   }
##   # If testing manual inputs
##   else if (test_type == 'manual') {
##     if(!dir.exists('Manual_tests')) {
##       dir.create("Manual_tests")
##     }
##     for (test in 1:iterations) {
##       model = c() # reset model
##       num_vars = sample(1:10, 1) # randomly set the number of variables to a value between one and ten
##       var_names = paste0('var_', 1:num_vars)
##       siv_names = paste0('var_', 1:num_vars, '.SIV')
##       for (var in 1:num_vars) {
##         num_SIV = sample(2:15, 1) # randomly set the number of SIVs between 1 and 15
##         cat = sample(0:1, 1) # randomly choose if variable is categorical (1) or not (0)
##       
##         if (cat == 1) {
##         categories = letters[1:num_SIV] # set categories to equal letters
##         } else {
##           categories = as.numeric(sort(sample(0:1000, num_SIV))) # if continuous, randomly select values between 0 and 1000
##         }
##         ## Randomly generate SIVs
##         SIVs = runif(num_SIV, min = 0, max = 1)
##         ## Add NAs to equal 15
##         SIVs = c(SIVs, rep(NA, 15 - num_SIV)) # add NAs if needed
##         categories = c(categories, rep(NA, 15 - num_SIV)) # add NAs if needed
##         model = cbind(model, categories, SIVs) # bind data
##       }
##         colnames(model) = c(rbind(var_names, siv_names)) # name columns
##         model = data.frame(model) # convert to dataframe
##         model = model[rowSums(is.na(model)) < ncol(model), ] # Remove rows that are all NA
##         model[] <- lapply(model, function(x) {
##           num <- suppressWarnings(as.numeric(x))
##           
##           # convert only if every non-NA value successfully became numeric
##           if (all(is.na(x) | !is.na(num))) {
##             num
##           } else {
##             x
##           }
##         })
##         try(HSIplotter(model, paste(getwd(), '/Manual_tests/model', test, sep = "",".png"))) # try graphing
##         model = c() # reset model
##     }
##     dev.off()
##   } else if (test_type == 'invalid') {
##       if(!dir.exists('Invalid_tests')) {
##         dir.create("Invalid_tests")
##       }
##       for (test in 1:iterations) {
##         model = c() # reset model
##         num_vars = sample(1:10, 1) # randomly set the number of variables to a value between one and ten
##         var_names = paste0('var_', 1:num_vars)
##         siv_names = paste0('var_', 1:num_vars, '.SIV')
##         for (var in 1:num_vars) {
##           num_SIV = sample(2:15, 1) # randomly set the number of SIVs between 1 and 15
##           cat = sample(0:1, 1) # randomly choose if variable is categorical (1) or not (0)
##         
##           if (cat == 1) {
##             categories = letters[1:num_SIV] # set categories to equal letters
##           } else {
##             categories = as.numeric(sort(sample(0:1000, num_SIV))) # if continuous, randomly select values between 0 and 1000
##           }
##           ## Randomly generate SIVs
##           SIVs = runif(num_SIV, min = 0, max = 1)
##           ## Add NAs to equal 15
##           SIVs = c(SIVs, rep(NA, 15 - num_SIV)) # add NAs if needed
##           categories = c(categories, rep(NA, 15 - num_SIV)) # add NAs if needed
##           model = cbind(model, categories, SIVs) # bind data
##         }
##         colnames(model) = c(rbind(var_names, siv_names)) # name columns
##         model = data.frame(model) # convert to dataframe
##         model = model[rowSums(is.na(model)) < ncol(model), ] # Remove rows that are all NA
##         model[] <- lapply(model, function(x) {
##           num <- suppressWarnings(as.numeric(x))
##         
##           # convert only if every non-NA value successfully became numeric
##           if (all(is.na(x) | !is.na(num))) {
##             num
##           } else {
##             x
##           }
##         })
##         invalid_loc = sample(1:length(model), 1) # randomly select a column to mess up
##         invalid_type = sample(1:2, 1) # randomly select the type of invalid input
##         
##         if (invalid_type == 1) {
##           if (invalid_loc %% 2 == 0) {
##             model[1, invalid_loc] = sample(
##               runif(1000, -10.4, 10.4) |> (\(x) x[x < 0 | x > 1])(),
##               size = 1,
##               replace = TRUE
##             ) # randomly generate invalid values
##           } else {
##             invalid_loc = invalid_loc + 1
##             model[1, invalid_loc] = sample(
##               runif(1000, -10.4, 10.4) |> (\(x) x[x < 0 | x > 1])(),
##               size = 1,
##               replace = TRUE
##             ) # randomly generate invalid values
##           }
##         } else {
##           model[1, invalid_loc] = Inf
##         }
##         
##         try(HSIplotter(model, paste(getwd(), '/Invalid_tests/model', test, sep = "",".png")), silent = T) # try graphing
##         model = c() # reset model
##       }
##       dev.off()
##   }
## }
## 
## HSIplotter_tester('blue-book')
## HSIplotter_tester('manual', 349)
## HSIplotter_tester('invalid', 349)
## 
## ################################################################################
## 
## # annualizer
## 
## annualizer_test = function(test_type = 'expected', iterations) {
##   passes = 0 # Set number of passes to zero
##   if (!test_type %in% c('NA', 'expected', 'wrong_time', 'wrong_benefit', 'wrong_order', 'duplicate_time', 'invalid_time', 'invalid_benefit', 'dataframe')) {
##     stop("Error: invalid test type. Please enter one of the following: 'NA', 'expected', 'wrong_time', 'wrong_benefit', 'wrong_order, 'duplicate_time', 'invalid_time', 'invalid_benefit', 'dataframe'.", call. = F)
##   }
##   
##   for (i in 1:iterations) {
##     num_inputs = sample(2:100, 1) # randomly generate number of inputs between 2 and 100
##     timevec = sort(sample(0:100, size = num_inputs)) # Randomly select time values with size num_inputs 
##     benefits = sample(0:100, size = num_inputs) # Randomly generate benefit values with size num_inputs
##     num_NA = 0 # specify no NA values
##     
##   if (test_type == 'NA') {
##     num_NA = sample(1:(num_inputs - 1), 1) # randomly select number of NA values to be included
##     timevec[sample(length(timevec), num_NA)] = NA # randomly replace some values with NA
##     na_locations <- is.na(timevec) # store where NA values occur
##     benefits[na_locations] = NA # replace same locations in benefits vector with NA
##   }
##   
##   else if (test_type == 'wrong_time') {
##     num_extra = sample(1:20, 1) # decide how many extra values to provide as inputs
##     timevec = append(timevec, sample(1:500, num_extra)) # append to timevec vector
##   }
##   
##   else if (test_type == 'wrong_benefit') {
##     num_extra = sample(1:20, 1) # decide how many extra values to provide as inputs
##     benefits = append(benefits, sample(1:500, num_extra)) # append to benefits vector
##   } 
##   
##   else if (test_type == 'wrong_order') {
##     # Shuffle timevec until it is out of order
##     while (identical(timevec, sort(timevec))) {
##       timevec = sample(timevec)
##     }
##   }
##     
##   else if (test_type == 'duplicate_time') {
##     dup_position = sample(1:length(timevec), 1) # select time value to duplicate
##     rep_position = sample(1:length(timevec), 1) # select value to replace with duplicate
##     # Make sure the two positions are not the same
##     while (dup_position == rep_position) {
##       rep_position = sample(1:length(timevec), 1) # select value to replace with duplicate
##     }
##     timevec[rep_position] = timevec[dup_position]
##   }
##     
##   else if (test_type == 'invalid_time') {
##     invalid_type = sample(1:3, 1) # randomly select what type of invalid input
##     if (invalid_type == 1) {
##       timevec[1] = sample(-1000:-0.01, 1)
##     } else if (invalid_type == 2) {
##       timevec[1] = sample(letters, 1)
##     } else {
##       timevec[1] = Inf
##     }
##   }
##     
##   else if (test_type == 'invalid_benefit') {
##     invalid_type = sample(1:3, 1) # randomly select what type of invalid input
##     if (invalid_type == 1) {
##       benefits[1] = sample(-1000:-0.01, 1)
##     } else if (invalid_type == 2) {
##       benefits[1] = sample(letters, 1)
##     } else {
##       benefits[1] = Inf
##     }
##   }
##     
##   else if (test_type == 'dataframe') {
##     timevec = data.frame(timevec)
##     benefits = data.frame(benefits)
##   }
##     
##   
##   result = suppressWarnings(try(annualizer(timevec, benefits), silent = T)) # Calculate time-averaged value
##   
##   ## If the result is numeric and is not NA or NA_real, pass
##   if (is.numeric(result) & !is.na(result))
##     passes = passes + 1
##   }
##   # Pass rate
##   if (test_type %in% c('expected', 'wrong_order', 'dataframe')) {
##     return(passes / iterations * 100) # if results should be valid, return the pass rate
##   } else {
##     return((iterations - passes) / iterations * 100) # if results should be errors, return the fail rate
##   }
## }
## 
## annualizer_test(test_type = 'expected', iterations = 9999)
## annualizer_test(test_type = 'NA', iterations = 9999)
## annualizer_test(test_type = 'wrong_time', iterations = 9999)
## annualizer_test(test_type = 'wrong_benefit', iterations = 9999)
## annualizer_test(test_type = 'wrong_order', iterations = 9999)
## annualizer_test(test_type = 'duplicate_time', iterations = 9999)
## annualizer_test(test_type = 'invalid_time', iterations = 9999)
## annualizer_test(test_type = 'invalid_benefit', iterations = 9999)
## annualizer_test(test_type = 'dataframe', iterations = 9999)
## 
## # Test specific inputs to ensure math calculations are correct
## timevec=c(0, 10) 
## benefits = c(2, 10)
## 
## annualizer(timevec, benefits)
## 
## ################################################################################
## 
## # CEfinder
## 
## CEfinder_tester = function(test_type = 'expected', iterations) {
##   passes = 0 # Set number of passes to zero
##   ## Make sure the correct tests are being run
##   if (!test_type %in% c('NA', 'expected', 'wrong_cost', 'wrong_benefit', 'invalid_cost', 'invalid_benefit', 'dataframe')) {
##     stop("Error: invalid test type. Please enter one of the following: 'NA', 'expected', 'wrong_cost', 'wrong_benefit', 'invalid_cost', 'invalid_benefit', 'dataframe'.", call. = F)
##   }
##   for (i in 1:iterations) {
##     num_inputs = sample(2:20, 1) # randomly select a number of samples
##     benefit = sample(0:100, num_inputs) # randomly sample num_inputs benefits
##     cost = sample(0:500, num_inputs) # randomly sample num_inputs costs
##     
##     if (test_type == 'NA') {
##       num_NA = sample(1:(num_inputs - 1), 1) # randomly select number of NA values to be included
##       benefit[sample(length(benefit), num_NA)] = NA # randomly replace some values with NA
##       na_locations <- is.na(benefit) # store where NA values occur
##       cost[na_locations] = NA # replace same locations in benefits vector with NA
##     } else if (test_type == 'wrong_benefit') {
##       num_extra = sample(1:20, 1) # decide how many extra values to provide as inputs
##       benefit = append(benefit, sample(1:500, num_extra)) # append to benefits vector
##     } else if (test_type == 'wrong_cost') {
##       num_extra = sample(1:20, 1) # decide how many extra values to provide as inputs
##       cost = append(cost, sample(1:500, num_extra)) # append to benefits vector
##     }
##     
##     else if (test_type == 'invalid_cost') {
##       invalid_type = sample(1:3, 1) # randomly select what type of invalid input
##       if (invalid_type == 1) {
##         cost[1] = sample(-1000:-0.01, 1)
##       } else if (invalid_type == 2) {
##         cost[1] = sample(letters, 1)
##       } else {
##         cost[1] = Inf
##       }
##     }
##     
##     else if (test_type == 'invalid_benefit') {
##       invalid_type = sample(1:3, 1) # randomly select what type of invalid input
##       if (invalid_type == 1) {
##         benefit[1] = sample(-1000:-0.01, 1)
##       } else if (invalid_type == 2) {
##         benefit[1] = sample(letters, 1)
##       } else {
##         benefit[1] = Inf
##       }
##     }
##     
##     else if (test_type == 'dataframe') {
##       benefit = data.frame(benefit)
##       cost = data.frame(cost)
##     }
##     
##     CE = try(CEfinder(benefit, cost), silent = T) # calculate cost effectiveness of each plan
##     
##     ## If all outputs are binary, pass
##     if (all(unique(CE) %in% c(0, 1))) {
##       passes = passes + 1
##     }
##   }
##   # Pass rate
##   if (test_type %in% c('expected', 'dataframe')) {
##     return(passes / iterations * 100) # if results should be valid, return the pass rate
##   } else {
##     return((iterations - passes) / iterations * 100) # if results should be errors, return the fail rate
##   }
## }
## 
## 
## CEfinder_tester('expected', 9999)
## CEfinder_tester('NA', 9999)
## CEfinder_tester('wrong_benefit', 9999)
## CEfinder_tester('wrong_cost', 9999)
## CEfinder_tester('invalid_cost', 9999)
## CEfinder_tester('invalid_benefit', 9999)
## CEfinder_tester('dataframe', 9999)
## 
## ################################################################################
## 
## 
## # BBfinder
## 
## BBfinder_tester = function(test_type = 'expected', iterations) {
##   passes = 0 # Set number of passes to zero
##   ## Make sure the correct tests are being run
##   if (!test_type %in% c('NA', 'expected', 'wrong_cost', 'wrong_benefit', 'wrong_plans', 'invalid_benefit', 'invalid_cost', 'invalid_CE', 'duplicate_benefit', 'dataframe')) {
##     stop("Error: invalid test type. Please enter one of the following: 'NA', 'expected', 'wrong_cost', 'wrong_benefit', 'wrong_plans', 'invalid', 'invalid_benefit', 'invalid_cost', 'invalid_CE', 'duplicate_benefit, 'dataframe'.", call. = F)
##   }
##     for (i in 1:iterations) {
##       num_inputs = sample(2:20, 1) # randomly select a number of samples
##       benefit = sample(0:100, num_inputs) # randomly sample num_inputs benefits
##       cost = sample(0:500, num_inputs) # randomly sample num_inputs costs
##       CE = CEfinder(benefit, cost)
##       
##       while (sum(CE, na.rm = T) <= 1) {
##         num_inputs = sample(2:20, 1) # randomly select a number of samples
##         benefit = sample(0:100, num_inputs) # randomly sample num_inputs benefits
##         cost = sample(0:500, num_inputs) # randomly sample num_inputs costs
##         CE = CEfinder(benefit, cost)
##       }
##        ## If NAs are included, add NAS
##       if (test_type == 'NA') {
##         num_NA = sample(1:(num_inputs - 1), 1) # randomly select number of NA values to be included
##         benefit[sample(length(benefit), num_NA)] = NA # randomly replace some values with NA
##         na_locations <- is.na(benefit) # store where NA values occur
##         cost[na_locations] = NA # replace same locations in cost vector with NA
##         CE[na_locations] = NA # replace same locations in CE vector with NA
##         
##         while (sum(CE, na.rm = T) <= 1) {
##           num_inputs = sample(2:20, 1) # randomly select a number of samples
##           benefit = sample(0:100, num_inputs) # randomly sample num_inputs benefits
##           cost = sample(0:500, num_inputs) # randomly sample num_inputs costs
##           CE = CEfinder(benefit, cost)
##           
##           num_NA = sample(1:(num_inputs - 1), 1) # randomly select number of NA values to be included
##           benefit[sample(length(benefit), num_NA)] = NA # randomly replace some values with NA
##           na_locations <- is.na(benefit) # store where NA values occur
##           cost[na_locations] = NA # replace same locations in cost vector with NA
##           CE[na_locations] = NA # replace same locations in CE vector with NA
##         }
##       } else if (test_type == 'wrong_benefit') {
##         num_extra = sample(1:20, 1) # decide how many extra values to provide as inputs
##         benefit = append(benefit, sample(1:500, num_extra)) # append to benefit vector
##       } else if (test_type == 'wrong_cost') {
##         num_extra = sample(1:20, 1) # decide how many extra values to provide as inputs
##         cost = append(cost, sample(1:500, num_extra)) # append to benefits vector
##       } else if (test_type == 'wrong_plans') {
##         num_extra = sample(1:20, 1) # decide how many extra values to provide as inputs
##         CE = append(CE, sample(0:1, num_extra, replace = T)) # append to benefits vector
##       } else if (test_type == 'invalid_cost') {
##           invalid_type = sample(1:3, 1) # randomly select what type of invalid input
##           if (invalid_type == 1) {
##             cost[1] = sample(-1000:-0.01, 1)
##           } else if (invalid_type == 2) {
##             cost[1] = sample(letters, 1)
##           } else {
##             cost[1] = Inf
##           }
##       } else if (test_type == 'invalid_benefit') {
##           invalid_type = sample(1:3, 1) # randomly select what type of invalid input
##           if (invalid_type == 1) {
##             benefit[1] = sample(-1000:-0.01, 1)
##           } else if (invalid_type == 2) {
##             benefit[1] = sample(letters, 1)
##           } else {
##             benefit[1] = Inf
##           }
##       } else if (test_type == 'invalid_CE') {
##           invalid_type = sample(1:4, 1) # randomly select what type of invalid input
##           if (invalid_type == 1) {
##             CE[1] = sample(-1000:-0.01, 1)
##           } else if (invalid_type == 2) {
##             CE[1] = sample(letters, 1)
##           } else if (invalid_type == 3) {
##             CE[1] = Inf
##           } else {
##             CE[1] = sample(2:200, 1)
##           } 
##       } else if (test_type == 'duplicate_benefit') {
##           dup_position = sample(1:length(benefit), 1) # select time value to duplicate
##           rep_position = sample(1:length(benefit), 1) # select value to replace with duplicate
##           # Make sure the two positions are not the same
##           while (dup_position == rep_position) {
##             rep_position = sample(1:length(benefit), 1) # select value to replace with duplicate
##           }
##           benefit[rep_position] = benefit[dup_position]
##       } else if (test_type == 'dataframe') {
##         benefit = data.frame(benefit)
##         cost = data.frame(cost)
##         CE = data.frame(CE)
##       }
##     
##       
##       
##       result = suppressWarnings(try(BBfinder(benefit, cost, CE), silent = TRUE))
##       
##       if (!inherits(result, 'try-error') & is.list(result)) {
##         passes = passes + 1
##       }
##     }
##     # Pass rate
##     if (test_type %in% c('expected', 'duplicate_benefit', 'dataframe')) {
##       return(passes / iterations * 100) # if results should be valid, return the pass rate
##     } else {
##       return((iterations - passes) / iterations * 100) # if results should be errors, return the fail rate
##     }
## }
## 
## BBfinder_tester('expected', 9999)
## BBfinder_tester('NA', 9999)
## BBfinder_tester('wrong_benefit', 9999)
## BBfinder_tester('wrong_cost', 9999)
## BBfinder_tester('wrong_plans', 9999)
## BBfinder_tester('invalid_benefit', 9999)
## BBfinder_tester('invalid_cost', 9999)
## BBfinder_tester('invalid_CE', 9999)
## BBfinder_tester('duplicate_benefit', 9999)
## BBfinder_tester('dataframe', 9999)
## 
## ################################################################################
## 
## ## CEICAplotter
## 
## CEICAplotter_tester = function(test_type = 'expected', iterations) {
##   ## Make sure the correct tests are being run
##   if (!test_type %in% c('expected', 'dataframe')) {
##     stop("Error: invalid test type. Please enter one of the following: 'expected', 'dataframe.", call. = F)
##   }
##   
##   if(!dir.exists('CEICA_tests')) {
##     dir.create("CEICA_tests")
##   }
##   
##   for (i in 1:iterations) {
##     num_inputs = sample(1:20, 1) # randomly select a number of samples
##     benefit = sample(0:100, num_inputs) # randomly sample num_inputs benefits
##     cost = sample(0:500, num_inputs) # randomly sample num_inputs costs
##     CE <- CEfinder(benefit, cost)
##     
##     while (sum(CE, na.rm = T) <= 1) {
##       num_inputs = sample(2:20, 1) # randomly select a number of samples
##       benefit = sample(0:100, num_inputs) # randomly sample num_inputs benefits
##       cost = sample(0:500, num_inputs) # randomly sample num_inputs costs
##       CE = CEfinder(benefit, cost)
##     }
##     
##     BB <- BBfinder(benefit, cost, CE)[[1]][,4]
##     altnames = paste("Alt", seq(1:num_inputs), sep = "")
##     
##     if (test_type == 'dataframe') {
##       altnames = data.frame(altnames)
##       benefit = data.frame(benefit)
##       cost = data.frame(cost)
##       CE = data.frame(CE)
##       BB = data.frame(BB)
##     }
##     try(CEICAplotter(altnames, benefit, cost, CE, BB, paste(getwd(), '/CEICA_tests/test', i, sep = "",".jpeg")))
##   }
## }
## 
## CEICAplotter_tester('expected', 300)
## CEICAplotter_tester('dataframe', 300)
Table C-2. Testing records for functions in ecorest.
Function Test Example output Number of tests Expected output Pass rate Outcome
HSImin Inputs for expected values c(0.25, 0.25, 0.5, 0.75) 9999 Numeric output between 0 and 1 equal to the minimum of the inputs 100% Pass
Inputs with NA values c(0.25, NA, 0.5, 0.75) 9999 Numeric output between 0 and 1 equal to the minimum of the non-NA inputs 100% Pass
Inputs formatted as data frames or matrices data.frame(0.25, 0.25, 0.5, 0.75) 9999 Numeric output between 0 and 1 equal to the minimum of the inputs 100% Pass
Inputs with invalid or out of range values (e.g., < 0 or > 1, Inf, character inputs) c(0.25, 0.25, 5.7, 0.75) 9999 Error message 100% Pass
HSIarimean Inputs for expected values c(0.25, 0.25, 0.5, 0.75) 9999 Numeric output between 0 and 1 equal to the arithmetic mean of the inputs 100% Pass
Inputs with NA values c(0.25, NA, 0.5, 0.75) 9999 Numeric output between 0 and 1 equal to the arithmetic mean of the non-NA inputs 100% Pass
Inputs formatted as data frames or matrices data.frame(0.25, 0.25, 0.5, 0.75) 9999 Numeric output between 0 and 1 equal to the arithmetic mean of the inputs 100% Pass
Inputs with invalid or out of range values (e.g., < 0 or > 1, Inf, character inputs) c(0.25, 0.25, 5.7, 0.75) 9999 Error message 100% Pass
HSIgeomean Inputs for expected values c(0.25, 0.25, 0.5, 0.75) 9999 Numeric output between 0 and 1 equal to the geometric mean of the inputs 100% Pass
Inputs with NA values c(0.25, NA, 0.5, 0.75) 9999 Numeric output between 0 and 1 equal to the geometric mean of the non-NA inputs 100% Pass
Inputs formatted as data frames or matrices data.frame(0.25, 0.25, 0.5, 0.75) 9999 Numeric output between 0 and 1 equal to the geometric mean of the inputs 100% Pass
Inputs with invalid or out of range values (e.g., < 0 or > 1, Inf, character inputs) c(0.25, 0.25, 5.7, 0.75) 9999 Error message 100% Pass
HSIwarimean Inputs for expected values c(0.25, 0.25, 0.5, 0.75), c(0.2, 0.3, 0.4, 0.1) 9999 Numeric output between 0 and 1 equal to the weighted arithmetic mean of the inputs 100% Pass
Inputs with NA values c(0.25, NA, 0.5, 0.75), c(0.2, NA, 0.4, 0.1) 9999 Numeric output between 0 and 1 equal to the weighted arithmetic mean of the non-NA inputs 100% Pass
Inputs formatted as data frames or matrices data.frame(0.25, 0.25, 0.5, 0.75), data.frame(0.2, 0.3, 0.4, 0.1) 9999 Numeric output between 0 and 1 equal to the weighted arithmetic mean of the inputs 100% Pass
Inputs with invalid or out of range values (e.g., < 0 or > 1, Inf, character inputs) c(0.25, 5.7, 0.5, 0.75), c(0.2, 0.3, 0.4, 0.1) 9999 Error message 100% Pass
Inputs with incorrect weighting c(0.25, 0.25, 0.5, 0.75), c(0.2, 0.96, 0.4, 0.1) 9999 Error message 100% Pass
Inputs with incorrect number of weights supplied c(0.25, 0.25, 0.5, 0.75), c(0.2, 0.3, 0.2, 0.2, 0.1) 9999 Error message 100% Pass
HSIeqtn Inputs for expected values ‘alewifeJuv’, c(0, 1, 1), HSImetadata, NULL 100 per model Numeric output between 0 and 1 100% Pass
Inputs formatted as data frames or matrices ‘alewifeJuv’, data.frame(0, 1, 1), HSImetadata, NULL 100 per model Numeric output between 0 and 1 100% Pass
Inputs with incorrect HSImodelname ‘alewifeJuvaes’, c(0, 1, 1), HSImetadata, NULL 100 per model Error message 100% Pass
Inputs with invalid SIV values (e.g., < 0 or > 1, Inf, character inputs) ‘alewifeJuv’, c(0, 3.2, 1), HSImetadata, NULL 100 per model Error message 100% Pass
Inputs with incorrect number of SIV values ‘alewifeJuv’, c(0, 1, 1, 0.75), HSImetadata, NULL 100 per model Error message 100% Pass
SIcalc Inputs with expected values from HSImodels HSImodels barredowl, c(4, 40, 60)] 100 per model Numeric outputs between 0 and 1 representing suitability index values for each input parameter 100% Pass
Inputs with expected values from manual models Manual dataframe, c(4, 40, 60) 9999 Numeric outputs between 0 and 1 representing suitability index values for each input parameter 100% Pass
Inputs with NA values for parameters Manual dataframe, c(4, NA, 60) 9999 Numeric outputs between 0 and 1 representing suitability index values for each non-NA input parameter 100% Pass
Inputs with invalid or out of range values Manual dataframe, c(4, 40, 1000) 9999 Error message 100% Pass
Inputs with incorrect number of values supplied Manual dataframe, c(4, 40, 60, 50) 9999 Error message 100% Pass
Inputs formatted as data frames or matrices Manual dataframe, c(4, 40, 60) 9999 Numeric outputs between 0 and 1 representing suitability index values for each input parameter 100% Pass
Hucalc Inputs for expected values c(0, 0.1, 1), 100, HSImin 9999 Dataframe containing habitat quality, quantity, and index units 100% Pass
Inputs with NA values c(0, NA, 1), 100, HSImin 9999 Dataframe containing habitat quality, quantity, and index units, excluding NA variables 100% Pass
Inputs formatted as data frames or matrices data.frame(0, 0.1, 1), 100, HSImin) 9999 Dataframe containing habitat quality, quantity, and index units 100% Pass
Inputs with invalid values c(0, 5.7, 1), 100, HSImin 9999 Error message 100% Pass
Inputs with negative, infinite, or character habitat quantities c(0, 0.1, 1), -100, HSImin 9999 Error message 100% Pass
HSIplotter Inputs using HSImodels HSImodels barredowl, “Barred_owl_curves.jpeg”) 349 Jpeg file with curves corresponding to HSImodels 100% Pass
Inputs for manual models Manual data frame of breakpoints, “Model_curves.jpeg”) 349 Jpeg file with randomly generated curves 100% Pass
Inputs with invalid or out of range values (e.g., < 0 or > 1, Inf, character inputs) Manual data frame of breakpoints with some incorrect values, “Model_curves.jpeg”) 349 Error message 100% Pass
annualizer Inputs for expected values c(0, 50), c(100, 100) 9999 Numeric output equal to the time-averaged value over the specified time horizon 100% Pass
Inputs with NA values c(0, NA), c(100, NA) 9999 NA 100% Pass
Inputs formatted as data frames or matrices data.frame(c(1,2 ,3 ,4)), data.frame(c(20, 30, 40, 50)) 9999 Numeric output equal to the time-averaged value over the specified time horizon 100% Pass
Inputs with incorrect number of time values c(0, 50, 100), c(100, 100) 9999 Error message 100% Pass
Inputs with incorrect number of benefit values c(0, 100), c(100, 50, 100) 9999 Error message 100% Pass
Inputs with out of order time values c(0, 50, 47), c(100, 100, 50) 9999 Numeric output equal to the time-averaged value over the specified time horizon, ordered from smallest to largest 100% Pass
Inputs with duplicate time values c(0, 50, 50), c(100, 50, 50) 9999 Error message 100% Pass
Inputs with invalid time values c(-4, 50), c(100, 100) 9999 Error message 100% Pass
Inputs with invalid benefit values c(0, 50), c(Inf, 100) 9999 Error message 100% Pass
CEfinder Inputs for expected values c(0, 10, 20), c(0, 100, 200) 9999 Vector of binary (0, 1) outputs reporting whether each plan is cost-effective 100% Pass
Inputs formatted as data frames or matrices data.frame(c(20, 30, 40)), data.frame(c(30, 40, 50)) 9999 Vector of binary (0, 1) outputs reporting whether each plan is cost-effective 100% Pass
Inputs with NA values c(0, NA, 20), c(0, NA, 200) 9999 Error message 100% Pass
Inputs with incorrect number of benefit values c(0, 10, 20, 30), c(0, 100, 200) 9999 Error message 100% Pass
Inputs with incorrect number of cost values c(0, 10, 20), c(0, 100, 200, 300) 9999 Error message 100% Pass
Inputs with invalid benefit values c(0, 10, 20), c(Inf, 100, 200) 9999 Error message 100% Pass
Inputs with invalid cost values c(0, -10, 20), c(0, 100, 200) 9999 Error message 100% Pass
BBfinder Inputs for expected values c(0, 10, 5), c(0, 100, 200), c(1, 1, 0) 9999 List containing summary of all restoration actions and best buy plans 100% Pass
Inputs formatted as data frames or matrices data.frame(c(0, 10, 5)), data.frame(c(0, 100, 200)), data.frame(c(1, 1, 0)) 9999 List containing summary of all restoration actions and best buy plans 100% Pass
Inputs with NA values c(0, NA, 5), c(0, NA, 200), c(1, NA, 1) 9999 Error message 100% Pass
Inputs with incorrect number of benefit values c(0, 10, 4, 5), c(0, 100, 200), c(1, 1, 0) 9999 Error message 100% Pass
Inputs with incorrect number of cost values c(0, 10, 5), c(0, 100, 150, 200), c(1, 1, 0) 9999 Error message 100% Pass
Inputs with incorrect number of cost-effective plan inputs c(0, 10, 5), c(0, 100, 200), c(1, 1, 0, 1) 9999 Error message 100% Pass
Inputs with invalid benefit values c(Inf, 10, 5), c(0, 100, 200), c(1, 1, 0) 9999 Error message 100% Pass
Inputs with invalid cost values c(0, 10, 5), c(0, -100, 200), c(1, 1, 0) 9999 Error message 100% Pass
Inputs with invalid CE values c(0, 10, 5), c(0, 100, 200), c(2, 1, 0) 9999 Error message 100% Pass
Inputs with duplicate benefits c(10, 10, 5), c(0, 100, 200), c(1, 1, 0) 9999 List containing summary of restoration actions and best buy plans with lowest cost duplicate benefit retained 100% Pass
CEICAplotter Inputs with expected values c(“Alt_1”, “Alt_2”, “Alt_3”), c(20, 30, 40), c(100, 75, 150), c(1, 0, 1), c(1, 0, 1), “CEICA.jpeg” 300 Jpeg output 100% Pass
Inputs formatted as data frames or matrices data.frame(c(“Alt_1”, “Alt_2”, “Alt_3”)), data.frame(c(20, 30, 40)), data.frame(c(100, 75, 150)), data.frame(c(1, 0, 1)), data.frame(c(1, 0, 1)), “CEICA.jpeg” 300 Jpeg output 100% Pass

Appendix D: Example of Sensitivity Analysis

A tutorial on how to conduct sensitivity and uncertainty analysis for HSI models can be found here: https://usace-wrises.github.io/USACE.EcoMod.Training/sensitivity-and-uncertainty-analysis-for-habitat-suitability-index-hsi-models.html

Appendix E: Example Applications

Appendix E provides example applications demonstrating how ecorest functions can be used individually and in combination to support ecosystem restoration analyses. The examples are intended to show practical workflows rather than prescribe a single approach. They include a single-site existing condition assessment using multiple packaged U.S. Fish and Wildlife Service models, application of a user-specified model using the San Francisco Tidal Habitats and Resilience Evaluation framework, comparison of single-site habitat restoration alternatives using cost-effectiveness and incremental cost analyses (CEICA), and comparison of multi-site restoration prioritization using habitat units and CEICA. Together, these examples illustrate how ecorest can support habitat assessment, restoration planning, and comparison of alternatives across a range of restoration decision contexts.

E.1. Existing condition assessment over multiple sites using multiple USFWS models

This example demonstrates how ecorest can be used with U.S. Fish and Wildlife Service HSI models, included in the package, to assess existing condition over multiple project sites. The example uses packaged suitability curves and model equations for four species: Pileated Woodpecker (eastern range), Barred Owl, Gray Squirrel, and Mink. For each species, hypothetical field inputs for six sites were generated. Suitability curves were plotted with HSIplotter(), suitability indices were calculated with SIcalc(), and overall habitat suitability for each species and site was calculated with HSIeqtn().

Step 1: Load ecorest, model objects, and example field inputs for all species.

#library(ecorest)
site.names <- c("Delta", "Clinton", "Vicksburg", "Jackson", "Pearl", "Brandon")

# Pileated Woodpecker (eastern range)
PW.model <- HSImodels$pileatedwoodpeckerE
PW <- data.frame(
  Site = site.names,
  SIV1 = c(45, 30, 20, 2, 50, 75),
  SIV2 = c(15, 20, 23, 3, 27, 30),
  SIV3 = c(8, 5, 10, 2, 8, 10),
  SIV4 = c(0.25, 0, 0.10, 0, 0.5, 0.40),
  SIV5 = c(55, 40, 38, 38, 55, 60),
  SIV6 = c(NA, NA, NA, NA, NA, NA),
  SIV7 = c(NA, NA, NA, NA, NA, NA)
)

# Barred Owl
BO.model <- HSImodels$barredowl
BO <- data.frame(
  Site = site.names,
  SIV1 = c(2, 1, 2, 0, 1, 1),
  SIV2 = c(10, 51, 20, 5, 45, 42),
  SIV3 = c(30, 45, 50, 25, 80, 95)
)

# Gray Squirrel
GS.model <- HSImodels$graysquirrel
GS <- data.frame(
  Site = site.names,
  SIV1 = c(50, 45, 20, 15, 55, 37),
  SIV2 = c("c", "b", "c", "a", "d", "e"),
  SIV3 = c(55, 30, 20, 15, 5, 38),
  SIV4 = c(70, 55, 30, 25, 30, 51),
  SIV5 = c(50.8, 50, 25, 20, 12, 46)
)

# Mink (lacustrine model)
MNK.model <- HSImodels$minkRivLac
MNK <- data.frame(
  Site = site.names,
  SIV1 = c(75, 55, 20, 15, 90, 75),
  SIV2 = c(NA, NA, NA, NA, NA, NA),
  SIV3 = c(NA, NA, NA, NA, NA, NA),
  SIV4 = c(NA, NA, NA, NA, NA, NA),
  SIV5 = c(50, 40, 20, 15, 75, 50),
  SIV6 = c(70, 55, 30, 25, 90, 80)
)

Step 2: Plot suitability curves for all species with ‘HSIplotter()’

HSIplotter(PW.model, "PW.jpeg")
## Warning in HSIplotter(PW.model, "PW.jpeg"): U.S. Army Corps of Engineers users must have approval from the National Ecosystem 
##   Planning Center of Expertise (Eco-PCX) prior to application of a new model.
HSIplotter(BO.model, "BO.jpeg")
## Warning in HSIplotter(BO.model, "BO.jpeg"): U.S. Army Corps of Engineers users must have approval from the National Ecosystem 
##   Planning Center of Expertise (Eco-PCX) prior to application of a new model.
HSIplotter(GS.model, "GS.jpeg")
## Warning in HSIplotter(GS.model, "GS.jpeg"): U.S. Army Corps of Engineers users must have approval from the National Ecosystem 
##   Planning Center of Expertise (Eco-PCX) prior to application of a new model.
HSIplotter(MNK.model, "MNK.jpeg")
## Warning in HSIplotter(MNK.model, "MNK.jpeg"): U.S. Army Corps of Engineers users must have approval from the National Ecosystem 
##   Planning Center of Expertise (Eco-PCX) prior to application of a new model.
Figure E.1.1. Pileated Woodpecker (eastern range) suitability curves.
Figure E.1.1. Pileated Woodpecker (eastern range) suitability curves.
Figure E.1.2. Barred Owl suitability curves.
Figure E.1.2. Barred Owl suitability curves.
Figure E.1.3. Gray Squirrel suitability curves.
Figure E.1.3. Gray Squirrel suitability curves.
Figure E.1.4. Mink (lacustrine model) suitability curves.
Figure E.1.4. Mink (lacustrine model) suitability curves.


Step 3: Use SIcalc() to calculate suitability indices for all species.

# Pileated Woodpecker
input.PW <- PW[, 2:8]
nPW <- nrow(input.PW)
SI.PW <- matrix(NA, nrow = nPW, ncol = 7)
colnames(SI.PW) <- colnames(input.PW)

for(i in 1:nPW){
  SI.PW[i, ] <- suppressWarnings(
    SIcalc(PW.model, input.PW[i, ])
  )
}

# Barred Owl
input.BO <- BO[, 2:4]
nBO <- nrow(input.BO)
SI.BO <- matrix(NA, nrow = nBO, ncol = 3)
colnames(SI.BO) <- colnames(input.BO)

for(i in 1:nBO){
  SI.BO[i, ] <- suppressWarnings(
    SIcalc(BO.model, input.BO[i, ])
  )
}

# Gray Squirrel
input.GS <- GS[, 2:6]
nGS <- nrow(input.GS)
SI.GS <- matrix(NA, nrow = nGS, ncol = 5)
colnames(SI.GS) <- colnames(input.GS)

for(i in 1:nGS){
  SI.GS[i, ] <- suppressWarnings(
    SIcalc(GS.model, input.GS[i, ])
  )
}

# Mink
MNK.model <- HSImodels$minkRivLac
MNK.model[] <- lapply(MNK.model, function(x) type.convert(as.character(x), as.is = TRUE))

input.MNK <- MNK[, 2:7]
nMNK <- nrow(input.MNK)
SI.MNK <- matrix(NA, nrow = nMNK, ncol = 6)
colnames(SI.MNK) <- colnames(input.MNK)

for(i in 1:nMNK){
  SI.MNK[i, ] <- suppressWarnings(
    SIcalc(MNK.model, input.MNK[i, ])
  )
}
## Warning: U.S. Army Corps of Engineers users must have approval from the
## National Ecosystem Planning Center of Expertise (Eco-PCX) prior to application
## of a new model.
Table E.1.1. Suitability index values for all species across hypothetical sites.
Site PW_SIV1 PW_SIV2 PW_SIV3 PW_SIV4 PW_SIV5 PW_SIV6 PW_SIV7 BO_SIV1 BO_SIV2 BO_SIV3 GS_SIV1 GS_SIV2 GS_SIV3 GS_SIV4 GS_SIV5 MNK_SIV1 MNK_SIV2 MNK_SIV3 MNK_SIV4 MNK_SIV5 MNK_SIV6
Delta 0.4 0.44 0.86 1.00 1.00 NA NA 1.00 0.00 0.25 0.55 0.5 1.00 1.00 1 1.0 NA NA NA 0.70 0.70
Clinton 0.1 0.63 0.65 0.00 0.34 NA NA 0.55 1.00 0.62 0.50 0.2 0.75 1.00 1 0.6 NA NA NA 0.58 0.55
Vicksburg 0.0 0.74 1.00 0.59 0.25 NA NA 1.00 0.18 0.75 0.28 0.5 0.50 0.75 0 0.0 NA NA NA 0.34 0.30
Jackson 0.0 0.00 0.44 0.00 0.25 NA NA 0.10 0.00 0.12 0.24 0.1 0.38 0.62 0 0.0 NA NA NA 0.28 0.25
Pearl 0.5 0.89 0.86 1.00 1.00 NA NA 0.55 0.84 1.00 0.60 0.8 0.12 0.75 0 1.0 NA NA NA 1.00 0.90
Brandon 1.0 1.00 1.00 1.00 1.00 NA NA 0.55 0.76 1.00 0.43 1.0 0.95 1.00 1 1.0 NA NA NA 0.70 0.80

Step 4: Use HSIeqtn() to calculate overall habitat suitability for all species and sites.

# Pileated Woodpecker
HSI.PW <- matrix(NA, nrow = nPW, ncol = 1)

for(i in 1:nPW){
  HSI.PW[i, ] <- HSIeqtn("pileatedwoodpeckerE", SI.PW[i, 1:5], HSImetadata)
}

# Barred Owl
HSI.BO <- matrix(NA, nrow = nBO, ncol = 1)

for(i in 1:nBO){
  HSI.BO[i, ] <- HSIeqtn("barredowl", SI.BO[i, ], HSImetadata)
}

# Gray Squirrel
HSI.GS <- matrix(NA, nrow = nGS, ncol = 1)

for(i in 1:nGS){
  HSI.GS[i, ] <- HSIeqtn("graysquirrel", SI.GS[i, ], HSImetadata)
}

# Mink
HSI.MNK <- matrix(NA, nrow = nMNK, ncol = 1)

for(i in 1:nMNK){
  HSI.MNK[i, ] <- HSIeqtn("minkRivLac", SI.MNK[i, c(1, 5:6)], HSImetadata)
}
Table E.1.2. Habitat suitability index values for all species across sites.
Site PW BO GS MNK
Delta 0.39 0.00 0.52 0.70
Clinton 0.00 0.46 0.24 0.56
Vicksburg 0.00 0.32 0.00 0.00
Jackson 0.00 0.00 0.00 0.00
Pearl 0.62 0.68 0.00 0.95
Brandon 1.00 0.65 0.63 0.75

E.2. User-specified Model: Tidal Habitats and Resilience Evaluation Model (THREM) (Reviewed and approved by the ECO-PCX)

This example demonstrates how a user-specified habitat suitability model can be applied using input tables developed outside of the built-in USFWS HSI library. All new user-specified models intended to be used in a USACE project require formal review and approval via the Eco-PCX. The San Francisco Tidal Habitats and Resilience Evaluation Model (THREM) was developed for the South San Francisco Bay Shoreline Phase II study to evaluate tidal marsh restoration alternatives (Murray, Hernandez-Abrams, and Swannack, 2021). The model was developed iteratively with the model development team, a project development team and project stakeholders via a series of workshops hosted by the USACE San Francisco District (Murray et al. 2021). The model uses four suitability variables: percent tidal range (PTR), average marsh age (MA), access to high tide refugia (HTR), and percent marsh shoreward edge with ecotone transition (E). These variables are scored using user-defined suitability curves and then combined into an overall habitat suitability index.

The example below reads in the San Francisco model input table and field data, plots the user-specified suitability curves using HSIplotter(), calculates suitability indices for each variable using SIcalc(), computes an overall HSI using the project-specific model equation, and then estimates habitat units for a 300-acre restoration area using HUcalc().

Step 1: Load ecorest, model csv file, and model input csv file

# Read field inputs and user-specified suitability curves
marsh.field <- read.csv("SF-TM-HEI_FieldData.csv") # field inputs
marsh.model <- read.csv("SF-TM-HEI_InputData.csv") #user-specified curves
Table E.2.1.THREM field input data.
Alternatives SIV1 SIV2 SIV3 SIV4
FWOP 0 0 0 0
Alt1a 20 100 0 0
Alt1b 50 100 0 0
Alt1c 100 100 0 0
Alt2a 20 100 20 100
Alt2b 50 100 20 100
Alt2c 100 100 20 100
Alt3a 20 100 100 100
Alt3b 50 100 100 100
Alt3c 100 100 100 100
Alt3d 100 20 100 100
Alt3e 100 10 100 100
Alt3f 100 1 100 100
Alt3g 100 0 100 100
Alt3h 100 0 0 0
Table E.2.2.THREM user-specified suitability curve input data.
PTR PTR.SIV MA MA.SIV HTR HTR.SIV E E.SIV
0 0.000 0.0 0.025 0 0.5 0 0.50
20 0.025 2.5 0.300 100 1.0 15 0.80
40 0.100 5.0 0.600 NA NA 30 0.95
50 0.200 10.0 0.800 NA NA 60 1.00
60 0.550 20.0 0.950 NA NA 100 1.00
70 0.900 30.0 0.975 NA NA NA NA
80 0.975 40.0 1.000 NA NA NA NA
90 1.000 100.0 1.000 NA NA NA NA
100 1.000 NA NA NA NA NA NA

Step 2: Use HSIplotter to visualize user-specified suitability curves to review model curves.

# Visualize user-specified suitability curves 
HSIplotter(marsh.model, "marsh.plot.jpeg")
## Warning in HSIplotter(marsh.model, "marsh.plot.jpeg"): U.S. Army Corps of Engineers users must have approval from the National Ecosystem 
##   Planning Center of Expertise (Eco-PCX) prior to application of a new model.

Figure E.2.1. Tidal Habitats and Resilience Evaluation Model Step 3: Use SIcalc() to calculate SI units.

# Extract alternative input values
input.marsh <- marsh.field[, 2:5]
nmarsh <- nrow(input.marsh)

# Calculate suitability indices for each variable
SI.marsh <- matrix(NA, nrow = nmarsh, ncol = 4)

for(i in 1:nmarsh){
  SI.marsh[i, ] <- SIcalc(marsh.model, as.character(input.marsh[i, ]))
}
## Warning: U.S. Army Corps of Engineers users must have approval from the
## National Ecosystem Planning Center of Expertise (Eco-PCX) prior to application
## of a new model.
Table E.2.3.: Suitability index values calculated using SIcalc().
Alternative PTR MA HTR E
FWOP 0.00 0.03 0.5 0.5
Alt1a 0.03 1.00 0.5 0.5
Alt1b 0.20 1.00 0.5 0.5
Alt1c 1.00 1.00 0.5 0.5
Alt2a 0.03 1.00 0.6 1.0
Alt2b 0.20 1.00 0.6 1.0
Alt2c 1.00 1.00 0.6 1.0
Alt3a 0.03 1.00 1.0 1.0
Alt3b 0.20 1.00 1.0 1.0
Alt3c 1.00 1.00 1.0 1.0
Alt3d 1.00 0.95 1.0 1.0
Alt3e 1.00 0.80 1.0 1.0
Alt3f 1.00 0.13 1.0 1.0
Alt3g 1.00 0.03 1.0 1.0
Alt3h 1.00 0.03 0.5 0.5

Step 4: Use user-specified HSI equation and HUcalc() to quantify HSIs and habitat units for each alternative.

# Calculate habitat quality and habitat units
marsh.HU <- do.call(rbind, lapply(1:nmarsh, function(i) {
  HUcalc(
    SI.out = SI.marsh[i, ],
    habitat.quantity = 300,
    HSIfunc = function(x) (((x[4] + x[3]) / 2) * (x[2] * x[1]))^(1/3)
  )
}))
## Warning: U.S. Army Corps of Engineers users must have approval from the
## National Ecosystem Planning Center of Expertise (Eco-PCX) prior to application
## of a new model.
Figure E.2.2. Tidal Habitats and Resilience Evaluation Model HSI Equation
Figure E.2.2. Tidal Habitats and Resilience Evaluation Model HSI Equation
Table E.2.4. Example output for a user-specified Tidal Habitats and Resilience Evaluation Model.
Alternative PTR MA HTR E HSI Habitat.Units
FWOP 0.00 0.03 0.5 0.5 0.00 0
Alt1a 0.03 1.00 0.5 0.5 0.23 70
Alt1b 0.20 1.00 0.5 0.5 0.46 139
Alt1c 1.00 1.00 0.5 0.5 0.79 238
Alt2a 0.03 1.00 0.6 1.0 0.27 81
Alt2b 0.20 1.00 0.6 1.0 0.54 163
Alt2c 1.00 1.00 0.6 1.0 0.93 278
Alt3a 0.03 1.00 1.0 1.0 0.29 88
Alt3b 0.20 1.00 1.0 1.0 0.58 175
Alt3c 1.00 1.00 1.0 1.0 1.00 300
Alt3d 1.00 0.95 1.0 1.0 0.98 295
Alt3e 1.00 0.80 1.0 1.0 0.93 278
Alt3f 1.00 0.13 1.0 1.0 0.51 154
Alt3g 1.00 0.03 1.0 1.0 0.29 88
Alt3h 1.00 0.03 0.5 0.5 0.23 70

E.3. Comparison of Single-Site Habitat Restoration Alternatives with CEICA

This example demonstrates how ecorest can be used to compare habitat restoration alternatives for a single project site using time-varying habitat benefits, annualized outputs, and cost-effectiveness and incremental cost analyses (CEICA). A hypothetical restoration site is evaluated under four alternatives: a future without project condition (FWOP), a low-intensity restoration plan, a moderate restoration plan, and a high-intensity restoration plan. Habitat outputs are first converted to average annual habitat units using annualizer(), and those annualized benefits are then used in CEICA.

Step 1: Define the alternatives, time horizon, and habitat outputs over time.

altnames <- c("FWOP", "Alt A", "Alt B", "Alt C")

# Time horizon (years)
timevec <- c(0, 10, 20, 30, 40, 50)

# Habitat outputs over time (acres)
FWOP <- c(120, 118, 115, 112, 110, 108)
AltA <- c(120, 140, 155, 165, 170, 172)
AltB <- c(120, 155, 185, 205, 215, 220)
AltC <- c(120, 145, 165, 175, 178, 180)

# Project costs in millions of dollars
cost <- c(0.0, 4.5, 9.0, 18.5)

Step 2: Convert time-varying habitat outputs to average annual habitat units using annualizer().

benefit <- c(
  annualizer(timevec, FWOP),
  annualizer(timevec, AltA),
  annualizer(timevec, AltB),
  annualizer(timevec, AltC)
)
Table E.3.1. Annualized habitat benefits and project costs for a hypothetical single-site restoration analysis.
Alternative Annualized_Benefit Cost_Million_USD
FWOP 113.8 0.0
Alt A 155.2 4.5
Alt B 186.0 9.0
Alt C 162.6 18.5

Step 3: Conduct the cost-effectiveness and incremental cost analyses.

CE.E2 <- CEfinder(benefit, cost)
BB.E2 <- BBfinder(benefit, cost, CE.E2)

# Identify the names of the best-buy alternatives
bestbuy.names <- c()

for(i in 1:nrow(BB.E2[[2]])){
  bestbuy.names[i] <- altnames[
    which(benefit == BB.E2[[2]][i, 1] & cost == BB.E2[[2]][i, 2])
  ]
}
Table.E3 <- data.frame(
  Alternative = bestbuy.names,
  Benefit = round(BB.E2[[2]][, 1], 2),
  Cost_Million_USD = round(BB.E2[[2]][, 2], 2),
  Incremental_Cost_per_Unit = round(BB.E2[[2]][, 3], 2)
)

knitr::kable(
  Table.E3,
  caption = "Table E.3.2. Incremental cost analysis summary for hypothetical single-site habitat restoration alternatives."
)
Table E.3.2. Incremental cost analysis summary for hypothetical single-site habitat restoration alternatives.
Alternative Benefit Cost_Million_USD Incremental_Cost_per_Unit
FWOP 113.8 0.0 0.00
Alt A 155.2 4.5 0.11
Alt B 186.0 9.0 0.15

Step 4: Plot the CEICA results with CEICAplotter().

CEICAplotter(
  altnames,
  benefit,
  cost,
  CE.E2,
  BB.E2[[1]][, 4],
  "CEICA.single.site.jpeg"
)

This example annualized habitat acreage over time and used those benefits with project costs to conduct CEICA. The analysis showed that FWOP, Alt A, and Alt B were retained as best-buy plans, while Alt C was not retained in the incremental cost analysis. The table and figure summarize differences in benefit, cost, and incremental cost across alternatives.

E.4. Multi-site restoration prioritization using habitat units and CEICA

This example builds directly on Steps 1–4 from Example E.1. In that previous example, suitability indices were calculated with SIcalc() and habitat suitability indices were calculated with HSIeqtn() for four taxa across multiple sites. Here, those existing HSI results are carried forward and combined with site acreage to calculate habitat units for each taxon and site. Habitat units are then summed across taxa to produce a total ecological output for each site, and those total outputs are compared with project costs using cost-effectiveness and incremental cost analyses (CEICA).

Step 5: Assign restoration acreage to each site and calculate habitat units for each taxon.

# Hypothetical restoration acreage by site
acres <- c(120, 175, 240, 300, 210, 160)
# Calculate habitat units for each taxon at each site
HU.PW <- HSI.PW[, 1] * acres
HU.BO <- HSI.BO[, 1] * acres
HU.GS <- HSI.GS[, 1] * acres
HU.MNK <- HSI.MNK[, 1] * acres
Table E.4.1. Habitat units for each taxon across hypothetical restoration sites.
Site Acres PW_HU BO_HU GS_HU MNK_HU
Delta 120 46.9 0.0 62.9 84.0
Clinton 175 0.0 81.1 41.7 98.8
Vicksburg 240 0.0 77.3 0.0 0.0
Jackson 300 0.0 0.0 0.0 0.0
Pearl 210 129.8 142.9 0.0 199.2
Brandon 160 160.0 103.7 100.0 119.7

Step 6: Sum habitat units across taxa to generate a total ecological benefit for each site.

benefit <- HU.PW+HU.BO+HU.GS+HU.MNK

#Hypothetical project costs in millions of dollars
cost <- c(3.5, 6.0, 8.8, 14.0, 10.2, 7.1)
Table E.4.2. Total habitat units and project costs used in the CEICA.
Site Total_Habitat_Units Cost_Million_USD
Delta 193.8 3.5
Clinton 221.7 6.0
Vicksburg 77.3 8.8
Jackson 0.0 14.0
Pearl 472.0 10.2
Brandon 483.4 7.1

Step 7: Conduct the cost-effectiveness and incremental cost analyses.

CE.E3<- CEfinder(benefit, cost)
BB.E3<- BBfinder(benefit, cost, CE.E3)

#Identify the names of the best-buy sites
bestbuy.names <- c()

for(i in 1:nrow(BB.E3[[2]])){
  bestbuy.names[i] <- site.names[
    which(benefit == BB.E3[[2]][i, 1] & cost == BB.E3[[2]][i, 2])
  ]
}
Table E.4.3. Incremental cost analysis summary for multi-site restoration prioritization.
Site Benefit_HU Cost_Million_USD Incremental_Cost_per_HU
Delta 193.8 3.5 0.000
Brandon 483.4 7.1 0.012

Step 8:Plot the CEICA results with CEICAplotter().

CEICAplotter(
  site.names,
  benefit,
  cost,
  CE.E3,
  BB.E3[[1]][, 4],
  "CEICA.multisite.jpeg"
)

This example extends the HSI results from Example E.1 into a restoration planning context by converting habitat quality into habitat units and comparing total ecological outputs against project costs. The resulting CEICA summarizes how sites differ in both total habitat benefit and incremental cost.