Skip to content

Commit

Permalink
Merge pull request #198 from gaiaresources/BDRSPS-779
Browse files Browse the repository at this point in the history
BDRSPS-779 Added basic files for the site visit template.
  • Loading branch information
Lincoln-GR authored Sep 6, 2024
2 parents a3099ea + 8987cb9 commit 0cd8031
Show file tree
Hide file tree
Showing 9 changed files with 393 additions and 37 deletions.
20 changes: 20 additions & 0 deletions abis_mapping/base/mapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

# Standard
import abc
import csv
import functools
import inspect
import json
Expand Down Expand Up @@ -126,6 +127,25 @@ def add_geometry_supplied_as(
graph.add((supplied_as, utils.namespaces.GEO.asWKT, geom.to_rdf_literal()))
graph.add((top_node, utils.namespaces.GEO.hasGeometry, supplied_as))

@classmethod
def generate_blank_template(cls) -> None:
"""Generates a blank csv for the template.
It is based on the schema field names and writes it to a file within
the template mapper's root dir. Note: full schema validation is not applied,
and metadata validation is.
"""
# Retrieve Schema Filepath
directory = pathlib.Path(inspect.getfile(cls)).parent
schema_file = directory / "schema.json"

# Get raw schema
fields: list[dict] = json.loads(schema_file.read_text())["fields"]
out_path = directory / f"{cls.metadata()['name']}.{cls.metadata()['file_type'].lower()}"
with out_path.open('w') as f:
csv_writer = csv.DictWriter(f, [field["name"] for field in fields])
csv_writer.writeheader()

@classmethod
def add_extra_fields_json(
cls,
Expand Down
2 changes: 1 addition & 1 deletion abis_mapping/templates/survey_site_data_v2/mapping.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""Provides ABIS Mapper for `survey_site_data.csv` Template v2"""
"""Provides ABIS Mapper for `survey_site_data-v2.0.0.csv` template."""

# Standard
import dataclasses
Expand Down
5 changes: 5 additions & 0 deletions abis_mapping/templates/survey_site_visit_data_v2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Template Description
A template to translate some Darwin Core fields

# Template Instructions
See `instructions.pdf` for more details
85 changes: 85 additions & 0 deletions abis_mapping/templates/survey_site_visit_data_v2/mapping.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
"""Provides ABIS Mapper for `survey_site_visit_data-v2.0.0` template."""

# Third-party
import frictionless
import rdflib

# Local
from abis_mapping import base

# Typing
from typing import Any, Iterator


class SurveySiteVisitMapper(base.mapper.ABISMapper):
"""ABIS mapper for the v2 survey site data csv template."""

# Default Dataset Metadata
DATASET_DEFAULT_NAME = "Example Systematic Survey Site Visit Dataset"
DATASET_DEFAULT_DESCRIPTION = "Example Systematic Survey Site Visit Dataset by Gaia Resources"

def apply_validation(
self,
data: base.types.ReadableType,
**kwargs: Any,
) -> frictionless.Report:
"""Applies Frictionless Validation for the csv Template
Args:
data (base.types.ReadableType): Raw data to be validated.
**kwargs (Any): Additional keyword arguments.
Keyword Args:
site_visit_id_map (dict[str, bool]): Site visit ids present in the occurrence template.
Returns:
frictionless.Report: Validation report for the specified data.
"""
# TODO: Implement
raise NotImplementedError

# Extract keyword arguments
# TODO: Uncomment
# site_visit_id_map: dict[str, bool] = kwargs.get("site_visit_id_map", {})

# Construct schema
schema = self.extra_fields_schema(data=data, full_schema=True)

# Construct resource
resource = frictionless.Resource(
source=data,
format="csv",
schema=schema,
encoding="utf-8",
)

# Validate
report = resource.validate()

# Return validation report
return report

def apply_mapping(
self,
data: base.types.ReadableType,
dataset_iri: rdflib.URIRef | None = None,
base_iri: rdflib.Namespace | None = None,
**kwargs: Any,
) -> Iterator[rdflib.Graph]:
"""Applies Mapping from Raw Data to ABIS conformant RDF.
Args:
data (ReadableType): Readable raw data.
dataset_iri (Optional[rdflib.URIRef]): Optional dataset IRI.
base_iri (Optional[rdflib.Namespace]): Optional mapping base IRI.
**kwargs (Any): Additional keyword arguments.
Keyword Args:
chunk_size (Optional[int]): How many rows of the original data to
ingest before yielding a graph. `None` will ingest all rows.
Yields:
rdflib.Graph: ABIS Conformant RDF Sub-Graph from Raw Data Chunk.
"""
# TODO: Implement
raise NotImplementedError
13 changes: 13 additions & 0 deletions abis_mapping/templates/survey_site_visit_data_v2/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "survey_site_visit_data",
"label": "Systematic Survey Site Visit Data Template",
"version": "2.0.0",
"description": "A template for systematic survey site visit data",
"biodiversity_type": "Systematic Survey Site Visit Data",
"spatial_type": "Point, line, polygon",
"file_type": "CSV",
"sampling_type": "systematic survey",
"template_url": "https://raw.githubusercontent.com/gaiaresources/abis-mapping/main/abis_mapping/templates/survey_site_visit_data_v2/survey_site_visit_data.csv",
"schema_url": "https://raw.githubusercontent.com/gaiaresources/abis-mapping/main/abis_mapping/templates/survey_site_visit_data_v2/schema.json",
"instructions_url": "https://raw.githubusercontent.com/gaiaresources/abis-mapping/main/abis_mapping/templates/survey_site_visit_data_v2/instructions.pdf"
}
167 changes: 167 additions & 0 deletions abis_mapping/templates/survey_site_visit_data_v2/schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
{
"fields": [
{
"name": "surveyID",
"title": "SurveyID",
"description": "The identifier of the Survey that the Site is related to in this dataset.",
"example": "AR220-01",
"type": "string",
"format": "default",
"constraints": {
"required": false
}
},
{
"name": "siteID",
"title": "Site ID",
"description": "A unique within dataset string identifier for the site. Valid values include strings that are used specifically for this survey or URIs from BDR Sites that have been established in previous surveys.",
"example": "P1",
"type": "string",
"format": "default",
"constraints": {
"required": true,
"unique": true
}
},
{
"name": "siteIDSource",
"title": "Site ID Source",
"description": "The organisation that assigned the SiteID to this Site",
"example": "TERN",
"type": "string",
"format": "default",
"constraints": {
"required": false
}
},
{
"name": "siteVisitID",
"title": "Site Visit ID",
"description": "The unique key assigned to a visit. A visit is a time distinct assessment conducted within a survey at a designated site.",
"example": "CPXEI0000001",
"type": "string",
"format": "default",
"constraints": {
"required": true,
"unique": true
}
},
{
"name": "siteVisitStart",
"title": "Site Visit Start",
"description": "The temporal start of when the Site was being used to collect data for the survey. Expected values include date, dateTime, dateTimeStamp.",
"example": "2016-02-28",
"type": "timestamp",
"format": "default",
"constraints": {
"required": true
}
},
{
"name": "siteVisitEnd",
"title": "Site Visit End",
"description": "The temporal end of when the Site was being used to collect data for the survey. Expected values include date, dateTime, dateTimeStamp.",
"example": "2016-02-28",
"type": "timestamp",
"format": "default",
"constraints": {
"required": false
}
},
{
"name": "visitOrgs",
"title": "Visit Orgs",
"description": "The names of the organisations responsible for recording the original Occurrence.",
"example": "NSW Dept of Planning, Industry and Environment.",
"type": "list",
"format": "default",
"constraints": {
"required": false
}
},
{
"name": "visitObservers",
"title": "Visit Observers",
"description": "A list (concatenated and separated using |) of names of people, groups, or organisations responsible for recording the original Occurrence.",
"example": "Oliver P. Pearson | Anita K. Pearson",
"type": "list",
"format": "default",
"constraints": {
"required": false
}
},
{
"name": "condition",
"title": "Condition",
"description": "The state of a patch of vegetation at the time of sampling relative to some specified standard or benchmark (where available).",
"example": "Burnt",
"type": "string",
"format": "default",
"constraints": {
"required": false
}
},
{
"name": "targetTaxonomicScope",
"title": "Target Taxonomic Scope",
"description": "The taxonomic group targeted for sampling during the Site Visit",
"example": "Coleoptera",
"type": "string",
"format": "default",
"constraints": {
"required": false
}
},
{
"_comment": "can we do a flexible vocabulary while I do the recon to establish the concepts?",
"name": "protocolName",
"title": "Protocol Name",
"description": "Categorical descriptive name for the method used during the Site Visit.",
"example": "harpTrapping",
"type": "string",
"format": "default",
"constraints": {
"required": false
},
"vocabularies": [
"VISIT_PROTOCOL_NAME"
]
},
{
"name": "protocolDescription",
"title": "Protocol Description",
"description": "A detailed description of the method used during the Site Visit. The description may include deviations from a protocol referred to in eco:protocolReferences. Recommended good practice is to provide information about instruments used, calibration, etc.",
"example": "Three conventional harp traps (3.2m ht x 2.2m w) were established in flight path zones for a period of 4 hrs at dawn and dusk for a total of 10 trap nights. Traps were visited on an hourly basis during each deployment period and the trap catch recorded for species, size, weight, sex, age and maternal status.",
"type": "string",
"format": "default",
"constraints": {
"required": false
}
},
{
"name": "samplingEffortValue",
"title": "Sample Effort",
"description": "Similar to eco:samplingEffortValue. The total sampling effort value. A samplingEffortValue must have a corresponding samplingEffortUnit",
"example": "20 x 12",
"type": "string",
"format": "default",
"constraints": {
"required": false
}
},
{
"name": "samplingEffortUnit",
"title": "Sampling Effort Units",
"description": "Similar to eco:samplingEffortUnit. The units associated with samplingEffortValue.",
"example": "trapDays",
"type": "string",
"format": "default",
"constraints": {
"required": false
},
"vocabularies": [
"SAMPLING_EFFORT_UNIT"
]
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
surveyID,siteID,siteIDSource,siteVisitID,siteVisitStart,siteVisitEnd,visitOrgs,visitObservers,condition,targetTaxonomicScope,protocolName,protocolDescription,samplingEffortValue,samplingEffortUnit
Loading

0 comments on commit 0cd8031

Please sign in to comment.