Temperatursummen in der Imkerei

Flux Abfragemonster here…

jan = from(bucket: "dwd_cdc")
    |> range(start:2019-01-01T00:00:00Z, stop: 2019-01-31T23:59:59Z)

    [...]

Saustark! Sieht nach ordentlich bewältigter Flux Lernkurve aus.


P.S.: Bei Gelegenheit muss ich mir von Euch mal erklären lassen, was Ihr da tut.

1 Like

You’ve asked for it, darling. Ick geh den Query mal Schritt für Schritt durch (wer nicht Flux lernen will, sollte hier vmtl. mit dem Lesen abbrechen.)

jan = from(bucket: "dwd_cdc")

Wir nehmen uns mal die “dwd_cdc”-Datenbank, aaaber tun das Ergebniss dieses ja noch weiter spezifizierten Queries in eine Art Variable und nennen sie “jan”.

  |> range(start:2019-01-01T00:00:00Z, stop: 2019-01-31T23:59:59Z)

Joar, hier würde mensch sonst[tm] “$range” in die Klammern schreiben: Eine Variable, die Grafana anhand des aktuell gewählten Zeitfensters Flux-gerecht bereitstellt. Aber wir wollen ja mal nur den Januar betrachten. Unsere DB denkt in UTC, der DWD auch: Schick.

  |> filter(fn: (r) =>
      r._measurement == "dwd_cdc_temp_2m_c" and
      r._field == "value" and
      r.sta_name == "$COMMON_CDC_NAME" and
      r.quality_level == "2" and
      r.produkt == "10_minutes"
     )

Lasst uns unsere Datenbank filtern! “r” definieren wir als unsere response. “interne” Variablen beginnen mit nem Undersore; das ist für _measurement, _field und _value gegeben. Übrige/individuelle tags werden ohne
_ angegeben. Der Wert aus der Variable $CDC_COMMON_NAME stellt das Grafana über unser Station-Dropdown bereit (hier könnte auch nen Stationsname “hardcodet” stehen).

  |> aggregateWindow(every: 1d, fn: mean)

Ist ne Helper-Function, die eigentlich erstmal window() aufruft, und denn die einzelnen Series wieder group()t. Damit lassen sich auch verschiedene Messrhytmen “normalisieren” und vergleichen. In diesem Fall machen wir aus unseren “alle 10min-Daten” die gewünschten Tagesmittelwerte.

  |> keep(columns: ["_value", "_time"])

Lasst uns unnötiges Wegschmeißen.

  |> filter(fn: (r) => r._value > 0)

Ah, wir interessieren uns ja nur für Tagesmittelwerte über 0°C! Also filtern wir mal auf die. Das macht ja auch jetzt erst Sinn, weil wir vorher noch nicht auf Tagesmittelwerte aggregiert haben.

  |> map(fn: (r) => ({
    _time: r._time,
    _value: r._value * 0.5
    }))

Tja, dann müssen wa noch unseren Wert gewichten. Ist ja Januar, also mit 0.5. _time muss mit aufgerufen werden, damits überlebt.

Ok, dasselbe für

feb = from(bucket: "dwd_cdc")

und analog für

rest = from(bucket: "dwd_cdc")

Jetz dieses union():

union(tables: [jan, feb, rest])
  |> sort(columns: ["_time"], desc: false)

Sortierung ist wichtig, sonst kommt etwa der 1.-11. Februar zuerst in die Tabelle und dananch erst der 1.-31. Januar und das arme Grafana ist sehr verwirrt und malt plötzlich Kreise. (Srsly. Grafana supports time-travel!)

  |> map(fn: (r) => ({
    _time: r._time,
    _value: r._value,
    foo: "GTS Tag"
    }))

Boar, diese Beschriften von einzelnen Datenserien ist die Hölle mit Grafana & Flux. Hier fügen wir an jeden Messwert noch nen key-value-Päarchen, damit wir die Serie als “Tag”(eswert) wiedererkennen können.

  |> yield(name: "bars")

Weil wir hier grafisch Balken nehmen, heissts “bars” und es wird die Series an genau dieser Stelle per yield() “vermeldet”, also als separate result-Tabelle ausgeworfen und gemalt, ehe wir sie weiter modizifieren. Somit haben wir jetz erstmal alle gewichteten Tagesmittelwerte > 0°C im Bild.

  |> cumulativeSum(columns: ["_value"])

Wir wollen aber auch die kummulierte Summe aller Werte! (Bei single stats: Nur sum() )

  |> map(fn: (r) => ({
    _time: r._time,
    _value: r._value,
    foo: "GTS Total"
    }))

Also benennen wir unser lustiges Feld nochmal um und brauchen es nicht nochmal yield(en), weil wir jetzt ja am Ende sind und damit eh unsere/(die) eine Ergebnistabelle rendern.

