weatherdb 1.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- docker/Dockerfile +30 -0
 - docker/docker-compose.yaml +58 -0
 - docker/docker-compose_test.yaml +24 -0
 - docker/start-docker-test.sh +6 -0
 - docs/requirements.txt +10 -0
 - docs/source/Changelog.md +2 -0
 - docs/source/License.rst +7 -0
 - docs/source/Methode.md +161 -0
 - docs/source/_static/custom.css +8 -0
 - docs/source/_static/favicon.ico +0 -0
 - docs/source/_static/logo.png +0 -0
 - docs/source/api/api.rst +15 -0
 - docs/source/api/cli.rst +8 -0
 - docs/source/api/weatherDB.broker.rst +10 -0
 - docs/source/api/weatherDB.config.rst +7 -0
 - docs/source/api/weatherDB.db.rst +23 -0
 - docs/source/api/weatherDB.rst +22 -0
 - docs/source/api/weatherDB.station.rst +56 -0
 - docs/source/api/weatherDB.stations.rst +46 -0
 - docs/source/api/weatherDB.utils.rst +22 -0
 - docs/source/conf.py +137 -0
 - docs/source/index.rst +33 -0
 - docs/source/setup/Configuration.md +127 -0
 - docs/source/setup/Hosting.md +9 -0
 - docs/source/setup/Install.md +49 -0
 - docs/source/setup/Quickstart.md +183 -0
 - docs/source/setup/setup.rst +12 -0
 - weatherdb/__init__.py +24 -0
 - weatherdb/_version.py +1 -0
 - weatherdb/alembic/README.md +8 -0
 - weatherdb/alembic/alembic.ini +80 -0
 - weatherdb/alembic/config.py +9 -0
 - weatherdb/alembic/env.py +100 -0
 - weatherdb/alembic/script.py.mako +26 -0
 - weatherdb/alembic/versions/V1.0.0_initial_database_creation.py +898 -0
 - weatherdb/alembic/versions/V1.0.2_more_charachters_for_settings+term_station_ma_raster.py +88 -0
 - weatherdb/alembic/versions/V1.0.5_fix-ma-raster-values.py +152 -0
 - weatherdb/alembic/versions/V1.0.6_update-views.py +22 -0
 - weatherdb/broker.py +667 -0
 - weatherdb/cli.py +214 -0
 - weatherdb/config/ConfigParser.py +663 -0
 - weatherdb/config/__init__.py +5 -0
 - weatherdb/config/config_default.ini +162 -0
 - weatherdb/db/__init__.py +3 -0
 - weatherdb/db/connections.py +374 -0
 - weatherdb/db/fixtures/RichterParameters.json +34 -0
 - weatherdb/db/models.py +402 -0
 - weatherdb/db/queries/get_quotient.py +155 -0
 - weatherdb/db/views.py +165 -0
 - weatherdb/station/GroupStation.py +710 -0
 - weatherdb/station/StationBases.py +3108 -0
 - weatherdb/station/StationET.py +111 -0
 - weatherdb/station/StationP.py +807 -0
 - weatherdb/station/StationPD.py +98 -0
 - weatherdb/station/StationT.py +164 -0
 - weatherdb/station/__init__.py +13 -0
 - weatherdb/station/constants.py +21 -0
 - weatherdb/stations/GroupStations.py +519 -0
 - weatherdb/stations/StationsBase.py +1021 -0
 - weatherdb/stations/StationsBaseTET.py +30 -0
 - weatherdb/stations/StationsET.py +17 -0
 - weatherdb/stations/StationsP.py +128 -0
 - weatherdb/stations/StationsPD.py +24 -0
 - weatherdb/stations/StationsT.py +21 -0
 - weatherdb/stations/__init__.py +11 -0
 - weatherdb/utils/TimestampPeriod.py +369 -0
 - weatherdb/utils/__init__.py +3 -0
 - weatherdb/utils/dwd.py +350 -0
 - weatherdb/utils/geometry.py +69 -0
 - weatherdb/utils/get_data.py +285 -0
 - weatherdb/utils/logging.py +126 -0
 - weatherdb-1.1.0.dist-info/LICENSE +674 -0
 - weatherdb-1.1.0.dist-info/METADATA +765 -0
 - weatherdb-1.1.0.dist-info/RECORD +77 -0
 - weatherdb-1.1.0.dist-info/WHEEL +5 -0
 - weatherdb-1.1.0.dist-info/entry_points.txt +2 -0
 - weatherdb-1.1.0.dist-info/top_level.txt +3 -0
 
