diff --git a/Example.ipynb b/Example.ipynb index ec50dd4..0ad1858 100644 --- a/Example.ipynb +++ b/Example.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 4, + "execution_count": 1, "id": "53bc9780", "metadata": {}, "outputs": [], @@ -14,7 +14,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 2, "id": "1f3871fc", "metadata": {}, "outputs": [], @@ -24,7 +24,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 3, "id": "6fd7e7f9", "metadata": {}, "outputs": [ @@ -50,7 +50,7 @@ "}" ] }, - "execution_count": 2, + "execution_count": 3, "metadata": {}, "output_type": "execute_result" } @@ -62,252 +62,128 @@ }, { "cell_type": "code", - "execution_count": null, - "id": "3dd386bd", + "execution_count": 6, + "id": "b77ff62c", "metadata": {}, "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "131\n" - ] - }, - { - "ename": "IndexError", - "evalue": "positional indexers are out-of-bounds", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mIndexError\u001b[0m Traceback (most recent call last)", - "File \u001b[0;32m/opt/homebrew/Caskroom/miniforge/base/envs/global-forecasting-system/lib/python3.10/site-packages/pandas/core/indexing.py:1714\u001b[0m, in \u001b[0;36m_iLocIndexer._get_list_axis\u001b[0;34m(self, key, axis)\u001b[0m\n\u001b[1;32m 1713\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m-> 1714\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mobj\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_take_with_is_copy\u001b[49m\u001b[43m(\u001b[49m\u001b[43mkey\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43maxis\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43maxis\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 1715\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mIndexError\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m err:\n\u001b[1;32m 1716\u001b[0m \u001b[38;5;66;03m# re-raise with different error message, e.g. test_getitem_ndarray_3d\u001b[39;00m\n", - "File \u001b[0;32m/opt/homebrew/Caskroom/miniforge/base/envs/global-forecasting-system/lib/python3.10/site-packages/pandas/core/generic.py:4153\u001b[0m, in \u001b[0;36mNDFrame._take_with_is_copy\u001b[0;34m(self, indices, axis)\u001b[0m\n\u001b[1;32m 4144\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[1;32m 4145\u001b[0m \u001b[38;5;124;03mInternal version of the `take` method that sets the `_is_copy`\u001b[39;00m\n\u001b[1;32m 4146\u001b[0m \u001b[38;5;124;03mattribute to keep track of the parent dataframe (using in indexing\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 4151\u001b[0m \u001b[38;5;124;03mSee the docstring of `take` for full explanation of the parameters.\u001b[39;00m\n\u001b[1;32m 4152\u001b[0m \u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[0;32m-> 4153\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mtake\u001b[49m\u001b[43m(\u001b[49m\u001b[43mindices\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mindices\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43maxis\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43maxis\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 4154\u001b[0m \u001b[38;5;66;03m# Maybe set copy if we didn't actually change the index.\u001b[39;00m\n", - "File \u001b[0;32m/opt/homebrew/Caskroom/miniforge/base/envs/global-forecasting-system/lib/python3.10/site-packages/pandas/core/generic.py:4133\u001b[0m, in \u001b[0;36mNDFrame.take\u001b[0;34m(self, indices, axis, **kwargs)\u001b[0m\n\u001b[1;32m 4129\u001b[0m indices \u001b[38;5;241m=\u001b[39m np\u001b[38;5;241m.\u001b[39marange(\n\u001b[1;32m 4130\u001b[0m indices\u001b[38;5;241m.\u001b[39mstart, indices\u001b[38;5;241m.\u001b[39mstop, indices\u001b[38;5;241m.\u001b[39mstep, dtype\u001b[38;5;241m=\u001b[39mnp\u001b[38;5;241m.\u001b[39mintp\n\u001b[1;32m 4131\u001b[0m )\n\u001b[0;32m-> 4133\u001b[0m new_data \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_mgr\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mtake\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 4134\u001b[0m \u001b[43m \u001b[49m\u001b[43mindices\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 4135\u001b[0m \u001b[43m \u001b[49m\u001b[43maxis\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_get_block_manager_axis\u001b[49m\u001b[43m(\u001b[49m\u001b[43maxis\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 4136\u001b[0m \u001b[43m \u001b[49m\u001b[43mverify\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[1;32m 4137\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 4138\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_constructor_from_mgr(new_data, axes\u001b[38;5;241m=\u001b[39mnew_data\u001b[38;5;241m.\u001b[39maxes)\u001b[38;5;241m.\u001b[39m__finalize__(\n\u001b[1;32m 4139\u001b[0m \u001b[38;5;28mself\u001b[39m, method\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtake\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 4140\u001b[0m )\n", - "File \u001b[0;32m/opt/homebrew/Caskroom/miniforge/base/envs/global-forecasting-system/lib/python3.10/site-packages/pandas/core/internals/managers.py:891\u001b[0m, in \u001b[0;36mBaseBlockManager.take\u001b[0;34m(self, indexer, axis, verify)\u001b[0m\n\u001b[1;32m 890\u001b[0m n \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mshape[axis]\n\u001b[0;32m--> 891\u001b[0m indexer \u001b[38;5;241m=\u001b[39m \u001b[43mmaybe_convert_indices\u001b[49m\u001b[43m(\u001b[49m\u001b[43mindexer\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mn\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mverify\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mverify\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 893\u001b[0m new_labels \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39maxes[axis]\u001b[38;5;241m.\u001b[39mtake(indexer)\n", - "File \u001b[0;32m/opt/homebrew/Caskroom/miniforge/base/envs/global-forecasting-system/lib/python3.10/site-packages/pandas/core/indexers/utils.py:282\u001b[0m, in \u001b[0;36mmaybe_convert_indices\u001b[0;34m(indices, n, verify)\u001b[0m\n\u001b[1;32m 281\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m mask\u001b[38;5;241m.\u001b[39many():\n\u001b[0;32m--> 282\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mIndexError\u001b[39;00m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mindices are out-of-bounds\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 283\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m indices\n", - "\u001b[0;31mIndexError\u001b[0m: indices are out-of-bounds", - "\nThe above exception was the direct cause of the following exception:\n", - "\u001b[0;31mIndexError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[3], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m Ta_C \u001b[38;5;241m=\u001b[39m \u001b[43mforecast_Ta_C\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 2\u001b[0m \u001b[43m \u001b[49m\u001b[43mtime_UTC\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43m2025-05-22 21:11:22.358885\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 3\u001b[0m \u001b[43m \u001b[49m\u001b[43mgeometry\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mgeometry\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 4\u001b[0m \u001b[43m)\u001b[49m\n\u001b[1;32m 6\u001b[0m Ta_C\n", - "File \u001b[0;32m~/Projects/global-forecasting-system/global_forecasting_system/global_forecasting_system.py:275\u001b[0m, in \u001b[0;36mforecast_Ta_C\u001b[0;34m(time_UTC, geometry, resampling, directory, listing)\u001b[0m\n\u001b[1;32m 269\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21mforecast_Ta_C\u001b[39m(\n\u001b[1;32m 270\u001b[0m time_UTC: datetime,\n\u001b[1;32m 271\u001b[0m geometry: rt\u001b[38;5;241m.\u001b[39mRasterGeometry \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[1;32m 272\u001b[0m resampling: \u001b[38;5;28mstr\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mcubic\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m 273\u001b[0m directory: \u001b[38;5;28mstr\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[1;32m 274\u001b[0m listing: pd\u001b[38;5;241m.\u001b[39mDataFrame \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m rt\u001b[38;5;241m.\u001b[39mRaster:\n\u001b[0;32m--> 275\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mforecast_Ta_K\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtime_UTC\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mtime_UTC\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mgeometry\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mgeometry\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mresampling\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mresampling\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdirectory\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mdirectory\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mlisting\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mlisting\u001b[49m\u001b[43m)\u001b[49m \u001b[38;5;241m-\u001b[39m \u001b[38;5;241m273.15\u001b[39m\n", - "File \u001b[0;32m~/Projects/global-forecasting-system/global_forecasting_system/global_forecasting_system.py:267\u001b[0m, in \u001b[0;36mforecast_Ta_K\u001b[0;34m(time_UTC, geometry, resampling, directory, listing)\u001b[0m\n\u001b[1;32m 261\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21mforecast_Ta_K\u001b[39m(\n\u001b[1;32m 262\u001b[0m time_UTC: datetime,\n\u001b[1;32m 263\u001b[0m geometry: rt\u001b[38;5;241m.\u001b[39mRasterGeometry \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[1;32m 264\u001b[0m resampling: \u001b[38;5;28mstr\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mcubic\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m 265\u001b[0m directory: \u001b[38;5;28mstr\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[1;32m 266\u001b[0m listing: pd\u001b[38;5;241m.\u001b[39mDataFrame \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m rt\u001b[38;5;241m.\u001b[39mRaster:\n\u001b[0;32m--> 267\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mGFS_interpolate\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmessage\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mGFS_TA_MESSAGE\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtime_UTC\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mtime_UTC\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mgeometry\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mgeometry\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mresampling\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mresampling\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdirectory\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mdirectory\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mlisting\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mlisting\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m~/Projects/global-forecasting-system/global_forecasting_system/global_forecasting_system.py:225\u001b[0m, in \u001b[0;36mGFS_interpolate\u001b[0;34m(message, time_UTC, geometry, resampling, directory, listing)\u001b[0m\n\u001b[1;32m 218\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21mGFS_interpolate\u001b[39m(\n\u001b[1;32m 219\u001b[0m message: \u001b[38;5;28mint\u001b[39m,\n\u001b[1;32m 220\u001b[0m time_UTC: datetime,\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 223\u001b[0m directory: \u001b[38;5;28mstr\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[1;32m 224\u001b[0m listing: pd\u001b[38;5;241m.\u001b[39mDataFrame \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m rt\u001b[38;5;241m.\u001b[39mRaster:\n\u001b[0;32m--> 225\u001b[0m before_after \u001b[38;5;241m=\u001b[39m \u001b[43mGFS_before_after_addresses\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtime_UTC\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mlisting\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mlisting\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 227\u001b[0m before_address \u001b[38;5;241m=\u001b[39m before_after\u001b[38;5;241m.\u001b[39miloc[\u001b[38;5;241m0\u001b[39m]\u001b[38;5;241m.\u001b[39maddress\n\u001b[1;32m 228\u001b[0m logger\u001b[38;5;241m.\u001b[39minfo(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mbefore URL: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mcolored_logging\u001b[38;5;241m.\u001b[39mURL(before_address)\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n", - "File \u001b[0;32m~/Projects/global-forecasting-system/global_forecasting_system/global_forecasting_system.py:164\u001b[0m, in \u001b[0;36mGFS_before_after_addresses\u001b[0;34m(time_UTC, listing)\u001b[0m\n\u001b[1;32m 155\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mzero-length GFS listing at time \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mtime_UTC\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m UTC\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 157\u001b[0m \u001b[38;5;66;03m# min_time = min(listing.forecast_time_UTC)\u001b[39;00m\n\u001b[1;32m 158\u001b[0m \u001b[38;5;66;03m# max_time = max(listing.forecast_time_UTC)\u001b[39;00m\n\u001b[1;32m 159\u001b[0m \n\u001b[1;32m 160\u001b[0m \u001b[38;5;66;03m# logger.info(f\"selecting GFS files for time {time_UTC} UTC between {min_time} UTC and {max_time} UTC\")\u001b[39;00m\n\u001b[1;32m 161\u001b[0m \n\u001b[1;32m 162\u001b[0m \u001b[38;5;66;03m# before = listing[listing.forecast_time_UTC <= time_UTC].iloc[[-1]]\u001b[39;00m\n\u001b[0;32m--> 164\u001b[0m before \u001b[38;5;241m=\u001b[39m \u001b[43mlisting\u001b[49m\u001b[43m[\u001b[49m\u001b[43mlisting\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mforecast_time_UTC\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mapply\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43;01mlambda\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mforecast_time_UTC\u001b[49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mstr\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mforecast_time_UTC\u001b[49m\u001b[43m)\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m<\u001b[39;49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m \u001b[49m\u001b[38;5;28;43mstr\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mtime_UTC\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\u001b[43m]\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43miloc\u001b[49m\u001b[43m[\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;241;43m-\u001b[39;49m\u001b[38;5;241;43m1\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m]\u001b[49m\n\u001b[1;32m 165\u001b[0m after \u001b[38;5;241m=\u001b[39m listing[listing\u001b[38;5;241m.\u001b[39mforecast_time_UTC\u001b[38;5;241m.\u001b[39mapply(\u001b[38;5;28;01mlambda\u001b[39;00m forecast_time_UTC: \u001b[38;5;28mstr\u001b[39m(forecast_time_UTC) \u001b[38;5;241m>\u001b[39m \u001b[38;5;28mstr\u001b[39m(time_UTC))]\u001b[38;5;241m.\u001b[39miloc[[\u001b[38;5;241m0\u001b[39m]]\n\u001b[1;32m 166\u001b[0m before_after \u001b[38;5;241m=\u001b[39m pd\u001b[38;5;241m.\u001b[39mconcat([before, after])\n", - "File \u001b[0;32m/opt/homebrew/Caskroom/miniforge/base/envs/global-forecasting-system/lib/python3.10/site-packages/pandas/core/indexing.py:1191\u001b[0m, in \u001b[0;36m_LocationIndexer.__getitem__\u001b[0;34m(self, key)\u001b[0m\n\u001b[1;32m 1189\u001b[0m maybe_callable \u001b[38;5;241m=\u001b[39m com\u001b[38;5;241m.\u001b[39mapply_if_callable(key, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mobj)\n\u001b[1;32m 1190\u001b[0m maybe_callable \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_check_deprecated_callable_usage(key, maybe_callable)\n\u001b[0;32m-> 1191\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_getitem_axis\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmaybe_callable\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43maxis\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43maxis\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m/opt/homebrew/Caskroom/miniforge/base/envs/global-forecasting-system/lib/python3.10/site-packages/pandas/core/indexing.py:1743\u001b[0m, in \u001b[0;36m_iLocIndexer._getitem_axis\u001b[0;34m(self, key, axis)\u001b[0m\n\u001b[1;32m 1741\u001b[0m \u001b[38;5;66;03m# a list of integers\u001b[39;00m\n\u001b[1;32m 1742\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m is_list_like_indexer(key):\n\u001b[0;32m-> 1743\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_get_list_axis\u001b[49m\u001b[43m(\u001b[49m\u001b[43mkey\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43maxis\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43maxis\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 1745\u001b[0m \u001b[38;5;66;03m# a single integer\u001b[39;00m\n\u001b[1;32m 1746\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 1747\u001b[0m key \u001b[38;5;241m=\u001b[39m item_from_zerodim(key)\n", - "File \u001b[0;32m/opt/homebrew/Caskroom/miniforge/base/envs/global-forecasting-system/lib/python3.10/site-packages/pandas/core/indexing.py:1717\u001b[0m, in \u001b[0;36m_iLocIndexer._get_list_axis\u001b[0;34m(self, key, axis)\u001b[0m\n\u001b[1;32m 1714\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mobj\u001b[38;5;241m.\u001b[39m_take_with_is_copy(key, axis\u001b[38;5;241m=\u001b[39maxis)\n\u001b[1;32m 1715\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mIndexError\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m err:\n\u001b[1;32m 1716\u001b[0m \u001b[38;5;66;03m# re-raise with different error message, e.g. test_getitem_ndarray_3d\u001b[39;00m\n\u001b[0;32m-> 1717\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mIndexError\u001b[39;00m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mpositional indexers are out-of-bounds\u001b[39m\u001b[38;5;124m\"\u001b[39m) \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21;01merr\u001b[39;00m\n", - "\u001b[0;31mIndexError\u001b[0m: positional indexers are out-of-bounds" - ] + "data": { + "text/plain": [ + "Timestamp('2025-05-28 00:00:00')" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ - "Ta_C = forecast_Ta_C(\n", - " time_UTC=time_UTC,\n", - " geometry=geometry,\n", - ")\n", + "from global_forecasting_system import earliest_time_UTC\n", "\n", - "Ta_C" + "earliest = earliest_time_UTC()\n", + "earliest" ] }, { "cell_type": "code", - "execution_count": 5, - "id": "31e6c9fc", + "execution_count": 9, + "id": "4f2aec61", "metadata": {}, "outputs": [ { "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", - "
forecast_time_UTCaddress
02025-05-28 00:00:00https://www.ncei.noaa.gov/data/global-forecast...
12025-05-28 03:00:00https://www.ncei.noaa.gov/data/global-forecast...
1292025-05-28 06:00:00https://www.ncei.noaa.gov/data/global-forecast...
1302025-05-28 09:00:00https://www.ncei.noaa.gov/data/global-forecast...
1312025-05-28 12:00:00https://www.ncei.noaa.gov/data/global-forecast...
.........
2532025-06-12 18:00:00https://www.ncei.noaa.gov/data/global-forecast...
2542025-06-12 21:00:00https://www.ncei.noaa.gov/data/global-forecast...
2552025-06-13 00:00:00https://www.ncei.noaa.gov/data/global-forecast...
2562025-06-13 03:00:00https://www.ncei.noaa.gov/data/global-forecast...
2572025-06-13 06:00:00https://www.ncei.noaa.gov/data/global-forecast...
\n", - "

131 rows × 2 columns

\n", - "
" - ], "text/plain": [ - " forecast_time_UTC address\n", - "0 2025-05-28 00:00:00 https://www.ncei.noaa.gov/data/global-forecast...\n", - "1 2025-05-28 03:00:00 https://www.ncei.noaa.gov/data/global-forecast...\n", - "129 2025-05-28 06:00:00 https://www.ncei.noaa.gov/data/global-forecast...\n", - "130 2025-05-28 09:00:00 https://www.ncei.noaa.gov/data/global-forecast...\n", - "131 2025-05-28 12:00:00 https://www.ncei.noaa.gov/data/global-forecast...\n", - ".. ... ...\n", - "253 2025-06-12 18:00:00 https://www.ncei.noaa.gov/data/global-forecast...\n", - "254 2025-06-12 21:00:00 https://www.ncei.noaa.gov/data/global-forecast...\n", - "255 2025-06-13 00:00:00 https://www.ncei.noaa.gov/data/global-forecast...\n", - "256 2025-06-13 03:00:00 https://www.ncei.noaa.gov/data/global-forecast...\n", - "257 2025-06-13 06:00:00 https://www.ncei.noaa.gov/data/global-forecast...\n", - "\n", - "[131 rows x 2 columns]" + "datetime.date(2025, 5, 28)" ] }, - "execution_count": 5, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "listing = global_forecasting_system.get_GFS_listing()\n", - "listing" + "earliest.to_pydatetime().date()" ] }, { "cell_type": "code", - "execution_count": 10, - "id": "99726c21", + "execution_count": 7, + "id": "229d091f", "metadata": {}, "outputs": [ { "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
forecast_time_UTCaddress
\n", - "
" - ], "text/plain": [ - "Empty DataFrame\n", - "Columns: [forecast_time_UTC, address]\n", - "Index: []" + "pandas._libs.tslibs.timestamps.Timestamp" ] }, - "execution_count": 10, + "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "listing[listing.forecast_time_UTC.apply(lambda forecast_time_UTC: str(forecast_time_UTC) <= str(time_UTC))]" + "type(earliest)" ] }, { "cell_type": "code", - "execution_count": 8, - "id": "d9e02cc4", + "execution_count": 4, + "id": "3dd386bd", "metadata": {}, "outputs": [ { - "ename": "IndexError", - "evalue": "positional indexers are out-of-bounds", + "ename": "ValueError", + "evalue": "no GFS files found before time 2025-05-22 21:11:22.358885 UTC", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mIndexError\u001b[0m Traceback (most recent call last)", - "File \u001b[0;32m/opt/homebrew/Caskroom/miniforge/base/envs/global-forecasting-system/lib/python3.10/site-packages/pandas/core/indexing.py:1714\u001b[0m, in \u001b[0;36m_iLocIndexer._get_list_axis\u001b[0;34m(self, key, axis)\u001b[0m\n\u001b[1;32m 1713\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m-> 1714\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mobj\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_take_with_is_copy\u001b[49m\u001b[43m(\u001b[49m\u001b[43mkey\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43maxis\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43maxis\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 1715\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mIndexError\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m err:\n\u001b[1;32m 1716\u001b[0m \u001b[38;5;66;03m# re-raise with different error message, e.g. test_getitem_ndarray_3d\u001b[39;00m\n", - "File \u001b[0;32m/opt/homebrew/Caskroom/miniforge/base/envs/global-forecasting-system/lib/python3.10/site-packages/pandas/core/generic.py:4153\u001b[0m, in \u001b[0;36mNDFrame._take_with_is_copy\u001b[0;34m(self, indices, axis)\u001b[0m\n\u001b[1;32m 4144\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[1;32m 4145\u001b[0m \u001b[38;5;124;03mInternal version of the `take` method that sets the `_is_copy`\u001b[39;00m\n\u001b[1;32m 4146\u001b[0m \u001b[38;5;124;03mattribute to keep track of the parent dataframe (using in indexing\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 4151\u001b[0m \u001b[38;5;124;03mSee the docstring of `take` for full explanation of the parameters.\u001b[39;00m\n\u001b[1;32m 4152\u001b[0m \u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[0;32m-> 4153\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mtake\u001b[49m\u001b[43m(\u001b[49m\u001b[43mindices\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mindices\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43maxis\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43maxis\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 4154\u001b[0m \u001b[38;5;66;03m# Maybe set copy if we didn't actually change the index.\u001b[39;00m\n", - "File \u001b[0;32m/opt/homebrew/Caskroom/miniforge/base/envs/global-forecasting-system/lib/python3.10/site-packages/pandas/core/generic.py:4133\u001b[0m, in \u001b[0;36mNDFrame.take\u001b[0;34m(self, indices, axis, **kwargs)\u001b[0m\n\u001b[1;32m 4129\u001b[0m indices \u001b[38;5;241m=\u001b[39m np\u001b[38;5;241m.\u001b[39marange(\n\u001b[1;32m 4130\u001b[0m indices\u001b[38;5;241m.\u001b[39mstart, indices\u001b[38;5;241m.\u001b[39mstop, indices\u001b[38;5;241m.\u001b[39mstep, dtype\u001b[38;5;241m=\u001b[39mnp\u001b[38;5;241m.\u001b[39mintp\n\u001b[1;32m 4131\u001b[0m )\n\u001b[0;32m-> 4133\u001b[0m new_data \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_mgr\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mtake\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 4134\u001b[0m \u001b[43m \u001b[49m\u001b[43mindices\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 4135\u001b[0m \u001b[43m \u001b[49m\u001b[43maxis\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_get_block_manager_axis\u001b[49m\u001b[43m(\u001b[49m\u001b[43maxis\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 4136\u001b[0m \u001b[43m \u001b[49m\u001b[43mverify\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[1;32m 4137\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 4138\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_constructor_from_mgr(new_data, axes\u001b[38;5;241m=\u001b[39mnew_data\u001b[38;5;241m.\u001b[39maxes)\u001b[38;5;241m.\u001b[39m__finalize__(\n\u001b[1;32m 4139\u001b[0m \u001b[38;5;28mself\u001b[39m, method\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtake\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 4140\u001b[0m )\n", - "File \u001b[0;32m/opt/homebrew/Caskroom/miniforge/base/envs/global-forecasting-system/lib/python3.10/site-packages/pandas/core/internals/managers.py:891\u001b[0m, in \u001b[0;36mBaseBlockManager.take\u001b[0;34m(self, indexer, axis, verify)\u001b[0m\n\u001b[1;32m 890\u001b[0m n \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mshape[axis]\n\u001b[0;32m--> 891\u001b[0m indexer \u001b[38;5;241m=\u001b[39m \u001b[43mmaybe_convert_indices\u001b[49m\u001b[43m(\u001b[49m\u001b[43mindexer\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mn\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mverify\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mverify\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 893\u001b[0m new_labels \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39maxes[axis]\u001b[38;5;241m.\u001b[39mtake(indexer)\n", - "File \u001b[0;32m/opt/homebrew/Caskroom/miniforge/base/envs/global-forecasting-system/lib/python3.10/site-packages/pandas/core/indexers/utils.py:282\u001b[0m, in \u001b[0;36mmaybe_convert_indices\u001b[0;34m(indices, n, verify)\u001b[0m\n\u001b[1;32m 281\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m mask\u001b[38;5;241m.\u001b[39many():\n\u001b[0;32m--> 282\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mIndexError\u001b[39;00m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mindices are out-of-bounds\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 283\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m indices\n", - "\u001b[0;31mIndexError\u001b[0m: indices are out-of-bounds", - "\nThe above exception was the direct cause of the following exception:\n", - "\u001b[0;31mIndexError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[8], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m before \u001b[38;5;241m=\u001b[39m \u001b[43mlisting\u001b[49m\u001b[43m[\u001b[49m\u001b[43mlisting\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mforecast_time_UTC\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mapply\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43;01mlambda\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mforecast_time_UTC\u001b[49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mstr\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mforecast_time_UTC\u001b[49m\u001b[43m)\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m<\u001b[39;49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m \u001b[49m\u001b[38;5;28;43mstr\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mtime_UTC\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\u001b[43m]\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43miloc\u001b[49m\u001b[43m[\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;241;43m-\u001b[39;49m\u001b[38;5;241;43m1\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m]\u001b[49m\n", - "File \u001b[0;32m/opt/homebrew/Caskroom/miniforge/base/envs/global-forecasting-system/lib/python3.10/site-packages/pandas/core/indexing.py:1191\u001b[0m, in \u001b[0;36m_LocationIndexer.__getitem__\u001b[0;34m(self, key)\u001b[0m\n\u001b[1;32m 1189\u001b[0m maybe_callable \u001b[38;5;241m=\u001b[39m com\u001b[38;5;241m.\u001b[39mapply_if_callable(key, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mobj)\n\u001b[1;32m 1190\u001b[0m maybe_callable \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_check_deprecated_callable_usage(key, maybe_callable)\n\u001b[0;32m-> 1191\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_getitem_axis\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmaybe_callable\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43maxis\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43maxis\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m/opt/homebrew/Caskroom/miniforge/base/envs/global-forecasting-system/lib/python3.10/site-packages/pandas/core/indexing.py:1743\u001b[0m, in \u001b[0;36m_iLocIndexer._getitem_axis\u001b[0;34m(self, key, axis)\u001b[0m\n\u001b[1;32m 1741\u001b[0m \u001b[38;5;66;03m# a list of integers\u001b[39;00m\n\u001b[1;32m 1742\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m is_list_like_indexer(key):\n\u001b[0;32m-> 1743\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_get_list_axis\u001b[49m\u001b[43m(\u001b[49m\u001b[43mkey\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43maxis\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43maxis\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 1745\u001b[0m \u001b[38;5;66;03m# a single integer\u001b[39;00m\n\u001b[1;32m 1746\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 1747\u001b[0m key \u001b[38;5;241m=\u001b[39m item_from_zerodim(key)\n", - "File \u001b[0;32m/opt/homebrew/Caskroom/miniforge/base/envs/global-forecasting-system/lib/python3.10/site-packages/pandas/core/indexing.py:1717\u001b[0m, in \u001b[0;36m_iLocIndexer._get_list_axis\u001b[0;34m(self, key, axis)\u001b[0m\n\u001b[1;32m 1714\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mobj\u001b[38;5;241m.\u001b[39m_take_with_is_copy(key, axis\u001b[38;5;241m=\u001b[39maxis)\n\u001b[1;32m 1715\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mIndexError\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m err:\n\u001b[1;32m 1716\u001b[0m \u001b[38;5;66;03m# re-raise with different error message, e.g. test_getitem_ndarray_3d\u001b[39;00m\n\u001b[0;32m-> 1717\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mIndexError\u001b[39;00m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mpositional indexers are out-of-bounds\u001b[39m\u001b[38;5;124m\"\u001b[39m) \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21;01merr\u001b[39;00m\n", - "\u001b[0;31mIndexError\u001b[0m: positional indexers are out-of-bounds" + "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[4], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m Ta_C \u001b[38;5;241m=\u001b[39m \u001b[43mforecast_Ta_C\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 2\u001b[0m \u001b[43m \u001b[49m\u001b[43mtime_UTC\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mtime_UTC\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 3\u001b[0m \u001b[43m \u001b[49m\u001b[43mgeometry\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mgeometry\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 4\u001b[0m \u001b[43m)\u001b[49m\n\u001b[1;32m 6\u001b[0m Ta_C\n", + "File \u001b[0;32m~/Projects/global-forecasting-system/global_forecasting_system/global_forecasting_system.py:297\u001b[0m, in \u001b[0;36mforecast_Ta_C\u001b[0;34m(time_UTC, geometry, resampling, directory, listing)\u001b[0m\n\u001b[1;32m 291\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21mforecast_Ta_C\u001b[39m(\n\u001b[1;32m 292\u001b[0m time_UTC: datetime,\n\u001b[1;32m 293\u001b[0m geometry: rt\u001b[38;5;241m.\u001b[39mRasterGeometry \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[1;32m 294\u001b[0m resampling: \u001b[38;5;28mstr\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mcubic\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m 295\u001b[0m directory: \u001b[38;5;28mstr\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[1;32m 296\u001b[0m listing: pd\u001b[38;5;241m.\u001b[39mDataFrame \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m rt\u001b[38;5;241m.\u001b[39mRaster:\n\u001b[0;32m--> 297\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mforecast_Ta_K\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtime_UTC\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mtime_UTC\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mgeometry\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mgeometry\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mresampling\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mresampling\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdirectory\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mdirectory\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mlisting\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mlisting\u001b[49m\u001b[43m)\u001b[49m \u001b[38;5;241m-\u001b[39m \u001b[38;5;241m273.15\u001b[39m\n", + "File \u001b[0;32m~/Projects/global-forecasting-system/global_forecasting_system/global_forecasting_system.py:289\u001b[0m, in \u001b[0;36mforecast_Ta_K\u001b[0;34m(time_UTC, geometry, resampling, directory, listing)\u001b[0m\n\u001b[1;32m 283\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21mforecast_Ta_K\u001b[39m(\n\u001b[1;32m 284\u001b[0m time_UTC: datetime,\n\u001b[1;32m 285\u001b[0m geometry: rt\u001b[38;5;241m.\u001b[39mRasterGeometry \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[1;32m 286\u001b[0m resampling: \u001b[38;5;28mstr\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mcubic\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m 287\u001b[0m directory: \u001b[38;5;28mstr\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[1;32m 288\u001b[0m listing: pd\u001b[38;5;241m.\u001b[39mDataFrame \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m rt\u001b[38;5;241m.\u001b[39mRaster:\n\u001b[0;32m--> 289\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mGFS_interpolate\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmessage\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mGFS_TA_MESSAGE\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtime_UTC\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mtime_UTC\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mgeometry\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mgeometry\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mresampling\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mresampling\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdirectory\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mdirectory\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mlisting\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mlisting\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/Projects/global-forecasting-system/global_forecasting_system/global_forecasting_system.py:247\u001b[0m, in \u001b[0;36mGFS_interpolate\u001b[0;34m(message, time_UTC, geometry, resampling, directory, listing)\u001b[0m\n\u001b[1;32m 240\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21mGFS_interpolate\u001b[39m(\n\u001b[1;32m 241\u001b[0m message: \u001b[38;5;28mint\u001b[39m,\n\u001b[1;32m 242\u001b[0m time_UTC: datetime,\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 245\u001b[0m directory: \u001b[38;5;28mstr\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[1;32m 246\u001b[0m listing: pd\u001b[38;5;241m.\u001b[39mDataFrame \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m rt\u001b[38;5;241m.\u001b[39mRaster:\n\u001b[0;32m--> 247\u001b[0m before_after \u001b[38;5;241m=\u001b[39m \u001b[43mGFS_before_after_addresses\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtime_UTC\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mlisting\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mlisting\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 249\u001b[0m before_address \u001b[38;5;241m=\u001b[39m before_after\u001b[38;5;241m.\u001b[39miloc[\u001b[38;5;241m0\u001b[39m]\u001b[38;5;241m.\u001b[39maddress\n\u001b[1;32m 250\u001b[0m logger\u001b[38;5;241m.\u001b[39minfo(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mbefore URL: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mcolored_logging\u001b[38;5;241m.\u001b[39mURL(before_address)\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n", + "File \u001b[0;32m~/Projects/global-forecasting-system/global_forecasting_system/global_forecasting_system.py:177\u001b[0m, in \u001b[0;36mGFS_before_after_addresses\u001b[0;34m(time_UTC, listing)\u001b[0m\n\u001b[1;32m 174\u001b[0m before_rows \u001b[38;5;241m=\u001b[39m listing[listing\u001b[38;5;241m.\u001b[39mforecast_time_UTC\u001b[38;5;241m.\u001b[39mapply(\u001b[38;5;28;01mlambda\u001b[39;00m forecast_time_UTC: \u001b[38;5;28mstr\u001b[39m(forecast_time_UTC) \u001b[38;5;241m<\u001b[39m\u001b[38;5;241m=\u001b[39m \u001b[38;5;28mstr\u001b[39m(time_UTC))]\n\u001b[1;32m 176\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(before_rows) \u001b[38;5;241m==\u001b[39m \u001b[38;5;241m0\u001b[39m:\n\u001b[0;32m--> 177\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mno GFS files found before time \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mtime_UTC\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m UTC\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 179\u001b[0m before \u001b[38;5;241m=\u001b[39m before_rows\u001b[38;5;241m.\u001b[39miloc[[\u001b[38;5;241m-\u001b[39m\u001b[38;5;241m1\u001b[39m]]\n\u001b[1;32m 181\u001b[0m after_rows \u001b[38;5;241m=\u001b[39m listing[listing\u001b[38;5;241m.\u001b[39mforecast_time_UTC\u001b[38;5;241m.\u001b[39mapply(\u001b[38;5;28;01mlambda\u001b[39;00m forecast_time_UTC: \u001b[38;5;28mstr\u001b[39m(forecast_time_UTC) \u001b[38;5;241m>\u001b[39m \u001b[38;5;28mstr\u001b[39m(time_UTC))]\n", + "\u001b[0;31mValueError\u001b[0m: no GFS files found before time 2025-05-22 21:11:22.358885 UTC" ] } ], + "source": [ + "Ta_C = forecast_Ta_C(\n", + " time_UTC=time_UTC,\n", + " geometry=geometry,\n", + ")\n", + "\n", + "Ta_C" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "31e6c9fc", + "metadata": {}, + "outputs": [], + "source": [ + "listing = global_forecasting_system.get_GFS_listing()\n", + "listing" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "99726c21", + "metadata": {}, + "outputs": [], + "source": [ + "listing[listing.forecast_time_UTC.apply(lambda forecast_time_UTC: str(forecast_time_UTC) <= str(time_UTC))]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d9e02cc4", + "metadata": {}, + "outputs": [], "source": [ "before = listing[listing.forecast_time_UTC.apply(lambda forecast_time_UTC: str(forecast_time_UTC) <= str(time_UTC))].iloc[[-1]]" ] @@ -319,6 +195,14 @@ "metadata": {}, "outputs": [], "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8ca59e87", + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { diff --git a/global_forecasting_system/__init__.py b/global_forecasting_system/__init__.py index 479d2e5..23ccd71 100644 --- a/global_forecasting_system/__init__.py +++ b/global_forecasting_system/__init__.py @@ -1,3 +1,3 @@ from .global_forecasting_system import * -__version__ = "1.1.1" +__version__ = "1.2.0" diff --git a/global_forecasting_system/global_forecasting_system.py b/global_forecasting_system/global_forecasting_system.py index c85a046..d482da9 100644 --- a/global_forecasting_system/global_forecasting_system.py +++ b/global_forecasting_system/global_forecasting_system.py @@ -142,6 +142,20 @@ def get_GFS_listing(date_URL: str = None) -> pd.DataFrame: return address_df +def earliest_time_UTC(listing: pd.DataFrame = None) -> datetime: + if listing is None: + listing = get_GFS_listing() + + if len(listing) == 0: + raise ValueError("zero-length GFS listing") + + earliest_time = min(listing.forecast_time_UTC).to_pydatetime() + + return earliest_time + +def earliest_date_UTC(listing: pd.DataFrame = None) -> date: + return earliest_date_UTC(listing=listing).date() + def GFS_before_after_addresses(time_UTC: datetime, listing: pd.DataFrame = None) -> pd.DataFrame: if not isinstance(time_UTC, datetime): time_UTC = parser.parse(time_UTC) diff --git a/pyproject.toml b/pyproject.toml index ee3819d..d209c86 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "global-forecasting-system" -version = "1.1.1" +version = "1.2.0" description = "Global Forecasting System (GFS) Search & Download Utility" readme = "README.md" authors = [