Skip to content

Commit

Permalink
Merge pull request #115 from Ingenjorsarbete-For-Klimatet/feature/smh…
Browse files Browse the repository at this point in the history
…i-class-to-match-0.2.0

Feature/smhi class to match 0.2.0
  • Loading branch information
mgcth authored May 22, 2024
2 parents 11c94bb + f0a5485 commit 3b7dc36
Show file tree
Hide file tree
Showing 16 changed files with 660 additions and 368 deletions.
7 changes: 7 additions & 0 deletions docs/assets/kiruna_snodjup.html

Large diffs are not rendered by default.

9 changes: 8 additions & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,14 @@ Currently, only these four APIs are supported

## Examples

You can reach example usage of the different clients
Examples of direct usage of the different clients, and the experimental parent class,
are available here:

- [example of Metobs use](/ifk-smhi/metobs-example/)
- [example of Mesan use](/ifk-smhi/mesan-example/)
- [example of Metfcts use](/ifk-smhi/metfcts-example/)
- [example of Strang use](/ifk-smhi/strang-example/)
- [example of SMHI use](/ifk-smhi/smhi-example/)

## Install

Expand All @@ -40,6 +45,8 @@ pip install git+/~https://github.com/Ingenjorsarbete-For-Klimatet/ifk-smhi.git@mai
The SMHI client is in an experimental state.
As of now, it only controls the Metobs sub-client.
It will be expanded in future versions.
See [example of SMHI use](/ifk-smhi/smhi-example/)
for details on how to use the client.

## Metobs client

Expand Down
123 changes: 123 additions & 0 deletions docs/smhi-example.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# Example of SMHI direct use

Direct usage of `SMHI`.

## Basic use

The `SMHI` client is in an experimental state and currently only deals with `Metobs`
data. It is intended as a parent class for easy traversing of SMHI observational
data from GPS or city names directly.

The most basic usage of the client is to simply ask for data for a given station
and a given parameter:

```python
from smhi.smhi import SMHI

client = SMHI()

client.parameters.data #List all available parameters
#Parameter 1 is hourly air temperature

stations = client.get_stations(1)
stations.data #List all available stations for parameter 1

data = client.get_data(1, 72630) #Get data from specific station
#Station 72630 is Gothenburg
```

The `data` variable holds four dataframes when a single station
is used to fetch data as above.
They are called `station`, `parameter`, `period` and `df`, where the latter holds
the actual observational data. See further
[example of Metobs use](/ifk-smhi/metobs-example/).

## Interpolation

When there are several stations close to a measurement location and historical data
records are incomplete, it is convenient to use nearby stations to fill in the missing
data: This naive interpolation feature is included in the package by the parameter
`radius`. Thus, if we want to fetch historical data on the snow coverage in Kiruna,
the call is:

```python
from smhi.smhi import SMHI

client = SMHI()

#Parameter 8 is depth of snow coverage
data = client.get_data(8, 180960, 40) #Get data from specific station
#Station 180960 is Kiruna. 40 indicates we will use stations within
#a 40km radius to complement any data losses.

data2 = client.get_data(8, 180960) #Get comparison data without the
#interpolation.
```

Visualise the data:

<details>
<summary>Scatter plot code</summary>

```python
import plotly.graph_objects as go

d1 = data.df
d2 = data2.df

index = d1.index.intersection(d2.index)
d2_dropped = d2.drop(index, axis=0)

fig = go.Figure()
fig.add_trace(
go.Scattergl(
x=d1.index,
y=d1["Snödjup"],
mode="markers",
name="Kiruna station"
)
)
fig.add_trace(
go.Scattergl(
x=d2_dropped.index,
y=d2_dropped["Snödjup"],
mode="markers",
name="Interpolerat, radie 40 km"
)
)
fig.update_layout(
title='Historiskt snödjup i Kiruna',
xaxis_title="År",
yaxis_title="Snödjup [m]",
legend={"orientation": "h"},
margin={"l": 0, "r": 0, "b": 80, "t": 100}
)

fig.show()
```

</details>

