Skip to content

Commit

Permalink
Merge pull request #286 from tdwg/term-updates
Browse files Browse the repository at this point in the history
Updates before splitting the observation table
  • Loading branch information
peterdesmet authored Feb 13, 2023
2 parents 9839b4f + c3ed7f7 commit 7561232
Show file tree
Hide file tree
Showing 28 changed files with 1,534 additions and 855 deletions.
14 changes: 12 additions & 2 deletions _config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,16 @@ exclude:
- Gemfile
- Gemfile.lock
- LICENSE
- example
- tests
- example/*
- tests/*
- "*.json"

# FRONTMATTER DEFAULTS
defaults:
- scope:
path: pages/example
values:
permalink: "/example/:basename/"
layout: example
title: Example dataset
toc: true
1 change: 1 addition & 0 deletions _data/deployments.csv
1 change: 1 addition & 0 deletions _data/media-observations.csv
1 change: 1 addition & 0 deletions _data/media.csv
10 changes: 10 additions & 0 deletions _data/navigation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,15 @@
href: /metadata/
- text: Data
href: /data/
- text: Example dataset
menu:
- text: Deployment 1
href: /example/00a2c20d-f038-490c-9b3f-7e32abfa0be7/
- text: Deployment 2
href: /example/29b7d356-4bb4-4ec4-b792-2af5cc32efa8/
- text: Deployment 3
href: /example/577b543a-2cf1-4b23-b6d2-cda7e2eac372/
- text: Deployment 4
href: /example/62c200a9-0e03-4495-bcd8-032944f6f5a1/
- text: GitHub
href: https://github.com/tdwg/camtrap-dp
1 change: 1 addition & 0 deletions _data/observations.csv
136 changes: 136 additions & 0 deletions _layouts/example.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
---
layout: default
---

{{ content }}

<p class="small">Source: <a href="{{ site.github.repository_url }}/blob/main/example"><code>example dataset</code></a></p>

{% assign dep_id = page.name | remove: '.md' %}
{% assign dep = site.data.deployments | where: 'deploymentID', dep_id | first %}
{% assign media = site.data.media | where: 'deploymentID', dep_id %}
{% assign media_observations = site.data.media-observations %}
{% assign event_observations = site.data.observations %}

<h2 id="{{ dep_id }}">Deployment information</h2>

<dl>
<dt>Location</dt>
<dd>
<code>{{ dep.locationName }}</code>
(<a href="https://www.google.com/maps/search/?api=1&query={{ dep.latitude }},{{ dep.longitude }}&zoom=12"><code>{{ dep.latitude }}, {{ dep.longitude }}</code></a>),
uncertainty: <code>{{ dep.coordinateUncertainty }}</code>m
<dd>
<dt>Duration</dt>
<dd>
<code>{{ dep.start }}</code> / <code>{{ dep.end }}</code>
</dd>
<dt>Camera setup</dt>
<dd>
interval: <code>{{ dep.cameraInterval }}</code>,
height: <code>{{ dep.cameraHeight }}</code>,
tilt: <code>{{ dep.cameraTilt }}</code>,
heading: <code>{{ dep.cameraHeading }}</code>
</dd>
<dt>Bait</dt>
<dd>
<code>{{ dep.baitUse }}</code>
</dd>
</dl>

{% assign event_ids = media | map: 'eventID' | uniq %}
{% for event_id in event_ids %}
{% assign event_media = media | where: 'eventID', event_id %}
{% assign event_media_count = event_media | size %}
<h2 id="{{ event_id }}">Event: {{ event_id }}</h2>

<div id="carousel-{{ event_id }}" class="carousel slide carousel-fade" data-bs-ride="carousel" data-bs-keyboard="false" data-bs-interval="500">
<div class="carousel-inner">
{% for med in event_media %}
<div class="carousel-item{% if forloop.first %} active{% endif %}">
<img class="d-block w-100" src="{{ med.filePath }}" alt="{{ med.timestamp }}">
<div class="carousel-caption d-none d-md-block">
<p class="fs-1">{{ forloop.index }}</p>
</div>
</div>
{% endfor %}
</div>
<button class="carousel-control-prev" type="button" data-bs-target="#carousel-{{ event_id }}" data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="visually-hidden">Previous</span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#carousel-{{ event_id }}" data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="visually-hidden">Next</span>
</button>
</div>

<table class="table table-sm mt-4">
<colgroup>
<col width="6%">
<col width="47%">
<col width="47%">
</colgroup>
<thead>
<tr>
<th>File</th>
<th>Media observations</th>
<th>Event observations</th>
</tr>
</thead>
<tbody>
{% for med in event_media %}
{% assign med_id = med.mediaID %}
<tr>
<td>
{{ forloop.index }}
</td>
<td title="mediaID: {{ med_id }}">
{% assign media_obs = media_observations | where: 'mediaID', med_id %}
{% for obs in media_obs %}
<code>{{ obs.observationType }}</code>
{% if obs.observationType == 'animal' %}
<span class="badge rounded-pill bg-secondary">{{ obs.count }}</span>
<em>{{ obs.scientificName }}</em>
{% if obs.lifeStage and obs.sex %}
({{ obs.lifeStage }}, {{ obs.sex }})
{% elsif obs.lifeStage %}
({{ obs.lifeStage }})
{% elsif obs.sex %}
({{ obs.sex }})
{% endif %}
{% endif %}
{% if obs.classificationMethod == 'machine' %}
<span class="text-muted small">Classified by machine</span>
{% endif %}
<br>
{% endfor %}
</td>
{% if forloop.first %}
<td title="eventID: {{ event_id }}" rowspan="{{ event_media_count }}">
{% assign event_obs = event_observations | where: 'eventID', event_id %}
{% for obs in event_obs %}
<code>{{ obs.observationType }}</code>
{% if obs.observationType == 'animal' %}
<span class="badge rounded-pill bg-secondary">{{ obs.count }}</span>
<em>{{ obs.scientificName }}</em>
{% if obs.lifeStage and obs.sex %}
({{ obs.lifeStage }}, {{ obs.sex }})
{% elsif obs.lifeStage %}
({{ obs.lifeStage }})
{% elsif obs.sex %}
({{ obs.sex }})
{% endif %}
{% endif %}
{% if obs.classificationMethod == 'machine' %}
<span class="text-muted small">Classified by machine</span>
{% endif %}
<br>
{% endfor %}
</td>
{% endif %}
</tr>
{% endfor %}
</tbody>
</table>
{% endfor %}
13 changes: 8 additions & 5 deletions _layouts/profile.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
{% assign properties1 = site.data[profile_file].allOf[1].properties %}
{% assign required1 = site.data[profile_file].allOf[1].required %}

<p class="small">Source: <a href="https://github.com/{{ site.github_username }}/blob/main/{{ profile_file }}.json"><code>{{ profile_file }}.json</code></a></p>
<p class="small">Source: <a href="{{ site.github.repository_url }}/blob/main/{{ profile_file }}.json"><code>{{ profile_file }}.json</code></a></p>

{% for p1_raw in properties1 %}
{% assign p1_name = p1_raw[0] %}
Expand All @@ -25,9 +25,9 @@ <h2 id="{{ p1_id }}">
{% if p1['skos:exactMatch'] %}
<p class="small text-muted">Same as <a href="{{ p1['skos:exactMatch'] }}">{{ p1['skos:exactMatch'] }}</a></p>
{% elsif p1['skos:narrowMatch'] %}
<p class="small text-muted">Narrower than <a href="{{ p1['skos:narrowMatch'] }}">{{ p1['skos:narrowMatch'] }}</a></p>
<p class="small text-muted">Broader than <a href="{{ p1['skos:narrowMatch'] }}">{{ p1['skos:narrowMatch'] }}</a></p>
{% elsif p1['skos:broadMatch'] %}
<p class="small text-muted">Broader than <a href="{{ p1['skos:broadMatch'] }}">{{ p1['skos:broadMatch'] }}</a></p>
<p class="small text-muted">Narrower than <a href="{{ p1['skos:broadMatch'] }}">{{ p1['skos:broadMatch'] }}</a></p>
{% endif %}

{% if p1.properties %}
Expand All @@ -36,6 +36,9 @@ <h2 id="{{ p1_id }}">
{% elsif p1.items.properties %}
{% assign properties2 = p1.items.properties %}
{% assign required2 = p1.items.required %}
{% elsif p1.items.oneOf[0].properties %}
{% assign properties2 = p1.items.oneOf[0].properties %}
{% assign required2 = p1.items.oneOf[0].required %}
{% else %}
{% assign properties2 = false %}
{% endif %}
Expand Down Expand Up @@ -83,9 +86,9 @@ <h2 id="{{ p1_id }}">
{% if p2['skos:exactMatch'] %}
<span class="small text-muted">Same as <a href="{{ p2['skos:exactMatch'] }}">{{ p2['skos:exactMatch'] }}</a></span>
{% elsif p2['skos:narrowMatch'] %}
<span class="small text-muted">Narrower than <a href="{{ p2['skos:narrowMatch'] }}">{{ p2['skos:narrowMatch'] }}</a></span>
<span class="small text-muted">Broader than <a href="{{ p2['skos:narrowMatch'] }}">{{ p2['skos:narrowMatch'] }}</a></span>
{% elsif p2['skos:broadMatch'] %}
<span class="small text-muted">Broader than <a href="{{ p2['skos:broadMatch'] }}">{{ p2['skos:broadMatch'] }}</a></span>
<span class="small text-muted">Narrower than <a href="{{ p2['skos:broadMatch'] }}">{{ p2['skos:broadMatch'] }}</a></span>
{% endif %}
</td>
<td>{{ p2.type }}</td>
Expand Down
6 changes: 3 additions & 3 deletions _layouts/tables.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

<h2 id="{{ table_schema_id }}">{{ table_schema.title }}</h2>

<p class="small">Source: <a href="https://github.com/{{ site.github_username }}/blob/main/{{ table_schema_file }}.json"><code>{{ table_schema_file }}.json</code></a></p>
<p class="small">Source: <a href="{{ site.github.repository_url }}/blob/main/{{ table_schema_file }}.json"><code>{{ table_schema_file }}.json</code></a></p>

{{ table_schema.description | markdownify }}

Expand Down Expand Up @@ -52,9 +52,9 @@ <h2 id="{{ table_schema_id }}">{{ table_schema.title }}</h2>
{% if field['skos:exactMatch'] %}
<span class="small text-muted">Same as <a href="{{ field['skos:exactMatch'] }}">{{ field['skos:exactMatch'] }}</a></span>
{% elsif field['skos:narrowMatch'] %}
<span class="small text-muted">Narrower than <a href="{{ field['skos:narrowMatch'] }}">{{ field['skos:narrowMatch'] }}</a></span>
<span class="small text-muted">Broader than <a href="{{ field['skos:narrowMatch'] }}">{{ field['skos:narrowMatch'] }}</a></span>
{% elsif field['skos:broadMatch'] %}
<span class="small text-muted">Broader than <a href="{{ field['skos:broadMatch'] }}">{{ field['skos:broadMatch'] }}</a></span>
<span class="small text-muted">Narrower than <a href="{{ field['skos:broadMatch'] }}">{{ field['skos:broadMatch'] }}</a></span>
{% endif %}
</td>
<td>{{ field.type }}</td>
Expand Down
94 changes: 66 additions & 28 deletions camtrap-dp-profile.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,41 +26,64 @@
"resources": {
"description": "See [Data Package specification](https://specs.frictionlessdata.io/data-package/#resource-information). Camtrap DP further requires each object to be a [Tabular Data Resource](https://specs.frictionlessdata.io/tabular-data-resource/) with a specific `name` and `schema`. See [Data](../data) for the requirements for those resources.",
"minItems": 3,
"maxItems": 3,
"items": {
"required": [
"schema",
"profile"
],
"properties": {
"name": {
"description": "Identifier of the resource.",
"enum": [
"deployments",
"media",
"observations"
]
},
"profile": {
"const": "tabular-data-resource"
},
"schema": {
"description": "URL of the used Camtrap DP Table Schema version (e.g. `https://raw.githubusercontent.com/tdwg/camtrap-dp/1.0/deployments-table-schema.json`).",
"$ref": "#$defs/version",
"oneOf": [
{
"required": [
"name"
"name",
"path",
"profile",
"schema"
],
"properties": {
"name": {
"description": "Identifier of the resource.",
"enum": [
"deployments",
"media",
"observations"
]
},
"path": {
"description": "Path or URL to the data file."
},
"profile": {
"description": "[Profile](https://specs.frictionlessdata.io/profiles/) of the resource.",
"enum": [
"tabular-data-resource"
]
},
"schema": {
"description": "URL of the used Camtrap DP Table Schema version (e.g. `https://raw.githubusercontent.com/tdwg/camtrap-dp/1.0/deployments-table-schema.json`).",
"allOf": [
{
"$ref": "#$defs/version"
},
{
"type": "string",
"format": "uri"
}
]
}
}
},
{
"required": [
"name"
],
"properties": {
"name": {
"not": {
"enum": [
"deployments",
"media",
"observations"
]
}
}
}
}
}
]
}
},
"profile": {
Expand All @@ -80,7 +103,21 @@
"description": "See [Data Package specification](https://specs.frictionlessdata.io/data-package/#title). Not to be confused with the title of the project that originated the package (`package.project.title`)."
},
"contributors": {
"description": "See [Data Package specification](https://specs.frictionlessdata.io/data-package/#contributors). Camtrap DP makes this a required property. Can include people and organizations."
"description": "See [Data Package specification](https://specs.frictionlessdata.io/data-package/#contributors). Camtrap DP makes this a required property and restricts `role` values. Can include people and organizations.",
"items": {
"properties": {
"role": {
"description": "Role of the contributor. Defaults to `contributor`.",
"enum": [
"contact",
"principalInvestigator",
"rightsHolder",
"publisher",
"contributor"
]
}
}
}
},
"description": {
"description": "See [Data Package specification](https://specs.frictionlessdata.io/data-package/#description). Not to be confused with the description of the project that originated the package (`package.project.description`)."
Expand Down Expand Up @@ -167,11 +204,12 @@
},
"samplingDesign": {
"description": "Type of a sampling design/layout. The values are based on Wearn & Glover-Kapfer (2017, <https://doi.org/10.13140/RG.2.2.23409.17767>), pages 80-82: `simple random`: random distribution of sampling locations; `systematic random`: random distribution of sampling locations, but arranged in a regular pattern; `clustered random`: random distribution of sampling locations, but clustered in arrays; `experimental`: non-random distribution aimed to study an effect, including the before-after control-impact (BACI) design; `targeted`: non-random distribution optimized for capturing specific target species (often using various bait types); `opportunistic`: opportunistic camera trapping (usually with a small number of cameras).",
"skos:broadMatch": "http://rs.tdwg.org/hc/terms/inventoryTypes",
"type": "string",
"enum": [
"simple random",
"systematic random",
"clustered random",
"simpleRandom",
"systematicRandom",
"clusteredRandom",
"experimental",
"targeted",
"opportunistic"
Expand All @@ -183,8 +221,8 @@
"items": {
"type": "string",
"enum": [
"motion detection",
"time lapse"
"motionDetection",
"timeLapse"
]
},
"uniqueItems": true,
Expand Down
Loading

0 comments on commit 7561232

Please sign in to comment.