| 
         @@ -0,0 +1,98 @@ 
     | 
|
| 
      
 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 ..utils.dwd import dwd_id_to_str
         
     | 
| 
      
 9 
     | 
    
         
            +
            from ..db.models import MetaPD
         
     | 
| 
      
 10 
     | 
    
         
            +
            from .StationBases import StationPBase, StationCanVirtualBase
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            # set settings
         
     | 
| 
      
 13 
     | 
    
         
            +
            # ############
         
     | 
| 
      
 14 
     | 
    
         
            +
            __all__ = ["StationPD"]
         
     | 
| 
      
 15 
     | 
    
         
            +
            log = logging.getLogger(__name__)
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            # class definition
         
     | 
| 
      
 18 
     | 
    
         
            +
            ##################
         
     | 
| 
      
 19 
     | 
    
         
            +
            class StationPD(StationPBase, StationCanVirtualBase):
         
     | 
| 
      
 20 
     | 
    
         
            +
                """A class to work with and download daily precipitation data for one station.
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                Those station data are only downloaded to do some quality checks on the 10 minute data.
         
     | 
| 
      
 23 
     | 
    
         
            +
                Therefor there is no special quality check and richter correction done on this data.
         
     | 
| 
      
 24 
     | 
    
         
            +
                If you want daily precipitation data, better use the 10 minutes station(StationP) and aggregate to daily values."""
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                # common settings
         
     | 
| 
      
 27 
     | 
    
         
            +
                _MetaModel = MetaPD
         
     | 
| 
      
 28 
     | 
    
         
            +
                _para = "p_d"
         
     | 
| 
      
 29 
     | 
    
         
            +
                _para_base = "p"
         
     | 
| 
      
 30 
     | 
    
         
            +
                _para_long = "daily Precipitation"
         
     | 
| 
      
 31 
     | 
    
         
            +
                _unit = "mm/day"
         
     | 
| 
      
 32 
     | 
    
         
            +
                _valid_kinds = {"raw", "filled", "filled_by"}
         
     | 
| 
      
 33 
     | 
    
         
            +
                _best_kind = "filled"
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                # cdc dwd parameters
         
     | 
| 
      
 36 
     | 
    
         
            +
                _ftp_folder_base = [
         
     | 
| 
      
 37 
     | 
    
         
            +
                    "climate_environment/CDC/observations_germany/climate/daily/kl/",
         
     | 
| 
      
 38 
     | 
    
         
            +
                    "climate_environment/CDC/observations_germany/climate/daily/more_precip/"]
         
     | 
| 
      
 39 
     | 
    
         
            +
                _cdc_col_names_imp = ["RSK"]
         
     | 
| 
      
 40 
     | 
    
         
            +
                _db_col_names_imp = ["raw"]
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                # timestamp configurations
         
     | 
| 
      
 43 
     | 
    
         
            +
                _tstp_format_db = "%Y%m%d"
         
     | 
| 
      
 44 
     | 
    
         
            +
                _tstp_format_human = "%Y-%m-%d"
         
     | 
| 
      
 45 
     | 
    
         
            +
                _tstp_dtype = "date"
         
     | 
| 
      
 46 
     | 
    
         
            +
                _interval = "1 day"
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                # aggregation
         
     | 
| 
      
 49 
     | 
    
         
            +
                _min_agg_to = "day"
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                # methods from the base class that should not be active for this class
         
     | 
| 
      
 52 
     | 
    
         
            +
                quality_check = property(doc='(!) Disallowed inherited')
         
     | 
| 
      
 53 
     | 
    
         
            +
                last_imp_quality_check = property(doc='(!) Disallowed inherited')
         
     | 
| 
      
 54 
     | 
    
         
            +
                get_corr = property(doc='(!) Disallowed inherited')
         
     | 
| 
      
 55 
     | 
    
         
            +
                get_adj = property(doc='(!) Disallowed inherited')
         
     | 
