From c349a7c864e3d01aed2bdfcc6a7da269f2ee81bc Mon Sep 17 00:00:00 2001 From: Michael Maier-Gerber Date: Thu, 24 Apr 2025 13:26:02 +0200 Subject: [PATCH 1/5] replaced channel "defaults" in environment.yml by "nodefaults" --- environment.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/environment.yml b/environment.yml index fd706d3..301bb4d 100644 --- a/environment.yml +++ b/environment.yml @@ -1,7 +1,7 @@ name: shearwater channels: - conda-forge -- defaults +- nodefaults dependencies: - pip - python>=3.9,<3.12 From 464d70b816560d099eb2c44b7a31b2a077039662 Mon Sep 17 00:00:00 2001 From: Michael Maier-Gerber Date: Fri, 9 May 2025 10:47:14 +0200 Subject: [PATCH 2/5] various fixes --- README.rst | 7 +- environment.yml | 3 +- notebooks/first_test.ipynb | 120 +++--- shearwater/default.cfg | 2 +- shearwater/processes/wps_cyclone.py | 474 ++++++++++++--------- shearwater/processes/wps_cyclone_backup.py | 297 +++++++++++++ 6 files changed, 648 insertions(+), 255 deletions(-) create mode 100644 shearwater/processes/wps_cyclone_backup.py diff --git a/README.rst b/README.rst index eceafc6..f3c4b31 100644 --- a/README.rst +++ b/README.rst @@ -24,7 +24,12 @@ ShearWater ShearWater (the bird) *ShearWater is a bird to perform detection and forecast of tropical cyclone activity.* -This WPS is designed to perform detection and forecast of tropical-cyclone activities. +This WPS is designed to perform detection and forecast of tropical-cyclone activities. In particular, the work at the basis of this WPS focuses on predicting the probability of TC activity in some regions of interest, therefore considering spatio-temporally distributed input features and target variable, in the form of gridded data with daily values. The main purpose of this work resides in daily predictions of the probability of TC activity. For this reason, the problem is formulated as a classification problem with binary targets, where the evaluation takes into account the calibration of the predicted probabilities. The target variable, derived from the International Best Track Archive for Climate Stewardship (IBTrACS), is defined as the occurrence of at least one TC exceeding tropical storm strength (>= 17m/s) evaluated within a 48-hour time window and a radius of 300 km at each grid point in the region of interest. Meteorologically relevant features are taken from the ERA5 atmospheric reanalysis dataset, produced by the Copernicus Climate Change Service at ECMWF. The training dataset covers the years 1980 to 2010, providing a substantial amount of historical data to build a robust predictive model (11323 daily values). The validation dataset includes the years from 2011 to 2015 (1826 daily values), allowing for the evaluation and fine-tuning of the model performance. Finally, the test dataset spans from 15 April 2016 to 31 December 2022 (2452 daily values). Additionally, a live connection to the ERA5 catalogue will be implemented as a next step, to enable this WPS to produce forecasts spanning from 15 April 2016 to the current day. + +Three main hyperparameters are the core of this WPS. +Firstly, a region can be selected among six possibilities available, covering the six main basins where TC activity is particularly relevant: Southern India, North Atlantic, North-West Pacific, Australia, Northern India, East Pacific. The current implementation of the WPS only includes the Southern India region, while the other regions will be available in next releases. +Then, an interval of dates can be selected spanning from 15 April 2016 to the current day, depending on the period of interest of the user for the detection/forecast. As mentioned, the current implementation only spans from 15 April 2016 to 31 December 2022, and it will be updated in next releases. For each selected date, the forecast for each of the subsequent 14 days is provided. If these dates are in the past, the user can validate the forecast skills of the selected model w.r.t. other forecasts. If these days are in the future, this can be actually considered as a forecast. The current implementation only performs the forecast of the TC activity of the current day, next releases will include the forecast in the subsequent 14 days. +Finally, the user can select the model of interest. The default model is a purely data-driven model, based on a Unet implementation that takes a set of meteorological features as inputs, treating them as channels of an image, and it produces the forecast of prediction probabilities, in the shape of as a grayscale image. Future implementations will include two additional models with different characteristics: the ECMWF’s ensemble forecast system, that produces a forecast based on climate models, and an hybrid approach, that combines a detection phase based on machine learning (the Unet mentioned above), with a forecast of the meteorological features based climate models. This way, the skillfullness of climate models in forecasting meteorological variables is combined with the skillfullness of the Unet to perform detection (i.e., extract TC activity from meteorological variables without lags). Documentation ------------- diff --git a/environment.yml b/environment.yml index 301bb4d..c10913e 100644 --- a/environment.yml +++ b/environment.yml @@ -23,4 +23,5 @@ dependencies: - pytest - pandoc - metview -- metview-python \ No newline at end of file +- metview-python +- matplotlib \ No newline at end of file diff --git a/notebooks/first_test.ipynb b/notebooks/first_test.ipynb index 43e4f60..2e33206 100644 --- a/notebooks/first_test.ipynb +++ b/notebooks/first_test.ipynb @@ -10,7 +10,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "2024-10-09 17:25:33.409107: I tensorflow/core/platform/cpu_feature_guard.cc:182] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations.\n", + "2025-05-09 10:42:14.287886: I tensorflow/core/platform/cpu_feature_guard.cc:182] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations.\n", "To enable the following instructions: SSE4.1 SSE4.2 AVX AVX2 FMA, in other operations, rebuild TensorFlow with the appropriate compiler flags.\n" ] } @@ -19,7 +19,8 @@ "import numpy as np\n", "import pandas as pd\n", "from birdy import WPSClient\n", - "from keras import models" + "from keras import models\n", + "from IPython.display import Image" ] }, { @@ -37,19 +38,19 @@ "Help on WPSClient in module birdy.client.base:\n", "\n", "\n", - " A WPS for forecasting ctropical-cyclone activities.\n", + " A WPS for tropical cyclone activity forecasting.\n", " \n", " Processes\n", " ---------\n", " \n", " cyclone\n", - " A process to forecast tropical cyclone activity.\n", + " A process to forecast tropical cyclone activity in tropical ocean basins up to 15 days ahead.\n", "\n" ] } ], "source": [ - "url = \"http://localhost:5000/wps\"\n", + "url = \"http://localhost:5008/wps\"\n", "# url = \"https://shearwater.copernicus-climate.eu/wps\"\n", "\n", "wps = WPSClient(url, verify=False)\n", @@ -58,41 +59,35 @@ }, { "cell_type": "code", - "execution_count": 4, - "id": "c5419eca-ac01-43ed-b54b-861f4232b69d", + "execution_count": 3, + "id": "fcc0024d-1374-4084-a24d-8d094508fa9a", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n" + ] + } + ], "source": [ - "# for day in range(1,30):\n", - "# print(day)\n", - "# if day<10:\n", - "# resp = wps.cyclone(init_date=f\"2022-01-0{day}\", leadtime=\"0-48 h\", region=\"Southern Indian\")\n", - "# else:\n", - "# resp = wps.cyclone(init_date=f\"2022-01-{day}\", leadtime=\"0-48 h\", region=\"Southern Indian\")\n", - "# print(resp)\n", - "# print(resp.get())\n", - "# " + "resp = wps.cyclone(init_date=\"2024-07-03\", leadtime=\"0-48 h\", region=\"North Atlantic\")\n", + "print(resp)" ] }, { "cell_type": "code", "execution_count": 4, - "id": "fcc0024d-1374-4084-a24d-8d094508fa9a", + "id": "b4ef4a6e-2b72-4bac-911d-baea247b32ca", "metadata": {}, "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n" - ] - }, { "data": { "text/plain": [ "cycloneResponse(\n", - " output_csv='http://localhost:5000/outputs/bac8a806-8624-11ef-9aeb-080038c050cd/tcactivity_48_17_20240701_lag0_Sindian.csv',\n", - " output_png='http://localhost:5000/outputs/bac8a806-8624-11ef-9aeb-080038c050cd/tcactivity_48_17_20240701_lag0_Sindian.1.png'\n", + " output_csv='',\n", + " output_png=''\n", ")" ] }, @@ -102,47 +97,72 @@ } ], "source": [ - "resp = wps.cyclone(init_date=\"2024-07-01\", leadtime=\"0-48 h\", region=\"North Atlantic\")\n", - "print(resp)\n", "resp.get()" ] }, { "cell_type": "code", - "execution_count": 3, - "id": "dc2b0678-6b9a-4c45-8152-30b293ae434d", + "execution_count": 5, + "id": "da54f9e8-c908-4a10-9fb5-d035ac87f5a8", "metadata": {}, "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n" - ] - }, - { - "ename": "ProcessFailed", - "evalue": "Sorry, process failed.", + "ename": "FileNotFoundError", + "evalue": "[Errno 2] No such file or directory: ''", "output_type": "error", "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mProcessFailed\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[3], line 3\u001b[0m\n\u001b[1;32m 1\u001b[0m resp \u001b[38;5;241m=\u001b[39m wps\u001b[38;5;241m.\u001b[39mcyclone(init_date\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m2024-06-29\u001b[39m\u001b[38;5;124m\"\u001b[39m, leadtime\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m48-96 h\u001b[39m\u001b[38;5;124m\"\u001b[39m, region\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mNorth Atlantic\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 2\u001b[0m \u001b[38;5;28mprint\u001b[39m(resp)\n\u001b[0;32m----> 3\u001b[0m \u001b[43mresp\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m/work/bk1318/b382633/conda/envs/shearwater/lib/python3.11/site-packages/birdy/client/outputs.py:40\u001b[0m, in \u001b[0;36mWPSResult.get\u001b[0;34m(self, asobj)\u001b[0m\n\u001b[1;32m 37\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m ProcessIsNotComplete(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mPlease wait ...\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 38\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39misSucceded():\n\u001b[1;32m 39\u001b[0m \u001b[38;5;66;03m# TODO: add reason for failure\u001b[39;00m\n\u001b[0;32m---> 40\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m ProcessFailed(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mSorry, process failed.\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 41\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_make_output(asobj)\n", - "\u001b[0;31mProcessFailed\u001b[0m: Sorry, process failed." + "\u001b[31m---------------------------------------------------------------------------\u001b[39m", + "\u001b[31mFileNotFoundError\u001b[39m Traceback (most recent call last)", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[5]\u001b[39m\u001b[32m, line 2\u001b[39m\n\u001b[32m 1\u001b[39m result_url = resp.get()[\u001b[32m0\u001b[39m]\n\u001b[32m----> \u001b[39m\u001b[32m2\u001b[39m df = \u001b[43mpd\u001b[49m\u001b[43m.\u001b[49m\u001b[43mread_csv\u001b[49m\u001b[43m(\u001b[49m\u001b[43mresult_url\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 3\u001b[39m df\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/.conda/envs/shearwater/lib/python3.11/site-packages/pandas/io/parsers/readers.py:1026\u001b[39m, in \u001b[36mread_csv\u001b[39m\u001b[34m(filepath_or_buffer, sep, delimiter, header, names, index_col, usecols, dtype, engine, converters, true_values, false_values, skipinitialspace, skiprows, skipfooter, nrows, na_values, keep_default_na, na_filter, verbose, skip_blank_lines, parse_dates, infer_datetime_format, keep_date_col, date_parser, date_format, dayfirst, cache_dates, iterator, chunksize, compression, thousands, decimal, lineterminator, quotechar, quoting, doublequote, escapechar, comment, encoding, encoding_errors, dialect, on_bad_lines, delim_whitespace, low_memory, memory_map, float_precision, storage_options, dtype_backend)\u001b[39m\n\u001b[32m 1013\u001b[39m kwds_defaults = _refine_defaults_read(\n\u001b[32m 1014\u001b[39m dialect,\n\u001b[32m 1015\u001b[39m delimiter,\n\u001b[32m (...)\u001b[39m\u001b[32m 1022\u001b[39m dtype_backend=dtype_backend,\n\u001b[32m 1023\u001b[39m )\n\u001b[32m 1024\u001b[39m kwds.update(kwds_defaults)\n\u001b[32m-> \u001b[39m\u001b[32m1026\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43m_read\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfilepath_or_buffer\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mkwds\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/.conda/envs/shearwater/lib/python3.11/site-packages/pandas/io/parsers/readers.py:620\u001b[39m, in \u001b[36m_read\u001b[39m\u001b[34m(filepath_or_buffer, kwds)\u001b[39m\n\u001b[32m 617\u001b[39m _validate_names(kwds.get(\u001b[33m\"\u001b[39m\u001b[33mnames\u001b[39m\u001b[33m\"\u001b[39m, \u001b[38;5;28;01mNone\u001b[39;00m))\n\u001b[32m 619\u001b[39m \u001b[38;5;66;03m# Create the parser.\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m620\u001b[39m parser = \u001b[43mTextFileReader\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfilepath_or_buffer\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwds\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 622\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m chunksize \u001b[38;5;129;01mor\u001b[39;00m iterator:\n\u001b[32m 623\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m parser\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/.conda/envs/shearwater/lib/python3.11/site-packages/pandas/io/parsers/readers.py:1620\u001b[39m, in \u001b[36mTextFileReader.__init__\u001b[39m\u001b[34m(self, f, engine, **kwds)\u001b[39m\n\u001b[32m 1617\u001b[39m \u001b[38;5;28mself\u001b[39m.options[\u001b[33m\"\u001b[39m\u001b[33mhas_index_names\u001b[39m\u001b[33m\"\u001b[39m] = kwds[\u001b[33m\"\u001b[39m\u001b[33mhas_index_names\u001b[39m\u001b[33m\"\u001b[39m]\n\u001b[32m 1619\u001b[39m \u001b[38;5;28mself\u001b[39m.handles: IOHandles | \u001b[38;5;28;01mNone\u001b[39;00m = \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[32m-> \u001b[39m\u001b[32m1620\u001b[39m \u001b[38;5;28mself\u001b[39m._engine = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_make_engine\u001b[49m\u001b[43m(\u001b[49m\u001b[43mf\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mengine\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/.conda/envs/shearwater/lib/python3.11/site-packages/pandas/io/parsers/readers.py:1880\u001b[39m, in \u001b[36mTextFileReader._make_engine\u001b[39m\u001b[34m(self, f, engine)\u001b[39m\n\u001b[32m 1878\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[33m\"\u001b[39m\u001b[33mb\u001b[39m\u001b[33m\"\u001b[39m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;129;01min\u001b[39;00m mode:\n\u001b[32m 1879\u001b[39m mode += \u001b[33m\"\u001b[39m\u001b[33mb\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m-> \u001b[39m\u001b[32m1880\u001b[39m \u001b[38;5;28mself\u001b[39m.handles = \u001b[43mget_handle\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 1881\u001b[39m \u001b[43m \u001b[49m\u001b[43mf\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1882\u001b[39m \u001b[43m \u001b[49m\u001b[43mmode\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1883\u001b[39m \u001b[43m \u001b[49m\u001b[43mencoding\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43moptions\u001b[49m\u001b[43m.\u001b[49m\u001b[43mget\u001b[49m\u001b[43m(\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mencoding\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1884\u001b[39m \u001b[43m \u001b[49m\u001b[43mcompression\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43moptions\u001b[49m\u001b[43m.\u001b[49m\u001b[43mget\u001b[49m\u001b[43m(\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mcompression\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1885\u001b[39m \u001b[43m \u001b[49m\u001b[43mmemory_map\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43moptions\u001b[49m\u001b[43m.\u001b[49m\u001b[43mget\u001b[49m\u001b[43m(\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mmemory_map\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1886\u001b[39m \u001b[43m \u001b[49m\u001b[43mis_text\u001b[49m\u001b[43m=\u001b[49m\u001b[43mis_text\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1887\u001b[39m \u001b[43m \u001b[49m\u001b[43merrors\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43moptions\u001b[49m\u001b[43m.\u001b[49m\u001b[43mget\u001b[49m\u001b[43m(\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mencoding_errors\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mstrict\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1888\u001b[39m \u001b[43m \u001b[49m\u001b[43mstorage_options\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43moptions\u001b[49m\u001b[43m.\u001b[49m\u001b[43mget\u001b[49m\u001b[43m(\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mstorage_options\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1889\u001b[39m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 1890\u001b[39m \u001b[38;5;28;01massert\u001b[39;00m \u001b[38;5;28mself\u001b[39m.handles \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[32m 1891\u001b[39m f = \u001b[38;5;28mself\u001b[39m.handles.handle\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/.conda/envs/shearwater/lib/python3.11/site-packages/pandas/io/common.py:873\u001b[39m, in \u001b[36mget_handle\u001b[39m\u001b[34m(path_or_buf, mode, encoding, compression, memory_map, is_text, errors, storage_options)\u001b[39m\n\u001b[32m 868\u001b[39m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(handle, \u001b[38;5;28mstr\u001b[39m):\n\u001b[32m 869\u001b[39m \u001b[38;5;66;03m# Check whether the filename is to be opened in binary mode.\u001b[39;00m\n\u001b[32m 870\u001b[39m \u001b[38;5;66;03m# Binary mode does not support 'encoding' and 'newline'.\u001b[39;00m\n\u001b[32m 871\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m ioargs.encoding \u001b[38;5;129;01mand\u001b[39;00m \u001b[33m\"\u001b[39m\u001b[33mb\u001b[39m\u001b[33m\"\u001b[39m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;129;01min\u001b[39;00m ioargs.mode:\n\u001b[32m 872\u001b[39m \u001b[38;5;66;03m# Encoding\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m873\u001b[39m handle = \u001b[38;5;28;43mopen\u001b[39;49m\u001b[43m(\u001b[49m\n\u001b[32m 874\u001b[39m \u001b[43m \u001b[49m\u001b[43mhandle\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 875\u001b[39m \u001b[43m \u001b[49m\u001b[43mioargs\u001b[49m\u001b[43m.\u001b[49m\u001b[43mmode\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 876\u001b[39m \u001b[43m \u001b[49m\u001b[43mencoding\u001b[49m\u001b[43m=\u001b[49m\u001b[43mioargs\u001b[49m\u001b[43m.\u001b[49m\u001b[43mencoding\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 877\u001b[39m \u001b[43m \u001b[49m\u001b[43merrors\u001b[49m\u001b[43m=\u001b[49m\u001b[43merrors\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 878\u001b[39m \u001b[43m \u001b[49m\u001b[43mnewline\u001b[49m\u001b[43m=\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[32m 879\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 880\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 881\u001b[39m \u001b[38;5;66;03m# Binary mode\u001b[39;00m\n\u001b[32m 882\u001b[39m handle = \u001b[38;5;28mopen\u001b[39m(handle, ioargs.mode)\n", + "\u001b[31mFileNotFoundError\u001b[39m: [Errno 2] No such file or directory: ''" ] } ], "source": [ - "resp = wps.cyclone(init_date=\"2024-06-29\", leadtime=\"48-96 h\", region=\"North Atlantic\")\n", - "print(resp)\n", - "resp.get()" + "result_url = resp.get()[0]\n", + "df = pd.read_csv(result_url)\n", + "df" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c269bf61-4e5c-4d78-b942-9f06e29e05f1", + "metadata": {}, + "outputs": [], + "source": [ + "result_url = resp.get()[1]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "250a9f8b-66c5-4aa3-bab8-f15bef5c3e18", + "metadata": {}, + "outputs": [], + "source": [ + "! wget $result_url -P /home/b/b382611/shearwater" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "27002ace-ce96-475c-81df-79a22eea8cfc", + "metadata": {}, + "outputs": [], + "source": [ + "Image(result_url)" ] }, { "cell_type": "code", "execution_count": null, - "id": "85251270-6efb-413b-892d-63372ad41e3a", + "id": "722ee197-a908-4c63-a780-b79d2a75b181", "metadata": {}, "outputs": [], "source": [] @@ -164,7 +184,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.10" + "version": "3.11.12" } }, "nbformat": 4, diff --git a/shearwater/default.cfg b/shearwater/default.cfg index 135c500..d3822b9 100644 --- a/shearwater/default.cfg +++ b/shearwater/default.cfg @@ -1,6 +1,6 @@ [metadata:main] identification_title = ShearWater -identification_abstract = A WPS for forecasting ctropical-cyclone activities. +identification_abstract = A WPS for tropical cyclone activity forecasting. identification_keywords = PyWPS, WPS, OGC, processing, birdhouse, shearwater, demo identification_keywords_type = theme provider_name = ShearWater diff --git a/shearwater/processes/wps_cyclone.py b/shearwater/processes/wps_cyclone.py index 1cbf8f1..765db14 100644 --- a/shearwater/processes/wps_cyclone.py +++ b/shearwater/processes/wps_cyclone.py @@ -7,7 +7,14 @@ from pywps import FORMATS, Format from pathlib import Path import urllib.request -import metview as mv +import xarray as xr +try: + import metview as mv +except Exception: + print("sorry ... no metview") + print(f"{os.environ}") + mv = None +import matplotlib.pyplot as plt import logging LOGGER = logging.getLogger("PYWPS") @@ -16,15 +23,15 @@ class Cyclone(Process): - """A process to forecast tropical cyclone activities.""" + """A process to forecast tropical cyclone activity.""" def __init__(self): inputs = [ LiteralInput( "init_date", "Initialisation date", data_type="string", - abstract="Enter the initialisation date, like 2024-02-17", - default="2024-02-17" + abstract="Enter an initialisation date between 1940-01-01 and 2024-12-31.", + default="2024-07-03" ), LiteralInput( "leadtime", @@ -55,26 +62,26 @@ def __init__(self): data_type="string", abstract="Choose the region of your interest", allowed_values=[ - "Southern Indian", - "North Atlantic", - "Northwest Pacific", "Australia", - "Northern Indian", "East Pacific", + "North Atlantic", + "Northern Indian", + "Northwest Pacific", "South Pacific", + "Southern Indian", ], - default="Southern Indian", + default="North Atlantic", ) ] outputs = [ ComplexOutput('output_csv', - 'Cyclone activity forecast', + 'Tropical cyclone activity forecast', abstract='csv file', as_reference=True, keywords=['output', 'result', 'response'], supported_formats=[FORMATS.CSV],), ComplexOutput("output_png", - "Cyclone activity forecast", + "Tropical cyclone activity forecast", abstract="png file", as_reference=True, supported_formats=[FORMAT_PNG],), @@ -83,9 +90,8 @@ def __init__(self): super(Cyclone, self).__init__( self._handler, identifier='cyclone', - title='Cyclone', - abstract='A process to forecast tropical cyclone activity.', - # keywords=['hello', 'demo'], + title='Tropical cyclone activity', + abstract='A process to forecast tropical cyclone activity in tropical ocean basins up to 15 days ahead.', metadata=[ Metadata('PyWPS', 'https://pywps.org/'), ], @@ -97,201 +103,265 @@ def __init__(self): ) def _handler(self, request, response): - LOGGER.info("running cyclone ...") + LOGGER.info("Running tropical cyclone activity process ...") # TODO: lazy load tensorflow ... issues with sphinx doc build - from tensorflow.keras import models - - init_date = request.inputs['init_date'][0].data - - leadtime = request.inputs['leadtime'][0].data - region = request.inputs['region'][0].data - - parameters = [ - [138, "vo", [850]], - [157, "r", [700]], - [131, "u", [200, 850]], - [132, "v", [200, 850]], - [34, "sst", [0]], - [137, "tcwv", [0]], - ] - reso = 2.5 - - regions_dict = { - "Southern Indian": [0, 20, -30, 90], # Southern Indian - "North Atlantic": [40, -90, 10, -20], # North Atlantic - "Northwest Pacific": [35, 100, 5, 170], # Northwest Pacific - "Australia": [0, 90, -30, 160], # Australia - "Northern Indian": [30, 30, 0, 100], # Northern Indian - "East Pacific": [30, -170, 0, -100], # East Pacific - "South Pacific": [0, 160, -30, 230], # South Pacific - } - - lags_dict = { - "0-48 h": 0, - "24-72 h": 1, - "48-96 h": 2, - "72-120 h": 3, - "96-144 h": 4, - "120-168 h": 5, - "144-192 h": 6, - "168-216 h": 7, - "192-240 h": 8, - "216-264 h": 9, - "240-288 h": 10, - "264-312 h": 11, - "288-336 h": 12, - "312-360 h": 13, + try: + from tensorflow.keras import models + except Exception as ex: + msg = 'models from tensorflow.keras could not be imported.' + LOGGER.error(msg) + + try: + init_date = request.inputs['init_date'][0].data + LOGGER.info(init_date) + leadtime = request.inputs['leadtime'][0].data + LOGGER.info(leadtime) + region = request.inputs['region'][0].data + LOGGER.info(region) + except Exception as ex: + msg = 'Input variables could not be set.' + LOGGER.error(msg) + + ### Check validity of input date + if ((pd.Timestamp(init_date)>=pd.Timestamp('1940-01-01')) & (pd.Timestamp(init_date)<=pd.Timestamp('2024-12-31'))): + msg = 'Input date is valid.' + LOGGER.info(msg) + + parameters = [ + [138, "vo", [850]], + [157, "r", [700]], + [131, "u", [200, 850]], + [132, "v", [200, 850]], + [34, "sst", [0]], + [137, "tcwv", [0]], + ] + reso = 2.5 + + regions_dict = { + "Southern Indian": [0, 20, -30, 90], # Southern Indian + "North Atlantic": [40, -90, 10, -20], # North Atlantic + "Northwest Pacific": [35, 100, 5, 170], # Northwest Pacific + "Australia": [0, 90, -30, 160], # Australia + "Northern Indian": [30, 30, 0, 100], # Northern Indian + "East Pacific": [30, -170, 0, -100], # East Pacific + "South Pacific": [0, 160, -30, 230], # South Pacific } - - region_bbox = regions_dict[region] - lag = lags_dict[leadtime] - - data = pd.DataFrame() - for param1 in parameters: - path = f'/pool/data/ERA5/E5/{"sf" if param1[2]==[0] else "pl"}/an/1D/{str(param1[0]).zfill(3)}' - fs1_param = mv.read( - f"{path}/E5{'sf' if param1[2]==[0] else 'pl'}00_1D_{init_date[:7]}_{str(param1[0]).zfill(3)}.grb" - ) - fs1_param = fs1_param.select( - date=init_date.replace("-", ""), level=param1[2] - ) - fs1_param_interp = mv.read( - data=fs1_param, - grid=[reso, reso], - area=region_bbox, - interpolation='"--interpolation=grid-box-average"', - ) - for level in param1[2]: - data.loc[ - :, - f"{param1[1]}{'_'+str(level) if (param1[1]=='u' or param1[1]=='v') else ''}", - ] = ( + + lags_dict = { + "0-48 h": 0, + "24-72 h": 1, + "48-96 h": 2, + "72-120 h": 3, + "96-144 h": 4, + "120-168 h": 5, + "144-192 h": 6, + "168-216 h": 7, + "192-240 h": 8, + "216-264 h": 9, + "240-288 h": 10, + "264-312 h": 11, + "288-336 h": 12, + "312-360 h": 13, + } + + region_string = { + "Southern Indian": "Sindian", # Southern Indian + "North Atlantic": "Natlantic", # North Atlantic + "Northwest Pacific": "NWpacific", # Northwest Pacific + "Australia": "Australia", # Australia + "Northern Indian": "Nindian", # Northern Indian + "East Pacific": "Epacific", # East Pacific + "South Pacific": "Spacific", # South Pacific + } + + region_bbox = regions_dict[region] + lag = lags_dict[leadtime] + + data = pd.DataFrame() + + if mv: + for param1 in parameters: + path = f'/pool/data/ERA5/E5/{"sf" if param1[2]==[0] else "pl"}/an/1D/{str(param1[0]).zfill(3)}' + fs1_param = mv.read( + f"{path}/E5{'sf' if param1[2]==[0] else 'pl'}00_1D_{init_date[:7]}_{str(param1[0]).zfill(3)}.grb" + ) + fs1_param = fs1_param.select( + date=init_date.replace("-", ""), level=param1[2] + ) + fs1_param_interp = mv.read( + data=fs1_param, + grid=[reso, reso], + area=region_bbox, + interpolation='"--interpolation=grid-box-average"', + ) + for level in param1[2]: + data.loc[ + :, + f"{param1[1]}{'_'+str(level) if (param1[1]=='u' or param1[1]=='v') else ''}", + ] = ( + fs1_param_interp.select(level=level) + .to_dataset() + .to_dataframe() + .reset_index(drop=True)[param1[1]] + ) + + data.loc[:, ["latitude", "longitude"]] = ( fs1_param_interp.select(level=level) .to_dataset() .to_dataframe() - .reset_index(drop=True)[param1[1]] + .reset_index()[["latitude", "longitude"]] ) - - data.loc[:, ["latitude", "longitude"]] = ( - fs1_param_interp.select(level=level) - .to_dataset() - .to_dataframe() - .reset_index()[["latitude", "longitude"]] - ) - data.loc[:, "time"] = init_date - data.loc[:, "shear"] = ( - (data.u_200 - data.u_850) ** 2 + (data.v_200 - data.v_850) ** 2 - ) ** 0.5 - data.loc[:, "sst"] = data.sst.fillna(0) - - variables = [ - "vo", - "r", - "u_200", - "u_850", - "v_200", - "v_850", - "tcwv", - "sst", - "shear", - ] - - means, stds = pd.read_pickle( - "https://github.com/climateintelligence/shearwater/raw/main/data/full_statistics.zip") - - data[variables] = (data[variables]-means[variables])/stds[variables] - - number_of_img, rows, cols = len(data.time.unique()), len(data.latitude.unique()), len(data.longitude.unique()) - images = np.zeros((number_of_img, rows, cols, len(variables))) - df = data.sort_values(by=['time', 'latitude', 'longitude']) - verbose = False - k = 0 - for day in range(0, number_of_img): - - a = df.iloc[377*day:377*(day+1)] - i = 0 - for var in variables: - images[day, :, :, i] = a.pivot(index='latitude', columns='longitude').sort_index(ascending=False)[var] - i += 1 - k += 1 - if ((k % 100 == 0) & (verbose is True)): - print(k) - - test_img_std = images - - test_img_std = np.pad(test_img_std, ((0, 0), (1, 2), (1, 2), (0, 0)), 'constant') - - workdir = Path(self.workdir) - model_path = os.path.join(workdir, f"Unet_sevenAreas_fullStd_{lag}lag_model.keras") - git_path = "https://github.com/climateintelligence/shearwater/raw/main" - urllib.request.urlretrieve( - f"{git_path}/data/Unet_sevenAreas_fullStd_{lag}lag_model.keras", - model_path - ) - - model_trained = models.load_model(model_path) - - prediction = model_trained.predict(test_img_std) - - data = data[["latitude", "longitude", "time"]] - data[f'predictions_lag{lag}'] = prediction.reshape(-1, 1) - - workdir = Path(self.workdir) - outfilename = os.path.join( - workdir, f'tcactivity_48_17_{init_date.replace("-","")}_lag{lag}_Sindian' - ) - - if True: - predscol = f"predictions_lag{lag}" - gpt = mv.create_geo( - latitudes=data["latitude"].values, - longitudes=data["longitude"].values, - values=data[predscol].values, - ).set_dates([pd.Timestamp(init_date)] * data.shape[0]) - fs = mv.geo_to_grib(geopoints=gpt, grid=[2.5, 2.5], tolerance=1.5) * 1e2 - - # cont_gen = mv.mcont( - # legend="on", - # contour_line_colour="avocado", - # contour_shade="on", - # contour_shade_technique="grid_shading", - # contour_shade_max_level_colour="red", - # contour_shade_min_level_colour="blue", - # contour_shade_colour_direction="clockwise", - # ) - # cont_tc = mv.mcont( - # legend="on", - # contour_line_colour="avocado", - # contour_shade="on", - # contour_max_level=105, - # contour_min_level=0, - # contour_shade_technique="grid_shading", - # contour_shade_max_level_colour="red", - # contour_shade_min_level_colour="blue", - # contour_shade_colour_direction="clockwise", - # ) - - cont_oper = mv.mcont( - contour_automatic_setting="style_name", - contour_style_name="prob_green2yellow", - legend="on", - ) - coastlines = mv.mcoast( - map_coastline_land_shade="on", map_coastline_land_shade_colour="grey" + data.loc[:, "time"] = init_date + data.loc[:, "shear"] = ( + (data.u_200 - data.u_850) ** 2 + (data.v_200 - data.v_850) ** 2 + ) ** 0.5 + data.loc[:, "sst"] = data.sst.fillna(0) + + else: + reg = region_string[region] + data1 = pd.read_csv( + f"https://github.com/climateintelligence/shearwater/raw/main/data/test_dailymeans_{reg}_1.zip") + data2 = pd.read_csv( + f"https://github.com/climateintelligence/shearwater/raw/main/data/test_dailymeans_{reg}_2.zip") + data = pd.concat((data1, data2), ignore_index=True) + data = data.loc[(data.time == init_date)] + + variables = [ + "vo", + "r", + "u_200", + "u_850", + "v_200", + "v_850", + "tcwv", + "sst", + "shear", + ] + + means, stds = pd.read_pickle( + "https://github.com/climateintelligence/shearwater/raw/main/data/full_statistics.zip") + + data[variables] = (data[variables]-means[variables])/stds[variables] + + number_of_img, rows, cols = len(data.time.unique()), len(data.latitude.dropna().unique()), len(data.longitude.dropna().unique()) + images = np.zeros((number_of_img, rows, cols, len(variables))) + df = data.sort_values(by=['time', 'latitude', 'longitude']) + verbose = False + k = 0 + for day in range(0, number_of_img): + + a = df.iloc[377*day:377*(day+1)] + i = 0 + for var in variables: + images[day, :, :, i] = a.pivot(index='latitude', columns='longitude').sort_index(ascending=False)[var] + i += 1 + k += 1 + if ((k % 100 == 0) & (verbose is True)): + print(k) + + test_img_std = images + + test_img_std = np.pad(test_img_std, ((0, 0), (1, 2), (1, 2), (0, 0)), 'constant') + + workdir = Path(self.workdir) + LOGGER.info(workdir) + model_path = os.path.join(workdir, f"Unet_sevenAreas_fullStd_{lag}lag_model.keras") + git_path = "https://github.com/climateintelligence/shearwater/raw/main" + urllib.request.urlretrieve( + f"{git_path}/data/Unet_sevenAreas_fullStd_{lag}lag_model.keras", + model_path ) - - gview = mv.geoview( - map_area_definition="corners", area=region_bbox, coastlines=coastlines - ) - legend = mv.mlegend( - legend_text_font_size=0.5, + + model_trained = models.load_model(model_path) + + prediction = model_trained.predict(test_img_std) + + data = data[["latitude", "longitude", "time"]] + data[f'predictions_lag{lag}'] = prediction.reshape(-1, 1) + + workdir = Path(self.workdir) + outfilename = os.path.join( + workdir, f'tcactivity_48_17_{init_date.replace("-","")}_lag{lag}_{region_string[region]}' ) - - mv.setoutput(mv.png_output(output_name=outfilename)) - mv.plot(gview, fs, cont_oper, legend) - response.outputs["output_png"].file = outfilename + ".1.png" - - data.to_csv(outfilename + ".csv") - response.outputs["output_csv"].file = outfilename + ".csv" + + if mv: + predscol = f"predictions_lag{lag}" + gpt = mv.create_geo( + latitudes=data["latitude"].values, + longitudes=data["longitude"].values, + values=data[predscol].values, + ).set_dates([pd.Timestamp(init_date)] * data.shape[0]) + fs = mv.geo_to_grib(geopoints=gpt, grid=[2.5, 2.5], tolerance=1.5) * 1e2 + + # cont_gen = mv.mcont( + # legend="on", + # contour_line_colour="avocado", + # contour_shade="on", + # contour_shade_technique="grid_shading", + # contour_shade_max_level_colour="red", + # contour_shade_min_level_colour="blue", + # contour_shade_colour_direction="clockwise", + # ) + # cont_tc = mv.mcont( + # legend="on", + # contour_line_colour="avocado", + # contour_shade="on", + # contour_max_level=105, + # contour_min_level=0, + # contour_shade_technique="grid_shading", + # contour_shade_max_level_colour="red", + # contour_shade_min_level_colour="blue", + # contour_shade_colour_direction="clockwise", + # ) + + cont_oper = mv.mcont( + contour_automatic_setting="style_name", + contour_style_name="prob_green2yellow", + legend="on", + ) + coastlines = mv.mcoast( + map_coastline_land_shade="on", map_coastline_land_shade_colour="grey" + ) + + gview = mv.geoview( + map_area_definition="corners", area=region_bbox, coastlines=coastlines + ) + legend = mv.mlegend( + legend_text_font_size=0.5, + ) + + title = mv.mtext( + text_font_size=0.50, + text_lines=[ + "Probability of tropical cyclone activity", + f"{region}, Initialisation: {init_date}, Lead time: {leadtime}", + "", + ], + text_colour="CHARCOAL", + ) + + mv.setoutput(mv.png_output(output_name=outfilename)) + mv.plot(gview, fs, cont_oper, legend, title) + response.outputs["output_png"].file = outfilename + ".1.png" + + data.to_csv(outfilename + ".csv") + response.outputs["output_csv"].file = outfilename + ".csv" + else: + xr_predictions = xr.Dataset.from_dataframe(data.set_index(['time', 'latitude', 'longitude'])) + xr_predictions = xr_predictions[f'predictions_lag{lag}'] + + figs, axs = plt.subplots() + xr_predictions.plot(ax=axs) + plt.savefig(outfilename + ".png") + + response.outputs["output_png"].file = outfilename + ".png" + + data.to_csv(outfilename + ".csv") + response.outputs["output_csv"].file = outfilename + ".csv" + + + else: + msg = f"Input date '{init_date}' outside the allowed period." + LOGGER.error(msg) return response diff --git a/shearwater/processes/wps_cyclone_backup.py b/shearwater/processes/wps_cyclone_backup.py new file mode 100644 index 0000000..1cbf8f1 --- /dev/null +++ b/shearwater/processes/wps_cyclone_backup.py @@ -0,0 +1,297 @@ +from pywps import Process, LiteralInput, ComplexOutput +from pywps.app.Common import Metadata +import numpy as np +import numpy +import pandas as pd +import os +from pywps import FORMATS, Format +from pathlib import Path +import urllib.request +import metview as mv + +import logging +LOGGER = logging.getLogger("PYWPS") + +FORMAT_PNG = Format("image/png", extension=".png", encoding="base64") + + +class Cyclone(Process): + """A process to forecast tropical cyclone activities.""" + def __init__(self): + inputs = [ + LiteralInput( + "init_date", + "Initialisation date", + data_type="string", + abstract="Enter the initialisation date, like 2024-02-17", + default="2024-02-17" + ), + LiteralInput( + "leadtime", + "Lead time", + data_type="string", + abstract="Enter the lead time, like 0-48 h", + allowed_values=[ + "0-48 h", + "24-72 h", + "48-96 h", + "72-120 h", + "96-144 h", + "120-168 h", + "144-192 h", + "168-216 h", + "192-240 h", + "216-264 h", + "240-288 h", + "264-312 h", + "288-336 h", + "312-360 h", + ], + default="0-48 h" + ), + LiteralInput( + "region", + "Region", + data_type="string", + abstract="Choose the region of your interest", + allowed_values=[ + "Southern Indian", + "North Atlantic", + "Northwest Pacific", + "Australia", + "Northern Indian", + "East Pacific", + "South Pacific", + ], + default="Southern Indian", + ) + ] + outputs = [ + ComplexOutput('output_csv', + 'Cyclone activity forecast', + abstract='csv file', + as_reference=True, + keywords=['output', 'result', 'response'], + supported_formats=[FORMATS.CSV],), + ComplexOutput("output_png", + "Cyclone activity forecast", + abstract="png file", + as_reference=True, + supported_formats=[FORMAT_PNG],), + ] + + super(Cyclone, self).__init__( + self._handler, + identifier='cyclone', + title='Cyclone', + abstract='A process to forecast tropical cyclone activity.', + # keywords=['hello', 'demo'], + metadata=[ + Metadata('PyWPS', 'https://pywps.org/'), + ], + version='0.1', + inputs=inputs, + outputs=outputs, + store_supported=True, + status_supported=True + ) + + def _handler(self, request, response): + LOGGER.info("running cyclone ...") + # TODO: lazy load tensorflow ... issues with sphinx doc build + from tensorflow.keras import models + + init_date = request.inputs['init_date'][0].data + + leadtime = request.inputs['leadtime'][0].data + region = request.inputs['region'][0].data + + parameters = [ + [138, "vo", [850]], + [157, "r", [700]], + [131, "u", [200, 850]], + [132, "v", [200, 850]], + [34, "sst", [0]], + [137, "tcwv", [0]], + ] + reso = 2.5 + + regions_dict = { + "Southern Indian": [0, 20, -30, 90], # Southern Indian + "North Atlantic": [40, -90, 10, -20], # North Atlantic + "Northwest Pacific": [35, 100, 5, 170], # Northwest Pacific + "Australia": [0, 90, -30, 160], # Australia + "Northern Indian": [30, 30, 0, 100], # Northern Indian + "East Pacific": [30, -170, 0, -100], # East Pacific + "South Pacific": [0, 160, -30, 230], # South Pacific + } + + lags_dict = { + "0-48 h": 0, + "24-72 h": 1, + "48-96 h": 2, + "72-120 h": 3, + "96-144 h": 4, + "120-168 h": 5, + "144-192 h": 6, + "168-216 h": 7, + "192-240 h": 8, + "216-264 h": 9, + "240-288 h": 10, + "264-312 h": 11, + "288-336 h": 12, + "312-360 h": 13, + } + + region_bbox = regions_dict[region] + lag = lags_dict[leadtime] + + data = pd.DataFrame() + for param1 in parameters: + path = f'/pool/data/ERA5/E5/{"sf" if param1[2]==[0] else "pl"}/an/1D/{str(param1[0]).zfill(3)}' + fs1_param = mv.read( + f"{path}/E5{'sf' if param1[2]==[0] else 'pl'}00_1D_{init_date[:7]}_{str(param1[0]).zfill(3)}.grb" + ) + fs1_param = fs1_param.select( + date=init_date.replace("-", ""), level=param1[2] + ) + fs1_param_interp = mv.read( + data=fs1_param, + grid=[reso, reso], + area=region_bbox, + interpolation='"--interpolation=grid-box-average"', + ) + for level in param1[2]: + data.loc[ + :, + f"{param1[1]}{'_'+str(level) if (param1[1]=='u' or param1[1]=='v') else ''}", + ] = ( + fs1_param_interp.select(level=level) + .to_dataset() + .to_dataframe() + .reset_index(drop=True)[param1[1]] + ) + + data.loc[:, ["latitude", "longitude"]] = ( + fs1_param_interp.select(level=level) + .to_dataset() + .to_dataframe() + .reset_index()[["latitude", "longitude"]] + ) + data.loc[:, "time"] = init_date + data.loc[:, "shear"] = ( + (data.u_200 - data.u_850) ** 2 + (data.v_200 - data.v_850) ** 2 + ) ** 0.5 + data.loc[:, "sst"] = data.sst.fillna(0) + + variables = [ + "vo", + "r", + "u_200", + "u_850", + "v_200", + "v_850", + "tcwv", + "sst", + "shear", + ] + + means, stds = pd.read_pickle( + "https://github.com/climateintelligence/shearwater/raw/main/data/full_statistics.zip") + + data[variables] = (data[variables]-means[variables])/stds[variables] + + number_of_img, rows, cols = len(data.time.unique()), len(data.latitude.unique()), len(data.longitude.unique()) + images = np.zeros((number_of_img, rows, cols, len(variables))) + df = data.sort_values(by=['time', 'latitude', 'longitude']) + verbose = False + k = 0 + for day in range(0, number_of_img): + + a = df.iloc[377*day:377*(day+1)] + i = 0 + for var in variables: + images[day, :, :, i] = a.pivot(index='latitude', columns='longitude').sort_index(ascending=False)[var] + i += 1 + k += 1 + if ((k % 100 == 0) & (verbose is True)): + print(k) + + test_img_std = images + + test_img_std = np.pad(test_img_std, ((0, 0), (1, 2), (1, 2), (0, 0)), 'constant') + + workdir = Path(self.workdir) + model_path = os.path.join(workdir, f"Unet_sevenAreas_fullStd_{lag}lag_model.keras") + git_path = "https://github.com/climateintelligence/shearwater/raw/main" + urllib.request.urlretrieve( + f"{git_path}/data/Unet_sevenAreas_fullStd_{lag}lag_model.keras", + model_path + ) + + model_trained = models.load_model(model_path) + + prediction = model_trained.predict(test_img_std) + + data = data[["latitude", "longitude", "time"]] + data[f'predictions_lag{lag}'] = prediction.reshape(-1, 1) + + workdir = Path(self.workdir) + outfilename = os.path.join( + workdir, f'tcactivity_48_17_{init_date.replace("-","")}_lag{lag}_Sindian' + ) + + if True: + predscol = f"predictions_lag{lag}" + gpt = mv.create_geo( + latitudes=data["latitude"].values, + longitudes=data["longitude"].values, + values=data[predscol].values, + ).set_dates([pd.Timestamp(init_date)] * data.shape[0]) + fs = mv.geo_to_grib(geopoints=gpt, grid=[2.5, 2.5], tolerance=1.5) * 1e2 + + # cont_gen = mv.mcont( + # legend="on", + # contour_line_colour="avocado", + # contour_shade="on", + # contour_shade_technique="grid_shading", + # contour_shade_max_level_colour="red", + # contour_shade_min_level_colour="blue", + # contour_shade_colour_direction="clockwise", + # ) + # cont_tc = mv.mcont( + # legend="on", + # contour_line_colour="avocado", + # contour_shade="on", + # contour_max_level=105, + # contour_min_level=0, + # contour_shade_technique="grid_shading", + # contour_shade_max_level_colour="red", + # contour_shade_min_level_colour="blue", + # contour_shade_colour_direction="clockwise", + # ) + + cont_oper = mv.mcont( + contour_automatic_setting="style_name", + contour_style_name="prob_green2yellow", + legend="on", + ) + coastlines = mv.mcoast( + map_coastline_land_shade="on", map_coastline_land_shade_colour="grey" + ) + + gview = mv.geoview( + map_area_definition="corners", area=region_bbox, coastlines=coastlines + ) + legend = mv.mlegend( + legend_text_font_size=0.5, + ) + + mv.setoutput(mv.png_output(output_name=outfilename)) + mv.plot(gview, fs, cont_oper, legend) + response.outputs["output_png"].file = outfilename + ".1.png" + + data.to_csv(outfilename + ".csv") + response.outputs["output_csv"].file = outfilename + ".csv" + + return response From 6fb371af727f622102f75df88b2fb1811495088e Mon Sep 17 00:00:00 2001 From: Michael Maier-Gerber Date: Mon, 12 May 2025 15:21:13 +0200 Subject: [PATCH 3/5] Updated documentation and various other minor changes. --- AUTHORS.rst | 4 +- README.rst | 21 +- ...ET020_sevenAreas_fullStd_0lag_model.keras} | Bin ...T020_sevenAreas_fullStd_10lag_model.keras} | Bin ...T020_sevenAreas_fullStd_11lag_model.keras} | Bin ...T020_sevenAreas_fullStd_12lag_model.keras} | Bin ...T020_sevenAreas_fullStd_13lag_model.keras} | Bin ...ET020_sevenAreas_fullStd_1lag_model.keras} | Bin ...ET020_sevenAreas_fullStd_2lag_model.keras} | Bin ...ET020_sevenAreas_fullStd_3lag_model.keras} | Bin ...ET020_sevenAreas_fullStd_4lag_model.keras} | Bin ...ET020_sevenAreas_fullStd_5lag_model.keras} | Bin ...ET020_sevenAreas_fullStd_6lag_model.keras} | Bin ...ET020_sevenAreas_fullStd_7lag_model.keras} | Bin ...ET020_sevenAreas_fullStd_8lag_model.keras} | Bin ...ET020_sevenAreas_fullStd_9lag_model.keras} | Bin notebooks/first_test.ipynb | 204 ++++++++++++++++-- shearwater/processes/wps_cyclone.py | 96 +++++---- 18 files changed, 251 insertions(+), 74 deletions(-) rename data/{Unet_sevenAreas_fullStd_0lag_model.keras => UNET020_sevenAreas_fullStd_0lag_model.keras} (100%) rename data/{Unet_sevenAreas_fullStd_10lag_model.keras => UNET020_sevenAreas_fullStd_10lag_model.keras} (100%) rename data/{Unet_sevenAreas_fullStd_11lag_model.keras => UNET020_sevenAreas_fullStd_11lag_model.keras} (100%) rename data/{Unet_sevenAreas_fullStd_12lag_model.keras => UNET020_sevenAreas_fullStd_12lag_model.keras} (100%) rename data/{Unet_sevenAreas_fullStd_13lag_model.keras => UNET020_sevenAreas_fullStd_13lag_model.keras} (100%) rename data/{Unet_sevenAreas_fullStd_1lag_model.keras => UNET020_sevenAreas_fullStd_1lag_model.keras} (100%) rename data/{Unet_sevenAreas_fullStd_2lag_model.keras => UNET020_sevenAreas_fullStd_2lag_model.keras} (100%) rename data/{Unet_sevenAreas_fullStd_3lag_model.keras => UNET020_sevenAreas_fullStd_3lag_model.keras} (100%) rename data/{Unet_sevenAreas_fullStd_4lag_model.keras => UNET020_sevenAreas_fullStd_4lag_model.keras} (100%) rename data/{Unet_sevenAreas_fullStd_5lag_model.keras => UNET020_sevenAreas_fullStd_5lag_model.keras} (100%) rename data/{Unet_sevenAreas_fullStd_6lag_model.keras => UNET020_sevenAreas_fullStd_6lag_model.keras} (100%) rename data/{Unet_sevenAreas_fullStd_7lag_model.keras => UNET020_sevenAreas_fullStd_7lag_model.keras} (100%) rename data/{Unet_sevenAreas_fullStd_8lag_model.keras => UNET020_sevenAreas_fullStd_8lag_model.keras} (100%) rename data/{Unet_sevenAreas_fullStd_9lag_model.keras => UNET020_sevenAreas_fullStd_9lag_model.keras} (100%) diff --git a/AUTHORS.rst b/AUTHORS.rst index 3faa8ed..b86ef54 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -10,4 +10,6 @@ Development Lead Contributors ------------ -None yet. Why not be the first? +* Michael Maier-Gerber +* Paolo Bonetti +* Linus Magnusson \ No newline at end of file diff --git a/README.rst b/README.rst index f3c4b31..7446229 100644 --- a/README.rst +++ b/README.rst @@ -22,14 +22,19 @@ ShearWater :alt: Join the chat at https://gitter.im/bird-house/birdhouse ShearWater (the bird) - *ShearWater is a bird to perform detection and forecast of tropical cyclone activity.* - -This WPS is designed to perform detection and forecast of tropical-cyclone activities. In particular, the work at the basis of this WPS focuses on predicting the probability of TC activity in some regions of interest, therefore considering spatio-temporally distributed input features and target variable, in the form of gridded data with daily values. The main purpose of this work resides in daily predictions of the probability of TC activity. For this reason, the problem is formulated as a classification problem with binary targets, where the evaluation takes into account the calibration of the predicted probabilities. The target variable, derived from the International Best Track Archive for Climate Stewardship (IBTrACS), is defined as the occurrence of at least one TC exceeding tropical storm strength (>= 17m/s) evaluated within a 48-hour time window and a radius of 300 km at each grid point in the region of interest. Meteorologically relevant features are taken from the ERA5 atmospheric reanalysis dataset, produced by the Copernicus Climate Change Service at ECMWF. The training dataset covers the years 1980 to 2010, providing a substantial amount of historical data to build a robust predictive model (11323 daily values). The validation dataset includes the years from 2011 to 2015 (1826 daily values), allowing for the evaluation and fine-tuning of the model performance. Finally, the test dataset spans from 15 April 2016 to 31 December 2022 (2452 daily values). Additionally, a live connection to the ERA5 catalogue will be implemented as a next step, to enable this WPS to produce forecasts spanning from 15 April 2016 to the current day. - -Three main hyperparameters are the core of this WPS. -Firstly, a region can be selected among six possibilities available, covering the six main basins where TC activity is particularly relevant: Southern India, North Atlantic, North-West Pacific, Australia, Northern India, East Pacific. The current implementation of the WPS only includes the Southern India region, while the other regions will be available in next releases. -Then, an interval of dates can be selected spanning from 15 April 2016 to the current day, depending on the period of interest of the user for the detection/forecast. As mentioned, the current implementation only spans from 15 April 2016 to 31 December 2022, and it will be updated in next releases. For each selected date, the forecast for each of the subsequent 14 days is provided. If these dates are in the past, the user can validate the forecast skills of the selected model w.r.t. other forecasts. If these days are in the future, this can be actually considered as a forecast. The current implementation only performs the forecast of the TC activity of the current day, next releases will include the forecast in the subsequent 14 days. -Finally, the user can select the model of interest. The default model is a purely data-driven model, based on a Unet implementation that takes a set of meteorological features as inputs, treating them as channels of an image, and it produces the forecast of prediction probabilities, in the shape of as a grayscale image. Future implementations will include two additional models with different characteristics: the ECMWF’s ensemble forecast system, that produces a forecast based on climate models, and an hybrid approach, that combines a detection phase based on machine learning (the Unet mentioned above), with a forecast of the meteorological features based climate models. This way, the skillfullness of climate models in forecasting meteorological variables is combined with the skillfullness of the Unet to perform detection (i.e., extract TC activity from meteorological variables without lags). + *ShearWater is a bird to produce AI-enhanced tropical cyclone (TC) activity forecasts.* + +This WPS is designed to produce AI-enhanced tropical cyclone (TC) activity forecasts. Given a user-defined initialisation date, lead time and region, the WPS generates a probabilistic forecast of TC activity by evaluating the environmental conditions using an AI model. We here define TC activity as the passage of at least one TC within a distance of 300 km and a time window of 48 h, following a definition already used at ECMWF for a medium-range TC product based on IFS ensemble forecasts (Vitart et al. 2012). +Following this definition of TC activity, the target variable used to train the AI model was derived from the International Best Track Archive for Climate Stewardship (IBTrACS; Knapp et al. 2010, Gahtan et al. 2024). Only those parts of the observed TC tracks were considered, where the intensity exceeded tropical storm strength (>= 17 m/s). Meteorologically relevant features were extracted from the ERA5 atmospheric reanalysis dataset (Hersbach et al., 2020), produced by the Copernicus Climate Change Service at ECMWF. The problem under consideration is of a classificatory nature with binary targets. The default model is a purely data-driven model, based on a Unet implementation that takes as input the set of meteorological features, treating them as channels of an image. The model is designed to make a probabilistic prediction in the form of a grey-scale image. +The years 1980 to 2010 (11323 daily values) were selected for training the AI model in order to base it on more reliable data from the satellite era. The following years, 2011 to 2015 (1826 daily values), were used to fine-tune the AI model for better performance. The developed AI model was independently tested on unseen data and evaluated against a set of benchmarks for the period 1 June 2016 to 31 December 2022 (2405 daily values). The results of this thorough evaluation study will be published shortly. Thanks to a live connection to the DKRZ data pool, the AI model can be used to generate forecasts for any initialisation date in the period 1 January 1940 to 31 December 2024. Note, however, that input data prior to 1 January 1980 are less reliable due to a poorer observation coverage and quality, while dates between 1 January 1980 and 31 December 2015 have been considered during model training and fine-tuning already and are therefore not independent. +To generate a forecast, the WPS requires three inputs from the user. First, an initialisation date must be specified, which defines the reference at which the input features are extracted and from which the (possibly retrospective) forecast is issued. Second, the lead time can be selected from a predefined list, where the starting point of the 48-hour target window can vary from immediately after initialisation (‘0-48 h’) up to 13 days (‘312-360 h’) into the future. Third, the region of interest must be selected from the following seven basins, which have been used to train the AI model: Australia, East Pacific, North Atlantic, Northern Indian, Northwest Pacific, South Pacific, Southern Indian. +Once all the necessary information has been provided, the user can click on the ‘Submit’ button, which will run the process and present the output in two formats: 1) a CSV table containing the predicted values at each geographic grid point in the region of interest, and 2) a PNG image displaying the predicted TC activity map using the same colour coding as for the equivalent IFS-based product. +Future plans are to include additional AI models and benchmarks, such as ECMWF’s IFS ensemble probability, the climatological probability and the probability predicted by the more sophisticated hybrid approach. The latter takes the input features from the IFS ensemble and applies the trained AI model to combine the benefits of both approaches. Another idea is to let the user select the region of interest. + +Gahtan, J., K. R. Knapp, C. J. Schreck, H. J. Diamond, J. P. Kossin, and M. C. Kruk, 2024: International Best Track Archive for Climate Stewardship (IBTrACS) project, version 4r01. NOAA National Centers for Environmental Information, accessed 1 July 2022, https://doi.org/10.25921/82ty-9e16. +Hersbach, H., B. Bell, P. Berrisford, S. Hirahara, A. Horányi, J. Muñoz‐Sabater, J. Nicolas, C. Peubey, R. Radu, D. Schepers, an A. Simmons, 2020: The ERA5 global reanalysis. Quart. J. Roy. Met. Soc., 146, 1999-2049, https://doi.org/10.1002/qj.3803. +Knapp, K. R., M. C. Kruk, D. H. Levinson, H. J. Diamond, and C. J. Neumann, 2010: The International Best Track Archive for Climate Stewardship (IBTrACS): Unifying tropical cyclone best track data. Bull. Amer. Meteor. Soc., 91, 363–376, https://doi.org/10.1175/2009BAMS2755.1. +Vitart, F., F. Prates, A. Bonet, and C. Sahin, 2012: New tropical cyclone products on the web. Tech. Rep. 130, ECMWF Newsletter, 17–23 pp. https://doi.org/10.21957/ti1191e2. Documentation ------------- diff --git a/data/Unet_sevenAreas_fullStd_0lag_model.keras b/data/UNET020_sevenAreas_fullStd_0lag_model.keras similarity index 100% rename from data/Unet_sevenAreas_fullStd_0lag_model.keras rename to data/UNET020_sevenAreas_fullStd_0lag_model.keras diff --git a/data/Unet_sevenAreas_fullStd_10lag_model.keras b/data/UNET020_sevenAreas_fullStd_10lag_model.keras similarity index 100% rename from data/Unet_sevenAreas_fullStd_10lag_model.keras rename to data/UNET020_sevenAreas_fullStd_10lag_model.keras diff --git a/data/Unet_sevenAreas_fullStd_11lag_model.keras b/data/UNET020_sevenAreas_fullStd_11lag_model.keras similarity index 100% rename from data/Unet_sevenAreas_fullStd_11lag_model.keras rename to data/UNET020_sevenAreas_fullStd_11lag_model.keras diff --git a/data/Unet_sevenAreas_fullStd_12lag_model.keras b/data/UNET020_sevenAreas_fullStd_12lag_model.keras similarity index 100% rename from data/Unet_sevenAreas_fullStd_12lag_model.keras rename to data/UNET020_sevenAreas_fullStd_12lag_model.keras diff --git a/data/Unet_sevenAreas_fullStd_13lag_model.keras b/data/UNET020_sevenAreas_fullStd_13lag_model.keras similarity index 100% rename from data/Unet_sevenAreas_fullStd_13lag_model.keras rename to data/UNET020_sevenAreas_fullStd_13lag_model.keras diff --git a/data/Unet_sevenAreas_fullStd_1lag_model.keras b/data/UNET020_sevenAreas_fullStd_1lag_model.keras similarity index 100% rename from data/Unet_sevenAreas_fullStd_1lag_model.keras rename to data/UNET020_sevenAreas_fullStd_1lag_model.keras diff --git a/data/Unet_sevenAreas_fullStd_2lag_model.keras b/data/UNET020_sevenAreas_fullStd_2lag_model.keras similarity index 100% rename from data/Unet_sevenAreas_fullStd_2lag_model.keras rename to data/UNET020_sevenAreas_fullStd_2lag_model.keras diff --git a/data/Unet_sevenAreas_fullStd_3lag_model.keras b/data/UNET020_sevenAreas_fullStd_3lag_model.keras similarity index 100% rename from data/Unet_sevenAreas_fullStd_3lag_model.keras rename to data/UNET020_sevenAreas_fullStd_3lag_model.keras diff --git a/data/Unet_sevenAreas_fullStd_4lag_model.keras b/data/UNET020_sevenAreas_fullStd_4lag_model.keras similarity index 100% rename from data/Unet_sevenAreas_fullStd_4lag_model.keras rename to data/UNET020_sevenAreas_fullStd_4lag_model.keras diff --git a/data/Unet_sevenAreas_fullStd_5lag_model.keras b/data/UNET020_sevenAreas_fullStd_5lag_model.keras similarity index 100% rename from data/Unet_sevenAreas_fullStd_5lag_model.keras rename to data/UNET020_sevenAreas_fullStd_5lag_model.keras diff --git a/data/Unet_sevenAreas_fullStd_6lag_model.keras b/data/UNET020_sevenAreas_fullStd_6lag_model.keras similarity index 100% rename from data/Unet_sevenAreas_fullStd_6lag_model.keras rename to data/UNET020_sevenAreas_fullStd_6lag_model.keras diff --git a/data/Unet_sevenAreas_fullStd_7lag_model.keras b/data/UNET020_sevenAreas_fullStd_7lag_model.keras similarity index 100% rename from data/Unet_sevenAreas_fullStd_7lag_model.keras rename to data/UNET020_sevenAreas_fullStd_7lag_model.keras diff --git a/data/Unet_sevenAreas_fullStd_8lag_model.keras b/data/UNET020_sevenAreas_fullStd_8lag_model.keras similarity index 100% rename from data/Unet_sevenAreas_fullStd_8lag_model.keras rename to data/UNET020_sevenAreas_fullStd_8lag_model.keras diff --git a/data/Unet_sevenAreas_fullStd_9lag_model.keras b/data/UNET020_sevenAreas_fullStd_9lag_model.keras similarity index 100% rename from data/Unet_sevenAreas_fullStd_9lag_model.keras rename to data/UNET020_sevenAreas_fullStd_9lag_model.keras diff --git a/notebooks/first_test.ipynb b/notebooks/first_test.ipynb index 2e33206..409743a 100644 --- a/notebooks/first_test.ipynb +++ b/notebooks/first_test.ipynb @@ -10,7 +10,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "2025-05-09 10:42:14.287886: I tensorflow/core/platform/cpu_feature_guard.cc:182] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations.\n", + "2025-05-12 14:06:56.501719: I tensorflow/core/platform/cpu_feature_guard.cc:182] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations.\n", "To enable the following instructions: SSE4.1 SSE4.2 AVX AVX2 FMA, in other operations, rebuild TensorFlow with the appropriate compiler flags.\n" ] } @@ -67,7 +67,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "\n" + "\n" ] } ], @@ -86,8 +86,8 @@ "data": { "text/plain": [ "cycloneResponse(\n", - " output_csv='',\n", - " output_png=''\n", + " output_csv='http://localhost:5008/outputs/9b0e3734-2f29-11f0-b902-080038c02de1/tcactivity_48_17_20240703_lag0_Natlantic.csv',\n", + " output_png='http://localhost:5008/outputs/9b0e3734-2f29-11f0-b902-080038c02de1/tcactivity_48_17_20240703_lag0_Natlantic.1.png'\n", ")" ] }, @@ -107,20 +107,147 @@ "metadata": {}, "outputs": [ { - "ename": "FileNotFoundError", - "evalue": "[Errno 2] No such file or directory: ''", - "output_type": "error", - "traceback": [ - "\u001b[31m---------------------------------------------------------------------------\u001b[39m", - "\u001b[31mFileNotFoundError\u001b[39m Traceback (most recent call last)", - "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[5]\u001b[39m\u001b[32m, line 2\u001b[39m\n\u001b[32m 1\u001b[39m result_url = resp.get()[\u001b[32m0\u001b[39m]\n\u001b[32m----> \u001b[39m\u001b[32m2\u001b[39m df = \u001b[43mpd\u001b[49m\u001b[43m.\u001b[49m\u001b[43mread_csv\u001b[49m\u001b[43m(\u001b[49m\u001b[43mresult_url\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 3\u001b[39m df\n", - "\u001b[36mFile \u001b[39m\u001b[32m~/.conda/envs/shearwater/lib/python3.11/site-packages/pandas/io/parsers/readers.py:1026\u001b[39m, in \u001b[36mread_csv\u001b[39m\u001b[34m(filepath_or_buffer, sep, delimiter, header, names, index_col, usecols, dtype, engine, converters, true_values, false_values, skipinitialspace, skiprows, skipfooter, nrows, na_values, keep_default_na, na_filter, verbose, skip_blank_lines, parse_dates, infer_datetime_format, keep_date_col, date_parser, date_format, dayfirst, cache_dates, iterator, chunksize, compression, thousands, decimal, lineterminator, quotechar, quoting, doublequote, escapechar, comment, encoding, encoding_errors, dialect, on_bad_lines, delim_whitespace, low_memory, memory_map, float_precision, storage_options, dtype_backend)\u001b[39m\n\u001b[32m 1013\u001b[39m kwds_defaults = _refine_defaults_read(\n\u001b[32m 1014\u001b[39m dialect,\n\u001b[32m 1015\u001b[39m delimiter,\n\u001b[32m (...)\u001b[39m\u001b[32m 1022\u001b[39m dtype_backend=dtype_backend,\n\u001b[32m 1023\u001b[39m )\n\u001b[32m 1024\u001b[39m kwds.update(kwds_defaults)\n\u001b[32m-> \u001b[39m\u001b[32m1026\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43m_read\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfilepath_or_buffer\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mkwds\u001b[49m\u001b[43m)\u001b[49m\n", - "\u001b[36mFile \u001b[39m\u001b[32m~/.conda/envs/shearwater/lib/python3.11/site-packages/pandas/io/parsers/readers.py:620\u001b[39m, in \u001b[36m_read\u001b[39m\u001b[34m(filepath_or_buffer, kwds)\u001b[39m\n\u001b[32m 617\u001b[39m _validate_names(kwds.get(\u001b[33m\"\u001b[39m\u001b[33mnames\u001b[39m\u001b[33m\"\u001b[39m, \u001b[38;5;28;01mNone\u001b[39;00m))\n\u001b[32m 619\u001b[39m \u001b[38;5;66;03m# Create the parser.\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m620\u001b[39m parser = \u001b[43mTextFileReader\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfilepath_or_buffer\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwds\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 622\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m chunksize \u001b[38;5;129;01mor\u001b[39;00m iterator:\n\u001b[32m 623\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m parser\n", - "\u001b[36mFile \u001b[39m\u001b[32m~/.conda/envs/shearwater/lib/python3.11/site-packages/pandas/io/parsers/readers.py:1620\u001b[39m, in \u001b[36mTextFileReader.__init__\u001b[39m\u001b[34m(self, f, engine, **kwds)\u001b[39m\n\u001b[32m 1617\u001b[39m \u001b[38;5;28mself\u001b[39m.options[\u001b[33m\"\u001b[39m\u001b[33mhas_index_names\u001b[39m\u001b[33m\"\u001b[39m] = kwds[\u001b[33m\"\u001b[39m\u001b[33mhas_index_names\u001b[39m\u001b[33m\"\u001b[39m]\n\u001b[32m 1619\u001b[39m \u001b[38;5;28mself\u001b[39m.handles: IOHandles | \u001b[38;5;28;01mNone\u001b[39;00m = \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[32m-> \u001b[39m\u001b[32m1620\u001b[39m \u001b[38;5;28mself\u001b[39m._engine = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_make_engine\u001b[49m\u001b[43m(\u001b[49m\u001b[43mf\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mengine\u001b[49m\u001b[43m)\u001b[49m\n", - "\u001b[36mFile \u001b[39m\u001b[32m~/.conda/envs/shearwater/lib/python3.11/site-packages/pandas/io/parsers/readers.py:1880\u001b[39m, in \u001b[36mTextFileReader._make_engine\u001b[39m\u001b[34m(self, f, engine)\u001b[39m\n\u001b[32m 1878\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[33m\"\u001b[39m\u001b[33mb\u001b[39m\u001b[33m\"\u001b[39m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;129;01min\u001b[39;00m mode:\n\u001b[32m 1879\u001b[39m mode += \u001b[33m\"\u001b[39m\u001b[33mb\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m-> \u001b[39m\u001b[32m1880\u001b[39m \u001b[38;5;28mself\u001b[39m.handles = \u001b[43mget_handle\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 1881\u001b[39m \u001b[43m \u001b[49m\u001b[43mf\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1882\u001b[39m \u001b[43m \u001b[49m\u001b[43mmode\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1883\u001b[39m \u001b[43m \u001b[49m\u001b[43mencoding\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43moptions\u001b[49m\u001b[43m.\u001b[49m\u001b[43mget\u001b[49m\u001b[43m(\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mencoding\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1884\u001b[39m \u001b[43m \u001b[49m\u001b[43mcompression\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43moptions\u001b[49m\u001b[43m.\u001b[49m\u001b[43mget\u001b[49m\u001b[43m(\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mcompression\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1885\u001b[39m \u001b[43m \u001b[49m\u001b[43mmemory_map\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43moptions\u001b[49m\u001b[43m.\u001b[49m\u001b[43mget\u001b[49m\u001b[43m(\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mmemory_map\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1886\u001b[39m \u001b[43m \u001b[49m\u001b[43mis_text\u001b[49m\u001b[43m=\u001b[49m\u001b[43mis_text\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1887\u001b[39m \u001b[43m \u001b[49m\u001b[43merrors\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43moptions\u001b[49m\u001b[43m.\u001b[49m\u001b[43mget\u001b[49m\u001b[43m(\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mencoding_errors\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mstrict\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1888\u001b[39m \u001b[43m \u001b[49m\u001b[43mstorage_options\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43moptions\u001b[49m\u001b[43m.\u001b[49m\u001b[43mget\u001b[49m\u001b[43m(\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mstorage_options\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1889\u001b[39m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 1890\u001b[39m \u001b[38;5;28;01massert\u001b[39;00m \u001b[38;5;28mself\u001b[39m.handles \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[32m 1891\u001b[39m f = \u001b[38;5;28mself\u001b[39m.handles.handle\n", - "\u001b[36mFile \u001b[39m\u001b[32m~/.conda/envs/shearwater/lib/python3.11/site-packages/pandas/io/common.py:873\u001b[39m, in \u001b[36mget_handle\u001b[39m\u001b[34m(path_or_buf, mode, encoding, compression, memory_map, is_text, errors, storage_options)\u001b[39m\n\u001b[32m 868\u001b[39m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(handle, \u001b[38;5;28mstr\u001b[39m):\n\u001b[32m 869\u001b[39m \u001b[38;5;66;03m# Check whether the filename is to be opened in binary mode.\u001b[39;00m\n\u001b[32m 870\u001b[39m \u001b[38;5;66;03m# Binary mode does not support 'encoding' and 'newline'.\u001b[39;00m\n\u001b[32m 871\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m ioargs.encoding \u001b[38;5;129;01mand\u001b[39;00m \u001b[33m\"\u001b[39m\u001b[33mb\u001b[39m\u001b[33m\"\u001b[39m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;129;01min\u001b[39;00m ioargs.mode:\n\u001b[32m 872\u001b[39m \u001b[38;5;66;03m# Encoding\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m873\u001b[39m handle = \u001b[38;5;28;43mopen\u001b[39;49m\u001b[43m(\u001b[49m\n\u001b[32m 874\u001b[39m \u001b[43m \u001b[49m\u001b[43mhandle\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 875\u001b[39m \u001b[43m \u001b[49m\u001b[43mioargs\u001b[49m\u001b[43m.\u001b[49m\u001b[43mmode\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 876\u001b[39m \u001b[43m \u001b[49m\u001b[43mencoding\u001b[49m\u001b[43m=\u001b[49m\u001b[43mioargs\u001b[49m\u001b[43m.\u001b[49m\u001b[43mencoding\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 877\u001b[39m \u001b[43m \u001b[49m\u001b[43merrors\u001b[49m\u001b[43m=\u001b[49m\u001b[43merrors\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 878\u001b[39m \u001b[43m \u001b[49m\u001b[43mnewline\u001b[49m\u001b[43m=\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[32m 879\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 880\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 881\u001b[39m \u001b[38;5;66;03m# Binary mode\u001b[39;00m\n\u001b[32m 882\u001b[39m handle = \u001b[38;5;28mopen\u001b[39m(handle, ioargs.mode)\n", - "\u001b[31mFileNotFoundError\u001b[39m: [Errno 2] No such file or directory: ''" - ] + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Unnamed: 0latitudelongitudetimepredictions_lag0
0040.0-90.02024-07-030.000159
1140.0-87.52024-07-030.000051
2240.0-85.02024-07-030.000059
3340.0-82.52024-07-030.000053
4440.0-80.02024-07-030.000105
..................
37237210.0-30.02024-07-030.000835
37337310.0-27.52024-07-030.000646
37437410.0-25.02024-07-030.000379
37537510.0-22.52024-07-030.000942
37637610.0-20.02024-07-030.005947
\n", + "

377 rows × 5 columns

\n", + "
" + ], + "text/plain": [ + " Unnamed: 0 latitude longitude time predictions_lag0\n", + "0 0 40.0 -90.0 2024-07-03 0.000159\n", + "1 1 40.0 -87.5 2024-07-03 0.000051\n", + "2 2 40.0 -85.0 2024-07-03 0.000059\n", + "3 3 40.0 -82.5 2024-07-03 0.000053\n", + "4 4 40.0 -80.0 2024-07-03 0.000105\n", + ".. ... ... ... ... ...\n", + "372 372 10.0 -30.0 2024-07-03 0.000835\n", + "373 373 10.0 -27.5 2024-07-03 0.000646\n", + "374 374 10.0 -25.0 2024-07-03 0.000379\n", + "375 375 10.0 -22.5 2024-07-03 0.000942\n", + "376 376 10.0 -20.0 2024-07-03 0.005947\n", + "\n", + "[377 rows x 5 columns]" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ @@ -131,7 +258,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "id": "c269bf61-4e5c-4d78-b942-9f06e29e05f1", "metadata": {}, "outputs": [], @@ -141,20 +268,51 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "id": "250a9f8b-66c5-4aa3-bab8-f15bef5c3e18", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--2025-05-12 14:07:15-- http://localhost:5008/outputs/9b0e3734-2f29-11f0-b902-080038c02de1/tcactivity_48_17_20240703_lag0_Natlantic.1.png\n", + "Resolving localhost (localhost)... ::1, 127.0.0.1\n", + "Connecting to localhost (localhost)|::1|:5008... failed: Connection refused.\n", + "Connecting to localhost (localhost)|127.0.0.1|:5008... connected.\n", + "HTTP request sent, awaiting response... 200 OK\n", + "Length: 65680 (64K) [image/png]\n", + "Saving to: ‘/home/b/b382611/shearwater/tcactivity_48_17_20240703_lag0_Natlantic.1.png’\n", + "\n", + "tcactivity_48_17_20 100%[===================>] 64.14K --.-KB/s in 0.002s \n", + "\n", + "2025-05-12 14:07:15 (38.0 MB/s) - ‘/home/b/b382611/shearwater/tcactivity_48_17_20240703_lag0_Natlantic.1.png’ saved [65680/65680]\n", + "\n" + ] + } + ], "source": [ "! wget $result_url -P /home/b/b382611/shearwater" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "id": "27002ace-ce96-475c-81df-79a22eea8cfc", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAyAAAAI2CAIAAAAn6nsNAAAABmJLR0QA/wD/AP+gvaeTAAAgAElEQVR4nOzdd1wT9/8H8A9hy5A9ZC9FxQUIiqI4qmLBOmudrVZRq3W2WGetWhwt1tE6sO5d3Iq4BRQXYBUEWSKo7L0CxIzfH/f95pdvEsLw5BJ4PR/9I3f5fO7e+eTOvri73CkJBAICAAAAAPRhMV0AAAAAQGuDgAUAAABAMwQsAAAAAJohYAEAAADQDAELAAAAgGYIWAAAAAA0Q8ACAAAAoBkCFgAAAADNELAAAAAAaIaABQAAAEAzBCwAAAAAmiFgAQAAANAMAQsAAACAZghYAAAAADRDwAIAAACgGQIWAAAAAM0QsAAAAABohoAFAAAAQDMELAAAAACaIWABAAAA0AwBCwAAAIBmCFgAAAAANEPAAgAAAKAZAhYAAAAAzRCwAAAAAGiGgAUAAABAMwQsAAAAAJohYAEAAADQDAELAAAAgGYIWAAAAAA0Q8ACAAAAoBkCFgAAAADNELAAAAAAaIaABQAAAEAzBCwAAAAAmiFgAQAAANAMAQsAAACAZghYAAAAADRDwAIAAACgGQIWAAAAAM0QsAAAAABohoAFAAAAQDMELAAAAACaIWABAAAA0AwBCwAAAIBmCFgAAAAANEPAAgAAAKAZAhYAAAAAzRCwAAAAAGiGgAUAAABAMwQsAAAAAJohYAEAAADQDAELAAAAgGYIWAAAAAA0Q8ACAAAAoBkCFgAAAADNELAAAAAAaIaABQAAAEAzBCwAAAAAmiFgAQAAANAMAQsAAACAZghYAAAAADRDwAIAAACgGQIWAAAAAM0QsAAAAABohoAFAAAAQDMELAAAAACaIWABAAAA0AwBCwAAAIBmCFgAAAAANEPAAgAAAKAZAhYAAAAAzRCwAAAAAGiGgAUAAABAMwQsAAAAAJohYAEAAADQDAELAAAAgGYIWAAAAAA0Q8ACAAAAoBkCFgAAAADNELAAAAAAaIaABQAAAEAzBCwAAAAAmiFgAQAAANAMAQsAAACAZghYAAAAADRDwAIAAACgGQIWAAAAAM0QsAAAAABohoAFAAAAQDMELAAAAACaIWABAAAA0AwBCwAAAIBmCFgAAAAANEPAAgAAAKAZAhYAAAAAzRCwAAAAAGiGgAUAAABAMwQsAAAAAJohYAEAAADQDAELAAAAgGYIWAAAAAA0Q8ACAAAAoBkCFgAAAADNELAAAAAAaIaABQAAAEAzBCwAAAAAmiFgAQAAANAMAQsAAACAZghYAAAAADRDwAIAAACgGQIWAAAAAM0QsAAAAABohoAFAAAAQDMELAAAAACaIWABAAAA0AwBCwAAAIBmCFgAAAAANEPAAgAAAKAZAhYAAAAAzRCwAAAAAGiGgAUAAABAMwQsAAAAAJohYAEAAADQDAELAAAAgGYIWAAAAAA0Q8ACAAAAoBkCFgAAAADNELAAAAAAaIaABQAAAEAzBCwAAAAAmiFgAQAAANAMAQsAAACAZghYAAAAADRDwAIAAACgGQIWAAAAAM0QsAAAAABohoAFAAAAQDMELAAAAACaIWABAAAA0AwBCwAAAIBmCFgAAAAANEPAAgAAAKAZAhYAAAAAzRCwAAAAAGiGgAUAAABAMwQsAAAAAJohYAEAAADQDAELAAAAgGYIWAAAAAA0Q8ACAAAAoBkCFgAAAADNELAAAAAAaIaABQAAAEAzBCwAAAAAmiFgAQAAANAMAQtav4sXL7q7u48fP37atGnjx4/39PQcMmRIVFRU85a2e/dub2/vT9H38OHD7u7ujZw8cOCAh4dH88poEJ/P//rrrwcNGrRgwYLFixfX1NSINfikaycSH5bx5cjzGj+S5FfZpI/QkpslgGJRYboAgBby888/d+vWjRDy9u3b2bNnr1u3Ljw8XF1dnem6/t+gQYOsrKya9y693r9/n5iYuHXr1sGDB7fMGsW05IcFMU0afHxTAPVBwII2x9raesyYMX///XdKSkr37t1jYmISEhJmzpwZExPz6tUrPT29UaNGEULi4uKSkpIEAoGLi4urq6vkcmJjY5OSkrS0tHx8fAwNDYXz37179+LFi+LiYgMDg+7du9vY2DSyb2lp6evXr4cMGSK1bNF3Hz58GBMTIxAIQkJCqHf79esXHR09ceLE9u3bC7v8+++/MTExX3/9dX05UupnjIiIuH//PiEkKioqPT3dzs7us88+E+0lufZZs2bFxcU1aRipYZ8xY8ajR4/S0tK0tbUbHIqMjIy4uLiqqioTE5PevXubmJg0fsBlkFxsUlLSgwcPGhzM+upp5DgLB2HmzJnU9qCnp9e3b19jY2PRvq9fv46NjWWz2XZ2dt7e3srKyvWtpcFxkCxY6lcpOviJiYnR0dFfffWVrq6ucDnPnz9/+vTp9OnTNTQ0PsVmCdA6IGBBW6ShoUEI4XK5hJCYmJiTJ08mJye/e/euc+fORkZGtbW1y5Yte/r0qb29PSFk165dffv2/e2330T/fxAUFHTv3j07O7v09PSdO3fu2LGjZ8+ehJBbt26tWbPGxsZGT0+vsLAwOzs7ICDg22+/FV17fX2fP38eEhISEBAgtWbRdysqKiorKwkhOTk51LuGhoYHDhzQ1NScNm2asMsff/yhrq4udYEyPmNZWVlRUREhpLi4mBCip6cn1ldy7c0YxpiYmBMnTjx//rympqZz58537tyRMRR8Pj8oKOjixYsmJiYWFhb5+fm//vrrw4cPGzng9alvsUZGRrIHU0Y9jR9n4aClp6dnZ2d36tTp2rVr27dv37t3b8eOHam1bNq06cKFC5aWlgYGBvv377e1td29e7fkN9LgONRXsNSvUnTwdXR0QkJC9PX1J0yYIGywZ88eNptNNaB3swRoVQQArd2FCxfc3Nzi4+OpSQ6HM2XKFA8Pj7KyMoFA8Ndff7m5ua1Zs4bH41ENduzY4e7uHhkZSU3evn3bzc1t165d1CTVfu7cuWw2WyAQlJeXT548eeTIkR8+fBAIBMXFxZWVlcJVX79+3c3N7fXr143pe+jQITc3N2Ff2ZN///137969RT/mjz/+OHr0aD6fT02+evXKzc3txo0bUsdE9meMj493c3OLjY2tb0gl1968YVyzZg1VMJfL/f777+sbioMHD7q5uZ0+fVo4JzU1lXohe8DFliNGxmJlD6aMjmJrbMwgbN68mZrkcDhjx45dtmwZNXnkyBE3N7dz585Rk1lZWUOHDl2zZo3UzyJ7HGQULPlVin2EGTNmfP3118LJnJwcd3d34aLo3SwBWhNc5A5txalTp4KDgzdu3DhhwoTk5OSZM2eKnrYICAhgsf6zO1y9etXLy2vAgAHU5JAhQ/r27Xv58mXRpX3//feampqEEF1d3blz5+bn58fExBBCDAwM1NXVo6Ojz549e/jw4dzcXBaLRb3VYN+PNHHixHfv3j19+pSaDA0NNTAwqO8iqsZ8xmZo6jDOnDlTSUmJEKKsrPz111/XNxShoaG9e/eeOHGicI6TkxP1ojEDXh8Zi5U9mDI6imnMIMyaNYt6oaqq2rdv3+TkZNG1jB07lpq0trb+6quvbt++zeFwJFckexwaX7AkPz+/ly9fZmVlUZNhYWHKysrDhw9vZPcmbZYArQkCFrQVWVlZKSkpBQUFffv23b9//5w5c4RvqaiodOjQgXpdWVlZUlLi7Ows2rdz584lJSVVVVXUJIvFok7iUDp16kQIyczMJIQkJyf7+/uvXbs2IiIiJSUlNTWVxWKVlZUJG8vo+5Hc3NwcHBzOnj1LfYobN26MHj1aRUXKZQCN+YzN0IxhtLa2Fr5ra2tLpA1FdXV1QUEB9QMFSQ0OeH1kL1bGYMruKKoxg6Curi56AZ+urm5JSQkhhM1m5+bm8ni8wyLevHnD4XDy8/ObNA6NL1iqzz77TE1NLSwsjJoMCwvr37+/1NOUUjV+swRoZbCVQ1vx008/1ff/GFVVVeFxF+qAilQy3hK+u2nTJmNj47///pu6yIbH4925c4fH48muTfaSG+/LL7/csmVLQUHBnTt3qPNNTV3dx1TS1GEUCARcLldNTY2apA7M1NdRIBBInd+8AW9wsaShwZTRUagxgyAcMTF8Pp8QUlFRkZqaKjp/2LBhUq8Nb3AcGlOwVDo6OgMHDrx27dq8efMSEhLevXu3ePHiJi2hkZslQCuDgAXwP7S1tQ0MDF69eiU689WrV4aGhlpaWtQkn89PTU3t0qULNUmd06F+tJWWlvbNN98I/xf4+vVrsf/Zy+jbJFL/5z1y5Mhdu3ZdvHjx5s2b/fv3NzMza/ZnbMbam7oKgUCQnJzcvXt34btE2lBoaWmZmprGx8dLXVGDA14f2Ysl9Q9mgx2FPmactbW1TUxM7O3tg4KCGvFpZI2D7IIbE6n9/f1v3boVFxd38+ZNPT29fv361dfyYzZLgFYGpwgBxPn7+z969Oju3bvU5O3btx89evTFF1+IttmxYwebzSaElJeX792718TEhLrdoqmp6evXr6k2PB5v9+7dksuvr2+T6Onp8fn8goIC0Zmampr+/v5HjhzJzMwcP378R37Gpq69GavYtWsXNRRlZWUhISH1DcXEiRPj4uJOnjwpPAwjPK7TmAGvj4zFEpmDKbtjUwehPtQVV1evXhWupa6u7tmzZ1Ibyx4HGQU35qvs06ePkZHR+fPnb926NWLECBkn+D5yswRoTXAEC0BcQEBAamrq8uXL7ezsBAJBZmZmv379hFciE0I0NTXt7Oz8/f1tbGwyMjL4fP727dtVVVUJIfPmzVuzZs2yZctsbGyePn3aoUOHdu3aiS5cRt8m6devX7t27b755htHR0cWi7Vt2zbqZNOECRNOnz5taWnZt2/fj/mMTV17M1ahqanp6Ojo5+dna2tL/d6tvqGYOnXq27dvt23bdvToUQsLi8LCwuLi4ujoaNKIAZdBxmIp9Q1mgx0bPwiyy8vLy/vll192795tbm5eVVWVnZ3dsWPHgwcPSjaWPQ4yCm7MV8lisXx9fY8dO0YI8fPzk1HzR26WAK0JAha0fs7OzgEBAaamplLf7d27N3VbLCF1dfVdu3bFxcUlJiYSQsRuDkm1nzlz5tChQxMTE319fQcNGmRkZES9O2zYMCcnp6dPn9bV1S1evNjd3f3w4cNdu3ZtTN+ePXuK3hxI9qSpqek///xz//596mYTwvkaGhpKSkrjxo2TfepH9mc0NTUNCAgwNzevr7vk2ps6jJTly5cPGTKkwaFgsVirV6+eNGlSbGxsTU2NsbGxp6cn9ZbsARdbjhgZi6XUN5gyOoqtsTHbkuiS3dzchLcSZbFYgYGBkyZNiomJKSsr09PTc3BwqO86QtnjIKNgya9S6qCNHz9eU1NTQ0ND7Jp9ejdLgNZEqdlXPgKAHPrtt98uX74cFhYmeuttObR79+5Tp05Rt4yXW4oymPIPIwltEI5gAbQS+/fvf/z48YsXLxYsWID/jX0kDCZdMJLQZiFgAbQSVlZWysrK3377rZeXF9O1NEzy7JhcUazBlGcYSWizcIoQAAAAgGa4TQMAAAAAzRCwAAAAAGimvG7dOqZrgP9RW1t78OBBExMT6lHEoaGhTk5Owl9uN6isrCwqKsrBwaG+BomJiQ8ePOjcubPY/MrKyjt37jT+EbDN6FhbW3vhwgXhT8cbXIiMJQvfal7Zzf6wFA6H8/Dhw8jIyPz8fFtbW+pOP2w2OywsLDU11c7OTllZWWobyunTpwUCgdhtI8S65+XlnTx5Mu6/nJycRB+QItaYei7K/fv3s7KyrK2txW4lJdZYcs7z588vX74sXFdaWpqLi4vYR5bx3TXG5cuXbWxs6nsw4sd8F6IkP6kY0ZEvKCi4fPnyq1evLCwsRK8Ga3APIoSEhoba2NgIH/Jz9epVfX19sZuzy95EW2BA2uBWqlgDQggJCQmhWlZWVlLP4mzJAYFPDUew5E5tbe3hw4f//PNPajI0NLSurk52F9Gng5WVld24cUNG4wMHDhw/fryoqEisY2VlZXh4eCOLFO1IPVGuMb1qa2tDQ0OlviVcSCOXLKy28WtvXs1SpaamPn/+3M7OLiEh4eeff6ZmLl26lMVisdnsVatW1deGEPLw4cODBw8mJCSILVOsu7a2tpubm5ubm729/cWLF7W1tWU0rqury8vL69ixY1FR0fz582UvWXKOmZmZ23+lp6dnZGRIfmQZ311jXLp0qba2VjhJ43chSvKTihIdeTabHRAQYGZm1r59+4CAAOrBf5QG9yBCyPv372/dukW9rq6u3rdvn4GBgVgb2ZtoCwxI29lKG/l4RHkbEELIpUuXqPZi6eojBwTkBH5FKI9sbW2ph7x27NhRODM3NzciIkJLS2v48OHq6uplZWVPnz7V0tLKzc2tq6t7+/ZtSEhI3759dXR0CCGxsbEpKSkDBgywsrISXXJJSQmbzZ4+fXp4ePi0adOioqKEHQ0NDak2fD7//v37mZmZpqamn332mbKyMrUubW3tjIyMgQMHWllZiXa0tbUV/iFeWlp69+7dmpoab29vGc/Xk1ygkpIStRCpS5YsSbgoYUdCSGRkZEZGhoGBga+vr4qKiliX+mqWOrCitRFCzp49O3r0aGEXFxcX6o/Fvn37jhw5khCSnJysqqo6atQoQsi1a9dyc3Ml2xBCeDze8ePHx4wZIzYgkt3Nzc3d3NwIIadOnfL19RX9S1pq42nTphFCvLy8QkNDBQKB8HaOko3Ly8slu1OPh4uJicnLy9u4cWN9X5zYtkQ9AWbEiBHa2tpSv6OsrKzo6GjhgxeFpH4X1Mjr6emlpKSMGDGiuro6KiqqV69e1K01xVYn+aVIHRbhGsVGvqioyMzMbNCgQYSQI0eOlJaWCrd/Sn17EMXPz2/r1q3U0m7dujVo0CAlJaXIyMgGN9GWHJC2s5WKjl63bt3E9mhhMzkcEEJIcXGxpaWlWMD6dLsttCQcwZJTc+fO3bt3r3CysLBw6dKlDg4OPB5v4cKFAoGgrKxs8+bNhJD+/fv36NHD1NTUz8/P3t6eEJKQkJCbm2tnZ7d06VLRP80JIdevX//888+HDRt27949QohYRwqHwyksLOzdu3dGRkZwcDAhpKys7LffflNRUfH09AwMDOTz+aIdhX+pl5SUzJ8/38jIqHv37qWlpTI+neQChQuRumTJkoSEbW7duhUREUFFTA6HI9lF6pKlDqxYbYQQ6pk2kh/k7t27PXv2JIS8ffvW0tKSmmllZfX+/XvJNoSQc+fODR8+XFNTU2w5MrpfvXpV7OEkUhvX1tZeu3Zt27Zt3333nejNsiUb17euwsLCzZs3b9q0SXjmS4aysrKFCxeamZkZGxsvXryYx+NJDnhBQcFPP/3k5OSUlJSUnp4u2l3qd1FWVvb7778XFRV16NBh0aJFYWFh3bp1+/XXX4uKiiRXRyS+FBljKDny1tbW3bp1O3r06IEDB7p27SqWrmTsQRQnJyc2m52Tk0MIuXbtmp+fX2M20RYeEKFWv5WKjp7kHi3PA+Lj41NRUbFv374dO3bIbkzLbgstDAFLTvXo0YPL5VKP1yCEREZGjhgxwsPDY8yYMTweLzc3lxDi7Ozcr18/6jSHurp6hw4dqKtAHB0d/f39vby8jI2NqVOBQmFhYR8+fIiIiPjw4UNqaqpYR4qGhsbgwYMrKiqcnZ1jY2Opmc7Ozh4eHk5OTvr6+kVFRVI7RkREDB06dODAgd27dxf+21QfsQUK5ze+JDGGhoaZmZlJSUldu3bV1taW7CJ1yfUNrFhtgYGBkv9+JSYmHj58+KeffqImhf/DUFL6/7ufiLapqqq6d++ev7+/cAnJycnXrl2jjkNI7Z6WlqaiomJnZ9eYxoQQFRWV48ePf/jwQbROycaSc3g83ooVKxYtWmRhYSF1eMXcvXvX2tqay+VS3V+/fi054JGRkZ9//nnv3r0nT54slmCkfheEECcnp5EjRw4ZMqSmpmb27Nm9evXq3bt3Wlqa5OqItC9F7HMJR0xy5IuKim7fvq2ioqKqqlpYWMjhcESXI2MPEvr888/DwsJycnIqKys7duzYmE205QeEtI2tVHT0pO7RcjsgP/744/jx44ODg69fvy52Kcin2G2hhSFgya+5c+fu2bNHOCn5DC/hX1RibwnnKysri17MkZaWZmBgQF3PO2TIkKtXr0p9LlhiYuLKlStLSkoIIcLLRIT/cFPLlNpR9Jh/g8QWKONj1leSGFdX1+DgYG1t7aVLlyYkJEh2qa82yfn11SYqNTX1119/DQ4Opi6+Ef2b8t27d9TfmmJt/vnnH0tLy+vXr6empiYnJ799+1a4NKndibS/g+trrKGhMXLkyIULF2poaOTn58toLLX7jh07evToMWDAAKkfVirhqaipU6eamJhI/Y6EbepLQmKEF5urqqpSXYRfgdjqJPvWN4ZE2sgnJCS4urpOnjx5+vTpampqYtfW1LcHiRoxYsTNmzevXbtGnUhqzCbawgNC2sxWKjZ6Mv4VkrcBoaioqKioqIhuaZ9ut4WWhGuw5FeXLl00NDSonWrAgAGLFi1ydnbOzc1lsVjm5uZZWVnClvr6+nl5eSkpKdQp+fpcvXp19OjRQ4YMIYTw+fwvv/xy1qxZkh1zc3Otra09PDyEl/FKkrrGQYMGzZ8/397e3sDAgDqNuHXr1sWLFzfp2LXUJTempKdPn3748MHKysrExKSmpqaiokKsi9Qlyx5YoT/++GP+/PnCD5KTk7N48eK5c+fm5+fn5+f37Nmzc+fOtbW1ly9frq2tNTIy6tChg2QbLy8vsQtRnZ2dhY/OFetOCKF+dXXy5MkGG6enp7969crMzCwtLY0QQnWnSBbWoUMHsTkRERERERHr1q17/vw5IYTFYnXv3l3yu6utraUaEEK8vLwuXrzIYrGMjIzS0tKoawHFBnzgwIErV64cMGBAcnLyu3fvGvyWZfDx8RFbneSXIvWTUiOWnJwsNvJdunTZtWvX/fv3uVxuWlqa6ClyqSRHw8DAwNLS8uTJk//88w9p3CbawgPSFrZSydGT3KOFa5G3AUlNTY2Pj7eysoqMjOzcubPowcuPHBCQE7hNgzxSUVGhLoN1dnbW1tZ2d3fX1dX18vJ69uyZurr6ggULqF84a2pqUj8mV1NTs7GxiY2N1dbWNjU1Fc4nhIj+Tvj9+/c+Pj7Uv79KSkpU4y5dugg7qqmpOTk52dnZ1dbWvnjxwsPDw8TEhPplvtgytbW1RddIddTU1Bw8ePDLly+zs7OdnZ3V1dX3798/fvx40T8oVVRUpC5QXV2dWojYZ5FREvWW8IWSklJSUtKbN2+GDRvm7u4u2UXqkrW0tGQMrLC29PT0bt26Ca9cLi4uVlVVraqqys7Ozs7Opi5rHTJkSFpampqa2ty5c5WVlSXbGBkZOTk5OTk5GRoauri4iP6CQbI7tRZTU1Op/2iKNVZRUcnKysrMzDQyMlq4cKHYD+Allyw2Jzs7W19fPycnhyo1Nze3S5cukt9dTU1N9n/16tXL19c3MTExMzPTysrKxsbG3t5ebMC1tLR69OgRGRlpamraq1evTp06iR6/kfwuxEZeeEsIKysrMzOzwYMHi65OSUlJ7EuR+kkpkiOvra3t5eWVkJDAZrPnz59vbGwsOmJiG4BAIJAcDaowBwcH6ttvzCbawgPS6rdSV1dXydGzt7eX3KPlc0BUVVUzMzPfvXvXuXPn2bNni21dHzMgICfwqBwAAAAAmuEaLAAAAACaIWABAAAA0AwBCwAAAIBmCFgAAAAANEPAAgAAAKAZAhYAAAAAzRCwAAAAAGiGgAUAAABAMwQsAAAAAJohYAEAAADQDAELAAAAgGYIWAAAAAA0Q8ACAAAAoBkCFgAAAADNVJguQO4kJGR///1p4eTWreM8PGyZK6cBiYk5p07FxMVldetmsXXrOOH8K1fiDxx4oKqq/N13PoMGdWKwQqlSU/OPHn384sV7HR31yZM9/Py6U/MTE3O2bLlRXFw1enTP2bO9mS1SUlpawV9/RaSl5WtoqH72WZfZs/srK7OI3JctdPNmUlBQ+MaNX/Tv70gIKS1lr19/9dWrPFdX61WrfLW01JkuUNyyZaFxcW+p1126mO/ePZkQwucLtm+/c+tWkoWF3qpVI+3sjBitUbq8vIqtW28kJeWamen+8MMwF5cORO73yj17Is+ciRVOGhhonT8/lyjC5h0e/vLo0cdVVXV9+9ovWTJUU1OVKELZ6ekFv/128+3bEm9vpx9++ExNTYXI615ZUlK9f/+Dp0/fVFbW3ry5WMZMoggj32JwBEtceXnN27clP/zwGfWfnZ0h0xXJEh+fXVxcpaOjER+fLZx5507y1KkHxo1zHTq086hRf7148Z7BCqUKCblfWsqeMsXDw8Nu0qS/z517RggpKqoaOPB3W1vD2bO9f/01fM+eSKbLFFdRUePgYBwQMGDs2F779kX9+us1oghlU+rquD/+eC4xMaeoqIqaM2bMnrdvSxYuHBwbmzlz5lFmy5PqxYv3/fs7UnvilCme1Mxffrl68GD0d9/5aGtrDB68rabmA7NFSiorY3t4BJWX18ya1d/Dw7akpJoowl7p49NR+O+etra6mpoyUYTN+8GD9LFj9w4e3On77wdduRK/aNEZoghlFxZWenpu7tBBb8mSobdvvxL+VS+fe2Vubnl8/Ht7e+OoqDTZM+V/5FuUAP7X/ftpPXqsZ7qKptm16+7w4TuEk/7+f65de5l6PW/eiW+/PcJQXfXi8/nC1ytWXJg4MUQgEAQH3xow4Ddq5pkzMQ4Oq5gprnF+/fXawIG/CxSn7PXrr65ff7VTpzUXLvwrEAji4rI0NedXVdUKBILc3HIWa87btyVM1yhuyJBtVLVCXC5PX3/x3bvJ1GSXLj8fO/aYidJkWbfuyvjxe8Vmyv9eKcTj8a2sll+9Gi9QhM07KOjaqFF/Ua9v3MAuS9gAACAASURBVEi0sVkhUISy9+2L8vLaQr1+/bpQWXlucXGVnO+VCQnZ6urfyZ4p/yPfknAES4q8vIpvvjm8ePE/jx5lMF1Lc8TGZnl7O1Kvvb2dYmOzmK1HkpKSkvB1bm65mVl7QkhsbKa3txM109vb6fXrwtJSNjP11S87u8zHJ7hnzw2rV18aNqwLUZCys7KKT5+O+fHHYcI5sbFZrq7W1AkIMzNdR0eTuDi5204IIfv33//660Pbtt2mjlRRw0ud4iSE9O/vKIeb9/XriQMGdJw9+9iECfsOH35IzZT/vVIoIiKltpY7fHhXogibt7e3U0ZGIYfDJYS8fJnTqZMpUYSyS0qqTU11qdempjo8Hv/Zs7eKslfKIP8j35IQsMTp6bWbNq1P//6OamrKQ4f+cenSC6YrarKSkmpDQ23qtaGhVnFxNbP1yPD0aebFi88XLPAhhJSUsA0Ntaj51Avq3IpcMTDQWrfOf/HiIRMnui9cOJgoSNmLFp3ZsOELDQ1V4RzRjYTI63YyaFCnYcO6eHrahYbGDRz4O5fLLymp1tXVUFVVphoYGmoXF1cxW6SkrKziTZvC3d1tvvqq9y+/XN2x4w5RqL3y6NHHkyb1VlFhEUXYvPv3dxw3ztXRcbWHx6aDB6MPHJhOFKFsNzeb+/fTqPP1Fy48J4QUF1crxF4pm/yPfEvCRe7iXFw6/Pbbf64WNzHR+e23G1980YPZkppKVVW5tvY/F6bU1n6grqWQQ6mp+WPG7Dl6dIajowkRL5tLCKGu+pQrmpqqPj4dCemor681deqBixe/k/+yr19PrKysGzu2l+hM0bKJvG4nq1aNpF58842Xre3KiIgUff121CBTams/yNtoU776qvecOQMIIXV13M2bry9aNERR9ko2m3P+/L937y6lJuV/8z558ulff0Vs3TrO3Lz9n3/eW7v28sGDX8t/2Z991nnMmF7OzmsdHIzV1VXNzHSNjbXfvy+V/71SNvkf+ZbUdj95Y3TqZJafX8l0FU1mb2+ckVHYt689IeTNmyL5/JlVVlbxsGE7tm4d6+//n58Q2tsbZWQUUa/fvCnS0FA1N2/PXIENMDdvf+9eClGEsvfvv19Tw/nqq/2EkJyc8uDgWxwOV7RsPl+QlVUin9sJpV07NSsr/fz8CldXaw6Hm51dZmGhRwh586bIzc2G6erEOTgYm5n95+yPmZkudYpEIfZKQsiFC/9aWOi5u/9nVOV/87506cXcuQNmzPAihLi72xgbL/v99/HyXzYhJCRk6rp1fgUFlVZWBubmP3bsaFpeXqNAe6VUCjHyLQanCMVlZRXz+QJCSG3th/3778vzPRrq4+/f/eDBh3y+gMPhHj36+IsvejJdkbjc3PIhQ/5Yvny48KdhhBB//+6XLr0oLKwkhOzff3/kSBfqJIX8+Pffd3V1XEIIl8vfuzeyc2dzoghlL1kydOHCwaNH9xw9uqeOjoanp13nzuaDBnXKzS2PjEwlhJw//6+amrKnpx3Tlf6PujpuTk4Z9ToyMjUxMcfNzcbAQKtfP4e//35ACMnKKr59+9WoUd0ZLVOK0aN7Xr2awOXyCSEXLjyn/g2R/72ScvTo42nT+ggn5X/ztrY2iI/PFggEhJB//32nrq6io6Mh/2UTQqqq6jp00Ove3XLFigtffNHD0lJf/vfKBinEyLcYJWq7BKGlS0OPHXtsaan/9m2Jo6PxhQvzOnTQY7qoekVHv162LDQ/v6K0lO3sbDZ2bK/AwOEVFbVDh/5RVsbmcHhOTiZXry5QV5evQ5UzZx45fTqme3dLatLV1Zq6xdGcOccvXHhuYaFXWsq+d2+pvP31Fhh4bu/eKDs7o9zc8vbtNf/5J6BXLysi92WLcnZeu3nz2NGjexJCjhx5tGjRmU6dTFNTC44dmyG8G5mcKCqqsrFZYWWlz2Kx3r4tCQoaTV309vz5O1/fnR066L15UzR/vs+GDV8wXam42toPo0b99fp1oa6uJpvNCQ9faG9vJP97JSEkN7fc2vqn9PSNNjb/f3saOd+88/Mrhg3bwWZzTE114uOzt2wZO2/eQCL3ZRNCTEx+MDdvn5tbbmNjcPnyfOpIj3zulTU1HwYNCq6p+ZCQkO3hYWtra3j69GypM4kijHyLQcCSIjOzODe33NRU187OUPT3bnKouLg6IeH/74DVoUP7jh1NCSF8vuDFi/eqqsrUHQ7lzatXuaLnXvX0NHv2tKJev35dWFxc3bOnpXyeuc/OLnv7tsTQUMvBwZi6yyhFzssWevo0097eyMjoPxfSFhZWpqcXOjub6eu3Y7YwqdhsTkpKvkAgcHIy0dHREM6vqfnw4sW7Dh30rK0NGCxPtsTEHB6P37mzufCSfDnfKwkhRUVV6ekFffrYi82X882bzxekpuZXVtY6OZno6f3/liznZVdU1CYl5ejqanbpYi46Xw73Sh6Pf/9+unCyXTs1Dw9bqTOp13I+8i0GAQsAAACAZm335CgAAADAJ4KABQAAAEAzBCwAAAAAmrXpC9Bky8hQyOfkKCkp5HV1KLslKWjZiktBBxxltyQFLZsQYm8v/qsIoCBgSbd3794FyxaoaCja+PAJ0dAkHB7TdTQZS9eIX17OdBVNxlI14lcXMV1Fk6kIdPjcCiLfv5CVxON9UCNKKsoKtlcKCF+TKHPIh4abyhk9Finjc5iuosmMdFhFtYr3b6BOe1LBFsj579Yl1dZyg4KCFy1axHQh8kjB/qlqMY8fP+ZN4PEOK9pemku09w2tWjeE6TqarP30l+VBB5iuosnaj5lcbneS6SqaTOvxZId3+5SJDtOFNE0u2R5IerpyfZgupGmKSG6s9g/rqkYzXUiTzWn/w75yPtNVNNlk6+qTfqVMV9Fkk+O0912t0lGwnZJ88w35999/ma5CTuEaLAAAAACaIWABAAAA0AwBCwAAAIBmCFgAAAAANEPAAgAAAKAZAhYAAAAAzRCwAAAAAGiGgAUAAABAMwQsAAAAAJohYAEAAADQDAELAAAAgGYIWAAAAAA0Q8ACAAAAoJmSQCBgugZ5tHXr1pU/r2RpKFoA5ROiqk54ivedstrp8aurma6iyVjK+vyaUqaraDIVvhafX6VElJgupGl4fI4qYamwVJgupGkEhK9GCI/wmS6kybRZgio+l+kqmkxfi5RyFG+0tdqTKjZRUrCdktTW8n/5JSgwMJDpQuQRAla9MjIymC6hOZSUFPI7RdktSUHLVlwKOuAouyUpaNmEEHt7e6ZLkFOK+o0CAAAAyC1FOwUGAAAAIPcQsAAAAABohoAFAAAAQDMELAAAAACaIWABAAAA0AwBCwAAAIBmCFiKLTU1defOnTdv3iSE5Ofn79mz5+XLl4QQHo9XVFQkEAjCw8MJIUeOHOHxeElJSW/evGG4YpBLFy5c+PPPPz98+PDhw4fDhw9TWxQhJC8vjxASFhZGCImIiMjIyGCz2ffu3WOyVpBXAoFg+/btXC6XEBIWFnb06FEej0cIKSoq4nK5kZGRVVVVmZmZd+/eJf/dqABaMQQsxbZ58+Zu3bpduXKFej1z5szdu3cTQvbs2bN+/foPHz5cuXKFx+OdO3cuNjb2xIkTenp6TJcMcufEiRN8Pn/s2LEqKip79uzp06dPYmJiRkZGeHj4vn37oqOjHzx4UF5eHhkZGRYWFhUVVVlZyXTJII/2798fFxfH5XLj4+PfvXvn4uJy6NChsrKyoKCgkJCQqqqqyMjIK1eu3L9/v6qqKioqiul6AT4tBXvoBIjx9fWtqqpisViEEB6Pp66urq+vX1tbO3fu3MrKSjU1NUNDw1u3bs2fP//Ro0dlZWX6+vpMlwxyJzY21sbGJjIyct68eenp6QsXLnz37l1aWpqvr6+7u7uxsXF1dfXt27e1tLRqamoiIyNXrFjBdMkgd27fvl1VVcXn89+8eZOSkuLi4tKtW7eTJ0/q6emtWrVKX1+fzWZv3Lixffv27du3v3Xrlo+PD9MlA3xaOIKl2C5fvjx06NCysjIul6usrFxXV1daWqqhoaGiokJlqcGDBwcFBfn4+OTl5RkZGTFdL8ijTp069e7du1u3bvn5+U5OTq9evUpISHByciKEGBsbE0K8vb23b9/u4eGhpqZWUlKiq6vLdMkgd7p06eLl5UW97tSp08uXL+Pj4zt37kwIMTQ0ZLFY2traZWVlampqHh4ev//++4ABAxitF+CTU163bh3TNUDzderU6dSpU1988YWtrW2vXr2OHTs2YcIEExMTYQMLCws+n+/p6UkI6devHzIWSOrVq9fdu3e1tLT8/PxcXV3DwsIcHBx69+4tbKCqqsrlcv38/ExNTU1NTR0dHRmsFuSTjo6OpaWljo6Ou7u7ubl5Xl5eVlbW9OnTqePrFDU1NU9PTxcXFx6PJ0xjAK0VnkUIAAAAQDOcIgQAAACgGQIWAAAAAM0U71eEpaWloaGhTFcBtOHz+aJXaQAAAIiZMGGCwv0KXvECVmho6JkzZ/A7Jhk+fPhQWVlpYGDAdCGEEMLlctPS0hwdHVVVVSXfFQgE8fHx3t7eUt8FZmVmZtra2jJdBSg2bEXw8TIzM9++fbtx40amC2kaxQtYhJBevXrhHioyFBcXx8bGDh8+nNkyjh8/fu3aNULI4MGDZ82aJbVNVFTUlStX7t27Z2Nj07LVQcPWrVuHXxnDR8JWBB9v5cqVfD6f6SqaTCEDFsi/s2fP3rp1KyQkRFtbW0azW7duTZ06FekKAABaGVz7ArSpra2lXsTHx584ceKHH36Qna6ePHmSkpKCg5EAAND6IGABDaqrq+fPnx8QEJCUlEQIadeuHZ/P79atm4wuv/7669mzZ0eOHDljxoyWKhMAoEWdPHkyMDCQ6SqAGQhY8FHi4+N37NgREhLi5eVVXV3N4/EIIWZmZqqqqhs3bpRx1rympubVq1dnz55twWIBAFpUUFBQeHh4UVER04UAA3ANFjQTn88vLS3966+/1NXVCSGlpaWurq5aWlqEEG1t7SVLlhw+fHj58uX+/v5iDx07f/7848ePf/zxR2bqBgBoKWPGjElNTcUzytomBCxopnnz5rFYrHXr1uXk5CQnJ0+ZMkX03X79+t24cePu3bvz5s1bsWKFubn5hAkTzM3NCwoKnj17Rp1JBABo3TZs2MB0CcAYnCKEZlq9erWamtqwYcMePXqUk5Mj2cDY2DgpKenUqVNPnjzZsGHDr7/+SggJDg6+cOFCixcLAADQohCwoJkOHTrE4/EeP36cmpqampoq2WDUqFHLli0jhLRr187T01NHR2fjxo0BAQF2dnYtXiwAAECLQsCCxqqqqqqqqhJODhgwwN/fPzw8XFlZWeqtFmxsbGxsbBYuXEgI4XA4GhoaP/7446JFi1qsYAAAAKYgYEFjnTlz5uLFi8LJ/Pz8Xr16ffPNN1VVVcrKylK7TJ069eXLl6NGjSKExMTEjBs3roVqBQBok1auXOnj4zN+/Pi0tDSma2nrELCgUe7evXvt2rXu3bsL52RnZ7u6up46dcrJyenly5dcLldqx6VLlxYVFSUnJ7dUpQAArZynp2fXrl23bNnCZrPF3jp+/PjYsWP79es3YsQIRmoDIQQsaNjJkyd37dq1ZMkSYcAKDQ21sbGJjo7et2+fjo5Ofn7+5MmT8/PzJftmZWU9f/5cQ0OjZUsGAGgluFyus7Ozi4vLzp07s7Ozi4qK7t+/7+zsvGHDBm1t7V69ej158kTY+MKFC5GRkWfPnv3iiy8YrBkIAhY0xvXr1319ffv378/hcIRzWCzW8ePHCwoKCgoK9u/f/88//5iamkr2tbKy2rNnT0BAQMuWDADQSqioqAwbNkxHR+fevXve3t5+fn59+vRxdXUtKyt7+fKlq6trYmKisLGbm9u5c+eio6O3bdvGYM1AcB8saAw+n//o0aPIyEhzc/ORI0f6+PhMnTr1zz//VFdXv3DhQm1tbUFBgYmJCYfDyc/Pt7KyEu3LYrG2bt2qo6PDVPEAAIpu586dhJCqqqrhw4fX1tbyeLzNmzffvHkzMjLywIEDTFcH0iFgQcO+/PLLnJwcXV3da9eunTlzJioq6ttvv928efP69esdHR3Pnz8/Y8aM9+/fc7lcIyOjjRs3ivYtKCioqqq6d+8eU8UDALQO2tra0dHRhBDqKWQsFs5ByTUELGgY9TPAy5cvjxo1Kj4+Xltb+/jx4zU1NZ06dVq6dOmLFy8ePHjA4XB27tx5584d0Y4lJSW//PJLRUWFiYkJQ7UDALQ2iFYKAV8SNFZKSsqZM2f8/f09PDyUlZV5PN7EiRNzc3Opd9XU1IYMGZKenp6ZmUnN4fP5mzdvVlZWXrduHVM1AwAAMAIBCxrrxx9/XLx4cXBwsKWlZWBg4NKlSw8cODBy5EjqYDUhpFevXjwe79SpU9SjBo8cOWJtba2jo4ObiwIAQFuDU4TQBN7e3uXl5cuWLVu4cOGgQYM2b94cERExePDgiIgIqsHTp0/37dv36NEjW1vb1NTUvLy8lJQURksGAAAp2Gx2jx49LC0tV6xYoa6unpeXV1lZ6eTkNHDgQKZLayUQsKBp/Pz8VFRUdu3a9fbt26+//trJySk+Pl74bkFBwZEjRzZv3rxjx44dO3YMHjyYwVIBAKA+7dq1MzQ0LC0tnTdvnqWlpZGREZvNjo2NLSwsZLq0VgIBC5psxIgRHh4eAQEBT58+VVNT2717NzWfz+dPmDBh7dq1hYWFfD4f6QoAQJ49fvz48ePHt27devjwYX5+vqmp6cmTJ5kuqvVAwILmMDAwCAkJCQkJef/+va2tLTVzw4YNHh4eurq6Bw8enDFjBqMFAgBAw/r06dOnTx+mq2idcJE7NNm2bduuXLliYGDw008/eXt7z5o1i5p/8eJFd3f3wMBAV1fXqVOnMlskAAAAg3AECxpWVVWVlJSkra1ta2vbrl27CRMmLF26tLCwcPDgwU+ePKHuyFJUVKSqqnrw4MGoqCjc9QoAANo4BCxoWH5+/sGDB8vKympqamxsbHr27DlnzpyjR49ev35969atCxYsIIRERUUZGRkVFxcjXQEAACBgQcMcHBz27t1LCMnIyAgNDY2Ojr58+fKYMWNMTEx27do1btw4c3PzAQMGzJ49+9q1a0wXCwAAwLw2cQ1WRUUF0yW0Evb29suXLz9w4IC7u/ubN2/S09NHjBjxww8/EEKow1eenp5M1wgAAM305s2bs2fPMl1FK9EmAlZwcPDy5cuZrqJVWbJkiUAg4PF4UVFR79+/nzdv3qFDh9hsNtN1AQBA840dO3bKlClr165lupDWoE0ErEmTJmVmZlIPIQdaaGlp/fzzz5WVlXp6elOnTjU3N79+/foXX3zBdF0AANB8T548KSwsRMCiRZu4BsvZ2dnOzu7ixYv9+vVjupbWg8VirVmzhnptbm7u6uq6evVqPp+Px7wDACgoNTU1NTU1pqtoJdrK/wsnTZqUlZVFPYQYPpGcnJygoCCmqwAAAGBeWwlYPXr00NfXv3fvHtOFtFp8Pr+uru7IkSNMFwIAAMC8thKwCCFmZmb5+flMV9FqZWRkuLu7v3v3jsvlMl0LAAAAw9pQwCoqKqquruZwOEwX0jo5OjpWV1ezWKy///6b6VoAAAAY1oYClqWlZV5eHu7w8fEyMjLKy8uFk1wud8WKFatWrbKxseFyudQtSQEAANqyNhSwVqxYYW1t/fr1a6YLUXiXLl26ePEiIaSiomL16tUTJ05s165dTExMnz59tLW1U1JSYmJimK4RAACASW3iNg0UPp+fnp4+ffp0pgtReBYWFvfu3Xv9+nVVVdWpU6f09PSKiorU1NSWLFmyaNGiwMDA8ePHZ2VlMV0mAAAAY9pQwMrOztbV1R0+fDjThSg8e3v7Fy9e8Pl8bW3tBQsWCASC9u3bl5eXd+jQ4eXLlx4eHsXFxQcPHpw5cybTlQIAADCjDQUsKyurAwcOMF1Fa+Du7u7u7i42c+HChVpaWr///vsvv/zSqVOnU6dOIWABAECb1YauwYJPh81m5+bmOjs7s1gsFRWVuLi4jh07Hjx4kOm6AAAAmIGABTRo167dihUrfH19//zzTy8vL0KInp7elStXmK4LAACAGQhY0FgZGRmbNm2ibtb64sWLJUuWVFVVCd91cHAIDAz08/P7448/CCEdOnQoKChgrFYAAABGtaFrsOAj2dvbKysrf/fdd0pKSg4ODgEBAStWrOjcufPAgQPV1dV37959/vx5FxcXqvGjR4+sra2ZLRgAAIApCFjQBIGBgYSQx48f37x58+zZsw8ePEhOTj569Cibzb5z546VlRXVjMPh3L179/Dhw0zWCgAAwBwELGiyPn36eHh4LF++nMPhDBkyZMiQIdR8Npu9bds2Pz+/4cOHOzs7Dxs2jNk6AQAAmIKABY21Z8+eoqKiVatWsVisGzdu+Pr62tnZiTbo06dP3759HR0d8VBtAABo4xCwoLHmzJkzc+bMKVOm2NjYKCsrjx49evr06Vu2bDE3N6caxMfHM1shAACAnGi7vyKsqqpKSEjIzs5muhCFwWKxDh48OH78eG1tbRMTk6KiIg0NDV9fX0dHx4qKCqarAwAAkCNt9AjW2rVrqcMtqqqqRkZGvr6+o0aNYrooBcBiscaNG8fn82/fvp2ZmfnixYvKysozZ87o6uoyXRoAAIAcaaMBa+LEiZMnT7a1tU1KSrp69erp06fv3r07evRoHx8fpkuTO4sXL96+ffuePXsKCwuVlJQ4HA4hhM1md+7cuby8/Pz584MHD2a6RgAAAPnSRgNW165dqReurq6urq6pqamHDx/euXOnkZGR8E5OQMnLy1u1atXMmTMXLVoknJmbmxsSEvLtt98iXQEAAEhqowFLTMeOHYOCgjIyMnBvTFF8Pn/Pnj29e/e+d++e2Fvm5uY///wzI1UBAADIv7Z7kbske3t7FRUkzv9ITk4ODAycPHmyZLoCAAAA2ZAnQIqbN28+e/bs4cOHBgYGTNcCAACgeBCw4H8UFBSkpqY+fPgwNjaW6VoAAAAUFQIW/I87d+6cPn367du3TBcCAACgwHANlrx4+vTppEmTDh8+zGazW3jVfD5f+DozM1NfX9/CwqKFawAAAGhNcARLXjg7O2toaDx48CA5OXnz5s0tsEY+n79v3778/HxNTU0NDQ0+n19eXu7i4hIWFtYCawcAAGjFELDkha6u7qFDh/79998tW7asXbt2/fr1n3R1YWFhkZGRy5cv//rrrz/pigAAANogBCw5smrVqpycHA6Hk5aWVlFR8emeP7N9+3Y7O7ukpKRPtHwAAIA2DgFLjkybNk1HR+dTX/90+PBhV1fXrVu3ftK1AAAAtGUIWHLE2dn5U68iPDxcSUkJ6QoAAOCTQsBqK7hc7vz5842MjF68eMF0LQAAAK0cbtPQVtTV1eXn53/++edMFwIAAND6IWC1Ffn5+c7OzkFBQUwXAgAA0PrhFGHrd/369SdPnmhoaERERDBdCwAAQJuAgNXKhYeHZ2dnh4WFmZiYMF0LAABAW4GA1TqVl5c/f/7833//zc7Ovn37tra2NtMVAQAAtCG4Bqt1ysjIOHbs2KBBgx4/fox0BQAA0MJwBKu1efXq1cOHD1+/fv3w4UM7OzumywEAAGiLELAUXkVFxZYtW9TV1S0sLBITEz09Pfv27evr64t0BQAAwBScIlRsW7duLSgosLe3Z7FY06ZNi4+PP3bs2JQpU5SUlJguDZopPz+fzWYzXQUAAHwUBCzFlpSUtH79+nfv3qmqqo4dO1ZDQ4PpiuCjnD592s7O7vnz50wXAgAAHwUBS7HNmjWrR48es2bNioyMZLoWoMHevXv/+usvLy8vpgsBAICPgmuwFFhERMTVq1eDg4PxAJxWAzeDBQBoHRCwFNi1a9eSk5OZrgIAAADEIWAppLCwsMePH48YMYLpQgAAAEAKBCyFFBYWFhMTY2pqynQhAAAAIAUuclc8QUFBffr0QboCAACQWziCpWCqq6vfvHlz8+ZNpgsBAACAeuEIloJJTU2tq6vD4wUBAADkGQKWIikrK7tw4cKOHTuYLgQAAABkQcBSJDdv3mSz2dOmTWO6EAAAAJAFAUth5ObmpqSkWFhYMF0IAAAANAABS2E8efKkf//+N27cYLoQAAAAaAAClsJIS0tzcXFRUcEPPwEAAOQdApbCePHixaFDh5iuAgAAABqGgKUwBAJB3759ma4CAAAAGtaGAlZWVta6dev4fD7ThTSThYXFxIkTma4CAAAAGtaGAtapU6f69+9/+vRpybeSkpIePHhw//79lq+q8fz9/Y8fP850FQAAANCwNnTFdG1t7dy5c+fOnSs2n8vl7tmzx9bWtqSkxNvbmxBSV1d38ODB/Px8Pp9fVlbm7e09YcIEJkr+Hx4eHrjFKAAAgEJoJQErMjKysrLyzZs3+fn5qqqqAoGAxWKpqqqy2WwVFRUej0cIsbKy6tixI4fDCQsL+/zzz1NSUrZt27Z69erdu3dXV1dHRkYaGhr+/PPPqqqqysrKixcvvnnz5qFDh9TV1Z89eyYPAUtdXb22tpbpKgAAAKBhChmwMjIyioqKRowYQT2S78iRI3w+v0+fPt98802fPn2oNt9991379u1/+eUXNTW1TZs2Xblyhc/nr1y5ksPhHD9+PDY2lsPhGBsbX7p0af369Wpqai4uLjY2NqJrmTBhwr59+8LCwkJCQlatWuXo6Pjll18ePXr0zZs3W7duZeBjE8LlcrlcLu7UAAAAIOcY/l91aWnpiRMniouL58yZY2Jisn37dg6HExAQYGBgEB4e3rVrVx6Pt2nTppCQkAMHDkybNk1NTY0Q4u3tnZiYOG/ePH19fR0dnc8//3zjxo1LlixxcXERLnnkyJE7d+4sLS01NTV1dHT08/Pr3bt3owd2tgAAIABJREFUaWlp165dnZ2dO3XqpKur22B5LBbL39/f39+fEHLixIktW7a0b9++srLy0w2IbD169Ni+ffsPP/zAVAEAAAAMunnz5suXL01MTKZOnfro0aMnT55YWFhMmDAhMzMzOTl5xIgR69atGzZsmKen54EDBwICAhgsleGApa+v37Nnz71797569erVq1d2dnYeHh779++fM2dORkZGbW2tk5NTWVnZ1atX37x5Q/0AkM/nHzt2zNDQUFtbe9myZTU1NQ8fPhw2bFh0dDR1iRL1SBk/Pz8/Pz9qLbSc4JsyZcqUKVOKioq6du367t07KysrGY3T0tKOHTumqqqqpKRUXV09ZswYDw+Pj6/B398/ODgYAQsAANqmAQMGxMfHh4eHT5069dSpUzt37lyyZMn48eOfPXuWlZU1aNCgysrKkydP9u7dOyMjg9lSmT/Z1L9/fx0dndra2vfv3xsbGxsZGRUXF+vp6c2fP58Q8vLly5EjR966dUtTU5Nqz2KxzMzMysvLNTQ04uLibty4oaGh0a9fvx9++GHLli2EkMrKyl27dq1cufITFRwQELB+/Xp7e3snJyepDTgczp07d+bNm0fVzOFwzp07t3///p49e5qamn7k2rOysqiPKUNFRUVycnJJSclHrgvauOjo6AY3NgDZsBXBx3v58qXwDJWGhsaCBQv++ecfQoiSkhIhRFNTk8PhjB07lmqgpKQ0efLkEydOMFWtEMMB6/Xr12/fvo2NjXVwcOjTp8+OHTsSExOHDh0q1mz27Nm+vr7r1q2jJrt06eLj4xMVFRUTE7Nu3ToVFZUTJ04cPXqUepfL5R46dGj58uWfruwNGzYM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", + "text/plain": [ + "" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "Image(result_url)" ] diff --git a/shearwater/processes/wps_cyclone.py b/shearwater/processes/wps_cyclone.py index 765db14..6751ece 100644 --- a/shearwater/processes/wps_cyclone.py +++ b/shearwater/processes/wps_cyclone.py @@ -30,7 +30,8 @@ def __init__(self): "init_date", "Initialisation date", data_type="string", - abstract="Enter an initialisation date between 1940-01-01 and 2024-12-31.", + abstract="""Enter an initialisation date between 1940-01-01 and 2024-12-31. + Note that the years 1980-2015 have been used for training and tuning the ML models.""", default="2024-07-03" ), LiteralInput( @@ -108,7 +109,7 @@ def _handler(self, request, response): try: from tensorflow.keras import models except Exception as ex: - msg = 'models from tensorflow.keras could not be imported.' + msg = 'Models from tensorflow.keras could not be imported. Reason for the failure: {} '.format(ex) LOGGER.error(msg) try: @@ -119,11 +120,13 @@ def _handler(self, request, response): region = request.inputs['region'][0].data LOGGER.info(region) except Exception as ex: - msg = 'Input variables could not be set.' + msg = 'Input variables could not be set. Reason for the failure: {} '.format(ex) LOGGER.error(msg) - ### Check validity of input date - if ((pd.Timestamp(init_date)>=pd.Timestamp('1940-01-01')) & (pd.Timestamp(init_date)<=pd.Timestamp('2024-12-31'))): + # Check validity of input date + VALIDstr = pd.Timestamp('1940-01-01') + VALIDend = pd.Timestamp('2024-12-31') + if ((pd.Timestamp(init_date) >= VALIDstr) & (pd.Timestamp(init_date) <= VALIDend)): msg = 'Input date is valid.' LOGGER.info(msg) @@ -135,8 +138,9 @@ def _handler(self, request, response): [34, "sst", [0]], [137, "tcwv", [0]], ] + reso = 2.5 - + regions_dict = { "Southern Indian": [0, 20, -30, 90], # Southern Indian "North Atlantic": [40, -90, 10, -20], # North Atlantic @@ -146,7 +150,7 @@ def _handler(self, request, response): "East Pacific": [30, -170, 0, -100], # East Pacific "South Pacific": [0, 160, -30, 230], # South Pacific } - + lags_dict = { "0-48 h": 0, "24-72 h": 1, @@ -163,7 +167,7 @@ def _handler(self, request, response): "288-336 h": 12, "312-360 h": 13, } - + region_string = { "Southern Indian": "Sindian", # Southern Indian "North Atlantic": "Natlantic", # North Atlantic @@ -173,17 +177,18 @@ def _handler(self, request, response): "East Pacific": "Epacific", # East Pacific "South Pacific": "Spacific", # South Pacific } - + region_bbox = regions_dict[region] lag = lags_dict[leadtime] - + data = pd.DataFrame() - + if mv: for param1 in parameters: path = f'/pool/data/ERA5/E5/{"sf" if param1[2]==[0] else "pl"}/an/1D/{str(param1[0]).zfill(3)}' + filename_part2 = f'{init_date[:7]}_{str(param1[0]).zfill(3)}' fs1_param = mv.read( - f"{path}/E5{'sf' if param1[2]==[0] else 'pl'}00_1D_{init_date[:7]}_{str(param1[0]).zfill(3)}.grb" + f"{path}/E5{'sf' if param1[2]==[0] else 'pl'}00_1D_{filename_part2}.grb" ) fs1_param = fs1_param.select( date=init_date.replace("-", ""), level=param1[2] @@ -204,7 +209,7 @@ def _handler(self, request, response): .to_dataframe() .reset_index(drop=True)[param1[1]] ) - + data.loc[:, ["latitude", "longitude"]] = ( fs1_param_interp.select(level=level) .to_dataset() @@ -216,7 +221,7 @@ def _handler(self, request, response): (data.u_200 - data.u_850) ** 2 + (data.v_200 - data.v_850) ** 2 ) ** 0.5 data.loc[:, "sst"] = data.sst.fillna(0) - + else: reg = region_string[region] data1 = pd.read_csv( @@ -225,7 +230,7 @@ def _handler(self, request, response): f"https://github.com/climateintelligence/shearwater/raw/main/data/test_dailymeans_{reg}_2.zip") data = pd.concat((data1, data2), ignore_index=True) data = data.loc[(data.time == init_date)] - + variables = [ "vo", "r", @@ -237,53 +242,56 @@ def _handler(self, request, response): "sst", "shear", ] - + means, stds = pd.read_pickle( "https://github.com/climateintelligence/shearwater/raw/main/data/full_statistics.zip") - + data[variables] = (data[variables]-means[variables])/stds[variables] - - number_of_img, rows, cols = len(data.time.unique()), len(data.latitude.dropna().unique()), len(data.longitude.dropna().unique()) + + sz_lat = len(data.latitude.dropna().unique()) + sz_lon = len(data.longitude.dropna().unique()) + number_of_img, rows, cols = len(data.time.unique()), sz_lat, sz_lon images = np.zeros((number_of_img, rows, cols, len(variables))) df = data.sort_values(by=['time', 'latitude', 'longitude']) verbose = False k = 0 for day in range(0, number_of_img): - + a = df.iloc[377*day:377*(day+1)] i = 0 for var in variables: - images[day, :, :, i] = a.pivot(index='latitude', columns='longitude').sort_index(ascending=False)[var] + anew = a.pivot(index='latitude', columns='longitude').sort_index(ascending=False)[var] + images[day, :, :, i] = anew i += 1 k += 1 if ((k % 100 == 0) & (verbose is True)): print(k) - + test_img_std = images - + test_img_std = np.pad(test_img_std, ((0, 0), (1, 2), (1, 2), (0, 0)), 'constant') - + workdir = Path(self.workdir) LOGGER.info(workdir) - model_path = os.path.join(workdir, f"Unet_sevenAreas_fullStd_{lag}lag_model.keras") + model_path = os.path.join(workdir, f"UNET020_sevenAreas_fullStd_{lag}lag_model.keras") git_path = "https://github.com/climateintelligence/shearwater/raw/main" urllib.request.urlretrieve( - f"{git_path}/data/Unet_sevenAreas_fullStd_{lag}lag_model.keras", + f"{git_path}/data/UNET020_sevenAreas_fullStd_{lag}lag_model.keras", model_path ) - + model_trained = models.load_model(model_path) - + prediction = model_trained.predict(test_img_std) - + data = data[["latitude", "longitude", "time"]] data[f'predictions_lag{lag}'] = prediction.reshape(-1, 1) - + workdir = Path(self.workdir) outfilename = os.path.join( workdir, f'tcactivity_48_17_{init_date.replace("-","")}_lag{lag}_{region_string[region]}' ) - + if mv: predscol = f"predictions_lag{lag}" gpt = mv.create_geo( @@ -292,7 +300,7 @@ def _handler(self, request, response): values=data[predscol].values, ).set_dates([pd.Timestamp(init_date)] * data.shape[0]) fs = mv.geo_to_grib(geopoints=gpt, grid=[2.5, 2.5], tolerance=1.5) * 1e2 - + # cont_gen = mv.mcont( # legend="on", # contour_line_colour="avocado", @@ -313,7 +321,7 @@ def _handler(self, request, response): # contour_shade_min_level_colour="blue", # contour_shade_colour_direction="clockwise", # ) - + cont_oper = mv.mcont( contour_automatic_setting="style_name", contour_style_name="prob_green2yellow", @@ -322,44 +330,48 @@ def _handler(self, request, response): coastlines = mv.mcoast( map_coastline_land_shade="on", map_coastline_land_shade_colour="grey" ) - + gview = mv.geoview( map_area_definition="corners", area=region_bbox, coastlines=coastlines ) legend = mv.mlegend( legend_text_font_size=0.5, ) - + + VTstr = (pd.Timestamp(init_date) + pd.Timedelta(str(lag)+'d')).strftime('%Y-%m-%d') + ' 00Z' + laggg = pd.Timedelta(str(2)+'d') + VTend = (pd.Timestamp(init_date) + pd.Timedelta(str(lag)+'d') + laggg).strftime('%Y-%m-%d') + ' 00Z' + subtitle1 = f"{region}, Initialisation: {init_date} 00Z, Lead time: {leadtime}" + subtitle2 = f", Valid time: {VTstr+' to '+VTend}" title = mv.mtext( text_font_size=0.50, text_lines=[ "Probability of tropical cyclone activity", - f"{region}, Initialisation: {init_date}, Lead time: {leadtime}", + subtitle1 + subtitle2, "", ], text_colour="CHARCOAL", ) - + mv.setoutput(mv.png_output(output_name=outfilename)) mv.plot(gview, fs, cont_oper, legend, title) response.outputs["output_png"].file = outfilename + ".1.png" - + data.to_csv(outfilename + ".csv") response.outputs["output_csv"].file = outfilename + ".csv" else: xr_predictions = xr.Dataset.from_dataframe(data.set_index(['time', 'latitude', 'longitude'])) xr_predictions = xr_predictions[f'predictions_lag{lag}'] - + figs, axs = plt.subplots() xr_predictions.plot(ax=axs) plt.savefig(outfilename + ".png") - + response.outputs["output_png"].file = outfilename + ".png" - + data.to_csv(outfilename + ".csv") response.outputs["output_csv"].file = outfilename + ".csv" - else: msg = f"Input date '{init_date}' outside the allowed period." LOGGER.error(msg) From 567a73f52df6706f4f806183698cc1c171edf890 Mon Sep 17 00:00:00 2001 From: Pingu Carsti Date: Tue, 13 May 2025 15:16:47 +0200 Subject: [PATCH 4/5] update conda spec-list.txt --- spec-list.txt | 572 ++++++++++++++++++++++++++------------------------ 1 file changed, 302 insertions(+), 270 deletions(-) diff --git a/spec-list.txt b/spec-list.txt index 4cb7941..7ddc075 100644 --- a/spec-list.txt +++ b/spec-list.txt @@ -2,84 +2,102 @@ # $ conda create --name --file # platform: linux-64 @EXPLICIT -https://conda.anaconda.org/conda-forge/linux-64/pandoc-3.5-ha770c72_0.conda +https://conda.anaconda.org/conda-forge/linux-64/pandoc-3.6.4-ha770c72_0.conda https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 -https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2024.8.30-hbcca054_0.conda +https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.4.26-hbd8a1cb_0.conda https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda -https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.43-h712a8e2_1.conda +https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.43-h712a8e2_4.conda +https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda +https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.1.0-h767d61c_2.conda https://conda.anaconda.org/conda-forge/noarch/poppler-data-0.4.12-hd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/linux-64/python_abi-3.11-5_cp311.conda -https://conda.anaconda.org/conda-forge/noarch/tzdata-2024b-hc8b5060_0.conda -https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-0.tar.bz2 -https://conda.anaconda.org/conda-forge/linux-64/libgomp-14.1.0-h77fa898_1.conda +https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-7_cp311.conda +https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2 +https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-0.tar.bz2 +https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda +https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 -https://conda.anaconda.org/conda-forge/linux-64/libgcc-14.1.0-h77fa898_1.conda -https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.1-heb4867d_0.conda +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.1.0-h767d61c_2.conda +https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.14-hb9d3cd8_0.conda +https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.5-hb9d3cd8_0.conda +https://conda.anaconda.org/conda-forge/linux-64/gettext-tools-0.24.1-h5888daf_0.conda https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.1.0-hb9d3cd8_2.conda -https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.6.3-h5888daf_0.conda -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-14.1.0-h69a702a_1.conda -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-14.1.0-hc5f4f2c_1.conda -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-14.1.0-hc0a3c3a_1.conda +https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.0-h5888daf_0.conda +https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.6-h2dba641_1.conda +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.1.0-h69a702a_2.conda +https://conda.anaconda.org/conda-forge/linux-64/libgettextpo-0.24.1-h5888daf_0.conda +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.1.0-hcea5267_2.conda +https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h4ce23a2_1.conda +https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.0-hb9d3cd8_0.conda +https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_1.conda +https://conda.anaconda.org/conda-forge/linux-64/libogg-1.3.5-hd0c01bc_1.conda +https://conda.anaconda.org/conda-forge/linux-64/libopus-1.5.2-hd0c01bc_0.conda +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.1.0-h8f9b012_2.conda +https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.5.0-h851e524_0.conda https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda -https://conda.anaconda.org/conda-forge/linux-64/openssl-3.3.2-hb9d3cd8_0.conda +https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda +https://conda.anaconda.org/conda-forge/linux-64/openssl-3.5.0-h7b32b05_1.conda https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda -https://conda.anaconda.org/conda-forge/linux-64/tzcode-2024b-hb9d3cd8_0.conda -https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.1-hb9d3cd8_1.conda -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.11-hb9d3cd8_1.conda +https://conda.anaconda.org/conda-forge/linux-64/rav1e-0.7.1-h8fae777_3.conda +https://conda.anaconda.org/conda-forge/linux-64/tzcode-2025b-hb9d3cd8_0.conda +https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.2-hb9d3cd8_0.conda +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb9d3cd8_0.conda https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb9d3cd8_0.conda -https://conda.anaconda.org/conda-forge/linux-64/xorg-xextproto-7.3.0-hb9d3cd8_1004.conda -https://conda.anaconda.org/conda-forge/linux-64/xorg-xf86vidmodeproto-2.3.1-hb9d3cd8_1003.conda -https://conda.anaconda.org/conda-forge/linux-64/xorg-xorgproto-2024.1-hb9d3cd8_1.conda -https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.12-h4ab18f5_0.conda +https://conda.anaconda.org/conda-forge/linux-64/xorg-xf86vidmodeproto-2.3.1-hb9d3cd8_1005.conda https://conda.anaconda.org/conda-forge/linux-64/attr-2.5.1-h166bdaf_1.tar.bz2 https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.9.13-hd590300_0.conda https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-h4bc722e_7.conda https://conda.anaconda.org/conda-forge/linux-64/dav1d-1.2.1-hd590300_0.conda -https://conda.anaconda.org/conda-forge/linux-64/expat-2.6.3-h5888daf_0.conda +https://conda.anaconda.org/conda-forge/linux-64/double-conversion-3.3.1-h5888daf_0.conda +https://conda.anaconda.org/conda-forge/linux-64/expat-2.7.0-h5888daf_0.conda https://conda.anaconda.org/conda-forge/linux-64/fribidi-1.0.10-h36c2ea0_0.tar.bz2 -https://conda.anaconda.org/conda-forge/linux-64/gettext-tools-0.22.5-he02047a_3.conda https://conda.anaconda.org/conda-forge/linux-64/giflib-5.2.2-hd590300_0.conda https://conda.anaconda.org/conda-forge/linux-64/json-c-0.17-h1220068_1.conda https://conda.anaconda.org/conda-forge/linux-64/jxrlib-1.1-hd590300_3.conda https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.1-h166bdaf_0.tar.bz2 https://conda.anaconda.org/conda-forge/linux-64/lame-3.100-h166bdaf_1003.tar.bz2 +https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda +https://conda.anaconda.org/conda-forge/linux-64/libasprintf-0.24.1-h8e693c7_0.conda https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.1.0-hb9d3cd8_2.conda https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.1.0-hb9d3cd8_2.conda https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.19-hd590300_0.conda +https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda -https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.2-h7f98852_5.tar.bz2 -https://conda.anaconda.org/conda-forge/linux-64/libgettextpo-0.22.5-he02047a_3.conda -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-14.1.0-h69a702a_1.conda -https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.17-hd590300_2.conda -https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.0.0-hd590300_1.conda +https://conda.anaconda.org/conda-forge/linux-64/libgettextpo-devel-0.24.1-h5888daf_0.conda +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.1.0-h69a702a_2.conda +https://conda.anaconda.org/conda-forge/linux-64/libgpg-error-1.55-h3f2d84a_0.conda +https://conda.anaconda.org/conda-forge/linux-64/liblzma-devel-5.8.1-hb9d3cd8_1.conda https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hd590300_0.conda -https://conda.anaconda.org/conda-forge/linux-64/libogg-1.3.5-h4ab18f5_0.conda -https://conda.anaconda.org/conda-forge/linux-64/libopus-1.3.1-h7f98852_1.tar.bz2 -https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.44-hadc24fc_0.conda +https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hd590300_0.conda +https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.47-h943b412_0.conda https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.20-h4ab18f5_0.conda -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.46.1-hadc24fc_0.conda -https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.0-h0841786_0.conda -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-14.1.0-h4852527_1.conda +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.49.2-hee588c1_0.conda +https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.1.0-h4852527_2.conda https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda -https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.4.0-hd590300_0.conda https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda https://conda.anaconda.org/conda-forge/linux-64/lzo-2.10-hd590300_1001.conda https://conda.anaconda.org/conda-forge/linux-64/m4-1.4.18-h516909a_1001.tar.bz2 -https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-he02047a_1.conda -https://conda.anaconda.org/conda-forge/linux-64/rav1e-0.6.6-he8a937b_2.conda +https://conda.anaconda.org/conda-forge/linux-64/mpg123-1.32.9-hc50e24c_0.conda +https://conda.anaconda.org/conda-forge/linux-64/nspr-4.36-h5888daf_0.conda +https://conda.anaconda.org/conda-forge/linux-64/pixman-0.46.0-h29eaf8c_0.conda +https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda https://conda.anaconda.org/conda-forge/linux-64/s2n-1.4.5-h06160fa_0.conda +https://conda.anaconda.org/conda-forge/linux-64/svt-av1-3.0.2-h5888daf_0.conda https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h4845f30_101.conda -https://conda.anaconda.org/conda-forge/linux-64/xz-5.2.6-h166bdaf_0.tar.bz2 +https://conda.anaconda.org/conda-forge/linux-64/wayland-1.23.1-h3e06ad9_1.conda +https://conda.anaconda.org/conda-forge/linux-64/xz-gpl-tools-5.8.1-hbcc6ac9_1.conda +https://conda.anaconda.org/conda-forge/linux-64/xz-tools-5.8.1-hb9d3cd8_1.conda https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h7f98852_2.tar.bz2 https://conda.anaconda.org/conda-forge/linux-64/zfp-1.0.1-h5888daf_2.conda https://conda.anaconda.org/conda-forge/linux-64/zlib-1.3.1-hb9d3cd8_2.conda https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.0.7-h0b41bf4_0.conda +https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb8e6e7a_2.conda https://conda.anaconda.org/conda-forge/linux-64/aom-3.9.1-hac33072_0.conda https://conda.anaconda.org/conda-forge/linux-64/aws-c-cal-0.6.10-hb29e0c7_1.conda https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.2.18-hecc5fa9_1.conda @@ -89,314 +107,328 @@ https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.1.0-hb9d3cd8_2.cond https://conda.anaconda.org/conda-forge/linux-64/charls-2.4.2-h59595ed_0.conda https://conda.anaconda.org/conda-forge/linux-64/flatbuffers-23.5.26-h59595ed_1.conda https://conda.anaconda.org/conda-forge/linux-64/flex-2.6.4-h58526e2_1004.tar.bz2 -https://conda.anaconda.org/conda-forge/linux-64/freetype-2.12.1-h267a509_2.conda +https://conda.anaconda.org/conda-forge/linux-64/gdbm-1.18-h0a1914f_2.tar.bz2 https://conda.anaconda.org/conda-forge/linux-64/geos-3.12.1-h59595ed_0.conda https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.13-h59595ed_1003.conda https://conda.anaconda.org/conda-forge/linux-64/hdf4-4.2.15-h2a13503_7.conda https://conda.anaconda.org/conda-forge/linux-64/icu-73.2-h59595ed_0.conda -https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h27087fc_0.tar.bz2 +https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda https://conda.anaconda.org/conda-forge/linux-64/libabseil-20230802.1-cxx17_h59595ed_0.conda https://conda.anaconda.org/conda-forge/linux-64/libaec-1.1.3-h59595ed_0.conda -https://conda.anaconda.org/conda-forge/linux-64/libasprintf-0.22.5-he8f35ee_3.conda -https://conda.anaconda.org/conda-forge/linux-64/libcap-2.69-h0f662aa_0.conda +https://conda.anaconda.org/conda-forge/linux-64/libasprintf-devel-0.24.1-h8e693c7_0.conda +https://conda.anaconda.org/conda-forge/linux-64/libcap-2.71-h39aace5_0.conda https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.bz2 -https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20191231-he28a2e2_2.tar.bz2 -https://conda.anaconda.org/conda-forge/linux-64/libgettextpo-devel-0.22.5-he02047a_3.conda -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-14.1.0-h69a702a_1.conda +https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.124-hb9d3cd8_0.conda +https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.13.3-h48d6fc4_1.conda +https://conda.anaconda.org/conda-forge/linux-64/libgcrypt-lib-1.11.1-hb9d3cd8_0.conda +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.1.0-h69a702a_2.conda https://conda.anaconda.org/conda-forge/linux-64/libhwy-1.1.0-h00ab1b0_0.conda -https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.58.0-h47da74e_1.conda +https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.64.0-h161d5f1_0.conda +https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.29-pthreads_h94d23a6_0.conda https://conda.anaconda.org/conda-forge/linux-64/libvorbis-1.3.7-h9c3ff4c_0.tar.bz2 -https://conda.anaconda.org/conda-forge/linux-64/libzip-1.11.1-hf83b1b0_0.conda +https://conda.anaconda.org/conda-forge/linux-64/libzip-1.11.2-h6991a6a_0.conda https://conda.anaconda.org/conda-forge/linux-64/libzopfli-1.0.3-h9c3ff4c_0.tar.bz2 https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.9.4-hcb278e6_0.conda -https://conda.anaconda.org/conda-forge/linux-64/mpg123-1.32.6-h59595ed_0.conda +https://conda.anaconda.org/conda-forge/linux-64/minizip-4.0.10-h05a5f5f_0.conda https://conda.anaconda.org/conda-forge/linux-64/mysql-common-8.3.0-h70512c7_5.conda -https://conda.anaconda.org/conda-forge/linux-64/nspr-4.35-h27087fc_0.conda +https://conda.anaconda.org/conda-forge/linux-64/nss-3.111-h159eef7_0.conda https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.43-hcad00b1_0.conda -https://conda.anaconda.org/conda-forge/linux-64/pixman-0.43.2-h59595ed_0.conda -https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8228510_1.conda +https://conda.anaconda.org/conda-forge/linux-64/python-3.11.12-h9e4cc4f_0_cpython.conda +https://conda.anaconda.org/conda-forge/linux-64/qhull-2020.2-h434a139_5.conda https://conda.anaconda.org/conda-forge/linux-64/snappy-1.1.10-hdb0a2a9_1.conda -https://conda.anaconda.org/conda-forge/linux-64/svt-av1-2.2.1-h5888daf_0.conda +https://conda.anaconda.org/conda-forge/linux-64/sqlite-3.49.2-h9eae976_0.conda https://conda.anaconda.org/conda-forge/linux-64/uriparser-0.9.8-hac33072_0.conda https://conda.anaconda.org/conda-forge/linux-64/xcb-util-0.4.1-hb711507_2.conda https://conda.anaconda.org/conda-forge/linux-64/xcb-util-keysyms-0.4.1-hb711507_0.conda https://conda.anaconda.org/conda-forge/linux-64/xcb-util-renderutil-0.3.10-hb711507_0.conda https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.2-hb711507_0.conda -https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.4-he73a12e_1.conda -https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.10-h4f16b4b_0.conda -https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.6-ha6fb4c9_0.conda +https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda +https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.12-h4f16b4b_0.conda +https://conda.anaconda.org/conda-forge/linux-64/xz-5.8.1-hbcc6ac9_1.conda +https://conda.anaconda.org/conda-forge/noarch/absl-py-2.2.0-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/aiohappyeyeballs-2.6.1-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/alabaster-1.0.0-pyhd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/noarch/asciitree-0.3.3-py_2.tar.bz2 +https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.0-pyhd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/noarch/attrs-25.3.0-pyh71513ae_0.conda https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.14.5-h50678d4_1.conda https://conda.anaconda.org/conda-forge/linux-64/bison-3.8.2-h59595ed_0.conda +https://conda.anaconda.org/conda-forge/noarch/blinker-1.9.0-pyhff2d567_0.conda https://conda.anaconda.org/conda-forge/linux-64/blosc-1.21.5-h0f2a231_0.conda +https://conda.anaconda.org/conda-forge/noarch/boltons-24.0.0-pyhd8ed1ab_1.conda https://conda.anaconda.org/conda-forge/linux-64/brotli-1.1.0-hb9d3cd8_2.conda +https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.1.0-py311hfdbb021_2.conda https://conda.anaconda.org/conda-forge/linux-64/c-blosc2-2.14.3-hb4ffafa_0.conda +https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 +https://conda.anaconda.org/conda-forge/noarch/cachetools-5.5.2-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/certifi-2025.4.26-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.2-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/click-8.2.0-pyh707e725_0.conda +https://conda.anaconda.org/conda-forge/noarch/cloudpickle-3.1.1-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.14-py311hfdbb021_0.conda +https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/docutils-0.21.2-pyhd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/noarch/executing-2.2.0-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/fasteners-0.19-pyhd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/noarch/fastprogress-1.0.3-pyhd8ed1ab_1.conda https://conda.anaconda.org/conda-forge/linux-64/fftw-3.3.10-nompi_hf1063bd_110.conda -https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.14.2-h14ed4e7_0.conda -https://conda.anaconda.org/conda-forge/linux-64/gdbm-1.18-h0a1914f_2.tar.bz2 -https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda -https://conda.anaconda.org/conda-forge/linux-64/libasprintf-devel-0.22.5-he8f35ee_3.conda -https://conda.anaconda.org/conda-forge/linux-64/libavif16-1.1.1-h104a339_1.conda +https://conda.anaconda.org/conda-forge/noarch/findlibs-0.0.5-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/linux-64/freexl-2.0.0-h9dce30a_2.conda +https://conda.anaconda.org/conda-forge/linux-64/frozenlist-1.6.0-py311h62d540b_0.conda +https://conda.anaconda.org/conda-forge/noarch/fsspec-2025.3.2-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/funcsigs-1.0.2-pyhd8ed1ab_4.conda +https://conda.anaconda.org/conda-forge/noarch/gast-0.6.0-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/linux-64/gettext-0.24.1-h5888daf_0.conda +https://conda.anaconda.org/conda-forge/linux-64/greenlet-3.2.2-py311hfdbb021_0.conda +https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/humanize-4.12.3-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/idna-3.10-pyhd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.bz2 +https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/noarch/keras-2.15.0-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.7-py311hd18a35c_0.conda +https://conda.anaconda.org/conda-forge/linux-64/libavif16-1.3.0-h766b0b6_0.conda +https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-31_h59b9bed_openblas.conda +https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h4637d8d_4.conda +https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.13.0-h332b0f4_0.conda +https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.13.3-ha770c72_1.conda https://conda.anaconda.org/conda-forge/linux-64/libglib-2.80.2-hf974151_0.conda +https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.10.3-h66b40c8_0.conda https://conda.anaconda.org/conda-forge/linux-64/libkml-1.3.0-hf539b9f_1021.conda -https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.27-pthreads_hac2b453_1.conda +https://conda.anaconda.org/conda-forge/linux-64/libpq-16.4-h2d7952a_3.conda https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-4.24.4-hf27288f_0.conda https://conda.anaconda.org/conda-forge/linux-64/libre2-11-2023.09.01-h7a70373_1.conda https://conda.anaconda.org/conda-forge/linux-64/librttopo-1.1.0-h8917695_15.conda +https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-256.9-h2774228_0.conda https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.6.0-ha9c0a0a_2.conda https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.12.7-h4c95cb1_3.conda -https://conda.anaconda.org/conda-forge/linux-64/minizip-4.0.7-h401b404_0.conda +https://conda.anaconda.org/conda-forge/noarch/locket-1.0.0-pyhd8ed1ab_0.tar.bz2 +https://conda.anaconda.org/conda-forge/linux-64/lz4-4.3.3-py311h2cbdf9a_1.conda +https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.2-py311h2dc5d0c_1.conda +https://conda.anaconda.org/conda-forge/linux-64/msgpack-python-1.1.0-py311hd18a35c_0.conda +https://conda.anaconda.org/conda-forge/linux-64/multidict-6.4.3-py311h2dc5d0c_0.conda +https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyh9f0ad1d_0.tar.bz2 https://conda.anaconda.org/conda-forge/linux-64/mysql-libs-8.3.0-ha479ceb_5.conda -https://conda.anaconda.org/conda-forge/linux-64/nss-3.105-hd34e28f_0.conda -https://conda.anaconda.org/conda-forge/linux-64/python-3.11.10-hc5c86c4_2_cpython.conda -https://conda.anaconda.org/conda-forge/linux-64/sqlite-3.46.1-h9eae976_0.conda +https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/noarch/networkx-3.4.2-pyh267e887_2.conda +https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.29-pthreads_h6ec200e_0.conda +https://conda.anaconda.org/conda-forge/noarch/opt_einsum-3.4.0-pyhd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda +https://conda.anaconda.org/conda-forge/noarch/parso-0.8.4-pyhd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/noarch/pickleshare-0.7.5-pyhd8ed1ab_1004.conda +https://conda.anaconda.org/conda-forge/noarch/pkgutil-resolve-name-1.3.10-pyhd8ed1ab_2.conda +https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.3.8-pyhe01879c_0.conda +https://conda.anaconda.org/conda-forge/noarch/pluggy-1.5.0-pyhd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/linux-64/propcache-0.3.1-py311h2dc5d0c_0.conda +https://conda.anaconda.org/conda-forge/linux-64/psutil-7.0.0-py311h9ecbd09_0.conda +https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/noarch/pyasn1-0.6.1-pyhd8ed1ab_2.conda +https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda +https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.1-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/pyjwt-2.10.1-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.3-pyhd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda +https://conda.anaconda.org/conda-forge/noarch/python-flatbuffers-25.2.10-pyhbc23db3_0.conda +https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.2-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.2-py311h2dc5d0c_2.conda +https://conda.anaconda.org/conda-forge/noarch/roman-numerals-py-3.1.0-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.24.0-py311h687327b_0.conda +https://conda.anaconda.org/conda-forge/noarch/setuptools-80.1.0-pyhff2d567_0.conda +https://conda.anaconda.org/conda-forge/linux-64/simplejson-3.20.1-py311h9ecbd09_0.conda +https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-2.2.0-pyhd8ed1ab_0.tar.bz2 +https://conda.anaconda.org/conda-forge/noarch/sortedcontainers-2.4.0-pyhd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/noarch/tblib-3.1.0-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/linux-64/tensorboard-data-server-0.7.0-py311hafd3f86_2.conda +https://conda.anaconda.org/conda-forge/noarch/termcolor-3.1.0-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/tomli-2.2.1-pyhd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/noarch/toolz-1.0.0-pyhd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/linux-64/tornado-6.4.2-py311h9ecbd09_0.conda +https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.3-pyhd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.13.2-pyh29332c3_0.conda +https://conda.anaconda.org/conda-forge/linux-64/unicodedata2-16.0.0-py311h9ecbd09_0.conda +https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.2.13-pyhd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/noarch/wheel-0.45.1-pyhd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/linux-64/wrapt-1.14.1-py311hd4cff14_1.tar.bz2 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda -https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.43-hb9d3cd8_0.conda +https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.44-hb9d3cd8_0.conda https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.6-hb9d3cd8_0.conda https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.1-hb9d3cd8_0.conda -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.11-hb9d3cd8_1.conda -https://conda.anaconda.org/conda-forge/noarch/absl-py-2.1.0-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/aiohappyeyeballs-2.4.3-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/alabaster-1.0.0-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/asciitree-0.3.3-py_2.tar.bz2 -https://conda.anaconda.org/conda-forge/noarch/attrs-24.2.0-pyh71513ae_0.conda +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda +https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h3b0a872_7.conda +https://conda.anaconda.org/conda-forge/noarch/zict-3.0.0-pyhd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/noarch/zipp-3.21.0-pyhd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/noarch/aiosignal-1.3.2-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/astunparse-1.6.3-pyhd8ed1ab_3.conda https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.4.2-hf9b2f7b_4.conda https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.8.1-h5d7533a_5.conda -https://conda.anaconda.org/conda-forge/noarch/blinker-1.8.2-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/boltons-24.0.0-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.1.0-py311hfdbb021_2.conda +https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.10.3-h91d86a7_1.conda +https://conda.anaconda.org/conda-forge/noarch/babel-2.17.0-pyhd8ed1ab_0.conda https://conda.anaconda.org/conda-forge/linux-64/brunsli-0.1-h9c3ff4c_0.tar.bz2 -https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 -https://conda.anaconda.org/conda-forge/noarch/cachetools-5.5.0-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.0-hbb29018_2.conda -https://conda.anaconda.org/conda-forge/noarch/certifi-2024.8.30-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.0-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/click-8.1.7-unix_pyh707e725_0.conda -https://conda.anaconda.org/conda-forge/noarch/cloudpickle-3.0.0-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_0.tar.bz2 -https://conda.anaconda.org/conda-forge/noarch/dataclasses-0.8-pyhc8e2a94_3.tar.bz2 +https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 +https://conda.anaconda.org/conda-forge/linux-64/cffi-1.17.1-py311hf29c0ef_0.conda +https://conda.anaconda.org/conda-forge/linux-64/cfitsio-4.4.0-hbdc6101_1.conda +https://conda.anaconda.org/conda-forge/noarch/click-plugins-1.1.1-pyhd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/noarch/cligj-0.7.2-pyhd8ed1ab_2.conda +https://conda.anaconda.org/conda-forge/noarch/comm-0.2.2-pyhd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/linux-64/cytoolz-1.0.1-py311h9ecbd09_0.conda https://conda.anaconda.org/conda-forge/linux-64/dbus-1.13.6-h5008d03_3.tar.bz2 -https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.6-py311hfdbb021_0.conda -https://conda.anaconda.org/conda-forge/noarch/decorator-5.1.1-pyhd8ed1ab_0.tar.bz2 -https://conda.anaconda.org/conda-forge/noarch/docutils-0.21.2-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.2.2-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/executing-2.1.0-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/fasteners-0.17.3-pyhd8ed1ab_0.tar.bz2 -https://conda.anaconda.org/conda-forge/noarch/fastprogress-1.0.3-pyhd8ed1ab_0.tar.bz2 -https://conda.anaconda.org/conda-forge/noarch/findlibs-0.0.5-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/linux-64/freexl-2.0.0-h743c826_0.conda -https://conda.anaconda.org/conda-forge/linux-64/frozenlist-1.4.1-py311h9ecbd09_1.conda -https://conda.anaconda.org/conda-forge/noarch/fsspec-2024.9.0-pyhff2d567_0.conda -https://conda.anaconda.org/conda-forge/noarch/funcsigs-1.0.2-py_3.tar.bz2 -https://conda.anaconda.org/conda-forge/noarch/gast-0.5.5-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/linux-64/gettext-0.22.5-he02047a_3.conda +https://conda.anaconda.org/conda-forge/noarch/deprecated-1.2.18-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.0-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.58.0-py311h2dc5d0c_0.conda +https://conda.anaconda.org/conda-forge/linux-64/freetype-2.13.3-ha770c72_1.conda https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.80.2-hb6ce0ca_0.conda -https://conda.anaconda.org/conda-forge/linux-64/greenlet-3.1.1-py311hfdbb021_0.conda -https://conda.anaconda.org/conda-forge/noarch/hpack-4.0.0-pyh9f0ad1d_0.tar.bz2 -https://conda.anaconda.org/conda-forge/noarch/humanize-4.11.0-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.0.1-pyhd8ed1ab_0.tar.bz2 -https://conda.anaconda.org/conda-forge/noarch/idna-3.10-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.bz2 -https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/keras-2.15.0-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/google-pasta-0.2.0-pyhd8ed1ab_2.conda +https://conda.anaconda.org/conda-forge/noarch/h2-4.2.0-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/linux-64/hdf5-1.14.3-nompi_h2d575fe_109.conda +https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.6.1-pyha770c72_0.conda +https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.5.2-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/intake-2.0.8-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/ipython_pygments_lexers-1.1.1-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/jedi-0.19.2-pyhd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.7.2-pyh31011fe_1.conda https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.16-hb7c19ff_0.conda https://conda.anaconda.org/conda-forge/linux-64/libarchive-3.7.4-hfca40fe_0.conda -https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-24_linux64_openblas.conda -https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h4637d8d_4.conda -https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.10.1-hbbe4b11_0.conda -https://conda.anaconda.org/conda-forge/linux-64/libglu-9.0.0-ha6d2627_1004.conda +https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-31_he106b2a_openblas.conda +https://conda.anaconda.org/conda-forge/linux-64/libflac-1.4.3-h59595ed_0.conda +https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda +https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-31_h7ac8fdf_openblas.conda https://conda.anaconda.org/conda-forge/linux-64/libllvm15-15.0.7-hb3ce162_4.conda -https://conda.anaconda.org/conda-forge/linux-64/libllvm19-19.1.1-ha7bfdaf_0.conda -https://conda.anaconda.org/conda-forge/linux-64/libpq-16.4-h2d7952a_2.conda +https://conda.anaconda.org/conda-forge/linux-64/libllvm18-18.1.8-h8b73ec9_2.conda +https://conda.anaconda.org/conda-forge/linux-64/libllvm19-19.1.2-ha7bfdaf_0.conda https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.7.0-h2c5496b_1.conda https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.39-h76b75d6_0.conda -https://conda.anaconda.org/conda-forge/noarch/locket-1.0.0-pyhd8ed1ab_0.tar.bz2 -https://conda.anaconda.org/conda-forge/linux-64/lz4-4.3.3-py311h2cbdf9a_1.conda -https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.1-py311h2dc5d0c_1.conda -https://conda.anaconda.org/conda-forge/linux-64/msgpack-python-1.1.0-py311hd18a35c_0.conda -https://conda.anaconda.org/conda-forge/linux-64/multidict-6.1.0-py311h9ecbd09_0.conda -https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/networkx-3.3-pyhd8ed1ab_1.conda -https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.27-pthreads_h9eca1d5_1.conda +https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.1.7-pyhd8ed1ab_1.conda https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.2-h488ebb8_0.conda -https://conda.anaconda.org/conda-forge/noarch/opt_einsum-3.4.0-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/packaging-24.1-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/parso-0.8.4-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/pickleshare-0.7.5-py_1003.tar.bz2 -https://conda.anaconda.org/conda-forge/noarch/pkgutil-resolve-name-1.3.10-pyhd8ed1ab_1.conda -https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.3.6-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/pluggy-1.5.0-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/linux-64/propcache-0.2.0-py311h9ecbd09_2.conda -https://conda.anaconda.org/conda-forge/linux-64/psutil-6.0.0-py311h9ecbd09_1.conda -https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd3deb0d_0.tar.bz2 -https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/pyasn1-0.6.1-pyhd8ed1ab_1.conda -https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/pygments-2.18.0-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/pyjwt-2.9.0-pyhd8ed1ab_1.conda -https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha2e5f31_6.tar.bz2 -https://conda.anaconda.org/conda-forge/noarch/python-flatbuffers-24.3.25-pyh59ac667_0.conda -https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2024.2-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/pytz-2024.2-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.2-py311h9ecbd09_1.conda -https://conda.anaconda.org/conda-forge/linux-64/re2-2023.09.01-h7f4b329_1.conda -https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.20.0-py311h9e33e62_1.conda -https://conda.anaconda.org/conda-forge/noarch/setuptools-75.1.0-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/linux-64/simplejson-3.19.3-py311h9ecbd09_1.conda -https://conda.anaconda.org/conda-forge/noarch/six-1.16.0-pyh6c4a22f_0.tar.bz2 -https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-2.2.0-pyhd8ed1ab_0.tar.bz2 -https://conda.anaconda.org/conda-forge/noarch/sortedcontainers-2.4.0-pyhd8ed1ab_0.tar.bz2 -https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/tblib-3.0.0-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/linux-64/tensorboard-data-server-0.7.0-py311h63ff55d_1.conda -https://conda.anaconda.org/conda-forge/noarch/termcolor-2.5.0-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/tomli-2.0.2-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/toolz-1.0.0-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/linux-64/tornado-6.4.1-py311h9ecbd09_1.conda -https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.3-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.12.2-pyha770c72_0.conda -https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.2.13-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/wheel-0.44.0-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/linux-64/wrapt-1.14.1-py311hd4cff14_1.tar.bz2 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxi-1.8.2-hb9d3cd8_0.conda -https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h3b0a872_6.conda -https://conda.anaconda.org/conda-forge/noarch/zict-3.0.0-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/zipp-3.20.2-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/aiosignal-1.3.1-pyhd8ed1ab_0.tar.bz2 -https://conda.anaconda.org/conda-forge/noarch/asttokens-2.4.1-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/astunparse-1.6.3-pyhd8ed1ab_0.tar.bz2 -https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.7.16-h79b3bcb_6.conda -https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.10.2-hf479d2b_4.conda -https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.10.3-h91d86a7_1.conda -https://conda.anaconda.org/conda-forge/noarch/babel-2.14.0-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 -https://conda.anaconda.org/conda-forge/linux-64/cffi-1.17.1-py311hf29c0ef_0.conda -https://conda.anaconda.org/conda-forge/linux-64/cfitsio-4.4.0-hbdc6101_1.conda -https://conda.anaconda.org/conda-forge/noarch/click-plugins-1.1.1-py_0.tar.bz2 -https://conda.anaconda.org/conda-forge/noarch/cligj-0.7.2-pyhd8ed1ab_1.tar.bz2 -https://conda.anaconda.org/conda-forge/noarch/comm-0.2.2-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/linux-64/cytoolz-1.0.0-py311h9ecbd09_1.conda -https://conda.anaconda.org/conda-forge/linux-64/freeglut-3.2.2-ha6d2627_3.conda -https://conda.anaconda.org/conda-forge/linux-64/glib-2.80.2-hf974151_0.conda -https://conda.anaconda.org/conda-forge/noarch/google-pasta-0.2.0-pyhd8ed1ab_1.conda -https://conda.anaconda.org/conda-forge/noarch/h2-4.1.0-pyhd8ed1ab_0.tar.bz2 -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-8.5.0-hfac3d4d_0.conda -https://conda.anaconda.org/conda-forge/linux-64/hdf5-1.14.3-nompi_hdf9ad27_105.conda -https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.5.0-pyha770c72_0.conda -https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.4.5-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/intake-2.0.7-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/jedi-0.19.1-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.4-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.7.2-pyh31011fe_1.conda -https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-24_linux64_openblas.conda -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp15-15.0.7-default_h127d8a8_5.conda -https://conda.anaconda.org/conda-forge/linux-64/libclang13-19.1.1-default_h9c6a7e4_0.conda -https://conda.anaconda.org/conda-forge/linux-64/libflac-1.4.3-h59595ed_0.conda -https://conda.anaconda.org/conda-forge/linux-64/libgpg-error-1.50-h4f305b6_0.conda -https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.59.3-hd6c4280_0.conda -https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-24_linux64_openblas.conda -https://conda.anaconda.org/conda-forge/linux-64/lxml-5.3.0-py311hcfaa980_1.conda -https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.1.7-pyhd8ed1ab_0.conda https://conda.anaconda.org/conda-forge/noarch/partd-1.4.2-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/pexpect-4.9.0-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/linux-64/pillow-10.4.0-py311h4aec55e_1.conda -https://conda.anaconda.org/conda-forge/noarch/pip-24.2-pyh8b19718_1.conda -https://conda.anaconda.org/conda-forge/linux-64/poppler-24.03.0-h590f24d_0.conda -https://conda.anaconda.org/conda-forge/linux-64/postgresql-16.4-hb2eb5c0_2.conda +https://conda.anaconda.org/conda-forge/noarch/pexpect-4.9.0-pyhd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/noarch/pip-25.1.1-pyh8b19718_0.conda +https://conda.anaconda.org/conda-forge/linux-64/postgresql-16.4-hb2eb5c0_3.conda https://conda.anaconda.org/conda-forge/linux-64/proj-9.3.1-h1d62c97_0.conda -https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.48-pyha770c72_0.conda +https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.51-pyha770c72_0.conda https://conda.anaconda.org/conda-forge/linux-64/protobuf-4.24.4-py311h46cbc50_0.conda -https://conda.anaconda.org/conda-forge/noarch/pyasn1-modules-0.4.1-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/pytest-8.3.3-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/pyu2f-0.1.5-pyhd8ed1ab_0.tar.bz2 -https://conda.anaconda.org/conda-forge/linux-64/pyzmq-26.2.0-py311h7deb3e3_2.conda -https://conda.anaconda.org/conda-forge/noarch/referencing-0.35.1-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/rsa-4.9-pyhd8ed1ab_0.tar.bz2 -https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.12.2-hd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/werkzeug-3.0.4-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/pyasn1-modules-0.4.2-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/linux-64/pydantic-1.10.21-py311h2deecd8_0.conda +https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhff2d567_1.conda +https://conda.anaconda.org/conda-forge/noarch/pyu2f-0.1.5-pyhd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/linux-64/pyzmq-26.4.0-py311h7deb3e3_0.conda +https://conda.anaconda.org/conda-forge/linux-64/re2-2023.09.01-h7f4b329_1.conda +https://conda.anaconda.org/conda-forge/noarch/referencing-0.36.2-pyh29332c3_0.conda +https://conda.anaconda.org/conda-forge/noarch/rsa-4.9.1-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.13.2-h0e9735f_0.conda +https://conda.anaconda.org/conda-forge/noarch/werkzeug-3.1.3-pyhd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/linux-64/xcb-util-cursor-0.1.5-hb9d3cd8_0.conda https://conda.anaconda.org/conda-forge/linux-64/xerces-c-3.2.5-hac6953d_0.conda -https://conda.anaconda.org/conda-forge/linux-64/yarl-1.14.0-py311h9ecbd09_0.conda -https://conda.anaconda.org/conda-forge/linux-64/aiohttp-3.10.9-py311h9ecbd09_0.conda -https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.5.2-h4ad9680_0.conda +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0.conda +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxi-1.8.2-hb9d3cd8_0.conda +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.6-hb9d3cd8_0.conda +https://conda.anaconda.org/conda-forge/linux-64/yarl-1.20.0-py311h2dc5d0c_0.conda +https://conda.anaconda.org/conda-forge/linux-64/aiohttp-3.11.18-py311h2dc5d0c_0.conda +https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.7.16-h79b3bcb_6.conda +https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.10.2-hf479d2b_4.conda https://conda.anaconda.org/conda-forge/linux-64/azure-storage-common-cpp-12.5.0-hb858b4b_2.conda -https://conda.anaconda.org/conda-forge/linux-64/cryptography-43.0.1-py311hafd3f86_0.conda +https://conda.anaconda.org/conda-forge/linux-64/cryptography-44.0.3-py311hafd3f86_0.conda https://conda.anaconda.org/conda-forge/noarch/dask-core-2023.3.0-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda +https://conda.anaconda.org/conda-forge/linux-64/freeglut-3.2.2-ha6d2627_3.conda https://conda.anaconda.org/conda-forge/linux-64/geotiff-1.7.1-h6b2125f_15.conda -https://conda.anaconda.org/conda-forge/linux-64/grpcio-1.59.3-py311ha6695c7_0.conda -https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.24.5-haf2f30d_0.conda -https://conda.anaconda.org/conda-forge/linux-64/jasper-4.2.4-h536e39c_0.conda -https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2024.10.1-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.3-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/linux-64/glib-2.80.2-hf974151_0.conda +https://conda.anaconda.org/conda-forge/noarch/ipython-9.2.0-pyhfb0248b_0.conda +https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.4.1-pyh29332c3_0.conda +https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.3-pyhd8ed1ab_1.conda https://conda.anaconda.org/conda-forge/linux-64/kealib-1.5.3-hf8d3e68_2.conda -https://conda.anaconda.org/conda-forge/linux-64/libgcrypt-1.11.0-h4ab18f5_1.conda -https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.17.0-h884d01b_1.conda +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp15-15.0.7-default_h127d8a8_5.conda +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp18.1-18.1.8-default_hb5137d0_9.conda +https://conda.anaconda.org/conda-forge/linux-64/libclang13-19.1.2-default_h9c6a7e4_1.conda +https://conda.anaconda.org/conda-forge/linux-64/libglu-9.0.3-h03adeef_0.conda +https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.59.3-hd6c4280_0.conda https://conda.anaconda.org/conda-forge/linux-64/libnetcdf-4.9.2-nompi_h135f659_114.conda https://conda.anaconda.org/conda-forge/linux-64/libsndfile-1.2.2-hc60ed4a_1.conda https://conda.anaconda.org/conda-forge/linux-64/libspatialite-5.1.0-h7bd4643_4.conda -https://conda.anaconda.org/conda-forge/noarch/markdown-3.6-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/linux-64/lxml-5.3.0-py311hcfaa980_2.conda +https://conda.anaconda.org/conda-forge/noarch/markdown-3.8-pyhd8ed1ab_0.conda https://conda.anaconda.org/conda-forge/linux-64/numpy-1.26.0-py311h64a7726_0.conda -https://conda.anaconda.org/conda-forge/linux-64/pango-1.54.0-h84a9a3c_0.conda -https://conda.anaconda.org/conda-forge/linux-64/pydantic-1.10.17-py311h61187de_0.conda +https://conda.anaconda.org/conda-forge/linux-64/pillow-10.4.0-py311h4aec55e_1.conda https://conda.anaconda.org/conda-forge/linux-64/pyproj-3.6.1-py311hca0b8b9_5.conda -https://conda.anaconda.org/conda-forge/linux-64/sqlalchemy-2.0.35-py311h9ecbd09_0.conda -https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.2-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/linux-64/zstandard-0.23.0-py311hbc35293_1.conda -https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.26.2-h19f5d62_7.conda +https://conda.anaconda.org/conda-forge/noarch/pytest-8.3.5-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/linux-64/sqlalchemy-2.0.40-py311h9ecbd09_0.conda +https://conda.anaconda.org/conda-forge/linux-64/zstandard-0.23.0-py311h9ecbd09_2.conda +https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.5.2-h4ad9680_0.conda https://conda.anaconda.org/conda-forge/linux-64/azure-storage-blobs-cpp-12.10.0-h00ab1b0_0.conda https://conda.anaconda.org/conda-forge/noarch/bokeh-2.4.3-pyhd8ed1ab_3.tar.bz2 +https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.0-hbb29018_2.conda https://conda.anaconda.org/conda-forge/linux-64/cftime-1.6.4-py311h9f3472d_1.conda -https://conda.anaconda.org/conda-forge/linux-64/eccodes-2.38.0-h8bb6dbc_0.conda -https://conda.anaconda.org/conda-forge/linux-64/gst-plugins-base-1.24.5-hbaaba92_0.conda -https://conda.anaconda.org/conda-forge/linux-64/h5py-3.11.0-nompi_py311h439e445_102.conda +https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.2-py311hd18a35c_0.conda +https://conda.anaconda.org/conda-forge/linux-64/grpcio-1.59.3-py311ha6695c7_0.conda +https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.24.5-haf2f30d_0.conda +https://conda.anaconda.org/conda-forge/linux-64/h5py-3.13.0-nompi_py311hb639ac4_100.conda https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2024.1.1-py311hd0e15ba_2.conda -https://conda.anaconda.org/conda-forge/noarch/ipython-8.28.0-pyh707e725_0.conda -https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.23.0-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-2.17.0-hc7a4891_1.conda -https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-256.7-h2774228_0.conda +https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.29.5-pyh3099207_0.conda +https://conda.anaconda.org/conda-forge/linux-64/jasper-4.2.5-h1920b20_0.conda +https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.23.0-pyhd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.17.0-h884d01b_1.conda https://conda.anaconda.org/conda-forge/linux-64/ml_dtypes-0.2.0-py311h320fe9a_2.conda -https://conda.anaconda.org/conda-forge/linux-64/numcodecs-0.13.1-py311h7db5c69_0.conda -https://conda.anaconda.org/conda-forge/noarch/oauthlib-3.2.2-pyhd8ed1ab_0.tar.bz2 -https://conda.anaconda.org/conda-forge/linux-64/pandas-2.2.2-py311h14de704_1.conda -https://conda.anaconda.org/conda-forge/noarch/pyopenssl-24.2.1-pyhd8ed1ab_2.conda -https://conda.anaconda.org/conda-forge/linux-64/scipy-1.14.1-py311he1f765f_0.conda +https://conda.anaconda.org/conda-forge/linux-64/numcodecs-0.15.1-py311h7db5c69_0.conda +https://conda.anaconda.org/conda-forge/noarch/oauthlib-3.2.2-pyhd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/linux-64/pandas-2.2.3-py311h7db5c69_3.conda +https://conda.anaconda.org/conda-forge/linux-64/pulseaudio-client-17.0-hb77b528_0.conda +https://conda.anaconda.org/conda-forge/noarch/pyopenssl-25.0.0-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/linux-64/scipy-1.15.2-py311h8f841c2_0.conda https://conda.anaconda.org/conda-forge/linux-64/shapely-2.0.4-py311h0bed3d6_1.conda -https://conda.anaconda.org/conda-forge/noarch/urllib3-2.2.3-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.267-h5606698_1.conda +https://conda.anaconda.org/conda-forge/noarch/urllib3-2.4.0-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.26.2-h19f5d62_7.conda https://conda.anaconda.org/conda-forge/noarch/distributed-2023.3.0-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.29.5-pyh3099207_0.conda -https://conda.anaconda.org/conda-forge/linux-64/netcdf4-1.7.1-nompi_py311hae66bec_102.conda -https://conda.anaconda.org/conda-forge/linux-64/pulseaudio-client-17.0-hb77b528_0.conda -https://conda.anaconda.org/conda-forge/linux-64/python-eccodes-2.37.0-py311h9f3472d_0.conda -https://conda.anaconda.org/conda-forge/noarch/requests-2.32.3-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/tifffile-2024.9.20-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/linux-64/eccodes-2.41.0-h8bb6dbc_0.conda +https://conda.anaconda.org/conda-forge/linux-64/gst-plugins-base-1.24.5-hbaaba92_0.conda +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-8.5.0-hfac3d4d_0.conda +https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-2.17.0-hc7a4891_1.conda +https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.3-py311h2b939e6_0.conda +https://conda.anaconda.org/conda-forge/linux-64/netcdf4-1.7.2-nompi_py311hae66bec_101.conda +https://conda.anaconda.org/conda-forge/linux-64/poppler-24.03.0-h590f24d_0.conda +https://conda.anaconda.org/conda-forge/noarch/requests-2.32.3-pyhd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/noarch/tifffile-2024.12.12-pyhd8ed1ab_0.conda https://conda.anaconda.org/conda-forge/noarch/xarray-2024.3.0-pyhd8ed1ab_0.conda https://conda.anaconda.org/conda-forge/noarch/zarr-2.12.0-pyhd8ed1ab_0.tar.bz2 -https://conda.anaconda.org/conda-forge/noarch/cfgrib-0.9.14.1-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.267-h5606698_1.conda https://conda.anaconda.org/conda-forge/noarch/dask-2023.3.0-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/google-auth-2.35.0-pyhff2d567_0.conda -https://conda.anaconda.org/conda-forge/noarch/owslib-0.31.0-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/python-geotiff-0.2.10-pyh6eeeb26_0.conda +https://conda.anaconda.org/conda-forge/noarch/google-auth-2.40.1-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/owslib-0.33.0-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/linux-64/pango-1.54.0-h84a9a3c_0.conda +https://conda.anaconda.org/conda-forge/linux-64/python-eccodes-2.37.0-py311h9f3472d_0.conda +https://conda.anaconda.org/conda-forge/noarch/python-geotiff-0.2.10-pyh516b878_1.conda https://conda.anaconda.org/conda-forge/linux-64/qt-main-5.15.8-ha2b5568_22.conda -https://conda.anaconda.org/conda-forge/noarch/requests-oauthlib-2.0.0-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/linux-64/tiledb-2.20.1-hd75ad12_1.conda -https://conda.anaconda.org/conda-forge/noarch/birdy-0.8.7-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/google-auth-oauthlib-1.2.1-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.7.2-h0f8cd61_2.conda +https://conda.anaconda.org/conda-forge/noarch/requests-oauthlib-2.0.0-pyhd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/noarch/birdy-0.8.7-pyhd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/noarch/cfgrib-0.9.15.0-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/google-auth-oauthlib-1.2.2-pyhd8ed1ab_0.conda https://conda.anaconda.org/conda-forge/noarch/intake-esm-2023.6.14-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/linux-64/libgdal-3.8.4-hab4ef92_3.conda https://conda.anaconda.org/conda-forge/linux-64/magics-metview-4.15.3-he53f960_0.conda -https://conda.anaconda.org/conda-forge/noarch/metview-python-1.16.1-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/linux-64/gdal-3.8.4-py311h8be719e_3.conda +https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.7.2-py311h9053184_4.conda +https://conda.anaconda.org/conda-forge/linux-64/tiledb-2.20.1-hd75ad12_1.conda +https://conda.anaconda.org/conda-forge/linux-64/libgdal-3.8.4-hab4ef92_3.conda +https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.3-py311h38be061_0.conda https://conda.anaconda.org/conda-forge/linux-64/metview-5.22.0-h3a65212_0.conda +https://conda.anaconda.org/conda-forge/noarch/metview-python-1.16.1-pyhff2d567_1.conda https://conda.anaconda.org/conda-forge/noarch/tensorboard-2.15.2-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/linux-64/fiona-1.9.6-py311hf8e0aa6_0.conda +https://conda.anaconda.org/conda-forge/linux-64/gdal-3.8.4-py311h8be719e_3.conda https://conda.anaconda.org/conda-forge/linux-64/tensorflow-base-2.15.0-cpu_py311h6aa969b_2.conda +https://conda.anaconda.org/conda-forge/linux-64/fiona-1.9.6-py311hf8e0aa6_0.conda https://conda.anaconda.org/conda-forge/linux-64/tensorflow-estimator-2.15.0-cpu_py311ha26c8b9_2.conda https://conda.anaconda.org/conda-forge/linux-64/tensorflow-2.15.0-cpu_py311hd3d7757_2.conda -https://conda.anaconda.org/conda-forge/noarch/pywps-4.6.0-pyhca7485f_0.conda -https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-applehelp-2.0.0-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-devhelp-2.0.0-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-htmlhelp-2.1.0-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-qthelp-2.0.0-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/sphinx-8.0.2-pyhd8ed1ab_0.conda -https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-serializinghtml-1.1.10-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/pywps-4.6.0-pyhd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-applehelp-2.0.0-pyhd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-devhelp-2.0.0-pyhd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-htmlhelp-2.1.0-pyhd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-qthelp-2.0.0-pyhd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/noarch/sphinx-8.2.3-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-serializinghtml-1.1.10-pyhd8ed1ab_1.conda From a5e6dc74cb81b3548214bff55bb6c57b568ed81c Mon Sep 17 00:00:00 2001 From: Pingu Carsti Date: Tue, 13 May 2025 15:17:26 +0200 Subject: [PATCH 5/5] added matplotlib to requirements.txt --- requirements.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 28f65bd..79049a3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,4 +12,5 @@ scipy ipykernel numpy eccodes -metview \ No newline at end of file +metview +matplotlib