Quick Guide
Hook up Data Sources
To access a data source, its BASIN-3D plugin must be configured. Custom plugins can be built. Documentation will be forthcoming in future versions. Current available plugins:
If a plugin exists for the data source, import it before registering a synthesizer.
from basin3d.plugins import <plugin_name>
Register a Synthesizer
- basin3d.synthesis.register(plugins=None)[source]
Register the specified plugins or implicitly register loaded plugins
>>> from basin3d import synthesis >>> synthesizer = synthesis.register(['basin3d.plugins.usgs.USGSDataSourcePlugin']) >>> synthesizer.datasources [DataSource(id='USGS', name='USGS', id_prefix='USGS', location='https://waterservices.usgs.gov/nwis/', credentials={})]
Get a List of Locations for a Data Source
- basin3d.synthesis.DataSynthesizer.monitoring_features(self, query=None, **kwargs)
Search for all Monitoring Features, Monitoring Features by parent monitoring features, or Monitoring Feature by id(s).
To see feature types for a given plugin: <plugin_module>.<plugin_class>.feature_types
Search for a single monitoring feature by id:
>>> from basin3d.plugins import usgs, epa >>> from basin3d import synthesis >>> synthesizer = synthesis.register() >>> response = synthesizer.monitoring_features(id='USGS-0101') >>> mf = response.data >>> print(f"{mf.id} - {mf.description}") USGS-0101 - SUBREGION: St. John
Search for all USGS monitoring features:
>>> for mf in synthesizer.monitoring_features(datasource='USGS', feature_type='region'): ... print(f"{mf.id} - {mf.description}") USGS-01 - REGION: New England USGS-02 - REGION: Mid Atlantic USGS-03 - REGION: South Atlantic-Gulf ...
Search for USGS points by parent (subbasin) monitoring features:
>>> for mf in synthesizer.monitoring_features(feature_type='point',parent_feature=['USGS-17040101']): ... print(f"{mf.id} {mf.coordinates and [(p.x, p.y) for p in mf.coordinates.absolute.horizontal_position]}") USGS-13010000 [(-110.6647222, 44.1336111)] USGS-13010065 [(-110.6675, 44.09888889)] USGS-13010450 [(-110.5874305, 43.9038296)] ...
Search for USGS points by monitoring features identifiers:
>>> for mf in synthesizer.monitoring_features(feature_type='point', monitoring_feature=['USGS-13010000', 'USGS-13010450']): ... print(f"{mf.id} {mf.coordinates and [(p.x, p.y) for p in mf.coordinates.absolute.horizontal_position]}") USGS-13010000 [(-110.6647222, 44.1336111)] USGS-13010450 [(-110.5874305, 43.9038296)]
Unsupported feature types warning:
The code below is an example of what you will see if a registered plugin does not support the requested feature type.
>>> response_itr = synthesizer.monitoring_features(feature_type='horizontal_path') >>> for mf in response_itr: ... print(mf) ...
Output warning messages from the returned iterator
This is an example of checking the synthesis response messages in the
basin3d.core.synthesis.DataSourceModelIterator
.>>> response_itr.synthesis_response.messages [SynthesisMessage(msg='Feature type HORIZONTAL_PATH not supported by USGS.', level='WARN', where=['USGS', 'MonitoringFeature']), SynthesisMessage(msg='Feature type HORIZONTAL_PATH not supported by EPA Water Quality eXchange.', level='WARN', where=['EPA', 'MonitoringFeature'])]
- Parameters:
query (
Optional
[QueryMonitoringFeature
]) – (optional) A Monitoring Feature Querybasin3d.core.schema.query.QueryMonitoringFeature
objectkwargs – (optional) Monitoring Feature Query parameters. See Query info below.
- Return type:
- Returns:
a single
SynthesisResponse
for a query by id or aDataSourceModelIterator
for multplebasin3d.core.models.MonitoringFeature
objects.
Note
Monitoring Feature Query parameters
basin3d.core.schema.query.QueryMonitoringFeature
All parameters are optional.* datasource A single data source id prefix.* feature_type Thebasin3d.core.schema.enum.FeatureTypeEnum
of the desired Monitoring Feature(s). Data Sources may not support all Feature Types.Only one of the following can be specified in a query:* id A single Monitoring Feature ID for the Monitoring Feature desired. Returns a single Synthesis Response object.* monitoring_feature List of Monitoring Feature IDs for the Monitoring Features desired. Returns iterator of MonitoringFeature objects.* parent_feature List of Monitoring Feature IDs for the parent features of the desired Monitoring Features. Returns iterator of MonitoringFeature objects.Note
Monitoring Feature attributes
basin3d.core.models.MonitoringFeature
Attributes values are dependent on data source features.* id Unique feature identifier, prefixed by data source id* name Feature name* description Description of the Monitoring Feature* feature_typebasin3d.core.schema.enum.FeatureTypeEnum
REGION, SUBREGION, BASIN, SUBBASIN, WATERSHED, SUBWATERSHED, SITE, PLOT, HORIZONTAL PATH, VERTICAL PATH, POINT* observed_properties List of observed propertiesbasin3d.core.models.ObservedProperty
collected at the feature.* related_sampling_feature_complex List ofbasin3d.core.models.RelatedSamplingFeature
. PARENT features are currently supported.* shape Shape of the feature: POINT, CURVE, SURFACE, SOLID* coordinates Location of feature in absolute and/or representative datum:basin3d.core.models.Coordinate
* description_reference Additional information about the feature* related_party List of people or organizations responsible for the feature* utc_offset Coordinate Universal Time offset in hours (offset in hours), e.g., +9* datasource The feature’s data sourcebasin3d.core.models.DataSource
Get a List of Attribute Mappings for a Data Source
- basin3d.synthesis.DataSynthesizer.attribute_mappings(self, datasource_id=None, attr_type=None, attr_vocab=None, from_basin3d=False)
>>> from basin3d.plugins import usgs >>> from basin3d import synthesis >>> synthesizer = synthesis.register() >>> response = synthesizer.attribute_mappings() # list all attribute mappings registered >>> for attr_mapping in response: ... print(f'{attr_mapping.attr_type} | {attr_mapping.basin3d_vocab} -- {attr_mapping.datasource_vocab}') OBSERVED_PROPERTY:SAMPLING_MEDIUM | PH:WATER -- 00400 OBSERVED_PROPERTY:SAMPLING_MEDIUM | RDC:WATER -- 00060 OBSERVED_PROPERTY:SAMPLING_MEDIUM | WLE:WATER -- 63161 OBSERVED_PROPERTY:SAMPLING_MEDIUM | WT:WATER -- 00010 OBSERVED_PROPERTY:SAMPLING_MEDIUM | DO:WATER -- 00300 ...
>>> response = synthesizer.attribute_mappings(datasource_id='USGS', attr_type='STATISTIC') >>> for attr_mapping in response: ... print(f'{attr_mapping.attr_type} | {attr_mapping.basin3d_vocab} -- {attr_mapping.datasource_vocab}') STATISTIC | MEAN -- 00003 STATISTIC | MIN -- 00002 STATISTIC | MAX -- 00001 STATISTIC | TOTAL -- 00006
>>> response = synthesizer.attribute_mappings(datasource_id='USGS', attr_type='RESULT_QUALITY', attr_vocab=['VALIDATED', 'ESTIMATED'], from_basin3d=True) >>> for attr_mapping in response: ... print(f'{attr_mapping.attr_type} | {attr_mapping.basin3d_vocab} -- {attr_mapping.datasource_vocab}, {attr_mapping.datasource_desc}') RESULT_QUALITY | ESTIMATED -- e, Value has been edited or estimated by USGS personnel and is write protected RESULT_QUALITY | ESTIMATED -- E, Value was computed from estimated unit values. RESULT_QUALITY | VALIDATED -- A, Approved for publication -- Processing and review completed.
Return all the
basin3d.core.models.AttributMapping
registered or those that match the specified fields.- Parameters:
datasource_id – str, The datasource identifier
attr_type – str, The attribute type (e.g., OBSERVED_PROPERTY, STATISTIC, etc)
attr_vocab – str, The attribute vocabulary, either the BASIN-3D vocabulary or the datasource vocabulary
from_basin3d – bool, True = the specified attr_vocab is a BASIN-3D vocabulary, False: the specified attr_vocab is from the datasource
- Returns:
iterator of
basin3d.core.models.AttributeMapping
objects
Get a List of Variables Supported by a BASIN-3D
- basin3d.synthesis.DataSynthesizer.observed_properties(self)
>>> from basin3d.plugins import usgs >>> from basin3d import synthesis >>> synthesizer = synthesis.register() >>> response = synthesizer.observed_properties() >>> for opv in response: ... print(f'{opv.basin3d_vocab} -- {opv.full_name} -- {opv.units}') ACT -- Acetate (CH3COO) -- mM Br -- Bromide (Br) -- mM Cl -- Chloride (Cl) -- mM DIN -- Dissolved Inorganic Nitrogen (Nitrate + Nitrite) -- mg/L DTN -- Dissolved Total Nitrogen (DTN) -- mg/L F -- Fluoride (F) -- mM ...
BASIN-3D observed properties. An observed property defines what is being measured. Data source observed property vocabularies are mapped and thus synthesized to the BASIN-3D observed property vocabulary.
- Returns:
an iterator of
basin3d.core.models.ObservedProperty
objects
Get Time Series Data
- basin3d.synthesis.DataSynthesizer.measurement_timeseries_tvp_observations(self, query=None, **kwargs)
Search for Measurement Timeseries TVP Observations for the specified query arguments.
Aggregation Duration for DAY (default) and NONE are both supported.
Search with aggregation duration DAY:
>>> from basin3d.plugins import usgs >>> from basin3d import synthesis >>> synthesizer = synthesis.register() >>> timeseries = synthesizer.measurement_timeseries_tvp_observations(monitoring_feature=['USGS-09110990'],observed_property=['RDC','WT'],start_date='2019-10-01',end_date='2019-10-30',aggregation_duration='DAY') >>> for timeseries in timeseries: ... print(f"{timeseries.feature_of_interest.id} - {timeseries.observed_property.get_basin3d_vocab()}") USGS-09110990 - RDC
Search with aggregation duration NONE:
>>> from basin3d.plugins import usgs >>> from basin3d import synthesis >>> synthesizer = synthesis.register() >>> timeseries = synthesizer.measurement_timeseries_tvp_observations(monitoring_feature=["USGS-09110990", "USGS-09111250"],observed_property=['RDC','WT'],start_date='2020-04-01',end_date='2020-04-30',aggregation_duration='NONE') >>> for timeseries in timeseries: ... print(f"{timeseries.feature_of_interest.id} - {timeseries.observed_property.get_basin3d_vocab()}") USGS-09110990 - RDC USGS-09111250 - RDC
- Parameters:
query (
Optional
[QueryMeasurementTimeseriesTVP
]) – (optional)basin3d.core.schema.query.QueryMeasurementTimeseriesTVP
objectkwargs – (required) Measurement Timeseries TVP Query parameters. See Query info below.
- Return type:
- Returns:
a
DataSourceModelIterator
that yieldsbasin3d.core.models.MeasurementTimeseriesTVPObservation
objects
Note
Measurement Timeseries TVP Query parameters
basin3d.core.schema.query.QueryMeasurementTimeseriesTVP
Required arguments:* monitoring_feature List of monitoring features id(s)* observed_property List of observed property(ies), i.e., BASIN-3D observed property vocabulary. Seebasin3d.synthesis.DataSynthesizer.observed_properties()
* start_date Start date YYYY-MM-DDOptional arguments:* end_date End date YYYY-MM-DD* aggregation_duration A single aggregation durationbasin3d.core.schema.enum.AggregationDurationEnum
(YEAR|MONTH|DAY|HOUR|MINUTE|SECOND|NONE)* statistic List of statistic(s)basin3d.core.schema.enum.StatisticEnum
(MEAN|MIN|MAX|INSTANTANEOUS)* result_quality List of result quality(ies)basin3d.core.schema.enum.ResultQualityEnum
(VALIDATED|UNVALIDATED|SUSPECTED|REJECTED|ESTIMATED)* sampling_medium List of sampling medium(s)basin3d.core.schema.enum.SamplingMediumEnum
(SOLID_PHASE|WATER|GAS|OTHER)* datasource A single data source id prefixNote
Measurement Timeseries TVP Observation attributes
basin3d.core.models.MeasurementTimeseriesTVPObservation
Attributes values are dependent on data source features.basin3d.core.models.MappedAttribute
are returned for several attributes so that the data source values are also available.* id Observation identifier* type Type of observation: MEASUREMENT_TVP_TIMESERIES* observed_property The observation’s observed propertybasin3d.core.models.MappedAttribute
* datasource The data sourcebasin3d.core.models.DataSource
* sampling_medium Observed property sampling mediumbasin3d.core.models.MappedAttribute
(SOLID_PHASE, WATER, GAS, OTHER)* phenomenon_time Datetime of the observation, for a timeseries the start and end times can be provided* utc_offset Coordinate Universal Time offset in hours (offset in hours), e.g., +9* feature_of_interest Monitoring Feature objectbasin3d.core.models.MonitoringFeature
, feature on which the observation is being made* feature_of_interest_type Feature type of the feature of interest,basin3d.core.schema.enum.FeatureTypeEnum
* result Observed values of the observed property being assessed, and (opt) their result quality,basin3d.core.models.ResultListTVP
* time_reference_position Position of timestamp in aggregated_duration (START, MIDDLE, END)* aggregation_duration Time period represented by observationbasin3d.core.models.MappedAttribute
(YEAR, MONTH, DAY, HOUR, MINUTE, SECOND)* unit_of_measurement Units in which the observation is reported* statistic Statistical property of the observation resultbasin3d.core.models.MappedAttribute
(MEAN, MIN, MAX, TOTAL)* result_quality List quality assessment found in the resultsbasin3d.core.models.MappedAttribute
(VALIDATED, UNVALIDATED, SUSPECTED, REJECTED, ESTIMATED)
See Measurement Timeseries TVP Observations Object Structure
Logging
Use basin3d.monitor.configure()
to configure python logging.
The example below changes the log level to DEBUG. Please refer to the Python logging documentation
(https://docs.python.org/3/howto/logging.html#configuring-logging) on logging configuration options. configure()
returns the logging configuration as a dictionary for review.
>>> from basin3d import monitor, synthesis
>>> from basin3d.plugins import usgs
>>> monitor.configure(loggers={"basin3d": {"level": "DEBUG"}})
{'version': 1, 'incremental': False, 'disable_existing_loggers': True,
...
Once logging is configured, all BASIN-3D logging is outputted.
>>> synthesizer = synthesis.register()
2022-04-14T16:59:31.082 INFO * basin3d.core.synthesis * - Loading Plugin = USGSDataSourcePlugin
2022-04-14T16:59:31.083 DEBUG * basin3d.core.catalog * - Initializing CatalogTinyDb metadata catalog
2022-04-14T16:59:31.084 INFO * basin3d.core.catalog * - Loading metadata catalog for Plugin USGS
2022-04-14T16:59:31.085 DEBUG * basin3d.core.catalog * - Mapping file mapping_usgs.csv for plugin package basin3d.plugins
2022-04-14T16:59:31.086 DEBUG * basin3d.core.catalog * - Mapped 00400 to pH
2022-04-14T16:59:31.087 DEBUG * basin3d.core.catalog * - Mapped 00060 to River Discharge
...
To create and output custom log messages:
Use
basin3d.monitor.get_logger()
to create a custom logger.Use
basin3d.monitor.configure()
to configure the custom logger output.
>>> from basin3d import monitor
>>> monitor.configure(loggers={"my_logger": {"level": "DEBUG",
... 'handlers': ['error-console', 'console'], 'propagate': True}})
{'version': 1, 'incremental': False, 'disable_existing_loggers': True,
...
>>> logger = monitor.get_logger("my_logger")
>>> logger.info("My logging message")
2022-04-14T16:57:36.163 INFO * my_logger * - My logging message
Write log messages to a file called basin3d.log:
>>> from basin3d import monitor, synthesis
>>> from basin3d.plugins import usgs
>>> monitor.configure(
... handlers={ "file":
... { "class":"logging.FileHandler", "formatter": "simple", "filename": ".}/basin3d.log"}},
... loggers={"basin3d": {"handlers": ["console", "file"]}})
{'version': 1, 'incremental': False, 'disable_existing_loggers': True,
...
>>> synthesizer = synthesis.register()
2022-04-14T17:32:50.502 INFO * basin3d.core.synthesis * - Loading Plugin = USGSDataSourcePlugin
2022-04-14T17:32:50.507 INFO * basin3d.core.catalog * - Loading metadata catalog for Plugin USGS
2022-04-14T17:32:50.509 INFO * basin3d.core.catalog * - Initialized CatalogTinyDb metadata catalog