Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,15 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## Unrelease
## Unreleased: 0.8.0

### Added
- water level for WQP

### Changed
- NM OSE Roswell data is now pulled from ST2 and not CKAN

### Fixed


## 0.7.0
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ Data comes from the following sources. We are continuously adding new sources as
- [USGS (NWIS)](https://waterdata.usgs.gov/nwis)
- Available data: `water levels`
- [Water Quality Portal (WQP)](https://www.waterqualitydata.us/)
- Available data: `water quality`
- Available data: `water levels`, `water quality`

## Usage

Expand All @@ -66,7 +66,7 @@ where `{parameter}` is the name of the parameter whose data is to be retrieved,
| **nmose-roswell** | X | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - |
| **nwis** | X | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - |
| **pvacd** | X | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - |
| **wqp** | - | X | X | X | X | X | X | X | X | X | X | X | X | X | X | X |
| **wqp** | X | X | X | X | X | X | X | X | X | X | X | X | X | X | X | X |

### Output
The `--output` option is required and used to set the output type:
Expand Down
27 changes: 7 additions & 20 deletions backend/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,11 @@
BernCoWaterLevelSource,
CABQSiteSource,
CABQWaterLevelSource,
NMOSERoswellSiteSource,
NMOSERoswellWaterLevelSource,
)
from .connectors.usgs.source import NWISSiteSource, NWISWaterLevelSource
from .connectors.wqp.source import WQPSiteSource, WQPAnalyteSource
from .connectors.wqp.source import WQPSiteSource, WQPAnalyteSource, WQPWaterLevelSource

SOURCE_KEYS = (
"bernco",
Expand Down Expand Up @@ -90,7 +92,7 @@ def get_source(source):
elif source == "nmose_isc_seven_rivers":
return ISCSevenRiversSiteSource()
elif source == "nmose_roswell":
return OSERoswellSiteSource(HONDO_RESOURCE_ID)
return NMOSERoswellSiteSource()
elif source == "nwis":
return NWISSiteSource()
elif source == "pvacd":
Expand Down Expand Up @@ -218,24 +220,7 @@ def water_level_sources(self):
sources.append((NWISSiteSource(), NWISWaterLevelSource()))

if self.use_source_nmose_roswell:
sources.append(
(
OSERoswellSiteSource(HONDO_RESOURCE_ID),
OSERoswellWaterLevelSource(HONDO_RESOURCE_ID),
)
)
sources.append(
(
OSERoswellSiteSource(FORT_SUMNER_RESOURCE_ID),
OSERoswellWaterLevelSource(FORT_SUMNER_RESOURCE_ID),
)
)
sources.append(
(
OSERoswellSiteSource(ROSWELL_RESOURCE_ID),
OSERoswellWaterLevelSource(ROSWELL_RESOURCE_ID),
)
)
sources.append((NMOSERoswellSiteSource(), NMOSERoswellWaterLevelSource()))
if self.use_source_pvacd:
sources.append((PVACDSiteSource(), PVACDWaterLevelSource()))
if self.use_source_bernco:
Expand All @@ -244,6 +229,8 @@ def water_level_sources(self):
sources.append((EBIDSiteSource(), EBIDWaterLevelSource()))
if self.use_source_cabq:
sources.append((CABQSiteSource(), CABQWaterLevelSource()))
if self.use_source_wqp:
sources.append((WQPSiteSource(), WQPWaterLevelSource()))

for s, ss in sources:
s.set_config(self)
Expand Down
2 changes: 1 addition & 1 deletion backend/connectors/mappings.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@
"Total Sulfate",
],
TDS: ["Total dissolved solids"],
URANIUM: ["Uranium", "Uranium-238"],
URANIUM: ["Uranium"],
PH: ["pH"],
}
# BOR ===============================================================================
Expand Down
18 changes: 18 additions & 0 deletions backend/connectors/st2/source.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
CABQ_BOUNDING_POLYGON,
)
from backend.connectors.st2.transformer import (
NMOSERoswellSiteTransformer,
NMOSERoswellWaterLevelTransformer,
PVACDSiteTransformer,
PVACDWaterLevelTransformer,
EBIDSiteTransformer,
Expand Down Expand Up @@ -64,6 +66,14 @@ def _get_filters(self):
return [f"properties/agency eq '{self.agency}'"]


class NMOSERoswellSiteSource(ST2SiteSource):
transformer_klass = NMOSERoswellSiteTransformer
agency = "OSE-Roswell"

def __repr__(self):
return "NMOSERoswellSiteSource"


class PVACDSiteSource(ST2SiteSource):
transformer_klass = PVACDSiteTransformer
agency = "PVACD"
Expand Down Expand Up @@ -172,6 +182,14 @@ def get_records(self, site_record, *args, **kw):
return records


class NMOSERoswellWaterLevelSource(ST2WaterLevelSource):
transformer_klass = NMOSERoswellWaterLevelTransformer
agency = "OSE-Roswell"

def __repr__(self):
return "NMOSERoswellWaterLevelSource"


class PVACDWaterLevelSource(ST2WaterLevelSource):
transformer_klass = PVACDWaterLevelTransformer
agency = "PVACD"
Expand Down
8 changes: 8 additions & 0 deletions backend/connectors/st2/transformer.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@
)


