weatherdb 1.1.0__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. docker/Dockerfile +30 -0
  2. docker/docker-compose.yaml +58 -0
  3. docker/docker-compose_test.yaml +24 -0
  4. docker/start-docker-test.sh +6 -0
  5. docs/requirements.txt +10 -0
  6. docs/source/Changelog.md +2 -0
  7. docs/source/License.rst +7 -0
  8. docs/source/Methode.md +161 -0
  9. docs/source/_static/custom.css +8 -0
  10. docs/source/_static/favicon.ico +0 -0
  11. docs/source/_static/logo.png +0 -0
  12. docs/source/api/api.rst +15 -0
  13. docs/source/api/cli.rst +8 -0
  14. docs/source/api/weatherDB.broker.rst +10 -0
  15. docs/source/api/weatherDB.config.rst +7 -0
  16. docs/source/api/weatherDB.db.rst +23 -0
  17. docs/source/api/weatherDB.rst +22 -0
  18. docs/source/api/weatherDB.station.rst +56 -0
  19. docs/source/api/weatherDB.stations.rst +46 -0
  20. docs/source/api/weatherDB.utils.rst +22 -0
  21. docs/source/conf.py +137 -0
  22. docs/source/index.rst +33 -0
  23. docs/source/setup/Configuration.md +127 -0
  24. docs/source/setup/Hosting.md +9 -0
  25. docs/source/setup/Install.md +49 -0
  26. docs/source/setup/Quickstart.md +183 -0
  27. docs/source/setup/setup.rst +12 -0
  28. weatherdb/__init__.py +24 -0
  29. weatherdb/_version.py +1 -0
  30. weatherdb/alembic/README.md +8 -0
  31. weatherdb/alembic/alembic.ini +80 -0
  32. weatherdb/alembic/config.py +9 -0
  33. weatherdb/alembic/env.py +100 -0
  34. weatherdb/alembic/script.py.mako +26 -0
  35. weatherdb/alembic/versions/V1.0.0_initial_database_creation.py +898 -0
  36. weatherdb/alembic/versions/V1.0.2_more_charachters_for_settings+term_station_ma_raster.py +88 -0
  37. weatherdb/alembic/versions/V1.0.5_fix-ma-raster-values.py +152 -0
  38. weatherdb/alembic/versions/V1.0.6_update-views.py +22 -0
  39. weatherdb/broker.py +667 -0
  40. weatherdb/cli.py +214 -0
  41. weatherdb/config/ConfigParser.py +663 -0
  42. weatherdb/config/__init__.py +5 -0
  43. weatherdb/config/config_default.ini +162 -0
  44. weatherdb/db/__init__.py +3 -0
  45. weatherdb/db/connections.py +374 -0
  46. weatherdb/db/fixtures/RichterParameters.json +34 -0
  47. weatherdb/db/models.py +402 -0
  48. weatherdb/db/queries/get_quotient.py +155 -0
  49. weatherdb/db/views.py +165 -0
  50. weatherdb/station/GroupStation.py +710 -0
  51. weatherdb/station/StationBases.py +3108 -0
  52. weatherdb/station/StationET.py +111 -0
  53. weatherdb/station/StationP.py +807 -0
  54. weatherdb/station/StationPD.py +98 -0
  55. weatherdb/station/StationT.py +164 -0
  56. weatherdb/station/__init__.py +13 -0
  57. weatherdb/station/constants.py +21 -0
  58. weatherdb/stations/GroupStations.py +519 -0
  59. weatherdb/stations/StationsBase.py +1021 -0
  60. weatherdb/stations/StationsBaseTET.py +30 -0
  61. weatherdb/stations/StationsET.py +17 -0
  62. weatherdb/stations/StationsP.py +128 -0
  63. weatherdb/stations/StationsPD.py +24 -0
  64. weatherdb/stations/StationsT.py +21 -0
  65. weatherdb/stations/__init__.py +11 -0
  66. weatherdb/utils/TimestampPeriod.py +369 -0
  67. weatherdb/utils/__init__.py +3 -0
  68. weatherdb/utils/dwd.py +350 -0
  69. weatherdb/utils/geometry.py +69 -0
  70. weatherdb/utils/get_data.py +285 -0
  71. weatherdb/utils/logging.py +126 -0
  72. weatherdb-1.1.0.dist-info/LICENSE +674 -0
  73. weatherdb-1.1.0.dist-info/METADATA +765 -0
  74. weatherdb-1.1.0.dist-info/RECORD +77 -0
  75. weatherdb-1.1.0.dist-info/WHEEL +5 -0
  76. weatherdb-1.1.0.dist-info/entry_points.txt +2 -0
  77. weatherdb-1.1.0.dist-info/top_level.txt +3 -0