| 
      
 56 
     | 
    
         
            +
                get_qc = property(doc='(!) Disallowed inherited')
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                def __init__(self, id, **kwargs):
         
     | 
| 
      
 59 
     | 
    
         
            +
                    super().__init__(id, **kwargs)
         
     | 
| 
      
 60 
     | 
    
         
            +
                    self.id_str = dwd_id_to_str(id)
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                def _download_raw(self, zipfiles):
         
     | 
| 
      
 63 
     | 
    
         
            +
                    df_all, max_hist_tstp = super()._download_raw(zipfiles)
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                    # fill RSK with values from RS if not given
         
     | 
| 
      
 66 
     | 
    
         
            +
                    if "RS" in df_all.columns and "RSK" in df_all.columns:
         
     | 
| 
      
 67 
     | 
    
         
            +
                        mask = df_all["RSK"].isna()
         
     | 
| 
      
 68 
     | 
    
         
            +
                        df_all.loc[mask, "RSK"] = df_all.loc[mask, "RS"]
         
     | 
| 
      
 69 
     | 
    
         
            +
                    elif "RS" in df_all.columns:
         
     | 
| 
      
 70 
     | 
    
         
            +
                        df_all["RSK"] = df_all["RS"]
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                    return df_all, max_hist_tstp
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
                @cached_property
         
     | 
| 
      
 75 
     | 
    
         
            +
                def _table(self):
         
     | 
| 
      
 76 
     | 
    
         
            +
                    return sa.table(
         
     | 
| 
      
 77 
     | 
    
         
            +
                        f"{self.id}_{self._para}",
         
     | 
| 
      
 78 
     | 
    
         
            +
                        sa.column("timestamp", sa.Date),
         
     | 
| 
      
 79 
     | 
    
         
            +
                        sa.column("raw", sa.Integer),
         
     | 
| 
      
 80 
     | 
    
         
            +
                        sa.column("filled", sa.Integer),
         
     | 
| 
      
 81 
     | 
    
         
            +
                        sa.column("filled_by", sa.SmallInteger),
         
     | 
| 
      
 82 
     | 
    
         
            +
                        schema="timeseries")
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                @db_engine.deco_create_privilege
         
     | 
| 
      
 85 
     | 
    
         
            +
                def _create_timeseries_table(self):
         
     | 
| 
      
 86 
     | 
    
         
            +
                    """Create the timeseries table in the DB if it is not yet existing."""
         
     | 
| 
      
 87 
     | 
    
         
            +
                    sql_add_table = '''
         
     | 
| 
      
 88 
     | 
    
         
            +
                        CREATE TABLE IF NOT EXISTS timeseries."{stid}_{para}"  (
         
     | 
| 
      
 89 
     | 
    
         
            +
                            timestamp date PRIMARY KEY,
         
     | 
| 
      
 90 
     | 
    
         
            +
                            raw int4,
         
     | 
| 
      
 91 
     | 
    
         
            +
                            filled int4,
         
     | 
| 
      
 92 
     | 
    
         
            +
                            filled_by int2
         
     | 
| 
      
 93 
     | 
    
         
            +
                        );
         
     | 
| 
      
 94 
     | 
    
         
            +
                    '''.format(stid=self.id, para=self._para)
         
     | 
| 
      
 95 
     | 
    
         
            +
                    with db_engine.connect() as con:
         
     | 
| 
      
 96 
     | 
    
         
            +
                        con.execute(sqltxt(sql_add_table))
         
     | 
| 
      
 97 
     | 
    
         
            +
                        con.commit()
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
         @@ -0,0 +1,164 @@ 
     | 
|
| 
      
 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 ..utils.dwd import dwd_id_to_str
         
     | 
| 
      
 9 
     | 
    
         
            +
            from ..db.models import MetaT
         
     | 
| 
      
 10 
     | 
    
         
            +
            from .StationBases import StationTETBase
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            # set settings
         
     | 
| 
      
 13 
     | 
    
         
            +
            # ############
         
     | 
| 
      
 14 
     | 
    
         
            +
            __all__ = ["StationT"]
         
     | 
| 
      
 15 
     | 
    
         
            +
            log = logging.getLogger(__name__)
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            # class definition
         
     | 
| 
      
 18 
     | 
    
         
            +
            ##################
         
     | 