3 Likes

Sorry for the buzz, aber wir können jetzt auch die Grünlandtemperatur-Berechnung mit der 10-Tage-Vorhersage weiterführen und dies auch auf die Kältesumme anwenden. Gibts nun in einem einzelnen Panel integriert im Referenz-Dashboard für die Grünlandtemperatursumme, funktioniert auch für Bremen (und auch für den Brocken, wenns etwas kälter sein darf):

(Standbild des dashboards)

:dancer: … ja, das sind dann auch nur im positiven je Zeitraum drei und für die Vorhersage je nochmal 3x2 = 6 Teilabfragen in einen Query (Kältesumme läuft separat). [Edit: Ein Glück müssen wa nun nicht mehr für die zwei Darstellungen (je Tag vs. akkumulierten Gesamtwert) noch einen Satz Queries fahren. :]

[Edit: Was die Populations-Abschätzung anbelangt muss ich leider feststellen, dass Flux zwar viel mehr tolles Neues kann, aber auch noch einige Grundlagen noch nicht. Zu diesen gehört leider leider auch noch das Rechnen mit Exponenten. :roll_eyes:]

3 Likes

english tl;dr
FLUX 0.12.0 (as deployed on swarm.hiveeyes) is not yet capable of functions like pow(), logx() or even sqrt(). Therefore to adopt the Bretschko (“Heuvel”) formula for oviposition rate, it should be substituted with a Taylor 3rd order polynome.


Aber wir haben *, /, - und + … was braucht es mehr! ;)

Um den Exponenten wegzubekommen, paßt ein Taylor-Polynom (hier ohne Restglied). Eine Polynom dritter Ordnung wurde gewählt, da die Annäherung als zunächst ausreichend angesehen wird. Dafür braucht es vier zuvor ausgerechnete Koeffizienten an einem Bezugswert x0. Hier wird als x0 = 10°C genommen, da das Polynom im interessierenden Wertebereich von 1°C bis 25°C mit den Koeffizienten von 10°C am besten “paßt”.

Mein eigenes Taylor-Reihen-Wissen reichte nicht mehr ganz, so daß dank @bty seit gestern also ein Näherungs-Polynom existiert, das man in FLUX verwenden könnte:

Formeln und kleine Herleitung

FIXME: also notate in mathjax

Der Term 22,8295*x^1,4254 (die Eiablagerate nach Bretschko, Bergmann…) hier vereinfacht “Heuvel-Formel” genannt) muß durch eine sinnvolle Näherung ohne Potenz ersetzt werden. x ist die Tageshöchsttemperatur.

f(x) = 22,8295 * x^1,4254
a = 22,8295
b = 1,4254
f(x) = a * x^b

Die gleich benötigten ersten drei Ableitungen dieser Funktion lauten:

f'(x) = a*b*x^(b-1)
f''(x) = a*b*(b-1)*x^(b-2)
f'''(x) = a*b*(b-1)*(b-2)*x^(b-3)

Taylor-Polynom 3. Ordnung hierfür:

T f(x) = f(x0)+f'(x0)*(x-x0) + f''(x0)/2 *(x-x0)*(x-x0) + f'''(x0)/6 * (x-x0) * (x-x0) * (x-x0)

Um damit nun rechnen zu können, werden

  • der Funktionswert (spätere Koeffizienten) für den Wert x0 berechnet, sowie die ersten drei Ableitungen an x0.

  • für x0 = 10°C ergeben sich:

    f(x0) = 607,989949
    f’(x0) = 86,662887
    f’‘(x0) = 3,686639
    f’‘’(x0) = -0,211834

  • dann wird eingesetzt (das wäre auch der Term, der im FLUX-query steht, solange es kein POW() gibt; die zwei Divisionen dort kann man da noch ‘kürzen’ und natürlich zu Konstanten machen, auch könnten (max(temp) -10) sowie dessen mehrfache Multiplikationen einen Schritt vorher natürlich auch Variablen zugewiesen werden), :

607,989949 + 86,662887*(max(temp) -10) + 3,686639/2 * (max(temp) -10) * (max(temp) -10) + -0,211834/6 * (max(temp) -10) * (max(temp) -10) * (max(temp) -10) 
Tagesmax. Eier/d; “Heuvel” Eier/d; Taylor-Poly 3.Ordn.
1°C 23 3
2°C 61 51
3°C 109 104
4°C 165 162
5°C 226 225
6°C 294 293
7°C 366 366
8°C 442 442
9°C 523 523
10°C 608 608
11°C 696 696
12°C 788 788
13°C 884 884
14°C 982 982
15°C 1084 1083
16°C 1188 1187
17°C 1295 1293
18°C 1405 1401
19°C 1518 1512
20°C 1633 1624
21°C 1751 1737
22°C 1871 1852
23°C 1993 1969
24°C 2118 2086
25°C 2245 2204


