diff --git a/DESCRIPTION b/DESCRIPTION index 86f1af7f0..20a026e07 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -120,3 +120,4 @@ LazyDataCompression: xz Config/Needs/website: rmarkdown BugReports: https://github.com/USEPA/EPATADA/issues Config/roxygen2/version: 8.0.0 +RoxygenNote: 7.3.3 diff --git a/NAMESPACE b/NAMESPACE index 56d796140..640050fed 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -23,6 +23,7 @@ export(TADA_CreateCSV) export(TADA_CreateComparableID) export(TADA_CreatePairRef) export(TADA_CreateUnitRef) +export(TADA_CrosswalkATTAINSWaterTypes) export(TADA_DataRetrieval) export(TADA_DefineCriteriaMethodology) export(TADA_DepthProfilePlot) diff --git a/R/ATTAINSCrosswalks.R b/R/ATTAINSCrosswalks.R index ce61af086..9e26f3911 100644 --- a/R/ATTAINSCrosswalks.R +++ b/R/ATTAINSCrosswalks.R @@ -384,7 +384,7 @@ TADA_UpdateATTAINSAUMLCrosswalk <- function( )) } - # check that crosswalk is a dataframe before proceeding + # check that crosswalk is a data frame before proceeding if (is.data.frame(crosswalk)) { # check crosswalk has all of the required columns crosswalk_cols <- c( @@ -411,7 +411,20 @@ TADA_UpdateATTAINSAUMLCrosswalk <- function( )) } + # filter user supplied crosswalk to only appropriate columns and unique values + crosswalk <- dplyr::select( + crosswalk, + ATTAINS.MonitoringLocationIdentifier, + OrganizationIdentifier, + ATTAINS.OrganizationIdentifier, + ATTAINS.AssessmentUnitIdentifier, + ATTAINS.MonitoringDataLinkText, + ATTAINS.WaterType + ) |> + dplyr::distinct() + if (all(batchupload_cols %in% names(crosswalk))) { + # rename columns as needed crosswalk <- crosswalk |> dplyr::rename( ATTAINS.AssessmentUnitIdentifier = ASSESSMENT_UNIT_ID, @@ -3640,6 +3653,18 @@ TADA_AssignUsesToWaterType <- function( # Pulls in all domain values of parameter and use names by orgs in ATTAINS. Filtering by state is done in the next steps. load(system.file("extdata", "ATTAINSParamUseOrgRef.rda", package = "EPATADA")) + # If AUMLRef is provided, filter by the ATTAINS.WaterType in the data frame + if (!is.null(AUMLRef)) { + ATTAINSParamUseOrgRef <- dplyr::filter( + ATTAINSParamUseOrgRef, + ATTAINS.WaterType %in% unique(AUMLRef$ATTAINS.WaterType) + ) + message( + "TADA_AssignUsesToWaterType: + An AUMLRef was provided. Filtering the crosswalk to water types found in your data frame." + ) + } + # Checks if org_id are valid names found in ATTAINS - with the exception of "EPA 304(a)" as that is not an ATTAINS org_id. if ( sum( @@ -3657,29 +3682,43 @@ TADA_AssignUsesToWaterType <- function( # Calls on EQ_Assessments from latest assessment cycle. Pulls in unique water types and uses by org message(paste0( "TADA_CreateWaterusesRef: Importing unique water types and uses ", - "by organization from Expert Query." + "by organization from Expert Query National Extract." )) - OrgID_assessments <- spsUtil::quiet(rExpertQuery::EQ_Assessments( - org_id = org_id, - api_key = api_key - )) + if (!org_id == "") { + ATTAINSParamUseOrgRef <- dplyr::filter( + ATTAINSParamUseOrgRef, + ATTAINS.OrganizationIdentifier %in% org_id + ) + } else { + ATTAINSParamUseOrgRef <- ATTAINSParamUseOrgRef |> + dplyr::mutate( + ATTAINS.OrganizationName = NA_character_, + ATTAINS.OrganizationIdentifier = NA_character_ + ) |> + dplyr::distinct() + } - CreateWaterUseRef <- OrgID_assessments[, c( - "organizationName", - "organizationId", - "waterType", - "useName" - )] |> + if (nrow(ATTAINSParamUseOrgRef) == 0) { + message( + "TADA_CreateWaterusesRef: + No uses were found for your ATTAINS organization identifier in prior ATTAINS + assessment cycles. A manual uses to water type crosswalk is required or selecting + another existing ATTAINS organization identifier to represent your uses to water type. " + ) + } + + CreateWaterUseRef <- ATTAINSParamUseOrgRef |> dplyr::distinct() |> dplyr::bind_cols(data.frame(IncludeOrExclude = as.character("Include"))) |> dplyr::select( - ATTAINS.OrganizationName = organizationName, - ATTAINS.OrganizationIdentifier = organizationId, - ATTAINS.UseName = useName, - ATTAINS.WaterType = waterType, + ATTAINS.OrganizationName, + ATTAINS.OrganizationIdentifier, + ATTAINS.UseName, + ATTAINS.WaterType, IncludeOrExclude - ) + ) |> + dplyr::distinct() # User supplies their own use to water ref table. if (!is.null(waterUseRef)) { @@ -3694,7 +3733,8 @@ TADA_AssignUsesToWaterType <- function( ATTAINS.UseName, ATTAINS.WaterType, IncludeOrExclude - ) + ) |> + dplyr::distinct() } return(CreateWaterUseRef) @@ -4313,12 +4353,12 @@ TADA_MLSummary <- function( if (!file.exists(downloads_path)) { message( "TADA_MLSummary: - ParamUseMLCrosswalks.xlsx does not exist yet. Generating the excel file using your usesRef input (or NULL input if generating a blank sheet)." + ParamUseMLCrosswalks.xlsx does not exist yet. Generating the excel file using your usesRef input (or NULL input if generating a blank sheet)." ) if (!isTRUE(overwrite)) { message( "TADA_MLSummary: - overwrite = F selected, creating original version as well as a copy with timestamp." + overwrite = F selected, creating original version as well as a copy with timestamp." ) } # if no file exists yet, use the paramRef as the input from this function to generate the paramRef tabs from TADA_ParametersForAnalysis @@ -4509,3 +4549,262 @@ TADA_MLSummary <- function( } return(MLSummaryRef) } + +#' Crosswalk WQP Monitoring Location Type to ATTAINS Water Type +#' +#' The WQP Monitoring Location Types and ATTAINS Water Types are not direct one to +#' one matches. This function crosswalks the WQP Monitoring Location Type to the +#' recommended ATTAINS Water Type. The crosswalk used in this function was created +#' and maintained by the TADA team. +#' +#' @param .data A TADA data frame. +#' @param replace_all Logical. If TRUE, replace all ATTAINS.WaterType values in the +#' TADA data frame with the recommended ATTAINS Water Type values. If FALSE, only +#' assigns an ATTAINS Water Type to rows with no ATTAINS Water Type value. Default +#' equals FALSE. +#' @param review_all Logical. If TRUE, review all ATTAINS.WaterType values to ensure +#' they are allowable values. If a value is not allowed, replace it with the ATTAINS +#' WaterType identified in the crosswalk. If FALSE, no review. Default equals FALSE. +#' @param review_action Character string. Options are "flag" or "update". If +#' review_action equals "flag", the flagging column TADA.ATTAINSWaterTypeFlag will +#' be added to .data and identify any rows where the ATTAINS.WaterType value does +#' not match any of the allowable values for water type in ATTAINS. When review_action +#' equals "update", the flagging column will be added and any flagged rows will have +#' their ATTAINS.WaterType values updated by crosswalking the +#' TADA.MonitoringLocationTypeName to ATTAINS.WaterType. The TADA.ATTAINSWaterTypeFlag +#' column will be updated to reflect this action. +#' @param create_AUMLRef Logical. If True, adds a column ATTAINS.AssessmentUnitIdentifier +#' that is identical to the newly created ATTAINS.WaterType. +#' +#' @param org_id Character vector. ATTAINS organization identifier(s). Note: +#' Only a single ATTAINS.Organization identifier should be supplied for the time being +#' +#' @return A TADA data frame with ATTAINS.WaterType column created (f not already +#' existing) and populated. +#' +#' @export +#' +#' @examples +#' \dontrun{ +#' # example TADA df already including an ATTAINS.WaterType column +#' MT_ExData <- Data_MT_AUMLRef$TADA_with_ATTAINS |> +#' sf::st_drop_geometry() +#' +#' # add ATTAINS.WaterType only for rows without values in that column +#' MT_addMissing <- TADA_CrosswalkATTAINSWaterTypes(MT_ExData) +#' +#' # add ATTAINS.WaterType for all rows (replace existing matches) +#' MT_replaceAll <- TADA_CrosswalkATTAINSWaterTypes(MT_ExData, replace_all = TRUE) +#' +#' # add ATTAINS.WaterType to TADA df without ATTAINS.WaterType column +#' Tribal_addAll <- TADA_CrosswalkATTAINSWaterTypes(Data_TribalNations_Harmonized) +#' +#' # modify tribal example data to include an ATTAINS.WaterType not allowed by ATTAINS +#' Tribal_modified <- Tribal_addAll |> +#' dplyr::mutate(ATTAINS.WaterType = +#' ifelse(TADA.MonitoringLocationIdentifier %in% +#' c("REDLAKE_WQX-GREE-REDLAKE", +#' "UTEMTN-COTTONWOOD WASH SPRING", +#' "BLCKFEET-00000054", +#' "BLCKFEET-00000056" +#' ), "INVALID WATER TYPE", +#' ATTAINS.WaterType)) +#' +#' # add ATTAINS.WaterType for any rows where it is missing, review all ATTAINS.WaterType +#' # values and update any that are not allowed +#' Tribal_reviewUpdate <- TADA_CrosswalkATTAINSWaterTypes(Tribal_modified, +#' review_all = TRUE, +#' review_action = "update") +#' +#' # filter to Blackfeet +#' Tribal_modified2 <- Tribal_modified |> +#' dplyr::filter(OrganizationIdentifier == "BLCKFEET") +#' +#' # append additional columns to the data frame to allow for creating the AUML crosswalk +#' Tribal_reviewUpdate2 <- TADA_CrosswalkATTAINSWaterTypes(Tribal_modified2, +#' org_id = "BLCKFEET", +#' review_all = TRUE, +#' review_action = "update", +#' create_AUMLRef = TRUE) +#' +#' Tribal_AUMLRef <- TADA_UpdateATTAINSAUMLCrosswalk( +#' org_id = "BLCKFEET", +#' crosswalk = Tribal_reviewUpdate2, +#' api_key = .setEQKey()) +#' } +#' +TADA_CrosswalkATTAINSWaterTypes <- function( + .data, + replace_all = FALSE, + review_all = FALSE, + review_action = "flag", + create_AUMLRef = FALSE, + org_id = NULL +) { + # create df of unique monitoring location identifiers, monitoring location type + # name, and (if present in TADA df) ATTAINS.WaterType + wqp.mls <- .data |> + dplyr::select(dplyr::any_of(c( + "TADA.MonitoringLocationIdentifier", + "TADA.MonitoringLocationTypeName", + "ATTAINS.WaterType" + ))) |> + dplyr::distinct() + + # if replace_all equals TRUE, remove all existing ATTAINS.WaterTypes + if (replace_all == TRUE) { + if ("ATTAINS.WaterType" %in% names(wqp.mls)) { + wqp.mls <- wqp.mls |> dplyr::select(-ATTAINS.WaterType) + } + # if replace_all equals FALSE, filter to retain only rows where ATTAINS.WaterType + # is NA or blank + } else { + if ("ATTAINS.WaterType" %in% names(wqp.mls)) { + wqp.mls <- wqp.mls |> + dplyr::filter(is.na(ATTAINS.WaterType) | ATTAINS.WaterType == "") |> + dplyr::select(-ATTAINS.WaterType) + } + } + + # load water type crosswalk + wattype.crosswalk <- utils::read.csv(system.file( + "extdata", + "ATTAINSWaterTypeToWQPMonLocType.csv", + package = "EPATADA" + )) |> + dplyr::select(Name, ATTAINS.WaterType) |> + dplyr::mutate(TADA.MonitoringLocationTypeName = toupper(Name)) |> + dplyr::select(-Name) |> + dplyr::distinct() + + # match ATTAINS.WaterType to TADA.MonitoringLocationTypeName + match.type <- wqp.mls |> + dplyr::left_join( + wattype.crosswalk, + dplyr::join_by(TADA.MonitoringLocationTypeName) + ) |> + dplyr::rename(New.ATTAINS.WaterType = ATTAINS.WaterType) |> + dplyr::select(-TADA.MonitoringLocationTypeName) + + # join ATTAINS.WaterType matches to TADA df + .data <- .data |> + dplyr::left_join( + match.type, + relationship = "many-to-many", + by = dplyr::join_by(TADA.MonitoringLocationIdentifier) + ) + + # retain all existing ATTAINS.WaterType matches if none were present in TADA df + # or if replace_all = TRUE + if (!"ATTAINS.WaterType" %in% names(.data)) { + .data <- .data |> dplyr::rename(ATTAINS.WaterType = New.ATTAINS.WaterType) + } else { + # if some ATTAINS.WaterType matches exist, only replace the NA or blank rows + # with the new matches + .data <- .data |> + dplyr::mutate( + ATTAINS.WaterType = ifelse( + is.na(ATTAINS.WaterType) | ATTAINS.WaterType == "", + New.ATTAINS.WaterType, + ATTAINS.WaterType + ) + ) |> + dplyr::select(-New.ATTAINS.WaterType) + } + + .data <- .data |> TADA_OrderCols() + + if (isTRUE(review_all)) { + # create list of allowable ATTAINS water types + attains.types <- quiet( + rExpertQuery::EQ_DomainValues("water_type") |> + dplyr::select(name) |> + dplyr::distinct() |> + dplyr::pull() + ) |> + append(c("", NA)) + + # identify and flag data without allowable ATTAINS Water Type + flag.data <- .data |> + dplyr::filter(!ATTAINS.WaterType %in% attains.types) |> + dplyr::mutate( + TADA.ATTAINSWaterType.Flag = "ATTAINS.WaterType value does not match any allowable ATTAINS.WaterType." + ) |> + dplyr::select( + TADA.MonitoringLocationIdentifier, + TADA.MonitoringLocationTypeName, + TADA.ATTAINSWaterType.Flag + ) |> + dplyr::distinct() + + # if users has selected the option to update invalid ATTAINS.WaterTypeValues then + # update any flagged rows + if (review_action == "update") { + # identify and flag data for updates + flag.data <- flag.data |> + dplyr::left_join( + wattype.crosswalk, + dplyr::join_by(TADA.MonitoringLocationTypeName) + ) |> + dplyr::rename(New.ATTAINS.WaterType = ATTAINS.WaterType) |> + dplyr::select(-TADA.MonitoringLocationTypeName) |> + dplyr::mutate( + TADA.ATTAINSWaterType.Flag = ifelse( + !is.na(New.ATTAINS.WaterType), + "ATTAINS.WaterType was updated to match an allowable ATTAINS.WaterType value by crosswalking ATTAINS.WaterType to TADA.MonitoringLocationTypeName.", + "ATTAINS.WaterType set to NA as no ATTAINS.WaterType value was found for this TADA.MonitoringLocationTypeName." + ) + ) + } + + # fill flag column for all results, updated ATTAINS.WaterType (if required) + .data <- .data |> + dplyr::left_join( + flag.data, + by = dplyr::join_by(TADA.MonitoringLocationIdentifier) + ) |> + dplyr::mutate( + ATTAINS.WaterType = ifelse( + !is.na(New.ATTAINS.WaterType), + New.ATTAINS.WaterType, + ATTAINS.WaterType + ), + TADA.ATTAINSWaterType.Flag = ifelse( + is.na(TADA.ATTAINSWaterType.Flag), + "ATTAINS.WaterType matches an allowable ATTAINS.WaterType value.", + ATTAINS.WaterType + ) + ) + + if (isTRUE(create_AUMLRef)) { + if (!is.character(org_id) & is.null(org_id)) { + org_id <- "" + message( + "Proceeding function with 'org_id = NULL'. If this was not intentional, please supply a valid 'org_id'." + ) + } + + .data <- .data |> + dplyr::mutate( + ATTAINS.AssessmentUnitIdentifier = TADA.MonitoringLocationIdentifier, + ATTAINS.OrganizationIdentifier = org_id, + ATTAINS.MonitoringLocationIdentifier = TADA.MonitoringLocationIdentifier, + ATTAINS.MonitoringDataLinkText = NA_character_ + ) + + message( + "TADA_CrosswalkATTAINSWaterTypes: + ATTAINS.OrganizationIdentifier, ATTAINS.MonitoringLocationIdentifier, ATTAINS.AssessmentUnitIdentifier, ATTAINS.MonitoringDataLinkText + have been appended. To create your AUMLRef crosswalk table, use the output as your crosswalk input for TADA_UpdateATTAINSAUMLCrosswalk." + ) + } + + # remove intermediate object + rm(attains.types) + } + + # remove intermediate objects + rm(match.type, wattype.crosswalk) + + return(.data) +} diff --git a/R/RequiredCols.R b/R/RequiredCols.R index 09aac3e10..965b0b770 100644 --- a/R/RequiredCols.R +++ b/R/RequiredCols.R @@ -280,6 +280,7 @@ attains.cols <- c( "ATTAINS.CatchmentStateCode", "ATTAINS.CatchmentResolution", "ATTAINS.WaterType", + "TADA.ATTAINSWaterType.Flag", "ATTAINS.ShapeArea" ) diff --git a/data/Data_HUC8_02070004_Mod1Output.rda b/data/Data_HUC8_02070004_Mod1Output.rda index 057c41c00..19ecaf289 100644 Binary files a/data/Data_HUC8_02070004_Mod1Output.rda and b/data/Data_HUC8_02070004_Mod1Output.rda differ diff --git a/data/Data_Nutrients_UT.rda b/data/Data_Nutrients_UT.rda index a99f7e2b7..93fc5cdad 100644 Binary files a/data/Data_Nutrients_UT.rda and b/data/Data_Nutrients_UT.rda differ diff --git a/data/Data_Participatory_Scientists.rda b/data/Data_Participatory_Scientists.rda index 53cb8010a..22a00d4c9 100644 Binary files a/data/Data_Participatory_Scientists.rda and b/data/Data_Participatory_Scientists.rda differ diff --git a/data/Data_Penobscot.rda b/data/Data_Penobscot.rda index a2daa03e4..f342c7b46 100644 Binary files a/data/Data_Penobscot.rda and b/data/Data_Penobscot.rda differ diff --git a/data/Data_R5_TADAPackageDemo.rda b/data/Data_R5_TADAPackageDemo.rda index 0190454fd..999ad4224 100644 Binary files a/data/Data_R5_TADAPackageDemo.rda and b/data/Data_R5_TADAPackageDemo.rda differ diff --git a/data/Data_TribalNations.rda b/data/Data_TribalNations.rda index d803b1fca..063ab9646 100644 Binary files a/data/Data_TribalNations.rda and b/data/Data_TribalNations.rda differ diff --git a/data/Data_TribalNations_Harmonized.rda b/data/Data_TribalNations_Harmonized.rda index 9594015b4..8fb33fb31 100644 Binary files a/data/Data_TribalNations_Harmonized.rda and b/data/Data_TribalNations_Harmonized.rda differ diff --git a/data/wqx3_fullPhysChem.rda b/data/wqx3_fullPhysChem.rda index 300d7c455..31d9b1996 100644 Binary files a/data/wqx3_fullPhysChem.rda and b/data/wqx3_fullPhysChem.rda differ diff --git a/inst/WORDLIST b/inst/WORDLIST index b84e54dc5..29d110ae1 100644 --- a/inst/WORDLIST +++ b/inst/WORDLIST @@ -1,5 +1,6 @@ ANDs AOI +ATTAINSWaterTypeFlag AUML AUMLRef AURefSource @@ -446,6 +447,7 @@ createBBox createTADABasemap cristinamullin criteriaMethods +crosswalking crs cst csv diff --git a/inst/extdata/AKAllotments.dbf b/inst/extdata/AKAllotments.dbf index a93455fd2..75ed4a14b 100644 Binary files a/inst/extdata/AKAllotments.dbf and b/inst/extdata/AKAllotments.dbf differ diff --git a/inst/extdata/AKVillages.dbf b/inst/extdata/AKVillages.dbf index ce0bcfb06..887aae5a6 100644 Binary files a/inst/extdata/AKVillages.dbf and b/inst/extdata/AKVillages.dbf differ diff --git a/inst/extdata/ATTAINSWaterTypeToWQPMonLocType.csv b/inst/extdata/ATTAINSWaterTypeToWQPMonLocType.csv new file mode 100644 index 000000000..10027ea85 --- /dev/null +++ b/inst/extdata/ATTAINSWaterTypeToWQPMonLocType.csv @@ -0,0 +1,124 @@ +Domain,Unique Identifier,Name,Description,Last Change Date,ATTAINS.WaterType +Monitoring Location Type(MonitoringLocationTypeName),86,Atmosphere,Atmosphere monitoring stations provide weather data about conditions,11/20/2013 10:57,NA +Monitoring Location Type(MonitoringLocationTypeName),58,BEACH Program Site-Channelized stream,"The process of straightening or redirecting natural streams in an artificially modified or constructed stream bed. Channelization has been carried out for numerous reasons, most often to drain wetlands , direct water flow for agricultural use, and control flooding . While this process makes a stream more useful for human activities, it tends to interfere with natural river habitats and to destabilize stream banks by destroying riparian vegetation.",8/11/2007 0:00,CHANNEL +Monitoring Location Type(MonitoringLocationTypeName),59,BEACH Program Site-Estuary,"a partially enclosed coastal body of brackish water with one or more rivers or streams flowing into it, and with a free connection to the open sea +Estuaries form a transition zone between river environments and maritime environments. +The sea water entering the estuary is diluted by the fresh water flowing from rivers and streams. +",8/11/2007 0:00,ESTUARY +Monitoring Location Type(MonitoringLocationTypeName),60,BEACH Program Site-Great Lake,"The Great Lakes, also called the Laurentian Great Lakes and the Great Lakes of North America, are a series of interconnected freshwater lakes primarily in the upper mid-east region of North America, on the Canada–United States border, which connect to the Atlantic Ocean through the Saint Lawrence River.",8/11/2007 0:00,GREAT LAKES BEACH +Monitoring Location Type(MonitoringLocationTypeName),61,BEACH Program Site-Lake,"A lake is an area filled with water, localized in a basin, that is surrounded by land, apart from any river or other outlet that serves to feed or drain the lake",8/11/2007 0:00,LAKE +Monitoring Location Type(MonitoringLocationTypeName),63,BEACH Program Site-Land,"Land, sometimes referred to as dry land, is the solid surface of Earth that is not permanently covered by water.",8/11/2007 0:00,NA +Monitoring Location Type(MonitoringLocationTypeName),62,BEACH Program Site-Land runoff,"Also known as overland flow is the flow of water that occurs when excess stormwater, meltwater, or other sources flows over the Earth's surface.",8/11/2007 0:00,NA +Monitoring Location Type(MonitoringLocationTypeName),64,BEACH Program Site-Ocean,An ocean is a body of water that composes much of a planet's hydrosphere.,8/11/2007 0:00,OCEAN +Monitoring Location Type(MonitoringLocationTypeName),65,BEACH Program Site-River/Stream,"A river is a natural flowing watercourse, usually freshwater, flowing towards an ocean, sea, lake or another river. In some cases a river flows into the ground and becomes dry at the end of its course without reaching another body of water. ",8/11/2007 0:00,STREAM/CREEK/RIVER +Monitoring Location Type(MonitoringLocationTypeName),66,BEACH Program Site-Storm sewer,The storm sewer is a system designed to carry rainfall runoff and other drainage.,4/1/2008 0:00,NA +Monitoring Location Type(MonitoringLocationTypeName),67,BEACH Program Site-Waste sewer,"The wastewater from residences and institutions, carrying bodily wastes (primarily feces and urine), washing water, food preparation wastes, laundry wastes, and other waste products of normal living, are classed as domestic or sanitary sewage.",4/1/2008 0:00,NA +Monitoring Location Type(MonitoringLocationTypeName),6,Borehole,"A borehole is a narrow shaft bored in the ground, either vertically or horizontally. A borehole may be constructed for many different purposes, including the extraction of water, other liquids (such as petroleum) or gases (such as natural gas), as part of a geotechnical investigation, environmental site assessment,",5/11/2011 23:18,NA +Monitoring Location Type(MonitoringLocationTypeName),5,CERCLA Superfund Site,The Superfund site assessment process evaluates potential or confirmed releases of hazardous substances that may pose a threat to human health or the environment using the Hazard Ranking System (HRS) criteria guide,8/11/2006 23:18,NA +Monitoring Location Type(MonitoringLocationTypeName),1,Canal Drainage,"As a channel drainage system it is designed to eliminate the need for further pipework systems to be installed in parallel to the drainage, reducing the environmental impact of production as well as improving water collection.",7/26/2006 10:57,DITCH OR CANAL +Monitoring Location Type(MonitoringLocationTypeName),2,Canal Irrigation,"Irrigation canals are the main waterways that bring irrigation water from a water source to the areas to be irrigated. They can be lined with concrete, brick, stone, or a flexible membrane to prevent seepage and erosion.",7/26/2006 10:57,DITCH OR CANAL +Monitoring Location Type(MonitoringLocationTypeName),3,Canal Transport,"Canals are human-made channels for water conveyance, or to service water transport vehicles. In most cases, the engineered works will have a series of dams and locks that create areas of low speed current flow. These areas are referred to as slack water levels, often just called levels.",7/26/2006 10:57,DITCH OR CANAL +Monitoring Location Type(MonitoringLocationTypeName),4,Cave,"A cave is a hollow place in the ground, specifically a natural underground space large enough for a human to enter. Caves form naturally by the weathering of rock and often extend deep underground. ",7/26/2006 10:57,NA +Monitoring Location Type(MonitoringLocationTypeName),10,Channelized Stream,"The process of straightening or redirecting natural streams in an artificially modified or constructed stream bed. Channelization has been carried out for numerous reasons, most often to drain wetlands , direct water flow for agricultural use, and control flooding . While this process makes a stream more useful for human activities, it tends to interfere with natural river habitats and to destabilize stream banks by destroying riparian vegetation.",8/11/2006 23:18,CHANNEL +Monitoring Location Type(MonitoringLocationTypeName),11,Combined Sewer,"A combined sewer system (CSS) collects rainwater runoff, domestic sewage, and industrial wastewater into one pipe. Under normal conditions, it transports all of the wastewater it collects to a sewage treatment plant for treatment, then discharges to a water body. Combined sewer overflows (CSOs) contain untreated or partially treated human and industrial waste, toxic materials, and debris as well as stormwater.",8/11/2006 23:18,NA +Monitoring Location Type(MonitoringLocationTypeName),87,Constructed Diversion Dam,"A diversion dam is a dam that diverts all or a portion of the flow of a river from its natural course. Diversion dams do not generally impound water in a reservoir. Instead, the water is diverted into an artificial water course or canal, which may be used for irrigation or return to the river after passing through hydroelectric generators, flow into a different river or be itself dammed forming a reservoir.",11/20/2013 10:57,NA +Monitoring Location Type(MonitoringLocationTypeName),88,Constructed Tunnel,"an artificial underground passage, especially one built through a hill or under a building, road, or river.",11/20/2013 10:57,NA +Monitoring Location Type(MonitoringLocationTypeName),89,Constructed Water Transport Structure,a system of structures and measures that support the intentional movement of water over large distances. simple aqueducts to transport water above ground level. short pipelines to transport water above or under another structure such as a water canal or an access road,12/2/2013 10:57,NA +Monitoring Location Type(MonitoringLocationTypeName),12,Constructed Wetland,"A constructed wetland (CW) is an artificial wetland to treat municipal or industrial wastewater, greywater or stormwater runoff. It may also be designed for land reclamation after mining, or as a mitigation step for natural areas lost to land development.Constructed wetlands are engineered systems that use natural functions vegetation, soil, and organisms to treat wastewater",7/26/2006 10:57,WETLAND +Monitoring Location Type(MonitoringLocationTypeName),13,Estuary,"a partially enclosed coastal body of brackish water with one or more rivers or streams flowing into it, and with a free connection to the open sea +Estuaries form a transition zone between river environments and maritime environments. +The sea water entering the estuary is diluted by the fresh water flowing from rivers and streams. +",7/26/2006 10:57,ESTUARY +Monitoring Location Type(MonitoringLocationTypeName),97,Estuary-Freshwater,"Freshwater estuaries are semi-enclosed areas of the Great Lakes in which lake and river water mix, forming a transition zone between river and lake environments that are chemically distinct",12/20/2022 16:43,"ESTUARY, FRESHWATER" +Monitoring Location Type(MonitoringLocationTypeName),14,Facility Industrial,"a facility composed of one or more pieces of equipment connected to or part of a structure and designed to provide a service such as heat or electricity or water or sewage disposal. ""the price of the house included all utilities",7/26/2006 10:57,NA +Monitoring Location Type(MonitoringLocationTypeName),15,Facility Municipal Sewage (POTW),"Treatment works treating domestic sewage means a POTW or any other sewage sludge or waste water treatment devices or systems, regardless of ownership (including federal facilities), used in the storage, treatment, recycling, and reclamation of municipal or domestic sewage, including land dedicated for the disposal of sewage sludge. This definition does not include septic tanks or similar devices.",7/26/2006 10:57,NA +Monitoring Location Type(MonitoringLocationTypeName),17,Facility Other,"a facility composed of one or more pieces of equipment connected to or part of a structure and designed to provide a service such as Reclaimed water can supply needed water for some purposes Reclaimed wastewater frees up fresh water that can be used somewhere else, such as for drinking water",7/26/2006 10:57,NA +Monitoring Location Type(MonitoringLocationTypeName),18,Facility Privately Owned Non-industrial,Privately owned treatment works means any device or system which is (a) used to treat wastes from any facility whose operator is not the operator of the treatment works,8/11/2006 23:18,NA +Monitoring Location Type(MonitoringLocationTypeName),16,Facility Public Water Supply (PWS),"A Public Water System is a public water supply for the provision to the public of piped water for human consumption, A Public Water System includes any collection, treatment, storage, +and distribution facilities under control of such system, including the operator or administrator of such system, and is used primarily in +connection with such system and any collection or pretreatment storage facilities not under such control which are used primarily in +connection with such system.”",8/11/2006 23:18,NA +Monitoring Location Type(MonitoringLocationTypeName),72,Floodwater Urban,"A flood is an overflow of water that submerges land that is usually dry In the sense of ""urban runoff water"". it may occur due to an accumulation of rainwater on saturated ground in an areal flood.",1/11/2012 17:40,NA +Monitoring Location Type(MonitoringLocationTypeName),73,Floodwater non-Urban,"A flood is an overflow of water that submerges land that is usually dry Flooding may occur as an overflow of water from water bodies, such as a river, lake, or ocean, in which the water overtops or breaks levees, resulting in some of that water escaping its usual boundaries",1/11/2012 17:40,NA +Monitoring Location Type(MonitoringLocationTypeName),19,Gallery,An infiltration gallery is a structure including perforated conduits in gravel to expedite transfer of water to or from a soil.,7/26/2006 10:57,NA +Monitoring Location Type(MonitoringLocationTypeName),76,Gas-Condensate,"Natural-gas condensate, also called natural gas liquids, is a low-density mixture of hydrocarbon liquids that are present as gaseous components in the raw natural gas produced from many natural gas fields. ",10/17/2013 15:00,NA +Monitoring Location Type(MonitoringLocationTypeName),77,Gas-Engine,"A gas engine is an internal combustion engine that runs on a gaseous fuel, such as coal gas, producer gas, biogas, landfill gas or natural gas.",10/17/2013 15:00,NA +Monitoring Location Type(MonitoringLocationTypeName),78,Gas-Extraction,"Oil and Gas Extraction is the exploration and production of petroleum and natural gas from wells. The industry generates wastewater from the water extracted from the geological formations and from chemicals used during exploration, well drilling and production of oil and gas.",10/17/2013 15:00,NA +Monitoring Location Type(MonitoringLocationTypeName),79,Gas-Flare,"A gas flare, alternatively known as a flare stack, is a gas combustion device used in industrial plants such as petroleum refineries, chemical plants, natural gas processing plants as well as at oil or gas production sites having oil wells, gas wells, offshore oil and gas rigs and landfills.",10/17/2013 15:00,NA +Monitoring Location Type(MonitoringLocationTypeName),80,Gas-Monitoring Probe,"Gas monitoring probes are used to enhance environmental protection at landfills. Gas +concentrations are measured at permit or regulatory specified time intervals. This process +allows potential environmental concerns to be identified early, evaluated and corrected +(when necessary) in accordance with regulations and sound scientific approaches.",10/17/2013 15:00,NA +Monitoring Location Type(MonitoringLocationTypeName),81,Gas-Passive Vent,Dispersion of gas safely from soil.,10/17/2013 15:00,NA +Monitoring Location Type(MonitoringLocationTypeName),92,Gas-Subslab,Sub-slab Soil Gas: Sub-slab samples are collected to characterize the nature and extent of vapor contamination in the soil immediately beneath a building with a slab or beneath the basement floor.,8/4/2014 0:00,NA +Monitoring Location Type(MonitoringLocationTypeName),82,Gas-Temporary,a gas capable of liquefaction,10/17/2013 15:00,NA +Monitoring Location Type(MonitoringLocationTypeName),20,Great Lake,"The Great Lakes, also called the Laurentian Great Lakes and the Great Lakes of North America, are a series of interconnected freshwater lakes primarily in the upper mid-east region of North America, on the Canada–United States border, which connect to the Atlantic Ocean through the Saint Lawrence River.",7/26/2006 10:57,GREAT LAKES OPEN WATER +Monitoring Location Type(MonitoringLocationTypeName),98,Intertidal,denoting the area of a seashore which is covered at high tide and uncovered at low tide,5/16/2023 12:54,OCEAN/NEAR COASTAL +Monitoring Location Type(MonitoringLocationTypeName),21,Lake,"A lake is an area filled with water, localized in a basin, that is surrounded by land, apart from any river or other outlet that serves to feed or drain the lake",7/26/2006 10:57,LAKE +Monitoring Location Type(MonitoringLocationTypeName),50,Land,"Land, sometimes referred to as dry land, is the solid surface of Earth that is not permanently covered by water.",7/26/2006 10:57,NA +Monitoring Location Type(MonitoringLocationTypeName),22,Land Flood Plain,"An area of land adjacent to a stream or river which stretches from the banks of its channel to the base of the enclosing valley walls, and which experiences flooding during periods of high discharge.",7/26/2006 10:57,NA +Monitoring Location Type(MonitoringLocationTypeName),23,Land Runoff,"Also known as overland flow is the flow of water that occurs when excess stormwater, meltwater, or other sources flows over the Earth's surface.",8/11/2006 23:18,NA +Monitoring Location Type(MonitoringLocationTypeName),24,Landfill,A site for the disposal of waste materials by burial.,7/26/2006 10:57,NA +Monitoring Location Type(MonitoringLocationTypeName),83,Leachate-Extraction,The pump systems which extract the leachate from the wastes,10/17/2013 15:00,NA +Monitoring Location Type(MonitoringLocationTypeName),84,Leachate-Head Well,The wells and boreholes within the landfill into which the leachate collection system conveys the leachate. The well head where samples of water are taken determining water quality in source Leachate,10/17/2013 15:00,NA +Monitoring Location Type(MonitoringLocationTypeName),71,Leachate-Lysimeter,Is a measuring device which can be used to measure the amount of actual evapotranspiration which is released by plants (usually crops or trees),12/22/2011 14:13,NA +Monitoring Location Type(MonitoringLocationTypeName),85,Leachate-SamplePoint,"The point where samples of water are taken determining water quality in source the pipes/pipelines which convey the leachate to the collection tank, or treatment plant location. Leachate is the liquid that drains or 'leaches' from a landfill. It varies widely in composition regarding the age of the landfill and the type of waste that it contains. It usually contains both dissolved and suspended material.",10/17/2013 15:00,NA +Monitoring Location Type(MonitoringLocationTypeName),91,Local Air Monitoring Station,"Ambient air monitoring is the systematic, long-term assessment of pollutant levels by measuring the quantity and types of certain pollutants in the surrounding, outdoor air.",1/24/2014 10:57,NA +Monitoring Location Type(MonitoringLocationTypeName),95,Mine Pit,"Open-pit mining, also known as opencast mining, is a surface mining technique that extracts minerals from an open pit in the ground. Open-pits are sometimes called ‘quarries’ when they produce building materials and dimension stone.",10/15/2014 0:00,NA +Monitoring Location Type(MonitoringLocationTypeName),25,Mine/Mine Discharge,"Formed when pyrite (an iron sulfide) is exposed and reacts with air and water to form sulfuric acid and dissolved iron. Some or all of this iron can precipitate to form the red, orange, or yellow sediments in the bottom of streams containing mine drainage. The acid runoff further dissolves heavy metals such as copper, lead, and mercury into groundwater or surface water. ",8/11/2006 23:18,NA +Monitoring Location Type(MonitoringLocationTypeName),26,Mine/Mine Discharge Adit (Mine Entrance),"An adit (from Latin aditus, entrance) is an entrance to an underground mine which is horizontal or nearly horizontal, by which the mine can be entered, drained of water, ventilated, and minerals extracted at the lowest convenient level.",8/11/2006 23:18,NA +Monitoring Location Type(MonitoringLocationTypeName),27,Mine/Mine Discharge Tailings Pile,Materials left over after the process of separating the valuable fraction from the uneconomic fraction (gangue) of an ore. ,8/11/2006 23:18,NA +Monitoring Location Type(MonitoringLocationTypeName),28,Mine/Mine Discharge Waste Rock Pile,"Mine drainage is metal-rich water formed from chemical reaction between water and rocks containing. sulfur-bearing minerals. • The runoff formed is usually acidic and frequently comes from areas where ore or coal mining activities. have exposed rocks containing pyrite, a sulfur bearing mineral",8/11/2006 23:18,NA +Monitoring Location Type(MonitoringLocationTypeName),29,National Air Monitoring Station,"Ambient air monitoring is the systematic, long-term assessment of pollutant levels by measuring the quantity and types of certain pollutants in the surrounding, outdoor air.",7/26/2006 10:57,NA +Monitoring Location Type(MonitoringLocationTypeName),30,Ocean,An ocean is a body of water that composes much of a planet's hydrosphere.,7/26/2006 10:57,OCEAN +Monitoring Location Type(MonitoringLocationTypeName),90,Oil and Gas Well,An oil well is a boring in the Earth that is designed to bring petroleum oil hydrocarbons to the surface. Usually some natural gas is released along with the oil. A well that is designed to produce only gas may be termed a gas well.,12/2/2013 17:35,NA +Monitoring Location Type(MonitoringLocationTypeName),52,Other-Ground Water,The water present beneath Earth's surface in soil pore spaces and in the fractures of rock formations.,7/26/2006 10:57,NA +Monitoring Location Type(MonitoringLocationTypeName),51,Other-Surface Water,"water on the surface of continents such as in a river, lake, or wetland.",7/26/2006 10:57,NA +Monitoring Location Type(MonitoringLocationTypeName),57,"Pipe, Unspecified Source","Methods used to remove already formed contaminants from a stream of air, water, waste, product or similar. ",11/20/2006 13:45,NA +Monitoring Location Type(MonitoringLocationTypeName),54,Playa,"Known as an alkali flat or sabkha, a desert basin with no outlet which periodically fills with water to form a temporary lake.",8/11/2006 23:18,"LAKE, PLAYA" +Monitoring Location Type(MonitoringLocationTypeName),201,Pond,"Naturally occurring. A pond is an area filled with water, that is smaller than a lake. It may arise naturally in floodplains as part of a river system, or be a somewhat isolated depression (such as a kettle, vernal pool, or prairie pothole).",5/28/2020 8:22,POND +Monitoring Location Type(MonitoringLocationTypeName),70,Pond-Anchialine,A landlocked body of water with a subterranean connection to the ocean. ,9/16/2011 14:15,POND +Monitoring Location Type(MonitoringLocationTypeName),93,Pond-Sediment,"A naturally occurring material that is broken down by processes of weathering and erosion, and is subsequently transported by the action of wind, water, or ice or by the force of gravity acting on the particles.",10/15/2014 0:00,POND +Monitoring Location Type(MonitoringLocationTypeName),94,Pond-Stock,Ponds for a specific purpose for watering livestock.,10/15/2014 0:00,POND +Monitoring Location Type(MonitoringLocationTypeName),68,Pond-Stormwater,"Stormwater, also spelled storm water, is water that originates during precipitation events and snow/ice melt.",2/18/2009 11:40,POND +Monitoring Location Type(MonitoringLocationTypeName),75,Pond-Wastewater,"Any water that has been affected by human use. Wastewater is ""used water from any combination of domestic, industrial, commercial or agricultural activities, surface runoff or stormwater, and any sewer inflow or sewer infiltration"".",10/17/2013 15:00,POND +Monitoring Location Type(MonitoringLocationTypeName),31,Reservoir,"An enlarged natural or artificial lake, pond or impoundment created using a dam or lock to store water.",7/26/2006 10:57,RESERVOIR +Monitoring Location Type(MonitoringLocationTypeName),32,River/Stream,A body of water with surface water flowing within the bed and banks of a channel.,7/26/2006 10:57,STREAM/CREEK/RIVER +Monitoring Location Type(MonitoringLocationTypeName),69,River/Stream Ephemeral,A stream that flows only briefly during and following a period of rainfall in the immediate locality,6/30/2009 14:15,"STREAM, EPHEMERAL" +Monitoring Location Type(MonitoringLocationTypeName),55,River/Stream Intermittent,Mormally cease flowing for weeks or months each year. ,8/11/2006 23:18,"STREAM, INTERMITTENT" +Monitoring Location Type(MonitoringLocationTypeName),56,River/Stream Perennial,A stream or river (channel) that has continuous flow in parts of its stream bed all year round during years of normal rainfall.,8/11/2006 23:18,"STREAM, PERENNIAL" +Monitoring Location Type(MonitoringLocationTypeName),74,River/stream Effluent-Dominated,A stream or river that gets a significant portion of its flow from effulent discharge.,3/13/2013 15:00,STREAM/CREEK/RIVER +Monitoring Location Type(MonitoringLocationTypeName),33,Riverine Impoundment,"Impoundments (also known as reservoirs) are artificially created standing water bodies, produced by dams on streams or rivers.",8/11/2006 23:18,IMPOUNDMENT +Monitoring Location Type(MonitoringLocationTypeName),53,Seep,"A moist or wet place where water, usually groundwater, reaches the earth's surface from an underground aquifer.",8/11/2006 23:18,NA +Monitoring Location Type(MonitoringLocationTypeName),101,Soil sediment,The unconsolidated mineral or organic material on the immediate surface of the Earth that serves as a natural medium for the growth of land plants,4/25/2024 18:12,NA +Monitoring Location Type(MonitoringLocationTypeName),100,Source-ManMade,"Industrial, agricultural, stormwater, sewer/septic, discharge/pipe, lagoon, or other source",11/2/2023 19:33,NA +Monitoring Location Type(MonitoringLocationTypeName),7,Spigot / Faucet,"A spigot is a single knob faucet that only has one pipe it controls, like the outdoor spigot that you connect a garden hose to. A tap is used when there isn't a pipe",5/11/2011 23:18,NA +Monitoring Location Type(MonitoringLocationTypeName),34,Spring,the result of an aquifer being filled to the point that the water overflows onto the land surface.,7/26/2006 10:57,SPRING +Monitoring Location Type(MonitoringLocationTypeName),35,State/Local Air Monitoring Station,A Facility to measure systematically concentrations of pollutants in ambient air. Synonym: Air quality measurement station.,7/26/2006 10:57,NA +Monitoring Location Type(MonitoringLocationTypeName),36,Storm Sewer,A system designed to carry rainfall runoff and other drainage.,8/11/2006 23:18,NA +Monitoring Location Type(MonitoringLocationTypeName),99,Subtidal,Refers to the area where the seabed is below the lowest tide,5/16/2023 12:54,OCEAN +Monitoring Location Type(MonitoringLocationTypeName),181,Sump,A sump is a shallow borehole (no well construction) that intersects the water table,12/17/2018 18:52,NA +Monitoring Location Type(MonitoringLocationTypeName),8,Survey Monument,"Boundary monuments are placed at every corner of the property, including any angle or change of direction of the boundary line.",5/11/2011 23:18,NA +Monitoring Location Type(MonitoringLocationTypeName),9,Test Pit,"A trial pit (or test pit) is an excavation of ground in order to study or sample the composition and structure of the subsurface, usually dug during a site investigation, a soil survey or a geological survey. Trial pits are dug before the construction. They are dug to determine the geology and the water table of that site.",5/11/2011 23:18,NA +Monitoring Location Type(MonitoringLocationTypeName),37,Waste Pit,"A mud pit in which a supply of drilling fluid has been stored. Also, a waste pit, usually an excavated, earthen-walled pit. It may be lined with plastic to prevent soil contamination.",8/11/2006 23:18,NA +Monitoring Location Type(MonitoringLocationTypeName),38,Waste Sewer,a waste pipe that carries away sewage or surface water,8/11/2006 23:18,NA +Monitoring Location Type(MonitoringLocationTypeName),39,Well,"An excavation or structure created in the ground by digging, driving, or drilling to access liquid resources, usually water.",7/26/2006 10:57,NA +Monitoring Location Type(MonitoringLocationTypeName),161,Wetland Estuarine-Ditch,"Open water estuary, bay, sound Vegetated and non-vegetated brackish and saltwater ditch",9/26/2017 13:06,WETLAND +Monitoring Location Type(MonitoringLocationTypeName),40,Wetland Estuarine-Emergent,"Open water estuary, bay, sound Herbaceous marsh, fen, swale and wet meadow",8/11/2006 23:18,WETLAND +Monitoring Location Type(MonitoringLocationTypeName),41,Wetland Estuarine-Forested,"Open water estuary, bay, sound Vegetated brackish and saltwater forest",8/11/2006 23:18,WETLAND +Monitoring Location Type(MonitoringLocationTypeName),163,Wetland Estuarine-Marsh,"Open water estuary, bay, sound Vegetated brackish and saltwater marsh",9/26/2017 13:06,WETLAND +Monitoring Location Type(MonitoringLocationTypeName),165,Wetland Estuarine-Pool,"Open water estuary, bay, sound Vegetated brackish and saltwater pool: lagoons",9/20/2017 6:51,WETLAND +Monitoring Location Type(MonitoringLocationTypeName),42,Wetland Estuarine-Scrub-Shrub,"Open water estuary, bay, sound Vegetated brackish and saltwater scrub-shrub",8/11/2006 23:18,WETLAND +Monitoring Location Type(MonitoringLocationTypeName),162,Wetland Estuarine-Tidal Creek,"Open water estuary, bay, sound Vegetated brackish and saltwater tidal creek",9/26/2017 13:06,"WETLAND, TIDAL" +Monitoring Location Type(MonitoringLocationTypeName),157,Wetland Lacustrine-Aquatic Bed,Includes nontidal wetlands fringing lakes and dominated by floating leaved and submergent plants,3/15/2024 9:42,WETLAND +Monitoring Location Type(MonitoringLocationTypeName),43,Wetland Lacustrine-Emergent,"bounded by upland or by wetland dominated by trees, shrubs, persistent emergents, emergent mosses, or lichens",8/11/2006 23:18,WETLAND +Monitoring Location Type(MonitoringLocationTypeName),158,Wetland Lacustrine-Unconsolidated Bottom,Includes nontidal wetlands ringing lakes in which substrate is at least 25% particles smaller than stones and vegetative cover less than 30%,3/15/2024 9:42,WETLAND +Monitoring Location Type(MonitoringLocationTypeName),96,Wetland Palustrine Pond,includes all nontidal wetlands dominated by pond and all such wetlands that occur in tidal areas where salinity due to ocean-derived salts is below 0.5 ‰,8/6/2015 14:12,WETLAND +Monitoring Location Type(MonitoringLocationTypeName),44,Wetland Palustrine-Emergent,"includes all nontidal wetlands characterized by erect, rooted, herbaceous hydrophytes, excluding mosses and lichens and all such wetlands that occur in tidal areas where salinity due to ocean-derived salts is below 0.5 ‰",8/11/2006 23:18,WETLAND +Monitoring Location Type(MonitoringLocationTypeName),45,Wetland Palustrine-Forested,"includes all nontidal wetlands dominated by trees, forest, and all such wetlands that occur in tidal areas where salinity due to ocean-derived salts is below 0.5 ‰",8/11/2006 23:18,WETLAND +Monitoring Location Type(MonitoringLocationTypeName),46,Wetland Palustrine-Moss-Lichen,"includes all nontidal wetlands dominated by mosses or lichens, and all such wetlands that occur in tidal areas where salinity due to ocean-derived salts is below 0.5 ‰",8/11/2006 23:18,WETLAND +Monitoring Location Type(MonitoringLocationTypeName),47,Wetland Palustrine-Shrub-Scrub,"includes all nontidal wetlands dominated by, shrubs, scrub and all such wetlands that occur in tidal areas where salinity due to ocean-derived salts is below 0.5 ‰",8/11/2006 23:18,WETLAND +Monitoring Location Type(MonitoringLocationTypeName),160,Wetland Riverine-Aquatic Bed,Includes wetlands connected by or within low gradient rivers dominated by floating leaved and submergent plants ,3/15/2024 9:42,WETLAND +Monitoring Location Type(MonitoringLocationTypeName),48,Wetland Riverine-Emergent,"wetlands connected by rivers. ... They are found along the edges of rivers, streams and creeks and include rivers, floodplains, marshes, lakes and billabongs. characterized by erect, rooted, herbaceous hydrophytes, excluding mosses and lichens",8/11/2006 23:18,WETLAND +Monitoring Location Type(MonitoringLocationTypeName),159,Wetland Riverine-Unconsolidated Bottom,Includes nontidal wetlands connected by rivers in which substrate is at least 25% particles smaller than stones and vegetative cover less than 30% ,3/15/2024 9:42,WETLAND +Monitoring Location Type(MonitoringLocationTypeName),49,Wetland Undifferentiated,"a land area that is saturated with water, either permanently or seasonally, It primarily is characteristized by vegetation of aquatic plants, adapted to the unique hydric soil.",7/26/2006 10:57,WETLAND diff --git a/inst/extdata/AmericanIndian.dbf b/inst/extdata/AmericanIndian.dbf index ccd39106e..b0ce38ca1 100644 Binary files a/inst/extdata/AmericanIndian.dbf and b/inst/extdata/AmericanIndian.dbf differ diff --git a/inst/extdata/OKTribe.dbf b/inst/extdata/OKTribe.dbf index 49dec4c3c..3f807a51d 100644 Binary files a/inst/extdata/OKTribe.dbf and b/inst/extdata/OKTribe.dbf differ diff --git a/inst/extdata/OffReservation.dbf b/inst/extdata/OffReservation.dbf index 38fc86186..052d211d0 100644 Binary files a/inst/extdata/OffReservation.dbf and b/inst/extdata/OffReservation.dbf differ diff --git a/inst/extdata/VATribe.dbf b/inst/extdata/VATribe.dbf index 42bac54b4..c8ba0c2c1 100644 Binary files a/inst/extdata/VATribe.dbf and b/inst/extdata/VATribe.dbf differ diff --git a/inst/extdata/WQXCharAliasRef.rda b/inst/extdata/WQXCharAliasRef.rda index acfead38d..a60929ff4 100644 Binary files a/inst/extdata/WQXCharAliasRef.rda and b/inst/extdata/WQXCharAliasRef.rda differ diff --git a/inst/extdata/WQXCharacteristicRef.rda b/inst/extdata/WQXCharacteristicRef.rda index a8082b773..ee462f3e3 100644 Binary files a/inst/extdata/WQXCharacteristicRef.rda and b/inst/extdata/WQXCharacteristicRef.rda differ diff --git a/man/TADA_CrosswalkATTAINSWaterTypes.Rd b/man/TADA_CrosswalkATTAINSWaterTypes.Rd new file mode 100644 index 000000000..d17886989 --- /dev/null +++ b/man/TADA_CrosswalkATTAINSWaterTypes.Rd @@ -0,0 +1,102 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/ATTAINSCrosswalks.R +\name{TADA_CrosswalkATTAINSWaterTypes} +\alias{TADA_CrosswalkATTAINSWaterTypes} +\title{Crosswalk WQP Monitoring Location Type to ATTAINS Water Type} +\usage{ +TADA_CrosswalkATTAINSWaterTypes( + .data, + replace_all = FALSE, + review_all = FALSE, + review_action = "flag", + create_AUMLRef = FALSE, + org_id = NULL +) +} +\arguments{ +\item{.data}{A TADA data frame.} + +\item{replace_all}{Logical. If TRUE, replace all ATTAINS.WaterType values in the +TADA data frame with the recommended ATTAINS Water Type values. If FALSE, only +assigns an ATTAINS Water Type to rows with no ATTAINS Water Type value. Default +equals FALSE.} + +\item{review_all}{Logical. If TRUE, review all ATTAINS.WaterType values to ensure +they are allowable values. If a value is not allowed, replace it with the ATTAINS +WaterType identified in the crosswalk. If FALSE, no review. Default equals FALSE.} + +\item{review_action}{Character string. Options are "flag" or "update". If +review_action equals "flag", the flagging column TADA.ATTAINSWaterTypeFlag will +be added to .data and identify any rows where the ATTAINS.WaterType value does +not match any of the allowable values for water type in ATTAINS. When review_action +equals "update", the flagging column will be added and any flagged rows will have +their ATTAINS.WaterType values updated by crosswalking the +TADA.MonitoringLocationTypeName to ATTAINS.WaterType. The TADA.ATTAINSWaterTypeFlag +column will be updated to reflect this action.} + +\item{create_AUMLRef}{Logical. If True, adds a column ATTAINS.AssessmentUnitIdentifier +that is identical to the newly created ATTAINS.WaterType.} + +\item{org_id}{Character vector. ATTAINS organization identifier(s). Note: +Only a single ATTAINS.Organization identifier should be supplied for the time being} +} +\value{ +A TADA data frame with ATTAINS.WaterType column created (f not already +existing) and populated. +} +\description{ +The WQP Monitoring Location Types and ATTAINS Water Types are not direct one to +one matches. This function crosswalks the WQP Monitoring Location Type to the +recommended ATTAINS Water Type. The crosswalk used in this function was created +and maintained by the TADA team. +} +\examples{ +\dontrun{ +# example TADA df already including an ATTAINS.WaterType column +MT_ExData <- Data_MT_AUMLRef$TADA_with_ATTAINS |> +sf::st_drop_geometry() + +# add ATTAINS.WaterType only for rows without values in that column +MT_addMissing <- TADA_CrosswalkATTAINSWaterTypes(MT_ExData) + +# add ATTAINS.WaterType for all rows (replace existing matches) +MT_replaceAll <- TADA_CrosswalkATTAINSWaterTypes(MT_ExData, replace_all = TRUE) + +# add ATTAINS.WaterType to TADA df without ATTAINS.WaterType column +Tribal_addAll <- TADA_CrosswalkATTAINSWaterTypes(Data_TribalNations_Harmonized) + +# modify tribal example data to include an ATTAINS.WaterType not allowed by ATTAINS +Tribal_modified <- Tribal_addAll |> +dplyr::mutate(ATTAINS.WaterType = +ifelse(TADA.MonitoringLocationIdentifier \%in\% + c("REDLAKE_WQX-GREE-REDLAKE", + "UTEMTN-COTTONWOOD WASH SPRING", + "BLCKFEET-00000054", + "BLCKFEET-00000056" + ), "INVALID WATER TYPE", + ATTAINS.WaterType)) + + # add ATTAINS.WaterType for any rows where it is missing, review all ATTAINS.WaterType + # values and update any that are not allowed + Tribal_reviewUpdate <- TADA_CrosswalkATTAINSWaterTypes(Tribal_modified, + review_all = TRUE, + review_action = "update") + + # filter to Blackfeet + Tribal_modified2 <- Tribal_modified |> + dplyr::filter(OrganizationIdentifier == "BLCKFEET") + + # append additional columns to the data frame to allow for creating the AUML crosswalk + Tribal_reviewUpdate2 <- TADA_CrosswalkATTAINSWaterTypes(Tribal_modified2, + org_id = "BLCKFEET", + review_all = TRUE, + review_action = "update", + create_AUMLRef = TRUE) + + Tribal_AUMLRef <- TADA_UpdateATTAINSAUMLCrosswalk( + org_id = "BLCKFEET", + crosswalk = Tribal_reviewUpdate2, + api_key = .setEQKey()) +} + +} diff --git a/tests/testthat/test-ATTAINSCrosswalks.R b/tests/testthat/test-ATTAINSCrosswalks.R index 2335b9864..c3e2cd95a 100644 --- a/tests/testthat/test-ATTAINSCrosswalks.R +++ b/tests/testthat/test-ATTAINSCrosswalks.R @@ -157,7 +157,7 @@ testthat::test_that("TADA_DefineCriteriaMethodology ", { ) }) -test_that("Excel file generation works correctly with overwrite = F in TADA_UsesForAnalysis when the ParamUseMLCrosswalks.xlsx does not exist yet.", { +testthat::test_that("Excel file generation works correctly with overwrite = F in TADA_UsesForAnalysis when the ParamUseMLCrosswalks.xlsx does not exist yet.", { # specify downloads path downloads_path <- .get_downloads_path("ParamUseMLCrosswalks.xlsx") @@ -199,7 +199,7 @@ test_that("Excel file generation works correctly with overwrite = F in TADA_Uses on.exit(if (file.exists(downloads_path)) file.remove(downloads_path)) }) -test_that("Excel file generation works correctly with overwrite = T in TADA_UsesForAnalysis when the ParamUseMLCrosswalks.xlsx does not exist yet.", { +testthat::test_that("Excel file generation works correctly with overwrite = T in TADA_UsesForAnalysis when the ParamUseMLCrosswalks.xlsx does not exist yet.", { # specify downloads path downloads_path <- .get_downloads_path("ParamUseMLCrosswalks.xlsx") @@ -227,7 +227,7 @@ test_that("Excel file generation works correctly with overwrite = T in TADA_Uses on.exit(if (file.exists(downloads_path)) file.remove(downloads_path)) }) -test_that("Excel file generation works correctly with overwrite = F in TADA_MLSummaryRef when the ParamUseMLCrosswalks.xlsx does not exist yet.", { +testthat::test_that("Excel file generation works correctly with overwrite = F in TADA_MLSummaryRef when the ParamUseMLCrosswalks.xlsx does not exist yet.", { # specify downloads path downloads_path <- .get_downloads_path("ParamUseMLCrosswalks.xlsx") @@ -274,7 +274,7 @@ test_that("Excel file generation works correctly with overwrite = F in TADA_MLSu on.exit(if (file.exists(downloads_path)) file.remove(downloads_path)) }) -test_that("Excel file generation works correctly with overwrite = T in TADA_MLSummaryRef when the ParamUseMLCrosswalks.xlsx does not exist yet.", { +testthat::test_that("Excel file generation works correctly with overwrite = T in TADA_MLSummaryRef when the ParamUseMLCrosswalks.xlsx does not exist yet.", { # specify downloads path downloads_path <- .get_downloads_path("ParamUseMLCrosswalks.xlsx") @@ -307,7 +307,7 @@ test_that("Excel file generation works correctly with overwrite = T in TADA_MLSu on.exit(if (file.exists(downloads_path)) file.remove(downloads_path)) }) -test_that("Excel file generation works with blank inputs in TADA_ParametersForAnalysis even when excel file does not exist yet.", { +testthat::test_that("Excel file generation works with blank inputs in TADA_ParametersForAnalysis even when excel file does not exist yet.", { # specify downloads path downloads_path <- .get_downloads_path("ParamUseMLCrosswalks.xlsx") @@ -357,7 +357,7 @@ test_that("Excel file generation works with blank inputs in TADA_ParametersForAn on.exit(if (file.exists(downloads_path)) file.remove(downloads_path)) }) -test_that("Excel file generation works with blank inputs in TADA_UsesForAnalysis even when excel file does not exist yet.", { +testthat::test_that("Excel file generation works with blank inputs in TADA_UsesForAnalysis even when excel file does not exist yet.", { # specify downloads path downloads_path <- .get_downloads_path("ParamUseMLCrosswalks.xlsx") @@ -411,7 +411,7 @@ test_that("Excel file generation works with blank inputs in TADA_UsesForAnalysis on.exit(if (file.exists(downloads_path)) file.remove(downloads_path)) }) -test_that("Excel file generation works with blank inputs in TADA_MLSummary even when excel file does not exist yet.", { +testthat::test_that("Excel file generation works with blank inputs in TADA_MLSummary even when excel file does not exist yet.", { # specify downloads path downloads_path <- .get_downloads_path("ParamUseMLCrosswalks.xlsx") @@ -467,3 +467,131 @@ test_that("Excel file generation works with blank inputs in TADA_MLSummary even # Clean up after test completes on.exit(if (file.exists(downloads_path)) file.remove(downloads_path)) }) + +testthat::test_that("TADA_CrosswalkATTAINSWaterTypes does not replace valid ATTAINS.WaterType entries", { + # create list of allowable ATTAINS water types + attains.types <- quiet( + rExpertQuery::EQ_DomainValues("water_type") |> + dplyr::select(name) |> + dplyr::distinct() |> + dplyr::pull() + ) + + # example TADA df already including an ATTAINS.WaterType column + MT_exData <- Data_MT_AUMLRef$TADA_with_ATTAINS |> + sf::st_drop_geometry() |> + dplyr::filter(ATTAINS.WaterType %in% attains.types) + + # run TADA_CrosswalkATTAINSWaterTypes + MT_exDataCw <- TADA_CrosswalkATTAINSWaterTypes(MT_exData) + + # compare dfs by anti-join + MT_compare <- MT_exData |> + dplyr::anti_join(MT_exDataCw, by = names(MT_exData)) + + # check to see that there are no rows in the df resulting from the anti-join + testthat::expect_equal(NROW(MT_compare), 0) +}) + +testthat::test_that("In TADA_CrosswalkATTAINSWaterType ATTAINS.WaterType values are only added for rows missing ATTAINS.WaterType", { + # load test data and drop geometry + MT_exData <- Data_MT_AUMLRef$TADA_with_ATTAINS |> sf::st_drop_geometry() + + # create a list of TADA.MonitoringLocationIdentifiers with existing ATTAINS.WaterType + WT_yes <- MT_exData |> + dplyr::filter(!is.na(ATTAINS.WaterType), ATTAINS.WaterType != "") |> + dplyr::select(TADA.MonitoringLocationIdentifier) |> + dplyr::distinct() |> + dplyr::pull() + + # create a list of TADA.MonitoringLocationIdentifiers without existing ATTAINS.WaterType + WT_no <- MT_exData |> + dplyr::filter(!TADA.MonitoringLocationIdentifier %in% WT_yes) |> + dplyr::select(TADA.MonitoringLocationIdentifier) |> + dplyr::distinct() |> + dplyr::pull() + + # add ATTAINS.WaterType only for rows without values in that column + MT_addMissing <- TADA_CrosswalkATTAINSWaterTypes(MT_exData) + + # compare existing ATTAINS.WaterType before and after running function + MT_filtYesOrig <- MT_exData |> + dplyr::filter(TADA.MonitoringLocationIdentifier %in% WT_yes) + + # filter new data set for + MT_filtYesNew <- MT_addMissing |> + dplyr::filter(TADA.MonitoringLocationIdentifier %in% WT_yes) + + # compare rows with existing ATTAINS.WaterType before and after running function + MT_compare <- MT_filtYesNew |> + dplyr::anti_join(MT_filtYesOrig, by = names(MT_filtYesOrig)) + + # filter for rows with newly assigned ATTAINS.WaterType + MT_filtNoNew <- MT_addMissing |> + dplyr::filter( + TADA.MonitoringLocationIdentifier %in% WT_no, + !is.na(ATTAINS.WaterType), + ATTAINS.WaterType != "" + ) + + # check to see that now rows with existing ATTAINS.WaterType values were changed + testthat::expect_equal(NROW(MT_compare), 0) + # check to see that new ATTAINS.WaterType values were added for rows without existing ATTAINS.WaterType values + testthat::expect_equal(NROW(MT_filtNoNew), 76) +}) + +testthat::test_that("TADA_CrosswalkATTAINSWaterType identifies and updates invalid ATTAINS.WaterType values.", { + # create list of allowable ATTAINS water types + attains.types <- quiet( + rExpertQuery::EQ_DomainValues("water_type") |> + dplyr::select(name) |> + dplyr::distinct() |> + dplyr::pull() + ) + + # add ATTAINS.WaterType to TADA df without ATTAINS.WaterType column + Tribal_addAll <- TADA_CrosswalkATTAINSWaterTypes( + Data_TribalNations_Harmonized + ) + + # modify tribal example data to include an ATTAINS.WaterType not allowed by ATTAINS + Tribal_modified <- Tribal_addAll |> + dplyr::mutate( + ATTAINS.WaterType = ifelse( + TADA.MonitoringLocationIdentifier %in% + c( + "REDLAKE_WQX-GREE-REDLAKE", + "UTEMTN-COTTONWOOD WASH SPRING", + "BLCKFEET-00000054", + "BLCKFEET-00000056" + ), + "INVALID WATER TYPE", + ATTAINS.WaterType + ) + ) + + # add ATTAINS.WaterType for any rows where it is missing, review all ATTAINS.WaterType + # values and update any that are not allowed + Tribal_reviewUpdate <- TADA_CrosswalkATTAINSWaterTypes( + Tribal_modified, + review_all = TRUE, + review_action = "update" + ) + + # filter to retain only monitoring locations that had invalid water types before function was run + Tribal_reviewFilt <- Tribal_reviewUpdate |> + dplyr::filter( + TADA.MonitoringLocationIdentifier %in% + c( + "REDLAKE_WQX-GREE-REDLAKE", + "UTEMTN-COTTONWOOD WASH SPRING", + "BLCKFEET-00000054", + "BLCKFEET-00000056" + ) + ) |> + dplyr::select(TADA.MonitoringLocationIdentifier, ATTAINS.WaterType) |> + dplyr::filter(ATTAINS.WaterType %in% attains.types) |> + dplyr::distinct() + + testthat::expect_equal(NROW(Tribal_reviewFilt), 4) +})