| 
      
 19 
     | 
    
         
            +
            class StationT(StationTETBase):
         
     | 
| 
      
 20 
     | 
    
         
            +
                """A class to work with and download temperaure data for one station."""
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                # common settings
         
     | 
| 
      
 23 
     | 
    
         
            +
                _MetaModel = MetaT
         
     | 
| 
      
 24 
     | 
    
         
            +
                _para = "t"
         
     | 
| 
      
 25 
     | 
    
         
            +
                _para_base = _para
         
     | 
| 
      
 26 
     | 
    
         
            +
                _para_long = "Temperature"
         
     | 
| 
      
 27 
     | 
    
         
            +
                _unit = "°C"
         
     | 
| 
      
 28 
     | 
    
         
            +
                _decimals = 10
         
     | 
| 
      
 29 
     | 
    
         
            +
                _valid_kinds = {"raw", "raw_min", "raw_max", "qc",
         
     | 
| 
      
 30 
     | 
    
         
            +
                                "filled", "filled_min", "filled_max", "filled_by"}
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                # cdc dwd parameters
         
     | 
| 
      
 33 
     | 
    
         
            +
                _ftp_folder_base = [
         
     | 
| 
      
 34 
     | 
    
         
            +
                    "climate_environment/CDC/observations_germany/climate/daily/kl/"]
         
     | 
| 
      
 35 
     | 
    
         
            +
                _cdc_date_col = "MESS_DATUM"
         
     | 
| 
      
 36 
     | 
    
         
            +
                _cdc_col_names_imp = ["TMK", "TNK", "TXK"]
         
     | 
| 
      
 37 
     | 
    
         
            +
                _db_col_names_imp = ["raw", "raw_min", "raw_max"]
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                # aggregation
         
     | 
| 
      
 40 
     | 
    
         
            +
                _agg_fun = "avg"
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                # for regionalistaion
         
     | 
| 
      
 43 
     | 
    
         
            +
                _ma_terms = ["year"]
         
     | 
| 
      
 44 
     | 
    
         
            +
                _coef_sign = ["-", "+"]
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                # # for the fillup
         
     | 
| 
      
 47 
     | 
    
         
            +
                _filled_by_n = 5
         
     | 
| 
      
 48 
     | 
    
         
            +
                _fillup_max_dist = 100e3
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                def __init__(self, id, **kwargs):
         
     | 
| 
      
 52 
     | 
    
         
            +
                    super().__init__(id, **kwargs)
         
     | 
| 
      
 53 
     | 
    
         
            +
                    self.id_str = dwd_id_to_str(id)
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                @cached_property
         
     | 
| 
      
 56 
     | 
    
         
            +
                def _table(self):
         
     | 
| 
      
 57 
     | 
    
         
            +
                    return sa.table(
         
     | 
| 
      
 58 
     | 
    
         
            +
                        f"{self.id}_{self._para}",
         
     | 
| 
      
 59 
     | 
    
         
            +
                        sa.column("timestamp", sa.Date),
         
     | 
| 
      
 60 
     | 
    
         
            +
                        sa.column("raw", sa.Integer),
         
     | 
| 
      
 61 
     | 
    
         
            +
                        sa.column("raw_min", sa.Integer),
         
     | 
| 
      
 62 
     | 
    
         
            +
                        sa.column("raw_max", sa.Integer),
         
     | 
| 
      
 63 
     | 
    
         
            +
                        sa.column("qc", sa.Integer),
         
     | 
| 
      
 64 
     | 
    
         
            +
                        sa.column("filled", sa.Integer),
         
     | 
| 
      
 65 
     | 
    
         
            +
                        sa.column("filled_min", sa.Integer),
         
     | 
| 
      
 66 
     | 
    
         
            +
                        sa.column("filled_max", sa.Integer),
         
     | 
| 
      
 67 
     | 
    
         
            +
                        sa.column("filled_by", sa.SmallInteger),
         
     | 
| 
      
 68 
     | 
    
         
            +
                        schema="timeseries")
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                def _create_timeseries_table(self):
         
     | 
| 
      
 71 
     | 
    
         
            +
                    """Create the timeseries table in the DB if it is not yet existing."""
         
     | 
