From dfbe3a428a26cd018eebe47dae0e8f79df47c3ce Mon Sep 17 00:00:00 2001 From: Joe Ranalli Date: Fri, 11 Oct 2024 14:32:25 -0400 Subject: [PATCH] Progress on demo. --- demos/synthetic_clouds_demo.ipynb | 226 ++++++++++++------ .../synthirrad/cloudfield.py | 4 +- 2 files changed, 159 insertions(+), 71 deletions(-) diff --git a/demos/synthetic_clouds_demo.ipynb b/demos/synthetic_clouds_demo.ipynb index 97d6d65..30583f2 100644 --- a/demos/synthetic_clouds_demo.ipynb +++ b/demos/synthetic_clouds_demo.ipynb @@ -1,86 +1,100 @@ { "cells": [ + { + "metadata": {}, + "cell_type": "markdown", + "source": [ + "# Generating Synthetic Time Series Using Randomized Cloud Fields\n", + "This file demonstrates code available in `solarspatialtools.synthirrad.cloudfield`, which implements methods described by Lave et al. [1] for generation of synthetic cloud fields that can be used to simulate high frequency solar irradiance data. Some aspects of the implementation diverge slightly from the initial paper to follow a subsequent code implementation of the method shared by the original authors. \n", + "\n", + "[1] Matthew Lave, Matthew J. Reno, Robert J. Broderick, \"Creation and Value of Synthetic High-Frequency Solar Inputs for Distribution System QSTS Simulations,\" 2017 IEEE 44th Photovoltaic Specialist Conference (PVSC), Washington, DC, USA, 2017, pp. 3031-3033, doi: https://dx.doi.org/10.1109/PVSC.2017.8366378.\n", + "\n", + "# Setup" + ], + "id": "d701625fd7e3ad13" + }, { "cell_type": "code", "id": "initial_id", "metadata": { "collapsed": true, "ExecuteTime": { - "end_time": "2024-10-09T18:03:34.852206Z", - "start_time": "2024-10-09T18:03:34.293367Z" + "end_time": "2024-10-10T18:23:19.260094Z", + "start_time": "2024-10-10T18:23:15.495840Z" } }, "source": [ + "import pvlib\n", "import pandas as pd\n", "import numpy as np\n", - "import pvlib\n", + "import matplotlib.pyplot as plt\n", + "from PIL.ImageColor import colormap\n", + "\n", "from solarspatialtools import irradiance\n", "from solarspatialtools import cmv\n", "from solarspatialtools import spatial\n", "\n", "from solarspatialtools.synthirrad.cloudfield import get_timeseries_stats, cloudfield_timeseries\n", - "\n", - "import matplotlib.pyplot as plt" + "\n" ], "outputs": [], - "execution_count": 8 + "execution_count": 1 }, { "metadata": {}, "cell_type": "markdown", - "source": "Load sample timeseries data and convert it to clear sky index", + "source": [ + "# Load Sample Timeseries Data\n", + "The model attempts to create representative variability to match that observed from a reference time series. In this case, we'll process one of the 1-second resolution timeseries from the HOPE-Melpitz campign. We will load the data and convert it to clearsky index. " + ], "id": "e386bd79e13077f4" }, { "metadata": { "ExecuteTime": { - "end_time": "2024-10-09T18:03:44.923539Z", - "start_time": "2024-10-09T18:03:44.866162Z" + "end_time": "2024-10-10T18:23:21.406904Z", + "start_time": "2024-10-10T18:23:19.270070Z" } }, "cell_type": "code", "source": [ - "# #### Load Timeseries Data\n", - "\n", "datafn = \"data/hope_melpitz_1s.h5\"\n", "twin = pd.date_range('2013-09-08 9:15:00', '2013-09-08 10:15:00', freq='1s', tz='UTC')\n", "data = pd.read_hdf(datafn, mode=\"r\", key=\"data\")\n", - "data_i = data[40]\n", "\n", - "# Get the time series for a single sensor and convert it to a clear sky index.\n", - "# Record some statistics about it.\n", + "# Load the sensor positions\n", "pos = pd.read_hdf(datafn, mode=\"r\", key=\"latlon\")\n", + "pos_utm = pd.read_hdf(datafn, mode=\"r\", key=\"utm\")\n", + "\n", + "# Compute clearsky ghi and clearsky index\n", "loc = pvlib.location.Location(np.mean(pos['lat']), np.mean(pos['lon']))\n", - "cs_ghi = loc.get_clearsky(data_i.index, model='simplified_solis')['ghi']\n", - "cs_ghi = 1000/max(cs_ghi) * cs_ghi # Rescale (possible scaling on\n", - "kt = pvlib.irradiance.clearsky_index(data_i, cs_ghi, 2)\n" + "cs_ghi = loc.get_clearsky(data.index, model='simplified_solis')['ghi']\n", + "cs_ghi = 1000/max(cs_ghi) * cs_ghi # Normalize to 1000 W/m^2\n", + "kt = irradiance.clearsky_index(data, cs_ghi, 2)\n" ], "id": "3ac0711770cafcde", "outputs": [], - "execution_count": 11 + "execution_count": 2 }, { "metadata": {}, "cell_type": "markdown", - "source": "Get the Cloud Motion Vector for the Timeseries", + "source": "For some of the later analysis, we will need to know something about the Cloud Motion Vector for this time period, so we can compute that using the `solarspatialtools.cmv` module.", "id": "b141cd1b18348ab4" }, { "metadata": { "ExecuteTime": { - "end_time": "2024-10-09T18:05:03.567591Z", - "start_time": "2024-10-09T18:05:02.509168Z" + "end_time": "2024-10-10T18:23:30.068291Z", + "start_time": "2024-10-10T18:23:28.992689Z" } }, "cell_type": "code", "source": [ - "# Get the Cloud Motion Vector for the Timeseries\n", - "pos_utm = pd.read_hdf(datafn, mode=\"r\", key=\"utm\")\n", - "kt_all = irradiance.clearsky_index(data, cs_ghi, 2)\n", - "cld_spd, cld_dir, _ = cmv.compute_cmv(kt_all, pos_utm, reference_id=None, method='jamaly')\n", + "cld_spd, cld_dir, _ = cmv.compute_cmv(kt, pos_utm, reference_id=None, method='jamaly')\n", "cld_vec_rect = spatial.pol2rect(cld_spd, cld_dir)\n", "\n", - "print(f\"Cld Speed {cld_spd:8.2f}, Cld Dir {np.rad2deg(cld_dir):8.2f}\")" + "print(f\"Cld Speed {cld_spd:8.2f}, Cld Dir {np.rad2deg(cld_dir):8.2f}°\")" ], "id": "5fcf7a2a50c72783", "outputs": [ @@ -88,35 +102,34 @@ "name": "stdout", "output_type": "stream", "text": [ - "Cld Speed 19.67, Cld Dir 90.70\n" + "Cld Speed 19.67, Cld Dir 90.70°\n" ] } ], - "execution_count": 12 + "execution_count": 3 }, { "metadata": {}, "cell_type": "markdown", - "source": "Redefine the positions to represent the rotated view in the cloud motion vector space", + "source": [ + "# Visualize the sensor layout in the CMV direction\n", + "We want to describe how the sensors are distributed in the cloud motion vector direction. So we'll rotate the positions of the entire field to align with the CMV in the +X direction. " + ], "id": "e5770aab6c893bf3" }, { "metadata": { "ExecuteTime": { - "end_time": "2024-10-09T18:05:55.487605Z", - "start_time": "2024-10-09T18:05:55.163653Z" + "end_time": "2024-10-10T18:25:30.103066Z", + "start_time": "2024-10-10T18:25:29.504469Z" } }, "cell_type": "code", "source": [ - "# Rotate the sensor positions by -cld dir to position the incoming clouds\n", - "# toward the upwind side of the plant. Shift to zero out the minimum value.\n", + "# Rotation by -cld_dir to make CMV align with X Axis\n", "rot = spatial.rotate_vector((pos_utm['E'], pos_utm['N']), theta=-cld_dir)\n", - "pos_utm_rot = pd.DataFrame({'X': rot[0] - np.min(rot[0]),\n", - " 'Y': rot[1] - np.min(rot[1])},\n", - " index=pos_utm.index)\n", + "pos_utm_rot = pd.DataFrame({'X': rot[0] - np.min(rot[0]), 'Y': rot[1] - np.min(rot[1])}, index=pos_utm.index)\n", "\n", - "# plot the original field and the rotated field side by side in two subplots\n", "fig, axs = plt.subplots(1, 2, figsize=(10, 5))\n", "axs[0].scatter(pos_utm['E'], pos_utm['N'])\n", "axs[0].set_title('Original Field')\n", @@ -144,84 +157,159 @@ "output_type": "display_data" } ], - "execution_count": 14 + "execution_count": 4 }, { "metadata": {}, "cell_type": "markdown", - "source": "Get statistics on the timeseries that will be used to scale the synthetic timeseries.", + "source": [ + "# Compute Timeseries Statistics\n", + "The scaling of the cloud field is based on statistical variability properties of the time series. So we'll extract those in advance. We do so for a single sensor (number 40) that is centrally located in the field. \n", + "- `ktmean` - The mean clearsky index\n", + "- `kt1pct` - The 1st percentile of clearsky index, used similar to a minimum\n", + "- `ktmax` - The maximum clearsky index (shows cloud enhancement)\n", + "- `frac_clear` - Fraction of clear sky conditions in time series (characterized as kt > 0.95)\n", + "- `vs` - The variability score of the clearsky index\n", + "- `weights` - The weights are calculated from the magnitude-squared of the various wavelet modes contained in the time series. \n", + "- `scales` - The scales of the various wavelet modes contained in the time series." + ], "id": "ec008ca89673e2b5" }, { "metadata": { "ExecuteTime": { - "end_time": "2024-10-09T18:05:08.239451Z", - "start_time": "2024-10-09T18:05:08.222836Z" + "end_time": "2024-10-10T18:29:36.028415Z", + "start_time": "2024-10-10T18:29:35.860665Z" } }, "cell_type": "code", - "outputs": [], - "execution_count": 13, - "source": "ktmean, kt1pct, ktmax, frac_clear, vs, weights, scales = get_timeseries_stats(kt, plot=False)", - "id": "67d8ef643e8e879c" + "source": [ + "ktmean, kt1pct, ktmax, frac_clear, vs, weights, scales = get_timeseries_stats(kt[40], plot=False)\n", + "print(f\"ktmean: {ktmean:8.2f}\")\n", + "print(f\"kt1pct: {kt1pct:8.2f}\")\n", + "print(f\"ktmax: {ktmax:8.2f}\")\n", + "print(f\"frac_clear: {frac_clear:8.2f}\")\n", + "print(f\"vs: {vs:8.2f}\")\n", + "\n", + "# Plot the wavelet scales\n", + "plt.plot(scales, weights)\n", + "plt.xlabel('Scale')\n", + "plt.ylabel('Weight')\n", + "plt.show()" + ], + "id": "67d8ef643e8e879c", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "ktmean: 0.64\n", + "kt1pct: 0.38\n", + "ktmax: 1.09\n", + "frac_clear: 0.12\n", + "vs: 25.31\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/png": "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" + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "execution_count": 7 }, { "metadata": {}, "cell_type": "markdown", - "source": "Generate a spatiotemporal relationship as a first step of creating the cloud field that represents the cloud data", + "source": [ + "# Relate the Time and Space Scales\n", + "Since we rotated the sensor positions, we can now calculate the overall spatial size of the distribution along and perpendicular to the cloud motion vector. We'll also look at the dureation of the time series (in this case 1 hour) and its temporal resolution (1 second). \n", + "\n", + "Using the cloud speed we can relate these spatial dimensions to time dimensions. When we generate the cloud field, we will assume that each pixel in the field represents a 1-second step in time. So moving 1 pixel within the field along the X axis represents either a 1 second shift upwind or downwind in space, or a 1 second shift of the time axis at a fixed spatial position. Moving 1 pixel along the Y axis will always represent a 1 second shift perpendicular to the cloud motion vector." + ], "id": "698a8f550447ffee" }, { "metadata": { "ExecuteTime": { - "end_time": "2024-10-09T18:06:55.117614Z", - "start_time": "2024-10-09T18:06:55.105094Z" + "end_time": "2024-10-10T18:33:54.282571Z", + "start_time": "2024-10-10T18:33:54.276562Z" } }, "cell_type": "code", "source": [ - "# #### Generate the Simulated Cloud Field\n", - "\n", - "# Calculate the size of the field\n", "x_extent = np.abs(np.max(pos_utm_rot['X']) - np.min(pos_utm_rot['X']))\n", "y_extent = np.abs(np.max(pos_utm_rot['Y']) - np.min(pos_utm_rot['Y']))\n", "t_extent = (np.max(twin) - np.min(twin)).total_seconds()\n", "dt = (twin[1] - twin[0]).total_seconds()\n", "\n", - "# Convert space to time\n", "spatial_time_x = x_extent / cld_spd\n", "spatial_time_y = y_extent / cld_spd\n", "\n", - "# This now represents the time to space relationship in seconds, so each pixel of the field represents a 1 second step.\n", - "# Our steps in X represent 1 second forward or backward in EITHER along-cloud space or time\n", - "# Our steps in Y represent 1 \"cloud second\" left or right perpendicular to the motion axis\n", - "# We actually have to oversize things a bit because if the field is too small, we can't\n", - "# halve its size a sufficient number of times.\n", "xt_size = int(np.ceil(spatial_time_x + t_extent))\n", - "yt_size = int(np.ceil(spatial_time_y))\n" + "yt_size = int(np.ceil(spatial_time_y))\n", + "\n", + "print(f\"X Extent: {x_extent:8.2f} m, Y Extent: {y_extent:8.2f} m\")\n", + "print(f\"Time Extent: {t_extent:8.2f} s, Time Resolution: {dt:8.2f} s\")\n", + "print(f\"Field Size: {xt_size}x{yt_size}\")\n" ], "id": "8925b0448ebf99d5", - "outputs": [], - "execution_count": 15 + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "X Extent: 1919.58 m, Y Extent: 2023.44 m\n", + "Time Extent: 3600.00 s, Time Resolution: 1.00 s\n", + "Field Size: 3698x103\n" + ] + } + ], + "execution_count": 10 }, { "metadata": {}, "cell_type": "markdown", - "source": "Unified methodology", + "source": "# Generating the Randomized Cloud Field", "id": "b673a7962eb556ee" }, { - "metadata": {}, + "metadata": { + "ExecuteTime": { + "end_time": "2024-10-10T18:37:53.983914Z", + "start_time": "2024-10-10T18:37:52.996109Z" + } + }, "cell_type": "code", - "outputs": [], - "execution_count": null, "source": [ - "np.random.seed(42) # Do seeding for repeatability\n", + "np.random.seed(42) # Seed for repeatability\n", "\n", "field_final = cloudfield_timeseries(weights, scales, (xt_size, yt_size), frac_clear, ktmean, ktmax, kt1pct)\n", - "\n" + "\n", + "plt.imshow(field_final.T, aspect='equal', cmap='viridis')\n", + "plt.xlabel('Time and X axis position')\n", + "plt.ylabel('Y axis position')\n", + "plt.show()" + ], + "id": "1111f040431c3115", + "outputs": [ + { + "data": { + "text/plain": [ + "
" + ], + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjsAAABSCAYAAACyshXgAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/TGe4hAAAACXBIWXMAAA9hAAAPYQGoP6dpAAA7GElEQVR4nO19eXgVRdb+W933ZiGBABGyiMEoiiI7KAKOMi4IyKL4IaOI4PYNIiATPx1HZgQdB9BREX6Ko8CnoswgCjj6oAjKph+IiGRYRVQQRTCK7Etyb9f5/VFLV9+bQC4kkEC9z3OTe7urq6tOnzr11qlT1YyICEfB3r17UatWLf39SFDpLCwsLCwsLCyqAlh5yI7ruti+fTvq168Px3HAGItLQ0RgjMHzvEopqIWFhYWFhYXFsSBUnkQLFixA3bp1AQALFy6s1AJZWFhYWFhYWFQkyuXZsbCwsLCwsLCornASvWDu3Ln45JNP9O/nn38eLVu2xC233IJdu3ZVaOEsLCwsLCwsLI4XCZOdBx54QAcpr1mzBgUFBejWrRu+/fZbFBQUVHgBLSwsLCwsLCyOB+WK2TGxefNmNGnSBAAwc+ZM9OjRA6NHj8YXX3yBbt26VXgBLSwsLCwsLCyOBwl7dpKSknDw4EEAwIcffojOnTsDAOrWrXvUZekWFhYWFhYWFicaCXt2LrvsMhQUFKBjx4747LPP8MYbbwAAvvrqKzRo0KDCC2hhYWFhYWFhcTxI2LPz3HPPIRQK4a233sILL7yAM888EwDw/vvvo0uXLhVeQAsLCwsLCwuL44Fdem5hYWFhYWFxSiNhzw4AeJ6HmTNn4vHHH8ff/vY3zJo166TvnDxx4kTk5+cjJSUFbdq0wccff3xSy2NhYWFhYWFRNZBwzM7XX3+Nbt26Ydu2bWjcuDGICF999RXOOusszJkzB+eee25llPOIeOONNzB8+HBMnDgRHTt2xIsvvoiuXbti/fr1yMvLO+HlsbCwsLCwsKg6SHgaq1u3biAiTJs2Tb9CYufOnbj11lvhOA7mzJlTKQU9Etq1a4fWrVvjhRde0McuvPBCXH/99RgzZswJL4+FhYWFhYVF1UHCZCctLQ2ffvopmjVrFjj+n//8Bx07dsT+/fsrtIBHQ0lJCWrUqIE333wTN9xwgz5+3333obCwEIsXL467pri4GMXFxfo35xy//vorMjMzS33JqYWFhYWFhUXVAxFh3759yM3NheOUHZmT8DRWcnIy9u3bF3d8//79SEpKSjS748Yvv/wCz/OQlZUVOJ6VlYUdO3aUes2YMWPw6KOPnojiWVhYWFhYWFQyvv/++yNuf5Mw2enevTv++7//G1OmTMEll1wCAFi+fDkGDRqEnj17HntJjxOxHhkiKtNL86c//Snwaos9e/YgLy8PZz/4FzjhFDDPuI4BIIB5gOMBjMvvEfk/SmAccKKAExHfGQfIAchVhTHyIZHOiRKcEoJbwsE8ghPhIAYwTv4nwgHOVQUBIjCPQIyBwi54sgsKOfBSXXCHgRFAsujkMlAIICkDRgQWFfnrckTFvYOClP8i4r48yQU5sp5EIIeBRUX5nIgHFuFgEQ+IerJ84j85DhAOAYppRz2waNSvj8HAyfjOOA+mkY5HchwgOQkUckAhBzzsAg4DVDmiXKdlUQ54HHCd+LxlOeE4+jyFXSDEQI74gMnvrvwt5fLj7SWY3Po1cFSM96/wcB7efPRaJO8sEc/XAcAh5Ch1AJDPUN2SMf2MGSdRVwDkinoyeS2iJOqrhUz6enjyHJF4LmpxAWPiXo4DSgmDJ4fEJ+yAh5UeAeCkdY1cB+QCJTVdXF3wf7im5toKkU1lIQyOfh/fjTorwgCT7VTKngCAqTZOor17qu2Ltg1AJCQhf3Lkc2P+KZVeQdgEAneFTgGyPXkEJkXPwww8JNptQL24yIsYwJMYvCSRjoeYti+k7k/C5oh8gvZH2SUA4PK4thdKDg4Al0T+SQQKEyjMAZdEHVWVogws4ujfzGNSTvI/V4Iw/gOAsquM/HNS5mCiroG6O5A20b9W10Pd21Bxs476YajbSfsNLtoIMQZGpGXjRI3nLJ8v5HNz5DMS9p0CNhUccLh4liDAKfGEXS3hcIojQCTq28WoByqOANESkMeBSARE2rSLPF0HLBQCQiGwpCQgJOwchUKA64qEMfYLIWknGQOFGHhSCNFUF16yCy+ZgSczRJOZ1gsekjbEkbri+B8tQ6bat/yEyP/OAHKFfqjnxjxfbwlCj8glw25RvD7IdMwlkMcM/ZDpORPpXeNaLnVP6gDjDNhXjK1/+ytq1qyJIyFhsjNhwgQMGDAA7du3RzgcBgBEo1H07NkT48ePTzS748YZZ5wB13XjvDhFRUVx3h6F5ORkJCcnxx1nqSlwQykACeKgwQ2SE5VERxnFMGmDyJIkkfGUEZX5KvLjMDBOCIHgcoLjElzHE52Wy2WHJzswB2AkiQQAuL6hYJyDmAvuhsFdBw5zwV0mGpzssHmIGR2ULGNIVko2ZodxOI7sHDlEQ5H3cR0OcICHHNEIHMNIuCQbdRSMPDDHFZaEczDmiobiOoAryA654hqwCFgkKsrgOD6RgCJhUqkdaQEAQWgAUMgFhcKCmDgAua7uaBjjYC4XcmMMcLl8Zj5RJJeJYxDGB65BtlgI5AjiSG6wXIL8iA6Rfq6F9JoOvAoiOznJJXBSUxFWBIsBcGVHS1zKkflkhwXLxTwOh7hPypgkf1EOEAdzSHeuwhjL5+/4JAkhCIOsHwQDQi4oHIKXHIaT5IC7jjRwTKcRRl/JFvi5ZQidsrYgzZBrVUQSgFCtMELhFN/IK7KjOlcCWBRwI2KA4DgAc31iogcEHnSnoAiDOu54kKRVkpUQg6s6EEfyIzdIdrwwC+QPQBj0kLxHEgPC4rfjQpJzeV95b2LinCY8qgPzfDvETBKkTIIkTDxMQkiK7CRxv7NRZfMYEGGioyHR0TklzCch5BMSbUeJifsygBw5KOFMykP+JugHoGynGgA4HgvkrUiNkr2qnzngY2b6qLTdUQrYYlEOIRNNbrlPeMQxkc5x/OeliJKqI4ty8ay5B9fzwFhUpHEcME/eIAyAuyC4oGixIAUxbIc5YbCQmiEJCRLBGeCGQG6Sb7dk3hQKDhop7ICFXSApBJbkACkOKJnBDUu9cAEnJATEXYCFAR729ZgZ8lW6xcMAV2RH6hoPEygUJCFK6MwVZEirMSNfh6LKrkMTIE121DlFrj3mE2CDMDOXgUWFPpA/Hj5qCErCZKd27dr497//jU2bNmHDhg0AgCZNmqBRo0aJZlUhSEpKQps2bTB//vxAzM78+fPRq1evhPJSoyLmCVYZaLDG/0AjBoLGifmNDfAbpU6nlINUBy/vLRsfi3J5H3NkyEFwDMIj/8tGKRonE0RHK60afbPgvWKYtTL0pufJvy/5o1d93h/FqFESPO6PLFRjdF2/MTIG4hzMcbS3RhAVR49UROctG75s/OQ6/v0BUU7Xr7vZ+ZvX6bTE/Po5jrSEru850kIwiAAZApLf1f2T9rIKIzouCK9vvxRJu6O63Azyv/JmMVFP5gAEFtQzBwBn4CHHP25cC5eBjLIrq6FJDjPq6DhBmSgPj/4NQTrlMVK/5fcDWSGM6PMmMt0DFSafyoALwmEKwd2W4ntAzXoajz7QNhXXNH6rkTHgkxydh4RPJIw2yGIGUgimJ2UfzCxV/iax0t4FkV4bfBj2x+wkTDJmEgVZZsbVvRmYWQCSJIORIMmqiTkMBNKER1ddyYXJ+3iC1MDoQJkqFAeY1GNRT9L3ZqrzNENKVR3k/7LkGJCpQfRAwTrHetwDniBN3GLu74r8Al6p2HKQtONRD4jdkkXZKYjOOaA7CuqaKAM5wrPDTBul26EhoxhbSObzJtLPkalsmPEJlN3/BPRD2ntBeChYbwZBUHT7iBEIK+U7I014yNChQBqK+W2QaZ3ULOdRkDDZUTjvvPM0wTnZQb0FBQXo378/2rZti/bt2+Oll17C1q1bMWjQoITy4WGC40KTDbORBhoNEBR6zGijLHuvRsKqlQo3tqHAqhOJSi9FlOvpBkYkdNokQQQxXccJ4AQeVtptGkM5GuGKFCHguQATHSmLa7G+EplGm3lyCkuVTU0LaU+MIjs+0RHHRd3IlSMdwL9OESDDEOiRC4vvnMl1dGfLPC7qrzwX0rUMY8SuvEuCuDhgnjHtpQiYzh8+wZJTCkoOJRkcLqhCOvSdXhq2vZWPMyKHSj2vpojAIAynGsEY01jkMN25aYKsPWTM9wpJMDkSYrEG2DSisdPBzCfQqlxaJvKyPY2Ai5J/rPJEJ8w4/vBVX9TYJgRmEhYAQtYx7TrQIZAvQ7Pj1ZfHTLEIkkNyUCDTSI8AOSzY7pTNgUHYZR5xXmJpByigs0pnoKfQeQiB3sAceKnnqL0wUhaMQ09LUMgYIKmLmJx2IA5E5XSCOuVATF0A/pSEaTuP0JGqjplcQxbGfZX3hzSRkpIzy288RxV6wEz7rTzHJKeeFPniZlojFMG01wRjOpkCdVF2VQ0w4VFw8CA9SHAdMQiMesImRaPinMMEoVGDPM+THiFP3J8ru27YRqNPCJwDRLtXH2UHpVzidLcUIhIYoJtQeuYw4yFKHVH5cYCRIMIiM6VDhsFwBNFhjiw/l+cd/z7BKU7doKC9SKWRo6PgmHzOU6ZMQdOmTZGSkoKUlBQ0bdoUkydPPpasKgR9+/bFs88+i8ceewwtW7bEkiVL8N5776Fhw4YJ5UOysZY21+1IN6jfeCg4jy/T63yMEVXcfQKjC4Ox6wSisTDPE14Tfcw4r9Kojl7dy/yoxkiqMUqCFeXahRusv9GRBoiHaEA8JBs7l/eOGCMX1/E/ITcQK6PiQFRnGiBbMr3+GHno/4wFPAtqqg4wiKnZYavYFwfQXgrpdaKwA0oKBd2/kpQJ8sk1YSBVVnmvUN4BUeRSiGEicEF4aH1v1N0gVwQaXiX9XByGH65Ow7Yr0kS5zedhGjZpkNU0lpKHGNkxbUiV1y8gk9LgGN4wIChXAzpWBUA07fjkcSLwZUkObvrsbvy4JssnBo4/Ao4bHRrkzveI+G1V6QY5MYRSTaXoOAiGAFmSUyXqHnoaCtBeWkfFB5r2xGW+PYohDfq3JKF+rAXpaQc9BWF2JKpMRn7mPRhnvofFhENiSjzgBhYxGjwkBo08RMF6GXkrAqTlTH4aLW9DLoqYkpoGMz6I/R6QZZDElOa5CRIi0nGZZltUhNN/XizgMdeeboLwxHLfhogMjDbkOiIuR045k7SfzJWdDufCpnIu4no8MSUdl5/6XQox0XqpZBiQk0+ezT4qlrjHZ8r8Zxj4b1ykfmuiQv6N1DlFqh1DfxR5CSiBT9A0kWJyBsPQO/N2R0PCnp2//OUvGDduHIYOHYr27dsDAJYtW4Y//OEP2LJlCx5//PFEs6wQDB48GIMHDz6+TBwSQb0q5kaOMvwRhtGIzAYLQ1liRhnEAEcHU/nHmeygxdQN/A5burrJdcU5LyrylJ0zMRavk8qLww0DYd7P6ADhMklWTEMFcKNTh+eTBz0S5QBT7njVyKRXhRj5IxQocgNBeFTn6ok6sFgDoMiFU0ZLkwaCXBFTI6ZcSHo0xOiFwQFxLjt7gh6NqVgdg+wIOXn6mCoLyQBvmJ2TKoIkk8lJUaTInuoAHbNTFPt4CrwFmWD8sHie0vAx6f4GY+BJLi64ZhNWfXk2sFgaMEN+Qg8IsaM9LTP1LJR3gfleBAo5YOAgD4G4Jg3XkI3Sc+ntYpx0EK32TNQpOWZZnAi4IDyxoTNqLEgHD8vA3hiCogJhA7Y0lhwY0wPm9IPSRYB08K/Z6XoOgwsybbRoU2pa1rAvojzkd6aB+0PbGAcAEYEbnVpgtG48Th6S3govWGddlNhrjL6GVGCp7GzACMz0iqmO1PXz08cUaWH6UlkgI43q32RBtD005GHKLDANogsfb6O140F/hK4G4pdYTL4GaQpMWToQ3goV46Nst5FGBSmbnndBXExBG3Y3HAIrcQDiov0zJrw+gCA72k4qNzXpdqwL7XExOHMdUNhos2a9YrkDEUiRDiNNnDfFgJInd+EPglRfY8o4buDPhBfHPKZIDqPgfZgSZAwJ0gUwymw8q9hsjoSELfYLL7yASZMm4eabb9bHevbsiebNm2Po0KEnjexUCBzI+UimvTwAE/oGg+goJg/4BoqMZ+X5jYYcc/WDuE6tCtDEQXamak5fKL7slKQLU08JRbnvKXFkQG2I+SN3wyCYKwfEATW694PzSHVe8nzA60Mk5tw9gsuZJAQGCVLZRoX1IOWdMeSp6xMSlo3CEI1brd6KerJ+hgcH8I0EY6BwCJTsiuBkbriKmZzSYiTn/n2iJQ4YdTahZK7qwCHkzeAH+qo6etBepLR/ZaDHnnsx+tLZuCBpB0qOzTGKCduuQt0vI1ArQnRMiCyTWHHGkJl8ECnbwiAnImJwJNnUHsSQfI4xpNaE6cHT35mYznMiEfEcAKjVHSZ5YiSc0WJ1F4CQTwr0VCwBdPDYid+JQsEFH2HM2huRWgTdUauODzDUxfACiCk/cVyMiEmPjgG/zce61ANTByQ6WK48M+qwIic82H9rHVQ23yM4DoNneGd0/Ima+imF4Cj46RliyUPAk2KQE3VSTR3BVxtZJb+nUfZST9NxQYLFiFwYoxheYhQOPinRfSADd33d0lNnyuQyPy/znr4XG/7UmuqMo0qW/jNX/aeWofTYODGV1fIhgFwmV9EZ5VbpOPwpSdMDy5ggPUSifSn7osiNMZWuwkFMr7jIR7ZL87g5uDEHiir2U8ZxxjjfgubB0Blm9HFadojRb63b/rFAnuYD1uRYJYrRP2JgDpe2iIxrILw+5m0lKdbkJ9bbGEuKy0DC1trzPLRt2zbueJs2bRCNRku5ohpBGQUJPYozltyVJlhmNC7TJa5dnoa3wJzT96+Xy8xjp7Rip39cJkaCjiA/XHaK5vRTPCsnqaRM14XLVVf+NaojFVNzAS2Db0BYlMCiUhGVx6Usj4ySpyIbZkyOytcz6kzkN1qZt1oZJOrsSE+OaoVG7JApT9MeOP5SXx3jo2MoTBLAfa+O0Yghia0iCWk7inHOK8Csn1sfc3yKC8LGn+vDKeFSBv58vyino3Xmp8M1UZzp4adLaoCbq5xUhwijU5V11NNzevsCDyzi6eX5wlsYMwLVz9KYLnOUF4zkMmyuy6rd5/J7+rchHD4OT1dlwwNDs+QfcNnVa8QCBGOgokbp/lJW8qeiVGdgdAAU0C/5hfn5BYgOgmnVcnE9pSRjQALTMjH3YUa5AtNMsfFBKg91nRlECwTbSGzxTDvnkH//0kgUMYCzYOdjDq/JsIdmvnJ1WNxoXhJP87iaQgu62Qwiw4LPMJCfJk1+vUxvhI6fMq4zp3XE9gAIysC8hbElRFxd5LMnVw7QQmp7DC4+UX+LDgA+wWEMzIhDBACmPL4A9Ghb2UmP+wQK0FNaaqZA67BHfps16hPrYVTTpmoKT/dhMc8+jqzGwiE52offl2ovDQIkhQggpUfqsBmLY+gUxZIb5VlU/yuL7Nx6662B1zIovPTSS+jXr19CeS1ZsgQ9evRAbm4uGGN4++23A+eJCKNGjUJubi5SU1PRqVMnrFu3LpCmuLgYQ4cOxRlnnIG0tDT07NkTP/zwQ6LVkjc0jItscOYoyjdSMrlUhsC0pTRgYLHGyCAOiFE4BTlXrAOUVdxIyNHeHAq7xrJrMXfsBy/6REUFMJrBaYHGqaaXXAYVDKg8VjpoWqVRpEGzfeZ7bRxHNOxwyCcokpz4RkbFCckGyg2SowhM7GjIcUTsj9xXJ47MmSQpdu6aw/dQcb9uzONytRsF7yXz025oFQCojEiUw4lwgANesosLa+44ZrLjgWHwhUuw9+wkOBHhhmaGq1vVs6hVCgoazMObPf4fHrtnKrZ3SA48X5FYkiQ5HUIyADyO8Hi+PulYMHNVltqvwxX7NwkdY4E8VIC7XgWnO3qGSNrxxzFVNjwwDM5agLRrfgIAY3RuLO2H+K0GArEEQbd31RmW0v41YdL6Y1zvys7UHCAQ4mwBmW3V+M8Igb2+SiU/Zh6l5Kk7dulxDsTxaJJhlEl2KoDf1IIZx9yvlGn0AOkxp9yMsgVkScwgc0z+lv91feUxFswzQFQAP0bKsOuxMtezKtw/bg5c/RgfI45P1tHxSO61ZhAgZfvUQFXvNRYFlURAkYjvuXb8tqpjeDxPBimbekLBabGYQY5OA/iLUXgwnY7ZUXUy9pGKJc0BuRorsBTJMAcB+uErYqn6To+JIHYvrpMEiIE8eU4RW0mgSX7UbyiSC/+evn5SuVnMMfnhVYDyXXfdhbvuugtNmzbFpEmT4DgOCgoK9OdoOHDgAFq0aIHnnnuu1PNPPvkknnnmGTz33HNYsWIFsrOzcc011wR2cB4+fDhmz56N6dOn45NPPsH+/fvRvXv3Y3sLu+lqU8pvzO/6Rs4nLqZh0iP0gBEiTTRMYiLSUyB2RjNzz5PBv+Q3mpDj76cSCo4CxMWGy1I3aGmkDGMOwAi8g78Pi9wnghkNBoAR1W8QKybup12z4ZDc/EqVMWYllicIHNTqM3PFUGBlmE8+9AhJTdWpkQ9BExP/uak5dPK9NlERQK29R5z7nT7nvgdDXq9WUASnKI2l/TKf4gwXF6b8WKr6lBeXpn6DxndtgJfs+ATCnE4EUOPqItR0DsMDw1mhX5Ha7heAAfsbJIk9lTgFnq+5CaIiwmoaRK3sU98DxFMZYylrKI+hfN5KR9WqN39Kwg+CjNTkpdSy6sEDw7jGM7CnRUmwgwJ8EqM9Lyx4jkHLNrazVmmAIPHQnST8TsT3GLAAczC9ERqGfdExPJ5aGEG6vQamZmLLo4iMOsagOyXT0xJYcao6GSMvZsZexNzDhDntwwIjdUPGag8gs/9zSExfmZUwbbDulP39fXTejszTIHJqsMk8iD12PF939aorg+T4A1wydJvp9Op80OtG/mAg0CHLG7lOgPAQERCNypgcmVht0REX6+P5fYOcxtIB8mrbDsPrHztwU9eW6Y2R9VaLbvznAEPfob1uvt2n4G+jzyEm4zchZeEBLMLAjFV7gQIpb4/aT8d8rpwFf6vrzNkX+b8UzSwVCfue165di9atWwMAvvnmGwBAvXr1UK9ePaxd6++eWp7l6F27dkXXrl1LPUdEePbZZzFixAj07t0bAPDqq68iKysL//znP/H73/8ee/bswZQpU/Daa6/h6quvBgC8/vrrOOuss/Dhhx/i2muvTbR6vtFRhidmlEUuAC+YPq5RymN+5L7fkFQ+gevjAtsgOloABGMZIWNgDsBlbIvu4JTngylyZSw5VErrqfgQEainzqmAXrESgftKabjoY+N+NNlRxMTopPWoRhlzk4gAfmPlvldJIxBgC+HBCjt6CbaOq1PEBIbHx4wl0jsEMz8/4x5xu0ZzgMET8TkydEhPlxlNSXVGO710nIefjsu7MyT7I/TrfgHOmyaCe/2RsZBrg5q7A/nv3pOG9LQQQrcWoWRyPaT+XBJ4LoH9kuRyNCbloAheIChd713k6xAcx9+3x+iMmceFPGI5jSQAOf9HmH5FO/Svu7RKLz8HgDDz0O6Cb/H1ssZgDPBM4y6JgFrKrAkNl+KIM/zQ6mEuWVadIgBtB3Rn74hLHEgyIINRzCkoE7Gda8A2yfyFXWE6piUw/aI68ZiBGRDzHaLsPIT4DtIfm8iE5CdSHaKyiQ5pouOvuJJxacoTw3xOI+pnrIA14qjgX17qdyWHWC+cnoLmanqGgjs7q2vNjzrMmCZijJfK57SsgveMsSkm+XAdY1Wt0Q4591dhlQLxFgAV8U6+fTTbsfKKqwdEBhEuZcWtqbexC1r8G8skjqELStcDwVK68gHiCel58wfMEBsNmsHHKi9NiBWZYfFBzWp35lgRc2F/ymtxEiY7CxcuTPSSY8LmzZuxY8cOdO7cWR9LTk7GFVdcgaVLl+L3v/89Vq5ciUgkEkiTm5uLpk2bYunSpWWSndgXge7duxeAlCfzbQk5JISvNpKSUAZIuf98wmOMfKXLOtboQN0jQHgooMwBYhAzX6lHl9LTw0PMCLILvjJC5y+Vjsv4HkeFVunGTj5JIEXQFMEK5hFY9hi4iWjcugOOec2FvladD7kxy+plj6I8WK4rOx5huch1fOOijGuUg5lESwUDOjDYf0w5FeEz9sFgAIhLL4ajRkV+LBCXnjRyGGrsKMHz/+yBMwdMRW5oF44VDuO49+p5mPXxNUjfsh+Myc7KYQAnrNyQD7eBX/Y/tvkA097ojtQxGQAvMXZNltVignQyYmCM4JAf+BzYC8kIkPTjmRydh/ii/6jCwo9JgHZtgwEsCoQOccybfQlKeoVw5xlLqjzhWf7lOchU9pr8lXh6YYEJaQzUIgMEZCRgdqYqpkntDmzGmWjigyBh0h19jLdHlE/my0iTMLNsccRMD7QMAqHSohSyAGnLTFIGxHQ4wigSSBRRjcb19YqEiWPMmLZQ9ijgdTY6WzBDlFomquP27U4cUUMwH/06n5gBp05qhhTI1XiaFFFMnkZZyGEgIv0qIE2wHIgYRoI/cJT9hdowlVHUf57RqPioqSrV5oj8wORYW2Xu1aP23DHIDeMkVqGGQ4JNgAsvFmMgl2vPcdAjD20X1CNTcTvEpOk0vW6MYkI4SOelXwcRo5OBRyRlTC6g9tfRSlEK2Qw4GKQnD4wQt7eOkX8ph0tFlY0qVK9/KO0Fn999951Ok5SUhDp16sSlKesloEDZLwLlhw8Lw1TCxOoTAtROyswD3Igw7hQBECEgAt3YnCiByz5FKwcPenVIGb4SAiLCVckpCgYVXyKnUVTHD4CYA/JcEMl4CrkZGREDh5zflNoWFyMQM9VFksioNI4MOHaiHIiI97kAotPk8hUUBEECnKgMUo0KouNwDsbFlujERcyHuWTW9AII7xH5Ll/An38m0sSDuAMgBIIDglrCJlfDqdVgnMDlHj+MczHvq5ZKy/iaQJ3BAmXRIw/lJlYuYZWeOSDhPgOiBLgAd0JCblxcW29JMQqS++AfPSchHDsMTQBtsB7Pd70E54wXK7PEijBBZHPeJvSO3IEaGYfBGKHn2Wuw5dqDOPc1wVS9ZFc/S2E3fLk7ILgkXufhRKNg0Yi4oSvrpYgsXN+Dx426E8UbIA5wxwV3HfCo0D0w1bkQMpcdxtyUC9C356IKe3dYZcABgXZFwIs9EbcS0ybUO7JUnJdeOakIha6zT0QQpWCnSeR38vJaPSgxBg+BAZQ6rkgYFwSKPIBzFvC0agJGDDwqbA33mI6D5SHAI7HyUd8rwhDr2TCnZcxOiTOCBwJ5BCqRHVSIB99jFHH8gZgiOJ4cZXsAPAZPkz9ZBrXFv0tgHtOeBQqJLT+Unqn3bOkymp20SZqUSJTXRu6FpjkDAygKoJhAUcQRQ/UMTe8FSfWHfuUH4EaFHChCUJ5uN8KF3VS6Im0v80RMoAMPDkUBRMB4FOARUPSw3CID/q7zHIDrisEOKfKg3iESBSJRMAoBCIOxEBCJSlsrbSY5okMy9zbzHHgIgYfD8MIuiDGhK2EVM+bLMZZEqs0oeQjgID3dSWpVoiNJjgOhH7Er9si313q7A4fAkwUxY2FZbq1D8hpVIAdiyt0hP95HxQhx+ZoIz9/zB5D9NkohizGosmRHIZEXfJY3TeyLQDdv3oyWLVvih5HVeNm8xYnFYqDrnysio8expaxTc/yvfwcAvIdjDL0/MfgQuHLEyS5EefAXfH+yi2BhYVGh2LdvHzIyMso8X2XJTnZ2NgDhvcnJydHHzRd8Zmdno6SkBLt27Qp4d4qKitChQ4cy8459EajaaXnr1q1HFNbpgL179+Kss87C999/j1q1ap3s4pxUWFn4sLLwYWXhw8rCh5WFjxMpCyLCvn37kJube8R0VZbs5OfnIzs7G/Pnz0erVq0AACUlJVi8eDGeeOIJAGJvn3A4jPnz5+Omm24CAGzfvh1r167Fk08+We57OdL9l5GRcdorqUKtWrWsLCSsLHxYWfiwsvBhZeHDysLHiZJFeZwUJ5Xs7N+/H19//bX+vXnzZhQWFqJu3brIy8vD8OHDMXr0aJx33nk477zzMHr0aNSoUQO33HILAFHBO++8E/fffz8yMzNRt25d/M///A+aNWumV2dZWFhYWFhYnN5IeJ+dV199FXPm+MEEDz74IGrXro0OHTrowOHy4vPPP0erVq2056agoACtWrXCI488ovMePnw4Bg8ejLZt22Lbtm2YN28eatasqfMYN24crr/+etx0003o2LEjatSogXfffRfuEZb0WVhYWFhYWJxGoARx/vnn00cffUREREuXLqXU1FR68cUXqUePHnTDDTckml2VwOHDh2nkyJF0+PDhk12Ukw4rCx9WFj6sLHxYWfiwsvBhZeGjKsqCER1lvVYMatSogS+//BJ5eXn44x//iO3bt2Pq1KlYt24dOnXqhJ9//rmyeJmFhYWFhYWFRcJIeBorPT0dO3fuBADMmzdPx8akpKTg0KFDFVs6CwsLCwsLC4vjRMIBytdccw3uuusutGrVCl999RWuu+46AMC6detw9tlnV3T5LCwsLCwsLCyOCwl7dp5//nm0b98eP//8M2bOnInMzEwAwMqVK3HzzTdXeAEtLCwsLCwsLI4HCcfsWFhYWFhYWFhUJ5TLs7N69Wpw+S6O1atXH/FT3TBx4kTk5+cjJSUFbdq0wccff3yyi1ThGDVqFBhjgY/aoRoQO1COGjUKubm5SE1NRadOnbBu3bpAHsXFxRg6dCjOOOMMpKWloWfPnvjhhyr98gIAwJIlS9CjRw/k5uaCMYa33347cL6i6r5r1y70798fGRkZyMjIQP/+/bF79+5Krl1iOJosBg4cGKcnl156aSDNqSCLMWPG4OKLL0bNmjVRv359XH/99di4cWMgzemkF+WRx+miGy+88AKaN2+uN8Nr37493n//fX3+dNKLo8mi2ulEuZZsMUY//fST/u44DjHG9Ef9dhynUpaMVRamT59O4XCYJk2aROvXr6f77ruP0tLS6LvvvjvZRatQjBw5ki666CLavn27/hQVFenzY8eOpZo1a9LMmTNpzZo11LdvX8rJyaG9e/fqNIMG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qI46kfDrIu68805MmDABaWlpgeOFhYW49dZbsXbt2mPyMFlYWFhYWFhYVAYq9N1YxcXFSE5OrqjsLCwsLCwsLCyOGwkvPTdx6NAhRCKRwDFLdiwsLCwsLCyqEhJejXXgwAEMGTIE9evXR3p6OurUqRP4WFhYWFhYWFhUJSRMdh588EEsWLAAEydORHJyMiZPnoxHH30Uubm5mDp1amWU0cLCwsLCwsLimJFwzE5eXh6mTp2KTp06oVatWvjiiy/QqFEjvPbaa/jXv/6F9957r7LKamFhYWFhYWGRMBL27Pz6669606latWrh119/BQBcdtllWLJkScWWzsLCwsLCwsLiOJEw2TnnnHOwZcsWAECTJk0wY8YMAMC7776L2rVrV2TZLCwsLCwsLCyOGwlPY40bNw6u62LYsGFYuHAhrrvuOnieh2g0imeeeQb33XdfZZXVwsLCwsLCwiJhHPc+O1u3bsXnn3+Oc889Fy1atKiocllYWBwBo0aNwttvv43CwsKTXZQKw9lnn43hw4dj+PDhJ7socajKZQPEm6Nnz56N66+/vsw0AwcOxO7du/H222+fsHJZWFQVHNc+O4AIWM7Ly6uIslhYWEB0XEfCgAED8Nxzz2Ho0KEnqERVA3379sWWLVuwdOlSuK4LAIhEImjXrh2aNGmC119/vdLuvWLFirhd46sStm/frrf+2LJlC/Lz87Fq1Sq0bNlSpxk/fjwqcA9ZC4tqheMmOxYWFhWL7du36+9vvPEGHnnkEWzcuFEfS01NRXp6OtLT009G8U4aJk6ciIsuughjx47FiBEjAAB//etfsWPHDnz00UeVeu969epVav7Hi+zs7KOmycjIOAElsbComkg4QNnCwqJykZ2drT8ZGRlgjMUdGzVqVGDUPnDgQFx//fUYPXo0srKyULt2bTz66KOIRqN44IEHULduXTRo0AD/+7//G7jXtm3b0LdvX9SpUweZmZno1auXXoBQGjzPw5133on8/HykpqaicePGGD9+fCCNKstTTz2FnJwcZGZm4t577w3stl5UVIQePXogNTUV+fn5mDZt2lHlkpmZiZdeegmPPfYYVq9ejZUrV2LMmDGYPHnyETc0nTt3Li677DLUrl0bmZmZ6N69O7755ht9furUqUhPT8emTZv0saFDh+L888/HgQMHAIhprGeffVafHzVqFPLy8pCcnIzc3FwMGzaszPurZ/Xiiy/irLPOQo0aNdCnTx/s3r1bp+Gc47HHHkODBg2QnJyMli1bYu7cufp8SUkJhgwZgpycHKSkpODss8/GmDFj9HnGmJ6eUqtlW7VqBcYYOnXqBMB/LgrFxcUYNmwY6tevj5SUFFx22WVYsWKFPr9o0SIwxvDRRx+hbdu2qFGjBjp06BAg3hYW1QXlJjs//PBDZZbDwsLiOLFgwQL8+OOPWLJkCZ555hmMGjUK3bt3R506dbB8+XIMGjQIgwYNwvfffw8AOHjwIH77298iPT0dS5YswSeffIL09HR06dIFJSUlpd6Dc44GDRpgxowZWL9+PR555BE8/PDDelWmwsKFC/HNN99g4cKFePXVV/HKK6/glVde0ecHDhyILVu2YMGCBXjrrbcwceJEFBUVHbWOPXv2xO9+9zvcdtttuO222zBgwAB069btiNccOHAABQUFWLFiBT766CM4joMbbrgBnHMAwG233YZu3bqhX79+iEajmDt3Ll588UVMmzat1Kmrt956C+PGjcOLL76ITZs24e2330azZs2OWIavv/4aM2bMwLvvvou5c+eisLAQ9957rz4/fvx4PP3003jqqaewevVqXHvttejZs6cmYBMmTMA777yDGTNmYOPGjXj99ddx9tlnl3qvzz77DADw4YcfYvv27Zg1a1ap6R588EHMnDkTr776qt4v7dprr9XbiSiMGDECTz/9ND7//HOEQiHccccdR6yrhUWVRHlfj56RkUFTp06t8NeuW1hYlI2XX36ZMjIy4o6PHDmSWrRooX8PGDCAGjZsSJ7n6WONGzem3/zmN/p3NBqltLQ0+te//kVERFOmTKHGjRsT51ynKS4uptTUVPrggw/KXcbBgwfTjTfeGFeWaDSqj/Xp04f69u1LREQbN24kAPTpp5/q8xs2bCAANG7cuKPeb9euXZSamkpZWVm0Z8+ecpdToaioiADQmjVr9LFff/2VGjRoQPfccw9lZWXR448/HrimYcOGumxPP/00nX/++VRSUlKu+40cOZJc16Xvv/9eH3v//ffJcRzavn07ERHl5ubS3/72t8B1F198MQ0ePJiIiIYOHUpXXnll4FmZAECzZ88mIqLNmzcTAFq1alUgzYABA6hXr15ERLR//34Kh8M0bdo0fb6kpIRyc3PpySefJCKihQsXEgD68MMP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" + }, + "metadata": {}, + "output_type": "display_data" + } ], - "id": "1111f040431c3115" + "execution_count": 17 }, { "metadata": {}, @@ -265,7 +353,7 @@ "plt.plot(field_final[:,1:5])\n", "\n", "plt.figure()\n", - "plt.plot(kt_all.iloc[:,1:5])\n", + "plt.plot(kt.iloc[:,1:5])\n", "plt.show()\n", "\n", "# Convert space to time to extract time series\n", @@ -282,7 +370,7 @@ "\n", "plt.plot(sim_kt[[40,42]])\n", "plt.figure()\n", - "plt.plot(kt_all[[40,42]])\n", + "plt.plot(kt[[40,42]])\n", "plt.show()\n", "\n", "\n", diff --git a/src/solarspatialtools/synthirrad/cloudfield.py b/src/solarspatialtools/synthirrad/cloudfield.py index 1022bef..780599a 100644 --- a/src/solarspatialtools/synthirrad/cloudfield.py +++ b/src/solarspatialtools/synthirrad/cloudfield.py @@ -1,6 +1,7 @@ import numpy as np from scipy.interpolate import RegularGridInterpolator -# from scipy.ndimage import map_coordinates + +import pvlib import matplotlib.pyplot as plt from scipy.ndimage import sobel, uniform_filter @@ -377,7 +378,6 @@ def get_timeseries_stats(kt_ts, clear_threshold=0.95, plot=False): scales : list The timescales of the wavelets """ - import pvlib # Get the mean and standard deviation of the time series ktmean = np.mean(kt_ts) # represents mean of kt