diff --git a/.github/workflows/testing.yml b/.github/workflows/testing_main_dev.yml similarity index 71% rename from .github/workflows/testing.yml rename to .github/workflows/testing_main_dev.yml index e1e10c53..4344818e 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing_main_dev.yml @@ -1,10 +1,9 @@ -name: Automated testing and coverage +name: Automated testing and coverage (in protected branches) on: push: - branches: - - 'cp_miscellaneous' + branches: [ "main", "dev" ] workflow_dispatch: @@ -13,7 +12,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Set up Python uses: actions/setup-python@v2 @@ -23,12 +22,12 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - pip install pytest coverage coverage-badge + if [ -f requirements_testing.txt ]; then pip install -r requirements_testing.txt; fi + pip install pytest coverage coverage-badge "setuptools<82.0.0" - name: Run tests with coverage run: | - coverage run --source=app -m pytest --ignore=tests + coverage run --source=geoprob_pipe -m pytest --ignore=_deprecated/tests coverage report -m if [ -f readme_images/coverage.svg ]; then rm readme_images/coverage.svg; fi coverage-badge -o readme_images/coverage.svg @@ -37,6 +36,7 @@ jobs: run: | git config --local user.email "action@github.com" git config --local user.name "GitHub Actions" + git pull git add . if ! git diff --cached --quiet; then git commit -m "Testing and coverage" diff --git a/.github/workflows/testing_pull_request.yml b/.github/workflows/testing_pull_request.yml new file mode 100644 index 00000000..44b8c765 --- /dev/null +++ b/.github/workflows/testing_pull_request.yml @@ -0,0 +1,34 @@ +name: Automated testing and coverage (during pull request) + + +on: + pull_request: + branches: [ "dev" ] + paths: + - 'geoprob_pipe/**' + - 'test_system.py' + workflow_dispatch: + + +jobs: + test: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: '3.12' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + if [ -f requirements_testing.txt ]; then pip install -r requirements_testing.txt; fi + pip install pytest coverage coverage-badge setuptools<82.0.0 + + - name: Run tests with coverage + run: | + coverage run --source=geoprob_pipe -m pytest --ignore=_deprecated/tests + coverage report -m diff --git a/.gitignore b/.gitignore index c9de3bca..67e1aad9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ +# GeoProb-Pipe +geoprob_pipe.ini +geoprob_pipe.log + # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] @@ -14,6 +18,8 @@ dist/ downloads/ eggs/ .eggs/ +workspaces/example_new_calculations/output/ +**/output/ lib/ lib64/ parts/ @@ -70,6 +76,7 @@ instance/ # Sphinx documentation docs/_build/ +docs/autoapi/ # PyBuilder .pybuilder/ @@ -169,4 +176,14 @@ _work_dir *.res #*.xlsx *.gdb -*.sqlite \ No newline at end of file +*.sqlite +!workspaces/traject_224/input/hlcd.sqlite +!workspaces/traject_224/input/WBI2017_Bovenrijn_224_v04.config.sqlite +!workspaces/traject_224/input/WBI2017_Bovenrijn_224_v04.sqlite +!geoprob_pipe/pre_processing/test_files/hrd_files/hlcd.sqlite +!geoprob_pipe/pre_processing/test_files/hrd_files/WBI2017_Bovenrijn_224_v04.config.sqlite +!geoprob_pipe/pre_processing/test_files/hrd_files/WBI2017_Bovenrijn_224_v04.sqlite +!tests/systeem_testen/224/hrd_files/hlcd.sqlite +!tests/systeem_testen/224/hrd_files/WBI2017_Bovenrijn_224_v04.config.sqlite +!tests/systeem_testen/224/hrd_files/WBI2017_Bovenrijn_224_v04.sqlite +tests/systeem_testen/224/exports/ diff --git a/README.md b/README.md index ddb9028b..842d49c2 100644 --- a/README.md +++ b/README.md @@ -1,73 +1,53 @@ ![Coverage](./readme_images/coverage.svg) # GeoProb-Pipe -Tool voor het parallel uitvoeren van probabilistische pipingberekeningen. De tool maakt gebruik van de probabilistische bibliotheek van Deltares. +Applicatie voor het uitvoeren van probabilistische piping berekeningen. De applicatie maakt gebruik van de probabilistische +bibliotheek van Deltares. Deze bibliotheek stuurt onder de motorkap de PTK-tool aan. -# Ontwikkeling -Deze repository is in ontwikkeling. In `dev_kernel_structure` worden de functionaliteiten ontwikkeld om de structuur van de database en de rekenkernel inclusief testen op te nemen. In `main` staan de functionaliteiten voor data invoer/uitvoer, de koppeling met de probabilitistische bibliotheek en het uitvoeren van de probabilistische som. # Contactpersonen + +Het GeoProb-Pipe-team bestaat uit de volgende personen + - Sander Kapinga, S.Kapinga@wsrl.nl - Laura van der Doef, L.vanderDoef@wshd.nl -- Martijn Kriebel, mkriebel@avecodebondt.nl +- Chris Pitzalis, ontwikkelaar, C.Pitzalis@wsrl.nl +- Vincent Jilesen, ontwikkelaar, V.Jilesen@wshd.nl + # Installatie -Deze tool in ontwikkeld met Python versie 3.12.5. -Installatie van de dependencies: -- Conda (aanbevolen, environment incl. correcte Python versie wordt automatisch aangemaakt): - - Methode 1: via Anaconda Navigator. Ga naar "environments" en importeer het .yml bestand. - - Methode 2: via Anaconda Prompt - ```console - # Install dependencies - conda env create -f environment.yml - - # Activate env - conda activate GeoProb-Pipe - ``` -- Pip (gebruiker moet zelf de environment aanmaken met juiste Python versie): - ```console - # Create environnment (note: use aforementioned supported Python version) - python -m venv GeoProb-Pipe - - # Activate env - GeoProb-Pipe/bin/activate - - # Install dependencies - pip install -r requirements.txt - ``` - -# Ontwikkeling - -- Pip (gebruiker moet zelf de environment aanmaken met juiste Python versie): - ```console - # Create environnment (note: use aforementioned supported Python version) - python -m venv GeoProb-Pipe - - # Activate env - GeoProb-Pipe/bin/activate - - # Install dependencies - pip install -r requirements.txt - pip install -r dev-requirements.txt - ``` +Op termijn wordt GeoProb-Pipe beschikbaar gesteld middels de Python Package Index (https://pypi.org) voor een eenvoudige +installatie via `pip install geoprob-pipe`. Voor nu is de installatie als volgt: -# Documentatie -De beschrijving van de rekenkernel is opgenomen in de documentatie. De documentatie kan worden gegeneerd door: + - Kloon de repository middels `git clone repo_weblink`. + - Maak een virtuele Python environment aan. Deze applicatie is ontwikkeld met Python versie 3.12. + - Installeer alle dependencies middels `pip install -r requirements.txt`. -windows: -```console -sphinx-build -M html docs\ docs\_build -``` # Quickstart -Tool wordt gestart door `main_piping.py` te runnen. +Start de applicatie als volgt + +- Vanuit de gekloonde repository met het commando `python -m geoprob_pipe.questionnaire.cmd startup_geoprob_pipe`. +- Wanneer de package/wheel geïnstalleerd is met het commando `geoprob-pipe`. + + +# Mee ontwikkelen +Wil je bijdragen aan de ontwikkeling van GeoProb-Pipe? Dat kan! :) + +Maak een nieuwe branch aan vanuit `dev`, ga coden en wanneer je klaar bent, maak een pull en review request aan. Zorg +er voor dat de unit tests werken en dat je PEP8 als code stijl hanteert. Bij vragen, neem contact op met één van de +ontwikkelaars. Voor PEP8, de IDE PyCharm heeft deze out of the box ingesteld. PyCharm is daarom de geadviseerde IDE. + + +# Documentatie +De documentatie genereer je middels het commando `sphinx-build -M html docs\ docs\_build`. Je vindt de +documentatie daarna terug in de map `GeoProb-Pipe\docs\_build\html\index.html`. Dit bestand opent in de browser. Tip: +voeg de documentatie toe aan je favorieten van de browser. -Benodigdheden: -- Een projectmap in "workspaces" (bijv. .../workspaces/my_project) met daarin een submap "input" (.../workspaces/my_project/input) -- De input-map bevat: - - input.xlsx (gebruik hiervoor het meegeleverde template input.xlsx) - - Unzipped HRD .sqlite (hydraulische database). Deze mag zowel in de input-map als in een submap staan. # Disclaimer -Het gebruik van deze tool gebeurt volledig op eigen risico. Door deze tool te gebruiken, accepteert de gebruiker volledige verantwoordelijkheid. De ontwikkelaars kunnen geen garanties geven over de werking, nauwkeurigheid of volledigheid van de tool, en kunnen op geen enkele manier verantwoordelijk worden gehouden voor eventuele fouten, schade, of verliezen die voortvloeien uit het gebruik van deze software. +Het gebruik van deze applicatie gebeurt volledig op eigen risico. Door deze applicatie te gebruiken, accepteert de +gebruiker volledige verantwoordelijkheid. Het GeoProb-Pipe-team kan geen garanties geven over de werking, +nauwkeurigheid of volledigheid van de applicatie, en kan op geen enkele manier verantwoordelijk worden gehouden voor +eventuele fouten, schade, of verliezen die voortvloeien uit het gebruik van deze software. diff --git a/app/classes/_old_fragility_curve.py b/app/classes/_old_fragility_curve.py deleted file mode 100644 index 39251eae..00000000 --- a/app/classes/_old_fragility_curve.py +++ /dev/null @@ -1,300 +0,0 @@ -from pathlib import Path - -import pandas as pd -import scipy.stats as stats -from scipy.stats import gumbel_r, norm - -from app.classes.dike_geometry import DikeGeometry -from app.classes.file_system import FileSystem -from app.classes.heave import Heave -from app.classes.line_geometry import LineGeometry -from app.classes.opbarsten import Opbarsten -from app.classes.subsoil import Subsoil -from app.classes.table import Table -from app.classes.terugschrijdende_erosie import Terugschr_erosie -from app.classes.toolkit import Toolkit -from app.classes.waterlevel_statistics import WaterlevelStatistics -from app.classes.workspace import Workspace -from app.helper_functions.fragility_curve_functions import ( - _densify_extrapolate_alphas, - _densify_extrapolate_betas, - calculate_design_point_beta, - calculate_design_point_waterlevel, - calculate_influence_factors_including_waterlevel, -) -from app.helper_functions.geodatabase_functions import process_geodatabase -from app.helper_functions.plotting_functions import ( - _plot_fragility_curve, - _plot_influence_factors, - _plot_multiple_fragility_curves, - _plot_waterlevel_statistics, -) - -# df_dike_geometry = pd.read_excel( -# r"V:\dr_Waterkeringen\08. Kennis\02. Probabilitische rekenen - werkmap\GeoProb-Pipe\testcase 20-4 STPH\Test_bestand_geoprob_pipe.xlsx", -# sheet_name="test_vak_par", -# ) - -# df_traject_par = pd.read_excel( -# r"V:\dr_Waterkeringen\08. Kennis\02. Probabilitische rekenen - werkmap\GeoProb-Pipe\testcase 20-4 STPH\Test_bestand_geoprob_pipe.xlsx", -# sheet_name="test_traject_par", -# index_col="Parameter", -# ) - -# df_general_par = pd.read_excel( -# r"V:\dr_Waterkeringen\08. Kennis\02. Probabilitische rekenen - werkmap\GeoProb-Pipe\testcase 20-4 STPH\Test_bestand_geoprob_pipe.xlsx", -# sheet_name="test_gen_par", -# index_col="Parameter", -# ) - - -class FragilityCurve: - """FragilityCurve class which carries out all actions required for generating a fragility curve and finding the design point""" - - def __init__( - self, - PATH_WORKSPACE: str | Path, - USE_EXISTING_TKX_RESULTS: bool, - CLEANUP_WORK_DIR: bool, - COMBINE_FRAGILITY_CURVES: bool, - FRAGILITY_CURVE_NON_FAILURE_ADJUSTMENT: bool, - NON_FAILURE_THRESHOLD: dict, - WATERLEVEL_RANGE: list[float], - MU: float, - SCALE: float, - ) -> None: - - # Initialize Workspace object - self.workspace = Workspace(PATH_WORKSPACE, USE_EXISTING_TKX_RESULTS) - - # Initialize Toolkit object - self.toolkit = Toolkit(self.workspace.input.folderpath, USE_EXISTING_TKX_RESULTS) - print("ABC") - - # def _start_heave_calculation(self): - # heave = Heave(self.dike_geometry, df_general_par.loc["i_toelaatbaar", "Waarde"]) - # return heave.fos_heave - - # def _start_terugschr_erosie_calculation(self): - # terugschr_erosie = Terugschr_erosie(self.dike_geometry, df_general_par) - # return terugschr_erosie.fos_terugschrijdende_erosie - - # # TODO voor nu wordt nog gdf_dikegeometry gebruikt, moet weg als tupple format hiervoor bekend is. (zie ook opbarsten.py) - # def _start_opbarsten_calculation(self): - # opbarsten = Opbarsten(self.dike_geometry, df_dike_geometry, df_general_par, df_general_par) - # return opbarsten.kritiek_stijgh_verschil - - # # Calculate fragility curve - # if USE_EXISTING_TKX_RESULTS: - # print( - # f"INFO: USE_EXISTING_TKX_RESULTS=True, so no new calculations are started. Instead, the .tkx files in the specified output folder ({self.workspace.folderpath}) are used." - # ) - # self.workspace.map_precalculated_tkx_input_stix(self.toolkit.settings.ptk_server_path) - # self.toolkit._use_precalculated_results(self.dstability.overview, self.workspace.mapping_tkx_stix) - # else: - # self.toolkit._use_new_calculations( - # self.dstability.overview, - # self.workspace.output.folderpath, - # self.workspace.work_dir.folderpath, - # CLEANUP_WORK_DIR, - # ) - # self.workspace.update_output_filesystem() # Update output FileSystem object because new output .tkx files were generated - - # # Initialize WaterlevelStatistics object - # self.waterlevel_statistics = WaterlevelStatistics(MU, SCALE, WATERLEVEL_RANGE) - - # # Interpolate and extrapolate the reliability index and alpha values between and beyond fragility curve points - # self._betas_densified_extrapolated = _densify_extrapolate_betas( - # self.waterlevel_statistics.waterlevel_array, - # self.betas, - # ) - # self._alphas_densified_extrapolate = _densify_extrapolate_alphas( - # self.waterlevel_statistics.waterlevel_array, self.alphas - # ) - - # # Convert interpolated/extrapolated reliability indices to failure probabilities - # self._failure_probabilities_densified_extrapolated = self._betas_densified_extrapolated.copy(deep=True) - # self._failure_probabilities_densified_extrapolated["Pf_h"] = norm.cdf( - # -1 * self._failure_probabilities_densified_extrapolated["beta"] - # ) # P(f|h) = Φ[−𝛽(ℎ)] - # self._failure_probabilities_densified_extrapolated.drop(labels="beta", axis=1, inplace=True) - - # # FIXME add option to modify FCs with a non-failure threshold/adjustment - # if FRAGILITY_CURVE_NON_FAILURE_ADJUSTMENT or NON_FAILURE_THRESHOLD: - # raise NotImplementedError() - - # # FIXME add functionality to combine FCs - # if COMBINE_FRAGILITY_CURVES: - # raise NotImplementedError() - - # # Obtain design point - # self.design_point = DesignPoint( - # self._failure_probabilities_densified_extrapolated, - # self._alphas_densified_extrapolate, - # self.waterlevel_statistics, - # ) - - @property - def waterlevels(self) -> pd.DataFrame: - """ - Returns: - dict: waterlevel for each .stix, shown in dict-format as {path_to_stix: waterlevel} - """ - return self.toolkit.overview[["waterlevel", "stix", "tkx"]] - - @property - def betas(self) -> pd.DataFrame: - """ - Returns: - pd.DataFrame: beta values (reliability indices) for each waterlevel - """ - return self.toolkit.results.betas - - @property - def alphas(self) -> pd.DataFrame: - """ - Returns: - pd.DataFrame: alpha values of variables for each waterlevel - """ - return self.toolkit.results.alphas - - @property - def influence_factors(self) -> pd.DataFrame: - """ - Returns: - pd.DataFrame: influence factors (squared alpha values) of variables for each waterlevel - """ - return self.toolkit.results.influence_factors - - @property - def variables(self) -> pd.DataFrame: - """ - Returns: - pd.DataFrame: distribution parameters per variable for each waterlevel - """ - return self.toolkit.results.variables - - def plot_fragility_curve(self) -> None: - """Plotting functions for fragility curve""" - _plot_fragility_curve( - self.toolkit.results.betas, - self._failure_probabilities_densified_extrapolated, - self.workspace.output.folderpath, - show_save=True, - ) - - def plot_waterlevel_statistics(self) -> None: - """Plot interpolated/extrapolated fragility curve together with waterlevel statistics""" - _plot_waterlevel_statistics( - self.betas, - self._betas_densified_extrapolated, - self.waterlevel_statistics, - self.workspace.output.folderpath, - design_point_beta=self.design_point.beta, - ) - - def plot_multiple_fragility_curves(self) -> None: - """Plotting functions for multiple fragility curves""" - # _plot_multiple_fragility_curves(self.toolkit.results.overview["waterlevel"], self.toolkit.results.overview["beta"], show=True) - raise NotImplementedError("Functionality to plot multiple fragility curves is not implemented yet!") - - def plot_influence_factors(self) -> None: - """Plotting functions for influence factors""" - df_design_point_influence_factors = self.design_point.influence_factors[ - "influence factor including waterlevel" - ].to_frame() - - df_design_point_influence_factors.rename( - columns={"influence factor including waterlevel": "influence factor"}, inplace=True - ) - - df_influence_factors_concat = pd.concat([self.influence_factors, df_design_point_influence_factors]) - _plot_influence_factors(df_influence_factors_concat.sort_index(level="waterlevel")) - - -class DesignPoint: - """The design point (ontwerppunt) is the waterlevel of the point on the limit state line (Z=0, grenstoestandslijn) is the point on the - limit state line (Z=0, grenstoestandslijn) that has the highest probability of occurrence (most probable combination of strength and load parameters). - To find the design point, we integrating (uitintegreren) the conditional failure probability (fragility curve) over the entire range of possible water - levels, weighted by the probability density function (PDF) of the water levels. This results in a "total" (/design point) failure probability with - corresponding reliability index. For this design point, the corresponding waterlevel and alpha values can then be found. - - This class determines the following: - 1. Reliability index (beta) of the design point - 2. Waterlevel of the design point - 3. Influence factors of the variables for the design point, including the influence factor of the waterlevel - """ - - def __init__( - self, - failure_probabilities_densified_extrapolated: pd.DataFrame, - alphas_densified_extrapolate: pd.DataFrame, - waterlevel_statistics: WaterlevelStatistics, - ) -> None: - """ "Initialize DesignPoint (ontwerppunt) instance. - - Args: - failure_probabilities_densified_extrapolated (pd.DataFrame): interpolated/extrapolated set of failure probabilities - alphas_densified_extrapolate (pd.DataFrame): interpolated/extrapolated set of alpha values - waterlevel_statistics (WaterlevelStatistics): WaterlevelStatistics class which stores data related to the waterlevels statistics (Gumbel fit) - """ - - self._beta, self._Pf = calculate_design_point_beta( - failure_probabilities_densified_extrapolated, - waterlevel_statistics, - ) - - self._waterlevel = calculate_design_point_waterlevel(waterlevel_statistics, self._Pf) - - self._influence_factors = calculate_influence_factors_including_waterlevel( - alphas_densified_extrapolate, - self.waterlevel, - waterlevel_statistics, - self.beta.squeeze(), - ) - - @property - def waterlevel(self) -> float: - """ - Returns: - float: waterlevel of the design point - """ - return self._waterlevel - - @property - def beta(self) -> pd.DataFrame: - """ - Returns: - pd.DataFrame: reliability index (beta) at the design point waterlevel - """ - return pd.DataFrame({"beta": [self._beta]}, index=[self.waterlevel]).rename_axis("waterlevel") - - @property - def Pf(self) -> pd.DataFrame: - """ - Returns: - pd.DataFrame: probability of failure at the design point waterlevel - """ - return pd.DataFrame({"Pf": [self._Pf]}, index=[self.waterlevel]).rename_axis("waterlevel") - - @property - def alphas(self) -> pd.DataFrame: - """ - Returns: - pd.DataFrame: alpha values of variables (including and excluding the waterlevel) for the design point - """ - return (self.influence_factors["inf. factor excluding waterlevel"] ** 0.5).to_frame() - - @property - def influence_factors(self) -> pd.DataFrame: - """ - Returns: - pd.DataFrame: influence factor (including and excluding the waterlevel) for the design point - """ - return self._influence_factors - return (self.alphas**2).rename( - columns={ - "alpha excluding waterlevel": "influence factor excluding waterlevel", - "alpha including waterlevel": "influence factor including waterlevel", - } - ) diff --git a/app/classes/_old_toolkit_results.py b/app/classes/_old_toolkit_results.py deleted file mode 100644 index 1b376cae..00000000 --- a/app/classes/_old_toolkit_results.py +++ /dev/null @@ -1,130 +0,0 @@ -import math -from pathlib import Path - -import pandas as pd - -from app.classes.toolkit_native_model import ToolkitNative, ToolkitProject -from app.helper_functions.toolkit_functions import load_tkx_file - - -class ToolkitResults: - """ToolkitResults class containing the results of the Probabilistic Toolkit calculations""" - - def __init__(self, toolkit_overview: pd.DataFrame, path_ptk_server: Path) -> None: - """Initialize ToolkitResults instance containing the results of the Probabilistic Toolkit calculations - - Args: - toolkit_overview (pd.DataFrame): general overview of the calculated .tkx files and their corresponding .stix files and parsed D-Stability models - path_ptk_server (Path): path to PTK server executable (Deltares.Probabilistic.Server.exe). - """ - self.overview = self._get_results(toolkit_overview, path_ptk_server) - self._valid_results() - - @property - def betas(self) -> pd.DataFrame: - """ - Returns: - pd.DataFrame: waterlevels and corresponding beta values (reliability indices) - """ - return self.overview[["waterlevel", "beta"]].set_index("waterlevel") - - @property - def variables(self) -> pd.DataFrame: - """ - Returns: - pd.DataFrame: distribution parameters per variable for each waterlevel - """ - return pd.concat( - self.overview["variable"].values, keys=self.overview["waterlevel"], names=["waterlevel", "variable"] - ) - - @property - def alphas(self) -> pd.DataFrame: - """ - Returns: - pd.DataFrame: alpha values per variable for each waterlevel - """ - return pd.DataFrame(self.variables["alpha"]) # type: ignore - - @property - def influence_factors(self) -> pd.DataFrame: - """ - Returns: - pd.DataFrame: influence factor (which is the squared alpha value) for each waterlevel - """ - return (self.alphas**2).rename(columns={"alpha": "influence factor"}) - - def _get_variables(self, tkx: ToolkitProject) -> pd.DataFrame: - """Get all variables and corresponding distribution parameters - - Args: - tkx (ToolkitProject): ToolkitProject object - - Returns: - pd.DataFrame: overview of variables and corresponding distribution parameters - """ - rows = [] - for variable in tkx.model.variables: - rows.append( - { - "variable": variable.name, - "distribution": variable.distribution, - "mean": variable.mean, - "sigma dev": variable.deviation, - "alpha": tkx.design_point.get_alpha(variable).alpha_value, - } - ) - return pd.DataFrame(rows).set_index("variable") - - def _get_reliability_index(self, tkx: ToolkitProject) -> float: - """Get calculated beta value (reliability index) of the PTK calculation - - Args: - tkx (ToolkitProject): ToolkitProject object - - Returns: - float: beta value (reliability index) - """ - return tkx.design_point.reliability_index - - def _valid_results(self) -> None: - """Checks whether the PTK calculation results are valid""" - sum_squared_alphas = self.alphas["alpha"].pow(2).groupby(level="waterlevel").sum() - - if not sum_squared_alphas.apply(lambda x: math.isclose(x, 1)).all(): - with pd.option_context("display.float_format", "{:.9f}".format): - # Make sure that the floats in the DataFrame are printed with up to 9 digits to facilitate - # inspection by the user - print( - f"\nWARNING: The sum of squared alpha's of each waterlevel should equal 1. This is not the case:\n{pd.DataFrame(sum_squared_alphas)}" - ) - - def _get_results(self, toolkit_overview: pd.DataFrame, path_ptk_server: Path) -> pd.DataFrame: - """Adds the PTK calculations results to the overview with general information of the PTK calculations - - Args: - toolkit_overview (pd.DataFrame): overview with general information of the PTK calculations (e.g. tkx filepaths and corresponding stix files and waterlevels) - path_ptk_server (Path): path to PTK server executable (Deltares.Probabilistic.Server.exe). - - Returns: - pd.DataFrame: overview with PTK calculations results - """ - results_overview = toolkit_overview.copy(deep=True) - - list_beta = [] - list_variables = [] - - for output_tkx in results_overview["tkx"]: - tkx = load_tkx_file(path_ptk_server, output_tkx["path"]) - - list_beta.append(self._get_reliability_index(tkx)) - list_variables.append(self._get_variables(tkx)) - - results_overview["beta"] = list_beta - results_overview["variable"] = list_variables - - # Return the DataFrame and make sure the waterlevels, betas and variables are shown as the first columns - return results_overview[ - ["waterlevel", "beta", "variable"] - + [col for col in results_overview.columns if col not in ["waterlevel", "beta", "variable"]] - ] diff --git a/app/classes/base_collection.py b/app/classes/base_collection.py deleted file mode 100644 index 3d6571e4..00000000 --- a/app/classes/base_collection.py +++ /dev/null @@ -1,151 +0,0 @@ -from __future__ import annotations # makes all annotations lazy (no quotes needed) - -from itertools import islice -from typing import TYPE_CHECKING, Generic, Iterator, TypeVar, Union - -if TYPE_CHECKING: - from app.classes.ondergrond_scenario import OndergrondScenario - from app.classes.uittredepunt import Uittredepunt - from app.classes.vak import Vak - from app.classes.overschrijdingsfrequentielijn import Overschrijdingsfrequentielijn -T = TypeVar("T") - -class BaseCollection(Generic[T]): - """ - A generic base class for managing a collection of items, each identified - by a unique string ID. This class provides common functionality for adding, - retrieving, iterating, and accessing items in the collection. - - Check the __repr__ attribute for examples regarding accessing data - - Attributes: - _items (dict): A dictionary that stores items using their unique string - ID as the key and the item object as the value. - - Methods: - __init__(): Initializes the collection. - __repr__(): Returns a string representation of the collection for easy inspection. - __getitem__(index: Union[str, int, slice]): Allows retrieving an item by its ID (str), - index (int), or slice (slice). - __iter__(): Returns an iterator for iterating over all items in the collection. - __len__(): Returns the number of items in the collection. - __contains__(id: str): Checks if an item with the given ID exists in the collection. - add(id: str, obj: T): Adds an item to the collection, using the specified - ID. Overwrites any existing item with the same ID. - keys(): Returns a list of all item IDs in the collection. - values(): Returns a list of all items in the collection. - items(): Returns a list of tuples, each containing an item ID and its corresponding object. - """ - - def __init__(self) -> None: - self._items: dict[str, T] = {} - - # Magic methods - def __repr__(self) -> str: - - # Header text - lines = [f"{self.__class__.__name__} with {len(self)} items:"] - - ## Text regarding instances within collection - SHOW_NUMBER_ATTRIBUTES = 2 # Defines number of attributes to show (to prevent long prints) - SHOW_NUMBER_SUBATTRIBUTES = 4 # Defines number of subattributes (i.e. attributes of attributes) to show (to prevent long prints) - def _show_limited_subattributes(instance: T) -> str: - attrs = list(instance.__dict__.items())[:SHOW_NUMBER_SUBATTRIBUTES] - return ", ".join(f"{ak}={repr(av)}" for ak, av in attrs) - - lines.append(" {") - for _, instance in islice(self._items.items(), SHOW_NUMBER_ATTRIBUTES): - lines.append(f" {instance.__class__.__name__}({_show_limited_subattributes(instance)}, ...)") - lines.append(" ...") - lines.append(" }") - - # Text with examples for accessing by ID, index and slice - lines.append("\nMethods to access items:") - lines.append(f" By ID: {self.__class__.__name__}['{self[0].id}'] (NOTE: ID should be given as string!) -> {self[0].__class__.__name__}({(_show_limited_subattributes(self._items[str(self[0].id)]))}, ...)") - lines.append(f" By collection index: {self.__class__.__name__}[0] -> {self[0].__class__.__name__}({_show_limited_subattributes(self[0])}, ...)") - if len(self) > 1: - lines.append(f" By slicing the collection: {self.__class__.__name__}[0:2] -> [" + - ", ".join( - f"{instance.__class__.__name__}({_show_limited_subattributes(instance)}, ...)" - for instance in self[0:2] - ) + "]") - return "\n".join(lines) - - def __getitem__(self, index: Union[str, int, slice]) -> Union[T, list[T]]: - if isinstance(index, int): # Handle integer indexing - return list(self._items.values())[index] - elif isinstance(index, slice): # Handle slicing - return list(self._items.values())[index] - elif isinstance(index, str): # Handle string-based ID lookup - return self._items[index] - else: - raise TypeError("Invalid index type") - - def __iter__(self) -> Iterator[T]: - return iter(self._items.values()) - - def __len__(self) -> int: - return len(self._items) - - def __contains__(self, id: str) -> bool: - return id in self._items - - # Normal methods - def add(self, id: str, obj: T) -> None: - self._items[str(id)] = obj - - def keys(self) -> list[str]: - return list(self._items.keys()) - - def values(self) -> list[T]: - return list(self._items.values()) - - def items(self) -> list[tuple[str, T]]: - return list(self._items.items()) - -def _pretty_repr(self: Vak | Uittredepunt | OndergrondScenario | Overschrijdingsfrequentielijn) -> str: - def format_value(v, indent=2): - spacer = ' ' * indent - - # Special case 1: Single instance of Vak/Uittredepunt/OndergrondScenario/Overschrijdingsfrequentielijn - if type(v).__name__ in ("Vak", "Uittredepunt", "OndergrondScenario"): - return format_instance(v, indent) - - # Special case 2: List of Uittredepunt or OndergrondScenario - if isinstance(v, list) and v and type(v[0]).__name__ in ("Uittredepunt", "OndergrondScenario"): - sliced = v[:2] - body = ''.join( - f'{spacer}{format_instance(item, indent + 1)}\n' - for item in sliced - ) - return '[\n' + body + f'{spacer}...]\n' - - # Regular dict - elif isinstance(v, dict): - return '{\n' + ''.join( - f'{spacer}{k}: {format_value(val, indent + 1)}\n' - for k, val in v.items() - ) + ' ' * (indent - 1) + '}' - - # Recursively format objects with __dict__ - elif hasattr(v, '__dict__'): - return format_value(v.__dict__, indent) - - # Fallback - else: - return repr(v) - - def format_instance(obj, indent=2): - spacer = ' ' * indent - items = list(obj.__dict__.items())[:4] - body = ''.join( - f'{spacer}{k}: {format_value(val, indent + 1)}\n' - for k, val in items - ) - return f'{obj.__class__.__name__}(\n{body}{spacer}...)\n{spacer[:-4]})' - - return ( - f"{self.__class__.__name__}(\n" + - ''.join(f' {k}: {format_value(v)}\n' for k, v in self.__dict__.items()) + - ")" - ) diff --git a/app/classes/ondergrond_scenario.py b/app/classes/ondergrond_scenario.py deleted file mode 100644 index 2fc7fc5b..00000000 --- a/app/classes/ondergrond_scenario.py +++ /dev/null @@ -1,98 +0,0 @@ -from types import SimpleNamespace - -import pandas as pd - -from app.classes.base_collection import BaseCollection, _pretty_repr -from app.classes.vak import Vak, VakCollection -from app.helper_functions.data_validation import ( - check_attribute_already_exists, - check_attribute_in_overview, - enforce_lower_upper_bounds, -) -from app.helper_functions.parameter_functions import ( - generate_parameter_dict_for_variable, - strip_suffix_from_list_parameter_names, -) - - -class OndergrondScenario: - - # Metadata attributes of the OndergrondScenario class. These are stored as class-level type hints to make the attributes visible to static type checkers (e.g. Pylance). - # The actual values are set dynamically in __init__ using setattr and a list of values. - ondergrondscenario_id: int # Note: this is a renamed version of ondergrondscenario_id - vak_id: int - ondergrondscenario_naam: str - - - # Other class-level typehints - id: int # Renamed version of ondergrondscenario_id - - def __init__(self, df_row: pd.Series, vak: Vak, df_overview_parameters: pd.DataFrame, input_parameter_names_without_suffix: list[str]) -> None: - - # Add each input parameter to the OndergrondScenario instance - for attr_name_without_suffix in input_parameter_names_without_suffix: - check_attribute_already_exists(self, attr_name_without_suffix) - check_attribute_in_overview(attr_name_without_suffix, df_overview_parameters) - - df_overview_row = df_overview_parameters.loc[attr_name_without_suffix] # Select relevant row from the parameter overview - - if df_overview_row["parameter_type"] == "metadata": - # Metadata should be set on the OndergrondScenario instance directly - name = "id" if attr_name_without_suffix == "ondergrondscenario_id" else attr_name_without_suffix # Rename ondergrondscenario_id to id to simplify the attribute name - setattr(self, name, df_row[attr_name_without_suffix]) - - elif df_overview_row["parameter_type"] in ["variable", "constant"]: - # Variables and constants should be set on the variables attribute of the OndergrondScenario instance - if not hasattr(self, "variables"): - # Create a SimpleNamespace to hold the variables/constants of this OndergrondScenario instance - self.variables = SimpleNamespace() - - # Generate input_dict for the variable or constant. This is a dictionary containing the parameters (e.g. mean, stdev/vc, etc.) - # All input dicts will be stored in the variables attribute of the OndergrondScenario instance - # This function also calls a helper function to enforce lower and upper bounds on the variable - input_dict = generate_parameter_dict_for_variable(attr_name_without_suffix, - df_overview_row=df_overview_row, - df_row=df_row) - - setattr(self.variables, attr_name_without_suffix, input_dict) - - - self.vak = vak # Link the corresponding Vak instance to this OndergrondScenario instance - - - def __repr__(self) -> str: - return _pretty_repr(self) - - -class OndergrondScenarioCollection(BaseCollection[OndergrondScenario]): - def __init__(self, df_ondergrond_scenarios: pd.DataFrame, vak_collection: VakCollection, df_overview_parameters: pd.DataFrame) -> None: - super().__init__() # Initialize the base collection - self.df = df_ondergrond_scenarios - - # Get unique column names from the df (without suffix) - input_parameter_names_without_suffix = strip_suffix_from_list_parameter_names(self.df.columns) - - # Create ondergrondscenarios from df. Note that the created OndergrondScenario is linked to the corresponding Vak - for _, row in self.df.iterrows(): - - ondergrond_scenario_id = row["ondergrondscenario_id"] - - # Perform checks - try: - vak = vak_collection[str(row["vak_id"])] - except KeyError: - # If the vak_id is not found in the vak_collection, raise an error - raise KeyError(f"Vak ID '{row["vak_id"]}' (corresponding to scenario '{ondergrond_scenario_id}') not found in VakCollection") - - if any(punt.id == ondergrond_scenario_id for punt in vak.ondergrond_scenarios): - # Check for duplicate ondergrondscenario_id within the same Vak - raise ValueError(f"Duplicate ondergrondscenario_id: scenario '{ondergrond_scenario_id}' already exists in vak '{vak.id}'") - - # Create OndergrondScenario instance - scenario = OndergrondScenario(row, vak, df_overview_parameters, input_parameter_names_without_suffix) - - # Add OndergrondScenario instance as attribute to the corresponding Vak instance - vak.ondergrond_scenarios.append(scenario) - - # Add OndergrondScenario instance to the collection - self.add(str(scenario.id), scenario) \ No newline at end of file diff --git a/app/classes/overschrijdingsfrequentielijn.py b/app/classes/overschrijdingsfrequentielijn.py deleted file mode 100644 index 82026e2e..00000000 --- a/app/classes/overschrijdingsfrequentielijn.py +++ /dev/null @@ -1,49 +0,0 @@ -from pathlib import Path - -import pydra_core as pydra - -from app.classes.base_collection import BaseCollection, _pretty_repr -from app.classes.uittredepunt import UittredepuntCollection - - -class Overschrijdingsfrequentielijn: - def __init__(self, HRD_PATH: Path, hydra_locatie_id: str): - - self.id = hydra_locatie_id - self.overschrijdingsfrequentielijn = self._calculate_overschrijdingsfrequentielijn(HRD_PATH, hydra_locatie_id) - - def _calculate_overschrijdingsfrequentielijn(self, HRD_PATH: Path, hydra_locatie_id: str): - # Read HRD - hrd = pydra.HRDatabase(HRD_PATH) - - # Setup calculation object exceedance frequency line - fl = pydra.ExceedanceFrequencyLine("h") - - # Setup location - settings = hrd.get_settings(hydra_locatie_id) - location = hrd.create_location(settings) - - # Calculate exceedance frequency line for the location - frequency_line = fl.calculate(location) - - return frequency_line - - def __repr__(self) -> str: - return _pretty_repr(self) - - -class OverschrijdingsfrequentielijnCollection(BaseCollection[Overschrijdingsfrequentielijn]): - def __init__(self, HRD_PATH: Path, uittredepunt_collection: UittredepuntCollection) -> None: - super().__init__() # Initialize the base collection - self.HRD_PATH = HRD_PATH - - # Create Overschrijdingsfrequentielijn for each hydra_locatie_id in the UittredepuntCollection - # Since the calculations for Overschrijdingsfrequentielijn might take a while, we only calculate it once per unique hydra_locatie_id - # and later assign it to the corresponding Uittredepunt instances. - unique_hydra_locatie_ids = list(set(uittredepunt.hydra_locatie_id for uittredepunt in uittredepunt_collection)) - for hydra_locatie_id in unique_hydra_locatie_ids: - self.add(hydra_locatie_id, Overschrijdingsfrequentielijn(self.HRD_PATH, hydra_locatie_id)) - - # Assign the correct Overschrijdingsfrequentielijn to each Uittredepunt - for uittredepunt in uittredepunt_collection: - uittredepunt.overschrijdingsfrequentielijn = self[uittredepunt.hydra_locatie_id] diff --git a/app/classes/project.py b/app/classes/project.py deleted file mode 100644 index b63279b8..00000000 --- a/app/classes/project.py +++ /dev/null @@ -1,124 +0,0 @@ - -from dataclasses import dataclass -from pathlib import Path - -import pandas as pd -from pandas.api.types import CategoricalDtype -from probabilistic_library.reliability import Settings - -from app.classes.ondergrond_scenario import OndergrondScenarioCollection -from app.classes.overschrijdingsfrequentielijn import ( - OverschrijdingsfrequentielijnCollection, -) -from app.classes.uittredepunt import UittredepuntCollection -from app.classes.vak import VakCollection -from app.classes.workspace import Workspace -from app.helper_functions.calculation_helpers import ( - build_and_run_combined_calculations, - build_and_run_unique_model_calculations, -) -from app.helper_functions.data_validation import ( - checks_input_parameters, - checks_overview_parameters, -) -from app.helper_functions.statistics_utils import convert_failure_probability_to_beta -from app.helper_functions.z_functions import calc_Z_h, calc_Z_p, calc_Z_u - - -@dataclass -class _DataClassResults: - """Used for dot-accessing the calculation results - """ - unique: pd.DataFrame - combined_models: pd.DataFrame - uittredepunt: pd.DataFrame - - -class Project(): - """ Project class """ - def __init__(self, PATH_WORKSPACE: str|Path) -> None: - - # Initialize Workspace object (also checks if input/output folders contain all necessary files) - self.workspace = Workspace(PATH_WORKSPACE) - print("\nINFO: workspace (I/O folders) successfully processed") - - # Read overview data of parameters from input Excel file (includes e.g. upper and lower bounds, type of distribution, etc.) and carry out checks - self.df_overview_parameters = pd.read_excel(self.workspace.excel_path, sheet_name="Overzicht_parameters", index_col=0, header=0).rename(columns=lambda x: x.strip()) - checks_overview_parameters(self.df_overview_parameters) - - # Read input data of vakken, uittredepunten and ondergrondscenarios data from input Excel file and carry out checks. - # Note that the df's are not set on self (Project) but are added below to VakCollection/UittredepuntCollection/OndergrondScenarioCollection - # Strip trailing whitespace in column names. Also, unused ondergrondscenario's (ondergrondscenario_kans=Nan or ondergrondscenario_kans=0) are removed since these are not relevant - df_vakken = pd.read_excel(self.workspace.excel_path, sheet_name="Vakken").rename(columns=lambda x: x.strip()) - df_uittredepunten = pd.read_excel(self.workspace.excel_path, sheet_name="Uittredepunten").rename(columns=lambda x: x.strip()) - df_ondergrond_scenarios = pd.read_excel(self.workspace.excel_path, sheet_name="Ondergrondscenarios").rename(columns=lambda x: x.strip()).dropna(subset=['ondergrondscenario_kans']).loc[lambda x: x['ondergrondscenario_kans'] != 0] - checks_input_parameters(self.df_overview_parameters, df_vakken, df_uittredepunten, df_ondergrond_scenarios) - print(f"INFO: parameter data successfully loaded from `{self.workspace.excel_path.name}`") - - # Initialize collections. Note that UittredepuntCollection and OndergrondscenarioCollection link the - # instances of Uittredepunt and OndergrondScenario to the corresponding Vak instance - self.vak_collection = VakCollection(df_vakken, self.df_overview_parameters) - self.uittredepunt_collection = UittredepuntCollection(df_uittredepunten, self.vak_collection, self.df_overview_parameters) - self.ondergrond_scenario_collection = OndergrondScenarioCollection(df_ondergrond_scenarios, self.vak_collection, self.df_overview_parameters) - self.overschrijdingsfrequentielijn_collection = OverschrijdingsfrequentielijnCollection(self.workspace.hrd_path, self.uittredepunt_collection) - print(f"INFO: HRD .sqlite file successfully loaded from `{self.workspace.hrd_path.name}`") - - # Read calculation settings from Excel file - self.df_settings = pd.read_excel(self.workspace.excel_path, sheet_name="Settings", index_col=0, header=0) - print(f"INFO: settings successfully loaded from `{self.workspace.excel_path.name}`") - print(f"INFO: full list of available settings (set these in `{self.workspace.excel_path.name}`):\n{Settings().__dir__()}") - - # Build and run ReliabilityCalculations objects (= combinations of uittredepunten, ondergrondscenarios) for each model (uplift/heave/piping). - # Note: due to limitations in the probabilistic_library, we cannot first set up all calculations and then run them. After setting up calculations for each model (uplift/heave/piping), we need to run them immediately before setting up the next model. - self._calculations_unique = { - "uplift": build_and_run_unique_model_calculations(calc_Z_u, self.vak_collection, self.df_overview_parameters, self.df_settings), - "heave": build_and_run_unique_model_calculations(calc_Z_h, self.vak_collection, self.df_overview_parameters, self.df_settings), - "piping": build_and_run_unique_model_calculations(calc_Z_p, self.vak_collection, self.df_overview_parameters, self.df_settings), - } - - # Use the probabilistic_library to combine the calculations of the separate models (uplift/heave/piping) into one beta/failure probability for each uittredepunt and ondergrondscenario combination - self._calculations_combined_models = self._combined_df_calculations_unique_model.groupby(["uittredepunt_id", "ondergrondscenario_id"]).apply(lambda df_group: build_and_run_combined_calculations(df_group, self.uittredepunt_collection[str(df_group.name[0])], self.ondergrond_scenario_collection[str(df_group.name[1])])).reset_index(drop=True) - - # Use the chances of the underlying scenarios to calculate the combined failure probability for each uittredepunt - self._calculations_uittredepunt = self._calculations_combined_models.assign(combined_failure_probability=self._calculations_combined_models.apply(lambda row: row['failure_probability'] * row['reliability_calculation'].ondergrond_scenario.variables.ondergrondscenario_kans["value"], axis=1)).groupby('uittredepunt_id', as_index=False)['combined_failure_probability'].sum() - self._calculations_uittredepunt["beta"] = self._calculations_uittredepunt["combined_failure_probability"].apply(lambda failure_prob: convert_failure_probability_to_beta(failure_prob)) - - print("INFO: calculations were performed successfully") - - - @property - def results(self) -> _DataClassResults: - """Returns a dataclass with dot-access to the results of the unique model calculations (uplift/heave/piping) and of the combined calculations.""" - return _DataClassResults( - unique = self._combined_df_calculations_unique_model, - combined_models = self._calculations_combined_models, - uittredepunt = self._calculations_uittredepunt - ) - - - @property - def _combined_df_calculations_unique_model(self) -> pd.DataFrame: - """Merge the DataFrames of the unique model calculations (uplift/heave/piping) into a single DataFrame for convenient access. - - Returns: - pd.DataFrame: containing the results of the unique model calculations, sorted by uittredepunt, ondergrondscenario and model type (uplift/heave/piping). - """ - - # Store the model type in a new column - df_unique_model_results = pd.concat( - [df.assign(model=key) for key, df in self._calculations_unique.items()], - ignore_index=True - ) - - # Sort DataFrame of all ReliabilityCalculations by model using custom order uplift, heave and piping - df_unique_model_results["model"] = df_unique_model_results["model"].astype(CategoricalDtype(categories=["uplift", "heave", "piping"], ordered=True)) - df_unique_model_results = df_unique_model_results.sort_values( - by=["uittredepunt_id", "ondergrondscenario_id", "model"] - ).reset_index(drop=True) - - # Make sure that the columns are in a specific order for easier access - known = ["uittredepunt_id", "uittredepunt", "ondergrondscenario_id", "ondergrondscenario", "model", "reliability_calculation"] - df_unique_model_results = df_unique_model_results[known + [col for col in df_unique_model_results.columns if col not in known]] - - return df_unique_model_results - diff --git a/app/classes/reliability_calculation.py b/app/classes/reliability_calculation.py deleted file mode 100644 index 31ff8a22..00000000 --- a/app/classes/reliability_calculation.py +++ /dev/null @@ -1,215 +0,0 @@ -import inspect -from abc import ABC, abstractmethod -from types import SimpleNamespace -from typing import Any, Callable - -import numpy as np -import pandas as pd -from misc._default_values_constants import ALLOWED_DISPERSION_TYPES -from pandas import DataFrame -from probabilistic_library import CombineProject, FragilityValue, ReliabilityProject -from probabilistic_library.reliability import Settings -from probabilistic_library.utils import FrozenList - -from app.classes.ondergrond_scenario import OndergrondScenario -from app.classes.uittredepunt import Uittredepunt -from app.helper_functions.data_validation import enforce_lower_upper_bounds -from app.helper_functions.parameter_functions import ( - generate_parameter_dict_for_constant, -) - - -class ResultsTemplate(ABC): - @property - def settings(self) -> SimpleNamespace: - """Return the settings of the reliability project as a SimpleNamespace object, which includes the settings DataFrame (simple overview) and the Settings object (actually used in ReliabilityProject).""" - return SimpleNamespace(df=self.df_settings, obj=self.reliability_project.settings) - - - @property - def variables(self) -> FrozenList: - return self.reliability_project.variables - - - @property - def design_point(self): - return self.reliability_project.design_point - - - @property - def beta(self): - return self.design_point.reliability_index - - - @property - def alphas(self): - return {a.identifier: a.alpha for a in self.design_point.alphas.get_list()} - - - @property - def influence_factors(self): - return {a.identifier: a.influence_factor for a in self.design_point.alphas.get_list()} - - - @property - def is_converged(self): - return self.design_point.is_converged - - - -class ReliabilityCalculation(ResultsTemplate): - """ReliabilityCalculation class for calculations of either the uplift, heave or piping model for each unique uittredepunt-ondergrondscenario combination.""" - - def __init__(self, uittredepunt: Uittredepunt, ondergrond_scenario: OndergrondScenario, model: Callable, df_constants: pd.DataFrame, df_settings: pd.DataFrame) -> None: - - self.id = {"uittredepunt": uittredepunt.id, "ondergrondscenario": ondergrond_scenario.id, "model": model.__name__} - self.uittredepunt = uittredepunt - self.ondergrond_scenario = ondergrond_scenario - self.model = model - self.constants = df_constants - self.df_settings = df_settings - - # Setup ReliabilityProject - self.reliability_project = ReliabilityProject() - - # Calculation settings - self._setup_settings(df_settings) - - # Model & Variables - # First the model (Z-function that will be run) must be set, since the probabilistic_library defines the variables of a ReliabilityProject - # based on the input args of the evaluated model function. Other args (i.e. variables from the input Excel) are not allowed, so we need to know which - # input args the current model requires so we can add the relevant variables. - self.reliability_project.model = self.model - - # Buitenwaterstand (from Overschrijdingsfrequentielijn) - # Special variable since it comes from Pydra (and not the input Excel file), so it is set separately - self._set_buitenwaterstand_overschrijdingsfrequentielijn(self.uittredepunt) - list_assigned_parameters = ["buitenwaterstand"] # Keep track of the parameters that were assigned to the ReliabilityProject - - # Variables - list_assigned_parameters += self._setup_variables(self.uittredepunt, self.ondergrond_scenario) - - # Constants - list_assigned_parameters += self._setup_constants() - - # Make sure all variables and constants are set in the ReliabilityProject - expected_parameters = [parameter.name for parameter in self.reliability_project.variables.get_list()] - if set(list_assigned_parameters) != set(expected_parameters): - raise ValueError(f"Not all input parameters expected by model '{self.model.__name__}' were set in the ReliabilityProject.\nExpected parameters: {expected_parameters}\nSet parameters: {list_assigned_variables+list_assigned_constants}\nMissing parameters: {set(expected_parameters) - set(list_assigned_variables + list_assigned_constants)}") - - - def _setup_settings(self, df_settings: pd.DataFrame) -> None: - - # Setup the settings of the ReliabilityProject - # Note: all supported settings can be found in probabilistic_library.reliability.Settings.__dir__ - for attr_name, row in df_settings.iterrows(): - if attr_name in Settings().__dir__(): - setattr(self.reliability_project.settings, attr_name, row['value']) - else: - raise ValueError(f"Attribute '{attr_name}' not found in SensitivitySettings class. Available attributes:\n{Settings().__dir__()}") - - - def _setup_variables(self, uittredepunt: Uittredepunt, ondergrond_scenario: OndergrondScenario) -> list[str]: - # Setup the different variables of the ReliabilityProject - # Notes: before a variable is assigned it is checked whether it is a valid input parameter of the current model function. - - list_assigned_variables = [] - - # FIXME code below can be optimized (repetitive tasks) - # Vak variables - for var_name, var_dict in uittredepunt.vak.variables.__dict__.items(): - if var_name in inspect.signature(self.model).parameters: - enforce_lower_upper_bounds(var_dict, f"Vak ID {uittredepunt.vak.id}") - self._set_reliability_project_variable(var_name, var_dict) - list_assigned_variables.append(var_name) - - # Uittredepunt variables - for var_name, var_dict in uittredepunt.variables.__dict__.items(): - if var_name in inspect.signature(self.model).parameters: - enforce_lower_upper_bounds(var_dict, f"Uittredepunt ID {uittredepunt.id}") - self._set_reliability_project_variable(var_name, var_dict) - list_assigned_variables.append(var_name) - - # Ondergrondscenario variables - for var_name, var_dict in ondergrond_scenario.variables.__dict__.items(): - if var_name in inspect.signature(self.model).parameters: - enforce_lower_upper_bounds(var_dict, f"Ondergrondscenario ID {ondergrond_scenario.id}") - self._set_reliability_project_variable(var_name, var_dict) - list_assigned_variables.append(var_name) - - return list_assigned_variables - - def _setup_constants(self) -> list[str]: - # Setup the constants of the ReliabilityProject - # Notes: before a constant is assigned it is checked whether it is a valid input parameter of the current model function. - - list_assigned_constants = [] - - for var_name, row in self.constants.iterrows(): - if var_name in inspect.signature(self.model).parameters: - constant_dict = generate_parameter_dict_for_constant(str(var_name), df_overview_row=row) - enforce_lower_upper_bounds(constant_dict, "located parameter overview sheet") - self._set_reliability_project_variable(str(var_name), var_dict=constant_dict) - - list_assigned_constants.append(str(var_name)) - - return list_assigned_constants - - - def _set_buitenwaterstand_overschrijdingsfrequentielijn(self, uittredepunt: Uittredepunt) -> None: - # Add the overschrijdingsfrequentielijn as stochastic variable to the ReliabilityProject - - waterlevel = uittredepunt.overschrijdingsfrequentielijn.overschrijdingsfrequentielijn.level - exceedance_frequency = uittredepunt.overschrijdingsfrequentielijn.overschrijdingsfrequentielijn.exceedance_frequency - - self.reliability_project.variables["buitenwaterstand"].distribution = "cdf_curve" - - for i in range(0, len(waterlevel)): - fc = FragilityValue() - fc.x = waterlevel[i] - fc.probability_of_failure = exceedance_frequency[i] - self.reliability_project.variables["buitenwaterstand"].fragility_values.append(fc) - - - - def _set_reliability_project_variable(self, var_name: str, var_dict: dict[str, Any]) -> None: - # Create the Stochastic variable in the ReliabilityProject - # Note: all supported variable attributes can be found in probabilistic_library.statistic.Stochast().__dir__() - - try: - self.reliability_project.variables[var_name].distribution = var_dict["distribution"] - - if var_dict["distribution"] == "deterministic": - self.reliability_project.variables[var_name].mean = var_dict["value"] - else: - self.reliability_project.variables[var_name].mean = var_dict["mean"] - - if var_dict["dispersion_type"] == "_stdev": - self.reliability_project.variables[var_name].deviation = var_dict["dispersion_value"] - elif var_dict["dispersion_type"] == "_vc": - self.reliability_project.variables[var_name].variation = var_dict["dispersion_value"] - else: - raise ValueError(f"Disperion type '{var_dict["dispersion_type"]}' of variable '{var_name}' is not implemented. Allowed types: {ALLOWED_DISPERSION_TYPES}") - - if pd.notna(var_dict["lower_bound_mean"]): - self.reliability_project.variables[var_name].minimum = var_dict["lower_bound_mean"] - if pd.notna(var_dict["upper_bound_mean"]): - self.reliability_project.variables[var_name].maximum = var_dict["upper_bound_mean"] - except AttributeError as e: - raise AttributeError(f"Trying to set variable '{var_name}', which is not an input arg of function {self._model.__name__}. The probabilistic_library package only allows variables defined as input args of the evaluated model function.\nError message: {e}") - - - def run(self): - # Run the reliability project - self.reliability_project.run() - - -class CombinedReliabilityCalculation(ResultsTemplate): - """CombinedReliabilityCalculation class for combined calculations of the uplift/heave/piping models for each unique uittredepunt-ondergrondscenario combination.""" - - def __init__(self, reliability_project: CombineProject, uittredepunt: Uittredepunt, ondergrond_scenario: OndergrondScenario) -> None: - self.id = {"uittredepunt": uittredepunt.id, "ondergrondscenario": ondergrond_scenario.id} - self.uittredepunt = uittredepunt - self.ondergrond_scenario = ondergrond_scenario - self.reliability_project = reliability_project - diff --git a/app/classes/test_vak.py b/app/classes/test_vak.py deleted file mode 100644 index 27493fd2..00000000 --- a/app/classes/test_vak.py +++ /dev/null @@ -1,24 +0,0 @@ - -def test_vak_collection(): - - ## - from app.classes.vak import VakCollection - from pandas import read_excel - from app.classes.workspace import Workspace - from app.helper_functions.utils import repository_root_path - import os - - assert 1+1 == 2 - - repo_root = repository_root_path() - # workspace_path = os.path.join(repo_root, "workspaces", "example_new_calculations") - # workspace = Workspace(workspace_path) - # df_overview_parameters = read_excel( - # workspace.input.folderpath / "input.xlsx", sheet_name="Overzicht_parameters", index_col=0, header=0).rename( - # columns=lambda x: x.strip()) - # df_vakken = read_excel(workspace.input.folderpath / "input.xlsx", sheet_name="Vakken").rename( - # columns=lambda x: x.strip()) - # # noinspection PyUnusedLocal - # vak_collection = VakCollection(df_vakken, df_overview_parameters) - - ## diff --git a/app/classes/uittredepunt.py b/app/classes/uittredepunt.py deleted file mode 100644 index 38468158..00000000 --- a/app/classes/uittredepunt.py +++ /dev/null @@ -1,102 +0,0 @@ -from types import SimpleNamespace - -import pandas as pd - -from app.classes.base_collection import BaseCollection, _pretty_repr -from app.classes.vak import Vak, VakCollection -from app.helper_functions.data_validation import ( - check_attribute_already_exists, - check_attribute_in_overview, - enforce_lower_upper_bounds, -) -from app.helper_functions.parameter_functions import ( - generate_parameter_dict_for_variable, - strip_suffix_from_list_parameter_names, -) - - -class Uittredepunt: - - # Metadata attributes of the Uittredepunt class. These are stored as class-level type hints to make the attributes visible to static type checkers (e.g. Pylance). - # The actual values are set dynamically in __init__ using setattr and a list of values. - id: int # Note: this is a renamed version of uittredepunt_id - vak_id: int # ID of the corresponding Vak instance - uittredepunt_x_coord: float - uittredepunt_y_coord: float - uittredelocatie: str - M_value: float - vak_naam: str - hydra_locatie_id: str - - - def __init__(self, df_row: pd.Series, vak: Vak, df_overview_parameters: pd.DataFrame, input_parameter_names_without_suffix: list[str]) -> None: - - # Add each input parameter to the Uittredepunt instance - for attr_name_without_suffix in input_parameter_names_without_suffix: - check_attribute_already_exists(self, attr_name_without_suffix) - check_attribute_in_overview(attr_name_without_suffix, df_overview_parameters) - - df_overview_row = df_overview_parameters.loc[attr_name_without_suffix] # Select relevant row from the parameter overview - - # TODO nice to have: convert x,y coordinates to a Shapely Point - if df_overview_row["parameter_type"] == "metadata": - # Metadata should be set on the Uittredepunt instance directly - name = "id" if attr_name_without_suffix == "uittredepunt_id" else attr_name_without_suffix # Rename uittredepunt_id to id to simplify the attribute name - setattr(self, name, df_row[attr_name_without_suffix]) - - elif df_overview_row["parameter_type"] in ["variable", "constant"]: - # Variables and constants should be set on the variables attribute of the Uittredepunt instance - if not hasattr(self, "variables"): - # Create a SimpleNamespace to hold the variables/constants of this Uittredepunt instance - self.variables = SimpleNamespace() - - # Generate input_dict for the variable or constant. This is a dictionary containing the parameters (e.g. mean, stdev/vc, etc.) - # All input dicts will be stored in the variables attribute of the Uittredepunt instance - # This function also calls a helper function to enforce lower and upper bounds on the variable - input_dict = generate_parameter_dict_for_variable(attr_name_without_suffix, - df_overview_row=df_overview_row, - df_row=df_row) - - setattr(self.variables, attr_name_without_suffix, input_dict) - - self.vak = vak # Link the corresponding Vak instance to this Uittredepunt instance - - self.overschrijdingsfrequentielijn = None # Filled in the Overschrijdingsfrequentielijn class and contains the exceedance frequency line for every Uittredepunt - - - def __repr__(self) -> str: - return _pretty_repr(self) - - -class UittredepuntCollection(BaseCollection[Uittredepunt]): - def __init__(self, df_uittredepunten: pd.DataFrame, vak_collection: VakCollection, df_overview_parameters: pd.DataFrame) -> None: - super().__init__() # Initialize the base collection - self.df = df_uittredepunten - - # Get unique column names from the df (without suffix) - input_parameter_names_without_suffix = strip_suffix_from_list_parameter_names(self.df.columns) - - # Create uittredepunten from df. Note that the created Uittredepunt is linked to the corresponding Vak - for _, row in self.df.iterrows(): - - uittredepunt_id = row["uittredepunt_id"] - - # Perform checks - try: - vak = vak_collection[str(row["vak_id"])] - except KeyError: - # If the vak_id is not found in the vak_collection, raise an error - raise KeyError(f"Vak ID '{row["vak_id"]}' (corresponding to uittredepunt {uittredepunt_id}') not found in VakCollection") - - if any(punt.id == uittredepunt_id for punt in vak.uittredepunten): - # Check for duplicate uittredepunt_id within the same Vak - raise ValueError(f"Duplicate uittredepunt_id: uittredepunt '{uittredepunt_id}' already exists in vak '{vak.id}'") - - # Create Uittredepunt instance - uittredepunt = Uittredepunt(row, vak, df_overview_parameters, input_parameter_names_without_suffix) - - # Add Uittredepunt instance as attribute to the corresponding Vak instance - vak.uittredepunten.append(uittredepunt) - - # Add Uittredepunt instance to the collection - self.add(str(uittredepunt.id), uittredepunt) \ No newline at end of file diff --git a/app/classes/vak.py b/app/classes/vak.py deleted file mode 100644 index 7577e352..00000000 --- a/app/classes/vak.py +++ /dev/null @@ -1,84 +0,0 @@ -from types import SimpleNamespace - -import pandas as pd - -from app.classes.base_collection import BaseCollection, _pretty_repr -from app.helper_functions.data_validation import ( - check_attribute_already_exists, - check_attribute_in_overview, - enforce_lower_upper_bounds, -) -from app.helper_functions.parameter_functions import ( - generate_parameter_dict_for_variable, - strip_suffix_from_list_parameter_names, -) - - -class Vak: - - # Metadata attributes of the Vak class. These are stored as class-level type hints to make the attributes visible to static type checkers (e.g. Pylance). - # The actual values are set dynamically in __init__ using setattr and a list of values. - id: int # Note: this is a renamed version of vak_id - vak_naam: str - M_van: float - M_tot: float - vak_lengte: float - - - def __init__(self, df_row: pd.Series, df_overview_parameters: pd.DataFrame, input_parameter_names_without_suffix: list[str]) -> None: - - # Add each input parameter to the Vak instance - for attr_name_without_suffix in input_parameter_names_without_suffix: - check_attribute_already_exists(self, attr_name_without_suffix) - check_attribute_in_overview(attr_name_without_suffix, df_overview_parameters) - - df_overview_row = df_overview_parameters.loc[attr_name_without_suffix] # Select relevant row from the parameter overview - - if df_overview_row["parameter_type"] == "metadata": - # Metadata should be set on the Vak instance directly - name = "id" if attr_name_without_suffix == "vak_id" else attr_name_without_suffix # Rename vak_id to id to simplify the attribute name - setattr(self, name, df_row[attr_name_without_suffix]) - - elif df_overview_row.at["parameter_type"] in ["variable", "constant"]: - # Variables and constants should be set on the variables attribute of the Vak instance - if not hasattr(self, "variables"): - # Create a SimpleNamespace to hold the variables/constants of this Vak instance - self.variables = SimpleNamespace() - - # Generate input_dict for the variable or constant. This is a dictionary containing the parameters (e.g. mean, stdev/vc, etc.) - # All input dicts will be stored in the variables attribute of the Vak instance - # This function also calls a helper function to enforce lower and upper bounds on the variable - input_dict = generate_parameter_dict_for_variable(attr_name_without_suffix, - df_overview_row=df_overview_row, - df_row=df_row) - - setattr(self.variables, attr_name_without_suffix, input_dict) - - # Initialize attributes which will be filled later - self.uittredepunten = [] # Filled in the UittredepuntCollection class and shows all Uittredepunten in this Vak - self.ondergrond_scenarios = [] # Filled in the OndergrondScenarioCollection class and shows all OndergrondScenarios in this Vak - - def __repr__(self) -> str: - return _pretty_repr(self) - - -class VakCollection(BaseCollection[Vak]): - def __init__(self, df_vakken: pd.DataFrame, df_overview_parameters: pd.DataFrame) -> None: - super().__init__() - self.df = df_vakken - - # Get unique column names from the df (without suffix) - input_parameter_names_without_suffix = strip_suffix_from_list_parameter_names(self.df.columns) - - # Create Vak instances from df - for _, row in self.df.iterrows(): - - # Create Vak instance - vak = Vak(row, df_overview_parameters, input_parameter_names_without_suffix) - - # Check for duplicate vak_id before adding Vak to collection - if vak.id in self._items: - raise ValueError(f"Duplicate vak_id {vak.id} found") - - # Add Vak instance to the collection - self.add(str(vak.id), vak) diff --git a/app/classes/workspace.py b/app/classes/workspace.py deleted file mode 100644 index 59461fc8..00000000 --- a/app/classes/workspace.py +++ /dev/null @@ -1,163 +0,0 @@ -from pathlib import Path -from typing import Tuple - -import pandas as pd - -from app.classes.file_system import FileSystem - - -# FIXME docstring -# FIXME add functionality to read existing results (without running prob. calculations again) -class Workspace: - """Workspace class which handles all actions related to input, output and intermediate working files""" - - def __init__(self, PATH_WORKSPACE: str | Path) -> None: - """Initialize Workspace instance - - Args: - PATH_WORKSPACE (str | Path): path to the folder that contains all required input and where all output and working files will be stored - """ - self.folderpath = FileSystem.validate_path(PATH_WORKSPACE) - - self.output = _prepare_output_folder(self.folderpath, checks=True) - self.input, self.excel_path, self.hrd_path = _prepare_input_folder(self.folderpath, self.output.folderpath) - - - # FIXME add functionality to read existing results (without running prob. calculations again) - # self.output = _prepare_output_folder(self.folderpath, USE_EXISTING_TKX_RESULTS, checks=True) - # self.input = _prepare_input_folder(self.folderpath, self.output.folderpath, USE_EXISTING_TKX_RESULTS) - - # if not USE_EXISTING_TKX_RESULTS: - # self.work_dir = _prepare_work_dir(self.folderpath) - - - def update_output_filesystem(self) -> None: - """ - Update the output subfolder FileSystem instance (to include new calculation results) - """ - self.output = _prepare_output_folder(self.folderpath, checks=False) - - -# FIXME docstring -def _prepare_output_folder(PATH_WORKSPACE: Path, checks: bool) -> FileSystem: -# def _prepare_output_folder(PATH_WORKSPACE: Path, USE_EXISTING_TKX_RESULTS: bool, checks: bool) -> FileSystem: - """Prepare output subfolder - - Args: - PATH_WORKSPACE (Path): path to the folder that contains all required input and where all output and working files will be stored - USE_EXISTING_TKX_RESULTS (bool): whether to use precalculated .tkx files (True) or to start new calculations (False) - checks (bool): whether to carry out checks on the output subfolder (only when the output subfolder is initialized, not when updating the FileSystem instance of the output subfolder after generating new results) - - Raises: - FileNotFoundError: raised if USE_EXISTING_TKX_RESULTS=True but the output subfolder contains no .tkx files - FileExistsError: raised if USE_EXISTING_TKX_RESULTS=False but the output subfolder still contains .tkx files from a previous run - - Returns: - FileSystem: _description_ - """ - # Create output folder if it didn't exist yet - if not Path(PATH_WORKSPACE / "output").exists(): - Path.mkdir(PATH_WORKSPACE / "output", parents=False, exist_ok=False) - print(f"INFO: output folder was succesfully created in project folder ({PATH_WORKSPACE / 'output'})") - - # Create FileSystem instance for output folder - filesystem_output = FileSystem(PATH_WORKSPACE / "output") - - return filesystem_output - -# FIXME docstring -def _prepare_input_folder(PATH_WORKSPACE: Path, path_output_folder: Path) -> Tuple[FileSystem, Path, Path]: - - """Prepare input subfolder - - Args: - PATH_WORKSPACE (Path): path to the folder that contains all required input and where all output and working files will be stored - path_output_folder (Path): path to the output subfolder - USE_EXISTING_TKX_RESULTS (bool): whether to use precalculated .tkx files (True) or to start new calculations (False) - - Raises: - FileNotFoundError: raised if USE_EXISTING_TKX_RESULTS=True but the number of .stix files in the input subfolder don't match the number of .tkx files in the output subfolder - FileNotFoundError: raised if USE_EXISTING_TKX_RESULTS=False but the input subfolder contains no .stix files - FileNotFoundError: raised if USE_EXISTING_TKX_RESULTS=False but the input subfolder contains no template .tkx file - - Returns: - FileSystem: FileSystem instance which creates a convenient overview of the input subfolder and the files within it - """ - # Create input folder if it didn't exist yet - if not Path(PATH_WORKSPACE / "input").exists(): - Path.mkdir(PATH_WORKSPACE / "input", parents=False, exist_ok=False) - print(f"INFO: input folder was succesfully created in project folder ({PATH_WORKSPACE / 'input'})") - - # Create FileSystem instance for input folder - filesystem_input = FileSystem(PATH_WORKSPACE / "input") - - # Make sure the "input" subfolder contains 1 .xlsx file named input.xlsx - xlsx_input = [filepath.name for filepath in FileSystem.find_files_in_dir(filesystem_input.folderpath, "xlsx")] - - if len(xlsx_input) != 1 or xlsx_input[0] != "input.xlsx": - raise FileNotFoundError( - f"\nInput folder {filesystem_input.folderpath} should contain exactly 1 .xlsx files named 'input.xlsx'\n(Currently found: {xlsx_input})" - ) - - # Check if input.xlsx has exactly four required sheets (case-sensitive!) - expected_sheets = {"Vakken", "Uittredepunten", "Ondergrondscenarios", "Overzicht_parameters", "Settings"} - xlsx_input_folderpath = pd.ExcelFile(filesystem_input.folderpath / "input.xlsx") - - if set(xlsx_input_folderpath.sheet_names) != expected_sheets: - raise FileNotFoundError( - f"\n{filesystem_input.folderpath / 'input.xlsx'} should contain exactly these sheets:\n" - f"{', '.join(expected_sheets)}\n" - f"Found sheets: {', '.join(xlsx_input_folderpath.sheet_names)}\n" - f"Note:\n1) Sheet names are case-sensitive!\n2) The order of sheets does not matter." - ) - - # Find HRD path - hrd_matches = filesystem_input.files.loc[ - lambda df: df["filename"].str.endswith(".sqlite") & - (df["filename"] != "hlcd.sqlite") & - ~df["filename"].str.endswith(".config.sqlite") - ] # The .zip files containing HRD have multiple .sqlite files, but we only want the one that ends with .sqlite (not ending with .config.sqlite) and is not called 'hlcd.sqlite' - - if len(hrd_matches) != 1: - if len(hrd_matches) > 1: - filepaths = ', '.join(hrd_matches["filepath"].tolist()) - raise ValueError(f"Expected exactly one matching HRD .sqlite file, but found {len(hrd_matches)}:\n{filepaths}") - else: - raise ValueError("One HRD .sqlite file is required in the input folder, but none was found.") - - hrd_path = hrd_matches["filepath"].iloc[0] - - return filesystem_input, filesystem_input.folderpath / "input.xlsx", hrd_path - - -def _prepare_work_dir(PATH_WORKSPACE: Path) -> FileSystem: - """Prepare working directory in which intermediate files are stored. - - Args: - PATH_WORKSPACE (Path): path to the folder that contains all required input and where all output and working files will be stored - - Raises: - FileExistsError: raised if the working directory still contains files from a previous run - - Returns: - FileSystem: FileSystem instance which creates a convenient overview of the working directory and the files within it - """ - # Create working directory if it didn't exist yet - if not Path(PATH_WORKSPACE / "_work_dir").exists(): - Path.mkdir(PATH_WORKSPACE / "_work_dir", parents=False, exist_ok=False) - print( - f"INFO: working folder for intermediate results was succesfully created in project folder ({PATH_WORKSPACE / '_work_dir'})" - ) - - # Create FileSystem object for working folder (intermediate results) - filesystem_work_dir = FileSystem(PATH_WORKSPACE / "_work_dir") - - # Perform checks - if filesystem_work_dir.files.shape[0] != 0: - # Make sure no files from a previous run are present in the working directory. If this is the case, - # let the user take of this in order to prevent accidental deletion of files. - raise FileExistsError( - f"Project folder {PATH_WORKSPACE} contains a subfolder '_work_dir' with intermediate files from a previous run. Delete (or archive) this folder before you continue." - ) - - return filesystem_work_dir diff --git a/app/helper_functions/calculation_helpers.py b/app/helper_functions/calculation_helpers.py deleted file mode 100644 index 0bd0f7af..00000000 --- a/app/helper_functions/calculation_helpers.py +++ /dev/null @@ -1,93 +0,0 @@ -from concurrent.futures import ThreadPoolExecutor -from typing import Callable - -import pandas as pd -from probabilistic_library import CombineProject, CombinerMethod, CombineType - -from app.classes.ondergrond_scenario import OndergrondScenario -from app.classes.reliability_calculation import ( - CombinedReliabilityCalculation, - ReliabilityCalculation, -) -from app.classes.uittredepunt import Uittredepunt -from app.classes.vak import VakCollection - - -def _result_dict(reliability_calculation: CombinedReliabilityCalculation|ReliabilityCalculation) -> dict: - """Helper function to convert a ReliabilityCalculation instance to a dictionary for easy access""" - return { - "uittredepunt_id": reliability_calculation.id["uittredepunt"], - "uittredepunt": reliability_calculation.uittredepunt, - "ondergrondscenario_id": reliability_calculation.id["ondergrondscenario"], - "ondergrondscenario": reliability_calculation.ondergrond_scenario, - "reliability_calculation": reliability_calculation, - "converged": reliability_calculation.is_converged, - "beta": reliability_calculation.beta, - "failure_probability": reliability_calculation.reliability_project.design_point.probability_failure, - "alphas": reliability_calculation.alphas, - "influence_factors": reliability_calculation.influence_factors, - } - - -def start_calculations(list_reliability_calculations: list[ReliabilityCalculation]) -> None: - def run_reliability_calculation(reliability_calculation: ReliabilityCalculation) -> None: - try: - reliability_calculation.run() - except Exception as e: - print(f"ERROR: could not run running reliability calculation {reliability_calculation.id}: {e}") - - with ThreadPoolExecutor() as executor: - executor.map(run_reliability_calculation, list_reliability_calculations) - - -def build_and_run_unique_model_calculations(model: Callable, vak_collection: VakCollection, df_overview_parameters: pd.DataFrame, df_settings: pd.DataFrame) -> pd.DataFrame: - - # Notes: - # 1. Due to limitations in the probabilistic_library, we cannot first set up all calculations and then run them. After setting up calculations for each model (uplift/heave/piping), we need to run them immediately before setting up the next model. - # 2. Not all combinations of uittredepunten and ondergrondscenarios are valid, so we need a helper-loop through the vakken which holds the valid combinations - # 3. Nested for-loops are inefficient but used on purpose since there are no heavy calculations and it's easily understandable - - list_calculations = [] - for vak in vak_collection.values(): - for uittredepunt in vak.uittredepunten: - for ondergrond_scenario in vak.ondergrond_scenarios: - list_calculations.append( - ReliabilityCalculation( - uittredepunt, - ondergrond_scenario, - model, - df_overview_parameters[df_overview_parameters["parameter_type"] == "constant"], - df_settings - ) - ) - start_calculations(list_calculations) - - # Return the calculations in a DataFrame for easy access. The DataFrame is sorted by uittredepunt and by ondergrondscenario - return pd.DataFrame([_result_dict(calc) for calc in list_calculations]).sort_values(by=["uittredepunt_id", "ondergrondscenario_id"]).reset_index(drop=True) - - -# FIXME docstring -def build_and_run_combined_calculations(df_group: pd.DataFrame, uittredepunt: Uittredepunt, ondergrond_scenario: OndergrondScenario) -> pd.Series: - """_summary_ - - Args: - df_group (pd.DataFrame): all three models (uplift/heave/piping) for a unique combination of uittredepunt and ondergrondscenario - - Returns: - pd.Series: Series containing the combined reliability calculation result for the unique combination of uittredepunt and ondergrondscenario - """ - - # Extract the model results of uplift/heave/piping from the DataFrame group - models = {row["model"]: row["reliability_calculation"] for _, row in df_group.iterrows()} - - # Set up and run combined project - combined_project = CombineProject() - combined_project.design_points.append(models["uplift"].design_point) - combined_project.design_points.append(models["heave"].design_point) - combined_project.design_points.append(models["piping"].design_point) - combined_project.settings.combine_type = CombineType.parallel - combined_project.settings.combiner_method = CombinerMethod.importance_sampling - combined_project.run() - - return pd.Series(_result_dict(CombinedReliabilityCalculation(combined_project, uittredepunt, ondergrond_scenario))) - diff --git a/app/helper_functions/calibration_WBI.py b/app/helper_functions/calibration_WBI.py deleted file mode 100644 index f671b365..00000000 --- a/app/helper_functions/calibration_WBI.py +++ /dev/null @@ -1,186 +0,0 @@ -"""This module contains calibration functions derived from the WBI2017 project -""" - -import math -from dataclasses import dataclass -from scipy.stats import norm - - -def calc_Beta_u( - F_u: float, Bnorm: float -) -> float: # Berekening van veiligheidsfactor naar benaderde beta voor opbarsten - r"""Calculation of the estimated reliability index of uplift based on the WBI2017 calibration - - see :cite:t:`calibration_piping_2016` - - .. math:: - \beta_u = \frac{ln(F_{u}/0.48) + 0.27 \cdot \beta_{norm}}{0.46} - - - Args: - F_u (float): safety factor for uplift - Bnorm (float): required reliability index of the dike trajectory - - Returns: - float: estimated reliability index for uplift failure mechanism - """ - return ( - math.log(F_u / 0.48) + (-0.27 * Bnorm) - ) / 0.46 #'Bnorm' is in python a negative value therefore -1*Bnorm - - -def calc_Beta_h( - F_h: float, Bnorm: float -) -> float: # Berekening van veiligheidsfactor naar benaderde beta voor heave - r"""Calculation of the estimated reliability index of heave based on the WBI2017 calibration - - see :cite:t:`calibration_piping_2016` - - .. math:: - - \beta_h = \frac{ln(F_{h}/0.37) + 0.30 \cdot \beta_{norm}}{0.48} - - Args: - F_h (float): safety factor for heave - Bnorm (float): required reliability index for the dike trajectory - - Returns: - float: estimated reliability index for heave failure mechanism - """ - return ( - math.log(F_h / 0.37) + (-0.30 * Bnorm) - ) / 0.48 ##'Bnorm' is in python a negative value therefore -1*Bnorm - - -def calc_Beta_p( - F_p: float, Bnorm: float -) -> float: # Berekening van veiligheidsfactor naar benaderde beta voor piping - r"""Calculation of the estimated reliability index of piping based on the WBI2017 calibration - - see :cite:t:`calibration_piping_2016` - - .. math:: - - \beta_p = \frac{ln(F_{p}/1.04) + 0.43 \cdot \beta_{norm}}{0.37} - - - Args: - F_h (float): safety factor for piping - Bnorm (float): required reliability index of the dike trajectory - - Returns: - float: estimated reliability index for piping failure mechanism - """ - return ( - math.log(F_p / 1.04) + (-0.43 * Bnorm) - ) / 0.37 ##'Bnorm' is in python a negative value therefore -1*Bnorm - - -def calc_SF_u(B_cross: float, Bnorm: float) -> float: - r"""Calculation of the required safety factor for uplift based on the WBI2017 calibration - - see :cite:t:`calibration_piping_2016` - - .. math:: - - \gamma_u = 0.48 \cdot e^{0.46 \cdot - \beta_{cross} - 0.27 \cdot - \beta_{norm}} - - - Args: - B_cross (float): required reliability index for uplift in cross section (negative value) - Bnorm (float): required reliability index of the dike trajectory (negative value) - - Returns: - float: safety factor for uplift failure mechanism - """ - return 0.48 * math.exp(0.46 * -1.0 * B_cross - 0.27 * -1.0 * Bnorm) - - -def calc_SF_h(B_cross: float, Bnorm: float) -> float: - r"""Calculation of the required safety factor for heave based on the WBI2017 calibration - - see :cite:t:`calibration_piping_2016` - - .. math:: - - \gamma_h = 0.37 \cdot e^{0.48 \cdot - \beta_{cross} - 0.30 \cdot - \beta_{norm}} - - - Args: - B_cross (float): required reliability index for heave in cross section (negative value) - Bnorm (float): required reliability index of the dike trajectory (negative value) - - Returns: - float: safety factor for heave failure mechanism - """ - return 0.37 * math.exp(0.48 * -1.0 * B_cross - 0.30 * -1.0 * Bnorm) - - -def calc_SF_p(B_cross: float, Bnorm: float) -> float: - r"""Calculation of the required safety factor for piping based on the WBI2017 calibration - - see :cite:t:`calibration_piping_2016` - - .. math:: - - \gamma_p = 1.04 \cdot e^{0.37 \cdot - \beta_{cross} - 0.43 \cdot - \beta_{norm}} - - - Args: - B_cross (float): required reliability index for piping in cross section (negative value) - Bnorm (float): required reliability index of the dike trajectory (negative value) - - Returns: - float: safety factor for piping failure mechanism - """ - return 1.04 * math.exp(0.37 * -1.0 * B_cross - 0.43 * -1.0 * Bnorm) - -@dataclass -class ReliabilityDikeTrajectory: - r"""Class to store the reliability of a dike trajectory and calculate the required cross section reliability indices and safety factors""" - - T: float - w: float - L: float - a: float - b: float - - @property - def Pnorm(self) -> float: - return 1.0 / self.T - - @property - def PfailureMechanism(self) -> float: - return self.w / self.T - - @property - def Bnorm(self) -> float: - return float(norm.ppf(self.Pnorm)) - - @property - def BfailureMechanism(self) -> float: - return float(norm.ppf(self.PfailureMechanism)) - - @property - def Ndsn(self) -> float: - return 1.0 + (self.a * self.L) / self.b - - @property - def Pcross(self) -> float: - return self.PfailureMechanism / self.Ndsn - - @property - def Bcross(self) -> float: - return float(norm.ppf(self.Pcross)) - - @property - def SF_u(self) -> float: - return calc_SF_u(self.Bcross, self.Bnorm) - - @property - def SF_h(self) -> float: - return calc_SF_h(self.Bcross, self.Bnorm) - - @property - def SF_p(self) -> float: - return calc_SF_p(self.Bcross, self.Bnorm) diff --git a/app/helper_functions/data_validation.py b/app/helper_functions/data_validation.py deleted file mode 100644 index 2cf491c5..00000000 --- a/app/helper_functions/data_validation.py +++ /dev/null @@ -1,126 +0,0 @@ -from __future__ import annotations # makes all annotations lazy (no quotes needed) - -from typing import TYPE_CHECKING - -import pandas as pd - -if TYPE_CHECKING: - from app.classes.vak import Vak - from app.classes.uittredepunt import Uittredepunt - from app.classes.ondergrond_scenario import OndergrondScenario - -from typing import Any, Optional, Type - -from app.helper_functions.parameter_functions import ( - strip_suffix_from_list_parameter_names, -) - - -def check_attribute_already_exists(instance: Vak | Uittredepunt | OndergrondScenario, attr_name: str) -> None: - if hasattr(instance, attr_name): - raise AttributeError(f"{instance.__class__.__name__} already has an attribute named '{attr_name}', please rename the column in the input Excel file.") - - -def checks_input_parameters(df_overview_parameters: pd.DataFrame, df_vak_collection: pd.DataFrame, df_uittredepunt_collection: pd.DataFrame, df_ondergrond_scenario_collection: pd.DataFrame) -> None: - - # Parameter names given - set_parameter_names_given = set(df_vak_collection.columns).union(df_uittredepunt_collection.columns, df_ondergrond_scenario_collection.columns) - - if not all(isinstance(param_name, str) for param_name in set_parameter_names_given): - # Parameter names should all be strings - raise ValueError(f"Parameter names in sheet 'Vakken'/'Uittredepunten'/'Ondergrondscenarios' must all be strings. Found invalid names: {[type(param_name).__name__ for param_name in set_parameter_names_given if not isinstance(param_name, str)]}") - - if any(" " in param_name for param_name in set_parameter_names_given): - # Prevent spaces in parameter names since we're using dot notation for accessing attributes later in the tool - raise ValueError(f"Parameter names in sheet 'Vakken'/'Uittredepunten'/'Ondergrondscenarios' are not allowed to contain spaces. Found invalid names: {[param_name for param_name in set_parameter_names_given if ' ' in param_name]}") - - # Parameter names expected - set_parameter_names_expected = set() - - for index, row in df_overview_parameters[df_overview_parameters["parameter_type"] == "metadata"].iterrows(): - # All expected metadata should be given in de Vakken/Uittredepunten/Ondergrondscenarios sheets - set_parameter_names_expected.update([str(index)]) - - for index, row in df_overview_parameters[df_overview_parameters["parameter_type"] == "variable"].iterrows(): - # All expected variables should be given in de Vakken/Uittredepunten/Ondergrondscenarios sheets, but we need to check if - # the suffix "_mean" should be added (necessary if the input is stochastic). Otherwise, if deterministic, simply add the variable name - if pd.notna(row["parameter_spreidingstype"]): - set_parameter_names_expected.update([str(index) + "_mean", str(index) + row["parameter_spreidingstype"]]) - else: - set_parameter_names_expected.update([str(index)]) - - if any(" " in c for c in set_parameter_names_expected): - # Prevent spaces in parameter names since we're using dot notation for accessing attributes later in the tool - raise ValueError(f"Parameter names in sheet 'Overzicht_parameters' are not allowed to contain spaces: {[c for c in set_parameter_names_expected if ' ' in c]}") - - # Check for missing or surplus input parameters - if set_parameter_names_expected != set_parameter_names_given: - parameters_missing = set_parameter_names_expected - set_parameter_names_given - parameters_surplus = set_parameter_names_given - set_parameter_names_expected - - def link_variables_to_source(variable_names: set[str]) -> pd.DataFrame: - df = pd.DataFrame({'variable name': list(strip_suffix_from_list_parameter_names(variable_names))}) # Note: make it a set to remove duplicates, then cast it back again to a list - df["source input sheet"] = df["variable name"].apply(lambda x: "Vakken" if x in strip_suffix_from_list_parameter_names(df_vak_collection.columns) else ("Uittredepunten" if x in strip_suffix_from_list_parameter_names(df_uittredepunt_collection.columns) else ("Ondergrondscenarios" if x in strip_suffix_from_list_parameter_names(df_ondergrond_scenario_collection.columns) else "Unknown"))) - return df - - if len(parameters_missing) > 0: - raise ValueError(f"\nMissing variables in input Excel file:\n\n{link_variables_to_source(parameters_missing)}\n\nHave a look at the sheet 'Overzicht_parameters' for an overview of expected variables.\nNote that if a variable (e.g. called 'my_variable') is stochastic, two input variables are expected: 'my_variable_mean' and 'my_variable_' (e.g. 'my_variable_stdev').") - elif len(parameters_surplus) > 0: - raise ValueError(f"\nToo many variables in input Excel file:\n\n{link_variables_to_source(parameters_surplus)}\n\nPossible causes:\n1. The variables are not defined in sheet 'Overzicht_parameters'.\n2. The variables are defined in 'Overzicht_parameters' but no 'variabele_spreidingstype' is specified.\n3. Unknown reason") - - -def checks_overview_parameters(df_overview_parameters: pd.DataFrame) -> None: - - if not all(isinstance(i, str) for i in df_overview_parameters.index): - raise ValueError(f"All parameter names in sheet 'Overzicht_parameters' must be strings/text. Found: {[type(i).__name__ for i in df_overview_parameters.index if not isinstance(i, str)]}") - - if df_overview_parameters.index.has_duplicates: - # Check duplicates - raise ValueError(f"Duplicate variables found in sheet 'Overzicht_parameters': {df_overview_parameters.index[df_overview_parameters.index.duplicated()].unique().tolist()}") - - for index, row in df_overview_parameters[df_overview_parameters["parameter_type"].isin(["Input", "Constant"])].iterrows(): - # Check all input variables and constants - - if row["parameter_distribution"] == "deterministic": - if pd.notna(row["parameter_spreidingstype"]): - # Make sure all deterministic variables have no dispersion type specified (e.g. _stdev, _vc) - raise ValueError(f"Deterministic variable '{index}' in sheet 'Overzicht_parameters' should have no dispersion type speciifed (e.g. _stdev, _vc). Remove it.") - else: - if pd.isna(row["parameter_spreidingstype"]): - # Make sure all stochastic variables have a dispersion type specified (e.g. _stdev, _vc) - raise ValueError(f"Stochastic variable '{index}' in sheet 'Overzicht_parameters' has no dispersion type specified (e.g. _stdev, _vc). Add it.") - - -def check_attribute_in_overview(attr_name_without_suffix: str, df_overview_parameters: pd.DataFrame) -> None: - if not attr_name_without_suffix in df_overview_parameters.index: - raise ValueError(f"Variable '{attr_name_without_suffix}' not found in sheet 'Overzicht_parameters' of input Excel file") - - -def is_number(var_value: Any) -> float: - return isinstance(var_value, (int, float)) and not pd.isna(var_value) - - -def enforce_lower_upper_bounds(parameter_dict: dict, id_print: str) -> None: - # Note: only appplicable to input parameters (variables and constants) - - - # Value (mean) is accessed differently for deterministic and stochastic parameters - attr_value = parameter_dict["value"] if parameter_dict["distribution"] == "deterministic" else parameter_dict["mean"] - - # Make sure the attribute value is a number (int/float) before checking bounds - if not is_number(attr_value): - raise ValueError(f"Value of parameter '{parameter_dict["name"]}' ({id_print}) should be a number (int/float) since lower/upper bounds were specified, but it's {attr_value} of type {type(attr_value)}") - - # Check if value lies within upper and lower bounds in parameter_dict (if specified) - if pd.notna(parameter_dict["lower_bound_mean"]): - if not is_number(parameter_dict["lower_bound_mean"]): - raise ValueError(f"Lower bound of parameter {parameter_dict["name"]} should be a number (int/float) but got {parameter_dict["lower_bound_mean"]} of type {type(parameter_dict["lower_bound_mean"])}") - if not (parameter_dict["lower_bound_mean"] <= attr_value): - raise ValueError(f"Parameter '{parameter_dict["name"]}' ({id_print}) has a mean value that exceeds the lower bound (value: {attr_value} < lower bound: {parameter_dict["lower_bound_mean"]})") - - if pd.notna(parameter_dict["upper_bound_mean"]): - if not is_number(parameter_dict["upper_bound_mean"]): - raise ValueError(f"Upper bound of parameter {parameter_dict["name"]} should be a number (int/float) but got {parameter_dict["upper_bound_mean"]} of type {type(parameter_dict["upper_bound_mean"])}") - if not (attr_value <= parameter_dict["upper_bound_mean"]): - raise ValueError(f"Parameter '{parameter_dict["name"]}' ({id_print}) has a mean value that exceeds the upper bound (value: {attr_value} > upper bound: {parameter_dict["upper_bound_mean"]})") - diff --git a/app/helper_functions/limitstatepiping_model4a_class_implementation.py b/app/helper_functions/limitstatepiping_model4a_class_implementation.py deleted file mode 100644 index afd9aa01..00000000 --- a/app/helper_functions/limitstatepiping_model4a_class_implementation.py +++ /dev/null @@ -1,294 +0,0 @@ -"""Python module for the calculation of the limit state function for piping, heave and uplift in a sand layer with a cover layer.""" - -from dataclasses import dataclass - -from app.helper_functions import geohydro_functions, model4a, piping_functions_old - -# Define the input variables for the functions for Uplift, Heave and Piping -# dist_L_geom: float -# dist_BUT: float -# dist_BIT: float -# L3_geom: float -# mv: float -# pp: float -# top_zand: float -# gamma_sat_cover: float -# gamma_w: float -# kD: float -# D: float -# d70: float -# c1: float -# c3: float -# mu: float -# mh: float -# mp: float -# i_c_h: float -# rc: float -# h: float -## Class implementation - - -@dataclass -class LimitStatePipingModel4a: - r""" - Class voor het berekenen van de gecombineerde grenstoestandfunctie voor uplift, heave en piping. - Gebruikt de model4a potentiaalberekening - """ - - dist_L_geom: float - dist_BUT: float - dist_BIT: float - L3_geom: float - mv: float - pp: float - top_zand: float - gamma_sat_cover: float - gamma_w: float - kD: float - D: float - d70: float - c_1: float - c_3: float - mu: float - mh: float - mp: float - i_c_h: float - rc: float - h: float - - @property - def Dcover(self) -> float: - return piping_functions_old.calc_Dcover(self.mv, self.top_zand) - - @property - def h_exit(self) -> float: - return piping_functions_old.calc_h_exit(self.pp, self.mv) - - @property - def dhred(self) -> float: - return piping_functions_old.calc_dH_red(self.h, self.h_exit, self.rc, self.Dcover) - - @property - def d_pot_c_u(self) -> float: - return piping_functions_old.calc_d_pot_c_u( - self.Dcover, self.gamma_sat_cover, self.gamma_w - ) - - @property - def k(self) -> float: - return self.kD / self.D - - @property - def r_exit(self) -> float: - pot_model = model4a.Model4a( - k=self.k, - D=self.D, - c1=self.c_1, - c3=self.c_3, - L1=self.dist_L_geom - self.dist_BUT, - L3=self.L3_geom, - x_but=(0.0 - (self.dist_BUT - self.dist_BIT)), - x_bit=0.0, - ) - r_exit, r_but, r_bit = pot_model.respons( - self.dist_BIT - ) # dist_BIT is gebruikt omdat Model4a rekent met een absolute waarde voor de x-coordinaat - return r_exit - - @property - def pot_exit(self) -> float: - return geohydro_functions.calc_respons2pot(self.pp, self.r_exit, self.h) - - @property - def L_kwelweg(self) -> float: - pot_model = model4a.Model4a( - k=self.k, - D=self.D, - c1=self.c_1, - c3=self.c_3, - L1=self.dist_L_geom - self.dist_BUT, - L3=self.L3_geom, - x_but=(0.0 - (self.dist_BUT - self.dist_BIT)), - x_bit=0.0, - ) - return pot_model.W1 + self.dist_BUT - - @property - def i_optredend(self) -> float: - return piping_functions_old.calc_i_optredend( - self.pot_exit, self.h_exit, self.Dcover - ) - - @property - def dhc(self) -> float: - return piping_functions_old.calc_dH_sellmeijer( - self.d70, self.k, self.D, self.L_kwelweg, self.gamma_w - ) - - @property - def Z_u(self) -> float: - return piping_functions_old.calc_Z_u( - self.d_pot_c_u, self.pot_exit, self.h_exit, self.mu - ) - - @property - def Z_h(self) -> float: - return piping_functions_old.calc_Z_h(self.i_c_h, self.i_optredend, self.mh) - - @property - def Z_p(self) -> float: - return piping_functions_old.calc_Z_p(self.dhc, self.dhred, self.mp) - - @property - def Z_combin(self) -> float: - return max(self.Z_u, self.Z_h, self.Z_p) - - -def Z_u( - dist_L_geom: float, - dist_BUT: float, - dist_BIT: float, - L3_geom: float, - mv: float, - pp: float, - top_zand: float, - gamma_sat_cover: float, - gamma_w: float, - kD: float, - D: float, - d70: float, - c_1: float, - c_3: float, - mu: float, - mh: float, - mp: float, - i_c_h: float, - rc: float, - h: float, -) -> float: - """ - Calculate the Z_u value for the given parameters, using the LimitStatePipingModel4a class." - """ - limit_state = LimitStatePipingModel4a( - dist_L_geom=dist_L_geom, - dist_BUT=dist_BUT, - dist_BIT=dist_BIT, - L3_geom=L3_geom, - mv=mv, - pp=pp, - top_zand=top_zand, - gamma_sat_cover=gamma_sat_cover, - gamma_w=gamma_w, - kD=kD, - D=D, - d70=d70, - c_1=c_1, - c_3=c_3, - mu=mu, - mh=mh, - mp=mp, - i_c_h=i_c_h, - rc=rc, - h=h, - ) - return limit_state.Z_u - - -def Z_h( - dist_L_geom: float, - dist_BUT: float, - dist_BIT: float, - L3_geom: float, - mv: float, - pp: float, - top_zand: float, - gamma_sat_cover: float, - gamma_w: float, - kD: float, - D: float, - d70: float, - c_1: float, - c_3: float, - mu: float, - mh: float, - mp: float, - i_c_h: float, - rc: float, - h: float, -) -> float: - """ - Calculate the Z_h value for the given parameters, using the LimitStatePipingModel4a class." - """ - limit_state = LimitStatePipingModel4a( - dist_L_geom=dist_L_geom, - dist_BUT=dist_BUT, - dist_BIT=dist_BIT, - L3_geom=L3_geom, - mv=mv, - pp=pp, - top_zand=top_zand, - gamma_sat_cover=gamma_sat_cover, - gamma_w=gamma_w, - kD=kD, - D=D, - d70=d70, - c_1=c_1, - c_3=c_3, - mu=mu, - mh=mh, - mp=mp, - i_c_h=i_c_h, - rc=rc, - h=h, - ) - return limit_state.Z_h - - -def Z_p( - dist_L_geom: float, - dist_BUT: float, - dist_BIT: float, - L3_geom: float, - mv: float, - pp: float, - top_zand: float, - gamma_sat_cover: float, - gamma_w: float, - kD: float, - D: float, - d70: float, - c_1: float, - c_3: float, - mu: float, - mh: float, - mp: float, - i_c_h: float, - rc: float, - h: float, -) -> float: - """ - Calculate the Z_p value for the given parameters, using the LimitStatePipingModel4a class." - """ - limit_state = LimitStatePipingModel4a( - dist_L_geom=dist_L_geom, - dist_BUT=dist_BUT, - dist_BIT=dist_BIT, - L3_geom=L3_geom, - mv=mv, - pp=pp, - top_zand=top_zand, - gamma_sat_cover=gamma_sat_cover, - gamma_w=gamma_w, - kD=kD, - D=D, - d70=d70, - c_1=c_1, - c_3=c_3, - mu=mu, - mh=mh, - mp=mp, - i_c_h=i_c_h, - rc=rc, - h=h, - ) - return limit_state.Z_p diff --git a/app/helper_functions/limitstatepiping_model4a_function_implementation.py b/app/helper_functions/limitstatepiping_model4a_function_implementation.py deleted file mode 100644 index 5e267b4b..00000000 --- a/app/helper_functions/limitstatepiping_model4a_function_implementation.py +++ /dev/null @@ -1,201 +0,0 @@ -"""Python module for the calculation of the limit state function for piping, heave and uplift in a sand layer with a cover layer.""" - -import math -from dataclasses import dataclass -from typing import List - -from app.helper_functions import geohydro_functions, model4a, piping_functions_old - -# Define the input variables for the functions for Uplift, Heave and Piping -# dist_L_geom: float -# dist_BUT: float -# dist_BIT: float -# L3_geom: float -# mv: float -# pp: float -# top_zand: float -# gamma_sat_cover: float -# gamma_w: float -# kD: float -# D: float -# d70: float -# c1: float -# c3: float -# mu: float -# mh: float -# mp: float -# i_c_h: float -# rc: float -# h: float - -# def Z_u(dist_L_geom: float,dist_BUT: float,dist_BIT: float,L3_geom: -# float,mv: float,pp: float,top_zand: float,gamma_sat_cover: float, -# gamma_w: float,kD: float,D: float,c_1: float,c_3: float,mu: float, -# h: float) -> float: -# r"""Calculate the uplift limit state function.""" -# # Calculate the geometrical values for potential calculation -# L1 = dist_L_geom - dist_BUT -# L2 = dist_BUT - dist_BIT - -# # Potential calculation -# k = kD / D -# # Call the potential calculation function with x_bit=0.0 to use dist_BIT as x -# pot_model = model4a.Model4a( -# k=k, D=D, c1=c_1, c3=c_3, L1=L1, L3=L3_geom, x_but=(0.0 - L2), x_bit=0.0 -# ) -# r_exit, r_but, r_bit = pot_model.respons(dist_BIT) -# pot_exit = geohydro_functions.calc_respons2pot(pp, r_exit, h) - -# # Calculate the h_exit -# h_exit = piping_functions.calc_h_exit(pp, mv) - -# # Calculate the deklaagdikte -# Dcover = piping_functions.calc_Dcover(mv, top_zand) - -# # Calculate the critical potential -# d_pot_c_u = piping_functions.calc_d_pot_c_u(Dcover, gamma_sat_cover, gamma_w) - -# # Calculate the uplift limit state function -# Zu = piping_functions.calc_Z_u(d_pot_c_u, pot_exit, h_exit, mu) -# return Zu - - -# def Zu( -# L_intrede, L_BUT, k, D, c1, c3, L3, WS, PP, L_BIT, d_dek, y_satdek, y_water, MV, mu -# ): -# L1 = L_intrede - L_BUT -# lam1 = np.sqrt(k * D * c1) -# lam3 = np.sqrt(k * D * c3) -# Φ1 = PP + (WS - PP) * (L_BUT - L_BIT + lam3 * math.tanh(L3 / lam3)) / ( -# lam1 * math.tanh(L1 / lam1) + L_BUT - L_BIT + lam3 * math.tanh(L3 / lam3) -# ) -# Φ2 = PP + (WS - PP) * lam3 * math.tanh(L3 / lam3) / ( -# lam1 * math.tanh(L1 / lam1) + L_BUT - L_BIT + lam3 * math.tanh(L3 / lam3) -# ) -# Φ_uittrede = PP + (Φ2 - PP) * (math.sinh((L3 - L_BIT) / lam3)) / math.sinh( -# L3 / lam3 -# ) -# h_exit = max(PP, MV) -# dΦ = Φ_uittrede - h_exit -# dΦc = d_dek * ((y_satdek - y_water) / y_water) -# Zu = mu * dΦc - dΦ -# return Zu - - -# def Zh(ic, L_intrede, L_BUT, k, D, c1, c3, L3, WS, PP, L_BIT, d_dek, MV): -# L1 = L_intrede - L_BUT -# lam1 = np.sqrt(k * D * c1) -# lam3 = np.sqrt(k * D * c3) -# Φ1 = PP + (WS - PP) * (L_BUT - L_BIT + lam3 * math.tanh(L3 / lam3)) / ( -# lam1 * math.tanh(L1 / lam1) + L_BUT - L_BIT + lam3 * math.tanh(L3 / lam3) -# ) -# Φ2 = PP + (WS - PP) * lam3 * math.tanh(L3 / lam3) / ( -# lam1 * math.tanh(L1 / lam1) + L_BUT - L_BIT + lam3 * math.tanh(L3 / lam3) -# ) -# Φ_uittrede = PP + (Φ2 - PP) * (math.sinh((L3 - L_BIT) / lam3)) / math.sinh( -# L3 / lam3 -# ) -# h_exit = max(PP, MV) -# dΦ = Φ_uittrede - h_exit -# Zh = ic - (dΦ / d_dek) -# return Zh - - -# def Zp(L_intrede, L_BUT, k, D, c1, y_water, d70, mp, WS, d_dek, PP, MV): -# L1 = L_intrede - L_BUT -# lam1 = np.sqrt(k * D * c1) -# w1 = lam1 * math.tanh(L1 / lam1) -# L = w1 + L_BUT -# k_ms = k / (24 * 3600) -# k_intr = (0.00000133 / 9.81) * k_ms -# Fres = 0.25 * ((26.0 - y_water) / y_water) * math.tan(37.0 * math.pi / 180.00) -# Fscale = pow((d70 / 1.0e6) / 2.08e-4, 0.4) * 2.08e-4 / pow(k_intr * L, (1.0 / 3.0)) -# if D == L: -# D = D - 0.001 -# else: -# pass -# totdemacht = 0.04 + (0.28 / (pow(D / L, 2.8) - 1.0)) -# Fgeom = 0.91 * pow(D / L, totdemacht) -# Hc = Fres * Fscale * Fgeom * L -# h_exit = max(PP, MV) -# Zp = (mp * Hc) - (max(0.01, (WS - h_exit - (0.3 * d_dek)))) -# return Zp - - -def calc_Z_combin_piping( - dist_L_geom: float, - dist_BUT: float, - dist_BIT: float, - L3_geom: float, - mv: float, - pp: float, - top_zand: float, - gamma_sat_cover: float, - gamma_w: float, - kD_wvp: float, - D_wvp: float, - d70: float, - c_1: float, - c_3: float, - mu: float, - mh: float, - mp: float, - i_c_h: float, - rc: float, - h: float, -) -> List[float]: - r""" - - Gecombineerde grenstoestandfunctie voor uplift, heave en piping. - Returns: - Y[0] (float): Z_u: limit state uplift [-] - Y[1] (float): Z_h: limit state heave [-] - Y[2] (float): Z_p: limit state piping [-] - Y[3] (float): Z_combin: limit state combinatie uplift, heave en piping [-] - """ - - # Berekening deklaagdikte - Dcover = piping_functions_old.calc_Dcover(mv, top_zand) - - # Berekening niveau bij het uittredepunt - h_exit = piping_functions_old.calc_h_exit(pp, mv) - - # Berekening gereduceerd verval - dhred = piping_functions_old.calc_dH_red(h, h_exit, rc, Dcover) - - # Berekening grenspotentiaal - d_pot_c_u = piping_functions_old.calc_d_pot_c_u(Dcover, gamma_sat_cover, gamma_w) - - # Berekening geometrische waarden voor potentiaalberekening - L1 = dist_L_geom - dist_BUT - L2 = dist_BUT - dist_BIT - # L3 is al opgegeven - - # potentiaalberekening - k = kD_wvp / D_wvp - # aanroepen functie potentiaalberekening, x_bit = 0.0 zodat we dist_BIT kunnen gebruiken als x) - pot_model = model4a.Model4a( - k=k, D=D_wvp, c1=c_1, c3=c_3, L1=L1, L3=L3_geom, x_but=(0.0 - L2), x_bit=0.0 - ) - r_exit, r_but, r_bit = pot_model.respons(dist_BIT) - pot_exit = geohydro_functions.calc_respons2pot(pp, r_exit, h) - - # Kwelweglengte - L_kwelweg = pot_model.W1 + dist_BUT - - # uplift - Z_u = piping_functions_old.calc_Z_u(d_pot_c_u, pot_exit, h_exit, mu) - - # heave - i_optredend = piping_functions_old.calc_i_optredend(pot_exit, h_exit, Dcover) - Z_h = piping_functions_old.calc_Z_h(i_c_h, i_optredend, mh) - - # piping - dhc = piping_functions_old.calc_dH_sellmeijer(d70, k, D_wvp, L_kwelweg, gamma_w) - Z_p = piping_functions_old.calc_Z_p(dhc, dhred, mp) - - # combinatie - Z_combin = max(Z_u, Z_h, Z_p) - - return [Z_u,Z_h,Z_p,Z_combin] - diff --git a/app/helper_functions/limitstatepiping_model4a_list_function_implementation.py b/app/helper_functions/limitstatepiping_model4a_list_function_implementation.py deleted file mode 100644 index 269e8172..00000000 --- a/app/helper_functions/limitstatepiping_model4a_list_function_implementation.py +++ /dev/null @@ -1,239 +0,0 @@ -"""Python module for the calculation of the limit state function for piping, heave and uplift in a sand layer with a cover layer.""" - -from typing import List - -from app.helper_functions import geohydro_functions, model4a, piping_functions_old - -# Define the input variables for the functions for Uplift, Heave and Piping -# dist_L_geom: float -# dist_BUT: float -# dist_BIT: float -# L3_geom: float -# mv: float -# pp: float -# top_zand: float -# gamma_sat_cover: float -# gamma_w: float -# kD: float -# D: float -# d70: float -# c1: float -# c3: float -# mu: float -# mh: float -# mp: float -# i_c_h: float -# rc: float -# h: float - - -def calc_Z_combin_piping(X: List[float]) -> List[float]: - r""" - - Gecombineerde grenstoestandfunctie voor uplift, heave en piping. De input X is een lijst met de volgende elementen: - - Args: - X (List[float]): lijst met volgende elementen - X[0] (float): dist_L_geom: geometrische voorlandlengte in m - X[1] (float): dist_BUT: afstand tot de buitenteen in m - X[2] (float): dist_BIT: afstand tot de binnenteen in m - X[3] (float): L3_geom: geometrische achterlandlengte in m - X[4] (float): mv: niveau bij het uittredepunt in m+NAP - X[5] (float): pp: polderpeil in m+NAP - X[6] (float): top_zand: bovenkant van de zandlaag in m+NAP - X[7] (float): gamma_sat_cover: verzadigd volumegewicht van de deklaag in kN/m3 - X[8] (float): gamma_w: volumegewicht van water in kN/m3 - X[9] (float): kD: transmissiviteit watervoerend zandpakket in m2/d - x[10] (float): D: dikte van de watervoerende zandlaag - X[11] (float): d70: 70% percentiel van de korrelgrootteverdeling in m - X[12] (float): c_1: weerstand van de deklaag in het voorland in d - X[13] (float): c_3: weerstand van de deklaag in het achterland in d - X[14] (float): mu: modelfactor voor uplift - X[15] (float): mh: modelfactor voor heave - X[16] (float): mp: modelfactor voor piping - X[17] (float): i_c_h: kritische heave gradient in [-] - X[18] (float): rc: reductiefactor van het verval evenredig met de dikte van de deklaag [-] - X[19] (float): h: buitenwaterstand in m+NAP - - Returns: - Y (List[float]): lijst me de volgende elementen: - Y[0] (float): Dcover: deklaagdikte in m - Y[1] (float): h_exit: niveau uittredepunt m+NAP - Y[2] (float): d_pot_c_u: grenspotentiaal in m - Y[3] (float): dhred: gereduceerd verval in m - Y[4] (float): k: doorlatendheid zandlaag in m/d - Y[5] (float): r_exit: respons in uittredepunt [-] - Y[6] (float): pot_exit: potentiaal in uittredepunt in m+NAP - Y[7] (float): L_kwelweg: kwelweglengte in m - Y[8] (float): i_optredend: optredend heave gradient in [-] - Y[9] (float): dhc: kritiek verval Sellmeijer m - Y[10] (float): Z_u: limit state uplift [-] - Y[11] (float): Z_h: limit state heave [-] - Y[12] (float): Z_p: limit state piping [-] - Y[13] (float): Z_combin: limit state combinatie uplift, heave en piping [-] - """ - [ - dist_L_geom, - dist_BUT, - dist_BIT, - L3_geom, - mv, - pp, - top_zand, - gamma_sat_cover, - gamma_w, - kD, - D, - d70, - c_1, - c_3, - mu, - mh, - mp, - i_c_h, - rc, - h, - ] = X - - # Berekening deklaagdikte - Dcover = piping_functions_old.calc_Dcover(mv, top_zand) - - # Berekening niveau bij het uittredepunt - h_exit = piping_functions_old.calc_h_exit(pp, mv) - - # Berekening gereduceerd verval - dhred = piping_functions_old.calc_dH_red(h, h_exit, rc, Dcover) - - # Berekening grenspotentiaal - d_pot_c_u = piping_functions_old.calc_d_pot_c_u(Dcover, gamma_sat_cover, gamma_w) - - # Berekening geometrische waarden voor potentiaalberekening - L1 = dist_L_geom - dist_BUT - L2 = dist_BUT - dist_BIT - # L3 is al opgegeven - - # potentiaalberekening - k = kD / D - # aanroepen functie potentiaalberekening, x_bit = 0.0 zodat we dist_BIT kunnen gebruiken als x) - pot_model = model4a.Model4a( - k=k, D=D, c1=c_1, c3=c_3, L1=L1, L3=L3_geom, x_but=(0.0 - L2), x_bit=0.0 - ) - r_exit, r_but, r_bit = pot_model.respons(dist_BIT) - pot_exit = geohydro_functions.calc_respons2pot(pp, r_exit, h) - - # Kwelweglengte - L_kwelweg = pot_model.W1 + dist_BUT - - # uplift - Z_u = piping_functions_old.calc_Z_u(d_pot_c_u, pot_exit, h_exit, mu) - - # heave - i_optredend = piping_functions_old.calc_i_optredend(pot_exit, h_exit, Dcover) - Z_h = piping_functions_old.calc_Z_h(i_c_h, i_optredend, mh) - - # piping - dhc = piping_functions_old.calc_dH_sellmeijer(d70, k, D, L_kwelweg, gamma_w) - Z_p = piping_functions_old.calc_Z_p(dhc, dhred, mp) - - # combinatie - Z_combin = max(Z_u, Z_h, Z_p) - - return [Dcover,h_exit,d_pot_c_u,dhred,k,r_exit,pot_exit,L_kwelweg,i_optredend,dhc,Z_u,Z_h,Z_p,Z_combin] - - - -def Z_u(X: List[float]) -> float: - r"""Grenstoestandfunctie voor uplift. - - Args: - X (List[float]): lijst met volgende elementen - X[0] (float): dist_L_geom: geometrische voorlandlengte in m - X[1] (float): dist_BUT: afstand tot de buitenteen in m - X[2] (float): dist_BIT: afstand tot de binnenteen in m - X[3] (float): L3_geom: geometrische achterlandlengte in m - X[4] (float): mv: niveau bij het uittredepunt in m+NAP - X[5] (float): pp: polderpeil in m+NAP - X[6] (float): top_zand: bovenkant van de zandlaag in m+NAP - X[7] (float): gamma_sat_cover: verzadigd volumegewicht van de deklaag in kN/m3 - X[8] (float): gamma_w: volumegewicht van water in kN/m3 - X[9] (float): kD: transmissiviteit watervoerend zandpakket in m2/d - x[10] (float): D: dikte van de watervoerende zandlaag - X[11] (float): d70: 70% percentiel van de korrelgrootteverdeling in m - X[12] (float): c_1: weerstand van de deklaag in het voorland in d - X[13] (float): c_3: weerstand van de deklaag in het achterland in d - X[14] (float): mu: modelfactor voor uplift - X[15] (float): mh: modelfactor voor heave - X[16] (float): mp: modelfactor voor piping - X[17] (float): i_c_h: kritische heave gradient in [-] - X[18] (float): rc: reductiefactor van het verval evenredig met de dikte van de deklaag [-] - X[19] (float): h: buitenwaterstand in m+NAP - - Returns: - Z_u (float): limit state uplift [-] - """ - - return calc_Z_combin_piping(X)[10] - - -def Z_h(X: List[float]) -> float: - r"""Grenstoestandfunctie voor uplift. - - Args: - X (List[float]): lijst met volgende elementen - X[0] (float): dist_L_geom: geometrische voorlandlengte in m - X[1] (float): dist_BUT: afstand tot de buitenteen in m - X[2] (float): dist_BIT: afstand tot de binnenteen in m - X[3] (float): L3_geom: geometrische achterlandlengte in m - X[4] (float): mv: niveau bij het uittredepunt in m+NAP - X[5] (float): pp: polderpeil in m+NAP - X[6] (float): top_zand: bovenkant van de zandlaag in m+NAP - X[7] (float): gamma_sat_cover: verzadigd volumegewicht van de deklaag in kN/m3 - X[8] (float): gamma_w: volumegewicht van water in kN/m3 - X[9] (float): kD: transmissiviteit watervoerend zandpakket in m2/d - x[10] (float): D: dikte van de watervoerende zandlaag - X[11] (float): d70: 70% percentiel van de korrelgrootteverdeling in m - X[12] (float): c_1: weerstand van de deklaag in het voorland in d - X[13] (float): c_3: weerstand van de deklaag in het achterland in d - X[14] (float): mu: modelfactor voor uplift - X[15] (float): mh: modelfactor voor heave - X[16] (float): mp: modelfactor voor piping - X[17] (float): i_c_h: kritische heave gradient in [-] - X[18] (float): rc: reductiefactor van het verval evenredig met de dikte van de deklaag [-] - X[19] (float): h: buitenwaterstand in m+NAP - - Returns: - Z_u (float): limit state uplift [-] - """ - return calc_Z_combin_piping(X)[11] - - -def Z_p(X: List[float]) -> float: - r"""Grenstoestandfunctie voor uplift. - - Args: - X (List[float]): lijst met volgende elementen - X[0] (float): dist_L_geom: geometrische voorlandlengte in m - X[1] (float): dist_BUT: afstand tot de buitenteen in m - X[2] (float): dist_BIT: afstand tot de binnenteen in m - X[3] (float): L3_geom: geometrische achterlandlengte in m - X[4] (float): mv: niveau bij het uittredepunt in m+NAP - X[5] (float): pp: polderpeil in m+NAP - X[6] (float): top_zand: bovenkant van de zandlaag in m+NAP - X[7] (float): gamma_sat_cover: verzadigd volumegewicht van de deklaag in kN/m3 - X[8] (float): gamma_w: volumegewicht van water in kN/m3 - X[9] (float): kD: transmissiviteit watervoerend zandpakket in m2/d - x[10] (float): D: dikte van de watervoerende zandlaag - X[11] (float): d70: 70% percentiel van de korrelgrootteverdeling in m - X[12] (float): c_1: weerstand van de deklaag in het voorland in d - X[13] (float): c_3: weerstand van de deklaag in het achterland in d - X[14] (float): mu: modelfactor voor uplift - X[15] (float): mh: modelfactor voor heave - X[16] (float): mp: modelfactor voor piping - X[17] (float): i_c_h: kritische heave gradient in [-] - X[18] (float): rc: reductiefactor van het verval evenredig met de dikte van de deklaag [-] - X[19] (float): h: buitenwaterstand in m+NAP - - Returns: - Z_u (float): limit state uplift [-] - """ - return calc_Z_combin_piping(X)[12] diff --git a/app/helper_functions/model4a.py b/app/helper_functions/model4a.py deleted file mode 100644 index 89a87c2a..00000000 --- a/app/helper_functions/model4a.py +++ /dev/null @@ -1,89 +0,0 @@ -import math -from dataclasses import dataclass -from typing import Tuple - -from .geohydro_functions import calc_lambda, calc_r_BIT, calc_r_BUT, calc_W - - -@dataclass -class Model4a: - """Class for groundwater model 4A Technisch Rapport Waterspanningen bij Dijken""" - - kD: float - D: float - c1: float - c3: float - L1: float - L3: float - x_but: float - x_bit: float - - @property - def L2(self) -> float: - return abs(self.x_bit - self.x_but) - - @property - def lambda1(self) -> float: - return calc_lambda(self.kD, self.c1) - - @property - def lambda3(self) -> float: - return calc_lambda(self.kD, self.c3) - - @property - def W1(self) -> float: - return calc_W(self.lambda1, self.L1) - - @property - def W3(self) -> float: - return calc_W(self.lambda3, self.L3) - - @property - def W_rad(self) -> float: - return 0.44 * self.D - - @property - def W_tot4a(self) -> float: - return self.W1 + self.L2 + self.W3 - - @property - def r_BUT(self) -> float: - return calc_r_BUT(self.W1, self.L2, self.W3) - - @property - def r_BIT(self) -> float: - return calc_r_BIT(self.W1, self.L2, self.W3) - - def respons(self, x: float) -> Tuple[float, float, float]: - """calculate response at x given model - x positive direction is inwards, so x_but < x_bit""" - - # Before floodplain - if x < self.x_but - self.L1: - r = 1.0 - - # Floodplain - elif x < self.x_but and x >= self.x_but - self.L1: - r = 1.0 - (1.0 - self.r_BUT) * math.sinh( - (self.L1 + x - self.x_but) / self.lambda1 - ) / math.sinh(self.L1 / self.lambda1) - - # Hinterland (where potential is affected) - elif x > self.x_bit and x <= self.x_bit + self.L3: - r = ( - self.r_BIT - * math.sinh((self.L3 - x + self.x_bit) / self.lambda3) - / math.sinh(self.L3 / self.lambda3) - ) - - # - elif x > self.x_bit + self.L3: - r = 0.0 - - # dike - else: - r = self.r_BIT + (self.r_BUT - self.r_BIT) * (self.x_bit - x) / ( - self.x_bit - self.x_but - ) - - return r, self.r_BUT, self.r_BIT \ No newline at end of file diff --git a/app/helper_functions/parameter_functions.py b/app/helper_functions/parameter_functions.py deleted file mode 100644 index 4296f693..00000000 --- a/app/helper_functions/parameter_functions.py +++ /dev/null @@ -1,55 +0,0 @@ - -from collections.abc import Iterable -from typing import Optional - -import pandas as pd - -from app.misc._default_values_constants import ALLOWED_SUFFIXES - - -def strip_suffix_from_parameter_name(var_name: str, list_suffixes: Optional[list[str]] = None) -> str: - suffixes = list_suffixes or ALLOWED_SUFFIXES # Use list_suffixes if provided, otherwise use the default allowed list suffixes - return next((var_name[:-len(suf)] for suf in suffixes if var_name.endswith(suf)), var_name) - - -def strip_suffix_from_list_parameter_names(list_var_names: Iterable[str], list_suffixes: Optional[list[str]] = None) -> list[str]: - if isinstance(list_var_names, str): - raise TypeError("Input must be an iterable of strings (e.g. list/set/pd.Index), not a single string.") - return list(dict.fromkeys([strip_suffix_from_parameter_name(var_name, list_suffixes) for var_name in list_var_names])) # Note: dict.fromkeys is used to remove duplicates while preserving order - - -def generate_parameter_dict_for_variable(attr_name: str, df_overview_row: pd.Series, df_row: pd.Series) -> dict: - return _generate_parameter_dict(attr_name, df_overview_row, df_row=df_row) - -def generate_parameter_dict_for_constant(attr_name: str, df_overview_row: pd.Series) -> dict: - return _generate_parameter_dict(attr_name, df_overview_row, df_row=None) - -def _generate_parameter_dict(attr_name_without_suffix: str, df_overview_row: pd.Series, df_row: Optional[pd.Series] = None) -> dict: - def _get_value(suffix: str, default_col: str): - col = attr_name_without_suffix + suffix - if df_row is not None and col in df_row and not pd.isna(df_row[col]): - # If df_row is provided (i.e. a variable is passed) and the value is not NaN, return the value from df_row - return df_row[col] - elif pd.notna(df_overview_row[default_col]): - # If df_row is None (i.e. a constant is passed) or the value is NaN, use the default value from df_overview (if available) - return df_overview_row[default_col] - else: - raise ValueError(f"Value for '{col}' is not provided in the input Excel. Please check the input data.") - - parameter_dict = { - "name": attr_name_without_suffix, - "type": df_overview_row["parameter_type"], - "distribution": df_overview_row["parameter_distribution"], # Note: all supported distribution strings can be found in probabilistic_library.statistic.DistributionType - "unit": df_overview_row["parameter_unit"], - "lower_bound_mean": df_overview_row["parameter_mean_lower_bound"], - "upper_bound_mean": df_overview_row["parameter_mean_upper_bound"] - } - - if parameter_dict["distribution"] == "deterministic": - parameter_dict["value"] = _get_value("", "parameter_default_value_mean") - else: - parameter_dict["mean"] = _get_value("_mean", "parameter_default_value_mean") - parameter_dict["dispersion_type"] = df_overview_row["parameter_spreidingstype"] - parameter_dict["dispersion_value"] = _get_value(parameter_dict["dispersion_type"], "parameter_default_value_spreiding") - - return parameter_dict \ No newline at end of file diff --git a/app/helper_functions/piping_functions.py b/app/helper_functions/piping_functions.py deleted file mode 100644 index d9d48c55..00000000 --- a/app/helper_functions/piping_functions.py +++ /dev/null @@ -1,382 +0,0 @@ -import math - -from .model4a import Model4a - -################################################################################### -# Functies hieronder direct volgend uit variabelen van input.xlsx -################################################################################### - -def calc_d_deklaag( - mv_exit: float, - top_zand: float - ) -> float: - r""" - - Berekening deklaagdikte, de minimale dikte van de deklaag is 0.1 m omdat negatieve deklaagdiktes niet mogelijk zijn. - - Args: - mv_exit (float): Bodemhoogte ter plaatse van Uittredepunten [m+NAP] - top_zand (float): Geschematiseerde top van het zak in het vak [m+NAP] - - Returns: - float: deklaagdikte [m] - """ - return max(mv_exit - top_zand, 0.1) - - -def calc_h_exit( - polderpeil: float, - mv_exit: float - ) -> float: - r"""Berekening van het niveau van het uittredepunt op basis van polderpeil of maaiveldniveau. - functie geeft de maximale waarde van polderpeil en mv_exit terug. - - Args: - polderpeil (float): polderpeil [m+NAP] - mv_exit (float): maaiveldniveau van uittredepunt [m+NAP] - - Returns: - float: niveau bij het uittredepunt in m+NAP - """ - return max(polderpeil, mv_exit) - -def calc_L_voorland( - L_intrede: float, - L_but:float - ) -> float: - r"""Berekent de geometrische voorlandlengte in m - - Args: - L_intrede (float): afstand van uittredepunten tot binnenteenlijn [m] - L_but (float): afstand van uittredepunten tot buitenteenlijn [m] - - Returns: - float: geometrische voorlandlengte [m] - """ - return abs(L_intrede - L_but) - - -def calc_lambda_achterland( - kD_wvp: float, - c_achterland: float - ) -> float: - r"""Berekent de spreidingslengte van het achterland in m - - .. math:: - - \lambda = \sqrt{kDc} - - Args: - kD (float): Transmissiviteit van het watervoerende pakket [m2/dag] - c_achterland (float): Weerstand van de deklaag in het achterland [dag] - - Returns: - float: spreidingslengte van het achterland [m] - """ - return (kD_wvp * c_achterland)**(1/2) - - -def calc_lambda_voorland( - kD_wvp: float, - c_voorland: float - ) -> float: - r"""Berekent de spreidingslengte van het achterland in m - - .. math:: - - \lambda = \sqrt{kDc} - - Args: - kD (float): Transmissiviteit van het watervoerende pakket [m2/dag] - c_voorland (float): Weerstand van de deklaag in het voorland [dag] - - Returns: - float: spreidingslengte van het voorland [m] - """ - return (kD_wvp * c_voorland)**(1/2) - -################################################################################### -# Functies hieronder bevatten uitkomsten uit bovenliggnde functies als input -################################################################################### - -def calc_dh_red( - buitenwaterstand: float, - h_exit: float, - r_c_deklaag: float, - d_deklaag: float - ) -> float: - r"""Berekening van het gereduceerde verval over de waterkering - - Args: - buitenwaterstand (float): buitenwaterstand [m+NAP] - h_exit (float): Benedestroomse randvoorwaarde verval [m+NAP] - r_c_deklaag (float): Reductieconstante van het verval over de deklaag [-] - d_deklaag (float): deklaagdikte in m - - Returns: - float: gereduceerd verval [m] - """ - return buitenwaterstand - h_exit - r_c_deklaag * d_deklaag - - -def calc_W_achterland( - lambda_achterland: float, - L_achterland: float - ) -> float: - r"""Berekent de geohydrologische weerstand van het achterland in m - - .. math:: - - W = \lambda tanh(\frac{L}{\lambda}) - - Args: - lambda_achterland (float): de spreidingslengte van het achterland [m] - L_achterland (float): afstand van uittredepunten tot achterlandlengte [m] - - Returns: - float: geohydrologische weerstand van het achterland [m] - """ - return lambda_achterland * math.tanh(L_achterland / lambda_achterland) - - -def calc_W_voorland( - lambda_voorland: float, - L_voorland: float - ) -> float: - r"""Berekent de geohydrologische weerstand van het voorland in m - - .. math:: - - W = \lambda tanh(\frac{L}{\lambda}) - - Args: - lambda_voorland (float): de spreidingslengte van het voorland [m] - L_voorland (float): Geometrische voorlandlengte [m] - - Returns: - float: geohydrologische weerstand van het voorland [m] - """ - return lambda_voorland * math.tanh(L_voorland / lambda_voorland) - - -def calc_L_kwelweg( - L_but: float, - W_voorland: float - ) -> float: - r"""Berekent de kwelweglengte in m - Args: - L_but (float): afstand van uittredepunten tot buitenteenlijn [m] - W_voorland (float): geohydrologische weerstand van het voorland [m] - - Returns: - float: kwelweglengte [m] - """ - - return W_voorland + L_but - - -def calc_dphi_c_u( - d_deklaag: float, - gamma_sat_deklaag: float, - gamma_water: float - ) -> float: - r"""Berekening grenspotentiaal ten opzichte van maaiveldniveau in m - - Args: - d_deklaag (float): Dikte van de cohesieve deklaag [m] - gamma_sat_deklaag (float): verzadigd volumegewicht van de deklaag [kN/m3] - gamma_water (float): volumegewicht van water [kN/m3] - - Returns: - float: grenspotentiaal ten opzichte van maaiveldniveau [m] - """ - return d_deklaag * (gamma_sat_deklaag - gamma_water) / gamma_water - - -def calc_i_exit( - phi_exit: float, - h_exit: float, - d_deklaag: float - ) -> float: - r"""Berekening van de optredende heave gradient. De heave gradient is het stijghoogteverschil over de deklaag gedeeld door de deklaagdikte. - - Args: - phi_exit (float): stijghoogte in het watervoerende zandpakket ter plaatse van uittredepunt in m+NAP - h_exit (float): niveau bij het uittredepunt [m+NAP] - d_deklaag (float): deklaagdikte [m] - - Returns: - float: heave gradient in [-] - """ - return (phi_exit - h_exit) / d_deklaag - -# functie om r_exit te berekenen met behulp van model4a module -def calc_r_exit_model4a( - kD_wvp: float, - D_wvp: float, - c_voorland: float, - c_achterland: float, - L_intrede: float, - L_but: float, - L_bit: float, - L_achterland: float, - L_voorland: float - ) -> float: - # L_voorland uitrekenen met behulp van de functie calc_L_voorland - #L_voorland = calc_L_voorland(L_intrede, L_but) - # Maak een Model4a object aan met uitgangspunt x_bit = 0.0. Dit betekent - # dat de lokale x waarde gelijk is aan L_bit. - # uittredepunten moeten altijd binnendijks van de binnenteenlijn liggen, - # # dus x_but moet negatief zijn. - model4a = Model4a( - kD=kD_wvp, - D=D_wvp, - c1=c_voorland, - c3=c_achterland, - L1=L_voorland, - L3=L_achterland, - x_but=-1.0*abs(L_but-L_bit), # x_but moet negatief zijn, x_bit is 0.0 - x_bit=0.0,) # x_bit is 0.0 - # Bereken de respons bij het uittredepunt - r_exit, _, _ = model4a.respons(L_bit) - return r_exit - -def calc_phi_exit( - polderpeil: float, - r_exit: float, - buitenwaterstand: float - ) -> float: # Van respons naar potentiaal - r"""Berekent de theoretische stijghoogte bij uittredepunten in m+NAP - - .. math:: - - \phi_exit(x) = polderpeil + r(x) (buitenwaterstand - polderpeil) - - Args: - polderpeil (float): Benedestroomse randvoorwaarde verval [m+NAP] - r_exit (float): Dempingsfactor bij uittredepunten [-] - buitenwaterstand (float): buitenwaterstand [m+NAP] - - Returns: - float: Theoretische stijghoogte bij uittredepunten [m+NAP] - """ - return polderpeil + r_exit * (buitenwaterstand - polderpeil) - -def calc_dh_c( - d70: float, - D_wvp: float, - kD_wvp: float, - L_kwelweg: float, - gamma_water: float, - g: float, - v: float, - theta: float, - eta: float, - d70_m: float, - gamma_korrel: float, - ) -> float: - r"""Berekening kritiek verval methode Sellmeijer inclusief berekeningsinstellingen - - Args: - d70 (float): 70% percentiel van de korrelgrootteverdeling [m] - D_wvp (float): dikte van het watervoerende pakket [m] - kD_wvp (float): transmissiviteit van het watervoerende pakket [m2/dag] - L_kwelweg (float): kwelweglengte in m - gamma_water (float): volumegewicht van water [kN/m3] - g (float): Zwaartekrachtversnelling [m/s2] - v (float): kinematische viscositeit [m2/s] - theta (float): rolweerstandshoek [graden] - eta (float): coefficiënt van White [-] - d70_m (float): gemiddelde d70 in kleine schaalproeven [m] - gamma_korrel (float): (schijnbaar) volumegewicht van de zandkorrels onder water [kN/m3] - - Returns: - float: kritiek verval [m] - """ - # Berekenen van de doorlatendheid - k_wvp_calc = kD_wvp / D_wvp # Omrekenen transmissiviteit naar doorlatendheid - - # Omrekenen doorlatendheid van m/d naar m/s - k_wvp_calc_sec = k_wvp_calc / (24 * 3600) - # Intrinsieke doorlatendheid - k_intr = (v / g) * k_wvp_calc_sec - # Berekening Fres - Fres = ( - eta - * ((gamma_korrel - gamma_water) / gamma_water) - * math.tan(theta * math.pi / 180.00) - ) - # Berekening Fscale - Fscale = pow(d70 / d70_m, 0.4) * d70_m / pow(k_intr * L_kwelweg, (1.0 / 3.0)) - # Berekening Fgeometry - if D_wvp == L_kwelweg: - D_wvp = D_wvp - 0.001 - else: - pass - totdemacht = 0.04 + (0.28 / (pow(D_wvp / L_kwelweg, 2.8) - 1.0)) - Fgeom = 0.91 * pow(D_wvp / L_kwelweg, totdemacht) - return Fres * Fscale * Fgeom * L_kwelweg - - -################################################################################### -# Z-functies -################################################################################### - -def calc_z_h( - modelfactor_h: float, - i_c_h: float, - i_exit: float - ) -> float: - r"""Grenstoestandfunctie voor het mechanisme heave - - Args: - modelfactor_h (float): modelfactor voor heave - i_c_h (float): kritiek verval [m] - i_exit (float): gereduceerd verval [m] - - Returns: - float: Z waarde van de grenstoestandfunctie voor heave - """ - - return (modelfactor_h * i_c_h) - i_exit - - -def calc_z_u( - modelfactor_u: float, - dphi_c_u: float, - phi_exit: float, - h_exit: float - ) -> float: - r"""Grenstoestandfunctie voor het mechanisme opbarsten (uplift) - - Args: - modelfactor_u (float): modelfactor voor uplift - dphi_c_u (float): kritiek verval [m] - phi_exit (float): stijghoogte in het watervoerende zandpakket ter plaatse van uittredepunt [m+NAP] - h_exit (float): niveau bij het uittredepunt [m+NAP] - - Returns: - float: Z waarde van de grenstoestandfunctie voor uplift - """ - - return modelfactor_u * dphi_c_u - (phi_exit - h_exit) - -def calc_z_p( - modelfactor_p: float, - dh_c: float, - dh_red: float - ) -> float: - r"""Grenstoestandfunctie voor het mechanisme piping - - Args: - modelfactor_p (float): modelfactor voor piping - dh_c (float): kritiek verval [m] - dh_red (float): gereduceerd verval [m] - - Returns: - float: Z waarde van de grenstoestandfunctie voor piping - """ - - return (modelfactor_p * dh_c) - dh_red - - diff --git a/app/helper_functions/piping_functions_old.py b/app/helper_functions/piping_functions_old.py deleted file mode 100644 index 53989280..00000000 --- a/app/helper_functions/piping_functions_old.py +++ /dev/null @@ -1,313 +0,0 @@ -"""This module contains multiple functions as defined in :cite:t:`sh_piping_2021`""" - -import math - -############################################################################################################ -# General functions -############################################################################################################ - - -def calc_Dcover( - bodemhoogte: float, zandhoogte: float -) -> float: # Functie voor berekening deklaagdikte - r""" - - Berekening deklaagdikte, de minimale dikte van de deklaag is 0.1 m omdat negatieve deklaagdiktes niet mogelijk zijn. - - Args: - bodemhoogte (float): hoogte van de bodem in m+NAP - zandhoogte (float): hoogte van de zandlaag in m+NAP - - Returns: - float: deklaagdikte in m - """ - return max(bodemhoogte - zandhoogte, 0.1) - - -def calc_h_exit(na: float, nb: float): - r"""Berekening van het niveau van het uittredepunt op basis van polderpeil of maaiveldniveau. - functie geeft de maximale waarde van na en nb terug. - - Args: - na (float): niveau 1(polderpeil) in m+NAP - nb (float): niveau 2 (maaiveldniveau) in m+NAP - - Returns: - float: niveau bij het uittredepunt in m+NAP - """ - return max(na, nb) - - -def calc_dH_red(h: float, h_exit: float, rc: float, Dcover: float) -> float: - r"""Berekening van het gereduceerde verval over een waterkering - - Args: - h (float): buitenwaterstand in m+NAP - h_exit (float): niveau bij het uittredepunt in m+NAP - rc (float): reductiefactor van het verval evenredig met de dikte van de deklaag [-] - Dcover (float): deklaagdikte in m - - Returns: - float: gereduceerd verval in m - """ - return h - h_exit - rc * Dcover - - -############################################################################################################ -# Functions for uplift and heave -############################################################################################################ - - -# Berekening grenspotentiaal -def calc_d_pot_c_u(d_cover: float, gamma_sat_cover: float, gamma_w: float) -> float: - r"""Berekening grenspotentiaal ten opzichte van maaiveldniveau. - - Args: - d_cover (float): deklaagdikte in m - gamma_sat_cover (float): verzadigd volumegewicht van de deklaag in kN/m3 - gamma_w (float): volumegewicht van water in kN/m3 - - Returns: - float: grenspotentiaal in m ten opzichte van maaiveldniveau - """ - return d_cover * (gamma_sat_cover - gamma_w) / gamma_w - - -# Berekening Z-functie opbarsten -def calc_Z_u(d_pot_c_u: float, pot_exit: float, h_exit: float, mu: float) -> float: - r"""Grenstoestandfunctie voor opbarsten (uplift). - - Args: - d_pot_c_u (float): grenspotentiaal in m ten opzichte van maaiveldniveau - pot_exit (float): stijghoogte ter plaatse van uittredepunt in m+NAP - h_exit (float): niveau bij het uittredepunt in m+NAP - mu: modelfactor voor uplift - - Returns: - float: Z waarde van de grenstoestandfunctie voor opbarsten - """ - return mu * d_pot_c_u - (pot_exit - h_exit) - - -# Berekening veiligheidsfactor opbarsten op basis van stijghoogte -def calc_F_u(d_pot_c_u: float, pot_exit: float, h_exit: float) -> float: - r"""Berekening van de veiligheidsfactor voor opbarsten op basis van effectieve spanningen - - Args: - d_pot_c_u (float): grenspotentiaal in m ten opzichte van maaiveldniveau - pot_exit (float): stijghoogte ter plaatse van uittredepunt in m+NAP - h_exit (float): niveau bij het uittredepunt in m+NAP - - Returns: - float: veiligheidsfactor voor opbarsten op basis stijghoogte - """ - if pot_exit <= h_exit: - Fu = 8.00 - else: - Fu = d_pot_c_u / (pot_exit - h_exit) - return Fu - - -# Berekening veiligheidsfactor opbarsten op basis van spanningen -def calc_F_u_macro( - d_cover: float, - gamma_sat_cover: float, - gamma_w: float, - pot_exit: float, - h_exit: float, -) -> float: - r"""Berekening van de veiligheidsfactor voor opbarsten op basis van spanningen ter plaatse van scheidingsvlak tussen deklaag en zandlaag. Deze methode wordt toegepast bij macrostabiliteit. - - Args: - d_cover (float): deklaagdikte in m - gamma_sat_cover (float): verzadigd volumegewicht van de deklaag in kN/m3 - gamma_w (float): volumegewicht van water in kN/m3 - pot_exit (float): stijghoogte ter plaatse van uittredepunt in m+NAP - h_exit (float): niveau bij het uittredepunt in m+NAP - - Returns: - float: veiligheidsfactor voor opbarsten op basis van spanningen - """ - if pot_exit <= h_exit: - Fu = 8.00 - else: - # opwaartse waterdruk in WVP - sigma_w = (pot_exit - (h_exit - d_cover)) * gamma_w - # neerwaartse druk grond - sigma_g = d_cover * gamma_sat_cover - # Fu_macro is verhouding neerwaarts / opwaarts - Fu = sigma_g / sigma_w - return Fu - - -def calc_i_optredend( - pot_exit: float, h_exit: float, d_cover: float -) -> float: # Berekening optreden heave gradient - r"""Berekening van de optredende heave gradient. De heave gradient is het stijghoogteverschil over de deklaag gedeeld door de deklaagdikte. - - Args: - pot_exit (float): stijghoogte in het watervoerende zandpakket ter plaatse van uittredepunt in m+NAP - h_exit (float): niveau bij het uittredepunt in m+NAP - d_cover (float): deklaagdikte in m - - Returns: - float: heave gradient in [-] - """ - return (pot_exit - h_exit) / d_cover - - -def calc_Z_h( - i_c_h: float, i_optredend: float, mh: float -) -> float: # Berekening Z-functie heave - r"""Berekening van de grenstoesstandfunctie voor heave - - Args: - i_c_h (float): kritische heave gradient in [-] - i_optredend (float): optredende heave gradient in [-] - - Returns: - float: Z waarde van de grenstoestandfunctie voor heave - """ - return (mh * i_c_h) - i_optredend - - -def calc_F_h( - i_c_h: float, i_optredend: float -) -> float: # Berekening veiligheidsfactor heave - r""" - - Berekening van de veiligheidsfactor F_h voor heave. Als de optredende heave gradient negatief is, wordt de - veiligheidsfactor op 5.00 gezet. - - Args: - i_c_h (float): kritische heave gradient in [-] - i_optredend (float): optredende heave gradient in [-] - - Returns: - float: veiligheidsfactor voor heave - """ - if i_optredend <= 0: - F_h = 8.00 - else: - F_h = i_c_h / i_optredend - return F_h - - -############################################################################################################ -# functions piping -############################################################################################################ - - -# functions from PipingCalculationUtilities -def calc_dH_sellmeijer_inc_calc_settings( - d70: float, - k_z: float, - D: float, - L: float, - gamma_w: float, - visc: float, - theta: float, - coefficient_white: float, - d70_ref: float, - gamma_p: float, -) -> float: # Functie voor berekening kritiek verval Sellmeijer - r"""Berekening kritiek verval methode Sellmeijer inclusief berekeningsinstellingen - - Args: - d70 (float): 70% percentiel van de korrelgrootteverdeling in m - k_z (float): doorlatendheid zandlaag in m/d - D (float): dikte van de zandlaag in m - L (float): kwelweglengte in m - gamma_w (float): volumegewicht van water in kN/m3 - visc (float): kinematische viscositeit in m2/s - theta (float): rolweerstandshoek in graden (37.0) - coefficient_white (float): coefficiënt van White (0.25) - d70_ref (float): gemiddelde d70 in kleine schaalproeven (2.08E-4 m) - gamma_p (float): (schijnbaar) volumegewicht van de zandkorrels onder water in kN/m3 (26.0) - - Returns: - float: kritiek verval in m - """ - # Omrekenen doorlatendheid van m/d naar m/s - k = k_z / (24 * 3600) - # Intrinsieke doorlatendheid - k_intr = (visc / 9.81) * k - # Berekening Fres - Fres = ( - coefficient_white - * ((gamma_p - gamma_w) / gamma_w) - * math.tan(theta * math.pi / 180.00) - ) - # Fres = 0.25 * ((26.0 - gamma_w) / gamma_w) * math.tan(37.0 * math.pi / 180.00) - # Berekening Fscale - Fscale = pow(d70 / d70_ref, 0.4) * d70_ref / pow(k_intr * L, (1.0 / 3.0)) - # Berekening Fgeometry - if D == L: - D = D - 0.001 - else: - pass - totdemacht = 0.04 + (0.28 / (pow(D / L, 2.8) - 1.0)) - Fgeom = 0.91 * pow(D / L, totdemacht) - return Fres * Fscale * Fgeom * L - - -# deze functie is gevalideerd aan de resultaten in riskeer. Dit is de functie van de LBO1 piping berekening. -# het verschil met de andere functie is de dat de rolweerstandshoek en sleepkrachtfactor als input worden gegeven. -def calc_dH_sellmeijer( - d70: float, k_z: float, D: float, L: float, gamma_w: float -) -> float: # Functie voor berekening kritiek verval Sellmeijer - r"""Berekening kritiek verval methode Sellmeijer - - Args: - d70 (float): 70% percentiel van de korrelgrootteverdeling in m - k_z (float): doorlatendheid zandlaag in m/d - D (float): dikte van de zandlaag in m - L (float): kwelweglengte in m - gamma_w (float): volumegewicht van water in kN/m3 - - Returns: - float: kritiek verval in m - """ - # Omrekenen doorlatendheid van m/d naar m/s - k = k_z / (24 * 3600) - # Intrinsieke doorlatendheid - k_intr = (0.00000133 / 9.81) * k - # Berekening Fres - Fres = 0.25 * ((26.0 - gamma_w) / gamma_w) * math.tan(37.0 * math.pi / 180.00) - # Berekening Fscale - Fscale = pow(d70 / 2.08e-4, 0.4) * 2.08e-4 / pow(k_intr * L, (1.0 / 3.0)) - # Berekening Fgeometry - if D == L: - D = D - 0.001 - else: - pass - totdemacht = 0.04 + (0.28 / (pow(D / L, 2.8) - 1.0)) - Fgeom = 0.91 * pow(D / L, totdemacht) - return Fres * Fscale * Fgeom * L - - -def calc_Z_p(dhc: float, dhred: float, mp: float) -> float: - r"""Grenstoestandfunctie voor het mechanisme piping - - Args: - mp (float): modelfactor voor piping - dhc (float): kritiek verval in m - dhred (float): gereduceerd verval in m - - Returns: - float: Z waarde van de grenstoestandfunctie voor piping - """ - return (mp * dhc) - dhred - - -def calc_F_p(dhc: float, dhred: float) -> float: - r"""Berekening van de veiligheidsfactor F_p voor piping. Als het gereduceerde verval kleiner of gelijk aan 0.01, wordt gerekend met een gereduceerd verval van 0.01._ - - Args: - dhc (float): kritiek verval in m - dhred (float): gereduceerd verval in m - - Returns: - float: veiligheidsfactor voor piping - """ - return dhc / max(dhred, 0.01) diff --git a/app/helper_functions/statistics_utils.py b/app/helper_functions/statistics_utils.py deleted file mode 100644 index f51fe486..00000000 --- a/app/helper_functions/statistics_utils.py +++ /dev/null @@ -1,18 +0,0 @@ -from scipy.stats import norm - - -def convert_failure_probability_to_beta(failure_probability: float) -> float: - """Converts failure probability (Pf) to the reliability index (β). - - The reliability index is the negative inverse of the standard normal - cumulative distribution function (Φ) applied to the failure probability. - - β = -1 * Φ⁻¹(Pf) - - Args: - failure_probability (float): failure probability (Pf) - - Returns: - float: reliability index (β) - """ - return float(-1 * norm.ppf(failure_probability)) \ No newline at end of file diff --git a/app/helper_functions/stats_utils.py b/app/helper_functions/stats_utils.py deleted file mode 100644 index 534789f4..00000000 --- a/app/helper_functions/stats_utils.py +++ /dev/null @@ -1,147 +0,0 @@ -import math -import scipy.stats as stats #importeer de scipy.stats module -import numpy as np - -#lognormale verdeling -def calc_kar_waarde_met_Vc (Verwachtingswaarde: float, Vc: float, Percentiel: float, Shift = 0.0) -> float: - r"""Berekening van de percentiel waarde van een lognormale verdeling - met variatiecoëfficiënt en verschuiving. - - Args: - Verwachtingswaarde (float): verwachtingswaarde van de lognormale verdeling - Vc (float): variatiecoëfficiënt van de lognormale verdeling - Percentiel (float): percentiel waarvoor de waarde van de lognormale verdeling wordt berekend - Shift (float, optional): verschuiving. Defaults to 0.0. - - Returns: - float: percentiel waarde van de lognormale verdeling - """ - sd = Vc * Verwachtingswaarde - Vc_shift = sd / (Verwachtingswaarde - Shift) - log_sd = math.sqrt(math.log(1.0 + math.pow(Vc_shift, 2.0))) - log_mu = math.log(Verwachtingswaarde - Shift) - 0.5 * math.pow(log_sd, 2.0) - return float(stats.lognorm.ppf(Percentiel, s = log_sd, loc = 0.0, scale = math.exp(log_mu))) + Shift - - -def calc_kar_waarde_met_sd(Verwachtingswaarde: float, sd: float, Percentiel: float, Shift = 0.0)-> float: - r"""Berekening van de percentiel waarde van een lognormale verdeling - met standaarddeviatie en verschuiving. - - Args: - Verwachtingswaarde (float): verwachtingswaarde van de lognormale verdeling - sd (float): standaarddeviatie van de lognormale verdeling - Percentiel (float): percentiel waarvoor de waarde van de lognormale verdeling wordt berekend - Shift (float, optional): verschuiving. Defaults to 0.0. - - Returns: - float: percentiel waarde van de lognormale verdeling - """ - Vc_shift = float(sd / (Verwachtingswaarde - Shift)) - log_sd = math.sqrt(math.log(1.0 + math.pow(Vc_shift, 2.0))) - log_mu = math.log(Verwachtingswaarde - Shift) - 0.5 * math.pow(log_sd, 2.0) - return float(stats.lognorm.ppf(Percentiel, s = log_sd, loc = 0.0, scale = math.exp(log_mu))) + Shift - -#normale verdeling -def calc_kar_waarde_normaal(Verwachtingswaarde: float, std: float, Percentiel: float) -> float: - """Berekening van de percentiel waarde van een normale verdeling - - Args: - Verwachtingswaarde (float): verwachtingswaarde van de normale verdeling - std (float): standaarddeviatie van de normale verdeling - Percentiel (float): percentiel waarvoor de waarde van de normale verdeling wordt berekend - - Returns: - float: percentiel waarde van de normale verdeling - """ - return float(stats.norm.ppf(Percentiel, loc= Verwachtingswaarde, scale=std)) - -#Berekenen parameters Gumbel verdeling - -# a = Gumbel location parameter -# b = Gumbel dispersion parameter - -#WBN = 15.12 # waterstand bij norm -#dec = 0.46 # decimeringshoogte -#norm = 1/10000.0 # overschrijdingkans WBN - -# Analytical solution a and b -#a = WBN + dec * np.log(-(np.log(1-norm))) / (np.log(-np.log(1-norm))-np.log(-np.log(1-norm/10))); -#b = dec /(np.log(-np.log(1-norm))-np.log(-np.log(1-norm/10))); - -def calc_Gumbel_parameters(WBN: float, dec: float, norm: float, parameter = 'a') -> float: - r"""Berekening van de parameters van de Gumbel verdeling op basis van WBN, decimeringshoogte - en overschrijdingskans van WBN - - Args: - WBN (float): Waterstand Bij Norm in m+NAP - dec (float): decimeringshoogte in m - norm (float): overschrijdingskans WBN - parameter (str, optional): a = Gumbel location(shift) parameter, - b = Gumbel dispersion(scale) parameter. Defaults to 'a'. - - Returns: - float: parameter a of b van de Gumbel verdeling - """ - if parameter == 'a': - return WBN + dec * np.log(-(np.log(1-norm))) / (np.log(-np.log(1-norm))-np.log(-np.log(1-norm/10))) - elif parameter == 'b': - return dec /(np.log(-np.log(1-norm))-np.log(-np.log(1-norm/10))) - else: - return 999.0 - -#a = shift, b = scale - -def calc_Gumbel_parameters_fromShiftScale(a: float, b: float, parameter = 'sd') -> float: - """Berekening van de standaarddeviatie of de verwachtingswaarde van de Gumbel verdeling op - basis van de shift en scale parameters - - Args: - a (float): Gumbel shift parameter - b (float): Gumbel scale parameter - parameter (str, optional): sd = standaarddeviatie of mean = gemiddelde. Defaults to 'sd'. - - Returns: - float: _description_ - """ - - if parameter == 'sd': #standaardafwijking - return (math.pi/math.sqrt(6.0)) * b - elif parameter == 'mean': #mean - return a + (b * np.euler_gamma) - else: - return 999.0 - -#todo: add tests -#todo: add type hints -#todo: van een karakteristieke waarde en een gemiddelde waarde de standaarddeviatie berekenen voor een lognormale verdeling - - -def calc_std_and_cv(percentile: float, mean: float, percentile_value: float) -> tuple: - """ - Calculate the standard deviation and coefficient of variation for a normal distribution. - - Args: - percentile (float): The percentile (e.g., 0.95 for the 95th percentile). - mean (float): The mean of the normal distribution. - percentile_value (float): The value at the given percentile. - - Returns: - tuple: A tuple containing the standard deviation and the coefficient of variation. - """ - # Calculate the z-score for the given percentile - z = stats.norm.ppf(percentile) - - # Calculate the standard deviation - std = (percentile_value - mean) / z - - # Calculate the coefficient of variation - cv = std / mean - - return std, cv - -# Example usage -#percentile = 0.95 -#mean = 100 -#percentile_value = 120 -#std, cv = calc_std_and_cv(percentile, mean, percentile_value) -#print(f"Standard Deviation: {std}, Coefficient of Variation: {cv}") \ No newline at end of file diff --git a/app/helper_functions/z_functions.py b/app/helper_functions/z_functions.py deleted file mode 100644 index 87e8e084..00000000 --- a/app/helper_functions/z_functions.py +++ /dev/null @@ -1,230 +0,0 @@ -import app.helper_functions.piping_functions as piping_functions - - -def calc_Z_h( - L_achterland: float, - c_voorland: float, - c_achterland: float, - L_intrede: float, - L_but: float, - L_bit: float, - polderpeil: float, - buitenwaterstand: float, - mv_exit: float, - top_zand: float, - kD_wvp: float, - modelfactor_h: float, - i_c_h: float, - D_wvp: float, - ) -> float: - r"""Berekening van de grenstoesstandfunctie voor heave - - Returns: - float: Z waarde van de grenstoestandfunctie voor heave - """ - - L_voorland = piping_functions.calc_L_voorland( - L_intrede = L_intrede, - L_but = L_but, - ) - - r_exit = piping_functions.calc_r_exit_model4a( - kD_wvp=kD_wvp, - D_wvp=D_wvp, - c_voorland=c_voorland, - c_achterland=c_achterland, - L_intrede=L_intrede, - L_but=L_but, - L_bit=L_bit, - L_achterland=L_achterland, - L_voorland=L_voorland - ) - - phi_exit = piping_functions.calc_phi_exit( - polderpeil = polderpeil, - r_exit = r_exit, - buitenwaterstand = buitenwaterstand - ) - - h_exit = piping_functions.calc_h_exit( - polderpeil = polderpeil, - mv_exit = mv_exit - ) - - d_deklaag = piping_functions.calc_d_deklaag( - mv_exit = mv_exit, - top_zand = top_zand - ) - - i_exit = piping_functions.calc_i_exit( - phi_exit = phi_exit, - h_exit = h_exit, - d_deklaag = d_deklaag - ) - - z_h = piping_functions.calc_z_h( - i_c_h = i_c_h, - i_exit = i_exit, - modelfactor_h = modelfactor_h - ) - - return z_h - - -def calc_Z_u( - L_achterland: float, - c_voorland: float, - c_achterland: float, - polderpeil: float, - buitenwaterstand: float, - L_intrede: float, - L_but: float, - L_bit: float, - mv_exit: float, - top_zand: float, - kD_wvp: float, - modelfactor_u: float, - gamma_water: float, - gamma_sat_deklaag: float, - D_wvp: float, - ) -> float: - r"""Grenstoestandfunctie voor opbarsten (uplift). - - Returns: - float: Z waarde van de grenstoestandfunctie voor opbarsten - """ - - L_voorland = piping_functions.calc_L_voorland( - L_intrede = L_intrede, - L_but = L_but, - ) - - r_exit = piping_functions.calc_r_exit_model4a( - kD_wvp=kD_wvp, - D_wvp=D_wvp, - c_voorland=c_voorland, - c_achterland=c_achterland, - L_intrede=L_intrede, - L_but=L_but, - L_bit=L_bit, - L_achterland=L_achterland, - L_voorland=L_voorland - ) - - phi_exit = piping_functions.calc_phi_exit( - polderpeil = polderpeil, - r_exit = r_exit, - buitenwaterstand = buitenwaterstand - ) - - h_exit = piping_functions.calc_h_exit( - polderpeil = polderpeil, - mv_exit = mv_exit, - ) - - d_deklaag = piping_functions.calc_d_deklaag( - mv_exit= mv_exit, - top_zand = top_zand - ) - - dphi_c_u = piping_functions.calc_dphi_c_u( - d_deklaag = d_deklaag, - gamma_sat_deklaag = gamma_sat_deklaag, - gamma_water = gamma_water - ) - - z_u = piping_functions.calc_z_u( - dphi_c_u = dphi_c_u, - phi_exit = phi_exit, - h_exit = h_exit, - modelfactor_u = modelfactor_u - ) - - return z_u - - -def calc_Z_p( - c_voorland: float, - buitenwaterstand: float, - polderpeil: float, - mv_exit: float, - L_but: float, - L_intrede: float, - modelfactor_p: float, - d70: float, - D_wvp: float, - kD_wvp: float, - top_zand: float, - gamma_water: float, - g: float, - v: float, - theta: float, - eta: float, - d70_m: float, - gamma_korrel: float, - r_c_deklaag: float, - ) -> float: - - r"""Grenstoestandfunctie voor het mechanisme piping - - Returns: - float: Z waarde van de grenstoestandfunctie voor piping - """ - - L_voorland = piping_functions.calc_L_voorland( - L_intrede = L_intrede, - L_but = L_but, - ) - - lambda_voorland = piping_functions.calc_lambda_voorland( - kD_wvp = kD_wvp, - c_voorland = c_voorland - ) - - W_voorland = piping_functions.calc_W_voorland( - lambda_voorland = lambda_voorland, - L_voorland = L_voorland - ) - - L_kwelweg = piping_functions.calc_L_kwelweg( - L_but = L_but, - W_voorland = W_voorland - ) - - dh_c = piping_functions.calc_dh_c( - d70 = d70, - D_wvp = D_wvp, - kD_wvp = kD_wvp, - L_kwelweg = L_kwelweg, - gamma_water = gamma_water, - g = g, - v = v, - theta = theta, - eta = eta, - d70_m = d70_m, - gamma_korrel = gamma_korrel - ) - - h_exit = piping_functions.calc_h_exit( - polderpeil = polderpeil, - mv_exit = mv_exit - ) - - d_deklaag = piping_functions.calc_d_deklaag( - mv_exit = mv_exit, - top_zand = top_zand - ) - - dh_red = piping_functions.calc_dh_red( - buitenwaterstand = buitenwaterstand, - h_exit = h_exit, - r_c_deklaag = r_c_deklaag, - d_deklaag = d_deklaag - ) - z_p = piping_functions.calc_z_p( - dh_c = dh_c, - dh_red = dh_red, - modelfactor_p = modelfactor_p - ) - - return z_p \ No newline at end of file diff --git a/app/main_piping.py b/app/main_piping.py deleted file mode 100644 index 34196229..00000000 --- a/app/main_piping.py +++ /dev/null @@ -1,73 +0,0 @@ -import sys -from datetime import datetime -from pathlib import Path - -sys.path.append(str(Path(__file__).parents[1])) # Add repo to sys.path to make sure all imports are correctly found - -from app.classes.project import Project - -# ==================================== -# User Input Section -# ==================================== - -# Define path to workspace (either absolute or relative) -PATH_WORKSPACE: str | Path = r"..\\workspaces\example_new_calculations" - -#FIXME implement feature to re-use existing results -# # Whether existing calculation results should be used -# # If True, the .tkx files that are found the "PATH_WORKSPACE/output" folder are used -# USE_EXISTING_TKX_RESULTS: bool = False - -# ==================================== -# End of User Input Section -# ==================================== - - -def start_tool( - PATH_WORKSPACE: str | Path, -) -> Project: - """Start PTK tool - Args: - PATH_WORKSPACE: path to the folder that contains all required input and where all output and working files will be stored - - Returns: - Project: project instance - """ - time_start = datetime.now() - print(f"Start time: {time_start.strftime('%d %b %Y %H:%M:%S')}") - - # Setup project and automatically start calculations - project = Project( - PATH_WORKSPACE, - ) - - # Print hints how to interacts with the results - print("\nHINTS:\n \t- Show the different result DataFrames using `project.results.unique` or `project.results.combined_models` or `project.results.uittredepunt`") - results_unique_models = project.results.unique - results_combined = project.results.combined_models - results_uittredepunt = project.results.uittredepunt - - - # Save DataFrame of combined results to csv - # # FIXME improve output data - results_uittredepunt.to_excel(project.workspace.output.folderpath / "fragility_curve_data_combined.xlsx") - - # # Print info - # print(f"\nResults are saved to: {fc.workspace.output.folderpath}") - - time_end = datetime.now() - time_diff = time_end - time_start - print(f"\nFinished succesfully, end time: {time_end.strftime('%d %b %Y %H:%M:%S')}") - print( - f"Total runtime (h:m:s): {int(time_diff.total_seconds() // 3600):02}:{int((time_diff.total_seconds() % 3600) // 60):02}:{int(time_diff.total_seconds() % 60):02}" - ) - - return project - - -if __name__ == "__main__": - - # Run tool - project = start_tool( - PATH_WORKSPACE - ) diff --git a/app/misc/_default_values_constants.py b/app/misc/_default_values_constants.py deleted file mode 100644 index 46466d9a..00000000 --- a/app/misc/_default_values_constants.py +++ /dev/null @@ -1,7 +0,0 @@ -""" -Collection of constants used thoughout the app -""" - -# Default values and constants related to the input Excel file -ALLOWED_DISPERSION_TYPES = ["_stdev", "_vc"] # Dispersion types (belonging to distribution types) that are allowed in the input Excel file. _stdev=standard deviation, _vc=variance coefficient -ALLOWED_SUFFIXES = ["_mean"] + ALLOWED_DISPERSION_TYPES # Variable suffixes (not part of the variable name) allowed in the input Excel file (e.g. '_mean' in 'c_voorland_mean') diff --git a/dev-requirements.txt b/dev-requirements.txt deleted file mode 100644 index 6d3bdc95..00000000 --- a/dev-requirements.txt +++ /dev/null @@ -1,6 +0,0 @@ -# black==24.4.2 #already in vscode -# mypy==1.11.0 #already in vscode -# isort==5.13.2 #already in vscode -sphinx -sphinxcontrib-bibtex -pytest==8.3.4 \ No newline at end of file diff --git a/docs/Assembleren.rst b/docs/Assembleren.rst new file mode 100644 index 00000000..fbf04750 --- /dev/null +++ b/docs/Assembleren.rst @@ -0,0 +1,440 @@ +.. _assembleren: + +.. contents:: + :local: + :depth: 3 + + +Assembleren +=========== + +Doel en scope +------------- + +Deze pagina beschrijft de assemblage van faalkansen binnen `GeoProb-Pipe` +voor het faalmechanisme STPH (piping). +De assemblage combineert lokaal berekende faalkansen op uittredepuntniveau +tot faalkansen op vak- en trajectniveau. + +Bron en afbakening +------------------ + +De assemblage van faalkansen in GeoProb-Pipe is conceptueel gebaseerd op +de bottom-up assemblage zoals beschreven door het Adviesteam Dijkontwerp +in :cite:`AdviesteamDijkontwerp2024Assembleren`. + +In deze publicatie wordt de assemblage beschreven vanuit een klassieke +opzet, waarbij faalkansen op doorsnedeniveau worden opgeschaald naar +vak- en trajectniveau. + +GeoProb-Pipe volgt dezelfde **systemische principes** (seriesysteem, +lengte-effect, SOM/MAX), maar hanteert een **andere elementaire +bouwsteen**: + +*De assemblage start niet bij een doorsnede, maar bij een uittredepunt, +waarin meerdere deelfaalmechanismen van STPH en ondergrondscenario’s +probabilistisch worden gecombineerd.* + +Hierdoor wijkt met name de eerste stap van de assemblage inhoudelijk af +van Rode draad #10, terwijl de vervolgstappen hiermee consistent blijven. + +Conceptuele opbouw (hiërarchie) +------------------------------- + +.. figure:: _static/Hierarchie_berekeningen.png + :width: 95% + :align: center + + Hiërarchische opbouw van faalkansen in GeoProb-Pipe van uittredepunt + tot trajectniveau. + +Stap 1: Scenario → uittredepunt +------------------------------- + +In GeoProb-Pipe vormt het **uittredepunt** de kleinste zelfstandige +bouwsteen in de assemblage van faalkansen. +Een uittredepunt representeert een fysieke locatie langs de waterkering +waar piping kan initiëren. + +In tegenstelling tot de klassieke BOI-benadering wordt geen enkele +doorsnede beschouwd, maar een **hiërarchische combinatie van +faalmechanismen en scenario’s**. + +Faalmechanismen en scenario’s +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Per uittredepunt worden meerdere faalmechanismen beschouwd, waaronder: + +- uplift +- heave +- piping + +Voor elk faalmechanisme worden meerdere hydraulische en geotechnische +scenario’s doorgerekend. +Per scenario wordt een faalkans bepaald, inclusief bijbehorende +FORM-resultaten (β en α). + +De faalkans per scenario wordt bepaald met Importance Sampling rondom +de FORM-design points. + +Combinatie tot faalkans per uittredepunt +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +De faalkans van een uittredepunt volgt uit de combinatie van alle +scenario’s die tot falen kunnen leiden: + +.. math:: + + P_{f,\mathrm{uittrede}} = + \sum_{i=1}^{N_\mathrm{scen}} + P(\mathrm{scenario}_i)\, P_f(\mathrm{scenario}_i) + +De bijbehorende betrouwbaarheidsindex volgt uit: + +.. math:: + + \beta_{\mathrm{uittrede}} = -\Phi^{-1}(P_{f,\mathrm{uittrede}}) + +De richting van falen (α-vector) wordt **niet gemiddeld**, maar +overgenomen uit het **meest ongunstige scenario**, omdat dit scenario +dominant is voor het optreden van falen. + +Stap 2: Uittredepunt → vak +-------------------------- + +Een dijkvak bevat meerdere uittredepunten waar piping kan initiëren. +De faalkans per vak volgt uit het combineren van deze bijdragen, +rekening houdend met het lengte-effect. + +Lengte-effect en opschaling +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Het aantal effectieve, onafhankelijke bijdragen binnen een vak wordt +benaderd met: + +.. math:: + + N_{\mathrm{vak}} = + \max\left( + 1,\; + a_{\mathrm{vak}} \frac{L_{\mathrm{vak}}}{\Delta L} + \right) + +waarbij: + +- :math:`L_{\mathrm{vak}}` de lengte van het vak is; +- :math:`\Delta L` de equivalente onafhankelijke lengte voor STPH; +- :math:`a_{\mathrm{vak}}` de mechanismegevoelige fractie van het vak. + +Bepaling van de faalkans per vak +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +De faalkans van het vak wordt bepaald met: + +.. math:: + + P_{f,\mathrm{vak}} = + N_{\mathrm{vak}} \cdot P_{f,\mathrm{uittrede,rep}} + +Hierin is :math:`P_{f,\mathrm{uittrede,rep}}` de representatieve +faalkans per uittredepunt binnen het vak. + +De ondergrens van de vakkans wordt bepaald door de grootste individuele +uittredepuntfaalkans; de bovengrens volgt uit de SOM-benadering. + +Stap 3: Vak → traject +---------------------- + +Een dijktraject bestaat uit meerdere dijkvakken en wordt beschouwd als +een seriesysteem: falen van één vak leidt tot falen van het traject. + +Bepaling van de trajectfaalkans +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Het lengte-effect is volledig verwerkt op vakniveau via +:math:`N_{\mathrm{vak}}`. +Daarom worden vakkansen op trajectniveau **niet opnieuw opgeschaald**. + +Voor STPH wordt de trajectfaalkans benaderd met: + +.. math:: + + P_{f,\mathrm{traject}} = + \sum_{k=1}^{N_{\mathrm{vak}}} P_{f,\mathrm{vak},k} + +De bijbehorende betrouwbaarheidsindex volgt uit: + +.. math:: + + \beta_{\mathrm{traject}} = -\Phi^{-1}(P_{f,\mathrm{traject}}) + +De α-vector op trajectniveau wordt overgenomen uit het +**meest ongunstige vak**. + +Bepaling van β en α bij assemblage +---------------------------------- + +Bij het combineren van kansen in GeoProb-Pipe wordt onderscheid gemaakt +tussen: + +- de **grootte van de faalkans** (:math:`P_f`, β); +- de **richting van falen** (α). + +Bij kanscombinaties (scenario → uittredepunt → vak → traject) +wordt de faalkans bepaald via probabilistische aggregatie. + +De bijbehorende α-vector wordt steeds overgenomen uit het +**meest ongunstige onderliggende element**, omdat: + +- α-vectoren niet lineair optelbaar zijn; +- het falen van het systeem wordt gedomineerd door één kritische + faalmodus; +- dit consistent is met het seriesysteem-concept. + +Concreet betekent dit: + +- α\ :sub:`uittredepunt` ← meest ongunstige scenario +- α\ :sub:`vak` ← meest ongunstige uittredepunt +- α\ :sub:`traject` ← meest ongunstige vak + +Samenvatting +------------ + +De assemblage van faalkansen voor STPH in GeoProb-Pipe verloopt +bottom-up, van scenario via uittredepunt en vak naar traject. +Het lengte-effect wordt uitsluitend toegepast bij de overgang van +uittredepunt naar vak, waarmee dubbeltelling wordt voorkomen. + +Deze werkwijze resulteert in een consistente, transparante en +fysisch onderbouwde bepaling van de trajectfaalkans voor piping. + + +.. contents:: + :local: + :depth: 3 + + +Assembleren +=========== + +Doel en scope +------------- + +Deze pagina beschrijft de assemblage van faalkansen binnen `GeoProb-Pipe` +voor het faalmechanisme STPH (piping). +De assemblage combineert lokaal berekende faalkansen op uittredepuntniveau +tot faalkansen op vak- en trajectniveau. + +Bron en afbakening +------------------ + +De assemblage van faalkansen in GeoProb-Pipe is conceptueel gebaseerd op +de bottom-up assemblage zoals beschreven door het Adviesteam Dijkontwerp +in :cite:`AdviesteamDijkontwerp2024Assembleren`. + +In deze publicatie wordt de assemblage beschreven vanuit een klassieke +opzet, waarbij faalkansen op doorsnedeniveau worden opgeschaald naar +vak- en trajectniveau. + +GeoProb-Pipe volgt dezelfde **systemische principes** (seriesysteem, +lengte-effect, SOM/MAX), maar hanteert een **andere elementaire +bouwsteen**: + +*De assemblage start niet bij een doorsnede, maar bij een uittredepunt, +waarin meerdere deelfaalmechanismen van STPH en ondergrondscenario’s +probabilistisch worden gecombineerd.* + +Hierdoor wijkt met name de eerste stap van de assemblage inhoudelijk af +van Rode draad #10, terwijl de vervolgstappen hiermee consistent blijven. + +Conceptuele opbouw (hiërarchie) +------------------------------- + +.. figure:: _static/Hierarchie_berekeningen.png + :width: 95% + :align: center + + Hiërarchische opbouw van faalkansen in GeoProb-Pipe van uittredepunt + tot trajectniveau. + +Stap 1: Scenario → uittredepunt +------------------------------- + +In GeoProb-Pipe vormt het **uittredepunt** de kleinste zelfstandige +bouwsteen in de assemblage van faalkansen. +Een uittredepunt representeert een fysieke locatie langs de waterkering +waar piping kan initiëren. + +In tegenstelling tot de klassieke BOI-benadering wordt geen enkele +doorsnede beschouwd, maar een **hiërarchische combinatie van +faalmechanismen en scenario’s**. + +Faalmechanismen en scenario’s +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Per uittredepunt worden meerdere faalmechanismen beschouwd, waaronder: + +- uplift +- heave +- piping + +Voor elk faalmechanisme worden meerdere hydraulische en geotechnische +scenario’s doorgerekend. +Per scenario wordt een faalkans bepaald, inclusief bijbehorende +FORM-resultaten (β en α). + +De faalkans per scenario wordt bepaald met Importance Sampling rondom +de FORM-design points. + +Combinatie tot faalkans per uittredepunt +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +De faalkans van een uittredepunt volgt uit de combinatie van alle +scenario’s die tot falen kunnen leiden: + +.. math:: + + P_{f,\mathrm{uittrede}} = + \sum_{i=1}^{N_\mathrm{scen}} + P(\mathrm{scenario}_i)\, P_f(\mathrm{scenario}_i) + +De bijbehorende betrouwbaarheidsindex volgt uit: + +.. math:: + + \beta_{\mathrm{uittrede}} = -\Phi^{-1}(P_{f,\mathrm{uittrede}}) + +De richting van falen (α-vector) wordt **niet gemiddeld**, maar +overgenomen uit het **meest ongunstige scenario**, omdat dit scenario +dominant is voor het optreden van falen. + +Stap 2: Uittredepunt → vak +-------------------------- + +Een dijkvak bevat meerdere uittredepunten waar piping kan initiëren. +De faalkans per vak volgt uit het combineren van deze bijdragen, +rekening houdend met het lengte-effect. + +.. _fig-bottom-up-traject: + +.. figure:: _static/bottom-up.png + :alt: Bottom-up assemblage van traject naar vakniveau met SOM/MAX en lengte-effect. + :align: center + :width: 95% + + Schematische weergave van bottom-up assembleren van traject naar + vakniveau. De trajectfaalkans wordt opgebouwd uit vakkansen (SOM/MAX), + waarbij op vakniveau het lengte-effect wordt gemodelleerd via + :math:`N_{\mathrm{vak}}`. + +:numref:`fig-bottom-up-traject` laat zien hoe faalkansen op hoger schaalniveau +worden opgebouwd uit onderliggende elementen en waar het lengte-effect +in de assemblage wordt toegepast. + +Lengte-effect en opschaling +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Het aantal effectieve, onafhankelijke bijdragen binnen een vak wordt +benaderd met: + +.. math:: + + N_{\mathrm{vak}} = + \max\left( + 1,\; + a_{\mathrm{vak}} \frac{L_{\mathrm{vak}}}{\Delta L} + \right) + +waarbij: + +- :math:`L_{\mathrm{vak}}` de lengte van het vak is; +- :math:`\Delta L` de equivalente onafhankelijke lengte voor STPH; +- :math:`a_{\mathrm{vak}}` de mechanismegevoelige fractie van het vak. + +Bepaling van de faalkans per vak +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +De faalkans van het vak wordt bepaald met: + +.. math:: + + P_{f,\mathrm{vak}} = + N_{\mathrm{vak}} \cdot P_{f,\mathrm{uittrede,rep}} + +Hierin is :math:`P_{f,\mathrm{uittrede,rep}}` de representatieve +faalkans per uittredepunt binnen het vak. + +De ondergrens van de vakkans wordt bepaald door de grootste individuele +uittredepuntfaalkans; de bovengrens volgt uit de SOM-benadering. + +In een vervolgstap kan :math:`P_{f,\mathrm{uittrede,rep}}` worden +afgeleid uit DSN-resultaten, bijvoorbeeld via een moving window- +benadering of via een representatieve discretisatie gekoppeld aan +:math:`\Delta L`. + +Stap 3: Vak → traject +---------------------- + +Een dijktraject bestaat uit meerdere dijkvakken en wordt beschouwd als +een seriesysteem: falen van één vak leidt tot falen van het traject. + +Bepaling van de trajectfaalkans +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Het lengte-effect is volledig verwerkt op vakniveau via +:math:`N_{\mathrm{vak}}`. +Daarom worden vakkansen op trajectniveau **niet opnieuw opgeschaald**. + +Voor STPH wordt de trajectfaalkans benaderd met: + +.. math:: + + P_{f,\mathrm{traject}} = + \sum_{k=1}^{N_{\mathrm{vak}}} P_{f,\mathrm{vak},k} + +De bijbehorende betrouwbaarheidsindex volgt uit: + +.. math:: + + \beta_{\mathrm{traject}} = -\Phi^{-1}(P_{f,\mathrm{traject}}) + +De α-vector op trajectniveau wordt overgenomen uit het +**meest ongunstige vak**. + +Bepaling van β en α bij assemblage +---------------------------------- + +Bij het combineren van kansen in GeoProb-Pipe wordt onderscheid gemaakt +tussen: + +- de **grootte van de faalkans** (:math:`P_f`, β); +- de **richting van falen** (α). + +Bij kanscombinaties (scenario → uittredepunt → vak → traject) +wordt de faalkans bepaald via probabilistische aggregatie. + +De bijbehorende α-vector wordt steeds overgenomen uit het +**meest ongunstige onderliggende element**, omdat: + +- α-vectoren niet lineair optelbaar zijn; +- het falen van het systeem wordt gedomineerd door één kritische + faalmodus; +- dit consistent is met het seriesysteem-concept. + +Concreet betekent dit: + +- α\ :sub:`uittredepunt` ← meest ongunstige scenario +- α\ :sub:`vak` ← meest ongunstige uittredepunt +- α\ :sub:`traject` ← meest ongunstige vak + +Samenvatting +------------ + +De assemblage van faalkansen voor STPH in GeoProb-Pipe verloopt +bottom-up, van scenario via uittredepunt en vak naar traject. +Het lengte-effect wordt uitsluitend toegepast bij de overgang van +uittredepunt naar vak, waarmee dubbeltelling wordt voorkomen. + +Deze werkwijze resulteert in een consistente, transparante en +fysisch onderbouwde bepaling van de trajectfaalkans voor piping. + diff --git a/docs/Relatie_beslisraamwerk_piping.rst b/docs/Relatie_beslisraamwerk_piping.rst new file mode 100644 index 00000000..f08e8720 --- /dev/null +++ b/docs/Relatie_beslisraamwerk_piping.rst @@ -0,0 +1,120 @@ +.. _BRP: + +Relatie beslissingsondersteunend raamwerk piping +================================================ + +Het Beslissingsondersteunend Raamwerk Piping (BRP) :cite:t:`BRP_2024` beschrijft een aanpak om aspecten te beschouwen die niet expliciet in de rekenregels zijn opgenomen. +Voor de bepaling van de overstromingskans van het faalmechanisme piping is het daarom belangrijk om ook deze aanvullende aspecten te beschouwen. + +In het BRP zijn 14 factsheets opgenomen waarin factoren worden beschreven die het optreden van piping beïnvloeden. Daarnaast worden handelingsperspectieven gegeven om met deze factoren om te gaan. +DDeze documentatie beschrijft hoe deze aspecten rekenkundig kunnen worden meegenomen +in de overstromingskansberekening met ``GeoProb-Pipe``. Het kennisniveau van elk aspect +bepaalt in welke mate het kan worden geïmplementeerd. + +1. Opbarsten: Sterkte deklaag +------------------------------- +Het is erg aannemelijk dat de deklaag enige weerstand tegen scheuren biedt. +Omdat de scheurbestendigheid nog niet kwantitatief kan worden bepaald en er geen gevalideerd model beschikbaar is, +is dit aspect niet geïmplementeerd in `GeoProb-Pipe`. +Wel kan via een modelfactor opbarsten :math:`m_{u}` gebruikt kunnen worden om gevoeligheidsberekeningen te doen. + +2. Opbarsten: Tijdsafhankelijke stroming en overige geohydrologische invloeden (aspect 2 en 3 uit BRP) +Grondwaterstroming is een bekend en goed bestudeerd fenomeen. Met numerieke +berekeningen kan het effect van een kortdurend hoogwater op de stijghoogte worden +bepaald. Binnen `GeoProb-Pipe` is het rekenmodel voor de stijghoogte flexibel opgezet, zodat +andere stijghoogtemodellen kunnen worden toegepast. + +4. Terugschrijdende erosie: Aanwezigheid voorland (> 1 keer dijkbasis) +Het meenemen van voorlanden sluit aan op de algemeen bekende +grondwaterstromingstheorie. Het voorland kan al meegenomen in de piping analyse conform +het BOI, er is een uitwerkingsmethode en benodigde parameters kunnen worden bepaald +door meten en monitoren. Daarnaast is mogelijk numerieke sommen te maken en er is een +methode om het analytisch mee te nemen. +`GeoProb-Pipe` neemt het voorland mee en voert geen controle uit op pipegroei. + +.. TODO: je doelt hier denk ik op de stijghoogtemodellen toch? en met voert geen controe uit op pipegroei -> je bedoelt dat we geen controle uitvoeren op de lengte van de pipegroei ten opzicht van de dijkbasis max? +.. twijfel over dat laatste stukje kun je die iets verduidelijken? + +5. Terugschrijdende erosie: Fijne fractie +De weerstand tegen erosie van zand met veel fijne fractie is theoretisch onderbouwd. +Specifiek voor piping in getijdenzand zijn er in Nederland op verschillende schalen ca. 35 +experimenten uitgevoerd om de hypothese te bewijzen en kwantificeren.Uit recente proeven met getijdenzand :cite:`getijdenzand_2023` blijkt dat deze grondsoorten +een aanzienlijk hogere weerstand tegen terugschrijdende erosie vertonen dan rivierzanden. +Dit wordt veroorzaakt door de aanwezigheid van fijne fracties, slechtere sortering en gedeeltelijke +cementatie, die gezamenlijk leiden tot een hogere kritieke gradiënt. +`GeoProb-Pipe` houdt rekening met de aanwezigheid van een fijne fractie in de door het toevoegen van een modelfactor :math:`m_{ff}` naast de modelfactor terugschrijdende erosie :math:`m_{p}`. + +6. Terugschrijdende erosie: Slechte sortering (korrelgrootteverdeling) +Er zijn experimentenseries met variaties in uniformiteitscoëfficiënt (Cu). Er is echter geen eenduidig beeld van de invloed van de sortering op het kritiek verval. Dit aspect is daarom niet meegenomen in `GeoProb-Pipe`. + +7. Terugschrijdende erosie: Drukval in opbarstkanaal (hoger of lager dan 0.3d) +De theorie dat er weerstand in het opbarstkanaal aanwezig is, is met veldmetingen en +experimenteel onderbouwd. Echter is in de praktijk moeilijk te +voorspellen hoe groot de weerstand zal zijn. Gedurende het piping proces zal de weerstand +in het kanaal veranderen doordat de stroomsnelheid toeneemt en de korrels uit het +opbarstkanaal spoelen. De vorm van het opbarstkanaal is ook van grote invloed, echter is het +formaat van het opbarstkanaal eveneens moeilijk te voorspellen. +`GeoProb-Pipe` houdt rekening met de weerstand in het opbarstkanaal door de reductieconstante van het verval over de deklaag :math:`r_{c,deklaag}` als een stochast te definiëren. + +8. Terugschrijdende erosie: Heterogeniteit korrelgrootte in baan van de pijp +Het is algemeen bekend dat de ondergrond op korrelschaal heterogeen is. De pipe volgt de +weg van de minste weerstand en meandert hierdoor. In dit proces is primaire erosie van +belang, echter is dit moeilijk te voorspellen. Er zijn voor zover bekend geen experimenten +met sterk heterogene ondergronden. Wel zijn er proefvelden met metingen. Ook zijn er +numerieke berekeningen met heterogeniteit waaruit blijkt dat de sterkste korrel in het zwakste +pad ongeveer overeen komt met de gemiddelde d70. In de praktijk is het ook moeilijk om de +heterogeniteit goed in kaart te brengen of te karakteriseren, dit maakt de inschatting van het +effect moeilijk. +`GeoProb-Pipe` biedt de mogelijkheid om de :math:`d_{70}` als een stochast te definiëren. + +9. Terugschrijdende erosie: Fluctuatie van de diepte of helling van de deklaag in de baan van de pipe. +Het effect van de helling is theoretisch onderbouwd en er is een erosie model dat ook in de rekenregel toegepast zou kunnen worden. Daarnaast zijn er enkele experimenten ter validatie van deze theorie. Toch is deze kennis nog niet +algemeen toepasbaar en te generaliseren, omdat het slechts enkele experimenten betreft. +`GeoProb-Pipe` biedt geen mogelijkheden om dit aspect mee te nemen. + + +10. Terugschrijdende erosie: 3D concentratie van stroming naar de pipe +In een aantal kleine schaal laboratoriumproeven is het kritieke verval in 3D ca. 1/2 zo groot +als met de 2D regel van Sellmeijer wordt voorspeld. In deze proeven vormt één pipe en is +geen afstroming naar het achterland. +Er is weinig informatie over het effect op grotere schaal, al wordt op basis van theorie +verwacht dat de invloed van 3D stroming groter kan zijn leidend tot lager kritiek verval. Op basis van +de geohydrologie en experimenten wordt verwacht dat de invloed van het 3D effect kleiner +wordt bij doorlatendere achterlanden. +Vanwege de verwachte grote invloed van dit aspect is er in `GeoProb-Pipe` de mogelijkheid om een modelfactor 3D :math:`m_{3D}` te gebruiken. + + +11. Terugschrijdende erosie: Tijdsafhankelijkheid +In het promotie onderzoek van Joost Pol is uitgebreid onderzoek gedaan naar +tijdsafhankelijke pipegroei met kleine en grote schaal experimenten, numerieke modellen en +er is een statistisch uitgewerkte methode voorgesteld. Voor de toepassing op grotere schaal +zijn er nog onzekerheden. Het is soms lastig vast te stellen of er nog oude pipes aanwezig +zijn en 3D numerieke modellen geven op grote schaal onverwachte resultaten voor het kritiek +verval. +`GeoProb-Pipe` heeft geen implementatie van dit aspect. Wel zou via een modelfactor terugschrijdende erosie :math:`m_{p}` gebruikt kunnen worden om gevoeligheidsberekeningen te doen. + + +12. Terugschrijdende erosie: Anisotropie van de doorlatendheid +Grondwaterstromingstheorie met anisotropie is goed bekend: voor het bepalen van het effect +op stroming kunnen daarom numerieke berekeningen uitgevoerd worden. Daarnaast is er +een toevoeging op de rekenregel van Sellmeijer, waarmee een eerste inschatting gemaakt +kan worden van de invloed van anisotropie. Experimentele validatie met anisotrope ondergrond ontbreekt tot op heden +`GeoProb-Pipe` biedt de mogelijkheid om het effect van anisotropie op het kritieke verval te verrekenen door middel van een modelfactor :math:`m_{aniso}`. + +13. Terugschrijdende erosie: Meerlaagsheid watervoerend pakket (ten opzichte van +gewogen gemiddelde) +Grondwaterstroming is een bekend fenomeen, met weinig onzekerheden. Zo geldt dat ook +voor meerlaagse stroming. De stroming naar de pipe toe is numeriek (met D-GeoFlow) goed +te bepalen. Echter is het zo dat er slechts enkele fysieke experimenten zijn die de invloed +van meerlaagsheid op piping bevestigen. Het is mogelijk dat een verandering in verticale +instroming de secundaire en primaire erosie beïnvloed op een manier die niet in numerieke +analyses meegenomen wordt. +`GeoProb-Pipe` heeft hiervoor een aparte modelfactor meerlaagsheid :math:`m_{ml}` geïmplementeerd. + +14. Vervolgprocessen: Duur van het bezwijkproces +Op globale lijn zijn de vervolgprocessen bekend. Tijdens de IJkdijkproeven is het +proces geobserveerd. De duur en observaties staan beschreven. Maar deze resultaten zijn niet te generaliseren, er is geen hypothese of model voor de duur van deze vervolgprocessen bij dijken in de praktijk. Internationaal zijn er numerieke modellen waarmee de duur van het bezwijkproces bij dammen berekend kan worden, echter zijn deze niet gevalideerd voor dijken zoals we die in Nederland hebben. Daarom is dit aspect niet meegenomen in `GeoProb-Pipe`. + + + + diff --git a/docs/_static/Hierarchie_berekeningen.png b/docs/_static/Hierarchie_berekeningen.png new file mode 100644 index 00000000..1ff00471 Binary files /dev/null and b/docs/_static/Hierarchie_berekeningen.png differ diff --git a/docs/_static/Kantelpunt_TRWSD_2004.png b/docs/_static/Kantelpunt_TRWSD_2004.png deleted file mode 100644 index 3aa8c78f..00000000 Binary files a/docs/_static/Kantelpunt_TRWSD_2004.png and /dev/null differ diff --git a/docs/_static/SchematischeHoogwaterRespons_TRWSD_2004.png b/docs/_static/SchematischeHoogwaterRespons_TRWSD_2004.png deleted file mode 100644 index 66700cd8..00000000 Binary files a/docs/_static/SchematischeHoogwaterRespons_TRWSD_2004.png and /dev/null differ diff --git a/docs/_static/TheoretischeVerbandCyclischePeilbuiswaarnemingen_TRWSD_2004.png b/docs/_static/TheoretischeVerbandCyclischePeilbuiswaarnemingen_TRWSD_2004.png deleted file mode 100644 index b1e67447..00000000 Binary files a/docs/_static/TheoretischeVerbandCyclischePeilbuiswaarnemingen_TRWSD_2004.png and /dev/null differ diff --git a/docs/_static/TypenOndergrondscenario.png b/docs/_static/TypenOndergrondscenario.png new file mode 100644 index 00000000..6067698c Binary files /dev/null and b/docs/_static/TypenOndergrondscenario.png differ diff --git a/docs/_static/bottom-up.png b/docs/_static/bottom-up.png new file mode 100644 index 00000000..c5fc22c7 Binary files /dev/null and b/docs/_static/bottom-up.png differ diff --git a/docs/_static/faalpad_piping.png b/docs/_static/faalpad_piping.png new file mode 100644 index 00000000..4bae1381 Binary files /dev/null and b/docs/_static/faalpad_piping.png differ diff --git a/docs/_static/lijst_met_variabelen.csv b/docs/_static/lijst_met_variabelen.csv deleted file mode 100644 index ba2a171d..00000000 --- a/docs/_static/lijst_met_variabelen.csv +++ /dev/null @@ -1,55 +0,0 @@ -"VariableName","VariableDescription","VariableUnit","VariableType" -"L_intrede","Afstand van uittredepunt tot geometrische intredelijn","m","Input" -"L_but","Afstand van uittredepunt tot buitenteenlijn","m","Input" -"L_bit","Afstand van uittredepunt tot binnenteenlijn","m","Input" -"L_achterland","Afstand van uittredepunt tot Achterlandlengte","m","Input" -"mv_exit","Bodemhoogte ter plaatse van uittredepunt","m+NAP","Input" -"mv_achterland_vak","Representatieve bodemhoogte achterland binnen een vak","m+NAP","Input" -"polderpeil","Polderpeil ter plaatse van uittredepunt","m+NAP","Input" -"top_zand","Geschematiseerde top van het zak in het vak","m+NAP","Input" -"gamma_sat_deklaag","Gemiddeld volumegewicht van de deklaag","kN/m^3","Input" -"d_deklaag","Dikte van de cohesieve deklaag","m","Calculated" -"d_deklaag_vak","Dikte van de cohesieve deklaag van het vak","m","Calculated" -"gamma_water","Volumegewicht van water","kN/m^3","Constant" -"kD_wvp","Transmissiviteit van het watervoerende pakket","m^2/dag","Input" -"D_wvp","Dikte van het watervoerende pakket","m","Input" -"k_wvp","Doorlatendheid van het watervoerende pakket","m/d","Calculated" -"d70","70% percentiel van de korrelverdeling","m","Input" -"c_voorland","Weerstand van de deklaag in het voorland","dag","Input" -"c_achterland","Weerstand van de deklaag in het achterland","dag","Input or calculated" -"modelfactor_u","modelfactor voor uplift","[-]","Input" -"modelfactor_h","modelfactor voor heave","[-]","Input" -"modelfactor_p","modelfactor voor piping","[-]","Input" -"i_c_h","Kritieke heave gradiënt","[-]","Constant" -"r_c_deklaag","Reductieconstante van het verval over de deklaag","[-]","Constant" -"buitenwaterstand","Buitenwaterstand","m+NAP","Input" -"eta","White's weerstandscoefficient (sleepkrachtfactor, constante van White) – Sellmeijer [-]","[-]","Constant" -"r_exit","Dempingsfactor bij uittredepunt","[-]","Calculated" -"phi_exit","Theoretische stijghoogte bij uittredepunt","m+NAP","Calculated" -"h_exit","Benedestroomse randvoorwaarde verval","m+NAP","Calculated" -"L_kwelweg","Kwelweglengte","m","Calculated" -"theta","Rolweerstandshoek – Sellmeijer","[graden]","Constant" -"d70_m","Referentiewaarde voor de 70% percentiel van de korrelverdeling – Sellmeijer","m","Constant" -"g","Zwaartekrachtversnelling – 9,81 m/s²","m/s^2","Constant" -"v","Kinematische viscositeit – Sellmeijer","m²/s","Constant" -"gamma_korrel","Volumieke dichtheid zand onder water – Sellmeijer","kN/m^3","Constant" -"dphi_c_u","grenspotentiaal ten opzicht van maaiveld","m","Calculated" -"dh_red","Gereduceerd verval","m","Calculated" -"i_exit","Optredende heave gradient","[-]","Calculated" -"dh_c","Kritiek verval Sellmeijer","m","Calculated" -"Z_u","Grenstoestand Uplift","[-]","Calculated" -"Z_h","Grenstoestand Heave","[-]","Calculated" -"Z_p","Grenstoestand Piping","[-]","Calculated" -"Z_combi","Gecombineerde grenstoestand","[-]","Calculated" -"L_voorland","Geometrische voorlandlengte","m","Calculated" -"L_dijk","Dijkzate","m","Calculated" -"lambda_voorland","Spreidingslengte van het voorland","m","Calculated" -"lambda_achterland","Spreidingslengte van het achterland","m","Calculated" -"W_voorland","Geohydrologische weerstand van het voorland","m","Calculated" -"W_achterland","Geohydrologische weerstand van het achterland","m","Calculated" -"FoS_u","Veiligheidsfactor Uplift","[-]","Calculated" -"FoS_h","Veiligheidsfactor Heave","[-]","Calculated" -"FoS_p","Veiligheidsfactor Piping","[-]","Calculated" -"k_v_boven_gws","Verticale doorlatendheid deklaag boven grondwaterstand","m/d","Constant" -"k_v_onder_gws","Verticale doorlatendheid deklaag onder grondwaterstand","m/d","Constant" -"gws_m_mv","Grondwaterstand meters min maaiveld (scheiding verticale doorlatendheid)","m","Constant" diff --git a/docs/_static/model4d_tijdsafhankelijk_met_voorland_trwd.png b/docs/_static/model4d_tijdsafhankelijk_met_voorland_trwd.png deleted file mode 100644 index 3fb732f1..00000000 Binary files a/docs/_static/model4d_tijdsafhankelijk_met_voorland_trwd.png and /dev/null differ diff --git a/docs/_static/model4d_tijdsafhankelijk_zondervoorland_trwd.png b/docs/_static/model4d_tijdsafhankelijk_zondervoorland_trwd.png deleted file mode 100644 index f6b436a0..00000000 Binary files a/docs/_static/model4d_tijdsafhankelijk_zondervoorland_trwd.png and /dev/null differ diff --git a/docs/_tmp_figures/Procesbeschrijving.md b/docs/_tmp_figures/Procesbeschrijving.md deleted file mode 100644 index 746f01a1..00000000 --- a/docs/_tmp_figures/Procesbeschrijving.md +++ /dev/null @@ -1,58 +0,0 @@ -# Procesbeschrijving - -Deze procesbeschrijving gaat uit van de uittredepuntenmethode in combinatie met het analytische stijghoogtemodel model 4a. - -## Pre Processing -### Vastleggen algemene uitgangspunten van de berekening - - -### Vastleggen uittredepunten - -De volgende informatie dient te worden vastgelegd per uittredepunt: - -* `UittredepuntID`: elk punt heeft een eigen identifer -* `Locatie (x, y)`: locatie in RD coördinaten (bijv. geopandas-object) -* `Mvalue`: waarde die de locatie van het uittredepunt weergeeft ten opzichte van de referentielijn. zie voorbeelden over linear referencing. -* `Uittredelocatie`: optioneel, beschrijving van de locatie van het uittredepunt. Handig voor analyse van de berekeningen. -* (Ruimtelijke) koppeling met het vak van de ondergrondschenario: `VakID` en `Vaknaam`. -* `DIST_L_GEOM`: kortste afstand tot de geschematiseerde `geometrische intredelijn`. -* `DIST_BUT`: korste afstand tot de geschematiseerde `buitenteen lijn`. -* `DIST_BIT`: korste afstand tot de geschematiseerde `binnenteen lijn`. -* `HydraLocatie`: ruimtelijke koppeling met de dichtsbijzijnde uitvoerlocatie. -* `Bodemhoogte`: bodemhoogte (maaiveldniveau) ter plaatse van het uittredepunt. -* `Polderpeil`: benedenstroomse waterpeil ter plaatse van het uittredepunt. - -De werkwijze is als volgt: - -1. definieer uittredepunten in GIS omgeving: dit levert `UittredepuntID`, `Locatie (x, y)` -2. Bepaal `Mvalue` via linear referencing aan de `referentielijn`. -3. Koppel `uittredepunten` aan `vakindeling`: dit levert `VakID` en `Vaknaam`. -4. Bepaal `DIST_L_GEOM`, `DIST_BUT`, `DIST_BIT` door spatial join met `Geometrische Intredelijn`, `Buitenteen` en `Binnenteen`. -5. Bepaal `Bodemhoogte` door samplen raster met DTM/AHN -6. Bepaal `Polderpeil` door intersectie met een polygon `Polderpeilen`. -7. Koppel `HydraLocatie` aan `Overschrijdingsfrequenties`. - -#### Discussie - -1. De geometrische lengte van het achterland `L3_geom` is nu vastgelegd per vak. Dit is een parameter die niet heel precies vastgelegd hoeft te worden en vaak vooraf onbekend is. In lijn met `DIST_BUT` kan `L3_geom` ook worden vastgelegd als een geometrie en als veld aan het object `uittredepunten` worden toegevoegd. - -2. Optioneel kan het model worden uitgebreid met de verwachte top van het zand ter plaatse van het uittredepunt. - -### Bronbestanden voor de uittredepunten tabel - -De locaties van mogelijke uittredepunten - -Uitvoer van een Hydra-NL berekening -TODO: format vastleggen - -### Vastleggen Ondergrondschematisatie - -### Genereren scenarioberekeningen - -## Uitvoeren scenarioberekeningen - -### Semi-probabilistische berekeningen - -### Probabilistische berekeningen - -## Verwerken scenarioberekeningen \ No newline at end of file diff --git a/docs/_tmp_figures/README.md b/docs/_tmp_figures/README.md deleted file mode 100644 index daf2efd9..00000000 --- a/docs/_tmp_figures/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# open-stph - -Het project open-stph werkt aan een piping rekenkernel in python en heeft tot doel om zowel semi-probabilistische als probabilistische scenarioberekeningen uit te voeren. Daarnaast ondersteunt het alle stappen om een beoordeling voor piping uit te voeren. - -## Uittredepunten vs. dwarsdoorsneden - -Piping is een ruimtelijk probleem. Door alle mogelijke uittredepunten te evalueren ontstaat een beeld waar de 'zwakke' plek in de waterkering is. Elk uittredepunt is in feite een dwarsdoorsnede. Door heel veel uittredepunten in een vak te evalueren, zijn er minder onzekerheden en worden fysiek onmogelijke combinaties van variabelen uitgesloten. - -## Procesbeschrijving - -Het uitvoeren van berekening als deze is op te delen in een aantal stappen: - -1. Pre-processing van de schematisatie -2. Uitvoeren van de berekeningen -3. Post-processing van de resultaten - -Deze stappen zijn beschreven in [procesbeschrijving](docs/Procesbeschrijving.md). - -## Beschrijving rekenkernel - -De standaard rekenkernel van het WBI heeft geen koppeling tussen de respons van de stijghoogte in het watervoerende pakket en de Sellmeijer berekening. Daarom is er sprake van meerdere rekenkernels. Dit project richt zich in eerste instantie op integratie met het analytische grondwatermodel 4a van het Technisch Rapport Waterspanningen bij dijken. - -De [beschrijving van de rekenkernel](docs/Beschrijving_rekenkernel.md) staat hier. \ No newline at end of file diff --git a/docs/_tmp_figures/generate_figures_k_en_kd.py b/docs/_tmp_figures/generate_figures_k_en_kd.py deleted file mode 100644 index 3c627cad..00000000 --- a/docs/_tmp_figures/generate_figures_k_en_kd.py +++ /dev/null @@ -1,78 +0,0 @@ -# import numpy as np -import matplotlib.pyplot as plt -from probabilistic_library import DistributionType, Stochast - - -def plot_dist(val_grid, stochast, title): - pdf = [stochast.get_pdf(val) for val in val_grid] - cdf = [stochast.get_cdf(val) for val in val_grid] - - fig, ax1 = plt.subplots() - color = "tab:blue" - ax1.set_xlabel("value (-)") - ax1.set_ylabel("pdf (-)", color=color) - ax1.plot(val_grid, pdf) - ax1.tick_params(axis="y", labelcolor=color) - ax2 = ax1.twinx() - color = "tab:red" - ax2.set_ylabel("cdf (-)", color=color) - ax2.plot(val_grid, cdf, "r--", label="pdf") - ax2.tick_params(axis="y", labelcolor=color) - fig.suptitle(title) - - -def plot_k(): - pass - - -def plot_kd(): - pass - - -def model_kD_from_k_and_D(k: float, D: float) -> float: - """ - Model the kD from k and D - :param k: rate constant - :param D: diffusion coefficient - :return: kD - """ - return k * D - - -def model_k_from_kD_and_D(kD: float, D: float) -> float: - """ - Model the k from kD and D - :param kD: rate constant - :param D: diffusion coefficient - :return: k - """ - return kD / D - - -# define stochastic variables -# kD -kD = Stochast() -kD.distribution = DistributionType.log_normal -kD.location = 3000.0 -kD.scale = 0.4 * kD.location - -# k -k = Stochast() -k.distribution = DistributionType.log_normal -k.location = 55.0 -k.scale = 0.5 * k.location - -# D -D = Stochast() -D.distribution = DistributionType.log_normal -D.location = kD.location / k.location -D.scale = 1.5 - - -def main(): - pass - - -if __name__ == "__main__": - main() - main() diff --git a/docs/background/grenstoestandfuncties.rst b/docs/background/grenstoestandfuncties.rst deleted file mode 100644 index a222b16d..00000000 --- a/docs/background/grenstoestandfuncties.rst +++ /dev/null @@ -1,206 +0,0 @@ -##################### -Grenstoestandfuncties -##################### - -In :cite:`sh_piping_2021` en :cite:`calibration_piping_2016` zijn de grenstoestandfuncties gedefinieerd zoals het basisinstrumentariumd die hanteert. Falen treedt op als de grenstoestandfuncties van opbarsten, heave en piping bereikt zijn. -Deze paragraaf is overgenomen uit bijlage C van :cite:`sh_piping_2021` en waarbij de variabelen hernoemd zijn naar de notatie die in deze package gehanteerd wordt, zie :ref:`Lijst van variabelen`. - -TODO: plaatje van de foutenboom toevoegen - - -Grenstoestandfunctie opbarsten -============================== - -De grenstoestandsfunctie voor opbarsten (uplift) :math:`Z_{u}` is gebaseerd op een vergelijking van de naar beneden gerichte druk die door het gewicht van de deklaag wordt uitgeoefend (weerstand) en de naar boven gerichte waterdruk in de watervoerende zandlaag (belasting), hier uitgedrukt in vorm van een stijghoogteverschil. De grenstoestandfunctie voor opbarsten :cite:`calibration_piping_2016` is gedefinieerd als: - -.. math:: - - Z_{u} = m_{u} \cdot \Delta \phi_{c,u} - (\phi_{exit} - h_{exit}) - - \Delta \phi_{c,u} = \frac{d_{deklaag} \cdot (\gamma_{sat,deklaag} - \gamma_{w})}{\gamma_{w}} - - -waarbij: - -- :math:`Z_{u}` = grenstoestandfunctie voor opbarsten [-] -- :math:`m_{u}` = modelfactor voor opbarsten [-] -- :math:`\Delta \phi_{c,u}` = grenspotentiaal ten opzichte van maaiveld in m -- :math:`\phi_{exit}` = theoretische stijghoogte bij uittredepunt in m+NAP -- :math:`h_{exit}` = niveau van de uittredepunt in m+NAP -- :math:`d_{deklaag}` = dikte van de deklaag in m -- :math:`\gamma_{sat,deklaag}` = gemiddeld volumegewicht van de deklaag in kN/m³ -- :math:`\gamma_{w}` = volumegewicht van water in kN/m³ - -De stijghoogte bij het uittredepunt :math:`\phi_{exit}` is binnen het WBI instrumentarium :cite:`sh_piping_2021` gedefinieerd als: - -.. math:: - - \phi_{exit} = h_{ref} + r_{exit} \cdot (h - h_{ref}) - -waarbij: - -- :math:`h_{ref}` = polderpeil ter plaatse van uittredepunt in m+NAP -- :math:`r_{exit}` = respons bij uittredepunt [-] -- :math:`h` = Buitenwaterstand in m+NAP - - -De respons bij het uittredepunt :math:`r_{exit}` is in :cite:`sh_piping_2021` bewust niet verder gedefinieerd. In principe kan dat via grondwaterstromingsanalyses (analytisch of numeriek, stationair of tijdsafhankelijk) of expert judgement gebeuren, bij voorkeur via monitoring. - -Indien het model 4a geintegreerd wordt in de grenstoestandfuncties, is de respons bij het uittredepunt afhankelijk van de geometrie, de weerstand van het voorland :math:`c_{voorland}`, de transmissiviteit van het watervoerend pakket :math:`kD` en de weerstand van het achterland :math:`c_{achterland}`. - -Het polderpeil :math:`h_{ref}` is de benedenstroomse randvoorwaarde. Het wordt ook het referentieniveau genoemd, -vandaar :math:`h_{ref}`. Deze randvoorwaarde is ook belangrijk bij het afleiden van de respons :math:`r_{exit}` op basis van peilbuismetingen. - -Bij stijgende buitenwaterstanden zal het polderpeil door kwel kunnen stijgen. Bij de schematisatie van de pipingberekeningen dient hierbij rekening gehouden te worden, bijvoorbeeld door een hogere waarde voor :math:`h_{ref}` te kiezen. In dit geval wordt de stijghoogte bij het uittredepunt :math:`\phi_{exit}` overschat. Dit is niet erg, omdat de faalkans wordt bepaald door het mechanisme piping. - -De respons :math:`r_{exit}` op elke willekeurige locatie in het dwarsprofiel kan worden beschreven door een analytische oplossing in het geval van een stationaire situatie. De respons :math:`r_{exit}` is dan een functie van de geometrie van het profiel (:math:`L_{voorland}`, :math:`L_{dijk}` en :math:`L_{achterland}`), de transmissiviteit :math:`kD` van het watervoerende pakket en de weerstand van het voor- en achterland (:math:`c_{voorland}` en :math:`c_{achterland}`). Zie hiervoor :ref:`stationair-model` en :cite:`sh_piping_2021` :cite:`trw_2004`. - -Grenstoestandfunctie heave -========================== - -Zandtransport kan alleen optreden als de verticale uitstroomgradiënt bij het uittredepunt een -kritieke waarde voor heave overschrijdt. -De grenstoestandfunctie voor heave :cite:`calibration_piping_2016` is gedefinieerd als: - -.. math:: - - Z_{h} = m_{h} \cdot i_{c,h} - i_{exit} = m_{h} \cdot i_{c,h} - \frac{(\phi_{exit} - h_{exit})}{d_{deklaag}} - -waarbij: - -- :math:`Z_{h}` = grenstoestandfunctie voor heave [-] -- :math:`m_{h}` = modelfactor voor heave [-] -- :math:`i_{c,h}` = Kritieke heave gradiënt [-] -- :math:`i_{exit}` = Optredende heave gradient [-] - -In afwijking van de definitie in het WBI is ook hier consequent een modelfactor :math:`m_{u}` toegepast omdat er ook onzekerheden zijn die niet door dit model beschreven worden. - -De stijghoogte in het uittredepunt :math:`\phi_{exit}` wordt beschreven door gebruik te maken van het stationaire grondwaterstromingsmodel. Dus geldt hetzelfde als bij het mechanisme opbarsten: - -.. math:: - - \phi_{exit} = f(L_{voorland}, L_{dijk}, L_{achterland},kD,c_{voorland},c_{achterland}) - -Zie hiervoor :ref:`stationair-model` en :cite:`sh_piping_2021`. - -Grenstoestandfunctie piping -=========================== - -De grenstoestandfunctie voor piping :cite:`calibration_piping_2016` en :cite:`sh_piping_2021` is gedefinieerd als: - -.. math:: - - Z_{p} = m_{p} \cdot \Delta H_{c} - (h -h_{exit} - r_{c,deklaag} \cdot d_{deklaag}) - -waarbij: - -- :math:`Z_{p}` = grenstoestandfunctie voor piping [-] -- :math:`m_{p}` = modelfactor voor piping [-] -- :math:`\Delta H_{c}` = kritiek verval voor piping in m -- :math:`h` = waterstand in de rivier in m+NAP -- :math:`h_{exit}` = benedenstroomse randvoorwaarde verval in m+NAP -- :math:`r_{c,deklaag}` = reductiefactor voor de deklaag -- :math:`d_{deklaag}` = dikte van de deklaag in m - -De kritiek verval :math:`\Delta H_{c}` is een functie van verschillende factoren en de kwelweglengte :math:`L_{kwelweg}` gedefinieerd als: - -.. math:: - - \Delta H_{c} = F_{resistance} \cdot F_{scale} \cdot F_{geometry} \cdot L_{kwelweg} - -In afwijking van de definitie in het WBI is de kwelweglengte geen aparte stochast. De kwelweglengte is gedefinieerd als: - -.. math:: - - L_{kwelweg} = L_{buitenteen} + \lambda_{voorland} \cdot tanh(\frac{L_{voorland}}{\lambda_{voorland}}) - - \lambda_{voorland} = \sqrt{kD \cdot c_{voorland}} - -waarbij: - -- :math:`L_{kwelweg}` = kwelweglengte in m -- :math:`L_{buitenteen}` = lengte van het uittredepunt tot de buitenteen in m -- :math:`\lambda_{voorland}` = de spreidingslengte van het voorland in m -- :math:`L_{voorland}` = fysiekee lengte van het voorland in m -- :math:`kD` = transmissiviteit van het watervoerend pakket in m²/d -- :math:`c_{voorland}` = weerstand van het voorland in dagen - -De tweede (sterkte) term van de grenstoestandfunctie van piping is het gereduceerd verval: - -.. math:: - - \Delta h_{red} = h - h_{exit} - r_{c,deklaag} \cdot d_{deklaag} - -waarbij de benedenstroomse randvoorwaarde :math:`h_{exit}` is gedefinieerd als: - -.. math:: - - h_{exit} = max(h_{ref}, mv_{exit}) - - - -Lijst van variabelen -==================== - -.. csv-table:: Lijst van variabelen - :header: "Naam van variabele","Beschrijving","Eenheid","Type" - :class: longtable - :widths: 15, 50, 15, 20 - - ":math:`L_{intrede}`","Afstand van uittredepunt tot geometrische intredelijn","m","Input" - ":math:`L_{but}`","Afstand van uittredepunt tot buitenteenlijn","m","Input" - ":math:`L_{bit}`","Afstand van uittredepunt tot binnenteenlijn","m","Input" - ":math:`L_{achterland}`","Afstand van uittredepunt tot Achterlandlengte","m","Input" - ":math:`mv_{exit}`","Bodemhoogte ter plaatse van uittredepunt","m+NAP","Input" - ":math:`mv_{achterland,vak}`","Representatieve bodemhoogte achterland binnen een vak","m+NAP","Input" - ":math:`h_{ref}`","Polderpeil ter plaatse van uittredepunt","m+NAP","Input" - ":math:`top_{zand}`","Geschematiseerde top van het zak in het vak","m+NAP","Input" - ":math:`\gamma_{sat,deklaag}`","Gemiddeld volumegewicht van de deklaag","kN/m^3","Input" - ":math:`d_{deklaag}`","Dikte van de cohesieve deklaag","m","Calculated" - ":math:`d_{deklaag,vak}`","Dikte van de cohesieve deklaag van het vak","m","Calculated" - ":math:`\gamma_{water}`","Volumegewicht van water","kN/m^3","Constant" - ":math:`kD_{wvp}`","Transmissiviteit van het watervoerende pakket","m^2/dag","Input" - ":math:`D_{wvp}`","Dikte van het watervoerende pakket","m","Input" - ":math:`k_{wvp}`","Doorlatendheid van het watervoerende pakket","m/d","Calculated" - ":math:`d_{70}`","70% percentiel van de korrelverdeling","m","Input" - ":math:`c_{voorland}`","Weerstand van de deklaag in het voorland","dag","Input" - ":math:`c_{achterland}`","Weerstand van de deklaag in het achterland","dag","Input or calculated" - ":math:`m_{u}`","modelfactor voor uplift","[-]","Input" - ":math:`m_{h}`","modelfactor voor heave","[-]","Input" - ":math:`m_{p}`","modelfactor voor piping","[-]","Input" - ":math:`i_{c,h}`","Kritieke heave gradiënt","[-]","Constant" - ":math:`r_{c,deklaag}`","Reductieconstante van het verval over de deklaag","[-]","Constant" - ":math:`h`","Buitenwaterstand","m+NAP","Input" - ":math:`\eta`","White's weerstandscoefficient (sleepkrachtfactor, constante van White) – Sellmeijer [-]","[-]","Constant" - ":math:`r_{exit}`","Respons (Dempingsfactor) bij uittredepunt","[-]","Calculated" - ":math:`\phi_{exit}`","Theoretische stijghoogte bij uittredepunt","m+NAP","Calculated" - ":math:`h_{exit}`","Benedestroomse randvoorwaarde verval","m+NAP","Calculated" - ":math:`L_{kwelweg}`","Kwelweglengte","m","Calculated" - ":math:`\theta`","Rolweerstandshoek – Sellmeijer","[graden]","Constant" - ":math:`d_{70,m}`","Referentiewaarde voor de 70% percentiel van de korrelverdeling – Sellmeijer","m","Constant" - ":math:`g`","Zwaartekrachtversnelling – 9,81 m/s²","m/s^2","Constant" - ":math:`v_{water}`","Kinematische viscositeit water – Sellmeijer","m²/s","Constant" - ":math:`\gamma_{k}`","Volumieke dichtheid zand onder water – Sellmeijer","kN/m^3","Constant" - ":math:`\Delta \phi_{c,u}`","grenspotentiaal ten opzicht van maaiveld","m","Calculated" - ":math:`\Delta h_{red}`","Gereduceerd verval","m","Calculated" - ":math:`i_{exit}`","Optredende heave gradient","[-]","Calculated" - ":math:`\Delta h_{c}`","Kritiek verval Sellmeijer","m","Calculated" - ":math:`Z_u`","Grenstoestand Uplift","[-]","Calculated" - ":math:`Z_h`","Grenstoestand Heave","[-]","Calculated" - ":math:`Z_p`","Grenstoestand Piping","[-]","Calculated" - ":math:`Z_{combi}`","Gecombineerde grenstoestand","[-]","Calculated" - ":math:`L_{voorland}`","Geometrische voorlandlengte","m","Calculated" - ":math:`L_{dijk}`","Dijkzate","m","Calculated" - ":math:`\lambda_{voorland}`","Spreidingslengte van het voorland","m","Calculated" - ":math:`\lambda_{achterland}`","Spreidingslengte van het achterland","m","Calculated" - ":math:`W_{voorland}`","Geohydrologische weerstand van het voorland","m","Calculated" - ":math:`W_{achterland}`","Geohydrologische weerstand van het achterland","m","Calculated" - ":math:`FoS_{u}`","Veiligheidsfactor Uplift","[-]","Calculated" - ":math:`FoS_{h}`","Veiligheidsfactor Heave","[-]","Calculated" - ":math:`FoS_{p}`","Veiligheidsfactor Piping","[-]","Calculated" - ":math:`k_{v,boven gws}`","Verticale doorlatendheid deklaag boven grondwaterstand","m/d","Constant" - ":math:`k_{v,onder gws}`","Verticale doorlatendheid deklaag onder grondwaterstand","m/d","Constant" - ":math:`gws_{m,mv}`","Grondwaterstand meters min maaiveld (scheiding verticale doorlatendheid)","m","Constant" - - -.. bibliography diff --git a/docs/background/piping.rst b/docs/background/piping.rst deleted file mode 100644 index f0686beb..00000000 --- a/docs/background/piping.rst +++ /dev/null @@ -1,44 +0,0 @@ -########## -Sellmeijer -########## - -De formulering van Sellmeijer zoals die gedefinieerd is in het WBI2017 is: - -.. math:: - - \Delta H = L F_{resistance} F_{scale} F_{geometry} - -waarbij: - -.. math:: - - F_{resistance} = \eta \cdot (\frac{(26.0 - \gamma_{w})}{\gamma_{w}}) \tan(\theta) - - F_{scale} = \frac{d_{70.m}}{\sqrt[3]{\kappa L}} \frac{d_{70}}{d_{70.m}}^{0.4} - - F_{geometry} = 0.91 \frac{D}{L}^{\frac{0.28}{(\frac{D}{L})^{2.8} - 1} + 0.04} - - \kappa = \frac{\upsilon}{g} \cdot k = 1.35 \cdot 10^{-6} \cdot k - -waarbij: - -- :math:`\Delta H` = kritiek verval in m -- :math:`L` = Kwelwelengte in m -- :math:`\eta` = Coëfficiënt van White (sleepkrachtfactor) = 0.25 -- :math:`\gamma_{w}` = soortelijk gewicht van het water in kN/m³ -- :math:`\theta` = Rolweerstandshoek van zandkorrels in graden -- :math:`d_{70.m}` = referentiewaarde van de korrelgrootte in m -- :math:`\kappa` = intrinsieke doorlatendheid in m\ :sup:`2` -- :math:`\upsilon` = kinematische viscositeit van grondwater van 10\ :sup:`o` Celsius in m²/s -- :math:`g` = valversnelling van de zwaartekracht in m/s² -- :math:`k` = doorlatendheid in m/s -- :math:`d_{70}` = 70-percentiel waarde van de korrelverdeling van de piping gevoelige laag in m -- :math:`D` = dikte van de zandlaag in m - -In de schematiseringshandleiding van het WBI2017 :cite:t:`sh_piping_2021` staat een formulering van de rekenregel van Sellmeijer die afwijkt van de implementatie in de WBI-software. De afwijking zit in de definitie van de weerstandsfactor :math:`F_{resistance}`. In de schematiseringshandleiding is de weerstandsfactor gedefinieerd als: - -.. math:: - - F_{resistance} = \eta \cdot (\frac{16.5}{\gamma_{w}}) \tan(\theta) - - diff --git a/docs/background/stationair_model.rst b/docs/background/stationair_model.rst deleted file mode 100644 index 2391a440..00000000 --- a/docs/background/stationair_model.rst +++ /dev/null @@ -1,97 +0,0 @@ -.. _stationair-model: - -################ -Stationair model -################ - -Op deze pagina volgt een uitleg van de implementatie van het stationaire model. Achtergronden staan in bijlage 4 van het Technisch rapport Waterspanningen bij Dijken :cite:t:`trw_2004`. - -Onder de aanname van horizontale stroming in het watervoerende zandpakket en verticale stroming in de weerstandbiedende deklaag is een analytische oplossing beschikbaar voor het debiet en het stijghoogteverloop in het zand. - -.. figure:: /_static/model4a_trwd.png - :width: 100% - - Schematisering grondwaterstroming stationair model (figuur b4.4 uit :cite:t:`trw_2004`) - - -Het stationaire model houdt in dat de respons op een gegeven locatie :math:`x` constant is. Op elke locatie is het verband tussen de stijghoogte in het watervoerende pakket :math:`\phi(x)` en de respons :math:`r(x)` bekend door: - -.. math:: - - \phi(x) = h_{ref} + r(x) (h_{rivier} - h_{ref}) - -en andersom: - -.. math:: - - r(x) = \frac{(\phi(x) - h_{ref})}{(h_{rivier} - h_{ref})} - -Aan het zandpakket met afdekkende kleilaag worden de volgende weerstanden gedefinieerd. -Voor het voorland: - -.. math:: - - W_{1} = \lambda_{1} tanh(\frac{L_{1}}{\lambda_{1}}) - -en voor het achterland: - -.. math:: - - W_{3} = \lambda_{3} tanh(\frac{L_{3}}{\lambda_{3}}) - -De totale weerstand is de som van bovenstaande weerstanden: :math:`\sum W = W_1 + L_2 + W_3`. - -In het geval van een radiale (intrede)weerstand is er een extra weerstandsfactor gedefinieerd: - -.. math:: - - W_{radiaal} = 0.44 D - -De radiale weerstand kan aan de totale weerstand :math:`\sum W` worden toegevoegd. - -De respons ter plaatse van de buitenteen :math:`r_{but}` en de binnenteen :math:`r_{bit}` van de dijk is gedefinieerd als: - -.. math:: - - r_{but} = \frac{(W_2 + L_2)}{\sum W} - -en - -.. math:: - - r_{bit} = \frac{(W_3)}{\sum W} - -Het model neemt aan dat tussen de buitenteen en de binnenteen van de dijk er geen uitwisseling plaatsvindt tussen het zandpakket en de deklaag. Over deze lengte :math:`L_2` wordt lineair geïnterpoleerd. Een bijzonder geval is wanneer :math:`L_2 = 0`. We spreken dan van een kantelpunt. De definitie van de respons in het kantelpunt (zie bladzijde b3-7 van :cite:`trw_2004` is: - -.. math:: - - r_{kp} = \frac{1}{(1 + \frac{W_1}{W_3})} - -Voor de faalmechanismen piping en macrostabiliteit is het potentiaalverloop verloop in de nabijheid van de dijk van belang. Door de aanname van lineaire interpolatie wordt het potentiaalverloop beschreven door drie formules: één voor het voorland tot de buitenteen, het gebied onder de dijk en een formulering voor het achterland. Hiervoor is het nodig de :math:`x` positie in het dwarsprofiel te kennen. Deze module hanteert hiervoor de volgende definities: - -De :math:`x` loopt op richting het achterland. De dijkzate is dan gedefinieerd als: :math:`L_2 = x_{bit} - x_{but}`. - -Als :math:`x < x_{but}` dan ligt :math:`x` in het voorland en als :math:`x > x_{but}` dan ligt :math:`x` in het achterland. - -Voorland: - -.. math:: - - r(x) = 1.0 - (1.0 - r_{but}) \frac{sinh(\frac{L_{1} + x - x_{but}}{\lambda_{1}})}{sinh (\frac{L_{1}}{\lambda_{1}})} - - -Onder de dijk: - -.. math:: - - r(x) = r_{bit} + (r_{but} - r_{bit}) \frac{x_{bit} - x}{L_{2}} - -Achterland: - -.. math:: - - r(x) = r_{bit} \frac{sinh(\frac{L_{3} - x + x_{bit}}{\lambda_{3}})}{sinh (\frac{L_{3}}{\lambda_{3}})} - - - -.. bibliography \ No newline at end of file diff --git a/docs/background/uittredepuntenmethode.rst b/docs/background/uittredepuntenmethode.rst deleted file mode 100644 index 3801461c..00000000 --- a/docs/background/uittredepuntenmethode.rst +++ /dev/null @@ -1,5 +0,0 @@ -##################### -Uittredepuntenmethode -##################### - -Hier volgt een beschrijving van de uittredepuntenmethode. \ No newline at end of file diff --git a/docs/bibliography.bib b/docs/bibliography.bib index 33b4f153..b1a1be17 100644 --- a/docs/bibliography.bib +++ b/docs/bibliography.bib @@ -31,7 +31,7 @@ @article{bauduin_barends_1988 } @techreport{sh_piping_2021, - author = {Rijkswaterstaat, Water Verkeer en Leefomgeving}, + author = {Rijkswaterstaat}, title = {Schematiseringshandleiding piping - WBI2017}, version = {4.0}, date = {28 mei 2021}, @@ -58,5 +58,22 @@ @techreport{KvK_2021 year = {2022}, reference = {11206817-010-GEO-0003} } - -@Comment{jabref-meta: databaseType:bibtex;} \ No newline at end of file +@techreport{getijdenzand_2023, + author = {Deltares and Fugro}, + title = {Piping in getijdenzand – Eindrapport Hedwige-Prosperpolder}, + version = {3.0}, + date = {2023}, + institution = {Deltares, Fugro}, + year = {2023}, + reference = {1220-164143.R08} +} +@techreport{AdviesteamDijkontwerp2024Assembleren, + author = {{Adviesteam Dijkontwerp}}, + title = {Rode draad \#10 -- Assembleren}, + institution = {Adviesteam Dijkontwerp}, + year = {2024}, + month = oct, + type = {Technisch rapport}, + address = {Nederland}, + abstract = {Dit rapport beschrijft de theoretische achtergrond en praktische toepassing van het bottom-up assembleren van faalkansen bij primaire waterkeringen, inclusief lengte-effecten en combinatieregels (SOM/MAX).}, +}@Comment{jabref-meta: databaseType:bibtex;} \ No newline at end of file diff --git a/docs/conf.py b/docs/conf.py index 53c89194..3107b4f0 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -5,40 +5,172 @@ # -- Project information ----------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information -# -import os + import sys +import os +import datetime +sys.path.insert(0, os.path.abspath("..")) +import os +import inflection +from bs4 import BeautifulSoup +from typing import Optional + + +class BColors: + HEADER = "\033[95m" + OKBLUE = "\033[94m" + OKCYAN = "\033[96m" + OKGREEN = "\033[92m" + WARNING = "\033[93m" + FAIL = "\033[91m" + ENDC = "\033[0m" + BOLD = "\033[1m" + UNDERLINE = "\033[4m" + + +def should_be_reformatted(value: Optional[str]) -> bool: + if value is None: + return False + if "geoprob_pipe" not in value: + return False + if value.split(sep=".").__len__() <= 1: + return False + return True + + +def reformat(value: str): + return inflection.humanize(value.split(sep=".")[-1]) + + +def simplify_anchor_text_in_file(filepath): + with open(filepath, "r", encoding="utf-8") as file: + soup = BeautifulSoup(file, "html.parser") + + changed = False + + # Hyperlinks + for a in soup.find_all("a"): + if not should_be_reformatted(a.string): + continue + a.string = reformat(a.string) + changed = True + + # For navigation items + for nav in soup.find_all("div", {"role": "navigation"}): + for li in nav.find_all("li", class_="breadcrumb-item active"): + if not should_be_reformatted(li.string): + continue + li.string = reformat(li.string) + changed = True + + # For h1 + for h1 in soup.find_all("h1"): + + # Check if h1 to format + if "geoprob_pipe." not in h1.contents[0]: + continue + + # Reformat + new_elements = [] + for element in h1.contents: + if "geoprob_pipe." in element: + new_elements.append(reformat(element.text)) + continue + new_elements.append(element) + + # Update + h1.clear() + for item in new_elements: + h1.append(item) + changed = True + + if changed: + with open(filepath, "w", encoding="utf-8") as file: + file.write(str(soup)) + + +def run_post_processing(): + conf_dir = os.path.dirname(os.path.abspath(__file__)) + html_dir = os.path.join(conf_dir, "_build", "html") + for root, _, files in os.walk(html_dir): + for filename in files: + if filename.endswith(".html"): + file_path = os.path.join(root, filename) + simplify_anchor_text_in_file(file_path) -sys.path.insert(0, os.path.abspath("../app/helper_functions")) project = "GeoProb-Pipe" -copyright = "2025, Martijn Kriebel, Sander Kapinga, Ard-jan Methorst, Oscar Ophof" -author = "Martijn Kriebel, Sander Kapinga, Ard-jan Methorst, Oscar Ophof" +copyright = f"{datetime.date.today().year}, WSRL & WSHD" +author = "WSRL & WSHD" release = "0.0.1" # -- General configuration --------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration extensions = [ - "sphinxcontrib.bibtex", - "sphinx.ext.autodoc", "sphinx.ext.autosummary", - "sphinx.ext.todo", - "sphinx.ext.coverage", + "autoapi.extension", + "sphinx.ext.autodoc", + "sphinx_autodoc_typehints", + "sphinx_mdinclude", + "sphinxcontrib.jquery", "sphinx.ext.napoleon", - "sphinx.ext.autosectionlabel", + "sphinxcontrib.bibtex", ] +bibtex_bibfiles = ["bibliography.bib"] + +source_suffix = [".rst", ".md"] + templates_path = ["_templates"] +autosummary_generate = True +add_module_names = False +autoapi_type = "python" +autodoc_typehints = "description" +autoapi_dirs = ["../geoprob_pipe"] +autoapi_template_dir = "autoapi/templates" +autoapi_output_dir = "autoapi" +autoapi_keep_files = True +autoapi_python_class_content = "both" exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] - -language = "nl" +numfig = True +numfig_format = {"figure": "Figuur %s"} # -- Options for HTML output ------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output -html_theme = "alabaster" +html_theme = "sphinx_rtd_theme" html_static_path = ["_static"] +html_theme_options = { + "collapse_navigation": False, + "sticky_navigation": True, + "navigation_depth": 5, + "titles_only": True, + "display_version": True, +} -# Bibliography -bibtex_bibfiles = ["bibliography.bib"] + +# -- Hooks --------------------------------------------------------------------- + + +# def shorten_titles(app, pagename, templatename, context, doctree): +# pass +# +# def setup(app): +# app.connect("html-page-context", shorten_titles) +# pass +def setup(app): + + # noinspection PyUnusedLocal + def on_build_finished(app_obj, exception): + if exception is not None: + print( + BColors.WARNING, + "Documentation build was not successful. The following exception was given. \n", + exception, + BColors.ENDC, + ) + return + run_post_processing() + + app.connect("build-finished", on_build_finished) diff --git a/docs/dev/calibration_WBI_2017.rst b/docs/dev/calibration_WBI_2017.rst deleted file mode 100644 index 2509f3e7..00000000 --- a/docs/dev/calibration_WBI_2017.rst +++ /dev/null @@ -1,7 +0,0 @@ -Calibration module -=================== - -.. automodule:: calibration_WBI - :members: - :undoc-members: - :show-inheritance: \ No newline at end of file diff --git a/docs/dev/geohydrology.rst b/docs/dev/geohydrology.rst deleted file mode 100644 index e94cdbbf..00000000 --- a/docs/dev/geohydrology.rst +++ /dev/null @@ -1,7 +0,0 @@ -Geohydrology functions -====================== - -.. automodule:: geohydro_functions - :members: - :undoc-members: - :show-inheritance: \ No newline at end of file diff --git a/docs/dev/overview.rst b/docs/dev/overview.rst deleted file mode 100644 index 79a7662e..00000000 --- a/docs/dev/overview.rst +++ /dev/null @@ -1,46 +0,0 @@ -.. _devapi: - -Developer API -============= - -GeoProb-Pipe bestaat uit verschillende submodules. - -Geohydrology models -------------------- - -.. toctree:: - :maxdepth: 3 - - geohydrology - -Piping models -------------- - -.. toctree:: - :maxdepth: 3 - - pipingmodels - -Calibration functions ---------------------- - -.. toctree:: - :maxdepth: 3 - - calibration_WBI_2017 - -Stats functions ---------------- - -.. toctree:: - :maxdepth: 3 - - stats_utils - - -Indices and tables ------------------- - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` \ No newline at end of file diff --git a/docs/dev/pipingmodels.rst b/docs/dev/pipingmodels.rst deleted file mode 100644 index 534702dc..00000000 --- a/docs/dev/pipingmodels.rst +++ /dev/null @@ -1,7 +0,0 @@ -Piping functions -=================== - -.. automodule:: piping_functions - :members: - :undoc-members: - :show-inheritance: \ No newline at end of file diff --git a/docs/dev/stats_utils.rst b/docs/dev/stats_utils.rst deleted file mode 100644 index 641e46b8..00000000 --- a/docs/dev/stats_utils.rst +++ /dev/null @@ -1,7 +0,0 @@ -Stats utilities Module -======================= - -.. automodule:: stats_utils - :members: - :undoc-members: - :show-inheritance: \ No newline at end of file diff --git a/docs/gebruik.rst b/docs/gebruik.rst new file mode 100644 index 00000000..832f04b5 --- /dev/null +++ b/docs/gebruik.rst @@ -0,0 +1,24 @@ +Gebruik applicatie +================== + +Je start de applicatie door in de virtual environment waarin GeoProb‑Pipe is geïnstalleerd het commando ``geoprob-pipe`` +uit te voeren. De applicatie begeleidt je vervolgens stap voor stap, te beginnen met een keuzemenu. Op deze pagina +wordt uitgelegd hoe je de applicatie gebruikt en waarvoor. Hierbij komen onder meer het importeren van invoergegevens, +het exporteren van resultaten, het vergelijken van verschillende projectbestanden en het inladen van data in andere +applicaties aan bod. + +.. toctree:: + :maxdepth: 2 + :caption: Inhoud + :titlesonly: + + gebruik/keuze_menu + gebruik/invoer + gebruik/uitvoer + gebruik/projectbestanden_vergelijken + gebruik/enkele_berekening_inspecteren + gebruik/inladen_in_qgis + gebruik/inladen_in_db_browser + + + diff --git a/docs/gebruik/enkele_berekening_inspecteren.rst b/docs/gebruik/enkele_berekening_inspecteren.rst new file mode 100644 index 00000000..e3891fc3 --- /dev/null +++ b/docs/gebruik/enkele_berekening_inspecteren.rst @@ -0,0 +1,6 @@ + +Enkele berekening inspecteren +============================= + + +Temp \ No newline at end of file diff --git a/docs/gebruik/inladen_in_db_browser.rst b/docs/gebruik/inladen_in_db_browser.rst new file mode 100644 index 00000000..57284289 --- /dev/null +++ b/docs/gebruik/inladen_in_db_browser.rst @@ -0,0 +1,6 @@ + +Inladen in DB Browser for SQLite +================================ + + +Temp \ No newline at end of file diff --git a/docs/gebruik/inladen_in_qgis.rst b/docs/gebruik/inladen_in_qgis.rst new file mode 100644 index 00000000..84f9b8e4 --- /dev/null +++ b/docs/gebruik/inladen_in_qgis.rst @@ -0,0 +1,6 @@ + +Inladen in QGIS / ArcGIS +======================== + + +Temp \ No newline at end of file diff --git a/docs/gebruik/invoer.rst b/docs/gebruik/invoer.rst new file mode 100644 index 00000000..8d085940 --- /dev/null +++ b/docs/gebruik/invoer.rst @@ -0,0 +1,228 @@ +Invoergegevens importeren +========================= + +Tijdens het importeren van de invoergegevens doorloop je de onderstaande stappen. Wanneer alle stappen een +vinkje hebben, zijn alle gegevens volledig ingevoerd. + + +.. code-block:: bash + + ALGEMEEN + ✔ Geohydrologisch model al ingesteld. + + GIS LAGEN + ✔ Dijktraject al toegevoegd. + ✔ Vakindeling al toegevoegd. + ✔ HRD-bestanden al toegevoegd. + ✔ HRD-locatie punten al uitgelezen. + ✔ HRD-fragility lines al uitgelezen. + ✔ Uittredepunten al toegevoegd (#### in totaal). + ✔ Polderpeil al toegevoegd. + ✔ Binnenteenlijn al toegevoegd. + ✔ Buitenteenlijn al toegevoegd. + ✔ Intredelijn al toegevoegd. + + GEOGRAFISCHE KOPPELINGEN + ✔ Afstand en metrering tot reflijn al gekoppeld aan uittredepunten. + ✔ HRD-locaties al gekoppeld aan uittredepunten. + ✔ Afstanden intrede, buitenteen en binnenteen al gekoppeld aan uittredepunten. + ✔ Polderpeil al gekoppeld aan uittredepunten. + ✔ Vakken al gekoppeld aan uittredepunten. + + PARAMETER INVOER + ✔ Parameter invoer afgerond. + + + +Algemeen +^^^^^^^^ +Er is één algemeen item in het invoerproces, namelijk de keuze van het geohydrologische model. Dit is een vertaling van +de grondwaterstroming als gevolg van het hoogwater, met als resultaat van het model een schatting van de stijghoogte in +het uittredepunt. Momenteel zijn 3 modellen ingebouwd, waaronder het veel gebruikte model 4A. Een gedetailleerde +beschrijving vind je :ref:`hier`. + + +GIS lagen & Geografische koppelingen +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +In het onderdeel 'GIS lagen' wordt de gebruiker gevraagd om verschillende geografische datasets te importeren. Dit +betreft onder andere het dijktraject, de vakindeling, de uittredepunten en de intredelijn. Gegevens kunnen worden +ingelezen vanuit een Shapefile, GeoDatabase of GeoPackage. + +Na het importeren van de geografische data worden de benodigde geografische koppelingen automatisch gelegd. Hierbij +worden de verschillende datasets voornamelijk gekoppeld aan de uittredepunten, zoals het polderpeil. + + +Parameter invoer +^^^^^^^^^^^^^^^^ +Het proces van parameterinvoer vraagt om enige toelichting, omdat het iteratief van aard is. De invoer van parameters +verloopt via een Excel‑bestand dat in GeoProb‑Pipe wordt geïmporteerd. Binnen dit bestand kunnen parameters op +verschillende hiërarchische niveaus worden gespecificeerd: + +- Trajectniveau +- Vakniveau +- Vakniveau per ondergrondscenario +- Uittredepuntniveau + +Wanneer voor een parameter zowel geografische invoer als Excel‑invoer beschikbaar is, heeft de Excel‑invoer voorrang +en wordt de geografische invoer overschreven. + +Het voordeel van invoer op verschillende niveaus is dat je GeoProb-Pipe eerst globaal kunt vullen op trajectniveau, +vervolgens de berekeningen kunt uitvoeren en daarna — op basis van de resultaten — de invoer verder kunt verfijnen op +lagere niveaus zoals vakniveau. Dit maakt het proces iteratief: je specificeert steeds meer detail naarmate het oordeel +verder moet worden aangescherpt. + +Onder de motorkap doorzoekt GeoProb‑Pipe deze niveaus hiërarchisch. Als op een lager niveau geen invoer beschikbaar is, +kijkt het programma automatisch naar het eerstvolgende hogere niveau. Wanneer er bijvoorbeeld geen invoer is op +vakniveau, wordt automatisch gecontroleerd of er invoer op trajectniveau aanwezig is. Hierdoor hoef je alleen invoer +op te geven voor de vakken, scenario’s of uittredepunten waarvoor je daadwerkelijk een nadere detaillering wilt +doorvoeren. + +In de onderstaande figuur staat een voorbeeld van hoe invoer op de verschillende niveaus wordt toegepast. + +[[TODO: Figuur toevoegen]] + +.. TODO: Waar beschrijven we hoe parameter invoer elkaar kan overlappen? + +Keuze menu 'Parameter invoer' +""""""""""""""""""""""""""""" +De volgende keuze opties zijn er: + + - Zijn de invoer tabellen zijn naar wens? Ga door naar volgende stap + - Overzichtsfiguren van invoertabellen: Exporteren + +De overzichtsfiguren bieden middels HTML-figuren een interactieve manier om snel visueel te zien hoe de invoer van je +parameters is gedaan. Je krijgt een figuur per parameter. + + - Invoer tabellen: Importeren vanuit Excel + - Invoer tabellen: Exporteren naar Excel + + +Beschrijving specifieke parameters +"""""""""""""""""""""""""""""""""" +Een beschrijving van de invoerparameters staat :ref:`hier` beschreven. + +.. TODO: Moeten we wel verwijzen naar de geohydrologische modellen? Er is nog een bovenliggende model Piping zelf. + Daar naar verwijzen, waarna die wel weer doorverwijst naar de geohydrologische modellen? + + + + + + +.. TODO: Verwijzingen aanmaken. + + + +Rekenmodel +~~~~~~~~~~ + +Er zijn enkele algemene instellingen, dit is hoofdzakelijk de systeem keuze. Momenteel is enkel `Piping`` een keuze. +Later wordt dit uitgewerkt naar onder andere de keuzes ``model4a`` en deze i.c.m. Moria en/of het toepassen van +respons. +:ref:`Rekenmethodiek ` + +Verschalingsfactoren +~~~~~~~~~~~~~~~~~~~~ + +sdfsdf + + +Importeren GIS-data +~~~~~~~~~~~~~~~~~~~ + +`GeoProb-Pipe` vraagt je stapsgewijs om de GIS-data te importeren. Hij zal je vragen naar de locatie van de data. Dit +kun je aanleveren als Shape-bestand, GeoDatabase of GeoPackage. De GIS data is bijvoorbeeld het dijktraject, de +vakindeling en de uittredepunten. Omdat je de applicatie op elk moment kunt afsluiten, kun je ook eerst een deel van de +GIS-data importeren en later verder gaan. Bijvoorbeeld, voor de uittredepunten locaties kan `GeoProb-Pipe` voor jou een +eerste suggestie maken, waarna jij deze in ArcGIS zelf verder kunt aanvullen. + +Omdat `GeoProp-Pipe` een GeoPackage is, kan je alle geïmporteerde data in ArcGIS bekijken en controleren of het goed is +geïmporteerd. + +Aan het einde van het importeren van alle GIS-data zal `GeoProb-Pipe` vinkjes geven voor elk onderdeel. Dit ziet er +als het volgt uit. + + + + +Importeren parameter invoer +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + + + +Dit doe doe je door de `GeoProb-Pipe`-applicatie +op te starten. Deze neemt je vervolgens mee door alle stappen. In paragraaf :ref:`pre-processing` is hier verder op +ingegaan. Het resultaat van dit bestand is een .geoprob_pipe.gpkp-bestand. Dit bestand is een GeoPackage, te openen in +ArcGIS, met alle invoer. + + + +Vastleggen algemene uitgangspunten van de berekening +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Vastleggen uittredepunten +~~~~~~~~~~~~~~~~~~~~~~~~~ + +De volgende informatie dient te worden vastgelegd per uittredepunt: + +* `UittredepuntID`: elk punt heeft een eigen identifer +* `Locatie (x, y)`: locatie in RD coördinaten (bijv. geopandas-object) +* `Mvalue`: waarde die de locatie van het uittredepunt weergeeft ten opzichte van de referentielijn. zie voorbeelden over linear referencing. +* `Uittredelocatie`: optioneel, beschrijving van de locatie van het uittredepunt. Handig voor analyse van de berekeningen. +* (Ruimtelijke) koppeling met het vak van de ondergrondschenario: `VakID` en `Vaknaam`. +* `DIST_L_GEOM`: kortste afstand tot de geschematiseerde `geometrische intredelijn`. +* `DIST_BUT`: korste afstand tot de geschematiseerde `buitenteen lijn`. +* `DIST_BIT`: korste afstand tot de geschematiseerde `binnenteen lijn`. +* `HydraLocatie`: ruimtelijke koppeling met de dichtsbijzijnde uitvoerlocatie. +* `Bodemhoogte`: bodemhoogte (maaiveldniveau) ter plaatse van het uittredepunt. +* `Polderpeil`: benedenstroomse waterpeil ter plaatse van het uittredepunt. + +De werkwijze is als volgt: + +1. definieer uittredepunten in GIS omgeving: dit levert `UittredepuntID`, `Locatie (x, y)` +2. Bepaal `Mvalue` via linear referencing aan de `referentielijn`. +3. Koppel `uittredepunten` aan `vakindeling`: dit levert `VakID` en `Vaknaam`. +4. Bepaal `DIST_L_GEOM`, `DIST_BUT`, `DIST_BIT` door spatial join met `Geometrische Intredelijn`, `Buitenteen` en `Binnenteen`. +5. Bepaal `Bodemhoogte` door samplen raster met DTM/AHN +6. Bepaal `Polderpeil` door intersectie met een polygon `Polderpeilen`. +7. Koppel `HydraLocatie` aan `Overschrijdingsfrequenties`. + + +Discussie uittredepunten tabel +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +1. De geometrische lengte van het achterland `L3_geom` is nu vastgelegd per vak. Dit is een parameter die niet heel precies vastgelegd hoeft te worden en vaak vooraf onbekend is. In lijn met `DIST_BUT` kan `L3_geom` ook worden vastgelegd als een geometrie en als veld aan het object `uittredepunten` worden toegevoegd. + +2. Optioneel kan het model worden uitgebreid met de verwachte top van het zand ter plaatse van het uittredepunt. + + +Typen ondergrondscenario's +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Een ondergrondscenario is een unieke verzameling van variabelen die de eigenschappen van de ondergrond beschrijven. Ondergrondscenario's worden per vak of per uittredepunt vastgelegd. Er zijn drie typen ondergrondscenario's: + +- Holoceen gefundeerd (HLF): Hierbij zit de deklaag boven een holocene zandlaag welke samen met de onderliggende pleistocene zandlaag het watervoerend pakket vormen. +- Pleistoceen (PL): Hierbij ligt de deklaag direct boven op een pleistocene zandlaag. +- Tussenzandlaag: Hierbij is er nog een tussenzandlaag aanwezig omsloten door de deklaag en een andere kleilaag. Deze is niet in direct contact met het pleistocene watervoerend pakket. + +Een kenmerk van ondergronscenario's is dat ze discreet zijn. Of het ene scenario komt voor binnen een vak of het andere. Afhankelijk van de beschikbare data kan je per uittredepunt de ondergrondscenario's vastleggen. We kiezen er in deze implementatie voor om per vak een ondergrondscenario vast te leggen. Dit betekent dat alle uittredepunten binnen een vak dezelfde (typen) ondergrondscenario's hebben. + +.. figure:: /_static/TypenOndergrondscenario.png + :width: 100% + + Voorbeeld typen ondergrondscenario's + + +.. TODO: + + Bronbestanden voor de uittredepunten tabel + De locaties van mogelijke uittredepunten + Uitvoer van een Hydra-NL berekening + Vakindeling + Genereren scenarioberekeningen + Uitvoeren scenarioberekeningen + Probabilistische berekeningen + Combineren deelfaalmechanismen + Combineren scenarioberekeningen + Post Processing diff --git a/docs/gebruik/keuze_menu.rst b/docs/gebruik/keuze_menu.rst new file mode 100644 index 00000000..f03125bb --- /dev/null +++ b/docs/gebruik/keuze_menu.rst @@ -0,0 +1,26 @@ +Keuzemenu GeoProb‑Pipe +====================== +In het hoofdmenu van GeoProb‑Pipe zijn de volgende functies beschikbaar. Hieronder volgt een korte toelichting per +optie. + +Bestaand project openen + Met deze optie open je een eerder aangemaakt project. Dit is handig wanneer de invoer nog niet compleet is of + wanneer je gevoeligheidsanalyses wilt uitvoeren op bestaande berekeningen. + +Nieuw project starten +^^^^^^^^^^^^^^^^^^^^^ + +Gebruik deze functie om een geheel nieuw project aan te maken. Je doorloopt daarbij alle invoerstappen die nodig zijn +voor een nieuwe analyse. + +Twee projectbestanden vergelijken +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Met deze functie kun je twee projectbestanden naast elkaar zetten om verschillen te identificeren. Dit is vooral nuttig +bij gevoeligheidsanalyses, waarbij je wilt zien welke invloed een wijziging heeft op de oorspronkelijke analyse. + +Inspecteer een enkele berekening +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Deze optie is bedoeld voor gebruikers met enige ervaring met Python. Hiermee kun je het rekenobject en de +onderliggende objecten uit de Probabilistic Library (PTK toolkit Python‑wrapper) bekijken. Dit is vooral waardevol +wanneer je berekeningen wilt vergelijken met de desktopversie van de PTK toolkit of wanneer je dieper inzicht wilt +krijgen in de gebruikte parameters en datastructuren. \ No newline at end of file diff --git a/docs/gebruik/projectbestanden_vergelijken.rst b/docs/gebruik/projectbestanden_vergelijken.rst new file mode 100644 index 00000000..d7df3cb0 --- /dev/null +++ b/docs/gebruik/projectbestanden_vergelijken.rst @@ -0,0 +1,6 @@ + +Projectbestanden vergelijken +============================ + + +Temp \ No newline at end of file diff --git a/docs/gebruik/uitvoer.rst b/docs/gebruik/uitvoer.rst new file mode 100644 index 00000000..c6821bfd --- /dev/null +++ b/docs/gebruik/uitvoer.rst @@ -0,0 +1,6 @@ + +Resultaten exporteren +===================== + + +test \ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst index f26f08f3..0a8796f2 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,64 +1,27 @@ .. GeoProb-Pipe documentation master file, created by - sphinx-quickstart on Fri Mar 28 16:05:34 2025. + sphinx-quickstart on Mon Sep 1 13:09:20 2025. You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. +GeoProb-Pipe documentation +========================== -**GeoProb-Pipe** is een Python app om probabilistische pipingberekeningen uit te voeren. De grenstoestandfuncties zijn aangepast zodat de respons in het watervoerende pakket beschreven wordt door model4a van het Technisch Rapport Waterspanningen bij Dijken :cite:`trw_2004`. Deze documentatie is bedoeld om de gebruiker achtergronden te geven bij keuzes die gemaakt zijn bij de implementatie van de grenstoestandfuncties en de analytische oplossing van het stationaire model. De documentatie is ook bedoeld voor ontwikkelaars die de bibliotheek verder willen ontwikkelen. +Welkom bij de documentatie van GeoProb-Pipe, een probabilistische applicatie om pipingberekeningen met de +uittredepuntenmethode uit te voeren. Deze documentatie biedt handreikingen voor het gebruik van GeoProb-Pipe, de +achtergronden van de methode, API-referenties en voorbeelden. - -Gebruiksinstructies -------- - -In het Python-bestand ``GeoProb-Pipe/app/main_piping.py`` vind je een template om de applicatie uit te voeren. Hier kun -je een kopie van maken en aanpassen naar jouw use case. Pas bijvoorbeeld de variabele ``PATH_WORKSPACE`` aan en verwijs -naar de locatie met jouw invoer bestanden. In de huidige locatie van ``PATH_WORKSPACE`` staan voorbeeld bestanden. - - -Toepassingsgebied -------- - -De methode gaat uit van (in principe) een oneindig aantal mogelijke locaties van wellen (of uittredepunten) die een onbekende bijdrage kunnen hebben aan de overstromingskans van een dijktraject. Meer informatie is te vinden in onderstaande link. +.. TODO: Uitnodigende afbeelding toevoegen de applicatie. Wellicht kaartje/bovenaanzicht van resultaat. .. toctree:: - :maxdepth: 2 - - background/uittredepuntenmethode - -Achtergronden -------------- - -In dit deel van de documentatie zijn de achtergronden beschreven van de implementatie van de functies die in deze bibliotheek zijn opgenomen. - -.. toctree:: - :maxdepth: 2 - - background/uittredepuntenmethode - background/stationair_model - background/piping - background/grenstoestandfuncties - - -API ---- - -.. toctree:: - :maxdepth: 2 - - dev/overview - - -Referenties ------------ - -.. toctree:: - :maxdepth: 2 - + :maxdepth: 1 + :caption: Contents: + + quick_start + installatie_proces + gebruik + rekenmethodiek + Uittredepuntenmethode + Relatie_beslisraamwerk_piping + Assembleren references -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` diff --git a/docs/installatie_proces.rst b/docs/installatie_proces.rst new file mode 100644 index 00000000..042b82a1 --- /dev/null +++ b/docs/installatie_proces.rst @@ -0,0 +1,28 @@ + +Installatie proces +================== + +De installatie en het gebruik van `GeoProb-Pipe` is eenvoudig en wordt hieronder toegelicht. + +Start een schone Python environment. `GeoProb-Pipe` is ontwikkelt op Python 3.12. Deze versie wordt aangeraden voor +gebruik. Voer daarna de volgende commando's uit om eerst `GeoProb-Pipe` te installeren en vervolgens de probabilistische +bibliotheek (PTK-tool wrapper) te installeren. + + +.. code-block:: bash + + pip install geoprob_pipe + pip install probabilistic_library + +.. TODO: Overleggen met Deltares dat ze de probabilistic_library beschikbaar maken in PyPI. + +Daarna start je de applicatie met het commando. Zorg er voor dat je Python-environment actief is. + +.. code-block:: bash + + geoprob_pipe + +Na het opstarten van de applicatie begeleidt `GeoProb-Pipe` je door het gebruik. Je kunt op elk moment de applicatie +afsluiten, en weer opstarten. Meestal geeft de applicatie je de mogelijkheid om af te sluiten, is dit niet het geval, +dan kun je dat doen middels de toetsencombinatie ``ctrl + c``. + diff --git a/docs/quick_start.rst b/docs/quick_start.rst new file mode 100644 index 00000000..6d7f0db7 --- /dev/null +++ b/docs/quick_start.rst @@ -0,0 +1,16 @@ +Quick start +=========== + +`GeoProb-Pipe` neemt je mee door het gebruik van de applicatie. De quick start voor gebruik is daarom enkel de +installatie en het commando om de applicatie op te starten. Dat zijn de volgende twee commando's. + +.. code-block:: bash + + pip install geoprob_pipe + geoprob_pipe + + +.. warning:: + Momenteel is ``geoprob_pipe``, en de onderliggende software requirement ``probabilistic_library``, nog niet + beschikbaar in de Python Package Index. Installeer voorlopig GeoProb-Pipe vanuit een kloon van de repository. + Je vind de instructies in de README. \ No newline at end of file diff --git a/docs/references.rst b/docs/references.rst index 62154803..679f8838 100644 --- a/docs/references.rst +++ b/docs/references.rst @@ -1,7 +1,5 @@ Referenties =========== -.. rubric:: References - .. bibliography:: bibliography.bib :style: unsrt diff --git a/docs/rekenmethodiek.rst b/docs/rekenmethodiek.rst new file mode 100644 index 00000000..53108c3a --- /dev/null +++ b/docs/rekenmethodiek.rst @@ -0,0 +1,14 @@ +Rekenmethodiek +============== + +Deze pagina beschrijft de rekenmethodiek die `GeoProb-Pipe` gebruikt voor het berekenen van de +totale faalkans op piping per uittredepunt. + +.. toctree:: + :maxdepth: 2 + :caption: Inhoud + :titlesonly: + + rekenmethodiek/implementatie + rekenmethodiek/faalpad + rekenmethodiek/geohydrologische_modellen \ No newline at end of file diff --git a/docs/rekenmethodiek/faalpad.rst b/docs/rekenmethodiek/faalpad.rst new file mode 100644 index 00000000..812089f3 --- /dev/null +++ b/docs/rekenmethodiek/faalpad.rst @@ -0,0 +1,155 @@ +Faalpad en foutenboom piping +============================ + +In :numref:`faalpad-STPH` zie je een veelvoorkomend faalpad voor het faalmechanisme *piping* :cite:`HOVK_STPH_2024`. +`GeoProb-Pipe` richt zich op het modelleren van de initiële mechanismen die leiden tot piping: opbarsten, heave en +terugschrijdende erosie. Hierbij wordt aangenomen dat piping optreedt wanneer de deklaag opbarst, heave optreedt en +er doorgaande terugschrijdende erosie plaatsvindt. In de schematiseringshandleiding piping :cite:`sh_piping_2021` +zijn de bijbehorende grenstoestandsfuncties beschreven die in het BOI en in `GeoProb-Pipe` worden gebruikt. + +.. _faalpad-STPH: + +.. figure:: _static/faalpad_piping.png + :alt: Veelvoorkomend faalpad voor het faalmechanisme piping. + :align: center + + Veelvoorkomend faalpad voor het faalmechanisme *piping* :cite:`HOVK_STPH_2024`. + +.. TODO: Foutenboom toevoegen als plaatje? + +Basis grenstoestandsfuncties BOI +-------------------------------- + +De onderstaande grenstoestandsfuncties vormen de kern van de berekening in `GeoProb-Pipe`. +Ze worden identiek toegepast in elk stijghoogtemodel (`limit_state_wbi`, `limit_state_model4a`, `limit_state_moria`). +De verschillen tussen de modellen zitten uitsluitend in de berekening van de stijghoogte :math:`\phi_{exit}` en bijbehorende parameters. + +Opbarsten +~~~~~~~~~ + +De grenstoestandfunctie van **opbarsten** :math:`Z_{u}` is in :cite:`sh_piping_2021` als volgt gedefinieerd: + +.. math:: + + Z_{u} = m_{u} \cdot \Delta \phi_{c,u} - (\phi_{exit} - h_{exit}) + +waarbij :math:`m_{u}` de modelfactor voor opbarsten is [-]. + +De grenspotentiaal ten opzichte van maaiveldniveau :math:`\Delta \phi_{c,u}` [m] wordt bepaald door het effectieve gewicht van de deklaag onder water: + +.. math:: + + \Delta \phi_{c,u} = \frac{d_{deklaag} \cdot (\gamma_{sat,deklaag} - \gamma_{w})}{\gamma_{w}} + +waarin: + +- :math:`d_{deklaag}` de dikte van de deklaag is [m] +- :math:`\gamma_{sat}` het gemiddeld verzadigd volumegewicht van de cohesieve deklaag is [kN/m³] +- :math:`\gamma_{w}` het volumegewicht van water is [kN/m³] + +De dikte van de deklaag :math:`d_{deklaag}` ter plaatse van het uittredepunt is gedefinieerd als de verticale afstand tussen het maaiveldniveau en de bovenkant van de pipinggevoelige zandlaag: + +.. math:: + + d_{deklaag} = mv_{exit} - top_{zandlaag} + +waarin: +- :math:`mv_{exit}` maaiveldniveau ter plaatse van het uittredepunt [m+NAP] +- :math:`top_{zandlaag}` niveau bovenkant van de pipinggevoelige zandlaag [m+NAP] + +De stijghoogte ter plaatse van het uittredepunt :math:`\phi_{exit}` [m+NAP] wordt volgens de schematiseringshandleiding :cite:`sh_piping_2021` beschreven door: + +.. math:: + + \phi_{exit} = \phi_{polder} + r_{exit} \cdot (h_{rivier} - \phi_{polder}) + +waarin: + +- :math:`\phi_{polder}` het waterniveau in de polder [m+NAP] +- :math:`r_{exit}` de dempingsfactor ter plaatse van het uittredepunt [-] +- :math:`h_{rivier}` het waterniveau in de rivier [m+NAP] + +De dempingsfactor :math:`r_{exit}` ter plaatse van het uittredepunt is afhankelijk van de locatie van het uittredepunt ten opzichte van de dijk en de geohydrologische situatie. De schematiseringshandleiding piping :cite:`sh_piping_2021` hanteert dit als een onafhankelijke invoerparameter. + +:math:`h_{exit}` is de randvoorwaarde in het uittredepunt, gedefinieerd door het maximum van het polderpeil en het maaiveldniveau ter plaatse van het uittredepunt: + +.. math:: + + h_{exit} = max(\phi_{polder}, mv_{exit}) + +waarin: + +- :math:`\phi_{polder}` het waterniveau in de polder [m+NAP] + + +Heave +~~~~~ + +De grenstoestandfunctie van **heave** :math:`Z_{h}` is in :cite:`sh_piping_2021` als volgt gedefinieerd: + +.. math:: + + Z_{h} = m_{h} \cdot i_{i,c} - \frac{\phi_{exit} - h_{exit}}{d_{deklaag}} + +waarin: + +- :math:`m_{h}` de modelfactor voor heave is [-] +- :math:`i_{i,c}` de kritieke heave-gradiënt is [-] + +Opgemerkt wordt dat de modelfactoren :math:`m_{u}` en :math:`m_{h}` niet zijn opgenomen in de formules van de schematiseringshandleiding piping :cite:`sh_piping_2021`, maar wel in deze implementatie zijn opgenomen om de modelonzekerheid expliciet te kunnen kwantificeren. + + +Terugschrijdende erosie +~~~~~~~~~~~~~~~~~~~~~~~ + +De grenstoestandfunctie van **terugschrijdende erosie** :math:`Z_{p}` is in :cite:`sh_piping_2021` als volgt gedefinieerd: + +.. math:: + + Z_{p} = m_{p} \cdot \Delta H_{c} - \Delta h_{red} + +met :math:`\Delta h_{red}` het gereduceerde verval over de deklaag [m] als: + +.. math:: + + \Delta h_{red} = h_{buitenwaterstand} - h_{exit} - r_{c,deklaag} \cdot d_{deklaag} + +waarin: + +- :math:`m_{p}` de modelfactor voor terugschrijdende erosie is [-] +- :math:`\Delta H_{c}` het kritieke verval over de deklaag is [m] +- :math:`h_{buitenwaterstand}` de buitenwaterstand is [m+NAP] +- :math:`h_{exit}` de randvoorwaarde in het uittredepunt is [m+NAP] +- :math:`r_{c,deklaag}` de reductieconstante van het verval over de deklaag is [-] +- :math:`d_{deklaag}` de dikte van de deklaag is [m] + + Het kritieke verval over de deklaag :math:`\Delta H_{c}` is gebaseerd op het in 2011 aangepaste model van Sellmeijer. + + .. math:: + + \Delta H_{c} = L_{kwelweg} \cdot F_{resistance} \cdot F_{scale} \cdot F_{geometry} + +met: + +.. math:: + + F_{resistance} = \eta \frac{\gamma_{korrel} - \gamma_{w}}{\gamma_{w}} \cdot tan(\theta) + + F_{scale} = \frac{d_{70,m}}{\sqrt[3]{L_{kwelweg} \cdot \frac{k \cdot \upsilon_{w}}{g}}} \left(\frac{d_{70}}{d_{70,m}} \right)^{0.4} + + F_{geometry} = 0.91 \left(\frac{D_{wvp}}{L_{kwelweg}} \right)^{\frac{0.28}{\left(\frac{D_{wvp}}{L_{kwelweg}} \right)^{2.8} - 1} + 0.04} + + +waarin: + +- :math:`L_{kwelweg}` de kwelweglengte is [m], gedefinieerd als de horizontale afstand tussen het uittredepunt en een onzeker intredepunt. +- :math:`\eta` coëfficiënt van White (sleepkrachtfactor) [-]. Standaardwaarde is 0.25 +- :math:`\gamma_{korrel}` volumieke dichtheid van zand [kN/m³]. Standaardwaarde is 26.0 kN/m³ +- :math:`\gamma_{w}` het volumegewicht van water [kN/m³] +- :math:`\theta` de rolweerstandshoek van zandkorrels van de aangepaste Sellmeijer-rekenregel [°]. Standaardwaarde is 37° +- :math:`d_{70,m}` de referentie- :math:`d_{70}`-waarde [m]. Standaardwaarde is 2.08E-4 m +- :math:`d_{70}` de 70-percentielwaarde van de korrelverdeling van de pipinggevoelige laag [m] +- :math:`k` de Darcy-doorlatendheid van de zandlaag [m/s] +- :math:`\upsilon_{w}` de kinematische viscositeit van water [m²/s]. Standaardwaarde is 1.33E-6 m²/s bij 10°C +- :math:`g` de zwaartekrachtversnelling [m/s²]. Standaardwaarde is 9.81 m/s² +- :math:`D_{wvp}` de dikte van de watervoerende zandlaag [m] diff --git a/docs/rekenmethodiek/geohydrologische_modellen.rst b/docs/rekenmethodiek/geohydrologische_modellen.rst new file mode 100644 index 00000000..f0b0993d --- /dev/null +++ b/docs/rekenmethodiek/geohydrologische_modellen.rst @@ -0,0 +1,296 @@ +.. _stijghoogtemodellen-geoprob: +Geohydrologische modellen in GeoProb-Pipe +========================================= + +De berekening van de stijghoogte :math:`\phi_{exit}` wordt uitgevoerd binnen de limit-state functies, +waarbij elke functie een specifiek type geohydrologisch / stijghoogte model aanroept: + +- ``limit_state_wbi`` – eenvoudige benadering met vaste responsfactor; +- ``limit_state_model4a`` – analytisch grondwatermodel 4A (doorsnede); +- ``limit_state_moria`` – numeriek rastermodel (zoals het regionale grondwatermodel MORIA). + +De code structuur is zodanig opgezet dat in de toekomst ook andere geohydrologische modellen kunnen worden toegevoegd. + + +Analytische stijghoogtemodel WBI +-------------------------------- +.. TODO: Tekst nog toevoegen. + + +.. _model4a: +Analytische stijghoogtemodel 4A +------------------------------- + +Het analytische grondwatermodel *4A* vormt één van de mogelijke implementaties van het stijghoogtemodel +(*stap 3* van de rekenmethodiek). +Dit model beschrijft de stroming van grondwater door de zandlaag onder een dijk op basis van stationaire, +lineaire stroming in doorsnedeniveau. +De overige fysische componenten en grenstoestandsfuncties worden op identieke wijze berekend als bij andere +stijghoogtemodellen; alleen de bepaling van de stijghoogte :math:`\phi_{exit}` en de responsfactor :math:`r_{exit}` +verschilt. + +De grondwaterstroming vormt de drijvende kracht achter het proces van terugschrijdende erosie. +Door het analytische grondwatermodel 4A van :cite:`trw_2004` toe te passen, +kan de respons :math:`r_{exit}` in het uittredepunt worden beschreven als functie van de locatie in het +dwarspofiel :math:`x_{exit}` [m] en de geohydrologische parameters van model 4A. +Een uitgebreide toelichting op de onderliggende theorie van dit model is te vinden in :ref:`stationair-model`. + +De respons in het uittredepunt wordt bepaald met: +.. math:: + + r_{exit}(x) = f(x_{exit}, L_1, L_2, L_3, c_{voorland}, c_{achterland}, k, D_{wvp}) + +Geometrische parameters +~~~~~~~~~~~~~~~~~~~~~~~ +Geometrische parameters :math:`L_1` en :math:`L_2` zijn omgeschreven naar afstanden ten opzichte van het uittredepunt: + +.. math:: + + L_1 = L_{intrede} - L_{but} + + L_2 = L_{but} - L_{bit} + +waarin: + +- :math:`L_{intrede}` de afstand van het uittredepunt tot een geometrische intredelijn [m] +- :math:`L_{but}` de afstand van het uittredepunt tot de buitenteen [m] +- :math:`L_{bit}` de afstand van het uittredepunt tot de binnenteen [m] +- :math:`L_3` de achterlandlengte [m] +- :math:`x_{exit}` de afstand van het uittredepunt tot de binnenteen [m]. De aanname is dat uittredepunten altijd binnendijks van een (denkbeeldige) binnenteen liggen. +- :math:`c_{voorland}` de weerstand van de deklaag in het voorland [dag] +- :math:`c_{achterland}` de weerstand van de deklaag in het achterland [dag] + + +Effectieve voorlandlengte +~~~~~~~~~~~~~~~~~~~~~~~~~ +De kwelweglengte :math:`L_{kwelweg}` maakt conform de schematiseringshandleiding piping :cite:`sh_piping_2021` gebruik van het principe van de effectieve voorlandlengte. + +.. math:: + + L_{kwelweg} = L_{but} + L_{eff,voorland} + + L_{eff,voorland} = \lambda_{1} \cdot tanh(\frac{L_1}{\lambda_{1}}) + + \lambda_{1} = \sqrt{c_{voorland} \cdot k \cdot D_{wvp}} + +waarin: + +- :math:`L_{eff,voorland}` de effectieve voorlandlengte is [m] +- :math:`\lambda_{1}` de spreidingslengte van het voorland is [m] +- :math:`\c` is de deklaagdikte gedeeld door de doorlatendheid van de deklaag [dag] + +Overzicht parameters model 4A +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Het berekeningsmodel met het analytische grondwatermodel 4A kent de volgende invoerparameters: + +.. list-table:: Invoerparameters berekeningsmodel met model 4A + :widths: 20 60 20 + :header-rows: 1 + + * - Variable + - Omschrijving + - Verdeling/Constante + * - :math:`h_{buitenwaterstand}` + - Buitenwaterstand [m+NAP] + - CDF + * - :math:`\phi_{polder}` + - Waterniveau in de polder [m+NAP] + - deterministisch + * - :math:`mv_{exit}` + - Maaiveldniveau ter plaatse van uittredepunt [m+NAP] + - deterministisch + * - :math:`r_{c,deklaag}` + - Reductieconstante van het verval over de deklaag [-] + - lognormaal + * - :math:`L_{bit}` + - Afstand van het uittredepunt tot de binnenteen [m] + - deterministisch + * - :math:`L_{but}` + - Afstand van het uittredepunt tot de buitenteen [m] + - deterministisch + * - :math:`L_{intrede}` + - Afstand van het uittredepunt tot geometrische intredelijn [m] + - deterministisch + * - :math:`L_{3}` + - Achterlandlengte [m] + - deterministisch + * - :math:`top_{zandlaag}` + - niveau bovenkant van de pipinggevoelige zandlaag [m+NAP] + - normaal + * - :math:`c_{voorland}` + - Weerstand van de deklaag in het voorland [dag] + - lognormaal + * - :math:`c_{achterland}` + - Weerstand van de deklaag in het achterland [dag] + - lognormaal + * - :math:`D_{wvp}` + - Dikte van de watervoerende zandlaag [m] + - lognormaal + * - :math:`kD_{wvp}` + - Transmissiviteit van het watervoerende pakket [m²/dag] + - lognormaal + * - :math:`d_{70}` + - 70-percentielwaarde van de korrelverdeling van de pipinggevoelige laag [m] + - lognormaal + * - :math:`\gamma_{sat,deklaag}` + - Gemiddeld verzadigd volumegewicht deklaag [kN/m³] + - lognormaal, shift = 10.0 + * - :math:`i_{i,c}` + - Kritieke heave gradiënt [-] + - lognormaal + * - :math:`d_{70,m}` + - Referentiewaarde voor de :math:`d_{70}` [m] + - 2.08E-4 m + * - :math:`\upsilon_{w}` + - Kinematische viscositeit van water [m²/s] + - 1.33E-6 m²/s bij 10°C + * - :math:`\eta` + - Coëfficiënt van White (sleepkrachtfactor) [-] + - 0.25 + * - :math:`\theta` + - Rolweerstandshoek van zandkorrels van de aangepaste Sellmeijer rekenregel [°] + - 37° + * - :math:`g` + - Zwaartekrachtversnelling [m/s²] + - 9.81 m/s² + * - :math:`\gamma_{korrel}` + - Volumieke dichtheid zand [kN/m³] + - 26.0 kN/m³ + * - :math:`\gamma_{w}` + - Volumegewicht van water [kN/m³] + - 9.81 kN/m³ + * - :math:`m_{u}` + - Modelfactor opbarsten [-] + - normaal + * - :math:`m_{h}` + - Modelfactor heave [-] + - normaal + * - :math:`m_{p}` + - Modelfactor terugschrijdende erosie [-] + - normaal + +Numerieke stijghoogtemodellen +----------------------------- + +Het numerieke stijghoogtemodel vormt een tweede implementatie van het stijghoogtemodel (*stap 3* van de rekenmethodiek). +In dit geval wordt de stijghoogte :math:`\phi_{exit}` niet analytisch berekend, maar afgeleid uit een numeriek grondwatermodel +dat de ruimtelijke variatie in stijghoogten expliciet beschrijft. +De overige fysische componenten en grenstoestandsfuncties worden op identieke wijze berekend als bij het analytische model 4A; +alleen de bepaling van de stijghoogte, responsfactor en kwelweglengte verschilt. + +Een numeriek stijghoogtemodel, zoals het regionale grondwatermodel MORIA van Waterschap Rivierenland, +levert informatie in de vorm van raster-bestanden. +Per uittredepunt kunnen hieruit de relevante geohydrologische parameters worden afgeleid. +De volgende variabelen worden uit het grid gelezen: + +- :math:`\phi_{gemiddeld}(x,y)` een grid met het gemiddelde grondwaterstandniveau bij gemiddelde rivierwaterstand [m+NAP] +- :math:`h_{gemiddeld}` de gemiddelde rivierwaterstand nabij het uittredepunt [m+NAP] +- :math:`r_{exit}(x,y)` een grid met de respons in het uittredepunt [-] +- :math:`\lambda_{1}` de spreidingslengte van het voorland [m] + +De stijghoogte in het uittredepunt wordt vervolgens bepaald met: + +.. math:: + + \phi_{exit}(x,y) = \phi_{gemiddeld}(x,y) + r_{exit}(x,y) \cdot (h_{buitenwaterstand} - h_{gemiddeld}) + + L_{eff,voorland} = \lambda_{1} \cdot tanh(\frac{L_1}{\lambda_{1}}) + + L_{kwelweg} = L_{but} + L_{eff,voorland} + +Bespreken: moeten we nog een modelfactor :math:`m_{gw}` voor het stijghoogtemodel toevoegen. + +Grenstoestandfuncties numeriek stijghoogtemodel +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +De formules van de grenstoestandsfuncties zijn nu als volgt: + +Grenstoestandfunctie opbarsten: + +.. math:: + + Z_{u} = m_{u} \cdot \Delta \phi_{c,u} - (\phi_{exit}(x,y) - h_{exit}) + +Grenstoestandfunctie heave: + +.. math:: + + Z_{h} = m_{h} \cdot i_{i,c} - \frac{\phi_{exit}(x,y) - h_{exit}}{d_{deklaag}} + +Grenstoestandfunctie terugschrijdende erosie: + +.. math:: + + Z_{p} = m_{p} \cdot \Delta H_{c} - \Delta h_{red} + + \Delta h_{red} = h_{buitenwaterstand} - h_{exit} - r_{c,deklaag} \cdot d_{deklaag} + + L_{kwelweg} = L_{but} + L_{eff,voorland} + + L_{eff,voorland} = \lambda_{1} \cdot tanh(\frac{L_1}{\lambda_{1}}) + + \lambda_{1} = \sqrt{c_{voorland} \cdot k \cdot D_{wvp}} + + +Correlatie tussen variabelen +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +De beschrijving van het geohydrologische systeem met de variabelen betekent ook dat de onderlinge correlatie van de variabelen apart moet worden gedefinieerd. Dit betreft met name de correlatie tussen de spreidingslengte van het voorland :math:`\lambda_{1}` en de transmissiviteit van het watervoerende zandpakket :math:`kD` en in mindere mate de correlatie tussen de respons in het uittredepunt :math:`r_{exit}` en de transmissiviteit van het watervoerende zandpakket :math:`kD`. In het model 4A zijn deze correlaties modelmatig beschreven. + +In het geval van een numeriek stijghoogtemodel is de correlatie tussen de spreidingslengte van het voorland en de transmissiviteit van het watervoerende zandpakket plaatsafhankelijk en wordt beschreven door het geohydrologische model. + +Om een inschatting te doen van de correlatie tussen deze variabelen wordt een beperkte set van modelberekeningen uitgevoerd waarbij de transmissiviteit van het watervoerende pakket en de weerstand van het voorland wordt gevarieerd. +Voor elke berekening uit deze set wordt de spreidingslengte van het voorland afgeleid. +Gebruikelijk is het om daarbij per variabele 3 scenario's te hanteren (gemiddeld, -1.64 * sigma, +1.64 * sigma). +Voor 2 variabelen resulteert dit in 9 modelberekeningen. + +Uit deze modelberekeningen wordt de gewogen correlatie tussen de transmissiviteit van het watervoerende pakket en de spreidingslengte van het voorland bepaald. Deze correlatie wordt vervolgens gebruikt in de probabilistische analyse. + +Op basis van het model 4A is de correlatie tussen de transmissiviteit van het watervoerende pakket en de spreidingslengte van het voorland ongeveer 0.7, afhankelijk van de gekozen spreiding. +.. TODO: Ik vind deze nog lastig te plaatsen. @skapinga kun jij kijken hoe we deze binnen de structuur een betere plek kunnen geven? + +Overzicht van implementaties in de code +--------------------------------------- +.. TODO: uiteindelijke implementatie controleren en tekst hierop aanpassen. +.. TODO: misschien de theorie (beschrijving grenstoestandsfuncties) en de implementatie (overzicht functies) beter scheiden? + +In onderstaande tabel zijn de huidige implementaties van de stijghoogtemodellen binnen `GeoProb-Pipe` samengevat. +Elke implementatie volgt dezelfde structuur: eerst worden de fysische componenten berekend, +vervolgens de grenstoestandsfuncties, en tenslotte de gecombineerde limiettoestand. + +.. list-table:: Overzicht van limit-state implementaties + :widths: 20 25 35 20 + :header-rows: 1 + + * - Functie + - Beschrijving + - Belangrijkste invoerparameters + - Belangrijkste uitvoerwaarden + + * - ``limit_state_wbi`` + - Basismodel volgens WBI-formulering (met vaste responsfactor). + Wordt gebruikt voor situaties zonder expliciet stijghoogtemodel. + - :math:`L_{kwelweg}`, :math:`h_{buiten}`, :math:`\phi_{polder}`, :math:`r_{exit}`, :math:`d_{70}`, :math:`D_{wvp}`, :math:`\gamma_{sat,deklaag}` + - :math:`Z_u`, :math:`Z_h`, :math:`Z_p`, :math:`Z_{combin}`, :math:`\phi_{exit}`, :math:`h_{exit}` + + * - ``limit_state_model4a`` + - Implementatie van het analytische grondwatermodel 4A (:cite:`trw_2004`). + Berekening van respons :math:`r_{exit}` op basis van doorsnedemodel. + - :math:`L_{intrede}`, :math:`L_{but}`, :math:`L_{bit}`, :math:`c_{voorland}`, :math:`c_{achterland}`, :math:`kD_{wvp}`, :math:`D_{wvp}` + - :math:`Z_u`, :math:`Z_h`, :math:`Z_p`, :math:`Z_{combin}`, :math:`\phi_{exit}`, :math:`r_{exit}`, :math:`L_{kwelweg}` + + * - ``limit_state_moria`` + - Implementatie van een numeriek grondwatermodel (zoals MORIA). + Gebruikt rasterinformatie voor de bepaling van :math:`\phi_{exit}` en :math:`r_{exit}`. + - :math:`\phi_{gemiddeld}(x,y)`, :math:`h_{gemiddeld}`, :math:`r_{exit}(x,y)`, :math:`\lambda_{1}`, :math:`L_{but}` + - :math:`Z_u`, :math:`Z_h`, :math:`Z_p`, :math:`Z_{combin}`, :math:`\phi_{exit}`, :math:`r_{exit}`, :math:`L_{kwelweg}` + + * - ``limit_state_ttim`` *(conceptueel voorbeeld)* + - Interface voor toekomstige uitbreiding met een tijdsafhankelijk grondwatermodel (TTIM). + Input- en outputstructuur is identiek aan de bestaande modellen. + - :math:`\phi_{exit}`, :math:`r_{exit}`, :math:`L_{kwelweg}`, :math:`\lambda_{1}` + - :math:`Z_u`, :math:`Z_h`, :math:`Z_p`, :math:`Z_{combin}` + +Alle functies bevinden zich in het pakket ``geoprob_pipe.calculations`` en maken gebruik van de onderliggende +fysische berekeningen uit ``geoprob_pipe.calculations.physical_components.piping``. +Door deze eenduidige structuur kan elk modeltype afzonderlijk worden aangeroepen in de probabilistische analyse, +zonder dat de onderliggende rekenlogica hoeft te worden aangepast. \ No newline at end of file diff --git a/docs/rekenmethodiek/implementatie.rst b/docs/rekenmethodiek/implementatie.rst new file mode 100644 index 00000000..57d9bd27 --- /dev/null +++ b/docs/rekenmethodiek/implementatie.rst @@ -0,0 +1,34 @@ +Implementatie +============= + +De implementatie van de rekenmethodiek is modulair opgebouwd en bestaat uit drie samenhangende onderdelen: + +1. **Fysische componenten** + In deze stap worden de geohydrologische en geotechnische componenten berekend die de fysieke toestand van het + systeem beschrijven, zoals de deklaagdikte, heave-gradiënt, kwelweglengte en het kritieke verval volgens + Sellmeijer. + Deze berekeningen zijn geïmplementeerd in het subpackage ``geoprob_pipe.calculations.physical_components.piping``. + De fysische componenten vormen de bouwstenen voor de grenstoestandsfuncties. Ze zijn onafhankelijk van het + gekozen stijghoogtemodel: ongeacht of de stijghoogte wordt bepaald met het analytische model 4A of een numeriek + model worden dezelfde fysische componenten toegepast. + +2. **Grenstoestandsfuncties** + De grenstoestandsfuncties beschrijven de drie deelmechanismen die leiden tot piping: + *opbarsten*, *heave* en *terugschrijdende erosie*. + Voor elk mechanisme wordt een aparte grenstoestandsfunctie berekend, waarna de gecombineerde toestand wordt + bepaald. In de implementatie is dit voor elk stijghoogtemodel één functie. Deze functie geeft als resultaat + alle grenstoestandsfuncties, ook de gecombineerde. + De grenstoestandsfuncties maken gebruik van de fysische componenten uit stap 1. + Elke implementatie van een stijghoogtemodel wordt aangeroepen via een eigen functie in de subpackage + ``geoprob_pipe.calculations`` (bijvoorbeeld ``limit_state_model4a`` of ``limit_state_moria``). + Deze functies combineren de fysische componenten en grenstoestandsfuncties tot één consistente berekening van + de faalkans per uittredepunt. + +3. **Stijghoogtemodellen** + Het stijghoogtemodel bepaalt de stijghoogte in het uittredepunt (:math:`\phi_{exit}`) en vormt daarmee de + koppeling tussen de hydraulische belasting (buitenwaterstand, polderpeil) en de ondergrondrespons. + `GeoProb-Pipe` ondersteunt meerdere typen stijghoogtemodellen: + - de WBI-formulering van de stijghoogte met een vaste responsfactor en kwelweglengte; + - het analytische grondwatermodel *4A* op doorsnedeiveau; + - resultaten van numerieke rastermodellen zoals *MORIA*; + - en toekomstige uitbreidingen (bijv. TTIM) die via dezelfde interface kunnen worden toegevoegd. diff --git a/docs/rekenmethodiek_oud.rst b/docs/rekenmethodiek_oud.rst new file mode 100644 index 00000000..596f02c0 --- /dev/null +++ b/docs/rekenmethodiek_oud.rst @@ -0,0 +1,505 @@ +.. _rekenmethodiek: + + +.. TODO: Ik vind deze pagina onduidelijk ingedeeld. Kunnen we het volgende voorstel bespreken? + Rekenmethodiek + Berekeningsmodel + Stijghoogtemodellen + standaard WBI model + Model 4a + Numeriek stijghoogtemodel + Modelfactoren + relatie met beslisraamwerk: welke factoren zijn er geimplementeerd? + Getijdezandfactor + 3D verschaling + Gebruikersgedefinieerde factoren + + + +.. contents:: + :local: + :depth: 3 + + +Rekenmethodiek +============== + +Deze pagina beschrijft de rekenmethodiek die `GeoProb-Pipe` gebruikt voor het berekenen van de totale faalkans op piping per uittredepunt. + +Implementatie +------------- + +De implementatie van de rekenmethodiek is modulair opgebouwd en bestaat uit drie samenhangende onderdelen: + +1. **Fysische componenten** + In deze stap worden de geohydrologische en geotechnische componenten berekend die de fysieke toestand van het systeem beschrijven, + zoals de deklaagdikte, heave-gradiënt, kwelweglengte en het kritieke verval volgens Sellmeijer. + Deze berekeningen zijn geïmplementeerd in het subpakket ``geoprob_pipe.calculations.physical_components.piping`` + De fysische componenten vormen de bouwstenen voor de grenstoestandsfuncties. + Ze zijn onafhankelijk van het gekozen stijghoogtemodel: ongeacht of de stijghoogte wordt bepaald met het analytische model 4A of een numeriek model worden dezelfde fysische componenten toegepast. + +2. **Grenstoestandsfuncties** + De grenstoestandfuncties beschrijven de drie deelmechanismen die leiden tot piping: + *opbarsten*, *heave* en *terugschrijdende erosie*. + Voor elk mechanisme wordt een aparte grenstoestandsfunctie berekend, waarna de gecombineerde toestand wordt bepaald. + In de implementatie is dit voor elk stijghoogtemodel één functie. Deze functie geeft als resultaat alle grenstoestandfuncties, ook de gecombineerde. + De grenstoestandsfuncties maken gebruik van de fysische componenten uit stap 1. + Elke implementatie van een stijghoogtemodel wordt aangeroepen via een eigen functie in het pakket ``geoprob_pipe.calculations`` (bijvoorbeeld ``limit_state_model4a`` of ``limit_state_moria``). + Deze functies combineren de fysische componenten en grenstoestandsfuncties tot één consistente berekening van de faalkans per uittredepunt. + +3. **Stijghoogtemodellen** + Het stijghoogtemodel bepaalt de stijghoogte in het uittredepunt (:math:`\phi_{exit}`) en vormt daarmee de koppeling tussen + de hydraulische belasting (buitenwaterstand, polderpeil) en de ondergrondrespons. + `GeoProb-Pipe` ondersteunt meerdere typen stijghoogtemodellen: + - de WBI-formulering van de stijghoogte met een vaste responsfactor en kwelweglengte; + - het analytische grondwatermodel *4A* op doorsnedeniveau; + - resultaten van numerieke rastermodellen zoals *MORIA*; + - en toekomstige uitbreidingen (bijv. TTIM) die via dezelfde interface kunnen worden toegevoegd. + + +Faalpad en foutenboom piping +---------------------------- + +In :numref:`faalpad-STPH` zie je een veelvoorkomend faalpad voor het faalmechanisme *piping* :cite:`HOVK_STPH_2024`. +`GeoProb-Pipe` richt zich op het modelleren van de initiële mechanismen die leiden tot piping: opbarsten, heave en terugschrijdende erosie. +Hierbij wordt aangenomen dat piping optreedt wanneer de deklaag opbarst, heave optreedt en er doorgaande terugschrijdende erosie plaatsvindt. +In de schematiseringshandleiding piping :cite:`sh_piping_2021` zijn de bijbehorende grenstoestandsfuncties beschreven die in het BOI en in `GeoProb-Pipe` worden gebruikt. + +.. _faalpad-STPH: + +.. figure:: _static/faalpad_piping.png + :alt: Veelvoorkomend faalpad voor het faalmechanisme piping. + :align: center + + Veelvoorkomend faalpad voor het faalmechanisme *piping* :cite:`HOVK_STPH_2024`. + +.. TODO: Foutenboom toevoegen als plaatje? + +Basis grenstoestandfuncties BOI +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +De onderstaande grenstoestandsfuncties vormen de kern van de berekening in `GeoProb-Pipe`. +Ze worden identiek toegepast in elk stijghoogtemodel (`limit_state_wbi`, `limit_state_model4a`, `limit_state_moria`). +De verschillen tussen de modellen zitten uitsluitend in de berekening van de stijghoogte :math:`\phi_{exit}` en bijbehorende parameters. + +Opbarsten +^^^^^^^^^ + +De grenstoestandfunctie van **opbarsten** :math:`Z_{u}` is in :cite:`sh_piping_2021` als volgt gedefinieerd: + +.. math:: + + Z_{u} = m_{u} \cdot \Delta \phi_{c,u} - (\phi_{exit} - h_{exit}) + +waarbij :math:`m_{u}` de modelfactor voor opbarsten is [-]. + +De grenspotentiaal ten opzichte van maaiveldniveau :math:`\Delta \phi_{c,u}` [m] wordt bepaald door het effectieve gewicht van de deklaag onder water: + +.. math:: + + \Delta \phi_{c,u} = \frac{d_{deklaag} \cdot (\gamma_{sat,deklaag} - \gamma_{w})}{\gamma_{w}} + +waarin: + +- :math:`d_{deklaag}` de dikte van de deklaag is [m] +- :math:`\gamma_{sat}` het gemiddeld verzadigd volumegewicht van de cohesieve deklaag is [kN/m³] +- :math:`\gamma_{w}` het volumegewicht van water is [kN/m³] + +De dikte van de deklaag :math:`d_{deklaag}` ter plaatse van het uittredepunt is gedefinieerd als de verticale afstand tussen het maaiveldniveau en de bovenkant van de pipinggevoelige zandlaag: + +.. math:: + + d_{deklaag} = mv_{exit} - top_{zandlaag} + +waarin: +- :math:`mv_{exit}` maaiveldniveau ter plaatse van het uittredepunt [m+NAP] +- :math:`top_{zandlaag}` niveau bovenkant van de pipinggevoelige zandlaag [m+NAP] + +De stijghoogte ter plaatse van het uittredepunt :math:`\phi_{exit}` [m+NAP] wordt volgens de schematiseringshandleiding :cite:`sh_piping_2021` beschreven door: + +.. math:: + + \phi_{exit} = \phi_{polder} + r_{exit} \cdot (h_{rivier} - \phi_{polder}) + +waarin: + +- :math:`\phi_{polder}` het waterniveau in de polder [m+NAP] +- :math:`r_{exit}` de dempingsfactor ter plaatse van het uittredepunt [-] +- :math:`h_{rivier}` het waterniveau in de rivier [m+NAP] + +De dempingsfactor :math:`r_{exit}` ter plaatse van het uittredepunt is afhankelijk van de locatie van het uittredepunt ten opzichte van de dijk en de geohydrologische situatie. De schematiseringshandleiding piping :cite:`sh_piping_2021` hanteert dit als een onafhankelijke invoerparameter. + +:math:`h_{exit}` is de randvoorwaarde in het uittredepunt, gedefinieerd door het maximum van het polderpeil en het maaiveldniveau ter plaatse van het uittredepunt: + +.. math:: + + h_{exit} = max(\phi_{polder}, mv_{exit}) + +waarin: + +- :math:`\phi_{polder}` het waterniveau in de polder [m+NAP] + + +Heave +^^^^^ + +De grenstoestandfunctie van **heave** :math:`Z_{h}` is in :cite:`sh_piping_2021` als volgt gedefinieerd: + +.. math:: + + Z_{h} = m_{h} \cdot i_{i,c} - \frac{\phi_{exit} - h_{exit}}{d_{deklaag}} + +waarin: + +- :math:`m_{h}` de modelfactor voor heave is [-] +- :math:`i_{i,c}` de kritieke heave-gradiënt is [-] + +Opgemerkt wordt dat de modelfactoren :math:`m_{u}` en :math:`m_{h}` niet zijn opgenomen in de formules van de schematiseringshandleiding piping :cite:`sh_piping_2021`, maar wel in deze implementatie zijn opgenomen om de modelonzekerheid expliciet te kunnen kwantificeren. + + +Terugschrijdende erosie +^^^^^^^^^^^^^^^^^^^^^^^^ + +De grenstoestandfunctie van **terugschrijdende erosie** :math:`Z_{p}` is in :cite:`sh_piping_2021` als volgt gedefinieerd: + +.. math:: + + Z_{p} = m_{p} \cdot \Delta H_{c} - \Delta h_{red} + +met :math:`\Delta h_{red}` het gereduceerde verval over de deklaag [m] als: + +.. math:: + + \Delta h_{red} = h_{buitenwaterstand} - h_{exit} - r_{c,deklaag} \cdot d_{deklaag} + +waarin: + +- :math:`m_{p}` de modelfactor voor terugschrijdende erosie is [-] +- :math:`\Delta H_{c}` het kritieke verval over de deklaag is [m] +- :math:`h_{buitenwaterstand}` de buitenwaterstand is [m+NAP] +- :math:`h_{exit}` de randvoorwaarde in het uittredepunt is [m+NAP] +- :math:`r_{c,deklaag}` de reductieconstante van het verval over de deklaag is [-] +- :math:`d_{deklaag}` de dikte van de deklaag is [m] + + Het kritieke verval over de deklaag :math:`\Delta H_{c}` is gebaseerd op het in 2011 aangepaste model van Sellmeijer. + + .. math:: + + \Delta H_{c} = L_{kwelweg} \cdot F_{resistance} \cdot F_{scale} \cdot F_{geometry} + +met: + +.. math:: + + F_{resistance} = \eta \frac{\gamma_{korrel} - \gamma_{w}}{\gamma_{w}} \cdot tan(\theta) + + F_{scale} = \frac{d_{70,m}}{\sqrt[3]{L_{kwelweg} \cdot \frac{k \cdot \upsilon_{w}}{g}}} \left(\frac{d_{70}}{d_{70,m}} \right)^{0.4} + + F_{geometry} = 0.91 \left(\frac{D_{wvp}}{L_{kwelweg}} \right)^{\frac{0.28}{\left(\frac{D_{wvp}}{L_{kwelweg}} \right)^{2.8} - 1} + 0.04} + + +waarin: + +- :math:`L_{kwelweg}` de kwelweglengte is [m], gedefinieerd als de horizontale afstand tussen het uittredepunt en een onzeker intredepunt. +- :math:`\eta` coëfficiënt van White (sleepkrachtfactor) [-]. Standaardwaarde is 0.25 +- :math:`\gamma_{korrel}` volumieke dichtheid van zand [kN/m³]. Standaardwaarde is 26.0 kN/m³ +- :math:`\gamma_{w}` het volumegewicht van water [kN/m³] +- :math:`\theta` de rolweerstandshoek van zandkorrels van de aangepaste Sellmeijer-rekenregel [°]. Standaardwaarde is 37° +- :math:`d_{70,m}` de referentie- :math:`d_{70}`-waarde [m]. Standaardwaarde is 2.08E-4 m +- :math:`d_{70}` de 70-percentielwaarde van de korrelverdeling van de pipinggevoelige laag [m] +- :math:`k` de Darcy-doorlatendheid van de zandlaag [m/s] +- :math:`\upsilon_{w}` de kinematische viscositeit van water [m²/s]. Standaardwaarde is 1.33E-6 m²/s bij 10°C +- :math:`g` de zwaartekrachtversnelling [m/s²]. Standaardwaarde is 9.81 m/s² +- :math:`D_{wvp}` de dikte van de watervoerende zandlaag [m] + +.. _stijghoogtemodellen-geoprob: + +Stijghoogtemodellen in GeoProb-Pipe +----------------------------------- + +De berekening van de stijghoogte :math:`\phi_{exit}` wordt uitgevoerd binnen de limit-state functies, +waarbij elke functie een specifiek type stijghoogtemodel aanroept: + +- ``limit_state_wbi`` – eenvoudige benadering met vaste responsfactor; +- ``limit_state_model4a`` – analytisch grondwatermodel 4A (doorsnede); +- ``limit_state_moria`` – numeriek rastermodel (zoals het regionale grondwatermodel MORIA). + +De rekenmethodiek is zodanig opgezet dat in de toekomst ook andere stijghoogtemodellen kunnen worden toegevoegd. + +.. _model4a: + +Analytische stijghoogtemodel 4A +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Het analytische grondwatermodel *4A* vormt één van de mogelijke implementaties van het stijghoogtemodel +(*stap 3* van de rekenmethodiek). +Dit model beschrijft de stroming van grondwater door de zandlaag onder een dijk op basis van stationaire, +lineaire stroming in doorsnedeniveau. +De overige fysische componenten en grenstoestandsfuncties worden op identieke wijze berekend als bij andere +stijghoogtemodellen; alleen de bepaling van de stijghoogte :math:`\phi_{exit}` en de responsfactor :math:`r_{exit}` +verschilt. + +De grondwaterstroming vormt de drijvende kracht achter het proces van terugschrijdende erosie. +Door het analytische grondwatermodel 4A van :cite:`trw_2004` toe te passen, +kan de respons :math:`r_{exit}` in het uittredepunt worden beschreven als functie van de locatie in het +dwarspofiel :math:`x_{exit}` [m] en de geohydrologische parameters van model 4A. +Een uitgebreide toelichting op de onderliggende theorie van dit model is te vinden in :ref:`stationair-model`. + +De respons in het uittredepunt wordt bepaald met: +.. math:: + + r_{exit}(x) = f(x_{exit}, L_1, L_2, L_3, c_{voorland}, c_{achterland}, k, D_{wvp}) + +Geometrische parameters +^^^^^^^^^^^^^^^^^^^^^^^ +Geometrische parameters :math:`L_1` en :math:`L_2` zijn omgeschreven naar afstanden ten opzichte van het uittredepunt: + +.. math:: + + L_1 = L_{intrede} - L_{but} + + L_2 = L_{but} - L_{bit} + +waarin: + +- :math:`L_{intrede}` de afstand van het uittredepunt tot een geometrische intredelijn [m] +- :math:`L_{but}` de afstand van het uittredepunt tot de buitenteen [m] +- :math:`L_{bit}` de afstand van het uittredepunt tot de binnenteen [m] +- :math:`L_3` de achterlandlengte [m] +- :math:`x_{exit}` de afstand van het uittredepunt tot de binnenteen [m]. De aanname is dat uittredepunten altijd binnendijks van een (denkbeeldige) binnenteen liggen. +- :math:`c_{voorland}` de weerstand van de deklaag in het voorland [dag] +- :math:`c_{achterland}` de weerstand van de deklaag in het achterland [dag] + + +Effectieve voorlandlengte +^^^^^^^^^^^^^^^^^^^^^^^^^ +De kwelweglengte :math:`L_{kwelweg}` maakt conform de schematiseringshandleiding piping :cite:`sh_piping_2021` gebruik van het principe van de effectieve voorlandlengte. + +.. math:: + + L_{kwelweg} = L_{but} + L_{eff,voorland} + + L_{eff,voorland} = \lambda_{1} \cdot tanh(\frac{L_1}{\lambda_{1}}) + + \lambda_{1} = \sqrt{c_{voorland} \cdot k \cdot D_{wvp}} + +waarin: + +- :math:`L_{eff,voorland}` de effectieve voorlandlengte is [m] +- :math:`\lambda_{1}` de spreidingslengte van het voorland is [m] +- :math:`\c` is de deklaagdikte gedeeld door de doorlatendheid van de deklaag [dag] + +Overzicht parameters model 4A +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Het berekeningsmodel met het analytische grondwatermodel 4A kent de volgende invoerparameters: + +.. list-table:: Invoerparameters berekeningsmodel met model 4A + :widths: 20 60 20 + :header-rows: 1 + + * - Variable + - Omschrijving + - Verdeling/Constante + * - :math:`h_{buitenwaterstand}` + - Buitenwaterstand [m+NAP] + - CDF + * - :math:`\phi_{polder}` + - Waterniveau in de polder [m+NAP] + - deterministisch + * - :math:`mv_{exit}` + - Maaiveldniveau ter plaatse van uittredepunt [m+NAP] + - deterministisch + * - :math:`r_{c,deklaag}` + - Reductieconstante van het verval over de deklaag [-] + - lognormaal + * - :math:`L_{bit}` + - Afstand van het uittredepunt tot de binnenteen [m] + - deterministisch + * - :math:`L_{but}` + - Afstand van het uittredepunt tot de buitenteen [m] + - deterministisch + * - :math:`L_{intrede}` + - Afstand van het uittredepunt tot geometrische intredelijn [m] + - deterministisch + * - :math:`L_{3}` + - Achterlandlengte [m] + - deterministisch + * - :math:`top_{zandlaag}` + - niveau bovenkant van de pipinggevoelige zandlaag [m+NAP] + - normaal + * - :math:`c_{voorland}` + - Weerstand van de deklaag in het voorland [dag] + - lognormaal + * - :math:`c_{achterland}` + - Weerstand van de deklaag in het achterland [dag] + - lognormaal + * - :math:`D_{wvp}` + - Dikte van de watervoerende zandlaag [m] + - lognormaal + * - :math:`kD_{wvp}` + - Transmissiviteit van het watervoerende pakket [m²/dag] + - lognormaal + * - :math:`d_{70}` + - 70-percentielwaarde van de korrelverdeling van de pipinggevoelige laag [m] + - lognormaal + * - :math:`\gamma_{sat,deklaag}` + - Gemiddeld verzadigd volumegewicht deklaag [kN/m³] + - lognormaal, shift = 10.0 + * - :math:`i_{i,c}` + - Kritieke heave gradiënt [-] + - lognormaal + * - :math:`d_{70,m}` + - Referentiewaarde voor de :math:`d_{70}` [m] + - 2.08E-4 m + * - :math:`\upsilon_{w}` + - Kinematische viscositeit van water [m²/s] + - 1.33E-6 m²/s bij 10°C + * - :math:`\eta` + - Coëfficiënt van White (sleepkrachtfactor) [-] + - 0.25 + * - :math:`\theta` + - Rolweerstandshoek van zandkorrels van de aangepaste Sellmeijer rekenregel [°] + - 37° + * - :math:`g` + - Zwaartekrachtversnelling [m/s²] + - 9.81 m/s² + * - :math:`\gamma_{korrel}` + - Volumieke dichtheid zand [kN/m³] + - 26.0 kN/m³ + * - :math:`\gamma_{w}` + - Volumegewicht van water [kN/m³] + - 9.81 kN/m³ + * - :math:`m_{u}` + - Modelfactor opbarsten [-] + - normaal + * - :math:`m_{h}` + - Modelfactor heave [-] + - normaal + * - :math:`m_{p}` + - Modelfactor terugschrijdende erosie [-] + - normaal + +Numerieke stijghoogtemodellen +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Het numerieke stijghoogtemodel vormt een tweede implementatie van het stijghoogtemodel (*stap 3* van de rekenmethodiek). +In dit geval wordt de stijghoogte :math:`\phi_{exit}` niet analytisch berekend, maar afgeleid uit een numeriek grondwatermodel +dat de ruimtelijke variatie in stijghoogten expliciet beschrijft. +De overige fysische componenten en grenstoestandsfuncties worden op identieke wijze berekend als bij het analytische model 4A; +alleen de bepaling van de stijghoogte, responsfactor en kwelweglengte verschilt. + +Een numeriek stijghoogtemodel, zoals het regionale grondwatermodel MORIA van Waterschap Rivierenland, +levert informatie in de vorm van raster-bestanden. +Per uittredepunt kunnen hieruit de relevante geohydrologische parameters worden afgeleid. +De volgende variabelen worden uit het grid gelezen: + +- :math:`\phi_{gemiddeld}(x,y)` een grid met het gemiddelde grondwaterstandniveau bij gemiddelde rivierwaterstand [m+NAP] +- :math:`h_{gemiddeld}` de gemiddelde rivierwaterstand nabij het uittredepunt [m+NAP] +- :math:`r_{exit}(x,y)` een grid met de respons in het uittredepunt [-] +- :math:`\lambda_{1}` de spreidingslengte van het voorland [m] + +De stijghoogte in het uittredepunt wordt vervolgens bepaald met: + +.. math:: + + \phi_{exit}(x,y) = \phi_{gemiddeld}(x,y) + r_{exit}(x,y) \cdot (h_{buitenwaterstand} - h_{gemiddeld}) + + L_{eff,voorland} = \lambda_{1} \cdot tanh(\frac{L_1}{\lambda_{1}}) + + L_{kwelweg} = L_{but} + L_{eff,voorland} + +Bespreken: moeten we nog een modelfactor :math:`m_{gw}` voor het stijghoogtemodel toevoegen. + +Grenstoestandfuncties numeriek stijghoogtemodel +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +De formules van de grenstoestandsfuncties zijn nu als volgt: + +Grenstoestandfunctie opbarsten: + +.. math:: + + Z_{u} = m_{u} \cdot \Delta \phi_{c,u} - (\phi_{exit}(x,y) - h_{exit}) + +Grenstoestandfunctie heave: + +.. math:: + + Z_{h} = m_{h} \cdot i_{i,c} - \frac{\phi_{exit}(x,y) - h_{exit}}{d_{deklaag}} + +Grenstoestandfunctie terugschrijdende erosie: + +.. math:: + + Z_{p} = m_{p} \cdot \Delta H_{c} - \Delta h_{red} + + \Delta h_{red} = h_{buitenwaterstand} - h_{exit} - r_{c,deklaag} \cdot d_{deklaag} + + L_{kwelweg} = L_{but} + L_{eff,voorland} + + L_{eff,voorland} = \lambda_{1} \cdot tanh(\frac{L_1}{\lambda_{1}}) + + \lambda_{1} = \sqrt{c_{voorland} \cdot k \cdot D_{wvp}} + + +Correlatie tussen variabelen +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +De beschrijving van het geohydrologische systeem met de variabelen betekent ook dat de onderlinge correlatie van de variabelen apart moet worden gedefinieerd. Dit betreft met name de correlatie tussen de spreidingslengte van het voorland :math:`\lambda_{1}` en de transmissiviteit van het watervoerende zandpakket :math:`kD` en in mindere mate de correlatie tussen de respons in het uittredepunt :math:`r_{exit}` en de transmissiviteit van het watervoerende zandpakket :math:`kD`. In het model 4A zijn deze correlaties modelmatig beschreven. + +In het geval van een numeriek stijghoogtemodel is de correlatie tussen de spreidingslengte van het voorland en de transmissiviteit van het watervoerende zandpakket plaatsafhankelijk en wordt beschreven door het geohydrologische model. + +Om een inschatting te doen van de correlatie tussen deze variabelen wordt een beperkte set van modelberekeningen uitgevoerd waarbij de transmissiviteit van het watervoerende pakket en de weerstand van het voorland wordt gevarieerd. +Voor elke berekening uit deze set wordt de spreidingslengte van het voorland afgeleid. +Gebruikelijk is het om daarbij per variabele 3 scenario's te hanteren (gemiddeld, -1.64 * sigma, +1.64 * sigma). +Voor 2 variabelen resulteert dit in 9 modelberekeningen. + +Uit deze modelberekeningen wordt de gewogen correlatie tussen de transmissiviteit van het watervoerende pakket en de spreidingslengte van het voorland bepaald. Deze correlatie wordt vervolgens gebruikt in de probabilistische analyse. + +Op basis van het model 4A is de correlatie tussen de transmissiviteit van het watervoerende pakket en de spreidingslengte van het voorland ongeveer 0.7, afhankelijk van de gekozen spreiding. +.. TODO: Ik vind deze nog lastig te plaatsen. @skapinga kun jij kijken hoe we deze binnen de structuur een betere plek kunnen geven? + +Overzicht van implementaties in de code +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. TODO: uiteindelijke implementatie controleren en tekst hierop aanpassen. +.. TODO: misschien de theorie (beschrijving grenstoestandsfuncties) en de implementatie (overzicht functies) beter scheiden? + +In onderstaande tabel zijn de huidige implementaties van de stijghoogtemodellen binnen `GeoProb-Pipe` samengevat. +Elke implementatie volgt dezelfde structuur: eerst worden de fysische componenten berekend, +vervolgens de grenstoestandsfuncties, en tenslotte de gecombineerde limiettoestand. + +.. list-table:: Overzicht van limit-state implementaties + :widths: 20 25 35 20 + :header-rows: 1 + + * - Functie + - Beschrijving + - Belangrijkste invoerparameters + - Belangrijkste uitvoerwaarden + + * - ``limit_state_wbi`` + - Basismodel volgens WBI-formulering (met vaste responsfactor). + Wordt gebruikt voor situaties zonder expliciet stijghoogtemodel. + - :math:`L_{kwelweg}`, :math:`h_{buiten}`, :math:`\phi_{polder}`, :math:`r_{exit}`, :math:`d_{70}`, :math:`D_{wvp}`, :math:`\gamma_{sat,deklaag}` + - :math:`Z_u`, :math:`Z_h`, :math:`Z_p`, :math:`Z_{combin}`, :math:`\phi_{exit}`, :math:`h_{exit}` + + * - ``limit_state_model4a`` + - Implementatie van het analytische grondwatermodel 4A (:cite:`trw_2004`). + Berekening van respons :math:`r_{exit}` op basis van doorsnedemodel. + - :math:`L_{intrede}`, :math:`L_{but}`, :math:`L_{bit}`, :math:`c_{voorland}`, :math:`c_{achterland}`, :math:`kD_{wvp}`, :math:`D_{wvp}` + - :math:`Z_u`, :math:`Z_h`, :math:`Z_p`, :math:`Z_{combin}`, :math:`\phi_{exit}`, :math:`r_{exit}`, :math:`L_{kwelweg}` + + * - ``limit_state_moria`` + - Implementatie van een numeriek grondwatermodel (zoals MORIA). + Gebruikt rasterinformatie voor de bepaling van :math:`\phi_{exit}` en :math:`r_{exit}`. + - :math:`\phi_{gemiddeld}(x,y)`, :math:`h_{gemiddeld}`, :math:`r_{exit}(x,y)`, :math:`\lambda_{1}`, :math:`L_{but}` + - :math:`Z_u`, :math:`Z_h`, :math:`Z_p`, :math:`Z_{combin}`, :math:`\phi_{exit}`, :math:`r_{exit}`, :math:`L_{kwelweg}` + + * - ``limit_state_ttim`` *(conceptueel voorbeeld)* + - Interface voor toekomstige uitbreiding met een tijdsafhankelijk grondwatermodel (TTIM). + Input- en outputstructuur is identiek aan de bestaande modellen. + - :math:`\phi_{exit}`, :math:`r_{exit}`, :math:`L_{kwelweg}`, :math:`\lambda_{1}` + - :math:`Z_u`, :math:`Z_h`, :math:`Z_p`, :math:`Z_{combin}` + +Alle functies bevinden zich in het pakket ``geoprob_pipe.calculations`` en maken gebruik van de onderliggende +fysische berekeningen uit ``geoprob_pipe.calculations.physical_components.piping``. +Door deze eenduidige structuur kan elk modeltype afzonderlijk worden aangeroepen in de probabilistische analyse, +zonder dat de onderliggende rekenlogica hoeft te worden aangepast. \ No newline at end of file diff --git a/docs/rekenmethodiek_oud2.rst b/docs/rekenmethodiek_oud2.rst new file mode 100644 index 00000000..141ea11c --- /dev/null +++ b/docs/rekenmethodiek_oud2.rst @@ -0,0 +1,27 @@ +.. _rekenmethodiek: + + +.. TODO: Ik vind deze pagina onduidelijk ingedeeld. Kunnen we het volgende voorstel bespreken? + Rekenmethodiek + Berekeningsmodel + Stijghoogtemodellen + standaard WBI model + Model 4a + Numeriek stijghoogtemodel + Modelfactoren + relatie met beslisraamwerk: welke factoren zijn er geimplementeerd? + Getijdezandfactor + 3D verschaling + Gebruikersgedefinieerde factoren + + + +.. contents:: + :local: + :depth: 3 + + + + + + diff --git a/docs/uittredepuntenmethode.rst b/docs/uittredepuntenmethode.rst new file mode 100644 index 00000000..2107a4af --- /dev/null +++ b/docs/uittredepuntenmethode.rst @@ -0,0 +1,25 @@ +Uittredepuntenmethode +===================== + +Wat is de uittredepuntenmethode? +-------------------------------- + +Conform de handleiding overstromingskansanalyse :cite:t:`HOVK_STPH_2024` en de eerdere schematiseringshandleidingen :cite:t:`sh_piping_2021` wordt een dijktraject opgedeeld in dijkvakken. Per dijkvak is de veronderstelling dat er sprake is van (statistische) homogeniteit. Dit betekent dat alle uitgangspunten uitgangspunten min of meer gelijk zijn over het dijkvak. +Per dijkvak wordt gewoonlijk één doorsnede gekozen die representatief is voor het dijkvak. +Op voorhand is echter niet bekend waar de zwakste plek in het dijkvak zich bevindt. De uittredepuntenmethode probeert dit probleem op te lossen door binnen een dijkvak meerdere mogelijke uittredepunten te definiëren. Deze uittredepunten kan je zien als doorsneden. Met deze methode kan relatief gemakkelijk veel uittredepunten (doorsneden) doorgerekend worden. Door een veelvoud aan berekende uittredepunten ontstaat een gebiedsdekkend beeld van het risico op piping. + +De uitkomst van de (probabilistische) som bepaalt welk uittredepunt de grootste bijdrage heeft aan de faalkans van het dijkvak. + +Hoe werkt de uittredepuntenmethode? +----------------------------------- + +De rekenmethodiek volgt de schematiseringshandleiding :cite:t:`sh_piping_2021` en de handleiding overstromingskansanalyse :cite:t:`HOVK_STPH_2024`, echter met een aantal belangrijke aanvullingen: + +* Per dijkvak worden meerdere uittredepunten gedefinieerd. Deze uittredepunten worden zodanig gekozen dat ze een goede dekking geven van het dijkvak. +* Elk uittredepunt kent zijn eigen (unieke) combinatie van uitgangspunten. Geometrische uitgangspunten zoals maaiveldniveau, aftstand tot de buitenteen en belastingen worden gekoppeld aan de locatie van het uittredepunt. +* Eigenschappen van de ondergrond worden, afhankelijk van de beschikbare data, op verschillende manieren gekoppeld aan de uittredepunten. Dit kan zijn door uitgangspunten op vakniveau te definiëren, of door gebruik van grids. +* Het combineren van de verschillende uitgangspunten heeft tot doel om een passende schematisatie per uittredepunt te maken. + + + +Meer informatie over de rekenmethodiek is te vinden in de :ref:`Rekenmethodiek `. \ No newline at end of file diff --git a/environment.yml b/environment.yml deleted file mode 100644 index 6cf6160b..00000000 --- a/environment.yml +++ /dev/null @@ -1,19 +0,0 @@ -name: GeoProb-Pipe -channels: - - conda-forge -dependencies: - - python=3.12.5 - - geopandas>=1.0.1,<1.1 - - matplotlib>=3.10.1,<3.11 - - openpyxl>=3.1.5,<3.2 - - scipy>=1.14.1,<1.15 - - openpyxl>=3.1.5 - - matplotlib~=3.10.1 - - numpy>=2.2.4 - - pytest>=8.3.5 - - sphinx>=8.2.3 - - sphinxcontrib-bibtex>=2.6.3 - - pip - - pip: - - ./wheels/probabilistic_library-25.1.1-py3-none-any.whl - - pydra-core>=0.0.9 \ No newline at end of file diff --git a/geoprob_pipe/__init__.py b/geoprob_pipe/__init__.py new file mode 100644 index 00000000..580a9f5d --- /dev/null +++ b/geoprob_pipe/__init__.py @@ -0,0 +1,4 @@ +from geoprob_pipe.app_object import GeoProbPipe +from geoprob_pipe.calculations.systems.base_objects.system_calculation import ( + SystemCalculation) +from geoprob_pipe.calculations.systems.single_calc import reproduce_single_calculation \ No newline at end of file diff --git a/geoprob_pipe/__main__.py b/geoprob_pipe/__main__.py new file mode 100644 index 00000000..fc8c844c --- /dev/null +++ b/geoprob_pipe/__main__.py @@ -0,0 +1,4 @@ +from geoprob_pipe.cmd_app.cmd import startup_geoprob_pipe + +if __name__ == "__main__": + startup_geoprob_pipe() diff --git a/geoprob_pipe/app_object.py b/geoprob_pipe/app_object.py new file mode 100644 index 00000000..9dc5c41f --- /dev/null +++ b/geoprob_pipe/app_object.py @@ -0,0 +1,94 @@ +from __future__ import annotations +import os +from datetime import datetime +from typing import TYPE_CHECKING, Optional, List +import pandas as pd + +try: + import probabilistic_library +except ModuleNotFoundError: + raise ModuleNotFoundError( + "No module named 'probabilistic_library'. This package is not publicly available or part of the repository. \n" + "Please request the wheel-file through the developer and install it manually. Due to copyright reasons, do \n" + "not commit the wheel-file into the repository.") + +# noinspection PyPep8Naming +from geoprob_pipe.utils.loggers import TmpAppConsoleHandler as logger +from geoprob_pipe.input_data import InputData +from geoprob_pipe.results import Results +from geoprob_pipe.spatial import Spatial +from geoprob_pipe.visualizations import Visualizations +from geoprob_pipe.calculations.systems.build_and_run import build_and_run_system_calculations +from geoprob_pipe.utils.update_metadata import update_metadata + +if TYPE_CHECKING: + from geoprob_pipe.calculations.systems.build_and_run import CalcResult + from geoprob_pipe.cmd_app.cmd import ApplicationSettings + + +class GeoProbPipe: + """ GeoProb-Pipe application object. """ + # TODO Later Could Groot: Gebruiker optie geven OpenTurns of Prob-library te kiezen? Dus engine keuze. + + def __init__(self, app_settings: ApplicationSettings) -> None: + + # Miscellaneous + import warnings + warnings.simplefilter( + action='ignore', + category=FutureWarning) # Preferably address FutureWarnings: part of pydra-core + + logger.info("Initiating project.") + self.time_start = datetime.now() + + self.input_data = InputData(app_settings=app_settings) # TODO: Alter with new option + + # Read calculation settings + # self._read_calculation_settings() # TODO: Not part of new version + # TODO: Unsure if the single statement belongs here. Wouldn't it be part of input data? + + self.calc_results: List[CalcResult] = build_and_run_system_calculations(self) + self.results = Results(self) + + # Log finish + self.time_end = datetime.now() + self.time_diff = self.time_end - self.time_start + logger.info(f"Calculations were performed successfully in {int(self.time_diff.total_seconds())} seconds.") + + + + # Append logic classes + self.visualizations = Visualizations(self) + self.spatial = Spatial(self) + + # def _read_calculation_settings(self): # TODO: Not (yet) part of new version + # """ Read calculation settings from Excel file. """ + # self.df_settings = read_excel(self.workspace.path_input_excel, sheet_name="Settings", index_col=0, header=0) + # logger.info(f"Settings successfully loaded from `{self.workspace.path_input_excel.name}`.") + # time.sleep(1) # Some time to make sure the print below, is printed after the logger print. + + def _export_validation_messages(self): + # Gather validation messages from calculations + df_val: Optional[pd.DataFrame] = None + [result.validation_message.concat_with_df(df_to_append_to=df_val) for result in self.calc_results + if result.validation_message is not None] + + # Export dataframe with validation messages + if df_val is not None: + export_path = os.path.join(self.input_data.app_settings.workspace_dir, "validation_messages.xlsx") + df_val.to_excel(export_path) + + def export_archive(self): + """ Exports everything related to this project. """ + logger.info("Now exporting archive...") + self.results.export_results() + self.visualizations.export_visualizations() + self.spatial.export_geopackage() + # add run metadata to geopackage + update_metadata(self) + self._export_validation_messages() + + path: str = os.path.join( + str(self.input_data.app_settings.workspace_dir), "exports", + str(self.input_data.app_settings.datetime_stamp)) + print(f"Exported archive to {path}") diff --git a/app/__init__.py b/geoprob_pipe/calculations/__init__.py similarity index 100% rename from app/__init__.py rename to geoprob_pipe/calculations/__init__.py diff --git a/geoprob_pipe/calculations/limit_states/__init__.py b/geoprob_pipe/calculations/limit_states/__init__.py new file mode 100644 index 00000000..58531252 --- /dev/null +++ b/geoprob_pipe/calculations/limit_states/__init__.py @@ -0,0 +1,7 @@ +""" +In deze `limit_states` subpackage worden alle grenstoestandsfuncties +opgebouwd. Deze worden als probabilistisch model toegevoegd aan de system +design points en individuele design point berekeningen onder de subpackage +`system_calculations`. De grenstoestandsfuncties zijn weer opgebouwd uit +fysieke sub-functies die in de subpackage `physical_components` staan. +""" diff --git a/geoprob_pipe/calculations/limit_states/piping_lm.py b/geoprob_pipe/calculations/limit_states/piping_lm.py new file mode 100644 index 00000000..f9ff2935 --- /dev/null +++ b/geoprob_pipe/calculations/limit_states/piping_lm.py @@ -0,0 +1,269 @@ +"""Alternatieve implementatie van de grenstoestandsfuncties voor het +WBI-model, model 4a en MORIA. Alle grenstoestandsfuncties worden +gecombineerd in één functie per model. De fysische componenten worden +geïmporteerd vanuit de subpackage `physical_components.piping`. Deze +implementatie is bedoeld om de leesbaarheid en onderhoudbaarheid van +de code te verbeteren.""" + +from typing import Tuple + +import geoprob_pipe.calculations.physical_components.piping as pc_piping + + +# noinspection PyPep8Naming +def limit_state_wbi( + # Geometry parameters + L_kwelweg: float, + # Boundary condition parameters + buitenwaterstand: float, polderpeil: float, mv_exit: float, + # Subsoil property parameters + top_zand: float, r_exit: float, k_wvp: float, D_wvp: float, d70: float, + gamma_sat_deklaag: float, + # Model property parameters + modelfactor_u: float, modelfactor_h: float, modelfactor_p: float, + modelfactor_ff: float, modelfactor_3d: float, modelfactor_aniso: float, + modelfactor_ml: float, i_c_h: float, r_c_deklaag: float, + # Overige parameters + gamma_water: float, + # Constants # TODO: Ombouwen tot globals + d70_m: float, gamma_korrel: float, v: float, theta: float, eta: float, g: float, +) -> Tuple[float, ...]: + """Grenstoestandsfuncties volgens het standaard WBI-model. + + :param L_kwelweg: + :param buitenwaterstand: + :param polderpeil: + :param mv_exit: + :param top_zand: + :param r_exit: + :param k_wvp: + :param D_wvp: + :param d70: + :param gamma_sat_deklaag: + :param gamma_water: + :param modelfactor_u: + :param modelfactor_h: + :param modelfactor_p: + :param modelfactor_ff: Model factor fijne fractie + :param modelfactor_3d: Model factor 3D effecten + :param modelfactor_aniso: Model factor anisotropie + :param modelfactor_ml: Model factor meerlaagsheid zandpakket + :param i_c_h: + :param r_c_deklaag: + :param d70_m: + :param gamma_korrel: + :param v: + :param theta: + :param eta: + :param g: + :return: + """ + d_deklaag = pc_piping.calc_d_deklaag(mv_exit=mv_exit, top_zand=top_zand) + phi_exit = pc_piping.calc_phi_exit( + polderpeil=polderpeil, r_exit=r_exit, + buitenwaterstand=buitenwaterstand) + h_exit = pc_piping.calc_h_exit(polderpeil=polderpeil, mv_exit=mv_exit) + dphi_c_u = pc_piping.calc_dphi_c_u( + d_deklaag=d_deklaag, gamma_sat_deklaag=gamma_sat_deklaag, + gamma_water=gamma_water) + i_exit = pc_piping.calc_i_exit( + phi_exit=phi_exit, h_exit=h_exit, d_deklaag=d_deklaag) + dh_c = pc_piping.calc_dh_c( + d70=d70, D_wvp=D_wvp, kD_wvp=k_wvp * D_wvp, L_kwelweg=L_kwelweg, + gamma_water=gamma_water, g=g, v=v, theta=theta, eta=eta, d70_m=d70_m, + gamma_korrel=gamma_korrel) + dh_red = pc_piping.calc_dh_red( + buitenwaterstand=buitenwaterstand, h_exit=h_exit, + r_c_deklaag=r_c_deklaag, d_deklaag=d_deklaag) + z_u = modelfactor_u * dphi_c_u - (phi_exit - h_exit) + z_h = (modelfactor_h * i_c_h) - i_exit + z_p = (modelfactor_p * modelfactor_ff * modelfactor_3d * modelfactor_aniso * modelfactor_ml * dh_c) - dh_red + z_combin = max(z_u, z_h, z_p) + return (z_u, z_h, z_p, z_combin, h_exit, phi_exit, dphi_c_u, i_exit, + dh_c, dh_red) + + +# Define the input variables for the model4 limit state +# The variables are grouped into categories for clarity +# --geometry-- +# L_intrede: float +# L_but: float +# L_bit: float +# L_achterland: float +# --Boundary conditions-- +# buitenwaterstand: float +# polderpeil: float +# mv_exit: float +# --subsoil properties-- +# top_zand: float +# kD_wvp: float +# D_wvp: float +# d70: float +# gamma_sat_deklaag: float +# c_voorland: float +# c_achterland: float +# --model properties-- +# modelfactor_u: float +# modelfactor_h: float +# modelfactor_p: float +# modelfactor_ff: float model factor fijne fractie +# modelfactor_3d: float model factor 3D effecten +# modelfactor_aniso: float model factor anisotropie +# modelfactor_ml: float model factor meerlaagsheid zandpakket +# i_c_h: float +# r_c_deklaag: float +# d70_m: float +# gamma_korrel: float +# v: float +# theta: float +# eta: float +# --constants-- +# g: float +# gamma_water: float + + +# noinspection PyPep8Naming +def limit_state_model4a( + L_intrede: float, L_but: float, L_bit: float, L_achterland: float, + buitenwaterstand: float, polderpeil: float, mv_exit: float, + top_zand: float, kD_wvp: float, D_wvp: float, d70: float, + gamma_sat_deklaag: float, c_voorland: float, c_achterland: float, + modelfactor_u: float, modelfactor_h: float, modelfactor_p: float, + modelfactor_ff: float, modelfactor_3d: float, modelfactor_aniso: float, + modelfactor_ml: float, i_c_h: float, r_c_deklaag: float, d70_m: float, + gamma_korrel: float, v: float, theta: float, eta: float, g: float, + gamma_water: float, + ) -> Tuple[float, ...]: + """Grenstoestandsfuncties volgens het WBI-model met grondwaterstroming + conform model 4a. + """ + L_voorland = pc_piping.calc_lengte_voorland(L_intrede=L_intrede, + L_but=L_but) + lambda_voorland = pc_piping.calc_lambda_voorland(kD_wvp=kD_wvp, + c_voorland=c_voorland) + W_voorland = pc_piping.calc_W_voorland(lambda_voorland=lambda_voorland, + L_voorland=L_voorland) + L_kwelweg = pc_piping.calc_L_kwelweg(L_but=L_but, W_voorland=W_voorland) + h_exit = pc_piping.calc_h_exit(polderpeil=polderpeil, mv_exit=mv_exit) + r_exit = pc_piping.calc_r_exit_model4a( + kD_wvp=kD_wvp, D_wvp=D_wvp, c_voorland=c_voorland, + c_achterland=c_achterland, L_but=L_but, L_bit=L_bit, + L_achterland=L_achterland, L_voorland=L_voorland) + d_deklaag = pc_piping.calc_d_deklaag(mv_exit=mv_exit, top_zand=top_zand) + phi_exit = pc_piping.calc_phi_exit(polderpeil=polderpeil, r_exit=r_exit, + buitenwaterstand=buitenwaterstand) + dphi_c_u = pc_piping.calc_dphi_c_u( + d_deklaag=d_deklaag, gamma_sat_deklaag=gamma_sat_deklaag, + gamma_water=gamma_water) + i_exit = pc_piping.calc_i_exit(phi_exit=phi_exit, h_exit=h_exit, + d_deklaag=d_deklaag) + dh_c = pc_piping.calc_dh_c( + d70=d70, D_wvp=D_wvp, kD_wvp=kD_wvp, L_kwelweg=L_kwelweg, + gamma_water=gamma_water, g=g, v=v, theta=theta, + eta=eta, d70_m=d70_m, gamma_korrel=gamma_korrel) + dh_red = pc_piping.calc_dh_red( + buitenwaterstand=buitenwaterstand, h_exit=h_exit, + r_c_deklaag=r_c_deklaag, d_deklaag=d_deklaag) + + z_u = modelfactor_u * dphi_c_u - (phi_exit - h_exit) + z_h = (modelfactor_h * i_c_h) - i_exit + z_p = (modelfactor_p * modelfactor_ff * modelfactor_3d + * modelfactor_aniso * modelfactor_ml * dh_c) - dh_red + z_combin = max(z_u, z_h, z_p) + + return (z_u, z_h, z_p, z_combin, h_exit, r_exit, phi_exit, d_deklaag, + dphi_c_u, i_exit, L_voorland, lambda_voorland, + W_voorland, L_kwelweg, dh_c, dh_red) + + +# noinspection PyPep8Naming +def limit_state_moria( # TODO: Naam moria vervangen voor iets generieks? + # Geometry parameters + # TODO: Moet L_but L_buk worden? Of L_spreidingslengte? + L_intrede: float, L_but: float, + # Boundary condition parameters + buitenwaterstand: float, buitenwaterstand_gemiddeld: float, + polderpeil: float, mv_exit: float, + # Subsoil property parameters + lambda_voorland: float, phi_exit_gemiddeld: float, r_exit: float, + top_zand: float, k_wvp: float, D_wvp: float, + d70: float, gamma_sat_deklaag: float, + # Model property parameters + modelfactor_u: float, modelfactor_h: float, modelfactor_p: float, + modelfactor_ff: float, modelfactor_3d: float, + modelfactor_aniso: float, modelfactor_ml: float, i_c_h: float, + r_c_deklaag: float, d70_m: float, gamma_korrel: float, v: float, + theta: float, eta: float, + # Constants + g: float, gamma_water: float, +) -> Tuple[float, ...]: + """ Grenstoestandsfuncties volgens het WBI-model met + grondwaterstroming conform MORIA model. + + :param L_intrede: + :param L_but: + :param buitenwaterstand: + :param buitenwaterstand_gemiddeld: + :param polderpeil: + :param mv_exit: + :param lambda_voorland: + :param phi_exit_gemiddeld: + :param r_exit: + :param top_zand: + :param k_wvp: + :param D_wvp: + :param d70: + :param gamma_sat_deklaag: + :param modelfactor_u: + :param modelfactor_h: + :param modelfactor_p: + :param modelfactor_ff: Model factor fijne fractie. + :param modelfactor_3d: Model factor 3D effecten. + :param modelfactor_aniso: Model factor anisotropie. + :param modelfactor_ml: Model factor meerlaagsheid zandpakket. + :param i_c_h: + :param r_c_deklaag: + :param d70_m: + :param gamma_korrel: + :param v: + :param theta: + :param eta: + :param g: + :param gamma_water: + :return: + """ + + kD_wvp = k_wvp * D_wvp + L_voorland = pc_piping.calc_lengte_voorland( + L_intrede=L_intrede, L_but=L_but) + W_voorland = pc_piping.calc_W_voorland( + lambda_voorland=lambda_voorland, L_voorland=L_voorland) + L_kwelweg = pc_piping.calc_L_kwelweg(L_but=L_but, W_voorland=W_voorland) + h_exit = pc_piping.calc_h_exit(polderpeil=polderpeil, mv_exit=mv_exit) + d_deklaag = pc_piping.calc_d_deklaag(mv_exit=mv_exit, top_zand=top_zand) + phi_exit = ( + phi_exit_gemiddeld + r_exit * (buitenwaterstand + - buitenwaterstand_gemiddeld) + ) + dphi_c_u = pc_piping.calc_dphi_c_u( + d_deklaag=d_deklaag, + gamma_sat_deklaag=gamma_sat_deklaag, + gamma_water=gamma_water) + i_exit = pc_piping.calc_i_exit( + phi_exit=phi_exit, h_exit=h_exit, d_deklaag=d_deklaag) + dh_c = pc_piping.calc_dh_c( + d70=d70, D_wvp=D_wvp, kD_wvp=kD_wvp, L_kwelweg=L_kwelweg, + gamma_water=gamma_water, g=g, v=v, theta=theta, + eta=eta, d70_m=d70_m, gamma_korrel=gamma_korrel) + dh_red = pc_piping.calc_dh_red( + buitenwaterstand=buitenwaterstand, h_exit=h_exit, + r_c_deklaag=r_c_deklaag, d_deklaag=d_deklaag) + z_u = modelfactor_u * dphi_c_u - (phi_exit - h_exit) + z_h = (modelfactor_h * i_c_h) - i_exit + z_p = (modelfactor_p * modelfactor_ff * modelfactor_3d * modelfactor_aniso + * modelfactor_ml * dh_c) - dh_red + z_combin = max(z_u, z_h, z_p) + + return (z_u, z_h, z_p, z_combin, h_exit, phi_exit, d_deklaag, + dphi_c_u, i_exit, L_voorland, W_voorland, + L_kwelweg, kD_wvp, dh_c, dh_red) diff --git a/geoprob_pipe/calculations/physical_components/__init__.py b/geoprob_pipe/calculations/physical_components/__init__.py new file mode 100644 index 00000000..3b29dc5f --- /dev/null +++ b/geoprob_pipe/calculations/physical_components/__init__.py @@ -0,0 +1,5 @@ +""" +In deze `physical_components` subpackage worden alle fysieke sub-functies +toegevoegd die als opbouw gelden voor de grenstoestandsfuncties in de +`limit_states`-subpackage. +""" diff --git a/app/helper_functions/geohydro_functions.py b/geoprob_pipe/calculations/physical_components/geohydro_functions.py similarity index 76% rename from app/helper_functions/geohydro_functions.py rename to geoprob_pipe/calculations/physical_components/geohydro_functions.py index 90e13dc0..12c42a76 100644 --- a/app/helper_functions/geohydro_functions.py +++ b/geoprob_pipe/calculations/physical_components/geohydro_functions.py @@ -1,6 +1,6 @@ -"""This module consists of different geohydrological methods used in the safety assesment of levees. - -There are different functions and classes defined. Background information can be found in +"""Deze module bevat verschillende geohydrologische methoden die worden +gebruikt bij de veiligheidsbeoordeling van dijken. Achtergrondinformatie +is te vinden in het 'Technisch Rapport Waterspanningen bij dijken' :cite:t:`trw_2004`. """ @@ -9,23 +9,20 @@ # Functions def calc_lambda(kd: float, c: float) -> float: - r"""Calculates leakage length + r""" Calculates leakage length .. math:: - \lambda = \sqrt{kDc} - Args: - kd (float): transmissivity [m2/day] - c (float): resistance of the top soil [day] - - Returns: - float: returns leakage length lambda [m] + :param kd: transmissivity [m2/day] + :param c: resistance of the topsoil [day] + :return: leakage length lambda [m] """ return math.sqrt(kd * c) -# W staat voor de effectieve voorlandlengteformule, lam = lambda +# W staat voor de effectieve voorland lengte formule, lam = lambda +# noinspection PyPep8Naming def calc_W(lam: float, L: float) -> float: r"""Calculates effective leakage length by: @@ -43,8 +40,10 @@ def calc_W(lam: float, L: float) -> float: return lam * math.tanh(L / lam) +# noinspection PyPep8Naming def calc_r_BIT(w1: float, l2: float, w3: float) -> float: - r"""Calculates response in stationary models at innertoe based on given weights. + r"""Calculates response in stationary models at inner toe based on + given weights. See :cite:t:`trw_2004`. .. math:: @@ -58,11 +57,14 @@ def calc_r_BIT(w1: float, l2: float, w3: float) -> float: Returns: float: response at inner toe [0.0-1.0] """ - return (w3) / (w1 + l2 + w3) + return w3 / (w1 + l2 + w3) +# noinspection PyPep8Naming def calc_r_BUT(w1: float, l2: float, w3: float) -> float: - r"""Calculates response in stationary models at outer toe based on given weights. + r"""Calculates response in stationary models at outer toe based on + given weights. + See :cite:t:`trw_2004`. .. math:: @@ -82,7 +84,7 @@ def calc_r_BUT(w1: float, l2: float, w3: float) -> float: def calc_respons2pot( h_ref: float, r_exit: float, h_riv: float ) -> float: # Van respons naar potentiaal - r"""Calculates potential from given response. + r"""Calculates potential from given response. See :cite:t:`trw_2004`. .. math:: @@ -99,10 +101,11 @@ def calc_respons2pot( return h_ref + r_exit * (h_riv - h_ref) -def calc_pot2repons( +def calc_pot2response( phi: float, h_ref: float, h_riv: float ) -> float: # Van potentiaal naar respons. - r"""Calculates response from given potential + r"""Calculates response from given potential. This is the reverse + function of `calc_respons2pot`. .. math:: @@ -110,7 +113,7 @@ def calc_pot2repons( Args: phi (float): given potential [m+ref] - h_ref (float): reference leve, eg. potential in polder [m+ref] + h_ref (float): reference leve, e.g. potential in polder [m+ref] h_riv (float): water level at river, given potential [m+ref] Returns: @@ -119,8 +122,10 @@ def calc_pot2repons( return (phi - h_ref) / (h_riv - h_ref) +# noinspection PyPep8Naming def calc_ang_frequency(T: float) -> float: r"""Calculates Angular frequency from period of a sinus wave. + See :cite:t:`trw_2004` for background information. .. math:: @@ -137,8 +142,9 @@ def calc_ang_frequency(T: float) -> float: return w +# noinspection PyPep8Naming def calc_P_from_T(T: float) -> float: - r"""Calculates duration P from period T + r"""Calculates duration P from period T. .. math:: @@ -156,8 +162,9 @@ def calc_P_from_T(T: float) -> float: return T / 2.0 +# noinspection PyPep8Naming def calc_T_from_P(P: float) -> float: - r"""Calculates storm period from storm duration P + r"""Calculates storm period from storm duration P. .. math:: @@ -172,8 +179,10 @@ def calc_T_from_P(P: float) -> float: return P * 2.0 -# functies voor berekening cyclische spreidingslengte op basis van de stationaire spreidingslengte -def calc_lambda_cycl_from_stationnary( +# functies voor berekening cyclische spreidingslengte op basis van de +# stationaire spreidingslengte +# noinspection PyPep8Naming +def calc_lambda_cycl_from_stationary( LambdaStat: float, d: float, c_v: float, w: float ) -> float: r"""Calculates cyclic lambda from stationary leakage length @@ -184,7 +193,8 @@ def calc_lambda_cycl_from_stationnary( t_{h} = \frac{d^{2}}{c_{v}^{'}} - \lambda_{\omega} = \frac{1.082 * \lambda_{s}}{\sqrt[4]{t_{h}^{'}\omega}} + \lambda_{\omega} = \frac{1.082 * \lambda_{s}} + {\sqrt[4]{t_{h}^{'}\omega}} Args: @@ -201,12 +211,15 @@ def calc_lambda_cycl_from_stationnary( return LambdaCycl +# noinspection PyPep8Naming def calc_lambda_cycl(LambdaCycl_1: float, T2: float, T1: float) -> float: - r"""Calculates cyclic lambda from one period to another + r"""Calculates cyclic lambda from one period to another. + See :cite:t:`trw_2004`. .. math:: - \lambda_{\omega, T_{2}}^{'} = \lambda_{\omega, T_{1}}^{'} \sqrt[4]{\frac{T_{2}}{T_{1}}} + \lambda_{\omega, T_{2}}^{'} = \lambda_{\omega, T_{1}}^{'} + \sqrt[4]{\frac{T_{2}}{T_{1}}} T1 and T2 are in same dimension (e.g. seconds, hours, days) @@ -222,7 +235,8 @@ def calc_lambda_cycl(LambdaCycl_1: float, T2: float, T1: float) -> float: def calc_theta(b: float, lambda_w_vl: float) -> float: - r"""Calculates theta, see figure b4.13 from 'Technisch Rapport Waterspanningen bij dijken' :cite:t:`trw_2004`. + r"""Calculates theta, see figure b4.13 from 'Technisch Rapport + Waterspanningen bij dijken' :cite:t:`trw_2004`. Approximation by 5th degree polynomials. Args: @@ -252,24 +266,22 @@ def calc_theta(b: float, lambda_w_vl: float) -> float: def calc_f(b: float, lambda_w_vl: float) -> float: - ( - r"""Calculates f, see figure b4.13 from 'Technisch Rapport Waterspanningen bij dijken' :cite:t:`trw_2004`. - Approximation by exponential function + """Calculates f, see figure b4.13 from 'Technisch Rapport + Waterspanningen bij dijken' :cite:t:`trw_2004`. + Approximation by exponential function. Args: - b (float): with of river [m], + b (float): with of river [m], lambda_w_vl (float): cyclic lambda of foreland [m] - + Raises: ValueError: Only for positive numbers Returns: float: f from b4.13 :cite:t:`trw_2004` - """ - """ - b : with of river in m - lambda_w_vl : cyclic lambda of foreland""" - ) + b : with of river in m + lambda_w_vl : cyclic lambda of foreland""" + x = b / lambda_w_vl if x < 0.0: raise ValueError @@ -277,11 +289,12 @@ def calc_f(b: float, lambda_w_vl: float) -> float: return 1.0 + 7.0659 * math.exp(-3.648 * x) +# noinspection PyPep8Naming def calc_mean_pot_gradient( W1: float, W3: float, x_tp: float, mean_wl: float, phi_onv: float ) -> float: r"""Approximation of hydraulic head under daily (mean) conditions. - Uses method from tipping point :cite:t:`trw_2004` + Uses method from tipping point :cite:t:`trw_2004`. .. math:: diff --git a/geoprob_pipe/calculations/physical_components/model4a.py b/geoprob_pipe/calculations/physical_components/model4a.py new file mode 100644 index 00000000..435c474a --- /dev/null +++ b/geoprob_pipe/calculations/physical_components/model4a.py @@ -0,0 +1,220 @@ +r""".. _stationair-model: + +Model 4a: Stationair model +========================== + +Op deze pagina volgt een uitleg van de implementatie van het stationaire +model. Achtergronden staan in bijlage 4 van het Technisch rapport +Waterspanningen bij Dijken :cite:t:`trw_2004`. +Onder de aanname van horizontale stroming in het watervoerende zandpakket +en verticale stroming in de weerstand biedende deklaag is een analytische +oplossing beschikbaar voor het debiet en het stijghoogteverloop in het zand. + +.. figure:: /_static/model4a_trwd.png + :width: 100% + + Schematisering grondwaterstroming stationair model + (figuur b4.4 uit :cite:t:`trw_2004`) + + +Het stationaire model houdt in dat de respons op een gegeven locatie +:math:`x` constant is. Op elke locatie is het verband tussen de stijghoogte +in het watervoerende pakket :math:`\phi(x)` en de respons :math:`r(x)` +bekend door: + +.. math:: + + \phi(x) = h_{ref} + r(x) (h_{rivier} - h_{ref}) + +en andersom: + +.. math:: + + r(x) = \frac{(\phi(x) - h_{ref})}{(h_{rivier} - h_{ref})} + +Aan het zandpakket met afdekkende kleilaag worden de volgende weerstanden +gedefinieerd. Voor het voorland: + +.. math:: + + W_{1} = \lambda_{1} tanh(\frac{L_{1}}{\lambda_{1}}) + +en voor het achterland: + +.. math:: + + W_{3} = \lambda_{3} tanh(\frac{L_{3}}{\lambda_{3}}) + +De totale weerstand is de som van bovenstaande weerstanden: +:math:`\sum W = W_1 + L_2 + W_3`. + +In het geval van een radiale (intrede)weerstand is er een extra +weerstandsfactor gedefinieerd: + +.. math:: + + W_{radiaal} = 0.44 D + +De radiale weerstand kan aan de totale weerstand :math:`\sum W` worden +toegevoegd. + +De respons ter plaatse van de buitenteen :math:`r_{but}` en de binnenteen +:math:`r_{bit}` van de dijk is gedefinieerd als: + +.. math:: + + r_{but} = \frac{(W_2 + L_2)}{\sum W} + +en + +.. math:: + + r_{bit} = \frac{(W_3)}{\sum W} + +Het model neemt aan dat tussen de buitenteen en de binnenteen van de dijk +er geen uitwisseling plaatsvindt tussen het zandpakket en de deklaag. +Over deze lengte :math:`L_2` wordt lineair geïnterpoleerd. +Een bijzonder geval is wanneer :math:`L_2 = 0`. We spreken dan van een +kantelpunt. De definitie van de respons in het kantelpunt (zie +bladzijde b3-7 van :cite:`trw_2004)` is: + +.. math:: + + r_{kp} = \frac{1}{(1 + \frac{W_1}{W_3})} + +Voor de faalmechanismen piping en macrostabiliteit is het potentiaalverloop +verloop in de nabijheid van de dijk van belang. Door de aanname van lineaire +interpolatie wordt het potentiaalverloop beschreven door drie formules: +één voor het voorland tot de buitenteen, het gebied onder de dijk en een +formulering voor het achterland. Hiervoor is het nodig de :math:`x` positie +in het dwarsprofiel te kennen. Deze module hanteert hiervoor de +volgende definities: + +De :math:`x` loopt op richting het achterland. De dijkzate is dan gedefinieerd +als: :math:`L_2 = x_{bit} - x_{but}`. + +Als :math:`x < x_{but}` dan ligt :math:`x` in het voorland en als +:math:`x > x_{but}` dan ligt :math:`x` in het achterland. + +Voorland: + +.. math:: + + r(x) = 1.0 - (1.0 - r_{but}) \frac{sinh(\frac{L_{1} + x - x_{but}} + {\lambda_{1}})}{sinh (\frac{L_{1}}{\lambda_{1}})} + +Onder de dijk: + +.. math:: + + r(x) = r_{bit} + (r_{but} - r_{bit}) \frac{x_{bit} - x}{L_{2}} + +Achterland: + +.. math:: + + r(x) = r_{bit} \frac{sinh(\frac{L_{3} - x + x_{bit}}{\lambda_{3}})} + {sinh (\frac{L_{3}}{\lambda_{3}})} + +""" + + +import math +from dataclasses import dataclass +from typing import Tuple +from geoprob_pipe.calculations.physical_components.geohydro_functions import ( + calc_lambda, calc_r_BIT, calc_r_BUT, calc_W + ) + + +@dataclass +class Model4a: + r"""Class for groundwater model 4A Technisch Rapport Waterspanningen + bij Dijken. + """ + + kD: float + D: float + c1: float + c3: float + L1: float + L3: float + x_but: float + x_bit: float + + # noinspection PyPep8Naming + @property + def L2(self) -> float: + return abs(self.x_bit - self.x_but) + + @property + def lambda1(self) -> float: + return calc_lambda(self.kD, self.c1) + + @property + def lambda3(self) -> float: + return calc_lambda(self.kD, self.c3) + + # noinspection PyPep8Naming + @property + def W1(self) -> float: + return calc_W(self.lambda1, self.L1) + + # noinspection PyPep8Naming + @property + def W3(self) -> float: + return calc_W(self.lambda3, self.L3) + + # noinspection PyPep8Naming + @property + def W_rad(self) -> float: + return 0.44 * self.D + + # noinspection PyPep8Naming + @property + def W_tot4a(self) -> float: + return self.W1 + self.L2 + self.W3 + + # noinspection PyPep8Naming + @property + def r_BUT(self) -> float: + return calc_r_BUT(self.W1, self.L2, self.W3) + + # noinspection PyPep8Naming + @property + def r_BIT(self) -> float: + return calc_r_BIT(self.W1, self.L2, self.W3) + + def respons(self, x: float) -> Tuple[float, float, float]: + """calculate response at x given model + x positive direction is inwards, so x_but < x_bit""" + + # Before floodplain + if x < self.x_but - self.L1: + r = 1.0 + + # Floodplain + elif self.x_but > x >= self.x_but - self.L1: + r = 1.0 - (1.0 - self.r_BUT) * math.sinh( + (self.L1 + x - self.x_but) / self.lambda1 + ) / math.sinh(self.L1 / self.lambda1) + + # Hinterland (where potential is affected) + elif self.x_bit < x <= self.x_bit + self.L3: + r = ( + self.r_BIT + * math.sinh((self.L3 - x + self.x_bit) / self.lambda3) + / math.sinh(self.L3 / self.lambda3) + ) + + # + elif x > self.x_bit + self.L3: + r = 0.0 + + # dike + else: + r = self.r_BIT + (self.r_BUT - self.r_BIT) * (self.x_bit - x) / ( + self.x_bit - self.x_but + ) + + return r, self.r_BUT, self.r_BIT diff --git a/geoprob_pipe/calculations/physical_components/piping.py b/geoprob_pipe/calculations/physical_components/piping.py new file mode 100644 index 00000000..5af31ae8 --- /dev/null +++ b/geoprob_pipe/calculations/physical_components/piping.py @@ -0,0 +1,386 @@ +r"""Module met functies voor het berekenen van fysische componenten van +piping en uplift. Dit betreft onder andere de dikte van de deklaag, +het niveau bij het uittredepunt en de kwelweglengte. +""" + +import math +from geoprob_pipe.calculations.physical_components.model4a import Model4a + + +def calc_d_deklaag( + mv_exit: float, + top_zand: float +) -> float: + r"""Berekening deklaagdikte ter plaatse van het uittredepunt, + de minimale dikte van de deklaag is 0.1 m omdat negatieve deklaagdiktes + niet mogelijk zijn. Dit uitgangspunt is gekozen omdat ook bij een zeer + dunne deklaag nog enige reductie van het verval verwacht mag worden. + + Args: + mv_exit (float): Bodemhoogte ter plaatse van Uittredepunten [m+NAP] + top_zand (float): Geschematiseerde top van het vak [m+NAP] + + Returns: + float: deklaagdikte [m] + """ + return max(mv_exit - top_zand, 0.1) + + +def calc_h_exit( + polderpeil: float, + mv_exit: float +) -> float: + r"""Berekening van het niveau van het uittredepunt op basis van polderpeil + of maaiveldniveau. Functie geeft de maximale waarde van polderpeil en + mv_exit terug. Dit is de benedenstroomse randvoorwaarde voor het verval + in pipingberekeningen. + + Args: + polderpeil (float): polderpeil [m+NAP] + mv_exit (float): maaiveldniveau van uittredepunt [m+NAP] + + Returns: + float: niveau bij het uittredepunt in m+NAP + """ + return max(polderpeil, mv_exit) + + +# noinspection PyPep8Naming +def calc_lengte_voorland( + L_intrede: float, + L_but: float +) -> float: + r""" Berekent de geometrische voorlandlengte in [m] op basis van + afstanden ten opzichte van een uittredepunt. In de + pre-processing tool worden :math:`L_{intrede}` en :math:`L_{but}` + als geografische lijnobjecten gedefinieerd. De kortste afstand tussen + deze objecten is invoer voor deze functie. + + Args: + L_intrede (float): afstand van uittredepunten tot een (denkbeeldige) + intredelijn [m]. + L_but (float): afstand van uittredepunten tot buitenteenlijn [m]. + + Returns: + float: geometrische voorlandlengte [m] + """ + return abs(L_intrede - L_but) + + +# noinspection PyPep8Naming +def calc_lambda_achterland( + kD_wvp: float, + c_achterland: float +) -> float: + r"""Berekent de spreidingslengte van het achterland in [m]. + + .. math:: + + \lambda = \sqrt{kDc} + + Args: + kD_wvp (float): Transmissiviteit van het watervoerende pakket [m²/dag] + c_achterland (float): Weerstand van de deklaag in het achterland [dag] + + Returns: + float: spreidingslengte van het achterland [m] + """ + return (kD_wvp * c_achterland) ** (1 / 2) + + +# noinspection PyPep8Naming +# TODO: functie samenvoegen met calc_lambda_achterland? +def calc_lambda_voorland( + kD_wvp: float, + c_voorland: float +) -> float: + r"""Berekent de spreidingslengte van het achterland in [m]. + + .. math:: + + \lambda = \sqrt{kDc} + + Args: + kD_wvp (float): Transmissiviteit van het watervoerende pakket [m²/dag] + c_voorland (float): Weerstand van de deklaag in het voorland [dag] + + Returns: + float: spreidingslengte van het voorland [m] + """ + return (kD_wvp * c_voorland) ** (1 / 2) + + +def calc_dh_red( + buitenwaterstand: float, + h_exit: float, + r_c_deklaag: float, + d_deklaag: float +) -> float: + r"""Berekening van het gereduceerde verval over de waterkering. + + .. math:: + + \Delta h_{red} = h_{buitenwaterstand} - h_{exit} - r_{c, deklaag} + \cdot d_{deklaag} + + Args: + buitenwaterstand (float): buitenwaterstand [m+NAP] + h_exit (float): Benedenstroomse randvoorwaarde verval [m+NAP] + r_c_deklaag (float): Reductie constante van het verval over de + deklaag [-] + d_deklaag (float): deklaagdikte in m + + Returns: + float: gereduceerd verval [m] + """ + return buitenwaterstand - h_exit - r_c_deklaag * d_deklaag + + +# noinspection PyPep8Naming +def calc_W_achterland( + lambda_achterland: float, + L_achterland: float +) -> float: + r"""Berekent de geohydrologische weerstand van het achterland in [m]. + + .. math:: + + W = \lambda tanh(\frac{L}{\lambda}) + + Args: + lambda_achterland (float): de spreidingslengte van het achterland [m] + L_achterland (float): afstand van uittredepunten tot + achterlandlengte [m] + + Returns: + float: geohydrologische weerstand van het achterland [m] + """ + return lambda_achterland * math.tanh(L_achterland / lambda_achterland) + + +# noinspection PyPep8Naming +# TODO: functie samenvoegen met calc_W_achterland? +def calc_W_voorland( + lambda_voorland: float, + L_voorland: float +) -> float: + r""" Berekent de geohydrologische weerstand van het voorland in [m]. + Dit wordt ook wel de effectieve voorlandlengte genoemd. + + .. math:: + + W = \lambda tanh(\frac{L}{\lambda}) + + Args: + lambda_voorland (float): de spreidingslengte van het voorland [m] + L_voorland (float): Geometrische voorlandlengte [m] + + Returns: + float: geohydrologische weerstand van het voorland [m] + """ + return lambda_voorland * math.tanh(L_voorland / lambda_voorland) + + +# noinspection PyPep8Naming +def calc_L_kwelweg( + L_but: float, + W_voorland: float +) -> float: + r"""Berekent de kwelweglengte in [m]. + De kwelweglengte is de som van de afstand van het uittredepunt tot de + buitenteenlijn en de effectieve voorlandlengte van het voorland. + De onzekerheid in de kwelweglengte zit in de effectieve voorlandlengte. + + Args: + L_but (float): afstand van uittredepunten tot buitenteenlijn [m] + W_voorland (float): geohydrologische weerstand van het voorland [m] + + Returns: + float: kwelweglengte [m] + """ + + return W_voorland + L_but + + +def calc_dphi_c_u( + d_deklaag: float, + gamma_sat_deklaag: float, + gamma_water: float +) -> float: + r"""Berekening grenspotentiaal ten opzichte van maaiveldniveau in [m]. + + .. math:: + + \Delta \phi_{c, u} = \frac{d_{deklaag} \cdot (\gamma_{sat, deklaag} + - \gamma_{w})}{\gamma_{w}} + + Args: + d_deklaag (float): Dikte van de cohesieve deklaag [m] + gamma_sat_deklaag (float): verzadigd volumegewicht van de + deklaag [kN/m³] + gamma_water (float): volumegewicht van water [kN/m³] + + Returns: + float: grenspotentiaal ten opzichte van maaiveldniveau [m] + """ + return d_deklaag * (gamma_sat_deklaag - gamma_water) / gamma_water + + +def calc_i_exit( + phi_exit: float, + h_exit: float, + d_deklaag: float +) -> float: + r""" Berekening van de optredende heave gradiënt. De heave gradient is + het stijghoogteverschil over de deklaag gedeeld door de deklaagdikte. + + .. math:: + + i_{exit} = \frac{(\phi_{exit} - h_{exit})}{d_{deklaag}} + + Args: + phi_exit (float): stijghoogte in het watervoerende zandpakket ter + plaatse van uittredepunt in m+NAP + h_exit (float): niveau bij het uittredepunt [m+NAP] + d_deklaag (float): deklaagdikte [m] + + Returns: + float: heave gradient in [-] + """ + return (phi_exit - h_exit) / d_deklaag + + +# noinspection PyPep8Naming +# TODO: deze wrapper functie wordt gebruikt in heave_icw_model4a.py +# en uplift_icw_model4a.py +# check of deze limit_state functies ook daadwerkelijk gebruikt worden +# in de berekeningen. +# zo niet, verwijder deze functies of roep de model4a klasse direct aan +# in de limit_state functies. +def calc_r_exit_model4a( + kD_wvp: float, + D_wvp: float, + c_voorland: float, + c_achterland: float, + L_but: float, + L_bit: float, + L_achterland: float, + L_voorland: float +) -> float: + r"""Wrapper functie voor het berekenen van de dempingsfactor bij + uittredepunten met behulp van Model4a. De functie gaat uit dat + x = 0.0 bij de binnenteen ligt. Dit betekent dat x_bit = 0.0 + en x_but negatief is. + Uittredepunten moeten altijd binnendijks van de binnenteenlijn liggen. + + """ + model4a = Model4a( + kD=kD_wvp, + D=D_wvp, + c1=c_voorland, + c3=c_achterland, + L1=L_voorland, + L3=L_achterland, + # x_but moet negatief zijn, x_bit is 0.0 + x_but=-1.0 * abs(L_but - L_bit), + x_bit=0.0, ) # x_bit is 0.0 + # Bereken de respons bij het uittredepunt + r_exit, _, _ = model4a.respons(L_bit) + return r_exit + + +def calc_phi_exit( + polderpeil: float, + r_exit: float, + buitenwaterstand: float +) -> float: # Van respons naar potentiaal + r"""Berekent de theoretische stijghoogte bij uittredepunten in [m+NAP]. + + .. math:: + + \phi_exit(x) = polderpeil + r(x) (buitenwaterstand - polderpeil) + + Args: + polderpeil (float): Benedenstroomse randvoorwaarde verval [m+NAP] + r_exit (float): Dempingsfactor bij uittredepunten [-] + buitenwaterstand (float): buitenwaterstand [m+NAP] + + Returns: + float: Theoretische stijghoogte bij uittredepunten [m+NAP] + """ + return polderpeil + r_exit * (buitenwaterstand - polderpeil) + + +# noinspection PyPep8Naming +# TODO: functies toevoegen in docstring +def calc_dh_c( + d70: float, + D_wvp: float, + kD_wvp: float, + L_kwelweg: float, + gamma_water: float, + g: float, + v: float, + theta: float, + eta: float, + d70_m: float, + gamma_korrel: float, +) -> float: + r"""Berekening kritiek verval methode Sellmeijer inclusief + berekeningsinstellingen + + .. math:: + + \Delta H_{c} = F_{resistance} \cdot F_{scale} \cdot F_{geometry} + \cdot L_{kwelweg} + + + Args: + d70 (float): 70% percentiel van de korrelgrootteverdeling [m] + D_wvp (float): dikte van het watervoerende pakket [m] + kD_wvp (float): transmissiviteit van het watervoerende pakket [m²/dag] + L_kwelweg (float): kwelweglengte in meters + gamma_water (float): volumegewicht van water [kN/m³] + g (float): Zwaartekrachtversnelling [m/s2] + v (float): kinematische viscositeit [m²/s] + theta (float): rolweerstandshoek [graden] + eta (float): coefficiënt van White [-] + d70_m (float): gemiddelde d70 in kleine schaalproeven [m] + gamma_korrel (float): (schijnbaar) volumegewicht van de zandkorrels + onder water [kN/m³] + + Returns: + float: kritiek verval [m] + """ + # Omrekenen transmissiviteit naar doorlatendheid + k_wvp_calc = kD_wvp / D_wvp + + # Omrekenen doorlatendheid van m/d naar m/s + k_wvp_calc_sec = k_wvp_calc / (24 * 3600) + # Intrinsieke doorlatendheid + k_intr = (v / g) * k_wvp_calc_sec + + # Berekening Fres + # noinspection PyPep8Naming + Fres = ( + eta + * ((gamma_korrel - gamma_water) / gamma_water) + * math.tan(theta * math.pi / 180.00) + ) + + # Berekening Fscale + # noinspection PyPep8Naming + Fscale = (pow(d70 / d70_m, 0.4) * d70_m + / pow(k_intr * L_kwelweg, (1.0 / 3.0))) + + # Berekening F_geometry + if D_wvp == L_kwelweg: + # noinspection PyPep8Naming + D_wvp = D_wvp - 0.001 + else: + pass + totdemacht = 0.04 + (0.28 / (pow(D_wvp / L_kwelweg, 2.8) - 1.0)) + # noinspection PyPep8Naming + Fgeom = 0.91 * pow(D_wvp / L_kwelweg, totdemacht) + + return Fres * Fscale * Fgeom * L_kwelweg diff --git a/app/classes/__init__.py b/geoprob_pipe/calculations/systems/__init__.py similarity index 100% rename from app/classes/__init__.py rename to geoprob_pipe/calculations/systems/__init__.py diff --git a/app/helper_functions/__init__.py b/geoprob_pipe/calculations/systems/base_objects/__init__.py similarity index 100% rename from app/helper_functions/__init__.py rename to geoprob_pipe/calculations/systems/base_objects/__init__.py diff --git a/geoprob_pipe/calculations/systems/base_objects/base_system_build.py b/geoprob_pipe/calculations/systems/base_objects/base_system_build.py new file mode 100644 index 00000000..a0f2be7a --- /dev/null +++ b/geoprob_pipe/calculations/systems/base_objects/base_system_build.py @@ -0,0 +1,131 @@ +from __future__ import annotations +from geoprob_pipe.calculations.systems.base_objects.system_calculation import ( + SystemCalculation) +from typing import List, Tuple +from pandas import DataFrame, Series +import sqlite3 +from geoprob_pipe.cmd_app.parameter_input.expand_input_tables import ( + run_expand_input_tables) +# if TYPE_CHECKING: +# from geoprob_pipe import GeoProbPipe + + +def _gather_variable_correlations(geopackage_filepath: str + ) -> List[Tuple[str, str, float]]: + """ Input originally from the input Excel-file. It defines per + combination of two parameters the correlation; a value between 0.0 + (no correlation) and 1.0 (fully correlated). By default, no correlation + is specified for parameter combinations, i.e. the probabilistic library + automatically assigns 0.0 as correlation for the combination. The + correlation applies for the entire trajectory. + + TODO: This setup applies for the entire trajectory. In future versions of + the code the user should be able to assign the correlation on vak, + scenario and uittredepunten level. + + :return: + """ + + try: + conn = sqlite3.connect(geopackage_filepath) + cursor = conn.cursor() + cursor.execute(""" +SELECT parameter_a, parameter_b, correlation FROM correlatie_invoer +WHERE correlation <> 0.0; +""") + rows = cursor.fetchall() # This will be a list of tuples + conn.close() + return rows + except sqlite3.OperationalError: + return [] + + +def _gather_calculation_input( + df_expanded: DataFrame, uittredepunt_id: int, + ondergrondscenario_naam: str) -> List: + + # Collect input for specific calculation + df_filter = df_expanded[ + (df_expanded["uittredepunt_id"] == uittredepunt_id) & + (df_expanded["ondergrondscenario_naam"] == ondergrondscenario_naam)] + df = df_filter.copy(deep=True) + + # Parse parameter input to list of dictionaries + df['parameter_input'] = df.apply( + lambda row2: {**row2['parameter_input'], + 'name': row2['parameter_name']}, axis=1) + return df['parameter_input'].values.tolist() + + +def _generate_single_calculation( + row_calculation_metadata: Series, vak_id: int, + df_expanded: DataFrame, system_class, + variable_correlations: List[Tuple[str, str, float]] +) -> SystemCalculation: + + # General information + uittredepunt_id = row_calculation_metadata["uittredepunt_id"] + ondergrondscenario_naam = row_calculation_metadata[ + "ondergrondscenario_naam"] + + # Construct calculation + calculation_input = _gather_calculation_input( + df_expanded=df_expanded, uittredepunt_id=uittredepunt_id, + ondergrondscenario_naam=ondergrondscenario_naam) + calc = system_class( + system_variable_distributions=calculation_input, + system_variable_correlations=variable_correlations) + calc.metadata["uittredepunt_id"] = uittredepunt_id + calc.metadata["ondergrondscenario_naam"] = ondergrondscenario_naam + calc.metadata["vak_id"] = vak_id + metadata_summary = { + "uittredepunt_id": uittredepunt_id, + "ondergrondscenario_naam": ondergrondscenario_naam, + "vak_id": vak_id} + calc.validation_messages.about = f"Calculation {metadata_summary}" + + return calc + + +class BaseSystemBuilder: + + def __init__(self, + geopackage_filepath: str, + to_run_vakken_ids: list[int]): + self.system_class = SystemCalculation + self.geopackage_filepath = geopackage_filepath + + # Gather input + df_expanded = run_expand_input_tables( + geopackage_filepath=self.geopackage_filepath) + + # Filter vakken (if only selection needs to run) + if to_run_vakken_ids is not None: + df_expanded = df_expanded[df_expanded['vak_id'] + .isin(to_run_vakken_ids)] + self.df_expanded = df_expanded + + def setup_iteration_df(self) -> DataFrame: + # Iteration dataframe + df_unique_combos: DataFrame = self.df_expanded[[ + "uittredepunt_id", "ondergrondscenario_naam", "vak_id" + ]].drop_duplicates() + return df_unique_combos + + def build_instance(self, row_unique) -> SystemCalculation: + + # Gather variable correlations + variable_correlations: List[Tuple[str, str, float]] = ( + _gather_variable_correlations(self.geopackage_filepath)) + # TODO: Should be made uittredepunt/vak specific in future versions + # of the code. For now only for the entire trajectory. + + calc = _generate_single_calculation( + row_calculation_metadata=row_unique, + vak_id=row_unique["vak_id"], + df_expanded=self.df_expanded, + system_class=self.system_class, + variable_correlations=variable_correlations + ) + + return calc diff --git a/geoprob_pipe/calculations/systems/base_objects/system_calculation.py b/geoprob_pipe/calculations/systems/base_objects/system_calculation.py new file mode 100644 index 00000000..23d64abd --- /dev/null +++ b/geoprob_pipe/calculations/systems/base_objects/system_calculation.py @@ -0,0 +1,186 @@ +from probabilistic_library import ( + ReliabilityProject, DesignPoint, CombineProject, ReliabilityMethod, + CombinerMethod, CombineType, Stochast, Settings) +from typing import Optional, Callable, List, Dict, Union, Tuple, cast +import logging +from geoprob_pipe.utils.validation_messages import ValidationMessages + + +logger = logging.getLogger("geoprob_pipe_logger") + + +class SystemCalculation: + """ Pre-defined system reliability calculation for parallel systems. """ + + def __init__( + self, + distributions: List[Dict], + correlations: List[Tuple[str, str, float]], + project_settings: Dict[str, Union[str, float, int]], + # For assigning in children + limit_states: Optional[List[Callable]] = None, + combin_limit_state: Optional[Callable] = None, + variables_setup_function: Optional[Callable] = None + ): + """ + + :param distributions: + :param correlations: + :param project_settings: ReliabilityProject settings for the limit + state design points. + :param limit_states: + :param variables_setup_function: Dummy functie waarmee variabele namen + worden geïnitieerd. + """ + + # Mutable arguments + if project_settings is None: + project_settings = {} + if correlations is None: + correlations = [] + + self.validation_messages = ValidationMessages() + self.metadata = {} + + # Input arguments + self.given_project_settings: Dict[str, Union[str, float, int]] = ( + project_settings) + self.given_variables_setup_function: Callable = cast( + Callable, variables_setup_function) + self.given_limit_states: List[Callable] = cast( + List[Callable], limit_states) + # self.given_combin_limit_state: Callable = cast( + # Callable, combin_limit_state) + self.given_distributions: List[Dict] = distributions + self.given_correlations: List[Tuple[str, str, float]] = correlations + # TODO Nu Should Klein: I.p.v. dict maak gebruik van + # Distributie-objecten. Minder fout gevoelig. + + # Placeholders + # self.project: Optional[ReliabilityProject] = None + self.model_design_points: List[DesignPoint] = [] + # self.combine_project: Optional[CombineProject] = None + # self.system_design_point: Optional[DesignPoint] = None + + def run(self): + """ Performs all logic of the system reliability calculation. + """ + self._setup_project() + self._apply_settings() + self._assign_variables() + self._assign_project_correlations() + self._generate_model_design_points() + self._generate_system_design_point() + + def _setup_project(self): + """ Sets up the ReliabilityProject-object. This will be used + for all model design points. + """ + self.project = ReliabilityProject() + self.project.settings.reliability_method = ReliabilityMethod.form + + # Some base settings, may be overwritten through self._apply_settings + self.project.settings.reliability_method = 'form' + self.project.settings.variation_coefficient = 0.02 + self.project.settings.maximum_iterations = 1000 + self.project.settings.relaxation_factor = 0.75 + + def _apply_settings(self): + """ + Set up the settings of the ReliabilityProject + + Note: all supported settings can be found in probabilistic_library + .reliability.Settings.__dir__ + """ + for attr_name, value in self.given_project_settings.items(): + + if attr_name not in Settings().__dir__(): + raise ValueError( + f"Attribute '{attr_name}' not found in the ReliabilityCalculation.Settings-class. " + f"Available attributes are:\n" + f"{Settings().__dir__()}") + + setattr(self.project.settings, str(attr_name), value) + + def _assign_variables(self): + self.project.model = self.given_variables_setup_function + + # Validate all system variables have a distribution provided + system_variable_keys = _system_variable_keys(self) + for var_item in self.project.variables: + var_item: Stochast + if var_item.name not in system_variable_keys: + raise KeyError( + """ + """ + f"The system variable '{var_item.name}' has no" + " distribution provided in system_variable_distributions-list." + " Please do so before running the system.") + + for item in self.given_distributions: + name = item['name'] + + # Check if variable exists + if self.project.variables[name] is None: + self.validation_messages.add_warning( + msg=f"The variable '{name}' is unknown in the ReliabilityProject, i.e. in the given " + f"'system_variables_setup'-function. For now this application skips unnecessary variables. If " + f"the variable is necessary, revisit your 'system_variables_setup'-function and the limit state " + f"functions.") + # TODO Nu Should Klein: Feedback aan gebruiker dat er validation messages zijn. + continue + + self.project.variables[name].distribution = item['distribution_type'] + + # Key-worded arguments for uniform + if 'minimum' in item.keys(): + self.project.variables[name].minimum = item['minimum'] + if 'maximum' in item.keys(): + self.project.variables[name].maximum = item['maximum'] + + # Key-worded arguments for deterministic, normal and/or log_normal + if 'mean' in item.keys(): + self.project.variables[name].mean = item['mean'] + if 'deviation' in item.keys(): + self.project.variables[name].deviation = item['deviation'] + if 'variation' in item.keys(): + self.project.variables[name].variation = item['variation'] + + # Key-worded arguments for cdf-curve + if 'fragility_values' in item.keys(): + self.project.variables[name].fragility_values.extend(item['fragility_values']) + + def _assign_project_correlations(self): + for correlation in self.given_correlations: + self.project.correlation_matrix[ + correlation[0], # Parameter name A + correlation[1] # Parameter name B + ] = correlation[2] # Correlation value between 0.0 and 1.0 + + def _generate_model_design_points(self): + for model_callable in self.given_limit_states: + self.project.model = model_callable + self._assign_project_correlations() + self.project.run() + design_point = self.project.design_point + design_point.identifier = model_callable.__name__ + self.model_design_points.append(design_point) + + def _generate_system_design_point(self): + self.combine_project = CombineProject() + for design_point in self.model_design_points: + self.combine_project.design_points.append(design_point) + self.combine_project.settings.combiner_method = CombinerMethod.importance_sampling + self.combine_project.settings.combine_type = CombineType.parallel + self.combine_project.run() + self.combine_project.design_point.identifier = "system" + self.system_design_point = self.combine_project.design_point + + +def _system_variable_keys(self: SystemCalculation) -> List[str]: + return_array = [] + for item in self.given_distributions: + print(f"{item=}") + return_array.append(item['name']) + return return_array + # return [item['name'] for item in self.given_distributions] diff --git a/geoprob_pipe/calculations/systems/build_and_run.py b/geoprob_pipe/calculations/systems/build_and_run.py new file mode 100644 index 00000000..aaf025fd --- /dev/null +++ b/geoprob_pipe/calculations/systems/build_and_run.py @@ -0,0 +1,143 @@ +from __future__ import annotations +from typing import TYPE_CHECKING, List +from geoprob_pipe.calculations.systems.mappers.calculation_mapper import ( + CALCULATION_MAPPER) +from multiprocessing import Pool, cpu_count +import time +import math +from dataclasses import dataclass +from geoprob_pipe.results.construct_dataframes import ( + collect_df_beta_limit_state, collect_df_beta_scenario) +from geoprob_pipe.results.alphas_and_physical_values import ( + collect_stochast_values, calculate_derived_values) +# noinspection PyPep8Naming +from geoprob_pipe.utils.loggers import TmpAppConsoleHandler as logger + +if TYPE_CHECKING: + from pandas import DataFrame + from geoprob_pipe import GeoProbPipe + from geoprob_pipe.calculations.systems.base_objects\ + .base_system_build import BaseSystemBuilder + from geoprob_pipe.utils.validation_messages import ValidationMessages + +_BUILDER: BaseSystemBuilder +_MODEL: str + + +@dataclass +class CalcResult: + """ + Dataclass om de resultaten te verzamelen vanuit de calculation. + Bevat de volgende attributen: + Dataframe: df_limit_state, + Dataframe: df_scenario, + Dataframe: df_stochast, + Dataframe: df_derived, + ValidationMessages: validation_message + """ + df_limit_state: DataFrame + df_scenario: DataFrame + df_stochast: DataFrame + df_derived: DataFrame + validation_message: ValidationMessages + + +def _init_worker(geohydrologisch_model, geopackage_filepath, + to_run_vakken_ids): + """ Initiator voor de worker, dit zorgt ervoor dat de tijdrovende + stappen een keer per worker worden uitgevoerd en dan beschikbaar blijven + voor iedere run. + """ + global _BUILDER, _MODEL + _MODEL = geohydrologisch_model + _BUILDER = ( + CALCULATION_MAPPER[geohydrologisch_model]["system_builder"]( + geopackage_filepath=geopackage_filepath, + to_run_vakken_ids=to_run_vakken_ids)) + + +def _worker(row_unique: dict): + """ De worker functie die op de parallelle rekenkernen wordt gedraaid. + """ + + # Build and run calculations + calc = _BUILDER.build_instance(row_unique=row_unique) + calc.run() + + # Collect results + df_limit_state = collect_df_beta_limit_state(calc) + df_scenario = collect_df_beta_scenario(calc) + df_stochast = collect_stochast_values(calc) + df_derived = calculate_derived_values(df_scenario, _MODEL) + df_scenario = df_scenario.drop(columns=["system_calculation"]) + + # Return results (without calculation object) + return CalcResult(df_limit_state, df_scenario, df_stochast, df_derived, + calc.validation_messages) + + +def build_and_run_system_calculations( + geoprob_pipe: GeoProbPipe + ) -> List[CalcResult]: + """ In deze functie worden de parameters voor de berekeningen verzamelt, + aan de workers gegeven en vervolgens de resultaten verzameld. + """ + geohydrologisch_model = geoprob_pipe.input_data.geohydrologisch_model + geopackage_filepath = ( + geoprob_pipe.input_data.app_settings.geopackage_filepath) + to_run_vakken_ids = geoprob_pipe.input_data.app_settings.to_run_vakken_ids + system_builder: BaseSystemBuilder = ( + CALCULATION_MAPPER[geohydrologisch_model]['system_builder']( + geopackage_filepath=geopackage_filepath, + to_run_vakken_ids=to_run_vakken_ids)) + + logger.info("Now building and running calculations...") + df_unique_combos = system_builder.setup_iteration_df() + # Bepaal de parameters voor de multiprocessing setup en de logger + n_threads: int = cpu_count() - 1 + n_calc_totaal: int = len(df_unique_combos) + # Minimaal 5 berekeningen per chunk en grootte van chunk beperken + # zodat er gelogd kan worden. + chunk_size: int = max(math.ceil(n_calc_totaal / (n_threads * 10)), 5) + logger.info( + f"Running {n_calc_totaal} calculations in chunks of {chunk_size}" + f" with {n_threads} parallel threads.") + char_len_total = str(n_calc_totaal).__len__() + logger.info( + f"Progress: {0:>{char_len_total}} / {n_calc_totaal} calculations.") + + # Dicts zijn gemakkelijker te pickelen en daardoor sneller te + # verwerken dan pandas series. + rows = [dict(zip(df_unique_combos.columns, r)) + for r in df_unique_combos.itertuples(index=False, name=None)] + + last_report = time.time() + done = 0 + results: List[CalcResult] = [] + pool_size = max(min(math.floor(n_calc_totaal / chunk_size), n_threads), 1) + + # Multiprocessing setup + with Pool(processes=pool_size, initializer=_init_worker, initargs=( + geohydrologisch_model, geopackage_filepath, to_run_vakken_ids + )) as pool: + + for res in pool.imap_unordered(_worker, rows, chunksize=chunk_size): + results.append(res) + done += 1 + + # Alleen kijken of er gelogd moet worden bij de laatste + # berekening die uit de chunk komt. + if done % chunk_size != 0: + continue + + # Alleen loggen wanneer 30 seconden is gepasseerd + now = time.time() + if now - last_report < 30.0: + continue + + # Log + logger.info(f"Progress: {done:>{char_len_total}} / {n_calc_totaal}" + " calculations.") + last_report = now + + return results diff --git a/geoprob_pipe/calculations/systems/mappers/__init__.py b/geoprob_pipe/calculations/systems/mappers/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/geoprob_pipe/calculations/systems/mappers/calculation_mapper.py b/geoprob_pipe/calculations/systems/mappers/calculation_mapper.py new file mode 100644 index 00000000..a5194ba9 --- /dev/null +++ b/geoprob_pipe/calculations/systems/mappers/calculation_mapper.py @@ -0,0 +1,37 @@ +from geoprob_pipe.calculations.systems.moria.system_builder import ( + MoriaSystemBuilder) +from geoprob_pipe.calculations.systems.model4a.system_builder import ( + Model4aSystemBuilder) +from geoprob_pipe.calculations.systems.wbi.system_builder import ( + WBISystemBuilder) +from geoprob_pipe.calculations.limit_states.piping_lm import limit_state_moria +from geoprob_pipe.calculations.systems.model4a.limit_state_functions import ( + limit_state_model4a) +# TODO: Dynamisch maken? Forceren dat naamgeving overeenkomt en +# we dynamisch importeren? + + +CALCULATION_MAPPER = { + "model4a": { + "label": "Model 4a", + "system_builder": Model4aSystemBuilder, + "system_return_parameter_keys": [ + "z_u", "z_h", "z_p", "z_combin", "h_exit", "r_exit", "phi_exit", + "d_deklaag", "dphi_c_u", "i_exit","L_voorland", "lambda_voorland", + "W_voorland", "L_kwelweg", "dh_c", "dh_red"], + "limit_state_function": limit_state_model4a, + }, + "wbi": { + "label": "WBI", + "system_builder": WBISystemBuilder, + }, + "moria": { + "label": "MORIA", + "system_builder": MoriaSystemBuilder, + "system_return_parameter_keys": [ + "z_u", "z_h", "z_p", "z_combin", "h_exit", "phi_exit", + "d_deklaag", "dphi_c_u", "i_exit", "L_voorland", "W_voorland", + "L_kwelweg", "kD_wvp", "dh_c", "dh_red"], + "limit_state_function": limit_state_moria, + }, +} diff --git a/geoprob_pipe/calculations/systems/mappers/initial_input_mapper.py b/geoprob_pipe/calculations/systems/mappers/initial_input_mapper.py new file mode 100644 index 00000000..8fa56d25 --- /dev/null +++ b/geoprob_pipe/calculations/systems/mappers/initial_input_mapper.py @@ -0,0 +1,26 @@ +from geoprob_pipe.calculations.systems.moria.initial_input import ( + INITIAL_INPUT as INITIAL_INPUT_MORIA) +from geoprob_pipe.calculations.systems.model4a.initial_input import ( + INITIAL_INPUT as INITIAL_INPUT_MODEL4A) +from geoprob_pipe.calculations.systems.wbi.initial_input import ( + INITIAL_INPUT as INITIAL_INPUT_WBI) + +# TODO: Dynamisch maken? Forceren dat naamgeving overeenkomt en +# we dynamisch importeren? + + +INITIAL_INPUT_MAPPER = { + # TODO: Dit is nog de oude model 4a logica. Aanpassen? + "model4a": { + "label": "Model 4a", + "input": INITIAL_INPUT_MODEL4A, + }, + "wbi": { + "label": "WBI", + "input": INITIAL_INPUT_WBI, + }, + "moria": { + "label": "MORIA", + "input": INITIAL_INPUT_MORIA, + }, +} diff --git a/geoprob_pipe/calculations/systems/model4a/__init__.py b/geoprob_pipe/calculations/systems/model4a/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/geoprob_pipe/calculations/systems/model4a/initial_input.py b/geoprob_pipe/calculations/systems/model4a/initial_input.py new file mode 100644 index 00000000..a33a0940 --- /dev/null +++ b/geoprob_pipe/calculations/systems/model4a/initial_input.py @@ -0,0 +1,296 @@ +from probabilistic_library import DistributionType + + +INITIAL_INPUT = [ + { + "name": "L_achterland", + "description": "Afstand van uittredepunten tot achterlandlengte.", + "remark": "", + "unit": "m", + "distribution_type": DistributionType.deterministic, + "mean": 3500.0, + "source": "excel", + }, + { + "name": "c_voorland", + "description": "Weerstand van de deklaag in het voorland.", + "remark": "", + "unit": "dagen", + "distribution_type": DistributionType.log_normal, + "mean": 10.0, + "variation": 0.1, + "source": "excel", + }, + { + "name": "c_achterland", + "description": "Weerstand van de deklaag in het achterland.", + "remark": "", + "unit": "dagen", + "distribution_type": DistributionType.log_normal, + "mean": 50.0, + "variation": 0.1, + "source": "excel", + }, + { + "name": "L_intrede", + "description": "Afstand van uittredepunten tot geometrische" + " intredelijn.", + "remark": "", + "unit": "m", + "distribution_type": DistributionType.deterministic, + "mean": 150.0, + "source": "spatial", + }, + { + "name": "L_but", + "description": "Afstand van uittredepunten tot buitenteenlijn.", + "remark": "", + "unit": "m", + "distribution_type": DistributionType.deterministic, + "mean": 65.0, + "source": "spatial", + }, + { + "name": "L_bit", + "description": "Afstand van uittredepunten tot binnenteenlijn.", + "remark": "", + "unit": "m", + "distribution_type": DistributionType.deterministic, + "mean": 20.0, + "source": "spatial", + }, + { + "name": "polderpeil", + "description": "Polderpeil ter plaatse van uittredepunten.", + "remark": "", + "unit": "m+NAP", + "distribution_type": DistributionType.deterministic, + "mean": 0.0, + "source": "spatial", + }, + { + "name": "buitenwaterstand", + "description": "Buitenwaterstand. Indien keuze voor 'cdf_curve' als" + " distributie type, dan wordt er een" + " overschrijdingsfrequentielijn berekend met de" + " Hydra-NL Python wrapper Pydra.", + "remark": "", + "unit": "m+NAP", + "distribution_type": DistributionType.deterministic, + "mean": 5.0, + "source": "excel", + }, + { + "name": "mv_exit", + "description": "Bodemhoogte ter plaatse van uittredepunten.", + "remark": "", + "unit": "m+NAP", + "distribution_type": DistributionType.deterministic, + "mean": 0.5, + "source": "spatial", + }, + { + "name": "top_zand", + "description": "Geschematiseerde top van het zand in het vak.", + "remark": "", + "unit": "m+NAP", + "distribution_type": DistributionType.normal, + "mean": -3.0, + "deviation": 0.5, + "source": "excel", + }, + { + "name": "kD_wvp", + "description": "Transmissiviteit van het watervoerende pakket.", + "remark": "", + "unit": "m²/dag", + "distribution_type": DistributionType.log_normal, + "mean": 2000.0, + "variation": 0.35, + "source": "excel", + }, + { + "name": "modelfactor_h", + "description": "Modelfactor voor heave.", + "remark": "", + "unit": "[-]", + "distribution_type": DistributionType.log_normal, + "mean": 1.0, + "variation": 0.1, + "source": "excel", + }, + { + "name": "modelfactor_ff", + "description": "Modelfactor fijne fractie.", + "remark": "", + "unit": "[-]", + "distribution_type": DistributionType.log_normal, + "mean": 1.0, + "variation": 0.1, + "source": "excel", + }, + { + "name": "modelfactor_3d", + "description": "Modelfactor 3D effecten.", + "remark": "", + "unit": "[-]", + "distribution_type": DistributionType.log_normal, + "mean": 1.0, + "variation": 0.1, + "source": "excel", + }, + { + "name": "modelfactor_aniso", + "description": "Modelfactor aniso.", + "remark": "", + "unit": "[-]", + "distribution_type": DistributionType.log_normal, + "mean": 1.0, + "variation": 0.1, + "source": "excel", + }, + { + "name": "modelfactor_ml", + "description": "Modelfactor ML.", + "remark": "", + "unit": "[-]", + "distribution_type": DistributionType.log_normal, + "mean": 1.0, + "variation": 0.1, + "source": "excel", + }, + { + "name": "i_c_h", + "description": "Kritieke heave gradiënt.", + "remark": "", + "unit": "[-]", + "distribution_type": DistributionType.log_normal, + "mean": 0.7, + "variation": 0.15, + "source": "excel", + }, + { + "name": "D_wvp", + "description": "Dikte van het watervoerende pakket.", + "remark": "", + "unit": "m", + "distribution_type": DistributionType.log_normal, + "mean": 50, + "deviation": 1.5, + "source": "excel", + }, + { + "name": "modelfactor_u", + "description": "Modelfactor voor uplift.", + "remark": "", + "unit": "[-]", + "distribution_type": DistributionType.log_normal, + "mean": 1.0, + "variation": 0.1, + "source": "excel", + }, + { + "name": "gamma_water", + "description": "Volumegewicht van water.", + "remark": "", + "unit": "kN/m³", + "distribution_type": DistributionType.deterministic, + "mean": 9.81, + "source": "excel", + }, + { + "name": "gamma_sat_deklaag", + "description": "Gemiddeld volumegewicht van de deklaag.", + "remark": "", + "unit": "kN/m³", + "distribution_type": DistributionType.log_normal, + "mean": 13.9, + "variation": 0.05, + "source": "excel", + }, + { + "name": "modelfactor_p", + "description": "Modelfactor voor piping.", + "remark": "", + "unit": "[-]", + "distribution_type": DistributionType.log_normal, + "mean": 1.0, + "variation": 0.1, + "source": "excel", + }, + { + "name": "d70", + "description": "70% percentiel van de korrelverdeling.", + "remark": "", + "unit": "m", + "distribution_type": DistributionType.log_normal, + "mean": 2.8e-4, + "variation": 0.15, + "source": "excel", + }, + { + "name": "g", + "description": "Zwaartekrachtversnelling.", + "remark": "", + "unit": "m/s²", + "distribution_type": DistributionType.deterministic, + "mean": 9.81, + "source": "excel", + }, + { + "name": "v", + "description": "Kinematische viscositeit – Sellmeijer.", + "remark": "", + "unit": "m²/s", + "distribution_type": DistributionType.deterministic, + "mean": 0.00000133, + "source": "excel", + }, + { + "name": "theta", + "description": "Rolweerstandshoek – Sellmeijer.", + "remark": "", + "unit": "graden", + "distribution_type": DistributionType.deterministic, + "mean": 37.0, + "source": "excel", + }, + { + "name": "eta", + "description": "White's weerstandscoëfficiënt (sleepkrachtfactor," + " constante van White) – Sellmeijer", + "remark": "", + "unit": "[-]", + "distribution_type": DistributionType.deterministic, + "mean": 0.25, + "source": "excel", + }, + { + "name": "d70_m", + "description": "Referentiewaarde voor de 70% percentiel van de" + " korrelverdeling – Sellmeijer.", + "remark": "", + "unit": "m", + "distribution_type": DistributionType.deterministic, + "mean": 2.08e-4, + "source": "excel", + }, + { + "name": "gamma_korrel", + "description": "Volumieke dichtheid zand onder water – Sellmeijer.", + "remark": "", + "unit": "kN/m³", + "distribution_type": DistributionType.deterministic, + "mean": 16.5, + "source": "excel", + }, + { + "name": "r_c_deklaag", + "description": "Reductie constante van het verval over de deklaag.", + "remark": "", + "unit": "[-]", + "distribution_type": DistributionType.deterministic, + "mean": 0.3, + "source": "excel", + }, +] diff --git a/geoprob_pipe/calculations/systems/model4a/limit_state_functions.py b/geoprob_pipe/calculations/systems/model4a/limit_state_functions.py new file mode 100644 index 00000000..4da0d2fa --- /dev/null +++ b/geoprob_pipe/calculations/systems/model4a/limit_state_functions.py @@ -0,0 +1,107 @@ +from geoprob_pipe.calculations.limit_states.piping_lm import ( + limit_state_model4a) + + +# noinspection PyPep8Naming +def calc_Z_u( + L_intrede: float, L_but: float, L_bit: float, L_achterland: float, + buitenwaterstand: float, polderpeil: float, mv_exit: float, + top_zand: float, kD_wvp: float, D_wvp: float, d70: float, + gamma_sat_deklaag: float, c_voorland: float, c_achterland: float, + modelfactor_u: float, modelfactor_h: float, modelfactor_p: float, + modelfactor_ff: float, modelfactor_3d: float, modelfactor_aniso: float, + modelfactor_ml: float, i_c_h: float, r_c_deklaag: float, d70_m: float, + gamma_korrel: float, v: float, theta: float, eta: float, g: float, + gamma_water: float +) -> float: + r"""Grenstoestandfunctie voor opbarsten (uplift). + + Returns: + float: Z waarde van de grenstoestandfunctie voor opbarsten + """ + + return limit_state_model4a( + L_intrede=L_intrede, L_but=L_but, L_bit=L_bit, + L_achterland=L_achterland, buitenwaterstand=buitenwaterstand, + polderpeil=polderpeil, mv_exit=mv_exit, top_zand=top_zand, + kD_wvp=kD_wvp, D_wvp=D_wvp, d70=d70, + gamma_sat_deklaag=gamma_sat_deklaag, c_voorland=c_voorland, + c_achterland=c_achterland, modelfactor_u=modelfactor_u, + modelfactor_h=modelfactor_h, modelfactor_p=modelfactor_p, + modelfactor_ff=modelfactor_ff, modelfactor_3d=modelfactor_3d, + modelfactor_aniso=modelfactor_aniso, modelfactor_ml=modelfactor_ml, + i_c_h=i_c_h, r_c_deklaag=r_c_deklaag, d70_m=d70_m, + gamma_korrel=gamma_korrel, v=v, theta=theta, eta=eta, g=g, + gamma_water=gamma_water)[0] + + +# noinspection PyPep8Naming +def calc_Z_h( + L_intrede: float, L_but: float, L_bit: float, L_achterland: float, + buitenwaterstand: float, polderpeil: float, mv_exit: float, + top_zand: float, kD_wvp: float, D_wvp: float, d70: float, + gamma_sat_deklaag: float, c_voorland: float, c_achterland: float, + modelfactor_u: float, modelfactor_h: float, modelfactor_p: float, + modelfactor_ff: float, modelfactor_3d: float, modelfactor_aniso: float, + modelfactor_ml: float, i_c_h: float, r_c_deklaag: float, d70_m: float, + gamma_korrel: float, v: float, theta: float, eta: float, g: float, + gamma_water: float +) -> float: + r""" Wrapper over de grenstoestandfunctie voor heave zodat deze bruikbaar + is voor de Probabilistic Library. + + Returns: + float: Z waarde van de grenstoestandfunctie voor heave + """ + return limit_state_model4a( + L_intrede=L_intrede, L_but=L_but, L_bit=L_bit, + L_achterland=L_achterland, buitenwaterstand=buitenwaterstand, + polderpeil=polderpeil, mv_exit=mv_exit, top_zand=top_zand, + kD_wvp=kD_wvp, D_wvp=D_wvp, d70=d70, + gamma_sat_deklaag=gamma_sat_deklaag, c_voorland=c_voorland, + c_achterland=c_achterland, modelfactor_u=modelfactor_u, + modelfactor_h=modelfactor_h, modelfactor_p=modelfactor_p, + modelfactor_ff=modelfactor_ff, modelfactor_3d=modelfactor_3d, + modelfactor_aniso=modelfactor_aniso, modelfactor_ml=modelfactor_ml, + i_c_h=i_c_h, r_c_deklaag=r_c_deklaag, d70_m=d70_m, + gamma_korrel=gamma_korrel, v=v, theta=theta, eta=eta, g=g, + gamma_water=gamma_water)[1] + + +# noinspection PyPep8Naming +def calc_Z_p( + L_intrede: float, L_but: float, L_bit: float, L_achterland: float, + buitenwaterstand: float, polderpeil: float, mv_exit: float, + top_zand: float, kD_wvp: float, D_wvp: float, d70: float, + gamma_sat_deklaag: float, c_voorland: float, c_achterland: float, + modelfactor_u: float, modelfactor_h: float, modelfactor_p: float, + modelfactor_ff: float, modelfactor_3d: float, modelfactor_aniso: float, + modelfactor_ml: float, i_c_h: float, r_c_deklaag: float, d70_m: float, + gamma_korrel: float, v: float, theta: float, eta: float, g: float, + gamma_water: float +) -> float: + r"""Grenstoestandfunctie voor het mechanisme piping + + Returns: + float: Z waarde van de grenstoestandfunctie voor piping + """ + return limit_state_model4a( + L_intrede=L_intrede, L_but=L_but, L_bit=L_bit, + L_achterland=L_achterland, buitenwaterstand=buitenwaterstand, + polderpeil=polderpeil, mv_exit=mv_exit, top_zand=top_zand, + kD_wvp=kD_wvp, D_wvp=D_wvp, d70=d70, + gamma_sat_deklaag=gamma_sat_deklaag, c_voorland=c_voorland, + c_achterland=c_achterland, modelfactor_u=modelfactor_u, + modelfactor_h=modelfactor_h, modelfactor_p=modelfactor_p, + modelfactor_ff=modelfactor_ff, modelfactor_3d=modelfactor_3d, + modelfactor_aniso=modelfactor_aniso, modelfactor_ml=modelfactor_ml, + i_c_h=i_c_h, r_c_deklaag=r_c_deklaag, d70_m=d70_m, + gamma_korrel=gamma_korrel, v=v, theta=theta, eta=eta, g=g, + gamma_water=gamma_water)[2] + + +MODEL_NAMES = { + calc_Z_h.__name__: "Heave", + calc_Z_u.__name__: "Uplift", + calc_Z_p.__name__: "Piping", +} diff --git a/geoprob_pipe/calculations/systems/model4a/reliability_calculation.py b/geoprob_pipe/calculations/systems/model4a/reliability_calculation.py new file mode 100644 index 00000000..9468fa8d --- /dev/null +++ b/geoprob_pipe/calculations/systems/model4a/reliability_calculation.py @@ -0,0 +1,28 @@ +from geoprob_pipe.calculations.systems.model4a.limit_state_functions import ( + limit_state_model4a, calc_Z_h, calc_Z_p, calc_Z_u) +from geoprob_pipe.calculations.systems.base_objects.system_calculation import ( + SystemCalculation) +from typing import List, Dict, Union, Tuple + + +class Model4aCalculation(SystemCalculation): + """ Pre-defined system reliability calculation for Piping. + + Usage by calling the object, inserting the variable distributions and + after that calling the run-method. The separate limit state models + (uplift, heave and piping) are already pre-defined in the class. + """ + + def __init__( + self, + system_variable_distributions: List[Dict], + system_variable_correlations: List[Tuple[str, str, float]] = None, + project_settings: Dict[str, Union[str, float, int]] = None + ): + + super().__init__( + distributions=system_variable_distributions, + project_settings=project_settings, + correlations=system_variable_correlations) + self.given_variables_setup_function = limit_state_model4a + self.given_limit_states = [calc_Z_u, calc_Z_h, calc_Z_p] diff --git a/geoprob_pipe/calculations/systems/model4a/system_builder.py b/geoprob_pipe/calculations/systems/model4a/system_builder.py new file mode 100644 index 00000000..c1395495 --- /dev/null +++ b/geoprob_pipe/calculations/systems/model4a/system_builder.py @@ -0,0 +1,15 @@ +from __future__ import annotations +from geoprob_pipe.calculations.systems.base_objects.base_system_build import ( + BaseSystemBuilder) +from geoprob_pipe.calculations.systems.model4a.reliability_calculation import ( + Model4aCalculation) + + +class Model4aSystemBuilder(BaseSystemBuilder): + + def __init__(self, + geopackage_filepath: str, + to_run_vakken_ids: list[int]): + super().__init__(geopackage_filepath=geopackage_filepath, + to_run_vakken_ids=to_run_vakken_ids) + self.system_class = Model4aCalculation diff --git a/geoprob_pipe/calculations/systems/moria/__init__.py b/geoprob_pipe/calculations/systems/moria/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/geoprob_pipe/calculations/systems/moria/initial_input.py b/geoprob_pipe/calculations/systems/moria/initial_input.py new file mode 100644 index 00000000..215c0d1c --- /dev/null +++ b/geoprob_pipe/calculations/systems/moria/initial_input.py @@ -0,0 +1,291 @@ +from probabilistic_library import DistributionType + + +INITIAL_INPUT = [ + { + "name": "L_intrede", + "description": "TODO", # TODO + "remark": "", + "unit": "m", + "distribution_type": DistributionType.deterministic, # TODO + "mean": 150.0, # TODO + "source": "spatial", # TODO + }, + { + "name": "L_but", + "description": "TODO", # TODO + "remark": "", + "unit": "m", + "distribution_type": DistributionType.deterministic, # TODO + "mean": 150.0, # TODO + "source": "spatial", # TODO + }, + { + "name": "polderpeil", + "description": "Polderpeil ter plaatse van uittredepunten.", + "remark": "", + "unit": "m+NAP", + "distribution_type": DistributionType.deterministic, + "mean": 0.0, + "source": "spatial", + }, + { + "name": "buitenwaterstand", + "description": "Buitenwaterstand. Indien keuze voor 'cdf_curve' als distributie type, dan wordt er een " + "een overschrijdingsfrequentielijn berekend met de Hydra-NL Python wrapper Pydra.", + "remark": "", + "unit": "m+NAP", + "distribution_type": DistributionType.deterministic, + "mean": 5.0, + "source": "excel", + }, + { + "name": "buitenwaterstand_gemiddeld", + "description": "TODO", # TODO + "remark": "", + "unit": "m+NAP", + "distribution_type": DistributionType.deterministic, # TODO + "mean": 5.0, # TODO + "source": "excel", # TODO + }, + { + "name": "mv_exit", + "description": "Bodemhoogte ter plaatse van uittredepunten.", + "remark": "", + "unit": "m+NAP", + "distribution_type": DistributionType.deterministic, + "mean": 0.5, + "source": "spatial", + }, + { + "name": "lambda_voorland", + "description": "", # TODO + "remark": "", # TODO + "unit": "", # TODO + "distribution_type": DistributionType.deterministic, # TODO + "mean": 50, # TODO + "source": "spatial", # TODO + }, + { + "name": "top_zand", + "description": "Geschematiseerde top van het zand in het vak.", + "remark": "", + "unit": "m+NAP", + "distribution_type": DistributionType.normal, + "mean": -3.0, + "deviation": 0.5, + "source": "excel", + }, + { + "name": "phi_exit_gemiddeld", + "description": "TODO", # TODO + "remark": "", + "unit": "m+NAP", # TODO + "distribution_type": DistributionType.normal, # TODO + "mean": -3.0, # TODO + "deviation": 0.5, # TODO + "source": "excel", # TODO + }, + { + "name": "r_exit", + "description": "TODO", # TODO + "remark": "", + "unit": "-", # TODO + "distribution_type": DistributionType.normal, # TODO + "mean": -0.5, # TODO + "deviation": 0.05, # TODO + "source": "excel", # TODO + }, + { + "name": "k_wvp", + "description": "", # TODO + "remark": "", # TODO + "unit": "m/dag", + "distribution_type": DistributionType.log_normal, # TODO + "mean": 45.0, + "variation": 0.35, + "source": "excel", # TODO + }, + { + "name": "modelfactor_h", + "description": "Modelfactor voor heave.", + "remark": "", + "unit": "[-]", + "distribution_type": DistributionType.log_normal, + "mean": 1.0, + "variation": 0.1, + "source": "excel", + }, + { + "name": "modelfactor_ff", + "description": "Modelfactor voor fijne fractie.", + "remark": "", + "unit": "[-]", + "distribution_type": DistributionType.log_normal, # TODO + "mean": 1.0, # TODO + "variation": 0.1, # TODO + "source": "excel", # TODO + }, + { + "name": "modelfactor_3d", + "description": "Modelfactor voor 3D effecten.", + "remark": "", + "unit": "[-]", + "distribution_type": DistributionType.log_normal, # TODO + "mean": 1.0, # TODO + "variation": 0.1, # TODO + "source": "excel", # TODO + }, + { + "name": "modelfactor_aniso", + "description": "Modelfactor voor anisotropie.", + "remark": "", + "unit": "[-]", + "distribution_type": DistributionType.log_normal, # TODO + "mean": 1.0, # TODO + "variation": 0.1, # TODO + "source": "excel", # TODO + }, + { + "name": "modelfactor_ml", + "description": "Modelfactor voor meerlaagsheid zandpakket.", + "remark": "", + "unit": "[-]", + "distribution_type": DistributionType.log_normal, # TODO + "mean": 1.0, # TODO + "variation": 0.1, # TODO + "source": "excel", # TODO + }, + { + "name": "i_c_h", + "description": "Kritieke heave gradiënt.", + "remark": "", + "unit": "[-]", + "distribution_type": DistributionType.log_normal, + "mean": 0.7, + "variation": 0.15, + "source": "excel", + }, + { + "name": "D_wvp", + "description": "Dikte van het watervoerende pakket.", + "remark": "", + "unit": "m", + "distribution_type": DistributionType.log_normal, + "mean": 50, + "deviation": 1.5, + "source": "excel", + }, + { + "name": "modelfactor_u", + "description": "Modelfactor voor uplift.", + "remark": "", + "unit": "[-]", + "distribution_type": DistributionType.log_normal, + "mean": 1.0, + "variation": 0.1, + "source": "excel", + }, + { + "name": "gamma_water", + "description": "Volumegewicht van water.", + "remark": "", + "unit": "kN/m³", + "distribution_type": DistributionType.deterministic, + "mean": 9.81, + "source": "excel", + }, + { + "name": "gamma_sat_deklaag", + "description": "Gemiddeld volumegewicht van de deklaag.", + "remark": "", + "unit": "kN/m³", + "distribution_type": DistributionType.log_normal, + "mean": 13.9, + "variation": 0.05, + "source": "excel", + }, + { + "name": "modelfactor_p", + "description": "Modelfactor voor piping.", + "remark": "", + "unit": "[-]", + "distribution_type": DistributionType.log_normal, + "mean": 1.0, + "variation": 0.1, + "source": "excel", + }, + { + "name": "d70", + "description": "70% percentiel van de korrelverdeling.", + "remark": "", + "unit": "m", + "distribution_type": DistributionType.log_normal, + "mean": 2.8e-4, + "variation": 0.15, + "source": "excel", + }, + { + "name": "g", + "description": "Zwaartekrachtversnelling.", + "remark": "", + "unit": "m/s²", + "distribution_type": DistributionType.deterministic, + "mean": 9.81, + "source": "excel", + }, + { + "name": "v", + "description": "Kinematische viscositeit – Sellmeijer.", + "remark": "", + "unit": "m²/s", + "distribution_type": DistributionType.deterministic, + "mean": 0.00000133, + "source": "excel", + }, + { + "name": "theta", + "description": "Rolweerstandshoek – Sellmeijer.", + "remark": "", + "unit": "graden", + "distribution_type": DistributionType.deterministic, + "mean": 37.0, + "source": "excel", + }, + { + "name": "eta", + "description": "White's weerstandscoëfficiënt (sleepkrachtfactor, constante van White) – Sellmeijer", + "remark": "", + "unit": "[-]", + "distribution_type": DistributionType.deterministic, + "mean": 0.25, + "source": "excel", + }, + { + "name": "d70_m", + "description": "Referentiewaarde voor de 70% percentiel van de korrelverdeling – Sellmeijer.", + "remark": "", + "unit": "m", + "distribution_type": DistributionType.deterministic, + "mean": 2.08e-4, + "source": "excel", + }, + { + "name": "gamma_korrel", + "description": "Volumieke dichtheid zand onder water – Sellmeijer.", + "remark": "", + "unit": "kN/m³", + "distribution_type": DistributionType.deterministic, + "mean": 16.5, + "source": "excel", + }, + { + "name": "r_c_deklaag", + "description": "Reductie constante van het verval over de deklaag.", + "remark": "", + "unit": "[-]", + "distribution_type": DistributionType.deterministic, + "mean": 0.3, + "source": "excel", + }, +] diff --git a/geoprob_pipe/calculations/systems/moria/limit_state_functions.py b/geoprob_pipe/calculations/systems/moria/limit_state_functions.py new file mode 100644 index 00000000..2c83f3b7 --- /dev/null +++ b/geoprob_pipe/calculations/systems/moria/limit_state_functions.py @@ -0,0 +1,141 @@ +from geoprob_pipe.calculations.limit_states.piping_lm import limit_state_moria as system_variable_setup + + +# noinspection PyPep8Naming +def calc_Z_u( + # Geometry parameters + L_intrede: float, L_but: float, + # Boundary condition parameters + buitenwaterstand: float, buitenwaterstand_gemiddeld: float, polderpeil: float, mv_exit: float, + # Subsoil property parameters + lambda_voorland: float, phi_exit_gemiddeld: float, top_zand: float, r_exit: float, k_wvp: float, D_wvp: float, + d70: float, gamma_sat_deklaag: float, + # Model property parameters + modelfactor_u: float, modelfactor_h: float, modelfactor_p: float, modelfactor_ff: float, modelfactor_3d: float, + modelfactor_aniso: float, modelfactor_ml: float, i_c_h: float, r_c_deklaag: float, + # Overige parameters + gamma_water: float, + # Constants # TODO: Ombouwen tot globals + d70_m: float, gamma_korrel: float, v: float, theta: float, eta: float, g: float +) -> float: + r"""Grenstoestandfunctie voor opbarsten (uplift). + + Returns: + float: Z waarde van de grenstoestandfunctie voor opbarsten + """ + return system_variable_setup( + buitenwaterstand=buitenwaterstand, buitenwaterstand_gemiddeld=buitenwaterstand_gemiddeld, polderpeil=polderpeil, + mv_exit=mv_exit, top_zand=top_zand, r_exit=r_exit, k_wvp=k_wvp, D_wvp=D_wvp, d70=d70, + gamma_sat_deklaag=gamma_sat_deklaag, modelfactor_u=modelfactor_u, modelfactor_h=modelfactor_h, + modelfactor_p=modelfactor_p, modelfactor_ff=modelfactor_ff, modelfactor_3d=modelfactor_3d, + modelfactor_aniso=modelfactor_aniso, modelfactor_ml=modelfactor_ml, i_c_h=i_c_h, r_c_deklaag=r_c_deklaag, + gamma_water=gamma_water, d70_m=d70_m, gamma_korrel=gamma_korrel, v=v, theta=theta, eta=eta, g=g, + L_intrede=L_intrede, L_but=L_but, lambda_voorland=lambda_voorland, phi_exit_gemiddeld=phi_exit_gemiddeld + )[0] + + +# noinspection PyPep8Naming +def calc_Z_h( + # Geometry parameters + L_intrede: float, L_but: float, + # Boundary condition parameters + buitenwaterstand: float, buitenwaterstand_gemiddeld: float, polderpeil: float, mv_exit: float, + # Subsoil property parameters + lambda_voorland: float, phi_exit_gemiddeld: float, top_zand: float, r_exit: float, k_wvp: float, D_wvp: float, + d70: float, gamma_sat_deklaag: float, + # Model property parameters + modelfactor_u: float, modelfactor_h: float, modelfactor_p: float, modelfactor_ff: float, modelfactor_3d: float, + modelfactor_aniso: float, modelfactor_ml: float, i_c_h: float, r_c_deklaag: float, + # Overige parameters + gamma_water: float, + # Constants # TODO: Ombouwen tot globals + d70_m: float, gamma_korrel: float, v: float, theta: float, eta: float, g: float +) -> float: + r""" Wrapper over de grenstoestandfunctie voor heave zodat deze bruikbaar is voor de Probabilistic Library. + + Returns: + float: Z waarde van de grenstoestandfunctie voor heave + """ + return system_variable_setup( + buitenwaterstand=buitenwaterstand, buitenwaterstand_gemiddeld=buitenwaterstand_gemiddeld, polderpeil=polderpeil, + mv_exit=mv_exit, top_zand=top_zand, r_exit=r_exit, k_wvp=k_wvp, D_wvp=D_wvp, d70=d70, + gamma_sat_deklaag=gamma_sat_deklaag, modelfactor_u=modelfactor_u, modelfactor_h=modelfactor_h, + modelfactor_p=modelfactor_p, modelfactor_ff=modelfactor_ff, modelfactor_3d=modelfactor_3d, + modelfactor_aniso=modelfactor_aniso, modelfactor_ml=modelfactor_ml, i_c_h=i_c_h, r_c_deklaag=r_c_deklaag, + gamma_water=gamma_water, d70_m=d70_m, gamma_korrel=gamma_korrel, v=v, theta=theta, eta=eta, g=g, + L_intrede=L_intrede, L_but=L_but, lambda_voorland=lambda_voorland, phi_exit_gemiddeld=phi_exit_gemiddeld + )[1] + + +# noinspection PyPep8Naming +def calc_Z_p( + # Geometry parameters + L_intrede: float, L_but: float, + # Boundary condition parameters + buitenwaterstand: float, buitenwaterstand_gemiddeld: float, polderpeil: float, mv_exit: float, + # Subsoil property parameters + lambda_voorland: float, phi_exit_gemiddeld: float, top_zand: float, r_exit: float, k_wvp: float, D_wvp: float, + d70: float, gamma_sat_deklaag: float, + # Model property parameters + modelfactor_u: float, modelfactor_h: float, modelfactor_p: float, modelfactor_ff: float, modelfactor_3d: float, + modelfactor_aniso: float, modelfactor_ml: float, i_c_h: float, r_c_deklaag: float, + # Overige parameters + gamma_water: float, + # Constants # TODO: Ombouwen tot globals + d70_m: float, gamma_korrel: float, v: float, theta: float, eta: float, g: float +) -> float: + r"""Grenstoestandfunctie voor het mechanisme piping + + Returns: + float: Z waarde van de grenstoestandfunctie voor piping + """ + return system_variable_setup( + buitenwaterstand=buitenwaterstand, buitenwaterstand_gemiddeld=buitenwaterstand_gemiddeld, polderpeil=polderpeil, + mv_exit=mv_exit, top_zand=top_zand, r_exit=r_exit, k_wvp=k_wvp, D_wvp=D_wvp, d70=d70, + gamma_sat_deklaag=gamma_sat_deklaag, modelfactor_u=modelfactor_u, modelfactor_h=modelfactor_h, + modelfactor_p=modelfactor_p, modelfactor_ff=modelfactor_ff, modelfactor_3d=modelfactor_3d, + modelfactor_aniso=modelfactor_aniso, modelfactor_ml=modelfactor_ml, i_c_h=i_c_h, r_c_deklaag=r_c_deklaag, + gamma_water=gamma_water, d70_m=d70_m, gamma_korrel=gamma_korrel, v=v, theta=theta, eta=eta, g=g, + L_intrede=L_intrede, L_but=L_but, lambda_voorland=lambda_voorland, phi_exit_gemiddeld=phi_exit_gemiddeld + )[2] + + +# noinspection PyPep8Naming +# def calc_Z_combin( +# # Geometry parameters +# L_intrede: float, L_but: float, +# # Boundary condition parameters +# buitenwaterstand: float, buitenwaterstand_gemiddeld: float, polderpeil: float, mv_exit: float, +# # Subsoil property parameters +# lambda_voorland: float, phi_exit_gemiddeld: float, top_zand: float, r_exit: float, k_wvp: float, D_wvp: float, +# d70: float, gamma_sat_deklaag: float, +# # Model property parameters +# modelfactor_u: float, modelfactor_h: float, modelfactor_p: float, modelfactor_ff: float, modelfactor_3d: float, +# modelfactor_aniso: float, modelfactor_ml: float, i_c_h: float, r_c_deklaag: float, +# # Overige parameters +# gamma_water: float, +# # Constants # TODO: Ombouwen tot globals +# d70_m: float, gamma_korrel: float, v: float, theta: float, eta: float, g: float +# ) -> float: +# r"""Grenstoestandfunctie voor het mechanisme piping +# +# Returns: +# float: Z waarde van de grenstoestandfunctie voor piping +# """ +# return system_variable_setup( +# buitenwaterstand=buitenwaterstand, buitenwaterstand_gemiddeld=buitenwaterstand_gemiddeld, polderpeil=polderpeil, +# mv_exit=mv_exit, top_zand=top_zand, r_exit=r_exit, k_wvp=k_wvp, D_wvp=D_wvp, d70=d70, +# gamma_sat_deklaag=gamma_sat_deklaag, modelfactor_u=modelfactor_u, modelfactor_h=modelfactor_h, +# modelfactor_p=modelfactor_p, modelfactor_ff=modelfactor_ff, modelfactor_3d=modelfactor_3d, +# modelfactor_aniso=modelfactor_aniso, modelfactor_ml=modelfactor_ml, i_c_h=i_c_h, r_c_deklaag=r_c_deklaag, +# gamma_water=gamma_water, d70_m=d70_m, gamma_korrel=gamma_korrel, v=v, theta=theta, eta=eta, g=g, +# L_intrede=L_intrede, L_but=L_but, lambda_voorland=lambda_voorland, phi_exit_gemiddeld=phi_exit_gemiddeld +# )[3] + + +MODEL_NAMES = { + calc_Z_u.__name__: "Uplift", + calc_Z_h.__name__: "Heave", + calc_Z_p.__name__: "Piping", + # calc_Z_combin.__name__: "Combin", +} diff --git a/geoprob_pipe/calculations/systems/moria/reliability_calculation.py b/geoprob_pipe/calculations/systems/moria/reliability_calculation.py new file mode 100644 index 00000000..a516d40a --- /dev/null +++ b/geoprob_pipe/calculations/systems/moria/reliability_calculation.py @@ -0,0 +1,25 @@ +from geoprob_pipe.calculations.systems.moria.limit_state_functions import ( + system_variable_setup, calc_Z_h, calc_Z_p, calc_Z_u) +from geoprob_pipe.calculations.systems.base_objects.system_calculation import ( + SystemCalculation) +from typing import List, Dict, Union, Tuple + + +class MORIACalculation(SystemCalculation): + """ Vooraf gedefinieerde System Reliability Calculation voor piping met het WBI-stijghoogtemodel. """ + + def __init__( + self, + system_variable_distributions: List[Dict], + system_variable_correlations: List[Tuple[str, str, float]] = None, + project_settings: Dict[str, Union[str, float, int]] = None + ): + + super().__init__( + distributions=system_variable_distributions, project_settings=project_settings, + correlations=system_variable_correlations + + ) + self.given_variables_setup_function = system_variable_setup + self.given_limit_states = [calc_Z_u, calc_Z_h, calc_Z_p] + # self.given_combin_limit_state = calc_Z_combin diff --git a/geoprob_pipe/calculations/systems/moria/system_builder.py b/geoprob_pipe/calculations/systems/moria/system_builder.py new file mode 100644 index 00000000..c1fe1161 --- /dev/null +++ b/geoprob_pipe/calculations/systems/moria/system_builder.py @@ -0,0 +1,17 @@ +from __future__ import annotations +from geoprob_pipe.calculations.systems.moria.reliability_calculation import \ + MORIACalculation +from geoprob_pipe.calculations.systems.base_objects.base_system_build import BaseSystemBuilder +# from typing import TYPE_CHECKING +# if TYPE_CHECKING: +# from geoprob_pipe import GeoProbPipe + + +class MoriaSystemBuilder(BaseSystemBuilder): + + def __init__(self, + geopackage_filepath: str, + to_run_vakken_ids: list[int]): + super().__init__(geopackage_filepath=geopackage_filepath, + to_run_vakken_ids=to_run_vakken_ids) + self.system_class = MORIACalculation diff --git a/geoprob_pipe/calculations/systems/single_calc.py b/geoprob_pipe/calculations/systems/single_calc.py new file mode 100644 index 00000000..268eefce --- /dev/null +++ b/geoprob_pipe/calculations/systems/single_calc.py @@ -0,0 +1,77 @@ +from __future__ import annotations +import sqlite3 +from geoprob_pipe.calculations.systems.mappers.calculation_mapper\ + import CALCULATION_MAPPER +from typing import TYPE_CHECKING +if TYPE_CHECKING: + from geoprob_pipe.calculations.systems.base_objects\ + .base_system_build import BaseSystemBuilder + from geoprob_pipe.calculations.systems.base_objects\ + .system_calculation import SystemCalculation + + +EXAMPLE_SCRIPT_REPRODUCING_SINGLE_CALCULATION = r""" +from geoprob_pipe import ( + reproduce_single_calculation, ParallelSystemReliabilityCalculation) + +calc: ParallelSystemReliabilityCalculation = reproduce_single_calculation( + geopackage_filepath=r"/pad/naar/het/bestand/geoprob_pipe.gpkg", + uittredepunt_id=1234, # Replace with id of interest + ondergrondscenario_naam="PL", # Replace with scenario name of interest +) +""" + + +EXPLANATION_REPRODUCING_SINGLE_CALCULATION = """ +Met de onderstaande code kun je in de Python console een enkele berekening +reproduceren en inspecteren. Dit is bijvoorbeeld handig wanneer je de Python +objecten wilt vergelijken met de gegenereerde in- en uitvoer. Of wanneer je een +vergelijk maakt met de PTK-tool. + +Om dit te doen kopieer je de onderstaande code naar de Python console. +Zorg er voor dat je de Python console gebruikt waarin je GeoProb-Pipe +ook hebt geïnstalleerd. Vervang eveneens het uittredepunt id met het id +wat je wilt bekijken. Hetzelfde doe je voor de ondergrondscenario_naam. + +Het reproduceren en herberekenen duurt slechts enkele seconden. Daarna +kun je de objecten inspecteren. + +Let op: Deze feature vergt enige ervaring met Python. +""" + + +def reproduce_single_calculation( + geopackage_filepath: str, + uittredepunt_id: int, + ondergrondscenario_naam: str, + ) -> SystemCalculation: + + # Fetch geohydrological model + conn = sqlite3.connect(geopackage_filepath) + cursor = conn.cursor() + cursor.execute( + 'SELECT "values" FROM geoprob_pipe_metadata WHERE metadata_type = ?', + ("geohydrologisch_model",)) + geohydrologisch_model: str = cursor.fetchone()[0] + + # Fetch vak id + cursor.execute( + 'SELECT vak_id FROM uittredepunten WHERE uittredepunt_id = ?', + (uittredepunt_id,)) + vak_id: int = int(cursor.fetchone()[0]) + conn.close() + + # Construct calculation builder + builder: BaseSystemBuilder = ( + CALCULATION_MAPPER[geohydrologisch_model]["system_builder"]( + geopackage_filepath=geopackage_filepath, + to_run_vakken_ids=None)) + + # Construct calculation + row = {"uittredepunt_id": uittredepunt_id, + "ondergrondscenario_naam": ondergrondscenario_naam, + "vak_id": vak_id} + calc = builder.build_instance(row_unique=row) + calc.run() + + return calc diff --git a/geoprob_pipe/calculations/systems/wbi/__init__.py b/geoprob_pipe/calculations/systems/wbi/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/geoprob_pipe/calculations/systems/wbi/initial_input.py b/geoprob_pipe/calculations/systems/wbi/initial_input.py new file mode 100644 index 00000000..d3285ac1 --- /dev/null +++ b/geoprob_pipe/calculations/systems/wbi/initial_input.py @@ -0,0 +1,254 @@ +from probabilistic_library import DistributionType + + +INITIAL_INPUT = [ + { + "name": "L_kwelweg", + "description": "TODO", # TODO + "remark": "", + "unit": "m", + "distribution_type": DistributionType.deterministic, # TODO + "mean": 150.0, # TODO + "source": "spatial", # TODO + }, + { + "name": "polderpeil", + "description": "Polderpeil ter plaatse van uittredepunten.", + "remark": "", + "unit": "m+NAP", + "distribution_type": DistributionType.deterministic, + "mean": 0.0, + "source": "spatial", + }, + { + "name": "buitenwaterstand", + "description": "Buitenwaterstand. Indien keuze voor 'cdf_curve' als distributie type, dan wordt er een " + "een overschrijdingsfrequentielijn berekend met de Hydra-NL Python wrapper Pydra.", + "remark": "", + "unit": "m+NAP", + "distribution_type": DistributionType.deterministic, + "mean": 5.0, + "source": "excel", + }, + { + "name": "mv_exit", + "description": "Bodemhoogte ter plaatse van uittredepunten.", + "remark": "", + "unit": "m+NAP", + "distribution_type": DistributionType.deterministic, + "mean": 0.5, + "source": "spatial", + }, + { + "name": "top_zand", + "description": "Geschematiseerde top van het zand in het vak.", + "remark": "", + "unit": "m+NAP", + "distribution_type": DistributionType.normal, + "mean": -3.0, + "deviation": 0.5, + "source": "excel", + }, + { + "name": "r_exit", + "description": "TODO", # TODO + "remark": "", + "unit": "-", # TODO + "distribution_type": DistributionType.normal, # TODO + "mean": -0.5, # TODO + "deviation": 0.05, # TODO + "source": "excel", # TODO + }, + { + "name": "k_wvp", + "description": "", # TODO + "remark": "", # TODO + "unit": "", # TODO + "distribution_type": DistributionType.log_normal, # TODO + "mean": 2000.0, # TODO + "variation": 0.35, # TODO + "source": "excel", # TODO + }, + { + "name": "modelfactor_h", + "description": "Modelfactor voor heave.", + "remark": "", + "unit": "[-]", + "distribution_type": DistributionType.log_normal, + "mean": 1.0, + "variation": 0.1, + "source": "excel", + }, + { + "name": "modelfactor_ff", + "description": "Modelfactor voor fijne fractie.", + "remark": "", + "unit": "[-]", + "distribution_type": DistributionType.log_normal, # TODO + "mean": 1.0, # TODO + "variation": 0.1, # TODO + "source": "excel", # TODO + }, + { + "name": "modelfactor_3d", + "description": "Modelfactor voor 3D effecten.", + "remark": "", + "unit": "[-]", + "distribution_type": DistributionType.log_normal, # TODO + "mean": 1.0, # TODO + "variation": 0.1, # TODO + "source": "excel", # TODO + }, + { + "name": "modelfactor_aniso", + "description": "Modelfactor voor anisotropie.", + "remark": "", + "unit": "[-]", + "distribution_type": DistributionType.log_normal, # TODO + "mean": 1.0, # TODO + "variation": 0.1, # TODO + "source": "excel", # TODO + }, + { + "name": "modelfactor_ml", + "description": "Modelfactor voor meerlaagsheid zandpakket.", + "remark": "", + "unit": "[-]", + "distribution_type": DistributionType.log_normal, # TODO + "mean": 1.0, # TODO + "variation": 0.1, # TODO + "source": "excel", # TODO + }, + { + "name": "i_c_h", + "description": "Kritieke heave gradiënt.", + "remark": "", + "unit": "[-]", + "distribution_type": DistributionType.log_normal, + "mean": 0.7, + "variation": 0.15, + "source": "excel", + }, + { + "name": "D_wvp", + "description": "Dikte van het watervoerende pakket.", + "remark": "", + "unit": "m", + "distribution_type": DistributionType.log_normal, + "mean": 50, + "deviation": 1.5, + "source": "excel", + }, + { + "name": "modelfactor_u", + "description": "Modelfactor voor uplift.", + "remark": "", + "unit": "[-]", + "distribution_type": DistributionType.log_normal, + "mean": 1.0, + "variation": 0.1, + "source": "excel", + }, + { + "name": "gamma_water", + "description": "Volumegewicht van water.", + "remark": "", + "unit": "kN/m³", + "distribution_type": DistributionType.deterministic, + "mean": 9.81, + "source": "excel", + }, + { + "name": "gamma_sat_deklaag", + "description": "Gemiddeld volumegewicht van de deklaag.", + "remark": "", + "unit": "kN/m³", + "distribution_type": DistributionType.log_normal, + "mean": 13.9, + "variation": 0.05, + "source": "excel", + }, + { + "name": "modelfactor_p", + "description": "Modelfactor voor piping.", + "remark": "", + "unit": "[-]", + "distribution_type": DistributionType.log_normal, + "mean": 1.0, + "variation": 0.1, + "source": "excel", + }, + { + "name": "d70", + "description": "70% percentiel van de korrelverdeling.", + "remark": "", + "unit": "m", + "distribution_type": DistributionType.log_normal, + "mean": 2.8e-4, + "variation": 0.15, + "source": "excel", + }, + { + "name": "g", + "description": "Zwaartekrachtversnelling.", + "remark": "", + "unit": "m/s²", + "distribution_type": DistributionType.deterministic, + "mean": 9.81, + "source": "excel", + }, + { + "name": "v", + "description": "Kinematische viscositeit – Sellmeijer.", + "remark": "", + "unit": "m²/s", + "distribution_type": DistributionType.deterministic, + "mean": 0.00000133, + "source": "excel", + }, + { + "name": "theta", + "description": "Rolweerstandshoek – Sellmeijer.", + "remark": "", + "unit": "graden", + "distribution_type": DistributionType.deterministic, + "mean": 37.0, + "source": "excel", + }, + { + "name": "eta", + "description": "White's weerstandscoëfficiënt (sleepkrachtfactor, constante van White) – Sellmeijer", + "remark": "", + "unit": "[-]", + "distribution_type": DistributionType.deterministic, + "mean": 0.25, + "source": "excel", + }, + { + "name": "d70_m", + "description": "Referentiewaarde voor de 70% percentiel van de korrelverdeling – Sellmeijer.", + "remark": "", + "unit": "m", + "distribution_type": DistributionType.deterministic, + "mean": 2.08e-4, + "source": "excel", + }, + { + "name": "gamma_korrel", + "description": "Volumieke dichtheid zand onder water – Sellmeijer.", + "remark": "", + "unit": "kN/m³", + "distribution_type": DistributionType.deterministic, + "mean": 16.5, + "source": "excel", + }, + { + "name": "r_c_deklaag", + "description": "Reductie constante van het verval over de deklaag.", + "remark": "", + "unit": "[-]", + "distribution_type": DistributionType.deterministic, + "mean": 0.3, + "source": "excel", + }, +] diff --git a/geoprob_pipe/calculations/systems/wbi/limit_state_functions.py b/geoprob_pipe/calculations/systems/wbi/limit_state_functions.py new file mode 100644 index 00000000..f8f1016f --- /dev/null +++ b/geoprob_pipe/calculations/systems/wbi/limit_state_functions.py @@ -0,0 +1,99 @@ +from geoprob_pipe.calculations.limit_states.piping_lm import limit_state_wbi as system_variable_setup + + +# noinspection PyPep8Naming +def calc_Z_u( + L_kwelweg: float, + # Boundary condition parameters + buitenwaterstand: float, polderpeil: float, mv_exit: float, + # Subsoil property parameters + top_zand: float, r_exit: float, k_wvp: float, D_wvp: float, d70: float, + gamma_sat_deklaag: float, + # Model property parameters + modelfactor_u: float, modelfactor_h: float, modelfactor_p: float, modelfactor_ff: float, modelfactor_3d: float, + modelfactor_aniso: float, modelfactor_ml: float, i_c_h: float, r_c_deklaag: float, + # Overige parameters + gamma_water: float, + # Constants # TODO: Ombouwen tot globals + d70_m: float, gamma_korrel: float, v: float, theta: float, eta: float, g: float +) -> float: + r"""Grenstoestandfunctie voor opbarsten (uplift). + + Returns: + float: Z waarde van de grenstoestandfunctie voor opbarsten + """ + return system_variable_setup( + L_kwelweg=L_kwelweg, buitenwaterstand=buitenwaterstand, polderpeil=polderpeil, mv_exit=mv_exit, + top_zand=top_zand, r_exit=r_exit, k_wvp=k_wvp, D_wvp=D_wvp, d70=d70, gamma_sat_deklaag=gamma_sat_deklaag, + modelfactor_u=modelfactor_u, modelfactor_h=modelfactor_h, modelfactor_p=modelfactor_p, + modelfactor_ff=modelfactor_ff, modelfactor_3d=modelfactor_3d, modelfactor_aniso=modelfactor_aniso, + modelfactor_ml=modelfactor_ml, i_c_h=i_c_h, r_c_deklaag=r_c_deklaag, gamma_water=gamma_water, + d70_m=d70_m, gamma_korrel=gamma_korrel, v=v, theta=theta, eta=eta, g=g, + )[0] + + +# noinspection PyPep8Naming +def calc_Z_h( + L_kwelweg: float, + # Boundary condition parameters + buitenwaterstand: float, polderpeil: float, mv_exit: float, + # Subsoil property parameters + top_zand: float, r_exit: float, k_wvp: float, D_wvp: float, d70: float, gamma_sat_deklaag: float, + # Model property parameters + modelfactor_u: float, modelfactor_h: float, modelfactor_p: float, modelfactor_ff: float, modelfactor_3d: float, + modelfactor_aniso: float, modelfactor_ml: float, i_c_h: float, r_c_deklaag: float, + # Overige parameters + gamma_water: float, + # Constants # TODO: Ombouwen tot globals + d70_m: float, gamma_korrel: float, v: float, theta: float, eta: float, g: float +) -> float: + r""" Wrapper over de grenstoestandfunctie voor heave zodat deze bruikbaar is voor de Probabilistic Library. + + Returns: + float: Z waarde van de grenstoestandfunctie voor heave + """ + return system_variable_setup( + L_kwelweg=L_kwelweg, buitenwaterstand=buitenwaterstand, polderpeil=polderpeil, mv_exit=mv_exit, + top_zand=top_zand, r_exit=r_exit, k_wvp=k_wvp, D_wvp=D_wvp, d70=d70, gamma_sat_deklaag=gamma_sat_deklaag, + modelfactor_u=modelfactor_u, modelfactor_h=modelfactor_h, modelfactor_p=modelfactor_p, + modelfactor_ff=modelfactor_ff, modelfactor_3d=modelfactor_3d, modelfactor_aniso=modelfactor_aniso, + modelfactor_ml=modelfactor_ml, i_c_h=i_c_h, r_c_deklaag=r_c_deklaag, gamma_water=gamma_water, + d70_m=d70_m, gamma_korrel=gamma_korrel, v=v, theta=theta, eta=eta, g=g, + )[1] + + +# noinspection PyPep8Naming +def calc_Z_p( + L_kwelweg: float, + # Boundary condition parameters + buitenwaterstand: float, polderpeil: float, mv_exit: float, + # Subsoil property parameters + top_zand: float, r_exit: float, k_wvp: float, D_wvp: float, d70: float, gamma_sat_deklaag: float, + # Model property parameters + modelfactor_u: float, modelfactor_h: float, modelfactor_p: float, modelfactor_ff: float, modelfactor_3d: float, + modelfactor_aniso: float, modelfactor_ml: float, i_c_h: float, r_c_deklaag: float, + # Overige parameters + gamma_water: float, + # Constants # TODO: Ombouwen tot globals + d70_m: float, gamma_korrel: float, v: float, theta: float, eta: float, g: float +) -> float: + r"""Grenstoestandfunctie voor het mechanisme piping + + Returns: + float: Z waarde van de grenstoestandfunctie voor piping + """ + return system_variable_setup( + L_kwelweg=L_kwelweg, buitenwaterstand=buitenwaterstand, polderpeil=polderpeil, mv_exit=mv_exit, + top_zand=top_zand, r_exit=r_exit, k_wvp=k_wvp, D_wvp=D_wvp, d70=d70, gamma_sat_deklaag=gamma_sat_deklaag, + modelfactor_u=modelfactor_u, modelfactor_h=modelfactor_h, modelfactor_p=modelfactor_p, + modelfactor_ff=modelfactor_ff, modelfactor_3d=modelfactor_3d, modelfactor_aniso=modelfactor_aniso, + modelfactor_ml=modelfactor_ml, i_c_h=i_c_h, r_c_deklaag=r_c_deklaag, gamma_water=gamma_water, + d70_m=d70_m, gamma_korrel=gamma_korrel, v=v, theta=theta, eta=eta, g=g, + )[2] + + +MODEL_NAMES = { + calc_Z_u.__name__: "Uplift", + calc_Z_h.__name__: "Heave", + calc_Z_p.__name__: "Piping", +} diff --git a/geoprob_pipe/calculations/systems/wbi/reliability_calculation.py b/geoprob_pipe/calculations/systems/wbi/reliability_calculation.py new file mode 100644 index 00000000..f7af0c2e --- /dev/null +++ b/geoprob_pipe/calculations/systems/wbi/reliability_calculation.py @@ -0,0 +1,23 @@ +from geoprob_pipe.calculations.systems.wbi.limit_state_functions import ( + system_variable_setup, calc_Z_h, calc_Z_p, calc_Z_u) +from geoprob_pipe.calculations.systems.base_objects.system_calculation import ( + SystemCalculation) +from typing import List, Dict, Union, Tuple + + +class WBICalculation(SystemCalculation): + """ Vooraf gedefinieerde System Reliability Calculation voor piping met het WBI-stijghoogtemodel. """ + + def __init__( + self, + system_variable_distributions: List[Dict], + system_variable_correlations: List[Tuple[str, str, float]] = None, + project_settings: Dict[str, Union[str, float, int]] = None + ): + + super().__init__( + distributions=system_variable_distributions, project_settings=project_settings, + correlations=system_variable_correlations + ) + self.given_variables_setup_function = system_variable_setup + self.given_limit_states = [calc_Z_u, calc_Z_h, calc_Z_p] diff --git a/geoprob_pipe/calculations/systems/wbi/system_builder.py b/geoprob_pipe/calculations/systems/wbi/system_builder.py new file mode 100644 index 00000000..eca97328 --- /dev/null +++ b/geoprob_pipe/calculations/systems/wbi/system_builder.py @@ -0,0 +1,14 @@ +from __future__ import annotations +from geoprob_pipe.calculations.systems.wbi.reliability_calculation import \ + WBICalculation +from geoprob_pipe.calculations.systems.base_objects.base_system_build import BaseSystemBuilder + + +class WBISystemBuilder(BaseSystemBuilder): + + def __init__(self, + geopackage_filepath: str, + to_run_vakken_ids: list[int]): + super().__init__(geopackage_filepath=geopackage_filepath, + to_run_vakken_ids=to_run_vakken_ids) + self.system_class = WBICalculation diff --git a/geoprob_pipe/changelog.py b/geoprob_pipe/changelog.py new file mode 100644 index 00000000..3fd4891f --- /dev/null +++ b/geoprob_pipe/changelog.py @@ -0,0 +1,30 @@ + +CHANGELOG = { + "1.3.1": + "Hotfix. Visualisatie en export issues. Geen issue aan berekeningen " + "zelf. 1e issue: Foute beta waarden in de hover van de " + "betrouwbaarheidsindex.html. 2e issue: De df_limit_states werd " + "geëxporteerd als df_scenarios.", + "1.3.0": + "Probabilistic Library nu toegevoegd als 'setup dependency' nadat " + "Deltares deze heeft vrijgegeven op PyPI. Eveneens Chrome " + "uitgefaseerd als software requirement. Daardoor zijn beiden geen " + "handmatige software requirements meer.", + "1.2.0": + "Implementatie van parallel rekenen en het inspecteren van een enkele " + "berekening.", + "1.1.0": + "Implementatie van een eerste versie van het vergelijken van twee " + "verschillende GeoProb-Pipe bestanden.", + "1.0.0": + "Implementatie GeoPackage als data (in- en uitvoer) bestand én " + "implementatie van keuze in geohydrologische modellen.", + "0.1.0": + "Toevoegen features na interne gebruikerssessie WSRL 2025-08-11: (a) " + "geopackage-export met resultaten, (b) Excel-export met physical " + "values, alphas en invloedsfactoren, (c) Excel-export met resultaat " + "per vak, (d) Excel-export met validatie berichten en (e) physical " + "values in grafiek waterstandssfrequentielijn.", + "0.0.15": + "Eerste vrijgave van wheel installatie-bestand.", +} diff --git a/geoprob_pipe/cmd_app/README.md b/geoprob_pipe/cmd_app/README.md new file mode 100644 index 00000000..6303ea0c --- /dev/null +++ b/geoprob_pipe/cmd_app/README.md @@ -0,0 +1,3 @@ +Run command line tool with the following command: + +```python -m geoprob_pipe.cmd_app.cmd startup_geoprob_pipe``` \ No newline at end of file diff --git a/geoprob_pipe/cmd_app/__init__.py b/geoprob_pipe/cmd_app/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/geoprob_pipe/cmd_app/cmd.py b/geoprob_pipe/cmd_app/cmd.py new file mode 100644 index 00000000..4ff01c1f --- /dev/null +++ b/geoprob_pipe/cmd_app/cmd.py @@ -0,0 +1,80 @@ +import typer +from rich.console import Console +import os +from geoprob_pipe.utils import clear_terminal +from datetime import datetime +from rich.panel import Panel +from geoprob_pipe.cmd_app.questionnaire import start_questionnaire +from typing import Optional, List +from geoprob_pipe.cmd_app.utils.misc import get_geoprob_pipe_version_number + + +app = typer.Typer(help="GeoProb-Pipe - CLI applicatie voor probabilistische piping berekeningen.") + + +class ApplicationSettings: + + def __init__(self): + self.workspace_dir: Optional[str] = None + self.geopackage_filename: Optional[str] = None + self.datetime_stamp: str = datetime.now().strftime("%Y-%m-%d_%H%M%S") + self.to_run = "all" + # -> or vakken:1,2,3,4,5 + + @property + def geopackage_filepath(self) -> str: + return os.path.join(self.workspace_dir, self.geopackage_filename) + + @property + def hrd_dir(self): + path_to_hrd_dir = os.path.join(self.workspace_dir, "hrd_files") + os.makedirs(path_to_hrd_dir, exist_ok=True) + return path_to_hrd_dir + + @property + def hrd_file_path(self) -> str: + for file in os.listdir(self.hrd_dir): + filename = os.fsdecode(file) + if filename.endswith(".config.sqlite"): + continue + if filename.endswith("hlcd.sqlite"): + continue + return os.path.join(self.hrd_dir, filename) + raise ValueError + + @property + def ahn_filepath(self) -> str: + return os.path.join(self.workspace_dir, "ahn", "ahn.tif") + + @property + def to_run_vakken_ids(self) -> Optional[List[int]]: + if self.to_run == "all": + return None + vak_ids_str: List[str] = self.to_run.replace("vakken:", "").split(sep=",") + return [int(vak_id_str) for vak_id_str in vak_ids_str] + + +@app.command() +def startup_geoprob_pipe(): + """ Starts up the GeoProb-Pipe console application. """ + clear_terminal() + + console = Console() + console.print(Panel( + """ +Welkom bij GeoProb-Pipe! Deze applicatie voert probabilistische pipingberekeningen uit met de uittredepuntenmethode en +een geohydrologisch model naar keuze (zoals model4a). GeoProb-Pipe maakt gebruik van de probabilistische bibliotheek +van Deltares, die onder de motorkap de PTK-tool aanstuurt. Met de onderstaande interactieve vragenmodule neemt +GeoProb-Pipe je stap voor stap mee door het opzetten van de invoer en het uitvoeren van de berekeningen. +""", + title=f"GeoProb-Pipe ({get_geoprob_pipe_version_number()})".upper(), + title_align="left", + border_style="bright_blue", + padding=(0, 2), + )) + + start_questionnaire(ApplicationSettings()) + + +if __name__ == "__main__": + startup_geoprob_pipe() diff --git a/geoprob_pipe/cmd_app/comparisons/__init__.py b/geoprob_pipe/cmd_app/comparisons/__init__.py new file mode 100644 index 00000000..5a185e74 --- /dev/null +++ b/geoprob_pipe/cmd_app/comparisons/__init__.py @@ -0,0 +1,120 @@ +from __future__ import annotations +import sqlite3 +import os +from datetime import datetime +import pandas as pd +import geopandas as gpd +from plotly.graph_objects import Figure as PlotlyFigure +from geoprob_pipe.cmd_app.comparisons.beta_dumbbell import \ + dumbbell_beta, dumbbell_uplift, dumbbell_heave, dumbbell_piping +from geoprob_pipe.cmd_app.comparisons.beta_map import map_delta_beta_comparison, \ + map_ratio_beta_comparison + + +class ComparisonCollector: + def __init__(self, + geopackage_filepath_1: str, + geopackage_filepath_2: str, + export_dir: str + ): + self.geopackage_filepath_1 = geopackage_filepath_1 + self.geopackage_filepath_2 = geopackage_filepath_2 + self.name_1 = self.geopackage_filepath_1.split("\\")[-1].split(".")[0] + self.name_2 = self.geopackage_filepath_2.split("\\")[-1].split(".")[0] + + timestamp = datetime.now().strftime("%Y-%m-%d_%H%M") + self.export_dir = os.path.join( + export_dir, f"comparisons/{self.name_1}_{self.name_2}_{timestamp}" + ) + os.makedirs(export_dir, exist_ok=True) + + # Placeholders + self.df1_beta_scenarios: pd.DataFrame + self.df1_beta_limit_states: pd.DataFrame + self.df1_beta_uittredepunten: pd.DataFrame + + self.df2_beta_scenarios: pd.DataFrame + self.df2_beta_limit_states: pd.DataFrame + self.df2_beta_uittredepunten: pd.DataFrame + + self.gdf1_uittredepunten: gpd.GeoDataFrame + self.gdf2_uittredepunten: gpd.GeoDataFrame + + # logic + self._load_result_data_from_geopackage() + self._load_uittredepunten_gdf() + + def _load_result_data_from_geopackage(self): + + conn_1 = sqlite3.connect(self.geopackage_filepath_1) + conn_2 = sqlite3.connect(self.geopackage_filepath_2) + + self.df1_beta_limit_states = pd.read_sql( + "SELECT * FROM beta_limit_states;", conn_1 + ) + self.df2_beta_limit_states = pd.read_sql( + "SELECT * FROM beta_limit_states;", conn_2 + ) + if len(self.df1_beta_limit_states) != len(self.df2_beta_limit_states): + raise ValueError("De beta_limit_states tables hebben niet hetzelfde formaat") + + self.df1_beta_scenarios = pd.read_sql( + "SELECT * FROM beta_scenarios;", conn_1 + ) + self.df2_beta_scenarios = pd.read_sql( + "SELECT * FROM beta_scenarios;", conn_2 + ) + if len(self.df1_beta_scenarios) != len(self.df2_beta_scenarios): + raise ValueError("De beta_scenario tables hebben niet hetzelfde formaat") + + self.df1_beta_uittredepunten = pd.read_sql( + "SELECT * FROM beta_uittredepunten;", conn_1 + ) + self.df2_beta_uittredepunten = pd.read_sql( + "SELECT * FROM beta_uittredepunten;", conn_2 + ) + if len(self.df1_beta_uittredepunten) != len(self.df2_beta_uittredepunten): + raise ValueError("De beta_uittredepunten tables hebben niet hetzelfde formaat") + + conn_1.close() + conn_2.close() + + def _load_uittredepunten_gdf(self): + self.gdf1_uittredepunten = gpd.read_file( + self.geopackage_filepath_1, + layer="beta_uittredepunten" + ) + self.gdf2_uittredepunten = gpd.read_file( + self.geopackage_filepath_2, + layer="beta_uittredepunten" + ) + if len(self.gdf1_uittredepunten) != len(self.gdf2_uittredepunten): + raise ValueError("De beta_uittredepunten tables hebben niet hetzelfde formaat") + if set(self.gdf1_uittredepunten.geometry) != set(self.gdf2_uittredepunten.geometry): + raise ValueError("De twee sets uittredepunten hebben afwijkende geometry") + + def dumbbell_beta(self, export: bool = False) -> PlotlyFigure: + return dumbbell_beta(self, export) + + def dumbbell_uplift(self, export: bool = False) -> list[PlotlyFigure]: + return dumbbell_uplift(self, export) + + def dumbbell_heave(self, export: bool = False) -> list[PlotlyFigure]: + return dumbbell_heave(self, export) + + def dumbbell_piping(self, export: bool = False) -> list[PlotlyFigure]: + return dumbbell_piping(self, export) + + def map_delta_beta_comparison(self, export: bool = False) -> PlotlyFigure: + return map_delta_beta_comparison(self, export) + + def map_ratio_beta_comparison(self, export: bool = False) -> PlotlyFigure: + return map_ratio_beta_comparison(self, export) + + def create_and_export_figures(self): + dumbbell_beta(self, export=True) + dumbbell_uplift(self, export=True) + dumbbell_heave(self, export=True) + dumbbell_piping(self, export=True) + map_delta_beta_comparison(self, export=True) + map_ratio_beta_comparison(self, export=True) diff --git a/geoprob_pipe/cmd_app/comparisons/beta_dumbbell.py b/geoprob_pipe/cmd_app/comparisons/beta_dumbbell.py new file mode 100644 index 00000000..7d3ae883 --- /dev/null +++ b/geoprob_pipe/cmd_app/comparisons/beta_dumbbell.py @@ -0,0 +1,295 @@ +from __future__ import annotations +import os +import plotly.graph_objects as go +import pandas as pd +from typing import TYPE_CHECKING +if TYPE_CHECKING: + from geoprob_pipe.cmd_app.comparisons import ComparisonCollector + + +def _add_traces(comparison: ComparisonCollector, + df: pd.DataFrame, + fig: go.Figure): + + hoverdata = df[["uittredepunt_id", "beta1", "beta2"]].to_numpy() + symbol_map = { + 1: "circle", + 0: "x" + } + + symbols1 = [symbol_map[b] for b in df["converged1"]] + symbols2 = [symbol_map[b] for b in df["converged2"]] + name1 = "Beta1: " + comparison.name_1 + ".geoprob_pipe.gpkg" + name2 = "Beta2: " + comparison.name_2 + ".geoprob_pipe.gpkg" + + for _, row in df.iterrows(): + fig.add_trace(go.Scatter( + x=[row["uittredepunt_id"], row["uittredepunt_id"]], + y=[row["beta1"], row["beta2"]], + mode="lines", + showlegend=False, + marker=dict( + color="grey" + ) + )) + + fig.add_trace(go.Scatter( + x=df["uittredepunt_id"], + y=df["beta1"], + mode="markers", + name=name1, + marker=dict( + symbol=symbols1, + color="green", + size=10 + ), + customdata=hoverdata, + hovertemplate=( + "Uittredepunt ID: %{customdata[0]}
" + "β1: %{customdata[1]:.2f}
" + "β2: %{customdata[2]:.2f}
" + "" + ), + legendgroup="beta1", + showlegend=False + )) + + fig.add_trace(go.Scatter( + x=df["uittredepunt_id"], y=df["beta2"], mode="markers", + name=name2, + marker=dict(symbol=symbols2, color="blue", size=10), + customdata=hoverdata, + hovertemplate=( + "Uittredepunt ID: %{customdata[0]}
" + "β2: %{customdata[2]:.2f}
" + "β1: %{customdata[1]:.2f}
" + "" + ), + legendgroup="beta2", + showlegend=False + )) + # Empty trace for legend + fig.add_trace(go.Scatter( + x=[None], y=[None], mode="markers", + marker=dict(symbol="circle", color="green", size=10), + name=name1, + legendgroup="beta1", + )) + fig.add_trace(go.Scatter( + x=[None], y=[None], mode="markers", + marker=dict(symbol="circle", color="blue", size=10), + name=name2, + legendgroup="beta2" + )) + fig.add_trace(go.Scatter( + x=[None], y=[None], mode="markers", name="Not converged", + marker=dict(symbol="x", color="white", size=10, line=dict(color="black", width=0.5)))) + return fig + + +def _add_vak_id(comparison: ComparisonCollector, fig: go.Figure): + + vak_ids = comparison.df1_beta_uittredepunten["vak_id"].unique() + for _, vak_id in enumerate(vak_ids): + df_vak = comparison.df1_beta_uittredepunten + uit_ids = df_vak.loc[df_vak["vak_id"] == vak_id, ["uittredepunt_id"]] + + min_id: int = uit_ids.min().iloc[0] + max_id: int = uit_ids.max().iloc[0] + + fig.add_trace(go.Scatter( + x=[min_id, max_id], y=[0, 0], mode="lines", + line=dict(color="red", width=2), showlegend=False, name=f"{vak_id}")) + + fig.add_annotation( + x=(min_id + max_id) / 2, y=-0.7, text=f"{vak_id}", showarrow=False, + font=dict(size=10, color="black"), align="center") + return fig + + +def dumbbell_beta(comparison: ComparisonCollector, + export: bool = False): + + df_result1 = (comparison.df1_beta_uittredepunten[ + ["uittredepunt_id", "converged", "beta"] + ].rename(columns={"beta": "beta1", "converged": "converged1"})) + df_result2 = (comparison.df2_beta_uittredepunten[ + ["uittredepunt_id", "converged", "beta"] + ].rename(columns={"beta": "beta2", "converged": "converged2"})) + + df = df_result1.merge(df_result2, on="uittredepunt_id") + + fig = go.Figure() + fig = _add_traces(comparison, df, fig) + fig = _add_vak_id(comparison, fig) + + fig.update_layout( + title=f"Vergelijk Beta tussen GeoProb-Pipe bestanden
" + f"Voor de gecombineerde limit state, en gevisualiseerd per uittredepunt.", + xaxis_title="Uittredepunt ID", + yaxis_title="β-value", + legend=dict(orientation="h", yanchor="bottom", y=1.02, xanchor="right", x=1)) + + if export: + os.makedirs(comparison.export_dir, exist_ok=True) + fig.write_html(os.path.join(comparison.export_dir, "dumbbell_beta.html"), include_plotlyjs='cdn') + # fig.write_image(os.path.join(comparison.export_dir, "dumbbell_beta.png"), + # format="png", scale=5, width=1400) + + return fig + + +def dumbbell_uplift(comparison: ComparisonCollector, + export: bool = False): + + df_result1 = (comparison.df1_beta_limit_states[ + ["uittredepunt_id", "limit_state", "beta", "ondergrondscenario_id", + "converged"]].rename(columns={"beta": "beta1", + "limit_state": "limit_state1", + "converged": "converged1"})) + df_result1 = df_result1[df_result1["limit_state1"] == "calc_Z_u"] + + df_result2 = (comparison.df2_beta_limit_states[ + ["uittredepunt_id", "limit_state", "beta", "ondergrondscenario_id", + "converged"]].rename(columns={"beta": "beta2", + "limit_state": "limit_state2", + "converged": "converged2"})) + df_result2 = df_result2[df_result2["limit_state2"] == "calc_Z_u"] + + df = df_result1.merge(df_result2, on=["uittredepunt_id", + "ondergrondscenario_id"]) + fig_list = [] + for scenario in df["ondergrondscenario_id"].unique(): + fig = go.Figure() + scenario_mask = df["ondergrondscenario_id"] == scenario + df_plot = df[scenario_mask] + fig = _add_traces(comparison, df_plot, fig) + fig = _add_vak_id(comparison, fig) + + fig.update_layout( + title=f"Vergelijk Beta tussen GeoProb-Pipe bestanden
" + f"Voor de limit state Uplift en scenario {scenario}, " + f"en gevisualiseerd per uittredepunt.", + xaxis_title="Uittredepunt ID", + yaxis_title="β-value", + legend=dict( + orientation="h", + yanchor="bottom", + y=1.02, + xanchor="right", + x=1 + ) + ) + fig_list.append(fig) + if export: + os.makedirs(comparison.export_dir, exist_ok=True) + fig.write_html(os.path.join( + comparison.export_dir, f"dumbbell_uplift_{scenario}.html"), include_plotlyjs='cdn') + # fig.write_image(os.path.join( + # comparison.export_dir, f"dumbbell_uplift_{scenario}.png" + # ), format="png", scale=5, width=1400) + return fig_list + + +def dumbbell_heave(comparison: ComparisonCollector, + export: bool = False): + df_result1 = (comparison.df1_beta_limit_states[ + ["uittredepunt_id", "limit_state", "beta", "ondergrondscenario_id", + "converged"]].rename(columns={"beta": "beta1", + "limit_state": "limit_state1", + "converged": "converged1"})) + df_result1 = df_result1[df_result1["limit_state1"] == "calc_Z_h"] + df_result2 = (comparison.df2_beta_limit_states[ + ["uittredepunt_id", "limit_state", "beta", "ondergrondscenario_id", + "converged"]].rename(columns={"beta": "beta2", + "limit_state": "limit_state2", + "converged": "converged2"})) + df_result2 = df_result2[df_result2["limit_state2"] == "calc_Z_h"] + + df = df_result1.merge(df_result2, on=["uittredepunt_id", + "ondergrondscenario_id"]) + fig_list = [] + for scenario in df["ondergrondscenario_id"].unique(): + fig = go.Figure() + scenario_mask = df["ondergrondscenario_id"] == scenario + df_plot = df[scenario_mask] + fig = _add_traces(comparison, df_plot, fig) + fig = _add_vak_id(comparison, fig) + + fig.update_layout( + title=f"Vergelijk Beta tussen GeoProb-Pipe bestanden
" + f"Voor de limit state Heave en scenario {scenario}, " + f"en gevisualiseerd per uittredepunt.", + xaxis_title="Uittredepunt ID", + yaxis_title="β-value", + legend=dict( + orientation="h", + yanchor="bottom", + y=1.02, + xanchor="right", + x=1 + ) + ) + fig_list.append(fig) + if export: + os.makedirs(comparison.export_dir, exist_ok=True) + fig.write_html(os.path.join( + comparison.export_dir, f"dumbbell_heave_{scenario}.html" + ), include_plotlyjs='cdn') + # fig.write_image(os.path.join( + # comparison.export_dir, f"dumbbell_heave_{scenario}.png" + # ), format="png", scale=5, width=1400) + return fig_list + + +def dumbbell_piping(comparison: ComparisonCollector, + export: bool = False): + df_result1 = (comparison.df1_beta_limit_states[ + ["uittredepunt_id", "limit_state", "beta", "ondergrondscenario_id", + "converged"]].rename(columns={ + "beta": "beta1", + "limit_state": "limit_state1", + "converged": "converged1"})) + df_result1 = df_result1[df_result1["limit_state1"] == "calc_Z_p"] + df_result2 = (comparison.df2_beta_limit_states[ + ["uittredepunt_id", "limit_state", "beta", "ondergrondscenario_id", + "converged"]].rename(columns={ + "beta": "beta2", + "limit_state": "limit_state2", + "converged": "converged2"})) + df_result2 = df_result2[df_result2["limit_state2"] == "calc_Z_p"] + + df = df_result1.merge(df_result2, on=["uittredepunt_id", + "ondergrondscenario_id"]) + fig_list = [] + for scenario in df["ondergrondscenario_id"].unique(): + fig = go.Figure() + scenario_mask = df["ondergrondscenario_id"] == scenario + df_plot = df[scenario_mask] + fig = _add_traces(comparison, df_plot, fig) + fig = _add_vak_id(comparison, fig) + + fig.update_layout( + title=f"Vergelijk Beta tussen GeoProb-Pipe bestanden
" + f"Voor de limit state Piping en scenario {scenario}, " + f"en gevisualiseerd per uittredepunt.", + xaxis_title="Uittredepunt ID", + yaxis_title="β-value", + legend=dict( + orientation="h", + yanchor="bottom", + y=1.02, + xanchor="right", + x=1 + ) + ) + fig_list.append(fig) + if export: + os.makedirs(comparison.export_dir, exist_ok=True) + fig.write_html(os.path.join( + comparison.export_dir, f"dumbbell_piping_{scenario}.html" + ), include_plotlyjs='cdn') + # fig.write_image(os.path.join( + # comparison.export_dir, f"dumbbell_piping_{scenario}.png" + # ), format="png", scale=5, width=1400) + return fig_list diff --git a/geoprob_pipe/cmd_app/comparisons/beta_map.py b/geoprob_pipe/cmd_app/comparisons/beta_map.py new file mode 100644 index 00000000..a153b2b8 --- /dev/null +++ b/geoprob_pipe/cmd_app/comparisons/beta_map.py @@ -0,0 +1,248 @@ +from __future__ import annotations +import os +import plotly.graph_objects as go +import geopandas as gpd +from shapely.geometry import LineString, MultiLineString, GeometryCollection +from typing import TYPE_CHECKING +if TYPE_CHECKING: + from geoprob_pipe.cmd_app.comparisons import ComparisonCollector + + +def _determine_zoom(gdf_latlon): + min_lat = gdf_latlon.geometry.y.min() + max_lat = gdf_latlon.geometry.y.max() + min_lon = gdf_latlon.geometry.x.min() + max_lon = gdf_latlon.geometry.x.max() + + def _calculate_zoom(lat_range_val, lon_range_val): + max_range = max(lat_range_val, lon_range_val) + if max_range < 0.01: + return 15 + elif max_range < 0.05: + return 13 + elif max_range < 0.1: + return 12 + elif max_range < 0.5: + return 10 + elif max_range < 1.0: + return 9 + else: + return 8 + + lat_range = max_lat - min_lat + lon_range = max_lon - min_lon + zoom = _calculate_zoom(lat_range, lon_range) + return zoom + + +def _add_line(comparison: ComparisonCollector, fig: go.Figure, + layer: str, color: str): + gdf_traject = gpd.read_file(comparison.geopackage_filepath_1, + layer=layer) + gdf_traject = gdf_traject.to_crs("EPSG:4326") + + def plot_linestring(ls, display): + xs, ys = ls.xy + xs = list(xs) + ys = list(ys) + fig.add_trace(go.Scattermap( + lon=xs, + lat=ys, + mode="lines", + line=dict(color=color, width=1.5), + hoverinfo="none", + name=layer, + legendgroup=layer, + showlegend=display + )) + show = True + for geom in gdf_traject.geometry: + if isinstance(geom, LineString): + plot_linestring(geom, show) + show = False + elif isinstance(geom, MultiLineString): + for line in geom.geoms: + plot_linestring(line, show) + show = False + elif isinstance(geom, GeometryCollection): + for g in geom.geoms: + if isinstance(g, LineString): + plot_linestring(g, show) + show = False + elif isinstance(g, MultiLineString): + for line in g.geoms: + plot_linestring(line, show) + show = False + + else: + print("Skipping unsupported geometry:", geom.geom_type) + + return fig + + +def map_delta_beta_comparison(comparison: ComparisonCollector, + export: bool = False) -> go.Figure: + # load data from class + gdf_result1 = (comparison.gdf1_uittredepunten[ + ["uittredepunt_id", "beta", "geometry"] + ].rename(columns={"beta": "beta1"})) + gdf_result2 = (comparison.gdf2_uittredepunten[ + ["uittredepunt_id", "beta"]].rename(columns={"beta": "beta2"})) + gdf = gdf_result1.merge(gdf_result2, on="uittredepunt_id") + gdf["beta_delta"] = gdf["beta2"] - gdf["beta1"] + + # Covert to crs for map. + gdf_latlon = gdf.to_crs("EPSG:4326") + + fig = go.Figure() + fig.add_trace(go.Scattermap( + mode="markers", + lat=gdf_latlon.geometry.y, + lon=gdf_latlon.geometry.x, + marker=dict( + size=9, + color="black" + ), + showlegend=False + )) + hoverdata = ["uittredepunt_id", "beta_delta", "beta1", "beta2"] + fig.add_trace(go.Scattermap( + mode="markers", + lat=gdf_latlon.geometry.y, + lon=gdf_latlon.geometry.x, + marker=dict( + size=8, + color=gdf_latlon["beta_delta"], + cmax=3, + cmin=-3, + colorscale="RdYlGn", + colorbar=dict(title="Delta Beta") + ), + hoverinfo='text', + text=gdf_latlon[hoverdata].apply( + lambda row: '
'.join( + [f"{col}: {round(row[col], 3)}" for col in hoverdata] + ), + axis=1), + showlegend=False + )) + + fig = _add_line(comparison, fig, "dijktraject", "black") + fig = _add_line(comparison, fig, "intredelijn", "blue") + fig = _add_line(comparison, fig, "binnenteenlijn", "red") + fig = _add_line(comparison, fig, "buitenteenlijn", "red") + + zoom = _determine_zoom(gdf_latlon) + fig.update_layout( + map_style="open-street-map", + # carto-positron, open-street-map, satellite-streets + map_zoom=zoom, + map_center=dict( + lat=gdf_latlon.geometry.y.mean(), + lon=gdf_latlon.geometry.x.mean() + ), + dragmode="zoom", + title=f"Delta beta van uittredepunten tussen
" + + f"Beta1: {comparison.name_1} en Beta2: {comparison.name_2}", + legend=dict( + orientation="h", + yanchor="bottom", + y=1.02, + xanchor="right", + x=1)) + + if export: + os.makedirs(comparison.export_dir, exist_ok=True) + fig.write_html(os.path.join( + comparison.export_dir, "delta_beta_map.html" + ), include_plotlyjs='cdn', include_mathjax='cdn') + # fig.write_image(os.path.join( + # comparison.export_dir, "delta_beta_map.png" + # ), format="png", scale=5, width=1400) + + return fig + + +def map_ratio_beta_comparison(comparison: ComparisonCollector, + export: bool = False) -> go.Figure: + # load data from class + gdf_result1 = (comparison.gdf1_uittredepunten[ + ["uittredepunt_id", "beta", "geometry"] + ].rename(columns={"beta": "beta1"})) + gdf_result2 = (comparison.gdf2_uittredepunten[ + ["uittredepunt_id", "beta"]].rename(columns={"beta": "beta2"})) + gdf = gdf_result1.merge(gdf_result2, on="uittredepunt_id") + + gdf["beta_ratio"] = round((gdf["beta1"] / gdf["beta2"]) * 100, 2) + + # Covert to crs for map. + gdf_latlon = gdf.to_crs("EPSG:4326") + + fig = go.Figure() + fig.add_trace(go.Scattermap( + mode="markers", + lat=gdf_latlon.geometry.y, + lon=gdf_latlon.geometry.x, + marker=dict( + size=9, + color="black" + ), + showlegend=False + )) + hoverdata = ["uittredepunt_id", "beta_ratio", "beta1", "beta2"] + fig.add_trace(go.Scattermap( + mode="markers", + lat=gdf_latlon.geometry.y, + lon=gdf_latlon.geometry.x, + marker=dict( + size=8, + color=gdf_latlon["beta_ratio"], + cmax=200, + cmin=0, + colorscale="RdYlGn", + colorbar=dict(title="Beta Ratio - Beta1/Beta2 [%]"), + ), + hoverinfo='text', + text=gdf_latlon[hoverdata].apply( + lambda row: '
'.join( + [f"{col}: {round(row[col], 3)}" for col in hoverdata] + ), + axis=1), + showlegend=False + )) + + fig = _add_line(comparison, fig, "dijktraject", "black") + fig = _add_line(comparison, fig, "intredelijn", "blue") + fig = _add_line(comparison, fig, "binnenteenlijn", "red") + fig = _add_line(comparison, fig, "buitenteenlijn", "red") + + zoom = _determine_zoom(gdf_latlon) + fig.update_layout( + map_style="open-street-map", + # carto-positron, open-street-map, satellite-streets + map_zoom=zoom, + map_center=dict( + lat=gdf_latlon.geometry.y.mean(), + lon=gdf_latlon.geometry.x.mean() + ), + dragmode="zoom", + title=f"Beta ratio van uittredepunten tussen
" + + f"Beta1: {comparison.name_1} en Beta2: {comparison.name_2}", + legend=dict( + orientation="h", + yanchor="bottom", + y=1.02, + xanchor="right", + x=1 + ) + ) + if export: + os.makedirs(comparison.export_dir, exist_ok=True) + fig.write_html(os.path.join( + comparison.export_dir, "ratio_beta_map.html" + ), include_plotlyjs='cdn', include_mathjax='cdn') + # fig.write_image(os.path.join( + # comparison.export_dir, "ratio_beta_map.png" + # ), format="png", scale=5, width=1400) + + return fig diff --git a/geoprob_pipe/cmd_app/comparisons/start_comparison.py b/geoprob_pipe/cmd_app/comparisons/start_comparison.py new file mode 100644 index 00000000..8d2b365b --- /dev/null +++ b/geoprob_pipe/cmd_app/comparisons/start_comparison.py @@ -0,0 +1,96 @@ +from __future__ import annotations +# noinspection PyPep8Naming +from InquirerPy.prompts.input import InputPrompt as inq_text +import os +from geoprob_pipe.utils.validation_messages import BColors +from geoprob_pipe.cmd_app.comparisons import ComparisonCollector + + +def specify_dir_for_first_file(): + filepath: str = "" + filepath_is_valid = False + while filepath_is_valid is False: + filepath: str = inq_text( + message="Specificeer het volledige bestandspad naar het eerste .geoprob_pipe.gpkg-bestand.", + ).execute() + + filepath = filepath.replace('"', '') + + if not filepath.endswith(".geoprob_pipe.gpkg"): + print(BColors.WARNING, + f"Het bestand moet een .geoprob_pipe.gpkg-bestand zijn. Jouw invoer " + f"{os.path.basename(filepath)} eindigt niet op deze extensie.", BColors.ENDC) + continue + if not os.path.exists(filepath): + print(BColors.WARNING, "Het opgegeven bestandspad bestaat niet.", + BColors.ENDC) + continue + + filepath_is_valid = True + + return filepath + + +def specify_dir_for_second_file(): + filepath: str = "" + filepath_is_valid = False + while filepath_is_valid is False: + filepath: str = inq_text( + message="Specificeer het volledige bestandspad naar het tweede .geoprob_pipe.gpkg-bestand.", + ).execute() + + filepath = filepath.replace('"', '') + + if not filepath.endswith(".geoprob_pipe.gpkg"): + print(BColors.WARNING, + f"Het bestand moet een .geoprob_pipe.gpkg-bestand zijn. Jouw invoer " + f"{os.path.basename(filepath)} eindigt niet op deze extensie.", BColors.ENDC) + continue + if not os.path.exists(filepath): + print(BColors.WARNING, "Het opgegeven bestandspad bestaat niet.", + BColors.ENDC) + continue + + filepath_is_valid = True + + return filepath + + +def specify_dir_for_comparison(): + workspace_dir: str = "" + workspace_dir_is_valid = False + while workspace_dir_is_valid is False: + workspace_dir: str = inq_text( + message="Specificeer het volledige pad naar de map waar je" + + " de export van de vergelijking wilt opslaan.", + ).execute() + workspace_dir = workspace_dir.replace('"', '') + + if not os.path.exists(workspace_dir): + print(BColors.WARNING, "De opgegeven map bestaat niet.", + BColors.ENDC) + continue + if not os.path.isdir(workspace_dir): + print(BColors.WARNING, "De opgegeven locatie is geen map.", + BColors.ENDC) + continue + + workspace_dir_is_valid = True + + return workspace_dir + + +def run_comparison(filepath1, filepath2, export_dir): + print(BColors.OKBLUE, "Vergelijking wordt uitgevoerd.", BColors.ENDC) + comparison = ComparisonCollector(filepath1, filepath2, export_dir) + comparison.create_and_export_figures() + print(BColors.OKBLUE, + f"Vergelijking voltooid en opgeslagen in {comparison.export_dir}.", + BColors.ENDC) + + +def start_comparison(): + filepath1 = specify_dir_for_first_file() + filepath2 = specify_dir_for_second_file() + export_dir = specify_dir_for_comparison() + run_comparison(filepath1, filepath2, export_dir) diff --git a/geoprob_pipe/cmd_app/general/__init__.py b/geoprob_pipe/cmd_app/general/__init__.py new file mode 100644 index 00000000..65d889da --- /dev/null +++ b/geoprob_pipe/cmd_app/general/__init__.py @@ -0,0 +1,2 @@ +from geoprob_pipe.cmd_app.general.project import created_project +from geoprob_pipe.cmd_app.general.geohydrologisch_model import created_model diff --git a/geoprob_pipe/cmd_app/general/geohydrologisch_model.py b/geoprob_pipe/cmd_app/general/geohydrologisch_model.py new file mode 100644 index 00000000..af8a486c --- /dev/null +++ b/geoprob_pipe/cmd_app/general/geohydrologisch_model.py @@ -0,0 +1,59 @@ +from __future__ import annotations +from geoprob_pipe.utils.validation_messages import BColors +from InquirerPy import inquirer +from typing import TYPE_CHECKING +from geopandas import read_file +import sqlite3 +from geoprob_pipe.calculations.systems.mappers.calculation_mapper import CALCULATION_MAPPER +from pandas import DataFrame +if TYPE_CHECKING: + from geoprob_pipe.cmd_app.cmd import ApplicationSettings + + +def created_model(app_settings: ApplicationSettings) -> bool: + df: DataFrame = read_file(app_settings.geopackage_filepath, layer="geoprob_pipe_metadata") + + # Check if no model specified yet + metadata_types = [str(value) for value in df['metadata_type'].values.tolist()] + if "geohydrologisch_model" not in metadata_types: + specify_model_to_use(app_settings, update_record=False) + return True + + # Check if specified model is legal + current_specified_model = df[df['metadata_type'] == "geohydrologisch_model"]["values"].iloc[0] + if current_specified_model not in CALCULATION_MAPPER.keys(): + specify_model_to_use(app_settings, update_record=True) + return True + + # Specified model is legal + print(BColors.OKBLUE, f"✔ Geohydrologisch model al ingesteld.", BColors.ENDC) + return True + + +def specify_model_to_use(app_settings: ApplicationSettings, update_record: bool = False): + model_labels = [value["label"] for key, value in CALCULATION_MAPPER.items()] + + choice = inquirer.select( + message="Welk geohydrologisch model wil je gebruiken? De invoer parameters variëren per model.", + choices=model_labels, + default=model_labels[0], + ).execute() + + # Push record + conn = sqlite3.connect(app_settings.geopackage_filepath) + cursor = conn.cursor() + choice_formatted: str = choice + choice_formatted = choice_formatted.replace(" ", "").lower() + sql_statement = f""" + INSERT INTO geoprob_pipe_metadata + ('metadata_type', 'values') VALUES ('geohydrologisch_model', '{choice_formatted}')""" + if update_record: + sql_statement = f""" + UPDATE geoprob_pipe_metadata + SET 'values' = '{choice_formatted}' + WHERE metadata_type = 'geohydrologisch_model'""" + cursor.execute(sql_statement) + conn.commit() + conn.close() + + print(BColors.OKBLUE, f"✅ Geohydrologisch model ingesteld.", BColors.ENDC) diff --git a/geoprob_pipe/cmd_app/general/project.py b/geoprob_pipe/cmd_app/general/project.py new file mode 100644 index 00000000..ce7340dc --- /dev/null +++ b/geoprob_pipe/cmd_app/general/project.py @@ -0,0 +1,153 @@ +from __future__ import annotations +from InquirerPy import inquirer +from typing import Optional, TYPE_CHECKING +from rich.console import Console +from rich.panel import Panel +from geoprob_pipe.utils import clear_terminal +import os +from pandas import DataFrame +from datetime import datetime +from pathlib import Path +import sys +from importlib.metadata import distributions +from geopandas import GeoDataFrame +from geoprob_pipe.cmd_app.utils.misc import get_geoprob_pipe_version_number +from geoprob_pipe.cmd_app.comparisons.start_comparison import start_comparison +from geoprob_pipe.utils.validation_messages import BColors +from geoprob_pipe.calculations.systems.single_calc import ( + EXAMPLE_SCRIPT_REPRODUCING_SINGLE_CALCULATION, EXPLANATION_REPRODUCING_SINGLE_CALCULATION) +if TYPE_CHECKING: + from geoprob_pipe.cmd_app.cmd import ApplicationSettings + + +def created_project(app_settings: ApplicationSettings) -> bool: + + choices_list = [ + "Bestaand project openen", + "Nieuw project starten", + "Twee projectbestanden vergelijken", + "Inspecteer een enkele berekening", + "Applicatie afsluiten" + ] + choice = inquirer.select( + message="Wil je verder gaan met een bestaand project, " + "een nieuw project starten, " + "of twee project bestanden vergelijken?", + choices=choices_list, + default=choices_list[0], + ).execute() + + if choice == choices_list[0]: + specify_path_to_existing_project(app_settings) + return True + elif choice == choices_list[1]: + specify_dir_for_new_project(app_settings) + return True + elif choice == choices_list[2]: + start_comparison() + sys.exit("Applicatie afgesloten") + elif choice == choices_list[3]: + clear_terminal() + console = Console() + console.print(Panel( + EXPLANATION_REPRODUCING_SINGLE_CALCULATION, + title=f"Inspecteer een enkele berekening".upper(), + title_align="left", + border_style="bright_blue", + padding=(0, 2))) + print(EXAMPLE_SCRIPT_REPRODUCING_SINGLE_CALCULATION) + sys.exit("Applicatie afgesloten") + return False + + +def specify_path_to_existing_project(app_settings: ApplicationSettings): + filepath: Optional[str] = None + filepath_is_valid = False + while filepath_is_valid is False: + filepath: str = inquirer.text( + message="Specificeer het volledige bestandspad naar het .geoprob_pipe.gpkg-bestand.", + ).execute() + + filepath = filepath.replace('"', '') + + if not filepath.endswith(".geoprob_pipe.gpkg"): + print(BColors.WARNING, f"Het bestand moet een .geoprob_pipe.gpkg-bestand zijn. Jouw invoer " + f"{os.path.basename(filepath)} eindigt niet op deze extensie.", BColors.ENDC) + continue + if not os.path.exists(filepath): + print(BColors.WARNING, f"Het opgegeven bestandspad bestaat niet.", BColors.ENDC) + continue + + filepath_is_valid = True + + app_settings.workspace_dir = os.path.dirname(filepath) + app_settings.geopackage_filename = os.path.basename(filepath) + + +def specify_dir_for_new_project(app_settings: ApplicationSettings): + workspace_dir: Optional[str] = None + workspace_dir_is_valid = False + while workspace_dir_is_valid is False: + workspace_dir: str = inquirer.text( + message="Specificeer het volledige pad naar de map waar je het GeoProb-Pipe-bestand wilt opslaan.", + ).execute() + workspace_dir = workspace_dir.replace('"', '') + + if not os.path.exists(workspace_dir): + print(BColors.WARNING, f"De opgegeven map bestaat niet.", BColors.ENDC) + continue + if not os.path.isdir(workspace_dir): + print(BColors.WARNING, f"De opgegeven locatie is geen map.", BColors.ENDC) + continue + + workspace_dir_is_valid = True + + app_settings.workspace_dir = workspace_dir + + # Continue questionnaire + specify_project_filename(app_settings) + + +def specify_project_filename(app_settings: ApplicationSettings): + filename: Optional[str] = None + filename_is_valid = False + while filename_is_valid is False: + project_name: str = inquirer.text( + message="Specificeer een bestandsnaam voor het project. " + "Het bestand wordt opgeslagen met een .geoprob_pipe.gpkg-extensie.", + ).execute() + + filename = f"{project_name}.geoprob_pipe.gpkg" + filepath = os.path.join(app_settings.workspace_dir, filename) + + if os.path.exists(filepath): + print(BColors.WARNING, f"De opgegeven bestandsnaam bestaat al. " + f"Kies een andere naam. " + f"Je gaf het volgden op:\n" + f" {filepath}", BColors.ENDC) + continue + + filename_is_valid = True + + app_settings.geopackage_filename = filename + + create_geopackage_file(app_settings) + + +def create_geopackage_file(app_settings: ApplicationSettings): + + df = DataFrame({ + "metadata_type": ["created_by", "created_datetime", "application_version", "python_version", "pip_freeze"], + "values": [ + os.getenv("USERNAME"), + datetime.now(), + get_geoprob_pipe_version_number(), + f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}", + {dist.metadata["Name"]: dist.version for dist in distributions()}, + ] + }) + + gdf = GeoDataFrame(df, geometry=None) + + gdf.to_file(Path(app_settings.geopackage_filepath), layer="geoprob_pipe_metadata", driver="GPKG") + print(BColors.OKBLUE, f"✅ Project-bestand aangemaakt op locatie:\n {app_settings.geopackage_filepath}", BColors.ENDC) diff --git a/geoprob_pipe/cmd_app/parameter_input/__init__.py b/geoprob_pipe/cmd_app/parameter_input/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/geoprob_pipe/cmd_app/parameter_input/added_input_parameters.py b/geoprob_pipe/cmd_app/parameter_input/added_input_parameters.py new file mode 100644 index 00000000..26e15713 --- /dev/null +++ b/geoprob_pipe/cmd_app/parameter_input/added_input_parameters.py @@ -0,0 +1,287 @@ +from __future__ import annotations +from InquirerPy import inquirer +import sqlite3 + +from geoprob_pipe.cmd_app.parameter_input.expand_input_tables import run_expand_input_tables +from geoprob_pipe.cmd_app.parameter_input.initiate_input_excel_tables import initiate_input_excel_tables +from geoprob_pipe.cmd_app.parameter_input.input_parameter_figures import InputParameterFigures +from geoprob_pipe.cmd_app.parameter_input.export_input_parameter_excel import export_input_parameter_tables +from geoprob_pipe.cmd_app.parameter_input.input_parameter_tables import InputParameterTables +from typing import TYPE_CHECKING, Optional +import os +import sys + +from geoprob_pipe.utils.loggers import BColors +if TYPE_CHECKING: + from geoprob_pipe.cmd_app.cmd import ApplicationSettings + + +def possibly_initiatie_input_tables_in_db(app_settings: ApplicationSettings): + + # Get table names + conn = sqlite3.connect(app_settings.geopackage_filepath) + cursor = conn.cursor() + cursor.execute("SELECT name FROM sqlite_master WHERE type='table';") + tables_names = [row[0] for row in cursor.fetchall()] + conn.close() + + # If already exist + if ("parameter_invoer" in tables_names and + "scenario_invoer" in tables_names and "fragility_values_invoer" in tables_names): + # print(f"{BColors.UNDERLINE}Tables already exist in geopackage{BColors.ENDC}") + return + + # If it doesn't exist yet + # print(f"{BColors.UNDERLINE}Tables do not yet exist in geopackage{BColors.ENDC}") + initiate_input_excel_tables(app_settings=app_settings) + print(f"{BColors.UNDERLINE}Basis invoer tabellen zijn nu geïnitieerd in het GeoProb-Pipe-bestand. Deze kun je naar " + f"wens aanpassen in het vervolgproces.{BColors.ENDC}") + + +def load_tables_from_db(app_settings: ApplicationSettings) -> InputParameterTables: + tables = InputParameterTables(geopackage_filepath=app_settings.geopackage_filepath) + return tables + + +def validate_raw_input_tables( + # app_settings: ApplicationSettings, tables: InputParameterTables +) -> bool: + valid: bool = True # TODO + if not valid: + print(f"Input Excel tables are not valid. Validation messages are exported to \n" + f"TODO") # TODO: Specify path to exported validation messages. + return valid + + +def inquire_if_input_figures_should_be_exported(app_settings: ApplicationSettings, tables: InputParameterTables): + choices_list = [ + "Ja", + "Nee", + "Applicatie afsluiten" + ] + choice = inquirer.select( + message="Wil je overzichtsfiguren exporteren van de invoer tabellen? \n" + "Hierin kun je gemakkelijk zien voor welke parameter welke invoer is ingesteld, en op welk niveau " + "(geografisch-, traject-, vak-, of uittredepunt-niveau).", + choices=choices_list, + default=choices_list[0], + ).execute() + + if choice == choices_list[0]: + InputParameterFigures(app_settings=app_settings, tables=tables, export=True) + elif choice == choices_list[1]: + pass # Just continue + elif choice == choices_list[2]: + sys.exit(f"Applicatie is afgesloten.") + else: + raise ValueError + + +def validate_expanded_input_tables(app_settings: ApplicationSettings) -> bool: + df_expanded = run_expand_input_tables(geopackage_filepath=app_settings.geopackage_filepath) + df_nans = df_expanded[df_expanded['parameter_input'].isna()] + + # No issues? + if df_nans.__len__() == 0: + return True + + # Report issues back + export_dir = os.path.join( + os.path.dirname(app_settings.geopackage_filepath), + "exports", + str(app_settings.datetime_stamp), + "parameter_input_process") + os.makedirs(export_dir, exist_ok=True) + export_path = os.path.join(export_dir, "validation_missing_parameter_input.xlsx") + print(f"{export_path=}") + if os.path.exists(export_path): + os.remove(export_path) + df_nans.to_excel(export_path) + print(f"{BColors.WARNING}Er mist parameter invoer voor {df_nans.__len__()} berekeningen.\n" + f"Dit is voor {df_nans['parameter_name'].unique().__len__()} unieke parameters, " + f"{df_nans['uittredepunt_id'].unique().__len__()} unieke uittredepunten en " + f"{df_nans['ondergrondscenario_naam'].unique().__len__()} unieke ondergrondscenarios.\n" + f"De gedetailleerde lijst is geëxporteerd naar\n" + f"{export_path}{BColors.ENDC}") + return False + + +def inquire_to_import_export_tables_and_figures_or_continue( + app_settings: ApplicationSettings, tables: InputParameterTables, + validity_raw_tables: bool, validity_extended_tables: bool +): + + # Determine options + choices_list = [] + if validity_raw_tables and validity_extended_tables: + choices_list.append("Zijn de invoer tabellen zijn naar wens? Ga door naar volgende stap") + else: + choices_list.append( + "Zijn de invoer tabellen zijn naar wens? Ga door naar volgende stap (n.v.t. -> invoer niet valide)") + if validity_raw_tables: + choices_list.append("Overzichtsfiguren van invoertabellen: Exporteren") + choices_list.extend([ + "Invoer tabellen: Importeren vanuit Excel", + "Invoer tabellen: Exporteren naar Excel", + "Toelichting per keuze optie", + "Applicatie afsluiten"]) + + # Provide user options + choice = inquirer.select( + message="Maak een keuze voor het gereedmaken van de invoertabellen.", + choices=choices_list, + default=choices_list[0], + ).execute() + + if choice == "Zijn de invoer tabellen zijn naar wens? Ga door naar volgende stap": + # run_calculations(geopackage_filepath=app_settings.geopackage_filepath) + print(BColors.OKBLUE, f"✔ Parameter invoer afgerond.", BColors.ENDC) + return + + elif choice == "Zijn de invoer tabellen zijn naar wens? Ga door naar volgende stap (n.v.t. -> invoer niet valide)": + inquire_to_import_export_tables_and_figures_or_continue( + app_settings=app_settings, tables=tables, validity_raw_tables=validity_raw_tables, + validity_extended_tables=validity_extended_tables) + + elif choice == "Overzichtsfiguren van invoertabellen: Exporteren": + InputParameterFigures(app_settings=app_settings, tables=tables, export=True) + inquire_to_import_export_tables_and_figures_or_continue( + app_settings=app_settings, tables=tables, validity_raw_tables=validity_raw_tables, + validity_extended_tables=validity_extended_tables) + + elif choice == "Invoer tabellen: Importeren vanuit Excel": + process_import_input(app_settings=app_settings) + + elif choice == "Invoer tabellen: Exporteren naar Excel": + process_export_input_of_db( + app_settings=app_settings, tables=tables, validity_raw_tables=validity_raw_tables, + validity_extended_tables=validity_extended_tables) + + elif choice == "Toelichting per keuze optie": + print(""" +Invoer tabellen zijn naar wens, ga door naar volgende stap -> Indien je deze keuzemogelijkheid krijgt zijn de invoertabellen valide en kun je door naar de volgende stap. + Je zegt daarmee eveneens dat de invoertabellen naar wens zijn. +Overzichtsfiguren van invoertabellen: Exporteren -> Deze interactive HTML-figuren geven je per parameter een snel visueel overzicht van de invoer in het GeoProb-Pipe-bestand. +Invoer tabellen: Importeren vanuit Excel -> Importeer vanuit Excel de invoertabellen om ze te laten valideren, visualiseren en/of op te slaan in het GeoProb-Pipe-bestand. +Invoer tabellen: Exporteren naar Excel -> Exporteer vanuit het GeoProb-Pipe-bestand de invoertabellen om ze in Excel te bekijken en/of verder aan te vullen. + """) + inquire_to_import_export_tables_and_figures_or_continue( + app_settings=app_settings, tables=tables, validity_raw_tables=validity_raw_tables, + validity_extended_tables=validity_extended_tables) + + elif choice == "Applicatie afsluiten": + sys.exit(f"Applicatie is afgesloten.") + + else: + raise ValueError + + +def export_input_tables_of_db(app_settings: ApplicationSettings, tables: InputParameterTables): + export_input_parameter_tables(app_settings=app_settings, tables=tables) + + +def import_input_tables(geopackage_filepath: str) -> InputParameterTables: + + filepath: Optional[str] = None + filepath_is_valid = False + while filepath_is_valid is False: + filepath: str = inquirer.text( + message="Specificeer het volledige bestandspad naar het input parameters Excel.", + ).execute() + + filepath = filepath.replace('"', '') + + if not filepath.endswith(".xlsx"): + print(BColors.WARNING, f"Het bestand moet een .xlsx-bestand zijn. Jouw invoer " + f"{os.path.basename(filepath)} eindigt niet op deze extensie.", BColors.ENDC) + continue + if not os.path.exists(filepath): + print(BColors.WARNING, f"Het opgegeven bestandspad bestaat niet.", BColors.ENDC) + continue + + filepath_is_valid = True + + tables = InputParameterTables(path_to_excel=filepath, geopackage_filepath=geopackage_filepath) + print(f"{BColors.UNDERLINE}Tabellen zijn nu geïmporteerd.{BColors.ENDC}") + return tables + + +def inquire_to_store_input_tables_to_db( + app_settings: ApplicationSettings, tables: InputParameterTables): + + choices_list = ["Ja", "Nee"] + choice = inquirer.select( + message="Wil je de nieuwe tabellen opslaan in het GeoProb-Pipe-bestand?", + choices=choices_list, + default=choices_list[0], + ).execute() + + if choice == "Ja": + conn = sqlite3.connect(app_settings.geopackage_filepath) + tables.df_scenario_invoer.to_sql("scenario_invoer", conn, if_exists="replace", index=False) + tables.df_parameter_invoer.to_sql("parameter_invoer", conn, if_exists="replace", index=False) + tables.df_fragility_values_invoer.to_sql( + "fragility_values_invoer", conn, if_exists="replace", index=False) + tables.df_correlatie_invoer.to_sql("correlatie_invoer", conn, if_exists="replace", index=False) + conn.close() + print(f"{BColors.UNDERLINE}Tabellen zijn nu opgeslagen in het GeoProb-Pipe-file.{BColors.ENDC}") + + elif choice == "Nee": + pass # Just continue + + else: + raise ValueError + + +def process_input_exist_in_db(app_settings: ApplicationSettings): + possibly_initiatie_input_tables_in_db(app_settings=app_settings) + tables: InputParameterTables = load_tables_from_db(app_settings=app_settings) + + # Validate raw tables + validity_raw_tables = validate_raw_input_tables() + + # Validate expanded tables + validity_extended_tables: Optional[bool] = None + if validity_raw_tables: validity_extended_tables = validate_expanded_input_tables(app_settings=app_settings) + + # Provide user with follow-up options + inquire_to_import_export_tables_and_figures_or_continue( + app_settings=app_settings, tables=tables, + validity_raw_tables=validity_raw_tables, validity_extended_tables=validity_extended_tables) + # -> Redirects also to new process loop + + +def process_export_input_of_db( + app_settings: ApplicationSettings, tables: InputParameterTables, + validity_raw_tables: bool, validity_extended_tables: bool): + export_input_tables_of_db(app_settings=app_settings, tables=tables) + inquire_to_import_export_tables_and_figures_or_continue( + app_settings=app_settings, tables=tables, validity_raw_tables=validity_raw_tables, + validity_extended_tables=validity_extended_tables) + # -> Redirects also to new process loop + + +def process_import_input(app_settings: ApplicationSettings): + tables = import_input_tables(app_settings.geopackage_filepath) # Asks user for path to input-file + + # Validate raw tables + validity_raw_tables = validate_raw_input_tables() + + # Ask to export overview pictures + if validity_raw_tables: inquire_if_input_figures_should_be_exported(app_settings=app_settings, tables=tables) + + # Validate expanded tables + validity_extended_tables: Optional[bool] = None + if validity_extended_tables: validity_extended_tables = validate_expanded_input_tables(app_settings=app_settings) + + # Provide user with follow-up options + inquire_to_store_input_tables_to_db(app_settings=app_settings, tables=tables) + inquire_to_import_export_tables_and_figures_or_continue( + app_settings=app_settings, tables=tables, validity_raw_tables=validity_raw_tables, + validity_extended_tables=validity_extended_tables) + # -> Redirects also to new process loop + + +def added_input_parameter_data(app_settings: ApplicationSettings) -> bool: + process_input_exist_in_db(app_settings=app_settings) + return True diff --git a/geoprob_pipe/cmd_app/parameter_input/expand_input_tables.py b/geoprob_pipe/cmd_app/parameter_input/expand_input_tables.py new file mode 100644 index 00000000..8d5405e6 --- /dev/null +++ b/geoprob_pipe/cmd_app/parameter_input/expand_input_tables.py @@ -0,0 +1,318 @@ +from typing import Dict, List +from pandas import DataFrame, isna, notna, concat, read_sql, read_csv +import sqlite3 +import numpy as np +import os +from geopandas import GeoDataFrame, read_file +from geoprob_pipe.calculations.systems.mappers.initial_input_mapper import INITIAL_INPUT_MAPPER +from geoprob_pipe.cmd_app.parameter_input.input_parameter_tables import InputParameterTables +from probabilistic_library import FragilityValue + + +def _combine_parameter_invoer_sources(tables: InputParameterTables) -> DataFrame: + """ Combineert de geo-gerefereerde parameter invoer met de handmatige invoer die oorspronkelijk uit de Excel kwam. + Zodoende kan vanuit één dataframe de invoer geëxplodeerd worden naar invoer per uittredepunt. """ + + # Gather raw data + df_gis_join_parameter_invoer = tables.df_gis_join_parameter_invoer + df_gis_join_parameter_invoer['scope'] = 'gis_uittredepunt' + df_parameter_invoer = tables.df_parameter_invoer + + # Concatenate + import warnings + with warnings.catch_warnings(): + warnings.simplefilter(action='ignore', category=FutureWarning) + df_parameter_invoer_combined = concat( + [df_gis_join_parameter_invoer, df_parameter_invoer], ignore_index=True) + + return df_parameter_invoer_combined + + +def _gather_hrd_frag_line_from_geopackage(ref: str, geopackage_filepath: str): + # Read database + conn = sqlite3.connect(geopackage_filepath) + df_frag_line = read_sql( + f"SELECT * FROM fragility_values_invoer_hrd WHERE fragility_values_ref = '{ref}';", + conn) + conn.close() + + # Validate + assert df_frag_line.__len__() > 2 + # It should be validated beforehand that all added fragility lines are at least 3 points. So if this assert triggers + # something should be improved earlier in validation. + + # Construct Fragility Values + df_frag_line = df_frag_line.sort_values(by=["waarde"]) + frag_points = [] + for index, row in df_frag_line.iterrows(): + fc = FragilityValue() + fc.x = row["waarde"] + fc.probability_of_failure = row["kans"] + frag_points.append(fc) + + return frag_points + + +def _gather_frag_line_from_csv(csv_file_name: str, geopackage_filepath: str): + + # Read csv-file + csv_dir = os.path.join(os.path.dirname(geopackage_filepath), "frag_csv_files") + os.makedirs(csv_dir, exist_ok=True) + path_to_csv = os.path.join(csv_dir, csv_file_name) + if not os.path.exists(path_to_csv): + raise FileNotFoundError( + f"CSV-file with fragility curve not found for reference '{csv_file_name}'. Please make sure to place your " + f"csv-files at the following location: \n{csv_dir}") + df_frag_line = read_csv(path_to_csv, sep=",") + + # Validate + assert df_frag_line.__len__() > 2 + # It should be validated beforehand that all added fragility lines are at least 3 points. So if this assert triggers + # something should be improved earlier in validation. + + # Construct Fragility Values + df_frag_line = df_frag_line.sort_values(by=["waarde"]) + frag_points = [] + for index, row in df_frag_line.iterrows(): + fc = FragilityValue() + fc.x = row["waarde"] + fc.probability_of_failure = row["kans"] + frag_points.append(fc) + + return frag_points + + +def _collect_fragility_values( + tables: InputParameterTables, fragility_refs: List[str], geopackage_filepath: str, +) -> DataFrame: + """ Collects the fragility values from the different sources. The sources are (a) the HRD-file, (b) the Excel input + file, and (c) the csv folder. + + :param tables: + :param fragility_refs: + :param geopackage_filepath: + :return: Returns a dataframe with columns fragility_values_ref and fragility_values. + """ + + df_frag_invoer = tables.df_fragility_values_invoer + available_frag_invoer_refs = df_frag_invoer['fragility_values_ref'].unique() + return_array = [] + for fragility_ref in fragility_refs: + + # From .csv-file (not stored in GeoPackage) + if fragility_ref.endswith(".csv"): + return_array.append({ + "fragility_values_ref": fragility_ref, + "fragility_values": _gather_frag_line_from_csv( + csv_file_name=fragility_ref, geopackage_filepath=geopackage_filepath)}) + + # From HRD-database (previously stored in GeoPackage) + elif fragility_ref not in available_frag_invoer_refs: + return_array.append({ + "fragility_values_ref": fragility_ref, + "fragility_values": _gather_hrd_frag_line_from_geopackage( + ref=fragility_ref, geopackage_filepath=geopackage_filepath)}) + + # Otherwise, retrieve custom curve from Excel (previously stored in GeoPackage) + else: + raise NotImplementedError(f"Should now retrieve it from the df_frag_invoer.") # TODO + + # Build dataframe + if return_array.__len__() == 0: + df = DataFrame(data=[], columns=["fragility_values_ref", "fragility_values"]) + return df + return DataFrame(return_array) + + +def _add_fragility_values_to_combined_parameter_invoer( + df_parameter_invoer_combined: DataFrame, tables: InputParameterTables, geopackage_filepath: str, drop_ref: bool = True) -> DataFrame: + """ Haalt uit de fragility values Excel de arrays op en vervang in de df_parameter_invoer_combined de referentie + met de daadwerkelijke fragility values. """ + + df = df_parameter_invoer_combined.copy(deep=True) + + # Replace empty values with NaN + df['fragility_values_ref'] = df['fragility_values_ref'].replace('', np.nan) + df['fragility_values_ref'] = df['fragility_values_ref'].infer_objects(copy=False) + + # Gather referenced fragility value refs + fragility_refs = df['fragility_values_ref'].dropna().unique() + + # Collect fragility lines + df_frag_lines = _collect_fragility_values( + tables=tables, fragility_refs=fragility_refs, geopackage_filepath=geopackage_filepath) + + # Attach to parameter invoer df + df = df.merge( + df_frag_lines, left_on="fragility_values_ref", right_on="fragility_values_ref", how="left") + + if drop_ref: + df = df.drop(columns=["fragility_values_ref"]) + + return df + + +def _collect_right_columns_combined_parameter_invoer(df_parameter_invoer_combined: DataFrame) -> DataFrame: + """ Parameter tabel omzetten naar juiste kolommen. Enkel per uittredepunt, scenario en parameter de + parameterinvoer. """ + + # Add parameter invoer: op uittredepunten niveau + df_parameter_invoer_combined = df_parameter_invoer_combined.drop(columns=["bronnen", "opmerking"]) + parameter_description_columns = [ + "distribution_type", "mean", "variation", "deviation", "minimum", "maximum", "fragility_values"] + if "fragility_values_ref" in df_parameter_invoer_combined.columns: + parameter_description_columns.append("fragility_values_ref") + df_parameter_invoer_combined['parameter_input'] = df_parameter_invoer_combined.apply(lambda row: { + k: row[k] for k in parameter_description_columns if isinstance(row[k], list) or notna(row[k]) + }, axis=1) + df_parameter_invoer_combined = df_parameter_invoer_combined.drop(columns=parameter_description_columns) + return df_parameter_invoer_combined + + +def _construct_df_identifiers(geopackage_filepath: str, tables: InputParameterTables): + """ Create identifiers table. + + The identifiers table is a table with unique rows (unique uittredepunt, vak and scenario combo). It is used as a + base to explode to input per scenario and uittredepunt. """ + + gdf_uittredepunten: GeoDataFrame = read_file(geopackage_filepath, layer="uittredepunten") + df_identifiers: DataFrame = gdf_uittredepunten[["uittredepunt_id", "vak_id"]] + df_scenario_invoer: DataFrame = tables.df_scenario_invoer + df_identifiers = df_identifiers.merge(df_scenario_invoer, left_on="vak_id", right_on="vak_id") + df_identifiers = df_identifiers.drop(columns=["kans"]) + return df_identifiers + + +def _gather_required_input_parameters(geopackage_filepath: str) -> List[str]: + + conn = sqlite3.connect(geopackage_filepath) + cursor = conn.cursor() + cursor.execute(""" + SELECT geoprob_pipe_metadata."values" + FROM geoprob_pipe_metadata + WHERE metadata_type='geohydrologisch_model'; + """) + result = cursor.fetchone() + if not result: + raise ValueError + model_string = result[0] + conn.close() + df_dummy_data = DataFrame(INITIAL_INPUT_MAPPER[model_string]['input']) + + _ = df_dummy_data.sort_values(by=["name"]) + df_dummy_data = df_dummy_data.sort_values(by=["name"]) + return df_dummy_data['name'].unique().tolist() + # TODO: Return this to use in iteration to retrieve data + + # Method to use the system_function. Not necessary because of the dummy input. But for now kept. + # from geoprob_pipe.calculations.system_calculations.piping_moria.reliability_calculation import \ + # PipingMORIASystemReliabilityCalculation + # from geoprob_pipe.calculations.system_calculations.piping_moria.dummy_input import PIPING_DUMMY_INPUT + # import inspect + # + # reliability_calculation = PipingMORIASystemReliabilityCalculation(PIPING_DUMMY_INPUT) + # sig = inspect.signature(reliability_calculation.given_system_variables_setup_function) + # _ = [ + # name for name, param in sig.parameters.items() + # if param.default == inspect.Parameter.empty and param.kind in (param.POSITIONAL_OR_KEYWORD, param.KEYWORD_ONLY) + # ] + + # return ["mv_exit", "gamma_sat_deklaag"] # TODO + # return ["gamma_sat_deklaag"] # TODO + + +def _expand(df_parameter_invoer_combined: DataFrame, df_identifiers: DataFrame, geopackage_filepath: str) -> Dict[str, DataFrame]: + + # Add parameter invoer: op uittredepunten niveau + required_input_parameters = _gather_required_input_parameters(geopackage_filepath=geopackage_filepath) + collection_of_dfs: Dict[str, DataFrame] = {} + for parameter_name in required_input_parameters: + + # Gather and merge input on uittredepunten-niveau + df_gather = df_parameter_invoer_combined[ + (df_parameter_invoer_combined['parameter'] == parameter_name) & + (df_parameter_invoer_combined['scope'] == 'uittredepunt')] + df_gather = df_gather[["scope_referentie", "parameter_input"]] + df = df_identifiers.copy(deep=True).merge( + df_gather, how="left", left_on="uittredepunt_id", right_on="scope_referentie") + df = df.drop(columns=["scope_referentie"]) + + # Vak / scenario niveau + df_gather = df_parameter_invoer_combined[ + (df_parameter_invoer_combined['parameter'] == parameter_name) & + (df_parameter_invoer_combined['scope'] == 'vak') & + (df_parameter_invoer_combined['ondergrondscenario_naam'].notna())] + df_gather = df_gather[["scope_referentie", "ondergrondscenario_naam", "parameter_input"]] + df_gather = df_gather.rename(columns={ + "scope_referentie": "vak_id", + "ondergrondscenario_naam": "naam"}) + df['parameter_input'] = df['parameter_input'].combine_first( + df_identifiers.copy(deep=True).merge(df_gather, on=["vak_id", "naam"], how="left")['parameter_input']) + + # Vak niveau + df_gather = df_parameter_invoer_combined[ + (df_parameter_invoer_combined['parameter'] == parameter_name) & + (df_parameter_invoer_combined['scope'] == 'vak') & + (df_parameter_invoer_combined['ondergrondscenario_naam'].isna())] + df_gather = df_gather[["scope_referentie", "parameter_input"]] + df_gather = df_gather.rename(columns={"scope_referentie": "vak_id"}) + df['parameter_input'] = df['parameter_input'].combine_first( + df_identifiers.copy(deep=True).merge(df_gather, on=["vak_id"], how="left")['parameter_input']) + + # Traject niveau + df_gather = df_parameter_invoer_combined[ + (df_parameter_invoer_combined['parameter'] == parameter_name) & + (df_parameter_invoer_combined['scope'] == 'traject')] + if df_gather.__len__() >= 1: + traject_value = df_gather['parameter_input'].values[0] + df['parameter_input'] = df['parameter_input'].apply(lambda x: traject_value if isna(x) else x) + + # GIS spatial joins + df_gather = df_parameter_invoer_combined[ + (df_parameter_invoer_combined['parameter'] == parameter_name) & + (df_parameter_invoer_combined['scope'] == 'gis_uittredepunt')].copy(deep=True) + df_gather = df_gather[["scope_referentie", "parameter_input"]] + df_gather = df_gather.rename(columns={"scope_referentie": "uittredepunt_id"}) + df['parameter_input'] = df['parameter_input'].combine_first( + df_identifiers.copy(deep=True).merge(df_gather, on=["uittredepunt_id"], how="left")['parameter_input']) + + # Add to collection + collection_of_dfs[parameter_name] = df + + return collection_of_dfs + + +def _concat_collection(collection: Dict[str, DataFrame]): + for parameter_name, df in collection.items(): + collection[parameter_name]['parameter_name'] = parameter_name + return_df = concat([df for _, df in collection.items()], ignore_index=True) + return_df = return_df.rename(columns={"naam": "ondergrondscenario_naam"}) + return return_df[["parameter_name", "vak_id", "uittredepunt_id", "ondergrondscenario_naam", "parameter_input"]] + + +def run_expand_input_tables(geopackage_filepath: str, add_frag_ref: bool = False) -> DataFrame: + """ + + :param geopackage_filepath: + :param add_frag_ref: Indien True, dan wordt voor parameter input met een distribution_type 'cdf_curve' de referentie + naar de invoer behouden. Deze is niet nodig voor de berekeningen, maar wordt wel gebruikt voor de visualisaties. + :return: + """ + tables = InputParameterTables(geopackage_filepath=geopackage_filepath) + df_identifiers = _construct_df_identifiers(geopackage_filepath=geopackage_filepath, tables=tables) + + # Construct df_parameter_invoer_combined + df_parameter_invoer_combined1 = _combine_parameter_invoer_sources(tables=tables) + df_parameter_invoer_combined2 = _add_fragility_values_to_combined_parameter_invoer( + df_parameter_invoer_combined=df_parameter_invoer_combined1, tables=tables, + geopackage_filepath=geopackage_filepath, drop_ref=add_frag_ref==False) + df_parameter_invoer_combined3 = _collect_right_columns_combined_parameter_invoer( + df_parameter_invoer_combined=df_parameter_invoer_combined2) + + # Expand + collection: Dict[str, DataFrame] = _expand( + df_parameter_invoer_combined=df_parameter_invoer_combined3, + df_identifiers=df_identifiers, + geopackage_filepath=geopackage_filepath) + + return _concat_collection(collection=collection) diff --git a/geoprob_pipe/cmd_app/parameter_input/export_input_parameter_excel.py b/geoprob_pipe/cmd_app/parameter_input/export_input_parameter_excel.py new file mode 100644 index 00000000..14fd0745 --- /dev/null +++ b/geoprob_pipe/cmd_app/parameter_input/export_input_parameter_excel.py @@ -0,0 +1,102 @@ +from __future__ import annotations +import os +import sqlite3 +import shutil +from openpyxl import load_workbook +from pandas import ExcelWriter, DataFrame +from geopandas import read_file, GeoDataFrame +from datetime import datetime +import importlib.resources +from typing import TYPE_CHECKING +from geoprob_pipe.calculations.systems.mappers.initial_input_mapper import INITIAL_INPUT_MAPPER +from geoprob_pipe.utils.validation_messages import BColors +if TYPE_CHECKING: + from geoprob_pipe.cmd_app.cmd import ApplicationSettings + from geoprob_pipe.cmd_app.parameter_input.input_parameter_tables import InputParameterTables + + +def join_vak_naam(df: DataFrame, app_settings: ApplicationSettings, ) -> DataFrame: + gdf_vakindeling: GeoDataFrame = read_file(app_settings.geopackage_filepath, layer="vakindeling") + gdf_vakindeling = gdf_vakindeling.rename(columns={"naam": "vak_naam", "id": "vak_id"}) + df = df.merge(gdf_vakindeling[["vak_naam", "vak_id"]], left_on="vak_id", right_on="vak_id") + return df[["vak_id", "vak_naam", "naam", "kans"]] + + +def export_input_parameter_tables(app_settings: ApplicationSettings, tables: InputParameterTables): + + # Copy template to workspace + dst_dir = os.path.join( + app_settings.workspace_dir, + "exports", + app_settings.datetime_stamp, + "parameter_input_process") + os.makedirs(dst_dir, exist_ok=True) + dst_path = os.path.join(dst_dir, "input_parameters_template.xlsx") + dst_path = dst_path.replace("_template.xlsx", f".xlsx") + if os.path.exists(dst_path): + datetime_stamp = datetime.now().strftime("%Y-%m-%d_%H%M%S") + dst_path = dst_path.replace(".xlsx", f"_{datetime_stamp}.xlsx") + with importlib.resources.path( + package='geoprob_pipe.cmd_app.parameter_input', + resource='parameter_input_template.xlsx' + ) as src_path: + shutil.copy2(src=src_path, dst=dst_path) + + # Fill 'Model parameters' + conn = sqlite3.connect(app_settings.geopackage_filepath) + cursor = conn.cursor() + cursor.execute(""" + SELECT geoprob_pipe_metadata."values" + FROM geoprob_pipe_metadata + WHERE metadata_type='geohydrologisch_model'; + """) + result = cursor.fetchone() + if not result: + raise ValueError + model_string = result[0] + conn.close() + df_dummy_data = DataFrame(INITIAL_INPUT_MAPPER[model_string]['input']) + df_dummy_data = df_dummy_data.sort_values(by=["name"]) + df_model_parameters = df_dummy_data[["name", "description", "remark", "unit"]].copy() + with ExcelWriter(dst_path, engine="openpyxl", mode="a", if_sheet_exists="overlay") as writer: + df_model_parameters.to_excel( + writer, sheet_name="Geohydrologisch model", index=False, header=False, startrow=6, startcol=0) + # TODO: Kolom 'invullen' is nog onduidelijk en niet gevuld. + # Geohydrologisch model in titel + wb = load_workbook(dst_path) + ws = wb["Geohydrologisch model"] + ws["A1"] = f"Geohydrologisch model '{INITIAL_INPUT_MAPPER[model_string]['label']}'" + wb.save(dst_path) + + # Fill 'Scenario invoer' + df_scenario_invoer = tables.df_scenario_invoer + df_scenario_invoer = join_vak_naam(df=df_scenario_invoer, app_settings=app_settings) + with ExcelWriter(dst_path, engine="openpyxl", mode="a", if_sheet_exists="overlay") as writer: + df_scenario_invoer.to_excel( + writer, sheet_name="Scenario invoer", index=False, header=False, startrow=3, startcol=0) + + # Fill 'Parameter invoer' + df_parameter_invoer = tables.df_parameter_invoer + df_parameter_invoer = df_parameter_invoer[[ + "parameter", "scope", "scope_referentie", "ondergrondscenario_naam", "distribution_type", "mean", "variation", + "deviation", "minimum", "maximum", "fragility_values_ref", "bronnen", "opmerking"]].copy() + with ExcelWriter(dst_path, engine="openpyxl", mode="a", if_sheet_exists="overlay") as writer: + df_parameter_invoer.to_excel( + writer, sheet_name="Parameter invoer", index=False, header=False, startrow=4, startcol=0) + + # Fill 'Fragility values' + df_fragility_values_invoer = tables.df_fragility_values_invoer + df_fragility_values_invoer = df_fragility_values_invoer[["fragility_values_ref", "waarde", "kans"]].copy() + with ExcelWriter(dst_path, engine="openpyxl", mode="a", if_sheet_exists="overlay") as writer: + df_fragility_values_invoer.to_excel( + writer, sheet_name="Fragility values", index=False, header=False, startrow=4, startcol=0) + + # Fill 'Correlatie invoer' + df_correlatie_invoer = tables.df_correlatie_invoer + df_correlatie_invoer = df_correlatie_invoer[["parameter_a", "parameter_b", "correlation"]].copy() + with ExcelWriter(dst_path, engine="openpyxl", mode="a", if_sheet_exists="overlay") as writer: + df_correlatie_invoer.to_excel( + writer, sheet_name="Correlatie invoer", index=False, header=False, startrow=4, startcol=0) + + print(f"{BColors.UNDERLINE}Exporteren van invoer tabellen compleet:\n" + f"{dst_path}{BColors.ENDC}") diff --git a/geoprob_pipe/cmd_app/parameter_input/initiate_input_excel_tables.py b/geoprob_pipe/cmd_app/parameter_input/initiate_input_excel_tables.py new file mode 100644 index 00000000..56a7642f --- /dev/null +++ b/geoprob_pipe/cmd_app/parameter_input/initiate_input_excel_tables.py @@ -0,0 +1,108 @@ +from __future__ import annotations +from geopandas import GeoDataFrame, read_file +from typing import TYPE_CHECKING +import sqlite3 +from geoprob_pipe.cmd_app.utils.misc import get_geohydrological_model +from geoprob_pipe.calculations.systems.mappers.initial_input_mapper import INITIAL_INPUT_MAPPER +from pandas import DataFrame +import numpy as np +if TYPE_CHECKING: + from geoprob_pipe.cmd_app.cmd import ApplicationSettings + + +def push_scenario_invoer_tabel(app_settings: ApplicationSettings): + + # Genereer tabel input (o.b.v. vakindeling) + gdf_vakindeling: GeoDataFrame = read_file(app_settings.geopackage_filepath, layer="vakindeling") + gdf_vakindeling = gdf_vakindeling.sort_values(by=["id"]) + df_scenarios = gdf_vakindeling[["id"]].copy() + df_scenarios.loc[:, 'naam'] = "scenario1" + df_scenarios.loc[:, 'kans'] = 1.00 + + # Rename columns + df_scenarios = df_scenarios.rename(columns={"id": "vak_id"}) + + # Push to geopackage + conn = sqlite3.connect(app_settings.geopackage_filepath) + df_scenarios.to_sql("scenario_invoer", conn, if_exists="replace", index=False) + conn.close() + + +def push_parameter_invoer_tabel(app_settings: ApplicationSettings): + + model_string = get_geohydrological_model(app_settings=app_settings) + + # Start base of table + df_dummy_data = DataFrame(INITIAL_INPUT_MAPPER[model_string]['input']) + df_dummy_data = df_dummy_data.sort_values(by=["name"]) + df_parameter_invoer: DataFrame = df_dummy_data[[ + "name", "distribution_type", "mean", "variation", "deviation"]].copy() + + # Rename columns + df_parameter_invoer = df_parameter_invoer.rename(columns={"name": "parameter"}) + + # Convert distribution type objects to string + df_parameter_invoer["distribution_type"] = df_parameter_invoer["distribution_type"].apply(lambda x: x.__str__()) + + # Add missing columns + df_parameter_invoer.loc[:, "scope"] = "traject" + df_parameter_invoer.loc[:, "scope_referentie"] = "" + df_parameter_invoer.loc[:, "ondergrondscenario_naam"] = "" + df_parameter_invoer.loc[:, "bronnen"] = "" + df_parameter_invoer.loc[:, "opmerking"] = "" + df_parameter_invoer.loc[:, "fragility_values_ref"] = "" + df_parameter_invoer.loc[:, "minimum"] = np.nan + df_parameter_invoer.loc[:, "maximum"] = np.nan + + # Sort dataframe + df_parameter_invoer = df_parameter_invoer[[ + "parameter", "scope", "scope_referentie", "ondergrondscenario_naam", + "distribution_type", "mean", "variation", "deviation", "minimum", "maximum", "fragility_values_ref", + "bronnen", "opmerking"]].copy() + + # Push to geopackage + conn = sqlite3.connect(app_settings.geopackage_filepath) + df_parameter_invoer.to_sql("parameter_invoer", conn, if_exists="replace", index=False) + conn.close() + + +def push_fragility_values_invoer_tabel(app_settings: ApplicationSettings): + + # Construct table + water_levels = [3.5, 4, 4.5, 5, 5.5, 6, 6.5, 7, 7.5, 8, 8.5, 9, 9.5, 10] + exceedance_values = [5.8, 4.6, 2.8, 1.7, 1.3, 0.65, 0.377, 0.236, 0.119, 0.048, 0.0195, 0.0069, 0.00134, 0.0001] + example_fragility_values = { + "fragility_values_ref": ["voorbeeld_hr"] * water_levels.__len__(), + "waarde": water_levels, + "kans": exceedance_values} + df_fragility_values_invoer = DataFrame(example_fragility_values) + + # Push to geopackage + conn = sqlite3.connect(app_settings.geopackage_filepath) + df_fragility_values_invoer.to_sql("fragility_values_invoer", conn, if_exists="replace", index=False) + conn.close() + + +DF_EMPTY_CORRELATIE_INVOER = DataFrame({"parameter_a": [], "parameter_b": [], "correlation": []}) + + +def push_correlatie_invoer_tabel(app_settings: ApplicationSettings): + # Push to geopackage + conn = sqlite3.connect(app_settings.geopackage_filepath) + DF_EMPTY_CORRELATIE_INVOER.to_sql("correlatie_invoer", conn, if_exists="replace", index=False) + conn.close() + + +def initiate_input_excel_tables(app_settings: ApplicationSettings): + + # Fill 'Scenario invoer' + push_scenario_invoer_tabel(app_settings=app_settings) + + # Fill 'Parameter invoer' + push_parameter_invoer_tabel(app_settings=app_settings) + + # Fill 'Fragility values invoer' + push_fragility_values_invoer_tabel(app_settings=app_settings) + + # Fill 'Correlatie invoer' + push_correlatie_invoer_tabel(app_settings=app_settings) diff --git a/geoprob_pipe/cmd_app/parameter_input/input_parameter_figures.py b/geoprob_pipe/cmd_app/parameter_input/input_parameter_figures.py new file mode 100644 index 00000000..4ff167c4 --- /dev/null +++ b/geoprob_pipe/cmd_app/parameter_input/input_parameter_figures.py @@ -0,0 +1,481 @@ +from __future__ import annotations +from typing import TYPE_CHECKING +from pandas import DataFrame +import os +import numpy as np +from typing import Optional, Dict, Tuple, List +from geopandas import GeoDataFrame, read_file +from geoprob_pipe.utils.statistics import calc_kar_waarde_lognormal, calc_kar_waarde_normal +import plotly.graph_objects as go +from geoprob_pipe.utils.validation_messages import BColors +if TYPE_CHECKING: + from geoprob_pipe.cmd_app.cmd import ApplicationSettings + from geoprob_pipe.cmd_app.parameter_input.input_parameter_tables import InputParameterTables + + +class InputParameterFigures: + + def __init__(self, app_settings: ApplicationSettings, tables: InputParameterTables, export: bool = False): + self.app_settings: ApplicationSettings = app_settings + self.tables: InputParameterTables = tables + self.export: bool = export + + # Placeholders + self.df_parameter_invoer: Optional[DataFrame] = None + self.dict_vakindeling: Dict[int, Dict] = {} + self.traject_length: Optional[float] = None + self.x_min = 0 + self.x_max = 0 # Will be set + self.y_min = 0 + self.y_max = 0 # Will be adjusted on each parameter + + # Perform logic + self._gather_data() + self._create_figures() + + def _gather_data(self): + + # Dataframe parameter invoer + self.df_parameter_invoer = self.tables.df_parameter_invoer + self.df_gis_join_parameter_invoer = self.tables.df_gis_join_parameter_invoer + + # Lengte traject + gpkg_file_path = self.app_settings.geopackage_filepath + gdf: GeoDataFrame = read_file(gpkg_file_path, layer="dijktraject") + assert gdf.__len__() == 1 + self.traject_length = gdf.iloc[0].geometry.length + self.x_max = self.traject_length + + # Vakindeling dictionary + gdf_vakindeling: GeoDataFrame = read_file(self.app_settings.geopackage_filepath, layer="vakindeling") + self.dict_vakindeling = gdf_vakindeling.set_index('id').to_dict(orient='index') + + # Uittredepunten dictionary + gdf_uittredepunten: GeoDataFrame = read_file(self.app_settings.geopackage_filepath, layer="uittredepunten") + self.dict_uittredepunten = gdf_uittredepunten.set_index('uittredepunt_id').to_dict(orient='index') + + @staticmethod + def _get_display_values_from_row(row) -> Tuple[float, Optional[float], Optional[float]]: + """ + + :param row: + :return: mean, 5% ondergrens, 95% bovengrens + """ + + # Deterministic + mean_value: float = row['mean'] + if row['distribution_type'] == 'deterministic': + return mean_value, None, None + + # Determine standard deviation + variation = row['variation'] + deviation = row['deviation'] + deviation_value: Optional[float] = None + if not np.isnan(deviation): + deviation_value = deviation + elif not np.isnan(variation): + deviation_value = mean_value * variation + else: + ValueError(f"Should have either a variation or deviation. Or maybe a bug and contact the developer.") + + # Log normal + if row['distribution_type'] == 'log_normal': + kar_5pr = calc_kar_waarde_lognormal(mean=mean_value, sd=deviation_value, percentiel=0.05) # TODO: Shift bepalen + kar_95pr = calc_kar_waarde_lognormal(mean=mean_value, sd=deviation_value, percentiel=0.95) + return mean_value, kar_5pr, kar_95pr + + # Normal + if row['distribution_type'] == 'normal': + kar_5pr = calc_kar_waarde_normal(mean=mean_value, std=deviation_value, percentiel=0.05) + kar_95pr = calc_kar_waarde_normal(mean=mean_value, std=deviation_value, percentiel=0.95) + return mean_value, kar_5pr, kar_95pr + + raise ValueError(f"Unknown distribution_type '{row['distribution_type']}'.") + + @staticmethod + def _get_display_values_from_df( + df: DataFrame +) -> Tuple[ + List[float], + Optional[List[Optional[None]]], + Optional[List[Optional[None]]], + ]: + """ Leest de gemiddelde en 5% en 95% karakteristieke waarden uit o.b.v. de mean en deviation. """ + + mean_values = [] + kar5pr_values = [] + kar95pr_values = [] + + for index, row in df.iterrows(): + mean_value = row['mean'] + mean_values.append(mean_value) + if row['distribution_type'] == 'deterministic': + kar5pr_values.append(None) + kar95pr_values.append(None) + continue + deviation_value: Optional[float] = None + if not np.isnan(row['deviation']): + deviation_value = row['deviation'] + elif not np.isnan(row['variation']): + deviation_value = mean_value * row['variation'] + else: + ValueError(f"Should have either a variation or deviation. Or maybe a bug and contact the developer.") + if row['distribution_type'] == 'log_normal': + kar5pr_values.append(calc_kar_waarde_lognormal( + mean=mean_value, sd=deviation_value, percentiel=0.05)) # TODO: Shift bepalen + kar95pr_values.append( + calc_kar_waarde_lognormal(mean=mean_value, sd=deviation_value, percentiel=0.95)) + continue + if row['distribution_type'] == 'normal': + kar5pr_values.append(calc_kar_waarde_normal(mean=mean_value, std=deviation_value, percentiel=0.05)) + kar95pr_values.append(calc_kar_waarde_normal(mean=mean_value, std=deviation_value, percentiel=0.95)) + continue + + return mean_values, kar5pr_values, kar95pr_values + + def _add_geospatial_level_data(self, fig: go.Figure, parameter_name: str) -> go.Figure: + df_filter: DataFrame = self.df_gis_join_parameter_invoer[ + (self.df_gis_join_parameter_invoer['parameter'] == parameter_name) & + (self.df_gis_join_parameter_invoer['scope'] == 'uittredepunt')] + show_legend_item_mean = True + + for index, row in df_filter.iterrows(): + + # Skip cdf curve + if row['distribution_type'] == 'cdf_curve': + continue + + # Add mean + mean, kar_5pr, kar_95pr = self._get_display_values_from_row(row=row) + x_value = self.dict_uittredepunten[row['scope_referentie']]['metrering'] + fig.add_trace(go.Scatter( + x=[x_value], + y=[mean], + mode='markers', + name="Geo-gerefereerd", + legendgroup="Geo-gerefereerd", + showlegend=show_legend_item_mean, + marker=dict(color='rgba(0, 0, 117, 1)', size=10, symbol="circle"))) + show_legend_item_mean = False + + # Add (possibly) deviation + if kar_5pr: + fig.add_trace(go.Scatter( + x=[x_value, x_value], + y=[kar_5pr, kar_5pr], + mode='markers', + name="Geo-gerefereerd", + legendgroup="Geo-gerefereerd", + showlegend=False, + marker=dict(color='rgba(0, 0, 117, 1)', size=10, symbol="triangle-up"))) + if kar_95pr: + fig.add_trace(go.Scatter( + x=[x_value, x_value], + y=[kar_95pr, kar_95pr], + mode='markers', + name="Geo-gerefereerd", + legendgroup="Geo-gerefereerd", + showlegend=False, + marker=dict(color='rgba(0, 0, 117, 1)', size=10, symbol="triangle-down"))) + + return fig + + def _add_traject_level_data(self, fig: go.Figure, parameter_name: str) -> go.Figure: + df_filter = self.df_parameter_invoer[ + (self.df_parameter_invoer['parameter'] == parameter_name) & + (self.df_parameter_invoer['scope'] == 'traject')] + for index, row in df_filter.iterrows(): + + # Skip cdf curve + if row['distribution_type'] == 'cdf_curve': + continue + + mean, kar_5pr, kar_95pr = self._get_display_values_from_row(row=row) + fig.add_trace(go.Scatter( + x=[self.x_min, self.x_max, self.x_max, self.x_min, self.x_min], + y=[self.y_min, self.y_min, mean, mean, self.y_min], + fill='toself', + mode='lines', + fillcolor='lightblue', + name="Traject-niveau", + legendgroup="Traject-niveau", + showlegend=True, + line=dict(width=1, color="rgb(0, 0, 0)"), + )) + + # Add (possibly) kar values + if kar_5pr: + fig.add_trace(go.Scatter( + x=[self.x_min, self.x_max], + y=[kar_5pr, kar_5pr], + mode='lines', + name="Traject-niveau", + legendgroup="Traject-niveau", + showlegend=False, + line=dict(width=4, color="rgba(0, 0, 0, 1)"), + )) + if kar_95pr: + fig.add_trace(go.Scatter( + x=[self.x_min, self.x_max], + y=[kar_95pr, kar_95pr], + mode='lines', + name="Traject-niveau", + legendgroup="Traject-niveau", + showlegend=False, + line=dict(width=4, color="rgba(0, 0, 0, 1)", dash='dot'), + )) + + return fig + + def _add_vak_level_data(self, fig: go.Figure, parameter_name: str) -> go.Figure: + df_filter: DataFrame = self.df_parameter_invoer[ + (self.df_parameter_invoer['parameter'] == parameter_name) & + (self.df_parameter_invoer['scope'] == 'vak') & + (self.df_parameter_invoer['ondergrondscenario_naam'].isna()) + ] + show_legend_item = True + + for index, row in df_filter.iterrows(): + + # Skip cdf curve + if row['distribution_type'] == 'cdf_curve': + continue + + mean, kar_5pr, kar_95pr = self._get_display_values_from_row(row=row) + vak_id = row['scope_referentie'] + x_min = self.dict_vakindeling[vak_id]['m_start'] + x_max = self.dict_vakindeling[vak_id]['m_end'] + + # Add mean + fig.add_trace(go.Scatter( + x=[x_min, x_max, x_max, x_min, x_min], + y=[self.y_min, self.y_min, mean, mean, self.y_min], + fill='toself', + mode='lines', + fillcolor='orange', + name="Vak-niveau", + legendgroup="Vak-niveau", + showlegend=show_legend_item, + line=dict(width=1, color="rgba(0, 0, 0, 1)"), + )) + show_legend_item = False + + # Add (possibly) deviation + if kar_5pr: + fig.add_trace(go.Scatter( + x=[x_min, x_max], + y=[kar_5pr, kar_5pr], + mode='lines', + name="Vak-niveau", + legendgroup="Vak-niveau", + showlegend=False, + line=dict(width=4, color="rgba(0, 0, 0, 1)"))) + if kar_95pr: + fig.add_trace(go.Scatter( + x=[x_min, x_max], + y=[kar_95pr, kar_95pr], + mode='lines', + name="Vak-niveau", + legendgroup="Vak-niveau", + showlegend=False, + line=dict(width=4, color="rgba(0, 0, 0, 1)", dash='dot'))) + + return fig + + def _add_vak_level_per_scenario_data(self, fig: go.Figure, parameter_name: str) -> go.Figure: + df_filter: DataFrame = self.df_parameter_invoer[ + (self.df_parameter_invoer['parameter'] == parameter_name) & + (self.df_parameter_invoer['scope'] == 'vak') & + (self.df_parameter_invoer['ondergrondscenario_naam'].notna())] + show_legend_item = True + + for vak_id in df_filter['scope_referentie'].unique(): + df_filter2 = df_filter[df_filter['scope_referentie'] == vak_id] + mean_values, kar_5pr_values, kar_95pr_values = self._get_display_values_from_df(df_filter2) + max_mean = max(mean_values) + x_min = self.dict_vakindeling[vak_id]['m_start'] + x_max = self.dict_vakindeling[vak_id]['m_end'] + + # Add max mean with fill to self + fig.add_trace(go.Scatter( + x=[x_min, x_max, x_max, x_min, x_min], + y=[self.y_min, self.y_min, max_mean, max_mean, self.y_min], + fill='toself', + mode='lines', + fillcolor='rgb(148, 103, 189)', + name="Vak-niveau per scenario", + legendgroup="Vak-niveau per scenario", + showlegend=show_legend_item, + line=dict(width=1, color="rgba(0, 0, 0, 1)"), + )) + show_legend_item = False + + # Add (possibly) deviation + for mean, kar_5pr_value, kar_95pr_value in zip(mean_values, kar_5pr_values, kar_95pr_values): + if mean is not max_mean: + fig.add_trace(go.Scatter( + x=[x_min, x_max], + y=[mean, mean], + mode='lines', + name="Vak-niveau per scenario", + legendgroup="Vak-niveau per scenario", + showlegend=False, + line=dict(width=1, color="rgba(0, 0, 0, 1)"))) + if kar_5pr_value is not None: + fig.add_trace(go.Scatter( + x=[x_min, x_max], + y=[kar_5pr_value, kar_5pr_value], + mode='lines', + name="Vak-niveau per scenario", + legendgroup="Vak-niveau per scenario", + showlegend=False, + line=dict(width=4, color="rgba(0, 0, 0, 1)"))) + if kar_95pr_value is not None: + fig.add_trace(go.Scatter( + x=[x_min, x_max], + y=[kar_95pr_value, kar_95pr_value], + mode='lines', + name="Vak-niveau per scenario", + legendgroup="Vak-niveau per scenario", + showlegend=False, + line=dict(width=4, color="rgba(0, 0, 0, 1)", dash='dot'))) + + return fig + + def _add_uittredepunt_level_data(self, fig: go.Figure, parameter_name: str) -> go.Figure: + df_filter: DataFrame = self.df_parameter_invoer[ + (self.df_parameter_invoer['parameter'] == parameter_name) & + (self.df_parameter_invoer['scope'] == 'uittredepunt')] + show_legend_item_mean = True + + # print(f"{df_filter.columns=}") + for index, row in df_filter.iterrows(): + + # Skip cdf curve + if row['distribution_type'] == 'cdf_curve': + continue + + mean, kar_5pr, kar_95pr = self._get_display_values_from_row(row=row) + x_value = self.dict_uittredepunten[row['scope_referentie']]['metrering'] + + # Add mean + fig.add_trace(go.Scatter( + x=[x_value], + y=[mean], + mode='markers', + name="Uittredepunt-niveau", + legendgroup="Uittredepunt-niveau", + showlegend=show_legend_item_mean, + marker=dict(color='rgba(0, 0, 0, 1)', size=10, symbol="circle"), + )) + show_legend_item_mean = False + + # Add (possibly) deviation + if kar_5pr: + fig.add_trace(go.Scatter( + x=[x_value, x_value], + y=[kar_5pr, kar_5pr], + mode='markers', + name="Uittredepunt-niveau", + legendgroup="Uittredepunt-niveau", + showlegend=False, + marker=dict(color='rgba(0, 0, 0, 1)', size=10, symbol="triangle-up"))) + if kar_95pr: + fig.add_trace(go.Scatter( + x=[x_value, x_value], + y=[kar_95pr, kar_95pr], + mode='markers', + name="Uittredepunt-niveau", + legendgroup="Uittredepunt-niveau", + showlegend=False, + marker=dict(color='rgba(0, 0, 0, 1)', size=10, symbol="triangle-down"))) + + return fig + + @staticmethod + def _add_legend_symbols(fig: go.Figure) -> go.Figure: + fig.add_trace(go.Scatter( + x=[-1000, -1000], + y=[0, 0], + mode='lines', + name="95% bovengrens", + legendgroup="95% bovengrens", + showlegend=True, + line=dict(width=4, color="rgba(0, 0, 0, 1)", dash='dot'))) + fig.add_trace(go.Scatter( + x=[-1000, -1000], + y=[0, 0], + mode='lines', + name="5% ondergrens", + legendgroup="5% ondergrens", + showlegend=True, + line=dict(width=4, color="rgba(0, 0, 0, 1)"))) + fig.add_trace(go.Scatter( + x=[-1000, -1000], + y=[0, 0], + mode='markers', + name="95% bovengrens", + legendgroup="95% bovengrens", + showlegend=True, + marker=dict(color='rgba(0, 0, 0, 1)', size=10, symbol="triangle-down"))) + fig.add_trace(go.Scatter( + x=[-1000, -1000], + y=[0, 0], + mode='markers', + name="5% ondergrens", + legendgroup="5% ondergrens", + showlegend=True, + marker=dict(color='rgba(0, 0, 0, 1)', size=10, symbol="triangle-up"))) + + return fig + + def _create_figures(self): + export_dir = os.path.join( + self.app_settings.workspace_dir, + "exports", + self.app_settings.datetime_stamp, + "parameter_input_process") + os.makedirs(export_dir, exist_ok=True) + + # TODO: Overal hovers toepassen + + parameters_to_iterate = self.df_gis_join_parameter_invoer['parameter'].unique().tolist() + parameters_to_iterate.extend(self.df_parameter_invoer['parameter'].unique().tolist()) + for parameter_name in parameters_to_iterate: + + # Initiate figure + fig = go.Figure() + + # Add geospatial-level + self._add_geospatial_level_data(fig=fig, parameter_name=parameter_name) + + # Add traject-level + fig = self._add_traject_level_data(fig=fig, parameter_name=parameter_name) + + # Add vak-level + fig = self._add_vak_level_data(fig=fig, parameter_name=parameter_name) + + # Add vak-level per scenario + fig = self._add_vak_level_per_scenario_data(fig=fig, parameter_name=parameter_name) + + # Add uittredepunten-level + fig = self._add_uittredepunt_level_data(fig=fig, parameter_name=parameter_name) + + # Add some legend items + fig = self._add_legend_symbols(fig=fig) + + # Update layout + fig.update_layout( + title=f"Parameter invoer voor '{parameter_name}'", + xaxis_title="Metrering [m]", + yaxis_title="Y-as") + fig.update_layout(xaxis=dict(range=[0, self.x_max])) + + # Export figure + if self.export: + export_path = os.path.join(export_dir, f"parameter_invoer_{parameter_name}.html") + fig.write_html(export_path, include_plotlyjs='cdn') + + if self.export: + print(f"{BColors.UNDERLINE}Overzichtsfiguren van de invoertabellen zijn geëxporteerd naar:\n" + f"{export_dir}{BColors.ENDC}") diff --git a/geoprob_pipe/cmd_app/parameter_input/input_parameter_tables.py b/geoprob_pipe/cmd_app/parameter_input/input_parameter_tables.py new file mode 100644 index 00000000..9b171a27 --- /dev/null +++ b/geoprob_pipe/cmd_app/parameter_input/input_parameter_tables.py @@ -0,0 +1,59 @@ +from __future__ import annotations +from pandas import DataFrame +import sqlite3 +from pandas import read_sql, read_excel +from typing import Optional +from geoprob_pipe.cmd_app.parameter_input.initiate_input_excel_tables import DF_EMPTY_CORRELATIE_INVOER + + +def _load_df_correlatie_invoer_from_geopackage(geopackage_filepath: str) -> DataFrame: + + # Check if table exists in geopackage (older versions don't have this) + conn = sqlite3.connect(geopackage_filepath) + cursor = conn.cursor() + cursor.execute(f"SELECT name FROM sqlite_master WHERE type='table' AND name='correlatie_invoer';") + bool_table_exists = cursor.fetchone() is not None + + # Return empty if not exists + if not bool_table_exists: + return DF_EMPTY_CORRELATIE_INVOER + + # Return db table if exists + df_correlatie_invoer = read_sql("SELECT * FROM correlatie_invoer;", conn) + conn.close() + return df_correlatie_invoer + + +class InputParameterTables: + + def __init__(self, geopackage_filepath: str, path_to_excel: Optional[str] = None): + + # Placeholders + self.df_scenario_invoer: Optional[DataFrame] = None + self.df_parameter_invoer: Optional[DataFrame] = None + self.df_fragility_values_invoer: Optional[DataFrame] = None + self.df_correlatie_invoer: Optional[DataFrame] = None + + if path_to_excel is not None: + self._load_data_from_excel(path_to_excel=path_to_excel, geopackage_filepath=geopackage_filepath) + else: + self._load_data_from_geopackage(geopackage_filepath=geopackage_filepath) + + def _load_data_from_geopackage(self, geopackage_filepath: str): + conn = sqlite3.connect(geopackage_filepath) + df_scenario_invoer = read_sql("SELECT * FROM scenario_invoer;", conn) + self.df_scenario_invoer = df_scenario_invoer[["vak_id", "naam", "kans"]] + self.df_parameter_invoer = read_sql("SELECT * FROM parameter_invoer;", conn) + self.df_gis_join_parameter_invoer = read_sql("SELECT * FROM gis_join_parameter_invoer;", conn) + self.df_fragility_values_invoer = read_sql("SELECT * FROM fragility_values_invoer;", conn) + self.df_correlatie_invoer = _load_df_correlatie_invoer_from_geopackage(geopackage_filepath=geopackage_filepath) + conn.close() + + def _load_data_from_excel(self, path_to_excel: str, geopackage_filepath: str): + self.df_scenario_invoer = read_excel(path_to_excel, sheet_name="Scenario invoer", header=2) + self.df_parameter_invoer = read_excel(path_to_excel, sheet_name="Parameter invoer", header=3) + conn = sqlite3.connect(geopackage_filepath) + self.df_gis_join_parameter_invoer = read_sql("SELECT * FROM gis_join_parameter_invoer;", conn) + conn.close() + self.df_fragility_values_invoer = read_excel(path_to_excel, sheet_name="Fragility values", header=3) + self.df_correlatie_invoer = read_excel(path_to_excel, sheet_name="Correlatie invoer", header=3) diff --git a/geoprob_pipe/cmd_app/parameter_input/parameter_input_template.xlsx b/geoprob_pipe/cmd_app/parameter_input/parameter_input_template.xlsx new file mode 100644 index 00000000..8a9fc933 Binary files /dev/null and b/geoprob_pipe/cmd_app/parameter_input/parameter_input_template.xlsx differ diff --git a/geoprob_pipe/cmd_app/questionnaire.py b/geoprob_pipe/cmd_app/questionnaire.py new file mode 100644 index 00000000..bc7fbc28 --- /dev/null +++ b/geoprob_pipe/cmd_app/questionnaire.py @@ -0,0 +1,52 @@ +from __future__ import annotations +from geoprob_pipe.cmd_app.general import created_project, created_model +from geoprob_pipe.cmd_app.spatial_layers import ( + added_dijktraject, added_vakindeling, added_uittredepunten, added_hrd, added_polderpeil, added_binnenteenlijn, + added_buitenteenlijn, added_intredelijn, added_ahn) +from geoprob_pipe.cmd_app.spatial_joins import ( + coupled_hrd_to_uittredepunten, coupled_distances_to_uittredepunten, coupled_polderpeil_to_uittredepunten, + coupled_uittredepunten_to_refline, coupled_uittredepunten_to_vakken, coupled_mv_exit_to_gis_parameter_invoer_table) +from geoprob_pipe.cmd_app.parameter_input.added_input_parameters import added_input_parameter_data +from typing import TYPE_CHECKING +from geoprob_pipe.cmd_app.run_calculations.run import run_calculations +import sys +if TYPE_CHECKING: + from geoprob_pipe.cmd_app.cmd import ApplicationSettings + + +EARLY_EXIT_MESSAGE = f"Applicatie vroegtijdig afgesloten" + + +def start_questionnaire(app_settings: ApplicationSettings): + if not created_project(app_settings=app_settings): sys.exit(EARLY_EXIT_MESSAGE) + questionnaire(app_settings=app_settings) + + +def questionnaire(app_settings: ApplicationSettings): + print(f"\nALGEMEEN") + if not created_model(app_settings=app_settings): sys.exit(EARLY_EXIT_MESSAGE) + + print(f"\nGIS LAGEN") + if not added_dijktraject(app_settings=app_settings): sys.exit(EARLY_EXIT_MESSAGE) + if not added_vakindeling(app_settings=app_settings): sys.exit(EARLY_EXIT_MESSAGE) + if not added_hrd(app_settings=app_settings): sys.exit(EARLY_EXIT_MESSAGE) + if not added_uittredepunten(app_settings=app_settings): sys.exit(EARLY_EXIT_MESSAGE) + if not added_polderpeil(app_settings=app_settings): sys.exit(EARLY_EXIT_MESSAGE) + if not added_binnenteenlijn(app_settings=app_settings): sys.exit(EARLY_EXIT_MESSAGE) + if not added_buitenteenlijn(app_settings=app_settings): sys.exit(EARLY_EXIT_MESSAGE) + if not added_intredelijn(app_settings=app_settings): sys.exit(EARLY_EXIT_MESSAGE) + added_ahn(app_settings=app_settings, display_added_msg=True) # AHN may be optional + + print(f"\nGEOGRAFISCHE KOPPELINGEN") + if not coupled_uittredepunten_to_refline(app_settings=app_settings): sys.exit(EARLY_EXIT_MESSAGE) + if not coupled_hrd_to_uittredepunten(app_settings=app_settings): sys.exit(EARLY_EXIT_MESSAGE) + if not coupled_distances_to_uittredepunten(app_settings=app_settings): sys.exit(EARLY_EXIT_MESSAGE) + if not coupled_polderpeil_to_uittredepunten(app_settings=app_settings): sys.exit(EARLY_EXIT_MESSAGE) + if not coupled_uittredepunten_to_vakken(app_settings=app_settings): sys.exit(EARLY_EXIT_MESSAGE) + if not coupled_mv_exit_to_gis_parameter_invoer_table(app_settings=app_settings): sys.exit(EARLY_EXIT_MESSAGE) + + print(f"\nPARAMETER INVOER") + if not added_input_parameter_data(app_settings=app_settings): sys.exit(EARLY_EXIT_MESSAGE) + + print(f"\nBEREKENINGEN UITVOEREN") + if not run_calculations(app_settings=app_settings): sys.exit(EARLY_EXIT_MESSAGE) diff --git a/geoprob_pipe/cmd_app/run_calculations/__init__.py b/geoprob_pipe/cmd_app/run_calculations/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/geoprob_pipe/cmd_app/run_calculations/run.py b/geoprob_pipe/cmd_app/run_calculations/run.py new file mode 100644 index 00000000..553a4dd8 --- /dev/null +++ b/geoprob_pipe/cmd_app/run_calculations/run.py @@ -0,0 +1,69 @@ +from __future__ import annotations +from InquirerPy import inquirer +from geoprob_pipe import GeoProbPipe +import sys +from geoprob_pipe.utils.validation_messages import BColors +from typing import TYPE_CHECKING, List + +if TYPE_CHECKING: + from geoprob_pipe.cmd_app.cmd import ApplicationSettings + + +def request_vakken_to_run() -> str: + list_vak_nummers_int: List[int] = [] + vakken_input_is_valid = False + while vakken_input_is_valid is False: + vakken_input: str = inquirer.text( + message="Specificeer welke vakken je wilt doorrekenen. Doe dit door comma-separated de vak nummers (id) " + "op te geven. Bijvoorbeeld '4,5,6,7'.", + ).execute() + + # Convert to integers + vakken_input = vakken_input.replace(" ", "") + list_vak_nummers_str = vakken_input.split(sep=",") + try: + list_vak_nummers_int = [int(vak_id) for vak_id in list_vak_nummers_str] + except ValueError: + print(f"{BColors.WARNING}Het bestand moet of een geopackage, shapefile of geodatabase zijn. Jouw invoer " + f"eindigt op de extensie .{vakken_input.split(sep='.')[-1]}.{BColors.ENDC}") + continue + + # Assure more than one vak id is given + if list_vak_nummers_int.__len__() == 0: + print(f"{BColors.WARNING}Het bestand moet of een geopackage, shapefile of geodatabase zijn. Jouw invoer " + f"eindigt op de extensie .{vakken_input.split(sep='.')[-1]}.{BColors.ENDC}") + continue + + vakken_input_is_valid = True + + return f"vakken:{','.join([str(item) for item in list_vak_nummers_int])}" + + +def run_calculations(app_settings: ApplicationSettings) -> bool: + choices_list = [ + "Ja, alles", + "Ja, specifieke vakken", + "Nee (applicatie sluit af)" + ] + choice = inquirer.select( + message="Wil je de berekeningen uitvoeren? \n" + "Let op: Indien je al rekenresultaten hebt, zullen deze verwijderd worden, alvorens de nieuwe " + "resultaten worden opgeslagen. ", choices=choices_list, default=choices_list[0], + ).execute() + + if choice == choices_list[0]: + geoprob_pipe = GeoProbPipe(app_settings) + geoprob_pipe.export_archive() + print(BColors.OKBLUE, f"✅ Berekeningen zijn uitgevoerd.", BColors.ENDC) + elif choice == choices_list[1]: + vakken_str: str = request_vakken_to_run() + app_settings.to_run = vakken_str + geoprob_pipe = GeoProbPipe(app_settings) + geoprob_pipe.export_archive() + print(BColors.OKBLUE, f"✅ Berekeningen zijn uitgevoerd, voor vakken " + f"{app_settings.to_run.replace("vakken:", "")}.", BColors.ENDC) + elif choice == choices_list[2]: + sys.exit(f"Applicatie is afgesloten.") + else: + raise ValueError + return True diff --git a/geoprob_pipe/cmd_app/spatial_joins/__init__.py b/geoprob_pipe/cmd_app/spatial_joins/__init__.py new file mode 100644 index 00000000..73a4725f --- /dev/null +++ b/geoprob_pipe/cmd_app/spatial_joins/__init__.py @@ -0,0 +1,7 @@ +from geoprob_pipe.cmd_app.spatial_joins.coupled_hrd import coupled_hrd_to_uittredepunten +from geoprob_pipe.cmd_app.spatial_joins.coupled_distance_to_exit_points import ( + coupled_distances_to_uittredepunten) +from geoprob_pipe.cmd_app.spatial_joins.coupled_polderpeil import coupled_polderpeil_to_uittredepunten +from geoprob_pipe.cmd_app.spatial_joins.coupled_exit_points_to_refline import coupled_uittredepunten_to_refline +from geoprob_pipe.cmd_app.spatial_joins.coupled_exit_points_to_vakken import coupled_uittredepunten_to_vakken +from geoprob_pipe.cmd_app.spatial_joins.coupled_mv_exit import coupled_mv_exit_to_gis_parameter_invoer_table diff --git a/geoprob_pipe/cmd_app/spatial_joins/coupled_distance_to_exit_points.py b/geoprob_pipe/cmd_app/spatial_joins/coupled_distance_to_exit_points.py new file mode 100644 index 00000000..7bcd785b --- /dev/null +++ b/geoprob_pipe/cmd_app/spatial_joins/coupled_distance_to_exit_points.py @@ -0,0 +1,59 @@ +""" +TODO Nu Must Klein: Voeg laag toe aan GeoPackage met visuele koppeling tussen intrede en uittredepunten. +""" + +from __future__ import annotations +from geopandas import GeoDataFrame, read_file +from pathlib import Path +from geoprob_pipe.cmd_app.spatial_joins.utils import append_to_gis_join_parameter_invoer_table +from geoprob_pipe.utils.validation_messages import BColors +from typing import TYPE_CHECKING +if TYPE_CHECKING: + from geoprob_pipe.cmd_app.cmd import ApplicationSettings + + +def coupled_distances_to_uittredepunten(app_settings: ApplicationSettings) -> bool: + + # Read uittredepunten + gdf_exit_points: GeoDataFrame = read_file(app_settings.geopackage_filepath, layer="uittredepunten") + + # Check if already added + columns = gdf_exit_points.columns + if "afstand_intredelijn" in columns and "afstand_buitenteenlijn" in columns and "afstand_binnenteenlijn" in columns: + print(BColors.OKBLUE, + f"✔ Afstanden intrede, buitenteen en binnenteen al gekoppeld aan uittredepunten.", BColors.ENDC) + return True # Assuming already added + # TODO: Uitfaseren dat deze kolommen gekoppeld worden aan de exit_points tabel + + # Distance to intredelijn + gdf_intredelijnen: GeoDataFrame = read_file(app_settings.geopackage_filepath, layer="intredelijn") + gdf_exit_points['afstand_intredelijn'] = gdf_exit_points.geometry.apply( + lambda pnt: round(gdf_intredelijnen.distance(pnt).min(), 1)) + df_l_intrede = gdf_exit_points[["uittredepunt_id", "afstand_intredelijn"]] + df_l_intrede = df_l_intrede.rename(columns={"afstand_intredelijn": "mean"}) + append_to_gis_join_parameter_invoer_table( + df_sjoin=df_l_intrede, parameter_name="L_intrede", geopackage_filepath=app_settings.geopackage_filepath) + + # Distance to buitenteenlijn + gdf_buitenteenlijnen: GeoDataFrame = read_file(app_settings.geopackage_filepath, layer="buitenteenlijn") + gdf_exit_points['afstand_buitenteenlijn'] = gdf_exit_points.geometry.apply( + lambda pnt: round(gdf_buitenteenlijnen.distance(pnt).min(), 1)) + df_l_but = gdf_exit_points[["uittredepunt_id", "afstand_buitenteenlijn"]] + df_l_but = df_l_but.rename(columns={"afstand_buitenteenlijn": "mean"}) + append_to_gis_join_parameter_invoer_table( + df_sjoin=df_l_but, parameter_name="L_but", geopackage_filepath=app_settings.geopackage_filepath) + + # Distance to binnenteenlijn + gdf_binnenteenlijn: GeoDataFrame = read_file(app_settings.geopackage_filepath, layer="binnenteenlijn") + gdf_exit_points['afstand_binnenteenlijn'] = gdf_exit_points.geometry.apply( + lambda pnt: round(gdf_binnenteenlijn.distance(pnt).min(), 1)) + df_l_intrede = gdf_exit_points[["uittredepunt_id", "afstand_binnenteenlijn"]] + df_l_intrede = df_l_intrede.rename(columns={"afstand_binnenteenlijn": "mean"}) + append_to_gis_join_parameter_invoer_table( + df_sjoin=df_l_intrede, parameter_name="L_bit", geopackage_filepath=app_settings.geopackage_filepath) + + # Store back in geopackage + gdf_exit_points.to_file(Path(app_settings.geopackage_filepath), layer="uittredepunten", driver="GPKG") + print(BColors.OKBLUE, + f"✅ Afstanden intrede, buitenteen en binnenteen zijn nu gekoppeld aan de uittredepunten.", BColors.ENDC) + return True diff --git a/geoprob_pipe/cmd_app/spatial_joins/coupled_exit_points_to_refline.py b/geoprob_pipe/cmd_app/spatial_joins/coupled_exit_points_to_refline.py new file mode 100644 index 00000000..05dee1eb --- /dev/null +++ b/geoprob_pipe/cmd_app/spatial_joins/coupled_exit_points_to_refline.py @@ -0,0 +1,47 @@ +from __future__ import annotations +from typing import TYPE_CHECKING +from shapely import MultiLineString, LineString +from geoprob_pipe.utils.validation_messages import BColors +from geopandas import GeoDataFrame, read_file +from pathlib import Path +if TYPE_CHECKING: + from geoprob_pipe.cmd_app.cmd import ApplicationSettings + + +def coupled_uittredepunten_to_refline(app_settings: ApplicationSettings) -> bool: + """ Controleert of de metrering al gekoppeld is aan de uittredepunten. Indien dit niet het geval is, doet deze + functie dat automatisch. """ + + # Read uittredepunten + gdf_exit_points: GeoDataFrame = read_file(app_settings.geopackage_filepath, layer="uittredepunten") + + # Check if already added + if "metrering" in gdf_exit_points.columns and "afstand_reflijn" in gdf_exit_points.columns: + print(BColors.OKBLUE, f"✔ Afstand en metrering tot reflijn al gekoppeld aan uittredepunten.", BColors.ENDC) + return True # Assuming already added + + gdf_dijktraject: GeoDataFrame = read_file(app_settings.geopackage_filepath, layer="dijktraject") + gdf_dijktraject_geom = gdf_dijktraject.iloc[0].geometry + if isinstance(gdf_dijktraject_geom, MultiLineString): + assert gdf_dijktraject_geom.geoms.__len__() == 1 + ls_dijktraject: LineString = gdf_dijktraject_geom.geoms[0] + elif isinstance(gdf_dijktraject_geom, LineString): + ls_dijktraject: LineString = gdf_dijktraject_geom + else: + raise NotImplementedError(f"Type of {type(gdf_dijktraject_geom)} is not yet implemented.") + + # Spatial analyses + gdf_exit_points['metrering'] = gdf_exit_points.geometry.apply( + lambda pnt: round(ls_dijktraject.project(pnt), 1)) + gdf_exit_points['afstand_reflijn'] = gdf_exit_points.geometry.apply( + lambda pnt: round(ls_dijktraject.distance(pnt), 1)) + + # Add uittredepunt id + gdf_exit_points = gdf_exit_points.sort_values(by=["metrering"]) + gdf_exit_points['uittredepunt_id'] = range(1, len(gdf_exit_points) + 1) + + # Store back in geopackage + gdf_exit_points.to_file(Path(app_settings.geopackage_filepath), layer="uittredepunten", driver="GPKG") + print(BColors.OKBLUE, + f"✅ Afstand en metrering tot reflijn zijn nu gekoppeld aan de uittredepunten.", BColors.ENDC) + return True diff --git a/geoprob_pipe/cmd_app/spatial_joins/coupled_exit_points_to_vakken.py b/geoprob_pipe/cmd_app/spatial_joins/coupled_exit_points_to_vakken.py new file mode 100644 index 00000000..4f418e8a --- /dev/null +++ b/geoprob_pipe/cmd_app/spatial_joins/coupled_exit_points_to_vakken.py @@ -0,0 +1,34 @@ +from __future__ import annotations +from typing import TYPE_CHECKING +from geoprob_pipe.utils.validation_messages import BColors +from geopandas import GeoDataFrame, read_file +from pathlib import Path +if TYPE_CHECKING: + from geoprob_pipe.cmd_app.cmd import ApplicationSettings + + +def coupled_uittredepunten_to_vakken(app_settings: ApplicationSettings) -> bool: + + # Read uittredepunten + gdf_exit_points: GeoDataFrame = read_file(app_settings.geopackage_filepath, layer="uittredepunten") + + # Check if already added + if "vak_id" in gdf_exit_points.columns: + print(BColors.OKBLUE, f"✔ Vakken al gekoppeld aan uittredepunten.", BColors.ENDC) + return True # Assuming already added + + # Spatial analyses + gdf_vakindeling: GeoDataFrame = read_file(app_settings.geopackage_filepath, layer="vakindeling") + gdf_exit_points_with_vakken = gdf_exit_points.sjoin_nearest( + gdf_vakindeling[['geometry', 'id']], how='left', distance_col='distance') + + # Define which columns to keep (after spatial join) + columns_to_keep = list(gdf_exit_points.columns) + columns_to_keep.append("id") + gdf_new_exit_points = gdf_exit_points_with_vakken[columns_to_keep] + gdf_new_exit_points = gdf_new_exit_points.rename(columns={"id": "vak_id"}) + + # Store back in geopackage + gdf_new_exit_points.to_file(Path(app_settings.geopackage_filepath), layer="uittredepunten", driver="GPKG") + print(BColors.OKBLUE, f"✅ Vakken zijn nu gekoppeld aan de uittredepunten.", BColors.ENDC) + return True diff --git a/geoprob_pipe/cmd_app/spatial_joins/coupled_hrd.py b/geoprob_pipe/cmd_app/spatial_joins/coupled_hrd.py new file mode 100644 index 00000000..e778e1c2 --- /dev/null +++ b/geoprob_pipe/cmd_app/spatial_joins/coupled_hrd.py @@ -0,0 +1,43 @@ +""" +TODO Nu Must Klein: Voeg laag toe aan GeoPackage met visuele koppeling tussen HRD en uittredepunten. +""" + +from __future__ import annotations +from geopandas import GeoDataFrame, read_file +from pathlib import Path +from geoprob_pipe.cmd_app.spatial_joins.utils import append_hrd_to_gis_join_parameter_invoer_table +from geoprob_pipe.utils.validation_messages import BColors +from typing import TYPE_CHECKING +if TYPE_CHECKING: + from geoprob_pipe.cmd_app.cmd import ApplicationSettings + + +def coupled_hrd_to_uittredepunten(app_settings: ApplicationSettings) -> bool: + + # Getting necessary GeoDataframes + gdf_exit_points: GeoDataFrame = read_file(app_settings.geopackage_filepath, layer="uittredepunten") + gdf_hrd_locations: GeoDataFrame = read_file(app_settings.geopackage_filepath, layer="hrd_locaties") + + # Check if already added + if "hrd_name" in gdf_exit_points.columns: + print(BColors.OKBLUE, f"✔ HRD-locaties al gekoppeld aan uittredepunten.", BColors.ENDC) + return True # Assuming already added + + # Perform spatial join to find the nearest HRD-location for each Exit Point + gdf_exit_with_hrd = gdf_exit_points.sjoin_nearest( + gdf_hrd_locations[['geometry', 'location_name']], how='left', distance_col='distance') + + # Define which columns to keep (after spatial join) + columns_to_keep = list(gdf_exit_points.columns) + columns_to_keep.append("location_name") + gdf_new_exit_points = gdf_exit_with_hrd[columns_to_keep] + gdf_new_exit_points = gdf_new_exit_points.rename(columns={"location_name": "hrd_name"}) + append_hrd_to_gis_join_parameter_invoer_table( + df_sjoin=gdf_new_exit_points[["uittredepunt_id", "hrd_name"]], + geopackage_filepath=app_settings.geopackage_filepath) + + # Store back in geopackage + gdf_new_exit_points.to_file(Path(app_settings.geopackage_filepath), layer="uittredepunten", driver="GPKG") + # TODO: Uitfaseren dat HRD-koppeling middels direct aan de geometrie van het uittredepunt zit. + print(BColors.OKBLUE, f"✅ HRD-locaties zijn nu gekoppeld aan de uittredepunten.", BColors.ENDC) + return True diff --git a/geoprob_pipe/cmd_app/spatial_joins/coupled_mv_exit.py b/geoprob_pipe/cmd_app/spatial_joins/coupled_mv_exit.py new file mode 100644 index 00000000..50b467cf --- /dev/null +++ b/geoprob_pipe/cmd_app/spatial_joins/coupled_mv_exit.py @@ -0,0 +1,30 @@ +from __future__ import annotations +from geopandas import GeoDataFrame, read_file +from pandas import DataFrame, read_sql_query +import sqlite3 +from geoprob_pipe.cmd_app.spatial_joins.utils import append_to_gis_join_parameter_invoer_table +from typing import TYPE_CHECKING +if TYPE_CHECKING: + from geoprob_pipe.cmd_app.cmd import ApplicationSettings + + +def coupled_mv_exit_to_gis_parameter_invoer_table(app_settings: ApplicationSettings) -> bool: + + # Check if already added, if so skip + conn = sqlite3.connect(app_settings.geopackage_filepath) + df_existing = read_sql_query("SELECT * FROM gis_join_parameter_invoer;", conn) + if "mv_exit" in df_existing['parameter'].unique(): + return True + + # Getting necessary GeoDataframes + gdf_exit_points: GeoDataFrame = read_file(app_settings.geopackage_filepath, layer="uittredepunten") + + # Append to new version of geospatial storage + df_to_append: DataFrame = gdf_exit_points[["mv_exit", "uittredepunt_id"]] + df_to_append = df_to_append.rename(columns={"mv_exit": "mean"}) + append_to_gis_join_parameter_invoer_table( + df_sjoin=df_to_append, + parameter_name="mv_exit", + geopackage_filepath=app_settings.geopackage_filepath) + + return True diff --git a/geoprob_pipe/cmd_app/spatial_joins/coupled_polderpeil.py b/geoprob_pipe/cmd_app/spatial_joins/coupled_polderpeil.py new file mode 100644 index 00000000..acc23c5d --- /dev/null +++ b/geoprob_pipe/cmd_app/spatial_joins/coupled_polderpeil.py @@ -0,0 +1,49 @@ +""" +TODO Nu Must Klein: Voeg laag toe aan GeoPackage met visuele koppeling tussen HRD en uittredepunten. +""" + +from __future__ import annotations +from geopandas import GeoDataFrame, read_file +from pathlib import Path +from pandas import DataFrame +from geoprob_pipe.cmd_app.spatial_joins.utils import append_to_gis_join_parameter_invoer_table +from geoprob_pipe.utils.validation_messages import BColors +from typing import TYPE_CHECKING +if TYPE_CHECKING: + from geoprob_pipe.cmd_app.cmd import ApplicationSettings + + +def coupled_polderpeil_to_uittredepunten(app_settings: ApplicationSettings) -> bool: + + + # Getting necessary GeoDataframes + gdf_exit_points: GeoDataFrame = read_file(app_settings.geopackage_filepath, layer="uittredepunten") + gdf_polderpeil: GeoDataFrame = read_file(app_settings.geopackage_filepath, layer="polderpeil") + + # Check if already added + if "polderpeil" in gdf_exit_points.columns: + print(BColors.OKBLUE, f"✔ Polderpeil al gekoppeld aan uittredepunten.", BColors.ENDC) + return True # Assuming already added + + # Perform spatial join to find the nearest HRD-location for each Exit Point + gdf_exit_with_hrd = gdf_exit_points.sjoin_nearest( + gdf_polderpeil[['geometry', 'polderpeil']], how='left', distance_col='distance') + + # Define which columns to keep (after spatial join) + columns_to_keep = list(gdf_exit_points.columns) + columns_to_keep.append("polderpeil") + gdf_new_exit_points = gdf_exit_with_hrd[columns_to_keep] + + # Append to new version of geospatial storage + df_to_append: DataFrame = gdf_new_exit_points[["polderpeil", "uittredepunt_id"]] + df_to_append = df_to_append.rename(columns={"polderpeil": "mean"}) + append_to_gis_join_parameter_invoer_table( + df_sjoin=df_to_append, + parameter_name="polderpeil", + geopackage_filepath=app_settings.geopackage_filepath) + + # Store back in geopackage + gdf_new_exit_points.to_file(Path(app_settings.geopackage_filepath), layer="uittredepunten", driver="GPKG") + # TODO: Uitfaseren deze oude manier van polderpeil opslaan + print(BColors.OKBLUE, f"✅ Polderpeil is nu gekoppeld aan de uittredepunten.", BColors.ENDC) + return True diff --git a/geoprob_pipe/cmd_app/spatial_joins/utils.py b/geoprob_pipe/cmd_app/spatial_joins/utils.py new file mode 100644 index 00000000..e1e2f714 --- /dev/null +++ b/geoprob_pipe/cmd_app/spatial_joins/utils.py @@ -0,0 +1,99 @@ +import sqlite3 +from pandas import read_sql_query +from pandas import DataFrame +import numpy as np + + +def append_to_gis_join_parameter_invoer_table(df_sjoin: DataFrame, parameter_name: str, geopackage_filepath: str): + """ Through mean only """ + + assert df_sjoin.columns.__len__() == 2 + assert "mean" in df_sjoin.columns + assert "uittredepunt_id" in df_sjoin.columns + + # Create other columns + df_to_append = df_sjoin.copy(deep=True) + df_to_append = df_to_append.rename(columns={"uittredepunt_id": "scope_referentie"}) + df_to_append["parameter"] = parameter_name + df_to_append["scope"] = "uittredepunt" + df_to_append["ondergrondscenario_naam"] = "" + df_to_append["distribution_type"] = "deterministic" + df_to_append["variation"] = np.nan + df_to_append["deviation"] = np.nan + df_to_append["minimum"] = np.nan + df_to_append["maximum"] = np.nan + df_to_append["fragility_values_ref"] = "" + df_to_append["bronnen"] = "" + df_to_append["opmerking"] = "" + + # Sort columns + df_to_append = df_to_append[ + ["parameter", "scope", "scope_referentie", "ondergrondscenario_naam", "distribution_type", "mean", "variation", + "deviation", "minimum", "maximum", "fragility_values_ref", "bronnen", "opmerking"]] + + # Get table names + conn = sqlite3.connect(geopackage_filepath) + cursor = conn.cursor() + cursor.execute("SELECT name FROM sqlite_master WHERE type='table';") + tables_names = [row[0] for row in cursor.fetchall()] + + # If gis_join-table is non-existent yet + if "gis_join_parameter_invoer" not in tables_names: + df_to_append.to_sql("gis_join_parameter_invoer", conn, if_exists="replace", index=False) + return + # If polderpeil not yet in gis_join-table + df_existing = read_sql_query("SELECT * FROM gis_join_parameter_invoer;", conn) + if parameter_name not in df_existing['parameter'].unique(): + df_to_append.to_sql("gis_join_parameter_invoer", conn, if_exists="append", index=False) + return + raise ValueError + # Should not have come here. Parameter should already be supplied, and thus user should not have been able to + # make a new spatial join. + + +def append_hrd_to_gis_join_parameter_invoer_table(df_sjoin: DataFrame, geopackage_filepath: str): + """ Through mean only """ + + assert df_sjoin.columns.__len__() == 2 + assert "hrd_name" in df_sjoin.columns + assert "uittredepunt_id" in df_sjoin.columns + + # Create other columns + df_to_append = df_sjoin.copy(deep=True) + df_to_append["parameter"] = "buitenwaterstand" + df_to_append["scope"] = "uittredepunt" + df_to_append = df_to_append.rename(columns={"uittredepunt_id": "scope_referentie"}) + df_to_append["ondergrondscenario_naam"] = "" + df_to_append["distribution_type"] = "cdf_curve" + df_to_append["mean"] = np.nan + df_to_append["variation"] = np.nan + df_to_append["deviation"] = np.nan + df_to_append["minimum"] = np.nan + df_to_append["maximum"] = np.nan + df_to_append = df_to_append.rename(columns={"hrd_name": "fragility_values_ref"}) + df_to_append["bronnen"] = "" + df_to_append["opmerking"] = "" + + # Sort columns + df_to_append = df_to_append[ + ["parameter", "scope", "scope_referentie", "ondergrondscenario_naam", "distribution_type", "mean", "variation", + "deviation", "minimum", "maximum", "fragility_values_ref", "bronnen", "opmerking"]] + + # Get table names + conn = sqlite3.connect(geopackage_filepath) + cursor = conn.cursor() + cursor.execute("SELECT name FROM sqlite_master WHERE type='table';") + tables_names = [row[0] for row in cursor.fetchall()] + + # If gis_join-table is non-existent yet + if "gis_join_parameter_invoer" not in tables_names: + df_to_append.to_sql("gis_join_parameter_invoer", conn, if_exists="replace", index=False) + return + # If polderpeil not yet in gis_join-table + df_existing = read_sql_query("SELECT * FROM gis_join_parameter_invoer;", conn) + if "polderpeil" not in df_existing['parameter'].unique(): + df_to_append.to_sql("gis_join_parameter_invoer", conn, if_exists="append", index=False) + return + raise ValueError + # Should not have come here. Parameter should already be supplied, and thus user should not have been able to + # make a new spatial join. diff --git a/geoprob_pipe/cmd_app/spatial_layers/__init__.py b/geoprob_pipe/cmd_app/spatial_layers/__init__.py new file mode 100644 index 00000000..606b58cb --- /dev/null +++ b/geoprob_pipe/cmd_app/spatial_layers/__init__.py @@ -0,0 +1,9 @@ +from geoprob_pipe.cmd_app.spatial_layers.dijktraject import added_dijktraject +from geoprob_pipe.cmd_app.spatial_layers.vakindeling import added_vakindeling +from geoprob_pipe.cmd_app.spatial_layers.uittredepunten.uittredepunten import added_uittredepunten +from geoprob_pipe.cmd_app.spatial_layers.hrd import added_hrd +from geoprob_pipe.cmd_app.spatial_layers.polderpeil import added_polderpeil +from geoprob_pipe.cmd_app.spatial_layers.binnenteenlijn import added_binnenteenlijn +from geoprob_pipe.cmd_app.spatial_layers.buitenteenlijn import added_buitenteenlijn +from geoprob_pipe.cmd_app.spatial_layers.intredelijn import added_intredelijn +from geoprob_pipe.cmd_app.spatial_layers.ahn import added_ahn diff --git a/geoprob_pipe/cmd_app/spatial_layers/ahn.py b/geoprob_pipe/cmd_app/spatial_layers/ahn.py new file mode 100644 index 00000000..1976628c --- /dev/null +++ b/geoprob_pipe/cmd_app/spatial_layers/ahn.py @@ -0,0 +1,50 @@ +from __future__ import annotations +from typing import TYPE_CHECKING +from InquirerPy import inquirer +import sys +from geoprob_pipe.utils.validation_messages import BColors + +import os +if TYPE_CHECKING: + from geoprob_pipe.cmd_app.cmd import ApplicationSettings + + +def added_ahn(app_settings: ApplicationSettings, display_added_msg: bool = False) -> bool: + # TODO Later Should Middel: Should validate if AHN grid fully overlaps area + exists = os.path.exists(app_settings.ahn_filepath) + + if exists and display_added_msg: + print(BColors.OKBLUE, f"✔ AHN-grid al toegevoegd.", BColors.ENDC) + return True + if exists and not display_added_msg: + return True + + return False + + +def request_ahn(app_settings: ApplicationSettings): + + choices_list = ["Ik heb het nu toegevoegd", "Applicatie afsluiten"] + choice = inquirer.select( + message=f"Voeg s.v.p. het AHN-grid toe aan de onderstaande map en met deze bestandsnaam. \n" + f"{app_settings.ahn_filepath}", + choices=choices_list, + default=choices_list[0], + ).execute() + + if choice == choices_list[0]: + + while not os.path.exists(app_settings.ahn_filepath): + + inquirer.select( + message=f"Voeg s.v.p. het AHN-grid toe aan de map.", + choices=choices_list, + default=choices_list[0], + ).execute() + print(BColors.OKBLUE, f"✅ AHN-bestand toegevoegd.", BColors.ENDC) + return True + + elif choice == choices_list[1]: + sys.exit(f"Applicatie is nu afgesloten.") + else: + raise ValueError diff --git a/geoprob_pipe/cmd_app/spatial_layers/binnenteenlijn.py b/geoprob_pipe/cmd_app/spatial_layers/binnenteenlijn.py new file mode 100644 index 00000000..5899092a --- /dev/null +++ b/geoprob_pipe/cmd_app/spatial_layers/binnenteenlijn.py @@ -0,0 +1,134 @@ +""" +TODO Later Should Klein: Controleer of de binnenteenlijn ook echt aan de binnenzijde is. +TODO Later Should Klein: Niet voor elk geohydrologisch model is de binnen/buiten/intredelijn benodigd. + Maak het toevoegen van deze lijnen afhankelijk van de model keuze. + + +""" + +from __future__ import annotations +from InquirerPy import inquirer +from typing import TYPE_CHECKING, Optional +import os +from shapely import LineString, MultiLineString +from geopandas import GeoDataFrame, read_file +import fiona +import warnings +from geoprob_pipe.utils.validation_messages import BColors +if TYPE_CHECKING: + from geoprob_pipe.cmd_app.cmd import ApplicationSettings + + +def added_binnenteenlijn(app_settings: ApplicationSettings) -> bool: + layers = fiona.listlayers(app_settings.geopackage_filepath) + + if "binnenteenlijn" in layers: + print(BColors.OKBLUE, f"✔ Binnenteenlijn al toegevoegd.", BColors.ENDC) + return True + + request_binnenteenlijn_filepath(app_settings=app_settings) + return True + + +def request_binnenteenlijn_filepath(app_settings: ApplicationSettings): + + # Request filepath + filepath: Optional[str] = None + filepath_is_valid = False + while filepath_is_valid is False: + filepath: str = inquirer.text( + message="Specificeer het volledige bestandspad naar de geopackage/shapefile/geodatabase waarin de " + "binnenteen lijnen zitten.", + ).execute() + + filepath = filepath.replace('"', '') + + if not (filepath.endswith(".gpkg") or filepath.endswith(".shp") or filepath.endswith(".gdb")): + print(BColors.WARNING, f"Het bestand moet of een geopackage, shapefile of geodatabase zijn. Jouw invoer " + f"eindigt op de extensie .{filepath.split(sep='.')[-1]}.", BColors.ENDC) + continue + if not os.path.exists(filepath): + print(BColors.WARNING, f"Het opgegeven bestandspad bestaat niet.", BColors.ENDC) + continue + + filepath_is_valid = True + + # Import data + if filepath.endswith(".shp"): + with warnings.catch_warnings(): + warnings.filterwarnings("ignore", message="Measured \\(M\\) geometry types are not supported.*") + gdf: GeoDataFrame = read_file(filepath) + elif filepath.endswith(".gpkg"): + gdf: GeoDataFrame = import_from_geopackage(filepath=filepath) + elif filepath.endswith(".gdb"): + with warnings.catch_warnings(): + warnings.filterwarnings("ignore", message="Measured \\(M\\) geometry types are not supported.*") + gdf: GeoDataFrame = import_from_geodatabase(filepath=filepath) + else: + raise NotImplementedError( + f"Applicatie vroegtijdig afgesloten: Een {filepath.split(sep='.')[-1]}-bestand is niet geïmplementeerd.") + + # Confirm all are points + all_geometries_are_points = gdf.geometry.apply( + lambda geom: isinstance(geom, LineString) or isinstance(geom, MultiLineString)).all() + if not all_geometries_are_points: + print(BColors.WARNING, f"Het geïmporteerde bestand bestaat niet (volledig) uit lijnen, maar ook uit " + f"andere typen geometrie. Enkel lijnen zijn toegestaan.", BColors.ENDC) + request_binnenteenlijn_filepath(app_settings=app_settings) + + # Add binnenteenlijn + gdf_to_add = gdf[["geometry"]] + gdf_to_add.to_file(app_settings.geopackage_filepath, layer="binnenteenlijn", driver="GPKG") + print(BColors.OKBLUE, f"✅ Binnenteenlijn toegevoegd.", BColors.ENDC) + + +def import_from_geodatabase(filepath: str) -> GeoDataFrame: + layer_name: Optional[str] = None + layer_name_is_valid = False + while layer_name_is_valid is False: + layer_name: str = inquirer.text( + message="Specificeer de layer waarin de binnenteenlijn staat. Type 'listlayers' om " + "een overzicht te krijgen van de geodatabase-layers. ", + ).execute() + + layer_names = fiona.listlayers(filepath) + layer_names.sort() + layers_str = ", ".join(layer_names) + if layer_name == "listlayers": + print(f"{BColors.OKBLUE}De volgende layers zijn beschikbaar in de geodatabase: {layers_str}{BColors.ENDC}") + continue + elif layer_name not in layer_names: + print(f"{BColors.OKBLUE} De laag name '{layer_name}' bestaat niet. De volgende layers zijn beschikbaar in " + f"de geodatabase: {layers_str}{BColors.ENDC}") + continue + + layer_name_is_valid = True + + gdf: GeoDataFrame = read_file(filepath, layer=layer_name) + return gdf + + +def import_from_geopackage(filepath: str) -> GeoDataFrame: + layer_name: Optional[str] = None + layer_name_is_valid = False + while layer_name_is_valid is False: + layer_name: str = inquirer.text( + message="Specificeer de laag met de binnenteen lijnen. Type 'listlayers' om " + "een overzicht te krijgen van de geopackage-layers. ", + ).execute() + + layer_names = fiona.listlayers(filepath) + layer_names.sort() + layers_str = ", ".join(layer_names) + if layer_name == "listlayers": + print(BColors.OKBLUE, f"De volgende layers zijn beschikbaar in de geopackage: {layers_str}", BColors.ENDC) + continue + elif layer_name not in layer_names: + print(BColors.OKBLUE, f"De laag name '{layer_name}' bestaat niet. De volgende layers zijn beschikbaar in " + f"de geopackage: {layers_str}", BColors.ENDC) + continue + + layer_name_is_valid = True + + gdf: GeoDataFrame = read_file(filepath, layer=layer_name) + return gdf diff --git a/geoprob_pipe/cmd_app/spatial_layers/buitenteenlijn.py b/geoprob_pipe/cmd_app/spatial_layers/buitenteenlijn.py new file mode 100644 index 00000000..3aeaedc0 --- /dev/null +++ b/geoprob_pipe/cmd_app/spatial_layers/buitenteenlijn.py @@ -0,0 +1,131 @@ +""" +TODO Later Should Klein: Controleer of de buitenteenlijn ook echt aan de buitenzijde is. + +""" + +from __future__ import annotations +from InquirerPy import inquirer +from typing import TYPE_CHECKING, Optional +import os +import warnings +from shapely import LineString, MultiLineString +from geopandas import GeoDataFrame, read_file +import fiona +from geoprob_pipe.utils.validation_messages import BColors +if TYPE_CHECKING: + from geoprob_pipe.cmd_app.cmd import ApplicationSettings + + +def added_buitenteenlijn(app_settings: ApplicationSettings) -> bool: + layers = fiona.listlayers(app_settings.geopackage_filepath) + + if "buitenteenlijn" in layers: + print(BColors.OKBLUE, f"✔ Buitenteenlijn al toegevoegd.", BColors.ENDC) + return True + + request_buitenteenlijn_filepath(app_settings=app_settings) + return True + + +def request_buitenteenlijn_filepath(app_settings: ApplicationSettings): + + # Request filepath + filepath: Optional[str] = None + filepath_is_valid = False + while filepath_is_valid is False: + filepath: str = inquirer.text( + message="Specificeer het volledige bestandspad naar de geopackage/shapefile/geodatabase waarin de " + "buitenteen lijnen zitten.", + ).execute() + + filepath = filepath.replace('"', '') + + if not (filepath.endswith(".gpkg") or filepath.endswith(".shp") or filepath.endswith(".gdb")): + print(BColors.WARNING, f"Het bestand moet of een geopackage, shapefile of geodatabase zijn. Jouw invoer " + f"eindigt op de extensie .{filepath.split(sep='.')[-1]}.", BColors.ENDC) + continue + if not os.path.exists(filepath): + print(BColors.WARNING, f"Het opgegeven bestandspad bestaat niet.", BColors.ENDC) + continue + + filepath_is_valid = True + + # Import data + if filepath.endswith(".shp"): + with warnings.catch_warnings(): + warnings.filterwarnings("ignore", message="Measured \\(M\\) geometry types are not supported.*") + gdf: GeoDataFrame = read_file(filepath) + elif filepath.endswith(".gpkg"): + gdf: GeoDataFrame = import_from_geopackage(filepath=filepath) + elif filepath.endswith(".gdb"): + with warnings.catch_warnings(): + warnings.filterwarnings("ignore", message="Measured \\(M\\) geometry types are not supported.*") + gdf: GeoDataFrame = import_from_geodatabase(filepath=filepath) + else: + raise NotImplementedError( + f"Applicatie vroegtijdig afgesloten: Een {filepath.split(sep='.')[-1]}-bestand is niet geïmplementeerd.") + + # Confirm all are points + all_geometries_are_points = gdf.geometry.apply( + lambda geom: isinstance(geom, LineString) or isinstance(geom, MultiLineString)).all() + if not all_geometries_are_points: + print(BColors.WARNING, f"Het geïmporteerde bestand bestaat niet (volledig) uit lijnen, maar ook uit " + f"andere typen geometrie. Enkel lijnen zijn toegestaan.", BColors.ENDC) + request_buitenteenlijn_filepath(app_settings=app_settings) + + # Add buitenteenlijn + gdf_to_add = gdf[["geometry"]] + gdf_to_add.to_file(app_settings.geopackage_filepath, layer="buitenteenlijn", driver="GPKG") + print(BColors.OKBLUE, f"✅ Buitenteenlijn toegevoegd.", BColors.ENDC) + + +def import_from_geodatabase(filepath: str) -> GeoDataFrame: + layer_name: Optional[str] = None + layer_name_is_valid = False + while layer_name_is_valid is False: + layer_name: str = inquirer.text( + message="Specificeer de layer waarin de buitenteenlijn staat. Type 'listlayers' om " + "een overzicht te krijgen van de geodatabase-layers. ", + ).execute() + + layer_names = fiona.listlayers(filepath) + layer_names.sort() + layers_str = ", ".join(layer_names) + if layer_name == "listlayers": + print(BColors.OKBLUE, f"De volgende layers zijn beschikbaar in de geodatabase: {layers_str}", BColors.ENDC) + continue + elif layer_name not in layer_names: + print(BColors.OKBLUE, f"De laag name '{layer_name}' bestaat niet. De volgende layers zijn beschikbaar in " + f"de geodatabase: {layers_str}", BColors.ENDC) + continue + + layer_name_is_valid = True + + gdf: GeoDataFrame = read_file(filepath, layer=layer_name) + return gdf + + +def import_from_geopackage(filepath: str) -> GeoDataFrame: + layer_name: Optional[str] = None + layer_name_is_valid = False + while layer_name_is_valid is False: + layer_name: str = inquirer.text( + message="Specificeer de laag met de buitenteen lijnen. Type 'listlayers' om " + "een overzicht te krijgen van de geopackage-layers. ", + ).execute() + + layer_names = fiona.listlayers(filepath) + layer_names.sort() + layers_str = ", ".join(layer_names) + if layer_name == "listlayers": + print(BColors.OKBLUE, f"De volgende layers zijn beschikbaar in de geopackage: {layers_str}", BColors.ENDC) + continue + elif layer_name not in layer_names: + print(BColors.OKBLUE, f"De laag name '{layer_name}' bestaat niet. De volgende layers zijn beschikbaar in " + f"de geopackage: {layers_str}", BColors.ENDC) + continue + + layer_name_is_valid = True + + gdf: GeoDataFrame = read_file(filepath, layer=layer_name) + return gdf diff --git a/geoprob_pipe/cmd_app/spatial_layers/dijktraject.py b/geoprob_pipe/cmd_app/spatial_layers/dijktraject.py new file mode 100644 index 00000000..18cb8a74 --- /dev/null +++ b/geoprob_pipe/cmd_app/spatial_layers/dijktraject.py @@ -0,0 +1,209 @@ +from __future__ import annotations +from InquirerPy import inquirer +import warnings +from typing import Optional, TYPE_CHECKING +import importlib.resources +import os +from geopandas import GeoDataFrame, read_file +import fiona +from geoprob_pipe.utils.validation_messages import BColors +if TYPE_CHECKING: + from geoprob_pipe.cmd_app.cmd import ApplicationSettings + + +def added_dijktraject(app_settings: ApplicationSettings) -> bool: + layers = fiona.listlayers(app_settings.geopackage_filepath) + + if "dijktraject" in layers: + print(BColors.OKBLUE, f"✔ Dijktraject al toegevoegd.", BColors.ENDC) + return True + else: + question_trajectory_source(app_settings) + # TODO Later Should Middel: We vragen nu filepath, we kunnen daarnaast de optie geven voor normtrajecten direct. + return True + + +def question_trajectory_source(app_settings: ApplicationSettings): + choices_list = ["Waterveiligheidsportaal (primaire keringen)", "Lokaal GIS bestand (geopackage/shapefile/geodatabase)"] + + choice = inquirer.select( + message="Van waaruit wil je de referentielijn van de dijk inladen?", + choices=choices_list, + default=choices_list[0], + ).execute() + + if choice == choices_list[0]: + with importlib.resources.path( + package='geoprob_pipe.input_data.dijktrajecten', + resource='dijktrajecten.shp') as shp_path: + gdf: GeoDataFrame = read_file(shp_path) + specify_single_trajectory( + app_settings, gdf=gdf, column_name="TRAJECT_ID") + elif choice == choices_list[1]: + request_trajectory_filepath(app_settings) + return False + + +def request_trajectory_filepath(app_settings: ApplicationSettings): + filepath: Optional[str] = None + filepath_is_valid = False + while filepath_is_valid is False: + filepath: str = inquirer.text( + message="Specificeer het volledige bestandspad naar de geopackage/shapefile/geodatabase waarin de " + "referentielijn van de dijk zit.", + ).execute() + + filepath = filepath.replace('"', '') + + if not (filepath.endswith(".gpkg") or filepath.endswith(".shp") or filepath.endswith(".gdb")): + print(BColors.WARNING, f"Het bestand moet of een geopackage, shapefile of geodatabase zijn. Jouw invoer " + f"eindigt op de extensie .{filepath.split(sep='.')[-1]}.", BColors.ENDC) + continue + if not os.path.exists(filepath): + print(BColors.WARNING, f"Het opgegeven bestandspad bestaat niet.", BColors.ENDC) + continue + + filepath_is_valid = True + + if filepath.endswith(".gdb"): + specify_geodatabase_layer(app_settings, filepath) + elif filepath.endswith(".gpkg"): + specify_geopackage_layer(app_settings, filepath) + elif filepath.endswith(".shp"): + with warnings.catch_warnings(): + warnings.filterwarnings("ignore", message="Measured \\(M\\) geometry types are not supported.*") + gdf: GeoDataFrame = read_file(filepath) + specify_column_with_trajectory_name(app_settings, gdf=gdf) + else: + raise NotImplementedError(f"File with extension {filepath.split(sep='.')[-1]} is not yet supported. " + f"Please make a request.") + + +def specify_geodatabase_layer(app_settings: ApplicationSettings, filepath: str): + layer_name: Optional[str] = None + layer_name_is_valid = False + while layer_name_is_valid is False: + layer_name: str = inquirer.text( + message="Specificeer de layer waarin met de referentielijn van het dijktraject. Type 'listlayers' om " + "een overzicht te krijgen van de geodatabase-layers. ", + ).execute() + + layer_names = fiona.listlayers(filepath) + layer_names.sort() + layers_str = ", ".join(layer_names) + if layer_name == "listlayers": + print(BColors.OKBLUE, f"De volgende layers zijn beschikbaar in de geodatabase: {layers_str}", BColors.ENDC) + continue + elif layer_name not in layer_names: + print(BColors.OKBLUE, f"De layer name '{layer_name}' bestaat niet. De volgende layers zijn beschikbaar in " + f"de geodatabase: {layers_str}", BColors.ENDC) + continue + # TODO Later Must Klein: Check dat een LineString-laag wordt opgegeven. + + layer_name_is_valid = True + + with warnings.catch_warnings(): + warnings.filterwarnings("ignore", message="Measured \\(M\\) geometry types are not supported.*") + gdf: GeoDataFrame = read_file(filepath, layer=layer_name) + specify_column_with_trajectory_name(app_settings, gdf) + + +def specify_geopackage_layer(app_settings: ApplicationSettings, filepath: str): + layer_name: Optional[str] = None + layer_name_is_valid = False + while layer_name_is_valid is False: + layer_name: str = inquirer.text( + message="Specificeer de layer waarin met de referentielijn van het dijktraject. Type 'listlayers' om " + "een overzicht te krijgen van de geopackage-layers. ", + ).execute() + + layer_names = fiona.listlayers(filepath) + layer_names.sort() + layers_str = ", ".join(layer_names) + if layer_name == "listlayers": + print(BColors.OKBLUE, f"De volgende layers zijn beschikbaar in de geopackage: {layers_str}", BColors.ENDC) + continue + elif layer_name not in layer_names: + print(BColors.OKBLUE, f"De layer name '{layer_name}' bestaat niet. De volgende layers zijn beschikbaar in " + f"de geopackage: {layers_str}", BColors.ENDC) + continue + # TODO Later Must Klein: Check dat een LineString-laag wordt opgegeven. + + layer_name_is_valid = True + + gdf: GeoDataFrame = read_file(filepath, layer=layer_name) + specify_column_with_trajectory_name(app_settings, gdf) + + +def specify_column_with_trajectory_name(app_settings: ApplicationSettings, gdf: GeoDataFrame): + column_name: Optional[str] = None + column_name_is_valid = False + while column_name_is_valid is False: + column_name: str = inquirer.text( + message="Specificeer de kolom waarin de naam van het dijktraject staat. Type 'listcolumns' om " + "een overzicht te krijgen van de kolommen. ", + ).execute() + + column_names = gdf.columns + columns_str = ", ".join(column_names) + if column_name == "listcolumns": + print(BColors.OKBLUE, + f"De volgende kolommen zijn beschikbaar in de spatial layer: {columns_str}", BColors.ENDC) + continue + elif column_name not in column_names: + print(BColors.OKBLUE, f"De kolom naam '{column_name}' bestaat niet. De volgende kolommen zijn beschikbaar " + f"in de spatial layer: {columns_str}", BColors.ENDC) + continue + + column_name_is_valid = True + + column_name: str + specify_single_trajectory(app_settings, gdf, column_name) + + +def specify_single_trajectory(app_settings: ApplicationSettings, gdf: GeoDataFrame, column_name: str): + + # Single item in gdf? Then we know enough + if gdf.__len__() == 1: + gdf = gdf[[column_name, gdf.geometry.name]] + gdf = gdf.rename(columns={ + column_name: "traject_naam", + gdf.geometry.name: "geometry", + }) + gdf.to_file(app_settings.geopackage_filepath, layer="dijktraject", driver="GPKG") + + print(BColors.OKBLUE, f"✅ Trajectlijn toegevoegd.", BColors.ENDC) + return + + # Multiple items in gdf? Make user select single one + trajectory_name: Optional[str] = None + trajectory_name_is_valid = False + while trajectory_name_is_valid is False: + trajectory_name: str = inquirer.text( + message=f"Er zijn {gdf.__len__()} opties. Type hier welke de juiste referentielijn is. Type " + f"'listoptions' om een overzicht te krijgen van de opties.", + ).execute() + + trajectory_names = gdf[column_name].values.tolist() + trajectory_names.sort() + trajectories_str = ", ".join(trajectory_names) + if trajectory_name == "listoptions": + print(BColors.OKBLUE, + f"De volgende opties zijn beschikbaar: {trajectories_str}", BColors.ENDC) + continue + elif trajectory_name not in trajectory_names: + print(BColors.OKBLUE, f"De keuze '{trajectory_name}' bestaat niet. De volgende opties zijn beschikbaar: " + f"{trajectories_str}", BColors.ENDC) + continue + + trajectory_name_is_valid = True + + gdf = gdf[gdf[column_name] == trajectory_name] + gdf = gdf[[column_name, gdf.geometry.name]] + gdf = gdf.rename(columns={ + column_name: "traject_naam", + gdf.geometry.name: "geometry", + }) + gdf.to_file(app_settings.geopackage_filepath, layer="dijktraject", driver="GPKG") + print(BColors.OKBLUE, f"✅ Trajectlijn toegevoegd.", BColors.ENDC) + return diff --git a/geoprob_pipe/cmd_app/spatial_layers/hrd.py b/geoprob_pipe/cmd_app/spatial_layers/hrd.py new file mode 100644 index 00000000..3feb8d93 --- /dev/null +++ b/geoprob_pipe/cmd_app/spatial_layers/hrd.py @@ -0,0 +1,179 @@ +from __future__ import annotations +from InquirerPy import inquirer +from pathlib import Path +from typing import TYPE_CHECKING +from geopandas import GeoDataFrame, read_file +from shapely import Point +import os +import sqlite3 +from geoprob_pipe.utils.validation_messages import BColors +import fiona +import warnings +import time +import pydra_core as pydra +from pandas import DataFrame, concat +from typing import List +if TYPE_CHECKING: + from geoprob_pipe.cmd_app.cmd import ApplicationSettings + + +def folder_contains_hrd_db(app_settings: ApplicationSettings) -> bool: + cnt_sql_files = 0 + cnt_config_files = 0 + cnt_hlcd_files = 0 + + + for file in os.listdir(app_settings.hrd_dir): + filename = os.fsdecode(file) + if filename.endswith(".sqlite"): + cnt_sql_files += 1 + if filename.endswith(".config.sqlite"): + cnt_config_files += 1 + if filename.endswith("hlcd.sqlite"): + cnt_hlcd_files += 1 + + if cnt_sql_files == 3 and cnt_config_files == 1 and cnt_hlcd_files == 1: + return True + return False + + +def added_hrd(app_settings: ApplicationSettings) -> bool: + hrd_files_are_provided: bool = folder_contains_hrd_db(app_settings=app_settings) + if hrd_files_are_provided: + print(BColors.OKBLUE, f"✔ HRD-bestanden al toegevoegd.", BColors.ENDC) + check_hrd_locations_added_to_geopackage(app_settings=app_settings) + return True + + # Verzoek toe te voegen + choices_list = ["Ik heb ze nu toegevoegd", "Applicatie afsluiten"] + choice = inquirer.select( + message=f"Voeg s.v.p. de bestanden van de hydraulische database toe aan de onderstaande map. Het gaat om alle " + f"drie SQLite-bestanden, inclusief hlcd.sqlite.\n" + f"{app_settings.hrd_dir}", + choices=choices_list, + default=choices_list[0], + ).execute() + + if choice == choices_list[0]: + + while folder_contains_hrd_db(app_settings=app_settings) is not True: + + inquirer.select( + message=f"De HRD-bestanden zijn nog niet gevonden in de map. Voeg ze s.v.p. toe.", + choices=choices_list, + default=choices_list[0], + ).execute() + print(BColors.OKBLUE, f"✅ HRD-bestanden toegevoegd.", BColors.ENDC) + check_hrd_locations_added_to_geopackage(app_settings=app_settings) + return True + + elif choice == choices_list[1]: + return False + else: + raise ValueError + + +def check_hrd_locations_added_to_geopackage(app_settings: ApplicationSettings): + + # Check if already added + layers = fiona.listlayers(app_settings.geopackage_filepath) + if "hrd_locaties" in layers: + print(BColors.OKBLUE, f"✔ HRD-locatie punten al uitgelezen.", BColors.ENDC) + check_hrd_frag_lines_added_to_geopackage(app_settings=app_settings) + return + + # Add HRD locations to GeoPackage + hrd_path = app_settings.hrd_file_path + hrd = pydra.HRDatabase(hrd_path) + location_names = hrd.locationnames + hrd_location_rows = [] + for location_name in location_names: + with warnings.catch_warnings(): + warnings.filterwarnings("ignore", category=FutureWarning) + try: + hrd_location = hrd.get_location(location_name) + except NotImplementedError as e: + print(f"{BColors.WARNING}Failed adding Hydra-NL location '{location_name}'. " + f"Code continues without adding location. " + f"Using fragility curve for this location is not possible. " + f"Error is: {e}{BColors.ENDC}") + continue + hrd_location_rows.append({ + "location_name": location_name, + "geometry": Point(hrd_location.settings.x_coordinate, hrd_location.settings.y_coordinate) + }) + + # Anticipate no locations added + # if hrd_location_rows.__len__() == 0: + # return + + gdf = GeoDataFrame(hrd_location_rows, columns=['location_name', 'geometry'], crs='EPSG:28992') + gdf.to_file(Path(app_settings.geopackage_filepath), layer="hrd_locaties", driver="GPKG") + print(BColors.OKBLUE, f"✅ HRD-locatie punten toegevoegd aan GeoProb-Pipe GeoPackage.", BColors.ENDC) + + check_hrd_frag_lines_added_to_geopackage(app_settings=app_settings) + + +def check_hrd_frag_lines_added_to_geopackage(app_settings: ApplicationSettings): + + conn = sqlite3.connect(app_settings.geopackage_filepath) + cursor = conn.cursor() + cursor.execute("SELECT name FROM sqlite_master WHERE type='table';") + tables_names = [row[0] for row in cursor.fetchall()] + conn.close() + + # If already exist + if "fragility_values_invoer_hrd" in tables_names: + print(BColors.OKBLUE, f"✔ HRD-fragility lines al uitgelezen.", BColors.ENDC) + return + + # Check if already added + # layers = fiona.listlayers(app_settings.geopackage_filepath) + # if "fragility_values_invoer_hrd" in layers: + # print(BColors.OKBLUE, f"✔ HRD-fragility lines al uitgelezen.", BColors.ENDC) + # return + + # Add frag lines to geopackage + print(f"{BColors.UNDERLINE}HRD-fragility lines worden nu toegevoegd aan de GeoProb-Pipe GeoPackage.{BColors.ENDC}") + hrd = pydra.HRDatabase(app_settings.hrd_file_path) + gdf_locations: GeoDataFrame = read_file(app_settings.geopackage_filepath, layer="hrd_locaties") + location_names = gdf_locations['location_name'].unique().tolist() + # location_names = hrd.get_location_names() + fl = pydra.ExceedanceFrequencyLine("h") + dfs: List[DataFrame] = [] + start_time = time.time() + last_report = start_time + + for index, location_name in enumerate(location_names): + + # Status report + if time.time() - last_report >= 10.0: + print(f"Bezig met locatie {index+1} ({location_name}) van in totaal {location_names.__len__()} locaties.") + last_report = time.time() + + # TODO: + # - Dit proces kan vrij lang duren. Daarom is het beter om per locatie de fragility values in de GeoPackage + # te zetten. Dan kan de gebruiker tussentijds afsluiten en later vanaf hetzelfde moment weer oppakken, + # indien gewenst. + # - Nice to have: In status bericht tijdsindicatie geven wanneer klaar. + + # Continue collecting fragility values + import warnings + with warnings.catch_warnings(): + warnings.simplefilter(action='ignore', category=FutureWarning) + location = hrd.get_location(location_name) + frequency_line = fl.calculate(location) + dfs.append(DataFrame({ + "fragility_values_ref": [location_name] * frequency_line.level.__len__(), + "waarde": frequency_line.level, + "kans": frequency_line.exceedance_frequency})) + + # Combine data and push + df = DataFrame(data=[], columns=["fragility_values_ref", "waarde", "kans"]) + if dfs.__len__() > 0: + df = concat(dfs, ignore_index=True) + conn = sqlite3.connect(app_settings.geopackage_filepath) + df.to_sql("fragility_values_invoer_hrd", conn, if_exists="replace", index=False) + conn.close() + + print(BColors.OKBLUE, f"✅ HRD-fragility lines toegevoegd aan GeoProb-Pipe GeoPackage.", BColors.ENDC) diff --git a/geoprob_pipe/cmd_app/spatial_layers/intredelijn.py b/geoprob_pipe/cmd_app/spatial_layers/intredelijn.py new file mode 100644 index 00000000..94269593 --- /dev/null +++ b/geoprob_pipe/cmd_app/spatial_layers/intredelijn.py @@ -0,0 +1,129 @@ +""" +TODO Later Should Klein: Controleer of de intredelijn ook echt aan de binnenzijde is. + +""" + +from __future__ import annotations +from InquirerPy import inquirer +from typing import TYPE_CHECKING, Optional +import warnings +import os +from shapely import LineString, MultiLineString +from geopandas import GeoDataFrame, read_file +import fiona +from geoprob_pipe.utils.validation_messages import BColors +if TYPE_CHECKING: + from geoprob_pipe.cmd_app.cmd import ApplicationSettings + + +def added_intredelijn(app_settings: ApplicationSettings) -> bool: + layers = fiona.listlayers(app_settings.geopackage_filepath) + + if "intredelijn" in layers: + print(BColors.OKBLUE, f"✔ Intredelijn al toegevoegd.", BColors.ENDC) + return True + + request_intredelijn_filepath(app_settings=app_settings) + return True + + +def request_intredelijn_filepath(app_settings: ApplicationSettings): + + # Request filepath + filepath: Optional[str] = None + filepath_is_valid = False + while filepath_is_valid is False: + filepath: str = inquirer.text( + message="Specificeer het volledige bestandspad naar de geopackage/shapefile/geodatabase waarin de " + "intrede lijnen zitten.", + ).execute() + + filepath = filepath.replace('"', '') + + if not (filepath.endswith(".gpkg") or filepath.endswith(".shp") or filepath.endswith(".gdb")): + print(BColors.WARNING, f"Het bestand moet of een geopackage, shapefile of geodatabase zijn. Jouw invoer " + f"eindigt op de extensie .{filepath.split(sep='.')[-1]}.", BColors.ENDC) + continue + if not os.path.exists(filepath): + print(BColors.WARNING, f"Het opgegeven bestandspad bestaat niet.", BColors.ENDC) + continue + + filepath_is_valid = True + + # Import data + if filepath.endswith(".shp"): + with warnings.catch_warnings(): + warnings.filterwarnings("ignore", message="Measured \\(M\\) geometry types are not supported.*") + gdf: GeoDataFrame = read_file(filepath) + elif filepath.endswith(".gpkg"): + gdf: GeoDataFrame = import_from_geopackage(filepath=filepath) + elif filepath.endswith(".gdb"): + gdf: GeoDataFrame = import_from_geodatabase(filepath=filepath) + else: + raise NotImplementedError( + f"Applicatie vroegtijdig afgesloten: Een {filepath.split(sep='.')[-1]}-bestand is niet geïmplementeerd.") + + # Confirm all are points + all_geometries_are_points = gdf.geometry.apply( + lambda geom: isinstance(geom, LineString) or isinstance(geom, MultiLineString)).all() + if not all_geometries_are_points: + print(BColors.WARNING, f"Het geïmporteerde bestand bestaat niet (volledig) uit lijnen, maar ook uit " + f"andere typen geometrie. Enkel lijnen zijn toegestaan.", BColors.ENDC) + request_intredelijn_filepath(app_settings=app_settings) + + # Add intredelijn + gdf_to_add = gdf[["geometry"]] + gdf_to_add.to_file(app_settings.geopackage_filepath, layer="intredelijn", driver="GPKG") + print(BColors.OKBLUE, f"✅ Intredelijn toegevoegd.", BColors.ENDC) + + +def import_from_geodatabase(filepath: str) -> GeoDataFrame: + layer_name: Optional[str] = None + layer_name_is_valid = False + while layer_name_is_valid is False: + layer_name: str = inquirer.text( + message="Specificeer de layer waarin de intredelijn staat. Type 'listlayers' om " + "een overzicht te krijgen van de geodatabase-layers. ", + ).execute() + + layer_names = fiona.listlayers(filepath) + layer_names.sort() + layers_str = ", ".join(layer_names) + if layer_name == "listlayers": + print(BColors.OKBLUE, f"De volgende layers zijn beschikbaar in de geodatabase: {layers_str}", BColors.ENDC) + continue + elif layer_name not in layer_names: + print(BColors.OKBLUE, f"De laag name '{layer_name}' bestaat niet. De volgende layers zijn beschikbaar in " + f"de geodatabase: {layers_str}", BColors.ENDC) + continue + + layer_name_is_valid = True + + gdf: GeoDataFrame = read_file(filepath, layer=layer_name) + return gdf + + +def import_from_geopackage(filepath: str) -> GeoDataFrame: + layer_name: Optional[str] = None + layer_name_is_valid = False + while layer_name_is_valid is False: + layer_name: str = inquirer.text( + message="Specificeer de laag met de intrede lijnen. Type 'listlayers' om " + "een overzicht te krijgen van de geopackage-layers. ", + ).execute() + + layer_names = fiona.listlayers(filepath) + layer_names.sort() + layers_str = ", ".join(layer_names) + if layer_name == "listlayers": + print(BColors.OKBLUE, f"De volgende layers zijn beschikbaar in de geopackage: {layers_str}", BColors.ENDC) + continue + elif layer_name not in layer_names: + print(BColors.OKBLUE, f"De laag name '{layer_name}' bestaat niet. De volgende layers zijn beschikbaar in " + f"de geopackage: {layers_str}", BColors.ENDC) + continue + + layer_name_is_valid = True + + gdf: GeoDataFrame = read_file(filepath, layer=layer_name) + return gdf diff --git a/geoprob_pipe/cmd_app/spatial_layers/polderpeil.py b/geoprob_pipe/cmd_app/spatial_layers/polderpeil.py new file mode 100644 index 00000000..ad73a421 --- /dev/null +++ b/geoprob_pipe/cmd_app/spatial_layers/polderpeil.py @@ -0,0 +1,149 @@ +from __future__ import annotations +from InquirerPy import inquirer +from typing import TYPE_CHECKING, Optional +import os +from shapely import Polygon, MultiPolygon +from geopandas import GeoDataFrame, read_file +import fiona +from geoprob_pipe.utils.validation_messages import BColors +import warnings +if TYPE_CHECKING: + from geoprob_pipe.cmd_app.cmd import ApplicationSettings + + +def added_polderpeil(app_settings: ApplicationSettings) -> bool: + layers = fiona.listlayers(app_settings.geopackage_filepath) + + if "polderpeil" in layers: + print(BColors.OKBLUE, f"✔ Polderpeil al toegevoegd.", BColors.ENDC) + return True + + request_polderpeil_filepath(app_settings=app_settings) + return True + + +def request_polderpeil_filepath(app_settings: ApplicationSettings): + + # Request filepath + filepath: Optional[str] = None + filepath_is_valid = False + while filepath_is_valid is False: + filepath: str = inquirer.text( + message="Specificeer het volledige bestandspad naar de geopackage/shapefile/geodatabase waarin de " + "polderpeilen zitten.", + ).execute() + + filepath = filepath.replace('"', '') + + if not (filepath.endswith(".gpkg") or filepath.endswith(".shp") or filepath.endswith(".gdb")): + print(BColors.WARNING, f"Het bestand moet of een geopackage, shapefile of geodatabase zijn. Jouw invoer " + f"eindigt op de extensie .{filepath.split(sep='.')[-1]}.", BColors.ENDC) + continue + if not os.path.exists(filepath): + print(BColors.WARNING, f"Het opgegeven bestandspad bestaat niet.", BColors.ENDC) + continue + + filepath_is_valid = True + + # Import data + if filepath.endswith(".shp"): + with warnings.catch_warnings(): + warnings.filterwarnings("ignore", message="Measured \\(M\\) geometry types are not supported.*") + gdf: GeoDataFrame = read_file(filepath) + elif filepath.endswith(".gpkg"): + gdf: GeoDataFrame = import_from_geopackage(filepath=filepath) + elif filepath.endswith(".gdb"): + gdf: GeoDataFrame = import_from_geodatabase(filepath=filepath) + else: + raise NotImplementedError( + f"Applicatie vroegtijdig afgesloten: Een {filepath.split(sep='.')[-1]}-bestand is niet geïmplementeerd.") + + # Confirm all are points + all_geometries_are_points = gdf.geometry.apply( + lambda geom: isinstance(geom, Polygon) or isinstance(geom, MultiPolygon)).all() + if not all_geometries_are_points: + print(BColors.WARNING, f"Het geïmporteerde bestand bestaat niet (volledig) uit vlakken/polygonen, maar ook uit " + f"andere typen geometrie. Enkel vlakken/polygonen zijn toegestaan.", BColors.ENDC) + request_polderpeil_filepath(app_settings=app_settings) + + # Continue questionnaire + specify_column_with_polderpeil_niveau(app_settings, gdf=gdf) + + +def import_from_geodatabase(filepath: str) -> GeoDataFrame: + layer_name: Optional[str] = None + layer_name_is_valid = False + while layer_name_is_valid is False: + layer_name: str = inquirer.text( + message="Specificeer de layer waarin met het polderpeil. Type 'listlayers' om " + "een overzicht te krijgen van de geodatabase-layers. ", + ).execute() + + layer_names = fiona.listlayers(filepath) + layer_names.sort() + layers_str = ", ".join(layer_names) + if layer_name == "listlayers": + print(BColors.OKBLUE, f"De volgende layers zijn beschikbaar in de geodatabase: {layers_str}", BColors.ENDC) + continue + elif layer_name not in layer_names: + print(BColors.OKBLUE, f"De laag name '{layer_name}' bestaat niet. De volgende layers zijn beschikbaar in " + f"de geodatabase: {layers_str}", BColors.ENDC) + continue + + layer_name_is_valid = True + + gdf: GeoDataFrame = read_file(filepath, layer=layer_name) + return gdf + + +def import_from_geopackage(filepath: str) -> GeoDataFrame: + layer_name: Optional[str] = None + layer_name_is_valid = False + while layer_name_is_valid is False: + layer_name: str = inquirer.text( + message="Specificeer de laag met de polderpeilen. Type 'listlayers' om " + "een overzicht te krijgen van de geopackage-layers. ", + ).execute() + + layer_names = fiona.listlayers(filepath) + layer_names.sort() + layers_str = ", ".join(layer_names) + if layer_name == "listlayers": + print(BColors.OKBLUE, f"De volgende layers zijn beschikbaar in de geopackage: {layers_str}", BColors.ENDC) + continue + elif layer_name not in layer_names: + print(BColors.OKBLUE, f"De laag name '{layer_name}' bestaat niet. De volgende layers zijn beschikbaar in " + f"de geopackage: {layers_str}", BColors.ENDC) + continue + + layer_name_is_valid = True + + gdf: GeoDataFrame = read_file(filepath, layer=layer_name) + return gdf + + +def specify_column_with_polderpeil_niveau(app_settings: ApplicationSettings, gdf: GeoDataFrame): + column_name: Optional[str] = None + column_name_is_valid = False + while column_name_is_valid is False: + column_name: str = inquirer.text( + message="Specificeer de kolom waarin het polderpeil staat. Type 'listcolumns' om " + "een overzicht te krijgen van de kolommen.", + ).execute() + + column_names = gdf.columns + columns_str = ", ".join(column_names) + if column_name == "listcolumns": + print(BColors.OKBLUE, + f"De volgende kolommen zijn beschikbaar in de spatial layer: {columns_str}", BColors.ENDC) + continue + elif column_name not in column_names: + print(BColors.OKBLUE, f"De kolom naam '{column_name}' bestaat niet. De volgende kolommen zijn beschikbaar " + f"in de spatial layer: {columns_str}", BColors.ENDC) + continue + column_name_is_valid = True + + gdf_to_add = gdf[["geometry", column_name]] + gdf_to_add = gdf_to_add.rename(columns={column_name: "polderpeil"}) + gdf_to_add.to_file(app_settings.geopackage_filepath, layer="polderpeil", driver="GPKG") + print(BColors.OKBLUE, f"✅ Polderpeilen toegevoegd.", BColors.ENDC) diff --git a/geoprob_pipe/cmd_app/spatial_layers/uittredepunten/__init__.py b/geoprob_pipe/cmd_app/spatial_layers/uittredepunten/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/geoprob_pipe/cmd_app/spatial_layers/uittredepunten/alg_walking_circles.py b/geoprob_pipe/cmd_app/spatial_layers/uittredepunten/alg_walking_circles.py new file mode 100644 index 00000000..7eb99ca4 --- /dev/null +++ b/geoprob_pipe/cmd_app/spatial_layers/uittredepunten/alg_walking_circles.py @@ -0,0 +1,199 @@ +from __future__ import annotations +from geoprob_pipe.cmd_app.spatial_layers.ahn import added_ahn, request_ahn +from typing import TYPE_CHECKING, Optional, Tuple, List +from geoprob_pipe.cmd_app.utils.spatial import load_dijktraject_linestring, load_hydra_nl_as_multipoint +from shapely import LineString, MultiPoint, Polygon, MultiPolygon, Point, unary_union +from shapely.geometry import mapping +import numpy as np +import rasterio.mask +import time +import random +from geopandas import GeoDataFrame +from copy import deepcopy +from geoprob_pipe.utils.validation_messages import BColors +from InquirerPy import inquirer + +if TYPE_CHECKING: + from geoprob_pipe.cmd_app.cmd import ApplicationSettings + + +def request_buffer_distance() -> int: + int_distance = 50 + distance_is_valid = False + while distance_is_valid is False: + str_distance: str = inquirer.text( + message="Specificeer de afstand (in meters) waarbinnen gezocht moet worden aan binnendijkse zijde.\n" + "Zorg er voor dat deze afstand volledig binnen het toegevoegde raster valt. ", + ).execute() + + # Validate + try: int_distance = int(str_distance) + except ValueError: + print(f"{BColors.WARNING}Het lukte niet om de invoer om te zetten naar een integer (geheel getal). Weet je " + f"zeker dat de invoer correct is? Probeer het opnieuw.{BColors.ENDC}") + continue + if int_distance < 50: + print(f"{BColors.WARNING}De opgegeven afstand moet ten minste 50 meter zijn. " + f"Vul opnieuw een waarde in. {BColors.ENDC}") + continue + + # Valid + distance_is_valid = True + return int_distance + + +def create_buffer_binnendijks( + app_settings: ApplicationSettings, +) -> Polygon: + + buffer_distance = request_buffer_distance() + + # Load data from geopackage + ls_dijktraject: LineString = load_dijktraject_linestring(app_settings=app_settings) + mp_hydra_nl_locaties: MultiPoint = load_hydra_nl_as_multipoint(app_settings=app_settings) + + # Create helper buffers + buffer_both_sides = ls_dijktraject.buffer(distance=buffer_distance, cap_style='flat') + buffer_single_side = ls_dijktraject.buffer(distance=buffer_distance, single_sided=True) + buffer_other_side = buffer_both_sides.difference(buffer_single_side) + + # Determine which side is binnendijks + buffer_binnendijks = buffer_single_side + if mp_hydra_nl_locaties.intersects(buffer_binnendijks): + buffer_binnendijks = buffer_other_side + + return buffer_binnendijks + + +def random_point_in_polygon(polygon): + if isinstance(polygon, MultiPolygon): + polygon = max(polygon.geoms, key=lambda poly: poly.area) + + minx, miny, maxx, maxy = polygon.bounds + while True: + p = Point(random.uniform(minx, maxx), random.uniform(miny, maxy)) + if polygon.contains(p): + return p + + +def walk(walk_id: int, src, radius: float, pnt_walk_start: Point) -> Tuple[List, List, List, List]: + iteration_id = 0 + distance = 999 + new_rows_circle_mid = [] + new_rows_circle = [] + new_rows_circle_lowest = [] + pnt_lowest: Optional[Point] = None + while distance > 0.5 and iteration_id <= 99: + iteration_id += 1 + + pnt_center = pnt_lowest + if pnt_center is None: + pnt_center = pnt_walk_start + circle = pnt_center.buffer(distance=radius) + circle_geojson = [mapping(circle)] + + out_image, out_transform = rasterio.mask.mask(src, circle_geojson, crop=True) + out_image = out_image[0] # take first band + out_image = np.where(out_image == src.nodata, np.nan, out_image) + + if np.all(np.isnan(out_image)): + return [], [], [], [circle] + + min_val = np.nanmin(out_image) + min_idx = np.nanargmin(out_image) + row, col = np.unravel_index(min_idx, out_image.shape) + rdx, rdy = rasterio.transform.xy(out_transform, int(row), col) + pnt_lowest = Point(rdx, rdy) + distance = pnt_center.distance(pnt_lowest) + + new_rows_circle_mid.append({"walk_id": walk_id, "iteration_id": iteration_id, "geometry": pnt_center}) + new_rows_circle.append({"walk_id": walk_id, "iteration_id": iteration_id, "geometry": circle}) + final_iteration = False + if distance <= 1: + final_iteration = True + new_rows_circle_lowest.append( + {"walk_id": walk_id, "iteration_id": iteration_id, "min_val": round(min_val, 2), + "geometry": pnt_lowest, "final_iteration": final_iteration}) + + circles_searched = [item['geometry'] for item in new_rows_circle] + + return new_rows_circle_mid, new_rows_circle, new_rows_circle_lowest, circles_searched + + +def search_lowes(app_settings: ApplicationSettings, buffer_binnendijks: Polygon, radius: float = 15.0): + to_search_buffer = deepcopy(buffer_binnendijks) # + with rasterio.open(app_settings.ahn_filepath) as src: + rows_circle_mid = [] + rows_circle = [] + rows_circle_lowest = [] + + start_time = time.time() + elapsed_time = 0.0 + interval_time = 2.0 # seconds + next_report_time = elapsed_time + interval_time + + walk_id = 0 + while to_search_buffer.area / buffer_binnendijks.area > 0.05 and walk_id <= 9999: + + walk_id += 1 + + # Get random point of largest polygon of multipolygon + pnt_walk_start = random_point_in_polygon(to_search_buffer) + + # Walk + new_rows_circle_mid, new_rows_circle, new_rows_circle_lowest, new_circles_searched = walk( + walk_id=walk_id, src=src, pnt_walk_start=pnt_walk_start, radius=radius) + + # Subtract from buffer + to_search_buffer = to_search_buffer.difference(unary_union(new_circles_searched)) + + rows_circle_mid.extend(new_rows_circle_mid) + rows_circle.extend(new_rows_circle) + rows_circle_lowest.extend(new_rows_circle_lowest) + + end_time = time.time() + elapsed_time = end_time - start_time + if elapsed_time > next_report_time: + next_report_time = next_report_time + interval_time + progress_in_percentage = 100 - round((to_search_buffer.area / buffer_binnendijks.area)*100, 0) + print(f"Elapsed time walking: {elapsed_time:.2f} seconds. " + f"Current walk number: {walk_id}. " + f"Searched buffer for {progress_in_percentage}% of buffer") + + progress_in_percentage = 100 - round((to_search_buffer.area / buffer_binnendijks.area) * 100, 0) + print(f"Completed walking buffer in {elapsed_time:.2f} seconds. " + f"Total of {walk_id} walks. " + f"Covered {progress_in_percentage}% of buffer. " + f"Remainder is considered irrelevant.") + + gdf_circle_lowests = GeoDataFrame(rows_circle_lowest, crs='EPSG:28992') + gdf_proposed_uittredepunten: GeoDataFrame = gdf_circle_lowests[gdf_circle_lowests['final_iteration'] == True] + + # Filter duplicates + indices_to_keep = [] + for row in gdf_proposed_uittredepunten.itertuples(): + # noinspection PyUnresolvedReferences + pnt = row.geometry.buffer(1) + indices = gdf_proposed_uittredepunten[gdf_proposed_uittredepunten.geometry.intersects(pnt)].index.values + indices.sort() + indices_to_keep.append(indices[0]) + gdf_proposed_uittredepunten = gdf_proposed_uittredepunten[gdf_proposed_uittredepunten.index.isin(indices_to_keep)] + + gdf_proposed_uittredepunten: GeoDataFrame = gdf_proposed_uittredepunten[["walk_id", "min_val", "geometry"]] + print(f"Found {gdf_proposed_uittredepunten.__len__()} proposed exit points.") + + return gdf_proposed_uittredepunten + + +def algorithm_walking_circles(app_settings: ApplicationSettings): + + if not added_ahn(app_settings=app_settings, display_added_msg=False): + request_ahn(app_settings=app_settings) + + buffer_binnendijks = create_buffer_binnendijks(app_settings=app_settings) + gdf_proposed_uittredepunten = search_lowes(app_settings=app_settings, buffer_binnendijks=buffer_binnendijks) + + gdf_to_add = gdf_proposed_uittredepunten[["geometry", "min_val"]] + gdf_to_add = gdf_to_add.rename(columns={"min_val": "mv_exit"}) + gdf_to_add.to_file(app_settings.geopackage_filepath, layer="uittredepunten", driver="GPKG") + print(BColors.OKBLUE, f"✅ Uittredepunten toegevoegd.", BColors.ENDC) diff --git a/geoprob_pipe/cmd_app/spatial_layers/uittredepunten/uittredepunten.py b/geoprob_pipe/cmd_app/spatial_layers/uittredepunten/uittredepunten.py new file mode 100644 index 00000000..03223173 --- /dev/null +++ b/geoprob_pipe/cmd_app/spatial_layers/uittredepunten/uittredepunten.py @@ -0,0 +1,217 @@ +from __future__ import annotations +from InquirerPy import inquirer +from typing import TYPE_CHECKING, Optional +import os +from geoprob_pipe.cmd_app.spatial_layers.uittredepunten.alg_walking_circles import algorithm_walking_circles +from shapely import Point +from geopandas import GeoDataFrame, read_file +import fiona +from geoprob_pipe.utils.validation_messages import BColors +import warnings +if TYPE_CHECKING: + from geoprob_pipe.cmd_app.cmd import ApplicationSettings + + +def added_uittredepunten(app_settings: ApplicationSettings) -> bool: + layers = fiona.listlayers(app_settings.geopackage_filepath) + + if "uittredepunten" not in layers: + define_method_of_adding_uittredepunten(app_settings) + return True + + gdf: GeoDataFrame = read_file(app_settings.geopackage_filepath, layer="uittredepunten") + if gdf.__len__() == 0: + define_method_of_adding_uittredepunten(app_settings) + return True + + print(BColors.OKBLUE, f"✔ Uittredepunten al toegevoegd ({gdf.__len__()} in totaal).", BColors.ENDC) + add_maaiveld_niveau_exit_points() + return True + + +def define_method_of_adding_uittredepunten(app_settings: ApplicationSettings): + choices_list = ["Nu klikken in ArcGIS/QGIS", "Importeren uit GIS-bestand", "Automatische suggestie"] + choice = inquirer.select( + message="Er zijn nog geen uittredepunten toegevoegd. Hoe wil je deze toevoegen?", + choices=choices_list, + default=choices_list[0], + ).execute() + + if choice == choices_list[0]: + create_empty_uittredepunten_layer() + elif choice == choices_list[1]: + import_uittredepunten_gis_file(app_settings) + elif choice == choices_list[2]: + generate_uittredepunten_suggestions(app_settings=app_settings) + else: + raise ValueError + + +def add_maaiveld_niveau_exit_points(): + # sys.exit("Applicatie vroegtijdig afgesloten: Functie 'add_maaiveld_niveau_exit_points' nog niet afgerond.") + # TODO + return + + +def create_empty_uittredepunten_layer(): + raise NotImplementedError("Applicatie vroegtijdig afgesloten: Deze keuze is nog niet geïmplementeerd.") + + +def import_uittredepunten_gis_file(app_settings: ApplicationSettings): + request_uittredepunten_filepath(app_settings=app_settings) + + +def import_from_geodatabase(filepath: str) -> GeoDataFrame: + layer_name: Optional[str] = None + layer_name_is_valid = False + while layer_name_is_valid is False: + layer_name: str = inquirer.text( + message="Specificeer de layer waarin met de uittredepunten. Type 'listlayers' om " + "een overzicht te krijgen van de geodatabase-layers. ", + ).execute() + + layer_names = fiona.listlayers(filepath) + layer_names.sort() + layers_str = ", ".join(layer_names) + if layer_name == "listlayers": + print(BColors.OKBLUE, f"De volgende layers zijn beschikbaar in de geodatabase: {layers_str}", BColors.ENDC) + continue + elif layer_name not in layer_names: + print(BColors.OKBLUE, f"De laag name '{layer_name}' bestaat niet. De volgende layers zijn beschikbaar in " + f"de geodatabase: {layers_str}", BColors.ENDC) + continue + + layer_name_is_valid = True + + gdf: GeoDataFrame = read_file(filepath, layer=layer_name) + return gdf + + +def import_from_geopackage(filepath: str) -> GeoDataFrame: + layer_name: Optional[str] = None + layer_name_is_valid = False + while layer_name_is_valid is False: + layer_name: str = inquirer.text( + message="Specificeer de layer waarin met de uittredepunten. Type 'listlayers' om " + "een overzicht te krijgen van de geopackage-layers. ", + ).execute() + + layer_names = fiona.listlayers(filepath) + layer_names.sort() + layers_str = ", ".join(layer_names) + if layer_name == "listlayers": + print(BColors.OKBLUE, f"De volgende layers zijn beschikbaar in de geopackage: {layers_str}", BColors.ENDC) + continue + elif layer_name not in layer_names: + print(BColors.OKBLUE, f"De laag name '{layer_name}' bestaat niet. De volgende layers zijn beschikbaar in " + f"de geopackage: {layers_str}", BColors.ENDC) + continue + + layer_name_is_valid = True + + with warnings.catch_warnings(): + warnings.filterwarnings("ignore", message="Measured \\(M\\) geometry types are not supported.*") + gdf: GeoDataFrame = read_file(filepath, layer=layer_name) + return gdf + + +LEGAL_MODEL_OPTIONS =["Walking Circles", "Walking Circles, tilted"] + + +def generate_uittredepunten_suggestions(app_settings: ApplicationSettings): + choices = inquirer.checkbox( + message="Welk algoritme wil je gebruiken? Meerdere opties mogelijk.\n" + "Press to select, Enter when finished. ", + choices=LEGAL_MODEL_OPTIONS, + ).execute() + + if choices.__len__() == 0: + print(BColors.OKBLUE, f"Je hebt geen selectie gemaakt. Maak een keuze of sluit af (ctrl+c).", BColors.ENDC) + generate_uittredepunten_suggestions(app_settings=app_settings) + + if LEGAL_MODEL_OPTIONS[0] in choices: + algorithm_walking_circles(app_settings=app_settings) + if LEGAL_MODEL_OPTIONS[1] in choices: + raise NotImplementedError( + f"Applicatie vroegtijdig afgesloten: 'LEGAL_MODEL_OPTIONS[1]' is nog niet geïmplementeerd.") + + +def request_uittredepunten_filepath(app_settings: ApplicationSettings): + + # Request filepath + filepath: Optional[str] = None + filepath_is_valid = False + while filepath_is_valid is False: + filepath: str = inquirer.text( + message="Specificeer het volledige bestandspad naar de geopackage/shapefile/geodatabase waarin de " + "uittredepunten zitten.", + ).execute() + + filepath = filepath.replace('"', '') + + if not (filepath.endswith(".gpkg") or filepath.endswith(".shp") or filepath.endswith(".gdb")): + print(BColors.WARNING, f"Het bestand moet of een geopackage, shapefile of geodatabase zijn. Jouw invoer " + f"eindigt op de extensie .{filepath.split(sep='.')[-1]}.", BColors.ENDC) + continue + if not os.path.exists(filepath): + print(BColors.WARNING, f"Het opgegeven bestandspad bestaat niet.", BColors.ENDC) + continue + + filepath_is_valid = True + + # Import data + if filepath.endswith(".shp"): + gdf: GeoDataFrame = read_file(filepath) + elif filepath.endswith(".gpkg"): + gdf: GeoDataFrame = import_from_geopackage(filepath=filepath) + elif filepath.endswith(".gdb"): + gdf: GeoDataFrame = import_from_geodatabase(filepath=filepath) + else: + raise NotImplementedError( + f"Applicatie vroegtijdig afgesloten: Een {filepath.split(sep='.')[-1]}-bestand is nog niet " + f"geïmplementeerd.") + + # Confirm all are points + all_geometries_are_points = gdf.geometry.apply(lambda geom: isinstance(geom, Point)).all() + if not all_geometries_are_points: + print(BColors.WARNING, f"Het geïmporteerde bestand bestaat niet (volledig) uit punten, maar ook uit " + f"andere typen geometrie. Enkel punten zijn toegestaan.", BColors.ENDC) + request_uittredepunten_filepath(app_settings=app_settings) + + # Continue questionnaire + specify_column_with_maaiveld_niveau(app_settings, gdf=gdf) + + +def specify_column_with_maaiveld_niveau(app_settings: ApplicationSettings, gdf: GeoDataFrame): + column_name: Optional[str] = None + column_name_is_valid = False + while column_name_is_valid is False: + column_name: str = inquirer.text( + message="Specificeer de kolom waarin het maaiveld niveau staat. Type 'listcolumns' om " + "een overzicht te krijgen van de kolommen. Type 'n.a.' als het maaiveld niveau niet gekoppeld is " + "aan de punten, dan zal de applicatie in een volgende stap deze voor je downloaden.", + ).execute() + + column_names = gdf.columns + columns_str = ", ".join(column_names) + if column_name == "listcolumns": + print(BColors.OKBLUE, + f"De volgende kolommen zijn beschikbaar in de spatial layer: {columns_str}", BColors.ENDC) + continue + elif column_name == "n.a.": + gdf_to_add = gdf[["geometry"]] + gdf_to_add["mv_exit"] = -999.9 + gdf_to_add.to_file(app_settings.geopackage_filepath, layer="uittredepunten", driver="GPKG") + print(BColors.OKBLUE, f"✅ Uittredepunten toegevoegd.", BColors.ENDC) + return + elif column_name not in column_names: + print(BColors.OKBLUE, f"De kolom naam '{column_name}' bestaat niet. De volgende kolommen zijn beschikbaar " + f"in de spatial layer: {columns_str}", BColors.ENDC) + continue + column_name_is_valid = True + + gdf_to_add = gdf[["geometry", column_name]] + # No uittredepunt id yet. This will be set when the metering is determined. + gdf_to_add = gdf_to_add.rename(columns={column_name: "mv_exit"}) + gdf_to_add.to_file(app_settings.geopackage_filepath, layer="uittredepunten", driver="GPKG") + print(BColors.OKBLUE, f"✅ Uittredepunten toegevoegd.", BColors.ENDC) diff --git a/geoprob_pipe/cmd_app/spatial_layers/vakindeling.py b/geoprob_pipe/cmd_app/spatial_layers/vakindeling.py new file mode 100644 index 00000000..eb40641c --- /dev/null +++ b/geoprob_pipe/cmd_app/spatial_layers/vakindeling.py @@ -0,0 +1,293 @@ +from __future__ import annotations +from geopandas import read_file +from InquirerPy import inquirer +import warnings +from geoprob_pipe.cmd_app.utils.spatial import load_dijktraject_linestring +from geoprob_pipe.utils.gdf import convert_mls_geom_column_to_ls +import os +from pathlib import Path +from shapely import LineString, MultiLineString +from shapely.ops import substring +from typing import TYPE_CHECKING, Optional +from pandas import DataFrame +from geopandas import GeoDataFrame +import fiona +from geoprob_pipe.utils.validation_messages import BColors +if TYPE_CHECKING: + from geoprob_pipe.cmd_app.cmd import ApplicationSettings + + +def added_vakindeling(app_settings: ApplicationSettings) -> bool: + layers = fiona.listlayers(app_settings.geopackage_filepath) + if "vakindeling" in layers: + check_validity_vakindeling(app_settings=app_settings) + return True + else: + request_vakindeling_filepath(app_settings) + return True + + +def check_validity_vakindeling(app_settings: ApplicationSettings): + gdf_dijktraject: GeoDataFrame = read_file(app_settings.geopackage_filepath, layer="dijktraject") + gdf_dijktraject_geom = gdf_dijktraject.iloc[0].geometry + if isinstance(gdf_dijktraject_geom, MultiLineString): + assert gdf_dijktraject_geom.geoms.__len__() == 1 + ls_dijktraject: LineString = gdf_dijktraject_geom.geoms[0] + elif isinstance(gdf_dijktraject_geom, LineString): + ls_dijktraject = gdf_dijktraject_geom + else: + raise NotImplementedError(f"Type of '{type(gdf_dijktraject_geom)} is not yet supported. Please contact the " + f"developer.'") + dijktraject_length = round(ls_dijktraject.length, 2) + + gdf_vakindeling: GeoDataFrame = read_file(app_settings.geopackage_filepath, layer="vakindeling") + vakindeling_geometries = gdf_vakindeling.geometry.tolist() + vakindeling_total_length = round(sum([geom.length for geom in vakindeling_geometries]), 2) + + assert dijktraject_length == vakindeling_total_length + print(BColors.OKBLUE, f"✔ Vakindeling al toegevoegd.", BColors.ENDC) + + +def import_from_geopackage(filepath: str) -> GeoDataFrame: + layer_name: Optional[str] = None + layer_name_is_valid = False + while layer_name_is_valid is False: + layer_name: str = inquirer.text( + message="Specificeer de laag met de vakindeling. " + "Type 'listlayers' om een overzicht te krijgen van de geopackage-layers. ", + ).execute() + + layer_names = fiona.listlayers(filepath) + layer_names.sort() + layers_str = ", ".join(layer_names) + if layer_name == "listlayers": + print(BColors.OKBLUE, f"De volgende layers zijn beschikbaar in de geopackage: {layers_str}", BColors.ENDC) + continue + elif layer_name not in layer_names: + print(BColors.OKBLUE, f"De laag name '{layer_name}' bestaat niet. De volgende layers zijn beschikbaar in " + f"de geopackage: {layers_str}", BColors.ENDC) + continue + + layer_name_is_valid = True + + with warnings.catch_warnings(): + warnings.filterwarnings("ignore", message="Measured \\(M\\) geometry types are not supported.*") + gdf: GeoDataFrame = read_file(filepath, layer=layer_name) + return gdf + + +def import_from_geodatabase(filepath: str) -> GeoDataFrame: + layer_name: Optional[str] = None + layer_name_is_valid = False + while layer_name_is_valid is False: + layer_name: str = inquirer.text( + message="Specificeer de laag met de vakindeling. " + "Type 'listlayers' om een overzicht te krijgen van de geodatabase-layers. ", + ).execute() + + layer_names = fiona.listlayers(filepath) + layer_names.sort() + layers_str = ", ".join(layer_names) + if layer_name == "listlayers": + print(BColors.OKBLUE, f"De volgende layers zijn beschikbaar in de geodatabase: {layers_str}", BColors.ENDC) + continue + elif layer_name not in layer_names: + print(BColors.OKBLUE, f"De laag name '{layer_name}' bestaat niet. De volgende layers zijn beschikbaar in " + f"de geodatabase: {layers_str}", BColors.ENDC) + continue + + layer_name_is_valid = True + + with warnings.catch_warnings(): + warnings.filterwarnings("ignore", message="Measured \\(M\\) geometry types are not supported.*") + gdf: GeoDataFrame = read_file(filepath, layer=layer_name) + return gdf + + +def request_vakindeling_filepath(app_settings: ApplicationSettings): + filepath: Optional[str] = None + filepath_is_valid = False + while filepath_is_valid is False: + filepath: str = inquirer.text( + message="Specificeer het volledige bestandspad naar de geopackage/shapefile/geodatabase waarin de " + "vakindeling van de dijk zit.", + ).execute() + + filepath = filepath.replace('"', '') + + if not (filepath.endswith(".gpkg") or filepath.endswith(".shp") or filepath.endswith(".gdb")): + print(BColors.WARNING, f"Het bestand moet of een geopackage, shapefile of geodatabase zijn. Jouw invoer " + f"eindigt op de extensie .{filepath.split(sep='.')[-1]}.", BColors.ENDC) + continue + if not os.path.exists(filepath): + print(BColors.WARNING, f"Het opgegeven bestandspad bestaat niet.", BColors.ENDC) + continue + + filepath_is_valid = True + + if filepath.endswith(".shp"): + with warnings.catch_warnings(): + warnings.filterwarnings("ignore", message="Measured \\(M\\) geometry types are not supported.*") + gdf: GeoDataFrame = read_file(filepath) + validate_vakindeling(app_settings, gdf=gdf) + elif filepath.endswith(".gpkg"): + gdf: GeoDataFrame = import_from_geopackage(filepath=filepath) + validate_vakindeling(app_settings, gdf=gdf) + elif filepath.endswith(".gdb"): + gdf: GeoDataFrame = import_from_geodatabase(filepath=filepath) + validate_vakindeling(app_settings, gdf=gdf) + else: + raise NotImplementedError(f"File with extension {filepath.split(sep='.')[-1]} is not yet supported. " + f"Please make a request.") + + +def validate_vakindeling(app_settings: ApplicationSettings, gdf: GeoDataFrame): + """ Validates the vakindeling shape, with some conversions if they can be + applied safely. """ + gdf = convert_mls_geom_column_to_ls(gdf=gdf) + assert gdf.geometry.apply(lambda geom: isinstance(geom, LineString)).all(), \ + ("De opgegeven vakindeling heeft niet voor elk vak een geometry. De " + "applicatie sluit nu af.") + specify_column_with_vaknaam(app_settings, gdf=gdf) + + +def specify_column_with_vaknaam( + app_settings: ApplicationSettings, gdf: GeoDataFrame): + column_name: Optional[str] = None + column_name_is_valid = False + while column_name_is_valid is False: + column_name: str = inquirer.text( + message="Specificeer de kolom waarin de vaknaam staat. Type " + "'listcolumns' om een overzicht te krijgen van de " + "kolommen. ", + ).execute() + + column_names = gdf.columns + columns_str = ", ".join(column_names) + if column_name == "listcolumns": + print(BColors.OKBLUE, + f"De volgende kolommen zijn beschikbaar in de spatial " + f"layer: {columns_str}", BColors.ENDC) + continue + elif column_name not in column_names: + print(BColors.OKBLUE, + f"De kolom naam '{column_name}' bestaat niet. De volgende " + f"kolommen zijn beschikbaar in de spatial layer: " + f"{columns_str}", BColors.ENDC) + continue + + column_name_is_valid = True + + column_name: str + specify_column_with_vak_id( + app_settings, gdf=gdf, kolom_vak_naam=column_name) + + +def is_numeric_integer(val): + try: + return float(val) % 1 == 0 + except (ValueError, TypeError): + return False + + +def specify_column_with_vak_id( + app_settings: ApplicationSettings, gdf: GeoDataFrame, + kolom_vak_naam: str): + kolom_vak_id: Optional[str] = None + column_name_is_valid = False + while column_name_is_valid is False: + kolom_vak_id: str = inquirer.text( + message="Specificeer de kolom waarin het vak id staat. Indien " + "onnodig, type 'nvt'. Type 'listcolumns' om een overzicht " + "te krijgen van de kolommen. ", + ).execute() + + column_names = gdf.columns + columns_str = ", ".join(column_names) + if kolom_vak_id.lower() == "nvt": + align_vak_shp_to_dijktraject( + app_settings, gdf_vakindeling=gdf, + kolom_vak_naam=kolom_vak_naam, kolom_vak_id=None) + return + elif kolom_vak_id == "listcolumns": + print(BColors.OKBLUE, + f"De volgende kolommen zijn beschikbaar in de spatial " + f"layer: {columns_str}", BColors.ENDC) + continue + elif kolom_vak_id not in column_names: + print(f"{BColors.OKBLUE}De kolom naam '{kolom_vak_id}' bestaat " + f"niet. De volgende kolommen zijn beschikbaar in de spatial " + f"layer: {columns_str}{BColors.ENDC}") + continue + + # Ensure column values are unique and integers + if gdf[kolom_vak_id].__len__() != gdf[kolom_vak_id].unique().__len__(): + print(f"{BColors.OKBLUE}De waarden in deze kolom zijn niet uniek. " + f"Corrigeer de dubbelingen, of kies een andere kolom." + f"{BColors.ENDC}") + continue + + elif not gdf[kolom_vak_id].apply(is_numeric_integer).all(): + print(f"{BColors.OKBLUE}De waarden in deze kolom zijn niet allen " + f"volledige getallen (integers). Corrigeer de kolom, of " + f"kies een andere.{BColors.ENDC}") + continue + + column_name_is_valid = True + + kolom_vak_id: str + align_vak_shp_to_dijktraject( + app_settings, gdf_vakindeling=gdf, kolom_vak_naam=kolom_vak_naam, + kolom_vak_id=kolom_vak_id) + + +def align_vak_shp_to_dijktraject( + app_settings: ApplicationSettings, gdf_vakindeling: GeoDataFrame , + kolom_vak_naam: str, kolom_vak_id: Optional[str] = None): + + # Get dijktraject linestring + ls_dijktraject = load_dijktraject_linestring(app_settings=app_settings) + + # Data verzamelen uit provided vak shp + rows = [] + for index, row in gdf_vakindeling.iterrows(): + pnt1 = row.geometry.boundary.geoms[0] + pnt2 = row.geometry.boundary.geoms[1] + m_pnt1 = round(ls_dijktraject.project(pnt1), 1) + m_pnt2 = round(ls_dijktraject.project(pnt2), 1) + m_start = min(m_pnt1, m_pnt2) + new_row = {"naam": row[kolom_vak_naam], "m_start": m_start} + if kolom_vak_id: + new_row['id'] = int(row[kolom_vak_id]) + rows.append(new_row) + df = DataFrame(rows) + df = df.sort_values(by=["m_start"], ignore_index=True) + df['m_end'] = df['m_start'].shift(periods=-1) + + # Add zero and final dijktraject length to first and last vak + df.loc[0, 'm_start'] = 0 + df.loc[max(df.index), 'm_end'] = ls_dijktraject.length + + # Align vak geometry to dijktraject by retrieving substring + rows = [] + for index, row in df.iterrows(): + new_row = { + "naam": row["naam"], + "m_start": row["m_start"], + "m_end": row["m_end"], + "geometry": substring(ls_dijktraject, row["m_start"], row["m_end"]) + } + if kolom_vak_id: + new_row["id"] = row['id'] + rows.append(new_row) + gdf_new_vakindeling = GeoDataFrame(rows, crs='EPSG:28992') + if not kolom_vak_id: + gdf_new_vakindeling['id'] = gdf_new_vakindeling.index + 1 + gdf_new_vakindeling: GeoDataFrame = gdf_new_vakindeling[ + ["id", "naam", "m_start", "m_end", "geometry"]] + + # Add to geopackage + gdf_new_vakindeling.to_file( + Path(app_settings.geopackage_filepath), + layer="vakindeling", driver="GPKG") + print(BColors.OKBLUE, f"✅ Vakindeling toegevoegd.", BColors.ENDC) diff --git a/geoprob_pipe/cmd_app/test_files/Analyse224.geoprob_pipe.gpkg b/geoprob_pipe/cmd_app/test_files/Analyse224.geoprob_pipe.gpkg new file mode 100644 index 00000000..2e4d55f4 Binary files /dev/null and b/geoprob_pipe/cmd_app/test_files/Analyse224.geoprob_pipe.gpkg differ diff --git a/geoprob_pipe/cmd_app/utils/__init__.py b/geoprob_pipe/cmd_app/utils/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/geoprob_pipe/cmd_app/utils/misc.py b/geoprob_pipe/cmd_app/utils/misc.py new file mode 100644 index 00000000..63ba4716 --- /dev/null +++ b/geoprob_pipe/cmd_app/utils/misc.py @@ -0,0 +1,32 @@ +from __future__ import annotations +from importlib.metadata import version, PackageNotFoundError +from typing import TYPE_CHECKING +import sqlite3 +if TYPE_CHECKING: + from geoprob_pipe.cmd_app.cmd import ApplicationSettings + + +def get_geoprob_pipe_version_number() -> str: + geoprob_pipe_version_number = "DEV" + try: geoprob_pipe_version_number = version('geoprob_pipe') + except PackageNotFoundError: pass + return geoprob_pipe_version_number + + +def get_geohydrological_model(app_settings: ApplicationSettings) -> str: + # Get geohydrological model + conn = sqlite3.connect(app_settings.geopackage_filepath) + cursor = conn.cursor() + cursor.execute(""" + SELECT geoprob_pipe_metadata."values" + FROM geoprob_pipe_metadata + WHERE metadata_type='geohydrologisch_model'; + """) + result = cursor.fetchone() + if not result: + raise ValueError + model_string = result[0] + conn.close() + + return model_string + diff --git a/geoprob_pipe/cmd_app/utils/spatial.py b/geoprob_pipe/cmd_app/utils/spatial.py new file mode 100644 index 00000000..4d1f07a0 --- /dev/null +++ b/geoprob_pipe/cmd_app/utils/spatial.py @@ -0,0 +1,26 @@ +from __future__ import annotations +from geopandas import read_file +from shapely import LineString, MultiLineString, MultiPoint +from typing import TYPE_CHECKING +from geopandas import GeoDataFrame +if TYPE_CHECKING: + from geoprob_pipe.cmd_app.cmd import ApplicationSettings + + +def load_dijktraject_linestring(app_settings: ApplicationSettings) -> LineString: + gdf_dijktraject: GeoDataFrame = read_file(app_settings.geopackage_filepath, layer="dijktraject") + gdf_dijktraject_geom = gdf_dijktraject.iloc[0].geometry + if isinstance(gdf_dijktraject_geom, MultiLineString): + assert gdf_dijktraject_geom.geoms.__len__() == 1 + ls_dijktraject: LineString = gdf_dijktraject_geom.geoms[0] + elif isinstance(gdf_dijktraject_geom, LineString): + ls_dijktraject = gdf_dijktraject_geom + else: + raise NotImplementedError(f"Type of '{type(gdf_dijktraject_geom)} is not yet supported. Please contact the " + f"developer.'") + return ls_dijktraject + + +def load_hydra_nl_as_multipoint(app_settings: ApplicationSettings) -> MultiPoint: + gdf_hrd_locaties: GeoDataFrame = read_file(app_settings.geopackage_filepath, layer="hrd_locaties") + return MultiPoint(gdf_hrd_locaties.geometry.values) diff --git a/geoprob_pipe/input_data/__init__.py b/geoprob_pipe/input_data/__init__.py new file mode 100644 index 00000000..da84f048 --- /dev/null +++ b/geoprob_pipe/input_data/__init__.py @@ -0,0 +1 @@ +from geoprob_pipe.input_data.input_data_object import InputData diff --git a/geoprob_pipe/input_data/dijktrajecten/dijktrajecten.cst b/geoprob_pipe/input_data/dijktrajecten/dijktrajecten.cst new file mode 100644 index 00000000..cd89cb97 --- /dev/null +++ b/geoprob_pipe/input_data/dijktrajecten/dijktrajecten.cst @@ -0,0 +1 @@ +ISO-8859-1 \ No newline at end of file diff --git a/geoprob_pipe/input_data/dijktrajecten/dijktrajecten.dbf b/geoprob_pipe/input_data/dijktrajecten/dijktrajecten.dbf new file mode 100644 index 00000000..5622a692 Binary files /dev/null and b/geoprob_pipe/input_data/dijktrajecten/dijktrajecten.dbf differ diff --git a/geoprob_pipe/input_data/dijktrajecten/dijktrajecten.prj b/geoprob_pipe/input_data/dijktrajecten/dijktrajecten.prj new file mode 100644 index 00000000..a13108a7 --- /dev/null +++ b/geoprob_pipe/input_data/dijktrajecten/dijktrajecten.prj @@ -0,0 +1 @@ +PROJCS["Amersfoort / RD New", GEOGCS["Amersfoort", DATUM["Amersfoort", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[565.2369, 50.0087, 465.658, -0.40685733032239757, -0.3507326765425626, 1.8703473836067956, 4.0812], AUTHORITY["EPSG","6289"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic latitude", NORTH], AXIS["Geodetic longitude", EAST], AUTHORITY["EPSG","4289"]], PROJECTION["Oblique_Stereographic", AUTHORITY["EPSG","9809"]], PARAMETER["central_meridian", 5.387638888888891], PARAMETER["latitude_of_origin", 52.15616055555556], PARAMETER["scale_factor", 0.9999079], PARAMETER["false_easting", 155000.0], PARAMETER["false_northing", 463000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28992"]] \ No newline at end of file diff --git a/geoprob_pipe/input_data/dijktrajecten/dijktrajecten.shp b/geoprob_pipe/input_data/dijktrajecten/dijktrajecten.shp new file mode 100644 index 00000000..9163ae16 Binary files /dev/null and b/geoprob_pipe/input_data/dijktrajecten/dijktrajecten.shp differ diff --git a/geoprob_pipe/input_data/dijktrajecten/dijktrajecten.shx b/geoprob_pipe/input_data/dijktrajecten/dijktrajecten.shx new file mode 100644 index 00000000..5e2229a3 Binary files /dev/null and b/geoprob_pipe/input_data/dijktrajecten/dijktrajecten.shx differ diff --git a/geoprob_pipe/input_data/input_data_object.py b/geoprob_pipe/input_data/input_data_object.py new file mode 100644 index 00000000..b43eed0a --- /dev/null +++ b/geoprob_pipe/input_data/input_data_object.py @@ -0,0 +1,163 @@ +from __future__ import annotations +from geopandas import GeoDataFrame, read_file +from pandas import read_sql, DataFrame +from probabilistic_library import FragilityValue +import pydra_core as pydra +from shapely import Point +from typing import Optional, TYPE_CHECKING, List +import sqlite3 +from geoprob_pipe.input_data.traject_normering import TrajectNormering +if TYPE_CHECKING: + from geoprob_pipe.cmd_app.cmd import ApplicationSettings + + +class Vak: + + def __init__(self, app_settings: ApplicationSettings, vak_id: int): + self.app_settings: ApplicationSettings = app_settings + self.vak_id = vak_id + + +class Uittredepunten: + + def __init__(self, app_settings: ApplicationSettings): + self.app_settings: ApplicationSettings = app_settings + self.gdf: GeoDataFrame = read_file(app_settings.geopackage_filepath, + layer="uittredepunten") + + def uittredepunt(self, uittredepunt_id: int): + row = self.gdf.loc[ + self.gdf['uittredepunt_id'] == uittredepunt_id + ].iloc[0] + kwargs = row.to_dict() + return Uittredepunt(self.app_settings, **kwargs) + + +class Uittredepunt: + + def __init__( + self, app_settings: ApplicationSettings, geometry: Point, + uittredepunt_id: int, vak_id: int, **_): + self.app_settings: ApplicationSettings = app_settings + self.geometry: Point = geometry + self.uittredepunt_id: int = uittredepunt_id + self.vak_id: int = vak_id + + @property + def vak(self) -> Vak: + return Vak(app_settings=self.app_settings, vak_id=self.vak_id) + + +class Scenarios: + + def __init__(self, app_settings: ApplicationSettings): + self.app_settings: ApplicationSettings = app_settings + self.df = self._query_scenarios() + + def _query_scenarios(self) -> DataFrame: + conn = sqlite3.connect(self.app_settings.geopackage_filepath) + df_scenario_invoer = read_sql("SELECT * FROM scenario_invoer;", conn) + df_scenario_invoer = df_scenario_invoer[["vak_id", "naam", "kans"]] + conn.close() + return df_scenario_invoer + + def scenario_kans(self, vak_id: int, scenario_naam: str) -> float: + kans: float = self.df[ + (self.df['vak_id'] == vak_id) & + (self.df['naam'] == scenario_naam) + ]['kans'].iloc[0] + return kans + + +class HydraNLData: + + def __init__(self, app_settings: ApplicationSettings): + self.app_settings: ApplicationSettings = app_settings + self.gdf_locations: GeoDataFrame = read_file( + app_settings.geopackage_filepath, layer="hrd_locaties") + + def hrd_fragility_values(self, ref: str) -> List[FragilityValue]: + + # Read from geopackage + conn = sqlite3.connect(self.app_settings.geopackage_filepath) + df_frag_line = read_sql( + "SELECT * FROM fragility_values_invoer_hrd" + f" WHERE fragility_values_ref = '{ref}';", + conn) + conn.close() + + # Construct Fragility Values + df_frag_line = df_frag_line.sort_values(by=["waarde"]) + frag_points = [] + for _, row in df_frag_line.iterrows(): + fc = FragilityValue() + fc.x = row["waarde"] + fc.probability_of_failure = row["kans"] + frag_points.append(fc) + + return frag_points + + # noinspection PyUnresolvedReferences + def hrd_frequency_line( + self, ref: str + ) -> pydra.core.datamodels.frequency_line.FrequencyLine: + hrd_fragility_values = self.hrd_fragility_values(ref=ref) + level = [item.x for item in hrd_fragility_values] + exceedance_frequency = [item.probability_of_failure + for item in hrd_fragility_values] + # noinspection PyUnresolvedReferences + return pydra.core.datamodels.frequency_line.FrequencyLine( + level=level, exceedance_frequency=exceedance_frequency) + + +class Vakken: + + def __init__(self, app_settings: ApplicationSettings): + self.app_settings: ApplicationSettings = app_settings + self.gdf: GeoDataFrame = read_file(app_settings.geopackage_filepath, + layer="vakindeling") + + +class InputData: + """ Subclass to group input data of vakken, uittredepunten and + ondergrondscenarios. Data is retrieved from the input Excel-file. + """ + + def __init__( + self, + app_settings: ApplicationSettings + # workspace: Workspace, + ): + + self.app_settings: ApplicationSettings = app_settings + + # Traject-data + self._traject_normering: Optional[TrajectNormering] = None + + self.uittredepunten = Uittredepunten(self.app_settings) + self.scenarios = Scenarios(self.app_settings) + self.vakken = Vakken(self.app_settings) + self.hydra_nl_data = HydraNLData(self.app_settings) + + @property + def geohydrologisch_model(self) -> str: + conn = sqlite3.connect(self.app_settings.geopackage_filepath) + cursor = conn.cursor() + cursor.execute(""" + SELECT geoprob_pipe_metadata."values" + FROM geoprob_pipe_metadata + WHERE metadata_type='geohydrologisch_model'; + """) + result = cursor.fetchone() + if not result: + raise ValueError + model_string = result[0] + conn.close() + return model_string + + @property + def traject_normering(self): + if self._traject_normering is None: + self._traject_normering = TrajectNormering( + hrd_path=self.app_settings.hrd_file_path) + return self._traject_normering diff --git a/geoprob_pipe/input_data/traject_normering.py b/geoprob_pipe/input_data/traject_normering.py new file mode 100644 index 00000000..c8950741 --- /dev/null +++ b/geoprob_pipe/input_data/traject_normering.py @@ -0,0 +1,151 @@ +import os.path +import scipy.stats as sct +import sqlite3 +from typing import Tuple, Optional +from shapely import LineString +import importlib.resources +from geopandas import read_file, GeoDataFrame + + +def _get_traject_id(hrd_path: str, hlcd_path: str) -> Tuple[int, str]: + """ Queries first the HRD for the integer ID of the traject. + Then queries the HLCD to find the textual traject ID. + """ + conn = sqlite3.connect(hrd_path) + cursor = conn.cursor() + query = "SELECT TrackID FROM General;" + cursor.execute(query) + track_id = cursor.fetchone()[0] + conn.close() + + conn = sqlite3.connect(hlcd_path) + cursor = conn.cursor() + query = f"SELECT Name FROM Tracks WHERE TrackID={track_id};" + cursor.execute(query) + traject_id = cursor.fetchone()[0] + conn.close() + + return track_id, traject_id + + +def _query_dijktrajecten(traject_id: str): + """ Queries the dijktrajecten.shp that was retrieved from the API of + the Waterveiligheidsportaal [1]. + + [1] https://www.nationaalgeoregister.nl/geonetwork/srv/dut/catalog.search#/metadata/fa4cc54e-26b3-4f25-b643-59458622901c + """ + with importlib.resources.path( + package='geoprob_pipe.input_data.dijktrajecten', + resource='dijktrajecten.shp') as shp_path: + gdf: GeoDataFrame = read_file(shp_path) + gdf = gdf[gdf['TRAJECT_ID'] == traject_id] + assert gdf.__len__() == 1, ("Only one traject id should have been found." + " Address this issue.") + geom: LineString = gdf.iloc[0].geometry + return gdf.iloc[0]['NORM_SW'], gdf.iloc[0]['NORM_OG'], geom.length + + +class TrajectNormering: + """ Gathers the traject id and calculates the traject normering + from the HRD-files. + """ + + def __init__( + self, + hrd_path: str, + # Non-existent in HRD? For now as optional parameter. + traject_naam: Optional[str] = None, + norm_is_ondergrens: bool = True, + # Where to find this? For now as manual parameter + bovenrivierengebied: bool = True, + ): + + # Input + self.traject_naam: Optional[str] = traject_naam + self.hrd_path = hrd_path + self.hlcd_path = os.path.join(os.path.dirname(self.hrd_path), + "hlcd.sqlite") + self.bovenrivierengebied: bool = bovenrivierengebied + + # Parameters + self.traject_id: str = _get_traject_id(self.hrd_path, + self.hlcd_path)[1].strip() + signaleringswaarde, ondergrens, traject_lengte = ( + _query_dijktrajecten(self.traject_id)) + self.signaleringswaarde: int = signaleringswaarde + self.ondergrens: int = ondergrens + self.w: float = 0.24 + self.traject_lengte: float = traject_lengte + self.faalkanseis_signaleringswaarde = 1.0 / self.signaleringswaarde + self.faalkanseis_ondergrens = 1.0 / self.ondergrens + self.faalkanseis_norm = self.faalkanseis_ondergrens + if not norm_is_ondergrens: + self.faalkanseis_norm = self.signaleringswaarde + self.beta_norm = sct.norm.ppf(self.faalkanseis_norm) + self.n_dsn = 1 + (0.9 * self.traject_lengte) / 300.0 + if not self.bovenrivierengebied: + self.n_dsn = 1 + (0.4 * self.traject_lengte) / 300.0 + # TODO Nu Must Klein: Eigenlijk hoofdletter N_dsn. + # Maar ipv afkorting naam gebruiken? + self.faalkanseis_sign_dsn = ( + self.w * self.faalkanseis_signaleringswaarde) / self.n_dsn + self.beta_sign_dsn = sct.norm.ppf(self.faalkanseis_sign_dsn) + self.faalkanseis_ond_dsn = ( + self.w * self.faalkanseis_ondergrens) / self.n_dsn + self.beta_ond_dsn = sct.norm.ppf(self.faalkanseis_ond_dsn) + self.beta_categorie_grenzen = { + "I": [ + -1 * sct.norm.ppf(self.faalkanseis_sign_dsn / 30), + 50 + ], + "II": [ + -1 * sct.norm.ppf(self.faalkanseis_sign_dsn), + -1 * sct.norm.ppf(self.faalkanseis_sign_dsn / 30), + ], + "III": [ + -1 * sct.norm.ppf(self.faalkanseis_ond_dsn), + -1 * sct.norm.ppf(self.faalkanseis_sign_dsn), + ], + "IV": [ + -1 * sct.norm.ppf(self.faalkanseis_ondergrens), + -1 * sct.norm.ppf(self.faalkanseis_ond_dsn), + ], + "V": [ + -1 * sct.norm.ppf(self.faalkanseis_ondergrens * 30), + -1 * sct.norm.ppf(self.faalkanseis_ondergrens), + ], + "VI": [ + -50, + -1 * sct.norm.ppf(self.faalkanseis_ondergrens * 30), + ], + } + self.riskeer_categorie_grenzen = { + "+III": [ + -1 * sct.norm.ppf(self.faalkanseis_sign_dsn / 1000), + 20 + ], + "+II": [ + -1 * sct.norm.ppf(self.faalkanseis_sign_dsn / 100), + -1 * sct.norm.ppf(self.faalkanseis_sign_dsn / 1000) + ], + "+I": [ + -1 * sct.norm.ppf(self.faalkanseis_sign_dsn / 10), + -1 * sct.norm.ppf(self.faalkanseis_sign_dsn / 100) + ], + "0": [ + -1 * sct.norm.ppf(self.faalkanseis_sign_dsn), + -1 * sct.norm.ppf(self.faalkanseis_sign_dsn / 10) + ], + "-I": [ + -1 * sct.norm.ppf(self.faalkanseis_ond_dsn), + -1 * sct.norm.ppf(self.faalkanseis_sign_dsn), + ], + "-II": [ + -1 * sct.norm.ppf(self.faalkanseis_ond_dsn * 10), + -1 * sct.norm.ppf(self.faalkanseis_ond_dsn) + ], + "-III": [ + 2, + -1 * sct.norm.ppf(self.faalkanseis_ond_dsn * 10) + ], + } diff --git a/geoprob_pipe/results/__init__.py b/geoprob_pipe/results/__init__.py new file mode 100644 index 00000000..d7fa03d6 --- /dev/null +++ b/geoprob_pipe/results/__init__.py @@ -0,0 +1,87 @@ +from __future__ import annotations +from pandas import DataFrame +from typing import TYPE_CHECKING, Optional +from geoprob_pipe.results.construct_dataframes import ( + combine_df_beta_per_limit_state, combine_df_beta_per_scenario, calculate_df_beta_per_uittredepunt, + construct_df_beta_per_vak) +from geoprob_pipe.results.alphas_and_physical_values import construct_df +import os +if TYPE_CHECKING: + from geoprob_pipe import GeoProbPipe + + +class Results: + """ Subclass to intuitively group the results. """ + + def __init__(self, geoprob_pipe: GeoProbPipe): + self.geoprob_pipe = geoprob_pipe + self.df_beta_limit_states = combine_df_beta_per_limit_state(geoprob_pipe.calc_results) + self.df_beta_scenarios = combine_df_beta_per_scenario(geoprob_pipe.calc_results) + self._df_alphas_influence_factors_and_physical_values: Optional[DataFrame] = None + self.df_beta_uittredepunten = calculate_df_beta_per_uittredepunt(geoprob_pipe=geoprob_pipe, results=self) + self.df_beta_vakken = construct_df_beta_per_vak(self) + + def df_alphas_influence_factors_and_physical_values( + self, + system_only: bool = True, + filter_deterministic: bool = True, + filter_derived: bool = False, + ) -> DataFrame: + + # Generate if not generated yet + if self._df_alphas_influence_factors_and_physical_values is None: + self._df_alphas_influence_factors_and_physical_values = ( + construct_df(self.geoprob_pipe)) + + # Filters + df = self._df_alphas_influence_factors_and_physical_values + if filter_deterministic: + df = df[df['distribution_type'] != "deterministic"] + if system_only: + df = df[df['design_point'] == "system"] + if filter_derived: + df = df[df['distribution_type'] != "derived"] + + return df + + @property + def export_dir(self) -> str: + path: str = os.path.join( + self.geoprob_pipe.input_data.app_settings.workspace_dir, + "exports", + str(self.geoprob_pipe.input_data.app_settings.datetime_stamp), + "results") + os.makedirs(path, exist_ok=True) + return path + + def export_results( + self, + bool_beta_limit_states: bool = True, + bool_beta_scenarios: bool = True, + bool_alphas_influence_factors_and_physical_values: bool = True, + bool_beta_uittredepunten: bool = True, + bool_beta_vakken: bool = True): + + # Results of limit state calculations + if bool_beta_limit_states: + df = self.df_beta_limit_states + # TODO Nu Must Klein: Voor export df_beta_limit_states, kolommen filteren? + df.to_excel(excel_writer=os.path.join(self.export_dir, "df_beta_limit_states.xlsx")) + # TODO Nu Should Klein: Sommige resultaten zijn niet converged. Wat doen we daarmee? + # Op dit moment worden ze gewoon gebruikt om de scenario-faalkans te berekenen. + + if bool_beta_scenarios: + df = self.df_beta_scenarios + df.to_excel(excel_writer=os.path.join(self.export_dir, "df_beta_scenarios.xlsx")) + + if bool_alphas_influence_factors_and_physical_values: + df = self.df_alphas_influence_factors_and_physical_values() + df.to_excel( + excel_writer=os.path.join(self.export_dir, "df_alphas_influence_factors_and_physical_values.xlsx")) + + if bool_beta_uittredepunten: + self.df_beta_uittredepunten.to_excel( + excel_writer=os.path.join(self.export_dir, "df_beta_uittredepunten.xlsx")) + + if bool_beta_vakken: + self.df_beta_vakken.to_excel(excel_writer=os.path.join(self.export_dir, "df_beta_vakken.xlsx")) diff --git a/geoprob_pipe/results/alphas_and_physical_values.py b/geoprob_pipe/results/alphas_and_physical_values.py new file mode 100644 index 00000000..b02ed0ae --- /dev/null +++ b/geoprob_pipe/results/alphas_and_physical_values.py @@ -0,0 +1,122 @@ +from __future__ import annotations +from pandas import DataFrame, concat +from probabilistic_library import DesignPoint, Alpha +from typing import TYPE_CHECKING, Dict, List, Union, cast +import numpy as np + +from geoprob_pipe.calculations.systems.mappers.calculation_mapper import CALCULATION_MAPPER + +if TYPE_CHECKING: + from geoprob_pipe import GeoProbPipe + from geoprob_pipe.calculations.systems.base_objects.system_calculation import ( + SystemCalculation) + from geoprob_pipe.calculations.systems.build_and_run import CalcResult + + +def collect_stochast_values(calc: SystemCalculation + ) -> DataFrame: + """ Collects all Alphas, Influence factors and Physical values of + the stochast input parameters. """ + + # Create + def create_df_rows_for_design_point( + dp: DesignPoint, calculation: SystemCalculation + ) -> List[Dict[str, Union[str, float]]]: + rows_from_dp = [] + for alpha in dp.alphas: + alpha: Alpha + rows_from_dp.append({ + "uittredepunt_id": calculation.metadata['uittredepunt_id'], + "ondergrondscenario_id": calculation.metadata['ondergrondscenario_naam'], + "vak_id": calculation.metadata['vak_id'], + "design_point": dp.identifier, + "variable": alpha.identifier, + "distribution_type": alpha.variable.distribution.value, + "alpha": alpha.alpha, + "influence_factor": alpha.alpha * alpha.alpha, + "physical_value": alpha.x + }) + return rows_from_dp + + # Gather data + rows = [] + for design_point in calc.model_design_points: + rows.extend(create_df_rows_for_design_point(dp=design_point, calculation=calc)) + sdp = cast(DesignPoint, calc.system_design_point) + rows.extend(create_df_rows_for_design_point(dp=sdp, calculation=calc)) + + # Generate df from rows + df = DataFrame(rows) + + return df + + +def _combine_stochast_values(calc_results: List[CalcResult]) -> DataFrame: + df = concat((result.df_stochast for result in calc_results), ignore_index=True) + return df + + +def calculate_derived_values(df_scenarios: DataFrame, + geohydrologisch_model: str): + """ Re-calculates all derived physical values, i.e. intermediate values that were calculated inside the limit state + functions. These are not returned by the probabilistic library, hence we need to re-calculate them. + """ + + # Get kwargs per calculation + df = df_scenarios.copy(deep=True) + df['physical_values'] = df['system_calculation'].apply( + lambda sc: {alpha.variable.name: alpha.x for alpha in sc.system_design_point.alphas} + ) + + # Calculate the derived values + def derived_values_single_calculation(model_naam: str, **kwargs): + + return_keys: List[str] = CALCULATION_MAPPER[model_naam]["system_return_parameter_keys"] + system_limit_state_function = CALCULATION_MAPPER[model_naam]["limit_state_function"] + derived_values = {key: value for key, value in zip(return_keys, system_limit_state_function(**kwargs))} + + return {**derived_values} + + df['derived_physical_values'] = df['physical_values'].apply( + lambda kwargs: derived_values_single_calculation( + model_naam=geohydrologisch_model, **kwargs) + ) + + # Create df with row per derived physical value + df_new = df[["uittredepunt_id", "ondergrondscenario_id", "vak_id", "derived_physical_values"]].copy(deep=True) + df_new['design_point'] = "system" + df_new['distribution_type'] = "derived" + df_new['alpha'] = np.nan + df_new['influence_factor'] = np.nan + + # Expand dictionary to new rows + df_new = concat([ + DataFrame({ + **row.drop('derived_physical_values'), + 'variable': list(row['derived_physical_values'].keys()), + 'physical_value': list(row['derived_physical_values'].values()) + }) + for _, row in df_new.iterrows() + ], ignore_index=True) + + return df_new + + +def _combine_derived_values(calc_results: List[CalcResult]) -> DataFrame: + df = concat((result.df_derived for result in calc_results), + ignore_index=True) + return df + + +def construct_df(geoprob_pipe: GeoProbPipe): + + # Merge derived and stochast values + df = concat([ + _combine_stochast_values(geoprob_pipe.calc_results), + _combine_derived_values(geoprob_pipe.calc_results) + ]) + + # Sort + df = df.sort_values(by=["vak_id", "uittredepunt_id", "ondergrondscenario_id", "design_point", "variable"]) + return df.reset_index(drop=True) + # TODO Later Could Klein: Bespreken of we de physical values willen afronden? Af wellicht afrondden in de export. diff --git a/geoprob_pipe/results/construct_dataframes.py b/geoprob_pipe/results/construct_dataframes.py new file mode 100644 index 00000000..edcf4d29 --- /dev/null +++ b/geoprob_pipe/results/construct_dataframes.py @@ -0,0 +1,107 @@ +from __future__ import annotations +from geoprob_pipe.utils.statistics import convert_failure_probability_to_beta +import pandas as pd +from typing import TYPE_CHECKING, List +if TYPE_CHECKING: + from geoprob_pipe.results import Results + from geoprob_pipe import GeoProbPipe + from geoprob_pipe.calculations.systems.base_objects.system_calculation import \ + SystemCalculation + from probabilistic_library import DesignPoint + from geoprob_pipe.calculations.systems.build_and_run import CalcResult + + +def collect_df_beta_limit_state(calculation: SystemCalculation) -> pd.DataFrame: + + def create_row(calc, dp: DesignPoint, model_name): + return { + "uittredepunt_id": calc.metadata["uittredepunt_id"], + "ondergrondscenario_id": calc.metadata["ondergrondscenario_naam"], # TODO: id naar naam veranderen? + "vak_id": calc.metadata["vak_id"], + "limit_state": model_name, + "converged": dp.is_converged, + "beta": round(dp.reliability_index, 2), + "failure_probability": dp.probability_failure, + "convergence": dp.convergence, + "total_iterations": dp.total_iterations, + "total_model_runs": dp.total_model_runs, + } + + rows = [] + for design_point, model in zip(calculation.model_design_points, calculation.given_limit_states): + rows.append(create_row(calc=calculation, dp=design_point, model_name=model.__name__)) + df = pd.DataFrame(rows).sort_values(by=["uittredepunt_id", "ondergrondscenario_id", "vak_id"]).reset_index(drop=True) + return df + + +def combine_df_beta_per_limit_state(calc_results: List[CalcResult]) -> pd.DataFrame: + df = pd.concat((result.df_limit_state for result in calc_results), ignore_index=True) + return df + + +def collect_df_beta_scenario(calc: SystemCalculation) -> pd.DataFrame: + + def create_row(calculation): + return { + "uittredepunt_id": calculation.metadata["uittredepunt_id"], + "ondergrondscenario_id": calculation.metadata["ondergrondscenario_naam"], # TODO: id naar naam veranderen? + "vak_id": calculation.metadata["vak_id"], + "system_calculation": calculation, + "converged": calculation.system_design_point.is_converged, + "beta": round(calculation.system_design_point.reliability_index, 2), + "failure_probability": calculation.system_design_point.probability_failure, + "convergence": calculation.system_design_point.convergence, + "total_model_runs": calculation.system_design_point.total_model_runs, + "total_iterations": calculation.system_design_point.total_iterations, + "model_betas": ", ".join([ + str(round(dp.reliability_index, 2)) for dp in calculation.model_design_points + ]) + } + row = create_row(calc) + + return pd.DataFrame([row]) + + +def combine_df_beta_per_scenario(calc_results: List[CalcResult]) -> pd.DataFrame: + df = pd.concat((result.df_scenario for result in calc_results), ignore_index=True) + df = df.sort_values(["uittredepunt_id", "ondergrondscenario_id", "vak_id"]).reset_index(drop=True) + return df + + +def calculate_df_beta_per_uittredepunt(geoprob_pipe: GeoProbPipe, results: Results) -> pd.DataFrame: + + # Sum + df = results.df_beta_scenarios.assign( + failure_probability=results.df_beta_scenarios.apply( + lambda row: row['failure_probability'] * geoprob_pipe.input_data.scenarios.scenario_kans( + vak_id=row['vak_id'], scenario_naam=row['ondergrondscenario_id'] + ), axis=1)).groupby('uittredepunt_id', as_index=False)[ + 'failure_probability'].sum() + df["beta"] = df["failure_probability"].apply(lambda failure_prob: convert_failure_probability_to_beta(failure_prob)) + + # Determine when uittredepunt is converged (when all scenarios are converged) + conv = results.df_beta_scenarios.groupby( + 'uittredepunt_id', as_index=False)["converged"].all() + df = df.merge(conv, on="uittredepunt_id", how="left") + + # Add vak id back to it + gdf_uittredepunten = geoprob_pipe.input_data.uittredepunten.gdf + df_uittredepunten = gdf_uittredepunten[["uittredepunt_id", "vak_id"]] + df = df.merge(df_uittredepunten, left_on="uittredepunt_id", right_on="uittredepunt_id") + + return df[["uittredepunt_id", "vak_id", "converged", "beta", "failure_probability"]] + + +def construct_df_beta_per_vak(results: Results): + + # TODO: Check if all calculations on scenario level are converged? + conv = results.df_beta_scenarios.groupby('vak_id', as_index=False)["converged"].all() + + # TODO: Wat doet dit stukje code? + df = results.df_beta_uittredepunten + df = df.drop(columns=["converged"]) # TODO: Waarom drop converged? + df = df.loc[df.groupby('vak_id')['beta'].idxmin()] # Minimale beta van beta uittredepunten per vak + + # TODO: Waarom de merge? + df = df.merge(conv, on="vak_id", how="left") + return df[["uittredepunt_id", "vak_id", "converged", "beta", "failure_probability"]] diff --git a/geoprob_pipe/spatial/__init__.py b/geoprob_pipe/spatial/__init__.py new file mode 100644 index 00000000..d6e4d7f6 --- /dev/null +++ b/geoprob_pipe/spatial/__init__.py @@ -0,0 +1,31 @@ +from __future__ import annotations +from typing import TYPE_CHECKING +from geoprob_pipe.spatial.gdf_beta_limit_states import ( + get_gdf_beta_limit_states, get_gdf_beta_scenarios, get_gdf_beta_uittredepunten) +from geopandas import GeoDataFrame +if TYPE_CHECKING: + from geoprob_pipe import GeoProbPipe + + +class Spatial: + + def __init__(self, geoprob_pipe: GeoProbPipe): + self.geoprob_pipe = geoprob_pipe + + def get_gdf_beta_limit_states(self, export: bool = False) -> GeoDataFrame: + return get_gdf_beta_limit_states(self.geoprob_pipe, export=export) + + def get_gdf_beta_scenarios(self, export: bool = False) -> GeoDataFrame: + return get_gdf_beta_scenarios(self.geoprob_pipe, export=export) + + def get_gdf_beta_uittredepunten(self, export: bool = False) -> GeoDataFrame: + return get_gdf_beta_uittredepunten(self.geoprob_pipe, export=export) + + @property + def export_dir(self) -> str: + return self.geoprob_pipe.input_data.app_settings.workspace_dir + + def export_geopackage(self): + self.get_gdf_beta_limit_states(export=True) + self.get_gdf_beta_scenarios(export=True) + self.get_gdf_beta_uittredepunten(export=True) diff --git a/geoprob_pipe/spatial/gdf_beta_limit_states.py b/geoprob_pipe/spatial/gdf_beta_limit_states.py new file mode 100644 index 00000000..ce3c4246 --- /dev/null +++ b/geoprob_pipe/spatial/gdf_beta_limit_states.py @@ -0,0 +1,44 @@ +from __future__ import annotations +from geopandas import GeoDataFrame +from pandas import DataFrame +from typing import TYPE_CHECKING +if TYPE_CHECKING: + from geoprob_pipe import GeoProbPipe + + +def _get_uittredepunten_gdf_beta_results(geoprob_pipe: GeoProbPipe, df_betas: DataFrame) -> GeoDataFrame: + + # Gather uittredepunten coord values + gdf_uittredepunten = geoprob_pipe.input_data.uittredepunten.gdf + gdf_coords = gdf_uittredepunten[["uittredepunt_id", "geometry"]] + + # Merge coord values to limit state dataframe + df_merged = df_betas.merge(gdf_coords, left_on="uittredepunt_id", right_on="uittredepunt_id") + + return GeoDataFrame(df_merged, geometry="geometry", crs=gdf_uittredepunten.crs) + + +def get_gdf_beta_limit_states(geoprob_pipe: GeoProbPipe, export: bool = False) -> GeoDataFrame: + gdf = _get_uittredepunten_gdf_beta_results(geoprob_pipe, geoprob_pipe.results.df_beta_limit_states) + if export: + gdf.to_file(geoprob_pipe.input_data.app_settings.geopackage_filepath, + layer="beta_limit_states", driver="GPKG", mode="w") + return gdf + + +def get_gdf_beta_scenarios(geoprob_pipe: GeoProbPipe, export: bool = False) -> GeoDataFrame: + gdf = _get_uittredepunten_gdf_beta_results(geoprob_pipe, geoprob_pipe.results.df_beta_scenarios) + if export: + gdf.to_file( + geoprob_pipe.input_data.app_settings.geopackage_filepath, + layer="beta_scenarios", driver="GPKG", mode="w") + return gdf + + +def get_gdf_beta_uittredepunten(geoprob_pipe: GeoProbPipe, export: bool = False) -> GeoDataFrame: + gdf = _get_uittredepunten_gdf_beta_results(geoprob_pipe, geoprob_pipe.results.df_beta_uittredepunten) + if export: + gdf.to_file( + geoprob_pipe.input_data.app_settings.geopackage_filepath, + layer="beta_uittredepunten", driver="GPKG", mode="w") + return gdf diff --git a/geoprob_pipe/utils/__init__.py b/geoprob_pipe/utils/__init__.py new file mode 100644 index 00000000..c40f1eb4 --- /dev/null +++ b/geoprob_pipe/utils/__init__.py @@ -0,0 +1,9 @@ +import platform +import os + + +def clear_terminal(): + if platform.system() == "Windows": + os.system("cls") + return + os.system("clear") diff --git a/app/classes/file_system.py b/geoprob_pipe/utils/file_system.py similarity index 67% rename from app/classes/file_system.py rename to geoprob_pipe/utils/file_system.py index 146c450e..20bbd59f 100644 --- a/app/classes/file_system.py +++ b/geoprob_pipe/utils/file_system.py @@ -6,13 +6,15 @@ class FileSystem: """FileSystem class which creates a convenient overview of a given folder and the files within it""" + # TODO Later Should Klein: Is het echt nodig om een 'FileSystem'-object te maken? Deze functies bestaan al toch? def __init__(self, path_folder: str | Path, extension: Optional[str] = None) -> None: """Initialize FileSystem instance which creates a convenient overview of a given folder and the files within it Args: path_folder (str | Path): path of folder for which a FileSystem instance will be created - extension (Optional[str], optional): extension of specific files to include in the FileSystem instance. Defaults to None, which returns all files path_folder regardless of extension. + extension (Optional[str], optional): extension of specific files to include in the FileSystem instance. + Defaults to None, which returns all files path_folder regardless of extension. """ self.folderpath = self.validate_path(path_folder) @@ -40,32 +42,36 @@ def validate_path(path_to_check: str | Path) -> Path: return Path(path_to_check).resolve() @staticmethod - def find_files_in_dir(dir: str | Path, extension: str | None = None) -> list[Path]: + def find_files_in_dir(path_to_dir: str | Path, extension: str | None = None) -> list[Path]: """Find all files with a specified extension in a folder and its subfolders. Note: files starting with ~$ are ignored since these are generally temporary files Args: - dir (str | Path): folder to search in + path_to_dir (str | Path): folder to search in extension (str, None): extension without the dot (e.g. "txt" instead of ".txt"). - If None is passed all files in dir, regarless of extension, are returned + If None is passed all files in dir, regardless of extension, are returned Returns: list[Path]: list of paths to the found files in the dir. Returns None if no files were found. """ if isinstance(extension, str): - files = [file for file in Path(dir).resolve().rglob(f"*.{extension}") if file.is_file() and not file.name.startswith("~$")] + files = [file + for file in Path(path_to_dir).resolve().rglob(f"*.{extension}") + if file.is_file() and not file.name.startswith("~$")] else: - files = [file for file in Path(dir).resolve().rglob(f"*") if file.is_file() and not file.name.startswith("~$")] + files = [file + for file in Path(path_to_dir).resolve().rglob(f"*") + if file.is_file() and not file.name.startswith("~$")] return files @staticmethod - def find_subfolders(dir: str | Path) -> list[Path]: + def find_subfolders(path_to_dir: str | Path) -> list[Path]: """Find all subfolders within a parent folder Args: - dir (str | Path): folder to search in + path_to_dir (str | Path): folder to search in Returns: list[Path]: list of paths to the found subfolders in the dir. """ - return [subfolder for subfolder in Path(dir).iterdir() if subfolder.is_dir()] + return [subfolder for subfolder in Path(path_to_dir).iterdir() if subfolder.is_dir()] diff --git a/geoprob_pipe/utils/gdf.py b/geoprob_pipe/utils/gdf.py new file mode 100644 index 00000000..93467e2f --- /dev/null +++ b/geoprob_pipe/utils/gdf.py @@ -0,0 +1,26 @@ +from geopandas import GeoDataFrame +from shapely import LineString, MultiLineString + + +def convert_mls_geom_column_to_ls(gdf: GeoDataFrame) -> GeoDataFrame: + """ Converts all MultiLineString geometries with a single line that single LineString. To simplify it. """ + + def unwrap_ls_in_mls(geom): + """ Unwrap a single LineString in a MultiLineString, if it is indeed a single line. """ + + if isinstance(geom, LineString): + return geom + + if isinstance(geom, MultiLineString): + mls: MultiLineString = geom + if mls.geoms.__len__() > 1: + return mls + elif mls.geoms.__len__() == 0: + return mls.geoms[0] + + raise NotImplementedError( + f"This function was built to handle LineStrings or MultiLineStrings. Given geometry " + f"is of type '{type(geom)}'. Please contact the developer.") + + gdf["geometry"] = gdf["geometry"].apply(unwrap_ls_in_mls) + return gdf diff --git a/geoprob_pipe/utils/loggers.py b/geoprob_pipe/utils/loggers.py new file mode 100644 index 00000000..c241959c --- /dev/null +++ b/geoprob_pipe/utils/loggers.py @@ -0,0 +1,32 @@ +# import logging +# from colorlog import ColoredFormatter +from datetime import datetime +from geoprob_pipe.utils.validation_messages import BColors + +# def initiate_app_logger(to_console: bool = True): +# +# # Initiate logger +# logger = logging.getLogger("geoprob_pipe_logger") +# logger.setLevel(logging.INFO) +# +# # Console handler +# if to_console: +# console_handler = logging.StreamHandler() +# console_handler.setLevel(logging.INFO) +# formatter = ColoredFormatter( +# "%(log_color)s%(asctime)s - %(levelname)s - %(message)s", +# datefmt= "%Y-%m-%d %H:%M:%S", +# log_colors={ +# "INFO": "green", +# } +# ) +# console_handler.setFormatter(formatter) +# logger.addHandler(console_handler) + + +class TmpAppConsoleHandler: + + @staticmethod + def info( msg: str): + timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + print(BColors.OKGREEN, f"{timestamp} - INFO - {msg}", BColors.ENDC) diff --git a/geoprob_pipe/utils/statistics.py b/geoprob_pipe/utils/statistics.py new file mode 100644 index 00000000..7390d92a --- /dev/null +++ b/geoprob_pipe/utils/statistics.py @@ -0,0 +1,69 @@ +import math +from typing import Optional +from scipy.stats import lognorm, norm + + +def calc_kar_waarde_lognormal( + mean: float, percentiel: float, sd: Optional[float] = None, vc: Optional[float] = None, shift: float = 0.0 +) -> float: + r""" Berekening van de percentiel waarde van een lognormale verdeling met standaarddeviatie/variatie coëfficient + en verschuiving. + + # TODO: Bron naar documentatie van deze methodiek. + + Args: + mean (float): verwachtingswaarde van de lognormale verdeling + sd (float): standaarddeviatie van de lognormale verdeling, verplicht indien vc niet gegeven + vc (float): variatie coëfficient van de lognormale verdeling, verplicht indien sd niet gegeven + percentiel (float): percentiel waarvoor de waarde van de lognormale verdeling wordt berekend. Waarde tussen 0.0 en 1.0. + shift (float, optional): verschuiving. Defaults to 0.0. + + Returns: + float: percentiel waarde van de lognormale verdeling + """ + + # Format input arguments + if sd is None and vc is None: + raise ValueError( + f"Provide either the standard deviation (input argument sd), or the variation coefficient (vc).") + if sd is None: + sd = vc * mean + + # Logic + vc_shift = float(sd / (mean - shift)) + log_sd = math.sqrt(math.log(1.0 + math.pow(vc_shift, 2.0))) + log_mu = math.log(mean - shift) - 0.5 * math.pow(log_sd, 2.0) + kar_waarde = float(lognorm.ppf(percentiel, s=log_sd, loc=0.0, scale=math.exp(log_mu))) + shift + + return kar_waarde + + +def calc_kar_waarde_normal(mean: float, std: float, percentiel: float) -> float: + """Berekening van de percentiel waarde van een normale verdeling + + Args: + mean (float): verwachtingswaarde van de normale verdeling + std (float): standaarddeviatie van de normale verdeling + percentiel (float): percentiel waarvoor de waarde van de normale verdeling wordt berekend + + Returns: + float: percentiel waarde van de normale verdeling + """ + return float(norm.ppf(percentiel, loc= mean, scale=std)) + + +def convert_failure_probability_to_beta(failure_probability: float) -> float: + """Converts failure probability (Pf) to the reliability index (β). + + The reliability index is the negative inverse of the standard normal + cumulative distribution function (Φ) applied to the failure probability. + + β = -1 * Φ⁻¹(Pf) + + Args: + failure_probability (float): failure probability (Pf) + + Returns: + float: reliability index (β) + """ + return float(-1 * norm.ppf(failure_probability)) diff --git a/geoprob_pipe/utils/update_metadata.py b/geoprob_pipe/utils/update_metadata.py new file mode 100644 index 00000000..ea724891 --- /dev/null +++ b/geoprob_pipe/utils/update_metadata.py @@ -0,0 +1,68 @@ +from __future__ import annotations +import sqlite3 +import json +from typing import TYPE_CHECKING +if TYPE_CHECKING: + from geoprob_pipe import GeoProbPipe + + +def _to_text(v): + if v is None: + return None + if isinstance(v, (dict, list)): + return json.dumps(v, ensure_ascii=False) + if isinstance(v, (bool, int, float)): + return json.dumps(v, ensure_ascii=False) + return str(v) + + +def _upsert_metadata(conn, table, metadata_type, value): + sql_update = f'UPDATE {table} SET "values" = ? WHERE metadata_type = ?' + sql_insert = f'INSERT INTO {table} (metadata_type, "values") VALUES (?, ?)' + + with conn: # transaction + cur = conn.execute(sql_update, (value, metadata_type)) + if cur.rowcount == 0: + conn.execute(sql_insert, (metadata_type, value)) + + +def update_metadata(geoprob_pipe: GeoProbPipe): + gpkg_path = geoprob_pipe.input_data.app_settings.geopackage_filepath + table = "geoprob_pipe_metadata" + + # tekst setup voor variable values + if geoprob_pipe.input_data.app_settings.to_run_vakken_ids: + ran_vakken_ids = geoprob_pipe.input_data.app_settings.to_run_vakken_ids + else: + ran_vakken_ids = "all" + + n_calcs: int = len(geoprob_pipe.results.df_beta_scenarios) + n_points: int = len(geoprob_pipe.results.df_beta_uittredepunten) + n_vakken: int = len(geoprob_pipe.results.df_beta_vakken) + ratio_points: float = n_points / len(geoprob_pipe.input_data.uittredepunten.gdf) + + records = [ + {"metadata_type": "last_calculation_run_datetime", + "values": geoprob_pipe.input_data.app_settings.datetime_stamp}, + {"metadata_type": "last_calculation_rub_in_seconds", + "values": geoprob_pipe.time_diff.total_seconds()}, + {"metadata_type": "last_calculation_run_vakken_to_run", + "values": ran_vakken_ids}, + {"metadata_type": "last_calculation_run_nr_of_calculations", + "values": n_calcs}, + {"metadata_type": "last_calculation_run_nr_of_uittredepunten", + "values": n_points}, + {"metadata_type": "last_calculation_run_nr_of_vakken", + "values": n_vakken}, + {"metadata_type": "last_calculation_run_percentage_of_uittredepunten", + "values": ratio_points * 100} + ] + + conn = sqlite3.connect(gpkg_path) + + for r in records: + _upsert_metadata(conn=conn, table=table, + metadata_type=r["metadata_type"], + value=_to_text(r["values"])) + conn.commit() + conn.close() diff --git a/geoprob_pipe/utils/validation_messages.py b/geoprob_pipe/utils/validation_messages.py new file mode 100644 index 00000000..ca2caf50 --- /dev/null +++ b/geoprob_pipe/utils/validation_messages.py @@ -0,0 +1,85 @@ +from pandas import DataFrame, concat +from typing import Optional, Dict, Union, List + + +class BColors: + """ Helper object om prints kleur te geven. Gebruik als + + >>> print(BColors.WARNING, 'Mijn waarschuwing. ', BColors.ENDC) + + Let op. Met `BColors.ENDC` eindig je de kleur. Als je dit vergeet dan zijn alle volgende prints eveneens in kleur. + + """ + HEADER = '\033[95m' + OKBLUE = '\033[94m' + OKCYAN = '\033[96m' + OKGREEN = '\033[92m' + WARNING = '\033[93m' + FAIL = '\033[91m' + ENDC = '\033[0m' + BOLD = '\033[1m' + UNDERLINE = '\033[4m' + + +class ValidationMessages: + + def __init__(self, about: str = ""): + self.about: str = about + self.df: Optional[DataFrame] = None + + def _append_new_rows(self, new_rows: Dict): + if self.df is None: + self.df = DataFrame(new_rows) + self.df = concat([self.df, DataFrame(new_rows)]) + + @staticmethod + def _to_list(msg: Union[str, List[str]]): + assert isinstance(msg, (str, List)) + if isinstance(msg, str): + msg = [msg] + return msg + + @property + def cnt(self) -> int: + if self.df is None: + return 0 + return self.df.__len__() + + def add_warning(self, msg: Union[str, List[str]]): + msgs = self._to_list(msg=msg) + new_rows = { + "about": [self.about] * msgs.__len__(), + "type": ["warning"] * msgs.__len__(), + "msg": msgs, + } + self._append_new_rows(new_rows) + + def add_error(self, msg: Union[str, List[str]]): + msgs = self._to_list(msg=msg) + new_rows = { + "about": [self.about] * msgs.__len__(), + "type": ["error"] * msgs.__len__(), + "msg": msgs, + } + self._append_new_rows(new_rows) + + def add_info(self, msg: Union[str, List[str]]): + msgs = self._to_list(msg=msg) + new_rows = { + "about": [self.about] * msgs.__len__(), + "type": ["info"] * msgs.__len__(), + "msg": msgs, + } + self._append_new_rows(new_rows) + + def concat_with_df(self, df_to_append_to: Optional[DataFrame] = None) -> Optional[DataFrame]: + """ Helper function to concatenate the validation messages with validation messages of another + ValidationMessages-dataframe. """ + + if self.df is None: + return df_to_append_to + + if df_to_append_to is None: + return self.df + + return concat([df_to_append_to, self.df]) diff --git a/geoprob_pipe/utils/workspace.py b/geoprob_pipe/utils/workspace.py new file mode 100644 index 00000000..10086cf6 --- /dev/null +++ b/geoprob_pipe/utils/workspace.py @@ -0,0 +1,121 @@ +from pathlib import Path +from typing import Tuple +import pandas as pd +from geoprob_pipe.utils.file_system import FileSystem +from datetime import datetime +# noinspection PyPep8Naming +from geoprob_pipe.utils.loggers import TmpAppConsoleHandler as logger + + +class Workspace: + """Workspace class which handles all actions related to input, output and intermediate working files""" + + def __init__(self, path_workspace: str | Path) -> None: + """Initialize Workspace instance + + Args: + path_workspace (str | Path): path to the folder that contains all required input and where all output and + working files will be stored + """ + self.folderpath = FileSystem.validate_path(path_workspace) + self.path_output_folder = _prepare_output_folder(self.folderpath) + self.input, self.path_input_excel, self.path_hrd = _prepare_input_folder(self.folderpath) + # TODO Later Could Groot: Add functionality to read existing results (without running prob. calculations again) + logger.info("Workspace (I/O folders) successfully processed.") + + def update_output_filesystem(self) -> None: + """ + Update the output subfolder FileSystem instance (to include new calculation results) + """ + self.path_output_folder = _prepare_output_folder(self.folderpath) + + +def _prepare_output_folder(path_workspace: Path) -> FileSystem: + """ Prepare output subfolder + + Args: + path_workspace (Path): path to the folder that contains all required input and where all output and working + files will be stored + + Raises: + FileNotFoundError: raised if USE_EXISTING_TKX_RESULTS=True but the output subfolder contains no .tkx files + FileExistsError: raised if USE_EXISTING_TKX_RESULTS=False but the output subfolder still contains .tkx files + from a previous run + + Returns: + FileSystem: _description_ + """ + timestamp = datetime.now().strftime("%Y-%m-%d_%H%M") + export_path = path_workspace / "output" / timestamp + export_path.mkdir(exist_ok=False, parents=True) + logger.info(f"Output folder was successfully created in workspace folder: output/{timestamp}/.") + return FileSystem(export_path) + + +def _prepare_input_folder(path_workspace: Path) -> Tuple[FileSystem, Path, Path]: + + """Prepare input subfolder + + Args: + path_workspace (Path): path to the folder that contains all required input and where all output and working + files will be stored + + Raises: + FileNotFoundError: raised if USE_EXISTING_TKX_RESULTS=True but the number of .stix files in the input subfolder + don't match the number of .tkx files in the output subfolder + FileNotFoundError: raised if USE_EXISTING_TKX_RESULTS=False but the input subfolder contains no .stix files + FileNotFoundError: raised if USE_EXISTING_TKX_RESULTS=False but the input subfolder contains no template .tkx + file + + Returns: + FileSystem: FileSystem instance which creates a convenient overview of the input subfolder and the files within it + """ + # Create input folder if it didn't exist yet + if not Path(path_workspace / "input").exists(): + Path.mkdir(path_workspace / "input", parents=False, exist_ok=False) + print(f"INFO: input folder was successfully created in project folder ({path_workspace / 'input'})") + + # Create FileSystem instance for input folder + filesystem_input = FileSystem(path_workspace / "input") + + # Make sure the "input" subfolder contains 1 .xlsx file named input.xlsx + xlsx_input = [filepath.name + for filepath in FileSystem.find_files_in_dir(filesystem_input.folderpath, "xlsx")] + + if len(xlsx_input) != 1 or xlsx_input[0] != "input.xlsx": + raise FileNotFoundError( + f"\nInput folder {filesystem_input.folderpath} should contain exactly 1 .xlsx files named 'input.xlsx'\n" + f"(Currently found: {xlsx_input})" + ) + + # Check if input.xlsx has exactly four required sheets (case-sensitive!) + expected_sheets = {"Vakken", "Uittredepunten", "Ondergrondscenarios", "Overzicht_parameters", "Settings"} + xlsx_input_folderpath = pd.ExcelFile(filesystem_input.folderpath / "input.xlsx") + + if set(xlsx_input_folderpath.sheet_names) != expected_sheets: + raise FileNotFoundError( + f"\n{filesystem_input.folderpath / 'input.xlsx'} should contain exactly these sheets:\n" + f"{', '.join(expected_sheets)}\n" + f"Found sheets: {', '.join(xlsx_input_folderpath.sheet_names)}\n" + f"Note:\n1) Sheet names are case-sensitive!\n2) The order of sheets does not matter." + ) + + # Find HRD path + hrd_matches = filesystem_input.files.loc[ + lambda df: df["filename"].str.endswith(".sqlite") & + (df["filename"] != "hlcd.sqlite") & + ~df["filename"].str.endswith(".config.sqlite") + ] + # The .zip files containing HRD have multiple .sqlite files, but we only want the one that ends with .sqlite (not + # ending with .config.sqlite) and is not called 'hlcd.sqlite' + + if len(hrd_matches) != 1: + if len(hrd_matches) > 1: + filepaths = ', '.join(hrd_matches["filepath"].tolist()) + raise ValueError(f"Expected exactly one matching HRD .sqlite file, but found {len(hrd_matches)}:\n{filepaths}") + else: + raise ValueError("One HRD .sqlite file is required in the input folder, but none was found.") + + hrd_path = hrd_matches["filepath"].iloc[0] + + return filesystem_input, filesystem_input.folderpath / "input.xlsx", hrd_path diff --git a/geoprob_pipe/visualizations/__init__.py b/geoprob_pipe/visualizations/__init__.py new file mode 100644 index 00000000..fabe2999 --- /dev/null +++ b/geoprob_pipe/visualizations/__init__.py @@ -0,0 +1,30 @@ +from __future__ import annotations +from typing import TYPE_CHECKING +from geoprob_pipe.visualizations.graphs import Graphs +from geoprob_pipe.visualizations.maps import Maps +import os +if TYPE_CHECKING: + from geoprob_pipe import GeoProbPipe + + +class Visualizations: + + def __init__(self, app_obj: GeoProbPipe): + self.geoprob_pipe = app_obj + self.graphs = Graphs(app_obj) + self.maps = Maps(app_obj) + + @property + def export_dir(self) -> str: + path = os.path.join( + self.geoprob_pipe.input_data.app_settings.workspace_dir, + "exports", + self.geoprob_pipe.input_data.app_settings.datetime_stamp, + "visualizations" + ) + os.makedirs(path, exist_ok=True) + return str(path) + + def export_visualizations(self): + self.graphs.export_graphs() + self.maps.export_maps() diff --git a/geoprob_pipe/visualizations/graphs/__init__.py b/geoprob_pipe/visualizations/graphs/__init__.py new file mode 100644 index 00000000..df036361 --- /dev/null +++ b/geoprob_pipe/visualizations/graphs/__init__.py @@ -0,0 +1,72 @@ +from __future__ import annotations +from geoprob_pipe.visualizations.graphs.betrouwbaarheidsindex import ( + GraphBetaValuesSingleInteractive) + # beta_uittredepunten_graph, beta_scenarios_graph, beta_vakken_graph) +from geoprob_pipe.visualizations.graphs.hfreq import GraphHFreqSingleInteractive +from geoprob_pipe.visualizations.graphs.physical_values_along_levee import physical_values_buitenwaterstand_and_top_zand +from geoprob_pipe.visualizations.graphs.invloedsfactoren import invloedsfactoren +from geoprob_pipe.visualizations.graphs.phreatic_waterline import phreatic_waterline +from geoprob_pipe.visualizations.graphs.overview_alpha import overview_alpha +from geoprob_pipe.visualizations.graphs.river_waterlevel import river_waterlevel +from typing import TYPE_CHECKING +from plotly.graph_objects import Figure as PlotlyFigure +import os + +if TYPE_CHECKING: + from geoprob_pipe import GeoProbPipe + + +class Graphs: + + def __init__(self, app_obj: GeoProbPipe): + self.geoprob_pipe = app_obj + + @property + def export_dir(self) -> str: + path = os.path.join(self.geoprob_pipe.visualizations.export_dir, "graphs") + os.makedirs(path, exist_ok=True) + return path + + def hfreq_graph_in_single_interactive(self, export: bool = False) -> PlotlyFigure: + graph = GraphHFreqSingleInteractive(self.geoprob_pipe, export=export) + return graph.fig + + def invloedsfactoren(self, export: bool = False) -> PlotlyFigure: + return invloedsfactoren(self.geoprob_pipe, export=export) + + def physical_values_buitenwaterstand_and_top_zand(self, export: bool = False) -> PlotlyFigure: + return physical_values_buitenwaterstand_and_top_zand(self.geoprob_pipe, export=export) + + def beta_value_in_single_interactive(self, export: bool = False) -> PlotlyFigure: + graph = GraphBetaValuesSingleInteractive(self.geoprob_pipe, export=export) + return graph.fig + + # def beta_scenarios(self) -> PlotlyFigure: + # return beta_scenarios_graph(self.geoprob_pipe, export=False) + # + # def beta_uittredepunten(self) -> PlotlyFigure: + # return beta_uittredepunten_graph(self.geoprob_pipe, export=False) + # + # def beta_vakken(self) -> PlotlyFigure: + # return beta_vakken_graph(self.geoprob_pipe, export=False) + + def phreatic_waterline(self) -> PlotlyFigure: + return phreatic_waterline(self.geoprob_pipe, export=False) + + def overview_alpha(self) -> PlotlyFigure: + return overview_alpha(self.geoprob_pipe, export=False) + + def river_waterlevel(self) -> PlotlyFigure: + return river_waterlevel(self.geoprob_pipe, export=False) + + def export_graphs(self): + GraphHFreqSingleInteractive(self.geoprob_pipe, export=True) + GraphBetaValuesSingleInteractive(self.geoprob_pipe, export=True) + # beta_scenarios_graph(self.geoprob_pipe, export=True) + # beta_uittredepunten_graph(self.geoprob_pipe, export=True) + # beta_vakken_graph(self.geoprob_pipe, export=True) + self.physical_values_buitenwaterstand_and_top_zand(export=True) + self.invloedsfactoren(export=True) + phreatic_waterline(self.geoprob_pipe, export=True) + overview_alpha(self.geoprob_pipe, export=True) + river_waterlevel(self.geoprob_pipe, export=True) diff --git a/geoprob_pipe/visualizations/graphs/betrouwbaarheidsindex.py b/geoprob_pipe/visualizations/graphs/betrouwbaarheidsindex.py new file mode 100644 index 00000000..992ba84e --- /dev/null +++ b/geoprob_pipe/visualizations/graphs/betrouwbaarheidsindex.py @@ -0,0 +1,889 @@ +from __future__ import annotations +from pandas import DataFrame, merge +import numpy as np +import os +from datetime import datetime +import plotly.graph_objects as go +from typing import TYPE_CHECKING +if TYPE_CHECKING: + from geoprob_pipe import GeoProbPipe + + +# def _background_graph( +# geoprob_pipe: GeoProbPipe, +# fig: go.Figure, +# ) -> go.Figure: +# # Categorie kleuren +# +# # # Oude categorie grenzen en kleuren +# # cg = geoprob_pipe.input_data.traject_normering.beta_categorie_grenzen +# # colors = ["rgba(0,128,0,0.4)", "rgba(144,238,144,0.4)", +# # "rgba(255,255,0,0.4)", "rgba(255,165,0,0.4)", +# # "rgba(255,0,0,0.4)", "rgba(128,0,128,0.4)"] +# # labels = ["βeis;sig;dsn / 30", "βeis;sig;dsn", +# # "βeis;ond;dsn", +# # "βeis;ond", "βeis;ond * 30", ""] +# +# cg = geoprob_pipe.input_data.traject_normering.riskeer_categorie_grenzen +# colors = ["rgba(30,141,41,0.6)", "rgba(146,206,90,0.6)", +# "rgba(198,226,176,0.6)", "rgba(255,255,0,0.6)", +# "rgba(254,165,3,0.6)", "rgba(255,0,0,0.6)", +# "rgba(177,33,38,0.6)"] +# labels = ["+III", "+II", "+I", "0", "-I", "-II", "-III"] +# +# vakken = geoprob_pipe.input_data.vakken.gdf +# x_line = np.linspace(vakken['m_start'].min()-10, +# vakken['m_end'].max()+10) +# +# fig.add_annotation( +# x=0.5, y=np.log10(2.2), text="Vak ID:", showarrow=False, +# xanchor="left", yanchor="bottom", font=dict(color="black")) +# +# # for _, vak in vakken.iterrows(): +# # x=0.5, y=np.log10(2.1), text="Vak ID:", showarrow=False, xanchor="left", yanchor="bottom", +# # font=dict(color="black")) +# for _, vak in geoprob_pipe.input_data.vakken.gdf.iterrows(): +# fig.add_vline(x=vak["m_start"], line_color="black", line_width=1) +# fig.add_vline(x=vak["m_end"], line_color="black", line_width=1) +# fig.add_annotation( +# x=(vak["m_start"] + vak["m_end"]) / 2, y=np.log10(2), +# text=f"{vak['id']}", +# showarrow=False, +# xanchor="center", +# yanchor="bottom", +# font=dict(color="black")) +# +# for i, grens in enumerate(cg): +# +# if cg[grens][0] <= 0: +# cg[grens][0] = np.log10(2) +# +# # Onderste lijn (zichtbaar) +# fig.add_trace(go.Scatter( +# x=x_line, y=[cg[grens][0]] * len(x_line), name=grens, +# mode="lines", line=dict(color="black", width=0.5), +# hoverinfo="skip", showlegend=False,)) +# +# # Bovenste lijn (onzichtbaar, zorgt voor fill) +# fig.add_trace(go.Scatter( +# x=x_line, y=[cg[grens][1]] * len(x_line), name=grens, mode="lines", +# line=dict(width=0), # geen bovenrand zichtbaar +# fill="tonexty", +# fillcolor=colors[i % len(colors)], # kleur uit lijst +# hoverinfo="skip", showlegend=False)) +# +# # Labels bij de ondergrens +# fig.add_annotation( +# x=x_line.max(), +# y=(np.log10(cg[grens][0]) + np.log10(cg[grens][1])) / 2, +# text=labels[i % len(labels)], +# showarrow=False, +# xanchor="left", +# yanchor="middle", +# font=dict(color="black", size=10), +# align="right" +# ) +# +# return fig + + +# def beta_scenarios_graph(geoprob_pipe: GeoProbPipe) -> go.Figure: +# """ Grafiek van de betrouwbaarheidsindex per scenario over de +# gecombineerde uitvoer (uplift/heave/piping). Over de x-as uitgezet +# tegen de dijkpaal nummering. Op de achtergrond zijn de +# categoriegrenzen weergegeven. """ +# +# # Collect data +# gdf_uittredepunten = geoprob_pipe.input_data.uittredepunten.gdf +# df_results_combined = geoprob_pipe.results.df_beta_scenarios +# df_for_graph = merge( +# left=df_results_combined[["uittredepunt_id", "beta", "converged"]], +# right=gdf_uittredepunten[["uittredepunt_id", "metrering"]], +# on="uittredepunt_id", +# how="left" +# ) +# +# # Plot data +# fig = go.Figure() +# # Background +# fig = _background_graph(geoprob_pipe, fig) +# beta_min = 2 +# beta_max = 20 +# for value, color, name in [(True, "black", 'Beta scenarios'), +# (False, "blue", "Unconverged Beta scenarios")]: +# mask = df_for_graph["converged"] == value +# mask_low = df_for_graph["beta"] < beta_min +# mask_high = df_for_graph["beta"] > beta_max +# +# # In range +# fig.add_trace( +# go.Scatter( +# x=df_for_graph.loc[mask, 'metrering'], +# y=df_for_graph.loc[mask, "beta"], +# mode='markers', +# marker=dict(symbol='diamond', size=7, +# color=color, +# line=dict(color="white", width=1)), +# legendgroup="Beta scenarios", +# name=name, +# customdata=df_for_graph.loc[ +# mask, ["uittredepunt_id", "beta", "metrering"] +# ], +# hovertemplate=("ID: %{customdata[0]}
" + +# "Beta: %{customdata[1]:.3f}
" + +# "Metrering: %{customdata[2]}"), +# showlegend=value +# ) +# ) +# # Above range +# mask_combi = mask & mask_high +# fig.add_trace( +# go.Scatter( +# x=df_for_graph.loc[mask_combi, 'metrering'], +# y=[beta_max-0.1] * mask_combi.sum(), +# mode='markers', +# marker=dict(symbol='triangle-up', size=7, +# color=color, +# line=dict(color="white", width=1)), +# legendgroup="Beta scenarios", +# name=name + " above plotted range", +# customdata=df_for_graph.loc[ +# mask_combi, ["uittredepunt_id", "beta", "metrering"] +# ], +# hovertemplate=("ID: %{customdata[0]}
" + +# "Beta: %{customdata[1]:.3f}
" + +# "Metrering: %{customdata[2]}"), +# showlegend=value +# ) +# ) +# # Below range +# mask_combi = mask & mask_low +# fig.add_trace( +# go.Scatter( +# x=df_for_graph.loc[mask_combi, 'metrering'], +# y=[beta_min+0.1] * mask_combi.sum(), +# mode='markers', +# marker=dict(symbol='triangle-down', size=7, +# color=color, +# line=dict(color="white", width=1)), +# legendgroup="Beta scenarios", +# name=name + " below plotted range", +# customdata=df_for_graph.loc[mask_combi, +# ["uittredepunt_id", "beta", "metrering"] +# ], +# hovertemplate=("ID: %{customdata[0]}
" + +# "Beta: %{customdata[1]:.3f}
" + +# "Metrering: %{customdata[2]}"), +# showlegend=value +# ) +# ) +# +# # Layout +# fig.update_layout( +# title="Betrouwbaarheidsindex STPH per scenarioberekening", +# xaxis=dict(title="Metrering", +# type='linear', +# range=[ +# 0, geoprob_pipe.input_data.vakken.gdf['m_end'].max()+10 +# ], +# showgrid=True, +# gridwidth=0.5, +# gridcolor="gray" +# ), +# yaxis=dict(title="Betrouwbaarheidsindex β [-]", +# type='log', +# range=[np.log10(2), np.log10(20)], +# showgrid=True, +# gridwidth=0.5, +# gridcolor="gray", +# tickmode="array", +# tickvals=[2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20], +# ticktext=[2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20] +# ), +# showlegend=False, +# ) +# +# return fig + + +# def beta_uittredepunten_graph(geoprob_pipe: GeoProbPipe) -> go.Figure: +# """ Grafiek van de betrouwbaarheidsindex per uittredepunt over +# de gecombineerde uitvoer (uplift/heave/piping). Over de x-as +# uitgezet tegen de dijkpaal nummering. Op de achtergrond zijn de +# categoriegrenzen weergegeven. """ +# +# # Collect data +# gdf_uittredepunten_m = geoprob_pipe.input_data.uittredepunten.gdf +# df_results_uittredepunten = geoprob_pipe.results.df_beta_uittredepunten +# df_for_graph = merge( +# left=df_results_uittredepunten[["uittredepunt_id", "beta", "converged"]], +# right=gdf_uittredepunten_m[["uittredepunt_id", "metrering"]], +# on="uittredepunt_id", +# how="left" +# ) +# # Plot data +# fig = go.Figure() +# # Background +# fig = _background_graph(geoprob_pipe, fig) +# beta_min = 2 +# beta_max = 20 +# # mask_low = df_for_graph["beta"] < beta_min +# # mask_high = df_for_graph["beta"] > beta_max +# # In range +# for value, color, name in [(True, "black", "Beta uittredepunt"), +# (False, "blue", "Unconverged Beta uittredepunt")]: +# mask = df_for_graph["converged"] == value +# mask_low = df_for_graph["beta"] < beta_min +# mask_high = df_for_graph["beta"] > beta_max +# # In range +# fig.add_trace( +# go.Scatter( +# x=df_for_graph.loc[mask, "metrering"], +# y=df_for_graph.loc[mask, "beta"], +# mode='markers', +# marker=dict(symbol='circle', size=7, color=color), +# name=name, +# customdata=df_for_graph[ +# ["uittredepunt_id", "beta", "metrering"] +# ], +# hovertemplate=("ID: %{customdata[0]}
" + +# "Beta: %{customdata[1]:.3f}
" + +# "Metrering: %{customdata[2]}"), +# legendgroup="Beta uittredepunten", +# showlegend=value +# ) +# ) +# # Above range +# mask_combi = mask & mask_high +# fig.add_trace( +# go.Scatter( +# x=df_for_graph.loc[mask_combi, 'metrering'], +# y=[beta_max-0.1] * mask_combi.sum(), +# mode='markers', +# marker=dict(symbol='triangle-up', size=7, color=color), +# name=name + " above plotted range", +# customdata=df_for_graph.loc[ +# mask_combi, ["uittredepunt_id", "beta", "metrering"] +# ], +# hovertemplate=("ID: %{customdata[0]}
" + +# "Beta: %{customdata[1]:.3f}
" + +# "Metrering: %{customdata[2]}"), +# legendgroup="Beta uittredepunten", +# showlegend=value +# ) +# ) +# # Below range +# mask_combi = mask & mask_low +# fig.add_trace( +# go.Scatter( +# x=df_for_graph.loc[mask_combi, 'metrering'], +# y=[beta_min+0.1] * mask_combi.sum(), +# mode='markers', +# marker=dict(symbol='triangle-down', size=7, color=color), +# name=name + " below plotted range", +# customdata=df_for_graph.loc[ +# mask_combi, ["uittredepunt_id", "beta", "metrering"] +# ], +# hovertemplate=("ID: %{customdata[0]}
" + +# "Beta: %{customdata[1]:.3f}
" + +# "Metrering: %{customdata[2]}"), +# legendgroup="Beta uittredepunten", +# showlegend=value +# ) +# ) +# +# # Layout +# fig.update_layout( +# title="Betrouwbaarheidsindex STPH per uittredepunt", +# xaxis=dict(title="Metrering", +# type='linear', +# range=[ +# 0, geoprob_pipe.input_data.vakken.gdf['m_end'].max()+10 +# ], +# showgrid=True, +# gridwidth=0.5, +# gridcolor="gray" +# ), +# yaxis=dict(title="Betrouwbaarheidsindex β [-]", +# type='log', +# range=[np.log10(2), np.log10(20)], +# showgrid=True, +# gridwidth=0.5, +# gridcolor="gray", +# tickmode="array", +# tickvals=[2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20], +# ticktext=[2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20] +# ), +# showlegend=False, +# ) +# +# # Export +# # if export: +# # export_dir = os.path.join( +# # geoprob_pipe.visualizations.graphs.export_dir, +# # "grafiek_betrouwbaarheidsindex" +# # ) +# # os.makedirs(export_dir, exist_ok=True) +# # if geoprob_pipe.software_requirements.chrome_is_installed: +# # fig.write_image(os.path.join(export_dir, +# # "beta_uittredepunten.png"), +# # format="png", width=1400, scale=5) +# +# return fig + + +# def beta_vakken_graph(geoprob_pipe: GeoProbPipe,) -> go.Figure: +# """ Grafiek van de betrouwbaarheidsindex per uittredepunt over de +# gecombineerde uitvoer (uplift/heave/piping). Over de x-as uitgezet +# tegen de dijkpaal nummering. Op de achtergrond zijn de +# categoriegrenzen weergegeven. """ +# +# # Collect data +# gdf_vakken = geoprob_pipe.input_data.vakken.gdf +# df_results_vakken = geoprob_pipe.results.df_beta_vakken +# df_results_vakken = df_results_vakken.rename(columns={"vak_id": "id"}) +# df_for_graph = merge( +# left=df_results_vakken[["id", "beta", "converged"]], +# right=gdf_vakken[["id", "m_start", "m_end"]], +# on="id", +# how="left" +# ) +# +# # Plot data +# fig = go.Figure() +# # Background +# fig = _background_graph(geoprob_pipe, fig) +# +# beta_min = 2 +# beta_max = 20 +# +# for value, color, name in [(True, "black", "Beta vakken"), +# (False, "blue", "Unconverged Beta vakken")]: +# mask = df_for_graph["converged"] == value +# mask_low = df_for_graph["beta"] < beta_min +# mask_high = df_for_graph["beta"] > beta_max +# for _, row in df_for_graph.loc[mask].iterrows(): +# fig.add_trace(go.Scatter( +# x=[row["m_start"], row["m_end"]], +# y=[row["beta"], row["beta"]], +# mode="lines", +# line=dict(color=color, width=2.5), +# name=name, +# customdata=[[row["id"], row["beta"]]] * 2, +# hovertemplate=("ID: %{customdata[0]}
" + +# "Beta: %{customdata[1]:.3f}
"), +# legendgroup="Beta vakken", +# showlegend=False +# )) +# # Above range +# mask_combi = mask & mask_high +# for _, row in df_for_graph.loc[mask_combi].iterrows(): +# fig.add_trace(go.Scatter( +# x=[(row["m_start"] + row["m_end"]) / 2], +# y=[beta_max-0.1], +# mode="markers", +# marker=dict(color=color, symbol="triangle-up", size=9), +# name=name + " above plotted range", +# customdata=[[row["id"], row["beta"]]], +# hovertemplate=("ID: %{customdata[0]}
" + +# "Beta: %{customdata[1]:.3f}
"), +# legendgroup="Beta vakken", +# showlegend=False +# )) +# +# # Below range +# mask_combi = mask & mask_low +# for _, row in df_for_graph.loc[mask_combi].iterrows(): +# fig.add_trace(go.Scatter( +# x=[(row["m_start"] + row["m_end"]) / 2], +# y=[beta_min+0.1], +# mode="markers", +# marker=dict(color=color, symbol="triangle-down", size=9), +# name=name + " below plotted range", +# customdata=[[row["id"], row["beta"]]], +# hovertemplate=("ID: %{customdata[0]}
" + +# "Beta: %{customdata[1]:.3f}
"), +# legendgroup="Beta vakken", +# showlegend=False +# )) +# +# +# # Layout +# fig.update_layout( +# title="Betrouwbaarheidsindex STPH per vak", +# xaxis=dict(title="Metrering", +# type='linear', +# range=[ +# 0, geoprob_pipe.input_data.vakken.gdf['m_end'].max()+10 +# ], +# showgrid=True, +# gridwidth=0.5, +# gridcolor="gray" +# ), +# yaxis=dict(title="Betrouwbaarheidsindex β [-]", +# type='log', +# range=[np.log10(2), np.log10(20)], +# showgrid=True, +# gridwidth=0.5, +# gridcolor="gray", +# tickmode="array", +# tickvals=[2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20], +# ticktext=[2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20] +# ) +# ) +# +# # Export +# # if export: +# # export_dir = os.path.join( +# # geoprob_pipe.visualizations.graphs.export_dir, +# # "grafiek_betrouwbaarheidsindex" +# # ) +# # os.makedirs(export_dir, exist_ok=True) +# # if geoprob_pipe.software_requirements.chrome_is_installed: +# # fig.write_image(os.path.join(export_dir, "beta_vakken.png"), +# # format="png", scale=5, width=1400) +# +# return fig + + +def _add_beta_per_uittredepunt_points( + self, df_for_graph: DataFrame, mask, name: str, color: str, value: bool): + """ Visualization of beta of uittredepunten. + + :param self: GraphBetaValuesSingleInteractive-object + :param df_for_graph: Data to plot + :param mask: Boolean Series for which uittredepunten to plot in graph. Either converged of unconverged points. + :param name: Marker name + :param color: Marker color + :param value: Requested option: converged or not converged + """ + + self.fig.add_trace( + go.Scatter( + x=df_for_graph.loc[mask, "metrering"], y=df_for_graph.loc[mask, "beta"], + mode='markers', marker=dict(symbol='circle', size=7, color=color), name=name, + customdata=df_for_graph.loc[mask, ["uittredepunt_id", "beta", "metrering"]], + hovertemplate=("ID: %{customdata[0]}
" + + "Beta: %{customdata[1]:.3f}
" + + "Metrering: %{customdata[2]}"), + legendgroup="Beta uittredepunten", showlegend=value)) + + +def _add_beta_per_uittredepunt_indication_above_plotting_range( + self, df_for_graph: DataFrame, mask, name: str, color: str, value: bool): + """ Indication to user that there are Beta results plotted outside the plotting range. In this case above range. """ + + self.fig.add_trace( + go.Scatter( + x=df_for_graph.loc[mask, 'metrering'], + y=[self.beta_max - 0.1] * mask.sum(), + mode='markers', + marker=dict(symbol='triangle-up', size=7, color=color), + name=name + " above plotted range", + customdata=df_for_graph.loc[mask, ["uittredepunt_id", "beta", "metrering"]], + hovertemplate=("ID: %{customdata[0]}
" + + "Beta: %{customdata[1]:.3f}
" + + "Metrering: %{customdata[2]}"), + legendgroup="Beta uittredepunten", + showlegend=value + ) + ) + + +def _add_beta_per_uittredepunt_indication_below_plotting_range( + self, df_for_graph: DataFrame, mask, name: str, color: str, value: bool): + """ Indication to user that there are Beta results plotted outside the plotting range. In this case below range. """ + + self.fig.add_trace( + go.Scatter( + x=df_for_graph.loc[mask, 'metrering'], + y=[self.beta_min + 0.1] * mask.sum(), + mode='markers', + marker=dict(symbol='triangle-down', size=7, color=color), + name=name + " below plotted range", + customdata=df_for_graph.loc[mask, ["uittredepunt_id", "beta", "metrering"]], + hovertemplate=("ID: %{customdata[0]}
" + + "Beta: %{customdata[1]:.3f}
" + + "Metrering: %{customdata[2]}"), + legendgroup="Beta uittredepunten", + showlegend=value + ) + ) + + +class GraphBetaValuesSingleInteractive: + + def __init__(self, geoprob_pipe: GeoProbPipe, export: bool = True): + + # Logic + self.geoprob_pipe = geoprob_pipe + self.fig = go.Figure() + + self.gdf_uittredepunten = self.geoprob_pipe.input_data.uittredepunten.gdf + self.gdf_vakken = self.geoprob_pipe.input_data.vakken.gdf + self.m_start = self.gdf_vakken['m_start'].min()-10 + self.m_end = self.gdf_vakken['m_end'].max()+10 + + self.beta_min = 2 + self.beta_max = 20 + + self._add_backgrond() + self._add_beta_per_vak() + self._add_beta_per_scenario() + self._add_beta_per_uittredepunt() + self._update_layout() + self._optionally_export(export=export) + + def _add_beta_per_vak(self): + df_results_vakken = self.geoprob_pipe.results.df_beta_vakken + df_results_vakken = df_results_vakken.rename(columns={"vak_id": "id"}) + df_for_graph = merge( + left=df_results_vakken[["id", "beta", "converged"]], + right=self.gdf_vakken[["id", "m_start", "m_end"]], + on="id", + how="left" + ) + first = True + for value, color, name in [(True, "black", "Beta vakken"), + (False, "blue", "Unconverged Beta vakken")]: + mask = df_for_graph["converged"] == value + mask_low = df_for_graph["beta"] < self.beta_min + mask_high = df_for_graph["beta"] > self.beta_max + for _, row in df_for_graph.loc[mask].iterrows(): + self.fig.add_trace(go.Scatter( + x=[row["m_start"], row["m_end"]], + y=[row["beta"], row["beta"]], + mode="lines", + line=dict(color=color, width=2.5), + name=name, + customdata=[[row["id"], row["beta"]]] * 2, + hovertemplate=("ID: %{customdata[0]}
" + + "Beta: %{customdata[1]:.3f}
"), + legendgroup="Beta vakken", + showlegend=first & value + )) + first = False + # Above range + mask_combi = mask & mask_high + first = True + for _, row in df_for_graph.loc[mask_combi].iterrows(): + self.fig.add_trace(go.Scatter( + x=[(row["m_start"] + row["m_end"]) / 2], + y=[self.beta_max-0.1], + mode="markers", + marker=dict(color=color, symbol="triangle-up", size=9), + name=name + " above plotted range", + customdata=[[row["id"], row["beta"]]], + hovertemplate=("ID: %{customdata[0]}
" + + "Beta: %{customdata[1]:.3f}
"), + legendgroup="Beta vakken", + showlegend=first & value + )) + first = False + # Below range + mask_combi = mask & mask_low + first = True + for _, row in df_for_graph.loc[mask_combi].iterrows(): + self.fig.add_trace(go.Scatter( + x=[(row["m_start"] + row["m_end"]) / 2], + y=[self.beta_min+0.1], + mode="markers", + marker=dict(color=color, symbol="triangle-down", size=9), + name=name + " below plotted range", + customdata=[[row["id"], row["beta"]]], + hovertemplate=("ID: %{customdata[0]}
" + + "Beta: %{customdata[1]:.3f}
"), + legendgroup="Beta vakken", + showlegend=first & value + )) + first = False + + def _add_beta_per_scenario(self): + df_results_combined = self.geoprob_pipe.results.df_beta_scenarios + df_for_graph = merge( + left=df_results_combined[["uittredepunt_id", "beta", "converged"]], + right=self.gdf_uittredepunten[["uittredepunt_id", "metrering"]], + on="uittredepunt_id", + how="left" + ) + + for value, color, name in [(True, "black", 'Beta scenarios'), + (False, "blue", "Unconverged Beta scenarios")]: + mask = df_for_graph["converged"] == value + mask_low = df_for_graph["beta"] < self.beta_min + mask_high = df_for_graph["beta"] > self.beta_max + + # In range + self.fig.add_trace( + go.Scatter( + x=df_for_graph.loc[mask, 'metrering'], + y=df_for_graph.loc[mask, "beta"], + mode='markers', + marker=dict(symbol='diamond', size=7, + color=color, + line=dict(color="white", width=1)), + legendgroup="Beta scenarios", + name=name, + customdata=df_for_graph.loc[ + mask, ["uittredepunt_id", "beta", "metrering"] + ], + hovertemplate=("ID: %{customdata[0]}
" + + "Beta: %{customdata[1]:.3f}
" + + "Metrering: %{customdata[2]}"), + showlegend=value + ) + ) + # Above range + mask_combi = mask & mask_high + self.fig.add_trace( + go.Scatter( + x=df_for_graph.loc[mask_combi, 'metrering'], + y=[self.beta_max-0.1] * mask_combi.sum(), + mode='markers', + marker=dict(symbol='triangle-up', size=7, + color=color, + line=dict(color="white", width=1)), + legendgroup="Beta scenarios", + name=name + " above plotted range", + customdata=df_for_graph.loc[ + mask_combi, ["uittredepunt_id", "beta", "metrering"] + ], + hovertemplate=("ID: %{customdata[0]}
" + + "Beta: %{customdata[1]:.3f}
" + + "Metrering: %{customdata[2]}"), + showlegend=value + ) + ) + # Below range + mask_combi = mask & mask_low + self.fig.add_trace( + go.Scatter( + x=df_for_graph.loc[mask_combi, 'metrering'], + y=[self.beta_min+0.1] * mask_combi.sum(), + mode='markers', + marker=dict(symbol='triangle-down', size=7, + color=color, + line=dict(color="white", width=1)), + legendgroup="Beta scenarios", + name=name + " below plotted range", + customdata=df_for_graph.loc[mask_combi, + ["uittredepunt_id", "beta", "metrering"] + ], + hovertemplate=("ID: %{customdata[0]}
" + + "Beta: %{customdata[1]:.3f}
" + + "Metrering: %{customdata[2]}"), + showlegend=value + ) + ) + + def _add_beta_per_uittredepunt(self): + + # Gather results to plot + df_results_uittredepunten = self.geoprob_pipe.results.df_beta_uittredepunten + df_for_graph: DataFrame = merge( + left=df_results_uittredepunten[["uittredepunt_id", "beta", "converged"]], + right=self.gdf_uittredepunten[["uittredepunt_id", "metrering"]], + on="uittredepunt_id", + how="left" + ) + + # Plot converged and unconverged Beta values + for value, color, name in [ + (True, "black", "Beta uittredepunt"), + (False, "blue", "Unconverged Beta uittredepunt") + ]: + + mask = df_for_graph["converged"] == value + _add_beta_per_uittredepunt_points( + self=self, df_for_graph=df_for_graph, mask=mask, name=name, color=color, value=value) + + mask_high = df_for_graph["beta"] > self.beta_max + _add_beta_per_uittredepunt_indication_above_plotting_range( + self=self, df_for_graph=df_for_graph, mask=mask & mask_high, name=name, color=color, value=value) + + mask_low = df_for_graph["beta"] < self.beta_min + _add_beta_per_uittredepunt_indication_below_plotting_range( + self=self, df_for_graph=df_for_graph, mask=mask & mask_low, name=name, color=color, value=value) + + def _add_backgrond(self): + # Oude categorie grenzen + # cg = (self.geoprob_pipe.input_data.traject_normering + # .beta_categorie_grenzen) + # colors = ["rgba(0,128,0,0.4)", "rgba(144,238,144,0.4)", + # "rgba(255,255,0,0.4)", "rgba(255,165,0,0.4)", + # "rgba(255,0,0,0.4)", "rgba(128,0,128,0.4)"] + + # labels = ["βeis;sig;dsn / 30", "βeis;sig;dsn", + # "βeis;ond;dsn", "βeis;ond", + # "βeis;ond * 30", ""] + + cg = (self.geoprob_pipe.input_data.traject_normering + .riskeer_categorie_grenzen) + colors = ["rgba(30,141,41,0.6)", "rgba(146,206,90,0.6)", + "rgba(198,226,176,0.6)", "rgba(255,255,0,0.6)", + "rgba(254,165,3,0.6)", "rgba(255,0,0,0.6)", + "rgba(177,33,38,0.6)"] + labels = ["+III", "+II", "+I", "0", "-I", "-II", "-III"] + + x_line = np.linspace(self.m_start, self.m_end) + self.annotation_vak = [] + self.annotation_vak.append(dict(x=0.5, + y=np.log10(2.1), + text="Vak ID:", + showarrow=False, + xanchor="left", + yanchor="bottom", + font=dict(color="black") + )) + self.vak_lines = [] + for _, vak in self.gdf_vakken.iterrows(): + self.vak_lines.append(dict( + x0=vak["m_start"], x1=vak["m_start"], + y0=0, y1=1, + xref="x", yref="paper", + line=dict(color="black", width=1) + )) + self.vak_lines.append(dict( + x0=vak["m_end"], x1=vak["m_end"], + y0=0, y1=1, + xref="x", yref="paper", + line=dict(color="black", width=1) + )) + self.annotation_vak.append(dict( + x=(vak["m_start"] + vak["m_end"]) / 2, y=np.log10(2), + text=vak["id"], + showarrow=False, + xanchor="center", + yanchor="bottom", + font=dict(color="black") + )) + self.annotation_label = [] + for i, grens in enumerate(cg): + + if cg[grens][0] <= 0: + cg[grens][0] = np.log10(2) + + # Onderste lijn (zichtbaar) + self.fig.add_trace( + go.Scatter( + x=x_line, + y=[cg[grens][0]] * len(x_line), + name=grens, + mode="lines", + line=dict(color="black", width=0.5), + hoverinfo="skip", + showlegend=False, + ) + ) + + # Bovenste lijn (onzichtbaar, zorgt voor fill) + self.fig.add_trace(go.Scatter( + x=x_line, + y=[cg[grens][1]] * len(x_line), + name=grens, + mode="lines", + line=dict(width=0), # geen bovenrand zichtbaar + fill="tonexty", + fillcolor=colors[i % len(colors)], # kleur uit lijst + hoverinfo="skip", + showlegend=False, + )) + + # Labels bij de ondergrens + self.annotation_label.append(dict( + x=x_line.max(), + y=(np.log10(cg[grens][0]) + np.log10(cg[grens][1])) / 2, + text=labels[i % len(labels)], + showarrow=False, + xanchor="left", + yanchor="middle", + font=dict(color="black", size=10), + align="right" + )) + + def _update_layout(self): + self.fig.add_trace(go.Scatter( + x=[0], + y=[0], + mode="markers", + marker=dict(color="blue", + symbol="square"), + name="Unconverged", + showlegend=True + )) + annotation = self.annotation_vak + self.annotation_label + self.fig.update_layout( + title="Betrouwbaarheidsindex STPH", + xaxis=dict(title="Metrering", + type='linear', + range=[0, self.m_end], + showgrid=True, + gridwidth=0.5, + gridcolor="gray" + ), + yaxis=dict(title="Betrouwbaarheidsindex β [-]", + type='log', + range=[np.log10(2), np.log10(20)], + showgrid=True, + gridwidth=0.5, + gridcolor="gray", + tickmode="array", + tickvals=[2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20], + ticktext=[2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20] + ), + legend=dict( + yanchor="top", + y=0.99, + xanchor="left", + x=0.01 + ), + annotations=annotation, + shapes=self.vak_lines + ) + # Toggles for annotations + self.fig.update_layout( + updatemenus=[ + dict( + type="buttons", + direction="right", + buttons=[ + dict( + label="Show annotations", + method="relayout", + args=["annotations", + self.annotation_vak + self.annotation_label] + ), + dict( + label="Hide annotations", + method="relayout", + args=["annotations", self.annotation_label] + ), + dict( + label="Show vlines", + method="relayout", + args=["shapes", self.vak_lines] + ), + dict( + label="Hide vlines", + method="relayout", + args=["shapes", []] + ) + ], + x=0.5, + y=1.15, + xanchor="center" + ) + ] + ) + + def _optionally_export(self, export: bool = False, add_timestamp: bool = False): + if not export: + return + os.makedirs(self.geoprob_pipe.visualizations.graphs.export_dir, exist_ok=True) + timestamp_str = "" + if add_timestamp: + timestamp = datetime.now().strftime("%Y-%m-%d_%H%M") + timestamp_str = f"{timestamp}_" + self.fig.write_html(os.path.join( + self.geoprob_pipe.visualizations.graphs.export_dir, f"{timestamp_str}betrouwbaarheidsindex.html" + ), include_plotlyjs='cdn') diff --git a/geoprob_pipe/visualizations/graphs/hfreq.py b/geoprob_pipe/visualizations/graphs/hfreq.py new file mode 100644 index 00000000..61fb222f --- /dev/null +++ b/geoprob_pipe/visualizations/graphs/hfreq.py @@ -0,0 +1,241 @@ +from __future__ import annotations +import os +# import matplotlib.pyplot as plt +from typing import TYPE_CHECKING, List +import plotly.graph_objects as go +from datetime import datetime +# from geopandas import GeoDataFrame, read_file +# from probabilistic_library import FragilityValue +import pydra_core as pydra +from pandas import Series, concat, DataFrame, read_sql +from geoprob_pipe.cmd_app.parameter_input.expand_input_tables import run_expand_input_tables +import sqlite3 + +if TYPE_CHECKING: + from geoprob_pipe import GeoProbPipe + + +class GraphHFreqSingleInteractive: + + def __init__(self, geoprob_pipe: GeoProbPipe, export: bool = False): + + # Check if there are fragility curves referenced: + conn = sqlite3.connect(geoprob_pipe.input_data.app_settings.geopackage_filepath) + df_parameter_invoer = read_sql("SELECT * FROM parameter_invoer;", conn) + fragility_values_refs = df_parameter_invoer['fragility_values_ref'].unique() + conn.close() + if (fragility_values_refs.__len__() == 0 or + (fragility_values_refs.__len__() == 1 and fragility_values_refs[0] == '')): + return # No graphs needed + + # Helper parameters + self.max_level: float = -999 + self.min_level: float = 999 + self.max_p: float = 0.0 + self.min_p: float = 1.0 + + # Class-wide used + self.geoprob_pipe = geoprob_pipe + self.df_parameter_input_expanded: DataFrame = run_expand_input_tables( + geopackage_filepath=self.geoprob_pipe.input_data.app_settings.geopackage_filepath, add_frag_ref=True) + self.df_fragility_ref_data: DataFrame = self._collect_fragility_ref_data() + if self.df_fragility_ref_data.__len__() == 0: + return # No fragility values, then no graphs needed + + # Logic + self.fig = go.Figure() + self._add_ondergrens() + self._add_signaleringswaarde() + self._add_dummy_physical_value_legend_marker() + self._add_overschrijdingsfrequentielijnen() + self._add_physical_values() + self._update_layout() + self._optionally_export(export=export) + + def _collect_fragility_ref_data(self) -> DataFrame: + + # Transform parameter_input dictionary to columns (added columns will be: fragility_values and fragility_ref) + df = self.df_parameter_input_expanded + df = df[df["parameter_name"] == "buitenwaterstand"] + df = concat([df.drop(columns=['parameter_input']), df['parameter_input'].apply(Series)], axis=1) + # print(f"{df.__len__()=}") + # print(f"{df.columns=}") + # print(f"{df=}") + + # If fragility_values_ref not in columns, then there are no fragility values needed + if "fragility_values_ref" not in df.columns: + return DataFrame( + data=[], + columns=["uittredepunt_id", "fragility_values", "uittredepunt_ids_multiline", "frequency_line"] + ) + + # Group uittredepunt ids and fragility values + df_result = ( + df.groupby('fragility_values_ref').agg({ + 'uittredepunt_id': lambda x: ', '.join(map(str, x)), # concatenate IDs + 'fragility_values': 'first' # keep the first list (since all are equal per ref) + }).reset_index()) + df_result = df_result.rename(columns={"uittredepunt_id": "uittredepunt_ids"}) + + # Create multiline item for uittredepunten ids + df_result['uittredepunt_ids_multiline'] = "" + df_result['frequency_line'] = "" + for index, row in df_result.iterrows(): + + # Uittredepunt ids multiline + arr = row['uittredepunt_ids'].split(", ") + lines = [', '.join(arr[i:i + 5]) for i in range(0, len(arr), 5)] + df_result.loc[index, 'uittredepunt_ids_multiline'] = '
'.join(lines) + + # Create frequency line + fragility_values = df_result.loc[index, 'fragility_values'] + levels = [item.x for item in fragility_values] + exceedance_frequencies = [item.probability_of_failure for item in fragility_values] + # noinspection PyUnresolvedReferences + df_result.loc[index, 'frequency_line'] = pydra.core.datamodels.frequency_line.FrequencyLine( + level=levels, exceedance_frequency=exceedance_frequencies) + + return df_result + + def _collect_used_fragility_refs(self) -> List[str]: + df = self.df_parameter_input_expanded + df = df[df["parameter_name"] == "buitenwaterstand"] + + # Transform parameter_input dictionary to columns (added columns will be: fragility_values and fragility_ref) + df = concat([df.drop(columns=['parameter_input']), df['parameter_input'].apply(Series)], axis=1) + + return df['fragility_values_ref'].unique() + + def _add_ondergrens(self): + ondergrens = 1 / self.geoprob_pipe.input_data.traject_normering.ondergrens + self.fig.add_trace(go.Scatter( + x=[-100, 999], + y=[ondergrens, ondergrens], + mode='lines', + name=f"Ondergrens (1/{self.geoprob_pipe.input_data.traject_normering.ondergrens:,} jaren)", + line=dict(color='black', width=3), + showlegend=True, + )) + + def _add_signaleringswaarde(self): + signaleringswaarde = 1 / self.geoprob_pipe.input_data.traject_normering.signaleringswaarde + self.fig.add_trace(go.Scatter( + x=[-100, 999], + y=[signaleringswaarde, signaleringswaarde], + mode='lines', + name=f"Signaleringswaarde (1/{self.geoprob_pipe.input_data.traject_normering.signaleringswaarde:,} jaren)", + line=dict(dash='dash', color='black', width=3), + showlegend=True, + )) + + def _add_dummy_physical_value_legend_marker(self): + # Dummy legend marker + self.fig.add_trace(go.Scatter( + x=[-99], y=[1], mode='markers', name='Physical values', showlegend=True, + marker=dict(color='LightSkyBlue', size=10, line=dict(color='black', width=1)))) + + def _get_fragility_values_ref_data(self, ref: str): + df = self.df_fragility_ref_data + df = df[df['fragility_values_ref'] == ref] + return (df['fragility_values'].iloc[0], + df['frequency_line'].iloc[0], + [int(item) for item in df['uittredepunt_ids'].iloc[0].replace(" ", "").split(",")], + df['uittredepunt_ids_multiline'].iloc[0]) + + def _add_overschrijdingsfrequentielijnen(self): + + for index, fragility_values_ref in enumerate(self.df_fragility_ref_data["fragility_values_ref"].unique()): + + # Collect data for the graph + fragility_values, _, uittredepunten, uittredepunten_multiline = self._get_fragility_values_ref_data( + ref=fragility_values_ref) + levels = [item.x for item in fragility_values] + self.max_level = max(self.max_level, max(levels)) + self.min_level = min(self.min_level, min(levels)) + freqs = [item.probability_of_failure for item in fragility_values] + self.max_p = max(self.max_p, max(freqs)) + self.min_p = min(self.min_p, min(freqs)) + + # Only first overschrijdingsfrequentielijn should be visible at first + visible = 'legendonly' + if index == 0: + visible = True + + # Add lines + legend_name = f"{fragility_values_ref}
uittredepunten:
{uittredepunten_multiline}" + self.fig.add_trace(go.Scatter( + x=levels, y=freqs, mode='lines', name=legend_name, legendgroup=legend_name, visible=visible, + line=dict(dash='dash', color='blue', width=1.5), showlegend=True)) + + def _add_physical_values(self): + + for index, fragility_values_ref in enumerate(self.df_fragility_ref_data["fragility_values_ref"].unique()): + + # Collect data for the graph + _, freq_line, uittredepunten, uittredepunten_multiline = self._get_fragility_values_ref_data( + ref=fragility_values_ref) + + # Only first overschrijdingsfrequentielijn should be visible at first + visible = 'legendonly' + if index == 0: + visible = True + + # Get physical values + legend_name = f"{fragility_values_ref}
uittredepunten:
{uittredepunten_multiline}" + df = self.geoprob_pipe.results.df_alphas_influence_factors_and_physical_values( + filter_deterministic=False, filter_derived=True) + df = df[df['variable'] == 'buitenwaterstand'] + df = df[df['uittredepunt_id'].isin(uittredepunten)] + + # Scenario may have no uittredepunt connections, then no physical values need to be added + if df.__len__() == 0: + return + + levels = df['physical_value'].values + self.max_level = max(self.max_level, levels.max()) + self.min_level = min(self.min_level, levels.min()) + frequencies = [freq_line.interpolate_level(level) for level in levels] + self.max_p = max(self.max_p, max(frequencies)) + self.min_p = min(self.min_p, min(frequencies)) + + # Add markers + self.fig.add_trace(go.Scatter( + x=levels, y=frequencies, mode='markers', visible=visible, showlegend=False, legendgroup=legend_name, + marker=dict(color='LightSkyBlue', size=10, line=dict(color='black', width=1)))) + + def _yticks(self): + min_range = int(f"{self.min_p:.0e}".split("e")[1]) + e_values = list(range(0, min_range - 15, -1)) + y_ticks = [10 ** e_value for e_value in e_values] + y_ticks_text = [f"10{e_value}" for e_value in e_values] + return y_ticks, y_ticks_text + + def _update_layout(self): + length_range_xaxis = self.max_level - self.min_level + xaxis_add = length_range_xaxis * 0.05 + y_ticks, y_ticks_text = self._yticks() + self.fig.update_layout( + title=f"Overschrijdingsfrequentielijnen voor alle HydraNL locaties
" + f"Traject {self.geoprob_pipe.input_data.traject_normering.traject_id}", + xaxis=dict( + title=f"Waterstand (m+NAP)", type='linear', showgrid=True, gridwidth=0.5, gridcolor="gray", + range=[self.min_level - xaxis_add, self.max_level + xaxis_add]), + yaxis=dict( + title=f"Overschrijdingsfrequentie (log-schaal)", type='log', showgrid=True, tickformat=".0e", + gridwidth=1.0, tickvals=y_ticks, ticktext=y_ticks_text, tickmode='array', gridcolor="gray", + minor=dict( + showgrid=True, dtick="D1", gridwidth=0.5, gridcolor='rgb(199, 197, 193)'))) + + def _optionally_export(self, export: bool = False, add_timestamp: bool = False): + if not export: + return + export_dir = self.geoprob_pipe.visualizations.graphs.export_dir + os.makedirs(export_dir, exist_ok=True) + timestamp_str = "" + if add_timestamp: + timestamp = datetime.now().strftime("%Y-%m-%d_%H%M") + timestamp_str = f"{timestamp}_" + self.fig.write_html(os.path.join(export_dir, f"{timestamp_str}hfreq.html"), include_plotlyjs='cdn') + # if self.geoprob_pipe.software_requirements.chrome_is_installed: + # self.fig.write_image(os.path.join(export_dir, f"{timestamp_str}hfreq.png"), format="png") + # Note CP: Export van PNG uitgezet. Meerwaarde beperkt denk ik aangezien je de HTML al hebt. diff --git a/geoprob_pipe/visualizations/graphs/invloedsfactoren.py b/geoprob_pipe/visualizations/graphs/invloedsfactoren.py new file mode 100644 index 00000000..f02ebfbc --- /dev/null +++ b/geoprob_pipe/visualizations/graphs/invloedsfactoren.py @@ -0,0 +1,138 @@ +from __future__ import annotations +from typing import TYPE_CHECKING, Optional +import os +from pandas import DataFrame, merge +from geopandas import GeoDataFrame, read_file +from plotly.graph_objects import Figure, Bar +if TYPE_CHECKING: + from geoprob_pipe import GeoProbPipe + + +DISTINCTIVE_COLORS = [ + '(60, 180, 75)', '(230, 25, 75)', '(255, 225, 25)', '(0, 130, 200)', '(245, 130, 48)', '(145, 30, 180)', + '(70, 240, 240)', '(240, 50, 230)', '(210, 245, 60)', '(250, 190, 212)', '(0, 128, 128)', + '(220, 190, 255)', '(170, 110, 40)', '(255, 250, 200)', '(128, 0, 0)', '(170, 255, 195)', + '(128, 128, 0)', '(255, 215, 180)', '(128, 128, 128)', '(255, 255, 255)'] + + +def get_plot_order(geoprob_pipe: GeoProbPipe) -> DataFrame: + """ Assigns color codes (indices) and color rgb-values to each stochast such that they can be plotted with the + same color and same order. + + :param geoprob_pipe: + :return: DataFrame with columns 'variable', 'plot_order' and 'color' + """ + + # Define plot order + df: DataFrame = geoprob_pipe.results.df_alphas_influence_factors_and_physical_values(filter_derived=True) + df = df[["variable", "influence_factor"]] + df = df.groupby(['variable']).mean() # Influence factor average value define color order + df = df.sort_values(by=["influence_factor"], ascending=False) + df = df.reset_index(drop=False) + df['plot_order'] = df.index # Result is df with columns 'variable', 'influence_factor' (average), 'plot_order' + + # Add colors to plot order + df_colors = DataFrame({"color": DISTINCTIVE_COLORS}) # Convert to dict to df for ease of use + df_colors['plot_order'] = df_colors.index + df = merge(df, df_colors, how="left", on="plot_order") + + return df + + +def get_influence_factors_for_vak( + geoprob_pipe: GeoProbPipe, df_invloedsfactoren: DataFrame, vak_id: int +) -> Optional[DataFrame]: + """ Returns the influence factors for the worst result of a scenario within the vak. May be empty dataframe if + vak has no results. + + In the past weigh it for the uittredepunt, or average is among all uittredepunten, as was done in the past. The + choice was made to keep the actual resulting influence factors because they sum up to 100%. There is also no + physical reason to average them, and the worst case scenario is normative for the final result anyway. """ + df_result = geoprob_pipe.results.df_beta_scenarios + df_result = df_result[df_result["vak_id"] == vak_id] + + # Check if results for vak + if df_result.__len__() == 0: + return None + + df_result = df_result.sort_values(by=["beta"], ascending=True) + worst_uittredepunt_id = df_result.iloc[0]['uittredepunt_id'] + worst_scenario_id = df_result.iloc[0]['ondergrondscenario_id'] + df = df_invloedsfactoren[ + (df_invloedsfactoren["uittredepunt_id"] == worst_uittredepunt_id) & + (df_invloedsfactoren["ondergrondscenario_id"] == worst_scenario_id) + ] + return df.sort_values(by=["plot_order"]) + + +def invloedsfactoren(geoprob_pipe: GeoProbPipe, export: bool = False) -> Figure: + + # Get data + df_invloedsfactoren = geoprob_pipe.results.df_alphas_influence_factors_and_physical_values(filter_derived=True) + + # Add plot order + df_plot_order = get_plot_order(geoprob_pipe=geoprob_pipe) + df_invloedsfactoren = merge( + df_invloedsfactoren, df_plot_order[["variable", "plot_order", "color"]], how="left", on="variable") + + # Plot data + fig = Figure() + gdf_vakindeling: GeoDataFrame = read_file( + geoprob_pipe.input_data.app_settings.geopackage_filepath, layer="vakindeling") + vakken = {row['id']: row["naam"] for index, row in gdf_vakindeling.iterrows()} + picked_colors = {} + added_to_legend = [] + for vak_id, vak_naam in vakken.items(): + + # Get invloedsfactoren data + df_factoren = get_influence_factors_for_vak(geoprob_pipe, df_invloedsfactoren, vak_id) + + # If not results/factors + if df_factoren is None: + color = f"rgb{DISTINCTIVE_COLORS[0]}" + # Add dummy zero value to visualize no results in vak + # noinspection PyTypeChecker + fig.add_trace(Bar(x=[vak_naam], y=[0], name="dummy", marker_color=color, showlegend=False)) + continue + + # Plot data + stochasten = df_factoren['variable'].unique().tolist() + for stochast in stochasten: + if stochast not in picked_colors.keys(): + color = f"rgb{DISTINCTIVE_COLORS[picked_colors.__len__()]}" + picked_colors[stochast] = color + else: + color = picked_colors[stochast] + show_legend = False + if stochast not in added_to_legend: + added_to_legend.append(stochast) + show_legend = True + fig.add_trace(Bar( + x=[vak_naam], + y=[df_factoren[df_factoren['variable'] == stochast].iloc[0]['influence_factor'] * 100], + name=stochast, marker_color=color, showlegend=show_legend, legendgroup=stochast, + )) + + # Layout styling + fig.update_layout( + barmode='stack', + bargap=0, # Geen ruimte tussen groepen + bargroupgap=0, # Geen ruimte tussen individuele bars binnen een groep + title='Invloedsfactoren
' + 'Invloedsfactoren zijn van het worstcase ondergrondscenario en uittredepunt.', + xaxis_title='Vak', + yaxis=dict( + title="Percentage", + ), # Pas dit aan naar jouw gewenste bereik + ) + + # Export + if export: + export_dir = geoprob_pipe.visualizations.graphs.export_dir + os.makedirs(export_dir, exist_ok=True) + fig.write_html(os.path.join(export_dir, f"invloedsfactoren.html"), include_plotlyjs='cdn') + # if geoprob_pipe.software_requirements.chrome_is_installed: + # fig.write_image(os.path.join(export_dir, f"invloedsfactoren.png"), format="png") + + # for stochast in + return fig diff --git a/geoprob_pipe/visualizations/graphs/overview_alpha.py b/geoprob_pipe/visualizations/graphs/overview_alpha.py new file mode 100644 index 00000000..e4875874 --- /dev/null +++ b/geoprob_pipe/visualizations/graphs/overview_alpha.py @@ -0,0 +1,188 @@ +from __future__ import annotations +import os +import pandas as pd +import plotly.graph_objects as go +from plotly.subplots import make_subplots +from pandas import merge +from geoprob_pipe.calculations.systems.mappers.initial_input_mapper import INITIAL_INPUT_MAPPER +from typing import TYPE_CHECKING + +from geoprob_pipe.cmd_app.utils.misc import get_geohydrological_model + +if TYPE_CHECKING: + from geoprob_pipe import GeoProbPipe + + +def overview_alpha(geoprob_pipe: GeoProbPipe, export: bool = False): + + model_string = get_geohydrological_model(app_settings=geoprob_pipe.input_data.app_settings) + initial_input_mapper = INITIAL_INPUT_MAPPER[model_string]['input'] + + # Get data for graphing + df = geoprob_pipe.results.df_alphas_influence_factors_and_physical_values( + system_only=True, filter_deterministic=False, filter_derived=False + ) + df = df[["uittredepunt_id", "ondergrondscenario_id", "vak_id", + "variable", "distribution_type", "physical_value"]] + + gdf_uittredepunten = geoprob_pipe.input_data.uittredepunten.gdf + df = merge(df, gdf_uittredepunten[["uittredepunt_id", "metrering"]], + on="uittredepunt_id", how="left") + + # Determine scenario order per uittredepunt_id + df["scenario_order"] = ( + df.groupby("uittredepunt_id")["ondergrondscenario_id"] + .transform(lambda x: pd.factorize(x)[0] + 1) + ) + scenario_orders = sorted(df["scenario_order"].unique()) + + # List of all alphas that can be shown + parameters: list[str] = list(df["variable"].unique()) + # Add distribution type + dist_types = {} + for param in parameters: + dist_type = df.loc[ + df["variable"] == param, "distribution_type"].unique()[0] + dist_types.update({param: dist_type}) + # Add units + unit_lookup = {item["name"]: item["unit"] for item in initial_input_mapper} + param_units = {} + for param in parameters: + try: + param_units.update({param: str(unit_lookup[param]).strip("[]")}) + except KeyError: + param_units.update({param: "?"}) + + # Add parameter units missing in DUMMY_INPUT by hand. + param_units.update({ + "L_kwelweg": "m", + "L_voorland": "m", + "W_voorland": "s/m", + "buitenwaterstand_gemiddeld": "m+NAP", + "d_deklaag": "m", + "dh_c": "m", + "dh_red": "m", + "dphi_c_u": "m+NAP", + "h_exit": "m+NAP", + "i_exit": "-", + "k_wvp": "m/dag", + "lambda_voorland": "m", + "phi_exit": "m+NAP", + "phi_exit_gemiddeld": "m+NAP", + "r_exit": "-", + "z_combin": "-", + "z_h": "-", + "z_p": "-", + "z_u": "-" + }) + + # Create subplots + fig = make_subplots( + rows=len(parameters), + cols=1, + shared_xaxes=False, + subplot_titles=parameters + ) + + # Add a button for each ondergrondscenario + buttons = [] + + # Add scatter plot per scenario + for i, scen_order in enumerate(scenario_orders): + df_case = df[df["scenario_order"] == scen_order] + + for row_idx, param in enumerate(parameters, start=1): + df_param = df_case[df_case["variable"] == param] + fig.add_trace( + go.Scatter( + x=df_param["metrering"], + y=df_param["physical_value"], + mode="markers", + marker=dict(color="black", symbol="x", size=5), + name=param, + visible=(i == 0) + ), + row=row_idx, col=1 + ) + fig.update_xaxes(showgrid=True, tickangle=90, + row=row_idx, col=1) + fig.update_yaxes(showgrid=True, + title_text=f"{param} [{param_units[param]}]" + + f"
({dist_types[param]})", + row=row_idx, col=1) + + total_traces = len(scenario_orders) * len(parameters) + + # Determine which scenario is visible + vis = [False] * total_traces + vis[i*len(parameters):(i+1)*len(parameters)] = [True] * len(parameters) + + buttons.append(dict( + label=f"Scenario {scen_order}", + method="update", + args=[ + {"visible": vis}, + {"title": f"Overview of parameters for Scenario {scen_order}"} + ] + )) + + # Layout and button + fig.update_layout( + height=300*len(parameters), + showlegend=False, + title=f"Overview of parameters for Scenario {scenario_orders[0]}", + updatemenus=[dict( + active=0, + buttons=buttons, + direction="down", + showactive=True, + x=1.05, y=1.01 + )], + ) + + # Export + if export: + export_dir = os.path.join( + geoprob_pipe.visualizations.graphs.export_dir, + "grafiek_physical_values" + ) + os.makedirs(export_dir, exist_ok=True) + + fig.write_html( + os.path.join(export_dir, "overview_alphas.html"), + include_plotlyjs='cdn' + ) + + for scen_order in scenario_orders: + df_case = df[df["scenario_order"] == scen_order] + fig_case = make_subplots( + rows=len(parameters), cols=1, + shared_xaxes=False, + subplot_titles=parameters + ) + for row_idx, param in enumerate(parameters, start=1): + df_param = df_case[df_case["variable"] == param] + fig_case.add_trace( + go.Scatter( + x=df_param["metrering"], + y=df_param["physical_value"], + mode="markers", + marker=dict(color="black", symbol="x", size=5), + name=param + ), + row=row_idx, col=1 + ) + fig_case.update_xaxes(showgrid=True, tickangle=90, + row=row_idx, col=1) + fig_case.update_yaxes(showgrid=True, + title_text=f"{param} [{param_units[param]}]" + + f"
({dist_types[param]})", + row=row_idx, col=1) + + fig_case.update_layout( + height=300*len(parameters), + showlegend=False, + title=f"Overview of parameters for Scenario {scen_order}" + ) + + return fig diff --git a/geoprob_pipe/visualizations/graphs/phreatic_waterline.py b/geoprob_pipe/visualizations/graphs/phreatic_waterline.py new file mode 100644 index 00000000..b97f206f --- /dev/null +++ b/geoprob_pipe/visualizations/graphs/phreatic_waterline.py @@ -0,0 +1,160 @@ +from __future__ import annotations +import os +import plotly.graph_objects as go +import pandas as pd +from typing import TYPE_CHECKING +if TYPE_CHECKING: + from geoprob_pipe import GeoProbPipe + + +def phreatic_waterline(geoprob_pipe: GeoProbPipe, export: bool = False): + # Prepare data + df = geoprob_pipe.results.df_alphas_influence_factors_and_physical_values( + system_only=True, filter_deterministic=False, filter_derived=False + ) + df = df[["uittredepunt_id", "ondergrondscenario_id", "vak_id", + "variable", "distribution_type", "physical_value"]] + + gdf_uittredepunten = geoprob_pipe.input_data.uittredepunten.gdf + df = df.merge( + gdf_uittredepunten[["uittredepunt_id", "metrering"]], + on="uittredepunt_id", how="left" + ) + + # Determine scenario rank per uittredepunt_id + # Assign "scenario_order" = 1, 2, 3, ... based on encounter order + df["scenario_order"] = ( + df.groupby("uittredepunt_id")["ondergrondscenario_id"] + .transform(lambda x: pd.factorize(x)[0] + 1) + ) + + scenario_orders = sorted(df["scenario_order"].unique()) + + # Plotly setup + fig = go.Figure() + buttons = [] + + colors = { + "buitenwaterstand": "blue", + "phi_exit": "green", + "h_exit": "black", + "top_zand": "brown" + } + symbols = { + "buitenwaterstand": "square", + "phi_exit": "x", + "h_exit": "circle", + "top_zand": "square" + } + names = { + "buitenwaterstand": "Buitenwaterstand", + "phi_exit": "Stijghoogte uittredepunt (phi_exit)", + "h_exit": "Gehanteerde hoogte uittredepunt (h_exit)", + "top_zand": "Bovenkant watervoerend pakket (top_zand)" + } + + # Build one frame per scenario order + for i, scen_order in enumerate(scenario_orders): + df_case: pd.DataFrame = df[df["scenario_order"] == scen_order] + + # Add 4 variable traces per scenario_order + for variable in ["buitenwaterstand", "phi_exit", "h_exit", "top_zand"]: + df_var = df_case[df_case["variable"] == variable] + dist_type = (str(df_var["distribution_type"].unique()) + .strip("[]").strip("'")) + fig.add_trace(go.Scatter( + x=df_var['metrering'], + y=df_var["physical_value"], + mode='markers', + name=f"{names[variable]} ({dist_type})", + marker=dict( + symbol=symbols[variable], + size=5, + color=colors[variable] + ), + visible=(i == 0) + )) + + # Button logic + # Disappearance of title is a plotly bug + total_traces = len(scenario_orders) * 4 + vis = [False] * total_traces + vis[i*4:(i+1)*4] = [True]*4 + + buttons.append(dict( + label=f"Scenario {scen_order}", + method="update", + args=[ + {"visible": vis}, + {"title": f"Physical values t.o.v. NAP voor scenario {scen_order}" + + "
Punten zijn per uittredepunt"} + ] + )) + + # Layout and controls + fig.update_layout( + title=f"Physical values t.o.v. NAP voor scenario {scenario_orders[0]}" + + "
Punten zijn per uittredepunt", + updatemenus=[dict( + active=0, + buttons=buttons, + direction="down", + showactive=True, + x=1.05, y=1.15 + )], + xaxis=dict( + title="Metrering", + showgrid=True, gridwidth=0.5, gridcolor="gray", + ), + yaxis=dict( + title="Hoogte [m+NAP]", + showgrid=True, gridwidth=0.5, gridcolor="gray", + ), + legend=dict( + orientation="h", + yanchor="bottom", + y=-0.25, + xanchor="center", + x=0.5 + ), + height=600, + ) + + # Exports + if export: + export_dir = os.path.join( + geoprob_pipe.visualizations.graphs.export_dir, + "grafiek_physical_values" + ) + os.makedirs(export_dir, exist_ok=True) + + # Export interactive HTML + fig.write_html( + os.path.join(export_dir, "phreatic_waterline.html"), include_plotlyjs='cdn') + + # Export one PNG per scenario_order + for scen_order in scenario_orders: + df_case = df[df["scenario_order"] == scen_order] + fig_case = go.Figure() + for variable in ["buitenwaterstand", "phi_exit", + "h_exit", "top_zand"]: + df_var = df_case[df_case["variable"] == variable] + fig_case.add_trace(go.Scatter( + x=df_var["metrering"], + y=df_var["physical_value"], + mode="markers", + name=names[variable], + marker=dict( + color=colors[variable], + symbol=symbols[variable], + size=5 + ) + )) + fig_case.update_layout( + title=f"Phreatic waterline for Scenario {scen_order}", + xaxis_title="Metrering", + yaxis_title="Hoogte [m+NAP]", + showlegend=True, + ) + + return fig diff --git a/geoprob_pipe/visualizations/graphs/physical_values_along_levee.py b/geoprob_pipe/visualizations/graphs/physical_values_along_levee.py new file mode 100644 index 00000000..976752de --- /dev/null +++ b/geoprob_pipe/visualizations/graphs/physical_values_along_levee.py @@ -0,0 +1,60 @@ +from __future__ import annotations +from typing import TYPE_CHECKING +from plotly.graph_objects import Figure, Scatter +import os +from pandas import merge +if TYPE_CHECKING: + from geoprob_pipe import GeoProbPipe + + +def physical_values_buitenwaterstand_and_top_zand(geoprob_pipe: GeoProbPipe, export: bool = False) -> Figure: + + # Get data for graphing + df = geoprob_pipe.results.df_alphas_influence_factors_and_physical_values( + system_only=True, filter_deterministic=False, filter_derived=True) + df = df[["uittredepunt_id", "ondergrondscenario_id", "vak_id", "variable", "distribution_type", "physical_value"]] + + # Attach measure + gdf_uittredepunten = geoprob_pipe.input_data.uittredepunten.gdf + df = merge( + left=df, + right=gdf_uittredepunten[["uittredepunt_id", "metrering"]], + on="uittredepunt_id", + how="left") + + fig = Figure() + + df_filtered = df[df['variable'] == "buitenwaterstand"] + fig.add_trace( + Scatter( + x=df_filtered['metrering'], + y=df_filtered["physical_value"], + name="Buitenwaterstand", + mode='markers', + marker=dict(symbol='circle', size=5, color='blue'))) + df_filtered = df[df['variable'] == "top_zand"] + fig.add_trace( + Scatter( + x=df_filtered['metrering'], + y=df_filtered["physical_value"], + mode='markers', + name="Top zand", + marker=dict(symbol='circle', size=5, color='brown'))) + + fig.update_layout( + xaxis=dict( + title=f"Metrering", type='linear', range=[df['metrering'].min()-10, df['metrering'].max()+10], + showgrid=True, gridwidth=0.5, gridcolor="gray"), + yaxis=dict( + title=f"Buitenwaterstand en top zand [m+NAP]", showgrid=True, gridwidth=0.5, gridcolor="gray", + minor=dict(showgrid=True, dtick=1)) + ) + + if export: + export_dir = geoprob_pipe.visualizations.graphs.export_dir + os.makedirs(export_dir, exist_ok=True) + fig.write_html( + os.path.join(export_dir, f"physical_values_buitenwaterstand_and_top_zand.html"), + include_plotlyjs='cdn') + + return fig diff --git a/geoprob_pipe/visualizations/graphs/river_waterlevel.py b/geoprob_pipe/visualizations/graphs/river_waterlevel.py new file mode 100644 index 00000000..ad96adc1 --- /dev/null +++ b/geoprob_pipe/visualizations/graphs/river_waterlevel.py @@ -0,0 +1,185 @@ +from __future__ import annotations +import os +import numpy as np +import pandas as pd +import plotly.colors as pc +from plotly.graph_objects import Figure, Scatter +from typing import TYPE_CHECKING + +from geoprob_pipe.cmd_app.parameter_input.expand_input_tables import run_expand_input_tables + +if TYPE_CHECKING: + from geoprob_pipe import GeoProbPipe + + +def river_waterlevel(geoprob_pipe: GeoProbPipe, export: bool = False): + # Prepare base data + df = geoprob_pipe.results.df_alphas_influence_factors_and_physical_values( + system_only=True, filter_deterministic=False, filter_derived=False + ) + + df = df[[ + "uittredepunt_id", "ondergrondscenario_id", "vak_id", + "variable", "distribution_type", "physical_value" + ]] + + gdf_uittredepunten = geoprob_pipe.input_data.uittredepunten.gdf + df = df.merge( + gdf_uittredepunten[["uittredepunt_id", "metrering", "hrd_name"]], + on="uittredepunt_id", how="left" + ) + df_beta = geoprob_pipe.results.df_beta_uittredepunten + + # Target exceedance frequencies + target_freqs = np.array([ + 0.1, 0.033333333, 0.01, 0.003333333, + 0.001, 0.000333333, 0.0001, 3.33333E-05, + 0.00001, 3.33333E-06 + ]) + + # Blue gradient for lines + line_colors = pc.sample_colorscale( + "Jet", np.linspace(0.2, 0.9, len(target_freqs)) + ) + freq_color_map = {f: c for f, c in zip(target_freqs, line_colors)} + + # Figure + fig = Figure() + + # Prepare storage for Hydra curves per frequency + hydra_curves = {freq: {"metrering": [], "level": []} + for freq in target_freqs} + + # Add Hydra lines (grouped per frequency) + df_input: pd.DataFrame = run_expand_input_tables( + geoprob_pipe.input_data.app_settings.geopackage_filepath, + add_frag_ref=True) + df_input = df_input[df_input["parameter_name"] == "buitenwaterstand"] + df_input = pd.concat( + [df_input.drop(columns=['parameter_input']), + df_input['parameter_input'].apply(pd.Series)], axis=1) + + for _, row in df_input.iterrows(): + if row["distribution_type"] != "deterministic": + df_subset = gdf_uittredepunten[ + gdf_uittredepunten["vak_id"] == row["vak_id"] + ] + if df_subset.empty: + continue + + m_values = df_subset["metrering"].to_numpy() + + # Hydra exceedance curve + freqs = np.array( + [fv.probability_of_failure for fv in row.loc["fragility_values"]], + dtype=float + ) + levels = np.array( + [fv.x for fv in row.loc["fragility_values"]], + dtype=float + ) + + # Sort for interpolation + sort_idx = np.argsort(freqs) + freqs = freqs[sort_idx] + levels = levels[sort_idx] + + # Interpolate levels for standard frequencies + interp_levels = np.interp(target_freqs, freqs, levels) + + # Store values for each frequency + for freq, level in zip(target_freqs, interp_levels): + hydra_curves[freq]["metrering"].extend(m_values) + hydra_curves[freq]["level"].extend(np.full_like(m_values, level)) + + # Plot one continuous line per exceedance frequency + + for freq, data in hydra_curves.items(): + # Sort by metrering for continuous line plotting + sort_idx = np.argsort(data["metrering"]) + m_sorted = np.array(data["metrering"])[sort_idx] + level_sorted = np.array(data["level"])[sort_idx] + + fig.add_trace( + Scatter( + x=m_sorted, + y=level_sorted, + mode="lines", + line=dict(color=freq_color_map[freq], width=2), + name=f"1/{1/freq:,.0f}".replace(",", "."), # mark thousands + showlegend=True, + ) + ) + + # Buitenwaterstand markers with β color scale + df_filtered = df[df["variable"] == "buitenwaterstand"].merge( + df_beta[["uittredepunt_id", "beta"]], + on="uittredepunt_id", how="left" + ) + + betas = df_filtered["beta"].to_numpy() + + # Green-to-red scale (low beta = red, high beta = green) + beta_colorscale = "RdYlGn" + fig.add_trace( + Scatter( + x=df_filtered["metrering"], + y=df_filtered["physical_value"], + mode="markers", + name="Physical values", + marker=dict( + symbol="circle", + size=7, + color=betas, + colorscale=beta_colorscale, + cmin=1, + cmax=10, + colorbar=dict( + title="β", + xanchor="right", + x=-0.05, # Make space on the left side for y-axis + ticks="outside", + ), + line=dict(width=0.5, color="black"), + ), + customdata=df_filtered[["beta"]], + hovertemplate=("metering: %{x}
" + + "buitenwaterstand: %{y:.2f}
" + + "beta: %{customdata:.3f}"), + showlegend=True + ) + ) + + # Layout + fig.update_layout( + title="Buitenwaterstanden bij herhaaltijd en physical values uit system design points", + xaxis=dict(title="Metrering [m]", showgrid=True, + gridwidth=0.5, gridcolor="gray"), + yaxis=dict(title="Buitenwaterstand [m+NAP]", showgrid=True, + gridwidth=0.5, gridcolor="gray"), + legend=dict( + orientation="v", + yanchor="middle", + y=0.5, + xanchor="left", + x=1.02, + title="Legenda", + bgcolor="rgba(255,255,255,0.7)", + ), + legend_traceorder="reversed", + height=600, + margin=dict(r=200), + ) + + # Export + if export: + export_dir = os.path.join( + geoprob_pipe.visualizations.graphs.export_dir, + "grafiek_physical_values" + ) + os.makedirs(export_dir, exist_ok=True) + + fig.write_html(os.path.join(export_dir, "river_waterlevel.html"), + include_plotlyjs='cdn') + + return fig diff --git a/geoprob_pipe/visualizations/maps/__init__.py b/geoprob_pipe/visualizations/maps/__init__.py new file mode 100644 index 00000000..b53af286 --- /dev/null +++ b/geoprob_pipe/visualizations/maps/__init__.py @@ -0,0 +1,29 @@ +from __future__ import annotations +from typing import TYPE_CHECKING +import os +from plotly.graph_objects import Figure as PlotlyFigure + +from geoprob_pipe.visualizations.maps.betamap import BetaMap + + +if TYPE_CHECKING: + from geoprob_pipe import GeoProbPipe + + +class Maps: + + def __init__(self, app_obj: GeoProbPipe): + self.geoprob_pipe = app_obj + + @property + def export_dir(self) -> str: + path = os.path.join(self.geoprob_pipe.visualizations.export_dir, "maps") + os.makedirs(path, exist_ok=True) + return path + + def betamap(self, export: bool = False) -> PlotlyFigure: + map_figure = BetaMap(self.geoprob_pipe, export=export) + return map_figure.fig + + def export_maps(self): + BetaMap(self.geoprob_pipe, export=True) diff --git a/geoprob_pipe/visualizations/maps/betamap.py b/geoprob_pipe/visualizations/maps/betamap.py new file mode 100644 index 00000000..5ab11f28 --- /dev/null +++ b/geoprob_pipe/visualizations/maps/betamap.py @@ -0,0 +1,262 @@ +from __future__ import annotations +from typing import TYPE_CHECKING +import plotly.graph_objects as go +import os +import geopandas as gpd +from shapely.geometry import LineString, MultiLineString, GeometryCollection + +if TYPE_CHECKING: + from geoprob_pipe import GeoProbPipe + + +def _add_line(geoprob_pipe: GeoProbPipe, fig: go.Figure, + layer: str, color: str): + """ Helperfunctie om de lijnen uit de geopackage te vinden en toe te voegen aan de map. Layer is de naam van de + laag in de geopackage waar de lijn is opgeslagen. Color is de kleur van deze lijn in de map. """ + + gdf_traject = gpd.read_file( + geoprob_pipe.input_data.app_settings.geopackage_filepath, + layer=layer) + gdf_traject = gdf_traject.to_crs("EPSG:4326") + + def plot_linestring(ls, display): + xs, ys = ls.xy + xs = list(xs) + ys = list(ys) + fig.add_trace(go.Scattermap( + lon=xs, + lat=ys, + mode="lines", + line=dict(color=color, width=1), + hoverinfo="none", + name=layer, + legendgroup=layer, + showlegend=display + )) + + show = True + for geom in gdf_traject.geometry: + if isinstance(geom, LineString): + plot_linestring(geom, show) + show = False + + elif isinstance(geom, MultiLineString): + for line in geom.geoms: + plot_linestring(line, show) + show = False + + elif isinstance(geom, GeometryCollection): + for g in geom.geoms: + if isinstance(g, LineString): + plot_linestring(g, show) + show = False + elif isinstance(g, MultiLineString): + for line in g.geoms: + plot_linestring(line, show) + show = False + + else: + print("Skipping unsupported geometry:", geom.geom_type) + + return fig + + +class BetaMap: + + def __init__(self, geoprob_pipe: GeoProbPipe, export: bool = False): + + self.geoprob_pipe = geoprob_pipe + self.export = export + + # Logic + self._import_results() + self._setup_gdf() + self._determine_zoom() + self._create_figure() + self._add_lines() + self._optionally_export() + + def _import_results(self): + # results import + self.inp_point = self.geoprob_pipe.input_data.uittredepunten.gdf + self.res_sc = self.geoprob_pipe.results.df_beta_scenarios + mask = self.inp_point["uittredepunt_id"].isin(self.res_sc["uittredepunt_id"]) + self.inp_point = self.inp_point[mask] + + # Setup of beta category limits + self.cg = (self.geoprob_pipe.input_data.traject_normering + .riskeer_categorie_grenzen) + self.colors = ["rgb(30,141,41)", "rgb(146,206,90)", + "rgb(198,226,176)", "rgb(255,255,0)", + "rgb(254,165,3)", "rgb(255,0,0)", + "rgb(177,33,38)"] + self.labels = ["+III", "+II", "+I", "0", "-I", "-II", "-III"] + + self.len_cg = self.cg[self.labels[0]][1] - self.cg[self.labels[6]][0] + + self.color1 = ((self.cg[self.labels[0]][1] + - self.cg[self.labels[6]][0]) / self.len_cg) + self.color2 = ((self.cg[self.labels[1]][1] + - self.cg[self.labels[6]][0]) / self.len_cg) + self.color3 = ((self.cg[self.labels[2]][1] + - self.cg[self.labels[6]][0]) / self.len_cg) + self.color4 = ((self.cg[self.labels[3]][1] + - self.cg[self.labels[6]][0]) / self.len_cg) + self.color5 = ((self.cg[self.labels[4]][1] + - self.cg[self.labels[6]][0]) / self.len_cg) + self.color6 = ((self.cg[self.labels[5]][1] + - self.cg[self.labels[6]][0]) / self.len_cg) + self.color7 = ((self.cg[self.labels[6]][1] + - self.cg[self.labels[6]][0]) / self.len_cg) + self.color8 = ((self.cg[self.labels[6]][0] + - self.cg[self.labels[6]][0]) / self.len_cg) + + def _setup_gdf(self): + self.hoverdata = ["uittredepunt_id", "converged", "beta", "model_betas"] + + self.df = self.res_sc.merge(self.inp_point, on="uittredepunt_id", + how="inner") + idx = self.df.groupby(["uittredepunt_id"])["beta"].idxmin() + self.df = self.df.loc[idx] + + self.gdf = gpd.GeoDataFrame( + self.df, geometry=gpd.points_from_xy( + self.inp_point.geometry.x, self.inp_point.geometry.y + ), + crs="EPSG:28992") + # Transformeer naar WGS84 (latitude / longitude) + self.gdf_latlon = self.gdf.to_crs("EPSG:4326") + + def _determine_zoom(self): + self.center_lat = self.gdf_latlon.geometry.y.mean() + self.center_lon = self.gdf_latlon.geometry.x.mean() + self.min_lat = self.gdf_latlon.geometry.y.min() + self.max_lat = self.gdf_latlon.geometry.y.max() + self.min_lon = self.gdf_latlon.geometry.x.min() + self.max_lon = self.gdf_latlon.geometry.x.max() + + def _calculate_zoom(lat_range, lon_range): + max_range = max(lat_range, lon_range) + if max_range < 0.01: + return 15 + elif max_range < 0.05: + return 13 + elif max_range < 0.1: + return 12 + elif max_range < 0.5: + return 10 + elif max_range < 1.0: + return 9 + else: + return 8 + + self.lat_range = self.max_lat - self.min_lat + self.lon_range = self.max_lon - self.min_lon + self.zoom = _calculate_zoom(self.lat_range, self.lon_range) + + def _create_figure(self): + self.fig = go.Figure() + self.fig.add_trace(go.Scattermap( + mode="markers", + lat=self.gdf_latlon.geometry.y, + lon=self.gdf_latlon.geometry.x, + marker=dict( + size=9, + color="black" + ), + showlegend=False + )) + self.fig.add_trace(go.Scattermap( + mode='markers', + lat=self.gdf_latlon.geometry.y, # direct uit geometrie + lon=self.gdf_latlon.geometry.x, # direct uit geometrie + marker=dict( + size=8, + color=self.gdf_latlon['beta'], + colorscale=[ + (self.color8, self.colors[6]), + (self.color7, self.colors[6]), + (self.color7, self.colors[5]), + (self.color6, self.colors[5]), + (self.color6, self.colors[4]), + (self.color5, self.colors[4]), + (self.color5, self.colors[3]), + (self.color4, self.colors[3]), + (self.color4, self.colors[2]), + (self.color3, self.colors[2]), + (self.color3, self.colors[1]), + (self.color2, self.colors[1]), + (self.color2, self.colors[0]), + (self.color1, self.colors[0]) + ], + cmin=self.cg[self.labels[6]][0], + cmax=self.cg[self.labels[0]][1], + colorbar=dict( + title="Bèta, WBI cat.", + tickvals=[ + self.cg[self.labels[6]][0], + self.cg[self.labels[6]][1], + self.cg[self.labels[5]][1], + self.cg[self.labels[4]][1], + self.cg[self.labels[3]][1], + self.cg[self.labels[2]][1], + self.cg[self.labels[1]][1], + self.cg[self.labels[0]][1] + ], + ticktext=[f"{v:.2f}" for v in [ + self.cg[self.labels[6]][0], + self.cg[self.labels[6]][1], + self.cg[self.labels[5]][1], + self.cg[self.labels[4]][1], + self.cg[self.labels[3]][1], + self.cg[self.labels[2]][1], + self.cg[self.labels[1]][1], + self.cg[self.labels[0]][1]]], + ) + ), + hoverinfo='text', + text=self.gdf_latlon[self.hoverdata].apply( + lambda row: '
'.join( + [f"{col}: {row[col]}" for col in self.hoverdata] + ), + axis=1), + showlegend=False + )) + + # Layout + self.fig.update_layout( + map_style="open-street-map", + # carto-positron, open-street-map, satellite-streets + map_zoom=self.zoom, + map_center=dict( + lat=self.gdf_latlon.geometry.y.mean(), + lon=self.gdf_latlon.geometry.x.mean() + ), + legend=dict( + orientation="h", + yanchor="bottom", + y=1.02, + xanchor="right", + x=1 + ), + dragmode='zoom', + title='Faalkansberekening STPH' + ) + + def _add_lines(self): + self.fig = _add_line(self.geoprob_pipe, self.fig, + "dijktraject", "black") + self.fig = _add_line(self.geoprob_pipe, self.fig, + "intredelijn", "blue") + self.fig = _add_line(self.geoprob_pipe, self.fig, + "binnenteenlijn", "purple") + self.fig = _add_line(self.geoprob_pipe, self.fig, + "buitenteenlijn", "red") + + def _optionally_export(self): + if self.export: + path = self.geoprob_pipe.visualizations.maps.export_dir + self.fig.write_html(os.path.join( + path, 'Faalkansberekening STPH.html'), include_plotlyjs='cdn') + # self.fig.write_image(os.path.join( + # path, 'Faalkansberekening STPH.png'), format='png') diff --git a/geoprob_pipe/visualizations/other/__init__.py b/geoprob_pipe/visualizations/other/__init__.py new file mode 100644 index 00000000..8a3cd0b0 --- /dev/null +++ b/geoprob_pipe/visualizations/other/__init__.py @@ -0,0 +1,29 @@ +from __future__ import annotations +from typing import TYPE_CHECKING +from pandas import DataFrame +from geoprob_pipe.visualizations.other.overview.generate_flow_chart_v2 import generate_overview_flow_chart_with_betas +import os +if TYPE_CHECKING: + from geoprob_pipe import GeoProbPipe + + +class Other: + + def __init__(self, app_obj: GeoProbPipe): + self.geoprob_pipe = app_obj + + @property + def export_dir(self) -> str: + path = os.path.join(self.geoprob_pipe.visualizations.export_dir, "visualizations") + os.makedirs(path, exist_ok=True) + return path + + def export_visualizations(self): + df = self.geoprob_pipe.results.df_beta_scenarios + lowest_beta_row: DataFrame = df.loc[df['beta'].idxmin()] + generate_overview_flow_chart_with_betas( + app_obj=self.geoprob_pipe, + export_dir=self.export_dir, + ondergrondscenario_id=lowest_beta_row['ondergrondscenario_id'], + uittredepunt_id=lowest_beta_row['uittredepunt_id'] + ) diff --git a/geoprob_pipe/visualizations/other/overview/Hierarchie_berekeningen_incl_result_tags.graphml b/geoprob_pipe/visualizations/other/overview/Hierarchie_berekeningen_incl_result_tags.graphml new file mode 100644 index 00000000..09927c18 --- /dev/null +++ b/geoprob_pipe/visualizations/other/overview/Hierarchie_berekeningen_incl_result_tags.graphml @@ -0,0 +1,1539 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Gecombineerd +vak + + + + + + + + + + + Uplift + + + + + + + + + + + Heave + + + + + + + + + + + Piping + + + + + + + + + + + Gecombineerd +scenario + + + + + + + + + + + Gecombineerd +Uittredepunt + + + + + + + + + + + Gecombineerd +andere scenario's + + + + + + + + + + + Uitredepunt + + + + + + + + + + + Gecombineerd +andere uittredepunten + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Gecombineerd +andere vakken + + + + + + + + + + + Gecombineerd +traject + + + + + + + + + + + Vak + + + + + + + + + + + 20 laagst scorende andere uittredepunten + + + + + + + + + + + 20 laagst scorende andere vakken + + + + + + + + + + + Traject + + + + + + + + + + + Uplift + + + + + + + + + + + Heave + + + + + + + + + + + Piping + + + + + + + + + + + FORM + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Gecombineerd +Scenario 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Gecombineerd +Uittredepunt 1 + + + + + + + + + + + Beta volgt uit sommatie van scenario +kansen maal de faalkans + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Importance Sampling o.b.v. +Design Points FORM + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Gecombineerd +Vak 1 + + + + + + + + + + + Beta volgt uit meest +ongunstige uittredepunt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Gecombineerd +Traject + + + + + + + + + + + Beta volgt uit meest +ongunstige vak + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Bepaling Beta's en Alpha's + + + + + + + + + + + {{ uittredepunt.1.beta }} + + + + + + + + + + + {{ scenario.1.beta }} + + + + + + + + + + + {{ scenario.6.beta }} + + + + + + + + + + + {{ scenario.7.beta }} + + + + + + + + + + + {{ piping.beta }} + + + + + + + + + + + {{ heave.beta }} + + + + + + + + + + + {{ uplift.beta }} + + + + + + + + + + + {{ uittredepunt.2.beta }} + + + + + + + + + + + {{ uittredepunt.3.beta }} + + + + + + + + + + + {{ vak.1.beta }} + + + + + + + + + + + {{ scenario.8.beta }} + + + + + + + + + + + {{ scenario.9.beta }} + + + + + + + + + + + {{ scenario.10.beta }} + + + + + + + + + + + {{ scenario.11.beta }} + + + + + + + + + + + {{ scenario.12.beta }} + + + + + + + + + + + {{ scenario.2.beta }} + + + + + + + + + + + {{ scenario.3.beta }} + + + + + + + + + + + {{ scenario.4.beta }} + + + + + + + + + + + {{ scenario.5.beta }} + + + + + + + + + + + {{ scenario.14.beta }} + + + + + + + + + + + {{ scenario.15.beta }} + + + + + + + + + + + {{ scenario.16.beta }} + + + + + + + + + + + {{ scenario.17.beta }} + + + + + + + + + + + {{ scenario.18.beta }} + + + + + + + + + + + {{ scenario.19.beta }} + + + + + + + + + + + {{ scenario.20.beta }} + + + + + + + + + + + {{ scenario.13.beta }} + + + + + + + + + + + {{ uittredepunt.4.beta }} + + + + + + + + + + + {{ uittredepunt.5.beta }} + + + + + + + + + + + {{ uittredepunt.6.beta }} + + + + + + + + + + + {{ uittredepunt.7.beta }} + + + + + + + + + + + {{ uittredepunt.8.beta }} + + + + + + + + + + + {{ uittredepunt.9.beta }} + + + + + + + + + + + {{ uittredepunt.10.beta }} + + + + + + + + + + + {{ uittredepunt.11.beta }} + + + + + + + + + + + {{ uittredepunt.12.beta }} + + + + + + + + + + + {{ uittredepunt.13.beta }} + + + + + + + + + + + {{ uittredepunt.14.beta }} + + + + + + + + + + + {{ uittredepunt.15.beta }} + + + + + + + + + + + {{ uittredepunt.16.beta }} + + + + + + + + + + + {{ uittredepunt.17.beta }} + + + + + + + + + + + {{ uittredepunt.18.beta }} + + + + + + + + + + + {{ uittredepunt.19.beta }} + + + + + + + + + + + {{ uittredepunt.20.beta }} + + + + + + + + + + + {{ vak.2.beta }} + + + + + + + + + + + {{ vak.3.beta }} + + + + + + + + + + + {{ vak.4.beta }} + + + + + + + + + + + {{ vak.8.beta }} + + + + + + + + + + + {{ vak.9.beta }} + + + + + + + + + + + {{ vak.10.beta }} + + + + + + + + + + + {{ vak.11.beta }} + + + + + + + + + + + {{ vak.12.beta }} + + + + + + + + + + + {{ vak.13.beta }} + + + + + + + + + + + {{ vak.14.beta }} + + + + + + + + + + + {{ vak.15.beta }} + + + + + + + + + + + {{ vak.16.beta }} + + + + + + + + + + + {{ vak.5.beta }} + + + + + + + + + + + {{ vak.6.beta }} + + + + + + + + + + + {{ vak.7.beta }} + + + + + + + + + + + {{ vak.17.beta }} + + + + + + + + + + + {{ vak.18.beta }} + + + + + + + + + + + {{ vak.19.beta }} + + + + + + + + + + + {{ vak.20.beta }} + + + + + + + + + + + {{ vak.21.beta }} + + + + + + + + + + + {{ uittredepunt.21.beta }} + + + + + + + + + + + traject.beta }} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/geoprob_pipe/visualizations/other/overview/Hierarchie_berekeningen_incl_result_tags.svg b/geoprob_pipe/visualizations/other/overview/Hierarchie_berekeningen_incl_result_tags.svg new file mode 100644 index 00000000..9270dce8 --- /dev/null +++ b/geoprob_pipe/visualizations/other/overview/Hierarchie_berekeningen_incl_result_tags.svg @@ -0,0 +1,456 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Gecombineerd + Vak 1 + + + + + + + + + Uplift + + + + + + + + + Heave + + + + + + + + + Piping + + + + + + + Gecombineerd + Scenario 1 + + + + + + + Gecombineerd + Uittredepunt 1 + + + + + + + Gecombineerd + Scenario N + Uitredepunt 1 + + + + + + + + + + + + + Gecombineerd + Uittredepunt N + + + + + + + Gecombineerd + Vak 2 + + + + + + + + + + + + + Gecombineerd + Vak N + + + + + + + Gecombineerd + Traject + Vak 1 + Uitredepunt N + Vak 2 + Vak N + Traject + + + + + + + + + Uplift + + + + + + + + + Heave + + + + + + + + + Piping + + + FORM + + + + + + + Gecombineerd + Scenario 1 + + + + + + + Gecombineerd + Uittredepunt 1 + Beta volgt uit sommatie van scenario + kansen maal de faalkans + Alpha's volgen uit meest + ongunstige scenario + Importance Sampling o.b.v. + Design Points FORM + Huidig issue: + Bijbehorende Alpha's zijn + niet gelijk aan 1.00 + + + + + + + Gecombineerd + Vak 1 + Beta volgt uit meest + ongunstige uittredepunt + Alpha's volgen uit meest + ongunstige uittredepunt + + + + + + + Gecombineerd + Traject + Beta volgt uit meest + ongunstige vak + Alpha's volgen uit meest + ongunstige vak + Bepaling Beta's en Alpha's + + + + + + + 6.23 + + + + + + + {{ scenarios.1.beta }} + + + + + + + 6.23 + + + + + + + 6.23 + + + + + + + {{ piping.beta }} + + + + + + + {{ heave.beta }} + + + + + + + {{ uplift.beta }} + + + + + + + 6.23 + + + + + + + 6.23 + + + + + + + {{COMB.VAK.FOCUS}} + + + + + + + 6.23 + + + + + + + {{ vakken. }} + + + + + + + 6.23 + + + + + + + 6.23 + + + + + + + 6.23 + + + + + + + 6.23 + + + + + + + 6.23 + + + + + + + 6.23 + + + + + + + 6.23 + + + + + + + 6.23 + + + + + + + 6.23 + + + + + + + 6.23 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/geoprob_pipe/visualizations/other/overview/Hierarchie_berekeningen_incl_result_tags_v2.svg b/geoprob_pipe/visualizations/other/overview/Hierarchie_berekeningen_incl_result_tags_v2.svg new file mode 100644 index 00000000..0c57d419 --- /dev/null +++ b/geoprob_pipe/visualizations/other/overview/Hierarchie_berekeningen_incl_result_tags_v2.svg @@ -0,0 +1,728 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Gecombineerd + vak + + + + + + + + + Uplift + + + + + + + + + Heave + + + + + + + + + Piping + + + + + + + Gecombineerd + scenario + + + + + + + Gecombineerd + Uittredepunt + + + + + + + Gecombineerd + andere scenario's + Uitredepunt + + + + + + + Gecombineerd + andere uittredepunten + + + + + + + + + + + + + Gecombineerd + andere vakken + + + + + + + Gecombineerd + traject + Vak + 20 laagst scorende andere uittredepunten + 20 laagst scorende andere vakken + Traject + + + + + + + + + Uplift + + + + + + + + + Heave + + + + + + + + + Piping + + + FORM + + + + + + + Gecombineerd + Scenario 1 + + + + + + + Gecombineerd + Uittredepunt 1 + Beta volgt uit sommatie van scenario + kansen maal de faalkans + Importance Sampling o.b.v. + Design Points FORM + + + + + + + Gecombineerd + Vak 1 + Beta volgt uit meest + ongunstige uittredepunt + + + + + + + Gecombineerd + Traject + Beta volgt uit meest + ongunstige vak + Bepaling Beta's en Alpha's + + + + + + + {{ uittredepunt.1.beta }} + + + + + + + {{ scenario.1.beta }} + + + + + + + {{ scenario.99.beta }} + + + + + + + {{ scenario.7.beta }} + + + + + + + {{ piping.beta }} + + + + + + + {{ heave.beta }} + + + + + + + {{ uplift.beta }} + + + + + + + {{ uittredepunt.2.beta }} + + + + + + + {{ uittredepunt.3.beta }} + + + + + + + {{ vak.1.beta }} + + + + + + + {{ scenario.99.beta }} + + + + + + + {{ scenario.9.beta }} + + + + + + + {{ scenario.99.beta }} + + + + + + + {{ scenario.5.beta }} + + + + + + + {{ scenario.4.beta }} + + + + + + + {{ scenario.99.beta }} + + + + + + + {{ scenario.99.beta }} + + + + + + + {{ scenario.3.beta }} + + + + + + + {{ scenario.2.beta }} + + + + + + + {{ scenario.14.beta }} + + + + + + + {{ scenario.15.beta }} + + + + + + + {{ scenario.16.beta }} + + + + + + + {{ scenario.17.beta }} + + + + + + + {{ scenario.18.beta }} + + + + + + + {{ scenario.19.beta }} + + + + + + + {{ scenario.20.beta }} + + + + + + + {{ scenario.13.beta }} + + + + + + + {{ uittredepunt.4.beta }} + + + + + + + {{ uittredepunt.5.beta }} + + + + + + + {{ uittredepunt.6.beta }} + + + + + + + {{ uittredepunt.7.beta }} + + + + + + + {{ uittredepunt.8.beta }} + + + + + + + {{ uittredepunt.9.beta }} + + + + + + + {{ uittredepunt.10.beta }} + + + + + + + {{ uittredepunt.11.beta }} + + + + + + + {{ uittredepunt.12.beta }} + + + + + + + {{ uittredepunt.13.beta }} + + + + + + + {{ uittredepunt.14.beta }} + + + + + + + {{ uittredepunt.15.beta }} + + + + + + + {{ uittredepunt.16.beta }} + + + + + + + {{ uittredepunt.17.beta }} + + + + + + + {{ uittredepunt.18.beta }} + + + + + + + {{ uittredepunt.19.beta }} + + + + + + + {{ uittredepunt.20.beta }} + + + + + + + {{ vak.2.beta }} + + + + + + + {{ vak.3.beta }} + + + + + + + {{ vak.4.beta }} + + + + + + + {{ vak.8.beta }} + + + + + + + {{ vak.9.beta }} + + + + + + + {{ vak.10.beta }} + + + + + + + {{ vak.11.beta }} + + + + + + + {{ vak.12.beta }} + + + + + + + {{ vak.13.beta }} + + + + + + + {{ vak.14.beta }} + + + + + + + {{ vak.15.beta }} + + + + + + + {{ vak.16.beta }} + + + + + + + {{ vak.5.beta }} + + + + + + + {{ vak.6.beta }} + + + + + + + {{ vak.7.beta }} + + + + + + + {{ vak.17.beta }} + + + + + + + {{ vak.18.beta }} + + + + + + + {{ vak.19.beta }} + + + + + + + {{ vak.20.beta }} + + + + + + + {{ vak.21.beta }} + + + + + + + {{ uittredepunt.21.beta }} + + + + + + + traject.beta }} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/geoprob_pipe/visualizations/other/overview/__init__.py b/geoprob_pipe/visualizations/other/overview/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/geoprob_pipe/visualizations/other/overview/generate_flow_chart.py b/geoprob_pipe/visualizations/other/overview/generate_flow_chart.py new file mode 100644 index 00000000..499544da --- /dev/null +++ b/geoprob_pipe/visualizations/other/overview/generate_flow_chart.py @@ -0,0 +1,188 @@ +# import os +# import random +# from typing import Union, Literal +# import sys +# +# # rgb(153,204,0) +# +# +# # class Tags: +# # +# # def __init__(self, main_tag: str): +# # self.main_tag: str = main_tag +# # +# # @property +# # def beta(self): +# # return +# # +# +# +# +# +# class VisualizeInfo: +# +# def __init__(self, main_tag: str, beta: Union[float, int, str] = "n.b.", visible: bool = False): +# self.main_tag: str = main_tag +# self.beta: Union[float, int, str] = beta +# self.visible: bool = visible +# +# @property +# def svg_color(self) -> str: +# """ Color value formatted for the SVG-file. """ +# if self.beta > 5.00: +# return "rgb(154,205,50)" # Green +# return "rgb(206,32,41)" # Red +# +# @property +# def svg_beta(self) -> str: +# """ Beta value formatted for the SVG-file. """ +# if isinstance(self.beta, float) or isinstance(self.beta, int): +# return f"{round(self.beta, 2):.2f}" +# return str(self.beta) +# +# @property +# def svg_visibility(self): +# """ Visibility value formatted for the SVG-file. """ +# if self.visible: +# return "visible" +# return "hidden" +# +# def svg_tag(self, option: Literal["beta", "color", "visibility"]) -> str: +# return f"{self.main_tag}.{option}" +# +# def svg_tag_incl_brackets(self, option: Literal["beta", "color", "visibility"]) -> str: +# return f"{{{{ {self.svg_tag(option=option)} }}}}" +# +# +# list_visualize_info = [ +# VisualizeInfo(main_tag=, beta=random.random() * 7 + 2, visible=True), +# ] +# +# dict_visualize_info = { +# "uplift": VisualizeInfo(main_tag="uplift", beta=random.random() * 7 + 2, visible=True), +# "heave": VisualizeInfo(main_tag="heave", beta=random.random() * 7 + 2, visible=True), +# "piping": VisualizeInfo(main_tag="piping", beta=random.random() * 7 + 2, visible=True), +# "scenarios.1": VisualizeInfo(main_tag="scenarios.1", beta=random.random() * 7 + 2, visible=True), +# "scenarios.2": VisualizeInfo(main_tag="scenarios.2", beta=random.random() * 7 + 2), +# } +# +# +# +# +# +# def generate_overview_flow_chart_with_betas(scenario, uittredepunt): +# """ Generates a flow chart that provides an overview what the beta values are per step in the calculation process. +# It displays it from the given scenario and uittredepunt, until vak- and traject-level. """ +# +# +# tags = { +# "uplift": VisualInfo(random.random() * 7 + 2, True), +# "heave": VisualInfo(random.random() * 7 + 2, True), +# "piping": VisualInfo(random.random() * 7 + 2, True), +# "scenarios": { +# 1: VisualInfo(random.random() * 7 + 2), +# 2: VisualInfo(random.random() * 7 + 2), +# 3: VisualInfo(random.random() * 7 + 2), +# 4: VisualInfo(random.random() * 7 + 2), +# 5: VisualInfo(random.random() * 7 + 2), +# 6: VisualInfo(random.random() * 7 + 2), +# 7: VisualInfo(random.random() * 7 + 2), +# }, +# "uittredepunten": { +# 1: VisualInfo(random.random() * 7 + 2), +# 2: VisualInfo(random.random() * 7 + 2), +# 3: VisualInfo(random.random() * 7 + 2), +# 4: VisualInfo(random.random() * 7 + 2), +# 5: VisualInfo(random.random() * 7 + 2), +# 6: VisualInfo(random.random() * 7 + 2), +# 7: VisualInfo(random.random() * 7 + 2), +# }, +# "vakken": { +# 1: VisualInfo(random.random() * 7 + 2), +# 2: VisualInfo(random.random() * 7 + 2), +# 3: VisualInfo(random.random() * 7 + 2), +# 4: VisualInfo(random.random() * 7 + 2), +# 5: VisualInfo(random.random() * 7 + 2), +# 6: VisualInfo(random.random() * 7 + 2), +# 7: VisualInfo(random.random() * 7 + 2), +# }, +# "traject": VisualInfo(random.random() * 7 + 2), +# +# } +# +# # Apply visual and value to each circle +# concatenated_tags = [] +# values_to_concatenated_tags = [] +# visibility_to_concatenated_tags = [] +# for key, value in tags.items(): +# +# print(f"{key=}, {value=}") +# +# +# # Determine tag .-string +# if isinstance(value, VisualInfo): +# tag_beta = f"{key}.beta" +# value_beta = value.beta +# tag_color = f"{key}.color" +# value_color = value.color +# +# concatenated_tags.append(tag_beta) +# values_to_concatenated_tags.append(value_beta) +# concatenated_tags.append(tag_color) +# values_to_concatenated_tags.append(value_color) +# +# elif isinstance(value, dict): +# # print(f"{concatenated_tags=}") +# # print(f"{values_to_concatenated_tags=}") +# # sys.exit() +# for key2, value2 in value.items(): +# # print(f"{key2=}, {value2=}") +# value2: VisualInfo +# tag_beta = f"{key}.{key2}.beta" +# # print(f"{value2=}") +# value_beta = value2.beta +# tag_color = f"{key}.{key2}.color" +# value_color = value2.color +# +# concatenated_tags.append(tag_beta) +# values_to_concatenated_tags.append(value_beta) +# concatenated_tags.append(tag_color) +# values_to_concatenated_tags.append(value_color) +# +# else: +# raise ValueError +# +# # Read template +# svg_text = None +# with open(r"C:\Users\CP\git_clones\GeoProb-Pipe\GeoProb-PipeV2\GeoProb-Pipe\geoprob_pipe\graphs\overview\Hierarchie_berekeningen_incl_result_tags.svg", +# "r", encoding="utf-8") as f: +# svg_text = f.read() +# if svg_text is None: +# raise ValueError +# +# # Replace tags +# for tag, value in zip(concatenated_tags, values_to_concatenated_tags): +# +# # Prepare tag to search +# tag_with_brackets = f"{{{{ {tag} }}}}" +# print(f"{tag_with_brackets=}", tag_with_brackets in svg_text) +# +# # Prepare value to add +# if isinstance(value, float) or isinstance(value, int): +# value_prepped = f"{round(value, 2):.2f}" +# else: +# value_prepped = str(value) +# +# # Add value and color +# svg_text = svg_text.replace(tag_with_brackets, value_prepped) +# +# # Save new svg +# print(f"{svg_text=}") +# export_dir = r"C:\Users\CP\git_clones\GeoProb-Pipe\GeoProb-PipeV2\exports" +# with open(os.path.join(export_dir, "updated5.svg"), "w", encoding="utf-8") as f: +# f.write(svg_text) +# +# return concatenated_tags, values_to_concatenated_tags +# +# +# generate_overview_flow_chart_with_betas(1, 2) diff --git a/geoprob_pipe/visualizations/other/overview/generate_flow_chart_v2.py b/geoprob_pipe/visualizations/other/overview/generate_flow_chart_v2.py new file mode 100644 index 00000000..88b26ded --- /dev/null +++ b/geoprob_pipe/visualizations/other/overview/generate_flow_chart_v2.py @@ -0,0 +1,194 @@ +from __future__ import annotations +import os +from typing import Union, Literal +from pandas import DataFrame, Series +from copy import deepcopy +# from geoprob_pipe.utils.other import repository_root_path +from typing import TYPE_CHECKING +if TYPE_CHECKING: + from geoprob_pipe import GeoProbPipe + + + +class VisualizeInfo: + + def __init__(self, main_tag: str, beta: Union[float, int, str] = "n.b.", visible: bool = False): + self.main_tag: str = main_tag + self.beta: Union[float, int, str] = beta + self.visible: bool = visible + + @property + def svg_color(self) -> str: + """ Color value formatted for the SVG-file. """ + if self.beta > 5.00: + return "rgb(154,205,50)" # Green + return "rgb(206,32,41)" # Red + + @property + def svg_beta(self) -> str: + """ Beta value formatted for the SVG-file. """ + if isinstance(self.beta, float) or isinstance(self.beta, int): + if self.beta >= 10.0: + return f"{round(self.beta, 1):.1f}" + return f"{round(self.beta, 2):.2f}" + return str(self.beta) + + @property + def svg_visibility(self): + """ Visibility value formatted for the SVG-file. """ + if self.visible: + return "visible" + return "hidden" + + def svg_tag(self, option: Literal["beta", "color", "visibility"]) -> str: + return f"{self.main_tag}.{option}" + + def svg_tag_incl_brackets(self, option: Literal["beta", "color", "visibility"]) -> str: + return f"{{{{ {self.svg_tag(option=option)} }}}}" + + +DICT_VISUALIZE_INFO = { + "uplift": VisualizeInfo(main_tag="uplift", beta=-1, visible=True), + "heave": VisualizeInfo(main_tag="heave", beta=-1, visible=True), + "piping": VisualizeInfo(main_tag="piping", beta=-1, visible=True), + "scenario.1": VisualizeInfo(main_tag="scenario.1", beta=-1), + "scenario.2": VisualizeInfo(main_tag="scenario.2", beta=-1), + "scenario.3": VisualizeInfo(main_tag="scenario.3", beta=-1), + "scenario.4": VisualizeInfo(main_tag="scenario.4", beta=-1), + "scenario.5": VisualizeInfo(main_tag="scenario.5", beta=-1), + "scenario.6": VisualizeInfo(main_tag="scenario.6", beta=-1), + "scenario.7": VisualizeInfo(main_tag="scenario.7", beta=-1), + "scenario.8": VisualizeInfo(main_tag="scenario.8", beta=-1), + "scenario.9": VisualizeInfo(main_tag="scenario.9", beta=-1), + "scenario.10": VisualizeInfo(main_tag="scenario.10", beta=-1), + "scenario.11": VisualizeInfo(main_tag="scenario.11", beta=-1), + "scenario.12": VisualizeInfo(main_tag="scenario.12", beta=-1), + "scenario.13": VisualizeInfo(main_tag="scenario.13", beta=-1), + "scenario.14": VisualizeInfo(main_tag="scenario.14", beta=-1), + "scenario.15": VisualizeInfo(main_tag="scenario.15", beta=-1), + "scenario.16": VisualizeInfo(main_tag="scenario.16", beta=-1), + "scenario.17": VisualizeInfo(main_tag="scenario.17", beta=-1), + "scenario.18": VisualizeInfo(main_tag="scenario.18", beta=-1), + "scenario.19": VisualizeInfo(main_tag="scenario.19", beta=-1), + "scenario.20": VisualizeInfo(main_tag="scenario.20", beta=-1), + "scenario.99": VisualizeInfo(main_tag="scenario.99", beta=-1), + "uittredepunt.1": VisualizeInfo(main_tag="uittredepunt.1", beta=-1), + "uittredepunt.2": VisualizeInfo(main_tag="uittredepunt.2", beta=-1), + "uittredepunt.3": VisualizeInfo(main_tag="uittredepunt.3", beta=-1), + "uittredepunt.4": VisualizeInfo(main_tag="uittredepunt.4", beta=-1), + "uittredepunt.5": VisualizeInfo(main_tag="uittredepunt.5", beta=-1), + "uittredepunt.6": VisualizeInfo(main_tag="uittredepunt.6", beta=-1), + "uittredepunt.7": VisualizeInfo(main_tag="uittredepunt.7", beta=-1), + "uittredepunt.8": VisualizeInfo(main_tag="uittredepunt.8", beta=-1), + "uittredepunt.9": VisualizeInfo(main_tag="uittredepunt.9", beta=-1), + "uittredepunt.10": VisualizeInfo(main_tag="uittredepunt.10", beta=-1), + "uittredepunt.11": VisualizeInfo(main_tag="uittredepunt.11", beta=-1), + "uittredepunt.12": VisualizeInfo(main_tag="uittredepunt.12", beta=-1), + "uittredepunt.13": VisualizeInfo(main_tag="uittredepunt.13", beta=-1), + "uittredepunt.14": VisualizeInfo(main_tag="uittredepunt.14", beta=-1), + "uittredepunt.15": VisualizeInfo(main_tag="uittredepunt.15", beta=-1), + "uittredepunt.16": VisualizeInfo(main_tag="uittredepunt.16", beta=-1), + "uittredepunt.17": VisualizeInfo(main_tag="uittredepunt.17", beta=-1), + "uittredepunt.18": VisualizeInfo(main_tag="uittredepunt.18", beta=-1), + "uittredepunt.19": VisualizeInfo(main_tag="uittredepunt.19", beta=-1), + "uittredepunt.20": VisualizeInfo(main_tag="uittredepunt.20", beta=-1), + "uittredepunt.21": VisualizeInfo(main_tag="uittredepunt.21", beta=-1), + "uittredepunt.99": VisualizeInfo(main_tag="uittredepunt.99", beta=-1), + "vak.1": VisualizeInfo(main_tag="vak.1", beta=-1), + "vak.2": VisualizeInfo(main_tag="vak.2", beta=-1), + "vak.3": VisualizeInfo(main_tag="vak.3", beta=-1), + "vak.4": VisualizeInfo(main_tag="vak.4", beta=-1), + "vak.5": VisualizeInfo(main_tag="vak.5", beta=-1), + "vak.6": VisualizeInfo(main_tag="vak.6", beta=-1), + "vak.7": VisualizeInfo(main_tag="vak.7", beta=-1), + "vak.8": VisualizeInfo(main_tag="vak.8", beta=-1), + "vak.9": VisualizeInfo(main_tag="vak.9", beta=-1), + "vak.10": VisualizeInfo(main_tag="vak.10", beta=-1), + "vak.11": VisualizeInfo(main_tag="vak.11", beta=-1), + "vak.12": VisualizeInfo(main_tag="vak.12", beta=-1), + "vak.13": VisualizeInfo(main_tag="vak.13", beta=-1), + "vak.14": VisualizeInfo(main_tag="vak.14", beta=-1), + "vak.15": VisualizeInfo(main_tag="vak.15", beta=-1), + "vak.16": VisualizeInfo(main_tag="vak.16", beta=-1), + "vak.17": VisualizeInfo(main_tag="vak.17", beta=-1), + "vak.18": VisualizeInfo(main_tag="vak.18", beta=-1), + "vak.19": VisualizeInfo(main_tag="vak.19", beta=-1), + "vak.20": VisualizeInfo(main_tag="vak.20", beta=-1), + "vak.21": VisualizeInfo(main_tag="vak.21", beta=-1), + "vak.99": VisualizeInfo(main_tag="vak.99", beta=-1), + "traject": VisualizeInfo(main_tag="traject", beta=-1), +} + + +def populate_visualize_dict(uittredepunt_id: int, ondergrondscenario_id: int, app_obj: GeoProbPipe): + + visualize_dict = deepcopy(DICT_VISUALIZE_INFO) + + # Populate uplift, heave and piping for focus scenario + df_filter_limit_states = app_obj.results.df_limit_states.copy(deep=True) + df_filter_limit_states: DataFrame = df_filter_limit_states[ + (df_filter_limit_states["uittredepunt_id"] == uittredepunt_id) & + (df_filter_limit_states["ondergrondscenario_id"] == ondergrondscenario_id) + ] + assert df_filter_limit_states.__len__() == 3 + for row in df_filter_limit_states.itertuples(index=False): + row: Series + visualize_dict[row.model].beta = row.beta + + # Populate scenarios results: other scenarios + df_filter_combined = app_obj.results.df_combined.copy(deep=True) + df_filter_combined: DataFrame = df_filter_combined[ + (df_filter_combined["uittredepunt_id"] == uittredepunt_id) & + (df_filter_combined["ondergrondscenario_id"] != ondergrondscenario_id) + ] + for index, row in enumerate(df_filter_combined.itertuples(index=False)): + row: Series + visualize_dict[f"scenario.{index+2}"].beta = row.beta + visualize_dict[f"scenario.{index+2}"].visible = True + + # Populate scenarios results: focus scenarios + df_filter_combined = app_obj.results.df_combined.copy(deep=True) + df_filter_combined: DataFrame = df_filter_combined[ + (df_filter_combined["uittredepunt_id"] == uittredepunt_id) & + (df_filter_combined["ondergrondscenario_id"] == ondergrondscenario_id) + ] + assert df_filter_combined.__len__() == 1 + for row in df_filter_combined.itertuples(index=False): + row: Series + visualize_dict["scenario.1"].beta = row.beta + visualize_dict["scenario.1"].visible = True + + # Populate vak + + return visualize_dict + + +def generate_overview_flow_chart_with_betas( + uittredepunt_id: int, ondergrondscenario_id: int, app_obj: GeoProbPipe, export_dir: str +): + """ Generates a flow chart that provides an overview what the beta values are per step in the calculation process. + It displays it from the given scenario and uittredepunt, until vak- and traject-level. """ + + dict_to_use = populate_visualize_dict( + uittredepunt_id=uittredepunt_id, ondergrondscenario_id=ondergrondscenario_id, app_obj=app_obj) + + # Read template + svg_text = None + # repo_root = repository_root_path() + path_to_svg = os.path.join( + repo_root, "geoprob_pipe", "graphs", "overview", "Hierarchie_berekeningen_incl_result_tags_v2.svg") + # TODO: Use 'import importlib.resources' for this + with open(path_to_svg, "r", encoding="utf-8") as f: + svg_text = f.read() + if svg_text is None: + raise ValueError + + # Replace tags + for main_tag, info in dict_to_use.items(): + svg_text = svg_text.replace(info.svg_tag_incl_brackets(option="beta"), info.svg_beta) + svg_text = svg_text.replace(info.svg_tag_incl_brackets(option="color"), info.svg_color) + svg_text = svg_text.replace(info.svg_tag_incl_brackets(option="visibility"), info.svg_visibility) + + # Save new svg + with open(os.path.join(export_dir, "results_overview_flow_chart.svg"), "w", encoding="utf-8") as f: + f.write(svg_text) diff --git a/geoprob_pipe/visualizations/utils.py b/geoprob_pipe/visualizations/utils.py new file mode 100644 index 00000000..e69de29b diff --git a/geoprob_pipe_example.ini b/geoprob_pipe_example.ini new file mode 100644 index 00000000..09875049 --- /dev/null +++ b/geoprob_pipe_example.ini @@ -0,0 +1 @@ +PATH_WORKSPACE = C:\Users\Username\path\to\workspaces\example_new_calculations diff --git a/main_comparison_vsc.py b/main_comparison_vsc.py new file mode 100644 index 00000000..1c73aa25 --- /dev/null +++ b/main_comparison_vsc.py @@ -0,0 +1,21 @@ +from geoprob_pipe.cmd_app.comparisons import ComparisonCollector +import time + +filepath1 = r"C:\Users\vinji\Python\GEOprob-Pipe\Bestandenuitwisseling\Analyse16-1_V5.geoprob_pipe\Analyse16-1_V5.geoprob_pipe.gpkg" +filepath2 = r"C:\Users\vinji\Python\GEOprob-Pipe\Bestandenuitwisseling\Analyse16-1_V5.geoprob_pipe\Analyse16-1_V5alt.geoprob_pipe.gpkg" +export_dir = r"C:\Users\vinji\Python\GEOprob-Pipe\Bestandenuitwisseling\Analyse16-1_V5.geoprob_pipe" + +comparison = ComparisonCollector(filepath1, + filepath2, + export_dir) +start_time = time.time() +comparison.create_and_export_figures() +# comparison.dumbbell_beta().show() +# comparison.dumbbell_uplift().show() +# comparison.dumbbell_heave().show() +# comparison.dumbbell_piping().show() +# comparison.map_delta_beta_comparison().show() +# comparison.map_ratio_beta_comparison().show() +end_time = time.time() + +print(f"Time passed for export: {end_time - start_time:.2f} sec") diff --git a/main_piping.py b/main_piping.py new file mode 100644 index 00000000..8dadb8d4 --- /dev/null +++ b/main_piping.py @@ -0,0 +1,16 @@ +""" The below code displays an example of how GeoProb-Pipe is run. This example works inside the repository. Use the +Project-object directly outside the repository. """ +from repo_utils.utils import repository_root_path +from geoprob_pipe import GeoProbPipe +from dotenv import load_dotenv +import os + + +# Import environment variables +repo_root = repository_root_path() +load_dotenv(os.path.join(repo_root, "geoprob_pipe.ini")) + + +# Initiate GeoProb-Pipe project object +geoprob_pipe = GeoProbPipe(os.getenv("PATH_WORKSPACE")) +geoprob_pipe.export_archive() diff --git a/main_piping_vsc.py b/main_piping_vsc.py new file mode 100644 index 00000000..dc993a64 --- /dev/null +++ b/main_piping_vsc.py @@ -0,0 +1,15 @@ +# %% +""" The below code displays an example of how GeoProb-Pipe is run. +This example works inside the repository. Use the project-object +directly outside the repository. """ +from geoprob_pipe import GeoProbPipe +import os +from geoprob_pipe.cmd_app.cmd import ApplicationSettings + +if __name__ == "__main__": + app_settings = ApplicationSettings() + filepath = r"tests\systeem_testen\224\Traject224_MORIA_WBN_prob.geoprob_pipe.gpkg" + app_settings.workspace_dir = os.path.dirname(filepath) + app_settings.geopackage_filename = os.path.basename(filepath) + geoprob_pipe = GeoProbPipe(app_settings) + geoprob_pipe.export_archive() diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 00000000..aa4d9c2d --- /dev/null +++ b/poetry.lock @@ -0,0 +1,1726 @@ +# This file is automatically @generated by Poetry 2.1.4 and should not be changed by hand. + +[[package]] +name = "affine" +version = "2.4.0" +description = "Matrices describing affine transformation of the plane" +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "affine-2.4.0-py3-none-any.whl", hash = "sha256:8a3df80e2b2378aef598a83c1392efd47967afec4242021a0b06b4c7cbc61a92"}, + {file = "affine-2.4.0.tar.gz", hash = "sha256:a24d818d6a836c131976d22f8c27b8d3ca32d0af64c1d8d29deb7bafa4da1eea"}, +] + +[package.extras] +dev = ["coveralls", "flake8", "pydocstyle"] +test = ["pytest (>=4.6)", "pytest-cov"] + +[[package]] +name = "attrs" +version = "25.3.0" +description = "Classes Without Boilerplate" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "attrs-25.3.0-py3-none-any.whl", hash = "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3"}, + {file = "attrs-25.3.0.tar.gz", hash = "sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b"}, +] + +[package.extras] +benchmark = ["cloudpickle ; platform_python_implementation == \"CPython\"", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-xdist[psutil]"] +cov = ["cloudpickle ; platform_python_implementation == \"CPython\"", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-xdist[psutil]"] +dev = ["cloudpickle ; platform_python_implementation == \"CPython\"", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-xdist[psutil]"] +docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier"] +tests = ["cloudpickle ; platform_python_implementation == \"CPython\"", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-xdist[psutil]"] +tests-mypy = ["mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\""] + +[[package]] +name = "certifi" +version = "2025.8.3" +description = "Python package for providing Mozilla's CA Bundle." +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "certifi-2025.8.3-py3-none-any.whl", hash = "sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5"}, + {file = "certifi-2025.8.3.tar.gz", hash = "sha256:e564105f78ded564e3ae7c923924435e1daa7463faeab5bb932bc53ffae63407"}, +] + +[[package]] +name = "choreographer" +version = "1.0.9" +description = "Devtools Protocol implementation for chrome." +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "choreographer-1.0.9-py3-none-any.whl", hash = "sha256:b3277e30953843a83d3d730e49958a6be82013885d2a4f54b3950a3715191d7f"}, + {file = "choreographer-1.0.9.tar.gz", hash = "sha256:36423b4b049cf2ec2a68fa4024bdd22d0c417d5421913ef62b6c0e89595b6895"}, +] + +[package.dependencies] +logistro = ">=1.0.11" +simplejson = ">=3.19.3" + +[[package]] +name = "click" +version = "8.2.1" +description = "Composable command line interface toolkit" +optional = false +python-versions = ">=3.10" +groups = ["main"] +files = [ + {file = "click-8.2.1-py3-none-any.whl", hash = "sha256:61a3265b914e850b85317d0b3109c7f8cd35a670f963866005d6ef1d5175a12b"}, + {file = "click-8.2.1.tar.gz", hash = "sha256:27c491cc05d968d271d5a1db13e3b5a184636d9d930f148c50b038f0d0646202"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[[package]] +name = "click-plugins" +version = "1.1.1.2" +description = "An extension module for click to enable registering CLI commands via setuptools entry-points." +optional = false +python-versions = "*" +groups = ["main"] +files = [ + {file = "click_plugins-1.1.1.2-py2.py3-none-any.whl", hash = "sha256:008d65743833ffc1f5417bf0e78e8d2c23aab04d9745ba817bd3e71b0feb6aa6"}, + {file = "click_plugins-1.1.1.2.tar.gz", hash = "sha256:d7af3984a99d243c131aa1a828331e7630f4a88a9741fd05c927b204bcf92261"}, +] + +[package.dependencies] +click = ">=4.0" + +[package.extras] +dev = ["coveralls", "pytest (>=3.6)", "pytest-cov", "wheel"] + +[[package]] +name = "cligj" +version = "0.7.2" +description = "Click params for commmand line interfaces to GeoJSON" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, <4" +groups = ["main"] +files = [ + {file = "cligj-0.7.2-py3-none-any.whl", hash = "sha256:c1ca117dbce1fe20a5809dc96f01e1c2840f6dcc939b3ddbb1111bf330ba82df"}, + {file = "cligj-0.7.2.tar.gz", hash = "sha256:a4bc13d623356b373c2c27c53dbd9c68cae5d526270bfa71f6c6fa69669c6b27"}, +] + +[package.dependencies] +click = ">=4.0" + +[package.extras] +test = ["pytest-cov"] + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +groups = ["main"] +markers = "platform_system == \"Windows\" or sys_platform == \"win32\"" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[[package]] +name = "colorlog" +version = "6.9.0" +description = "Add colours to the output of Python's logging module." +optional = false +python-versions = ">=3.6" +groups = ["main"] +files = [ + {file = "colorlog-6.9.0-py3-none-any.whl", hash = "sha256:5906e71acd67cb07a71e779c47c4bcb45fb8c2993eebe9e5adcd6a6f1b283eff"}, + {file = "colorlog-6.9.0.tar.gz", hash = "sha256:bfba54a1b93b94f54e1f4fe48395725a3d92fd2a4af702f6bd70946bdc0c6ac2"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "sys_platform == \"win32\""} + +[package.extras] +development = ["black", "flake8", "mypy", "pytest", "types-colorama"] + +[[package]] +name = "contourpy" +version = "1.3.3" +description = "Python library for calculating contours of 2D quadrilateral grids" +optional = false +python-versions = ">=3.11" +groups = ["main"] +files = [ + {file = "contourpy-1.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:709a48ef9a690e1343202916450bc48b9e51c049b089c7f79a267b46cffcdaa1"}, + {file = "contourpy-1.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:23416f38bfd74d5d28ab8429cc4d63fa67d5068bd711a85edb1c3fb0c3e2f381"}, + {file = "contourpy-1.3.3-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:929ddf8c4c7f348e4c0a5a3a714b5c8542ffaa8c22954862a46ca1813b667ee7"}, + {file = "contourpy-1.3.3-cp311-cp311-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9e999574eddae35f1312c2b4b717b7885d4edd6cb46700e04f7f02db454e67c1"}, + {file = "contourpy-1.3.3-cp311-cp311-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0bf67e0e3f482cb69779dd3061b534eb35ac9b17f163d851e2a547d56dba0a3a"}, + {file = "contourpy-1.3.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:51e79c1f7470158e838808d4a996fa9bac72c498e93d8ebe5119bc1e6becb0db"}, + {file = "contourpy-1.3.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:598c3aaece21c503615fd59c92a3598b428b2f01bfb4b8ca9c4edeecc2438620"}, + {file = "contourpy-1.3.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:322ab1c99b008dad206d406bb61d014cf0174df491ae9d9d0fac6a6fda4f977f"}, + {file = "contourpy-1.3.3-cp311-cp311-win32.whl", hash = "sha256:fd907ae12cd483cd83e414b12941c632a969171bf90fc937d0c9f268a31cafff"}, + {file = "contourpy-1.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:3519428f6be58431c56581f1694ba8e50626f2dd550af225f82fb5f5814d2a42"}, + {file = "contourpy-1.3.3-cp311-cp311-win_arm64.whl", hash = "sha256:15ff10bfada4bf92ec8b31c62bf7c1834c244019b4a33095a68000d7075df470"}, + {file = "contourpy-1.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b08a32ea2f8e42cf1d4be3169a98dd4be32bafe4f22b6c4cb4ba810fa9e5d2cb"}, + {file = "contourpy-1.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:556dba8fb6f5d8742f2923fe9457dbdd51e1049c4a43fd3986a0b14a1d815fc6"}, + {file = "contourpy-1.3.3-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92d9abc807cf7d0e047b95ca5d957cf4792fcd04e920ca70d48add15c1a90ea7"}, + {file = "contourpy-1.3.3-cp312-cp312-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b2e8faa0ed68cb29af51edd8e24798bb661eac3bd9f65420c1887b6ca89987c8"}, + {file = "contourpy-1.3.3-cp312-cp312-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:626d60935cf668e70a5ce6ff184fd713e9683fb458898e4249b63be9e28286ea"}, + {file = "contourpy-1.3.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4d00e655fcef08aba35ec9610536bfe90267d7ab5ba944f7032549c55a146da1"}, + {file = "contourpy-1.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:451e71b5a7d597379ef572de31eeb909a87246974d960049a9848c3bc6c41bf7"}, + {file = "contourpy-1.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:459c1f020cd59fcfe6650180678a9993932d80d44ccde1fa1868977438f0b411"}, + {file = "contourpy-1.3.3-cp312-cp312-win32.whl", hash = "sha256:023b44101dfe49d7d53932be418477dba359649246075c996866106da069af69"}, + {file = "contourpy-1.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:8153b8bfc11e1e4d75bcb0bff1db232f9e10b274e0929de9d608027e0d34ff8b"}, + {file = "contourpy-1.3.3-cp312-cp312-win_arm64.whl", hash = "sha256:07ce5ed73ecdc4a03ffe3e1b3e3c1166db35ae7584be76f65dbbe28a7791b0cc"}, + {file = "contourpy-1.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:177fb367556747a686509d6fef71d221a4b198a3905fe824430e5ea0fda54eb5"}, + {file = "contourpy-1.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d002b6f00d73d69333dac9d0b8d5e84d9724ff9ef044fd63c5986e62b7c9e1b1"}, + {file = "contourpy-1.3.3-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:348ac1f5d4f1d66d3322420f01d42e43122f43616e0f194fc1c9f5d830c5b286"}, + {file = "contourpy-1.3.3-cp313-cp313-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:655456777ff65c2c548b7c454af9c6f33f16c8884f11083244b5819cc214f1b5"}, + {file = "contourpy-1.3.3-cp313-cp313-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:644a6853d15b2512d67881586bd03f462c7ab755db95f16f14d7e238f2852c67"}, + {file = "contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4debd64f124ca62069f313a9cb86656ff087786016d76927ae2cf37846b006c9"}, + {file = "contourpy-1.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a15459b0f4615b00bbd1e91f1b9e19b7e63aea7483d03d804186f278c0af2659"}, + {file = "contourpy-1.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ca0fdcd73925568ca027e0b17ab07aad764be4706d0a925b89227e447d9737b7"}, + {file = "contourpy-1.3.3-cp313-cp313-win32.whl", hash = "sha256:b20c7c9a3bf701366556e1b1984ed2d0cedf999903c51311417cf5f591d8c78d"}, + {file = "contourpy-1.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:1cadd8b8969f060ba45ed7c1b714fe69185812ab43bd6b86a9123fe8f99c3263"}, + {file = "contourpy-1.3.3-cp313-cp313-win_arm64.whl", hash = "sha256:fd914713266421b7536de2bfa8181aa8c699432b6763a0ea64195ebe28bff6a9"}, + {file = "contourpy-1.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:88df9880d507169449d434c293467418b9f6cbe82edd19284aa0409e7fdb933d"}, + {file = "contourpy-1.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:d06bb1f751ba5d417047db62bca3c8fde202b8c11fb50742ab3ab962c81e8216"}, + {file = "contourpy-1.3.3-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e4e6b05a45525357e382909a4c1600444e2a45b4795163d3b22669285591c1ae"}, + {file = "contourpy-1.3.3-cp313-cp313t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ab3074b48c4e2cf1a960e6bbeb7f04566bf36b1861d5c9d4d8ac04b82e38ba20"}, + {file = "contourpy-1.3.3-cp313-cp313t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6c3d53c796f8647d6deb1abe867daeb66dcc8a97e8455efa729516b997b8ed99"}, + {file = "contourpy-1.3.3-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50ed930df7289ff2a8d7afeb9603f8289e5704755c7e5c3bbd929c90c817164b"}, + {file = "contourpy-1.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4feffb6537d64b84877da813a5c30f1422ea5739566abf0bd18065ac040e120a"}, + {file = "contourpy-1.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2b7e9480ffe2b0cd2e787e4df64270e3a0440d9db8dc823312e2c940c167df7e"}, + {file = "contourpy-1.3.3-cp313-cp313t-win32.whl", hash = "sha256:283edd842a01e3dcd435b1c5116798d661378d83d36d337b8dde1d16a5fc9ba3"}, + {file = "contourpy-1.3.3-cp313-cp313t-win_amd64.whl", hash = "sha256:87acf5963fc2b34825e5b6b048f40e3635dd547f590b04d2ab317c2619ef7ae8"}, + {file = "contourpy-1.3.3-cp313-cp313t-win_arm64.whl", hash = "sha256:3c30273eb2a55024ff31ba7d052dde990d7d8e5450f4bbb6e913558b3d6c2301"}, + {file = "contourpy-1.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fde6c716d51c04b1c25d0b90364d0be954624a0ee9d60e23e850e8d48353d07a"}, + {file = "contourpy-1.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:cbedb772ed74ff5be440fa8eee9bd49f64f6e3fc09436d9c7d8f1c287b121d77"}, + {file = "contourpy-1.3.3-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:22e9b1bd7a9b1d652cd77388465dc358dafcd2e217d35552424aa4f996f524f5"}, + {file = "contourpy-1.3.3-cp314-cp314-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a22738912262aa3e254e4f3cb079a95a67132fc5a063890e224393596902f5a4"}, + {file = "contourpy-1.3.3-cp314-cp314-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:afe5a512f31ee6bd7d0dda52ec9864c984ca3d66664444f2d72e0dc4eb832e36"}, + {file = "contourpy-1.3.3-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f64836de09927cba6f79dcd00fdd7d5329f3fccc633468507079c829ca4db4e3"}, + {file = "contourpy-1.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:1fd43c3be4c8e5fd6e4f2baeae35ae18176cf2e5cced681cca908addf1cdd53b"}, + {file = "contourpy-1.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6afc576f7b33cf00996e5c1102dc2a8f7cc89e39c0b55df93a0b78c1bd992b36"}, + {file = "contourpy-1.3.3-cp314-cp314-win32.whl", hash = "sha256:66c8a43a4f7b8df8b71ee1840e4211a3c8d93b214b213f590e18a1beca458f7d"}, + {file = "contourpy-1.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:cf9022ef053f2694e31d630feaacb21ea24224be1c3ad0520b13d844274614fd"}, + {file = "contourpy-1.3.3-cp314-cp314-win_arm64.whl", hash = "sha256:95b181891b4c71de4bb404c6621e7e2390745f887f2a026b2d99e92c17892339"}, + {file = "contourpy-1.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:33c82d0138c0a062380332c861387650c82e4cf1747aaa6938b9b6516762e772"}, + {file = "contourpy-1.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ea37e7b45949df430fe649e5de8351c423430046a2af20b1c1961cae3afcda77"}, + {file = "contourpy-1.3.3-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d304906ecc71672e9c89e87c4675dc5c2645e1f4269a5063b99b0bb29f232d13"}, + {file = "contourpy-1.3.3-cp314-cp314t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ca658cd1a680a5c9ea96dc61cdbae1e85c8f25849843aa799dfd3cb370ad4fbe"}, + {file = "contourpy-1.3.3-cp314-cp314t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ab2fd90904c503739a75b7c8c5c01160130ba67944a7b77bbf36ef8054576e7f"}, + {file = "contourpy-1.3.3-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b7301b89040075c30e5768810bc96a8e8d78085b47d8be6e4c3f5a0b4ed478a0"}, + {file = "contourpy-1.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:2a2a8b627d5cc6b7c41a4beff6c5ad5eb848c88255fda4a8745f7e901b32d8e4"}, + {file = "contourpy-1.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:fd6ec6be509c787f1caf6b247f0b1ca598bef13f4ddeaa126b7658215529ba0f"}, + {file = "contourpy-1.3.3-cp314-cp314t-win32.whl", hash = "sha256:e74a9a0f5e3fff48fb5a7f2fd2b9b70a3fe014a67522f79b7cca4c0c7e43c9ae"}, + {file = "contourpy-1.3.3-cp314-cp314t-win_amd64.whl", hash = "sha256:13b68d6a62db8eafaebb8039218921399baf6e47bf85006fd8529f2a08ef33fc"}, + {file = "contourpy-1.3.3-cp314-cp314t-win_arm64.whl", hash = "sha256:b7448cb5a725bb1e35ce88771b86fba35ef418952474492cf7c764059933ff8b"}, + {file = "contourpy-1.3.3-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:cd5dfcaeb10f7b7f9dc8941717c6c2ade08f587be2226222c12b25f0483ed497"}, + {file = "contourpy-1.3.3-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:0c1fc238306b35f246d61a1d416a627348b5cf0648648a031e14bb8705fcdfe8"}, + {file = "contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70f9aad7de812d6541d29d2bbf8feb22ff7e1c299523db288004e3157ff4674e"}, + {file = "contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5ed3657edf08512fc3fe81b510e35c2012fbd3081d2e26160f27ca28affec989"}, + {file = "contourpy-1.3.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:3d1a3799d62d45c18bafd41c5fa05120b96a28079f2393af559b843d1a966a77"}, + {file = "contourpy-1.3.3.tar.gz", hash = "sha256:083e12155b210502d0bca491432bb04d56dc3432f95a979b429f2848c3dbe880"}, +] + +[package.dependencies] +numpy = ">=1.25" + +[package.extras] +bokeh = ["bokeh", "selenium"] +docs = ["furo", "sphinx (>=7.2)", "sphinx-copybutton"] +mypy = ["bokeh", "contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.17.0)", "types-Pillow"] +test = ["Pillow", "contourpy[test-no-images]", "matplotlib"] +test-no-images = ["pytest", "pytest-cov", "pytest-rerunfailures", "pytest-xdist", "wurlitzer"] + +[[package]] +name = "cycler" +version = "0.12.1" +description = "Composable style cycles" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30"}, + {file = "cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c"}, +] + +[package.extras] +docs = ["ipython", "matplotlib", "numpydoc", "sphinx"] +tests = ["pytest", "pytest-cov", "pytest-xdist"] + +[[package]] +name = "et-xmlfile" +version = "2.0.0" +description = "An implementation of lxml.xmlfile for the standard library" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "et_xmlfile-2.0.0-py3-none-any.whl", hash = "sha256:7a91720bc756843502c3b7504c77b8fe44217c85c537d85037f0f536151b2caa"}, + {file = "et_xmlfile-2.0.0.tar.gz", hash = "sha256:dab3f4764309081ce75662649be815c4c9081e88f0837825f90fd28317d4da54"}, +] + +[[package]] +name = "fiona" +version = "1.10.1" +description = "Fiona reads and writes spatial data files" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "fiona-1.10.1-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:6e2a94beebda24e5db8c3573fe36110d474d4a12fac0264a3e083c75e9d63829"}, + {file = "fiona-1.10.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fc7366f99bdc18ec99441b9e50246fdf5e72923dc9cbb00267b2bf28edd142ba"}, + {file = "fiona-1.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c32f424b0641c79f4036b96c2e80322fb181b4e415c8cd02d182baef55e6730"}, + {file = "fiona-1.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:9a67bd88918e87d64168bc9c00d9816d8bb07353594b5ce6c57252979d5dc86e"}, + {file = "fiona-1.10.1-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:98fe556058b370da07a84f6537c286f87eb4af2343d155fbd3fba5d38ac17ed7"}, + {file = "fiona-1.10.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:be29044d4aeebae92944b738160dc5f9afc4cdf04f551d59e803c5b910e17520"}, + {file = "fiona-1.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94bd3d448f09f85439e4b77c38b9de1aebe3eef24acc72bd631f75171cdfde51"}, + {file = "fiona-1.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:30594c0cd8682c43fd01e7cdbe000f94540f8fa3b7cb5901e805c88c4ff2058b"}, + {file = "fiona-1.10.1-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:7338b8c68beb7934bde4ec9f49eb5044e5e484b92d940bc3ec27defdb2b06c67"}, + {file = "fiona-1.10.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8c77fcfd3cdb0d3c97237965f8c60d1696a64923deeeb2d0b9810286cbe25911"}, + {file = "fiona-1.10.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:537872cbc9bda7fcdf73851c91bc5338fca2b502c4c17049ccecaa13cde1f18f"}, + {file = "fiona-1.10.1-cp312-cp312-win_amd64.whl", hash = "sha256:41cde2c52c614457e9094ea44b0d30483540789e62fe0fa758c2a2963e980817"}, + {file = "fiona-1.10.1-cp313-cp313-macosx_10_15_x86_64.whl", hash = "sha256:a00b05935c9900678b2ca660026b39efc4e4b916983915d595964eb381763ae7"}, + {file = "fiona-1.10.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f78b781d5bcbbeeddf1d52712f33458775dbb9fd1b2a39882c83618348dd730f"}, + {file = "fiona-1.10.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:29ceeb38e3cd30d91d68858d0817a1bb0c4f96340d334db4b16a99edb0902d35"}, + {file = "fiona-1.10.1-cp313-cp313-win_amd64.whl", hash = "sha256:15751c90e29cee1e01fcfedf42ab85987e32f0b593cf98d88ed52199ef5ca623"}, + {file = "fiona-1.10.1-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:6f1242f872dc33d3b4269dcaebf1838a359f9097e1cc848b0e11367bce010e4d"}, + {file = "fiona-1.10.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:65308b7a7e57fcc533de8a5855b0fce798faabc736d1340192dd8673ff61bc4e"}, + {file = "fiona-1.10.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:632bc146355af5ff0d77e34ebd1be5072d623b4aedb754b94a3d8c356c4545ac"}, + {file = "fiona-1.10.1-cp38-cp38-win_amd64.whl", hash = "sha256:b7b4c3c97b1d64a1b3321577e9edaebbd36b64006e278f225f300c497cc87c35"}, + {file = "fiona-1.10.1-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:b62aa8d5a0981bd33d81c247219b1eaa1e655e0a0682b3a4759fccc40954bb30"}, + {file = "fiona-1.10.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f4b19cb5bd22443ef439b39239272349023556994242a8f953a0147684e1c47f"}, + {file = "fiona-1.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa7e7e5ad252ef29905384bf92e7d14dd5374584b525632652c2ab8925304670"}, + {file = "fiona-1.10.1-cp39-cp39-win_amd64.whl", hash = "sha256:4e82d18acbe55230e9cf8ede2a836d99ea96b7c0cc7d2b8b993e6c9f0ac14dc2"}, + {file = "fiona-1.10.1.tar.gz", hash = "sha256:b00ae357669460c6491caba29c2022ff0acfcbde86a95361ea8ff5cd14a86b68"}, +] + +[package.dependencies] +attrs = ">=19.2.0" +certifi = "*" +click = ">=8.0,<9.0" +click-plugins = ">=1.0" +cligj = ">=0.5" + +[package.extras] +all = ["fiona[calc,s3,test]"] +calc = ["pyparsing", "shapely"] +s3 = ["boto3 (>=1.3.1)"] +test = ["aiohttp", "fiona[s3]", "fsspec", "pytest (>=7)", "pytest-cov", "pytz"] + +[[package]] +name = "fonttools" +version = "4.59.0" +description = "Tools to manipulate font files" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "fonttools-4.59.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:524133c1be38445c5c0575eacea42dbd44374b310b1ffc4b60ff01d881fabb96"}, + {file = "fonttools-4.59.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:21e606b2d38fed938dde871c5736822dd6bda7a4631b92e509a1f5cd1b90c5df"}, + {file = "fonttools-4.59.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e93df708c69a193fc7987192f94df250f83f3851fda49413f02ba5dded639482"}, + {file = "fonttools-4.59.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:62224a9bb85b4b66d1b46d45cbe43d71cbf8f527d332b177e3b96191ffbc1e64"}, + {file = "fonttools-4.59.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b8974b2a266b54c96709bd5e239979cddfd2dbceed331aa567ea1d7c4a2202db"}, + {file = "fonttools-4.59.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:209b75943d158f610b78320eacb5539aa9e920bee2c775445b2846c65d20e19d"}, + {file = "fonttools-4.59.0-cp310-cp310-win32.whl", hash = "sha256:4c908a7036f0f3677f8afa577bcd973e3e20ddd2f7c42a33208d18bee95cdb6f"}, + {file = "fonttools-4.59.0-cp310-cp310-win_amd64.whl", hash = "sha256:8b4309a2775e4feee7356e63b163969a215d663399cce1b3d3b65e7ec2d9680e"}, + {file = "fonttools-4.59.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:841b2186adce48903c0fef235421ae21549020eca942c1da773ac380b056ab3c"}, + {file = "fonttools-4.59.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9bcc1e77fbd1609198966ded6b2a9897bd6c6bcbd2287a2fc7d75f1a254179c5"}, + {file = "fonttools-4.59.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:37c377f7cb2ab2eca8a0b319c68146d34a339792f9420fca6cd49cf28d370705"}, + {file = "fonttools-4.59.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fa39475eaccb98f9199eccfda4298abaf35ae0caec676ffc25b3a5e224044464"}, + {file = "fonttools-4.59.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d3972b13148c1d1fbc092b27678a33b3080d1ac0ca305742b0119b75f9e87e38"}, + {file = "fonttools-4.59.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a408c3c51358c89b29cfa5317cf11518b7ce5de1717abb55c5ae2d2921027de6"}, + {file = "fonttools-4.59.0-cp311-cp311-win32.whl", hash = "sha256:6770d7da00f358183d8fd5c4615436189e4f683bdb6affb02cad3d221d7bb757"}, + {file = "fonttools-4.59.0-cp311-cp311-win_amd64.whl", hash = "sha256:84fc186980231a287b28560d3123bd255d3c6b6659828c642b4cf961e2b923d0"}, + {file = "fonttools-4.59.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:f9b3a78f69dcbd803cf2fb3f972779875b244c1115481dfbdd567b2c22b31f6b"}, + {file = "fonttools-4.59.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:57bb7e26928573ee7c6504f54c05860d867fd35e675769f3ce01b52af38d48e2"}, + {file = "fonttools-4.59.0-cp312-cp312-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:4536f2695fe5c1ffb528d84a35a7d3967e5558d2af58b4775e7ab1449d65767b"}, + {file = "fonttools-4.59.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:885bde7d26e5b40e15c47bd5def48b38cbd50830a65f98122a8fb90962af7cd1"}, + {file = "fonttools-4.59.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6801aeddb6acb2c42eafa45bc1cb98ba236871ae6f33f31e984670b749a8e58e"}, + {file = "fonttools-4.59.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:31003b6a10f70742a63126b80863ab48175fb8272a18ca0846c0482968f0588e"}, + {file = "fonttools-4.59.0-cp312-cp312-win32.whl", hash = "sha256:fbce6dae41b692a5973d0f2158f782b9ad05babc2c2019a970a1094a23909b1b"}, + {file = "fonttools-4.59.0-cp312-cp312-win_amd64.whl", hash = "sha256:332bfe685d1ac58ca8d62b8d6c71c2e52a6c64bc218dc8f7825c9ea51385aa01"}, + {file = "fonttools-4.59.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:78813b49d749e1bb4db1c57f2d4d7e6db22c253cb0a86ad819f5dc197710d4b2"}, + {file = "fonttools-4.59.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:401b1941ce37e78b8fd119b419b617277c65ae9417742a63282257434fd68ea2"}, + {file = "fonttools-4.59.0-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:efd7e6660674e234e29937bc1481dceb7e0336bfae75b856b4fb272b5093c5d4"}, + {file = "fonttools-4.59.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:51ab1ff33c19e336c02dee1e9fd1abd974a4ca3d8f7eef2a104d0816a241ce97"}, + {file = "fonttools-4.59.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a9bf8adc9e1f3012edc8f09b08336272aec0c55bc677422273e21280db748f7c"}, + {file = "fonttools-4.59.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:37e01c6ec0c98599778c2e688350d624fa4770fbd6144551bd5e032f1199171c"}, + {file = "fonttools-4.59.0-cp313-cp313-win32.whl", hash = "sha256:70d6b3ceaa9cc5a6ac52884f3b3d9544e8e231e95b23f138bdb78e6d4dc0eae3"}, + {file = "fonttools-4.59.0-cp313-cp313-win_amd64.whl", hash = "sha256:26731739daa23b872643f0e4072d5939960237d540c35c14e6a06d47d71ca8fe"}, + {file = "fonttools-4.59.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8d77f92438daeaddc05682f0f3dac90c5b9829bcac75b57e8ce09cb67786073c"}, + {file = "fonttools-4.59.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:60f6665579e909b618282f3c14fa0b80570fbf1ee0e67678b9a9d43aa5d67a37"}, + {file = "fonttools-4.59.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:169b99a2553a227f7b5fea8d9ecd673aa258617f466b2abc6091fe4512a0dcd0"}, + {file = "fonttools-4.59.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:052444a5d0151878e87e3e512a1aa1a0ab35ee4c28afde0a778e23b0ace4a7de"}, + {file = "fonttools-4.59.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d40dcf533ca481355aa7b682e9e079f766f35715defa4929aeb5597f9604272e"}, + {file = "fonttools-4.59.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b818db35879d2edf7f46c7e729c700a0bce03b61b9412f5a7118406687cb151d"}, + {file = "fonttools-4.59.0-cp39-cp39-win32.whl", hash = "sha256:2e7cf8044ce2598bb87e44ba1d2c6e45d7a8decf56055b92906dc53f67c76d64"}, + {file = "fonttools-4.59.0-cp39-cp39-win_amd64.whl", hash = "sha256:902425f5afe28572d65d2bf9c33edd5265c612ff82c69e6f83ea13eafc0dcbea"}, + {file = "fonttools-4.59.0-py3-none-any.whl", hash = "sha256:241313683afd3baacb32a6bd124d0bce7404bc5280e12e291bae1b9bba28711d"}, + {file = "fonttools-4.59.0.tar.gz", hash = "sha256:be392ec3529e2f57faa28709d60723a763904f71a2b63aabe14fee6648fe3b14"}, +] + +[package.extras] +all = ["brotli (>=1.0.1) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\"", "lxml (>=4.0)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres ; platform_python_implementation == \"PyPy\"", "pycairo", "scipy ; platform_python_implementation != \"PyPy\"", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=15.1.0) ; python_version <= \"3.12\"", "xattr ; sys_platform == \"darwin\"", "zopfli (>=0.1.4)"] +graphite = ["lz4 (>=1.7.4.2)"] +interpolatable = ["munkres ; platform_python_implementation == \"PyPy\"", "pycairo", "scipy ; platform_python_implementation != \"PyPy\""] +lxml = ["lxml (>=4.0)"] +pathops = ["skia-pathops (>=0.5.0)"] +plot = ["matplotlib"] +repacker = ["uharfbuzz (>=0.23.0)"] +symfont = ["sympy"] +type1 = ["xattr ; sys_platform == \"darwin\""] +unicode = ["unicodedata2 (>=15.1.0) ; python_version <= \"3.12\""] +woff = ["brotli (>=1.0.1) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\"", "zopfli (>=0.1.4)"] + +[[package]] +name = "geopandas" +version = "1.1.1" +description = "Geographic pandas extensions" +optional = false +python-versions = ">=3.10" +groups = ["main"] +files = [ + {file = "geopandas-1.1.1-py3-none-any.whl", hash = "sha256:589e61aaf39b19828843df16cb90234e72897e2579be236f10eee0d052ad98e8"}, + {file = "geopandas-1.1.1.tar.gz", hash = "sha256:1745713f64d095c43e72e08e753dbd271678254b24f2e01db8cdb8debe1d293d"}, +] + +[package.dependencies] +numpy = ">=1.24" +packaging = "*" +pandas = ">=2.0.0" +pyogrio = ">=0.7.2" +pyproj = ">=3.5.0" +shapely = ">=2.0.0" + +[package.extras] +all = ["GeoAlchemy2", "SQLAlchemy (>=2.0)", "folium", "geopy", "mapclassify (>=2.5)", "matplotlib (>=3.7)", "psycopg[binary] (>=3.1.0)", "pyarrow (>=10.0.0)", "scipy", "xyzservices"] +dev = ["codecov", "pre-commit", "pytest (>=3.1.0)", "pytest-cov", "pytest-xdist", "ruff"] + +[[package]] +name = "inquirerpy" +version = "0.3.4" +description = "Python port of Inquirer.js (A collection of common interactive command-line user interfaces)" +optional = false +python-versions = ">=3.7,<4.0" +groups = ["main"] +files = [ + {file = "InquirerPy-0.3.4-py3-none-any.whl", hash = "sha256:c65fdfbac1fa00e3ee4fb10679f4d3ed7a012abf4833910e63c295827fe2a7d4"}, + {file = "InquirerPy-0.3.4.tar.gz", hash = "sha256:89d2ada0111f337483cb41ae31073108b2ec1e618a49d7110b0d7ade89fc197e"}, +] + +[package.dependencies] +pfzy = ">=0.3.1,<0.4.0" +prompt-toolkit = ">=3.0.1,<4.0.0" + +[package.extras] +docs = ["Sphinx (>=4.1.2,<5.0.0)", "furo (>=2021.8.17-beta.43,<2022.0.0)", "myst-parser (>=0.15.1,<0.16.0)", "sphinx-autobuild (>=2021.3.14,<2022.0.0)", "sphinx-copybutton (>=0.4.0,<0.5.0)"] + +[[package]] +name = "kaleido" +version = "1.0.0" +description = "Plotly graph export library" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "kaleido-1.0.0-py3-none-any.whl", hash = "sha256:a7e8bd95648378d2746f6c86084d419d15f95b1ec7bb0ec810289b7feb25b18d"}, + {file = "kaleido-1.0.0.tar.gz", hash = "sha256:502d8ba64737924efaf5e94c2736745bcc7c926e6cc535838be36c0fc06330bd"}, +] + +[package.dependencies] +choreographer = ">=1.0.5" +logistro = ">=1.0.8" +orjson = ">=3.10.15" +packaging = "*" + +[[package]] +name = "kiwisolver" +version = "1.4.8" +description = "A fast implementation of the Cassowary constraint solver" +optional = false +python-versions = ">=3.10" +groups = ["main"] +files = [ + {file = "kiwisolver-1.4.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:88c6f252f6816a73b1f8c904f7bbe02fd67c09a69f7cb8a0eecdbf5ce78e63db"}, + {file = "kiwisolver-1.4.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c72941acb7b67138f35b879bbe85be0f6c6a70cab78fe3ef6db9c024d9223e5b"}, + {file = "kiwisolver-1.4.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ce2cf1e5688edcb727fdf7cd1bbd0b6416758996826a8be1d958f91880d0809d"}, + {file = "kiwisolver-1.4.8-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:c8bf637892dc6e6aad2bc6d4d69d08764166e5e3f69d469e55427b6ac001b19d"}, + {file = "kiwisolver-1.4.8-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:034d2c891f76bd3edbdb3ea11140d8510dca675443da7304205a2eaa45d8334c"}, + {file = "kiwisolver-1.4.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d47b28d1dfe0793d5e96bce90835e17edf9a499b53969b03c6c47ea5985844c3"}, + {file = "kiwisolver-1.4.8-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eb158fe28ca0c29f2260cca8c43005329ad58452c36f0edf298204de32a9a3ed"}, + {file = "kiwisolver-1.4.8-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5536185fce131780ebd809f8e623bf4030ce1b161353166c49a3c74c287897f"}, + {file = "kiwisolver-1.4.8-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:369b75d40abedc1da2c1f4de13f3482cb99e3237b38726710f4a793432b1c5ff"}, + {file = "kiwisolver-1.4.8-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:641f2ddf9358c80faa22e22eb4c9f54bd3f0e442e038728f500e3b978d00aa7d"}, + {file = "kiwisolver-1.4.8-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d561d2d8883e0819445cfe58d7ddd673e4015c3c57261d7bdcd3710d0d14005c"}, + {file = "kiwisolver-1.4.8-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:1732e065704b47c9afca7ffa272f845300a4eb959276bf6970dc07265e73b605"}, + {file = "kiwisolver-1.4.8-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:bcb1ebc3547619c3b58a39e2448af089ea2ef44b37988caf432447374941574e"}, + {file = "kiwisolver-1.4.8-cp310-cp310-win_amd64.whl", hash = "sha256:89c107041f7b27844179ea9c85d6da275aa55ecf28413e87624d033cf1f6b751"}, + {file = "kiwisolver-1.4.8-cp310-cp310-win_arm64.whl", hash = "sha256:b5773efa2be9eb9fcf5415ea3ab70fc785d598729fd6057bea38d539ead28271"}, + {file = "kiwisolver-1.4.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a4d3601908c560bdf880f07d94f31d734afd1bb71e96585cace0e38ef44c6d84"}, + {file = "kiwisolver-1.4.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:856b269c4d28a5c0d5e6c1955ec36ebfd1651ac00e1ce0afa3e28da95293b561"}, + {file = "kiwisolver-1.4.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c2b9a96e0f326205af81a15718a9073328df1173a2619a68553decb7097fd5d7"}, + {file = "kiwisolver-1.4.8-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c5020c83e8553f770cb3b5fc13faac40f17e0b205bd237aebd21d53d733adb03"}, + {file = "kiwisolver-1.4.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dace81d28c787956bfbfbbfd72fdcef014f37d9b48830829e488fdb32b49d954"}, + {file = "kiwisolver-1.4.8-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:11e1022b524bd48ae56c9b4f9296bce77e15a2e42a502cceba602f804b32bb79"}, + {file = "kiwisolver-1.4.8-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b9b4d2892fefc886f30301cdd80debd8bb01ecdf165a449eb6e78f79f0fabd6"}, + {file = "kiwisolver-1.4.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a96c0e790ee875d65e340ab383700e2b4891677b7fcd30a699146f9384a2bb0"}, + {file = "kiwisolver-1.4.8-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:23454ff084b07ac54ca8be535f4174170c1094a4cff78fbae4f73a4bcc0d4dab"}, + {file = "kiwisolver-1.4.8-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:87b287251ad6488e95b4f0b4a79a6d04d3ea35fde6340eb38fbd1ca9cd35bbbc"}, + {file = "kiwisolver-1.4.8-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:b21dbe165081142b1232a240fc6383fd32cdd877ca6cc89eab93e5f5883e1c25"}, + {file = "kiwisolver-1.4.8-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:768cade2c2df13db52475bd28d3a3fac8c9eff04b0e9e2fda0f3760f20b3f7fc"}, + {file = "kiwisolver-1.4.8-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d47cfb2650f0e103d4bf68b0b5804c68da97272c84bb12850d877a95c056bd67"}, + {file = "kiwisolver-1.4.8-cp311-cp311-win_amd64.whl", hash = "sha256:ed33ca2002a779a2e20eeb06aea7721b6e47f2d4b8a8ece979d8ba9e2a167e34"}, + {file = "kiwisolver-1.4.8-cp311-cp311-win_arm64.whl", hash = "sha256:16523b40aab60426ffdebe33ac374457cf62863e330a90a0383639ce14bf44b2"}, + {file = "kiwisolver-1.4.8-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:d6af5e8815fd02997cb6ad9bbed0ee1e60014438ee1a5c2444c96f87b8843502"}, + {file = "kiwisolver-1.4.8-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:bade438f86e21d91e0cf5dd7c0ed00cda0f77c8c1616bd83f9fc157fa6760d31"}, + {file = "kiwisolver-1.4.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b83dc6769ddbc57613280118fb4ce3cd08899cc3369f7d0e0fab518a7cf37fdb"}, + {file = "kiwisolver-1.4.8-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:111793b232842991be367ed828076b03d96202c19221b5ebab421ce8bcad016f"}, + {file = "kiwisolver-1.4.8-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:257af1622860e51b1a9d0ce387bf5c2c4f36a90594cb9514f55b074bcc787cfc"}, + {file = "kiwisolver-1.4.8-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:69b5637c3f316cab1ec1c9a12b8c5f4750a4c4b71af9157645bf32830e39c03a"}, + {file = "kiwisolver-1.4.8-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:782bb86f245ec18009890e7cb8d13a5ef54dcf2ebe18ed65f795e635a96a1c6a"}, + {file = "kiwisolver-1.4.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc978a80a0db3a66d25767b03688f1147a69e6237175c0f4ffffaaedf744055a"}, + {file = "kiwisolver-1.4.8-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:36dbbfd34838500a31f52c9786990d00150860e46cd5041386f217101350f0d3"}, + {file = "kiwisolver-1.4.8-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:eaa973f1e05131de5ff3569bbba7f5fd07ea0595d3870ed4a526d486fe57fa1b"}, + {file = "kiwisolver-1.4.8-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:a66f60f8d0c87ab7f59b6fb80e642ebb29fec354a4dfad687ca4092ae69d04f4"}, + {file = "kiwisolver-1.4.8-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:858416b7fb777a53f0c59ca08190ce24e9abbd3cffa18886a5781b8e3e26f65d"}, + {file = "kiwisolver-1.4.8-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:085940635c62697391baafaaeabdf3dd7a6c3643577dde337f4d66eba021b2b8"}, + {file = "kiwisolver-1.4.8-cp312-cp312-win_amd64.whl", hash = "sha256:01c3d31902c7db5fb6182832713d3b4122ad9317c2c5877d0539227d96bb2e50"}, + {file = "kiwisolver-1.4.8-cp312-cp312-win_arm64.whl", hash = "sha256:a3c44cb68861de93f0c4a8175fbaa691f0aa22550c331fefef02b618a9dcb476"}, + {file = "kiwisolver-1.4.8-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:1c8ceb754339793c24aee1c9fb2485b5b1f5bb1c2c214ff13368431e51fc9a09"}, + {file = "kiwisolver-1.4.8-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:54a62808ac74b5e55a04a408cda6156f986cefbcf0ada13572696b507cc92fa1"}, + {file = "kiwisolver-1.4.8-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:68269e60ee4929893aad82666821aaacbd455284124817af45c11e50a4b42e3c"}, + {file = "kiwisolver-1.4.8-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:34d142fba9c464bc3bbfeff15c96eab0e7310343d6aefb62a79d51421fcc5f1b"}, + {file = "kiwisolver-1.4.8-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ddc373e0eef45b59197de815b1b28ef89ae3955e7722cc9710fb91cd77b7f47"}, + {file = "kiwisolver-1.4.8-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:77e6f57a20b9bd4e1e2cedda4d0b986ebd0216236f0106e55c28aea3d3d69b16"}, + {file = "kiwisolver-1.4.8-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08e77738ed7538f036cd1170cbed942ef749137b1311fa2bbe2a7fda2f6bf3cc"}, + {file = "kiwisolver-1.4.8-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a5ce1e481a74b44dd5e92ff03ea0cb371ae7a0268318e202be06c8f04f4f1246"}, + {file = "kiwisolver-1.4.8-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:fc2ace710ba7c1dfd1a3b42530b62b9ceed115f19a1656adefce7b1782a37794"}, + {file = "kiwisolver-1.4.8-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:3452046c37c7692bd52b0e752b87954ef86ee2224e624ef7ce6cb21e8c41cc1b"}, + {file = "kiwisolver-1.4.8-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:7e9a60b50fe8b2ec6f448fe8d81b07e40141bfced7f896309df271a0b92f80f3"}, + {file = "kiwisolver-1.4.8-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:918139571133f366e8362fa4a297aeba86c7816b7ecf0bc79168080e2bd79957"}, + {file = "kiwisolver-1.4.8-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e063ef9f89885a1d68dd8b2e18f5ead48653176d10a0e324e3b0030e3a69adeb"}, + {file = "kiwisolver-1.4.8-cp313-cp313-win_amd64.whl", hash = "sha256:a17b7c4f5b2c51bb68ed379defd608a03954a1845dfed7cc0117f1cc8a9b7fd2"}, + {file = "kiwisolver-1.4.8-cp313-cp313-win_arm64.whl", hash = "sha256:3cd3bc628b25f74aedc6d374d5babf0166a92ff1317f46267f12d2ed54bc1d30"}, + {file = "kiwisolver-1.4.8-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:370fd2df41660ed4e26b8c9d6bbcad668fbe2560462cba151a721d49e5b6628c"}, + {file = "kiwisolver-1.4.8-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:84a2f830d42707de1d191b9490ac186bf7997a9495d4e9072210a1296345f7dc"}, + {file = "kiwisolver-1.4.8-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:7a3ad337add5148cf51ce0b55642dc551c0b9d6248458a757f98796ca7348712"}, + {file = "kiwisolver-1.4.8-cp313-cp313t-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7506488470f41169b86d8c9aeff587293f530a23a23a49d6bc64dab66bedc71e"}, + {file = "kiwisolver-1.4.8-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f0121b07b356a22fb0414cec4666bbe36fd6d0d759db3d37228f496ed67c880"}, + {file = "kiwisolver-1.4.8-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d6d6bd87df62c27d4185de7c511c6248040afae67028a8a22012b010bc7ad062"}, + {file = "kiwisolver-1.4.8-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:291331973c64bb9cce50bbe871fb2e675c4331dab4f31abe89f175ad7679a4d7"}, + {file = "kiwisolver-1.4.8-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:893f5525bb92d3d735878ec00f781b2de998333659507d29ea4466208df37bed"}, + {file = "kiwisolver-1.4.8-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b47a465040146981dc9db8647981b8cb96366fbc8d452b031e4f8fdffec3f26d"}, + {file = "kiwisolver-1.4.8-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:99cea8b9dd34ff80c521aef46a1dddb0dcc0283cf18bde6d756f1e6f31772165"}, + {file = "kiwisolver-1.4.8-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:151dffc4865e5fe6dafce5480fab84f950d14566c480c08a53c663a0020504b6"}, + {file = "kiwisolver-1.4.8-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:577facaa411c10421314598b50413aa1ebcf5126f704f1e5d72d7e4e9f020d90"}, + {file = "kiwisolver-1.4.8-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:be4816dc51c8a471749d664161b434912eee82f2ea66bd7628bd14583a833e85"}, + {file = "kiwisolver-1.4.8-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:e7a019419b7b510f0f7c9dceff8c5eae2392037eae483a7f9162625233802b0a"}, + {file = "kiwisolver-1.4.8-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:286b18e86682fd2217a48fc6be6b0f20c1d0ed10958d8dc53453ad58d7be0bf8"}, + {file = "kiwisolver-1.4.8-pp310-pypy310_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4191ee8dfd0be1c3666ccbac178c5a05d5f8d689bbe3fc92f3c4abec817f8fe0"}, + {file = "kiwisolver-1.4.8-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7cd2785b9391f2873ad46088ed7599a6a71e762e1ea33e87514b1a441ed1da1c"}, + {file = "kiwisolver-1.4.8-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c07b29089b7ba090b6f1a669f1411f27221c3662b3a1b7010e67b59bb5a6f10b"}, + {file = "kiwisolver-1.4.8-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:65ea09a5a3faadd59c2ce96dc7bf0f364986a315949dc6374f04396b0d60e09b"}, + {file = "kiwisolver-1.4.8.tar.gz", hash = "sha256:23d5f023bdc8c7e54eb65f03ca5d5bb25b601eac4d7f1a042888a1f45237987e"}, +] + +[[package]] +name = "logistro" +version = "1.1.0" +description = "Simple wrapper over logging for a couple basic features" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "logistro-1.1.0-py3-none-any.whl", hash = "sha256:4f88541fe7f3c545561b754d86121abd9c6d4d8b312381046a78dcd794fddc7c"}, + {file = "logistro-1.1.0.tar.gz", hash = "sha256:ad51f0efa2bc705bea7c266e8a759cf539457cf7108202a5eec77bdf6300d774"}, +] + +[[package]] +name = "markdown-it-py" +version = "4.0.0" +description = "Python port of markdown-it. Markdown parsing, done right!" +optional = false +python-versions = ">=3.10" +groups = ["main"] +files = [ + {file = "markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147"}, + {file = "markdown_it_py-4.0.0.tar.gz", hash = "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3"}, +] + +[package.dependencies] +mdurl = ">=0.1,<1.0" + +[package.extras] +benchmarking = ["psutil", "pytest", "pytest-benchmark"] +compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "markdown-it-pyrs", "mistletoe (>=1.0,<2.0)", "mistune (>=3.0,<4.0)", "panflute (>=2.3,<3.0)"] +linkify = ["linkify-it-py (>=1,<3)"] +plugins = ["mdit-py-plugins (>=0.5.0)"] +profiling = ["gprof2dot"] +rtd = ["ipykernel", "jupyter_sphinx", "mdit-py-plugins (>=0.5.0)", "myst-parser", "pyyaml", "sphinx", "sphinx-book-theme (>=1.0,<2.0)", "sphinx-copybutton", "sphinx-design"] +testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions", "requests"] + +[[package]] +name = "matplotlib" +version = "3.10.5" +description = "Python plotting package" +optional = false +python-versions = ">=3.10" +groups = ["main"] +files = [ + {file = "matplotlib-3.10.5-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:5d4773a6d1c106ca05cb5a5515d277a6bb96ed09e5c8fab6b7741b8fcaa62c8f"}, + {file = "matplotlib-3.10.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dc88af74e7ba27de6cbe6faee916024ea35d895ed3d61ef6f58c4ce97da7185a"}, + {file = "matplotlib-3.10.5-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:64c4535419d5617f7363dad171a5a59963308e0f3f813c4bed6c9e6e2c131512"}, + {file = "matplotlib-3.10.5-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a277033048ab22d34f88a3c5243938cef776493f6201a8742ed5f8b553201343"}, + {file = "matplotlib-3.10.5-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e4a6470a118a2e93022ecc7d3bd16b3114b2004ea2bf014fff875b3bc99b70c6"}, + {file = "matplotlib-3.10.5-cp310-cp310-win_amd64.whl", hash = "sha256:7e44cada61bec8833c106547786814dd4a266c1b2964fd25daa3804f1b8d4467"}, + {file = "matplotlib-3.10.5-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:dcfc39c452c6a9f9028d3e44d2d721484f665304857188124b505b2c95e1eecf"}, + {file = "matplotlib-3.10.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:903352681b59f3efbf4546985142a9686ea1d616bb054b09a537a06e4b892ccf"}, + {file = "matplotlib-3.10.5-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:080c3676a56b8ee1c762bcf8fca3fe709daa1ee23e6ef06ad9f3fc17332f2d2a"}, + {file = "matplotlib-3.10.5-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4b4984d5064a35b6f66d2c11d668565f4389b1119cc64db7a4c1725bc11adffc"}, + {file = "matplotlib-3.10.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3967424121d3a46705c9fa9bdb0931de3228f13f73d7bb03c999c88343a89d89"}, + {file = "matplotlib-3.10.5-cp311-cp311-win_amd64.whl", hash = "sha256:33775bbeb75528555a15ac29396940128ef5613cf9a2d31fb1bfd18b3c0c0903"}, + {file = "matplotlib-3.10.5-cp311-cp311-win_arm64.whl", hash = "sha256:c61333a8e5e6240e73769d5826b9a31d8b22df76c0778f8480baf1b4b01c9420"}, + {file = "matplotlib-3.10.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:00b6feadc28a08bd3c65b2894f56cf3c94fc8f7adcbc6ab4516ae1e8ed8f62e2"}, + {file = "matplotlib-3.10.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ee98a5c5344dc7f48dc261b6ba5d9900c008fc12beb3fa6ebda81273602cc389"}, + {file = "matplotlib-3.10.5-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a17e57e33de901d221a07af32c08870ed4528db0b6059dce7d7e65c1122d4bea"}, + {file = "matplotlib-3.10.5-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:97b9d6443419085950ee4a5b1ee08c363e5c43d7176e55513479e53669e88468"}, + {file = "matplotlib-3.10.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ceefe5d40807d29a66ae916c6a3915d60ef9f028ce1927b84e727be91d884369"}, + {file = "matplotlib-3.10.5-cp312-cp312-win_amd64.whl", hash = "sha256:c04cba0f93d40e45b3c187c6c52c17f24535b27d545f757a2fffebc06c12b98b"}, + {file = "matplotlib-3.10.5-cp312-cp312-win_arm64.whl", hash = "sha256:a41bcb6e2c8e79dc99c5511ae6f7787d2fb52efd3d805fff06d5d4f667db16b2"}, + {file = "matplotlib-3.10.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:354204db3f7d5caaa10e5de74549ef6a05a4550fdd1c8f831ab9bca81efd39ed"}, + {file = "matplotlib-3.10.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b072aac0c3ad563a2b3318124756cb6112157017f7431626600ecbe890df57a1"}, + {file = "matplotlib-3.10.5-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d52fd5b684d541b5a51fb276b2b97b010c75bee9aa392f96b4a07aeb491e33c7"}, + {file = "matplotlib-3.10.5-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee7a09ae2f4676276f5a65bd9f2bd91b4f9fbaedf49f40267ce3f9b448de501f"}, + {file = "matplotlib-3.10.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ba6c3c9c067b83481d647af88b4e441d532acdb5ef22178a14935b0b881188f4"}, + {file = "matplotlib-3.10.5-cp313-cp313-win_amd64.whl", hash = "sha256:07442d2692c9bd1cceaa4afb4bbe5b57b98a7599de4dabfcca92d3eea70f9ebe"}, + {file = "matplotlib-3.10.5-cp313-cp313-win_arm64.whl", hash = "sha256:48fe6d47380b68a37ccfcc94f009530e84d41f71f5dae7eda7c4a5a84aa0a674"}, + {file = "matplotlib-3.10.5-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:3b80eb8621331449fc519541a7461987f10afa4f9cfd91afcd2276ebe19bd56c"}, + {file = "matplotlib-3.10.5-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:47a388908e469d6ca2a6015858fa924e0e8a2345a37125948d8e93a91c47933e"}, + {file = "matplotlib-3.10.5-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8b6b49167d208358983ce26e43aa4196073b4702858670f2eb111f9a10652b4b"}, + {file = "matplotlib-3.10.5-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8a8da0453a7fd8e3da114234ba70c5ba9ef0e98f190309ddfde0f089accd46ea"}, + {file = "matplotlib-3.10.5-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:52c6573dfcb7726a9907b482cd5b92e6b5499b284ffacb04ffbfe06b3e568124"}, + {file = "matplotlib-3.10.5-cp313-cp313t-win_amd64.whl", hash = "sha256:a23193db2e9d64ece69cac0c8231849db7dd77ce59c7b89948cf9d0ce655a3ce"}, + {file = "matplotlib-3.10.5-cp313-cp313t-win_arm64.whl", hash = "sha256:56da3b102cf6da2776fef3e71cd96fcf22103a13594a18ac9a9b31314e0be154"}, + {file = "matplotlib-3.10.5-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:96ef8f5a3696f20f55597ffa91c28e2e73088df25c555f8d4754931515512715"}, + {file = "matplotlib-3.10.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:77fab633e94b9da60512d4fa0213daeb76d5a7b05156840c4fd0399b4b818837"}, + {file = "matplotlib-3.10.5-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:27f52634315e96b1debbfdc5c416592edcd9c4221bc2f520fd39c33db5d9f202"}, + {file = "matplotlib-3.10.5-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:525f6e28c485c769d1f07935b660c864de41c37fd716bfa64158ea646f7084bb"}, + {file = "matplotlib-3.10.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:1f5f3ec4c191253c5f2b7c07096a142c6a1c024d9f738247bfc8e3f9643fc975"}, + {file = "matplotlib-3.10.5-cp314-cp314-win_amd64.whl", hash = "sha256:707f9c292c4cd4716f19ab8a1f93f26598222cd931e0cd98fbbb1c5994bf7667"}, + {file = "matplotlib-3.10.5-cp314-cp314-win_arm64.whl", hash = "sha256:21a95b9bf408178d372814de7baacd61c712a62cae560b5e6f35d791776f6516"}, + {file = "matplotlib-3.10.5-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:a6b310f95e1102a8c7c817ef17b60ee5d1851b8c71b63d9286b66b177963039e"}, + {file = "matplotlib-3.10.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:94986a242747a0605cb3ff1cb98691c736f28a59f8ffe5175acaeb7397c49a5a"}, + {file = "matplotlib-3.10.5-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1ff10ea43288f0c8bab608a305dc6c918cc729d429c31dcbbecde3b9f4d5b569"}, + {file = "matplotlib-3.10.5-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f6adb644c9d040ffb0d3434e440490a66cf73dbfa118a6f79cd7568431f7a012"}, + {file = "matplotlib-3.10.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:4fa40a8f98428f789a9dcacd625f59b7bc4e3ef6c8c7c80187a7a709475cf592"}, + {file = "matplotlib-3.10.5-cp314-cp314t-win_amd64.whl", hash = "sha256:95672a5d628b44207aab91ec20bf59c26da99de12b88f7e0b1fb0a84a86ff959"}, + {file = "matplotlib-3.10.5-cp314-cp314t-win_arm64.whl", hash = "sha256:2efaf97d72629e74252e0b5e3c46813e9eeaa94e011ecf8084a971a31a97f40b"}, + {file = "matplotlib-3.10.5-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b5fa2e941f77eb579005fb804026f9d0a1082276118d01cc6051d0d9626eaa7f"}, + {file = "matplotlib-3.10.5-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1fc0d2a3241cdcb9daaca279204a3351ce9df3c0e7e621c7e04ec28aaacaca30"}, + {file = "matplotlib-3.10.5-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8dee65cb1424b7dc982fe87895b5613d4e691cc57117e8af840da0148ca6c1d7"}, + {file = "matplotlib-3.10.5-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:160e125da27a749481eaddc0627962990f6029811dbeae23881833a011a0907f"}, + {file = "matplotlib-3.10.5-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:ac3d50760394d78a3c9be6b28318fe22b494c4fcf6407e8fd4794b538251899b"}, + {file = "matplotlib-3.10.5-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6c49465bf689c4d59d174d0c7795fb42a21d4244d11d70e52b8011987367ac61"}, + {file = "matplotlib-3.10.5.tar.gz", hash = "sha256:352ed6ccfb7998a00881692f38b4ca083c691d3e275b4145423704c34c909076"}, +] + +[package.dependencies] +contourpy = ">=1.0.1" +cycler = ">=0.10" +fonttools = ">=4.22.0" +kiwisolver = ">=1.3.1" +numpy = ">=1.23" +packaging = ">=20.0" +pillow = ">=8" +pyparsing = ">=2.3.1" +python-dateutil = ">=2.7" + +[package.extras] +dev = ["meson-python (>=0.13.1,<0.17.0)", "pybind11 (>=2.13.2,!=2.13.3)", "setuptools (>=64)", "setuptools_scm (>=7)"] + +[[package]] +name = "mdurl" +version = "0.1.2" +description = "Markdown URL utilities" +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, + {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, +] + +[[package]] +name = "narwhals" +version = "2.0.1" +description = "Extremely lightweight compatibility layer between dataframe libraries" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "narwhals-2.0.1-py3-none-any.whl", hash = "sha256:837457e36a2ba1710c881fb69e1f79ce44fb81728c92ac378f70892a53af8ddb"}, + {file = "narwhals-2.0.1.tar.gz", hash = "sha256:235e61ca807bc21110ca36a4d53888ecc22c42dcdf50a7c886e10dde3fd7f38c"}, +] + +[package.extras] +cudf = ["cudf (>=24.10.0)"] +dask = ["dask[dataframe] (>=2024.8)"] +duckdb = ["duckdb (>=1.0)"] +ibis = ["ibis-framework (>=6.0.0)", "packaging", "pyarrow-hotfix", "rich"] +modin = ["modin"] +pandas = ["pandas (>=1.1.3)"] +polars = ["polars (>=0.20.4)"] +pyarrow = ["pyarrow (>=13.0.0)"] +pyspark = ["pyspark (>=3.5.0)"] +pyspark-connect = ["pyspark[connect] (>=3.5.0)"] +sqlframe = ["sqlframe (>=3.22.0)"] + +[[package]] +name = "numpy" +version = "2.3.2" +description = "Fundamental package for array computing in Python" +optional = false +python-versions = ">=3.11" +groups = ["main"] +files = [ + {file = "numpy-2.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:852ae5bed3478b92f093e30f785c98e0cb62fa0a939ed057c31716e18a7a22b9"}, + {file = "numpy-2.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7a0e27186e781a69959d0230dd9909b5e26024f8da10683bd6344baea1885168"}, + {file = "numpy-2.3.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:f0a1a8476ad77a228e41619af2fa9505cf69df928e9aaa165746584ea17fed2b"}, + {file = "numpy-2.3.2-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:cbc95b3813920145032412f7e33d12080f11dc776262df1712e1638207dde9e8"}, + {file = "numpy-2.3.2-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f75018be4980a7324edc5930fe39aa391d5734531b1926968605416ff58c332d"}, + {file = "numpy-2.3.2-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:20b8200721840f5621b7bd03f8dcd78de33ec522fc40dc2641aa09537df010c3"}, + {file = "numpy-2.3.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1f91e5c028504660d606340a084db4b216567ded1056ea2b4be4f9d10b67197f"}, + {file = "numpy-2.3.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:fb1752a3bb9a3ad2d6b090b88a9a0ae1cd6f004ef95f75825e2f382c183b2097"}, + {file = "numpy-2.3.2-cp311-cp311-win32.whl", hash = "sha256:4ae6863868aaee2f57503c7a5052b3a2807cf7a3914475e637a0ecd366ced220"}, + {file = "numpy-2.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:240259d6564f1c65424bcd10f435145a7644a65a6811cfc3201c4a429ba79170"}, + {file = "numpy-2.3.2-cp311-cp311-win_arm64.whl", hash = "sha256:4209f874d45f921bde2cff1ffcd8a3695f545ad2ffbef6d3d3c6768162efab89"}, + {file = "numpy-2.3.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:bc3186bea41fae9d8e90c2b4fb5f0a1f5a690682da79b92574d63f56b529080b"}, + {file = "numpy-2.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2f4f0215edb189048a3c03bd5b19345bdfa7b45a7a6f72ae5945d2a28272727f"}, + {file = "numpy-2.3.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:8b1224a734cd509f70816455c3cffe13a4f599b1bf7130f913ba0e2c0b2006c0"}, + {file = "numpy-2.3.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:3dcf02866b977a38ba3ec10215220609ab9667378a9e2150615673f3ffd6c73b"}, + {file = "numpy-2.3.2-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:572d5512df5470f50ada8d1972c5f1082d9a0b7aa5944db8084077570cf98370"}, + {file = "numpy-2.3.2-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8145dd6d10df13c559d1e4314df29695613575183fa2e2d11fac4c208c8a1f73"}, + {file = "numpy-2.3.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:103ea7063fa624af04a791c39f97070bf93b96d7af7eb23530cd087dc8dbe9dc"}, + {file = "numpy-2.3.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fc927d7f289d14f5e037be917539620603294454130b6de200091e23d27dc9be"}, + {file = "numpy-2.3.2-cp312-cp312-win32.whl", hash = "sha256:d95f59afe7f808c103be692175008bab926b59309ade3e6d25009e9a171f7036"}, + {file = "numpy-2.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:9e196ade2400c0c737d93465327d1ae7c06c7cb8a1756121ebf54b06ca183c7f"}, + {file = "numpy-2.3.2-cp312-cp312-win_arm64.whl", hash = "sha256:ee807923782faaf60d0d7331f5e86da7d5e3079e28b291973c545476c2b00d07"}, + {file = "numpy-2.3.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c8d9727f5316a256425892b043736d63e89ed15bbfe6556c5ff4d9d4448ff3b3"}, + {file = "numpy-2.3.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:efc81393f25f14d11c9d161e46e6ee348637c0a1e8a54bf9dedc472a3fae993b"}, + {file = "numpy-2.3.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:dd937f088a2df683cbb79dda9a772b62a3e5a8a7e76690612c2737f38c6ef1b6"}, + {file = "numpy-2.3.2-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:11e58218c0c46c80509186e460d79fbdc9ca1eb8d8aee39d8f2dc768eb781089"}, + {file = "numpy-2.3.2-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5ad4ebcb683a1f99f4f392cc522ee20a18b2bb12a2c1c42c3d48d5a1adc9d3d2"}, + {file = "numpy-2.3.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:938065908d1d869c7d75d8ec45f735a034771c6ea07088867f713d1cd3bbbe4f"}, + {file = "numpy-2.3.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:66459dccc65d8ec98cc7df61307b64bf9e08101f9598755d42d8ae65d9a7a6ee"}, + {file = "numpy-2.3.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a7af9ed2aa9ec5950daf05bb11abc4076a108bd3c7db9aa7251d5f107079b6a6"}, + {file = "numpy-2.3.2-cp313-cp313-win32.whl", hash = "sha256:906a30249315f9c8e17b085cc5f87d3f369b35fedd0051d4a84686967bdbbd0b"}, + {file = "numpy-2.3.2-cp313-cp313-win_amd64.whl", hash = "sha256:c63d95dc9d67b676e9108fe0d2182987ccb0f11933c1e8959f42fa0da8d4fa56"}, + {file = "numpy-2.3.2-cp313-cp313-win_arm64.whl", hash = "sha256:b05a89f2fb84d21235f93de47129dd4f11c16f64c87c33f5e284e6a3a54e43f2"}, + {file = "numpy-2.3.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4e6ecfeddfa83b02318f4d84acf15fbdbf9ded18e46989a15a8b6995dfbf85ab"}, + {file = "numpy-2.3.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:508b0eada3eded10a3b55725b40806a4b855961040180028f52580c4729916a2"}, + {file = "numpy-2.3.2-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:754d6755d9a7588bdc6ac47dc4ee97867271b17cee39cb87aef079574366db0a"}, + {file = "numpy-2.3.2-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:a9f66e7d2b2d7712410d3bc5684149040ef5f19856f20277cd17ea83e5006286"}, + {file = "numpy-2.3.2-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:de6ea4e5a65d5a90c7d286ddff2b87f3f4ad61faa3db8dabe936b34c2275b6f8"}, + {file = "numpy-2.3.2-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a3ef07ec8cbc8fc9e369c8dcd52019510c12da4de81367d8b20bc692aa07573a"}, + {file = "numpy-2.3.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:27c9f90e7481275c7800dc9c24b7cc40ace3fdb970ae4d21eaff983a32f70c91"}, + {file = "numpy-2.3.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:07b62978075b67eee4065b166d000d457c82a1efe726cce608b9db9dd66a73a5"}, + {file = "numpy-2.3.2-cp313-cp313t-win32.whl", hash = "sha256:c771cfac34a4f2c0de8e8c97312d07d64fd8f8ed45bc9f5726a7e947270152b5"}, + {file = "numpy-2.3.2-cp313-cp313t-win_amd64.whl", hash = "sha256:72dbebb2dcc8305c431b2836bcc66af967df91be793d63a24e3d9b741374c450"}, + {file = "numpy-2.3.2-cp313-cp313t-win_arm64.whl", hash = "sha256:72c6df2267e926a6d5286b0a6d556ebe49eae261062059317837fda12ddf0c1a"}, + {file = "numpy-2.3.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:448a66d052d0cf14ce9865d159bfc403282c9bc7bb2a31b03cc18b651eca8b1a"}, + {file = "numpy-2.3.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:546aaf78e81b4081b2eba1d105c3b34064783027a06b3ab20b6eba21fb64132b"}, + {file = "numpy-2.3.2-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:87c930d52f45df092f7578889711a0768094debf73cfcde105e2d66954358125"}, + {file = "numpy-2.3.2-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:8dc082ea901a62edb8f59713c6a7e28a85daddcb67454c839de57656478f5b19"}, + {file = "numpy-2.3.2-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:af58de8745f7fa9ca1c0c7c943616c6fe28e75d0c81f5c295810e3c83b5be92f"}, + {file = "numpy-2.3.2-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed5527c4cf10f16c6d0b6bee1f89958bccb0ad2522c8cadc2efd318bcd545f5"}, + {file = "numpy-2.3.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:095737ed986e00393ec18ec0b21b47c22889ae4b0cd2d5e88342e08b01141f58"}, + {file = "numpy-2.3.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b5e40e80299607f597e1a8a247ff8d71d79c5b52baa11cc1cce30aa92d2da6e0"}, + {file = "numpy-2.3.2-cp314-cp314-win32.whl", hash = "sha256:7d6e390423cc1f76e1b8108c9b6889d20a7a1f59d9a60cac4a050fa734d6c1e2"}, + {file = "numpy-2.3.2-cp314-cp314-win_amd64.whl", hash = "sha256:b9d0878b21e3918d76d2209c924ebb272340da1fb51abc00f986c258cd5e957b"}, + {file = "numpy-2.3.2-cp314-cp314-win_arm64.whl", hash = "sha256:2738534837c6a1d0c39340a190177d7d66fdf432894f469728da901f8f6dc910"}, + {file = "numpy-2.3.2-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:4d002ecf7c9b53240be3bb69d80f86ddbd34078bae04d87be81c1f58466f264e"}, + {file = "numpy-2.3.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:293b2192c6bcce487dbc6326de5853787f870aeb6c43f8f9c6496db5b1781e45"}, + {file = "numpy-2.3.2-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:0a4f2021a6da53a0d580d6ef5db29947025ae8b35b3250141805ea9a32bbe86b"}, + {file = "numpy-2.3.2-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:9c144440db4bf3bb6372d2c3e49834cc0ff7bb4c24975ab33e01199e645416f2"}, + {file = "numpy-2.3.2-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f92d6c2a8535dc4fe4419562294ff957f83a16ebdec66df0805e473ffaad8bd0"}, + {file = "numpy-2.3.2-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cefc2219baa48e468e3db7e706305fcd0c095534a192a08f31e98d83a7d45fb0"}, + {file = "numpy-2.3.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:76c3e9501ceb50b2ff3824c3589d5d1ab4ac857b0ee3f8f49629d0de55ecf7c2"}, + {file = "numpy-2.3.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:122bf5ed9a0221b3419672493878ba4967121514b1d7d4656a7580cd11dddcbf"}, + {file = "numpy-2.3.2-cp314-cp314t-win32.whl", hash = "sha256:6f1ae3dcb840edccc45af496f312528c15b1f79ac318169d094e85e4bb35fdf1"}, + {file = "numpy-2.3.2-cp314-cp314t-win_amd64.whl", hash = "sha256:087ffc25890d89a43536f75c5fe8770922008758e8eeeef61733957041ed2f9b"}, + {file = "numpy-2.3.2-cp314-cp314t-win_arm64.whl", hash = "sha256:092aeb3449833ea9c0bf0089d70c29ae480685dd2377ec9cdbbb620257f84631"}, + {file = "numpy-2.3.2-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:14a91ebac98813a49bc6aa1a0dfc09513dcec1d97eaf31ca21a87221a1cdcb15"}, + {file = "numpy-2.3.2-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:71669b5daae692189540cffc4c439468d35a3f84f0c88b078ecd94337f6cb0ec"}, + {file = "numpy-2.3.2-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:69779198d9caee6e547adb933941ed7520f896fd9656834c300bdf4dd8642712"}, + {file = "numpy-2.3.2-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:2c3271cc4097beb5a60f010bcc1cc204b300bb3eafb4399376418a83a1c6373c"}, + {file = "numpy-2.3.2-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8446acd11fe3dc1830568c941d44449fd5cb83068e5c70bd5a470d323d448296"}, + {file = "numpy-2.3.2-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:aa098a5ab53fa407fded5870865c6275a5cd4101cfdef8d6fafc48286a96e981"}, + {file = "numpy-2.3.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:6936aff90dda378c09bea075af0d9c675fe3a977a9d2402f95a87f440f59f619"}, + {file = "numpy-2.3.2.tar.gz", hash = "sha256:e0486a11ec30cdecb53f184d496d1c6a20786c81e55e41640270130056f8ee48"}, +] + +[[package]] +name = "openpyxl" +version = "3.1.5" +description = "A Python library to read/write Excel 2010 xlsx/xlsm files" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "openpyxl-3.1.5-py2.py3-none-any.whl", hash = "sha256:5282c12b107bffeef825f4617dc029afaf41d0ea60823bbb665ef3079dc79de2"}, + {file = "openpyxl-3.1.5.tar.gz", hash = "sha256:cf0e3cf56142039133628b5acffe8ef0c12bc902d2aadd3e0fe5878dc08d1050"}, +] + +[package.dependencies] +et-xmlfile = "*" + +[[package]] +name = "orjson" +version = "3.11.1" +description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "orjson-3.11.1-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:92d771c492b64119456afb50f2dff3e03a2db8b5af0eba32c5932d306f970532"}, + {file = "orjson-3.11.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0085ef83a4141c2ed23bfec5fecbfdb1e95dd42fc8e8c76057bdeeec1608ea65"}, + {file = "orjson-3.11.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5caf7f13f2e1b4e137060aed892d4541d07dabc3f29e6d891e2383c7ed483440"}, + {file = "orjson-3.11.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f716bcc166524eddfcf9f13f8209ac19a7f27b05cf591e883419079d98c8c99d"}, + {file = "orjson-3.11.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:507d6012fab05465d8bf21f5d7f4635ba4b6d60132874e349beff12fb51af7fe"}, + {file = "orjson-3.11.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b1545083b0931f754c80fd2422a73d83bea7a6d1b6de104a5f2c8dd3d64c291e"}, + {file = "orjson-3.11.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e217ce3bad76351e1eb29ebe5ca630326f45cd2141f62620107a229909501a3"}, + {file = "orjson-3.11.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:06ef26e009304bda4df42e4afe518994cde6f89b4b04c0ff24021064f83f4fbb"}, + {file = "orjson-3.11.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:ba49683b87bea3ae1489a88e766e767d4f423a669a61270b6d6a7ead1c33bd65"}, + {file = "orjson-3.11.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:5072488fcc5cbcda2ece966d248e43ea1d222e19dd4c56d3f82747777f24d864"}, + {file = "orjson-3.11.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f58ae2bcd119226fe4aa934b5880fe57b8e97b69e51d5d91c88a89477a307016"}, + {file = "orjson-3.11.1-cp310-cp310-win32.whl", hash = "sha256:6723be919c07906781b9c63cc52dc7d2fb101336c99dd7e85d3531d73fb493f7"}, + {file = "orjson-3.11.1-cp310-cp310-win_amd64.whl", hash = "sha256:5fd44d69ddfdfb4e8d0d83f09d27a4db34930fba153fbf79f8d4ae8b47914e04"}, + {file = "orjson-3.11.1-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:15e2a57ce3b57c1a36acffcc02e823afefceee0a532180c2568c62213c98e3ef"}, + {file = "orjson-3.11.1-cp311-cp311-macosx_15_0_arm64.whl", hash = "sha256:17040a83ecaa130474af05bbb59a13cfeb2157d76385556041f945da936b1afd"}, + {file = "orjson-3.11.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a68f23f09e5626cc0867a96cf618f68b91acb4753d33a80bf16111fd7f9928c"}, + {file = "orjson-3.11.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:47e07528bb6ccbd6e32a55e330979048b59bfc5518b47c89bc7ab9e3de15174a"}, + {file = "orjson-3.11.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3807cce72bf40a9d251d689cbec28d2efd27e0f6673709f948f971afd52cb09"}, + {file = "orjson-3.11.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b2dc7e88da4ca201c940f5e6127998d9e89aa64264292334dad62854bc7fc27"}, + {file = "orjson-3.11.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3091dad33ac9e67c0a550cfff8ad5be156e2614d6f5d2a9247df0627751a1495"}, + {file = "orjson-3.11.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ed0fce2307843b79a0c83de49f65b86197f1e2310de07af9db2a1a77a61ce4c"}, + {file = "orjson-3.11.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5a31e84782a18c30abd56774c0cfa7b9884589f4d37d9acabfa0504dad59bb9d"}, + {file = "orjson-3.11.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:26b6c821abf1ae515fbb8e140a2406c9f9004f3e52acb780b3dee9bfffddbd84"}, + {file = "orjson-3.11.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f857b3d134b36a8436f1e24dcb525b6b945108b30746c1b0b556200b5cb76d39"}, + {file = "orjson-3.11.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:df146f2a14116ce80f7da669785fcb411406d8e80136558b0ecda4c924b9ac55"}, + {file = "orjson-3.11.1-cp311-cp311-win32.whl", hash = "sha256:d777c57c1f86855fe5492b973f1012be776e0398571f7cc3970e9a58ecf4dc17"}, + {file = "orjson-3.11.1-cp311-cp311-win_amd64.whl", hash = "sha256:e9a5fd589951f02ec2fcb8d69339258bbf74b41b104c556e6d4420ea5e059313"}, + {file = "orjson-3.11.1-cp311-cp311-win_arm64.whl", hash = "sha256:4cddbe41ee04fddad35d75b9cf3e3736ad0b80588280766156b94783167777af"}, + {file = "orjson-3.11.1-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2b7c8be96db3a977367250c6367793a3c5851a6ca4263f92f0b48d00702f9910"}, + {file = "orjson-3.11.1-cp312-cp312-macosx_15_0_arm64.whl", hash = "sha256:72e18088f567bd4a45db5e3196677d9ed1605e356e500c8e32dd6e303167a13d"}, + {file = "orjson-3.11.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d346e2ae1ce17888f7040b65a5a4a0c9734cb20ffbd228728661e020b4c8b3a5"}, + {file = "orjson-3.11.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4bda5426ebb02ceb806a7d7ec9ba9ee5e0c93fca62375151a7b1c00bc634d06b"}, + {file = "orjson-3.11.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:10506cebe908542c4f024861102673db534fd2e03eb9b95b30d94438fa220abf"}, + {file = "orjson-3.11.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:45202ee3f5494644e064c41abd1320497fb92fd31fc73af708708af664ac3b56"}, + {file = "orjson-3.11.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5adaf01b92e0402a9ac5c3ebe04effe2bbb115f0914a0a53d34ea239a746289"}, + {file = "orjson-3.11.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6162a1a757a1f1f4a94bc6ffac834a3602e04ad5db022dd8395a54ed9dd51c81"}, + {file = "orjson-3.11.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:78404206977c9f946613d3f916727c189d43193e708d760ea5d4b2087d6b0968"}, + {file = "orjson-3.11.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:db48f8e81072e26df6cdb0e9fff808c28597c6ac20a13d595756cf9ba1fed48a"}, + {file = "orjson-3.11.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0c1e394e67ced6bb16fea7054d99fbdd99a539cf4d446d40378d4c06e0a8548d"}, + {file = "orjson-3.11.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e7a840752c93d4eecd1378e9bb465c3703e127b58f675cd5c620f361b6cf57a4"}, + {file = "orjson-3.11.1-cp312-cp312-win32.whl", hash = "sha256:4537b0e09f45d2b74cb69c7f39ca1e62c24c0488d6bf01cd24673c74cd9596bf"}, + {file = "orjson-3.11.1-cp312-cp312-win_amd64.whl", hash = "sha256:dbee6b050062540ae404530cacec1bf25e56e8d87d8d9b610b935afeb6725cae"}, + {file = "orjson-3.11.1-cp312-cp312-win_arm64.whl", hash = "sha256:f55e557d4248322d87c4673e085c7634039ff04b47bfc823b87149ae12bef60d"}, + {file = "orjson-3.11.1-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:53cfefe4af059e65aabe9683f76b9c88bf34b4341a77d329227c2424e0e59b0e"}, + {file = "orjson-3.11.1-cp313-cp313-macosx_15_0_arm64.whl", hash = "sha256:93d5abed5a6f9e1b6f9b5bf6ed4423c11932b5447c2f7281d3b64e0f26c6d064"}, + {file = "orjson-3.11.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5dbf06642f3db2966df504944cdd0eb68ca2717f0353bb20b20acd78109374a6"}, + {file = "orjson-3.11.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dddf4e78747fa7f2188273f84562017a3c4f0824485b78372513c1681ea7a894"}, + {file = "orjson-3.11.1-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fa3fe8653c9f57f0e16f008e43626485b6723b84b2f741f54d1258095b655912"}, + {file = "orjson-3.11.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6334d2382aff975a61f6f4d1c3daf39368b887c7de08f7c16c58f485dcf7adb2"}, + {file = "orjson-3.11.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a3d0855b643f259ee0cb76fe3df4c04483354409a520a902b067c674842eb6b8"}, + {file = "orjson-3.11.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0eacdfeefd0a79987926476eb16e0245546bedeb8febbbbcf4b653e79257a8e4"}, + {file = "orjson-3.11.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0ed07faf9e4873518c60480325dcbc16d17c59a165532cccfb409b4cdbaeff24"}, + {file = "orjson-3.11.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:d6d308dd578ae3658f62bb9eba54801533225823cd3248c902be1ebc79b5e014"}, + {file = "orjson-3.11.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:c4aa13ca959ba6b15c0a98d3d204b850f9dc36c08c9ce422ffb024eb30d6e058"}, + {file = "orjson-3.11.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:be3d0653322abc9b68e5bcdaee6cfd58fcbe9973740ab222b87f4d687232ab1f"}, + {file = "orjson-3.11.1-cp313-cp313-win32.whl", hash = "sha256:4dd34e7e2518de8d7834268846f8cab7204364f427c56fb2251e098da86f5092"}, + {file = "orjson-3.11.1-cp313-cp313-win_amd64.whl", hash = "sha256:d6895d32032b6362540e6d0694b19130bb4f2ad04694002dce7d8af588ca5f77"}, + {file = "orjson-3.11.1-cp313-cp313-win_arm64.whl", hash = "sha256:bb7c36d5d3570fcbb01d24fa447a21a7fe5a41141fd88e78f7994053cc4e28f4"}, + {file = "orjson-3.11.1-cp314-cp314-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:7b71ef394327b3d0b39f6ea7ade2ecda2731a56c6a7cbf0d6a7301203b92a89b"}, + {file = "orjson-3.11.1-cp314-cp314-macosx_15_0_arm64.whl", hash = "sha256:77c0fe28ed659b62273995244ae2aa430e432c71f86e4573ab16caa2f2e3ca5e"}, + {file = "orjson-3.11.1-cp314-cp314-manylinux_2_34_aarch64.whl", hash = "sha256:1495692f1f1ba2467df429343388a0ed259382835922e124c0cfdd56b3d1f727"}, + {file = "orjson-3.11.1-cp314-cp314-manylinux_2_34_x86_64.whl", hash = "sha256:08c6a762fca63ca4dc04f66c48ea5d2428db55839fec996890e1bfaf057b658c"}, + {file = "orjson-3.11.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:9e26794fe3976810b2c01fda29bd9ac7c91a3c1284b29cc9a383989f7b614037"}, + {file = "orjson-3.11.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:4b4b4f8f0b1d3ef8dc73e55363a0ffe012a42f4e2f1a140bf559698dca39b3fa"}, + {file = "orjson-3.11.1-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:848be553ea35aa89bfefbed2e27c8a41244c862956ab8ba00dc0b27e84fd58de"}, + {file = "orjson-3.11.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c964c29711a4b1df52f8d9966f015402a6cf87753a406c1c4405c407dd66fd45"}, + {file = "orjson-3.11.1-cp314-cp314-win32.whl", hash = "sha256:33aada2e6b6bc9c540d396528b91e666cedb383740fee6e6a917f561b390ecb1"}, + {file = "orjson-3.11.1-cp314-cp314-win_amd64.whl", hash = "sha256:68e10fd804e44e36188b9952543e3fa22f5aa8394da1b5283ca2b423735c06e8"}, + {file = "orjson-3.11.1-cp314-cp314-win_arm64.whl", hash = "sha256:f3cf6c07f8b32127d836be8e1c55d4f34843f7df346536da768e9f73f22078a1"}, + {file = "orjson-3.11.1-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:3d593a9e0bccf2c7401ae53625b519a7ad7aa555b1c82c0042b322762dc8af4e"}, + {file = "orjson-3.11.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0baad413c498fc1eef568504f11ea46bc71f94b845c075e437da1e2b85b4fb86"}, + {file = "orjson-3.11.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:22cf17ae1dae3f9b5f37bfcdba002ed22c98bbdb70306e42dc18d8cc9b50399a"}, + {file = "orjson-3.11.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e855c1e97208133ce88b3ef6663c9a82ddf1d09390cd0856a1638deee0390c3c"}, + {file = "orjson-3.11.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b5861c5f7acff10599132854c70ab10abf72aebf7c627ae13575e5f20b1ab8fe"}, + {file = "orjson-3.11.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b1e6415c5b5ff3a616a6dafad7b6ec303a9fc625e9313c8e1268fb1370a63dcb"}, + {file = "orjson-3.11.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:912579642f5d7a4a84d93c5eed8daf0aa34e1f2d3f4dc6571a8e418703f5701e"}, + {file = "orjson-3.11.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2092e1d3b33f64e129ff8271642afddc43763c81f2c30823b4a4a4a5f2ea5b55"}, + {file = "orjson-3.11.1-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:b8ac64caba1add2c04e9cd4782d4d0c4d6c554b7a3369bdec1eed7854c98db7b"}, + {file = "orjson-3.11.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:23196b826ebc85c43f8e27bee0ab33c5fb13a29ea47fb4fcd6ebb1e660eb0252"}, + {file = "orjson-3.11.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f2d3364cfad43003f1e3d564a069c8866237cca30f9c914b26ed2740b596ed00"}, + {file = "orjson-3.11.1-cp39-cp39-win32.whl", hash = "sha256:20b0dca94ea4ebe4628330de50975b35817a3f52954c1efb6d5d0498a3bbe581"}, + {file = "orjson-3.11.1-cp39-cp39-win_amd64.whl", hash = "sha256:200c3ad7ed8b5d31d49143265dfebd33420c4b61934ead16833b5cd2c3d241be"}, + {file = "orjson-3.11.1.tar.gz", hash = "sha256:48d82770a5fd88778063604c566f9c7c71820270c9cc9338d25147cbf34afd96"}, +] + +[[package]] +name = "packaging" +version = "25.0" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484"}, + {file = "packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f"}, +] + +[[package]] +name = "pandas" +version = "2.3.1" +description = "Powerful data structures for data analysis, time series, and statistics" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "pandas-2.3.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:22c2e866f7209ebc3a8f08d75766566aae02bcc91d196935a1d9e59c7b990ac9"}, + {file = "pandas-2.3.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3583d348546201aff730c8c47e49bc159833f971c2899d6097bce68b9112a4f1"}, + {file = "pandas-2.3.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f951fbb702dacd390561e0ea45cdd8ecfa7fb56935eb3dd78e306c19104b9b0"}, + {file = "pandas-2.3.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cd05b72ec02ebfb993569b4931b2e16fbb4d6ad6ce80224a3ee838387d83a191"}, + {file = "pandas-2.3.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:1b916a627919a247d865aed068eb65eb91a344b13f5b57ab9f610b7716c92de1"}, + {file = "pandas-2.3.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:fe67dc676818c186d5a3d5425250e40f179c2a89145df477dd82945eaea89e97"}, + {file = "pandas-2.3.1-cp310-cp310-win_amd64.whl", hash = "sha256:2eb789ae0274672acbd3c575b0598d213345660120a257b47b5dafdc618aec83"}, + {file = "pandas-2.3.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2b0540963d83431f5ce8870ea02a7430adca100cec8a050f0811f8e31035541b"}, + {file = "pandas-2.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fe7317f578c6a153912bd2292f02e40c1d8f253e93c599e82620c7f69755c74f"}, + {file = "pandas-2.3.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e6723a27ad7b244c0c79d8e7007092d7c8f0f11305770e2f4cd778b3ad5f9f85"}, + {file = "pandas-2.3.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3462c3735fe19f2638f2c3a40bd94ec2dc5ba13abbb032dd2fa1f540a075509d"}, + {file = "pandas-2.3.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:98bcc8b5bf7afed22cc753a28bc4d9e26e078e777066bc53fac7904ddef9a678"}, + {file = "pandas-2.3.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4d544806b485ddf29e52d75b1f559142514e60ef58a832f74fb38e48d757b299"}, + {file = "pandas-2.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:b3cd4273d3cb3707b6fffd217204c52ed92859533e31dc03b7c5008aa933aaab"}, + {file = "pandas-2.3.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:689968e841136f9e542020698ee1c4fbe9caa2ed2213ae2388dc7b81721510d3"}, + {file = "pandas-2.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:025e92411c16cbe5bb2a4abc99732a6b132f439b8aab23a59fa593eb00704232"}, + {file = "pandas-2.3.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b7ff55f31c4fcb3e316e8f7fa194566b286d6ac430afec0d461163312c5841e"}, + {file = "pandas-2.3.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7dcb79bf373a47d2a40cf7232928eb7540155abbc460925c2c96d2d30b006eb4"}, + {file = "pandas-2.3.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:56a342b231e8862c96bdb6ab97170e203ce511f4d0429589c8ede1ee8ece48b8"}, + {file = "pandas-2.3.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ca7ed14832bce68baef331f4d7f294411bed8efd032f8109d690df45e00c4679"}, + {file = "pandas-2.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:ac942bfd0aca577bef61f2bc8da8147c4ef6879965ef883d8e8d5d2dc3e744b8"}, + {file = "pandas-2.3.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9026bd4a80108fac2239294a15ef9003c4ee191a0f64b90f170b40cfb7cf2d22"}, + {file = "pandas-2.3.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6de8547d4fdb12421e2d047a2c446c623ff4c11f47fddb6b9169eb98ffba485a"}, + {file = "pandas-2.3.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:782647ddc63c83133b2506912cc6b108140a38a37292102aaa19c81c83db2928"}, + {file = "pandas-2.3.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ba6aff74075311fc88504b1db890187a3cd0f887a5b10f5525f8e2ef55bfdb9"}, + {file = "pandas-2.3.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e5635178b387bd2ba4ac040f82bc2ef6e6b500483975c4ebacd34bec945fda12"}, + {file = "pandas-2.3.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6f3bf5ec947526106399a9e1d26d40ee2b259c66422efdf4de63c848492d91bb"}, + {file = "pandas-2.3.1-cp313-cp313-win_amd64.whl", hash = "sha256:1c78cf43c8fde236342a1cb2c34bcff89564a7bfed7e474ed2fffa6aed03a956"}, + {file = "pandas-2.3.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:8dfc17328e8da77be3cf9f47509e5637ba8f137148ed0e9b5241e1baf526e20a"}, + {file = "pandas-2.3.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:ec6c851509364c59a5344458ab935e6451b31b818be467eb24b0fe89bd05b6b9"}, + {file = "pandas-2.3.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:911580460fc4884d9b05254b38a6bfadddfcc6aaef856fb5859e7ca202e45275"}, + {file = "pandas-2.3.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2f4d6feeba91744872a600e6edbbd5b033005b431d5ae8379abee5bcfa479fab"}, + {file = "pandas-2.3.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:fe37e757f462d31a9cd7580236a82f353f5713a80e059a29753cf938c6775d96"}, + {file = "pandas-2.3.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:5db9637dbc24b631ff3707269ae4559bce4b7fd75c1c4d7e13f40edc42df4444"}, + {file = "pandas-2.3.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4645f770f98d656f11c69e81aeb21c6fca076a44bed3dcbb9396a4311bc7f6d8"}, + {file = "pandas-2.3.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:342e59589cc454aaff7484d75b816a433350b3d7964d7847327edda4d532a2e3"}, + {file = "pandas-2.3.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d12f618d80379fde6af007f65f0c25bd3e40251dbd1636480dfffce2cf1e6da"}, + {file = "pandas-2.3.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd71c47a911da120d72ef173aeac0bf5241423f9bfea57320110a978457e069e"}, + {file = "pandas-2.3.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:09e3b1587f0f3b0913e21e8b32c3119174551deb4a4eba4a89bc7377947977e7"}, + {file = "pandas-2.3.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2323294c73ed50f612f67e2bf3ae45aea04dce5690778e08a09391897f35ff88"}, + {file = "pandas-2.3.1-cp39-cp39-win_amd64.whl", hash = "sha256:b4b0de34dc8499c2db34000ef8baad684cfa4cbd836ecee05f323ebfba348c7d"}, + {file = "pandas-2.3.1.tar.gz", hash = "sha256:0a95b9ac964fe83ce317827f80304d37388ea77616b1425f0ae41c9d2d0d7bb2"}, +] + +[package.dependencies] +numpy = {version = ">=1.26.0", markers = "python_version >= \"3.12\""} +python-dateutil = ">=2.8.2" +pytz = ">=2020.1" +tzdata = ">=2022.7" + +[package.extras] +all = ["PyQt5 (>=5.15.9)", "SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)", "beautifulsoup4 (>=4.11.2)", "bottleneck (>=1.3.6)", "dataframe-api-compat (>=0.1.7)", "fastparquet (>=2022.12.0)", "fsspec (>=2022.11.0)", "gcsfs (>=2022.11.0)", "html5lib (>=1.1)", "hypothesis (>=6.46.1)", "jinja2 (>=3.1.2)", "lxml (>=4.9.2)", "matplotlib (>=3.6.3)", "numba (>=0.56.4)", "numexpr (>=2.8.4)", "odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "pandas-gbq (>=0.19.0)", "psycopg2 (>=2.9.6)", "pyarrow (>=10.0.1)", "pymysql (>=1.0.2)", "pyreadstat (>=1.2.0)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "qtpy (>=2.3.0)", "s3fs (>=2022.11.0)", "scipy (>=1.10.0)", "tables (>=3.8.0)", "tabulate (>=0.9.0)", "xarray (>=2022.12.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)", "zstandard (>=0.19.0)"] +aws = ["s3fs (>=2022.11.0)"] +clipboard = ["PyQt5 (>=5.15.9)", "qtpy (>=2.3.0)"] +compression = ["zstandard (>=0.19.0)"] +computation = ["scipy (>=1.10.0)", "xarray (>=2022.12.0)"] +consortium-standard = ["dataframe-api-compat (>=0.1.7)"] +excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)"] +feather = ["pyarrow (>=10.0.1)"] +fss = ["fsspec (>=2022.11.0)"] +gcp = ["gcsfs (>=2022.11.0)", "pandas-gbq (>=0.19.0)"] +hdf5 = ["tables (>=3.8.0)"] +html = ["beautifulsoup4 (>=4.11.2)", "html5lib (>=1.1)", "lxml (>=4.9.2)"] +mysql = ["SQLAlchemy (>=2.0.0)", "pymysql (>=1.0.2)"] +output-formatting = ["jinja2 (>=3.1.2)", "tabulate (>=0.9.0)"] +parquet = ["pyarrow (>=10.0.1)"] +performance = ["bottleneck (>=1.3.6)", "numba (>=0.56.4)", "numexpr (>=2.8.4)"] +plot = ["matplotlib (>=3.6.3)"] +postgresql = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "psycopg2 (>=2.9.6)"] +pyarrow = ["pyarrow (>=10.0.1)"] +spss = ["pyreadstat (>=1.2.0)"] +sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)"] +test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"] +xml = ["lxml (>=4.9.2)"] + +[[package]] +name = "pfzy" +version = "0.3.4" +description = "Python port of the fzy fuzzy string matching algorithm" +optional = false +python-versions = ">=3.7,<4.0" +groups = ["main"] +files = [ + {file = "pfzy-0.3.4-py3-none-any.whl", hash = "sha256:5f50d5b2b3207fa72e7ec0ef08372ef652685470974a107d0d4999fc5a903a96"}, + {file = "pfzy-0.3.4.tar.gz", hash = "sha256:717ea765dd10b63618e7298b2d98efd819e0b30cd5905c9707223dceeb94b3f1"}, +] + +[package.extras] +docs = ["Sphinx (>=4.1.2,<5.0.0)", "furo (>=2021.8.17-beta.43,<2022.0.0)", "myst-parser (>=0.15.1,<0.16.0)", "sphinx-autobuild (>=2021.3.14,<2022.0.0)", "sphinx-copybutton (>=0.4.0,<0.5.0)"] + +[[package]] +name = "pillow" +version = "11.3.0" +description = "Python Imaging Library (Fork)" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "pillow-11.3.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:1b9c17fd4ace828b3003dfd1e30bff24863e0eb59b535e8f80194d9cc7ecf860"}, + {file = "pillow-11.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:65dc69160114cdd0ca0f35cb434633c75e8e7fad4cf855177a05bf38678f73ad"}, + {file = "pillow-11.3.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7107195ddc914f656c7fc8e4a5e1c25f32e9236ea3ea860f257b0436011fddd0"}, + {file = "pillow-11.3.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:cc3e831b563b3114baac7ec2ee86819eb03caa1a2cef0b481a5675b59c4fe23b"}, + {file = "pillow-11.3.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f1f182ebd2303acf8c380a54f615ec883322593320a9b00438eb842c1f37ae50"}, + {file = "pillow-11.3.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4445fa62e15936a028672fd48c4c11a66d641d2c05726c7ec1f8ba6a572036ae"}, + {file = "pillow-11.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:71f511f6b3b91dd543282477be45a033e4845a40278fa8dcdbfdb07109bf18f9"}, + {file = "pillow-11.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:040a5b691b0713e1f6cbe222e0f4f74cd233421e105850ae3b3c0ceda520f42e"}, + {file = "pillow-11.3.0-cp310-cp310-win32.whl", hash = "sha256:89bd777bc6624fe4115e9fac3352c79ed60f3bb18651420635f26e643e3dd1f6"}, + {file = "pillow-11.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:19d2ff547c75b8e3ff46f4d9ef969a06c30ab2d4263a9e287733aa8b2429ce8f"}, + {file = "pillow-11.3.0-cp310-cp310-win_arm64.whl", hash = "sha256:819931d25e57b513242859ce1876c58c59dc31587847bf74cfe06b2e0cb22d2f"}, + {file = "pillow-11.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:1cd110edf822773368b396281a2293aeb91c90a2db00d78ea43e7e861631b722"}, + {file = "pillow-11.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9c412fddd1b77a75aa904615ebaa6001f169b26fd467b4be93aded278266b288"}, + {file = "pillow-11.3.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7d1aa4de119a0ecac0a34a9c8bde33f34022e2e8f99104e47a3ca392fd60e37d"}, + {file = "pillow-11.3.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:91da1d88226663594e3f6b4b8c3c8d85bd504117d043740a8e0ec449087cc494"}, + {file = "pillow-11.3.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:643f189248837533073c405ec2f0bb250ba54598cf80e8c1e043381a60632f58"}, + {file = "pillow-11.3.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:106064daa23a745510dabce1d84f29137a37224831d88eb4ce94bb187b1d7e5f"}, + {file = "pillow-11.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cd8ff254faf15591e724dc7c4ddb6bf4793efcbe13802a4ae3e863cd300b493e"}, + {file = "pillow-11.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:932c754c2d51ad2b2271fd01c3d121daaa35e27efae2a616f77bf164bc0b3e94"}, + {file = "pillow-11.3.0-cp311-cp311-win32.whl", hash = "sha256:b4b8f3efc8d530a1544e5962bd6b403d5f7fe8b9e08227c6b255f98ad82b4ba0"}, + {file = "pillow-11.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:1a992e86b0dd7aeb1f053cd506508c0999d710a8f07b4c791c63843fc6a807ac"}, + {file = "pillow-11.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:30807c931ff7c095620fe04448e2c2fc673fcbb1ffe2a7da3fb39613489b1ddd"}, + {file = "pillow-11.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdae223722da47b024b867c1ea0be64e0df702c5e0a60e27daad39bf960dd1e4"}, + {file = "pillow-11.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:921bd305b10e82b4d1f5e802b6850677f965d8394203d182f078873851dada69"}, + {file = "pillow-11.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:eb76541cba2f958032d79d143b98a3a6b3ea87f0959bbe256c0b5e416599fd5d"}, + {file = "pillow-11.3.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:67172f2944ebba3d4a7b54f2e95c786a3a50c21b88456329314caaa28cda70f6"}, + {file = "pillow-11.3.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:97f07ed9f56a3b9b5f49d3661dc9607484e85c67e27f3e8be2c7d28ca032fec7"}, + {file = "pillow-11.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:676b2815362456b5b3216b4fd5bd89d362100dc6f4945154ff172e206a22c024"}, + {file = "pillow-11.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3e184b2f26ff146363dd07bde8b711833d7b0202e27d13540bfe2e35a323a809"}, + {file = "pillow-11.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6be31e3fc9a621e071bc17bb7de63b85cbe0bfae91bb0363c893cbe67247780d"}, + {file = "pillow-11.3.0-cp312-cp312-win32.whl", hash = "sha256:7b161756381f0918e05e7cb8a371fff367e807770f8fe92ecb20d905d0e1c149"}, + {file = "pillow-11.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:a6444696fce635783440b7f7a9fc24b3ad10a9ea3f0ab66c5905be1c19ccf17d"}, + {file = "pillow-11.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:2aceea54f957dd4448264f9bf40875da0415c83eb85f55069d89c0ed436e3542"}, + {file = "pillow-11.3.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:1c627742b539bba4309df89171356fcb3cc5a9178355b2727d1b74a6cf155fbd"}, + {file = "pillow-11.3.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:30b7c02f3899d10f13d7a48163c8969e4e653f8b43416d23d13d1bbfdc93b9f8"}, + {file = "pillow-11.3.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:7859a4cc7c9295f5838015d8cc0a9c215b77e43d07a25e460f35cf516df8626f"}, + {file = "pillow-11.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ec1ee50470b0d050984394423d96325b744d55c701a439d2bd66089bff963d3c"}, + {file = "pillow-11.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7db51d222548ccfd274e4572fdbf3e810a5e66b00608862f947b163e613b67dd"}, + {file = "pillow-11.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2d6fcc902a24ac74495df63faad1884282239265c6839a0a6416d33faedfae7e"}, + {file = "pillow-11.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f0f5d8f4a08090c6d6d578351a2b91acf519a54986c055af27e7a93feae6d3f1"}, + {file = "pillow-11.3.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c37d8ba9411d6003bba9e518db0db0c58a680ab9fe5179f040b0463644bc9805"}, + {file = "pillow-11.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:13f87d581e71d9189ab21fe0efb5a23e9f28552d5be6979e84001d3b8505abe8"}, + {file = "pillow-11.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:023f6d2d11784a465f09fd09a34b150ea4672e85fb3d05931d89f373ab14abb2"}, + {file = "pillow-11.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:45dfc51ac5975b938e9809451c51734124e73b04d0f0ac621649821a63852e7b"}, + {file = "pillow-11.3.0-cp313-cp313-win32.whl", hash = "sha256:a4d336baed65d50d37b88ca5b60c0fa9d81e3a87d4a7930d3880d1624d5b31f3"}, + {file = "pillow-11.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:0bce5c4fd0921f99d2e858dc4d4d64193407e1b99478bc5cacecba2311abde51"}, + {file = "pillow-11.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:1904e1264881f682f02b7f8167935cce37bc97db457f8e7849dc3a6a52b99580"}, + {file = "pillow-11.3.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4c834a3921375c48ee6b9624061076bc0a32a60b5532b322cc0ea64e639dd50e"}, + {file = "pillow-11.3.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5e05688ccef30ea69b9317a9ead994b93975104a677a36a8ed8106be9260aa6d"}, + {file = "pillow-11.3.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1019b04af07fc0163e2810167918cb5add8d74674b6267616021ab558dc98ced"}, + {file = "pillow-11.3.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f944255db153ebb2b19c51fe85dd99ef0ce494123f21b9db4877ffdfc5590c7c"}, + {file = "pillow-11.3.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1f85acb69adf2aaee8b7da124efebbdb959a104db34d3a2cb0f3793dbae422a8"}, + {file = "pillow-11.3.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:05f6ecbeff5005399bb48d198f098a9b4b6bdf27b8487c7f38ca16eeb070cd59"}, + {file = "pillow-11.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a7bc6e6fd0395bc052f16b1a8670859964dbd7003bd0af2ff08342eb6e442cfe"}, + {file = "pillow-11.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:83e1b0161c9d148125083a35c1c5a89db5b7054834fd4387499e06552035236c"}, + {file = "pillow-11.3.0-cp313-cp313t-win32.whl", hash = "sha256:2a3117c06b8fb646639dce83694f2f9eac405472713fcb1ae887469c0d4f6788"}, + {file = "pillow-11.3.0-cp313-cp313t-win_amd64.whl", hash = "sha256:857844335c95bea93fb39e0fa2726b4d9d758850b34075a7e3ff4f4fa3aa3b31"}, + {file = "pillow-11.3.0-cp313-cp313t-win_arm64.whl", hash = "sha256:8797edc41f3e8536ae4b10897ee2f637235c94f27404cac7297f7b607dd0716e"}, + {file = "pillow-11.3.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:d9da3df5f9ea2a89b81bb6087177fb1f4d1c7146d583a3fe5c672c0d94e55e12"}, + {file = "pillow-11.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0b275ff9b04df7b640c59ec5a3cb113eefd3795a8df80bac69646ef699c6981a"}, + {file = "pillow-11.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0743841cabd3dba6a83f38a92672cccbd69af56e3e91777b0ee7f4dba4385632"}, + {file = "pillow-11.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2465a69cf967b8b49ee1b96d76718cd98c4e925414ead59fdf75cf0fd07df673"}, + {file = "pillow-11.3.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41742638139424703b4d01665b807c6468e23e699e8e90cffefe291c5832b027"}, + {file = "pillow-11.3.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:93efb0b4de7e340d99057415c749175e24c8864302369e05914682ba642e5d77"}, + {file = "pillow-11.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7966e38dcd0fa11ca390aed7c6f20454443581d758242023cf36fcb319b1a874"}, + {file = "pillow-11.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:98a9afa7b9007c67ed84c57c9e0ad86a6000da96eaa638e4f8abe5b65ff83f0a"}, + {file = "pillow-11.3.0-cp314-cp314-win32.whl", hash = "sha256:02a723e6bf909e7cea0dac1b0e0310be9d7650cd66222a5f1c571455c0a45214"}, + {file = "pillow-11.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:a418486160228f64dd9e9efcd132679b7a02a5f22c982c78b6fc7dab3fefb635"}, + {file = "pillow-11.3.0-cp314-cp314-win_arm64.whl", hash = "sha256:155658efb5e044669c08896c0c44231c5e9abcaadbc5cd3648df2f7c0b96b9a6"}, + {file = "pillow-11.3.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:59a03cdf019efbfeeed910bf79c7c93255c3d54bc45898ac2a4140071b02b4ae"}, + {file = "pillow-11.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f8a5827f84d973d8636e9dc5764af4f0cf2318d26744b3d902931701b0d46653"}, + {file = "pillow-11.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ee92f2fd10f4adc4b43d07ec5e779932b4eb3dbfbc34790ada5a6669bc095aa6"}, + {file = "pillow-11.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c96d333dcf42d01f47b37e0979b6bd73ec91eae18614864622d9b87bbd5bbf36"}, + {file = "pillow-11.3.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4c96f993ab8c98460cd0c001447bff6194403e8b1d7e149ade5f00594918128b"}, + {file = "pillow-11.3.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:41342b64afeba938edb034d122b2dda5db2139b9a4af999729ba8818e0056477"}, + {file = "pillow-11.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:068d9c39a2d1b358eb9f245ce7ab1b5c3246c7c8c7d9ba58cfa5b43146c06e50"}, + {file = "pillow-11.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a1bc6ba083b145187f648b667e05a2534ecc4b9f2784c2cbe3089e44868f2b9b"}, + {file = "pillow-11.3.0-cp314-cp314t-win32.whl", hash = "sha256:118ca10c0d60b06d006be10a501fd6bbdfef559251ed31b794668ed569c87e12"}, + {file = "pillow-11.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:8924748b688aa210d79883357d102cd64690e56b923a186f35a82cbc10f997db"}, + {file = "pillow-11.3.0-cp314-cp314t-win_arm64.whl", hash = "sha256:79ea0d14d3ebad43ec77ad5272e6ff9bba5b679ef73375ea760261207fa8e0aa"}, + {file = "pillow-11.3.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:48d254f8a4c776de343051023eb61ffe818299eeac478da55227d96e241de53f"}, + {file = "pillow-11.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7aee118e30a4cf54fdd873bd3a29de51e29105ab11f9aad8c32123f58c8f8081"}, + {file = "pillow-11.3.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:23cff760a9049c502721bdb743a7cb3e03365fafcdfc2ef9784610714166e5a4"}, + {file = "pillow-11.3.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6359a3bc43f57d5b375d1ad54a0074318a0844d11b76abccf478c37c986d3cfc"}, + {file = "pillow-11.3.0-cp39-cp39-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:092c80c76635f5ecb10f3f83d76716165c96f5229addbd1ec2bdbbda7d496e06"}, + {file = "pillow-11.3.0-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cadc9e0ea0a2431124cde7e1697106471fc4c1da01530e679b2391c37d3fbb3a"}, + {file = "pillow-11.3.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:6a418691000f2a418c9135a7cf0d797c1bb7d9a485e61fe8e7722845b95ef978"}, + {file = "pillow-11.3.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:97afb3a00b65cc0804d1c7abddbf090a81eaac02768af58cbdcaaa0a931e0b6d"}, + {file = "pillow-11.3.0-cp39-cp39-win32.whl", hash = "sha256:ea944117a7974ae78059fcc1800e5d3295172bb97035c0c1d9345fca1419da71"}, + {file = "pillow-11.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:e5c5858ad8ec655450a7c7df532e9842cf8df7cc349df7225c60d5d348c8aada"}, + {file = "pillow-11.3.0-cp39-cp39-win_arm64.whl", hash = "sha256:6abdbfd3aea42be05702a8dd98832329c167ee84400a1d1f61ab11437f1717eb"}, + {file = "pillow-11.3.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:3cee80663f29e3843b68199b9d6f4f54bd1d4a6b59bdd91bceefc51238bcb967"}, + {file = "pillow-11.3.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b5f56c3f344f2ccaf0dd875d3e180f631dc60a51b314295a3e681fe8cf851fbe"}, + {file = "pillow-11.3.0-pp310-pypy310_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e67d793d180c9df62f1f40aee3accca4829d3794c95098887edc18af4b8b780c"}, + {file = "pillow-11.3.0-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d000f46e2917c705e9fb93a3606ee4a819d1e3aa7a9b442f6444f07e77cf5e25"}, + {file = "pillow-11.3.0-pp310-pypy310_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:527b37216b6ac3a12d7838dc3bd75208ec57c1c6d11ef01902266a5a0c14fc27"}, + {file = "pillow-11.3.0-pp310-pypy310_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:be5463ac478b623b9dd3937afd7fb7ab3d79dd290a28e2b6df292dc75063eb8a"}, + {file = "pillow-11.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:8dc70ca24c110503e16918a658b869019126ecfe03109b754c402daff12b3d9f"}, + {file = "pillow-11.3.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7c8ec7a017ad1bd562f93dbd8505763e688d388cde6e4a010ae1486916e713e6"}, + {file = "pillow-11.3.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:9ab6ae226de48019caa8074894544af5b53a117ccb9d3b3dcb2871464c829438"}, + {file = "pillow-11.3.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fe27fb049cdcca11f11a7bfda64043c37b30e6b91f10cb5bab275806c32f6ab3"}, + {file = "pillow-11.3.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:465b9e8844e3c3519a983d58b80be3f668e2a7a5db97f2784e7079fbc9f9822c"}, + {file = "pillow-11.3.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5418b53c0d59b3824d05e029669efa023bbef0f3e92e75ec8428f3799487f361"}, + {file = "pillow-11.3.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:504b6f59505f08ae014f724b6207ff6222662aab5cc9542577fb084ed0676ac7"}, + {file = "pillow-11.3.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:c84d689db21a1c397d001aa08241044aa2069e7587b398c8cc63020390b1c1b8"}, + {file = "pillow-11.3.0.tar.gz", hash = "sha256:3828ee7586cd0b2091b6209e5ad53e20d0649bbe87164a459d0676e035e8f523"}, +] + +[package.extras] +docs = ["furo", "olefile", "sphinx (>=8.2)", "sphinx-autobuild", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"] +fpx = ["olefile"] +mic = ["olefile"] +test-arrow = ["pyarrow"] +tests = ["check-manifest", "coverage (>=7.4.2)", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "trove-classifiers (>=2024.10.12)"] +typing = ["typing-extensions ; python_version < \"3.10\""] +xmp = ["defusedxml"] + +[[package]] +name = "plotly" +version = "6.2.0" +description = "An open-source interactive data visualization library for Python" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "plotly-6.2.0-py3-none-any.whl", hash = "sha256:32c444d4c940887219cb80738317040363deefdfee4f354498cc0b6dab8978bd"}, + {file = "plotly-6.2.0.tar.gz", hash = "sha256:9dfa23c328000f16c928beb68927444c1ab9eae837d1fe648dbcda5360c7953d"}, +] + +[package.dependencies] +narwhals = ">=1.15.1" +packaging = "*" + +[package.extras] +dev = ["plotly[dev-optional]"] +dev-build = ["build", "jupyter", "plotly[dev-core]"] +dev-core = ["pytest", "requests", "ruff (==0.11.12)"] +dev-optional = ["anywidget", "colorcet", "fiona (<=1.9.6) ; python_version <= \"3.8\"", "geopandas", "inflect", "numpy", "orjson", "pandas", "pdfrw", "pillow", "plotly-geo", "plotly[dev-build]", "plotly[kaleido]", "polars[timezone]", "pyarrow", "pyshp", "pytz", "scikit-image", "scipy", "shapely", "statsmodels", "vaex ; python_version <= \"3.9\"", "xarray"] +express = ["numpy"] +kaleido = ["kaleido (>=1.0.0)"] + +[[package]] +name = "prompt-toolkit" +version = "3.0.52" +description = "Library for building powerful interactive command lines in Python" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "prompt_toolkit-3.0.52-py3-none-any.whl", hash = "sha256:9aac639a3bbd33284347de5ad8d68ecc044b91a762dc39b7c21095fcd6a19955"}, + {file = "prompt_toolkit-3.0.52.tar.gz", hash = "sha256:28cde192929c8e7321de85de1ddbe736f1375148b02f2e17edd840042b1be855"}, +] + +[package.dependencies] +wcwidth = "*" + +[[package]] +name = "pydra-core" +version = "0.0.9" +description = "Python package for calculating hydraulic loads" +optional = false +python-versions = "*" +groups = ["main"] +files = [ + {file = "pydra_core-0.0.9-py2.py3-none-any.whl", hash = "sha256:7bf4c4c4c161929fadf008f3cb5a78754be22c184fa6767ee81b01025c6baac5"}, + {file = "pydra_core-0.0.9.tar.gz", hash = "sha256:9f547cb0094174d0ee338f146b42144bba048fd8ac6a50a27fd49dc29ad22940"}, +] + +[package.dependencies] +fiona = "*" +matplotlib = ">=3.9.3" +numpy = "*" +pandas = "*" +scipy = "*" +shapely = "*" + +[[package]] +name = "pygments" +version = "2.19.2" +description = "Pygments is a syntax highlighting package written in Python." +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b"}, + {file = "pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887"}, +] + +[package.extras] +windows-terminal = ["colorama (>=0.4.6)"] + +[[package]] +name = "pyogrio" +version = "0.11.1" +description = "Vectorized spatial vector file format I/O using GDAL/OGR" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "pyogrio-0.11.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:838ead7df8388d938ce848354e384ae5aa46fe7c5f74f9da2d58f064bda053f7"}, + {file = "pyogrio-0.11.1-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:6f51aa9fc3632e6dcb3dd5562b4a56a3a31850c3f630aef3587d5889a1f65275"}, + {file = "pyogrio-0.11.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4982107653ce30de395678b50a1ee00299a4cfcb41043778f1b66c5911b8adbe"}, + {file = "pyogrio-0.11.1-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:7b20ffbf72013d464012d8f0f69322459a6528bef08c85f85b8a42b056f730b0"}, + {file = "pyogrio-0.11.1-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:5b8d60ead740b366cdc2f3b076d21349e5a5d4b9a0e6726922c5a031206b93b2"}, + {file = "pyogrio-0.11.1-cp310-cp310-win_amd64.whl", hash = "sha256:1948027b2809f2248f69b069ab9833d56b53658f182a3b418d12d3d3eb9959d7"}, + {file = "pyogrio-0.11.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:d36162ddc1a309bb941a3cfb550b8f88c862c67ef2f52df6460100e5e958bbc6"}, + {file = "pyogrio-0.11.1-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:845c78d5e7c9ec1c7d00250c07e144e5fe504fdb4ccdc141d9413f85b8c55c91"}, + {file = "pyogrio-0.11.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50aa869509f189fa1bff4d90d2d4c7860b963e693af85f2957646306e882b631"}, + {file = "pyogrio-0.11.1-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:dd0f44dd2d849d32aea3f73647c74083996917e446479645bf93de6656160f2d"}, + {file = "pyogrio-0.11.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:36b910d4037694b2935b5b1c1eb757dcc2906dca05cb2992cbdaf1291b54ff97"}, + {file = "pyogrio-0.11.1-cp311-cp311-win_amd64.whl", hash = "sha256:cb744097f302f19dcc5c93ee5e9cfd707b864c9a418e399f0908406a60003728"}, + {file = "pyogrio-0.11.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:f186456ebe5d5f61e7bd883bad25a59d43d6304178d4f0d3e03273f42b40a4cc"}, + {file = "pyogrio-0.11.1-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:b8a199bc0e421eac444af96942b7553268e43d0cadf30d0d6d41017de05b7e9e"}, + {file = "pyogrio-0.11.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afce80b4b32f043fcf76a50e8572e3ad8d9d3e6abbbfa6137f0975ba55c4eeb8"}, + {file = "pyogrio-0.11.1-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:0cfd79caf0b8cb7bbf30b419dff7f21509169efcf4d431172c61b44fe1029dba"}, + {file = "pyogrio-0.11.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:ab3aa6dbf2441d2407ce052233f2966324a3cff752bd43d99e4c779ea54e0a16"}, + {file = "pyogrio-0.11.1-cp312-cp312-win_amd64.whl", hash = "sha256:cd10035eb3b5e5a43bdafbd777339d2274e9b75972658364f0ce31c4d3400d1e"}, + {file = "pyogrio-0.11.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:3b368c597357ff262f3b46591ded86409462ee594ef42556708b090d121f873c"}, + {file = "pyogrio-0.11.1-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:1cb82cfd3493f32396e9c3f9255e17885610f62a323870947f4e04dd59bc3595"}, + {file = "pyogrio-0.11.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d61aae22e67030fd354f03e21c6462537bf56160134dd8663709335a5a46b28"}, + {file = "pyogrio-0.11.1-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:76150a3cd787c31628191c7abc6f8c796660125852fb65ae15dd7be1e9196816"}, + {file = "pyogrio-0.11.1-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:e929452f6988c0365dd32ff2485d9488160a709fee28743abbbc18d663169ed0"}, + {file = "pyogrio-0.11.1-cp313-cp313-win_amd64.whl", hash = "sha256:d6d56862b89a05fccd7211171c88806b6ec9b5effb79bf807cce0a57c1f2a606"}, + {file = "pyogrio-0.11.1-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:9ae8efbe4f9f215b2321655f988be8bb133829037dbefebc2643f52da4e7782a"}, + {file = "pyogrio-0.11.1-cp39-cp39-macosx_12_0_x86_64.whl", hash = "sha256:7cbbc24a785cca733b80c96e8e10f7c316df295786ac9900c145e2b12f828050"}, + {file = "pyogrio-0.11.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e924de96f1a436567fb57cd94b02b2572c066663c5b6431d2827993d8f3a646"}, + {file = "pyogrio-0.11.1-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:580001084562b55059f161b8c8f2c15135a4523256a3b910ea3a58cd8ffb6c4f"}, + {file = "pyogrio-0.11.1-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:56d2315f28cdbde98c23f719c85a0f0ee1953a1eae617505c7349c660847dbf5"}, + {file = "pyogrio-0.11.1-cp39-cp39-win_amd64.whl", hash = "sha256:db372785b2a32ad6006477366c4c07285d98f7a7e6d356b2eba15a4fbaaa167f"}, + {file = "pyogrio-0.11.1.tar.gz", hash = "sha256:e1441dc9c866f10d8e6ae7ea9249a10c1f57ea921b1f19a5b0977ab91ef8082c"}, +] + +[package.dependencies] +certifi = "*" +numpy = "*" +packaging = "*" + +[package.extras] +benchmark = ["pytest-benchmark"] +dev = ["cython"] +geopandas = ["geopandas"] +test = ["pytest", "pytest-cov"] + +[[package]] +name = "pyparsing" +version = "3.2.3" +description = "pyparsing module - Classes and methods to define and execute parsing grammars" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "pyparsing-3.2.3-py3-none-any.whl", hash = "sha256:a749938e02d6fd0b59b356ca504a24982314bb090c383e3cf201c95ef7e2bfcf"}, + {file = "pyparsing-3.2.3.tar.gz", hash = "sha256:b9c13f1ab8b3b542f72e28f634bad4de758ab3ce4546e4301970ad6fa77c38be"}, +] + +[package.extras] +diagrams = ["jinja2", "railroad-diagrams"] + +[[package]] +name = "pyproj" +version = "3.7.1" +description = "Python interface to PROJ (cartographic projections and coordinate transformations library)" +optional = false +python-versions = ">=3.10" +groups = ["main"] +files = [ + {file = "pyproj-3.7.1-cp310-cp310-macosx_13_0_x86_64.whl", hash = "sha256:bf09dbeb333c34e9c546364e7df1ff40474f9fddf9e70657ecb0e4f670ff0b0e"}, + {file = "pyproj-3.7.1-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:6575b2e53cc9e3e461ad6f0692a5564b96e7782c28631c7771c668770915e169"}, + {file = "pyproj-3.7.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8cb516ee35ed57789b46b96080edf4e503fdb62dbb2e3c6581e0d6c83fca014b"}, + {file = "pyproj-3.7.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e47c4e93b88d99dd118875ee3ca0171932444cdc0b52d493371b5d98d0f30ee"}, + {file = "pyproj-3.7.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3e8d276caeae34fcbe4813855d0d97b9b825bab8d7a8b86d859c24a6213a5a0d"}, + {file = "pyproj-3.7.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f173f851ee75e54acdaa053382b6825b400cb2085663a9bb073728a59c60aebb"}, + {file = "pyproj-3.7.1-cp310-cp310-win32.whl", hash = "sha256:f550281ed6e5ea88fcf04a7c6154e246d5714be495c50c9e8e6b12d3fb63e158"}, + {file = "pyproj-3.7.1-cp310-cp310-win_amd64.whl", hash = "sha256:3537668992a709a2e7f068069192138618c00d0ba113572fdd5ee5ffde8222f3"}, + {file = "pyproj-3.7.1-cp311-cp311-macosx_13_0_x86_64.whl", hash = "sha256:a94e26c1a4950cea40116775588a2ca7cf56f1f434ff54ee35a84718f3841a3d"}, + {file = "pyproj-3.7.1-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:263b54ba5004b6b957d55757d846fc5081bc02980caa0279c4fc95fa0fff6067"}, + {file = "pyproj-3.7.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f6d6a2ccd5607cd15ef990c51e6f2dd27ec0a741e72069c387088bba3aab60fa"}, + {file = "pyproj-3.7.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c5dcf24ede53d8abab7d8a77f69ff1936c6a8843ef4fcc574646e4be66e5739"}, + {file = "pyproj-3.7.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:3c2e7449840a44ce860d8bea2c6c1c4bc63fa07cba801dcce581d14dcb031a02"}, + {file = "pyproj-3.7.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0829865c1d3a3543f918b3919dc601eea572d6091c0dd175e1a054db9c109274"}, + {file = "pyproj-3.7.1-cp311-cp311-win32.whl", hash = "sha256:6181960b4b812e82e588407fe5c9c68ada267c3b084db078f248db5d7f45d18a"}, + {file = "pyproj-3.7.1-cp311-cp311-win_amd64.whl", hash = "sha256:5ad0ff443a785d84e2b380869fdd82e6bfc11eba6057d25b4409a9bbfa867970"}, + {file = "pyproj-3.7.1-cp312-cp312-macosx_13_0_x86_64.whl", hash = "sha256:2781029d90df7f8d431e29562a3f2d8eafdf233c4010d6fc0381858dc7373217"}, + {file = "pyproj-3.7.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:d61bf8ab04c73c1da08eedaf21a103b72fa5b0a9b854762905f65ff8b375d394"}, + {file = "pyproj-3.7.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:04abc517a8555d1b05fcee768db3280143fe42ec39fdd926a2feef31631a1f2f"}, + {file = "pyproj-3.7.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:084c0a475688f934d386c2ab3b6ce03398a473cd48adfda70d9ab8f87f2394a0"}, + {file = "pyproj-3.7.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a20727a23b1e49c7dc7fe3c3df8e56a8a7acdade80ac2f5cca29d7ca5564c145"}, + {file = "pyproj-3.7.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:bf84d766646f1ebd706d883755df4370aaf02b48187cedaa7e4239f16bc8213d"}, + {file = "pyproj-3.7.1-cp312-cp312-win32.whl", hash = "sha256:5f0da2711364d7cb9f115b52289d4a9b61e8bca0da57f44a3a9d6fc9bdeb7274"}, + {file = "pyproj-3.7.1-cp312-cp312-win_amd64.whl", hash = "sha256:aee664a9d806612af30a19dba49e55a7a78ebfec3e9d198f6a6176e1d140ec98"}, + {file = "pyproj-3.7.1-cp313-cp313-macosx_13_0_x86_64.whl", hash = "sha256:5f8d02ef4431dee414d1753d13fa82a21a2f61494737b5f642ea668d76164d6d"}, + {file = "pyproj-3.7.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:0b853ae99bda66cbe24b4ccfe26d70601d84375940a47f553413d9df570065e0"}, + {file = "pyproj-3.7.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:83db380c52087f9e9bdd8a527943b2e7324f275881125e39475c4f9277bdeec4"}, + {file = "pyproj-3.7.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b35ed213892e211a3ce2bea002aa1183e1a2a9b79e51bb3c6b15549a831ae528"}, + {file = "pyproj-3.7.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a8b15b0463d1303bab113d1a6af2860a0d79013c3a66fcc5475ce26ef717fd4f"}, + {file = "pyproj-3.7.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:87229e42b75e89f4dad6459200f92988c5998dfb093c7c631fb48524c86cd5dc"}, + {file = "pyproj-3.7.1-cp313-cp313-win32.whl", hash = "sha256:d666c3a3faaf3b1d7fc4a544059c4eab9d06f84a604b070b7aa2f318e227798e"}, + {file = "pyproj-3.7.1-cp313-cp313-win_amd64.whl", hash = "sha256:d3caac7473be22b6d6e102dde6c46de73b96bc98334e577dfaee9886f102ea2e"}, + {file = "pyproj-3.7.1.tar.gz", hash = "sha256:60d72facd7b6b79853f19744779abcd3f804c4e0d4fa8815469db20c9f640a47"}, +] + +[package.dependencies] +certifi = "*" + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +description = "Extensions to the standard Python datetime module" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +groups = ["main"] +files = [ + {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, + {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, +] + +[package.dependencies] +six = ">=1.5" + +[[package]] +name = "pytz" +version = "2025.2" +description = "World timezone definitions, modern and historical" +optional = false +python-versions = "*" +groups = ["main"] +files = [ + {file = "pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00"}, + {file = "pytz-2025.2.tar.gz", hash = "sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3"}, +] + +[[package]] +name = "rasterio" +version = "1.4.3" +description = "Fast and direct raster I/O for use with Numpy and SciPy" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "rasterio-1.4.3-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:80f994b92e5dda78f13291710bd5c43efcfd164f69a8a2c20489115df9d178c8"}, + {file = "rasterio-1.4.3-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:1a6e6ca9ec361599b48c9918ce25adb1a9203b8c8ca9b34ad78dccb3aef7945a"}, + {file = "rasterio-1.4.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5b8a4311582274de2346450e5361d092b80b8b5c7b02fda6203402ba101ffabf"}, + {file = "rasterio-1.4.3-cp310-cp310-win_amd64.whl", hash = "sha256:e79847a5a0e01399457a1e02d8c92040cb56729d054fe7796f0c17b246b18bf0"}, + {file = "rasterio-1.4.3-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:9c30114d95ebba4ff49f078b3c193d29ff56d832588649400a3fa78f1dda1c96"}, + {file = "rasterio-1.4.3-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:812c854e7177064aeb58def2d59752887ad6b3d39ff3f858ed9df3f2ddc95613"}, + {file = "rasterio-1.4.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:54eef32d20a0dfbba59a8bb9828e562c3e9e97e2355b8dfe4a5274117976059f"}, + {file = "rasterio-1.4.3-cp311-cp311-win_amd64.whl", hash = "sha256:4009f7ce4e0883d8e5b400970daa3f1ca309caac8916d955722ee4486654d452"}, + {file = "rasterio-1.4.3-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:e703e4b2c74c678786d5d110a3f30e26f3acfd65f09ccf35f69683a532f7a772"}, + {file = "rasterio-1.4.3-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:38a126f8dbf405cd3450b5bd10c6cc493a2e1be4cf83442d26f5e4f412372d36"}, + {file = "rasterio-1.4.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e90c2c300294265c16becc9822337ded0f01fb8664500b4d77890d633d8cd0e"}, + {file = "rasterio-1.4.3-cp312-cp312-win_amd64.whl", hash = "sha256:a962ad4c29feaf38b1d7a94389313127de3646a5b9b734fbf9a04e16051a27ff"}, + {file = "rasterio-1.4.3-cp313-cp313-macosx_10_15_x86_64.whl", hash = "sha256:5d4fcb635379b3d7b2f5e944c153849e3d27e93f35ad73ad4d3f0b8a580f0c8e"}, + {file = "rasterio-1.4.3-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:98a9c89eade8c779e8ac1e525269faaa18c6b9818fc3c72cfc4627df71c66d0d"}, + {file = "rasterio-1.4.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d9bab1a0bb22b8bed1db34b5258db93d790ed4e61ef21ac055a7c6933c8d5e84"}, + {file = "rasterio-1.4.3-cp313-cp313-win_amd64.whl", hash = "sha256:1839960e2f3057a6daa323ccf67b330f8f2f0dbd4a50cc7031e88e649301c5c0"}, + {file = "rasterio-1.4.3-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:af04f788f6f814569184bd9da6c5d9889512212385ab58c52720dfb1f972671d"}, + {file = "rasterio-1.4.3-cp39-cp39-macosx_14_0_arm64.whl", hash = "sha256:3f411a6a5bcb81ab6dc9128a8bccd13d3822cfa4a50c239e3a0528751a1ad5fc"}, + {file = "rasterio-1.4.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:597f8dcf494d0ca4254434496e83b1723fec206d23d64da5751a582a2b01e1d3"}, + {file = "rasterio-1.4.3-cp39-cp39-win_amd64.whl", hash = "sha256:a702e21712ba237e34515d829847f9f5f06d8e665e864a7bb0a3d4d8f6dec10d"}, + {file = "rasterio-1.4.3.tar.gz", hash = "sha256:201f05dbc7c4739dacb2c78a1cf4e09c0b7265b0a4d16ccbd1753ce4f2af350a"}, +] + +[package.dependencies] +affine = "*" +attrs = "*" +certifi = "*" +click = ">=4.0" +click-plugins = "*" +cligj = ">=0.5" +numpy = ">=1.24" +pyparsing = "*" + +[package.extras] +all = ["boto3 (>=1.2.4)", "fsspec", "ghp-import", "hypothesis", "ipython (>=2.0)", "matplotlib", "numpydoc", "packaging", "pytest (>=2.8.2)", "pytest-cov (>=2.2.0)", "shapely", "sphinx", "sphinx-click", "sphinx-rtd-theme"] +docs = ["ghp-import", "numpydoc", "sphinx", "sphinx-click", "sphinx-rtd-theme"] +ipython = ["ipython (>=2.0)"] +plot = ["matplotlib"] +s3 = ["boto3 (>=1.2.4)"] +test = ["boto3 (>=1.2.4)", "fsspec", "hypothesis", "packaging", "pytest (>=2.8.2)", "pytest-cov (>=2.2.0)", "shapely"] + +[[package]] +name = "rich" +version = "14.1.0" +description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" +optional = false +python-versions = ">=3.8.0" +groups = ["main"] +files = [ + {file = "rich-14.1.0-py3-none-any.whl", hash = "sha256:536f5f1785986d6dbdea3c75205c473f970777b4a0d6c6dd1b696aa05a3fa04f"}, + {file = "rich-14.1.0.tar.gz", hash = "sha256:e497a48b844b0320d45007cdebfeaeed8db2a4f4bcf49f15e455cfc4af11eaa8"}, +] + +[package.dependencies] +markdown-it-py = ">=2.2.0" +pygments = ">=2.13.0,<3.0.0" + +[package.extras] +jupyter = ["ipywidgets (>=7.5.1,<9)"] + +[[package]] +name = "scipy" +version = "1.16.1" +description = "Fundamental algorithms for scientific computing in Python" +optional = false +python-versions = ">=3.11" +groups = ["main"] +files = [ + {file = "scipy-1.16.1-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:c033fa32bab91dc98ca59d0cf23bb876454e2bb02cbe592d5023138778f70030"}, + {file = "scipy-1.16.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:6e5c2f74e5df33479b5cd4e97a9104c511518fbd979aa9b8f6aec18b2e9ecae7"}, + {file = "scipy-1.16.1-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:0a55ffe0ba0f59666e90951971a884d1ff6f4ec3275a48f472cfb64175570f77"}, + {file = "scipy-1.16.1-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:f8a5d6cd147acecc2603fbd382fed6c46f474cccfcf69ea32582e033fb54dcfe"}, + {file = "scipy-1.16.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cb18899127278058bcc09e7b9966d41a5a43740b5bb8dcba401bd983f82e885b"}, + {file = "scipy-1.16.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:adccd93a2fa937a27aae826d33e3bfa5edf9aa672376a4852d23a7cd67a2e5b7"}, + {file = "scipy-1.16.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:18aca1646a29ee9a0625a1be5637fa798d4d81fdf426481f06d69af828f16958"}, + {file = "scipy-1.16.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d85495cef541729a70cdddbbf3e6b903421bc1af3e8e3a9a72a06751f33b7c39"}, + {file = "scipy-1.16.1-cp311-cp311-win_amd64.whl", hash = "sha256:226652fca853008119c03a8ce71ffe1b3f6d2844cc1686e8f9806edafae68596"}, + {file = "scipy-1.16.1-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:81b433bbeaf35728dad619afc002db9b189e45eebe2cd676effe1fb93fef2b9c"}, + {file = "scipy-1.16.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:886cc81fdb4c6903a3bb0464047c25a6d1016fef77bb97949817d0c0d79f9e04"}, + {file = "scipy-1.16.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:15240c3aac087a522b4eaedb09f0ad061753c5eebf1ea430859e5bf8640d5919"}, + {file = "scipy-1.16.1-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:65f81a25805f3659b48126b5053d9e823d3215e4a63730b5e1671852a1705921"}, + {file = "scipy-1.16.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:6c62eea7f607f122069b9bad3f99489ddca1a5173bef8a0c75555d7488b6f725"}, + {file = "scipy-1.16.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f965bbf3235b01c776115ab18f092a95aa74c271a52577bcb0563e85738fd618"}, + {file = "scipy-1.16.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f006e323874ffd0b0b816d8c6a8e7f9a73d55ab3b8c3f72b752b226d0e3ac83d"}, + {file = "scipy-1.16.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e8fd15fc5085ab4cca74cb91fe0a4263b1f32e4420761ddae531ad60934c2119"}, + {file = "scipy-1.16.1-cp312-cp312-win_amd64.whl", hash = "sha256:f7b8013c6c066609577d910d1a2a077021727af07b6fab0ee22c2f901f22352a"}, + {file = "scipy-1.16.1-cp313-cp313-macosx_10_14_x86_64.whl", hash = "sha256:5451606823a5e73dfa621a89948096c6528e2896e40b39248295d3a0138d594f"}, + {file = "scipy-1.16.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:89728678c5ca5abd610aee148c199ac1afb16e19844401ca97d43dc548a354eb"}, + {file = "scipy-1.16.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:e756d688cb03fd07de0fffad475649b03cb89bee696c98ce508b17c11a03f95c"}, + {file = "scipy-1.16.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:5aa2687b9935da3ed89c5dbed5234576589dd28d0bf7cd237501ccfbdf1ad608"}, + {file = "scipy-1.16.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0851f6a1e537fe9399f35986897e395a1aa61c574b178c0d456be5b1a0f5ca1f"}, + {file = "scipy-1.16.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fedc2cbd1baed37474b1924c331b97bdff611d762c196fac1a9b71e67b813b1b"}, + {file = "scipy-1.16.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2ef500e72f9623a6735769e4b93e9dcb158d40752cdbb077f305487e3e2d1f45"}, + {file = "scipy-1.16.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:978d8311674b05a8f7ff2ea6c6bce5d8b45a0cb09d4c5793e0318f448613ea65"}, + {file = "scipy-1.16.1-cp313-cp313-win_amd64.whl", hash = "sha256:81929ed0fa7a5713fcdd8b2e6f73697d3b4c4816d090dd34ff937c20fa90e8ab"}, + {file = "scipy-1.16.1-cp313-cp313t-macosx_10_14_x86_64.whl", hash = "sha256:bcc12db731858abda693cecdb3bdc9e6d4bd200213f49d224fe22df82687bdd6"}, + {file = "scipy-1.16.1-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:744d977daa4becb9fc59135e75c069f8d301a87d64f88f1e602a9ecf51e77b27"}, + {file = "scipy-1.16.1-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:dc54f76ac18073bcecffb98d93f03ed6b81a92ef91b5d3b135dcc81d55a724c7"}, + {file = "scipy-1.16.1-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:367d567ee9fc1e9e2047d31f39d9d6a7a04e0710c86e701e053f237d14a9b4f6"}, + {file = "scipy-1.16.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:4cf5785e44e19dcd32a0e4807555e1e9a9b8d475c6afff3d21c3c543a6aa84f4"}, + {file = "scipy-1.16.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3d0b80fb26d3e13a794c71d4b837e2a589d839fd574a6bbb4ee1288c213ad4a3"}, + {file = "scipy-1.16.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:8503517c44c18d1030d666cb70aaac1cc8913608816e06742498833b128488b7"}, + {file = "scipy-1.16.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:30cc4bb81c41831ecfd6dc450baf48ffd80ef5aed0f5cf3ea775740e80f16ecc"}, + {file = "scipy-1.16.1-cp313-cp313t-win_amd64.whl", hash = "sha256:c24fa02f7ed23ae514460a22c57eca8f530dbfa50b1cfdbf4f37c05b5309cc39"}, + {file = "scipy-1.16.1-cp314-cp314-macosx_10_14_x86_64.whl", hash = "sha256:796a5a9ad36fa3a782375db8f4241ab02a091308eb079746bc0f874c9b998318"}, + {file = "scipy-1.16.1-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:3ea0733a2ff73fd6fdc5fecca54ee9b459f4d74f00b99aced7d9a3adb43fb1cc"}, + {file = "scipy-1.16.1-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:85764fb15a2ad994e708258bb4ed8290d1305c62a4e1ef07c414356a24fcfbf8"}, + {file = "scipy-1.16.1-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:ca66d980469cb623b1759bdd6e9fd97d4e33a9fad5b33771ced24d0cb24df67e"}, + {file = "scipy-1.16.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e7cc1ffcc230f568549fc56670bcf3df1884c30bd652c5da8138199c8c76dae0"}, + {file = "scipy-1.16.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3ddfb1e8d0b540cb4ee9c53fc3dea3186f97711248fb94b4142a1b27178d8b4b"}, + {file = "scipy-1.16.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4dc0e7be79e95d8ba3435d193e0d8ce372f47f774cffd882f88ea4e1e1ddc731"}, + {file = "scipy-1.16.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:f23634f9e5adb51b2a77766dac217063e764337fbc816aa8ad9aaebcd4397fd3"}, + {file = "scipy-1.16.1-cp314-cp314-win_amd64.whl", hash = "sha256:57d75524cb1c5a374958a2eae3d84e1929bb971204cc9d52213fb8589183fc19"}, + {file = "scipy-1.16.1-cp314-cp314t-macosx_10_14_x86_64.whl", hash = "sha256:d8da7c3dd67bcd93f15618938f43ed0995982eb38973023d46d4646c4283ad65"}, + {file = "scipy-1.16.1-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:cc1d2f2fd48ba1e0620554fe5bc44d3e8f5d4185c8c109c7fbdf5af2792cfad2"}, + {file = "scipy-1.16.1-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:21a611ced9275cb861bacadbada0b8c0623bc00b05b09eb97f23b370fc2ae56d"}, + {file = "scipy-1.16.1-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:8dfbb25dffc4c3dd9371d8ab456ca81beeaf6f9e1c2119f179392f0dc1ab7695"}, + {file = "scipy-1.16.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f0ebb7204f063fad87fc0a0e4ff4a2ff40b2a226e4ba1b7e34bf4b79bf97cd86"}, + {file = "scipy-1.16.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f1b9e5962656f2734c2b285a8745358ecb4e4efbadd00208c80a389227ec61ff"}, + {file = "scipy-1.16.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5e1a106f8c023d57a2a903e771228bf5c5b27b5d692088f457acacd3b54511e4"}, + {file = "scipy-1.16.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:709559a1db68a9abc3b2c8672c4badf1614f3b440b3ab326d86a5c0491eafae3"}, + {file = "scipy-1.16.1-cp314-cp314t-win_amd64.whl", hash = "sha256:c0c804d60492a0aad7f5b2bb1862f4548b990049e27e828391ff2bf6f7199998"}, + {file = "scipy-1.16.1.tar.gz", hash = "sha256:44c76f9e8b6e8e488a586190ab38016e4ed2f8a038af7cd3defa903c0a2238b3"}, +] + +[package.dependencies] +numpy = ">=1.25.2,<2.6" + +[package.extras] +dev = ["cython-lint (>=0.12.2)", "doit (>=0.36.0)", "mypy (==1.10.0)", "pycodestyle", "pydevtool", "rich-click", "ruff (>=0.0.292)", "types-psutil", "typing_extensions"] +doc = ["intersphinx_registry", "jupyterlite-pyodide-kernel", "jupyterlite-sphinx (>=0.19.1)", "jupytext", "linkify-it-py", "matplotlib (>=3.5)", "myst-nb (>=1.2.0)", "numpydoc", "pooch", "pydata-sphinx-theme (>=0.15.2)", "sphinx (>=5.0.0,<8.2.0)", "sphinx-copybutton", "sphinx-design (>=0.4.0)"] +test = ["Cython", "array-api-strict (>=2.3.1)", "asv", "gmpy2", "hypothesis (>=6.30)", "meson", "mpmath", "ninja ; sys_platform != \"emscripten\"", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] + +[[package]] +name = "shapely" +version = "2.1.1" +description = "Manipulation and analysis of geometric objects" +optional = false +python-versions = ">=3.10" +groups = ["main"] +files = [ + {file = "shapely-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d8ccc872a632acb7bdcb69e5e78df27213f7efd195882668ffba5405497337c6"}, + {file = "shapely-2.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f24f2ecda1e6c091da64bcbef8dd121380948074875bd1b247b3d17e99407099"}, + {file = "shapely-2.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45112a5be0b745b49e50f8829ce490eb67fefb0cea8d4f8ac5764bfedaa83d2d"}, + {file = "shapely-2.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c10ce6f11904d65e9bbb3e41e774903c944e20b3f0b282559885302f52f224a"}, + {file = "shapely-2.1.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:61168010dfe4e45f956ffbbaf080c88afce199ea81eb1f0ac43230065df320bd"}, + {file = "shapely-2.1.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cacf067cdff741cd5c56a21c52f54ece4e4dad9d311130493a791997da4a886b"}, + {file = "shapely-2.1.1-cp310-cp310-win32.whl", hash = "sha256:23b8772c3b815e7790fb2eab75a0b3951f435bc0fce7bb146cb064f17d35ab4f"}, + {file = "shapely-2.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:2c7b2b6143abf4fa77851cef8ef690e03feade9a0d48acd6dc41d9e0e78d7ca6"}, + {file = "shapely-2.1.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:587a1aa72bc858fab9b8c20427b5f6027b7cbc92743b8e2c73b9de55aa71c7a7"}, + {file = "shapely-2.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9fa5c53b0791a4b998f9ad84aad456c988600757a96b0a05e14bba10cebaaaea"}, + {file = "shapely-2.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aabecd038841ab5310d23495253f01c2a82a3aedae5ab9ca489be214aa458aa7"}, + {file = "shapely-2.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:586f6aee1edec04e16227517a866df3e9a2e43c1f635efc32978bb3dc9c63753"}, + {file = "shapely-2.1.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b9878b9e37ad26c72aada8de0c9cfe418d9e2ff36992a1693b7f65a075b28647"}, + {file = "shapely-2.1.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d9a531c48f289ba355e37b134e98e28c557ff13965d4653a5228d0f42a09aed0"}, + {file = "shapely-2.1.1-cp311-cp311-win32.whl", hash = "sha256:4866de2673a971820c75c0167b1f1cd8fb76f2d641101c23d3ca021ad0449bab"}, + {file = "shapely-2.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:20a9d79958b3d6c70d8a886b250047ea32ff40489d7abb47d01498c704557a93"}, + {file = "shapely-2.1.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2827365b58bf98efb60affc94a8e01c56dd1995a80aabe4b701465d86dcbba43"}, + {file = "shapely-2.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a9c551f7fa7f1e917af2347fe983f21f212863f1d04f08eece01e9c275903fad"}, + {file = "shapely-2.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78dec4d4fbe7b1db8dc36de3031767e7ece5911fb7782bc9e95c5cdec58fb1e9"}, + {file = "shapely-2.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:872d3c0a7b8b37da0e23d80496ec5973c4692920b90de9f502b5beb994bbaaef"}, + {file = "shapely-2.1.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2e2b9125ebfbc28ecf5353511de62f75a8515ae9470521c9a693e4bb9fbe0cf1"}, + {file = "shapely-2.1.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4b96cea171b3d7f6786976a0520f178c42792897653ecca0c5422fb1e6946e6d"}, + {file = "shapely-2.1.1-cp312-cp312-win32.whl", hash = "sha256:39dca52201e02996df02e447f729da97cfb6ff41a03cb50f5547f19d02905af8"}, + {file = "shapely-2.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:13d643256f81d55a50013eff6321142781cf777eb6a9e207c2c9e6315ba6044a"}, + {file = "shapely-2.1.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:3004a644d9e89e26c20286d5fdc10f41b1744c48ce910bd1867fdff963fe6c48"}, + {file = "shapely-2.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1415146fa12d80a47d13cfad5310b3c8b9c2aa8c14a0c845c9d3d75e77cb54f6"}, + {file = "shapely-2.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21fcab88b7520820ec16d09d6bea68652ca13993c84dffc6129dc3607c95594c"}, + {file = "shapely-2.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5ce6a5cc52c974b291237a96c08c5592e50f066871704fb5b12be2639d9026a"}, + {file = "shapely-2.1.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:04e4c12a45a1d70aeb266618d8cf81a2de9c4df511b63e105b90bfdfb52146de"}, + {file = "shapely-2.1.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6ca74d851ca5264aae16c2b47e96735579686cb69fa93c4078070a0ec845b8d8"}, + {file = "shapely-2.1.1-cp313-cp313-win32.whl", hash = "sha256:fd9130501bf42ffb7e0695b9ea17a27ae8ce68d50b56b6941c7f9b3d3453bc52"}, + {file = "shapely-2.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:ab8d878687b438a2f4c138ed1a80941c6ab0029e0f4c785ecfe114413b498a97"}, + {file = "shapely-2.1.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0c062384316a47f776305ed2fa22182717508ffdeb4a56d0ff4087a77b2a0f6d"}, + {file = "shapely-2.1.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4ecf6c196b896e8f1360cc219ed4eee1c1e5f5883e505d449f263bd053fb8c05"}, + {file = "shapely-2.1.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb00070b4c4860f6743c600285109c273cca5241e970ad56bb87bef0be1ea3a0"}, + {file = "shapely-2.1.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d14a9afa5fa980fbe7bf63706fdfb8ff588f638f145a1d9dbc18374b5b7de913"}, + {file = "shapely-2.1.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b640e390dabde790e3fb947198b466e63223e0a9ccd787da5f07bcb14756c28d"}, + {file = "shapely-2.1.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:69e08bf9697c1b73ec6aa70437db922bafcea7baca131c90c26d59491a9760f9"}, + {file = "shapely-2.1.1-cp313-cp313t-win32.whl", hash = "sha256:ef2d09d5a964cc90c2c18b03566cf918a61c248596998a0301d5b632beadb9db"}, + {file = "shapely-2.1.1-cp313-cp313t-win_amd64.whl", hash = "sha256:8cb8f17c377260452e9d7720eeaf59082c5f8ea48cf104524d953e5d36d4bdb7"}, + {file = "shapely-2.1.1.tar.gz", hash = "sha256:500621967f2ffe9642454808009044c21e5b35db89ce69f8a2042c2ffd0e2772"}, +] + +[package.dependencies] +numpy = ">=1.21" + +[package.extras] +docs = ["matplotlib", "numpydoc (==1.1.*)", "sphinx", "sphinx-book-theme", "sphinx-remove-toctrees"] +test = ["pytest", "pytest-cov", "scipy-doctest"] + +[[package]] +name = "shellingham" +version = "1.5.4" +description = "Tool to Detect Surrounding Shell" +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686"}, + {file = "shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de"}, +] + +[[package]] +name = "simplejson" +version = "3.20.1" +description = "Simple, fast, extensible JSON encoder/decoder for Python" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.5" +groups = ["main"] +files = [ + {file = "simplejson-3.20.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:f5272b5866b259fe6c33c4a8c5073bf8b359c3c97b70c298a2f09a69b52c7c41"}, + {file = "simplejson-3.20.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:5c0de368f3052a59a1acf21f8b2dd28686a9e4eba2da7efae7ed9554cb31e7bc"}, + {file = "simplejson-3.20.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:0821871404a537fd0e22eba240c74c0467c28af6cc435903eca394cfc74a0497"}, + {file = "simplejson-3.20.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:c939a1e576bded47d7d03aa2afc2ae90b928b2cf1d9dc2070ceec51fd463f430"}, + {file = "simplejson-3.20.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:3c4f0a61cdc05550782ca4a2cdb311ea196c2e6be6b24a09bf71360ca8c3ca9b"}, + {file = "simplejson-3.20.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:6c21f5c026ca633cfffcb6bc1fac2e99f65cb2b24657d3bef21aed9916cc3bbf"}, + {file = "simplejson-3.20.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:8d23b7f8d6b72319d6d55a0261089ff621ce87e54731c2d3de6a9bf7be5c028c"}, + {file = "simplejson-3.20.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:cda5c32a98f392909088111ecec23f2b0d39346ceae1a0fea23ab2d1f84ec21d"}, + {file = "simplejson-3.20.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e580aa65d5f6c3bf41b9b4afe74be5d5ddba9576701c107c772d936ea2b5043a"}, + {file = "simplejson-3.20.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4a586ce4f78cec11f22fe55c5bee0f067e803aab9bad3441afe2181693b5ebb5"}, + {file = "simplejson-3.20.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:74a1608f9e6e8c27a4008d70a54270868306d80ed48c9df7872f9f4b8ac87808"}, + {file = "simplejson-3.20.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:03db8cb64154189a92a7786209f24e391644f3a3fa335658be2df2af1960b8d8"}, + {file = "simplejson-3.20.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eea7e2b7d858f6fdfbf0fe3cb846d6bd8a45446865bc09960e51f3d473c2271b"}, + {file = "simplejson-3.20.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e66712b17d8425bb7ff8968d4c7c7fd5a2dd7bd63728b28356223c000dd2f91f"}, + {file = "simplejson-3.20.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2cc4f6486f9f515b62f5831ff1888886619b84fc837de68f26d919ba7bbdcbc"}, + {file = "simplejson-3.20.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a3c2df555ee4016148fa192e2b9cd9e60bc1d40769366134882685e90aee2a1e"}, + {file = "simplejson-3.20.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:78520f04b7548a5e476b5396c0847e066f1e0a4c0c5e920da1ad65e95f410b11"}, + {file = "simplejson-3.20.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:f4bd49ecde87b0fe9f55cc971449a32832bca9910821f7072bbfae1155eaa007"}, + {file = "simplejson-3.20.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7eaae2b88eb5da53caaffdfa50e2e12022553949b88c0df4f9a9663609373f72"}, + {file = "simplejson-3.20.1-cp310-cp310-win32.whl", hash = "sha256:e836fb88902799eac8debc2b642300748f4860a197fa3d9ea502112b6bb8e142"}, + {file = "simplejson-3.20.1-cp310-cp310-win_amd64.whl", hash = "sha256:b122a19b552b212fc3b5b96fc5ce92333d4a9ac0a800803e1f17ebb16dac4be5"}, + {file = "simplejson-3.20.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:325b8c107253d3217e89d7b50c71015b5b31e2433e6c5bf38967b2f80630a8ca"}, + {file = "simplejson-3.20.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:88a7baa8211089b9e58d78fbc1b0b322103f3f3d459ff16f03a36cece0d0fcf0"}, + {file = "simplejson-3.20.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:299b1007b8101d50d95bc0db1bf5c38dc372e85b504cf77f596462083ee77e3f"}, + {file = "simplejson-3.20.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:03ec618ed65caab48e81e3ed29586236a8e57daef792f1f3bb59504a7e98cd10"}, + {file = "simplejson-3.20.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cd2cdead1d3197f0ff43373cf4730213420523ba48697743e135e26f3d179f38"}, + {file = "simplejson-3.20.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3466d2839fdc83e1af42e07b90bc8ff361c4e8796cd66722a40ba14e458faddd"}, + {file = "simplejson-3.20.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d492ed8e92f3a9f9be829205f44b1d0a89af6582f0cf43e0d129fa477b93fe0c"}, + {file = "simplejson-3.20.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:f924b485537b640dc69434565463fd6fc0c68c65a8c6e01a823dd26c9983cf79"}, + {file = "simplejson-3.20.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:9e8eacf6a3491bf76ea91a8d46726368a6be0eb94993f60b8583550baae9439e"}, + {file = "simplejson-3.20.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:d34d04bf90b4cea7c22d8b19091633908f14a096caa301b24c2f3d85b5068fb8"}, + {file = "simplejson-3.20.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:69dd28d4ce38390ea4aaf212902712c0fd1093dc4c1ff67e09687c3c3e15a749"}, + {file = "simplejson-3.20.1-cp311-cp311-win32.whl", hash = "sha256:dfe7a9da5fd2a3499436cd350f31539e0a6ded5da6b5b3d422df016444d65e43"}, + {file = "simplejson-3.20.1-cp311-cp311-win_amd64.whl", hash = "sha256:896a6c04d7861d507d800da7642479c3547060bf97419d9ef73d98ced8258766"}, + {file = "simplejson-3.20.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f31c4a3a7ab18467ee73a27f3e59158255d1520f3aad74315edde7a940f1be23"}, + {file = "simplejson-3.20.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:884e6183d16b725e113b83a6fc0230152ab6627d4d36cb05c89c2c5bccfa7bc6"}, + {file = "simplejson-3.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03d7a426e416fe0d3337115f04164cd9427eb4256e843a6b8751cacf70abc832"}, + {file = "simplejson-3.20.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:000602141d0bddfcff60ea6a6e97d5e10c9db6b17fd2d6c66199fa481b6214bb"}, + {file = "simplejson-3.20.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:af8377a8af78226e82e3a4349efdde59ffa421ae88be67e18cef915e4023a595"}, + {file = "simplejson-3.20.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15c7de4c88ab2fbcb8781a3b982ef883696736134e20b1210bca43fb42ff1acf"}, + {file = "simplejson-3.20.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:455a882ff3f97d810709f7b620007d4e0aca8da71d06fc5c18ba11daf1c4df49"}, + {file = "simplejson-3.20.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:fc0f523ce923e7f38eb67804bc80e0a028c76d7868500aa3f59225574b5d0453"}, + {file = "simplejson-3.20.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:76461ec929282dde4a08061071a47281ad939d0202dc4e63cdd135844e162fbc"}, + {file = "simplejson-3.20.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:ab19c2da8c043607bde4d4ef3a6b633e668a7d2e3d56f40a476a74c5ea71949f"}, + {file = "simplejson-3.20.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b2578bedaedf6294415197b267d4ef678fea336dd78ee2a6d2f4b028e9d07be3"}, + {file = "simplejson-3.20.1-cp312-cp312-win32.whl", hash = "sha256:339f407373325a36b7fd744b688ba5bae0666b5d340ec6d98aebc3014bf3d8ea"}, + {file = "simplejson-3.20.1-cp312-cp312-win_amd64.whl", hash = "sha256:627d4486a1ea7edf1f66bb044ace1ce6b4c1698acd1b05353c97ba4864ea2e17"}, + {file = "simplejson-3.20.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:71e849e7ceb2178344998cbe5ade101f1b329460243c79c27fbfc51c0447a7c3"}, + {file = "simplejson-3.20.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b63fdbab29dc3868d6f009a59797cefaba315fd43cd32ddd998ee1da28e50e29"}, + {file = "simplejson-3.20.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1190f9a3ce644fd50ec277ac4a98c0517f532cfebdcc4bd975c0979a9f05e1fb"}, + {file = "simplejson-3.20.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1336ba7bcb722ad487cd265701ff0583c0bb6de638364ca947bb84ecc0015d1"}, + {file = "simplejson-3.20.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e975aac6a5acd8b510eba58d5591e10a03e3d16c1cf8a8624ca177491f7230f0"}, + {file = "simplejson-3.20.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6a6dd11ee282937ad749da6f3b8d87952ad585b26e5edfa10da3ae2536c73078"}, + {file = "simplejson-3.20.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab980fcc446ab87ea0879edad41a5c28f2d86020014eb035cf5161e8de4474c6"}, + {file = "simplejson-3.20.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f5aee2a4cb6b146bd17333ac623610f069f34e8f31d2f4f0c1a2186e50c594f0"}, + {file = "simplejson-3.20.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:652d8eecbb9a3b6461b21ec7cf11fd0acbab144e45e600c817ecf18e4580b99e"}, + {file = "simplejson-3.20.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:8c09948f1a486a89251ee3a67c9f8c969b379f6ffff1a6064b41fea3bce0a112"}, + {file = "simplejson-3.20.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:cbbd7b215ad4fc6f058b5dd4c26ee5c59f72e031dfda3ac183d7968a99e4ca3a"}, + {file = "simplejson-3.20.1-cp313-cp313-win32.whl", hash = "sha256:ae81e482476eaa088ef9d0120ae5345de924f23962c0c1e20abbdff597631f87"}, + {file = "simplejson-3.20.1-cp313-cp313-win_amd64.whl", hash = "sha256:1b9fd15853b90aec3b1739f4471efbf1ac05066a2c7041bf8db821bb73cd2ddc"}, + {file = "simplejson-3.20.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:c7edf279c1376f28bf41e916c015a2a08896597869d57d621f55b6a30c7e1e6d"}, + {file = "simplejson-3.20.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d9202b9de38f12e99a40addd1a8d508a13c77f46d87ab1f9095f154667f4fe81"}, + {file = "simplejson-3.20.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:391345b4157cc4e120027e013bd35c45e2c191e2bf48b8913af488cdc3b9243c"}, + {file = "simplejson-3.20.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c6fdcc9debb711ddd2ad6d69f9386a3d9e8e253234bbb30513e0a7caa9510c51"}, + {file = "simplejson-3.20.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9daf8cdc7ee8a9e9f7a3b313ba0a003391857e90d0e82fbcd4d614aa05cb7c3b"}, + {file = "simplejson-3.20.1-cp36-cp36m-musllinux_1_2_aarch64.whl", hash = "sha256:c02f4868a3a46ffe284a51a88d134dc96feff6079a7115164885331a1ba8ed9f"}, + {file = "simplejson-3.20.1-cp36-cp36m-musllinux_1_2_i686.whl", hash = "sha256:3d7310172d5340febd258cb147f46aae30ad57c445f4d7e1ae8461c10aaf43b0"}, + {file = "simplejson-3.20.1-cp36-cp36m-musllinux_1_2_ppc64le.whl", hash = "sha256:4762e05577955312a4c6802f58dd02e040cc79ae59cda510aa1564d84449c102"}, + {file = "simplejson-3.20.1-cp36-cp36m-musllinux_1_2_x86_64.whl", hash = "sha256:8bb98fdf318c05aefd08a92583bd6ee148e93c6756fb1befb7b2d5f27824be78"}, + {file = "simplejson-3.20.1-cp36-cp36m-win32.whl", hash = "sha256:9a74e70818818981294b8e6956ce3496c5e1bd4726ac864fae473197671f7b85"}, + {file = "simplejson-3.20.1-cp36-cp36m-win_amd64.whl", hash = "sha256:e041add470e8f8535cc05509485eb7205729a84441f03b25cde80ad48823792e"}, + {file = "simplejson-3.20.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7e9d73f46119240e4f4f07868241749d67d09873f40cb968d639aa9ccc488b86"}, + {file = "simplejson-3.20.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ae6e637dc24f8fee332ed23dd070e81394138e42cd4fd9d0923e5045ba122e27"}, + {file = "simplejson-3.20.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:efd3bc6c6b17e3d4620eb6be5196f0d1c08b6ce7c3101fa8e292b79e0908944b"}, + {file = "simplejson-3.20.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:87fc623d457173a0213bc9ca4e346b83c9d443f63ed5cca847fb0cacea3cfc95"}, + {file = "simplejson-3.20.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec6a1e0a7aff76f0e008bebfa950188b9c50b58c1885d898145f48fc8e189a56"}, + {file = "simplejson-3.20.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:9c079606f461a6e950099167e21e13985147c8a24be8eea66c9ad68f73fad744"}, + {file = "simplejson-3.20.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:9faceb68fba27ef17eda306e4cd97a7b4b14fdadca5fbb15790ba8b26ebeec0c"}, + {file = "simplejson-3.20.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:7ceed598e4bacbf5133fe7a418f7991bb2df0683f3ac11fbf9e36a2bc7aa4b85"}, + {file = "simplejson-3.20.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:ede69c765e9901861ad7c6139023b7b7d5807c48a2539d817b4ab40018002d5f"}, + {file = "simplejson-3.20.1-cp37-cp37m-win32.whl", hash = "sha256:d8853c269a4c5146ddca4aa7c70e631795e9d11239d5fedb1c6bbc91ffdebcac"}, + {file = "simplejson-3.20.1-cp37-cp37m-win_amd64.whl", hash = "sha256:ed6a17fd397f0e2b3ad668fc9e19253ed2e3875ad9086bd7f795c29a3223f4a1"}, + {file = "simplejson-3.20.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:7551682b60bba3a9e2780742e101cf0a64250e76de7d09b1c4b0c8a7c7cc6834"}, + {file = "simplejson-3.20.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bd9577ec1c8c3a43040e3787711e4c257c70035b7551a21854b5dec88dad09e1"}, + {file = "simplejson-3.20.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4a8e197e4cf6d42c2c57e7c52cd7c1e7b3e37c5911df1314fb393320131e2101"}, + {file = "simplejson-3.20.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6bd09c8c75666e7f62a33d2f1fb57f81da1fcbb19a9fe7d7910b5756e1dd6048"}, + {file = "simplejson-3.20.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1bd6bfe5678d73fbd5328eea6a35216503796428fc47f1237432522febaf3a0c"}, + {file = "simplejson-3.20.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:71b75d448fd0ceb2e7c90e72bb82c41f8462550d48529980bc0bab1d2495bfbb"}, + {file = "simplejson-3.20.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a7e15b716d09f318c8cda3e20f82fae81684ce3d3acd1d7770fa3007df1769de"}, + {file = "simplejson-3.20.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:3e7963197d958fcf9e98b212b80977d56c022384621ff463d98afc3b6b1ce7e8"}, + {file = "simplejson-3.20.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:2e671dd62051129185d3a9a92c60101f56cbc174854a1a3dfb69114ebd9e1699"}, + {file = "simplejson-3.20.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:e25b2a0c396f3b84fb89573d07b0e1846ed563eb364f2ea8230ca92b8a8cb786"}, + {file = "simplejson-3.20.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:489c3a43116082bad56795215786313832ba3991cca1f55838e52a553f451ab6"}, + {file = "simplejson-3.20.1-cp38-cp38-win32.whl", hash = "sha256:4a92e948bad8df7fa900ba2ba0667a98303f3db206cbaac574935c332838208e"}, + {file = "simplejson-3.20.1-cp38-cp38-win_amd64.whl", hash = "sha256:49d059b8363327eee3c94799dd96782314b2dbd7bcc293b4ad48db69d6f4d362"}, + {file = "simplejson-3.20.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a8011f1dd1d676befcd4d675ebdbfdbbefd3bf350052b956ba8c699fca7d8cef"}, + {file = "simplejson-3.20.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e91703a4c5fec53e36875ae426ad785f4120bd1d93b65bed4752eeccd1789e0c"}, + {file = "simplejson-3.20.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e39eaa57c7757daa25bcd21f976c46be443b73dd6c3da47fe5ce7b7048ccefe2"}, + {file = "simplejson-3.20.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ceab2ce2acdc7fbaa433a93006758db6ba9a659e80c4faa13b80b9d2318e9b17"}, + {file = "simplejson-3.20.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6d4f320c33277a5b715db5bf5b10dae10c19076bd6d66c2843e04bd12d1f1ea5"}, + {file = "simplejson-3.20.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2b6436c48e64378fa844d8c9e58a5ed0352bbcfd4028369a9b46679b7ab79d2d"}, + {file = "simplejson-3.20.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e18345c8dda5d699be8166b61f9d80aaee4545b709f1363f60813dc032dac53"}, + {file = "simplejson-3.20.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:90b573693d1526bed576f6817e2a492eaaef68f088b57d7a9e83d122bbb49e51"}, + {file = "simplejson-3.20.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:272cc767826e924a6bd369ea3dbf18e166ded29059c7a4d64d21a9a22424b5b5"}, + {file = "simplejson-3.20.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:51b41f284d603c4380732d7d619f8b34bd04bc4aa0ed0ed5f4ffd0539b14da44"}, + {file = "simplejson-3.20.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:6e6697a3067d281f01de0fe96fc7cba4ea870d96d7deb7bfcf85186d74456503"}, + {file = "simplejson-3.20.1-cp39-cp39-win32.whl", hash = "sha256:6dd3a1d5aca87bf947f3339b0f8e8e329f1badf548bdbff37fac63c17936da8e"}, + {file = "simplejson-3.20.1-cp39-cp39-win_amd64.whl", hash = "sha256:463f1fca8fbf23d088e5850fdd0dd4d5faea8900a9f9680270bd98fd649814ca"}, + {file = "simplejson-3.20.1-py3-none-any.whl", hash = "sha256:8a6c1bbac39fa4a79f83cbf1df6ccd8ff7069582a9fd8db1e52cea073bc2c697"}, + {file = "simplejson-3.20.1.tar.gz", hash = "sha256:e64139b4ec4f1f24c142ff7dcafe55a22b811a74d86d66560c8815687143037d"}, +] + +[[package]] +name = "six" +version = "1.17.0" +description = "Python 2 and 3 compatibility utilities" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +groups = ["main"] +files = [ + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, +] + +[[package]] +name = "typer" +version = "0.17.3" +description = "Typer, build great CLIs. Easy to code. Based on Python type hints." +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "typer-0.17.3-py3-none-any.whl", hash = "sha256:643919a79182ab7ac7581056d93c6a2b865b026adf2872c4d02c72758e6f095b"}, + {file = "typer-0.17.3.tar.gz", hash = "sha256:0c600503d472bcf98d29914d4dcd67f80c24cc245395e2e00ba3603c9332e8ba"}, +] + +[package.dependencies] +click = ">=8.0.0" +rich = ">=10.11.0" +shellingham = ">=1.3.0" +typing-extensions = ">=3.7.4.3" + +[[package]] +name = "typing-extensions" +version = "4.15.0" +description = "Backported and Experimental Type Hints for Python 3.9+" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548"}, + {file = "typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466"}, +] + +[[package]] +name = "tzdata" +version = "2025.2" +description = "Provider of IANA time zone data" +optional = false +python-versions = ">=2" +groups = ["main"] +files = [ + {file = "tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8"}, + {file = "tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9"}, +] + +[[package]] +name = "wcwidth" +version = "0.2.13" +description = "Measures the displayed width of unicode strings in a terminal" +optional = false +python-versions = "*" +groups = ["main"] +files = [ + {file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"}, + {file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"}, +] + +[metadata] +lock-version = "2.1" +python-versions = "^3.12" +content-hash = "ce077e2a08658cb8db373a9edf4f98d614311dc26e4fbee98133a59d1baa968a" diff --git a/pyproject.toml b/pyproject.toml index 115f1349..cd35c1c9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,8 +1,8 @@ + [project] -name = "GeoProb-Pipe" -version = "0.0.1" -description = "Execute probabilistic piping calculations using a Deltares probabilic library" -readme = "README.md" +name = "geoprob_pipe" +version = "1.3.4" +description = "Execute probabilistic piping calculations using the Deltares probabilic library." requires-python = ">=3.12" license = "GPL-3.0-or-later" classifiers = [ @@ -12,40 +12,22 @@ classifiers = [ "Programming Language :: Python :: 3.12", ] -dependencies = [ - "geopandas~=1.0.1", - "matplotlib~=3.10.1", - "openpyxl>=3.1.5", - "probabilistic-library", - "scipy~=1.14.1", -] - -[tool.black] -line-length = 120 -include = '\.pyi?$' -exclude = ''' -/( - \.git - | \.hg - | \.mypy_cache - | \.tox - | \.venv - | _build - | buck-out - | build - | dist -)/ -''' -[tool.isort] -profile = "black" +[tool.poetry.dependencies] +python = "^3.12" +pandas = "^2.3.1" +scipy = "^1.16.1" +pydra-core = "^0.0.9" +geopandas = "^1.1.1" +plotly = "^6.2.0" +openpyxl = "^3.1.5" +kaleido = "^1.0.0" +colorlog = "^6.9.0" +typer = "^0.17.3" +inquirerpy = "^0.3.4" +rasterio = "^1.4.3" +probabilistic-library = "^26.1.1" -[tool.uv.sources] -probabilistic-library = { path = "wheels/probabilistic_library-25.1.1-py3-none-any.whl" } -[dependency-groups] -dev = [ - "numpy>=2.2.4", - "pytest>=8.3.5", - "sphinx>=8.2.3", - "sphinxcontrib-bibtex>=2.6.3", -] +[tool.poetry.scripts] +geoprob_pipe = "geoprob_pipe.cmd_app.cmd:app" +geoprob-pipe = "geoprob_pipe.cmd_app.cmd:app" \ No newline at end of file diff --git a/readme_images/coverage.svg b/readme_images/coverage.svg index e123fe5b..565169ed 100644 --- a/readme_images/coverage.svg +++ b/readme_images/coverage.svg @@ -15,7 +15,7 @@ coverage coverage - 9% - 9% + 28% + 28% diff --git a/repo_utils/__init__.py b/repo_utils/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/repo_utils/collect_todos.py b/repo_utils/collect_todos.py new file mode 100644 index 00000000..9a22c750 --- /dev/null +++ b/repo_utils/collect_todos.py @@ -0,0 +1,123 @@ +from typing import Tuple +from pandas import DataFrame +import os +from git import Repo, InvalidGitRepositoryError +from typing import Optional + + +def repository_root_path() -> Optional[str]: + + # Bold guess, it is the execution path + base_dir = os.getcwd() + try: + repo_root = Repo(base_dir, search_parent_directories=False).working_tree_dir + return repo_root + except InvalidGitRepositoryError: + pass + + # Otherwise, search subdirectories + for subdir, dirs, files in os.walk(os.getcwd()): + for directory in dirs: + try: + repo = Repo(os.path.join(subdir, directory), search_parent_directories=False) + return repo.working_tree_dir + except InvalidGitRepositoryError: + continue + return None + return None + + +def get_todo_contents(line: str) -> Tuple[bool, str, str, str, str]: + line = line[line.find("# TODO")+7:] + items = line.split(sep=':') + description = items[1] + items = items[0].split(sep=' ') + if items.__len__() >= 4: + return False, "", "", "", "" + if items[0].lower() not in ['nu', 'later']: + return False, "", "", "", "" + if items[1].lower() not in ['must', 'should', 'could', 'nice']: + return False, "", "", "", "" + if items[2].lower() not in ['groot', 'middel', 'klein']: + return False, "", "", "", "" + return True, items[0].lower(), items[1].lower(), items[2].lower(), description + + +def find_todos_in_file(filepath: str, path_to_package: str): + todos = [] + with open(filepath, 'r', encoding='utf-8', errors='ignore') as file: + for lineno, line in enumerate(file, start=1): + if '# TODO ' not in line: + continue + valid, wanneer, belang, formaat, description = get_todo_contents(line=line) + if not valid: + continue + todos.append({ + 'bestand': filepath.replace(path_to_package, ""), + 'regel': lineno, + 'line': line, + 'wanneer': wanneer, + 'belang': belang, + 'formaat': formaat, + 'description': description + }) + return todos + + +def collect_all_todos(): + todos = [] + repo_root = repository_root_path() + path_to_package = os.path.join(repo_root, "geoprob_pipe") + for subdir, _, files in os.walk(path_to_package): + for file in files: + if not file.endswith(".py"): + continue + path = os.path.join(subdir, file) + todos.extend(find_todos_in_file(filepath=path, path_to_package=path_to_package)) + + df_todos = DataFrame(todos) + df_todos = df_todos.sort_values(by=['wanneer', 'belang', 'formaat'], ascending=[False, True, True]) + + return df_todos + + +def df_to_markdown(df: DataFrame): + markdown = "| Belang | Formaat | Beschrijving | Bestand | Regel |\n" + markdown += "| -- | -- | -- | -- | -- |\n" + for _, row in df.iterrows(): + markdown += (f"| {row['belang']} | {row['formaat']} | {str(row['description']).strip()} " + f"| {row['bestand']} | {row['regel']} | \n") + return markdown + + +def update_readme_with_table(wanneer: str = "nu"): + start_marker = f"" + end_marker = f" " + + readme_path = os.path.join(repository_root_path(), "README.md") + + # Construct Markdown table + df_todos = collect_all_todos() + df_todos = df_todos[df_todos['wanneer'] == wanneer] + markdown = df_to_markdown(df_todos) + + with open(readme_path, 'r', encoding='utf-8') as f: + content = f.read() + + if start_marker not in content or end_marker not in content: + raise ValueError(f"Markers niet gevonden in het README.md-bestand.") + + new_content = \ + content.split(start_marker)[0] + \ + start_marker + '\n' + \ + markdown + '\n' + \ + end_marker + '\n' + \ + content.split(end_marker)[1] + + with open(readme_path, 'w', encoding='utf-8') as f: + f.write(new_content) + + +update_readme_with_table(wanneer='nu') +update_readme_with_table(wanneer='later') +print(f"Finished updating README.") diff --git a/app/helper_functions/utils.py b/repo_utils/utils.py similarity index 100% rename from app/helper_functions/utils.py rename to repo_utils/utils.py diff --git a/requirements.txt b/requirements.txt index 00ea3f15..4123f500 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,21 @@ -geopandas~=1.0.1 -matplotlib~=3.10.1 -openpyxl~=3.1.5 -pydra-core~=0.0.9 -scipy~=1.14.1 -./wheels/probabilistic_library-25.1.1-py3-none-any.whl; platform_system == 'Windows' -# TODO: Inquire if probabilistic_library can be pushed to the repository. Will be useful for unit testing. +dotenv +pandas +pydra-core +# TODO Later Should Middel: Er bestaat ook een Python-wrapper voor Hydra-Ring. Pydra-core vervangen? +openpyxl +colorlog +plotly +kaleido +geopandas +probabilistic_library +typer[all] +InquirerPy gitpython +rasterio +sphinx +sphinx-autodoc-typehints +sphinx-autoapi +sphinx-mdinclude +sphinxcontrib-jquery +sphinx-rtd-theme +sphinxcontrib-bibtex diff --git a/requirements_testing.txt b/requirements_testing.txt new file mode 100644 index 00000000..d9278fb5 --- /dev/null +++ b/requirements_testing.txt @@ -0,0 +1,7 @@ +-r requirements.txt + +openturns +gitpython +inflection +bs4 +pytest \ No newline at end of file diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 4018a1e8..00000000 --- a/setup.cfg +++ /dev/null @@ -1,3 +0,0 @@ -[mypy] -install_types = true -non_interactive = true \ No newline at end of file diff --git a/single_calc.py b/single_calc.py new file mode 100644 index 00000000..0af4bdd7 --- /dev/null +++ b/single_calc.py @@ -0,0 +1,10 @@ +from geoprob_pipe.calculations.systems.single_calc import create_single_calc +from geoprob_pipe.calculations.systems.base_objects.system_calculation import ( + SystemCalculation + ) + +calc: SystemCalculation = create_single_calc( + geopackage_filepath=r"C:\Users\vinji\Python\GEOprob-Pipe\Bestandenuitwisseling\Analyse16-1_V5.geoprob_pipe\Analyse16-1_V5.geoprob_pipe.gpkg", + uittredepunt_id=160, + ondergrondscenario_naam="PL", +) diff --git a/tests/__init__.py b/tests/__init__.py index c57acdc5..e69de29b 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1,3 +0,0 @@ -# FIXME? Deze tests zijn een kopie van de code van Sander. Moeten we uitzoeken welke gebruikt worden, en welke niet? -# Indien gebruiken: unit tests plaatsen bij code i.p.v. een aparte map. Deze 'tests' folder is overigens uitgesloten -# in de workflow. \ No newline at end of file diff --git a/tests/calculations/__init__.py b/tests/calculations/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/calculations/limit_states/__init__.py b/tests/calculations/limit_states/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/calculations/limit_states/test_piping_lm.py b/tests/calculations/limit_states/test_piping_lm.py new file mode 100644 index 00000000..21158754 --- /dev/null +++ b/tests/calculations/limit_states/test_piping_lm.py @@ -0,0 +1,264 @@ +"""Tests for piping limit state calculations in piping_lm.py. There are three functions to be tested: +- limit_state_wbi +- limit_state_model4a +- limit_state_moria + +""" + +from pathlib import Path + +import pytest + +from geoprob_pipe.calculations.limit_states import piping_lm +from geoprob_pipe.calculations.systems.mappers.calculation_mapper import ( + CALCULATION_MAPPER) + +testset_path = Path( + Path(__file__).resolve(strict=True).parents[3], + "tests/testset", + "testset_limitstate_piping.xlsx", +) + + +def get_data(): + """Get data for testing""" + import pandas as pd + + data = pd.read_excel(testset_path, sheet_name="Blad1", header=0) + return data + + +# define input and output keys +input_keys_lm_wbi = [ + "L_kwelweg", "buitenwaterstand", "polderpeil", "mv_exit", "top_zand", + "r_exit", "k_wvp", "D_wvp", "d70", "gamma_sat_deklaag", "modelfactor_u", + "modelfactor_h", "modelfactor_p", "modelfactor_ff", "modelfactor_3d", + "modelfactor_aniso", "modelfactor_ml", "i_c_h", "r_c_deklaag", "d70_m", + "gamma_korrel", "v", "theta", "eta", "g", "gamma_water", +] + +output_keys_lm_wbi = [ + "z_u", "z_h", "z_p", "z_combin", "h_exit", "phi_exit", "dphi_c_u", + "i_exit", "dh_c", "dh_red", +] + +input_keys_lm_model4a = [ + "L_intrede", "L_but", "L_bit", "L_achterland", "buitenwaterstand", + "polderpeil", "mv_exit", "top_zand", "kD_wvp", "D_wvp", "d70", + "gamma_sat_deklaag", "c_voorland", "c_achterland", "modelfactor_u", + "modelfactor_h", "modelfactor_p", "modelfactor_ff", "modelfactor_3d", + "modelfactor_aniso", "modelfactor_ml", "i_c_h", "r_c_deklaag", "d70_m", + "gamma_korrel", "v", "theta", "eta", "g", "gamma_water", +] + +output_keys_lm_model4a = [ + "z_u", "z_h", "z_p", "z_combin", "h_exit", "r_exit", "phi_exit", + "d_deklaag", "dphi_c_u", "i_exit", "L_voorland", "lambda_voorland", + "W_voorland", "L_kwelweg", "dh_c", "dh_red", +] + +input_keys_lm_moria = [ + "L_intrede", + "L_but", + "buitenwaterstand", + "buitenwaterstand_gemiddeld", + "polderpeil", + "mv_exit", + "lambda_voorland", + "phi_exit_gemiddeld", + "r_exit", + "top_zand", + "k_wvp", + "D_wvp", + "d70", + "gamma_sat_deklaag", + "modelfactor_u", + "modelfactor_h", + "modelfactor_p", + "modelfactor_ff", + "modelfactor_3d", + "modelfactor_aniso", + "modelfactor_ml", + "i_c_h", + "r_c_deklaag", + "d70_m", + "gamma_korrel", + "v", + "theta", + "eta", + "g", + "gamma_water", +] + +output_keys_lm_moria = [ + "z_u", + "z_h", + "z_p", + "z_combin", + "h_exit", + "r_exit", + "phi_exit", + "d_deklaag", + "dphi_c_u", + "i_exit", + "L_voorland", + "W_voorland", + "L_kwelweg", + "kD_wvp", + "dh_c", + "dh_red", +] + +# global variables +# G = 9.81 # m/s^2 +# V = 1.33e-6 # m^2/s +# ETA = 0.25 # [-] +# THETA = 37.0 # grd +# GAMMA_KORREL = 26.0 # kN/m^3 +# GAMMA_WATER = 9.81 # kN/m^3 +# D70_M = 2.08e-4 # m + +# setup test construct +test_data = get_data() + +# extract inputs and expected outputs for limit_state_wbi +inputs_lm_wbi = test_data.loc[:, input_keys_lm_wbi] + +# add global variables in dataframe in the right order +# inputs_lm_wbi["g"] = G +# inputs_lm_wbi["v"] = V +# inputs_lm_wbi["eta"] = ETA +# inputs_lm_wbi["theta"] = THETA +# inputs_lm_wbi["gamma_korrel"] = GAMMA_KORREL +# inputs_lm_wbi["gamma_water"] = GAMMA_WATER +# inputs_lm_wbi["d70_m"] = D70_M + +inputs_lm_wbi_dict = inputs_lm_wbi.to_dict(orient="records") +expected_outputs_lm_wbi = test_data[output_keys_lm_wbi].to_dict( + orient="records") + + +@pytest.mark.parametrize( + "input_data, expected", zip(inputs_lm_wbi_dict, expected_outputs_lm_wbi) +) +def test_limit_state_wbi(input_data, expected): + """Test limit_state_wbi function""" + results = piping_lm.limit_state_wbi( + L_kwelweg=input_data["L_kwelweg"], + buitenwaterstand=input_data["buitenwaterstand"], + polderpeil=input_data["polderpeil"], + mv_exit=input_data["mv_exit"], + top_zand=input_data["top_zand"], + r_exit=input_data["r_exit"], + k_wvp=input_data["k_wvp"], + D_wvp=input_data["D_wvp"], + d70=input_data["d70"], + gamma_sat_deklaag=input_data["gamma_sat_deklaag"], + modelfactor_u=input_data["modelfactor_u"], + modelfactor_h=input_data["modelfactor_h"], + modelfactor_p=input_data["modelfactor_p"], + modelfactor_ff=input_data["modelfactor_ff"], + modelfactor_3d=input_data["modelfactor_3d"], + modelfactor_aniso=input_data["modelfactor_aniso"], + modelfactor_ml=input_data["modelfactor_ml"], + i_c_h=input_data["i_c_h"], + r_c_deklaag=input_data["r_c_deklaag"], + d70_m=input_data["d70_m"], + gamma_korrel=input_data["gamma_korrel"], + v=input_data["v"], + theta=input_data["theta"], + eta=input_data["eta"], + g=input_data["g"], + gamma_water=input_data["gamma_water"], + ) + assert results[0] == pytest.approx(expected["z_u"], rel=1e-3) + assert results[1] == pytest.approx(expected["z_h"], rel=1e-3) + assert results[2] == pytest.approx(expected["z_p"], rel=1e-3) + assert results[3] == pytest.approx(expected["z_combin"], rel=1e-3) + assert results[4] == pytest.approx(expected["h_exit"], rel=1e-3) + assert results[5] == pytest.approx(expected["phi_exit"], rel=1e-3) + assert results[6] == pytest.approx(expected["dphi_c_u"], rel=1e-3) + assert results[7] == pytest.approx(expected["i_exit"], rel=1e-3) + assert results[8] == pytest.approx(expected["dh_c"], rel=1e-3) + assert results[9] == pytest.approx(expected["dh_red"], rel=1e-3) + + +# extract inputs and expected outputs for limit state_model4a +inputs_lm_model4a = test_data.loc[:, input_keys_lm_model4a].to_dict( + orient="records") +expected_outputs_lm_model4a = test_data[output_keys_lm_model4a].to_dict( + orient="records" +) + + +@pytest.mark.parametrize( + "input_data, expected", zip(inputs_lm_model4a, expected_outputs_lm_model4a) +) +def test_limit_state_model4a(input_data, expected): + """Test limit_state_model4a function""" + results = piping_lm.limit_state_model4a( + L_intrede=input_data["L_intrede"], + L_but=input_data["L_but"], + L_bit=input_data["L_bit"], + L_achterland=input_data["L_achterland"], + buitenwaterstand=input_data["buitenwaterstand"], + polderpeil=input_data["polderpeil"], + mv_exit=input_data["mv_exit"], + top_zand=input_data["top_zand"], + kD_wvp=input_data["kD_wvp"], + D_wvp=input_data["D_wvp"], + d70=input_data["d70"], + gamma_sat_deklaag=input_data["gamma_sat_deklaag"], + c_voorland=input_data["c_voorland"], + c_achterland=input_data["c_achterland"], + modelfactor_u=input_data["modelfactor_u"], + modelfactor_h=input_data["modelfactor_h"], + modelfactor_p=input_data["modelfactor_p"], + modelfactor_ff=input_data["modelfactor_ff"], + modelfactor_3d=input_data["modelfactor_3d"], + modelfactor_aniso=input_data["modelfactor_aniso"], + modelfactor_ml=input_data["modelfactor_ml"], + i_c_h=input_data["i_c_h"], + r_c_deklaag=input_data["r_c_deklaag"], + d70_m=input_data["d70_m"], + gamma_korrel=input_data["gamma_korrel"], + v=input_data["v"], + theta=input_data["theta"], + eta=input_data["eta"], + g=input_data["g"], + gamma_water=input_data["gamma_water"], + ) + assert results[0] == pytest.approx(expected["z_u"], rel=1e-3) + assert results[1] == pytest.approx(expected["z_h"], rel=1e-3) + assert results[2] == pytest.approx(expected["z_p"], rel=1e-3) + assert results[3] == pytest.approx(expected["z_combin"], rel=1e-3) + assert results[4] == pytest.approx(expected["h_exit"], rel=1e-3) + assert results[5] == pytest.approx(expected["r_exit"], rel=1) + assert results[6] == pytest.approx(expected["phi_exit"], rel=1e-3) + assert results[7] == pytest.approx(expected["d_deklaag"], rel=1e-3) + assert results[8] == pytest.approx(expected["dphi_c_u"], rel=1e-3) + assert results[9] == pytest.approx(expected["i_exit"], rel=1e-3) + assert results[10] == pytest.approx(expected["L_voorland"], rel=1e-3) + assert results[11] == pytest.approx(expected["lambda_voorland"], rel=1e-3) + assert results[12] == pytest.approx(expected["W_voorland"], rel=1e-3) + assert results[13] == pytest.approx(expected["L_kwelweg"], rel=1e-3) + assert results[14] == pytest.approx(expected["dh_c"], rel=1e-3) + assert results[15] == pytest.approx(expected["dh_red"], rel=1e-3) + + +# extract inputs and expected outputs for limit_state_moria +inputs_lm_moria = test_data.loc[:, input_keys_lm_moria].to_dict( + orient="records") +expected_outputs_lm_moria = test_data[output_keys_lm_moria].to_dict( + orient="records") + + +@pytest.mark.parametrize( + "input_data, expected", zip(inputs_lm_moria, expected_outputs_lm_moria) +) +def test_limit_state_moria(input_data, expected): + """Test limit_state_moria function""" + results = piping_lm.limit_state_moria(**input_data) + result_keys = CALCULATION_MAPPER["moria"]["system_return_parameter_keys"] + for index, result_key in enumerate(result_keys): + assert results[index] == pytest.approx(expected[result_key], rel=1e-3) diff --git a/tests/calculations/physical_components/__init__.py b/tests/calculations/physical_components/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/test_geohydromodels.py b/tests/calculations/physical_components/test_geohydro_functions.py similarity index 87% rename from tests/test_geohydromodels.py rename to tests/calculations/physical_components/test_geohydro_functions.py index ca87a1bd..2ec45bfb 100644 --- a/tests/test_geohydromodels.py +++ b/tests/calculations/physical_components/test_geohydro_functions.py @@ -1,8 +1,6 @@ import math - import pytest - -from app.helper_functions import geohydro_functions +from geoprob_pipe.calculations.physical_components import geohydro_functions ## testcase model 4a # k = 40 #m/d @@ -33,14 +31,17 @@ def test_calc_lambda(): assert geohydro_functions.calc_lambda(2000.0, 10.0) == 141.4213562373095 +# noinspection PyPep8Naming def test_calc_W(): assert geohydro_functions.calc_W(141.4213562373095, 150.0) == 111.14536276273107 +# noinspection PyPep8Naming def test_calc_r_BIT(): assert geohydro_functions.calc_r_BIT(50.0, 35.0, 85.0) == 0.5 +# noinspection PyPep8Naming def test_calc_r_BUT(): assert geohydro_functions.calc_r_BUT(50.0, 25.0, 50.0) == 0.6 @@ -49,22 +50,23 @@ def test_calc_respons2pot(): assert geohydro_functions.calc_respons2pot(1.0, 0.5, 6.0) == (1.0 + 2.5) -def test_calc_pot2repons(): - assert geohydro_functions.calc_pot2repons(3.5, 1.0, 6.0) == 0.5 +def test_calc_pot2reponse(): + assert geohydro_functions.calc_pot2response(3.5, 1.0, 6.0) == 0.5 def test_calc_ang_freq(): assert geohydro_functions.calc_ang_frequency(math.pi) == 2.0 -def test_P_from_T(): +# noinspection PyPep8Naming +def test_P_from_T_and_vv(): assert geohydro_functions.calc_P_from_T(100.0) == 50.0 assert geohydro_functions.calc_T_from_P(200.0) == 400.0 def test_lambda_cyclic_from_stationary(): assert ( - geohydro_functions.calc_lambda_cycl_from_stationnary( + geohydro_functions.calc_lambda_cycl_from_stationary( 100.0, 8.0, 8e-6, geohydro_functions.calc_ang_frequency(12 * 3600) ) == 18.525960495667167 diff --git a/tests/test_model4a.py b/tests/calculations/physical_components/test_model4a.py similarity index 90% rename from tests/test_model4a.py rename to tests/calculations/physical_components/test_model4a.py index d10f5262..0c452f31 100644 --- a/tests/test_model4a.py +++ b/tests/calculations/physical_components/test_model4a.py @@ -1,6 +1,5 @@ import pytest - -from app.helper_functions import model4a +from geoprob_pipe.calculations.physical_components import model4a ## testcase model 4a # k = 40 #m/d @@ -29,7 +28,7 @@ def test_class_4a(): model = model4a.Model4a( - k=40.0, D=50.0, c1=10.0, c3=50.0, L1=150.0, L3=3000.0, x_but=0.0, x_bit=45.0 + kD=40.0*50.0, D=50.0, c1=10.0, c3=50.0, L1=150.0, L3=3000.0, x_but=0.0, x_bit=45.0 ) assert model.lambda1 == pytest.approx(141.4213562373095, abs=0.0001) assert model.lambda3 == pytest.approx(316.22776601683793319988935444327, abs=0.0001) diff --git a/tests/calculations/physical_components/test_piping.py b/tests/calculations/physical_components/test_piping.py new file mode 100644 index 00000000..41b231a9 --- /dev/null +++ b/tests/calculations/physical_components/test_piping.py @@ -0,0 +1,189 @@ +"""Test module for piping.py""" + +import pytest +from geoprob_pipe.calculations.physical_components import piping + +## testcase model 4a +# k = 40 #m/d +# D = 50 #m +# c1 = 10 #d +# c3 = 50 #d +# L1 = 150 #m +# L2 = 45 #m +# L3 = 3000.0 #m +# x_but = 0.0 #m +# x_bit = 45.0 #m +# lambda1 = 141.4213562373095 +# lambda3 = 316.22776601683793319988935444327 +# W1 = 111.14536276273107 +# W3 = 316.2277623787640000 +# W_tot4a = 472.373125141495 +# r_but = 0.76470853898 +# r_bit = 0.66944486371 +# r(-150.0) = 1.0 +# r(3045.0) = 0.0 +# r(-50.0) = 0.8579165276194 +# r(55.0) = 0.648606379956042 +# r(90.0) = 0.580648922902315 +# r(22.5) = 0.717076701341341 +# piping input +# D70 = 2.7E-4 m + + +# noinspection PyPep8Naming +def test_calc_Dcover(): + assert piping.calc_d_deklaag(0.0, 2.0) == 0.1 + assert piping.calc_d_deklaag(2.0, 1.0) == 1.0 + + +def test_calc_h_exit(): + assert piping.calc_h_exit(0.1, 2.0) == 2.0 + assert piping.calc_h_exit(0.0, 0.1) == 0.1 + assert piping.calc_h_exit(0.0, 0.000001) == 0.000001 + assert piping.calc_h_exit(0.0, 0.0) == 0.0 + + +def test_calc_lengte_voorland(): + assert piping.calc_lengte_voorland(500.0, 200.0) == 300.0 + assert piping.calc_lengte_voorland(200.0, 300.0) == 100.0 + assert piping.calc_lengte_voorland(0.0, 1.0) == 1.0 + assert piping.calc_lengte_voorland(1.0, 0.0) == 1.0 + assert piping.calc_lengte_voorland(0.0, 0.0) == 0.0 + + +def test_calc_lambda_achterland(): + assert piping.calc_lambda_achterland(50.0 * 40.0, 10.0) == pytest.approx( + 141.4213562373095, 0.0001 + ) + assert piping.calc_lambda_achterland(50.0 * 40.0, 50.0) == pytest.approx( + 316.22776601683793, 0.0001 + ) + + +def test_calc_lambda_voorland(): + assert piping.calc_lambda_voorland(50.0 * 40.0, 10.0) == pytest.approx( + 141.4213562373095, 0.0001 + ) + assert piping.calc_lambda_voorland(50.0 * 40.0, 50.0) == pytest.approx( + 316.22776601683793, 0.0001 + ) + + +def test_calc_dh_red(): + assert piping.calc_dh_red(5.0, 2.0, 0.3, 10.0) == pytest.approx( + (3.0 - 0.3 * 10), 0.0001 + ) + + +# noinspection PyPep8Naming +def test_calc_W_achterland(): + assert piping.calc_W_achterland( + piping.calc_lambda_achterland(50.0 * 40.0, 10.0), 150.0 + ) == pytest.approx(111.14536276273107, 0.0001) + assert piping.calc_W_achterland( + piping.calc_lambda_achterland(50.0 * 40.0, 50.0), 3500.0 + ) == pytest.approx(316.2277623787640000, 0.0001) + + +# noinspection PyPep8Naming +def test_calc_W_voorland(): + assert piping.calc_W_voorland( + piping.calc_lambda_achterland(50.0 * 40.0, 10.0), 150.0 + ) == pytest.approx(111.14536276273107, 0.0001) + assert piping.calc_W_voorland( + piping.calc_lambda_achterland(50.0 * 40.0, 50.0), 3500.0 + ) == pytest.approx(316.2277623787640000, 0.0001) + + +# noinspection PyPep8Naming +def test_calc_L_kwelweg(): + assert piping.calc_L_kwelweg(500.0, 200.0) == 700.0 + assert piping.calc_L_kwelweg(0.0, 0.0) == 0.0 + assert piping.calc_L_kwelweg(100.1, 0.4) == 100.5 + + +def test_calc_dphi_c_u(): + assert piping.calc_dphi_c_u(6.0, 15.0, 9.81) == pytest.approx(3.174, 0.0001) + assert piping.calc_dphi_c_u(0.0, 15.0, 9.81) == 0.0 + assert piping.calc_dphi_c_u(2.36690, 16.5, 9.81) == pytest.approx(1.614, 0.0001) + + +def test_calc_i_exit(): + assert piping.calc_i_exit(0.1, 0.1, 0.1) == 0.0 + assert piping.calc_i_exit(0.0, 1.0, 1.0) == -1.0 + assert piping.calc_i_exit(2.0, 1.0, 1.0) == 1.0 + with pytest.raises(ZeroDivisionError): + piping.calc_i_exit(2.0, 1.0, 0.0) + + +def test_calc_phi_exit(): + assert piping.calc_phi_exit(0.0, 0.5, 1.0) == 0.5 + assert piping.calc_phi_exit(1.0, 1.0, 1.0) == 1.0 + assert piping.calc_phi_exit(2.0, 1.0, 1.0) == 1.0 + assert piping.calc_phi_exit(0.0, 0.1, 1.0) == 0.1 + + +## Get data for testing calc_dh_c function +from pathlib import Path + +testset_path = Path( + Path(__file__).resolve(strict=True).parents[3], + "tests/testset", + "testset_limitstate_piping.xlsx", +) + + +def get_data_calc_dh_c(): + """Get data for testing calc_dh_c function""" + import pandas as pd + + data = pd.read_excel(testset_path, sheet_name="Blad1", header=0) + return data + + +# define input and output keys for calc_dh_c function +input_keys_calc_dh_c = [ + "d70", # i1 + "D_wvp", # i2 + "kD_wvp", # i3 + "L_kwelweg", # i4 + "gamma_water", # i5 +] + +output_key_calc_dh_c = ["dh_c"] # expected output + +# global variables for calc_dh_c function +G = 9.81 # m/s^2 +V = 1.33e-6 # m^2/s +ETA = 0.25 # [-] +THETA = 37.0 # grd +GAMMA_KORREL = 26.0 # kN/m^3 +D70_M = 2.08e-4 # m + +# setup test construct +data_calc_dh_c = get_data_calc_dh_c() +inputs_calc_dh_c = data_calc_dh_c[input_keys_calc_dh_c].to_dict(orient="records") +expected_outputs_calc_dh_c = data_calc_dh_c[output_key_calc_dh_c].to_dict( + orient="records" +) + + +@pytest.mark.parametrize( + "inputs, expected", zip(inputs_calc_dh_c, expected_outputs_calc_dh_c) +) +def test_calc_dh_c(inputs, expected): + """Test calc_dh_c function with multiple test cases from Excel file""" + result = piping.calc_dh_c( + d70=inputs["d70"], + D_wvp=inputs["D_wvp"], + kD_wvp=inputs["kD_wvp"], + L_kwelweg=inputs["L_kwelweg"], + gamma_water=inputs["gamma_water"], + g=G, + v=V, + theta=THETA, + eta=ETA, + d70_m=D70_M, + gamma_korrel=GAMMA_KORREL, + ) + assert result == pytest.approx(expected["dh_c"], 0.01) diff --git a/tests/calculations/systems/__init__.py b/tests/calculations/systems/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/calculations/systems/moria/__init__.py b/tests/calculations/systems/moria/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/calculations/systems/moria/test_calculation.py b/tests/calculations/systems/moria/test_calculation.py new file mode 100644 index 00000000..5db2b736 --- /dev/null +++ b/tests/calculations/systems/moria/test_calculation.py @@ -0,0 +1,46 @@ + + +def test_calculation(): + + ## + from probabilistic_library import Alpha + from geoprob_pipe.calculations.systems.moria.reliability_calculation import ( + MORIACalculation) + from geoprob_pipe.calculations.systems.moria.initial_input import ( + INITIAL_INPUT) + + obj = MORIACalculation(system_variable_distributions=INITIAL_INPUT) + + # Run prob system + obj.run() + assert obj.validation_messages.cnt == 0 + + # Model resultaten + print(f"\nModellen:") + for design_point in obj.model_design_points: + print(f"{design_point.identifier=}") + print(f" {design_point.is_converged=}") + print(f" {design_point.reliability_index=}") + for alpha in design_point.alphas: + alpha: Alpha + print(f" {alpha.variable.name=}, {alpha.alpha=}, {alpha.alpha*alpha.alpha=}") + alphas_values = [alpha.alpha for alpha in design_point.alphas] + invloedsfactoren = [value * value for value in alphas_values] + sum_invloedsfactoren = round(sum(invloedsfactoren), 2) + assert sum_invloedsfactoren == 1.00, \ + f"De som van de invloedsfactoren ({sum_invloedsfactoren=}) is niet gelijk aan aan 1.00." + + # Systeem resultaten + print(f"\nSysteem:") + beta = obj.system_design_point.reliability_index + print(f" {beta=}") + for alpha in obj.system_design_point.alphas: + alpha: Alpha + print(f" {alpha.variable.name=}, {alpha.alpha=}, {alpha.alpha*alpha.alpha=}") + alphas_values = [alpha.alpha for alpha in obj.system_design_point.alphas] + invloedsfactoren = [value * value for value in alphas_values] + sum_invloedsfactoren = round(sum(invloedsfactoren), 2) + assert sum_invloedsfactoren == 1.00, \ + f"De som van de invloedsfactoren ({sum_invloedsfactoren=}) is niet gelijk aan aan 1.00." + + ## diff --git a/tests/calculations/systems/system/__init__.py b/tests/calculations/systems/system/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/calculations/systems/system/test_calculation.py b/tests/calculations/systems/system/test_calculation.py new file mode 100644 index 00000000..6ca54ff9 --- /dev/null +++ b/tests/calculations/systems/system/test_calculation.py @@ -0,0 +1,63 @@ + + +def test_calculation(): + # TODO Later Should Klein: Nadenken hoe we binnen een half uur een + # quick scan piping kunnen uitvoeren met het object. + # Is het daarvoor te complex? + + ## + from probabilistic_library import Alpha + from geoprob_pipe.calculations.systems.model4a.reliability_calculation import ( + Model4aCalculation) + from geoprob_pipe.calculations.systems.mappers.initial_input_mapper import INITIAL_INPUT_MAPPER + # from pprint import pprint + # pprint(f"{INITIAL_INPUT_MAPPER['model4a']=}") + # pprint(f"{INITIAL_INPUT_MAPPER['model4a']['label']=}") + # pprint(f"{INITIAL_INPUT_MAPPER['model4a']['input']=}") + # pprint(f"{INITIAL_INPUT_MAPPER['model4a'].keys()=}") + # raise ValueError + obj = Model4aCalculation( + system_variable_distributions=INITIAL_INPUT_MAPPER['model4a']['input']) + + # Run prob system + obj.run() + + # Model resultaten + print(f"\nModellen:") + for design_point in obj.model_design_points: + print(f"{design_point.identifier=}") + print(f" {design_point.is_converged=}") + print(f" {design_point.reliability_index=}") + for alpha in design_point.alphas: + alpha: Alpha + print(f" {alpha.variable.name=}, {alpha.alpha=}, " + f"{alpha.alpha*alpha.alpha=}") + alphas_values = [alpha.alpha for alpha in design_point.alphas] + invloedsfactoren = [value * value for value in alphas_values] + sum_invloedsfactoren = round(sum(invloedsfactoren), 2) + assert sum_invloedsfactoren == 1.00, \ + (f"De som van de invloedsfactoren ({sum_invloedsfactoren=}) is " + f"niet gelijk aan aan 1.00.") + + # Systeem resultaten + print(f"\nSysteem:") + beta = obj.system_design_point.reliability_index + print(f" {beta=}") + for alpha in obj.system_design_point.alphas: + alpha: Alpha + print(f" {alpha.variable.name=}, {alpha.alpha=}, " + f"{alpha.alpha*alpha.alpha=}") + alphas_values = [alpha.alpha for alpha in obj.system_design_point.alphas] + invloedsfactoren = [value * value for value in alphas_values] + sum_invloedsfactoren = round(sum(invloedsfactoren), 2) + assert sum_invloedsfactoren == 1.00, \ + (f"De som van de invloedsfactoren ({sum_invloedsfactoren=}) is niet " + f"gelijk aan aan 1.00.") + + # TODO Nu Must Middel: Optie toevoegen dat + # ParallelSystemReliabilityCalculation ook deterministisch word + # uitgerekend + # Dit doen door gemiddelde waarden te gebruiken. + # TODO Nu Must Middel: Assert toevoegen die piping resultaat unit test + + ## diff --git a/tests/calculations/systems/wbi/__init__.py b/tests/calculations/systems/wbi/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/calculations/systems/wbi/test_calculation.py b/tests/calculations/systems/wbi/test_calculation.py new file mode 100644 index 00000000..5b9b377e --- /dev/null +++ b/tests/calculations/systems/wbi/test_calculation.py @@ -0,0 +1,45 @@ + + +def test_calculation(): + + ## + from probabilistic_library import Alpha + from geoprob_pipe.calculations.systems.wbi.reliability_calculation import ( + WBICalculation) + from geoprob_pipe.calculations.systems.wbi.initial_input import INITIAL_INPUT + + obj = WBICalculation(system_variable_distributions=INITIAL_INPUT) + + # Run prob system + obj.run() + assert obj.validation_messages.cnt == 0 + + # Model resultaten + print(f"\nModellen:") + for design_point in obj.model_design_points: + print(f"{design_point.identifier=}") + print(f" {design_point.is_converged=}") + print(f" {design_point.reliability_index=}") + for alpha in design_point.alphas: + alpha: Alpha + print(f" {alpha.variable.name=}, {alpha.alpha=}, {alpha.alpha*alpha.alpha=}") + alphas_values = [alpha.alpha for alpha in design_point.alphas] + invloedsfactoren = [value * value for value in alphas_values] + sum_invloedsfactoren = round(sum(invloedsfactoren), 2) + assert sum_invloedsfactoren == 1.00, \ + f"De som van de invloedsfactoren ({sum_invloedsfactoren=}) is niet gelijk aan aan 1.00." + + # Systeem resultaten + print(f"\nSysteem:") + beta = obj.system_design_point.reliability_index + print(f" {beta=}") + for alpha in obj.system_design_point.alphas: + alpha: Alpha + print(f" {alpha.variable.name=}, {alpha.alpha=}, {alpha.alpha*alpha.alpha=}") + alphas_values = [alpha.alpha for alpha in obj.system_design_point.alphas] + invloedsfactoren = [value * value for value in alphas_values] + sum_invloedsfactoren = round(sum(invloedsfactoren), 2) + assert sum_invloedsfactoren == 1.00, \ + f"De som van de invloedsfactoren ({sum_invloedsfactoren=}) is niet gelijk aan aan 1.00." + + ## diff --git a/tests/datastructure/Variable_definition.xlsx b/tests/datastructure/Variable_definition.xlsx deleted file mode 100644 index d9bb8ecf..00000000 Binary files a/tests/datastructure/Variable_definition.xlsx and /dev/null differ diff --git a/tests/datastructure/create_datastructure.py b/tests/datastructure/create_datastructure.py deleted file mode 100644 index 5d310b4e..00000000 --- a/tests/datastructure/create_datastructure.py +++ /dev/null @@ -1,151 +0,0 @@ -"""Define and create a datastructure and variables for the app -Deze code geeft in hoofdlijnen aan welke velden er in de verschillende tabellen zitten. De tabellen zijn: 1) vakken, 2) uittredepunten en 3) ondergrondscenarios.""" - -import os -from dataclasses import dataclass - -import pandas as pd - -# Define the input variables for the functions for Uplift, Heave and Piping -# dist_L_geom: float -# dist_BUT: float -# dist_BIT: float -# L3_geom: float -# mv: float -# pp: float -# top_zand: float -# gamma_sat_cover: float -# gamma_w: float -# kD: float -# D: float -# d70: float -# c1: float -# c3: float -# mu: float -# mh: float -# mp: float -# i_c_h: float -# rc: float -# h: float - - -@dataclass -class Variables: - """Class to store a description of the variables used in the model.""" - - VariableName: str # name of the variable - VariableDescription: str # description of the variable - VariableUnit: str # dimension of the variable - VariableType: str # Input, Output, Constant, Calculated - VariableDistribution: str # Lognormal, Normal, Deterministic, n.b. CalculationSettings in different class - VariableSpreidingstype: str # _mean, _stdev, _vc - VariableDefaultValue: float - VariableLowerBound: float - VariableUpperBound: float - VariableMemberOf: str # name of the group the variable belongs to - - -@dataclass -class Vakken: - VakID: int - Vaknaam: str - M_van: float - M_tot: float - Vaklengte: float - mv_achterland_vak: float - L_achterland: float - c_voorland_mean: float - c_voorland_vc: float - #c_achterland_mean: float # to be calculated in the model - c_achterland_vc: float - - -@dataclass -class Uittredepunten: - UittredepuntID: int - X_uitrede: float - Y_uitrede: float - Uitredelocatie: str - Mvalue: float - VakID: int - Vaknaam: str - L_intrede: float - L_but: float - L_bit: float - HydraLocatieID: str - buitenwaterstand: float - mv_exit: float - polderpeil: float - modelfactor_u_mean: float - modelfactor_u_stdev: float - modelfactor_h_mean: float - modelfactor_h_stdev: float - modelfactor_p_mean: float - modelfactor_p_stdev: float - - - -@dataclass -class Ondergrondscenarios: - OndergrondscenarioID: int - VakID: int - ScenarioID: int - Scenarionaam: str - Scenariokans: float - top_zand_mean: float - top_zand_stdev: float - gamma_sat_deklaag_mean: float - gamma_sat_deklaag_stdev: float - D_wvp_mean: float - D_wvp_stdev: float - kD_wvp_mean: float - kD_wvp_vc: float - k_wvp_mean: float - d70_mean: float - d70_vc: float - -def create_table_from_dataclass(dataclass): - """Create a pandas DataFrame from a dataclass instance.""" - # Get the field names and values from the dataclass - field_names = [field.name for field in dataclass.__dataclass_fields__.values()] - # field_values = [getattr(dataclass_instance, field) for field in field_names] - # Create a DataFrame with the field names as columns and the values as a single row - df = pd.DataFrame(columns=field_names) - return df - - -if __name__ == "__main__": - # Need to creat a excel file with the dataclass instances - # Create dataframes of the dataclasses - variable_table = create_table_from_dataclass(Variables) - - filepath_variable_table = "tests/datastructure/variable_definition_generated.xlsx" - # if file exists, do not create a new file - if not os.path.exists(filepath_variable_table): - variable_table.to_excel( - filepath_variable_table, sheet_name="Variables", index=False - ) - print(f"Excel file {filepath_variable_table} created.") - else: - print( - f"File {filepath_variable_table} already exists. Not creating a new file." - ) - - vakken_table = create_table_from_dataclass(Vakken) - uittredepunten_table = create_table_from_dataclass(Uittredepunten) - ondergrondscenarios_table = create_table_from_dataclass(Ondergrondscenarios) - - filepath_datastructure = "tests/datastructure/example_datastructure.xlsx" - - # Create a dictionary to hold the dataframes - dataframes = { - "Vakken": vakken_table, - "Uittredepunten": uittredepunten_table, - "Ondergrondscenarios": ondergrondscenarios_table, - } - # Create a Pandas Excel writer using XlsxWriter as the engine. - with pd.ExcelWriter(filepath_datastructure, engine="openpyxl") as writer: - # Write each dataframe to a different worksheet. - for sheet_name, df in dataframes.items(): - df.to_excel(writer, sheet_name=sheet_name, index=False) - print(f"Excel file {filepath_datastructure} created.") diff --git a/tests/datastructure/variable_definition_generated.xlsx b/tests/datastructure/variable_definition_generated.xlsx deleted file mode 100644 index 76f2b2bd..00000000 Binary files a/tests/datastructure/variable_definition_generated.xlsx and /dev/null differ diff --git a/tests/questionnaire/__init__.py b/tests/questionnaire/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/questionnaire/test_pre_processing.py b/tests/questionnaire/test_pre_processing.py new file mode 100644 index 00000000..e61ad59b --- /dev/null +++ b/tests/questionnaire/test_pre_processing.py @@ -0,0 +1,17 @@ + + +def test_questionnaire(): + + ## + + from geoprob_pipe.cmd_app.cmd import ApplicationSettings + from repo_utils.utils import repository_root_path + import os + + # Create application settings + app_settings = ApplicationSettings() + repo_root = repository_root_path() + app_settings.workspace_dir = os.path.join(repo_root, "geoprob_pipe", "questionnaire", "test_files") + app_settings.geopackage_filename = os.path.basename("Analyse224.geoprob_pipe.gpkg") + + ## diff --git a/tests/systeem_testen/224/Traject224_MORIA_WBN_det_corr.geoprob_pipe.gpkg b/tests/systeem_testen/224/Traject224_MORIA_WBN_det_corr.geoprob_pipe.gpkg new file mode 100644 index 00000000..02636b97 Binary files /dev/null and b/tests/systeem_testen/224/Traject224_MORIA_WBN_det_corr.geoprob_pipe.gpkg differ diff --git a/tests/systeem_testen/224/Traject224_MORIA_WBN_det_uncorr.geoprob_pipe.gpkg b/tests/systeem_testen/224/Traject224_MORIA_WBN_det_uncorr.geoprob_pipe.gpkg new file mode 100644 index 00000000..01b5a842 Binary files /dev/null and b/tests/systeem_testen/224/Traject224_MORIA_WBN_det_uncorr.geoprob_pipe.gpkg differ diff --git a/tests/systeem_testen/224/Traject224_MORIA_WBN_prob.geoprob_pipe.gpkg b/tests/systeem_testen/224/Traject224_MORIA_WBN_prob.geoprob_pipe.gpkg new file mode 100644 index 00000000..1e6d26aa Binary files /dev/null and b/tests/systeem_testen/224/Traject224_MORIA_WBN_prob.geoprob_pipe.gpkg differ diff --git a/tests/systeem_testen/224/Traject224_model4a_WBN_prob.geoprob_pipe.gpkg b/tests/systeem_testen/224/Traject224_model4a_WBN_prob.geoprob_pipe.gpkg new file mode 100644 index 00000000..87b7673e Binary files /dev/null and b/tests/systeem_testen/224/Traject224_model4a_WBN_prob.geoprob_pipe.gpkg differ diff --git a/tests/systeem_testen/224/ahn/ahn.tif b/tests/systeem_testen/224/ahn/ahn.tif new file mode 100644 index 00000000..fe17d79a Binary files /dev/null and b/tests/systeem_testen/224/ahn/ahn.tif differ diff --git a/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1059/delta_beta_map.html b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1059/delta_beta_map.html new file mode 100644 index 00000000..68772c7b --- /dev/null +++ b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1059/delta_beta_map.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1059/delta_beta_map.png b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1059/delta_beta_map.png new file mode 100644 index 00000000..f1152f87 Binary files /dev/null and b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1059/delta_beta_map.png differ diff --git a/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1059/dumbbell_beta.html b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1059/dumbbell_beta.html new file mode 100644 index 00000000..b45dbb19 --- /dev/null +++ b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1059/dumbbell_beta.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1059/dumbbell_beta.png b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1059/dumbbell_beta.png new file mode 100644 index 00000000..996d7f2d Binary files /dev/null and b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1059/dumbbell_beta.png differ diff --git a/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1059/dumbbell_heave.html b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1059/dumbbell_heave.html new file mode 100644 index 00000000..8e9e5236 --- /dev/null +++ b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1059/dumbbell_heave.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1059/dumbbell_heave.png b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1059/dumbbell_heave.png new file mode 100644 index 00000000..e53fa91b Binary files /dev/null and b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1059/dumbbell_heave.png differ diff --git a/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1059/dumbbell_piping.html b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1059/dumbbell_piping.html new file mode 100644 index 00000000..2e09e2b7 --- /dev/null +++ b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1059/dumbbell_piping.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1059/dumbbell_piping.png b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1059/dumbbell_piping.png new file mode 100644 index 00000000..38dc4269 Binary files /dev/null and b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1059/dumbbell_piping.png differ diff --git a/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1059/dumbbell_uplift.html b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1059/dumbbell_uplift.html new file mode 100644 index 00000000..26086947 --- /dev/null +++ b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1059/dumbbell_uplift.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1059/dumbbell_uplift.png b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1059/dumbbell_uplift.png new file mode 100644 index 00000000..e1941d9a Binary files /dev/null and b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1059/dumbbell_uplift.png differ diff --git a/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1059/ratio_beta_map.html b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1059/ratio_beta_map.html new file mode 100644 index 00000000..4c68b275 --- /dev/null +++ b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1059/ratio_beta_map.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1059/ratio_beta_map.png b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1059/ratio_beta_map.png new file mode 100644 index 00000000..e314da16 Binary files /dev/null and b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1059/ratio_beta_map.png differ diff --git a/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1105/delta_beta_map.html b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1105/delta_beta_map.html new file mode 100644 index 00000000..b6623dbf --- /dev/null +++ b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1105/delta_beta_map.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1105/delta_beta_map.png b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1105/delta_beta_map.png new file mode 100644 index 00000000..f1152f87 Binary files /dev/null and b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1105/delta_beta_map.png differ diff --git a/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1105/dumbbell_beta.html b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1105/dumbbell_beta.html new file mode 100644 index 00000000..1b48434d --- /dev/null +++ b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1105/dumbbell_beta.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1105/dumbbell_beta.png b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1105/dumbbell_beta.png new file mode 100644 index 00000000..996d7f2d Binary files /dev/null and b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1105/dumbbell_beta.png differ diff --git a/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1105/dumbbell_heave.html b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1105/dumbbell_heave.html new file mode 100644 index 00000000..a8efeb42 --- /dev/null +++ b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1105/dumbbell_heave.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1105/dumbbell_heave.png b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1105/dumbbell_heave.png new file mode 100644 index 00000000..e53fa91b Binary files /dev/null and b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1105/dumbbell_heave.png differ diff --git a/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1105/dumbbell_piping.html b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1105/dumbbell_piping.html new file mode 100644 index 00000000..db415dae --- /dev/null +++ b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1105/dumbbell_piping.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1105/dumbbell_piping.png b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1105/dumbbell_piping.png new file mode 100644 index 00000000..38dc4269 Binary files /dev/null and b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1105/dumbbell_piping.png differ diff --git a/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1105/dumbbell_uplift.html b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1105/dumbbell_uplift.html new file mode 100644 index 00000000..ee15fb25 --- /dev/null +++ b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1105/dumbbell_uplift.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1105/dumbbell_uplift.png b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1105/dumbbell_uplift.png new file mode 100644 index 00000000..e1941d9a Binary files /dev/null and b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1105/dumbbell_uplift.png differ diff --git a/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1105/ratio_beta_map.html b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1105/ratio_beta_map.html new file mode 100644 index 00000000..4a65584f --- /dev/null +++ b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1105/ratio_beta_map.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1105/ratio_beta_map.png b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1105/ratio_beta_map.png new file mode 100644 index 00000000..e314da16 Binary files /dev/null and b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1105/ratio_beta_map.png differ diff --git a/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1109/delta_beta_map.html b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1109/delta_beta_map.html new file mode 100644 index 00000000..e24a84c3 --- /dev/null +++ b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1109/delta_beta_map.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1109/delta_beta_map.png b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1109/delta_beta_map.png new file mode 100644 index 00000000..0f87c203 Binary files /dev/null and b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1109/delta_beta_map.png differ diff --git a/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1109/dumbbell_beta.html b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1109/dumbbell_beta.html new file mode 100644 index 00000000..3e326ea5 --- /dev/null +++ b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1109/dumbbell_beta.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1109/dumbbell_beta.png b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1109/dumbbell_beta.png new file mode 100644 index 00000000..996d7f2d Binary files /dev/null and b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1109/dumbbell_beta.png differ diff --git a/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1109/dumbbell_heave.html b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1109/dumbbell_heave.html new file mode 100644 index 00000000..97fb4653 --- /dev/null +++ b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1109/dumbbell_heave.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1109/dumbbell_heave.png b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1109/dumbbell_heave.png new file mode 100644 index 00000000..e53fa91b Binary files /dev/null and b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1109/dumbbell_heave.png differ diff --git a/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1109/dumbbell_piping.html b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1109/dumbbell_piping.html new file mode 100644 index 00000000..9889aef5 --- /dev/null +++ b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1109/dumbbell_piping.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1109/dumbbell_piping.png b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1109/dumbbell_piping.png new file mode 100644 index 00000000..38dc4269 Binary files /dev/null and b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1109/dumbbell_piping.png differ diff --git a/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1109/dumbbell_uplift.html b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1109/dumbbell_uplift.html new file mode 100644 index 00000000..47e2bd94 --- /dev/null +++ b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1109/dumbbell_uplift.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1109/dumbbell_uplift.png b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1109/dumbbell_uplift.png new file mode 100644 index 00000000..e1941d9a Binary files /dev/null and b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1109/dumbbell_uplift.png differ diff --git a/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1109/ratio_beta_map.html b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1109/ratio_beta_map.html new file mode 100644 index 00000000..0cedb54b --- /dev/null +++ b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1109/ratio_beta_map.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1109/ratio_beta_map.png b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1109/ratio_beta_map.png new file mode 100644 index 00000000..e314da16 Binary files /dev/null and b/tests/systeem_testen/224/comparisons/Traject224_model4a_WBN_prob_Traject224_MORIA_WBN_prob_2026-01-07_1109/ratio_beta_map.png differ diff --git a/tests/systeem_testen/224/frag_csv_files/041-02_0040_9_WA_km0897_hfreq.csv b/tests/systeem_testen/224/frag_csv_files/041-02_0040_9_WA_km0897_hfreq.csv new file mode 100644 index 00000000..759021a7 --- /dev/null +++ b/tests/systeem_testen/224/frag_csv_files/041-02_0040_9_WA_km0897_hfreq.csv @@ -0,0 +1,501 @@ +waarde,kans +10.8752419764628,0.1224847 +10.88640936898016,0.1194921142 +10.89919782658111,0.11657264422 +10.91071814944605,0.11372450367 +10.92196406981688,0.11094594982 +10.93450627904781,0.10823528249 +10.94530646342082,0.10559084307 +10.95736837534407,0.10301101344 +10.96931762822194,0.10049421505 +10.98258176506693,0.098038907884 +10.99214482111838,0.095643589581 +11.00380372355161,0.093306794468 +11.01592496742694,0.09102709269 +11.027478104316,0.088803089322 +11.03798908142681,0.086633423524 +11.04964429999745,0.084516767703 +11.06152204013276,0.082451826701 +11.07144359219538,0.080437337005 +11.08368927435152,0.078472065974 +11.09333492402493,0.076554811079 +11.10616612590963,0.074684399177 +11.11654386274247,0.072859685783 +11.12736743264937,0.071079554376 +11.13727303380211,0.069342915716 +11.14946812509155,0.067648707173 +11.16035346336881,0.065995892082 +11.17005122125278,0.064383459103 +11.18389795317262,0.062810421608 +11.19354263902081,0.061275817074 +11.20623290101684,0.059778706494 +11.21806956653945,0.058318173804 +11.22783865946019,0.056893325321 +11.23853342324234,0.055503289197 +11.25246095977608,0.054147214885 +11.2607715683763,0.05282427262 +11.27390563444543,0.051533652907 +11.286356196752,0.050274566033 +11.29634404138993,0.049046241577 +11.3080382218385,0.04784792794 +11.32006979648143,0.046678891891 +11.32969453083488,0.045538418108 +11.34158129176246,0.044425808749 +11.35429493494949,0.043340383022 +11.3652639245173,0.042281476767 +11.37430975667893,0.041248442053 +11.38862324362872,0.040240646777 +11.39953937758147,0.039257474281 +11.41149688207134,0.038298322973 +11.42236525171318,0.03736260596 +11.43304182507558,0.036449750688 +11.44245693705417,0.035559198591 +11.45797641118255,0.034690404751 +11.46773299272315,0.033842837563 +11.47827391803651,0.03301597841 +11.49082976156549,0.032209321348 +11.50136529661708,0.031422372792 +11.51517846811476,0.030654651218 +11.52677805701145,0.029905686866 +11.53530850111356,0.029175021452 +11.5436221689992,0.028462207893 +11.55994742628389,0.027766810025 +11.5692144766868,0.027088402342 +11.58427392819616,0.026426569736 +11.59473136599262,0.025780907237 +11.60313623840349,0.025151019774 +11.61590106930517,0.024536521925 +11.62869821304114,0.023937037686 +11.63735043053155,0.02335220024 +11.65155297343447,0.022781651731 +11.65985434008179,0.022225043048 +11.67057165745956,0.021682033609 +11.68713527480728,0.021152291152 +11.6957548064912,0.020635491533 +11.70373997528914,0.020131318531 +11.7143315719468,0.019639463646 +11.72920623804223,0.019159625918 +11.73866936070617,0.018691511741 +11.75370408205615,0.018234834682 +11.7604419485103,0.017789315303 +11.77193038089591,0.017354680999 +11.78559775916714,0.01693066582 +11.79519399930488,0.016517010317 +11.80361377954927,0.016113461379 +11.81366394709124,0.01571977208 +11.82828164121065,0.015335701524 +11.8375415565833,0.014961014705 +11.84649372931682,0.014595482355 +11.86087692235887,0.01423888081 +11.869561197303,0.013890991869 +11.87936352882598,0.013551602663 +11.891958914445,0.013220505524 +11.90266804161659,0.012897497858 +11.91142549732896,0.012582382019 +11.92093225447719,0.012274965192 +11.93455968761194,0.011975059273 +11.9428554824879,0.011682480752 +11.95666843489068,0.011397050604 +11.96446072465106,0.011118594178 +11.97393353501283,0.010846941089 +11.98274267649509,0.010581925116 +11.99568488035878,0.0103233841 +12.00519928852861,0.010071159841 +12.01357857425,0.0098250980063 +12.02728488726427,0.0095850480343 +12.03551620403761,0.0093508630409 +12.04385168291316,0.0091223997309 +12.05664857871026,0.0088995183104 +12.06513409503523,0.0086820824009 +12.07254544910112,0.0084699589558 +12.07978460800549,0.0082630181794 +12.09314856415881,0.0080611334469 +12.1016513177845,0.0078641812275 +12.10847391680601,0.0076720410084 +12.11629020728772,0.0074845952213 +12.13032286284407,0.0073017291703 +12.13755508584403,0.0071233309618 +12.14527041713587,0.006949291436 +12.15898727955217,0.0067795041001 +12.16627088887078,0.0066138650634 +12.17340214072904,0.0064522729732 +12.18103624975758,0.0062946289532 +12.19023229265498,0.0061408365429 +12.19985248057195,0.0059908016385 +12.20693216460382,0.0058444324354 +12.21485975627937,0.005701639372 +12.22378559557498,0.0055623350749 +12.23212902623134,0.0054264343055 +12.23891020678536,0.0052938539076 +12.24777185474832,0.0051645127568 +12.25744651130719,0.0050383317109 +12.26473452990264,0.0049152335611 +12.27203457289328,0.0047951429851 +12.28096310329234,0.0046779865009 +12.28865822998009,0.0045636924219 +12.2956920792192,0.0044521908127 +12.30361329449595,0.0043434134469 +12.31160559166752,0.0042372937648 +12.32047331724336,0.0041337668332 +12.32668347641473,0.0040327693051 +12.33255557759731,0.0039342393812 +12.33816597539956,0.0038381167722 +12.34968820192467,0.003744342662 +12.35541450234178,0.0036528596711 +12.36109498889864,0.0035636118223 +12.36688437761356,0.0034765445057 +12.37592838530353,0.003391604446 +12.38291502172692,0.0033087396693 +12.3895069546365,0.0032278994717 +12.39546541572119,0.0031490343879 +12.40181986650505,0.0030720961613 +12.40888215698423,0.0029970377143 +12.41777589440456,0.0029238131196 +12.42389221908546,0.0028523775719 +12.4295443326295,0.0027826873606 +12.43689791273845,0.002714699843 +12.44476344076462,0.0026483734185 +12.45154450998453,0.0025836675027 +12.457181701691,0.0025205425027 +12.46338531877917,0.0024589597931 +12.46993270112532,0.0023988816922 +12.47638321821316,0.0023402714388 +12.4825115774544,0.0022830931702 +12.4883682069114,0.0022273118995 +12.4940752497336,0.0021728934948 +12.49969377769217,0.0021198046582 +12.50671047988074,0.0020680129053 +12.51280260691838,0.0020174865452 +12.51796780152865,0.0019681946614 +12.52426815610434,0.0019201070929 +12.53042699729692,0.0018731944154 +12.53774582847368,0.0018274279237 +12.54328621118158,0.0017827796136 +12.54822237858173,0.0017392221656 +12.553245083011,0.0016967289271 +12.55819300736724,0.0016552738973 +12.5670031383204,0.0016148317101 +12.57266092689167,0.0015753776195 +12.57873971594879,0.001536887484 +12.58378829655178,0.0014993377519 +12.58863007573399,0.0014627054471 +12.59697660555105,0.0014269681546 +12.60234184412054,0.0013921040071 +12.60836697650764,0.0013580916718 +12.6129677665337,0.0013249103369 +12.61724447501549,0.001292539699 +12.62216320944532,0.0012609599511 +12.62770198935998,0.0012301517697 +12.63472345000625,0.0012000963039 +12.64074357014068,0.0011707751629 +12.64539211466075,0.0011421704054 +12.65011152504131,0.0011142645287 +12.6555412415218,0.0010870404574 +12.66146984952883,0.0010604815334 +12.66834703885185,0.0010345715056 +12.67301665901073,0.00100929452 +12.67750465267585,0.00098463510984 +12.68232924386514,0.0009605781864 +12.68710766035599,0.00093710902949 +12.6922171338316,0.00091421327861 +12.69929266070992,0.00089187692413 +12.70472506929658,0.00087008629868 +12.70995371829814,0.00084882806884 +12.71494604210156,0.00082808922694 +12.7199842839033,0.00080785708314 +12.72629658975957,0.00078811925762 +12.73204783871099,0.00076886367303 +12.73695046072106,0.00075007854712 +12.74205668214375,0.00073175238547 +12.74721977981288,0.00071387397454 +12.75230084241076,0.00069643237472 +12.75752389547968,0.00067941691371 +12.7622276391963,0.00066281717994 +12.76795602240984,0.00064662301624 +12.7734912121987,0.00063082451359 +12.77869901622316,0.00061541200506 +12.78319088980487,0.00060037605992 +12.78775660814012,0.00058570747786 +12.79196180649602,0.00057139728334 +12.79696811431851,0.00055743672012 +12.80129963637566,0.00054381724589 +12.80484926879092,0.00053053052707 +12.80831217543904,0.00051756843365 +12.81406251861389,0.0005049230343 +12.81943217689597,0.00049258659143 +12.82385324829896,0.00048055155652 +12.82834720822933,0.00046881056548 +12.83283257356832,0.00045735643412 +12.83726964603617,0.00044618215381 +12.84212999116936,0.00043528088713 +12.84718943975931,0.00042464596372 +12.85388362411378,0.00041427087621 +12.85998605500798,0.00040414927618 +12.864315655702,0.00039427497036 +12.86852566698033,0.00038464191677 +12.87319324957426,0.00037524422107 +12.8778041420188,0.0003660761329 +12.88450704810396,0.00035713204243 +12.89129457079854,0.00034840647687 +12.8954133725377,0.00033989409715 +12.89957962176532,0.00033158969464 +12.90411279563063,0.00032348818799 +12.90849971844065,0.00031558461996 +12.91262362615266,0.00030787415446 +12.91674763010869,0.00030035207355 +12.92073743503007,0.00029301377455 +12.92465164768859,0.00028585476725 +12.92836834518843,0.00027887067113 +12.93125831258162,0.0002720572127 +12.93383683633149,0.0002654102229 +12.9363523607552,0.0002589256345 +12.93894695065492,0.00025259947966 +12.94286354898736,0.00024642788748 +12.94677288682603,0.00024040708163 +12.95082400016024,0.00023453337807 +12.9552286237717,0.00022880318272 +12.96117562236185,0.00022321298937 +12.9653369938745,0.00021775937742 +12.96978095597221,0.00021243900989 +12.97501224376404,0.00020724863129 +12.97982562709268,0.00020218506571 +12.98441408350143,0.00019724521479 +12.99148448646336,0.00019242605592 +12.99562068314129,0.00018772464029 +13.00026788940046,0.00018313809116 +13.00693775117047,0.00017866360209 +13.01135910209787,0.00017429843518 +13.01590804717445,0.00017003991945 +13.0209288483109,0.00016588544914 +13.02604835650768,0.0001618324822 +13.03144900142397,0.00015787853866 +13.0370377238844,0.00015402119914 +13.04033090076449,0.00015025810339 +13.04320735157283,0.00014658694882 +13.04592017485592,0.00014300548908 +13.04864582688583,0.00013951153272 +13.05148067712237,0.00013610294183 +13.05440695335151,0.00013277763074 +13.05729796655681,0.00012953356472 +13.0601686550556,0.00012636875878 +13.06305300954016,0.0001232812764 +13.06596117733009,0.00012026922838 +13.06902035115823,0.0001173307717 +13.07264615366728,0.00011446410834 +13.07614160069274,0.00011166748422 +13.07959960666482,0.00010893918813 +13.08299675901288,0.00010627755066 +13.08669194923748,0.00010368094317 +13.09008600134046,0.00010114777684 +13.09343220154425,9.867650164e-05 +13.09679749077704,9.6265605439e-05 +13.10280173558952,9.3913613034e-05 +13.10891865610211,9.1619085268e-05 +13.11366251343081,8.9380618146e-05 +13.11975838181057,8.7196841977e-05 +13.1245395368777,8.5066420534e-05 +13.12885884569322,8.2988050237e-05 +13.1326791280204,8.0960459354e-05 +13.1363629081962,7.8982407228e-05 +13.14316753478095,7.7052683511e-05 +13.14909587135863,7.5170107428e-05 +13.1537732100326,7.3333527053e-05 +13.15925955091709,7.1541818603e-05 +13.16402634387458,6.9793885754e-05 +13.16861733942274,6.8088658966e-05 +13.17254713021863,6.6425094829e-05 +13.17613562279822,6.480217543e-05 +13.17911050500318,6.3218907723e-05 +13.18185445010348,6.1674322924e-05 +13.18457073171253,6.016747592e-05 +13.18764335822197,5.869744469e-05 +13.19075675429965,5.7263329738e-05 +13.19383392496481,5.5864253546e-05 +13.19776919584298,5.4499360037e-05 +13.20163204930308,5.3167814047e-05 +13.20482404046702,5.1868800819e-05 +13.20793804387053,5.0601525503e-05 +13.21330012477678,4.9365212667e-05 +13.21677457880678,4.8159105826e-05 +13.21840618178205,4.6982466977e-05 +13.21999792090577,4.583457615e-05 +13.22155077014442,4.4714730962e-05 +13.22306567966828,4.3622246194e-05 +13.22454357643272,4.2556453367e-05 +13.22673560544755,4.1516700336e-05 +13.23113145180248,4.0502350886e-05 +13.23587978373944,3.9512784351e-05 +13.24070972963994,3.8547395225e-05 +13.2457543911124,3.7605592798e-05 +13.2516217740335,3.6686800793e-05 +13.25677311439155,3.5790457011e-05 +13.26225869996765,3.4916012991e-05 +13.26749430217717,3.4062933669e-05 +13.27295815910017,3.3230697057e-05 +13.27761583611625,3.241879392e-05 +13.28149492477108,3.1626727462e-05 +13.28527923827737,3.0854013029e-05 +13.29265334465983,3.0100177804e-05 +13.29754667661049,2.9364760525e-05 +13.30230067039737,2.8647311199e-05 +13.30674040708519,2.7947390827e-05 +13.31086199409637,2.7264571136e-05 +13.31488320585953,2.6598434317e-05 +13.31843380920317,2.5948572767e-05 +13.32171694883973,2.5314588846e-05 +13.32516218397417,2.4696094624e-05 +13.33063250077134,2.4092711653e-05 +13.33527653232102,2.350407073e-05 +13.34022415205675,2.2929811673e-05 +13.34515367650303,2.2369583098e-05 +13.34645332485669,2.182304221e-05 +13.34719872481904,2.1289854585e-05 +13.34792591292844,2.0769693972e-05 +13.34863533414277,2.0262242092e-05 +13.34932742254856,1.976718844e-05 +13.3500026016266,1.9284230099e-05 +13.35066128451104,1.8813071553e-05 +13.35130387424223,1.8353424504e-05 +13.35193076401329,1.7905007701e-05 +13.35254233741072,1.7467546763e-05 +13.35313896864912,1.7040774011e-05 +13.35372102280014,1.6624428309e-05 +13.35428885601591,1.62182549e-05 +13.35484281574691,1.5822005251e-05 +13.3553832409546,1.5435436902e-05 +13.35790638817934,1.5058313316e-05 +13.36229517460134,1.4690403735e-05 +13.36654441661248,1.433148304e-05 +13.3705771787529,1.3981331611e-05 +13.37451141114448,1.3639735196e-05 +13.38357518350394,1.3306484774e-05 +13.38989110814238,1.2981376435e-05 +13.39540523096175,1.2664211248e-05 +13.39996658400358,1.2354795143e-05 +13.40430954273037,1.2052938792e-05 +13.40844863729026,1.1758457494e-05 +13.41244292068022,1.1471171057e-05 +13.41856304284256,1.1190903696e-05 +13.42693497963135,1.0917483918e-05 +13.43256807030636,1.065074442e-05 +13.43767197715168,1.0390521988e-05 +13.4420770979694,1.0136657394e-05 +13.44635055412829,9.8889953025e-06 +13.45040575623627,9.6473841711e-06 +13.45436188033487,9.411676161e-06 +13.4593311879737,9.1817270452e-06 +13.4647155386401,8.9573961206e-06 +13.46929214037224,8.7385461217e-06 +13.47282122746011,8.5250431367e-06 +13.47340718006281,8.3167565258e-06 +13.47397881648203,8.1135588406e-06 +13.47453648649537,7.915325747e-06 +13.4750805313346,7.7219359485e-06 +13.47561128389437,7.5332711121e-06 +13.47612906893595,7.349215796e-06 +13.47663420328594,7.1696573788e-06 +13.47712699603012,6.994485991e-06 +13.4776077487026,6.8235944472e-06 +13.47807675547032,6.6568781809e-06 +13.478534303313,6.4942351803e-06 +13.47898067219882,6.3355659261e-06 +13.47941613525565,6.1807733304e-06 +13.47984095893826,6.0297626775e-06 +13.48025540319126,5.8824415657e-06 +13.48065972160823,5.738719851e-06 +13.48105416158688,5.5985095916e-06 +13.48143896448041,5.4617249947e-06 +13.4818143657452,5.3282823632e-06 +13.48218059508488,5.1981000453e-06 +13.48253787659089,5.0710983839e-06 +13.48288642887959,4.9471996682e-06 +13.48322646522606,4.8263280859e-06 +13.48355819369454,4.7084096773e-06 +13.48388181726579,4.5933722893e-06 +13.48419753396129,4.481145532e-06 +13.48450553696437,4.3716607351e-06 +13.48480601473848,4.2648509062e-06 +13.48509915114243,4.1606506896e-06 +13.48538512554296,4.0589963264e-06 +13.48600336824251,3.9598256154e-06 +13.49019765746281,3.8630778753e-06 +13.49428947045242,3.7686939073e-06 +13.49845039465437,3.676615959e-06 +13.50259405365247,3.5867876888e-06 +13.50836949977646,3.499154132e-06 +13.51717166654501,3.4136616666e-06 +13.52447912355213,3.3302579808e-06 +13.52496488662062,3.2488920407e-06 +13.53183375187237,3.1695140597e-06 +13.53749913458313,3.0920754671e-06 +13.54169716077226,3.0165288793e-06 +13.54585785270962,2.9428280702e-06 +13.5515673898919,2.870927943e-06 +13.55713742981523,2.8007845031e-06 +13.56417464002102,2.7323548303e-06 +13.57083780586576,2.6655970534e-06 +13.57677907519038,2.6004703241e-06 +13.581032058611,2.5369347922e-06 +13.58518113176525,2.4749515808e-06 +13.59076834565323,2.4144827634e-06 +13.59641135304915,2.3554913397e-06 +13.60134449185336,2.2979412135e-06 +13.60277412154267,2.2417971706e-06 +13.60322468158859,2.1870248571e-06 +13.60366423340575,2.1335907585e-06 +13.60409304595075,2.0814621791e-06 +13.60451138160898,2.0306072219e-06 +13.60491949635512,1.9809947696e-06 +13.60531763990979,1.9325944647e-06 +13.60570605589237,1.8853766917e-06 +13.60608498197004,1.8393125586e-06 +13.60645465000324,1.7943738794e-06 +13.6068152861875,1.7505331564e-06 +13.60716711119187,1.7077635642e-06 +13.60751034029395,1.6660389325e-06 +13.60784518351161,1.6253337305e-06 +13.60817184573148,1.5856230512e-06 +13.60849052683436,1.546882596e-06 +13.60880142181746,1.5090886601e-06 +13.60910472091379,1.4722181179e-06 +13.60940060970851,1.4362484087e-06 +13.6096892692525,1.4011575231e-06 +13.60997087617316,1.3669239894e-06 +13.61024560278246,1.3335268604e-06 +13.6105136171824,1.3009457009e-06 +13.61077508336784,1.2691605748e-06 +13.61103016132687,1.2381520331e-06 +13.61127900713872,1.2079011022e-06 +13.61152177306921,1.1783892719e-06 +13.61175860766398,1.1495984841e-06 +13.61198965583933,1.1215111221e-06 +13.61221505897094,1.0941099997e-06 +13.61243495498034,1.0673783503e-06 +13.61264947841932,1.0412998173e-06 +13.61285876055227,1.0158584434e-06 +13.61306292943646,9.9103866136e-07 +13.61326211000043,9.6682528427e-07 +13.61345642412046,9.4320349625e-07 +13.61364599069506,9.2015884339e-07 +13.61383092571781,8.9767722494e-07 +13.61401134234826,8.7574488467e-07 +13.61418735098126,8.5434840242e-07 +13.61435905931441,8.3347468595e-07 +13.61452657241404,8.1311096287e-07 +13.61468999277944,7.9324477286e-07 +13.61484942040562,7.7386396003e-07 +13.61500495284448,7.5495666549e-07 +13.61515668526449,7.3651132008e-07 +13.61530471050894,7.1851663731e-07 +13.61544911915275,7.0096160645e-07 +13.61558999955787,6.8383548579e-07 +13.61890160667541,6.6712779604e-07 +13.62393504678495,6.5082831398e-07 +13.62904890378615,6.3492706613e-07 +13.63414341084253,6.1941432271e-07 +13.64176008242301,6.0428059165e-07 +13.65030375106577,5.8951661281e-07 +13.65239274572476,5.7511335227e-07 +13.66093325770732,5.6106199685e-07 +13.66653569740867,5.4735394869e-07 +13.67160805473392,5.3398082e-07 diff --git a/tests/systeem_testen/224/frag_csv_files/041-02_0041_9_WA_km0897_hfreq.csv b/tests/systeem_testen/224/frag_csv_files/041-02_0041_9_WA_km0897_hfreq.csv new file mode 100644 index 00000000..0252a287 --- /dev/null +++ b/tests/systeem_testen/224/frag_csv_files/041-02_0041_9_WA_km0897_hfreq.csv @@ -0,0 +1,501 @@ +waarde,kans +10.85769460520807,0.1224847 +10.86897575408806,0.1194921142 +10.88168342644204,0.11657264422 +10.89322170267637,0.11372450367 +10.90448442235152,0.11094594982 +10.91688394815164,0.10823528249 +10.92769029153866,0.10559084307 +10.93960374178231,0.10301101344 +10.95166389228386,0.10049421505 +10.96475324782475,0.098038907884 +10.97436128994258,0.095643589581 +10.98602270317647,0.093306794468 +10.99821488900191,0.09102709269 +11.00963500121421,0.088803089322 +11.02017711057422,0.086633423524 +11.03186289198853,0.084516767703 +11.04375625240066,0.082451826701 +11.05377135045304,0.080437337005 +11.06573465426676,0.078472065974 +11.0756506622687,0.076554811079 +11.08840961358387,0.074684399177 +11.09866649533988,0.072859685783 +11.109544442202,0.071079554376 +11.11949497605241,0.069342915716 +11.13161045202024,0.067648707173 +11.14236680465403,0.065995892082 +11.15218772392647,0.064383459103 +11.16582908106241,0.062810421608 +11.17571054181433,0.061275817074 +11.18838243128386,0.059778706494 +11.19996175700048,0.058318173804 +11.21001554044878,0.056893325321 +11.22098085959163,0.055503289197 +11.23435064642113,0.054147214885 +11.24269108321666,0.05282427262 +11.25619184840149,0.051533652907 +11.26830782086896,0.050274566033 +11.27848936702938,0.049046241577 +11.29024077917374,0.04784792794 +11.30202661385643,0.046678891891 +11.31175244825356,0.045538418108 +11.32388469327314,0.044425808749 +11.33622928246224,0.043340383022 +11.34776612114431,0.042281476767 +11.35676191952202,0.041248442053 +11.37061299043988,0.040240646777 +11.38205481696297,0.039257474281 +11.3936497841945,0.038298322973 +11.4043321827498,0.03736260596 +11.41544362133164,0.036449750688 +11.4249210124433,0.035559198591 +11.44018324626017,0.034690404751 +11.450240564871,0.033842837563 +11.46052621495197,0.03301597841 +11.47285219851187,0.032209321348 +11.48384091041512,0.031422372792 +11.49723901936315,0.030654651218 +11.50919599829849,0.029905686866 +11.51783937821358,0.029175021452 +11.52616390742987,0.028462207893 +11.5422216939933,0.027766810025 +11.55174229693995,0.027088402342 +11.566335449639,0.026426569736 +11.57719721210451,0.025780907237 +11.58568806926587,0.025151019774 +11.59852241584008,0.024536521925 +11.61121347297322,0.023937037686 +11.6198406036602,0.02335220024 +11.63375906946677,0.022781651731 +11.64256644302353,0.022225043048 +11.65319142823243,0.021682033609 +11.66958736834456,0.021152291152 +11.67829050174509,0.020635491533 +11.68630163152493,0.020131318531 +11.69719923868281,0.019639463646 +11.71173436764667,0.019159625918 +11.72126483761423,0.018691511741 +11.73621044517761,0.018234834682 +11.74320307602258,0.017789315303 +11.75481667080401,0.017354680999 +11.76831252177093,0.01693066582 +11.77773585111533,0.016517010317 +11.78629116172894,0.016113461379 +11.79677827839365,0.01571977208 +11.81086452243437,0.015335701524 +11.82045549389473,0.014961014705 +11.82965621395608,0.014595482355 +11.84343042527025,0.01423888081 +11.85233010623245,0.013890991869 +11.8625147919832,0.013551602663 +11.87466373255089,0.013220505524 +11.88558632514929,0.012897497858 +11.89459266794977,0.012582382019 +11.90393158738569,0.012274965192 +11.91755823228096,0.011975059273 +11.926035827674,0.011682480752 +11.93926133420199,0.011397050604 +11.94718088200311,0.011118594178 +11.95704447104672,0.010846941089 +11.96585117719284,0.010581925116 +11.97861286207818,0.0103233841 +11.98834601863662,0.010071159841 +11.9967736615908,0.0098250980063 +12.01005480955701,0.0095850480343 +12.01854332738934,0.0093508630409 +12.02696812294502,0.0091223997309 +12.03928466962011,0.0088995183104 +12.04815710103409,0.0086820824009 +12.05572295936355,0.0084699589558 +12.06296296224254,0.0082630181794 +12.07623251860098,0.0080611334469 +12.0848258619924,0.0078641812275 +12.09166735072319,0.0076720410084 +12.09948529462852,0.0074845952213 +12.11340358395233,0.0073017291703 +12.12073035422335,0.0071233309618 +12.12846550447668,0.006949291436 +12.1419914521967,0.0067795041001 +12.14940524940677,0.0066138650634 +12.15657595926277,0.0064522729732 +12.16422527473627,0.0062946289532 +12.17338762897482,0.0061408365429 +12.18299110680454,0.0059908016385 +12.19011415163914,0.0058444324354 +12.19805484362017,0.005701639372 +12.20696507866893,0.0055623350749 +12.21526604661056,0.0054264343055 +12.22196396144209,0.0052938539076 +12.23093746285942,0.0051645127568 +12.24060847332536,0.0050383317109 +12.2478417385843,0.0049152335611 +12.25507547566188,0.0047951429851 +12.2641574273887,0.0046779865009 +12.27184944981781,0.0045636924219 +12.27888588964871,0.0044521908127 +12.28667923359761,0.0043434134469 +12.29450043735737,0.0042372937648 +12.30366565123198,0.0041337668332 +12.30987779914309,0.0040327693051 +12.31575066493811,0.0039342393812 +12.32136106274037,0.0038381167722 +12.33287774400003,0.003744342662 +12.33857818209836,0.0036528596711 +12.34424755891574,0.0035636118223 +12.35006780844274,0.0034765445057 +12.35887617288595,0.003391604446 +12.36590113074178,0.0033087396693 +12.37267577256391,0.0032278994717 +12.37865059948642,0.0031490343879 +12.38501495384585,0.0030720961613 +12.39207724432504,0.0029970377143 +12.40093849303429,0.0029238131196 +12.40702191165789,0.0028523775719 +12.41261226946832,0.0027826873606 +12.42005532170935,0.002714699843 +12.42786043997341,0.0026483734185 +12.43460442830238,0.0025836675027 +12.44025659990776,0.0025205425027 +12.44649697825585,0.0024589597931 +12.45312756583003,0.0023988816922 +12.45957641611341,0.0023402714388 +12.46566640503883,0.0022830931702 +12.47145845812511,0.0022273118995 +12.47708606904455,0.0021728934948 +12.4826133060602,0.0021198046582 +12.48979094138247,0.0020680129053 +12.49598913555285,0.0020174865452 +12.50114541670971,0.0019681946614 +12.50730878238657,0.0019201070929 +12.51333252848714,0.0018731944154 +12.52087643762867,0.0018274279237 +12.52647209241399,0.0017827796136 +12.53139944100225,0.0017392221656 +12.53642743320721,0.0016967289271 +12.54138509110832,0.0016552738973 +12.54989224262851,0.0016148317101 +12.55560596771963,0.0015753776195 +12.56189868534643,0.001536887484 +12.56697349637186,0.0014993377519 +12.57182433763225,0.0014627054471 +12.57987523361766,0.0014269681546 +12.58525914708346,0.0013921040071 +12.59151035848273,0.0013580916718 +12.59612217018424,0.0013249103369 +12.60037236680759,0.001292539699 +12.60527847348395,0.0012609599511 +12.61088125609225,0.0012301517697 +12.6177869002439,0.0012000963039 +12.62377293126724,0.0011707751629 +12.62846383565816,0.0011421704054 +12.63320704423976,0.0011142645287 +12.63869639350221,0.0010870404574 +12.64461125612798,0.0010604815334 +12.65134864477241,0.0010345715056 +12.65606723959234,0.00100929452 +12.66058991611813,0.00098463510984 +12.66538321898493,0.0009605781864 +12.67009883389496,0.00093710902949 +12.67511385056911,0.00091421327861 +12.68247278692804,0.00089187692413 +12.68782990505399,0.00087008629868 +12.69299229537368,0.00084882806884 +12.69794307195711,0.00082808922694 +12.70292584235164,0.00080785708314 +12.70938215755749,0.00078811925762 +12.71522330441653,0.00076886367303 +12.72009524428101,0.00075007854712 +12.72513526703153,0.00073175238547 +12.73021058124555,0.00071387397454 +12.73520835472638,0.00069643237472 +12.74040304383054,0.00067941691371 +12.74513019812476,0.00066281717994 +12.75110237857703,0.00064662301624 +12.75655374550974,0.00063082451359 +12.76161890573262,0.00061541200506 +12.76604453061932,0.00060037605992 +12.7705921187708,0.00058570747786 +12.77480483850941,0.00057139728334 +12.77999373882962,0.00055743672012 +12.78444156035714,0.00054381724589 +12.7879934095214,0.00053053052707 +12.79145847875819,0.00051756843365 +12.79704619104185,0.0005049230343 +12.80232381439361,0.00049258659143 +12.8067723820241,0.00048055155652 +12.81132658455398,0.00046881056548 +12.81587418381234,0.00045735643412 +12.82038385464548,0.00044618215381 +12.82528352711027,0.00043528088713 +12.83037249632573,0.00042464596372 +12.83694488330922,0.00041427087621 +12.84298848067548,0.00040414927618 +12.84740649122075,0.00039427497036 +12.85170007510558,0.00038464191677 +12.85628140140446,0.00037524422107 +12.86078282901691,0.0003660761329 +12.86716500177844,0.00035713204243 +12.87432121138639,0.00034840647687 +12.87849125032573,0.00033989409715 +12.88269249157124,0.00033158969464 +12.88716658724755,0.00032348818799 +12.89149616347637,0.00031558461996 +12.89559428497208,0.00030787415446 +12.89971268787379,0.00030035207355 +12.90370041445921,0.00029301377455 +12.90762060058181,0.00028585476725 +12.91135536360619,0.00027887067113 +12.91430993153499,0.0002720572127 +12.91690478011894,0.0002654102229 +12.91943623052308,0.0002589256345 +12.92203212879394,0.00025259947966 +12.92583923660772,0.00024642788748 +12.92965890562409,0.00024040708163 +12.93359851488943,0.00023453337807 +12.93796858202424,0.00022880318272 +12.94421961107789,0.00022321298937 +12.94836826119609,0.00021775937742 +12.95276090534801,0.00021243900989 +12.95785688566933,0.00020724863129 +12.96257075130134,0.00020218506571 +12.96709648000177,0.00019724521479 +12.97465949977385,0.00019242605592 +12.97877675423232,0.00018772464029 +12.98334345641939,0.00018313809116 +12.98970702585765,0.00017866360209 +12.99404073412279,0.00017429843518 +12.99854986364689,0.00017003991945 +13.0037480997452,0.00016588544914 +13.0090908367652,0.0001618324822 +13.01455029063261,0.00015787853866 +13.01994142180257,0.00015402119914 +13.023260438152,0.00015025810339 +13.02615265191422,0.00014658694882 +13.02886275283924,0.00014300548908 +13.03157773904504,0.00013951153272 +13.03438438472918,0.00013610294183 +13.03731430253846,0.00013277763074 +13.04021589378991,0.00012953356472 +13.0430918079533,0.00012636875878 +13.04599545516461,0.0001232812764 +13.04894072591962,0.00012026922838 +13.05201361224263,0.0001173307717 +13.05558122167788,0.00011446410834 +13.05901179856538,0.00011166748422 +13.06240166319537,0.00010893918813 +13.06572994611315,0.00010627755066 +13.06943183198307,0.00010368094317 +13.07288841897894,0.00010114777684 +13.07630326782579,9.867650164e-05 +13.07975508196867,9.6265605439e-05 +13.08556821294689,9.3913613034e-05 +13.09157780680081,9.1619085268e-05 +13.09635555436039,8.9380618146e-05 +13.10274541076777,8.7196841977e-05 +13.10754753634008,8.5066420534e-05 +13.11185044523995,8.2988050237e-05 +13.11568379312801,8.0960459354e-05 +13.11937195028488,7.8982407228e-05 +13.12585574185596,7.7052683511e-05 +13.13174844389437,7.5170107428e-05 +13.13661459581939,7.3333527053e-05 +13.14245074224063,7.1541818603e-05 +13.1471189861331,6.9793885754e-05 +13.15161984804458,6.8088658966e-05 +13.15547777534028,6.6425094829e-05 +13.15894860014808,6.480217543e-05 +13.16186194148173,6.3218907723e-05 +13.16456187281792,6.1674322924e-05 +13.16724285122134,6.016747592e-05 +13.170343091801,5.869744469e-05 +13.17347169813925,5.7263329738e-05 +13.17657143273254,5.5864253546e-05 +13.18070929114428,5.4499360037e-05 +13.1846774070312,5.3167814047e-05 +13.18786030992437,5.1868800819e-05 +13.19096544710468,5.0601525503e-05 +13.19607692689345,4.9365212667e-05 +13.19937438406824,4.8159105826e-05 +13.20101131186262,4.6982466977e-05 +13.20260824570774,4.583457615e-05 +13.20416616274869,4.4714730962e-05 +13.20568601625665,4.3622246194e-05 +13.20716873621218,4.2556453367e-05 +13.20951094053186,4.1516700336e-05 +13.21385008360661,4.0502350886e-05 +13.21854423082491,3.9512784351e-05 +13.22341353148379,3.8547395225e-05 +13.22856647146018,3.7605592798e-05 +13.23459819723989,3.6686800793e-05 +13.23974505241527,3.5790457011e-05 +13.245170228244,3.4916012991e-05 +13.25027226204012,3.4062933669e-05 +13.25556975073324,3.3230697057e-05 +13.26014575136728,3.241879392e-05 +13.26402484002211,3.1626727462e-05 +13.2678091535284,3.0854013029e-05 +13.27561272299659,3.0100177804e-05 +13.28044882918904,2.9364760525e-05 +13.285148998414,2.8647311199e-05 +13.28949782871041,2.7947390827e-05 +13.29354912458706,2.7264571136e-05 +13.29750272348017,2.6598434317e-05 +13.30105162485088,2.5948572767e-05 +13.30435140177924,2.5314588846e-05 +13.30785985111642,2.4696094624e-05 +13.31360559127736,2.4092711653e-05 +13.3182334479898,2.350407073e-05 +13.32309336030481,2.2929811673e-05 +13.3277702628334,2.2369583098e-05 +13.32901407611039,2.182304221e-05 +13.32975790885283,2.1289854585e-05 +13.33048356803314,2.0769693972e-05 +13.33119149767367,2.0262242092e-05 +13.33188213094827,1.976718844e-05 +13.33255589044736,1.9284230099e-05 +13.33321318843646,1.8813071553e-05 +13.33385442710852,1.8353424504e-05 +13.33447999882996,1.7905007701e-05 +13.33509028638079,1.7467546763e-05 +13.33568566318881,1.7040774011e-05 +13.3362664935581,1.6624428309e-05 +13.33683313289197,1.62182549e-05 +13.33738592791037,1.5822005251e-05 +13.33792521686211,1.5435436902e-05 +13.34050933486531,1.5058313316e-05 +13.34485667936759,1.4690403735e-05 +13.34907433186351,1.433148304e-05 +13.35310709400393,1.3981331611e-05 +13.3570413263955,1.3639735196e-05 +13.36649423230899,1.3306484774e-05 +13.37263711850715,1.2981376435e-05 +13.37804100067788,1.2664211248e-05 +13.38254959528225,1.2354795143e-05 +13.38685191347357,1.2052938792e-05 +13.39097855254129,1.1758457494e-05 +13.39497283593124,1.1471171057e-05 +13.40136185945512,1.1190903696e-05 +13.40973784285414,1.0917483918e-05 +13.41526196465444,1.065074442e-05 +13.42027578779441,1.0390521988e-05 +13.42464005847624,1.0136657394e-05 +13.42888046937932,9.8889953025e-06 +13.43293567148729,9.6473841711e-06 +13.43689179558589,9.411676161e-06 +13.44204388792934,9.1817270452e-06 +13.44769490860416,8.9573961206e-06 +13.45146807224389,8.7385461217e-06 +13.454729760578,8.5250431367e-06 +13.45534411560913,8.3167565258e-06 +13.45594346051946,8.1135588406e-06 +13.4565281620411,7.915325747e-06 +13.45709857794608,7.7219359485e-06 +13.45765505726518,7.5332711121e-06 +13.45819794050159,7.349215796e-06 +13.4587275598392,7.1696573788e-06 +13.45924423934587,6.994485991e-06 +13.45974829517173,6.8235944472e-06 +13.46024003574264,6.6568781809e-06 +13.46071976194889,6.4942351803e-06 +13.46118776732932,6.3355659261e-06 +13.46164433825094,6.1807733304e-06 +13.46208975408415,6.0297626775e-06 +13.46252428737366,5.8824415657e-06 +13.46294820400532,5.738719851e-06 +13.46336176336874,5.5985095916e-06 +13.46376521851603,5.4617249947e-06 +13.46415881631669,5.3282823632e-06 +13.4645427976086,5.1981000453e-06 +13.46491739734539,5.0710983839e-06 +13.46528284474027,4.9471996682e-06 +13.46563936340621,4.8263280859e-06 +13.4659871714928,4.7084096773e-06 +13.46632648181974,4.5933722893e-06 +13.46665750200703,4.481145532e-06 +13.46698043460205,4.3716607351e-06 +13.46729547720347,4.2648509062e-06 +13.46760282258217,4.1606506896e-06 +13.46790265879918,4.0589963264e-06 +13.46853328349354,3.9598256154e-06 +13.47272757271384,3.8630778753e-06 +13.47681938570345,3.7686939073e-06 +13.4809803099054,3.676615959e-06 +13.48512396890349,3.5867876888e-06 +13.49101761791806,3.499154132e-06 +13.4998992708845,3.4136616666e-06 +13.5070361503892,3.3302579808e-06 +13.50792337124971,3.2488920407e-06 +13.51451648973957,3.1695140597e-06 +13.52002904983416,3.0920754671e-06 +13.52422707602329,3.0165288793e-06 +13.52839852925864,2.9428280702e-06 +13.534390841918,2.870927943e-06 +13.5402367484565,2.8007845031e-06 +13.54640201565448,2.7323548303e-06 +13.55324099554408,2.6655970534e-06 +13.55930899044141,2.6004703241e-06 +13.56356197386203,2.5369347922e-06 +13.56771104701628,2.4749515808e-06 +13.57355222352321,2.4144827634e-06 +13.57947471138447,2.3554913397e-06 +13.58333337996148,2.2979412135e-06 +13.58468716222656,2.2417971706e-06 +13.58515932411697,2.1870248571e-06 +13.58561994999537,2.1335907585e-06 +13.58606932171334,2.0814621791e-06 +13.58650771423616,2.0306072219e-06 +13.58693539581109,1.9809947696e-06 +13.58735262813146,1.9325944647e-06 +13.58775966649685,1.8853766917e-06 +13.58815675996925,1.8393125586e-06 +13.58854415152552,1.7943738794e-06 +13.58892207820599,1.7505331564e-06 +13.58929077125959,1.7077635642e-06 +13.58965045628526,1.6660389325e-06 +13.59000135337006,1.6253337305e-06 +13.5903436772238,1.5856230512e-06 +13.59067763731043,1.546882596e-06 +13.59100343797622,1.5090886601e-06 +13.59132127857479,1.4722181179e-06 +13.59163135358905,1.4362484087e-06 +13.59193385275029,1.4011575231e-06 +13.59222896115418,1.3669239894e-06 +13.59251685937412,1.3335268604e-06 +13.59279772357164,1.3009457009e-06 +13.59307172560424,1.2691605748e-06 +13.59333903313058,1.2381520331e-06 +13.59359980971298,1.2079011022e-06 +13.59385421491758,1.1783892719e-06 +13.59410240441195,1.1495984841e-06 +13.59434453006033,1.1215111221e-06 +13.59458074001655,1.0941099997e-06 +13.59481117881474,1.0673783503e-06 +13.59503598745768,1.0412998173e-06 +13.59525530350316,1.0158584434e-06 +13.59546926114808,9.9103866136e-07 +13.59567799131063,9.6682528427e-07 +13.59588162171034,9.4320349625e-07 +13.59608027694626,9.2015884339e-07 +13.59627407857322,8.9767722494e-07 +13.59646314517616,8.7574488467e-07 +13.5966475924427,8.5434840242e-07 +13.59682753323397,8.3347468595e-07 +13.59700307765364,8.1311096287e-07 +13.59717433311528,7.9324477286e-07 +13.59734140440809,7.7386396003e-07 +13.59750439376104,7.5495666549e-07 +13.59766340090541,7.3651132008e-07 +13.59781852313581,7.1851663731e-07 +13.5979698553697,7.0096160645e-07 +13.59811749020552,6.8383548579e-07 +13.60143152192643,6.6712779604e-07 +13.60646496203598,6.5082831398e-07 +13.61157881903718,6.3492706613e-07 +13.61667332609355,6.1941432271e-07 +13.62404433329034,6.0428059165e-07 +13.63224502112381,5.8951661281e-07 +13.63463182812287,5.7511335227e-07 +13.64280447916478,5.6106199685e-07 +13.64832440369889,5.4735394869e-07 +13.65335607437066,5.3398082e-07 diff --git a/tests/systeem_testen/224/frag_csv_files/041-02_0042_9_WA_km0897_hfreq.csv b/tests/systeem_testen/224/frag_csv_files/041-02_0042_9_WA_km0897_hfreq.csv new file mode 100644 index 00000000..12f73c90 --- /dev/null +++ b/tests/systeem_testen/224/frag_csv_files/041-02_0042_9_WA_km0897_hfreq.csv @@ -0,0 +1,501 @@ +waarde,kans +10.83995880451022,0.1224847 +10.85135493130607,0.1194921142 +10.86398095091452,0.11657264422 +10.87553737330742,0.11372450367 +10.88681707268335,0.11094594982 +10.89907238287107,0.10823528249 +10.90988495140962,0.10559084307 +10.92164834574332,0.10301101344 +10.9338205847237,0.10049421505 +10.94673328210138,0.098038907884 +10.95638679336076,0.095643589581 +10.96805074435712,0.093306794468 +10.98031463393066,0.09102709269 +10.99160029300347,0.088803089322 +11.00217386892101,0.086633423524 +11.01389054137285,0.084516767703 +11.02579968979747,0.082451826701 +11.03590933836722,0.080437337005 +11.047587231567,0.078472065974 +11.05777650109413,0.076554811079 +11.07046242598938,0.074684399177 +11.080597154887,0.072859685783 +11.09153006262197,0.071079554376 +11.10152601167215,0.069342915716 +11.11356101738286,0.067648707173 +11.12418699928292,0.065995892082 +11.13413240249132,0.064383459103 +11.14756617946139,0.062810421608 +11.15768695768382,0.061275817074 +11.17034027733661,0.059778706494 +11.18165949984778,0.058318173804 +11.19200103092416,0.056893325321 +11.20323981074014,0.055503289197 +11.21604585856565,0.054147214885 +11.22441644386146,0.05282427262 +11.23828784589768,0.051533652907 +11.25006563559034,0.050274566033 +11.2604429633039,0.049046241577 +11.27225222171682,0.04784792794 +11.28378967760275,0.046678891891 +11.29361769768908,0.045538418108 +11.30599806288956,0.044425808749 +11.31796963505755,0.043340383022 +11.33008042060442,0.042281476767 +11.33902564791897,0.041248442053 +11.35240933722948,0.040240646777 +11.36438250138263,0.039257474281 +11.3756110383115,0.038298322973 +11.38610546876158,0.03736260596 +11.39765644228859,0.036449750688 +11.40719678130713,0.035559198591 +11.42219901248142,0.034690404751 +11.43256029757604,0.033842837563 +11.44258793119523,0.03301597841 +11.45468158647411,0.032209321348 +11.46612834159109,0.031422372792 +11.47910693091132,0.030654651218 +11.49142513765708,0.029905686866 +11.50018266612704,0.029175021452 +11.50851817330652,0.028462207893 +11.52430561696013,0.027766810025 +11.5340824951811,0.027088402342 +11.54820434179988,0.026426569736 +11.55947477070571,0.025780907237 +11.56805253595007,0.025151019774 +11.58095714467897,0.024536521925 +11.59354097601646,0.023937037686 +11.60214275050967,0.02335220024 +11.6157740887066,0.022781651731 +11.6250929028414,0.022225043048 +11.63562456438824,0.021682033609 +11.65185102669147,0.021152291152 +11.66063865955135,0.020635491533 +11.66867602909064,0.020131318531 +11.67988293279013,0.019639463646 +11.69407487856103,0.019159625918 +11.70367341902972,0.018691511741 +11.71852895587335,0.018234834682 +11.72577908685294,0.017789315303 +11.73751918806515,0.017354680999 +11.75084166981117,0.01693066582 +11.76009023158928,0.016517010317 +11.76878252794178,0.016113461379 +11.7797112858326,0.01571977208 +11.79326037290891,0.015335701524 +11.80318595544612,0.014961014705 +11.81263789181825,0.014595482355 +11.82579658195849,0.01423888081 +11.8349139820394,0.013890991869 +11.84548512786336,0.013551602663 +11.85718282930596,0.013220505524 +11.8683211795931,0.012897497858 +11.87757908211309,0.012582382019 +11.88674836154017,0.012274965192 +11.90037420973158,0.011975059273 +11.90903555787543,0.011682480752 +11.92166731034165,0.011397050604 +11.92971548272219,0.011118594178 +11.93997404675764,0.010846941089 +11.94877829141617,0.010581925116 +11.961357518851,0.0103233841 +11.97131177279021,0.010071159841 +11.97978829225305,0.0098250980063 +11.99263970960907,0.0095850480343 +12.00138819040995,0.0093508630409 +12.00990326175766,0.0091223997309 +12.02173430116389,0.0088995183104 +12.03099780248834,0.0086820824009 +12.03871982419897,0.0084699589558 +12.04596068011545,0.0082630181794 +12.05913482298297,0.0080611334469 +12.06781972892282,0.0078641812275 +12.07468031020679,0.0076720410084 +12.08249992529077,0.0074845952213 +12.09630262027981,0.0073017291703 +12.10372495310158,0.0071233309618 +12.11148013513892,0.006949291436 +12.12481311805787,0.0067795041001 +12.13235850115979,0.0066138650634 +12.13956909272649,0.0064522729732 +12.14723377793675,0.0062946289532 +12.15636208175656,0.0061408365429 +12.16594867006062,0.0059908016385 +12.17311554132051,0.0058444324354 +12.18106947428241,0.005701639372 +12.18996393752078,0.0055623350749 +12.19822198676909,0.0054264343055 +12.20483574174341,0.0052938539076 +12.21392229773429,0.0051645127568 +12.22358962295436,0.0050383317109 +12.23076754691746,0.0049152335611 +12.23793426606728,0.0047951429851 +12.24717128661053,0.0046779865009 +12.25486017144645,0.0045636924219 +12.26189922968777,0.0044521908127 +12.26956332918444,0.0043434134469 +12.27721160227508,0.0042372937648 +12.28667749897564,0.0041337668332 +12.29289165698223,0.0040327693051 +12.29876529560035,0.0039342393812 +12.30437569340261,0.0038381167722 +12.31588676984996,0.003744342662 +12.32156106791142,0.0036528596711 +12.32721921568927,0.0035636118223 +12.3330706574219,0.0034765445057 +12.34164084820366,0.003391604446 +12.34870453900008,0.0033087396693 +12.35566385172316,0.0032278994717 +12.36165522022523,0.0031490343879 +12.3680295845081,0.0030720961613 +12.37509187498728,0.0029970377143 +12.38392028611099,0.0029238131196 +12.38997044532124,0.0028523775719 +12.39549838424468,0.0027826873606 +12.40303186939896,0.002714699843 +12.41077592920102,0.0026483734185 +12.41748243845224,0.0025836675027 +12.42314975081562,0.0025205425027 +12.42942728517812,0.0024589597931 +12.43614197146542,0.0023988816922 +12.44258913704565,0.0023402714388 +12.44864034362219,0.0022830931702 +12.45436712689546,0.0022273118995 +12.45991445294624,0.0021728934948 +12.4653494187068,0.0021198046582 +12.47268971531567,0.0020680129053 +12.47899511560255,0.0020174865452 +12.48414238759042,0.0019681946614 +12.49016729333658,0.0019201070929 +12.49605449364964,0.0018731944154 +12.50382589771712,0.0018274279237 +12.5094774181096,0.0017827796136 +12.51439585318669,0.0017392221656 +12.5194291899492,0.0016967289271 +12.52439668591721,0.0016552738973 +12.53259760451163,0.0016148317101 +12.53836786678734,0.0015753776195 +12.54487681021916,0.001536887484 +12.54997813333794,0.0014993377519 +12.55483813398807,0.0014627054471 +12.56259022152852,0.0014269681546 +12.56799301042782,0.0013921040071 +12.57447272855003,0.0013580916718 +12.57909568028138,0.0013249103369 +12.58331908035322,0.001292539699 +12.58821242367515,0.0012609599511 +12.59387989625904,0.0012301517697 +12.60066848024048,0.0012000963039 +12.60662005609264,0.0011707751629 +12.61135377522864,0.0011421704054 +12.61612103756419,0.0011142645287 +12.62167065996503,0.0010870404574 +12.6275716296071,0.0010604815334 +12.63416771634728,0.0010345715056 +12.63893581173428,0.00100929452 +12.6434935435567,0.00098463510984 +12.64825522211673,0.0009605781864 +12.65290736106192,0.00093710902949 +12.6578269066264,0.00091421327861 +12.66547229581013,0.00089187692413 +12.67075331498165,0.00087008629868 +12.67584873511195,0.00084882806884 +12.68075751832769,0.00082808922694 +12.68568422164479,0.00080785708314 +12.69228609261997,0.00078811925762 +12.69821810273994,0.00076886367303 +12.70305903098386,0.00075007854712 +12.70803214419908,0.00073175238547 +12.71301873231039,0.00071387397454 +12.71793232228824,0.00069643237472 +12.72309834284606,0.00067941691371 +12.72784915910837,0.00066281717994 +12.73406775477428,0.00064662301624 +12.73943439873345,0.00063082451359 +12.74435538339871,0.00061541200506 +12.74871404819011,0.00060037605992 +12.75324331146995,0.00058570747786 +12.75746363335835,0.00057139728334 +12.76283708691458,0.00055743672012 +12.76740245677441,0.00054381724589 +12.77095654649186,0.00053053052707 +12.77442380153991,0.00051756843365 +12.77984713654838,0.0005049230343 +12.78503173666849,0.00049258659143 +12.78950809579,0.00048055155652 +12.79412318782425,0.00046881056548 +12.79873368929025,0.00045735643412 +12.80331673807381,0.00044618215381 +12.80825616018002,0.00043528088713 +12.81337496702318,0.00042464596372 +12.81982424873546,0.00041427087621 +12.82580838080001,0.00040414927618 +12.83031575057059,0.00039427497036 +12.83469380449205,0.00038464191677 +12.83918794824741,0.00037524422107 +12.84357873555841,0.0003660761329 +12.84963673085641,0.00035713204243 +12.85716558645905,0.00034840647687 +12.86138741280046,0.00033989409715 +12.86562402181967,0.00033158969464 +12.87003840490596,0.00032348818799 +12.87431001874713,0.00031558461996 +12.87838207712568,0.00030787415446 +12.8824948188271,0.00030035207355 +12.8864804447587,0.00029301377455 +12.8904066684904,0.00028585476725 +12.89415969103286,0.00027887067113 +12.89717955319907,0.0002720572127 +12.89979090191853,0.0002654102229 +12.90233844932153,0.0002589256345 +12.90493567001324,0.00025259947966 +12.90863211156317,0.00024642788748 +12.91236114886393,0.00024040708163 +12.91618805669304,0.00023453337807 +12.92052319627241,0.00022880318272 +12.92708152056865,0.00022321298937 +12.93121731268589,0.00021775937742 +12.93555808782302,0.00021243900989 +12.94051730769774,0.00020724863129 +12.94513058697936,0.00020218506571 +12.94959291438071,0.00019724521479 +12.95765384084425,0.00019242605592 +12.96175194967547,0.00018772464029 +12.96623728331123,0.00018313809116 +12.97229127134997,0.00017866360209 +12.9765363958171,0.00017429843518 +12.98100528223623,0.00017003991945 +12.98638285865137,0.00016588544914 +12.99195122159911,0.0001618324822 +12.99747011592751,0.00015787853866 +13.00266153400674,0.00015402119914 +13.00600666729821,0.00015025810339 +13.0089148132821,0.00014658694882 +13.01162216261548,0.00014300548908 +13.01432636846403,0.00013951153272 +13.01710450672601,0.00013610294183 +13.02003810521992,0.00013277763074 +13.02295038810806,0.00012953356472 +13.02583158405096,0.00012636875878 +13.02875473116067,0.0001232812764 +13.0317375033046,0.00012026922838 +13.03482424937176,0.0001173307717 +13.03833304083684,0.00011446410834 +13.04169805098952,0.00011166748422 +13.04501904255326,0.00010893918813 +13.04827771649817,0.00010627755066 +13.05198636991345,0.00010368094317 +13.05550616332246,0.00010114777684 +13.05899039798408,9.867650164e-05 +13.06252966616998,9.6265605439e-05 +13.06814963107075,9.3913613034e-05 +13.07405074575704,9.1619085268e-05 +13.07886274747194,8.9380618146e-05 +13.08554974884707,8.7196841977e-05 +13.09037307011274,8.5066420534e-05 +13.09465940298927,8.2988050237e-05 +13.0985059567405,8.0960459354e-05 +13.10219853787989,7.8982407228e-05 +13.10835804920542,7.7052683511e-05 +13.11421473404917,7.5170107428e-05 +13.11927172676403,7.3333527053e-05 +13.12546143504889,7.1541818603e-05 +13.13003007162408,6.9793885754e-05 +13.13443983201423,6.8088658966e-05 +13.13822512411586,6.6425094829e-05 +13.14157701759663,6.480217543e-05 +13.14442815721286,6.3218907723e-05 +13.14708360215067,6.1674322924e-05 +13.14972889825102,6.016747592e-05 +13.15285704942987,5.869744469e-05 +13.15600102936147,5.7263329738e-05 +13.15912357018178,5.5864253546e-05 +13.16346619157863,5.4499360037e-05 +13.16754070023494,5.3167814047e-05 +13.1707144172645,5.1868800819e-05 +13.17381059301318,5.0601525503e-05 +13.17866878064725,4.9365212667e-05 +13.1817873403164,4.8159105826e-05 +13.18342965010955,4.6982466977e-05 +13.1850318344587,4.583457615e-05 +13.18659487372167,4.4714730962e-05 +13.18811972430387,4.3622246194e-05 +13.1896073192435,4.2556453367e-05 +13.19210131149985,4.1516700336e-05 +13.19638314239594,4.0502350886e-05 +13.20102252304225,3.9512784351e-05 +13.20593160106384,3.8547395225e-05 +13.21119398227436,3.7605592798e-05 +13.21739181568032,3.6686800793e-05 +13.22253413750968,3.5790457011e-05 +13.2278982548913,3.4916012991e-05 +13.23286528597248,3.4062933669e-05 +13.23799461991896,3.3230697057e-05 +13.24248806710309,3.241879392e-05 +13.24636715575792,3.1626727462e-05 +13.25015146926421,3.0854013029e-05 +13.25838911353399,3.0100177804e-05 +13.26316737945922,2.9364760525e-05 +13.26781314613641,2.8647311199e-05 +13.27207009385869,2.7947390827e-05 +13.27605034379148,2.7264571136e-05 +13.2799356037653,2.6598434317e-05 +13.28348278488673,2.5948572767e-05 +13.28679937776361,2.5314588846e-05 +13.29037172011844,2.4696094624e-05 +13.29639584122979,2.4092711653e-05 +13.30100734941427,2.350407073e-05 +13.30577861247744,2.2929811673e-05 +13.3102001803511,2.2369583098e-05 +13.31138755897602,2.182304221e-05 +13.31212980766922,2.1289854585e-05 +13.31285392150229,2.0769693972e-05 +13.31356034355202,2.0262242092e-05 +13.31424950606976,1.976718844e-05 +13.31492183074598,1.9284230099e-05 +13.31557772896829,1.8813071553e-05 +13.3162176020731,1.8353424504e-05 +13.31684184159128,1.7905007701e-05 +13.31745082948766,1.7467546763e-05 +13.31804493839481,1.7040774011e-05 +13.318624531841,1.6624428309e-05 +13.31918996447267,1.62182549e-05 +13.31974158227142,1.5822005251e-05 +13.32027972276571,1.5435436902e-05 +13.32292546627164,1.5058313316e-05 +13.32723092383724,1.4690403735e-05 +13.33141664759932,1.433148304e-05 +13.33544940973974,1.3981331611e-05 +13.33938364213132,1.3639735196e-05 +13.34922986024289,1.3306484774e-05 +13.35519784985711,1.2981376435e-05 +13.36049030757885,1.2664211248e-05 +13.36494557720832,1.2354795143e-05 +13.36920681845272,1.2052938792e-05 +13.3733208682771,1.1758457494e-05 +13.37731515166706,1.1471171057e-05 +13.38397596410372,1.1190903696e-05 +13.3923560375668,1.0917483918e-05 +13.39777002034879,1.065074442e-05 +13.40269279243495,1.0390521988e-05 +13.40701577431869,1.0136657394e-05 +13.41122278511513,9.8889953025e-06 +13.41527798722311,9.6473841711e-06 +13.41923411132171,9.411676161e-06 +13.42457095117203,9.1817270452e-06 +13.43049150544553,8.9573961206e-06 +13.43345260341039,8.7385461217e-06 +13.43644402157498,8.5250431367e-06 +13.43708708402916,8.3167565258e-06 +13.43771443497349,8.1135588406e-06 +13.43832645827666,7.915325747e-06 +13.43892352842856,7.7219359485e-06 +13.4395060107694,7.5332711121e-06 +13.44007426171331,7.349215796e-06 +13.44062862896639,7.1696573788e-06 +13.44116945173946,6.994485991e-06 +13.44169706095562,6.8235944472e-06 +13.44221177945278,6.6568781809e-06 +13.44271392218116,6.4942351803e-06 +13.443203796396,6.3355659261e-06 +13.44368170184559,6.1807733304e-06 +13.44414793095468,6.0297626775e-06 +13.4446027690034,5.8824415657e-06 +13.44504649430182,5.738719851e-06 +13.44547937836023,5.5985095916e-06 +13.44590168605534,5.4617249947e-06 +13.44631367579226,5.3282823632e-06 +13.44671559966269,5.1981000453e-06 +13.44710770359913,5.0710983839e-06 +13.44749022752538,4.9471996682e-06 +13.44786340550336,4.8263280859e-06 +13.4482274658763,4.7084096773e-06 +13.44858263140846,4.5933722893e-06 +13.44892911942147,4.481145532e-06 +13.4492671419273,4.3716607351e-06 +13.44959690575794,4.2648509062e-06 +13.44991861269203,4.1606506896e-06 +13.45023245957826,4.0589963264e-06 +13.45087559922935,3.9598256154e-06 +13.45506988844965,3.8630778753e-06 +13.45916170143926,3.7686939073e-06 +13.46332262564121,3.676615959e-06 +13.46746628463931,3.5867876888e-06 +13.47347940584596,3.499154132e-06 +13.48244139855922,3.4136616666e-06 +13.48940586884419,3.3302579808e-06 +13.4906988584825,3.2488920407e-06 +13.49701326915108,3.1695140597e-06 +13.50237136556998,3.0920754671e-06 +13.5065693917591,3.0165288793e-06 +13.51075172185079,2.9428280702e-06 +13.5170298465233,2.870927943e-06 +13.52315458202342,2.8007845031e-06 +13.52843854300283,2.7323548303e-06 +13.53545522488633,2.6655970534e-06 +13.54165130617722,2.6004703241e-06 +13.54590428959785,2.5369347922e-06 +13.55005336275209,2.4749515808e-06 +13.5561512290121,2.4144827634e-06 +13.56235619849184,2.3554913397e-06 +13.56512885882701,2.2979412135e-06 +13.56640597919328,2.2417971706e-06 +13.56689997489589,2.1870248571e-06 +13.56738190113572,2.1335907585e-06 +13.56785205279781,2.0814621791e-06 +13.56831071756244,2.0306072219e-06 +13.5687581760812,1.9809947696e-06 +13.56919470214873,1.9325944647e-06 +13.56962056287019,1.8853766917e-06 +13.57003601882478,1.8393125586e-06 +13.57044132422513,1.7943738794e-06 +13.57083672707286,1.7505331564e-06 +13.57122246931033,1.7077635642e-06 +13.57159878696871,1.6660389325e-06 +13.57196591031236,1.6253337305e-06 +13.57232406397974,1.5856230512e-06 +13.57267346712089,1.546882596e-06 +13.5730143335315,1.5090886601e-06 +13.57334687178372,1.4722181179e-06 +13.57367128535382,1.4362484087e-06 +13.57398777274666,1.4011575231e-06 +13.57429652761716,1.3669239894e-06 +13.57459773888882,1.3335268604e-06 +13.57489159086927,1.3009457009e-06 +13.5751782633631,1.2691605748e-06 +13.57545793178184,1.2381520331e-06 +13.57573076725134,1.2079011022e-06 +13.57599693671641,1.1783892719e-06 +13.57625660304302,1.1495984841e-06 +13.57650992511797,1.1215111221e-06 +13.57675705794605,1.0941099997e-06 +13.57699815274496,1.0673783503e-06 +13.57723335703776,1.0412998173e-06 +13.57746281474322,1.0158584434e-06 +13.57768666626381,9.9103866136e-07 +13.57790504857165,9.6682528427e-07 +13.57811809529232,9.4320349625e-07 +13.57832593678661,9.2015884339e-07 +13.5785287002303,8.9767722494e-07 +13.57872650969195,8.7574488467e-07 +13.57891948620886,8.5434840242e-07 +13.57910774786111,8.3347468595e-07 +13.57929140984377,8.1311096287e-07 +13.57947058453749,7.9324477286e-07 +13.57964538157713,7.7386396003e-07 +13.57981590791898,7.5495666549e-07 +13.57998226790609,7.3651132008e-07 +13.58014456333219,7.1851663731e-07 +13.58030289350396,7.0096160645e-07 +13.58045735530176,6.8383548579e-07 +13.58377383766225,6.6712779604e-07 +13.58880727777179,6.5082831398e-07 +13.59392113477299,6.3492706613e-07 +13.59901564182937,6.1941432271e-07 +13.60613834661751,6.0428059165e-07 +13.61399237060099,5.8951661281e-07 +13.61668018794695,5.7511335227e-07 +13.62448102783646,5.6106199685e-07 +13.62991755112833,5.4735394869e-07 +13.63490809823995,5.3398082e-07 diff --git a/tests/systeem_testen/224/frag_csv_files/041-02_0043_9_WA_km0897_hfreq.csv b/tests/systeem_testen/224/frag_csv_files/041-02_0043_9_WA_km0897_hfreq.csv new file mode 100644 index 00000000..21d5f3c2 --- /dev/null +++ b/tests/systeem_testen/224/frag_csv_files/041-02_0043_9_WA_km0897_hfreq.csv @@ -0,0 +1,501 @@ +waarde,kans +10.82595955284217,0.1224847 +10.83744643419755,0.1194921142 +10.85000800352526,0.11657264422 +10.8615787490742,0.11372450367 +10.87287185089575,0.11094594982 +10.88501332857673,0.10823528249 +10.89583081076222,0.10559084307 +10.90747576271583,0.10301101344 +10.91973647556051,0.10049421505 +10.93250973282336,0.098038907884 +10.94219913386107,0.095643589581 +10.95386508796831,0.093306794468 +10.96618557486341,0.09102709269 +10.97736510716082,0.088803089322 +10.98796352031382,0.086633423524 +10.99970457573071,0.084516767703 +11.01162618597558,0.082451826701 +11.02181046531676,0.080437337005 +11.03326307773665,0.078472065974 +11.04366803850475,0.076554811079 +11.05629632206493,0.074684399177 +11.06633463306546,0.072859685783 +11.07731092260788,0.071079554376 +11.08734271885897,0.069342915716 +11.09931420765267,0.067648707173 +11.10983728510863,0.065995892082 +11.11988094618415,0.064383459103 +11.13315087563287,0.062810421608 +11.14346055231865,0.061275817074 +11.15609921441285,0.059778706494 +11.16721313182984,0.058318173804 +11.17778178834199,0.056893325321 +11.18923641659073,0.055503289197 +11.20159749300918,0.054147214885 +11.20999187516932,0.05282427262 +11.22415582890075,0.051533652907 +11.23566668360382,0.050274566033 +11.24619854593813,0.049046241577 +11.25805346366383,0.04784792794 +11.26939486878532,0.046678891891 +11.2793035462496,0.045538418108 +11.29187975808343,0.044425808749 +11.30355689983668,0.043340383022 +11.31612071407626,0.042281476767 +11.32502602455524,0.041248442053 +11.33804079943907,0.040240646777 +11.35043335989298,0.039257474281 +11.36137266544667,0.038298322973 +11.3717187285997,0.03736260596 +11.38361663657975,0.036449750688 +11.39320666174472,0.035559198591 +11.40800366720128,0.034690404751 +11.41860487962581,0.033842837563 +11.42842885526279,0.03301597841 +11.44033912879696,0.032209321348 +11.45214742734426,0.031422372792 +11.46479488073501,0.030654651218 +11.47739821241613,0.029905686866 +11.48624584081304,0.029175021452 +11.49459001313666,0.028462207893 +11.51016406927562,0.027766810025 +11.52014323112183,0.027088402342 +11.53389306564242,0.026426569736 +11.54548606382177,0.025780907237 +11.55413242749857,0.025151019774 +11.56709249566813,0.024536521925 +11.57959169136248,0.023937037686 +11.58817345166269,0.02335220024 +11.60157815381784,0.022781651731 +11.61130065907926,0.022225043048 +11.62175865823814,0.021682033609 +11.63785134803573,0.021152291152 +11.64670567814922,0.020635491533 +11.65476375929904,0.020131318531 +11.66621479745852,0.019639463646 +11.68013586130149,0.019159625918 +11.68978813129119,0.018691511741 +11.70457257336469,0.018234834682 +11.71202595477829,0.017789315303 +11.72386591025659,0.017354680999 +11.73705154792118,0.01693066582 +11.74616216187355,0.016517010317 +11.75496258403702,0.016113461379 +11.76623993891406,0.01571977208 +11.77936503636294,0.015335701524 +11.78955473467115,0.014961014705 +11.799204961519,0.014595482355 +11.81187780746378,0.01423888081 +11.82116705796114,0.013890991869 +11.83204324509203,0.013551602663 +11.84338477371885,0.013220505524 +11.85469342622328,0.012897497858 +11.86414989027894,0.012582382019 +11.87318526917244,0.012274965192 +11.88681048850824,0.011975059273 +11.89561687667859,0.011682480752 +11.90777996620248,0.011397050604 +11.91592966474972,0.011118594178 +11.92649999110183,0.010846941089 +11.93530229285488,0.010581925116 +11.9477375026718,0.0103233841 +11.95786627356285,0.010071159841 +11.96638137231269,0.0098250980063 +11.97889359398967,0.0095850480343 +11.98784726919271,0.0093508630409 +11.99643359717852,0.0091223997309 +12.00788141518082,0.0088995183104 +12.01745359645662,0.0086820824009 +12.02529888130668,0.0084699589558 +12.03254041054413,0.0082630181794 +12.0456392414765,0.0080611334469 +12.05439641971918,0.0078641812275 +12.06127207116895,0.0076720410084 +12.06909300535041,0.0074845952213 +12.08280445922713,0.0073017291703 +12.0903022216402,0.0071233309618 +12.09807321519856,0.006949291436 +12.1112538868202,0.0067795041001 +12.11890313351686,0.0066138650634 +12.12614520458169,0.0064522729732 +12.1338220214581,0.0062946289532 +12.14292344854483,0.0061408365429 +12.15249670558043,0.0059908016385 +12.15969816998714,0.0058444324354 +12.16766255434206,0.005701639372 +12.17654456854885,0.0055623350749 +12.18476874114285,0.0054264343055 +12.19131606691888,0.0052938539076 +12.20049185933355,0.0051645127568 +12.21015627570923,0.0050383317109 +12.21729051758878,0.0049152335611 +12.22440433803652,0.0047951429851 +12.23376375775555,0.0046779865009 +12.2414501660212,0.0045636924219 +12.24849129103059,0.0044521908127 +12.25605337508152,0.0043434134469 +12.26356515024915,0.0042372937648 +12.27326838241737,0.0041337668332 +12.27948412703585,0.0040327693051 +12.28535837566,0.0039342393812 +12.29096877346226,0.0038381167722 +12.30247542590983,0.003744342662 +12.30812909107397,0.0036528596711 +12.3137783755277,0.0035636118223 +12.31965443794389,0.0034765445057 +12.32803663309557,0.003391604446 +12.33513089664099,0.0033087396693 +12.34223597410636,0.0032278994717 +12.34824039923549,0.0031490343879 +12.35462266456774,0.0030720961613 +12.36168495504693,0.0029970377143 +12.37048744675306,0.0029238131196 +12.37651135358792,0.0028523775719 +12.3819900239318,0.0027826873606 +12.38959488974339,0.002714699843 +12.39729075477879,0.0026483734185 +12.40396768098211,0.0025836675027 +12.40964694427374,0.0025205425027 +12.41595380668326,0.0024589597931 +12.42273487390651,0.0023988816922 +12.42918070971405,0.0023402714388 +12.43520130454254,0.0022830931702 +12.44087656893858,0.0022273118995 +12.44636052440348,0.0021728934948 +12.4517226584637,0.0021198046582 +12.4591913471495,0.0020680129053 +12.46558136754633,0.0020174865452 +12.47072152840197,0.0019681946614 +12.47663714472564,0.0019201070929 +12.48241656649087,0.0018731944154 +12.49036753723121,0.0018274279237 +12.49606315355754,0.0017827796136 +12.50097455300718,0.0017392221656 +12.50601210834474,0.0016967289271 +12.51098736971204,0.0016552738973 +12.5189465720248,0.0016148317101 +12.52476146032497,0.0015753776195 +12.53144107546838,0.001536887484 +12.53656332515672,0.0014993377519 +12.54143055551159,0.0014627054471 +12.54894678707391,0.0014269681546 +12.55436447476173,0.0013921040071 +12.56102455819007,0.0013580916718 +12.56565630298827,0.0013249103369 +12.56985855196156,0.001292539699 +12.57474182089137,0.0012609599511 +12.58046035467427,0.0012301517697 +12.58715654052769,0.0012000963039 +12.59308092016691,0.0011707751629 +12.59784843390861,0.0011421704054 +12.60263468239319,0.0011142645287 +12.60823187968773,0.0010870404574 +12.61412188329684,0.0010604815334 +12.62060643738324,0.0010345715056 +12.62541360464006,0.00100929452 +12.62999900636746,0.00098463510984 +12.63473572317712,0.0009605781864 +12.6393377591683,0.00093710902949 +12.64418194731791,0.00091421327861 +12.65205343992115,0.00089187692413 +12.65727439253955,0.00087008629868 +12.66231695164872,0.00084882806884 +12.66719258858971,0.00082808922694 +12.67207503694813,0.00080785708314 +12.67879179824493,0.00078811925762 +12.68479552870495,0.00076886367303 +12.68961197880503,0.00075007854712 +12.6945322788747,0.00073175238547 +12.69944883355123,0.00071387397454 +12.70429597566667,0.00069643237472 +12.70943936751988,0.00067941691371 +12.71420886068614,0.00066281717994 +12.7206219572178,0.00064662301624 +12.72592172749876,0.00063082451359 +12.73072891127338,0.00061541200506 +12.73503472301115,0.00060037605992 +12.73954952207286,0.00058570747786 +12.74377584450276,0.00057139728334 +12.7492949699258,0.00055743672012 +12.75395312323057,0.00054381724589 +12.75750898146517,0.00053053052707 +12.76097796182139,0.00051756843365 +12.76627155028596,0.0005049230343 +12.77138272515434,0.00049258659143 +12.77588102070171,0.00048055155652 +12.78054417414069,0.00046881056548 +12.78520432568173,0.00045735643412 +12.789845293271,0.00044618215381 +12.79481609063019,0.00043528088713 +12.79995844895922,0.00042464596372 +12.80631056101434,0.00041427087621 +12.81224775582815,0.00040414927618 +12.8168256587709,0.00039427497036 +12.82127038672199,0.00038464191677 +12.82569571540728,0.00037524422107 +12.82999917193174,0.0003660761329 +12.83580128693574,0.00035713204243 +12.84362428009392,0.00034840647687 +12.84788698335356,0.00033989409715 +12.85215150892265,0.00033158969464 +12.85651875956819,0.00032348818799 +12.86074462244126,0.00031558461996 +12.86479610863688,0.00030787415446 +12.86890438183028,0.00030035207355 +12.87288834967031,0.00029301377455 +12.87681933901767,0.00028585476725 +12.88058677419328,0.00027887067113 +12.88365817451542,0.0002720572127 +12.88628254714923,0.0002654102229 +12.88884280026212,0.0002589256345 +12.89144106476926,0.00025259947966 +12.89505015503997,0.00024642788748 +12.89870765476442,0.00024040708163 +12.90244560490867,0.00023453337807 +12.90675317541195,0.00022880318272 +12.91355405449954,0.00022321298937 +12.91767969751809,0.00021775937742 +12.92197953131831,0.00021243900989 +12.92683080321014,0.00020724863129 +12.93136468750658,0.00020218506571 +12.93577697088924,0.00019724521479 +12.94423090588955,0.00019242605592 +12.94831390266248,0.00018772464029 +12.95273501033816,0.00018313809116 +12.95854463907237,0.00017866360209 +12.96271984242892,0.00017429843518 +12.96715696409357,0.00017003991945 +12.97267609770552,0.00016588544914 +12.97842255208533,0.0001618324822 +12.98398836405712,0.00015787853866 +12.98902214426782,0.00015402119914 +12.99238789222737,0.00015025810339 +12.99530861385894,0.00014658694882 +12.99801379130143,0.00014300548908 +13.0007094879805,0.00013951153272 +13.00346512471667,0.00013610294183 +13.00640162845468,0.00013277763074 +13.00932235048326,0.00012953356472 +13.01220771544912,0.00012636875878 +13.01514625425103,0.0001232812764 +13.01815862705356,0.00012026922838 +13.02125631291699,0.0001173307717 +13.02471867808415,0.00011446410834 +13.02803193499278,0.00011166748422 +13.03129856355348,0.00010893918813 +13.0345022936283,0.00010627755066 +13.03821628881372,0.00010368094317 +13.04178597241374,0.00010114777684 +13.04532497480192,9.867650164e-05 +13.04893327235834,9.6265605439e-05 +13.05440076708998,9.3913613034e-05 +13.06021625681948,9.1619085268e-05 +13.06505529608116,8.9380618146e-05 +13.07197684041583,8.7196841977e-05 +13.07681689190139,8.5066420534e-05 +13.08109014096364,8.2988050237e-05 +13.08494711838873,8.0960459354e-05 +13.08864319147336,7.8982407228e-05 +13.0945467413768,7.7052683511e-05 +13.10037499706862,7.5170107428e-05 +13.10558262455272,7.3333527053e-05 +13.11205140687509,7.1541818603e-05 +13.11654142123714,6.9793885754e-05 +13.12087927322315,6.8088658966e-05 +13.12460723279274,6.6425094829e-05 +13.12786525120091,6.480217543e-05 +13.13066729365421,6.3218907723e-05 +13.13328762451416,6.1674322924e-05 +13.13590475579977,6.016747592e-05 +13.13905493741914,5.869744469e-05 +13.14221105206098,5.7263329738e-05 +13.14535159433028,5.5864253546e-05 +13.14985583958669,5.4499360037e-05 +13.15401432636045,5.3167814047e-05 +13.15718079278889,5.1868800819e-05 +13.16026989508548,5.0601525503e-05 +13.16492815373525,4.9365212667e-05 +13.16790550572807,4.8159105826e-05 +13.16955206364943,4.6982466977e-05 +13.17115839233514,4.583457615e-05 +13.17272547467891,4.4714730962e-05 +13.17425426956005,4.3622246194e-05 +13.17574571243022,4.2556453367e-05 +13.17835951419288,4.1516700336e-05 +13.18259610734491,4.0502350886e-05 +13.18719225954965,3.9512784351e-05 +13.19213273470525,3.8547395225e-05 +13.19748150025248,3.7605592798e-05 +13.20381044600593,3.6686800793e-05 +13.20894918956707,3.5790457011e-05 +13.21426511219379,3.4916012991e-05 +13.21912558270775,3.4062933669e-05 +13.22412218847029,3.3230697057e-05 +13.22855047442822,3.241879392e-05 +13.23242956308305,3.1626727462e-05 +13.23621387658934,3.0854013029e-05 +13.24479414550255,3.0100177804e-05 +13.24952675685198,2.9364760525e-05 +13.25412958241979,2.8647311199e-05 +13.25831400523603,2.7947390827e-05 +13.2622381770664,2.7264571136e-05 +13.26606949565094,2.6598434317e-05 +13.26961531894235,2.5948572767e-05 +13.27294518501163,2.5314588846e-05 +13.27656795950929,2.4696094624e-05 +13.28281181273485,2.4092711653e-05 +13.28741041667208,2.350407073e-05 +13.29211170696054,2.2929811673e-05 +13.29633173366023,2.2369583098e-05 +13.29747456719183,2.182304221e-05 +13.29821556556065,2.1289854585e-05 +13.29893845961768,2.0769693972e-05 +13.29964369169331,2.0262242092e-05 +13.3003316933108,1.976718844e-05 +13.30100288545027,1.9284230099e-05 +13.30165767880631,1.8813071553e-05 +13.30229647403932,1.8353424504e-05 +13.3029196620206,1.7905007701e-05 +13.30352762407158,1.7467546763e-05 +13.30412073219712,1.7040774011e-05 +13.30469934931311,1.6624428309e-05 +13.3052638294686,1.62182549e-05 +13.30581451806237,1.5822005251e-05 +13.30635175205432,1.5435436902e-05 +13.30904613790443,1.5058313316e-05 +13.31331853320359,1.4690403735e-05 +13.31747905492445,1.433148304e-05 +13.32151181706487,1.3981331611e-05 +13.32544604945645,1.3639735196e-05 +13.33560271740555,1.3306484774e-05 +13.34143265735761,1.2981376435e-05 +13.34663716534818,1.2664211248e-05 +13.35105034441988,1.2354795143e-05 +13.35527916274032,1.2052938792e-05 +13.35938327560223,1.1758457494e-05 +13.36337755899218,1.1471171057e-05 +13.37025290030495,1.1190903696e-05 +13.3786362021442,1.0917483918e-05 +13.38396324981329,1.065074442e-05 +13.38881415333042,1.0390521988e-05 +13.39310454507146,1.0136657394e-05 +13.39728519244026,9.8889953025e-06 +13.40134039454824,9.6473841711e-06 +13.40529651864683,9.411676161e-06 +13.41077918370618,9.1817270452e-06 +13.4169124866875,8.9573961206e-06 +13.41923260362494,8.7385461217e-06 +13.42201069169039,8.5250431367e-06 +13.42267641353541,8.3167565258e-06 +13.42332587024902,8.1135588406e-06 +13.42395945922617,7.915325747e-06 +13.42457756815251,7.7219359485e-06 +13.42518057524167,7.5332711121e-06 +13.42576884946661,7.349215796e-06 +13.42634275078544,7.1696573788e-06 +13.42690263036164,6.994485991e-06 +13.42744883077896,6.8235944472e-06 +13.42798168625104,6.6568781809e-06 +13.4285015228259,6.4942351803e-06 +13.42900865858544,6.3355659261e-06 +13.4295034038401,6.1807733304e-06 +13.42998606131869,6.0297626775e-06 +13.43045692635366,5.8824415657e-06 +13.43091628706182,5.738719851e-06 +13.4313644245206,5.5985095916e-06 +13.43180161294006,5.4617249947e-06 +13.43222811983066,5.3282823632e-06 +13.43264420616697,5.1981000453e-06 +13.43305012654735,5.0710983839e-06 +13.43344612934972,4.9471996682e-06 +13.43383245688355,4.8263280859e-06 +13.43420934553814,4.7084096773e-06 +13.43457702592722,4.5933722893e-06 +13.43493572303013,4.481145532e-06 +13.43528565632942,4.3716607351e-06 +13.43562703994517,4.2648509062e-06 +13.43596008276601,4.1606506896e-06 +13.43628498857694,4.0589963264e-06 +13.43693800655448,3.9598256154e-06 +13.44113229577478,3.8630778753e-06 +13.44522410876439,3.7686939073e-06 +13.44938503296634,3.676615959e-06 +13.45352869196444,3.5867876888e-06 +13.4596361151602,3.499154132e-06 +13.46866152177587,3.4136616666e-06 +13.47548990572913,3.3302579808e-06 +13.47710317745318,3.2488920407e-06 +13.48319759800128,3.1695140597e-06 +13.4884337728951,3.0920754671e-06 +13.49263179908423,3.0165288793e-06 +13.49682271451424,2.9428280702e-06 +13.50332643679973,2.870927943e-06 +13.50967125803899,2.8007845031e-06 +13.51425958493001,2.7323548303e-06 +13.52141653084651,2.6655970534e-06 +13.52771371350235,2.6004703241e-06 +13.53196669692297,2.5369347922e-06 +13.53611577007722,2.4749515808e-06 +13.54241624711951,2.4144827634e-06 +13.54884418545959,2.3554913397e-06 +13.55075963596532,2.2979412135e-06 +13.55197624543428,2.2417971706e-06 +13.5524874750378,2.1870248571e-06 +13.55298621411431,2.1335907585e-06 +13.5534727678364,2.0814621791e-06 +13.55394743392061,2.0306072219e-06 +13.55441050280954,1.9809947696e-06 +13.55486225784961,1.9325944647e-06 +13.55530297546444,1.8853766917e-06 +13.55573292532397,1.8393125586e-06 +13.55615237050949,1.7943738794e-06 +13.55656156767458,1.7505331564e-06 +13.5569607672022,1.7077635642e-06 +13.55735021335785,1.6660389325e-06 +13.55773014443908,1.6253337305e-06 +13.55810079292127,1.5856230512e-06 +13.55846238559986,1.546882596e-06 +13.55881514372919,1.5090886601e-06 +13.55915928315782,1.4722181179e-06 +13.55949501446063,1.4362484087e-06 +13.55982254306767,1.4011575231e-06 +13.56014206938987,1.3669239894e-06 +13.56045378894162,1.3335268604e-06 +13.56075789246047,1.3009457009e-06 +13.56105456602379,1.2691605748e-06 +13.56134399116267,1.2381520331e-06 +13.56162634497296,1.2079011022e-06 +13.56190180022364,1.1783892719e-06 +13.56217052546255,1.1495984841e-06 +13.56243268511951,1.1215111221e-06 +13.56268843960695,1.0941099997e-06 +13.56293794541805,1.0673783503e-06 +13.56318135522247,1.0412998173e-06 +13.56341881795983,1.0158584434e-06 +13.56365047893079,9.9103866136e-07 +13.56387647988599,9.6682528427e-07 +13.56409695911277,9.4320349625e-07 +13.56431205151977,9.2015884339e-07 +13.56452188871952,8.9767722494e-07 +13.56472659910894,8.7574488467e-07 +13.56492630794792,8.5434840242e-07 +13.56512113743597,8.3347468595e-07 +13.56531120678695,8.1311096287e-07 +13.56549663230208,7.9324477286e-07 +13.56567752744105,7.7386396003e-07 +13.56585400289149,7.5495666549e-07 +13.56602616663664,7.3651132008e-07 +13.5661941240215,7.1851663731e-07 +13.56635797781721,7.0096160645e-07 +13.566517828284,6.8383548579e-07 +13.56983624498737,6.6712779604e-07 +13.57486968509692,6.5082831398e-07 +13.57998354209812,6.3492706613e-07 +13.58507804915449,6.1941432271e-07 +13.59200476347298,6.0428059165e-07 +13.59958515817053,5.8951661281e-07 +13.60251056950354,5.7511335227e-07 +13.6100179307966,5.6106199685e-07 +13.6153886236814,5.4735394869e-07 +13.62034671107623,5.3398082e-07 diff --git a/tests/systeem_testen/224/frag_csv_files/041-02_0044_9_WA_km0897_hfreq.csv b/tests/systeem_testen/224/frag_csv_files/041-02_0044_9_WA_km0897_hfreq.csv new file mode 100644 index 00000000..5ffbc8aa --- /dev/null +++ b/tests/systeem_testen/224/frag_csv_files/041-02_0044_9_WA_km0897_hfreq.csv @@ -0,0 +1,501 @@ +waarde,kans +10.80369984075877,0.1224847 +10.81533102771086,0.1194921142 +10.82779011693987,0.11657264422 +10.83938363722968,0.11372450367 +10.85069804980326,0.11094594982 +10.86265852646461,0.10823528249 +10.87348382166533,0.10559084307 +10.88494044260368,0.10301101344 +10.89734183459271,0.10049421505 +10.90989337308925,0.098038907884 +10.91963984118679,0.095643589581 +10.9313089803694,0.093306794468 +10.94371946065218,0.09102709269 +10.95473024453925,0.088803089322 +10.96536815049682,0.086633423524 +10.97714797639908,0.084516767703 +10.98908940174102,0.082451826701 +10.99939234881701,0.080437337005 +11.01048675028269,0.078472065974 +11.0212346740203,0.076554811079 +11.03377130414405,0.074684399177 +11.04365630447628,0.072859685783 +11.05470157388751,0.071079554376 +11.0647903694976,0.069342915716 +11.07666086230103,0.067648707173 +11.08702031506102,0.065995892082 +11.09722021247572,0.064383459103 +11.11022961380929,0.062810421608 +11.120839651222,0.061275817074 +11.13345500685369,0.059778706494 +11.14424247594369,0.058318173804 +11.15517227653176,0.056893325321 +11.1669701176951,0.055503289197 +11.1786236609081,0.054147214885 +11.18705588161566,0.05282427262 +11.20168501139074,0.051533652907 +11.21277142226254,0.050274566033 +11.22354900460004,0.049046241577 +11.23547652357477,0.04784792794 +11.24650619534982,0.046678891891 +11.25654312324155,0.045538418108 +11.26943074384023,0.044425808749 +11.28063972226476,0.043340383022 +11.29392388131307,0.042281476767 +11.30276572145177,0.041248442053 +11.31519389862908,0.040240646777 +11.32825332622169,0.039257474281 +11.33873273525451,0.038298322973 +11.34884288484636,0.03736260596 +11.36129244095872,0.036449750688 +11.37096147029764,0.035559198591 +11.38543215364092,0.034690404751 +11.39641486597783,0.033842837563 +11.40591501230199,0.03301597841 +11.41753369704734,0.032209321348 +11.42991687294205,0.031422372792 +11.44203779887078,0.030654651218 +11.4550944975689,0.029905686866 +11.46408539065454,0.029175021452 +11.4724433411156,0.028462207893 +11.48767809735833,0.027766810025 +11.49797890320122,0.027088402342 +11.51113721451804,0.026426569736 +11.52324311862449,0.025780907237 +11.53199855822846,0.025151019774 +11.54504681048175,0.024536521925 +11.55741143005067,0.023937037686 +11.56596136649457,0.02335220024 +11.57900570274179,0.022781651731 +11.58937010290317,0.022225043048 +11.59971097411934,0.021682033609 +11.61559095701439,0.021152291152 +11.62455134005824,0.020635491533 +11.63264235400317,0.020131318531 +11.64448158168292,0.019639463646 +11.65797192580835,0.019159625918 +11.66770962919811,0.018691511741 +11.68238102600667,0.018234834682 +11.69015758870517,0.017789315303 +11.70215631889987,0.017354680999 +11.71512436565852,0.01693066582 +11.72401563368038,0.016517010317 +11.73298798284954,0.016113461379 +11.74481962939375,0.01571977208 +11.7572705560186,0.015335701524 +11.76788021541892,0.014961014705 +11.77784573689845,0.014595482355 +11.7897460592709,0.01423888081 +11.79930856300224,0.013890991869 +11.81066978546409,0.013551602663 +11.82144497636664,0.013220505524 +11.83302442036862,0.012897497858 +11.84279661005874,0.012582382019 +11.85161907847703,0.012274965192 +11.86524329789189,0.011975059273 +11.8742803090489,0.011682480752 +11.88569819429988,0.011397050604 +11.8940093259932,0.011118594178 +11.90507537451473,0.010846941089 +11.91387458692292,0.010581925116 +11.92608079944871,0.0103233841 +11.93648706353682,0.010071159841 +11.94506350583855,0.0098250980063 +11.95703638453243,0.0095850480343 +11.96631633205499,0.0093508630409 +11.97501596268627,0.0091223997309 +11.98585443396646,0.0088995183104 +11.99591743625226,0.0086820824009 +12.0039587174355,0.0084699589558 +12.01120131729667,0.0082630181794 +12.02418039740003,0.0080611334469 +12.0330524932605,0.0078641812275 +12.0399521072448,0.0076720410084 +12.04777513887627,0.0074845952213 +12.06134151350599,0.0073017291703 +12.06895921382893,0.0071233309618 +12.07675534872442,0.006949291436 +12.08969383557035,0.0067795041001 +12.09750823207426,0.0066138650634 +12.10480035756927,0.0064522729732 +12.11249646457646,0.0062946289532 +12.121555155926,0.0061408365429 +12.13110721538587,0.0059908016385 +12.13836368512476,0.0058444324354 +12.14634468786792,0.005701639372 +12.15520690731244,0.0055623350749 +12.16337721384352,0.0054264343055 +12.16981891291443,0.0052938539076 +12.17913659699217,0.0051645127568 +12.18879638811786,0.0050383317109 +12.19586117267024,0.0049152335611 +12.20289088077359,0.0047951429851 +12.21244492306791,0.0046779865009 +12.22012739342729,0.0045636924219 +12.22717180473104,0.0044521908127 +12.23457167765072,0.0043434134469 +12.24186641232659,0.0042372937648 +12.25194702317921,0.0041337668332 +12.25816529061284,0.0040327693051 +12.26404050918586,0.0039342393812 +12.26965090698811,0.0038381167722 +12.28115052499103,0.003744342662 +12.2867713825191,0.0036528596711 +12.29240657371643,0.0035636118223 +12.29832178460572,0.0034765445057 +12.30640505459355,0.003391604446 +12.31354793077961,0.0033087396693 +12.32088478357643,0.0032278994717 +12.32690996958377,0.0031490343879 +12.3333047980936,0.0030720961613 +12.34036708857278,0.0029970377143 +12.34912836673508,0.0029238131196 +12.35511053060169,0.0028523775719 +12.36051086072982,0.0027826873606 +12.36822922638539,0.002714699843 +12.37584845863676,0.0026483734185 +12.38247834588797,0.0025836675027 +12.38817661192548,0.0025205425027 +12.39453010781928,0.0024589597931 +12.40141672500741,0.0023988816922 +12.4078604463907,0.0023402714388 +12.41383236656757,0.0022830931702 +12.41942571262961,0.0022273118995 +12.42480890478015,0.0021728934948 +12.4300552317445,0.0021198046582 +12.43772807210456,0.0020680129053 +12.44425264392806,0.0020174865452 +12.44938149762528,0.0019681946614 +12.455123336726,0.0019201070929 +12.46073138365633,0.0018731944154 +12.46896787697547,0.0018274279237 +12.47473360867758,0.0017827796136 +12.47963382102629,0.0017392221656 +12.48467808416997,0.0016967289271 +12.48966569302245,0.0016552738973 +12.4972405508743,0.0016148317101 +12.5031263974285,0.0015753776195 +12.51007739158921,0.001536887484 +12.5152329158714,0.0014993377519 +12.52011164192257,0.0014627054471 +12.52725284728416,0.0014269681546 +12.53269422500561,0.0013921040071 +12.5396411008911,0.0013580916718 +12.54428682723211,0.0013249103369 +12.54845544459601,0.001292539699 +12.55332269459328,0.0012609599511 +12.55912241897231,0.0012301517697 +12.56567168584926,0.0012000963039 +12.57155282175772,0.0011707751629 +12.57637407109977,0.0011421704054 +12.58119050878452,0.0011142645287 +12.58686335322518,0.0010870404574 +12.59273592013536,0.0010604815334 +12.59904313011653,0.0010345715056 +12.60391242416366,0.00100929452 +12.60854182282266,0.00098463510984 +12.61323884884102,0.0009605781864 +12.61776121790734,0.00093710902949 +12.62248558291225,0.00091421327861 +12.6307165945197,0.00089187692413 +12.63584203744871,0.00087008629868 +12.64080054412861,0.00084882806884 +12.64562347635723,0.00082808922694 +12.65043555648012,0.00080785708314 +12.65733500079036,0.00078811925762 +12.66345277121179,0.00076886367303 +12.66823029948609,0.00075007854712 +12.67306662325176,0.00073175238547 +12.67787182025493,0.00071387397454 +12.6826133059881,0.00069643237472 +12.68772071674307,0.00067941691371 +12.6925199073899,0.00066281717994 +12.69924227282925,0.00064662301624 +12.70443570965339,0.00063082451359 +12.70906194268002,0.00061541200506 +12.71328371465733,0.00060037605992 +12.71777551468033,0.00058570747786 +12.72201137835783,0.00057139728334 +12.7277621314343,0.00055743672012 +12.73256781639428,0.00054381724589 +12.73612648668511,0.00053053052707 +12.73959821039248,0.00051756843365 +12.74468549349306,0.0005049230343 +12.74967991748061,0.00049258659143 +12.75421309335839,0.00048055155652 +12.75895266752736,0.00046881056548 +12.7636917658865,0.00045735643412 +12.76842482810839,0.00044618215381 +12.77344551414126,0.00043528088713 +12.77862532085016,0.00042464596372 +12.78482292689003,0.00041427087621 +12.79068548845116,0.00040414927618 +12.79537554368189,0.00039427497036 +12.7999262876357,0.00038464191677 +12.80424219592603,0.00037524422107 +12.80840679087343,0.0003660761329 +12.81380203972433,0.00035713204243 +12.82209273054624,0.00034840647687 +12.82642043073946,0.00033989409715 +12.83072934542144,0.00033158969464 +12.83502165244959,0.00032348818799 +12.83917476833578,0.00031558461996 +12.84319354343512,0.00030787415446 +12.84729471141289,0.00030035207355 +12.85127604278051,0.00029301377455 +12.85521460976378,0.00028585476725 +12.85900496195465,0.00027887067113 +12.86215831126517,0.0002720572127 +12.86480339276193,0.0002654102229 +12.86738384877211,0.0002589256345 +12.86998377301303,0.00025259947966 +12.87345396912199,0.00024642788748 +12.87699771949116,0.00024040708163 +12.8805942211852,0.00023453337807 +12.88485795508131,0.00022880318272 +12.89204451191422,0.00022321298937 +12.896154017212,0.00021775937742 +12.90038875164881,0.00021243900989 +12.90506837929306,0.00020724863129 +12.90947602044788,0.00020218506571 +12.91380873061661,0.00019724521479 +12.92288757451081,0.00019242605592 +12.92694654213741,0.00018772464029 +12.93126552639868,0.00018313809116 +12.93668660809533,0.00017866360209 +12.94075063238123,0.00017429843518 +12.94513724603977,0.00017003991945 +12.95088146471473,0.00016588544914 +12.95691109594545,0.0001618324822 +12.96255150999301,0.00015787853866 +12.96733463583661,0.00015402119914 +12.97073316244655,0.00015025810339 +12.97367388016814,0.00014658694882 +12.97637560416419,0.00014300548908 +12.97905777071555,0.00013951153272 +12.98177762857598,0.00013610294183 +12.98471875183928,0.00013277763074 +12.98765289264487,0.00012953356472 +12.99054488662584,0.00012636875878 +12.99350789920999,0.0001232812764 +12.99656733896678,0.00012026922838 +12.99968241981109,0.0001173307717 +13.00307096417346,0.00011446410834 +13.00630193008975,0.00011166748422 +13.00948211797315,0.00010893918813 +13.01259848375464,0.00010627755066 +13.01632097269874,0.00010368094317 +13.01996998491676,0.00010114777684 +13.0235960715187,9.867650164e-05 +13.0273141302216,9.6265605439e-05 +13.03253918756112,9.3913613034e-05 +13.03821852809276,9.1619085268e-05 +13.04310055879577,8.9380618146e-05 +13.05039504154701,8.7196841977e-05 +13.05526169516008,8.5066420534e-05 +13.05951414011468,8.2988050237e-05 +13.06338769185276,8.0960459354e-05 +13.0670893173553,7.8982407228e-05 +13.07258587210677,7.7052683511e-05 +13.07836892361541,7.5170107428e-05 +13.08381607008758,7.3333527053e-05 +13.09072859810951,7.1541818603e-05 +13.09509359808727,6.9793885754e-05 +13.09931711107785,6.8088658966e-05 +13.10295390822771,6.6425094829e-05 +13.10606265922234,6.480217543e-05 +13.10878663402342,6.3218907723e-05 +13.11135113123726,6.1674322924e-05 +13.11392347865287,6.016747592e-05 +13.11710869009202,5.869744469e-05 +13.12028409970494,5.7263329738e-05 +13.12345326543792,5.5864253546e-05 +13.12821450304397,5.4499360037e-05 +13.13250652043497,5.3167814047e-05 +13.13566145794047,5.1868800819e-05 +13.13873931299252,5.0601525503e-05 +13.14307967167642,4.9365212667e-05 +13.14583249436628,4.8159105826e-05 +13.14748580708518,4.6982466977e-05 +13.14909872553304,4.583457615e-05 +13.15067223663575,4.4714730962e-05 +13.15220730320632,4.3622246194e-05 +13.15370486453398,4.2556453367e-05 +13.15650917113064,4.1516700336e-05 +13.16067383335508,4.0502350886e-05 +13.16520124955263,3.9512784351e-05 +13.17019164817414,3.8547395225e-05 +13.17567777038223,3.7605592798e-05 +13.18221519321537,3.6686800793e-05 +13.1873482470995,3.5790457011e-05 +13.19258753696089,3.4916012991e-05 +13.19727856930759,3.4062933669e-05 +13.20206412870638,3.3230697057e-05 +13.20638880411648,3.241879392e-05 +13.21026789277131,3.1626727462e-05 +13.2140522062776,3.0854013029e-05 +13.22317727044818,3.0100177804e-05 +13.22783728808071,2.9364760525e-05 +13.23237183451803,2.8647311199e-05 +13.2364409380611,2.7947390827e-05 +13.24027594209567,2.7264571136e-05 +13.24402149039595,2.6598434317e-05 +13.24756515465016,2.5948572767e-05 +13.25091612595053,2.5314588846e-05 +13.25461909080447,2.4696094624e-05 +13.26121233224833,2.4092711653e-05 +13.26579041760104,2.350407073e-05 +13.27038044666955,2.2929811673e-05 +13.27428000991792,2.2369583098e-05 +13.27535201388123,2.182304221e-05 +13.27609102415374,2.1289854585e-05 +13.27681197868827,2.0769693972e-05 +13.27751531862845,2.0262242092e-05 +13.27820147433974,1.976718844e-05 +13.27887086567279,1.9284230099e-05 +13.27952390222031,1.8813071553e-05 +13.2801609835677,1.8353424504e-05 +13.28078249953757,1.7905007701e-05 +13.28138883042827,1.7467546763e-05 +13.28198034724655,1.7040774011e-05 +13.28255741193462,1.6624428309e-05 +13.28312037759161,1.62182549e-05 +13.28366958868961,1.5822005251e-05 +13.28420538128443,1.5435436902e-05 +13.28697711159569,1.5058313316e-05 +13.2911969357611,1.4690403735e-05 +13.29531738461271,1.433148304e-05 +13.29935014675313,1.3981331611e-05 +13.30328437914471,1.3639735196e-05 +13.31393468233688,1.3306484774e-05 +13.31954511443196,1.2981376435e-05 +13.32460977668363,1.2664211248e-05 +13.32895602905671,1.2354795143e-05 +13.33313329283911,1.2052938792e-05 +13.33722160529049,1.1758457494e-05 +13.34121588868045,1.1471171057e-05 +13.34843234472771,1.1190903696e-05 +13.35682077989305,1.0917483918e-05 +13.36200959513166,1.065074442e-05 +13.36674622299373,1.0390521988e-05 +13.37098479430821,1.0136657394e-05 +13.37512352212852,9.8889953025e-06 +13.3791787242365,9.6473841711e-06 +13.3831348483351,9.411676161e-06 +13.38884938487188,9.1817270452e-06 +13.39532097200543,8.9573961206e-06 +13.39662188781273,8.7385461217e-06 +13.39906076727627,8.5250431367e-06 +13.39976251901263,8.3167565258e-06 +13.4004471253236,8.1135588406e-06 +13.40111500511179,7.915325747e-06 +13.40176656704498,7.7219359485e-06 +13.40240220980631,7.5332711121e-06 +13.40302232233812,7.349215796e-06 +13.40362728408001,7.1696573788e-06 +13.40421746520096,6.994485991e-06 +13.40479322682591,6.8235944472e-06 +13.40535492125662,6.6568781809e-06 +13.40590289218735,6.4942351803e-06 +13.40643747491508,6.3355659261e-06 +13.40695899654472,6.1807733304e-06 +13.40746777618924,6.0297626775e-06 +13.40796412516494,5.8824415657e-06 +13.40844834718195,5.738719851e-06 +13.40892073853004,5.5985095916e-06 +13.40938158825993,5.4617249947e-06 +13.40983117836018,5.3282823632e-06 +13.4102697839297,5.1981000453e-06 +13.4106976733461,5.0710983839e-06 +13.41111510842989,4.9471996682e-06 +13.41152234460472,4.8263280859e-06 +13.41191963105362,4.7084096773e-06 +13.41230721087151,4.5933722893e-06 +13.41268532121395,4.481145532e-06 +13.41305419344221,4.3716607351e-06 +13.4134140532649,4.2648509062e-06 +13.41376512087603,4.1606506896e-06 +13.41410761108973,4.0589963264e-06 +13.41477633624274,3.9598256154e-06 +13.41897062546305,3.8630778753e-06 +13.42306243845266,3.7686939073e-06 +13.4272233626546,3.676615959e-06 +13.4313670216527,3.5867876888e-06 +13.43762439108676,3.499154132e-06 +13.44675062989284,3.4136616666e-06 +13.45336262781103,3.3302579808e-06 +13.45548516868624,3.2488920407e-06 +13.46122979076946,3.1695140597e-06 +13.46627210258337,3.0920754671e-06 +13.47047012877249,3.0165288793e-06 +13.47467469544355,2.9428280702e-06 +13.48153713246829,2.870927943e-06 +13.48823190421228,2.8007845031e-06 +13.49171412808506,2.7323548303e-06 +13.49909410285085,2.6655970534e-06 +13.50555204319061,2.6004703241e-06 +13.50980502661124,2.5369347922e-06 +13.51395409976548,2.4749515808e-06 +13.52057674100524,2.4144827634e-06 +13.52735921419849,2.3554913397e-06 +13.52791164584787,2.2979412135e-06 +13.52903203909155,2.2417971706e-06 +13.52957067170786,2.1870248571e-06 +13.53009614427788,2.1335907585e-06 +13.53060877833213,2.0814621791e-06 +13.53110888754538,2.0306072219e-06 +13.53159677792859,1.9809947696e-06 +13.53207274801617,1.9325944647e-06 +13.53253708904864,1.8853766917e-06 +13.53299008515083,1.8393125586e-06 +13.53343201350575,1.7943738794e-06 +13.53386314452419,1.7505331564e-06 +13.53428374201015,1.7077635642e-06 +13.5346940633223,1.6660389325e-06 +13.53509435953146,1.6253337305e-06 +13.53548487557418,1.5856230512e-06 +13.53586585040264,1.546882596e-06 +13.53623751713089,1.5090886601e-06 +13.53660010317743,1.4722181179e-06 +13.53695383040442,1.4362484087e-06 +13.5372989152534,1.4011575231e-06 +13.53763556887775,1.3669239894e-06 +13.53796399727188,1.3335268604e-06 +13.53828440139726,1.3009457009e-06 +13.53859697730542,1.2691605748e-06 +13.53890191625792,1.2381520331e-06 +13.5391994048433,1.2079011022e-06 +13.53948962509136,1.1783892719e-06 +13.53977275458445,1.1495984841e-06 +13.54004896656621,1.1215111221e-06 +13.5403184300475,1.0941099997e-06 +13.54058130990986,1.0673783503e-06 +13.54083776700642,1.0412998173e-06 +13.54108795826025,1.0158584434e-06 +13.54133203676045,9.9103866136e-07 +13.5415701518558,9.6682528427e-07 +13.54180244924613,9.4320349625e-07 +13.54202907107149,9.2015884339e-07 +13.54225015599912,8.9767722494e-07 +13.54246583930831,8.7574488467e-07 +13.54267625297313,8.5434840242e-07 +13.54288152574324,8.3347468595e-07 +13.54308178322264,8.1311096287e-07 +13.54327714794655,7.9324477286e-07 +13.54346773945633,7.7386396003e-07 +13.54365367437271,7.5495666549e-07 +13.54383506646708,7.3651132008e-07 +13.54401202673114,7.1851663731e-07 +13.5441846634448,7.0096160645e-07 +13.54435308224243,6.8383548579e-07 +13.54767457467564,6.6712779604e-07 +13.55270801478519,6.5082831398e-07 +13.55782187178638,6.3492706613e-07 +13.56291637884276,6.1941432271e-07 +13.56953145568741,6.0428059165e-07 +13.57667676219119,5.8951661281e-07 +13.57997996327107,5.7511335227e-07 +13.58702067468782,5.6106199685e-07 +13.59228669298413,5.4735394869e-07 +13.59719316733795,5.3398082e-07 diff --git a/tests/systeem_testen/224/hrd_files/WBI2017_Bovenrijn_224_v04.config.sqlite b/tests/systeem_testen/224/hrd_files/WBI2017_Bovenrijn_224_v04.config.sqlite new file mode 100644 index 00000000..73f3e89d Binary files /dev/null and b/tests/systeem_testen/224/hrd_files/WBI2017_Bovenrijn_224_v04.config.sqlite differ diff --git a/tests/systeem_testen/224/hrd_files/WBI2017_Bovenrijn_224_v04.sqlite b/tests/systeem_testen/224/hrd_files/WBI2017_Bovenrijn_224_v04.sqlite new file mode 100644 index 00000000..a57dfd7d Binary files /dev/null and b/tests/systeem_testen/224/hrd_files/WBI2017_Bovenrijn_224_v04.sqlite differ diff --git a/tests/systeem_testen/224/hrd_files/hlcd.sqlite b/tests/systeem_testen/224/hrd_files/hlcd.sqlite new file mode 100644 index 00000000..1bf2956e Binary files /dev/null and b/tests/systeem_testen/224/hrd_files/hlcd.sqlite differ diff --git a/tests/systeem_testen/__init__.py b/tests/systeem_testen/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/test_calibration_WBI.py b/tests/test_calibration_WBI.py deleted file mode 100644 index c2efd11e..00000000 --- a/tests/test_calibration_WBI.py +++ /dev/null @@ -1,55 +0,0 @@ -import pytest - -from app.helper_functions import calibration_WBI - - -def test_calc_Beta_u(): - assert calibration_WBI.calc_Beta_u(1.0, -4.5) == pytest.approx( - 4.23688951104391, 0.0001 - ) - - -def test_calc_Beta_h(): - assert calibration_WBI.calc_Beta_h(1.0, -4.5) == pytest.approx( - 4.88385890279972, 0.0001 - ) - - -def test_calc_Beta_p(): - assert calibration_WBI.calc_Beta_p(1.00, -4.5) == pytest.approx( - 5.12372780228843, 0.0001 - ) - - -def test_calc_SF_u(): - assert calibration_WBI.calc_SF_u(-4.23688951104391, -4.5) == pytest.approx( - 1.0000, 0.0001 - ) - - -def test_calc_SF_h(): - assert calibration_WBI.calc_SF_h(-4.88385890279972, -4.5) == pytest.approx( - 1.0000, 0.0001 - ) - - -def test_calc_SF_p(): - assert calibration_WBI.calc_SF_p(-5.12372780228843, -4.5) == pytest.approx( - 1.0000, 0.0001 - ) - - -def test_class_reliability_dike_trajectory(): - model = calibration_WBI.ReliabilityDikeTrajectory( - T=10000.0, w=0.24, L=3000.0, a=0.9, b=300.0 - ) - assert model.Pnorm == pytest.approx(0.0001, 0.0001) - assert model.PfailureMechanism == pytest.approx(2.4e-5, 0.0001) - assert model.Pcross == pytest.approx(2.4e-6, 0.0001) - assert model.Bnorm == pytest.approx(-3.719016485, 0.001) - assert model.BfailureMechanism == pytest.approx(-4.065157, 0.001) - assert model.Bcross == pytest.approx(-4.573344477, 0.001) - assert model.Ndsn == pytest.approx(10.0, 0.0001) - assert model.SF_u == pytest.approx(1.441429, 0.0001) - assert model.SF_h == pytest.approx(1.088987, 0.0001) - assert model.SF_p == pytest.approx(1.141315, 0.0001) diff --git a/tests/test_limitstatepiping_model4a_class_implementation.py b/tests/test_limitstatepiping_model4a_class_implementation.py deleted file mode 100644 index f4231b12..00000000 --- a/tests/test_limitstatepiping_model4a_class_implementation.py +++ /dev/null @@ -1,201 +0,0 @@ -from pathlib import Path - -import pandas as pd -import pytest - -from app.helper_functions import limitstatepiping_model4a_class_implementation - -test_path = Path( - Path(__file__).resolve(strict=True).parent, - "testset", - "testset_limitstate_piping.xlsx", -) - - -def get_data(): - testdata = pd.read_excel(test_path) - return testdata - - -# Define the input variables for the functions for Uplift, Heave and Piping -# dist_L_geom: float -# dist_BUT: float -# dist_BIT: float -# L3_geom: float -# mv: float -# pp: float -# top_zand: float -# gamma_sat_cover: float -# gamma_w: float -# kD: float -# D: float -# d70: float -# c1: float -# c3: float -# mu: float -# mh: float -# mp: float -# i_c_h: float -# rc: float -# h: float -## Class implementation - -# input variables -input_keys = [ - "DIST_L_GEOM", - "DIST_BUT", - "DIST_BIT", - "L3_geom", - "mv", - "pp", - "top_zand", - "gamma_sat_cover", - "gamma_w", - "kD_WVP", - "D_zand", - "D70", - "c_1", - "c_3", - "mu", - "mh", - "mp", - "i_c_h", - "rc", - "h", -] - -# Expected output keys -expected_keys = ["Z_u"] + ["Z_h"] + ["Z_p"] + ["L_kwelweg"] + ["dHc_piping"] -testset_keys = input_keys + expected_keys -testset_keys_string = ", ".join(testset_keys) -#print(testset_keys_string) -# Get the test data from the Excel file -testset_df = get_data()[testset_keys] -# Convert the DataFrame to a list of tuples for pytest parametrize -test_data = [tuple(row) for row in testset_df.itertuples(index=False, name=None)] -#print(test_data[:5]) - -# Test function for LimitStatePipingModel4a -# This function will be called for each row of test data -@pytest.mark.parametrize( - "i1,i2,i3,i4,i5,i6,i7,i8,i9,i10,i11,i12,i13,i14,i15,i16,i17,i18,i19,i20,Z_u, Z_h, Z_p, expected_L_kwelweg, expected_dHc_piping", - test_data, -) -def test_LimitStatePipingModel4a( - i1, - i2, - i3, - i4, - i5, - i6, - i7, - i8, - i9, - i10, - i11, - i12, - i13, - i14, - i15, - i16, - i17, - i18, - i19, - i20, - Z_u, - Z_h, - Z_p, - expected_L_kwelweg, - expected_dHc_piping, -): - model = limitstatepiping_model4a_class_implementation.LimitStatePipingModel4a( - dist_L_geom=i1, - dist_BUT=i2, - dist_BIT=i3, - L3_geom=i4, - mv=i5, - pp=i6, - top_zand=i7, - gamma_sat_cover=i8, - gamma_w=i9, - kD=i10, - D=i11, - d70=i12, - c_1=i13, - c_3=i14, - mu=i15, - mh=i16, - mp=i17, - i_c_h=i18, - rc=i19, - h=i20, - ) - assert model.Z_u == pytest.approx(Z_u, 0.0001) - assert model.Z_h == pytest.approx(Z_h, 0.0001) - assert model.Z_p == pytest.approx(Z_p, 0.0001) - assert model.L_kwelweg == pytest.approx(expected_L_kwelweg, 0.0001) - assert model.dhc == pytest.approx(expected_dHc_piping, 0.0001) - assert limitstatepiping_model4a_class_implementation.Z_u( - dist_L_geom=i1, - dist_BUT=i2, - dist_BIT=i3, - L3_geom=i4, - mv=i5, - pp=i6, - top_zand=i7, - gamma_sat_cover=i8, - gamma_w=i9, - kD=i10, - D=i11, - d70=i12, - c_1=i13, - c_3=i14, - mu=i15, - mh=i16, - mp=i17, - i_c_h=i18, - rc=i19, - h=i20,) == pytest.approx(Z_u, 0.0001) - assert limitstatepiping_model4a_class_implementation.Z_h( - dist_L_geom=i1, - dist_BUT=i2, - dist_BIT=i3, - L3_geom=i4, - mv=i5, - pp=i6, - top_zand=i7, - gamma_sat_cover=i8, - gamma_w=i9, - kD=i10, - D=i11, - d70=i12, - c_1=i13, - c_3=i14, - mu=i15, - mh=i16, - mp=i17, - i_c_h=i18, - rc=i19, - h=i20,) == pytest.approx(Z_h, 0.0001) - assert limitstatepiping_model4a_class_implementation.Z_p( - dist_L_geom=i1, - dist_BUT=i2, - dist_BIT=i3, - L3_geom=i4, - mv=i5, - pp=i6, - top_zand=i7, - gamma_sat_cover=i8, - gamma_w=i9, - kD=i10, - D=i11, - d70=i12, - c_1=i13, - c_3=i14, - mu=i15, - mh=i16, - mp=i17, - i_c_h=i18, - rc=i19, - h=i20,) == pytest.approx(Z_p, 0.0001) - diff --git a/tests/test_limitstatepiping_model4a_function_implementation.py b/tests/test_limitstatepiping_model4a_function_implementation.py deleted file mode 100644 index 13f9b968..00000000 --- a/tests/test_limitstatepiping_model4a_function_implementation.py +++ /dev/null @@ -1,134 +0,0 @@ -from pathlib import Path - -import pandas as pd -import pytest - -from app.helper_functions import limitstatepiping_model4a_function_implementation - -test_path = Path( - Path(__file__).resolve(strict=True).parent, - "testset", - "testset_limitstate_piping.xlsx", -) - - -def get_data(): - testdata = pd.read_excel(test_path) - return testdata - - -# Define the input variables for the functions for Uplift, Heave and Piping -# dist_L_geom: float -# dist_BUT: float -# dist_BIT: float -# L3_geom: float -# mv: float -# pp: float -# top_zand: float -# gamma_sat_cover: float -# gamma_w: float -# kD: float -# D: float -# d70: float -# c1: float -# c3: float -# mu: float -# mh: float -# mp: float -# i_c_h: float -# rc: float -# h: float -## Class implementation - -# input variables -input_keys = [ - "DIST_L_GEOM", # i1 - "DIST_BUT", # i2 - "DIST_BIT", # i3 - "L3_geom", # i4 - "mv", # i5 - "pp", # i6 - "top_zand", # i7 - "gamma_sat_cover", # i8 - "gamma_w", # i9 - "kD_WVP", # i10 - "D_zand", # i11 - "D70", # i12 - "c_1", # i13 - "c_3", # i14 - "mu", # i15 - "mh", # i16 - "mp", # i17 - "i_c_h", # i18 - "rc", # i19 - "h", # i20 -] - -# Expected output keys -expected_keys = ["Z_u"] + ["Z_h"] + ["Z_p"] -testset_keys = input_keys + expected_keys -testset_keys_string = ", ".join(testset_keys) -# print(testset_keys_string) -# Get the test data from the Excel file -testset_df = get_data()[testset_keys] -# Convert the DataFrame to a list of tuples for pytest parametrize -test_data = [tuple(row) for row in testset_df.itertuples(index=False, name=None)] -# print(test_data[:5]) - - -# Test function for Uplift limit state function Z_u -# This function will be called for each row of test data -@pytest.mark.parametrize( - "i1,i2,i3,i4,i5,i6,i7,i8,i9,i10,i11,i12,i13,i14,i15,i16,i17,i18,i19,i20,Z_u, Z_h, Z_p", - test_data, -) -def test_calc_Z_combin_piping( - i1, - i2, - i3, - i4, - i5, - i6, - i7, - i8, - i9, - i10, - i11, - i12, - i13, - i14, - i15, - i16, - i17, - i18, - i19, - i20, - Z_u, - Z_h, - Z_p, -): - model = limitstatepiping_model4a_function_implementation.calc_Z_combin_piping( - dist_L_geom=i1, - dist_BUT=i2, - dist_BIT=i3, - L3_geom=i4, - mv=i5, - pp=i6, - top_zand=i7, - gamma_sat_cover=i8, - gamma_w=i9, - kD_wvp=i10, - D_wvp=i11, - d70=i12, - c_1=i13, - c_3=i14, - mu=i15, - mh=i16, - mp=i17, - i_c_h=i18, - rc=i19, - h=i20, - ) - assert model[0] == pytest.approx(Z_u, rel=1e-2, abs=1e-2) - assert model[1] == pytest.approx(Z_h, rel=1e-2, abs=1e-2) - assert model[2] == pytest.approx(Z_p, rel=1e-2, abs=1e-2) diff --git a/tests/test_limitstatepiping_model4a_list_function_implementation.py b/tests/test_limitstatepiping_model4a_list_function_implementation.py deleted file mode 100644 index a3c04f75..00000000 --- a/tests/test_limitstatepiping_model4a_list_function_implementation.py +++ /dev/null @@ -1,117 +0,0 @@ -from pathlib import Path - -import pandas as pd -import pytest - -from app.helper_functions import limitstatepiping_model4a_list_function_implementation - -test_path = Path( - Path(__file__).resolve(strict=True).parent, - "testset", - "testset_limitstate_piping.xlsx", -) - - -def get_data(): - testdata = pd.read_excel(test_path) - return testdata - - -# Define the input variables for the functions for Uplift, Heave and Piping -# dist_L_geom: float -# dist_BUT: float -# dist_BIT: float -# L3_geom: float -# mv: float -# pp: float -# top_zand: float -# gamma_sat_cover: float -# gamma_w: float -# kD: float -# D: float -# d70: float -# c1: float -# c3: float -# mu: float -# mh: float -# mp: float -# i_c_h: float -# rc: float -# h: float -## Class implementation - -# input variables -input_keys = [ - "DIST_L_GEOM", - "DIST_BUT", - "DIST_BIT", - "L3_geom", - "mv", - "pp", - "top_zand", - "gamma_sat_cover", - "gamma_w", - "kD_WVP", - "D_zand", - "D70", - "c_1", - "c_3", - "mu", - "mh", - "mp", - "i_c_h", - "rc", - "h", -] - -# Expected output keys -expected_keys = ["Z_u"] + ["Z_h"] + ["Z_p"] + ["L_kwelweg"] + ["dHc_piping"] -testset_keys = input_keys + expected_keys -testset_keys_string = ", ".join(testset_keys) -#print(testset_keys_string) -# Get the test data from the Excel file -testset_df = get_data()[testset_keys] -# Convert the DataFrame to a list of tuples for pytest parametrize -test_data = [tuple(row) for row in testset_df.itertuples(index=False, name=None)] -#print(test_data[:5]) - -# Test function for LimitStatePipingModel4a -# This function will be called for each row of test data -@pytest.mark.parametrize( - "i1,i2,i3,i4,i5,i6,i7,i8,i9,i10,i11,i12,i13,i14,i15,i16,i17,i18,i19,i20,Z_u, Z_h, Z_p, expected_L_kwelweg, expected_dHc_piping", - test_data, -) -def test_LimitStatePipingModel4a( - i1, - i2, - i3, - i4, - i5, - i6, - i7, - i8, - i9, - i10, - i11, - i12, - i13, - i14, - i15, - i16, - i17, - i18, - i19, - i20, - Z_u, - Z_h, - Z_p, - expected_L_kwelweg, - expected_dHc_piping, -): - X = [i1,i2,i3,i4,i5,i6,i7,i8,i9,i10,i11,i12,i13,i14,i15,i16,i17,i18,i19,i20] - assert limitstatepiping_model4a_list_function_implementation.Z_u(X) == pytest.approx(Z_u, 0.0001) - assert limitstatepiping_model4a_list_function_implementation.Z_h(X) == pytest.approx(Z_h, 0.0001) - assert limitstatepiping_model4a_list_function_implementation.Z_p(X) == pytest.approx(Z_p, 0.0001) - assert limitstatepiping_model4a_list_function_implementation.calc_Z_combin_piping(X)[7] == pytest.approx(expected_L_kwelweg, 0.0001) - assert limitstatepiping_model4a_list_function_implementation.calc_Z_combin_piping(X)[9] == pytest.approx(expected_dHc_piping, 0.0001) - diff --git a/tests/test_piping_functions.py b/tests/test_piping_functions.py deleted file mode 100644 index e40cbb3d..00000000 --- a/tests/test_piping_functions.py +++ /dev/null @@ -1,148 +0,0 @@ -"""Test module for piping_functions.py""" - -import pytest - -from app.helper_functions import piping_functions_old - -## testcase model 4a -# k = 40 #m/d -# D = 50 #m -# c1 = 10 #d -# c3 = 50 #d -# L1 = 150 #m -# L2 = 45 #m -# L3 = 3000.0 #m -# x_but = 0.0 #m -# x_bit = 45.0 #m -# lambda1 = 141.4213562373095 -# lambda3 = 316.22776601683793319988935444327 -# W1 = 111.14536276273107 -# W3 = 316.2277623787640000 -# W_tot4a = 472.373125141495 -# r_but = 0.76470853898 -# r_bit = 0.66944486371 -# r(-150.0) = 1.0 -# r(3045.0) = 0.0 -# r(-50.0) = 0.8579165276194 -# r(55.0) = 0.648606379956042 -# r(90.0) = 0.580648922902315 -# r(22.5) = 0.717076701341341 -# piping input -# D70 = 2.7E-4 m - - -def test_calc_Dcover(): - assert piping_functions_old.calc_Dcover(0.0, 2.0) == 0.1 - assert piping_functions_old.calc_Dcover(2.0, 1.0) == 1.0 - - -def test_calc_h_exit(): - assert piping_functions_old.calc_h_exit(0.1, 2.0) == 2.0 - assert piping_functions_old.calc_h_exit(0.0, 0.1) == 0.1 - assert piping_functions_old.calc_h_exit(0.0, 0.000001) == 0.000001 - assert piping_functions_old.calc_h_exit(0.0, 0.0) == 0.0 - - -def test_calc_dH_red(): - assert piping_functions_old.calc_dH_red(5.0, 2.0, 0.3, 10.0) == 0.0 - - -def test_calc_d_pot_c_u(): - assert piping_functions_old.calc_d_pot_c_u(6.0, 15.0, 9.81) == pytest.approx( - 3.174, 0.0001 - ) - assert piping_functions_old.calc_d_pot_c_u(0.0, 15.0, 9.81) == 0.0 - assert piping_functions_old.calc_d_pot_c_u(2.36690, 16.5, 9.81) == pytest.approx( - 1.614, 0.0001 - ) - - -def test_calc_Z_u(): - assert piping_functions_old.calc_Z_u(1.614127, 3.18087, 2.466904, 1.0) == pytest.approx( - 0.900157, 0.0001 - ) - assert piping_functions_old.calc_Z_u(3.1743, 7.04412, -0.5, 1.0) == pytest.approx( - -4.3698, 0.0001 - ) - - -def test_calc_F_u(): - assert piping_functions_old.calc_F_u(3.1743, 7.0441, -0.500) == pytest.approx( - 0.4208, 0.0001 - ) - assert piping_functions_old.calc_F_u(1.6141, 1.5, 1.5) == 8.00 - assert piping_functions_old.calc_F_u(2.0, 1.5, 1.48) == pytest.approx(100.000, 0.001) - - -def test_calc_F_u_macro(): - assert piping_functions_old.calc_F_u_macro(2.0, 15.0, 9.81, 1.5, 1.0) == pytest.approx( - 1.2232415902140672, 0.0001 - ) - assert piping_functions_old.calc_F_u_macro(2.0, 15.0, 9.81, 1.5, 1.5) == 8.00 - - -def test_calc_i_optredend(): - assert piping_functions_old.calc_i_optredend(4.0, 2.0, 1.0) == 2.0 - assert piping_functions_old.calc_i_optredend(4.0, 2.0, 2.0) == 1.0 - assert piping_functions_old.calc_i_optredend(4.0, 2.0, 0.1) == 20.0 - - -def test_calc_Z_h(): - assert piping_functions_old.calc_Z_h(0.5, 0.5, 1.0) == 0.0 - assert piping_functions_old.calc_Z_h(0.5, 0.1, 1.0) == 0.4 - assert piping_functions_old.calc_Z_h(0.5, 0.51, 1.0) == pytest.approx(-0.01, 0.0001) - assert piping_functions_old.calc_Z_h(0.5, 0.55, 1.1) == 0.0 - - -def test_calc_F_h(): - assert piping_functions_old.calc_F_h(0.5, 0.5) == 1.0 - assert piping_functions_old.calc_F_h(0.5, 0.1) == 5.0 - assert piping_functions_old.calc_F_h(0.5, 0.51) == pytest.approx((0.5 / 0.51), 0.0001) - assert piping_functions_old.calc_F_h(0.5, 1.0) == 0.5 - - -def test_calc_dH_sellmeijer_inc_calc_settings(): - assert piping_functions_old.calc_dH_sellmeijer_inc_calc_settings( - 2.530e-04, # m - 19.24, # m/d - 27.5, # m - 108.157096, # m - 9.81, # m/s^2 - 0.00000133, # viscosity - 37.0, # grd - 0.25, # [-] - 2.08e-4, # m - 26.0, - ) == pytest.approx(6.50006e00, 0.0001) - - -def test_calc_dH_sellmeijer(): - assert piping_functions_old.calc_dH_sellmeijer( - 3.50e-04, - 41.4, - 50.0, - 238.0892, - 9.81, # m # m/d # m # m # m/s^2 - ) == pytest.approx(10.1276, 0.0001) - assert piping_functions_old.calc_dH_sellmeijer( - 2.530e-04, # m - 19.24, # m/d - 27.5, # m - 108.157096, # m - 9.81, # m/s^2 - ) == pytest.approx(6.50006e00, 0.0001) - - -def test_Z_p(): - assert piping_functions_old.calc_Z_p(5.0, 5.0, 1.0) == 0.0 - assert piping_functions_old.calc_Z_p(6.5, 7.5, 1.0) == -1.0 - assert piping_functions_old.calc_Z_p(6.5, 7.5, 1.2) == pytest.approx(0.3, 0.001) - - -def test_calc_F_p(): - assert piping_functions_old.calc_F_p(5.0, 5.0) == 1.0 - assert piping_functions_old.calc_F_p(6.5, 7.5) == pytest.approx( - 0.8666666666666667, 0.0001 - ) - assert piping_functions_old.calc_F_p(1.0, 10.0) == pytest.approx(0.1, 0.0001) - assert piping_functions_old.calc_F_p(1.0, 0.0) == 100.0 diff --git a/tests/test_piping_functions_nieuw.py b/tests/test_piping_functions_nieuw.py deleted file mode 100644 index 54d42114..00000000 --- a/tests/test_piping_functions_nieuw.py +++ /dev/null @@ -1,152 +0,0 @@ -"""Test module for piping_functions.py""" - -import pytest - -from app.helper_functions import piping_functions - -## testcase model 4a -# k = 40 #m/d -# D = 50 #m -# c1 = 10 #d -# c3 = 50 #d -# L1 = 150 #m -# L2 = 45 #m -# L3 = 3000.0 #m -# x_but = 0.0 #m -# x_bit = 45.0 #m -# lambda1 = 141.4213562373095 -# lambda3 = 316.22776601683793319988935444327 -# W1 = 111.14536276273107 -# W3 = 316.2277623787640000 -# W_tot4a = 472.373125141495 -# r_but = 0.76470853898 -# r_bit = 0.66944486371 -# r(-150.0) = 1.0 -# r(3045.0) = 0.0 -# r(-50.0) = 0.8579165276194 -# r(55.0) = 0.648606379956042 -# r(90.0) = 0.580648922902315 -# r(22.5) = 0.717076701341341 -# piping input -# D70 = 2.7E-4 m - -def test_calc_r_exit_model4a(): - assert piping_functions.calc_r_exit_model4a(40.0, 50.0, 10.0, 50.0, - (150.0+45.0+10.),(45.0+10.0), - 10.0, 3000.0) == pytest.approx(0.648606379956042, 0.001) - -# def test_calc_Dcover(): -# assert piping_functions.calc_Dcover(0.0, 2.0) == 0.1 -# assert piping_functions.calc_Dcover(2.0, 1.0) == 1.0 - - -# def test_calc_h_exit(): -# assert piping_functions.calc_h_exit(0.1, 2.0) == 2.0 -# assert piping_functions.calc_h_exit(0.0, 0.1) == 0.1 -# assert piping_functions.calc_h_exit(0.0, 0.000001) == 0.000001 -# assert piping_functions.calc_h_exit(0.0, 0.0) == 0.0 - - -# def test_calc_dH_red(): -# assert piping_functions.calc_dH_red(5.0, 2.0, 0.3, 10.0) == 0.0 - - -# def test_calc_d_pot_c_u(): -# assert piping_functions.calc_d_pot_c_u(6.0, 15.0, 9.81) == pytest.approx( -# 3.174, 0.0001 -# ) -# assert piping_functions.calc_d_pot_c_u(0.0, 15.0, 9.81) == 0.0 -# assert piping_functions.calc_d_pot_c_u(2.36690, 16.5, 9.81) == pytest.approx( -# 1.614, 0.0001 -# ) - - -# def test_calc_Z_u(): -# assert piping_functions.calc_Z_u(1.614127, 3.18087, 2.466904, 1.0) == pytest.approx( -# 0.900157, 0.0001 -# ) -# assert piping_functions.calc_Z_u(3.1743, 7.04412, -0.5, 1.0) == pytest.approx( -# -4.3698, 0.0001 -# ) - - -# def test_calc_F_u(): -# assert piping_functions.calc_F_u(3.1743, 7.0441, -0.500) == pytest.approx( -# 0.4208, 0.0001 -# ) -# assert piping_functions.calc_F_u(1.6141, 1.5, 1.5) == 8.00 -# assert piping_functions.calc_F_u(2.0, 1.5, 1.48) == pytest.approx(100.000, 0.001) - - -# def test_calc_F_u_macro(): -# assert piping_functions.calc_F_u_macro(2.0, 15.0, 9.81, 1.5, 1.0) == pytest.approx( -# 1.2232415902140672, 0.0001 -# ) -# assert piping_functions.calc_F_u_macro(2.0, 15.0, 9.81, 1.5, 1.5) == 8.00 - - -# def test_calc_i_optredend(): -# assert piping_functions.calc_i_optredend(4.0, 2.0, 1.0) == 2.0 -# assert piping_functions.calc_i_optredend(4.0, 2.0, 2.0) == 1.0 -# assert piping_functions.calc_i_optredend(4.0, 2.0, 0.1) == 20.0 - - -# def test_calc_Z_h(): -# assert piping_functions.calc_Z_h(0.5, 0.5, 1.0) == 0.0 -# assert piping_functions.calc_Z_h(0.5, 0.1, 1.0) == 0.4 -# assert piping_functions.calc_Z_h(0.5, 0.51, 1.0) == pytest.approx(-0.01, 0.0001) -# assert piping_functions.calc_Z_h(0.5, 0.55, 1.1) == 0.0 - - -# def test_calc_F_h(): -# assert piping_functions.calc_F_h(0.5, 0.5) == 1.0 -# assert piping_functions.calc_F_h(0.5, 0.1) == 5.0 -# assert piping_functions.calc_F_h(0.5, 0.51) == pytest.approx((0.5 / 0.51), 0.0001) -# assert piping_functions.calc_F_h(0.5, 1.0) == 0.5 - - -# def test_calc_dH_sellmeijer_inc_calc_settings(): -# assert piping_functions.calc_dH_sellmeijer_inc_calc_settings( -# 2.530e-04, # m -# 19.24, # m/d -# 27.5, # m -# 108.157096, # m -# 9.81, # m/s^2 -# 0.00000133, # viscosity -# 37.0, # grd -# 0.25, # [-] -# 2.08e-4, # m -# 26.0, -# ) == pytest.approx(6.50006e00, 0.0001) - - -# def test_calc_dH_sellmeijer(): -# assert piping_functions.calc_dH_sellmeijer( -# 3.50e-04, -# 41.4, -# 50.0, -# 238.0892, -# 9.81, # m # m/d # m # m # m/s^2 -# ) == pytest.approx(10.1276, 0.0001) -# assert piping_functions.calc_dH_sellmeijer( -# 2.530e-04, # m -# 19.24, # m/d -# 27.5, # m -# 108.157096, # m -# 9.81, # m/s^2 -# ) == pytest.approx(6.50006e00, 0.0001) - - -# def test_Z_p(): -# assert piping_functions.calc_Z_p(5.0, 5.0, 1.0) == 0.0 -# assert piping_functions.calc_Z_p(6.5, 7.5, 1.0) == -1.0 -# assert piping_functions.calc_Z_p(6.5, 7.5, 1.2) == pytest.approx(0.3, 0.001) - - -# def test_calc_F_p(): -# assert piping_functions.calc_F_p(5.0, 5.0) == 1.0 -# assert piping_functions.calc_F_p(6.5, 7.5) == pytest.approx( -# 0.8666666666666667, 0.0001 -# ) -# assert piping_functions.calc_F_p(1.0, 10.0) == pytest.approx(0.1, 0.0001) -# assert piping_functions.calc_F_p(1.0, 0.0) == 100.0 diff --git a/tests/test_system.py b/tests/test_system.py new file mode 100644 index 00000000..70e8c0cd --- /dev/null +++ b/tests/test_system.py @@ -0,0 +1,29 @@ + +def test_system(): + + ## + if __name__ == "__main__": + from repo_utils.utils import repository_root_path + from geoprob_pipe import GeoProbPipe + import os + repo_root = repository_root_path() + from geoprob_pipe.cmd_app.cmd import ApplicationSettings + + file_names = [ + # "Traject224_MORIA_WBN_det_corr.geoprob_pipe.gpkg", + # "Traject224_MORIA_WBN_det_uncorr.geoprob_pipe.gpkg", + "Traject224_MORIA_WBN_prob.geoprob_pipe.gpkg", + # "Traject224_model4a_WBN_prob.geoprob_pipe.gpkg", + # "Traject224_WBI_WBN_prob.geoprob_pipe.gpkg", # TODO + ] + + for file_name in file_names: + print(f"\nNow running {file_name}") + app_settings = ApplicationSettings() + filepath = os.path.join(repo_root, "tests", "systeem_testen", "224", file_name) + app_settings.workspace_dir = os.path.dirname(filepath) + app_settings.geopackage_filename = os.path.basename(filepath) + geoprob_pipe = GeoProbPipe(app_settings) + geoprob_pipe.export_archive() + + ## diff --git a/tests/testset/DT41-4_WBI2017.csv b/tests/testset/DT41-4_WBI2017.csv deleted file mode 100644 index ca31e97a..00000000 --- a/tests/testset/DT41-4_WBI2017.csv +++ /dev/null @@ -1,1394 +0,0 @@ -Randvoorwaardendatabase Locatie X-cordinaat Y-cordinaat Profiel Klimaatscenario Type Berekening Overslagdebiet [l/s/m]/Type bekleding Waterstandsniveau [m+NAP] Terugkeertijd [jaar] Belastingniveau [m+NAP]/Golfparameter [m]/[s]/Sterkte bekleding [-] Golfhoogte [m] Piekperiode [s] Golfrichting [] Golfinval [] -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00004 188420 418765 - WBI2017 Waterstand - - 10 10.691 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00004 188420 418765 - WBI2017 Waterstand - - 100 12.021 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00004 188420 418765 - WBI2017 Waterstand - - 300 12.424 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00004 188420 418765 - WBI2017 Waterstand - - 1000 12.744 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00004 188420 418765 - WBI2017 Waterstand - - 3000 12.996 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00004 188420 418765 - WBI2017 Waterstand - - 10000 13.295 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00004 188420 418765 - WBI2017 Waterstand - - 30000 13.621 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00005 188352 418818 - WBI2017 Waterstand - - 10 10.691 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00005 188352 418818 - WBI2017 Waterstand - - 100 12.022 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00005 188352 418818 - WBI2017 Waterstand - - 300 12.427 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00005 188352 418818 - WBI2017 Waterstand - - 1000 12.746 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00005 188352 418818 - WBI2017 Waterstand - - 3000 12.998 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00005 188352 418818 - WBI2017 Waterstand - - 10000 13.295 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00005 188352 418818 - WBI2017 Waterstand - - 30000 13.626 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00006 188269 418848 - WBI2017 Waterstand - - 10 10.691 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00006 188269 418848 - WBI2017 Waterstand - - 100 12.016 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00006 188269 418848 - WBI2017 Waterstand - - 300 12.415 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00006 188269 418848 - WBI2017 Waterstand - - 1000 12.735 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00006 188269 418848 - WBI2017 Waterstand - - 3000 12.988 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00006 188269 418848 - WBI2017 Waterstand - - 10000 13.287 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00006 188269 418848 - WBI2017 Waterstand - - 30000 13.615 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00007 188167 418913 - WBI2017 Waterstand - - 10 10.668 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00007 188167 418913 - WBI2017 Waterstand - - 100 12.021 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00007 188167 418913 - WBI2017 Waterstand - - 300 12.424 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00007 188167 418913 - WBI2017 Waterstand - - 1000 12.741 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00007 188167 418913 - WBI2017 Waterstand - - 3000 12.991 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00007 188167 418913 - WBI2017 Waterstand - - 10000 13.293 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00007 188167 418913 - WBI2017 Waterstand - - 30000 13.623 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00008 188098 418953 - WBI2017 Waterstand - - 10 10.691 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00008 188098 418953 - WBI2017 Waterstand - - 100 12.021 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00008 188098 418953 - WBI2017 Waterstand - - 300 12.424 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00008 188098 418953 - WBI2017 Waterstand - - 1000 12.741 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00008 188098 418953 - WBI2017 Waterstand - - 3000 12.991 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00008 188098 418953 - WBI2017 Waterstand - - 10000 13.293 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00008 188098 418953 - WBI2017 Waterstand - - 30000 13.620 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00009 187982 418986 - WBI2017 Waterstand - - 10 10.699 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00009 187982 418986 - WBI2017 Waterstand - - 100 12.017 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00009 187982 418986 - WBI2017 Waterstand - - 300 12.421 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00009 187982 418986 - WBI2017 Waterstand - - 1000 12.737 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00009 187982 418986 - WBI2017 Waterstand - - 3000 12.988 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00009 187982 418986 - WBI2017 Waterstand - - 10000 13.287 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00009 187982 418986 - WBI2017 Waterstand - - 30000 13.615 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00010 187920 419038 - WBI2017 Waterstand - - 10 10.700 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00010 187920 419038 - WBI2017 Waterstand - - 100 12.021 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00010 187920 419038 - WBI2017 Waterstand - - 300 12.424 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00010 187920 419038 - WBI2017 Waterstand - - 1000 12.742 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00010 187920 419038 - WBI2017 Waterstand - - 3000 12.991 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00010 187920 419038 - WBI2017 Waterstand - - 10000 13.290 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00010 187920 419038 - WBI2017 Waterstand - - 30000 13.620 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00011 187818 419102 - WBI2017 Waterstand - - 10 10.699 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00011 187818 419102 - WBI2017 Waterstand - - 100 12.016 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00011 187818 419102 - WBI2017 Waterstand - - 300 12.414 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00011 187818 419102 - WBI2017 Waterstand - - 1000 12.732 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00011 187818 419102 - WBI2017 Waterstand - - 3000 12.983 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00011 187818 419102 - WBI2017 Waterstand - - 10000 13.281 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00011 187818 419102 - WBI2017 Waterstand - - 30000 13.606 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00012 187750 419153 - WBI2017 Waterstand - - 10 10.700 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00012 187750 419153 - WBI2017 Waterstand - - 100 12.015 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00012 187750 419153 - WBI2017 Waterstand - - 300 12.414 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00012 187750 419153 - WBI2017 Waterstand - - 1000 12.732 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00012 187750 419153 - WBI2017 Waterstand - - 3000 12.981 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00012 187750 419153 - WBI2017 Waterstand - - 10000 13.280 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00012 187750 419153 - WBI2017 Waterstand - - 30000 13.609 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00013 187687 419237 - WBI2017 Waterstand - - 10 10.700 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00013 187687 419237 - WBI2017 Waterstand - - 100 12.016 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00013 187687 419237 - WBI2017 Waterstand - - 300 12.419 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00013 187687 419237 - WBI2017 Waterstand - - 1000 12.733 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00013 187687 419237 - WBI2017 Waterstand - - 3000 12.986 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00013 187687 419237 - WBI2017 Waterstand - - 10000 13.284 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00013 187687 419237 - WBI2017 Waterstand - - 30000 13.613 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00014 187611 419292 - WBI2017 Waterstand - - 10 10.700 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00014 187611 419292 - WBI2017 Waterstand - - 100 12.020 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00014 187611 419292 - WBI2017 Waterstand - - 300 12.421 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00014 187611 419292 - WBI2017 Waterstand - - 1000 12.737 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00014 187611 419292 - WBI2017 Waterstand - - 3000 12.988 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00014 187611 419292 - WBI2017 Waterstand - - 10000 13.287 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00014 187611 419292 - WBI2017 Waterstand - - 30000 13.615 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00015 187538 419391 - WBI2017 Waterstand - - 10 10.771 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00015 187538 419391 - WBI2017 Waterstand - - 100 12.022 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00015 187538 419391 - WBI2017 Waterstand - - 300 12.421 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00015 187538 419391 - WBI2017 Waterstand - - 1000 12.739 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00015 187538 419391 - WBI2017 Waterstand - - 3000 12.988 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00015 187538 419391 - WBI2017 Waterstand - - 10000 13.290 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00015 187538 419391 - WBI2017 Waterstand - - 30000 13.620 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00016 187451 419450 - WBI2017 Waterstand - - 10 10.771 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00016 187451 419450 - WBI2017 Waterstand - - 100 12.022 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00016 187451 419450 - WBI2017 Waterstand - - 300 12.421 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00016 187451 419450 - WBI2017 Waterstand - - 1000 12.739 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00016 187451 419450 - WBI2017 Waterstand - - 3000 12.988 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00016 187451 419450 - WBI2017 Waterstand - - 10000 13.290 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00016 187451 419450 - WBI2017 Waterstand - - 30000 13.620 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00017 187412 419551 - WBI2017 Waterstand - - 10 10.700 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00017 187412 419551 - WBI2017 Waterstand - - 100 12.022 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00017 187412 419551 - WBI2017 Waterstand - - 300 12.421 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00017 187412 419551 - WBI2017 Waterstand - - 1000 12.739 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00017 187412 419551 - WBI2017 Waterstand - - 3000 12.988 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00017 187412 419551 - WBI2017 Waterstand - - 10000 13.290 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00017 187412 419551 - WBI2017 Waterstand - - 30000 13.620 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00018 187364 419603 - WBI2017 Waterstand - - 10 10.700 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00018 187364 419603 - WBI2017 Waterstand - - 100 12.022 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00018 187364 419603 - WBI2017 Waterstand - - 300 12.421 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00018 187364 419603 - WBI2017 Waterstand - - 1000 12.739 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00018 187364 419603 - WBI2017 Waterstand - - 3000 12.988 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00018 187364 419603 - WBI2017 Waterstand - - 10000 13.290 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00018 187364 419603 - WBI2017 Waterstand - - 30000 13.620 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00019 187315 419703 - WBI2017 Waterstand - - 10 10.700 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00019 187315 419703 - WBI2017 Waterstand - - 100 12.022 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00019 187315 419703 - WBI2017 Waterstand - - 300 12.421 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00019 187315 419703 - WBI2017 Waterstand - - 1000 12.739 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00019 187315 419703 - WBI2017 Waterstand - - 3000 12.988 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00019 187315 419703 - WBI2017 Waterstand - - 10000 13.290 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00019 187315 419703 - WBI2017 Waterstand - - 30000 13.620 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00020 187260 419802 - WBI2017 Waterstand - - 10 10.700 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00020 187260 419802 - WBI2017 Waterstand - - 100 12.022 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00020 187260 419802 - WBI2017 Waterstand - - 300 12.421 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00020 187260 419802 - WBI2017 Waterstand - - 1000 12.739 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00020 187260 419802 - WBI2017 Waterstand - - 3000 12.988 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00020 187260 419802 - WBI2017 Waterstand - - 10000 13.290 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00020 187260 419802 - WBI2017 Waterstand - - 30000 13.620 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00021 187256 419902 - WBI2017 Waterstand - - 10 10.700 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00021 187256 419902 - WBI2017 Waterstand - - 100 12.022 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00021 187256 419902 - WBI2017 Waterstand - - 300 12.421 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00021 187256 419902 - WBI2017 Waterstand - - 1000 12.739 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00021 187256 419902 - WBI2017 Waterstand - - 3000 12.988 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00021 187256 419902 - WBI2017 Waterstand - - 10000 13.290 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00021 187256 419902 - WBI2017 Waterstand - - 30000 13.620 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00022 187193 419995 - WBI2017 Waterstand - - 10 10.771 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00022 187193 419995 - WBI2017 Waterstand - - 100 12.022 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00022 187193 419995 - WBI2017 Waterstand - - 300 12.421 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00022 187193 419995 - WBI2017 Waterstand - - 1000 12.739 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00022 187193 419995 - WBI2017 Waterstand - - 3000 12.988 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00022 187193 419995 - WBI2017 Waterstand - - 10000 13.290 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00022 187193 419995 - WBI2017 Waterstand - - 30000 13.620 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00023 187136 419990 - WBI2017 Waterstand - - 10 10.700 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00023 187136 419990 - WBI2017 Waterstand - - 100 12.022 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00023 187136 419990 - WBI2017 Waterstand - - 300 12.421 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00023 187136 419990 - WBI2017 Waterstand - - 1000 12.739 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00023 187136 419990 - WBI2017 Waterstand - - 3000 12.988 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00023 187136 419990 - WBI2017 Waterstand - - 10000 13.290 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00023 187136 419990 - WBI2017 Waterstand - - 30000 13.620 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00024 187085 419939 - WBI2017 Waterstand - - 10 10.771 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00024 187085 419939 - WBI2017 Waterstand - - 100 12.022 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00024 187085 419939 - WBI2017 Waterstand - - 300 12.421 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00024 187085 419939 - WBI2017 Waterstand - - 1000 12.739 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00024 187085 419939 - WBI2017 Waterstand - - 3000 12.988 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00024 187085 419939 - WBI2017 Waterstand - - 10000 13.290 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00024 187085 419939 - WBI2017 Waterstand - - 30000 13.620 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00025 187148 419846 - WBI2017 Waterstand - - 10 10.700 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00025 187148 419846 - WBI2017 Waterstand - - 100 12.022 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00025 187148 419846 - WBI2017 Waterstand - - 300 12.421 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00025 187148 419846 - WBI2017 Waterstand - - 1000 12.739 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00025 187148 419846 - WBI2017 Waterstand - - 3000 12.988 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00025 187148 419846 - WBI2017 Waterstand - - 10000 13.290 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00025 187148 419846 - WBI2017 Waterstand - - 30000 13.620 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00026 187206 419800 - WBI2017 Waterstand - - 10 10.700 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00026 187206 419800 - WBI2017 Waterstand - - 100 12.022 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00026 187206 419800 - WBI2017 Waterstand - - 300 12.421 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00026 187206 419800 - WBI2017 Waterstand - - 1000 12.739 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00026 187206 419800 - WBI2017 Waterstand - - 3000 12.988 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00026 187206 419800 - WBI2017 Waterstand - - 10000 13.290 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00026 187206 419800 - WBI2017 Waterstand - - 30000 13.620 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00027 187262 419703 - WBI2017 Waterstand - - 10 10.700 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00027 187262 419703 - WBI2017 Waterstand - - 100 12.022 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00027 187262 419703 - WBI2017 Waterstand - - 300 12.421 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00027 187262 419703 - WBI2017 Waterstand - - 1000 12.739 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00027 187262 419703 - WBI2017 Waterstand - - 3000 12.988 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00027 187262 419703 - WBI2017 Waterstand - - 10000 13.290 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00027 187262 419703 - WBI2017 Waterstand - - 30000 13.620 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00028 187313 419604 - WBI2017 Waterstand - - 10 10.700 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00028 187313 419604 - WBI2017 Waterstand - - 100 12.022 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00028 187313 419604 - WBI2017 Waterstand - - 300 12.421 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00028 187313 419604 - WBI2017 Waterstand - - 1000 12.739 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00028 187313 419604 - WBI2017 Waterstand - - 3000 12.988 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00028 187313 419604 - WBI2017 Waterstand - - 10000 13.290 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00028 187313 419604 - WBI2017 Waterstand - - 30000 13.617 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00029 187359 419505 - WBI2017 Waterstand - - 10 10.700 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00029 187359 419505 - WBI2017 Waterstand - - 100 12.022 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00029 187359 419505 - WBI2017 Waterstand - - 300 12.421 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00029 187359 419505 - WBI2017 Waterstand - - 1000 12.739 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00029 187359 419505 - WBI2017 Waterstand - - 3000 12.988 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00029 187359 419505 - WBI2017 Waterstand - - 10000 13.290 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00029 187359 419505 - WBI2017 Waterstand - - 30000 13.620 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00030 187400 419408 - WBI2017 Waterstand - - 10 10.636 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00030 187400 419408 - WBI2017 Waterstand - - 100 12.022 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00030 187400 419408 - WBI2017 Waterstand - - 300 12.421 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00030 187400 419408 - WBI2017 Waterstand - - 1000 12.739 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00030 187400 419408 - WBI2017 Waterstand - - 3000 12.988 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00030 187400 419408 - WBI2017 Waterstand - - 10000 13.290 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00030 187400 419408 - WBI2017 Waterstand - - 30000 13.620 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00031 187302 419331 - WBI2017 Waterstand - - 10 10.624 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00031 187302 419331 - WBI2017 Waterstand - - 100 11.928 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00031 187302 419331 - WBI2017 Waterstand - - 300 12.322 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00031 187302 419331 - WBI2017 Waterstand - - 1000 12.639 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00031 187302 419331 - WBI2017 Waterstand - - 3000 12.886 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00031 187302 419331 - WBI2017 Waterstand - - 10000 13.181 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00031 187302 419331 - WBI2017 Waterstand - - 30000 13.504 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00032 187210 419334 - WBI2017 Waterstand - - 10 10.622 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00032 187210 419334 - WBI2017 Waterstand - - 100 11.928 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00032 187210 419334 - WBI2017 Waterstand - - 300 12.327 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00032 187210 419334 - WBI2017 Waterstand - - 1000 12.643 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00032 187210 419334 - WBI2017 Waterstand - - 3000 12.894 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00032 187210 419334 - WBI2017 Waterstand - - 10000 13.188 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00032 187210 419334 - WBI2017 Waterstand - - 30000 13.512 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00033 187117 419374 - WBI2017 Waterstand - - 10 10.600 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00033 187117 419374 - WBI2017 Waterstand - - 100 11.920 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00033 187117 419374 - WBI2017 Waterstand - - 300 12.321 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00033 187117 419374 - WBI2017 Waterstand - - 1000 12.639 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00033 187117 419374 - WBI2017 Waterstand - - 3000 12.888 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00033 187117 419374 - WBI2017 Waterstand - - 10000 13.188 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00033 187117 419374 - WBI2017 Waterstand - - 30000 13.512 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00034 187020 419412 - WBI2017 Waterstand - - 10 10.591 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00034 187020 419412 - WBI2017 Waterstand - - 100 11.913 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00034 187020 419412 - WBI2017 Waterstand - - 300 12.313 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00034 187020 419412 - WBI2017 Waterstand - - 1000 12.633 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00034 187020 419412 - WBI2017 Waterstand - - 3000 12.884 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00034 187020 419412 - WBI2017 Waterstand - - 10000 13.181 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00034 187020 419412 - WBI2017 Waterstand - - 30000 13.504 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00035 186929 419364 - WBI2017 Waterstand - - 10 10.590 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00035 186929 419364 - WBI2017 Waterstand - - 100 11.904 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00035 186929 419364 - WBI2017 Waterstand - - 300 12.303 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00035 186929 419364 - WBI2017 Waterstand - - 1000 12.621 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00035 186929 419364 - WBI2017 Waterstand - - 3000 12.874 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00035 186929 419364 - WBI2017 Waterstand - - 10000 13.170 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00035 186929 419364 - WBI2017 Waterstand - - 30000 13.494 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00036 186831 419396 - WBI2017 Waterstand - - 10 10.577 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00036 186831 419396 - WBI2017 Waterstand - - 100 11.892 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00036 186831 419396 - WBI2017 Waterstand - - 300 12.290 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00036 186831 419396 - WBI2017 Waterstand - - 1000 12.607 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00036 186831 419396 - WBI2017 Waterstand - - 3000 12.865 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00036 186831 419396 - WBI2017 Waterstand - - 10000 13.161 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00036 186831 419396 - WBI2017 Waterstand - - 30000 13.486 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00037 186739 419385 - WBI2017 Waterstand - - 10 10.571 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00037 186739 419385 - WBI2017 Waterstand - - 100 11.881 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00037 186739 419385 - WBI2017 Waterstand - - 300 12.281 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00037 186739 419385 - WBI2017 Waterstand - - 1000 12.591 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00037 186739 419385 - WBI2017 Waterstand - - 3000 12.855 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00037 186739 419385 - WBI2017 Waterstand - - 10000 13.149 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00037 186739 419385 - WBI2017 Waterstand - - 30000 13.475 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00038 186644 419417 - WBI2017 Waterstand - - 10 10.567 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00038 186644 419417 - WBI2017 Waterstand - - 100 11.874 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00038 186644 419417 - WBI2017 Waterstand - - 300 12.271 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00038 186644 419417 - WBI2017 Waterstand - - 1000 12.585 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00038 186644 419417 - WBI2017 Waterstand - - 3000 12.848 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00038 186644 419417 - WBI2017 Waterstand - - 10000 13.144 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00038 186644 419417 - WBI2017 Waterstand - - 30000 13.471 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00039 186551 419450 - WBI2017 Waterstand - - 10 10.542 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00039 186551 419450 - WBI2017 Waterstand - - 100 11.853 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00039 186551 419450 - WBI2017 Waterstand - - 300 12.250 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00039 186551 419450 - WBI2017 Waterstand - - 1000 12.567 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00039 186551 419450 - WBI2017 Waterstand - - 3000 12.826 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00039 186551 419450 - WBI2017 Waterstand - - 10000 13.115 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00039 186551 419450 - WBI2017 Waterstand - - 30000 13.447 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00040 186466 419438 - WBI2017 Waterstand - - 10 10.531 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00040 186466 419438 - WBI2017 Waterstand - - 100 11.842 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00040 186466 419438 - WBI2017 Waterstand - - 300 12.238 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00040 186466 419438 - WBI2017 Waterstand - - 1000 12.556 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00040 186466 419438 - WBI2017 Waterstand - - 3000 12.812 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00040 186466 419438 - WBI2017 Waterstand - - 10000 13.105 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00040 186466 419438 - WBI2017 Waterstand - - 30000 13.437 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00041 186378 419472 - WBI2017 Waterstand - - 10 10.529 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00041 186378 419472 - WBI2017 Waterstand - - 100 11.832 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00041 186378 419472 - WBI2017 Waterstand - - 300 12.231 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00041 186378 419472 - WBI2017 Waterstand - - 1000 12.550 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00041 186378 419472 - WBI2017 Waterstand - - 3000 12.805 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00041 186378 419472 - WBI2017 Waterstand - - 10000 13.098 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00041 186378 419472 - WBI2017 Waterstand - - 30000 13.431 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00042 186250 419500 - WBI2017 Waterstand - - 10 10.524 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00042 186250 419500 - WBI2017 Waterstand - - 100 11.828 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00042 186250 419500 - WBI2017 Waterstand - - 300 12.227 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00042 186250 419500 - WBI2017 Waterstand - - 1000 12.546 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00042 186250 419500 - WBI2017 Waterstand - - 3000 12.800 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00042 186250 419500 - WBI2017 Waterstand - - 10000 13.096 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00042 186250 419500 - WBI2017 Waterstand - - 30000 13.427 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00043 186168 419489 - WBI2017 Waterstand - - 10 10.517 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00043 186168 419489 - WBI2017 Waterstand - - 100 11.829 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00043 186168 419489 - WBI2017 Waterstand - - 300 12.227 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00043 186168 419489 - WBI2017 Waterstand - - 1000 12.547 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00043 186168 419489 - WBI2017 Waterstand - - 3000 12.800 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00043 186168 419489 - WBI2017 Waterstand - - 10000 13.098 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00043 186168 419489 - WBI2017 Waterstand - - 30000 13.430 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00044 186141 419390 - WBI2017 Waterstand - - 10 10.515 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00044 186141 419390 - WBI2017 Waterstand - - 100 11.815 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00044 186141 419390 - WBI2017 Waterstand - - 300 12.214 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00044 186141 419390 - WBI2017 Waterstand - - 1000 12.532 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00044 186141 419390 - WBI2017 Waterstand - - 3000 12.784 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00044 186141 419390 - WBI2017 Waterstand - - 10000 13.081 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00044 186141 419390 - WBI2017 Waterstand - - 30000 13.410 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00045 186008 419416 - WBI2017 Waterstand - - 10 10.491 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00045 186008 419416 - WBI2017 Waterstand - - 100 11.792 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00045 186008 419416 - WBI2017 Waterstand - - 300 12.186 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00045 186008 419416 - WBI2017 Waterstand - - 1000 12.501 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00045 186008 419416 - WBI2017 Waterstand - - 3000 12.762 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00045 186008 419416 - WBI2017 Waterstand - - 10000 13.058 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00045 186008 419416 - WBI2017 Waterstand - - 30000 13.383 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00046 185965 419410 - WBI2017 Waterstand - - 10 10.491 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00046 185965 419410 - WBI2017 Waterstand - - 100 11.792 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00046 185965 419410 - WBI2017 Waterstand - - 300 12.186 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00046 185965 419410 - WBI2017 Waterstand - - 1000 12.501 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00046 185965 419410 - WBI2017 Waterstand - - 3000 12.762 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00046 185965 419410 - WBI2017 Waterstand - - 10000 13.057 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00046 185965 419410 - WBI2017 Waterstand - - 30000 13.383 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00047 185886 419348 - WBI2017 Waterstand - - 10 10.488 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00047 185886 419348 - WBI2017 Waterstand - - 100 11.784 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00047 185886 419348 - WBI2017 Waterstand - - 300 12.181 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00047 185886 419348 - WBI2017 Waterstand - - 1000 12.491 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00047 185886 419348 - WBI2017 Waterstand - - 3000 12.755 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00047 185886 419348 - WBI2017 Waterstand - - 10000 13.049 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00047 185886 419348 - WBI2017 Waterstand - - 30000 13.378 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00048 185754 419324 - WBI2017 Waterstand - - 10 10.482 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00048 185754 419324 - WBI2017 Waterstand - - 100 11.772 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00048 185754 419324 - WBI2017 Waterstand - - 300 12.167 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00048 185754 419324 - WBI2017 Waterstand - - 1000 12.482 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00048 185754 419324 - WBI2017 Waterstand - - 3000 12.742 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00048 185754 419324 - WBI2017 Waterstand - - 10000 13.035 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00048 185754 419324 - WBI2017 Waterstand - - 30000 13.364 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00049 185665 419308 - WBI2017 Waterstand - - 10 10.474 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00049 185665 419308 - WBI2017 Waterstand - - 100 11.767 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00049 185665 419308 - WBI2017 Waterstand - - 300 12.158 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00049 185665 419308 - WBI2017 Waterstand - - 1000 12.474 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00049 185665 419308 - WBI2017 Waterstand - - 3000 12.733 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00049 185665 419308 - WBI2017 Waterstand - - 10000 13.024 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00049 185665 419308 - WBI2017 Waterstand - - 30000 13.354 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00050 185577 419291 - WBI2017 Waterstand - - 10 10.465 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00050 185577 419291 - WBI2017 Waterstand - - 100 11.758 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00050 185577 419291 - WBI2017 Waterstand - - 300 12.151 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00050 185577 419291 - WBI2017 Waterstand - - 1000 12.468 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00050 185577 419291 - WBI2017 Waterstand - - 3000 12.728 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00050 185577 419291 - WBI2017 Waterstand - - 10000 13.020 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00050 185577 419291 - WBI2017 Waterstand - - 30000 13.351 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00051 185498 419231 - WBI2017 Waterstand - - 10 10.452 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00051 185498 419231 - WBI2017 Waterstand - - 100 11.745 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00051 185498 419231 - WBI2017 Waterstand - - 300 12.138 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00051 185498 419231 - WBI2017 Waterstand - - 1000 12.456 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00051 185498 419231 - WBI2017 Waterstand - - 3000 12.711 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00051 185498 419231 - WBI2017 Waterstand - - 10000 13.005 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00051 185498 419231 - WBI2017 Waterstand - - 30000 13.335 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00052 185419 419174 - WBI2017 Waterstand - - 10 10.451 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00052 185419 419174 - WBI2017 Waterstand - - 100 11.728 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00052 185419 419174 - WBI2017 Waterstand - - 300 12.120 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00052 185419 419174 - WBI2017 Waterstand - - 1000 12.433 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00052 185419 419174 - WBI2017 Waterstand - - 3000 12.684 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00052 185419 419174 - WBI2017 Waterstand - - 10000 12.979 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00052 185419 419174 - WBI2017 Waterstand - - 30000 13.303 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00053 185387 419094 - WBI2017 Waterstand - - 10 10.434 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00053 185387 419094 - WBI2017 Waterstand - - 100 11.701 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00053 185387 419094 - WBI2017 Waterstand - - 300 12.087 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00053 185387 419094 - WBI2017 Waterstand - - 1000 12.393 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00053 185387 419094 - WBI2017 Waterstand - - 3000 12.653 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00053 185387 419094 - WBI2017 Waterstand - - 10000 12.940 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00053 185387 419094 - WBI2017 Waterstand - - 30000 13.256 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00054 185250 419108 - WBI2017 Waterstand - - 10 10.415 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00054 185250 419108 - WBI2017 Waterstand - - 100 11.677 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00054 185250 419108 - WBI2017 Waterstand - - 300 12.063 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00054 185250 419108 - WBI2017 Waterstand - - 1000 12.374 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00054 185250 419108 - WBI2017 Waterstand - - 3000 12.627 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00054 185250 419108 - WBI2017 Waterstand - - 10000 12.909 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00054 185250 419108 - WBI2017 Waterstand - - 30000 13.229 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00055 185200 419139 - WBI2017 Waterstand - - 10 10.409 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00055 185200 419139 - WBI2017 Waterstand - - 100 11.677 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00055 185200 419139 - WBI2017 Waterstand - - 300 12.063 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00055 185200 419139 - WBI2017 Waterstand - - 1000 12.373 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00055 185200 419139 - WBI2017 Waterstand - - 3000 12.627 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00055 185200 419139 - WBI2017 Waterstand - - 10000 12.909 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00055 185200 419139 - WBI2017 Waterstand - - 30000 13.231 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00056 185106 419166 - WBI2017 Waterstand - - 10 10.404 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00056 185106 419166 - WBI2017 Waterstand - - 100 11.677 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00056 185106 419166 - WBI2017 Waterstand - - 300 12.063 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00056 185106 419166 - WBI2017 Waterstand - - 1000 12.374 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00056 185106 419166 - WBI2017 Waterstand - - 3000 12.627 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00056 185106 419166 - WBI2017 Waterstand - - 10000 12.910 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00056 185106 419166 - WBI2017 Waterstand - - 30000 13.231 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00057 185017 419154 - WBI2017 Waterstand - - 10 10.404 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00057 185017 419154 - WBI2017 Waterstand - - 100 11.672 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00057 185017 419154 - WBI2017 Waterstand - - 300 12.060 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00057 185017 419154 - WBI2017 Waterstand - - 1000 12.373 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00057 185017 419154 - WBI2017 Waterstand - - 3000 12.628 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00057 185017 419154 - WBI2017 Waterstand - - 10000 12.909 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00057 185017 419154 - WBI2017 Waterstand - - 30000 13.233 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00058 184923 419185 - WBI2017 Waterstand - - 10 10.358 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00058 184923 419185 - WBI2017 Waterstand - - 100 11.672 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00058 184923 419185 - WBI2017 Waterstand - - 300 12.060 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00058 184923 419185 - WBI2017 Waterstand - - 1000 12.374 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00058 184923 419185 - WBI2017 Waterstand - - 3000 12.628 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00058 184923 419185 - WBI2017 Waterstand - - 10000 12.909 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00058 184923 419185 - WBI2017 Waterstand - - 30000 13.233 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00059 184842 419128 - WBI2017 Waterstand - - 10 10.390 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00059 184842 419128 - WBI2017 Waterstand - - 100 11.666 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00059 184842 419128 - WBI2017 Waterstand - - 300 12.055 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00059 184842 419128 - WBI2017 Waterstand - - 1000 12.368 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00059 184842 419128 - WBI2017 Waterstand - - 3000 12.625 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00059 184842 419128 - WBI2017 Waterstand - - 10000 12.909 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00059 184842 419128 - WBI2017 Waterstand - - 30000 13.233 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00060 184766 419038 - WBI2017 Waterstand - - 10 10.380 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00060 184766 419038 - WBI2017 Waterstand - - 100 11.649 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00060 184766 419038 - WBI2017 Waterstand - - 300 12.036 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00060 184766 419038 - WBI2017 Waterstand - - 1000 12.347 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00060 184766 419038 - WBI2017 Waterstand - - 3000 12.596 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00060 184766 419038 - WBI2017 Waterstand - - 10000 12.888 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00060 184766 419038 - WBI2017 Waterstand - - 30000 13.212 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00061 184737 418937 - WBI2017 Waterstand - - 10 10.372 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00061 184737 418937 - WBI2017 Waterstand - - 100 11.635 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00061 184737 418937 - WBI2017 Waterstand - - 300 12.022 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00061 184737 418937 - WBI2017 Waterstand - - 1000 12.335 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00061 184737 418937 - WBI2017 Waterstand - - 3000 12.582 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00061 184737 418937 - WBI2017 Waterstand - - 10000 12.873 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00061 184737 418937 - WBI2017 Waterstand - - 30000 13.191 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00062 184656 418898 - WBI2017 Waterstand - - 10 10.367 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00062 184656 418898 - WBI2017 Waterstand - - 100 11.619 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00062 184656 418898 - WBI2017 Waterstand - - 300 12.007 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00062 184656 418898 - WBI2017 Waterstand - - 1000 12.319 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00062 184656 418898 - WBI2017 Waterstand - - 3000 12.568 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00062 184656 418898 - WBI2017 Waterstand - - 10000 12.855 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00062 184656 418898 - WBI2017 Waterstand - - 30000 13.170 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00063 184527 418879 - WBI2017 Waterstand - - 10 10.333 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00063 184527 418879 - WBI2017 Waterstand - - 100 11.608 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00063 184527 418879 - WBI2017 Waterstand - - 300 11.993 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00063 184527 418879 - WBI2017 Waterstand - - 1000 12.301 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00063 184527 418879 - WBI2017 Waterstand - - 3000 12.556 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00063 184527 418879 - WBI2017 Waterstand - - 10000 12.842 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00063 184527 418879 - WBI2017 Waterstand - - 30000 13.158 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00064 184440 418865 - WBI2017 Waterstand - - 10 10.304 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00064 184440 418865 - WBI2017 Waterstand - - 100 11.601 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00064 184440 418865 - WBI2017 Waterstand - - 300 11.985 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00064 184440 418865 - WBI2017 Waterstand - - 1000 12.291 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00064 184440 418865 - WBI2017 Waterstand - - 3000 12.548 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00064 184440 418865 - WBI2017 Waterstand - - 10000 12.835 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00064 184440 418865 - WBI2017 Waterstand - - 30000 13.152 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00065 184354 418852 - WBI2017 Waterstand - - 10 10.285 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00065 184354 418852 - WBI2017 Waterstand - - 100 11.596 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00065 184354 418852 - WBI2017 Waterstand - - 300 11.978 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00065 184354 418852 - WBI2017 Waterstand - - 1000 12.287 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00065 184354 418852 - WBI2017 Waterstand - - 3000 12.545 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00065 184354 418852 - WBI2017 Waterstand - - 10000 12.826 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00065 184354 418852 - WBI2017 Waterstand - - 30000 13.145 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00066 184229 418808 - WBI2017 Waterstand - - 10 10.326 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00066 184229 418808 - WBI2017 Waterstand - - 100 11.576 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00066 184229 418808 - WBI2017 Waterstand - - 300 11.957 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00066 184229 418808 - WBI2017 Waterstand - - 1000 12.266 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00066 184229 418808 - WBI2017 Waterstand - - 3000 12.519 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00066 184229 418808 - WBI2017 Waterstand - - 10000 12.799 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00066 184229 418808 - WBI2017 Waterstand - - 30000 13.118 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00067 184138 418816 - WBI2017 Waterstand - - 10 10.256 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00067 184138 418816 - WBI2017 Waterstand - - 100 11.568 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00067 184138 418816 - WBI2017 Waterstand - - 300 11.949 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00067 184138 418816 - WBI2017 Waterstand - - 1000 12.261 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00067 184138 418816 - WBI2017 Waterstand - - 3000 12.512 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00067 184138 418816 - WBI2017 Waterstand - - 10000 12.793 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00067 184138 418816 - WBI2017 Waterstand - - 30000 13.112 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00068 184042 418855 - WBI2017 Waterstand - - 10 10.312 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00068 184042 418855 - WBI2017 Waterstand - - 100 11.566 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00068 184042 418855 - WBI2017 Waterstand - - 300 11.948 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00068 184042 418855 - WBI2017 Waterstand - - 1000 12.260 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00068 184042 418855 - WBI2017 Waterstand - - 3000 12.510 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00068 184042 418855 - WBI2017 Waterstand - - 10000 12.793 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00068 184042 418855 - WBI2017 Waterstand - - 30000 13.113 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00069 183955 418840 - WBI2017 Waterstand - - 10 10.311 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00069 183955 418840 - WBI2017 Waterstand - - 100 11.565 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00069 183955 418840 - WBI2017 Waterstand - - 300 11.948 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00069 183955 418840 - WBI2017 Waterstand - - 1000 12.260 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00069 183955 418840 - WBI2017 Waterstand - - 3000 12.510 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00069 183955 418840 - WBI2017 Waterstand - - 10000 12.793 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00069 183955 418840 - WBI2017 Waterstand - - 30000 13.114 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00070 183871 418797 - WBI2017 Waterstand - - 10 10.301 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00070 183871 418797 - WBI2017 Waterstand - - 100 11.551 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00070 183871 418797 - WBI2017 Waterstand - - 300 11.935 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00070 183871 418797 - WBI2017 Waterstand - - 1000 12.246 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00070 183871 418797 - WBI2017 Waterstand - - 3000 12.493 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00070 183871 418797 - WBI2017 Waterstand - - 10000 12.782 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00070 183871 418797 - WBI2017 Waterstand - - 30000 13.101 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00071 183783 418783 - WBI2017 Waterstand - - 10 10.287 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00071 183783 418783 - WBI2017 Waterstand - - 100 11.534 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00071 183783 418783 - WBI2017 Waterstand - - 300 11.920 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00071 183783 418783 - WBI2017 Waterstand - - 1000 12.228 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00071 183783 418783 - WBI2017 Waterstand - - 3000 12.476 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00071 183783 418783 - WBI2017 Waterstand - - 10000 12.765 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00071 183783 418783 - WBI2017 Waterstand - - 30000 13.081 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00072 183655 418733 - WBI2017 Waterstand - - 10 10.266 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00072 183655 418733 - WBI2017 Waterstand - - 100 11.512 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00072 183655 418733 - WBI2017 Waterstand - - 300 11.897 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00072 183655 418733 - WBI2017 Waterstand - - 1000 12.203 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00072 183655 418733 - WBI2017 Waterstand - - 3000 12.459 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00072 183655 418733 - WBI2017 Waterstand - - 10000 12.745 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00072 183655 418733 - WBI2017 Waterstand - - 30000 13.060 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00073 183567 418716 - WBI2017 Waterstand - - 10 10.257 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00073 183567 418716 - WBI2017 Waterstand - - 100 11.500 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00073 183567 418716 - WBI2017 Waterstand - - 300 11.882 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00073 183567 418716 - WBI2017 Waterstand - - 1000 12.189 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00073 183567 418716 - WBI2017 Waterstand - - 3000 12.446 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00073 183567 418716 - WBI2017 Waterstand - - 10000 12.726 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00073 183567 418716 - WBI2017 Waterstand - - 30000 13.043 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00074 183484 418674 - WBI2017 Waterstand - - 10 10.247 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00074 183484 418674 - WBI2017 Waterstand - - 100 11.491 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00074 183484 418674 - WBI2017 Waterstand - - 300 11.872 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00074 183484 418674 - WBI2017 Waterstand - - 1000 12.180 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00074 183484 418674 - WBI2017 Waterstand - - 3000 12.435 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00074 183484 418674 - WBI2017 Waterstand - - 10000 12.713 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00074 183484 418674 - WBI2017 Waterstand - - 30000 13.031 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00075 183398 418656 - WBI2017 Waterstand - - 10 10.154 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00075 183398 418656 - WBI2017 Waterstand - - 100 11.473 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00075 183398 418656 - WBI2017 Waterstand - - 300 11.853 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00075 183398 418656 - WBI2017 Waterstand - - 1000 12.165 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00075 183398 418656 - WBI2017 Waterstand - - 3000 12.414 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00075 183398 418656 - WBI2017 Waterstand - - 10000 12.694 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00075 183398 418656 - WBI2017 Waterstand - - 30000 13.012 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00076 183316 418637 - WBI2017 Waterstand - - 10 10.196 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00076 183316 418637 - WBI2017 Waterstand - - 100 11.459 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00076 183316 418637 - WBI2017 Waterstand - - 300 11.841 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00076 183316 418637 - WBI2017 Waterstand - - 1000 12.152 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00076 183316 418637 - WBI2017 Waterstand - - 3000 12.399 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00076 183316 418637 - WBI2017 Waterstand - - 10000 12.685 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00076 183316 418637 - WBI2017 Waterstand - - 30000 12.998 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00077 183194 418638 - WBI2017 Waterstand - - 10 10.200 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00077 183194 418638 - WBI2017 Waterstand - - 100 11.433 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00077 183194 418638 - WBI2017 Waterstand - - 300 11.815 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00077 183194 418638 - WBI2017 Waterstand - - 1000 12.126 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00077 183194 418638 - WBI2017 Waterstand - - 3000 12.374 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00077 183194 418638 - WBI2017 Waterstand - - 10000 12.661 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00077 183194 418638 - WBI2017 Waterstand - - 30000 12.973 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00078 183120 418623 - WBI2017 Waterstand - - 10 10.187 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00078 183120 418623 - WBI2017 Waterstand - - 100 11.424 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00078 183120 418623 - WBI2017 Waterstand - - 300 11.806 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00078 183120 418623 - WBI2017 Waterstand - - 1000 12.113 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00078 183120 418623 - WBI2017 Waterstand - - 3000 12.366 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00078 183120 418623 - WBI2017 Waterstand - - 10000 12.649 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00078 183120 418623 - WBI2017 Waterstand - - 30000 12.962 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00079 183009 418600 - WBI2017 Waterstand - - 10 10.180 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00079 183009 418600 - WBI2017 Waterstand - - 100 11.415 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00079 183009 418600 - WBI2017 Waterstand - - 300 11.796 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00079 183009 418600 - WBI2017 Waterstand - - 1000 12.103 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00079 183009 418600 - WBI2017 Waterstand - - 3000 12.359 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00079 183009 418600 - WBI2017 Waterstand - - 10000 12.642 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00079 183009 418600 - WBI2017 Waterstand - - 30000 12.956 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00080 182934 418585 - WBI2017 Waterstand - - 10 10.166 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00080 182934 418585 - WBI2017 Waterstand - - 100 11.403 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00080 182934 418585 - WBI2017 Waterstand - - 300 11.781 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00080 182934 418585 - WBI2017 Waterstand - - 1000 12.085 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00080 182934 418585 - WBI2017 Waterstand - - 3000 12.343 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00080 182934 418585 - WBI2017 Waterstand - - 10000 12.621 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00080 182934 418585 - WBI2017 Waterstand - - 30000 12.937 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00081 182828 418533 - WBI2017 Waterstand - - 10 10.146 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00081 182828 418533 - WBI2017 Waterstand - - 100 11.375 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00081 182828 418533 - WBI2017 Waterstand - - 300 11.753 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00081 182828 418533 - WBI2017 Waterstand - - 1000 12.064 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00081 182828 418533 - WBI2017 Waterstand - - 3000 12.312 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00081 182828 418533 - WBI2017 Waterstand - - 10000 12.593 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00081 182828 418533 - WBI2017 Waterstand - - 30000 12.911 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00082 182718 418512 - WBI2017 Waterstand - - 10 10.129 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00082 182718 418512 - WBI2017 Waterstand - - 100 11.345 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00082 182718 418512 - WBI2017 Waterstand - - 300 11.721 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00082 182718 418512 - WBI2017 Waterstand - - 1000 12.031 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00082 182718 418512 - WBI2017 Waterstand - - 3000 12.276 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00082 182718 418512 - WBI2017 Waterstand - - 10000 12.559 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00082 182718 418512 - WBI2017 Waterstand - - 30000 12.866 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00083 182644 418499 - WBI2017 Waterstand - - 10 10.123 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00083 182644 418499 - WBI2017 Waterstand - - 100 11.331 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00083 182644 418499 - WBI2017 Waterstand - - 300 11.710 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00083 182644 418499 - WBI2017 Waterstand - - 1000 12.016 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00083 182644 418499 - WBI2017 Waterstand - - 3000 12.264 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00083 182644 418499 - WBI2017 Waterstand - - 10000 12.545 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00083 182644 418499 - WBI2017 Waterstand - - 30000 12.856 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00084 182531 418482 - WBI2017 Waterstand - - 10 10.116 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00084 182531 418482 - WBI2017 Waterstand - - 100 11.321 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00084 182531 418482 - WBI2017 Waterstand - - 300 11.695 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00084 182531 418482 - WBI2017 Waterstand - - 1000 11.999 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00084 182531 418482 - WBI2017 Waterstand - - 3000 12.253 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00084 182531 418482 - WBI2017 Waterstand - - 10000 12.528 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00084 182531 418482 - WBI2017 Waterstand - - 30000 12.838 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00085 182455 418472 - WBI2017 Waterstand - - 10 10.105 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00085 182455 418472 - WBI2017 Waterstand - - 100 11.309 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00085 182455 418472 - WBI2017 Waterstand - - 300 11.680 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00085 182455 418472 - WBI2017 Waterstand - - 1000 11.984 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00085 182455 418472 - WBI2017 Waterstand - - 3000 12.236 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00085 182455 418472 - WBI2017 Waterstand - - 10000 12.509 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00085 182455 418472 - WBI2017 Waterstand - - 30000 12.821 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00086 182336 418534 - WBI2017 Waterstand - - 10 10.093 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00086 182336 418534 - WBI2017 Waterstand - - 100 11.298 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00086 182336 418534 - WBI2017 Waterstand - - 300 11.671 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00086 182336 418534 - WBI2017 Waterstand - - 1000 11.977 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00086 182336 418534 - WBI2017 Waterstand - - 3000 12.226 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00086 182336 418534 - WBI2017 Waterstand - - 10000 12.499 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00086 182336 418534 - WBI2017 Waterstand - - 30000 12.815 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00087 182261 418529 - WBI2017 Waterstand - - 10 10.078 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00087 182261 418529 - WBI2017 Waterstand - - 100 11.286 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00087 182261 418529 - WBI2017 Waterstand - - 300 11.660 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00087 182261 418529 - WBI2017 Waterstand - - 1000 11.970 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00087 182261 418529 - WBI2017 Waterstand - - 3000 12.218 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00087 182261 418529 - WBI2017 Waterstand - - 10000 12.497 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00087 182261 418529 - WBI2017 Waterstand - - 30000 12.808 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00088 182149 418483 - WBI2017 Waterstand - - 10 10.069 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00088 182149 418483 - WBI2017 Waterstand - - 100 11.277 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00088 182149 418483 - WBI2017 Waterstand - - 300 11.650 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00088 182149 418483 - WBI2017 Waterstand - - 1000 11.960 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00088 182149 418483 - WBI2017 Waterstand - - 3000 12.205 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00088 182149 418483 - WBI2017 Waterstand - - 10000 12.486 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00088 182149 418483 - WBI2017 Waterstand - - 30000 12.798 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00089 182072 418481 - WBI2017 Waterstand - - 10 10.069 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00089 182072 418481 - WBI2017 Waterstand - - 100 11.275 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00089 182072 418481 - WBI2017 Waterstand - - 300 11.648 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00089 182072 418481 - WBI2017 Waterstand - - 1000 11.956 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00089 182072 418481 - WBI2017 Waterstand - - 3000 12.202 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00089 182072 418481 - WBI2017 Waterstand - - 10000 12.484 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00089 182072 418481 - WBI2017 Waterstand - - 30000 12.793 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00090 181957 418480 - WBI2017 Waterstand - - 10 10.064 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00090 181957 418480 - WBI2017 Waterstand - - 100 11.269 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00090 181957 418480 - WBI2017 Waterstand - - 300 11.642 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00090 181957 418480 - WBI2017 Waterstand - - 1000 11.949 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00090 181957 418480 - WBI2017 Waterstand - - 3000 12.191 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00090 181957 418480 - WBI2017 Waterstand - - 10000 12.476 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00090 181957 418480 - WBI2017 Waterstand - - 30000 12.783 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00091 181881 418482 - WBI2017 Waterstand - - 10 10.059 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00091 181881 418482 - WBI2017 Waterstand - - 100 11.258 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00091 181881 418482 - WBI2017 Waterstand - - 300 11.634 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00091 181881 418482 - WBI2017 Waterstand - - 1000 11.937 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00091 181881 418482 - WBI2017 Waterstand - - 3000 12.180 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00091 181881 418482 - WBI2017 Waterstand - - 10000 12.463 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00091 181881 418482 - WBI2017 Waterstand - - 30000 12.769 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00092 181764 418487 - WBI2017 Waterstand - - 10 10.048 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00092 181764 418487 - WBI2017 Waterstand - - 100 11.243 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00092 181764 418487 - WBI2017 Waterstand - - 300 11.617 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00092 181764 418487 - WBI2017 Waterstand - - 1000 11.922 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00092 181764 418487 - WBI2017 Waterstand - - 3000 12.168 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00092 181764 418487 - WBI2017 Waterstand - - 10000 12.446 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00092 181764 418487 - WBI2017 Waterstand - - 30000 12.754 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00093 181689 418537 - WBI2017 Waterstand - - 10 10.041 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00093 181689 418537 - WBI2017 Waterstand - - 100 11.238 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00093 181689 418537 - WBI2017 Waterstand - - 300 11.611 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00093 181689 418537 - WBI2017 Waterstand - - 1000 11.916 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00093 181689 418537 - WBI2017 Waterstand - - 3000 12.162 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00093 181689 418537 - WBI2017 Waterstand - - 10000 12.440 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00093 181689 418537 - WBI2017 Waterstand - - 30000 12.747 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00094 181616 418594 - WBI2017 Waterstand - - 10 10.038 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00094 181616 418594 - WBI2017 Waterstand - - 100 11.233 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00094 181616 418594 - WBI2017 Waterstand - - 300 11.607 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00094 181616 418594 - WBI2017 Waterstand - - 1000 11.913 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00094 181616 418594 - WBI2017 Waterstand - - 3000 12.160 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00094 181616 418594 - WBI2017 Waterstand - - 10000 12.437 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00094 181616 418594 - WBI2017 Waterstand - - 30000 12.746 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00095 181502 418609 - WBI2017 Waterstand - - 10 10.035 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00095 181502 418609 - WBI2017 Waterstand - - 100 11.209 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00095 181502 418609 - WBI2017 Waterstand - - 300 11.575 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00095 181502 418609 - WBI2017 Waterstand - - 1000 11.877 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00095 181502 418609 - WBI2017 Waterstand - - 3000 12.124 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00095 181502 418609 - WBI2017 Waterstand - - 10000 12.395 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00095 181502 418609 - WBI2017 Waterstand - - 30000 12.705 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00096 181427 418621 - WBI2017 Waterstand - - 10 9.979 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00096 181427 418621 - WBI2017 Waterstand - - 100 11.170 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00096 181427 418621 - WBI2017 Waterstand - - 300 11.542 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00096 181427 418621 - WBI2017 Waterstand - - 1000 11.849 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00096 181427 418621 - WBI2017 Waterstand - - 3000 12.091 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00096 181427 418621 - WBI2017 Waterstand - - 10000 12.370 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00096 181427 418621 - WBI2017 Waterstand - - 30000 12.677 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00097 181362 418689 - WBI2017 Waterstand - - 10 9.933 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00097 181362 418689 - WBI2017 Waterstand - - 100 11.137 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00097 181362 418689 - WBI2017 Waterstand - - 300 11.513 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00097 181362 418689 - WBI2017 Waterstand - - 1000 11.821 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00097 181362 418689 - WBI2017 Waterstand - - 3000 12.069 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00097 181362 418689 - WBI2017 Waterstand - - 10000 12.350 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00097 181362 418689 - WBI2017 Waterstand - - 30000 12.658 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00098 181337 418755 - WBI2017 Waterstand - - 10 9.913 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00098 181337 418755 - WBI2017 Waterstand - - 100 11.129 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00098 181337 418755 - WBI2017 Waterstand - - 300 11.511 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00098 181337 418755 - WBI2017 Waterstand - - 1000 11.819 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00098 181337 418755 - WBI2017 Waterstand - - 3000 12.068 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00098 181337 418755 - WBI2017 Waterstand - - 10000 12.352 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00098 181337 418755 - WBI2017 Waterstand - - 30000 12.664 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00099 181280 418835 - WBI2017 Waterstand - - 10 9.913 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00099 181280 418835 - WBI2017 Waterstand - - 100 11.135 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00099 181280 418835 - WBI2017 Waterstand - - 300 11.519 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00099 181280 418835 - WBI2017 Waterstand - - 1000 11.826 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00099 181280 418835 - WBI2017 Waterstand - - 3000 12.075 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00099 181280 418835 - WBI2017 Waterstand - - 10000 12.361 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00099 181280 418835 - WBI2017 Waterstand - - 30000 12.673 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00100 181280 418981 - WBI2017 Waterstand - - 10 9.878 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00100 181280 418981 - WBI2017 Waterstand - - 100 11.122 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00100 181280 418981 - WBI2017 Waterstand - - 300 11.507 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00100 181280 418981 - WBI2017 Waterstand - - 1000 11.819 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00100 181280 418981 - WBI2017 Waterstand - - 3000 12.068 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00100 181280 418981 - WBI2017 Waterstand - - 10000 12.355 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00100 181280 418981 - WBI2017 Waterstand - - 30000 12.670 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00101 181264 419058 - WBI2017 Waterstand - - 10 9.876 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00101 181264 419058 - WBI2017 Waterstand - - 100 11.119 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00101 181264 419058 - WBI2017 Waterstand - - 300 11.507 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00101 181264 419058 - WBI2017 Waterstand - - 1000 11.819 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00101 181264 419058 - WBI2017 Waterstand - - 3000 12.068 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00101 181264 419058 - WBI2017 Waterstand - - 10000 12.355 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00101 181264 419058 - WBI2017 Waterstand - - 30000 12.671 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00102 181217 419145 - WBI2017 Waterstand - - 10 9.856 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00102 181217 419145 - WBI2017 Waterstand - - 100 11.113 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00102 181217 419145 - WBI2017 Waterstand - - 300 11.503 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00102 181217 419145 - WBI2017 Waterstand - - 1000 11.814 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00102 181217 419145 - WBI2017 Waterstand - - 3000 12.065 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00102 181217 419145 - WBI2017 Waterstand - - 10000 12.354 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00102 181217 419145 - WBI2017 Waterstand - - 30000 12.670 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00103 181172 419233 - WBI2017 Waterstand - - 10 9.845 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00103 181172 419233 - WBI2017 Waterstand - - 100 11.105 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00103 181172 419233 - WBI2017 Waterstand - - 300 11.499 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00103 181172 419233 - WBI2017 Waterstand - - 1000 11.812 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00103 181172 419233 - WBI2017 Waterstand - - 3000 12.064 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00103 181172 419233 - WBI2017 Waterstand - - 10000 12.353 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00103 181172 419233 - WBI2017 Waterstand - - 30000 12.667 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00104 181128 419322 - WBI2017 Waterstand - - 10 9.841 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00104 181128 419322 - WBI2017 Waterstand - - 100 11.105 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00104 181128 419322 - WBI2017 Waterstand - - 300 11.494 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00104 181128 419322 - WBI2017 Waterstand - - 1000 11.804 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00104 181128 419322 - WBI2017 Waterstand - - 3000 12.061 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00104 181128 419322 - WBI2017 Waterstand - - 10000 12.349 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00104 181128 419322 - WBI2017 Waterstand - - 30000 12.664 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00105 181085 419412 - WBI2017 Waterstand - - 10 9.836 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00105 181085 419412 - WBI2017 Waterstand - - 100 11.105 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00105 181085 419412 - WBI2017 Waterstand - - 300 11.494 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00105 181085 419412 - WBI2017 Waterstand - - 1000 11.804 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00105 181085 419412 - WBI2017 Waterstand - - 3000 12.061 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00105 181085 419412 - WBI2017 Waterstand - - 10000 12.349 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00105 181085 419412 - WBI2017 Waterstand - - 30000 12.664 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00106 180964 419376 - WBI2017 Waterstand - - 10 9.834 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00106 180964 419376 - WBI2017 Waterstand - - 100 11.095 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00106 180964 419376 - WBI2017 Waterstand - - 300 11.487 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00106 180964 419376 - WBI2017 Waterstand - - 1000 11.795 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00106 180964 419376 - WBI2017 Waterstand - - 3000 12.055 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00106 180964 419376 - WBI2017 Waterstand - - 10000 12.341 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00106 180964 419376 - WBI2017 Waterstand - - 30000 12.658 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00107 180865 419409 - WBI2017 Waterstand - - 10 9.824 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00107 180865 419409 - WBI2017 Waterstand - - 100 11.084 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00107 180865 419409 - WBI2017 Waterstand - - 300 11.474 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00107 180865 419409 - WBI2017 Waterstand - - 1000 11.786 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00107 180865 419409 - WBI2017 Waterstand - - 3000 12.044 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00107 180865 419409 - WBI2017 Waterstand - - 10000 12.330 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00107 180865 419409 - WBI2017 Waterstand - - 30000 12.648 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00108 180822 419498 - WBI2017 Waterstand - - 10 9.819 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00108 180822 419498 - WBI2017 Waterstand - - 100 11.072 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00108 180822 419498 - WBI2017 Waterstand - - 300 11.460 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00108 180822 419498 - WBI2017 Waterstand - - 1000 11.774 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00108 180822 419498 - WBI2017 Waterstand - - 3000 12.028 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00108 180822 419498 - WBI2017 Waterstand - - 10000 12.310 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00108 180822 419498 - WBI2017 Waterstand - - 30000 12.633 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00109 180747 419597 - WBI2017 Waterstand - - 10 9.810 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00109 180747 419597 - WBI2017 Waterstand - - 100 11.065 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00109 180747 419597 - WBI2017 Waterstand - - 300 11.450 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00109 180747 419597 - WBI2017 Waterstand - - 1000 11.765 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00109 180747 419597 - WBI2017 Waterstand - - 3000 12.018 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00109 180747 419597 - WBI2017 Waterstand - - 10000 12.300 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00109 180747 419597 - WBI2017 Waterstand - - 30000 12.624 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00110 180736 419674 - WBI2017 Waterstand - - 10 9.801 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00110 180736 419674 - WBI2017 Waterstand - - 100 11.066 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00110 180736 419674 - WBI2017 Waterstand - - 300 11.455 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00110 180736 419674 - WBI2017 Waterstand - - 1000 11.768 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00110 180736 419674 - WBI2017 Waterstand - - 3000 12.025 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00110 180736 419674 - WBI2017 Waterstand - - 10000 12.309 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00110 180736 419674 - WBI2017 Waterstand - - 30000 12.633 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00111 180808 419803 - WBI2017 Waterstand - - 10 9.798 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00111 180808 419803 - WBI2017 Waterstand - - 100 11.066 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00111 180808 419803 - WBI2017 Waterstand - - 300 11.455 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00111 180808 419803 - WBI2017 Waterstand - - 1000 11.768 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00111 180808 419803 - WBI2017 Waterstand - - 3000 12.025 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00111 180808 419803 - WBI2017 Waterstand - - 10000 12.309 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00111 180808 419803 - WBI2017 Waterstand - - 30000 12.633 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00112 180760 419888 - WBI2017 Waterstand - - 10 9.790 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00112 180760 419888 - WBI2017 Waterstand - - 100 11.066 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00112 180760 419888 - WBI2017 Waterstand - - 300 11.455 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00112 180760 419888 - WBI2017 Waterstand - - 1000 11.768 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00112 180760 419888 - WBI2017 Waterstand - - 3000 12.025 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00112 180760 419888 - WBI2017 Waterstand - - 10000 12.309 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00112 180760 419888 - WBI2017 Waterstand - - 30000 12.633 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00113 180662 419912 - WBI2017 Waterstand - - 10 9.787 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00113 180662 419912 - WBI2017 Waterstand - - 100 11.066 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00113 180662 419912 - WBI2017 Waterstand - - 300 11.455 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00113 180662 419912 - WBI2017 Waterstand - - 1000 11.768 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00113 180662 419912 - WBI2017 Waterstand - - 3000 12.025 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00113 180662 419912 - WBI2017 Waterstand - - 10000 12.309 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00113 180662 419912 - WBI2017 Waterstand - - 30000 12.633 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00114 180610 419992 - WBI2017 Waterstand - - 10 9.808 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00114 180610 419992 - WBI2017 Waterstand - - 100 11.066 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00114 180610 419992 - WBI2017 Waterstand - - 300 11.454 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00114 180610 419992 - WBI2017 Waterstand - - 1000 11.768 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00114 180610 419992 - WBI2017 Waterstand - - 3000 12.024 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00114 180610 419992 - WBI2017 Waterstand - - 10000 12.309 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00114 180610 419992 - WBI2017 Waterstand - - 30000 12.633 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00115 180496 419950 - WBI2017 Waterstand - - 10 9.801 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00115 180496 419950 - WBI2017 Waterstand - - 100 11.060 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00115 180496 419950 - WBI2017 Waterstand - - 300 11.451 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00115 180496 419950 - WBI2017 Waterstand - - 1000 11.764 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00115 180496 419950 - WBI2017 Waterstand - - 3000 12.019 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00115 180496 419950 - WBI2017 Waterstand - - 10000 12.300 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00115 180496 419950 - WBI2017 Waterstand - - 30000 12.625 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00116 180397 419972 - WBI2017 Waterstand - - 10 9.803 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00116 180397 419972 - WBI2017 Waterstand - - 100 11.054 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00116 180397 419972 - WBI2017 Waterstand - - 300 11.442 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00116 180397 419972 - WBI2017 Waterstand - - 1000 11.757 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00116 180397 419972 - WBI2017 Waterstand - - 3000 12.009 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00116 180397 419972 - WBI2017 Waterstand - - 10000 12.297 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00116 180397 419972 - WBI2017 Waterstand - - 30000 12.622 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00117 180298 419995 - WBI2017 Waterstand - - 10 9.783 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00117 180298 419995 - WBI2017 Waterstand - - 100 11.049 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00117 180298 419995 - WBI2017 Waterstand - - 300 11.436 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00117 180298 419995 - WBI2017 Waterstand - - 1000 11.752 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00117 180298 419995 - WBI2017 Waterstand - - 3000 12.001 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00117 180298 419995 - WBI2017 Waterstand - - 10000 12.290 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00117 180298 419995 - WBI2017 Waterstand - - 30000 12.612 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00118 180193 420023 - WBI2017 Waterstand - - 10 9.780 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00118 180193 420023 - WBI2017 Waterstand - - 100 11.043 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00118 180193 420023 - WBI2017 Waterstand - - 300 11.429 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00118 180193 420023 - WBI2017 Waterstand - - 1000 11.746 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00118 180193 420023 - WBI2017 Waterstand - - 3000 11.992 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00118 180193 420023 - WBI2017 Waterstand - - 10000 12.284 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00118 180193 420023 - WBI2017 Waterstand - - 30000 12.604 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00119 180082 420054 - WBI2017 Waterstand - - 10 9.785 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00119 180082 420054 - WBI2017 Waterstand - - 100 11.038 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00119 180082 420054 - WBI2017 Waterstand - - 300 11.427 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00119 180082 420054 - WBI2017 Waterstand - - 1000 11.738 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00119 180082 420054 - WBI2017 Waterstand - - 3000 11.988 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00119 180082 420054 - WBI2017 Waterstand - - 10000 12.279 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00119 180082 420054 - WBI2017 Waterstand - - 30000 12.597 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00120 180004 420078 - WBI2017 Waterstand - - 10 9.796 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00120 180004 420078 - WBI2017 Waterstand - - 100 11.035 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00120 180004 420078 - WBI2017 Waterstand - - 300 11.423 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00120 180004 420078 - WBI2017 Waterstand - - 1000 11.737 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00120 180004 420078 - WBI2017 Waterstand - - 3000 11.983 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00120 180004 420078 - WBI2017 Waterstand - - 10000 12.276 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00120 180004 420078 - WBI2017 Waterstand - - 30000 12.594 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00121 179897 420111 - WBI2017 Waterstand - - 10 9.780 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00121 179897 420111 - WBI2017 Waterstand - - 100 11.014 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00121 179897 420111 - WBI2017 Waterstand - - 300 11.405 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00121 179897 420111 - WBI2017 Waterstand - - 1000 11.716 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00121 179897 420111 - WBI2017 Waterstand - - 3000 11.971 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00121 179897 420111 - WBI2017 Waterstand - - 10000 12.261 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00121 179897 420111 - WBI2017 Waterstand - - 30000 12.580 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00122 179829 420134 - WBI2017 Waterstand - - 10 9.776 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00122 179829 420134 - WBI2017 Waterstand - - 100 11.008 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00122 179829 420134 - WBI2017 Waterstand - - 300 11.397 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00122 179829 420134 - WBI2017 Waterstand - - 1000 11.710 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00122 179829 420134 - WBI2017 Waterstand - - 3000 11.965 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00122 179829 420134 - WBI2017 Waterstand - - 10000 12.256 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00122 179829 420134 - WBI2017 Waterstand - - 30000 12.574 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00123 179709 420177 - WBI2017 Waterstand - - 10 9.758 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00123 179709 420177 - WBI2017 Waterstand - - 100 10.982 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00123 179709 420177 - WBI2017 Waterstand - - 300 11.378 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00123 179709 420177 - WBI2017 Waterstand - - 1000 11.706 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00123 179709 420177 - WBI2017 Waterstand - - 3000 11.964 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00123 179709 420177 - WBI2017 Waterstand - - 10000 12.260 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00123 179709 420177 - WBI2017 Waterstand - - 30000 12.580 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00124 179615 420159 - WBI2017 Waterstand - - 10 9.758 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00124 179615 420159 - WBI2017 Waterstand - - 100 10.976 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00124 179615 420159 - WBI2017 Waterstand - - 300 11.355 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00124 179615 420159 - WBI2017 Waterstand - - 1000 11.671 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00124 179615 420159 - WBI2017 Waterstand - - 3000 11.921 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00124 179615 420159 - WBI2017 Waterstand - - 10000 12.205 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00124 179615 420159 - WBI2017 Waterstand - - 30000 12.527 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00125 179529 420142 - WBI2017 Waterstand - - 10 9.735 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00125 179529 420142 - WBI2017 Waterstand - - 100 10.938 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00125 179529 420142 - WBI2017 Waterstand - - 300 11.322 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00125 179529 420142 - WBI2017 Waterstand - - 1000 11.635 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00125 179529 420142 - WBI2017 Waterstand - - 3000 11.882 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00125 179529 420142 - WBI2017 Waterstand - - 10000 12.171 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00125 179529 420142 - WBI2017 Waterstand - - 30000 12.482 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00126 179437 420135 - WBI2017 Waterstand - - 10 9.660 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00126 179437 420135 - WBI2017 Waterstand - - 100 10.893 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00126 179437 420135 - WBI2017 Waterstand - - 300 11.274 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00126 179437 420135 - WBI2017 Waterstand - - 1000 11.583 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00126 179437 420135 - WBI2017 Waterstand - - 3000 11.837 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00126 179437 420135 - WBI2017 Waterstand - - 10000 12.116 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00126 179437 420135 - WBI2017 Waterstand - - 30000 12.434 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00127 179361 420184 - WBI2017 Waterstand - - 10 9.630 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00127 179361 420184 - WBI2017 Waterstand - - 100 10.872 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00127 179361 420184 - WBI2017 Waterstand - - 300 11.260 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00127 179361 420184 - WBI2017 Waterstand - - 1000 11.572 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00127 179361 420184 - WBI2017 Waterstand - - 3000 11.829 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00127 179361 420184 - WBI2017 Waterstand - - 10000 12.103 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00127 179361 420184 - WBI2017 Waterstand - - 30000 12.416 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00128 179277 420249 - WBI2017 Waterstand - - 10 9.539 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00128 179277 420249 - WBI2017 Waterstand - - 100 10.818 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00128 179277 420249 - WBI2017 Waterstand - - 300 11.207 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00128 179277 420249 - WBI2017 Waterstand - - 1000 11.522 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00128 179277 420249 - WBI2017 Waterstand - - 3000 11.773 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00128 179277 420249 - WBI2017 Waterstand - - 10000 12.062 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00128 179277 420249 - WBI2017 Waterstand - - 30000 12.380 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00129 179237 420332 - WBI2017 Waterstand - - 10 9.539 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00129 179237 420332 - WBI2017 Waterstand - - 100 10.818 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00129 179237 420332 - WBI2017 Waterstand - - 300 11.210 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00129 179237 420332 - WBI2017 Waterstand - - 1000 11.522 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00129 179237 420332 - WBI2017 Waterstand - - 3000 11.774 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00129 179237 420332 - WBI2017 Waterstand - - 10000 12.064 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00129 179237 420332 - WBI2017 Waterstand - - 30000 12.381 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00130 179162 420389 - WBI2017 Waterstand - - 10 9.540 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00130 179162 420389 - WBI2017 Waterstand - - 100 10.818 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00130 179162 420389 - WBI2017 Waterstand - - 300 11.210 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00130 179162 420389 - WBI2017 Waterstand - - 1000 11.522 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00130 179162 420389 - WBI2017 Waterstand - - 3000 11.774 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00130 179162 420389 - WBI2017 Waterstand - - 10000 12.063 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00130 179162 420389 - WBI2017 Waterstand - - 30000 12.381 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00131 179078 420448 - WBI2017 Waterstand - - 10 9.540 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00131 179078 420448 - WBI2017 Waterstand - - 100 10.818 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00131 179078 420448 - WBI2017 Waterstand - - 300 11.214 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00131 179078 420448 - WBI2017 Waterstand - - 1000 11.526 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00131 179078 420448 - WBI2017 Waterstand - - 3000 11.778 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00131 179078 420448 - WBI2017 Waterstand - - 10000 12.067 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00131 179078 420448 - WBI2017 Waterstand - - 30000 12.383 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00132 178991 420502 - WBI2017 Waterstand - - 10 9.475 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00132 178991 420502 - WBI2017 Waterstand - - 100 10.818 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00132 178991 420502 - WBI2017 Waterstand - - 300 11.212 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00132 178991 420502 - WBI2017 Waterstand - - 1000 11.525 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00132 178991 420502 - WBI2017 Waterstand - - 3000 11.778 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00132 178991 420502 - WBI2017 Waterstand - - 10000 12.068 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00132 178991 420502 - WBI2017 Waterstand - - 30000 12.385 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00133 178894 420522 - WBI2017 Waterstand - - 10 9.539 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00133 178894 420522 - WBI2017 Waterstand - - 100 10.807 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00133 178894 420522 - WBI2017 Waterstand - - 300 11.202 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00133 178894 420522 - WBI2017 Waterstand - - 1000 11.516 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00133 178894 420522 - WBI2017 Waterstand - - 3000 11.768 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00133 178894 420522 - WBI2017 Waterstand - - 10000 12.057 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00133 178894 420522 - WBI2017 Waterstand - - 30000 12.374 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00134 178777 420571 - WBI2017 Waterstand - - 10 9.529 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00134 178777 420571 - WBI2017 Waterstand - - 100 10.793 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00134 178777 420571 - WBI2017 Waterstand - - 300 11.180 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00134 178777 420571 - WBI2017 Waterstand - - 1000 11.492 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00134 178777 420571 - WBI2017 Waterstand - - 3000 11.748 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00134 178777 420571 - WBI2017 Waterstand - - 10000 12.035 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00134 178777 420571 - WBI2017 Waterstand - - 30000 12.353 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00135 178702 420598 - WBI2017 Waterstand - - 10 9.512 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00135 178702 420598 - WBI2017 Waterstand - - 100 10.771 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00135 178702 420598 - WBI2017 Waterstand - - 300 11.157 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00135 178702 420598 - WBI2017 Waterstand - - 1000 11.468 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00135 178702 420598 - WBI2017 Waterstand - - 3000 11.724 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00135 178702 420598 - WBI2017 Waterstand - - 10000 12.001 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00135 178702 420598 - WBI2017 Waterstand - - 30000 12.321 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00136 178600 420654 - WBI2017 Waterstand - - 10 9.468 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00136 178600 420654 - WBI2017 Waterstand - - 100 10.729 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00136 178600 420654 - WBI2017 Waterstand - - 300 11.115 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00136 178600 420654 - WBI2017 Waterstand - - 1000 11.429 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00136 178600 420654 - WBI2017 Waterstand - - 3000 11.675 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00136 178600 420654 - WBI2017 Waterstand - - 10000 11.963 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00136 178600 420654 - WBI2017 Waterstand - - 30000 12.278 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00137 178495 420688 - WBI2017 Waterstand - - 10 9.455 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00137 178495 420688 - WBI2017 Waterstand - - 100 10.712 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00137 178495 420688 - WBI2017 Waterstand - - 300 11.099 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00137 178495 420688 - WBI2017 Waterstand - - 1000 11.412 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00137 178495 420688 - WBI2017 Waterstand - - 3000 11.664 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00137 178495 420688 - WBI2017 Waterstand - - 10000 11.948 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00137 178495 420688 - WBI2017 Waterstand - - 30000 12.262 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00138 178428 420709 - WBI2017 Waterstand - - 10 9.444 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00138 178428 420709 - WBI2017 Waterstand - - 100 10.702 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00138 178428 420709 - WBI2017 Waterstand - - 300 11.089 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00138 178428 420709 - WBI2017 Waterstand - - 1000 11.400 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00138 178428 420709 - WBI2017 Waterstand - - 3000 11.654 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00138 178428 420709 - WBI2017 Waterstand - - 10000 11.940 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00138 178428 420709 - WBI2017 Waterstand - - 30000 12.253 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00139 178327 420740 - WBI2017 Waterstand - - 10 9.442 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00139 178327 420740 - WBI2017 Waterstand - - 100 10.701 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00139 178327 420740 - WBI2017 Waterstand - - 300 11.089 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00139 178327 420740 - WBI2017 Waterstand - - 1000 11.397 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00139 178327 420740 - WBI2017 Waterstand - - 3000 11.654 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00139 178327 420740 - WBI2017 Waterstand - - 10000 11.940 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00139 178327 420740 - WBI2017 Waterstand - - 30000 12.253 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00140 178223 420771 - WBI2017 Waterstand - - 10 9.425 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00140 178223 420771 - WBI2017 Waterstand - - 100 10.685 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00140 178223 420771 - WBI2017 Waterstand - - 300 11.072 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00140 178223 420771 - WBI2017 Waterstand - - 1000 11.381 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00140 178223 420771 - WBI2017 Waterstand - - 3000 11.638 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00140 178223 420771 - WBI2017 Waterstand - - 10000 11.919 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00140 178223 420771 - WBI2017 Waterstand - - 30000 12.235 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00141 178113 420782 - WBI2017 Waterstand - - 10 9.406 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00141 178113 420782 - WBI2017 Waterstand - - 100 10.667 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00141 178113 420782 - WBI2017 Waterstand - - 300 11.056 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00141 178113 420782 - WBI2017 Waterstand - - 1000 11.367 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00141 178113 420782 - WBI2017 Waterstand - - 3000 11.620 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00141 178113 420782 - WBI2017 Waterstand - - 10000 11.901 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00141 178113 420782 - WBI2017 Waterstand - - 30000 12.218 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00142 178038 420782 - WBI2017 Waterstand - - 10 9.406 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00142 178038 420782 - WBI2017 Waterstand - - 100 10.665 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00142 178038 420782 - WBI2017 Waterstand - - 300 11.050 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00142 178038 420782 - WBI2017 Waterstand - - 1000 11.365 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00142 178038 420782 - WBI2017 Waterstand - - 3000 11.617 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00142 178038 420782 - WBI2017 Waterstand - - 10000 11.898 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00142 178038 420782 - WBI2017 Waterstand - - 30000 12.215 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00143 177930 420810 - WBI2017 Waterstand - - 10 9.390 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00143 177930 420810 - WBI2017 Waterstand - - 100 10.654 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00143 177930 420810 - WBI2017 Waterstand - - 300 11.042 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00143 177930 420810 - WBI2017 Waterstand - - 1000 11.355 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00143 177930 420810 - WBI2017 Waterstand - - 3000 11.607 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00143 177930 420810 - WBI2017 Waterstand - - 10000 11.891 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00143 177930 420810 - WBI2017 Waterstand - - 30000 12.208 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00144 177823 420841 - WBI2017 Waterstand - - 10 9.327 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00144 177823 420841 - WBI2017 Waterstand - - 100 10.642 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00144 177823 420841 - WBI2017 Waterstand - - 300 11.029 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00144 177823 420841 - WBI2017 Waterstand - - 1000 11.344 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00144 177823 420841 - WBI2017 Waterstand - - 3000 11.590 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00144 177823 420841 - WBI2017 Waterstand - - 10000 11.881 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00144 177823 420841 - WBI2017 Waterstand - - 30000 12.197 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00145 177721 420877 - WBI2017 Waterstand - - 10 9.368 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00145 177721 420877 - WBI2017 Waterstand - - 100 10.631 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00145 177721 420877 - WBI2017 Waterstand - - 300 11.023 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00145 177721 420877 - WBI2017 Waterstand - - 1000 11.338 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00145 177721 420877 - WBI2017 Waterstand - - 3000 11.585 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00145 177721 420877 - WBI2017 Waterstand - - 10000 11.878 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00145 177721 420877 - WBI2017 Waterstand - - 30000 12.194 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00146 177648 420877 - WBI2017 Waterstand - - 10 9.357 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00146 177648 420877 - WBI2017 Waterstand - - 100 10.618 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00146 177648 420877 - WBI2017 Waterstand - - 300 11.014 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00146 177648 420877 - WBI2017 Waterstand - - 1000 11.326 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00146 177648 420877 - WBI2017 Waterstand - - 3000 11.578 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00146 177648 420877 - WBI2017 Waterstand - - 10000 11.869 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00146 177648 420877 - WBI2017 Waterstand - - 30000 12.185 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00147 177556 420833 - WBI2017 Waterstand - - 10 9.312 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00147 177556 420833 - WBI2017 Waterstand - - 100 10.582 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00147 177556 420833 - WBI2017 Waterstand - - 300 10.967 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00147 177556 420833 - WBI2017 Waterstand - - 1000 11.281 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00147 177556 420833 - WBI2017 Waterstand - - 3000 11.536 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00147 177556 420833 - WBI2017 Waterstand - - 10000 11.818 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00147 177556 420833 - WBI2017 Waterstand - - 30000 12.135 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00148 177444 420830 - WBI2017 Waterstand - - 10 9.249 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00148 177444 420830 - WBI2017 Waterstand - - 100 10.564 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00148 177444 420830 - WBI2017 Waterstand - - 300 10.950 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00148 177444 420830 - WBI2017 Waterstand - - 1000 11.263 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00148 177444 420830 - WBI2017 Waterstand - - 3000 11.517 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00148 177444 420830 - WBI2017 Waterstand - - 10000 11.798 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00148 177444 420830 - WBI2017 Waterstand - - 30000 12.115 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00149 177341 420854 - WBI2017 Waterstand - - 10 9.287 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00149 177341 420854 - WBI2017 Waterstand - - 100 10.555 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00149 177341 420854 - WBI2017 Waterstand - - 300 10.942 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00149 177341 420854 - WBI2017 Waterstand - - 1000 11.255 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00149 177341 420854 - WBI2017 Waterstand - - 3000 11.507 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00149 177341 420854 - WBI2017 Waterstand - - 10000 11.790 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00149 177341 420854 - WBI2017 Waterstand - - 30000 12.108 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00150 177242 420886 - WBI2017 Waterstand - - 10 9.288 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00150 177242 420886 - WBI2017 Waterstand - - 100 10.544 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00150 177242 420886 - WBI2017 Waterstand - - 300 10.934 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00150 177242 420886 - WBI2017 Waterstand - - 1000 11.246 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00150 177242 420886 - WBI2017 Waterstand - - 3000 11.494 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00150 177242 420886 - WBI2017 Waterstand - - 10000 11.780 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00150 177242 420886 - WBI2017 Waterstand - - 30000 12.094 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00151 177146 420928 - WBI2017 Waterstand - - 10 9.280 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00151 177146 420928 - WBI2017 Waterstand - - 100 10.530 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00151 177146 420928 - WBI2017 Waterstand - - 300 10.920 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00151 177146 420928 - WBI2017 Waterstand - - 1000 11.231 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00151 177146 420928 - WBI2017 Waterstand - - 3000 11.481 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00151 177146 420928 - WBI2017 Waterstand - - 10000 11.769 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00151 177146 420928 - WBI2017 Waterstand - - 30000 12.082 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00152 177078 420956 - WBI2017 Waterstand - - 10 9.269 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00152 177078 420956 - WBI2017 Waterstand - - 100 10.523 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00152 177078 420956 - WBI2017 Waterstand - - 300 10.912 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00152 177078 420956 - WBI2017 Waterstand - - 1000 11.222 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00152 177078 420956 - WBI2017 Waterstand - - 3000 11.474 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00152 177078 420956 - WBI2017 Waterstand - - 10000 11.760 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00152 177078 420956 - WBI2017 Waterstand - - 30000 12.073 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00153 176998 421033 - WBI2017 Waterstand - - 10 9.260 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00153 176998 421033 - WBI2017 Waterstand - - 100 10.513 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00153 176998 421033 - WBI2017 Waterstand - - 300 10.903 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00153 176998 421033 - WBI2017 Waterstand - - 1000 11.213 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00153 176998 421033 - WBI2017 Waterstand - - 3000 11.466 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00153 176998 421033 - WBI2017 Waterstand - - 10000 11.752 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00153 176998 421033 - WBI2017 Waterstand - - 30000 12.065 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00154 176929 421077 - WBI2017 Waterstand - - 10 9.256 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00154 176929 421077 - WBI2017 Waterstand - - 100 10.508 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00154 176929 421077 - WBI2017 Waterstand - - 300 10.895 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00154 176929 421077 - WBI2017 Waterstand - - 1000 11.203 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00154 176929 421077 - WBI2017 Waterstand - - 3000 11.459 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00154 176929 421077 - WBI2017 Waterstand - - 10000 11.744 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00154 176929 421077 - WBI2017 Waterstand - - 30000 12.056 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00155 176853 421177 - WBI2017 Waterstand - - 10 9.247 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00155 176853 421177 - WBI2017 Waterstand - - 100 10.501 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00155 176853 421177 - WBI2017 Waterstand - - 300 10.889 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00155 176853 421177 - WBI2017 Waterstand - - 1000 11.197 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00155 176853 421177 - WBI2017 Waterstand - - 3000 11.454 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00155 176853 421177 - WBI2017 Waterstand - - 10000 11.737 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00155 176853 421177 - WBI2017 Waterstand - - 30000 12.053 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00156 176787 421236 - WBI2017 Waterstand - - 10 9.242 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00156 176787 421236 - WBI2017 Waterstand - - 100 10.491 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00156 176787 421236 - WBI2017 Waterstand - - 300 10.880 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00156 176787 421236 - WBI2017 Waterstand - - 1000 11.187 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00156 176787 421236 - WBI2017 Waterstand - - 3000 11.446 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00156 176787 421236 - WBI2017 Waterstand - - 10000 11.726 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00156 176787 421236 - WBI2017 Waterstand - - 30000 12.042 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00157 176742 421310 - WBI2017 Waterstand - - 10 9.234 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00157 176742 421310 - WBI2017 Waterstand - - 100 10.491 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00157 176742 421310 - WBI2017 Waterstand - - 300 10.874 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00157 176742 421310 - WBI2017 Waterstand - - 1000 11.186 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00157 176742 421310 - WBI2017 Waterstand - - 3000 11.442 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00157 176742 421310 - WBI2017 Waterstand - - 10000 11.726 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00157 176742 421310 - WBI2017 Waterstand - - 30000 12.042 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00158 176680 421424 - WBI2017 Waterstand - - 10 9.225 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00158 176680 421424 - WBI2017 Waterstand - - 100 10.478 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00158 176680 421424 - WBI2017 Waterstand - - 300 10.865 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00158 176680 421424 - WBI2017 Waterstand - - 1000 11.179 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00158 176680 421424 - WBI2017 Waterstand - - 3000 11.433 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00158 176680 421424 - WBI2017 Waterstand - - 10000 11.713 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00158 176680 421424 - WBI2017 Waterstand - - 30000 12.028 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00159 176641 421501 - WBI2017 Waterstand - - 10 9.215 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00159 176641 421501 - WBI2017 Waterstand - - 100 10.478 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00159 176641 421501 - WBI2017 Waterstand - - 300 10.865 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00159 176641 421501 - WBI2017 Waterstand - - 1000 11.177 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00159 176641 421501 - WBI2017 Waterstand - - 3000 11.433 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00159 176641 421501 - WBI2017 Waterstand - - 10000 11.710 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00159 176641 421501 - WBI2017 Waterstand - - 30000 12.028 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00160 176623 421589 - WBI2017 Waterstand - - 10 9.212 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00160 176623 421589 - WBI2017 Waterstand - - 100 10.472 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00160 176623 421589 - WBI2017 Waterstand - - 300 10.857 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00160 176623 421589 - WBI2017 Waterstand - - 1000 11.170 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00160 176623 421589 - WBI2017 Waterstand - - 3000 11.424 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00160 176623 421589 - WBI2017 Waterstand - - 10000 11.701 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00160 176623 421589 - WBI2017 Waterstand - - 30000 12.021 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00161 176564 421706 - WBI2017 Waterstand - - 10 9.203 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00161 176564 421706 - WBI2017 Waterstand - - 100 10.455 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00161 176564 421706 - WBI2017 Waterstand - - 300 10.843 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00161 176564 421706 - WBI2017 Waterstand - - 1000 11.158 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00161 176564 421706 - WBI2017 Waterstand - - 3000 11.407 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00161 176564 421706 - WBI2017 Waterstand - - 10000 11.691 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00161 176564 421706 - WBI2017 Waterstand - - 30000 12.008 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00162 176570 421811 - WBI2017 Waterstand - - 10 9.190 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00162 176570 421811 - WBI2017 Waterstand - - 100 10.443 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00162 176570 421811 - WBI2017 Waterstand - - 300 10.829 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00162 176570 421811 - WBI2017 Waterstand - - 1000 11.143 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00162 176570 421811 - WBI2017 Waterstand - - 3000 11.389 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00162 176570 421811 - WBI2017 Waterstand - - 10000 11.677 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00162 176570 421811 - WBI2017 Waterstand - - 30000 11.988 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00163 176606 421881 - WBI2017 Waterstand - - 10 9.174 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00163 176606 421881 - WBI2017 Waterstand - - 100 10.431 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00163 176606 421881 - WBI2017 Waterstand - - 300 10.822 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00163 176606 421881 - WBI2017 Waterstand - - 1000 11.134 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00163 176606 421881 - WBI2017 Waterstand - - 3000 11.381 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00163 176606 421881 - WBI2017 Waterstand - - 10000 11.671 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00163 176606 421881 - WBI2017 Waterstand - - 30000 11.982 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00164 176652 421956 - WBI2017 Waterstand - - 10 9.170 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00164 176652 421956 - WBI2017 Waterstand - - 100 10.431 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00164 176652 421956 - WBI2017 Waterstand - - 300 10.823 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00164 176652 421956 - WBI2017 Waterstand - - 1000 11.140 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00164 176652 421956 - WBI2017 Waterstand - - 3000 11.385 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00164 176652 421956 - WBI2017 Waterstand - - 10000 11.676 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00164 176652 421956 - WBI2017 Waterstand - - 30000 11.992 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00165 176689 422077 - WBI2017 Waterstand - - 10 9.169 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00165 176689 422077 - WBI2017 Waterstand - - 100 10.431 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00165 176689 422077 - WBI2017 Waterstand - - 300 10.824 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00165 176689 422077 - WBI2017 Waterstand - - 1000 11.140 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00165 176689 422077 - WBI2017 Waterstand - - 3000 11.386 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00165 176689 422077 - WBI2017 Waterstand - - 10000 11.677 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00165 176689 422077 - WBI2017 Waterstand - - 30000 11.992 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00166 176647 422161 - WBI2017 Waterstand - - 10 9.058 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00166 176647 422161 - WBI2017 Waterstand - - 100 10.420 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00166 176647 422161 - WBI2017 Waterstand - - 300 10.819 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00166 176647 422161 - WBI2017 Waterstand - - 1000 11.134 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00166 176647 422161 - WBI2017 Waterstand - - 3000 11.383 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00166 176647 422161 - WBI2017 Waterstand - - 10000 11.675 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00166 176647 422161 - WBI2017 Waterstand - - 30000 11.990 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00167 176646 422272 - WBI2017 Waterstand - - 10 9.015 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00167 176646 422272 - WBI2017 Waterstand - - 100 10.420 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00167 176646 422272 - WBI2017 Waterstand - - 300 10.819 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00167 176646 422272 - WBI2017 Waterstand - - 1000 11.134 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00167 176646 422272 - WBI2017 Waterstand - - 3000 11.383 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00167 176646 422272 - WBI2017 Waterstand - - 10000 11.675 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00167 176646 422272 - WBI2017 Waterstand - - 30000 11.990 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00168 176715 422366 - WBI2017 Waterstand - - 10 9.057 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00168 176715 422366 - WBI2017 Waterstand - - 100 10.420 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00168 176715 422366 - WBI2017 Waterstand - - 300 10.819 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00168 176715 422366 - WBI2017 Waterstand - - 1000 11.134 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00168 176715 422366 - WBI2017 Waterstand - - 3000 11.383 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00168 176715 422366 - WBI2017 Waterstand - - 10000 11.675 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00168 176715 422366 - WBI2017 Waterstand - - 30000 11.990 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00169 176737 422437 - WBI2017 Waterstand - - 10 9.111 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00169 176737 422437 - WBI2017 Waterstand - - 100 10.418 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00169 176737 422437 - WBI2017 Waterstand - - 300 10.814 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00169 176737 422437 - WBI2017 Waterstand - - 1000 11.129 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00169 176737 422437 - WBI2017 Waterstand - - 3000 11.380 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00169 176737 422437 - WBI2017 Waterstand - - 10000 11.672 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00169 176737 422437 - WBI2017 Waterstand - - 30000 11.987 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00170 176733 422566 - WBI2017 Waterstand - - 10 9.107 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00170 176733 422566 - WBI2017 Waterstand - - 100 10.397 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00170 176733 422566 - WBI2017 Waterstand - - 300 10.801 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00170 176733 422566 - WBI2017 Waterstand - - 1000 11.118 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00170 176733 422566 - WBI2017 Waterstand - - 3000 11.372 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00170 176733 422566 - WBI2017 Waterstand - - 10000 11.663 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00170 176733 422566 - WBI2017 Waterstand - - 30000 11.982 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00171 176753 422644 - WBI2017 Waterstand - - 10 9.107 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00171 176753 422644 - WBI2017 Waterstand - - 100 10.396 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00171 176753 422644 - WBI2017 Waterstand - - 300 10.799 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00171 176753 422644 - WBI2017 Waterstand - - 1000 11.113 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00171 176753 422644 - WBI2017 Waterstand - - 3000 11.369 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00171 176753 422644 - WBI2017 Waterstand - - 10000 11.661 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00171 176753 422644 - WBI2017 Waterstand - - 30000 11.980 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00172 176696 422765 - WBI2017 Waterstand - - 10 9.107 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00172 176696 422765 - WBI2017 Waterstand - - 100 10.394 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00172 176696 422765 - WBI2017 Waterstand - - 300 10.781 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00172 176696 422765 - WBI2017 Waterstand - - 1000 11.098 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00172 176696 422765 - WBI2017 Waterstand - - 3000 11.355 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00172 176696 422765 - WBI2017 Waterstand - - 10000 11.648 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00172 176696 422765 - WBI2017 Waterstand - - 30000 11.967 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00173 176662 422826 - WBI2017 Waterstand - - 10 9.107 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00173 176662 422826 - WBI2017 Waterstand - - 100 10.394 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00173 176662 422826 - WBI2017 Waterstand - - 300 10.782 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00173 176662 422826 - WBI2017 Waterstand - - 1000 11.096 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00173 176662 422826 - WBI2017 Waterstand - - 3000 11.355 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00173 176662 422826 - WBI2017 Waterstand - - 10000 11.647 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00173 176662 422826 - WBI2017 Waterstand - - 30000 11.967 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00174 176675 422921 - WBI2017 Waterstand - - 10 9.122 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00174 176675 422921 - WBI2017 Waterstand - - 100 10.393 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00174 176675 422921 - WBI2017 Waterstand - - 300 10.782 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00174 176675 422921 - WBI2017 Waterstand - - 1000 11.093 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00174 176675 422921 - WBI2017 Waterstand - - 3000 11.353 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00174 176675 422921 - WBI2017 Waterstand - - 10000 11.642 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00174 176675 422921 - WBI2017 Waterstand - - 30000 11.964 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00175 176678 423017 - WBI2017 Waterstand - - 10 9.122 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00175 176678 423017 - WBI2017 Waterstand - - 100 10.393 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00175 176678 423017 - WBI2017 Waterstand - - 300 10.780 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00175 176678 423017 - WBI2017 Waterstand - - 1000 11.090 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00175 176678 423017 - WBI2017 Waterstand - - 3000 11.351 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00175 176678 423017 - WBI2017 Waterstand - - 10000 11.640 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00175 176678 423017 - WBI2017 Waterstand - - 30000 11.963 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00176 176529 423106 - WBI2017 Waterstand - - 10 9.122 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00176 176529 423106 - WBI2017 Waterstand - - 100 10.393 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00176 176529 423106 - WBI2017 Waterstand - - 300 10.780 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00176 176529 423106 - WBI2017 Waterstand - - 1000 11.088 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00176 176529 423106 - WBI2017 Waterstand - - 3000 11.350 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00176 176529 423106 - WBI2017 Waterstand - - 10000 11.639 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00176 176529 423106 - WBI2017 Waterstand - - 30000 11.962 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00177 176470 423160 - WBI2017 Waterstand - - 10 9.122 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00177 176470 423160 - WBI2017 Waterstand - - 100 10.393 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00177 176470 423160 - WBI2017 Waterstand - - 300 10.779 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00177 176470 423160 - WBI2017 Waterstand - - 1000 11.088 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00177 176470 423160 - WBI2017 Waterstand - - 3000 11.350 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00177 176470 423160 - WBI2017 Waterstand - - 10000 11.638 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00177 176470 423160 - WBI2017 Waterstand - - 30000 11.959 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00178 176443 423260 - WBI2017 Waterstand - - 10 9.122 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00178 176443 423260 - WBI2017 Waterstand - - 100 10.393 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00178 176443 423260 - WBI2017 Waterstand - - 300 10.779 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00178 176443 423260 - WBI2017 Waterstand - - 1000 11.088 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00178 176443 423260 - WBI2017 Waterstand - - 3000 11.350 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00178 176443 423260 - WBI2017 Waterstand - - 10000 11.638 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00178 176443 423260 - WBI2017 Waterstand - - 30000 11.959 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00179 176371 423306 - WBI2017 Waterstand - - 10 9.122 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00179 176371 423306 - WBI2017 Waterstand - - 100 10.393 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00179 176371 423306 - WBI2017 Waterstand - - 300 10.779 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00179 176371 423306 - WBI2017 Waterstand - - 1000 11.088 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00179 176371 423306 - WBI2017 Waterstand - - 3000 11.350 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00179 176371 423306 - WBI2017 Waterstand - - 10000 11.639 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00179 176371 423306 - WBI2017 Waterstand - - 30000 11.959 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00180 176295 423343 - WBI2017 Waterstand - - 10 9.122 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00180 176295 423343 - WBI2017 Waterstand - - 100 10.393 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00180 176295 423343 - WBI2017 Waterstand - - 300 10.780 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00180 176295 423343 - WBI2017 Waterstand - - 1000 11.088 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00180 176295 423343 - WBI2017 Waterstand - - 3000 11.350 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00180 176295 423343 - WBI2017 Waterstand - - 10000 11.639 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00180 176295 423343 - WBI2017 Waterstand - - 30000 11.959 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00181 176127 423343 - WBI2017 Waterstand - - 10 9.122 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00181 176127 423343 - WBI2017 Waterstand - - 100 10.393 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00181 176127 423343 - WBI2017 Waterstand - - 300 10.780 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00181 176127 423343 - WBI2017 Waterstand - - 1000 11.088 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00181 176127 423343 - WBI2017 Waterstand - - 3000 11.350 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00181 176127 423343 - WBI2017 Waterstand - - 10000 11.639 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00181 176127 423343 - WBI2017 Waterstand - - 30000 11.959 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00182 176056 423361 - WBI2017 Waterstand - - 10 9.122 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00182 176056 423361 - WBI2017 Waterstand - - 100 10.393 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00182 176056 423361 - WBI2017 Waterstand - - 300 10.780 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00182 176056 423361 - WBI2017 Waterstand - - 1000 11.088 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00182 176056 423361 - WBI2017 Waterstand - - 3000 11.350 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00182 176056 423361 - WBI2017 Waterstand - - 10000 11.639 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00182 176056 423361 - WBI2017 Waterstand - - 30000 11.959 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00183 175974 423324 - WBI2017 Waterstand - - 10 2.284 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00183 175974 423324 - WBI2017 Waterstand - - 100 10.157 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00183 175974 423324 - WBI2017 Waterstand - - 300 10.763 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00183 175974 423324 - WBI2017 Waterstand - - 1000 11.090 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00183 175974 423324 - WBI2017 Waterstand - - 3000 11.350 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00183 175974 423324 - WBI2017 Waterstand - - 10000 11.639 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00183 175974 423324 - WBI2017 Waterstand - - 30000 11.959 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00184 175896 423287 - WBI2017 Waterstand - - 10 9.106 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00184 175896 423287 - WBI2017 Waterstand - - 100 10.390 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00184 175896 423287 - WBI2017 Waterstand - - 300 10.780 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00184 175896 423287 - WBI2017 Waterstand - - 1000 11.088 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00184 175896 423287 - WBI2017 Waterstand - - 3000 11.350 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00184 175896 423287 - WBI2017 Waterstand - - 10000 11.639 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00184 175896 423287 - WBI2017 Waterstand - - 30000 11.959 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00185 175760 423267 - WBI2017 Waterstand - - 10 9.106 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00185 175760 423267 - WBI2017 Waterstand - - 100 10.390 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00185 175760 423267 - WBI2017 Waterstand - - 300 10.780 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00185 175760 423267 - WBI2017 Waterstand - - 1000 11.088 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00185 175760 423267 - WBI2017 Waterstand - - 3000 11.350 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00185 175760 423267 - WBI2017 Waterstand - - 10000 11.638 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00185 175760 423267 - WBI2017 Waterstand - - 30000 11.959 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00186 175690 423232 - WBI2017 Waterstand - - 10 9.106 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00186 175690 423232 - WBI2017 Waterstand - - 100 10.387 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00186 175690 423232 - WBI2017 Waterstand - - 300 10.779 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00186 175690 423232 - WBI2017 Waterstand - - 1000 11.088 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00186 175690 423232 - WBI2017 Waterstand - - 3000 11.349 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00186 175690 423232 - WBI2017 Waterstand - - 10000 11.636 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00186 175690 423232 - WBI2017 Waterstand - - 30000 11.955 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00187 175578 423259 - WBI2017 Waterstand - - 10 9.106 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00187 175578 423259 - WBI2017 Waterstand - - 100 10.384 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00187 175578 423259 - WBI2017 Waterstand - - 300 10.777 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00187 175578 423259 - WBI2017 Waterstand - - 1000 11.087 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00187 175578 423259 - WBI2017 Waterstand - - 3000 11.345 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00187 175578 423259 - WBI2017 Waterstand - - 10000 11.632 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00187 175578 423259 - WBI2017 Waterstand - - 30000 11.954 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00188 175469 423279 - WBI2017 Waterstand - - 10 9.106 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00188 175469 423279 - WBI2017 Waterstand - - 100 10.382 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00188 175469 423279 - WBI2017 Waterstand - - 300 10.774 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00188 175469 423279 - WBI2017 Waterstand - - 1000 11.087 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00188 175469 423279 - WBI2017 Waterstand - - 3000 11.344 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00188 175469 423279 - WBI2017 Waterstand - - 10000 11.630 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00188 175469 423279 - WBI2017 Waterstand - - 30000 11.953 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00189 175400 423203 - WBI2017 Waterstand - - 10 9.101 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00189 175400 423203 - WBI2017 Waterstand - - 100 10.381 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00189 175400 423203 - WBI2017 Waterstand - - 300 10.766 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00189 175400 423203 - WBI2017 Waterstand - - 1000 11.081 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00189 175400 423203 - WBI2017 Waterstand - - 3000 11.337 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00189 175400 423203 - WBI2017 Waterstand - - 10000 11.619 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00189 175400 423203 - WBI2017 Waterstand - - 30000 11.942 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00190 175329 423129 - WBI2017 Waterstand - - 10 9.098 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00190 175329 423129 - WBI2017 Waterstand - - 100 10.368 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00190 175329 423129 - WBI2017 Waterstand - - 300 10.759 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00190 175329 423129 - WBI2017 Waterstand - - 1000 11.072 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00190 175329 423129 - WBI2017 Waterstand - - 3000 11.325 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00190 175329 423129 - WBI2017 Waterstand - - 10000 11.609 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00190 175329 423129 - WBI2017 Waterstand - - 30000 11.927 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00191 175258 423057 - WBI2017 Waterstand - - 10 9.093 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00191 175258 423057 - WBI2017 Waterstand - - 100 10.358 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00191 175258 423057 - WBI2017 Waterstand - - 300 10.749 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00191 175258 423057 - WBI2017 Waterstand - - 1000 11.060 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00191 175258 423057 - WBI2017 Waterstand - - 3000 11.311 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00191 175258 423057 - WBI2017 Waterstand - - 10000 11.593 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00191 175258 423057 - WBI2017 Waterstand - - 30000 11.911 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00192 175189 422990 - WBI2017 Waterstand - - 10 9.083 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00192 175189 422990 - WBI2017 Waterstand - - 100 10.351 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00192 175189 422990 - WBI2017 Waterstand - - 300 10.736 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00192 175189 422990 - WBI2017 Waterstand - - 1000 11.050 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00192 175189 422990 - WBI2017 Waterstand - - 3000 11.297 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00192 175189 422990 - WBI2017 Waterstand - - 10000 11.584 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00192 175189 422990 - WBI2017 Waterstand - - 30000 11.898 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00193 175080 422942 - WBI2017 Waterstand - - 10 9.080 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00193 175080 422942 - WBI2017 Waterstand - - 100 10.335 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00193 175080 422942 - WBI2017 Waterstand - - 300 10.720 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00193 175080 422942 - WBI2017 Waterstand - - 1000 11.030 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00193 175080 422942 - WBI2017 Waterstand - - 3000 11.277 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00193 175080 422942 - WBI2017 Waterstand - - 10000 11.562 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00193 175080 422942 - WBI2017 Waterstand - - 30000 11.876 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00194 175028 422920 - WBI2017 Waterstand - - 10 9.075 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00194 175028 422920 - WBI2017 Waterstand - - 100 10.324 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00194 175028 422920 - WBI2017 Waterstand - - 300 10.710 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00194 175028 422920 - WBI2017 Waterstand - - 1000 11.019 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00194 175028 422920 - WBI2017 Waterstand - - 3000 11.268 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00194 175028 422920 - WBI2017 Waterstand - - 10000 11.553 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00194 175028 422920 - WBI2017 Waterstand - - 30000 11.862 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00195 174929 422879 - WBI2017 Waterstand - - 10 9.062 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00195 174929 422879 - WBI2017 Waterstand - - 100 10.292 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00195 174929 422879 - WBI2017 Waterstand - - 300 10.672 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00195 174929 422879 - WBI2017 Waterstand - - 1000 10.981 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00195 174929 422879 - WBI2017 Waterstand - - 3000 11.231 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00195 174929 422879 - WBI2017 Waterstand - - 10000 11.503 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00195 174929 422879 - WBI2017 Waterstand - - 30000 11.816 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00196 174802 422877 - WBI2017 Waterstand - - 10 9.028 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00196 174802 422877 - WBI2017 Waterstand - - 100 10.247 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00196 174802 422877 - WBI2017 Waterstand - - 300 10.626 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00196 174802 422877 - WBI2017 Waterstand - - 1000 10.931 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00196 174802 422877 - WBI2017 Waterstand - - 3000 11.175 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00196 174802 422877 - WBI2017 Waterstand - - 10000 11.453 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00196 174802 422877 - WBI2017 Waterstand - - 30000 11.755 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00197 174715 422842 - WBI2017 Waterstand - - 10 8.979 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00197 174715 422842 - WBI2017 Waterstand - - 100 10.197 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00197 174715 422842 - WBI2017 Waterstand - - 300 10.569 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00197 174715 422842 - WBI2017 Waterstand - - 1000 10.876 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00197 174715 422842 - WBI2017 Waterstand - - 3000 11.122 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00197 174715 422842 - WBI2017 Waterstand - - 10000 11.389 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00197 174715 422842 - WBI2017 Waterstand - - 30000 11.694 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00198 174605 422868 - WBI2017 Waterstand - - 10 8.948 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00198 174605 422868 - WBI2017 Waterstand - - 100 10.159 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00198 174605 422868 - WBI2017 Waterstand - - 300 10.536 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00198 174605 422868 - WBI2017 Waterstand - - 1000 10.841 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00198 174605 422868 - WBI2017 Waterstand - - 3000 11.082 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00198 174605 422868 - WBI2017 Waterstand - - 10000 11.361 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00198 174605 422868 - WBI2017 Waterstand - - 30000 11.664 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00199 174533 422886 - WBI2017 Waterstand - - 10 8.928 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00199 174533 422886 - WBI2017 Waterstand - - 100 10.136 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00199 174533 422886 - WBI2017 Waterstand - - 300 10.511 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00199 174533 422886 - WBI2017 Waterstand - - 1000 10.815 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00199 174533 422886 - WBI2017 Waterstand - - 3000 11.064 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00199 174533 422886 - WBI2017 Waterstand - - 10000 11.338 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00199 174533 422886 - WBI2017 Waterstand - - 30000 11.636 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00200 174426 422917 - WBI2017 Waterstand - - 10 8.895 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00200 174426 422917 - WBI2017 Waterstand - - 100 10.108 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00200 174426 422917 - WBI2017 Waterstand - - 300 10.482 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00200 174426 422917 - WBI2017 Waterstand - - 1000 10.786 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00200 174426 422917 - WBI2017 Waterstand - - 3000 11.034 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00200 174426 422917 - WBI2017 Waterstand - - 10000 11.304 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00200 174426 422917 - WBI2017 Waterstand - - 30000 11.605 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00201 174330 422981 - WBI2017 Waterstand - - 10 8.880 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00201 174330 422981 - WBI2017 Waterstand - - 100 10.086 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00201 174330 422981 - WBI2017 Waterstand - - 300 10.452 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00201 174330 422981 - WBI2017 Waterstand - - 1000 10.757 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00201 174330 422981 - WBI2017 Waterstand - - 3000 10.998 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00201 174330 422981 - WBI2017 Waterstand - - 10000 11.272 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00201 174330 422981 - WBI2017 Waterstand - - 30000 11.566 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00202 174261 423010 - WBI2017 Waterstand - - 10 8.868 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00202 174261 423010 - WBI2017 Waterstand - - 100 10.067 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00202 174261 423010 - WBI2017 Waterstand - - 300 10.438 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00202 174261 423010 - WBI2017 Waterstand - - 1000 10.741 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00202 174261 423010 - WBI2017 Waterstand - - 3000 10.979 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00202 174261 423010 - WBI2017 Waterstand - - 10000 11.253 - - - - -WBI2017_Bovenmaas_41-4_v03.sqlite MA_1_41-4_dk_00202 174261 423010 - WBI2017 Waterstand - - 30000 11.547 - - - - diff --git a/tests/testset/__init__.py b/tests/testset/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/testset/create_testset.py b/tests/testset/create_testset.py deleted file mode 100644 index 8a7fc6ca..00000000 --- a/tests/testset/create_testset.py +++ /dev/null @@ -1,90 +0,0 @@ -"""Create a test set for piping calculations.""" - -import itertools - -import numpy as np -import pandas as pd - - -def create_permutations_dataframe(**kwargs): - """ - Create a DataFrame with all possible permutations of the provided variables. - - Parameters: - **kwargs: Each keyword argument represents a variable name and its list of possible values. - - Returns: - pd.DataFrame: A DataFrame containing all permutations of the input variables. - """ - # Extract variable names and their values - variable_names = kwargs.keys() - variable_values = kwargs.values() - - # Generate all possible permutations - permutations = list(itertools.product(*variable_values)) - - # Create a DataFrame from the permutations - df = pd.DataFrame(permutations, columns=list(variable_names)) - - return df - - -# Example usage -# variables = { -# "dist_L_geom": [200.0, 500.0, 1000.0], -# "distBUT": [20.0, 40.0], -# "gamma_w": [9.81], -# "h": [0.0, 5.0, 10.0], -# } - -# list_of_variables = [ -# dist_L_geom, -# dist_BUT, -# dist_BIT, -# L3_geom, -# mv, -# pp, -# top_zand, -# gamma_sat_cover, -# gamma_w, -# kD, -# D, -# d70, -# c_1, -# c_3, -# mu, -# mh, -# mp, -# i_c_h, -# rc, -# h, -# ] - -size = 5 - -variables = { - "dist_L_geom": [10.0, 100.0, 500.0], - "distBUT": [20.0], - "distBIT": [5.0], - "L3_geom": [500.0, 3000.0], - "mv": [0.0], - "pp": [0.0], - "top_zand": np.linspace(-10.0, 0.1, size), - "gamma_sat_cover": [15.0], - "gamma_w": [9.81], - "k": np.linspace(1.0, 120.0, size), - "D": np.linspace(1.5, 60.0, size), - "d70": np.linspace(1.5e-4, 5.0e-4, size), - "c_1": np.linspace(1, 100.0, size), - "c_3": np.linspace(1, 600.0, size), - "mu": [1.0], - "mh": [1.0], - "mp": [1.0], - "i_c_h": [0.3], - "rc": [0.3], - "h": np.linspace(0.0, 10.0, size), -} - -df = create_permutations_dataframe(**variables) -df["kD"] = df["k"] * df["D"] -df.to_excel("tests/testset/input_testset.xlsx", index=False) diff --git a/tests/testset/testset_app.xlsx b/tests/testset/testset_app.xlsx deleted file mode 100644 index 4714708a..00000000 Binary files a/tests/testset/testset_app.xlsx and /dev/null differ diff --git a/tests/testset/testset_limitstate_piping.xlsx b/tests/testset/testset_limitstate_piping.xlsx index 7471a8e7..6eae4ed7 100644 Binary files a/tests/testset/testset_limitstate_piping.xlsx and b/tests/testset/testset_limitstate_piping.xlsx differ diff --git a/todo b/todo deleted file mode 100644 index 6286f632..00000000 --- a/todo +++ /dev/null @@ -1,43 +0,0 @@ -# TODO List for GeoProb-Pipe - -1. **Project Setup** - - [x] Initialize project structure. - - [x] Set up version control with Git. - - [ ] Create a README file with project description. - - [X] Harmonize requirements for documentation. - -2. **Core Functionality** - - [X] Implement piping kernel and testing different formats. - - [ ] naamgeving in de variable_definition doorvoeren in alle functies,classes en tests - - [ ] "variable_definition.xlsx" invullen en opsturen naar WSHD voor verificatie: doel = gelijke naamgeving van de variabelen - - [X] Rewrite Sellmeijer function to implement all contstants - - [ ] Add support for multiple input data formats (e.g., GeoJSON, Shapefile). - - [ ] Develop probabilistic analysis module. - -3. **User Interface** - - [ ] Design and implement datastructure - - [ ] Documentation - -4. **Testing** - - [ ] Write unit tests for core modules. - - [ ] testset uitbreiden naar Z_h en Z_p (eerst class implementatie) - - [ ] Set up testing workflow. - - [ ] Perform integration testing. - -5. **Documentation** - - [ ] Document codebase with comments and docstrings. - - [ ] Write user guide for running the pipeline. - - [ ] Create API documentation if applicable. - -6. **Optimization** - - [ ] Optimize pipeline for performance. - - [ ] Add logging and error handling. - -7. **Deployment** - - [ ] Package the application for distribution. - - [ ] GitObs integration. - -8. **Future Enhancements** - - [ ] Add visualization tools for geospatial data. - - [ ] Implement machine learning models for advanced analysis. - - [ ] Explore cloud integration for scalability. \ No newline at end of file diff --git a/uv.lock b/uv.lock deleted file mode 100644 index bf89bae7..00000000 --- a/uv.lock +++ /dev/null @@ -1,918 +0,0 @@ -version = 1 -requires-python = ">=3.12" - -[[package]] -name = "alabaster" -version = "1.0.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a6/f8/d9c74d0daf3f742840fd818d69cfae176fa332022fd44e3469487d5a9420/alabaster-1.0.0.tar.gz", hash = "sha256:c00dca57bca26fa62a6d7d0a9fcce65f3e026e9bfe33e9c538fd3fbb2144fd9e", size = 24210 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl", hash = "sha256:fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b", size = 13929 }, -] - -[[package]] -name = "babel" -version = "2.17.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7d/6b/d52e42361e1aa00709585ecc30b3f9684b3ab62530771402248b1b1d6240/babel-2.17.0.tar.gz", hash = "sha256:0c54cffb19f690cdcc52a3b50bcbf71e07a808d1c80d549f2459b9d2cf0afb9d", size = 9951852 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b7/b8/3fe70c75fe32afc4bb507f75563d39bc5642255d1d94f1f23604725780bf/babel-2.17.0-py3-none-any.whl", hash = "sha256:4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2", size = 10182537 }, -] - -[[package]] -name = "certifi" -version = "2025.1.31" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/1c/ab/c9f1e32b7b1bf505bf26f0ef697775960db7932abeb7b516de930ba2705f/certifi-2025.1.31.tar.gz", hash = "sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651", size = 167577 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/38/fc/bce832fd4fd99766c04d1ee0eead6b0ec6486fb100ae5e74c1d91292b982/certifi-2025.1.31-py3-none-any.whl", hash = "sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe", size = 166393 }, -] - -[[package]] -name = "charset-normalizer" -version = "3.4.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/16/b0/572805e227f01586461c80e0fd25d65a2115599cc9dad142fee4b747c357/charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3", size = 123188 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/0a/9a/dd1e1cdceb841925b7798369a09279bd1cf183cef0f9ddf15a3a6502ee45/charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545", size = 196105 }, - { url = "https://files.pythonhosted.org/packages/d3/8c/90bfabf8c4809ecb648f39794cf2a84ff2e7d2a6cf159fe68d9a26160467/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7", size = 140404 }, - { url = "https://files.pythonhosted.org/packages/ad/8f/e410d57c721945ea3b4f1a04b74f70ce8fa800d393d72899f0a40526401f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757", size = 150423 }, - { url = "https://files.pythonhosted.org/packages/f0/b8/e6825e25deb691ff98cf5c9072ee0605dc2acfca98af70c2d1b1bc75190d/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa", size = 143184 }, - { url = "https://files.pythonhosted.org/packages/3e/a2/513f6cbe752421f16d969e32f3583762bfd583848b763913ddab8d9bfd4f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d", size = 145268 }, - { url = "https://files.pythonhosted.org/packages/74/94/8a5277664f27c3c438546f3eb53b33f5b19568eb7424736bdc440a88a31f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616", size = 147601 }, - { url = "https://files.pythonhosted.org/packages/7c/5f/6d352c51ee763623a98e31194823518e09bfa48be2a7e8383cf691bbb3d0/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b", size = 141098 }, - { url = "https://files.pythonhosted.org/packages/78/d4/f5704cb629ba5ab16d1d3d741396aec6dc3ca2b67757c45b0599bb010478/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d", size = 149520 }, - { url = "https://files.pythonhosted.org/packages/c5/96/64120b1d02b81785f222b976c0fb79a35875457fa9bb40827678e54d1bc8/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a", size = 152852 }, - { url = "https://files.pythonhosted.org/packages/84/c9/98e3732278a99f47d487fd3468bc60b882920cef29d1fa6ca460a1fdf4e6/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9", size = 150488 }, - { url = "https://files.pythonhosted.org/packages/13/0e/9c8d4cb99c98c1007cc11eda969ebfe837bbbd0acdb4736d228ccaabcd22/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1", size = 146192 }, - { url = "https://files.pythonhosted.org/packages/b2/21/2b6b5b860781a0b49427309cb8670785aa543fb2178de875b87b9cc97746/charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35", size = 95550 }, - { url = "https://files.pythonhosted.org/packages/21/5b/1b390b03b1d16c7e382b561c5329f83cc06623916aab983e8ab9239c7d5c/charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f", size = 102785 }, - { url = "https://files.pythonhosted.org/packages/38/94/ce8e6f63d18049672c76d07d119304e1e2d7c6098f0841b51c666e9f44a0/charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda", size = 195698 }, - { url = "https://files.pythonhosted.org/packages/24/2e/dfdd9770664aae179a96561cc6952ff08f9a8cd09a908f259a9dfa063568/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313", size = 140162 }, - { url = "https://files.pythonhosted.org/packages/24/4e/f646b9093cff8fc86f2d60af2de4dc17c759de9d554f130b140ea4738ca6/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9", size = 150263 }, - { url = "https://files.pythonhosted.org/packages/5e/67/2937f8d548c3ef6e2f9aab0f6e21001056f692d43282b165e7c56023e6dd/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b", size = 142966 }, - { url = "https://files.pythonhosted.org/packages/52/ed/b7f4f07de100bdb95c1756d3a4d17b90c1a3c53715c1a476f8738058e0fa/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11", size = 144992 }, - { url = "https://files.pythonhosted.org/packages/96/2c/d49710a6dbcd3776265f4c923bb73ebe83933dfbaa841c5da850fe0fd20b/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f", size = 147162 }, - { url = "https://files.pythonhosted.org/packages/b4/41/35ff1f9a6bd380303dea55e44c4933b4cc3c4850988927d4082ada230273/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd", size = 140972 }, - { url = "https://files.pythonhosted.org/packages/fb/43/c6a0b685fe6910d08ba971f62cd9c3e862a85770395ba5d9cad4fede33ab/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2", size = 149095 }, - { url = "https://files.pythonhosted.org/packages/4c/ff/a9a504662452e2d2878512115638966e75633519ec11f25fca3d2049a94a/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886", size = 152668 }, - { url = "https://files.pythonhosted.org/packages/6c/71/189996b6d9a4b932564701628af5cee6716733e9165af1d5e1b285c530ed/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601", size = 150073 }, - { url = "https://files.pythonhosted.org/packages/e4/93/946a86ce20790e11312c87c75ba68d5f6ad2208cfb52b2d6a2c32840d922/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd", size = 145732 }, - { url = "https://files.pythonhosted.org/packages/cd/e5/131d2fb1b0dddafc37be4f3a2fa79aa4c037368be9423061dccadfd90091/charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407", size = 95391 }, - { url = "https://files.pythonhosted.org/packages/27/f2/4f9a69cc7712b9b5ad8fdb87039fd89abba997ad5cbe690d1835d40405b0/charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971", size = 102702 }, - { url = "https://files.pythonhosted.org/packages/0e/f6/65ecc6878a89bb1c23a086ea335ad4bf21a588990c3f535a227b9eea9108/charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85", size = 49767 }, -] - -[[package]] -name = "colorama" -version = "0.4.6" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, -] - -[[package]] -name = "contourpy" -version = "1.3.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "numpy" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/25/c2/fc7193cc5383637ff390a712e88e4ded0452c9fbcf84abe3de5ea3df1866/contourpy-1.3.1.tar.gz", hash = "sha256:dfd97abd83335045a913e3bcc4a09c0ceadbe66580cf573fe961f4a825efa699", size = 13465753 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/37/6b/175f60227d3e7f5f1549fcb374592be311293132207e451c3d7c654c25fb/contourpy-1.3.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:0ffa84be8e0bd33410b17189f7164c3589c229ce5db85798076a3fa136d0e509", size = 271494 }, - { url = "https://files.pythonhosted.org/packages/6b/6a/7833cfae2c1e63d1d8875a50fd23371394f540ce809d7383550681a1fa64/contourpy-1.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805617228ba7e2cbbfb6c503858e626ab528ac2a32a04a2fe88ffaf6b02c32bc", size = 255444 }, - { url = "https://files.pythonhosted.org/packages/7f/b3/7859efce66eaca5c14ba7619791b084ed02d868d76b928ff56890d2d059d/contourpy-1.3.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ade08d343436a94e633db932e7e8407fe7de8083967962b46bdfc1b0ced39454", size = 307628 }, - { url = "https://files.pythonhosted.org/packages/48/b2/011415f5e3f0a50b1e285a0bf78eb5d92a4df000553570f0851b6e309076/contourpy-1.3.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:47734d7073fb4590b4a40122b35917cd77be5722d80683b249dac1de266aac80", size = 347271 }, - { url = "https://files.pythonhosted.org/packages/84/7d/ef19b1db0f45b151ac78c65127235239a8cf21a59d1ce8507ce03e89a30b/contourpy-1.3.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2ba94a401342fc0f8b948e57d977557fbf4d515f03c67682dd5c6191cb2d16ec", size = 318906 }, - { url = "https://files.pythonhosted.org/packages/ba/99/6794142b90b853a9155316c8f470d2e4821fe6f086b03e372aca848227dd/contourpy-1.3.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efa874e87e4a647fd2e4f514d5e91c7d493697127beb95e77d2f7561f6905bd9", size = 323622 }, - { url = "https://files.pythonhosted.org/packages/3c/0f/37d2c84a900cd8eb54e105f4fa9aebd275e14e266736778bb5dccbf3bbbb/contourpy-1.3.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1bf98051f1045b15c87868dbaea84f92408337d4f81d0e449ee41920ea121d3b", size = 1266699 }, - { url = "https://files.pythonhosted.org/packages/3a/8a/deb5e11dc7d9cc8f0f9c8b29d4f062203f3af230ba83c30a6b161a6effc9/contourpy-1.3.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:61332c87493b00091423e747ea78200659dc09bdf7fd69edd5e98cef5d3e9a8d", size = 1326395 }, - { url = "https://files.pythonhosted.org/packages/1a/35/7e267ae7c13aaf12322ccc493531f1e7f2eb8fba2927b9d7a05ff615df7a/contourpy-1.3.1-cp312-cp312-win32.whl", hash = "sha256:e914a8cb05ce5c809dd0fe350cfbb4e881bde5e2a38dc04e3afe1b3e58bd158e", size = 175354 }, - { url = "https://files.pythonhosted.org/packages/a1/35/c2de8823211d07e8a79ab018ef03960716c5dff6f4d5bff5af87fd682992/contourpy-1.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:08d9d449a61cf53033612cb368f3a1b26cd7835d9b8cd326647efe43bca7568d", size = 220971 }, - { url = "https://files.pythonhosted.org/packages/9a/e7/de62050dce687c5e96f946a93546910bc67e483fe05324439e329ff36105/contourpy-1.3.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a761d9ccfc5e2ecd1bf05534eda382aa14c3e4f9205ba5b1684ecfe400716ef2", size = 271548 }, - { url = "https://files.pythonhosted.org/packages/78/4d/c2a09ae014ae984c6bdd29c11e74d3121b25eaa117eca0bb76340efd7e1c/contourpy-1.3.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:523a8ee12edfa36f6d2a49407f705a6ef4c5098de4f498619787e272de93f2d5", size = 255576 }, - { url = "https://files.pythonhosted.org/packages/ab/8a/915380ee96a5638bda80cd061ccb8e666bfdccea38d5741cb69e6dbd61fc/contourpy-1.3.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece6df05e2c41bd46776fbc712e0996f7c94e0d0543af1656956d150c4ca7c81", size = 306635 }, - { url = "https://files.pythonhosted.org/packages/29/5c/c83ce09375428298acd4e6582aeb68b1e0d1447f877fa993d9bf6cd3b0a0/contourpy-1.3.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:573abb30e0e05bf31ed067d2f82500ecfdaec15627a59d63ea2d95714790f5c2", size = 345925 }, - { url = "https://files.pythonhosted.org/packages/29/63/5b52f4a15e80c66c8078a641a3bfacd6e07106835682454647aca1afc852/contourpy-1.3.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9fa36448e6a3a1a9a2ba23c02012c43ed88905ec80163f2ffe2421c7192a5d7", size = 318000 }, - { url = "https://files.pythonhosted.org/packages/9a/e2/30ca086c692691129849198659bf0556d72a757fe2769eb9620a27169296/contourpy-1.3.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ea9924d28fc5586bf0b42d15f590b10c224117e74409dd7a0be3b62b74a501c", size = 322689 }, - { url = "https://files.pythonhosted.org/packages/6b/77/f37812ef700f1f185d348394debf33f22d531e714cf6a35d13d68a7003c7/contourpy-1.3.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5b75aa69cb4d6f137b36f7eb2ace9280cfb60c55dc5f61c731fdf6f037f958a3", size = 1268413 }, - { url = "https://files.pythonhosted.org/packages/3f/6d/ce84e79cdd128542ebeb268f84abb4b093af78e7f8ec504676673d2675bc/contourpy-1.3.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:041b640d4ec01922083645a94bb3b2e777e6b626788f4095cf21abbe266413c1", size = 1326530 }, - { url = "https://files.pythonhosted.org/packages/72/22/8282f4eae20c73c89bee7a82a19c4e27af9b57bb602ecaa00713d5bdb54d/contourpy-1.3.1-cp313-cp313-win32.whl", hash = "sha256:36987a15e8ace5f58d4d5da9dca82d498c2bbb28dff6e5d04fbfcc35a9cb3a82", size = 175315 }, - { url = "https://files.pythonhosted.org/packages/e3/d5/28bca491f65312b438fbf076589dcde7f6f966b196d900777f5811b9c4e2/contourpy-1.3.1-cp313-cp313-win_amd64.whl", hash = "sha256:a7895f46d47671fa7ceec40f31fae721da51ad34bdca0bee83e38870b1f47ffd", size = 220987 }, - { url = "https://files.pythonhosted.org/packages/2f/24/a4b285d6adaaf9746e4700932f579f1a7b6f9681109f694cfa233ae75c4e/contourpy-1.3.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:9ddeb796389dadcd884c7eb07bd14ef12408aaae358f0e2ae24114d797eede30", size = 285001 }, - { url = "https://files.pythonhosted.org/packages/48/1d/fb49a401b5ca4f06ccf467cd6c4f1fd65767e63c21322b29b04ec40b40b9/contourpy-1.3.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:19c1555a6801c2f084c7ddc1c6e11f02eb6a6016ca1318dd5452ba3f613a1751", size = 268553 }, - { url = "https://files.pythonhosted.org/packages/79/1e/4aef9470d13fd029087388fae750dccb49a50c012a6c8d1d634295caa644/contourpy-1.3.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:841ad858cff65c2c04bf93875e384ccb82b654574a6d7f30453a04f04af71342", size = 310386 }, - { url = "https://files.pythonhosted.org/packages/b0/34/910dc706ed70153b60392b5305c708c9810d425bde12499c9184a1100888/contourpy-1.3.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4318af1c925fb9a4fb190559ef3eec206845f63e80fb603d47f2d6d67683901c", size = 349806 }, - { url = "https://files.pythonhosted.org/packages/31/3c/faee6a40d66d7f2a87f7102236bf4780c57990dd7f98e5ff29881b1b1344/contourpy-1.3.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:14c102b0eab282427b662cb590f2e9340a9d91a1c297f48729431f2dcd16e14f", size = 321108 }, - { url = "https://files.pythonhosted.org/packages/17/69/390dc9b20dd4bb20585651d7316cc3054b7d4a7b4f8b710b2b698e08968d/contourpy-1.3.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05e806338bfeaa006acbdeba0ad681a10be63b26e1b17317bfac3c5d98f36cda", size = 327291 }, - { url = "https://files.pythonhosted.org/packages/ef/74/7030b67c4e941fe1e5424a3d988080e83568030ce0355f7c9fc556455b01/contourpy-1.3.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4d76d5993a34ef3df5181ba3c92fabb93f1eaa5729504fb03423fcd9f3177242", size = 1263752 }, - { url = "https://files.pythonhosted.org/packages/f0/ed/92d86f183a8615f13f6b9cbfc5d4298a509d6ce433432e21da838b4b63f4/contourpy-1.3.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:89785bb2a1980c1bd87f0cb1517a71cde374776a5f150936b82580ae6ead44a1", size = 1318403 }, - { url = "https://files.pythonhosted.org/packages/b3/0e/c8e4950c77dcfc897c71d61e56690a0a9df39543d2164040301b5df8e67b/contourpy-1.3.1-cp313-cp313t-win32.whl", hash = "sha256:8eb96e79b9f3dcadbad2a3891672f81cdcab7f95b27f28f1c67d75f045b6b4f1", size = 185117 }, - { url = "https://files.pythonhosted.org/packages/c1/31/1ae946f11dfbd229222e6d6ad8e7bd1891d3d48bde5fbf7a0beb9491f8e3/contourpy-1.3.1-cp313-cp313t-win_amd64.whl", hash = "sha256:287ccc248c9e0d0566934e7d606201abd74761b5703d804ff3df8935f523d546", size = 236668 }, -] - -[[package]] -name = "cycler" -version = "0.12.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a9/95/a3dbbb5028f35eafb79008e7522a75244477d2838f38cbb722248dabc2a8/cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c", size = 7615 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30", size = 8321 }, -] - -[[package]] -name = "docutils" -version = "0.21.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ae/ed/aefcc8cd0ba62a0560c3c18c33925362d46c6075480bfa4df87b28e169a9/docutils-0.21.2.tar.gz", hash = "sha256:3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f", size = 2204444 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/8f/d7/9322c609343d929e75e7e5e6255e614fcc67572cfd083959cdef3b7aad79/docutils-0.21.2-py3-none-any.whl", hash = "sha256:dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2", size = 587408 }, -] - -[[package]] -name = "et-xmlfile" -version = "2.0.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d3/38/af70d7ab1ae9d4da450eeec1fa3918940a5fafb9055e934af8d6eb0c2313/et_xmlfile-2.0.0.tar.gz", hash = "sha256:dab3f4764309081ce75662649be815c4c9081e88f0837825f90fd28317d4da54", size = 17234 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c1/8b/5fe2cc11fee489817272089c4203e679c63b570a5aaeb18d852ae3cbba6a/et_xmlfile-2.0.0-py3-none-any.whl", hash = "sha256:7a91720bc756843502c3b7504c77b8fe44217c85c537d85037f0f536151b2caa", size = 18059 }, -] - -[[package]] -name = "fonttools" -version = "4.56.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/1c/8c/9ffa2a555af0e5e5d0e2ed7fdd8c9bef474ed676995bb4c57c9cd0014248/fonttools-4.56.0.tar.gz", hash = "sha256:a114d1567e1a1586b7e9e7fc2ff686ca542a82769a296cef131e4c4af51e58f4", size = 3462892 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/39/32/71cfd6877999576a11824a7fe7bc0bb57c5c72b1f4536fa56a3e39552643/fonttools-4.56.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:d6f195c14c01bd057bc9b4f70756b510e009c83c5ea67b25ced3e2c38e6ee6e9", size = 2747757 }, - { url = "https://files.pythonhosted.org/packages/15/52/d9f716b072c5061a0b915dd4c387f74bef44c68c069e2195c753905bd9b7/fonttools-4.56.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fa760e5fe8b50cbc2d71884a1eff2ed2b95a005f02dda2fa431560db0ddd927f", size = 2279007 }, - { url = "https://files.pythonhosted.org/packages/d1/97/f1b3a8afa9a0d814a092a25cd42f59ccb98a0bb7a295e6e02fc9ba744214/fonttools-4.56.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d54a45d30251f1d729e69e5b675f9a08b7da413391a1227781e2a297fa37f6d2", size = 4783991 }, - { url = "https://files.pythonhosted.org/packages/95/70/2a781bedc1c45a0c61d29c56425609b22ed7f971da5d7e5df2679488741b/fonttools-4.56.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:661a8995d11e6e4914a44ca7d52d1286e2d9b154f685a4d1f69add8418961563", size = 4855109 }, - { url = "https://files.pythonhosted.org/packages/0c/02/a2597858e61a5e3fb6a14d5f6be9e6eb4eaf090da56ad70cedcbdd201685/fonttools-4.56.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9d94449ad0a5f2a8bf5d2f8d71d65088aee48adbe45f3c5f8e00e3ad861ed81a", size = 4762496 }, - { url = "https://files.pythonhosted.org/packages/f2/00/aaf00100d6078fdc73f7352b44589804af9dc12b182a2540b16002152ba4/fonttools-4.56.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f59746f7953f69cc3290ce2f971ab01056e55ddd0fb8b792c31a8acd7fee2d28", size = 4990094 }, - { url = "https://files.pythonhosted.org/packages/bf/dc/3ff1db522460db60cf3adaf1b64e0c72b43406717d139786d3fa1eb20709/fonttools-4.56.0-cp312-cp312-win32.whl", hash = "sha256:bce60f9a977c9d3d51de475af3f3581d9b36952e1f8fc19a1f2254f1dda7ce9c", size = 2142888 }, - { url = "https://files.pythonhosted.org/packages/6f/e3/5a181a85777f7809076e51f7422e0dc77eb04676c40ec8bf6a49d390d1ff/fonttools-4.56.0-cp312-cp312-win_amd64.whl", hash = "sha256:300c310bb725b2bdb4f5fc7e148e190bd69f01925c7ab437b9c0ca3e1c7cd9ba", size = 2189734 }, - { url = "https://files.pythonhosted.org/packages/a5/55/f06b48d48e0b4ec3a3489efafe9bd4d81b6e0802ac51026e3ee4634e89ba/fonttools-4.56.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:f20e2c0dfab82983a90f3d00703ac0960412036153e5023eed2b4641d7d5e692", size = 2735127 }, - { url = "https://files.pythonhosted.org/packages/59/db/d2c7c9b6dd5cbd46f183e650a47403ffb88fca17484eb7c4b1cd88f9e513/fonttools-4.56.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f36a0868f47b7566237640c026c65a86d09a3d9ca5df1cd039e30a1da73098a0", size = 2272519 }, - { url = "https://files.pythonhosted.org/packages/4d/a2/da62d779c34a0e0c06415f02eab7fa3466de5d46df459c0275a255cefc65/fonttools-4.56.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62b4c6802fa28e14dba010e75190e0e6228513573f1eeae57b11aa1a39b7e5b1", size = 4762423 }, - { url = "https://files.pythonhosted.org/packages/be/6a/fd4018e0448c8a5e12138906411282c5eab51a598493f080a9f0960e658f/fonttools-4.56.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a05d1f07eb0a7d755fbe01fee1fd255c3a4d3730130cf1bfefb682d18fd2fcea", size = 4834442 }, - { url = "https://files.pythonhosted.org/packages/6d/63/fa1dec8efb35bc11ef9c39b2d74754b45d48a3ccb2cf78c0109c0af639e8/fonttools-4.56.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0073b62c3438cf0058488c002ea90489e8801d3a7af5ce5f7c05c105bee815c3", size = 4742800 }, - { url = "https://files.pythonhosted.org/packages/dd/f4/963247ae8c73ccc4cf2929e7162f595c81dbe17997d1d0ea77da24a217c9/fonttools-4.56.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e2cad98c94833465bcf28f51c248aaf07ca022efc6a3eba750ad9c1e0256d278", size = 4963746 }, - { url = "https://files.pythonhosted.org/packages/ea/e0/46f9600c39c644b54e4420f941f75fa200d9288c9ae171e5d80918b8cbb9/fonttools-4.56.0-cp313-cp313-win32.whl", hash = "sha256:d0cb73ccf7f6d7ca8d0bc7ea8ac0a5b84969a41c56ac3ac3422a24df2680546f", size = 2140927 }, - { url = "https://files.pythonhosted.org/packages/27/6d/3edda54f98a550a0473f032d8050315fbc8f1b76a0d9f3879b72ebb2cdd6/fonttools-4.56.0-cp313-cp313-win_amd64.whl", hash = "sha256:62cc1253827d1e500fde9dbe981219fea4eb000fd63402283472d38e7d8aa1c6", size = 2186709 }, - { url = "https://files.pythonhosted.org/packages/bf/ff/44934a031ce5a39125415eb405b9efb76fe7f9586b75291d66ae5cbfc4e6/fonttools-4.56.0-py3-none-any.whl", hash = "sha256:1088182f68c303b50ca4dc0c82d42083d176cba37af1937e1a976a31149d4d14", size = 1089800 }, -] - -[[package]] -name = "geopandas" -version = "1.0.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "numpy" }, - { name = "packaging" }, - { name = "pandas" }, - { name = "pyogrio" }, - { name = "pyproj" }, - { name = "shapely" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/39/08/2cf5d85356e45b10b8d066cf4c3ba1e9e3185423c48104eed87e8afd0455/geopandas-1.0.1.tar.gz", hash = "sha256:b8bf70a5534588205b7a56646e2082fb1de9a03599651b3d80c99ea4c2ca08ab", size = 317736 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c4/64/7d344cfcef5efddf9cf32f59af7f855828e9d74b5f862eddf5bfd9f25323/geopandas-1.0.1-py3-none-any.whl", hash = "sha256:01e147d9420cc374d26f51fc23716ac307f32b49406e4bd8462c07e82ed1d3d6", size = 323587 }, -] - -[[package]] -name = "geoprob-pipe" -version = "0.0.1" -source = { virtual = "." } -dependencies = [ - { name = "geopandas" }, - { name = "matplotlib" }, - { name = "openpyxl" }, - { name = "probabilistic-library" }, - { name = "scipy" }, -] - -[package.dev-dependencies] -dev = [ - { name = "numpy" }, - { name = "pytest" }, - { name = "sphinx" }, - { name = "sphinxcontrib-bibtex" }, -] - -[package.metadata] -requires-dist = [ - { name = "geopandas", specifier = "~=1.0.1" }, - { name = "matplotlib", specifier = "~=3.10.1" }, - { name = "openpyxl", specifier = ">=3.1.5" }, - { name = "probabilistic-library", path = "wheels/probabilistic_library-25.1.1-py3-none-any.whl" }, - { name = "scipy", specifier = "~=1.14.1" }, -] - -[package.metadata.requires-dev] -dev = [ - { name = "numpy", specifier = ">=2.2.4" }, - { name = "pytest", specifier = ">=8.3.5" }, - { name = "sphinx", specifier = ">=8.2.3" }, - { name = "sphinxcontrib-bibtex", specifier = ">=2.6.3" }, -] - -[[package]] -name = "idna" -version = "3.10" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 }, -] - -[[package]] -name = "imagesize" -version = "1.4.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a7/84/62473fb57d61e31fef6e36d64a179c8781605429fd927b5dd608c997be31/imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a", size = 1280026 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ff/62/85c4c919272577931d407be5ba5d71c20f0b616d31a0befe0ae45bb79abd/imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b", size = 8769 }, -] - -[[package]] -name = "iniconfig" -version = "2.1.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f2/97/ebf4da567aa6827c909642694d71c9fcf53e5b504f2d96afea02718862f3/iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", size = 4793 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760", size = 6050 }, -] - -[[package]] -name = "jinja2" -version = "3.1.6" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "markupsafe" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899 }, -] - -[[package]] -name = "kiwisolver" -version = "1.4.8" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/82/59/7c91426a8ac292e1cdd53a63b6d9439abd573c875c3f92c146767dd33faf/kiwisolver-1.4.8.tar.gz", hash = "sha256:23d5f023bdc8c7e54eb65f03ca5d5bb25b601eac4d7f1a042888a1f45237987e", size = 97538 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/fc/aa/cea685c4ab647f349c3bc92d2daf7ae34c8e8cf405a6dcd3a497f58a2ac3/kiwisolver-1.4.8-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:d6af5e8815fd02997cb6ad9bbed0ee1e60014438ee1a5c2444c96f87b8843502", size = 124152 }, - { url = "https://files.pythonhosted.org/packages/c5/0b/8db6d2e2452d60d5ebc4ce4b204feeb16176a851fd42462f66ade6808084/kiwisolver-1.4.8-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:bade438f86e21d91e0cf5dd7c0ed00cda0f77c8c1616bd83f9fc157fa6760d31", size = 66555 }, - { url = "https://files.pythonhosted.org/packages/60/26/d6a0db6785dd35d3ba5bf2b2df0aedc5af089962c6eb2cbf67a15b81369e/kiwisolver-1.4.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b83dc6769ddbc57613280118fb4ce3cd08899cc3369f7d0e0fab518a7cf37fdb", size = 65067 }, - { url = "https://files.pythonhosted.org/packages/c9/ed/1d97f7e3561e09757a196231edccc1bcf59d55ddccefa2afc9c615abd8e0/kiwisolver-1.4.8-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:111793b232842991be367ed828076b03d96202c19221b5ebab421ce8bcad016f", size = 1378443 }, - { url = "https://files.pythonhosted.org/packages/29/61/39d30b99954e6b46f760e6289c12fede2ab96a254c443639052d1b573fbc/kiwisolver-1.4.8-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:257af1622860e51b1a9d0ce387bf5c2c4f36a90594cb9514f55b074bcc787cfc", size = 1472728 }, - { url = "https://files.pythonhosted.org/packages/0c/3e/804163b932f7603ef256e4a715e5843a9600802bb23a68b4e08c8c0ff61d/kiwisolver-1.4.8-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:69b5637c3f316cab1ec1c9a12b8c5f4750a4c4b71af9157645bf32830e39c03a", size = 1478388 }, - { url = "https://files.pythonhosted.org/packages/8a/9e/60eaa75169a154700be74f875a4d9961b11ba048bef315fbe89cb6999056/kiwisolver-1.4.8-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:782bb86f245ec18009890e7cb8d13a5ef54dcf2ebe18ed65f795e635a96a1c6a", size = 1413849 }, - { url = "https://files.pythonhosted.org/packages/bc/b3/9458adb9472e61a998c8c4d95cfdfec91c73c53a375b30b1428310f923e4/kiwisolver-1.4.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc978a80a0db3a66d25767b03688f1147a69e6237175c0f4ffffaaedf744055a", size = 1475533 }, - { url = "https://files.pythonhosted.org/packages/e4/7a/0a42d9571e35798de80aef4bb43a9b672aa7f8e58643d7bd1950398ffb0a/kiwisolver-1.4.8-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:36dbbfd34838500a31f52c9786990d00150860e46cd5041386f217101350f0d3", size = 2268898 }, - { url = "https://files.pythonhosted.org/packages/d9/07/1255dc8d80271400126ed8db35a1795b1a2c098ac3a72645075d06fe5c5d/kiwisolver-1.4.8-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:eaa973f1e05131de5ff3569bbba7f5fd07ea0595d3870ed4a526d486fe57fa1b", size = 2425605 }, - { url = "https://files.pythonhosted.org/packages/84/df/5a3b4cf13780ef6f6942df67b138b03b7e79e9f1f08f57c49957d5867f6e/kiwisolver-1.4.8-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:a66f60f8d0c87ab7f59b6fb80e642ebb29fec354a4dfad687ca4092ae69d04f4", size = 2375801 }, - { url = "https://files.pythonhosted.org/packages/8f/10/2348d068e8b0f635c8c86892788dac7a6b5c0cb12356620ab575775aad89/kiwisolver-1.4.8-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:858416b7fb777a53f0c59ca08190ce24e9abbd3cffa18886a5781b8e3e26f65d", size = 2520077 }, - { url = "https://files.pythonhosted.org/packages/32/d8/014b89fee5d4dce157d814303b0fce4d31385a2af4c41fed194b173b81ac/kiwisolver-1.4.8-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:085940635c62697391baafaaeabdf3dd7a6c3643577dde337f4d66eba021b2b8", size = 2338410 }, - { url = "https://files.pythonhosted.org/packages/bd/72/dfff0cc97f2a0776e1c9eb5bef1ddfd45f46246c6533b0191887a427bca5/kiwisolver-1.4.8-cp312-cp312-win_amd64.whl", hash = "sha256:01c3d31902c7db5fb6182832713d3b4122ad9317c2c5877d0539227d96bb2e50", size = 71853 }, - { url = "https://files.pythonhosted.org/packages/dc/85/220d13d914485c0948a00f0b9eb419efaf6da81b7d72e88ce2391f7aed8d/kiwisolver-1.4.8-cp312-cp312-win_arm64.whl", hash = "sha256:a3c44cb68861de93f0c4a8175fbaa691f0aa22550c331fefef02b618a9dcb476", size = 65424 }, - { url = "https://files.pythonhosted.org/packages/79/b3/e62464a652f4f8cd9006e13d07abad844a47df1e6537f73ddfbf1bc997ec/kiwisolver-1.4.8-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:1c8ceb754339793c24aee1c9fb2485b5b1f5bb1c2c214ff13368431e51fc9a09", size = 124156 }, - { url = "https://files.pythonhosted.org/packages/8d/2d/f13d06998b546a2ad4f48607a146e045bbe48030774de29f90bdc573df15/kiwisolver-1.4.8-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:54a62808ac74b5e55a04a408cda6156f986cefbcf0ada13572696b507cc92fa1", size = 66555 }, - { url = "https://files.pythonhosted.org/packages/59/e3/b8bd14b0a54998a9fd1e8da591c60998dc003618cb19a3f94cb233ec1511/kiwisolver-1.4.8-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:68269e60ee4929893aad82666821aaacbd455284124817af45c11e50a4b42e3c", size = 65071 }, - { url = "https://files.pythonhosted.org/packages/f0/1c/6c86f6d85ffe4d0ce04228d976f00674f1df5dc893bf2dd4f1928748f187/kiwisolver-1.4.8-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:34d142fba9c464bc3bbfeff15c96eab0e7310343d6aefb62a79d51421fcc5f1b", size = 1378053 }, - { url = "https://files.pythonhosted.org/packages/4e/b9/1c6e9f6dcb103ac5cf87cb695845f5fa71379021500153566d8a8a9fc291/kiwisolver-1.4.8-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ddc373e0eef45b59197de815b1b28ef89ae3955e7722cc9710fb91cd77b7f47", size = 1472278 }, - { url = "https://files.pythonhosted.org/packages/ee/81/aca1eb176de671f8bda479b11acdc42c132b61a2ac861c883907dde6debb/kiwisolver-1.4.8-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:77e6f57a20b9bd4e1e2cedda4d0b986ebd0216236f0106e55c28aea3d3d69b16", size = 1478139 }, - { url = "https://files.pythonhosted.org/packages/49/f4/e081522473671c97b2687d380e9e4c26f748a86363ce5af48b4a28e48d06/kiwisolver-1.4.8-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08e77738ed7538f036cd1170cbed942ef749137b1311fa2bbe2a7fda2f6bf3cc", size = 1413517 }, - { url = "https://files.pythonhosted.org/packages/8f/e9/6a7d025d8da8c4931522922cd706105aa32b3291d1add8c5427cdcd66e63/kiwisolver-1.4.8-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a5ce1e481a74b44dd5e92ff03ea0cb371ae7a0268318e202be06c8f04f4f1246", size = 1474952 }, - { url = "https://files.pythonhosted.org/packages/82/13/13fa685ae167bee5d94b415991c4fc7bb0a1b6ebea6e753a87044b209678/kiwisolver-1.4.8-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:fc2ace710ba7c1dfd1a3b42530b62b9ceed115f19a1656adefce7b1782a37794", size = 2269132 }, - { url = "https://files.pythonhosted.org/packages/ef/92/bb7c9395489b99a6cb41d502d3686bac692586db2045adc19e45ee64ed23/kiwisolver-1.4.8-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:3452046c37c7692bd52b0e752b87954ef86ee2224e624ef7ce6cb21e8c41cc1b", size = 2425997 }, - { url = "https://files.pythonhosted.org/packages/ed/12/87f0e9271e2b63d35d0d8524954145837dd1a6c15b62a2d8c1ebe0f182b4/kiwisolver-1.4.8-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:7e9a60b50fe8b2ec6f448fe8d81b07e40141bfced7f896309df271a0b92f80f3", size = 2376060 }, - { url = "https://files.pythonhosted.org/packages/02/6e/c8af39288edbce8bf0fa35dee427b082758a4b71e9c91ef18fa667782138/kiwisolver-1.4.8-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:918139571133f366e8362fa4a297aeba86c7816b7ecf0bc79168080e2bd79957", size = 2520471 }, - { url = "https://files.pythonhosted.org/packages/13/78/df381bc7b26e535c91469f77f16adcd073beb3e2dd25042efd064af82323/kiwisolver-1.4.8-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e063ef9f89885a1d68dd8b2e18f5ead48653176d10a0e324e3b0030e3a69adeb", size = 2338793 }, - { url = "https://files.pythonhosted.org/packages/d0/dc/c1abe38c37c071d0fc71c9a474fd0b9ede05d42f5a458d584619cfd2371a/kiwisolver-1.4.8-cp313-cp313-win_amd64.whl", hash = "sha256:a17b7c4f5b2c51bb68ed379defd608a03954a1845dfed7cc0117f1cc8a9b7fd2", size = 71855 }, - { url = "https://files.pythonhosted.org/packages/a0/b6/21529d595b126ac298fdd90b705d87d4c5693de60023e0efcb4f387ed99e/kiwisolver-1.4.8-cp313-cp313-win_arm64.whl", hash = "sha256:3cd3bc628b25f74aedc6d374d5babf0166a92ff1317f46267f12d2ed54bc1d30", size = 65430 }, - { url = "https://files.pythonhosted.org/packages/34/bd/b89380b7298e3af9b39f49334e3e2a4af0e04819789f04b43d560516c0c8/kiwisolver-1.4.8-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:370fd2df41660ed4e26b8c9d6bbcad668fbe2560462cba151a721d49e5b6628c", size = 126294 }, - { url = "https://files.pythonhosted.org/packages/83/41/5857dc72e5e4148eaac5aa76e0703e594e4465f8ab7ec0fc60e3a9bb8fea/kiwisolver-1.4.8-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:84a2f830d42707de1d191b9490ac186bf7997a9495d4e9072210a1296345f7dc", size = 67736 }, - { url = "https://files.pythonhosted.org/packages/e1/d1/be059b8db56ac270489fb0b3297fd1e53d195ba76e9bbb30e5401fa6b759/kiwisolver-1.4.8-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:7a3ad337add5148cf51ce0b55642dc551c0b9d6248458a757f98796ca7348712", size = 66194 }, - { url = "https://files.pythonhosted.org/packages/e1/83/4b73975f149819eb7dcf9299ed467eba068ecb16439a98990dcb12e63fdd/kiwisolver-1.4.8-cp313-cp313t-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7506488470f41169b86d8c9aeff587293f530a23a23a49d6bc64dab66bedc71e", size = 1465942 }, - { url = "https://files.pythonhosted.org/packages/c7/2c/30a5cdde5102958e602c07466bce058b9d7cb48734aa7a4327261ac8e002/kiwisolver-1.4.8-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f0121b07b356a22fb0414cec4666bbe36fd6d0d759db3d37228f496ed67c880", size = 1595341 }, - { url = "https://files.pythonhosted.org/packages/ff/9b/1e71db1c000385aa069704f5990574b8244cce854ecd83119c19e83c9586/kiwisolver-1.4.8-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d6d6bd87df62c27d4185de7c511c6248040afae67028a8a22012b010bc7ad062", size = 1598455 }, - { url = "https://files.pythonhosted.org/packages/85/92/c8fec52ddf06231b31cbb779af77e99b8253cd96bd135250b9498144c78b/kiwisolver-1.4.8-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:291331973c64bb9cce50bbe871fb2e675c4331dab4f31abe89f175ad7679a4d7", size = 1522138 }, - { url = "https://files.pythonhosted.org/packages/0b/51/9eb7e2cd07a15d8bdd976f6190c0164f92ce1904e5c0c79198c4972926b7/kiwisolver-1.4.8-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:893f5525bb92d3d735878ec00f781b2de998333659507d29ea4466208df37bed", size = 1582857 }, - { url = "https://files.pythonhosted.org/packages/0f/95/c5a00387a5405e68ba32cc64af65ce881a39b98d73cc394b24143bebc5b8/kiwisolver-1.4.8-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b47a465040146981dc9db8647981b8cb96366fbc8d452b031e4f8fdffec3f26d", size = 2293129 }, - { url = "https://files.pythonhosted.org/packages/44/83/eeb7af7d706b8347548313fa3a3a15931f404533cc54fe01f39e830dd231/kiwisolver-1.4.8-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:99cea8b9dd34ff80c521aef46a1dddb0dcc0283cf18bde6d756f1e6f31772165", size = 2421538 }, - { url = "https://files.pythonhosted.org/packages/05/f9/27e94c1b3eb29e6933b6986ffc5fa1177d2cd1f0c8efc5f02c91c9ac61de/kiwisolver-1.4.8-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:151dffc4865e5fe6dafce5480fab84f950d14566c480c08a53c663a0020504b6", size = 2390661 }, - { url = "https://files.pythonhosted.org/packages/d9/d4/3c9735faa36ac591a4afcc2980d2691000506050b7a7e80bcfe44048daa7/kiwisolver-1.4.8-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:577facaa411c10421314598b50413aa1ebcf5126f704f1e5d72d7e4e9f020d90", size = 2546710 }, - { url = "https://files.pythonhosted.org/packages/4c/fa/be89a49c640930180657482a74970cdcf6f7072c8d2471e1babe17a222dc/kiwisolver-1.4.8-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:be4816dc51c8a471749d664161b434912eee82f2ea66bd7628bd14583a833e85", size = 2349213 }, -] - -[[package]] -name = "latexcodec" -version = "3.0.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/98/e7/ed339caf3662976949e4fdbfdf4a6db818b8d2aa1cf2b5f73af89e936bba/latexcodec-3.0.0.tar.gz", hash = "sha256:917dc5fe242762cc19d963e6548b42d63a118028cdd3361d62397e3b638b6bc5", size = 31023 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b0/bf/ea8887e9f31a8f93ca306699d11909c6140151393a4216f0d9f85a004077/latexcodec-3.0.0-py3-none-any.whl", hash = "sha256:6f3477ad5e61a0a99bd31a6a370c34e88733a6bad9c921a3ffcfacada12f41a7", size = 18150 }, -] - -[[package]] -name = "markupsafe" -version = "3.0.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b2/97/5d42485e71dfc078108a86d6de8fa46db44a1a9295e89c5d6d4a06e23a62/markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", size = 20537 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/22/09/d1f21434c97fc42f09d290cbb6350d44eb12f09cc62c9476effdb33a18aa/MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf", size = 14274 }, - { url = "https://files.pythonhosted.org/packages/6b/b0/18f76bba336fa5aecf79d45dcd6c806c280ec44538b3c13671d49099fdd0/MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225", size = 12348 }, - { url = "https://files.pythonhosted.org/packages/e0/25/dd5c0f6ac1311e9b40f4af06c78efde0f3b5cbf02502f8ef9501294c425b/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028", size = 24149 }, - { url = "https://files.pythonhosted.org/packages/f3/f0/89e7aadfb3749d0f52234a0c8c7867877876e0a20b60e2188e9850794c17/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8", size = 23118 }, - { url = "https://files.pythonhosted.org/packages/d5/da/f2eeb64c723f5e3777bc081da884b414671982008c47dcc1873d81f625b6/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c", size = 22993 }, - { url = "https://files.pythonhosted.org/packages/da/0e/1f32af846df486dce7c227fe0f2398dc7e2e51d4a370508281f3c1c5cddc/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557", size = 24178 }, - { url = "https://files.pythonhosted.org/packages/c4/f6/bb3ca0532de8086cbff5f06d137064c8410d10779c4c127e0e47d17c0b71/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22", size = 23319 }, - { url = "https://files.pythonhosted.org/packages/a2/82/8be4c96ffee03c5b4a034e60a31294daf481e12c7c43ab8e34a1453ee48b/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48", size = 23352 }, - { url = "https://files.pythonhosted.org/packages/51/ae/97827349d3fcffee7e184bdf7f41cd6b88d9919c80f0263ba7acd1bbcb18/MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30", size = 15097 }, - { url = "https://files.pythonhosted.org/packages/c1/80/a61f99dc3a936413c3ee4e1eecac96c0da5ed07ad56fd975f1a9da5bc630/MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87", size = 15601 }, - { url = "https://files.pythonhosted.org/packages/83/0e/67eb10a7ecc77a0c2bbe2b0235765b98d164d81600746914bebada795e97/MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd", size = 14274 }, - { url = "https://files.pythonhosted.org/packages/2b/6d/9409f3684d3335375d04e5f05744dfe7e9f120062c9857df4ab490a1031a/MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430", size = 12352 }, - { url = "https://files.pythonhosted.org/packages/d2/f5/6eadfcd3885ea85fe2a7c128315cc1bb7241e1987443d78c8fe712d03091/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094", size = 24122 }, - { url = "https://files.pythonhosted.org/packages/0c/91/96cf928db8236f1bfab6ce15ad070dfdd02ed88261c2afafd4b43575e9e9/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396", size = 23085 }, - { url = "https://files.pythonhosted.org/packages/c2/cf/c9d56af24d56ea04daae7ac0940232d31d5a8354f2b457c6d856b2057d69/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79", size = 22978 }, - { url = "https://files.pythonhosted.org/packages/2a/9f/8619835cd6a711d6272d62abb78c033bda638fdc54c4e7f4272cf1c0962b/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a", size = 24208 }, - { url = "https://files.pythonhosted.org/packages/f9/bf/176950a1792b2cd2102b8ffeb5133e1ed984547b75db47c25a67d3359f77/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca", size = 23357 }, - { url = "https://files.pythonhosted.org/packages/ce/4f/9a02c1d335caabe5c4efb90e1b6e8ee944aa245c1aaaab8e8a618987d816/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c", size = 23344 }, - { url = "https://files.pythonhosted.org/packages/ee/55/c271b57db36f748f0e04a759ace9f8f759ccf22b4960c270c78a394f58be/MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", size = 15101 }, - { url = "https://files.pythonhosted.org/packages/29/88/07df22d2dd4df40aba9f3e402e6dc1b8ee86297dddbad4872bd5e7b0094f/MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", size = 15603 }, - { url = "https://files.pythonhosted.org/packages/62/6a/8b89d24db2d32d433dffcd6a8779159da109842434f1dd2f6e71f32f738c/MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c", size = 14510 }, - { url = "https://files.pythonhosted.org/packages/7a/06/a10f955f70a2e5a9bf78d11a161029d278eeacbd35ef806c3fd17b13060d/MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb", size = 12486 }, - { url = "https://files.pythonhosted.org/packages/34/cf/65d4a571869a1a9078198ca28f39fba5fbb910f952f9dbc5220afff9f5e6/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c", size = 25480 }, - { url = "https://files.pythonhosted.org/packages/0c/e3/90e9651924c430b885468b56b3d597cabf6d72be4b24a0acd1fa0e12af67/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d", size = 23914 }, - { url = "https://files.pythonhosted.org/packages/66/8c/6c7cf61f95d63bb866db39085150df1f2a5bd3335298f14a66b48e92659c/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe", size = 23796 }, - { url = "https://files.pythonhosted.org/packages/bb/35/cbe9238ec3f47ac9a7c8b3df7a808e7cb50fe149dc7039f5f454b3fba218/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5", size = 25473 }, - { url = "https://files.pythonhosted.org/packages/e6/32/7621a4382488aa283cc05e8984a9c219abad3bca087be9ec77e89939ded9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a", size = 24114 }, - { url = "https://files.pythonhosted.org/packages/0d/80/0985960e4b89922cb5a0bac0ed39c5b96cbc1a536a99f30e8c220a996ed9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9", size = 24098 }, - { url = "https://files.pythonhosted.org/packages/82/78/fedb03c7d5380df2427038ec8d973587e90561b2d90cd472ce9254cf348b/MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", size = 15208 }, - { url = "https://files.pythonhosted.org/packages/4f/65/6079a46068dfceaeabb5dcad6d674f5f5c61a6fa5673746f42a9f4c233b3/MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", size = 15739 }, -] - -[[package]] -name = "matplotlib" -version = "3.10.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "contourpy" }, - { name = "cycler" }, - { name = "fonttools" }, - { name = "kiwisolver" }, - { name = "numpy" }, - { name = "packaging" }, - { name = "pillow" }, - { name = "pyparsing" }, - { name = "python-dateutil" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/2f/08/b89867ecea2e305f408fbb417139a8dd941ecf7b23a2e02157c36da546f0/matplotlib-3.10.1.tar.gz", hash = "sha256:e8d2d0e3881b129268585bf4765ad3ee73a4591d77b9a18c214ac7e3a79fb2ba", size = 36743335 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7c/1d/5e0dc3b59c034e43de16f94deb68f4ad8a96b3ea00f4b37c160b7474928e/matplotlib-3.10.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:66e907a06e68cb6cfd652c193311d61a12b54f56809cafbed9736ce5ad92f107", size = 8175488 }, - { url = "https://files.pythonhosted.org/packages/7a/81/dae7e14042e74da658c3336ab9799128e09a1ee03964f2d89630b5d12106/matplotlib-3.10.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e9b4bb156abb8fa5e5b2b460196f7db7264fc6d62678c03457979e7d5254b7be", size = 8046264 }, - { url = "https://files.pythonhosted.org/packages/21/c4/22516775dcde10fc9c9571d155f90710761b028fc44f660508106c363c97/matplotlib-3.10.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1985ad3d97f51307a2cbfc801a930f120def19ba22864182dacef55277102ba6", size = 8452048 }, - { url = "https://files.pythonhosted.org/packages/63/23/c0615001f67ce7c96b3051d856baedc0c818a2ed84570b9bf9bde200f85d/matplotlib-3.10.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c96f2c2f825d1257e437a1482c5a2cf4fee15db4261bd6fc0750f81ba2b4ba3d", size = 8597111 }, - { url = "https://files.pythonhosted.org/packages/ca/c0/a07939a82aed77770514348f4568177d7dadab9787ebc618a616fe3d665e/matplotlib-3.10.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:35e87384ee9e488d8dd5a2dd7baf471178d38b90618d8ea147aced4ab59c9bea", size = 9402771 }, - { url = "https://files.pythonhosted.org/packages/a6/b6/a9405484fb40746fdc6ae4502b16a9d6e53282ba5baaf9ebe2da579f68c4/matplotlib-3.10.1-cp312-cp312-win_amd64.whl", hash = "sha256:cfd414bce89cc78a7e1d25202e979b3f1af799e416010a20ab2b5ebb3a02425c", size = 8063742 }, - { url = "https://files.pythonhosted.org/packages/60/73/6770ff5e5523d00f3bc584acb6031e29ee5c8adc2336b16cd1d003675fe0/matplotlib-3.10.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c42eee41e1b60fd83ee3292ed83a97a5f2a8239b10c26715d8a6172226988d7b", size = 8176112 }, - { url = "https://files.pythonhosted.org/packages/08/97/b0ca5da0ed54a3f6599c3ab568bdda65269bc27c21a2c97868c1625e4554/matplotlib-3.10.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4f0647b17b667ae745c13721602b540f7aadb2a32c5b96e924cd4fea5dcb90f1", size = 8046931 }, - { url = "https://files.pythonhosted.org/packages/df/9a/1acbdc3b165d4ce2dcd2b1a6d4ffb46a7220ceee960c922c3d50d8514067/matplotlib-3.10.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa3854b5f9473564ef40a41bc922be978fab217776e9ae1545c9b3a5cf2092a3", size = 8453422 }, - { url = "https://files.pythonhosted.org/packages/51/d0/2bc4368abf766203e548dc7ab57cf7e9c621f1a3c72b516cc7715347b179/matplotlib-3.10.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e496c01441be4c7d5f96d4e40f7fca06e20dcb40e44c8daa2e740e1757ad9e6", size = 8596819 }, - { url = "https://files.pythonhosted.org/packages/ab/1b/8b350f8a1746c37ab69dda7d7528d1fc696efb06db6ade9727b7887be16d/matplotlib-3.10.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5d45d3f5245be5b469843450617dcad9af75ca50568acf59997bed9311131a0b", size = 9402782 }, - { url = "https://files.pythonhosted.org/packages/89/06/f570373d24d93503988ba8d04f213a372fa1ce48381c5eb15da985728498/matplotlib-3.10.1-cp313-cp313-win_amd64.whl", hash = "sha256:8e8e25b1209161d20dfe93037c8a7f7ca796ec9aa326e6e4588d8c4a5dd1e473", size = 8063812 }, - { url = "https://files.pythonhosted.org/packages/fc/e0/8c811a925b5a7ad75135f0e5af46408b78af88bbb02a1df775100ef9bfef/matplotlib-3.10.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:19b06241ad89c3ae9469e07d77efa87041eac65d78df4fcf9cac318028009b01", size = 8214021 }, - { url = "https://files.pythonhosted.org/packages/4a/34/319ec2139f68ba26da9d00fce2ff9f27679fb799a6c8e7358539801fd629/matplotlib-3.10.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:01e63101ebb3014e6e9f80d9cf9ee361a8599ddca2c3e166c563628b39305dbb", size = 8090782 }, - { url = "https://files.pythonhosted.org/packages/77/ea/9812124ab9a99df5b2eec1110e9b2edc0b8f77039abf4c56e0a376e84a29/matplotlib-3.10.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f06bad951eea6422ac4e8bdebcf3a70c59ea0a03338c5d2b109f57b64eb3972", size = 8478901 }, - { url = "https://files.pythonhosted.org/packages/c9/db/b05bf463689134789b06dea85828f8ebe506fa1e37593f723b65b86c9582/matplotlib-3.10.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a3dfb036f34873b46978f55e240cff7a239f6c4409eac62d8145bad3fc6ba5a3", size = 8613864 }, - { url = "https://files.pythonhosted.org/packages/c2/04/41ccec4409f3023a7576df3b5c025f1a8c8b81fbfe922ecfd837ac36e081/matplotlib-3.10.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:dc6ab14a7ab3b4d813b88ba957fc05c79493a037f54e246162033591e770de6f", size = 9409487 }, - { url = "https://files.pythonhosted.org/packages/ac/c2/0d5aae823bdcc42cc99327ecdd4d28585e15ccd5218c453b7bcd827f3421/matplotlib-3.10.1-cp313-cp313t-win_amd64.whl", hash = "sha256:bc411ebd5889a78dabbc457b3fa153203e22248bfa6eedc6797be5df0164dbf9", size = 8134832 }, -] - -[[package]] -name = "numpy" -version = "2.2.4" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e1/78/31103410a57bc2c2b93a3597340a8119588571f6a4539067546cb9a0bfac/numpy-2.2.4.tar.gz", hash = "sha256:9ba03692a45d3eef66559efe1d1096c4b9b75c0986b5dff5530c378fb8331d4f", size = 20270701 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a2/30/182db21d4f2a95904cec1a6f779479ea1ac07c0647f064dea454ec650c42/numpy-2.2.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a7b9084668aa0f64e64bd00d27ba5146ef1c3a8835f3bd912e7a9e01326804c4", size = 20947156 }, - { url = "https://files.pythonhosted.org/packages/24/6d/9483566acfbda6c62c6bc74b6e981c777229d2af93c8eb2469b26ac1b7bc/numpy-2.2.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:dbe512c511956b893d2dacd007d955a3f03d555ae05cfa3ff1c1ff6df8851854", size = 14133092 }, - { url = "https://files.pythonhosted.org/packages/27/f6/dba8a258acbf9d2bed2525cdcbb9493ef9bae5199d7a9cb92ee7e9b2aea6/numpy-2.2.4-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:bb649f8b207ab07caebba230d851b579a3c8711a851d29efe15008e31bb4de24", size = 5163515 }, - { url = "https://files.pythonhosted.org/packages/62/30/82116199d1c249446723c68f2c9da40d7f062551036f50b8c4caa42ae252/numpy-2.2.4-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:f34dc300df798742b3d06515aa2a0aee20941c13579d7a2f2e10af01ae4901ee", size = 6696558 }, - { url = "https://files.pythonhosted.org/packages/0e/b2/54122b3c6df5df3e87582b2e9430f1bdb63af4023c739ba300164c9ae503/numpy-2.2.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c3f7ac96b16955634e223b579a3e5798df59007ca43e8d451a0e6a50f6bfdfba", size = 14084742 }, - { url = "https://files.pythonhosted.org/packages/02/e2/e2cbb8d634151aab9528ef7b8bab52ee4ab10e076509285602c2a3a686e0/numpy-2.2.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f92084defa704deadd4e0a5ab1dc52d8ac9e8a8ef617f3fbb853e79b0ea3592", size = 16134051 }, - { url = "https://files.pythonhosted.org/packages/8e/21/efd47800e4affc993e8be50c1b768de038363dd88865920439ef7b422c60/numpy-2.2.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7a4e84a6283b36632e2a5b56e121961f6542ab886bc9e12f8f9818b3c266bfbb", size = 15578972 }, - { url = "https://files.pythonhosted.org/packages/04/1e/f8bb88f6157045dd5d9b27ccf433d016981032690969aa5c19e332b138c0/numpy-2.2.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:11c43995255eb4127115956495f43e9343736edb7fcdb0d973defd9de14cd84f", size = 17898106 }, - { url = "https://files.pythonhosted.org/packages/2b/93/df59a5a3897c1f036ae8ff845e45f4081bb06943039ae28a3c1c7c780f22/numpy-2.2.4-cp312-cp312-win32.whl", hash = "sha256:65ef3468b53269eb5fdb3a5c09508c032b793da03251d5f8722b1194f1790c00", size = 6311190 }, - { url = "https://files.pythonhosted.org/packages/46/69/8c4f928741c2a8efa255fdc7e9097527c6dc4e4df147e3cadc5d9357ce85/numpy-2.2.4-cp312-cp312-win_amd64.whl", hash = "sha256:2aad3c17ed2ff455b8eaafe06bcdae0062a1db77cb99f4b9cbb5f4ecb13c5146", size = 12644305 }, - { url = "https://files.pythonhosted.org/packages/2a/d0/bd5ad792e78017f5decfb2ecc947422a3669a34f775679a76317af671ffc/numpy-2.2.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1cf4e5c6a278d620dee9ddeb487dc6a860f9b199eadeecc567f777daace1e9e7", size = 20933623 }, - { url = "https://files.pythonhosted.org/packages/c3/bc/2b3545766337b95409868f8e62053135bdc7fa2ce630aba983a2aa60b559/numpy-2.2.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1974afec0b479e50438fc3648974268f972e2d908ddb6d7fb634598cdb8260a0", size = 14148681 }, - { url = "https://files.pythonhosted.org/packages/6a/70/67b24d68a56551d43a6ec9fe8c5f91b526d4c1a46a6387b956bf2d64744e/numpy-2.2.4-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:79bd5f0a02aa16808fcbc79a9a376a147cc1045f7dfe44c6e7d53fa8b8a79392", size = 5148759 }, - { url = "https://files.pythonhosted.org/packages/1c/8b/e2fc8a75fcb7be12d90b31477c9356c0cbb44abce7ffb36be39a0017afad/numpy-2.2.4-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:3387dd7232804b341165cedcb90694565a6015433ee076c6754775e85d86f1fc", size = 6683092 }, - { url = "https://files.pythonhosted.org/packages/13/73/41b7b27f169ecf368b52533edb72e56a133f9e86256e809e169362553b49/numpy-2.2.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f527d8fdb0286fd2fd97a2a96c6be17ba4232da346931d967a0630050dfd298", size = 14081422 }, - { url = "https://files.pythonhosted.org/packages/4b/04/e208ff3ae3ddfbafc05910f89546382f15a3f10186b1f56bd99f159689c2/numpy-2.2.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bce43e386c16898b91e162e5baaad90c4b06f9dcbe36282490032cec98dc8ae7", size = 16132202 }, - { url = "https://files.pythonhosted.org/packages/fe/bc/2218160574d862d5e55f803d88ddcad88beff94791f9c5f86d67bd8fbf1c/numpy-2.2.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:31504f970f563d99f71a3512d0c01a645b692b12a63630d6aafa0939e52361e6", size = 15573131 }, - { url = "https://files.pythonhosted.org/packages/a5/78/97c775bc4f05abc8a8426436b7cb1be806a02a2994b195945600855e3a25/numpy-2.2.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:81413336ef121a6ba746892fad881a83351ee3e1e4011f52e97fba79233611fd", size = 17894270 }, - { url = "https://files.pythonhosted.org/packages/b9/eb/38c06217a5f6de27dcb41524ca95a44e395e6a1decdc0c99fec0832ce6ae/numpy-2.2.4-cp313-cp313-win32.whl", hash = "sha256:f486038e44caa08dbd97275a9a35a283a8f1d2f0ee60ac260a1790e76660833c", size = 6308141 }, - { url = "https://files.pythonhosted.org/packages/52/17/d0dd10ab6d125c6d11ffb6dfa3423c3571befab8358d4f85cd4471964fcd/numpy-2.2.4-cp313-cp313-win_amd64.whl", hash = "sha256:207a2b8441cc8b6a2a78c9ddc64d00d20c303d79fba08c577752f080c4007ee3", size = 12636885 }, - { url = "https://files.pythonhosted.org/packages/fa/e2/793288ede17a0fdc921172916efb40f3cbc2aa97e76c5c84aba6dc7e8747/numpy-2.2.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:8120575cb4882318c791f839a4fd66161a6fa46f3f0a5e613071aae35b5dd8f8", size = 20961829 }, - { url = "https://files.pythonhosted.org/packages/3a/75/bb4573f6c462afd1ea5cbedcc362fe3e9bdbcc57aefd37c681be1155fbaa/numpy-2.2.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a761ba0fa886a7bb33c6c8f6f20213735cb19642c580a931c625ee377ee8bd39", size = 14161419 }, - { url = "https://files.pythonhosted.org/packages/03/68/07b4cd01090ca46c7a336958b413cdbe75002286295f2addea767b7f16c9/numpy-2.2.4-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:ac0280f1ba4a4bfff363a99a6aceed4f8e123f8a9b234c89140f5e894e452ecd", size = 5196414 }, - { url = "https://files.pythonhosted.org/packages/a5/fd/d4a29478d622fedff5c4b4b4cedfc37a00691079623c0575978d2446db9e/numpy-2.2.4-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:879cf3a9a2b53a4672a168c21375166171bc3932b7e21f622201811c43cdd3b0", size = 6709379 }, - { url = "https://files.pythonhosted.org/packages/41/78/96dddb75bb9be730b87c72f30ffdd62611aba234e4e460576a068c98eff6/numpy-2.2.4-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f05d4198c1bacc9124018109c5fba2f3201dbe7ab6e92ff100494f236209c960", size = 14051725 }, - { url = "https://files.pythonhosted.org/packages/00/06/5306b8199bffac2a29d9119c11f457f6c7d41115a335b78d3f86fad4dbe8/numpy-2.2.4-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2f085ce2e813a50dfd0e01fbfc0c12bbe5d2063d99f8b29da30e544fb6483b8", size = 16101638 }, - { url = "https://files.pythonhosted.org/packages/fa/03/74c5b631ee1ded596945c12027649e6344614144369fd3ec1aaced782882/numpy-2.2.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:92bda934a791c01d6d9d8e038363c50918ef7c40601552a58ac84c9613a665bc", size = 15571717 }, - { url = "https://files.pythonhosted.org/packages/cb/dc/4fc7c0283abe0981e3b89f9b332a134e237dd476b0c018e1e21083310c31/numpy-2.2.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:ee4d528022f4c5ff67332469e10efe06a267e32f4067dc76bb7e2cddf3cd25ff", size = 17879998 }, - { url = "https://files.pythonhosted.org/packages/e5/2b/878576190c5cfa29ed896b518cc516aecc7c98a919e20706c12480465f43/numpy-2.2.4-cp313-cp313t-win32.whl", hash = "sha256:05c076d531e9998e7e694c36e8b349969c56eadd2cdcd07242958489d79a7286", size = 6366896 }, - { url = "https://files.pythonhosted.org/packages/3e/05/eb7eec66b95cf697f08c754ef26c3549d03ebd682819f794cb039574a0a6/numpy-2.2.4-cp313-cp313t-win_amd64.whl", hash = "sha256:188dcbca89834cc2e14eb2f106c96d6d46f200fe0200310fc29089657379c58d", size = 12739119 }, -] - -[[package]] -name = "openpyxl" -version = "3.1.5" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "et-xmlfile" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/3d/f9/88d94a75de065ea32619465d2f77b29a0469500e99012523b91cc4141cd1/openpyxl-3.1.5.tar.gz", hash = "sha256:cf0e3cf56142039133628b5acffe8ef0c12bc902d2aadd3e0fe5878dc08d1050", size = 186464 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c0/da/977ded879c29cbd04de313843e76868e6e13408a94ed6b987245dc7c8506/openpyxl-3.1.5-py2.py3-none-any.whl", hash = "sha256:5282c12b107bffeef825f4617dc029afaf41d0ea60823bbb665ef3079dc79de2", size = 250910 }, -] - -[[package]] -name = "packaging" -version = "24.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", size = 163950 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451 }, -] - -[[package]] -name = "pandas" -version = "2.2.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "numpy" }, - { name = "python-dateutil" }, - { name = "pytz" }, - { name = "tzdata" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/9c/d6/9f8431bacc2e19dca897724cd097b1bb224a6ad5433784a44b587c7c13af/pandas-2.2.3.tar.gz", hash = "sha256:4f18ba62b61d7e192368b84517265a99b4d7ee8912f8708660fb4a366cc82667", size = 4399213 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/17/a3/fb2734118db0af37ea7433f57f722c0a56687e14b14690edff0cdb4b7e58/pandas-2.2.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b1d432e8d08679a40e2a6d8b2f9770a5c21793a6f9f47fdd52c5ce1948a5a8a9", size = 12529893 }, - { url = "https://files.pythonhosted.org/packages/e1/0c/ad295fd74bfac85358fd579e271cded3ac969de81f62dd0142c426b9da91/pandas-2.2.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a5a1595fe639f5988ba6a8e5bc9649af3baf26df3998a0abe56c02609392e0a4", size = 11363475 }, - { url = "https://files.pythonhosted.org/packages/c6/2a/4bba3f03f7d07207481fed47f5b35f556c7441acddc368ec43d6643c5777/pandas-2.2.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5de54125a92bb4d1c051c0659e6fcb75256bf799a732a87184e5ea503965bce3", size = 15188645 }, - { url = "https://files.pythonhosted.org/packages/38/f8/d8fddee9ed0d0c0f4a2132c1dfcf0e3e53265055da8df952a53e7eaf178c/pandas-2.2.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fffb8ae78d8af97f849404f21411c95062db1496aeb3e56f146f0355c9989319", size = 12739445 }, - { url = "https://files.pythonhosted.org/packages/20/e8/45a05d9c39d2cea61ab175dbe6a2de1d05b679e8de2011da4ee190d7e748/pandas-2.2.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6dfcb5ee8d4d50c06a51c2fffa6cff6272098ad6540aed1a76d15fb9318194d8", size = 16359235 }, - { url = "https://files.pythonhosted.org/packages/1d/99/617d07a6a5e429ff90c90da64d428516605a1ec7d7bea494235e1c3882de/pandas-2.2.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:062309c1b9ea12a50e8ce661145c6aab431b1e99530d3cd60640e255778bd43a", size = 14056756 }, - { url = "https://files.pythonhosted.org/packages/29/d4/1244ab8edf173a10fd601f7e13b9566c1b525c4f365d6bee918e68381889/pandas-2.2.3-cp312-cp312-win_amd64.whl", hash = "sha256:59ef3764d0fe818125a5097d2ae867ca3fa64df032331b7e0917cf5d7bf66b13", size = 11504248 }, - { url = "https://files.pythonhosted.org/packages/64/22/3b8f4e0ed70644e85cfdcd57454686b9057c6c38d2f74fe4b8bc2527214a/pandas-2.2.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f00d1345d84d8c86a63e476bb4955e46458b304b9575dcf71102b5c705320015", size = 12477643 }, - { url = "https://files.pythonhosted.org/packages/e4/93/b3f5d1838500e22c8d793625da672f3eec046b1a99257666c94446969282/pandas-2.2.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3508d914817e153ad359d7e069d752cdd736a247c322d932eb89e6bc84217f28", size = 11281573 }, - { url = "https://files.pythonhosted.org/packages/f5/94/6c79b07f0e5aab1dcfa35a75f4817f5c4f677931d4234afcd75f0e6a66ca/pandas-2.2.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:22a9d949bfc9a502d320aa04e5d02feab689d61da4e7764b62c30b991c42c5f0", size = 15196085 }, - { url = "https://files.pythonhosted.org/packages/e8/31/aa8da88ca0eadbabd0a639788a6da13bb2ff6edbbb9f29aa786450a30a91/pandas-2.2.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3a255b2c19987fbbe62a9dfd6cff7ff2aa9ccab3fc75218fd4b7530f01efa24", size = 12711809 }, - { url = "https://files.pythonhosted.org/packages/ee/7c/c6dbdb0cb2a4344cacfb8de1c5808ca885b2e4dcfde8008266608f9372af/pandas-2.2.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:800250ecdadb6d9c78eae4990da62743b857b470883fa27f652db8bdde7f6659", size = 16356316 }, - { url = "https://files.pythonhosted.org/packages/57/b7/8b757e7d92023b832869fa8881a992696a0bfe2e26f72c9ae9f255988d42/pandas-2.2.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6374c452ff3ec675a8f46fd9ab25c4ad0ba590b71cf0656f8b6daa5202bca3fb", size = 14022055 }, - { url = "https://files.pythonhosted.org/packages/3b/bc/4b18e2b8c002572c5a441a64826252ce5da2aa738855747247a971988043/pandas-2.2.3-cp313-cp313-win_amd64.whl", hash = "sha256:61c5ad4043f791b61dd4752191d9f07f0ae412515d59ba8f005832a532f8736d", size = 11481175 }, - { url = "https://files.pythonhosted.org/packages/76/a3/a5d88146815e972d40d19247b2c162e88213ef51c7c25993942c39dbf41d/pandas-2.2.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:3b71f27954685ee685317063bf13c7709a7ba74fc996b84fc6821c59b0f06468", size = 12615650 }, - { url = "https://files.pythonhosted.org/packages/9c/8c/f0fd18f6140ddafc0c24122c8a964e48294acc579d47def376fef12bcb4a/pandas-2.2.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:38cf8125c40dae9d5acc10fa66af8ea6fdf760b2714ee482ca691fc66e6fcb18", size = 11290177 }, - { url = "https://files.pythonhosted.org/packages/ed/f9/e995754eab9c0f14c6777401f7eece0943840b7a9fc932221c19d1abee9f/pandas-2.2.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ba96630bc17c875161df3818780af30e43be9b166ce51c9a18c1feae342906c2", size = 14651526 }, - { url = "https://files.pythonhosted.org/packages/25/b0/98d6ae2e1abac4f35230aa756005e8654649d305df9a28b16b9ae4353bff/pandas-2.2.3-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1db71525a1538b30142094edb9adc10be3f3e176748cd7acc2240c2f2e5aa3a4", size = 11871013 }, - { url = "https://files.pythonhosted.org/packages/cc/57/0f72a10f9db6a4628744c8e8f0df4e6e21de01212c7c981d31e50ffc8328/pandas-2.2.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:15c0e1e02e93116177d29ff83e8b1619c93ddc9c49083f237d4312337a61165d", size = 15711620 }, - { url = "https://files.pythonhosted.org/packages/ab/5f/b38085618b950b79d2d9164a711c52b10aefc0ae6833b96f626b7021b2ed/pandas-2.2.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:ad5b65698ab28ed8d7f18790a0dc58005c7629f227be9ecc1072aa74c0c1d43a", size = 13098436 }, -] - -[[package]] -name = "pillow" -version = "11.1.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f3/af/c097e544e7bd278333db77933e535098c259609c4eb3b85381109602fb5b/pillow-11.1.0.tar.gz", hash = "sha256:368da70808b36d73b4b390a8ffac11069f8a5c85f29eff1f1b01bcf3ef5b2a20", size = 46742715 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/95/20/9ce6ed62c91c073fcaa23d216e68289e19d95fb8188b9fb7a63d36771db8/pillow-11.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2062ffb1d36544d42fcaa277b069c88b01bb7298f4efa06731a7fd6cc290b81a", size = 3226818 }, - { url = "https://files.pythonhosted.org/packages/b9/d8/f6004d98579a2596c098d1e30d10b248798cceff82d2b77aa914875bfea1/pillow-11.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a85b653980faad27e88b141348707ceeef8a1186f75ecc600c395dcac19f385b", size = 3101662 }, - { url = "https://files.pythonhosted.org/packages/08/d9/892e705f90051c7a2574d9f24579c9e100c828700d78a63239676f960b74/pillow-11.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9409c080586d1f683df3f184f20e36fb647f2e0bc3988094d4fd8c9f4eb1b3b3", size = 4329317 }, - { url = "https://files.pythonhosted.org/packages/8c/aa/7f29711f26680eab0bcd3ecdd6d23ed6bce180d82e3f6380fb7ae35fcf3b/pillow-11.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7fdadc077553621911f27ce206ffcbec7d3f8d7b50e0da39f10997e8e2bb7f6a", size = 4412999 }, - { url = "https://files.pythonhosted.org/packages/c8/c4/8f0fe3b9e0f7196f6d0bbb151f9fba323d72a41da068610c4c960b16632a/pillow-11.1.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:93a18841d09bcdd774dcdc308e4537e1f867b3dec059c131fde0327899734aa1", size = 4368819 }, - { url = "https://files.pythonhosted.org/packages/38/0d/84200ed6a871ce386ddc82904bfadc0c6b28b0c0ec78176871a4679e40b3/pillow-11.1.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:9aa9aeddeed452b2f616ff5507459e7bab436916ccb10961c4a382cd3e03f47f", size = 4496081 }, - { url = "https://files.pythonhosted.org/packages/84/9c/9bcd66f714d7e25b64118e3952d52841a4babc6d97b6d28e2261c52045d4/pillow-11.1.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3cdcdb0b896e981678eee140d882b70092dac83ac1cdf6b3a60e2216a73f2b91", size = 4296513 }, - { url = "https://files.pythonhosted.org/packages/db/61/ada2a226e22da011b45f7104c95ebda1b63dcbb0c378ad0f7c2a710f8fd2/pillow-11.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:36ba10b9cb413e7c7dfa3e189aba252deee0602c86c309799da5a74009ac7a1c", size = 4431298 }, - { url = "https://files.pythonhosted.org/packages/e7/c4/fc6e86750523f367923522014b821c11ebc5ad402e659d8c9d09b3c9d70c/pillow-11.1.0-cp312-cp312-win32.whl", hash = "sha256:cfd5cd998c2e36a862d0e27b2df63237e67273f2fc78f47445b14e73a810e7e6", size = 2291630 }, - { url = "https://files.pythonhosted.org/packages/08/5c/2104299949b9d504baf3f4d35f73dbd14ef31bbd1ddc2c1b66a5b7dfda44/pillow-11.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:a697cd8ba0383bba3d2d3ada02b34ed268cb548b369943cd349007730c92bddf", size = 2626369 }, - { url = "https://files.pythonhosted.org/packages/37/f3/9b18362206b244167c958984b57c7f70a0289bfb59a530dd8af5f699b910/pillow-11.1.0-cp312-cp312-win_arm64.whl", hash = "sha256:4dd43a78897793f60766563969442020e90eb7847463eca901e41ba186a7d4a5", size = 2375240 }, - { url = "https://files.pythonhosted.org/packages/b3/31/9ca79cafdce364fd5c980cd3416c20ce1bebd235b470d262f9d24d810184/pillow-11.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ae98e14432d458fc3de11a77ccb3ae65ddce70f730e7c76140653048c71bfcbc", size = 3226640 }, - { url = "https://files.pythonhosted.org/packages/ac/0f/ff07ad45a1f172a497aa393b13a9d81a32e1477ef0e869d030e3c1532521/pillow-11.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cc1331b6d5a6e144aeb5e626f4375f5b7ae9934ba620c0ac6b3e43d5e683a0f0", size = 3101437 }, - { url = "https://files.pythonhosted.org/packages/08/2f/9906fca87a68d29ec4530be1f893149e0cb64a86d1f9f70a7cfcdfe8ae44/pillow-11.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:758e9d4ef15d3560214cddbc97b8ef3ef86ce04d62ddac17ad39ba87e89bd3b1", size = 4326605 }, - { url = "https://files.pythonhosted.org/packages/b0/0f/f3547ee15b145bc5c8b336401b2d4c9d9da67da9dcb572d7c0d4103d2c69/pillow-11.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b523466b1a31d0dcef7c5be1f20b942919b62fd6e9a9be199d035509cbefc0ec", size = 4411173 }, - { url = "https://files.pythonhosted.org/packages/b1/df/bf8176aa5db515c5de584c5e00df9bab0713548fd780c82a86cba2c2fedb/pillow-11.1.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:9044b5e4f7083f209c4e35aa5dd54b1dd5b112b108648f5c902ad586d4f945c5", size = 4369145 }, - { url = "https://files.pythonhosted.org/packages/de/7c/7433122d1cfadc740f577cb55526fdc39129a648ac65ce64db2eb7209277/pillow-11.1.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:3764d53e09cdedd91bee65c2527815d315c6b90d7b8b79759cc48d7bf5d4f114", size = 4496340 }, - { url = "https://files.pythonhosted.org/packages/25/46/dd94b93ca6bd555588835f2504bd90c00d5438fe131cf01cfa0c5131a19d/pillow-11.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:31eba6bbdd27dde97b0174ddf0297d7a9c3a507a8a1480e1e60ef914fe23d352", size = 4296906 }, - { url = "https://files.pythonhosted.org/packages/a8/28/2f9d32014dfc7753e586db9add35b8a41b7a3b46540e965cb6d6bc607bd2/pillow-11.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b5d658fbd9f0d6eea113aea286b21d3cd4d3fd978157cbf2447a6035916506d3", size = 4431759 }, - { url = "https://files.pythonhosted.org/packages/33/48/19c2cbe7403870fbe8b7737d19eb013f46299cdfe4501573367f6396c775/pillow-11.1.0-cp313-cp313-win32.whl", hash = "sha256:f86d3a7a9af5d826744fabf4afd15b9dfef44fe69a98541f666f66fbb8d3fef9", size = 2291657 }, - { url = "https://files.pythonhosted.org/packages/3b/ad/285c556747d34c399f332ba7c1a595ba245796ef3e22eae190f5364bb62b/pillow-11.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:593c5fd6be85da83656b93ffcccc2312d2d149d251e98588b14fbc288fd8909c", size = 2626304 }, - { url = "https://files.pythonhosted.org/packages/e5/7b/ef35a71163bf36db06e9c8729608f78dedf032fc8313d19bd4be5c2588f3/pillow-11.1.0-cp313-cp313-win_arm64.whl", hash = "sha256:11633d58b6ee5733bde153a8dafd25e505ea3d32e261accd388827ee987baf65", size = 2375117 }, - { url = "https://files.pythonhosted.org/packages/79/30/77f54228401e84d6791354888549b45824ab0ffde659bafa67956303a09f/pillow-11.1.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:70ca5ef3b3b1c4a0812b5c63c57c23b63e53bc38e758b37a951e5bc466449861", size = 3230060 }, - { url = "https://files.pythonhosted.org/packages/ce/b1/56723b74b07dd64c1010fee011951ea9c35a43d8020acd03111f14298225/pillow-11.1.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:8000376f139d4d38d6851eb149b321a52bb8893a88dae8ee7d95840431977081", size = 3106192 }, - { url = "https://files.pythonhosted.org/packages/e1/cd/7bf7180e08f80a4dcc6b4c3a0aa9e0b0ae57168562726a05dc8aa8fa66b0/pillow-11.1.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ee85f0696a17dd28fbcfceb59f9510aa71934b483d1f5601d1030c3c8304f3c", size = 4446805 }, - { url = "https://files.pythonhosted.org/packages/97/42/87c856ea30c8ed97e8efbe672b58c8304dee0573f8c7cab62ae9e31db6ae/pillow-11.1.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:dd0e081319328928531df7a0e63621caf67652c8464303fd102141b785ef9547", size = 4530623 }, - { url = "https://files.pythonhosted.org/packages/ff/41/026879e90c84a88e33fb00cc6bd915ac2743c67e87a18f80270dfe3c2041/pillow-11.1.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:e63e4e5081de46517099dc30abe418122f54531a6ae2ebc8680bcd7096860eab", size = 4465191 }, - { url = "https://files.pythonhosted.org/packages/e5/fb/a7960e838bc5df57a2ce23183bfd2290d97c33028b96bde332a9057834d3/pillow-11.1.0-cp313-cp313t-win32.whl", hash = "sha256:dda60aa465b861324e65a78c9f5cf0f4bc713e4309f83bc387be158b077963d9", size = 2295494 }, - { url = "https://files.pythonhosted.org/packages/d7/6c/6ec83ee2f6f0fda8d4cf89045c6be4b0373ebfc363ba8538f8c999f63fcd/pillow-11.1.0-cp313-cp313t-win_amd64.whl", hash = "sha256:ad5db5781c774ab9a9b2c4302bbf0c1014960a0a7be63278d13ae6fdf88126fe", size = 2631595 }, - { url = "https://files.pythonhosted.org/packages/cf/6c/41c21c6c8af92b9fea313aa47c75de49e2f9a467964ee33eb0135d47eb64/pillow-11.1.0-cp313-cp313t-win_arm64.whl", hash = "sha256:67cd427c68926108778a9005f2a04adbd5e67c442ed21d95389fe1d595458756", size = 2377651 }, -] - -[[package]] -name = "pluggy" -version = "1.5.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556 }, -] - -[[package]] -name = "probabilistic-library" -version = "25.1.1" -source = { path = "wheels/probabilistic_library-25.1.1-py3-none-any.whl" } -wheels = [ - { filename = "probabilistic_library-25.1.1-py3-none-any.whl", hash = "sha256:e99ee4c47bc507774a8bbb94d2d474dc9fd027bade99778c1ad3adc26a7fc260" }, -] - -[[package]] -name = "pybtex" -version = "0.24.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "latexcodec" }, - { name = "pyyaml" }, - { name = "six" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/46/9b/fd39836a6397fb363446d83075a7b9c2cc562f4c449292e039ed36084376/pybtex-0.24.0.tar.gz", hash = "sha256:818eae35b61733e5c007c3fcd2cfb75ed1bc8b4173c1f70b56cc4c0802d34755", size = 402879 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ad/5f/40d8e90f985a05133a8895fc454c6127ecec3de8b095dd35bba91382f803/pybtex-0.24.0-py2.py3-none-any.whl", hash = "sha256:e1e0c8c69998452fea90e9179aa2a98ab103f3eed894405b7264e517cc2fcc0f", size = 561354 }, -] - -[[package]] -name = "pybtex-docutils" -version = "1.0.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "docutils" }, - { name = "pybtex" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/7e/84/796ea94d26188a853660f81bded39f8de4cfe595130aef0dea1088705a11/pybtex-docutils-1.0.3.tar.gz", hash = "sha256:3a7ebdf92b593e00e8c1c538aa9a20bca5d92d84231124715acc964d51d93c6b", size = 18348 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/11/b1/ce1f4596211efb5410e178a803f08e59b20bedb66837dcf41e21c54f9ec1/pybtex_docutils-1.0.3-py3-none-any.whl", hash = "sha256:8fd290d2ae48e32fcb54d86b0efb8d573198653c7e2447d5bec5847095f430b9", size = 6385 }, -] - -[[package]] -name = "pygments" -version = "2.19.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7c/2d/c3338d48ea6cc0feb8446d8e6937e1408088a72a39937982cc6111d17f84/pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f", size = 4968581 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/8a/0b/9fcc47d19c48b59121088dd6da2488a49d5f72dacf8262e2790a1d2c7d15/pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c", size = 1225293 }, -] - -[[package]] -name = "pyogrio" -version = "0.10.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "certifi" }, - { name = "numpy" }, - { name = "packaging" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/a5/8f/5a784595524a79c269f2b1c880f4fdb152867df700c97005dda51997da02/pyogrio-0.10.0.tar.gz", hash = "sha256:ec051cb568324de878828fae96379b71858933413e185148acb6c162851ab23c", size = 281950 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b5/b5/3c5dfd0b50cbce6f3d4e42c0484647feb1809dbe20e225c4c6abd067e69f/pyogrio-0.10.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:2d6558b180e020f71ab7aa7f82d592ed3305c9f698d98f6d0a4637ec7a84c4ce", size = 15079211 }, - { url = "https://files.pythonhosted.org/packages/b8/9a/1ba9c707a094976f343bd0177741eaba0e842fa05ecd8ab97192db4f2ec1/pyogrio-0.10.0-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:a99102037eead8ba491bc57825c1e395ee31c9956d7bff7b4a9e4fdbff3a13c2", size = 16442782 }, - { url = "https://files.pythonhosted.org/packages/5e/bb/b4250746c2c85fea5004cae93e9e25ad01516e9e94e04de780a2e78139da/pyogrio-0.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a4c373281d7cbf560c5b61f8f3c7442103ad7f1c7ac4ef3a84572ed7a5dd2f6", size = 23899832 }, - { url = "https://files.pythonhosted.org/packages/bd/4c/79e47e40a8e54e79a45133786a0a58209534f580591c933d40c5ed314fe7/pyogrio-0.10.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:19f18411bdf836d24cdc08b9337eb3ec415e4ac4086ba64516b36b73a2e88622", size = 23081469 }, - { url = "https://files.pythonhosted.org/packages/47/78/2b62c8a340bcb0ea56b9ddf2ef5fd3d1f101dc0e98816b9e6da87c5ac3b7/pyogrio-0.10.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:1abbcdd9876f30bebf1df8a0273f6cdeb29d03259290008275c7fddebe139f20", size = 24024758 }, - { url = "https://files.pythonhosted.org/packages/43/97/34605480f06b0ad9611bf58a174eccc6f3673275f3d519cf763391892881/pyogrio-0.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:2a3e09839590d71ff832aa95c4f23fa00a2c63c3de82c1fbd4fb8d265792acfc", size = 16160294 }, - { url = "https://files.pythonhosted.org/packages/14/4a/4c8e4f5b9edbca46e0f8d6c1c0b56c0d4af0900c29f4bea22d37853c07f3/pyogrio-0.10.0-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:c90478209537a31dcc65664a87a04c094bb0e08efe502908a6682b8cec0259bf", size = 15076879 }, - { url = "https://files.pythonhosted.org/packages/5f/be/7db0644eef9ef3382518399aaf3332827c43018112d2a74f78784fd496ec/pyogrio-0.10.0-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:fec45e1963b7058e5a1aa98598aed07c0858512c833d6aad2c672c3ec98bbf04", size = 16440405 }, - { url = "https://files.pythonhosted.org/packages/96/77/f199230ba86fe88b1f57e71428c169ed982de68a32d6082cd7c12d0f5d55/pyogrio-0.10.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28cb139f8a5d0365ede602230104b407ae52bb6b55173c8d5a35424d28c4a2c5", size = 23871511 }, - { url = "https://files.pythonhosted.org/packages/25/ac/ca483bec408b59c54f7129b0244cc9de21d8461aefe89ece7bd74ad33807/pyogrio-0.10.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:cea0187fcc2d574e52af8cfab041fa0a7ad71d5ef6b94b49a3f3d2a04534a27e", size = 23048830 }, - { url = "https://files.pythonhosted.org/packages/d7/3e/c35f2d8dad95b24e568c468f09ff60fb61945065465e0ec7868400596566/pyogrio-0.10.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:7c02b207ea8cf09c501ea3e95d29152781a00d3c32267286bc36fa457c332205", size = 23996873 }, - { url = "https://files.pythonhosted.org/packages/27/5d/0deb16d228362a097ee3258d0a887c9c0add4b9678bb4847b08a241e124d/pyogrio-0.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:02e54bcfb305af75f829044b0045f74de31b77c2d6546f7aaf96822066147848", size = 16158260 }, -] - -[[package]] -name = "pyparsing" -version = "3.2.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/bb/22/f1129e69d94ffff626bdb5c835506b3a5b4f3d070f17ea295e12c2c6f60f/pyparsing-3.2.3.tar.gz", hash = "sha256:b9c13f1ab8b3b542f72e28f634bad4de758ab3ce4546e4301970ad6fa77c38be", size = 1088608 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/05/e7/df2285f3d08fee213f2d041540fa4fc9ca6c2d44cf36d3a035bf2a8d2bcc/pyparsing-3.2.3-py3-none-any.whl", hash = "sha256:a749938e02d6fd0b59b356ca504a24982314bb090c383e3cf201c95ef7e2bfcf", size = 111120 }, -] - -[[package]] -name = "pyproj" -version = "3.7.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "certifi" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/67/10/a8480ea27ea4bbe896c168808854d00f2a9b49f95c0319ddcbba693c8a90/pyproj-3.7.1.tar.gz", hash = "sha256:60d72facd7b6b79853f19744779abcd3f804c4e0d4fa8815469db20c9f640a47", size = 226339 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e6/c9/876d4345b8d17f37ac59ebd39f8fa52fc6a6a9891a420f72d050edb6b899/pyproj-3.7.1-cp312-cp312-macosx_13_0_x86_64.whl", hash = "sha256:2781029d90df7f8d431e29562a3f2d8eafdf233c4010d6fc0381858dc7373217", size = 6264087 }, - { url = "https://files.pythonhosted.org/packages/ff/e6/5f8691f8c90e7f402cc80a6276eb19d2ec1faa150d5ae2dd9c7b0a254da8/pyproj-3.7.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:d61bf8ab04c73c1da08eedaf21a103b72fa5b0a9b854762905f65ff8b375d394", size = 4669628 }, - { url = "https://files.pythonhosted.org/packages/42/ec/16475bbb79c1c68845c0a0d9c60c4fb31e61b8a2a20bc18b1a81e81c7f68/pyproj-3.7.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:04abc517a8555d1b05fcee768db3280143fe42ec39fdd926a2feef31631a1f2f", size = 9721415 }, - { url = "https://files.pythonhosted.org/packages/b3/a3/448f05b15e318bd6bea9a32cfaf11e886c4ae61fa3eee6e09ed5c3b74bb2/pyproj-3.7.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:084c0a475688f934d386c2ab3b6ce03398a473cd48adfda70d9ab8f87f2394a0", size = 9556447 }, - { url = "https://files.pythonhosted.org/packages/6a/ae/bd15fe8d8bd914ead6d60bca7f895a4e6f8ef7e3928295134ff9a7dad14c/pyproj-3.7.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a20727a23b1e49c7dc7fe3c3df8e56a8a7acdade80ac2f5cca29d7ca5564c145", size = 10758317 }, - { url = "https://files.pythonhosted.org/packages/9d/d9/5ccefb8bca925f44256b188a91c31238cae29ab6ee7f53661ecc04616146/pyproj-3.7.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:bf84d766646f1ebd706d883755df4370aaf02b48187cedaa7e4239f16bc8213d", size = 10771259 }, - { url = "https://files.pythonhosted.org/packages/2a/7d/31dedff9c35fa703162f922eeb0baa6c44a3288469a5fd88d209e2892f9e/pyproj-3.7.1-cp312-cp312-win32.whl", hash = "sha256:5f0da2711364d7cb9f115b52289d4a9b61e8bca0da57f44a3a9d6fc9bdeb7274", size = 5859914 }, - { url = "https://files.pythonhosted.org/packages/3e/47/c6ab03d6564a7c937590cff81a2742b5990f096cce7c1a622d325be340ee/pyproj-3.7.1-cp312-cp312-win_amd64.whl", hash = "sha256:aee664a9d806612af30a19dba49e55a7a78ebfec3e9d198f6a6176e1d140ec98", size = 6273196 }, - { url = "https://files.pythonhosted.org/packages/ef/01/984828464c9960036c602753fc0f21f24f0aa9043c18fa3f2f2b66a86340/pyproj-3.7.1-cp313-cp313-macosx_13_0_x86_64.whl", hash = "sha256:5f8d02ef4431dee414d1753d13fa82a21a2f61494737b5f642ea668d76164d6d", size = 6253062 }, - { url = "https://files.pythonhosted.org/packages/68/65/6ecdcdc829811a2c160cdfe2f068a009fc572fd4349664f758ccb0853a7c/pyproj-3.7.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:0b853ae99bda66cbe24b4ccfe26d70601d84375940a47f553413d9df570065e0", size = 4660548 }, - { url = "https://files.pythonhosted.org/packages/67/da/dda94c4490803679230ba4c17a12f151b307a0d58e8110820405ca2d98db/pyproj-3.7.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:83db380c52087f9e9bdd8a527943b2e7324f275881125e39475c4f9277bdeec4", size = 9662464 }, - { url = "https://files.pythonhosted.org/packages/6f/57/f61b7d22c91ae1d12ee00ac4c0038714e774ebcd851b9133e5f4f930dd40/pyproj-3.7.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b35ed213892e211a3ce2bea002aa1183e1a2a9b79e51bb3c6b15549a831ae528", size = 9497461 }, - { url = "https://files.pythonhosted.org/packages/b7/f6/932128236f79d2ac7d39fe1a19667fdf7155d9a81d31fb9472a7a497790f/pyproj-3.7.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a8b15b0463d1303bab113d1a6af2860a0d79013c3a66fcc5475ce26ef717fd4f", size = 10708869 }, - { url = "https://files.pythonhosted.org/packages/1d/0d/07ac7712994454a254c383c0d08aff9916a2851e6512d59da8dc369b1b02/pyproj-3.7.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:87229e42b75e89f4dad6459200f92988c5998dfb093c7c631fb48524c86cd5dc", size = 10729260 }, - { url = "https://files.pythonhosted.org/packages/b0/d0/9c604bc72c37ba69b867b6df724d6a5af6789e8c375022c952f65b2af558/pyproj-3.7.1-cp313-cp313-win32.whl", hash = "sha256:d666c3a3faaf3b1d7fc4a544059c4eab9d06f84a604b070b7aa2f318e227798e", size = 5855462 }, - { url = "https://files.pythonhosted.org/packages/98/df/68a2b7f5fb6400c64aad82d72bcc4bc531775e62eedff993a77c780defd0/pyproj-3.7.1-cp313-cp313-win_amd64.whl", hash = "sha256:d3caac7473be22b6d6e102dde6c46de73b96bc98334e577dfaee9886f102ea2e", size = 6266573 }, -] - -[[package]] -name = "pytest" -version = "8.3.5" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, - { name = "iniconfig" }, - { name = "packaging" }, - { name = "pluggy" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/ae/3c/c9d525a414d506893f0cd8a8d0de7706446213181570cdbd766691164e40/pytest-8.3.5.tar.gz", hash = "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845", size = 1450891 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/30/3d/64ad57c803f1fa1e963a7946b6e0fea4a70df53c1a7fed304586539c2bac/pytest-8.3.5-py3-none-any.whl", hash = "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820", size = 343634 }, -] - -[[package]] -name = "python-dateutil" -version = "2.9.0.post0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "six" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892 }, -] - -[[package]] -name = "pytz" -version = "2025.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f8/bf/abbd3cdfb8fbc7fb3d4d38d320f2441b1e7cbe29be4f23797b4a2b5d8aac/pytz-2025.2.tar.gz", hash = "sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3", size = 320884 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00", size = 509225 }, -] - -[[package]] -name = "pyyaml" -version = "6.0.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/86/0c/c581167fc46d6d6d7ddcfb8c843a4de25bdd27e4466938109ca68492292c/PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab", size = 183873 }, - { url = "https://files.pythonhosted.org/packages/a8/0c/38374f5bb272c051e2a69281d71cba6fdb983413e6758b84482905e29a5d/PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725", size = 173302 }, - { url = "https://files.pythonhosted.org/packages/c3/93/9916574aa8c00aa06bbac729972eb1071d002b8e158bd0e83a3b9a20a1f7/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5", size = 739154 }, - { url = "https://files.pythonhosted.org/packages/95/0f/b8938f1cbd09739c6da569d172531567dbcc9789e0029aa070856f123984/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425", size = 766223 }, - { url = "https://files.pythonhosted.org/packages/b9/2b/614b4752f2e127db5cc206abc23a8c19678e92b23c3db30fc86ab731d3bd/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476", size = 767542 }, - { url = "https://files.pythonhosted.org/packages/d4/00/dd137d5bcc7efea1836d6264f049359861cf548469d18da90cd8216cf05f/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48", size = 731164 }, - { url = "https://files.pythonhosted.org/packages/c9/1f/4f998c900485e5c0ef43838363ba4a9723ac0ad73a9dc42068b12aaba4e4/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", size = 756611 }, - { url = "https://files.pythonhosted.org/packages/df/d1/f5a275fdb252768b7a11ec63585bc38d0e87c9e05668a139fea92b80634c/PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", size = 140591 }, - { url = "https://files.pythonhosted.org/packages/0c/e8/4f648c598b17c3d06e8753d7d13d57542b30d56e6c2dedf9c331ae56312e/PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", size = 156338 }, - { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309 }, - { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679 }, - { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428 }, - { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361 }, - { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523 }, - { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660 }, - { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597 }, - { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527 }, - { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446 }, -] - -[[package]] -name = "requests" -version = "2.32.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "certifi" }, - { name = "charset-normalizer" }, - { name = "idna" }, - { name = "urllib3" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928 }, -] - -[[package]] -name = "roman-numerals-py" -version = "3.1.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/30/76/48fd56d17c5bdbdf65609abbc67288728a98ed4c02919428d4f52d23b24b/roman_numerals_py-3.1.0.tar.gz", hash = "sha256:be4bf804f083a4ce001b5eb7e3c0862479d10f94c936f6c4e5f250aa5ff5bd2d", size = 9017 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/53/97/d2cbbaa10c9b826af0e10fdf836e1bf344d9f0abb873ebc34d1f49642d3f/roman_numerals_py-3.1.0-py3-none-any.whl", hash = "sha256:9da2ad2fb670bcf24e81070ceb3be72f6c11c440d73bd579fbeca1e9f330954c", size = 7742 }, -] - -[[package]] -name = "scipy" -version = "1.14.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "numpy" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/62/11/4d44a1f274e002784e4dbdb81e0ea96d2de2d1045b2132d5af62cc31fd28/scipy-1.14.1.tar.gz", hash = "sha256:5a275584e726026a5699459aa72f828a610821006228e841b94275c4a7c08417", size = 58620554 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c0/04/2bdacc8ac6387b15db6faa40295f8bd25eccf33f1f13e68a72dc3c60a99e/scipy-1.14.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:631f07b3734d34aced009aaf6fedfd0eb3498a97e581c3b1e5f14a04164a456d", size = 39128781 }, - { url = "https://files.pythonhosted.org/packages/c8/53/35b4d41f5fd42f5781dbd0dd6c05d35ba8aa75c84ecddc7d44756cd8da2e/scipy-1.14.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:af29a935803cc707ab2ed7791c44288a682f9c8107bc00f0eccc4f92c08d6e07", size = 29939542 }, - { url = "https://files.pythonhosted.org/packages/66/67/6ef192e0e4d77b20cc33a01e743b00bc9e68fb83b88e06e636d2619a8767/scipy-1.14.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:2843f2d527d9eebec9a43e6b406fb7266f3af25a751aa91d62ff416f54170bc5", size = 23148375 }, - { url = "https://files.pythonhosted.org/packages/f6/32/3a6dedd51d68eb7b8e7dc7947d5d841bcb699f1bf4463639554986f4d782/scipy-1.14.1-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:eb58ca0abd96911932f688528977858681a59d61a7ce908ffd355957f7025cfc", size = 25578573 }, - { url = "https://files.pythonhosted.org/packages/f0/5a/efa92a58dc3a2898705f1dc9dbaf390ca7d4fba26d6ab8cfffb0c72f656f/scipy-1.14.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:30ac8812c1d2aab7131a79ba62933a2a76f582d5dbbc695192453dae67ad6310", size = 35319299 }, - { url = "https://files.pythonhosted.org/packages/8e/ee/8a26858ca517e9c64f84b4c7734b89bda8e63bec85c3d2f432d225bb1886/scipy-1.14.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f9ea80f2e65bdaa0b7627fb00cbeb2daf163caa015e59b7516395fe3bd1e066", size = 40849331 }, - { url = "https://files.pythonhosted.org/packages/a5/cd/06f72bc9187840f1c99e1a8750aad4216fc7dfdd7df46e6280add14b4822/scipy-1.14.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:edaf02b82cd7639db00dbff629995ef185c8df4c3ffa71a5562a595765a06ce1", size = 42544049 }, - { url = "https://files.pythonhosted.org/packages/aa/7d/43ab67228ef98c6b5dd42ab386eae2d7877036970a0d7e3dd3eb47a0d530/scipy-1.14.1-cp312-cp312-win_amd64.whl", hash = "sha256:2ff38e22128e6c03ff73b6bb0f85f897d2362f8c052e3b8ad00532198fbdae3f", size = 44521212 }, - { url = "https://files.pythonhosted.org/packages/50/ef/ac98346db016ff18a6ad7626a35808f37074d25796fd0234c2bb0ed1e054/scipy-1.14.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1729560c906963fc8389f6aac023739ff3983e727b1a4d87696b7bf108316a79", size = 39091068 }, - { url = "https://files.pythonhosted.org/packages/b9/cc/70948fe9f393b911b4251e96b55bbdeaa8cca41f37c26fd1df0232933b9e/scipy-1.14.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:4079b90df244709e675cdc8b93bfd8a395d59af40b72e339c2287c91860deb8e", size = 29875417 }, - { url = "https://files.pythonhosted.org/packages/3b/2e/35f549b7d231c1c9f9639f9ef49b815d816bf54dd050da5da1c11517a218/scipy-1.14.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:e0cf28db0f24a38b2a0ca33a85a54852586e43cf6fd876365c86e0657cfe7d73", size = 23084508 }, - { url = "https://files.pythonhosted.org/packages/3f/d6/b028e3f3e59fae61fb8c0f450db732c43dd1d836223a589a8be9f6377203/scipy-1.14.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:0c2f95de3b04e26f5f3ad5bb05e74ba7f68b837133a4492414b3afd79dfe540e", size = 25503364 }, - { url = "https://files.pythonhosted.org/packages/a7/2f/6c142b352ac15967744d62b165537a965e95d557085db4beab2a11f7943b/scipy-1.14.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b99722ea48b7ea25e8e015e8341ae74624f72e5f21fc2abd45f3a93266de4c5d", size = 35292639 }, - { url = "https://files.pythonhosted.org/packages/56/46/2449e6e51e0d7c3575f289f6acb7f828938eaab8874dbccfeb0cd2b71a27/scipy-1.14.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5149e3fd2d686e42144a093b206aef01932a0059c2a33ddfa67f5f035bdfe13e", size = 40798288 }, - { url = "https://files.pythonhosted.org/packages/32/cd/9d86f7ed7f4497c9fd3e39f8918dd93d9f647ba80d7e34e4946c0c2d1a7c/scipy-1.14.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e4f5a7c49323533f9103d4dacf4e4f07078f360743dec7f7596949149efeec06", size = 42524647 }, - { url = "https://files.pythonhosted.org/packages/f5/1b/6ee032251bf4cdb0cc50059374e86a9f076308c1512b61c4e003e241efb7/scipy-1.14.1-cp313-cp313-win_amd64.whl", hash = "sha256:baff393942b550823bfce952bb62270ee17504d02a1801d7fd0719534dfb9c84", size = 44469524 }, -] - -[[package]] -name = "setuptools" -version = "78.1.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a9/5a/0db4da3bc908df06e5efae42b44e75c81dd52716e10192ff36d0c1c8e379/setuptools-78.1.0.tar.gz", hash = "sha256:18fd474d4a82a5f83dac888df697af65afa82dec7323d09c3e37d1f14288da54", size = 1367827 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/54/21/f43f0a1fa8b06b32812e0975981f4677d28e0f3271601dc88ac5a5b83220/setuptools-78.1.0-py3-none-any.whl", hash = "sha256:3e386e96793c8702ae83d17b853fb93d3e09ef82ec62722e61da5cd22376dcd8", size = 1256108 }, -] - -[[package]] -name = "shapely" -version = "2.0.7" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "numpy" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/21/c0/a911d1fd765d07a2b6769ce155219a281bfbe311584ebe97340d75c5bdb1/shapely-2.0.7.tar.gz", hash = "sha256:28fe2997aab9a9dc026dc6a355d04e85841546b2a5d232ed953e3321ab958ee5", size = 283413 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/4f/3e/ea100eec5811bafd0175eb21828a3be5b0960f65250f4474391868be7c0f/shapely-2.0.7-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4c2b9859424facbafa54f4a19b625a752ff958ab49e01bc695f254f7db1835fa", size = 1482451 }, - { url = "https://files.pythonhosted.org/packages/ce/53/c6a3487716fd32e1f813d2a9608ba7b72a8a52a6966e31c6443480a1d016/shapely-2.0.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5aed1c6764f51011d69a679fdf6b57e691371ae49ebe28c3edb5486537ffbd51", size = 1345765 }, - { url = "https://files.pythonhosted.org/packages/fd/dd/b35d7891d25cc11066a70fb8d8169a6a7fca0735dd9b4d563a84684969a3/shapely-2.0.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:73c9ae8cf443187d784d57202199bf9fd2d4bb7d5521fe8926ba40db1bc33e8e", size = 2421540 }, - { url = "https://files.pythonhosted.org/packages/62/de/8dbd7df60eb23cb983bb698aac982944b3d602ef0ce877a940c269eae34e/shapely-2.0.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9469f49ff873ef566864cb3516091881f217b5d231c8164f7883990eec88b73", size = 2525741 }, - { url = "https://files.pythonhosted.org/packages/96/64/faf0413ebc7a84fe7a0790bf39ec0b02b40132b68e57aba985c0b6e4e7b6/shapely-2.0.7-cp312-cp312-win32.whl", hash = "sha256:6bca5095e86be9d4ef3cb52d56bdd66df63ff111d580855cb8546f06c3c907cd", size = 1296552 }, - { url = "https://files.pythonhosted.org/packages/63/05/8a1c279c226d6ad7604d9e237713dd21788eab96db97bf4ce0ea565e5596/shapely-2.0.7-cp312-cp312-win_amd64.whl", hash = "sha256:f86e2c0259fe598c4532acfcf638c1f520fa77c1275912bbc958faecbf00b108", size = 1443464 }, - { url = "https://files.pythonhosted.org/packages/c6/21/abea43effbfe11f792e44409ee9ad7635aa93ef1c8ada0ef59b3c1c3abad/shapely-2.0.7-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a0c09e3e02f948631c7763b4fd3dd175bc45303a0ae04b000856dedebefe13cb", size = 1481618 }, - { url = "https://files.pythonhosted.org/packages/d9/71/af688798da36fe355a6e6ffe1d4628449cb5fa131d57fc169bcb614aeee7/shapely-2.0.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:06ff6020949b44baa8fc2e5e57e0f3d09486cd5c33b47d669f847c54136e7027", size = 1345159 }, - { url = "https://files.pythonhosted.org/packages/67/47/f934fe2b70d31bb9774ad4376e34f81666deed6b811306ff574faa3d115e/shapely-2.0.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d6dbf096f961ca6bec5640e22e65ccdec11e676344e8157fe7d636e7904fd36", size = 2410267 }, - { url = "https://files.pythonhosted.org/packages/f5/8a/2545cc2a30afc63fc6176c1da3b76af28ef9c7358ed4f68f7c6a9d86cf5b/shapely-2.0.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:adeddfb1e22c20548e840403e5e0b3d9dc3daf66f05fa59f1fcf5b5f664f0e98", size = 2514128 }, - { url = "https://files.pythonhosted.org/packages/87/54/2344ce7da39676adec94e84fbaba92a8f1664e4ae2d33bd404dafcbe607f/shapely-2.0.7-cp313-cp313-win32.whl", hash = "sha256:a7f04691ce1c7ed974c2f8b34a1fe4c3c5dfe33128eae886aa32d730f1ec1913", size = 1295783 }, - { url = "https://files.pythonhosted.org/packages/d7/1e/6461e5cfc8e73ae165b8cff6eb26a4d65274fad0e1435137c5ba34fe4e88/shapely-2.0.7-cp313-cp313-win_amd64.whl", hash = "sha256:aaaf5f7e6cc234c1793f2a2760da464b604584fb58c6b6d7d94144fd2692d67e", size = 1442300 }, -] - -[[package]] -name = "six" -version = "1.17.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050 }, -] - -[[package]] -name = "snowballstemmer" -version = "2.2.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/44/7b/af302bebf22c749c56c9c3e8ae13190b5b5db37a33d9068652e8f73b7089/snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1", size = 86699 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ed/dc/c02e01294f7265e63a7315fe086dd1df7dacb9f840a804da846b96d01b96/snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a", size = 93002 }, -] - -[[package]] -name = "sphinx" -version = "8.2.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "alabaster" }, - { name = "babel" }, - { name = "colorama", marker = "sys_platform == 'win32'" }, - { name = "docutils" }, - { name = "imagesize" }, - { name = "jinja2" }, - { name = "packaging" }, - { name = "pygments" }, - { name = "requests" }, - { name = "roman-numerals-py" }, - { name = "snowballstemmer" }, - { name = "sphinxcontrib-applehelp" }, - { name = "sphinxcontrib-devhelp" }, - { name = "sphinxcontrib-htmlhelp" }, - { name = "sphinxcontrib-jsmath" }, - { name = "sphinxcontrib-qthelp" }, - { name = "sphinxcontrib-serializinghtml" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/38/ad/4360e50ed56cb483667b8e6dadf2d3fda62359593faabbe749a27c4eaca6/sphinx-8.2.3.tar.gz", hash = "sha256:398ad29dee7f63a75888314e9424d40f52ce5a6a87ae88e7071e80af296ec348", size = 8321876 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/31/53/136e9eca6e0b9dc0e1962e2c908fbea2e5ac000c2a2fbd9a35797958c48b/sphinx-8.2.3-py3-none-any.whl", hash = "sha256:4405915165f13521d875a8c29c8970800a0141c14cc5416a38feca4ea5d9b9c3", size = 3589741 }, -] - -[[package]] -name = "sphinxcontrib-applehelp" -version = "2.0.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ba/6e/b837e84a1a704953c62ef8776d45c3e8d759876b4a84fe14eba2859106fe/sphinxcontrib_applehelp-2.0.0.tar.gz", hash = "sha256:2f29ef331735ce958efa4734873f084941970894c6090408b079c61b2e1c06d1", size = 20053 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5d/85/9ebeae2f76e9e77b952f4b274c27238156eae7979c5421fba91a28f4970d/sphinxcontrib_applehelp-2.0.0-py3-none-any.whl", hash = "sha256:4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5", size = 119300 }, -] - -[[package]] -name = "sphinxcontrib-bibtex" -version = "2.6.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "docutils" }, - { name = "pybtex" }, - { name = "pybtex-docutils" }, - { name = "setuptools" }, - { name = "sphinx" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/c1/ce/054a8ec04063f9a27772fea7188f796edbfa382e656d3b76428323861f0e/sphinxcontrib_bibtex-2.6.3.tar.gz", hash = "sha256:7c790347ef1cb0edf30de55fc324d9782d085e89c52c2b8faafa082e08e23946", size = 117177 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/8e/49/c23f9493c0a5d5881fb7ed3002e87708454fef860aa96a48e755d27bf6f0/sphinxcontrib_bibtex-2.6.3-py3-none-any.whl", hash = "sha256:ff016b738fcc867df0f75c29e139b3b2158d26a2c802db27963cb128be3b75fb", size = 40340 }, -] - -[[package]] -name = "sphinxcontrib-devhelp" -version = "2.0.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f6/d2/5beee64d3e4e747f316bae86b55943f51e82bb86ecd325883ef65741e7da/sphinxcontrib_devhelp-2.0.0.tar.gz", hash = "sha256:411f5d96d445d1d73bb5d52133377b4248ec79db5c793ce7dbe59e074b4dd1ad", size = 12967 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/35/7a/987e583882f985fe4d7323774889ec58049171828b58c2217e7f79cdf44e/sphinxcontrib_devhelp-2.0.0-py3-none-any.whl", hash = "sha256:aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2", size = 82530 }, -] - -[[package]] -name = "sphinxcontrib-htmlhelp" -version = "2.1.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/43/93/983afd9aa001e5201eab16b5a444ed5b9b0a7a010541e0ddfbbfd0b2470c/sphinxcontrib_htmlhelp-2.1.0.tar.gz", hash = "sha256:c9e2916ace8aad64cc13a0d233ee22317f2b9025b9cf3295249fa985cc7082e9", size = 22617 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/0a/7b/18a8c0bcec9182c05a0b3ec2a776bba4ead82750a55ff798e8d406dae604/sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl", hash = "sha256:166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8", size = 98705 }, -] - -[[package]] -name = "sphinxcontrib-jsmath" -version = "1.0.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b2/e8/9ed3830aeed71f17c026a07a5097edcf44b692850ef215b161b8ad875729/sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8", size = 5787 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c2/42/4c8646762ee83602e3fb3fbe774c2fac12f317deb0b5dbeeedd2d3ba4b77/sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178", size = 5071 }, -] - -[[package]] -name = "sphinxcontrib-qthelp" -version = "2.0.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/68/bc/9104308fc285eb3e0b31b67688235db556cd5b0ef31d96f30e45f2e51cae/sphinxcontrib_qthelp-2.0.0.tar.gz", hash = "sha256:4fe7d0ac8fc171045be623aba3e2a8f613f8682731f9153bb2e40ece16b9bbab", size = 17165 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/27/83/859ecdd180cacc13b1f7e857abf8582a64552ea7a061057a6c716e790fce/sphinxcontrib_qthelp-2.0.0-py3-none-any.whl", hash = "sha256:b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb", size = 88743 }, -] - -[[package]] -name = "sphinxcontrib-serializinghtml" -version = "2.0.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/3b/44/6716b257b0aa6bfd51a1b31665d1c205fb12cb5ad56de752dfa15657de2f/sphinxcontrib_serializinghtml-2.0.0.tar.gz", hash = "sha256:e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d", size = 16080 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/52/a7/d2782e4e3f77c8450f727ba74a8f12756d5ba823d81b941f1b04da9d033a/sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl", hash = "sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331", size = 92072 }, -] - -[[package]] -name = "tzdata" -version = "2025.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/95/32/1a225d6164441be760d75c2c42e2780dc0873fe382da3e98a2e1e48361e5/tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9", size = 196380 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8", size = 347839 }, -] - -[[package]] -name = "urllib3" -version = "2.3.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/aa/63/e53da845320b757bf29ef6a9062f5c669fe997973f966045cb019c3f4b66/urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d", size = 307268 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c8/19/4ec628951a74043532ca2cf5d97b7b14863931476d117c471e8e2b1eb39f/urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df", size = 128369 }, -] diff --git a/workspaces/example_new_calculations/input/input.xlsx b/workspaces/example_new_calculations/input/input.xlsx index 617a6110..5d6d747d 100644 Binary files a/workspaces/example_new_calculations/input/input.xlsx and b/workspaces/example_new_calculations/input/input.xlsx differ diff --git a/workspaces/traject_224/input/WBI2017_Bovenrijn_224_v04.config.sqlite b/workspaces/traject_224/input/WBI2017_Bovenrijn_224_v04.config.sqlite new file mode 100644 index 00000000..73f3e89d Binary files /dev/null and b/workspaces/traject_224/input/WBI2017_Bovenrijn_224_v04.config.sqlite differ diff --git a/workspaces/traject_224/input/WBI2017_Bovenrijn_224_v04.sqlite b/workspaces/traject_224/input/WBI2017_Bovenrijn_224_v04.sqlite new file mode 100644 index 00000000..a57dfd7d Binary files /dev/null and b/workspaces/traject_224/input/WBI2017_Bovenrijn_224_v04.sqlite differ diff --git a/workspaces/traject_224/input/hlcd.sqlite b/workspaces/traject_224/input/hlcd.sqlite new file mode 100644 index 00000000..1bf2956e Binary files /dev/null and b/workspaces/traject_224/input/hlcd.sqlite differ diff --git a/workspaces/traject_224/input/hr_frequency_lines/vk0224_0001_1_WA_hm0386.csv b/workspaces/traject_224/input/hr_frequency_lines/vk0224_0001_1_WA_hm0386.csv new file mode 100644 index 00000000..dc3cf668 --- /dev/null +++ b/workspaces/traject_224/input/hr_frequency_lines/vk0224_0001_1_WA_hm0386.csv @@ -0,0 +1,85 @@ +Level,Exceedance_Frequency +3.586,5.86082403 +3.686,5.66715759 +3.786,5.37800029 +3.886,5.03955286 +3.986,4.65422534 +4.086,4.25895799 +4.186,3.87473238 +4.286,3.4946515 +4.386,3.16913082 +4.486,2.87305072 +4.586,2.60476 +4.686,2.36236175 +4.786,2.14137909 +4.886,1.95592542 +4.986,1.79941894 +5.086,1.66965893 +5.186,1.56109352 +5.286,1.45785137 +5.386,1.34839483 +5.486,1.23049159 +5.586,1.10195949 +5.686,0.972351541 +5.786,0.852178144 +5.886,0.745570882 +5.986,0.653309851 +6.086,0.57226996 +6.186,0.507372845 +6.286,0.455555565 +6.386,0.413471011 +6.486,0.377025191 +6.586,0.344538549 +6.686,0.312729867 +6.786,0.285667641 +6.886,0.260376924 +6.986,0.236387057 +7.086,0.212597359 +7.186,0.187947097 +7.286,0.163624477 +7.386,0.140761641 +7.486,0.119296711 +7.586,0.0998199898 +7.686,0.0828114163 +7.786,0.0684686435 +7.886,0.0571681563 +7.986,0.0480819547 +8.086,0.0400199856 +8.186,0.0337491654 +8.286,0.0280634018 +8.386,0.0234993639 +8.486,0.019523801 +8.586,0.0162010836 +8.686,0.0134446987 +8.786,0.0110803622 +8.886,0.00891552984 +8.986,0.00697635452 +9.086,0.00540370571 +9.186,0.00406119701 +9.286,0.00287141843 +9.386,0.00200511735 +9.486,0.00134678614 +9.586,0.000867293232 +9.686,0.000563885163 +9.786,0.000339243143 +9.886,0.000194149581 +9.986,0.000105695088 +10.086,6.29898933e-05 +10.186,3.67998314e-05 +10.286,2.21641306e-05 +10.386,1.41027935e-05 +10.486,9.02138407e-06 +10.586,5.68953915e-06 +10.686,3.55528158e-06 +10.786,2.25311343e-06 +10.886,1.40811258e-06 +10.986,9.01344258e-07 +11.086,5.60828605e-07 +11.186,3.47763638e-07 +11.286,2.15759828e-07 +11.386,1.30680626e-07 +11.486,8.06021806e-08 +11.586,4.6956722e-08 +11.686,2.60818195e-08 +11.786,1.32012175e-08 +11.886,5.8894924e-09 diff --git a/workspaces/traject_224/input/hr_frequency_lines/vk0224_0002_1_WA_hm0384.csv b/workspaces/traject_224/input/hr_frequency_lines/vk0224_0002_1_WA_hm0384.csv new file mode 100644 index 00000000..dc3cf668 --- /dev/null +++ b/workspaces/traject_224/input/hr_frequency_lines/vk0224_0002_1_WA_hm0384.csv @@ -0,0 +1,85 @@ +Level,Exceedance_Frequency +3.586,5.86082403 +3.686,5.66715759 +3.786,5.37800029 +3.886,5.03955286 +3.986,4.65422534 +4.086,4.25895799 +4.186,3.87473238 +4.286,3.4946515 +4.386,3.16913082 +4.486,2.87305072 +4.586,2.60476 +4.686,2.36236175 +4.786,2.14137909 +4.886,1.95592542 +4.986,1.79941894 +5.086,1.66965893 +5.186,1.56109352 +5.286,1.45785137 +5.386,1.34839483 +5.486,1.23049159 +5.586,1.10195949 +5.686,0.972351541 +5.786,0.852178144 +5.886,0.745570882 +5.986,0.653309851 +6.086,0.57226996 +6.186,0.507372845 +6.286,0.455555565 +6.386,0.413471011 +6.486,0.377025191 +6.586,0.344538549 +6.686,0.312729867 +6.786,0.285667641 +6.886,0.260376924 +6.986,0.236387057 +7.086,0.212597359 +7.186,0.187947097 +7.286,0.163624477 +7.386,0.140761641 +7.486,0.119296711 +7.586,0.0998199898 +7.686,0.0828114163 +7.786,0.0684686435 +7.886,0.0571681563 +7.986,0.0480819547 +8.086,0.0400199856 +8.186,0.0337491654 +8.286,0.0280634018 +8.386,0.0234993639 +8.486,0.019523801 +8.586,0.0162010836 +8.686,0.0134446987 +8.786,0.0110803622 +8.886,0.00891552984 +8.986,0.00697635452 +9.086,0.00540370571 +9.186,0.00406119701 +9.286,0.00287141843 +9.386,0.00200511735 +9.486,0.00134678614 +9.586,0.000867293232 +9.686,0.000563885163 +9.786,0.000339243143 +9.886,0.000194149581 +9.986,0.000105695088 +10.086,6.29898933e-05 +10.186,3.67998314e-05 +10.286,2.21641306e-05 +10.386,1.41027935e-05 +10.486,9.02138407e-06 +10.586,5.68953915e-06 +10.686,3.55528158e-06 +10.786,2.25311343e-06 +10.886,1.40811258e-06 +10.986,9.01344258e-07 +11.086,5.60828605e-07 +11.186,3.47763638e-07 +11.286,2.15759828e-07 +11.386,1.30680626e-07 +11.486,8.06021806e-08 +11.586,4.6956722e-08 +11.686,2.60818195e-08 +11.786,1.32012175e-08 +11.886,5.8894924e-09 diff --git a/workspaces/traject_224/input/input.xlsx b/workspaces/traject_224/input/input.xlsx new file mode 100644 index 00000000..0d7905c8 Binary files /dev/null and b/workspaces/traject_224/input/input.xlsx differ diff --git a/workspaces/traject_224/input_v1.xlsx b/workspaces/traject_224/input_v1.xlsx new file mode 100644 index 00000000..76618c03 Binary files /dev/null and b/workspaces/traject_224/input_v1.xlsx differ diff --git a/workspaces/traject_224/input_v2.xlsx b/workspaces/traject_224/input_v2.xlsx new file mode 100644 index 00000000..011a3338 Binary files /dev/null and b/workspaces/traject_224/input_v2.xlsx differ diff --git a/workspaces/traject_224/input_v3_in_use.xlsx b/workspaces/traject_224/input_v3_in_use.xlsx new file mode 100644 index 00000000..ec53d255 Binary files /dev/null and b/workspaces/traject_224/input_v3_in_use.xlsx differ