class NMOSERoswellSiteTransformer(STSiteTransformer):
source_id = "ST2/NMOSE-Roswell"


class PVACDSiteTransformer(STSiteTransformer):
source_id = "ST2/PVACD"

Expand Down Expand Up @@ -103,6 +107,10 @@ def _transform_elevation(self, elevation, record):
# return rec


class NMOSERoswellWaterLevelTransformer(WaterLevelTransformer):
source_tag = "ST2/NMOSE-Roswell"


class PVACDWaterLevelTransformer(WaterLevelTransformer):
source_tag = "ST2/PVACD"

Expand Down
76 changes: 56 additions & 20 deletions backend/connectors/wqp/source.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,23 @@
from backend.connectors import NM_STATE_BOUNDING_POLYGON
from backend.connectors.mappings import WQP_ANALYTE_MAPPING
from backend.constants import (
TDS,
URANIUM,
NITRATE,
SULFATE,
ARSENIC,
CHLORIDE,
PARAMETER_NAME,
PARAMETER_VALUE,
PARAMETER_UNITS,
SOURCE_PARAMETER_NAME,
SOURCE_PARAMETER_UNITS,
DT_MEASURED,
)
from backend.connectors.wqp.transformer import WQPSiteTransformer, WQPAnalyteTransformer
from backend.connectors.wqp.transformer import (
WQPSiteTransformer,
WQPAnalyteTransformer,
WQPWaterLevelTransformer,
)
from backend.source import (
BaseSource,
BaseSiteSource,
BaseAnalyteSource,
BaseWaterLevelSource,
BaseParameterSource,
make_site_list,
get_most_recent,
get_analyte_search_param,
Expand All @@ -61,7 +60,7 @@ def get_date_range(config):

class WQPSiteSource(BaseSiteSource):
transformer_klass = WQPSiteTransformer
chunk_size = 100
chunk_size = 50

bounding_polygon = NM_STATE_BOUNDING_POLYGON

Expand Down Expand Up @@ -93,6 +92,10 @@ def get_records(self):
params["characteristicName"] = get_analyte_search_param(
config.parameter, WQP_ANALYTE_MAPPING
)
else:
# every record with pCode 30210 (depth in m) has a corresponding
# record with pCode 72019 (depth in ft) but not vice versa
params["pCode"] = "30210"

params.update(get_date_range(config))

Expand All @@ -103,17 +106,15 @@ def get_records(self):
return parse_tsv(text)


class WQPAnalyteSource(BaseAnalyteSource):
transformer_klass = WQPAnalyteTransformer

def __repr__(self):
return "WQPAnalyteSource"
class WQPParameterSource(BaseParameterSource):

def _extract_parameter_record(self, record):
record[PARAMETER_NAME] = self.config.parameter
record[PARAMETER_VALUE] = record["ResultMeasureValue"]
record[PARAMETER_UNITS] = self.config.analyte_output_units
record[DT_MEASURED] = record["ActivityStartDate"]
record[PARAMETER_UNITS] = self._parameter_units_hook()
record[DT_MEASURED] = (
f"{record['ActivityStartDate']} {record['ActivityStartTime/Time']}"
)
record[SOURCE_PARAMETER_NAME] = record["CharacteristicName"]
record[SOURCE_PARAMETER_UNITS] = record["ResultMeasure/MeasureUnitCode"]
return record
Expand Down Expand Up @@ -148,22 +149,57 @@ def _extract_most_recent(self, records):
}