Dann fehlen noch

  • der Stärke des Überwinterungsvolkes (Konstante bzw. dashboard-ad-hoc-Variable),

  • die Mortalitätsrate (einfaches lineares Glied),

  • und die auflaufende Brut, die cumulativeSum der Formel oben ab 21 Tage nach Beginn (1.2. oder ab nachgewiesenener Brut)

Vielleicht brauchen wir für letzteres gar kein time shift, aber das soll @wtf entscheiden! ;)

2 Likes

Yeah. Hab das mal etwas umgeknetet, zur Ermittlung das Temperatur-Tagesmaxima zugrunde gelegt und ruf erstmal nur den Zeitraum 1.2. bis 31.12.2019 auf, soweit erstmal in meinem Sandkasten-Dashboard zu finden: :nerd_face: Labor / Eiablage & geschlüpfte Bienen nach Heuvel (2019). Die referenzierte DWD-Station ist dort einstellbar.

(Standbild des dashboards)

Bitte schaut mal jemand vom Fachlichen drauf ob das grob Sinn ergibt. (Ne Vorhersage klebt da auch dran; der “Knick” in einigen Stationen sieht erstmal aus wie nen Rechenfehler in der Vorhersage, aber bspw. Berlin hatte gestern & heute (!) 15-16°C, vgl. Hamburg für “ohne Knick”.)

Wenn des stimmig erscheint stünde wohl an als nächstes mit der Mortalitätsrate noch ne Kurve “Brut” zu bauen, am Besten um 20 Tage versetzt, wenn ich @mde’s Beitrag nochmal studiere.

2 Likes

Hmmm, bei der maximal en Eianzahl pro Tag streiten sich die Gelehrten, früher waren es mal 1500, dann das 2-fache Körpergewicht, nun hört man 2000 oder das 6-fache Gewicht. Wie auch immer, jedenfalls ist das das Maximum im Mai / Juni! Wenn wir da an einem warmen Tag jetzt schon mit 1000 Eiern rankommen macht mich das stutzig, die müssen nicht nur gelegt werden, sondern auch gepflegt und gefüttert werden, und dass es dann – am nächten Tag – auf 150 runter geht kann ich mir auch nicht vorstellen. Befürchte so dynamisch ist dass System Bienenvolk dann doch nicht. Aber nur ein leichter Zweifel ohne Zahlen die das widerlegen im Hintergrund …

Danke @wtf - gefällt mir wieder einmal sehr gut! :)

Nein - denn die hast Du ja bereits mit der orange-farbigen Kurve gebaut , yeah! 8)

  • Als zweite Kurve braucht es die “Gesamtzahl Bienen”, die startet per fixem Wert am besten als einstellbare Variable ab Tag 1. (10000 wäre ein sinnvoller default)

  • ab dem zweiten Tag wird diese Gesamtzahl jeden Tag mit 0,975 multipliziert - die Mortalität.

  • die auflaufende Brut findet in beiden Kurven Eingang: 20 Tage nach Eiablage (am 21. Tag des Ei) verschwindet diese Anzahl von “Brut” und wird “Anzahl Bienen” zugeschlagen (welche mit 0,975 multipliziert wird, s. o.).

  • darüber hinaus interessiert das Verhältnis Brut zu Bienen: ab >= 90% Brut/Bienen möchte man das markiert sehen (paßt daher als gauge und anderes panel).

Wenn das fertig ist, wollen wir noch den Anteil verdeckelter Brut an Gesamt-Brut sehen, aber dazu später … ;)

1 Like

zur erläuterung der zusammenhänge im bienenvolk beginne ich hier eine literatursammlung zum thema:

  • josef bretschko - naturgemäße bienenzucht
    hab ich in meinem archiv, bei interesse geb ich den link weiter.
  • ferdinand gerstung - das grundgesetz der brut- und volksentwicklung
    pdf, 14Mb hier
  • ludwig armbruster - imkerbetriebslehre der erzeugnung
    html hier
2 Likes

Die Knicke in der Kurve düften einigermaßen normal sein, weil die Temperatur sich ja sprunghaft ändert. Wenn ich mal die Formel von Heuvel zugrunde lege, werden die 2000 Eier am Tag bei 23-24 °C erreicht. Bei den hier ja auch im Sommer ab und an möglichen 30 °C wären es dann schon 3000. Einzelne Tage sollten da nicht das Problem sein, das dürfte sich recht schnell wegmitteln. Aber wenn es mal 2-3 Wochen über 25 °C ist könnte das Volk unrealistisch groß werden, wobei es (beginnend bei 0) immer noch über einen Monat von 30 °C braucht, um ein Volk von 40000 Bienen zu erreichen.

