Python scripts samenmeten-rivm-tools

In gemeente Heusden is er ook een samenmeten project en ik wilde weten in hoeverre de fijnstof uitstoot van PM10 en PM2.5 voldoet aan de WHO (World Health Organization) of EU richtlijnen en/of hoever we daarvan af zitten. Ik kon bij de RIVM wel historische data vinden, maar geen actuele informatie. Daarnaast wilde ik gebruik maken van gekalibreerde uurwaardes om zo te berekenen of een meetstation of een groep van meetstations op (lopende) jaarbasis wel of niet aan de richtlijnen voldoen. Daarom heb ik deze python scripts gemaakt en deze beschikbaar gesteld, zodat die door andere ook gebruikt kunnen worden. En eventuele verbeteringen aangebracht kunnen worden.

Er zijn 3 python scripts:

  • gemeente_station_namen.py: hiermee kun je meetstation namen van een gemeente achterhalen
  • station_data_naar_csv.py: hiermee kun je de uurwaardes van een meeststation of een groep van meetstations ophalen en toevoegen aan reeds beschikbare .csv bestanden
  • samenvatting.py: genereert een samenvatting van de jaar waardes (en optioneel maand, week, dag) van een meetstation of groep van meetstations en schrijft deze ook naar een kml bestand, zodat je die in Google My Maps kunt importeren.

Voorbeeld van de resultaten van fijnstof over 2022 van gemeente Heusden kun je hier vinden op Google My Maps.

Meer informatie en de python scripts op github hier.

Opmerkingen welkom.

1 like

Handige scripts. Data vam rivm meetstations is te vinden op Luchtmeetnet dataset. De data van het actuele jaar wordt achteraf gecorriggeerd (2022 was in mei 2023 beschikaar).

1 like

Ik zie dat heel vaak er géén gekalibreerde PM2.5 data is voor de data voor bijna alle meetstations, terwijl dit er wel is voor de PM10. Hoe komt het dat heel vaak deze informatie per uur er niet is? Nu val ik terug op de ongekalibreerde PM2.5 waarde. Kan ik ook met behulp van luchtvochtigheid en temperatuur een betere zelf berekende gekalibreerde waarde berekenen?

Niet op alle stations wordt zowel PM2.5, PM10 gemeten. Het is wel vreemd als er wel ruwe PM2.5 data te vinden is maar geen gekalibreerde waarde. In dit document Ervaringen RIVM SDS011 sensor 12-7-2018 | Samen meten aan luchtkwaliteit staat een beschrijving van de correctie voor luchtvochtigheid. Zonder referentiemetingen wordt het wel lastig om de juiste factoren te vinden.

1 like

Dank je wel, die kende ik nog niet (lees nu alles via de API in. Enerzijds makkelijk, maar wel een gedoe met rate limitingvan de API).

Mooi dat het er is! Wat ik wel een verbeterpunt vindt, is dat de datum-tijdnotatie zo onduidelijk is. Het is even zoeken om ergens in de pdfjes te vinden dat het om wintertijd gaat (UTC+1). Staat niet in de .csv bestanden zelf.

Het probleem dat de RIVM API vaak tijdseries oplevert met gaten er in is goed bekend. LV2 (Leidschendam-Voorburg) heeft een procedure waarbij ze een drietal verschillende gegevens gebruikt:

  1. de ongekalibreerde data verkregen van de rivm api
  2. de gekalibreerde data verkregen van de RIVM API
    —> deze twee geven een kalibratiefunctie ; gekalibreerde data delen door de ongekalibreerde data en dan interpoleren
    en 3. ongekalibreerde data verkregen van een storage die verbonden is met samenmeten.rivm.nl versie 1.5 (dus een oude versie). De data in die store hebben niet veel gaten. Daarvoor heeft LV2 een aparte executable, gebouwd (alweer jaren geleden) door Diederik van Hemert. Handleiding - summier:
    Handleiding_getrivm_oud.docx (21,7 KB)