def get_records(self, site_record):
config = self.config
sites = make_site_list(site_record)

params = {
"siteid": sites,
"mimeType": "tsv",
"characteristicName": get_analyte_search_param(
self.config.parameter, WQP_ANALYTE_MAPPING
),
}
params.update(get_date_range(self.config))

if config.parameter.lower() != "waterlevels":
params["characteristicName"] = get_analyte_search_param(
config.parameter, WQP_ANALYTE_MAPPING
)
else:
# every record with pCode 30210 (depth in m) has a corresponding
# record with pCode 72019 (depth in ft) but not vice versa
params["pCode"] = "30210"

params.update(get_date_range(config))

text = self._execute_text_request(
"https://www.waterqualitydata.us/data/Result/search?", params
"https://www.waterqualitydata.us/data/Result/search?", params, timeout=30
)
if text:
return parse_tsv(text)

def _parameter_units_hook(self):
raise NotImplementedError(
f"{self.__class__.__name__} must implement _parameter_units_hook"
)


class WQPAnalyteSource(WQPParameterSource, BaseAnalyteSource):
transformer_klass = WQPAnalyteTransformer

def __repr__(self):
return "WQPAnalyteSource"

def _parameter_units_hook(self):
return self.config.analyte_output_units


# inherit from WQPParameterSource first so that its _extract_souce_parameter_units method is used instead of BaseWaterLevelSource's method
class WQPWaterLevelSource(WQPParameterSource, BaseWaterLevelSource):
transformer_klass = WQPWaterLevelTransformer

def __repr__(self):
return "WQPWaterLevelSource"

def _parameter_units_hook(self):
return self.config.waterlevel_output_units


# ============= EOF =============================================
11 changes: 10 additions & 1 deletion backend/connectors/wqp/transformer.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@
import pprint

from backend.record import SiteRecord, AnalyteSummaryRecord
from backend.transformer import BaseTransformer, SiteTransformer, AnalyteTransformer
from backend.transformer import (
BaseTransformer,
SiteTransformer,
AnalyteTransformer,
WaterLevelTransformer,
)


class WQPSiteTransformer(SiteTransformer):
Expand Down Expand Up @@ -44,4 +49,8 @@ class WQPAnalyteTransformer(AnalyteTransformer):
source_tag = "WQP"


class WQPWaterLevelTransformer(WaterLevelTransformer):
source_tag = "WQP"


# ============= EOF =============================================
2 changes: 1 addition & 1 deletion frontend/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -264,10 +264,10 @@ def weave(
config.use_source_nmose_roswell = no_nmose_roswell
config.use_source_nwis = no_nwis
config.use_source_pvacd = no_pvacd
config.use_source_wqp = no_wqp

config.use_source_bor = False
config.use_source_nmed_dwb = False
config.use_source_wqp = False

elif parameter == "carbonate":
config.use_source_nmbgmr_amp = no_nmbgmr_amp
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

setup(
name="nmuwd",
version="0.7.0",
version="0.7.1",
author="Jake Ross",
description="New Mexico Water Data Integration Engine",
long_description=long_description,
Expand Down