<iframe id="igraph"
alt="Historiskt snödjup i Kiruna."
scrolling="no" style="border:none;" seamless="seamless"
src="/ifk-smhi/assets/kiruna_snodjup.html" height="525" width="100%">
</iframe>

## Finding data from a city

There are a lot of stations available: Frequently, we are simply interested
in meterological observations from a specific city. Using the library `geopy`,
this is included in the package too:

```python
from smhi.smhi import SMHI

client = SMHI()

#Parameter 8 is depth of snow coverage
data = client.get_data_by_city(8, "Kiruna", 40) #Get data from a station
#close to the city centre of Kiruna, and fill any empty holes with data
#from stations within a 40km perimeter

```
3 changes: 3 additions & 0 deletions docs/smhi-reference.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# SMHI reference

::: smhi.smhi.SMHI
2 changes: 2 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ nav:
- "Metfcts": metfcts-example.md
- "Mesan": mesan-example.md
- "Strang": strang-example.md
- "SMHI": smhi-example.md
- Reference:
- "Clients":
- "Metobs reference": metobs-reference.md
- "Metfcts reference": metfcts-reference.md
- "Mesan reference": mesan-reference.md
- "Strang reference": strang-reference.md
- "SMHI reference": smhi-reference.md
- "Models":
- "Metobs model": metobs-model.md
- "Metfcts model": metfcts-model.md
Expand Down
12 changes: 6 additions & 6 deletions src/smhi/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ def get_now() -> datetime:
return arrow.utcnow().datetime # .isoformat("T", "seconds") + "Z"


METOBS_AVAILABLE_PERIODS = [
"latest-hour",
"latest-day",
"latest-months",
"corrected-archive",
]
METOBS_AVAILABLE_PERIODS = {
"corrected-archive": 0,
"latest-months": 1,
"latest-day": 2,
"latest-hour": 3,
}

METFCTS_URL = (
"https://opendata-download-metfcst.smhi.se/"
Expand Down
12 changes: 8 additions & 4 deletions src/smhi/metobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -298,15 +298,15 @@ def __init__(
class Data(BaseMetobs):
"""Get data from period for version 1 of Metobs API."""

_metobs_available_periods: Dict[str, str] = METOBS_AVAILABLE_PERIODS
_metobs_available_periods: Dict[str, int] = METOBS_AVAILABLE_PERIODS
_metobs_parameter_tim: List[str] = ["Datum", "Tid (UTC)"]
_metobs_parameter_dygn: List[str] = ["Representativt dygn"]
_metobs_parameter_manad: List[str] = ["Representativ månad"]

def __init__(
self,
periods_in_station: Periods,
period: str = "corrected-archive",
period: Optional[str] = None,
data_type: str = "json",
) -> None:
"""Get data from period.
Expand All @@ -326,6 +326,10 @@ def __init__(
if data_type != "json":
raise TypeError("Only json supported.")

if period is None:
period = periods_in_station.data[0]
logger.info(f"No period selected, selecting: {period}.")

if self._check_available_periods(periods_in_station.data, period):
logger.info(
"Found only one period to download. "
Expand All @@ -335,8 +339,8 @@ def __init__(

if period not in self._metobs_available_periods:
raise NotImplementedError(
"Select a supported periods: }"
+ ", ".join([p for p in self._metobs_available_periods])
"Select a supported period: "
+ ", ".join([p for p in self._metobs_available_periods.keys()])
)

self.periods_in_station = periods_in_station
Expand Down
3 changes: 2 additions & 1 deletion src/smhi/models/metobs_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import pandas as pd
from pydantic import BaseModel, ConfigDict, Field, field_validator
from smhi.constants import METOBS_AVAILABLE_PERIODS


class MetobsLink(BaseModel):
Expand Down Expand Up @@ -183,7 +184,7 @@ class MetobsStationModel(MetobsBaseModel):
@field_validator("period")
@classmethod
def serialise_period_in_order(cls, period: List[MetobsLinks]):
return sorted(period, key=lambda x: x.key)
return sorted(period, key=lambda x: METOBS_AVAILABLE_PERIODS[x.key])

@property
def data(self) -> Tuple[Optional[str], ...]:
Expand Down
Loading

0 comments on commit 3b7dc36

Please sign in to comment.