Toepassen van de kalibratiefunctie op deze laatste ongekalibreerde data levert de
gekalibreerde functie op.
Details staan in het laatste stukje van het LV2 voortgangsrapport van 31 januari 2023, en in de bijdrage aan de Amersfoortse Koppelting meeting van januari 2023 (in de powerpoint omstreeks slide 19 als ik het goed heb. Beide documenten vind je op dit forum.

Natuurlijk zijn er procedures om deze routines heengebouwd - maar dat zal Heusden ook wel hebben gedaan.

Succes

1 like

Voor zover ik kan zien zijn er over 2023 geen gekalibreerde waarden, dus kan ook niets compenseren. Verder zie ik in deze periode minder dan 4% a 5% ontbrekende waarden

Dat je de calibratiefunctie kan herleiden door simpel te delen vind ik onwaarschijnlijk. Er komen best wel wat negatieve waarden voor, dus er moet ook nog een soort van “offset” bij, en wellicht ook andere invloeden als temperatuur, luchtvochtigheid en wat er meer aan de hand kan zijn.

Hallo Henk,
Waarschijnlijk hebben we het over verschillende processen. Mijn benadering gaat over het krijgen van zo goed mogelijk gekalibreerde waarden voor metingen met onze eigen meetkastjes. Deze waarden willen wij zsm hebben - niet later dan een paar weken na de meting. Op samenmeten.rivm.nl kun je twee verschillende resultaten zien - de gekalibreerde metingen en de ongekalibreerde metingen van onze meetkastjes. Als je deze uitleest met de door RIVM ter beschikking gestelde API (die ik maar RIVM API noem) dan zie je dat er met name bij de gekalibreerde PM2,5 reeks heel wat metingen missen. De plaatjes op samenmeten.rivm.nl laten deze gaten in de data niet (of nauwelijks) zien.
Er is dus zaak van twee verschillende datastores. Bij navraag bij RIVM (bij één van de samenmeten meetings) bleek dat de berekening van gekalibreerde metingen tijd kost (een proces van vergelijken van metingen van officiële meetstations met meetkastjes metingen in de nabijheid). Als de resultaten van deze berekeningen niet op tijd ter beschikking zijn wordt de datastore met de RIVM API niet gevuld - dus je krijgt NaN waarden. Heel vervelend als je, zoals ik in mijn verslag bij Koppelting/WAR in Amersfoort wilde laten zien, resultaten van de vuurwerkpiek wil laten zien. Veel waarden waren verdwenen, terwijl de hoeveelheid fijnstof natuurlijk flink omhoog en omlaag spoot.
De uitweg die ik had is dat ik via het programmatje van Diederik van Hemert toegang had tot de datastore die de ongekalibreerde plaatjes genereert (via direct uitlezen van samnmeten.rivm.nl.versie 1.5. In die data hoeveelheid zitten nauwelijks gaten. Om nu gekalibreerde data te verkrijgen moet ik eerst eerst aannemen dat de kalibratiefunctie langzaam varieert - dus dat het quotient van gekalibreerd / ongekalibreerd niet per uur verandert. Die kan ik afschatten van de gegevens met de RIVM API - een langzaam variërende functie laat zich goed interpoleren. Om een continue gekalibreerde functie te krijgen gebruik ik dus de geïnterpoleerde quotiënt (langzaam variërend) en de continue snel variërende functie die ik via samenmeten.rivm.nl.1.5 heb binnengekregen. Wat betreft de natuurkunde: de geïnterpoleerde quotiënt bevat de weersinvloeden - dat is het hele punt van de tijdsafhankelijke correctie die RIVM uitrekent - de quotient van wat de goedkope meetapparaatjes leveren in vergelijking met de luchtmeetnet stations.
Voor de officiële meetnet stations - is een andere categorie. De kalibratie van luchtmeetnetstations gebeurt eens per dag, en bij die kalibratie kunnen negatieve getallen worden gegenereerd. Aan het eind van het jaar is er weer een kalibratie / QC ronde, waarbij overgebleven anomalieën worden uitgefilterd. Natuurlijk is luchtvochtigheid deel van die RIVM / Luchtmeetnet procedure, maar in het proces dat ik hierboven behandelde voor mijn eigen meetkastjes is het irrelevant.

Hopelijk is het nu wat duidelijker.

Frans

Dank je wel voor je uitgebreide uitleg. Ik ben op dit moment vooral geïnteresseerd in de relatieve verschillen tussen sensoren van hetzelfde type, en niet zozeer de absolute waarden. Na wat meten en analyseren lijkt dat te werken (zie ook een ander topic op dit forum). De materie wordt al gauw ingewikkeld dus het is continue afwegen tussen accepteren wat je weet en kan weten, en verder zoeken.

De negatieve waarden van LML snap ik wiskundig wel, maar als natuurkundige heb ik er een beetje moeite mee. Een thermometer die minder dan nul graden Kelvin afgeeft zou ik ook met enig wantrouwen benaderen.

Is het een systematische fout in de waarde die de LML sensoren aangeven (dat lijkt er wel op, maar dat kost weer aardig wat analysewerk)? Je ziet overigens dat ik niet de enige ben. In de api documentatie staat dat je deze negatieve waarden moet gebruiken as-is, en niet zomaar op 0 moet zetten. In de kaart van de Hollandse Luchten worden deze waarden toch gewoon op 0 gezet.

Even een grappig voorbeeld: hieronder een detail van een plot van LML ongecalibreerde waarden (horizontaal) met een Hollandse Luchtensensor 545 (verticaal) die op dezelfde plek is gemonteerd. Ik kan me niet aan de indruk ontrekken dat het nulpunt van de LML ongeveer 2 a 2.5 ug/cm3 verschoven is. Met andere woorden de LML data geeft systematisch ~2 te laag aan (ik heb ook bij een andere analyse een hint gevonden dat het nulpunt van de ongecalibreerde data net iets verschoven is). De 545 begint overigens bij 1, en nooit 0. Is een studie op zich en ik heb daar verder te weinig gegevens (en ook tijd) voor.

Ik heb een nieuwe versie van samenmeten-rivm-tools gemaakt, waarbij ik de uurwaardes met geen gekalibreerde waarde gewoon oversla en bijhoudt hoeveel uurwaardes er meegenomen zijn, om het gemiddelde goed te kunnen bepalen.

Aangezien ik geïnteresseerd ben in het feit dat in de wintermaanden en bepaalde uren er mogelijk meer last van houtstook is, heb ik filteropties toegevoegd: [j2000-3000] [m1-12] [u0-23]

Gebruik  : python samenvatting.py STATION_LIJST.txt
Voorbeeld: python samenvatting.py _heusden.txt
Opties   : [uur] [dag] [week] [maand] [j2000-3000] [m1-12] [u0-23]

Opm.1: Wilt u meer details zien, gebruik parameter uur/dag/week/maand
Opm.2: Wilt u alleen bepaalde jaren mee te nemen,
       kunt u filteren met optie [j2000-3000]:
       bijvoorbeeld alleen jaren 2021 tot en met 2022: j2021-2022
Opm.3: Wilt u alleen bepaalde maanden mee te nemen,
       kunt u filteren met optie [m1-12]:
       bijvoorbeeld alleen de maanden november tot en met maart: m11-3
Opm.4: Wilt u alleen bepaalde uren mee te nemen,
       kunt u filteren met optie [u0-23]:
       bijvoorbeeld alleen de uren van 18:00 tot en met 02:00: u18-2
Opm.5: station namen van een gemeente kan opgevraagd worden met tool:
            python gemeente_station_namen.py gemeente_code
Opm.6: Voordat dit script gedraaid wordt, moeten de .csv bestanden voor
       deze STATION_LIJST.txt gegenereerd zijn met:
            python station_data_naar_csv.py STATION_LIJST.txt

Voor gemeente Heusden geeft dit hogere gemiddelde waardes voor de wintermaanden en avonduren.
Voorbeelden voor gemiddeldes…

python ..\samenvatting.py j2022-2022 _GemeenteHeusden.txt|egrep "Datum|Gemiddelde"
    Station,   Periode,      Datum,  Info, PM10, (Min,  Max, #WHO, #EU), PM2.5, (Min,  Max, #WHO), Commentaar
 Gemiddelde,      JAAR, 2022-01-01,  2022,   16,    0, 1000,   12,   12,    11,    0, 1000,   144, PM10  > WHO jaar 15; PM2.5 > WHO jaar 5

PM10 is gemiddeld 16 en PM2.5 is gemiddeld 11 voor jaar 2022

python ..\samenvatting.py j2022-2022 m11-3 _GemeenteHeusden.txt|egrep "Datum|Gemiddelde"
    Station,   Periode,      Datum,  Info, PM10, (Min,  Max, #WHO, #EU), PM2.5, (Min,  Max, #WHO), Commentaar
 Gemiddelde,      JAAR, 2022-01-01,  2022,   18,    0, 1000,   10,    8,    13,    0, 1000,    85, PM10  > WHO jaar 15; PM2.5 > WHO jaar 5

PM10 is gemiddeld 18 (2 hoger) en PM2.5 is gemiddeld 13 (2 hoger) voor jaar 2022 van november tot en met maart.

python ..\samenvatting.py j2022-2022 u18-3 _GemeenteHeusden.txt|egrep "Datum|Gemiddelde"
    Station,   Periode,      Datum,  Info, PM10, (Min,  Max, #WHO, #EU), PM2.5, (Min,  Max, #WHO), Commentaar
 Gemiddelde,      JAAR, 2022-01-01,  2022,   17,    0, 1000,   18,   13,    10,    0, 1000,   124, PM10  > WHO jaar 15; PM2.5 > WHO jaar 5

PM10 is gemiddeld 17 (1 hoger) en PM2.5 is gemiddeld 10 (1 lager) voor jaar 2022 van 18:00 tot en met 04:00 uur

python ..\samenvatting.py j2022-2022 m11-3 u18-3 _GemeenteHeusden.txt|egrep "Datum|Gemiddelde"
    Station,   Periode,      Datum,  Info, PM10, (Min,  Max, #WHO, #EU), PM2.5, (Min,  Max, #WHO), Commentaar
 Gemiddelde,      JAAR, 2022-01-01,  2022,   19,    0,  789,   16,   13,    13,    0,  789,    90, PM10  > WHO jaar 15; PM2.5 > WHO jaar 5

PM10 is gemiddeld 19 (3 hoger) en PM2.5 is gemiddeld 13 (2 hoger) voor jaar 2022 van november tot en met maart en 18:00 tot en met 03:00 uur

Ik heb mijn python scripts aangepast, zodat deze ook de gemiddelde over alle metingen toont en niet alleen per jaar. De samenvatting.py genereert ook een kml bestand, die je kunt inladen in mymaps van google.

Ik heb de meetsensoren die iets gemeten hebben in gemeente Heusden van 2021 tot en met 2023 op een gedeelde Google Maps kaart beschikbaar gemaakt. Die kan iedereen bekijken.

HeusdenFijnstof2022.

De meetsensoren zijn in gemeente Heusden allemaal rood (vuur symbool) weergegeven, omdat deze boven de jaarlijkse WHO waardes van PM2.5 zitten. In ongeveer het midden van de kaart, staat de gemiddelde van alle meetsensoren, een oranje huisje met een vlaggetje. Naam van het symbool bevat gemiddelde gekalibreerde PM10/PM2.5 uur-waardes van samenmeten-rivm en aantal gekalibreerde metingen in dagen. Je kunt op een sensor op het kaartje klikken om de detail informatie te laten zien (sensor naam, de verschillende jaren van metingen).

Er zitten 5 meetstations bij die maar maximaal 5 dagen meetgegevens gestuurd hebben.

Voor de kalibratie met LML stations in ons project gebruiken we alleen daggemiddelden, in Nijmegen staat op de Graafseweg een BAM1020 (beta attenuation monitor) dit is een near reference monitor, die gekalibreerd wordt met een gravimetrische referentie (bijv. Leckel) die alleen dagwaarden levert. Als je naar de BAM grafieken kijkt dan varieëren de pieken vaak veel meer dan bij de low-cost sensoren waarbij je je kan afvragen of het aannemelijk is dat de concentraties werkelijk zo abrupt veranderen. Kalibratie met (definitieve) daggemiddelden geeft met onze sensoren vrij goede resultaten.

We hebben met behulp van Python minutendata van ons meetnet (Ohnics | Fijnstofkaart) over de periode april 2021-december 2023 gecombineerd met data uit het 10-minuten meetnet van het KNMI (https://dataplatform.knmi.nl/) met als doel meer inzicht te krijgen in de meteo invloeden (met name windsnelheid/richting en temperatuur en relatieve luchtvochtigheid) op PM2.5 concentraties en het opzetten van een set Python functies voor de automatisering van de dataverwerking. In de eerste stap is voor 10 sensoren de mediaan per minuut bepaald, hiermee zijn 14 miljoen records ingedikt naar 1,4 miljoen records. Vervolgens is die data met meteodata verrijkt. Om de informatie te visualiseren is de dataset (arbitrair) opgesplitst in concentratie intervallen, 0-5 ug/m3 (cat.5), 5-10 ug/m3 (cat.10), …55-60 ug/m3(cat.60) en alles > 60 (cat.99). Voor deze sets zijn de gegevens in een scatterplot gezet met op de assen de meteo variabelen waarbij de puntgrootte in de grafiek bepaald wordt door aantal metingen. Vervolgens zijn de PNG grafieken omgezet naar GIF. We gaan de output ook gebruiken om data te selecteren waarbij we gaan inzoomen op onderlinge verschillen tussen de sensoren.
Wind
RHenT

1 like