| 
      
 72 
     | 
    
         
            +
                    sql_add_table = f'''
         
     | 
| 
      
 73 
     | 
    
         
            +
                        CREATE TABLE IF NOT EXISTS timeseries."{self.id}_{self._para}"  (
         
     | 
| 
      
 74 
     | 
    
         
            +
                            timestamp date PRIMARY KEY,
         
     | 
| 
      
 75 
     | 
    
         
            +
                            raw integer NULL DEFAULT NULL,
         
     | 
| 
      
 76 
     | 
    
         
            +
                            raw_min integer NULL DEFAULT NULL,
         
     | 
| 
      
 77 
     | 
    
         
            +
                            raw_max integer NULL DEFAULT NULL,
         
     | 
| 
      
 78 
     | 
    
         
            +
                            qc integer NULL DEFAULT NULL,
         
     | 
| 
      
 79 
     | 
    
         
            +
                            filled integer NULL DEFAULT NULL,
         
     | 
| 
      
 80 
     | 
    
         
            +
                            filled_min integer NULL DEFAULT NULL,
         
     | 
| 
      
 81 
     | 
    
         
            +
                            filled_max integer NULL DEFAULT NULL,
         
     | 
| 
      
 82 
     | 
    
         
            +
                            filled_by smallint[{self._filled_by_n}] NULL DEFAULT NULL
         
     | 
| 
      
 83 
     | 
    
         
            +
                            );
         
     | 
| 
      
 84 
     | 
    
         
            +
                    '''
         
     | 
| 
      
 85 
     | 
    
         
            +
                    with db_engine.connect() as con:
         
     | 
| 
      
 86 
     | 
    
         
            +
                        con.execute(sqltxt(sql_add_table))
         
     | 
| 
      
 87 
     | 
    
         
            +
                        con.commit()
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
                def _get_sql_new_qc(self, period):
         
     | 
| 
      
 90 
     | 
    
         
            +
                    # inversion possible?
         
     | 
| 
      
 91 
     | 
    
         
            +
                    do_invers = self.get_meta(infos=["stationshoehe"])>800
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
                    sql_nears = self._get_sql_near_median(
         
     | 
| 
      
 94 
     | 
    
         
            +
                        period=period, only_real=False, add_is_winter=do_invers,
         
     | 
| 
      
 95 
     | 
    
         
            +
                        extra_cols="raw-nbs_median AS diff")
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
                    if do_invers:
         
     | 
| 
      
 98 
     | 
    
         
            +
                        # without inversion
         
     | 
| 
      
 99 
     | 
    
         
            +
                        sql_null_case = "CASE WHEN (winter) THEN "+\
         
     | 
| 
      
 100 
     | 
    
         
            +
                            f"diff < {-5 * self._decimals} ELSE "+\
         
     | 
| 
      
 101 
     | 
    
         
            +
                            f"ABS(diff) > {5 * self._decimals} END "+\
         
     | 
| 
      
 102 
     | 
    
         
            +
                            f"OR raw < {-50 * self._decimals} OR raw > {50 * self._decimals}"
         
     | 
| 
      
 103 
     | 
    
         
            +
                    else:
         
     | 
| 
      
 104 
     | 
    
         
            +
                        # with inversion
         
     | 
| 
      
 105 
     | 
    
         
            +
                        sql_null_case = f"ABS(diff) > {5 * self._decimals}"
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
                    # create sql for new qc
         
     | 
| 
      
 108 
     | 
    
         
            +
                    sql_new_qc = f"""
         
     | 
| 
      
 109 
     | 
    
         
            +
                        WITH nears AS ({sql_nears})
         
     | 
| 
      
 110 
     | 
    
         
            +
                        SELECT
         
     | 
| 
      
 111 
     | 
    
         
            +
                            timestamp,
         
     | 
| 
      
 112 
     | 
    
         
            +
                            (CASE WHEN ({sql_null_case})
         
     | 
| 
      
 113 
     | 
    
         
            +
                                THEN NULL
         
     | 
| 
      
 114 
     | 
    
         
            +
                                ELSE nears."raw"
         
     | 
| 
      
 115 
     | 
    
         
            +
                                END) as qc
         
     | 
| 
      
 116 
     | 
    
         
            +
                        FROM nears
         
     | 
| 
      
 117 
     | 
    
         
            +
                    """
         
     | 
| 
      
 118 
     | 
    
         
            +
             
     | 