@@ -0,0 +1,111 @@
1
+ # libraries
2
+ import logging
3
+ import sqlalchemy as sa
4
+ from sqlalchemy import text as sqltxt
5
+ from functools import cached_property
6
+
7
+ from ..db.connections import db_engine
8
+ from ..db.models import MetaET
9
+ from .StationBases import StationTETBase
10
+
11
+ # set settings
12
+ # ############
13
+ __all__ = ["StationET"]
14
+ log = logging.getLogger(__name__)
15
+
16
+ # class definition
17
+ ##################
18
+ class StationET(StationTETBase):
19
+ """A class to work with and download potential Evapotranspiration (VPGB) data for one station."""
20
+
21
+ # common settings
22
+ _MetaModel = MetaET
23
+ _para = "et"
24
+ _para_base = _para
25
+ _para_long = "potential Evapotranspiration"
26
+ _unit = "mm/Tag"
27
+ _decimals = 10
28
+
29
+ # cdc dwd parameters
30
+ _ftp_folder_base = ["climate_environment/CDC/derived_germany/soil/daily/"]
31
+ _ftp_zip_regex_prefix = r".*_v2_"
32
+ _cdc_date_col = "Datum"
33
+ _cdc_col_names_imp = ["VPGFAO"]
34
+
35
+ # for regionalistaion
36
+ _ma_terms = ["year"]
37
+
38
+ # for the fillup
39
+ _fillup_max_dist = 100000
40
+
41
+ def __init__(self, id, **kwargs):
42
+ super().__init__(id, **kwargs)
43
+ self.id_str = str(id)
44
+
45
+ @cached_property
46
+ def _table(self):
47
+ return sa.table(
48
+ f"{self.id}_{self._para}",
49
+ sa.column("timestamp", sa.Date),
50
+ sa.column("raw", sa.Integer),
51
+ sa.column("qc", sa.Integer),
52
+ sa.column("filled", sa.Integer),
53
+ sa.column("filled_by", sa.SmallInteger),
54
+ schema="timeseries")
55
+
56
+ def _create_timeseries_table(self):
57
+ """Create the timeseries table in the DB if it is not yet existing."""
58
+ sql_add_table = '''
59
+ CREATE TABLE IF NOT EXISTS timeseries."{stid}_{para}" (
60
+ timestamp date PRIMARY KEY,
61
+ raw integer NULL DEFAULT NULL,
62
+ qc integer NULL DEFAULT NULL,
63
+ filled integer NULL DEFAULT NULL,
64
+ filled_by smallint NULL DEFAULT NULL
65
+ );
66
+ '''.format(stid=self.id, para=self._para)
67
+ with db_engine.connect() as con:
68
+ con.execute(sqltxt(sql_add_table))
69
+ con.commit()
70
+
71
+ def _get_sql_new_qc(self, period):
72
+ # inversion possible?
73
+ do_invers = self.get_meta(infos=["stationshoehe"])>800
74
+
75
+ sql_nears = self._get_sql_near_median(
76
+ period=period, only_real=False, add_is_winter=do_invers,
77
+ extra_cols="raw-nbs_median AS diff")
78
+
79
+ sql_null_case = f"""(nears.raw > (nears.nbs_median * 2) AND nears.raw > {3*self._decimals})
80
+ OR ((nears.raw * 4) < nears.nbs_median AND nears.raw > {2*self._decimals})"""
81
+ if do_invers:
82
+ # without inversion
83
+ sql_null_case = "CASE WHEN (winter) THEN "+\
84
+ f"((nears.raw * 4) < nears.nbs_median AND nears.raw > {2*self._decimals}) ELSE "+\
85
+ f"{sql_null_case} END"
86
+
87
+ # create sql for new qc
88
+ sql_new_qc = f"""
89
+ WITH nears AS ({sql_nears})
90
+ SELECT
91
+ timestamp,
92
+ (CASE WHEN ({sql_null_case}
93
+ OR (nears.raw < 0)
94
+ OR (nears.raw > {20*self._decimals}))
95
+ THEN NULL
96
+ ELSE nears."raw" END) as qc
97
+ FROM nears
98
+ """
99
+
100
+ return sql_new_qc
101
+
102
+ def get_adj(self, **kwargs):
103
+ main_df, adj_df, ma, main_df_tr = super().get_adj(**kwargs)
104
+
105
+ # calculate the yearly
106
+ main_df_y = main_df.groupby(main_df_tr.index.year)\
107
+ .sum(min_count=345).mean()
108
+
109
+ adj_df["adj"] = (main_df * (ma[0] / main_df_y)).round(1)
110
+
111
+ return adj_df