In https://doi.org/10.1016/j.ecolmodel.2013.06.005 findet man recht interessante Daten die hier hilfreich sein könnten (auch wenn deren Modell deutlich komplizierter ist), vor allem in den angegebenen Referenzen:

  • Todesraten von Eiern, Larven und Puppen, die könnte man vermutlich recht einfach einbauen
  • Maxima von 30000 verdeckelten Zellen (die sollten sich einfach ausrechen lassen, wenn man die Legerate schrittweise und nicht auf einen Schlag zu Bienen umwandelt
  • Volksstärke bis um die 50000
  • Maximale Legerate (Gleichung 10 und Werte aus Tabelle 4) um die 1000
1 Like

gerade scheint die Balkendarstellung kaputt zu sein, kannst Du @wtf mal nachsehen; es waren keine edits… @andreas: hast Du FLUX geupdated?

1 Like

Es ist alles beim alten, in jüngster Zeit kam nix rein. Die relevanten Softwarestände sind:

  • elbanco: InfluxDB 1.7.3
  • eltiempo: InfluxDB 1.7.2

mir auch grad unklar worans lag. aber es ist jetzt besser; ich konnte sinnvollerweise noch den zweiten “aggregateWindow” ausm mosmix-query rausnehmen und in den join() tun (hats besser gemacht). traditionell hatt ich so nen effekt AFAIR mal bei “doppelte ergebnisse” (bspw. bei nicht differenziertem qualitätsniveau) und/oder “irgendwas mit windowing/mittelwert-bildung in hohen zoomstufen”.

leider nicht viel schlauer geworden, aber habe gerne gestochert!

ps.: müsste man jetz nochmal nen debug-modus anwerfen und gucken ob die aggregation so weiterhin sinn ergibt.[tm]

1 Like

Die Grünlandtemperatursumme (GTS) plus Vorhersage mit der DWD-CDC-MOSMIX-Datenbasis in unserem Grafana funktioniert dank @wtf wieder:

https://weather.hiveeyes.org/grafana/d/dN_inOwmz/grunlandtemperatursumme-gts-and-kaltesumme?refresh=2h&orgId=1

2 Likes

In Berlin haben wir mit dem heutigen Tag die GTS von 200 erreicht (zum Vergleich: 9 Tage früher als im letzten Jahr):

(dashboard-url siehe posting zuvor)

3 Likes

das ist eine wichtige information die wir auch dem obmann für beobachtung und den ideengebern nicht vorenthalten sollen.

2 Likes

Letztes Jahr hatte ich hier die Entwicklung der GTS gerne beobachtet. Eine automatische Nullung zu Beginn eines neuen Betrachtungszeitraums wäre hilfreich. Beste Grüße und vielen Dank für die tollen Ideen!!

2 Likes

Hi @limago! Danke für die Anregung … hab dieses Jahr auch just erst mit dem Temperaturanstieg dieser Tage wieder dran gedacht.

Ich hab das Dashboard jetzt mal etwas umjebaut: Da gibts oben jetzt die Variablen “letztes Jahr” (wichtig für die Kältesumme, die wird am 1.11. des Vorjahres genullt) und “dieses Jahr”; aktuell sind sie nun auf 2020 und 2021 gesetzt, auch der Zeitraum des Dashboards läuft nun auf dieses Jahr/ab 1.11.2020:

So sollte sich jede:r zu nem nächsten Jahr dann auch schonmal ne aktuelle Ansicht erzeugen können auch wenn die defaults noch nicht aufs neuste Jahr gesetzt werden-wurden [insert Futur Konjuktiv BER II] . (Und mensch kann alte Jahre nachschlagen … letztes Jahr um die Zeit standen wa ja schon vieeel weiter! :)

3 Likes

Dazu gibt es von Bernhard (Heuvel) auch einen Beitrag im aktuellen Bienen-Journal (Heft-Nr. 2021/03, S.14-15)! Gerne bei mir anfragen, wer einen scan haben möchte.

4 Likes

Das allgemeine Grafana-panel Grünlandtemperatursumme (GTS) und Kältesumme funktioniert jetzt wieder für 2023, auch mit Vorhersage (siehe oben; DWD-MOSMIX-Daten).
Nur den Ort einstellen, für 2023 die Jahres- und Zeitraumeinstellungen so lassen.

Hinweis: es lassen sich nur für jene Orte aus der Auswahlliste die GTS errechnen, für die nicht nur die Vorhersagedaten (MOSMIX), sondern auch echte Meßdaten (CDC) vorliegen.

2 Likes

Vielen Dank an Dich und @wtf für die Pflege der Datenanzeige!