| 
      
 119 
     | 
    
         
            +
                    return sql_new_qc
         
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
                @db_engine.deco_update_privilege
         
     | 
| 
      
 122 
     | 
    
         
            +
                def _sql_fillup_extra_dict(self, **kwargs):
         
     | 
| 
      
 123 
     | 
    
         
            +
                    # additional parts to calculate the filling of min and max
         
     | 
| 
      
 124 
     | 
    
         
            +
                    fillup_extra_dict = super()._sql_fillup_extra_dict(**kwargs)
         
     | 
| 
      
 125 
     | 
    
         
            +
                    sql_array_init = "ARRAY[{0}]".format(
         
     | 
| 
      
 126 
     | 
    
         
            +
                        ", ".join(["NULL::smallint"] * self._filled_by_n))
         
     | 
| 
      
 127 
     | 
    
         
            +
                    fillup_extra_dict.update({
         
     | 
| 
      
 128 
     | 
    
         
            +
                        "extra_new_temp_cols": "raw_min AS filled_min, raw_max AS filled_max," +
         
     | 
| 
      
 129 
     | 
    
         
            +
                                    f"{sql_array_init} AS nb_min, {sql_array_init} AS nb_max,",
         
     | 
| 
      
 130 
     | 
    
         
            +
                        "extra_cols_fillup_calc": "filled_min=round(nb.raw_min + %3$s, 0)::int, " +
         
     | 
| 
      
 131 
     | 
    
         
            +
                                                  "filled_max=round(nb.raw_max + %3$s, 0)::int, ",
         
     | 
| 
      
 132 
     | 
    
         
            +
                        "extra_cols_fillup": "filled_min = new.filled_min, " +
         
     | 
| 
      
 133 
     | 
    
         
            +
                                             "filled_max = new.filled_max, ",
         
     | 
| 
      
 134 
     | 
    
         
            +
                        "extra_fillup_where": ' OR ts."filled_min" IS DISTINCT FROM new."filled_min"' +
         
     | 
| 
      
 135 
     | 
    
         
            +
                                              ' OR ts."filled_max" IS DISTINCT FROM new."filled_max"',
         
     | 
| 
      
 136 
     | 
    
         
            +
                        "extra_exec_cols": "nb_max[{i}]=round(nb.raw_max + %3$s, 0)::int,"+
         
     | 
| 
      
 137 
     | 
    
         
            +
                                           "nb_min[{i}]=round(nb.raw_min + %3$s, 0)::int,",
         
     | 
| 
      
 138 
     | 
    
         
            +
                        "extra_after_loop_extra_col": """,
         
     | 
| 
      
 139 
     | 
    
         
            +
                            filled_min=(SELECT percentile_cont(0.5) WITHIN GROUP (ORDER BY v)
         
     | 
| 
      
 140 
     | 
    
         
            +
                                        FROM unnest(nb_min) as T(v)),
         
     | 
| 
      
 141 
     | 
    
         
            +
                            filled_max=(SELECT percentile_cont(0.5) WITHIN GROUP (ORDER BY v)
         
     | 
| 
      
 142 
     | 
    
         
            +
                                        FROM unnest(nb_max) as T(v))"""})
         
     | 
| 
      
 143 
     | 
    
         
            +
                    return fillup_extra_dict
         
     | 
| 
      
 144 
     | 
    
         
            +
             
     | 
| 
      
 145 
     | 
    
         
            +
                def get_multi_annual_raster(self):
         
     | 
| 
      
 146 
     | 
    
         
            +
                    mas = super().get_multi_annual_raster()
         
     | 
| 
      
 147 
     | 
    
         
            +
                    if mas is not None:
         
     | 
| 
      
 148 
     | 
    
         
            +
                        return [ma / 10 for ma in mas]
         
     | 
| 
      
 149 
     | 
    
         
            +
                    else:
         
     | 
| 
      
 150 
     | 
    
         
            +
                        return None
         
     | 
| 
      
 151 
     | 
    
         
            +
             
     | 
| 
      
 152 
     | 
    
         
            +
                def get_adj(self, **kwargs):
         
     | 
| 
      
 153 
     | 
    
         
            +
                    main_df, adj_df, ma, main_df_tr = super().get_adj(**kwargs)
         
     | 
| 
      
 154 
     | 
    
         
            +
             
     | 
| 
      
 155 
     | 
    
         
            +
                    # calculate the yearly
         
     | 
| 
      
 156 
     | 
    
         
            +
                    main_df_y = main_df.groupby(main_df_tr.index.year)\
         
     | 
| 
      
 157 
     | 
    
         
            +
                        .mean().mean()
         
     | 
| 
      
 158 
     | 
    
         
            +
             
     | 
| 
      
 159 
     | 
    
         
            +
                    adj_df["adj"] = (main_df + (ma[0] - main_df_y)).round(1)
         
     | 
| 
      
 160 
     | 
    
         
            +
             
     | 
| 
      
 161 
     | 
    
         
            +
                    return adj_df
         
     | 
| 
      
 162 
     | 
    
         
            +
             
     | 
| 
      
 163 
     | 
    
         
            +
                def get_quotient(self, **kwargs):
         
     | 
| 
      
 164 
     | 
    
         
            +
                    raise NotImplementedError("The quotient is not yet implemented for temperature.")
         
     | 
| 
         @@ -0,0 +1,13 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            """
         
     | 
| 
      
 2 
     | 
    
         
            +
            This module has a class for every type of station. E.g. StationP (or StationP).
         
     | 
| 
      
 3 
     | 
    
         
            +
            One object represents one Station with one parameter.
         
     | 
| 
      
 4 
     | 
    
         
            +
            This object can get used to get the corresponding timeserie.
         
     | 
| 
      
 5 
     | 
    
         
            +
            There is also a StationGroup class that groups the three parameters precipitation, temperature and evapotranspiration together for one station.
         
     | 
| 
      
 6 
     | 
    
         
            +
            """
         
     | 
| 
      
 7 
     | 
    
         
            +
            from .StationET import StationET
         
     | 
| 
      
 8 
     | 
    
         
            +
            from .StationP import StationP
         
     | 
| 
      
 9 
     | 
    
         
            +
            from .StationPD import StationPD
         
     | 
| 
      
 10 
     | 
    
         
            +
            from .StationT import StationT
         
     | 
| 
      
 11 
     | 
    
         
            +
            from .GroupStation import GroupStation
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            __all__ = ["StationET", "StationP", "StationPD", "StationT", "GroupStation"]
         
     | 
| 
         @@ -0,0 +1,21 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Variables
         
     | 
| 
      
 2 
     | 
    
         
            +
            # ---------
         
     | 
| 
      
 3 
     | 
    
         
            +
            # possible aggregation periods from small to big
         
     | 
| 
      
 4 
     | 
    
         
            +
            AGG_TO = {
         
     | 
| 
      
 5 
     | 
    
         
            +
                None: {
         
     | 
| 
      
 6 
     | 
    
         
            +
                    "split":{"p": 5, "t":3, "et": 3}},
         
     | 
| 
      
 7 
     | 
    
         
            +
                "10 min": {
         
     | 
| 
      
 8 
     | 
    
         
            +
                    "split":{"p": 5, "t":3, "et": 3}},
         
     | 
| 
      
 9 
     | 
    
         
            +
                "hour": {
         
     | 
| 
      
 10 
     | 
    
         
            +
                    "split":{"p": 4, "t":3, "et": 3}},
         
     | 
| 
      
 11 
     | 
    
         
            +
                "day": {
         
     | 
| 
      
 12 
     | 
    
         
            +
                    "split":{"p": 3, "t":3, "et": 3}},
         
     | 
| 
      
 13 
     | 
    
         
            +
                "month": {
         
     | 
| 
      
 14 
     | 
    
         
            +
                    "split":{"p": 2, "t":2, "et": 2}},
         
     | 
| 
      
 15 
     | 
    
         
            +
                "year": {
         
     | 
| 
      
 16 
     | 
    
         
            +
                    "split":{"p": 1, "t":1, "et": 1}},
         
     | 
| 
      
 17 
     | 
    
         
            +
                "decade": {
         
     | 
| 
      
 18 
     | 
    
         
            +
                    "split":{"p": 1, "t":1, "et": 1}}
         
     | 
| 
      
 19 
     | 
    
         
            +
                }
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            __all__ = ["AGG_TO"]
         
     |