From ee7c8e20127a47303f2567be3823c2e3d86008e5 Mon Sep 17 00:00:00 2001 From: pciturri Date: Tue, 20 Aug 2024 04:09:08 +0200 Subject: [PATCH 01/17] refac: initial refactoring of the plotting module. - Harmonized the parameters for all plotting functions. Removed the `plot_args` argument from all functions. Now, default parameters, such as `title`, `figsize` and many other repeating parameters are now found in a global dictionary `DEFAULT_PLOT_ARGS`. All plotting functions now default to these parameters and update a copy of it with **kwargs, thus having control to customize plots. Relevant parameters to the function are left in the function signature. - Added type hints for all signatures. - Removed functions `plot_cumulative_events_versus_time_dev`, `plot_ecdf`, `plot_magnitude_histogram_dev`. - Refactored catalog evaluation plot functions `plot_number_test`, `plot_magnitude_test`, `plot_spatial_test`, `plot_likelihood_test` into a generic `plot_distribution_test` (Should it be renamed plot_consistency_test?). Automatic annotations for each type test are done if required, or when called directly from EvaluationResult subclasses. - The function `plot_poisson_consistency_test` was collapsed onto `plot_consistency_test`, which also included the negative binomial model. - Reworked `plot_magnitude_vs_time`: removed some old functionality and give the possibility to scale the size of each event by its magnitude. Added datetime formatter/locator - Reworked`plot_cumulative_events_versus_time`. Now it has the option to plot with the real datetimes, or hours/days after a given mainshock. - Now plot_magnitude_histogram plots in log scale. - plot_basemap now allows cacheing of downloaded data - Created or refactored from existing functions multiple helper functions to ease unit testing and code readability: `_get_basemap`,`_autosize_scatter`, `_size_map`, `_autoscale_histogram`, `_annotate_distribution_plot`, `_calculate_spatial_extent`, `_create_geo_axes`, `_calculate_marker_size`, `_add_gridlines`, `_define_colormap_and_alpha`, `_add_colorbar`, _process_stat_distribution`. These still needs some review, type hinting and further refactoring if necessary. tests: Completed test coverage of almost all plots.py functions. Added test artifacts for catalog based evaluations (catalogs, forecasts, test results). --- csep/core/catalog_evaluations.py | 4 +- csep/models.py | 12 +- csep/utils/plots.py | 4326 +++---- .../tutorials/gridded_forecast_evaluation.py | 4 +- examples/tutorials/plot_customizations.py | 2 +- .../Catalog/catalog.json | 173 + .../Forecasts/ucerf3-landers_short.csv | 2426 ++++ .../Results/calibration_m.json | 125 + .../Results/calibration_n.json | 141 + .../Results/catalog_l_test.json | 10016 ++++++++++++++++ .../Results/catalog_m_test.json | 7411 ++++++++++++ .../Results/catalog_n_test.json | 10016 ++++++++++++++++ .../Results/catalog_s_test.json | 7411 ++++++++++++ tests/test_plots.py | 1393 ++- 14 files changed, 41010 insertions(+), 2450 deletions(-) create mode 100644 tests/artifacts/example_csep2_forecasts/Catalog/catalog.json create mode 100644 tests/artifacts/example_csep2_forecasts/Forecasts/ucerf3-landers_short.csv create mode 100644 tests/artifacts/example_csep2_forecasts/Results/calibration_m.json create mode 100644 tests/artifacts/example_csep2_forecasts/Results/calibration_n.json create mode 100644 tests/artifacts/example_csep2_forecasts/Results/catalog_l_test.json create mode 100644 tests/artifacts/example_csep2_forecasts/Results/catalog_m_test.json create mode 100644 tests/artifacts/example_csep2_forecasts/Results/catalog_n_test.json create mode 100644 tests/artifacts/example_csep2_forecasts/Results/catalog_s_test.json diff --git a/csep/core/catalog_evaluations.py b/csep/core/catalog_evaluations.py index 885898f3..7caa12f7 100644 --- a/csep/core/catalog_evaluations.py +++ b/csep/core/catalog_evaluations.py @@ -136,7 +136,7 @@ def spatial_test(forecast, observed_catalog, verbose=True): delta_1, delta_2 = get_quantiles(test_distribution_spatial_1d, obs_lh_norm) result = CatalogSpatialTestResult(test_distribution=test_distribution_spatial_1d, - name='S-Test', + name='Catalog S-Test', observed_statistic=obs_lh_norm, quantile=(delta_1, delta_2), status=message, @@ -160,7 +160,7 @@ def magnitude_test(forecast, observed_catalog, verbose=True): print("Cannot perform magnitude test when observed event count is zero.") # prepare result result = CatalogMagnitudeTestResult(test_distribution=test_distribution, - name='M-Test', + name='Catalog M-Test', observed_statistic=None, quantile=(None, None), status='not-valid', diff --git a/csep/models.py b/csep/models.py index 5224a83d..65e94c73 100644 --- a/csep/models.py +++ b/csep/models.py @@ -143,7 +143,7 @@ def plot(self, show=False, plot_args=None): 'bins': bins} # looks funny, but will update the defaults with the user defined arguments plot_args_defaults.update(plot_args) - ax = plots.plot_number_test(self, show=show, plot_args=plot_args) + ax = plots.plot_distribution_test(self, show=show) return ax @@ -160,7 +160,7 @@ def plot(self, show=False, plot_args=None): 'bins': 'auto'} # looks funny, but will update the defaults with the user defined arguments plot_args_defaults.update(plot_args) - ax = plots.plot_likelihood_test(self, show=show, plot_args=plot_args) + ax = plots.plot_distribution_test(self, show=show) return ax @@ -175,7 +175,7 @@ def plot(self, show=False, plot_args=None): 'title': 'Magnitude Test', 'bins': 'auto'} plot_args_defaults.update(plot_args) - ax = plots.plot_magnitude_test(self, show=show, plot_args=plot_args) + ax = plots.plot_distribution_test(self, show=show) return ax @@ -194,7 +194,7 @@ def plot(self, show=False, plot_args=None): } # looks funny, but will update the defaults with the user defined arguments plot_args_defaults.update(plot_args) - ax = plots.plot_spatial_test(self, show=show, plot_args=plot_args) + ax = plots.plot_distribution_test(self, show=show) return ax @@ -211,7 +211,7 @@ def plot(self, show=False, axes=None, plot_args=None): 'title': self.name } plot_args_defaults.update(plot_args) - ax = plots.plot_calibration_test(self, show=show, axes=axes, plot_args=plot_args) + ax = plots.plot_calibration_test(self, show=show, ax=axes, plot_args=plot_args) return ax @@ -361,4 +361,4 @@ def from_great_circle_radius(cls, centroid, radius, num_points=10): # get new lons and lats endlon, endlat, backaz = geod.fwd(center_lons, center_lats, azim, radius) # class method - return cls(np.column_stack([endlon, endlat])) \ No newline at end of file + return cls(np.column_stack([endlon, endlat])) diff --git a/csep/utils/plots.py b/csep/utils/plots.py index 6ecdbfc6..ae0009ee 100644 --- a/csep/utils/plots.py +++ b/csep/utils/plots.py @@ -1,150 +1,245 @@ -import time +import string +from typing import TYPE_CHECKING, Optional, Any, List, Union, Tuple # Third-party imports import numpy -import string +import numpy as np import pandas as pandas -from scipy.integrate import cumulative_trapezoid +import cartopy +import cartopy.crs as ccrs +from cartopy.io import img_tiles +from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER +from matplotlib.axes import Axes +from matplotlib.dates import AutoDateLocator, DateFormatter +from matplotlib.lines import Line2D import scipy.stats +from scipy.integrate import cumulative_trapezoid import matplotlib import matplotlib.lines -from matplotlib import cm -from matplotlib.collections import PatchCollection import matplotlib.pyplot as pyplot -import cartopy -import cartopy.crs as ccrs -from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER -from cartopy.io import img_tiles + + # PyCSEP imports -from csep.utils.constants import SECONDS_PER_DAY, CSEP_MW_BINS +import csep.utils.time_utils from csep.utils.calc import bin1d_vec +from csep.utils.constants import SECONDS_PER_DAY, CSEP_MW_BINS, SECONDS_PER_HOUR from csep.utils.time_utils import datetime_to_utc_epoch -""" -This module contains plotting routines that generate figures for the stochastic -event sets produced from CSEP2 experiments and Poisson based CSEP1 experiments. - -Right now functions dont have consistent signatures, which will be addressed in -future releases. That means that some functions might have more functionality -than others while the routines are being developed. - -TODO: Add annotations for other two plots. -TODO: Add ability to plot annotations from multiple catalogs. - Esp, for plot_histogram() -IDEA: Same concept mentioned in evaluations might apply here. The plots could - be a common class that might provide more control to the end user. -IDEA: Since plotting functions are usable by these classes only that don't - implement iter routines, maybe make them a class method. like - data.plot_thing() -""" - - -def plot_cumulative_events_versus_time_dev(xdata, ydata, obs_data, - plot_args, show=False): +if TYPE_CHECKING: + from csep.core.catalogs import CSEPCatalog + from csep.core.forecasts import GriddedForecast, CatalogForecast + from csep.models import EvaluationResult + from csep.core.regions import CartesianGrid2D + + +DEFAULT_PLOT_ARGS = { + # General figure/axes handling + "figsize": None, + "tight_layout": True, + "grid": True, + "title": None, + "title_fontsize": 16, + "xlabel": None, + "ylabel": None, + "xlabel_fontsize": 12, + "ylabel_fontsize": 12, + "xticks_fontsize": 12, + "yticks_fontsize": 12, + "xlim": None, + "ylim": None, + "legend": True, + "legend_loc": "best", + "legend_fontsize": 10, + "legend_title": None, + "legend_titlesize": None, + "legend_labelspacing": 1, + "legend_borderpad": 0.4, + "legend_framealpha": None, + # Line/Scatter parameters + "color": "steelblue", + "alpha": 0.8, + "linewidth": 1, + "size": 5, + "marker": "o", + "markersize": 5, + "markercolor": "steelblue", + "markeredgecolor": "black", + # Time-Series + "datetime_locator": AutoDateLocator(), + "datetime_formatter": DateFormatter("%Y-%m-%d"), + # Consistency and Comparison tests + "capsize": 2, + "hbars": True, + # Specific to spatial plotting + "grid_labels": True, + "grid_fontsize": 8, + "region_color": "black", + "coastline": True, + "coastline_color": "black", + "coastline_linewidth": 1.5, + "borders": False, + "borders_color": "black", + "borders_linewidth": 1.5, + # Color bars + "colorbar_labelsize": 12, + "colorbar_ticksize": 10, +} + + +######################## +# Data-exploratory plots +######################## +def plot_magnitude_vs_time( + catalog: "CSEPCatalog", + ax: Optional[Axes] = None, + color: Optional[str] = "steelblue", + size: Optional[int] = 4, + mag_scale: Optional[int] = 6, + alpha: Optional[float] = 0.5, + show: bool = False, + **kwargs: Any, +) -> matplotlib.axes.Axes: """ - + Plots magnitude versus time for a given catalog. Args: - xdata (ndarray): time bins for plotting shape (N,) - ydata (ndarray or list like): ydata for plotting; shape (N,5) in order 2.5%Per, 25%Per, 50%Per, 75%Per, 97.5%Per - obs_data (ndarry): same shape as xdata - plot_args: - show: + catalog (:class:`csep.core.catalogs.CSEPCatalog`): + Catalog of seismic events to be plotted. + ax (Axes): + Matplotlib axis object on which to plot. If not provided, a new figure and axis are + created. + color (str): + Color of the scatter plot points. If not provided, defaults to value in + `DEFAULT_PLOT_ARGS`. + size (int): + Size of the scatter plot markers. + mag_scale (int): + Scaling factor for the magnitudes. + alpha (float): + Transparency level for the scatter plot points. If not provided, defaults to value + in `DEFAULT_PLOT_ARGS`. + show (bool): + Whether to display the plot. Defaults to `False`. + **kwargs: + Additional keyword arguments for customizing the plot. These are merged with + `DEFAULT_PLOT_ARGS`. + Returns: + Axes: + The Matplotlib axes object with the plotted data. """ - figsize = plot_args.get('figsize', None) - sim_label = plot_args.get('sim_label', 'Simulated') - obs_label = plot_args.get('obs_label', 'Observation') - legend_loc = plot_args.get('legend_loc', 'best') - title = plot_args.get('title', 'Cumulative Event Counts') - xlabel = plot_args.get('xlabel', 'Days') - - fig, ax = pyplot.subplots(figsize=figsize) - try: - fifth_per = ydata[0, :] - first_quar = ydata[1, :] - med_counts = ydata[2, :] - second_quar = ydata[3, :] - nine_fifth = ydata[4, :] - except: - raise TypeError("ydata must be a [N,5] ndarray.") - # plotting - - ax.plot(xdata, obs_data, color='black', label=obs_label) - ax.plot(xdata, med_counts, color='red', label=sim_label) - ax.fill_between(xdata, fifth_per, nine_fifth, color='red', alpha=0.2, - label='5%-95%') - ax.fill_between(xdata, first_quar, second_quar, color='red', alpha=0.5, - label='25%-75%') - ax.legend(loc=legend_loc) - ax.set_xlabel(xlabel) - ax.set_ylabel('Cumulative event count') - ax.set_title(title) - # pyplot.subplots_adjust(right=0.75) - # annotate the plot with information from data - # ax.annotate(str(observation), xycoords='axes fraction', xy=xycoords, fontsize=10, annotation_clip=False) - # save figure - filename = plot_args.get('filename', None) - if filename is not None: - fig.savefig(filename + '.pdf') - fig.savefig(filename + '.png', dpi=300) - # optionally show figure + + # Initialize plot + plot_args = {**DEFAULT_PLOT_ARGS, **kwargs} + fig, ax = pyplot.subplots(figsize=plot_args["figsize"]) if ax is None else (ax.figure, ax) + + # Plot data + mag = catalog.data["magnitude"] + datetimes = catalog.get_datetimes() + ax.scatter( + datetimes, + mag, + marker="o", + c=color, + s=_autosize_scatter(size, mag, mag_scale), + alpha=alpha, + ) + + # Set labels and title + ax.set_xlabel(plot_args["xlabel"] or "Datetime", fontsize=plot_args["xlabel_fontsize"]) + ax.set_ylabel(plot_args["ylabel"] or "$M$", fontsize=plot_args["ylabel_fontsize"]) + ax.set_title( + plot_args["title"] or "Magnitude vs. Time", fontsize=plot_args["title_fontsize"] + ) + + # Autoformat ticks and labels + ax.xaxis.set_major_locator(plot_args["datetime_locator"]) + ax.xaxis.set_major_formatter(plot_args["datetime_formatter"]) + ax.grid(plot_args["grid"]) + fig.autofmt_xdate() + + if plot_args["tight_layout"]: + fig.tight_layout() if show: pyplot.show() return ax -def plot_cumulative_events_versus_time(stochastic_event_sets, observation, - show=False, plot_args=None): +def plot_cumulative_events_versus_time( + catalog_forecast: "CatalogForecast", + observation: "CSEPCatalog", + time_axis: str = "datetime", + bins: int = 50, + ax: Optional[matplotlib.axes.Axes] = None, + sim_label: Optional[str] = "Simulated", + obs_label: Optional[str] = "Observation", + show: bool = False, + **kwargs, +) -> matplotlib.axes.Axes: """ - Same as below but performs the statistics on numpy arrays without using pandas data frames. + Plots the cumulative number of forecasted events versus observed events over time. Args: - stochastic_event_sets: - observation: - show: - plot_args: + catalog_forecast (GriddedForecast): The forecasted catalogs. + observation (CSEPCatalog): The observed catalog of events. + time_axis (str): The type of time axis ('datetime', 'days', 'hours'). Defaults + to 'datetime'. + ax (Optional[pyplot.Axes]): The axes to plot on. If None, a new figure and + axes are created. + bins (int): The number of bins for time slicing. Defaults to 50. + sim_label (str): Label for simulated data. Defaults to 'Simulated'. + obs_label (str): Label for observed data. Defaults to 'Observation'. + show (bool): If True, displays the plot. Defaults to False. + **kwargs: Additional plotting arguments to override `DEFAULT_PLOT_ARGS`. Returns: - ax: matplotlib.Axes + pyplot.Axes: The axes with the cumulative event plot. """ - plot_args = plot_args or {} - print('Plotting cumulative event counts.') - figsize = plot_args.get('figsize', None) - fig, ax = pyplot.subplots(figsize=figsize) - # get global information from stochastic event set - t0 = time.time() - n_cat = len(stochastic_event_sets) - - extreme_times = [] - for ses in stochastic_event_sets: - start_epoch = datetime_to_utc_epoch(ses.start_time) - end_epoch = datetime_to_utc_epoch(ses.end_time) - if start_epoch == None or end_epoch == None: - continue - extreme_times.append((start_epoch, end_epoch)) + # Initialize plot + plot_args = {**DEFAULT_PLOT_ARGS, **kwargs} + fig, ax = pyplot.subplots(figsize=plot_args["figsize"]) if ax is None else (ax.figure, ax) + + # Get information from stochastic event set + if catalog_forecast.start_time is None or catalog_forecast.end_time is None: + extreme_times = [] + for ses in catalog_forecast: + if ses.start_time and ses.end_time: + extreme_times.append( + (datetime_to_utc_epoch(ses.start_time), datetime_to_utc_epoch(ses.end_time)) + ) + start_time = numpy.min(numpy.array(extreme_times)) + end_time = numpy.max(numpy.array(extreme_times)) + else: + start_time = datetime_to_utc_epoch(catalog_forecast.start_time) + end_time = datetime_to_utc_epoch(catalog_forecast.end_time) # offsets to start at 0 time and converts from millis to hours - time_bins, dt = numpy.linspace(numpy.min(extreme_times), - numpy.max(extreme_times), 100, - endpoint=True, retstep=True) + time_bins, dt = numpy.linspace(start_time, end_time, bins, endpoint=True, retstep=True) n_bins = time_bins.shape[0] - binned_counts = numpy.zeros((n_cat, n_bins)) - for i, ses in enumerate(stochastic_event_sets): + + # Initialize an empty list to store binned counts for each stochastic event set + binned_counts_list = [] + + for i, ses in enumerate(catalog_forecast): n_events = ses.data.shape[0] ses_origin_time = ses.get_epoch_times() inds = bin1d_vec(ses_origin_time, time_bins) + + # Create a temporary array for the current stochastic event set + temp_binned_counts = numpy.zeros(n_bins) for j in range(n_events): - binned_counts[i, inds[j]] += 1 - if (i + 1) % 1500 == 0: - t1 = time.time() - print(f"Processed {i + 1} catalogs in {t1 - t0} seconds.") - t1 = time.time() - print(f'Collected binned counts in {t1 - t0} seconds.') + temp_binned_counts[inds[j]] += 1 + + # Append the temporary array to the list + binned_counts_list.append(temp_binned_counts) + + # Convert the list of arrays to a 2D NumPy array + binned_counts = numpy.array(binned_counts_list) + # Compute the cumulative sum along the specified axis summed_counts = numpy.cumsum(binned_counts, axis=1) # compute summary statistics for plotting @@ -153,6 +248,7 @@ def plot_cumulative_events_versus_time(stochastic_event_sets, observation, med_counts = numpy.percentile(summed_counts, 50, axis=0) second_quar = numpy.percentile(summed_counts, 75, axis=0) nine_fifth = numpy.percentile(summed_counts, 95, axis=0) + # compute median for comcat data obs_binned_counts = numpy.zeros(n_bins) inds = bin1d_vec(observation.get_epoch_times(), time_bins) @@ -160,12 +256,8 @@ def plot_cumulative_events_versus_time(stochastic_event_sets, observation, obs_binned_counts[inds[j]] += 1 obs_summed_counts = numpy.cumsum(obs_binned_counts) - # update time_bins for plotting - millis_to_hours = 60 * 60 * 1000 * 24 - time_bins = (time_bins - time_bins[0]) / millis_to_hours - time_bins = time_bins + (dt / millis_to_hours) # make all arrays start at zero - time_bins = numpy.insert(time_bins, 0, 0) + time_bins = numpy.insert(time_bins, 0, 2 * time_bins[0] - time_bins[1]) # One DT before fifth_per = numpy.insert(fifth_per, 0, 0) first_quar = numpy.insert(first_quar, 0, 0) med_counts = numpy.insert(med_counts, 0, 0) @@ -173,512 +265,528 @@ def plot_cumulative_events_versus_time(stochastic_event_sets, observation, nine_fifth = numpy.insert(nine_fifth, 0, 0) obs_summed_counts = numpy.insert(obs_summed_counts, 0, 0) - # get values from plotting args - sim_label = plot_args.get('sim_label', 'Simulated') - obs_label = plot_args.get('obs_label', 'Observation') - xycoords = plot_args.get('xycoords', (1.00, 0.40)) - legend_loc = plot_args.get('legend_loc', 'best') - title = plot_args.get('title', 'Cumulative Event Counts') - # plotting - ax.plot(time_bins, obs_summed_counts, color='black', label=obs_label) - ax.plot(time_bins, med_counts, color='red', label=sim_label) - ax.fill_between(time_bins, fifth_per, nine_fifth, color='red', alpha=0.2, - label='5%-95%') - ax.fill_between(time_bins, first_quar, second_quar, color='red', alpha=0.5, - label='25%-75%') - ax.legend(loc=legend_loc) - ax.set_xlabel('Days since Mainshock') - ax.set_ylabel('Cumulative Event Count') - ax.set_title(title) - pyplot.subplots_adjust(right=0.75) - # annotate the plot with information from data - # ax.annotate(str(observation), xycoords='axes fraction', xy=xycoords, fontsize=10, annotation_clip=False) - # save figure - filename = plot_args.get('filename', None) - if filename is not None: - fig.savefig(filename + '.pdf') - fig.savefig(filename + '.png', dpi=300) - # optionally show figure + if time_axis == "datetime": + time_bins = [csep.epoch_time_to_utc_datetime(i) for i in time_bins] + ax.xaxis.set_major_locator(plot_args["datetime_locator"]) + ax.xaxis.set_major_formatter(plot_args["datetime_formatter"]) + ax.set_xlabel(plot_args["xlabel"] or "Datetime", fontsize=plot_args["xlabel_fontsize"]) + fig.autofmt_xdate() + elif time_axis == "days": + time_bins = (time_bins - time_bins[0]) / (SECONDS_PER_DAY * 1000) + ax.set_xlabel( + plot_args["xlabel"] or "Days after Mainshock", fontsize=plot_args["xlabel_fontsize"] + ) + elif time_axis == "hours": + time_bins = (time_bins - time_bins[0]) / (SECONDS_PER_HOUR * 1000) + ax.set_xlabel( + plot_args["xlabel"] or "Hours after Mainshock", + fontsize=plot_args["xlabel_fontsize"], + ) + + # Plotting + ax.plot( + time_bins, + obs_summed_counts, + color="black", + linewidth=plot_args["linewidth"], + label=obs_label, + ) + ax.plot( + time_bins, + med_counts, + color=plot_args["color"], + linewidth=plot_args["linewidth"], + label=sim_label, + ) + ax.fill_between( + time_bins, fifth_per, nine_fifth, color=plot_args["color"], alpha=0.2, label="5%-95%" + ) + ax.fill_between( + time_bins, first_quar, second_quar, color=plot_args["color"], alpha=0.5, label="25%-75%" + ) + + # Plot formatting + ax.grid(plot_args["grid"]) + ax.set_ylabel( + plot_args["ylabel"] or "Cumulative event counts", fontsize=plot_args["ylabel_fontsize"] + ) + ax.set_title(plot_args["title"], fontsize=plot_args["title_fontsize"]) + + if plot_args["legend"]: + ax.legend(loc=plot_args["legend_loc"], fontsize=plot_args["legend_fontsize"]) + if plot_args["tight_layout"]: + fig.tight_layout() if show: pyplot.show() - return ax -def plot_magnitude_versus_time(catalog, filename=None, show=False, - reset_times=False, plot_args=None, **kwargs): +def plot_magnitude_histogram( + catalog_forecast: Union["CatalogForecast", List["CSEPCatalog"]], + observation: "CSEPCatalog", + magnitude_bins: Optional[Union[List[float], numpy.ndarray]] = None, + percentile: int = 95, + ax: Optional["matplotlib.axes.Axes"] = None, + show: bool = False, + **kwargs, +) -> matplotlib.axes.Axes: """ - Plots magnitude versus linear time for an earthquake data. - - Catalog class must implement get_magnitudes() and get_datetimes() in order for this function to work correctly. + Generates a semi-log magnitude histogram comparing a catalog-based forecast with observed + data. The forecast's median and uncertainty intervals are displayed along with the observed + event counts. Args: - catalog (:class:`~csep.core.catalogs.AbstractBaseCatalog`): data to visualize + catalog_forecast (CatalogForecast, List[CSEPCatalog]): A Catalog-based forecast + observation (CSEPCatalog): The observed catalog for comparison. + magnitude_bins (Optional[Union[List[float], numpy.ndarray]]): The bins for magnitude + histograms. If None, defaults to the region magnitudes or standard CSEP bins. + percentile (int): The percentile used for uncertainty intervals (default: 95). + ax (Optional[pyplot.Axes]): The axes object to draw the plot on. If None, a new + figure and axes are created. + show (bool): Whether to display the plot immediately (default: False). + **kwargs: Additional keyword arguments for plot customization. These override defaults. Returns: - (tuple): fig and axes handle + matplotlib.axes.Axes: The axes object containing the plot. """ - # get values from plotting args - plot_args = plot_args or {} - title = plot_args.get('title', '') - marker_size = plot_args.get('marker_size', 10) - color = plot_args.get('color', 'blue') - c = plot_args.get('c', None) - clabel = plot_args.get('clabel', None) - - print('Plotting magnitude versus time.') - fig = pyplot.figure(figsize=(8, 3)) - ax = fig.add_subplot(111) - - # get time in days - # plotting timestamps for now, until I can format dates on axis properly - f = lambda x: numpy.array(x.timestamp()) / SECONDS_PER_DAY - - # map returns a generator function which we collapse with list - days_elapsed = numpy.array(list(map(f, catalog.get_datetimes()))) - - if reset_times: - days_elapsed = days_elapsed - days_elapsed[0] - - magnitudes = catalog.get_magnitudes() - - # make plot - if c is not None: - h = ax.scatter(days_elapsed, magnitudes, marker='.', s=marker_size, - c=c, cmap=cm.get_cmap('jet'), **kwargs) - cbar = fig.colorbar(h) - cbar.set_label(clabel) - else: - ax.scatter(days_elapsed, magnitudes, marker='.', s=marker_size, - color=color, **kwargs) - - # do some labeling of the figure - ax.set_title(title, fontsize=16, color='black') - ax.set_xlabel('Days Elapsed') - ax.set_ylabel('Magnitude') - fig.tight_layout() - - # # annotate the plot with information from data - # if data is not None: - # try: - # ax.annotate(str(data), xycoords='axes fraction', xy=xycoords, fontsize=10, annotation_clip=False) - # except: - # pass - - # handle displaying of figures - if filename is not None: - fig.savefig(filename + '.pdf') - fig.savefig(filename + '.png', dpi=300) + # Initialize plot + plot_args = {**DEFAULT_PLOT_ARGS, **kwargs} + fig, ax = pyplot.subplots(figsize=plot_args["figsize"]) if ax is None else (ax.figure, ax) + + # Get magnitudes from observations and (lazily) from forecast + forecast_mws = list(map(lambda x: x.get_magnitudes(), catalog_forecast)) + obs_mw = observation.get_magnitudes() + n_obs = observation.get_number_of_events() + + # Get magnitude bins from args, if not from region, or lastly from standard CSEP bins. + if magnitude_bins is None: + try: + magnitude_bins = observation.region.magnitudes + except AttributeError: + magnitude_bins = CSEP_MW_BINS + + def get_histogram_synthetic_cat(x, mags, normed=True): + n_temp = len(x) + if normed and n_temp != 0: + temp_scale = n_obs / n_temp + hist = numpy.histogram(x, bins=mags)[0] * temp_scale + else: + hist = numpy.histogram(x, bins=mags)[0] + return hist + # get histogram values + forecast_hist = numpy.array( + list(map(lambda x: get_histogram_synthetic_cat(x, magnitude_bins), forecast_mws)) + ) + + obs_hist, bin_edges = numpy.histogram(obs_mw, bins=magnitude_bins) + bin_centers = (bin_edges[1:] + bin_edges[:-1]) / 2 + + # Compute statistics for the forecast histograms + forecast_median = numpy.median(forecast_hist, axis=0) + forecast_low = numpy.percentile(forecast_hist, (100 - percentile) / 2.0, axis=0) + forecast_high = numpy.percentile(forecast_hist, 100 - (100 - percentile) / 2.0, axis=0) + + forecast_err_lower = forecast_median - forecast_low + forecast_err_upper = forecast_high - forecast_median + + # Plot observed histogram + ax.semilogy( + bin_centers, + obs_hist, + color=plot_args["color"], + marker="o", + lw=0, + markersize=plot_args["markersize"], + label="Observation", + zorder=3, + ) + + # Plot forecast histograms as bar plot with error bars + ax.plot( + bin_centers, + forecast_median, + ".", + markersize=plot_args["markersize"], + color="darkred", + label="Forecast Median", + ) + ax.errorbar( + bin_centers, + forecast_median, + yerr=[forecast_err_lower, forecast_err_upper], + fmt="None", + color="darkred", + markersize=plot_args["markersize"], + capsize=plot_args["capsize"], + linewidth=plot_args["linewidth"], + label="Forecast (95% CI)", + ) + + # Scale x-axis + if plot_args["xlim"]: + ax.set_xlim(plot_args["xlim"]) + else: + ax = _autoscale_histogram( + ax, magnitude_bins, numpy.hstack(forecast_mws), obs_mw, mass=100 + ) + + # Format plot + ax.grid(plot_args["grid"]) + ax.legend(loc=plot_args["legend_loc"], fontsize=plot_args["legend_fontsize"]) + ax.set_xlabel(plot_args["xlabel"] or "Magnitude", fontsize=plot_args["xlabel_fontsize"]) + ax.set_ylabel(plot_args["ylabel"] or "Event count", fontsize=plot_args["ylabel_fontsize"]) + ax.set_title( + plot_args["title"] or "Magnitude Histogram", fontsize=plot_args["title_fontsize"] + ) + + if plot_args["tight_layout"]: + fig.tight_layout() if show: pyplot.show() return ax -def plot_histogram(simulated, observation, bins='fd', percentile=None, - show=False, axes=None, catalog=None, plot_args=None): +##################### +# Single Result plots +##################### +def plot_distribution_test( + evaluation_result: "EvaluationResult", + bins: Union[str, int, List[Any]] = "fd", + percentile: Optional[int] = 95, + ax: Optional[matplotlib.axes.Axes] = None, + auto_annotate: Union[bool, dict] = True, + sim_label: str = "Simulated", + obs_label: str = "Observation", + legend: bool = True, + show: bool = False, + **kwargs, +) -> matplotlib.axes.Axes: """ - Plots histogram of single statistic for stochastic event sets and observations. The function will behave differently - depending on the inumpyuts. - - Simulated should always be either a list or numpy.array where there would be one value per data in the stochastic event - set. Observation could either be a scalar or a numpy.array/list. If observation is a scale a vertical line would be - plotted, if observation is iterable a second histogram would be plotted. - - This allows for comparisons to be made against catalogs where there are multiple values e.g., magnitude, and single values - e.g., event count. - - If an axis handle is included, additional function calls will only addition extra simulations, observations will not be - plotted. Since this function returns an axes handle, any extra modifications to the figure can be made using that. + Plots a histogram of a single statistic for stochastic event sets and observations. Args: - simulated (numpy.arrays): numpy.array like representation of statistics computed from catalogs. - observation(numpy.array or scalar): observation to plot against stochastic event set - filename (str): filename to save figure - show (bool): show interactive version of the figure - ax (axis object): axis object with interface defined by matplotlib - catalog (csep.AbstractBaseCatalog): used for annotating the figures - plot_args (dict): additional plotting commands. TODO: Documentation + evaluation_result (EvaluationResult): Object containing test distributions and + observed statistics. + bins (Union[str, int], optional): Binning strategy for the histogram. Defaults + to 'fd'. + percentile (int, optional): Percentile for shading regions. Defaults to None + (use global setting). + ax (Optional[matplotlib.axes.Axes], optional): Axes object to plot on. If None, + creates a new figure and axes. + auto_annotate (bool, dict): If True, automatically format the plot details based + on the evaluation result. It can be customized by passing the keyword arguments + `xlabel`, `ylabel`, `annotation_text`, `annotation_xy` and `annotation_fontsize`. + sim_label (str, optional): Label for the simulated data. + obs_label (str, optional): Label for the observation data. + legend (Optional[bool], optional): Whether to display the legend. Defaults to + global setting. + show (bool, optional): If True, show the plot. Defaults to False. + **kwargs: Additional keyword arguments for plot customization. Returns: - axis: matplolib axes handle + matplotlib.axes.Axes: Matplotlib axes handle. """ - # Plotting - plot_args = plot_args or {} - chained = False - figsize = plot_args.get('figsize', None) - if axes is not None: - chained = True - ax = axes - else: - if catalog: - fig, ax = pyplot.subplots(figsize=figsize) - else: - fig, ax = pyplot.subplots() - - # parse plotting arguments - sim_label = plot_args.get('sim_label', 'Simulated') - obs_label = plot_args.get('obs_label', 'Observation') - xlabel = plot_args.get('xlabel', 'X') - ylabel = plot_args.get('ylabel', 'Frequency') - xycoords = plot_args.get('xycoords', (1.00, 0.40)) - title = plot_args.get('title', None) - legend_loc = plot_args.get('legend_loc', 'best') - legend = plot_args.get('legend', True) - bins = plot_args.get('bins', bins) - color = plot_args.get('color', '') - filename = plot_args.get('filename', None) - xlim = plot_args.get('xlim', None) - - # this could throw an error exposing bad implementation - observation = numpy.array(observation) - try: - n = len(observation) - except TypeError: - ax.axvline(x=observation, color='black', linestyle='--', - label=obs_label) + # Initialize plot + plot_args = {**DEFAULT_PLOT_ARGS, **kwargs} + fig, ax = pyplot.subplots(figsize=plot_args["figsize"]) if ax is None else (ax.figure, ax) - else: - # remove any nan values - observation = observation[~numpy.isnan(observation)] - ax.hist(observation, bins=bins, label=obs_label, edgecolor=None, - linewidth=0) + # Get distributions + simulated = evaluation_result.test_distribution + observation = evaluation_result.observed_statistic - # remove any potential nans from arrays + # Remove any potential nans from arrays simulated = numpy.array(simulated) simulated = simulated[~numpy.isnan(simulated)] - if color: - n, bin_edges, patches = ax.hist(simulated, bins=bins, label=sim_label, - color=color, edgecolor=None, - linewidth=0) + # Plot forecast statistic histogram + n, bin_edges, patches = ax.hist( + simulated, + bins=bins, + label=sim_label, + color=plot_args["color"], + alpha=plot_args["alpha"], + edgecolor=None, + linewidth=0, + ) + + # Plot observation statistic value/distribution + if isinstance(observation, (float, int)): + ax.axvline( + x=observation, + color="black", + linestyle="--", + label=obs_label + numpy.isinf(observation) * " (-inf)", + ) + else: + observation = observation[~numpy.isnan(observation)] + ax.hist( + observation, + bins=bins, + label=obs_label, + edgecolor=None, + linewidth=0, + alpha=plot_args["alpha"], + color="green", + ) + + # Annotate statistic analysis + ax = _annotate_distribution_plot(ax, evaluation_result, auto_annotate, plot_args) + + # Format axis object + if plot_args["xlim"] is None: + ax = _autoscale_histogram(ax, bin_edges, simulated, observation) else: - n, bin_edges, patches = ax.hist(simulated, bins=bins, label=sim_label, - edgecolor=None, linewidth=0) + ax.set_xlim(plot_args["xlim"]) + ax.grid(plot_args["grid"]) + + if legend: + ax.legend(loc=plot_args["legend_loc"], fontsize=plot_args["legend_fontsize"]) - # color bars for rejection area + # Color bars for rejection area (after setting legend) if percentile is not None: inc = (100 - percentile) / 2 inc_high = 100 - inc inc_low = inc + p_high = numpy.percentile(simulated, inc_high) idx_high = numpy.digitize(p_high, bin_edges) p_low = numpy.percentile(simulated, inc_low) idx_low = numpy.digitize(p_low, bin_edges) + for idx in range(idx_low): + patches[idx].set_fc("red") + for idx in range(idx_high, len(patches)): + patches[idx].set_fc("red") - # show 99.5% of data - if xlim is None: - upper_xlim = numpy.percentile(simulated, 99.75) - upper_xlim = numpy.max([upper_xlim, numpy.max(observation)]) - d_bin = bin_edges[1] - bin_edges[0] - upper_xlim = upper_xlim + 2 * d_bin + if plot_args["tight_layout"]: + fig.tight_layout() + if show: + pyplot.show() - lower_xlim = numpy.percentile(simulated, 0.25) - lower_xlim = numpy.min([lower_xlim, numpy.min(observation)]) - lower_xlim = lower_xlim - 2 * d_bin + return ax - try: - ax.set_xlim([lower_xlim, upper_xlim]) - except ValueError: - print('Ignoring observation in axis scaling because inf or -inf') - upper_xlim = numpy.percentile(simulated, 99.75) - upper_xlim = upper_xlim + 2 * d_bin - lower_xlim = numpy.percentile(simulated, 0.25) - lower_xlim = lower_xlim - 2 * d_bin +def plot_calibration_test( + evaluation_result: "EvaluationResult", + percentile: float = 95, + ax: Optional[matplotlib.axes.Axes] = None, + label: Optional[str] = None, + show: bool = False, + **kwargs, +) -> matplotlib.axes.Axes: + """ + Plots a calibration test (QQ plot) with confidence intervals. - ax.set_xlim([lower_xlim, upper_xlim]) - else: - ax.set_xlim(xlim) + Args: + evaluation_result (EvaluationResult): The evaluation result object containing the test distribution. + percentile (float): Percentile to build confidence interval + ax (Optional[matplotlib.axes.Axes]): Axes object to plot on. If None, creates a new figure. + show (bool): If True, displays the plot. Default is False. + label (Optional[str]): Label for the plotted data. If None, uses `evaluation_result.sim_name`. + **kwargs: Additional keyword arguments for customizing the plot. These are merged with + `DEFAULT_PLOT_ARGS`. - ax.set_title(title) - ax.set_xlabel(xlabel) - ax.set_ylabel(ylabel) - if legend: - ax.legend(loc=legend_loc) + Returns: + pyplot.Axes: The matplotlib axes object containing the plot. + """ + # Initialize plot + plot_args = {**DEFAULT_PLOT_ARGS, **kwargs} + fig, ax = pyplot.subplots(figsize=plot_args["figsize"]) if ax is None else (ax.figure, ax) - # hacky workaround for coloring legend, by calling after legend is drawn. - if percentile is not None: - for idx in range(idx_low): - patches[idx].set_fc('red') - for idx in range(idx_high, len(patches)): - patches[idx].set_fc('red') - if filename is not None: - ax.figure.savefig(filename + '.pdf') - ax.figure.savefig(filename + '.png', dpi=300) - if show: - pyplot.show() - return ax + # Set up QQ plots and KS test + n = len(evaluation_result.test_distribution) + k = numpy.arange(1, n + 1) + # Plotting points for uniform quantiles + pp = k / (n + 1) + # Compute confidence intervals for order statistics using beta distribution + inf = (100 - percentile) / 2 + sup = 100 - (100 - percentile) / 2 + ulow = scipy.stats.beta.ppf(inf / 100, k, n - k + 1) + uhigh = scipy.stats.beta.ppf(sup / 100, k, n - k + 1) + # Quantiles should be sorted for plotting + sorted_td = numpy.sort(evaluation_result.test_distribution) -def plot_ecdf(x, ecdf, axes=None, xv=None, show=False, plot_args=None): - """ Plots empirical cumulative distribution function. """ - plot_args = plot_args or {} - # get values from plotting args - sim_label = plot_args.get('sim_label', 'Simulated') - obs_label = plot_args.get('obs_label', 'Observation') - xlabel = plot_args.get('xlabel', 'X') - ylabel = plot_args.get('ylabel', '$P(X \leq x)$') - xycoords = plot_args.get('xycoords', (1.00, 0.40)) - legend_loc = plot_args.get('legend_loc', 'best') - filename = plot_args.get('filename', None) - - # make figure - if axes == None: + if ax is None: fig, ax = pyplot.subplots() else: - ax = axes - fig = axes.figure - ax.plot(x, ecdf, label=sim_label) - if xv: - ax.axvline(x=xv, color='black', linestyle='--', label=obs_label) - ax.set_xlabel(xlabel) - ax.set_ylabel(ylabel) - ax.legend(loc=legend_loc) - - # if data is not None: - # ax.annotate(str(data), xycoords='axes fraction', xy=xycoords, fontsize=10, annotation_clip=False) - - if filename is not None: - fig.savefig(filename + '.pdf') - fig.savefig(filename + '.png', dpi=300) - + ax = ax + + # Plot QQ plot + ax.plot( + sorted_td, + pp, + linewidth=0, + label=label or evaluation_result.sim_name, + c=plot_args["color"], + marker=plot_args["marker"], + markersize=plot_args["markersize"], + ) + + # Plot uncertainty on uniform quantiles + ax.plot(pp, pp, "-k") + ax.plot(ulow, pp, ":k") + ax.plot(uhigh, pp, ":k") + + # Format plot + ax.grid(plot_args["grid"]) + ax.set_title(plot_args["title"] or "Calibration test", fontsize=plot_args["title_fontsize"]) + ax.set_xlabel( + plot_args["xlabel"] or "Quantile scores", fontsize=plot_args["xlabel_fontsize"] + ) + ax.set_ylabel( + plot_args["ylabel"] or "Standard uniform quantiles", + fontsize=plot_args["ylabel_fontsize"], + ) + ax.legend(loc=plot_args["legend_loc"], fontsize=plot_args["legend_fontsize"]) + + if plot_args["tight_layout"]: + fig.tight_layout() if show: pyplot.show() return ax -def plot_magnitude_histogram_dev(ses_data, obs, plot_args, show=False): - bin_edges, obs_hist = obs.magnitude_counts(retbins=True) - n_obs = numpy.sum(obs_hist) - event_counts = numpy.sum(ses_data, axis=1) - # normalize all histograms by counts in each - scale = n_obs / event_counts - # use broadcasting - ses_data = ses_data * scale.reshape(-1, 1) - figsize = plot_args.get('figsize', None) - fig = pyplot.figure(figsize=figsize) - ax = fig.gca() - u3etas_median = numpy.median(ses_data, axis=0) - u3etas_low = numpy.percentile(ses_data, 2.5, axis=0) - u3etas_high = numpy.percentile(ses_data, 97.5, axis=0) - u3etas_min = numpy.min(ses_data, axis=0) - u3etas_max = numpy.max(ses_data, axis=0) - u3etas_emax = u3etas_max - u3etas_median - u3etas_emin = u3etas_median - u3etas_min - dmw = bin_edges[1] - bin_edges[0] - bin_edges_plot = bin_edges + dmw / 2 - - # u3etas_emax = u3etas_max - # plot 95% range as rectangles - rectangles = [] - for i in range(len(bin_edges)): - width = dmw / 2 - height = u3etas_high[i] - u3etas_low[i] - xi = bin_edges[i] + width / 2 - yi = u3etas_low[i] - rect = matplotlib.patches.Rectangle((xi, yi), width, height) - rectangles.append(rect) - pc = matplotlib.collections.PatchCollection(rectangles, facecolor='blue', - alpha=0.3, edgecolor='blue') - ax.add_collection(pc) - # plot whiskers - sim_label = plot_args.get('sim_label', 'Simulated Catalogs') - obs_label = plot_args.get('obs_label', 'Observed Catalog') - xlim = plot_args.get('xlim', None) - title = plot_args.get('title', "UCERF3-ETAS Histogram") - filename = plot_args.get('filename', None) - - ax.errorbar(bin_edges_plot, u3etas_median, yerr=[u3etas_emin, u3etas_emax], - xerr=0.8 * dmw / 2, fmt=' ', label=sim_label, - color='blue', alpha=0.7) - ax.plot(bin_edges_plot, obs_hist, '.k', markersize=10, label=obs_label) - ax.legend(loc='upper right') - ax.set_xlim(xlim) - ax.set_xlabel('Magnitude') - ax.set_ylabel('Event count per magnitude bin') - ax.set_title(title) - # ax.annotate(str(comcat), xycoords='axes fraction', xy=xycoords, fontsize=10, annotation_clip=False) - # pyplot.subplots_adjust(right=0.75) - if filename is not None: - fig.savefig(filename + '.pdf') - fig.savefig(filename + '.png', dpi=300) - if show: - pyplot.show() - return ax +##################### +# Results batch plots +##################### +def plot_comparison_test( + results_t: List["EvaluationResult"], + results_w: Optional[List["EvaluationResult"]] = None, + percentile: int = 95, + ax: Optional[matplotlib.axes.Axes] = None, + show: bool = False, + **kwargs, +) -> pyplot.Axes: + """ + Plots a list of T-Test (and optional W-Test) results on a single axis. + Args: + results_t (List[EvaluationResult]): List of T-Test results. + results_w (Optional[List[EvaluationResult]]): List of W-Test results. If provided, they + are plotted alongside the T-Test results. + percentile (int): Percentile for coloring W-Test results. Default is 95. + ax (Optional[matplotlib.axes.Axes]): Matplotlib axes object to plot on. If None, a new + figure and axes are created. + show (bool): If True, the plot is displayed after creation. Default is False. + **kwargs: Additional plotting arguments to override defaults. -def plot_magnitude_histogram(catalogs, comcat, show=True, plot_args=None): - """ Generates a magnitude histogram from a catalog-based forecast """ - # get list of magnitudes list of ndarray - plot_args = plot_args or {} - catalogs_mws = list(map(lambda x: x.get_magnitudes(), catalogs)) - obs_mw = comcat.get_magnitudes() - n_obs = comcat.get_number_of_events() + Returns: + pyplot.Axes: The matplotlib axes object containing the plot. + """ - # get histogram at arbitrary values - mws = CSEP_MW_BINS - dmw = mws[1] - mws[0] + # Initialize plot + plot_args = {**DEFAULT_PLOT_ARGS, **kwargs} + fig, ax = pyplot.subplots(figsize=plot_args["figsize"]) if ax is None else (ax.figure, ax) - def get_hist(x, mws, normed=True): - n_temp = len(x) - if normed and n_temp != 0: - temp_scale = n_obs / n_temp - hist = numpy.histogram(x, bins=mws)[0] * temp_scale - else: - hist = numpy.histogram(x, bins=mws)[0] - return hist + # Iterate through T-test results, or jointly through t- and w- test results + Results = zip(results_t, results_w) if results_w else zip(results_t) + for index, result in enumerate(Results): + result_t = result[0] + result_w = result[1] if results_w else None - # get hist values - u3etas_hist = numpy.array( - list(map(lambda x: get_hist(x, mws), catalogs_mws))) - obs_hist, bin_edges = numpy.histogram(obs_mw, bins=mws) - bin_edges_plot = (bin_edges[1:] + bin_edges[:-1]) / 2 - - figsize = plot_args.get('figsize', None) - fig = pyplot.figure(figsize=figsize) - ax = fig.gca() - u3etas_median = numpy.median(u3etas_hist, axis=0) - u3etas_low = numpy.percentile(u3etas_hist, 2.5, axis=0) - u3etas_high = numpy.percentile(u3etas_hist, 97.5, axis=0) - u3etas_min = numpy.min(u3etas_hist, axis=0) - u3etas_max = numpy.max(u3etas_hist, axis=0) - u3etas_emax = u3etas_max - u3etas_median - u3etas_emin = u3etas_median - u3etas_min - - # u3etas_emax = u3etas_max - # plot 95% range as rectangles - rectangles = [] - for i in range(len(mws) - 1): - width = dmw / 2 - height = u3etas_high[i] - u3etas_low[i] - xi = mws[i] + width / 2 - yi = u3etas_low[i] - rect = matplotlib.patches.Rectangle((xi, yi), width, height) - rectangles.append(rect) - pc = matplotlib.collections.PatchCollection(rectangles, facecolor='blue', - alpha=0.3, edgecolor='blue') - ax.add_collection(pc) - # plot whiskers - sim_label = plot_args.get('sim_label', 'Simulated Catalogs') - xlim = plot_args.get('xlim', None) - title = plot_args.get('title', "UCERF3-ETAS Histogram") - xycoords = plot_args.get('xycoords', (1.00, 0.40)) - filename = plot_args.get('filename', None) - - pyplot.errorbar(bin_edges_plot, u3etas_median, - yerr=[u3etas_emin, u3etas_emax], xerr=0.8 * dmw / 2, - fmt=' ', - label=sim_label, color='blue', alpha=0.7) - pyplot.plot(bin_edges_plot, obs_hist, '.k', markersize=10, label='Comcat') - pyplot.legend(loc='upper right') - pyplot.xlim(xlim) - pyplot.xlabel('Mw') - pyplot.ylabel('Count') - pyplot.title(title) - # ax.annotate(str(comcat), xycoords='axes fraction', xy=xycoords, fontsize=10, annotation_clip=False) - pyplot.subplots_adjust(right=0.75) - if filename is not None: - fig.savefig(filename + '.pdf') - fig.savefig(filename + '.png', dpi=300) - if show: - pyplot.show() + # Get confidence bounds + ylow = result_t.observed_statistic - result_t.test_distribution[0] + yhigh = result_t.test_distribution[1] - result_t.observed_statistic + color = _get_marker_t_color(result_t.test_distribution) + if not numpy.isinf(result_t.observed_statistic): + # Plot observed statistic and confidence bounds + ax.errorbar( + index, + result_t.observed_statistic, + yerr=numpy.array([[ylow, yhigh]]).T, + color=color, + linewidth=plot_args["linewidth"], + capsize=plot_args["capsize"], + ) + + facecolor = "white" + if result_w is not None: + if _get_marker_w_color(result_w.quantile, percentile): + facecolor = _get_marker_t_color(result_t.test_distribution) -def plot_basemap(basemap, extent, ax=None, figsize=None, coastline=True, - borders=False, tile_scaling='auto', - set_global=False, projection=ccrs.PlateCarree(), apprx=False, - central_latitude=0.0, - linecolor='black', linewidth=True, - grid=False, grid_labels=False, grid_fontsize=None, - show=False): - """ Wrapper function for multiple cartopy base plots, including access to standard raster webservices - - Args: - basemap (str): Possible values are: stock_img, stamen_terrain, stamen_terrain-background, google-satellite, ESRI_terrain, ESRI_imagery, ESRI_relief, ESRI_topo, ESRI_terrain, or webservice link (see examples in :func:`csep.utils.plots._get_basemap`. Default is None - extent (list): [lon_min, lon_max, lat_min, lat_max] - ax (:class:`matplotlib.pyplot.ax`): Previously defined ax object - figsize (tuple): If no ax is provided, a tuple of floats can be provided to define figure size - coastline (str): Flag to plot coastline. default True, - borders (bool): Flag to plot country borders. default False, - tile_scaling (str/int): Zoom level (1-12) of the basemap tiles. If 'auto', is automatically derived from extent - set_global (bool): Display the complete globe as basemap - projection (:class:`cartopy.crs.Projection`): Projection to be used in the basemap - apprx (bool): If true, approximates transformation by setting aspect ratio of axes based on middle latitude - central_latitude (float): average latitude from plotting region - linecolor (str): Color of borders and coast lines. default 'black', - linewidth (float): Line width of borders and coast lines. default 1.5, - grid (bool): Draws a grid in the basemap - grid_labels (bool): Annotate grid values - grid_fontsize (float): Font size of the grid x and y labels - show (bool): Flag if the figure is displayed - - Returns: - :class:`matplotlib.pyplot.ax` object - - """ - if ax is None: - if apprx: - projection = ccrs.PlateCarree() - fig = pyplot.figure(figsize=figsize) - ax = fig.add_subplot(111, projection=projection) - # Set plot aspect according to local longitude-latitude ratio in metric units - # (only compatible with plain PlateCarree "projection") - LATKM = 110.574 # length of a ° of latitude [km]; constant --> ignores Earth's flattening - ax.set_aspect( - LATKM / (111.320 * numpy.cos(numpy.deg2rad(central_latitude)))) + ax.plot( + index, + result_t.observed_statistic, + marker="o", + markerfacecolor=facecolor, + markeredgecolor=color, + markersize=plot_args["markersize"], + ) else: - fig = pyplot.figure(figsize=figsize) - ax = fig.add_subplot(111, projection=projection) - - if set_global: - ax.set_global() - else: - ax.set_extent(extents=extent, crs=ccrs.PlateCarree()) + print( + f"Diverging information gain for forecast {result_t.sim_name}, index {index}. " + f"Check for zero-valued bins within the forecast" + ) + ax.axvspan(index - 0.5, index + 0.5, alpha=0.5, facecolor="red") + + # Format plot + ax.axhline(y=0, linestyle="--", color="black") + ax.set_xticks(numpy.arange(len(results_t))) + ax.set_xticklabels( + [res.sim_name[0] for res in results_t], + rotation=90, + fontsize=plot_args["xlabel_fontsize"], + ) + ax.set_ylabel( + plot_args["ylabel"] or "Information gain per earthquake", + fontsize=plot_args["ylabel_fontsize"], + ) + + ax.set_title(plot_args["title"] or results_t[0].name) + ax.set_ylim(plot_args["ylim"]) + ax.set_xlim([-0.5, len(results_t) - 0.5]) - try: - # Set adaptive scaling - line_autoscaler = cartopy.feature.AdaptiveScaler('110m', ( - ('50m', 50), ('10m', 5))) - tile_autoscaler = cartopy.feature.AdaptiveScaler(5, ((6, 50), (7, 15))) - tiles = None - # Set tile depth - if tile_scaling == 'auto': - tile_depth = 4 if set_global else tile_autoscaler.scale_from_extent( - extent) - else: - tile_depth = tile_scaling - if coastline: - ax.coastlines(color=linecolor, linewidth=linewidth) - if borders: - borders = cartopy.feature.NaturalEarthFeature('cultural', - 'admin_0_boundary_lines_land', - line_autoscaler, - edgecolor=linecolor, - facecolor='never') - ax.add_feature(borders, linewidth=linewidth) - if basemap == 'stock_img': - ax.stock_img() - elif basemap is not None: - tiles = _get_basemap(basemap) - if tiles: - ax.add_image(tiles, tile_depth) - except: - print( - "Unable to plot basemap. This might be due to no internet access, try pre-downloading the files.") - - # Gridline options - if grid: - gl = ax.gridlines(draw_labels=grid_labels, alpha=0.5) - gl.right_labels = False - gl.top_labels = False - gl.xlabel_style['fontsize'] = grid_fontsize - gl.ylabel_style['fontsize'] = grid_fontsize - gl.xformatter = LONGITUDE_FORMATTER - gl.yformatter = LATITUDE_FORMATTER + if plot_args["grid"]: + ax.yaxis.grid() + ax.yaxis.set_major_locator(pyplot.MaxNLocator(integer=True)) + + if plot_args["hbars"]: + if len(results_t) > 2: + ax.bar( + ax.get_xticks(), + numpy.array([9999] * len(ax.get_xticks())), + bottom=-2000, + width=(ax.get_xticks()[1] - ax.get_xticks()[0]), + color=["gray", "w"], + alpha=0.2, + ) + + if plot_args["legend"]: + # Add custom legend to explain results + legend_elements = [ + Line2D([0], [0], color="red", lw=2, label="T-test rejected"), + Line2D([0], [0], color="green", lw=2, label="T-test non-rejected"), + Line2D([0], [0], color="gray", lw=2, label="T-test indistinguishable"), + Line2D( + [0], + [0], + color="gray", + lw=2, + marker="o", + markersize=6, + markerfacecolor="green", + label="W-test non-rejected", + ), + Line2D( + [0], + [0], + color="gray", + lw=2, + marker="o", + markersize=6, + markerfacecolor="white", + label="W-test indistinguishable", + ), + ] + ax.legend(handles=legend_elements, loc="best", fontsize=plot_args["legend_fontsize"]) + + if plot_args["tight_layout"]: + fig.tight_layout() if show: pyplot.show() @@ -686,865 +794,706 @@ def plot_basemap(basemap, extent, ax=None, figsize=None, coastline=True, return ax -def plot_catalog(catalog, ax=None, show=False, extent=None, set_global=False, - plot_args=None): - """ Plot catalog in a region +def plot_consistency_test( + eval_results: Union[List["EvaluationResult"], "EvaluationResult"], + normalize: bool = False, + one_sided_lower: bool = False, + percentile: float = 95, + variance: Optional[float] = None, + ax: Optional[pyplot.Axes] = None, + plot_mean: bool = False, + color: str = "black", + show: bool = False, + **kwargs, +) -> matplotlib.axes.Axes: + """ + Plots the results from ultiple consistency tests. The distribution of score results from + multiple realizations of a model are plotted as a line representing for a given percentile. + The score of the observation under a model is plotted as a marker. The model is assumed + inconsistent when the observation score lies outside from the model distribution for a + two-sided test, or lies to the right of the distribution for a one-sided test. Args: - catalog (:class:`CSEPCatalog`): Catalog object to be plotted - ax (:class:`matplotlib.pyplot.ax`): Previously defined ax object (e.g from plot_spatial_dataset) - show (bool): Flag if the figure is displayed - extent (list): default 1.05-:func:`catalog.region.get_bbox()` - set_global (bool): Display the complete globe as basemap - plot_args (dict): matplotlib and cartopy plot arguments. The dictionary keys are str, whose items can be: - - - :figsize: :class:`tuple`/:class:`list` - default [6.4, 4.8] - - :title: :class:`str` - default :class:`catalog.name` - - :title_size: :class:`int` - default 10 - - :filename: :class:`str` - File to save figure. default None - - :projection: :class:`cartopy.crs.Projection` - default :class:`cartopy.crs.PlateCarree`. Note: this can be - 'fast' to apply an approximate transformation of axes. - - :basemap: :class:`str`/:class:`None`. Possible values are: stock_img, stamen_terrain, stamen_terrain-background, google-satellite, ESRI_terrain, ESRI_imagery, ESRI_relief, ESRI_topo, ESRI_terrain, or webservice link. Default is None - - :coastline: :class:`bool` - Flag to plot coastline. default True, - - :grid: :class:`bool` - default True - - :grid_labels: :class:`bool` - default True - - :grid_fontsize: :class:`float` - default 10.0 - - :marker: :class:`str` - Marker type - - :markersize: :class:`float` - Constant size for all earthquakes - - :markercolor: :class:`str` - Color for all earthquakes - - :borders: :class:`bool` - Flag to plot country borders. default False, - - :region_border: :class:`bool` - Flag to plot the catalog region border. default True, - - :alpha: :class:`float` - Transparency for the earthquakes scatter - - :mag_scale: :class:`float` - Scaling of the scatter - - :legend: :class:`bool` - Flag to display the legend box - - :legend_loc: :class:`int`/:class:`str` - Position of the legend - - :mag_ticks: :class:`list` - Ticks to display in the legend - - :labelspacing: :class:`int` - Separation between legend ticks - - :tile_scaling: :class:`str`/:class:`int`. Zoom level (1-12) of the basemap tiles. If 'auto', is automatically derived from extent - - :linewidth: :class:`float` - Line width of borders and coast lines. default 1.5, - - :linecolor: :class:`str` - Color of borders and coast lines. default 'black', + eval_results (Union[List[EvaluationResult], EvaluationResult]): + Evaluation results from one or multiple models + normalize (bool): + Normalize the forecast likelihood by observed likelihood (default: False). + percentile (float): + Percentile for the extent of the model score distribution (default: 95). + one_sided_lower (bool): + Plot for a one-sided test (default: False). + variance (Optional[float]): + Variance for negative binomial distribution (default: None). + ax (Optional[pyplot.Axes]): + Axes object to plot on (default: None). + plot_mean (bool): + Plot the mean of the test distribution (default: False). + color (str): + Color for the line representing a model score distribution (default: 'black'). + show (bool): + If True, display the plot (default: False). + **kwargs: + Additional keyword arguments for plot customization from DEFAULT_PLOT_ARGS. Returns: - :class:`matplotlib.pyplot.ax` object - + matplotlib.axes.Axes: Matplotlib axes object with the consistency test plot. """ - # Get spatial information for plotting - # Retrieve plot arguments - plot_args = plot_args or {} - # figure and axes properties - figsize = plot_args.get('figsize', None) - title = plot_args.get('title', catalog.name) - title_size = plot_args.get('title_size', None) - filename = plot_args.get('filename', None) - # scatter properties - markersize = plot_args.get('markersize', 2) - markercolor = plot_args.get('markercolor', 'blue') - markeredgecolor = plot_args.get('markeredgecolor', 'black') - alpha = plot_args.get('alpha', 1) - mag_scale = plot_args.get('mag_scale', 1) - legend = plot_args.get('legend', False) - legend_title = plot_args.get('legend_title', r"Magnitudes") - legend_loc = plot_args.get('legend_loc', 1) - legend_framealpha = plot_args.get('legend_framealpha', None) - legend_fontsize = plot_args.get('legend_fontsize', None) - legend_titlesize = plot_args.get('legend_titlesize', None) - mag_ticks = plot_args.get('mag_ticks', False) - labelspacing = plot_args.get('labelspacing', 1) - region_border = plot_args.get('region_border', True) - legend_borderpad = plot_args.get('legend_borderpad', 0.4) - # cartopy properties - projection = plot_args.get('projection', - ccrs.PlateCarree(central_longitude=0.0)) - basemap = plot_args.get('basemap', None) - coastline = plot_args.get('coastline', True) - grid = plot_args.get('grid', True) - grid_labels = plot_args.get('grid_labels', False) - grid_fontsize = plot_args.get('grid_fontsize', False) - borders = plot_args.get('borders', False) - tile_scaling = plot_args.get('tile_scaling', 'auto') - linewidth = plot_args.get('linewidth', True) - linecolor = plot_args.get('linecolor', 'black') - - bbox = catalog.get_bbox() - if region_border: - try: - bbox = catalog.region.get_bbox() - except AttributeError: - pass + # Initialize plot + plot_args = {**DEFAULT_PLOT_ARGS, **kwargs} + fig, ax = pyplot.subplots(figsize=plot_args["figsize"]) if ax is None else (ax.figure, ax) - if extent is None and not set_global: - dh = (bbox[1] - bbox[0]) / 20. - dv = (bbox[3] - bbox[2]) / 20. - extent = [bbox[0] - dh, bbox[1] + dh, bbox[2] - dv, bbox[3] + dv] + # Ensure eval_results is a list + results = list(eval_results) if isinstance(eval_results, list) else [eval_results] + results.reverse() - apprx = False - central_latitude = 0.0 - if projection == 'fast': - projection = ccrs.PlateCarree() - apprx = True - n_lats = len(catalog.region.ys) // 2 - central_latitude = catalog.region.ys[n_lats] + xlims = [] - # Instantiage GeoAxes object - if ax is None: - fig = pyplot.figure(figsize=figsize) - ax = fig.add_subplot(111, projection=projection) + for index, res in enumerate(results): + plow, phigh, mean, observed_statistic = _process_stat_distribution( + res, percentile, variance, normalize, one_sided_lower + ) + + if not numpy.isinf(observed_statistic): # Check if test result does not diverge + percentile_lims = numpy.abs(numpy.array([[mean - plow, phigh - mean]]).T) + ax.plot( + observed_statistic, + index, + _get_marker_style(observed_statistic, (plow, phigh), one_sided_lower), + ) + ax.errorbar( + mean, + index, + xerr=percentile_lims, + fmt="ko" if plot_mean else "k", + capsize=plot_args["capsize"], + linewidth=plot_args["linewidth"], + ecolor=color, + ) + # Determine the limits to use + xlims.append((plow, phigh, observed_statistic)) - if set_global: - ax.set_global() - region_border = False - else: - ax.set_extent(extents=extent, - crs=ccrs.PlateCarree()) # Defined extent always in lat/lon - - # Basemap plotting - ax = plot_basemap(basemap, extent, ax=ax, coastline=coastline, - borders=borders, tile_scaling=tile_scaling, - linecolor=linecolor, linewidth=linewidth, - projection=projection, apprx=apprx, - central_latitude=central_latitude, set_global=set_global) - - # Scaling function - mw_range = [min(catalog.get_magnitudes()), max(catalog.get_magnitudes())] - - def size_map(markersize, values, scale): - if isinstance(mag_scale, (int, float)): - return (markersize / (scale ** mw_range[0]) * numpy.power(values, - scale)) - elif isinstance(scale, (numpy.ndarray, list)): - return scale + # Extend distribution to +inf, in case it is a one-sided test + if one_sided_lower and observed_statistic >= plow and phigh < observed_statistic: + xt = numpy.linspace(phigh, 99999, 100) + yt = numpy.ones(100) * index + ax.plot(xt, yt, linestyle="--", linewidth=plot_args["linewidth"], color=color) else: - raise ValueError('scale data type not supported') - - ## Plot catalog - scatter = ax.scatter(catalog.get_longitudes(), catalog.get_latitudes(), - s=size_map(markersize, catalog.get_magnitudes(), - mag_scale), - transform=cartopy.crs.PlateCarree(), - color=markercolor, - edgecolors=markeredgecolor, - alpha=alpha) + print( + f"Observed statistic diverges for forecast {res.sim_name}, index {index}. " + f"Check for zero-valued bins within the forecast" + ) + ax.barh(index, 99999, left=-10000, height=1, color=["red"], alpha=0.5) - # Legend - if legend: - if isinstance(mag_ticks, (tuple, list, numpy.ndarray)): - if not numpy.all([i >= mw_range[0] and i <= mw_range[1] for i in - mag_ticks]): - print( - "Magnitude ticks do not lie within the catalog magnitude range") - elif mag_ticks is False: - mag_ticks = numpy.linspace(mw_range[0], mw_range[1], 4) - handles, labels = scatter.legend_elements(prop="sizes", - num=list(size_map(markersize, - mag_ticks, - mag_scale)), - alpha=0.3) - ax.legend(handles, numpy.round(mag_ticks, 1), - loc=legend_loc, title=legend_title, fontsize=legend_fontsize, - title_fontsize=legend_titlesize, - labelspacing=labelspacing, handletextpad=5, - borderpad=legend_borderpad, framealpha=legend_framealpha) + # Plot formatting + try: + ax.set_xlim(*_get_axis_limits(xlims)) + except ValueError: + raise ValueError("All EvaluationResults have infinite observed_statistics") + ax.set_ylim([-0.5, len(results) - 0.5]) + ax.set_yticks(numpy.arange(len(results))) + ax.set_yticklabels([res.sim_name for res in results], fontsize=plot_args["ylabel_fontsize"]) + ax.set_xlabel( + plot_args["xlabel"] or "Statistic distribution", fontsize=plot_args["xlabel_fontsize"] + ) + ax.tick_params(axis="x", labelsize=plot_args["xticks_fontsize"]) + ax.set_title(plot_args["title"], fontsize=plot_args["title_fontsize"]) + if plot_args["hbars"]: + yTickPos = ax.get_yticks() + if len(yTickPos) >= 2: + ax.barh( + yTickPos, + numpy.array([99999] * len(yTickPos)), + left=-10000, + height=(yTickPos[1] - yTickPos[0]), + color=["w", "gray"], + alpha=0.2, + zorder=0, + ) + if plot_args["tight_layout"]: + fig.tight_layout() - if region_border: - try: - pts = catalog.region.tight_bbox() - ax.plot(pts[:, 0], pts[:, 1], lw=1, color='black') - except AttributeError: - pass - # print("unable to get tight bbox") - - # Gridline options - if grid: - gl = ax.gridlines(draw_labels=grid_labels, alpha=0.5) - gl.right_labels = False - gl.top_labels = False - gl.xlabel_style['fontsize'] = grid_fontsize - gl.ylabel_style['fontsize'] = grid_fontsize - gl.xformatter = LONGITUDE_FORMATTER - gl.yformatter = LATITUDE_FORMATTER - - # Figure options - ax.set_title(title, fontsize=title_size, y=1.06) - if filename is not None: - ax.get_figure().savefig(filename + '.pdf') - ax.get_figure().savefig(filename + '.png', dpi=300) if show: pyplot.show() return ax -def plot_spatial_dataset(gridded, region, ax=None, show=False, extent=None, - set_global=False, plot_args=None): - """ Plot spatial dataset such as data from a gridded forecast +################### +# Alarm-based plots +################### +def plot_concentration_ROC_diagram( + forecast, + catalog, + linear=True, + axes=None, + plot_uniform=True, + show=True, + figsize=(9, 8), + forecast_linecolor="black", + forecast_linestyle="-", + observed_linecolor="blue", + observed_linestyle="-", + legend_fontsize=16, + legend_loc="upper left", + title_fontsize=18, + label_fontsize=14, + title="Concentration ROC Curve", +): + if not catalog.region == forecast.region: + raise RuntimeError("catalog region and forecast region must be identical.") - Args: - gridded (2D :class:`numpy.array`): Values according to `region`, - region (:class:`CartesianGrid2D`): Region in which gridded values are contained - show (bool): Flag if the figure is displayed - extent (list): default :func:`forecast.region.get_bbox()` - set_global (bool): Display the complete globe as basemap - plot_args (dict): matplotlib and cartopy plot arguments. Dict keys are str, whose values can be: - - - :figsize: :class:`tuple`/:class:`list` - default [6.4, 4.8] - - :title: :class:`str` - default None - - :title_size: :class:`int` - default 10 - - :filename: :class:`str` - default None - - :projection: :class:`cartopy.crs.Projection` - default :class:`cartopy.crs.PlateCarree` - - :grid: :class:`bool` - default True - - :grid_labels: :class:`bool` - default True - - :grid_fontsize: :class:`float` - default 10.0 - - :basemap: :class:`str`. Possible values are: stock_img, stamen_terrain, stamen_terrain-background, google-satellite, ESRI_terrain, ESRI_imagery, ESRI_relief, ESRI_topo, ESRI_terrain, or webservice link. Default is None - - :coastline: :class:`bool` - Flag to plot coastline. default True, - - :borders: :class:`bool` - Flag to plot country borders. default False, - - :region_border: :class:`bool` - Flag to plot the dataset region border. default True, - - :tile_scaling: :class:`str`/:class:`int`. Zoom level (1-12) of the basemap tiles. If 'auto', is automatically derived from extent - - :linewidth: :class:`float` - Line width of borders and coast lines. default 1.5, - - :linecolor: :class:`str` - Color of borders and coast lines. default 'black', - - :cmap: :class:`str`/:class:`pyplot.colors.Colormap` - default 'viridis' - - :clim: :class:`list` - Range of the colorbar. default None - - :clabel: :class:`str` - Label of the colorbar. default None - - :clabel_fontsize: :class:`float` - default None - - :cticks_fontsize: :class:`float` - default None - - :alpha: :class:`float` - default 1 - - :alpha_exp: :class:`float` - Exponent for the alpha func (recommended between 0.4 and 1). default 0 + name = forecast.name + forecast_label = f"Forecast {name}" if name else "Forecast" + observed_label = f"Observed {name}" if name else "Observed" + # Initialize figure + if axes is not None: + ax = axes + else: + fig, ax = pyplot.subplots(figsize=figsize) - Returns: - :class:`matplotlib.pyplot.ax` object + area_km2 = catalog.region.get_cell_area() + obs_counts = catalog.spatial_counts() + rate = forecast.spatial_counts() + I = numpy.argsort(rate) + I = numpy.flip(I) - """ - # Get spatial information for plotting - bbox = region.get_bbox() - if extent is None and not set_global: - extent = [bbox[0], bbox[1], bbox[2], bbox[3]] - - # Retrieve plot arguments - plot_args = plot_args or {} - # figure and axes properties - figsize = plot_args.get('figsize', None) - title = plot_args.get('title', None) - title_size = plot_args.get('title_size', None) - filename = plot_args.get('filename', None) - # cartopy properties - projection = plot_args.get('projection', - ccrs.PlateCarree(central_longitude=0.0)) - grid = plot_args.get('grid', True) - grid_labels = plot_args.get('grid_labels', False) - grid_fontsize = plot_args.get('grid_fontsize', False) - basemap = plot_args.get('basemap', None) - coastline = plot_args.get('coastline', True) - borders = plot_args.get('borders', False) - tile_scaling = plot_args.get('tile_scaling', 'auto') - linewidth = plot_args.get('linewidth', True) - linecolor = plot_args.get('linecolor', 'black') - region_border = plot_args.get('region_border', True) - # color bar properties - include_cbar = plot_args.get('include_cbar', True) - cmap = plot_args.get('cmap', None) - clim = plot_args.get('clim', None) - clabel = plot_args.get('clabel', None) - clabel_fontsize = plot_args.get('clabel_fontsize', None) - cticks_fontsize = plot_args.get('cticks_fontsize', None) - alpha = plot_args.get('alpha', 1) - alpha_exp = plot_args.get('alpha_exp', 0) - - apprx = False - central_latitude = 0.0 - if projection == 'fast': - projection = ccrs.PlateCarree() - apprx = True - n_lats = len(region.ys) // 2 - central_latitude = region.ys[n_lats] + fore_norm_sorted = numpy.cumsum(rate[I]) / numpy.sum(rate) + area_norm_sorted = numpy.cumsum(area_km2[I]) / numpy.sum(area_km2) + obs_norm_sorted = numpy.cumsum(obs_counts[I]) / numpy.sum(obs_counts) - # Instantiate GeoAxes object - if ax is None: - fig = pyplot.figure(figsize=figsize) - ax = fig.add_subplot(111, projection=projection) - else: - fig = ax.get_figure() + if plot_uniform: + ax.plot(area_norm_sorted, area_norm_sorted, "k--", label="Uniform") + + ax.plot( + area_norm_sorted, + fore_norm_sorted, + label=forecast_label, + color=forecast_linecolor, + linestyle=forecast_linestyle, + ) + + ax.step( + area_norm_sorted, + obs_norm_sorted, + label=observed_label, + color=observed_linecolor, + linestyle=observed_linestyle, + ) - if set_global: - ax.set_global() - region_border = False - else: - ax.set_extent(extents=extent, - crs=ccrs.PlateCarree()) # Defined extent always in lat/lon - - # Basemap plotting - ax = plot_basemap(basemap, extent, ax=ax, coastline=coastline, - borders=borders, - linecolor=linecolor, linewidth=linewidth, - projection=projection, apprx=apprx, - central_latitude=central_latitude, - tile_scaling=tile_scaling, set_global=set_global) - - ## Define colormap and transparency function - if isinstance(cmap, str) or not cmap: - cmap = pyplot.get_cmap(cmap) - cmap_tup = cmap(numpy.arange(cmap.N)) - if isinstance(alpha_exp, (float, int)): - if alpha_exp != 0: - cmap_tup[:, -1] = numpy.linspace(0, 1, cmap.N) ** alpha_exp - alpha = None - cmap = matplotlib.colors.ListedColormap(cmap_tup) + ax.set_ylabel("True Positive Rate", fontsize=label_fontsize) + ax.set_xlabel("False Positive Rate (Normalized Area)", fontsize=label_fontsize) - ## Plot spatial dataset - lons, lats = numpy.meshgrid(numpy.append(region.xs, bbox[1]), - numpy.append(region.ys, bbox[3])) - im = ax.pcolor(lons, lats, gridded, cmap=cmap, alpha=alpha, snap=True, - transform=ccrs.PlateCarree()) - im.set_clim(clim) + if not linear: + ax.set_xscale("log") - # Colorbar options - # create an axes on the right side of ax. The width of cax will be 5% - # of ax and the padding between cax and ax will be fixed at 0.05 inch. - if include_cbar: - cax = fig.add_axes( - [ax.get_position().x1 + 0.01, ax.get_position().y0, 0.025, - ax.get_position().height], - label='Colorbar') - cbar = fig.colorbar(im, ax=ax, cax=cax) - cbar.set_label(clabel, fontsize=clabel_fontsize) - cbar.ax.tick_params(labelsize=cticks_fontsize) - - # Gridline options - if grid: - gl = ax.gridlines(draw_labels=grid_labels, alpha=0.5) - gl.right_labels = False - gl.top_labels = False - gl.xlabel_style['fontsize'] = grid_fontsize - gl.ylabel_style['fontsize'] = grid_fontsize - gl.xformatter = LONGITUDE_FORMATTER - gl.yformatter = LATITUDE_FORMATTER + ax.legend(loc=legend_loc, shadow=True, fontsize=legend_fontsize) + ax.set_title(title, fontsize=title_fontsize) - if region_border: - pts = region.tight_bbox() - ax.plot(pts[:, 0], pts[:, 1], lw=1, color='black', - transform=ccrs.PlateCarree()) - - # matplotlib figure options - ax.set_title(title, y=1.06, fontsize=title_size) - if filename is not None: - ax.get_figure().savefig(filename + '.pdf') - ax.get_figure().savefig(filename + '.png', dpi=300) if show: pyplot.show() return ax -def plot_number_test(evaluation_result, axes=None, show=True, plot_args=None): - """ - Takes result from evaluation and generates a specific histogram plot to show the results of the statistical evaluation - for the n-test. +def plot_ROC_diagram( + forecast, + catalog, + linear=True, + axes=None, + plot_uniform=True, + show=True, + figsize=(9, 8), + forecast_linestyle="-", + legend_fontsize=16, + legend_loc="upper left", + title_fontsize=16, + label_fontsize=14, + title="ROC Curve from contingency table", +): + if not catalog.region == forecast.region: + raise RuntimeError("catalog region and forecast region must be identical.") - Args: - evaluation_result: object-like var that implements the interface of the above EvaluationResult - axes (matplotlib.Axes): axes object used to chain this plot - show (bool): if true, call pyplot.show() - plot_args(dict): optional argument containing a dictionary of plotting arguments, with keys as strings and items as described below - - Optional plotting arguments: - * figsize: (:class:`list`/:class:`tuple`) - default: [6.4, 4.8] - * title: (:class:`str`) - default: name of the first evaluation result type - * title_fontsize: (:class:`float`) Fontsize of the plot title - default: 10 - * xlabel: (:class:`str`) - default: 'X' - * xlabel_fontsize: (:class:`float`) - default: 10 - * xticks_fontsize: (:class:`float`) - default: 10 - * ylabel_fontsize: (:class:`float`) - default: 10 - * text_fontsize: (:class:`float`) - default: 14 - * tight_layout: (:class:`bool`) Set matplotlib.figure.tight_layout to remove excess blank space in the plot - default: True - * percentile (:class:`float`) Critial region to shade on histogram - default: 95 - * bins: (:class:`str`) - Set binning type. see matplotlib.hist for more info - default: 'auto' - * xy: (:class:`list`/:class:`tuple`) - default: (0.55, 0.3) + if axes is not None: + ax = axes + else: + fig, ax = pyplot.subplots(figsize=figsize) - Returns: - ax (matplotlib.axes.Axes): can be used to modify the figure + rate = forecast.spatial_counts() + obs_counts = catalog.spatial_counts() - """ + I = numpy.argsort(rate) + I = numpy.flip(I) - # chain plotting axes if requested - if axes: - chained = True - else: - chained = False - - # default plotting arguments - plot_args = plot_args or {} - title = plot_args.get('title', 'Number Test') - title_fontsize = plot_args.get('title_fontsize', None) - xlabel = plot_args.get('xlabel', 'Event count of catalogs') - xlabel_fontsize = plot_args.get('xlabel_fontsize', None) - ylabel = plot_args.get('ylabel', 'Number of catalogs') - ylabel_fontsize = plot_args.get('ylabel_fontsize', None) - text_fontsize = plot_args.get('text_fontsize', 14) - tight_layout = plot_args.get('tight_layout', True) - percentile = plot_args.get('percentile', 95) - filename = plot_args.get('filename', None) - bins = plot_args.get('bins', 'auto') - xy = plot_args.get('xy', (0.5, 0.3)) - - # set default plotting arguments - fixed_plot_args = {'obs_label': evaluation_result.obs_name, - 'sim_label': evaluation_result.sim_name} - plot_args.update(fixed_plot_args) - ax = plot_histogram(evaluation_result.test_distribution, - evaluation_result.observed_statistic, - catalog=evaluation_result.obs_catalog_repr, - plot_args=plot_args, - bins=bins, - axes=axes, - percentile=percentile) - - # annotate plot with p-values - if not chained: - try: - ax.annotate( - '$\delta_1 = P(X \geq x) = {:.2f}$\n$\delta_2 = P(X \leq x) = {:.2f}$\n$\omega = {:d}$' - .format(*evaluation_result.quantile, - evaluation_result.observed_statistic), - xycoords='axes fraction', - xy=xy, - fontsize=text_fontsize) - except: - ax.annotate('$\gamma = P(X \leq x) = {:.2f}$\n$\omega = {:.2f}$' - .format(evaluation_result.quantile, - evaluation_result.observed_statistic), - xycoords='axes fraction', - xy=xy, - fontsize=text_fontsize) + thresholds = (rate[I]) / numpy.sum(rate) + obs_counts = obs_counts[I] - ax.set_title(title, fontsize=title_fontsize) - ax.set_xlabel(xlabel, fontsize=xlabel_fontsize) - ax.set_ylabel(ylabel, fontsize=ylabel_fontsize) + Table_ROC = pandas.DataFrame({"Threshold": [], "H": [], "F": []}) - if tight_layout: - ax.figure.tight_layout() + for threshold in thresholds: + threshold = float(threshold) + + binary_forecast = numpy.where(thresholds >= threshold, 1, 0) + forecastedYes_observedYes = obs_counts[(binary_forecast == 1) & (obs_counts > 0)] + forecastedYes_observedNo = obs_counts[(binary_forecast == 1) & (obs_counts == 0)] + forecastedNo_observedYes = obs_counts[(binary_forecast == 0) & (obs_counts > 0)] + forecastedNo_observedNo = obs_counts[(binary_forecast == 0) & (obs_counts == 0)] + + H = len(forecastedYes_observedYes) / ( + len(forecastedYes_observedYes) + len(forecastedNo_observedYes) + ) + F = len(forecastedYes_observedNo) / ( + len(forecastedYes_observedNo) + len(forecastedNo_observedNo) + ) + + threshold_row = {"Threshold": threshold, "H": H, "F": F} + Table_ROC = pandas.concat( + [Table_ROC, pandas.DataFrame([threshold_row])], ignore_index=True + ) + + Table_ROC = pandas.concat( + [pandas.DataFrame({"H": [0], "F": [0]}), Table_ROC], ignore_index=True + ) + + ax.plot( + Table_ROC["F"], + Table_ROC["H"], + label=forecast.name or "Forecast", + color="black", + linestyle=forecast_linestyle, + ) + + if plot_uniform: + ax.plot( + numpy.arange(0, 1.001, 0.001), + numpy.arange(0, 1.001, 0.001), + linestyle="--", + color="gray", + label="SUP", + ) - if filename is not None: - ax.figure.savefig(filename + '.pdf') - ax.figure.savefig(filename + '.png', dpi=300) + ax.set_ylabel("Hit Rate", fontsize=label_fontsize) + ax.set_xlabel("Fraction of false alarms", fontsize=label_fontsize) + + if not linear: + ax.set_xscale("log") + + ax.set_yscale("linear") + ax.tick_params(axis="x", labelsize=label_fontsize) + ax.tick_params(axis="y", labelsize=label_fontsize) + ax.legend(loc=legend_loc, shadow=True, fontsize=legend_fontsize) + ax.set_title(title, fontsize=title_fontsize) - # func has different return types, before release refactor and remove plotting from evaluation. - # plotting should be separated from evaluation. - # evaluation should return some object that can be plotted maybe with verbose option. if show: pyplot.show() return ax -def plot_magnitude_test(evaluation_result, axes=None, show=True, - plot_args=None): +def plot_Molchan_diagram( + forecast, + catalog, + linear=True, + axes=None, + plot_uniform=True, + show=True, + figsize=(9, 8), + forecast_linestyle="-", + legend_fontsize=16, + legend_loc="lower left", + title_fontsize=16, + label_fontsize=14, + title="Molchan diagram", + forecast_label=None, + observed_label=None, + color="black", +): """ - Takes result from evaluation and generates a specific histogram plot to show the results of the statistical evaluation - for the M-test. - - Args: - evaluation_result: object-like var that implements the interface of the above EvaluationResult - axes (matplotlib.Axes): axes object used to chain this plot - show (bool): if true, call pyplot.show() - plot_args(dict): optional argument containing a dictionary of plotting arguments, with keys as strings and items as described below - - Optional plotting arguments: - * figsize: (:class:`list`/:class:`tuple`) - default: [6.4, 4.8] - * title: (:class:`str`) - default: name of the first evaluation result type - * title_fontsize: (:class:`float`) Fontsize of the plot title - default: 10 - * xlabel: (:class:`str`) - default: 'X' - * xlabel_fontsize: (:class:`float`) - default: 10 - * xticks_fontsize: (:class:`float`) - default: 10 - * ylabel_fontsize: (:class:`float`) - default: 10 - * tight_layout: (:class:`bool`) Set matplotlib.figure.tight_layout to remove excess blank space in the plot - default: True - * percentile (:class:`float`) Critial region to shade on histogram - default: 95 - * bins: (:class:`str`) - Set binning type. see matplotlib.hist for more info - default: 'auto' - * xy: (:class:`list`/:class:`tuple`) - default: (0.55, 0.6) + Plot the Molchan Diagram based on forecast and test catalogs using the contingency table. + The Area Skill score and its error are shown in the legend. + + The Molchan diagram is computed following this procedure: + (1) Obtain spatial rates from GriddedForecast and the observed events from the observed catalog. + (2) Rank the rates in descending order (highest rates first). + (3) Sort forecasted rates by ordering found in (2), and normalize rates so their sum is equal to unity. + (4) Obtain binned spatial rates from the observed catalog. + (5) Sort gridded observed rates by ordering found in (2). + (6) Test each ordered and normalized forecasted rate defined in (3) as a threshold value to obtain the + corresponding contingency table. + (7) Define the "nu" (Miss rate) and "tau" (Fraction of spatial alarmed cells) for each threshold using the + information provided by the corresponding contingency table defined in (6). + + Note that: + (1) The testing catalog and forecast should have exactly the same time-window (duration). + (2) Forecasts should be defined over the same region. + (3) If calling this function multiple times, update the color in the arguments. + (4) The user can choose the x-scale (linear or log). + + Args: + forecast (:class: `csep.forecast.GriddedForecast`): + catalog (:class:`AbstractBaseCatalog`): evaluation catalog + linear (bool): if true, a linear x-axis is used; if false, a logarithmic x-axis is used. + axes (:class:`matplotlib.pyplot.Axes`): Previously defined ax object. + plot_uniform (bool): if true, include uniform forecast on plot. + show (bool): if true, displays the plot. + figsize (tuple): Figure size - default: (9, 8). + forecast_linestyle (str): Linestyle for the forecast line - default: '-'. + legend_fontsize (float): Fontsize of the plot legend - default: 16. + legend_loc (str): Location of the plot legend - default: 'lower left'. + title_fontsize (float): Fontsize of the plot title - default: 16. + label_fontsize (float): Fontsize of the axis labels - default: 14. + title (str): Title of the plot - default: 'Molchan diagram'. + forecast_label (str): Label for the forecast in the legend - default: forecast name. + observed_label (str): Label for the observed catalog in the legend - default: forecast name. + color (str): Color of the forecast line - default: 'black'. Returns: - ax (matplotlib.Axes): containing the new plot + :class:`matplotlib.pyplot.Axes` object + Raises: + TypeError: Throws error if a CatalogForecast-like object is provided. + RuntimeError: Throws error if Catalog and Forecast do not have the same region. """ - plot_args = plot_args or {} - title = plot_args.get('title', 'Magnitude Test') - title_fontsize = plot_args.get('title_fontsize', None) - xlabel = plot_args.get('xlabel', 'D* Statistic') - xlabel_fontsize = plot_args.get('xlabel_fontsize', None) - ylabel = plot_args.get('ylabel', 'Number of catalogs') - ylabel_fontsize = plot_args.get('ylabel_fontsize', None) - tight_layout = plot_args.get('tight_layout', True) - percentile = plot_args.get('percentile', 95) - text_fontsize = plot_args.get('text_fontsize', 14) - filename = plot_args.get('filename', None) - bins = plot_args.get('bins', 'auto') - xy = plot_args.get('xy', (0.55, 0.6)) - - # handle plotting - if axes: - chained = True + if not catalog.region == forecast.region: + raise RuntimeError("Catalog region and forecast region must be identical.") + + # Initialize figure + if axes is not None: + ax = axes else: - chained = False - - # supply fixed arguments to plots - # might want to add other defaults here - fixed_plot_args = {'obs_label': evaluation_result.obs_name, - 'sim_label': evaluation_result.sim_name} - plot_args.update(fixed_plot_args) - ax = plot_histogram(evaluation_result.test_distribution, - evaluation_result.observed_statistic, - catalog=evaluation_result.obs_catalog_repr, - plot_args=plot_args, - bins=bins, - axes=axes, - percentile=percentile) - - # annotate plot with quantile values - if not chained: - try: - ax.annotate('$\gamma = P(X \geq x) = {:.2f}$\n$\omega = {:.2f}$' - .format(evaluation_result.quantile, - evaluation_result.observed_statistic), - xycoords='axes fraction', - xy=xy, - fontsize=text_fontsize) - except TypeError: - # if both quantiles are provided, we want to plot the greater-equal quantile - ax.annotate('$\gamma = P(X \geq x) = {:.2f}$\n$\omega = {:.2f}$' - .format(evaluation_result.quantile[0], - evaluation_result.observed_statistic), - xycoords='axes fraction', - xy=xy, - fontsize=text_fontsize) + fig, ax = pyplot.subplots(figsize=figsize) - ax.set_title(title, fontsize=title_fontsize) - ax.set_xlabel(xlabel, fontsize=xlabel_fontsize) - ax.set_ylabel(ylabel, fontsize=ylabel_fontsize) + if forecast_label is None: + forecast_label = forecast.name if forecast.name else "" - if tight_layout: - var = ax.get_figure().tight_layout - () + if observed_label is None: + observed_label = forecast.name if forecast.name else "" - if filename is not None: - ax.figure.savefig(filename + '.pdf') - ax.figure.savefig(filename + '.png', dpi=300) + # Obtain forecast rates (or counts) and observed catalog aggregated in spatial cells + rate = forecast.spatial_counts() + obs_counts = catalog.spatial_counts() - # func has different return types, before release refactor and remove plotting from evaluation. - # plotting should be separated from evaluation. - # evaluation should return some object that can be plotted maybe with verbose option. - if show: - pyplot.show() + # Get index of rates (descending sort) + I = numpy.argsort(rate) + I = numpy.flip(I) - return ax + # Order forecast and cells rates by highest rate cells first + thresholds = (rate[I]) / numpy.sum(rate) + obs_counts = obs_counts[I] + Table_molchan = pandas.DataFrame( + { + "Threshold": [], + "Successful_bins": [], + "Obs_active_bins": [], + "tau": [], + "nu": [], + "R_score": [], + } + ) -def plot_distribution_test(evaluation_result, axes=None, show=True, - plot_args=None): - """ - Takes result from evaluation and generates a specific histogram plot to show the results of the statistical evaluation - for the M-test. + # Each forecasted and normalized rate is tested as a threshold value to define the + # contingency table. + for threshold in thresholds: + threshold = float(threshold) + binary_forecast = numpy.where(thresholds >= threshold, 1, 0) + forecastedYes_observedYes = obs_counts[(binary_forecast == 1) & (obs_counts > 0)] + forecastedYes_observedNo = obs_counts[(binary_forecast == 1) & (obs_counts == 0)] + forecastedNo_observedYes = obs_counts[(binary_forecast == 0) & (obs_counts > 0)] + forecastedNo_observedNo = obs_counts[(binary_forecast == 0) & (obs_counts == 0)] - Args: - evaluation_result: object-like var that implements the interface of the above EvaluationResult + # Creating the DataFrame for the contingency table + data = { + "Observed": [len(forecastedYes_observedYes), len(forecastedNo_observedYes)], + "Not Observed": [len(forecastedYes_observedNo), len(forecastedNo_observedNo)], + } + index = ["Forecasted", "Not Forecasted"] + contingency_df = pandas.DataFrame(data, index=index) + nu = contingency_df.loc["Not Forecasted", "Observed"] / contingency_df["Observed"].sum() + tau = contingency_df.loc["Forecasted"].sum() / ( + contingency_df.loc["Forecasted"].sum() + contingency_df.loc["Not Forecasted"].sum() + ) + R_score = ( + contingency_df.loc["Forecasted", "Observed"] / contingency_df["Observed"].sum() + ) - ( + contingency_df.loc["Forecasted", "Not Observed"] + / contingency_df["Not Observed"].sum() + ) - Returns: - ax (matplotlib.axes.Axes): can be used to modify the figure + threshold_row = { + "Threshold": threshold, + "Successful_bins": contingency_df.loc["Forecasted", "Observed"], + "Obs_active_bins": contingency_df["Observed"].sum(), + "tau": tau, + "nu": nu, + "R_score": R_score, + } + threshold_row_df = pandas.DataFrame([threshold_row]) - """ - plot_args = plot_args or {} - # handle plotting - if axes: - chained = True - else: - chained = False - # supply fixed arguments to plots - # might want to add other defaults here - filename = plot_args.get('filename', None) - xlabel = plot_args.get('xlabel', '') - ylabel = plot_args.get('ylabel', '') - fixed_plot_args = {'obs_label': evaluation_result.obs_name, - 'sim_label': evaluation_result.sim_name} - plot_args.update(fixed_plot_args) - bins = plot_args.get('bins', 'auto') - percentile = plot_args.get('percentile', 95) - ax = plot_histogram(evaluation_result.test_distribution, - evaluation_result.observed_statistic, - catalog=evaluation_result.obs_catalog_repr, - plot_args=plot_args, - bins=bins, - axes=axes, - percentile=percentile) - - # annotate plot with p-values - if not chained: - ax.annotate('$\gamma = P(X \leq x) = {:.3f}$\n$\omega$ = {:.3f}' - .format(evaluation_result.quantile, - evaluation_result.observed_statistic), - xycoords='axes fraction', - xy=(0.5, 0.3), - fontsize=14) - - title = plot_args.get('title', evaluation_result.name) - ax.set_title(title, fontsize=14) - ax.set_xlabel(xlabel) - ax.set_ylabel(ylabel) - - if filename is not None: - ax.figure.savefig(filename + '.pdf') - ax.figure.savefig(filename + '.png', dpi=300) - - # func has different return types, before release refactor and remove plotting from evaluation. - # plotting should be separated from evaluation. - # evaluation should return some object that can be plotted maybe with verbose option. - if show: - pyplot.show() + Table_molchan = pandas.concat([Table_molchan, threshold_row_df], ignore_index=True) - return ax + bottom_row = { + "Threshold": "Full alarms", + "tau": 1, + "nu": 0, + "Obs_active_bins": contingency_df["Observed"].sum(), + } + top_row = { + "Threshold": "No alarms", + "tau": 0, + "nu": 1, + "Obs_active_bins": contingency_df["Observed"].sum(), + } + + Table_molchan = pandas.concat( + [pandas.DataFrame([top_row]), Table_molchan], ignore_index=True + ) + Table_molchan = pandas.concat( + [Table_molchan, pandas.DataFrame([bottom_row])], ignore_index=True + ) + # Computation of Area Skill score (ASS) + Tab_as_score = pandas.DataFrame() + Tab_as_score["Threshold"] = Table_molchan["Threshold"] + Tab_as_score["tau"] = Table_molchan["tau"] + Tab_as_score["nu"] = Table_molchan["nu"] -def plot_likelihood_test(evaluation_result, axes=None, show=True, - plot_args=None): - """ - Takes result from evaluation and generates a specific histogram plot to show the results of the statistical evaluation - for the L-test. + ONE = numpy.ones(len(Tab_as_score)) + Tab_as_score["CUM_BAND"] = cumulative_trapezoid( + ONE, Tab_as_score["tau"], initial=0 + ) - cumulative_trapezoid(Tab_as_score["nu"], Tab_as_score["tau"], initial=0) + Tab_as_score["AS_score"] = numpy.divide( + Tab_as_score["CUM_BAND"], + cumulative_trapezoid(ONE, Tab_as_score["tau"], initial=0) + 1e-10, + ) + Tab_as_score.loc[Tab_as_score.index[-1], "AS_score"] = max( + 0.5, Tab_as_score["AS_score"].iloc[-1] + ) + ASscore = numpy.round(Tab_as_score.loc[Tab_as_score.index[-1], "AS_score"], 2) - Args: - evaluation_result: object-like var that implements the interface of the above EvaluationResult - axes (matplotlib.Axes): axes object used to chain this plot - show (bool): if true, call pyplot.show() - plot_args(dict): optional argument containing a dictionary of plotting arguments, with keys as strings and items as described below - - Optional plotting arguments: - * figsize: (:class:`list`/:class:`tuple`) - default: [6.4, 4.8] - * title: (:class:`str`) - default: name of the first evaluation result type - * title_fontsize: (:class:`float`) Fontsize of the plot title - default: 10 - * xlabel: (:class:`str`) - default: 'X' - * xlabel_fontsize: (:class:`float`) - default: 10 - * xticks_fontsize: (:class:`float`) - default: 10 - * ylabel_fontsize: (:class:`float`) - default: 10 - * text_fontsize: (:class:`float`) - default: 14 - * tight_layout: (:class:`bool`) Set matplotlib.figure.tight_layout to remove excess blank space in the plot - default: True - * percentile (:class:`float`) Critial region to shade on histogram - default: 95 - * bins: (:class:`str`) - Set binning type. see matplotlib.hist for more info - default: 'auto' - * xy: (:class:`list`/:class:`tuple`) - default: (0.55, 0.3) + bin = 0.01 + devstd = numpy.sqrt(1 / (12 * Table_molchan["Obs_active_bins"].iloc[0])) + devstd = devstd * bin**-1 + devstd = numpy.ceil(devstd + 0.5) + devstd = devstd / bin**-1 + dev_std = numpy.round(devstd, 2) - Returns: - ax (matplotlib.axes.Axes): can be used to modify the figure - """ - plot_args = plot_args or {} - title = plot_args.get('title', 'Pseudo-likelihood Test') - title_fontsize = plot_args.get('title_fontsize', None) - xlabel = plot_args.get('xlabel', 'Pseudo likelihood') - xlabel_fontsize = plot_args.get('xlabel_fontsize', None) - ylabel = plot_args.get('ylabel', 'Number of catalogs') - ylabel_fontsize = plot_args.get('ylabel_fontsize', None) - text_fontsize = plot_args.get('text_fontsize', 14) - tight_layout = plot_args.get('tight_layout', True) - percentile = plot_args.get('percentile', 95) - filename = plot_args.get('filename', None) - bins = plot_args.get('bins', 'auto') - xy = plot_args.get('xy', (0.55, 0.3)) - - # handle plotting - if axes: - chained = True - else: - chained = False - # supply fixed arguments to plots - # might want to add other defaults here - fixed_plot_args = {'obs_label': evaluation_result.obs_name, - 'sim_label': evaluation_result.sim_name} - plot_args.update(fixed_plot_args) - ax = plot_histogram(evaluation_result.test_distribution, - evaluation_result.observed_statistic, - catalog=evaluation_result.obs_catalog_repr, - plot_args=plot_args, - bins=bins, - axes=axes, - percentile=percentile) - - # annotate plot with p-values - if not chained: - try: - ax.annotate('$\gamma = P(X \leq x) = {:.2f}$\n$\omega = {:.2f}$' - .format(evaluation_result.quantile, - evaluation_result.observed_statistic), - xycoords='axes fraction', - xy=xy, - fontsize=text_fontsize) - except TypeError: - # if both quantiles are provided, we want to plot the greater-equal quantile - ax.annotate('$\gamma = P(X \leq x) = {:.2f}$\n$\omega = {:.2f}$' - .format(evaluation_result.quantile[1], - evaluation_result.observed_statistic), - xycoords='axes fraction', - xy=xy, - fontsize=text_fontsize) + # Plot the Molchan trajectory + ax.plot( + Table_molchan["tau"], + Table_molchan["nu"], + label=f"{forecast_label}, ASS={ASscore}±{dev_std} ", + color=color, + linestyle=forecast_linestyle, + ) - ax.set_title(title, fontsize=title_fontsize) - ax.set_xlabel(xlabel, fontsize=xlabel_fontsize) - ax.set_ylabel(ylabel, fontsize=ylabel_fontsize) + # Plot uniform forecast + if plot_uniform: + x_uniform = numpy.arange(0, 1.001, 0.001) + y_uniform = numpy.arange(1.00, -0.001, -0.001) + ax.plot(x_uniform, y_uniform, linestyle="--", color="gray", label="SUP") - if tight_layout: - ax.figure.tight_layout() + # Plotting arguments + ax.set_ylabel("Miss Rate", fontsize=label_fontsize) + ax.set_xlabel("Fraction of area occupied by alarms", fontsize=label_fontsize) - if filename is not None: - ax.figure.savefig(filename + '.pdf') - ax.figure.savefig(filename + '.png', dpi=300) + if linear: + legend_loc = "upper right" + else: + ax.set_xscale("log") + + ax.tick_params(axis="x", labelsize=label_fontsize) + ax.tick_params(axis="y", labelsize=label_fontsize) + ax.legend(loc=legend_loc, shadow=True, fontsize=legend_fontsize) + ax.set_title(title, fontsize=title_fontsize) - # func has different return types, before release refactor and remove plotting from evaluation. - # plotting should be separated from evaluation. - # evaluation should return some object that can be plotted maybe with verbose option. if show: pyplot.show() + return ax -def plot_spatial_test(evaluation_result, axes=None, plot_args=None, show=True): +############### +# Spatial plots +############### +def plot_basemap( + basemap: Optional[str] = None, + extent: Optional[List[float]] = None, + coastline: bool = True, + borders: bool = False, + tile_depth: Union[str, int] = "auto", + set_global: bool = False, + projection: ccrs.Projection = ccrs.PlateCarree(), + ax: Optional[pyplot.Axes] = None, + show: bool = False, + **kwargs, +) -> matplotlib.axes.Axes: """ - Plot spatial test result from catalog based forecast + Wrapper function for multiple Cartopy base plots, including access to standard raster + webservices. Args: - evaluation_result: object-like var that implements the interface of the above EvaluationResult - axes (matplotlib.Axes): axes object used to chain this plot - show (bool): if true, call pyplot.show() - plot_args(dict): optional argument containing a dictionary of plotting arguments, with keys as strings and items as described below - - Optional plotting arguments: - * figsize: (:class:`list`/:class:`tuple`) - default: [6.4, 4.8] - * title: (:class:`str`) - default: name of the first evaluation result type - * title_fontsize: (:class:`float`) Fontsize of the plot title - default: 10 - * xlabel: (:class:`str`) - default: 'X' - * xlabel_fontsize: (:class:`float`) - default: 10 - * xticks_fontsize: (:class:`float`) - default: 10 - * ylabel_fontsize: (:class:`float`) - default: 10 - * text_fontsize: (:class:`float`) - default: 14 - * tight_layout: (:class:`bool`) Set matplotlib.figure.tight_layout to remove excess blank space in the plot - default: True - * percentile (:class:`float`) Critial region to shade on histogram - default: 95 - * bins: (:class:`str`) - Set binning type. see matplotlib.hist for more info - default: 'auto' - * xy: (:class:`list`/:class:`tuple`) - default: (0.2, 0.6) + basemap (str): Possible values are: 'stock_img', 'google-satellite', 'ESRI_terrain', + 'ESRI_imagery', 'ESRI_relief', 'ESRI_topo', or a webservice link. + Default is None. + extent (list): [lon_min, lon_max, lat_min, lat_max] + ax (matplotlib.Axes): Previously defined ax object. + coastline (bool): Flag to plot coastline. Default True. + borders (bool): Flag to plot country borders. Default False. + tile_depth (str/int): Zoom level (1-12) of the basemap tiles. If 'auto', it is + automatically derived from extent. + set_global (bool): Display the complete globe as basemap. + projection (cartopy.crs.Projection): Projection to be used in the basemap. + show (bool): If True, displays the plot. Returns: - ax (matplotlib.axes.Axes): can be used to modify the figure + matplotlib.Axes: Matplotlib Axes object. """ - plot_args = plot_args or {} - title = plot_args.get('title', 'Spatial Test') - title_fontsize = plot_args.get('title_fontsize', None) - xlabel = plot_args.get('xlabel', 'Normalized pseudo-likelihood') - xlabel_fontsize = plot_args.get('xlabel_fontsize', None) - ylabel = plot_args.get('ylabel', 'Number of catalogs') - ylabel_fontsize = plot_args.get('ylabel_fontsize', None) - text_fontsize = plot_args.get('text_fontsize', 14) - tight_layout = plot_args.get('tight_layout', True) - percentile = plot_args.get('percentile', 95) - filename = plot_args.get('filename', None) - bins = plot_args.get('bins', 'auto') - xy = plot_args.get('xy', (0.2, 0.6)) - - # handle plotting - if axes: - chained = True - else: - chained = False - - # supply fixed arguments to plots - # might want to add other defaults here - fixed_plot_args = {'obs_label': evaluation_result.obs_name, - 'sim_label': evaluation_result.sim_name} - plot_args.update(fixed_plot_args) - - ax = plot_histogram(evaluation_result.test_distribution, - evaluation_result.observed_statistic, - catalog=evaluation_result.obs_catalog_repr, - plot_args=plot_args, - bins=bins, - axes=axes, - percentile=percentile) - - # annotate plot with p-values - if not chained: - try: - ax.annotate('$\gamma = P(X \leq x) = {:.2f}$\n$\omega = {:.2f}$' - .format(evaluation_result.quantile, - evaluation_result.observed_statistic), - xycoords='axes fraction', - xy=xy, - fontsize=text_fontsize) - except TypeError: - # if both quantiles are provided, we want to plot the greater-equal quantile - ax.annotate('$\gamma = P(X \leq x) = {:.2f}$\n$\omega = {:.2f}$' - .format(evaluation_result.quantile[1], - evaluation_result.observed_statistic), - xycoords='axes fraction', - xy=xy, - fontsize=text_fontsize) - - ax.set_title(title, fontsize=title_fontsize) - ax.set_xlabel(xlabel, fontsize=xlabel_fontsize) - ax.set_ylabel(ylabel, fontsize=ylabel_fontsize) - - if tight_layout: - ax.figure.tight_layout() + plot_args = {**DEFAULT_PLOT_ARGS, **kwargs} + ax = ax or _create_geo_axes(plot_args["figsize"], extent, projection, set_global) + + line_autoscaler = cartopy.feature.AdaptiveScaler("110m", (("50m", 50), ("10m", 5))) + tile_autoscaler = cartopy.feature.AdaptiveScaler(5, ((6, 50), (7, 15))) + tile_depth = ( + 4 + if set_global + else (tile_autoscaler.scale_from_extent(extent) if tile_depth == "auto" else tile_depth) + ) + # Add coastlines and borders + if coastline: + ax.coastlines( + color=plot_args["coastline_color"], linewidth=plot_args["coastline_linewidth"] + ) + if borders: + borders = cartopy.feature.NaturalEarthFeature( + "cultural", + "admin_0_boundary_lines_land", + line_autoscaler, + edgecolor=plot_args["borders_color"], + facecolor="never", + ) + ax.add_feature(borders, linewidth=plot_args["borders_linewidth"]) + + # Add basemap tiles + try: + if basemap == "stock_img": + ax.stock_img() + elif basemap is not None: + tiles = _get_basemap(basemap) + if tiles: + ax.add_image(tiles, tile_depth) + except Exception as e: + print( + f"Unable to plot basemap. This might be due to no internet access. " + f"Error: {str(e)}" + ) - if filename is not None: - ax.figure.savefig(filename + '.pdf') - ax.figure.savefig(filename + '.png', dpi=300) + # Set up Grid-lines + if plot_args["grid"]: + _add_gridlines(ax, plot_args["grid_labels"], plot_args["grid_fontsize"]) - # func has different return types, before release refactor and remove plotting from evaluation. - # plotting should be separated from evaluation. - # evaluation should return some object that can be plotted maybe with verbose option. if show: pyplot.show() return ax -def plot_calibration_test(evaluation_result, axes=None, plot_args=None, - show=False): - # set up QQ plots and KS test - plot_args = plot_args or {} - n = len(evaluation_result.test_distribution) - k = numpy.arange(1, n + 1) - # plotting points for uniform quantiles - pp = k / (n + 1) - # compute confidence intervals for order statistics using beta distribution - ulow = scipy.stats.beta.ppf(0.025, k, n - k + 1) - uhigh = scipy.stats.beta.ppf(0.975, k, n - k + 1) - - # get stuff from plot_args - label = plot_args.get('label', evaluation_result.sim_name) - xlim = plot_args.get('xlim', [0, 1.05]) - ylim = plot_args.get('ylim', [0, 1.05]) - xlabel = plot_args.get('xlabel', 'Quantile scores') - ylabel = plot_args.get('ylabel', 'Standard uniform quantiles') - color = plot_args.get('color', 'tab:blue') - marker = plot_args.get('marker', 'o') - size = plot_args.get('size', 5) - legend_loc = plot_args.get('legend_loc', 'best') - - # quantiles should be sorted for plotting - sorted_td = numpy.sort(evaluation_result.test_distribution) +def plot_catalog( + catalog: "CSEPCatalog", + basemap: Optional[str] = None, + ax: Optional[matplotlib.axes.Axes] = None, + projection: Optional[Union[ccrs.Projection, str]] = ccrs.PlateCarree(), + show: bool = False, + extent: Optional[List[float]] = None, + set_global: bool = False, + mag_scale: float = 1, + mag_ticks: Optional[List[float]] = None, + plot_region: bool = False, + **kwargs, +) -> matplotlib.axes.Axes: + """Plot catalog in a region. - if axes is None: - fig, ax = pyplot.subplots() - else: - ax = axes + Args: + catalog (:class:`CSEPCatalog`): Catalog object to be plotted. + basemap (str): Optional. Passed to :func:`plot_basemap` along with `kwargs` + ax (:class:`matplotlib.pyplot.ax`): Previously defined ax object. + show (bool): Flag if the figure is displayed. + extent (list): Default 1.05 * :func:`catalog.region.get_bbox()`. + projection (cartopy.crs.Projection): Projection to be used in the underlying basemap + set_global (bool): Display the complete globe as basemap. + mag_scale (float): Scaling of the scatter. + mag_ticks (list): Ticks to display in the legend. + plot_region (bool): Flag to plot the catalog region border. + kwargs: size, alpha, markercolor, markeredgecolor, figsize, legend, + legend_title, legend_labelspacing, legend_borderpad, legend_framealpha + + Returns: + :class:`matplotlib.pyplot.ax` object + """ + + plot_args = {**DEFAULT_PLOT_ARGS, **kwargs} + # Get spatial information for plotting + extent = extent or _calculate_spatial_extent(catalog, set_global, plot_region) + # Instantiate GeoAxes object + ax = ax or _create_geo_axes(plot_args["figsize"], extent, projection, set_global) + # chain basemap + ax = plot_basemap(basemap, extent, ax=ax, set_global=set_global, show=False, **plot_args) + + # Plot catalog + scatter = ax.scatter( + catalog.get_longitudes(), + catalog.get_latitudes(), + s=_size_map(plot_args["size"], catalog.get_magnitudes(), mag_scale), + transform=ccrs.PlateCarree(), + color=plot_args["markercolor"], + edgecolors=plot_args["markeredgecolor"], + alpha=plot_args["alpha"], + ) + + # Legend + if plot_args["legend"]: + mw_range = [min(catalog.get_magnitudes()), max(catalog.get_magnitudes())] + + if isinstance(mag_ticks, (tuple, list, numpy.ndarray)): + if not numpy.all([mw_range[0] <= i <= mw_range[1] for i in mag_ticks]): + print("Magnitude ticks do not lie within the catalog magnitude range") + elif mag_ticks is None: + mag_ticks = numpy.linspace(mw_range[0], mw_range[1], 4) - # plot qq plot - _ = ax.scatter(sorted_td, pp, label=label, c=color, marker=marker, s=size) - # plot uncertainty on uniform quantiles - ax.plot(pp, pp, '-k') - ax.plot(ulow, pp, ':k') - ax.plot(uhigh, pp, ':k') + handles, labels = scatter.legend_elements( + prop="sizes", + num=list(_size_map(plot_args["size"], mag_ticks, mag_scale)), + alpha=0.3, + ) + ax.legend( + handles, + numpy.round(mag_ticks, 1), + loc=plot_args["legend_loc"], + handletextpad=5, + title=plot_args.get("legend_title") or "Magnitudes", + fontsize=plot_args["legend_fontsize"], + title_fontsize=plot_args["legend_titlesize"], + labelspacing=plot_args["legend_labelspacing"], + borderpad=plot_args["legend_borderpad"], + framealpha=plot_args["legend_framealpha"], + ) + + # Draw catalog's region border + if plot_region: + try: + pts = catalog.region.tight_bbox() + ax.plot(pts[:, 0], pts[:, 1], lw=1, color=plot_args["region_color"]) + except AttributeError: + pass - ax.set_ylim(ylim) - ax.set_xlim(xlim) - ax.set_xlabel(xlabel) - ax.set_ylabel(ylabel) + ax.set_title(plot_args["title"], fontsize=plot_args["title_fontsize"], y=1.06) - ax.legend(loc=legend_loc) + if plot_args["tight_layout"]: + ax.figure.tight_layout() if show: pyplot.show() @@ -1552,148 +1501,86 @@ def plot_calibration_test(evaluation_result, axes=None, plot_args=None, return ax -def plot_poisson_consistency_test(eval_results, normalize=False, - one_sided_lower=False, axes=None, - plot_args=None, show=False): - """ Plots results from CSEP1 tests following the CSEP1 convention. - - Note: All of the evaluations should be from the same type of evaluation, otherwise the results will not be - comparable on the same figure. +def plot_spatial_dataset( + gridded: numpy.ndarray, + region: "CartesianGrid2D", + basemap: Optional[str] = None, + ax: Optional[pyplot.Axes] = None, + projection: Optional[Union[ccrs.Projection, str]] = ccrs.PlateCarree(), + show: bool = False, + extent: Optional[List[float]] = None, + set_global: bool = False, + plot_region: bool = True, + colorbar: bool = True, + colormap: Union[str, matplotlib.colors.Colormap] = "viridis", + clim: Optional[Tuple[float, float]] = None, + clabel: Optional[str] = None, + alpha: Optional[float] = None, + alpha_exp: float = 0, + **kwargs, +) -> matplotlib.axes.Axes: + """ + Plot spatial dataset such as data from a gridded forecast. Args: - results (list): Contains the tests results :class:`csep.core.evaluations.EvaluationResult` (see note above) - normalize (bool): select this if the forecast likelihood should be normalized by the observed likelihood. useful - for plotting simulation based simulation tests. - one_sided_lower (bool): select this if the plot should be for a one sided test - plot_args(dict): optional argument containing a dictionary of plotting arguments, with keys as strings and items as described below - - Optional plotting arguments: - * figsize: (:class:`list`/:class:`tuple`) - default: [6.4, 4.8] - * title: (:class:`str`) - default: name of the first evaluation result type - * title_fontsize: (:class:`float`) Fontsize of the plot title - default: 10 - * xlabel: (:class:`str`) - default: 'X' - * xlabel_fontsize: (:class:`float`) - default: 10 - * xticks_fontsize: (:class:`float`) - default: 10 - * ylabel_fontsize: (:class:`float`) - default: 10 - * color: (:class:`float`/:class:`None`) If None, sets it to red/green according to :func:`_get_marker_style` - default: 'black' - * linewidth: (:class:`float`) - default: 1.5 - * capsize: (:class:`float`) - default: 4 - * hbars: (:class:`bool`) Flag to draw horizontal bars for each model - default: True - * tight_layout: (:class:`bool`) Set matplotlib.figure.tight_layout to remove excess blank space in the plot - default: True - + gridded (numpy.ndarray): 2D array of values corresponding to the region. + region (CartesianGrid2D): Region in which gridded values are contained. + basemap (str): Optional. Passed to :func:`plot_basemap` along with `kwargs` + ax (Optional[pyplot.Axes]): Previously defined ax object. + projection (cartopy.crs.Projection): Projection to be used in the basemap. + show (bool): If True, displays the plot. + extent (Optional[List[float]]): [lon_min, lon_max, lat_min, lat_max]. + set_global (bool): Display the complete globe as basemap. + plot_region (bool): If True, plot the dataset region border. + colorbar (bool): If True, include a colorbar. + colormap (Union[str, matplotlib.colors.Colormap]): Colormap to use. + clim (Optional[Tuple[float, float]]): Range of the colorbar. + clabel (Optional[str]): Label of the colorbar. + alpha (Optional[float]): Transparency level. + alpha_exp (float): Exponent for the alpha function (recommended between 0.4 and 1). + kwargs: colorbar_labelsize, colorbar_ticksize Returns: - ax (:class:`matplotlib.pyplot.axes` object) + matplotlib.axes.Axes: Matplotlib axes handle. """ - try: - results = list(eval_results) - except TypeError: - results = [eval_results] - results.reverse() - # Parse plot arguments. More can be added here - if plot_args is None: - plot_args = {} - figsize = plot_args.get('figsize', None) - title = plot_args.get('title', results[0].name) - title_fontsize = plot_args.get('title_fontsize', None) - xlabel = plot_args.get('xlabel', '') - xlabel_fontsize = plot_args.get('xlabel_fontsize', None) - xticks_fontsize = plot_args.get('xticks_fontsize', None) - ylabel_fontsize = plot_args.get('ylabel_fontsize', None) - color = plot_args.get('color', 'black') - linewidth = plot_args.get('linewidth', None) - capsize = plot_args.get('capsize', 4) - hbars = plot_args.get('hbars', True) - tight_layout = plot_args.get('tight_layout', True) - percentile = plot_args.get('percentile', 95) - plot_mean = plot_args.get('mean', False) - - if axes is None: - fig, ax = pyplot.subplots(figsize=figsize) - else: - ax = axes - fig = ax.get_figure() + plot_args = {**DEFAULT_PLOT_ARGS, **kwargs} - xlims = [] - for index, res in enumerate(results): - # handle analytical distributions first, they are all in the form ['name', parameters]. - if res.test_distribution[0] == 'poisson': - plow = scipy.stats.poisson.ppf((1 - percentile / 100.) / 2., - res.test_distribution[1]) - phigh = scipy.stats.poisson.ppf(1 - (1 - percentile / 100.) / 2., - res.test_distribution[1]) - mean = res.test_distribution[1] - observed_statistic = res.observed_statistic - # empirical distributions - else: - if normalize: - test_distribution = numpy.array( - res.test_distribution) - res.observed_statistic - observed_statistic = 0 - else: - test_distribution = numpy.array(res.test_distribution) - observed_statistic = res.observed_statistic - # compute distribution depending on type of test - if one_sided_lower: - plow = numpy.percentile(test_distribution, 100 - percentile) - phigh = numpy.percentile(test_distribution, 100) - else: - plow = numpy.percentile(test_distribution, - (100 - percentile) / 2.) - phigh = numpy.percentile(test_distribution, - 100 - (100 - percentile) / 2.) - mean = numpy.mean(test_distribution) - - if not numpy.isinf( - observed_statistic): # Check if test result does not diverges - percentile_lims = numpy.abs(numpy.array([[mean - plow, - phigh - mean]]).T) - ax.plot(observed_statistic, index, - _get_marker_style(observed_statistic, (plow, phigh), - one_sided_lower)) - ax.errorbar(mean, index, xerr=percentile_lims, - fmt='ko' * plot_mean, capsize=capsize, - linewidth=linewidth, ecolor=color) - # determine the limits to use - xlims.append((plow, phigh, observed_statistic)) - # we want to only extent the distribution where it falls outside of it in the acceptable tail - if one_sided_lower: - if observed_statistic >= plow and phigh < observed_statistic: - # draw dashed line to infinity - xt = numpy.linspace(phigh, 99999, 100) - yt = numpy.ones(100) * index - ax.plot(xt, yt, linestyle='--', linewidth=linewidth, - color=color) + # Get spatial information for plotting + extent = extent or _calculate_spatial_extent(region, set_global, plot_region) + # Instantiate GeoAxes object + ax = ax or _create_geo_axes(plot_args["figsize"], extent, projection, set_global) + + # chain basemap + ax = plot_basemap(basemap, extent, ax=ax, set_global=set_global, show=False, **plot_args) + + # Define colormap and alpha transparency + colormap, alpha = _define_colormap_and_alpha(colormap, alpha_exp, alpha) + + # Plot spatial dataset + lons, lats = numpy.meshgrid( + numpy.append(region.xs, region.get_bbox()[1]), + numpy.append(region.ys, region.get_bbox()[3]), + ) + im = ax.pcolor( + lons, lats, gridded, cmap=colormap, alpha=alpha, snap=True, transform=ccrs.PlateCarree() + ) + im.set_clim(clim) - else: - print('Observed statistic diverges for forecast %s, index %i.' - ' Check for zero-valued bins within the forecast' % ( - res.sim_name, index)) - ax.barh(index, 99999, left=-10000, height=1, color=['red'], - alpha=0.5) + # Colorbar options + if colorbar: + _add_colorbar( + ax, im, clabel, plot_args["colorbar_labelsize"], plot_args["colorbar_ticksize"] + ) - try: - ax.set_xlim(*_get_axis_limits(xlims)) - except ValueError: - raise ValueError('All EvaluationResults have infinite ' - 'observed_statistics') - ax.set_yticks(numpy.arange(len(results))) - ax.set_yticklabels([res.sim_name for res in results], - fontsize=ylabel_fontsize) - ax.set_ylim([-0.5, len(results) - 0.5]) - if hbars: - yTickPos = ax.get_yticks() - if len(yTickPos) >= 2: - ax.barh(yTickPos, numpy.array([99999] * len(yTickPos)), - left=-10000, - height=(yTickPos[1] - yTickPos[0]), color=['w', 'gray'], - alpha=0.2, zorder=0) - ax.set_title(title, fontsize=title_fontsize) - ax.set_xlabel(xlabel, fontsize=xlabel_fontsize) - ax.tick_params(axis='x', labelsize=xticks_fontsize) - if tight_layout: - ax.figure.tight_layout() - fig.tight_layout() + # Draw forecast's region border + if plot_region and not set_global: + try: + pts = region.tight_bbox() + ax.plot(pts[:, 0], pts[:, 1], lw=1, color=plot_args["region_color"]) + except AttributeError: + pass + + ax.set_title(plot_args["title"], fontsize=plot_args["title_fontsize"], y=1.06) if show: pyplot.show() @@ -1701,248 +1588,116 @@ def plot_poisson_consistency_test(eval_results, normalize=False, return ax -def plot_comparison_test(results_t, results_w=None, axes=None, plot_args=None): - """Plots list of T-Test (and W-Test) Results""" - - if plot_args is None: - plot_args = {} - - figsize = plot_args.get('figsize', None) - title = plot_args.get('title', 'CSEP1 Comparison Test') - xlabel = plot_args.get('xlabel', None) - ylabel = plot_args.get('ylabel', 'Information gain per earthquake') - ylim = plot_args.get('ylim', (None, None)) - capsize = plot_args.get('capsize', 2) - linewidth = plot_args.get('linewidth', 1) - markersize = plot_args.get('markersize', 2) - percentile = plot_args.get('percentile', 95) - xticklabels_rotation = plot_args.get('xticklabels_rotation', 90) - xlabel_fontsize = plot_args.get('xlabel_fontsize', 12) - ylabel_fontsize = plot_args.get('ylabel_fontsize', 12) - - if axes is None: - fig, ax = pyplot.subplots(figsize=figsize) +##################### +# Plot helper functions +##################### +def _get_marker_style(obs_stat, p, one_sided_lower): + """Returns matplotlib marker style as fmt string""" + if obs_stat < p[0] or obs_stat > p[1]: + # red circle + fmt = "ro" else: - ax = axes - fig = ax.get_figure() - - ax.axhline(y=0, linestyle='--', color='black') - - Results = zip(results_t, results_w) if results_w else zip(results_t) - - for index, result in enumerate(Results): - result_t = result[0] - result_w = result[1] if results_w else None - - ylow = result_t.observed_statistic - result_t.test_distribution[0] - yhigh = result_t.test_distribution[1] - result_t.observed_statistic - color = _get_marker_t_color(result_t.test_distribution) - - if numpy.isinf(result_t.observed_statistic): - print('Diverging information gain for forecast %s, index %i.' - ' Check for zero-valued bins within the forecast' % - (result_t.sim_name, index)) - ax.axvspan(index - 0.5, index + 0.5, alpha=0.5, facecolor='red') + # green square + fmt = "gs" + if one_sided_lower: + if obs_stat < p[0]: + fmt = "ro" else: - ax.errorbar(index, result_t.observed_statistic, - yerr=numpy.array([[ylow, yhigh]]).T, color=color, - linewidth=linewidth, capsize=capsize) - - if result_w is not None: - if _get_marker_w_color(result_w.quantile, percentile): - facecolor = _get_marker_t_color(result_t.test_distribution) - else: - facecolor = 'white' - else: - facecolor = 'white' - ax.plot(index, result_t.observed_statistic, marker='o', - markerfacecolor=facecolor, markeredgecolor=color, - markersize=markersize) + fmt = "gs" + return fmt - ax.set_xticks(numpy.arange(len(results_t))) - ax.set_xticklabels([res.sim_name[0] for res in results_t], - rotation=xticklabels_rotation, fontsize=xlabel_fontsize) - ax.set_xlabel(xlabel) - ax.set_ylabel(ylabel, fontsize=ylabel_fontsize) - ax.set_title(title) - ax.yaxis.grid() - xTickPos = ax.get_xticks() - ax.yaxis.set_major_locator(matplotlib.ticker.MaxNLocator(integer=True)) - ax.set_ylim([ylim[0], ylim[1]]) - ax.set_xlim([-0.5, len(results_t) - 0.5]) - if len(results_t) > 2: - ax.bar(xTickPos, numpy.array([9999] * len(xTickPos)), bottom=-2000, - width=(xTickPos[1] - xTickPos[0]), color=['gray', 'w'], alpha=0.2) - fig.tight_layout() - return ax +def _get_marker_t_color(distribution): + """Returns matplotlib marker style as fmt string""" + if distribution[0] > 0.0 and distribution[1] > 0.0: + fmt = "green" + elif distribution[0] < 0.0 and distribution[1] < 0.0: + fmt = "red" + else: + fmt = "grey" + return fmt -def plot_consistency_test(eval_results, normalize=False, axes=None, - one_sided_lower=False, variance=None, plot_args=None, - show=False): - """ Plots results from CSEP1 tests following the CSEP1 convention. - Note: All of the evaluations should be from the same type of evaluation, otherwise the results will not be - comparable on the same figure. +def _get_marker_w_color(distribution, percentile): + """Returns matplotlib marker style as fmt string""" - Args: - eval_results (list): Contains the tests results :class:`csep.core.evaluations.EvaluationResult` (see note above) - normalize (bool): select this if the forecast likelihood should be normalized by the observed likelihood. useful - for plotting simulation based simulation tests. - one_sided_lower (bool): select this if the plot should be for a one sided test - plot_args(dict): optional argument containing a dictionary of plotting arguments, with keys as strings and items as described below - - Optional plotting arguments: - * figsize: (:class:`list`/:class:`tuple`) - default: [6.4, 4.8] - * title: (:class:`str`) - default: name of the first evaluation result type - * title_fontsize: (:class:`float`) Fontsize of the plot title - default: 10 - * xlabel: (:class:`str`) - default: 'X' - * xlabel_fontsize: (:class:`float`) - default: 10 - * xticks_fontsize: (:class:`float`) - default: 10 - * ylabel_fontsize: (:class:`float`) - default: 10 - * color: (:class:`float`/:class:`None`) If None, sets it to red/green according to :func:`_get_marker_style` - default: 'black' - * linewidth: (:class:`float`) - default: 1.5 - * capsize: (:class:`float`) - default: 4 - * hbars: (:class:`bool`) Flag to draw horizontal bars for each model - default: True - * tight_layout: (:class:`bool`) Set matplotlib.figure.tight_layout to remove excess blank space in the plot - default: True + if distribution < (1 - percentile / 100): + fmt = True + else: + fmt = False - Returns: - ax (:class:`matplotlib.pyplot.axes` object) - """ + return fmt - try: - results = list(eval_results) - except TypeError: - results = [eval_results] - results.reverse() - # Parse plot arguments. More can be added here - if plot_args is None: - plot_args = {} - figsize = plot_args.get('figsize', None) - title = plot_args.get('title', results[0].name) - title_fontsize = plot_args.get('title_fontsize', None) - xlabel = plot_args.get('xlabel', '') - xlabel_fontsize = plot_args.get('xlabel_fontsize', None) - xticks_fontsize = plot_args.get('xticks_fontsize', None) - ylabel_fontsize = plot_args.get('ylabel_fontsize', None) - color = plot_args.get('color', 'black') - linewidth = plot_args.get('linewidth', None) - capsize = plot_args.get('capsize', 4) - hbars = plot_args.get('hbars', True) - tight_layout = plot_args.get('tight_layout', True) - percentile = plot_args.get('percentile', 95) - plot_mean = plot_args.get('mean', False) - - if axes is None: - fig, ax = pyplot.subplots(figsize=figsize) - else: - ax = axes - fig = ax.get_figure() - xlims = [] +def _get_axis_limits(pnts, border=0.05): + """Returns a tuple of x_min and x_max given points on plot.""" + x_min = numpy.min(pnts) + x_max = numpy.max(pnts) + xd = (x_max - x_min) * border + return x_min - xd, x_max + xd - for index, res in enumerate(results): - # handle analytical distributions first, they are all in the form ['name', parameters]. - if res.test_distribution[0] == 'poisson': - plow = scipy.stats.poisson.ppf((1 - percentile / 100.) / 2., - res.test_distribution[1]) - phigh = scipy.stats.poisson.ppf(1 - (1 - percentile / 100.) / 2., - res.test_distribution[1]) - mean = res.test_distribution[1] - observed_statistic = res.observed_statistic - elif res.test_distribution[0] == 'negative_binomial': - var = variance - observed_statistic = res.observed_statistic - mean = res.test_distribution[1] - upsilon = 1.0 - ((var - mean) / var) - tau = (mean ** 2 / (var - mean)) - plow = scipy.stats.nbinom.ppf((1 - percentile / 100.) / 2., tau, - upsilon) - phigh = scipy.stats.nbinom.ppf(1 - (1 - percentile / 100.) / 2., - tau, upsilon) - - # empirical distributions - else: - if normalize: - test_distribution = numpy.array( - res.test_distribution) - res.observed_statistic - observed_statistic = 0 - else: - test_distribution = numpy.array(res.test_distribution) - observed_statistic = res.observed_statistic - # compute distribution depending on type of test - if one_sided_lower: - plow = numpy.percentile(test_distribution, 5) - phigh = numpy.percentile(test_distribution, 100) - else: - plow = numpy.percentile(test_distribution, 2.5) - phigh = numpy.percentile(test_distribution, 97.5) - mean = numpy.mean(res.test_distribution) - - if not numpy.isinf( - observed_statistic): # Check if test result does not diverges - percentile_lims = numpy.array([[mean - plow, phigh - mean]]).T - ax.plot(observed_statistic, index, - _get_marker_style(observed_statistic, (plow, phigh), - one_sided_lower)) - ax.errorbar(mean, index, xerr=percentile_lims, - fmt='ko' * plot_mean, capsize=capsize, - linewidth=linewidth, ecolor=color) - # determine the limits to use - xlims.append((plow, phigh, observed_statistic)) - # we want to only extent the distribution where it falls outside of it in the acceptable tail - if one_sided_lower: - if observed_statistic >= plow and phigh < observed_statistic: - # draw dashed line to infinity - xt = numpy.linspace(phigh, 99999, 100) - yt = numpy.ones(100) * index - ax.plot(xt, yt, linestyle='--', linewidth=linewidth, - color=color) +def _get_basemap(basemap): + if basemap == "google-satellite": + tiles = img_tiles.GoogleTiles(style="satellite", cache=True) + elif basemap == "ESRI_terrain": + webservice = ( + "https://server.arcgisonline.com/ArcGIS/rest/services/World_Terrain_Base/" + "MapServer/tile/{z}/{y}/{x}.jpg" + ) + tiles = img_tiles.GoogleTiles(url=webservice, cache=True) + elif basemap == "ESRI_imagery": + webservice = ( + "https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/" + "MapServer/tile/{z}/{y}/{x}.jpg" + ) + tiles = img_tiles.GoogleTiles(url=webservice, cache=True) + elif basemap == "ESRI_relief": + webservice = ( + "https://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/" + "MapServer/tile/{z}/{y}/{x}.jpg" + ) + tiles = img_tiles.GoogleTiles(url=webservice, cache=True) + elif basemap == "ESRI_topo": + webservice = ( + "https://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/" + "MapServer/tile/{z}/{y}/{x}.jpg" + ) + tiles = img_tiles.GoogleTiles(url=webservice, cache=True) + else: + try: + webservice = basemap + tiles = img_tiles.GoogleTiles(url=webservice, cache=True) + except Exception as e: + raise ValueError(f"Basemap type not valid or not implemented. {e}") - else: - print('Observed statistic diverges for forecast %s, index %i.' - ' Check for zero-valued bins within the forecast' % ( - res.sim_name, index)) - ax.barh(index, 99999, left=-10000, height=1, color=['red'], - alpha=0.5) + return tiles - try: - ax.set_xlim(*_get_axis_limits(xlims)) - except ValueError: - raise ValueError( - 'All EvaluationResults have infinite observed_statistics') - ax.set_yticks(numpy.arange(len(results))) - ax.set_yticklabels([res.sim_name for res in results], - fontsize=ylabel_fontsize) - ax.set_ylim([-0.5, len(results) - 0.5]) - if hbars: - yTickPos = ax.get_yticks() - if len(yTickPos) >= 2: - ax.barh(yTickPos, numpy.array([99999] * len(yTickPos)), - left=-10000, - height=(yTickPos[1] - yTickPos[0]), color=['w', 'gray'], - alpha=0.2, zorder=0) - ax.set_title(title, fontsize=title_fontsize) - ax.set_xlabel(xlabel, fontsize=xlabel_fontsize) - ax.tick_params(axis='x', labelsize=xticks_fontsize) - if tight_layout: - ax.figure.tight_layout() - fig.tight_layout() - if show: - pyplot.show() +def _add_labels_for_publication(figure, style="bssa", labelsize=16): + """Adds publication labels too the outside of a figure.""" + all_axes = figure.get_axes() + ascii_iter = iter(string.ascii_lowercase) + for ax in all_axes: + # check for colorbar and ignore for annotations + if ax.get_label() == "Colorbar": + continue + annot = next(ascii_iter) + if style == "bssa": + ax.annotate( + f"({annot})", (0.025, 1.025), xycoords="axes fraction", fontsize=labelsize + ) - return ax + return -def plot_pvalues_and_intervals(test_results, ax, var=None): - """ Plots p-values and intervals for a list of Poisson or NBD test results +def _plot_pvalues_and_intervals(test_results, ax, var=None): + """Plots p-values and intervals for a list of Poisson or NBD test results Args: - test_results (list): list of EvaluationResults for N-test. All tests should use the same distribution - (ie Poisson or NBD). + test_results (list): list of EvaluationResults for N-test. All tests should use the same + distribution (ie Poisson or NBD). ax (matplotlib.axes.Axes.axis): axes to use for plot. create using matplotlib var (float): variance of the NBD distribution. Must be used for NBD plots. @@ -1958,117 +1713,227 @@ def plot_pvalues_and_intervals(test_results, ax, var=None): p_values = [] # Differentiate between N-tests and other consistency tests - if test_results[0].name == 'NBD N-Test' or test_results[ - 0].name == 'Poisson N-Test': + if test_results[0].name == "NBD N-Test" or test_results[0].name == "Poisson N-Test": legend_elements = [ - matplotlib.lines.Line2D([0], [0], marker='o', color='red', lw=0, - label=r'p < 10e-5', markersize=10, - markeredgecolor='k'), - matplotlib.lines.Line2D([0], [0], marker='o', color='#FF7F50', - lw=0, label=r'10e-5 $\leq$ p < 10e-4', - markersize=10, markeredgecolor='k'), - matplotlib.lines.Line2D([0], [0], marker='o', color='gold', lw=0, - label=r'10e-4 $\leq$ p < 10e-3', - markersize=10, markeredgecolor='k'), - matplotlib.lines.Line2D([0], [0], marker='o', color='white', lw=0, - label=r'10e-3 $\leq$ p < 0.0125', - markersize=10, markeredgecolor='k'), - matplotlib.lines.Line2D([0], [0], marker='o', color='skyblue', - lw=0, label=r'0.0125 $\leq$ p < 0.025', - markersize=10, markeredgecolor='k'), - matplotlib.lines.Line2D([0], [0], marker='o', color='blue', lw=0, - label=r'p $\geq$ 0.025', markersize=10, - markeredgecolor='k')] - ax.legend(handles=legend_elements, loc=4, fontsize=13, edgecolor='k') + matplotlib.lines.Line2D( + [0], + [0], + marker="o", + color="red", + lw=0, + label=r"p < 10e-5", + markersize=10, + markeredgecolor="k", + ), + matplotlib.lines.Line2D( + [0], + [0], + marker="o", + color="#FF7F50", + lw=0, + label=r"10e-5 $\leq$ p < 10e-4", + markersize=10, + markeredgecolor="k", + ), + matplotlib.lines.Line2D( + [0], + [0], + marker="o", + color="gold", + lw=0, + label=r"10e-4 $\leq$ p < 10e-3", + markersize=10, + markeredgecolor="k", + ), + matplotlib.lines.Line2D( + [0], + [0], + marker="o", + color="white", + lw=0, + label=r"10e-3 $\leq$ p < 0.0125", + markersize=10, + markeredgecolor="k", + ), + matplotlib.lines.Line2D( + [0], + [0], + marker="o", + color="skyblue", + lw=0, + label=r"0.0125 $\leq$ p < 0.025", + markersize=10, + markeredgecolor="k", + ), + matplotlib.lines.Line2D( + [0], + [0], + marker="o", + color="blue", + lw=0, + label=r"p $\geq$ 0.025", + markersize=10, + markeredgecolor="k", + ), + ] + ax.legend(handles=legend_elements, loc=4, fontsize=13, edgecolor="k") # Act on Negative binomial tests - if test_results[0].name == 'NBD N-Test': + if test_results[0].name == "NBD N-Test": if var is None: - raise ValueError( - "var must not be None if N-tests use the NBD distribution.") + raise ValueError("var must not be None if N-tests use the NBD distribution.") for i in range(len(test_results)): mean = test_results[i].test_distribution[1] upsilon = 1.0 - ((variance - mean) / variance) - tau = (mean ** 2 / (variance - mean)) - phigh97 = scipy.stats.nbinom.ppf( - (1 - percentile / 100.) / 2., tau, upsilon - ) + tau = mean**2 / (variance - mean) + phigh97 = scipy.stats.nbinom.ppf((1 - percentile / 100.0) / 2.0, tau, upsilon) plow97 = scipy.stats.nbinom.ppf( - 1 - (1 - percentile / 100.) / 2., tau, upsilon + 1 - (1 - percentile / 100.0) / 2.0, tau, upsilon ) low97 = test_results[i].observed_statistic - plow97 high97 = phigh97 - test_results[i].observed_statistic - ax.errorbar(test_results[i].observed_statistic, - (len(test_results) - 1) - i, - xerr=numpy.array([[low97, high97]]).T, capsize=4, - color='slategray', alpha=1.0, zorder=0) - p_values.append(test_results[i].quantile[ - 1] * 2.0) # Calculated p-values according to Meletti et al., (2021) + ax.errorbar( + test_results[i].observed_statistic, + (len(test_results) - 1) - i, + xerr=numpy.array([[low97, high97]]).T, + capsize=4, + color="slategray", + alpha=1.0, + zorder=0, + ) + p_values.append( + test_results[i].quantile[1] * 2.0 + ) # Calculated p-values according to Meletti et al., (2021) if p_values[i] < 10e-5: - ax.plot(test_results[i].observed_statistic, - (len(test_results) - 1) - i, marker='o', - color='red', markersize=8, zorder=2) + ax.plot( + test_results[i].observed_statistic, + (len(test_results) - 1) - i, + marker="o", + color="red", + markersize=8, + zorder=2, + ) if p_values[i] >= 10e-5 and p_values[i] < 10e-4: - ax.plot(test_results[i].observed_statistic, - (len(test_results) - 1) - i, marker='o', - color='#FF7F50', markersize=8, zorder=2) + ax.plot( + test_results[i].observed_statistic, + (len(test_results) - 1) - i, + marker="o", + color="#FF7F50", + markersize=8, + zorder=2, + ) if p_values[i] >= 10e-4 and p_values[i] < 10e-3: - ax.plot(test_results[i].observed_statistic, - (len(test_results) - 1) - i, marker='o', - color='gold', markersize=8, zorder=2) + ax.plot( + test_results[i].observed_statistic, + (len(test_results) - 1) - i, + marker="o", + color="gold", + markersize=8, + zorder=2, + ) if p_values[i] >= 10e-3 and p_values[i] < 0.0125: - ax.plot(test_results[i].observed_statistic, - (len(test_results) - 1) - i, marker='o', - color='white', markersize=8, zorder=2) + ax.plot( + test_results[i].observed_statistic, + (len(test_results) - 1) - i, + marker="o", + color="white", + markersize=8, + zorder=2, + ) if p_values[i] >= 0.0125 and p_values[i] < 0.025: - ax.plot(test_results[i].observed_statistic, - (len(test_results) - 1) - i, marker='o', - color='skyblue', markersize=8, zorder=2) + ax.plot( + test_results[i].observed_statistic, + (len(test_results) - 1) - i, + marker="o", + color="skyblue", + markersize=8, + zorder=2, + ) if p_values[i] >= 0.025: - ax.plot(test_results[i].observed_statistic, - (len(test_results) - 1) - i, marker='o', - color='blue', markersize=8, zorder=2) + ax.plot( + test_results[i].observed_statistic, + (len(test_results) - 1) - i, + marker="o", + color="blue", + markersize=8, + zorder=2, + ) # Act on Poisson N-test - if test_results[0].name == 'Poisson N-Test': + if test_results[0].name == "Poisson N-Test": for i in range(len(test_results)): - plow97 = scipy.stats.poisson.ppf((1 - percentile / 100.) / 2., - test_results[ - i].test_distribution[1]) + plow97 = scipy.stats.poisson.ppf( + (1 - percentile / 100.0) / 2.0, test_results[i].test_distribution[1] + ) phigh97 = scipy.stats.poisson.ppf( - 1 - (1 - percentile / 100.) / 2., - test_results[i].test_distribution[1]) + 1 - (1 - percentile / 100.0) / 2.0, test_results[i].test_distribution[1] + ) low97 = test_results[i].observed_statistic - plow97 high97 = phigh97 - test_results[i].observed_statistic - ax.errorbar(test_results[i].observed_statistic, - (len(test_results) - 1) - i, - xerr=numpy.array([[low97, high97]]).T, capsize=4, - color='slategray', alpha=1.0, zorder=0) + ax.errorbar( + test_results[i].observed_statistic, + (len(test_results) - 1) - i, + xerr=numpy.array([[low97, high97]]).T, + capsize=4, + color="slategray", + alpha=1.0, + zorder=0, + ) p_values.append(test_results[i].quantile[1] * 2.0) if p_values[i] < 10e-5: - ax.plot(test_results[i].observed_statistic, - (len(test_results) - 1) - i, marker='o', - color='red', markersize=8, zorder=2) + ax.plot( + test_results[i].observed_statistic, + (len(test_results) - 1) - i, + marker="o", + color="red", + markersize=8, + zorder=2, + ) elif p_values[i] >= 10e-5 and p_values[i] < 10e-4: - ax.plot(test_results[i].observed_statistic, - (len(test_results) - 1) - i, marker='o', - color='#FF7F50', markersize=8, zorder=2) + ax.plot( + test_results[i].observed_statistic, + (len(test_results) - 1) - i, + marker="o", + color="#FF7F50", + markersize=8, + zorder=2, + ) elif p_values[i] >= 10e-4 and p_values[i] < 10e-3: - ax.plot(test_results[i].observed_statistic, - (len(test_results) - 1) - i, marker='o', - color='gold', markersize=8, zorder=2) + ax.plot( + test_results[i].observed_statistic, + (len(test_results) - 1) - i, + marker="o", + color="gold", + markersize=8, + zorder=2, + ) elif p_values[i] >= 10e-3 and p_values[i] < 0.0125: - ax.plot(test_results[i].observed_statistic, - (len(test_results) - 1) - i, marker='o', - color='white', markersize=8, zorder=2) + ax.plot( + test_results[i].observed_statistic, + (len(test_results) - 1) - i, + marker="o", + color="white", + markersize=8, + zorder=2, + ) elif p_values[i] >= 0.0125 and p_values[i] < 0.025: - ax.plot(test_results[i].observed_statistic, - (len(test_results) - 1) - i, marker='o', - color='skyblue', markersize=8, zorder=2) + ax.plot( + test_results[i].observed_statistic, + (len(test_results) - 1) - i, + marker="o", + color="skyblue", + markersize=8, + zorder=2, + ) elif p_values[i] >= 0.025: - ax.plot(test_results[i].observed_statistic, - (len(test_results) - 1) - i, marker='o', - color='blue', markersize=8, zorder=2) + ax.plot( + test_results[i].observed_statistic, + (len(test_results) - 1) - i, + marker="o", + color="blue", + markersize=8, + zorder=2, + ) # Operate on all other consistency tests else: for i in range(len(test_results)): @@ -2076,698 +1941,397 @@ def plot_pvalues_and_intervals(test_results, ax, var=None): phigh97 = numpy.percentile(test_results[i].test_distribution, 97.5) low97 = test_results[i].observed_statistic - plow97 high97 = phigh97 - test_results[i].observed_statistic - ax.errorbar(test_results[i].observed_statistic, - (len(test_results) - 1) - i, - xerr=numpy.array([[low97, high97]]).T, capsize=4, - color='slategray', alpha=1.0, zorder=0) + ax.errorbar( + test_results[i].observed_statistic, + (len(test_results) - 1) - i, + xerr=numpy.array([[low97, high97]]).T, + capsize=4, + color="slategray", + alpha=1.0, + zorder=0, + ) p_values.append(test_results[i].quantile) if p_values[i] < 10e-5: - ax.plot(test_results[i].observed_statistic, - (len(test_results) - 1) - i, marker='o', color='red', - markersize=8, zorder=2) + ax.plot( + test_results[i].observed_statistic, + (len(test_results) - 1) - i, + marker="o", + color="red", + markersize=8, + zorder=2, + ) elif p_values[i] >= 10e-5 and p_values[i] < 10e-4: - ax.plot(test_results[i].observed_statistic, - (len(test_results) - 1) - i, marker='o', - color='#FF7F50', markersize=8, zorder=2) + ax.plot( + test_results[i].observed_statistic, + (len(test_results) - 1) - i, + marker="o", + color="#FF7F50", + markersize=8, + zorder=2, + ) elif p_values[i] >= 10e-4 and p_values[i] < 10e-3: - ax.plot(test_results[i].observed_statistic, - (len(test_results) - 1) - i, marker='o', color='gold', - markersize=8, zorder=2) + ax.plot( + test_results[i].observed_statistic, + (len(test_results) - 1) - i, + marker="o", + color="gold", + markersize=8, + zorder=2, + ) elif p_values[i] >= 10e-3 and p_values[i] < 0.025: - ax.plot(test_results[i].observed_statistic, - (len(test_results) - 1) - i, marker='o', color='white', - markersize=8, zorder=2) + ax.plot( + test_results[i].observed_statistic, + (len(test_results) - 1) - i, + marker="o", + color="white", + markersize=8, + zorder=2, + ) elif p_values[i] >= 0.025 and p_values[i] < 0.05: - ax.plot(test_results[i].observed_statistic, - (len(test_results) - 1) - i, marker='o', - color='skyblue', markersize=8, zorder=2) + ax.plot( + test_results[i].observed_statistic, + (len(test_results) - 1) - i, + marker="o", + color="skyblue", + markersize=8, + zorder=2, + ) elif p_values[i] >= 0.05: - ax.plot(test_results[i].observed_statistic, - (len(test_results) - 1) - i, marker='o', color='blue', - markersize=8, zorder=2) + ax.plot( + test_results[i].observed_statistic, + (len(test_results) - 1) - i, + marker="o", + color="blue", + markersize=8, + zorder=2, + ) legend_elements = [ - matplotlib.lines.Line2D([0], [0], marker='o', color='red', lw=0, - label=r'p < 10e-5', markersize=10, - markeredgecolor='k'), - matplotlib.lines.Line2D([0], [0], marker='o', color='#FF7F50', - lw=0, label=r'10e-5 $\leq$ p < 10e-4', - markersize=10, markeredgecolor='k'), - matplotlib.lines.Line2D([0], [0], marker='o', color='gold', lw=0, - label=r'10e-4 $\leq$ p < 10e-3', - markersize=10, markeredgecolor='k'), - matplotlib.lines.Line2D([0], [0], marker='o', color='white', lw=0, - label=r'10e-3 $\leq$ p < 0.025', - markersize=10, markeredgecolor='k'), - matplotlib.lines.Line2D([0], [0], marker='o', color='skyblue', - lw=0, label=r'0.025 $\leq$ p < 0.05', - markersize=10, markeredgecolor='k'), - matplotlib.lines.Line2D([0], [0], marker='o', color='blue', lw=0, - label=r'p $\geq$ 0.05', markersize=10, - markeredgecolor='k')] - - ax.legend(handles=legend_elements, loc=4, fontsize=13, edgecolor='k') + matplotlib.lines.Line2D( + [0], + [0], + marker="o", + color="red", + lw=0, + label=r"p < 10e-5", + markersize=10, + markeredgecolor="k", + ), + matplotlib.lines.Line2D( + [0], + [0], + marker="o", + color="#FF7F50", + lw=0, + label=r"10e-5 $\leq$ p < 10e-4", + markersize=10, + markeredgecolor="k", + ), + matplotlib.lines.Line2D( + [0], + [0], + marker="o", + color="gold", + lw=0, + label=r"10e-4 $\leq$ p < 10e-3", + markersize=10, + markeredgecolor="k", + ), + matplotlib.lines.Line2D( + [0], + [0], + marker="o", + color="white", + lw=0, + label=r"10e-3 $\leq$ p < 0.025", + markersize=10, + markeredgecolor="k", + ), + matplotlib.lines.Line2D( + [0], + [0], + marker="o", + color="skyblue", + lw=0, + label=r"0.025 $\leq$ p < 0.05", + markersize=10, + markeredgecolor="k", + ), + matplotlib.lines.Line2D( + [0], + [0], + marker="o", + color="blue", + lw=0, + label=r"p $\geq$ 0.05", + markersize=10, + markeredgecolor="k", + ), + ] + + ax.legend(handles=legend_elements, loc=4, fontsize=13, edgecolor="k") return ax -def plot_concentration_ROC_diagram(forecast, catalog, linear=True, axes=None, plot_uniform=True, savepdf=True, - savepng=True, show=True, - plot_args=None): - """ - Plot Receiver operating characteristic (ROC) Curves based on forecast and test catalog. - - The ROC is computed following this procedure: - (1) Obtain spatial rates from GriddedForecast - (2) Rank the rates in descending order (highest rates first). - (3) Sort forecasted rates by ordering found in (2), and normalize rates so the cumulative sum equals unity. - (4) Obtain binned spatial rates from observed catalog - (5) Sort gridded observed rates by ordering found in (2), and normalize so the cumulative sum equals unity. - (6) Compute spatial bin areas, sort by ordering found in (2), and normalize so the cumulative sum equals unity. - (7) Plot ordered and cumulated rates (forecast and catalog) against ordered and cumulated bin areas. - - Note that: - (1) The testing catalog and forecast should have exactly the same time-window (duration) - (2) Forecasts should be defined over the same region - (3) If calling this function multiple times, update the color in plot_args - - Args: - forecast (:class: `csep.forecast.GriddedForecast`): - catalog (:class:`AbstractBaseCatalog`): evaluation catalog - linear: (bool): if true, a linear x-axis is used; if false a logarithmic x-axis is used. - axes (:class:`matplotlib.pyplot.ax`): Previously defined ax object - savepdf (str): output option of pdf file - savepng (str): output option of png file - plot_uniform (bool): if true, include uniform forecast on plot - - Optional plotting arguments: - * figsize: (:class:`list`/:class:`tuple`) - default: [9, 8] - * forecast_linecolor: (:class:`str`) - default: 'black' - * title_fontsize: (:class:`float`) Fontsize of the plot title - default: 18 - * forecast_linecolor: (:class:`str`) - default: 'black' - * forecast_linestyle: (:class:`str`) - default: '-' - * observed_linecolor: (:class:`str`) - default: 'blue' - * observed_linestyle: (:class:`str`) - default: '-' - * forecast_label: (:class:`str`) - default: Observed (Forecast) - * legend_fontsize: (:class:`float`) Fontsize of the plot title - default: 16 - * legend_loc: (:class:`str`) - default: 'upper left' - * title_fontsize: (:class:`float`) Fontsize of the plot title - default: 18 - * label_fontsize: (:class:`float`) Fontsize of the plot title - default: 14 - * title: (:class:`str`) - default: 'ROC Curve' - * filename: (:class:`str`) - default: roc_curve. - - Returns: - :class:`matplotlib.pyplot.ax` object - - Raises: - TypeError: throws error if CatalogForecast-like object is provided - RuntimeError: throws error if Catalog and Forecast do not have the same region +def _autosize_scatter(markersize, values, scale): + if isinstance(scale, (int, float)): + # return (values - min(values) + markersize) ** scale # Adjust this formula as needed for better visualization + # return mark0ersize * (1 + (values - numpy.min(values)) / (numpy.max(values) - numpy.min(values)) ** scale) + return markersize / (scale ** min(values)) * numpy.power(values, scale) - Written by Han Bao, UCLA, March 2021. Modified June 2021. - Modified by Emanuele Biondini, University of Bologna, May 2024. - """ - if not catalog.region == forecast.region: - raise RuntimeError( - "catalog region and forecast region must be identical.") - - # Parse plotting arguments - plot_args = plot_args or {} - figsize = plot_args.get('figsize', (9, 8)) - forecast_linecolor = plot_args.get('forecast_linecolor', 'black') - forecast_linestyle = plot_args.get('forecast_linestyle', '-') - observed_linecolor = plot_args.get('observed_linecolor', 'blue') - observed_linestyle = plot_args.get('observed_linestyle', '-') - legend_fontsize = plot_args.get('legend_fontsize', 16) - legend_loc = plot_args.get('legend_loc', 'upper left') - title_fontsize = plot_args.get('title_fontsize', 18) - label_fontsize = plot_args.get('label_fontsize', 14) - filename = plot_args.get('filename', 'roc_figure') - title = plot_args.get('title', 'Concentration ROC Curve') - - # Plot catalog ordered by forecast rates - name = forecast.name - if not name: - name = '' + elif isinstance(scale, (numpy.ndarray, list)): + return scale else: - name = f'({name})' + raise ValueError("scale data type not supported") - forecast_label = plot_args.get('forecast_label', f'Forecast {name}') - observed_label = plot_args.get('observed_label', f'Observed {name}') - # Initialize figure - if axes is not None: - ax = axes +def _size_map(markersize, values, scale): + if isinstance(scale, (int, float)): + return markersize / (scale ** min(values)) * numpy.power(values, scale) + elif isinstance(scale, (numpy.ndarray, list)): + return scale else: - fig, ax = pyplot.subplots(figsize=figsize) + raise ValueError("Scale data type not supported") - # This part could be vectorized if optimizations become necessary - # Initialize array to store cell area in km^2 - area_km2 = catalog.region.get_cell_area() - obs_counts = catalog.spatial_counts() - # Obtain rates (or counts) aggregated in spatial cells - # If CatalogForecast, needs expected rates. Might take some time to compute. - rate = forecast.spatial_counts() - - # Get index of rates (descending sort) - I = numpy.argsort(rate) - I = numpy.flip(I) +def _autoscale_histogram(ax: pyplot.Axes, bin_edges, simulated, observation, mass=99.5): - # Order forecast and cells rates by highest rate cells first - fore_norm_sorted = numpy.cumsum(rate[I]) / numpy.sum(rate) - area_norm_sorted = numpy.cumsum(area_km2[I]) / numpy.sum(area_km2) + upper_xlim = numpy.percentile(simulated, 100 - (100 - mass) / 2) + upper_xlim = numpy.max([upper_xlim, numpy.max(observation)]) + d_bin = bin_edges[1] - bin_edges[0] + upper_xlim = upper_xlim + 2 * d_bin - # Compute normalized and sorted rates of observations - obs_norm_sorted = numpy.cumsum(obs_counts[I]) / numpy.sum(obs_counts) + lower_xlim = numpy.percentile(simulated, (100 - mass) / 2) + lower_xlim = numpy.min([lower_xlim, numpy.min(observation)]) + lower_xlim = lower_xlim - 2 * d_bin - # Plot uniform forecast - if plot_uniform: - ax.plot(area_norm_sorted, area_norm_sorted, 'k--', label='Uniform') - - # Plot sorted and normalized forecast (descending order) - ax.plot(area_norm_sorted, fore_norm_sorted, - label=forecast_label, - color=forecast_linecolor, - linestyle=forecast_linestyle) - - # Plot cell-wise rates of observed catalog ordered by forecast rates (descending order) - ax.step(area_norm_sorted, obs_norm_sorted, - label=observed_label, - color=observed_linecolor, - linestyle=observed_linestyle) - - # Plotting arguments - ax.set_ylabel("True Positive Rate", fontsize=label_fontsize) - ax.set_xlabel('False Positive Rate (Normalized Area)', - fontsize=label_fontsize) - if linear==True: - legend_loc=plot_args.get('legend_loc', 'lower right') - elif linear==False: - ax.set_xscale('log') + try: + ax.set_xlim([lower_xlim, upper_xlim]) + except ValueError: + print("Ignoring observation in axis scaling because inf or -inf") + upper_xlim = numpy.percentile(simulated, 99.75) + upper_xlim = upper_xlim + 2 * d_bin - ax.legend(loc=legend_loc, shadow=True, fontsize=legend_fontsize) - ax.set_title(title, fontsize=title_fontsize) + lower_xlim = numpy.percentile(simulated, 0.25) + lower_xlim = lower_xlim - 2 * d_bin - if filename: - if savepdf: - outFile = "{}.pdf".format(filename) - pyplot.savefig(outFile, format='pdf') - if savepng: - outFile = "{}.png".format(filename) - pyplot.savefig(outFile, format='png') + ax.set_xlim([lower_xlim, upper_xlim]) - if show: - pyplot.show() return ax -def plot_ROC_diagram(forecast, catalog, linear=True, axes=None, plot_uniform=True, savepdf=True, savepng=True, show=True, - plot_args=None): - """ - Plot Receiver operating characteristic (ROC) based on forecast and test catalogs using the contingency table. - The ROC is computed following this procedure: - (1) Obtain spatial rates from GriddedForecast and the observed events from the observed catalog. - (2) Rank the rates in descending order (highest rates first). - (3) Sort forecasted rates by ordering found in (2), and normalize rates so their sum is equals unity. - (4) Obtain binned spatial rates from observed catalog - (5) Sort gridded observed rates by ordering found in (2). - (6) Test each ordered and normalized forecasted rate defined in (3) as a threshold value to obtain the - corresponding contingency table. - (7) Define the H (Success rate) and F (False alarm rate) for each threshold soil using the information provided - by the correspondent contingency table defined in (6). - - Note that: - (1) The testing catalog and forecast should have exactly the same time-window (duration) - (2) Forecasts should be defined over the same region - (3) If calling this function multiple times, update the color in plot_args - (4) The user can choose the x-scale (linear or log), see the Args section below - - Args: - forecast (:class: `csep.forecast.GriddedForecast`): - catalog (:class:`AbstractBaseCatalog`): evaluation catalog - linear: (bool): if true, a linear x-axis is used; if false a logarithmic x-axis is used. - axes (:class:`matplotlib.pyplot.ax`): Previously defined ax object - savepdf (str): output option of pdf file - savepng (str): output option of png file - plot_uniform (bool): if true, include uniform forecast on plot - - Optional plotting arguments: - * figsize: (:class:`list`/:class:`tuple`) - default: [9, 8] - * forecast_linestyle: (:class:`str`) - default: '-' - * legend_fontsize: (:class:`float`) Fontsize of the plot title - default: 16 - * legend_loc: (:class:`str`) - default: 'upper left' - * title_fontsize: (:class:`float`) Fontsize of the plot title - default: 18 - * label_fontsize: (:class:`float`) Fontsize of the plot title - default: 14 - * title: (:class:`str`) - default: ROC Curve from contingency table - * filename: (:class:`str`) - default: contingency_roc_figure. - - Returns: - :class:`matplotlib.pyplot.ax` object - - Raises: - TypeError: throws error if CatalogForecast-like object is provided - RuntimeError: throws error if Catalog and Forecast do not have the same region - - Written by Emanuele Biondini, UNIBO, March 2023. - """ - if not catalog.region == forecast.region: - raise RuntimeError( - "catalog region and forecast region must be identical.") - - # Parse plotting arguments - plot_args = plot_args or {} - figsize = plot_args.get('figsize', (9, 8)) - forecast_linestyle = plot_args.get('forecast_linestyle', '-') - legend_fontsize = plot_args.get('legend_fontsize', 16) - legend_loc = plot_args.get('legend_loc', 'upper left') - title_fontsize = plot_args.get('title_fontsize', 16) - label_fontsize = plot_args.get('label_fontsize', 14) - title = plot_args.get('title', 'ROC Curve from contingency table') - filename = plot_args.get('filename', 'contingency_roc_figure') - - # Initialize figure - if axes is not None: - ax = axes - else: - fig, ax = pyplot.subplots(figsize=figsize) - - name = forecast.name - if not name: - name = '' - else: - name = f'{name}' - - forecast_label = plot_args.get('forecast_label', f'{name}') - observed_label = plot_args.get('observed_label', f'{name}') - - # Obtain forecast rates (or counts) and observed catalog aggregated in spatial cells - rate = forecast.spatial_counts() - obs_counts = catalog.spatial_counts() - # Define the threshold to be analysed to compile the contingency table and draw the ROC curve - - # Get index of rates (descending sort) - I = numpy.argsort(rate) - I = numpy.flip(I) - - # Order forecast and cells rates by highest rate cells first and normalize the rates. - thresholds = (rate[I]) / numpy.sum(rate) - obs_counts = obs_counts[I] - - Table_ROC = pandas.DataFrame({ - 'Threshold': [], - 'Successful_bins': [], - 'Obs_active_bins': [], - 'H': [], - 'F': [] +def _annotate_distribution_plot( + ax, evaluation_result, auto_annotate, plot_args +) -> matplotlib.axes.Axes: + """Returns specific plot details based on the type of evaluation_result.""" + + annotation_text = None + annotation_xy = None + title = None + xlabel = None + ylabel = None + + if auto_annotate: + if evaluation_result.name == "Catalog N-Test": + xlabel = "Event Count" + ylabel = "Number of Catalogs" + title = f"{evaluation_result.name}: {evaluation_result.sim_name}" + annotation_xy = (0.5, 0.3) + if isinstance(evaluation_result.quantile, (list, np.ndarray)): + annotation_text = ( + f"$\\delta_1 = P(X \\geq x) = {evaluation_result.quantile[0]:.2f}$\n" + f"$\\delta_2 = P(X \\leq x) = {evaluation_result.quantile[1]:.2f}$\n" + f"$\\omega = {evaluation_result.observed_statistic:.2f}$" + ) + else: + annotation_text = ( + f"$\\gamma = P(X \\leq x) = {evaluation_result.quantile:.2f}$\n" + f"$\\omega = {evaluation_result.observed_statistic:.2f}$" + ) - }) + elif evaluation_result.name == "Catalog S-Test": + xlabel = "Normalized Spatial Statistic" + ylabel = "Number of Catalogs" + title = f"{evaluation_result.name}: {evaluation_result.sim_name}" + annotation_xy = (0.2, 0.6) + annotation_text = ( + f"$\\gamma = P(X \\leq x) = {numpy.array(evaluation_result.quantile).ravel()[-1]:.2f}$\n" + f"$\\omega = {evaluation_result.observed_statistic:.2f}$" + ) + + elif evaluation_result.name == "Catalog M-Test": + xlabel = "Magnitude" + ylabel = "Number of Catalogs" + title = f"{evaluation_result.name}: {evaluation_result.sim_name}" + annotation_xy = (0.55, 0.6) + annotation_text = ( + f"$\\gamma = P(X \\geq x) = {numpy.array(evaluation_result.quantile).ravel()[0]:.2f}$\n" + f"$\\omega = {evaluation_result.observed_statistic:.2f}$" + ) + elif evaluation_result.name == "Catalog PL-Test": + xlabel = "Likelihood" + ylabel = "Number of Catalogs" + title = f"{evaluation_result.name}: {evaluation_result.sim_name}" + annotation_xy = (0.55, 0.3) + annotation_text = ( + f"$\\gamma = P(X \\leq x) = {numpy.array(evaluation_result.quantile).ravel()[-1]:.2f}$\n" + f"$\\omega = {evaluation_result.observed_statistic:.2f}$" + ) - #Each forecasted and normalized rate are tested as a threshold value to define the contingency table. - for threshold in thresholds: - threshold = float(threshold) + else: + xlabel = "Statistic" + ylabel = "Number of Catalogs" + + if annotation_text or plot_args.get("annotation_text"): + ax.annotate( + annotation_text or plot_args.get("annotation_text"), + annotation_xy or plot_args.get("annotation_xy"), + xycoords="axes fraction", + fontsize=plot_args.get("annotation_fontsize"), + ) + ax.set_xlabel(plot_args.get("xlabel") or xlabel) + ax.set_ylabel(plot_args.get("ylabel") or ylabel) + ax.set_title(plot_args["title"] or title) - binary_forecast = numpy.where(thresholds >= threshold, 1, 0) - forecastedYes_observedYes = obs_counts[(binary_forecast == 1) & (obs_counts > 0)] - forecastedYes_observedNo=obs_counts[(binary_forecast == 1) & (obs_counts == 0)] - forecastedNo_observedYes=obs_counts[(binary_forecast == 0) & (obs_counts > 0)] - forecastedNo_observedNo = obs_counts[(binary_forecast == 0) & (obs_counts == 0)] - # Creating the DataFrame for the contingency table - data = { - "Observed": [len(forecastedYes_observedYes), len(forecastedNo_observedYes)], - "Not Observed": [len(forecastedYes_observedNo), len(forecastedNo_observedNo)] - } - index = ["Forecasted", "Not Forecasted"] - contingency_df = pandas.DataFrame(data, index=index) + return ax - H = contingency_df.loc['Forecasted', 'Observed'] / ( - contingency_df.loc['Forecasted', 'Observed'] + contingency_df.loc['Not Forecasted', 'Observed']) - F = contingency_df.loc['Forecasted', 'Not Observed'] / ( - contingency_df.loc['Forecasted', 'Not Observed'] + contingency_df.loc[ - 'Not Forecasted', 'Not Observed']) - threshold_row = { - 'Threshold': threshold, - 'Successful_bins': contingency_df.loc['Forecasted', 'Observed'], - 'Obs_active_bins': contingency_df['Observed'].sum(), - 'H': H, - 'F': F +def _calculate_spatial_extent(catalog, set_global, region_border, padding_fraction=0.05): + # todo: perhaps calculate extent also from chained ax object + bbox = catalog.get_bbox() + if region_border: + try: + bbox = catalog.region.get_bbox() + except AttributeError: + pass - } - threshold_row_df = pandas.DataFrame([threshold_row]) + if set_global: + return None - # Concatena threshold_row_df a Table_molchan - Table_ROC = pandas.concat([Table_ROC, threshold_row_df], ignore_index=True) + dh = (bbox[1] - bbox[0]) * padding_fraction + dv = (bbox[3] - bbox[2]) * padding_fraction + return [bbox[0] - dh, bbox[1] + dh, bbox[2] - dv, bbox[3] + dv] - # to start the trajecroy in the poin (0,0) - first_row = pandas.DataFrame({'H': [0], 'F': [0]}) - Table_ROC = pandas.concat([first_row, Table_ROC], ignore_index=True) - # Plot the ROC curve - ax.plot((Table_ROC['F']), (Table_ROC['H']), - label=forecast_label, - color='black', - linestyle=forecast_linestyle) +def _create_geo_axes(figsize, extent, projection, set_global): - # Plot uniform forecast - if plot_uniform: - x_uniform = numpy.arange(0, 1.001, 0.001) - y_uniform = numpy.arange(0, 1.001, 0.001) - ax.plot(x_uniform, y_uniform, linestyle='--', color='gray', label='SUP') - # Plotting arguments - ax.set_ylabel("Hit Rate", fontsize=label_fontsize) - ax.set_xlabel('Fraction of false alarms', fontsize=label_fontsize) + if projection == "approx": + fig = pyplot.figure(figsize=figsize) + ax = fig.add_subplot(111, projection=ccrs.PlateCarree()) + central_latitude = (extent[2] + extent[3]) / 2.0 + # Set plot aspect according to local longitude-latitude ratio in metric units + LATKM = 110.574 # length of a ° of latitude [km] --> ignores Earth's flattening + ax.set_aspect(LATKM / (111.320 * numpy.cos(numpy.deg2rad(central_latitude)))) + else: + fig = pyplot.figure(figsize=figsize) + ax = fig.add_subplot(111, projection=projection) + if set_global: + ax.set_global() + elif extent: + ax.set_extent(extent, crs=ccrs.PlateCarree()) + return ax - if linear==True: - pass - elif linear==False: - ax.set_xscale('log') - ax.set_yscale('linear') - ax.tick_params(axis='x', labelsize=label_fontsize) - ax.tick_params(axis='y', labelsize=label_fontsize) - ax.legend(loc=legend_loc, shadow=True, fontsize=legend_fontsize) - ax.set_title(title, fontsize=title_fontsize) +def _calculate_marker_size(markersize, magnitudes, scale): + mw_range = [min(magnitudes), max(magnitudes)] + if isinstance(scale, (int, float)): + return (markersize / (scale ** mw_range[0])) * numpy.power(magnitudes, scale) + elif isinstance(scale, (numpy.ndarray, list)): + return scale + else: + raise ValueError("Scale data type not supported") - if filename: - if savepdf: - outFile = "{}.pdf".format(filename) - pyplot.savefig(outFile, format='pdf') - if savepng: - outFile = "{}.png".format(filename) - pyplot.savefig(outFile,format='png') +# Helper function to add gridlines +def _add_gridlines(ax, grid_labels, grid_fontsize): + gl = ax.gridlines(draw_labels=grid_labels, alpha=0.5) + gl.right_labels = False + gl.top_labels = False + gl.xlabel_style["fontsize"] = grid_fontsize + gl.ylabel_style["fontsize"] = grid_fontsize + gl.xformatter = LONGITUDE_FORMATTER + gl.yformatter = LATITUDE_FORMATTER - if show: - pyplot.show() - return ax - -def plot_Molchan_diagram(forecast, catalog, linear=True, axes=None, plot_uniform=True, savepdf=True, savepng=True, - show=True, - plot_args=None): +def _define_colormap_and_alpha(cmap, alpha_exp, alpha_0=None): """ - Plot the Molchan Diagram based on forecast and test catalogs using the contingency table. - The Area Skill score and its error are shown in the legend - - The Molchan diagram is computed following this procedure: - (1) Obtain spatial rates from GriddedForecast and the observed events from the observed catalog. - (2) Rank the rates in descending order (highest rates first). - (3) Sort forecasted rates by ordering found in (2), and normalize rates so their sum is equals unity. - (4) Obtain binned spatial rates from observed catalog - (5) Sort gridded observed rates by ordering found in (2). - (6) Test each ordered and normalized forecasted rate defined in (3) as a threshold value to obtain the - corresponding contingency table. - (7) Define the "nu" (Miss rate) and "tau" (Fraction of spatial alarmed cells) for each threshold soil using the - information provided by the correspondent contingency table defined in (6). - - - Note that: - (1) The testing catalog and forecast should have exactly the same time-window (duration) - (2) Forecasts should be defined over the same region - (3) If calling this function multiple times, update the color in plot_args - (4) The user can choose the x-scale (linear or log), see the Args section below + Defines the colormap and applies alpha transparency based on the given parameters. Args: - forecast (:class: `csep.forecast.GriddedForecast`): - catalog (:class:`AbstractBaseCatalog`): evaluation catalog - linear: (bool): if true, a linear x-axis is used; if false a logarithmic x-axis is used. - axes (:class:`matplotlib.pyplot.ax`): Previously defined ax object - savepdf (str): output option of pdf file - savepng (str): output option of png file - plot_uniform (bool): if true, include uniform forecast on plot - - Optional plotting arguments: - * figsize: (:class:`list`/:class:`tuple`) - default: [9, 8] - * forecast_linestyle: (:class:`str`) - default: '-' - * legend_fontsize: (:class:`float`) Fontsize of the plot title - default: 16 - * legend_loc: (:class:`str`) - default: 'lower left' - * title_fontsize: (:class:`float`) Fontsize of the plot title - default: 18 - * label_fontsize: (:class:`float`) Fontsize of the plot title - default: 14 - * title: (:class:`str`) - default: 'Molchan diagram' - * filename: (:class:`str`) - default: molchan_diagram. + cmap (str or matplotlib.colors.Colormap): The colormap to be used. + alpha_0 (float or None): If set, this alpha will be applied uniformly across the colormap. + alpha_exp (float): Exponent to control transparency scaling. If set to 0, no alpha scaling is applied. Returns: - :class:`matplotlib.pyplot.ax` object - - Raises: - TypeError: throws error if CatalogForecast-like object is provided - RuntimeError: throws error if Catalog and Forecast do not have the same region - - Written by Emanuele Biondini, UNIBO, March 2023. + cmap (matplotlib.colors.ListedColormap): The resulting colormap with applied alpha. + alpha (float or None): The alpha value used for the entire colormap, or None if alpha is scaled per color. """ - if not catalog.region == forecast.region: - raise RuntimeError( - "catalog region and forecast region must be identical.") - - # Parse plotting arguments - plot_args = plot_args or {} - figsize = plot_args.get('figsize', (9, 8)) - forecast_linestyle = plot_args.get('forecast_linestyle', '-') - legend_fontsize = plot_args.get('legend_fontsize', 16) - legend_loc = plot_args.get('legend_loc', 'lower left') - title_fontsize = plot_args.get('title_fontsize', 16) - label_fontsize = plot_args.get('label_fontsize', 14) - title = plot_args.get('title', '') - filename = plot_args.get('filename', 'molchan_figure') - # Initialize figure - if axes is not None: - ax = axes - else: - fig, ax = pyplot.subplots(figsize=figsize) - - name = forecast.name - if not name: - name = '' - else: - name = f'{name}' - - forecast_label = plot_args.get('forecast_label', f'{name}') - observed_label = plot_args.get('observed_label', f'{name}') - - # Obtain forecast rates (or counts) and observed catalog aggregated in spatial cells - rate = forecast.spatial_counts() - obs_counts = catalog.spatial_counts() - - # Define the threshold to be analysed tp draw the Molchan diagram - - # Get index of rates (descending sort) - I = numpy.argsort(rate) - I = numpy.flip(I) - - # Order forecast and cells rates by highest rate cells first - thresholds = (rate[I]) / numpy.sum(rate) - obs_counts = obs_counts[I] - - Table_molchan = pandas.DataFrame({ - 'Threshold': [], - 'Successful_bins': [], - 'Obs_active_bins': [], - 'tau': [], - 'nu': [], - 'R_score': [] - }) - - # Each forecasted and normalized rate are tested as a threshold value to define the contingency table. - for threshold in thresholds: - threshold = float(threshold) - - binary_forecast = numpy.where(thresholds >= threshold, 1, 0) - forecastedYes_observedYes = obs_counts[(binary_forecast == 1) & (obs_counts > 0)] - forecastedYes_observedNo = obs_counts[(binary_forecast == 1) & (obs_counts == 0)] - forecastedNo_observedYes = obs_counts[(binary_forecast == 0) & (obs_counts > 0)] - forecastedNo_observedNo = obs_counts[(binary_forecast == 0) & (obs_counts == 0)] - # Creating the DataFrame for the contingency table - data = { - "Observed": [len(forecastedYes_observedYes), len(forecastedNo_observedYes)], - "Not Observed": [len(forecastedYes_observedNo), len(forecastedNo_observedNo)] - } - index = ["Forecasted", "Not Forecasted"] - contingency_df = pandas.DataFrame(data, index=index) - nu = contingency_df.loc['Not Forecasted', 'Observed'] / contingency_df['Observed'].sum() - tau = contingency_df.loc['Forecasted'].sum() / (contingency_df.loc['Forecasted'].sum() + - contingency_df.loc['Not Forecasted'].sum()) - R_score = (contingency_df.loc['Forecasted', 'Observed'] / contingency_df['Observed'].sum()) - \ - (contingency_df.loc['Forecasted', 'Not Observed'] / contingency_df['Not Observed'].sum()) - - threshold_row = { - 'Threshold': threshold, - 'Successful_bins': contingency_df.loc['Forecasted', 'Observed'], - 'Obs_active_bins': contingency_df['Observed'].sum(), - 'tau': tau, - 'nu': nu, - 'R_score': R_score, - - } - threshold_row_df = pandas.DataFrame([threshold_row]) - - Table_molchan = pandas.concat([Table_molchan, threshold_row_df], ignore_index=True) - - bottom_row = {'Threshold': 'Full alarms', 'tau': 1, 'nu': 0, 'Obs_active_bins': contingency_df['Observed'].sum()} - top_row = {'Threshold': 'No alarms', 'tau': 0, 'nu': 1, 'Obs_active_bins': contingency_df['Observed'].sum()} - - Table_molchan = pandas.concat([pandas.DataFrame([top_row]), Table_molchan], ignore_index=True) - - Table_molchan = pandas.concat([Table_molchan, pandas.DataFrame([bottom_row])], ignore_index=True) - - # Computation of Area Skill score (ASS) - Tab_as_score = pandas.DataFrame() - - Tab_as_score['Threshold'] = Table_molchan['Threshold'] - Tab_as_score['tau'] = Table_molchan['tau'] - Tab_as_score['nu'] = Table_molchan['nu'] - - ONE = numpy.ones(len(Tab_as_score)) - Tab_as_score['CUM_BAND'] = cumulative_trapezoid(ONE, Tab_as_score['tau'], initial=0) - cumulative_trapezoid(Tab_as_score['nu'], - Tab_as_score['tau'], - initial=0) - Tab_as_score['AS_score'] = numpy.divide(Tab_as_score['CUM_BAND'], - cumulative_trapezoid(ONE, Tab_as_score['tau'], initial=0) + 1e-10) - Tab_as_score.loc[Tab_as_score.index[-1], 'AS_score'] = max(0.5, Tab_as_score['AS_score'].iloc[-1]) - ASscore = numpy.round(Tab_as_score.loc[Tab_as_score.index[-1], 'AS_score'], 2) - - bin = 0.01 - import math - devstd = numpy.sqrt(1 / (12 * Table_molchan['Obs_active_bins'].iloc[0])) - devstd = devstd * bin ** -1 - devstd = math.ceil(devstd + 0.5) - devstd = devstd / bin ** -1 - Tab_as_score['st_dev'] = devstd - Tab_as_score['st_dev'] = devstd - dev_std = numpy.round(devstd, 2) - - # Plot the Molchan trajectory - - ax.plot(Table_molchan['tau'], Table_molchan['nu'], - label=f"{forecast_label}, ASS={ASscore}±{dev_std} ", - color='black', - linestyle=forecast_linestyle) - - # Plot uniform forecast - if plot_uniform: - x_uniform = numpy.arange(0, 1.001, 0.001) - y_uniform = numpy.arange(1.00, -0.001, -0.001) - ax.plot(x_uniform, y_uniform, linestyle='--', color='gray', label='SUP' + ' ASS=0.50') - - # Plotting arguments - ax.set_ylabel("Miss Rate", fontsize=label_fontsize) - ax.set_xlabel('Fraction of area occupied by alarms', fontsize=label_fontsize) - - if linear == True: - legend_loc = plot_args.get('legend_loc', 'upper right') - elif linear == False: - ax.set_xscale('log') - - ax.tick_params(axis='x', labelsize=label_fontsize) - ax.tick_params(axis='y', labelsize=label_fontsize) - ax.legend(loc=legend_loc, shadow=True, fontsize=legend_fontsize) - ax.set_title(title, fontsize=title_fontsize) - - if filename: - if savepdf: - outFile = "{}.pdf".format(filename) - pyplot.savefig(outFile, format='pdf') - if savepng: - outFile = "{}.png".format(filename) - pyplot.savefig(outFile, format='png') - - if show: - pyplot.show() - return ax + # Get the colormap object if a string is provided + if isinstance(cmap, str): + cmap = matplotlib.pyplot.get_cmap(cmap) + cmap_tup = cmap(numpy.arange(cmap.N)) -def _get_marker_style(obs_stat, p, one_sided_lower): - """Returns matplotlib marker style as fmt string""" - if obs_stat < p[0] or obs_stat > p[1]: - # red circle - fmt = 'ro' + if alpha_0 is not None: + cmap_tup[:, -1] = alpha_0 + alpha = alpha_0 else: - # green square - fmt = 'gs' - if one_sided_lower: - if obs_stat < p[0]: - fmt = 'ro' + if alpha_exp != 0: + cmap_tup[:, -1] = numpy.linspace(0, 1, cmap.N) ** alpha_exp + alpha = None else: - fmt = 'gs' - return fmt - - -def _get_marker_t_color(distribution): - """Returns matplotlib marker style as fmt string""" - if distribution[0] > 0. and distribution[1] > 0.: - fmt = 'green' - elif distribution[0] < 0. and distribution[1] < 0.: - fmt = 'red' - else: - fmt = 'grey' - - return fmt - - -def _get_marker_w_color(distribution, percentile): - """Returns matplotlib marker style as fmt string""" + alpha = 1 - if distribution < (1 - percentile / 100): - fmt = True - else: - fmt = False - - return fmt - - -def _get_axis_limits(pnts, border=0.05): - """Returns a tuple of x_min and x_max given points on plot.""" - x_min = numpy.min(pnts) - x_max = numpy.max(pnts) - xd = (x_max - x_min) * border - return (x_min - xd, x_max + xd) + cmap = matplotlib.colors.ListedColormap(cmap_tup) + return cmap, alpha + + +def _add_colorbar(ax, im, clabel, clabel_fontsize, cticks_fontsize): + fig = ax.get_figure() + cax = fig.add_axes( + [ax.get_position().x1 + 0.01, ax.get_position().y0, 0.025, ax.get_position().height], + label="Colorbar", + ) + cbar = fig.colorbar(im, ax=ax, cax=cax) + cbar.set_label(clabel, fontsize=clabel_fontsize) + cbar.ax.tick_params(labelsize=cticks_fontsize) + + +def _process_stat_distribution(res, percentile, variance, normalize, one_sided_lower): + """Process the distribution based on its type and return plotting values.""" + dist_type = res.test_distribution[0] + + if dist_type == "poisson": + mean = res.test_distribution[1] + plow = scipy.stats.poisson.ppf((1 - percentile / 100.0) / 2.0, mean) + phigh = scipy.stats.poisson.ppf(1 - (1 - percentile / 100.0) / 2.0, mean) + observed_statistic = res.observed_statistic + elif dist_type == "negative_binomial": + mean = res.test_distribution[1] + upsilon = 1.0 - ((variance - mean) / variance) + tau = mean**2 / (variance - mean) + plow = scipy.stats.nbinom.ppf((1 - percentile / 100.0) / 2.0, tau, upsilon) + phigh = scipy.stats.nbinom.ppf(1 - (1 - percentile / 100.0) / 2.0, tau, upsilon) + observed_statistic = res.observed_statistic -def _get_basemap(basemap): - if basemap == 'stamen_terrain': - tiles = img_tiles.Stamen('terrain') - elif basemap == 'stamen_terrain-background': - tiles = img_tiles.Stamen('terrain-background') - elif basemap == 'google-satellite': - tiles = img_tiles.GoogleTiles(style='satellite') - elif basemap == 'ESRI_terrain': - webservice = 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Terrain_Base/' \ - 'MapServer/tile/{z}/{y}/{x}.jpg' - tiles = img_tiles.GoogleTiles(url=webservice) - elif basemap == 'ESRI_imagery': - webservice = 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/' \ - 'MapServer/tile/{z}/{y}/{x}.jpg' - tiles = img_tiles.GoogleTiles(url=webservice) - elif basemap == 'ESRI_relief': - webservice = 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/' \ - 'MapServer/tile/{z}/{y}/{x}.jpg' - tiles = img_tiles.GoogleTiles(url=webservice) - elif basemap == 'ESRI_topo': - webservice = 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/' \ - 'MapServer/tile/{z}/{y}/{x}.jpg' - tiles = img_tiles.GoogleTiles(url=webservice) else: - try: - webservice = basemap - tiles = img_tiles.GoogleTiles(url=webservice) - except: - raise ValueError('Basemap type not valid or not implemented') - - return tiles - + if normalize: + test_distribution = numpy.array(res.test_distribution) - res.observed_statistic + observed_statistic = 0 + else: + test_distribution = numpy.array(res.test_distribution) + observed_statistic = res.observed_statistic -def add_labels_for_publication(figure, style='bssa', labelsize=16): - """ Adds publication labels too the outside of a figure. """ - all_axes = figure.get_axes() - ascii_iter = iter(string.ascii_lowercase) - for ax in all_axes: - # check for colorbar and ignore for annotations - if ax.get_label() == 'Colorbar': - continue - annot = next(ascii_iter) - if style == 'bssa': - ax.annotate(f'({annot})', (0.025, 1.025), xycoords='axes fraction', - fontsize=labelsize) + if one_sided_lower: + plow = numpy.percentile(test_distribution, 100 - percentile) + phigh = numpy.percentile(test_distribution, 100) + else: + plow = numpy.percentile(test_distribution, (100 - percentile) / 2.0) + phigh = numpy.percentile(test_distribution, 100 - (100 - percentile) / 2.0) + mean = numpy.mean(test_distribution) - return + return plow, phigh, mean, observed_statistic diff --git a/examples/tutorials/gridded_forecast_evaluation.py b/examples/tutorials/gridded_forecast_evaluation.py index fd40184f..447569aa 100644 --- a/examples/tutorials/gridded_forecast_evaluation.py +++ b/examples/tutorials/gridded_forecast_evaluation.py @@ -102,8 +102,8 @@ # We provide the function :func:`csep.utils.plotting.plot_poisson_consistency_test` to visualize the evaluation results from # consistency tests. -ax = plots.plot_poisson_consistency_test(spatial_test_result, - plot_args={'xlabel': 'Spatial likelihood'}) +ax = plots.plot_consistency_test(spatial_test_result, + plot_args={'xlabel': 'Spatial likelihood'}) plt.show() #################################################################################################################################### diff --git a/examples/tutorials/plot_customizations.py b/examples/tutorials/plot_customizations.py index 87e4de2c..88ccec79 100644 --- a/examples/tutorials/plot_customizations.py +++ b/examples/tutorials/plot_customizations.py @@ -191,7 +191,7 @@ # Description of plot arguments can be found in :func:`plot_poisson_consistency_test`. # We set ``one_sided_lower=True`` as usual for an L-test, where the model is rejected if the observed # is located within the lower tail of the simulated distribution. -ax = plots.plot_poisson_consistency_test(L_results, one_sided_lower=True, plot_args=args) +ax = plots.plot_consistency_test(L_results, one_sided_lower=True, plot_args=args) # Needed to show plots if running as script plt.show() diff --git a/tests/artifacts/example_csep2_forecasts/Catalog/catalog.json b/tests/artifacts/example_csep2_forecasts/Catalog/catalog.json new file mode 100644 index 00000000..eada22bd --- /dev/null +++ b/tests/artifacts/example_csep2_forecasts/Catalog/catalog.json @@ -0,0 +1,173 @@ +{ + "catalog": [ + [ + "ci3043549", + 709732845000, + 34.131, + -116.408, + -1.1, + 5.77 + ], + [ + "ci3043630", + 709732876190, + 34.12, + -116.323, + 5.706, + 5.7 + ], + [ + "ci12178451", + 709732936960, + 34.0605, + -116.4726667, + 5.378, + 5.0 + ], + [ + "ci12178455", + 709732951080, + 34.1031667, + -116.4246667, + 5.586, + 5.0 + ], + [ + "ci2056979", + 709735000770, + 34.115, + -116.4263333, + 7.502, + 5.49 + ], + [ + "ci2056980", + 709735253570, + 34.3411667, + -116.5106667, + 4.388, + 5.41 + ], + [ + "ci3031243", + 709739446160, + 34.109, + -116.403, + 4.664, + 4.95 + ], + [ + "ci2057008", + 709742601850, + 34.162, + -116.852, + 9.615, + 5.53 + ], + [ + "ci3031425", + 709743930730, + 34.203, + -116.827, + 3.634, + 6.3 + ], + [ + "ci3031154", + 709750892010, + 34.1788333, + -116.9246667, + 9.226, + 4.98 + ], + [ + "ci3031157", + 709751157560, + 34.255, + -116.912, + 6.553, + 5.26 + ], + [ + "usp00059w1", + 709812862280, + 36.705, + -116.293, + 8.8, + 5.8 + ], + [ + "ci3031935", + 709826917730, + 34.105, + -116.403, + 9.649, + 5.69 + ], + [ + "ci3031615", + 709827218770, + 34.1045, + -116.39, + 11.191, + 5.08 + ], + [ + "ci3032166", + 709915091720, + 33.9971667, + -116.3565, + 1.021, + 4.99 + ], + [ + "ci3032643", + 709976429900, + 34.33, + -116.464, + 5.091, + 5.34 + ], + [ + "ci3035348", + 710371107600, + 34.583, + -116.322, + 4.922, + 5.42 + ], + [ + "ci3041390", + 710878456160, + 35.21, + -118.067, + 9.564, + 5.67 + ], + [ + "ci3046661", + 712001676250, + 33.901, + -116.285, + 7.214, + 4.96 + ] + ], + "catalog_id": null, + "compute_stats": true, + "date_accessed": "2024-08-16 15:10:23.729781+00:00", + "end_time": "1992-07-24 18:14:36.250000+00:00", + "filename": null, + "filters": [], + "format": null, + "max_latitude": 36.705, + "max_longitude": -116.285, + "max_magnitude": 6.3, + "metadata": {}, + "min_latitude": 33.901, + "min_longitude": -118.067, + "min_magnitude": 4.95, + "name": null, + "region": null, + "start_time": "1992-06-28 12:00:45+00:00" +} \ No newline at end of file diff --git a/tests/artifacts/example_csep2_forecasts/Forecasts/ucerf3-landers_short.csv b/tests/artifacts/example_csep2_forecasts/Forecasts/ucerf3-landers_short.csv new file mode 100644 index 00000000..6a4f2849 --- /dev/null +++ b/tests/artifacts/example_csep2_forecasts/Forecasts/ucerf3-landers_short.csv @@ -0,0 +1,2426 @@ +lon,lat,mag,time_string,depth,catalog_id,event_id +-124.56793,40.419548,5.65,1992-07-10T19:10:07.057000,18.083824,0, +-124.56,40.4,6.693793,1992-08-30T16:44:54.183000,21.0,0, +-124.319466,40.21936,5.15,1992-08-30T21:14:55.449000,6.1641793,0, +-116.36257,33.96388,5.25,1992-09-11T14:57:55.473000,0.25818658,0, +-121.804115,35.214355,4.95,1992-11-15T13:46:20.408000,4.7234006,0, +-124.12038,40.24399,4.95,1993-02-10T02:23:33.236000,7.3369,0, +-124.65515,41.067368,5.05,1993-03-13T09:52:26.443000,8.264682,0, +-124.3605,40.236816,5.15,1993-03-14T21:07:07.274000,5.2129073,0, +-124.58436,40.31746,5.25,1993-03-21T01:14:50.159000,6.1258917,0, +-116.47828,34.058193,6.05,1993-03-22T05:54:05.062000,8.345069,0, +-116.53763,34.094604,4.95,1993-03-22T05:57:17.964000,8.776093,0, +-122.32095,40.564854,5.25,1993-04-13T06:33:29.818000,3.3861973,0, +-124.2525,40.34345,5.25,1993-06-05T13:12:33.587000,9.122693,0, +-118.10435,35.739872,5.05,1993-06-20T22:27:26.814000,7.359808,0, +-118.521706,37.463905,5.95,1993-06-21T03:59:07.323000,6.8553424,0, +-118.55879,37.456974,5.05,1993-06-21T03:59:19.998000,5.317263,0, +-118.48898,37.442837,4.95,1993-06-21T06:05:25.118000,4.2579846,0, +-124.37556,40.358555,4.95,1992-07-16T01:02:51.151000,7.405314,1, +-118.79586,38.0308,5.05,1992-07-21T19:00:06.082000,1.1610073,1, +-124.33405,40.260395,5.25,1992-09-26T21:10:46.141000,7.082733,1, +-119.99263,38.573963,5.85,1993-03-01T00:07:22.062000,4.5522327,1, +-120.16515,38.578465,4.95,1993-03-01T00:44:13.907000,2.0563285,1, +-115.64397,32.49147,5.65,1993-03-25T17:38:46.863000,9.608384,1, +-116.9824,33.552574,5.45,1993-04-26T10:04:06.882000,15.802314,1, +-124.553314,40.40729,5.15,1993-06-10T11:01:43.828000,8.766783,1, +-124.48043,40.38163,4.95,1992-07-04T07:45:08.481000,18.54043,2, +-124.48,40.4,6.693793,1992-07-04T12:27:34.937000,19.0,2, +-124.6263,40.33851,5.15,1992-07-04T13:21:00.613000,3.0160804,2, +-124.63463,40.3499,5.05,1992-07-04T14:32:26.801000,6.784469,2, +-124.5001,40.335373,5.05,1992-07-04T21:56:21.607000,21.733051,2, +-124.72429,40.368298,5.55,1992-07-18T15:56:52.203000,2.9509346,2, +-124.73707,40.351444,5.55,1992-08-14T12:10:35.381000,6.0311127,2, +-124.60377,40.23384,5.05,1992-08-22T13:28:55.411000,13.943317,2, +-124.16069,40.42294,5.35,1992-09-29T14:32:11.444000,11.7511835,2, +-115.84815,32.98529,4.95,1993-01-03T03:16:53.241000,10.158423,2, +-113.68977,34.657116,5.05,1993-06-09T04:20:26.762000,8.157414,2, +-124.27569,40.279175,5.35,1992-07-22T21:40:32.243000,7.4590473,3, +-115.800476,31.981258,4.95,1992-10-21T20:42:56.038000,8.201252,3, +-116.31569,36.83416,5.35,1993-02-21T15:43:58.525000,8.59871,3, +-122.02754,37.94564,5.15,1993-05-04T15:38:09.537000,5.763932,3, +-118.76884,37.46628,5.15,1993-05-13T21:01:35.648000,14.59427,3, +-116.930756,33.570526,5.05,1992-09-21T09:16:43.498000,8.338859,4, +-116.335205,34.0406,5.35,1992-10-25T15:23:09.454000,1.6041985,4, +-121.43158,36.56761,4.95,1992-11-12T12:47:10.040000,1.7849816,4, +-117.38229,31.995123,5.923531,1993-01-17T22:05:22.972000,0.9,4, +-115.60687,32.654037,4.95,1993-05-01T14:13:30.254000,10.497245,4, +-124.22349,40.279385,4.95,1992-07-28T09:01:10.017000,10.235089,5, +-124.23469,40.279205,5.65,1992-07-28T12:48:35.256000,10.155748,5, +-124.967896,40.47695,5.15,1992-08-09T03:38:52.657000,11.007629,5, +-121.61517,37.303467,4.95,1992-09-06T06:35:49.372000,11.945657,5, +-118.51425,34.776554,5.35,1992-09-15T17:38:42.973000,6.231831,5, +-120.59202,39.70867,5.45,1992-10-14T12:38:06.678000,5.13096,5, +-120.53528,39.62039,5.55,1992-10-14T22:35:42.537000,6.407091,5, +-122.2293,39.695744,4.95,1993-03-20T01:10:08.873000,8.40151,5, +-121.409676,36.796684,5.05,1993-05-16T18:54:59.317000,11.922865,5, +-124.48888,40.34293,4.95,1993-06-07T04:47:08.061000,20.18112,5, +-124.234604,40.276653,5.65,1992-07-14T08:31:53.889000,7.9110594,6, +-124.54499,40.38445,5.45,1992-07-14T21:59:02.643000,19.732105,6, +-119.66427,40.77507,5.75,1992-10-02T02:32:45.134000,8.184627,6, +-122.260704,37.937,5.95,1993-03-27T22:58:05.524000,4.476187,6, +-122.233284,37.93554,5.85,1993-03-28T00:00:35.917000,5.597117,6, +-116.8341,34.344177,5.15,1992-07-24T23:00:23.075000,14.823363,7, +-124.52627,40.34242,5.65,1992-08-15T20:09:36.214000,21.436798,7, +-124.61737,40.435867,5.85,1992-09-12T02:10:26.027000,10.213113,7, +-122.95275,40.437435,5.15,1992-09-12T05:18:16.595000,5.267299,7, +-124.62,40.34,6.628068,1992-09-12T06:55:05.065000,9.0,7, +-124.49383,40.29057,5.15,1992-09-12T07:05:10.235000,4.961973,7, +-123.53549,39.601177,5.15,1992-09-21T13:37:19.879000,6.3607564,7, +-117.290016,34.128616,5.15,1992-10-17T17:05:09.946000,8.599481,7, +-117.36112,34.652096,5.35,1992-12-02T16:29:39.370000,6.539236,7, +-124.296196,40.378098,5.25,1992-12-05T18:49:37.025000,8.498029,7, +-116.391655,34.101627,4.95,1993-03-17T19:22:18.691000,1.4083573,7, +-116.44205,34.20032,5.75,1992-07-06T09:20:26.062000,0.3854398,8, +-124.49513,40.50934,4.95,1992-08-14T00:43:22.803000,17.226818,8, +-122.69219,38.823563,4.95,1992-08-19T15:30:49.023000,14.820213,8, +-124.23214,40.55948,5.35,1992-08-22T21:13:48.246000,7.9299626,8, +-124.44879,40.744198,6.05,1992-08-22T21:55:01.555000,9.12925,8, +-124.46889,40.699997,5.05,1992-08-22T22:08:59.550000,9.283585,8, +-124.31335,40.796883,5.85,1992-08-23T04:45:07.682000,8.433627,8, +-124.44906,40.741665,5.25,1992-08-25T17:52:27.719000,14.10394,8, +-124.46334,40.723984,5.25,1992-08-26T16:45:22.365000,14.431433,8, +-122.69461,38.83957,5.75,1992-09-02T18:57:32.983000,13.470306,8, +-119.52216,40.377556,4.95,1992-09-18T23:10:45.200000,9.487662,8, +-124.46,40.34,7.4036174,1992-11-15T03:33:43.458000,21.0,8, +-124.115,39.846485,5.15,1992-11-15T03:37:16.918000,4.8344436,8, +-124.00254,39.77458,5.25,1992-11-15T03:40:33.665000,0.15927178,8, +-124.34326,40.21517,5.45,1992-11-15T03:51:32.509000,5.63846,8, +-124.43824,40.270744,5.95,1992-11-15T04:02:12.181000,0.8168236,8, +-124.55266,40.304886,5.05,1992-11-15T04:30:37.873000,6.5134735,8, +-123.79426,39.22772,5.05,1992-11-15T07:46:05.993000,8.360149,8, +-124.04414,39.91104,5.45,1992-11-15T10:09:21.910000,8.925189,8, +-124.186104,40.128723,5.25,1992-11-15T13:26:37.196000,2.883747,8, +-123.984215,39.73832,5.05,1992-11-15T15:11:45.838000,8.207838,8, +-124.1218,40.075474,5.05,1992-11-15T15:56:03.199000,2.0286684,8, +-124.27221,40.120255,5.35,1992-11-16T01:06:05.835000,6.993016,8, +-124.02609,39.7714,4.95,1992-11-17T10:33:28.901000,1.4862379,8, +-124.16621,40.08555,5.25,1992-11-20T13:39:11.678000,10.234785,8, +-124.18948,40.07548,5.45,1992-11-20T13:55:14.913000,9.657006,8, +-123.99855,39.69631,5.15,1992-11-22T14:01:56.075000,5.0647297,8, +-124.4164,40.303,4.95,1992-12-03T02:58:01.072000,3.891474,8, +-123.95575,39.555595,5.15,1992-12-10T20:02:58.144000,6.9166107,8, +-124.1138,40.046535,4.95,1992-12-16T12:10:48.281000,7.1530514,8, +-123.969734,39.654617,5.65,1993-01-04T15:33:20.278000,2.7731018,8, +-123.79329,39.212177,5.45,1993-01-09T19:27:02.673000,3.1404862,8, +-124.068474,40.000523,4.95,1993-01-20T01:07:14.950000,6.9228644,8, +-124.10127,40.027584,5.05,1993-01-23T06:27:04.345000,7.052238,8, +-124.3936,40.182816,5.25,1993-01-30T07:57:54.373000,6.8664675,8, +-115.842545,33.23605,5.35,1993-02-04T18:53:12.755000,4.474577,8, +-124.79855,40.97438,4.95,1993-02-14T05:21:28.658000,10.362736,8, +-124.4927,40.296402,5.35,1993-03-14T07:35:13.474000,5.187454,8, +-124.211716,40.30344,5.15,1993-03-16T09:53:49.209000,9.835393,8, +-124.35334,40.77429,5.05,1993-04-21T14:49:49.367000,7.640023,8, +-118.28413,35.37036,5.85,1993-04-29T19:24:54.759000,6.911575,8, +-124.66,40.3,6.2110257,1993-06-21T21:26:03.211000,13.0,8, +-124.614395,40.33749,5.85,1993-06-22T11:27:50.900000,8.925802,8, +-124.66733,40.357204,5.25,1993-06-23T07:20:22.592000,2.5502052,8, +-115.720634,32.77666,5.55,1992-10-17T15:07:21.357000,7.375868,9, +-116.60389,33.521385,5.55,1992-11-18T13:38:57.349000,8.921251,9, +-116.349724,34.041634,5.45,1992-11-21T10:03:00.823000,15.012485,9, +-116.34548,34.046593,5.55,1992-12-03T06:46:38.618000,12.906937,9, +-124.38484,40.42276,5.55,1993-01-24T00:56:07.594000,9.727561,9, +-124.29032,40.415333,5.25,1993-02-12T16:17:33.982000,8.412599,9, +-115.63517,34.14442,6.3189235,1993-02-23T03:58:46.424000,7.15,9, +-124.80784,41.02246,5.45,1993-02-26T05:57:55.482000,5.3602962,9, +-121.17997,36.719078,5.05,1993-03-20T12:33:41.379000,5.482697,9, +-119.87159,38.61696,5.25,1992-07-27T20:42:18.586000,12.426715,10, +-118.69986,35.201458,5.55,1992-08-27T02:50:48,9.587827,10, +-119.84922,39.195114,5.05,1992-11-13T01:25:33.737000,6.2634783,10, +-124.37389,40.25368,5.15,1992-11-18T14:43:39.633000,6.234989,10, +-124.181335,40.26345,5.15,1992-12-24T08:30:12.587000,10.61828,10, +-124.210754,40.34987,4.95,1993-02-11T07:27:13.647000,11.81832,10, +-121.08222,37.326946,5.55,1993-03-16T08:45:10.620000,7.0841894,10, +-121.11949,37.331326,4.95,1993-03-27T13:05:34.720000,5.6457276,10, +-116.23293,34.026497,4.95,1992-07-24T13:56:23.070000,6.6365914,11, +-116.395454,34.10801,5.25,1992-07-27T07:10:44.898000,6.9571605,11, +-116.25525,34.012993,5.05,1992-08-05T21:38:16.411000,6.4608493,11, +-116.26306,34.019955,4.95,1992-08-05T22:10:00.564000,5.0604844,11, +-121.68727,40.980854,6.252306,1992-08-14T14:11:41.239000,6.57,11, +-121.62346,40.886528,5.05,1992-08-14T19:51:12.478000,2.0290325,11, +-124.24946,40.402832,4.95,1992-10-07T22:14:56.302000,9.452664,11, +-124.38762,40.226913,4.95,1992-11-25T20:06:01.015000,6.0483813,11, +-121.62455,40.87862,5.15,1993-03-29T16:54:51.829000,1.7768915,11, +-116.667694,34.6747,5.95,1993-05-29T18:48:46.417000,5.7281194,11, +-116.70235,34.674755,5.15,1993-05-31T00:01:46.630000,2.1774807,11, +-119.24853,35.129818,5.15,1992-07-23T12:00:44.512000,3.9818645,12, +-124.17286,40.418148,5.55,1992-08-27T02:03:43.040000,10.928483,12, +-119.3166,37.375015,5.15,1992-10-13T09:11:52.490000,0.5544798,12, +-121.9454,36.77706,4.95,1993-05-18T08:09:33.294000,6.6413865,12, +-115.85773,32.93175,4.95,1992-07-06T19:59:50.293000,7.279625,13, +-117.35856,32.749416,4.95,1992-09-09T17:52:49.088000,6.7252483,13, +-120.43678,35.88365,6.0140595,1992-10-30T14:14:32.217000,9.27724,13, +-120.52563,35.951015,5.35,1992-10-30T14:33:05.191000,8.814822,13, +-124.714424,40.409462,5.25,1992-11-23T09:09:16.702000,21.543865,13, +-121.539375,37.13727,4.95,1993-02-20T07:44:05.961000,9.672917,13, +-118.77022,38.06504,5.95,1993-03-12T04:23:43.200000,11.871214,13, +-118.72158,38.042427,5.05,1993-03-17T00:53:57.134000,12.8358,13, +-122.36775,38.02118,5.55,1993-04-04T08:54:25.957000,9.065458,13, +-122.38077,38.018578,4.95,1993-04-04T11:11:15.921000,7.847786,13, +-118.34919,33.785664,5.35,1993-04-18T03:58:05.431000,7.7713704,13, +-124.33737,40.282658,5.45,1992-07-09T17:30:47.496000,6.5053267,14, +-117.87319,32.87485,5.35,1992-07-10T21:23:10.067000,6.085868,14, +-120.23314,36.06497,5.45,1992-07-21T13:41:48.928000,4.8610625,14, +-118.76073,37.485977,4.95,1992-09-30T10:44:38.152000,5.4323225,14, +-116.40919,31.990952,6.05,1992-11-19T10:31:49.515000,10.848535,14, +-116.3166,31.94431,5.55,1992-11-19T13:33:47.870000,6.3593125,14, +-124.48895,40.380634,5.55,1992-12-23T02:28:46.025000,18.263813,14, +-119.976845,35.991226,5.05,1993-05-13T14:43:18.078000,8.604205,14, +-116.5749,34.00077,5.05,1993-05-25T20:32:10.953000,9.668223,14, +-117.9195,37.91763,5.15,1992-07-07T09:47:43.799000,14.918304,15, +-124.118706,40.28226,5.65,1992-07-15T05:05:01.415000,11.842918,15, +-124.10673,40.297955,5.05,1992-07-15T05:30:57.938000,8.6161,15, +-123.95585,39.866196,5.35,1992-09-17T06:46:51.571000,5.716721,15, +-115.87576,33.485153,6.9600973,1992-10-25T16:47:13.469000,3.2694547,15, +-115.76322,32.49108,4.95,1992-10-25T16:47:51.192000,6.1332145,15, +-115.48851,32.829937,5.05,1992-10-25T16:51:31.599000,2.9625604,15, +-115.66246,33.19204,4.95,1992-10-25T16:56:00.969000,10.590029,15, +-115.654526,33.135883,5.25,1992-10-25T22:55:26.175000,7.096471,15, +-115.67324,33.132244,5.35,1992-10-27T05:00:29.755000,7.269377,15, +-115.67066,33.14415,5.75,1992-10-27T05:46:32.355000,6.6411614,15, +-116.01694,33.606873,5.25,1992-11-02T04:54:08.226000,12.138392,15, +-118.485085,36.16602,4.95,1993-01-18T15:29:34.632000,1.8112378,15, +-124.71973,40.537533,5.75,1993-02-16T14:27:46.745000,8.050642,15, +-124.74524,40.523655,5.45,1993-02-16T14:27:55.682000,6.0956016,15, +-124.70672,40.509552,5.05,1993-02-17T05:02:23.993000,5.393781,15, +-124.75132,40.526276,4.95,1993-02-17T09:51:11.975000,7.3973045,15, +-124.69493,40.4994,5.25,1993-02-26T22:15:47.147000,7.22495,15, +-124.12463,40.35841,5.25,1993-03-29T08:04:27.875000,12.040723,15, +-124.13112,40.694645,5.15,1993-04-20T16:19:32.025000,4.192272,15, +-117.78356,32.51345,5.65,1993-06-03T22:12:21.673000,3.552733,15, +-115.5741,33.489483,4.95,1993-06-25T07:54:07.066000,9.917993,15, +-118.34273,33.765587,5.55,1993-03-13T23:39:35.399000,5.753005,16, +-122.11882,37.829956,5.95,1993-05-13T00:30:10.183000,5.371983,16, +-124.17205,40.263664,4.95,1992-07-01T20:43:07.277000,10.525206,17, +-116.83935,33.544815,4.95,1992-08-10T08:32:08.862000,10.802358,17, +-121.152985,36.59359,4.95,1992-08-19T12:35:49.350000,9.625697,17, +-117.60494,34.31095,5.65,1992-11-15T18:18:38.701000,1.044577,17, +-122.226715,36.476494,5.05,1992-11-28T10:20:05.233000,12.553424,17, +-124.33017,40.342754,5.75,1993-03-02T20:01:24.205000,7.6645894,17, +-124.2663,40.16234,4.95,1993-03-03T00:33:34.619000,16.371777,17, +-124.26319,40.16342,5.65,1993-03-03T00:38:29.168000,17.487816,17, +-115.77353,31.85593,5.55,1993-03-14T02:08:19.737000,2.6126041,17, +-121.83308,38.13319,4.95,1993-04-03T12:17:50.834000,0.5245612,17, +-115.860634,32.829678,5.15,1993-04-05T17:13:09.676000,10.638244,17, +-124.39824,40.41158,5.55,1993-04-11T03:05:16.738000,6.019092,17, +-122.72353,39.387157,5.25,1993-05-11T10:15:03.693000,18.297445,17, +-122.71235,39.381664,5.35,1993-05-13T06:31:12.196000,19.606085,17, +-124.23055,40.365772,5.05,1993-05-20T10:41:12.875000,9.8122,17, +-120.94922,34.981636,5.35,1992-07-13T22:35:02.223000,8.441275,18, +-124.36175,40.23098,5.25,1992-08-02T14:26:52.357000,6.3340917,18, +-125.08683,40.761562,5.75,1992-12-11T00:21:35.062000,21.372065,18, +-114.82063,32.242302,5.05,1993-01-28T13:16:43.859000,9.28294,18, +-124.488014,40.369404,5.25,1993-01-31T04:24:38.273000,20.450808,18, +-124.15323,40.32985,5.15,1993-04-28T06:06:21.094000,11.25565,18, +-116.617294,33.57813,5.55,1993-04-29T04:56:46.836000,3.9730408,18, +-124.54713,40.374565,5.05,1992-07-16T16:20:58.039000,19.739613,19, +-124.41349,40.40449,5.15,1992-07-17T02:36:52.269000,6.1315775,19, +-124.4464,40.304874,5.15,1992-07-30T03:26:36.807000,3.9756048,19, +-123.40797,39.402794,5.45,1992-12-07T13:19:27.327000,6.76039,19, +-123.386894,39.402874,4.95,1992-12-07T13:29:56.174000,6.9745626,19, +-123.42864,39.41852,5.05,1992-12-09T17:56:04.777000,7.4932427,19, +-124.30925,40.409058,5.25,1993-03-09T02:48:11.477000,8.2890415,19, +-124.32769,40.42685,4.95,1993-03-12T20:51:19.609000,9.035536,19, +-118.976494,38.268875,5.85,1993-04-05T23:56:39.145000,8.151211,19, +-118.974785,38.288036,5.55,1993-04-06T13:06:22.479000,5.0552177,19, +-118.94016,38.274723,4.95,1993-04-06T14:19:45.034000,2.7871366,19, +-121.09534,37.054924,6.0623145,1993-05-23T22:10:49.110000,2.09,19, +-117.832565,38.327785,5.05,1993-06-28T01:08:53.623000,8.656627,19, +-115.65477,32.871326,5.45,1992-07-01T05:09:56.310000,8.506744,20, +-121.91904,37.094196,5.65,1992-07-02T08:44:40.321000,9.279373,20, +-115.92695,33.45537,5.05,1992-07-30T03:59:15.175000,9.417519,20, +-116.35225,34.02083,4.95,1992-08-12T21:08:28.336000,8.040814,20, +-124.28997,40.298153,4.95,1992-09-16T20:23:39.859000,15.64356,20, +-124.379234,40.35418,5.05,1992-12-26T19:18:35.492000,6.693037,20, +-120.259865,36.29652,5.15,1993-01-24T02:03:34.265000,17.429218,20, +-118.07055,34.093094,5.05,1993-02-18T04:49:21.889000,17.417393,20, +-115.426216,32.404263,4.95,1993-04-17T19:16:43.991000,5.613379,20, +-119.09843,34.986523,5.25,1993-04-30T05:09:48.756000,6.817059,20, +-122.13764,42.02722,5.45,1992-07-28T07:13:05.679000,8.178245,21, +-122.13485,42.028194,4.95,1992-08-01T20:21:54.864000,5.479957,21, +-124.32619,40.869244,5.25,1992-08-15T11:22:43.373000,7.641134,21, +-122.93372,39.474174,4.95,1992-10-02T11:51:32.475000,6.502251,21, +-124.53218,40.36439,5.25,1992-10-05T02:47:13.833000,17.343918,21, +-124.333336,39.590313,5.25,1992-07-16T16:50:01.262000,7.9091616,22, +-116.384125,35.019855,6.939884,1992-07-27T10:06:42.785000,8.25,22, +-116.61248,34.9564,5.45,1992-07-27T10:12:38.287000,8.285452,22, +-116.455894,34.998913,5.65,1992-07-27T10:17:37.926000,4.8399897,22, +-116.55682,34.98399,4.95,1992-07-27T13:02:05.770000,12.795961,22, +-116.72595,34.93235,5.45,1992-07-27T17:44:16.780000,1.7021044,22, +-116.66,35.2,6.085645,1992-07-28T10:05:15.700000,11.0,22, +-116.37942,35.023773,5.95,1992-08-09T03:46:25.592000,3.546031,22, +-116.4053,35.0058,4.95,1992-08-09T03:55:31.457000,3.413706,22, +-116.236855,35.01901,4.95,1992-08-09T19:49:54.895000,6.8265715,22, +-116.370514,35.01026,4.95,1992-08-13T13:31:26.666000,5.332457,22, +-116.37871,34.992603,4.95,1992-08-16T04:01:03.267000,9.801688,22, +-116.30045,35.003895,5.55,1992-08-30T07:55:04.349000,10.750548,22, +-124.16047,40.263973,5.05,1992-11-19T09:28:22.203000,10.884712,22, +-116.4645,34.982788,5.35,1993-01-22T22:27:30.933000,5.426866,22, +-116.631065,35.207077,5.25,1993-02-07T16:32:45.731000,3.0046487,22, +-124.13012,40.287746,5.25,1993-04-25T13:07:32.791000,11.507689,22, +-118.79554,37.066063,5.45,1993-06-28T08:31:25.301000,14.599162,22, +-124.54712,40.375496,5.15,1992-08-22T14:06:40.863000,20.54178,23, +-124.50546,40.34461,5.15,1992-08-26T06:30:23.211000,21.578484,23, +-123.007416,38.870224,5.45,1992-09-05T07:01:22.405000,8.322737,23, +-120.8,36.8,6.0329366,1992-09-29T17:31:31.279000,7.0,23, +-121.05029,36.881382,5.35,1992-09-30T18:28:04.378000,5.135672,23, +-116.06611,36.63924,4.95,1992-11-24T00:58:42.349000,10.531753,23, +-124.2362,40.390896,4.95,1992-12-05T00:30:41.801000,8.783334,23, +-120.36,35.9,6.11956,1993-01-18T07:10:33.595000,5.0,23, +-122.73159,38.772465,5.45,1993-02-17T10:59:37.149000,10.635392,23, +-124.60653,40.58038,5.05,1993-06-01T02:50:54.268000,13.245527,23, +-120.67307,35.703293,4.95,1993-06-27T17:18:13.911000,16.56386,23, +-124.70694,40.445286,4.95,1992-06-29T17:04:44.577000,14.787524,24, +-124.319595,40.299786,4.95,1992-07-01T04:16:38.202000,2.9416773,24, +-124.66,40.32,6.693793,1992-07-17T03:03:49.624000,7.0,24, +-124.64732,40.344387,5.45,1992-07-17T03:16:06.069000,3.623742,24, +-124.6797,40.17472,6.35,1992-07-17T05:04:13.664000,3.4614851,24, +-124.574425,40.33209,5.45,1992-07-17T23:59:15.440000,2.6133456,24, +-121.94958,37.123447,5.65,1992-07-22T17:54:40.744000,6.247414,24, +-124.64439,40.359516,5.15,1992-07-25T01:25:53.080000,2.945943,24, +-116.35124,34.49812,5.85,1992-08-20T06:18:21.665000,8.206576,24, +-119.112045,34.42233,5.15,1992-09-03T23:13:00.796000,15.002305,24, +-124.14196,40.407803,4.95,1992-09-06T14:17:07.323000,3.649813,24, +-124.393845,40.314106,5.45,1992-10-14T04:32:10.939000,6.5896235,24, +-116.28433,31.84297,5.05,1993-02-21T22:11:50.245000,7.5713487,24, +-119.98008,36.37292,5.45,1993-05-11T22:24:02.005000,9.771463,24, +-116.84872,33.663437,5.25,1993-05-28T11:37:19.365000,3.5666203,24, +-118.93867,37.623394,5.15,1993-05-31T04:01:54.413000,10.916228,24, +-124.39121,40.425735,5.15,1992-07-10T03:19:34.847000,9.734439,25, +-124.529915,40.341476,5.05,1992-07-24T21:19:43.920000,21.185202,25, +-124.47201,40.29498,4.95,1992-07-31T02:50:23.052000,4.4258056,25, +-124.20573,40.38848,4.95,1992-08-24T05:09:51.668000,11.159814,25, +-117.92,34.54,7.2812004,1992-08-31T04:02:53.296000,9.0,25, +-117.63536,34.354774,5.35,1992-08-31T04:06:58.910000,11.017752,25, +-117.20854,34.116924,5.15,1992-08-31T04:09:06.565000,2.0729232,25, +-117.60757,34.333115,5.75,1992-08-31T04:24:14.011000,1.6661228,25, +-117.493576,34.28688,4.95,1992-08-31T04:58:16.558000,2.2749834,25, +-117.60094,34.247208,5.25,1992-08-31T05:42:19.239000,3.5234654,25, +-117.68835,34.383904,5.45,1992-08-31T10:24:16.889000,0.9402963,25, +-117.109276,34.099476,5.35,1992-08-31T12:22:02.260000,12.045378,25, +-117.18865,34.139507,5.35,1992-08-31T21:05:11.881000,7.898653,25, +-117.38069,34.252735,5.75,1992-09-02T00:38:08.013000,7.2675586,25, +-117.67181,34.357113,4.95,1992-09-02T15:49:52.910000,9.446159,25, +-117.17999,34.13689,5.05,1992-09-05T17:34:09.057000,9.009353,25, +-117.32709,34.20176,5.35,1992-09-08T19:29:17.352000,4.3896284,25, +-117.42629,34.225933,5.95,1992-09-11T18:52:43.463000,8.15647,25, +-124.42545,40.211117,5.25,1992-09-15T21:29:28.097000,5.0767174,25, +-116.08465,33.687275,4.95,1992-10-23T07:19:22.411000,15.241895,25, +-119.5565,38.746136,5.25,1992-11-08T03:34:46.345000,6.08443,25, +-117.420494,34.201492,4.95,1992-11-18T07:51:32.150000,6.7476172,25, +-119.56547,38.740074,5.45,1992-12-02T04:47:38.108000,7.0402336,25, +-117.76272,34.410053,5.15,1992-12-13T18:05:49.906000,7.334033,25, +-124.48,40.36,6.693793,1992-12-20T22:46:05.886000,5.0,25, +-124.37717,40.234264,4.95,1992-12-20T22:47:23.755000,2.737827,25, +-124.388725,40.239708,5.25,1992-12-21T05:00:07.629000,8.340937,25, +-124.38613,40.25195,5.15,1992-12-24T04:40:47.589000,8.204137,25, +-119.322136,34.42391,4.95,1993-01-21T18:18:24.049000,9.967995,25, +-119.322235,34.4013,5.65,1993-01-21T18:46:02.365000,8.98102,25, +-119.972664,35.819546,5.15,1993-03-13T18:06:06.066000,16.49606,25, +-119.96312,35.83687,5.55,1993-03-13T18:17:04.309000,16.301031,25, +-119.994514,35.780037,4.95,1993-03-14T05:32:39.057000,15.827616,25, +-117.31337,34.178093,5.35,1993-03-31T20:20:43.898000,7.725403,25, +-122.724655,38.9021,4.95,1993-04-01T08:57:39.046000,7.9683084,25, +-116.3884,34.071823,5.65,1993-04-20T00:58:33.298000,3.5530646,25, +-124.700485,40.394714,5.05,1993-05-22T00:05:13.205000,2.8993225,25, +-124.50054,40.3495,5.35,1993-05-30T05:19:31.073000,22.064728,25, +-124.36649,40.278576,5.45,1992-07-17T18:37:29.184000,7.793533,26, +-124.427284,40.27358,5.45,1992-07-19T09:33:05.518000,5.2355604,26, +-124.30766,40.299946,5.45,1992-07-28T14:40:14.280000,7.883083,26, +-124.247826,40.401535,5.15,1992-09-21T05:54:47.070000,9.923846,26, +-120.84185,37.48087,5.45,1992-10-11T20:11:44.602000,6.674578,26, +-116.50262,32.454914,5.25,1992-11-08T01:53:53.539000,4.5364223,26, +-124.76027,42.476006,5.15,1992-12-17T23:08:56.898000,7.0174546,26, +-125.02566,40.83455,4.95,1993-01-06T04:48:57.143000,6.5004134,26, +-124.75382,42.48084,5.85,1993-02-28T09:36:55.408000,5.6799693,26, +-124.749855,42.49972,4.95,1993-03-08T07:10:21.833000,7.9122825,26, +-120.73182,37.15199,5.35,1993-03-30T11:52:07.866000,10.034078,26, +-117.62676,34.287655,5.35,1993-05-30T17:30:09.196000,10.735604,26, +-116.57129,33.326744,5.15,1992-08-24T06:23:44.904000,2.6798728,27, +-116.327484,34.515892,5.55,1992-10-09T15:55:28.168000,6.9028625,27, +-116.26572,34.358326,5.05,1992-10-09T16:13:34.508000,9.553706,27, +-124.56,40.42,6.693793,1992-10-26T08:35:53.485000,21.0,27, +-124.46971,40.291485,5.05,1992-11-17T18:22:00.421000,6.2309175,27, +-124.45514,40.302452,5.05,1992-11-17T18:35:03.637000,7.400855,27, +-124.75859,40.410347,5.35,1992-11-25T18:02:28.629000,5.5063667,27, +-116.38496,34.099854,5.05,1992-12-26T02:27:09.234000,6.4921694,27, +-121.88424,37.54446,5.55,1993-03-09T14:48:36.761000,4.326141,27, +-119.57261,38.822258,4.95,1993-06-09T17:51:16.154000,7.6687737,27, +-124.37662,40.296024,5.65,1992-07-07T19:39:17.724000,4.8336573,28, +-124.47811,40.24481,5.05,1992-07-08T10:58:57.101000,7.1143928,28, +-117.343735,35.390152,5.15,1992-08-08T10:02:21.690000,9.901802,28, +-123.248436,40.811626,5.25,1993-03-15T11:28:09.158000,7.848772,28, +-120.2467,39.731148,5.05,1993-03-17T01:34:00.384000,5.4568,28, +-120.260376,39.720573,5.55,1993-03-17T01:38:41.140000,4.552788,28, +-122.667984,39.933186,4.95,1993-05-02T09:15:28.531000,5.9647717,28, +-116.315315,33.9302,5.25,1992-08-02T22:46:09.896000,4.9348354,29, +-116.312096,33.95257,5.15,1992-08-19T21:21:36.880000,6.847574,29, +-121.40358,36.786297,5.05,1992-08-25T02:36:31.775000,6.7924848,29, +-116.665955,33.963844,5.25,1992-10-16T04:32:27.468000,11.1642,29, +-124.04,40.3,6.621897,1992-12-03T01:14:51.915000,5.0,29, +-124.00801,40.204628,4.95,1992-12-03T01:41:24.701000,22.048944,29, +-124.09415,40.34049,4.95,1992-12-03T05:34:59.883000,13.307335,29, +-124.06238,40.284065,5.35,1992-12-06T01:43:18.343000,0.7849598,29, +-123.97595,40.164333,5.45,1992-12-06T13:37:58.182000,21.711607,29, +-124.13816,39.717663,4.95,1992-12-08T00:49:53.747000,8.434238,29, +-124.00352,40.215443,5.05,1992-12-08T10:15:33.977000,13.410407,29, +-123.95722,40.253048,5.95,1992-12-08T17:42:01.452000,16.105362,29, +-116.36316,33.979885,4.95,1993-01-12T09:31:38.986000,11.384832,29, +-116.40449,34.063503,4.95,1992-08-03T19:23:17.025000,7.7541137,30, +-122.14593,40.54869,5.35,1992-09-08T18:44:49.845000,10.773142,30, +-120.12444,39.699062,5.35,1992-09-28T09:18:25.596000,6.2607937,30, +-120.14821,39.70179,6.15,1992-09-28T09:25:10.375000,6.4034386,30, +-120.10859,39.723373,5.05,1992-09-28T11:26:56.147000,11.638397,30, +-120.15429,39.697685,5.15,1992-09-28T18:37:57.123000,6.071207,30, +-124.1702,40.121326,4.95,1992-10-04T10:26:36.759000,7.0880537,30, +-123.74328,41.55805,5.05,1993-01-02T21:50:29.559000,6.2243385,30, +-124.689865,40.47631,5.85,1993-02-07T03:15:55.412000,2.2967362,30, +-116.26476,31.743523,5.15,1993-03-26T06:12:45.412000,2.307616,30, +-116.2235,31.748713,6.95,1993-03-26T16:22:35.775000,5.104866,30, +-116.178055,31.616508,5.45,1993-03-26T19:58:59.110000,7.6867394,30, +-116.25269,31.843485,5.25,1993-04-01T01:03:42.393000,3.7855573,30, +-116.22722,31.632545,5.85,1993-04-05T05:00:58.412000,9.291642,30, +-124.531105,40.355003,5.35,1992-07-26T02:22:01.384000,22.226152,31, +-124.390816,40.40746,5.25,1992-07-29T09:12:00.152000,6.6463203,31, +-124.33792,40.313824,5.65,1992-07-30T15:22:51.719000,8.518683,31, +-124.32617,40.307274,5.35,1992-08-05T20:46:44.286000,8.607787,31, +-120.62253,36.460594,5.75,1992-09-03T23:39:23.936000,5.791747,31, +-124.50512,40.357437,5.05,1992-10-12T23:29:48.733000,22.128218,31, +-116.65334,31.921028,5.35,1992-11-29T09:47:31.090000,8.938995,31, +-116.40677,31.693287,5.25,1992-12-07T00:05:09.392000,10.653646,31, +-123.868904,39.330532,5.15,1993-02-07T16:37:50.918000,6.6331134,31, +-117.40125,37.812626,5.65,1993-02-16T14:45:35.816000,4.2836614,31, +-117.67997,38.053295,5.05,1993-02-17T07:57:42.907000,12.7974825,31, +-119.672905,38.711475,5.45,1993-03-28T05:55:02.508000,3.7208838,31, +-116.33954,32.359394,5.05,1993-06-07T14:00:57.991000,10.397949,31, +-121.429016,36.92306,6.1391573,1992-07-20T16:38:53.219000,6.828125,32, +-121.38297,36.92281,4.95,1992-07-20T19:31:11.268000,9.872187,32, +-121.25144,36.76958,5.55,1992-07-20T22:57:18.890000,2.6018634,32, +-121.225624,36.767002,5.35,1992-07-21T15:27:13.978000,6.9339566,32, +-121.4241,36.912037,5.05,1992-07-21T17:40:08.457000,8.989554,32, +-121.41104,36.917576,5.25,1992-07-21T17:52:14.927000,9.203955,32, +-121.3827,36.866703,4.95,1992-07-25T17:18:29.176000,5.9819326,32, +-121.24791,36.741398,4.95,1992-08-18T03:39:14.178000,2.697426,32, +-124.24171,42.022964,5.35,1992-08-28T09:32:55.771000,6.3585854,32, +-117.94862,37.190014,5.55,1992-09-01T01:32:43.751000,17.032457,32, +-124.49133,40.37444,5.05,1992-09-03T23:06:18.309000,22.68285,32, +-124.48,40.26,6.628068,1992-12-12T17:33:45.345000,15.0,32, +-124.35203,40.267303,4.95,1992-12-12T18:34:37.239000,3.3376014,32, +-124.55566,40.31576,4.95,1992-12-13T05:53:04.981000,3.5024745,32, +-121.835434,36.946476,5.05,1993-01-05T02:33:12.308000,5.63024,32, +-124.566666,40.297577,5.05,1993-04-08T03:49:17.202000,6.301203,32, +-124.55043,40.298004,4.95,1993-04-08T17:56:52.006000,7.1767497,32, +-116.359825,34.06858,5.15,1993-05-13T18:52:37.571000,3.258716,32, +-120.95537,36.531334,5.55,1993-06-12T21:14:16.148000,9.213247,32, +-124.4394,40.368187,4.95,1992-07-02T20:56:21.997000,20.396812,33, +-125.274864,41.144432,5.15,1992-07-19T06:27:17.143000,1.0395099,33, +-119.06153,36.750694,5.65,1992-10-12T09:43:32.170000,8.097663,33, +-121.152306,36.7848,4.95,1992-10-24T22:16:30.513000,8.313942,33, +-124.363655,40.322937,4.95,1992-11-21T21:47:08.063000,7.070212,33, +-120.56097,34.609272,6.2125072,1992-11-27T13:05:14.350000,8.4,33, +-120.64461,34.63369,5.25,1992-11-27T17:09:01.397000,3.888075,33, +-120.75436,39.72058,5.05,1993-04-25T21:39:09.858000,16.977692,33, +-124.49405,40.33908,5.85,1992-07-01T18:21:05.468000,17.617146,34, +-116.29098,33.942432,5.15,1992-07-30T04:39:21.997000,2.8883529,34, +-118.549614,35.27501,5.45,1992-07-31T09:53:30.393000,7.3216643,34, +-123.53227,39.801544,5.65,1992-09-25T01:35:25.874000,11.835831,34, +-123.5127,39.81695,4.95,1992-09-25T21:31:16.761000,15.996668,34, +-122.52944,37.60926,5.55,1993-03-02T09:48:17.718000,11.46762,34, +-124.10216,40.229828,5.05,1992-09-06T21:09:31.565000,15.6187,35, +-120.07188,36.16648,5.05,1992-10-13T12:52:29.560000,7.3892,35, +-115.12436,32.379826,4.95,1993-01-12T18:53:40.860000,10.752958,35, +-121.45386,36.911854,4.95,1993-02-16T17:17:41.113000,5.0748367,35, +-120.948204,37.59396,5.25,1993-03-31T16:08:41.146000,11.175842,35, +-115.73342,33.186344,5.15,1993-04-18T16:03:07.751000,4.579889,35, +-118.32265,37.609436,5.25,1993-05-22T16:34:24.148000,5.85286,35, +-117.22977,32.35426,5.05,1992-07-09T09:53:04.541000,7.4654713,36, +-120.21018,36.3933,5.45,1992-07-15T11:46:33.253000,12.946693,36, +-115.59723,31.953897,5.15,1992-08-01T01:17:50.846000,11.146921,36, +-124.42522,40.279892,5.45,1992-08-18T01:55:42.512000,4.49838,36, +-124.41896,40.26786,4.95,1992-08-18T02:47:50.555000,4.3180346,36, +-124.72836,40.431187,5.75,1992-08-19T22:09:31.141000,5.37496,36, +-124.75595,40.444443,5.05,1992-08-20T21:13:08.521000,4.9967394,36, +-121.21849,36.594772,5.45,1992-10-01T23:59:37.532000,14.268371,36, +-118.27167,37.365185,5.05,1993-01-17T04:40:20.235000,5.8942537,36, +-121.62709,36.97308,5.05,1993-02-28T23:07:55.412000,3.4568713,36, +-121.01542,36.191635,5.35,1993-03-26T12:26:40.671000,16.787012,36, +-120.32664,34.416683,5.15,1993-04-12T09:27:02.261000,3.768641,36, +-121.781494,37.018524,5.65,1993-04-15T21:57:43.396000,10.995938,36, +-114.84705,32.30695,5.35,1993-04-22T06:52:13.666000,7.6288567,36, +-124.53465,40.37568,5.25,1993-04-26T19:17:05.330000,18.174492,36, +-121.60672,36.803642,4.95,1993-04-30T05:47:50.665000,5.064441,36, +-116.35578,31.89244,5.55,1993-05-04T19:32:44.299000,9.5110445,36, +-116.30193,31.857124,5.05,1993-05-24T04:33:57.489000,9.782951,36, +-124.34891,40.290913,5.15,1992-07-15T09:57:33.666000,9.642533,37, +-124.541466,40.31225,6.2110257,1992-07-31T01:49:45.647000,5.0,37, +-124.661064,40.35143,5.95,1992-07-31T02:18:13.811000,2.5273325,37, +-124.67137,40.338474,5.05,1992-07-31T02:29:48.710000,5.152951,37, +-124.35464,40.351128,5.15,1992-07-31T02:53:51.854000,7.3526278,37, +-124.30893,40.358955,4.95,1992-08-17T13:01:53.153000,10.124512,37, +-117.48764,33.889565,4.95,1992-08-30T19:22:17.838000,8.935387,37, +-118.85943,34.79829,4.95,1992-10-21T11:03:53.866000,15.352344,37, +-124.58353,40.407574,5.95,1992-10-29T03:32:24.240000,22.856415,37, +-125.048836,40.36229,5.45,1992-11-23T14:57:50.875000,5.6972184,37, +-124.36951,40.259544,5.15,1992-12-21T11:45:07.896000,6.0509524,37, +-118.45726,37.569862,6.05,1993-01-31T17:30:39.122000,5.1219287,37, +-121.281975,36.71015,5.75,1993-03-21T19:57:21.825000,1.8746343,37, +-118.86512,34.797,5.25,1993-04-09T01:13:51.876000,12.979711,37, +-122.62612,38.373444,5.05,1993-04-13T14:46:53.492000,2.004461,37, +-122.47227,37.1228,5.15,1992-12-19T06:34:30.511000,5.6642923,38, +-124.48277,40.35647,4.95,1993-03-23T06:42:00.858000,18.531027,38, +-124.4869,40.365818,5.35,1993-03-23T06:56:14.372000,19.10281,38, +-124.5,40.34,6.4624553,1993-03-23T07:01:22.415000,19.0,38, +-124.63386,40.350872,5.65,1993-03-23T07:49:30.442000,8.314001,38, +-124.57494,40.371662,5.05,1993-03-24T14:33:44.324000,7.718097,38, +-124.462036,40.362343,5.45,1993-03-25T10:46:37.611000,16.971142,38, +-124.63181,40.34,5.05,1993-03-27T16:42:38.477000,8.714016,38, +-124.49266,40.296642,4.95,1993-04-14T23:20:41.737000,3.6763542,38, +-124.48474,40.341244,5.55,1993-04-15T00:23:11.971000,3.8228896,38, +-124.48621,40.323715,5.25,1993-05-25T10:59:14.265000,4.888294,38, +-118.76198,37.875698,4.95,1993-06-26T15:51:16.658000,10.359746,38, +-124.39788,40.303482,5.25,1992-06-29T03:16:58.684000,19.69397,39, +-124.58,40.36,6.2110257,1992-07-29T14:59:19.540000,19.0,39, +-124.19914,40.295338,6.05,1992-08-30T00:40:48.399000,9.597305,39, +-124.169,40.280586,4.95,1992-09-01T09:04:40.248000,9.572134,39, +-124.18138,40.28002,4.95,1992-09-09T22:07:24.686000,10.292248,39, +-117.805824,34.034863,5.15,1992-11-11T19:53:28.551000,3.746893,39, +-117.8051,34.051975,5.45,1992-11-11T21:35:42.997000,3.9247334,39, +-122.84479,40.913666,4.95,1993-02-11T13:59:56.442000,7.439627,39, +-122.83961,40.921505,5.45,1993-02-11T16:53:27.897000,6.329333,39, +-122.84152,40.91632,5.15,1993-02-11T18:12:20.051000,9.135369,39, +-120.03266,39.10061,5.25,1993-02-19T20:04:50.820000,10.47202,39, +-120.73353,39.33639,5.05,1993-04-16T16:31:38.592000,9.195428,39, +-121.599655,37.168358,5.25,1993-05-05T00:45:52.515000,6.79522,39, +-118.50165,35.031925,4.95,1993-05-17T23:12:36.737000,12.380711,39, +-124.41983,40.37642,5.55,1992-07-30T16:57:17.104000,5.8597045,40, +-124.4292,40.391666,5.15,1992-07-30T19:22:39.900000,6.7564044,40, +-124.429054,40.374046,5.15,1992-08-10T01:36:22.967000,7.3050513,40, +-124.418396,40.39906,5.15,1992-11-19T04:01:02.026000,5.6071515,40, +-120.7413,39.71433,5.05,1992-12-16T11:23:08.757000,9.970438,40, +-121.7952,39.628708,5.25,1993-02-25T03:07:02.747000,5.1215715,40, +-121.70595,41.45821,5.65,1993-03-04T16:59:59.085000,17.111578,40, +-124.29371,40.43065,4.95,1993-04-07T19:31:49.310000,9.359091,40, +-115.30062,32.62039,7.393764,1993-04-26T15:35:51.233000,2.09,40, +-115.74335,33.340755,4.95,1993-04-26T15:43:51.425000,7.7643356,40, +-115.68464,33.213943,5.05,1993-04-26T16:47:37.955000,8.49922,40, +-115.77665,33.3903,5.35,1993-04-26T16:52:22.922000,3.760682,40, +-115.54995,32.92178,4.95,1993-04-26T23:30:45.103000,2.8955343,40, +-115.52971,32.895206,5.05,1993-04-27T00:10:26.128000,5.575071,40, +-115.51366,32.935947,5.55,1993-04-27T00:21:42.891000,7.6061363,40, +-115.60552,33.03554,5.85,1993-04-27T03:46:45.226000,11.153064,40, +-115.96878,33.77291,6.05,1993-04-27T05:44:45.591000,6.029188,40, +-116.06184,33.634827,5.15,1993-04-27T06:06:59.746000,10.401199,40, +-116.0009,33.775085,4.95,1993-04-27T06:43:12.134000,10.854321,40, +-115.96371,33.77718,5.05,1993-04-27T09:10:02.605000,1.0396763,40, +-116.15436,33.719433,4.95,1993-04-28T04:32:29.482000,4.266054,40, +-116.3972,33.88291,5.25,1993-04-28T08:00:27.559000,4.877439,40, +-118.65995,35.208893,4.95,1993-05-05T18:54:41.018000,12.7365265,40, +-116.009674,33.60627,5.35,1993-05-15T11:02:37.808000,6.7089314,40, +-115.317795,32.781906,4.95,1993-05-15T14:07:14.535000,5.5582695,40, +-124.44,40.34,6.830105,1992-07-17T04:30:50.637000,15.0,41, +-124.32709,40.19967,5.65,1992-07-17T04:43:57.719000,7.1394534,41, +-124.51452,40.29662,5.15,1992-07-17T05:52:58.283000,5.453231,41, +-124.342476,40.209774,5.15,1992-07-17T18:10:44.029000,10.279852,41, +-124.291405,40.174988,5.35,1992-07-18T09:18:37.696000,5.7172866,41, +-120.456375,35.762085,5.45,1992-07-18T09:33:32.611000,5.725332,41, +-124.291916,40.18696,5.05,1992-07-24T16:42:30.042000,6.30893,41, +-124.56398,40.31751,5.65,1992-08-21T16:14:24.202000,0.8822799,41, +-124.53426,40.319725,5.55,1992-08-23T06:53:05.660000,5.39796,41, +-124.41545,40.263103,5.15,1992-08-26T06:29:14.103000,11.013903,41, +-124.492615,40.247143,4.95,1992-08-28T23:05:00.943000,5.267188,41, +-115.829,31.894981,5.05,1992-08-31T06:12:08.851000,6.8538904,41, +-124.42515,40.26626,5.35,1992-12-10T03:20:43.716000,3.1820004,41, +-114.993675,34.744328,5.25,1993-05-01T11:57:42.519000,6.274252,41, +-124.398155,40.296642,5.45,1993-06-10T21:30:21.050000,3.354951,41, +-118.02279,33.700443,5.05,1993-06-17T10:37:04.471000,0.67293346,41, +-118.866234,37.392815,5.05,1992-07-24T02:07:40.680000,6.462207,42, +-124.39145,40.342747,5.15,1992-11-13T04:09:05.563000,6.36701,42, +-115.79923,32.445354,5.95,1992-12-06T20:32:02.195000,7.3766704,42, +-115.83865,32.453533,5.25,1992-12-07T06:01:52.500000,6.2389054,42, +-115.84016,32.41514,5.05,1992-12-07T09:16:37.719000,7.1559615,42, +-122.74026,40.236687,5.05,1992-08-22T17:42:39.926000,8.970335,43, +-124.17342,40.35904,5.55,1992-10-09T02:10:49.036000,8.834136,43, +-124.368385,40.332752,4.95,1992-10-16T04:34:06.775000,8.448379,43, +-116.7037,34.69345,4.95,1993-01-27T08:18:46.579000,5.748945,43, +-120.39522,36.287945,4.95,1993-02-10T20:24:35.341000,9.445775,43, +-119.81924,36.1523,5.45,1993-03-29T06:38:34.736000,15.328915,43, +-121.95552,40.83263,5.05,1993-04-27T15:31:34.603000,5.864654,43, +-117.6,34.36,6.3001337,1993-04-27T23:27:53.362000,9.0,43, +-117.59485,34.340298,5.55,1993-04-29T12:27:21.536000,9.774795,43, +-117.49102,34.38111,5.55,1993-05-05T10:54:12.288000,6.235364,43, +-117.67587,34.077953,5.45,1993-05-05T12:34:28.777000,5.0467405,43, +-124.472336,40.407402,5.25,1992-07-02T23:37:48.633000,20.228136,44, +-124.25554,40.307137,5.55,1992-07-25T07:35:05.002000,6.9953847,44, +-116.96885,33.47638,5.05,1992-09-05T02:26:32.827000,6.090052,44, +-124.222595,40.362347,5.05,1992-10-04T06:46:45.679000,11.03039,44, +-123.32961,39.81453,5.65,1992-11-01T19:43:25.901000,19.418928,44, +-123.3497,39.79631,5.75,1992-11-03T05:25:48.864000,16.133825,44, +-114.52321,33.272964,4.95,1992-11-26T07:22:29.830000,9.53517,44, +-122.881935,39.62447,5.05,1993-03-20T11:05:39.982000,7.9166846,44, +-118.94127,37.546673,4.95,1992-07-07T11:21:03.264000,5.876215,45, +-125.03952,40.825146,5.05,1992-07-09T21:21:04.989000,8.989733,45, +-123.12776,39.035717,4.95,1992-09-11T17:37:57.399000,5.909698,45, +-121.54445,40.499027,6.55,1992-10-21T14:19:43.979000,6.867963,45, +-121.557655,40.58803,5.15,1992-10-21T14:59:02.104000,6.071094,45, +-117.36406,34.912766,5.35,1992-10-27T17:41:27.761000,8.410626,45, +-121.51693,40.463562,5.35,1992-11-16T05:55:03.577000,0.90126723,45, +-124.16528,40.435757,4.95,1992-11-17T15:01:51.576000,11.259957,45, +-124.82804,41.161522,5.05,1992-11-29T10:08:03.779000,13.9469595,45, +-120.85768,36.45671,4.95,1993-01-03T20:39:17.832000,8.165708,45, +-117.77106,36.392548,5.25,1993-01-08T11:02:56.287000,10.937323,45, +-124.555275,40.40788,4.95,1993-03-06T13:57:02.642000,19.601631,45, +-119.073044,35.23819,5.25,1993-06-16T17:23:15.794000,8.312556,45, +-116.405235,33.943806,5.25,1992-07-09T14:20:50.482000,6.5737896,46, +-116.397644,33.932106,5.25,1992-07-09T15:44:03.597000,5.9268813,46, +-116.38056,33.942673,5.05,1992-07-09T17:05:55.403000,5.0892525,46, +-116.53181,34.41147,5.85,1992-08-03T11:24:57.113000,4.0925307,46, +-116.509705,34.31839,4.95,1992-09-07T07:40:47.034000,5.5876613,46, +-118.944664,37.0434,4.95,1992-10-07T16:11:59.900000,7.980056,46, +-120.46,35.96,6.11956,1992-11-04T02:15:24.037000,11.0,46, +-124.53133,40.36536,5.05,1992-12-19T23:42:51.851000,22.589851,46, +-118.69221,33.94347,4.95,1992-12-27T09:28:15.789000,15.257616,46, +-120.619255,36.358368,5.15,1992-07-04T07:28:10,9.539966,47, +-124.43111,40.2968,5.05,1992-07-31T18:25:37.163000,7.3775735,47, +-124.201416,40.262096,4.95,1992-08-30T14:11:23.159000,9.6224165,47, +-124.31824,40.24453,5.05,1992-09-26T13:46:43.905000,7.3481746,47, +-118.84237,38.237446,4.95,1992-10-08T16:19:46.259000,11.335373,47, +-117.715965,32.234936,5.15,1992-10-13T17:30:59.960000,5.1685934,47, +-124.37224,40.30404,5.05,1992-11-06T03:47:07.208000,7.432862,47, +-121.00608,40.76968,5.35,1992-12-25T12:48:51.175000,10.4824095,47, +-124.6,40.38,6.018107,1993-01-05T08:13:15.789000,9.0,47, +-124.66528,40.361492,5.25,1993-01-05T08:37:23.759000,4.82533,47, +-124.60608,40.372505,5.45,1993-02-12T10:34:45.872000,2.1089294,47, +-124.66248,40.380962,5.45,1993-02-28T10:58:35.833000,6.4469776,47, +-115.68426,31.792126,5.35,1993-03-04T22:06:58.430000,6.7950487,47, +-116.03235,31.70384,5.05,1993-03-23T00:24:20.658000,4.5048738,47, +-124.39153,40.228195,4.95,1992-07-01T01:08:58.741000,5.0222244,48, +-122.591484,37.82624,5.05,1992-07-10T08:06:32.005000,2.572056,48, +-121.25979,36.647877,5.15,1992-08-02T00:56:18.332000,6.9167633,48, +-121.268814,36.644897,5.15,1992-08-04T13:37:37.957000,7.7500577,48, +-124.43017,40.35581,4.95,1992-09-25T09:43:36.162000,6.8137836,48, +-116.623505,34.60876,4.95,1992-09-27T10:49:31.292000,6.7917767,48, +-121.70973,37.095608,5.65,1992-10-04T17:05:39.282000,6.058707,48, +-122.2868,37.72866,5.15,1992-10-25T17:50:59.117000,11.76832,48, +-121.70083,37.111477,5.25,1992-11-03T05:22:17.809000,4.2391276,48, +-124.55216,40.38541,5.35,1992-12-07T06:31:25.914000,16.659857,48, +-115.594025,33.208065,5.75,1992-12-07T20:29:25.544000,12.403474,48, +-115.74,33.1,5.8690944,1992-12-26T12:18:56.585000,7.0,48, +-124.36,40.28,6.4624553,1993-02-04T06:19:38.332000,7.0,48, +-124.42259,40.2283,5.55,1993-02-05T07:21:36.273000,7.391748,48, +-124.3495,40.272324,5.05,1993-02-05T12:55:58.465000,6.622345,48, +-124.56548,40.319393,5.25,1993-02-05T21:33:09.661000,4.333073,48, +-124.4754,40.254337,5.25,1993-02-05T21:39:18.823000,7.480547,48, +-124.40626,40.24822,5.05,1993-02-18T08:11:21.087000,1.777375,48, +-124.430916,40.2955,5.25,1993-02-24T06:02:04.439000,8.10324,48, +-122.28332,37.90652,5.25,1993-03-05T23:08:41.510000,12.835611,48, +-125.06881,40.469143,5.45,1993-03-08T07:35:12.449000,3.8287275,48, +-118.215004,36.940796,5.25,1993-03-09T00:25:32.859000,12.505698,48, +-118.432686,35.796837,5.15,1993-03-12T20:02:42.278000,9.607838,48, +-117.68932,34.147423,4.95,1993-04-03T02:49:03.577000,8.532592,48, +-121.48,36.94,6.3477087,1993-04-14T21:40:01.614000,13.0,48, +-118.669754,37.382065,5.05,1993-04-19T20:53:16.239000,5.0752487,48, +-124.45475,39.795994,4.95,1993-04-23T02:28:31.250000,3.13538,48, +-121.27458,36.822445,4.95,1993-04-23T15:19:32.345000,7.3639193,48, +-121.20941,36.77014,4.95,1993-05-08T09:08:15.297000,3.4600472,48, +-121.63526,41.25817,5.75,1993-05-18T11:48:27.196000,20.257217,48, +-121.62347,41.28861,5.15,1993-05-19T21:09:45.123000,21.411545,48, +-121.597664,41.288925,5.85,1993-05-20T03:20:07.762000,22.409418,48, +-124.25459,40.32995,5.25,1993-06-17T04:45:58.205000,9.191593,48, +-124.62072,40.31245,5.05,1993-06-19T02:17:53.038000,5.3404775,48, +-120.31653,37.273518,5.25,1993-06-22T16:35:53.721000,9.409621,48, +-121.29028,34.59394,5.35,1992-07-05T20:15:57.268000,5.1359615,49, +-124.46389,40.3123,4.95,1992-07-13T04:06:24.628000,16.983688,49, +-124.29371,40.27628,5.05,1992-08-03T01:20:44.176000,9.460031,49, +-118.65796,37.967598,5.25,1992-08-04T08:15:31.642000,8.583285,49, +-124.48,40.38,6.628068,1992-08-26T06:13:10.647000,23.0,49, +-124.492165,40.286617,5.35,1992-08-26T06:22:22.178000,9.742202,49, +-124.63775,40.347218,5.15,1992-08-26T06:51:53.450000,3.1407628,49, +-124.81723,40.32532,4.95,1992-08-26T13:33:39.275000,8.80955,49, +-124.646935,40.345325,5.15,1992-08-26T21:03:12.446000,3.4089932,49, +-124.38036,40.317467,5.15,1992-09-28T04:25:30.377000,6.5417085,49, +-124.61781,40.330654,5.55,1992-12-13T08:52:41.659000,4.862931,49, +-118.33777,33.613083,5.75,1993-02-20T20:48:44.037000,7.829941,49, +-124.54074,40.370487,5.85,1993-03-29T17:59:06.210000,17.639036,49, +-121.30893,36.694748,6.506964,1993-04-05T21:53:30.649000,12.0,49, +-121.22769,36.606853,5.05,1993-04-05T22:31:01.894000,2.456963,49, +-120.95148,36.376156,4.95,1993-04-06T14:22:02.048000,10.122304,49, +-123.88358,40.370686,4.95,1993-05-13T07:45:49.972000,9.227072,49, +-124.456665,40.36694,5.35,1992-07-02T12:26:00.490000,18.151644,50, +-124.34441,40.326775,5.45,1992-08-14T19:16:30.241000,4.702788,50, +-119.50093,35.03662,4.95,1992-08-25T00:46:24.785000,10.444812,50, +-118.09278,35.453392,5.25,1992-11-04T02:52:16.467000,9.105417,50, +-121.71232,37.575394,4.95,1993-01-03T08:22:52.676000,9.31742,50, +-115.3929,33.046303,6.15,1993-04-24T15:08:36.998000,12.78653,50, +-116.17653,33.331223,5.45,1993-04-25T16:35:30.758000,2.5523329,50, +-119.438446,34.704475,5.45,1993-06-07T15:12:43.299000,7.9923472,50, +-124.31011,40.25712,4.95,1992-06-30T21:18:50.934000,7.4016247,51, +-120.535255,36.29892,5.05,1992-07-25T09:10:40.512000,5.493752,51, +-116.027504,32.690674,4.95,1992-08-22T07:45:07.449000,8.362339,51, +-119.343155,34.58041,5.55,1992-11-28T16:11:17.439000,8.693368,51, +-119.08028,34.731213,6.55,1992-11-30T11:01:37.973000,10.273923,51, +-119.05527,34.779884,4.95,1992-11-30T11:01:48.671000,4.0091844,51, +-119.06097,34.696262,4.95,1992-11-30T11:20:39.904000,2.17417,51, +-119.19186,34.771152,5.65,1992-11-30T12:30:31.495000,8.340197,51, +-119.105385,34.76108,5.35,1992-11-30T14:54:12.517000,14.014351,51, +-119.07675,34.69927,5.95,1992-11-30T19:09:41.185000,10.881556,51, +-118.52349,34.565563,4.95,1992-12-01T07:47:34.340000,7.299975,51, +-118.55,35.27491,4.95,1992-12-13T14:57:45.646000,7.1049767,51, +-115.3218,32.18079,5.35,1993-01-27T23:46:38.832000,11.169668,51, +-124.35239,40.248177,5.05,1993-03-01T13:27:16.200000,6.745219,51, +-118.859146,37.353622,5.05,1993-03-30T19:29:11.264000,4.4346237,51, +-118.909195,37.691803,5.05,1993-04-27T19:23:44.533000,13.442289,51, +-120.28185,35.874302,5.15,1993-05-03T05:31:07.562000,10.66296,51, +-116.86325,33.615646,4.95,1993-06-13T23:33:01.261000,4.7093,51, +-124.0574,40.292587,5.05,1992-07-03T00:51:30.937000,9.925892,52, +-124.067314,40.28802,5.45,1992-07-03T07:19:18.309000,7.3289366,52, +-120.74554,40.424953,5.05,1992-08-09T17:13:10.671000,6.4062076,52, +-117.57837,36.094112,5.35,1992-11-15T11:58:18.190000,8.954986,52, +-115.627014,33.15506,5.15,1992-11-15T22:36:59.648000,1.4308784,52, +-123.86819,40.49126,5.25,1992-12-11T13:26:29.736000,8.853735,52, +-120.86567,34.74765,6.15,1993-03-05T20:51:29.984000,5.1454787,52, +-118.60372,33.06539,4.95,1993-03-09T12:13:26.736000,5.822008,52, +-120.814316,34.77852,4.95,1993-04-07T08:27:50.060000,5.182489,52, +-116.50689,34.42515,5.05,1993-04-15T19:01:33.884000,8.769609,52, +-119.743515,38.676876,4.95,1992-09-03T23:43:21.436000,13.814667,53, +-119.57072,38.694443,5.25,1992-09-27T05:13:32.084000,11.585932,53, +-124.167274,40.372276,5.55,1992-11-08T18:25:49.207000,11.234232,53, +-122.5978,38.633545,4.95,1992-11-30T18:27:44.420000,7.8438606,53, +-116.394005,34.12412,5.05,1992-12-14T11:17:35.537000,5.278797,53, +-121.31129,40.559345,5.35,1992-12-24T07:23:44.841000,9.164128,53, +-118.0567,37.656628,4.95,1993-01-06T10:18:46.591000,7.346296,53, +-119.60977,38.7639,5.35,1993-01-13T18:59:08.750000,10.301743,53, +-120.38761,36.536983,4.95,1993-05-27T22:32:47.216000,6.132201,53, +-118.81958,38.047943,5.05,1993-06-23T11:47:25.503000,16.427967,53, +-124.173164,40.41314,5.35,1992-07-02T13:19:12.214000,12.07885,54, +-124.49295,40.352837,5.45,1992-07-24T13:16:41.975000,17.905457,54, +-121.029076,39.02752,5.05,1992-08-21T05:12:32.917000,7.493758,54, +-116.918785,34.12668,5.05,1992-08-25T09:51:33.059000,6.5251746,54, +-124.26878,40.283554,5.85,1992-12-11T13:44:39.455000,8.1962185,54, +-124.25001,40.294506,5.25,1992-12-12T10:43:03.925000,6.747808,54, +-121.12,36.46,6.113826,1993-04-08T13:06:45.102000,17.0,54, +-121.03668,36.459496,5.05,1993-04-18T13:08:16.795000,9.84879,54, +-117.95543,33.754158,4.95,1993-06-01T06:57:46.804000,17.97012,54, +-116.921265,34.994164,7.2540135,1993-06-17T15:25:07.116000,8.126154,54, +-116.91666,34.982594,5.65,1993-06-17T15:26:09.426000,10.498159,54, +-116.3255,34.52117,5.55,1993-06-17T15:28:50.922000,14.110805,54, +-116.67806,34.853695,4.95,1993-06-17T15:32:32.689000,6.484337,54, +-116.32552,34.517605,5.85,1993-06-17T15:46:10.615000,17.0253,54, +-116.90565,35.001614,5.05,1993-06-17T15:56:51.077000,8.005246,54, +-116.824036,34.940113,5.25,1993-06-17T16:01:50.948000,12.239802,54, +-116.304695,34.50597,5.05,1993-06-17T16:19:16.219000,14.5231695,54, +-116.50937,34.587738,5.65,1993-06-17T21:48:34.852000,5.7881613,54, +-116.47943,34.605137,5.25,1993-06-17T22:11:53.549000,7.5697794,54, +-116.81989,34.93734,4.95,1993-06-18T05:16:07.343000,1.94008,54, +-116.01574,34.16966,5.65,1993-06-18T08:02:29.431000,5.819349,54, +-116.53523,34.67862,5.25,1993-06-19T00:20:55.693000,3.7838814,54, +-116.37487,34.510414,5.55,1993-06-19T09:46:47.312000,4.6507382,54, +-116.794815,34.924248,4.95,1993-06-22T13:28:26.594000,13.918597,54, +-116.99055,34.919125,5.45,1993-06-25T15:41:23.103000,7.2421675,54, +-116.97519,34.927986,4.95,1993-06-25T21:38:47.194000,8.503905,54, +-116.72995,34.88576,5.35,1993-06-26T19:58:11.453000,12.032769,54, +-123.5271,40.067947,5.55,1992-07-06T02:09:08.329000,10.54876,55, +-123.55725,40.07023,5.15,1992-07-06T09:57:58.742000,11.951846,55, +-116.467064,33.74453,4.95,1992-10-17T06:26:45.667000,15.758853,55, +-124.32512,40.4007,5.95,1992-11-19T08:17:18.771000,4.539483,55, +-114.939285,32.212627,5.55,1992-12-04T11:06:05.361000,7.6417522,55, +-115.593315,33.011074,4.95,1992-12-06T23:01:36.649000,6.739429,55, +-116.66497,34.008854,5.55,1993-01-11T00:00:54.812000,11.059236,55, +-116.65295,33.985836,5.05,1993-01-11T01:42:45.740000,12.935746,55, +-120.12007,35.88338,4.95,1993-02-18T10:50:57.153000,13.08954,55, +-117.35459,35.20613,5.05,1993-04-01T10:45:05.204000,9.8765,55, +-120.01236,36.3142,5.15,1993-06-18T09:56:27.975000,6.4213176,55, +-120.77101,39.77532,5.25,1992-09-25T01:16:42.429000,11.535817,56, +-116.35855,32.012146,5.15,1992-10-16T02:36:20.716000,4.3857675,56, +-124.44363,40.379585,5.65,1992-10-26T23:27:34.973000,5.4379525,56, +-124.37661,40.40977,5.05,1992-11-14T13:24:51.482000,8.889788,56, +-122.00178,42.046158,5.35,1993-01-10T04:28:23.910000,7.2473373,56, +-122.00422,42.0535,4.95,1993-01-13T12:30:35.552000,8.261808,56, +-118.28597,32.880066,4.95,1993-02-03T23:57:24.434000,10.652937,56, +-116.37714,31.968082,4.95,1993-03-25T21:35:47.638000,3.320995,56, +-116.36827,31.965773,5.55,1993-03-30T00:19:14.011000,4.198283,56, +-118.75736,37.746616,5.35,1993-04-06T21:45:48.277000,9.7547245,56, +-124.23873,40.394817,4.95,1993-04-18T10:14:46.787000,9.847997,56, +-124.357445,40.3174,5.45,1993-06-06T22:19:57.251000,6.653215,56, +-121.66864,40.737797,4.95,1992-07-10T14:41:55.754000,5.335747,57, +-116.83755,34.59498,5.85,1992-07-14T07:43:43.626000,1.810563,57, +-124.767914,40.358818,5.25,1992-09-23T21:21:59.009000,3.53887,57, +-118.79797,34.23007,5.15,1992-09-30T08:59:45.686000,5.488514,57, +-121.42724,39.743534,5.55,1992-12-20T07:28:29.174000,8.336083,57, +-121.44984,39.727077,5.55,1992-12-20T18:58:27.100000,8.959508,57, +-118.94287,37.61122,5.25,1993-06-22T03:40:06.588000,7.9035554,57, +-120.94024,36.174118,5.85,1992-07-31T05:45:58.671000,4.145354,58, +-124.34309,40.404602,5.25,1992-11-05T05:26:46.364000,7.4389625,58, +-121.6593,37.45885,5.05,1992-11-21T04:35:01.464000,12.569678,58, +-116.29301,32.071568,5.45,1992-12-26T10:53:05.756000,6.266585,58, +-124.346214,40.307873,5.65,1993-01-01T15:06:21.282000,7.4748387,58, +-119.30107,38.292267,5.75,1993-05-21T20:08:03.010000,1.3353554,58, +-119.27415,38.307854,5.45,1993-06-14T15:57:41.687000,2.9267879,58, +-115.75197,31.971153,6.15,1992-09-06T22:07:47.493000,5.730414,59, +-115.765495,31.940742,5.15,1992-11-11T02:08:28.090000,0.0001,59, +-115.80727,32.032173,5.35,1992-11-25T03:58:04.532000,5.5410137,59, +-118.37014,37.475075,5.15,1992-12-02T04:35:34.305000,8.246543,59, +-115.50662,32.388912,4.95,1992-12-20T19:48:34.681000,2.747083,59, +-120.50826,35.902103,5.05,1993-01-14T08:30:55.141000,5.005314,59, +-117.01775,35.11417,5.05,1993-01-24T02:20:43.225000,7.110229,59, +-116.325905,33.283092,5.45,1993-04-27T00:56:30.987000,9.642494,59, +-120.08575,41.217384,5.05,1993-05-19T21:57:45.359000,5.2377806,59, +-124.209656,40.363827,5.05,1992-07-30T08:22:09.073000,10.154805,60, +-120.80989,38.08324,5.25,1992-08-21T03:06:47.994000,13.477502,60, +-124.51226,40.36858,5.55,1992-09-21T06:52:40.469000,18.27164,60, +-124.46,40.34,6.693793,1992-10-06T19:13:02.308000,21.0,60, +-124.35212,40.224068,5.65,1992-10-06T19:15:59.202000,2.4052653,60, +-121.42242,42.542942,5.05,1992-10-06T21:55:26.113000,5.176481,60, +-124.5213,40.29778,5.35,1992-10-14T23:16:21.474000,1.4679999,60, +-124.32407,40.397545,4.95,1992-10-16T13:44:57.119000,5.692869,60, +-121.39859,35.83812,5.05,1992-11-07T22:53:07.399000,3.4961655,60, +-124.349266,40.353313,5.35,1992-11-10T05:57:46.357000,8.085799,60, +-124.54017,40.370163,5.75,1992-11-24T21:26:35.126000,21.547897,60, +-124.44855,40.27498,5.05,1992-12-30T01:40:03.487000,8.200756,60, +-121.32015,36.62106,5.05,1993-03-11T11:04:16.876000,4.838656,60, +-118.55905,34.243652,5.15,1993-04-23T09:03:49.179000,13.681444,60, +-123.486755,39.648933,4.95,1993-06-11T05:55:26.827000,5.7526636,60, +-118.003235,36.654175,5.65,1992-07-13T12:25:47.547000,7.890574,61, +-124.35029,40.28269,4.95,1992-07-14T13:27:23.672000,6.309321,61, +-124.221275,40.276134,5.75,1992-07-30T16:09:34.596000,9.3867035,61, +-115.79866,33.004787,5.15,1992-11-06T15:44:16.044000,3.3112302,61, +-118.23942,35.383984,5.45,1992-11-11T22:30:08.023000,11.7326975,61, +-115.11631,32.226864,4.95,1992-12-03T04:32:53.408000,12.499694,61, +-115.11322,32.238644,4.95,1992-12-03T05:31:07.283000,11.554031,61, +-115.587494,31.827784,5.15,1993-04-22T11:03:53.740000,4.846953,61, +-124.434715,40.403122,5.15,1992-07-31T10:43:25.194000,5.4248986,62, +-123.63667,37.501354,5.85,1992-09-03T12:16:23.628000,22.029232,62, +-124.29009,40.37979,5.05,1992-10-08T16:42:59.341000,7.9444413,62, +-116.36193,33.429226,5.45,1992-10-15T11:15:43.993000,4.280851,62, +-124.52861,40.36489,5.55,1992-11-04T02:30:38.566000,18.957909,62, +-116.31736,33.415653,5.05,1992-12-15T23:52:13.795000,6.814295,62, +-116.159744,31.717512,5.05,1993-01-08T20:08:30.717000,7.7062926,62, +-117.44655,35.706234,5.15,1993-01-31T07:41:28.146000,5.503464,62, +-124.215706,40.24706,5.15,1993-02-11T18:35:40.860000,8.971238,62, +-119.5669,38.699047,5.25,1993-04-23T05:13:09.517000,7.000146,62, +-117.37499,34.322685,5.65,1993-06-11T12:27:59.026000,9.282896,62, +-117.35748,34.279125,5.05,1993-06-11T12:36:42.547000,7.6886845,62, +-116.89338,35.51451,5.55,1992-07-16T04:00:19.921000,8.680831,63, +-124.20199,40.236847,5.05,1992-07-17T09:44:16.996000,9.331096,63, +-118.79422,35.138474,5.35,1992-08-25T12:40:22.199000,9.334782,63, +-115.66927,33.014023,5.35,1992-11-05T09:16:58.281000,6.176422,63, +-115.731476,33.405785,4.95,1992-11-13T11:25:07.500000,3.4295123,63, +-124.8454,40.943333,5.25,1992-11-19T05:58:19.009000,6.0192423,63, +-115.21806,32.29024,5.85,1992-11-26T16:19:38.675000,5.7603493,63, +-115.24078,32.276966,5.45,1992-11-30T15:12:04.493000,7.8550973,63, +-116.8031,33.67225,5.55,1992-12-02T18:27:32.707000,4.09026,63, +-124.393166,40.338974,5.85,1992-12-29T07:03:09.627000,7.4549613,63, +-120.524925,36.131317,5.05,1993-02-12T17:55:35.028000,9.259804,63, +-117.723274,34.156685,5.75,1993-04-05T13:39:21.554000,4.4527373,63, +-115.61213,32.838676,5.05,1993-06-09T15:31:40.337000,10.8891735,63, +-118.961044,37.559982,5.15,1993-06-12T14:36:35.304000,9.630592,63, +-124.1798,40.73197,6.25,1993-06-19T07:04:03.720000,18.630192,63, +-121.26461,35.69196,4.95,1992-08-31T15:02:43.931000,6.232673,64, +-115.86793,32.9846,4.95,1992-10-25T00:43:04.552000,3.6319282,64, +-124.486496,40.337265,4.95,1993-01-01T06:46:07.950000,22.23268,64, +-117.638245,34.285732,5.45,1993-01-04T20:59:30.061000,8.389308,64, +-116.88498,34.99301,5.15,1993-02-15T16:03:11.126000,18.217333,64, +-122.84898,40.449276,6.95,1993-05-12T18:50:26.023000,18.207727,64, +-122.93289,40.44794,5.05,1993-05-12T19:15:14.855000,14.823796,64, +-122.918526,40.50892,5.15,1993-05-12T19:22:12.575000,7.115031,64, +-122.81547,40.371555,5.05,1993-05-12T19:42:58.247000,11.727758,64, +-122.82005,40.38706,4.95,1993-05-12T19:43:21.266000,11.744472,64, +-122.70837,40.47538,5.15,1993-05-13T21:58:28.317000,6.9533153,64, +-124.515045,40.34566,4.95,1992-07-18T04:45:18.652000,19.756037,65, +-118.10262,34.072582,5.25,1992-07-29T11:27:37.705000,8.266494,65, +-115.076126,32.30278,5.35,1992-09-07T05:54:08.913000,7.850327,65, +-120.66729,36.243515,5.55,1992-09-30T21:44:05.633000,4.3172684,65, +-120.67461,36.249943,5.05,1992-10-06T10:05:57.695000,2.5362594,65, +-119.84397,39.53615,5.05,1992-10-14T22:11:45.648000,15.730212,65, +-119.77499,38.903503,5.45,1992-12-23T09:32:45.236000,16.62479,65, +-122.8883,37.980545,5.15,1993-02-02T12:45:49.009000,7.1415224,65, +-120.34211,36.030746,4.95,1993-03-16T06:52:26.018000,8.1234255,65, +-117.89078,36.032276,4.95,1993-03-19T15:05:13.395000,2.7400515,65, +-116.12835,36.84674,4.95,1992-07-02T14:35:31.796000,7.9193764,66, +-118.32127,37.92799,5.55,1992-08-09T16:34:17.364000,13.149875,66, +-118.303474,37.945473,4.95,1992-08-09T17:15:24.866000,6.922217,66, +-121.91453,36.78983,5.05,1992-08-19T20:28:24.901000,5.2595835,66, +-116.35502,34.03621,5.05,1992-09-11T05:59:46.808000,11.42375,66, +-121.92845,36.78845,5.75,1992-10-03T23:42:39.490000,6.3884807,66, +-115.85987,31.730175,5.15,1992-11-19T09:32:30.217000,6.0132,66, +-124.191734,40.283897,5.85,1992-11-24T15:38:19.464000,6.9602313,66, +-124.4924,40.400345,5.35,1992-11-25T11:06:49.833000,18.652498,66, +-124.31868,40.350483,4.95,1992-12-10T12:04:14.313000,7.0413446,66, +-124.11831,40.234234,5.55,1992-12-24T19:03:24.592000,12.55297,66, +-118.43984,37.50182,5.45,1993-03-14T17:04:57.968000,3.9235554,66, +-117.47857,35.6783,5.35,1993-04-04T04:37:22.723000,12.715549,66, +-124.27529,40.286736,5.15,1993-04-17T00:14:20.908000,10.551364,66, +-121.07559,35.679707,5.15,1993-05-04T21:55:05.291000,7.443542,66, +-116.38186,34.113876,5.05,1992-07-02T07:23:04.859000,4.781056,67, +-124.56368,40.32576,5.05,1992-07-28T09:53:32.279000,15.953943,67, +-124.47592,40.315544,5.35,1992-09-19T14:37:13.341000,0.8559812,67, +-118.87676,37.54502,5.35,1992-11-29T00:07:22.507000,8.749418,67, +-124.55931,40.414814,4.95,1992-12-08T04:06:06.591000,18.271349,67, +-120.69823,34.402985,4.95,1993-04-23T04:46:59.658000,6.946781,67, +-121.71458,36.961823,5.35,1993-05-12T04:11:37.494000,20.24885,67, +-121.56725,37.254852,5.05,1993-06-04T22:21:20.472000,13.036194,67, +-118.21906,34.970722,5.15,1992-08-29T21:11:30.362000,20.811949,68, +-116.82467,34.606483,5.75,1992-09-03T03:01:11.874000,4.295359,68, +-124.389854,40.315998,5.65,1992-10-12T13:45:10.249000,7.431408,68, +-118.10295,32.531345,5.35,1992-11-03T18:19:27.142000,5.6629796,68, +-121.69491,37.474697,4.95,1993-01-09T17:47:48.702000,8.4543915,68, +-121.63678,36.839302,5.55,1993-03-25T05:22:24.384000,9.202812,68, +-119.82152,34.43406,5.45,1993-06-16T14:53:30.434000,8.7515545,68, +-116.33081,33.957348,5.05,1992-07-29T10:02:27.851000,4.7885356,69, +-118.300446,34.160496,5.15,1992-09-04T18:57:19.830000,17.374624,69, +-115.42639,32.153122,5.15,1993-01-16T07:32:07.390000,5.264404,69, +-116.07453,33.26792,5.45,1993-01-29T17:37:53.181000,6.643561,69, +-124.1314,40.341778,5.15,1993-02-17T18:39:10.960000,14.164086,69, +-124.54442,40.398716,5.65,1993-02-24T07:04:01.705000,17.04512,69, +-117.89192,33.50676,5.75,1993-03-15T09:10:30.046000,8.417141,69, +-117.88201,33.514446,5.15,1993-03-18T17:41:12.759000,5.3993425,69, +-120.15661,36.090023,5.15,1993-05-01T19:20:19.898000,8.602952,69, +-122.91469,39.389675,5.35,1993-05-03T20:58:40.139000,15.081708,69, +-121.72164,37.345005,5.05,1993-05-23T18:20:07.019000,18.27265,69, +-124.54491,40.371994,4.95,1992-09-16T00:55:53.993000,22.10844,70, +-115.58799,33.158657,5.35,1992-09-19T07:36:45.588000,6.714501,70, +-124.97718,40.869442,4.95,1992-09-30T10:12:25.741000,8.639555,70, +-121.998955,37.59328,5.25,1992-10-04T20:57:40.330000,4.6899166,70, +-118.938675,37.644577,4.95,1992-10-06T13:01:42.647000,7.134324,70, +-116.936104,34.861225,5.75,1992-11-20T02:24:43.192000,6.640062,70, +-124.18209,40.401485,5.15,1992-11-23T04:16:27.797000,10.897264,70, +-124.19142,40.380367,5.55,1992-12-27T04:26:17.210000,11.044706,70, +-124.55939,40.38638,5.35,1993-01-03T02:41:39.169000,21.292017,70, +-118.61541,34.37597,5.35,1993-01-15T21:26:57.944000,18.714203,70, +-124.522896,40.165302,4.95,1993-03-11T22:23:37.734000,9.49887,70, +-119.62417,38.807537,5.25,1993-03-29T14:16:46.835000,9.260894,70, +-124.45019,40.416424,5.55,1993-04-03T15:34:42.668000,5.383175,70, +-119.90406,38.80749,5.25,1993-05-25T23:05:42.778000,6.7318716,70, +-124.6,40.34,6.3526235,1992-07-14T03:53:22.529000,3.0,71, +-116.34198,34.081936,5.75,1992-08-09T05:37:44.325000,5.089137,71, +-115.59305,33.132767,5.05,1992-08-30T04:22:07.998000,7.208321,71, +-124.41555,40.38561,5.45,1992-10-03T00:05:35.522000,5.692967,71, +-122.8067,39.53469,5.15,1993-06-03T02:39:11.456000,4.385322,71, +-119.82486,39.243687,5.15,1993-06-05T20:07:51.830000,6.0944624,71, +-119.73751,39.271305,5.05,1993-06-17T12:41:20.541000,8.372367,71, +-120.37291,35.97675,5.15,1992-07-28T06:12:36,8.699571,72, +-124.25713,40.37854,4.95,1992-08-11T00:24:38.106000,9.391185,72, +-117.303856,34.409256,4.95,1992-09-07T02:19:08.683000,18.920227,72, +-124.8247,40.014942,6.55,1992-09-15T06:12:50.549000,12.377176,72, +-124.912636,39.966072,6.75,1992-09-15T07:04:35.896000,8.821323,72, +-124.79807,40.040524,5.15,1992-09-15T07:13:31.248000,5.1703877,72, +-124.39415,40.656483,4.95,1992-09-15T07:17:41.830000,6.376011,72, +-124.877785,40.042202,5.95,1992-09-15T20:27:46.197000,10.994095,72, +-115.75147,33.272125,5.45,1992-09-18T00:13:39.038000,10.627369,72, +-124.93755,40.01194,4.95,1992-10-27T05:14:55.894000,12.627669,72, +-124.93551,40.004654,5.55,1992-11-14T15:27:03.717000,12.420216,72, +-124.952896,40.026585,5.25,1992-11-19T19:19:28.424000,13.464899,72, +-117.81795,34.256195,5.15,1992-12-14T21:38:25.250000,6.302125,72, +-116.04108,33.681297,4.95,1992-12-25T04:18:47.896000,7.137315,72, +-120.02779,36.836308,5.15,1992-12-27T08:44:10.483000,2.9766903,72, +-116.070656,32.670067,5.25,1993-04-01T08:05:01.619000,4.298438,72, +-116.07494,32.690067,5.15,1993-04-01T16:24:27.223000,3.8687792,72, +-116.07642,32.690006,5.25,1993-04-01T19:56:10.073000,4.748876,72, +-121.47181,37.31672,5.55,1993-04-12T04:47:05.527000,8.5463705,72, +-124.25572,40.329586,5.15,1993-05-11T13:52:38.017000,8.670882,72, +-124.26155,40.323437,5.55,1993-05-11T13:57:41.264000,8.677,72, +-118.37775,35.68482,5.35,1993-05-16T12:08:14.272000,6.1148024,72, +-117.49237,37.515507,5.15,1992-07-14T08:15:58.278000,2.6598637,73, +-123.96387,39.884228,5.05,1992-07-30T07:09:15.238000,1.7007805,73, +-124.10411,40.31383,5.05,1992-08-13T18:30:19.206000,8.596565,73, +-120.706474,37.08358,5.25,1992-08-26T20:19:49.163000,6.5995903,73, +-117.783966,33.7847,5.15,1992-08-30T04:29:38.166000,6.0837035,73, +-117.79816,33.776558,4.95,1992-08-31T03:43:33.732000,6.810958,73, +-125.04888,40.776234,5.05,1992-10-14T23:50:19.507000,7.3941436,73, +-124.41959,40.43575,5.45,1992-10-16T17:06:57.863000,20.490059,73, +-118.89891,38.01827,5.25,1992-11-15T22:17:31.986000,6.027109,73, +-117.76694,35.233788,6.05,1992-12-14T13:24:23.744000,9.519213,73, +-117.81922,35.251,5.35,1992-12-15T04:30:39.121000,10.271977,73, +-116.65551,32.585175,6.25,1992-12-16T21:47:26.952000,5.317222,73, +-116.69469,32.625805,5.05,1992-12-18T12:18:02.411000,1.8058223,73, +-117.809875,35.240086,5.05,1992-12-19T06:30:02.230000,13.543945,73, +-123.128815,39.594395,5.05,1993-01-02T07:04:24.060000,10.177078,73, +-116.02,34.54,6.7187543,1993-02-04T11:53:25.789000,11.0,73, +-116.015594,34.561443,5.15,1993-02-23T19:31:51.346000,7.5423665,73, +-125.19119,40.42378,4.95,1993-04-11T10:27:04.972000,12.118744,73, +-115.9996,34.568233,4.95,1993-05-06T21:29:29.259000,9.130317,73, +-124.40209,40.237564,5.25,1992-07-01T23:44:09.588000,5.7949924,74, +-120.66111,34.212193,5.25,1992-09-22T10:35:37.573000,10.116282,74, +-115.9802,31.784555,5.25,1992-10-14T14:02:36.579000,4.997729,74, +-118.24542,38.095135,4.95,1992-11-12T09:15:51.438000,12.616196,74, +-117.42583,34.1896,5.05,1992-12-21T02:15:31.402000,10.256639,74, +-123.97728,40.367985,5.15,1993-01-11T06:24:04.373000,5.1198425,74, +-122.73478,38.927124,5.25,1993-01-19T22:03:38.448000,8.273856,74, +-116.37306,34.092262,5.45,1993-02-21T18:31:18.094000,10.906274,74, +-122.858055,39.18768,5.35,1992-09-02T19:42:00.126000,10.779758,75, +-120.457306,36.17128,5.45,1992-10-13T03:44:27.868000,18.926792,75, +-124.28417,40.248573,5.95,1992-10-29T12:20:38.885000,8.090591,75, +-116.571304,34.467976,5.25,1992-12-19T10:36:40.487000,5.671432,75, +-124.37643,40.28522,5.55,1993-02-08T12:02:10.979000,6.489426,75, +-124.38194,40.280006,5.45,1993-02-08T13:19:35.253000,8.801736,75, +-118.07888,32.71271,5.45,1993-02-10T04:20:13.909000,11.588787,75, +-120.274315,37.026386,5.25,1993-04-26T11:29:44.172000,1.3543013,75, +-125.15802,40.57632,5.85,1993-05-13T19:06:08.342000,10.574458,75, +-125.18744,40.587856,5.15,1993-05-13T19:41:02.372000,7.2145967,75, +-125.18892,40.585186,5.15,1993-05-13T19:52:40.134000,4.8783574,75, +-117.19929,34.14616,4.95,1993-05-22T18:07:08.687000,5.774953,75, +-121.017,36.55596,5.05,1993-06-17T13:42:48.825000,8.859463,75, +-120.998505,36.56288,5.15,1993-06-17T22:02:48.725000,9.235029,75, +-124.52561,40.41568,5.25,1993-06-20T07:15:36.969000,17.113674,75, +-124.18038,40.283573,5.25,1992-07-31T07:13:11.930000,11.480225,76, +-124.43684,40.284515,4.95,1992-08-21T04:25:41.231000,7.3155093,76, +-117.7407,32.19529,5.25,1992-11-13T09:38:44.521000,6.292514,76, +-117.73785,32.20927,5.45,1992-11-13T10:52:35.565000,6.017071,76, +-125.03928,40.384624,5.65,1992-12-05T13:22:10.982000,5.476214,76, +-116.38146,34.111546,5.25,1992-12-12T02:31:06.487000,7.952058,76, +-117.73735,32.184464,5.35,1992-12-19T20:01:36.185000,6.0627837,76, +-120.07281,39.53115,4.95,1993-01-26T06:49:25.314000,10.921605,76, +-118.31547,36.687786,5.05,1993-04-22T05:46:07.910000,4.5451617,76, +-121.65494,37.419353,5.05,1993-05-03T03:24:58.361000,7.5312634,76, +-122.760796,38.742172,5.25,1993-06-23T02:11:16.435000,3.70008,76, +-124.14627,40.349545,5.15,1992-08-15T12:56:09.104000,11.421975,77, +-115.394165,32.79747,5.65,1992-11-16T08:02:17.644000,5.4891653,77, +-124.52028,40.358543,5.25,1992-11-29T20:27:35.427000,18.276915,77, +-116.32007,34.022667,5.55,1993-02-13T12:31:31.796000,20.574337,77, +-116.300064,34.041492,5.45,1993-02-13T22:08:22.806000,20.63531,77, +-120.9191,39.672897,5.15,1993-03-19T13:30:17.799000,8.408092,77, +-120.41722,35.864853,5.8987956,1993-04-02T18:44:24.555000,7.6862097,77, +-124.53004,40.399273,4.95,1993-04-15T10:57:29.939000,18.210188,77, +-118.87637,37.50459,6.05,1993-05-21T23:22:53.881000,5.3907924,77, +-118.870316,37.54403,6.35,1993-05-21T23:25:03.394000,8.062907,77, +-118.80457,37.528618,5.05,1993-05-21T23:42:32.685000,7.4944153,77, +-118.85207,37.463715,5.65,1993-05-22T00:20:29.810000,6.4328136,77, +-118.89818,37.533245,5.85,1993-05-22T04:03:31.310000,8.1494465,77, +-118.859726,37.44561,4.95,1993-05-22T08:06:45.153000,10.875744,77, +-118.89754,37.67339,5.25,1993-05-24T10:21:31.593000,9.791926,77, +-118.86999,37.512592,5.45,1993-05-26T15:00:35.418000,2.4197469,77, +-119.935265,34.89065,4.95,1993-06-13T16:54:45.696000,5.9736032,77, +-119.94812,34.888206,5.15,1993-06-13T17:43:14.701000,5.7431536,77, +-116.28055,33.959316,5.05,1992-09-22T14:38:53.671000,4.8533525,78, +-121.61951,36.930004,5.05,1992-12-10T03:17:00.568000,6.872328,78, +-124.49081,40.378437,4.95,1993-02-13T13:29:41.502000,20.74028,78, +-124.328514,40.31925,5.75,1992-07-17T12:39:07.898000,7.0202765,79, +-124.215546,40.385174,5.05,1992-07-24T21:10:11.791000,9.865294,79, +-118.74822,37.820995,4.95,1992-09-03T08:53:46.381000,3.5061836,79, +-124.92085,40.29249,5.25,1992-10-06T15:13:54.157000,8.270323,79, +-122.92595,40.45099,5.15,1992-10-17T05:12:41.991000,4.287654,79, +-124.48096,40.324795,4.95,1992-10-26T02:10:38.146000,19.336786,79, +-124.3864,40.25955,4.95,1993-01-08T02:43:57.930000,6.259051,79, +-116.45731,36.694717,5.45,1993-01-22T17:43:50.986000,9.346376,79, +-121.44806,35.839237,4.95,1993-03-29T05:32:33.205000,5.7156916,79, +-116.06554,32.682224,5.05,1993-05-22T05:56:24.448000,6.617359,79, +-116.31682,33.999924,5.05,1993-05-22T13:47:11.979000,4.958046,79, +-124.24041,40.26231,5.55,1993-06-22T12:12:55.434000,9.135626,79, +-124.416,40.267063,5.45,1992-07-01T11:31:31.395000,5.4568405,80, +-122.589325,40.70284,5.05,1992-07-30T22:11:51.229000,12.74194,80, +-124.39909,40.30048,5.75,1992-08-18T07:17:49.754000,7.0344586,80, +-124.52301,40.39359,5.85,1992-09-30T08:54:48.143000,19.341383,80, +-124.35606,40.291584,4.95,1993-01-09T13:14:07.214000,6.164184,80, +-124.50983,40.41177,4.95,1993-01-16T11:11:46.208000,9.496854,80, +-118.75365,37.526936,5.05,1993-06-27T12:18:05.673000,7.526782,80, +-121.09147,36.504696,5.25,1992-08-05T12:28:57.337000,9.400488,81, +-124.19705,40.42522,4.95,1992-08-07T13:21:36.912000,10.741541,81, +-124.19482,40.412933,5.15,1992-08-07T13:34:52.908000,10.258857,81, +-124.48,40.38,6.628068,1992-08-15T11:49:48.721000,19.0,81, +-124.6838,40.36988,4.95,1992-08-15T11:59:12.271000,1.4653003,81, +-124.44895,40.275173,5.05,1992-08-15T12:12:23.720000,9.022912,81, +-124.470184,40.282887,5.15,1992-08-15T14:15:44.446000,1.3140583,81, +-124.44434,40.275127,4.95,1992-08-17T02:25:00.243000,8.468511,81, +-124.347694,40.259876,5.45,1992-08-20T01:48:37.453000,6.715252,81, +-118.7141,35.73137,6.35,1992-09-12T10:16:51.636000,4.260433,81, +-118.6865,35.69357,4.95,1992-09-12T10:34:36.466000,7.5842023,81, +-118.66458,35.781433,5.35,1992-09-12T12:07:53.625000,8.03402,81, +-124.4828,40.21446,5.15,1992-09-23T10:53:14.750000,6.64414,81, +-117.38389,35.775944,5.05,1992-11-04T10:47:47.195000,10.449018,81, +-116.325066,34.06191,5.15,1992-12-01T08:29:38.996000,11.048153,81, +-117.38167,35.47504,5.55,1992-12-03T11:10:09.531000,22.579817,81, +-121.41601,41.499924,5.45,1992-12-07T16:47:28.149000,3.3218544,81, +-121.412964,41.521847,5.35,1992-12-17T12:48:07.051000,3.3806617,81, +-124.48565,40.195984,5.15,1992-12-17T14:27:24.758000,6.561826,81, +-116.801636,34.412395,5.35,1992-07-07T17:04:02.039000,1.1313584,82, +-116.80376,34.43545,5.25,1992-07-08T07:37:01.529000,2.3288999,82, +-119.94179,37.826134,4.95,1992-08-09T16:13:25.556000,13.296321,82, +-123.03036,39.042835,5.05,1992-09-30T01:04:49.664000,16.17059,82, +-116.93336,35.05481,5.15,1992-12-28T16:10:51.816000,6.5317144,82, +-124.552895,40.406975,5.35,1993-01-02T06:32:11.826000,17.07576,82, +-124.351845,40.369617,5.05,1993-01-10T15:51:25.945000,6.7017217,82, +-124.39253,40.5887,5.15,1993-02-03T00:02:54.326000,3.0188985,82, +-124.35586,40.561733,5.35,1993-02-03T09:15:31.480000,3.343941,82, +-115.633644,32.42052,4.95,1993-04-11T11:04:50,6.696045,82, +-124.57053,40.42587,4.95,1993-04-28T15:43:41.691000,16.409536,82, +-118.83321,37.516502,5.25,1993-05-21T16:26:11.469000,16.209671,82, +-124.88375,40.790756,5.05,1993-06-25T05:56:47.528000,6.5426598,82, +-116.40416,34.38387,4.95,1993-06-27T12:18:24.795000,2.5493329,82, +-118.536285,35.41042,5.35,1992-08-04T11:36:14.993000,5.7169285,83, +-124.580605,40.370796,4.95,1992-08-07T01:35:39.565000,6.2812715,83, +-121.29712,36.787506,5.35,1992-10-11T21:21:14.816000,15.566506,83, +-124.990036,40.847942,5.35,1992-10-15T20:15:43.557000,3.8823965,83, +-119.64357,38.83225,5.15,1992-10-18T05:32:33.130000,8.451287,83, +-124.4,40.28,7.6814165,1992-12-25T23:49:33.596000,7.0,83, +-123.93726,39.496273,5.35,1992-12-25T23:50:59.565000,0.86014795,83, +-123.99769,39.721592,5.25,1992-12-25T23:56:48.768000,7.525346,83, +-123.86595,39.333317,5.35,1992-12-26T00:04:36.452000,3.3493054,83, +-123.78335,39.138924,5.45,1992-12-26T00:14:12.151000,4.7248974,83, +-123.79964,39.18592,5.35,1992-12-26T00:24:49.778000,4.898944,83, +-123.86695,39.33065,5.15,1992-12-26T02:13:29.350000,2.150278,83, +-124.23286,40.130505,4.95,1992-12-26T02:45:16.895000,10.141236,83, +-123.86461,39.319553,4.95,1992-12-26T03:24:01.146000,6.741137,83, +-125.12719,40.39191,5.25,1992-12-26T03:27:52.044000,9.679671,83, +-123.943756,39.523666,5.35,1992-12-26T05:05:13.442000,4.56363,83, +-123.85879,39.316128,4.95,1992-12-26T11:33:34.249000,5.1565123,83, +-124.2783,40.163654,5.05,1992-12-26T16:56:31.967000,10.820443,83, +-124.80165,40.345932,5.25,1992-12-26T23:54:42.413000,6.9174905,83, +-123.93821,39.46218,5.05,1992-12-27T15:15:24.616000,2.188553,83, +-124.0448,39.804977,4.95,1992-12-28T09:46:00.424000,4.507296,83, +-123.89819,39.374413,5.25,1992-12-30T20:02:40.512000,8.068899,83, +-124.06367,39.980453,5.25,1992-12-30T23:34:35.705000,1.7923381,83, +-124.225525,39.956516,4.95,1993-01-01T00:54:37.242000,21.722181,83, +-123.8215,40.48273,5.25,1993-01-01T20:21:42.449000,5.5890646,83, +-123.8759,39.349957,5.05,1993-01-06T08:29:10.097000,5.3792744,83, +-124.27469,40.17009,5.05,1993-01-16T04:50:52.039000,2.819632,83, +-123.890945,39.361546,5.05,1993-01-23T11:48:58.783000,3.2158422,83, +-124.95355,40.38814,4.95,1993-01-24T07:19:56.842000,4.7593517,83, +-124.00554,39.570896,5.05,1993-01-25T04:24:29.168000,9.983977,83, +-125.23548,40.38933,5.15,1993-01-28T10:34:34.252000,6.0486083,83, +-124.23747,40.138077,5.75,1993-02-02T03:59:19.130000,5.02984,83, +-124.23189,40.124863,4.95,1993-02-02T05:15:49.435000,5.7871594,83, +-119.69624,36.022293,5.65,1993-02-03T10:51:53.134000,8.992363,83, +-119.67539,36.066383,5.75,1993-02-04T06:27:03.715000,10.355718,83, +-119.68227,36.112103,4.95,1993-02-04T11:50:06.076000,16.049301,83, +-123.94198,39.438396,5.15,1993-02-04T11:50:18.075000,11.43091,83, +-124.57681,40.329765,5.15,1993-04-07T22:05:42.374000,0.1155853,83, +-124.49397,40.377453,4.95,1992-06-30T05:36:27.401000,21.672585,84, +-124.45896,40.331673,5.65,1992-08-11T18:11:24.758000,17.450388,84, +-120.496025,36.2834,5.75,1992-10-22T01:01:14.681000,9.019089,84, +-120.90824,34.313404,5.05,1992-12-08T03:13:35.224000,3.8425314,84, +-120.4104,39.585575,4.95,1992-12-19T00:50:05.798000,4.986797,84, +-124.445045,40.349934,4.95,1992-12-31T08:56:23.835000,17.238556,84, +-121.32585,36.58438,4.95,1993-06-07T12:36:34.602000,6.23387,84, +-116.60225,34.2459,6.15,1992-06-28T18:41:24.040000,6.2001824,85, +-116.5933,34.26718,5.05,1992-09-10T23:58:49.123000,5.5736127,85, +-118.37049,35.69347,5.45,1992-11-08T14:44:51.402000,7.2434087,85, +-115.73733,32.06515,4.95,1992-11-12T21:34:56.154000,7.9011,85, +-123.13211,39.57927,5.25,1992-11-20T08:57:59.583000,21.684353,85, +-123.15116,39.604973,5.75,1992-12-05T03:10:53.631000,21.995249,85, +-116.42,35.62,6.931767,1993-02-28T16:50:08.716000,9.0,85, +-116.66821,35.588745,5.35,1993-02-28T17:20:41.191000,8.074494,85, +-116.50687,35.725677,5.25,1993-03-01T09:45:49.173000,4.3020124,85, +-116.43382,35.587616,5.05,1993-03-04T09:01:07.934000,4.793974,85, +-116.72217,35.594906,5.35,1993-03-04T16:14:42.798000,13.101314,85, +-116.27702,35.76201,5.15,1993-03-23T05:59:44.759000,5.817335,85, +-116.46383,35.652374,5.45,1993-04-19T22:49:15.435000,4.3274317,85, +-124.34834,40.315407,5.05,1992-08-07T03:13:45.080000,8.292118,86, +-124.32682,40.2831,5.35,1992-10-14T04:15:16.591000,9.0381775,86, +-121.954575,37.970592,6.680419,1992-10-29T07:41:57.831000,4.48,86, +-121.87717,37.90079,5.25,1992-10-29T08:43:45.425000,13.16093,86, +-121.78715,37.833427,6.15,1992-10-29T11:32:52.405000,14.624508,86, +-121.81907,37.820854,4.95,1992-10-30T10:18:00.304000,17.367455,86, +-121.87972,37.896862,5.25,1992-11-02T03:05:27.785000,9.883619,86, +-116.72047,33.516052,5.15,1992-11-09T08:32:13.348000,8.785517,86, +-122.61245,36.39938,5.65,1992-11-10T22:38:06.032000,4.662522,86, +-120.339066,35.78962,5.9905787,1992-11-24T18:18:02.542000,7.489452,86, +-120.36605,35.801044,5.05,1992-11-25T17:20:22.059000,0.81413096,86, +-124.187546,40.322113,4.95,1992-12-23T06:26:06.573000,10.634741,86, +-116.328354,33.414173,5.95,1993-04-17T14:16:08.611000,8.421629,86, +-118.11177,38.168434,5.35,1993-06-06T02:33:27.686000,13.958658,86, +-118.101395,38.142483,5.15,1993-06-07T00:07:19.583000,18.116768,86, +-115.74914,32.052845,5.25,1992-07-06T12:07:44.933000,15.638889,87, +-120.47215,36.194393,5.05,1992-07-23T17:45:32.977000,11.903936,87, +-123.46392,39.745464,5.05,1992-09-20T13:21:59.311000,21.192295,87, +-123.473175,39.743378,5.15,1992-09-20T14:52:44.501000,21.216036,87, +-118.74442,38.22453,5.75,1992-10-21T00:15:04.951000,12.926288,87, +-119.02729,34.051453,4.95,1992-12-25T04:44:39.905000,8.255221,87, +-122.163246,36.872547,5.75,1993-01-01T15:43:35.832000,9.500623,87, +-118.375786,35.765133,5.55,1993-01-28T21:34:51.554000,5.006482,87, +-115.06,32.18,6.7653356,1993-01-31T13:35:18.639000,9.0,87, +-118.71203,34.435852,6.05,1993-04-05T19:31:08.237000,5.9917345,87, +-124.04341,39.87001,4.95,1993-04-13T12:25:14.146000,3.541121,87, +-122.186676,36.88038,5.45,1993-04-17T02:49:45.908000,12.083349,87, +-124.25661,40.25709,5.55,1992-08-02T08:00:13.306000,7.7543097,88, +-118.079315,34.190983,4.95,1992-08-08T13:41:57.328000,7.3573484,88, +-118.47173,35.33918,5.45,1992-09-05T12:04:06.531000,11.883414,88, +-124.41991,40.287476,5.65,1992-10-08T00:31:25.292000,6.8592625,88, +-118.30947,35.644997,5.15,1992-12-12T13:23:59.859000,8.16143,88, +-118.38168,37.519527,5.25,1992-12-17T11:18:52.210000,6.8941717,88, +-116.235,32.961926,5.15,1993-01-05T05:43:25.872000,5.2961526,88, +-117.59406,34.335426,6.3001337,1993-03-30T05:40:09.253000,6.55,88, +-117.61359,34.356873,4.95,1993-03-30T06:17:03.313000,6.736593,88, +-122.80964,38.73755,6.978551,1993-05-31T22:37:34.195000,7.4444323,88, +-122.765396,38.657017,5.75,1993-05-31T22:50:22.257000,1.8819772,88, +-122.72868,38.669952,5.65,1993-06-01T00:44:10.852000,9.8563795,88, +-122.95212,38.907288,5.25,1993-06-01T14:38:11.423000,7.4545403,88, +-122.92398,38.793716,4.95,1993-06-11T21:23:59.614000,0.76039743,88, +-117.302376,35.917114,5.15,1992-08-03T12:58:37.616000,5.8090634,89, +-120.36,35.82,6.098612,1992-10-24T21:37:40.298000,7.0,89, +-121.89692,39.434803,5.35,1992-11-02T03:30:57.213000,8.777307,89, +-116.33367,33.995358,5.15,1992-11-11T21:10:01.739000,7.6943545,89, +-124.446434,40.335243,4.95,1992-06-29T08:38:21.421000,5.5015473,90, +-124.54941,40.374813,4.95,1992-07-19T12:40:55.862000,20.666758,90, +-122.74517,38.935863,5.35,1992-11-05T08:00:20.178000,3.851566,90, +-120.52904,36.509014,5.35,1992-11-20T21:21:04.422000,6.138235,90, +-120.541046,36.331074,5.55,1993-03-31T15:28:07.582000,4.8786287,90, +-118.10851,35.781036,5.25,1993-05-05T16:31:42.059000,12.1656475,90, +-122.58499,42.080765,5.35,1992-08-05T09:08:30.247000,12.01036,91, +-124.326454,40.254097,5.25,1992-10-22T11:03:06.798000,6.609567,91, +-121.64569,36.949223,5.75,1992-12-21T13:39:20.050000,5.910861,91, +-121.66721,36.964584,5.65,1992-12-21T13:50:15.217000,7.536619,91, +-121.304825,36.826904,5.05,1993-03-06T12:51:53.668000,5.8309875,91, +-124.14882,40.296974,4.95,1993-03-09T01:12:58.712000,13.277195,91, +-115.218796,32.43154,5.65,1993-04-10T02:02:37.490000,7.33828,91, +-124.320694,40.332546,5.35,1993-06-12T04:25:16.320000,7.148854,91, +-124.46,40.34,6.628068,1992-09-10T01:22:51.511000,19.0,92, +-124.37841,40.27012,4.95,1992-09-10T05:05:20.380000,4.996919,92, +-124.36933,40.230488,5.25,1992-09-14T13:30:34.848000,1.7553247,92, +-124.547615,40.36909,5.75,1992-10-27T03:17:54.403000,20.59383,92, +-124.505714,40.391922,5.75,1992-10-28T15:56:30.395000,18.059175,92, +-120.882675,35.507,5.05,1992-11-16T11:03:25.218000,9.508952,92, +-120.69989,39.723686,5.35,1993-03-12T12:47:51.712000,7.3499994,92, +-117.29166,35.704086,5.05,1993-03-12T18:34:16.971000,5.587764,92, +-115.51172,32.38045,5.05,1993-04-15T20:44:51.700000,7.1443615,92, +-124.507866,40.347027,5.35,1992-07-07T12:06:51.909000,21.619688,93, +-116.442375,32.27508,5.05,1992-07-12T03:02:26.221000,8.1654,93, +-124.36841,40.27372,5.15,1992-07-12T23:10:47.857000,6.3293386,93, +-124.36586,40.262196,4.95,1992-07-13T08:43:36.483000,6.730118,93, +-115.29624,32.397793,5.15,1992-07-15T03:25:06.382000,12.974616,93, +-116.914185,34.172993,4.95,1992-09-24T04:22:25.905000,9.837289,93, +-124.19883,40.46477,5.05,1992-10-17T17:13:32.016000,4.9960065,93, +-119.312706,39.423443,5.45,1992-10-31T22:06:14.416000,12.118714,93, +-116.38297,31.76125,5.65,1993-01-31T15:33:51.496000,10.633162,93, +-115.21799,32.367012,4.95,1993-02-01T11:04:55.738000,5.1246147,93, +-122.335365,38.65125,6.1334887,1993-03-05T07:09:09.644000,7.811163,93, +-124.47617,41.16721,5.05,1993-05-12T19:51:26.024000,10.862766,93, +-124.42656,40.333515,5.05,1992-07-20T05:31:40.614000,6.5574594,94, +-114.958435,32.02732,4.95,1992-09-19T18:31:24.084000,9.3857155,94, +-117.66621,34.365993,6.3001337,1992-10-24T05:42:08.824000,12.164286,94, +-122.25903,40.5795,4.95,1992-10-24T09:52:25.455000,10.07189,94, +-117.6,34.34,6.3001337,1992-10-28T07:34:54.017000,5.0,94, +-117.62729,34.336594,5.25,1992-10-28T22:30:47.476000,4.0980034,94, +-120.87097,37.54174,5.25,1992-11-03T13:03:11.160000,12.203198,94, +-117.617386,34.355785,4.95,1992-12-17T10:42:03.962000,6.8778386,94, +-122.63642,38.423786,5.9986005,1993-01-03T02:16:41.552000,6.0,94, +-122.63397,38.41434,5.35,1993-01-03T02:37:42.550000,7.70418,94, +-120.218,39.696415,6.35,1993-01-03T22:24:04.777000,6.5095587,94, +-120.19358,39.677208,4.95,1993-01-03T22:59:48.912000,13.262306,94, +-122.606705,38.43182,5.25,1993-01-04T11:39:14.997000,2.6896176,94, +-124.46894,40.327675,5.85,1993-01-22T01:27:22.443000,17.538387,94, +-122.77984,38.787575,5.35,1993-03-28T07:57:09.744000,4.1553144,94, +-120.38594,36.28222,4.95,1993-04-28T11:58:29.570000,6.538233,94, +-122.457825,38.394344,5.35,1993-05-12T12:50:21.289000,17.197376,94, +-124.33469,40.320766,4.95,1992-11-18T13:41:03.505000,7.406787,95, +-120.11176,40.37673,5.55,1992-12-19T14:01:04.931000,13.512745,95, +-121.80418,41.289616,5.25,1993-01-17T20:58:43.719000,7.2129126,95, +-120.54326,42.456093,5.15,1993-04-23T17:40:39.058000,5.2264605,95, +-124.408455,40.386974,5.15,1993-04-30T08:52:59.012000,6.922378,95, +-116.44799,34.43591,5.05,1993-05-06T21:09:50.679000,18.330301,95, +-124.13718,40.395428,5.25,1993-05-13T21:51:48.117000,7.0795093,95, +-118.59091,38.004116,4.95,1993-05-29T21:55:41.586000,4.977666,95, +-115.6464,33.097687,5.85,1992-10-14T04:30:40.995000,15.704556,96, +-115.8715,32.744846,5.65,1992-11-17T21:59:52.842000,5.417926,96, +-115.64266,33.10809,5.15,1992-11-25T08:51:34.514000,15.543944,96, +-122.032326,40.172657,5.45,1992-12-14T11:23:58.464000,16.175934,96, +-116.59592,34.53777,4.95,1993-01-04T12:01:19.954000,6.691847,96, +-124.59606,40.395035,5.05,1993-05-15T14:41:49.380000,22.436426,96, +-124.50462,40.30268,4.95,1993-05-21T09:30:31.069000,17.038872,96, +-124.11977,40.26154,5.25,1993-06-11T06:56:13.572000,11.163583,96, +-124.48095,40.32349,5.25,1993-06-11T16:41:22.997000,17.636528,96, +-124.30986,40.264748,4.95,1992-06-29T02:17:16.679000,11.468061,97, +-124.46,40.38,6.3526235,1992-07-11T00:56:48.796000,19.0,97, +-124.462,40.27852,4.95,1992-07-13T18:30:37.682000,8.027355,97, +-124.194534,40.262558,5.25,1992-07-20T17:04:35.784000,10.26646,97, +-121.96199,37.18083,4.95,1992-07-23T13:37:58.753000,4.524217,97, +-124.376,40.241714,5.05,1992-07-27T16:35:40.749000,6.9887023,97, +-115.5843,36.521942,5.35,1992-10-22T00:51:37.184000,10.296286,97, +-124.353584,40.333885,5.45,1992-10-22T08:13:23.399000,9.718633,97, +-118.75623,37.69298,5.15,1992-10-23T02:02:23.963000,17.491198,97, +-115.84484,33.03358,5.05,1992-11-01T22:53:02.856000,3.723727,97, +-124.49988,40.334698,5.15,1993-01-11T17:17:02.326000,20.804127,97, +-117.70838,33.52963,5.85,1993-02-27T21:39:53.438000,6.6232586,97, +-117.709526,33.524246,5.25,1993-02-28T01:25:57.509000,7.658521,97, +-117.694466,33.556614,5.45,1993-06-10T04:00:02.061000,4.7620764,97, +-116.44497,34.123245,5.25,1992-06-30T07:23:48.465000,4.543839,98, +-117.85708,35.705822,6.05,1992-07-03T18:53:30.595000,9.267354,98, +-119.00298,34.01798,5.35,1992-07-08T03:00:07.159000,6.13738,98, +-116.241104,32.078606,5.85,1992-07-22T18:09:33.657000,10.084279,98, +-116.17177,32.092724,5.15,1992-07-23T00:49:50.868000,8.457717,98, +-124.7818,40.984074,6.05,1992-08-12T21:53:39.936000,7.215742,98, +-124.85147,41.04313,5.05,1992-08-14T07:35:49.725000,7.6999583,98, +-124.56,40.42,6.628068,1992-09-13T05:38:20.631000,21.0,98, +-124.56667,40.333736,4.95,1992-09-13T06:19:01.341000,3.9889274,98, +-124.83624,41.01431,4.95,1992-10-01T13:29:31.240000,7.578868,98, +-124.652214,40.66539,5.75,1992-10-18T17:42:02.518000,11.971756,98, +-124.644615,40.350822,5.75,1992-10-28T08:37:38.912000,2.6867664,98, +-124.56688,40.42022,5.25,1993-02-24T17:02:55.109000,17.539845,98, +-121.71331,37.394547,5.55,1993-05-27T18:31:54.897000,10.584551,98, +-124.6259,40.463272,5.55,1993-06-01T02:14:39.114000,17.354797,98, +-124.328224,40.3305,4.95,1992-07-01T12:13:06.082000,9.025205,99, +-124.48645,40.33444,4.95,1992-07-01T19:37:39.369000,21.59273,99, +-124.537186,40.3781,5.25,1992-07-22T21:02:30.806000,20.77054,99, +-121.5525,37.106884,4.95,1992-08-11T08:31:31.985000,0.5162134,99, +-118.3733,37.493183,5.35,1992-09-27T06:17:25.451000,5.9969416,99, +-124.16274,40.331196,4.95,1992-10-01T12:46:16.092000,11.471429,99, +-118.702934,34.673977,5.55,1992-10-28T04:04:27.438000,15.944714,99, +-120.610214,36.07253,5.65,1993-01-27T06:02:00.428000,8.863089,99, +-118.14227,33.552856,5.05,1993-02-03T19:51:39.584000,6.3927836,99, +-118.496735,38.220264,5.35,1993-03-08T00:35:45.374000,5.7754755,99, +-124.290085,40.351982,5.05,1993-03-14T12:52:01.570000,8.613677,99, +-120.58159,35.228615,5.25,1993-04-18T22:49:23.215000,5.132181,99, +-116.42281,36.697475,5.05,1993-05-05T19:31:36.549000,13.998106,99, +-120.06613,35.497486,5.15,1993-05-21T14:26:35.845000,15.788776,99, +-115.28826,32.535828,5.05,1992-09-22T07:58:18.794000,5.9484224,100, +-119.67559,38.859554,5.55,1992-10-13T14:44:44.496000,9.350491,100, +-124.538864,40.358627,5.65,1992-11-15T20:00:26.133000,21.129921,100, +-124.47988,40.339825,4.95,1993-01-07T01:17:09.600000,21.439022,100, +-116.70576,35.02444,5.15,1993-03-25T07:08:55.960000,15.158573,100, +-124.51976,40.346573,5.45,1992-06-29T02:05:10.746000,23.208895,101, +-118.86969,38.649216,5.35,1992-07-22T07:04:27.939000,4.98656,101, +-115.648964,33.180763,4.95,1992-08-18T06:05:10.814000,7.3907003,101, +-125.27797,40.69156,5.15,1992-10-15T08:11:34.204000,8.171027,101, +-124.37419,40.327526,5.25,1992-10-25T12:13:35.715000,6.663375,101, +-124.67352,41.045284,4.95,1992-11-28T04:34:56.261000,7.6723466,101, +-122.14911,37.930206,5.15,1993-01-24T22:26:35.878000,5.4246454,101, +-116.37245,33.030094,5.15,1993-02-05T07:09:48.579000,8.849531,101, +-116.59706,34.303646,5.05,1993-03-25T23:30:31.999000,7.0456185,101, +-119.51471,38.734447,5.25,1993-04-03T20:46:23.940000,15.590255,101, +-120.37024,42.93691,5.25,1993-04-04T09:58:11.638000,3.797181,101, +-119.520134,38.739647,5.45,1993-04-06T18:05:26.512000,14.063737,101, +-115.193054,33.299942,5.05,1993-04-11T10:34:35.492000,8.694698,101, +-122.14746,37.460056,4.95,1993-04-28T20:41:33.047000,20.726902,101, +-118.77828,35.78836,5.55,1992-07-23T18:39:39.296000,5.6556253,102, +-118.7866,35.784332,4.95,1992-07-25T01:22:57.750000,5.197723,102, +-124.414276,40.356762,5.05,1992-07-28T17:47:42.146000,16.131824,102, +-120.63958,39.641747,5.05,1992-08-13T05:40:16.468000,7.4070687,102, +-123.76976,40.255196,5.05,1992-09-21T00:56:56.420000,7.833292,102, +-122.4396,40.67224,4.95,1992-11-09T05:13:01.965000,10.368877,102, +-119.14,38.02,6.567126,1993-04-02T18:49:07.742000,9.0,102, +-119.12579,38.027042,5.15,1993-04-02T19:41:40.150000,3.4320207,102, +-119.12242,38.088135,5.25,1993-04-15T20:19:11.375000,8.236643,102, +-119.120575,38.03896,4.95,1993-05-07T00:11:25.854000,5.692263,102, +-119.12498,38.0502,5.55,1993-05-07T16:43:36.466000,6.6165156,102, +-124.38485,40.285316,4.95,1992-08-11T15:09:41.768000,7.4235177,103, +-124.32547,40.361023,5.35,1992-08-12T09:35:03.921000,8.174336,103, +-120.25281,40.167557,5.85,1992-10-03T09:34:28.257000,8.89148,103, +-120.23293,40.15487,4.95,1992-10-03T09:46:02.390000,9.836424,103, +-120.27576,40.178932,5.75,1992-10-03T11:02:50.267000,6.0514464,103, +-124.12816,40.271626,4.95,1992-12-29T12:03:47.284000,10.282132,103, +-116.11747,32.68919,5.35,1993-01-09T13:34:26.519000,4.9814777,103, +-115.880974,33.31574,5.65,1993-03-22T07:55:47.386000,8.302361,103, +-115.90367,33.312603,5.05,1993-04-06T15:25:59.406000,10.282786,103, +-118.26169,32.687527,5.55,1993-05-22T00:51:52.382000,8.465781,103, +-119.432755,38.224583,4.95,1993-05-30T10:47:22.921000,0.9779372,103, +-116.361176,31.991753,5.05,1993-06-07T00:43:51.417000,6.4238415,103, +-122.30611,39.669666,5.35,1992-07-18T21:34:56.548000,11.746509,104, +-122.897514,37.835033,5.15,1992-08-18T21:48:12.829000,5.9031534,104, +-122.89367,37.838753,5.55,1992-08-18T22:05:17.847000,6.9120736,104, +-124.53387,40.391224,5.35,1992-09-13T07:37:40.311000,17.972696,104, +-122.93379,38.827145,5.15,1992-10-25T12:09:59.011000,11.0352955,104, +-120.787895,36.178528,4.95,1993-01-14T11:30:57.487000,8.996975,104, +-115.42816,32.50025,4.95,1993-02-25T23:13:38.929000,5.4006205,104, +-122.83347,38.83374,5.35,1992-07-01T19:34:18.355000,3.3359966,105, +-116.30006,33.92395,5.05,1992-07-26T06:24:25.234000,5.376913,105, +-124.26021,40.25099,5.05,1992-10-17T06:07:59.756000,8.56154,105, +-116.34563,32.066532,4.95,1992-11-06T02:47:37.560000,6.3741393,105, +-118.09782,35.941418,4.95,1992-12-29T16:47:28.854000,5.3387074,105, +-116.420105,34.00394,5.15,1993-04-11T17:47:30.910000,7.6183205,105, +-116.42757,34.01094,5.45,1993-04-11T17:54:26.089000,9.240964,105, +-116.43473,34.013435,5.15,1993-04-11T18:00:46.963000,8.983962,105, +-120.966034,37.075333,5.55,1992-07-11T21:15:59.839000,1.4694557,106, +-118.36625,33.896553,5.35,1992-10-09T15:44:58.708000,6.6210566,106, +-118.35383,33.90265,4.95,1992-10-09T16:08:29.767000,6.9710274,106, +-119.65266,33.542183,4.95,1992-12-18T18:29:22.558000,5.5436993,106, +-115.01995,32.23146,4.95,1993-06-03T05:56:22.292000,6.158065,106, +-124.16544,40.329704,4.95,1992-06-28T12:58:29.354000,9.890986,107, +-118.788124,34.774708,5.45,1992-09-04T02:54:29.341000,14.779842,107, +-124.18872,40.32049,5.15,1993-03-27T06:11:48.192000,9.414898,107, +-116.26144,33.95347,4.95,1992-07-09T00:38:39.440000,11.082007,108, +-120.9,36.46,6.0210204,1992-07-15T10:25:47.474000,11.0,108, +-118.86009,37.536114,4.95,1992-08-30T13:07:43.364000,16.584246,108, +-118.614136,33.86549,5.25,1992-09-27T11:10:42.539000,4.9707,108, +-116.29834,33.99469,6.15,1993-01-26T05:30:59.908000,5.694511,108, +-124.22943,40.301304,5.05,1993-02-21T10:06:39.239000,8.195768,108, +-120.26947,40.930088,4.95,1993-03-19T10:22:33.055000,8.463582,108, +-120.0184,39.818356,5.15,1993-03-26T17:53:55.505000,6.1158495,108, +-120.16094,40.199856,5.05,1993-03-27T10:39:08.672000,4.35811,108, +-116.784485,35.08839,5.15,1993-03-27T16:45:20.116000,7.4685774,108, +-117.36078,34.00617,4.95,1993-04-19T20:19:28.335000,4.679125,108, +-116.736,34.84104,5.95,1993-05-14T06:00:40.076000,6.3885856,108, +-116.73193,34.885693,4.95,1993-05-14T11:56:04.197000,2.781122,108, +-121.95379,37.130035,5.25,1993-06-25T08:32:34.094000,4.37698,108, +-121.92206,37.12148,5.85,1993-06-26T04:14:02.006000,4.845785,108, +-124.506424,40.351353,4.95,1992-06-29T15:29:34.174000,19.236979,109, +-124.21669,40.30215,5.35,1992-07-08T11:11:39.069000,9.547999,109, +-120.41804,34.60088,5.05,1992-10-10T19:33:23.356000,10.564407,109, +-117.49414,34.169147,5.95,1992-11-27T06:48:58.036000,14.962079,109, +-117.02303,35.703262,5.25,1992-12-11T03:54:57.354000,5.484647,109, +-124.29827,40.27711,5.05,1992-12-23T12:44:28.580000,8.577745,109, +-116.66049,33.966377,5.65,1992-12-28T06:53:18.723000,9.26809,109, +-117.58505,34.331604,6.3001337,1993-02-04T16:55:26.294000,3.7428572,109, +-117.55332,34.265648,4.95,1993-02-04T17:44:38.991000,7.0512323,109, +-117.14,32.64,6.90027,1993-03-22T18:56:33.275000,11.0,109, +-117.274895,32.888405,4.95,1993-03-23T07:40:25.132000,5.151289,109, +-117.140076,32.671345,4.95,1993-03-23T22:54:16.241000,6.886916,109, +-122.58045,38.806416,5.65,1993-04-08T12:47:47.894000,5.5205274,109, +-121.00802,36.42324,5.948134,1993-06-12T14:42:55.774000,12.0,109, +-120.69813,35.951134,5.25,1992-08-30T16:27:14.614000,9.819977,110, +-119.60743,35.67508,5.35,1992-09-05T22:04:05.089000,6.118883,110, +-116.29365,34.04764,5.45,1992-09-06T05:17:28.234000,8.35566,110, +-119.517944,35.66208,5.45,1992-09-06T13:55:31.916000,7.2771454,110, +-119.539635,35.661472,5.45,1992-09-06T15:14:25.510000,8.175029,110, +-118.78045,37.52286,4.95,1992-09-13T08:43:26.352000,16.598282,110, +-116.30788,33.931145,5.35,1992-10-24T05:37:30.895000,0.0022961262,110, +-122.74,37.96,6.137487,1993-01-30T08:19:59.989000,9.0,110, +-122.65965,37.924736,5.05,1993-01-30T11:07:28.250000,3.8607635,110, +-122.76684,37.728657,5.05,1993-02-04T08:34:59.506000,13.985803,110, +-116.66695,32.718952,5.05,1993-03-17T05:50:13.725000,6.7322807,110, +-118.407486,38.17409,5.55,1993-05-03T03:46:58.730000,5.714922,110, +-119.02613,38.68146,4.95,1993-05-30T02:22:10.033000,9.774005,110, +-120.12884,35.57918,4.95,1992-08-03T08:56:32.849000,4.331083,112, +-116.94393,35.022312,5.15,1992-11-02T20:04:28.807000,4.7577,112, +-122.53376,40.86239,5.35,1993-06-05T00:58:56.810000,10.67327,112, +-124.160484,40.273926,5.05,1992-08-21T14:02:24.230000,10.450016,113, +-124.5,40.3,6.5521946,1992-09-16T01:04:45.124000,19.0,113, +-124.48515,40.29606,5.25,1992-09-16T01:29:49.820000,5.3590326,113, +-124.6568,40.355618,5.05,1992-09-16T01:43:07.925000,4.2697287,113, +-124.66202,40.36529,4.95,1992-09-17T09:32:05.821000,3.3366997,113, +-124.73247,40.498604,5.25,1992-10-07T01:34:57.712000,2.8367624,113, +-124.99756,40.425083,5.05,1992-12-17T15:35:50.004000,15.062343,113, +-121.12156,36.495293,4.95,1993-04-26T06:31:32.966000,7.3715105,113, +-124.41664,40.99452,5.05,1993-06-27T00:00:26.675000,0.43784422,113, +-124.82507,40.42789,5.05,1992-07-14T02:49:54.671000,5.7560096,114, +-124.6189,40.316578,5.45,1992-07-16T18:52:05.215000,17.910828,114, +-124.55302,40.383045,5.05,1992-07-20T02:38:25.252000,16.814777,114, +-121.2724,36.75035,5.45,1992-07-26T08:38:28.699000,10.8984995,114, +-124.37412,40.376095,5.85,1992-08-15T23:08:32.753000,4.1680126,114, +-117.595276,35.679688,5.15,1992-12-12T18:40:38.268000,2.0208225,114, +-124.44674,40.31748,5.55,1993-01-04T20:29:33.344000,20.42909,114, +-119.63062,35.100838,5.35,1993-02-14T14:36:52.098000,6.710932,114, +-120.32939,35.10475,5.15,1993-02-27T01:26:17.144000,5.701942,114, +-124.54206,40.415756,5.25,1992-07-25T13:13:02.932000,21.103266,115, +-121.65585,36.9084,6.05,1993-02-11T12:00:16.214000,5.3516927,115, +-124.36688,40.329403,5.45,1993-06-19T20:29:54.228000,8.28755,115, +-124.168015,40.345932,5.45,1992-08-03T09:13:01.318000,11.021508,116, +-125.12071,40.585487,6.45,1992-08-15T09:29:47.872000,8.577312,116, +-125.21923,40.6425,5.35,1992-08-19T13:06:38.566000,7.354106,116, +-124.40701,40.331074,5.25,1992-09-22T21:55:06.339000,6.05328,116, +-121.84074,40.09669,4.95,1992-09-26T05:47:55.466000,21.807823,116, +-124.525406,40.22403,5.15,1992-09-28T10:57:09.066000,2.5957718,116, +-124.26068,40.262203,5.05,1992-10-26T12:00:56.440000,7.012953,116, +-120.00538,36.162838,5.95,1992-11-25T23:02:48.405000,4.0406523,116, +-121.2,36.62,6.3945494,1992-11-30T03:25:41.469000,9.0,116, +-121.38196,36.73961,5.45,1992-12-10T03:24:09.720000,4.5044384,116, +-125.00114,40.2894,5.25,1993-01-09T23:01:10.474000,0.6208796,116, +-125.00707,40.28602,5.35,1993-01-09T23:19:03.195000,1.4487177,116, +-118.40867,38.32671,5.15,1993-01-21T17:40:43.597000,10.712796,116, +-118.38581,38.335197,5.35,1993-01-25T03:53:27.069000,6.46333,116, +-118.37177,38.404774,5.65,1993-01-25T04:08:28.852000,5.538878,116, +-118.32409,33.75053,5.05,1993-02-19T16:09:19.668000,11.458655,116, +-118.362686,38.39545,4.95,1993-04-01T11:24:36.097000,9.516601,116, +-116.48744,33.37608,5.15,1993-05-22T07:38:47.581000,3.5093749,116, +-117.9154,37.21843,5.15,1992-09-04T11:13:14.729000,9.920564,117, +-118.378395,32.923317,5.05,1992-10-26T03:18:25.191000,5.7885704,117, +-124.578865,40.58273,7.1548967,1992-11-18T04:24:18.636000,7.5454545,117, +-124.13318,40.356155,5.65,1992-11-18T04:39:41.432000,13.8117075,117, +-124.36574,40.512154,4.95,1992-11-18T04:48:22.656000,9.73133,117, +-124.024925,40.163616,5.05,1992-11-18T05:21:28.787000,16.542557,117, +-124.01785,40.188656,5.75,1992-11-18T10:40:13.620000,16.55603,117, +-124.63032,40.595192,5.05,1992-11-18T14:18:21.577000,5.9053483,117, +-124.09411,40.314125,4.95,1992-11-18T17:54:52.545000,5.2045574,117, +-124.594574,40.557808,4.95,1992-11-19T16:44:58.284000,5.959447,117, +-124.046875,40.29985,5.55,1992-11-20T18:55:16.702000,2.410139,117, +-124.003494,40.202423,5.35,1992-11-21T00:11:09.405000,1.3013909,117, +-124.646484,40.59122,5.85,1992-11-30T03:25:38.104000,4.5596757,117, +-124.63371,40.635708,5.05,1992-12-02T09:59:49.466000,4.224939,117, +-124.07657,40.304955,5.05,1993-01-27T11:05:15.867000,4.4654355,117, +-124.05656,40.252487,5.35,1993-03-19T06:16:22.489000,7.0512977,117, +-121.71064,36.9165,5.05,1993-04-21T07:10:32.845000,9.729109,117, +-124.09722,40.333553,4.95,1993-06-05T23:19:15.402000,4.9465456,117, +-121.93672,37.383503,5.05,1993-06-20T02:49:31.662000,12.920809,117, +-125.187454,40.405895,5.15,1992-08-11T08:03:14.697000,15.696346,118, +-120.45063,39.256226,4.95,1992-10-02T22:27:28.162000,8.582573,118, +-116.016685,33.2111,4.95,1992-10-07T02:52:09.607000,3.245698,118, +-121.57593,36.972515,4.95,1992-10-17T23:10:10.318000,7.3921185,118, +-123.628296,38.872784,4.95,1992-10-25T13:55:18.933000,10.65588,118, +-116.3667,34.052658,5.15,1992-10-27T22:15:48.952000,12.418742,118, +-124.55822,40.381508,5.95,1992-10-28T03:51:39.943000,17.588072,118, +-124.51107,40.4954,5.35,1992-12-10T02:13:36.823000,6.7597857,118, +-121.72863,41.01878,5.55,1992-12-14T22:11:29.717000,9.565397,118, +-116.475365,34.009922,5.35,1993-03-21T03:22:28.770000,1.6848098,118, +-116.385025,33.90605,4.95,1993-05-06T15:25:44.954000,7.8312306,118, +-119.14755,33.53366,4.95,1993-06-10T21:58:11.207000,9.039918,118, +-124.30299,40.340176,5.35,1992-09-09T23:24:37.620000,8.124575,119, +-124.27209,40.2954,4.95,1992-09-25T14:20:15.864000,8.595774,119, +-124.55243,40.37822,5.25,1992-11-12T08:17:26.635000,22.921095,119, +-115.182175,32.189945,5.55,1992-12-23T23:41:50.885000,20.371351,119, +-124.27628,40.414013,5.45,1992-12-28T23:35:38.395000,9.077349,119, +-119.91436,38.46135,6.15,1993-01-04T16:39:27.604000,7.6515365,119, +-122.05248,38.49372,5.05,1993-01-07T15:14:57.051000,8.553306,119, +-124.264145,40.398705,5.75,1993-02-11T10:27:30.226000,11.879462,119, +-121.01583,35.044792,5.15,1993-04-08T10:10:25.844000,13.113758,119, +-120.887314,34.33141,5.15,1993-06-09T10:21:33.158000,11.113527,119, +-121.66357,36.879265,5.15,1992-06-30T09:15:54.714000,8.387033,120, +-120.47725,35.03904,4.95,1992-08-08T00:35:21.735000,4.7217307,120, +-124.53822,40.405148,5.35,1992-08-24T10:31:00.837000,17.481527,120, +-124.26867,40.35384,5.55,1992-08-30T08:03:16.820000,3.3149838,120, +-124.2598,40.328506,5.25,1992-09-06T18:02:51.078000,8.091053,120, +-124.28811,40.349438,5.15,1992-09-22T08:33:28.435000,2.2668352,120, +-118.69204,38.172726,5.05,1992-09-26T01:34:15.524000,6.6614676,120, +-115.74792,34.19718,6.632966,1992-09-29T11:08:44.117000,4.225,120, +-115.79258,34.270126,5.35,1992-09-29T21:37:42.846000,10.439812,120, +-120.587555,39.752243,5.55,1992-10-03T09:58:10.975000,21.125896,120, +-115.71159,34.154583,5.15,1992-10-08T17:07:55.869000,4.4103484,120, +-121.67282,36.94931,5.35,1992-10-23T04:36:38.597000,4.6130986,120, +-118.63501,37.550568,5.15,1992-10-31T05:20:06.200000,3.3895342,120, +-124.291115,40.337048,4.95,1993-01-08T18:03:34.507000,8.232353,120, +-115.25341,32.23945,5.05,1993-02-09T11:16:15.509000,6.1080647,120, +-117.93547,32.973164,5.45,1992-08-04T18:08:50.128000,6.012628,121, +-122.67548,37.190098,4.95,1992-08-30T23:34:38.817000,8.021522,121, +-116.16925,33.974205,4.95,1992-09-02T01:17:19.862000,6.3600283,121, +-124.48971,40.35122,4.95,1992-09-24T14:01:37.514000,21.211626,121, +-120.31305,35.76453,6.066308,1992-12-06T23:51:10.339000,10.2,121, +-120.38355,35.838863,5.05,1992-12-07T00:05:36.661000,8.334923,121, +-120.45685,35.915253,4.95,1992-12-07T00:47:47.749000,2.858689,121, +-120.33437,35.78612,5.35,1992-12-09T13:21:30.071000,1.0530213,121, +-120.37073,35.83517,5.65,1992-12-13T02:43:36.994000,8.90334,121, +-116.39243,34.111492,5.05,1992-12-23T09:34:50.328000,10.30314,121, +-116.537636,33.32883,4.95,1992-12-27T08:42:03.351000,8.365862,121, +-119.64688,38.691055,5.25,1993-01-21T06:10:11.569000,5.926727,121, +-124.5135,40.387775,4.95,1993-04-13T16:09:55.144000,20.111547,121, +-124.51639,40.366924,5.35,1993-04-15T03:05:39.298000,17.076485,121, +-122.843925,39.330997,5.05,1993-05-14T13:19:36.046000,3.9121253,121, +-115.83766,32.476135,5.05,1993-06-03T01:35:30.059000,5.2988977,121, +-115.88,34.4,6.1393147,1993-06-05T22:14:12.087000,5.0,121, +-118.97826,33.52973,5.45,1993-06-12T11:39:42.832000,16.279324,121, +-116.326775,34.09992,5.05,1992-07-02T21:14:33.616000,7.8447275,122, +-124.086365,40.330803,5.55,1992-07-22T00:56:19.271000,14.247515,122, +-124.099945,40.326416,5.75,1992-07-23T12:33:45.186000,14.393808,122, +-124.06,40.22,7.0563517,1992-07-23T12:34:57.258000,7.0,122, +-123.77932,40.074413,4.95,1992-07-23T12:42:10.855000,11.174867,122, +-123.92985,40.13707,4.95,1992-07-23T12:46:28.384000,3.514746,122, +-123.73346,40.050903,5.95,1992-07-23T12:49:09.446000,15.593191,122, +-123.782005,40.022343,5.95,1992-07-23T12:49:29.342000,16.022459,122, +-124.055405,40.266056,5.95,1992-07-23T14:50:35.482000,22.813347,122, +-123.92804,40.142548,5.95,1992-07-23T17:03:06.300000,10.271071,122, +-124.01691,39.782974,4.95,1992-07-24T05:32:11.470000,11.997477,122, +-123.69684,40.004402,4.95,1992-07-24T13:17:11.945000,11.576806,122, +-124.064,40.323128,5.05,1992-07-30T15:38:00.964000,17.215437,122, +-123.95187,40.14106,5.25,1992-08-18T05:05:35.165000,10.25112,122, +-123.91325,40.105625,5.05,1992-11-13T05:53:45.452000,10.1156225,122, +-124.48652,40.33359,4.95,1992-11-26T20:26:38.090000,18.381998,122, +-120.37795,39.93408,4.95,1992-12-17T21:58:36.796000,5.651911,122, +-116.21136,31.713448,5.15,1993-03-09T10:11:15.190000,8.683701,122, +-124.38847,40.32696,5.05,1993-03-19T13:09:53.146000,6.804518,122, +-124.87878,40.922314,5.05,1993-04-01T07:54:43.489000,2.4195657,122, +-124.38607,40.296394,5.05,1992-06-29T14:49:14.560000,6.130963,123, +-124.291695,40.348755,5.25,1992-07-02T22:00:10.035000,10.306361,123, +-119.81285,34.184204,5.35,1992-10-27T04:24:43.268000,4.088701,123, +-115.67511,31.92358,5.15,1993-03-30T12:55:45.060000,14.0744915,123, +-117.41675,34.30613,5.45,1993-06-04T20:34:56.605000,4.5385294,123, +-117.41994,34.283234,5.35,1993-06-04T20:53:34.015000,5.346958,123, +-117.41204,34.289394,5.05,1993-06-04T21:10:06.191000,3.7214205,123, +-117.43465,34.281,5.05,1993-06-04T21:26:36.080000,4.6705117,123, +-120.05163,36.44169,6.05,1992-07-11T04:37:05.855000,9.357414,124, +-117.33938,37.619415,5.95,1992-07-11T22:12:34.420000,8.046547,124, +-120.026855,36.46987,4.95,1992-07-12T00:36:54.395000,10.10872,124, +-124.31348,40.42683,5.15,1992-07-16T04:43:04.674000,8.292329,124, +-118.898026,34.54976,6.3092403,1992-07-17T14:45:46.972000,10.537692,124, +-118.952515,34.54802,5.05,1992-07-17T15:01:28.575000,7.873992,124, +-118.92576,34.549934,5.45,1992-07-17T15:26:11.645000,7.07647,124, +-118.94257,34.52936,6.05,1992-07-17T15:45:27.192000,5.8398743,124, +-118.91587,34.525284,6.45,1992-07-17T15:55:13.754000,9.827391,124, +-118.90871,34.448402,5.15,1992-07-17T16:01:10.969000,14.327019,124, +-119.02275,34.559708,5.95,1992-07-30T20:24:44.953000,0.37745038,124, +-119.01217,34.56705,5.15,1992-08-02T16:18:49.454000,1.9513757,124, +-120.0345,36.419933,4.95,1992-08-14T05:35:25.737000,8.031104,124, +-117.718216,32.904186,5.45,1992-09-17T04:12:19.904000,5.381201,124, +-120.28057,33.502613,5.55,1992-09-26T22:22:08.734000,19.6189,124, +-121.10291,36.58732,5.15,1992-10-04T01:05:09.920000,9.475622,124, +-119.05552,34.553764,4.95,1992-10-12T11:20:22.556000,0.29121107,124, +-124.205864,40.41405,4.95,1992-11-26T20:34:50.263000,10.141385,124, +-124.21845,40.42296,5.05,1992-12-02T06:05:35.034000,8.021756,124, +-124.21495,40.438137,5.45,1992-12-03T13:45:58.150000,7.9915695,124, +-121.742645,37.39146,6.0844784,1993-02-05T22:22:39.879000,9.175849,124, +-122.77566,38.816895,5.75,1993-02-21T13:20:16.875000,0.14938742,124, +-122.78684,38.84288,5.05,1993-02-21T19:48:03.983000,2.2337723,124, +-122.7911,38.852726,5.15,1993-02-21T21:10:55.886000,2.0028498,124, +-121.57443,37.00369,4.95,1993-03-19T15:38:35.685000,17.986616,124, +-120.0424,36.430073,5.35,1993-04-05T10:58:32.015000,11.590158,124, +-121.441185,37.26741,4.95,1993-04-14T20:23:30.196000,5.6648197,124, +-121.362656,37.266624,5.45,1993-04-14T20:26:34.497000,3.8813117,124, +-121.27942,36.87485,4.95,1993-05-03T07:25:46.554000,8.527767,124, +-124.19754,40.270653,5.85,1993-05-22T15:09:47.600000,7.8623705,124, +-121.54,37.02,6.9384775,1993-06-15T14:34:25.194000,17.0,124, +-121.29347,36.71274,5.45,1993-06-15T14:51:23.184000,10.177198,124, +-121.00008,36.43884,5.15,1993-06-15T17:54:08.496000,8.851396,124, +-121.40322,36.871998,5.25,1993-06-15T18:46:26.167000,7.389722,124, +-121.18,36.58,6.164287,1993-06-17T06:16:40.295000,13.0,124, +-120.96011,36.35165,4.95,1993-06-17T12:35:09.508000,0.45004869,124, +-120.88383,36.29155,5.25,1993-06-21T22:35:53.450000,0.20562512,124, +-121.16153,36.58865,5.25,1993-06-23T08:22:51.427000,4.281011,124, +-121.140205,36.597725,5.35,1993-06-25T02:35:31.159000,3.6755924,124, +-124.39036,40.503075,5.15,1992-06-29T13:46:45.818000,5.2360067,125, +-124.398575,40.491096,4.95,1992-06-29T14:37:53.007000,4.3005586,125, +-116.77085,33.650486,6.6602077,1992-07-10T11:23:01.202000,2.4211764,125, +-116.652275,33.588776,5.25,1992-07-10T17:32:02.558000,4.9040565,125, +-116.7917,33.649704,5.15,1992-07-15T20:18:23.937000,5.3745813,125, +-116.66926,33.576775,6.05,1992-07-27T11:58:33.454000,11.312185,125, +-116.68112,33.54428,4.95,1992-07-28T21:39:25.818000,15.752746,125, +-124.19818,40.43888,4.95,1992-11-16T12:17:38.840000,9.664781,125, +-124.13717,40.559464,6.75,1992-12-03T04:58:42.402000,13.840223,125, +-124.280556,40.58642,5.05,1992-12-03T05:15:09.916000,10.899059,125, +-124.16234,40.441658,5.25,1992-12-03T06:05:09.984000,13.738034,125, +-124.28792,40.58523,4.95,1992-12-03T07:27:58.196000,10.152353,125, +-123.9845,40.488422,5.45,1992-12-09T18:03:09.803000,6.754542,125, +-124.101715,40.62635,5.25,1992-12-16T21:31:03.298000,22.284014,125, +-115.05419,35.73584,5.05,1993-02-18T07:08:53.520000,9.962234,125, +-116.64202,33.579895,4.95,1993-02-23T17:41:03.919000,2.681992,125, +-116.630066,33.588474,5.45,1993-02-25T22:58:16.716000,5.726553,125, +-116.884415,36.715824,5.45,1993-04-18T10:34:01.611000,7.9785624,125, +-116.660934,33.572964,5.25,1993-05-31T11:22:36.648000,7.790358,125, +-124.31215,40.317543,5.15,1992-11-07T02:28:30.123000,7.8681707,126, +-121.590065,36.915504,4.95,1993-01-02T05:08:54.510000,15.589984,126, +-123.648544,38.857582,5.15,1993-06-26T19:56:03.729000,6.586776,126, +-117.9825,34.29168,6.25,1992-07-04T23:45:30.755000,10.609497,127, +-124.504585,40.277794,5.85,1992-10-10T13:28:03.045000,11.252648,127, +-124.48253,40.306335,5.85,1992-10-31T11:19:59.926000,13.441359,127, +-117.96782,38.148605,5.25,1992-11-12T08:21:18.744000,4.1514277,127, +-124.56391,40.411743,4.95,1993-01-06T17:26:12.938000,20.208858,127, +-116.68173,33.629944,5.05,1993-03-01T02:33:45.278000,9.140763,127, +-124.4041,40.40058,5.15,1993-04-21T10:59:24.811000,6.1783447,127, +-124.01018,40.33398,5.65,1992-07-05T20:24:53.842000,7.604562,128, +-121.14737,36.598415,4.95,1992-07-19T07:36:54.228000,3.9906855,128, +-124.33209,40.37087,5.15,1992-07-19T12:49:50.339000,8.4339075,128, +-120.3656,39.265007,5.05,1992-08-17T06:12:04.208000,8.110316,128, +-116.361725,33.96118,5.45,1992-08-21T00:34:33.837000,4.054829,128, +-125.028114,40.83814,4.95,1992-11-03T21:34:14.624000,2.310208,128, +-121.403824,36.461094,7.05,1993-01-03T11:17:53.137000,4.393621,128, +-121.37988,36.549324,4.95,1993-01-03T13:54:55.143000,10.929238,128, +-121.43417,36.51795,6.25,1993-01-04T05:41:51.408000,10.489646,128, +-121.33452,36.414703,5.55,1993-01-05T16:38:34.938000,18.345932,128, +-121.42,36.66,6.14105,1993-01-08T07:40:30.373000,7.0,128, +-121.58585,36.464054,5.45,1993-01-12T12:39:07.310000,8.688309,128, +-121.320335,36.5619,5.15,1993-01-13T06:42:19.791000,1.6052703,128, +-121.30356,36.378353,4.95,1993-05-05T21:29:44.235000,6.4198904,128, +-116.57181,37.125214,5.15,1993-05-12T20:59:28.291000,5.844137,128, +-117.686935,33.679066,4.95,1993-05-23T12:08:22.560000,6.0908675,128, +-116.34644,33.19062,5.15,1993-05-28T23:41:09.237000,11.708305,128, +-116.21991,31.99715,4.95,1992-09-14T19:24:10.972000,6.414656,129, +-117.89818,35.68831,5.55,1992-09-22T18:19:22.746000,11.219877,129, +-117.79941,34.398777,5.35,1992-10-20T02:18:58.419000,9.09574,129, +-118.95466,34.831013,4.95,1992-11-05T13:04:19.894000,5.609889,129, +-116.63279,35.296688,5.15,1992-12-23T12:40:15.387000,6.569167,129, +-122.71847,37.917072,5.05,1993-03-31T20:03:32.457000,6.5550327,129, +-115.465866,32.48247,5.45,1993-04-02T08:26:38.249000,4.9768524,129, +-120.410706,35.858585,6.11956,1993-05-29T12:04:51.142000,9.36207,129, +-124.26672,40.37352,5.05,1992-07-02T12:43:01.389000,8.495411,130, +-124.26371,40.295784,4.95,1992-07-04T05:13:49.152000,6.7944326,130, +-120.59072,39.553177,5.25,1992-07-12T17:28:06.108000,6.3633533,130, +-124.588104,40.42508,5.35,1992-07-27T07:31:35.962000,19.083878,130, +-116.34495,33.952126,5.65,1992-09-17T07:05:12.332000,5.838484,130, +-116.366974,33.927013,4.95,1992-09-17T07:12:40.494000,4.2535477,130, +-116.86412,33.68946,4.95,1992-11-11T02:35:22.287000,9.926207,130, +-122.559326,37.788853,5.35,1993-01-10T10:48:43.376000,9.161858,130, +-116.90873,33.74391,5.65,1993-01-18T16:50:22.305000,6.673104,130, +-121.64653,39.55889,5.65,1993-04-01T12:53:07.319000,9.385179,130, +-115.71545,32.148735,4.95,1993-05-16T02:50:04.414000,7.1102734,130, +-124.38201,40.412617,5.65,1993-05-30T05:35:36.680000,9.022258,130, +-123.64423,38.82776,5.25,1993-06-03T00:45:59.161000,11.163181,130, +-116.34337,34.13302,5.35,1993-06-13T07:13:32.520000,8.693676,130, +-124.39685,40.241093,5.05,1992-08-19T07:00:18.893000,5.549402,131, +-118.700035,37.55255,4.95,1992-08-21T04:01:25.498000,3.5762155,131, +-124.51852,40.371136,5.55,1992-09-10T13:03:00.653000,22.321238,131, +-116.239746,36.77988,5.15,1992-11-06T15:00:13.093000,15.813979,131, +-122.81155,39.903194,4.95,1992-12-05T19:40:12.126000,7.701031,131, +-118.44472,38.201096,5.25,1992-12-27T21:36:46.242000,6.7348733,131, +-118.41947,38.209995,5.05,1992-12-27T21:51:14.469000,7.2315297,131, +-121.78239,35.320793,5.05,1993-01-06T05:11:58.610000,6.479878,131, +-122.62167,37.758625,5.15,1993-02-27T07:55:07.452000,8.064516,131, +-122.67831,39.829506,5.25,1993-03-01T08:50:03.023000,5.3849635,131, +-121.030174,35.719395,5.65,1993-05-03T05:55:17.629000,17.47426,131, +-118.70593,37.531063,5.45,1992-09-22T03:57:44.435000,1.6687123,132, +-124.5529,40.47636,5.15,1992-11-17T20:22:48.983000,14.540081,132, +-124.25706,40.42478,5.15,1992-11-22T04:52:20.687000,9.513855,132, +-124.100945,40.28398,5.35,1992-12-19T18:23:56.843000,13.149577,132, +-124.18943,40.245823,4.95,1992-12-28T16:48:26.512000,9.574265,132, +-125.21341,40.390984,5.55,1993-01-12T05:16:12.205000,5.616781,132, +-116.670166,33.697235,5.15,1993-03-31T07:58:56.572000,6.49182,132, +-124.513885,40.365368,5.65,1993-06-05T09:31:58.934000,18.693283,132, +-124.43193,40.33185,4.95,1993-06-25T09:07:57.009000,16.842499,132, +-124.4854,40.324497,4.95,1992-07-10T07:45:35.247000,22.439743,133, +-124.36726,40.37327,5.75,1992-07-30T13:02:16.323000,16.52155,133, +-124.335655,40.39932,4.95,1992-07-30T15:25:57.986000,18.744633,133, +-125.21308,40.484356,5.35,1992-09-30T01:23:25.726000,4.8690543,133, +-118.629105,37.473614,4.95,1992-10-18T06:44:42.188000,14.023471,133, +-118.597694,37.45099,5.05,1992-10-18T06:49:55.603000,9.965018,133, +-116.76973,35.02179,5.15,1993-04-20T09:13:21.783000,4.27754,133, +-115.79504,32.027653,4.95,1993-06-12T11:39:44.799000,3.702864,133, +-124.58641,40.420704,4.95,1992-07-06T09:58:16.358000,20.329315,134, +-124.321014,40.30753,5.05,1992-07-18T09:05:30.993000,7.644152,134, +-124.481026,40.320587,5.05,1992-08-13T06:50:11.941000,9.349463,134, +-124.48309,40.363277,4.95,1992-12-04T08:32:21.665000,23.05833,134, +-124.13611,40.36873,5.15,1993-01-10T09:00:43.654000,11.691628,134, +-124.15518,40.36996,5.15,1993-01-22T03:25:16.722000,12.036556,134, +-121.94859,39.53578,4.95,1993-01-23T20:48:56.730000,5.230459,134, +-124.17726,40.421837,5.05,1993-04-27T00:39:40.740000,8.22316,134, +-117.16257,32.70097,6.228303,1993-05-02T16:54:59.499000,1.76,134, +-117.14053,32.63531,4.95,1993-05-02T17:43:38.604000,5.8605704,134, +-116.35901,34.326138,4.95,1993-05-16T09:28:02.935000,2.3778799,134, +-124.52983,40.40367,4.95,1992-07-16T22:28:33.812000,20.884409,135, +-124.21233,40.282154,5.35,1992-08-17T06:55:49.735000,8.4519005,135, +-121.70118,37.03281,5.45,1992-09-24T04:49:57.920000,1.4061283,135, +-124.40061,40.26324,5.35,1992-11-23T12:51:28.578000,17.131878,135, +-124.41335,40.250824,5.25,1992-11-24T11:00:09.493000,18.036276,135, +-115.936874,31.852903,5.35,1992-12-09T11:36:04.182000,22.051603,135, +-124.96756,40.81906,4.95,1992-12-13T13:55:44.995000,7.512682,135, +-122.325836,40.52788,5.35,1993-01-27T09:11:36.498000,4.9097004,135, +-120.38299,36.165936,5.45,1993-03-26T07:33:52.074000,13.379765,135, +-120.40567,37.709995,5.15,1993-04-01T12:10:02.856000,7.170222,135, +-120.3795,36.1591,5.65,1993-04-01T14:16:32.585000,14.586431,135, +-120.394745,36.15396,5.45,1993-04-09T09:45:42.455000,16.96286,135, +-120.35126,39.75702,4.95,1993-04-11T09:22:15.784000,18.816189,135, +-118.49892,37.62569,5.05,1992-08-26T09:51:28.307000,9.143364,136, +-117.87252,36.166477,5.05,1992-10-07T20:47:52.213000,3.0080698,136, +-116.8127,35.019253,5.25,1993-02-18T04:26:51.605000,7.339712,136, +-123.96437,39.644028,4.95,1993-02-28T01:16:35.716000,6.5514913,136, +-116.47469,33.531418,4.95,1993-05-25T22:18:31.074000,0.63318384,136, +-116.22789,36.59287,4.95,1993-06-23T16:04:55.950000,8.405041,136, +-116.35767,34.073753,5.25,1992-07-24T12:28:19.767000,14.559846,137, +-124.153435,40.32492,5.55,1992-07-29T09:51:32.402000,7.8895965,137, +-124.14614,40.350082,5.45,1992-07-29T11:03:50.377000,7.1908736,137, +-123.99417,40.249508,5.15,1992-07-29T18:26:13.041000,9.449709,137, +-124.02,40.12,6.7979875,1992-07-29T19:15:42.682000,11.0,137, +-123.96735,40.183247,5.75,1992-07-29T19:36:50.471000,13.248681,137, +-123.918945,40.371674,5.65,1992-07-30T01:00:02.421000,9.718736,137, +-123.87409,40.131905,5.35,1992-07-30T10:33:51.549000,20.284681,137, +-123.94648,40.15465,4.95,1992-07-30T21:33:24.632000,11.528834,137, +-124.1586,40.33362,5.85,1992-08-08T13:09:10.119000,11.870665,137, +-123.99066,40.199654,5.65,1992-08-11T04:11:16.134000,6.6831045,137, +-123.99579,40.151485,4.95,1992-08-14T12:27:45.126000,10.835903,137, +-117.792435,35.995026,5.05,1992-08-20T11:53:00.494000,1.5292102,137, +-118.0,35.4,6.509872,1992-08-28T11:06:13.933000,7.0,137, +-124.01387,40.220512,5.05,1992-10-07T00:48:29.969000,1.4500269,137, +-124.175415,40.35226,5.05,1992-11-13T02:53:26.023000,8.615011,137, +-119.34705,39.092186,4.95,1992-11-23T10:21:06.881000,2.8438313,137, +-119.40884,39.222126,5.15,1992-11-25T15:00:24.569000,9.333075,137, +-120.68265,36.49921,5.45,1992-12-10T04:29:03.722000,7.451432,137, +-123.99725,40.20521,5.45,1993-01-01T05:06:09.877000,0.910255,137, +-121.21156,36.546597,5.05,1993-01-11T14:00:42.142000,4.903151,137, +-124.11228,40.308044,5.25,1993-01-23T02:54:31.271000,11.893408,137, +-121.82419,37.2718,5.45,1993-03-15T03:22:43.013000,4.2397437,137, +-125.13951,40.792496,4.95,1993-03-27T13:34:36.783000,8.863883,137, +-116.373314,34.682594,5.35,1992-07-03T03:54:10.268000,5.291758,138, +-124.249794,40.220707,5.05,1992-08-12T02:51:03.328000,9.017423,138, +-124.51065,40.336338,4.95,1992-08-30T14:47:57.701000,21.012184,138, +-116.32,33.98,6.481133,1992-11-13T03:41:39.894000,7.0,138, +-116.356705,34.06457,4.95,1992-11-16T00:52:09.413000,13.376691,138, +-124.149994,40.304047,5.15,1992-11-27T01:56:09.312000,10.37074,138, +-115.58188,32.954853,5.25,1993-01-10T04:03:23.220000,6.6312866,138, +-124.51367,40.35487,5.35,1993-04-26T15:29:44.343000,19.99223,138, +-120.694786,36.246933,5.25,1993-04-27T20:53:11.150000,6.305041,138, +-124.537895,40.34414,5.25,1993-05-27T09:18:27.679000,20.650757,138, +-124.55771,40.37034,5.05,1993-05-31T13:23:12.935000,21.36842,138, +-117.03789,37.514565,4.95,1993-06-08T05:54:54.586000,7.789781,138, +-117.10288,37.576878,4.95,1993-06-18T15:37:38.367000,6.78852,138, +-118.54555,34.66339,5.15,1992-07-02T19:55:52.078000,2.4812975,139, +-124.17628,40.254982,4.95,1992-07-23T00:22:53.645000,10.769503,139, +-116.30724,33.942204,5.05,1992-08-10T03:30:32.371000,6.154588,139, +-122.87672,39.390175,5.85,1992-09-10T18:22:56.788000,10.05902,139, +-124.319016,40.309334,5.65,1992-09-18T03:33:52.495000,7.711603,139, +-124.33873,40.325714,4.95,1992-09-18T06:14:47.485000,5.2592764,139, +-122.84019,39.4985,5.25,1992-09-20T22:36:31.361000,11.291883,139, +-124.63714,40.30109,5.15,1992-10-15T11:51:29.268000,5.165674,139, +-124.62325,40.292717,5.35,1992-10-15T13:28:28.261000,4.403472,139, +-124.618706,40.30499,5.05,1992-10-15T13:38:37.654000,6.1899395,139, +-117.87622,36.001343,5.75,1992-11-10T00:47:42.546000,3.1795108,139, +-117.89329,36.031216,5.35,1992-11-10T02:43:24.810000,2.7394102,139, +-116.43897,33.474716,5.35,1992-11-20T14:15:31.936000,8.704986,139, +-118.65878,37.55257,5.35,1992-12-06T17:04:47.794000,5.3649054,139, +-120.39159,36.208534,5.25,1993-01-05T02:51:10.342000,9.247178,139, +-116.434784,31.77369,5.25,1993-05-04T04:16:56.168000,16.04046,139, +-116.444725,31.768084,5.25,1993-05-04T05:31:11.742000,14.626387,139, +-120.136314,36.13246,5.65,1992-07-24T12:28:49.929000,9.102898,140, +-117.89706,35.98834,5.15,1992-10-07T03:04:48.105000,11.504632,140, +-121.451775,34.527473,4.95,1992-11-04T12:46:33.906000,9.355947,140, +-115.8809,36.80665,4.95,1992-11-20T17:28:34.819000,6.8533306,140, +-120.10534,36.142513,6.25,1992-11-24T21:24:46.765000,10.511275,140, +-120.06384,36.15619,4.95,1992-11-24T21:39:19.194000,4.352552,140, +-120.08576,36.18986,5.45,1992-11-26T23:20:17.073000,5.7293735,140, +-117.96655,38.556652,5.45,1992-12-13T07:06:00.808000,9.218226,140, +-117.205,35.252758,5.25,1993-05-05T12:32:59.698000,15.927206,140, +-120.14579,36.119633,5.35,1993-05-08T10:25:19.287000,6.1107845,140, +-124.47817,40.32759,5.15,1992-06-28T23:50:53.932000,20.582012,141, +-124.68,40.34,6.693793,1992-07-24T08:38:59.307000,3.0,141, +-124.38791,40.213932,5.15,1992-07-24T09:15:52.449000,1.554682,141, +-124.37643,40.205658,5.05,1992-07-24T09:16:38.974000,3.4442208,141, +-124.307175,40.418118,5.05,1992-07-25T09:56:02.432000,7.485326,141, +-124.378265,40.276985,5.75,1992-07-27T05:42:22.093000,4.2473607,141, +-124.441185,40.26561,5.25,1992-07-27T07:09:16.619000,4.2913723,141, +-116.38815,34.122097,4.95,1992-08-12T16:43:42.284000,6.7352867,141, +-116.36337,34.03341,5.75,1992-09-23T11:24:31.513000,7.759159,141, +-123.94,39.56,6.435592,1992-12-20T21:29:49.983000,1.0,141, +-115.58754,32.66468,5.05,1993-01-04T18:33:01.756000,8.6969185,141, +-123.95175,39.623337,5.15,1993-02-19T01:58:03.450000,7.3038177,141, +-124.51039,40.383137,5.45,1993-04-24T10:57:49.697000,19.048525,141, +-124.53672,40.409485,5.05,1992-06-30T01:49:51.180000,18.071743,142, +-122.078316,40.421318,4.95,1992-07-21T23:02:24.667000,5.6059613,142, +-124.24241,40.422264,5.05,1992-07-25T16:14:03.992000,10.129986,142, +-124.33944,40.240845,4.95,1992-09-07T18:21:53.951000,6.7294683,142, +-118.09705,33.727573,5.45,1992-10-03T18:57:19.300000,1.381079,142, +-118.44,35.007153,5.45,1992-10-31T13:17:51.046000,7.9563403,142, +-118.40429,35.104492,5.15,1992-11-18T22:10:33.547000,13.686858,142, +-115.61904,32.941254,5.75,1992-12-31T13:21:47.309000,12.612875,142, +-124.55262,40.381218,5.45,1993-02-07T08:00:04.820000,19.257772,142, +-120.03415,37.877422,5.45,1993-03-22T13:36:41.030000,20.64266,142, +-124.18163,40.3523,5.75,1993-05-12T23:26:11.426000,11.418695,142, +-115.441284,32.773808,5.55,1993-06-19T21:23:35.300000,8.453874,142, +-120.69286,40.027267,5.05,1993-06-25T18:01:44.730000,6.6141157,142, +-124.424355,40.38552,5.45,1992-06-29T19:57:27.282000,14.583238,143, +-124.48339,40.338413,5.05,1992-07-12T02:58:27.009000,20.18701,143, +-115.21227,32.49857,5.15,1992-07-15T21:05:23.787000,10.301366,143, +-118.44776,37.593456,5.05,1992-08-21T21:21:56.717000,8.730376,143, +-120.36,35.86,5.9905787,1992-11-06T06:37:06.939000,7.0,143, +-120.38384,35.83689,4.95,1992-11-14T21:40:27.384000,7.2375965,143, +-118.65717,34.74942,5.65,1992-11-23T15:01:47.431000,6.719039,143, +-124.255104,40.425915,5.25,1992-11-27T10:19:51.383000,9.691938,143, +-118.694756,34.846485,4.95,1992-12-20T16:25:48.816000,7.697143,143, +-122.03375,40.39494,4.95,1993-01-19T06:36:18.904000,9.35478,143, +-125.33039,41.06916,4.95,1993-01-31T19:31:09.054000,4.8784814,143, +-120.62122,36.05773,5.15,1993-04-28T05:06:45.947000,6.335403,143, +-124.51357,40.335773,5.55,1992-08-22T08:03:57.638000,18.73251,144, +-124.46904,40.316975,5.15,1993-01-08T07:58:51.124000,17.564594,144, +-118.70209,37.522163,5.35,1993-01-31T02:29:03.303000,18.27638,144, +-124.76597,41.604233,5.05,1993-04-08T01:16:59.982000,4.546965,144, +-124.24935,40.26903,5.65,1992-07-06T11:20:31.387000,12.59463,145, +-124.545456,40.377563,4.95,1992-08-03T13:47:50.021000,19.964764,145, +-116.39061,34.114056,5.35,1992-08-12T17:38:59.699000,14.523543,145, +-121.08715,40.34818,5.35,1992-08-22T17:00:11.513000,7.7790565,145, +-124.42264,40.244576,5.15,1992-09-07T06:29:21.086000,8.349216,145, +-121.15326,36.56263,6.113826,1992-09-28T18:15:16.481000,12.0,145, +-121.052734,36.445454,5.95,1992-09-28T18:38:05.240000,3.7087488,145, +-121.0507,36.471905,4.95,1992-09-28T19:30:41.941000,2.7489505,145, +-121.233444,36.614872,4.95,1992-09-28T22:27:17.323000,6.3468695,145, +-121.06867,36.448997,5.05,1992-09-30T05:48:46.856000,3.2371747,145, +-124.58,40.36,6.3526235,1992-10-03T06:58:06.833000,11.0,145, +-124.608536,40.32834,5.05,1992-10-03T07:32:08.344000,0.90208644,145, +-124.66337,40.367985,5.25,1992-10-12T22:47:57.089000,7.146813,145, +-121.03201,36.45863,5.25,1992-11-07T01:09:24.691000,5.0635786,145, +-125.29903,40.441975,5.05,1992-11-13T01:05:39.676000,10.186833,145, +-123.37063,38.719105,5.35,1992-09-03T02:02:31.898000,3.9377935,146, +-124.24873,40.351124,5.05,1992-09-17T23:25:35.376000,8.237084,146, +-117.98377,36.003963,5.15,1992-11-12T15:53:47.704000,5.2946057,146, +-121.7129,37.2006,5.05,1992-12-11T19:39:58.734000,6.107728,146, +-118.41506,38.226936,5.15,1993-04-19T02:45:38.119000,8.787284,146, +-124.3415,40.381725,5.95,1992-06-29T23:07:13.385000,7.1255746,147, +-124.33161,40.321873,5.25,1992-08-01T13:28:22.937000,8.33267,147, +-124.582146,40.42013,5.45,1992-08-15T06:14:21.045000,20.188452,147, +-124.55739,40.30521,5.45,1992-09-30T17:29:29.504000,11.948832,147, +-124.493774,40.337734,4.95,1992-10-06T23:48:20.306000,20.005621,147, +-116.936615,36.45189,4.95,1992-12-05T03:56:01.861000,13.593587,147, +-120.269554,36.117264,5.05,1992-12-09T07:59:56.869000,12.262283,147, +-119.70615,35.174664,6.35,1993-02-03T01:33:50.100000,10.948597,147, +-119.70455,35.149014,4.95,1993-02-05T09:44:26.390000,5.631955,147, +-119.83674,38.798332,5.05,1993-03-17T05:17:14.673000,2.8456147,147, +-119.70523,36.293903,5.55,1993-04-15T13:38:46.432000,12.248377,147, +-121.1424,36.587414,5.15,1993-05-02T14:43:34.519000,19.436655,147, +-119.79533,35.181404,5.15,1993-06-04T02:01:59.402000,6.6532297,147, +-122.934975,39.41437,5.05,1992-12-01T05:54:41.062000,6.9402523,148, +-125.11564,40.27723,5.85,1993-01-02T05:30:15.596000,10.242919,148, +-118.1739,33.75355,5.45,1993-01-29T13:22:18.562000,9.731761,148, +-122.58218,38.882183,4.95,1993-03-01T10:46:14.086000,9.949269,148, +-123.05486,39.704037,5.75,1993-03-31T02:09:08.384000,4.5150595,148, +-121.40615,35.70719,5.55,1993-05-01T07:21:32.740000,6.4798846,148, +-118.386406,37.512127,5.35,1993-05-02T05:36:37.522000,5.9658494,148, +-116.65297,33.617157,5.25,1993-05-08T07:39:33.457000,8.913933,148, +-120.60054,34.486652,4.95,1992-08-29T09:11:52.232000,8.507341,149, +-121.48184,36.802628,5.35,1992-09-03T09:50:56.771000,6.712538,149, +-124.54,40.36,6.4624553,1992-09-17T20:19:13.933000,23.0,149, +-124.53243,40.291245,5.15,1992-09-17T20:42:04.106000,9.419208,149, +-124.386925,40.12605,5.25,1992-10-06T09:44:04.367000,5.067299,149, +-121.49765,36.79395,5.05,1992-10-13T05:54:00.028000,8.280941,149, +-121.25721,36.98664,5.85,1992-11-07T19:11:08.048000,8.636319,149, +-121.28667,36.973465,5.85,1992-11-13T10:26:15.711000,8.842533,149, +-124.40072,40.03209,5.15,1992-11-18T17:10:23.385000,5.8627515,149, +-121.29181,36.9584,5.55,1992-12-18T13:02:08.165000,9.220085,149, +-121.272606,36.983795,5.45,1992-12-21T10:14:17.704000,9.048017,149, +-121.25827,36.968742,5.35,1992-12-21T10:36:00.101000,7.4440103,149, +-121.2445,36.953564,5.55,1992-12-23T07:58:47.294000,6.4857936,149, +-121.225815,36.937943,6.15,1992-12-23T12:18:27.735000,5.6731668,149, +-121.0,37.08,6.122676,1992-12-23T12:52:48.184000,15.0,149, +-120.960106,37.055344,5.35,1992-12-23T12:55:19.424000,7.7438083,149, +-121.25843,36.953735,5.35,1992-12-23T20:13:51.606000,6.8295574,149, +-120.918564,37.014458,5.95,1992-12-26T12:17:02.466000,7.57625,149, +-120.946,36.974194,5.05,1992-12-26T14:14:00.080000,8.886686,149, +-120.88647,36.978855,5.35,1992-12-26T19:17:59.321000,6.6859016,149, +-120.970985,36.92285,5.75,1993-01-02T02:18:26.067000,5.3630385,149, +-121.25132,36.98067,5.05,1993-02-06T10:32:11.256000,6.433588,149, +-122.892624,38.7729,4.95,1993-03-17T08:21:59.194000,7.0698752,149, +-124.27485,40.41893,5.05,1993-04-03T21:13:45.304000,6.4689636,149, +-116.78647,35.11758,5.15,1993-05-04T03:26:33.601000,6.810538,149, +-120.9064,36.960167,5.05,1993-06-24T02:40:06.920000,8.439101,149, +-115.50888,33.0163,4.95,1992-07-07T15:48:56.801000,7.6003423,150, +-124.190216,40.41397,5.05,1992-07-15T14:10:27.532000,9.966414,150, +-114.93308,32.152218,6.3219037,1992-09-23T02:59:55.732000,2.6557143,150, +-114.9904,32.201,5.25,1992-09-23T04:33:06.089000,8.5013895,150, +-114.98362,32.182713,5.05,1992-09-23T12:29:17.956000,2.3507226,150, +-124.40905,40.29321,4.95,1992-09-28T08:45:44.332000,21.694887,150, +-116.30994,33.71403,5.25,1992-10-11T08:29:56.139000,5.8559184,150, +-115.057846,32.28128,6.15,1992-11-01T18:33:52.214000,6.385748,150, +-124.44302,40.259956,5.75,1992-12-06T20:29:30.793000,7.8967013,150, +-115.99545,31.640783,5.05,1993-01-07T01:50:21.890000,8.973777,150, +-121.562195,36.657986,5.05,1993-04-10T17:12:54.124000,4.798577,150, +-121.35617,35.595684,5.15,1993-05-02T01:36:21.698000,16.156666,150, +-116.17935,33.67399,4.95,1993-06-04T23:51:59.805000,9.102509,150, +-124.36355,40.411602,5.15,1992-09-01T06:34:19,5.7965136,151, +-124.36,40.34,6.2110257,1992-09-13T13:08:37.993000,9.0,151, +-124.42304,40.280014,5.05,1992-09-13T23:47:54.667000,5.8844533,151, +-124.37374,40.231163,4.95,1992-09-15T02:52:11.212000,7.940003,151, +-124.41391,40.25362,5.05,1992-09-16T18:02:51.796000,3.8086562,151, +-121.72188,37.242386,5.45,1992-09-26T08:13:51.942000,6.059144,151, +-117.712776,34.235672,5.25,1992-10-01T17:07:02.011000,11.59544,151, +-117.69295,34.168972,6.05,1992-10-01T17:43:07.763000,5.4504275,151, +-121.97593,37.87294,5.05,1992-11-14T16:05:58.030000,7.996076,151, +-118.511215,37.72052,5.45,1992-12-14T03:15:20.082000,7.10494,151, +-121.99819,37.157265,4.95,1993-01-19T17:20:45.599000,10.336911,151, +-122.00803,37.15451,5.55,1993-01-19T17:43:53.189000,9.916868,151, +-123.66468,39.989082,5.05,1993-02-26T09:56:11.120000,11.006092,151, +-117.687935,37.503063,6.75,1993-05-24T00:14:39.462000,2.573638,151, +-117.70716,37.53673,4.95,1993-05-24T00:29:39.494000,1.8845649,151, +-117.60966,37.53395,5.25,1993-05-24T18:13:57.533000,6.034358,151, +-117.71631,37.550312,5.65,1993-05-25T01:25:00.703000,8.984548,151, +-117.71863,37.55705,5.15,1993-05-27T07:18:21.360000,5.1490645,151, +-117.78494,37.48838,5.05,1993-06-01T04:50:09.289000,2.9678028,151, +-120.339806,36.15346,6.05,1992-07-26T00:55:12.492000,1.4068187,152, +-124.6,40.34,6.018107,1992-08-18T12:53:29.182000,15.0,152, +-122.285965,40.84007,6.35,1992-08-24T23:46:58.459000,7.4848037,152, +-122.25006,40.784817,5.75,1992-08-25T05:55:35.238000,4.3087473,152, +-122.27388,40.86553,5.05,1992-08-25T20:33:15.436000,5.13014,152, +-122.3535,40.843002,6.55,1992-08-27T10:12:41.331000,6.397465,152, +-122.365486,40.843025,6.05,1992-08-27T11:34:43.033000,14.150655,152, +-122.304344,40.888695,5.15,1992-08-27T12:44:59.539000,15.692993,152, +-122.278694,40.85332,5.05,1992-09-03T19:28:09.678000,15.646882,152, +-121.625244,36.93339,5.35,1992-09-10T05:40:55.985000,7.9570236,152, +-117.486015,34.209133,5.95,1992-09-22T18:42:14.444000,10.391458,152, +-122.33657,40.88832,5.45,1992-11-18T12:19:06.863000,10.563113,152, +-122.330894,40.906002,5.85,1992-11-19T23:18:04.676000,11.872198,152, +-115.761345,32.019276,5.35,1992-12-27T01:29:29.699000,13.499685,152, +-122.294304,40.74915,5.75,1993-01-04T19:48:07.077000,4.7063465,152, +-118.21772,35.222034,5.45,1993-04-09T12:00:23.833000,3.6680412,152, +-121.83998,37.028805,5.35,1993-06-16T02:02:49.451000,8.291561,152, +-121.84834,37.040195,5.65,1993-06-16T02:05:18.787000,7.295371,152, +-124.1427,40.331814,4.95,1993-06-17T02:46:30.883000,10.721667,152, +-124.191864,40.36133,5.55,1992-07-22T18:40:33.365000,6.9569426,153, +-124.53747,40.35577,5.05,1992-07-23T06:35:37.802000,19.445211,153, +-124.56473,40.428577,5.25,1992-08-07T01:14:28.505000,20.072489,153, +-124.21805,40.26121,5.65,1992-08-18T20:20:30.644000,9.6959305,153, +-121.06913,36.58475,5.55,1992-08-22T03:02:11.869000,5.437708,153, +-121.06605,36.603806,5.35,1992-08-22T04:08:42.511000,7.326579,153, +-122.01091,37.872784,5.05,1992-09-01T06:54:01.935000,8.718085,153, +-121.91973,36.87856,4.95,1992-09-05T11:41:10.389000,4.921292,153, +-122.17513,39.709587,5.45,1992-09-13T09:46:13.099000,5.3289595,153, +-118.00403,34.238976,5.15,1992-10-02T18:26:14.779000,9.21625,153, +-116.36849,34.065517,6.05,1992-11-17T11:30:46.487000,13.122452,153, +-116.347694,34.10252,5.45,1992-11-18T08:50:08.927000,14.201018,153, +-117.959785,34.25827,4.95,1993-01-02T20:41:36.166000,10.929973,153, +-118.63868,34.199326,5.65,1993-03-11T23:20:56.763000,6.8142953,153, +-116.27752,32.04911,4.95,1992-08-09T23:53:03.507000,16.325964,154, +-120.461655,35.49211,4.95,1992-10-11T21:07:03.482000,12.79292,154, +-122.26835,37.478916,5.05,1992-10-22T01:10:33.227000,2.4713106,154, +-124.536575,40.379787,5.35,1992-11-06T19:54:56.981000,19.79567,154, +-124.55806,40.36655,5.75,1992-11-07T14:21:19.705000,18.170668,154, +-122.85863,40.237095,5.25,1993-01-31T01:31:01.243000,5.6973333,154, +-116.02782,33.204556,5.05,1993-02-10T14:14:27.618000,15.338586,154, +-118.70219,34.339775,5.15,1993-06-24T03:42:01.299000,10.650833,154, +-123.00642,38.952984,5.05,1993-06-24T06:11:34.500000,14.626832,154, +-123.027756,38.967106,5.25,1993-06-25T18:38:06.586000,15.261681,154, +-124.38232,40.317226,5.15,1992-07-06T23:11:28.322000,6.479272,155, +-124.56,40.42,6.693793,1992-07-16T09:19:32.772000,23.0,155, +-124.75011,40.32596,5.25,1992-07-16T09:19:50.101000,7.918118,155, +-124.74765,40.39249,4.95,1992-07-16T09:45:29.460000,1.8881996,155, +-124.87883,40.366314,5.05,1992-07-16T10:49:31.039000,20.60843,155, +-124.465355,40.32107,5.55,1992-07-22T10:05:12.572000,8.260178,155, +-124.69299,40.353848,5.45,1992-07-24T20:00:02.720000,9.161351,155, +-117.87538,34.043674,4.95,1993-03-30T17:10:39.939000,11.5672455,155, +-118.60854,38.26018,5.55,1993-04-15T04:12:25.884000,15.702913,155, +-124.31972,40.281136,5.05,1992-09-23T04:17:22.678000,9.346822,156, +-120.15863,36.2851,4.95,1992-11-18T21:35:25.070000,4.9419928,156, +-118.14,34.08,6.3457932,1992-11-27T09:46:37.821000,15.0,156, +-118.2,34.16,6.546674,1992-11-27T09:53:41.215000,11.0,156, +-118.18634,34.02938,5.15,1992-11-27T09:59:59.498000,6.158254,156, +-118.14312,34.13907,5.25,1992-11-27T10:26:35.793000,13.898565,156, +-118.21255,33.99149,5.35,1992-11-27T11:55:35.854000,7.979082,156, +-118.20793,34.042797,5.75,1992-11-28T05:58:54.144000,7.7816343,156, +-124.58079,40.393257,5.55,1992-12-20T15:33:57.479000,12.69215,156, +-118.20429,34.12486,5.45,1992-12-23T12:38:17.330000,11.599319,156, +-118.22021,34.047913,5.25,1993-01-29T09:15:57.337000,7.1250186,156, +-121.15848,36.46142,4.95,1993-05-14T01:55:37.823000,4.2300806,156, +-117.97125,32.639114,5.65,1992-07-14T20:27:37.390000,12.291723,157, +-121.178116,36.723778,5.05,1992-07-14T21:58:57.289000,9.260646,157, +-121.18638,36.725403,5.05,1992-07-18T10:38:11.499000,11.265553,157, +-124.49375,40.398342,5.75,1992-09-03T16:58:33.341000,18.345354,157, +-117.52895,34.47416,4.95,1992-12-12T21:16:23.939000,7.520124,157, +-120.711296,39.553333,4.95,1992-12-18T21:18:36.033000,6.5818167,157, +-120.73979,39.563034,5.35,1992-12-25T14:56:25.116000,5.4384656,157, +-117.64196,34.209442,5.05,1993-02-25T17:40:58.430000,21.037752,157, +-115.60264,32.485134,4.95,1993-03-28T16:09:12.874000,11.415233,157, +-115.89365,34.46596,5.35,1993-05-13T14:32:47.304000,14.758605,157, +-115.40843,32.16297,5.65,1993-05-20T18:01:59.636000,12.436192,157, +-124.72464,40.320942,4.95,1993-05-26T12:31:40.689000,5.614934,157, +-123.942986,40.384727,5.35,1992-07-07T21:34:22.331000,3.312356,158, +-124.24422,40.298832,4.95,1992-07-08T18:45:52.614000,8.677389,158, +-124.54,40.4,6.2110257,1992-08-21T05:50:02.656000,21.0,158, +-118.12418,36.41701,5.25,1992-09-03T06:07:28.861000,5.6810503,158, +-118.855705,34.28313,5.85,1992-09-13T17:16:49.681000,8.725909,158, +-120.650566,34.260887,5.05,1992-09-15T11:41:10.637000,6.2645454,158, +-124.37749,40.394333,5.55,1992-09-21T21:36:58.791000,9.178694,158, +-124.36955,40.395912,5.05,1992-09-22T13:09:16.428000,10.128539,158, +-118.31826,37.323765,4.95,1992-12-25T03:39:13.288000,10.917682,158, +-120.817505,34.178738,4.95,1993-02-05T15:05:03.517000,8.11311,158, +-117.29372,34.334126,5.15,1993-03-07T14:45:28.973000,5.329538,158, +-124.22558,40.3031,5.15,1993-05-20T11:45:07.819000,9.476303,158, +-122.508064,37.64363,5.05,1993-06-22T04:11:23.561000,13.679011,158, +-124.54001,40.372726,5.05,1992-07-31T06:26:50.385000,18.582134,159, +-120.08221,38.58419,4.95,1992-08-19T08:27:33.285000,13.508325,159, +-124.748276,41.11085,5.45,1992-12-01T21:20:13.996000,6.3289404,159, +-124.524536,40.39589,5.85,1993-01-05T11:39:02.094000,20.000107,159, +-124.19086,40.42727,4.95,1993-01-30T21:14:15.147000,11.557189,159, +-124.3081,40.37744,5.05,1993-01-30T21:19:50.026000,9.130649,159, +-124.21638,40.430912,4.95,1993-01-30T22:05:56.284000,10.232742,159, +-124.27784,40.429424,5.35,1993-01-31T08:17:57.690000,3.2272854,159, +-122.6295,38.909515,5.75,1993-02-17T02:07:43.033000,7.8602085,159, +-122.6287,38.927856,5.15,1993-02-17T06:50:55.187000,11.278187,159, +-122.656,38.926086,5.45,1993-03-04T00:50:32.073000,7.87923,159, +-124.34593,40.231518,4.95,1992-07-20T05:39:42.956000,5.577374,160, +-124.448166,40.42129,5.15,1992-07-31T04:59:59.480000,10.595778,160, +-122.362686,40.10863,5.35,1992-08-27T15:04:43.797000,9.253407,160, +-116.79646,34.423206,4.95,1992-09-23T10:42:00.753000,6.0190434,160, +-115.688255,32.164654,5.35,1992-11-02T03:13:06.090000,9.421114,160, +-124.25911,40.38179,5.25,1992-11-29T17:26:40.513000,13.007194,160, +-119.49473,38.717625,5.55,1992-12-20T07:47:29.314000,10.187505,160, +-124.52544,40.39702,5.15,1992-12-20T15:55:26.555000,10.291721,160, +-123.84361,40.40558,4.95,1993-01-26T06:58:50.848000,7.785066,160, +-120.84629,37.657448,4.95,1993-05-01T21:59:06.864000,6.562355,160, +-124.39997,40.27984,5.75,1992-07-04T05:20:58.795000,16.811226,161, +-124.41587,40.23862,4.95,1992-07-06T06:31:53.460000,11.287718,161, +-124.23809,40.392788,4.95,1992-08-01T05:18:52.088000,9.812053,161, +-124.47753,40.31065,4.95,1992-09-01T21:43:54.485000,10.152004,161, +-124.542,40.3557,5.15,1992-10-16T08:11:18.890000,15.372634,161, +-124.52105,40.32629,4.95,1992-10-20T05:28:21.634000,19.395018,161, +-117.82111,37.319798,6.25,1992-11-19T15:01:47.357000,5.9182115,161, +-117.77421,37.295025,5.95,1992-11-19T15:07:39.473000,11.3061,161, +-117.84075,37.307808,5.05,1992-11-19T15:21:30.598000,9.321776,161, +-117.85189,37.26388,5.55,1992-11-19T16:12:33.134000,3.2905924,161, +-117.57807,37.545315,5.45,1992-11-20T04:14:06.784000,11.303073,161, +-117.272354,31.825144,6.45,1993-01-25T04:20:18.090000,5.713145,161, +-121.37803,36.839226,5.25,1993-06-03T13:06:46.565000,4.1952944,161, +-117.78798,37.3618,5.45,1993-06-03T17:33:57.474000,5.90628,161, +-124.16,40.38,6.1160855,1993-06-23T15:57:14.610000,11.0,161, +-124.09815,40.38186,4.95,1993-06-23T19:54:20.636000,8.590341,161, +-122.02326,37.596806,5.35,1992-11-02T10:38:20.295000,7.2227545,162, +-124.219986,40.352234,5.25,1992-12-11T10:06:49.672000,14.929649,162, +-124.46057,40.312977,5.05,1993-01-15T14:47:54.136000,19.008314,162, +-115.51309,32.725708,5.05,1993-01-20T14:41:25.866000,4.8766127,162, +-120.20032,36.043076,5.55,1993-04-09T14:29:29.733000,7.5892158,162, +-118.607635,35.385796,5.85,1993-05-19T12:19:38.820000,6.3851657,162, +-116.346504,34.032753,5.25,1993-05-21T02:55:55.613000,1.9782257,162, +-123.085556,37.671875,5.05,1992-08-02T18:22:36.928000,7.2548633,163, +-124.15815,40.163563,5.15,1992-11-17T03:30:31.708000,3.2524068,163, +-118.54822,35.686253,5.25,1992-12-21T10:00:52.288000,5.456618,163, +-124.437454,40.089016,5.25,1993-01-01T11:39:04.756000,10.227204,163, +-124.45967,40.101524,5.75,1993-01-01T11:41:06.107000,11.039606,163, +-121.70664,36.952484,4.95,1993-03-27T13:07:34.265000,6.9645014,163, +-121.7112,34.415176,5.45,1993-04-07T14:43:55.163000,5.7222843,163, +-123.941895,39.602787,4.95,1992-07-17T15:53:18.693000,13.360089,164, +-124.5059,40.52997,5.75,1992-08-06T00:24:56.939000,4.0145245,164, +-124.17229,40.355446,5.05,1992-08-25T20:06:32.833000,10.728679,164, +-124.95948,40.13567,5.05,1992-09-08T22:16:26.105000,9.038672,164, +-124.190765,40.41341,4.95,1993-02-06T07:38:16.518000,9.419791,164, +-119.89786,36.845695,4.95,1993-03-19T08:51:00.123000,12.404777,164, +-124.46971,40.32445,4.95,1993-03-19T11:01:20.932000,20.953575,164, +-118.47604,37.006973,4.95,1993-03-20T00:09:45.458000,7.1081877,164, +-118.46628,34.1671,5.75,1992-07-16T03:27:20.362000,7.9390144,165, +-121.32831,36.53048,5.05,1992-07-18T21:27:31.651000,6.790304,165, +-124.29132,40.37926,5.15,1992-07-18T23:08:48.792000,9.290069,165, +-116.29515,36.697266,5.35,1992-08-08T06:09:08.043000,4.2717104,165, +-116.33966,33.96719,4.95,1992-11-11T10:38:08.415000,5.6281977,165, +-121.92671,38.015068,5.15,1992-12-10T05:30:46.218000,10.122469,165, +-115.670364,32.269115,4.95,1992-12-13T01:43:25.204000,7.1170306,165, +-115.557526,33.1611,5.25,1993-01-19T01:40:51.221000,4.398168,165, +-117.91426,32.54384,5.05,1993-01-28T17:21:59.446000,13.114461,165, +-117.9988,33.14322,4.95,1993-02-04T23:22:57.419000,5.0917497,165, +-117.08141,34.0979,6.2231793,1993-03-07T08:01:56.430000,4.16,165, +-123.64487,38.916718,4.95,1993-05-13T05:50:47.280000,5.4370317,165, +-115.50799,32.781487,4.95,1993-06-13T22:18:31.356000,6.4445,165, +-124.176704,40.253757,5.25,1992-06-30T18:13:23.818000,10.167467,166, +-121.00365,36.53879,4.95,1992-07-30T10:02:17.858000,5.8386784,166, +-124.901634,41.712738,5.45,1992-09-12T07:37:52.446000,4.427449,166, +-124.91219,41.706947,5.75,1992-09-12T16:59:10.836000,4.9598603,166, +-118.07735,33.755642,5.75,1992-10-06T12:44:45.526000,3.9627898,166, +-118.09846,33.78121,5.75,1992-10-13T13:15:31.856000,6.1951737,166, +-118.08782,33.74351,5.65,1992-10-14T06:43:05.682000,6.4472113,166, +-117.86623,33.95113,6.205862,1992-11-14T01:15:51.907000,4.96,166, +-115.357025,32.046997,5.15,1992-12-01T22:09:23.515000,2.8366396,166, +-116.36606,34.044357,5.55,1993-01-10T04:35:30.337000,8.000128,166, +-124.47825,40.3277,4.95,1993-01-26T00:42:59.054000,21.604424,166, +-124.37864,40.27992,5.55,1993-03-13T17:51:33.366000,7.782393,166, +-120.2042,36.00011,5.35,1993-04-13T21:08:12.262000,7.552722,166, +-124.38468,40.244022,4.95,1992-07-21T08:31:12.307000,7.2557435,167, +-121.593834,37.20727,5.25,1992-07-28T16:46:02.418000,12.287478,167, +-121.62103,37.203434,5.45,1992-07-30T02:34:58.172000,9.466642,167, +-120.728775,37.3745,5.05,1992-09-26T07:49:02.603000,5.1765885,167, +-116.360275,34.036957,5.75,1993-01-13T11:24:56.839000,8.113923,167, +-121.42047,36.789707,5.45,1993-01-17T17:42:00.770000,5.1760745,167, +-116.39251,34.069088,5.35,1993-02-02T17:32:02.856000,10.280638,167, +-122.25959,38.550804,4.95,1993-04-18T19:05:48.413000,4.6175456,167, +-118.341835,34.67086,5.15,1993-05-18T06:13:42.621000,3.0489306,167, +-118.174194,32.711414,5.05,1993-06-06T02:33:54.315000,11.181908,167, +-116.003914,34.879776,5.95,1992-06-29T16:21:02.431000,7.010147,168, +-124.40793,40.383656,5.25,1992-11-17T20:57:51.764000,6.7494874,168, +-118.87369,35.086346,5.85,1992-11-23T05:13:52.578000,11.666555,168, +-115.97127,34.860096,4.95,1993-01-12T17:26:22.894000,10.358915,168, +-116.34406,36.73959,5.15,1993-01-18T19:21:41.517000,6.4209414,168, +-124.642105,40.499134,5.45,1993-02-14T12:15:11.336000,5.272734,168, +-119.62421,34.76579,5.65,1993-02-15T12:11:13.482000,3.710962,168, +-118.194496,37.015102,4.95,1993-03-16T06:23:35.930000,4.5746093,168, +-119.61039,34.75157,5.05,1993-04-11T22:21:15.723000,4.6432295,168, +-123.88035,39.477894,5.25,1993-05-31T04:11:04.849000,7.376561,168, +-123.89065,39.488556,5.65,1993-05-31T08:14:02.751000,7.348832,168, +-123.88643,39.486565,5.05,1993-05-31T08:22:12.800000,9.005132,168, +-124.4082,39.05329,5.15,1993-05-31T08:45:01.846000,10.424431,168, +-124.07035,39.507023,5.85,1993-05-31T09:52:24.565000,5.459741,168, +-117.78563,33.031715,5.25,1993-06-01T03:02:09.884000,6.3895106,168, +-124.66584,40.472458,5.75,1993-06-16T00:27:06.110000,4.695301,168, +-116.44291,34.191517,5.45,1992-06-29T20:48:07.104000,3.4732704,169, +-120.281685,35.897503,4.95,1992-07-25T15:48:34.179000,4.903123,169, +-124.13821,38.95941,5.05,1992-10-01T03:37:21.943000,5.0373416,169, +-115.66232,33.224255,6.064668,1992-10-08T22:53:45.013000,2.0727272,169, +-115.53608,33.05788,4.95,1992-10-09T00:43:19.099000,12.179811,169, +-115.58298,32.644863,4.95,1992-10-28T16:17:35.246000,6.9639797,169, +-123.42,40.04,6.343759,1992-11-22T05:07:00.598000,7.0,169, +-123.343094,40.085243,5.05,1993-01-09T04:29:12.096000,3.1174114,169, +-123.90007,40.104275,4.95,1993-02-21T13:04:45.711000,6.4947267,169, +-115.26128,32.214184,5.85,1993-04-30T07:12:00.201000,5.0521164,169, +-115.83744,33.034855,5.05,1993-05-14T07:45:13.467000,7.5438676,169, +-118.94362,37.61598,4.95,1993-06-25T04:03:06.892000,10.659395,169, +-124.38388,40.26197,5.05,1992-08-05T10:42:42.847000,5.7871504,170, +-120.48199,36.335285,5.55,1992-08-18T02:26:57.489000,5.332248,170, +-117.449,35.410614,5.65,1992-11-06T13:25:05.292000,8.809817,170, +-116.35473,34.039623,5.05,1992-11-16T18:45:48.217000,10.308466,170, +-116.034935,33.18353,5.15,1993-05-07T04:13:13.020000,7.0094576,170, +-118.815796,37.576206,5.05,1992-07-06T16:23:13.164000,9.113832,171, +-116.681366,34.092896,5.25,1992-07-06T20:25:12.572000,8.529553,171, +-124.22038,40.360756,6.35,1992-07-24T04:27:35.638000,7.1553006,171, +-124.32657,40.331516,4.95,1992-07-24T04:32:16.190000,5.059834,171, +-123.97217,39.91346,4.95,1992-07-24T18:08:36.913000,6.2333326,171, +-123.980446,39.90981,5.05,1992-07-24T18:17:23.864000,5.040717,171, +-124.529045,40.38775,4.95,1992-08-04T00:58:05.996000,21.859362,171, +-124.54265,40.395752,5.15,1992-08-17T22:09:32.226000,22.791063,171, +-124.49976,40.39976,5.35,1992-08-31T14:56:47.104000,21.698286,171, +-116.15907,32.751106,4.95,1992-12-14T20:32:55.168000,21.983053,171, +-116.9687,33.82741,5.35,1992-12-25T08:39:16.594000,17.324467,171, +-117.26373,34.03845,6.05,1993-01-25T06:49:29.940000,5.11632,171, +-115.87439,31.847427,5.15,1993-04-17T01:46:35.582000,4.8425784,171, +-120.96073,36.376064,6.2241535,1992-07-13T08:26:44.068000,11.4,172, +-121.03126,36.437675,4.95,1992-07-14T20:31:00.103000,8.72705,172, +-121.09942,36.513718,5.65,1992-07-18T14:30:15.550000,6.7216606,172, +-121.078156,36.510147,5.45,1992-08-01T08:06:05.066000,4.099623,172, +-116.82903,34.291782,5.15,1992-08-16T20:20:47.154000,10.397067,172, +-123.43937,40.07438,5.65,1992-08-25T11:21:27.709000,11.883866,172, +-123.591705,40.018356,5.05,1992-08-26T21:01:04.008000,12.792919,172, +-116.853096,34.91698,5.35,1992-10-26T04:53:53.955000,9.357315,172, +-120.71524,36.19954,5.55,1992-11-21T05:35:31.450000,6.4969106,172, +-121.582504,37.037754,5.05,1992-11-25T10:32:46.955000,6.2263308,172, +-124.46418,40.324635,5.15,1992-12-30T00:45:49.553000,18.220032,172, +-120.2951,36.262836,5.55,1993-03-15T08:55:43.423000,8.57337,172, +-118.732185,35.060818,5.15,1993-04-11T00:34:08.862000,10.428769,172, +-122.64382,38.20659,5.05,1993-04-20T00:15:43.144000,6.566755,172, +-121.88869,39.96665,5.05,1993-05-21T00:33:40.393000,7.6827607,172, +-124.20987,40.387672,5.05,1992-07-29T23:36:31.688000,4.4245043,173, +-116.42908,31.934134,5.35,1992-08-05T18:58:20.088000,7.8960834,173, +-124.32184,40.272022,5.05,1992-08-26T13:53:00.568000,6.6528554,173, +-124.13368,40.36012,5.05,1992-08-31T14:15:42.720000,11.774358,173, +-116.88148,35.067207,5.75,1992-10-27T06:52:54.064000,17.973494,173, +-118.810555,37.715557,4.95,1992-12-19T08:01:45.468000,5.7869987,173, +-120.80164,39.69324,5.05,1993-02-16T19:11:45.649000,11.605126,173, +-123.92,40.18,6.7979875,1993-03-21T05:01:53.134000,11.0,173, +-123.83001,40.01518,5.25,1993-03-21T05:02:36.654000,2.0903459,173, +-123.9242,40.13851,6.05,1993-04-17T21:39:25.867000,14.325702,173, +-116.91279,35.041786,5.65,1993-04-30T20:06:00.040000,15.108178,173, +-124.46,40.34,6.3526235,1993-05-08T03:52:02.155000,21.0,173, +-124.52574,40.328766,5.55,1993-05-09T03:13:17.726000,6.2149568,173, +-124.53993,40.32978,4.95,1993-05-12T08:23:14.876000,4.682629,173, +-122.91897,39.56259,5.25,1992-07-31T23:48:03.600000,18.912683,174, +-116.7535,33.795654,6.35,1992-08-05T18:03:36.807000,5.781588,174, +-116.740486,33.814404,5.35,1992-08-05T18:13:39.626000,1.27764,174, +-124.02787,40.15699,5.35,1992-10-27T13:16:58.440000,10.878738,174, +-120.551476,35.962437,5.25,1992-10-31T10:23:55.162000,5.1528835,174, +-115.730316,31.77914,5.15,1992-11-13T13:15:13.822000,6.27112,174, +-124.24769,40.248707,4.95,1992-11-30T03:53:23.992000,8.350412,174, +-115.58379,33.38038,4.95,1993-01-25T06:03:35.598000,9.559282,174, +-124.15456,40.177433,5.75,1993-02-23T07:45:21.478000,11.650744,174, +-124.4928,40.32102,5.25,1993-03-09T02:04:11.045000,1.5649927,174, +-121.4908,35.76175,5.45,1993-04-07T01:55:13.247000,6.0323067,174, +-124.162415,40.192577,5.25,1993-05-14T20:02:16.679000,11.049801,174, +-121.31706,36.81494,5.25,1992-07-07T16:23:42.222000,6.414454,175, +-124.43532,40.30086,5.65,1992-08-18T12:19:21.778000,5.2181196,175, +-118.47654,35.682457,5.65,1992-08-21T19:31:29.444000,6.513965,175, +-118.56781,35.327625,5.45,1992-11-26T12:11:22.895000,8.424894,175, +-124.82649,40.956318,4.95,1992-12-05T03:47:56.984000,9.982586,175, +-120.29678,40.23007,4.95,1993-04-17T08:42:54.667000,7.122408,175, +-124.542465,40.466675,6.05,1992-08-24T05:49:23.256000,7.3861775,176, +-124.10869,40.28185,5.15,1992-09-27T05:33:09.623000,12.214723,176, +-120.410706,35.858585,6.0478396,1992-11-27T00:56:08.193000,10.2,176, +-120.53211,35.984394,5.65,1992-11-27T02:39:31.412000,8.502886,176, +-124.14829,40.261097,5.45,1992-11-28T17:46:33.378000,10.58993,176, +-115.74118,32.959423,6.05,1992-12-02T00:28:14.157000,2.450856,176, +-119.03227,35.938374,5.05,1992-12-11T02:04:25.082000,13.841429,176, +-119.63669,38.7461,4.95,1993-01-09T19:35:56.526000,20.373316,176, +-124.40627,40.277966,5.25,1993-02-02T23:26:03.508000,5.706441,176, +-119.918976,34.015667,5.15,1993-06-13T13:53:45.059000,9.177697,176, +-116.037155,33.082,4.95,1992-07-25T05:17:18.411000,21.364252,177, +-116.29988,34.050922,5.05,1992-12-02T15:41:05.805000,0.11067854,177, +-124.16,40.32,7.0563517,1993-02-22T22:03:12.312000,11.0,177, +-124.08761,40.322926,5.75,1993-02-22T22:21:42.402000,14.577377,177, +-123.760376,40.07362,4.95,1993-02-22T23:20:53.204000,19.443298,177, +-124.05751,40.27599,5.65,1993-02-24T21:49:03.592000,13.44077,177, +-124.11046,40.26158,5.15,1993-02-28T22:48:31.884000,8.238278,177, +-124.00142,40.197575,5.95,1993-05-18T17:44:25.588000,2.089315,177, +-123.93086,40.20225,5.05,1993-05-21T18:56:20.353000,19.782991,177, +-124.226265,40.338905,5.15,1992-07-10T11:25:54.763000,6.730285,178, +-120.55917,39.656513,4.95,1992-08-08T21:15:35.012000,8.198064,178, +-124.42871,40.28748,5.15,1992-08-23T06:24:08.625000,4.6468277,178, +-115.87426,31.718567,6.15,1992-12-01T16:42:52.510000,5.3353148,178, +-116.36854,33.459568,5.05,1993-04-13T21:45:34.600000,15.24116,178, +-122.5664,39.35796,5.05,1992-08-03T00:08:47.197000,6.4031773,179, +-114.84527,32.602695,6.05,1992-08-10T09:29:32.009000,6.6096287,179, +-114.87315,32.628323,5.15,1992-08-11T04:08:53.737000,8.362819,179, +-122.12197,38.004025,5.55,1992-10-06T05:22:10.356000,8.208137,179, +-122.489655,39.2537,5.45,1992-10-19T20:37:28.129000,9.652108,179, +-115.44084,32.311176,5.65,1992-11-19T08:15:51.136000,10.640835,179, +-115.46242,32.31833,5.35,1992-11-19T08:40:20.382000,8.080174,179, +-124.16083,40.41081,5.05,1992-11-28T05:21:33.476000,11.466667,179, +-124.47082,40.37121,5.35,1992-12-28T00:07:28.414000,18.214725,179, +-122.59283,39.30183,5.35,1993-01-30T22:26:44.211000,5.885479,179, +-115.703926,32.007095,5.45,1993-02-14T09:52:20.215000,7.9284816,179, +-115.72704,32.041748,5.25,1993-02-15T01:54:45.216000,7.1124783,179, +-120.52262,36.330868,5.15,1993-04-23T23:40:49.011000,11.033729,179, +-118.75346,37.53175,5.85,1993-06-22T12:17:33.923000,11.364867,179, +-124.12841,40.31826,5.05,1992-09-08T21:07:37.348000,12.302745,180, +-124.177025,40.271187,4.95,1992-09-11T16:49:51.587000,9.808301,180, +-115.03629,32.31092,5.15,1992-10-26T21:26:07.792000,6.2352686,180, +-120.16593,36.228508,5.05,1992-11-26T21:28:31.142000,19.2676,180, +-115.61218,32.827095,5.15,1992-12-06T07:56:42.629000,3.7975926,180, +-121.66873,41.346035,4.95,1992-12-21T08:49:42.620000,4.733828,180, +-124.4,40.36,7.416092,1993-02-03T09:02:32.293000,5.0,180, +-124.20382,40.178574,4.95,1993-02-03T09:07:34.316000,8.2800865,180, +-123.852,39.26528,5.25,1993-02-03T09:41:25.054000,1.4096915,180, +-124.05889,39.939796,5.15,1993-02-03T10:16:18.520000,3.9897385,180, +-123.89053,39.801216,5.45,1993-02-03T10:54:03.847000,4.994901,180, +-124.02779,39.91683,4.95,1993-02-03T15:29:43.478000,10.626071,180, +-123.95401,39.655575,4.95,1993-02-03T22:21:25.744000,5.369603,180, +-124.16268,40.082653,5.05,1993-02-03T23:26:26.194000,10.369015,180, +-124.847824,40.466507,5.85,1993-02-05T19:08:19.037000,16.792671,180, +-123.89551,39.36252,5.45,1993-02-08T06:33:03.406000,7.8555255,180, +-123.90573,39.353092,4.95,1993-02-08T06:38:29.149000,7.17786,180, +-124.02856,39.851215,5.85,1993-02-12T01:17:39.204000,8.693694,180, +-123.983505,39.88117,5.05,1993-02-12T04:29:20.566000,8.285318,180, +-124.00529,39.798088,4.95,1993-02-15T22:10:29.909000,12.50209,180, +-124.05153,39.941982,5.35,1993-02-16T17:52:02.151000,5.4475403,180, +-123.936455,39.517597,5.55,1993-03-04T05:59:13.166000,1.4267974,180, +-123.89304,39.79277,5.25,1993-03-04T13:41:22.923000,5.8976192,180, +-123.8464,39.632717,5.45,1993-03-31T07:37:03.955000,1.5189867,180, +-124.57402,40.380505,5.95,1993-04-13T03:56:28.498000,18.55346,180, +-118.51019,35.29969,5.55,1993-06-25T17:45:12.621000,7.292234,180, +-124.69779,40.375935,5.05,1993-06-28T10:50:12.702000,11.51267,180, +-124.14132,40.315384,5.45,1992-12-13T04:14:50.453000,11.466957,181, +-121.98288,37.574684,5.85,1992-07-17T10:10:22.046000,3.9302883,182, +-118.72207,34.436836,4.95,1992-08-20T13:21:00.391000,14.79767,182, +-120.618744,36.945595,5.05,1992-08-20T16:25:55.674000,6.224553,182, +-120.59203,37.026897,4.95,1992-08-21T02:10:40.606000,5.2681007,182, +-119.82406,35.230556,5.05,1992-08-29T12:36:58.540000,7.2917705,182, +-116.45639,33.001045,5.75,1992-10-03T01:24:33.086000,5.988683,182, +-120.525024,35.86229,5.05,1993-02-20T21:15:34.888000,6.0325985,182, +-124.1533,40.322037,4.95,1993-06-04T06:45:01.172000,9.912965,182, +-124.22473,40.38771,5.75,1992-08-01T19:15:43.362000,8.401943,183, +-124.207146,40.374443,5.15,1992-08-03T03:45:52.383000,6.464326,183, +-117.99836,34.628067,4.95,1992-09-26T06:22:37.105000,3.9705033,183, +-115.50648,32.399944,5.35,1992-10-12T19:58:29.680000,7.3715043,183, +-121.6541,37.33039,5.25,1992-10-24T10:08:15.585000,8.966185,183, +-115.39221,32.795868,5.15,1992-12-05T13:38:18.875000,9.028566,183, +-116.22912,36.840485,5.45,1992-12-22T09:08:27.159000,7.7049737,183, +-115.94168,31.773516,6.35,1993-01-11T05:04:57.651000,6.051642,183, +-115.99972,31.691242,5.05,1993-01-11T05:05:59.067000,8.054469,183, +-116.190315,33.796936,5.35,1993-01-31T01:54:57.717000,6.8848333,183, +-116.01267,31.816153,5.75,1993-02-01T15:14:59.935000,3.4472613,183, +-122.13978,36.489254,5.15,1993-03-09T21:19:36.673000,16.11031,183, +-121.68655,36.961517,5.35,1993-03-15T11:18:32.519000,6.487166,183, +-124.17167,40.307274,5.75,1993-03-26T09:11:05.371000,9.986821,183, +-124.24984,40.30693,5.25,1993-04-04T07:34:31.726000,7.666263,183, +-124.54,40.28,6.2110257,1993-05-31T22:30:46.471000,5.0,183, +-124.654144,40.368034,5.25,1993-05-31T22:37:13.712000,2.9189916,183, +-124.59893,40.32794,5.45,1993-06-01T00:05:21.738000,9.564136,183, +-116.30591,33.960526,4.95,1992-07-13T16:57:47.739000,2.483414,184, +-124.57811,40.426983,5.05,1992-08-12T11:52:50.845000,18.124382,184, +-124.15118,40.431004,4.95,1992-08-19T05:11:40.617000,11.597304,184, +-121.64,37.26,6.4293175,1992-09-05T18:39:29.971000,9.0,184, +-121.76105,37.41719,5.15,1992-09-06T17:24:22.250000,10.198276,184, +-121.75169,37.325397,5.45,1992-10-08T14:44:29.851000,3.0849924,184, +-124.56621,40.41845,5.25,1992-11-22T20:40:20.845000,19.619255,184, +-124.42305,40.355293,4.95,1992-11-26T20:32:49.420000,7.422985,184, +-124.232635,40.41193,6.15,1992-12-28T13:11:49.927000,9.791981,184, +-124.61928,39.224243,5.15,1993-03-05T15:31:10.555000,12.648916,184, +-124.13859,40.316,5.75,1993-03-12T00:41:00.060000,11.519174,184, +-118.720406,37.596634,5.45,1993-03-18T02:09:21.728000,11.584843,184, +-124.5824,39.590473,6.15,1993-03-19T22:45:59.162000,5.8130665,184, +-122.58226,38.890537,5.75,1993-04-01T13:19:20.110000,17.977268,184, +-122.60617,38.894753,5.15,1993-04-02T16:06:05.760000,16.13236,184, +-121.718994,37.333477,5.65,1993-04-23T22:20:43.388000,6.1066227,184, +-116.80024,34.40827,4.95,1992-07-10T05:10:21.890000,8.4509735,185, +-124.52605,40.301277,5.05,1992-07-14T05:37:30.127000,6.4354744,185, +-124.49769,40.316505,5.05,1992-10-15T20:55:09.789000,19.245523,185, +-124.497925,40.301533,5.15,1992-10-15T20:59:56.590000,18.61685,185, +-124.25371,40.391163,4.95,1992-10-20T07:24:26.271000,9.199066,185, +-122.636986,39.90051,5.05,1992-11-22T05:43:53.503000,6.204678,185, +-124.61865,40.327538,5.25,1992-12-12T15:21:06.772000,5.9563856,185, +-117.79002,34.383427,5.85,1993-04-03T17:33:50.278000,7.290117,185, +-124.577515,40.425953,5.05,1992-07-27T14:47:11.062000,17.226408,186, +-124.58727,40.371384,5.25,1992-08-13T16:01:03.098000,17.608574,186, +-119.77249,35.855846,5.55,1993-01-31T23:41:06.907000,9.595592,186, +-120.56428,36.362522,5.65,1993-02-05T04:45:19.521000,13.371407,186, +-118.457794,34.27215,5.55,1993-02-20T10:41:15.053000,12.544166,186, +-118.36,37.48,6.779193,1993-03-01T16:22:15.053000,9.0,186, +-118.4746,37.395073,5.15,1993-03-01T21:38:18.082000,12.527125,186, +-118.40991,37.57297,4.95,1993-03-17T01:10:16.245000,3.1475096,186, +-118.55626,34.51495,5.05,1993-04-19T18:36:24.048000,5.5725856,186, +-121.83131,42.335087,5.15,1993-05-17T08:49:10.052000,8.835785,186, +-119.55024,40.218765,4.95,1993-06-14T18:54:08.775000,11.996179,186, +-118.98199,38.749523,5.15,1992-07-07T18:36:51.027000,7.192236,187, +-121.75277,36.980167,4.95,1992-08-26T14:38:53.651000,7.4091234,187, +-118.94976,38.831623,5.35,1992-10-27T02:26:27.941000,11.031686,187, +-118.95515,38.821983,5.15,1992-10-27T02:33:25.152000,8.305194,187, +-118.75504,37.48558,5.05,1993-01-27T03:20:22.368000,2.83063,187, +-122.07495,37.92211,5.25,1993-04-26T01:52:47.555000,18.852337,187, +-116.30034,34.532326,5.35,1993-05-20T01:58:24.261000,9.780654,187, +-116.30509,34.548866,5.65,1993-05-21T01:28:34.686000,10.546824,187, +-118.53076,34.431046,6.15,1993-06-24T06:23:07.233000,15.278544,187, +-118.68399,34.386673,5.05,1993-06-24T19:34:33.293000,8.772938,187, +-118.517105,37.400913,5.05,1992-07-04T15:25:18.780000,17.517614,188, +-124.15767,40.277386,4.95,1992-07-15T23:10:33.849000,10.304594,188, +-124.41831,40.33656,5.35,1992-09-16T16:32:38.241000,4.0616374,188, +-116.338745,34.055264,5.55,1992-12-17T03:14:13.516000,6.0138583,188, +-124.78663,40.4459,4.95,1992-12-28T05:17:55.068000,3.2585993,188, +-124.18437,40.44,5.55,1992-10-08T08:35:31.559000,11.614586,189, +-120.10274,35.722095,5.05,1992-10-24T05:14:09.374000,6.1301637,189, +-121.07941,36.64747,5.25,1993-01-11T03:18:34.812000,15.167663,189, +-122.434425,40.488415,5.25,1993-03-26T19:35:04.752000,11.023224,189, +-120.54,35.9,6.066308,1993-03-29T12:38:27.600000,7.0,189, +-118.50582,34.437122,5.15,1993-04-26T02:25:06.407000,19.029856,189, +-116.0213,33.29583,5.25,1993-05-09T17:31:16.792000,6.0131407,189, +-116.038795,33.30145,5.05,1993-05-10T13:20:19.112000,6.4727764,189, +-116.81634,32.167118,5.15,1993-05-18T16:07:32.219000,7.5700984,189, +-121.65936,37.267414,6.0868263,1993-05-28T09:32:04.761000,4.488,189, +-121.47905,37.671364,4.95,1993-05-28T09:41:26.799000,6.7168417,189, +-118.737175,34.748928,5.05,1992-07-02T01:07:32.331000,19.6117,190, +-124.5797,40.13065,5.05,1992-07-12T21:05:13.542000,4.0827236,190, +-124.36447,40.34696,5.05,1992-07-30T04:11:16.938000,6.9379735,190, +-124.351036,40.34753,5.45,1992-07-30T04:23:08.142000,5.2400923,190, +-118.3641,37.58817,4.95,1992-10-09T20:28:28.163000,7.9723177,190, +-124.27685,40.321697,5.15,1992-12-26T19:12:51.414000,8.584875,190, +-124.223625,40.36172,5.85,1993-01-14T06:19:54.603000,9.312033,190, +-116.28461,33.84448,5.05,1993-03-27T09:00:05.115000,8.340819,190, +-124.29276,40.29563,5.05,1993-06-05T10:43:40.472000,7.8602066,190, +-124.5163,40.399956,4.95,1992-07-16T04:42:24.099000,17.048649,191, +-124.11524,40.411137,5.65,1992-07-22T05:56:57.935000,10.768266,191, +-124.36,40.3,6.2110257,1992-09-08T11:10:05.882000,7.0,191, +-124.35626,40.226585,4.95,1992-09-08T11:28:29.229000,4.8898997,191, +-116.485,33.377266,5.15,1992-09-16T00:07:44.535000,6.86902,191, +-124.34672,40.277527,4.95,1992-10-04T15:01:52.792000,7.7164087,191, +-121.88001,41.59905,5.45,1992-10-12T03:49:55.571000,4.891984,191, +-121.98,37.94,6.595845,1992-10-25T07:00:42.704000,5.0,191, +-122.08702,38.10966,5.05,1992-10-25T07:29:42.185000,1.7723999,191, +-122.08466,38.09888,5.05,1992-10-25T07:48:31.653000,0.85993344,191, +-120.87371,37.834053,5.05,1992-10-25T07:49:24.791000,7.9321914,191, +-122.43407,38.23492,4.95,1992-10-26T05:46:09.276000,17.556784,191, +-124.618645,40.346893,5.05,1992-11-22T13:46:02.263000,4.7949247,191, +-115.12633,32.275173,5.55,1992-12-27T12:04:47.404000,7.9529195,191, +-122.1055,38.09143,4.95,1993-04-10T01:30:54.366000,3.8170683,191, +-116.862045,34.42467,5.35,1993-05-29T13:06:37.328000,13.384171,191, +-124.54853,40.34047,5.25,1992-07-24T17:59:59.036000,23.337608,192, +-116.70507,34.610107,5.85,1992-08-25T13:41:59.300000,6.7968936,192, +-121.244804,36.706802,5.25,1992-09-16T08:50:57.354000,11.543755,192, +-116.7174,34.585865,5.95,1992-09-22T04:10:52.302000,9.848406,192, +-115.96895,34.841496,5.45,1992-09-22T04:47:38.449000,5.6195264,192, +-117.19335,34.1116,5.55,1993-04-06T20:28:51.761000,5.5950246,192, +-115.91027,31.704556,5.05,1993-04-21T02:25:20.686000,4.716404,192, +-119.74941,38.84294,4.95,1993-06-04T08:55:21.153000,16.305693,192, +-121.9705,37.123974,5.95,1993-06-18T00:14:15.793000,11.859802,192, +-121.94985,37.152348,5.55,1993-06-20T09:50:13.548000,9.90295,192, +-121.98371,37.23939,5.05,1993-06-20T10:07:43.226000,10.062528,192, +-124.17139,40.440674,5.25,1992-07-01T00:58:42.324000,12.181534,193, +-124.16776,40.446285,4.95,1992-07-05T04:06:18.593000,13.695651,193, +-120.65612,35.967377,4.95,1992-09-15T21:50:07.579000,3.1118026,193, +-124.46175,40.28031,5.45,1993-03-15T02:15:20.397000,7.6856546,193, +-118.21931,34.23293,6.05,1993-05-08T02:27:07.286000,9.451405,193, +-118.23609,34.22905,5.45,1993-05-08T03:15:21.405000,8.087418,193, +-118.01916,34.25353,5.75,1993-05-11T21:18:53.813000,13.519154,193, +-117.99299,34.279514,5.05,1993-05-11T21:46:19.227000,13.747334,193, +-124.36225,40.300316,4.95,1993-05-15T12:30:36.269000,7.6824756,193, +-116.900955,34.255173,5.15,1993-05-24T03:25:41.695000,7.175554,193, +-116.91583,34.24833,4.95,1993-05-24T06:22:53.605000,7.9499044,193, +-124.3307,40.376205,5.15,1992-09-02T05:39:18.539000,7.396652,194, +-124.87331,40.928894,5.95,1992-09-27T15:11:39.569000,3.1409335,194, +-122.862885,39.83298,5.05,1992-09-29T00:43:03.844000,9.525667,194, +-124.87498,40.94374,5.05,1992-11-14T14:39:05.643000,2.8903491,194, +-116.27691,36.719273,5.05,1993-02-13T22:41:23.282000,9.934244,194, +-121.735016,37.000164,5.65,1993-04-01T08:03:56.405000,3.7930884,194, +-124.10439,40.277103,5.05,1993-04-03T09:52:37.682000,10.864044,194, +-124.45784,40.289337,5.45,1993-04-26T21:44:59.444000,21.368982,194, +-124.47415,40.27358,5.15,1993-04-26T22:40:15.354000,20.229757,194, +-116.37016,33.90498,5.05,1993-05-20T17:20:04.314000,13.643714,194, +-124.94782,40.70474,6.35,1993-05-26T21:51:44.571000,5.2454095,194, +-124.88306,40.753746,5.15,1993-05-27T03:52:39.361000,6.035556,194, +-119.6093,42.17515,5.15,1993-05-28T07:41:10.724000,3.9297268,194, +-116.42576,34.46917,5.05,1992-08-03T03:28:19.818000,15.643542,195, +-119.97604,39.59214,5.55,1992-08-10T11:10:16.112000,8.712701,195, +-119.935005,39.578255,5.25,1992-08-10T11:17:09.494000,5.0613256,195, +-115.05127,32.080154,5.15,1992-09-11T15:41:40.892000,7.2125564,195, +-120.87892,41.817337,5.05,1992-12-28T23:11:27.854000,5.399865,195, +-123.03398,40.341263,4.95,1993-01-10T09:26:16.165000,6.787769,195, +-115.83184,33.120144,5.05,1993-02-22T17:10:58.820000,3.6118686,195, +-124.17785,40.278698,5.35,1992-08-18T01:33:27.172000,12.0840435,196, +-124.35227,40.473476,5.15,1992-09-04T08:13:00.320000,10.935138,196, +-121.66776,39.925255,4.95,1992-09-20T12:33:33.252000,6.77586,196, +-121.682655,39.919804,5.25,1992-09-21T01:38:41.149000,6.7414675,196, +-123.1324,39.84557,5.35,1992-12-05T11:34:16.908000,14.555071,196, +-123.16,39.84,7.0559835,1992-12-05T11:57:33.592000,11.0,196, +-123.230225,39.71209,5.65,1992-12-05T12:08:53.824000,9.546965,196, +-123.309586,39.869843,5.75,1992-12-05T12:27:26.973000,5.655661,196, +-123.4286,40.005,5.05,1992-12-05T12:28:59.979000,14.277181,196, +-123.31385,39.86123,5.05,1992-12-05T13:25:43.077000,1.8191692,196, +-122.65119,40.13443,5.05,1992-12-05T22:09:08.106000,5.408835,196, +-123.40063,39.993748,5.75,1992-12-06T19:16:20.685000,1.1663437,196, +-123.3715,39.93512,5.05,1992-12-07T08:32:10.607000,4.1677346,196, +-123.40894,39.99634,5.15,1992-12-07T21:15:42.208000,4.9944715,196, +-123.35456,39.82802,5.15,1992-12-08T16:27:18.892000,9.03658,196, +-123.406075,40.005177,5.15,1992-12-13T19:48:56.468000,4.146501,196, +-123.149185,39.687527,5.45,1992-12-16T14:24:45.678000,8.007139,196, +-123.32104,39.89098,4.95,1993-01-04T06:08:35.071000,7.3532314,196, +-122.02212,40.134144,4.95,1993-01-09T11:26:41.027000,5.195841,196, +-115.027855,32.18483,5.65,1993-01-17T17:47:02.185000,8.154374,196, +-115.04,32.22,6.6555033,1993-01-17T17:48:10.469000,7.0,196, +-114.98697,32.19058,5.65,1993-01-17T18:03:15.299000,5.9909716,196, +-115.026085,32.167175,5.05,1993-01-17T20:06:15.307000,9.654871,196, +-122.2008,40.559105,4.95,1993-01-19T22:16:42.764000,8.012474,196, +-123.17018,39.65724,5.05,1993-02-09T16:37:20.429000,10.216662,196, +-118.467064,37.46494,4.95,1993-02-24T21:26:16.912000,9.709422,196, +-114.964424,32.177296,5.05,1993-04-21T08:43:33.793000,13.124451,196, +-124.19157,40.290466,5.05,1992-07-19T01:36:17.660000,10.209869,197, +-124.60501,40.709415,4.95,1992-08-17T22:24:02.804000,14.5644045,197, +-117.04669,31.75689,5.55,1992-10-20T19:17:37.114000,4.812543,197, +-124.29683,40.2798,5.05,1992-10-21T01:01:49.174000,9.770945,197, +-124.380135,40.436577,5.45,1992-12-21T02:14:15.716000,9.223336,197, +-120.151375,36.264317,5.25,1992-12-21T10:08:38.010000,5.4207835,197, +-124.37535,40.459126,5.05,1992-12-25T04:34:52.684000,9.488355,197, +-121.66503,36.908894,5.35,1993-01-18T07:57:18.337000,6.840602,197, +-124.34699,40.311405,5.55,1993-05-22T21:46:52.054000,5.9395013,197, +-119.0266,37.008034,4.95,1992-07-09T16:53:51.410000,18.876175,198, +-121.55103,36.780605,5.45,1992-10-16T05:07:19.629000,15.039715,198, +-116.8615,34.354465,5.35,1992-11-10T19:08:33.608000,3.7673824,198, +-122.647026,38.42339,4.95,1993-03-30T15:06:50.063000,7.2451835,198, +-123.6033,38.8888,5.25,1993-04-08T04:43:01.547000,8.151295,198, +-123.64185,40.870853,5.85,1992-07-31T19:04:15.953000,13.241051,199, +-121.67279,36.934772,4.95,1992-08-18T22:23:48.592000,5.52786,199, +-118.28,33.98,6.3608303,1993-06-26T06:25:35.503000,7.0,199, +-118.324875,33.954807,4.95,1993-06-26T06:25:56.311000,3.5491087,199, +-118.31441,33.999462,5.15,1993-06-26T06:27:04.872000,4.6716175,199, \ No newline at end of file diff --git a/tests/artifacts/example_csep2_forecasts/Results/calibration_m.json b/tests/artifacts/example_csep2_forecasts/Results/calibration_m.json new file mode 100644 index 00000000..89bdff6c --- /dev/null +++ b/tests/artifacts/example_csep2_forecasts/Results/calibration_m.json @@ -0,0 +1,125 @@ +{ + "name": "M-Test Calibration Test", + "sim_name": "mock model", + "obs_name": null, + "obs_catalog_repr": "\n Name: None\n\n Start Date: 2016-08-24 23:22:05.830000+00:00\n End Date: 2016-08-25 19:40:44.870000+00:00\n\n Latitude: (42.594, 42.748)\n Longitude: (13.17, 13.326)\n\n Min Mw: 3.0\n Max Mw: 4.2\n\n Event Count: 12\n ", + "quantile": 4.035055561627383e-76, + "observed_statistic": 0.7940668202764978, + "test_distribution": [ + 1.0, + 0.9897959183673469, + 1.0, + 0.9431818181818182, + 0.875, + 1.0, + 0.8823529411764706, + 0.98989898989899, + 1.0, + 0.8823529411764706, + 0.8421052631578947, + 1.0, + 0.8421052631578947, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.8421052631578947, + 1.0, + 1.0, + 1.0, + 1.0, + 0.8421052631578947, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.8421052631578947, + 0.9571428571428572, + 0.8, + 1.0, + 1.0, + 1.0, + 0.8421052631578947, + 1.0, + 1.0, + 1.0, + 0.8421052631578947, + 0.7571428571428571, + 0.9571428571428572, + 1.0, + 1.0, + 0.9896907216494846, + 0.9489795918367347, + 1.0, + 0.99, + 1.0, + 0.9896907216494846, + 1.0, + 1.0, + 0.8953488372093024, + 0.8953488372093024, + 1.0, + 0.9130434782608695, + 1.0, + 0.8953488372093024, + 0.8571428571428571, + 1.0, + 0.8571428571428571, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.8076923076923077, + 1.0, + 1.0, + 0.8076923076923077, + 0.9292929292929293, + 0.9292929292929293, + 1.0, + 0.8709677419354839, + 1.0, + 0.8709677419354839, + 0.6206896551724138, + 1.0, + 0.8709677419354839, + 1.0, + 0.8709677419354839, + 0.859375, + 1.0, + 0.8709677419354839, + 1.0, + 0.8387096774193549, + 0.859375, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.8709677419354839, + 1.0, + 1.0 + ], + "status": "normal", + "min_mw": 3.0, + "type": "CalibrationTestResult" +} \ No newline at end of file diff --git a/tests/artifacts/example_csep2_forecasts/Results/calibration_n.json b/tests/artifacts/example_csep2_forecasts/Results/calibration_n.json new file mode 100644 index 00000000..cbc168c6 --- /dev/null +++ b/tests/artifacts/example_csep2_forecasts/Results/calibration_n.json @@ -0,0 +1,141 @@ +{ + "name": "Catalog N-Test Calibration Test", + "sim_name": "mock model", + "obs_name": null, + "obs_catalog_repr": "\n Name: None\n\n Start Date: 2016-08-24 23:22:05.830000+00:00\n End Date: 2016-08-25 19:40:44.870000+00:00\n\n Latitude: (42.594, 42.748)\n Longitude: (13.17, 13.326)\n\n Min Mw: 3.0\n Max Mw: 4.2\n\n Event Count: 12\n ", + "quantile": 2.9459914902189315e-58, + "observed_statistic": 0.6752683080808081, + "test_distribution": [ + 0.0, + 1.0, + 1.0, + 1.0, + 0.98, + 0.89, + 1.0, + 0.98, + 0.89, + 1.0, + 0.12, + 1.0, + 0.89, + 1.0, + 0.63, + 0.8080808080808081, + 1.0, + 0.98989898989899, + 0.98989898989899, + 0.98989898989899, + 0.98989898989899, + 1.0, + 0.11, + 0.98989898989899, + 1.0, + 0.98989898989899, + 1.0, + 0.98989898989899, + 1.0, + 0.98989898989899, + 0.98989898989899, + 1.0, + 0.8080808080808081, + 0.8080808080808081, + 0.98989898989899, + 0.8080808080808081, + 1.0, + 0.8080808080808081, + 0.98989898989899, + 1.0, + 0.98989898989899, + 0.98989898989899, + 1.0, + 1.0, + 0.98989898989899, + 0.898989898989899, + 0.29292929292929293, + 1.0, + 0.8080808080808081, + 0.98989898989899, + 0.98989898989899, + 0.8080808080808081, + 1.0, + 0.29292929292929293, + 0.8080808080808081, + 0.98989898989899, + 0.98989898989899, + 0.8080808080808081, + 0.8080808080808081, + 0.98989898989899, + 1.0, + 0.6060606060606061, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.0, + 1.0, + 1.0, + 1.0, + 0.93, + 1.0, + 1.0, + 0.9696969696969697, + 0.98989898989899, + 1.0, + 1.0, + 0.9696969696969697, + 1.0, + 0.88, + 1.0, + 0.9797979797979798, + 1.0, + 0.8787878787878788, + 1.0, + 1.0, + 1.0, + 1.0, + 0.98, + 1.0, + 0.13131313131313133, + 1.0, + 1.0, + 1.0, + 0.96, + 0.98, + 0.11, + 1.0, + 0.88, + 1.0, + 0.41, + 0.65, + 1.0, + 0.88, + 1.0, + 0.99, + 0.88, + 1.0, + 0.65, + 0.98, + 0.99, + 0.73, + 0.98, + 0.98, + 1.0, + 1.0, + 0.98, + 1.0, + 0.98, + 0.98, + 0.98, + 1.0, + 1.0, + 0.58, + 0.69, + 0.98, + 0.69 + ], + "status": "normal", + "min_mw": 3.0, + "type": "CalibrationTestResult" +} \ No newline at end of file diff --git a/tests/artifacts/example_csep2_forecasts/Results/catalog_l_test.json b/tests/artifacts/example_csep2_forecasts/Results/catalog_l_test.json new file mode 100644 index 00000000..1a376ecc --- /dev/null +++ b/tests/artifacts/example_csep2_forecasts/Results/catalog_l_test.json @@ -0,0 +1,10016 @@ +{ + "name": "Catalog PL-Test", + "sim_name": "ucerf3-landers", + "obs_name": null, + "obs_catalog_repr": "\n Name: None\n\n Start Date: 1992-06-28 12:00:45+00:00\n End Date: 1992-07-24 18:14:36.250000+00:00\n\n Latitude: (33.901, 36.705)\n Longitude: (-118.067, -116.285)\n\n Min Mw: 4.95\n Max Mw: 6.3\n\n Event Count: 19\n ", + "quantile": [ + 0.9831, + 0.0169 + ], + "observed_statistic": -83.84476165566868, + "test_distribution": [ + -9.736368600516062, + -16.939910453761918, + -25.530490391405127, + -9.439757897319982, + -5.933199999999999, + -9.439757897319982, + -11.728440085145035, + -12.14780809842219, + -6.632767748362867, + -5.933199999999999, + -13.757246010856292, + -14.758550117057403, + -15.143540371976181, + -12.840955278982136, + -23.85857493184441, + -22.120517120000272, + -5.933199999999999, + -9.768261964292018, + -15.143540371976181, + -12.98957130331092, + -19.517598837000886, + -15.143540371976181, + -52.265015842704855, + -5.933199999999999, + -42.1778119488188, + -12.636432014204495, + -12.02598434856935, + -5.933199999999999, + -12.02598434856935, + -5.933199999999999, + -5.933199999999999, + -8.221882187825054, + -54.92833014996567, + -16.468551504679173, + -8.3568234213711, + -5.933199999999999, + -23.66073356339242, + -8.839091569554201, + -5.933199999999999, + -8.828182370453847, + -5.933199999999999, + -39.20243754652971, + -15.143540371976181, + -5.933199999999999, + -13.826730074386877, + -19.229916764549106, + -19.811011584161655, + -13.757246010856292, + -16.950819652862272, + -16.87401661278734, + -8.3568234213711, + -15.746846848536338, + -16.165191619508164, + -5.933199999999999, + -12.64718286751916, + -21.581292021712585, + -5.933199999999999, + -20.328529053217213, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -16.950819652862272, + -5.933199999999999, + -17.26380390817627, + -5.933199999999999, + -8.221882187825054, + -15.143540371976181, + -11.621081566824536, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -8.221882187825054, + -15.143540371976181, + -15.143540371976181, + -9.120092779015149, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -11.954023329354857, + -9.120092779015149, + -5.933199999999999, + -17.132044918663915, + -5.933199999999999, + -8.3568234213711, + -10.98465728861651, + -5.933199999999999, + -20.179493474056727, + -5.933199999999999, + -5.933199999999999, + -10.645505609196155, + -5.933199999999999, + -5.933199999999999, + -29.05314868922367, + -8.3568234213711, + -5.933199999999999, + -5.933199999999999, + -26.999704294100702, + -39.56919652506448, + -13.540487979650003, + -5.933199999999999, + -17.432222559801236, + -22.967586382832476, + -5.933199999999999, + -15.143540371976181, + -16.676017243274153, + -13.757246010856292, + -9.1446038100295, + -17.668019796884007, + -11.347723146726064, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -26.004083152559783, + -9.736368600516062, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -12.14780809842219, + -5.933199999999999, + -71.76858307738873, + -11.964932528455211, + -78.85462141920162, + -45.50456592936327, + -5.933199999999999, + -12.310327027919966, + -19.95448581511739, + -5.933199999999999, + -25.57910782871324, + -5.933199999999999, + -5.933199999999999, + -8.3568234213711, + -12.631350970969912, + -9.736368600516062, + -5.933199999999999, + -9.498093474332943, + -11.083097361429763, + -18.285455155708256, + -13.351780902748127, + -28.314127075226715, + -21.88228732322649, + -18.044877065663073, + -5.933199999999999, + -9.439757897319982, + -5.933199999999999, + -8.828182370453847, + -5.933199999999999, + -5.933199999999999, + -18.740752637564295, + -5.933199999999999, + -14.044928083308072, + -11.433285997854554, + -5.933199999999999, + -35.97089337360363, + -5.933199999999999, + -30.791632393688765, + -16.70418812024085, + -5.933199999999999, + -8.839091569554201, + -12.02598434856935, + -5.933199999999999, + -5.933199999999999, + -11.92466454710798, + -26.093427341733488, + -9.768261964292018, + -8.839091569554201, + -13.064098830296345, + -16.150303007014415, + -5.933199999999999, + -39.3609413544745, + -25.83229039398006, + -5.933199999999999, + -5.933199999999999, + -13.534102459542082, + -5.933199999999999, + -13.351780902748128, + -9.059040958901011, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -12.578591014514647, + -5.933199999999999, + -9.95058352108597, + -13.821304647157012, + -9.736368600516062, + -15.143540371976181, + -17.032692187212888, + -5.933199999999999, + -20.66500128983843, + -12.512241633973112, + -8.221882187825054, + -14.513918892296115, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -9.768261964292018, + -15.143540371976181, + -5.933199999999999, + -16.47762186164914, + -13.472819231125182, + -5.933199999999999, + -5.933199999999999, + -8.3568234213711, + -16.246763273201974, + -8.3568234213711, + -18.85106346738292, + -5.933199999999999, + -15.143540371976181, + -9.439757897319982, + -5.933199999999999, + -22.55974077702525, + -24.353880743952363, + -5.933199999999999, + -14.450393191416238, + -13.06298694866589, + -15.11806757600315, + -12.578591014514647, + -8.839091569554201, + -30.61256612961548, + -5.933199999999999, + -13.757246010856292, + -30.287703747686678, + -15.143540371976181, + -8.221882187825054, + -5.933199999999999, + -13.757246010856292, + -8.839091569554201, + -13.351780902748127, + -8.3568234213711, + -12.025050788341117, + -8.828182370453847, + -5.933199999999999, + -5.933199999999999, + -16.024463960013044, + -43.026104513740634, + -13.90976375464959, + -11.5682272314006, + -16.468551504679173, + -10.539001385152376, + -54.349328314619285, + -5.933199999999999, + -14.672287523330015, + -5.933199999999999, + -8.221882187825054, + -5.933199999999999, + -17.170769042209084, + -19.926685364539935, + -5.933199999999999, + -27.19710003215996, + -5.933199999999999, + -5.933199999999999, + -16.884349933680408, + -12.565598856220992, + -5.933199999999999, + -5.933199999999999, + -22.595471254405865, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -22.156656166616145, + -12.370951649736401, + -15.143540371976181, + -21.868974094164365, + -9.736368600516062, + -9.967390639402353, + -5.933199999999999, + -8.221882187825054, + -5.933199999999999, + -13.154283418417503, + -14.044928083308072, + -11.8854438339547, + -9.1446038100295, + -5.933199999999999, + -9.571386339798417, + -24.683913756944676, + -9.439757897319982, + -5.933199999999999, + -5.933199999999999, + -22.156656166616145, + -12.578591014514647, + -5.933199999999999, + -9.059040958901011, + -15.143540371976181, + -12.253168614080018, + -15.143540371976181, + -5.933199999999999, + -10.23088548624013, + -9.059040958901011, + -5.933199999999999, + -26.127014749057253, + -20.770361805496254, + -13.534102459542082, + -8.221882187825054, + -5.933199999999999, + -5.933199999999999, + -13.534102459542082, + -17.532233096090298, + -5.933199999999999, + -5.933199999999999, + -14.939843895174535, + -12.946315794639963, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -11.965486541628238, + -8.3568234213711, + -16.950819652862272, + -34.04193438824433, + -11.811335861800977, + -5.933199999999999, + -48.698839004275115, + -5.933199999999999, + -22.80419793147842, + -22.156656166616145, + -15.143540371976181, + -11.954023329354857, + -27.540773522967513, + -10.621751794927142, + -23.03707044636306, + -5.933199999999999, + -5.933199999999999, + -9.120092779015149, + -5.933199999999999, + -5.933199999999999, + -8.221882187825054, + -16.78137775893198, + -19.854071073622098, + -15.77540432411923, + -26.59067809640841, + -17.35628476097044, + -11.262714990925303, + -5.933199999999999, + -21.645830542850153, + -8.221882187825054, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -8.3568234213711, + -10.700889115485865, + -19.959431589279927, + -5.933199999999999, + -21.581292021712585, + -8.828182370453847, + -14.450393191416238, + -17.170769042209084, + -11.8854438339547, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -9.120092779015149, + -9.1446038100295, + -14.450393191416238, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -9.1446038100295, + -12.658633722188181, + -9.059040958901011, + -33.24039999686089, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -8.221882187825054, + -5.933199999999999, + -5.933199999999999, + -14.65846341823297, + -12.684986253348095, + -12.74564509917781, + -32.980888801375805, + -12.946315794639963, + -14.044928083308072, + -5.933199999999999, + -14.044928083308072, + -14.450393191416238, + -18.75723369250423, + -8.221882187825054, + -43.81364208119474, + -5.933199999999999, + -12.709497284362444, + -5.933199999999999, + -5.933199999999999, + -12.099017934252759, + -12.039586180483347, + -68.60631753365848, + -13.064098830296345, + -9.439757897319982, + -10.223559446148057, + -5.933199999999999, + -20.137712431877425, + -12.946315794639963, + -5.933199999999999, + -26.9322499179523, + -43.57106918663056, + -46.57994003537554, + -17.651477917629432, + -23.72884306218547, + -11.839572377373532, + -55.81449119819182, + -42.62392561413135, + -30.261079149293824, + -45.69842615631221, + -58.679374245816604, + -31.14812748565946, + -24.598177060343765, + -69.05467275443914, + -48.687688170691565, + -31.45305071920789, + -35.133981658143405, + -19.527532430230337, + -63.21439005402571, + -34.33548447853303, + -41.80104340553968, + -37.47776510057158, + -25.740443428106122, + -19.770985396127898, + -15.350270847347089, + -36.019727375389195, + -35.350111422264106, + -37.724950345097284, + -19.35112799938552, + -20.831021063518765, + -27.534309229014568, + -55.10041563301059, + -23.484652550147203, + -45.30381817895512, + -17.148465665248075, + -35.045427739061154, + -61.705206516628934, + -37.719888319593004, + -10.047785564395253, + -23.293036582501358, + -31.1364384465452, + -12.389790043230917, + -14.928600194762936, + -33.82739411512051, + -19.707018259165082, + -23.898159376680777, + -32.77511413145985, + -29.260108097566317, + -25.421718964218922, + -11.601883048781502, + -19.821567630263154, + -20.473405400130027, + -36.46306985747238, + -47.09702415679264, + -25.99315626725466, + -21.339279070483023, + -26.46113080071575, + -34.61035667128088, + -13.31190425308424, + -37.832948791503966, + -23.21608245314064, + -82.93615452077738, + -40.074712012849126, + -23.422235414875743, + -48.96952356836328, + -41.29822832711899, + -28.94983673521917, + -28.93783015491588, + -41.877128545664696, + -159.28390367910603, + -35.199760812255846, + -30.501230757525395, + -34.40981802334062, + -32.23071943611063, + -25.378032124532183, + -31.939625399283823, + -28.720173099595485, + -25.59078784857588, + -12.442616904415, + -51.743565738715596, + -84.68767882147112, + -42.37559282122175, + -45.16469574832509, + -28.735223824343894, + -31.06037648996514, + -51.58343465268344, + -25.00325007725844, + -15.38967450108212, + -15.897750557562869, + -19.975943891965468, + -13.317770882632264, + -45.40848441329423, + -22.35064995274927, + -41.00457677774705, + -23.3104808794039, + -13.024303671652632, + -42.36096677721459, + -30.193843519189546, + -50.61698594130338, + -26.304737348575696, + -12.504483042360924, + -12.306985558030298, + -12.435490170873972, + -15.143540371976181, + -26.632749310329093, + -5.933199999999999, + -5.933199999999999, + -9.1446038100295, + -5.933199999999999, + -8.3568234213711, + -22.967586382832476, + -8.828182370453847, + -9.736368600516062, + -9.768261964292018, + -12.946315794639963, + -5.933199999999999, + -9.498093474332943, + -5.933199999999999, + -5.933199999999999, + -15.143540371976181, + -5.933199999999999, + -5.933199999999999, + -9.736368600516062, + -11.677804469176454, + -5.933199999999999, + -21.095923333300952, + -8.221882187825054, + -27.552953941524386, + -14.044928083308072, + -13.534102459542082, + -21.48078514090669, + -16.793800278930537, + -5.933199999999999, + -22.156656166616145, + -17.098995933875027, + -31.07931446614055, + -8.3568234213711, + -13.351780902748127, + -13.064098830296345, + -5.933199999999999, + -8.3568234213711, + -44.233976376190654, + -14.63996550956225, + -14.889208279205954, + -12.578591014514647, + -5.933199999999999, + -8.828182370453847, + -30.92516378631329, + -10.347749826379442, + -14.044928083308072, + -5.933199999999999, + -22.967586382832476, + -14.522641355623861, + -5.933199999999999, + -11.728440085145035, + -13.603323928584036, + -5.933199999999999, + -12.658633722188181, + -10.510564375650109, + -13.697457154665258, + -5.933199999999999, + -15.143540371976181, + -14.044928083308072, + -5.933199999999999, + -17.57493886200283, + -9.059040958901011, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -11.709553167491036, + -10.518567558691911, + -13.274819861611999, + -5.933199999999999, + -23.560067388933046, + -5.933199999999999, + -12.504483042360924, + -16.43125716973508, + -22.967586382832472, + -5.933199999999999, + -9.120092779015149, + -5.933199999999999, + -5.933199999999999, + -9.059040958901011, + -5.933199999999999, + -11.454660917862245, + -10.645505609196155, + -5.933199999999999, + -15.143540371976181, + -5.933199999999999, + -5.933199999999999, + -9.059040958901011, + -13.757246010856292, + -8.221882187825054, + -10.780446842742203, + -12.504483042360924, + -8.221882187825054, + -12.306985558030298, + -5.933199999999999, + -9.1446038100295, + -5.933199999999999, + -12.894102923193028, + -5.933199999999999, + -44.663713303141435, + -18.54651903918586, + -15.640463090573181, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -21.645830542850156, + -5.933199999999999, + -5.933199999999999, + -8.221882187825054, + -5.933199999999999, + -8.3568234213711, + -5.933199999999999, + -8.3568234213711, + -18.94112281046687, + -13.534102459542082, + -5.933199999999999, + -13.67542921319605, + -5.933199999999999, + -5.933199999999999, + -8.221882187825054, + -46.30774266034515, + -15.143540371976181, + -5.933199999999999, + -5.933199999999999, + -25.534137021660985, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -9.1446038100295, + -8.221882187825054, + -8.3568234213711, + -13.06298694866589, + -23.11413395963927, + -18.61087755614288, + -51.44183624762312, + -5.933199999999999, + -5.933199999999999, + -21.645830542850156, + -5.933199999999999, + -24.18160952301191, + -17.26380390817627, + -5.933199999999999, + -19.160923893062154, + -13.197630222920868, + -8.839091569554201, + -19.471078821365992, + -14.450393191416238, + -5.933199999999999, + -18.469551620052446, + -24.353880743952363, + -5.933199999999999, + -5.933199999999999, + -8.3568234213711, + -13.197630222920868, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -15.424962001956416, + -9.059040958901011, + -15.143540371976181, + -5.933199999999999, + -20.06090939180249, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -14.473564105627077, + -13.351780902748127, + -15.129637466807191, + -5.933199999999999, + -9.736368600516062, + -12.856475090640174, + -11.61717984736002, + -12.253168614080018, + -27.9012606357926, + -5.933199999999999, + -11.347723146726064, + -5.933199999999999, + -18.35494418200568, + -41.32023471639301, + -5.933199999999999, + -13.337877997579136, + -5.933199999999999, + -5.933199999999999, + -53.41201821552106, + -5.933199999999999, + -31.382516350250366, + -13.197630222920868, + -5.933199999999999, + -24.500063254130446, + -5.933199999999999, + -23.876405099867927, + -10.510564375650109, + -12.946315794639963, + -5.933199999999999, + -5.933199999999999, + -39.763389029862864, + -37.0583382217294, + -45.63053555764782, + -20.35081473986866, + -16.557910490986387, + -70.73652219353181, + -32.76421546629925, + -24.29280470535344, + -26.25035866445733, + -32.040556779136864, + -72.9722260358881, + -16.63442647518991, + -19.865844031104423, + -19.398694026609903, + -22.827245660298406, + -29.159129405906224, + -25.87875903198401, + -17.212024688727176, + -30.009551052961953, + -10.837287956361017, + -23.39044167606034, + -25.910647066349526, + -45.14902164555717, + -68.30948669537256, + -24.395216993631276, + -21.982306616542182, + -30.303973522464787, + -8.325089522335853, + -34.12674931101774, + -28.376519467502906, + -17.22298025645618, + -23.39116491856113, + -12.187045605634875, + -33.02226028650128, + -43.0578449111221, + -42.03840373717593, + -30.279907755119712, + -41.947173350271925, + -29.41155186353003, + -72.41375105979283, + -15.222658561089402, + -24.797574654792182, + -41.010940178279284, + -40.427419733408, + -115.24001618760805, + -33.23504837790894, + -36.73344691625898, + -94.69448192844305, + -17.565980323869457, + -24.39304781434346, + -37.94995468607131, + -28.771386970345027, + -19.8245167168901, + -16.61780173574159, + -17.57025951155851, + -42.39866517582194, + -21.577092385597876, + -40.7527653071356, + -36.56344344809139, + -27.73563365454438, + -24.16752586868492, + -53.43832684762622, + -12.884822006119796, + -23.99373387234707, + -43.68710941724698, + -43.706381302331316, + -19.478952200178583, + -36.902212803122104, + -17.627185262879294, + -19.60915231603533, + -13.649338916089503, + -36.15089224370621, + -34.07813203270207, + -43.74532035158192, + -21.723780151516788, + -21.833229416931278, + -23.559071464941415, + -24.71705347570023, + -59.296668486360375, + -28.056188748711822, + -37.708141955320656, + -8.096361132356119, + -19.292976479117613, + -43.179027934489405, + -17.621531921522703, + -17.88487462457413, + -14.304658278694356, + -27.95999130357064, + -61.70199287959039, + -40.973256614069456, + -30.884834336143047, + -48.26201590557228, + -28.419000370196187, + -31.237442698659184, + -41.03366067728505, + -16.33746084884803, + -61.355733884091975, + -15.651792685823725, + -33.30280534838404, + -15.920007861567335, + -14.986459675430785, + -9.120092779015149, + -16.13320857365511, + -5.933199999999999, + -15.143540371976181, + -19.78953255248453, + -12.09901793425276, + -5.933199999999999, + -33.579740927586585, + -7.633109815598175, + -8.3568234213711, + -5.933199999999999, + -5.933199999999999, + -14.450393191416238, + -5.933199999999999, + -8.828182370453847, + -14.25433310851177, + -5.933199999999999, + -26.87960938826062, + -5.933199999999999, + -23.803103904684146, + -5.933199999999999, + -8.3568234213711, + -13.757246010856292, + -5.933199999999999, + -5.933199999999999, + -10.758950774499187, + -16.8830869697573, + -5.933199999999999, + -22.05129565095832, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -21.471541157753464, + -5.933199999999999, + -9.1446038100295, + -8.828182370453847, + -27.314862279824528, + -5.933199999999999, + -144.52652764231405, + -44.255611286726804, + -15.143540371976181, + -5.933199999999999, + -5.933199999999999, + -227.6544233988356, + -12.840955278982136, + -22.967586382832476, + -27.747109955965342, + -8.221882187825054, + -8.839091569554201, + -18.35494418200568, + -5.933199999999999, + -5.933199999999999, + -8.3568234213711, + -21.868974094164365, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -8.828182370453847, + -5.933199999999999, + -5.933199999999999, + -9.059040958901011, + -5.933199999999999, + -5.933199999999999, + -9.967390639402353, + -8.3568234213711, + -26.792768926912142, + -11.314898975487086, + -5.933199999999999, + -27.600384608921907, + -27.89129488485218, + -13.351780902748127, + -16.303177362482067, + -8.221882187825054, + -17.23182086232322, + -5.933199999999999, + -22.156656166616145, + -35.78157611748048, + -5.933199999999999, + -19.834892824215768, + -8.221882187825054, + -14.450393191416238, + -5.933199999999999, + -5.933199999999999, + -13.534102459542082, + -5.933199999999999, + -11.5682272314006, + -9.1446038100295, + -5.933199999999999, + -5.933199999999999, + -9.1446038100295, + -5.933199999999999, + -8.3568234213711, + -15.385994171824892, + -9.120092779015149, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -24.297208128093146, + -15.35781121839231, + -10.223559446148057, + -5.933199999999999, + -14.450393191416238, + -21.135004919084164, + -9.439757897319982, + -11.756022800370584, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -10.347749826379442, + -14.4386985708401, + -22.967586382832476, + -13.351780902748127, + -5.933199999999999, + -13.821304647157012, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -12.504483042360924, + -16.87401661278734, + -9.498093474332943, + -15.143540371976181, + -5.933199999999999, + -12.310327027919966, + -9.95058352108597, + -5.933199999999999, + -5.933199999999999, + -15.143540371976181, + -5.933199999999999, + -10.645505609196155, + -5.933199999999999, + -8.828182370453847, + -19.299634388401536, + -5.933199999999999, + -12.946315794639963, + -5.933199999999999, + -15.143540371976181, + -5.933199999999999, + -15.143540371976181, + -5.933199999999999, + -5.933199999999999, + -23.52432506361287, + -12.578591014514645, + -9.768261964292018, + -5.933199999999999, + -5.933199999999999, + -39.96858999567978, + -26.502543754674154, + -19.533599178347327, + -34.60155017617976, + -5.933199999999999, + -9.059040958901011, + -5.933199999999999, + -5.933199999999999, + -9.571386339798417, + -5.933199999999999, + -15.143540371976181, + -5.933199999999999, + -27.298919903190836, + -5.933199999999999, + -21.148698246216167, + -8.3568234213711, + -5.933199999999999, + -11.39674112727648, + -9.95058352108597, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -16.129083759078163, + -14.044928083308072, + -20.447292480014262, + -13.351780902748127, + -27.651802081358483, + -5.933199999999999, + -12.435490170873972, + -11.744983139108403, + -22.744442831518263, + -21.58129202171258, + -24.353880743952363, + -15.143540371976181, + -17.345375561870085, + -40.43893752697297, + -5.933199999999999, + -14.044928083308072, + -5.933199999999999, + -9.967390639402353, + -12.947772410545562, + -14.595667745855353, + -14.450393191416238, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -14.044928083308072, + -5.933199999999999, + -22.120517120000272, + -14.044928083308072, + -13.064098830296345, + -22.744442831518263, + -15.143540371976181, + -13.064098830296345, + -5.933199999999999, + -5.933199999999999, + -25.139143213420116, + -11.734073940008049, + -15.143540371976181, + -13.197630222920868, + -29.760168793683583, + -5.933199999999999, + -18.67320518976107, + -5.933199999999999, + -13.534102459542082, + -5.933199999999999, + -11.314898975487086, + -23.66073356339242, + -8.221882187825054, + -9.059040958901011, + -11.408774966840204, + -5.933199999999999, + -15.777002666250493, + -5.933199999999999, + -12.658633722188181, + -18.766632085552114, + -11.677804469176454, + -12.099017934252759, + -5.933199999999999, + -5.933199999999999, + -15.39946541281477, + -8.3568234213711, + -17.110615119389337, + -5.933199999999999, + -5.933199999999999, + -53.27945492135267, + -14.480567573488173, + -13.534102459542082, + -12.184881917802022, + -21.80592566464052, + -5.933199999999999, + -5.933199999999999, + -20.09831200673213, + -8.3568234213711, + -13.351780902748127, + -8.3568234213711, + -5.933199999999999, + -5.933199999999999, + -15.143540371976181, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -8.221882187825054, + -36.67082908582847, + -19.856711222416475, + -5.933199999999999, + -12.14780809842219, + -34.88248306665661, + -14.541850801905072, + -22.74987757300831, + -5.933199999999999, + -13.351780902748127, + -26.65646583694641, + -5.933199999999999, + -5.933199999999999, + -14.450393191416238, + -9.439757897319982, + -18.729216362773847, + -5.933199999999999, + -25.50683260430809, + -13.064098830296345, + -8.828182370453847, + -32.692007671295315, + -10.223559446148057, + -12.578591014514647, + -22.562121274724312, + -15.143540371976181, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -47.2888677275877, + -5.933199999999999, + -26.093427341733488, + -16.439994029096283, + -14.450393191416238, + -16.87401661278734, + -30.568488842374556, + -14.450393191416238, + -5.933199999999999, + -10.510564375650109, + -9.059040958901011, + -14.044928083308072, + -92.49142627528228, + -5.933199999999999, + -9.768261964292018, + -9.498093474332943, + -8.3568234213711, + -5.933199999999999, + -15.704431973415655, + -64.64846053624159, + -26.811883015125137, + -15.721273455973186, + -22.291933895862304, + -17.925124722085872, + -45.25688438137652, + -13.043494657608438, + -32.150051497740535, + -27.026378596784518, + -20.19357135360611, + -37.33318217680629, + -23.3751185958608, + -21.92375719062784, + -28.394433936902523, + -18.227619024286653, + -20.208518974418404, + -107.8007456920458, + -33.383874204097204, + -29.080151488669827, + -35.58550273030333, + -25.263946881103355, + -44.0463264363429, + -21.75742230363919, + -31.95805088142097, + -156.2398981839316, + -19.61485805351409, + -25.941558478824867, + -21.28878122942791, + -23.498385994544172, + -16.494290409260778, + -61.48018964469637, + -49.922358292254046, + -18.53317903978383, + -19.267395558222482, + -56.31476711502441, + -43.55577742998818, + -13.986132949982292, + -54.53692447732609, + -9.706547654972997, + -21.345066350651262, + -35.281601616042295, + -11.97876903763792, + -50.00985929434777, + -22.70789140568497, + -22.8924220944136, + -52.57197600779011, + -12.201022737665197, + -43.476384656292105, + -53.70843044411538, + -23.588226699696214, + -37.77220731309865, + -27.05707044931234, + -48.62825799206864, + -26.49514467853943, + -21.29107321057139, + -38.82140468044962, + -15.658944738254409, + -43.25012838554885, + -28.184867570354356, + -35.192118416083346, + -16.724326120678853, + -27.30772113165588, + -35.41301283581835, + -23.65959817854485, + -35.78377870310933, + -21.841555203858952, + -22.306188226155363, + -13.630396913476915, + -36.17097560976507, + -43.17286376802864, + -29.62591107903055, + -30.68817719213481, + -25.311093599618466, + -13.412346259713264, + -30.646092639404827, + -24.810349516064136, + -34.2501271463306, + -31.22676043141888, + -18.074230201627607, + -60.46248030522192, + -35.088746470043375, + -13.372459739965652, + -12.765879414843237, + -26.873659904443585, + -22.75223768267058, + -38.543022017159835, + -17.946947781400944, + -44.136896285871856, + -27.898234116931178, + -30.142030046673543, + -14.08483995032251, + -27.015432038825843, + -16.99205256104692, + -34.070573267765624, + -17.42702270888168, + -18.56982454880895, + -122.5144066545706, + -54.03599314037519, + -12.711802432376466, + -26.670587920606323, + -12.840955278982136, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -9.059040958901011, + -14.450393191416238, + -10.700889115485865, + -5.933199999999999, + -14.450393191416238, + -15.143540371976181, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -22.349591579627543, + -12.578591014514647, + -25.10169532585462, + -5.933199999999999, + -5.933199999999999, + -8.3568234213711, + -49.357259433080955, + -5.933199999999999, + -8.221882187825054, + -5.933199999999999, + -5.933199999999999, + -16.87401661278734, + -21.172333024350163, + -15.942048068193953, + -5.933199999999999, + -17.609821557641016, + -16.409034032950366, + -22.050510229482533, + -12.565598856220992, + -8.828182370453847, + -5.933199999999999, + -5.933199999999999, + -144.9795914535035, + -5.933199999999999, + -5.933199999999999, + -9.120092779015149, + -5.933199999999999, + -12.840955278982136, + -11.433285997854554, + -11.92466454710798, + -5.933199999999999, + -33.46989096164694, + -9.1446038100295, + -19.441225858216313, + -13.064098830296345, + -9.332399378999481, + -5.933199999999999, + -11.27233936106829, + -5.933199999999999, + -5.933199999999999, + -21.4635089860562, + -15.143540371976181, + -13.197630222920868, + -12.946315794639963, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -29.678076075343256, + -14.450393191416238, + -18.35494418200568, + -21.02167623377716, + -14.044928083308072, + -74.0707455313299, + -35.239798830867194, + -13.757246010856292, + -21.714823414337108, + -5.933199999999999, + -8.221882187825054, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -8.3568234213711, + -18.92729066241992, + -13.064098830296345, + -22.383172967611856, + -5.933199999999999, + -24.768184800727735, + -27.495795527684436, + -13.351780902748127, + -5.933199999999999, + -5.933199999999999, + -13.351780902748127, + -9.059040958901011, + -8.3568234213711, + -24.13545457400573, + -9.1446038100295, + -9.439757897319982, + -14.287004740062184, + -8.839091569554201, + -5.933199999999999, + -19.17015189596809, + -12.946315794639963, + -11.118188681241033, + -11.811335861800977, + -22.156656166616145, + -15.143540371976181, + -20.619115338816385, + -8.3568234213711, + -15.143540371976181, + -5.933199999999999, + -8.828182370453847, + -24.96259486853748, + -5.933199999999999, + -12.946315794639963, + -5.933199999999999, + -16.413652978806663, + -12.334740267773828, + -14.450393191416238, + -5.933199999999999, + -28.845722244633453, + -5.933199999999999, + -79.08493525995073, + -21.581292021712585, + -23.25264419167808, + -15.143540371976181, + -5.933199999999999, + -9.1446038100295, + -5.933199999999999, + -9.059040958901011, + -16.384523001936017, + -25.163560257623296, + -5.933199999999999, + -5.933199999999999, + -9.1446038100295, + -5.933199999999999, + -8.3568234213711, + -5.933199999999999, + -34.97594292299563, + -9.768261964292018, + -8.839091569554201, + -16.15690529630853, + -14.044928083308072, + -14.044928083308072, + -8.221882187825054, + -5.933199999999999, + -5.933199999999999, + -8.221882187825054, + -11.744983139108403, + -5.933199999999999, + -5.933199999999999, + -35.37150039681464, + -5.933199999999999, + -14.450393191416238, + -5.933199999999999, + -12.256072827227408, + -5.933199999999999, + -5.933199999999999, + -13.802452603694372, + -17.576234150317248, + -5.933199999999999, + -25.600538631437537, + -25.821819094112765, + -14.672287523330015, + -18.382704622121295, + -18.330433150991333, + -9.736368600516062, + -95.40057313755715, + -5.933199999999999, + -5.933199999999999, + -27.298919903190836, + -20.32741717158676, + -5.933199999999999, + -10.510564375650109, + -8.3568234213711, + -14.044928083308072, + -8.828182370453847, + -12.840955278982136, + -8.3568234213711, + -5.933199999999999, + -21.87358470672205, + -22.967586382832476, + -15.369939216011065, + -32.15014335290073, + -22.156656166616145, + -8.3568234213711, + -5.933199999999999, + -9.498093474332943, + -12.504483042360924, + -15.143540371976181, + -5.933199999999999, + -8.839091569554201, + -5.933199999999999, + -5.933199999999999, + -38.11520429834686, + -10.347749826379442, + -28.726619445327728, + -5.933199999999999, + -15.143540371976181, + -5.933199999999999, + -5.933199999999999, + -14.768190887772642, + -44.831177212030816, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -16.87401661278734, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -15.169268520548913, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -32.17792675480866, + -32.19894612203273, + -5.933199999999999, + -5.933199999999999, + -41.63691564591665, + -8.3568234213711, + -22.051295650958316, + -9.95058352108597, + -22.7599626431763, + -8.3568234213711, + -12.709497284362444, + -5.933199999999999, + -10.347749826379442, + -5.933199999999999, + -20.888144841152638, + -9.439757897319982, + -8.828182370453847, + -9.1446038100295, + -17.52368017029007, + -8.221882187825054, + -15.143540371976181, + -5.933199999999999, + -15.605575831572741, + -5.933199999999999, + -15.143540371976181, + -5.933199999999999, + -5.933199999999999, + -39.746636590460696, + -9.059040958901011, + -5.933199999999999, + -15.143540371976181, + -13.351780902748127, + -19.87654392947416, + -23.23664299116109, + -9.059040958901011, + -12.74564509917781, + -24.353880743952363, + -5.933199999999999, + -17.444127462307556, + -15.143540371976181, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -21.175826913604418, + -5.933199999999999, + -5.933199999999999, + -24.353880743952363, + -11.860068527623472, + -5.933199999999999, + -5.933199999999999, + -14.450393191416238, + -15.651536668732014, + -5.933199999999999, + -15.143540371976181, + -5.933199999999999, + -12.578591014514645, + -5.933199999999999, + -8.3568234213711, + -19.995742170607038, + -5.933199999999999, + -12.310327027919966, + -12.862209559417074, + -5.933199999999999, + -5.933199999999999, + -24.696652782722104, + -5.933199999999999, + -5.933199999999999, + -13.534102459542082, + -14.044928083308072, + -5.933199999999999, + -15.143540371976181, + -8.839091569554201, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -12.74564509917781, + -8.828182370453847, + -32.01251693612458, + -5.933199999999999, + -11.92466454710798, + -13.351780902748127, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -16.87401661278734, + -21.358148470398373, + -5.933199999999999, + -5.933199999999999, + -24.10778599138032, + -55.46970457789738, + -13.976273860950156, + -59.92909811559724, + -19.616663073768315, + -15.333543630514429, + -32.9610180525858, + -50.38893539930159, + -14.339291647236077, + -23.03091415009297, + -38.80268352183311, + -50.06043095514994, + -26.06352143927873, + -32.06336428875046, + -33.61186187891719, + -26.50764444668995, + -23.11600223163302, + -52.09708084245109, + -36.45457887490764, + -41.75620582453458, + -64.84032246694403, + -21.87238254045306, + -41.45056189475862, + -20.825365430207697, + -66.69231172085115, + -34.006794583506405, + -14.834188564977673, + -10.877811481305052, + -67.38691480770044, + -47.35410527658341, + -43.26484578776842, + -41.41495764587096, + -22.09190873636722, + -22.811373004147544, + -62.79446003383334, + -25.330560117217267, + -33.47350534494717, + -44.65705297147196, + -38.50293314212463, + -46.89248837325298, + -65.37426634088703, + -21.46224722717131, + -27.983541052050498, + -36.923077017225054, + -26.8544047450008, + -20.619835023194547, + -52.56544101778219, + -39.13208268166043, + -28.58088420463291, + -14.87428181879438, + -69.39442069779199, + -51.455641693980255, + -31.474024319725693, + -59.50513475242642, + -24.199246447192788, + -23.016521330939874, + -29.585640616161644, + -57.36903103715046, + -61.74206489860981, + -17.377396708743127, + -30.488481836520812, + -37.48530665876915, + -40.40461708460952, + -27.872270356660643, + -44.125682391644816, + -36.190846245408046, + -22.409147611606468, + -85.0440445310656, + -46.26535985367675, + -35.988431135362106, + -36.21428276713527, + -52.445097946394824, + -44.65964763140261, + -22.935353985633128, + -23.304034377309197, + -43.83793596623671, + -25.664075834142626, + -28.11967254423396, + -20.373226369298585, + -89.09733359043813, + -188.17244492705362, + -35.821880937771546, + -60.98099054417012, + -38.91210115043477, + -49.16024542918207, + -26.210719944791613, + -29.862276282568157, + -25.575380126939265, + -28.600300526651317, + -46.33688941177696, + -27.339265207183363, + -26.254032672658465, + -26.971990551775516, + -21.178583475622837, + -35.80037019078982, + -36.65512244056959, + -22.923971668815387, + -18.308140340259413, + -44.15444936281104, + -273.8568458373845, + -29.062030484320236, + -34.34548220492986, + -27.876383172963934, + -28.05497407423364, + -25.977925904814935, + -34.98269640419987, + -46.6891341226107, + -27.706242015709392, + -72.233787369582, + -52.733839621103556, + -22.63748022848413, + -75.71352382493843, + -29.415031997203073, + -41.349560034265245, + -29.231980949190866, + -53.38596992582337, + -26.701452620286375, + -51.9716269689043, + -22.40011645826569, + -84.24930221675392, + -34.59766034691599, + -99.83317900638933, + -44.526269013439325, + -32.38376370567639, + -39.23728311724357, + -32.57008887814993, + -13.619483914130015, + -22.808867651565766, + -23.098833932334525, + -16.251516430349668, + -15.124130307324767, + -12.350399075117583, + -29.37777036057728, + -29.459910849793545, + -50.251028442534086, + -28.577950296949478, + -34.779437041410276, + -41.88127043121849, + -52.273539455817584, + -65.61094326791527, + -32.59152407397109, + -33.97963150935833, + -32.023147583883, + -17.584668254654435, + -36.34325023082599, + -28.13163827991043, + -54.190526255153564, + -21.49349940793252, + -43.680630537384125, + -40.84464860264287, + -31.416553712765904, + -61.27550190322641, + -37.64961556588952, + -27.6020557031982, + -21.027596947677864, + -30.165058278496307, + -47.51438599471836, + -20.523999403683643, + -96.13033129346242, + -22.927753548905415, + -20.703037076139097, + -34.46528740997105, + -105.26253401955196, + -21.654662527013866, + -21.149777478494933, + -15.271697147314901, + -19.129053898561978, + -28.283856968786363, + -58.28827154902439, + -22.64179929784453, + -13.246120349414294, + -23.899409822674478, + -14.873870232135296, + -126.10221737290271, + -36.593908944358645, + -52.19487769845505, + -13.491473733053667, + -37.046840152535765, + -17.893474214891462, + -17.10229712271112, + -47.04850301373534, + -23.195803275388045, + -39.61840279821214, + -13.773664884528397, + -42.700842102713615, + -26.28257290176471, + -36.68608834156248, + -33.72029744330895, + -15.825475904396676, + -24.148136750529638, + -14.244893596317784, + -50.22861495620045, + -42.42278937959079, + -30.303969017836028, + -14.376470790724309, + -17.915287271262457, + -32.907293497424476, + -49.94273020277079, + -102.68557859824195, + -15.612902521737084, + -50.803392740198056, + -29.766852308886858, + -38.52835622041936, + -123.21518355689702, + -21.268307074417464, + -46.005528744044724, + -25.03931147380856, + -19.64596243556086, + -26.371856589883127, + -28.75131359072458, + -36.9374563317121, + -31.102961567144494, + -34.953698229941224, + -9.413619619908012, + -13.166925284127645, + -29.542067847075355, + -43.23782789023195, + -41.3321418724714, + -53.947111285869234, + -45.754050569684196, + -20.309616363847702, + -14.043061471157449, + -29.378662772970234, + -30.934820367611543, + -22.89044339784234, + -42.49366495352504, + -28.551355626865668, + -13.777326968193048, + -45.721429320920606, + -41.31357070115193, + -22.425062733254926, + -57.193921311526196, + -17.16811977393703, + -46.5924849169499, + -52.910573093941885, + -25.22036323461719, + -15.968218908156535, + -30.66410224794363, + -49.337150946391276, + -16.62651772408643, + -31.292698482656267, + -45.133814899958224, + -55.79255542341133, + -20.875955784809744, + -13.603535093486041, + -21.917602312293525, + -22.458895147883272, + -37.252176916210296, + -17.580747414689853, + -28.735464722907086, + -26.213249973052, + -32.994618219926096, + -30.102391313949614, + -34.85425221507585, + -43.146182098226255, + -63.48918797034241, + -28.67381178523994, + -20.212528012383302, + -14.27760401927237, + -55.40425618535554, + -20.90164506364586, + -28.488271985334087, + -43.605245094397624, + -25.995444793412897, + -41.39530646999747, + -21.698811461310875, + -21.781581549804457, + -38.58409886442371, + -36.734174765641626, + -19.71217978136472, + -26.891332313875804, + -25.149085641421724, + -112.93930247295043, + -26.480708157956013, + -13.524968589206555, + -20.045188355550376, + -38.76445006104609, + -15.289434445797713, + -32.8985299735204, + -140.27054584186186, + -20.06552174964199, + -13.065298978325554, + -59.527101600789294, + -25.421061901034633, + -47.98191148284671, + -30.49667516174372, + -18.749838761484092, + -56.87195217142992, + -19.337486060918057, + -14.980972894425827, + -28.44345126420679, + -61.27402065435061, + -21.092278527192388, + -40.359300760723734, + -17.767536305433584, + -63.7254336626595, + -30.74329638009426, + -28.107655242822695, + -16.208157145553493, + -12.358341449112896, + -18.948625606268145, + -12.98957130331092, + -5.933199999999999, + -23.255268455284252, + -5.933199999999999, + -17.432222559801236, + -5.933199999999999, + -15.957725880913184, + -75.38007885131366, + -9.439757897319982, + -5.933199999999999, + -51.110649862454906, + -22.007116099346568, + -5.933199999999999, + -16.29026346662976, + -13.004651371652926, + -5.933199999999999, + -5.933199999999999, + -50.593276641660246, + -12.578591014514647, + -5.933199999999999, + -5.933199999999999, + -22.05129565095832, + -41.649136649934945, + -10.780446842742203, + -5.933199999999999, + -12.74564509917781, + -8.828182370453847, + -15.143540371976181, + -5.933199999999999, + -5.933199999999999, + -18.759037059868948, + -15.143540371976181, + -114.20553307120113, + -5.933199999999999, + -17.26380390817627, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -8.3568234213711, + -8.3568234213711, + -19.083566839814196, + -5.933199999999999, + -15.143540371976181, + -14.450393191416238, + -5.933199999999999, + -33.03520977135542, + -9.059040958901011, + -5.933199999999999, + -13.064098830296345, + -19.840168168453108, + -5.933199999999999, + -8.839091569554201, + -5.933199999999999, + -14.044928083308072, + -8.828182370453847, + -9.1446038100295, + -15.143540371976181, + -5.933199999999999, + -9.120092779015149, + -13.351780902748127, + -5.933199999999999, + -5.933199999999999, + -9.1446038100295, + -13.197630222920868, + -5.933199999999999, + -5.933199999999999, + -62.8291526839633, + -30.568488842374556, + -9.736368600516062, + -14.450393191416238, + -5.933199999999999, + -28.855307320771676, + -14.044928083308072, + -5.933199999999999, + -18.85406357120404, + -13.854307723699423, + -22.820165107234505, + -5.933199999999999, + -9.1446038100295, + -5.933199999999999, + -13.209572679596835, + -16.052359089011638, + -8.3568234213711, + -5.933199999999999, + -23.14971676590129, + -5.933199999999999, + -12.840955278982136, + -54.30768966019248, + -21.02167623377716, + -5.933199999999999, + -9.95058352108597, + -5.933199999999999, + -12.391014060773454, + -13.757246010856292, + -5.933199999999999, + -13.534102459542082, + -5.933199999999999, + -5.933199999999999, + -11.811335861800977, + -18.892174926050274, + -15.143540371976181, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -13.204070264113305, + -15.143540371976181, + -5.933199999999999, + -9.059040958901011, + -5.933199999999999, + -8.828182370453847, + -34.36150816083976, + -30.268384249924217, + -15.630324001261934, + -5.933199999999999, + -5.933199999999999, + -9.1446038100295, + -5.933199999999999, + -50.428611591657706, + -15.550005980417929, + -5.933199999999999, + -5.933199999999999, + -12.393075844786793, + -5.933199999999999, + -5.933199999999999, + -11.127773757379256, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -9.1446038100295, + -23.66073356339242, + -17.661797001445738, + -5.933199999999999, + -9.95058352108597, + -19.768998983241186, + -11.27233936106829, + -16.762523697253812, + -15.143540371976181, + -9.439757897319982, + -5.933199999999999, + -23.828487483337724, + -5.933199999999999, + -115.56056573811233, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -16.027848057997286, + -19.687427329547376, + -17.567163793347284, + -20.91897782982504, + -5.933199999999999, + -12.74564509917781, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -19.448605965513934, + -5.933199999999999, + -12.658633722188181, + -5.933199999999999, + -17.3691644238341, + -12.658633722188181, + -5.933199999999999, + -14.044928083308072, + -8.3568234213711, + -21.615498260066488, + -19.177731011378533, + -14.595667745855353, + -5.933199999999999, + -5.933199999999999, + -15.143540371976181, + -29.6521981105004, + -5.933199999999999, + -6.047264956287972, + -21.358148470398376, + -5.933199999999999, + -19.959431589279927, + -15.143540371976181, + -13.757246010856292, + -9.736368600516062, + -5.933199999999999, + -5.933199999999999, + -12.227381749453329, + -5.933199999999999, + -13.534102459542082, + -12.856475090640174, + -8.221882187825054, + -9.95058352108597, + -17.9363451893782, + -23.66073356339242, + -21.581292021712585, + -5.933199999999999, + -29.24963721553963, + -11.116864558278902, + -5.933199999999999, + -9.1446038100295, + -18.26938133087719, + -5.933199999999999, + -15.143540371976181, + -8.839091569554201, + -13.197630222920868, + -5.933199999999999, + -13.197630222920868, + -5.933199999999999, + -13.197630222920868, + -5.933199999999999, + -5.933199999999999, + -31.772461646700492, + -31.366996538592325, + -8.221882187825054, + -5.933199999999999, + -8.828182370453847, + -7.496231539619944, + -5.933199999999999, + -8.839091569554201, + -8.3568234213711, + -8.828182370453847, + -16.652228381310138, + -24.243807351366033, + -9.059040958901011, + -20.19499766059269, + -9.059040958901011, + -15.143540371976181, + -12.09901793425276, + -14.59900921574502, + -57.1261613252394, + -26.47414428015246, + -5.933199999999999, + -43.321937150252225, + -12.099017934252759, + -18.740752637564295, + -14.044928083308072, + -5.933199999999999, + -18.049431941530383, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -8.828182370453847, + -38.75093420542994, + -5.933199999999999, + -13.534102459542082, + -13.06298694866589, + -37.253100570042484, + -5.933199999999999, + -22.197478161136402, + -14.044928083308072, + -8.3568234213711, + -32.59103698592378, + -68.78224178623019, + -9.1446038100295, + -5.933199999999999, + -21.581292021712585, + -10.510564375650109, + -5.933199999999999, + -13.644408517592922, + -40.433063421412086, + -5.933199999999999, + -9.736368600516062, + -8.839091569554201, + -55.55522571284405, + -5.933199999999999, + -5.933199999999999, + -88.58727537811008, + -15.143540371976181, + -5.933199999999999, + -13.534102459542082, + -8.221882187825054, + -5.933199999999999, + -5.933199999999999, + -22.156656166616145, + -5.933199999999999, + -8.3568234213711, + -16.67779215082439, + -5.933199999999999, + -8.839091569554201, + -18.40063740966458, + -22.27443920227253, + -9.120092779015149, + -5.933199999999999, + -16.611351907261263, + -9.736368600516062, + -31.00130197796864, + -9.967390639402353, + -18.07958775924454, + -13.197630222920868, + -5.933199999999999, + -8.3568234213711, + -5.933199999999999, + -11.433285997854554, + -5.933199999999999, + -5.933199999999999, + -15.143540371976181, + -5.933199999999999, + -5.933199999999999, + -19.750045562286125, + -5.933199999999999, + -10.347749826379442, + -35.67816192673921, + -15.367209611440199, + -14.450393191416238, + -8.839091569554201, + -17.551485980628055, + -5.933199999999999, + -14.90208550089072, + -12.799246563475162, + -22.36127786690507, + -5.933199999999999, + -17.642140348896184, + -25.472593704327476, + -23.85692426912449, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -7.633109815598175, + -5.933199999999999, + -5.933199999999999, + -11.786775662157998, + -11.505954212249797, + -19.992404121207432, + -5.933199999999999, + -12.191885385663118, + -30.79163239368877, + -12.578591014514645, + -13.351780902748128, + -5.933199999999999, + -8.828182370453847, + -24.353880743952363, + -17.567163793347284, + -14.733950449291068, + -5.933199999999999, + -5.933199999999999, + -29.620649630376782, + -19.177731011378533, + -16.563184712777627, + -8.3568234213711, + -30.482898474540374, + -21.02167623377716, + -5.933199999999999, + -16.159532965487845, + -5.933199999999999, + -12.862209559417074, + -12.435490170873972, + -9.736368600516062, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -9.736368600516062, + -8.221882187825054, + -12.578591014514647, + -5.933199999999999, + -16.01994388209404, + -15.143540371976181, + -5.933199999999999, + -22.156656166616145, + -5.933199999999999, + -14.90302852650088, + -16.275502640325847, + -8.3568234213711, + -9.439757897319982, + -5.933199999999999, + -13.384554001710963, + -16.275502640325847, + -5.933199999999999, + -8.839091569554201, + -5.933199999999999, + -10.780446842742203, + -12.631350970969912, + -40.81681977056113, + -8.828182370453847, + -15.77540432411923, + -9.1446038100295, + -44.08389480788849, + -42.77884842369728, + -28.594407816352547, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -8.828182370453847, + -10.223559446148057, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -22.27443920227253, + -5.933199999999999, + -29.405338032568874, + -8.828182370453847, + -15.457155826454468, + -12.504483042360924, + -15.143540371976181, + -8.221882187825054, + -27.93608067811722, + -21.868974094164365, + -8.3568234213711, + -14.044928083308072, + -13.351780902748127, + -5.933199999999999, + -5.933199999999999, + -12.578591014514647, + -5.933199999999999, + -5.933199999999999, + -14.314666536394405, + -5.933199999999999, + -12.14780809842219, + -26.308629841674886, + -23.039834547040098, + -31.170772076629383, + -13.757246010856292, + -9.439757897319982, + -18.99104048138883, + -8.3568234213711, + -41.750898788875006, + -8.470888377659074, + -22.90779752664144, + -26.736298966582957, + -5.933199999999999, + -9.439757897319982, + -5.933199999999999, + -9.498093474332943, + -5.933199999999999, + -40.226025537053935, + -5.933199999999999, + -17.567163793347284, + -5.933199999999999, + -5.933199999999999, + -32.37257396129325, + -9.498093474332943, + -8.221882187825054, + -8.828182370453847, + -5.933199999999999, + -31.491411055886594, + -13.534102459542082, + -12.578591014514647, + -5.933199999999999, + -9.120092779015149, + -9.1446038100295, + -15.143540371976181, + -5.933199999999999, + -15.143540371976181, + -5.933199999999999, + -5.933199999999999, + -22.634799500222293, + -5.933199999999999, + -21.58129202171258, + -5.933199999999999, + -5.933199999999999, + -8.839091569554201, + -18.03852274243003, + -18.650098269296162, + -9.95058352108597, + -21.581292021712585, + -5.933199999999999, + -5.933199999999999, + -17.848096683824135, + -25.722699050619546, + -14.450393191416238, + -5.933199999999999, + -40.789430625696134, + -22.27443920227253, + -5.933199999999999, + -9.688219256618481, + -11.964932528455211, + -9.480579891840236, + -12.253168614080018, + -5.933199999999999, + -12.946315794639963, + -5.933199999999999, + -18.015286665749183, + -8.3568234213711, + -5.933199999999999, + -38.494625720021055, + -12.334740267773828, + -9.498093474332943, + -13.069129030567257, + -5.933199999999999, + -8.839091569554201, + -9.1446038100295, + -5.933199999999999, + -17.651920377949825, + -9.498093474332943, + -15.034327287002865, + -8.839091569554201, + -5.933199999999999, + -5.933199999999999, + -15.744837898906248, + -8.221882187825054, + -58.961878607905, + -5.933199999999999, + -9.1446038100295, + -24.69806262364363, + -5.933199999999999, + -18.47545612384608, + -5.933199999999999, + -21.520667399896148, + -13.534102459542082, + -9.498093474332943, + -5.933199999999999, + -5.933199999999999, + -15.945171897828718, + -5.933199999999999, + -36.55198521983336, + -20.770361805496254, + -12.09901793425276, + -9.768261964292018, + -31.400346518273878, + -13.757246010856292, + -26.736353556631204, + -12.504483042360924, + -18.740752637564295, + -12.74564509917781, + -5.933199999999999, + -9.1446038100295, + -5.933199999999999, + -13.064098830296345, + -9.1446038100295, + -9.439757897319982, + -8.839091569554201, + -5.933199999999999, + -19.61082167301429, + -14.762299652758882, + -9.439757897319982, + -8.828182370453847, + -8.3568234213711, + -5.933199999999999, + -9.95058352108597, + -5.933199999999999, + -269.33775436532585, + -5.933199999999999, + -13.242926497836045, + -8.3568234213711, + -16.87401661278734, + -5.933199999999999, + -11.262714990925303, + -12.946315794639963, + -9.498093474332943, + -33.82353797080642, + -28.0427601980663, + -13.757246010856292, + -5.933199999999999, + -12.64718286751916, + -15.143540371976181, + -5.933199999999999, + -14.450393191416238, + -5.933199999999999, + -20.683243548662922, + -8.221882187825054, + -16.333610271133125, + -27.965799156930174, + -34.9913374715687, + -5.933199999999999, + -38.78557744134046, + -12.631350970969912, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -8.221882187825054, + -12.512241633973112, + -5.933199999999999, + -15.143540371976181, + -31.441168512794135, + -24.339977838783376, + -13.069129030567257, + -23.39089728408623, + -5.933199999999999, + -11.262714990925303, + -14.659633837561454, + -5.933199999999999, + -29.12156985943823, + -50.283310891572185, + -5.933199999999999, + -22.156656166616145, + -5.933199999999999, + -8.3568234213711, + -5.933199999999999, + -13.534102459542082, + -72.57961652962922, + -8.828182370453847, + -5.933199999999999, + -10.056733236969277, + -5.933199999999999, + -20.616211125668997, + -16.739075379241292, + -47.78882828286959, + -8.3568234213711, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -11.454660917862245, + -5.933199999999999, + -5.933199999999999, + -24.787745326582225, + -5.933199999999999, + -12.946315794639963, + -5.933199999999999, + -17.567163793347284, + -9.059040958901011, + -5.933199999999999, + -9.768261964292018, + -15.264578700353237, + -13.697457154665258, + -5.933199999999999, + -21.17455474379068, + -24.604588143855548, + -40.25956825513024, + -31.559390163699863, + -25.687526490627178, + -26.890210112561967, + -31.661459422732392, + -12.969433900530461, + -34.06502327667323, + -39.12105978216363, + -23.195369084272617, + -38.95004004827708, + -15.582541521629452, + -23.22539717728723, + -10.83613789311411, + -50.363360494600265, + -32.06822317457548, + -23.7269884781461, + -25.11996153668752, + -42.88737809198, + -21.79391173690832, + -42.87390762552785, + -31.347754058189505, + -51.84687870935339, + -60.879826192842515, + -22.88462118595582, + -28.59925050187239, + -32.20691295816178, + -31.056545191536337, + -34.814681140050936, + -24.632657125126705, + -41.244938985972034, + -30.110516490860842, + -38.34703510014556, + -34.33543100368846, + -21.798116766746325, + -23.81954173495935, + -35.51781679644171, + -23.833978595484528, + -39.352074683604954, + -57.48571591286154, + -34.65638214731163, + -34.85401508664638, + -27.73833287887021, + -25.853581804403216, + -25.86049929950199, + -19.259055681985764, + -204.27408851441763, + -60.73745827070582, + -44.08245889821481, + -27.487518248924317, + -220.4250808935757, + -32.35288204068709, + -24.06992432617852, + -58.28558304764102, + -70.74268164286298, + -39.771909331630546, + -29.00819743968446, + -15.450538546696112, + -30.545388774449872, + -41.81116399109092, + -46.87053587981796, + -10.237903972444904, + -28.057197876714387, + -32.77041109901059, + -66.79968686735216, + -30.536910012071377, + -36.56993430623713, + -30.32466460944453, + -74.90553321879153, + -23.122317166114385, + -30.892136727335597, + -24.02054777149197, + -43.3956288068756, + -64.10135476071207, + -57.36592656261797, + -38.10282858617137, + -20.950982598263256, + -31.118198884529164, + -37.23796170084805, + -29.403335077852304, + -10.389381955855383, + -13.288653643008699, + -18.435713742544987, + -21.22404870003536, + -29.505813476588834, + -19.620743606604446, + -49.48679312313426, + -22.34924653136311, + -30.29158019325324, + -46.04325368467189, + -35.95978468599002, + -38.425336212798776, + -8.292561340000201, + -45.8612602779653, + -25.80742657291867, + -29.367917643540355, + -14.897927816061603, + -34.30135306372698, + -31.021736417895372, + -5.933199999999999, + -10.223559446148057, + -18.049431941530383, + -23.154488940656595, + -14.450393191416238, + -15.143540371976181, + -48.01143762497467, + -24.3694005556104, + -22.744442831518263, + -5.933199999999999, + -5.933199999999999, + -10.223559446148057, + -9.736368600516062, + -21.788931386490827, + -15.143540371976181, + -12.658633722188181, + -5.933199999999999, + -9.736368600516062, + -8.3568234213711, + -13.785645485377989, + -29.28755499691249, + -18.670386694573075, + -8.221882187825054, + -14.450393191416238, + -8.828182370453847, + -15.514604053367014, + -25.90925643681291, + -5.933199999999999, + -5.933199999999999, + -15.143540371976181, + -5.933199999999999, + -28.594407816352547, + -5.933199999999999, + -14.648234559868229, + -11.744983139108403, + -5.933199999999999, + -70.06459757844866, + -13.197630222920868, + -5.933199999999999, + -5.933199999999999, + -14.15675389849033, + -5.933199999999999, + -11.560021433520072, + -13.473590785280452, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -12.74564509917781, + -14.849005699808707, + -10.654904002244042, + -16.159176220575063, + -18.573137228160036, + -9.95058352108597, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -12.67415353384622, + -14.659633837561454, + -24.770027387078315, + -9.059040958901011, + -5.933199999999999, + -5.933199999999999, + -15.143540371976181, + -5.933199999999999, + -12.393075844786793, + -9.736368600516062, + -5.933199999999999, + -5.933199999999999, + -25.73220693542308, + -20.966363172346767, + -22.562121274724312, + -5.933199999999999, + -15.969990399850548, + -11.27233936106829, + -9.571386339798417, + -13.333155438624962, + -15.650872106487917, + -5.933199999999999, + -5.933199999999999, + -19.177731011378533, + -12.310327027919966, + -5.933199999999999, + -5.933199999999999, + -11.723164740907695, + -5.933199999999999, + -5.933199999999999, + -13.064098830296345, + -13.064098830296345, + -13.204070264113305, + -18.808703299472803, + -5.933199999999999, + -19.006773213234894, + -8.3568234213711, + -5.933199999999999, + -18.588815040879265, + -22.27443920227253, + -15.143540371976181, + -9.736368600516062, + -5.933199999999999, + -13.757246010856292, + -5.933199999999999, + -15.143540371976181, + -10.645505609196155, + -8.221882187825054, + -12.942190980063014, + -13.416455945204309, + -8.828182370453847, + -15.3527810181214, + -18.877673710274497, + -15.963955561166454, + -5.933199999999999, + -5.933199999999999, + -8.828182370453847, + -14.450393191416238, + -9.1446038100295, + -5.933199999999999, + -8.3568234213711, + -29.220415694074863, + -12.74564509917781, + -13.351780902748127, + -5.933199999999999, + -8.839091569554201, + -28.579463786675145, + -5.933199999999999, + -22.19754760799222, + -13.705626519676699, + -5.933199999999999, + -13.534102459542082, + -5.933199999999999, + -19.843021237435515, + -11.954023329354857, + -8.3568234213711, + -5.933199999999999, + -5.933199999999999, + -11.35935073805792, + -5.933199999999999, + -9.498093474332943, + -21.955985471153994, + -5.933199999999999, + -5.933199999999999, + -8.3568234213711, + -5.933199999999999, + -9.768261964292018, + -13.064098830296345, + -19.160923893062154, + -16.8830869697573, + -5.933199999999999, + -14.450393191416238, + -15.369939216011065, + -13.351780902748127, + -61.28895880213187, + -9.1446038100295, + -15.143540371976181, + -13.534102459542082, + -12.658633722188181, + -5.933199999999999, + -10.347749826379442, + -11.559082985111669, + -5.933199999999999, + -14.450393191416238, + -15.487722251667448, + -13.534102459542082, + -15.143540371976181, + -5.933199999999999, + -7.633109815598175, + -5.933199999999999, + -22.156656166616145, + -5.933199999999999, + -17.567163793347284, + -14.450393191416238, + -34.96078956622375, + -8.3568234213711, + -5.933199999999999, + -5.933199999999999, + -12.578591014514647, + -22.967586382832476, + -17.491974239271332, + -5.933199999999999, + -10.700889115485865, + -5.933199999999999, + -5.933199999999999, + -26.314295579210558, + -5.933199999999999, + -14.450393191416238, + -5.933199999999999, + -14.450393191416238, + -24.483700522649684, + -5.933199999999999, + -5.933199999999999, + -9.498093474332943, + -12.840955278982136, + -12.310327027919966, + -18.494695801853474, + -5.933199999999999, + -21.095784205930883, + -15.143540371976181, + -15.143540371976181, + -5.933199999999999, + -31.01908992434545, + -53.36849906160756, + -5.933199999999999, + -5.933199999999999, + -12.862209559417074, + -8.839091569554201, + -5.933199999999999, + -33.79969031693339, + -13.771346568097165, + -5.933199999999999, + -9.967390639402353, + -13.534102459542082, + -5.933199999999999, + -110.25481774009678, + -9.95058352108597, + -5.933199999999999, + -5.933199999999999, + -24.367574071084366, + -5.933199999999999, + -9.439757897319982, + -32.493493660570095, + -23.828487483337724, + -9.768261964292018, + -17.08148235138232, + -23.66073356339242, + -15.046961306638622, + -11.27233936106829, + -13.534102459542082, + -5.933199999999999, + -15.957725880913184, + -25.949415751217472, + -5.933199999999999, + -5.933199999999999, + -9.059040958901011, + -14.044928083308072, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -12.709497284362444, + -5.933199999999999, + -30.632382238316808, + -5.933199999999999, + -5.933199999999999, + -28.71722105227984, + -12.65116170734948, + -22.14452816899739, + -12.253168614080018, + -15.143540371976181, + -5.933199999999999, + -14.044928083308072, + -5.933199999999999, + -8.221882187825054, + -12.435490170873972, + -19.990787214718384, + -5.933199999999999, + -8.3568234213711, + -5.933199999999999, + -24.91718310150468, + -9.736368600516062, + -5.933199999999999, + -8.3568234213711, + -5.933199999999999, + -5.933199999999999, + -18.650098269296162, + -17.567163793347284, + -5.933199999999999, + -8.828182370453847, + -5.933199999999999, + -12.393075844786793, + -15.49825486742189, + -14.313732976166172, + -14.23495928317208, + -17.917501758416552, + -23.760761124564322, + -5.933199999999999, + -5.933199999999999, + -26.39718323901633, + -13.534102459542082, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -20.542243979757355, + -5.933199999999999, + -15.143540371976181, + -10.510564375650109, + -5.933199999999999, + -131.12175846838477, + -11.92466454710798, + -11.742342990314027, + -8.221882187825054, + -13.757246010856292, + -31.483667692618255, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -18.932838919509337, + -26.041365437150585, + -48.92920695028698, + -22.808015359898395, + -26.453985357286065, + -21.29479029408891, + -18.107953167515774, + -41.57155824809735, + -49.01655356690349, + -25.95082219696692, + -43.44160267738254, + -30.369690599491445, + -59.26879666223474, + -32.89978364962438, + -37.50446504381853, + -38.406770839894406, + -26.563615375849942, + -22.235800256837805, + -29.904656342710414, + -15.594895746952368, + -42.52886481896384, + -27.166135139056543, + -28.275876497041217, + -30.12314642762939, + -35.77911756882291, + -33.6203447640426, + -39.082481283709846, + -21.443662360347545, + -42.725777506618776, + -20.426383834530576, + -9.788682906329104, + -50.31879294730889, + -9.30869814209068, + -49.63249865002972, + -34.70846173612446, + -38.77626046945164, + -34.30502459182459, + -19.297114072885883, + -31.729028956354867, + -21.420088693919595, + -24.89565576898683, + -33.27330255525446, + -24.232322537535335, + -14.78640569741605, + -15.46244365865513, + -17.93085836264426, + -22.572461438899083, + -113.43380471335315, + -23.548975866403648, + -22.585036334042655, + -18.254096776768822, + -33.525639277334065, + -34.183431706035364, + -36.118895024841976, + -18.966098922889746, + -33.37511847729998, + -25.07277647234197, + -30.440226663191464, + -26.03692787862495, + -14.427560523470833, + -37.810857080506246, + -54.76207460884739, + -39.29698587598763, + -24.906843624035403, + -13.658133842999037, + -45.84934840125507, + -70.98145095229525, + -73.19706813815104, + -29.51996572530631, + -29.276450866145726, + -46.84088946402382, + -39.63060486471919, + -24.22770071003157, + -22.4348088590975, + -22.40576773991872, + -30.397680152590556, + -22.606537525201805, + -20.49435056133379, + -31.87323916552313, + -46.835070490596316, + -41.82363564495613, + -34.37448847609754, + -21.913233748590187, + -15.283446595343559, + -50.6827569437382, + -19.070648486322824, + -41.25108258171581, + -34.242609273116166, + -42.84578639798126, + -52.45906146951644, + -36.15031154617458, + -55.22042485952686, + -41.916393646280746, + -45.935312236444226, + -28.309765458202463, + -8.1942911185674, + -23.321455413611535, + -24.57862549125949, + -30.24064065632252, + -26.672712709443072, + -18.02108769014867, + -14.547092240811686, + -13.882275926084773, + -10.893347973977958, + -21.190413440510852, + -29.089489570391816, + -22.80641528089945, + -19.82659002869049, + -29.17039507260019, + -26.12770262327316, + -22.13184814914916, + -11.732681452549956, + -78.02125369619108, + -17.320328961969103, + -25.460447061014992, + -32.71264536019004, + -10.732128034693053, + -25.846898430265558, + -19.96463502336307, + -8.063492714798945, + -45.04705660306027, + -33.62354989848077, + -457.33686301962194, + -44.5910798839548, + -67.40516145865766, + -22.7627155335446, + -43.97468837108708, + -23.586728646527874, + -44.559780236176316, + -35.432870784794304, + -17.108361293274637, + -21.75578851215733, + -21.877821819324293, + -18.30801155553808, + -56.975986653287215, + -33.864477841407336, + -59.619440831327964, + -24.52402838071108, + -20.085525281332686, + -17.395469804559255, + -25.234371692743927, + -28.080378570525216, + -40.95613239628204, + -22.252372991215058, + -21.540076102962285, + -36.84224501244643, + -17.44846628651888, + -32.601465343823634, + -44.26950380360263, + -29.695174018963996, + -31.280738684931865, + -18.90898639951982, + -26.918118952571305, + -101.99312063301727, + -29.953088178395163, + -41.706255631358715, + -41.903389444382896, + -44.76626302557585, + -27.24011185446696, + -65.38630618308261, + -27.684404100175847, + -71.98052083793556, + -32.766440367322936, + -36.53046805135217, + -15.731482540620231, + -38.015560049099435, + -91.65290900746776, + -18.791298531050458, + -17.672930629307267, + -37.32390051256732, + -26.995520186268266, + -37.12954009648246, + -26.1717419048891, + -11.258520245723695, + -44.69318178661484, + -70.10118005181715, + -24.60579711470034, + -26.23109252528695, + -127.1819442691856, + -29.275146028932006, + -27.06262560310158, + -50.763268058033944, + -25.928715867707798, + -25.400327159936023, + -62.01852601331247, + -18.480519356516496, + -34.64639826276332, + -108.29003486070802, + -12.323923881613105, + -30.8983584368401, + -27.531223908178763, + -34.03087758372837, + -22.15774226030495, + -24.93656300850349, + -24.405070666689344, + -28.541741407437993, + -25.49149538461821, + -55.38133393015126, + -21.702787832944345, + -34.571691229051204, + -21.828131461651207, + -5.933199999999999, + -8.828182370453847, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -21.463508986056198, + -5.933199999999999, + -11.532622459331957, + -9.967390639402353, + -5.933199999999999, + -5.933199999999999, + -166.63565468008298, + -33.06891530382059, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -14.044928083308072, + -14.450393191416238, + -8.828182370453847, + -8.3568234213711, + -9.059040958901011, + -15.143540371976181, + -23.255268455284252, + -5.933199999999999, + -9.967390639402353, + -5.933199999999999, + -8.221882187825054, + -5.933199999999999, + -9.120092779015149, + -16.659943418443092, + -29.49679564305771, + -5.933199999999999, + -25.096218168703082, + -22.967586382832472, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -14.044928083308072, + -18.797052682252826, + -9.1446038100295, + -5.933199999999999, + -10.347749826379442, + -5.933199999999999, + -12.74564509917781, + -5.933199999999999, + -8.221882187825054, + -5.933199999999999, + -8.828182370453847, + -39.51074289059599, + -13.757246010856292, + -18.46777671250221, + -5.933199999999999, + -20.888144841152638, + -28.961836912789185, + -8.828182370453847, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -18.015286665749183, + -28.82669374778129, + -16.792739903826984, + -5.933199999999999, + -21.30935830622894, + -18.484583830818593, + -9.498093474332943, + -5.933199999999999, + -8.3568234213711, + -25.510226765250607, + -9.439757897319982, + -5.933199999999999, + -10.518567558691911, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -27.70058994033045, + -5.933199999999999, + -9.1446038100295, + -5.933199999999999, + -19.183396748914213, + -10.518567558691911, + -5.933199999999999, + -5.933199999999999, + -34.103446214216234, + -10.780446842742203, + -15.86256551737898, + -20.462060445841736, + -5.933199999999999, + -5.933199999999999, + -9.120092779015149, + -11.811335861800977, + -25.078640910745868, + -5.933199999999999, + -14.75505089807732, + -12.840955278982136, + -5.933199999999999, + -16.939910453761918, + -13.197630222920868, + -9.1446038100295, + -18.30179157502795, + -11.92466454710798, + -8.3568234213711, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -11.742342990314027, + -38.90336047699684, + -5.933199999999999, + -5.933199999999999, + -19.671749516828143, + -5.933199999999999, + -19.229916764549106, + -8.828182370453847, + -5.933199999999999, + -12.946315794639963, + -5.933199999999999, + -9.736368600516062, + -22.981431789654525, + -8.828182370453847, + -5.933199999999999, + -30.79163239368877, + -20.206183946241605, + -11.61717984736002, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -11.744983139108403, + -17.609821557641016, + -8.828182370453847, + -15.165427139384358, + -5.933199999999999, + -9.768261964292018, + -29.487171272914722, + -46.49530832129555, + -11.786775662157998, + -5.933199999999999, + -24.353880743952363, + -8.828182370453847, + -8.221882187825054, + -5.933199999999999, + -5.933199999999999, + -7.633109815598175, + -16.468551504679173, + -9.120092779015149, + -32.556401706069614, + -27.289459094686606, + -10.510564375650109, + -12.93418779702121, + -11.965486541628238, + -5.933199999999999, + -13.197630222920868, + -5.933199999999999, + -16.439994029096283, + -8.221882187825054, + -5.933199999999999, + -5.933199999999999, + -8.3568234213711, + -16.092612593374717, + -5.933199999999999, + -10.645505609196155, + -11.347723146726064, + -8.828182370453847, + -5.933199999999999, + -5.933199999999999, + -9.967390639402353, + -5.933199999999999, + -9.571386339798417, + -22.156656166616145, + -13.197630222920868, + -28.882089888804327, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -13.004651371652926, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -19.95691007960108, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -11.347723146726064, + -13.757246010856292, + -9.967390639402353, + -5.933199999999999, + -17.432222559801236, + -5.933199999999999, + -9.498093474332943, + -9.95058352108597, + -5.933199999999999, + -14.450393191416238, + -14.044928083308072, + -12.578591014514647, + -9.059040958901011, + -5.933199999999999, + -15.143540371976181, + -25.480892507142173, + -13.534102459542082, + -20.346547558719895, + -17.385473732100046, + -22.38446809442311, + -33.707816346074516, + -17.96477702363997, + -26.11993248394961, + -18.749855042892705, + -27.498906678216457, + -18.041129627122636, + -45.528191298129215, + -26.643972078153467, + -17.0465707773417, + -121.74721813221399, + -95.51024627410864, + -13.394623581706051, + -29.8854706164889, + -30.276701463160798, + -48.54588753366208, + -134.34170590530135, + -14.660852871271041, + -22.012143111505786, + -28.08638300638681, + -21.481469397651278, + -35.76763862037614, + -27.69548276186734, + -48.049691357847784, + -13.038239545888471, + -21.356186849244814, + -33.65208162024862, + -36.665868220083546, + -56.444875436004665, + -46.818988428755155, + -29.567954125935195, + -29.81567373801181, + -17.94591968643559, + -22.29239262778781, + -65.09964268804461, + -44.56319934767889, + -15.44688334650814, + -20.68921869162969, + -45.64446553478484, + -23.79125926293996, + -70.87598734622826, + -30.881131147960367, + -59.420589652903544, + -35.61003724908486, + -19.789353110417935, + -22.009078837629563, + -21.28525069587299, + -27.142840604533014, + -146.2035683668895, + -45.90426086241208, + -12.790966166635629, + -20.747080453394457, + -8.096020897134597, + -39.69770447219458, + -45.0984185236369, + -38.049748777866114, + -32.36199232283636, + -32.15994807337857, + -31.999792732648725, + -23.772718072944194, + -12.487399526518141, + -24.453723068090355, + -34.39582998809389, + -26.75142228687916, + -295.5174130106854, + -58.69994978199167, + -21.91061658911904, + -22.275525079854763, + -42.46111906826146, + -20.65621852906524, + -23.003122833337613, + -14.940238155312747, + -57.50652627576651, + -62.108413556863006, + -35.42096910859487, + -41.67963001782765, + -24.83553025532619, + -338.31920263159793, + -59.932961782852644, + -24.325294359950743, + -29.74972436701378, + -25.176506594646792, + -16.68664329309256, + -15.527670589173225, + -30.34133879213929, + -302.7117215153468, + -26.086073315513953, + -17.227282985757505, + -32.43362318883432, + -23.347350100444487, + -47.26988341866292, + -42.829179577909976, + -157.85673071286124, + -26.68034048825735, + -27.379602116329483, + -31.524463802686746, + -46.42070459067382, + -45.1360484945897, + -34.44151411105534, + -17.567163793347284, + -9.498093474332943, + -5.933199999999999, + -21.868974094164365, + -9.768261964292018, + -13.351780902748127, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -14.044928083308072, + -8.221882187825054, + -13.351780902748127, + -5.933199999999999, + -29.38003584970666, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -11.61717984736002, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -41.88839349478496, + -14.897540038519045, + -15.143540371976181, + -17.51333421466368, + -5.933199999999999, + -28.21711358521108, + -15.48184857896001, + -18.10785949803835, + -5.933199999999999, + -26.345311408309485, + -17.26380390817627, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -17.618620090492747, + -20.473055362901484, + -8.828182370453847, + -16.87401661278734, + -9.498093474332943, + -9.413440589002608, + -21.868974094164365, + -5.933199999999999, + -22.40797059489705, + -17.828446475892544, + -5.933199999999999, + -10.654904002244042, + -5.933199999999999, + -28.98394996777505, + -14.450393191416238, + -55.45159822377576, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -8.839091569554201, + -14.044928083308072, + -10.510564375650109, + -14.450393191416238, + -19.566389001170318, + -39.1320506323184, + -5.933199999999999, + -8.3568234213711, + -25.189744226713906, + -12.658633722188181, + -11.744983139108403, + -8.221882187825054, + -19.64048864002543, + -20.95268336229021, + -5.933199999999999, + -13.757246010856292, + -12.840955278982136, + -15.143540371976181, + -16.739075379241292, + -14.450393191416238, + -19.177731011378533, + -31.366996538592325, + -12.74564509917781, + -19.56865239404586, + -12.039586180483347, + -8.3568234213711, + -9.498093474332943, + -12.256072827227408, + -5.933199999999999, + -8.828182370453847, + -27.832973939514606, + -11.262714990925303, + -5.933199999999999, + -21.581292021712585, + -5.933199999999999, + -5.933199999999999, + -9.059040958901011, + -20.205224779748207, + -5.933199999999999, + -5.933199999999999, + -8.221882187825054, + -42.696199927953074, + -26.330043936178697, + -21.116379454961, + -26.202734064677834, + -20.93063845007241, + -18.720318610482533, + -55.26720145372616, + -11.361307133172115, + -24.41411893505811, + -87.21744848781672, + -11.592766663539898, + -55.82920961442218, + -30.722373902238235, + -24.742180255957567, + -19.927732067691835, + -32.991352747754966, + -23.552238988032144, + -31.324487438192893, + -9.299894898841561, + -22.31425132034478, + -30.706592420423686, + -28.01044622837249, + -18.47354229363595, + -34.57579326176095, + -13.5855895084335, + -32.198176206517715, + -45.84535847695584, + -21.93077932405253, + -29.223660884850993, + -13.382760181541897, + -19.83906109010137, + -14.778188361162398, + -36.390032138665546, + -81.76834003278304, + -27.548772382652764, + -27.98023293896093, + -38.83285792108953, + -48.04051153110469, + -23.26708768021914, + -34.85233861808838, + -33.44415683899313, + -24.61831221912295, + -60.58958034311123, + -37.67825796459493, + -27.26053268012844, + -43.61406890101532, + -52.70440346892087, + -15.87662869068544, + -30.902774877590687, + -27.448311256603475, + -21.961176026117073, + -29.805568465566424, + -57.38561280685432, + -13.619956827234224, + -36.86163956537626, + -31.85246774927134, + -28.35629683486346, + -17.075845091411924, + -133.54926316487524, + -22.113138782663956, + -56.06624022242818, + -13.895847788888878, + -21.1530427781179, + -36.23019930023844, + -38.929638961557146, + -32.81767729825878, + -37.90585628493129, + -32.06920608679673, + -22.60669616824873, + -135.7316295144771, + -43.49542668790097, + -36.643066076221785, + -43.02255105695773, + -21.886332261360064, + -21.830316917084502, + -22.224489395512386, + -22.76256566316011, + -34.262064079351866, + -29.724779260381165, + -27.612142362169866, + -39.037095591305416, + -40.88266116726919, + -27.708649394785503, + -41.0875264028998, + -46.77139847429993, + -41.749108048676625, + -25.20143539086037, + -13.188530946920405, + -39.31374279881848, + -26.10464330501951, + -35.2270266729616, + -14.685522769806063, + -26.198166656420312, + -11.08839527181878, + -36.521242426928154, + -58.71966720447057, + -17.668040308923366, + -25.602746357663687, + -63.73471098222529, + -20.016416823856634, + -24.91942857903291, + -15.275353616841892, + -57.684782006940665, + -26.34858570296894, + -28.392286567702968, + -39.858385285261164, + -14.624772393854533, + -32.60658418220274, + -34.85252519871216, + -52.04392589919675, + -52.18572898083703, + -29.249830854104758, + -32.51823106509276, + -26.596306858722393, + -25.41465128005061, + -34.63590604592146, + -19.73266706326022, + -32.5884984915581, + -28.27355178688285, + -118.73413391948634, + -26.044539634945416, + -17.772422998688455, + -39.04138442177132, + -29.41378808395202, + -38.91910968963088, + -34.749186025045944, + -43.273622450449565, + -55.68986427084323, + -78.32769553190452, + -20.58720692830493, + -32.486716492915534, + -31.495290761297788, + -25.44412515490368, + -27.816141231987746, + -107.67001511294724, + -34.6600089348927, + -15.765327194501705, + -12.935855329947223, + -238.97890873835271, + -20.115960793070236, + -33.54993555478539, + -40.89528746447261, + -25.38612730774429, + -50.386028739439624, + -25.507736144667994, + -44.6202641519168, + -44.589737549431156, + -85.17209506312243, + -37.870864105352005, + -45.12601453926243, + -24.47894183840177, + -50.90133627225653, + -32.41661705533086, + -15.295209250298726, + -19.78535773175396, + -138.8427482640344, + -28.8054724397571, + -26.423742855365145, + -24.60399719041785, + -19.493973045077198, + -31.531772545991174, + -55.94124449317485, + -17.546201805782463, + -22.030670369626872, + -27.01006827183923, + -30.237294172573172, + -41.06542632519295, + -23.51871896841798, + -42.8666807390092, + -33.805356725737646, + -15.323332749143352, + -26.63595212503599, + -44.737311703486235, + -30.745508674319964, + -33.12743983178456, + -93.60748877031443, + -25.348265657345237, + -29.637925995791853, + -54.61832336844115, + -28.13748461426597, + -21.834781877022667, + -21.486915002336396, + -36.92020686727783, + -50.589957004153725, + -14.817214072020358, + -31.352863141843212, + -56.163594018787485, + -91.3896827082234, + -38.23657838344898, + -10.2596014759891, + -42.885894371297205, + -196.7660306810449, + -23.297350745428957, + -33.05711396775085, + -37.87806539055941, + -36.11586452494471, + -9.544418023676467, + -26.45284377074363, + -15.84311746455845, + -20.96682897507098, + -89.21229569240322, + -36.36356830792994, + -51.6386339256283, + -5.933199999999999, + -12.504483042360924, + -12.946315794639963, + -27.495795527684436, + -7.633109815598175, + -13.757246010856292, + -70.71590094999817, + -5.933199999999999, + -25.062287440982434, + -9.1446038100295, + -8.221882187825054, + -24.19538777978822, + -5.933199999999999, + -18.478950013100334, + -51.075845787092085, + -5.933199999999999, + -17.170769042209084, + -20.66500128983843, + -8.3568234213711, + -11.127773757379256, + -5.933199999999999, + -8.828182370453847, + -8.828182370453847, + -14.044928083308072, + -5.933199999999999, + -13.757246010856292, + -30.345345291060347, + -33.94929553438898, + -5.933199999999999, + -17.775292557862045, + -5.933199999999999, + -21.279189426599572, + -5.933199999999999, + -9.120092779015149, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -13.197630222920868, + -5.933199999999999, + -15.143540371976181, + -5.933199999999999, + -5.933199999999999, + -29.792762174489106, + -5.933199999999999, + -5.933199999999999, + -8.3568234213711, + -23.66073356339242, + -5.933199999999999, + -5.933199999999999, + -9.120092779015149, + -5.933199999999999, + -14.450393191416238, + -13.197630222920868, + -23.66073356339242, + -14.450393191416238, + -9.439757897319982, + -5.933199999999999, + -9.571386339798417, + -10.223559446148057, + -5.933199999999999, + -13.595871485939714, + -21.868974094164365, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -13.197630222920868, + -14.450393191416238, + -5.933199999999999, + -18.67030097661368, + -13.351780902748127, + -58.19404491887205, + -12.658633722188181, + -22.967586382832476, + -13.534642605394591, + -8.3568234213711, + -5.933199999999999, + -8.3568234213711, + -10.780446842742203, + -15.564525291742383, + -8.3568234213711, + -13.534102459542082, + -5.933199999999999, + -13.534102459542082, + -18.59633383070204, + -21.4635089860562, + -10.700889115485865, + -5.933199999999999, + -124.12334526966141, + -5.933199999999999, + -12.050495379583701, + -9.059040958901011, + -20.547218254182045, + -15.143540371976181, + -5.933199999999999, + -5.933199999999999, + -23.698231456284027, + -10.223559446148057, + -20.754056572362433, + -5.933199999999999, + -8.221882187825054, + -5.933199999999999, + -5.933199999999999, + -12.946315794639963, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -12.946315794639963, + -8.3568234213711, + -22.273653780796746, + -5.933199999999999, + -5.933199999999999, + -10.700889115485865, + -5.933199999999999, + -13.757246010856292, + -5.933199999999999, + -9.059040958901011, + -9.332399378999481, + -5.933199999999999, + -5.933199999999999, + -10.98465728861651, + -5.933199999999999, + -9.120092779015149, + -74.1535303736813, + -13.603323928584036, + -5.933199999999999, + -17.636421695114507, + -15.85566651913393, + -5.933199999999999, + -5.933199999999999, + -14.450393191416238, + -5.933199999999999, + -36.70939119238129, + -15.62125364429197, + -18.511835130725903, + -13.064098830296345, + -5.933199999999999, + -5.933199999999999, + -38.09243026078051, + -5.933199999999999, + -86.25629081059432, + -42.75944849613791, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -16.950819652862272, + -9.120092779015149, + -30.824413883213143, + -15.143540371976181, + -22.967586382832476, + -36.3978345400061, + -22.967586382832476, + -20.23733447374658, + -30.268384249924217, + -28.213167097135248, + -15.143540371976181, + -8.839091569554201, + -9.059040958901011, + -26.777504165323464, + -19.8540710736221, + -5.933199999999999, + -11.347723146726064, + -22.56854184252723, + -28.10522593770048, + -5.933199999999999, + -17.348354678579174, + -9.120092779015149, + -14.044928083308072, + -18.573137228160036, + -5.933199999999999, + -5.933199999999999, + -26.57950479581028, + -5.933199999999999, + -5.933199999999999, + -9.439757897319982, + -12.056944152117072, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -21.058043877948037, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -15.143540371976181, + -62.91004065994902, + -5.933199999999999, + -5.933199999999999, + -14.313732976166172, + -13.064098830296345, + -130.54967416037522, + -5.933199999999999, + -21.070408899599656, + -5.933199999999999, + -9.95058352108597, + -5.933199999999999, + -9.332399378999481, + -5.933199999999999, + -27.132218660769176, + -13.534102459542082, + -5.933199999999999, + -8.839091569554201, + -5.933199999999999, + -5.933199999999999, + -15.143540371976181, + -26.689475924025793, + -5.933199999999999, + -25.05163853706999, + -5.933199999999999, + -5.933199999999999, + -18.049431941530383, + -13.434963256177557, + -53.82493681627788, + -9.967390639402353, + -14.48374317109779, + -15.143540371976181, + -5.933199999999999, + -5.933199999999999, + -15.62125364429197, + -5.933199999999999, + -5.933199999999999, + -12.709497284362444, + -14.044928083308072, + -10.654904002244042, + -15.143540371976181, + -5.933199999999999, + -9.059040958901011, + -12.74564509917781, + -5.933199999999999, + -19.547210751763988, + -5.933199999999999, + -11.532622459331957, + -5.933199999999999, + -20.95268336229021, + -20.25953618173026, + -8.221882187825054, + -5.933199999999999, + -19.07576608472185, + -36.96879027565083, + -14.450393191416238, + -8.3568234213711, + -14.278500830112822, + -5.933199999999999, + -17.87999004760009, + -9.059040958901011, + -8.839091569554201, + -8.839091569554201, + -8.3568234213711, + -15.143540371976181, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -8.839091569554201, + -22.771135943774425, + -5.933199999999999, + -129.8953716778916, + -5.933199999999999, + -23.847665732744055, + -11.347723146726064, + -9.498093474332943, + -7.773309730169101, + -18.650098269296162, + -20.864281918791253, + -15.250989990512846, + -16.8830869697573, + -8.839091569554201, + -10.645505609196155, + -22.156656166616145, + -24.787745326582225, + -13.204070264113305, + -5.933199999999999, + -13.333155438624962, + -5.933199999999999, + -5.933199999999999, + -14.044928083308072, + -13.405546746103955, + -5.933199999999999, + -5.933199999999999, + -11.560021433520072, + -13.351780902748127, + -16.384523001936017, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -18.60768953786102, + -5.933199999999999, + -31.82926059574389, + -30.791632393688765, + -5.933199999999999, + -35.381298393140895, + -16.468551504679173, + -9.439757897319982, + -31.24725923801498, + -34.33901228552901, + -5.933199999999999, + -5.933199999999999, + -13.757246010856292, + -11.27233936106829, + -15.143540371976181, + -5.933199999999999, + -11.61717984736002, + -29.246733002392237, + -16.739075379241292, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -8.828182370453847, + -8.221882187825054, + -15.143540371976181, + -15.143540371976181, + -19.467017156333664, + -21.095784205930883, + -12.840955278982136, + -32.30439425681699, + -5.933199999999999, + -5.933199999999999, + -12.504483042360924, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -13.648032925882974, + -5.933199999999999, + -16.27439075869539, + -5.933199999999999, + -8.3568234213711, + -26.91696309801589, + -10.780446842742203, + -19.160923893062154, + -5.933199999999999, + -5.933199999999999, + -9.95058352108597, + -16.265420202630295, + -5.933199999999999, + -5.933199999999999, + -21.509314442234704, + -5.933199999999999, + -5.933199999999999, + -9.059040958901011, + -12.370951649736401, + -24.353880743952363, + -13.064098830296345, + -12.452697369211693, + -5.933199999999999, + -5.933199999999999, + -29.656808723058084, + -5.933199999999999, + -5.933199999999999, + -30.791632393688765, + -9.95058352108597, + -5.933199999999999, + -11.27233936106829, + -10.347749826379442, + -5.933199999999999, + -13.549886372697891, + -5.933199999999999, + -15.143540371976181, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -116.79802306835457, + -5.933199999999999, + -9.059040958901011, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -21.463508986056198, + -12.504483042360924, + -8.221882187825054, + -8.828182370453847, + -8.828182370453847, + -5.933199999999999, + -9.768261964292018, + -5.933199999999999, + -5.933199999999999, + -9.571386339798417, + -24.228129538646805, + -17.664255258699132, + -5.933199999999999, + -32.8710739353686, + -8.839091569554201, + -28.867180268321064, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -15.143540371976181, + -24.66749619843065, + -5.933199999999999, + -13.197630222920868, + -27.716497264430856, + -5.933199999999999, + -5.933199999999999, + -13.757246010856292, + -13.534102459542082, + -22.27443920227253, + -10.223559446148057, + -5.933199999999999, + -15.77540432411923, + -5.933199999999999, + -9.768261964292018, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -9.059040958901011, + -5.933199999999999, + -5.933199999999999, + -15.212877127584502, + -11.116864558278902, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -38.51695726190457, + -11.756022800370584, + -5.933199999999999, + -25.839332676605473, + -12.039586180483347, + -35.9889738428968, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -8.839091569554201, + -5.933199999999999, + -5.933199999999999, + -21.714823414337108, + -21.581292021712585, + -5.933199999999999, + -5.933199999999999, + -12.025050788341117, + -5.933199999999999, + -27.860438641272346, + -5.933199999999999, + -17.934914683670506, + -9.439757897319982, + -9.1446038100295, + -9.1446038100295, + -5.933199999999999, + -5.933199999999999, + -19.183396748914213, + -5.933199999999999, + -14.044928083308072, + -5.933199999999999, + -9.059040958901011, + -11.35935073805792, + -22.967586382832476, + -5.933199999999999, + -5.933199999999999, + -13.757246010856292, + -5.933199999999999, + -5.933199999999999, + -14.450393191416238, + -17.576234150317248, + -15.234997982465018, + -5.933199999999999, + -8.221882187825054, + -5.933199999999999, + -9.498093474332943, + -10.238265593537752, + -16.87401661278734, + -15.143540371976181, + -5.933199999999999, + -12.052497918617867, + -31.198942953596077, + -12.370951649736401, + -5.933199999999999, + -10.780446842742203, + -5.933199999999999, + -8.3568234213711, + -14.8672732023397, + -13.064098830296345, + -18.07348490499217, + -13.534102459542082, + -14.16596641168513, + -5.933199999999999, + -14.044928083308072, + -13.204070264113305, + -13.757246010856292, + -22.156656166616145, + -8.839091569554201, + -14.769272888245284, + -5.933199999999999, + -14.450393191416238, + -12.253168614080018, + -10.260738449389812, + -9.1446038100295, + -17.71440499014717, + -11.127773757379256, + -14.450393191416238, + -21.645830542850156, + -13.534102459542082, + -36.012988719100676, + -16.10352179247507, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -9.1446038100295, + -22.744442831518263, + -13.757246010856292, + -12.245933737916161, + -12.504483042360924, + -42.26933720238446, + -13.729971368721412, + -5.933199999999999, + -16.045928198681345, + -11.8854438339547, + -8.839091569554201, + -24.797306444299764, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -14.044928083308072, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -15.143540371976181, + -13.757246010856292, + -24.610952434751685, + -13.534102459542082, + -5.933199999999999, + -5.933199999999999, + -9.1446038100295, + -15.143540371976181, + -5.933199999999999, + -49.415654061659154, + -17.87999004760009, + -15.986139342490311, + -15.7597265114, + -17.010867795536534, + -28.71219085200893, + -8.828182370453847, + -31.42533211560529, + -8.221882187825054, + -5.933199999999999, + -13.534102459542082, + -5.933199999999999, + -7.633109815598175, + -15.64062746963166, + -17.576234150317248, + -45.01694746858735, + -13.351780902748127, + -12.039586180483347, + -8.839091569554201, + -5.933199999999999, + -5.933199999999999, + -14.450393191416238, + -10.654904002244042, + -17.848096683824135, + -5.933199999999999, + -5.933199999999999, + -12.578591014514645, + -15.143540371976181, + -5.933199999999999, + -14.044928083308072, + -15.143540371976181, + -9.059040958901011, + -11.811335861800977, + -8.839091569554201, + -5.933199999999999, + -14.450393191416238, + -22.967586382832472, + -5.933199999999999, + -21.868974094164365, + -5.933199999999999, + -19.687427329547376, + -5.933199999999999, + -23.502317256464934, + -5.933199999999999, + -5.933199999999999, + -16.29026346662976, + -21.135004919084164, + -16.739075379241292, + -5.933199999999999, + -15.634563368445994, + -5.933199999999999, + -21.175826913604418, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -20.310829476117814, + -12.345649466874182, + -16.180869432227393, + -12.052497918617867, + -14.450393191416238, + -21.175826913604418, + -12.310327027919966, + -5.933199999999999, + -14.044928083308072, + -22.967586382832476, + -5.933199999999999, + -9.120092779015149, + -14.450393191416238, + -21.135004919084164, + -19.160923893062154, + -15.143540371976181, + -8.839091569554201, + -5.933199999999999, + -18.459477909687514, + -15.143540371976181, + -16.56080421507857, + -11.61717984736002, + -8.3568234213711, + -5.933199999999999, + -5.933199999999999, + -15.762272973105507, + -5.933199999999999, + -5.933199999999999, + -12.840955278982136, + -5.933199999999999, + -5.933199999999999, + -9.120092779015149, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -16.749484395156028, + -11.964932528455211, + -5.933199999999999, + -5.933199999999999, + -20.59409369127854, + -24.586948376464267, + -5.933199999999999, + -5.933199999999999, + -11.27233936106829, + -8.828182370453847, + -5.933199999999999, + -15.902186534768823, + -5.933199999999999, + -15.143540371976181, + -9.95058352108597, + -5.933199999999999, + -8.221882187825054, + -9.967390639402353, + -5.933199999999999, + -8.3568234213711, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -25.99171813090816, + -14.962835721671274, + -102.4641706254026, + -19.384067444376363, + -18.26938133087719, + -14.044928083308072, + -5.933199999999999, + -9.439757897319982, + -5.933199999999999, + -14.450393191416238, + -5.933199999999999, + -5.933199999999999, + -26.97254738391989, + -8.3568234213711, + -11.116864558278902, + -13.534102459542082, + -5.933199999999999, + -5.933199999999999, + -22.835900442007098, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -16.045928198681345, + -8.3568234213711, + -5.933199999999999, + -20.25953618173026, + -8.828182370453847, + -21.175826913604418, + -15.143540371976181, + -28.12361273059949, + -21.645830542850156, + -15.143540371976181, + -19.027757567066345, + -5.933199999999999, + -29.884172277183204, + -19.152654842756178, + -18.864943017795678, + -5.933199999999999, + -5.933199999999999, + -14.044928083308072, + -15.143540371976181, + -5.933199999999999, + -18.46777671250221, + -17.567163793347284, + -5.933199999999999, + -15.143540371976181, + -21.868974094164365, + -5.933199999999999, + -66.74510262424104, + -20.770361805496254, + -9.95058352108597, + -9.439757897319982, + -15.002214435885747, + -23.255268455284252, + -12.056944152117072, + -13.757246010856292, + -17.576234150317248, + -14.044928083308072, + -5.933199999999999, + -47.1330779180119, + -13.757246010856292, + -8.221882187825054, + -12.504483042360924, + -16.543528060228077, + -9.439757897319982, + -33.797240670878864, + -8.3568234213711, + -5.933199999999999, + -46.740338930164995, + -13.539537201032127, + -5.933199999999999, + -15.143540371976181, + -15.852207364194165, + -11.27233936106829, + -5.933199999999999, + -19.398053686351105, + -21.395222289778204, + -5.933199999999999, + -14.450393191416238, + -5.933199999999999, + -24.878688295859018, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -26.00280121625791, + -11.262714990925303, + -17.556766278216806, + -5.933199999999999, + -8.828182370453847, + -5.933199999999999, + -20.105385501903005, + -5.933199999999999, + -41.64261758772376, + -9.498093474332943, + -5.933199999999999, + -9.967390639402353, + -21.135004919084164, + -9.736368600516062, + -5.933199999999999, + -9.498093474332943, + -18.708433846309127, + -9.736368600516062, + -9.1446038100295, + -22.967586382832476, + -23.255268455284252, + -5.933199999999999, + -12.039586180483347, + -5.933199999999999, + -38.470014087245715, + -5.933199999999999, + -8.3568234213711, + -14.7796310414301, + -24.676387262577354, + -10.780446842742203, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -33.56422111592855, + -5.933199999999999, + -15.761501418950237, + -5.933199999999999, + -27.459427883513563, + -5.933199999999999, + -5.933199999999999, + -24.63074157777256, + -17.032692187212888, + -28.173125076002457, + -5.933199999999999, + -8.3568234213711, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -21.955985471153994, + -13.351780902748127, + -14.450393191416238, + -22.967586382832476, + -5.933199999999999, + -10.510564375650109, + -9.439757897319982, + -17.884391075958415, + -8.828182370453847, + -5.933199999999999, + -5.933199999999999, + -19.64229859527067, + -35.59144978616145, + -5.933199999999999, + -8.221882187825054, + -5.933199999999999, + -13.534102459542082, + -22.156656166616145, + -5.933199999999999, + -18.245731097032365, + -5.933199999999999, + -32.86937517111734, + -5.933199999999999, + -41.59750777293006, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -14.044928083308072, + -5.933199999999999, + -36.706135899660616, + -28.476624780696163, + -5.933199999999999, + -9.1446038100295, + -26.764956579991487, + -5.933199999999999, + -18.062311604394043, + -13.534102459542082, + -5.933199999999999, + -9.498093474332943, + -11.127773757379256, + -5.933199999999999, + -17.256331893337574, + -9.768261964292018, + -5.933199999999999, + -21.07077403926333, + -14.044928083308072, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -13.757246010856292, + -31.353093633423335, + -5.933199999999999, + -15.143540371976181, + -14.450393191416238, + -13.757246010856292, + -12.099017934252759, + -11.27233936106829, + -25.93641525962521, + -9.120092779015149, + -5.933199999999999, + -12.838957276319464, + -14.450393191416238, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -15.715886852390422, + -5.933199999999999, + -11.27233936106829, + -5.933199999999999, + -19.55809019835562, + -13.197630222920868, + -28.126141807005354, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -9.498093474332943, + -5.933199999999999, + -5.933199999999999, + -8.828182370453847, + -22.632865679250067, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -21.714823414337104, + -19.959431589279927, + -8.3568234213711, + -13.197630222920868, + -15.143540371976181, + -8.3568234213711, + -14.450393191416238, + -13.534102459542082, + -5.933199999999999, + -15.143540371976181, + -27.740749176844815, + -8.839091569554201, + -13.197630222920868, + -46.78996764216064, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -17.59230797514831, + -24.76395646461821, + -5.933199999999999, + -13.197630222920868, + -30.26425943534727, + -15.222869984846263, + -18.049431941530383, + -9.1446038100295, + -22.27443920227253, + -15.129637466807191, + -10.844513625627675, + -5.933199999999999, + -5.933199999999999, + -17.432222559801236, + -10.510564375650109, + -15.143540371976181, + -10.654904002244042, + -16.544559248654462, + -5.933199999999999, + -20.986584913965892, + -15.143540371976181, + -5.933199999999999, + -16.333610271133125, + -5.933199999999999, + -15.143540371976181, + -18.472889210242453, + -16.32347118182188, + -8.3568234213711, + -8.3568234213711, + -22.56212127472431, + -20.179493474056727, + -5.933199999999999, + -28.792279793980423, + -54.26377042625764, + -22.967586382832476, + -29.917026093752128, + -5.933199999999999, + -5.933199999999999, + -13.757246010856292, + -5.933199999999999, + -27.40276066171725, + -14.450393191416238, + -14.450393191416238, + -8.221882187825054, + -5.933199999999999, + -5.933199999999999, + -21.581292021712585, + -26.571205992995587, + -5.933199999999999, + -5.933199999999999, + -8.839091569554201, + -12.840955278982136, + -12.356007620059, + -5.933199999999999, + -14.583696038730658, + -25.407830524130123, + -14.044928083308072, + -5.933199999999999, + -5.933199999999999, + -9.1446038100295, + -5.933199999999999, + -5.933199999999999, + -22.27443920227253, + -8.221882187825054, + -11.543716200386251, + -33.48726007479242, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -33.678936586377716, + -9.768261964292018, + -13.351780902748127, + -5.933199999999999, + -19.81038416374706, + -13.534102459542082, + -8.839091569554201, + -19.78953255248453, + -26.67666854426393, + -23.66073356339242, + -15.211455082030966, + -23.44813554931156, + -5.933199999999999, + -19.35666847018825, + -20.24035793232393, + -18.820088879983086, + -15.37900957298103, + -8.839091569554201, + -21.581292021712585, + -5.933199999999999, + -5.933199999999999, + -8.221882187825054, + -27.03931987814877, + -5.933199999999999, + -14.543331187075506, + -5.933199999999999, + -8.3568234213711, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -9.059040958901011, + -5.933199999999999, + -13.757246010856292, + -14.044928083308072, + -12.840955278982136, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -13.854307723699423, + -13.06298694866589, + -22.27443920227253, + -12.393075844786793, + -5.933199999999999, + -18.650098269296162, + -18.409794014429416, + -45.528604061420836, + -19.441376756339174, + -26.646743913102885, + -91.82806868826445, + -25.275333622140035, + -21.914618786912193, + -41.700658155921616, + -29.199490897109175, + -25.846489294439703, + -80.31954109757288, + -37.01666521429675, + -141.01312716012623, + -27.128837886723396, + -22.185052922528744, + -31.1964637888797, + -42.696260503679966, + -17.14118214375589, + -51.380843847399845, + -32.16370767462723, + -30.43920571237794, + -41.877680654190165, + -19.63880676741976, + -46.33535711060639, + -30.226737533437017, + -34.946018896728965, + -14.469750807188186, + -65.86976706732992, + -53.13514172670938, + -29.605476754490788, + -22.494796955820348, + -33.42798065650801, + -25.45746673585088, + -32.74147832311655, + -20.64608687791261, + -14.984399775707269, + -25.365296770956398, + -47.739445208625355, + -28.274539724519016, + -81.67356002164411, + -38.664992344870825, + -24.120886274076256, + -24.8397912626876, + -14.314014190093921, + -28.179537609649834, + -36.89031999605844, + -71.59879837418848, + -11.631687860077815, + -17.36976121890081, + -26.17730673621671, + -39.048158586479104, + -47.181711922389724, + -44.77444818527343, + -17.008186200717628, + -52.08665975719244, + -64.58081872592209, + -39.0119635348004, + -31.83701276942731, + -48.53004840500139, + -57.95411384598325, + -41.023781285676705, + -78.38426210525822, + -26.036247595625422, + -33.945564550782976, + -38.10422425972064, + -21.340062630373776, + -47.72498719156253, + -30.45444165594681, + -24.80721809468396, + -21.6503315373233, + -85.14092070200738, + -28.97433575244391, + -26.19392608997867, + -58.57419249158378, + -16.32997701695871, + -28.234883679631942, + -15.017194875383856, + -23.51946314642717, + -45.11057223756579, + -28.676458175637006, + -22.62749064022435, + -29.872981402188863, + -32.91927330263728, + -12.804778823834571, + -27.13632900117529, + -18.722515675636913, + -17.720661838423837, + -46.41863178221966, + -16.55992876183812, + -20.98675527539566, + -16.84397143298171, + -32.806797551936526, + -14.71574826557194, + -23.90559732456746, + -26.383007204702096, + -13.455153477023577, + -46.03699182316543, + -32.399132091931875, + -26.692378774234136, + -20.743324187058633, + -5.933199999999999, + -5.933199999999999, + -23.632927753054435, + -5.933199999999999, + -12.840955278982136, + -35.257744617650246, + -35.46134110081442, + -5.933199999999999, + -9.498093474332943, + -5.933199999999999, + -5.933199999999999, + -51.427215612311755, + -12.840955278982136, + -8.3568234213711, + -15.143540371976181, + -5.933199999999999, + -9.439757897319982, + -18.946708972492246, + -5.933199999999999, + -5.933199999999999, + -30.79163239368877, + -5.933199999999999, + -5.933199999999999, + -12.64718286751916, + -19.971854109278482, + -5.933199999999999, + -23.487957419441994, + -5.933199999999999, + -5.933199999999999, + -26.87213737342192, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -22.90489331349405, + -5.933199999999999, + -18.95181976823555, + -12.310327027919966, + -15.143540371976181, + -5.933199999999999, + -13.351780902748127, + -5.933199999999999, + -9.439757897319982, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -28.306725743900763, + -8.828182370453847, + -12.578591014514645, + -15.143540371976181, + -5.933199999999999, + -5.933199999999999, + -14.450393191416238, + -5.933199999999999, + -5.933199999999999, + -10.780446842742203, + -5.933199999999999, + -19.927674557666734, + -21.93364913662055, + -8.221882187825054, + -13.197630222920868, + -13.333155438624962, + -5.933199999999999, + -5.933199999999999, + -11.723164740907695, + -13.351780902748127, + -32.8710739353686, + -5.933199999999999, + -42.64084211295, + -5.933199999999999, + -13.197630222920868, + -10.223559446148057, + -5.933199999999999, + -5.933199999999999, + -10.347749826379442, + -5.933199999999999, + -5.933199999999999, + -16.10352179247507, + -13.757246010856292, + -5.933199999999999, + -22.392160458969833, + -21.395222289778204, + -12.27044476893051, + -19.637863520829008, + -5.933199999999999, + -5.933199999999999, + -14.450393191416238, + -5.933199999999999, + -16.663137580410492, + -19.32344282255993, + -14.733950449291068, + -5.933199999999999, + -15.640463090573181, + -11.5682272314006, + -9.1446038100295, + -5.933199999999999, + -5.933199999999999, + -15.715755557123991, + -30.307701168761827, + -54.999610157740875, + -20.932735558956818, + -35.640536319284664, + -16.40370238325703, + -87.48327413208824, + -29.477387851767453, + -25.857626543190257, + -59.2895780952634, + -28.482633919111265, + -29.2994686452886, + -32.6259519811052, + -37.73581871991146, + -74.9144868935877, + -28.199644205235924, + -25.05430961536763, + -99.588998632842, + -20.8557790578039, + -24.691976679663178, + -17.455454965160556, + -24.798792355597538, + -22.293704930081123, + -31.6656013631871, + -43.19545422244537, + -18.75808977357757, + -22.421939585873176, + -18.579945080186775, + -25.78614444101443, + -35.278556853136394, + -22.510388044230844, + -32.89230238120996, + -44.980599529112965, + -38.82077818218028, + -11.65797208701213, + -35.771116122742455, + -25.60558013078825, + -23.96048812590436, + -127.97384909450973, + -42.642256859600025, + -32.19197415218965, + -26.799750485113815, + -51.5649762001993, + -45.88103807255704, + -16.0462468430854, + -44.45389972042382, + -13.41679653329296, + -130.3713146041538, + -34.13428417514312, + -64.60371597824025, + -33.66580626874733, + -12.088546162633493, + -26.463796669073847, + -56.02349501810798, + -29.220554004214637, + -27.88930525752346, + -42.0115259510289, + -44.74651706967679, + -32.25781580614756, + -32.8417918410417, + -25.105965592075975, + -22.00305341332963, + -33.20381346414005, + -25.300773000104254, + -50.596107392543836, + -15.266803588012593, + -18.34281944480901, + -43.116737743251065, + -52.71546433225434, + -36.71201141164356, + -31.607418387508904, + -44.46146965372727, + -77.66062783911703, + -19.086918839404046, + -25.403485848098086, + -17.35502467475397, + -20.223862537298242, + -52.51093387851917, + -23.53125628218815, + -17.096484891960586, + -29.154089625316345, + -73.24315368060077, + -25.352052881370295, + -53.06543861485555, + -33.54210306174862, + -14.139419536779487, + -27.459688393650403, + -85.61008947766342, + -144.54365536276305, + -15.622831275395317, + -51.005775825007376, + -22.956633094000175, + -22.00750737576426, + -84.52337758347144, + -116.92797916181173, + -43.72484363390212, + -47.9909850178745, + -25.789964743003047, + -13.32852630006642, + -20.753371119369625, + -45.25511831294006, + -26.245752274235514, + -13.18065789462226, + -41.437152219301765, + -18.41004120962425, + -39.16751689509538, + -38.27196926384855, + -25.517606432190874, + -30.44991078022979, + -20.777751568317356, + -36.59527874051496, + -62.90397532211665, + -54.13888955312741, + -14.487636744277328, + -32.3645698261297, + -101.09410301299161, + -94.41594943584313, + -36.31600551602789, + -27.80272946189205, + -16.801205028439604, + -32.139064659944815, + -62.9961258023174, + -27.869165723370575, + -163.34509395828852, + -77.33364588290404, + -23.671240995322442, + -15.40064956994813, + -37.78025018103749, + -28.43281609078394, + -86.21552857986468, + -38.90101531259511, + -38.2373029610209, + -16.05685653959767, + -31.12502890919388, + -34.60996270793092, + -33.90062095488426, + -32.51167520562437, + -26.57642319240253, + -33.74160448304363, + -52.563893528284815, + -22.828837936306012, + -69.38591675156891, + -43.019714487002155, + -16.728863844530608, + -28.596255650368782, + -27.69419235989356, + -19.316198087426436, + -42.92328842700329, + -34.702695869549615, + -20.74059531946778, + -45.1835761077566, + -33.52952592540805, + -41.72547966923255, + -33.40187338621523, + -28.549399674805485, + -147.35687883701783, + -35.57636682595047, + -33.963287345677514, + -15.464548623137256, + -41.33896891817876, + -30.170708197549306, + -40.422381755706766, + -12.992900807285164, + -17.89116499638358, + -93.2652730020165, + -19.42234947515646, + -32.21342069665494, + -41.28376532123087, + -47.07007488584812, + -17.362101212567907, + -28.47820296638156, + -17.871023576709728, + -17.618675727509768, + -52.66685412882007, + -44.89396973736721, + -77.91485451722484, + -50.66245926471321, + -32.90537769664593, + -21.372004699644684, + -139.0620772101517, + -15.629035214543292, + -20.501474197807966, + -22.706168831685012, + -29.871508883577935, + -33.80215327257478, + -27.110664898359836, + -11.798180524694871, + -55.72099409442026, + -41.56772559297838, + -32.268647213098134, + -33.718327956452875, + -19.156498890046883, + -31.600259523832978, + -24.8723955480285, + -32.20459863194133, + -46.93514343087233, + -55.99189427901912, + -143.71590370193016, + -62.52503892202703, + -27.729319859414446, + -5.933199999999999, + -14.044928083308072, + -5.933199999999999, + -17.567163793347284, + -8.3568234213711, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -8.3568234213711, + -5.933199999999999, + -21.868974094164365, + -42.2786613716261, + -24.032406961866418, + -8.3568234213711, + -14.044928083308072, + -12.74564509917781, + -8.221882187825054, + -13.351780902748127, + -10.223559446148057, + -8.828182370453847, + -5.933199999999999, + -5.933199999999999, + -30.02972996987322, + -5.933199999999999, + -18.740752637564295, + -5.933199999999999, + -5.933199999999999, + -157.4243069443497, + -5.933199999999999, + -8.221882187825054, + -5.933199999999999, + -11.965486541628238, + -25.055866873179514, + -5.933199999999999, + -13.534102459542082, + -28.7767293731465, + -13.534102459542082, + -33.72543631363054, + -5.933199999999999, + -5.933199999999999, + -20.532804850367494, + -24.500063254130446, + -16.333610271133125, + -17.444127462307556, + -5.933199999999999, + -5.933199999999999, + -72.19178550689644, + -5.933199999999999, + -17.157065642052643, + -5.933199999999999, + -15.143540371976181, + -13.351780902748127, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -8.221882187825054, + -5.933199999999999, + -5.933199999999999, + -8.839091569554201, + -10.223559446148057, + -14.044928083308072, + -9.439757897319982, + -9.736368600516062, + -126.87456291479624, + -5.933199999999999, + -5.933199999999999, + -8.3568234213711, + -12.578591014514647, + -19.147020987893164, + -20.462060445841736, + -13.197630222920868, + -8.221882187825054, + -28.170593569576184, + -5.933199999999999, + -5.933199999999999, + -25.256268570657532, + -5.933199999999999, + -5.933199999999999, + -13.757246010856292, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -17.15494950326419, + -10.654904002244042, + -8.221882187825054, + -8.828182370453847, + -12.658633722188181, + -10.780446842742203, + -5.933199999999999, + -5.933199999999999, + -9.439757897319982, + -5.933199999999999, + -5.933199999999999, + -19.160923893062154, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -12.370951649736401, + -34.535319153898214, + -16.98005674995045, + -49.91901631812863, + -36.61699954756526, + -17.216442642590685, + -14.165949082180815, + -21.747583277104045, + -169.53538244709966, + -21.28951236755743, + -49.20949660269862, + -37.59094069083792, + -33.90410496937912, + -19.5989767190115, + -63.32175070605312, + -34.66908727187554, + -54.13082690506903, + -19.115135334569846, + -34.23304027916799, + -40.013724172272035, + -15.143112971439141, + -29.920204157986365, + -16.12300354477222, + -23.78431033333453, + -42.978236328355266, + -19.717923043973244, + -22.991653497182536, + -25.20376317606788, + -27.03914278822407, + -28.834770021482676, + -35.89565546290248, + -28.638441180818727, + -29.842721073342606, + -28.291439354794964, + -31.939112162075094, + -107.65371720119329, + -64.604651041684, + -36.28606617625527, + -29.467342622540144, + -20.356441371731464, + -12.447067177994697, + -37.404860422658174, + -22.582828870269452, + -96.2972004125514, + -42.71926761594178, + -20.13089152052269, + -101.33579039708302, + -79.83631730629092, + -67.6500651750923, + -17.153762380024638, + -27.830112428396973, + -29.17490187078633, + -28.175589434072595, + -18.943599573389683, + -26.64071741531323, + -72.55921719898336, + -20.98207657098647, + -9.708000714727753, + -53.69657770503368, + -17.307778250404866, + -31.61662391446805, + -24.9863524805859, + -82.18319134204162, + -71.04588495935786, + -20.652463974350944, + -37.010635504160845, + -59.28556066473437, + -76.89537275919207, + -27.827531008271613, + -32.23668460450483, + -40.874170155042144, + -35.74377659231881, + -18.89525865853561, + -60.48512523188914, + -32.36777843066957, + -49.597356542012996, + -33.54836155696955, + -26.59781467898324, + -39.88577630492151, + -34.236117644473445, + -25.460513927190696, + -19.6579786278386, + -26.514057704183937, + -15.450926187039935, + -15.907856231693705, + -22.85653502619858, + -38.493225466351205, + -30.23183762031174, + -33.27379841277234, + -25.617955909645154, + -23.37255209396772, + -37.11136691566791, + -20.971181292985623, + -42.66178450345008, + -18.88225606879794, + -27.862906230502816, + -37.19206319172257, + -39.121363581752, + -36.1414352823173, + -42.80668791144861, + -17.93466078788539, + -32.7760218147924, + -30.982638293585484, + -24.300693017218933, + -25.036086071531862, + -43.04269755455341, + -22.632172925758255, + -15.501090937854777, + -29.05201939522979, + -61.388755801209236, + -31.13341049908754, + -42.858541926078004, + -18.384857829140635, + -18.450921973731344, + -50.835335027949874, + -23.87039739928728, + -40.8385196263435, + -9.12198877950621, + -34.934141266663886, + -50.86396602344671, + -47.22759300750874, + -27.741498939543398, + -33.73071479288712, + -26.052204563030525, + -27.821701588030468, + -35.720817932849044, + -25.17402788044693, + -43.125023226017966, + -43.15546086195316, + -80.54932320142515, + -27.99977168081389, + -17.172132660152187, + -33.71981329592324, + -19.741081243773557, + -35.51165928772751, + -9.70352613288616, + -56.78347277475841, + -25.342727780981097, + -32.43726663475998, + -32.262487923429596, + -35.3981855388419, + -29.784119172467605, + -25.39433999706337, + -27.50547879940322, + -26.27488769032083, + -40.42710783011002, + -41.05547245244292, + -17.481657269815436, + -30.12190784950036, + -29.43380844740245, + -21.07869875258972, + -35.90453219599561, + -27.971831636380905, + -22.120262882883768, + -22.668922176515697, + -15.374641072763396, + -22.790270989817813, + -25.32704826321504, + -39.284211291453374, + -69.49378893230164, + -29.849984448242257, + -18.81720250161939, + -20.792395853080258, + -18.907299864470495, + -27.435150367981343, + -78.3151773308267, + -17.476025842776032, + -60.88777661340656, + -88.31778769692096, + -29.391299059838282, + -21.329663329738278, + -26.127330089690602, + -44.4780509039709, + -12.03988301022115, + -17.962501973493723, + -37.12837542964998, + -18.808103018959088, + -24.16022826885864, + -33.83616865769432, + -23.132770966181138, + -15.866929898869829, + -34.926497677140674, + -38.524644370203596, + -18.395892168051205, + -35.857801154158494, + -58.22620670934742, + -17.225503589747543, + -24.88085959886748, + -25.13661008334291, + -23.366163205975703, + -25.646335720888615, + -37.30034014239803, + -37.828173496361444, + -69.19710712047811, + -23.63249394217103, + -20.12418896582441, + -21.783251612267744, + -38.53267799482331, + -28.43149845638808, + -19.939322574279572, + -86.26219142473882, + -30.027215956383152, + -14.294168399769854, + -22.541148854199413, + -27.629853649603092, + -33.924493596938824, + -32.23270810469862, + -59.849291818485355, + -95.45040851896368, + -24.72265762023232, + -72.59215495873347, + -44.049126175658195, + -21.029371022367854, + -20.64485933533182, + -18.805297134611987, + -13.60446998668654, + -20.409635053564674, + -17.421507092907436, + -17.89362679648739, + -95.63547824500297, + -21.092119991512007, + -17.011832839797048, + -28.466469295037076, + -42.629416717782334, + -19.953261095271984, + -60.65340222396976, + -35.60107893788478, + -30.03974294905067, + -50.9072135544966, + -46.69456713212185, + -22.02205688436913, + -26.34762432656676, + -50.406555315489285, + -117.33258820676843, + -27.177026845780354, + -23.752965923236683, + -19.08276172219514, + -21.7714688649384, + -15.906086522238137, + -40.47811623903223, + -118.84615018190263, + -22.160822962956313, + -20.513961122302987, + -38.874111109753905, + -26.96904694023522, + -29.135090746352514, + -45.24312757316792, + -45.13116279887923, + -49.32078227629928, + -30.824762650555886, + -119.15881865767233, + -12.805192797681165, + -80.36866617899366, + -25.863921769976546, + -25.432576776065382, + -19.32677714100586, + -32.32563570269929, + -41.047541798593244, + -45.827306047982916, + -22.164276067119246, + -37.26538203759926, + -55.648791621605916, + -80.14778810731052, + -51.2749365934073, + -17.571809508988153, + -10.145117073202744, + -26.04142602159338, + -34.89234374002501, + -18.523944465466116, + -25.770176303851528, + -23.615839051406127, + -40.45667808568741, + -108.54327521043169, + -47.282454695131605, + -45.58570059818244, + -10.072663843326843, + -26.5620594350006, + -26.767262917140897, + -17.46760704588631, + -13.310726919613373, + -16.13594538687166, + -32.29801465047595, + -27.386075880677176, + -25.71944756994227, + -32.654307964246556, + -23.265636108700118, + -12.351832495598579, + -22.357082374809828, + -34.19933521507231, + -11.852018380406975, + -35.0492892598604, + -20.585615359369037, + -61.19401475490663, + -37.19797588713345, + -18.318567793908812, + -88.30728572642835, + -15.401165174602166, + -141.72150471996088, + -12.664846018799654, + -11.250783145297575, + -102.16239271800768, + -11.954023329354857, + -8.828182370453847, + -11.756022800370584, + -24.737532369655504, + -17.26380390817627, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -23.657239674138165, + -5.933199999999999, + -9.439757897319982, + -19.655444283694322, + -5.933199999999999, + -5.933199999999999, + -10.223559446148057, + -20.179493474056727, + -14.044928083308072, + -5.933199999999999, + -13.757246010856292, + -12.310327027919966, + -12.840955278982136, + -5.933199999999999, + -5.933199999999999, + -24.698062623643633, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -53.74052228249309, + -5.933199999999999, + -8.828182370453847, + -12.658633722188181, + -12.631350970969912, + -13.064098830296345, + -12.74564509917781, + -9.439757897319982, + -8.3568234213711, + -38.30252387168157, + -9.059040958901011, + -5.933199999999999, + -5.933199999999999, + -14.044928083308072, + -5.933199999999999, + -8.828182370453847, + -5.933199999999999, + -9.439757897319982, + -5.933199999999999, + -15.487722251667448, + -13.757246010856292, + -16.85003999725341, + -22.05129565095832, + -5.933199999999999, + -5.933199999999999, + -12.578591014514647, + -15.143540371976181, + -15.143540371976181, + -8.221882187825054, + -15.143540371976181, + -5.933199999999999, + -14.450393191416238, + -17.005909619180233, + -13.534102459542082, + -7.633109815598175, + -14.044928083308072, + -9.1446038100295, + -5.933199999999999, + -43.30141214246157, + -5.933199999999999, + -10.510564375650109, + -18.52182555431176, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -8.221882187825054, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -17.35628476097044, + -21.645830542850156, + -13.551397178750356, + -5.933199999999999, + -5.933199999999999, + -83.32190789782634, + -15.143540371976181, + -13.197630222920868, + -5.933199999999999, + -20.569691110034103, + -15.143540371976181, + -8.828182370453847, + -5.933199999999999, + -14.044928083308072, + -11.049195809754082, + -14.387700122077813, + -8.3568234213711, + -5.933199999999999, + -17.347789503826405, + -8.3568234213711, + -5.933199999999999, + -34.353099236800105, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -8.828182370453847, + -18.403238191364636, + -5.933199999999999, + -9.439757897319982, + -5.933199999999999, + -5.933199999999999, + -11.92466454710798, + -9.571386339798417, + -23.255268455284252, + -27.138971613360862, + -19.748710557964273, + -13.534102459542082, + -5.933199999999999, + -9.059040958901011, + -12.946315794639963, + -12.09901793425276, + -5.933199999999999, + -36.05796671438375, + -20.07721462493631, + -14.044928083308072, + -21.26283829059405, + -8.828182370453847, + -8.839091569554201, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -30.82999456189725, + -8.839091569554201, + -5.933199999999999, + -12.578591014514647, + -9.120092779015149, + -5.933199999999999, + -9.332399378999481, + -5.933199999999999, + -8.839091569554201, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -8.221882187825054, + -21.788931386490827, + -5.933199999999999, + -15.666549919207146, + -5.933199999999999, + -15.497219806935115, + -5.933199999999999, + -12.056944152117072, + -5.933199999999999, + -15.369939216011065, + -5.933199999999999, + -22.16126677917383, + -9.571386339798417, + -10.223559446148057, + -5.933199999999999, + -18.26938133087719, + -18.119470018233994, + -9.332399378999481, + -5.933199999999999, + -8.221882187825054, + -13.064098830296345, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -8.828182370453847, + -5.933199999999999, + -16.189939789197357, + -5.933199999999999, + -16.468551504679173, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -15.143540371976181, + -13.757246010856292, + -15.143540371976181, + -17.156445389855776, + -5.933199999999999, + -28.882089888804327, + -15.143540371976181, + -71.44743655868278, + -5.933199999999999, + -5.933199999999999, + -17.35628476097044, + -14.450393191416238, + -5.933199999999999, + -15.822784647367136, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -18.770384435170666, + -25.54395064310931, + -5.933199999999999, + -9.967390639402353, + -8.3568234213711, + -5.933199999999999, + -11.921716895704046, + -5.933199999999999, + -5.933199999999999, + -18.46777671250221, + -5.933199999999999, + -18.26938133087719, + -15.18190254018467, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -15.143540371976181, + -12.578591014514645, + -5.933199999999999, + -5.933199999999999, + -14.450393191416238, + -15.870037532217681, + -19.8540710736221, + -20.120905313561043, + -14.271326927342955, + -5.933199999999999, + -10.98465728861651, + -5.933199999999999, + -30.612566129615484, + -8.221882187825054, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -18.33528752945613, + -12.199101392809741, + -94.38854626016816, + -5.933199999999999, + -12.663244334745865, + -35.843089682305276, + -11.734073940008049, + -5.933199999999999, + -5.933199999999999, + -9.498093474332943, + -5.933199999999999, + -5.933199999999999, + -8.3568234213711, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -27.947450018261975, + -23.44529965514826, + -5.933199999999999, + -5.933199999999999, + -100.00242499027728, + -5.933199999999999, + -11.965486541628238, + -100.31220263727093, + -13.757246010856292, + -14.587244374165433, + -5.933199999999999, + -18.03852274243003, + -5.933199999999999, + -18.484583830818593, + -15.822784647367136, + -5.933199999999999, + -21.581292021712585, + -10.347749826379442, + -5.933199999999999, + -13.534102459542082, + -8.839091569554201, + -9.967390639402353, + -20.888144841152638, + -5.933199999999999, + -5.933199999999999, + -17.432222559801236, + -5.933199999999999, + -5.933199999999999, + -33.727210744423004, + -9.439757897319982, + -12.310327027919966, + -36.40684723712775, + -25.534137021660985, + -5.933199999999999, + -14.044928083308072, + -5.933199999999999, + -15.486312410745922, + -28.72793920897707, + -24.353880743952363, + -8.221882187825054, + -5.933199999999999, + -13.906287801643213, + -12.310327027919966, + -5.933199999999999, + -32.8710739353686, + -12.840955278982136, + -5.933199999999999, + -18.35494418200568, + -14.450393191416238, + -5.933199999999999, + -12.74564509917781, + -16.96864982088579, + -14.044928083308072, + -8.828182370453847, + -9.059040958901011, + -5.933199999999999, + -8.221882187825054, + -14.044928083308072, + -22.05129565095832, + -19.865244374220225, + -9.498093474332943, + -12.799246563475162, + -12.370951649736401, + -9.560278301152367, + -13.757246010856292, + -5.933199999999999, + -11.921716895704046, + -5.933199999999999, + -5.933199999999999, + -8.828182370453847, + -20.462060445841736, + -17.578514653015972, + -5.933199999999999, + -5.933199999999999, + -15.143540371976181, + -15.143540371976181, + -5.933199999999999, + -5.933199999999999, + -8.3568234213711, + -486.7310219650817, + -24.875873250413186, + -5.933199999999999, + -5.933199999999999, + -22.05129565095832, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -21.095784205930883, + -5.933199999999999, + -8.3568234213711, + -25.72154964094909, + -5.933199999999999, + -20.873200811475236, + -15.871486058078823, + -8.3568234213711, + -5.933199999999999, + -24.817313621516096, + -17.567163793347284, + -15.143540371976181, + -43.60488128028668, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -14.044928083308072, + -12.642260170070266, + -20.770361805496254, + -5.933199999999999, + -5.933199999999999, + -8.221882187825054, + -5.933199999999999, + -8.828182370453847, + -5.933199999999999, + -9.120092779015149, + -14.044928083308072, + -5.933199999999999, + -15.959081200750195, + -5.933199999999999, + -5.933199999999999, + -14.450393191416238, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -23.79747008696589, + -8.221882187825054, + -5.933199999999999, + -16.659943418443092, + -5.933199999999999, + -19.232820977696495, + -12.504483042360924, + -5.933199999999999, + -5.933199999999999, + -21.47918679877543, + -61.494575921529346, + -13.351780902748127, + -9.1446038100295, + -5.933199999999999, + -14.849005699808707, + -208.67534225959588, + -13.757246010856292, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -19.789532552484527, + -13.351780902748127, + -14.764008645894522, + -15.046961306638622, + -5.933199999999999, + -20.3673292833573, + -18.858297790932973, + -5.933199999999999, + -43.70317786946952, + -9.439757897319982, + -5.933199999999999, + -39.596507657556785, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -11.25180579182495, + -5.933199999999999, + -13.757246010856292, + -9.332399378999481, + -14.450393191416238, + -5.933199999999999, + -5.933199999999999, + -18.286420899666645, + -9.768261964292018, + -14.450393191416238, + -11.742342990314027, + -21.884493905822403, + -5.933199999999999, + -8.828182370453847, + -42.26634603166409, + -5.933199999999999, + -5.933199999999999, + -13.129451015702259, + -5.933199999999999, + -5.933199999999999, + -23.209463385014814, + -14.450393191416238, + -32.8710739353686, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -16.61147872213658, + -5.933199999999999, + -5.933199999999999, + -15.143540371976181, + -30.073183030266602, + -22.453266869812225, + -25.87347795238668, + -8.828182370453847, + -9.498093474332943, + -15.143540371976181, + -9.120092779015149, + -5.933199999999999, + -10.347749826379442, + -15.143540371976181, + -44.505037728715884, + -19.160923893062154, + -5.933199999999999, + -5.933199999999999, + -12.709497284362444, + -5.933199999999999, + -12.504483042360924, + -9.498093474332943, + -16.223527196521125, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -21.581292021712585, + -11.965486541628238, + -5.933199999999999, + -12.199101392809741, + -5.933199999999999, + -13.534102459542082, + -5.933199999999999, + -9.736368600516062, + -14.044928083308072, + -31.366996538592325, + -5.933199999999999, + -21.647605450400395, + -8.3568234213711, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -14.313732976166172, + -5.933199999999999, + -5.933199999999999, + -9.571386339798417, + -9.95058352108597, + -12.771373247750542, + -5.933199999999999, + -18.382704622121295, + -20.74296283130814, + -5.933199999999999, + -15.822784647367136, + -5.933199999999999, + -23.73828826871226, + -12.356007620059, + -5.933199999999999, + -21.581292021712585, + -15.143540371976181, + -5.933199999999999, + -92.88186065626306, + -14.044928083308072, + -17.95695108873622, + -8.3568234213711, + -5.933199999999999, + -5.933199999999999, + -25.870283790419272, + -8.3568234213711, + -14.044928083308072, + -20.686255570273367, + -13.197630222920868, + -5.933199999999999, + -18.195294787524496, + -18.049431941530383, + -19.30953991739094, + -16.196244445302856, + -14.044928083308072, + -5.933199999999999, + -8.828182370453847, + -14.859113592245073, + -5.933199999999999, + -9.439757897319982, + -26.474144280152455, + -17.567163793347284, + -5.933199999999999, + -17.95695108873622, + -9.498093474332943, + -5.933199999999999, + -33.56422111592855, + -5.933199999999999, + -20.857373182485883, + -5.933199999999999, + -8.839091569554201, + -13.351780902748127, + -8.3568234213711, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -14.52794789673608, + -19.075851802681242, + -29.599985239053467, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -20.623292574331455, + -21.581292021712585, + -8.221882187825054, + -22.967586382832472, + -5.933199999999999, + -8.3568234213711, + -5.933199999999999, + -31.497105223939347, + -17.345375561870085, + -21.135004919084164, + -29.066186353148517, + -22.165503428473677, + -12.310327027919966, + -13.405546746103955, + -5.933199999999999, + -10.645505609196155, + -5.933199999999999, + -41.8201222660193, + -21.520667399896148, + -9.768261964292018, + -12.743955618064186, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -15.143540371976181, + -5.933199999999999, + -28.88208988880433, + -9.413440589002608, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -17.478678409184504, + -12.658633722188181, + -9.1446038100295, + -12.946315794639963, + -8.3568234213711, + -8.828182370453847, + -5.933199999999999, + -25.886357615250336, + -18.708433846309127, + -21.135004919084164, + -5.933199999999999, + -5.933199999999999, + -14.450393191416238, + -5.933199999999999, + -5.933199999999999, + -14.615444737045237, + -5.933199999999999, + -5.933199999999999, + -75.24775385288466, + -13.757246010856292, + -5.933199999999999, + -5.933199999999999, + -14.450393191416238, + -13.124512536856967, + -15.143540371976181, + -5.933199999999999, + -22.88004556102349, + -5.933199999999999, + -23.869974209537638, + -9.736368600516062, + -5.933199999999999, + -17.985350563257917, + -5.933199999999999, + -31.711178418283595, + -5.933199999999999, + -8.828182370453847, + -12.578591014514647, + -28.43060387949715, + -14.641553696877395, + -5.933199999999999, + -5.933199999999999, + -11.977446274979055, + -32.16391218920725, + -5.933199999999999, + -16.47524136395008, + -14.931875918123552, + -13.534102459542082, + -5.933199999999999, + -14.146788162278796, + -8.221882187825054, + -9.439757897319982, + -13.534102459542082, + -20.462060445841736, + -5.933199999999999, + -9.439757897319982, + -29.531220183947497, + -5.933199999999999, + -28.517050763104585, + -14.473564105627077, + -8.221882187825054, + -35.60752361099251, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -14.044928083308072, + -5.933199999999999, + -10.223559446148057, + -8.839091569554201, + -5.933199999999999, + -12.578591014514647, + -24.040896488638367, + -20.3509937922191, + -10.700889115485865, + -13.534102459542082, + -5.933199999999999, + -9.439757897319982, + -5.933199999999999, + -18.24908751153738, + -21.714823414337108, + -15.143540371976181, + -5.933199999999999, + -9.059040958901011, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -16.835816562719288, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -28.02266403079837, + -9.95058352108597, + -8.221882187825054, + -8.3568234213711, + -13.757246010856292, + -22.56212127472431, + -20.405718691908344, + -5.933199999999999, + -12.623934433233956, + -5.933199999999999, + -16.843450187574355, + -5.933199999999999, + -39.93770705046379, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -9.736368600516062, + -12.946315794639963, + -5.933199999999999, + -11.5682272314006, + -17.567163793347284, + -5.933199999999999, + -5.933199999999999, + -8.3568234213711, + -5.933199999999999, + -5.933199999999999, + -19.56638900117032, + -24.98574469609541, + -19.00941336202927, + -5.933199999999999, + -13.351780902748127, + -10.347749826379442, + -12.897292853332427, + -8.3568234213711, + -11.8854438339547, + -5.933199999999999, + -5.933199999999999, + -14.044928083308072, + -5.933199999999999, + -5.933199999999999, + -9.1446038100295, + -5.933199999999999, + -5.933199999999999, + -17.098995933875027, + -11.847703505971854, + -13.757246010856292, + -5.933199999999999, + -13.064098830296345, + -13.351780902748127, + -5.933199999999999, + -13.349782900085454, + -9.1446038100295, + -9.439757897319982, + -8.828182370453847, + -16.773266709687196, + -9.439757897319982, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -24.353880743952363, + -18.650098269296162, + -18.0898933216161, + -5.933199999999999, + -5.933199999999999, + -12.946315794639963, + -5.933199999999999, + -5.933199999999999, + -22.967586382832472, + -10.223559446148057, + -5.933199999999999, + -5.933199999999999, + -8.839091569554201, + -9.1446038100295, + -5.933199999999999, + -23.46450910142947, + -12.74564509917781, + -5.933199999999999, + -38.87743115749258, + -13.534102459542082, + -5.933199999999999, + -5.933199999999999, + -15.143540371976181, + -5.933199999999999, + -5.933199999999999, + -22.156656166616145, + -5.933199999999999, + -5.933199999999999, + -19.72090474762629, + -27.18997581620166, + -11.860068527623472, + -14.044928083308072, + -5.933199999999999, + -17.186842867040145, + -20.463275469398283, + -5.933199999999999, + -5.933199999999999, + -9.059040958901011, + -8.221882187825054, + -13.197630222920868, + -5.933199999999999, + -23.66073356339242, + -16.58450213443838, + -15.143540371976181, + -26.50214774256232, + -5.933199999999999, + -9.1446038100295, + -22.964092493578217, + -8.828182370453847, + -10.510564375650109, + -16.159176220575063, + -13.197630222920868, + -14.534615925741214, + -5.933199999999999, + -5.933199999999999, + -18.049431941530383, + -5.933199999999999, + -23.255268455284252, + -5.933199999999999, + -9.120092779015149, + -40.330060252751764, + -5.933199999999999, + -8.221882187825054, + -22.967586382832476, + -12.799246563475162, + -8.3568234213711, + -5.933199999999999, + -12.504483042360924, + -12.27044476893051, + -13.540487979650003, + -15.369939216011065, + -16.58595875034398, + -12.840955278982136, + -11.049195809754082, + -5.933199999999999, + -5.933199999999999, + -12.245933737916161, + -9.439757897319982, + -11.776244541989708, + -26.584137636976187, + -14.852364410270145, + -5.933199999999999, + -13.757246010856292, + -8.828182370453847, + -8.221882187825054, + -5.933199999999999, + -36.64801440806231, + -9.1446038100295, + -81.68318821908682, + -5.933199999999999, + -5.933199999999999, + -8.221882187825054, + -5.933199999999999, + -15.143540371976181, + -9.736368600516062, + -15.487722251667448, + -5.933199999999999, + -8.828182370453847, + -5.933199999999999, + -5.933199999999999, + -8.221882187825054, + -5.933199999999999, + -15.143540371976181, + -15.688612434470764, + -5.933199999999999, + -12.504483042360924, + -25.93960212976915, + -15.143540371976181, + -5.933199999999999, + -12.504483042360924, + -23.66073356339242, + -24.47491907232942, + -14.044928083308072, + -5.933199999999999, + -5.933199999999999, + -15.143540371976181, + -15.143540371976181, + -26.88957961951671, + -9.498093474332943, + -19.486346293496783, + -5.933199999999999, + -15.143540371976181, + -8.3568234213711, + -13.351780902748127, + -5.933199999999999, + -16.25767247230233, + -5.933199999999999, + -9.1446038100295, + -8.3568234213711, + -19.052701975123313, + -12.840955278982136, + -8.828182370453847, + -32.0935856063749, + -5.933199999999999, + -14.26578258981881, + -5.933199999999999, + -5.933199999999999, + -17.774629531942264, + -16.045928198681345, + -8.3568234213711, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -15.143540371976181, + -9.95058352108597, + -33.43806491192337, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -12.356007620059, + -9.1446038100295, + -22.74262448571148, + -12.942190980063014, + -5.933199999999999, + -8.3568234213711, + -16.045928198681345, + -5.933199999999999, + -13.534102459542082, + -5.933199999999999, + -5.933199999999999, + -15.143540371976181, + -5.933199999999999, + -11.728440085145035, + -23.43778227008719, + -9.768261964292018, + -13.197630222920868, + -8.3568234213711, + -14.244029640142044, + -15.143540371976181, + -5.933199999999999, + -5.933199999999999, + -25.53805092098212, + -5.933199999999999, + -5.933199999999999, + -14.450393191416238, + -15.143540371976181, + -5.933199999999999, + -5.933199999999999, + -14.450393191416238, + -5.933199999999999, + -5.933199999999999, + -16.739075379241292, + -13.064098830296345, + -5.933199999999999, + -5.933199999999999, + -30.268384249924217, + -15.143540371976181, + -9.498093474332943, + -5.933199999999999, + -29.826551497645177, + -5.933199999999999, + -12.025050788341117, + -5.933199999999999, + -15.143540371976181, + -11.742342990314027, + -9.059040958901011, + -21.44680483600383, + -12.310327027919966, + -5.933199999999999, + -8.3568234213711, + -12.504483042360924, + -21.358148470398373, + -14.934568550937195, + -35.93454729279411, + -19.865244374220225, + -5.933199999999999, + -18.864943017795678, + -5.933199999999999, + -9.736368600516062, + -5.933199999999999, + -5.933199999999999, + -12.946315794639963, + -5.933199999999999, + -5.933199999999999, + -8.221882187825054, + -9.120092779015149, + -14.044928083308072, + -5.933199999999999, + -8.828182370453847, + -19.0178470753101, + -83.45655916007084, + -8.828182370453847, + -9.967390639402353, + -5.933199999999999, + -10.780446842742203, + -23.972640024735064, + -14.450393191416238, + -15.49825486742189, + -5.933199999999999, + -15.55361609264203, + -5.933199999999999, + -23.255268455284252, + -9.059040958901011, + -18.381349302284285, + -13.351780902748127, + -34.19034177299723, + -24.353880743952363, + -5.933199999999999, + -5.933199999999999, + -15.234997982465018, + -9.768261964292018, + -8.3568234213711, + -8.3568234213711, + -9.967390639402353, + -9.498093474332943, + -13.534102459542082, + -12.306985558030298, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -10.654904002244042, + -17.345375561870085, + -5.933199999999999, + -9.498093474332943, + -14.945263448392101, + -30.519698678205124, + -15.143540371976181, + -5.933199999999999, + -13.337877997579136, + -5.933199999999999, + -8.221882187825054, + -11.116864558278902, + -15.143540371976181, + -5.933199999999999, + -5.933199999999999, + -30.869129600661672, + -15.143540371976181, + -8.3568234213711, + -5.933199999999999, + -14.450393191416238, + -5.933199999999999, + -14.450393191416238, + -25.368059976645643, + -12.14780809842219, + -11.744983139108403, + -5.933199999999999, + -22.40797059489705, + -5.933199999999999, + -19.39399152557406, + -14.450393191416238, + -5.933199999999999, + -14.450393191416238, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -22.349591579627543, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -10.518567558691911, + -5.933199999999999, + -5.933199999999999, + -8.839091569554201, + -9.439757897319982, + -5.933199999999999, + -40.86501898302029, + -17.438385892876052, + -21.714823414337104, + -13.757246010856292, + -45.98982463661513, + -12.050495379583701, + -20.402637025370936, + -5.933199999999999, + -13.534102459542082, + -5.933199999999999, + -8.839091569554201, + -5.933199999999999, + -5.933199999999999, + -21.02167623377716, + -16.011040939680903, + -21.581292021712585, + -8.3568234213711, + -11.723164740907695, + -5.933199999999999, + -12.84556589153982, + -13.539537201032127, + -17.432222559801236, + -8.404126942834614, + -11.25180579182495, + -34.80901591477474, + -9.768261964292018, + -13.534102459542082, + -71.71049852912823, + -5.933199999999999, + -34.945187456193636, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -12.64718286751916, + -13.757246010856292, + -9.736368600516062, + -9.1446038100295, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -49.49999521009291, + -12.306985558030298, + -12.008046156047033, + -5.933199999999999, + -15.169268520548913, + -29.360520032723276, + -31.772461646700492, + -12.334740267773828, + -37.00949578483163, + -5.933199999999999, + -12.840955278982136, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -42.740023722655835, + -8.3568234213711, + -5.933199999999999, + -21.296865241981475, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -17.75401024473953, + -11.8854438339547, + -13.204070264113305, + -8.3568234213711, + -24.500063254130446, + -19.149874056875568, + -8.221882187825054, + -25.64777327524976, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -9.059040958901011, + -9.059040958901011, + -9.439757897319982, + -35.68523841807239, + -68.98791902230676, + -54.1713495978891, + -19.70185535001134, + -41.13127377286186, + -23.70900682960109, + -18.44146220249675, + -32.317254837826, + -46.63112040063016, + -19.5993479150262, + -23.5369361765486, + -65.97158605181066, + -17.164270653366138, + -21.281065415200523, + -24.34740863891325, + -34.49264889261875, + -50.17112292981462, + -32.18315861459739, + -28.507267562336118, + -38.278081114795825, + -52.589708052060864, + -34.08645735880465, + -25.680702851410004, + -37.71738804412399, + -39.182141457526825, + -19.80610590577153, + -14.162687661834296, + -28.8890596453444, + -19.255017751248552, + -54.44598909761789, + -21.844531521900922, + -179.70551155826269, + -28.41759467409699, + -27.567801657433986, + -26.18704141491675, + -15.333259973855558, + -45.23115647042067, + -28.896664543140098, + -26.591771526832783, + -22.135190018975052, + -28.58917108982941, + -77.35853571829355, + -70.10492517420712, + -86.02352943192719, + -26.423695240043294, + -41.392833604910535, + -26.285280457765534, + -35.99777877789032, + -58.49613325832506, + -61.986381266348786, + -24.57560678460755, + -70.8331400960458, + -49.63168206187464, + -32.15095638212743, + -36.993754341033785, + -34.46147225676863, + -24.150071950547165, + -28.196151924442695, + -79.1333747081703, + -36.40281648796409, + -25.268847041573547, + -41.71235273641738, + -32.441647055421875, + -27.787656846563895, + -14.550930938783827, + -19.49383234206852, + -30.35406212617706, + -40.466710949566014, + -24.438216601509236, + -51.32690889872371, + -32.955354417615666, + -20.975908886595494, + -35.09201500942832, + -41.17973465420393, + -17.6761716588824, + -30.32515393609617, + -48.430374632254455, + -25.001277891689085, + -31.716971138602787, + -18.955113749142065, + -33.41295502398199, + -27.933917617615933, + -18.583751114537193, + -65.04114067719682, + -20.62459185059501, + -35.34690906301245, + -47.52725785695553, + -25.887739667480478, + -32.88831326455749, + -24.351778880139506, + -27.860439031900324, + -34.02669912259883, + -30.727426678640306, + -37.501756538829355, + -13.904884206620373, + -36.5743894830277, + -22.896978921243395, + -26.92431786324576, + -23.277654933439408, + -120.82696219040344, + -20.891340309854133, + -37.40259923258563, + -132.74915716644097, + -42.57079562798593, + -67.40446824337042, + -20.20688804904634, + -38.198217003325055, + -179.28031703342228, + -27.99490277256638, + -37.34102007965465, + -21.632253151577686, + -31.4982004785008, + -33.67414809692284, + -22.95304258776623, + -30.66559694197302, + -29.459550655442634, + -16.176884380285657, + -39.70237417840061, + -15.125879024970388, + -24.249728646539708, + -22.678847638835414, + -24.569914652786405, + -61.74429827502018, + -23.529534558313788, + -15.544523270780209, + -114.7228439867785, + -19.178494679752717, + -17.849928189516792, + -39.76105854362365, + -43.03810663946248, + -35.496057542960585, + -27.182865850668815, + -44.901285292799685, + -25.35859447004061, + -18.53741365447975, + -26.002640155945343, + -29.7807317361604, + -41.95600079960728, + -27.000873809042986, + -43.41057628377717, + -22.384291889197602, + -29.992070835334278, + -37.561004226306764, + -64.04540198929263, + -37.30274171265683, + -24.52421013346002, + -22.168154740011015, + -34.50820654482297, + -19.852817643963512, + -22.206729820045716, + -14.69362544504109, + -15.956943960395275, + -25.219171536448496, + -32.339125758298735, + -42.06288962256399, + -31.63369209254126, + -33.28900631020223, + -42.606601788451606, + -30.103909270468165, + -17.68860732889535, + -28.179010171767462, + -24.71152518939347, + -16.387654300753155, + -31.183794217138903, + -25.85497782097732, + -75.65230525603985, + -59.36743491027799, + -42.94797940039525, + -22.026171901534795, + -45.21194248494455, + -92.98894963331715, + -15.375389368217148, + -28.349185838496822, + -49.687974398804094, + -25.56220512457586, + -30.164383862710284, + -22.692607123780515, + -17.579008887140283, + -102.21175234236362, + -20.387241285764723, + -25.008124106140748, + -32.15009971205225, + -30.102356088462773, + -35.79804543314104, + -32.92801802653247, + -30.805994771147777, + -24.97922791927427, + -67.46834377016515, + -33.73550549313389, + -28.37296658455311, + -25.948933427847138, + -43.62091220557342, + -24.64973424536185, + -15.119168148994941, + -28.905531123581362, + -272.5345938646598, + -29.53276065646062, + -26.46913612776929, + -30.54886463382674, + -31.199871138275004, + -27.38160017732428, + -29.701051672006226, + -15.972124925384817, + -30.76373170576612, + -27.34110974120984, + -30.329392775440837, + -36.72535415432076, + -30.24547877031681, + -26.315336590817793, + -22.0331877741932, + -29.31599085753137, + -17.94195406936859, + -23.76087186892018, + -35.141074514400884, + -34.23053999899124, + -30.46934695214507, + -29.744120515615954, + -72.24554882354306, + -32.019038542024674, + -44.410729607857455, + -13.89835460532382, + -183.41094632504874, + -48.56910514391198, + -33.33449400757999, + -30.689158818272134, + -36.4275316719709, + -23.502282459302084, + -46.644967141224534, + -38.23421116181296, + -25.751407917610706, + -31.94875520399992, + -80.43631384420843, + -15.559346021803087, + -26.620050884097623, + -22.626729401694053, + -48.08679339185349, + -36.57464788841091, + -27.843319816672672, + -20.52461238529637, + -50.38234589055031, + -35.157635019682445, + -26.784521521445313, + -38.13259921255587, + -19.89015532858559, + -30.608458745344663, + -19.032980294171928, + -29.67635955732198, + -32.927173509093095, + -24.909042588522162, + -21.62302862419292, + -15.706712550917796, + -35.87172027676583, + -18.124494327554757, + -49.118098599348286, + -46.6308269329986, + -27.289820618901665, + -35.020422115263116, + -29.14170743335763, + -26.31617507682851, + -37.00819108464694, + -19.819116501452367, + -27.926641523772883, + -16.00297978283626, + -54.099084037074576, + -29.788092590501932, + -30.175323918873925, + -23.874914327656747, + -16.547994201324137, + -29.89729191949306, + -18.261179531821192, + -14.695979483371401, + -33.311015458583164, + -20.815572152579414, + -13.449530689519733, + -34.040676164994494, + -69.22140371983228, + -20.539184496927163, + -36.15854961647116, + -34.926799181886274, + -33.190581388205516, + -16.532485958840212, + -46.631177301001706, + -17.4362797711507, + -24.85315319247099, + -45.69152104474564, + -11.349525580706654, + -31.242824171625966, + -31.818915172517986, + -41.84752124585644, + -16.651008706920692, + -33.699621187861624, + -11.314843709505702, + -34.47266094372472, + -46.533449723606076, + -65.52483147643532, + -50.62998071013592, + -51.31060873236243, + -21.306628417160077, + -41.396981216431314, + -19.64347052428081, + -33.22041929965259, + -16.940731685247464, + -20.899896521127594, + -22.6613532288421, + -38.307275978908436, + -70.5141884511027, + -30.30051563557401, + -40.37020568141244, + -29.20953624873082, + -55.69607753329582, + -66.05404901280943, + -15.342003804159454, + -91.62907377725912, + -34.26455105537715, + -57.405556100024945, + -43.2220800579484, + -49.50933233841848, + -39.87013961656727, + -36.08844030892441, + -45.81515883608619, + -37.235831511439144, + -16.058981813545678, + -22.368660455202367, + -34.302873150373834, + -27.70974052486708, + -30.772796492653068, + -11.59310689876142, + -19.614020172216563, + -300.5863248411893, + -31.41884023542132, + -38.1591022678775, + -34.31997669850815, + -66.40083651758421, + -18.77254548221476, + -61.495658605591395, + -198.04888890364907, + -28.048566870004684, + -47.118177485375476, + -28.9407291803182, + -29.964666496952656, + -52.08076867851416, + -32.52169257851823, + -22.435096652118677, + -26.659689560808886, + -63.86938399144118, + -27.81527231691006, + -29.437008027656535, + -12.06851019059021, + -45.23823653641114, + -23.700244281409468, + -15.956541077586603, + -13.158955758560976, + -16.511812433501667, + -32.561676693121626, + -15.285519125956773, + -35.69626294124385, + -61.62278276699942, + -52.79639489462931, + -35.978531538684805, + -32.156782167477346, + -30.42392320042122, + -24.57833990849833, + -39.93595061899233, + -44.90247773686022, + -44.35779620998071, + -40.30463421283418, + -28.8030268493318, + -24.551774171723945, + -24.351184012634697, + -32.65302845279191, + -10.521348293817727, + -20.523427370536517, + -17.74625849343535, + -14.739686728510675, + -19.62594361002057, + -27.367350554420767, + -35.72610496478205, + -10.927389529711824, + -24.634861152715334, + -25.38408300734645, + -87.27233064490021, + -30.711507231601182, + -45.088851896812145, + -45.81855306017966, + -38.85534061434551, + -57.63347767170071, + -14.198248042947887, + -22.933623069640863, + -20.387005863069085, + -50.090717488910684, + -17.215867085626112, + -20.651484933264612, + -30.76403498792563, + -57.627464206447065, + -53.33708841637926, + -14.305942430523992, + -24.389056618519167, + -11.48976065612117, + -16.055721377876388, + -26.26122952839241, + -5.933199999999999, + -13.064098830296345, + -10.23088548624013, + -45.568169577368586, + -41.726821529610376, + -8.828182370453847, + -9.439757897319982, + -5.933199999999999, + -9.059040958901011, + -13.534102459542082, + -30.856170914826336, + -5.933199999999999, + -13.197630222920868, + -5.933199999999999, + -12.008046156047033, + -33.635438842378925, + -12.862209559417074, + -5.933199999999999, + -9.498093474332943, + -19.525567006650064, + -25.90269403457003, + -16.157719604669463, + -5.933199999999999, + -13.064098830296345, + -9.439757897319982, + -5.933199999999999, + -19.684114538479765, + -5.933199999999999, + -13.534102459542082, + -27.107451460356383, + -5.933199999999999, + -41.0223747937965, + -8.828182370453847, + -12.393075844786793, + -9.498093474332943, + -15.234997982465018, + -5.933199999999999, + -40.28965483811673, + -5.933199999999999, + -11.965486541628238, + -21.788931386490827, + -5.933199999999999, + -24.66258218362822, + -18.049431941530383, + -5.933199999999999, + -15.567411430088498, + -8.839091569554201, + -5.933199999999999, + -20.36489669738809, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -20.693400764360128, + -23.748066359304303, + -5.933199999999999, + -5.933199999999999, + -19.911229487462048, + -5.933199999999999, + -5.933199999999999, + -9.498093474332943, + -10.223559446148057, + -5.933199999999999, + -10.510564375650109, + -5.933199999999999, + -5.933199999999999, + -9.1446038100295, + -9.120092779015149, + -12.578591014514647, + -50.867664107089645, + -5.933199999999999, + -5.933199999999999, + -9.059040958901011, + -44.83739324363294, + -5.933199999999999, + -13.991850652771703, + -5.933199999999999, + -5.933199999999999, + -18.28282471335717, + -5.933199999999999, + -5.933199999999999, + -12.74564509917781, + -8.221882187825054, + -8.3568234213711, + -5.933199999999999, + -15.143540371976181, + -5.933199999999999, + -5.933199999999999, + -15.103935117383823, + -5.933199999999999, + -5.933199999999999, + -22.156656166616145, + -15.561331129774983, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -62.546457576684475, + -9.332399378999481, + -14.50405771600193, + -5.933199999999999, + -9.768261964292018, + -26.569798526285048, + -71.33928043168842, + -21.91470547839207, + -49.005007577831755, + -42.709755714232244, + -15.586865236831226, + -50.713594501330576, + -28.416940274699293, + -20.126306636026044, + -42.037843575423054, + -159.93185230611667, + -24.131907365956028, + -34.852340238346706, + -33.12857249228179, + -15.23143186455313, + -53.923337860813206, + -43.79617909212125, + -26.007780995185716, + -25.613585708711636, + -13.662067194332582, + -26.096165783765464, + -34.83607368717901, + -24.072215277522712, + -37.80476025934015, + -21.946045589473677, + -123.03879863030065, + -41.48383585023405, + -13.80534368849588, + -26.352303086513047, + -30.187066020995317, + -66.55301565628206, + -20.51321427497337, + -84.4336774546024, + -13.012362619937353, + -44.57208896398559, + -20.66161719427887, + -16.141494228230457, + -27.1040192237916, + -27.951345292814892, + -46.80485830958665, + -91.84982162208155, + -33.54134543068572, + -19.881655352722102, + -41.89386533211448, + -51.76511702499575, + -26.177565307674065, + -32.453775123591946, + -19.62865002724441, + -14.252113922647059, + -71.62876348395613, + -18.999248006430037, + -28.631508001009813, + -33.69672722415284, + -18.431755851713614, + -33.644974844733504, + -38.80430100692056, + -31.177071062628237, + -30.832096174773586, + -29.184380507331664, + -25.231835616403895, + -24.092973602906056, + -18.796494422286557, + -42.35526681733042, + -50.66279293081797, + -13.26418866083658, + -19.658611935707025, + -33.82148731030778, + -29.0538099028031, + -161.169745470591, + -55.53437633072359, + -47.071998522365035, + -25.745377850733593, + -19.073178718539353, + -14.528112857326345, + -39.24463202516092, + -39.35357410906434, + -11.409060593572836, + -50.655021458197616, + -20.965917018723232, + -47.38000982895323, + -50.617072300215355, + -38.24343128375016, + -17.076376022968738, + -38.42988765248001, + -47.06234067310125, + -20.52388848637434, + -18.84246674269103, + -13.298621538646813, + -35.20537137055616, + -21.991122346294535, + -25.094665423085026, + -38.658115256222246, + -13.855557094497664, + -12.67867702122231, + -37.57089042996341, + -34.90346291793864, + -30.83721397172366, + -35.77832647716166, + -71.51228472658114, + -26.822204513817972, + -43.816771485893085, + -16.31361805660066, + -161.34514523824097, + -33.59182004557765, + -41.17549008446132, + -164.46051879842094, + -25.918066042421525, + -75.00204313933494, + -88.63770130245959, + -33.08566562432161, + -21.93621362433268, + -35.466917200350544, + -17.022190789706833, + -34.71373057670568, + -35.684594529783396, + -42.33724789316506, + -22.21297222381068, + -28.05500631800269, + -16.998128867191134, + -13.585951880792031, + -37.70367075740597, + -37.463398225639246, + -38.05666114195428, + -30.530571745200888, + -24.084522706225638, + -43.42865607279036, + -21.207950404203615, + -46.0509002588629, + -23.27822013003288, + -86.5888877600533, + -18.87821625368484, + -30.217851616879994, + -42.358449625924884, + -42.30005590018013, + -23.923511512707947, + -30.535334000580875, + -50.73754013573523, + -14.872013433506964, + -21.551282394690055, + -27.959209541786574, + -10.942614807776891, + -25.877939148033636, + -32.106061201736594, + -41.19117733020382, + -17.989160525215592, + -11.819552489891988, + -138.05221042054316, + -17.9081827750933, + -49.49692266040765, + -109.03535626855047, + -65.86006268940358, + -44.29293548589637, + -39.8707323357655, + -20.64475620694243, + -16.13773497414452, + -42.18021743242031, + -32.46291766573883, + -22.008149491751283, + -28.605841871445932, + -54.68405766981051, + -18.074489258004405, + -150.06504963869108, + -25.43802375128637, + -33.300430881824724, + -22.44875809106737, + -26.297655200366346, + -38.73971067418194, + -113.78796104561864, + -15.748687748948331, + -19.490327623729826, + -65.58649125755534, + -32.497985698291764, + -49.84144091216565, + -56.54402829428, + -42.68256950189015, + -81.29279979153156, + -37.52584966628078, + -23.459987984589176, + -18.670239726970195, + -31.620070216007775, + -32.3115794507906, + -18.266771873012132, + -44.28940413751939, + -36.801054558146845, + -53.765160212667425, + -19.141618136397902, + -45.478219355766, + -48.03542598233573, + -54.83583340543709, + -33.84076915303004, + -50.6316234036925, + -28.829515210900823, + -24.9246644151231, + -20.462642999407358, + -19.370599211144345, + -13.318675370661088, + -26.462265248413477, + -48.273034634248305, + -30.012906665708915, + -66.4678273950961, + -15.486312410745922, + -14.398180319969303, + -5.933199999999999, + -16.468551504679173, + -5.933199999999999, + -17.567163793347284, + -19.009677426382286, + -5.933199999999999, + -13.534102459542082, + -5.933199999999999, + -16.045928198681345, + -5.933199999999999, + -21.868974094164365, + -13.757246010856292, + -5.933199999999999, + -38.49789536888868, + -5.933199999999999, + -5.933199999999999, + -19.278706928718538, + -34.45679532118538, + -5.933199999999999, + -12.862209559417074, + -9.439757897319982, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -10.700889115485865, + -5.933199999999999, + -32.34480812711473, + -12.370951649736401, + -5.933199999999999, + -15.143540371976181, + -5.933199999999999, + -5.933199999999999, + -9.736368600516062, + -5.933199999999999, + -15.143540371976181, + -13.757246010856292, + -5.933199999999999, + -8.828182370453847, + -5.933199999999999, + -16.628992304629293, + -8.828182370453847, + -22.562121274724312, + -8.3568234213711, + -5.933199999999999, + -11.965486541628238, + -5.933199999999999, + -5.933199999999999, + -18.875881969404748, + -5.933199999999999, + -63.44678128333273, + -5.933199999999999, + -9.059040958901011, + -5.933199999999999, + -23.92769839425548, + -24.393125482994265, + -8.221882187825054, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -21.358148470398373, + -9.1446038100295, + -5.933199999999999, + -10.510564375650109, + -21.645830542850156, + -5.933199999999999, + -9.498093474332943, + -14.044928083308072, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -8.828182370453847, + -9.967390639402353, + -5.933199999999999, + -35.25388407414002, + -18.253561791932302, + -17.576234150317248, + -5.933199999999999, + -5.933199999999999, + -26.01875250682579, + -13.694717320576345, + -8.3568234213711, + -5.933199999999999, + -117.70189128023019, + -18.758098933748364, + -5.933199999999999, + -8.221882187825054, + -5.933199999999999, + -5.933199999999999, + -24.353880743952363, + -5.933199999999999, + -12.14780809842219, + -30.09848521312882, + -5.933199999999999, + -17.576234150317248, + -5.933199999999999, + -5.933199999999999, + -10.71272357313287, + -21.581292021712585, + -5.933199999999999, + -14.450393191416238, + -20.888144841152638, + -13.757246010856292, + -74.9067220312711, + -5.933199999999999, + -9.332399378999481, + -25.949415751217472, + -5.933199999999999, + -5.933199999999999, + -8.839091569554201, + -12.946315794639963, + -5.933199999999999, + -12.512241633973112, + -19.310455627033118, + -5.933199999999999, + -21.035865715719638, + -5.933199999999999, + -14.450393191416238, + -5.933199999999999, + -5.933199999999999, + -16.8830869697573, + -9.059040958901011, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -14.450393191416238, + -9.95058352108597, + -8.221882187825054, + -17.917730375582938, + -13.242926497836045, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -9.439757897319982, + -25.643411436639948, + -5.933199999999999, + -26.06867917204429, + -5.933199999999999, + -5.933199999999999, + -27.965799156930174, + -14.450393191416238, + -21.714823414337104, + -15.143540371976181, + -9.059040958901011, + -5.933199999999999, + -5.933199999999999, + -10.347749826379442, + -12.862373009856201, + -5.933199999999999, + -23.255268455284252, + -5.933199999999999, + -5.933199999999999, + -13.351780902748127, + -15.226478959498497, + -5.933199999999999, + -14.629056310461896, + -13.351780902748127, + -16.42908482999593, + -5.933199999999999, + -18.9786023362682, + -9.439757897319982, + -5.933199999999999, + -14.450393191416238, + -17.368546476080923, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -16.246763273201974, + -30.70559805634696, + -5.933199999999999, + -5.933199999999999, + -21.737288153338987, + -13.064098830296345, + -24.3660239857883, + -16.180869432227393, + -9.059040958901011, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -15.561331129774983, + -17.91612909421596, + -13.351780902748127, + -14.450393191416238, + -5.933199999999999, + -13.351780902748127, + -13.757246010856292, + -5.933199999999999, + -12.02598434856935, + -32.17792675480866, + -14.450393191416238, + -11.776244541989708, + -14.001581278804707, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -167.57560552753816, + -5.933199999999999, + -22.967586382832472, + -11.723164740907695, + -5.933199999999999, + -29.315480598255917, + -5.933199999999999, + -9.967390639402353, + -5.933199999999999, + -13.351780902748127, + -5.933199999999999, + -9.498093474332943, + -5.933199999999999, + -8.3568234213711, + -11.8854438339547, + -15.143540371976181, + -10.621751794927142, + -12.233899898352437, + -8.221882187825054, + -258.96272122854214, + -12.199101392809741, + -12.946315794639963, + -9.736368600516062, + -18.35494418200568, + -5.933199999999999, + -8.221882187825054, + -5.933199999999999, + -11.543716200386251, + -15.143540371976181, + -8.3568234213711, + -27.986945628902056, + -8.839091569554201, + -40.34448435759947, + -20.25953618173026, + -8.3568234213711, + -20.16422600192594, + -5.933199999999999, + -21.135004919084164, + -15.143540371976181, + -5.933199999999999, + -15.143540371976181, + -5.933199999999999, + -10.758950774499187, + -5.933199999999999, + -24.08171848315862, + -9.967390639402353, + -16.696597950974173, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -11.964932528455211, + -10.510564375650109, + -39.82374832003345, + -5.933199999999999, + -5.933199999999999, + -14.450393191416238, + -5.933199999999999, + -89.55276050802715, + -5.933199999999999, + -5.933199999999999, + -8.839091569554201, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -17.23182086232322, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -9.768261964292018, + -15.143540371976181, + -20.24035793232393, + -17.322139485189236, + -5.933199999999999, + -14.449607769940453, + -20.74457494086957, + -51.500995325466185, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -18.35494418200568, + -5.933199999999999, + -5.933199999999999, + -14.16732173152214, + -16.87401661278734, + -5.933199999999999, + -5.933199999999999, + -28.78560050554386, + -20.003069157622445, + -11.965486541628238, + -14.450393191416238, + -29.612977397347116, + -35.04986281923715, + -11.742342990314027, + -9.059040958901011, + -15.969990399850548, + -19.41223832134306, + -14.672287523330015, + -5.933199999999999, + -19.29764003415844, + -5.933199999999999, + -24.260845877985176, + -5.933199999999999, + -16.94413878987144, + -8.3568234213711, + -5.933199999999999, + -5.933199999999999, + -11.116864558278902, + -12.015075149468997, + -5.933199999999999, + -15.143540371976181, + -15.053699667976392, + -68.44385280827018, + -5.933199999999999, + -14.450393191416238, + -9.967390639402353, + -5.933199999999999, + -5.933199999999999, + -34.04329229139649, + -9.498093474332943, + -52.46336123249519, + -31.44468806246602, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -14.044928083308072, + -5.933199999999999, + -5.933199999999999, + -25.480892507142173, + -5.933199999999999, + -14.450393191416238, + -31.184674981798373, + -21.16436370133104, + -16.092612593374717, + -5.933199999999999, + -17.39729186254425, + -16.950819652862272, + -5.933199999999999, + -5.933199999999999, + -18.00456904021548, + -5.933199999999999, + -8.828182370453847, + -5.933199999999999, + -12.435490170873972, + -8.3568234213711, + -11.408774966840204, + -14.450393191416238, + -12.840955278982136, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -9.059040958901011, + -5.933199999999999, + -5.933199999999999, + -20.79853268246295, + -14.044928083308072, + -16.96864982088579, + -13.534102459542082, + -5.933199999999999, + -8.221882187825054, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -11.965486541628238, + -8.3568234213711, + -5.933199999999999, + -50.45110598429169, + -34.55874369607228, + -13.351780902748127, + -41.59919918020033, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -15.143540371976181, + -5.933199999999999, + -20.46533109470986, + -5.933199999999999, + -8.221882187825054, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -46.01364002009045, + -14.450393191416238, + -5.933199999999999, + -22.202746182236858, + -14.450393191416238, + -9.736368600516062, + -12.946315794639963, + -26.610029777914313, + -5.933199999999999, + -10.780446842742203, + -5.933199999999999, + -21.782019528510688, + -41.34965749545595, + -8.3568234213711, + -27.94445864611662, + -5.933199999999999, + -147.4766901303839, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -11.27233936106829, + -8.221882187825054, + -5.933199999999999, + -21.581292021712585, + -5.933199999999999, + -5.933199999999999, + -30.791632393688765, + -14.044928083308072, + -15.169268520548913, + -8.828182370453847, + -5.933199999999999, + -5.933199999999999, + -27.463902163908486, + -5.933199999999999, + -5.933199999999999, + -8.221882187825054, + -8.828182370453847, + -12.391014060773454, + -10.654904002244042, + -5.933199999999999, + -9.439757897319982, + -15.143540371976181, + -12.256072827227408, + -16.08514891183463, + -21.175826913604418, + -20.06090939180249, + -5.933199999999999, + -22.156656166616145, + -14.450393191416238, + -5.933199999999999, + -5.933199999999999, + -13.135567979515546, + -9.1446038100295, + -20.88194965879761, + -28.188942708244383, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -13.534102459542082, + -5.933199999999999, + -13.161987331115471, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -16.98050643404232, + -5.933199999999999, + -15.143540371976181, + -15.143540371976181, + -15.143540371976181, + -5.933199999999999, + -13.534102459542082, + -5.933199999999999, + -5.933199999999999, + -9.736368600516062, + -10.223559446148057, + -33.106543136373446, + -5.933199999999999, + -9.736368600516062, + -13.757246010856292, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -17.256331893337574, + -123.50370689687801, + -5.933199999999999, + -19.855845981172337, + -5.933199999999999, + -5.933199999999999, + -13.064098830296345, + -13.534102459542082, + -5.933199999999999, + -5.933199999999999, + -15.143540371976181, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -20.71944427614399, + -5.933199999999999, + -10.700889115485865, + -5.933199999999999, + -8.828182370453847, + -5.933199999999999, + -19.579578811535853, + -29.980702177472438, + -29.674017724306967, + -5.933199999999999, + -17.344590140394303, + -17.23667524078802, + -30.921676645499105, + -9.498093474332943, + -9.1446038100295, + -14.450393191416238, + -14.849005699808707, + -5.933199999999999, + -16.87401661278734, + -5.933199999999999, + -14.044928083308072, + -5.933199999999999, + -5.933199999999999, + -10.700889115485865, + -8.828182370453847, + -5.933199999999999, + -12.64718286751916, + -14.450393191416238, + -5.933199999999999, + -12.504483042360924, + -5.933199999999999, + -9.059040958901011, + -21.773412755751487, + -12.658633722188181, + -5.933199999999999, + -13.534102459542082, + -5.933199999999999, + -5.933199999999999, + -19.384067444376363, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -15.143540371976181, + -12.840955278982136, + -11.811335861800977, + -20.616211125668997, + -5.933199999999999, + -8.221882187825054, + -24.353880743952363, + -5.933199999999999, + -14.41863318254062, + -21.306069257277393, + -13.905862035185075, + -15.143540371976181, + -13.064098830296345, + -9.95058352108597, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -11.723164740907695, + -16.659943418443092, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -34.970189101419194, + -15.359211908451691, + -12.578591014514647, + -27.569172997489215, + -5.933199999999999, + -27.32589649088904, + -5.933199999999999, + -15.143540371976181, + -5.933199999999999, + -10.510564375650109, + -5.933199999999999, + -5.933199999999999, + -11.482664380272112, + -43.043065310950176, + -18.983212948825884, + -15.663911408585705, + -5.933199999999999, + -12.658633722188181, + -5.933199999999999, + -13.06298694866589, + -20.226746358907274, + -11.454660917862245, + -15.07986428825587, + -12.894102923193028, + -9.95058352108597, + -9.439757897319982, + -5.933199999999999, + -5.933199999999999, + -16.180869432227393, + -5.933199999999999, + -8.3568234213711, + -12.840955278982136, + -10.223559446148057, + -16.333610271133125, + -24.26294374896026, + -5.933199999999999, + -22.56212127472431, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -17.97175937959917, + -27.110838823652077, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -8.828182370453847, + -5.933199999999999, + -57.611723293400985, + -18.46777671250221, + -5.933199999999999, + -25.29365895987609, + -9.059040958901011, + -11.756022800370584, + -29.16977196125611, + -9.1446038100295, + -29.42540044360593, + -5.933199999999999, + -13.534102459542082, + -5.933199999999999, + -5.933199999999999, + -21.865978585184564, + -9.120092779015149, + -21.714823414337104, + -5.933199999999999, + -5.933199999999999, + -13.197630222920868, + -5.933199999999999, + -13.351780902748127, + -9.736368600516062, + -5.933199999999999, + -17.106705576945078, + -24.804552444898608, + -37.946247750602424, + -5.933199999999999, + -5.933199999999999, + -24.004915443083686, + -22.066815462616354, + -13.197630222920868, + -30.29775273861439, + -14.044928083308072, + -26.152829465054964, + -5.933199999999999, + -13.197630222920868, + -15.143540371976181, + -5.933199999999999, + -16.468551504679173, + -5.933199999999999, + -27.664383681154852, + -31.158644079010628, + -11.744983139108403, + -36.25557934492745, + -5.933199999999999, + -49.99072466659097, + -5.933199999999999, + -15.143540371976181, + -13.064098830296345, + -11.049195809754082, + -12.025050788341117, + -11.863381318691083, + -13.757246010856292, + -14.450393191416238, + -13.197630222920868, + -24.529586473671728, + -20.179493474056727, + -13.595871485939714, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -20.73422275888038, + -36.089949760236806, + -29.38003584970666, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -10.645505609196155, + -12.099017934252759, + -5.933199999999999, + -8.839091569554201, + -13.064098830296345, + -13.757246010856292, + -19.177731011378533, + -9.967390639402353, + -13.064098830296345, + -14.81711847120847, + -19.517598837000886, + -18.05416598135485, + -5.933199999999999, + -8.3568234213711, + -71.82920507021916, + -15.143540371976181, + -24.551478388298836, + -5.933199999999999, + -14.450393191416238, + -14.055917435657175, + -5.933199999999999, + -11.99500976116952, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -8.221882187825054, + -22.967586382832476, + -10.510564375650109, + -13.757246010856292, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -9.1446038100295, + -5.933199999999999, + -5.933199999999999, + -13.124512536856967, + -27.223861812200795, + -9.059040958901011, + -5.933199999999999, + -14.450393191416238, + -24.353880743952363, + -5.933199999999999, + -8.828182370453847, + -13.534102459542082, + -14.74449583167094, + -5.933199999999999, + -29.722152873027675, + -12.050495379583701, + -5.933199999999999, + -5.933199999999999, + -23.756583889049253, + -24.580279587987246, + -5.933199999999999, + -12.253168614080018, + -5.933199999999999, + -5.933199999999999, + -9.439757897319982, + -14.044928083308072, + -14.044928083308072, + -9.059040958901011, + -9.967390639402353, + -5.933199999999999, + -5.933199999999999, + -8.839091569554201, + -10.347749826379442, + -17.501559315409555, + -5.933199999999999, + -9.768261964292018, + -10.223559446148057, + -13.7433431056873, + -13.351780902748127, + -9.059040958901011, + -16.96864982088579, + -5.933199999999999, + -5.933199999999999, + -15.143540371976181, + -5.933199999999999, + -5.933199999999999, + -27.570561306423254, + -5.933199999999999, + -13.351780902748127, + -5.933199999999999, + -35.844935134104425, + -14.044928083308072, + -12.27044476893051, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -12.658633722188181, + -5.933199999999999, + -9.439757897319982, + -10.654904002244042, + -12.578591014514647, + -5.933199999999999, + -5.933199999999999, + -8.828182370453847, + -15.143540371976181, + -28.213690877933576, + -12.658633722188181, + -13.197630222920868, + -5.933199999999999, + -5.933199999999999, + -6.632767748362867, + -5.933199999999999, + -5.933199999999999, + -15.143540371976181, + -13.351780902748127, + -13.534102459542082, + -62.934788829638215, + -9.498093474332943, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -28.979253637257976, + -17.567163793347284, + -5.933199999999999, + -24.163591017509233, + -12.663244334745865, + -5.933199999999999, + -8.828182370453847, + -14.044928083308072, + -12.191885385663118, + -5.933199999999999, + -13.534102459542082, + -13.757246010856292, + -10.645505609196155, + -55.84937796279696, + -34.69825073518582, + -76.10096692187626, + -14.853854200287849, + -53.60826822177667, + -32.61749443684523, + -12.80130677690877, + -24.218595638220364, + -24.22153389701365, + -36.683000204611915, + -32.913500820421774, + -20.52754361087198, + -44.70634548912971, + -28.256591602635567, + -58.50969239904996, + -15.958244664794588, + -66.12894249588776, + -51.25372516052484, + -12.214894292822251, + -28.246701266802717, + -35.894154142731495, + -8.48867221338714, + -18.863275621095337, + -13.290067514172351, + -52.660864608032476, + -42.40441520427778, + -40.548102753670186, + -25.254812459682825, + -15.430404866717492, + -45.186872614909994, + -22.739909537465063, + -35.85728843281065, + -30.354025829709784, + -29.5049855694772, + -32.51536944653815, + -20.05877912215112, + -18.011754569607117, + -21.321234723285706, + -30.380266230542993, + -18.974655595747638, + -26.54004909656336, + -36.15985626949495, + -37.27567581970422, + -34.000177935859924, + -62.71486986689645, + -27.666022508984742, + -20.105283744434995, + -48.10388463598747, + -13.553746091053831, + -20.059653260055715, + -58.059551013991424, + -22.658782739343398, + -15.501750299638164, + -79.33668863560045, + -33.2484782239141, + -47.1348857553314, + -31.768954077647518, + -38.412465971030535, + -22.841394413563382, + -45.21400307004691, + -28.098303567596417, + -34.074147404025354, + -62.911087726976334, + -28.30820560612739, + -20.205836427321444, + -123.49305209711616, + -34.68055785803702, + -53.020819803361135, + -31.51697398256433, + -25.98900586914036, + -33.28111951459837, + -33.84207670846479, + -36.95063510479951, + -43.11649950629672, + -32.44302518784926, + -27.531613354032437, + -19.31442306154974, + -22.873237433969248, + -31.42040703132838, + -72.90335702594108, + -5.933199999999999, + -8.839091569554201, + -16.25767247230233, + -5.933199999999999, + -5.933199999999999, + -11.965486541628238, + -13.197630222920868, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -8.839091569554201, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -8.221882187825054, + -5.933199999999999, + -9.95058352108597, + -5.933199999999999, + -13.374554940314482, + -5.933199999999999, + -9.059040958901011, + -5.933199999999999, + -14.044928083308072, + -5.933199999999999, + -9.332399378999481, + -5.933199999999999, + -13.757246010856292, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -13.534102459542082, + -8.221882187825054, + -5.933199999999999, + -16.477621861649137, + -14.706318232254826, + -5.933199999999999, + -12.099017934252759, + -11.262714990925303, + -11.35935073805792, + -18.03852274243003, + -5.933199999999999, + -5.933199999999999, + -11.954023329354857, + -48.4013829214248, + -24.206832748574673, + -5.933199999999999, + -5.933199999999999, + -14.044928083308072, + -20.95268336229021, + -5.933199999999999, + -25.643411436639948, + -17.774994598570977, + -11.347723146726064, + -14.044928083308072, + -12.191885385663118, + -13.757246010856292, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -20.373240670976056, + -49.26294875360971, + -9.967390639402353, + -5.933199999999999, + -5.933199999999999, + -8.221882187825054, + -5.933199999999999, + -15.768101128971276, + -5.933199999999999, + -19.843021237435515, + -9.1446038100295, + -10.654904002244042, + -27.390435012026607, + -5.933199999999999, + -5.933199999999999, + -22.562121274724312, + -5.933199999999999, + -5.933199999999999, + -18.467776712502207, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -8.828182370453847, + -9.120092779015149, + -11.482664380272112, + -5.933199999999999, + -5.933199999999999, + -22.780432959994194, + -5.933199999999999, + -5.933199999999999, + -24.742882617865515, + -14.044928083308072, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -14.044928083308072, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -8.839091569554201, + -12.310327027919966, + -5.933199999999999, + -21.722582005949292, + -5.933199999999999, + -31.484779574248712, + -12.93418779702121, + -12.370951649736401, + -9.967390639402353, + -16.452873691959944, + -5.933199999999999, + -5.933199999999999, + -17.6855226109843, + -5.933199999999999, + -8.3568234213711, + -5.933199999999999, + -5.933199999999999, + -24.366896928134636, + -25.395141376735538, + -14.026728046664122, + -17.82446190569014, + -8.3568234213711, + -30.03720198471192, + -5.933199999999999, + -5.933199999999999, + -24.36271969261957, + -5.933199999999999, + -9.736368600516062, + -5.933199999999999, + -10.347749826379442, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -12.565598856220992, + -21.868974094164365, + -5.933199999999999, + -8.839091569554201, + -13.534102459542082, + -5.933199999999999, + -29.481291456521745, + -5.933199999999999, + -19.29764003415844, + -13.351780902748128, + -14.450393191416238, + -5.933199999999999, + -19.911229487462048, + -9.1446038100295, + -17.2908966237108, + -5.933199999999999, + -5.933199999999999, + -24.57353040601232, + -14.044928083308072, + -30.890789965221984, + -5.933199999999999, + -13.197630222920868, + -11.61717984736002, + -5.933199999999999, + -17.567163793347284, + -5.933199999999999, + -5.933199999999999, + -26.983505143870083, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -9.120092779015149, + -5.933199999999999, + -5.933199999999999, + -12.025050788341117, + -11.118188681241033, + -9.498093474332943, + -30.579072628536295, + -24.349222512043465, + -17.289723299999302, + -44.06887529325659, + -31.62538264775476, + -9.43815245963528, + -22.462471035869445, + -79.4514414084134, + -9.908991818018414, + -43.383208065415076, + -52.67290220912524, + -66.00941232704625, + -26.881501889132128, + -28.207351553415023, + -17.809159071530935, + -32.08454195679115, + -58.714665307496674, + -46.0378645989601, + -31.30475871435808, + -18.152956809509316, + -45.45311736666041, + -17.882817425374192, + -24.483188044189415, + -14.947054473986016, + -21.79050649602994, + -27.12803584606048, + -30.932870620634645, + -41.05544678241546, + -16.490586872863165, + -18.688758114373233, + -23.63649145426575, + -43.59367489659099, + -25.323023671100458, + -29.049747129955943, + -23.907947326542004, + -22.971285121209938, + -17.500506332549435, + -69.05582193208582, + -34.213169435173626, + -47.879896785380424, + -130.84425313900135, + -16.845339608228656, + -37.454732780076455, + -52.92956128527791, + -31.73255378813156, + -19.729904112716714, + -51.25974112186077, + -52.090496063609606, + -14.013713427521708, + -23.483120693739455, + -61.50422950459838, + -58.016329983783045, + -26.18711578199096, + -16.09065950253464, + -13.799136823726334, + -35.73018064230587, + -19.1831136884128, + -49.25426748235762, + -25.88982555460225, + -51.342155347964635, + -41.08533536625632, + -38.1041034705359, + -22.120556764002362, + -29.993048340752168, + -13.113023746536681, + -27.696046791127618, + -28.458461442287838, + -20.086563369236693, + -16.74959796835136, + -55.756623037580304, + -13.504820480438255, + -23.359302961650837, + -25.210984165118653, + -22.287588366033397, + -28.466508835979674, + -35.28946517318592, + -54.853849120609546, + -30.86845254483868, + -18.03410298589421, + -29.927111515541817, + -16.69800086078497, + -32.722725120712546, + -33.518982470004, + -23.69856310999051, + -26.520496814088542, + -11.842665391093439, + -33.83711549678148, + -17.314256139726567, + -35.027412357702644, + -33.78333417387126, + -24.746785984014274, + -33.7966601955819, + -36.74790467249763, + -124.90186363344358, + -16.774358632529037, + -5.933199999999999, + -5.933199999999999, + -15.567411430088498, + -5.933199999999999, + -28.62076034751246, + -5.933199999999999, + -5.933199999999999, + -12.504483042360924, + -15.143540371976181, + -12.74564509917781, + -14.526302785516586, + -5.933199999999999, + -15.143540371976181, + -10.23088548624013, + -14.044928083308072, + -5.933199999999999, + -5.933199999999999, + -45.191435727300906, + -14.450393191416238, + -8.221882187825054, + -27.225627037725364, + -5.933199999999999, + -21.58129202171258, + -9.439757897319982, + -5.933199999999999, + -8.3568234213711, + -5.933199999999999, + -5.933199999999999, + -8.3568234213711, + -12.623934433233956, + -21.792013053028235, + -5.933199999999999, + -5.933199999999999, + -9.120092779015149, + -11.742342990314027, + -7.144533158732228, + -21.30935830622894, + -13.534102459542082, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -20.36489669738809, + -18.180094640050427, + -8.828182370453847, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -23.66073356339242, + -8.828182370453847, + -5.933199999999999, + -37.80474818832873, + -17.43815729532105, + -5.933199999999999, + -24.353880743952363, + -13.757246010856292, + -14.450393191416238, + -14.044928083308072, + -8.3568234213711, + -5.933199999999999, + -5.933199999999999, + -20.07721462493631, + -41.82066694936634, + -9.768261964292018, + -5.933199999999999, + -15.436167986820976, + -12.946315794639963, + -5.933199999999999, + -84.44423671311176, + -9.498093474332943, + -10.510564375650109, + -11.116864558278902, + -15.149960939779106, + -9.059040958901011, + -5.933199999999999, + -18.946708972492246, + -5.933199999999999, + -15.310722876703032, + -25.060721251644313, + -14.793165230185977, + -5.933199999999999, + -71.49331645274094, + -15.143540371976181, + -8.221882187825054, + -11.35935073805792, + -14.450393191416238, + -14.450393191416238, + -5.933199999999999, + -5.933199999999999, + -11.5682272314006, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -24.959487102703328, + -12.477277909352619, + -8.221882187825054, + -5.933199999999999, + -24.5309609499377, + -51.232183602642664, + -86.68396261390504, + -145.14864469970865, + -36.51568474861802, + -44.78662454787954, + -25.250364632397847, + -66.25863278205793, + -65.14594688429482, + -17.918222213081158, + -46.953734834839935, + -36.99485404210236, + -44.7182110282568, + -33.70715263125915, + -21.654062607349825, + -20.76352986189402, + -30.769628284065558, + -25.938962782437798, + -36.42005447730189, + -21.457105957326867, + -76.04792001201888, + -22.965955828483995, + -61.56665745699768, + -50.44970414320315, + -29.061453099862902, + -66.71436709509885, + -26.609895068863324, + -18.712837121439275, + -27.647148858505147, + -44.4501258209554, + -40.407082279209064, + -22.91985616735858, + -99.12360510530372, + -22.530141542630904, + -44.14825938866003, + -35.54797540995706, + -14.891776959656669, + -42.31802782410279, + -27.93478313874065, + -19.613612824977082, + -24.241533013646855, + -20.954011708713054, + -22.53717901986014, + -37.157439627230325, + -23.609268616292365, + -38.16408337808439, + -22.787581510714272, + -30.97671050812875, + -31.754534651778915, + -19.443312825992834, + -21.03888056234954, + -35.47249622335262, + -26.608949075192765, + -37.085410905402966, + -28.21059294332133, + -24.63316241006898, + -41.368154496271885, + -33.080633947618225, + -55.08323143303595, + -22.170737880964925, + -23.750963094430507, + -39.945653040247706, + -30.56189314791351, + -35.08219340385603, + -43.514950612794365, + -35.465056276647566, + -18.154475709819838, + -11.450610415009601, + -15.353603563947791, + -31.884473104356786, + -35.49074149259093, + -17.83338420230195, + -22.327133250615624, + -16.260197953074467, + -17.292239830347306, + -22.593656892968447, + -25.474996184328923, + -33.73177502709159, + -15.60277098533934, + -24.184479127632706, + -13.033206492621368, + -14.812926969722826, + -11.293336430891312, + -44.56107272364741, + -39.801231255539626, + -21.40764570490923, + -31.074557746116266, + -46.65532157168396, + -62.61058178526684, + -20.093403019877236, + -33.05959867250098, + -8.828182370453847, + -12.184881917802022, + -14.044928083308072, + -10.654904002244042, + -27.637295089958137, + -12.435490170873972, + -8.828182370453847, + -13.832398388211306, + -11.482664380272112, + -9.736368600516062, + -5.933199999999999, + -15.143540371976181, + -42.298394491289265, + -12.09901793425276, + -9.332399378999481, + -5.933199999999999, + -23.789500603589836, + -5.933199999999999, + -5.933199999999999, + -14.450393191416238, + -48.17823937011059, + -5.933199999999999, + -5.933199999999999, + -34.88971331506944, + -9.120092779015149, + -28.306725743900763, + -16.25767247230233, + -5.933199999999999, + -24.923041944731317, + -16.628992304629293, + -16.25767247230233, + -13.534102459542082, + -12.93418779702121, + -13.197630222920868, + -9.059040958901011, + -12.840955278982136, + -12.67415353384622, + -5.933199999999999, + -5.933199999999999, + -9.768261964292018, + -8.828182370453847, + -12.709497284362444, + -8.221882187825054, + -15.034327287002865, + -5.933199999999999, + -20.616211125668997, + -22.744442831518263, + -5.933199999999999, + -9.059040958901011, + -46.46204018401839, + -11.118188681241033, + -9.059040958901011, + -17.425837857256848, + -35.072909125262505, + -24.353880743952363, + -9.059040958901011, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -8.828182370453847, + -5.933199999999999, + -17.744539696074632, + -5.933199999999999, + -8.839091569554201, + -18.360838941366026, + -16.189939789197357, + -5.933199999999999, + -17.019291167226456, + -5.933199999999999, + -15.143540371976181, + -11.532622459331957, + -14.044928083308072, + -13.064098830296345, + -5.933199999999999, + -9.059040958901011, + -23.255268455284252, + -15.143540371976181, + -12.435490170873972, + -9.1446038100295, + -8.828182370453847, + -5.933199999999999, + -5.933199999999999, + -9.1446038100295, + -12.504483042360924, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -10.223559446148057, + -5.933199999999999, + -8.3568234213711, + -5.933199999999999, + -5.933199999999999, + -17.791436650258646, + -23.222156103834052, + -9.768261964292018, + -5.933199999999999, + -22.05129565095832, + -20.06090939180249, + -5.933199999999999, + -74.41242328952447, + -35.51316657211687, + -44.2595074101051, + -83.06726428420725, + -25.48388215886214, + -63.647590270954176, + -39.336285021153394, + -32.26441803476608, + -64.15329363554218, + -27.498426679456053, + -39.38864850567861, + -29.810094684210405, + -38.094012425571925, + -34.40786970098876, + -50.56618886348204, + -34.90380716604848, + -14.029448158182662, + -16.79934060210138, + -36.84162767360677, + -20.07270084028015, + -39.10015705455676, + -69.19247071467474, + -43.1882432726964, + -37.60507981633819, + -26.52018712647984, + -28.94085572302504, + -26.391958494591588, + -36.19079455943275, + -24.635724062913, + -19.911612893734258, + -11.774979327755515, + -22.368573436880745, + -116.78011094723594, + -31.733673636778885, + -22.436478519934695, + -35.63784747922995, + -20.214253572253504, + -29.426329566857056, + -30.638889315659, + -54.10850008029211, + -32.27803950235355, + -32.36175150331341, + -44.49662204412764, + -23.953173518586937, + -120.60337211262858, + -25.945707279070003, + -44.15068250096292, + -32.372662467358424, + -39.823469467070446, + -31.27063254415719, + -43.655268724544, + -35.16041918938949, + -17.91116315713284, + -61.024906510256564, + -16.736351367200676, + -31.13090820522084, + -18.170921037139607, + -11.969091833295153, + -29.84348541186721, + -23.509858380539924, + -23.783297041886033, + -39.65354900825756, + -43.888008691041435, + -47.22211486450516, + -24.810161487599064, + -30.93923641272792, + -83.62835318243249, + -27.358246090261446, + -37.85297757410684, + -40.14438929601775, + -24.479286311421745, + -69.31566668001949, + -15.487401935073834, + -31.693780037862197, + -30.959203451166395, + -27.228183310804873, + -74.80108112484146, + -49.34077475443571, + -10.5456697829234, + -50.65559143206254, + -10.632349643844838, + -11.234389933038615, + -43.364686677433205, + -17.19536456723953, + -26.74839128886176, + -36.54406140882396, + -30.562846795156315, + -17.73015181628972, + -80.59320897473857, + -31.047723200051323, + -26.074811529063567, + -35.83771715644671, + -37.65509456832401, + -28.13246011796207, + -36.22478794082332, + -18.078499999334973, + -19.556798454025127, + -25.406313440636495, + -20.507111770049388, + -24.611144176647414, + -20.37618790274414, + -34.740805328354604, + -44.384563735986596, + -37.79649708231728, + -27.704057413499186, + -31.178464369225892, + -38.66394010914074, + -13.663491233473653, + -38.307135862193824, + -22.76935120477017, + -38.46249620856473, + -43.51234976869911, + -28.950182892222657, + -28.3607310705095, + -43.97159105684386, + -22.75257568567894, + -17.784218010408562, + -149.3452459025305, + -56.46957200144996, + -31.59808234434876, + -29.718346725613554, + -37.355841664307704, + -35.984180433067365, + -15.43925831234424, + -31.19798233653725, + -40.675127162179194, + -34.477119671775135, + -43.655847632247976, + -28.244308570541925, + -40.723765641262275, + -22.92621582654997, + -16.37858754593358, + -55.33409710064268, + -56.809735804447776, + -100.8744053625779, + -34.14413298073704, + -50.137678679125436, + -39.25512454543701, + -6.779360886986492, + -143.17161268148257, + -26.295955150160463, + -23.002899973260757, + -46.85695696138138, + -21.79929063625989, + -28.763666754274638, + -263.5623420004458, + -53.736833809386646, + -21.970961769447754, + -36.36422751298453, + -40.529990525048895, + -30.722063865346986, + -15.88694324961416, + -46.77127320914147, + -22.847198642562613, + -18.684769044055102, + -24.794564672710862, + -44.3877295124198, + -33.98344703506437, + -33.66554656960753, + -30.923551154862054, + -10.813417744452723, + -19.910433113477957, + -26.46403820699077, + -35.18212261466801, + -39.59209254692428, + -35.121004759555944, + -10.132671457014663, + -36.11853381556596, + -33.945525098864685, + -30.705309465449186, + -17.966354570630337, + -49.153265963251684, + -60.70765977149428, + -21.646541489360327, + -18.537510922749036, + -24.98932013247729, + -49.98801745605407, + -35.28280523356706, + -37.0660695487627, + -20.211428873242735, + -22.363308459264182, + -19.979794330573455, + -50.10596706620086, + -38.124968597124926, + -20.3392194153185, + -51.68285455041179, + -42.61006254254595, + -155.19824609373, + -47.37826778471596, + -30.879488697478866, + -38.55902578802649, + -108.33226093214373, + -25.760586516693138, + -50.39369938616325, + -65.45493377294287, + -79.04664687058039, + -36.75306326480177, + -37.53283932683267, + -16.814425769026002, + -201.98911853909073, + -20.436786519818074, + -35.919635211631004, + -52.3311167765099, + -24.83664158907106, + -15.143907240146653, + -16.87315765251916, + -12.629075156184655, + -34.27055760803195, + -27.925762726297936, + -29.011464654892734, + -48.57695969746137, + -35.88427953677964, + -82.71346454117469, + -45.62745215667124, + -71.78333985797573, + -55.19699552959835, + -25.889460052762654, + -24.720144734128528, + -29.21172999576612, + -37.82811632446891, + -52.510719876137294, + -20.081063150097112, + -35.97185473916524, + -5.933199999999999, + -12.758279118813567, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -8.828182370453847, + -13.686338412296404, + -5.933199999999999, + -33.880738189828875, + -29.565944776752964, + -5.933199999999999, + -8.839091569554201, + -14.450393191416238, + -5.933199999999999, + -52.98792764328973, + -21.095784205930883, + -21.058043877948037, + -5.933199999999999, + -5.933199999999999, + -10.223559446148057, + -19.92306394510905, + -5.933199999999999, + -11.314898975487086, + -32.974436448363754, + -12.345649466874182, + -5.933199999999999, + -15.763994867142687, + -16.42908482999593, + -5.933199999999999, + -22.156656166616145, + -5.933199999999999, + -5.933199999999999, + -20.259536181730265, + -15.49387833704545, + -19.911229487462048, + -5.933199999999999, + -10.223559446148057, + -5.933199999999999, + -5.933199999999999, + -13.534102459542082, + -19.12277212709778, + -5.933199999999999, + -5.933199999999999, + -23.03111208371235, + -5.933199999999999, + -5.933199999999999, + -13.351780902748127, + -9.498093474332943, + -13.757246010856292, + -12.578591014514647, + -5.933199999999999, + -19.898503745466073, + -41.760690479936606, + -5.933199999999999, + -42.14768087961505, + -14.450393191416238, + -5.933199999999999, + -42.814966902539766, + -11.347723146726064, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -44.08389480788849, + -24.708595239398072, + -5.933199999999999, + -9.498093474332943, + -5.933199999999999, + -5.933199999999999, + -11.965486541628238, + -12.4486159380929, + -5.933199999999999, + -15.034327287002865, + -36.196927182383675, + -14.044928083308072, + -11.25180579182495, + -14.676792035451118, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -8.221882187825054, + -5.933199999999999, + -19.63538187265727, + -25.886357615250336, + -21.868974094164365, + -5.933199999999999, + -14.044928083308072, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -15.822784647367136, + -9.95058352108597, + -16.333610271133125, + -5.933199999999999, + -5.933199999999999, + -13.351780902748127, + -15.143540371976181, + -5.933199999999999, + -19.444565251317478, + -12.015075149468997, + -5.933199999999999, + -12.310327027919966, + -5.933199999999999, + -5.933199999999999, + -9.967390639402353, + -15.932537878192962, + -5.933199999999999, + -5.933199999999999, + -21.868974094164365, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -8.3568234213711, + -21.358148470398373, + -32.46560882726043, + -5.933199999999999, + -5.933199999999999, + -16.858338800068108, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -18.9786023362682, + -15.496792608637412, + -5.933199999999999, + -13.124512536856967, + -8.828182370453847, + -5.933199999999999, + -15.143540371976181, + -20.743079054277985, + -5.933199999999999, + -10.510564375650109, + -5.933199999999999, + -5.933199999999999, + -8.3568234213711, + -20.754056572362433, + -15.143540371976181, + -5.933199999999999, + -12.74564509917781, + -8.828182370453847, + -5.933199999999999, + -8.828182370453847, + -5.933199999999999, + -5.933199999999999, + -9.120092779015149, + -8.3568234213711, + -13.534102459542082, + -30.986086452540547, + -5.933199999999999, + -9.768261964292018, + -9.498093474332943, + -5.933199999999999, + -16.939910453761918, + -29.82655149764518, + -17.614775149198326, + -5.933199999999999, + -5.933199999999999, + -16.27055213516599, + -5.933199999999999, + -70.59900767633454, + -13.648032925882974, + -5.933199999999999, + -5.933199999999999, + -23.720488663352576, + -8.3568234213711, + -12.14780809842219, + -32.71590263369591, + -15.822784647367136, + -8.3568234213711, + -6.632767748362867, + -17.661797001445738, + -15.502150844986247, + -5.933199999999999, + -15.248900887634008, + -5.933199999999999, + -14.044928083308072, + -9.498093474332943, + -14.583615443258267, + -19.467356507273472, + -28.172637475110562, + -16.420976489626334, + -13.351780902748127, + -9.95058352108597, + -18.9786023362682, + -5.933199999999999, + -13.534102459542082, + -17.59230797514831, + -22.562121274724312, + -26.2918227233585, + -8.3568234213711, + -9.059040958901011, + -13.757246010856292, + -21.562666557589417, + -14.450393191416238, + -5.933199999999999, + -9.059040958901011, + -11.118188681241033, + -15.143540371976181, + -9.439757897319982, + -8.221882187825054, + -15.143540371976181, + -13.434963256177557, + -5.933199999999999, + -5.933199999999999, + -15.143540371976181, + -16.4381756832895, + -5.933199999999999, + -8.221882187825054, + -13.124512536856967, + -5.933199999999999, + -13.757246010856292, + -14.450393191416238, + -17.444747714504423, + -14.945477750037549, + -57.35114401465045, + -16.87401661278734, + -16.87176182040025, + -19.144862098134887, + -14.450393191416238, + -5.933199999999999, + -5.933199999999999, + -11.25180579182495, + -15.143540371976181, + -8.839091569554201, + -9.768261964292018, + -15.07986428825587, + -5.933199999999999, + -15.143540371976181, + -5.933199999999999, + -17.567163793347284, + -5.933199999999999, + -5.933199999999999, + -6.632767748362867, + -8.839091569554201, + -15.143540371976181, + -18.26938133087719, + -5.933199999999999, + -14.450393191416238, + -13.967967042171944, + -15.143540371976181, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -15.143540371976181, + -5.933199999999999, + -35.27169355583432, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -27.544950758482585, + -8.839091569554201, + -5.933199999999999, + -5.933199999999999, + -13.351780902748128, + -13.197630222920868, + -5.933199999999999, + -5.933199999999999, + -9.439757897319982, + -5.933199999999999, + -5.933199999999999, + -21.081881300761893, + -21.714823414337104, + -26.38130153678542, + -5.933199999999999, + -17.432222559801236, + -9.736368600516062, + -17.160194925557253, + -13.351780902748127, + -42.109813781866485, + -14.618147111361543, + -19.758760893817776, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -23.255268455284256, + -18.26938133087719, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -14.450393191416238, + -9.736368600516062, + -22.562121274724312, + -5.933199999999999, + -21.135004919084164, + -5.933199999999999, + -10.223559446148057, + -8.3568234213711, + -5.933199999999999, + -14.947480289071713, + -17.70988009554888, + -9.439757897319982, + -5.933199999999999, + -9.1446038100295, + -5.933199999999999, + -5.933199999999999, + -9.059040958901011, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -11.734073940008049, + -14.044928083308072, + -5.933199999999999, + -5.933199999999999, + -14.450393191416238, + -5.933199999999999, + -15.640463090573181, + -18.153880038071485, + -32.33682978810157, + -29.61631447989081, + -39.84534458284321, + -50.00619416368925, + -30.14722183792635, + -37.41548527758667, + -14.956817429962364, + -36.259023165932135, + -36.336881213370276, + -18.807058832472784, + -21.687663537202017, + -58.92022547552452, + -38.006933643438174, + -18.782275237563603, + -26.174109050621862, + -18.06948735250379, + -23.283343156957606, + -62.58401723369451, + -57.574203078940066, + -17.087247154378133, + -36.47530979654984, + -29.293208341549033, + -10.039968014721092, + -19.913185833211795, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -8.3568234213711, + -33.49599956983656, + -21.463508986056198, + -5.933199999999999, + -27.67989199202863, + -5.933199999999999, + -15.143540371976181, + -9.059040958901011, + -15.143540371976181, + -5.933199999999999, + -9.216614346005771, + -27.544950758482585, + -15.143540371976181, + -17.609821557641016, + -5.933199999999999, + -11.723164740907695, + -10.780446842742203, + -14.450393191416238, + -9.059040958901011, + -5.933199999999999, + -5.933199999999999, + -12.025050788341117, + -12.862209559417074, + -11.116864558278902, + -13.004651371652926, + -5.933199999999999, + -15.968878518220091, + -5.933199999999999, + -16.413652978806663, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -9.439757897319982, + -14.150918426895505, + -14.381940465781796, + -5.933199999999999, + -14.450393191416238, + -24.287197575484612, + -15.769417934937236, + -15.758333377788292, + -17.877563455738944, + -95.49139070204029, + -20.82934103407968, + -71.81365325248892, + -44.20705118906922, + -16.165522749544643, + -30.896087150941305, + -38.77708538379227, + -58.5412695062632, + -26.523259445791183, + -43.82710451328049, + -29.005005777724918, + -42.58131992508373, + -34.7686847512916, + -23.529710380444353, + -37.948075323285074, + -50.757016449670424, + -29.82371845031451, + -21.754455948868646, + -31.490460495885465, + -27.87423212247738, + -34.33123648855202, + -18.678555348721847, + -40.342736407385715, + -33.08771664312755, + -38.78558706597615, + -13.31682233654813, + -42.78709866376342, + -11.568445174434224, + -13.340997291427051, + -11.926158289154698, + -26.84879615010602, + -24.11424609457263, + -18.02588158876387, + -10.4639089913853, + -25.220218421908374, + -25.78160269407236, + -24.660440996062892, + -36.93863937806045, + -22.007232380090958, + -21.217284468236393, + -16.060016591672138, + -39.24536301368467, + -31.738173057098493, + -32.30808353110488, + -34.48732195666673, + -50.82254232281927, + -25.16278230379856, + -34.77050946850542, + -57.79550877341681, + -39.19834565304182, + -26.031494991075522, + -34.79509105437087, + -35.6864311865251, + -17.567163793347284, + -5.933199999999999, + -5.933199999999999, + -27.349613017506357, + -5.933199999999999, + -18.03852274243003, + -71.24491229457131, + -8.828182370453847, + -5.933199999999999, + -5.933199999999999, + -28.207667388956015, + -5.933199999999999, + -8.221882187825054, + -8.828182370453847, + -12.578591014514647, + -5.933199999999999, + -14.450393191416238, + -5.933199999999999, + -13.351780902748127, + -9.439757897319982, + -11.433285997854554, + -35.940078831041404, + -16.916674377081073, + -15.289722882154264, + -15.341381740428172, + -5.933199999999999, + -15.822784647367136, + -5.933199999999999, + -15.143540371976181, + -9.654602645819496, + -16.72099523855723, + -58.93787598538575, + -11.744983139108403, + -5.933199999999999, + -5.933199999999999, + -12.74564509917781, + -5.933199999999999, + -8.839091569554201, + -5.933199999999999, + -21.0058310065011, + -8.839091569554201, + -14.044928083308072, + -5.933199999999999, + -29.45443636921857, + -5.933199999999999, + -8.828182370453847, + -5.933199999999999, + -9.439757897319982, + -12.578591014514647, + -5.933199999999999, + -15.702232116970814, + -5.933199999999999, + -8.221882187825054, + -22.072713381832383, + -5.933199999999999, + -15.143540371976181, + -8.3568234213711, + -5.933199999999999, + -8.839091569554201, + -17.432222559801236, + -5.933199999999999, + -23.222156103834052, + -5.933199999999999, + -5.933199999999999, + -34.99092089168347, + -13.757246010856292, + -16.665378159933137, + -23.19463464762766, + -9.736368600516062, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -11.709553167491036, + -9.059040958901011, + -9.059040958901011, + -18.26938133087719, + -9.059040958901011, + -30.268384249924217, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -12.310327027919966, + -25.85487375148643, + -34.429870469491746, + -26.13000111121803, + -39.63344203543918, + -81.33688628264973, + -31.915050463943693, + -29.87452116355022, + -32.04328881642396, + -27.678936686312273, + -28.3009971910888, + -50.85218643088978, + -23.686803720837748, + -29.94033361842632, + -25.79776736530399, + -20.952164372903837, + -29.53253914721926, + -29.00083431363049, + -31.30865165891307, + -45.73130362846995, + -26.248265516763794, + -35.12845846389198, + -17.66269816771513, + -33.94831432401579, + -23.98116395200731, + -32.73608735264082, + -19.4311977551321, + -42.57524026012033, + -53.071980324040936, + -24.184912105803033, + -10.51363807677021, + -24.862558690277506, + -31.55822227205273, + -32.37233780252484, + -20.67406267460192, + -24.17643499986916, + -17.87010798669273, + -28.48785393112922, + -35.94452647615968, + -20.870918681777177, + -40.44738561778863, + -24.038625518087787, + -20.4922392109236, + -37.69351739205641, + -45.79172913397281, + -25.466086693648236, + -43.09622462211635, + -14.68933279661125, + -39.74197651024668, + -152.00257494358547, + -10.34282545026224, + -21.78086924693653, + -9.667790541626637, + -41.064080832966106, + -26.991556890820576, + -23.734738751794932, + -24.306195006549647, + -52.97434488692652, + -26.161953835569562, + -47.462472034883774, + -32.90670151902032, + -24.888979360197112, + -29.240008200845097, + -48.460958963289535, + -19.229858657336884, + -12.400888952771062, + -25.931410089467988, + -51.8160967069627, + -24.001085629226665, + -48.205981090708946, + -46.61774073253148, + -20.439276838295932, + -27.74806750511022, + -33.22912051205847, + -63.15059123836094, + -5.933199999999999, + -17.345375561870085, + -5.933199999999999, + -15.143540371976181, + -5.933199999999999, + -13.129451015702259, + -5.933199999999999, + -18.459477909687514, + -5.933199999999999, + -5.933199999999999, + -23.598040494053997, + -5.933199999999999, + -8.3568234213711, + -9.1446038100295, + -13.534642605394591, + -5.933199999999999, + -10.510564375650109, + -5.933199999999999, + -8.3568234213711, + -29.948361380177502, + -70.37166712612657, + -13.515476995418917, + -5.933199999999999, + -9.498093474332943, + -29.875341661814613, + -37.253100570042484, + -12.393075844786793, + -25.25626857065753, + -11.811335861800977, + -5.933199999999999, + -12.391014060773454, + -41.678826294107644, + -5.933199999999999, + -24.742882617865515, + -12.015075149468997, + -5.933199999999999, + -13.534102459542082, + -15.567411430088498, + -5.933199999999999, + -15.143540371976181, + -12.504483042360924, + -5.933199999999999, + -11.860068527623472, + -12.65116170734948, + -5.933199999999999, + -8.3568234213711, + -5.933199999999999, + -12.578591014514647, + -9.059040958901011, + -5.933199999999999, + -15.143540371976181, + -13.410452225163207, + -5.933199999999999, + -15.74374380689339, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -111.80071518071152, + -5.933199999999999, + -5.933199999999999, + -12.658633722188181, + -5.933199999999999, + -89.7921258755101, + -5.933199999999999, + -31.238036284386645, + -15.822784647367136, + -9.1446038100295, + -13.55915363640894, + -5.933199999999999, + -8.221882187825054, + -19.855845981172337, + -12.946315794639963, + -20.810275844277545, + -14.450393191416238, + -8.828182370453847, + -21.058043877948037, + -17.345375561870085, + -16.165191619508164, + -22.967586382832472, + -5.933199999999999, + -24.353880743952363, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -15.143540371976181, + -8.3568234213711, + -23.76431787964899, + -5.933199999999999, + -16.8830869697573, + -5.933199999999999, + -31.422686684982317, + -8.221882187825054, + -18.614693005722117, + -16.045928198681345, + -9.498093474332943, + -8.3568234213711, + -17.170769042209084, + -5.933199999999999, + -5.933199999999999, + -8.221882187825054, + -12.578591014514645, + -8.221882187825054, + -18.330433150991333, + -24.759577964256483, + -9.439757897319982, + -22.45307256880947, + -5.933199999999999, + -5.933199999999999, + -13.55915363640894, + -35.871063264206015, + -28.271272870147655, + -11.482664380272112, + -24.162266894547102, + -19.437884388326644, + -5.933199999999999, + -8.828182370453847, + -13.534102459542082, + -26.74202372530806, + -7.1686634714173065, + -5.933199999999999, + -13.064098830296345, + -21.868974094164365, + -13.351780902748127, + -5.933199999999999, + -97.64287521431223, + -5.933199999999999, + -16.94413878987144, + -30.500862904716108, + -5.933199999999999, + -14.044928083308072, + -12.27044476893051, + -5.933199999999999, + -12.658633722188181, + -11.293392770266124, + -22.967586382832472, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -17.95695108873622, + -5.933199999999999, + -16.045928198681345, + -30.46888334385561, + -8.221882187825054, + -16.939910453761918, + -5.933199999999999, + -12.946315794639963, + -28.188942708244383, + -21.30935830622894, + -5.933199999999999, + -23.63804391148677, + -22.156656166616145, + -13.351780902748127, + -5.933199999999999, + -9.967390639402353, + -12.840955278982136, + -11.744983139108403, + -9.439757897319982, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -14.044928083308072, + -9.498093474332943, + -12.047659641977617, + -13.539537201032127, + -14.450393191416238, + -5.933199999999999, + -5.933199999999999, + -14.450393191416238, + -5.933199999999999, + -5.933199999999999, + -14.044928083308072, + -5.933199999999999, + -13.197630222920868, + -5.933199999999999, + -8.828182370453847, + -15.133120705733546, + -8.3568234213711, + -19.999857571688352, + -5.933199999999999, + -15.705138133029363, + -31.88499132308038, + -29.312302477818484, + -16.509673492766833, + -25.97466461502021, + -72.4044690260372, + -71.92348511457763, + -22.572603136489377, + -25.151489671708244, + -27.717378453854604, + -21.528160424172235, + -19.034896103926624, + -5.933199999999999, + -24.480313596646727, + -11.543716200386251, + -9.498093474332943, + -5.933199999999999, + -5.933199999999999, + -11.677804469176454, + -5.933199999999999, + -8.3568234213711, + -5.933199999999999, + -13.064098830296345, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -9.059040958901011, + -12.840955278982136, + -5.933199999999999, + -5.933199999999999, + -13.064098830296345, + -17.487989669068927, + -5.933199999999999, + -14.450393191416238, + -16.333610271133125, + -5.933199999999999, + -5.933199999999999, + -19.520801009439346, + -16.80781997216899, + -159.019587144365, + -5.933199999999999, + -5.933199999999999, + -11.127773757379256, + -8.3568234213711, + -5.933199999999999, + -5.933199999999999, + -8.221882187825054, + -9.120092779015149, + -5.933199999999999, + -28.27016189104096, + -22.21938135332084, + -21.202353488049493, + -62.230965896975434, + -36.84747297352716, + -24.818614180381417, + -39.18023017359923, + -14.18389107779732, + -15.234454057209755, + -19.459583524358706, + -16.62304624281003, + -40.774396717202244, + -30.742084721476267, + -19.464074071436432, + -5.933199999999999, + -21.22056280744581, + -24.305062239871177, + -25.197821047248077, + -5.933199999999999, + -8.839091569554201, + -26.978060345773212, + -10.223559446148057, + -15.143540371976181, + -14.450393191416238, + -20.792418740570923, + -15.148150984533865, + -16.563184712777627, + -9.498093474332943, + -13.697457154665258, + -16.191069584351016, + -18.91146303343057, + -5.933199999999999, + -25.617229048679327, + -5.933199999999999, + -5.933199999999999, + -8.828182370453847, + -28.322474100868906, + -17.567163793347284, + -22.156656166616145, + -5.933199999999999, + -5.933199999999999, + -9.967390639402353, + -5.933199999999999, + -13.534102459542082, + -9.498093474332943, + -15.646397826092995, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -17.95285287619282, + -17.432222559801236, + -9.967390639402353, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -14.044928083308072, + -8.221882187825054, + -5.933199999999999, + -13.711165347993877, + -20.50486841708522, + -134.6962218559228, + -36.002614963272016, + -41.819641204410416, + -184.47071528577075, + -15.78811437245372, + -105.47271997370984, + -27.32235006753095, + -24.690073208496898, + -26.38275966572445, + -5.933199999999999, + -11.744983139108403, + -13.351780902748127, + -8.839091569554201, + -5.933199999999999, + -5.933199999999999, + -27.592959276138085, + -5.933199999999999, + -23.571644524637538, + -12.253168614080018, + -13.686338412296404, + -5.933199999999999, + -34.122566837139125, + -34.893589902334476, + -15.033356337814636, + -70.49344873539897, + -30.948916664239736, + -31.616853293430186, + -18.63400652410843, + -24.061205192349846, + -28.118529075156033, + -92.31259647386112, + -15.229861613167486, + -115.51558286439133, + -36.10904499028845, + -20.25962339844631, + -21.868974094164365, + -5.933199999999999, + -11.347723146726064, + -5.933199999999999, + -37.39928308022056, + -15.143540371976181, + -5.933199999999999, + -9.1446038100295, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -19.160923893062154, + -79.59850625134067, + -19.271746831487796, + -9.059040958901011, + -8.3568234213711, + -13.757246010856292, + -17.432222559801236, + -10.347749826379442, + -8.828182370453847, + -15.143540371976181, + -8.839091569554201, + -5.933199999999999, + -10.645505609196155, + -13.351780902748127, + -5.933199999999999, + -5.933199999999999, + -12.356007620059, + -5.933199999999999, + -16.8830869697573, + -5.933199999999999, + -5.933199999999999, + -15.932537878192962, + -13.197630222920868, + -5.933199999999999, + -13.534102459542082, + -5.933199999999999, + -15.755206999058482, + -10.510564375650109, + -5.933199999999999, + -52.942802036436824, + -40.298533165793586, + -23.591068021924656, + -16.208717095699463, + -23.979629842446943, + -40.14498028055918, + -40.25540632076597, + -22.733990139788183, + -40.08316505519017, + -14.430182871115065, + -48.317778953694635, + -46.89944587474559, + -22.49506478865864, + -19.49494438490067, + -21.30812293169598, + -659.4997252892381, + -35.03286719202803, + -33.729378892378826, + -14.190410204184813, + -36.90658374372765, + -22.739758268273242, + -27.9674618662032, + -34.871648363050745, + -22.18063383346221, + -46.67772160340751, + -27.22548751077961, + -26.813871680311973, + -30.77460831316028, + -35.9764890644427, + -16.215218563722573, + -47.89620834164433, + -47.92374665907207, + -29.1536526678301, + -13.249230637385393, + -27.199838876398893, + -34.433007937231054, + -28.15498221628437, + -20.787964125700526, + -22.524350325200945, + -18.803534911784922, + -16.919222128410993, + -31.25720452863649, + -17.173925702009065, + -46.89552391086265, + -26.92952212520398, + -18.22190315110329, + -25.477237309100463, + -43.350782900240674, + -33.98013464815339, + -23.125588476329902, + -25.837567451080904, + -5.933199999999999, + -5.933199999999999, + -21.820183929994933, + -15.143540371976181, + -19.72090474762629, + -9.768261964292018, + -8.839091569554201, + -19.990787214718384, + -14.730608979401401, + -12.946315794639963, + -15.143540371976181, + -5.933199999999999, + -8.828182370453847, + -13.337877997579136, + -5.933199999999999, + -53.14673366539534, + -5.933199999999999, + -8.828182370453847, + -40.95690220965001, + -81.96898538032028, + -31.01294105723432, + -9.32543158957116, + -31.79869220389465, + -42.80427005466703, + -49.28032659093604, + -40.97556362547349, + -59.86271758923986, + -36.8027877753416, + -25.2136678592481, + -33.56695498358556, + -5.933199999999999, + -20.888144841152638, + -8.221882187825054, + -9.498093474332943, + -5.933199999999999, + -17.567163793347284, + -5.933199999999999, + -5.933199999999999, + -13.534102459542082, + -19.874541390439994, + -5.933199999999999, + -5.933199999999999, + -14.044928083308072, + -5.933199999999999, + -5.933199999999999, + -23.592280837757976, + -27.32589649088904, + -14.450393191416238, + -5.933199999999999, + -5.933199999999999, + -8.3568234213711, + -18.812617198793937, + -5.933199999999999, + -10.654904002244042, + -5.933199999999999, + -17.50062575518132, + -8.839091569554201, + -15.715886852390422, + -13.351780902748127, + -5.933199999999999, + -5.933199999999999, + -5.933199999999999, + -9.498093474332943, + -8.828182370453847, + -5.933199999999999, + -8.3568234213711, + -22.744442831518263, + -42.588746041856524, + -5.933199999999999, + -23.08998003104654, + -14.329592491270532, + -19.010446619604885, + -12.435490170873972, + -14.450393191416238, + -5.933199999999999, + -32.995774677514156, + -20.172534983729104, + -18.486965945059154, + -42.732226792273075, + -41.28010407876353, + -31.115331203697004, + -54.45685509209371, + -27.33301704583675, + -20.939727529683665, + -22.181108686635355, + -5.933199999999999, + -5.933199999999999, + -8.3568234213711, + -25.237287721931317, + -21.868974094164365, + -5.933199999999999, + -13.078527423615144, + -9.768261964292018, + -13.093231598303365, + -29.246733002392237, + -79.24064293677338, + -18.037398245919036, + -23.29573123655846, + -22.72054367611021, + -34.70037758796859, + -30.998777480369657, + -29.028359465284243, + -41.575514193535604, + -32.69746083602197, + -43.39451065509535, + -5.933199999999999, + -5.933199999999999, + -50.05861149769525, + -5.933199999999999, + -18.542739750975663, + -19.72090474762629, + -5.933199999999999, + -19.709489844810992, + -58.802396793491745, + -34.646566432132786, + -21.714823414337108, + -16.584167589644274, + -8.3568234213711, + -5.933199999999999, + -5.933199999999999, + -12.504483042360924, + -12.840955278982136, + -9.768261964292018, + -18.015286665749183, + -12.578591014514647 + ], + "status": "normal", + "min_mw": 4.95, + "type": "CatalogPseudolikelihoodTestResult" +} \ No newline at end of file diff --git a/tests/artifacts/example_csep2_forecasts/Results/catalog_m_test.json b/tests/artifacts/example_csep2_forecasts/Results/catalog_m_test.json new file mode 100644 index 00000000..f35388ae --- /dev/null +++ b/tests/artifacts/example_csep2_forecasts/Results/catalog_m_test.json @@ -0,0 +1,7411 @@ +{ + "name": "Catalog M-Test", + "sim_name": "ucerf3-landers", + "obs_name": null, + "obs_catalog_repr": "\n Name: None\n\n Start Date: 1992-06-28 12:00:45+00:00\n End Date: 1992-07-24 18:14:36.250000+00:00\n\n Latitude: (33.901, 36.705)\n Longitude: (-118.067, -116.285)\n\n Min Mw: 4.95\n Max Mw: 6.3\n\n Event Count: 19\n ", + "quantile": [ + 0.6626098715348209, + 0.3373901284651792 + ], + "observed_statistic": 0.8674796893735761, + "test_distribution": [ + 3.0197310759414897, + 1.3611333024799808, + 1.2440016426024894, + 2.597485654058433, + 1.8476743345236084, + 2.8380026136553065, + 2.2619882652122514, + 3.115812494737077, + 2.4422042700327533, + 1.662580227087135, + 2.2619882652122514, + 1.8476743345236084, + 2.508868107616188, + 1.7715390054014857, + 1.8476743345236084, + 2.597485654058433, + 1.6863317636107102, + 2.8380026136553065, + 2.7676757380202464, + 1.9227572700113216, + 1.7422464799820194, + 1.6863317636107102, + 2.7676757380202464, + 2.2810904181711433, + 2.597485654058433, + 0.9224802965723984, + 1.5211271812256442, + 3.2090900715462665, + 2.08325008034921, + 2.2619882652122514, + 2.4422042700327533, + 1.4950262041145155, + 2.058150606944274, + 2.482270985196589, + 1.3611333024799808, + 1.8660595925061179, + 2.2619882652122514, + 1.3611333024799808, + 1.7844618810384465, + 2.597485654058433, + 1.3611333024799808, + 2.08325008034921, + 2.5065786589076757, + 2.340817939335098, + 2.264515291401005, + 2.1158858357860773, + 2.1808240605894347, + 1.8476743345236084, + 1.8476743345236084, + 2.058150606944274, + 3.5659509171218624, + 2.2619882652122514, + 2.2619882652122514, + 2.4422042700327533, + 2.356505525463452, + 2.7676757380202464, + 2.2511133880306673, + 1.8476743345236084, + 3.469823829994782, + 1.8277848094722016, + 1.8476743345236084, + 0.8574367262233663, + 2.058150606944274, + 1.3263908238301663, + 1.946967144999608, + 1.6025274431324954, + 2.5065786589076757, + 2.015619478204368, + 2.597485654058433, + 1.949666463423513, + 2.891988316701276, + 1.8476743345236084, + 2.3469857869408033, + 1.7844618810384465, + 2.08325008034921, + 2.4422042700327533, + 2.2619882652122514, + 1.7524135144562667, + 1.8277848094722016, + 1.565030805840658, + 1.6998171554110524, + 3.582079689185183, + 1.6315534406617571, + 0.9225145384731542, + 1.8476743345236084, + 1.3611333024799808, + 1.8476743345236084, + 2.4422042700327533, + 2.597485654058433, + 1.5211271812256442, + 3.0197310759414897, + 1.5660671707880502, + 1.390835498459361, + 1.6038996396013907, + 3.0197310759414897, + 3.314160295599997, + 1.3611333024799808, + 3.384015286101267, + 2.1808240605894347, + 0.8148350362682613, + 2.1703581637338116, + 1.7844618810384465, + 1.8476743345236084, + 2.1913009430783856, + 1.8476743345236084, + 1.8354417509053258, + 2.4422042700327533, + 1.8476743345236084, + 3.314160295599997, + 1.9180454979641435, + 1.310335600241959, + 2.434872226690443, + 2.4422042700327533, + 1.8476743345236084, + 2.2619882652122514, + 3.2090900715462665, + 1.8476743345236084, + 1.3611333024799808, + 2.058150606944274, + 2.2619882652122514, + 1.3611333024799808, + 2.058150606944274, + 2.1158858357860773, + 2.4422042700327533, + 1.662580227087135, + 2.058150606944274, + 1.8476743345236084, + 2.08325008034921, + 1.8277848094722016, + 1.8476743345236084, + 2.2619882652122514, + 1.8476743345236084, + 2.8121133109812453, + 2.058150606944274, + 2.058150606944274, + 3.0467555261647976, + 2.2810904181711433, + 1.8476743345236084, + 2.3846970049563643, + 2.2619882652122514, + 2.891988316701276, + 2.2619882652122514, + 1.7690867232190706, + 3.0197310759414897, + 1.1106054087113804, + 2.058150606944274, + 1.8476743345236084, + 2.4422042700327533, + 1.8476743345236084, + 2.2619882652122514, + 2.597485654058433, + 2.1158858357860773, + 2.597485654058433, + 3.01099170118784, + 0.958854863063285, + 1.4110227771922441, + 2.2511133880306673, + 2.3846970049563643, + 1.8277848094722016, + 1.0497734153137577, + 2.482270985196589, + 1.8476743345236084, + 1.662580227087135, + 2.4449473274705875, + 1.7474767939433504, + 1.8808086742650336, + 1.662580227087135, + 2.1703581637338116, + 2.1158858357860773, + 1.8476743345236084, + 2.058150606944274, + 2.3469857869408033, + 2.4422042700327533, + 2.058150606944274, + 2.7676757380202464, + 2.7623991597968542, + 3.384015286101267, + 2.597485654058433, + 2.2619882652122514, + 1.8476743345236084, + 1.4826676654967779, + 1.8476743345236084, + 2.5572779544191317, + 2.2619882652122514, + 1.8476743345236084, + 1.8476743345236084, + 2.2619882652122514, + 2.597485654058433, + 2.058150606944274, + 1.8476743345236084, + 1.328343782877219, + 2.4018155518380553, + 2.2619882652122514, + 1.8476743345236084, + 2.597485654058433, + 2.4714766335579115, + 1.7953351261557207, + 1.3611333024799808, + 2.2619882652122514, + 1.8476743345236084, + 2.5825373427782976, + 1.2653775983549835, + 2.2619882652122514, + 1.4896003123516497, + 2.2004615368404865, + 2.340817939335098, + 1.8476743345236084, + 2.015619478204368, + 1.897479690465043, + 2.2619882652122514, + 1.8189951082469618, + 3.5659509171218624, + 1.8476743345236084, + 1.3611333024799808, + 1.662580227087135, + 1.6863317636107102, + 1.4907079969402144, + 1.8476743345236084, + 3.1481561191964627, + 1.8476743345236084, + 2.058150606944274, + 1.8476743345236084, + 1.8476743345236084, + 1.9180454979641435, + 1.662580227087135, + 2.058150606944274, + 3.0197310759414897, + 1.9180454979641435, + 2.2619882652122514, + 1.8476743345236084, + 2.058150606944274, + 3.314160295599997, + 2.4422042700327533, + 2.058150606944274, + 2.2619882652122514, + 1.4548600830007987, + 3.2090900715462665, + 2.264515291401005, + 2.1913009430783856, + 2.2619882652122514, + 1.487791829283236, + 2.2619882652122514, + 2.891988316701276, + 1.8476743345236084, + 1.8476743345236084, + 3.1656983213520453, + 2.2619882652122514, + 1.5533888185231057, + 1.987778688217865, + 2.058150606944274, + 2.058150606944274, + 0.6324016801989464, + 1.8476743345236084, + 2.4422042700327533, + 1.8476743345236084, + 2.434872226690443, + 3.0197310759414897, + 0.5024432748080659, + 0.7788435328857765, + 0.32613235189138823, + 0.8182627053432353, + 0.48404041473392084, + 1.8033586059565487, + 0.8743173790696852, + 0.8969148377232131, + 0.25096668664199384, + 0.5665607182479243, + 0.5696721479042691, + 0.3847089790174886, + 0.35944419456198284, + 0.4587800928380382, + 0.7850802745518354, + 0.47109763253467746, + 0.5458662798264371, + 0.9021618405559098, + 0.2688810147690015, + 0.6842523623196098, + 0.22704887939299234, + 0.9443303947414002, + 0.31878860391464264, + 0.6578119800195369, + 1.0935264991481906, + 0.49820115933701425, + 0.5796937504382471, + 0.379034449277921, + 0.8935422299764184, + 0.33308505803499905, + 0.4451755264094731, + 0.45142174058110796, + 1.5521736686874483, + 0.5535923976865194, + 0.99581023949221, + 1.409962454328002, + 0.5384698879185799, + 0.23920195115067555, + 0.9070047199911795, + 0.802304523529797, + 0.6357319174434704, + 1.1410142596768602, + 0.874715690172512, + 0.394809308275774, + 0.7649178899921667, + 1.285622857214964, + 0.8586694753775871, + 0.2662499086274399, + 0.34901147265220994, + 1.062233184030298, + 0.8007022472566436, + 0.896410506215909, + 0.3777074033735856, + 0.5560793178217589, + 0.767699154007234, + 0.7364615005107735, + 0.6492011358107996, + 0.578076451901031, + 0.8582774082028704, + 0.7749614499151322, + 0.581527690243939, + 0.6531493677374816, + 0.6922644236277944, + 0.960138675535845, + 0.32599922270028003, + 0.4313384665395352, + 0.6715664450015368, + 0.866226173981187, + 0.16686707898365868, + 0.20122182487512727, + 0.5168947441843482, + 0.3644618485430186, + 0.6070939227403664, + 0.5303827888027538, + 0.5870302385883561, + 0.4538933415762515, + 1.1607711230778426, + 1.355643885342432, + 0.768813632650488, + 0.9226525566166115, + 0.4124561122329279, + 0.4392826029848834, + 0.4241865791268856, + 0.8041016393393912, + 0.6406599544283054, + 1.0402270550347066, + 0.9542895669860891, + 0.6915189788361297, + 0.8403102844479523, + 1.3922451281956025, + 0.6515936155997786, + 0.4689981348886295, + 1.0077506691141573, + 0.5236018517626, + 0.8617360672426085, + 1.3488214804023086, + 1.330224489420457, + 0.5697888636552308, + 0.6036750362439691, + 1.4801087569733715, + 2.891988316701276, + 2.853048452344537, + 1.8476743345236084, + 2.597485654058433, + 2.5055966930408395, + 2.2619882652122514, + 2.4422042700327533, + 2.9355189478843355, + 1.8476743345236084, + 2.058150606944274, + 2.2619882652122514, + 2.058150606944274, + 2.7676757380202464, + 2.7676757380202464, + 2.2619882652122514, + 2.4422042700327533, + 2.0370233794619454, + 1.8476743345236084, + 2.050537219550897, + 2.4422042700327533, + 2.058150606944274, + 2.1637026742283343, + 2.2511133880306673, + 1.8476743345236084, + 2.058150606944274, + 1.4959831486773143, + 3.0197310759414897, + 2.4422042700327533, + 2.597485654058433, + 2.058150606944274, + 0.9804531619823323, + 1.559885894181154, + 1.8476743345236084, + 2.058150606944274, + 3.115812494737077, + 1.3874319744869243, + 1.8476743345236084, + 2.058150606944274, + 2.7044189967296095, + 1.6863317636107102, + 2.1096603421691764, + 3.1112580587695486, + 2.7676757380202464, + 1.8476743345236084, + 2.7683693294952363, + 2.2619882652122514, + 2.891988316701276, + 2.1766118171248925, + 2.7676757380202464, + 2.4422042700327533, + 2.058150606944274, + 2.6343719762904607, + 1.235751264514235, + 2.058150606944274, + 2.7044189967296095, + 1.3611333024799808, + 2.4422042700327533, + 2.058150606944274, + 2.597485654058433, + 1.5211271812256442, + 2.2619882652122514, + 3.314160295599997, + 1.8476743345236084, + 2.2619882652122514, + 2.4410842969168067, + 2.2619882652122514, + 3.0197310759414897, + 3.060585810280874, + 2.4422042700327533, + 2.058150606944274, + 1.7305126663987844, + 3.0595045685671787, + 2.4422042700327533, + 2.3846970049563643, + 2.2619882652122514, + 2.7676757380202464, + 2.058150606944274, + 1.5837738524973792, + 1.8476743345236084, + 2.787075311210793, + 1.8476743345236084, + 1.0261006006829516, + 2.7676757380202464, + 1.7697288692656943, + 2.4422042700327533, + 2.597485654058433, + 2.2619882652122514, + 1.987778688217865, + 1.734373759379837, + 2.853048452344537, + 1.1817940670986729, + 1.7844618810384465, + 1.9806299258143218, + 1.662580227087135, + 2.2511133880306673, + 1.8476743345236084, + 3.2090900715462665, + 2.813637293933024, + 2.058150606944274, + 2.377801862709366, + 2.6721842480715328, + 2.4422042700327533, + 3.314160295599997, + 2.469710141212218, + 2.058150606944274, + 3.5659509171218624, + 2.2434367401361124, + 2.597485654058433, + 2.058150606944274, + 2.7044189967296095, + 2.891988316701276, + 1.9180454979641435, + 2.2619882652122514, + 2.058150606944274, + 2.6771538401877724, + 2.356505525463452, + 1.8277848094722016, + 1.938893243532497, + 1.8476743345236084, + 1.603256719422419, + 1.398648929089192, + 3.0197310759414897, + 1.806438411552133, + 1.8719823539518994, + 3.3793137163623843, + 2.4422042700327533, + 1.3279218978110927, + 0.3581959208189418, + 0.23426993864263349, + 0.617198594274258, + 0.9805106786434052, + 0.7248382270283343, + 1.968860051503621, + 0.7795190419137655, + 0.6927017111827718, + 0.4143356643586729, + 0.6675460944308889, + 1.0627104459594099, + 0.9928217414666617, + 1.1793741255978964, + 0.5913789332156696, + 0.5366940339244048, + 0.7544873568209591, + 0.7549156000800603, + 0.8203670948964893, + 0.5216406010833524, + 0.56453352275207, + 0.5233562637418108, + 0.4475812405525935, + 0.572228960794675, + 0.36660346649513387, + 0.7615837645308157, + 0.8818698464874435, + 1.0130537424366683, + 0.5343053122876188, + 0.6549700337483262, + 1.1165912341291202, + 0.7514102841110624, + 0.6926890521498703, + 0.8032002726550658, + 0.3036180946579793, + 0.6458577857458815, + 0.2515452030247386, + 0.6548701970190547, + 1.3481928011303632, + 0.7455023952563725, + 0.7717369913215505, + 0.5654572352952939, + 0.162067684448521, + 0.6064496601820905, + 0.32630375060895395, + 0.8027760968689474, + 0.6137017883771594, + 0.28397380105104253, + 0.632114442639141, + 0.4836451578918579, + 0.26223225839988895, + 0.3319007434694433, + 1.2178496156093148, + 0.8604424732536968, + 0.8840367594250771, + 0.5714159499148739, + 0.3983717306382247, + 0.6995022523050052, + 0.4398941273371701, + 0.6338000444438732, + 0.3333495779833784, + 0.7154546574517365, + 0.6653843317120176, + 0.8031218119753851, + 0.6463740154348417, + 0.7712885560673285, + 1.0404143618835913, + 0.8092081324198273, + 0.7366352184533294, + 0.580516885913141, + 1.6588955299211976, + 0.6866478213928426, + 0.36711420092390795, + 0.5283361793831902, + 0.44574417948503464, + 0.5213334703870665, + 0.34606678340723296, + 0.30746556995659846, + 0.5659832772475322, + 0.8385626053549102, + 0.4645774113377036, + 0.8172869077368641, + 1.5943524727174707, + 0.3289614227115405, + 0.6323465171145529, + 1.1336076291275596, + 0.8680122398791593, + 0.5478078140899293, + 0.24553101649381215, + 0.43777664045021936, + 0.33347964476457087, + 0.6561799997220457, + 0.6485529123206849, + 0.8842957454689566, + 0.35342028162120304, + 0.968889554195609, + 0.9170911335875391, + 0.6544303439662567, + 0.38779738086314014, + 0.5540196752598578, + 0.725285323615626, + 2.058150606944274, + 2.1096603421691764, + 3.0197310759414897, + 1.7844618810384465, + 2.597485654058433, + 1.398648929089192, + 1.8476743345236084, + 2.597485654058433, + 1.8476743345236084, + 2.4422042700327533, + 1.3611333024799808, + 2.1206154905540506, + 1.6315534406617571, + 1.8476743345236084, + 2.4422042700327533, + 2.058150606944274, + 2.597485654058433, + 3.5526501774026036, + 2.337957327240744, + 1.8476743345236084, + 2.058150606944274, + 2.0316549082801365, + 0.5444233500353808, + 1.666850887643042, + 2.597485654058433, + 0.21718929596363157, + 2.4422042700327533, + 2.1096603421691764, + 2.3164861275302515, + 2.2619882652122514, + 2.2619882652122514, + 1.5211271812256442, + 1.8476743345236084, + 2.8380026136553065, + 2.4422042700327533, + 2.597485654058433, + 2.4422042700327533, + 2.4422042700327533, + 1.7049962589880687, + 2.7676757380202464, + 1.590522021431977, + 1.3746383996430316, + 2.058150606944274, + 2.2810904181711433, + 1.8476743345236084, + 2.015619478204368, + 1.5211271812256442, + 2.875982387828919, + 1.9097144340054233, + 3.115812494737077, + 2.597485654058433, + 2.058150606944274, + 2.3846970049563643, + 2.891988316701276, + 2.4422042700327533, + 1.8476743345236084, + 1.9180454979641435, + 2.4422042700327533, + 1.0124161349179812, + 1.594544933895527, + 1.8476743345236084, + 2.058150606944274, + 2.015619478204368, + 2.058150606944274, + 1.5211271812256442, + 2.4422042700327533, + 2.5115194544866215, + 2.058150606944274, + 1.8476743345236084, + 2.1808240605894347, + 1.8476743345236084, + 2.058150606944274, + 1.8476743345236084, + 2.891988316701276, + 2.058150606944274, + 1.8476743345236084, + 3.314160295599997, + 2.6343719762904607, + 1.8476743345236084, + 2.0317836289157807, + 2.058150606944274, + 2.2619882652122514, + 2.058150606944274, + 1.8719823539518994, + 2.058150606944274, + 1.8476743345236084, + 0.9848088348171574, + 1.656333347149456, + 1.5211271812256442, + 3.092513778945497, + 2.7676757380202464, + 2.7676757380202464, + 1.8476743345236084, + 1.6025274431324954, + 1.390835498459361, + 3.5850673040480663, + 2.8380026136553065, + 1.8476743345236084, + 1.9948385371730537, + 2.058150606944274, + 1.3874319744869243, + 2.058150606944274, + 1.6280087876102627, + 2.058150606944274, + 2.356505525463452, + 1.3611333024799808, + 2.3469857869408033, + 1.7844618810384465, + 2.4422042700327533, + 2.058150606944274, + 2.4114168903758326, + 2.4422042700327533, + 3.0197310759414897, + 1.8277848094722016, + 2.036626252385164, + 2.891988316701276, + 3.0197310759414897, + 2.0317836289157807, + 2.597485654058433, + 1.8476743345236084, + 1.3611333024799808, + 3.115812494737077, + 1.8476743345236084, + 2.54945685258906, + 1.3611333024799808, + 2.891988316701276, + 2.058150606944274, + 1.9737515778687285, + 1.8189951082469618, + 2.7676757380202464, + 2.2619882652122514, + 2.7311667983932253, + 1.8476743345236084, + 2.058150606944274, + 2.8848214193836603, + 2.1968744764999206, + 3.0197310759414897, + 3.115812494737077, + 2.058150606944274, + 2.4422042700327533, + 1.6863317636107102, + 2.2619882652122514, + 1.869995322592043, + 0.8893077439609667, + 2.190496596306886, + 2.7676757380202464, + 1.3611333024799808, + 1.6461781850499237, + 1.6219238337408712, + 2.4422042700327533, + 2.058150606944274, + 2.597485654058433, + 1.8476743345236084, + 2.058150606944274, + 1.660660583374527, + 2.002718797933716, + 2.597485654058433, + 1.5747746181144326, + 1.3611333024799808, + 1.390835498459361, + 3.314160295599997, + 2.804948670519246, + 2.4422042700327533, + 2.4422042700327533, + 1.9134505313995152, + 1.938600054043278, + 2.058150606944274, + 2.058150606944274, + 2.2245831473842514, + 2.7676757380202464, + 2.4422042700327533, + 2.1808240605894347, + 3.582079689185183, + 1.1947456331807709, + 2.594838629075765, + 2.356505525463452, + 3.2090900715462665, + 1.3611333024799808, + 2.0016039390719147, + 2.2619882652122514, + 2.5065786589076757, + 2.058150606944274, + 1.8476743345236084, + 0.6867021784384095, + 2.058150606944274, + 2.4422042700327533, + 2.891988316701276, + 2.08325008034921, + 0.258136448358958, + 0.4569873849405227, + 0.8002356675608518, + 0.6018866406531915, + 0.8883244922132103, + 0.522715655895533, + 0.8569635848100532, + 1.1846011352876193, + 0.6372679710201478, + 0.8526803920209586, + 0.7216785296810249, + 0.9034821913615956, + 0.7486472494683878, + 0.47768163141029363, + 0.4053011118605485, + 0.5354612527090477, + 0.5613760198067714, + 0.47903099375421127, + 0.48080898419304813, + 0.5839429234917104, + 0.507251963661533, + 0.5931159663027697, + 0.9732427902340047, + 0.7246939281184708, + 0.3986366018960761, + 0.8851314723979544, + 0.7518779737601076, + 1.2663468458789282, + 0.41303812585867905, + 0.5776809554913769, + 0.40140040092991663, + 0.36600428916425476, + 0.9698912655716689, + 0.6497928272094835, + 0.8720896381502944, + 0.462886894646304, + 1.1311181334286888, + 0.577369258061934, + 1.0237320422496383, + 0.5787516181193971, + 0.7938897602874253, + 0.9121068894388986, + 0.5664008642318163, + 0.4227885073173778, + 1.4001831276480394, + 0.7626616382076754, + 0.7129916469968688, + 0.3125713574063079, + 0.4515737355980766, + 0.4477432713109213, + 0.40380829877307256, + 1.0357953682550678, + 0.6751255961062537, + 1.0079692228259864, + 0.716748440784365, + 0.6186203519701255, + 0.8299413969961479, + 0.6473811483506047, + 0.550811306201503, + 0.5761474929998247, + 0.3618792279878146, + 0.5078341524285224, + 0.9537045469425467, + 0.944386708931535, + 0.5910032211927682, + 0.7859470706341881, + 0.5669435362577306, + 1.2062696399983015, + 0.4850305035602842, + 0.6834674006068431, + 0.5349672046536137, + 0.5577034930967317, + 0.9103534555110824, + 0.911270808094474, + 0.4289044049924174, + 0.7204154307889812, + 1.001786068165604, + 0.8878978749404558, + 1.2118547452266673, + 0.40717273712522833, + 0.8559736089332349, + 1.1410142596768602, + 1.19269019257105, + 0.7441953978266795, + 0.4227915900764154, + 0.6440218612348688, + 0.9901430000781344, + 0.3371987930106698, + 0.6119088095751585, + 0.39242824589041225, + 0.5536993873693266, + 0.4879806591169961, + 0.6290817387916683, + 0.5300051040366099, + 0.8161498585230426, + 1.0267749069189063, + 0.2743173674354173, + 0.626967583466226, + 1.3683060184699798, + 0.6436024550596782, + 1.8476743345236084, + 1.8476743345236084, + 2.4422042700327533, + 2.058150606944274, + 2.597485654058433, + 1.8476743345236084, + 1.4503080810311917, + 2.891988316701276, + 2.3311659799232376, + 3.115812494737077, + 1.3314922932342572, + 1.8476743345236084, + 3.3793137163623843, + 2.1348241019127823, + 2.5825373427782976, + 2.5825373427782976, + 2.1158858357860773, + 2.0288277185374666, + 1.8277848094722016, + 1.8476743345236084, + 0.5804577832192853, + 2.597485654058433, + 2.4422042700327533, + 1.3611333024799808, + 2.2619882652122514, + 1.0663285856881413, + 1.8476743345236084, + 2.986632069270234, + 2.058150606944274, + 2.2619882652122514, + 2.597485654058433, + 1.662580227087135, + 2.7676757380202464, + 2.2619882652122514, + 2.4422042700327533, + 1.0638348510133466, + 2.058150606944274, + 2.7098229290372036, + 1.8476743345236084, + 2.2619882652122514, + 1.3048383027630401, + 1.8572702773394505, + 2.7676757380202464, + 2.7098229290372036, + 2.2619882652122514, + 1.8476743345236084, + 2.906249874231007, + 2.2619882652122514, + 2.3573073892837764, + 1.9936948317948047, + 2.4583952721084588, + 2.7676757380202464, + 1.8476743345236084, + 2.7676757380202464, + 2.891988316701276, + 1.4190556497426368, + 2.597485654058433, + 2.058150606944274, + 1.4959831486773143, + 2.2619882652122514, + 1.5687643749231754, + 1.5211271812256442, + 3.0197310759414897, + 1.8476743345236084, + 1.3611333024799808, + 2.891988316701276, + 2.745327489565261, + 3.469823829994782, + 3.384015286101267, + 2.4422042700327533, + 2.3023700283245954, + 3.0197310759414897, + 1.949666463423513, + 1.8476743345236084, + 2.2619882652122514, + 2.6568765686354823, + 1.1619350861558506, + 1.949666463423513, + 2.221026667433179, + 1.8476743345236084, + 3.469823829994782, + 1.8476743345236084, + 1.9180454979641435, + 1.3158325326253075, + 2.7676757380202464, + 2.058150606944274, + 0.9836003294439223, + 2.4422042700327533, + 2.891988316701276, + 1.5016476231502476, + 2.4422042700327533, + 1.8476743345236084, + 2.058150606944274, + 2.891988316701276, + 2.1913009430783856, + 1.3167244641054947, + 2.058150606944274, + 1.8476743345236084, + 2.058150606944274, + 1.3611333024799808, + 1.0753357012288185, + 1.4110227771922441, + 1.8277848094722016, + 2.2434367401361124, + 2.340817939335098, + 2.2619882652122514, + 1.0347512202215243, + 2.1584763686510424, + 2.152909760085203, + 3.1112580587695486, + 2.4422042700327533, + 2.597485654058433, + 2.2619882652122514, + 1.8476743345236084, + 2.891988316701276, + 0.9920163401270353, + 2.6041526391479004, + 1.8476743345236084, + 0.9309933443453626, + 2.4410842969168067, + 3.115812494737077, + 2.7676757380202464, + 2.2619882652122514, + 3.2090900715462665, + 3.0197310759414897, + 2.050816338718299, + 2.891988316701276, + 1.7662000478094928, + 2.058150606944274, + 2.5596229582529304, + 1.1294313965291145, + 1.8476743345236084, + 1.5211271812256442, + 2.210162496909271, + 1.8135183259714691, + 1.4000336846666133, + 2.058150606944274, + 3.5528726186839443, + 2.2619882652122514, + 1.6315534406617571, + 1.8476743345236084, + 2.356505525463452, + 2.4422042700327533, + 1.662580227087135, + 2.058150606944274, + 2.2619882652122514, + 1.8476743345236084, + 1.6105677745759317, + 1.8476743345236084, + 1.8476743345236084, + 1.3611333024799808, + 1.8476743345236084, + 1.68928808973709, + 2.2619882652122514, + 2.2619882652122514, + 1.8476743345236084, + 2.3846970049563643, + 2.9974666290074614, + 3.0197310759414897, + 1.8476743345236084, + 2.6721842480715328, + 1.5211271812256442, + 2.597485654058433, + 2.058150606944274, + 1.9180454979641435, + 3.3891245095965568, + 2.058150606944274, + 2.5164994042091156, + 1.8476743345236084, + 3.314160295599997, + 2.597485654058433, + 2.6261040803852387, + 2.2619882652122514, + 1.9180454979641435, + 1.6025274431324954, + 2.891988316701276, + 1.8476743345236084, + 2.058150606944274, + 1.8476743345236084, + 2.4422042700327533, + 2.7676757380202464, + 1.8919337443921482, + 2.058150606944274, + 2.891988316701276, + 2.264515291401005, + 1.3611333024799808, + 0.20196505450680047, + 0.7624108171500346, + 0.8224858811225808, + 0.6626276772219335, + 0.535851367288204, + 0.7646915967826025, + 0.29817855707599195, + 0.5720469323254056, + 0.8978013966698231, + 0.6111259074881495, + 0.589958566748797, + 1.3401155543616938, + 0.6904314230030708, + 0.6196236585141413, + 0.3848578111111818, + 0.4123494339440575, + 0.9701080704925285, + 0.5174095949362384, + 0.41026619502010064, + 1.059421901512532, + 1.2281710491598, + 0.846463303117498, + 0.47102206927579426, + 0.7883940505212186, + 0.9217189925586216, + 0.48342237449039765, + 0.922398477907306, + 1.7075877606945655, + 0.26773684661055136, + 0.4875580714001766, + 0.5984325761972488, + 0.7230954065155999, + 0.3550449035058376, + 0.7447230345398885, + 0.5149027534088807, + 0.933897184551643, + 0.8246473780869069, + 0.5217789355781935, + 0.4910464550809359, + 0.5260494961653587, + 0.3659918035709334, + 0.5575945307172704, + 0.8136860368759898, + 0.7951863047350193, + 0.8722846482801919, + 0.6141186246462, + 0.43629786610540294, + 0.3215214228226133, + 0.6671233155693972, + 0.9538022906155754, + 0.47714694686986814, + 0.7021831324235442, + 0.8014579666267587, + 0.22936593069374955, + 0.3536993015697938, + 0.6379766344518076, + 0.913340981849762, + 0.41904410875008946, + 0.7012050165257485, + 0.6513325983125297, + 0.42008451523717805, + 0.8281899583856165, + 0.6395683754740236, + 0.7951791161152351, + 0.9447150798147695, + 0.7453720201547692, + 1.1228601386692758, + 0.41199097653834155, + 0.37783994557219286, + 0.4496935567627637, + 0.4807169673401061, + 0.26061530876931605, + 0.4242035709383907, + 0.5880634406596801, + 1.0437185161372962, + 0.4279887058489056, + 1.1375482341247403, + 0.6898715987202014, + 1.2412322013613672, + 0.4067831483041202, + 0.26081655081913413, + 0.4516102664064432, + 0.57141907907551, + 0.3193555716742172, + 1.0064637627893283, + 0.5560549234813755, + 1.043060417321044, + 0.4264967934824262, + 0.5456219202019728, + 0.3493962763473944, + 0.646163601945988, + 1.1291790774046846, + 0.7694604921695203, + 0.5395979071090727, + 0.5878803710066846, + 0.40704290406974303, + 0.5280581851151547, + 1.526950309885836, + 0.42282971700231115, + 0.24768818454018265, + 0.4705107767660467, + 0.9464594334368084, + 0.705187406560187, + 0.42279076606321686, + 0.5125227108924628, + 0.4076785665000914, + 0.5681621515937332, + 0.7859502606902504, + 0.6807552018412489, + 0.5031153447261112, + 0.5851473604114947, + 0.4574708683868778, + 1.1046717094710425, + 0.432182919607874, + 0.328945237512809, + 0.9791288540825005, + 0.4029028476827323, + 0.5208243327319921, + 1.2064962295762194, + 0.6404753765872037, + 0.26453914731630596, + 0.41506097748318865, + 0.5655261621839465, + 0.8467499529704493, + 0.4384468648638673, + 1.066955430933875, + 1.3978074484364353, + 0.6567604546170768, + 0.6724737719847027, + 1.0200736775005241, + 0.5083445229296528, + 0.6758414559802328, + 0.8006715256118703, + 0.5274592548546302, + 0.6642620303644357, + 0.9394923187228251, + 0.45574494429195894, + 0.45718872036726305, + 0.19897213185525836, + 0.9404212121441905, + 0.9138847420927091, + 0.5819790594056562, + 0.8085811369248563, + 1.06608042892252, + 0.6703014193793999, + 0.5557683969295532, + 0.44511304126861284, + 0.941085197649712, + 0.5499453256504347, + 0.5797327233950083, + 0.5362417630534007, + 0.27648495732764894, + 0.5024914879640386, + 0.3435156352713158, + 0.40100422413860687, + 0.7233706812575286, + 0.5704423117067636, + 0.5297431200911402, + 0.32992675537716404, + 0.5480230295661077, + 0.9369670096740996, + 0.3754777432016049, + 0.22146880197599228, + 1.117427201264557, + 0.6615671311512096, + 0.7633541977202309, + 0.7645820268895334, + 0.5891546589307797, + 0.5364501925471944, + 1.1035922071412165, + 0.7057372576373457, + 1.113880856115991, + 1.1219881390998174, + 0.32546217973861363, + 0.403221514312597, + 0.6488111031266474, + 1.116335758026605, + 0.24800717802609556, + 1.5267000574628176, + 1.1688528172247616, + 0.4090094528613061, + 0.7086268832907084, + 0.4735949868060566, + 0.6984585641458463, + 0.3424973667654564, + 0.7640499906668905, + 0.4162318299733402, + 0.7268510221995274, + 0.8577175911989183, + 0.541829926158341, + 1.00827064156793, + 0.6289921383569832, + 0.4730512390815337, + 0.849707913151545, + 0.5913559623011502, + 1.2653245889127316, + 0.28196764206144204, + 0.5984225421361531, + 0.3182074150941484, + 1.2251641585552626, + 0.6043537079455041, + 0.3866324569668259, + 0.27837446495699575, + 0.2872914807513895, + 0.5294274206826982, + 0.5101331945002561, + 0.5883155824414785, + 0.7646060671613457, + 0.44755670876072107, + 0.34067793954997133, + 0.39406322601001736, + 0.48405948722274983, + 0.396566726538215, + 0.9251913526054448, + 1.0883977862789402, + 0.586944524796003, + 0.4844365631243278, + 0.5086726000911839, + 0.31675552420850017, + 0.4967525132510379, + 1.2700218743571479, + 0.4836795240324131, + 0.7516984685392585, + 0.7732291367546171, + 0.5695914179324801, + 0.9351029816874816, + 0.5872246187652376, + 0.512590336304321, + 0.8204249742981127, + 0.648468135053765, + 0.70313991665927, + 0.8775319745793377, + 1.748812564366438, + 0.2584667854440521, + 0.8980043442106427, + 0.3579808841965713, + 0.8343929378343982, + 1.1543731812512452, + 0.7131507684959495, + 0.8795412834743115, + 0.3715735435415726, + 0.73728655377481, + 0.945025540914296, + 0.36971912538230134, + 1.2440676979025553, + 0.6721175155461698, + 0.36772494643493603, + 0.9625783764208791, + 0.6526039665181063, + 0.36491798550434873, + 0.48400612694968104, + 0.7331035031858504, + 0.7753694966237029, + 0.5240752715136745, + 0.46498630189262996, + 0.2922063009687095, + 0.6923141676891124, + 0.9884560626039101, + 0.7553438247687148, + 0.6009899618234731, + 0.5680558702266572, + 0.5041578937050646, + 0.44090666782724663, + 1.2307727432798594, + 0.36456541412557614, + 0.37168016697405243, + 1.3843229534246373, + 0.5093274232576448, + 0.9353619994791109, + 0.4358163855151703, + 0.8737385270525315, + 0.28741676277591865, + 0.3371886753466501, + 0.2537948398653946, + 0.557551507510446, + 0.401662800337396, + 0.8864424861465803, + 0.666351675677267, + 0.8616459973694832, + 0.48580395906406, + 0.5083788516626222, + 1.265001688513557, + 0.4565088718316265, + 1.258918596274464, + 0.3694404916452776, + 1.3522969088551515, + 0.7417673943131574, + 0.33634466154195714, + 0.7364981350911535, + 0.572246257024926, + 0.6282088674304231, + 0.3665167621350895, + 0.6976128338197698, + 0.29279861765945314, + 1.2262015885228075, + 0.6599808941274614, + 0.4871059536628749, + 0.7747803491427805, + 0.6330580891687021, + 1.169062481749637, + 1.4826676654967779, + 1.949666463423513, + 2.058150606944274, + 2.1808240605894347, + 2.1158858357860773, + 0.9789868992504976, + 2.4422042700327533, + 1.0778704461371276, + 1.7697288692656943, + 2.3261157344511374, + 1.8277848094722016, + 1.3777046853437653, + 2.2619882652122514, + 1.5211271812256442, + 1.590334484063495, + 1.9180454979641435, + 2.4422042700327533, + 3.0197310759414897, + 2.2619882652122514, + 2.2295258418270327, + 1.8476743345236084, + 0.5881468769222613, + 2.7311667983932253, + 2.597485654058433, + 2.2619882652122514, + 2.2619882652122514, + 3.469823829994782, + 2.597485654058433, + 1.8125730644900901, + 2.4422042700327533, + 2.597485654058433, + 2.180647674397531, + 1.8476743345236084, + 2.058150606944274, + 1.8476743345236084, + 2.058150606944274, + 2.058150606944274, + 3.632934828272867, + 2.7676757380202464, + 2.891988316701276, + 3.115812494737077, + 1.1327857171393072, + 2.18245626486345, + 2.058150606944274, + 1.8476743345236084, + 2.97230854034911, + 2.2619882652122514, + 1.6664528468124042, + 2.5065786589076757, + 1.7507460439438525, + 3.115812494737077, + 1.8277848094722016, + 2.08325008034921, + 2.891988316701276, + 1.7223285043941488, + 2.058150606944274, + 1.263065951248851, + 1.6863317636107102, + 1.8476743345236084, + 2.813637293933024, + 2.2619882652122514, + 1.8476743345236084, + 2.7676757380202464, + 1.3507224322004856, + 2.058150606944274, + 2.1186882814577563, + 2.2619882652122514, + 2.2619882652122514, + 1.8476743345236084, + 0.6976785859468047, + 1.5837738524973792, + 1.3611333024799808, + 2.891988316701276, + 1.0233129489496542, + 2.2432439590948734, + 1.5211271812256442, + 2.5897137525317344, + 3.2090900715462665, + 1.7844618810384465, + 1.662580227087135, + 2.4422042700327533, + 2.1703581637338116, + 3.384015286101267, + 1.8277848094722016, + 2.058150606944274, + 1.8476743345236084, + 1.2850243246698159, + 0.4014892027547623, + 2.4422042700327533, + 1.7514132182974744, + 2.058150606944274, + 1.9309054181401635, + 2.4422042700327533, + 1.9309054181401635, + 1.8476743345236084, + 2.7943658550361237, + 2.597485654058433, + 2.2619882652122514, + 2.058150606944274, + 2.1183191872581517, + 1.3611333024799808, + 2.724286245472211, + 2.891988316701276, + 2.377801862709366, + 2.058150606944274, + 2.853048452344537, + 2.482270985196589, + 3.0197310759414897, + 1.8476743345236084, + 2.4422042700327533, + 1.662580227087135, + 2.058150606944274, + 1.6863317636107102, + 2.058150606944274, + 1.8476743345236084, + 2.0853977922487412, + 1.7844618810384465, + 2.7798341040219183, + 1.7320291053472046, + 1.5211271812256442, + 2.597485654058433, + 2.1158858357860773, + 2.2619882652122514, + 3.314160295599997, + 1.8476743345236084, + 2.597485654058433, + 2.2619882652122514, + 1.8738350541590871, + 3.4170490643040496, + 1.8476743345236084, + 2.597485654058433, + 3.469823829994782, + 1.8476743345236084, + 2.597485654058433, + 2.058150606944274, + 1.987778688217865, + 2.2781599683995784, + 2.058150606944274, + 1.3611333024799808, + 3.2090900715462665, + 2.058150606944274, + 2.058150606944274, + 1.9180454979641435, + 1.6044879743098945, + 0.9920163401270353, + 1.2253127571351934, + 1.8476743345236084, + 2.567020134223122, + 2.597485654058433, + 1.987778688217865, + 2.597485654058433, + 1.2444836210367136, + 2.4422042700327533, + 3.1112580587695486, + 2.0846608199034327, + 2.147538210676071, + 1.8476743345236084, + 2.2619882652122514, + 1.4129257283170586, + 1.604897060369414, + 1.8476743345236084, + 2.482270985196589, + 2.7044189967296095, + 1.6863317636107102, + 2.213394944108816, + 2.597485654058433, + 2.058150606944274, + 1.154852472637272, + 0.8529325353635309, + 3.115812494737077, + 2.058150606944274, + 3.0197310759414897, + 1.3611333024799808, + 2.4422042700327533, + 1.347097373512335, + 2.058150606944274, + 2.3469857869408033, + 2.015619478204368, + 2.7676757380202464, + 2.434804469403139, + 1.8476743345236084, + 1.7995564954684753, + 2.2619882652122514, + 1.723759417237108, + 2.891988316701276, + 2.058150606944274, + 1.8277848094722016, + 2.058150606944274, + 2.612858691179377, + 1.8476743345236084, + 1.199594116567958, + 2.8538109064683477, + 2.597485654058433, + 1.8476743345236084, + 1.662580227087135, + 2.1158858357860773, + 2.5336432602451078, + 1.5837738524973792, + 2.4297198737860715, + 1.7382647621746443, + 1.6989645067419874, + 2.2619882652122514, + 2.1913009430783856, + 2.7676757380202464, + 1.824852988941001, + 2.9355765938955307, + 2.1371742310563575, + 2.058150606944274, + 2.2619882652122514, + 1.8476743345236084, + 2.567020134223122, + 1.662580227087135, + 2.5164994042091156, + 1.1875514989048077, + 2.1158858357860773, + 2.2511133880306673, + 2.4422042700327533, + 1.5315722679462986, + 2.1808240605894347, + 1.859268245188611, + 2.1808240605894347, + 3.384015286101267, + 2.891988316701276, + 2.891988316701276, + 2.2619882652122514, + 1.8476743345236084, + 1.723759417237108, + 2.058150606944274, + 2.8380026136553065, + 2.597485654058433, + 1.3611333024799808, + 2.7676757380202464, + 2.058150606944274, + 1.8354417509053258, + 1.6863317636107102, + 2.4422042700327533, + 1.6863317636107102, + 2.3469857869408033, + 1.5349129100469496, + 3.0197310759414897, + 1.987778688217865, + 1.8476743345236084, + 1.7180433636002448, + 1.6933352626269889, + 1.8829205119268706, + 2.058150606944274, + 1.8476743345236084, + 2.340817939335098, + 1.757494125725314, + 1.8476743345236084, + 2.340817939335098, + 2.2619882652122514, + 2.7676757380202464, + 2.058150606944274, + 2.0730766581517344, + 2.356505525463452, + 1.8476743345236084, + 1.8476743345236084, + 2.4422042700327533, + 2.058150606944274, + 2.35795990200179, + 2.891988316701276, + 2.0016298844905607, + 1.347097373512335, + 1.4005341623595484, + 1.8476743345236084, + 2.2619882652122514, + 2.002718797933716, + 2.2619882652122514, + 1.1450329832118107, + 1.6863317636107102, + 2.4647670688610464, + 1.9077816599366075, + 2.597485654058433, + 2.058150606944274, + 1.3486011334573254, + 2.264515291401005, + 1.5231182165439487, + 1.8476743345236084, + 2.058150606944274, + 1.8476743345236084, + 1.2629492011777543, + 1.8476743345236084, + 1.8476743345236084, + 2.058150606944274, + 2.058150606944274, + 1.8476743345236084, + 2.7676757380202464, + 1.3507224322004856, + 2.1096603421691764, + 2.597485654058433, + 2.4422042700327533, + 1.6863317636107102, + 2.2619882652122514, + 1.8476743345236084, + 1.662580227087135, + 2.4892514228577474, + 2.2619882652122514, + 1.3737141278559242, + 1.5211271812256442, + 3.0197310759414897, + 2.08325008034921, + 2.891988316701276, + 2.2619882652122514, + 2.891988316701276, + 1.662580227087135, + 2.058150606944274, + 1.781949048356978, + 2.08325008034921, + 3.314160295599997, + 1.6315534406617571, + 1.8476743345236084, + 2.597485654058433, + 3.1912841717746234, + 1.8476743345236084, + 2.567020134223122, + 2.058150606944274, + 1.9180454979641435, + 3.5659509171218624, + 1.0562338423018558, + 2.7676757380202464, + 0.9920163401270353, + 1.3874319744869243, + 1.3611333024799808, + 2.2619882652122514, + 2.7676757380202464, + 2.8716453519485268, + 1.1744010489819492, + 1.3611333024799808, + 2.2619882652122514, + 2.2619882652122514, + 1.7623504537482835, + 1.8476743345236084, + 1.5802938525322712, + 2.058150606944274, + 2.567020134223122, + 2.4422042700327533, + 3.115812494737077, + 1.8476743345236084, + 2.058150606944274, + 1.8476743345236084, + 3.0197310759414897, + 1.5687643749231754, + 2.935818900897615, + 1.8476743345236084, + 2.2619882652122514, + 3.2090900715462665, + 2.2619882652122514, + 0.38443815505299855, + 2.2432439590948734, + 2.058150606944274, + 1.7844618810384465, + 2.1808240605894347, + 2.4422042700327533, + 2.891988316701276, + 1.8216987544063346, + 1.8546892407507647, + 2.2619882652122514, + 1.5211271812256442, + 2.058150606944274, + 2.891988316701276, + 2.1215696885182393, + 2.058150606944274, + 1.3611333024799808, + 2.595693634832246, + 1.858761764395333, + 1.764455547273154, + 1.6863317636107102, + 3.5659509171218624, + 1.949666463423513, + 2.2619882652122514, + 1.5791670759997178, + 1.1118761177627527, + 1.6105677745759317, + 1.470582209836203, + 1.8476743345236084, + 1.987778688217865, + 2.348287040197626, + 1.2183130109974831, + 2.6721842480715328, + 2.058150606944274, + 2.2619882652122514, + 0.9833557825196634, + 2.2619882652122514, + 2.1096603421691764, + 3.8305166282296113, + 1.3611333024799808, + 0.9144691831036831, + 2.058150606944274, + 3.6695878433215654, + 1.8354417509053258, + 2.4422042700327533, + 2.9355765938955307, + 2.2619882652122514, + 2.891988316701276, + 2.5121903693258694, + 2.325363679779433, + 1.0124119077431848, + 0.8269797567441082, + 0.9016855281939891, + 0.31028405413331506, + 1.1612896996666167, + 0.43357730760186736, + 0.9220138851412811, + 0.7317687573395162, + 0.37387918720045105, + 0.5511001669422874, + 0.6361012374624766, + 0.7180814991423357, + 0.4611899730424046, + 0.675971750411626, + 1.342890551598379, + 0.3853524223332713, + 0.8169868519838026, + 0.537940432112832, + 0.460121056939908, + 1.1393151838058966, + 0.5990800565043839, + 0.5084956643601144, + 1.1775803545009338, + 0.2212945671484043, + 0.3407917546440944, + 0.27618464369540785, + 0.5720329083618736, + 0.8016283771931128, + 0.38834175394574155, + 1.3635681002239162, + 0.4013077454101247, + 0.602333948968875, + 0.4989615321444795, + 0.7505501979428542, + 1.0957418596147517, + 0.7690684691140206, + 0.7828010004678984, + 0.4962599956724345, + 0.8185819200714681, + 0.5489779003340556, + 0.217730090928695, + 0.7226540786215514, + 0.6901207210628639, + 0.7344602058578967, + 0.46625361792009434, + 0.8033226008370442, + 0.33980943878762415, + 0.1805665226445842, + 0.5968862028467088, + 0.4943742688016011, + 0.8894728286644196, + 0.2928712645014665, + 0.3353894644516039, + 0.6847707243289837, + 0.669220427123195, + 0.5201900147518365, + 0.736869592720967, + 0.4738166019566452, + 0.8105205764111205, + 1.0005343059545948, + 0.20391022224840266, + 0.38296479546908957, + 0.9816029960065905, + 0.262164348646478, + 0.7195335530768934, + 0.3987394195172832, + 0.8808692516563048, + 0.34456135944088734, + 1.3930445407431284, + 0.4377510894343549, + 0.275398335862075, + 0.7737090836266438, + 0.4805507048759122, + 0.7039089022684283, + 0.14899696655531966, + 0.582190488844278, + 0.4464142969317393, + 0.38106666776531384, + 0.595407241943122, + 0.6790250287377979, + 0.34023802267783443, + 0.6033106342737061, + 0.34557874870572997, + 0.9408271324003349, + 0.9324320859027562, + 0.37743596248484657, + 1.0391762034767582, + 0.41097306344995294, + 0.3318261221597407, + 0.9109837030014802, + 0.7086392349155272, + 0.8047427984339125, + 0.5924328100591214, + 1.1288413975112799, + 0.4971853295683465, + 0.7009580257836348, + 0.36544980110877917, + 0.9866403119785365, + 0.462826005406497, + 0.7061891062673327, + 2.058150606944274, + 1.5211271812256442, + 1.3098944877173526, + 2.058150606944274, + 2.4422042700327533, + 2.181515799159564, + 2.36329651777183, + 1.8476743345236084, + 1.8476743345236084, + 2.058150606944274, + 1.9180454979641435, + 2.597485654058433, + 2.2619882652122514, + 2.597485654058433, + 2.058150606944274, + 2.6343719762904607, + 1.806438411552133, + 2.6131542800439846, + 2.2619882652122514, + 2.7676757380202464, + 2.2619882652122514, + 2.4297198737860715, + 2.1427688434278687, + 1.8476743345236084, + 1.8273752314781504, + 1.7844618810384465, + 1.3611333024799808, + 0.9005941153643067, + 1.8476743345236084, + 2.5939343032886533, + 2.4422042700327533, + 2.264515291401005, + 3.314160295599997, + 2.112575159110614, + 3.314160295599997, + 1.9016741025619868, + 1.9180454979641435, + 1.8476743345236084, + 1.5211271812256442, + 2.4297198737860715, + 2.0648124051905614, + 3.314160295599997, + 2.4422042700327533, + 2.4422042700327533, + 2.058150606944274, + 2.5683973479484674, + 1.7058034655857854, + 1.949666463423513, + 1.3611333024799808, + 2.2619882652122514, + 3.0197310759414897, + 2.058150606944274, + 1.3611333024799808, + 1.987778688217865, + 2.058150606944274, + 2.08325008034921, + 2.891988316701276, + 2.2619882652122514, + 1.8273752314781504, + 2.1808240605894347, + 1.7844618810384465, + 1.8476743345236084, + 1.3507224322004856, + 1.3611333024799808, + 3.115812494737077, + 1.8476743345236084, + 3.115812494737077, + 3.384015286101267, + 1.5211271812256442, + 2.058150606944274, + 1.8277848094722016, + 2.2306884460253498, + 2.4422042700327533, + 2.597485654058433, + 2.1348241019127823, + 1.6038996396013907, + 2.2619882652122514, + 2.2619882652122514, + 1.8476743345236084, + 2.058150606944274, + 0.9920163401270353, + 3.632934828272867, + 2.058150606944274, + 2.058150606944274, + 3.000785814099154, + 2.307339485639952, + 2.2511133880306673, + 3.314160295599997, + 2.567020134223122, + 3.0691025648100325, + 3.314160295599997, + 1.8476743345236084, + 1.8476743345236084, + 1.8476743345236084, + 2.597485654058433, + 1.8476743345236084, + 3.115812494737077, + 2.3469857869408033, + 1.949666463423513, + 1.8476743345236084, + 2.8848214193836603, + 1.8476743345236084, + 1.3120675111855844, + 2.058150606944274, + 2.4422042700327533, + 3.2090900715462665, + 2.4422042700327533, + 2.058150606944274, + 2.5065786589076757, + 3.115812494737077, + 1.8476743345236084, + 2.891988316701276, + 1.8476743345236084, + 1.8476743345236084, + 2.2810904181711433, + 2.4297198737860715, + 2.891988316701276, + 1.788916762599605, + 3.2090900715462665, + 2.597485654058433, + 1.3611333024799808, + 2.165144503625583, + 2.4422042700327533, + 2.265410956951932, + 2.4422042700327533, + 2.2619882652122514, + 0.9691893594890818, + 2.058150606944274, + 2.597485654058433, + 2.4422042700327533, + 2.067456031736355, + 2.2432439590948734, + 2.2619882652122514, + 2.2619882652122514, + 1.973920894568543, + 1.898126120163308, + 1.8476743345236084, + 2.2619882652122514, + 1.5554565377911724, + 1.723759417237108, + 2.7676757380202464, + 2.4422042700327533, + 0.46249910509451103, + 2.2619882652122514, + 2.01733946810076, + 2.891988316701276, + 2.2407655888463136, + 1.5342263050523801, + 3.0197310759414897, + 1.8476743345236084, + 1.6863317636107102, + 2.3626336793216423, + 2.4422042700327533, + 2.7676757380202464, + 2.2619882652122514, + 2.6411410396066364, + 3.314160295599997, + 2.058150606944274, + 2.2619882652122514, + 2.009993767379165, + 2.0573647822852124, + 2.058150606944274, + 1.5886908262153567, + 2.2619882652122514, + 3.2090900715462665, + 2.4422042700327533, + 2.058150606944274, + 2.597485654058433, + 2.471327604768158, + 2.891988316701276, + 1.968261944584257, + 2.2619882652122514, + 2.058150606944274, + 2.727014012968785, + 1.662580227087135, + 1.8476743345236084, + 1.949666463423513, + 2.6476390176760325, + 1.463914074861662, + 1.7844618810384465, + 2.728717141670434, + 1.6177788442916419, + 2.002718797933716, + 2.2619882652122514, + 1.470582209836203, + 3.384015286101267, + 2.6041526391479004, + 0.6329290441903721, + 1.8476743345236084, + 2.2619882652122514, + 3.0197310759414897, + 2.058150606944274, + 1.6638688621723507, + 1.4597008336661754, + 0.5534719394022266, + 0.5775455225538931, + 0.20514004210616732, + 0.5614453387367396, + 0.8221633215480137, + 0.5919319442540658, + 0.40774846847683566, + 0.19337786243052407, + 0.7700510746582362, + 0.651033909951731, + 1.308681023617602, + 0.6049503434180373, + 1.2410933677853286, + 1.1759058995073421, + 0.7313880274096966, + 0.6378225289202193, + 0.7081075194203795, + 0.6447543966471175, + 0.8272794369545042, + 0.556919626620576, + 0.840851494440795, + 0.9801732967246929, + 0.4117161260074915, + 0.3024408343306615, + 1.04749519948372, + 0.3395360431309277, + 0.7995411194630615, + 0.8762230038366647, + 0.5453848610288126, + 0.8696638111448614, + 0.4315085242566009, + 1.0705364658815963, + 0.6324552347137256, + 1.1295381904815545, + 0.38725145343127076, + 1.1455070679614017, + 1.9730486350796934, + 0.3319373447872119, + 0.9949512216543951, + 1.2914626149775783, + 0.8280553200709528, + 0.886511385060715, + 1.0116432848560328, + 0.9723996934474358, + 0.6094093614652507, + 0.7502562018239491, + 0.44191344514717246, + 0.4483118787230166, + 0.7974778405450097, + 0.605629556081493, + 0.5258055446738888, + 1.0189545882188806, + 0.45153964447910533, + 0.9171945223976985, + 0.6422758856710519, + 0.6641421053048686, + 0.2811050085484198, + 1.4030564363252953, + 0.5769057935294254, + 0.707272857913838, + 0.5758876707172271, + 0.8394707883585009, + 0.9327628032454499, + 0.8460394715645433, + 0.48812506867643846, + 0.2978518036639437, + 0.4237887269322721, + 0.7547389140214324, + 0.5384222485936951, + 0.48104449699515894, + 0.8130770726035376, + 0.4908407675860358, + 0.8411872406800975, + 1.0995163074129541, + 0.514844009442078, + 0.7328095490927963, + 0.5216406010833524, + 0.7622630240802899, + 0.45945871883943357, + 0.5604990377179591, + 0.266643920334818, + 1.1506122971384178, + 1.3541724917451705, + 0.2556997545270132, + 1.403407307881034, + 0.8402001751472621, + 0.405984094800355, + 0.6447661961299339, + 0.30379086857454096, + 0.4559042244842182, + 1.223415326244405, + 0.49684815487587974, + 0.3732698307819343, + 0.462834047462773, + 1.5293618427737923, + 0.5536083206866534, + 0.33053613044270497, + 0.7903617937578533, + 0.3696777630084555, + 0.8641165765046979, + 0.528798508611114, + 0.4640875487852802, + 0.5512554995507564, + 0.7696801366506376, + 0.7178127737925943, + 0.3461809777431246, + 0.6222148100793095, + 0.858757350928604, + 0.35236372262143906, + 0.4576145991261486, + 0.6083524912313372, + 0.3252358120456467, + 0.6297340515973058, + 0.7159716648244022, + 0.43950155769183274, + 1.4249034722937208, + 0.32376309903631106, + 0.808976848332651, + 0.8659011825933237, + 0.5689268785494686, + 0.8315259442437558, + 0.16547331218289862, + 0.6421977022405546, + 0.6376211677913897, + 1.353956235829094, + 0.3238361028489701, + 1.0262471182597723, + 0.4741474584066382, + 0.6515487086011584, + 0.7005079521164748, + 0.4789506119495605, + 0.4169733441125094, + 1.0481914570006097, + 0.5439320707161615, + 1.1755937036078912, + 0.32497690362351694, + 0.9124932980314875, + 0.4598599130711467, + 0.8974580843532264, + 0.3037001785991491, + 0.7374977965442396, + 0.6602935716757922, + 0.9477228444836913, + 0.9964231433278297, + 0.3800754825238404, + 0.32562054808760776, + 0.6518864556227956, + 0.743024863854987, + 0.8989568410150501, + 0.3293274362893391, + 1.7976623890683028, + 0.42958901317338505, + 0.5361947571292651, + 1.5256200997953047, + 0.5561098068776773, + 0.5208085660988232, + 0.6814639986788364, + 0.2661557292694433, + 0.5145594536263682, + 0.4646482223156572, + 0.4655223328316692, + 0.7713147202936521, + 0.6173631621042597, + 1.148443626075058, + 0.27131978071328744, + 0.3567936808248244, + 0.5932952862084231, + 1.196347000417681, + 0.24622045523510824, + 0.5958305780675883, + 0.4458491818974152, + 0.661873720363832, + 1.5793067025395864, + 0.6324454132073014, + 0.5845177443151924, + 0.6947131054822484, + 0.9802479544759692, + 0.3474365372597377, + 1.3400184335270826, + 1.4154551041514576, + 0.5665485490473092, + 0.648052607361213, + 0.48767091885574276, + 0.46900531475748386, + 0.767488218518611, + 0.460067797877412, + 0.44876850839546245, + 0.8268487836979106, + 1.0424051232547957, + 0.79736898398815, + 0.6890551686592349, + 0.9278015170253744, + 0.29336281869517966, + 1.3635954811292765, + 0.4077206685677181, + 0.6363203740428239, + 0.332506695121208, + 0.2922280382687505, + 0.35708410362565834, + 1.2471605604684077, + 2.058150606944274, + 2.8380026136553065, + 2.597485654058433, + 1.8476743345236084, + 0.47208699609786503, + 1.489625478462226, + 1.8476743345236084, + 2.2619882652122514, + 2.2619882652122514, + 2.2619882652122514, + 2.7676757380202464, + 2.891988316701276, + 2.356505525463452, + 1.8476743345236084, + 2.4422042700327533, + 1.8476743345236084, + 2.9355189478843355, + 1.696683286712712, + 1.8153159638013143, + 2.356505525463452, + 3.314160295599997, + 2.597485654058433, + 2.058150606944274, + 1.8476743345236084, + 2.058150606944274, + 2.7676757380202464, + 3.0197310759414897, + 0.9778837577525286, + 1.8476743345236084, + 2.1096603421691764, + 1.5211271812256442, + 1.8814074215468057, + 2.058150606944274, + 1.987778688217865, + 1.7590373453822046, + 2.01733946810076, + 1.8476743345236084, + 1.7844618810384465, + 2.7676757380202464, + 2.4422042700327533, + 1.86426164770767, + 2.2619882652122514, + 3.5659509171218624, + 2.3661799545502045, + 2.597485654058433, + 2.1096603421691764, + 2.891988316701276, + 1.0753357012288185, + 2.2432439590948734, + 2.0055656145764855, + 2.567020134223122, + 1.8476743345236084, + 2.058150606944274, + 1.3939331234298173, + 2.114698314808771, + 2.4422042700327533, + 1.662580227087135, + 1.8476743345236084, + 2.4422042700327533, + 1.7844618810384465, + 2.4422042700327533, + 2.058150606944274, + 3.2090900715462665, + 1.656333347149456, + 2.6721842480715328, + 3.3423580099242747, + 2.597485654058433, + 2.2619882652122514, + 2.4422042700327533, + 1.6870498749506693, + 1.8476743345236084, + 2.224765684579568, + 2.2039918820672852, + 2.2619882652122514, + 2.4410842969168067, + 2.2810904181711433, + 2.891988316701276, + 2.876493519522545, + 3.5850673040480663, + 0.9764733001718929, + 1.2994320463445908, + 1.662580227087135, + 1.6863317636107102, + 2.4422042700327533, + 2.058150606944274, + 1.8476743345236084, + 2.1808240605894347, + 2.4422042700327533, + 1.9637531751001842, + 1.9946748054904933, + 2.724827540637997, + 2.3626336793216423, + 2.7676757380202464, + 1.8476743345236084, + 1.5211271812256442, + 2.2619882652122514, + 2.058150606944274, + 2.2810904181711433, + 2.1913009430783856, + 3.7106800250988194, + 2.4422042700327533, + 3.0197310759414897, + 3.469823829994782, + 2.8698168077828665, + 3.469823829994782, + 1.3874319744869243, + 2.5897137525317344, + 1.6954561861655968, + 2.4410842969168067, + 2.597485654058433, + 1.8476743345236084, + 3.288858152014848, + 2.4422042700327533, + 1.8476743345236084, + 2.4422042700327533, + 2.597485654058433, + 3.5659509171218624, + 2.058150606944274, + 2.2619882652122514, + 3.206287066324917, + 3.384015286101267, + 1.662580227087135, + 0.5458051850487717, + 0.6790050338290963, + 0.5023007567524906, + 1.2971978782253895, + 0.5522619646537907, + 0.883100350886447, + 0.837665589895814, + 0.5163519412873323, + 0.45143738777018017, + 0.6866600330579056, + 1.0317506959047822, + 0.20925742814353038, + 0.6876490455392779, + 0.6624271754722766, + 0.3210217229270562, + 0.3977850322637176, + 0.3224457893640078, + 0.20612229378985952, + 0.9428947397845716, + 0.6600482932017024, + 0.7233381922591419, + 1.6654429921844776, + 0.7320108163565322, + 0.9271265059721955, + 0.589517507717831, + 0.7216831635855714, + 1.0190525239152146, + 1.348718860335408, + 0.493861020599087, + 0.9729418439027716, + 0.3267368400240477, + 0.8827079472160331, + 0.815085704207946, + 0.8206679004859432, + 0.5902813501675037, + 0.3051564701033091, + 0.6668074205605357, + 0.6472424460242984, + 1.219459308614761, + 0.8713841650454931, + 1.013964585127423, + 0.5448203171620329, + 0.607201921919976, + 0.6289757381868517, + 0.32577370019109575, + 0.45827894160323324, + 1.0482020950106914, + 1.0269930389746258, + 0.7825458547785955, + 0.7240316981611505, + 0.7329146437333427, + 0.8234536460177988, + 0.30956555411224684, + 0.6954788354366838, + 0.5146195898520656, + 0.62793537963619, + 0.8242372077324298, + 0.8143590044700717, + 0.6879516279116785, + 0.5477104439245865, + 0.7033509704729236, + 0.4522720403700212, + 0.46530757575854054, + 0.3758010903716271, + 0.8774035239848066, + 0.15705640068424398, + 0.5651391450151954, + 1.4514353971742864, + 0.3693334732250173, + 0.3435882583171797, + 0.6157674717784961, + 0.4310116169910452, + 1.3187218739283795, + 0.41588564173163917, + 0.40866719346011027, + 0.30053069416316563, + 0.4480446500075471, + 0.3645610853885848, + 0.30105735617520335, + 0.3275756348415544, + 0.7996098084207804, + 0.649623130875256, + 0.498890881969495, + 0.49631189215461285, + 0.7110229154413295, + 0.8288160741147695, + 0.27227180758026326, + 0.5220894471320663, + 0.9537711527437408, + 0.4531876566989683, + 1.1452496476736154, + 0.4443441980253578, + 0.45273374383498627, + 0.1894962614127102, + 0.34490070332567013, + 0.6537962418976354, + 1.2889312049491835, + 0.6736719528347457, + 0.3782226733956778, + 0.5353283019675121, + 3.5526501774026036, + 2.058150606944274, + 1.949666463423513, + 2.7676757380202464, + 1.8476743345236084, + 3.0197310759414897, + 2.058150606944274, + 1.8476743345236084, + 1.2845157322572476, + 2.058150606944274, + 1.0004672504787429, + 2.4018155518380553, + 2.058150606944274, + 2.7623991597968542, + 2.1206154905540506, + 2.3036882389680624, + 2.4481076440196627, + 2.4749788514400475, + 1.6863317636107102, + 1.7274682727526334, + 1.806438411552133, + 2.058150606944274, + 1.949666463423513, + 1.8476743345236084, + 1.8476743345236084, + 1.662580227087135, + 2.340817939335098, + 1.6025274431324954, + 2.058150606944274, + 1.7033521065985138, + 2.058150606944274, + 1.10412180099796, + 3.115812494737077, + 2.4422042700327533, + 3.3793137163623843, + 2.4422042700327533, + 2.1808240605894347, + 1.4045292626743084, + 1.8476743345236084, + 1.2151521402160428, + 2.058150606944274, + 1.7844618810384465, + 2.2619882652122514, + 1.4907079969402144, + 2.264515291401005, + 2.058150606944274, + 3.115812494737077, + 2.2619882652122514, + 2.469167393905394, + 3.2090900715462665, + 1.9180454979641435, + 1.4959831486773143, + 3.0197310759414897, + 2.8113062941902314, + 2.1096603421691764, + 2.4422042700327533, + 2.2619882652122514, + 1.9180454979641435, + 2.597485654058433, + 2.2511133880306673, + 2.724827540637997, + 2.868467058830276, + 3.115812494737077, + 2.370179864374547, + 2.597485654058433, + 1.2140703893516092, + 1.708749939662904, + 2.2859864515254635, + 0.3662350625157961, + 0.6438173810469616, + 1.8856192484177727, + 0.5137727880008811, + 1.2323684099539332, + 0.9906028340501883, + 0.35447224096351526, + 0.8983358653006137, + 0.40558026019808213, + 0.8480297639716375, + 0.8258867601447343, + 0.6809214068393331, + 0.7068195336711045, + 1.1836424109366182, + 0.53112954729963, + 1.6558951494278125, + 0.549863875352374, + 0.3995052763605731, + 0.6972663592765592, + 1.242186825689887, + 0.33461005087199275, + 1.0522889529739954, + 0.5464337683102034, + 0.7231388961001773, + 0.5297772353783227, + 0.5481016608151191, + 0.46822685929798286, + 0.235912047496801, + 0.5979521659626125, + 0.43344654675572647, + 0.3470962991196599, + 0.4879991869055701, + 0.5094932042570063, + 0.2779439873778335, + 0.391275398604651, + 0.8408004347607203, + 2.1548154770360646, + 1.0841183352866843, + 0.8837521466917766, + 0.5961801058295195, + 0.36817015549469057, + 0.8887906865284904, + 0.38509705093043994, + 0.3874525079792172, + 1.0676522105559112, + 0.4376507616928824, + 0.7965033642156051, + 0.6823505974323025, + 1.1250232457285196, + 0.7270615548440059, + 1.2798905912993912, + 0.695004565225251, + 0.6254808363076224, + 0.9494043101470955, + 0.6779489764624549, + 0.20605112351479737, + 0.7898215662020942, + 0.6517447355288424, + 0.4270881312898781, + 0.3717502093056002, + 0.5628893332278374, + 0.7420630684224385, + 0.5873674021195082, + 0.3792710945890978, + 0.910705015755049, + 0.5373920298257194, + 0.27821554654621944, + 0.7794890842501492, + 0.36099442697420825, + 0.6871145838311798, + 0.6897076054202544, + 0.46761360404437974, + 0.41038170720808886, + 0.5433190906050183, + 0.44588394856845515, + 0.6653486889139937, + 0.7435925777668517, + 0.29186496693500547, + 0.7912237209942796, + 0.5849653483834436, + 0.36045126074515155, + 0.6761461480733921, + 0.43190765236436096, + 0.5773397530332129, + 1.0012576479357185, + 0.34999813804350766, + 0.2429927032458339, + 0.36452758397314267, + 1.034230644318328, + 0.797960910917451, + 1.3706578704113448, + 1.0740430809490944, + 0.20058335382258757, + 1.1142480210943293, + 0.4687911078737591, + 0.26700605469065325, + 1.2146682172136485, + 1.0138474129663502, + 0.6563004150304473, + 0.3361213328165003, + 0.8486717512214605, + 0.8580757899401549, + 0.5207253874581399, + 0.8149801787361919, + 0.8417101853911507, + 0.476777665098912, + 0.34965827538318767, + 0.49342571088497067, + 0.4301527165691852, + 0.7589836870766407, + 0.7303995604982741, + 0.6493237097307445, + 0.41785215428721956, + 0.573680198810453, + 0.7455277503159555, + 0.9215781697837119, + 0.6049560520072895, + 0.5336550505666926, + 0.7381751300367316, + 0.39902876703178514, + 0.6219838354818572, + 0.9238864006883777, + 0.5863841258240408, + 0.5157569909875965, + 0.14735357228511467, + 0.3481470341656606, + 0.5482341250260758, + 0.88075771080953, + 0.9146117975062364, + 0.2530120371260926, + 1.408267511793694, + 0.3627521253577207, + 0.7123319585115955, + 0.5803838858664114, + 1.0358875119850954, + 0.29346546372431037, + 0.6186514417030966, + 0.5268302983472591, + 0.6103874792106371, + 1.164151497670182, + 0.28740032867583154, + 0.5410503371961852, + 1.0830019016202237, + 0.36549605395047147, + 0.2746999610284035, + 0.924449961488848, + 0.4086554912985736, + 1.3462737139025898, + 0.4882836588878555, + 0.5566584617341775, + 0.9634285053196696, + 0.6398641087747852, + 0.28381940484073853, + 0.6205160355909927, + 0.6398155149917315, + 0.5429608926514402, + 0.36645442625349334, + 0.2268001025035173, + 0.3804895186120569, + 0.7671186866780728, + 1.1846785010621748, + 0.7649977077006127, + 0.7894941102293166, + 0.4363397242272647, + 0.709834965386332, + 0.9690774948719987, + 0.438364341419169, + 1.014906714955616, + 0.7313932993293148, + 0.7655997462690454, + 0.49969025173357984, + 0.4969834011017799, + 0.7138911076541652, + 1.0965053556202566, + 0.5201562369738414, + 0.530095391636028, + 0.4819825780444611, + 0.674685641623062, + 0.4586146114677802, + 0.41615962532936773, + 0.9723431853619636, + 0.6446578481279966, + 0.6096803843664454, + 0.45770948525055044, + 0.3529339046635806, + 0.2513034987568447, + 2.830033696841608, + 0.6568190836228676, + 0.282531824485043, + 0.30571696918126523, + 0.1361232947962784, + 0.3583139021392513, + 0.5041317225863386, + 1.0027392765442396, + 0.818146806653453, + 1.0813039951493129, + 0.6514845098486515, + 0.27796825128299646, + 0.9119626237136585, + 0.6278128119645964, + 1.8476743345236084, + 2.7676757380202464, + 2.1905454424666946, + 2.2619882652122514, + 2.058150606944274, + 1.1888957554904016, + 2.1416296414832114, + 1.8476743345236084, + 2.4422042700327533, + 1.8476743345236084, + 2.727014012968785, + 1.5825083942342786, + 2.2432439590948734, + 2.5825373427782976, + 3.115812494737077, + 1.3611333024799808, + 2.058150606944274, + 2.891988316701276, + 2.4422042700327533, + 2.7676757380202464, + 2.5380804918564293, + 1.781997180063116, + 1.3076856627804363, + 2.7909004579467633, + 2.058150606944274, + 1.8476743345236084, + 1.8476743345236084, + 1.412552018575346, + 2.597485654058433, + 1.3611333024799808, + 2.058150606944274, + 2.597485654058433, + 1.8476743345236084, + 2.6579524500706064, + 2.891988316701276, + 1.8476743345236084, + 3.0197310759414897, + 2.2619882652122514, + 2.9134177209476153, + 3.01099170118784, + 2.058150606944274, + 1.8476743345236084, + 2.4297198737860715, + 1.8476743345236084, + 2.313997164115918, + 1.8476743345236084, + 2.1158858357860773, + 1.9180454979641435, + 1.8476743345236084, + 2.4422042700327533, + 1.9180454979641435, + 1.7844618810384465, + 2.597485654058433, + 2.058150606944274, + 3.0197310759414897, + 1.806438411552133, + 2.6315373781043965, + 2.2619882652122514, + 0.6920419387658211, + 1.7844618810384465, + 2.2619882652122514, + 2.6579524500706064, + 1.8476743345236084, + 2.0262889541784586, + 2.2619882652122514, + 2.1907507605156096, + 2.058150606944274, + 2.2619882652122514, + 1.8476743345236084, + 3.469823829994782, + 2.1622354935334682, + 2.597485654058433, + 1.8476743345236084, + 2.891988316701276, + 2.597485654058433, + 2.058150606944274, + 2.597485654058433, + 0.781860196658726, + 2.6721842480715328, + 2.402968280296231, + 2.7943658550361237, + 3.0197310759414897, + 1.1288413975112799, + 2.3846970049563643, + 2.2859864515254635, + 2.2619882652122514, + 2.316120915941808, + 0.6359274808493538, + 1.8387557416124, + 2.853048452344537, + 1.8476743345236084, + 1.6528796261340795, + 1.8476743345236084, + 2.2511133880306673, + 1.750626419019596, + 2.2432439590948734, + 2.7601525910887723, + 2.925622821830588, + 0.8172869077368641, + 2.891988316701276, + 2.7676757380202464, + 2.058150606944274, + 1.7260740277663893, + 2.1096603421691764, + 1.949666463423513, + 1.347097373512335, + 0.911381138419854, + 2.6131542800439846, + 3.0197310759414897, + 2.058150606944274, + 2.597485654058433, + 1.8476743345236084, + 2.4422042700327533, + 1.9180454979641435, + 2.935818900897615, + 1.8476743345236084, + 2.1497076931363193, + 2.2544481879705343, + 2.058150606944274, + 0.29557855592904975, + 2.6512721345176056, + 2.7676757380202464, + 1.8476743345236084, + 2.2639784106505823, + 2.2619882652122514, + 1.8476743345236084, + 2.597485654058433, + 1.0533897642926922, + 2.1144626232308057, + 1.987778688217865, + 3.279394732288361, + 1.0154609669928254, + 2.058150606944274, + 2.08325008034921, + 2.058150606944274, + 2.2810904181711433, + 1.987778688217865, + 1.8476743345236084, + 2.891988316701276, + 2.058150606944274, + 2.597485654058433, + 2.058150606944274, + 2.401446499015322, + 1.8476743345236084, + 1.3611333024799808, + 2.2619882652122514, + 2.891988316701276, + 2.2511133880306673, + 2.2760412313709257, + 3.115812494737077, + 3.0197310759414897, + 1.949666463423513, + 2.3846970049563643, + 2.058150606944274, + 2.2619882652122514, + 2.2619882652122514, + 2.4422042700327533, + 2.058150606944274, + 2.2619882652122514, + 1.3507224322004856, + 0.41723457563198385, + 1.8476743345236084, + 2.015619478204368, + 3.115812494737077, + 2.2619882652122514, + 1.987778688217865, + 1.7719393859147898, + 2.1941478429787757, + 1.6863317636107102, + 2.2619882652122514, + 2.015619478204368, + 1.8476743345236084, + 1.7514132182974744, + 2.082465509310558, + 1.8476743345236084, + 3.2090900715462665, + 1.6025274431324954, + 1.8476743345236084, + 2.891988316701276, + 2.7311667983932253, + 2.428086058575861, + 1.1771260083504402, + 1.7697288692656943, + 0.9166604307929841, + 2.3469857869408033, + 1.8476743345236084, + 1.7863817692928663, + 1.949666463423513, + 2.058150606944274, + 2.2619882652122514, + 3.115812494737077, + 2.4422042700327533, + 1.463914074861662, + 2.469167393905394, + 1.8476743345236084, + 3.6287811278451905, + 2.891988316701276, + 1.8476743345236084, + 1.4686536953809721, + 2.5825373427782976, + 2.597485654058433, + 0.988262744875242, + 1.8476743345236084, + 2.7943658550361237, + 2.002718797933716, + 2.597485654058433, + 1.5440170594737004, + 2.5825373427782976, + 1.662580227087135, + 2.597485654058433, + 2.471327604768158, + 2.007552645936342, + 2.2619882652122514, + 2.2619882652122514, + 1.7844618810384465, + 2.597485654058433, + 2.015619478204368, + 1.6654429921844776, + 2.045284725989866, + 2.7676757380202464, + 2.2619882652122514, + 2.7676757380202464, + 1.8476743345236084, + 1.8476743345236084, + 0.8795188507528192, + 2.891988316701276, + 3.3793137163623843, + 1.8476743345236084, + 2.7676757380202464, + 2.058150606944274, + 2.2619882652122514, + 3.0197310759414897, + 2.891988316701276, + 1.5687643749231754, + 1.6939184569516472, + 2.9125366310514416, + 2.4422042700327533, + 2.6390896928252943, + 3.2090900715462665, + 2.489897419945101, + 2.2619882652122514, + 1.7244141325002005, + 2.4422042700327533, + 2.2619882652122514, + 2.727014012968785, + 2.2619882652122514, + 1.8476743345236084, + 2.2619882652122514, + 3.0197310759414897, + 2.3917072857704635, + 1.8277848094722016, + 1.686018244338074, + 1.987778688217865, + 1.3874319744869243, + 2.4297198737860715, + 1.8124086844135792, + 1.8476743345236084, + 1.5211271812256442, + 1.5211271812256442, + 2.1158858357860773, + 2.0229060766665996, + 2.070890982879892, + 2.4422042700327533, + 1.8476743345236084, + 2.058150606944274, + 2.4410842969168067, + 1.8476743345236084, + 1.8476743345236084, + 2.891988316701276, + 1.8476743345236084, + 2.2619882652122514, + 2.4422042700327533, + 1.3611333024799808, + 1.987778688217865, + 2.2619882652122514, + 3.469823829994782, + 3.0197310759414897, + 1.6863317636107102, + 1.8476743345236084, + 1.8476743345236084, + 2.773422945224246, + 1.8476743345236084, + 1.3611333024799808, + 3.314160295599997, + 2.1158858357860773, + 3.0197310759414897, + 1.3611333024799808, + 2.2619882652122514, + 1.3611333024799808, + 2.7676757380202464, + 1.88952715527254, + 2.058150606944274, + 2.469167393905394, + 2.4422042700327533, + 1.708749939662904, + 2.2619882652122514, + 2.058150606944274, + 2.2619882652122514, + 2.058150606944274, + 1.6105677745759317, + 2.610909537385862, + 3.314160295599997, + 2.7044189967296095, + 2.7676757380202464, + 2.130358293363134, + 1.7844618810384465, + 2.597485654058433, + 3.1844724070921675, + 1.8476743345236084, + 1.5211271812256442, + 2.058150606944274, + 1.0400348560292727, + 2.1158858357860773, + 2.7676757380202464, + 1.8476743345236084, + 3.115812494737077, + 2.2075573378630464, + 3.0197310759414897, + 3.115812494737077, + 2.2619882652122514, + 1.5581489256776342, + 3.0197310759414897, + 2.2619882652122514, + 2.7676757380202464, + 1.8140711116060495, + 1.7844618810384465, + 1.5898291282361523, + 2.3469857869408033, + 1.3874319744869243, + 2.5608129117539997, + 1.8476743345236084, + 1.8410928771720096, + 3.0197310759414897, + 1.8476743345236084, + 2.891988316701276, + 2.015619478204368, + 2.9134177209476153, + 0.9473690588927693, + 2.7676757380202464, + 1.9180454979641435, + 2.597485654058433, + 2.891988316701276, + 2.2619882652122514, + 1.7844618810384465, + 2.2619882652122514, + 2.4422042700327533, + 2.2619882652122514, + 1.8476743345236084, + 2.058150606944274, + 2.4422042700327533, + 2.891988316701276, + 3.384015286101267, + 1.662580227087135, + 1.3611333024799808, + 1.7862511328192499, + 0.9796005441355007, + 1.347097373512335, + 1.3611333024799808, + 2.4410842969168067, + 2.08325008034921, + 1.9180454979641435, + 3.5171516931029503, + 1.9180454979641435, + 2.567020134223122, + 2.058150606944274, + 2.4422042700327533, + 1.9180454979641435, + 2.891988316701276, + 1.8476743345236084, + 1.7844618810384465, + 2.2619882652122514, + 2.4422042700327533, + 3.2090900715462665, + 2.058150606944274, + 1.8476743345236084, + 2.058150606944274, + 1.3611333024799808, + 2.891988316701276, + 1.347097373512335, + 1.8476743345236084, + 2.4422042700327533, + 1.708749939662904, + 3.469823829994782, + 2.058150606944274, + 2.6041526391479004, + 1.949666463423513, + 1.7897988286019824, + 1.9420087035365758, + 3.0197310759414897, + 2.2619882652122514, + 1.8277848094722016, + 1.8476743345236084, + 2.2619882652122514, + 2.597485654058433, + 2.058150606944274, + 2.4422042700327533, + 1.6664528468124042, + 2.3499195705583533, + 0.4309134008047107, + 2.5065786589076757, + 2.5572779544191317, + 2.058150606944274, + 1.8476743345236084, + 2.058150606944274, + 1.470582209836203, + 2.058150606944274, + 2.482270985196589, + 1.8476743345236084, + 1.390835498459361, + 2.9134177209476153, + 2.4422042700327533, + 2.853048452344537, + 2.2619882652122514, + 2.1808240605894347, + 3.0197310759414897, + 2.2087638106167837, + 2.356505525463452, + 3.2090900715462665, + 2.1206154905540506, + 1.8453761779497113, + 1.347097373512335, + 1.5211271812256442, + 2.2619882652122514, + 2.4422042700327533, + 2.482270985196589, + 2.340817939335098, + 2.2619882652122514, + 1.949666463423513, + 1.5556701109850186, + 1.3611333024799808, + 2.891988316701276, + 2.2619882652122514, + 2.08325008034921, + 2.4422042700327533, + 2.5825373427782976, + 3.0197310759414897, + 1.987778688217865, + 3.384015286101267, + 1.3736307313750462, + 1.8476743345236084, + 2.597485654058433, + 3.314160295599997, + 1.987778688217865, + 1.8476743345236084, + 1.6488458280958025, + 2.058150606944274, + 1.0771259065559473, + 2.1913009430783856, + 2.058150606944274, + 2.3846970049563643, + 3.115812494737077, + 1.5211271812256442, + 2.349911855205372, + 2.597485654058433, + 1.7779461531040437, + 1.7181279321210134, + 2.4297198737860715, + 2.452355844311216, + 2.058150606944274, + 2.2810904181711433, + 1.48851217500864, + 2.891988316701276, + 2.2619882652122514, + 3.0197310759414897, + 3.0197310759414897, + 2.2619882652122514, + 2.853048452344537, + 2.891988316701276, + 1.8476743345236084, + 3.221506309947509, + 2.2619882652122514, + 1.3611333024799808, + 1.807100747035492, + 2.4422042700327533, + 2.4206363215557696, + 1.904581988988863, + 1.949666463423513, + 1.7058034655857854, + 3.172696211228355, + 2.2342609092376513, + 2.530158485422711, + 1.6863317636107102, + 1.614899260201113, + 2.4422042700327533, + 1.9180454979641435, + 2.597485654058433, + 2.058150606944274, + 2.2810904181711433, + 2.469167393905394, + 2.4422042700327533, + 1.347097373512335, + 2.058150606944274, + 2.8939364423454483, + 1.8616705403627694, + 2.058150606944274, + 2.597485654058433, + 1.7844618810384465, + 2.675192219603702, + 1.2545010706303312, + 2.3335152055386295, + 2.597485654058433, + 1.1176437656542713, + 1.3507224322004856, + 2.2619882652122514, + 1.5586412314360607, + 2.058150606944274, + 1.8476743345236084, + 1.8476743345236084, + 2.5164994042091156, + 1.8277848094722016, + 2.891988316701276, + 0.9892462043947926, + 1.8476743345236084, + 1.8476743345236084, + 1.5271104702215967, + 1.8476743345236084, + 1.8476743345236084, + 1.8476743345236084, + 1.8476743345236084, + 3.2090900715462665, + 1.3746506668276692, + 3.0197310759414897, + 1.3611333024799808, + 2.2619882652122514, + 1.662580227087135, + 2.058150606944274, + 2.2432439590948734, + 2.891988316701276, + 1.8719823539518994, + 3.2090900715462665, + 2.7676757380202464, + 1.6865786339164157, + 2.597485654058433, + 1.949666463423513, + 1.8476743345236084, + 2.4422042700327533, + 2.058150606944274, + 2.2619882652122514, + 1.8476743345236084, + 1.8476743345236084, + 1.8476743345236084, + 2.5408243830666897, + 2.891988316701276, + 2.058150606944274, + 1.4332584365796208, + 1.9180454979641435, + 1.723759417237108, + 2.891988316701276, + 2.4211598090759776, + 2.4221807532084085, + 2.2619882652122514, + 2.2619882652122514, + 1.7844618810384465, + 1.949666463423513, + 2.3846970049563643, + 1.8277848094722016, + 1.8277848094722016, + 2.058150606944274, + 1.8476743345236084, + 1.2151521402160428, + 2.3469857869408033, + 3.632934828272867, + 2.4297198737860715, + 2.058150606944274, + 1.944208649395649, + 1.6863317636107102, + 2.4422042700327533, + 2.058150606944274, + 1.8476743345236084, + 1.987778688217865, + 2.65068099238073, + 2.305483728777379, + 1.5211271812256442, + 2.1216965689390186, + 2.891988316701276, + 1.8124086844135792, + 2.597485654058433, + 2.058150606944274, + 3.0197310759414897, + 2.4410842969168067, + 2.067456031736355, + 1.8476743345236084, + 3.5850673040480663, + 1.7844618810384465, + 2.058150606944274, + 1.599083998110258, + 1.8476743345236084, + 2.058150606944274, + 1.8476743345236084, + 2.058150606944274, + 2.1158858357860773, + 1.1660040752988636, + 1.3960741838516837, + 2.597485654058433, + 3.0197310759414897, + 1.8363770715126349, + 2.4422042700327533, + 2.4422042700327533, + 1.3611333024799808, + 2.401446499015322, + 2.8380026136553065, + 1.861618374332186, + 1.9095248739686461, + 1.6863317636107102, + 1.6664528468124042, + 1.7849583554172694, + 1.987778688217865, + 2.597485654058433, + 1.8476743345236084, + 2.2619882652122514, + 1.5235690283057295, + 1.662580227087135, + 2.4422042700327533, + 2.4422042700327533, + 2.058150606944274, + 2.058150606944274, + 2.2619882652122514, + 2.1096603421691764, + 2.7676757380202464, + 3.18572773835532, + 2.1096603421691764, + 1.3611333024799808, + 1.1723612192556225, + 0.5885145288748457, + 0.7366160525185574, + 0.3907903326325138, + 0.40922827647793986, + 0.43920328835487027, + 0.6620139375451659, + 0.9089821651144331, + 0.288252903101609, + 0.7669242870295092, + 0.6088754965465408, + 0.9126178105641304, + 0.4380756093354068, + 1.1162822966961208, + 0.6420093336049633, + 0.4134065320983766, + 0.3863478611011368, + 1.2768206707109568, + 0.19180963543869903, + 0.6889789036048986, + 0.9200882760102052, + 0.47415895994092094, + 1.3392817676411157, + 0.23248646458603284, + 0.4992679280448552, + 0.6669043799243455, + 0.6158354501475514, + 0.4360004265610615, + 0.5162960987758392, + 0.6425383531381393, + 0.4910826104673675, + 0.5560784245658921, + 0.6248476592313638, + 0.6219751692272005, + 0.6481964232349476, + 0.5788505860237381, + 0.9768578885418294, + 0.4666711085817051, + 0.4495394970911584, + 1.0476866443235957, + 0.9338548174210819, + 0.4511870393154612, + 0.557348696701276, + 0.7210067097054507, + 1.0899014992676324, + 0.765558008811905, + 0.5656282093486633, + 0.758285723910893, + 0.8281897739731772, + 0.44161267907835844, + 0.4225717243756817, + 0.6137238531225426, + 0.5507101586377292, + 0.7474143586318259, + 0.6371383522880572, + 0.31662247420299605, + 0.3158770912311849, + 1.2244922733958796, + 0.764446949045235, + 0.7391610617909936, + 0.4220484050767924, + 0.6584375436872919, + 0.9453093873502504, + 1.1118668630536686, + 1.131460963869343, + 0.730673474546074, + 0.32038965444264633, + 0.677694529401831, + 0.5075092813169269, + 1.1150959482012874, + 0.4320695547416493, + 0.6327317732809948, + 0.27211096525621403, + 0.37873047516268965, + 0.4796521611027331, + 0.6742997617664506, + 0.7619655253033009, + 0.9858116608167131, + 0.39078104767230265, + 0.46633570681898195, + 0.5453574486469093, + 0.8120839931001426, + 0.8888309771612976, + 1.465352794077048, + 0.7183163802542554, + 0.5465409148680936, + 1.7049578681827036, + 0.45894163077613664, + 1.4644210089273453, + 0.6950864670449872, + 1.1682898756502569, + 0.8093268933862393, + 0.5324378019534519, + 0.9444896394564595, + 0.34539024352363656, + 0.4173002335171091, + 0.6497017940353962, + 0.4947884643684529, + 0.47027536649998186, + 0.8801511438997025, + 0.9166604307929841, + 2.4422042700327533, + 0.5715525285112733, + 1.2776376443999347, + 1.8476743345236084, + 1.2333576675458984, + 2.2619882652122514, + 3.0197310759414897, + 2.2619882652122514, + 2.2619882652122514, + 1.3611333024799808, + 1.4907079969402144, + 2.9355765938955307, + 1.3611333024799808, + 1.757494125725314, + 1.3507224322004856, + 1.4110227771922441, + 2.393216354510376, + 2.2619882652122514, + 2.058150606944274, + 2.597485654058433, + 2.058150606944274, + 2.002718797933716, + 1.8476743345236084, + 2.2619882652122514, + 1.8476743345236084, + 2.7676757380202464, + 2.058150606944274, + 1.1118761177627527, + 2.7828064443740637, + 2.058150606944274, + 1.8476743345236084, + 2.1096603421691764, + 1.8476743345236084, + 3.0197310759414897, + 2.1968744764999206, + 1.4901729388075804, + 2.7676757380202464, + 2.2619882652122514, + 2.058150606944274, + 2.9355765938955307, + 1.8476743345236084, + 2.409171451504832, + 1.8476743345236084, + 3.3423580099242747, + 1.9948385371730537, + 2.597485654058433, + 1.949666463423513, + 1.8277848094722016, + 2.2432439590948734, + 1.5211271812256442, + 3.166676545050257, + 3.115812494737077, + 1.5436830185764618, + 0.7542196156964736, + 0.5513470023039677, + 0.3994436702934644, + 0.6418959190202352, + 0.6548407723955089, + 0.20363362477789393, + 0.6701939035064541, + 0.8039722785600939, + 0.5610543599030255, + 0.8236355111557987, + 1.2400495730303245, + 0.2915597814418503, + 0.5790801524906717, + 0.8787051511248617, + 0.9279882634881246, + 0.34011410366179495, + 0.3256345529301269, + 1.1628242253937224, + 0.9684706790739468, + 0.43454290361211667, + 1.233896492124341, + 1.3632186536300677, + 0.7451283529372004, + 0.40762258979105676, + 0.537200880548968, + 0.25222943358885375, + 0.4283948707916668, + 1.4124723383632987, + 0.5315229519075193, + 0.5738178056068475, + 0.3572144933363075, + 0.9482073855634467, + 0.88910879172971, + 1.210088514669295, + 0.7567901890456726, + 0.8307166425222663, + 0.635367011702961, + 0.4808554059417653, + 0.42016271102298675, + 0.6903380469950502, + 0.6450328730967976, + 0.8946330145808801, + 0.39330740871822045, + 0.8813789192594412, + 0.5286317961801489, + 1.0342614295709622, + 0.2542143012268936, + 0.38264167213075406, + 0.4977326795183435, + 0.6613333928111191, + 1.0611625920488619, + 1.0038170350635942, + 0.2125643555517387, + 0.3666584918095976, + 0.45242527994984116, + 0.2948191586824634, + 0.7628418305357917, + 0.3145086122083478, + 0.21179467643944172, + 0.8700497545566026, + 1.2346931292070669, + 0.49271854475723204, + 0.8372941500634147, + 0.47504897746623287, + 1.1780333835070778, + 0.9572301410990853, + 0.8139463892790011, + 0.4624241744032896, + 0.8120611809280417, + 1.3323745460019687, + 0.38045401569280324, + 0.9541509754340622, + 0.9726622614188398, + 0.8094493127061057, + 0.97760419145256, + 0.5685222968406481, + 0.617152886903962, + 1.575166600747739, + 1.144809567853751, + 0.6053589920757121, + 0.5190978369312553, + 0.5638556234469738, + 0.4783138381581102, + 0.36570596049520454, + 1.0415347878441068, + 0.8641246804653614, + 0.3423099717510246, + 0.49134639975231953, + 1.0072504907799786, + 0.5817964371054746, + 0.595125736247504, + 0.7316905095300072, + 0.41114810126226325, + 0.35807237869744896, + 0.39673718823020276, + 1.0472127511268012, + 0.42504583902599347, + 0.9455964573854402, + 0.9383857301857403, + 0.7115533711983039, + 1.1599177313256082, + 1.2349239514235264, + 0.3608745124636136, + 0.4987221092370251, + 0.3852899785322016, + 0.6018624624824563, + 0.7161061407963225, + 0.5265688314793839, + 0.7354342261159976, + 0.48902463489895637, + 0.5364788631209761, + 0.8107613477229922, + 1.1918180069833664, + 0.4741217825151731, + 0.5765608714533847, + 0.3034106129315763, + 0.9492631535756442, + 0.27658002278992505, + 0.9291893493084616, + 1.068355570178985, + 0.6635936058140268, + 0.6839399046539646, + 0.40892746241590316, + 0.5154965939645362, + 0.6676868494222153, + 0.6379185977408711, + 0.3031907614173356, + 0.6650789101980611, + 0.5536872026472713, + 0.6765197178004443, + 0.7775688919054491, + 0.9942982730753072, + 0.9406410280567752, + 0.631791631023142, + 1.1715275451954992, + 0.2996747764104549, + 0.9281584248021097, + 1.483295577685483, + 0.3929072509713082, + 0.8662989472333867, + 0.5302941123272424, + 0.8030142911188143, + 0.9915257317860644, + 1.2401241200517288, + 0.945675318726619, + 0.4564046317541012, + 0.4772926946953529, + 1.055150394519834, + 0.4955716203722378, + 0.33991317250260544, + 1.311590690315936, + 0.3172220066869569, + 0.497439811921327, + 0.82576471611232, + 0.20757510088592407, + 0.7160721921077896, + 0.676957957993238, + 0.557068805237366, + 0.41890475989258713, + 0.5724495892657434, + 0.42217364064871704, + 1.620260553103607, + 0.5533313879061184, + 0.25062804428769025, + 0.12320250629341145, + 0.6138630238919573, + 0.577520459987062, + 0.341583686308374, + 1.298929395086288, + 0.673360999283774, + 0.6212410977878695, + 0.7951474625100415, + 0.49728262881962504, + 0.5006941875300917, + 0.3397906894866838, + 0.5702025535779618, + 0.38315757008838414, + 0.4567723913232665, + 0.3809599062109163, + 1.9918979450689656, + 0.43075841977596646, + 0.6884386757613254, + 0.5134051900330422, + 1.0835052084097687, + 0.7636522553649877, + 0.6159924698948236, + 0.5513670335623573, + 0.7013620487149995, + 0.8596963069755713, + 0.5517065874449533, + 1.6192171027318538, + 0.37162529600152283, + 0.9230922665442419, + 0.34090359155833194, + 0.9519598583818432, + 0.5345656593195319, + 0.4753806264384485, + 0.4927258550213174, + 0.9794199897443665, + 2.058150606944274, + 1.3611333024799808, + 2.2619882652122514, + 2.2619882652122514, + 1.7844618810384465, + 1.8664528416006843, + 2.4017927530052914, + 1.8476743345236084, + 2.597485654058433, + 3.384015286101267, + 2.2619882652122514, + 1.8476743345236084, + 1.8476743345236084, + 2.058150606944274, + 1.7679364906618558, + 1.8476743345236084, + 0.4076570877896411, + 2.2619882652122514, + 2.058150606944274, + 1.6105677745759317, + 2.7676757380202464, + 2.559118308588223, + 1.8476743345236084, + 1.4815070865925652, + 3.0261096518667245, + 1.8546892407507647, + 2.724827540637997, + 2.5825373427782976, + 0.9931825695469596, + 1.88952715527254, + 2.891988316701276, + 2.2619882652122514, + 3.5659509171218624, + 2.058150606944274, + 2.4422042700327533, + 2.597485654058433, + 1.8476743345236084, + 3.0197310759414897, + 0.9050982905224136, + 3.115812494737077, + 2.7676757380202464, + 2.058150606944274, + 1.5211271812256442, + 2.597485654058433, + 3.5659509171218624, + 1.347097373512335, + 1.1118761177627527, + 2.058150606944274, + 1.8277848094722016, + 2.7676757380202464, + 1.8476743345236084, + 2.4422042700327533, + 1.8476743345236084, + 1.7844618810384465, + 1.8476743345236084, + 3.321772667529218, + 1.8476743345236084, + 0.21509599789688186, + 1.3147091885023405, + 0.40354462435052785, + 1.0126901918670361, + 0.43414566639245067, + 0.2985871422528784, + 0.7669092993242963, + 0.528737825380968, + 0.9773255541326447, + 0.6222943889636857, + 0.7574845815053228, + 0.5790873771547744, + 0.7588789903748617, + 0.32436068828968057, + 0.6362039828075197, + 0.37202957822865135, + 0.4902240316316069, + 0.5240205205371544, + 0.9778449568507234, + 0.5758992172026949, + 0.27075727300975944, + 0.9069925707750641, + 1.1264883070431284, + 0.36091550961967644, + 0.6211331878193396, + 1.325432326921428, + 0.4634185957046415, + 0.5048319420678097, + 0.5091554936548096, + 0.6043311493116568, + 0.776966878420086, + 1.7283004110729867, + 0.6227596127315709, + 0.6372713680949619, + 0.3288808287607252, + 0.17378323627389883, + 0.36434698764330065, + 1.1991702882377329, + 0.6346485750644904, + 1.1593716482789436, + 0.8528766993774286, + 0.7415110484187379, + 0.5779041542388141, + 0.6998183360337095, + 0.7831771963347314, + 0.23565705381673982, + 0.9536761859534664, + 0.2724682428141557, + 0.6570358748429335, + 0.6047850930665983, + 0.7042937182145386, + 0.289293573485846, + 1.157304857214605, + 1.212529398868987, + 0.6555840239099037, + 1.016659927059014, + 1.7473660966511915, + 0.4933095318222499, + 0.7394307412307496, + 0.3597168412605192, + 0.4896972881308841, + 0.38657802278582937, + 0.33589903552211486, + 0.8167477402057872, + 0.5049444871245954, + 0.23302892671104053, + 0.5794382930145557, + 0.3954866121169828, + 0.5920677823436746, + 0.2876771655297422, + 0.6910640268747459, + 0.8808856067797478, + 0.3530193487240659, + 0.500177470492938, + 0.19804698376613028, + 0.567077967461159, + 0.38236930187469365, + 0.6230986386653155, + 0.9855593000792289, + 0.5510958295096722, + 0.7467501242088053, + 0.4809563975137039, + 1.437750448743034, + 0.7268857016462144, + 0.49704316629672646, + 0.5823728413124502, + 0.5510618704309607, + 0.4784728729127232, + 0.4824746166376641, + 0.44177294095653596, + 0.8421143339820081, + 0.9901776692789208, + 0.7909191828349422, + 0.2698446727142, + 0.2354416506397474, + 0.3828995490196857, + 0.8559752889728478, + 0.44896891529645605, + 0.6198617486749185, + 0.377078972297536, + 0.5083142549893032, + 0.37725103181117037, + 0.5142688696621351, + 0.759062400922502, + 0.4892446788063581, + 1.0991510483702978, + 1.4045292626743084, + 0.3817137301349665, + 0.5452864270439886, + 0.3900082617036913, + 0.5826187046414137, + 0.7495579693423243, + 0.8332811155525393, + 0.37774457377197307, + 0.5996231671579608, + 0.7744053727704714, + 1.1953139657657108, + 0.6356456230809115, + 0.4799116569286271, + 0.5491430992999602, + 1.0214885465998547, + 0.5608917014486795, + 0.6047515819610292, + 1.0629847118984488, + 0.7557354588171327, + 0.485189859837843, + 0.6096706076198806, + 0.21132860306613513, + 0.473229734704798, + 0.36398225301358333, + 0.6485961386780053, + 0.8542921232410083, + 0.9461059851433122, + 0.8526524160411616, + 1.4376015936531914, + 0.41396123822417114, + 0.7145374961230413, + 0.7433776434675898, + 0.8130406780376078, + 0.4594464143374314, + 0.6191060413023497, + 0.26951566082169415, + 0.30318598904352434, + 0.4878168379240263, + 0.5751709750760663, + 0.9123804332837644, + 0.8019319657395161, + 1.097587017826096, + 1.078189962084794, + 0.7028558615866549, + 0.38162887242049115, + 0.6286148375475461, + 2.151825162991765, + 0.21395830269097776, + 1.0613011849049072, + 0.9809629380567332, + 0.6444260962997133, + 0.4899037851376819, + 0.5332277600074474, + 0.7265859814926696, + 0.6061510411185914, + 1.2220490959399997, + 0.46724232341169913, + 0.5014802126672564, + 0.7168060175491753, + 1.2389585446375608, + 0.7154847785870423, + 0.7603162048653136, + 0.9875397798038623, + 0.7293130684960718, + 0.899279810435844, + 0.9149721438729228, + 0.826982216905313, + 1.0538865781097209, + 0.6007702313440549, + 0.5654572352952939, + 0.6879264790176625, + 0.5903570760627599, + 0.9319324463529745, + 1.2867701570447627, + 0.9119133893533078, + 0.491218576642952, + 0.8576895783761427, + 0.47562797833489395, + 0.47437130683998807, + 1.0332971003747438, + 1.5235059011316645, + 1.103528099248392, + 0.9998100729744722, + 0.9618713854594367, + 1.19753095301947, + 0.8698216509467644, + 0.42090871967267585, + 0.49305976912795124, + 0.5763282195410873, + 0.617946612674193, + 0.7718434794621206, + 0.5234518129827728, + 0.5537722870905155, + 0.750385144531332, + 0.2989826467124755, + 1.3210411054636357, + 0.6649363577546691, + 0.6633531535632768, + 0.2874591596398981, + 0.477884628498046, + 0.43216877626756667, + 0.5550896242568504, + 1.0928623770341792, + 0.5254980414077653, + 0.9898147547512566, + 0.3207476839000583, + 0.9111016500744281, + 0.512133698431171, + 0.4586351192621185, + 1.2622267587316534, + 1.14394644125341, + 0.7781342504869209, + 0.6237527848318463, + 0.671376959441105, + 0.3970177088435465, + 0.36993661284400203, + 0.39211056647124054, + 0.523058199668295, + 0.9921828157516387, + 0.2826030437040816, + 0.8218777871689718, + 0.8334301096197657, + 0.8237748978873287, + 0.631847602671398, + 0.4355775178269065, + 0.42008298716729964, + 0.27044649369959645, + 0.5405606834560776, + 0.7260759032158105, + 0.5013128237916186, + 1.0495087077310556, + 1.102394292393606, + 0.6165461746592604, + 0.3896432792172122, + 0.6724992781126164, + 1.0994418406222652, + 0.3468932392737828, + 0.7200354333957963, + 0.5195349434647462, + 0.6189335203426607, + 0.2211263122617614, + 0.8607683477019984, + 0.6395270242497546, + 0.2411892917672887, + 0.6883640265506923, + 0.8480863930978091, + 0.8114860249160465, + 1.0677484582095707, + 1.1498632006349205, + 1.158706756808452, + 0.4058785298594086, + 0.481185581266143, + 0.36209744032467506, + 0.7770114286954282, + 0.4248640050356416, + 0.6976311712345302, + 0.5507517924840513, + 0.9358692715695005, + 0.7162280500575352, + 0.5991789225925669, + 0.7298010028420633, + 0.9189853495080513, + 0.8893752358436698, + 1.0223980853903794, + 0.41703098450625886, + 0.5021058901862736, + 0.3596731822581092, + 0.5753821362694784, + 1.0225671904149018, + 0.6124620265431738, + 0.7004980836256519, + 0.6926653160006948, + 0.6355451885933774, + 0.793101103585178, + 0.6168141299149756, + 0.8651241882947558, + 0.31154174745517904, + 0.24656042731578548, + 0.6679473050896942, + 0.8845830016374459, + 1.7649824601817334, + 0.7778586181518201, + 0.6858035686038916, + 0.7818298640553017, + 0.856439685529943, + 0.6435594457853276, + 0.69753734534075, + 1.5313563119227958, + 0.4034794768180018, + 0.8748755513989019, + 0.34796361478647814, + 1.0604865300986481, + 1.1746873830989792, + 0.251894258611277, + 1.5211271812256442, + 2.058150606944274, + 1.3611333024799808, + 2.729069372966599, + 1.3611333024799808, + 1.861618374332186, + 2.2619882652122514, + 1.9553015285410429, + 2.058150606944274, + 2.891988316701276, + 1.8476743345236084, + 2.2619882652122514, + 1.8476743345236084, + 2.7676757380202464, + 1.8273752314781504, + 1.9714306767089713, + 3.0197310759414897, + 1.8476743345236084, + 2.6579524500706064, + 2.2619882652122514, + 2.058150606944274, + 1.8476743345236084, + 1.8476743345236084, + 1.6240925782806817, + 1.8476743345236084, + 1.8476743345236084, + 1.8476743345236084, + 1.8476743345236084, + 2.9355189478843355, + 3.2090900715462665, + 2.7798341040219183, + 1.7844618810384465, + 2.058150606944274, + 2.058150606944274, + 2.597485654058433, + 1.8476743345236084, + 1.8476743345236084, + 1.8476743345236084, + 2.3311659799232376, + 1.8476743345236084, + 2.4422042700327533, + 2.058150606944274, + 2.597485654058433, + 0.98987736829218, + 1.9180454979641435, + 2.5304752857289596, + 1.8476743345236084, + 3.1481561191964627, + 1.6863317636107102, + 1.8476743345236084, + 1.1207992541228984, + 1.8476743345236084, + 2.4422042700327533, + 1.3611333024799808, + 2.058150606944274, + 1.8476743345236084, + 2.4422042700327533, + 2.891988316701276, + 2.722482536804198, + 2.058150606944274, + 1.4826676654967779, + 2.7676757380202464, + 1.2578570194114627, + 1.8476743345236084, + 2.4422042700327533, + 2.4422042700327533, + 2.058150606944274, + 3.314160295599997, + 1.3611333024799808, + 1.722626815349451, + 1.3611333024799808, + 1.8476743345236084, + 2.4422042700327533, + 3.314160295599997, + 2.2619882652122514, + 2.0490816222984223, + 2.4018155518380553, + 1.8476743345236084, + 2.1808240605894347, + 2.4422042700327533, + 2.597485654058433, + 2.168899404432432, + 2.058150606944274, + 2.4422042700327533, + 2.4422042700327533, + 1.8476743345236084, + 1.8476743345236084, + 2.058150606944274, + 1.7844618810384465, + 1.347097373512335, + 2.058150606944274, + 1.3611333024799808, + 1.5211271812256442, + 1.9154398697171597, + 3.632934828272867, + 2.7676757380202464, + 2.08325008034921, + 2.5825373427782976, + 1.8476743345236084, + 2.058150606944274, + 3.115812494737077, + 2.2619882652122514, + 1.6863317636107102, + 2.4410842969168067, + 2.058150606944274, + 2.058150606944274, + 2.4422042700327533, + 1.949666463423513, + 2.8209032200551674, + 1.8476743345236084, + 1.4936454961781072, + 1.6863317636107102, + 1.8476743345236084, + 2.6721842480715328, + 1.5211271812256442, + 1.559885894181154, + 3.314160295599997, + 2.891988316701276, + 1.5211271812256442, + 1.6863317636107102, + 1.662580227087135, + 1.9038185430588073, + 1.8476743345236084, + 3.0197310759414897, + 2.2619882652122514, + 1.949666463423513, + 1.8476743345236084, + 1.8476743345236084, + 3.1112580587695486, + 3.115812494737077, + 2.0713439829114506, + 2.2619882652122514, + 2.015619478204368, + 2.2619882652122514, + 0.9715445601406758, + 1.987778688217865, + 2.0446248507910894, + 2.2511133880306673, + 1.8476743345236084, + 2.891988316701276, + 2.3313420400284293, + 1.328343782877219, + 1.0811184793016397, + 3.314160295599997, + 0.866905419280513, + 2.2619882652122514, + 2.5065786589076757, + 2.08325008034921, + 2.08325008034921, + 1.5211271812256442, + 2.08325008034921, + 3.115812494737077, + 1.8476743345236084, + 2.2619882652122514, + 1.8476743345236084, + 1.662580227087135, + 2.264515291401005, + 2.3565587288446603, + 2.058150606944274, + 2.7676757380202464, + 0.9657218792010503, + 1.8829205119268706, + 1.8476743345236084, + 2.058150606944274, + 1.390835498459361, + 2.1808240605894347, + 2.4422042700327533, + 2.8092606085981515, + 2.058150606944274, + 1.2151521402160428, + 2.7676757380202464, + 2.08325008034921, + 2.891988316701276, + 1.8476743345236084, + 2.4018155518380553, + 2.7676757380202464, + 2.4422042700327533, + 2.2619882652122514, + 2.2619882652122514, + 2.891988316701276, + 1.3611333024799808, + 2.482270985196589, + 2.891988316701276, + 2.262524635132258, + 2.891988316701276, + 2.2810904181711433, + 2.891988316701276, + 1.7844618810384465, + 1.8476743345236084, + 2.08325008034921, + 2.08325008034921, + 2.2619882652122514, + 1.8476743345236084, + 1.8476743345236084, + 0.1672629185600277, + 1.2339000502528295, + 2.7377362560735974, + 2.935818900897615, + 1.8476743345236084, + 1.3507224322004856, + 1.2474464097471953, + 1.5211271812256442, + 2.2619882652122514, + 1.7597846426973422, + 1.662580227087135, + 2.058150606944274, + 1.4463493534700764, + 2.2619882652122514, + 1.3611333024799808, + 1.5211271812256442, + 2.2619882652122514, + 1.8476743345236084, + 3.0197310759414897, + 2.4422042700327533, + 2.058150606944274, + 2.4422042700327533, + 2.6067218366474094, + 2.058150606944274, + 2.264515291401005, + 1.9420087035365758, + 2.597485654058433, + 2.732838581816158, + 1.2943316326428753, + 2.7676757380202464, + 3.0197310759414897, + 2.1078664481516696, + 0.2244954489037876, + 3.0197310759414897, + 1.8476743345236084, + 1.8476743345236084, + 1.9180454979641435, + 2.6044958064392825, + 2.386367233283088, + 1.2151521402160428, + 1.628245864676951, + 1.8476743345236084, + 1.7690272375521627, + 1.6863317636107102, + 2.597485654058433, + 3.2090900715462665, + 2.058150606944274, + 2.8209032200551674, + 1.8476743345236084, + 2.7676757380202464, + 3.582079689185183, + 2.2434367401361124, + 2.4422042700327533, + 0.8798520439687282, + 2.058150606944274, + 2.414837699091072, + 2.4422042700327533, + 1.463914074861662, + 2.1096603421691764, + 2.058150606944274, + 1.3817670325354245, + 1.6865786339164157, + 1.967360796217879, + 1.8476743345236084, + 1.8476743345236084, + 2.058150606944274, + 2.4422042700327533, + 2.7676757380202464, + 2.058150606944274, + 2.0325599191602324, + 2.015619478204368, + 1.7844618810384465, + 2.597485654058433, + 2.2619882652122514, + 1.8277848094722016, + 2.5897137525317344, + 2.597485654058433, + 2.4422042700327533, + 1.8476743345236084, + 1.8476743345236084, + 1.8476743345236084, + 1.1118761177627527, + 1.6105677745759317, + 2.4422042700327533, + 2.3164861275302515, + 3.115812494737077, + 2.2619882652122514, + 2.2810904181711433, + 2.4138449742382626, + 2.7798341040219183, + 2.7943658550361237, + 1.9555292462161882, + 2.2810904181711433, + 2.868467058830276, + 2.2619882652122514, + 0.6821783001018737, + 2.597485654058433, + 2.08325008034921, + 2.2619882652122514, + 1.328343782877219, + 1.8476743345236084, + 2.7676757380202464, + 2.2227908658380393, + 2.7676757380202464, + 1.2474464097471953, + 2.08325008034921, + 2.5336432602451078, + 1.6025274431324954, + 3.314160295599997, + 3.2090900715462665, + 2.058150606944274, + 2.891988316701276, + 1.3507224322004856, + 2.4422042700327533, + 2.4297198737860715, + 1.8476743345236084, + 2.7732174970692554, + 1.6863317636107102, + 2.4422042700327533, + 2.4422042700327533, + 1.8476743345236084, + 2.5370167909997647, + 1.3507224322004856, + 0.9225145384731542, + 0.9225145384731542, + 1.949666463423513, + 2.2619882652122514, + 1.987778688217865, + 2.058150606944274, + 1.6571228230119934, + 3.145811115362664, + 2.3469857869408033, + 2.1776980309373184, + 1.5554565377911724, + 3.0197310759414897, + 1.723759417237108, + 1.949666463423513, + 1.7332585000760898, + 1.987778688217865, + 2.7676757380202464, + 2.5825373427782976, + 3.0197310759414897, + 2.6315373781043965, + 2.058150606944274, + 2.0317836289157807, + 1.8476743345236084, + 1.8476743345236084, + 1.3611333024799808, + 2.058150606944274, + 3.115812494737077, + 1.6870498749506693, + 2.340817939335098, + 2.2432439590948734, + 1.8476743345236084, + 2.1808240605894347, + 1.143100147117953, + 3.115812494737077, + 2.2619882652122514, + 2.8848214193836603, + 2.4422042700327533, + 1.8996078228054951, + 0.9920163401270353, + 1.8476743345236084, + 1.328343782877219, + 2.3528358706012247, + 1.8476743345236084, + 2.058150606944274, + 1.8363770715126349, + 2.2810904181711433, + 3.1747674508067196, + 0.9764733001718929, + 1.390835498459361, + 2.471151544662966, + 2.891988316701276, + 1.390835498459361, + 2.891988316701276, + 2.058150606944274, + 2.058150606944274, + 1.8476743345236084, + 2.2619882652122514, + 1.3960741838516837, + 1.0638348510133466, + 2.2783361462867595, + 2.891988316701276, + 1.9986731705586258, + 2.058150606944274, + 1.8476743345236084, + 1.8476743345236084, + 1.8476743345236084, + 2.0585775509943334, + 1.3507224322004856, + 2.2619882652122514, + 2.058150606944274, + 2.058150606944274, + 3.011269853644358, + 1.9180454979641435, + 2.597485654058433, + 2.891988316701276, + 1.7844618810384465, + 2.58774284055305, + 2.058150606944274, + 2.058150606944274, + 2.597485654058433, + 2.597485654058433, + 2.4410842969168067, + 1.723759417237108, + 2.8380026136553065, + 1.9180454979641435, + 0.8631906024015857, + 1.8476743345236084, + 2.891988316701276, + 1.8476743345236084, + 1.8277848094722016, + 2.7676757380202464, + 2.356505525463452, + 1.9097144340054233, + 1.6025274431324954, + 2.597485654058433, + 2.058150606944274, + 2.5897137525317344, + 2.2619882652122514, + 2.058150606944274, + 2.058150606944274, + 2.058150606944274, + 2.6721842480715328, + 2.891988316701276, + 2.7676757380202464, + 2.058150606944274, + 2.4422042700327533, + 3.18572773835532, + 2.058150606944274, + 1.8476743345236084, + 3.2090900715462665, + 1.9309054181401635, + 2.058150606944274, + 2.935818900897615, + 2.853048452344537, + 1.3874319744869243, + 2.058150606944274, + 1.8476743345236084, + 2.058150606944274, + 1.8476743345236084, + 1.8476743345236084, + 2.370179864374547, + 1.8476743345236084, + 1.4094709820638498, + 2.891988316701276, + 2.058150606944274, + 1.6863317636107102, + 2.0016039390719147, + 2.6997997486116994, + 1.6863317636107102, + 3.0197310759414897, + 3.0197310759414897, + 1.1118761177627527, + 1.8476743345236084, + 2.597485654058433, + 2.4422042700327533, + 2.1158858357860773, + 2.6579524500706064, + 1.8476743345236084, + 1.4035359816282003, + 2.058150606944274, + 2.026969075021646, + 1.8476743345236084, + 2.08325008034921, + 2.9047247906986513, + 2.058150606944274, + 2.5665446477412797, + 2.1158858357860773, + 1.8476743345236084, + 2.7676757380202464, + 1.9807214091741887, + 3.0197310759414897, + 1.9180454979641435, + 2.4987749721942825, + 2.891988316701276, + 2.7676757380202464, + 1.662580227087135, + 2.2546838795485, + 1.7844618810384465, + 2.1637026742283343, + 3.314160295599997, + 2.4422042700327533, + 1.987778688217865, + 2.891988316701276, + 1.8476743345236084, + 1.941350488441066, + 2.2511133880306673, + 2.4422042700327533, + 2.058150606944274, + 2.7676757380202464, + 1.4249034722937208, + 2.891988316701276, + 1.5001813171582765, + 2.4422042700327533, + 2.058150606944274, + 2.2619882652122514, + 1.7844618810384465, + 1.8476743345236084, + 1.8476743345236084, + 2.2619882652122514, + 2.1096603421691764, + 2.2619882652122514, + 2.228916087544387, + 2.2619882652122514, + 2.597485654058433, + 2.1096603421691764, + 2.6417973029032478, + 2.4422042700327533, + 2.058150606944274, + 2.058150606944274, + 1.4642794718014343, + 2.058150606944274, + 2.482270985196589, + 2.058150606944274, + 2.058150606944274, + 2.4422042700327533, + 1.9180454979641435, + 2.058150606944274, + 3.5659509171218624, + 1.546593069176687, + 2.058150606944274, + 2.891988316701276, + 1.4991607541661076, + 1.3611333024799808, + 2.264515291401005, + 1.6863317636107102, + 2.2619882652122514, + 2.597485654058433, + 2.2619882652122514, + 1.5038129118856802, + 2.1808240605894347, + 2.058150606944274, + 2.6131542800439846, + 2.724827540637997, + 2.058150606944274, + 1.3611333024799808, + 2.058150606944274, + 2.058150606944274, + 1.8476743345236084, + 1.8329010215046986, + 2.4422042700327533, + 1.8476743345236084, + 2.058150606944274, + 1.662580227087135, + 2.4422042700327533, + 1.7697288692656943, + 1.8476743345236084, + 2.4422042700327533, + 2.597485654058433, + 2.264515291401005, + 2.058150606944274, + 1.9016741025619868, + 2.7676757380202464, + 3.469823829994782, + 2.180647674397531, + 1.5211271812256442, + 2.058150606944274, + 3.0197310759414897, + 2.891988316701276, + 1.6219238337408712, + 2.058150606944274, + 2.058150606944274, + 2.2619882652122514, + 2.356505525463452, + 1.559885894181154, + 1.4578072976086758, + 1.662580227087135, + 2.1913009430783856, + 3.314160295599997, + 2.058150606944274, + 2.058150606944274, + 3.115812494737077, + 3.0197310759414897, + 3.0197310759414897, + 1.9432312299891945, + 0.8345450745864135, + 2.2619882652122514, + 2.597485654058433, + 2.2511133880306673, + 1.8270354396903983, + 2.4422042700327533, + 2.3661799545502045, + 1.6863317636107102, + 3.01099170118784, + 2.058150606944274, + 2.395244785532269, + 3.115812494737077, + 1.8862015464929511, + 2.6343719762904607, + 2.9355765938955307, + 1.8476743345236084, + 3.0197310759414897, + 2.597485654058433, + 1.8476743345236084, + 2.058150606944274, + 2.058150606944274, + 2.7098229290372036, + 2.4422042700327533, + 2.7676757380202464, + 3.384015286101267, + 1.662580227087135, + 1.1118761177627527, + 1.8476743345236084, + 2.2511133880306673, + 2.2619882652122514, + 1.662580227087135, + 2.058150606944274, + 2.304248759758008, + 2.2619882652122514, + 1.8476743345236084, + 2.7676757380202464, + 1.8476743345236084, + 1.559885894181154, + 3.314160295599997, + 3.2598875143844763, + 2.2432439590948734, + 2.325363679779433, + 2.058150606944274, + 1.8476743345236084, + 2.304114488445587, + 3.5659509171218624, + 2.058150606944274, + 2.2619882652122514, + 2.2923559031915173, + 2.1905454424666946, + 3.2817397361221596, + 2.597485654058433, + 2.1992784396410094, + 1.662580227087135, + 1.8476743345236084, + 3.115812494737077, + 2.058150606944274, + 2.08325008034921, + 2.3469857869408033, + 1.8277848094722016, + 2.4422042700327533, + 1.7844618810384465, + 1.3611333024799808, + 1.7844618810384465, + 1.8476743345236084, + 2.340817939335098, + 2.6579524500706064, + 2.366474390967386, + 2.058150606944274, + 2.4422042700327533, + 0.9881777803187259, + 1.2640937599837798, + 1.3611333024799808, + 3.2090900715462665, + 3.314160295599997, + 1.8476743345236084, + 1.6394306267208247, + 2.7798341040219183, + 1.8476743345236084, + 2.1913009430783856, + 1.4781246282467542, + 2.165144503625583, + 2.2432439590948734, + 1.5110475329649113, + 2.058150606944274, + 1.77949552319194, + 3.0197310759414897, + 1.3874319744869243, + 2.4018155518380553, + 3.384015286101267, + 1.4907079969402144, + 2.058150606944274, + 2.876493519522545, + 1.9180454979641435, + 2.058150606944274, + 1.5991954027963784, + 1.8476743345236084, + 1.8476743345236084, + 2.2619882652122514, + 0.48867189860057114, + 0.5885757197582273, + 0.972217023964357, + 0.9949648169383324, + 0.4701448449161419, + 0.36624663163271276, + 0.20414017473522428, + 0.781662083746345, + 0.7771725261406726, + 0.5166340697152094, + 1.1144758030042243, + 0.37098417581820187, + 0.9592419338350118, + 0.8223544514305821, + 0.5231821048903245, + 0.19150015467079623, + 0.24951307772433018, + 0.6426491025860934, + 0.5329604145567479, + 0.41907903371560534, + 0.6164337876699324, + 1.3533203278266535, + 1.091948011291402, + 0.86391906907832, + 0.38199844593758947, + 1.0220537846060882, + 1.1907856383429851, + 0.7127410739889937, + 0.6859896769277757, + 0.3257628491140039, + 0.5190657488609061, + 0.24575899061261025, + 0.5780558376434504, + 0.5357041523271149, + 1.0253853281681793, + 0.7397530531044751, + 0.2540098233878462, + 0.6343951762807647, + 0.5604820516059013, + 0.6619861574075658, + 0.7529879841805522, + 0.5442290231579501, + 0.5039966759005838, + 0.2926549840389906, + 0.5811791180133811, + 0.8627143480806179, + 0.9643829061255931, + 0.9532836336927533, + 0.336427736770751, + 0.6135150919978387, + 1.1099575948022267, + 0.5458653775614, + 0.45450771001444956, + 0.35299875308011, + 0.5448170037677809, + 0.4004081546387497, + 0.6844210103987743, + 0.4904200108988522, + 0.43069313862090874, + 0.4349037053992691, + 0.3685670663394851, + 0.45420862063830086, + 1.140068302868801, + 0.4932235963940902, + 0.6075977282258147, + 1.7911356143611905, + 0.5292034742974792, + 0.490495197163209, + 0.6655194286686283, + 0.46700165680380745, + 0.5105803032939962, + 0.7435446375884014, + 1.1194776032961655, + 1.0656270109419181, + 1.6023496187364752, + 0.7784709372807672, + 0.46509736061079, + 0.4724682144536736, + 0.2817964268768788, + 1.3707233209326766, + 0.5499674903499732, + 0.36779736489826875, + 0.601741561737235, + 0.5753101972972932, + 0.5477422136879888, + 0.505549165943473, + 1.0911563229046193, + 0.42606620556198854, + 0.9655848893913684, + 0.7027653336065167, + 0.38450965882104055, + 0.5253571652801146, + 0.5661759726522114, + 0.8814841214327778, + 0.7198172674113423, + 0.8063828083649196, + 1.230709185773072, + 0.7477947695570341, + 0.7210484959207643, + 0.21667682374747138, + 1.29292729604463, + 0.7757706071255103, + 0.4226364228670692, + 0.17364266210375778, + 0.525625714672557, + 0.7759066817616176, + 0.43376593434329963, + 0.258399552448972, + 0.8934637193622803, + 0.8107592480266372, + 0.6436178803377101, + 0.5645242415719579, + 0.44918200844745537, + 0.4796031075946906, + 0.9561590656127918, + 0.7769882989227348, + 0.9581247054261957, + 0.6500793353942644, + 0.8095714847679307, + 0.9496100635953806, + 0.7123693331383147, + 1.0043496815862443, + 0.5486262893932147, + 0.8681700399230778, + 1.0876553637666782, + 0.23080868290077164, + 0.28997309764466306, + 1.184120601422929, + 0.7910687917815501, + 0.8923352822551354, + 0.44105258767875194, + 0.8515233427962798, + 0.9860526348430533, + 0.7498452014569952, + 0.6799666571462601, + 0.7944496010541529, + 0.9412152505027649, + 1.0234170196554702, + 0.416923663479027, + 0.4773945143228649, + 0.44761093110093564, + 1.296098153265798, + 0.6865140243710741, + 0.23873983631974507, + 0.634583299342697, + 1.1635846428386554, + 0.7810353189393286, + 1.1743082237503222, + 0.6527977375273419, + 0.40512518388079344, + 0.7473272505441964, + 0.6626602335022577, + 0.5504477311683993, + 0.5455580666681463, + 0.483546101119161, + 0.5039242912753605, + 0.6846247117126532, + 0.8097399525997997, + 1.09057708646323, + 0.7781539983548891, + 0.5431346177137155, + 0.6677489150073648, + 1.2835807653028295, + 0.7298591041421733, + 1.288759318193982, + 0.5676598736302504, + 0.7696398500131101, + 0.7490238053284197, + 0.6966428481786365, + 0.27189238780995284, + 0.45637080377965195, + 0.5839058190575585, + 0.5744446663446303, + 0.4475101965720296, + 1.1740528130022951, + 0.37436587492062967, + 0.4800368438469145, + 0.8752224610816868, + 0.2259783148466264, + 0.607308878010788, + 0.36073445746478006, + 0.3997241996453574, + 0.3239143935812687, + 1.2080977568295863, + 0.9420032552025619, + 0.8455841278303668, + 0.5027261039809697, + 0.5387970203009899, + 0.3707590967238009, + 0.5362998409204238, + 0.6480884241402327, + 0.2707282854569056, + 0.7351904882028099, + 1.4143961289746265, + 0.1697716872853371, + 0.3541134067885844, + 1.112757584513524, + 0.7838404798953785, + 0.6464445454395906, + 0.4651269167329659, + 0.6768301680052173, + 0.4479137937212957, + 0.7102841663800217, + 0.4494337358580542, + 0.6423485558575748, + 0.7163949094824484, + 0.7037933141882795, + 0.39212520407848483, + 0.5136332650597867, + 0.5590312184484211, + 0.7961333610477074, + 1.7338519883972485, + 0.7580580315270837, + 0.7642574081321878, + 0.6538509981526632, + 0.474951699966667, + 1.2890934019873026, + 0.5101416564771201, + 0.40972023506499466, + 0.6424706332025651, + 0.520530129116261, + 0.2634178516113682, + 0.48863515439496635, + 0.6362725433689105, + 0.9734312809874381, + 0.7833238405164451, + 0.39234039066109083, + 0.5034811247238715, + 0.5410615363017501, + 0.3074124906211807, + 0.5603575243128536, + 0.5888269824411199, + 0.955977513871587, + 0.5788836920119912, + 0.4152706184286134, + 0.3765867230310422, + 0.763442308302275, + 0.5112947642310477, + 1.1932148511733915, + 0.3662043474094189, + 0.7630752601963136, + 0.42592645771666626, + 0.4817200234141469, + 0.981719084967044, + 0.3905518004021066, + 0.9706280662381613, + 0.4459832327889996, + 1.5182677004266425, + 0.43906112520379503, + 0.758285723910893, + 0.6628939785983023, + 0.88837461213616, + 0.4997741483656285, + 0.5821659949754612, + 0.8287987431310158, + 0.45504759899921243, + 0.5322489932372031, + 0.35360298849781874, + 1.1079700035416455, + 0.8493481009917538, + 1.2220771569217732, + 0.8911878976749977, + 0.7852141399351118, + 0.5836463943464842, + 0.31430825525830003, + 0.9087986812251339, + 0.5868271368246901, + 0.7319549143602787, + 0.7604259649096742, + 0.5639538374741524, + 0.9480086639173891, + 0.6521822804762267, + 1.2339875225257202, + 0.8038726420527612, + 0.396999095424708, + 0.47006672949004824, + 0.9458758707305569, + 0.45771347969624115, + 0.8226049102207165, + 0.7568903508660412, + 0.7940158469882357, + 0.4581856931695981, + 1.0130367948885926, + 1.948416190517461, + 0.30417847431384243, + 1.5773738236494537, + 0.7639617274463049, + 0.6652722459923383, + 0.5959379456287873, + 0.5977148674259367, + 1.1549505336149357, + 0.2649593755288052, + 0.3667526230595164, + 0.4336613403876164, + 0.8529518551368597, + 0.532109859246849, + 0.5286971656436941, + 0.8172869077368641, + 0.7526356350260688, + 0.670878388732628, + 0.7532117826219263, + 1.0555508928682231, + 0.43613875381964096, + 0.9794658336328633, + 0.31982451636183606, + 0.25329889199199473, + 0.5113847773832235, + 0.5966642573240685, + 1.0933294739593646, + 0.8640735809900746, + 0.2438587532394874, + 0.9057700047069175, + 0.3137402047331066, + 0.5465503755983087, + 0.6574887978564667, + 0.6598506703944362, + 0.3544888849912696, + 1.294221640078515, + 0.7831246028266841, + 0.484436738641558, + 0.7777221290883098, + 1.6635993147211963, + 0.6382423750037071, + 0.8080537065723865, + 0.5326626702596394, + 0.5341331672309162, + 1.2294484913217985, + 0.7082800449998984, + 0.2525977773056911, + 0.4990394376602221, + 0.21114989849458193, + 0.6717284582919075, + 0.6336132187409541, + 0.7918583502282457, + 0.44525563724577777, + 0.49052231854329875, + 0.8124239179492876, + 0.4411096680631264, + 0.4823720786471906, + 0.9115730283091835, + 0.5002256553482506, + 0.6286844349739773, + 0.729667790766042, + 0.3189444096933285, + 0.6212978725546658, + 0.6813967862641004, + 0.43832821797585675, + 0.29922449703987963, + 0.7825127517584708, + 0.4434903523824692, + 0.6103431346791586, + 0.6374270128324204, + 0.380788013701971, + 0.7353547721845722, + 1.324874946471224, + 0.4012631751129542, + 0.3811033969585462, + 1.2617536510131535, + 0.833488053789351, + 0.21899696697726892, + 0.9177498172208889, + 1.6218415889994118, + 0.4920298962204609, + 0.55324855261673, + 0.5692231390289659, + 0.666061376289097, + 0.39502587934791245, + 1.1957511656924902, + 0.5769297446341787, + 0.3860902591255809, + 1.1932247681257264, + 0.5248109970323039, + 0.5730558970619457, + 0.6346485750644904, + 0.6655194286686283, + 0.6090718098909019, + 0.6270052333678036, + 1.1661458118404657, + 0.376488307223584, + 0.3420550962241309, + 0.31584805467483457, + 0.619350629516962, + 0.7570934313391142, + 0.7534822539963891, + 0.3873970167778444, + 0.8759125675320302, + 0.7031608681110568, + 0.5631201018969054, + 0.5535614395965028, + 0.6334779362876269, + 1.1069584782770914, + 0.5541032904986907, + 0.9738736348930225, + 0.40246395893941694, + 0.5630307858973188, + 1.2026009692105866, + 0.4296007257267774, + 1.1484496821696042, + 0.44876960907698693, + 1.079531416930429, + 2.4422042700327533, + 2.597485654058433, + 2.576282957936971, + 1.6706702458167149, + 2.058150606944274, + 2.058150606944274, + 2.2619882652122514, + 2.891988316701276, + 2.1584763686510424, + 1.8476743345236084, + 2.4422042700327533, + 1.213360324304979, + 2.058150606944274, + 2.597485654058433, + 2.015619478204368, + 2.698114651529055, + 2.0229060766665996, + 2.891988316701276, + 2.058150606944274, + 2.147538210676071, + 2.2619882652122514, + 1.1118761177627527, + 1.3298813244777814, + 2.2619882652122514, + 2.7044189967296095, + 2.7676757380202464, + 1.3611333024799808, + 1.6010211462063677, + 2.2619882652122514, + 2.058150606944274, + 1.328343782877219, + 1.987778688217865, + 2.3263210525000524, + 3.5850673040480663, + 2.058150606944274, + 2.1765005627905234, + 2.003705192224647, + 1.8476743345236084, + 1.8476743345236084, + 2.4422042700327533, + 3.288858152014848, + 3.2090900715462665, + 2.597485654058433, + 2.597485654058433, + 2.057898353760048, + 2.2619882652122514, + 1.8337942585116656, + 1.4826676654967779, + 2.3894156471488124, + 2.4422042700327533, + 2.058150606944274, + 2.058150606944274, + 2.597485654058433, + 1.5211271812256442, + 2.1096603421691764, + 2.2432439590948734, + 0.9274771023236548, + 1.8476743345236084, + 2.015619478204368, + 2.2619882652122514, + 1.4994178227199542, + 0.28502424794936665, + 0.27307304251091136, + 0.4086944482038333, + 0.7548953417265422, + 0.6284696555007536, + 0.5679953377324009, + 0.33683536683870874, + 0.43666797569985316, + 0.6207970809352626, + 0.33010918349472845, + 0.5797462713657593, + 1.1067413118655287, + 0.214433112404275, + 0.7579829305082684, + 0.23160967043084352, + 0.6990442714938407, + 0.5071829062826869, + 0.7293153311683911, + 0.6165577330159223, + 0.7413382894025572, + 0.5229756023703942, + 0.6372738751393924, + 0.20063425356324016, + 0.7363545918927197, + 0.18862397306462686, + 0.5771360534583795, + 0.4137126559822677, + 0.6237420516152794, + 0.30550262804307626, + 0.5752150362207914, + 0.4580493949259059, + 0.7520764462012008, + 0.9043051166602887, + 1.30438740222285, + 0.7141566737178106, + 0.8275919105265898, + 0.38860714605218805, + 0.705127940863953, + 1.0961631416035886, + 0.8987025576930323, + 0.6217985022389796, + 1.042485155286768, + 0.7351875597875128, + 0.295458928356688, + 1.4646510247544633, + 0.516635551132187, + 0.6005308354366456, + 1.3110220952890264, + 0.6113350711140656, + 2.123807830950086, + 0.43240711785841934, + 0.49115871517867726, + 0.4206394342764146, + 0.6155353871909078, + 0.48802693820330834, + 0.507939819688576, + 0.9284666929062105, + 0.49819546678854426, + 0.5427308606770213, + 1.095527467961761, + 0.6057494425082145, + 1.125655264806165, + 0.20768631995739795, + 0.36575244947511254, + 0.6202043687867542, + 0.6615131145985755, + 0.6825832910556089, + 0.15140209284096767, + 0.5508625248154149, + 0.31975749569515716, + 1.020759954725532, + 0.5337377192093848, + 0.5401283213315273, + 0.7437875156312354, + 1.0645935399250406, + 0.5068790493772461, + 0.3657087253589293, + 0.5818319267067703, + 0.322127383438569, + 0.9701940392925872, + 0.5766745772419998, + 0.8725016893236397, + 0.2950808783714772, + 0.3457070952590743, + 0.37476011369565704, + 1.0665195375484156, + 1.2385581360421785, + 0.7797666651454647, + 0.6649694834460308, + 1.4300638438337523, + 0.35632231112064305, + 1.3189176216340277, + 1.142032557050402, + 0.41490339234117696, + 0.8140340873736615, + 0.2455947902878469, + 0.400307634511897, + 0.23178436474109704, + 0.4627011390914908, + 0.9651965526435258, + 0.7114557803114891, + 0.18036021060623952, + 0.4524969059530115, + 0.46772322816901585, + 0.14502003787436374, + 0.3927539138458261, + 0.6195945983395783, + 0.15898089263282428, + 0.8002356675608518, + 1.1954589743514323, + 0.5368009196760213, + 0.6168724541793043, + 0.729476694439153, + 1.3829398348274309, + 0.39690753209940316, + 0.6139602401071659, + 0.5094964842205809, + 1.5253288949587989, + 0.9879155181640662, + 0.45256474528378376, + 0.32460228513747275, + 0.24854877892071786, + 0.9230402723135336, + 0.3351671823020964, + 0.9896814841560216, + 0.2734579057118104, + 0.32050752648466263, + 0.2917110585959341, + 0.2204311752541253, + 0.7958036881058903, + 0.7879086357668657, + 0.8507141516462567, + 0.7819727505151478, + 0.3802697027494472, + 0.5572426518344935, + 1.1308480155334468, + 0.720075016594828, + 0.5393161370211699, + 0.7858435743751981, + 0.8443749436578923, + 0.6234665920203531, + 0.4861697972281354, + 0.8817107141690388, + 1.2982847675107247, + 0.7207745199861851, + 0.5017869813342268, + 0.5774062762390088, + 0.33893221927768147, + 0.3857010768213252, + 0.5470280485196977, + 0.5318519599063352, + 0.3437355378171793, + 0.4207026199820926, + 0.7576362588227559, + 0.626392225468064, + 1.0083213972980771, + 0.7122319954263965, + 0.5529232567778244, + 0.7635205435955159, + 0.19824893598594537, + 0.25626613774232054, + 0.9605813612816698, + 0.5965959861950795, + 0.4236548806223749, + 0.23867769131792305, + 1.1481053908639653, + 0.19264260336055014, + 0.7655498514898923, + 0.923922747028022, + 0.32389536779212796, + 0.4751293538224475, + 0.23773367518766064, + 0.9256603622671682, + 0.33985558992726916, + 0.46567128452233253, + 0.5682046297407395, + 0.5295429467423673, + 0.730117606371324, + 0.22391288361574813, + 1.245363112411571, + 0.680141872767341, + 0.6055291207774419, + 0.518782550223678, + 0.39013006714930554, + 0.5865582457195075, + 0.33210001529271227, + 0.4456835163813887, + 0.5416393678702157, + 0.5480278476365156, + 0.819464872627498, + 0.20411901066352703, + 0.8206180878089415, + 0.7917516198724363, + 0.9966781656539502, + 0.8228315070748297, + 1.5868841614697966, + 0.7255893282861796, + 0.8274400532729151, + 0.41828215730139273, + 1.5211271812256442, + 2.058150606944274, + 2.2432439590948734, + 2.5939343032886533, + 1.6025274431324954, + 2.058150606944274, + 2.2432439590948734, + 3.145811115362664, + 2.891988316701276, + 2.1953224752198084, + 1.662580227087135, + 1.340978895250525, + 1.7844618810384465, + 1.8476743345236084, + 2.2619882652122514, + 2.507631060443087, + 2.2619882652122514, + 3.0197310759414897, + 2.2619882652122514, + 2.597485654058433, + 1.8476743345236084, + 3.0197310759414897, + 2.1158858357860773, + 2.2619882652122514, + 1.6863317636107102, + 2.058150606944274, + 1.8476743345236084, + 1.6954561861655968, + 1.244573016023921, + 1.8476743345236084, + 2.722299214112355, + 0.7266185336668192, + 2.058150606944274, + 1.662580227087135, + 1.8476743345236084, + 1.8476743345236084, + 1.662580227087135, + 2.058150606944274, + 2.7676757380202464, + 2.597485654058433, + 1.8476743345236084, + 1.3635744972229853, + 1.9180454979641435, + 1.987778688217865, + 1.5502422864997132, + 2.4422042700327533, + 2.2619882652122514, + 1.5557627979655884, + 1.43485278199626, + 1.8476743345236084, + 2.7377362560735974, + 2.2619882652122514, + 2.233807133215227, + 2.015619478204368, + 2.058150606944274, + 2.1808240605894347, + 1.8476743345236084, + 2.986632069270234, + 2.2619882652122514, + 1.3321606182983585, + 2.058150606944274, + 1.8189951082469618, + 2.7676757380202464, + 1.3611333024799808, + 2.08325008034921, + 1.8277848094722016, + 1.7862511328192499, + 1.8476743345236084, + 2.058150606944274, + 1.8476743345236084, + 3.115812494737077, + 2.597485654058433, + 3.469823829994782, + 1.8476743345236084, + 2.5596229582529304, + 2.2619882652122514, + 1.4959831486773143, + 1.3507224322004856, + 2.2265741827025565, + 2.058150606944274, + 2.7591388856737193, + 2.891988316701276, + 2.2619882652122514, + 1.8476743345236084, + 1.3611333024799808, + 2.6041526391479004, + 1.8476743345236084, + 1.1118761177627527, + 1.2474464097471953, + 2.597485654058433, + 1.662580227087135, + 1.6863317636107102, + 2.597485654058433, + 2.7676757380202464, + 1.337963371956792, + 2.5121903693258694, + 1.8971945539776351, + 2.010176450803009, + 3.115812494737077, + 2.296225486537535, + 1.8476743345236084, + 2.597485654058433, + 1.949666463423513, + 1.6863317636107102, + 2.891988316701276, + 2.2619882652122514, + 1.8476743345236084, + 2.7676757380202464, + 2.6343719762904607, + 1.9553015285410429, + 2.2619882652122514, + 2.058150606944274, + 1.9180454979641435, + 0.41671291510051217, + 1.6863317636107102, + 2.2810904181711433, + 1.7803626681808928, + 1.8476743345236084, + 3.2090900715462665, + 1.8476743345236084, + 2.058150606944274, + 1.8476743345236084, + 2.058150606944274, + 2.891988316701276, + 1.8277848094722016, + 2.597485654058433, + 0.3902952486405913, + 1.8476743345236084, + 2.058150606944274, + 2.058150606944274, + 1.3611333024799808, + 2.058150606944274, + 2.356505525463452, + 1.8476743345236084, + 2.597485654058433, + 1.5803745867869687, + 2.597485654058433, + 1.7036321574270352, + 2.8380026136553065, + 2.2619882652122514, + 1.662580227087135, + 1.5211271812256442, + 2.058150606944274, + 2.2619882652122514, + 2.1808240605894347, + 1.8354417509053258, + 3.2090900715462665, + 2.058150606944274, + 2.4422042700327533, + 2.356505525463452, + 0.8141209826863706, + 1.8476743345236084, + 0.5903893736111507, + 2.058150606944274, + 2.1808240605894347, + 2.4422042700327533, + 2.891988316701276, + 2.662443177201321, + 1.5211271812256442, + 2.18245626486345, + 2.4749788514400475, + 1.9577519973552207, + 1.3611333024799808, + 1.8277848094722016, + 2.2619882652122514, + 1.4346547318003282, + 2.8754863619073507, + 2.058150606944274, + 1.8476743345236084, + 1.8270354396903983, + 1.4344546314251019, + 2.4422042700327533, + 2.2619882652122514, + 2.2810904181711433, + 1.987778688217865, + 2.2511133880306673, + 2.688257125584185, + 2.5219375252675302, + 1.3611333024799808, + 2.4422042700327533, + 2.1158858357860773, + 2.058150606944274, + 2.597485654058433, + 2.2511133880306673, + 0.5957354878549947, + 2.7676757380202464, + 2.058150606944274, + 1.0388527097534093, + 2.058150606944274, + 1.1981364288317806, + 1.528509242884083, + 2.2619882652122514, + 2.4126397772311416, + 3.115812494737077, + 1.0218880615292742, + 1.7461380665603745, + 2.4297198737860715, + 1.9692717622352345, + 2.567020134223122, + 1.4826676654967779, + 2.058150606944274, + 2.058150606944274, + 2.597485654058433, + 1.662580227087135, + 3.115812494737077, + 2.058150606944274, + 2.4422042700327533, + 1.3611333024799808, + 3.115812494737077, + 2.3469857869408033, + 1.8476743345236084, + 2.058150606944274, + 2.4422042700327533, + 2.4422042700327533, + 1.2790741752757544, + 1.3041624585720801, + 1.8476743345236084, + 0.741044464260747, + 2.058150606944274, + 1.7058034655857854, + 2.597485654058433, + 1.066998154633156, + 1.8476743345236084, + 1.8582485745840973, + 1.8476743345236084, + 2.2619882652122514, + 1.8476743345236084, + 1.8811237091838187, + 1.987778688217865, + 3.1811749596806305, + 1.3111735303260867, + 1.8476743345236084, + 1.5475678049943515, + 0.5006662268803865, + 2.597485654058433, + 1.8476743345236084, + 2.4297198737860715, + 2.2672328608903474, + 2.891988316701276, + 2.7377362560735974, + 2.058150606944274, + 2.39446986842855, + 2.058150606944274, + 3.314160295599997, + 1.3611333024799808, + 2.597485654058433, + 2.597485654058433, + 3.115812494737077, + 1.3611333024799808, + 1.949666463423513, + 2.8380026136553065, + 1.8660595925061179, + 1.8476743345236084, + 3.0197310759414897, + 2.9355765938955307, + 2.891988316701276, + 0.9166604307929841, + 2.3626336793216423, + 2.058150606944274, + 2.2511133880306673, + 1.5211271812256442, + 1.8476743345236084, + 2.891988316701276, + 1.8476743345236084, + 2.4422042700327533, + 2.2619882652122514, + 2.058150606944274, + 2.1913009430783856, + 1.8476743345236084, + 2.4422042700327533, + 1.8277848094722016, + 0.609921522967696, + 1.7862511328192499, + 2.2619882652122514, + 1.8476743345236084, + 1.8476743345236084, + 2.4126397772311416, + 2.2619882652122514, + 1.8476743345236084, + 1.814077008343395, + 1.806438411552133, + 1.493227058789952, + 1.7849583554172694, + 1.8277848094722016, + 0.6350523087289974, + 2.058150606944274, + 2.891988316701276, + 1.8476743345236084, + 2.002718797933716, + 1.5211271812256442, + 2.058150606944274, + 2.058150606944274, + 2.4422042700327533, + 1.8476743345236084, + 1.8476743345236084, + 3.115812494737077, + 1.8476743345236084, + 1.6609724170732028, + 2.4422042700327533, + 2.597485654058433, + 1.3611333024799808, + 3.2090900715462665, + 2.058150606944274, + 3.5659509171218624, + 2.7044189967296095, + 2.597485654058433, + 2.5121903693258694, + 2.3261157344511374, + 1.8819243500942884, + 2.5897137525317344, + 2.058150606944274, + 2.058150606944274, + 1.8476743345236084, + 1.5211271812256442, + 1.3611333024799808, + 1.1164140449560336, + 2.2432439590948734, + 3.314160295599997, + 1.5246851359388396, + 2.8991581821328123, + 2.2619882652122514, + 1.662580227087135, + 2.4410842969168067, + 1.1245557646490507, + 2.348287040197626, + 1.8476743345236084, + 2.891988316701276, + 2.340817939335098, + 1.6863317636107102, + 2.4422042700327533, + 1.8593297092215508, + 1.8476743345236084, + 1.8476743345236084, + 2.2619882652122514, + 1.662580227087135, + 1.8476743345236084, + 2.597485654058433, + 2.891988316701276, + 1.8277848094722016, + 2.6068978967526006, + 2.5121903693258694, + 1.4035359816282003, + 2.169446689467489, + 1.8476743345236084, + 1.5274003351094558, + 2.2810904181711433, + 1.764455547273154, + 2.058150606944274, + 2.4410842969168067, + 1.6025274431324954, + 1.8476743345236084, + 1.4781246282467542, + 1.8476743345236084, + 1.4907079969402144, + 2.058150606944274, + 1.5211271812256442, + 2.597485654058433, + 2.4422042700327533, + 1.8476743345236084, + 2.6411410396066364, + 2.852698359451875, + 2.6313621556018494, + 1.7382647621746443, + 1.9806299258143218, + 2.7676757380202464, + 1.1404154792506311, + 3.0197310759414897, + 1.3576363243724865, + 2.2619882652122514, + 1.8476743345236084, + 2.482270985196589, + 1.3611675962191083, + 1.8608003554327013, + 1.9180454979641435, + 0.9871032176377843, + 1.037643916307703, + 2.597485654058433, + 2.4422042700327533, + 2.7676757380202464, + 1.7844618810384465, + 2.058150606944274, + 1.8476743345236084, + 2.2619882652122514, + 1.8476743345236084, + 2.6090039217253813, + 1.8277848094722016, + 1.662580227087135, + 1.6870498749506693, + 2.4879607303540943, + 1.1744010489819492, + 1.662580227087135, + 2.7676757380202464, + 2.7676757380202464, + 3.314160295599997, + 1.8476743345236084, + 2.058150606944274, + 2.2619882652122514, + 2.2619882652122514, + 3.01099170118784, + 2.3846970049563643, + 2.3902541715329426, + 1.8476743345236084, + 1.2161975268315675, + 3.582079689185183, + 2.9069350888465104, + 2.7676757380202464, + 1.463914074861662, + 2.2511133880306673, + 1.8476743345236084, + 2.1096603421691764, + 2.7311667983932253, + 2.2619882652122514, + 3.2090900715462665, + 1.949666463423513, + 1.5687643749231754, + 2.7676757380202464, + 2.4422042700327533, + 2.7311667983932253, + 1.8476743345236084, + 1.8476743345236084, + 1.7844618810384465, + 1.673787173203109, + 1.9180454979641435, + 2.745572455490983, + 2.6476390176760325, + 2.597485654058433, + 2.4422042700327533, + 1.8476743345236084, + 3.2090900715462665, + 2.2619882652122514, + 2.597485654058433, + 1.8476743345236084, + 2.2619882652122514, + 2.046404539294619, + 1.8476743345236084, + 2.058150606944274, + 2.9355765938955307, + 1.8476743345236084, + 2.2619882652122514, + 2.1158858357860773, + 2.058150606944274, + 2.282968455568092, + 2.058150606944274, + 2.3681136466714503, + 2.4422042700327533, + 2.356505525463452, + 3.582079689185183, + 2.891988316701276, + 2.2619882652122514, + 2.058150606944274, + 1.8476743345236084, + 3.2090900715462665, + 1.7320291053472046, + 1.8476743345236084, + 1.8476743345236084, + 2.597485654058433, + 2.7676757380202464, + 2.058150606944274, + 2.2619882652122514, + 1.164197202368665, + 3.115812494737077, + 2.9855209068938526, + 1.987778688217865, + 1.4907079969402144, + 2.1096603421691764, + 2.597485654058433, + 2.7676757380202464, + 2.5825373427782976, + 2.2619882652122514, + 2.597485654058433, + 1.5211271812256442, + 0.5366947304341205, + 0.7450164977798912, + 0.3105523942513979, + 0.5424990334339717, + 0.5074182191486282, + 0.5053974930814535, + 1.3279472933209537, + 0.8304493767406871, + 0.6143220079603868, + 0.7321246021319511, + 0.4213180139548348, + 0.9322211920033925, + 0.51460825456609, + 0.9807044825615534, + 0.3676601569353063, + 1.0257300646077805, + 0.7131905010574775, + 0.8027056789644259, + 1.1576469061459842, + 0.2692436636185779, + 0.9535342736175065, + 2.050559877726966, + 0.3849834400866069, + 0.8570723653220684, + 0.21583073466715508, + 0.8407212643558282, + 0.7801499892744868, + 1.7262731842942776, + 0.7175044212451833, + 0.42133158317228203, + 0.5747997786321797, + 0.49954798409412415, + 0.8527765067637991, + 0.6619902961383758, + 0.7907835619059082, + 0.5034522447351065, + 0.314267557275166, + 0.8555985456657346, + 0.5122105317013557, + 0.7212289109683091, + 0.28696634011732347, + 0.5817143663134253, + 0.3444938978087684, + 0.6966198122580072, + 0.5224532168187934, + 0.40648461492276666, + 0.8338166305282712, + 0.37353344645744313, + 1.2532831971725023, + 0.48542823079606345, + 0.349750895836674, + 1.07006220843009, + 0.8554949323372707, + 0.6005887802570288, + 0.4496047665026016, + 0.4365144422301165, + 0.423388449843077, + 0.9780178540903471, + 0.32302572273854685, + 0.38556673690274734, + 0.8107177575221539, + 0.5117736361185182, + 0.3343253781750183, + 0.6778262486937372, + 0.6213940935698442, + 0.6755953716512575, + 0.5339469148554018, + 0.44317472188860907, + 0.44834735717637064, + 1.2675667843006342, + 0.6245336483621804, + 0.891559877079444, + 0.7674220800251637, + 0.43224345551773813, + 1.1796745931937505, + 0.9434579144977243, + 1.0109999737289295, + 0.6472424460242984, + 0.4822487814098084, + 0.26272520486097095, + 2.058150606944274, + 2.356505525463452, + 3.314160295599997, + 3.0197310759414897, + 2.2619882652122514, + 2.891988316701276, + 2.2619882652122514, + 2.6343719762904607, + 1.8476743345236084, + 2.2619882652122514, + 2.058150606944274, + 1.8476743345236084, + 3.2090900715462665, + 2.058150606944274, + 2.5825373427782976, + 1.3611333024799808, + 1.8476743345236084, + 2.482270985196589, + 2.4422042700327533, + 1.987778688217865, + 2.5164994042091156, + 1.292994733975404, + 2.425605459316416, + 2.2619882652122514, + 1.3611333024799808, + 2.0853977922487412, + 1.9946748054904933, + 1.6863317636107102, + 1.8476743345236084, + 1.7844618810384465, + 2.4422042700327533, + 1.1118761177627527, + 2.3664072182788787, + 2.891988316701276, + 2.058150606944274, + 1.3507224322004856, + 3.1481561191964627, + 3.469823829994782, + 3.2090900715462665, + 2.5608129117539997, + 1.662580227087135, + 2.853048452344537, + 1.8476743345236084, + 1.8476743345236084, + 2.3846970049563643, + 1.655938032584853, + 1.5802938525322712, + 2.058150606944274, + 3.0197310759414897, + 1.8476743345236084, + 2.2619882652122514, + 2.8733442337499486, + 2.564557616381423, + 2.114698314808771, + 2.058150606944274, + 1.8476743345236084, + 2.5897137525317344, + 1.2850243246698159, + 1.8476743345236084, + 1.5211271812256442, + 1.3432841977684973, + 1.3611333024799808, + 1.987778688217865, + 3.469823829994782, + 1.382771117555332, + 2.2619882652122514, + 1.8476743345236084, + 2.2619882652122514, + 2.2432439590948734, + 2.482270985196589, + 2.597485654058433, + 1.8476743345236084, + 1.2083121397243164, + 2.7743612024475044, + 3.115812494737077, + 1.8476743345236084, + 1.3611333024799808, + 2.058150606944274, + 2.2962988487973686, + 2.727014012968785, + 1.8476743345236084, + 2.263893103641785, + 1.8476743345236084, + 3.2090900715462665, + 2.340817939335098, + 2.0600801498260215, + 2.058150606944274, + 2.1096603421691764, + 1.8476743345236084, + 3.2090900715462665, + 0.5705163505393274, + 1.010438946213007, + 1.2686421767972937, + 0.815955520017267, + 0.903070055919441, + 1.1294495890810983, + 1.0938431071054118, + 0.6255492392034085, + 1.252113073011196, + 0.26688858504552115, + 0.5040773116654917, + 0.3174912850474103, + 1.0066834785479233, + 0.8620574730898509, + 0.5356700288429612, + 0.6764492404497959, + 0.20335166748270178, + 0.5094498229744344, + 0.7037480856170835, + 0.5535798117736699, + 0.3367303448862127, + 0.6656767340948103, + 0.7291910149113016, + 0.8167524553079433, + 0.9948360504847054, + 0.8075232111651478, + 0.23269036408267071, + 0.501015920421927, + 1.296452963363361, + 2.193543185260392, + 1.3981745324452424, + 0.22329960231668483, + 0.6798812049968375, + 0.37249449618604946, + 0.5173031769233184, + 0.3562714310317461, + 0.621394539907415, + 0.5220157768880558, + 0.6450456013128798, + 0.16824177559543732, + 0.23619860676917703, + 0.5358108575980032, + 0.5770020157670394, + 0.6990823695029782, + 0.42047084846778415, + 1.2461391493287848, + 0.9227066207758694, + 0.551844878998166, + 1.2541971819286404, + 0.2826550892613801, + 0.4117330928592139, + 0.7055360330716185, + 0.3981543387796214, + 0.8791966089108945, + 1.2181862869572215, + 0.65712438930122, + 0.7487580208995993, + 0.7862740446116201, + 1.0529275904032613, + 0.6079505516543771, + 0.38040021468313856, + 0.6739304797426263, + 0.7954547716952948, + 0.3357317345855645, + 0.7199945695615854, + 0.33537204814153165, + 0.5350611064488482, + 0.5141854962909448, + 0.6184238909456115, + 0.6671931144178344, + 0.5848192602257041, + 0.5214609833396087, + 0.8012690569867879, + 0.4120138509177069, + 0.7813806852474715, + 0.975456010800786, + 0.5604211336390128, + 0.5643562288117585, + 0.34961981531745945, + 1.313202500878466, + 0.9233285093264411, + 0.3616545518140556, + 0.8178484390251266, + 0.7032671091163831, + 0.6563878289490646, + 1.0093536449299907, + 0.23754643955474528, + 1.0237896194117369, + 0.38170100068585006, + 0.8379729530784323, + 1.1392750511563599, + 1.0326443941403831, + 0.4700998425731948, + 0.5108420622572452, + 1.1991536229580766, + 1.9420087035365758, + 1.4502289070548822, + 2.2619882652122514, + 2.7676757380202464, + 2.2619882652122514, + 2.340817939335098, + 2.2619882652122514, + 2.891988316701276, + 3.2090900715462665, + 1.4414161955895717, + 2.597485654058433, + 1.8476743345236084, + 2.39446986842855, + 2.482270985196589, + 2.597485654058433, + 1.8476743345236084, + 2.597485654058433, + 1.6863317636107102, + 1.7862511328192499, + 1.8476743345236084, + 2.4422042700327533, + 2.058150606944274, + 3.0691025648100325, + 2.4422042700327533, + 2.567020134223122, + 2.2619882652122514, + 3.0197310759414897, + 2.1158858357860773, + 2.7676757380202464, + 2.049256026737006, + 1.7844618810384465, + 2.6041526391479004, + 1.8476743345236084, + 2.7676757380202464, + 2.597485654058433, + 2.058150606944274, + 2.6041526391479004, + 1.1579572783157168, + 2.058150606944274, + 1.3611333024799808, + 1.8476743345236084, + 1.40462837721844, + 2.4422042700327533, + 1.6863317636107102, + 1.6863317636107102, + 2.1913009430783856, + 2.058150606944274, + 2.2511133880306673, + 2.65150501922635, + 2.2586738461974853, + 2.2810904181711433, + 1.37739870835809, + 1.8476743345236084, + 3.5659509171218624, + 2.4422042700327533, + 2.4422042700327533, + 2.4422042700327533, + 2.1096603421691764, + 2.1747988595838663, + 2.4422042700327533, + 2.2619882652122514, + 1.1164072278737485, + 0.2767065781685628, + 0.4154743111322243, + 0.307538861398718, + 0.40715269288475314, + 0.31837167474377337, + 0.620262788991543, + 0.8463256638569019, + 0.34605503000484605, + 0.7264285130630521, + 0.32280769753616007, + 0.46314671684518166, + 0.5713944086238187, + 0.8650302980621258, + 0.8275585792045572, + 0.31663272152321065, + 0.5710694887286643, + 1.1664497388767012, + 0.7739007624778114, + 0.40032202359458124, + 0.5089329297948895, + 0.5246995668755929, + 0.8398538370490356, + 0.2761503320876533, + 0.6041186319008398, + 0.594998387176955, + 0.7031224255808746, + 0.5751416373814229, + 0.5763351601522156, + 0.6251683908735021, + 0.3355061292317406, + 0.5559702100249293, + 0.5453393399471913, + 0.7218587457853585, + 0.642876048572122, + 0.3421956947917042, + 0.8284563189159628, + 0.35487994210269574, + 0.38089497364468117, + 0.3083818513178971, + 0.9446972257403703, + 0.535013431441455, + 1.1207824033229499, + 0.4001331592112374, + 0.8383579513173696, + 0.4614681008760887, + 0.6086010851497574, + 1.2536988121124943, + 0.607187242666198, + 0.783392801770574, + 0.5104887766194313, + 0.8247085259551923, + 0.8306180224971957, + 0.7284230746748197, + 0.7561567941935678, + 0.6305245400031236, + 0.29243623869407065, + 1.0132353972379968, + 0.4492221262579804, + 1.1943559505997712, + 0.4203657090560544, + 1.0539058897052498, + 0.33383547654909285, + 0.359199369727048, + 0.36133766940022355, + 0.46774841633865366, + 0.6880112694226945, + 0.8478448760680034, + 0.5450038238173747, + 0.9295349115651758, + 0.4612637755132797, + 0.8259132723714846, + 0.7833070482781233, + 0.4660116046900818, + 0.5730093861539708, + 0.3898722476726695, + 0.3449867227306514, + 1.212106896241206, + 0.7968624846140747, + 0.7531135935662194, + 0.7060966535819123, + 1.1052802414659282, + 0.8272756658348903, + 1.1253077636866964, + 0.3316153224740793, + 0.5977414062047812, + 0.6647978984368572, + 0.6285723310166729, + 0.5690380516516313, + 0.6545314689450148, + 1.0338065590895282, + 2.891988316701276, + 1.6863317636107102, + 3.115812494737077, + 2.4422042700327533, + 1.8476743345236084, + 2.7676757380202464, + 2.597485654058433, + 3.2493434390245337, + 2.1096603421691764, + 2.7676757380202464, + 1.8476743345236084, + 1.7614273756095642, + 2.4422042700327533, + 2.4422042700327533, + 0.8172869077368641, + 2.7676757380202464, + 1.7924052622115019, + 1.021071229125867, + 2.597485654058433, + 2.624117049025382, + 1.6863317636107102, + 2.5219375252675302, + 2.058150606944274, + 2.2810904181711433, + 2.597485654058433, + 3.2389102343651643, + 2.2619882652122514, + 2.058150606944274, + 2.891988316701276, + 1.3611333024799808, + 2.058150606944274, + 2.2619882652122514, + 1.9180454979641435, + 2.058150606944274, + 1.987778688217865, + 2.058150606944274, + 2.5164994042091156, + 3.314160295599997, + 1.5368875756353728, + 3.314160295599997, + 2.058150606944274, + 2.8744079346066127, + 0.8172869077368641, + 2.7044189967296095, + 3.2090900715462665, + 2.4422042700327533, + 1.8073430482999675, + 2.058150606944274, + 1.8593297092215508, + 1.3611333024799808, + 1.8616705403627694, + 2.058150606944274, + 2.7676757380202464, + 2.058150606944274, + 1.8476743345236084, + 2.4422042700327533, + 1.987778688217865, + 2.7676757380202464, + 3.469823829994782, + 2.058150606944274, + 1.8476743345236084, + 3.314160295599997, + 1.8476743345236084, + 2.597485654058433, + 3.5659509171218624, + 2.058150606944274, + 2.026969075021646, + 2.7676757380202464, + 1.8476743345236084, + 1.4826676654967779, + 0.45228203228436403, + 0.4817041150246603, + 0.5744073515586589, + 0.5444912243352911, + 1.1345599202210122, + 0.5898217106249396, + 0.41494536552320416, + 0.41522361837794475, + 0.5900209056360752, + 0.5799752399250173, + 0.4089703003989029, + 0.34242123898400667, + 0.5846405255070626, + 0.5971862952824296, + 0.9437336641122361, + 0.7304394640150396, + 0.5423212562452429, + 1.6789343649201975, + 0.6017517033369009, + 0.6477696965821196, + 0.42298167329854536, + 0.42293073497436073, + 0.5691320557529955, + 0.3729599309252736, + 0.3696023067834578, + 0.5767803525126689, + 1.2817193642646, + 0.309231163015955, + 0.6247341065918066, + 0.762242432205473, + 1.129483784327725, + 0.7858113400626512, + 0.37580354488170076, + 1.6323747324747582, + 0.18777289224974814, + 0.7636263498470225, + 0.6922594926627643, + 0.7581118700312616, + 0.5061706391450819, + 0.5071907874703347, + 1.0046472268873106, + 0.9966781656539502, + 0.8819632448368744, + 0.31493072277966283, + 0.45716876313761157, + 0.9728968253709512, + 0.28086207062566493, + 0.6096802646824645, + 0.7486677553830192, + 0.5298262991845355, + 0.4007136686279279, + 0.7065888806483691, + 1.6146103113841752, + 0.5436673232475336, + 0.7198476093280404, + 1.0327972939420431, + 0.975165478017097, + 0.8443853299807336, + 0.9356372900242089, + 0.7900253528657722, + 0.5114539295584843, + 0.33714993519819636, + 0.6483820411812032, + 0.8826918179472676, + 1.18324770719539, + 0.5007303260605548, + 0.4319547961739868, + 0.5492488000315455, + 0.365064334159927, + 1.0838173214011189, + 0.7506173671137856, + 0.11034006772184898, + 1.0644680795494363, + 0.6296361477946506, + 0.8900015964566002, + 0.6457962438381988, + 0.5812452957971297, + 0.6888373196354897, + 2.155480779260606, + 0.3818237292177193, + 0.715974108228322, + 0.6470603124169304, + 1.0647905542315752, + 1.0665503343362122, + 0.5222336018509777, + 0.6316731299282095, + 0.694144084594434, + 0.9384191697533764, + 0.3703858052465139, + 0.37375955808785377, + 0.49476856836475536, + 0.40723245749387865, + 0.32082202842479957, + 0.7218588309233269, + 0.6698025125042468, + 0.8192461335551835, + 1.2106900044554192, + 0.3698750263137886, + 0.8038979088767209, + 1.1753989651925336, + 0.45870906398732286, + 0.8878973483458329, + 0.5419735543413502, + 0.7266147237307989, + 1.064479040855963, + 0.40098321233991113, + 0.7438543766807697, + 1.1651737774709754, + 0.24868359374998708, + 0.33716323479882804, + 0.8143602524783755, + 0.3300842438557497, + 0.3552626251363457, + 0.7767119184606115, + 0.7264060792554518, + 1.3740731273737685, + 1.4265967048355281, + 0.3608713351233931, + 0.5056597519527822, + 0.5991845226275956, + 0.5918782943134075, + 0.9975256091885669, + 0.5596222350083323, + 0.7129916469968688, + 0.7925859261776346, + 0.43072286737023524, + 0.597472062086864, + 0.8576755338724079, + 0.5098080450947784, + 0.4654315628156862, + 0.38110404154158356, + 1.1058001625799077, + 0.6488500562827686, + 0.34331507248690074, + 0.318152345681603, + 0.6846157874003738, + 0.4605113686178516, + 0.6246350052852909, + 2.4422042700327533, + 0.38793725519913824, + 0.5607910619956755, + 0.424642252429276, + 0.794108479929698, + 1.1188696233409028, + 0.3658883618848335, + 0.2764440123990233, + 0.8772455897219864, + 0.6954788354366838, + 0.46206016653775595, + 0.45860507280107043, + 0.9735266158695103, + 0.8406219650161184, + 0.6978403799176847, + 0.8365209779946229, + 0.7720371979260559, + 0.5318905719398666, + 0.3784143869174777, + 0.4812186935066395, + 1.2356681934332814, + 0.5909455243151145, + 1.3611333024799808, + 0.4403802962800874, + 0.5105179055105027, + 0.7981460991062375, + 0.3207386764774283, + 0.4263077838803235, + 2.1551775987841326, + 0.3754269741413161, + 0.6077122171836056, + 0.5107949298482021, + 0.3961373201193345, + 0.19844176412153347, + 0.27290217871936323, + 0.5782775538982347, + 0.8805381600283293, + 0.39300196929248865, + 0.30530290021606854, + 1.2897483794643723, + 0.43471032256413145, + 0.3914361585705422, + 0.7078376775120302, + 0.5578415180444094, + 0.5431906186901552, + 0.838886807796619, + 0.3293182877956139, + 0.6350094175753085, + 0.5650072038057999, + 0.40441206969697907, + 1.0575502964381172, + 0.7426820149815705, + 1.0393435269783535, + 0.38365756067983386, + 0.7533873095305004, + 0.5481565973960354, + 0.29349148740407066, + 0.6605018525427864, + 0.39552996794909395, + 1.0064472870880876, + 0.2538235483180034, + 0.1697638864810398, + 1.0201128585273955, + 0.6008860538435072, + 0.7402437738213345, + 0.6204474512515545, + 0.7184606617020733, + 0.4413026110017697, + 1.8289847108575192, + 0.6728747798191843, + 1.189144061043011, + 1.0992754580644615, + 0.3251325477236166, + 0.38660501476963816, + 0.512771444039489, + 0.4098264268027608, + 0.17130343802612621, + 0.8084402689114074, + 0.5648555847977315, + 0.6857614108888184, + 0.329381813462766, + 0.6523686028241313, + 0.37323940952524304, + 1.9918170130654766, + 0.7771250668370396, + 3.1481561191964627, + 2.4422042700327533, + 2.506244302749521, + 0.9309933443453626, + 1.0481914570006097, + 3.115812494737077, + 2.597485654058433, + 0.7770948525602446, + 1.662580227087135, + 2.3846970049563643, + 2.4422042700327533, + 3.4704021231441455, + 2.7676757380202464, + 1.834936227350092, + 1.949666463423513, + 2.4018155518380553, + 1.8277848094722016, + 1.3611333024799808, + 1.949666463423513, + 1.9097144340054233, + 2.853048452344537, + 2.4422042700327533, + 3.314160295599997, + 2.5164994042091156, + 2.010176450803009, + 2.2619882652122514, + 2.891988316701276, + 2.2619882652122514, + 2.4422042700327533, + 1.9038185430588073, + 0.7731346229164052, + 1.8511830845837949, + 1.8476743345236084, + 1.383162604052505, + 2.2432439590948734, + 2.241502865043686, + 1.9469432694812379, + 1.8476743345236084, + 2.058150606944274, + 1.662580227087135, + 1.949666463423513, + 1.7783436215809805, + 2.4422042700327533, + 1.9180454979641435, + 2.2619882652122514, + 1.8476743345236084, + 1.5211271812256442, + 2.026969075021646, + 2.058150606944274, + 1.8476743345236084, + 2.853048452344537, + 3.384015286101267, + 2.7311667983932253, + 2.058150606944274, + 1.8476743345236084, + 1.9010559604007211, + 2.1158858357860773, + 2.058150606944274, + 2.058150606944274, + 3.1481561191964627, + 2.4297198737860715, + 2.058150606944274, + 2.08325008034921, + 1.9936948317948047, + 2.2432439590948734, + 2.1096603421691764, + 2.5572779544191317, + 2.1158858357860773, + 1.8476743345236084, + 1.8476743345236084, + 1.5837738524973792, + 1.7844618810384465, + 2.2619882652122514, + 1.4907079969402144, + 2.597485654058433, + 1.8476743345236084, + 2.7676757380202464, + 2.4422042700327533, + 2.2619882652122514, + 1.8476743345236084, + 2.058150606944274, + 1.3267042989098945, + 1.8476743345236084, + 1.8476743345236084, + 2.6041526391479004, + 2.1941478429787757, + 2.8744079346066127, + 1.987778688217865, + 1.6280305030814266, + 2.4410842969168067, + 2.4297198737860715, + 2.2619882652122514, + 1.8476743345236084, + 1.3209089561894722, + 2.482270985196589, + 3.6504081550418146, + 1.8476743345236084, + 1.662580227087135, + 2.199422994715876, + 1.8476743345236084, + 1.8476743345236084, + 3.314160295599997, + 1.390835498459361, + 1.8734543689621141, + 1.7665042305534557, + 2.4520564195146948, + 1.8476743345236084, + 3.2090900715462665, + 1.5211271812256442, + 3.0197310759414897, + 2.567020134223122, + 3.0577005548489264, + 2.1206154905540506, + 3.115812494737077, + 1.8476743345236084, + 2.597485654058433, + 1.3874319744869243, + 2.058150606944274, + 2.058150606944274, + 1.8476743345236084, + 3.2090900715462665, + 2.597485654058433, + 2.891988316701276, + 2.2619882652122514, + 2.356505525463452, + 2.597485654058433, + 1.7382647621746443, + 3.0197310759414897, + 1.662580227087135, + 2.2619882652122514, + 1.8476743345236084, + 2.8536018615812995, + 1.7715390054014857, + 1.0129647233766843, + 2.3469857869408033, + 2.1808240605894347, + 1.7867703752473507, + 1.8476743345236084, + 2.7311667983932253, + 2.058150606944274, + 2.058150606944274, + 1.8476743345236084, + 2.0317836289157807, + 2.597485654058433, + 1.6863317636107102, + 1.8476743345236084, + 2.2619882652122514, + 2.891988316701276, + 1.949666463423513, + 2.2619882652122514, + 3.266942902631966, + 1.8476743345236084, + 2.4422042700327533, + 2.510068442335756, + 2.1730015930197664, + 2.2619882652122514, + 2.058150606944274, + 2.891988316701276, + 1.8476743345236084, + 2.2619882652122514, + 1.3611333024799808, + 1.517887452520366, + 2.469167393905394, + 2.891988316701276, + 2.1913009430783856, + 2.058150606944274, + 1.4112463198271246, + 1.9309054181401635, + 2.1913009430783856, + 0.9920163401270353, + 2.482270985196589, + 1.8476743345236084, + 2.2619882652122514, + 1.9180454979641435, + 2.1158858357860773, + 3.115812494737077, + 1.8476743345236084, + 2.1913009430783856, + 2.130245097474936, + 2.891988316701276, + 3.115812494737077, + 2.7676757380202464, + 1.8476743345236084, + 2.4422042700327533, + 2.597485654058433, + 1.5211271812256442, + 0.5788873126701026, + 0.5293819522211993, + 0.3085927720334677, + 0.6979536729127278, + 0.851848203243533, + 0.3534833209948004, + 0.2361239304511982, + 1.2135606456484709, + 0.34146533249699185, + 0.6939351666383187, + 0.8464491772934978, + 0.8429688411661368, + 0.2751702415908704, + 0.4368711319112442, + 0.4422077631746618, + 1.0287338778695416, + 1.0701388737874613, + 0.20382585230488476, + 0.5983583535266092, + 0.5629841640442003, + 0.5602095613269036, + 0.7435680253489163, + 0.5076572745674176, + 2.853048452344537, + 0.9980976868589654, + 3.469823829994782, + 1.3580298506541122, + 2.1808240605894347, + 1.8036000149407108, + 1.8476743345236084, + 3.115812494737077, + 1.8476743345236084, + 3.384015286101267, + 1.9465763845013913, + 2.2619882652122514, + 2.7311667983932253, + 3.3891245095965568, + 3.084206049510459, + 1.8476743345236084, + 2.4422042700327533, + 2.813637293933024, + 1.987778688217865, + 1.987778688217865, + 2.7311667983932253, + 2.285732307527181, + 1.5211271812256442, + 2.058150606944274, + 2.4422042700327533, + 2.1913009430783856, + 1.8476743345236084, + 0.44126543717550204, + 0.7005079521164748, + 0.4162320312861204, + 1.0458606115972389, + 0.31377322714865064, + 1.6217313748964108, + 0.2805536852944884, + 0.4122216323992759, + 0.5638497771097096, + 0.2904661414370308, + 0.21943209016532508, + 0.38565305883444145, + 0.38319733228225605, + 0.5745959256835144, + 0.5669405441151422, + 0.3994183471964711, + 0.8250950899692675, + 0.598542580673292, + 0.30500219591332767, + 0.6567386557361545, + 1.0030279786225618, + 0.5685458853944778, + 0.8198389652289827, + 0.43287985839632365, + 0.5228342219654507, + 1.8224430948119734, + 0.709035695811193, + 0.8788512482931091, + 0.8353136032286836, + 1.2514044652023457, + 0.9395465233673654, + 0.9788869976649173, + 1.285390812930585, + 0.9225818969898321, + 0.7343139470545508, + 1.2335755229626577, + 0.44190660641679336, + 1.4889890054292936, + 0.5787260947183679, + 0.743780404300838, + 0.5114390186526887, + 0.7331017785040642, + 1.6557832273349793, + 1.2729618816374664, + 0.8707848032621808, + 0.872439979520451, + 0.6074517256692249, + 0.9707397738249653, + 0.41585729822927575, + 0.8317098461987092, + 1.1317996370261516, + 0.4558014852464366, + 0.49373105660473515, + 0.6708913219510331, + 1.0072635476207834, + 0.6525121244786987, + 1.1537559343492203, + 2.1158858357860773, + 2.228916087544387, + 2.1096603421691764, + 2.168054935057076, + 2.058150606944274, + 2.1747988595838663, + 2.2619882652122514, + 2.597485654058433, + 2.597485654058433, + 2.058150606944274, + 2.2619882652122514, + 2.2619882652122514, + 1.8476743345236084, + 1.9472049664510696, + 1.5211271812256442, + 1.662580227087135, + 1.7844618810384465, + 1.6863317636107102, + 1.8476743345236084, + 2.4422042700327533, + 2.5825373427782976, + 1.1882663386409362, + 2.1808240605894347, + 1.8476743345236084, + 1.8476743345236084, + 1.6038996396013907, + 2.2619882652122514, + 3.0197310759414897, + 1.6631618330875217, + 2.891988316701276, + 1.8476743345236084, + 2.597485654058433, + 1.88952715527254, + 2.058150606944274, + 1.470582209836203, + 1.8476743345236084, + 2.7676757380202464, + 3.469823829994782, + 2.1808240605894347, + 1.3874319744869243, + 2.347390338120625, + 1.8476743345236084, + 1.6865786339164157, + 1.0638348510133466, + 2.058150606944274, + 2.2619882652122514, + 2.2619882652122514, + 2.058150606944274, + 1.987778688217865, + 2.7676757380202464, + 1.8354417509053258, + 2.4422042700327533, + 0.46694173392205046, + 0.7076957492408192, + 0.4177337318912731, + 0.5506762270295269, + 0.3493972113493348, + 0.3668496273326096, + 0.27664776890248666, + 1.0557086602880161, + 0.6250998161134217, + 0.6039296862762344, + 0.4925585113931921, + 0.7097699713350837, + 0.9201474517953732, + 0.4635028749934065, + 0.5316188684488702, + 0.4167770844317668, + 0.20414017473522428, + 0.7811380372932166, + 0.8814417427674207, + 0.39611673616708065, + 1.0441418959579403, + 0.824059193704739, + 0.6732671916189742, + 0.5779915772754096, + 0.46177557328726754, + 0.6742312593954058, + 0.5679470702315573, + 0.5762952292719999, + 0.401384295810745, + 0.8811172806996191, + 0.7867461370693083, + 0.7362308670975313, + 0.8229864009966671, + 0.3052769307595473, + 0.7424221664289385, + 0.5921011950236812, + 1.2254616536554923, + 1.0355460143695836, + 0.24921013470392733, + 0.6587309401234107, + 0.49492399356170036, + 1.435566754851745, + 0.4270711617864891, + 0.5366024147697835, + 0.5678118083065, + 0.2709328112081876, + 0.4609698046687652, + 0.6866081759314688, + 0.16829832128084457, + 1.0607698119553508, + 1.1048391933192685, + 1.5393153482599145, + 0.7014813277040335, + 0.9355728127278571, + 0.6576332972210163, + 0.29454471212519573, + 0.39654153054958446, + 1.3230042015486352, + 0.5190037659525187, + 0.3344057586390622, + 0.5209469439598742, + 0.7030105855910523, + 0.7259100081978158, + 0.8748997545118902, + 0.4767645210390735, + 1.0692045068216045, + 0.8910630697528621, + 1.051198074071137, + 0.710480199211459, + 1.2511764908972536, + 1.4814312329062087, + 0.5005061758628306, + 1.4383385129621955, + 0.38321283210275625, + 3.084206049510459, + 2.2619882652122514, + 1.7844618810384465, + 1.8476743345236084, + 1.806438411552133, + 2.4422042700327533, + 2.2619882652122514, + 2.1158858357860773, + 2.4410842969168067, + 1.8476743345236084, + 2.256718251861917, + 1.0220801195120541, + 2.340817939335098, + 2.2619882652122514, + 1.9946748054904933, + 2.382913353012737, + 1.8476743345236084, + 1.8153159638013143, + 1.8476743345236084, + 2.724827540637997, + 1.3368245804052605, + 1.7737963495427844, + 2.1096603421691764, + 3.0197310759414897, + 1.9185919862546044, + 3.115812494737077, + 2.2619882652122514, + 2.922393038542517, + 2.1096603421691764, + 2.058150606944274, + 2.2619882652122514, + 2.2619882652122514, + 2.597485654058433, + 1.5211271812256442, + 2.5164994042091156, + 0.6953251053101797, + 1.8476743345236084, + 0.7135130338789275, + 2.3446105666328916, + 2.2619882652122514, + 2.7676757380202464, + 1.3611333024799808, + 2.2619882652122514, + 2.3816121687400496, + 2.4422042700327533, + 2.4146806864141896, + 2.4422042700327533, + 3.2090900715462665, + 1.7844618810384465, + 1.8476743345236084, + 2.3846970049563643, + 1.3611333024799808, + 3.166676545050257, + 2.2619882652122514, + 2.4422042700327533, + 2.0016039390719147, + 1.8277848094722016, + 1.9903298577266257, + 2.2619882652122514, + 1.0753357012288185, + 2.936107998516592, + 1.8476743345236084, + 2.2619882652122514, + 2.5164994042091156, + 1.8476743345236084, + 1.8476743345236084, + 2.058150606944274, + 2.340817939335098, + 1.781949048356978, + 1.8476743345236084, + 1.6663913551835323, + 1.987778688217865, + 1.71415818836443, + 1.4139177957255984, + 2.6721842480715328, + 1.0415347878441068, + 2.070890982879892, + 2.058150606944274, + 1.8476743345236084, + 1.9420087035365758, + 2.058150606944274, + 3.2090900715462665, + 2.482270985196589, + 2.2619882652122514, + 0.6296453932469599, + 1.3611333024799808, + 2.0600801498260215, + 3.0197310759414897, + 2.4018155518380553, + 2.058150606944274, + 2.058150606944274, + 1.8277848094722016, + 2.5971945774117877, + 2.5065786589076757, + 2.0875115325844797, + 2.2619882652122514, + 2.015619478204368, + 1.8476743345236084, + 2.010176450803009, + 2.2619882652122514, + 1.0944738351310828, + 2.8698168077828665, + 2.058150606944274, + 2.2619882652122514, + 2.891988316701276, + 2.813637293933024, + 1.8476743345236084, + 2.2619882652122514, + 1.8476743345236084, + 2.1096603421691764, + 3.3643091047615905, + 3.2090900715462665, + 2.2619882652122514, + 2.058150606944274, + 2.4422042700327533, + 2.891988316701276, + 2.1907507605156096, + 2.4422042700327533, + 1.6025274431324954, + 2.0114989976892135, + 0.3988957447621903, + 0.6142170393649988, + 0.7531465743123509, + 0.4219826974427586, + 0.34895753615232156, + 0.28383962737974866, + 0.373450485480312, + 1.875882659211045, + 0.7802757162181435, + 0.6272142791847289, + 0.7279211738764108, + 1.412552018575346, + 1.3611333024799808, + 3.2090900715462665, + 1.8476743345236084, + 3.0197310759414897, + 2.2619882652122514, + 1.8476743345236084, + 1.8476743345236084, + 2.597485654058433, + 2.5897137525317344, + 2.891988316701276, + 1.8277848094722016, + 2.6284070702929307, + 2.256185782538493, + 0.7310968394570125, + 2.08325008034921, + 1.8476743345236084, + 2.058150606944274, + 2.891988316701276, + 0.6910247803134066, + 0.6532289073901218, + 0.6994259948157278, + 0.4296973339019554, + 0.589115089190622, + 0.34989687637693556, + 0.6294047783493542, + 0.8347333348142023, + 0.9428947397845716, + 0.9204997930833867, + 0.6980117321094493, + 0.6013310410950824, + 0.4787778588947675, + 0.22297554076945314, + 2.36329651777183, + 1.7305126663987844, + 1.35052673800719, + 2.4422042700327533, + 1.380528297989975, + 2.4422042700327533, + 1.8476743345236084, + 2.891988316701276, + 1.6876402307319913, + 1.949666463423513, + 1.6863317636107102, + 2.058150606944274, + 1.88952715527254, + 2.6261040803852387, + 2.727014012968785, + 1.429236426793052, + 3.5850673040480663, + 1.390835498459361, + 1.6863317636107102, + 2.5572779544191317, + 2.2619882652122514, + 2.2619882652122514, + 1.8476743345236084, + 2.5065786589076757, + 2.057566545169104, + 1.6863317636107102, + 2.058150606944274, + 2.058150606944274, + 1.8476743345236084, + 0.8827885920083819, + 1.0984703147412862, + 0.5378502346587578, + 0.5990753283824561, + 0.7275553382504976, + 0.18353113297325302, + 0.7253643067386626, + 0.7314624063611253, + 0.5053684297473658, + 0.8690297001405991, + 0.43196421566470267, + 2.5121903693258694, + 2.4422042700327533, + 1.8476743345236084, + 2.2342609092376513, + 1.781949048356978, + 1.8476743345236084, + 2.4206363215557696, + 0.49684882136391484, + 0.3055484894303561, + 0.6605699684196749, + 0.552232975509736, + 0.6241355851139766, + 0.6562861611509052, + 0.5593561749336022, + 0.48336251277738085, + 1.1262380471361155, + 0.4331178199105171, + 0.8090270470269423, + 0.1463185187509018, + 0.76620678153903, + 0.5563170216935946, + 2.5164994042091156, + 2.1808240605894347, + 1.7522531491901994, + 2.2619882652122514, + 1.8476743345236084, + 2.2511133880306673, + 0.6326171103359157, + 2.1206154905540506, + 1.8476743345236084, + 2.2619882652122514, + 2.2619882652122514, + 1.8476743345236084, + 1.8476743345236084, + 3.2090900715462665, + 2.4422042700327533, + 1.8476743345236084, + 1.987778688217865, + 1.8476743345236084, + 1.6863317636107102, + 1.9180454979641435, + 1.7844618810384465, + 2.2619882652122514, + 1.8476743345236084, + 2.2544481879705343, + 1.8476743345236084, + 1.0525584368614782, + 1.112124195950634, + 0.5220810873893149, + 1.2591802215176813, + 1.2047851198992316, + 0.8674985089971801, + 0.5234286878168487, + 0.8062446746090666, + 0.5924790373583277, + 0.3574204135914888, + 0.5034194121649087, + 0.38814351447195033, + 0.6519150702251526, + 1.056300823116361, + 0.7225199439417761, + 0.12889497712183776, + 0.8311080491874028, + 0.570817850589461, + 1.1191045232970576, + 0.48200484722177567, + 0.8915659388202553, + 0.470668050406294, + 0.6532945144007828, + 0.6463285229343028, + 0.7562893897738583, + 0.6257221970984608, + 0.8122343497977413, + 0.8151899539183193, + 0.5422856256193311, + 0.8260775564605949, + 0.5827862488769454, + 0.6094539111513589, + 0.7811433331093229, + 0.94442163506765, + 0.33543221758916275, + 0.7137515115164451, + 0.5086359902750331, + 0.6037506691279897, + 1.0598614996053555, + 0.35980345816782483, + 0.43488990751683054, + 0.4430587644130865, + 1.6587382529120749, + 0.5362888176955307, + 0.7825458547785955, + 0.46137696806770245, + 0.7345750112577911, + 0.6844504205665436, + 0.7051328436751297, + 0.9893261211679325, + 1.6038996396013907, + 2.0229060766665996, + 2.2619882652122514, + 2.082465509310558, + 2.2619882652122514, + 3.0197310759414897, + 1.347097373512335, + 1.347097373512335, + 2.058150606944274, + 2.597485654058433, + 2.2619882652122514, + 3.0940222695585287, + 1.4059447709165789, + 1.8476743345236084, + 2.2753731348740027, + 0.45312920224693165, + 0.5496551960960343, + 1.1221243403584635, + 1.184221972517551, + 0.4819448586057004, + 0.7966148759300465, + 0.26201356553930544, + 0.28192474505512966, + 0.6109616356993027, + 0.8862136974876098, + 1.423042983250979, + 2.5572779544191317, + 2.058150606944274, + 2.058150606944274, + 2.986632069270234, + 2.2619882652122514, + 2.434804469403139, + 1.8476743345236084, + 1.470582209836203, + 2.441704608213206, + 1.8476743345236084, + 2.4422042700327533, + 1.662580227087135, + 2.058150606944274, + 2.036347049359129, + 1.8476743345236084, + 2.5121903693258694, + 2.891988316701276, + 2.597485654058433, + 1.8476743345236084, + 3.469823829994782, + 1.6863317636107102, + 2.0234528282825077, + 1.6105677745759317, + 2.1096603421691764, + 2.4693190708306534, + 1.8476743345236084, + 1.8476743345236084, + 0.5008430767437717, + 1.1472772191940444, + 0.3742206131637235, + 0.7577334463626749, + 0.5243613182119509, + 0.9622540630906671, + 0.9106269261850113, + 0.6180545588443068, + 0.9759424816595492, + 0.4484748978695576, + 1.8476743345236084, + 2.010264223874775, + 2.2511133880306673, + 2.5065786589076757, + 2.058150606944274, + 1.9180454979641435, + 2.597485654058433, + 0.8267285845255679, + 0.7978548779248045, + 0.4897660751693462, + 0.6757516410166275, + 0.3657262622015941, + 0.3439218450395004, + 0.8806084876191785, + 1.0054885390610133, + 0.4851065903703945, + 0.33119399188631715, + 1.9313442015537254, + 1.7844618810384465, + 1.6025274431324954, + 1.987778688217865, + 1.5476290080061503, + 2.32854706033417, + 2.482270985196589, + 2.0908718205254857, + 2.4422042700327533, + 2.891988316701276, + 2.4422042700327533, + 2.597485654058433, + 3.0197310759414897, + 1.8476743345236084 + ], + "status": "normal", + "min_mw": 4.95, + "type": "CatalogMagnitudeTestResult" +} \ No newline at end of file diff --git a/tests/artifacts/example_csep2_forecasts/Results/catalog_n_test.json b/tests/artifacts/example_csep2_forecasts/Results/catalog_n_test.json new file mode 100644 index 00000000..5ba462f4 --- /dev/null +++ b/tests/artifacts/example_csep2_forecasts/Results/catalog_n_test.json @@ -0,0 +1,10016 @@ +{ + "name": "Catalog N-Test", + "sim_name": "ucerf3-landers", + "obs_name": null, + "obs_catalog_repr": "\n Name: None\n\n Start Date: 1992-06-28 12:00:45+00:00\n End Date: 1992-07-24 18:14:36.250000+00:00\n\n Latitude: (33.901, 36.705)\n Longitude: (-118.067, -116.285)\n\n Min Mw: 4.95\n Max Mw: 6.3\n\n Event Count: 19\n ", + "quantile": [ + 0.0805, + 0.9316 + ], + "observed_statistic": 19, + "test_distribution": [ + 1, + 2, + 6, + 1, + 0, + 1, + 2, + 1, + 1, + 0, + 1, + 2, + 1, + 1, + 3, + 3, + 0, + 1, + 1, + 2, + 2, + 1, + 7, + 0, + 8, + 2, + 2, + 0, + 2, + 0, + 0, + 1, + 7, + 2, + 1, + 0, + 2, + 1, + 0, + 1, + 0, + 7, + 1, + 0, + 2, + 2, + 3, + 1, + 2, + 2, + 1, + 2, + 2, + 0, + 2, + 2, + 0, + 2, + 0, + 0, + 0, + 2, + 0, + 2, + 0, + 1, + 1, + 2, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 2, + 1, + 0, + 2, + 0, + 1, + 1, + 0, + 2, + 0, + 0, + 2, + 0, + 0, + 5, + 1, + 0, + 0, + 6, + 5, + 3, + 0, + 2, + 2, + 0, + 1, + 2, + 1, + 1, + 2, + 2, + 0, + 0, + 0, + 0, + 4, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 12, + 2, + 10, + 6, + 0, + 1, + 3, + 0, + 4, + 0, + 0, + 1, + 2, + 1, + 0, + 1, + 1, + 2, + 1, + 7, + 3, + 3, + 0, + 1, + 0, + 1, + 0, + 0, + 2, + 0, + 1, + 2, + 0, + 7, + 0, + 3, + 2, + 0, + 1, + 2, + 0, + 0, + 1, + 3, + 1, + 1, + 1, + 2, + 0, + 6, + 3, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 2, + 1, + 1, + 2, + 0, + 2, + 2, + 1, + 2, + 0, + 0, + 0, + 1, + 1, + 0, + 2, + 2, + 0, + 0, + 1, + 2, + 1, + 4, + 0, + 1, + 1, + 0, + 3, + 2, + 0, + 1, + 2, + 2, + 1, + 1, + 4, + 0, + 1, + 6, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 2, + 1, + 0, + 0, + 2, + 5, + 3, + 2, + 2, + 2, + 7, + 0, + 2, + 0, + 1, + 0, + 2, + 4, + 0, + 6, + 0, + 0, + 4, + 2, + 0, + 0, + 3, + 0, + 0, + 0, + 0, + 0, + 2, + 1, + 1, + 2, + 1, + 1, + 0, + 1, + 0, + 2, + 1, + 1, + 1, + 0, + 1, + 3, + 1, + 0, + 0, + 2, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 3, + 2, + 1, + 1, + 0, + 0, + 1, + 4, + 0, + 0, + 3, + 2, + 0, + 0, + 0, + 1, + 1, + 2, + 4, + 1, + 0, + 7, + 0, + 4, + 2, + 1, + 2, + 3, + 1, + 3, + 0, + 0, + 1, + 0, + 0, + 1, + 2, + 2, + 2, + 3, + 2, + 2, + 0, + 2, + 1, + 0, + 0, + 0, + 1, + 1, + 2, + 0, + 2, + 1, + 1, + 2, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 4, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 2, + 2, + 1, + 4, + 1, + 1, + 0, + 1, + 1, + 3, + 1, + 6, + 0, + 2, + 0, + 0, + 1, + 2, + 13, + 1, + 1, + 1, + 0, + 3, + 1, + 0, + 19, + 22, + 16, + 12, + 15, + 6, + 17, + 12, + 15, + 14, + 19, + 12, + 14, + 15, + 16, + 16, + 26, + 7, + 24, + 15, + 20, + 14, + 17, + 12, + 7, + 17, + 16, + 22, + 13, + 17, + 15, + 18, + 9, + 21, + 14, + 10, + 17, + 17, + 6, + 13, + 19, + 7, + 10, + 18, + 12, + 7, + 18, + 20, + 13, + 9, + 14, + 10, + 17, + 18, + 14, + 12, + 13, + 13, + 9, + 14, + 11, + 28, + 15, + 8, + 16, + 20, + 13, + 13, + 22, + 46, + 20, + 11, + 15, + 15, + 15, + 22, + 11, + 12, + 8, + 15, + 23, + 19, + 17, + 11, + 11, + 12, + 7, + 8, + 9, + 9, + 16, + 22, + 11, + 15, + 13, + 6, + 11, + 13, + 18, + 9, + 1, + 2, + 1, + 1, + 3, + 0, + 0, + 1, + 0, + 1, + 2, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 4, + 1, + 3, + 1, + 1, + 3, + 2, + 0, + 2, + 2, + 3, + 1, + 1, + 1, + 0, + 1, + 8, + 3, + 2, + 1, + 0, + 1, + 3, + 1, + 1, + 0, + 2, + 2, + 0, + 2, + 2, + 0, + 1, + 2, + 3, + 0, + 1, + 1, + 0, + 3, + 1, + 0, + 0, + 0, + 1, + 1, + 2, + 0, + 4, + 0, + 1, + 2, + 2, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 2, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 2, + 1, + 1, + 2, + 0, + 1, + 0, + 2, + 0, + 5, + 3, + 2, + 0, + 0, + 0, + 2, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 3, + 1, + 0, + 3, + 0, + 0, + 1, + 6, + 1, + 0, + 0, + 3, + 0, + 0, + 0, + 1, + 1, + 1, + 2, + 4, + 2, + 8, + 0, + 0, + 2, + 0, + 3, + 2, + 0, + 2, + 1, + 1, + 2, + 1, + 0, + 3, + 2, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 3, + 1, + 1, + 0, + 3, + 0, + 0, + 0, + 3, + 1, + 2, + 0, + 1, + 2, + 1, + 1, + 3, + 0, + 2, + 0, + 2, + 5, + 0, + 2, + 0, + 0, + 6, + 0, + 4, + 1, + 0, + 3, + 0, + 3, + 2, + 1, + 0, + 0, + 5, + 19, + 25, + 9, + 12, + 18, + 9, + 12, + 16, + 18, + 19, + 11, + 9, + 8, + 14, + 15, + 16, + 12, + 13, + 8, + 12, + 11, + 19, + 29, + 18, + 13, + 16, + 5, + 18, + 15, + 13, + 9, + 10, + 12, + 16, + 18, + 18, + 16, + 11, + 24, + 9, + 11, + 18, + 13, + 41, + 12, + 20, + 25, + 10, + 10, + 20, + 17, + 9, + 10, + 12, + 26, + 19, + 18, + 19, + 12, + 15, + 21, + 8, + 13, + 19, + 14, + 13, + 16, + 12, + 10, + 6, + 17, + 21, + 22, + 15, + 11, + 18, + 17, + 24, + 15, + 18, + 4, + 7, + 21, + 10, + 9, + 12, + 12, + 32, + 12, + 13, + 20, + 14, + 15, + 14, + 8, + 22, + 11, + 17, + 10, + 7, + 1, + 2, + 0, + 1, + 2, + 1, + 0, + 4, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 2, + 0, + 3, + 0, + 3, + 0, + 1, + 1, + 0, + 0, + 2, + 2, + 0, + 2, + 0, + 0, + 0, + 0, + 3, + 0, + 1, + 1, + 4, + 0, + 18, + 6, + 1, + 0, + 0, + 30, + 1, + 2, + 3, + 1, + 1, + 2, + 0, + 0, + 1, + 2, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 7, + 1, + 0, + 7, + 6, + 1, + 2, + 1, + 2, + 0, + 2, + 5, + 0, + 3, + 1, + 1, + 0, + 0, + 1, + 0, + 2, + 1, + 0, + 0, + 1, + 0, + 1, + 2, + 1, + 0, + 0, + 0, + 4, + 4, + 1, + 0, + 1, + 2, + 1, + 2, + 0, + 0, + 0, + 1, + 3, + 2, + 1, + 0, + 2, + 0, + 0, + 0, + 1, + 2, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 2, + 0, + 1, + 3, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 3, + 1, + 1, + 0, + 0, + 8, + 4, + 2, + 4, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 3, + 0, + 3, + 1, + 0, + 2, + 1, + 0, + 0, + 0, + 0, + 0, + 3, + 1, + 3, + 1, + 5, + 0, + 1, + 2, + 2, + 2, + 2, + 1, + 2, + 6, + 0, + 1, + 0, + 1, + 2, + 3, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 3, + 1, + 1, + 2, + 1, + 1, + 0, + 0, + 3, + 2, + 1, + 1, + 5, + 0, + 3, + 0, + 1, + 0, + 1, + 2, + 1, + 1, + 2, + 0, + 3, + 0, + 1, + 2, + 1, + 1, + 0, + 0, + 2, + 1, + 3, + 0, + 0, + 8, + 3, + 1, + 2, + 5, + 0, + 0, + 3, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 5, + 3, + 0, + 1, + 4, + 2, + 3, + 0, + 1, + 3, + 0, + 0, + 1, + 1, + 4, + 0, + 4, + 1, + 1, + 4, + 1, + 1, + 2, + 1, + 0, + 0, + 0, + 0, + 6, + 0, + 3, + 2, + 1, + 2, + 3, + 1, + 0, + 2, + 1, + 1, + 10, + 0, + 1, + 1, + 1, + 0, + 2, + 24, + 11, + 11, + 11, + 11, + 17, + 10, + 10, + 12, + 10, + 11, + 12, + 13, + 18, + 13, + 14, + 20, + 19, + 17, + 15, + 19, + 17, + 11, + 16, + 36, + 10, + 9, + 12, + 11, + 13, + 28, + 22, + 12, + 8, + 17, + 19, + 6, + 24, + 8, + 16, + 16, + 7, + 19, + 10, + 8, + 17, + 6, + 25, + 22, + 19, + 15, + 17, + 15, + 11, + 11, + 15, + 8, + 19, + 18, + 14, + 17, + 15, + 16, + 10, + 18, + 16, + 15, + 6, + 14, + 16, + 15, + 12, + 11, + 8, + 23, + 11, + 15, + 13, + 9, + 21, + 12, + 7, + 8, + 11, + 19, + 17, + 7, + 20, + 16, + 14, + 11, + 13, + 13, + 12, + 17, + 9, + 25, + 23, + 4, + 10, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 4, + 1, + 3, + 0, + 0, + 1, + 6, + 0, + 1, + 0, + 0, + 2, + 3, + 2, + 0, + 2, + 2, + 4, + 2, + 1, + 0, + 0, + 21, + 0, + 0, + 1, + 0, + 1, + 2, + 1, + 0, + 5, + 1, + 2, + 1, + 1, + 0, + 1, + 0, + 0, + 2, + 1, + 1, + 1, + 0, + 0, + 0, + 4, + 1, + 2, + 2, + 1, + 8, + 4, + 1, + 2, + 0, + 1, + 0, + 0, + 0, + 1, + 3, + 1, + 4, + 0, + 3, + 3, + 1, + 0, + 0, + 1, + 1, + 1, + 4, + 1, + 1, + 3, + 1, + 0, + 3, + 2, + 1, + 1, + 2, + 1, + 3, + 1, + 1, + 0, + 1, + 4, + 0, + 1, + 0, + 2, + 2, + 1, + 0, + 3, + 0, + 10, + 2, + 4, + 1, + 0, + 1, + 0, + 1, + 2, + 4, + 0, + 0, + 1, + 0, + 1, + 0, + 7, + 1, + 1, + 4, + 1, + 1, + 1, + 0, + 0, + 1, + 2, + 0, + 0, + 4, + 0, + 1, + 0, + 2, + 0, + 0, + 2, + 2, + 0, + 4, + 3, + 2, + 3, + 2, + 1, + 12, + 0, + 0, + 3, + 3, + 0, + 2, + 1, + 1, + 1, + 1, + 1, + 0, + 3, + 2, + 2, + 5, + 2, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 5, + 1, + 4, + 0, + 1, + 0, + 0, + 2, + 6, + 0, + 0, + 0, + 0, + 2, + 0, + 0, + 0, + 2, + 0, + 0, + 0, + 3, + 4, + 0, + 0, + 8, + 1, + 2, + 1, + 3, + 1, + 2, + 0, + 1, + 0, + 2, + 1, + 1, + 1, + 3, + 1, + 1, + 0, + 2, + 0, + 1, + 0, + 0, + 6, + 1, + 0, + 1, + 1, + 2, + 3, + 1, + 1, + 2, + 0, + 2, + 1, + 0, + 0, + 0, + 0, + 0, + 2, + 0, + 0, + 2, + 2, + 0, + 0, + 1, + 2, + 0, + 1, + 0, + 1, + 0, + 1, + 3, + 0, + 1, + 2, + 0, + 0, + 3, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 7, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 2, + 2, + 0, + 0, + 21, + 16, + 11, + 21, + 13, + 7, + 16, + 18, + 6, + 14, + 20, + 13, + 13, + 15, + 27, + 15, + 8, + 27, + 18, + 13, + 13, + 14, + 20, + 12, + 15, + 14, + 11, + 8, + 18, + 16, + 16, + 14, + 14, + 11, + 22, + 17, + 10, + 17, + 20, + 19, + 26, + 13, + 15, + 12, + 15, + 13, + 17, + 16, + 12, + 9, + 32, + 15, + 14, + 22, + 17, + 13, + 10, + 22, + 18, + 12, + 12, + 13, + 17, + 11, + 19, + 11, + 11, + 32, + 21, + 21, + 17, + 27, + 27, + 10, + 10, + 18, + 11, + 12, + 7, + 27, + 50, + 12, + 24, + 18, + 16, + 12, + 11, + 15, + 12, + 20, + 17, + 15, + 13, + 9, + 19, + 17, + 14, + 7, + 26, + 44, + 16, + 12, + 13, + 13, + 13, + 15, + 18, + 15, + 26, + 18, + 14, + 19, + 16, + 31, + 15, + 13, + 16, + 20, + 9, + 20, + 17, + 31, + 21, + 11, + 20, + 13, + 13, + 9, + 10, + 10, + 10, + 8, + 13, + 13, + 16, + 11, + 14, + 23, + 24, + 24, + 18, + 17, + 18, + 9, + 16, + 13, + 17, + 13, + 20, + 19, + 17, + 19, + 14, + 15, + 19, + 15, + 21, + 15, + 28, + 17, + 14, + 16, + 31, + 10, + 14, + 10, + 12, + 13, + 27, + 13, + 15, + 13, + 9, + 30, + 19, + 25, + 12, + 16, + 7, + 9, + 21, + 14, + 17, + 10, + 18, + 10, + 17, + 15, + 7, + 14, + 11, + 13, + 11, + 14, + 9, + 8, + 18, + 17, + 31, + 4, + 13, + 17, + 22, + 39, + 15, + 23, + 19, + 7, + 15, + 15, + 18, + 21, + 12, + 6, + 10, + 12, + 27, + 20, + 23, + 21, + 8, + 12, + 22, + 15, + 9, + 19, + 13, + 10, + 19, + 15, + 11, + 21, + 7, + 19, + 19, + 15, + 7, + 13, + 16, + 10, + 23, + 20, + 10, + 10, + 7, + 12, + 16, + 10, + 13, + 15, + 15, + 16, + 10, + 17, + 29, + 21, + 13, + 8, + 11, + 17, + 13, + 16, + 20, + 16, + 17, + 13, + 7, + 14, + 12, + 15, + 15, + 17, + 27, + 12, + 7, + 15, + 13, + 10, + 17, + 37, + 12, + 6, + 22, + 10, + 25, + 12, + 10, + 28, + 10, + 11, + 17, + 25, + 12, + 23, + 7, + 21, + 16, + 10, + 10, + 8, + 3, + 2, + 0, + 2, + 0, + 2, + 0, + 2, + 9, + 1, + 0, + 7, + 3, + 0, + 3, + 2, + 0, + 0, + 9, + 1, + 0, + 0, + 2, + 6, + 2, + 0, + 1, + 1, + 1, + 0, + 0, + 4, + 1, + 20, + 0, + 2, + 0, + 0, + 0, + 1, + 1, + 3, + 0, + 1, + 1, + 0, + 5, + 1, + 0, + 1, + 3, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 12, + 3, + 1, + 1, + 0, + 4, + 1, + 0, + 3, + 2, + 6, + 0, + 1, + 0, + 2, + 2, + 1, + 0, + 4, + 0, + 1, + 7, + 2, + 0, + 1, + 0, + 2, + 1, + 0, + 1, + 0, + 0, + 1, + 3, + 1, + 0, + 0, + 0, + 3, + 1, + 0, + 1, + 0, + 1, + 8, + 3, + 2, + 0, + 0, + 1, + 0, + 6, + 2, + 0, + 0, + 2, + 0, + 0, + 2, + 0, + 0, + 0, + 1, + 2, + 2, + 0, + 1, + 3, + 1, + 2, + 1, + 1, + 0, + 4, + 0, + 21, + 0, + 0, + 0, + 2, + 3, + 2, + 3, + 0, + 1, + 0, + 0, + 0, + 3, + 0, + 1, + 0, + 2, + 1, + 0, + 1, + 1, + 5, + 2, + 3, + 0, + 0, + 1, + 3, + 0, + 1, + 2, + 0, + 2, + 1, + 1, + 1, + 0, + 0, + 2, + 0, + 1, + 2, + 1, + 1, + 3, + 2, + 2, + 0, + 4, + 2, + 0, + 1, + 2, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 3, + 3, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 2, + 4, + 1, + 2, + 1, + 1, + 1, + 2, + 8, + 3, + 0, + 6, + 1, + 2, + 1, + 0, + 2, + 0, + 0, + 0, + 1, + 8, + 0, + 1, + 2, + 4, + 0, + 3, + 1, + 1, + 7, + 8, + 1, + 0, + 2, + 2, + 0, + 2, + 5, + 0, + 1, + 1, + 8, + 0, + 0, + 15, + 1, + 0, + 1, + 1, + 0, + 0, + 2, + 0, + 1, + 3, + 0, + 1, + 2, + 2, + 1, + 0, + 3, + 1, + 5, + 1, + 3, + 1, + 0, + 1, + 0, + 2, + 0, + 0, + 1, + 0, + 0, + 4, + 0, + 1, + 8, + 3, + 1, + 1, + 2, + 0, + 2, + 3, + 3, + 0, + 2, + 3, + 5, + 0, + 0, + 0, + 1, + 0, + 0, + 2, + 1, + 5, + 0, + 2, + 3, + 1, + 1, + 0, + 1, + 2, + 2, + 2, + 0, + 0, + 7, + 2, + 2, + 1, + 4, + 2, + 0, + 3, + 0, + 2, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 3, + 1, + 0, + 2, + 0, + 2, + 2, + 1, + 1, + 0, + 3, + 2, + 0, + 1, + 0, + 2, + 2, + 7, + 1, + 2, + 1, + 5, + 6, + 3, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 2, + 0, + 3, + 1, + 2, + 1, + 1, + 1, + 5, + 2, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 3, + 0, + 1, + 3, + 3, + 4, + 1, + 1, + 3, + 1, + 7, + 2, + 4, + 4, + 0, + 1, + 0, + 1, + 0, + 8, + 0, + 2, + 0, + 0, + 4, + 1, + 1, + 1, + 0, + 6, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 3, + 0, + 2, + 0, + 0, + 1, + 2, + 2, + 1, + 2, + 0, + 0, + 2, + 5, + 1, + 0, + 5, + 2, + 0, + 1, + 2, + 1, + 1, + 0, + 1, + 0, + 2, + 1, + 0, + 5, + 2, + 1, + 3, + 0, + 1, + 1, + 0, + 2, + 1, + 2, + 1, + 0, + 0, + 2, + 1, + 7, + 0, + 1, + 3, + 0, + 3, + 0, + 2, + 1, + 1, + 0, + 0, + 3, + 0, + 4, + 2, + 1, + 1, + 4, + 1, + 4, + 1, + 2, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 3, + 2, + 1, + 1, + 1, + 0, + 1, + 0, + 35, + 0, + 2, + 1, + 2, + 0, + 2, + 1, + 1, + 7, + 3, + 1, + 0, + 2, + 1, + 0, + 1, + 0, + 4, + 1, + 2, + 3, + 4, + 0, + 4, + 2, + 0, + 0, + 0, + 1, + 2, + 0, + 1, + 5, + 3, + 3, + 3, + 0, + 2, + 2, + 0, + 3, + 7, + 0, + 2, + 0, + 1, + 0, + 1, + 13, + 1, + 0, + 2, + 0, + 2, + 2, + 8, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 3, + 0, + 1, + 0, + 2, + 1, + 0, + 1, + 2, + 3, + 0, + 9, + 11, + 18, + 14, + 11, + 19, + 15, + 9, + 20, + 18, + 13, + 17, + 9, + 13, + 6, + 16, + 12, + 9, + 14, + 12, + 12, + 15, + 18, + 22, + 24, + 15, + 14, + 17, + 19, + 11, + 12, + 17, + 15, + 18, + 13, + 10, + 12, + 20, + 11, + 21, + 27, + 11, + 11, + 14, + 18, + 10, + 14, + 55, + 26, + 23, + 13, + 43, + 22, + 12, + 15, + 14, + 14, + 22, + 15, + 12, + 22, + 20, + 6, + 20, + 17, + 31, + 17, + 23, + 15, + 21, + 13, + 12, + 14, + 22, + 27, + 25, + 16, + 9, + 12, + 20, + 18, + 10, + 15, + 10, + 7, + 14, + 8, + 28, + 16, + 7, + 16, + 13, + 17, + 5, + 25, + 11, + 29, + 9, + 13, + 15, + 0, + 1, + 2, + 5, + 1, + 1, + 6, + 3, + 2, + 0, + 0, + 1, + 1, + 2, + 1, + 1, + 0, + 1, + 1, + 2, + 3, + 3, + 1, + 1, + 1, + 2, + 5, + 0, + 0, + 1, + 0, + 3, + 0, + 2, + 2, + 0, + 13, + 1, + 0, + 0, + 2, + 0, + 1, + 2, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 3, + 1, + 3, + 2, + 1, + 0, + 0, + 0, + 0, + 2, + 2, + 4, + 1, + 0, + 0, + 1, + 0, + 2, + 1, + 0, + 0, + 3, + 3, + 2, + 0, + 2, + 1, + 1, + 2, + 2, + 0, + 0, + 2, + 1, + 0, + 0, + 2, + 0, + 0, + 1, + 1, + 3, + 2, + 0, + 2, + 1, + 0, + 3, + 2, + 1, + 1, + 0, + 1, + 0, + 1, + 2, + 1, + 2, + 3, + 1, + 2, + 3, + 3, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 3, + 1, + 1, + 0, + 1, + 4, + 0, + 3, + 2, + 0, + 1, + 0, + 2, + 2, + 1, + 0, + 0, + 1, + 0, + 1, + 2, + 0, + 0, + 1, + 0, + 1, + 1, + 2, + 2, + 0, + 1, + 2, + 1, + 8, + 1, + 1, + 1, + 1, + 0, + 1, + 2, + 0, + 1, + 2, + 1, + 1, + 0, + 1, + 0, + 2, + 0, + 2, + 1, + 6, + 1, + 0, + 0, + 1, + 2, + 3, + 0, + 1, + 0, + 0, + 3, + 0, + 1, + 0, + 1, + 6, + 0, + 0, + 1, + 1, + 1, + 3, + 0, + 2, + 1, + 1, + 0, + 4, + 7, + 0, + 0, + 2, + 1, + 0, + 4, + 3, + 0, + 1, + 1, + 0, + 17, + 1, + 0, + 0, + 3, + 0, + 1, + 5, + 4, + 1, + 2, + 2, + 3, + 1, + 1, + 0, + 2, + 3, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 2, + 0, + 4, + 0, + 0, + 5, + 2, + 4, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 3, + 0, + 1, + 0, + 5, + 1, + 0, + 1, + 0, + 0, + 2, + 2, + 0, + 1, + 0, + 2, + 3, + 3, + 2, + 4, + 4, + 0, + 0, + 3, + 1, + 0, + 0, + 0, + 0, + 3, + 0, + 1, + 2, + 0, + 17, + 1, + 1, + 1, + 1, + 4, + 0, + 0, + 0, + 4, + 12, + 18, + 15, + 18, + 15, + 13, + 16, + 18, + 14, + 20, + 16, + 21, + 14, + 10, + 19, + 12, + 13, + 17, + 8, + 15, + 9, + 9, + 21, + 17, + 9, + 21, + 12, + 12, + 12, + 8, + 24, + 6, + 18, + 12, + 15, + 15, + 10, + 16, + 13, + 7, + 14, + 9, + 5, + 7, + 14, + 10, + 24, + 15, + 12, + 11, + 19, + 14, + 18, + 12, + 16, + 16, + 15, + 11, + 6, + 20, + 23, + 11, + 8, + 10, + 16, + 21, + 21, + 15, + 17, + 22, + 16, + 12, + 16, + 12, + 16, + 12, + 8, + 17, + 15, + 14, + 17, + 9, + 11, + 23, + 11, + 18, + 15, + 16, + 20, + 16, + 20, + 17, + 23, + 14, + 5, + 12, + 13, + 17, + 9, + 7, + 13, + 10, + 9, + 15, + 12, + 16, + 16, + 8, + 15, + 15, + 9, + 28, + 14, + 14, + 15, + 5, + 14, + 13, + 5, + 14, + 14, + 79, + 20, + 16, + 11, + 21, + 10, + 29, + 17, + 8, + 16, + 13, + 5, + 21, + 15, + 26, + 11, + 12, + 12, + 20, + 17, + 16, + 14, + 11, + 12, + 13, + 23, + 16, + 14, + 19, + 6, + 16, + 29, + 12, + 18, + 18, + 15, + 19, + 20, + 16, + 18, + 15, + 17, + 13, + 25, + 24, + 15, + 8, + 18, + 13, + 15, + 18, + 8, + 15, + 19, + 16, + 12, + 32, + 9, + 12, + 20, + 17, + 15, + 21, + 11, + 15, + 24, + 10, + 11, + 16, + 14, + 11, + 21, + 9, + 15, + 14, + 21, + 15, + 16, + 13, + 0, + 1, + 0, + 0, + 0, + 2, + 0, + 1, + 1, + 0, + 0, + 24, + 4, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 2, + 0, + 1, + 0, + 1, + 0, + 1, + 2, + 4, + 0, + 3, + 2, + 0, + 0, + 0, + 0, + 1, + 2, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 5, + 1, + 2, + 0, + 2, + 5, + 1, + 0, + 0, + 0, + 2, + 5, + 3, + 0, + 2, + 2, + 1, + 0, + 1, + 6, + 1, + 0, + 1, + 0, + 0, + 0, + 3, + 0, + 1, + 0, + 2, + 1, + 0, + 0, + 4, + 2, + 3, + 2, + 0, + 0, + 1, + 1, + 4, + 0, + 3, + 1, + 0, + 2, + 1, + 1, + 2, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 4, + 0, + 0, + 2, + 0, + 2, + 1, + 0, + 1, + 0, + 1, + 3, + 1, + 0, + 3, + 5, + 1, + 0, + 0, + 0, + 2, + 2, + 1, + 3, + 0, + 1, + 5, + 7, + 2, + 0, + 2, + 1, + 1, + 0, + 0, + 1, + 2, + 1, + 6, + 3, + 2, + 3, + 1, + 0, + 1, + 0, + 2, + 1, + 0, + 0, + 1, + 2, + 0, + 2, + 2, + 1, + 0, + 0, + 1, + 0, + 1, + 2, + 1, + 3, + 0, + 0, + 0, + 2, + 0, + 0, + 0, + 3, + 0, + 0, + 0, + 2, + 1, + 1, + 0, + 2, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 3, + 1, + 2, + 12, + 16, + 14, + 9, + 15, + 13, + 13, + 12, + 11, + 10, + 8, + 37, + 27, + 11, + 17, + 17, + 21, + 40, + 7, + 13, + 10, + 8, + 23, + 10, + 17, + 10, + 10, + 10, + 15, + 19, + 23, + 13, + 14, + 12, + 17, + 23, + 11, + 11, + 11, + 12, + 16, + 19, + 20, + 19, + 22, + 11, + 11, + 13, + 13, + 34, + 20, + 8, + 12, + 5, + 19, + 16, + 11, + 11, + 19, + 19, + 20, + 13, + 14, + 19, + 12, + 68, + 22, + 12, + 16, + 25, + 12, + 14, + 7, + 28, + 23, + 19, + 14, + 15, + 53, + 25, + 16, + 15, + 14, + 9, + 12, + 13, + 57, + 15, + 16, + 18, + 12, + 17, + 14, + 41, + 20, + 15, + 10, + 13, + 15, + 21, + 2, + 1, + 0, + 2, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 4, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 9, + 2, + 1, + 2, + 0, + 3, + 3, + 4, + 0, + 3, + 2, + 0, + 0, + 0, + 4, + 3, + 1, + 2, + 1, + 1, + 2, + 0, + 2, + 3, + 0, + 1, + 0, + 5, + 1, + 7, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 2, + 1, + 2, + 5, + 0, + 1, + 3, + 1, + 2, + 1, + 3, + 2, + 0, + 1, + 1, + 1, + 2, + 1, + 2, + 3, + 1, + 3, + 2, + 1, + 1, + 2, + 0, + 1, + 4, + 2, + 0, + 2, + 0, + 0, + 1, + 3, + 0, + 0, + 1, + 6, + 3, + 3, + 19, + 20, + 8, + 19, + 5, + 10, + 23, + 7, + 26, + 13, + 15, + 15, + 15, + 13, + 18, + 4, + 15, + 15, + 12, + 8, + 21, + 9, + 16, + 22, + 12, + 12, + 12, + 18, + 10, + 13, + 26, + 11, + 15, + 21, + 22, + 16, + 8, + 14, + 10, + 20, + 19, + 12, + 19, + 20, + 12, + 14, + 12, + 9, + 13, + 20, + 6, + 12, + 18, + 11, + 10, + 35, + 9, + 16, + 15, + 13, + 21, + 18, + 17, + 19, + 8, + 11, + 43, + 16, + 20, + 13, + 11, + 13, + 16, + 18, + 18, + 12, + 11, + 16, + 24, + 15, + 17, + 20, + 18, + 17, + 10, + 22, + 14, + 16, + 11, + 15, + 6, + 11, + 23, + 9, + 14, + 22, + 11, + 7, + 9, + 20, + 12, + 12, + 18, + 12, + 10, + 21, + 21, + 18, + 15, + 23, + 14, + 11, + 18, + 10, + 19, + 10, + 26, + 14, + 9, + 14, + 14, + 17, + 16, + 16, + 25, + 24, + 14, + 16, + 13, + 22, + 9, + 35, + 15, + 11, + 7, + 51, + 14, + 11, + 15, + 11, + 20, + 14, + 16, + 23, + 27, + 12, + 18, + 8, + 16, + 15, + 7, + 14, + 32, + 13, + 19, + 14, + 18, + 19, + 25, + 10, + 8, + 11, + 16, + 15, + 11, + 12, + 17, + 9, + 13, + 18, + 12, + 18, + 18, + 12, + 13, + 21, + 17, + 11, + 16, + 22, + 17, + 11, + 14, + 21, + 28, + 15, + 3, + 18, + 43, + 23, + 18, + 13, + 17, + 6, + 14, + 9, + 12, + 28, + 13, + 22, + 0, + 1, + 1, + 3, + 1, + 1, + 10, + 0, + 4, + 1, + 1, + 4, + 0, + 2, + 8, + 0, + 2, + 2, + 1, + 2, + 0, + 1, + 1, + 1, + 0, + 1, + 3, + 4, + 0, + 4, + 0, + 3, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 4, + 0, + 0, + 1, + 2, + 0, + 0, + 1, + 0, + 1, + 1, + 2, + 1, + 1, + 0, + 1, + 1, + 0, + 2, + 2, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 2, + 1, + 7, + 1, + 2, + 2, + 1, + 0, + 1, + 2, + 2, + 1, + 1, + 0, + 1, + 3, + 3, + 1, + 0, + 18, + 0, + 2, + 1, + 2, + 1, + 0, + 0, + 5, + 1, + 3, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 4, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 15, + 2, + 0, + 3, + 2, + 0, + 0, + 1, + 0, + 5, + 2, + 3, + 1, + 0, + 0, + 4, + 0, + 14, + 9, + 0, + 0, + 0, + 2, + 1, + 4, + 1, + 2, + 4, + 2, + 3, + 3, + 4, + 1, + 1, + 1, + 3, + 2, + 0, + 2, + 3, + 5, + 0, + 3, + 1, + 1, + 2, + 0, + 0, + 3, + 0, + 0, + 1, + 2, + 0, + 0, + 0, + 0, + 0, + 2, + 0, + 0, + 0, + 1, + 7, + 0, + 0, + 3, + 1, + 25, + 0, + 3, + 0, + 1, + 0, + 1, + 0, + 5, + 1, + 0, + 1, + 0, + 0, + 1, + 4, + 0, + 3, + 0, + 0, + 2, + 2, + 9, + 1, + 2, + 1, + 0, + 0, + 2, + 0, + 0, + 2, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 3, + 0, + 1, + 0, + 2, + 2, + 1, + 0, + 2, + 5, + 1, + 1, + 2, + 0, + 2, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 3, + 0, + 18, + 0, + 3, + 2, + 1, + 1, + 2, + 5, + 3, + 2, + 1, + 2, + 2, + 3, + 3, + 0, + 2, + 0, + 0, + 1, + 3, + 0, + 0, + 1, + 1, + 2, + 0, + 0, + 0, + 0, + 4, + 0, + 5, + 3, + 0, + 4, + 2, + 1, + 7, + 4, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 3, + 2, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 4, + 2, + 1, + 6, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 2, + 0, + 3, + 0, + 1, + 5, + 2, + 2, + 0, + 0, + 1, + 3, + 0, + 0, + 3, + 0, + 0, + 1, + 1, + 2, + 1, + 2, + 0, + 0, + 4, + 0, + 0, + 3, + 1, + 0, + 1, + 1, + 0, + 2, + 0, + 1, + 0, + 0, + 0, + 0, + 14, + 0, + 1, + 0, + 0, + 0, + 2, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 3, + 4, + 0, + 3, + 1, + 5, + 0, + 0, + 0, + 1, + 3, + 0, + 1, + 6, + 0, + 0, + 1, + 1, + 2, + 1, + 0, + 2, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 3, + 2, + 0, + 0, + 0, + 6, + 2, + 0, + 3, + 2, + 4, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 2, + 2, + 0, + 0, + 2, + 0, + 3, + 0, + 3, + 1, + 1, + 1, + 0, + 0, + 2, + 0, + 1, + 0, + 1, + 1, + 2, + 0, + 0, + 1, + 0, + 0, + 1, + 2, + 2, + 0, + 1, + 0, + 1, + 1, + 2, + 1, + 0, + 1, + 4, + 1, + 0, + 2, + 0, + 1, + 2, + 1, + 2, + 1, + 2, + 0, + 1, + 3, + 1, + 2, + 1, + 3, + 0, + 1, + 1, + 1, + 1, + 3, + 2, + 1, + 2, + 1, + 4, + 2, + 0, + 0, + 0, + 1, + 2, + 1, + 2, + 1, + 6, + 2, + 0, + 2, + 1, + 1, + 4, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 6, + 1, + 0, + 0, + 1, + 1, + 0, + 6, + 2, + 4, + 2, + 3, + 3, + 1, + 4, + 1, + 0, + 1, + 0, + 1, + 2, + 2, + 10, + 1, + 2, + 1, + 0, + 0, + 1, + 1, + 2, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 2, + 0, + 2, + 0, + 3, + 0, + 6, + 0, + 0, + 3, + 2, + 2, + 0, + 2, + 0, + 2, + 0, + 0, + 0, + 2, + 2, + 2, + 1, + 1, + 2, + 1, + 0, + 1, + 2, + 0, + 1, + 1, + 2, + 2, + 1, + 1, + 0, + 2, + 1, + 3, + 1, + 1, + 0, + 0, + 3, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 2, + 2, + 0, + 0, + 4, + 3, + 0, + 0, + 1, + 1, + 0, + 2, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 3, + 3, + 18, + 2, + 2, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 3, + 1, + 2, + 1, + 0, + 0, + 3, + 0, + 0, + 0, + 0, + 2, + 1, + 0, + 2, + 1, + 2, + 1, + 5, + 2, + 1, + 3, + 0, + 5, + 3, + 2, + 0, + 0, + 1, + 1, + 0, + 2, + 2, + 0, + 1, + 2, + 0, + 8, + 2, + 1, + 1, + 2, + 2, + 2, + 1, + 2, + 1, + 0, + 9, + 1, + 1, + 1, + 2, + 1, + 6, + 1, + 0, + 10, + 2, + 0, + 1, + 2, + 1, + 0, + 2, + 3, + 0, + 1, + 0, + 5, + 0, + 0, + 0, + 6, + 2, + 4, + 0, + 1, + 0, + 2, + 0, + 6, + 1, + 0, + 1, + 2, + 1, + 0, + 1, + 2, + 1, + 1, + 2, + 2, + 0, + 2, + 0, + 6, + 0, + 1, + 3, + 5, + 2, + 0, + 0, + 0, + 3, + 0, + 3, + 0, + 3, + 0, + 0, + 4, + 2, + 7, + 0, + 1, + 0, + 0, + 0, + 0, + 2, + 1, + 1, + 2, + 0, + 2, + 1, + 3, + 1, + 0, + 0, + 3, + 4, + 0, + 1, + 0, + 1, + 2, + 0, + 3, + 0, + 7, + 0, + 5, + 0, + 0, + 0, + 1, + 0, + 4, + 3, + 0, + 1, + 4, + 0, + 2, + 1, + 0, + 1, + 2, + 0, + 2, + 1, + 0, + 4, + 1, + 0, + 0, + 0, + 1, + 4, + 0, + 1, + 1, + 1, + 1, + 1, + 5, + 1, + 0, + 2, + 1, + 0, + 0, + 0, + 0, + 0, + 2, + 0, + 1, + 0, + 2, + 1, + 3, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 3, + 0, + 0, + 0, + 2, + 2, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 6, + 1, + 1, + 9, + 0, + 0, + 0, + 2, + 3, + 0, + 1, + 4, + 4, + 2, + 1, + 2, + 2, + 2, + 0, + 0, + 2, + 2, + 1, + 1, + 3, + 0, + 2, + 1, + 0, + 2, + 0, + 1, + 4, + 2, + 1, + 1, + 2, + 2, + 0, + 5, + 6, + 2, + 5, + 0, + 0, + 1, + 0, + 4, + 1, + 1, + 1, + 0, + 0, + 2, + 3, + 0, + 0, + 1, + 1, + 2, + 0, + 2, + 5, + 1, + 0, + 0, + 1, + 0, + 0, + 2, + 1, + 2, + 4, + 0, + 0, + 0, + 0, + 5, + 1, + 1, + 0, + 4, + 1, + 1, + 2, + 3, + 2, + 3, + 4, + 0, + 2, + 3, + 4, + 2, + 1, + 2, + 0, + 0, + 1, + 5, + 0, + 2, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 2, + 2, + 2, + 2, + 0, + 2, + 12, + 22, + 12, + 15, + 30, + 19, + 13, + 13, + 18, + 18, + 25, + 16, + 33, + 10, + 15, + 20, + 23, + 9, + 17, + 18, + 13, + 16, + 13, + 22, + 14, + 19, + 13, + 20, + 20, + 17, + 16, + 19, + 11, + 13, + 12, + 13, + 18, + 22, + 17, + 19, + 16, + 18, + 18, + 11, + 15, + 17, + 22, + 7, + 10, + 16, + 23, + 19, + 21, + 12, + 25, + 29, + 23, + 11, + 18, + 19, + 14, + 20, + 12, + 10, + 16, + 10, + 21, + 12, + 15, + 8, + 25, + 14, + 16, + 28, + 16, + 20, + 11, + 8, + 16, + 18, + 18, + 12, + 14, + 6, + 17, + 16, + 6, + 17, + 10, + 14, + 11, + 15, + 12, + 15, + 15, + 12, + 13, + 15, + 13, + 11, + 0, + 0, + 4, + 0, + 1, + 7, + 4, + 0, + 1, + 0, + 0, + 7, + 1, + 1, + 1, + 0, + 1, + 2, + 0, + 0, + 3, + 0, + 0, + 2, + 2, + 0, + 3, + 0, + 0, + 3, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3, + 0, + 3, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 3, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 2, + 0, + 3, + 4, + 1, + 1, + 2, + 0, + 0, + 2, + 1, + 3, + 0, + 6, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 2, + 1, + 0, + 5, + 3, + 2, + 3, + 0, + 0, + 1, + 0, + 2, + 2, + 2, + 0, + 2, + 2, + 1, + 0, + 0, + 7, + 16, + 16, + 14, + 20, + 11, + 25, + 13, + 19, + 22, + 15, + 11, + 24, + 13, + 22, + 12, + 16, + 31, + 7, + 8, + 14, + 11, + 7, + 14, + 19, + 13, + 18, + 12, + 13, + 13, + 10, + 20, + 17, + 13, + 10, + 12, + 13, + 13, + 32, + 16, + 15, + 16, + 14, + 22, + 15, + 12, + 9, + 35, + 22, + 28, + 16, + 10, + 18, + 19, + 16, + 17, + 20, + 22, + 19, + 26, + 13, + 12, + 18, + 13, + 22, + 7, + 8, + 15, + 20, + 14, + 13, + 29, + 16, + 9, + 12, + 10, + 13, + 21, + 9, + 12, + 17, + 15, + 11, + 22, + 20, + 4, + 9, + 27, + 33, + 13, + 14, + 12, + 12, + 25, + 31, + 20, + 12, + 12, + 8, + 17, + 17, + 10, + 7, + 20, + 6, + 18, + 22, + 14, + 13, + 12, + 18, + 38, + 18, + 11, + 18, + 38, + 29, + 16, + 18, + 10, + 16, + 21, + 14, + 44, + 25, + 15, + 7, + 21, + 14, + 22, + 15, + 13, + 7, + 15, + 21, + 10, + 18, + 7, + 16, + 26, + 11, + 23, + 15, + 13, + 9, + 13, + 12, + 20, + 19, + 15, + 24, + 13, + 25, + 15, + 13, + 48, + 11, + 12, + 12, + 13, + 13, + 17, + 8, + 14, + 33, + 15, + 17, + 16, + 21, + 9, + 15, + 8, + 9, + 20, + 18, + 23, + 15, + 17, + 16, + 35, + 5, + 8, + 12, + 13, + 13, + 12, + 8, + 23, + 15, + 13, + 15, + 10, + 23, + 13, + 18, + 15, + 25, + 30, + 18, + 13, + 0, + 1, + 0, + 2, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 2, + 7, + 5, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 5, + 0, + 2, + 0, + 0, + 27, + 0, + 1, + 0, + 1, + 3, + 0, + 1, + 3, + 1, + 6, + 0, + 0, + 3, + 3, + 2, + 2, + 0, + 0, + 10, + 0, + 3, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 17, + 0, + 0, + 1, + 1, + 3, + 2, + 1, + 1, + 3, + 0, + 0, + 3, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 2, + 1, + 1, + 1, + 1, + 2, + 0, + 0, + 1, + 0, + 0, + 2, + 0, + 0, + 0, + 1, + 18, + 5, + 18, + 14, + 14, + 11, + 17, + 33, + 11, + 23, + 21, + 13, + 10, + 23, + 19, + 21, + 13, + 13, + 16, + 16, + 22, + 8, + 12, + 20, + 12, + 15, + 15, + 22, + 17, + 18, + 11, + 12, + 17, + 19, + 29, + 21, + 14, + 8, + 8, + 9, + 13, + 9, + 19, + 15, + 11, + 35, + 26, + 24, + 10, + 14, + 18, + 20, + 10, + 14, + 26, + 9, + 4, + 16, + 13, + 19, + 14, + 28, + 20, + 17, + 17, + 26, + 18, + 18, + 15, + 27, + 13, + 17, + 21, + 10, + 22, + 15, + 16, + 11, + 9, + 10, + 9, + 17, + 7, + 11, + 14, + 13, + 14, + 16, + 14, + 12, + 17, + 13, + 18, + 18, + 16, + 20, + 12, + 27, + 16, + 11, + 12, + 20, + 13, + 15, + 18, + 14, + 5, + 11, + 21, + 22, + 13, + 10, + 15, + 21, + 8, + 22, + 8, + 13, + 20, + 21, + 14, + 11, + 11, + 12, + 14, + 13, + 17, + 21, + 31, + 17, + 13, + 10, + 6, + 14, + 5, + 16, + 13, + 15, + 23, + 16, + 14, + 16, + 17, + 13, + 13, + 10, + 7, + 11, + 12, + 15, + 17, + 15, + 6, + 13, + 10, + 13, + 16, + 15, + 19, + 11, + 14, + 10, + 11, + 16, + 21, + 9, + 21, + 16, + 9, + 8, + 11, + 15, + 10, + 8, + 11, + 11, + 13, + 15, + 10, + 10, + 19, + 22, + 13, + 14, + 25, + 11, + 11, + 9, + 13, + 10, + 11, + 14, + 28, + 18, + 11, + 14, + 18, + 20, + 14, + 19, + 20, + 9, + 16, + 15, + 22, + 14, + 24, + 21, + 9, + 24, + 13, + 15, + 8, + 10, + 15, + 13, + 12, + 13, + 26, + 14, + 13, + 21, + 25, + 15, + 18, + 19, + 12, + 15, + 19, + 14, + 14, + 24, + 35, + 20, + 12, + 10, + 13, + 9, + 18, + 26, + 13, + 9, + 20, + 13, + 11, + 13, + 26, + 19, + 14, + 26, + 11, + 24, + 16, + 8, + 12, + 12, + 24, + 19, + 16, + 16, + 30, + 27, + 17, + 8, + 8, + 10, + 15, + 9, + 15, + 13, + 22, + 27, + 21, + 18, + 7, + 15, + 15, + 11, + 8, + 12, + 17, + 16, + 18, + 17, + 10, + 11, + 9, + 18, + 8, + 15, + 10, + 16, + 15, + 8, + 30, + 9, + 33, + 6, + 8, + 42, + 2, + 1, + 2, + 5, + 2, + 0, + 0, + 0, + 3, + 0, + 1, + 3, + 0, + 0, + 1, + 2, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 3, + 0, + 0, + 0, + 0, + 0, + 6, + 0, + 1, + 1, + 2, + 1, + 1, + 1, + 1, + 6, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 2, + 1, + 2, + 2, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 3, + 1, + 1, + 1, + 1, + 0, + 8, + 0, + 2, + 3, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 2, + 2, + 3, + 0, + 0, + 10, + 1, + 1, + 0, + 2, + 1, + 1, + 0, + 1, + 1, + 2, + 1, + 0, + 3, + 1, + 0, + 5, + 0, + 0, + 0, + 0, + 0, + 1, + 2, + 0, + 1, + 0, + 0, + 1, + 1, + 2, + 4, + 2, + 1, + 0, + 1, + 1, + 1, + 0, + 4, + 2, + 1, + 2, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 5, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 2, + 0, + 3, + 0, + 2, + 0, + 2, + 0, + 2, + 0, + 3, + 1, + 1, + 0, + 2, + 2, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 2, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 2, + 0, + 3, + 1, + 8, + 0, + 0, + 2, + 1, + 0, + 2, + 0, + 0, + 0, + 0, + 0, + 0, + 2, + 3, + 0, + 1, + 1, + 0, + 2, + 0, + 0, + 2, + 0, + 2, + 3, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 2, + 2, + 3, + 2, + 0, + 1, + 0, + 4, + 1, + 0, + 0, + 0, + 0, + 2, + 1, + 11, + 0, + 2, + 4, + 2, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 3, + 3, + 0, + 0, + 17, + 0, + 1, + 13, + 1, + 2, + 0, + 2, + 0, + 2, + 2, + 0, + 2, + 1, + 0, + 1, + 1, + 1, + 2, + 0, + 0, + 2, + 0, + 0, + 4, + 1, + 1, + 10, + 3, + 0, + 1, + 0, + 2, + 3, + 2, + 1, + 0, + 3, + 1, + 0, + 3, + 1, + 0, + 2, + 1, + 0, + 1, + 2, + 1, + 1, + 1, + 0, + 1, + 1, + 2, + 2, + 1, + 3, + 1, + 2, + 1, + 0, + 2, + 0, + 0, + 1, + 2, + 2, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 71, + 6, + 0, + 0, + 2, + 0, + 0, + 0, + 0, + 2, + 0, + 1, + 3, + 0, + 3, + 2, + 1, + 0, + 5, + 2, + 1, + 7, + 0, + 0, + 0, + 1, + 2, + 2, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 2, + 0, + 0, + 1, + 0, + 0, + 0, + 3, + 1, + 0, + 2, + 0, + 3, + 1, + 0, + 0, + 3, + 8, + 1, + 1, + 0, + 3, + 25, + 1, + 0, + 0, + 0, + 2, + 1, + 2, + 3, + 0, + 3, + 3, + 0, + 6, + 1, + 0, + 4, + 0, + 0, + 0, + 0, + 0, + 2, + 0, + 1, + 1, + 1, + 0, + 0, + 3, + 1, + 1, + 1, + 3, + 0, + 1, + 6, + 0, + 0, + 2, + 0, + 0, + 5, + 1, + 3, + 0, + 0, + 0, + 0, + 2, + 0, + 0, + 1, + 4, + 3, + 3, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 5, + 2, + 0, + 0, + 2, + 0, + 1, + 1, + 2, + 0, + 0, + 0, + 2, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 3, + 0, + 3, + 1, + 0, + 0, + 0, + 3, + 0, + 0, + 1, + 1, + 2, + 0, + 3, + 2, + 0, + 2, + 0, + 4, + 2, + 0, + 2, + 1, + 0, + 16, + 1, + 2, + 1, + 0, + 0, + 3, + 1, + 1, + 3, + 1, + 0, + 3, + 2, + 3, + 3, + 1, + 0, + 1, + 2, + 0, + 1, + 3, + 2, + 0, + 2, + 1, + 0, + 3, + 0, + 2, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 3, + 3, + 4, + 0, + 0, + 0, + 4, + 2, + 1, + 2, + 0, + 1, + 0, + 4, + 2, + 2, + 4, + 4, + 1, + 3, + 0, + 2, + 0, + 8, + 2, + 1, + 2, + 0, + 0, + 0, + 1, + 0, + 3, + 1, + 0, + 0, + 0, + 3, + 1, + 1, + 2, + 1, + 1, + 0, + 3, + 2, + 2, + 0, + 0, + 1, + 0, + 0, + 2, + 0, + 0, + 12, + 1, + 0, + 0, + 1, + 2, + 1, + 0, + 4, + 0, + 3, + 1, + 0, + 3, + 0, + 4, + 0, + 1, + 1, + 4, + 2, + 0, + 0, + 3, + 5, + 0, + 3, + 3, + 1, + 0, + 3, + 1, + 1, + 1, + 2, + 0, + 1, + 5, + 0, + 4, + 3, + 1, + 4, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 3, + 3, + 1, + 1, + 0, + 1, + 0, + 2, + 2, + 1, + 0, + 1, + 0, + 0, + 0, + 2, + 0, + 0, + 0, + 5, + 1, + 1, + 1, + 1, + 2, + 3, + 0, + 2, + 0, + 2, + 0, + 9, + 0, + 0, + 0, + 1, + 1, + 0, + 2, + 2, + 0, + 0, + 1, + 0, + 0, + 2, + 3, + 3, + 0, + 1, + 1, + 2, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 2, + 1, + 1, + 0, + 1, + 1, + 0, + 2, + 1, + 1, + 1, + 3, + 1, + 0, + 0, + 0, + 2, + 2, + 3, + 0, + 0, + 1, + 0, + 0, + 2, + 1, + 0, + 0, + 1, + 1, + 0, + 3, + 1, + 0, + 6, + 1, + 0, + 0, + 1, + 0, + 0, + 2, + 0, + 0, + 3, + 5, + 2, + 1, + 0, + 2, + 3, + 0, + 0, + 1, + 1, + 1, + 0, + 2, + 2, + 1, + 4, + 0, + 1, + 3, + 1, + 2, + 3, + 1, + 3, + 0, + 0, + 2, + 0, + 2, + 0, + 1, + 5, + 0, + 1, + 2, + 3, + 1, + 0, + 1, + 2, + 3, + 2, + 3, + 1, + 1, + 0, + 0, + 2, + 1, + 1, + 6, + 2, + 0, + 1, + 1, + 1, + 0, + 5, + 1, + 12, + 0, + 0, + 1, + 0, + 1, + 1, + 2, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 2, + 0, + 1, + 3, + 1, + 0, + 1, + 2, + 3, + 1, + 0, + 0, + 1, + 1, + 7, + 1, + 2, + 0, + 1, + 1, + 1, + 0, + 2, + 0, + 1, + 1, + 3, + 1, + 1, + 4, + 0, + 2, + 0, + 0, + 2, + 2, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 7, + 0, + 0, + 0, + 2, + 1, + 3, + 2, + 0, + 1, + 2, + 0, + 1, + 0, + 0, + 1, + 0, + 2, + 6, + 1, + 1, + 1, + 2, + 1, + 0, + 0, + 3, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 2, + 1, + 0, + 0, + 3, + 1, + 1, + 0, + 3, + 0, + 2, + 0, + 1, + 1, + 1, + 3, + 1, + 0, + 1, + 1, + 2, + 3, + 5, + 2, + 0, + 2, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 4, + 12, + 1, + 1, + 0, + 2, + 3, + 1, + 3, + 0, + 2, + 0, + 2, + 1, + 3, + 1, + 5, + 2, + 0, + 0, + 2, + 1, + 1, + 1, + 1, + 1, + 1, + 2, + 0, + 0, + 0, + 1, + 2, + 0, + 1, + 2, + 3, + 1, + 0, + 2, + 0, + 1, + 2, + 1, + 0, + 0, + 6, + 1, + 1, + 0, + 1, + 0, + 1, + 3, + 1, + 2, + 0, + 2, + 0, + 3, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 4, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 5, + 3, + 2, + 1, + 8, + 2, + 2, + 0, + 1, + 0, + 1, + 0, + 0, + 2, + 2, + 2, + 1, + 2, + 0, + 2, + 2, + 2, + 2, + 2, + 4, + 1, + 1, + 13, + 0, + 5, + 0, + 0, + 0, + 2, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 5, + 2, + 1, + 0, + 2, + 4, + 3, + 2, + 5, + 0, + 1, + 0, + 0, + 0, + 0, + 6, + 1, + 0, + 3, + 0, + 0, + 0, + 2, + 1, + 3, + 1, + 3, + 2, + 1, + 5, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 12, + 16, + 12, + 13, + 20, + 15, + 13, + 17, + 16, + 9, + 10, + 25, + 13, + 12, + 14, + 22, + 24, + 13, + 12, + 17, + 30, + 11, + 15, + 20, + 22, + 10, + 8, + 13, + 10, + 25, + 14, + 56, + 13, + 13, + 11, + 8, + 23, + 20, + 12, + 15, + 11, + 23, + 21, + 22, + 16, + 16, + 14, + 13, + 26, + 27, + 11, + 16, + 18, + 13, + 18, + 17, + 14, + 18, + 21, + 20, + 14, + 19, + 7, + 15, + 8, + 6, + 15, + 15, + 14, + 22, + 17, + 14, + 12, + 15, + 9, + 17, + 23, + 9, + 18, + 11, + 17, + 19, + 12, + 27, + 13, + 15, + 15, + 18, + 14, + 14, + 12, + 16, + 11, + 18, + 11, + 14, + 11, + 14, + 11, + 42, + 12, + 18, + 27, + 24, + 21, + 15, + 11, + 41, + 18, + 17, + 10, + 16, + 17, + 9, + 12, + 17, + 9, + 11, + 11, + 12, + 9, + 6, + 24, + 14, + 10, + 31, + 14, + 11, + 22, + 16, + 17, + 14, + 12, + 15, + 12, + 12, + 15, + 12, + 17, + 13, + 16, + 10, + 14, + 28, + 19, + 11, + 13, + 20, + 9, + 14, + 13, + 10, + 13, + 12, + 21, + 19, + 12, + 13, + 12, + 10, + 13, + 11, + 14, + 15, + 10, + 20, + 20, + 15, + 16, + 21, + 28, + 13, + 10, + 18, + 9, + 15, + 14, + 14, + 37, + 11, + 20, + 18, + 21, + 14, + 14, + 16, + 16, + 20, + 13, + 11, + 15, + 21, + 11, + 9, + 19, + 49, + 17, + 14, + 14, + 18, + 13, + 16, + 5, + 17, + 12, + 18, + 22, + 18, + 14, + 13, + 12, + 9, + 14, + 14, + 18, + 12, + 8, + 22, + 16, + 15, + 11, + 44, + 19, + 20, + 13, + 11, + 16, + 15, + 16, + 13, + 13, + 24, + 12, + 12, + 15, + 25, + 12, + 15, + 11, + 18, + 15, + 14, + 20, + 8, + 17, + 8, + 20, + 12, + 16, + 7, + 10, + 13, + 9, + 15, + 13, + 11, + 18, + 22, + 12, + 15, + 9, + 15, + 12, + 23, + 13, + 11, + 16, + 6, + 16, + 16, + 11, + 15, + 9, + 8, + 20, + 20, + 10, + 18, + 13, + 18, + 8, + 20, + 11, + 12, + 24, + 5, + 12, + 11, + 13, + 14, + 12, + 11, + 18, + 20, + 28, + 20, + 22, + 8, + 19, + 11, + 15, + 13, + 11, + 14, + 16, + 36, + 15, + 17, + 16, + 23, + 26, + 12, + 28, + 21, + 23, + 18, + 19, + 17, + 20, + 26, + 17, + 10, + 12, + 17, + 10, + 18, + 6, + 15, + 65, + 17, + 17, + 13, + 24, + 12, + 22, + 33, + 14, + 20, + 12, + 13, + 26, + 20, + 14, + 15, + 17, + 13, + 15, + 10, + 16, + 15, + 15, + 11, + 14, + 11, + 6, + 14, + 24, + 13, + 15, + 21, + 13, + 8, + 18, + 22, + 16, + 13, + 11, + 9, + 18, + 14, + 8, + 18, + 14, + 8, + 14, + 17, + 16, + 8, + 16, + 15, + 29, + 17, + 12, + 16, + 24, + 17, + 11, + 13, + 10, + 16, + 11, + 14, + 14, + 23, + 18, + 11, + 13, + 7, + 14, + 15, + 0, + 1, + 1, + 5, + 5, + 1, + 1, + 0, + 1, + 1, + 3, + 0, + 1, + 0, + 1, + 7, + 2, + 0, + 1, + 2, + 3, + 3, + 0, + 1, + 1, + 0, + 3, + 0, + 1, + 3, + 0, + 5, + 1, + 2, + 1, + 2, + 0, + 4, + 0, + 1, + 2, + 0, + 3, + 2, + 0, + 3, + 1, + 0, + 2, + 0, + 0, + 0, + 3, + 4, + 0, + 0, + 2, + 0, + 0, + 1, + 1, + 0, + 2, + 0, + 0, + 1, + 1, + 1, + 6, + 0, + 0, + 1, + 7, + 0, + 3, + 0, + 0, + 4, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 2, + 0, + 0, + 2, + 2, + 0, + 0, + 0, + 11, + 1, + 2, + 0, + 1, + 10, + 27, + 14, + 23, + 13, + 12, + 17, + 13, + 14, + 17, + 42, + 13, + 13, + 13, + 10, + 29, + 25, + 11, + 15, + 13, + 16, + 15, + 13, + 17, + 8, + 31, + 11, + 15, + 15, + 18, + 21, + 12, + 21, + 10, + 17, + 12, + 10, + 16, + 12, + 18, + 22, + 13, + 11, + 18, + 21, + 8, + 15, + 13, + 9, + 19, + 7, + 12, + 19, + 15, + 10, + 16, + 17, + 12, + 15, + 15, + 11, + 11, + 14, + 28, + 11, + 14, + 16, + 15, + 36, + 22, + 22, + 12, + 13, + 10, + 13, + 14, + 7, + 25, + 12, + 27, + 18, + 16, + 12, + 21, + 21, + 13, + 12, + 6, + 13, + 13, + 9, + 20, + 10, + 7, + 23, + 14, + 15, + 19, + 21, + 14, + 16, + 10, + 41, + 21, + 17, + 45, + 18, + 22, + 24, + 11, + 13, + 13, + 13, + 15, + 11, + 19, + 15, + 10, + 7, + 12, + 13, + 16, + 18, + 14, + 16, + 20, + 17, + 24, + 14, + 31, + 9, + 11, + 16, + 22, + 12, + 13, + 14, + 8, + 14, + 12, + 10, + 20, + 9, + 12, + 10, + 9, + 46, + 14, + 16, + 33, + 20, + 20, + 16, + 14, + 14, + 18, + 20, + 10, + 16, + 22, + 16, + 45, + 12, + 20, + 10, + 20, + 11, + 36, + 8, + 10, + 33, + 18, + 29, + 13, + 26, + 26, + 17, + 10, + 10, + 20, + 16, + 11, + 18, + 18, + 13, + 12, + 18, + 17, + 23, + 20, + 18, + 21, + 20, + 15, + 10, + 12, + 12, + 23, + 15, + 17, + 2, + 2, + 0, + 2, + 0, + 2, + 3, + 0, + 1, + 0, + 2, + 0, + 2, + 1, + 0, + 4, + 0, + 0, + 2, + 4, + 0, + 2, + 1, + 0, + 0, + 0, + 1, + 0, + 4, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 2, + 1, + 2, + 1, + 0, + 1, + 0, + 0, + 3, + 0, + 11, + 0, + 1, + 0, + 3, + 4, + 1, + 0, + 0, + 0, + 2, + 1, + 0, + 2, + 2, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 6, + 2, + 2, + 0, + 0, + 5, + 2, + 1, + 0, + 15, + 4, + 0, + 1, + 0, + 0, + 2, + 0, + 1, + 3, + 0, + 2, + 0, + 0, + 1, + 2, + 0, + 1, + 2, + 1, + 12, + 0, + 1, + 3, + 0, + 0, + 1, + 2, + 0, + 2, + 2, + 0, + 3, + 0, + 1, + 0, + 0, + 2, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 2, + 2, + 0, + 0, + 0, + 1, + 3, + 0, + 3, + 0, + 0, + 4, + 1, + 2, + 1, + 1, + 0, + 0, + 1, + 2, + 0, + 2, + 0, + 0, + 1, + 3, + 0, + 3, + 1, + 2, + 0, + 2, + 1, + 0, + 1, + 4, + 0, + 0, + 0, + 0, + 2, + 4, + 0, + 0, + 3, + 1, + 5, + 2, + 1, + 0, + 0, + 0, + 0, + 0, + 2, + 2, + 1, + 1, + 0, + 1, + 1, + 0, + 2, + 3, + 1, + 1, + 2, + 0, + 0, + 0, + 26, + 0, + 2, + 2, + 0, + 6, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 2, + 1, + 33, + 1, + 1, + 1, + 2, + 0, + 1, + 0, + 2, + 1, + 1, + 6, + 1, + 7, + 2, + 1, + 2, + 0, + 2, + 1, + 0, + 1, + 0, + 2, + 0, + 3, + 1, + 2, + 0, + 0, + 0, + 0, + 2, + 2, + 10, + 0, + 0, + 1, + 0, + 10, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 2, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 3, + 2, + 0, + 3, + 3, + 6, + 0, + 0, + 0, + 0, + 2, + 0, + 0, + 2, + 2, + 0, + 0, + 5, + 4, + 1, + 1, + 3, + 5, + 1, + 1, + 2, + 2, + 2, + 0, + 3, + 0, + 3, + 0, + 2, + 1, + 0, + 0, + 2, + 2, + 0, + 1, + 2, + 13, + 0, + 1, + 1, + 0, + 0, + 5, + 1, + 9, + 5, + 0, + 0, + 0, + 1, + 0, + 0, + 3, + 0, + 1, + 4, + 3, + 2, + 0, + 4, + 2, + 0, + 0, + 3, + 0, + 1, + 0, + 1, + 1, + 2, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 2, + 1, + 2, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 7, + 4, + 1, + 11, + 0, + 0, + 0, + 1, + 0, + 3, + 0, + 1, + 0, + 0, + 0, + 5, + 1, + 0, + 6, + 1, + 1, + 1, + 6, + 0, + 2, + 0, + 4, + 7, + 1, + 5, + 0, + 24, + 0, + 0, + 0, + 1, + 1, + 0, + 2, + 0, + 0, + 3, + 1, + 2, + 1, + 0, + 0, + 3, + 0, + 0, + 1, + 1, + 2, + 1, + 0, + 1, + 1, + 2, + 2, + 2, + 3, + 0, + 2, + 1, + 0, + 0, + 2, + 1, + 4, + 3, + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 0, + 0, + 2, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 4, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 2, + 25, + 0, + 3, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 3, + 0, + 1, + 0, + 1, + 0, + 4, + 3, + 5, + 0, + 4, + 2, + 10, + 1, + 1, + 1, + 3, + 0, + 2, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 2, + 1, + 0, + 1, + 0, + 1, + 4, + 1, + 0, + 1, + 0, + 0, + 2, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 2, + 0, + 1, + 2, + 0, + 3, + 5, + 2, + 1, + 1, + 1, + 0, + 0, + 0, + 2, + 2, + 0, + 0, + 0, + 10, + 2, + 1, + 4, + 0, + 3, + 0, + 1, + 0, + 2, + 0, + 0, + 2, + 6, + 3, + 2, + 0, + 1, + 0, + 2, + 2, + 1, + 3, + 2, + 1, + 1, + 0, + 0, + 2, + 0, + 1, + 1, + 1, + 2, + 3, + 0, + 2, + 0, + 0, + 0, + 0, + 4, + 4, + 0, + 0, + 0, + 1, + 0, + 6, + 2, + 0, + 4, + 1, + 2, + 3, + 1, + 4, + 0, + 1, + 0, + 0, + 3, + 1, + 2, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 3, + 3, + 4, + 0, + 0, + 3, + 3, + 1, + 8, + 1, + 6, + 0, + 1, + 1, + 0, + 2, + 0, + 5, + 6, + 2, + 6, + 0, + 8, + 0, + 1, + 1, + 1, + 2, + 2, + 1, + 1, + 1, + 4, + 2, + 2, + 0, + 0, + 0, + 0, + 3, + 4, + 4, + 0, + 0, + 0, + 0, + 2, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 1, + 2, + 2, + 3, + 0, + 1, + 9, + 1, + 3, + 0, + 1, + 3, + 0, + 2, + 0, + 0, + 0, + 1, + 2, + 2, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 2, + 3, + 1, + 0, + 1, + 2, + 0, + 1, + 1, + 2, + 0, + 4, + 2, + 0, + 0, + 3, + 3, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 4, + 0, + 1, + 1, + 2, + 1, + 1, + 2, + 0, + 0, + 1, + 0, + 0, + 5, + 0, + 1, + 0, + 5, + 1, + 2, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 4, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 7, + 1, + 0, + 0, + 0, + 3, + 2, + 0, + 3, + 2, + 0, + 1, + 1, + 2, + 0, + 1, + 1, + 2, + 15, + 14, + 25, + 10, + 23, + 15, + 7, + 11, + 15, + 16, + 19, + 14, + 21, + 14, + 23, + 12, + 20, + 19, + 9, + 21, + 16, + 3, + 12, + 12, + 20, + 14, + 14, + 6, + 11, + 24, + 14, + 16, + 12, + 15, + 13, + 16, + 14, + 14, + 16, + 8, + 16, + 16, + 18, + 13, + 19, + 13, + 10, + 23, + 7, + 7, + 19, + 12, + 11, + 21, + 14, + 15, + 14, + 17, + 14, + 26, + 13, + 18, + 21, + 8, + 11, + 23, + 11, + 21, + 18, + 9, + 13, + 13, + 20, + 26, + 16, + 12, + 9, + 11, + 13, + 29, + 0, + 1, + 2, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 2, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 2, + 2, + 0, + 1, + 2, + 1, + 2, + 0, + 0, + 2, + 5, + 4, + 0, + 0, + 1, + 2, + 0, + 3, + 3, + 2, + 1, + 2, + 1, + 0, + 0, + 0, + 3, + 6, + 1, + 0, + 0, + 1, + 0, + 3, + 0, + 2, + 1, + 1, + 3, + 0, + 0, + 2, + 0, + 0, + 2, + 0, + 0, + 0, + 0, + 1, + 1, + 2, + 0, + 0, + 4, + 0, + 0, + 4, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 3, + 0, + 3, + 3, + 1, + 1, + 2, + 0, + 0, + 4, + 0, + 1, + 0, + 0, + 4, + 6, + 2, + 2, + 1, + 4, + 0, + 0, + 3, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 2, + 2, + 0, + 1, + 1, + 0, + 4, + 0, + 3, + 1, + 1, + 0, + 2, + 1, + 3, + 0, + 0, + 4, + 1, + 4, + 0, + 1, + 1, + 0, + 2, + 0, + 0, + 4, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 2, + 1, + 1, + 12, + 9, + 12, + 17, + 14, + 6, + 13, + 21, + 6, + 19, + 14, + 31, + 10, + 16, + 13, + 22, + 22, + 13, + 16, + 10, + 20, + 11, + 13, + 10, + 14, + 15, + 16, + 20, + 10, + 7, + 11, + 17, + 12, + 18, + 16, + 15, + 11, + 21, + 17, + 24, + 36, + 15, + 20, + 14, + 15, + 12, + 10, + 21, + 13, + 23, + 21, + 14, + 14, + 10, + 9, + 11, + 11, + 17, + 9, + 13, + 22, + 18, + 11, + 17, + 12, + 17, + 14, + 10, + 9, + 12, + 13, + 16, + 12, + 10, + 14, + 12, + 17, + 19, + 11, + 15, + 13, + 16, + 17, + 15, + 20, + 8, + 13, + 12, + 24, + 14, + 8, + 9, + 22, + 36, + 7, + 0, + 0, + 3, + 0, + 4, + 0, + 0, + 1, + 1, + 1, + 2, + 0, + 1, + 1, + 1, + 0, + 0, + 5, + 1, + 1, + 3, + 0, + 2, + 1, + 0, + 1, + 0, + 0, + 1, + 2, + 3, + 0, + 0, + 1, + 1, + 1, + 2, + 1, + 0, + 0, + 0, + 0, + 2, + 2, + 1, + 0, + 0, + 0, + 0, + 2, + 1, + 0, + 4, + 2, + 0, + 2, + 1, + 1, + 1, + 1, + 0, + 0, + 2, + 6, + 1, + 0, + 2, + 1, + 0, + 9, + 1, + 2, + 2, + 2, + 1, + 0, + 2, + 0, + 3, + 3, + 2, + 0, + 15, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 2, + 0, + 0, + 0, + 0, + 4, + 2, + 1, + 0, + 6, + 27, + 18, + 39, + 13, + 16, + 9, + 15, + 26, + 9, + 28, + 17, + 21, + 6, + 9, + 14, + 20, + 8, + 20, + 12, + 21, + 16, + 23, + 33, + 14, + 20, + 23, + 18, + 15, + 16, + 22, + 14, + 27, + 9, + 20, + 18, + 12, + 16, + 21, + 17, + 12, + 17, + 8, + 16, + 16, + 18, + 9, + 11, + 16, + 11, + 16, + 14, + 12, + 17, + 10, + 12, + 20, + 10, + 27, + 8, + 11, + 14, + 15, + 24, + 19, + 17, + 14, + 7, + 11, + 16, + 19, + 10, + 14, + 18, + 11, + 15, + 20, + 17, + 12, + 18, + 12, + 8, + 8, + 13, + 25, + 12, + 11, + 19, + 21, + 13, + 14, + 1, + 2, + 1, + 1, + 3, + 1, + 1, + 3, + 2, + 1, + 0, + 1, + 6, + 1, + 1, + 0, + 4, + 0, + 0, + 1, + 6, + 0, + 0, + 7, + 1, + 3, + 2, + 0, + 3, + 2, + 2, + 1, + 3, + 1, + 1, + 1, + 2, + 0, + 0, + 1, + 1, + 2, + 1, + 2, + 0, + 2, + 2, + 0, + 1, + 7, + 1, + 1, + 3, + 4, + 2, + 1, + 0, + 0, + 0, + 1, + 0, + 4, + 0, + 1, + 3, + 2, + 0, + 4, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 2, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 2, + 3, + 1, + 0, + 2, + 3, + 0, + 25, + 13, + 21, + 22, + 8, + 20, + 18, + 22, + 20, + 9, + 21, + 19, + 21, + 13, + 14, + 21, + 9, + 12, + 19, + 14, + 14, + 27, + 18, + 15, + 14, + 12, + 8, + 25, + 14, + 14, + 7, + 11, + 25, + 8, + 23, + 15, + 9, + 20, + 16, + 20, + 13, + 10, + 23, + 18, + 22, + 12, + 21, + 16, + 15, + 12, + 18, + 12, + 8, + 17, + 14, + 9, + 12, + 9, + 18, + 14, + 11, + 22, + 9, + 18, + 12, + 17, + 22, + 13, + 13, + 15, + 10, + 24, + 7, + 13, + 15, + 11, + 18, + 20, + 4, + 17, + 8, + 8, + 13, + 8, + 18, + 13, + 13, + 14, + 26, + 15, + 20, + 20, + 15, + 13, + 10, + 13, + 13, + 16, + 17, + 12, + 17, + 15, + 15, + 19, + 12, + 12, + 27, + 9, + 23, + 15, + 16, + 18, + 15, + 12, + 19, + 13, + 14, + 36, + 23, + 14, + 16, + 13, + 13, + 6, + 8, + 22, + 11, + 14, + 18, + 19, + 20, + 6, + 23, + 21, + 26, + 16, + 24, + 16, + 2, + 36, + 9, + 15, + 14, + 11, + 17, + 43, + 14, + 10, + 19, + 18, + 10, + 10, + 17, + 15, + 12, + 14, + 25, + 13, + 9, + 17, + 2, + 18, + 11, + 12, + 17, + 14, + 7, + 18, + 21, + 16, + 18, + 21, + 29, + 10, + 10, + 11, + 22, + 13, + 16, + 12, + 10, + 11, + 15, + 13, + 22, + 20, + 16, + 40, + 20, + 14, + 13, + 26, + 12, + 16, + 22, + 24, + 14, + 15, + 10, + 43, + 8, + 17, + 22, + 10, + 10, + 13, + 9, + 16, + 9, + 16, + 21, + 13, + 21, + 24, + 32, + 25, + 12, + 11, + 20, + 15, + 24, + 9, + 12, + 0, + 2, + 0, + 0, + 0, + 0, + 0, + 1, + 3, + 0, + 5, + 5, + 0, + 1, + 1, + 0, + 7, + 2, + 2, + 0, + 0, + 1, + 2, + 0, + 1, + 4, + 2, + 0, + 2, + 2, + 0, + 2, + 0, + 0, + 2, + 3, + 2, + 0, + 1, + 0, + 0, + 1, + 2, + 0, + 0, + 3, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 3, + 7, + 0, + 7, + 1, + 0, + 5, + 2, + 0, + 0, + 0, + 5, + 4, + 0, + 1, + 0, + 0, + 1, + 2, + 0, + 2, + 6, + 1, + 2, + 2, + 0, + 0, + 0, + 1, + 0, + 2, + 3, + 2, + 0, + 1, + 0, + 0, + 0, + 2, + 1, + 2, + 0, + 0, + 1, + 1, + 0, + 3, + 2, + 0, + 1, + 0, + 0, + 1, + 2, + 0, + 0, + 2, + 0, + 0, + 0, + 0, + 1, + 2, + 3, + 0, + 0, + 2, + 0, + 0, + 0, + 2, + 2, + 0, + 2, + 1, + 0, + 1, + 3, + 0, + 2, + 0, + 0, + 1, + 3, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 5, + 0, + 1, + 1, + 0, + 2, + 3, + 3, + 0, + 0, + 2, + 0, + 10, + 2, + 0, + 0, + 4, + 1, + 1, + 6, + 2, + 1, + 1, + 2, + 3, + 0, + 2, + 0, + 1, + 1, + 3, + 5, + 4, + 3, + 1, + 1, + 2, + 0, + 1, + 2, + 2, + 3, + 1, + 1, + 1, + 3, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 2, + 0, + 0, + 1, + 3, + 0, + 1, + 2, + 0, + 1, + 1, + 3, + 3, + 12, + 2, + 2, + 4, + 1, + 0, + 0, + 2, + 1, + 1, + 1, + 3, + 0, + 1, + 0, + 2, + 0, + 0, + 1, + 1, + 1, + 2, + 0, + 1, + 2, + 1, + 0, + 0, + 0, + 1, + 0, + 5, + 0, + 0, + 0, + 0, + 4, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 3, + 2, + 5, + 0, + 2, + 1, + 2, + 1, + 5, + 3, + 2, + 0, + 0, + 0, + 3, + 2, + 0, + 0, + 0, + 0, + 1, + 1, + 2, + 0, + 2, + 0, + 1, + 1, + 0, + 2, + 3, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 2, + 1, + 0, + 0, + 1, + 0, + 2, + 9, + 17, + 21, + 15, + 14, + 15, + 20, + 11, + 21, + 11, + 10, + 12, + 30, + 22, + 9, + 14, + 9, + 20, + 14, + 15, + 13, + 17, + 15, + 2, + 11, + 0, + 0, + 0, + 1, + 5, + 2, + 0, + 4, + 0, + 1, + 1, + 1, + 0, + 1, + 4, + 1, + 2, + 0, + 2, + 2, + 1, + 1, + 0, + 0, + 2, + 2, + 2, + 2, + 0, + 3, + 0, + 2, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 2, + 2, + 0, + 1, + 17, + 8, + 13, + 11, + 28, + 9, + 28, + 18, + 14, + 19, + 23, + 20, + 18, + 19, + 12, + 15, + 15, + 17, + 23, + 28, + 13, + 16, + 13, + 19, + 17, + 7, + 17, + 14, + 17, + 7, + 21, + 11, + 6, + 8, + 10, + 10, + 12, + 5, + 15, + 12, + 14, + 14, + 7, + 13, + 10, + 15, + 13, + 19, + 19, + 20, + 10, + 18, + 19, + 17, + 9, + 7, + 11, + 2, + 0, + 0, + 3, + 0, + 2, + 8, + 1, + 0, + 0, + 4, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 2, + 6, + 2, + 2, + 2, + 0, + 2, + 0, + 1, + 1, + 2, + 8, + 2, + 0, + 0, + 1, + 0, + 1, + 0, + 3, + 1, + 1, + 0, + 4, + 0, + 1, + 0, + 1, + 1, + 0, + 3, + 0, + 1, + 3, + 0, + 1, + 1, + 0, + 1, + 2, + 0, + 3, + 0, + 0, + 4, + 1, + 3, + 4, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 0, + 0, + 0, + 0, + 1, + 15, + 11, + 18, + 17, + 26, + 21, + 16, + 15, + 14, + 18, + 23, + 10, + 14, + 12, + 16, + 20, + 13, + 13, + 13, + 16, + 14, + 9, + 16, + 14, + 12, + 13, + 19, + 19, + 17, + 6, + 13, + 11, + 15, + 14, + 14, + 15, + 12, + 12, + 15, + 19, + 12, + 11, + 14, + 21, + 15, + 17, + 14, + 15, + 37, + 6, + 9, + 5, + 16, + 9, + 7, + 15, + 19, + 13, + 14, + 16, + 14, + 12, + 15, + 8, + 8, + 11, + 13, + 13, + 16, + 11, + 8, + 13, + 9, + 22, + 0, + 2, + 0, + 1, + 0, + 2, + 0, + 2, + 0, + 0, + 3, + 0, + 1, + 1, + 2, + 0, + 2, + 0, + 1, + 4, + 10, + 2, + 0, + 1, + 3, + 4, + 2, + 3, + 1, + 0, + 2, + 6, + 0, + 4, + 2, + 0, + 1, + 3, + 0, + 1, + 1, + 0, + 2, + 2, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 2, + 0, + 2, + 0, + 0, + 0, + 0, + 15, + 0, + 0, + 1, + 0, + 16, + 0, + 5, + 2, + 1, + 2, + 0, + 1, + 3, + 1, + 4, + 1, + 1, + 2, + 2, + 2, + 2, + 0, + 2, + 0, + 0, + 0, + 1, + 1, + 3, + 0, + 2, + 0, + 5, + 1, + 4, + 2, + 1, + 1, + 2, + 0, + 0, + 1, + 1, + 1, + 2, + 5, + 1, + 3, + 0, + 0, + 2, + 7, + 5, + 2, + 4, + 3, + 0, + 1, + 1, + 3, + 1, + 0, + 1, + 2, + 1, + 0, + 14, + 0, + 2, + 4, + 0, + 1, + 2, + 0, + 1, + 1, + 2, + 0, + 0, + 0, + 2, + 0, + 2, + 5, + 1, + 2, + 0, + 1, + 3, + 2, + 0, + 4, + 2, + 1, + 0, + 1, + 1, + 2, + 1, + 0, + 0, + 0, + 1, + 1, + 2, + 2, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 3, + 1, + 3, + 0, + 4, + 18, + 11, + 9, + 15, + 21, + 30, + 13, + 7, + 19, + 13, + 10, + 0, + 4, + 2, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 2, + 0, + 1, + 2, + 0, + 0, + 4, + 3, + 26, + 0, + 0, + 2, + 1, + 0, + 0, + 1, + 1, + 0, + 13, + 11, + 12, + 22, + 16, + 15, + 20, + 7, + 7, + 12, + 10, + 20, + 16, + 13, + 0, + 3, + 5, + 4, + 0, + 1, + 7, + 1, + 1, + 1, + 5, + 2, + 2, + 1, + 3, + 3, + 2, + 0, + 5, + 0, + 0, + 1, + 3, + 2, + 2, + 0, + 0, + 1, + 0, + 1, + 1, + 2, + 0, + 0, + 0, + 4, + 2, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 14, + 7, + 30, + 12, + 19, + 51, + 13, + 22, + 18, + 13, + 16, + 0, + 2, + 1, + 1, + 0, + 0, + 3, + 0, + 5, + 1, + 3, + 0, + 21, + 18, + 9, + 25, + 14, + 9, + 15, + 21, + 15, + 30, + 13, + 31, + 13, + 12, + 2, + 0, + 2, + 0, + 4, + 1, + 0, + 1, + 0, + 0, + 0, + 2, + 10, + 3, + 1, + 1, + 1, + 2, + 1, + 1, + 1, + 1, + 0, + 2, + 1, + 0, + 0, + 2, + 0, + 2, + 0, + 0, + 2, + 1, + 0, + 1, + 0, + 3, + 2, + 0, + 11, + 12, + 16, + 11, + 9, + 18, + 22, + 13, + 19, + 9, + 20, + 25, + 15, + 20, + 9, + 118, + 11, + 15, + 7, + 25, + 16, + 13, + 11, + 9, + 19, + 17, + 13, + 13, + 19, + 14, + 13, + 21, + 12, + 11, + 18, + 18, + 17, + 12, + 12, + 11, + 15, + 13, + 9, + 16, + 13, + 15, + 12, + 20, + 12, + 10, + 3, + 0, + 0, + 3, + 1, + 3, + 1, + 1, + 3, + 3, + 1, + 1, + 0, + 1, + 2, + 0, + 8, + 0, + 1, + 7, + 28, + 20, + 5, + 15, + 20, + 19, + 20, + 19, + 16, + 20, + 6, + 0, + 2, + 1, + 1, + 0, + 2, + 0, + 0, + 1, + 3, + 0, + 0, + 1, + 0, + 0, + 3, + 3, + 1, + 0, + 0, + 1, + 2, + 0, + 1, + 0, + 4, + 1, + 2, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 2, + 5, + 0, + 3, + 2, + 4, + 1, + 1, + 0, + 11, + 7, + 16, + 12, + 12, + 10, + 20, + 13, + 10, + 17, + 0, + 0, + 1, + 4, + 2, + 0, + 2, + 1, + 2, + 3, + 24, + 13, + 11, + 15, + 20, + 21, + 19, + 11, + 17, + 19, + 0, + 0, + 6, + 0, + 2, + 3, + 0, + 2, + 8, + 4, + 2, + 3, + 1, + 0, + 0, + 1, + 1, + 1, + 2, + 1 + ], + "status": "normal", + "min_mw": 4.95, + "type": "CatalogNumberTestResult" +} \ No newline at end of file diff --git a/tests/artifacts/example_csep2_forecasts/Results/catalog_s_test.json b/tests/artifacts/example_csep2_forecasts/Results/catalog_s_test.json new file mode 100644 index 00000000..4c38cb8a --- /dev/null +++ b/tests/artifacts/example_csep2_forecasts/Results/catalog_s_test.json @@ -0,0 +1,7411 @@ +{ + "name": "Catalog S-Test", + "sim_name": "ucerf3-landers", + "obs_name": null, + "obs_catalog_repr": "\n Name: None\n\n Start Date: 1992-06-28 12:00:45+00:00\n End Date: 1992-07-24 18:14:36.250000+00:00\n\n Latitude: (33.901, 36.705)\n Longitude: (-118.067, -116.285)\n\n Min Mw: 4.95\n Max Mw: 6.3\n\n Event Count: 19\n ", + "quantile": [ + 0.6355645706558486, + 0.36443542934415146 + ], + "observed_statistic": -5.881172204660409, + "test_distribution": [ + -5.583732296983384, + -7.28391892334828, + -5.046778761701508, + -5.287121593787302, + -5.287121593787302, + -4.678183739039838, + -7.995171794889512, + -2.4801314448301883, + -9.604609707323613, + -6.193238754996022, + -10.990904068443502, + -8.688318975449457, + -7.75568867374879, + -7.176336069800745, + -5.615625660759338, + -10.990904068443502, + -5.30874934812278, + -8.572763114967763, + -10.990904068443502, + -8.399394531139443, + -6.311140190069671, + -5.132179703569568, + -4.826955870751996, + -4.826955870751996, + -4.069245884292374, + -8.779868003605275, + -7.048239448806907, + -4.204187117838422, + -10.64433047816353, + -4.686455266021522, + -4.675546066921168, + -6.533311917400136, + -10.990904068443502, + -5.727328733660759, + -8.428922078741873, + -6.406500891187871, + -9.604609707323613, + -7.289373522898457, + -7.2509720028609905, + -4.204187117838422, + -6.687387120735489, + -6.8965595062214025, + -5.1375551302269, + -9.604609707323613, + -8.978228223075927, + -7.289373522898457, + -7.445865650555458, + -4.069245884292374, + -10.990904068443502, + -4.6245044798795885, + -4.069245884292374, + -10.990904068443502, + -10.990904068443502, + -4.96745647548247, + -4.790975361144749, + -4.96745647548247, + -7.379986155799278, + -4.204187117838422, + -6.832020985083831, + -8.903710433495684, + -4.136716501065398, + -6.404553434312054, + -4.204187117838422, + -5.291647745484103, + -8.507763001480216, + -4.316326356350655, + -7.530074976367938, + -10.297756887883558, + -10.990904068443502, + -7.151972318104397, + -9.604609707323613, + -4.99196750649682, + -7.647973594909324, + -4.487825269830353, + -6.798284484607266, + -5.583732296983384, + -7.995171794889512, + -7.266845619583048, + -4.796429960694926, + -9.072705838387483, + -8.3757913513612, + -8.157690724387287, + -6.454325634839784, + -6.69204065364563, + -4.204187117838422, + -5.129639181952276, + -5.583732296983384, + -5.345457170800265, + -6.930461057897084, + -7.956691274321448, + -9.199144599215447, + -4.977838992928279, + -7.096926137542816, + -5.817789385021679, + -5.287121593787302, + -4.675546066921168, + -8.184340015249468, + -9.892291779775393, + -4.530606695394598, + -6.071662749839269, + -10.06670782769691, + -7.166057756587746, + -4.686455266021522, + -4.826955870751996, + -7.772028243575302, + -8.50063947704515, + -5.615625660759338, + -4.686455266021522, + -8.911462526763668, + -6.889115199974527, + -7.35185392221307, + -8.413593827794008, + -9.381466156009402, + -9.199144599215447, + -4.906404655368331, + -8.425954710981966, + -5.7979472175532925, + -5.724616020045826, + -5.583732296983384, + -10.990904068443502, + -7.330309790073764, + -9.146464341386535, + -5.070084513453876, + -4.069245884292374, + -6.070923142615378, + -5.615625660759338, + -10.990904068443502, + -7.052774627291889, + -5.550373312029912, + -4.204187117838422, + -6.937345333068308, + -4.204187117838422, + -5.01002956331305, + -10.990904068443502, + -5.287121593787302, + -7.322743955475737, + -10.990904068443502, + -10.297756887883558, + -5.345457170800265, + -6.372997484468896, + -8.425954710981966, + -4.686455266021522, + -7.950405228871191, + -9.604609707323613, + -5.8396476544151, + -10.990904068443502, + -4.069245884292374, + -9.604609707323613, + -4.686455266021522, + -9.199144599215447, + -4.204187117838422, + -4.826489090637879, + -4.675546066921168, + -6.826195676473844, + -9.199144599215447, + -4.439418281350517, + -4.5980773121676215, + -7.048239448806907, + -4.083464389043509, + -8.697153455698647, + -6.150107458132328, + -4.069245884292374, + -7.399348217571863, + -5.278935037602304, + -5.324547035160646, + -4.518351179887421, + -5.096763124577817, + -7.33465411460261, + -9.892291779775393, + -8.218315346203722, + -10.990904068443502, + -9.748450743549503, + -5.583732296983384, + -5.814754335869674, + -4.069245884292374, + -5.391105405676072, + -9.892291779775393, + -7.732807530422021, + -4.99196750649682, + -5.418750036265738, + -8.030801615448878, + -5.287121593787302, + -9.892291779775393, + -8.425954710981966, + -4.906404655368331, + -10.990904068443502, + -8.100532310547338, + -10.990904068443502, + -6.0782491827074505, + -4.906404655368331, + -8.511835279486405, + -9.199144599215447, + -9.381466156009402, + -4.069245884292374, + -9.381466156009402, + -4.680321970489895, + -4.782778328192165, + -5.287121593787302, + -7.812850238095558, + -4.204187117838422, + -7.289373522898457, + -8.807747293528404, + -7.658699558268299, + -7.889940697078052, + -5.998313179336926, + -9.892291779775393, + -10.990904068443502, + -4.790975361144749, + -8.983088204123158, + -6.469115491394462, + -7.4818538452550065, + -4.96745647548247, + -4.069245884292374, + -7.204652575933311, + -8.74099923327837, + -6.701665858526935, + -8.666389728603457, + -7.49210607695254, + -4.445321191929972, + -9.636878967892397, + -4.069245884292374, + -4.204187117838422, + -6.548252811953186, + -8.793679491107284, + -9.604609707323613, + -4.675546066921168, + -10.297756887883558, + -7.399348217571863, + -7.732807530422021, + -4.96745647548247, + -4.99196750649682, + -10.297756887883558, + -4.99196750649682, + -8.505997418655502, + -4.906404655368331, + -8.607363695682544, + -4.069245884292374, + -6.143195405583805, + -5.156456823141367, + -8.593008795645133, + -8.542485896811272, + -8.793679491107284, + -9.892291779775393, + -9.892291779775393, + -10.297756887883558, + -6.05524159396873, + -4.069245884292374, + -8.093970709999779, + -5.168712338648543, + -7.946381630720079, + -4.833756786708994, + -6.601572737517973, + -8.911462526763668, + -5.287121593787302, + -6.070923142615378, + -6.515401173759795, + -8.793679491107284, + -2.885776850043757, + -3.4913759322232547, + -4.3209849486782925, + -2.757086856269773, + -2.9669399006130184, + -2.7649590926962424, + -4.714757296360956, + -4.8381241643116, + -3.4024223064202417, + -4.620936993346764, + -4.5566781304576685, + -3.8818076536056085, + -3.1137763436347323, + -5.988661880096596, + -4.4527192071355435, + -3.3755543664178136, + -2.90367068331899, + -3.722611186500226, + -4.167279948718392, + -3.674049328369522, + -3.573955866744305, + -4.033746917936719, + -2.945695662826504, + -2.9337124794779785, + -3.125859531802619, + -3.5503594244313903, + -3.6191206603588273, + -3.2256432576081067, + -2.8127120041123606, + -2.656906111968424, + -3.220637645068292, + -4.512075676079019, + -3.730725090928121, + -3.6553550383223268, + -2.581654101127897, + -4.691786470373435, + -5.061269962151375, + -3.650368891737497, + -2.4663279571998626, + -3.1159357412751167, + -3.107049930496015, + -2.7029337026431657, + -2.680103715943614, + -3.3302411473073494, + -2.928381884731077, + -4.346986464564575, + -3.2717811482150894, + -2.9469091013456366, + -3.279680539868776, + -2.4104173685541537, + -2.772589955771832, + -3.2345842364803232, + -3.576438393965695, + -4.067442816289134, + -3.2134177155569392, + -3.0644036190075723, + -3.359635296522378, + -3.986498825027388, + -2.6004197245877916, + -4.059117181574747, + -3.3517348285710145, + -4.530669215066512, + -4.056664497323928, + -3.966693123326788, + -4.470333919490026, + -3.5488151128232692, + -3.5510742145611025, + -3.5501506314608493, + -3.41437863036117, + -5.114274646013103, + -3.243891737080113, + -4.0140210380605374, + -3.679004898023362, + -3.533731658874696, + -3.076885838102799, + -2.9626739418893124, + -3.8521067055214555, + -3.418696017181977, + -2.5942408095191953, + -4.83458807904836, + -5.20467147131389, + -3.6985843712684656, + -4.088298740486444, + -3.8534749532258563, + -4.064852468282332, + -5.584749917524273, + -4.504856564647097, + -2.962623009102585, + -2.8877359806409726, + -3.3408685733523726, + -2.242099376631837, + -3.5748948061625128, + -3.2730591467172543, + -4.118655481650456, + -3.1172776102676205, + -2.9624143084094263, + -5.092178858032283, + -3.646767044097286, + -4.262996248761953, + -4.044067846309065, + -8.351846738828245, + -4.96745647548247, + -8.282853867341293, + -10.990904068443502, + -8.680413466577017, + -4.99196750649682, + -4.204187117838422, + -10.297756887883558, + -4.675546066921168, + -5.583732296983384, + -5.615625660759338, + -8.793679491107284, + -5.345457170800265, + -10.990904068443502, + -5.583732296983384, + -7.525168165643776, + -5.571244529792558, + -4.069245884292374, + -8.987148343642115, + -9.892291779775393, + -9.381466156009402, + -6.963092076769551, + -7.210863835932589, + -9.892291779775393, + -7.363461663404834, + -10.162601851847503, + -4.204187117838422, + -9.199144599215447, + -8.911462526763668, + -4.204187117838422, + -6.568160743491153, + -4.682818866321404, + -6.2585678360702985, + -8.425954710981966, + -4.675546066921168, + -10.111218291905084, + -6.1951135228467615, + -9.892291779775393, + -10.297756887883558, + -6.075284374279251, + -4.678183739039838, + -5.615625660759338, + -8.505997418655502, + -4.069245884292374, + -4.368649414689073, + -10.990904068443502, + -9.892291779775393, + -5.661143317134932, + -4.906404655368331, + -7.556916863958357, + -6.365931255159232, + -5.45137362727332, + -6.187280543700582, + -8.351846738828245, + -7.02959228133486, + -10.297756887883558, + -4.96745647548247, + -4.906404655368331, + -7.302024614329566, + -4.136716501065398, + -10.990904068443502, + -4.906404655368331, + -9.604609707323613, + -4.069245884292374, + -4.204187117838422, + -8.351846738828245, + -4.069245884292374, + -4.96745647548247, + -4.99196750649682, + -5.2610151580638345, + -9.526666357095609, + -5.985003376195941, + -6.634195241753911, + -9.636878967892397, + -4.069245884292374, + -4.204187117838422, + -4.204187117838422, + -6.116537966622943, + -9.381466156009402, + -4.36130676753267, + -4.069245884292374, + -8.509654139858178, + -10.990904068443502, + -8.314209370354316, + -4.99196750649682, + -4.069245884292374, + -4.204187117838422, + -5.345457170800265, + -6.075797186377137, + -8.119402474538761, + -7.469143227420212, + -9.636878967892397, + -7.863366870804625, + -7.445865650555458, + -8.394425642998398, + -9.04499391938819, + -4.686455266021522, + -8.549503107150318, + -10.297756887883558, + -5.959347569818136, + -10.990904068443502, + -4.204187117838422, + -9.04499391938819, + -4.944484363786127, + -4.906404655368331, + -10.990904068443502, + -6.489800160401483, + -4.627351731676345, + -9.199144599215447, + -6.378782429870915, + -5.583732296983384, + -5.2422012417874075, + -7.464543543827341, + -8.100532310547338, + -9.103250575064854, + -4.487825269830353, + -7.991435787470161, + -8.857970639745924, + -5.482902695256888, + -9.693700065720831, + -8.142892784029911, + -9.04499391938819, + -7.9695181145108025, + -7.761632063089963, + -4.069245884292374, + -8.793679491107284, + -8.546601502439893, + -3.4187288660320254, + -3.3684571187732324, + -3.3825208897860604, + -2.665956237382852, + -5.3807482627746435, + -4.761787637167236, + -3.3105307552467735, + -3.0503861129959033, + -3.230972406419369, + -5.308933487829852, + -2.7534024669391304, + -3.3286352554789236, + -3.463750449793558, + -2.987281243631492, + -3.328958990194402, + -3.027161135966321, + -2.7204657538612516, + -3.6325907005413165, + -2.3935746910124474, + -3.235333836139015, + -3.5966952479536407, + -3.844554309391382, + -3.9314701342387885, + -2.8062313072246132, + -3.0151103592782578, + -3.30373704162137, + -2.2589416009344907, + -3.3468719915238614, + -3.2767849943008476, + -2.649008331579334, + -3.7203375763074464, + -2.405948257030808, + -4.037985387009093, + -4.100854003412452, + -3.78640834853265, + -3.1331585717517485, + -4.0314370308593155, + -3.914959320424595, + -4.550586657292022, + -2.8127257588105876, + -3.4955068469029738, + -3.729327039705058, + -4.433965214421781, + -4.446583603482151, + -4.055717727959732, + -3.320576042280269, + -5.3310149736050425, + -2.943841728854266, + -3.626548477901666, + -3.381401430770886, + -3.1239864594287927, + -3.324043331677331, + -2.849023870041479, + -2.750318655763863, + -3.1830815878450878, + -2.6039264536040507, + -3.714983991308187, + -3.3926817726826575, + -3.597433167679352, + -2.996185421046315, + -4.042712593973331, + -2.649516447232295, + -3.1698355328017107, + -3.767611560532952, + -4.478648075205271, + -2.8225446349425956, + -3.7161269966624517, + -2.755062468373928, + -3.1481589280708535, + -3.0665868491489037, + -3.558075004920627, + -3.120798555167419, + -3.4992964397210433, + -2.833269039901773, + -3.226020916188346, + -2.7597787778529543, + -2.8854962538614513, + -4.004041550065669, + -3.255429613048108, + -3.5458382495406897, + -2.32135397955635, + -3.6891031934841223, + -3.554174550490625, + -2.949396888619591, + -3.1085275436422237, + -2.47818521969185, + -3.61612963843154, + -3.523338473954519, + -4.700568414306441, + -3.6999201838629387, + -3.897004491745934, + -3.3866922943384763, + -3.4675132097112655, + -4.287739459130537, + -3.0810963025733242, + -4.299769782107865, + -2.6640721224512953, + -3.390540481666382, + -2.779244482624054, + -3.0738865072431465, + -4.96745647548247, + -6.880567983294877, + -10.990904068443502, + -8.708729972709586, + -7.94638163072008, + -8.692198928363966, + -3.480473512065496, + -4.204187117838422, + -10.297756887883558, + -4.675546066921168, + -5.941130250723205, + -8.762700159220861, + -7.737198331362035, + -4.204187117838422, + -9.604609707323613, + -4.193439083716914, + -7.255507181345973, + -9.83961152194648, + -6.960010749051809, + -4.99196750649682, + -4.675546066921168, + -7.125979266423451, + -9.480193009929213, + -8.167632244255122, + -10.990904068443502, + -9.171271143095174, + -8.688318975449457, + -10.297756887883558, + -9.051867015122435, + -4.069245884292374, + -4.686455266021522, + -7.991435787470161, + -4.204187117838422, + -9.748450743549503, + -4.675546066921168, + -4.906404655368331, + -5.814754335869674, + -4.204187117838422, + -4.760502114597626, + -7.162262671954408, + -4.875875783456165, + -5.440246177276016, + -9.199144599215447, + -6.965552377708353, + -4.069245884292374, + -7.429874127628932, + -9.892291779775393, + -7.750238919963417, + -6.414461304539242, + -4.069245884292374, + -10.297756887883558, + -9.381466156009402, + -4.5980773121676215, + -4.99196750649682, + -4.99196750649682, + -4.204187117838422, + -6.506960782379766, + -4.96745647548247, + -6.371565728490608, + -4.136716501065398, + -6.070923142615378, + -10.297756887883558, + -9.381466156009402, + -5.287121593787302, + -4.691975096652612, + -6.1951135228467615, + -4.615729886747353, + -10.297756887883558, + -9.199144599215447, + -5.724616020045826, + -8.351846738828245, + -7.2509720028609905, + -5.345457170800265, + -10.990904068443502, + -8.157690724387287, + -5.7979472175532925, + -10.990904068443502, + -4.136716501065398, + -4.675546066921168, + -6.2360418259345, + -8.793679491107284, + -10.990904068443502, + -10.990904068443502, + -7.644272051004944, + -8.425954710981966, + -5.615625660759338, + -6.0349874459272925, + -6.92289963513586, + -8.580763285640984, + -8.947651240512261, + -4.906404655368331, + -5.418750036265738, + -10.990904068443502, + -8.902470330864267, + -6.852396445206042, + -4.204187117838422, + -4.51233426010556, + -5.7979472175532925, + -5.179191616160041, + -9.892291779775393, + -6.618594523138742, + -9.199144599215447, + -6.124284112739017, + -8.282853867341293, + -4.686455266021522, + -10.186185112226452, + -9.604609707323611, + -10.990904068443502, + -10.990904068443502, + -7.486651477402363, + -7.531519950962816, + -9.892291779775393, + -5.814754335869674, + -5.287849901740103, + -4.668052945085772, + -10.297756887883558, + -9.892291779775393, + -7.176336069800745, + -9.892291779775393, + -8.911462526763668, + -10.186185112226452, + -10.990904068443502, + -8.911462526763668, + -8.182544767607359, + -4.681000666471345, + -10.990904068443502, + -9.04499391938819, + -6.545957455204037, + -6.027232093054344, + -9.381466156009402, + -7.162262671954408, + -10.64433047816353, + -4.069245884292374, + -4.906404655368331, + -4.518351179887421, + -5.0618312518841515, + -8.505997418655502, + -8.197279739243378, + -7.525168165643776, + -7.946381630720079, + -6.513696402874706, + -4.204187117838422, + -5.5063687362637666, + -7.698845561636403, + -4.629686220963378, + -9.381466156009402, + -4.906404655368331, + -4.9551088293954235, + -6.502267698711363, + -4.204187117838422, + -9.199144599215447, + -4.204187117838422, + -10.990904068443502, + -4.069245884292374, + -7.928089513633014, + -6.421734103939478, + -7.995171794889512, + -9.017884463131473, + -6.084889097419856, + -7.38612288747009, + -9.199144599215447, + -8.688318975449457, + -10.297756887883558, + -5.287121593787302, + -4.979567787160781, + -6.673971847544344, + -8.911462526763668, + -4.675546066921168, + -8.47026561429115, + -6.070923142615378, + -8.425954710981966, + -10.095024333829475, + -10.990904068443502, + -8.673174984398605, + -8.50063947704515, + -7.033960711015462, + -10.297756887883558, + -7.2509720028609905, + -9.992326643925507, + -10.297756887883558, + -4.069245884292374, + -4.906404655368331, + -9.892291779775393, + -10.436386323995546, + -5.615625660759338, + -5.345457170800265, + -4.204187117838422, + -6.666179683175148, + -4.227032885477386, + -3.6786257887514235, + -2.670388556101246, + -3.2677213233638938, + -2.8707386712023997, + -4.093721601254175, + -2.491593162228164, + -4.402248846241373, + -3.538328579532697, + -3.206600831827931, + -4.635107530722437, + -3.2340569127890535, + -3.010606557284846, + -3.0284100262952385, + -2.726288236797063, + -2.8002293374972065, + -6.873940981069611, + -3.225336022998752, + -3.142149078153781, + -3.7573838784875426, + -2.7979714270517073, + -4.022512310369844, + -3.2191293604345192, + -3.4071168765561315, + -5.955749757132087, + -3.1487295018187296, + -4.003714638558972, + -3.0601954655863133, + -3.377398786880427, + -2.592955266410457, + -3.764384755206477, + -3.780070891569777, + -2.8305619497826395, + -3.4473381412451305, + -4.744185291468757, + -3.760699350677225, + -3.1227191881310357, + -3.8057188830225743, + -2.252232153338945, + -2.7438053433830243, + -3.614838797469963, + -2.6442164161298805, + -4.100387869854045, + -3.4580328370358173, + -3.90046645826902, + -4.524021108690269, + -2.82520081941152, + -3.2822910827190044, + -3.952165080290747, + -2.7097756280302794, + -3.9031641840072298, + -3.0231443111327523, + -4.626900895938563, + -3.649831394516359, + -3.1767339883374475, + -3.9731106751639618, + -2.9962817887491218, + -3.744612558864628, + -3.016767450375896, + -3.870486440473274, + -2.415335821213135, + -3.205531771911046, + -3.623051998705967, + -3.5532035143218055, + -3.4389291799733943, + -2.7748358967085047, + -2.8720962448776777, + -3.0634298487134726, + -3.94040481145054, + -4.108042681969111, + -3.3600777684026903, + -3.8434784624785543, + -3.5421903873417264, + -2.715456978931478, + -2.855037289484921, + -3.4966681979276966, + -3.668358839556027, + -3.72622219119185, + -3.129567052203721, + -4.377196091954079, + -4.210192568970935, + -2.843315087890985, + -2.6346486233227253, + -3.6842418695985555, + -2.6657762060815613, + -3.6987885210061338, + -3.4968133795245975, + -3.6907485107609133, + -3.153378328775519, + -3.5097658426582874, + -2.5216218737693663, + -3.4022738533000774, + -2.631244662701699, + -4.125344802114456, + -2.4566709146368306, + -3.184633090779426, + -6.4438119626501456, + -3.871989485179285, + -3.4752143045614368, + -3.854302488527953, + -8.688318975449457, + -4.906404655368331, + -10.297756887883558, + -6.548252811953186, + -10.297756887883558, + -10.990904068443502, + -5.884661591374206, + -8.425954710981966, + -8.17006213841886, + -4.204187117838422, + -9.017906935314146, + -4.069245884292374, + -7.2509720028609905, + -6.86027470458404, + -6.784987730564297, + -7.618874475287829, + -7.018480712942505, + -5.809891253837954, + -5.096763124577817, + -4.675546066921168, + -8.40182043234844, + -4.96745647548247, + -8.688318975449457, + -4.530606695394598, + -7.772028243575302, + -7.287901888796708, + -4.99196750649682, + -8.534576625575477, + -8.911462526763668, + -5.179763075466803, + -7.119703057535612, + -9.545718189495421, + -10.990904068443502, + -9.04499391938819, + -8.793679491107284, + -7.716782715303133, + -10.297756887883558, + -7.991435787470161, + -9.3248018133559, + -9.892291779775393, + -10.297756887883558, + -9.107213404184119, + -9.604609707323613, + -9.671375403635874, + -4.069245884292374, + -4.204187117838422, + -6.111927250607295, + -8.911462526763668, + -5.893056938370284, + -8.058891963376565, + -8.9680955390288, + -9.199144599215447, + -9.199144599215447, + -4.906404655368331, + -4.204187117838422, + -6.331127339968753, + -4.99196750649682, + -5.287121593787302, + -4.565165276488049, + -4.686455266021522, + -6.1928809951233506, + -5.287121593787302, + -6.965552377708353, + -7.658699558268299, + -9.892291779775393, + -10.990904068443502, + -6.675868809406115, + -4.204187117838422, + -10.990904068443502, + -4.675546066921168, + -6.53791241360169, + -8.793679491107284, + -7.020790185870652, + -4.9813338303542345, + -10.297756887883558, + -9.418071111345139, + -9.095737222462393, + -9.604609707323613, + -6.11042474438684, + -10.990904068443502, + -4.99196750649682, + -4.906404655368331, + -7.00622519743533, + -6.588153760873144, + -4.99196750649682, + -4.204187117838422, + -5.929526971180982, + -5.615625660759338, + -4.686455266021522, + -4.336490020544453, + -9.892291779775393, + -9.892291779775393, + -4.069245884292374, + -4.069245884292374, + -4.686455266021522, + -9.140138795670978, + -10.297756887883558, + -4.942000110081024, + -5.715189998314505, + -7.602080771625944, + -6.697398354326705, + -8.410103394504908, + -6.150107458132328, + -5.930398570507752, + -7.979180271962986, + -5.583732296983384, + -9.236178124597082, + -8.902470330864267, + -6.578636086996241, + -4.069245884292374, + -4.204187117838422, + -9.892291779775393, + -4.675546066921168, + -8.688318975449457, + -4.204187117838422, + -7.094025265374669, + -10.297756887883558, + -6.498933304472853, + -7.023952367047466, + -9.892291779775393, + -4.204187117838422, + -5.345457170800265, + -8.351846738828245, + -10.990904068443502, + -4.686455266021522, + -8.216964556136693, + -6.1951135228467615, + -7.478918557799253, + -10.990904068443502, + -6.1980591403536405, + -8.263559898472456, + -7.2509720028609905, + -6.398597956741778, + -10.528805948070206, + -8.347000226975503, + -6.243528152206901, + -4.204187117838422, + -9.83961152194648, + -5.7979472175532925, + -7.389484577526088, + -4.204187117838422, + -5.168712338648543, + -6.1951135228467615, + -9.25803611704364, + -5.287121593787302, + -4.675546066921168, + -4.99196750649682, + -5.644057086564011, + -4.069245884292374, + -10.990904068443502, + -6.616751612253691, + -10.990904068443502, + -7.416136461544103, + -4.906404655368331, + -10.990904068443502, + -9.199144599215447, + -8.7522356612044, + -7.548378026854351, + -4.906404655368331, + -8.593008795645133, + -10.990904068443502, + -7.536027427621098, + -10.990904068443502, + -9.401877153269531, + -10.990904068443502, + -4.7439979602790565, + -10.297756887883558, + -6.639732030833327, + -10.990904068443502, + -8.425954710981966, + -4.204187117838422, + -6.468077753336334, + -8.157690724387287, + -5.245068476175858, + -8.035047957374688, + -9.381466156009402, + -9.892291779775393, + -10.990904068443502, + -4.686455266021522, + -8.593008795645133, + -4.675546066921168, + -5.506180401627974, + -7.772028243575302, + -9.199144599215447, + -7.2509720028609905, + -9.493037931666507, + -2.6460201722473355, + -4.876595232585907, + -2.511752229280971, + -4.351796940067189, + -2.8331377790648826, + -3.123469929397953, + -3.4698023247539327, + -4.250326774206297, + -3.1815789710066666, + -3.0018289929025324, + -3.4240378725589755, + -5.1749660776327, + -3.3290499610272226, + -3.5225746490506844, + -2.8056993216124018, + -3.152193326246651, + -3.9284139754214475, + -3.490337061002546, + -3.476195856184411, + -4.536179529123826, + -6.311880809309169, + -2.9190767350711107, + -3.556431791205251, + -3.0215774823179617, + -5.831171144524063, + -3.785820452432063, + -2.589744475101654, + -2.398640131630452, + -5.194658963561789, + -4.369370276253784, + -4.113791558202847, + -4.314974956886675, + -2.9347571776364068, + -3.3149430604807333, + -4.365166425277926, + -2.9215848798330417, + -4.534594230962038, + -4.058437400671554, + -3.4090503535735523, + -3.9363157161122135, + -4.066758555732206, + -2.975105790865114, + -3.2505864332706866, + -4.363053447902741, + -3.1753106794673736, + -2.91030485209767, + -4.523636697513332, + -3.855493864071097, + -3.6678707135200628, + -2.774017231888918, + -3.7637268432733197, + -4.815393142732671, + -3.6049082907334413, + -4.21565163975943, + -2.8550370168904253, + -3.0946653373088493, + -4.1458077580834845, + -4.118556016337795, + -4.881056190834531, + -2.7342467555292473, + -3.8268371828440544, + -4.207648824064947, + -3.8082941132090564, + -3.7750246379819234, + -3.790694348659153, + -4.531258809686234, + -3.2783771157042723, + -4.25277758806312, + -3.7011427371185937, + -3.211765179103611, + -3.561803859239983, + -3.5032265833708323, + -3.2148765717044543, + -3.480779095030633, + -3.51764713419824, + -3.8863823612582484, + -3.5742796813893776, + -3.6294364084868165, + -3.8434246063671176, + -4.860716792409472, + -5.425348595008392, + -4.271287107948282, + -4.074221635807743, + -3.6127248714914746, + -4.482254035791199, + -3.4703570251999545, + -3.9559342676098797, + -3.0900423715966046, + -3.66948874035493, + -3.800748167056168, + -3.039744002772224, + -3.135285874644551, + -3.3989322004500524, + -3.4744951937587465, + -3.352520022298363, + -3.5877356047361197, + -2.994190244239848, + -3.548412316504379, + -3.25061174888313, + -7.869737465498787, + -3.2261156017373347, + -4.148253880211475, + -3.468500863618392, + -3.4822386252545234, + -3.322465689145392, + -3.717196790080645, + -4.044782258834582, + -3.232099830847947, + -4.33058628760509, + -4.380599230973073, + -2.9737265699304727, + -5.4532123188325015, + -3.2481781962925127, + -2.923026923379102, + -3.3338157597467113, + -5.4307767676845025, + -3.0785794852352186, + -4.082485044912536, + -3.6102210807190636, + -5.696368807305016, + -3.4667084227564966, + -4.809595277318589, + -3.6183288875834796, + -4.185160396983355, + -3.4457678523294986, + -3.8295551486327, + -2.3718163052465524, + -3.655637879974628, + -3.4971270897007734, + -2.812395339502287, + -2.699656727199797, + -2.582713580857018, + -3.5839921857424955, + -3.5903106849129776, + -4.550427974125701, + -3.8391773598263637, + -3.841009199425197, + -3.3435232804333417, + -3.7114111737930533, + -4.267136332630456, + -3.2615817005768246, + -3.4303537852531036, + -3.2300052289052648, + -3.075171280317813, + -3.681191835893945, + -3.4881358718450457, + -4.619229946770471, + -2.977509804769822, + -3.667935223336527, + -3.618008359764313, + -3.279584503100609, + -4.69331642821608, + -4.0460219511737145, + -3.2251540766805333, + -2.575005641081945, + -3.396020915033741, + -3.76062017240629, + -2.753283656712896, + -5.001889814090978, + -2.7802433169911684, + -2.8355520590486845, + -3.5638191595905107, + -4.984735761614156, + -3.3527099491687067, + -2.867462087788387, + -2.714413411198811, + -2.8802181880141524, + -3.499845001758579, + -3.719640420505261, + -3.065840565532284, + -2.2680917197616064, + -3.162579836673049, + -2.7739715000379084, + -5.786197608897411, + -3.3942852198546176, + -3.6310308044055235, + -2.410419840888459, + -3.7251662060008055, + -3.4891742985946723, + -3.0215744878796666, + -3.738435268549956, + -3.0136067875664665, + -3.7620462140092106, + -2.56461018492016, + -3.82321047995141, + -3.8155009866437917, + -3.5895571283239365, + -3.6330368593545828, + -3.1937459685239884, + -3.081630607219437, + -2.5361722052234827, + -5.187903308482739, + -5.097799094611938, + -3.521332912027036, + -2.718704895436688, + -3.2783246053751274, + -3.2791244463242353, + -4.369359590747955, + -4.901608167378352, + -4.200489326901591, + -5.232116984174862, + -3.1825432440489005, + -3.2621617064863826, + -4.787794044080064, + -2.8029041680951514, + -3.5228388592518733, + -2.7861485108782973, + -3.7395297586903005, + -3.1431408024595284, + -3.301771269182292, + -3.5030223815624364, + -2.9791237710932483, + -4.198938548962422, + -2.3606336331186557, + -2.5039362248800847, + -3.747969350390267, + -3.162216581290726, + -3.5505107900908897, + -3.8681250567225045, + -3.676794675976092, + -3.577615741948283, + -2.4563854857304412, + -2.846266549784149, + -3.447338387641423, + -3.6647018517831356, + -3.7047986940212696, + -3.5204218216108334, + -2.564976393286625, + -3.8746810291473524, + -4.139255076544116, + -3.279823944945041, + -4.2215504255876155, + -3.385552235601182, + -3.920526060517316, + -4.253057017201104, + -3.0663745787751333, + -3.214137826203968, + -3.682940792462984, + -4.493310630616775, + -2.849895468875963, + -2.883150587017593, + -3.7405944414652317, + -6.766499238808454, + -3.2748392749482944, + -2.8763258526796123, + -3.1125972224917806, + -2.813419643210025, + -4.91246138808835, + -2.6765288822126934, + -3.3007146779944585, + -3.1325670280041202, + -3.4719023352127016, + -4.197482827862282, + -3.4818020620600176, + -3.063769975716501, + -4.521325028388387, + -3.5298415261011624, + -3.5654796980152335, + -2.5391458800375357, + -4.690625825017646, + -2.9319825475170016, + -3.190255695550701, + -3.6641659511872016, + -3.034453996055626, + -3.8665699594083485, + -2.99330303964508, + -4.044618203582243, + -4.112770758211871, + -4.347311593604123, + -2.6991623485583016, + -3.177772517392374, + -2.9109099106685976, + -5.743752676946967, + -3.492856042963654, + -2.8651020663539706, + -2.721362920170679, + -4.3060444703939424, + -2.716187141047092, + -3.3667595772626373, + -5.4113027732743975, + -2.958257175604153, + -2.9692468595215793, + -4.216650132866833, + -3.729349886570783, + -3.462512155781189, + -3.8275199599459633, + -3.0622275726157295, + -3.5998048454469607, + -3.120992302559126, + -2.6030885050514865, + -3.104696123773602, + -3.9941965226413445, + -3.0438202404000196, + -3.277350686064005, + -3.4711831686721184, + -4.53257482326063, + -3.3311947202232113, + -3.99800922074959, + -2.8080594110226693, + -2.583706377606432, + -6.119038898556703, + -5.30874934812278, + -10.441597924109448, + -7.530074976367938, + -6.7928266369239125, + -9.496883568835505, + -5.287121593787302, + -8.23448510538945, + -7.138535729582844, + -5.232918185343908, + -5.316289382293784, + -6.74279443442957, + -8.425954710981966, + -9.83961152194648, + -7.733219804789812, + -4.204187117838422, + -8.593008795645133, + -4.675546066921168, + -10.990904068443502, + -4.987022961434557, + -10.990904068443502, + -7.194180350027376, + -7.445865650555457, + -4.204187117838422, + -4.204187117838422, + -6.164019309738719, + -10.990904068443502, + -10.297756887883558, + -7.200965650738405, + -4.906404655368331, + -8.911462526763668, + -6.416219752618357, + -4.686455266021522, + -9.892291779775393, + -4.675546066921168, + -4.99196750649682, + -10.990904068443502, + -4.96745647548247, + -9.199144599215447, + -4.99196750649682, + -9.04499391938819, + -6.521893086797594, + -9.992326643925507, + -5.583732296983384, + -10.297756887883558, + -7.511090526660239, + -9.892291779775393, + -6.087518220202001, + -5.741117558317032, + -4.595057881006404, + -4.99196750649682, + -5.418750036265738, + -6.840143240973139, + -4.204187117838422, + -6.084692887942643, + -8.688318975449457, + -8.691205076494818, + -9.3248018133559, + -5.7979472175532925, + -5.0094707268540475, + -9.604609707323613, + -9.381466156009402, + -7.658699558268299, + -6.100222005150745, + -10.990904068443502, + -4.204187117838422, + -10.990904068443502, + -4.906404655368331, + -4.675546066921168, + -5.3341022165722904, + -9.892291779775393, + -6.629125697098289, + -4.99196750649682, + -9.196465628410271, + -6.588966686676285, + -5.010501618860717, + -4.377850575156948, + -4.99196750649682, + -10.64433047816353, + -7.644862197190189, + -5.7979472175532925, + -6.39249669088105, + -7.119703057535612, + -7.195225545094228, + -10.990904068443502, + -5.287121593787302, + -6.254385567301751, + -7.00091444590124, + -6.827887725465963, + -6.365306139649779, + -7.597545593140962, + -6.775822973075667, + -8.593008795645133, + -6.285699018305299, + -8.505997418655502, + -7.49854590838437, + -8.505997418655502, + -9.892291779775393, + -4.204187117838422, + -4.917023348480617, + -8.402829202156589, + -4.668052945085772, + -10.990904068443502, + -9.686896399967454, + -1.8946286527552927, + -9.493037931666507, + -8.793679491107284, + -10.990904068443502, + -9.604609707323613, + -5.583732296983384, + -4.927654571193985, + -9.381466156009402, + -5.2422012417874075, + -4.069245884292374, + -5.7979472175532925, + -5.781612092926721, + -10.64433047816353, + -9.604609707323613, + -7.6096730003522275, + -4.372395975606771, + -4.99196750649682, + -7.948654361905916, + -10.990904068443502, + -4.686455266021522, + -9.04499391938819, + -9.04499391938819, + -9.04499391938819, + -10.39365091203415, + -10.258495875998095, + -4.069245884292374, + -4.675546066921168, + -3.343595236087265, + -4.686455266021522, + -4.204187117838422, + -4.675546066921168, + -7.14007788712239, + -6.358215534308829, + -4.906404655368331, + -8.911462526763668, + -4.906404655368331, + -10.990904068443502, + -7.94638163072008, + -6.113468304339831, + -8.179683862122246, + -8.627545123184806, + -8.012019888176022, + -7.946381630720079, + -8.184340015249468, + -9.892291779775393, + -7.838679667232512, + -4.675546066921168, + -5.882780472146063, + -9.381466156009402, + -5.345457170800265, + -9.610538838977941, + -7.201989750179454, + -9.892291779775393, + -4.204187117838422, + -5.588826123027859, + -9.636693919746094, + -4.99196750649682, + -9.604609707323613, + -4.069245884292374, + -5.636167955263781, + -8.680536380749738, + -5.583732296983384, + -4.686455266021522, + -7.983316910572828, + -7.290835388341325, + -10.990904068443502, + -9.381466156009402, + -4.069245884292374, + -9.892291779775393, + -4.204187117838422, + -5.3620944134087845, + -4.686455266021522, + -8.01428240129961, + -9.951183297603585, + -4.96745647548247, + -5.339947665554408, + -5.583732296983384, + -6.794184092061049, + -5.814754335869674, + -5.829359616215499, + -9.04499391938819, + -4.204187117838422, + -4.530606695394598, + -10.990904068443502, + -5.234775087038852, + -6.1951135228467615, + -5.498683937309721, + -4.925233566947386, + -10.297756887883558, + -4.686455266021522, + -7.589706686781348, + -6.265006446912681, + -4.069245884292374, + -7.2565896521023445, + -7.635033870915413, + -8.293694931243145, + -5.365308550292218, + -3.480473512065496, + -4.70735152754632, + -7.353317908717117, + -4.592404520708806, + -4.90990638929888, + -10.06670782769691, + -8.425954710981966, + -9.199144599215447, + -4.675546066921168, + -10.990904068443502, + -7.597545593140962, + -6.180938921112855, + -5.164485072235432, + -8.402829202156589, + -7.095556052856134, + -4.204187117838422, + -7.917988315102415, + -9.3248018133559, + -5.189341351629935, + -5.245068476175858, + -8.282853867341293, + -5.583732296983384, + -5.583732296983384, + -4.069245884292374, + -8.425954710981966, + -5.142811657165333, + -10.990904068443502, + -9.892291779775393, + -6.26547795971776, + -6.951715016630244, + -4.204187117838422, + -5.287121593787302, + -4.264348363704308, + -6.951715016630244, + -4.686455266021522, + -4.204187117838422, + -5.129639181952276, + -6.7639379494046254, + -4.675546066921168, + -6.701665858526935, + -4.99196750649682, + -9.410702658045016, + -7.921505100416867, + -9.334299635251503, + -4.675546066921168, + -6.070923142615378, + -9.951183297603585, + -9.604609707323613, + -4.675546066921168, + -6.542541609694554, + -8.351846738828245, + -10.990904068443502, + -4.069245884292374, + -6.181139832090764, + -9.748450743549503, + -4.204187117838422, + -9.892291779775393, + -9.199144599215447, + -8.425954710981966, + -4.574385875265455, + -7.995171794889512, + -8.572373643692282, + -7.482775212147353, + -8.089956715624666, + -9.604609707323613, + -5.287121593787302, + -6.133177190263596, + -4.204187117838422, + -6.89737780916375, + -3.049407885296857, + -6.02421307812768, + -6.98133843811306, + -5.287121593787302, + -5.345457170800265, + -6.067166888599062, + -7.597545593140962, + -8.390407186790632, + -5.345457170800265, + -4.069245884292374, + -4.675546066921168, + -6.040265539115087, + -9.381466156009402, + -8.425954710981966, + -4.96745647548247, + -4.99196750649682, + -10.990904068443502, + -10.990904068443502, + -7.347763529874752, + -9.604609707323611, + -4.686455266021522, + -7.833225067682335, + -8.139012831115402, + -5.7979472175532925, + -9.604609707323613, + -7.738012038379388, + -5.73846350659123, + -10.297756887883558, + -8.751809821606548, + -9.951183297603585, + -5.535582953085801, + -4.796429960694926, + -5.327943588307557, + -8.100532310547338, + -8.793679491107284, + -7.821607029341912, + -4.204187117838422, + -8.29284884047153, + -4.9813338303542345, + -5.345457170800265, + -4.159206706656406, + -4.686455266021522, + -4.99196750649682, + -7.639923885442233, + -5.345457170800265, + -6.331127339968754, + -4.686455266021522, + -6.686382645920444, + -4.069245884292374, + -9.35608921188232, + -4.99196750649682, + -8.03551790434853, + -5.961315737749346, + -9.574297396415394, + -9.381466156009402, + -5.345457170800265, + -5.117887662410226, + -9.435260001425661, + -9.199144599215447, + -7.94638163072008, + -5.615625660759338, + -8.147350326035792, + -9.604609707323613, + -6.981352085625122, + -8.351846738828245, + -8.184340015249468, + -8.593008795645133, + -4.99196750649682, + -8.911462526763668, + -4.99196750649682, + -5.287121593787302, + -4.686455266021522, + -6.339770920805417, + -6.1951135228467615, + -5.287121593787302, + -4.675546066921168, + -4.204187117838422, + -5.7979472175532925, + -9.3064081069052, + -5.435426945385343, + -4.204187117838422, + -7.2509720028609905, + -4.445321191929972, + -8.793679491107284, + -5.345457170800265, + -5.764897692296809, + -9.150417095822753, + -9.604609707323613, + -5.1375551302269, + -10.990904068443502, + -10.297756887883558, + -5.468074583633051, + -4.069245884292374, + -6.980768832033883, + -9.124763415444045, + -9.045098064359495, + -9.993658056802435, + -5.129639181952276, + -4.069245884292374, + -5.070084513453876, + -10.990904068443502, + -6.882157399026148, + -7.916156309395112, + -4.159206706656406, + -7.599796124496063, + -4.445321191929972, + -6.143780615248048, + -9.510020316280064, + -8.116293823834775, + -9.892291779775393, + -4.204187117838422, + -9.381466156009402, + -6.907211121823414, + -4.675546066921168, + -3.842330314951959, + -9.122069259301819, + -7.183501386087967, + -7.012517231826019, + -4.204187117838422, + -7.302024614329566, + -8.065412138661396, + -8.793679491107284, + -7.597545593140962, + -4.906404655368331, + -5.615625660759338, + -6.446253046643939, + -4.368649414689073, + -3.4740475568885074, + -3.477962618636006, + -3.687584155085667, + -3.6110058510173104, + -3.5764115592516093, + -2.8835642287074243, + -3.495780991316146, + -2.562367463192927, + -3.1871548603009816, + -3.624333684365299, + -3.108422856795983, + -3.7227307581306786, + -2.852712754426148, + -3.1107327101047995, + -2.5977200119863384, + -4.557448727379837, + -3.95848229434861, + -3.7576513051502207, + -3.1510466633735716, + -4.860078537465653, + -3.1022896745430137, + -4.243277538169177, + -3.192483366366737, + -3.8675490923470193, + -4.070006454502425, + -2.910658442197708, + -3.399567303743919, + -3.326076223418014, + -3.1028450223376534, + -4.406152891017405, + -3.338851790227879, + -3.8577248132892046, + -3.3923847958580433, + -3.5813323131420742, + -3.9653506967510483, + -3.367055373141953, + -3.2710921743805996, + -3.259794536289405, + -3.4079072051477315, + -3.37193868140089, + -3.6899161376844147, + -4.39176207349565, + -4.409728704344263, + -3.338073187815192, + -2.8872515744897216, + -3.7732936264175185, + -2.7324105308948745, + -5.386761669456732, + -3.8884197838021595, + -3.4392271268244854, + -3.4385881771538065, + -6.768746973062102, + -2.98145833468037, + -3.2919573903155306, + -5.270722566310055, + -6.409812385243247, + -4.1976143630123595, + -2.8294272164529777, + -2.4150529329137282, + -3.831579427671476, + -3.4113802415169077, + -3.827430490458218, + -2.4980143585414716, + -2.8867635903030395, + -3.359223172879708, + -3.743998756704486, + -3.2278407560009303, + -3.1125956228254568, + -3.406661337096956, + -5.064960516409774, + -3.102803478476119, + -3.860475090411954, + -3.0725171087167467, + -3.4834013695071206, + -3.934939798715916, + -3.8378727589720385, + -3.7911654831030304, + -3.44920620738546, + -3.879313603511417, + -3.345801781509723, + -3.084460089681337, + -2.226181892052858, + -2.2709272726678997, + -3.030815070721819, + -3.964970653615229, + -3.4643218019379516, + -3.491506647292876, + -3.336049165150687, + -2.8065666046775144, + -5.260332295503498, + -4.287442051759314, + -4.090300980005015, + -3.691865826631954, + -2.2524359644673604, + -3.3776861075859324, + -3.5873115667326543, + -2.58865740831354, + -2.7766445649186093, + -3.9627293167540114, + -3.4531327909936786, + -6.070923142615378, + -7.838679667232512, + -5.224821484598639, + -10.297756887883558, + -10.990904068443502, + -8.793603300629766, + -7.9259638816707865, + -10.186185112226452, + -6.070923142615378, + -5.583732296983384, + -9.708429389712734, + -10.990904068443502, + -8.505997418655502, + -5.583732296983384, + -4.204187117838422, + -5.706786439156315, + -9.565348695438152, + -6.026292594658346, + -4.069245884292374, + -10.297756887883558, + -4.675546066921168, + -6.571265723150828, + -5.775774983829902, + -10.990904068443502, + -9.334299635251503, + -6.138080976401435, + -4.686455266021522, + -6.713748125578756, + -9.04499391938819, + -5.892340645712485, + -7.407385129987393, + -5.5507590891075465, + -8.593008795645133, + -4.7524989297368885, + -6.502267698711363, + -5.1892224366590085, + -8.100532310547338, + -5.7979472175532925, + -5.15104046339043, + -6.143780615248048, + -6.4897705432369, + -4.906404655368331, + -10.990904068443502, + -5.010501618860717, + -5.583732296983384, + -8.380232674941679, + -6.791618087249575, + -10.095024333829475, + -6.798958896392595, + -7.119703057535612, + -5.418750036265738, + -5.480541415779801, + -6.639399749711279, + -8.402829202156589, + -8.157690724387287, + -4.675546066921168, + -8.911462526763668, + -8.911462526763668, + -4.204187117838422, + -8.218315346203722, + -8.317350303084769, + -4.204187117838422, + -5.999102043427075, + -9.951183297603585, + -10.990904068443502, + -5.583732296983384, + -9.604609707323613, + -10.990904068443502, + -4.136716501065398, + -4.069245884292374, + -5.285059186498827, + -4.274982344868756, + -4.675546066921168, + -6.490354205528021, + -6.095388266558818, + -5.124148883522806, + -4.675546066921168, + -10.297756887883558, + -4.99196750649682, + -4.204187117838422, + -9.542968927825608, + -8.593008795645133, + -9.199144599215447, + -4.686455266021522, + -7.442129643136107, + -7.202012899131394, + -5.66677695630567, + -9.381466156009402, + -8.735474315185078, + -4.790975361144749, + -4.204187117838422, + -7.206714434525241, + -5.345457170800265, + -9.791956432044318, + -4.204187117838422, + -5.615625660759338, + -8.911462526763668, + -8.394425642998398, + -7.255507181345973, + -10.297756887883558, + -6.498933304472853, + -9.199144599215447, + -8.700033546733804, + -4.99196750649682, + -10.990904068443502, + -9.381466156009402, + -8.505997418655502, + -6.1951135228467615, + -4.593505189023155, + -10.297756887883558, + -6.557824822301045, + -9.381466156009402, + -10.990904068443502, + -3.480473512065496, + -9.892291779775393, + -7.597545593140962, + -10.297756887883558, + -6.618495290837946, + -4.204187117838422, + -8.425954710981966, + -10.297756887883558, + -5.633488442891097, + -6.548252811953186, + -8.574262222870841, + -10.297756887883558, + -10.297756887883558, + -4.872313783575602, + -5.345457170800265, + -8.688318975449457, + -8.157690724387287, + -5.967728963751811, + -9.361855799432762, + -10.990904068443502, + -10.990904068443502, + -8.052036177553683, + -8.557034990982686, + -5.245068476175858, + -4.686455266021522, + -8.747186275700669, + -4.393279219166376, + -5.814754335869674, + -9.381466156009402, + -7.917129445884778, + -5.7979472175532925, + -7.925355053495443, + -5.287121593787302, + -7.092622428581339, + -6.254385567301751, + -5.615625660759338, + -7.3547048721584805, + -10.64433047816353, + -4.818484132013528, + -7.119703057535612, + -9.381466156009402, + -6.7928266369239125, + -8.452635613539812, + -4.906404655368331, + -9.892291779775393, + -5.168712338648543, + -7.955359256046523, + -6.337367906923289, + -5.139544550142061, + -5.833395738716668, + -8.100532310547338, + -10.990904068443502, + -9.892291779775393, + -4.069245884292374, + -8.282853867341293, + -6.466426101373448, + -4.204187117838422, + -5.577360316768257, + -5.583732296983384, + -4.204187117838422, + -8.139012831115402, + -7.597545593140962, + -4.675546066921168, + -5.010501618860717, + -4.968915318941284, + -4.57407468852271, + -5.93144333805336, + -4.7766391360714575, + -6.237453977608401, + -8.601891442806096, + -9.381466156009402, + -6.650245023053105, + -10.990904068443502, + -4.069245884292374, + -9.144596547548778, + -7.772028243575302, + -7.589706686781348, + -4.069245884292374, + -9.604609707323613, + -8.168180619621882, + -5.030473426344654, + -3.4562441495632026, + -4.169230749261042, + -2.9055513871272134, + -2.9206073274276574, + -2.8046697160732474, + -2.7170831708916103, + -4.007961086973405, + -4.17408333907307, + -3.2103938533935295, + -3.6559838303364467, + -3.3078443589355357, + -4.320354013716594, + -3.706748242869062, + -4.937690200849173, + -3.4896990038301836, + -3.4997649777881485, + -3.034609870070228, + -3.19064936368558, + -2.988275664836366, + -4.220274684398244, + -4.139778711918048, + -4.263083307249678, + -2.9324659073068147, + -3.5362059063980795, + -4.856913114694276, + -3.3591009004535035, + -3.073102226496283, + -4.846611822018883, + -2.988329016011535, + -2.262499059758458, + -3.6299634026051915, + -2.3431467201491003, + -4.20830251035786, + -4.178502174477692, + -3.97010106109743, + -3.672018669255627, + -3.1169551037559087, + -3.3928030062395, + -2.971862826768828, + -4.489485949179725, + -3.733428164699782, + -3.8137995339712467, + -3.551204835950531, + -3.141884219132339, + -2.6375392937990525, + -3.444489840357229, + -6.2597555595237, + -2.9549487542275634, + -3.1682167243042083, + -2.900645221628122, + -3.2327973426427974, + -3.7984373897555606, + -3.4575467534029856, + -2.866638606708132, + -3.495683601298569, + -2.9767872259886934, + -3.4143654740134175, + -3.6081753217968613, + -3.196290450379126, + -3.3744465504926326, + -3.903558244678076, + -4.813635139738924, + -4.152269149471746, + -2.553057080767224, + -4.27532297154576, + -4.878099456100427, + -4.9836050363792745, + -3.353014744821075, + -3.1536961003582453, + -3.640004126650221, + -3.8866515005122704, + -3.305105422303285, + -2.811914250160914, + -3.1532776747938804, + -3.30959370600423, + -3.1700084902341374, + -3.600707516634044, + -3.3064483532627986, + -4.507355062507074, + -4.344166242535615, + -3.4535806656495285, + -3.5561230018662306, + -2.6305861142258258, + -3.726196607064633, + -2.9748771952239412, + -3.742668284340421, + -3.667857648008399, + -4.087600346341149, + -4.106856769943143, + -3.6691331681032318, + -4.2449249394436634, + -3.8972221462485415, + -3.5197859676170697, + -3.378889800624639, + -2.2327819201808, + -3.2295849809349484, + -3.2148271957949737, + -3.210413146839233, + -4.084953997516551, + -3.507404795059987, + -2.443170791914373, + -2.575471289075798, + -2.331691249131538, + -2.797711259168044, + -3.710254493999972, + -2.835139651523536, + -2.648900573260476, + -4.685213080542345, + -3.1268638713521977, + -2.860473573077264, + -2.4249505245284264, + -4.355137042759859, + -2.593930050893685, + -3.175367057968391, + -3.565860053813323, + -2.7403493034059307, + -3.2029707272005745, + -2.8599048521106334, + -2.2066222394271096, + -4.574410596685911, + -3.7584458320730896, + -7.4945341144372195, + -3.7134576906650594, + -5.622561287633423, + -3.310519654062284, + -3.592063142709562, + -3.545916561120108, + -3.1125147390940904, + -3.515838448514044, + -3.1774588581266494, + -2.769475478477154, + -3.0070730671845736, + -4.255526007574938, + -4.211172584719092, + -3.6426488858944763, + -3.845419113056857, + -3.4706390038046915, + -2.9599241365783775, + -2.7357528468472587, + -2.7456222811045166, + -3.0833389064982155, + -3.969496971234947, + -2.9462189101255385, + -3.1993706149184375, + -4.356317447504523, + -2.666353410814926, + -2.9400534940248697, + -4.176582684192485, + -3.477847554964749, + -3.114644679884787, + -3.9431947630539566, + -3.0921211310030268, + -5.092974752778262, + -3.782221044666917, + -3.7679556759872486, + -3.778907554488592, + -4.369434564839043, + -2.901980109860318, + -4.7532190056214505, + -3.140013952728311, + -5.44985929857485, + -3.569446387622183, + -3.580402993605683, + -2.534277738053492, + -3.063858098431298, + -5.352218238445143, + -2.6377702652040176, + -3.248030025130728, + -3.524491502721061, + -3.40074217233411, + -3.860319702899484, + -2.904927135627826, + -2.446228727182782, + -4.364562482241643, + -5.157825804457698, + -2.9476010161360917, + -3.472054740241233, + -5.5695869548793695, + -4.374113255237543, + -3.541349163392452, + -4.022067099369018, + -2.9567705122148378, + -3.0783721737963883, + -4.451293506625056, + -2.921229092514275, + -3.694776913984875, + -6.045431815663488, + -2.419636084628631, + -4.050123554361875, + -3.1304401907284927, + -3.787540666733633, + -3.2555220837677705, + -2.6854857444912965, + -3.832993770543914, + -3.28779979029652, + -3.177584795368621, + -4.135236740760237, + -2.8318695519969435, + -3.5704693982830205, + -3.0032507319789516, + -4.675546066921168, + -9.545718189495421, + -7.379986155799278, + -5.814754335869674, + -8.476499308137447, + -8.564492522422468, + -9.892291779775393, + -10.297756887883558, + -4.675546066921168, + -4.204187117838422, + -4.906404655368331, + -10.990904068443502, + -10.441597924109448, + -5.814754335869674, + -4.069245884292374, + -4.96745647548247, + -7.143935405688866, + -7.671462607231748, + -8.168236419368348, + -10.297756887883558, + -9.892291779775393, + -8.212490037593735, + -4.99196750649682, + -6.1951135228467615, + -8.593008795645133, + -4.069245884292374, + -4.675546066921168, + -8.496072274586519, + -9.604609707323613, + -8.047852052718426, + -9.258036117043641, + -6.386291079025158, + -4.675546066921168, + -7.821607029341912, + -6.359262446023579, + -5.400410331076315, + -9.46864284958179, + -8.056255611876615, + -5.345457170800265, + -4.204187117838422, + -5.0434014906757545, + -5.287121593787302, + -6.365931255159232, + -9.036360343244136, + -4.99196750649682, + -8.405662070924427, + -6.365931255159232, + -8.823125250021379, + -4.204187117838422, + -5.090352202260314, + -9.04499391938819, + -4.96745647548247, + -7.658699558268299, + -6.566923924153787, + -4.721180662493094, + -8.688318975449457, + -7.28391892334828, + -9.04499391938819, + -4.99196750649682, + -7.964859483981295, + -7.772028243575302, + -4.204187117838422, + -7.589706686781348, + -10.023103815716532, + -8.649838454881394, + -8.428922078741873, + -4.675546066921168, + -8.793679491107284, + -5.583732296983384, + -7.4633076263521625, + -4.675546066921168, + -10.06670782769691, + -4.635160485715641, + -7.464543543827341, + -4.686455266021522, + -7.618874475287829, + -4.675546066921168, + -4.857972742928773, + -5.615625660759338, + -6.491357951050264, + -7.575150599509542, + -4.70735152754632, + -10.990904068443502, + -4.675546066921168, + -4.069245884292374, + -3.480473512065496, + -7.048239448806907, + -4.96745647548247, + -6.217763980812257, + -8.899316728029524, + -4.069245884292374, + -4.114226295474389, + -7.812850238095558, + -9.04499391938819, + -7.033960711015462, + -4.069245884292374, + -4.204187117838422, + -6.860269993154679, + -4.136716501065398, + -4.487825269830353, + -4.675546066921168, + -5.814754335869674, + -5.418750036265738, + -9.892291779775393, + -9.04499391938819, + -9.430193659402095, + -5.316289382293784, + -6.455133723001015, + -4.487825269830353, + -9.604609707323613, + -5.814754335869674, + -7.530074976367938, + -5.345457170800265, + -5.7979472175532925, + -10.297756887883558, + -9.892291779775393, + -8.425954710981966, + -4.906404655368331, + -10.990904068443502, + -8.296461198848045, + -9.381466156009402, + -8.987237475827268, + -2.7349198408089905, + -2.8087679523687648, + -3.7644648640440717, + -3.117405587982873, + -3.1263458620639613, + -2.7664602382282975, + -3.4394642101762782, + -2.7895578320608734, + -5.380108359933613, + -3.8516409042826667, + -3.1697350436350327, + -4.910672294635266, + -5.098232076989863, + -2.4588749311678706, + -3.189520791554903, + -3.2125343707708964, + -3.809739293308371, + -4.990776344099854, + -3.0273712495060403, + -3.017405474275458, + -3.9958819971060016, + -3.7240973711737304, + -3.0777132017010653, + -3.9567919726540546, + -4.2580043645760135, + -2.4910676510561673, + -3.322862381391802, + -4.552451858492182, + -3.8294082444728903, + -4.439072929941251, + -3.5582066716305873, + -3.5986217061546437, + -3.4864546777538785, + -2.7816236703369523, + -2.742869145160721, + -4.353017726382304, + -5.292381818983583, + -2.645444000695333, + -3.1220199411609286, + -5.089835824366058, + -2.8966924004010677, + -5.198605135742492, + -3.0279602538653387, + -4.595689467672771, + -3.1295108441529957, + -3.040213979232587, + -3.242007227160917, + -2.961490673072935, + -3.4120745122006286, + -5.906162766081716, + -3.779116739587925, + -2.6377844672967736, + -3.0150537342501917, + -2.21312787589424, + -3.557642879214403, + -4.228389854194627, + -4.700249949000604, + -4.183181180361535, + -3.1609188582240875, + -3.152489629764622, + -2.6725396001145296, + -2.28473289081487, + -3.1034582013309167, + -3.2785968537354195, + -3.51541555370725, + -6.039155064271517, + -4.179052322921486, + -3.1120150788939074, + -2.801959013958243, + -3.2416804591977786, + -3.0074819072227563, + -2.9998438988485785, + -3.06728343294057, + -3.622468206316124, + -4.222964285896147, + -3.3325515442881026, + -4.3338801263121525, + -3.0407190468224004, + -8.051997708384263, + -3.9405541677814266, + -2.9300695939642414, + -3.368331987601573, + -3.155085596084948, + -2.97539072903316, + -2.5801029122317556, + -3.658112834324189, + -6.987204424806738, + -3.1240885841682506, + -2.4864438830771642, + -3.252809429180338, + -3.2317428715043612, + -4.212133309329845, + -4.415990809175176, + -5.486015665073692, + -2.8179207208801875, + -3.210323837555953, + -4.339690076735995, + -4.894987126519154, + -4.3940869294399665, + -3.138102463660432, + -7.597545593140962, + -5.345457170800265, + -9.748450743549503, + -5.615625660759338, + -9.199144599215447, + -9.892291779775393, + -4.069245884292374, + -9.199144599215447, + -7.642272658893985, + -7.464543543827341, + -5.775585195887872, + -6.262733715726843, + -10.990904068443502, + -7.57063080379916, + -9.20853489153768, + -4.963446556120657, + -4.824228570976907, + -8.584600832570484, + -7.445865650555458, + -4.701918719090506, + -6.6271821507678155, + -4.675546066921168, + -7.2509720028609905, + -5.345457170800265, + -5.260804285469929, + -9.748450743549503, + -10.017948993915846, + -5.745645855098168, + -6.502267698711363, + -6.390713690022331, + -10.297756887883558, + -8.854620585578145, + -4.686455266021522, + -9.892291779775393, + -4.069245884292374, + -10.297756887883558, + -8.59715819705248, + -8.420333822931003, + -4.204187117838422, + -8.199411772038621, + -8.505997418655502, + -4.686455266021522, + -4.069245884292374, + -6.34965990980913, + -9.290305377612425, + -9.604609707323613, + -8.688318975449457, + -10.990904068443502, + -7.183501386087967, + -10.297756887883558, + -8.402829202156589, + -10.258495875998095, + -8.593008795645133, + -6.3257144944826065, + -4.833756786708994, + -4.204187117838422, + -5.345457170800265, + -4.942000110081024, + -4.675546066921168, + -7.255507181345973, + -4.445321191929972, + -9.604609707323613, + -4.906404655368331, + -6.537905289716723, + -4.069245884292374, + -7.907730351126166, + -8.579511675193553, + -6.841623514787654, + -2.8473812788187858, + -2.5304356189709405, + -3.3789535227776373, + -4.377090088768697, + -2.8661851231017432, + -3.628655589973131, + -5.314661456807179, + -2.589073219830163, + -3.699640989329713, + -3.687423227408723, + -3.0344957135311574, + -2.713532500980109, + -3.5844405463176514, + -3.135874387854408, + -3.1911907763669256, + -2.622237421177711, + -2.8726337844903056, + -3.4321231911622325, + -3.6203342154983615, + -3.3481064831718146, + -3.1444967089321274, + -2.630829197404376, + -3.422124709374678, + -3.5947527181471313, + -3.113695306805031, + -3.721435436871569, + -2.401360378262478, + -2.553111534806286, + -2.6650625325835597, + -4.123396937903132, + -4.6972998515743605, + -3.7456157312539347, + -3.250365892398049, + -3.3472140736620597, + -3.694532402426624, + -2.863931676481017, + -5.395456023728369, + -3.745632042109687, + -3.6490749183796156, + -4.513382713622883, + -3.4513562209196844, + -3.5578414198113566, + -3.7637673228365487, + -4.119123869913364, + -2.6091827540244403, + -3.5641047591523694, + -3.5734896345176104, + -3.56144992159144, + -3.616899732280122, + -4.3531843368100365, + -3.0616898343396906, + -4.357933660248675, + -3.220523015871284, + -3.8190270450912718, + -2.894828205608513, + -5.426736929749471, + -3.5783346723188703, + -4.913878710369081, + -2.3114068823932454, + -2.9513208332456204, + -3.2232779488596273, + -3.613699194331606, + -3.3620035375413666, + -3.4633350798847564, + -5.047564457316912, + -3.296336075399023, + -4.799131824710972, + -4.128202864461131, + -3.31605700027841, + -4.633590700848685, + -3.230848447500053, + -3.0034188439353593, + -2.7987692836868443, + -2.7155284555317705, + -3.3543894786535353, + -3.7631953014990835, + -3.7513766384827623, + -3.8495571709239096, + -3.236791245103536, + -3.2322603227863533, + -3.8484652495790734, + -3.822473620182316, + -3.770336365838244, + -2.913989307694401, + -2.506096791159361, + -3.297861096413615, + -3.2213810753972854, + -3.61142786352742, + -2.576229402813326, + -3.131561473562008, + -2.639762908437117, + -4.561294826188061, + -4.07562748796604, + -3.0844348419032506, + -3.1855312934432978, + -4.407905104750288, + -3.0608561349997414, + -4.492882064900593, + -2.8185807650053087, + -4.368142796814354, + -3.4818458383813984, + -3.6521542437759007, + -3.6652962123151616, + -2.504861395955198, + -4.447902114687594, + -3.157674420215519, + -3.9763125488100233, + -4.350148639847155, + -3.335005753407638, + -2.936434612340919, + -3.2564999006617765, + -3.551604721926467, + -3.37515847679629, + -3.160510402793342, + -3.1834741433914306, + -4.014598875155606, + -6.119061154909104, + -3.2170879561062793, + -3.0960329185438153, + -4.145434012308129, + -3.45774855960675, + -3.7209113252691366, + -3.581562823032692, + -4.114340099620419, + -3.770830267301049, + -4.7970010102966745, + -2.82727847706053, + -3.440158477274542, + -3.7468783704133037, + -2.6674239307811245, + -4.212001611132625, + -4.687329842551527, + -3.6956842921268334, + -2.6743934414220205, + -2.7809430293169237, + -6.350087397219335, + -2.7936180388294796, + -4.29117601962963, + -4.111369527432162, + -3.549011633534983, + -4.003205133439302, + -3.1787448496578916, + -4.19850520596212, + -3.4612827203556313, + -4.715337587694077, + -4.442035705246654, + -3.9579422819818992, + -4.098781426267542, + -4.591072213483353, + -3.5461248334893773, + -3.1179935893671384, + -2.770003534449746, + -5.933987079718397, + -3.539969268756328, + -2.859013320433907, + -3.114192067211452, + -2.5339399767493864, + -3.1278569883615925, + -3.780885476194314, + -2.941863877045567, + -3.7927474926706792, + -3.696642630270887, + -3.2995695822531435, + -4.1227121181468505, + -3.3792472390507737, + -4.858353758051419, + -3.4201023273930637, + -2.8239117797054707, + -3.3730830907008587, + -3.9363476799943333, + -3.8482560859939845, + -3.291354798233129, + -6.651357517040343, + -3.3984858345794233, + -3.604004157682078, + -4.0989029044883285, + -3.086698085541789, + -3.226162048923926, + -2.7526708841133454, + -3.1890640086163127, + -4.407431755535186, + -2.5882013393782617, + -3.596253920884693, + -4.172487221171487, + -4.8325809360467264, + -3.934122255363919, + -3.2226975217970204, + -3.833491161539387, + -6.218536503003249, + -2.535526772355536, + -3.287447805786812, + -4.237861034202659, + -3.556014550875833, + -2.382433367080065, + -3.246252537234722, + -2.8816656369738145, + -3.0333661110565693, + -4.754817114053149, + -4.121361258615777, + -3.858083420359515, + -8.351846738828245, + -8.793679491107284, + -8.9680955390288, + -3.480473512065496, + -9.604609707323613, + -8.258833791467136, + -6.562835556712931, + -4.99196750649682, + -4.069245884292374, + -6.346110641414375, + -8.053438703017488, + -7.423394419853832, + -7.399348217571863, + -9.146464341386535, + -4.204187117838422, + -4.377850575156948, + -4.675546066921168, + -4.675546066921168, + -9.892291779775393, + -9.604609707323613, + -9.917945460154103, + -8.784587580064564, + -4.7410868359328315, + -6.895893505333844, + -4.96745647548247, + -9.04499391938819, + -10.990904068443502, + -7.745454240089597, + -4.204187117838422, + -10.64433047816353, + -4.96745647548247, + -10.297756887883558, + -9.04499391938819, + -10.64433047816353, + -10.297756887883558, + -5.287121593787302, + -5.418750036265738, + -6.070923142615378, + -5.6118994394371775, + -9.748450743549503, + -9.04499391938819, + -10.297756887883558, + -8.149114184774163, + -9.199144599215447, + -9.246398684877613, + -8.505997418655502, + -10.297756887883558, + -5.581284999164616, + -4.204187117838422, + -4.204187117838422, + -4.204187117838422, + -6.596226342338512, + -4.204187117838422, + -9.381466156009402, + -9.381466156009402, + -6.001608306701335, + -6.9573333584860535, + -6.548252811953186, + -8.346682878115177, + -4.839211386259171, + -4.906404655368331, + -9.087572823558343, + -10.990904068443502, + -5.333569987724126, + -6.070923142615378, + -6.720849220588131, + -4.069245884292374, + -8.793679491107284, + -8.793679491107284, + -4.204187117838422, + -5.865677141666506, + -6.548252811953186, + -9.604609707323613, + -4.906404655368331, + -5.179763075466803, + -6.832020985083831, + -4.96745647548247, + -6.328585721379407, + -5.615625660759338, + -5.681637594838823, + -6.741796956034285, + -10.297756887883558, + -7.935801934943579, + -6.6245905186133065, + -5.973442073375954, + -8.911462526763668, + -9.820371261662448, + -7.517927325795485, + -5.8723690849270875, + -7.289373522898457, + -4.96745647548247, + -8.003367167270607, + -10.990904068443502, + -10.297756887883558, + -9.396722331468847, + -10.297756887883558, + -6.548608521049513, + -9.892291779775393, + -7.350555470751132, + -10.990904068443502, + -4.686455266021522, + -4.906404655368331, + -8.728665084908476, + -8.74099923327837, + -4.487825269830353, + -7.325677643976398, + -6.214968884007416, + -5.585615255993712, + -4.96745647548247, + -9.892291779775393, + -8.100532310547338, + -8.662665295070747, + -5.287121593787302, + -4.842435772525856, + -9.342985635441337, + -10.990904068443502, + -9.920112362174322, + -4.57407468852271, + -8.911462526763668, + -6.76522266288233, + -6.826299996333872, + -5.7979472175532925, + -5.179763075466803, + -6.020367428621155, + -9.381466156009402, + -4.686455266021522, + -10.990904068443502, + -6.9696326774737685, + -8.153376542157318, + -7.838679667232512, + -5.531445324556099, + -7.101867787164863, + -5.814754335869674, + -6.055835282016217, + -10.990904068443502, + -6.6245905186133065, + -5.168712338648543, + -9.892291779775393, + -6.502267698711363, + -10.990904068443502, + -4.906404655368331, + -8.593008795645133, + -6.318567280388649, + -7.379986155799278, + -9.290305377612425, + -8.943731787332453, + -4.069245884292374, + -8.351846738828245, + -7.987681751597487, + -10.297756887883558, + -4.204187117838422, + -5.953214111523731, + -7.753958720267365, + -4.906404655368331, + -4.686455266021522, + -4.686455266021522, + -4.204187117838422, + -10.990904068443502, + -4.686455266021522, + -7.393209011058796, + -8.667351011905742, + -7.752052274048673, + -4.487825269830353, + -5.345457170800265, + -3.6206734266364218, + -8.139012831115402, + -4.766780080225571, + -4.886493693304936, + -7.255507181345973, + -4.686455266021522, + -4.136716501065398, + -9.892291779775393, + -8.065412138661396, + -4.204187117838422, + -5.480541415779801, + -9.892291779775393, + -4.271345945168639, + -7.407385129987393, + -9.199144599215447, + -7.00622519743533, + -4.949186080932575, + -6.959775815616098, + -10.06670782769691, + -9.142588294752542, + -7.048239448806907, + -5.287121593787302, + -5.396857873326603, + -8.88201676784957, + -9.604609707323613, + -7.119703057535612, + -10.990904068443502, + -7.464543543827341, + -9.551741363931399, + -7.183501386087967, + -4.675546066921168, + -4.069245884292374, + -10.990904068443502, + -10.990904068443502, + -5.1640179855507355, + -9.361855799432762, + -8.688318975449457, + -6.1757627392701515, + -8.351846738828245, + -5.637980159408808, + -5.227627282699117, + -4.204187117838422, + -5.977316316070498, + -4.204187117838422, + -8.394425642998398, + -5.7979472175532925, + -5.224637097344085, + -6.972601843878889, + -4.906404655368331, + -8.218315346203722, + -10.990904068443502, + -8.911462526763668, + -5.040312381073167, + -7.7114658772318405, + -10.06670782769691, + -5.7979472175532925, + -7.119703057535612, + -6.1951135228467615, + -5.588906882816266, + -10.990904068443502, + -9.699479629921218, + -4.906404655368331, + -9.545718189495421, + -8.351846738828245, + -4.069245884292374, + -4.675546066921168, + -4.675546066921168, + -5.615625660759338, + -5.418750036265738, + -7.878873542682922, + -4.713327511142103, + -10.759855008256855, + -4.686455266021522, + -6.367359750131533, + -10.990904068443502, + -8.025329095944205, + -9.04499391938819, + -5.41111324053913, + -9.604609707323613, + -9.381466156009402, + -9.951183297603585, + -6.070923142615378, + -6.701665858526935, + -5.615625660759338, + -4.906404655368331, + -4.873789405662154, + -4.372395975606771, + -7.2111899067847505, + -4.691975096652612, + -8.415941255335811, + -4.833756786708994, + -9.294507157191521, + -4.686455266021522, + -9.671375403635874, + -9.604609707323613, + -4.826489090637879, + -9.089643243558102, + -5.7811352576908215, + -5.287121593787302, + -4.99196750649682, + -4.99196750649682, + -8.405662070924429, + -9.892291779775393, + -4.906404655368331, + -7.206714434525241, + -10.297756887883558, + -9.604609707323613, + -10.297756887883558, + -7.602080771625944, + -6.431462687699829, + -4.069245884292374, + -5.345457170800265, + -6.085629290005073, + -7.2509720028609905, + -10.990904068443502, + -7.899861615085187, + -8.09699943486634, + -8.218315346203722, + -4.204187117838422, + -4.204187117838422, + -6.24760029763717, + -8.911462526763668, + -7.850706148963406, + -9.381466156009402, + -5.896946902309885, + -9.892291779775393, + -4.204187117838422, + -9.604609707323613, + -9.892291779775393, + -4.686455266021522, + -4.725921325882415, + -10.297756887883558, + -8.100532310547338, + -6.108102145857132, + -4.99196750649682, + -5.707632026516376, + -4.377850575156948, + -10.297756887883558, + -9.636878967892397, + -9.381466156009402, + -9.300510876242488, + -6.865724592704856, + -4.99196750649682, + -10.186185112226452, + -9.604609707323613, + -4.936930565425401, + -8.351846738828245, + -7.836586563531397, + -5.678949380828026, + -6.836927795807993, + -7.732807530422021, + -4.686455266021522, + -6.496590307542262, + -9.892291779775393, + -10.990904068443502, + -9.604609707323613, + -4.8935224355926, + -9.381466156009402, + -4.99196750649682, + -10.990904068443502, + -9.027639373410514, + -7.753958720267365, + -4.293798532089898, + -6.693826952167321, + -5.4731196283128325, + -9.373560647136964, + -4.675546066921168, + -8.153596725368642, + -4.069245884292374, + -9.381466156009402, + -3.480473512065496, + -6.6342774312831505, + -7.602080771625944, + -5.688938443326056, + -9.199144599215447, + -4.833756786708994, + -4.686455266021522, + -10.297756887883558, + -6.502267698711363, + -7.738012038379388, + -8.425954710981966, + -10.990904068443502, + -9.892291779775393, + -10.990904068443502, + -4.906404655368331, + -7.658699558268299, + -4.686455266021522, + -10.297756887883558, + -10.297756887883558, + -9.748450743549503, + -6.365306139649779, + -4.708749905878142, + -5.232918185343908, + -9.381466156009402, + -7.183501386087967, + -6.631245380690317, + -9.401877153269531, + -8.969378434526227, + -4.986788429904411, + -6.904398412581017, + -7.899861615085187, + -10.297756887883558, + -9.401877153269531, + -8.157690724387287, + -9.892291779775393, + -10.297756887883558, + -4.96745647548247, + -10.297756887883558, + -9.381466156009402, + -8.394425642998398, + -10.990904068443502, + -4.686455266021522, + -8.043702651311078, + -10.990904068443502, + -5.323098434826843, + -7.464543543827341, + -4.204187117838422, + -5.056921354169155, + -8.688318975449457, + -4.96745647548247, + -7.188705894045334, + -4.796429960694926, + -5.445787119286956, + -7.998479821955409, + -7.119703057535612, + -4.675546066921168, + -6.765056963851732, + -10.990904068443502, + -5.7979472175532925, + -4.069245884292374, + -5.814754335869674, + -4.204187117838422, + -8.46673640677004, + -4.790442270357745, + -7.143395397878576, + -8.505997418655502, + -7.948654361905916, + -9.892291779775393, + -5.287121593787302, + -10.297756887883558, + -8.793679491107284, + -4.204187117838422, + -4.372395975606771, + -9.381466156009402, + -7.414797177136353, + -6.836927795807993, + -4.204187117838422, + -8.943731787332453, + -4.675546066921168, + -9.401877153269531, + -10.990904068443502, + -6.218646242587218, + -9.636878967892397, + -10.990904068443502, + -6.14541621882277, + -6.570758151903962, + -6.187048644052712, + -8.24643520536516, + -9.892291779775393, + -10.990904068443502, + -8.047852052718426, + -7.597545593140962, + -10.990904068443502, + -9.748450743549503, + -9.382051524497449, + -9.199144599215447, + -5.7979472175532925, + -5.287121593787302, + -6.315070914410194, + -10.441597924109448, + -4.842435772525856, + -9.604609707323613, + -7.602080771625944, + -9.892291779775393, + -6.358327909579753, + -9.604609707323613, + -4.069245884292374, + -8.351846738828245, + -7.085727726581358, + -5.287121593787302, + -6.424570474947131, + -4.204187117838422, + -5.861277589483819, + -5.583732296983384, + -10.990904068443502, + -6.740067378564403, + -7.119703057535612, + -8.512990539642873, + -6.934571126393389, + -10.297756887883558, + -5.569661355639124, + -5.1254972325103045, + -4.445321191929972, + -4.686455266021522, + -4.675546066921168, + -8.866656447418823, + -7.73213329442128, + -5.345457170800265, + -5.814754335869674, + -9.381466156009402, + -5.583732296983384, + -5.345457170800265, + -8.168180619621884, + -5.583732296983384, + -4.99196750649682, + -10.297756887883558, + -10.441597924109448, + -4.833756786708994, + -7.203366044341607, + -4.204187117838422, + -4.7293740436106875, + -5.529201148982791, + -4.204187117838422, + -10.990904068443504, + -5.056664169450733, + -8.955972990971842, + -6.4549490909104605, + -7.330309790073764, + -4.957695850181957, + -4.204187117838422, + -9.791956432044318, + -9.199144599215447, + -10.297756887883558, + -10.297756887883558, + -4.069245884292374, + -5.287121593787302, + -5.764294055120125, + -4.675546066921168, + -6.35026322822421, + -9.195126143007682, + -4.069245884292374, + -9.381466156009402, + -9.892291779775393, + -5.884740728811443, + -5.628588720912655, + -8.913425251053331, + -9.892291779775393, + -9.473797671382474, + -9.295038623366041, + -4.99196750649682, + -6.988502841465192, + -7.845119498664342, + -9.381466156009402, + -5.345457170800265, + -4.377850575156948, + -7.442129643136107, + -5.615625660759338, + -5.564957206283153, + -9.892291779775393, + -9.604609707323613, + -8.135537104823154, + -10.990904068443502, + -10.297756887883558, + -9.604609707323613, + -7.946381630720079, + -7.119703057535612, + -5.781206748392362, + -4.96745647548247, + -5.233442334627052, + -10.297756887883558, + -6.671907122662533, + -7.119703057535612, + -8.593008795645133, + -9.04499391938819, + -9.178210965469104, + -5.345457170800265, + -4.675546066921168, + -7.347118922884008, + -9.671375403635874, + -8.793679491107284, + -4.204187117838422, + -9.04499391938819, + -10.990904068443502, + -4.204187117838422, + -10.297756887883558, + -9.381466156009402, + -10.990904068443502, + -5.415155225941455, + -4.686455266021522, + -9.04499391938819, + -6.32020454559628, + -7.610117684041475, + -8.057482518006724, + -9.04499391938819, + -7.863328555304137, + -4.102981192678886, + -7.838679667232512, + -4.99196750649682, + -9.951183297603585, + -6.378782429870915, + -4.236220509281158, + -7.530074976367938, + -4.069245884292374, + -10.990904068443502, + -6.502267698711363, + -5.317683446018808, + -9.307256153450265, + -10.990904068443502, + -6.980768832033883, + -10.990904068443502, + -4.915485999027933, + -6.97569928737826, + -4.204187117838422, + -4.204187117838422, + -10.095024333829475, + -8.903710433495684, + -6.352379655263404, + -9.835658767510262, + -10.297756887883558, + -6.577328915217746, + -9.604609707323613, + -7.147953861896632, + -10.297756887883558, + -10.297756887883558, + -4.069245884292374, + -9.604609707323613, + -8.65989902746585, + -4.686455266021522, + -8.688318975449457, + -4.99196750649682, + -6.105811715832649, + -5.675489801293345, + -9.892291779775393, + -4.99196750649682, + -9.951183297603585, + -4.069245884292374, + -4.585821796660445, + -8.669078715165426, + -7.329711013742863, + -5.615625660759338, + -9.199144599215447, + -5.249859737404085, + -9.381466156009402, + -4.686455266021522, + -8.708729972709586, + -8.695053211221964, + -10.64433047816353, + -4.873315390477642, + -6.15929758379521, + -8.492297931561446, + -6.549616340575298, + -5.002285916463092, + -6.503468482957835, + -4.686455266021522, + -9.604609707323613, + -4.069245884292374, + -6.001787672097075, + -6.085629290005073, + -4.204187117838422, + -4.906404655368331, + -9.604609707323613, + -9.892291779775393, + -8.688318975449457, + -5.741117558317032, + -5.345457170800265, + -9.951183297603585, + -5.010501618860717, + -8.139012831115402, + -2.820279864336438, + -3.5803547901682675, + -2.9062450928289185, + -3.161466624007512, + -4.643725986076136, + -2.7985707292115323, + -3.0099036031528734, + -4.531906631538214, + -3.073135412973385, + -2.8868575461584154, + -4.756017340370236, + -3.723280272360868, + -5.873894822531751, + -3.9001274851396603, + -2.864020557969236, + -3.0437268859113056, + -3.378957631409927, + -3.025895045773531, + -4.453954511020251, + -3.2378141228355, + -3.665641058957931, + -4.027093737354205, + -2.8348411401149938, + -3.6170253833130657, + -3.515816377427108, + -3.3075541647162128, + -2.4372214508664114, + -4.777392049833816, + -4.140660782802788, + -3.1730505643785434, + -2.815663506206092, + -3.2276574152308997, + -3.555497036090127, + -3.842738952091671, + -3.0066376029600383, + -2.4768098330601873, + -2.8601246281871204, + -3.6808475695866547, + -3.0947601508507914, + -5.766898434448589, + -3.826300718021746, + -2.790990711693779, + -2.8309298777277423, + -2.5424558955667678, + -3.2636528704439765, + -3.601570755058993, + -4.765363622566796, + -2.5946333907641512, + -2.9242198183574013, + -3.045820367480865, + -3.220344504575107, + -3.9515380081720424, + -3.6301469433851024, + -2.7034792131937895, + -3.6267020867550186, + -3.8028953766715303, + -3.218770806676033, + -4.135455766415258, + -4.147055274522954, + -4.518506530466438, + -4.28703378830137, + -5.403116801730231, + -3.455817662769439, + -4.581800151545618, + -3.79125271269986, + -3.321249959504698, + -3.770648800827441, + -3.824000501129554, + -3.038831569446251, + -3.7452051386327327, + -4.948872524547616, + -3.4263591073561703, + -3.0468590770909874, + -3.6605991425953124, + -2.4303622600272394, + -2.895647880448917, + -2.606381412411307, + -3.9788465897707175, + -4.229149461315182, + -3.044078039558265, + -2.708024287590895, + -3.775545479983059, + -3.7081403609414116, + -2.925826833773082, + -3.027806578889396, + -2.5798959261946277, + -3.74514066953796, + -4.162059683656712, + -2.843236572651132, + -2.8558176447098673, + -2.7724520085565665, + -3.5721368665964217, + -2.512442718598315, + -2.978723518105151, + -3.143884176780793, + -2.407393152885952, + -4.865470759787739, + -3.544959169262778, + -3.3774236021776387, + -3.12693862256356, + -6.205495634730928, + -8.688318975449457, + -5.969784356131641, + -9.162598971670928, + -5.345457170800265, + -8.27970878394043, + -8.688318975449457, + -4.204187117838422, + -10.990904068443502, + -5.287121593787302, + -8.287318182713443, + -10.06670782769691, + -5.1375551302269, + -8.799890751106563, + -7.632149502947986, + -8.76020948760796, + -7.437794800965338, + -6.120103619212503, + -8.157690724387287, + -10.990904068443502, + -9.199144599215447, + -5.287121593787302, + -9.238405611100909, + -4.675546066921168, + -8.425954710981966, + -10.990904068443502, + -10.297756887883558, + -4.204187117838422, + -6.445388549022899, + -5.780675980622457, + -4.069245884292374, + -9.04499391938819, + -5.480541415779801, + -4.675546066921168, + -9.199144599215447, + -10.759855008256855, + -7.898504048625651, + -9.04499391938819, + -6.070923142615378, + -6.1951135228467615, + -6.865724592704856, + -9.604609707323613, + -5.072355788261287, + -6.934571126393389, + -4.949186080932575, + -6.34878487007699, + -10.297756887883558, + -7.145532486672567, + -8.475685107747285, + -6.180938921112855, + -6.634195241753911, + -4.5980773121676215, + -4.99196750649682, + -3.178071633199319, + -3.3039700195149346, + -4.847214331326125, + -2.8519590935356645, + -3.2659305124315536, + -2.7324275494906867, + -5.04256666175085, + -3.5916550696802014, + -2.8292177250562816, + -4.205853609888383, + -3.283859291074738, + -3.904769936948102, + -2.8927616956800377, + -4.226918982614356, + -4.916076737084944, + -3.6361007135703134, + -2.975633047427797, + -4.8017184910751265, + -3.9123607047250206, + -4.125410781425218, + -2.603581908264503, + -3.4956175469761877, + -4.11777868647891, + -3.6185923652663985, + -3.741734971332866, + -2.7670936790502103, + -2.696604784571386, + -2.834459119816218, + -3.3077132688530453, + -4.037898839016273, + -3.4382825008904048, + -3.1285188155278183, + -4.077469551121024, + -4.3103774027888795, + -2.353040905168533, + -4.2670567066958585, + -3.2938237065279554, + -3.1672781676907324, + -5.594333980670749, + -4.074879750192322, + -3.5311486399466303, + -3.0847231017869334, + -5.039976282195842, + -3.5963745179471855, + -2.4547668193396803, + -4.9906220065026385, + -2.61207442238876, + -5.335938399443143, + -3.062431158973826, + -3.875939267118757, + -3.513851588264029, + -2.3960983127306696, + -2.9211524003047566, + -4.416895013209846, + -3.236023321730735, + -3.072099299851053, + -3.5844799940187655, + -3.544805381452628, + -3.1660697915277187, + -2.8155095365073857, + -3.2553918189347026, + -3.119718147578123, + -3.295597777808434, + -3.2703770041676483, + -3.810695850673858, + -3.1139356376119767, + -3.331766127068447, + -4.259466212684059, + -4.1196769130800375, + -3.9790502258704317, + -3.755503572429544, + -3.10912471900964, + -6.263527936412135, + -3.2420880119566586, + -3.403087517142161, + -2.9227461639427177, + -2.8798454301056466, + -3.998551024015851, + -3.7359032833771146, + -2.710837437464036, + -3.1464983803094584, + -6.267893941840705, + -3.545913958410074, + -3.922938178960754, + -3.1610088495547513, + -3.832118580662192, + -4.1723957402062535, + -4.7315596030474465, + -5.980880525641957, + -2.5259199484208064, + -5.000033398253561, + -3.199183120967335, + -3.1200893111143415, + -4.924170799806178, + -5.361040443622538, + -3.670145878162427, + -5.285379114623528, + -3.4352940917175743, + -2.704979483975623, + -2.6523384681949453, + -4.093617714875559, + -3.811818923890871, + -2.8159148242705005, + -3.555761307432409, + -3.860037231404695, + -3.62691463508373, + -3.2505077539149814, + -3.1794498701952394, + -3.6664645257157664, + -3.017609660493767, + -3.4840125153848183, + -3.279794625996706, + -4.458657560529954, + -2.5582397641288956, + -3.248973131252304, + -4.284797986282889, + -4.831692987358463, + -3.679489041219064, + -2.995537555461323, + -2.8673641993112806, + -3.4184302377138707, + -4.497845877530054, + -3.34741839099379, + -5.358106740973877, + -4.636581531783482, + -2.9630997628221496, + -3.133056492174196, + -3.2970898955643433, + -3.3876791315233166, + -5.429760450097533, + -3.9784180506403275, + -4.265494693468928, + -3.226800344981273, + -3.4600189570802455, + -3.1461238254164114, + -4.577305791955746, + -3.257145652335341, + -4.7295955810962536, + -3.518588976657548, + -3.5740519090936598, + -3.3165307815860485, + -4.539377468274664, + -4.252997995600797, + -2.610999376815829, + -4.29868099095274, + -3.4544861856899023, + -2.8958135370861897, + -3.6300681178174847, + -3.2947476896015107, + -2.7677233844318385, + -3.4159960342905116, + -3.9033579984217863, + -3.2122548832366227, + -3.6118085888816696, + -3.5202713637600502, + -4.726890338905191, + -4.475397044280999, + -4.1164043086071125, + -2.5748427483954246, + -4.5040843824810715, + -3.644987403971113, + -3.809339093861836, + -2.6630262973779657, + -2.6347040533518618, + -4.4269901510738805, + -2.6798403281444174, + -3.32645903156467, + -3.98997402904425, + -3.7394625005553257, + -3.0504416089748663, + -3.283563894226091, + -3.272791643556037, + -3.0789498884128497, + -4.117246402908323, + -3.945050904098832, + -4.910200849390139, + -4.762514314114868, + -3.3671623845053165, + -2.7454889901951134, + -5.584245902471655, + -3.7197307393759784, + -3.6015979711933164, + -3.1783110991077383, + -3.6219720721271615, + -3.9243293328192266, + -3.5453524379973067, + -2.513686262054179, + -3.945250396224724, + -4.1561987359992125, + -3.8063673282440997, + -3.6329055602308453, + -3.102893585472009, + -2.8965228061991883, + -3.237424892469513, + -3.240085842686283, + -4.5140265918588085, + -3.7829114676280846, + -6.373320486531659, + -4.924554747691045, + -3.457188301037662, + -9.892291779775393, + -7.597545593140962, + -4.204187117838422, + -4.204187117838422, + -9.748450743549503, + -6.972772463842477, + -5.400405088840604, + -4.204187117838422, + -9.892291779775393, + -8.593008795645133, + -4.069245884292374, + -9.199144599215447, + -6.070923142615378, + -4.675546066921168, + -6.599869690441965, + -8.184340015249468, + -7.39134543514694, + -4.069245884292374, + -7.812850238095558, + -8.154785987527157, + -9.381466156009402, + -9.395073487516155, + -9.381466156009402, + -6.412603082072411, + -6.647098646589819, + -7.9695181145108025, + -6.980768832033883, + -7.536027427621098, + -8.406422247156964, + -5.521852243818202, + -10.990904068443502, + -9.199144599215447, + -4.069245884292374, + -4.686455266021522, + -6.070923142615378, + -9.892291779775393, + -5.287121593787302, + -5.583732296983384, + -8.894761514984747, + -4.204187117838422, + -8.425954710981966, + -6.185170692431708, + -9.04499391938819, + -9.04499391938819, + -4.069245884292374, + -9.193028219659382, + -8.221586553353164, + -9.604609707323613, + -7.391438448099416, + -6.502267698711363, + -4.069245884292374, + -4.675546066921168, + -8.505997418655502, + -4.204187117838422, + -5.287121593787302, + -8.394425642998398, + -8.218315346203722, + -3.369570316128333, + -3.98993504645741, + -4.224220158585577, + -3.972263664150552, + -2.5865095995095126, + -2.5289954312110305, + -2.7108215362969696, + -6.738205588803674, + -3.176592093517996, + -3.6621418096281304, + -3.2880751579357925, + -3.9321717710349455, + -3.1471413683684704, + -4.27571807499137, + -3.292978816039717, + -4.075688787184894, + -2.7945587222034622, + -3.95747448717255, + -3.9105964572343233, + -2.3561832571822667, + -2.870882067284882, + -3.0542891395638483, + -3.268156224245198, + -3.6328155128850836, + -2.929290616798424, + -2.9177939296128224, + -3.0652679082051786, + -2.739924732295687, + -3.127714874201595, + -3.4451445555174582, + -3.844676531087205, + -3.7730237859125375, + -3.095754246749377, + -3.149295915523904, + -5.288167737887778, + -4.574442317499892, + -3.9486255661998397, + -4.722331524284838, + -3.583468867933753, + -2.504326716244509, + -4.201460652056411, + -3.630522459830593, + -6.536563718180551, + -4.232968204196772, + -3.071262925605747, + -4.5063519935268355, + -4.622991285170818, + -4.352099745429499, + -2.9026199344697843, + -3.344628869924247, + -3.0717693559554493, + -2.89268316817095, + -3.081603653806289, + -3.2596720832754085, + -4.343102819505142, + -3.452661093243595, + -2.724263875149259, + -4.765774803031926, + -2.6555312541907714, + -3.1323228498603757, + -3.1415031593663127, + -4.503777672968806, + -5.036197944435214, + -2.6464027537820813, + -3.608648137888546, + -3.832577568187873, + -5.722906627533547, + -2.9969154191490768, + -3.5341293367676423, + -3.0746737022096227, + -4.073684972799536, + -2.543037735204709, + -4.378274421795375, + -4.4240215395342775, + -3.7652980847406385, + -3.6215744669319574, + -3.072102113903773, + -4.867161542369275, + -4.925332323631037, + -3.7332950891863894, + -3.3055390995604976, + -2.991202384948729, + -3.1402388660444536, + -2.687350626621294, + -2.9893733411957903, + -4.285181040032797, + -3.516180669346731, + -3.4893510972655912, + -3.1866176900134024, + -3.233843037631297, + -3.6145735150360214, + -2.9373314882354458, + -3.8210406133256587, + -2.499955700289428, + -3.151170335873746, + -3.343506856053449, + -4.546243994946654, + -2.899387225442035, + -4.085156690932859, + -2.8716055862750833, + -4.017465514366687, + -3.0330356111465946, + -3.193447774714931, + -3.0540894345694443, + -3.8422024494980653, + -2.9733474768786246, + -3.694141884038275, + -3.8822745505791194, + -4.421304448905856, + -2.9260278100622084, + -4.620974613857936, + -3.0257294793813836, + -2.615078494716077, + -3.918760602560171, + -4.022713371378231, + -3.3671691340283885, + -2.1791622939055966, + -4.011405332364542, + -4.027101997639656, + -3.7469633634915462, + -3.338299335006134, + -4.307610495820696, + -3.609564111288277, + -3.6046054954698588, + -3.9082506916708235, + -3.2606273795786227, + -3.9683180038801424, + -3.5530523089412807, + -4.187535412642325, + -3.07859732475049, + -2.6450969780174884, + -4.559225026059645, + -4.081877237096246, + -3.893310788447857, + -2.5346289230445525, + -4.958705744889721, + -3.273604295004328, + -3.5475014721179856, + -2.9253153453120855, + -3.6221252926449394, + -3.4842007802150063, + -2.9968849462837808, + -3.049521272902804, + -3.3453089034150767, + -4.433941221860399, + -5.292790941711613, + -3.4303433064409545, + -3.9795371373309893, + -3.7389477337508574, + -2.790263613306635, + -3.5435832374082388, + -3.2498058055593813, + -4.478407510281282, + -3.0679269408146816, + -2.72470780374366, + -3.0772614649148453, + -2.9926792129182607, + -4.003964449230879, + -5.125857850798987, + -3.9548168281257077, + -2.7008495894401343, + -3.266483281775346, + -2.960027320510093, + -3.124435594466154, + -5.227324521744782, + -3.0630999012202125, + -4.397448297105727, + -6.929600427524881, + -4.387019147560462, + -3.705121612684605, + -3.6163937046210113, + -4.350220423398714, + -2.3912319974894354, + -3.284226443154036, + -4.616488735526409, + -2.9510094254636012, + -3.1826427940718314, + -3.6407616069802753, + -3.500520793085434, + -2.773936686354303, + -3.306526732106303, + -3.2619929860220296, + -2.7392323247789516, + -3.918035207478641, + -3.8722839648412166, + -2.807136750080733, + -3.5030782054552727, + -3.9142759279498653, + -3.1215608661577585, + -3.751877268556181, + -4.632121891230778, + -4.058776089064566, + -4.03998895077011, + -2.7638578043657107, + -3.0706536024513578, + -2.9127102402007305, + -3.5916458072908375, + -2.9054786192867246, + -2.7810010232015756, + -6.008405350400943, + -2.985264494286478, + -2.709560185330637, + -2.8185604998547835, + -3.2270072731075268, + -3.052895223600903, + -3.659099989660078, + -4.027067522237544, + -6.043287911656067, + -3.8682812098264674, + -4.558020153081215, + -4.712558017671797, + -2.78697509795851, + -3.619521113383798, + -3.067773409928519, + -2.2919816955797563, + -2.8941356236646034, + -2.7379226208762737, + -2.7005965269663506, + -5.230651321275127, + -2.8633436958610345, + -2.6327662226055546, + -2.8535765200405145, + -3.2484123651786136, + -2.715234436152119, + -4.820574931132307, + -3.342031008987572, + -3.789442275554876, + -4.778831266767093, + -3.9258988086842597, + -2.9297677596365435, + -3.2387368626506605, + -3.6336201679460403, + -4.963403359517846, + -2.842755038756338, + -3.265544190070377, + -3.095519868686835, + -2.998892070693351, + -2.8886621989382246, + -3.699725709746888, + -6.123369472694344, + -3.0288423859254983, + -3.4006482656120967, + -3.4276092519550154, + -3.3987057687931066, + -3.889826491590276, + -4.804404279018698, + -3.2881776502703675, + -4.064120658377809, + -3.5585324572213124, + -6.135395183300872, + -2.4052903144383353, + -4.88204145392539, + -3.0262338070908545, + -4.217985793475493, + -2.8966951248844754, + -3.979933338358928, + -3.243661271408706, + -3.8802534884664217, + -2.795005950662273, + -3.738825073817274, + -3.4377500838541843, + -4.529252144886229, + -4.447724672550103, + -3.23538988509084, + -2.3070533306176633, + -3.7913862986266578, + -3.711173279135655, + -3.179535303741333, + -3.1030287833907555, + -3.1407667004216373, + -3.349812700362202, + -5.580936852409235, + -3.749575824806921, + -3.9834803963663443, + -2.371915674085441, + -3.155820992134027, + -3.1695012242767135, + -2.8291461551842576, + -2.702754561418992, + -2.6307924787066255, + -3.3314351464953176, + -3.1213684390096432, + -2.879799672575224, + -3.352393576717118, + -3.513807307337333, + -2.364075741521736, + -3.605439515890635, + -3.3509045417491152, + -2.520415994018192, + -3.7216363137913477, + -3.245805232404224, + -5.234364618648984, + -3.8648820889428834, + -3.3287346707059218, + -4.526366554014932, + -2.832559826978672, + -5.895360809193407, + -2.902504699600596, + -2.445261589629517, + -4.071734951657978, + -4.790975361144749, + -4.675546066921168, + -4.691975096652612, + -5.541430170398421, + -7.445865650555458, + -7.688576921180041, + -5.287121593787302, + -6.354645124365429, + -6.070923142615378, + -8.903710433495684, + -9.892291779775393, + -9.604609707323613, + -8.157690724387287, + -8.688318975449457, + -8.03551790434853, + -9.748450743549503, + -4.675546066921168, + -8.505997418655502, + -5.129639181952276, + -8.911462526763668, + -8.593008795645133, + -5.287121593787302, + -4.204187117838422, + -7.175451008414249, + -4.906404655368331, + -9.892291779775393, + -4.675546066921168, + -5.287121593787302, + -6.557824822301045, + -9.604609707323613, + -7.238983695094028, + -9.83961152194648, + -8.425954710981966, + -10.990904068443502, + -10.990904068443502, + -4.069245884292374, + -10.990904068443502, + -10.297756887883558, + -5.471466902860732, + -9.381466156009402, + -3.480473512065496, + -9.892291779775393, + -4.99196750649682, + -6.451590214275017, + -4.069245884292374, + -5.97677221457124, + -4.069245884292374, + -7.49210607695254, + -9.636878967892397, + -4.3199627560507725, + -9.519434486249954, + -10.990904068443502, + -9.04499391938819, + -9.098809251484372, + -10.990904068443502, + -4.675546066921168, + -9.892291779775393, + -6.8965595062214025, + -6.007813757506227, + -4.204187117838422, + -5.585426864409456, + -4.204187117838422, + -7.464543543827341, + -4.675546066921168, + -8.01558279214964, + -5.287121593787302, + -7.772028243575302, + -5.418750036265738, + -10.441597924109448, + -7.082006599807537, + -8.688318975449457, + -9.381466156009402, + -4.906404655368331, + -8.793679491107284, + -7.94638163072008, + -9.311755375063258, + -8.852571008935476, + -9.892291779775393, + -9.445382841764346, + -4.675546066921168, + -4.686455266021522, + -6.75992260884677, + -4.686455266021522, + -8.425954710981966, + -4.96745647548247, + -5.179763075466803, + -4.686455266021522, + -4.069245884292374, + -9.708429389712734, + -5.02501366953637, + -6.562573599934878, + -4.842435772525856, + -6.498933304472853, + -7.189919289525264, + -5.418750036265738, + -6.070923142615378, + -7.948654361905916, + -7.873698705584317, + -5.179763075466803, + -4.069245884292374, + -8.911462526763668, + -4.675546066921168, + -6.908933591065999, + -7.048239448806907, + -10.990904068443502, + -9.604609707323613, + -10.990904068443502, + -7.392186391395208, + -9.430193659402097, + -10.990904068443502, + -9.969843266302668, + -7.49210607695254, + -10.297756887883558, + -6.725356020150889, + -8.199155914052653, + -8.317480577503757, + -5.814754335869674, + -4.204187117838422, + -4.7748221443193435, + -8.047852052718426, + -7.948654361905916, + -4.863464543195543, + -10.990904068443502, + -8.425954710981966, + -10.297756887883558, + -6.748982462576161, + -8.74099923327837, + -6.509798800987668, + -5.949627160138798, + -6.832020985083831, + -7.950405228871191, + -4.069245884292374, + -7.981607461195385, + -8.046465089277062, + -9.821958811028061, + -5.145585863840253, + -9.258036117043641, + -4.681000666471345, + -5.345457170800265, + -4.204187117838422, + -9.11864703588798, + -7.617930248183408, + -7.314047519424809, + -7.812850238095558, + -9.040486976257393, + -9.604609707323613, + -6.107585883550037, + -7.833225067682335, + -8.056255611876615, + -6.725356020150889, + -9.604609707323613, + -6.1951135228467615, + -9.381466156009402, + -4.686455266021522, + -5.814754335869674, + -9.25803611704364, + -7.530074976367938, + -8.729066382573073, + -5.287121593787302, + -8.157690724387287, + -4.827928420180095, + -8.314209370354316, + -9.892291779775393, + -6.557119901840283, + -9.378810099459676, + -10.990904068443502, + -4.069245884292374, + -4.438259630348392, + -8.157690724387287, + -10.759855008256855, + -8.688318975449457, + -7.991435787470161, + -10.297756887883558, + -8.593008795645133, + -7.298288606910217, + -9.892291779775393, + -4.675546066921168, + -4.906404655368331, + -4.069245884292374, + -9.892291779775393, + -9.83961152194648, + -8.746585883577433, + -5.345457170800265, + -4.069245884292374, + -8.218315346203722, + -3.594102847043504, + -9.604609707323613, + -4.7748221443193435, + -4.675546066921168, + -9.04499391938819, + -7.6032210229753066, + -10.990904068443502, + -10.990904068443502, + -4.204187117838422, + -8.55236400583467, + -4.937675904869518, + -9.83961152194648, + -9.361855799432762, + -4.204187117838422, + -8.37668024345035, + -6.760563966959066, + -6.749706725506732, + -4.204187117838422, + -5.5573864207705395, + -7.597545593140962, + -10.990904068443502, + -7.162232450793988, + -9.892291779775393, + -5.135093781502453, + -9.199144599215447, + -4.069245884292374, + -4.675546066921168, + -4.96745647548247, + -9.892291779775393, + -6.793504296842418, + -10.297756887883558, + -7.735320392122618, + -4.069245884292374, + -7.143935405688866, + -6.213770689032818, + -8.351846738828245, + -6.962559296059131, + -8.72573568665849, + -9.199144599215447, + -4.99196750649682, + -4.7524989297368885, + -9.890249386851156, + -9.604609707323613, + -8.708729972709584, + -9.199144599215447, + -6.195968019414582, + -4.818484132013528, + -6.591940124253086, + -6.088929626778312, + -8.075560008045574, + -5.287121593787302, + -10.196390610856517, + -4.439866592379795, + -9.604609707323613, + -5.179763075466803, + -10.297756887883558, + -5.898303996356202, + -5.615625660759338, + -10.297756887883558, + -7.589706686781348, + -7.097661665074788, + -4.675546066921168, + -7.836088035078003, + -5.37868920431845, + -5.235816373470283, + -10.297756887883558, + -10.759855008256855, + -7.119703057535612, + -10.990904068443502, + -7.815559454033972, + -7.287252653071396, + -8.427323013929547, + -4.675546066921168, + -5.345457170800265, + -10.990904068443502, + -4.96745647548247, + -6.1951135228467615, + -10.990904068443502, + -9.494931242210498, + -8.394425642998398, + -5.168712338648543, + -8.351846738828245, + -5.345457170800265, + -6.925727294727883, + -9.604609707323613, + -7.812850238095558, + -8.046465089277062, + -9.381466156009402, + -5.583732296983384, + -9.892291779775393, + -10.258495875998095, + -7.018698846600785, + -4.204187117838422, + -4.57407468852271, + -5.418750036265738, + -5.7979472175532925, + -5.199650320342592, + -5.930398570507752, + -9.18544511212139, + -6.725356020150889, + -6.231835763645386, + -4.99196750649682, + -9.604609707323613, + -10.990904068443502, + -7.21485498748376, + -9.892291779775393, + -7.79243924083543, + -4.204187117838422, + -8.426258293273746, + -4.204187117838422, + -9.892291779775393, + -6.698248886558443, + -9.04499391938819, + -5.8679286256421515, + -7.838679667232512, + -6.2393436689309665, + -5.201578511568273, + -9.892291779775393, + -4.675546066921168, + -6.243520492589857, + -5.287121593787302, + -8.627545123184806, + -7.597545593140962, + -7.79243924083543, + -5.345457170800265, + -10.990904068443504, + -9.242650287710262, + -4.686455266021522, + -9.199144599215447, + -4.204187117838422, + -4.6454796620460135, + -6.1614476306944015, + -7.697260006230687, + -5.453086840050183, + -9.604609707323613, + -4.069245884292374, + -10.297756887883558, + -4.204187117838422, + -8.171540002452156, + -7.486651477402363, + -9.381466156009402, + -7.56381028475445, + -5.838639553585739, + -8.157690724387287, + -4.271345945168639, + -4.136716501065398, + -6.266428979719732, + -9.574297396415394, + -5.615625660759338, + -5.185941505499414, + -10.990904068443502, + -9.430193659402097, + -5.260804285469929, + -5.629056499528822, + -8.505997418655502, + -4.99196750649682, + -5.287121593787302, + -4.204187117838422, + -4.675546066921168, + -8.4316162348841, + -8.168180619621884, + -9.381466156009402, + -10.297756887883558, + -6.121686064989939, + -7.556776517541041, + -9.604609707323613, + -10.297756887883558, + -5.376219964895804, + -10.990904068443502, + -6.017275086723193, + -7.759488432979867, + -5.583732296983384, + -5.7979472175532925, + -8.225058301038219, + -4.675546066921168, + -8.425954710981966, + -7.404914666341607, + -6.134740544906018, + -3.795312454793672, + -7.026706134308772, + -5.29457748445068, + -4.780122335841837, + -9.381466156009402, + -4.5184264172269195, + -4.069245884292374, + -5.287121593787302, + -9.381466156009402, + -9.04499391938819, + -5.287121593787302, + -6.500167733256821, + -7.426526387243467, + -4.627351731676345, + -4.069245884292374, + -9.199144599215447, + -9.892291779775393, + -6.070923142615378, + -4.686455266021522, + -8.425954710981966, + -7.816462526013442, + -6.586494960540353, + -6.548252811953186, + -9.381466156009402, + -5.287121593787302, + -7.93850745223601, + -9.671375403635874, + -10.990904068443502, + -4.906404655368331, + -7.231871977826964, + -6.198456502626994, + -5.7979472175532925, + -4.069245884292374, + -4.204187117838422, + -9.604609707323613, + -10.095024333829475, + -6.604736593770102, + -5.125930913084298, + -7.235688790254499, + -5.558842257629964, + -5.583732296983384, + -8.793679491107284, + -4.5980773121676215, + -7.597545593140962, + -4.204187117838422, + -8.59715819705248, + -8.131411928499125, + -6.139301483810411, + -9.199144599215447, + -6.1951135228467615, + -5.262610123133534, + -4.204187117838422, + -7.732807530422021, + -9.892291779775393, + -4.99196750649682, + -7.363461663404834, + -7.695067202439174, + -9.604609707323613, + -8.911462526763668, + -9.199144599215447, + -5.488855146510048, + -4.99196750649682, + -5.287121593787302, + -4.675546066921168, + -5.393919266363052, + -5.287121593787302, + -10.990904068443502, + -8.139012831115402, + -5.832794803672686, + -8.793679491107284, + -10.297756887883558, + -6.070923142615378, + -4.686455266021522, + -4.99196750649682, + -7.624333396943811, + -8.593008795645133, + -7.271268889382751, + -9.381466156009402, + -10.990904068443502, + -9.892291779775393, + -6.376465279009416, + -6.031918859707652, + -4.7439979602790565, + -9.892291779775393, + -7.407385129987393, + -6.623922186266749, + -4.906404655368331, + -4.069245884292374, + -9.04499391938819, + -10.64433047816353, + -7.106214763686511, + -10.990904068443502, + -6.922800632107901, + -4.99196750649682, + -7.457527860993392, + -4.675546066921168, + -4.069245884292374, + -5.1892224366590085, + -9.04499391938819, + -4.647702338381058, + -7.838679667232512, + -10.441597924109448, + -4.96745647548247, + -8.659935747017673, + -4.069245884292374, + -10.297756887883558, + -4.069245884292374, + -4.204187117838422, + -8.351846738828245, + -4.949186080932575, + -4.316326356350655, + -6.498933304472853, + -5.3314832799153145, + -8.688318975449457, + -6.8965595062214025, + -4.936930565425401, + -5.287121593787302, + -7.623608238457029, + -5.222386635963352, + -6.240145901602393, + -9.604609707323613, + -4.675546066921168, + -4.069245884292374, + -7.923526578079782, + -4.99196750649682, + -8.093062714724557, + -4.069245884292374, + -10.990904068443502, + -5.583732296983384, + -6.557824822301045, + -4.675546066921168, + -4.069245884292374, + -10.990904068443502, + -6.658269913702703, + -8.351846738828245, + -8.449364406390371, + -10.990904068443502, + -8.351846738828245, + -10.64433047816353, + -7.9611367205771275, + -9.892291779775393, + -10.990904068443502, + -10.990904068443502, + -4.774332213541137, + -5.345457170800265, + -8.557136843215712, + -10.990904068443502, + -4.204187117838422, + -9.199144599215447, + -6.942799932618485, + -4.99196750649682, + -4.204187117838422, + -6.153731021508424, + -8.688318975449457, + -4.675546066921168, + -8.320660098061047, + -5.946854991376726, + -7.701278462438452, + -6.836927795807993, + -4.204187117838422, + -10.990904068443502, + -5.7979472175532925, + -5.709830112456372, + -4.99196750649682, + -4.99196750649682, + -7.383705191704482, + -5.285059186498827, + -4.204187117838422, + -6.836927795807993, + -9.381466156009402, + -10.990904068443502, + -4.678183739039838, + -4.697994074815186, + -5.615625660759338, + -9.04499391938819, + -4.204187117838422, + -5.935978516538342, + -10.990904068443502, + -8.315514003461361, + -10.297756887883558, + -10.990904068443502, + -10.297756887883558, + -7.183501386087967, + -8.911462526763668, + -9.892291779775393, + -10.990904068443502, + -5.345457170800265, + -9.74501419568238, + -4.826489090637879, + -10.990904068443502, + -7.589706686781348, + -4.906404655368331, + -6.951765308468597, + -8.157690724387287, + -4.204187117838422, + -8.351846738828245, + -9.493037931666507, + -4.781019880113052, + -7.7808331550261425, + -8.746585883577433, + -8.24643520536516, + -5.583732296983384, + -8.793679491107284, + -4.069245884292374, + -4.96745647548247, + -9.892291779775393, + -4.675546066921168, + -5.051725465294846, + -8.240843626473223, + -4.675546066921168, + -5.814754335869674, + -4.204187117838422, + -7.793710371379009, + -10.297756887883558, + -4.968915318941284, + -6.590771742788335, + -10.441597924109448, + -4.906404655368331, + -5.929946797228749, + -9.199144599215447, + -7.431992051066766, + -10.990904068443502, + -6.431462687699829, + -5.615625660759338, + -4.204187117838422, + -4.204187117838422, + -5.814754335869674, + -5.345457170800265, + -9.381466156009402, + -4.96745647548247, + -6.502267698711363, + -7.486651477402363, + -5.345457170800265, + -6.286595420663371, + -9.976063255869027, + -10.990904068443502, + -5.482902695256888, + -4.069245884292374, + -4.372395975606771, + -10.990904068443502, + -5.936551963244265, + -10.990904068443502, + -4.204187117838422, + -10.297756887883558, + -10.297756887883558, + -8.258850355349201, + -7.995171794889512, + -4.686455266021522, + -10.017948993915846, + -6.267494204992006, + -10.297756887883558, + -10.297756887883558, + -5.884661591374206, + -6.365931255159232, + -4.686455266021522, + -5.287121593787302, + -8.766927493071378, + -5.615625660759338, + -9.671375403635874, + -9.604609707323613, + -6.787641776044212, + -4.839211386259171, + -9.01528220915279, + -9.381466156009402, + -4.686455266021522, + -9.3248018133559, + -6.819484166307774, + -9.604609707323613, + -4.204187117838422, + -4.675546066921168, + -5.236746642237231, + -5.583732296983384, + -7.530074976367938, + -3.0160271678846273, + -4.439866592379795, + -8.999517675161005, + -5.615625660759338, + -9.381466156009402, + -6.840355891015646, + -7.582961187706047, + -5.1375551302269, + -9.604609707323613, + -5.583732296983384, + -4.99196750649682, + -10.493922738485903, + -4.96745647548247, + -7.855409852514353, + -6.398597956741778, + -7.637393704648138, + -10.39365091203415, + -4.9813338303542345, + -7.995822853433647, + -8.688318975449457, + -7.915034316909959, + -4.204187117838422, + -6.901785443794478, + -7.690968818837085, + -7.732807530422021, + -4.204187117838422, + -4.204187117838422, + -7.9695181145108025, + -8.388900724905106, + -4.069245884292374, + -5.723478351517272, + -4.906404655368331, + -4.906404655368331, + -5.287121593787302, + -4.259900231306686, + -5.721483635361493, + -5.800409496291412, + -2.8396910310835772, + -3.5404673851104134, + -2.965617485107393, + -2.742737712043993, + -3.332566922221791, + -4.324183721506706, + -3.299024575914676, + -3.5409373141221807, + -4.182099138539746, + -2.6444922082647158, + -3.0595524810673638, + -3.0958643135325525, + -3.078720464313627, + -3.623810485209596, + -3.7997912822055806, + -3.6617359933286635, + -3.6832037620435454, + -3.335780631536016, + -4.339950729085924, + -3.0970638865613207, + -3.3697730986735204, + -3.291879217263994, + -3.167854287044473, + -2.8092496541966074, + -3.546399053801505, + -3.112745471592176, + -3.721075260372036, + -2.9170873766031002, + -4.883640688579154, + -3.510132517551704, + -3.4447638239622425, + -3.6218220069142975, + -2.9555711931992654, + -3.489170499529089, + -2.9287369236243257, + -3.5021113237033856, + -2.86069636439899, + -3.840197431906357, + -4.886013075523563, + -4.836360133334326, + -5.4210332161003745, + -3.061219648970026, + -3.9967907967742287, + -3.234283729164858, + -4.093223602458883, + -3.802214975633669, + -3.8566074470728307, + -3.4753279496134613, + -5.836809952470182, + -4.208257144349245, + -3.797314187400199, + -3.5061500487469752, + -3.4586973586301806, + -3.081768835792118, + -3.017394358936359, + -5.266286301618287, + -3.3040445208655242, + -3.161681342294002, + -3.663676998384025, + -5.567484704384731, + -3.237527486238247, + -2.857780063815299, + -4.040669086812073, + -3.408621171545791, + -4.082797759771721, + -3.1023505965751226, + -3.8439141009547613, + -3.3701021916211835, + -2.8550429026527127, + -4.210464947253015, + -4.13033267341425, + -3.0853383252320317, + -3.2153845162376835, + -3.6282669413479485, + -3.8992390177661083, + -3.212995426389697, + -2.964374037298417, + -3.397019874348614, + -2.938496202657633, + -2.83477628934542, + -3.969746684511647, + -2.9106707618977055, + -3.7414776340014835, + -4.5535008869310225, + -2.889149233549569, + -3.7059289296499975, + -3.0961764736201416, + -3.6078336157923467, + -3.536407391629747, + -4.034584303616439, + -3.5343723930689506, + -2.505262260705536, + -3.9692200881121558, + -3.322725416580357, + -3.279929258127732, + -3.3573323267799937, + -4.516129462905497, + -3.027075388955165, + -3.5288636538331883, + -6.477450998928098, + -3.3071301809667353, + -4.707766946151625, + -2.7321428997370765, + -4.713747060405962, + -6.008542160697132, + -3.006213850498786, + -3.6280825246823, + -3.3504690116250893, + -3.3783762263736197, + -3.412384172756899, + -3.6716573173302347, + -3.8415967749650712, + -3.1644666761992397, + -2.918750849832394, + -4.850488621776466, + -2.6162617896464466, + -3.3069410836789626, + -3.641191211893478, + -4.886682805265054, + -4.106026124593161, + -3.037444736346877, + -2.741696023545341, + -5.28990705087953, + -2.726656173592514, + -2.8639026227870286, + -3.318193630268395, + -4.099620361433725, + -3.5195553166414726, + -3.2983969715150927, + -5.027904137533961, + -3.075589994470028, + -2.8309148343406325, + -3.4530170427960987, + -3.3703991455446802, + -4.782463763101259, + -3.0198386264110253, + -4.66343879521941, + -2.8087569395421705, + -4.186450780000748, + -4.039692569774946, + -3.8559994817992, + -3.4315922076597856, + -3.4706555267818673, + -3.02940636877586, + -3.209314023708468, + -3.3271878791299327, + -2.9429586836134427, + -2.454442576855097, + -2.7829380925068476, + -3.26409996850182, + -3.9810575096588807, + -3.501025107065606, + -3.1332211750221233, + -4.060214222317506, + -4.60159460327129, + -3.794789469006334, + -2.9561044293568552, + -3.491779863526356, + -3.487684168230363, + -2.5273104322354025, + -3.4639366442765804, + -3.7727414785650524, + -5.266518959269313, + -4.45227544198122, + -4.24821565649367, + -2.7863744403132453, + -3.650980005274204, + -4.889697611942933, + -2.506885955560947, + -4.022162280317002, + -4.211384496400881, + -3.961564265864638, + -3.3959759539813392, + -2.9776642053087854, + -2.612407188405912, + -4.382686732747419, + -3.094567449718659, + -2.734309901774358, + -3.2370581249146673, + -2.931475891156024, + -3.91376694169168, + -3.7087649840767827, + -3.335113369664056, + -2.9709404414219622, + -4.857320884975577, + -3.9192025805545425, + -3.8205424768812395, + -3.1149459249904634, + -3.575216658637483, + -3.482066809682034, + -2.8012268241334253, + -2.989633755603181, + -7.22140846921548, + -3.168773146847357, + -3.24741627702227, + -3.5388254560263728, + -3.184267648593709, + -3.430440633184573, + -3.2660544259677096, + -3.7883486815442837, + -3.24118320857121, + -3.5645561749014743, + -3.1359077395473665, + -3.1802070671182645, + -3.13124585037381, + -3.2364305958114485, + -3.0190242944821817, + -3.729129601261601, + -3.1148697041749416, + -3.053968829961619, + -3.8668404474959552, + -3.3526381408557224, + -3.8252426091460765, + -4.756928760919315, + -4.794761370264732, + -3.4109286053438623, + -4.3457323369911505, + -2.504668660587668, + -5.814148840218429, + -4.0245587040416355, + -3.1506283968463196, + -3.6848682209497925, + -4.552775666646493, + -2.8786313501737006, + -4.494681505882289, + -3.79937689408063, + -3.305041228591221, + -3.7817602506211596, + -4.884860106642671, + -2.5827425316175776, + -3.504467936808789, + -2.8934656565802572, + -3.46670743214146, + -4.33401768716823, + -3.2412383509121647, + -3.107055731494263, + -4.249960690386782, + -3.7288593644461505, + -3.2699438051419856, + -3.3905336570951135, + -3.5251831125405184, + -3.2320495050170064, + -3.4180362332388117, + -2.9677216743334194, + -4.030061488891745, + -2.9665538582499553, + -4.021967785637737, + -2.7579149515591, + -4.083526794680076, + -3.1351519550845155, + -4.659556936423873, + -4.911150383621059, + -3.7220746618220173, + -3.3965204806486042, + -2.835495852529031, + -3.479144952869696, + -3.8522297687771156, + -3.323443307739806, + -3.246793131385513, + -2.619712011703675, + -3.8747325676444753, + -3.615555434198238, + -3.9843931436376776, + -2.9019208419458673, + -3.549696063354677, + -3.278319441435637, + -2.551062417206145, + -2.5771800131374474, + -3.605751393706198, + -3.4341606023094773, + -2.7201050326572873, + -3.185937504717045, + -4.944973882458934, + -3.241162146160036, + -3.459749786271274, + -4.010840556612418, + -3.294862662478738, + -3.1054744413223467, + -3.8154625615174056, + -2.826298221117384, + -3.3572264625065693, + -3.4371604066650554, + -2.863828812608651, + -3.8896990441028176, + -4.133810530332591, + -4.543203792302431, + -2.5461214612473704, + -4.094432128789123, + -2.2698040336951113, + -3.366089304452027, + -3.8105761826476248, + -3.9088362491971544, + -4.015402731974116, + -3.8431731843019765, + -3.70224224861233, + -3.647078497332126, + -3.026951925947394, + -3.5997116497774924, + -2.627296903024818, + -3.1411724711152833, + -2.9754317842417564, + -3.8039434451490974, + -3.574480042331284, + -3.4050514055055876, + -3.806269913020994, + -3.2353347120129965, + -3.9441670674801816, + -4.092904043113837, + -2.5646306801472747, + -4.841130617083718, + -3.1296756514852797, + -4.018492222555361, + -3.852168144131121, + -4.074044345857767, + -3.776854262147748, + -3.288325711913541, + -3.314485190162943, + -3.6218949618460936, + -2.7931418778218875, + -3.1501854010675174, + -3.449367999430487, + -3.958217748954028, + -3.1605412793924907, + -2.723881512927557, + -2.6926183746150913, + -6.313688694024079, + -3.2797190044332805, + -3.676205006342467, + -3.964161904044871, + -4.300048551366663, + -2.85050915331855, + -4.3061299967214755, + -7.602251239002143, + -3.360232758610512, + -3.8398125707360946, + -3.6978577948271703, + -3.6291380423867556, + -3.55547018410248, + -3.1099883253932314, + -2.959270600190083, + -3.1623296671879126, + -5.188574519493272, + -3.463800028537325, + -3.347484231644423, + -2.3940947155263412, + -4.237128479993016, + -2.9650333152279518, + -2.448786434973094, + -2.4374505836092273, + -2.536178870288868, + -4.201334304932923, + -3.3392835507934486, + -3.9064967636990238, + -4.100962978425629, + -5.385424842208037, + -3.7835857990463078, + -3.0293057044424323, + -3.664465481115106, + -4.111206185029612, + -3.669605397522449, + -3.5518945026882394, + -4.182100959591115, + -4.424520174377642, + -3.8596388645883932, + -3.849294159992203, + -2.8037850305025813, + -3.689122871666742, + -2.354082233194536, + -2.591131883719349, + -2.624353588855559, + -2.881374537531155, + -2.7586168114687895, + -3.0413960820214827, + -3.6426202567661985, + -2.4048373876812983, + -2.9494175185120284, + -3.0772892302904173, + -4.585361304912156, + -3.2381111806791543, + -5.043534687868332, + -4.273398262728549, + -3.1523195553983836, + -4.82175650068501, + -2.5319317003716737, + -3.088288547978155, + -3.225944282774228, + -4.540408539524238, + -2.8062607042515126, + -2.831869763129078, + -3.5541947670334366, + -4.028140401095454, + -4.4141130529328345, + -2.5417220992422287, + -3.2002449748149484, + -2.574358075913202, + -2.5036009377442054, + -3.1357656650268146, + -8.911462526763668, + -6.0782491827074505, + -9.707557611941038, + -8.939288002389395, + -4.675546066921168, + -5.287121593787302, + -4.906404655368331, + -9.381466156009402, + -10.088220668076099, + -9.04499391938819, + -7.855409852514353, + -5.738026388235738, + -5.245068476175858, + -5.345457170800265, + -8.576747199792353, + -8.437061707990663, + -5.188736898023808, + -8.911462526763668, + -5.287121593787302, + -6.364201875960575, + -9.381466156009402, + -8.838647516586116, + -8.798398655226618, + -4.675546066921168, + -5.010501618860717, + -5.345457170800265, + -6.431462687699829, + -10.369677405996502, + -7.812850238095558, + -9.708429389712734, + -8.02369109101006, + -7.838679667232512, + -4.99196750649682, + -4.686455266021522, + -8.996412045161366, + -6.700630617920695, + -6.234280286293397, + -8.769578440198345, + -5.345457170800265, + -6.070923142615378, + -4.069245884292374, + -4.99196750649682, + -4.96745647548247, + -8.425954710981966, + -9.269641047648927, + -4.906404655368331, + -7.338305588414883, + -4.466780580724555, + -4.8679698748066125, + -8.593008795645133, + -4.069245884292374, + -4.204187117838422, + -10.990904068443502, + -6.365931255159232, + -9.892291779775393, + -6.594629261354813, + -6.927223476165909, + -5.179763075466803, + -6.065992554468285, + -5.615625660759338, + -3.844223549095825, + -4.203011119863187, + -2.9220998020667537, + -3.6532509824600052, + -4.609529520639031, + -2.5850357995365894, + -4.414704549486766, + -3.5100821791364964, + -2.7943570276120377, + -3.9043662597275, + -5.447198275184384, + -3.1804642630793225, + -4.005112945570914, + -3.8725154266428423, + -2.710386882922633, + -3.4353960364953626, + -3.2950828601521702, + -3.6055256051205675, + -3.0925894103814295, + -2.3750919421852115, + -3.040749057952662, + -3.707421942279254, + -3.1758725639690675, + -3.655361358781447, + -3.78216939515153, + -5.55816365228347, + -5.012439682852234, + -2.305373275700379, + -3.1418372355681896, + -3.128000697633727, + -4.667221584861704, + -2.9955648860484345, + -5.518681670496006, + -2.4884799584610553, + -4.053439517878237, + -3.00793179599056, + -2.801393119290366, + -3.103739897954295, + -3.6154091375352286, + -4.051211380333245, + -5.685864679289209, + -3.9042671911354527, + -3.0486050921693293, + -3.778378437140347, + -3.963035935752833, + -4.311109359926578, + -3.5486020380401166, + -2.834059852409198, + -2.704887465650327, + -5.238224932465012, + -3.647141983100183, + -3.6720893632181384, + -3.2418019714227326, + -2.613800753248228, + -4.55174118094067, + -3.8350075093998552, + -3.2654972883866282, + -3.855471711031786, + -3.330642396956098, + -3.0671394042275804, + -3.4314522058224166, + -2.949954098493371, + -4.3821398977052075, + -3.378049158282248, + -2.4470172110888275, + -2.760950263303536, + -3.523581653361557, + -3.321937689987527, + -6.092689959539293, + -4.0351626205911195, + -3.6505090838475494, + -3.4315785173617868, + -2.791331290201117, + -2.640054982199955, + -4.342981544556622, + -4.167733275686202, + -2.5628294955491535, + -3.569436554795225, + -3.0332901146942564, + -3.315630727169292, + -4.2630010464792845, + -3.799953151701706, + -2.7091616983813815, + -3.3280250132520828, + -3.7390942047102365, + -2.902924349265346, + -2.856335925024906, + -3.0081339529084556, + -4.032269186510102, + -3.0157884923361307, + -3.909615410143435, + -3.416809459278432, + -2.572799405917087, + -2.7442032709276503, + -3.156115454291817, + -3.8498681906057945, + -3.440831294582231, + -3.35135982684425, + -4.903377254875946, + -3.272635447454318, + -4.148286914335638, + -2.8186055021273866, + -5.5710989461805145, + -3.0976408414948273, + -3.853639583788574, + -5.303393003098896, + -2.890834032157405, + -4.920056566437091, + -5.226584584069802, + -4.248969662314739, + -3.0115647444929112, + -4.052388096494285, + -2.6335629879832303, + -3.6992657349143654, + -4.48523592644763, + -3.696566217160219, + -2.8658818447213656, + -3.9927443282675896, + -3.361267820351768, + -2.418293019866656, + -4.224446062421626, + -3.751201085569773, + -3.565200426575891, + -3.5375188211245265, + -2.9150213656064228, + -3.6553365001068387, + -2.6790784261263565, + -3.452134540586608, + -3.0194937057553837, + -4.382360075823878, + -3.218898835765636, + -3.9882592980018647, + -4.057141798087626, + -3.4336026010209624, + -3.279756322526316, + -3.6730355426658496, + -4.980873706162694, + -2.897915375655691, + -2.896141010373753, + -3.6160644916162012, + -2.28150517724501, + -2.777800653869002, + -4.6886593855491645, + -4.718728473984306, + -2.9861597489888796, + -2.4346028620108746, + -4.652716096913911, + -2.635919608973985, + -4.503296362742799, + -4.904871462180971, + -4.7769068309375, + -3.6985504707621395, + -3.901659467452664, + -2.831389139820351, + -2.5094590517633577, + -3.794286887157338, + -3.1070495797542614, + -3.388058645642449, + -3.1976038134326914, + -3.9965117723677976, + -2.5393942750925955, + -4.983493688438234, + -3.4059656757411845, + -3.1489252405585573, + -3.4321195055740574, + -2.7987864564856375, + -4.762973757756588, + -4.776529281067838, + -3.007499665085862, + -3.136276458840303, + -3.5882391891205128, + -3.256385124150196, + -3.294640969300619, + -5.673704334488859, + -3.1940009850015567, + -4.679009842295457, + -3.638954853307366, + -3.533242494926238, + -3.0542676691643402, + -3.064907207267709, + -3.429212412141733, + -2.9017975031047865, + -3.9114639263295086, + -3.4954445052532566, + -5.459945251287892, + -2.881265207833812, + -3.977509216232098, + -4.25716522484001, + -3.906765148877628, + -3.1759421541188226, + -4.263809441116903, + -2.8708644207959306, + -2.7301369172234753, + -2.7491932297611443, + -3.1243036175817545, + -2.3960199773557442, + -3.4913191338351104, + -3.6214260718694202, + -3.385877474181248, + -5.341424131472972, + -6.557119901840283, + -6.013053856451972, + -7.048239448806907, + -7.597545593140962, + -6.139389505261415, + -9.381466156009402, + -6.836927795807993, + -9.748450743549503, + -9.604609707323613, + -9.92173753868949, + -8.45331716082659, + -8.911462526763668, + -5.245068476175858, + -5.287121593787302, + -6.548252811953186, + -8.383465728246005, + -8.218315346203722, + -10.990904068443502, + -5.583732296983384, + -10.990904068443502, + -9.604609707323613, + -4.675546066921168, + -7.128459848781967, + -4.675546066921168, + -10.095024333829475, + -4.204187117838422, + -7.812850238095558, + -6.094791019602237, + -7.009071085861206, + -4.906404655368331, + -7.778729827885814, + -6.3955450672158864, + -4.069245884292374, + -9.493037931666507, + -4.99196750649682, + -4.069245884292374, + -9.636878967892397, + -5.345457170800265, + -9.892291779775393, + -4.675546066921168, + -5.814754335869674, + -6.667344375490656, + -7.940744592433472, + -7.602080771625944, + -5.797674197832479, + -5.661322356755493, + -4.204187117838422, + -9.231809781815999, + -4.986788429904411, + -4.069245884292374, + -10.990904068443502, + -7.995171794889512, + -9.835658767510262, + -7.602080771625944, + -6.5600872696001895, + -9.604609707323613, + -10.297756887883558, + -9.258036117043641, + -9.604609707323613, + -7.528357199073246, + -5.179763075466803, + -8.452635613539812, + -4.686455266021522, + -5.287121593787302, + -5.070084513453876, + -8.46919150998388, + -6.8147856017072, + -10.297756887883558, + -7.255507181345973, + -4.906404655368331, + -10.297756887883558, + -5.7979472175532925, + -4.069245884292374, + -7.772828884258789, + -5.435426945385343, + -5.287121593787302, + -8.350634175347302, + -8.49239008714875, + -7.288713485699864, + -10.297756887883558, + -9.671375403635874, + -10.990904068443502, + -4.906404655368331, + -6.1951135228467615, + -5.245150201395421, + -10.441597924109448, + -9.199144599215447, + -4.878323349633486, + -4.679182466621286, + -9.199144599215447, + -7.028506111465285, + -8.30326486460142, + -5.287121593787302, + -10.297756887883558, + -4.639400315487551, + -6.937345333068308, + -7.9736632105540615, + -7.048593080913651, + -8.911462526763668, + -5.46712849362498, + -6.904398412581017, + -4.906404655368331, + -6.594629261354813, + -7.772028243575302, + -9.199144599215447, + -10.297756887883558, + -9.199144599215447, + -9.604609707323613, + -4.826955870751996, + -10.528805948070206, + -10.297756887883558, + -7.623608238457029, + -5.814754335869674, + -7.997579293680327, + -10.297756887883558, + -4.675546066921168, + -5.6776104628433055, + -5.814754335869674, + -9.199144599215447, + -5.345457170800265, + -4.204187117838422, + -7.732807530422021, + -10.990904068443502, + -6.469115491394462, + -4.930913645643539, + -4.069245884292374, + -9.448124945817082, + -8.046465089277062, + -8.793679491107284, + -5.583732296983384, + -7.991435787470161, + -4.069245884292374, + -4.585821796660445, + -10.990904068443502, + -4.204187117838422, + -5.456187967950997, + -4.686455266021522, + -6.696461461838672, + -8.943731787332453, + -4.204187117838422, + -8.89607669743029, + -9.381466156009402, + -10.990904068443502, + -10.990904068443502, + -4.193439083716914, + -7.8300698575201935, + -5.814754335869674, + -7.162262671954408, + -4.796429960694926, + -4.069245884292374, + -5.169618528470666, + -10.297756887883558, + -10.142519747270033, + -4.686455266021522, + -7.429874127628932, + -5.615625660759338, + -10.990904068443502, + -6.549616340575298, + -7.475033439061939, + -4.6193662864474705, + -6.717688676757176, + -9.375196250711683, + -7.991435787470161, + -5.8976245622283905, + -7.2509720028609905, + -6.351043797576094, + -5.2980309858729315, + -7.812850238095558, + -10.297756887883558, + -9.67382282891636, + -7.60389626031475, + -7.589706686781348, + -4.906404655368331, + -6.798958896392595, + -8.520082857138851, + -6.150107458132328, + -6.235377041186801, + -7.889778989129045, + -7.286033091403041, + -4.204187117838422, + -4.372395975606771, + -4.821501271201819, + -10.990904068443502, + -6.340813530455517, + -6.5890754509496405, + -10.297756887883558, + -5.814754335869674, + -7.402582154746618, + -5.345457170800265, + -6.950581611189007, + -6.882861308960524, + -9.892291779775393, + -8.296461198848045, + -10.297756887883558, + -8.093432441916914, + -6.857618263577667, + -6.860269993154679, + -4.646586662103383, + -7.289373522898457, + -5.804353376539147, + -4.675546066921168, + -8.282853867341293, + -4.204187117838422, + -4.518351179887421, + -10.297756887883558, + -8.688318975449457, + -4.906404655368331, + -9.213230037698796, + -9.892291779775393, + -7.298288606910217, + -9.381466156009402, + -4.069245884292374, + -7.812850238095558, + -4.204187117838422, + -8.140264551366132, + -8.93694962048539, + -9.199144599215447, + -5.022927258303714, + -10.990904068443502, + -6.624607394703941, + -4.069245884292374, + -9.79665170048541, + -10.297756887883558, + -4.49215472684013, + -10.297756887883558, + -5.583732296983384, + -8.793679491107284, + -5.2267019927863725, + -4.204187117838422, + -5.742768578594993, + -6.840057624389599, + -4.204187117838422, + -6.182815425690644, + -7.678209118566649, + -7.119703057535612, + -4.069245884292374, + -9.604609707323613, + -10.06670782769691, + -9.892291779775393, + -6.398597956741778, + -4.675546066921168, + -8.957464417770149, + -4.069245884292374, + -4.675546066921168, + -5.0094707268540475, + -6.502267698711363, + -5.287121593787302, + -10.990904068443502, + -4.942000110081024, + -6.856538152384633, + -9.401877153269531, + -6.489800160401483, + -9.892291779775393, + -10.297756887883558, + -5.3817476862250935, + -4.99196750649682, + -5.517751111166723, + -9.199144599215447, + -9.381466156009402, + -5.394957362025057, + -7.304216913488479, + -10.990904068443502, + -10.990904068443502, + -10.990904068443502, + -9.381466156009402, + -5.583732296983384, + -6.070923142615378, + -8.573899480560682, + -5.583732296983384, + -9.604609707323613, + -7.442129643136107, + -6.48338397234244, + -6.421445690191433, + -8.911462526763668, + -9.381466156009402, + -10.990904068443502, + -6.709311788515316, + -6.548252811953186, + -4.675546066921168, + -5.192158399351284, + -9.7963977556248, + -6.528727241328714, + -4.633411231565895, + -7.432301316861331, + -4.27941136101723, + -5.345457170800265, + -4.99196750649682, + -10.297756887883558, + -4.7524989297368885, + -7.2509720028609905, + -9.892291779775393, + -6.548252811953186, + -4.675546066921168, + -5.1375551302269, + -10.297756887883558, + -8.351846738828245, + -4.906404655368331, + -5.740616885405192, + -8.505997418655502, + -9.381466156009402, + -8.505997418655502, + -10.990904068443502, + -8.688318975449457, + -7.658699558268299, + -9.122069259301819, + -4.069245884292374, + -10.990904068443502, + -4.609041423980861, + -4.855137547922799, + -5.766894714059857, + -10.990904068443502, + -8.911462526763668, + -5.7979472175532925, + -4.675546066921168, + -7.143935405688866, + -4.68426260660924, + -6.493569650693166, + -8.425954710981966, + -7.189556945839623, + -8.911462526763668, + -10.990904068443502, + -4.069245884292374, + -4.555295886603377, + -7.96554124829235, + -6.130568012742614, + -6.645919400760173, + -8.505997418655502, + -5.345457170800265, + -8.927336875920957, + -7.302024614329566, + -4.82945179255261, + -5.2610151580638345, + -5.7979472175532925, + -5.287121593787302, + -6.904398412581017, + -4.204187117838422, + -8.688318975449457, + -6.070923142615378, + -6.980768832033883, + -7.890478279454075, + -10.095024333829475, + -4.790203541367113, + -7.074973402380341, + -4.675546066921168, + -10.39365091203415, + -8.047852052718426, + -6.620678436436342, + -4.906404655368331, + -4.691975096652612, + -9.52608768355269, + -4.99196750649682, + -7.653613807368803, + -9.381466156009402, + -7.091489891528842, + -4.96745647548247, + -9.671375403635874, + -9.04499391938819, + -9.199144599215447, + -5.583732296983384, + -5.505065555449014, + -8.071014511433523, + -9.783825634117928, + -7.804468844161883, + -7.158435517339439, + -9.04499391938819, + -4.826132788794119, + -9.892291779775393, + -5.150501940643148, + -9.04499391938819, + -10.990904068443502, + -7.048239448806907, + -6.126800432698291, + -5.984804376302424, + -4.686455266021522, + -6.834293587288561, + -7.287754279791191, + -10.990904068443502, + -8.911462526763668, + -6.8965595062214025, + -4.826489090637879, + -4.745654355812862, + -9.604609707323613, + -10.297756887883558, + -9.04499391938819, + -6.429660314885253, + -8.903710433495684, + -5.6118994394371775, + -6.714237949427447, + -9.31975113652652, + -7.642272658893985, + -4.136716501065398, + -7.946381630720079, + -4.686455266021522, + -8.911462526763668, + -9.604609707323613, + -8.402829202156589, + -5.814754335869674, + -8.911462526763668, + -6.222522932071556, + -8.572763114967763, + -5.820885690252269, + -4.204187117838422, + -9.102342037602783, + -10.990904068443502, + -7.986656492566932, + -10.297756887883558, + -4.488136175019712, + -4.81146857705208, + -4.069245884292374, + -10.297756887883558, + -4.069245884292374, + -9.604609707323613, + -4.99196750649682, + -5.376219964895804, + -8.87745096720092, + -4.906404655368331, + -10.297756887883558, + -10.990904068443502, + -4.675546066921168, + -9.381466156009402, + -6.186211612302791, + -7.727801914724239, + -4.839211386259171, + -7.721691659483739, + -7.9962568924630695, + -8.100532310547338, + -5.287121593787302, + -9.892291779775393, + -9.892291779775393, + -4.906404655368331, + -5.814754335869674, + -4.686455266021522, + -6.1951135228467615, + -4.672653525319709, + -5.615625660759338, + -6.070923142615378, + -5.68563524931097, + -9.199144599215447, + -4.906404655368331, + -7.298288606910217, + -10.990904068443502, + -6.108035957751971, + -9.199144599215447, + -7.762910723288205, + -9.892291779775393, + -4.949186080932575, + -8.505997418655502, + -5.287121593787302, + -6.502267698711363, + -8.425954710981966, + -4.675546066921168, + -10.990904068443502, + -7.350686415950715, + -8.505997418655502, + -9.04499391938819, + -2.4801314448301883, + -10.990904068443502, + -9.199144599215447, + -9.381466156009402, + -9.923647814987065, + -5.345457170800265, + -9.462581575553314, + -7.597545593140962, + -7.857360702303732, + -5.145585863840253, + -4.675546066921168, + -9.892291779775393, + -4.90990638929888, + -9.381466156009402, + -9.604609707323613, + -4.136716501065398, + -5.108308893987117, + -3.8352101775520224, + -4.58727437334237, + -2.6726291164961054, + -3.853392749588046, + -3.5595166589236693, + -2.7617218074542875, + -3.4428723908509897, + -2.9997859562682305, + -3.702426209255565, + -3.200579529121098, + -2.823016811529605, + -3.6269039578544486, + -3.375091668084146, + -4.066498148599927, + -2.6159840852002025, + -4.7903508212617085, + -4.16585449438968, + -2.4785297290031263, + -2.843111375838878, + -3.653123330388038, + -2.632387767596367, + -2.858069998225265, + -2.3936359893150163, + -4.116946926868945, + -4.385650496772875, + -4.253056750300905, + -5.000832439747792, + -2.6439459570780013, + -3.4161333887552368, + -2.9810429491433967, + -3.6508192235179857, + -3.8156325156098023, + -3.3520160677658004, + -3.8253459615856396, + -2.6634123916017653, + -2.6433175942964, + -2.879709033844871, + -3.3085053358762573, + -3.410745645935775, + -3.068491765002531, + -3.6697297133107547, + -3.5218123531175545, + -3.939561999225776, + -4.769072636830291, + -3.452319274081531, + -3.19777207091082, + -3.61407172411895, + -2.869213138046439, + -3.7986284479038512, + -4.524055855098449, + -3.1743622580792703, + -2.6504319055253354, + -5.275967917210199, + -3.7316549981754696, + -4.527342746822748, + -3.625974702013571, + -3.6911087535867635, + -2.9882918688647053, + -3.2913638145460475, + -3.485571663205506, + -3.343949663357618, + -4.493796445370956, + -4.5774393972332446, + -3.078076098951088, + -6.89186161373324, + -4.393959865379777, + -4.022831306151184, + -3.2018844732764498, + -4.0089865708162495, + -3.884249812974888, + -3.927400366349227, + -3.3314354517072964, + -3.2106906005556555, + -3.4374277707078984, + -3.5804314759700233, + -3.2673662588617356, + -3.320567099555434, + -3.74111808349258, + -4.08987945598253, + -4.686455266021522, + -6.942799932618485, + -7.812850238095558, + -9.04499391938819, + -4.686455266021522, + -4.069245884292374, + -5.7979472175532925, + -5.5012411666245615, + -4.906404655368331, + -9.892291779775393, + -5.179763075466803, + -9.604609707323613, + -9.381466156009402, + -4.069245884292374, + -7.052774627291889, + -6.167122812594734, + -7.946381630720079, + -4.445321191929972, + -7.206714434525241, + -7.833225067682335, + -4.790975361144749, + -10.274200280752279, + -6.3489718836109885, + -9.892291779775393, + -9.290305377612425, + -8.350634175347302, + -5.727828562657646, + -4.487825269830353, + -9.892291779775393, + -4.90990638929888, + -9.604609707323613, + -6.593910586792673, + -9.002188488735607, + -5.814754335869674, + -4.069245884292374, + -5.058864072791079, + -8.735474315185078, + -4.99196750649682, + -6.502267698711363, + -8.932975367142857, + -10.095024333829475, + -8.047852052718426, + -4.675546066921168, + -4.96745647548247, + -4.555295886603377, + -5.992371936465869, + -6.482984350933699, + -9.892291779775393, + -9.892291779775393, + -4.686455266021522, + -8.157690724387287, + -7.0436910317837516, + -10.297756887883557, + -4.114226295474389, + -8.218315346203722, + -5.814754335869674, + -7.040400542447292, + -4.718644349213396, + -4.204187117838422, + -6.38898792850098, + -5.02422059258991, + -5.827327719799381, + -7.72619464931239, + -4.204187117838422, + -7.806564192645301, + -7.92373692734051, + -5.583732296983384, + -6.1951135228467615, + -5.096763124577817, + -9.748450743549503, + -4.686455266021522, + -9.381466156009402, + -7.667586560597757, + -6.235377041186801, + -9.199144599215447, + -10.297756887883558, + -8.769578440198345, + -4.99196750649682, + -5.5664625710375875, + -6.4406462979704, + -9.892291779775393, + -8.019961187772816, + -9.04499391938819, + -7.464543543827341, + -7.597545593140962, + -7.043139982434841, + -4.96745647548247, + -4.826489090637879, + -6.965552377708353, + -5.345457170800265, + -3.8343864155120113, + -3.8267884200277047, + -2.7269406381339287, + -4.023838713717708, + -3.615719599878374, + -2.3647224397398667, + -3.0520460838418932, + -5.281432334963197, + -2.443195666137056, + -3.751616752541798, + -5.11911385426198, + -3.7185060295978443, + -3.875393885380533, + -3.172698168555759, + -2.694099009662008, + -2.9692610581396455, + -4.179721210444442, + -4.865537896387329, + -3.3662861161147, + -3.0025393774182523, + -3.756559564800341, + -2.8668925533195195, + -3.2074858537126594, + -2.681949143865922, + -2.9132284461837443, + -3.1935527528713528, + -3.3430431102569855, + -3.536676035588093, + -2.8363023837536367, + -3.6027862842349245, + -3.3899538286732978, + -3.9958857492079667, + -3.3963823357256917, + -3.0648163147982057, + -2.9039854043761952, + -2.9164360378813163, + -2.83213699942636, + -4.7864028360904545, + -3.4440913103010633, + -3.5283427291915044, + -5.250315172550692, + -2.5080396703492314, + -3.3566403354711434, + -5.137446645415742, + -3.500520615676091, + -2.930289039193713, + -6.313217808653397, + -3.978530175686825, + -2.4021416524305286, + -2.543603726629905, + -4.426803196686291, + -5.500787266737538, + -3.2272719666095315, + -2.7963096467207835, + -2.6545566768813575, + -4.489380118495126, + -2.9851013045048473, + -4.328861783664827, + -3.9979665358675707, + -5.273560261695369, + -3.378388031297153, + -3.5678361114970922, + -3.2521415841038985, + -3.195848892982154, + -2.378882342012044, + -3.060731154768945, + -3.389510942345023, + -3.19590003339099, + -2.982385692950805, + -5.93251561626568, + -2.362996041116417, + -2.8696951315704977, + -3.387045710227208, + -3.4160025330706603, + -3.3900857561801545, + -4.2269191275661475, + -4.658248938856118, + -3.092945409353567, + -2.880645786094067, + -3.3801577975034416, + -2.6086253011430873, + -3.4549090165118543, + -3.4032567829381435, + -2.964921237133354, + -2.8099285371717473, + -2.5192468703540003, + -3.92701873468128, + -2.7289850414445347, + -2.992822544704931, + -3.7698589946009813, + -4.132261944469104, + -4.876503718198644, + -3.1812320906717586, + -5.085248797396308, + -3.3293006439714685, + -4.99196750649682, + -7.452453783345435, + -8.351846738828245, + -10.990904068443502, + -8.593008795645133, + -6.0771150892256145, + -10.990904068443502, + -6.0782491827074505, + -9.892291779775393, + -9.632210841927499, + -10.297756887883558, + -4.069245884292374, + -8.87803937570911, + -9.604609707323611, + -5.287121593787302, + -4.204187117838422, + -4.204187117838422, + -5.125930913084298, + -7.0668347141434, + -4.96745647548247, + -7.589706686781348, + -2.9918968551995486, + -9.46864284958179, + -9.381466156009402, + -8.996412045161366, + -7.904011016492534, + -4.675546066921168, + -10.64433047816353, + -4.675546066921168, + -9.748450743549503, + -7.533042344127846, + -10.990904068443502, + -9.604609707323613, + -10.297756887883558, + -9.892291779775393, + -4.204187117838422, + -8.852571008935474, + -7.761808188028376, + -5.615625660759338, + -6.532047689877809, + -8.793679491107284, + -10.504012220146405, + -5.345457170800265, + -4.069245884292374, + -4.372395975606771, + -6.388944166356874, + -4.906404655368331, + -8.287318182713443, + -4.906404655368331, + -8.156404113682092, + -6.210546311560309, + -6.151238126650049, + -10.990904068443502, + -4.069245884292374, + -7.206714434525241, + -10.297756887883558, + -10.297756887883558, + -4.5980773121676215, + -6.537135472143152, + -5.05260265114363, + -4.069245884292374, + -4.880190521456937, + -3.4583038298985294, + -6.2667171750176, + -5.350190483639338, + -4.133062523284091, + -4.208902730709792, + -3.926915322289304, + -5.802259215271182, + -4.057977038170967, + -3.112232831254116, + -3.245582797711603, + -3.607719816590989, + -3.627468983527168, + -6.409555801677178, + -3.5273262083950785, + -2.8398729723168934, + -3.022385110670598, + -4.281284044272045, + -3.304906420332415, + -3.0742225262445593, + -5.119359887515837, + -2.8451109357475697, + -4.199409672858524, + -3.1295486705037794, + -3.432581775028957, + -4.819622051222263, + -2.6795504385918125, + -2.49054353654728, + -3.2281602870343296, + -4.187871560277032, + -3.3475583455222777, + -2.993896279850076, + -5.23206018184894, + -3.624668312315199, + -3.6913166659003216, + -3.4258289970204903, + -2.527111776438709, + -4.054615435473744, + -2.828258131645446, + -2.585293862642443, + -3.3062581142712246, + -2.6641408558033826, + -3.8560610739498373, + -3.7320786731692155, + -2.885317984985593, + -3.57116832858312, + -3.6532727532133515, + -4.05724646993357, + -3.394397112203502, + -3.008755771557578, + -2.724668731614167, + -3.890513426706793, + -3.5035427860667174, + -3.613046690902789, + -4.0083029907994545, + -3.3388938973064017, + -3.5523114212809146, + -4.495307091229142, + -3.600935231024207, + -3.810255931587936, + -3.400360341415548, + -4.210024627913586, + -3.4224765729948876, + -2.9951050882946553, + -3.7585505708249194, + -3.5177317127407064, + -2.6535119614544516, + -2.5687651843258346, + -2.636964020462574, + -3.4025182654896193, + -3.3362237750247377, + -2.9705821166975155, + -2.9515589286541504, + -2.3542858049714575, + -2.813203681044348, + -2.891260822665217, + -2.7576535056837663, + -3.4157739921785897, + -2.586361278578932, + -2.7945236480024707, + -2.3722309041857677, + -2.890529567682674, + -2.4505807503287342, + -4.751938521363275, + -3.135284946688905, + -3.0701008385430892, + -4.066141673386981, + -3.9238332528717392, + -4.479486638622885, + -2.8698100826117234, + -3.718163601645962, + -4.675546066921168, + -4.906404655368331, + -9.892291779775393, + -6.502267698711363, + -9.015262059786698, + -8.282853867341293, + -4.675546066921168, + -4.413629825871088, + -4.555295886603377, + -5.583732296983384, + -10.990904068443502, + -7.841429445015532, + -7.94638163072008, + -5.179763075466803, + -6.244638847364779, + -10.297756887883558, + -8.821403591485753, + -5.917208455762955, + -4.96745647548247, + -9.238405611100909, + -6.942799932618485, + -8.11051101137776, + -7.128459848781967, + -6.942799932618485, + -9.381466156009402, + -4.114226295474389, + -9.04499391938819, + -4.906404655368331, + -8.688318975449457, + -5.15104046339043, + -5.615625660759338, + -4.675546066921168, + -5.168712338648543, + -4.069245884292374, + -6.331127339968754, + -9.122069259301819, + -10.186185112226452, + -4.906404655368331, + -7.5703980084699465, + -6.965552377708353, + -4.906404655368331, + -5.611442982219603, + -9.065490977782947, + -10.990904068443502, + -4.906404655368331, + -4.675546066921168, + -4.7333986204859775, + -4.686455266021522, + -5.923110010255996, + -6.908933591065999, + -4.552086488273934, + -10.990904068443502, + -7.379986155799278, + -9.892291779775393, + -8.911462526763668, + -4.906404655368331, + -10.441597924109448, + -10.990904068443502, + -8.282853867341293, + -4.99196750649682, + -4.675546066921168, + -4.99196750649682, + -8.351846738828245, + -6.070923142615378, + -4.204187117838422, + -7.7096820215966435, + -7.543549064412005, + -5.615625660759338, + -9.83961152194648, + -6.489800160401483, + -4.5197326280483, + -4.055945740476311, + -3.6056259540913724, + -5.286657527567651, + -4.224398966325087, + -4.666283210015029, + -3.6362906420869527, + -2.977437243502143, + -4.691568378244431, + -4.176699994184659, + -3.3736802919758255, + -3.037242364057341, + -3.3120309548278883, + -3.970922904235687, + -4.96863432957318, + -3.1601164186601047, + -2.680146825154283, + -2.686075413309102, + -3.4073230477097822, + -2.790528042201616, + -4.149632057507088, + -4.1234996488626825, + -3.8502883227282307, + -3.892022350889866, + -3.251062776930166, + -3.69786834005274, + -4.337908508291268, + -2.9908674788446303, + -3.116458272389677, + -2.779021760305482, + -2.615103600432394, + -3.2746885543655693, + -6.21444013435676, + -5.005622901064681, + -2.4980975451601326, + -3.760873528415984, + -3.3673474267177097, + -2.955220174810173, + -3.3246692786960077, + -4.189328700481926, + -3.8070898120329777, + -4.423418846798661, + -3.4572342201250437, + -2.7816733363888164, + -6.992844247041346, + -3.44827263638982, + -3.600443815560793, + -3.433030100677222, + -4.039914994272016, + -3.8920164084804196, + -3.876234181164209, + -4.216165295583112, + -3.2778090911089253, + -5.021252314717707, + -2.552217365553083, + -4.580309052602969, + -2.8003737828956208, + -2.451218344611226, + -3.1089128860154984, + -3.036039295077315, + -3.403299791184233, + -3.3133068332063007, + -5.997764662138591, + -4.07439230005094, + -3.353643820433909, + -3.2515070148630802, + -5.3121615683960695, + -3.42864416494897, + -4.235931202167847, + -4.06130964953517, + -3.6351723276094945, + -4.421499808134798, + -3.145449687192154, + -3.762146776302875, + -3.4489639265450793, + -3.716471270176854, + -5.606557092291847, + -3.9509424341891055, + -2.9336811421981706, + -4.411292604235705, + -2.3679574019479253, + -2.4432124380971474, + -4.659908825500644, + -3.1883342673722614, + -2.936963212515196, + -4.135245343299932, + -3.6751519114793436, + -2.6232031119165855, + -4.6521025031880345, + -3.454865243137408, + -2.787644272920499, + -3.2757895542896565, + -3.895356667688921, + -3.48819909015671, + -4.809722490549651, + -2.7148175425700107, + -2.8285328083154067, + -2.997633286507101, + -2.6378526241172837, + -3.3370590445212716, + -2.630151220158152, + -3.701070718357627, + -4.343987945533092, + -3.4575793323787565, + -3.594801814258919, + -3.884335727236145, + -2.9928133301392, + -2.639484944631059, + -3.188126125258356, + -2.902973776785332, + -3.813644709502616, + -3.868294239172826, + -3.3150292226154976, + -3.6495246190097785, + -3.782584278406471, + -3.074361826134931, + -2.6270649829250745, + -5.764231638204279, + -3.977797261747753, + -3.613769578206518, + -3.2671353668181675, + -4.197689978337143, + -4.092177575934041, + -3.3649067485246937, + -4.938661488534477, + -3.359742203839102, + -4.375465484810515, + -4.475038527342175, + -3.0200697281640942, + -3.611646098639019, + -2.630214487794819, + -3.5214616207895832, + -3.9284287877996102, + -4.2032558776315, + -5.432148518104933, + -3.5437470077633857, + -3.622416974764214, + -3.8631839805571335, + -2.2036441399605664, + -5.592741826508503, + -4.043092046485149, + -2.9185436946847036, + -4.703689193708848, + -3.2229355724909468, + -3.123532329071711, + -7.771939091826523, + -5.195108968566366, + -3.384339873412096, + -3.382196723466506, + -3.7026076145255917, + -4.259450083002019, + -2.775938021428736, + -4.182803297005054, + -2.9081636059714944, + -2.843194450138579, + -3.127804030232382, + -3.3187448769641135, + -3.938275006856887, + -4.861935537534824, + -3.250584352635676, + -4.220672568693682, + -2.5570766472160957, + -3.647003533466481, + -4.217973914356322, + -3.7604985521687486, + -3.8654068935784593, + -2.3804881903265582, + -3.4575266862209855, + -3.114483939270401, + -3.328820538057894, + -2.449072283724561, + -3.838662075669782, + -3.6693381713464333, + -3.3518978454033537, + -3.040994788742224, + -3.5129382539652556, + -3.783055399015233, + -4.038225637510941, + -3.7263680432649893, + -2.9704161025708813, + -3.4235745423937387, + -3.0575268174285437, + -4.725414834214044, + -4.256853588553853, + -2.435382760799979, + -4.0680464239879095, + -4.072867605376441, + -5.512189848810571, + -3.852817085703118, + -3.5624414605729533, + -4.290242603238588, + -5.718989116934385, + -3.4328459061917482, + -4.559344908102523, + -4.486097049782905, + -4.826957316074837, + -3.981982501096018, + -3.887206318256166, + -2.8686862733699203, + -6.340003662492685, + -3.593512011444579, + -3.544471650092673, + -3.8895599135814067, + -3.670907855374426, + -2.701634420481986, + -2.622098900507256, + -2.524549824932282, + -3.551648546969317, + -4.224181777167091, + -3.2229552373981165, + -3.811218920155958, + -4.084492891604215, + -5.436766769856591, + -3.4344908696619556, + -3.8383805670290623, + -3.7511155176512547, + -3.443585367530875, + -3.4884677632062773, + -2.944490196255626, + -3.906891451431915, + -3.7212936913063746, + -3.352548490922555, + -4.283784924731091, + -5.193103255874104, + -4.675546066921168, + -4.364943167232789, + -7.370071334433095, + -6.5071126518179145, + -4.686455266021522, + -10.297756887883558, + -8.50266764550871, + -9.361855799432762, + -9.342985635441337, + -6.070923142615378, + -8.775495669021847, + -7.162262671954408, + -8.540872808558259, + -4.986788429904411, + -6.695961130038663, + -7.028506111465285, + -9.892291779775393, + -8.943731787332453, + -4.96745647548247, + -8.769578440198345, + -6.070923142615378, + -9.381466156009402, + -8.37534976001621, + -7.479867724371438, + -9.199144599215447, + -5.345457170800265, + -9.604609707323613, + -8.425954710981966, + -6.43566494495601, + -6.89877662217255, + -6.954060964983755, + -10.297756887883558, + -9.156917076975274, + -4.487825269830353, + -9.41070265804502, + -6.474412506316838, + -5.345457170800265, + -7.812850238095558, + -5.03827166551377, + -6.331127339968754, + -6.8245182268646, + -9.892291779775393, + -4.439866592379795, + -6.15235971419288, + -4.069245884292374, + -8.631654632795957, + -8.431616234884098, + -9.748450743549503, + -9.892291779775393, + -6.725356020150889, + -5.7979472175532925, + -6.980768832033883, + -9.199144599215447, + -10.990904068443502, + -6.284352113573147, + -4.821501271201819, + -8.157690724387287, + -5.814754335869674, + -6.780232635563801, + -9.748450743549503, + -4.204187117838422, + -9.493037931666507, + -10.6246999722208, + -7.243133096501374, + -8.30326486460142, + -6.562360000786027, + -5.376219964895804, + -4.675546066921168, + -10.990904068443502, + -6.717190047893315, + -4.069245884292374, + -4.204187117838422, + -6.720849220588131, + -10.990904068443502, + -8.593008795645133, + -4.675546066921168, + -4.675546066921168, + -4.96745647548247, + -4.204187117838422, + -9.381466156009402, + -6.79114098697543, + -5.615625660759338, + -5.345457170800265, + -7.28391892334828, + -9.74501419568238, + -5.6744220795334295, + -6.949239764050315, + -8.247144464100774, + -5.637980159408808, + -6.227385862305464, + -4.204187117838422, + -7.995171794889512, + -6.2443474687499725, + -6.725356020150889, + -4.204187117838422, + -2.4801314448301883, + -7.644862197190189, + -4.970213978129402, + -6.4384141402843245, + -9.892291779775393, + -5.345457170800265, + -4.664035510886742, + -4.487394997922015, + -7.340423065244961, + -5.276489193009432, + -9.199144599215447, + -5.7979472175532925, + -8.30326486460142, + -9.381466156009402, + -7.610117684041475, + -10.095024333829475, + -8.566771270920155, + -4.204187117838422, + -4.906404655368331, + -9.604609707323613, + -6.99038588233046, + -10.297756887883558, + -4.906404655368331, + -6.965552377708353, + -10.990904068443502, + -5.287121593787302, + -4.069245884292374, + -10.990904068443502, + -5.531445324556099, + -10.990904068443502, + -5.28222225756382, + -4.069245884292374, + -5.376219964895804, + -9.604609707323613, + -10.297756887883558, + -5.617746267968795, + -4.78465627981317, + -6.0653923643548575, + -7.2509720028609905, + -7.249844606667445, + -5.083479221001042, + -10.297756887883558, + -4.439866592379795, + -10.990904068443502, + -4.686455266021522, + -5.615625660759338, + -4.82945179255261, + -10.990904068443502, + -7.597545593140962, + -2.4801314448301883, + -4.686455266021522, + -10.990904068443502, + -7.948654361905916, + -10.297756887883558, + -5.7979472175532925, + -10.990904068443502, + -10.990904068443502, + -7.648262407634185, + -7.183501386087967, + -4.686455266021522, + -9.199144599215447, + -9.04499391938819, + -5.287121593787302, + -6.830124130054617, + -9.671375403635874, + -5.870184003824404, + -7.530074976367938, + -5.583732296983384, + -7.394061159245947, + -9.199144599215447, + -9.015886452840617, + -4.675546066921168, + -8.693344143376208, + -7.554586514895405, + -7.948654361905916, + -10.297756887883558, + -5.583732296983384, + -10.095024333829475, + -9.381466156009402, + -6.070923142615378, + -4.204187117838422, + -6.287703841003177, + -5.706123728316947, + -5.287121593787302, + -4.99196750649682, + -4.906404655368331, + -4.681000666471345, + -9.892291779775393, + -10.297756887883558, + -6.634195241753911, + -3.1384170340308186, + -3.3337183898850595, + -2.908331052652597, + -4.041373335323535, + -4.928634708159409, + -3.394831818995743, + -3.3546779603466534, + -2.6008925537366263, + -3.22465051389266, + -4.544534715864618, + -3.0679495797145986, + -3.0934356579008218, + -3.5467978789848047, + -3.2384606802599647, + -3.2082387228632765, + -3.2263429143688818, + -3.129040068967741, + -2.6480708543152005, + -5.827050641731215, + -5.223297235063325, + -2.638567323727177, + -3.577158390382017, + -3.3378975859039226, + -3.8339477038278664, + -3.0514714994865746, + -4.204187117838422, + -7.293123610434631, + -9.545718189495421, + -7.217236694474478, + -10.990904068443502, + -4.906404655368331, + -10.990904068443502, + -5.063978042473092, + -7.183501386087967, + -10.990904068443502, + -7.618874475287829, + -4.675546066921168, + -4.204187117838422, + -10.297756887883558, + -4.906404655368331, + -4.826489090637879, + -5.245068476175858, + -4.372395975606771, + -5.316289382293784, + -5.125789869207351, + -7.020790185870652, + -5.287121593787302, + -5.889422909915073, + -6.004933929358218, + -10.297756887883558, + -2.8602106126722977, + -3.010090938334475, + -2.5363431870664197, + -2.8664149197163153, + -4.979070507254474, + -3.435690478031729, + -4.133437026913354, + -3.9068887625267217, + -2.5114438928633662, + -3.0943998623063367, + -3.2085587131539404, + -4.410967171780481, + -2.924455887900164, + -3.7749797234820828, + -3.7032141779443966, + -4.223771691472902, + -3.7029293465534274, + -2.815652542375812, + -3.1725147974797148, + -3.38141428395555, + -3.618295884953052, + -2.76939219327161, + -3.746506811535433, + -2.935354860808235, + -3.4510364310880277, + -3.6013287462847274, + -3.8046540733723617, + -3.7201720281192876, + -3.7130570532894467, + -2.8353668874027678, + -3.535511251884626, + -2.292858712324977, + -3.0151965783718286, + -2.5296834826116577, + -3.872123311477922, + -3.5986683059245825, + -2.7882871621976424, + -2.68670549474438, + -3.066364924594545, + -3.4345972543066843, + -3.11822376761467, + -3.9952379377573526, + -4.076854036480314, + -2.956262501716274, + -2.7932453556345345, + -4.001374564046298, + -3.765561623936435, + -3.168715461262314, + -3.2834122205024117, + -4.025030812608284, + -3.703521926847176, + -3.3826364447176216, + -4.510158895068205, + -3.737336970175663, + -4.0137075843646, + -5.903690989948873, + -4.48540289524233, + -7.597545593140962, + -8.919368035636106, + -7.833225067682335, + -9.944527733288732, + -4.675546066921168, + -7.349180543706325, + -4.069245884292374, + -4.675546066921168, + -8.425954710981966, + -10.297756887883558, + -9.199144599215447, + -5.287121593787302, + -4.530606695394598, + -6.781710168307555, + -7.272300885007857, + -6.458825137544452, + -6.4846545666814075, + -6.725356020150889, + -10.990904068443502, + -5.501966342286816, + -7.174461315745936, + -8.40614819464054, + -4.686455266021522, + -8.593008795645133, + -4.686455266021522, + -6.804774031967686, + -4.686455266021522, + -9.892291779775393, + -7.660872788771963, + -4.675546066921168, + -5.287121593787302, + -8.425954710981966, + -5.036907735457592, + -4.069245884292374, + -7.160401490411448, + -10.990904068443502, + -4.204187117838422, + -4.686455266021522, + -7.530074976367938, + -7.543549064412005, + -9.04499391938819, + -9.604609707323613, + -5.357956416445034, + -6.095922358374235, + -5.583732296983384, + -7.556916863958357, + -4.906404655368331, + -4.906404655368331, + -7.948654361905916, + -4.906404655368331, + -9.892291779775393, + -8.157690724387287, + -3.108675279899749, + -4.371170102784752, + -2.9026082026460998, + -3.7629308750225663, + -4.6807054765692335, + -3.0177946709408294, + -3.276896269189209, + -3.5212362842289178, + -3.3338306026324824, + -3.0232190959722534, + -3.7335631065060064, + -3.555924068551095, + -3.4953589549263433, + -3.4359443102426526, + -2.7192489697738105, + -2.960530653828284, + -3.5549971052081277, + -3.7325215163837107, + -4.841956283272702, + -3.0502552912650573, + -3.8659393010310334, + -3.0838412706578904, + -3.531508341718307, + -3.0697039787535565, + -4.014137642520722, + -2.8188712160928664, + -3.7090921312104954, + -4.261552134574739, + -2.8541938203380863, + -2.5439700425956886, + -3.2366682111040523, + -4.110111175744842, + -3.54317288330231, + -2.8334824589388856, + -3.083651910743689, + -2.5763575622468355, + -3.6601181907280886, + -4.2815075694806275, + -2.7764116085857986, + -3.597099781614091, + -3.2893491563079693, + -3.1041127156421924, + -4.049157795899921, + -3.6785888933231687, + -3.082756142710535, + -3.966623968356517, + -2.406001753368124, + -4.034482130483765, + -5.728384640888549, + -2.515501271511027, + -3.5414158350158234, + -2.5274818047926475, + -3.976243748527702, + -4.120381128780718, + -4.323640661009454, + -3.005430030237297, + -4.25641342735819, + -3.3366216838188247, + -4.74694027038759, + -3.46640754140609, + -3.1345479364813995, + -3.7227977132044123, + -4.615747627353289, + -3.4426460286344316, + -2.589024815563703, + -3.598582795509864, + -5.310017289310604, + -3.1704010525616795, + -4.422612514636628, + -5.479158308515637, + -3.5938233012543117, + -3.458630427629645, + -4.813443753362706, + -4.381354207301908, + -7.486651477402363, + -10.990904068443502, + -5.37868920431845, + -8.043702651311078, + -7.668843861151985, + -4.204187117838422, + -4.99196750649682, + -5.581284999164616, + -4.069245884292374, + -4.204187117838422, + -7.784354041511697, + -8.224410409079976, + -5.571702194176779, + -5.345457170800265, + -9.761277583738858, + -9.610538838977941, + -5.010501618860717, + -8.221586553353163, + -7.658699558268299, + -5.0094707268540475, + -7.738168078818593, + -6.482984350933699, + -4.821501271201819, + -9.381466156009402, + -4.99196750649682, + -10.990904068443502, + -8.351846738828245, + -4.7439979602790565, + -5.139544550142061, + -4.204187117838422, + -8.425954710981966, + -4.906404655368331, + -10.990904068443502, + -5.519189809048924, + -6.685835599914015, + -8.83839804184809, + -8.505997418655502, + -7.021746563686702, + -6.84153095334465, + -6.725356020150889, + -4.99196750649682, + -5.5935405146717905, + -4.069245884292374, + -6.421445690191433, + -8.793679491107284, + -5.4998326575367065, + -10.297756887883558, + -4.675546066921168, + -9.342985635441337, + -7.486651477402363, + -6.8965595062214025, + -10.297756887883558, + -10.990904068443502, + -10.990904068443502, + -4.204187117838422, + -7.724269656350317, + -7.255507181345973, + -6.878461033463784, + -4.069245884292374, + -4.9509369478978495, + -6.836927795807993, + -5.345457170800265, + -4.204187117838422, + -7.399348217571863, + -4.069245884292374, + -8.425954710981966, + -4.069245884292374, + -7.979180271962986, + -5.545839289318616, + -5.287121593787302, + -7.287187886070478, + -5.5935405146717905, + -6.057401305639607, + -6.248178270496852, + -4.555295886603377, + -6.337830420104096, + -6.282125159242869, + -4.675546066921168, + -9.381466156009402, + -8.716838271570007, + -3.0160271678846273, + -8.911462526763668, + -9.748450743549503, + -9.199144599215447, + -8.331254783203907, + -7.286033091403041, + -7.922479422646347, + -9.892291779775393, + -4.949186080932575, + -8.505997418655502, + -7.140756466733444, + -10.297756887883558, + -7.79243924083543, + -6.836927795807993, + -6.687700365238442, + -4.069245884292374, + -7.28391892334828, + -8.793679491107284, + -9.199144599215447, + -9.46864284958179, + -6.206774674339012, + -9.892291779775393, + -9.199144599215447, + -5.814754335869674, + -8.688318975449457, + -4.686455266021522, + -5.287121593787302, + -9.892291779775393, + -5.345457170800265, + -4.837793517456129, + -5.583732296983384, + -10.297756887883558, + -10.297756887883558, + -9.892291779775393, + -9.04499391938819, + -4.675546066921168, + -4.847203931711836, + -4.204187117838422, + -6.46944955369677, + -4.223548229724661, + -3.2223298810828975, + -3.9059366489962737, + -2.9557274178858575, + -3.116661337468668, + -4.945862221516711, + -3.9802398669532417, + -3.06051778388958, + -4.5260336495684985, + -2.927099404564931, + -2.980176036788262, + -3.0907333068599825, + -6.417342095629002, + -4.585821796660445, + -5.345457170800265, + -7.525168165643776, + -4.204187117838422, + -8.911462526763668, + -4.906404655368331, + -8.688318975449457, + -8.911462526763668, + -7.557958531001784, + -10.297756887883558, + -6.980768832033883, + -5.177463948827157, + -5.40543702052365, + -7.668501663558283, + -4.377850575156948, + -4.204187117838422, + -4.069245884292374, + -4.96745647548247, + -3.498791534239701, + -3.261125637678306, + -3.052993153804778, + -4.339553055420748, + -3.7127057573127678, + -3.039591308492748, + -3.442915205147282, + -2.959233850438366, + -3.1093142760687136, + -2.907762323497213, + -2.8495483207483234, + -3.522623532327433, + -3.331118991559587, + -2.8214001635008916, + -6.876351298949257, + -5.454936144441556, + -6.5967189582793395, + -4.686455266021522, + -4.786972317292066, + -6.070923142615378, + -10.990904068443502, + -10.297756887883558, + -4.752407444581505, + -6.388039188734253, + -7.095556052856134, + -5.345457170800265, + -4.368649414689073, + -5.19985355791766, + -8.269695213182606, + -5.717369506203186, + -4.675546066921168, + -9.243655063423622, + -7.597545593140962, + -9.892291779775393, + -5.814754335869674, + -9.381466156009402, + -5.345457170800265, + -6.637162609513818, + -4.785476915515526, + -7.530074976367938, + -5.814754335869674, + -9.892291779775393, + -4.069245884292374, + -2.3361326498954544, + -3.862230613193781, + -6.072664424998081, + -4.2863482767399885, + -3.6693237598573423, + -5.281299290305962, + -2.5386340328099144, + -6.305087331635948, + -2.968849811330151, + -3.2234000971209276, + -3.0586611755750983, + -4.686455266021522, + -9.199144599215447, + -4.686455266021522, + -9.000483455180015, + -5.308252601394827, + -8.100532310547338, + -4.364943167232789, + -3.12291449823585, + -3.3894742465970134, + -2.7916921784467243, + -4.3629736458832795, + -3.5674006010558728, + -4.634302951292897, + -2.6272841314078823, + -2.64380203896017, + -3.2595856348110557, + -4.65987691226269, + -2.495691512864819, + -5.315479272738009, + -4.101782541874124, + -2.974432313004513, + -9.748450743549503, + -4.487825269830353, + -9.647084466522461, + -10.990904068443502, + -4.99196750649682, + -8.394425642998398, + -9.147094321601388, + -6.226745973629918, + -4.906404655368331, + -4.204187117838422, + -9.604609707323613, + -7.530074976367938, + -6.1951135228467615, + -4.675546066921168, + -10.990904068443502, + -4.686455266021522, + -4.136716501065398, + -9.199144599215447, + -4.99196750649682, + -7.255507181345973, + -6.780232635563801, + -9.04499391938819, + -9.381466156009402, + -5.054566029486814, + -4.069245884292374, + -6.05416388159794, + -4.644341460283453, + -2.884180447837611, + -2.7147016142581806, + -3.785722567850314, + -3.6812181564983857, + -3.3406639837748644, + -3.0729321687587188, + -3.577930278319434, + -2.724672904368995, + -3.899792644152052, + -3.419213531457144, + -2.88468801571123, + -2.458650915712354, + -3.4888884666557627, + -7.31926306332527, + -4.425987986651688, + -3.633642289292575, + -2.9601651542080085, + -3.0194990462164264, + -2.830973588234398, + -3.47550691694449, + -4.411331729471933, + -3.5858341224075665, + -3.9250122019098206, + -3.033051197101415, + -3.386769210337472, + -3.6914412590181107, + -3.3617894367011463, + -2.5149935938760755, + -5.008487415055345, + -3.7801135373755144, + -3.7156014187864947, + -2.445657390775083, + -2.9620436340450365, + -3.3638863596468234, + -3.0877273562487537, + -3.0184607069423635, + -3.1631595569007325, + -2.9505941429932223, + -2.5129651716947197, + -3.7285640448239734, + -3.0295332189127717, + -4.340708940896236, + -3.3956653984060883, + -2.59981057320754, + -3.4092334722256923, + -3.651442841479354, + -4.1178082504801035, + -3.49980254410031, + -8.415352846827622, + -7.076225006465631, + -10.990904068443502, + -6.376465279009416, + -5.615625660759338, + -4.686455266021522, + -6.466426101373448, + -4.713033356267787, + -8.793679491107284, + -10.990904068443502, + -4.675546066921168, + -5.482902695256888, + -7.682255404641738, + -4.675546066921168, + -6.78394972641732, + -4.496127460050187, + -3.0345507493290365, + -2.459010014381552, + -3.5049298433936307, + -3.624117199200672, + -4.061991411779744, + -3.5326818777409956, + -4.618959359058891, + -3.70991293242617, + -2.7445870894297255, + -6.386189527064913, + -9.258036117043641, + -4.069245884292374, + -5.345457170800265, + -7.597545593140962, + -9.381466156009402, + -6.427677493280652, + -9.892291779775393, + -7.666923975719979, + -8.911462526763668, + -10.297756887883558, + -4.204187117838422, + -8.220272295864289, + -6.502267698711363, + -4.67242013526265, + -4.686455266021522, + -6.671907122662533, + -9.199144599215447, + -5.345457170800265, + -4.675546066921168, + -4.204187117838422, + -10.186185112226452, + -9.111672904838624, + -7.499490373482835, + -5.978759942102586, + -5.0498753513685415, + -8.282853867341293, + -10.297756887883558, + -4.240797758059516, + -3.814754408428621, + -2.5651740680335173, + -4.847149262490077, + -4.726139036364281, + -4.298776816837021, + -4.206746451072005, + -3.4267034692239937, + -3.281216449435688, + -2.736323030975282, + -4.204187117838422, + -6.6065856269501495, + -9.748450743549503, + -5.3532274082748925, + -5.615625660759338, + -5.360579495619003, + -9.551741363931399, + -4.835040485499545, + -2.7116558692303228, + -3.358975627063544, + -2.8997199415413344, + -3.21892257586575, + -2.9741626241039705, + -2.996098405166491, + -5.020774077697831, + -3.354931980939201, + -3.7522116256828655, + -9.134798946083196, + -8.085333571955152, + -6.376465279009416, + -8.668708618872817, + -8.38921329565379, + -8.958905304500517, + -9.671375403635874, + -5.3308862263487455, + -4.204187117838422, + -8.351846738828245, + -8.688318975449457, + -5.615625660759338, + -7.821607029341912, + -8.425954710981966 + ], + "status": "normal", + "min_mw": 4.95, + "type": "CatalogSpatialTestResult" +} \ No newline at end of file diff --git a/tests/test_plots.py b/tests/test_plots.py index 2c3db7b3..10c8ee1d 100644 --- a/tests/test_plots.py +++ b/tests/test_plots.py @@ -1,116 +1,1393 @@ -import matplotlib.pyplot as plt -import numpy -import matplotlib.pyplot -from unittest import mock -import unittest +import copy +import gc +import json +import os.path import random +import socket import string -from csep.utils import plots +import unittest +from unittest import mock +from unittest.mock import MagicMock, patch, Mock + +import matplotlib.pyplot +import matplotlib.pyplot as plt +import numpy +from cartopy import crs as ccrs +from matplotlib import colors +from matplotlib.text import Annotation + +import csep +from csep.core.catalog_evaluations import ( + CatalogNumberTestResult, + CatalogSpatialTestResult, + CatalogMagnitudeTestResult, + CatalogPseudolikelihoodTestResult, + CalibrationTestResult, +) +from csep.core import catalogs +from csep.utils.plots import ( + plot_cumulative_events_versus_time, + plot_magnitude_vs_time, + plot_distribution_test, + plot_magnitude_histogram, + plot_calibration_test, + plot_comparison_test, + plot_consistency_test, + plot_basemap, + plot_catalog, + plot_spatial_dataset, + plot_concentration_ROC_diagram, + plot_Molchan_diagram, + plot_ROC_diagram, + _get_basemap, # noqa + _calculate_spatial_extent, # noqa + _create_geo_axes, # noqa + _calculate_marker_size, # noqa + _add_gridlines, # noqa + _get_marker_style, # noqa + _get_marker_t_color, # noqa + _get_marker_w_color, # noqa + _get_axis_limits, # noqa + _add_labels_for_publication, # noqa + _autosize_scatter, # noqa + _size_map, # noqa + _autoscale_histogram, # noqa + _annotate_distribution_plot, # noqa + _define_colormap_and_alpha, # noqa + _add_colorbar, # noqa + _process_stat_distribution, # noqa +) + + +def is_internet_available(): + """Check if internet is available by attempting to connect to a well-known host.""" + try: + # Try to connect to Google's DNS server + socket.create_connection(("8.8.8.8", 53), timeout=1) + return True + except OSError: + return False + + +is_github_actions = os.getenv("GITHUB_ACTIONS") == "true" + +show_plots = False + + +class TestPlots(unittest.TestCase): + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) # Call the parent constructor + # Define the save directory + self.artifacts = os.path.join(os.path.dirname(__file__), "artifacts") + self.save_dir = os.path.join(self.artifacts, "plots") + os.makedirs(self.save_dir, exist_ok=True) + + def savefig(self, ax, name): + ax.figure.savefig(os.path.join(self.save_dir, name)) + + +class TestTimeSeriesPlots(TestPlots): + + def setUp(self): + # This method is called before each test. + # Load the stochastic event sets and observation here. + + cat_file_m2 = csep.datasets.comcat_example_catalog_fname + cat_file_m5 = os.path.join( + self.artifacts, + "example_csep2_forecasts", + "Catalog", + "catalog.json", + ) + + forecast_file = os.path.join( + self.artifacts, + "example_csep2_forecasts", + "Forecasts", + "ucerf3-landers_short.csv", + ) + + self.stochastic_event_sets = csep.load_catalog_forecast(forecast_file) + self.observation_m5 = catalogs.CSEPCatalog.load_json(cat_file_m5) + self.observation_m2 = csep.load_catalog(cat_file_m2) + + def test_plot_magnitude_vs_time(self): + # Basic test + ax = plot_magnitude_vs_time(catalog=self.observation_m2, show=show_plots) + self.assertEqual(ax.get_title(), "Magnitude vs. Time") + self.assertEqual(ax.get_xlabel(), "Datetime") + self.assertEqual(ax.get_ylabel(), "$M$") + + # Test with custom color + ax = plot_magnitude_vs_time(catalog=self.observation_m2, color='red', show=show_plots) + scatter_color = ax.collections[0].get_facecolor()[0] + self.assertTrue(all(scatter_color[:3] == (1.0, 0.0, 0.0))) # Check if color is red + + # Test with custom marker size + ax = plot_magnitude_vs_time(catalog=self.observation_m2, size=10, mag_scale=1, + show=show_plots) + scatter_sizes = ax.collections[0].get_sizes() + func_sizes = _autosize_scatter(10, self.observation_m2.data["magnitude"], 1) + numpy.testing.assert_array_almost_equal(scatter_sizes, func_sizes) + + # Test with custom alpha + ax = plot_magnitude_vs_time(catalog=self.observation_m2, alpha=0.5, show=show_plots) + scatter_alpha = ax.collections[0].get_alpha() + self.assertEqual(scatter_alpha, 0.5) + + # Test with custom mag_scale + ax = plot_magnitude_vs_time(catalog=self.observation_m2, mag_scale=8, show=show_plots) + scatter_sizes = ax.collections[0].get_sizes() + func_sizes = _autosize_scatter(4, self.observation_m2.data["magnitude"], 8) + numpy.testing.assert_array_almost_equal(scatter_sizes, func_sizes) + + # Test with show=show_plots (just to ensure no errors occur) + plot_magnitude_vs_time(catalog=self.observation_m2, show=show_plots) + + def test_plot_cumulative_events_default(self): + # Test with default arguments to ensure basic functionality + ax = plot_cumulative_events_versus_time( + catalog_forecast=self.stochastic_event_sets, + observation=self.observation_m5, + show=show_plots + ) + + self.assertIsNotNone(ax.get_title()) + self.assertIsNotNone(ax.get_xlabel()) + self.assertIsNotNone(ax.get_ylabel()) + + def test_plot_cumulative_events_hours(self): + # Test with time_axis set to 'hours' + ax = plot_cumulative_events_versus_time( + catalog_forecast=self.stochastic_event_sets, + observation=self.observation_m5, + bins=50, + time_axis="hours", + xlabel="Hours since Mainshock", + ylabel="Cumulative Event Count", + title="Cumulative Event Counts by Hour", + legend_loc="upper left", + show=show_plots + ) + + self.assertEqual(ax.get_xlabel(), "Hours since Mainshock") + self.assertEqual(ax.get_ylabel(), "Cumulative Event Count") + self.assertEqual(ax.get_title(), "Cumulative Event Counts by Hour") + + def test_plot_cumulative_events_different_bins(self): + # Test with different number of bins + ax = plot_cumulative_events_versus_time( + catalog_forecast=self.stochastic_event_sets, + observation=self.observation_m5, + bins=200, + show=show_plots, + figsize=(12, 8), + time_axis="days", + xlabel="Days since Mainshock", + ylabel="Cumulative Event Count", + title="Cumulative Event Counts with More Bins", + legend_loc="best" + ) + + self.assertEqual(ax.get_title(), "Cumulative Event Counts with More Bins") + self.assertEqual(ax.get_xlabel(), "Days since Mainshock") + self.assertEqual(ax.get_ylabel(), "Cumulative Event Count") + + def test_plot_cumulative_events_custom_legend(self): + # Test with a custom legend location and size + ax = plot_cumulative_events_versus_time( + catalog_forecast=self.stochastic_event_sets, + observation=self.observation_m5, + bins=75, + show=show_plots, + figsize=(8, 5), + time_axis="days", + xlabel="Days since Mainshock", + ylabel="Cumulative Event Count", + title="Cumulative Event Counts with Custom Legend", + legend_loc="lower right", + legend_fontsize=14 + ) + + self.assertEqual(ax.get_legend()._get_loc(), 4) + self.assertEqual(ax.get_legend().get_texts()[0].get_fontsize(), 14) + + def tearDown(self): + plt.close("all") + del self.stochastic_event_sets + del self.observation_m2 + del self.observation_m5 + gc.collect() + + +class TestPlotMagnitudeHistogram(TestPlots): + + def setUp(self): + + def gr_dist(num_events, mag_min=3.0, mag_max=8.0, b_val=1.0): + U = numpy.random.uniform(0, 1, num_events) + magnitudes = mag_min - (1.0 / b_val) * numpy.log10(1 - U) + magnitudes = magnitudes[magnitudes <= mag_max] + return magnitudes + + self.mock_forecast = [MagicMock(), MagicMock(), MagicMock()] + for i in self.mock_forecast: + i.get_magnitudes.return_value = gr_dist(5000) + + self.mock_cat = MagicMock() + self.mock_cat.get_magnitudes.return_value = gr_dist(500, b_val=1.2) + self.mock_cat.get_number_of_events.return_value = 500 + self.mock_cat.region.magnitudes = numpy.arange(3.0, 8.0, 0.1) + self.save_dir = os.path.join(os.path.dirname(__file__), "artifacts", "plots") + + cat_file_m5 = os.path.join( + self.artifacts, + "example_csep2_forecasts", + "Catalog", + "catalog.json", + ) + self.comcat = catalogs.CSEPCatalog.load_json(cat_file_m5) + forecast_file = os.path.join( + self.artifacts, + "example_csep2_forecasts", + "Forecasts", + "ucerf3-landers_short.csv", + ) + + self.stochastic_event_sets = csep.load_catalog_forecast(forecast_file) + + os.makedirs(self.save_dir, exist_ok=True) + + def test_plot_magnitude_histogram_basic(self): + # Test with basic arguments + ax = plot_magnitude_histogram(self.mock_forecast, + self.mock_cat, show=show_plots, + density=True) + + # Verify that magnitudes were retrieved + for catalog in self.mock_forecast: + catalog.get_magnitudes.assert_called_once() + self.mock_cat.get_magnitudes.assert_called_once() + self.mock_cat.get_number_of_events.assert_called_once() + ax.figure.savefig(os.path.join(self.save_dir, "magnitude_histogram.png")) + + def test_plot_magnitude_histogram_ucerf(self): + # Test with basic arguments + ax = plot_magnitude_histogram(self.stochastic_event_sets, self.comcat, + show=show_plots) + + # # Verify that magnitudes were retrieved + # for catalog in self.stochastic_event_sets: + # catalog.get_magnitudes.assert_called_once() + # self.comcat.get_magnitudes.assert_called_once() + # self.comcat.get_number_of_events.assert_called_once() + ax.figure.savefig(os.path.join(self.save_dir, "magnitude_histogram_ucerf.png")) + + def tearDown(self): + plt.close("all") + gc.collect() + + +class TestPlotDistributionTests(TestPlots): + def setUp(self): + self.result_obs_scalar = MagicMock() + self.result_obs_scalar.test_distribution = numpy.random.normal(0, 1, 1000) + self.result_obs_scalar.observed_statistic = numpy.random.rand(1)[0] -class TestPoissonPlots(unittest.TestCase): + self.result_obs_array = MagicMock() + self.result_obs_array.test_distribution = numpy.random.normal(0, 1, 1000) + self.result_obs_array.observed_statistic = numpy.random.normal(0, 1, 100) + + self.result_nan = MagicMock() + self.result_nan.test_distribution = numpy.random.normal(0, 1, 1000) + self.result_nan.observed_statistic = -numpy.inf + + # Example data for testing + n_test = os.path.join( + self.artifacts, "example_csep2_forecasts", "Results", "catalog_n_test.json" + ) + s_test = os.path.join( + self.artifacts, "example_csep2_forecasts", "Results", "catalog_s_test.json" + ) + m_test = os.path.join( + self.artifacts, "example_csep2_forecasts", "Results", "catalog_m_test.json" + ) + l_test = os.path.join( + self.artifacts, "example_csep2_forecasts", "Results", "catalog_l_test.json" + ) + + with open(n_test, "r") as fp: + self.n_test = CatalogNumberTestResult.from_dict(json.load(fp)) + with open(s_test, "r") as fp: + self.s_test = CatalogSpatialTestResult.from_dict(json.load(fp)) + with open(m_test, "r") as fp: + self.m_test = CatalogMagnitudeTestResult.from_dict(json.load(fp)) + with open(l_test, "r") as fp: + self.l_test = CatalogPseudolikelihoodTestResult.from_dict(json.load(fp)) + + def test_plot_dist_test_with_scalar_observation_default(self): + ax = plot_distribution_test( + evaluation_result=self.result_obs_scalar, + show=show_plots, + ) + + # Check if a vertical line was drawn for the scalar observation + lines = [line for line in ax.get_lines() if line.get_linestyle() == "--"] + self.assertEqual(len(lines), 1) # Expect one vertical line + self.assertEqual(lines[0].get_xdata()[0], self.result_obs_scalar.observed_statistic) + + def test_plot_dist_test_with_scalar_observation_w_labels(self): + ax = plot_distribution_test( + evaluation_result=self.result_obs_scalar, + xlabel="Test X Label", + ylabel="Test Y Label", + title="Test Title", + show=show_plots, + ) + + # Check if a vertical line was drawn for the scalar observation + lines = [line for line in ax.get_lines() if line.get_linestyle() == "--"] + self.assertEqual(len(lines), 1) # Expect one vertical line + self.assertEqual(lines[0].get_xdata()[0], self.result_obs_scalar.observed_statistic) + + def test_plot_dist_test_with_array_observation(self): + ax = plot_distribution_test( + evaluation_result=self.result_obs_array, + alpha=0.5, + show=show_plots, + ) + bars = ax.patches + self.assertTrue( + all(bar.get_alpha() == 0.5 for bar in bars), + "Alpha transparency not set correctly for bars", + ) + + def test_plot_dist_test_with_percentile_shading(self): + ax = plot_distribution_test( + evaluation_result=self.result_obs_scalar, + percentile=60, + show=show_plots, + ) + expected_red = (1.0, 0.0, 0.0) + red_patches = [] + for patch_ in ax.patches: + facecolor = patch_.get_facecolor()[:3] # Get RGB, ignore alpha + if all(abs(facecolor[i] - expected_red[i]) < 0.01 for i in range(3)): + red_patches.append(patch_) + self.assertGreater( + len(red_patches), + 0, + "Expected some patches to be colored red for percentile shading", + ) + + def test_plot_dist_test_with_annotation(self): + annotation_text = "Test Annotation" + ax = plot_distribution_test( + evaluation_result=self.result_obs_scalar, + xlabel="Test X Label", + ylabel="Test Y Label", + title="Test Title", + annotation_text=annotation_text, + annotation_xy=(0.5, 0.5), + annotation_fontsize=12, + show=show_plots, + ) + annotations = ax.texts + self.assertEqual(len(annotations), 1) + self.assertEqual(annotations[0].get_text(), annotation_text) + + def test_plot_dist_test_xlim(self): + xlim = (-5, 5) + ax = plot_distribution_test( + evaluation_result=self.result_obs_scalar, + percentile=95, + xlim=xlim, + show=show_plots, + ) + self.savefig(ax, "plot_dist_test_xlims.png") + self.assertEqual(ax.get_xlim(), xlim) + + def test_plot_dist_test_autoxlim_nan(self): + + ax = plot_distribution_test( + evaluation_result=self.result_nan, + percentile=95, + show=show_plots, + ) + self.savefig(ax, "plot_dist_test_xlims_inf.png") + + def test_plot_n_test(self): + ax = plot_distribution_test( + self.n_test, + show=show_plots, + ) + self.savefig(ax, "plot_n_test.png") + + def test_plot_m_test(self): + ax = plot_distribution_test( + self.m_test, + show=show_plots, + ) + self.savefig(ax, "plot_m_test.png") + + def test_plot_s_test(self): + ax = plot_distribution_test( + self.s_test, + show=show_plots, + ) + self.savefig(ax, "plot_s_test.png") + + def test_plot_l_test(self): + ax = plot_distribution_test( + self.l_test, + show=show_plots, + ) + self.savefig(ax, "plot_l_test.png") + + def tearDown(self): + plt.close("all") + gc.collect() + + +class TestPlotCalibrationTest(TestPlots): + + def setUp(self): + # Create a mock evaluation result with a uniform distribution + self.evaluation_result = MagicMock() + self.evaluation_result.test_distribution = numpy.random.uniform(0, 1, 1000) ** 1.3 + self.evaluation_result.sim_name = "Simulated Data" + + # Example data for testing + cal_n_test = os.path.join( + os.path.dirname(__file__), + "artifacts", + "example_csep2_forecasts", + "Results", + "calibration_n.json", + ) + cal_m_test = os.path.join( + os.path.dirname(__file__), + "artifacts", + "example_csep2_forecasts", + "Results", + "calibration_m.json", + ) + + with open(cal_n_test, "r") as fp: + self.cal_n_test = CalibrationTestResult.from_dict(json.load(fp)) + with open(cal_m_test, "r") as fp: + self.cal_m_test = CalibrationTestResult.from_dict(json.load(fp)) + + def test_plot_calibration_basic(self): + # Test with basic arguments + ax = plot_calibration_test(self.evaluation_result, show=show_plots) + # Check if the plot was created + self.assertIsInstance(ax, plt.Axes) + # Check if the confidence intervals were plotted (3 lines: pp, ulow, uhigh) + self.assertEqual(len(ax.lines), 4) + # Check if the legend was created with the correct label + legend = ax.get_legend() + self.assertIsNotNone(legend) + legend_labels = [text.get_text() for text in legend.get_texts()] + self.assertIn(self.evaluation_result.sim_name, legend_labels) + + def test_plot_calibration_test_n_test(self): + + ax = plot_calibration_test(self.cal_n_test, show=show_plots) + self.savefig(ax, "calibration_n_test.png") + legend = ax.get_legend() + self.assertIsNotNone(legend) + legend_labels = [text.get_text() for text in legend.get_texts()] + self.assertIn(self.cal_n_test.sim_name, legend_labels) + + def test_plot_calibration_test_m_test(self): + ax = plot_calibration_test(self.cal_m_test, show=show_plots) + self.savefig(ax, "calibration_m_test.png") + legend = ax.get_legend() + self.assertIsNotNone(legend) + legend_labels = [text.get_text() for text in legend.get_texts()] + self.assertIn(self.cal_m_test.sim_name, legend_labels) + + def tearDown(self): + plt.close("all") + gc.collect() + + +class TestBatchPlots(TestPlots): + def setUp(self): + # Mocking EvaluationResult for testing + self.mock_result = Mock() + self.mock_result.sim_name = "Mock Forecast" + self.mock_result.test_distribution = numpy.random.normal(loc=10, scale=2, size=100) + self.mock_result.observed_statistic = 8 + + def test_plot_consistency_basic(self): + ax = plot_consistency_test(eval_results=self.mock_result, show=show_plots) + self.assertEqual(ax.get_title(), '') + self.assertEqual(ax.get_xlabel(), "Statistic distribution") + + def test_plot_consistency_with_multiple_results(self): + mock_results = [self.mock_result for _ in range(5)] + ax = plot_consistency_test(eval_results=mock_results, show=show_plots) + self.assertEqual(len(ax.get_yticklabels()), 5) + + def test_plot_consistency_with_normalization(self): + ax = plot_consistency_test(eval_results=self.mock_result, normalize=True, + show=show_plots) + # Assert that the observed statistic is plotted at 0 + self.assertEqual(ax.lines[0].get_xdata(), 0) + + def test_plot_consistency_with_one_sided_lower(self): + mock_result = copy.deepcopy(self.mock_result) + # THe observed statistic is placed to the right of the model test distribution. + mock_result.observed_statistic = max(self.mock_result.test_distribution) + 1 + ax = plot_consistency_test(eval_results=mock_result, one_sided_lower=True, + show=show_plots) + # The end of the infinite dashed line should extend way away from the plot limit + self.assertGreater(ax.lines[-1].get_xdata()[-1], ax.get_xlim()[1]) + + def test_plot_consistency_with_custom_percentile(self): + ax = plot_consistency_test(eval_results=self.mock_result, percentile=99, + show=show_plots) + + # Check that the line extent equals the lower 0.5 % percentile + self.assertAlmostEqual(ax.lines[2].get_xdata(), + numpy.percentile(self.mock_result.test_distribution, 0.5)) + + def test_plot_consistency_with_variance(self): + mock_nb = copy.deepcopy(self.mock_result) + mock_poisson = copy.deepcopy(self.mock_result) + mock_nb.test_distribution = ('negative_binomial', 8) + mock_poisson.test_distribution = ('poisson', 8) + ax_nb = plot_consistency_test(eval_results=mock_nb, variance=16, show=show_plots) + ax_p = plot_consistency_test(eval_results=mock_poisson, variance=None, show=show_plots) + # Ensure the negative binomial has a larger x-axis extent than poisson + self.assertTrue(ax_p.get_xlim()[1] < ax_nb.get_xlim()[1]) + + def test_plot_consistency_with_custom_plot_args(self): + ax = plot_consistency_test(eval_results=self.mock_result, show=show_plots, + xlabel="Custom X", ylabel="Custom Y", title="Custom Title") + self.assertEqual(ax.get_xlabel(), "Custom X") + self.assertEqual(ax.get_title(), "Custom Title") + + def test_plot_consistency_with_mean(self): + ax = plot_consistency_test(eval_results=self.mock_result, plot_mean=True, + show=show_plots) + # Check for the mean line plotted as a circle + self.assertTrue(any(["o" in str(line.get_marker()) for line in ax.lines])) def test_SingleNTestPlot(self): expected_val = numpy.random.randint(0, 20) observed_val = numpy.random.randint(0, 20) Ntest_result = mock.Mock() - Ntest_result.name = 'Mock NTest' - Ntest_result.sim_name = 'Mock SimName' - Ntest_result.test_distribution = ['poisson', expected_val] + Ntest_result.name = "Mock NTest" + Ntest_result.sim_name = "Mock SimName" + Ntest_result.test_distribution = ["poisson", expected_val] Ntest_result.observed_statistic = observed_val matplotlib.pyplot.close() - ax = plots.plot_poisson_consistency_test(Ntest_result) + plot_consistency_test(Ntest_result, show=show_plots) - self.assertEqual( - [i.get_text() for i in matplotlib.pyplot.gca().get_yticklabels()], - [i.sim_name for i in [Ntest_result]]) - self.assertEqual(matplotlib.pyplot.gca().get_title(), - Ntest_result.name) + if not show_plots: + self.assertEqual( + [i.get_text() for i in matplotlib.pyplot.gca().get_yticklabels()], + [i.sim_name for i in [Ntest_result]], + ) + self.assertEqual(matplotlib.pyplot.gca().get_title(), '') - def test_MultiNTestPlot(self, show=False): + def test_MultiNTestPlot(self): n_plots = numpy.random.randint(1, 20) Ntests = [] for n in range(n_plots): Ntest_result = mock.Mock() - Ntest_result.name = 'Mock NTest' - Ntest_result.sim_name = ''.join( - random.choice(string.ascii_letters) for _ in range(8)) - Ntest_result.test_distribution = ['poisson', - numpy.random.randint(0, 20)] + Ntest_result.name = "Mock NTest" + Ntest_result.sim_name = "".join( + random.choice(string.ascii_letters) for _ in range(8) + ) + Ntest_result.test_distribution = ["poisson", numpy.random.randint(0, 20)] Ntest_result.observed_statistic = numpy.random.randint(0, 20) Ntests.append(Ntest_result) matplotlib.pyplot.close() - ax = plots.plot_poisson_consistency_test(Ntests) + plot_consistency_test(Ntests, show=show_plots) Ntests.reverse() + if not show_plots: + self.assertEqual( + [i.get_text() for i in matplotlib.pyplot.gca().get_yticklabels()], + [i.sim_name for i in Ntests], + ) - self.assertEqual( - [i.get_text() for i in matplotlib.pyplot.gca().get_yticklabels()], - [i.sim_name for i in Ntests]) - self.assertEqual(matplotlib.pyplot.gca().get_title(), Ntests[0].name) - if show: - matplotlib.pyplot.show() - - def test_MultiSTestPlot(self, show=False): + def test_MultiSTestPlot(self): s_plots = numpy.random.randint(1, 20) Stests = [] for n in range(s_plots): Stest_result = mock.Mock() # Mock class with random attributes - Stest_result.name = 'Mock STest' - Stest_result.sim_name = ''.join( - random.choice(string.ascii_letters) for _ in range(8)) - Stest_result.test_distribution = numpy.random.uniform(-1000, 0, - numpy.random.randint( - 3, - 500)).tolist() - Stest_result.observed_statistic = numpy.random.uniform(-1000, - 0) # random observed statistic + Stest_result.name = "Mock STest" + Stest_result.sim_name = "".join( + random.choice(string.ascii_letters) for _ in range(8) + ) + Stest_result.test_distribution = numpy.random.uniform( + -1000, 0, numpy.random.randint(3, 500) + ).tolist() + Stest_result.observed_statistic = numpy.random.uniform( + -1000, 0 + ) # random observed statistic if numpy.random.random() < 0.02: # sim possible infinite values Stest_result.observed_statistic = -numpy.inf Stests.append(Stest_result) matplotlib.pyplot.close() - plots.plot_poisson_consistency_test(Stests) + plot_consistency_test(Stests) Stests.reverse() self.assertEqual( [i.get_text() for i in matplotlib.pyplot.gca().get_yticklabels()], - [i.sim_name for i in Stests]) - self.assertEqual(matplotlib.pyplot.gca().get_title(), Stests[0].name) + [i.sim_name for i in Stests], + ) - def test_MultiTTestPlot(self, show=False): + def test_MultiTTestPlot(self): - for i in range(10): + for i in range(1): t_plots = numpy.random.randint(2, 20) t_tests = [] - def rand(limit=10, offset=0): + def rand(limit=10, offset=0.): return limit * (numpy.random.random() - offset) for n in range(t_plots): t_result = mock.Mock() # Mock class with random attributes - t_result.name = 'CSEP1 Comparison Test' + t_result.name = "CSEP1 Comparison Test" t_result.sim_name = ( - ''.join(random.choice(string.ascii_letters) - for _ in range(8)), 'ref') + "".join(random.choice(string.ascii_letters) for _ in range(8)), + "ref", + ) t_result.observed_statistic = rand(offset=0.5) t_result.test_distribution = [ t_result.observed_statistic - rand(5), - t_result.observed_statistic + rand(5)] + t_result.observed_statistic + rand(5), + ] if numpy.random.random() < 0.05: # sim possible infinite values t_result.observed_statistic = -numpy.inf t_tests.append(t_result) matplotlib.pyplot.close() - plots.plot_comparison_test(t_tests) + plot_comparison_test(t_tests, show=show_plots) t_tests.reverse() - self.assertEqual( - [i.get_text() for i in - matplotlib.pyplot.gca().get_xticklabels()], - [i.sim_name[0] for i in t_tests[::-1]]) - self.assertEqual(matplotlib.pyplot.gca().get_title(), - t_tests[0].name) + if not show_plots: + self.assertEqual( + [i.get_text() for i in matplotlib.pyplot.gca().get_xticklabels()], + [i.sim_name[0] for i in t_tests[::-1]], + ) + self.assertEqual(matplotlib.pyplot.gca().get_title(), t_tests[0].name) + + def tearDown(self): + plt.close("all") + + gc.collect() + + +class TestPlotBasemap(TestPlots): + + def setUp(self): + self.chiloe_extent = [-75, -71, -44, -40] + + @patch("csep.utils.plots._get_basemap") + def test_plot_basemap_default(self, mock_get_basemap): + + mock_tiles = MagicMock() + mock_get_basemap.return_value = mock_tiles + ax = plot_basemap(show=show_plots) + self.assertIsInstance(ax, plt.Axes) + mock_get_basemap.assert_not_called() + + @patch("csep.utils.plots._get_basemap") + def test_plot_basemap_with_features(self, mock_get_basemap): + mock_tiles = MagicMock() + mock_get_basemap.return_value = mock_tiles + + basemap = 'stock_img' + ax = plot_basemap( + basemap=basemap, + extent=self.chiloe_extent, + coastline=True, + borders=True, + tile_scaling=5, + grid=True, + grid_labels=True, + grid_fontsize=8, + show=show_plots, + ) + + self.assertIsInstance(ax, plt.Axes) + mock_get_basemap.assert_not_called() + self.assertTrue(ax.get_legend() is None) + + @unittest.skipIf(is_github_actions, "Skipping test in GitHub CI environment") + @unittest.skipIf(not is_internet_available(), "Skipping test due to no internet connection") + def test_plot_google_satellite(self): + basemap = "google-satellite" + ax = plot_basemap( + basemap=basemap, + extent=self.chiloe_extent, + coastline=True, + tile_depth=4, + show=show_plots, + ) + self.assertIsInstance(ax, plt.Axes) + self.assertTrue(ax.get_legend() is None) + + @unittest.skipIf(is_github_actions, "Skipping test in GitHub CI environment") + @unittest.skipIf(not is_internet_available(), "Skipping test due to no internet connection") + def test_plot_esri(self): + basemap = "ESRI_terrain" + + ax = plot_basemap( + basemap, + self.chiloe_extent, + coastline=True, + borders=True, + tile_depth=4, + show=show_plots, + ) + self.assertIsInstance(ax, plt.Axes) + self.assertTrue(ax.get_legend() is None) + + @patch("csep.utils.plots._get_basemap") + def test_plot_basemap_set_global(self, mock_get_basemap): + # Mock the _get_basemap function + mock_tiles = MagicMock() + mock_get_basemap.return_value = mock_tiles + + # Test data for global view + basemap = None + ax = plot_basemap(basemap, set_global=True, show=show_plots) + + # Assertions + self.assertIsInstance(ax, plt.Axes) + mock_get_basemap.assert_not_called() + self.assertTrue(ax.get_extent() == (-180, 180, -90, 90)) + + def test_plot_basemap_with_custom_projection(self): + projection = ccrs.Mercator() + basemap = None + ax = plot_basemap(basemap, self.chiloe_extent, projection=projection, show=show_plots) + + self.assertIsInstance(ax, plt.Axes) + self.assertEqual(ax.projection, projection) + + def test_plot_basemap_with_custom_projection_and_features(self): + projection = ccrs.Mercator() + basemap = None + ax = plot_basemap(basemap=basemap, + extent=self.chiloe_extent, + projection=projection, + coastline=True, + borders=True, + grid=True, + grid_labels=True, + grid_fontsize=8, + show=show_plots) + + self.assertIsInstance(ax, plt.Axes) + self.assertEqual(ax.projection, projection) + + def tearDown(self): + + plt.close("all") + gc.collect() + + +class TestPlotCatalog(TestPlots): + + def setUp(self): + # Set up a mock catalog with basic properties + self.mock_catalog = MagicMock() + + size = numpy.random.randint(4, 20) + self.mock_catalog.get_magnitudes.return_value = numpy.random.random(size) * 4 + 4 + self.mock_catalog.get_longitudes.return_value = numpy.random.random(size) * 30 - 120 + self.mock_catalog.get_latitudes.return_value = numpy.random.random(size) * 30 + 30 + self.mock_catalog.name = "Mock Catalog" + + self.mock_catalog.get_bbox.return_value = [ + numpy.min(self.mock_catalog.get_longitudes()), + numpy.max(self.mock_catalog.get_longitudes()), + numpy.min(self.mock_catalog.get_latitudes()), + numpy.max(self.mock_catalog.get_latitudes()) + ] + + # Mock region if needed + self.mock_catalog.region.get_bbox.return_value = [-125, -85, 25, 65] + self.mock_catalog.region.tight_bbox.return_value = numpy.array( + [[-125, 25], [-85, 25], [-85, 65], [-125, 65], [-125, 25]] + ) + + def test_plot_catalog_default(self): + # Test plot with default settings + ax = plot_catalog(self.mock_catalog, show=show_plots) + self.assertIsInstance(ax, plt.Axes) + self.assertEqual(ax.get_title(), '') + + def test_plot_catalog_title(self): + # Test plot with default settings + ax = plot_catalog(self.mock_catalog, show=show_plots, title=self.mock_catalog.name) + self.assertIsInstance(ax, plt.Axes) + self.assertEqual(ax.get_title(), 'Mock Catalog') + + def test_plot_catalog_without_legend(self): + # Test plot with legend + ax = plot_catalog(self.mock_catalog, mag_scale=7, show=show_plots, legend=False) + legend = ax.get_legend() + self.assertIsNone(legend) + + def test_plot_catalog_with_custom_extent(self): + # Test plot with custom extent + custom_extent = (-130, 20, 10, 80) + ax = plot_catalog(self.mock_catalog, extent=custom_extent, show=show_plots) + self.assertIsInstance(ax, plt.Axes) + self.assertAlmostEqual(ax.get_extent(crs=ccrs.PlateCarree()), custom_extent) + + def test_plot_catalog_global(self): + # Test plot with global extent + ax = plot_catalog(self.mock_catalog, set_global=True, show=show_plots) + self.assertTrue(ax.spines["geo"].get_visible()) + + def test_plot_catalog_with_region_border(self): + # Test plot with region border + ax = plot_catalog(self.mock_catalog, show=show_plots, plot_region=True) + self.assertIsInstance(ax, plt.Axes) + + def test_plot_catalog_with_no_grid(self): + # Test plot with grid disabled + ax = plot_catalog( + self.mock_catalog, show=show_plots, grid=False + ) + gl = ax.gridlines() + self.assertIsNotNone(gl) + + def test_plot_catalog_w_basemap(self): + # Test plot with default settings + ax = plot_catalog(self.mock_catalog, basemap='stock_img', show=show_plots) + self.assertIsInstance(ax, plt.Axes) + self.assertEqual(ax.get_title(), '') + + def test_plot_catalog_w_basemap_stream_kwargs(self): + + projection = ccrs.Mercator() + ax = plot_catalog(self.mock_catalog, basemap=None, + projection=projection, + coastline=True, + borders=True, + grid=True, + grid_labels=True, + grid_fontsize=8, + show=show_plots) + self.assertIsInstance(ax, plt.Axes) + self.assertEqual(ax.get_title(), '') + + def test_plot_catalog_w_approx_projection(self): + projection = 'approx' + ax = plot_catalog(self.mock_catalog, basemap='stock_img', + projection=projection, + coastline=True, + borders=True, + grid=True, + grid_labels=True, + grid_fontsize=8, + show=show_plots) + self.assertIsInstance(ax, plt.Axes) + self.assertEqual(ax.get_title(), '') + + def tearDown(self): + plt.close("all") + gc.collect() + + +class TestPlotSpatialDataset(TestPlots): + + def setUp(self): + # Mock region and data + self.region = self.MockRegion() + self.gridded_data = numpy.random.rand(len(self.region.ys), len(self.region.xs)) + + class MockRegion: + def __init__(self): + self.xs = numpy.linspace(-20, 20, 100) + self.ys = numpy.linspace(-10, 10, 50) + + @staticmethod + def get_bbox(): + return [-20, 20, -10, 10] + + @staticmethod + def tight_bbox(): + return numpy.array([[-20, -10], [20, -10], [20, 10], [-20, 10], [-20, -10]]) + + def test_default_plot(self): + fig, ax = plt.subplots(subplot_kw={"projection": ccrs.PlateCarree()}) + ax = plot_spatial_dataset(self.gridded_data, self.region, ax=ax) + self.assertIsInstance(ax, plt.Axes) + + def test_extent_setting_w_ax(self): + extent = (-30, 30, -20, 20) + ax = plot_spatial_dataset( + self.gridded_data, self.region, extent=extent, show=show_plots + ) + numpy.testing.assert_array_almost_equal(ax.get_extent(crs=ccrs.PlateCarree()), extent) + + def test_extent_setting(self): + extent = (-30, 30, -20, 20) + ax = plot_spatial_dataset( + self.gridded_data, self.region, extent=extent, show=show_plots + ) + numpy.testing.assert_array_almost_equal(ax.get_extent(crs=ccrs.PlateCarree()), extent) + # self.assertAlmostEqual(ax.get_extent(crs=ccrs.PlateCarree()), extent) + + def test_color_mapping(self): + cmap = plt.get_cmap("plasma") + fig, ax = plt.subplots(subplot_kw={"projection": ccrs.PlateCarree()}) + ax = plot_spatial_dataset(self.gridded_data, self.region, ax=ax, colormap=cmap, show=show_plots) + self.assertIsInstance(ax.collections[0].cmap, colors.ListedColormap) + + def test_gridlines(self): + fig, ax = plt.subplots(subplot_kw={"projection": ccrs.PlateCarree()}) + ax = plot_spatial_dataset(self.gridded_data, self.region, ax=ax, grid=True, show=show_plots) + self.assertTrue(ax.gridlines()) + + def test_alpha_transparency(self): + fig, ax = plt.subplots(subplot_kw={"projection": ccrs.PlateCarree()}) + ax = plot_spatial_dataset(self.gridded_data, self.region, ax=ax, alpha=0.5, show=show_plots) + self.assertIsInstance(ax, plt.Axes) + + def test_plot_with_alpha_exp(self): + ax = plot_spatial_dataset( + self.gridded_data, self.region, alpha_exp=0.5, include_cbar=True, show=show_plots + ) + self.assertIsInstance(ax, plt.Axes) + + def test_include_colorbar(self): + fig, ax = plt.subplots(subplot_kw={"projection": ccrs.PlateCarree()}) + ax = plot_spatial_dataset( + self.gridded_data, self.region, ax=ax, include_cbar=True, show=show_plots + ) + colorbars = [ + child + for child in ax.get_figure().get_children() + if isinstance(child, plt.Axes) and "Colorbar" in child.get_label() + ] + self.assertGreater(len(colorbars), 0) + + def test_no_region_border(self): + fig, ax = plt.subplots(subplot_kw={"projection": ccrs.PlateCarree()}) + ax = plot_spatial_dataset( + self.gridded_data, self.region, ax=ax, plot_region=False, show=show_plots + ) + lines = ax.get_lines() + self.assertEqual(len(lines), 0) + + def test_plot_spatial_dataset_w_basemap_stream_kwargs(self): + + projection = ccrs.Mercator() + ax = plot_spatial_dataset( + self.gridded_data, + self.region, + extent=[-20, 40, -5, 25], + projection=projection, + coastline=True, + borders=True, + grid=True, + grid_labels=True, + grid_fontsize=8, + show=show_plots, + plot_region=False + ) + + self.assertIsInstance(ax, plt.Axes) + self.assertEqual(ax.get_title(), '') + + def test_plot_spatial_dataset_w_approx_projection(self): + projection = 'approx' + ax = plot_spatial_dataset( + self.gridded_data, + self.region, basemap='stock_img', + extent=[-20, 40, -5, 25], + projection=projection, + coastline=True, + borders=True, + grid=True, + grid_labels=True, + grid_fontsize=8, + show=show_plots, + plot_region=False + ) + + self.assertIsInstance(ax, plt.Axes) + self.assertEqual(ax.get_title(), '') + + def tearDown(self): + plt.close("all") + del self.region + del self.gridded_data + gc.collect() + + +class TestHelperFunctions(TestPlots): + + def setUp(self): + # Set up a mock catalog with basic properties + self.mock_catalog = MagicMock() + self.mock_catalog.get_bbox.return_value = [-120, -115, 30, 35] + self.mock_catalog.get_magnitudes.return_value = numpy.array([3.5, 4.0, 4.5]) + + # Mock region if needed + self.mock_catalog.region.get_bbox.return_value = [-120, -115, 30, 35] + + def test_get_marker_style(self): + self.assertEqual(_get_marker_style(1, [2, 3], False), "ro") + self.assertEqual(_get_marker_style(2, [1, 3], False), "gs") + self.assertEqual(_get_marker_style(1, [2, 3], True), "ro") + self.assertEqual(_get_marker_style(4, [2, 3], True), "gs") + + def test_get_marker_t_color(self): + self.assertEqual(_get_marker_t_color([1, 2]), "green") + self.assertEqual(_get_marker_t_color([-2, -1]), "red") + self.assertEqual(_get_marker_t_color([-1, 1]), "grey") + + def test_get_marker_w_color(self): + self.assertTrue(_get_marker_w_color(0.01, 95)) + self.assertFalse(_get_marker_w_color(0.99, 95)) + + def test_get_axis_limits(self): + pnts = numpy.array([1, 2, 3, 4, 5]) + expected_limits = (0.8, 5.2) + self.assertEqual(_get_axis_limits(pnts, border=0.05), expected_limits) + + def test_add_labels_for_publication(self): + fig = plt.figure() + ax = fig.add_subplot(111) + _add_labels_for_publication(fig) + annotations = [child for child in ax.get_children() if isinstance(child, Annotation)] + self.assertEqual(len(annotations), 1) + self.assertEqual(annotations[0].get_text(), "(a)") + + def test_autosize_scatter(self): + values = numpy.array([1, 2, 3]) + scale = 1.5 + expected_sizes = (2 / (scale**1)) * numpy.power(values, scale) + numpy.testing.assert_array_almost_equal( + _autosize_scatter(2, values, scale), expected_sizes + ) + + def test_size_map(self): + values = numpy.array([1, 2, 3]) + scale = 1.5 + expected_sizes = (2 / (scale**1)) * numpy.power(values, scale) + numpy.testing.assert_array_almost_equal(_size_map(2, values, scale), expected_sizes) + + def test_autoscale_histogram(self): + fig, ax = plt.subplots() + simulated = numpy.random.normal(size=1000) + observation = numpy.random.normal(size=1000) + bin_edges = numpy.linspace(-5, 5, 21) + + ax = _autoscale_histogram(ax, bin_edges, simulated, observation) + + x_min, x_max = ax.get_xlim() + + self.assertGreaterEqual(x_min, -6) + self.assertLessEqual(x_max, 6) + self.assertGreater(x_max, x_min) + + def test_annotate_distribution_plot(self): + # Mock evaluation_result for Catalog N-Test + evaluation_result = Mock() + evaluation_result.name = 'Catalog N-Test' + evaluation_result.sim_name = 'Simulated Catalog' + evaluation_result.quantile = [0.25, 0.75] + evaluation_result.observed_statistic = 5.0 + + ax = plt.gca() + plot_args = { + "annotation_text": None, + "annotation_xy": (0.5, 0.5), + "annotation_fontsize": 12, + "xlabel": None, + "ylabel": None, + "title": None, + } + + ax = _annotate_distribution_plot(ax, evaluation_result, auto_annotate=True, + plot_args=plot_args) + + # Assertions to check if the annotations were correctly set + self.assertEqual(ax.get_xlabel(), 'Event Count') + self.assertEqual(ax.get_ylabel(), 'Number of Catalogs') + self.assertEqual(ax.get_title(), 'Catalog N-Test: Simulated Catalog') + + annotation = ax.texts[0].get_text() + expected_annotation = ( + f'$\\delta_1 = P(X \\geq x) = 0.25$\n' + f'$\\delta_2 = P(X \\leq x) = 0.75$\n' + f'$\\omega = 5.00$' + ) + self.assertEqual(annotation, expected_annotation) + + def test_calculate_spatial_extent(self): + # Test with plot_region and set_global=False + extent = _calculate_spatial_extent( + self.mock_catalog, set_global=False, region_border=True + ) + expected_extent = [-120.25, -114.75, 29.75, 35.25] + self.assertEqual(extent, expected_extent) + + # Test with set_global=True + extent = _calculate_spatial_extent( + self.mock_catalog, set_global=True, region_border=True + ) + self.assertIsNone(extent) + + # Test with no plot_region + extent = _calculate_spatial_extent( + self.mock_catalog, set_global=False, region_border=False + ) + self.assertEqual(extent, expected_extent) + + def test_create_geo_axes(self): + # Test GeoAxes creation with no extent (global) + ax = _create_geo_axes(figsize=(10, 8), extent=None, projection=ccrs.PlateCarree(), + set_global=True) + self.assertIsInstance(ax, plt.Axes) + self.assertAlmostEqual(ax.get_xlim(), (-180, 180)) + self.assertAlmostEqual(ax.get_ylim(), (-90, 90)) + + # Test GeoAxes creation with a specific extent + extent = (-125, -110, 25, 40) + ax = _create_geo_axes(figsize=(10, 8), extent=extent, projection=ccrs.PlateCarree(), + set_global=False) + self.assertIsInstance(ax, plt.Axes) + self.assertAlmostEqual(ax.get_extent(), extent) + + def test_calculate_marker_size(self): + # Test marker size calculation with a scale factor + magnitudes = numpy.array([4.0, 5.0, 6.0]) + markersize = 5 + scale = 1.2 + sizes = _calculate_marker_size(markersize, magnitudes, scale) + expected_sizes = (markersize / (scale ** min(magnitudes))) * numpy.power( + magnitudes, scale + ) + numpy.testing.assert_array_almost_equal(sizes, expected_sizes) + + # Test marker size calculation with a fixed scale array + scale_array = numpy.array([10, 20, 30]) + sizes = _calculate_marker_size(markersize, magnitudes, scale_array) + numpy.testing.assert_array_almost_equal(sizes, scale_array) + + # Test invalid scale type + with self.assertRaises(ValueError): + _calculate_marker_size(markersize, magnitudes, "invalid_scale") + + def test_add_gridlines(self): + # Test adding gridlines to an axis + fig, ax = plt.subplots(subplot_kw={"projection": ccrs.PlateCarree()}) + _add_gridlines(ax, grid_labels=True, grid_fontsize=12) + gl = ax.gridlines() + self.assertIsNotNone(gl) + + @patch("csep.utils.plots.img_tiles.GoogleTiles") + def test_get_basemap_google_satellite(self, mock_google_tiles): + # Simulate return value for Google satellite + mock_google_tiles.return_value = MagicMock() + tiles = _get_basemap("google-satellite") + mock_google_tiles.assert_called_once_with(style="satellite", cache=True) + self.assertIsNotNone(tiles) + + @patch("csep.utils.plots.img_tiles.GoogleTiles") + def test_get_basemap_esri_terrain(self, mock_google_tiles): + # Simulate return value for ESRI terrain + mock_google_tiles.return_value = MagicMock() + tiles = _get_basemap("ESRI_terrain") + mock_google_tiles.assert_called_once_with( + url="https://server.arcgisonline.com/ArcGIS/rest/services/World_Terrain_Base/" + "MapServer/tile/{z}/{y}/{x}.jpg", + cache=True + ) + self.assertIsNotNone(tiles) + + @patch("csep.utils.plots.img_tiles.GoogleTiles") + def test_get_basemap_custom_url(self, mock_google_tiles): + # Simulate return value for custom URL + custom_url = "https://custom.tileserver.com/tiles/{z}/{y}/{x}.jpg" + mock_google_tiles.return_value = MagicMock() + tiles = _get_basemap(custom_url) + mock_google_tiles.assert_called_once_with(url=custom_url, cache=True) + self.assertIsNotNone(tiles) + + def test_plot_basemap_basic(self): + basemap = "stock_img" + extent = [-180, 180, -90, 90] + ax = plot_basemap(basemap, extent, show=show_plots) + self.assertIsInstance(ax, plt.Axes) + + def test_plot_basemap_no_basemap(self): + # Test with no basemap (should handle it gracefully) + extent = [-75, -71, -44, -40] + ax = plot_basemap(None, extent, show=show_plots) + + # Assertions + self.assertIsInstance(ax, plt.Axes) + + def test_default_colormap(self): + cmap, alpha = _define_colormap_and_alpha("viridis", 0) + self.assertIsInstance(cmap, matplotlib.colors.ListedColormap) + expected_cmap = plt.get_cmap("viridis") + self.assertTrue(numpy.allclose(cmap.colors, expected_cmap(numpy.arange(cmap.N)))) + + def test_custom_colormap(self): + cmap = plt.get_cmap("plasma") + cmap, alpha = _define_colormap_and_alpha(cmap, 0) + self.assertIsInstance(cmap, matplotlib.colors.ListedColormap) + expected_cmap = plt.get_cmap("plasma") + self.assertTrue(numpy.allclose(cmap.colors, expected_cmap(numpy.arange(cmap.N)))) + + def test_alpha_exponent(self): + cmap, alpha = _define_colormap_and_alpha("viridis", 0.5) + self.assertIsInstance(cmap, matplotlib.colors.ListedColormap) + self.assertIsNone(alpha) + # Check that alpha values are correctly modified + self.assertTrue(numpy.all(cmap.colors[:, -1] == numpy.linspace(0, 1, cmap.N) ** 0.5)) + + def test_no_alpha_exponent(self): + cmap, alpha = _define_colormap_and_alpha("viridis", 0) + self.assertEqual(alpha, 1) + self.assertTrue(numpy.all(cmap.colors[:, -1] == 1)) # No alpha modification + + def test_add_colorbar(self): + fig, ax = plt.subplots() + im = ax.imshow(numpy.random.rand(10, 10), cmap="viridis") + _add_colorbar( + ax, im, clabel="Colorbar Label", clabel_fontsize=12, cticks_fontsize=10 + ) + + # Check if the colorbar is added to the figure + colorbars = [ + child + for child in fig.get_children() + if isinstance(child, plt.Axes) and "Colorbar" in child.get_label() + ] + self.assertGreater(len(colorbars), 0) + + # Check colorbar label and font sizes + cbar = colorbars[0] + self.assertEqual(cbar.get_ylabel(), "Colorbar Label") + self.assertEqual(cbar.get_ylabel(), "Colorbar Label") + self.assertEqual(cbar.yaxis.label.get_size(), 12) + + # Check tick label font size + tick_labels = cbar.get_yticklabels() + self.assertTrue(all(label.get_fontsize() == 10 for label in tick_labels)) + + def tearDown(self): + plt.close("all") + gc.collect() + + +class TestPlotAlarmBasedEvaluations(unittest.TestCase): + + def setUp(self): + # Set up a mock catalog with basic properties + self.forecast = MagicMock() + self.forecast.region = MagicMock() + self.forecast.spatial_counts.return_value = numpy.array([1, 10, 2, 40, 50, 2, 70, 80]) + self.forecast.name = "Test Forecast" + + self.catalog = MagicMock() + self.catalog.region = self.forecast.region + self.catalog.spatial_counts.return_value = numpy.array([2, 8, 0, 38, 52, 0, 67, 78]) + self.catalog.region.get_cell_area.return_value = numpy.array([1, 1, 1, 1, 2, 2, 2, 2]) + self.catalog.name = "Test Catalog" + + def test_plot_concentration_ROC_diagram(self): + ax = plot_concentration_ROC_diagram(self.forecast, self.catalog, show=show_plots) + self.assertIsInstance(ax, plt.Axes) + + def test_plot_ROC_diagram(self): + ax = plot_ROC_diagram(self.forecast, self.catalog, show=show_plots) + self.assertIsInstance(ax, plt.Axes) + + def test_plot_Molchan_diagram(self): + + ax = plot_Molchan_diagram(self.forecast, self.catalog, show=show_plots) + self.assertIsInstance(ax, plt.Axes) + + def tearDown(self): + plt.close("all") + gc.collect() + + +class TestProcessDistribution(unittest.TestCase): + + def setUp(self): + self.result_poisson = mock.Mock() + self.result_poisson.test_distribution = ['poisson', 10] + self.result_poisson.observed_statistic = 8 + + self.result_neg_binom = mock.Mock() + self.result_neg_binom.test_distribution = ['negative_binomial', 10] + self.result_neg_binom.observed_statistic = 8 + + self.result_empirical = mock.Mock() + self.result_empirical.test_distribution = numpy.random.normal(10, 2, 100) + self.result_empirical.observed_statistic = 8 + + def test_process_distribution_poisson(self): + plow, phigh, mean, observed_statistic = _process_stat_distribution( + self.result_poisson, percentile=95, variance=None, normalize=False, + one_sided_lower=False + ) + self.assertAlmostEqual(mean, 10) + self.assertAlmostEqual(observed_statistic, 8) + self.assertTrue(plow < mean < phigh) + + def test_process_distribution_negative_binomial(self): + variance = 12 + plow, phigh, mean, observed_statistic = _process_stat_distribution( + self.result_neg_binom, percentile=95, variance=variance, normalize=False, + one_sided_lower=False + ) + self.assertAlmostEqual(mean, 10) + self.assertAlmostEqual(observed_statistic, 8) + self.assertTrue(plow < mean < phigh) + + def test_process_distribution_empirical(self): + plow, phigh, mean, observed_statistic = _process_stat_distribution( + self.result_empirical, percentile=95, variance=None, normalize=False, + one_sided_lower=False + ) + self.assertAlmostEqual(mean, numpy.mean(self.result_empirical.test_distribution)) + self.assertAlmostEqual(observed_statistic, 8) + self.assertTrue(plow < mean < phigh) + + def test_process_distribution_empirical_normalized(self): + plow, phigh, mean, observed_statistic = _process_stat_distribution( + self.result_empirical, percentile=95, variance=None, normalize=True, + one_sided_lower=False + ) + self.assertAlmostEqual(mean, numpy.mean(self.result_empirical.test_distribution - + self.result_empirical.observed_statistic)) + self.assertAlmostEqual(observed_statistic, 0) + self.assertTrue(plow < mean < phigh) + + def test_process_distribution_empirical_one_sided(self): + plow, phigh, mean, observed_statistic = _process_stat_distribution( + self.result_empirical, percentile=95, variance=None, normalize=False, + one_sided_lower=True + ) + self.assertAlmostEqual(mean, numpy.mean(self.result_empirical.test_distribution)) + self.assertAlmostEqual(observed_statistic, 8) + self.assertTrue(plow <= mean <= phigh) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() From ada9191e96c0acce1267900817b7daa4cfe2777a Mon Sep 17 00:00:00 2001 From: pciturri Date: Thu, 22 Aug 2024 16:12:13 +0200 Subject: [PATCH 02/17] ft: Added rasterio reader for plot_basemap, which plots a raster in the same projection of the cartopy GeoAxes. ft: Added cache handler for plot_basemap. Uses the cache option from cartopy, but removes the cache if a different basemap source is selected (otherwise it would get stuck with the first cached map). tests: added .tif basemap plotting to existing unit tests build: added rasterio as requirement --- .../ExampleBasemaps/basemap_california.tif | Bin 0 -> 1604416 bytes csep/utils/datasets.py | 5 + csep/utils/plots.py | 140 ++++++++++++------ examples/tutorials/plot_customizations.py | 9 +- requirements.txt | 1 + requirements.yml | 1 + requirements_dev.txt | 1 + setup.py | 1 + tests/test_plots.py | 9 ++ 9 files changed, 119 insertions(+), 48 deletions(-) create mode 100644 csep/artifacts/ExampleBasemaps/basemap_california.tif diff --git a/csep/artifacts/ExampleBasemaps/basemap_california.tif b/csep/artifacts/ExampleBasemaps/basemap_california.tif new file mode 100644 index 0000000000000000000000000000000000000000..5537a75ad72443075188d25a060ba456f51ae201 GIT binary patch literal 1604416 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�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�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

Z>K(d z>z9U4hW_}I>x1N4)TbYvZ$kH@wu;P`x`TKd&b6cQEy4eShZud>`F776YTN2rrJSxV zcmi+o6nd{bt5zjXngwq5hkZNcb3Ns;OtX4X3u;Cf$3<=l4*YdBK9A?y* z_hwD0J`nF?zKlA0u)4X8`0B%7kG@*7hu6*i$mc!mXOXXLFQsC9;dxpHkA04{`^mnc zi>r<5$1mzb@xypKY@Wv%jupJWj9{-M#{-T{E}^aJd6CoQms5D)_4l6K&-el#Ks$Av zE_zyzQ!C(o^kC?{?}E+GhVKP0JH1xrZu`NSeR-jKnn~eyHTM>3fc2_d3u@1zLHfL! z+tPwQe&G~-HwVdLp&m8fYw88m;V+$nw_(m7zVNTh=q~E)ju~Y2PI{o)PqgjWR$ixb z5r@&r_oRLFgw=;}zGXw&v&w9vC3t_NN2qcahOixeeb7eB817#neK7M|&O}TK#l7Oi!W1 z>u2F{$J23?Y@aP;TpxNh&3pQ5k^N$x%VhmZ*a?=e;CqE1*&My&ikG3)1=p50l$S zeJK9*zOqNs>7%eWd5z0o{{7Hutz{jopx(7&0UqWj@zT%_XW2t(m@JUNgZP`v7f=)X zINI>i$nCBr2S$Ih-iq=Kucpc^ucsrM=B8Vxb}(jmF??bLr!$X54esI>zn=E3cq+UZ z&KsO1Q@#)1{yVcDiSfJN6Mq-YxB9gmp*q&D7R);x>7iuAh-&_A`C z&qViuxzSh1?AwY>jDdpF3r#&ZJ$PN;%hK?vJOAK3MK4*6Yv(_jrmEkh|LgNfty{i! zj>X&63?Z> ztDXq{KD6vX){irH@)$jDAEBn;NjUu>>W807jhh~c&w<<4Zhq!&=yd0h^=$>*hv?)~!Z_j(NLR{O^$gVV3S`$6wo#Hzy6!> zzx=CzbBEQ{*6+sYdSC9Pr_c1gWY3E^FF8YfsJ$lqE@RydQAhgG#o_S5nBg+eQW<^~ z^T$HVi|ixz(T;P%kb`%YFwM*3;|?fPBJ zRCGOsKJWVa1X(iV!F1KrqY-XbU)Qs)27h^^ncJA}@2*b&=%dN>!^=JNFxrx;$etc; zucX$rBfK#`ywpt}(vxIWkhOTOB^}(lEb^c~Jx_n!!`srIesG#h^%nBf$!qVcg+r2C@jJIC4FKTP)56*G%Ipu4|3F_F92T47luR*O}o>w0qCJRQdkN#%;_O0DKgL!lEU`FBVQEE-!9ijgao^|U7955lnZziL?OJ#C1Ue5Pb2e;?UMR`2eh~~AtuEy@-?cte$)uWyjeSNsa z44J|gBggB%DR^ElJKs6R4w0=6tDo;Wghz?j$9riVhdKCLm%ReN?@Mje-CpE%>1)4o z>QM0b7@zNnhIQ${x>;%4l4l~nQP!*7hp(#rAo)25W2~pw<=x&L>4PE0I42l;QNK4< zvnuUd{c<|8aW;DDDts_+q^X*>srh_}y1*AAudrbU+393(*q2>j@Zwj#joo=*qX zycAmPnm3+czH4o;v3W6D-uP~^mQI*l#6q@XT)i0pgF5|iA&%m(^T^Jrc+ps)sdi!a58ksY% zM|*X;#2m)C#uaG%^kUdU4ZO{xUUtVYem0J+dy*XU z@21uG`epR?ZQoBDX8lfj>$yJ&PVXSc(HxyqFuKe>TD6G0b$);8x7E7)H8S&GN=Mc_ zO^pM!qwAlF{#VtTUm(Nhh19vL7>jkm{Q6#wk|A_>#UrU=^`o&qw)Tmrb#B=D92qc= zraG9tYQxhd#B~4SZ*v6h#_0EbFJJyhW~yY+(TNtbEm>CD!yGq=m=)`m`;yBIZ> zvaNm*nZA_MGuM~0etsMueTgZI{OBV3`4C=}9u~Civ)z%SXpVY)1-a?uDq0Jw zMs5!xv(NRP+Z#!5`zIIs$x}QS+326(W7i{N|D-807xlHv>*lh5ba60!e1S0yk8769 zXN(QH>kgzbm|dTHcg>#YFKQm+Sv>M;?Pk9G;@#nNYn<$Km(lukiyXQ0r;g$eCgbHW z{Zo$bOvm@ZbJUvp_#fkU|Lj5s9vJ$&!zlW6KO`sp)u+E3S%J;ytnUv|v)YT^38P#4 zICvaC3!cbhTjoYT9P|Fb@_9PWk+5=cJ}oqL zIo}#sYe}PT(X_X{*mt#cHTEsR%x0SKL@W)(HqKfj#=W?GdMPJ%+Shs!8%gCH63Qi;9GGF zFa@7q?1g=Kj;r(x>U8|XIPN069)6qFgJcl#d30gF^tF%UG4G?!^u5#MDZ%8;6?lPQ z_t4ML$L)=DhsV{>izQ!|*QdGO44GUvnzi=4{UrLko|xN9a698_#sv0a8gC@|4K%hHnB-w#dnTKk4zqWAiD<7ptHkzSkw6$^t?^=a#S(64@~9DYK>+)ppk)-v?* zMcO`PxNktm4&F zyY=O?f9dzgW&gv}e-y4fJU@KU!-ro
4RcP#6=J9afanpdZ@7tLD9-jvVl*!g?lcO#gb?{{W%=egwaycEAP{NBjrEdIur$CCf| z_N)tJeLd^wvF5ii{|?=2Z3b?xp*Nq&4EU4uS8%bnsGf9tyvpg@cu)1Pn2))4#j|9g zzmRJ2?1%TIgwu2XDCZvRRir<>iu^_UvzEiq-Fsh1&0D^o=0E*=)Or39zVx|xUEYk` zb>}th$)%1ye2m&s#&iukUXIV0{Ya~syE(e{si<)r`E{D#x|G3Z-mmnwdtG*X z;+%lKmy6eLrEBlr(bM(4xcu>-{8=pWx!&}D`p^H*^jE+7oAeid^{ezR{_?Mr9(Dh> zPid+D1XeqN&RT;r>Fsy*{`4O;W26>3+4t{kDt(U)T~Dz@BIry z;i;MGr~f$ho_+XXtV=yN*c$og*2eXsyIV(keT*7aGSKUf;ALz)9DIGYuRgsuNfr(B z`#-#jmXFWYUXN;npTOVcJC>zGTj-C22l?=}C8=!f!te=K>{^+wjkTr^&vnB)=!*Do zuZ`4)pLq2``jQ;lh=;f?-5Q`ij#^DMJvEliOI}DT=RX-Nd4{ZKc~TF$o)EnxX04bN zB8%$z*3V*1r>v_EUFv)BvYNFS=tWivndxZAo`d_*)O*Ps>%ddlfriv}kow0x_z#aYA1ac;bt>p z^x9Y->TA)*BIi4Aka9M z$As76``}p0p0oCBY{Um*ezz2(dV@Y5uS_2dGsf-Mp4KmV zF?~3CjN{MelsSW=JE;RC5A(y(qs(cLdDFvO1{$&bA}1TxqL0I4XqdHl#dj`y4*$no z{MHN8n<0= z+fSgmE=lLeI#(|rJ2pS9n*B}m@9(7}>t0G57gGDTp6~hV-;4f0>lQwhuC{MXZ$AG= z=-e;juc1Bz--RA!HTH8S>A^%k%cYac(Zpv{8~SjX^W-0-HS-@yXBt<>;~rqFFhQ@> zm1H_j9DOw{cj&xq`8hMg=l}1%#y`VvU+&SQr@Vz) zP<`dr*E;U$*2j-G$^KT>YnnxWY#n`8*S(xBFuzc{V@`Y?vYxIE?=oDun0z1d7I!ih z!hfRfz2t>|2q!<9+RL6#-~PS77vrRAGWnaSOFl{Os19=JI}YG=*^mF_2y?3V;WsTL zlb_GWL0J1RzAHU2t<)Zv&DhH0?x%Nb7j?zG6*3*Cd z^IwKP-L)FJ+IeugUYGytUqv>fjP7NZQt!*%IQ_TL)2$J;r;&X~^`{S$nLYxq>j$6e zYf5c3hr*X4gZ}`3xLGRZy_ls~TfUoqrM>Cc{%z?KSl`F6SJF@4or25Bb0NdU-bb#l zjfPh9P?djAG8Fsi6)J;v<~u+tG3Y7HE} zjQ{J}M%MPU6W7%~zJxqdr|rTB@b1_YT09`ak4t&%^qu^`#%%OkWq6wvk2OO~-UCX=v(f ztFPk5DY7%r+RZ+3F*C;AK>9)C@yzMPxv|J*^W1HApyyO?FSyrS}(bb9X=6`k8=%X!+1<&_~S5o8y<0)yYTK5>lk04 zsYj*@KGn7(c-wg$K92gjV;(aa&1T7CA)mW+Kdf){I``3S&2#a&<#*=;yzd3_%pG5u zQ)A}6x0~gnZ^cX={p)A(Z^)G9HL4*`P*ZA+qdAV|s~@CB^8Jar;<l($9;0@7zK&zM}TnN5&%T<4NXy^rAcVsM@_e`k%_>_TMt= z#oYG+a^Lm4n;A3Id^k8=9@l@aPhE{&b~l?*?L2!~^rDw~UT!nG+WSl$y@b>4M`|`q zEL_&RejZ=Gxs@XvGsix@?{)iEMdrlf8ukgUWO;+$*9*W-+*qpX;ys39j6}KIv+jWzLR`!H_Qo^ z9jjkYug#~@=0#7Z%Jt8ZE&h1gw)ENXF&tPsJB{(3a8Bw*4|Ute7IFI%p>^wn89%-d z{`!8}w-O)2W_&exPgcJEP-ODS;hkiwZ^g6n+LK>TQ`D0Wli#?14LW-#<5%{1qJC8x zu9zRWkY@6k@mP*Or?31?p64+<^e?1EFMd6G6Kz`XEm(b4T0j4x=vi96{$(=FXQAyc zPg~x`%Zwjg|Aun~ht|QP+sK|`?m$m^*3zAG(#LJB$*EbGq{qa(WLrExtGF=6;L1gvV27*)yqq=ab}Y{!V&>jLm~7j`pp18o&9YY2&cb&J%OrQV1+uCjJ#_^faW#-J*zwKIGJl{7n_!q6ck6xbYruNj* z-IpdWTuv9S-AY$)y&u`>_BwLW_o9|Aqnnv7umAP0{$=Rrna`~yHS{vH{Nzxd!RwWvM8`R|<{jP1-(zcAFsgURLu1-zIb|w20+4ty2S5Afh!0SJz{!^Xt zy)m+4$V7j4fhU&t%eru!(2HFt*g5B%hNY@6) znj@cLCv2fNJqRw|Xv=Vbz=~wk~8psgHtd z?djQ#o~z#O`B(mS(R+~Rusyf>JjMCgnoqPb&XITYu|iju6J>R|vOmTdMc#@&7(E`| z7WwS3dBNw@ccOQ@e`;xF$$K2^kK|*`TrywhIR&{{ZQb6djz6p~^)<-^YW+hzPr?4h zxG3k&+-+^XdtSUfU(Rb;U2b<=;(kt$0j}n)e`S>X7<_^OV_e29Dn9nYnvZ%sh-jDqdQ8QYjc zX|Gqu3g!#xPuKg>UbQ3Lpr6tx*^NKG+!eK}Ke^PBPT-%f!P9O1#3(hVqiyBXP9LN; zgWgB5w)%SEWht^=^urXMb#fTd!)10eAKf-M-8G9$Uufq=f22D)I$19;yNi5o9(!J{ z4%M>1The*zZfh7D9;PO=kIeOByH-Tz%Y|O%*6;^iW324B#B8A5d>{9%U%-1()ay=> z|5CY~-b0K<&oysMi(h>RUjzMrmf!`iU5p+4rn?Cj9xQ;QD~$&Q}z-Cuw2gUDw5!H<3#b)@FL$msSpGA})r zf5Do?ex!1GY2J%jFIiK+8>eUAi+=Q(OU`3-ojF}LzYM3}IyXR8%RuxWH51)zMSBum zp*QH6esWy!rMI2f2b=FtzxePROidmO`H61xqw8aliQWRY>o@mt)Yjj}=kjB+Vm`St zoc{Q|(~JRX*uD?n`51jldn5nx=dk@xZ%yD|-ye0T<~0ts98En9N1|@@)|6T5&FL~( zEgz7t*iu!7N1ooL<1OjP&Xws?dXC;2Kbd}fsVnkZ{JlShH{=L8aYwf=O1tpAn1yG( z=+Cb8(#xeLcv20$;UL-8@b#`$v(jg$tI~BeYUkHaFzkD8c*0+J`ZkZ9V{K3YG2QyK2^TYKAM8l^BARAhwhC(NLDu+ z$H$AhT=u;k#`iVoBT@5K`!+LD-+Aj1axka)`#0hAd>_3h>h3bM`uF+vop{-g&_i=s z9CPas%D2$#1P#BP>_xL)^og4{C{LGfUy`m59*dlws7v58U~Z&yBQkr@mx+uT#tVh+ z?`Hrn6t7cuvF2E2RkycqsXD*@81wxr%T|VVZg!F0_;cN4Irdjf--kY2o%_i?Tuinj zHP-0q=kSf|^|IfQd~Uu=!Qe%I(kXmlYV78yo9mK&=Vmj?=YLB_S3959&nMyX%;>VY zm+iIWl3CsHg1M;8%u7`>hG?rK*B`CDmfo$0wk%Fp`l%l;TTZqOxj4NCn4_W>48C;p zl{`**%Pw~AfxV~?KF+w848p7AJRaMGr<)$_=9$cPkkHM3NH zKix>(YTNd-b;)z-BH1$?hZaQ+&AWYN>2m9uWG2W3uCLmTk7U<^$W$MzSq_W8O25(v zQt#n;=%r7kqwC4f#=oNPyo^kBwbVX5$`f^rm&p<8#vgu~{j4i{GwL@>6HWb%;mMe9ruZ`0IXhL zhW7&Q4o;uJ=LL(~cNA|*aCE`y&bj%0&RlKXr{nU>Z&CPN_>J**#^=%N;_pxR)44p;`w~5i`Q5Sx#qpNwB9n0q z{w6Y4@y9tnasD7{7JgRr2Rf(WSVm7&`NmnPY&kW!)E7HHVOCBLIWcPK!Rd_A&f!5C zI5HOvo%+x952ukMucZFHPp3DY|D%|9iOfgFRrW7+e5KFEEOmPx`QDn5--PeHeb+NF zZ_>!PaW9{j;bRL^)utE8aHO9`+3PVLXx}?4vN89fvzIM>99Dld^&WU7yz1pEsU?Qh z>o(I@iKS}&)3EyeI?^vkllR{0UV8d{PQUjtE4?N2b!B~Xs%z;?=AG2CmXS+y88es9 zT<80L*>&dhnVP!K_hq;|^Yy)0J>RZAo-h9H1%CzKi{h za_y+z7d7?py8P>Zdz;O(re2!&VxOa2M;e?yqaSJJ^~~wP=>P4%ryFNrbNGDX)XDIx ze2C}8zN15U%hk=zIaf>n;M^%ZCuB|FN9n91$C(UuYd`y&+~#=Xr+jvGI31;@&gnDz)LEDQ_`|d5$2Ue&PyNAEU%r!Gp`($f0&&;LH^y&Hbv}FbPW#bL$Czm_ZzKw5& zE~#hT47)R3N618POh}cjgJ{fhF&<~RT20JsL&p%Z zY%k}=qK9a)ZFp-K3xtn^u|__hdJgwF^|Cs?u&+_*VmwE9OnDv|)62uKvYOh_Eepcm zt^Y=L_O>F=rO=h-&r%O91F(<9;e)wNzZpT{OY`f46pY_ zo|T==pds7 z;;E`k*9R)l-`C+ECzFKNqCW22NRca}&&K1ge@NY)-dJ4r7}!5n&d;}>?e)<^CGfADP{M&&iz2zvG`gpnG`14t5M)&VNzKsl0^4{r1B&VC7*l`@D$J3=o zF0&W@7PWDCy;$V+%;|ZZb#(vN7h}eYi;Q0IdIkUA;dSddCgJ#4%k1P++B@u24P%|5 z6Y1UYy2!OO&r^?3&EDl?E-sDNc5}EgJTiXvPxBhD_LD6Wbq#CqmCfOML#=1W&d{Ux zt+6L5_e0n0f|rhNnUBxxEi##?X~idgrWp?kY$gwzjkFJ4RWGsmE%MVlvmOd9bgG7& zPI4UWHB<}tPu8tSo8NvSa{ly&58{Kdc2FP1nt2c7e||0Pc;~rvlRC{>c)a)MJLzoG zx^x<^+g|obzsU|b{1kbVExXOGDKfVQ=}$CT$GD5!?iS|T%o04r_`sUesruE_os%O& z5Bq~_$d1H+zVWT6BBR~B?j4IBrQY?)7*CjQSwrsv#{}`chgJ2w$jvT3fA+oPK3}dK z%gg2Z$^HHCvOMmR$Mspyj`=j$ya(3KJ;P-4tfR+oh`%{-y5oNz&!w2-ntpt?kFmWP zI=>bEcK93R=kyMn>!U0EzqsuDVEA@maPcE;8>$|6lj9q8Dq^ z{>9-z)EB7deD(at(yIB7<0F3~^&G|@gulf)gf4oBc9Xxkf7P?}qk4;8qVzq(Uo=6j z@5cGxiQZPrW<8L$EPf{5r>h;C(!q7)^^lw6@4ViZ9(8rHJp0RGaP;`PEzd@tPxIEt z@G*TYZNNk0c<%UmddZSme+<7>-FD6uJ7!aF`WiLPc(UksTeX4f@xbV3uia>mTKdOs zdYoLw?**e<*Lwf&s~v&+oc`60pZSY9gHdm`TC!P-a8Hs)KaW4fdd{B4 zqoI@k@Y+aZnqMAi2|u}7_avF=H|bmS-noAA6OV)k{rXrlKJnVr-GEP=%*L|=&B6Y+ zrg~D%VZ66T@zpj`=Se-OJw(0TK1SyTn+wl5*UR}b`_HZqkdZ;J@v2?v&psGWH3wi& z=J&4*98dN1XEz^kqU})n0A@c*kD^KH+J113=f|7Sa2Pgi*dN{jdlwzt`VJoV+USee zK}Pz|ZuCd57_;)!EbW0_xqDUma2Rhx`;K&>4UM%Gef!vA>d;=}_xsJrj8NmUKlgF+ z((SP`)og~y3Ut_&@T$DFF7n13@I6?YD39IN)3f(un$cwydo1dEQHyFk!1;>vUF3vw z4z(WB^Pn2Lo&q^IxSO?%u8yz%93B)ndzAb^_a*zdgPo`OS>4k68*N5u4T`&2ejdO!@ z%CAH9MV)Oij)Ac`9v-XQL)Ec?`)&TC+jzTmma=-UzLjZjOJ?%S=y$t*=5_i18v}>a zI5|7|mr6Ya_QkZuK&{*NNH2XI8gT2;P3dyqQMBS!P&KYDTW;gC6qhsC@|{V)FS z9E7jO+)6*IJ-n82dUD#=(=kd1^{LjRo<^s?F@!&a4A9=XvS4y+O#KY|na!Cp_G7Ju zd95q$#2?>U$uS_C(c5bez*zWA&h}Ko?nSnuoUUf>TCe(P7~Hj*daya`q91AYyP(6f zedhG6sjHih!{a`-Y z{1?B6j=nm2LylChOf}?lm|JR2ivI3V^mubP_Aev*g<8Jy)sLq=@8E0M_(JpyGS6e= z1pUeAPjiBr!9KXztd%kP7#-dCY8ozoJ-o?B_|DhCTh^i+qu0>k4e*!whb(H=`e!Eb zrN8y^1L=dl?dkQWzaCz4v(9VF=+QuKlQ}HyFneUO;FVD)w_nnZWzVxOv%^Np+h&^U9d9B}u@VpX>1urD6>s2onUl-`T0Qqc z-m8UCSKLqDqdDv9>b~dBi8%i2+CL}yPBra(i432wrOxdSryUFaFl~4pugrElEbE?6 zr}n>!{~Yf;^{lPCsVN|z@faSMVKVb;H{)Ml`cP`7e$|@NliR3?hRf?WKN*>w9c6fC zR(|iRLDv0y-}k+I#m_)ybbT)NAN7CrWc?prww_d;meIZ5EEE^BUYa^j-DdWzv%6is zT)Hl0buZtG(Z5Jn&m3OL=lQys>tDy}_qxr;b-ZHU33sv^B2{;ts(vF`Xrp* zls<-+^|^Gx=@W4DVA~0Jy+0j4K#eH3O`akTWwJA!r-!JyiIcrBJNb(5lh^pOTjTM6 zKlv@!C%U5c^dJA|I@)|SKKCxPbh1J4oLety52JI83Do87nRH>ejpuLVxdy@;Gem}Z z@5v*uJ(^ud6?5v_g0-t*c0IcvOf&|UPgv)NhIonE(W}&zHj!EP>A5z1>^ssY=c!AD z;jdG>rgy?~N=xO=^w~vxGUTU!dbSlkz9n6yuB{htA18B8t^Q2guIO!K){5t7{oqB< z`l1#~9#da_cVK_?%4fsVkw@_=hDxU z&#igwHtvtwcC2}P`Ps!hN5>fEO4RQ|_nJOO>-lyJ;XZrWzEA$2`<)iIp{q^LHOR1f z#nshE@uL*SXB+ot%);yPe!gCPB4+9oT+jA0{R|B~vwFTQ^Z4D?Q}oolf!9S2v2VHj zVJ@86lFmzbdm}ZV`ePg`nETRwV%u~M#{0;7G1b05YC?VOKEB%ena)F@r>m*^nQlC?F9&5BVobyMFS37_KeAVrnzVV3){KtgVcWZg{+!$1ivCLHJ9aaU-WL90v&N5Xo{L6~ z4}r|aqZ?mI`&K=VF9q)c-h}0|z8jg@$G6UoemFJMla8NQ61A!W(J3R(vsI6j10ciwf|_b z%;a`ItLp3Wv}~;xCG_#o&-Iuyo`<7@t*2Q%Gj*;V^|qpRojF0q1M2s3e^H03ZeP@< z7i_L>P%O9oG}FIR{$9x7`FF$L1{dG+JHKga>BVoxSR-CC78zaL!`^Yuos8C#vvhbV z<0k4fU}n87*6izT86*$aZ1fg20q*B~hR3y&<8+#g&6RT>N#pdka2#e&S9=IqgD^&| zue`l!;UkgVd5kPYGxtyKp2y?iamOFy`@du9GkCA?!{a~N{?0UB9cP{=u*)a5pMqfX; zg1XXu_V1L@JPNLl}5-~HEV>GypvU+%MEt*C4& z!rH7kMEKh z-L=nM%HpM$OKwB@dx8LhF_fbwCJ99p~>F<5?gJ5+TT~@cp(Led8|3`RU z)Y0X27i&r*i}BwS{f)AQE~C4srOWAAOTSxxqnV7Jed%iHF6N|vfZydN%xpg)S-Q5o zEIjAtp|_kknEvr+m#FI`XOS$Ho2NU{WKT`>8&U(GJVnm=m7(yHpC4>WN6OZxx{5vN z{78Ff>ehzpp)q@LybHhVaC_vdTX!m_U!@1Cmw*2LRAf4S1gj6V(zgh<|HZ9Q^upcg z2WJ}7$7fEas=as^@!j4UZ%!XgHK8x!Mc=(TeMr8`<^HPB;k)q#G?v4o&E;fcl%?Z) zR!6?|Y3kYP4sJ+4yVRTxZ(kPq=_}vhd^>P3eSEquogji(+qkx!=p%mQhDWPPWV;S4KVxY#F?ac360?i=IdFi~K9E$|w0ecE{Hu zrx&d5x`%V1{O{vhqgb%3On#@%GyLtLbL)k{Q^I~VGd_@&v;RcC4X-$?SKJrgi^r6i z-Dk%E=)gRVdZ&IIxxW}I6z5z0EVntG?d4O)6vccuTn)GTSaN+{%)yECH{1J~V;`pX z-El*qmBZ*{$LI}-3`=g8XNxh0o{{3172^}<5Ljk#dS>>_llE2&bH%mA&2EOV=OiFE<7fK1#o)!^Zl;XMZCst+*7V0~qO{Vv#-+(!8Nr&oK(N2v-giJ3(c z@c0O02R-urhV(dA8RRm?e24txehy1Yw9@G+(v!slk_`1gFY^UtFNn- zhj$%**W+?!uqHg{^7qpt23ssuWDrDkjXefhGjqXw?piwdU`jR z>b|em={hIkaWFUExualt<{11QoMmi$wuRftDL0$6iR^60fa7H5+iz^g3i?h`t1yLk zxuNV0dMnM3Jd_6dnl|lUf?wp#baL-o(R0b(lC?WtXD)0()OnuR0XuD(mrmn-c3w=D z*K1-ggr&0|=6nBEaP$EAPG&Cp$6 z$5V%}X2qq;#|mxU$5f-2+Y7B;E#1qGN%QYR@talrmgu?5tbY49hVQ@cvA<1v&17*| zTV34OrMJa-%q~19>e-!#3!k`k33|l!37J!A4*vl4BW)ZX*tP;*{{Lo52cPBkEgP?z8$%bdf4rI zRKM+&s9QaL)6`3uJ+ry@ z$(Qpwv-lUS@5STyx?WF@-k-}i-;2DL8}EIXtRL0?;$nund~OYC*3r#PchR3-n(vYs z-L;Hv*2}&8E;AWD_aBwdb3Y^3Ke=@#eSBpMJ$opfqlUESBpNiiFXpuTkQ&jSe{d%1 zLHBN5O}`^@7wIoF1)uleb2-~v8}+2`PIg2-j6QQSTyCPf%kMYIW@$c7uXOnQ8apqWp>T2yDk%Mj@()Z5bLBH6Y4sD}0sAgYksMwMI@c-8AS%J6rP#VB9KT6-y8))Y5PT;#AuaB(ZW82?MpPi{mo0h&tJ=+@U zN$X-x_0T5rzhFvx)tqkfe6l^=pjOa6nG@u`wUPzU!@0PFd2h9K&r7G7tCvAtvPK=O z3oFY_UZ*}Ro9eMpt3BIZ#`CO+e0Fu*k-EZ;J*xGQaZ%#W*ALw#PFV(ffXao;+vJw$0D1-n}$D^ry-0aeq(nSsHIW z5VZ_y!Fpcgba_*4(bsAJqZ&Li&PjMY^bWVi9E!)Nmi>3zmhqPYS8v$GM}-fVk4Xm7qh?SiMFEI zU+9MKIZp1s$4k$6k+r@*^!0JF8_jAAKMVDzGWsY!cbVL}RQnm}Y028THKXe9xqdX? zW^d977g*gfMb_2Luhie-_{ROzYwz5FS@|)3Jj8d0{qnN8@s4ww50iDuvGKcckbX&O z)5od#G|S~g88y4ThhiLgY{#N_pJd!U=cuM3vdsiObNNpcn zcYMd2WQmYhivQhABIya?Na~}?ESPflH*XyHqJJ*sHy1HJN>Do>-^j_uw{9i9lc+~k_iF!;J+}{&* zcK5?Ek^e{bA)nL8cVZiRfa=grTvb?4!8pXT!L({O#B?{jT^%xy+@ zEIz&X+ZBvH&FnI|k2hFD9xAVGfW8!6yuS9sWXi(m>f&;{InH#$}^3m^J7(y=w@;j11 zOYJ6VN7p|d^`zCT8|X=T|L?ay0{1!nw?B6Io|$tqA7@t2Jna9aY@IKwqh~EWYv`rC zp11p=b$-75{H5EMUYGYLuk(I?nf2Y6{BGCzSdK09^XPjqm+|KNABCQt8C_1-`=Wks zHltn_dmH(GDW}Wp;d>$TCF|*#(|?_ou7;jfogEc3cOi-V2qA*u$Y#;2|-bIGsjs0F7}Cy1~3)5$9G#ptcRm8F6z82>TtRwaOD<4GtD%%%ztc8A_S=BLt z-VmRw(9Db1U>{EPVZ9$_vYVMGtIN^ZCzP4f>wQ9LYY z=P>k*(T3=6q@J%<9sYJS=wAFUK8Np5;{kfD^BRlX_l@bmCbB4Y(+3ByP`CY6yN|-_ zcx}jOG#5rcjI6HLyz>P5J^Fo5=EP3<-0aOY zkyEd3e5dAe9oH?3ZOk>DfVGb>R#)4#w@~9=#sr7(ETh}D99qskZNodiAXUNqxi(Xt zJ$;ff2V;Oq#`fm>>2t5xOrIhAE#|hLZ(*JT|GZg&`g59i&Xao=a+|EWmhTF@4WF)g z4km{Z%_Nw^`#UUEb8Cr?cCpe^mn8fPw08sK!y=>I|mkopS$34 zyhO|gW=40MQE+#`=#Dw9M|UlwpNj9k-+%vCKQFSQ{Qei?@M7N2&)!T<&vR*ct?uA& z#W0%06rP~|s+FO8czhce+n;1E#Bt03W34X6DAnX!7TM|K`n5d7Q zN5SpXnCgM)fz>DQ(KPbj%ljAV`OH*NcR==HEq!3^dv&FSanh=%(@y44PHcURynbrM zd9Tdk(NE)IzR;Qlj}@Mk)z738^ot!hGAFHg`S;T9#ShSX^pDb#m(bUbE=;|9$%EYR zP+I=-@23`OOE=H`TH3ex+iB~9Z{k5GL!Ulc$MCwe?R+L`o7K>(VgKXgyHs+04K=0J z8y<@sn9NJ}*T4A@xX-i2&t90){qu6>^U}-tI@j5E@8!(o_u4k!&+U9I>gl~B6XAWa zFR7ZkoNj-k%o=t(!{#dXeQG>0)~F=lOD&x?$1&Wnsbv;SzRmY#L=tf9YqZYZ)7 zZ=UH7UH#lpN8wc`M{x>&%1}pL`m-NgNV$8BR_`z>gt1+2W!&@<27V1&Q6=&nG+uL^XhgR=ck(ktS|I8-`gATrZ#ZiwtmbWHu^i%(d-oznriqaU~g(iWp%Z9+3SO$gK^$3 z=Bv>WVGDhyYGa;*htQO)GjqTAbm#^lmHm2TKXk>T*U=z>r zp10LW9d|g_AdB99eppf-x7U+?^WgFs3|-3C(Gx2C6ZBHyHD=zHx%1_`edh4I_WFA* zvbnEUc9#G3RIB@roZKB_gigE~dQr~6mp-oy>3t^fm6%T{XNDgDtslDQSLJL}Q4 zts~as?z#c?SKoFlGTB<(&l=o3_Hy21jJ~Mq<#P0=XX?}8EqJfG4#)GGqi%iXR43jQ zJm6QUUo~&t>>2$r7a4!bQk#}C&(1zNFJRV?&)I$yjg-%Zuj4d2_Z2*0`oYxCBbO0g zzc^5vnyKSBORv%*^QFj1m&r%@{)~|2QfTW1w~yjW&mML4^hx;L{-eR_Y^x8(Wt1#S z7v~1X$gNutezl-^Z)(Pt&*VlA%_X7G*p}&`t-+AQCbdHRkA!-Q@u6-%` zBB`7BTWT-Y^=~|y&ebeTuRi|!X{=@yeQK#O-ZqEY1bRrJxu2xI)Sgn6TjoS>D|?I9 z| z(bd<^{=?M2@9FTWA6@mm@Ve-2saQiV(sv$>%onp@y7$kHtf0EBFGc<7Om4dW|Cc)g zUxv}|`(D2ISXvv}*xntCEHBIGvaw9-I_v3~vE^7jFK+AQyw0rd+HLdp-tOZ6`egF| zrE72VetJ%6k zpM)n}uS;fhIbDCcHKdu(UF%afi!t{$nyICiGJ2_w{vI`>){fpfH<->2wx_d0^cBMI z@`I}r!R_X~{Pf*3;d}WMrf#n}07rL5KI6?PcpI;Ie{)4-D>hZ)hsF1Dg&g%?yg!+& z{ha8mqF!`c`o(*v)1Q2BI+*|3X?(W$UG%(MrDjwQj5_*{Z+f5O=<4X;74(p7EKffo zU&efPHFbL_RUh1vDt6PykoQ2eLlWX((j#)FMM%Hq$ zs1Oh>-2@_UGbb*tf!ff+dg;y z{1|!7?ZNr%d$2lV4R!P4JYM*E9DDfse4WvMFnqYypy8e69BXfL+0^}3XE&=xW|Y&_ zQiI9ibNAaE6knHmdU#*BEC-izwfQK%F17XWufz53qyJ|%FI|`3_sd)!5(ZH5_xSgSD%e~0&l+EO_^a@XmBWZh|zxmbA7)y%Ws zMO|GcAH(A!pNH>-`K!XCZcS;i=z+q`#*2bcXWIX4wLISd{A8a|aT=JU+(GOJ^q z%;)OIYUM80UPM+Y-^UjGIgVBHcOp2Q`-Pu`^#Fc*Sy*43p9k-o-|yS^fs1oJr_Z0Y zZvE!gG+P%cqX(bE<@)R*gN557D;*z8;T12uH<{HPGwN~CQ+|ijW%uHk#BJ`6JRfV0 zPmHPM@jFZ|cW1pkdsobX_4=F#D~D$m&wQS*E9G?OO{_WSM<;JXulBc1{re35B(ry{ zKQKeb`Az$Vwj5Z3*M+)nxO$ij-2O^54dyZ3&N@;ve!8f=9i>j74IjBZsmv!Yr`J$l z#al6c^BAp~_h`D@z9~Kbz28aCeD4qFGy7`lKRgHaW?rQF4RY*0*7FboG@_!~OVeVD~C? zb^9XK^O*Ple!C-ZpVNQ4<2LhNa;{t~AIslfRxj84p{}gP?QNwj?d@{5x4FH1ojE<< z-?ht39?$=0{`Y^GJYVl)dRwWEo-gO|!%Q~+qW@*|tf_w)URTpsPal~)d%G{G{ugUX ztr^wt@)v*ktEeTF)%CpC-zaik@S@vyR6n|Ym)wK&i+t&&ewUxVe?A!f(kOj{SY&oN z{T$0@*H5R>?uPK7|M{nv(I$;(_P2u^LQfi)zvDU^Z)D|88@eEsBc0i zr_M~RJ^Q82(_E_@Oi%7?ek^VasNB_jjS5@T+dCRmlfx6y*=)S`meREGQ9H#vXpc8 zF0J@`i<(k3xI$A?-}f=y562K{_g>bI5xPEnK8U|wZ9H;c_&+XBYvEZlFV)DSN0I)R zxUbrLk^S=P*xdWfyxr%Q`<)+``(y2-UU;8Fe~y{_GO7KvF^fzun9USeJcr|FZZ@IIp0O$M2M%rK|KCi);}3{Hn#O%gX05 zKP9)K6U(}CY39(PHnL#!aUNSP%{=aQ`LZk?{uTJz`vlvfJ!fBtc`0&up)Ff`X^k}= z7JW_dxLNPkWay=_2daIR)T7nTy^mwJ23}YGK4h&r^Ll1v*O6!LI3e_LSeD;~s1t>; z{a(rM_8Bhi52`+1ytabNi~Mw7D}F6rTjZfz2g>JDz1`y@pBLkQKYzu%*XJ00S|87R zp1<#|9ees+&X+?2n7-cMgwiE{_lNnujFA^>9sUrWb9vhgmsa{XRc?MQ`hQyYGe8z) zPsLKS?YXg?If)$y-zMAq?Z~!o!AoxM&zAjfQOmo6ez5d>UH@Fvh3;ATLfWKctr6IeI0nAYW)c^$)Yi`7E-4CM)Pi z`qtOe(UlKTYx-b1xb%T^bk)O=?NUzP(K>2Nhsll67h`YK*6mNGo?TDO#HRcIf5{_o zpVPnOf%<~YOPmp!R*PYi&xTxYd0hNCFe5! zvw!{Vf&?hv(9dZcM=aV`Qd}r0bJC=~NRr6g=Oh zk+xKKWCyu3ZQ-ZsZ8(^Ieq$i|qyO;osi+-Q5B$mH_Q*|tcepaNLNljZE782SE+c=v zFM1o*9o|9?Olvx^Z+&=Y_iS7en);p%Z>JxeJ()h8s*b$3$cbZ)Rv$+L8u}?TV6!Of zy{Y$f-`ZKld6)Vo&o>{996~E!8gt$HWIdOvG3$A`+`TuIbFPrn3y+JOZhaVjVQQ$X zZF76;zx-eSOUwSZ!(Xe%rf$y?7=&!HU_u#PpSqdccpwIkpi!?X7`K$SOE1HQZmYN8 zHpk23ZsWRiiR~vC;LwOU|CVxv`S6~r%|fv*Ox;{9vdDU;cPESz^{4Es=lbyN zu)Sjq^D5PWUF&xVT^uf!W94UA+eOX2^#6Q)UeCNO|DWqa-OlUowUlc1a&6TvGWyiL z;U)K7c9z#q(&NaSL+e#9bm9F#3s)ahGxeCrdvdp*6?svA#7Xq@esuUj7<9O?EXEs- zN7T5jIrcrT-;3v&F;5TgjmN`dXfC=LjJL)bV!r5dKl*t)*@ZioMNYeqv3u?Oc;C!8 zREyTHqnAbv{Yqas-j*$JJM#m)7RQrj8CLIlEBqk7HXpB^xsD%SXbo?d{hChMSE&v5 zMoYJzbg=0_=Zl^unn!u>E2E&geUrJIy&M^k+RN1*hNU z?`dxLdYL=4cG;E7d7HQmHupLi+3}VcEpl?f{;)61u1;CxfsMYU@g{XF%=pnaRa=zQd9a)Rtnbz%qoipb8H zY+RpqzVmE)?TJ4?1ECJ3d{*k*{e0AT)@^w{Eq(Rd>A zZQs9&KBW9E58y{1tm1c{zF529e*4sR(0i+GA6bof-77b}%$VV&)Vb%ywCIK3OWPNG zEggF2yJ+f$8u0`@X|z+nz&d^R5GF!}h)5@0Q!mWn8nREWN#AeJty@?TOq*nO)C}oUZ=t zw(9PgxBXu(&pLeRI&YJiJZtNv++ND&r8@ddM!y%Af7R<{b;ld_J34#$T5!5K>h>qK z=aIFfIiE3m)vY7V`nhZ_tGnFI^D>jsXZq63N}uX)4v&jk`lYdMIJz@>kxtORNPYV> zy-7#A8t}hNrKYO=v7CjW^}T#_p%=ZpE`4~G@z#-TF*jdxaC3N5_H0_7Y7XM%!1prP zd^l}h^;WtFqhFt-H&R~{m#rV|O`Y}SkqdJT4~_jz-#ycvuAsA<$3EIs6P_3I9reCg zld3n~9QDrHgY+pHN~7(Sk%7MY?N{;amWO71d=I)2IT=;EmPY@gpI+%Ef02GowPopK z`DXgbRMFoN%^dca>Vy%x%G1r^>h#GZIdrh6+$PUl=z<;4#ns#FkLd4yH+*hC(#E}S zQjhgchsI&a`zDXp{A^l#rr!BFeAt9V_uxs@A+Bn(et(YZ8nSNb@|+E6m>-z zUncf3^w?NKdE3vzb6WeV-s+M)F?Zu`nOyFc`|TrC%INvB9t-P2JwEF7X0%(2D(lMN z-oFhWx4s&Wt#bvwm(AtWf#Pu~JU(Qyn8%5ps+KBuRBWaHA>$VHaM`Dc*WkEr0I!wo z>>{uG_&#p&*u}WS%X&Ue?6LN9XLwc``FwtMzODEy!u1|IdykqmezPBsJfFSeu!z~( zyVuMK{_CV~l&{0Q9P3AA^eM)b`UqqeeN;8%i(fQX2UFb@;bHMRqNe`&T2a|tPA_UkN8$6r*HUo$X!z6N^w8Mv@cQYFA``~G zWRVL)eW@9aV|ZbF{munM77oWzAGe?VD`b^dlC3DWHSUJl@I_d6Xn#sG3$5#Le#)%! zUUCm>sQtXyu`6mrFL#v%pPOAS;}$(PWz=<1yK4QYeRE=AtlWeL&Hg(2rn}%fub1=m zhuZ^7rgbUms0*K)eTe;>t4sU6ckTRA=I>Z@dwhTS%oo>ZCN9?2efYS;%;N>8GcG7J z{9+v7b&f3@S2!MaTwz|Kufrw$HuCoLm_*M@EV4V-xs8lotiA2d{DAxHKHb*NW6bQ_ z+nvSluJdxi<@Z?6WOP5b6DM~>y@p!4-x2*x!)WTmHEYsnHNS^smp7r2H?YHv1JBEmbuXvxy)UPQFMK1N zXIVQIZbccb@Lxghw!&= zc>9^ucks2eYWBD3T{?#>bv*Rdcy6{mn_hYJck#ubsneIXdfV*Oj@Iv-K-ZCi*Y(bv zIznwJ9{15>^YEX~O3k}of!kk>EXHGa+V?GcEOqXmN6#br(c;0`^2T@I^vBcN&-^dH z8C2ch`t}jH&*`@h#aFsu_M#b#n|AI`t2gfoCYRH!tEw%opA!}c`q?G@>@d5h93 zufG+`{6#C{K3RX)BV+D(t^+M)beX-B%}XzrGWr*BdMU5}wjBPOXzI=roIZak`jX1% z<};e1F0217PXE>4gg?EM(`EJSO^?1t)R5-BqjGwwjviY2fBWxID{7|8jj6uym`uRp zS0;L?w^yh4RlD^(p8Kl0 z)~_!E6!oK=_u0PSezRe+{}mqQaSJaD$DjQQy&aE;dR+LodCtNUuNV978o8RXdUNE% z@cQI)JuaEk&5`l-hu?;MH?PJ0?Ii!w+sya&vGaI9PO)dIoUJxK#(iU)!h4l<*T}~X zc4E8*-?YH=K8E+nI(laH*gyA&W2Hyj$JDE`bL|^=ueOrqPv%c0S~z`&K08x?o12Pp z(N?@F2htgRR4}^P-ew0n-{NP}F`)bEYmZu0-XA><<{bJNJlnFJp0V@skud(iV=_!m zqIoN3#QXi|Lr))U+#BOoJvU~j%jMRNx*lqx{*(P0C+{VE>FDZbyDB0lQVm_5JnQNH zKhjLUG42=MmuXg?;J(B0I6Nkd9~tZD>ZfX8bJoLncl6EYngca!8B)K;#dgNj^{b=r zs6CA2xs&@AF)qe8Ol?R5o*sKuHshVh^@#)cn8zD7gtl#l#}NG`_5CAFg(ZB`L9BccU;Z;&u7DRuG{dk<2qS9JYv&ao*6xB=>A{uy7N=a z)A7A^?RZtzcU~sEDg0IhOT+v!c=+ant(hC(^Cx@jU-34_hPhvn{O)c3X5}Ss8-5qI z^|3Oi-_g+v4c+g9udUS6lE>HCKUd1?cW(Q#&1md9 zg5PA-lflrfW%j3Hesj<3;YUBZiF!@mQ^$7W)l13Ce=!|g{%G2;;Gr}{X5+f~-@|ME zGFtkx^qZZHcYbZU(y}u05?l7p3lI9$=B24>{WEFBYkx$aq=%^=B}0i!M?E{{y7yKr zn%4X0us?66_PwvCO8REmA89k*^r{Wdrj}hVp`Y91i05DZY--*;I}IFq4gP;Rt$F2l z(utMd_)3iRKk}XLbNb)SyPug^omy>u>+VCr?P}{=cOOi1-&~g7Sh70JUa%z1n!h+b z_sZP#{Hycg|M{@H3@_I&TemeX`xxf0%jS8>?4F;ibggb(%IE&?;{LcUW%I11yZ$Pi z{$*L+{m=P~deim2eEivuBlATq-TZWYFX31Jt6xPfqh6Q)@?ZYn$aXQ`MJ?U6zL(M( z(!1*E)0}?m+yHru-RaY7)OQZFrfZXZWF&UQ`oqhkXzYEdtD&48q}Ax!^!FsA<@#iA z)O`M&UZeFDJ5$3^YthQ1uJgj+N&0}+ahY)kb!is{>gYqXmb`Ro5!lYYN!5q8N3YS* z&g$rO)O?&Co(&cBKD z&=&CqTRq@ZCm_QoIC89Qo9@P zB+Mkk$;QvoHp~@oJ%(cF7v;7t>@6lAe6sl z@99O)xVQVe!-cZ4q^#yN1+6x{1v$=TMOY1{HwnFm-?j32mP=JM==cYnMtbGq{d zzCT0wVRo)rz`jsR%Q1X+q%szLFxLkvg5T^hmFx4=aP<_cV>YZ{%%%HXz==A!Xu;BZYIpMZ=Fn-vt37m z+4V1toTN6LIhAuAWW@6wa}MF?mic79Y>#{wYq0h7gh!3BawlV27rpEDK5*?e^10ic zBKOeR%v>wtcv(J|#hvpSWPVGZkXawGP3CvBcKzsncbwbu`ytEv{`eUUKA+a1Gw1rg zIra=LkI!zw=mnQMmxPav`xcC@?^~_C$YAw8G0zm+=pipWDt3Z|k)XjTQQ#bD=_a*)F|Lvcqe*vdkOZpdZx|uK8k8a;l7a9Fab2@qH zk(oYmD!qSUBw8A?C@@Io5L`!d{FN6(}2^vRWB^!2v%;s4Lx zdw$1toq4+d$PH`FnmhLNbhq8pwj3l`Igz3$k(5M=Q517dAP9m02@n90Ge7_Y5eeoX zQdEwXgWR?|r|IrVcT)F+dq2&(eZTGdJnybe!W{Kn((O+zVXd<&pz74AQ>W@Y`?r7Z z@1<9%b*JVtS}WRGw>NEj^=0Zdx2GG^U1;7_>G~x7LeKS(eYh_j-n~A0iT>b?$ux)G z#hjN@J@gR84{!e?^Is<5cJmhPe|i?LyS+!xj>7$?+o=Dx%f0p-+L+F@uTM=|A49*)JqORzpIpD<8S49;hgZ{6r!xyq zpRwmo&$~r4%hxN~7jw?$6Iv4|qxW*YwFpYPSI8s`D*t789FYb#w>(c9f$!5tND zkUgz^Ec;P!jsN%Yj(2>n>-Rks&Ae#q`mx;(w<-J1VSU&<7VekpgW=(Bub;yUEsML9 z`}M*2e){pD=pWGwBV!ltm#<}d*;vMMU!G(9acmd;->J#04ZWsvd-FgePcKu2NaQX=Tmr;5vsjJW715+0tBD>K#)9|ME z)urBs-I4oZp1S&a_P3a+p0#sttGUbWw|E>T4;`LM`90^tRNopCGVGUlVqQ8DYh9iN$8ZCyyNk+j}2v%0mWKE`pd*(>fN z$B%u?Gx$ApoF&g%8=|IemZ!=EZWIwBJGbIUoBRYkVKP&(CVUPoyxf zb59<({y!hXGBAwJXX$5Lek!@=61K$v12Wy(GHyEX6^zfzyXdm>N+VxyyBK94E$6<0gTt4roe)QNjvRu&A zU1W8c-Rt(SvaYmghyIggXzTDX9`)9}OXzPzttqd2rEgoBYgt7e<0@{G&CYA9w_KnP zMlBhM%b)tqwCb6!rB%<~M_uUCY40jM=bX#%yA0Epbp4{QryVcfpJevBwfChxuY4EA zemqScdnp}ePSxy}mYoYzKd;}%BB!gdckNr0T6f_|Bge(pIY3|2X0jJg?07nzAdj(Q z&q8Wo>5Gd$-7NK~!%w84U0-tgFGHJm%jo5CzszfVQJy0^%hGzW=j-0y=l=>P%hQE( z<#?~l^2IBoZ)WSB>bOsRT~6P$^FVms)#%mccUK>|^*ZypeLl0_$?NLrWhtCq^z?FB zw(DLl@0Qi|;Ezquh37?1S5H@0|MBnqEdBiV|1kF^{TF|AtCqC*UJ9psS!zi2z7*e! zm-D?ZB`@9nqb_fdyD~T075V7$_o-ey;V}CLwZ_GH%Zr{+6 zu4Cz^)PKH9_R7`M?V*`po$QX@pJpWvbAC6k{Nrn<(+D-8H|TL>KFe|P)89m=w||nE zE_zK~GWK7l9w9sKX+#hj8O$gFEW49n1?@!}wJ z^PIz5syC#TLwIrV(bn!-lQyha6uR88y=1kK<Y^2k*$1g`v^O3o)O}xm-Ql^PYNIuEF$t z441;Sp@G2!XFIk;k0rT5Hdkww6H3Oio>b4NUYawZj;7XZ9jWWg=W)4>b7Vy?_fk$T zx4kY?s!OYv%ai)xNATOIui6V{@&qi(?dnZr1ykQP2b*6WWNw3Vxm@Gx$${!^p=I-) zoX6Hb8{-AWBbiZTZ_dwbgPg1|Ei-0tFVsXP4si`_dKpQ-#S@Yqwt76 z9^b#~$^FfJ4cW#0yD7ZwEo771mr1?b*LCsz>e1H!Q?zUuSvFQrk6x!RzTB-pMtxh) zx?>YrS^tQ-t97I9UylX(&0KE175bKa?~XZg&d1BCVGn+0)>qc=_Jn@VYi9nZ_L2P~ zllQ}$eaBdD>;BYHOYJBg5BYPFOUD^{=bbx<&yLSf-gddoM0r2EZQkej#r;wK@9|;n zLJ#vP>bxE|`dlWP;WhYX*UCpDm%4#*g>yy?+n-}T>BZpF-HcDw)Thl~p*PXsamIG^ zSd!JPDIIMiOR@I|JYE+y;&X!yksUeHOKmA*W;J$uAjJ}zd)DFA;xnW3zhLx|-Ie83w z>^TnAFK#aA6n=llKHc25W>pQ_xhNkKSwt{#_L`g5qbEg%%~`AN>&(r5$1|gPT>F{1 z@0~*ne&@JUllHUo|2{UpOa3+lpUdOEVBWUhbOYtTy#q;t6nTz;qjx9;n zh#uLzAnG*ik2KEx^0xk&vASice(SU0t2%io=e3Mb$J)4kVH&G`B5ir$pQqsi^g&(y zt#o|LWAshpJ?vkY4$#l^5S)I(xqw~I!ru#n*?X&)7udfj4IbjRWY<%X?b5OPnbgSk zwC;K)weMMgX8&mFFdt^`(~+A#46_gKf8>jTgTK=ES@`>IFMp*k{ts+rvbc<{mTrDa z(Z9XlMHViPk*DS8`5L&qYptoAuGd{A_j=)US-yB^{GW{PdVI|?7I6KA)eEQJsjc71 z>i5FrpZD0i<#hLp8I5|=i|0j7|Nf7Dl79Ake-Pdm>qynqts_-W*Y_fu&tLBJr~loY zJ_@6ck(*8*pbMwc7=HBE@wCY7p?Twhxr)zadI(({&-&%b{caf<9dV)#6dLhx#8x>YcYfICfSPm)2~kUq;q4P;e(OSFOual z-p!o<+yIO|k&e*MRB!t1Pz##bt*xu1~hDD&g;fIOi;UB85Sw~IP@;dC$6 zx74-GSnyn}j%YT9`f21QG8S?CphqQ-FE)o)-FX3DU(N}=miHj1_tHf-W9 z=3>~z@j`{wuMQpL{GYQkay~}Z|AN6ekH@??3>mevv41jq$2ca~#e5IW{S_t;j%Q!F z59D_Di#50IGyCD3s9ICu@Vp=7ue@Kfj$N2sW_CZBw<4p@z~{av{U36%8ojyQhc_>Z zK9lyk)WhQ(#A$PR&}}CeqnO)cc80xL8uyajOxCrx@D|;mLPw=Kgb>CTE7`%~;a92YKForzgmLr^l=32rS8c&MP?gQ1-bs z$hYTf@^M}AiCkCAb->mhOMY+iXDsh$4P538-$;dfV?4!Y;{VmwGXrPtE?Rccvop`j z#(6yJbNy`NIhFOx=p&V}gx52(=kJi;kNK?b=j!*w-x+_SvUkSEWJdS(3!~@l%Huy@ zw;XF;pTFd>2fsnQCyzP5AHI&`0DrrtsTXxl!taXp0{Zs+?X))DV{jNAKe313RQ&(; zE9$LT0iUCFSG^QEdE+)XmYP!abU9rnAEK^Qoqe>Pob%n!g*Qh3OJViNCh{?llD%HH z2#uS3MQTmQ>Xy=T^ns`$8moUP=}$SliFNau>J<9iFLzM;w(MK<6kVLwEc#}e!Q*J} z(7mtRkEaG*p4U1@f268czL^H7Ppw&fUz)CaI=%GRSJTdyzmqld-Or-ClkbC9-5eVG zo3`#|%zI!#cwFT1=50@g*Trqq>(T?m>rL<6`%F5r{vrPNSnAvJ*q5CCOET}>@_BjO zFZnWGh^NWQGIL>Yue%gZms9P7WR{E9%Tn?eiiS>Q)PvFSzL?Eu z&m;ZmYUo8bm(PRI|NHG4((=F0)6>miw6~G@M^jOulVCuoPy7c|)lj$dKPNj~c`=j>r?C^2)?pDsH2h+~=%hH)){OnWY z$BefH%U{B~uIF6u%jMIZX`~%(j?DD$U!RV?Mtav@C;xHJrj=x#52uglMfyAMoTGO1 zWaPB>96!MQ{n4Xzq^%l8?@nzs8&d=R_mNg|=FrpC%X^OE%Rq;>uj1>I?dbz*Pk(TA zD7}BSJ^CMB7=$(OR@f^=|L)dTp1{9KA8$PC_L;oM|F4hIJ5+Bcees+-m(M-Fcuui4 z&FtLf-7f@lmke#skLA28r)Ngbx|j38a%j=XyzS%d$L(Br=5xK=tb^>d$cE!Jk;=If`d;nhX+#Ws%&efhH)vn~%?pid!<6Gf$>O;}c&HhtQ%j1Aesh;{+IpWRn z8qTX(V=Hs;dafg*naBIup@Xyj@TqW4E-WLXgr|qsiSxOfURlibR!{TXEg!fJwL70H ze_S1+7Y`iiqW{NBc|Pmro70t{{lVz^X5!qB$Gv1(#D3zo>m7p$d|%Pa#eKhiMutVh4_joamI$3HTMIoN9Glg(@!pM{#beB(OhjmVoM_t15DtjzWJ zI*hkizx?lhaR00IyY4o$c^N!!#~vPsh7O=>-BPMmf1@Wcn(^LX}m@xc@} zvOd)Hd%xT3;&G-QSO$&HhsQY1xzLOM>9C#$--kYf>@CnkPz$d#?syh%Sx8>Yf|yTv z3xC+z{zK%x=-X$`itSWaw|-PkcQLnd0X6sduCl}9xwa7^}8aM=kMfg4liu(G3GWn2JzDSy)5s? z`^)0G+$MV-`~5q`_kIRXx;jTI^#b}#M(Ay%=S0uH^|`&wPulOuUJ+{Ot!U^?)QNWE z^)pLLZ@P7*t&AznNw>aq^eDc-qsz%+q)#2czlG7goTTT`XdOP7YHIqc7KK;w(E2A} z^rdMVbwv7LtT%0Dd|*ARHN<1osoKwU`_kV^iyrvL@tqiDTSlk{)mJ{%NT$$%7wB0E z*H=H2hN~CiHD8!c9eRqsqhC$?SALfq#;4N2!RJyhnT-8a3sdKwXHpxzP0dla*Qgok zO)z@Pj;A8ur3v3l=bmTryzrgdiEolR*Ax8j*yhJmGmo|Y^~=9|-vfoe@AmTEU*U`M z3^nw^T8@;f#9u_&hXyApfy_9pkl!;xuUG#aM?{j=zulJrj zb!$xEW6FB&WOdh3mNGv0WiIcQ(~C#_!nGU0==LX-(|_`_-%Wq^7k?FXq%wNRWwds* zu(-9O^Xo^;{a$_^r|WsKuaR}3H(0V?{3M?6E;184(adY3p7g`lXVUL~d@X$BC(+zx z^dHfmbcU>!u7>?+<-60*Ke&W%{1{x^k*ar~ZJ>=$(|_nHoIciBo2)ri4?lCVl|G?| z(}$NwQyX=qW~Gn8?yt`bq&9f}6we#!JQ_ZjcP@A8uIMS+abz2PkNP7kT_4O<`jnm>YDD92N*`RH7t^(obYa9Cn$GmrEdHGFqnuZ^ zrfVk;g`ZU>c0OF+tN9#iY0iiDa4zwG4LhEX-*vr?1GV%jL5JD57SG{kJd^lb<+sp+ zIXBMdbXk4=ZFASkJht=lo@YI0dXAP4)w`poDX;14s@Kbf`b_nwsK4u#QR|j{^^oh+ zkY`VEo{j~k)Pp>SmaccixqQ#t_TA9~U|pnHCz4_i}nLIIr!#DCcwEkBiwi>e4wUZbQ`OnLXni zg|AbS-L+euV_WqlGe%+zq>rbqT2Bd_AKn@EG2^1PgKNV#BcElKk*ll? z$YTRv*T?I(9)kh(fymwH(0P<=9fcmOf#}A&q3;ouJN6EnRLqfi|DnEpMw?r6Voq z)=?WOd&A{@N63OX7TN0OnMYGwm(^#fF+Jl#{dn{-<#C1AgWZGGD|s<+yu5zrQgUPp zqu=(#lsxuapQ=AbUNsn$1`K5%*ctoks;&d5OWu5@|Q>IxsTkM z&YVT*W8L?To2=;_gUcPGxJ>bR_HdcJ z8|A#zFM3^ktuj6c{+_q}<-It66aQoT@?{xEGEd<+m9d1sOX}!X2RY99-dLM!9qGw> zvR3fAxacu7%l2gbYP=?RL#V|uhh?zx+p5o8e|qb_rR2SkQx0qEM^``Z!p|b3H;~CV zpVRep4OTqm>gMg}*@rhgN#^-uc;HvDj%C5+zK*rQ))G(Qn;#(e`~X_{{#D<@Z@w%& z|L|ACCo@)u-w~c3N0UE~p5C00?$X9zRg@<@1M znzlU=%&osg54x9mSrGX%<^E%MZiev1wBT27-tO`gHLDB1I6(L-dZ%~G=662sSM>7# z;8s&OT?Uue<#g|pk-cu-qMWXNu9hyN%hcwkm!&X$(Zjv;IVD?N9#&glvuS5|V${Xe z(1%Y?r>?<~WEQ)N>vkJ_Zdr$YmVBHnU%1`p|0+2B^Vt6L*xhY2L;doNHgwtL?mzs;$V<0wbUu%N-u3?>?}Zvtb#&`Q^`F0m=jFXi5W!YaQq?ql&ZzwICTWBBl~4DUP4%Fn0mGMXO4&edV>1O7HZ0( zPbhiJry5qLs#l+&*9Lv@JZEseF<;rNKBk^BlNy z&YpwiD)YI=U>maT&gSES2gNA_b-pJKp&nMeKGQ{TD7m!3B$)+J}g+y z(=uabNzdJRaeQNrySlynEvu{N%FlXnLqlXAT*hYNYuv+Y6SeJdCwRAo5 znFGgRz;0@uXV8T8TFdIwWYx%kdUE6?$310Cr`IAgdL9GJ*EG9p$+yG16aV+KjcuUT znR-%dgeUL?>p^gTTMyY&4G-ZzFtg6==kslA(wi1y=9@hIZ zj+SmMsWsa6@tr{{*Z(qwj(!$qpM%fO4mCs%Q~Q{n9b)0Kc-AlQ-Mc~#)F^tpeUjw! zNxbTEe0XEH?WI|cdSLvYi~9Vk8$e_)iG;5MtmUBFA6y6?Vj==m!-)@7iRv)cdo*=MZcDL=X3aNPR`@I^8G4o>}6r~Te>=| zecKC`{V&B6=6KTYO&RZc8Q%GMTDs%1JH0NkO&&+{7q^|;zrgYQhJ}ZWdg{4u=cds2 znJyQ43f=ahL##gKi{)9_`HpbO>6XJ z_aStV0T|qVa=rLw)JZ0r@Nw}wTOids%8c<#JiO=;yM! z3|$!9|LI$i(`9=f=cVh^E8^|K)aJ0S-MlM!T_241Pncj+4$k1>O-V*E&b8Qm&kp==Y42v_*SeNof$X=OSh%V zW5-k1(cS6j{tfBo8TK>TFW1rC-y~=Klgk6~zwX8Z^f?+zKfF1cPWPaBk^Q0vrniZ# z#Oc2Dv-i%XpS?Yq-o{)0-bH$qlGm=L{`%>b@TRvM-j;s+#_2RpFQp;s-})M;C&UAz z&TjvuAHF_<-}V@D->-#E=DGUXaCP*jQI|fxZ#8TL6AT@S^N%`m^eCs^$i68f)*96> zr~e$93G=S)u$$)?bxAW|j&4VD*@s31!xarZv@Xtt@|*X0jy6X@Ud`ugI10Vg|Ers- z1KXp|3lZf?pYj~=Mb7x({B10p^KVL*H_VZ^+=mZq4qn7W+kIL$86v2Q^!`O zB~Sb|tg3%J=bFe7S+Cs{{hK-tt>v}R!O*bPvAd{`R5zBB^>@g@>eA}|Zl{aq_FI~p zj4qS1SclmW*&1?wMT2HPI^V9A?>@LbQWIl}LB<_={(TKS;r2e!U*dSg=eiAYzMd9u z7cS45dY;oS+Pd8Cddj@Mp8N3l;LAO}_Z4_rA4m3|%ed;za=Y^l9rO&9P4)knTR+{( zbJ>T(eCGC>(myMwo4dK-q2G!Op(ERu#q-~uJQib{39?44tteT_9|bTN6XZ*wM)^{<=?{Zh2e{qE<39)%hN99 z{=)D+UY7QMa=JY2y5w~8U-YEAemPw(cX1u^dPo0oJhw2qujP7L7!SC8h0T4w|C955 z?!9pNosXT*<@0&HJkITOaT~^G&xNLb^WFC&n^8UePyhTcgVX=RfBNh6*Z=vygg3qT z(Zlm{hcEr_Vstaotsm77{{8DycuhF((gXDR>|pp%dX68YW|TTh{`bL^@yK{Flkpw& z@tZv7or~k#&p4)~CVlqiRMc#mn|P3(M(W^uH^GQq_3?Onh<<#DKC=9OxOq={cdiTV z+@+KHQnKr}z|^H5zA=Sfj`tUKSI_TmJP6Ov z&;#{EYN*I{U8ly9Nxv8DjB$2 zpGDKAt_i-)UTGLId>+dAbti1-m2IqUV-@*~H zy668{I92_<4OZ1dA@7>+Cl`mmCiHaXt{D?Jr)|zf8DpsJSx=`XUpVB0>7#MZK1rQz z&V0u^!aChAy>R+8@9_dXBKy#?q6Syp9Iaiiy-Z%}TeFT&Z9v7J?`?ao`+3L#uG2Y% z+xsAAO_*h)j%dFqIo*9@t)TBaeB*G2eVFv|+fQ@??cF+5-@AJHBzZ2*!RuQch1ETW zkCE-XZ{3rOGwoQjFm!J{#UIVo$GplhYBHU7P{%h@+x;SMm5i67rw50ddkFW2 zrvet7)RKLbl=-%MTT;IsN=@X4HNw?0+B z%#k$Mgf882h?-S&ch)rthpXLt{oS*j@txLp<9!!L8sU4q=&f*eS55Ry&=;@AUEO_# zZL+sg_RrWS)j5oVY_HxJ*&Kbp;&qqL=d*gz)%}djaL?YC+l=n#S$s88FIM)~TB+hN|`%`|KJWl2>!QmA)_xx>5b<#p9wzE{6x3JAT-^D6V(2J!%E!#zx=zmJ#Z&~-|g*tdzCNFqYFpN*Iw5PUNq$5eer*V*9)i1)GqR?_o=OW-TU-& z>t|7$ciD5OF6v3;bp7bEdSP^*C*#ZJ`e|I$=)EoHd+Fk1+y;5wb-HaX^S8OM^}SxY zJ$Ewt{M)`x(euqww;$;bKl^F;)Bohp{~|d3-~PLQA9}hqq@{K=cpZOw(b2v91y6cK zM>mtPaQX~6E9%wiU3es8e!kKdXLhCjM* zL-ZlKIZf92X+Fy>E7Ko;bT;)gpheM($XZc*9v#@al5=rmYOdLyu8il`{N(l1e@0vHLw_8r{Q%{FKWl%k> z)`;cvzGD%*BIs!{guLNL_Q!Z(5Ejol@2pxiD~$4F2W$v%;S;t4}9< zM)bziTf$hw9yr5rx|+C)uN@pFbK!wdQ`hfoE$NuN9-MCOV6I`*6LX6H%j-T~4)pUY z`7yGSV-9b-?+cs9SOaz{$C-UG_2M`$;+RSQ(dlMb&0_|JI@7+D8q!5k@3(L5lc^rh zx}Jig=#{cd19Kc^!sjspHN(_ncA)?3C%bqOp6kU?Oc{Hk&h%K5%6N%=p0#wxPGrsS z*-Xmr?ds}zz9anUd@eG&H45G~$6rprHD|@=6=P#Qb3cC<_4Qj?b!D7Ym^f;K`JR?} zsaubemu2{QORgW5`#HAwK05BtUXy(3d{boo@VkBS#^o6{?= z#p`;U&3|35d%WfQ7?bcGCOF=#kFjTv{geG&R8P>mH-XnhHaSOMf$6Y9*h2 z&!cJU3tvmyU;0kuwx6nhF*45U*WDMsmtz|q2>pEg@PgE_i+tYo-%Iry9*$bkR%%FF zcP)sejdO%`rdcyzKuzl6B%}9Gb87EXYe&t=C-r zysS%Rm(P8^_jz5-zPyI(D$HNT18#HKcDKWI`+D>F`d)b5=iT|-`M34Sk4(;{OV@8k z?#rh?{+(d;lA&%5shawK{lEV2=xbE+)9+;U|L1T2Ho5$5h0))?I+L!?jfCgi{FWcz zoJyy=kEENkJ=A#OaX||=V^Kf2HK4QPDcT?O_ufAn-j<6K>fC+F?8SG__Hj`1#`LqEYw-Ua86cO6OnP5aVEmxqGG+ga}imxj|PS4Yw(S5Bg(w?w~{Pp%A;-#(b8 z`Ww^RbG_;NmwMA&@4@i53?EkqJeUq|dy$Om<&n$bJa8AhVf~qWq0V+=qABwmIUh2N zJfm-0Zfm7iY4KO;7x!FKv+)^t25scPOTou-je4(omFLZ(r-%2Gb6fa~D_T@5Ipv|L z^Vm3dav7dt{_lBL{oXtT`)GUa>&KtjN&TvQB=t_4u^t&H@Thrf<7l|!aBt4@ATN<^ zah_OCf9dJ_LIWXsTm@hDbM8Fw+Oxsp>T&X%+O&GNbLsNAuN&SH zE`1NTJ@{E?zcff5Bj;araknkBbk^Z^dtZ1_U~HN3$Tsp94z3Cvy9-~qJ`Ht2=L-5+ z^wwrwos16HS0;BG9Oo48i*xyEX$n3sx_Qn-hvS)h z=*15!v)WVqOegDt(Z?Itz~_#2m`A5RbOf#YZ129bi*a2C^Al=}uIp^~F2)jWFa6C~ z+;)8cGD)N6AZiky@*mU*OnuJ0jbiF~lrfYZi=STeA{f%vYI}-TA(&iR(deG4Cb3EO=w| z#i)VHZ5VD!FBRWx=#hg({Dh11p2i+*m8RC8g* z!|Rg$O!B(_cPY93k^jSE{H{4RE^|*FlQO;YEm>=K442thKKAo1TD#8)Hm=wJ>^l4KHuKCfEJH<8j9a=gcYPSSk7G zeh2jGo$28Bf$x&_91S~P;5*H4nzih0>(jQE?k8XT@$j6hxjTQON2ZTHQUe@set)uG z56>OhDrPV0Mb}rTf4!5e7xi<;0CM^;jBfUe-WPw5tut+*KT_{O>Pyi#d=k+67W<`w2S3dR6$Y*>$jn^(p`ou+X%x}5%ld7AqF`S1Tj`j3D8 zH^J%Vr*L4LmetRplX0%(Jlt}4JDPS| zI(~37EIyhB;PlIi$>#L>bZ@M~ zoR%HymPEbjHO}E}HJj7kjW0!CrBAO6rXd)=zj06KX%jtl>8-gwveCQZJR)D|dFZF7 z%qQnN;EH|WH)*fIgHg|U#q4S{IOoSdoNEiMNKb^C_83`V>z6$oI`a(vbbS!kE1jUW zX$mjq;f>SaSamQxqoEVSz1C9t z`V)*3tdlZlMlXx6Geu7#eVyvd@}QcT=j79HeK%}ne!(#QboF#OeUSO!N5A#eIOpHV z>3V51JHQHTgY~Ow+iJpU=Dv?f&cV4BEpxGqEdM#qkq69R^SLp90F$a!zdKbQJg!!* z7B2t0=>2y6nbosb$7~yYby^xGIKd&5nj)I<(R?Rfx_)FyFF_1 zz9%ajE#24CtBR9yhbh4aiG#UG$ggf(QAG;<)fw!aHn+zQ@%V z``YnL)?Voe#C(VQs($-Y-Ur?!J~Njx&T8dYpKZ;bo4rdr8K1Oh(Q(toc0uK(Td zsN9{`S(kn3QDQ$DGWvW@FMRIzEOWZ!Dm?k{e6To-Ewjtu`FDWd0)G$Y zE#>|6TjmpF>X4)RwupoR_ z9&4qR+;M#LU1KhBh_SIA^bT0u-?Dz@24!*knab&E?RsUr&z_&w4V~D%m|9cjGMW4G zd6V=u)mM_|Jn<#sRj=EOKb&pYx9WT8IC-QpzICKBznPHw+iTW-H`!}wyymIYz4Lo% zKQ*N4@4W|?M4zPD#wBUI`k{1e}` z2xixN9<`$Q&oiUn=JYnX9nVj1)#Auu&%FNJ7Xt==h41oix%|$@{R%hXAJnSkUKv?7 z)t@4-%esZn%{uqGTD3e}m|8~mxrNX5x~Qeg-|}_wrkAXAxn9ne<;`#L|E{a>zJ3{> zr;e__-AkF@^}Bs8KHk^#vBe|rI75c_|E^nJFJq3v;P-MlpU>w%Pfj0X4#0ZS>#(|Y zq;k3$>OcM6-;b=9|MWNi`4*>}&FE5kkrwaEd@a57AiXv_9DPP-hTF(*8BZVIn8knI z8a;)~dU+j>`ZzVB1Fh6&4K$OZems5h`ege3_h!=hu?}?X=JdxOo{j9}{hMA&Hz!*- zryflw4sA~F%(kTyHCuwsJttqHhV;WrCsRL}E>|bIsX0B9-a+#|-CfIgfUI`(vY%WZ zigT;;;bx-$`1&w<8rwlX(_TC;m&WLUwR>&kpIdu6ijVc;7Mrf=-QpDV!m8YjQx?UdwYATDKgxwi8F8R?WyMABYSaP>?K!_ zbIyTRpT@(x4u)G4+PQrjt#NAE_j1&XHt*w{1Rpl-LH`NH$+cSMAgVQc?sQTA@?2`( zVB5jfaVdMsdGctUi_RYH&_wY`n?KycInS)&0d?BLXqvEPcu9D!j4q$L=ubHXH_O4E z>xSV>ebw3b@^yR~%tL#AhZD*oXN6`4Kj`t1fz_Z(?x38fPOV<;d0#%xyqw1s)~9){ zwsvy_-K_Nh{RH7)*<8+cEaCc2>Jdj**SoKluHW2k)?4EkCVG=s#x~xTVaof8y0^;f zyA9F15iV65bbKIx#QX)<-QO;5lk)(+uJ6fhmXFL(DV&iRop}QNEpWgHeGd1nd5qpE zi__T-7@peOQTh-*^}uhCDUK&SK1Z0BJeHcRFQ%)*hoVLxvO4iYO}D|k@Pn+b9<7$? zc68$Tx1Lk&HRpq5b}Jk{&_K;F{8xBTe^&Oa!-ldT&kJ8gd{+2lm=BP#<+EJdkn0B> zvt(bg$HJ!YUzvBQes0F5zMkV8qk4t>Y+UpRP2+c(Wgfv?9LHzwZ?D@2OV5$>A=WF` z!SR==t#&=??oE5?-OlsPN9sSyXVDCQqB)bc zi!cs?$-RAhsc7na?_x|7e4RO4PfO-t#!g%hPm~;w=3Z{gd87%Gl*M z#^0CH+tlxez1G6pf_`2+E~O?WKUVEMYw6j?k{P{>1xoFV$C}UccgeBf`7VCX$Sb`- zF3`v^`X`&^%C_7%xi9TrgFl7eDf!&v#_y-v!d%-1JlD_Cp9l`#NVYgRR433Iy66?= z@4=A23H){qb9oBCx?UFRKh1bi8;Rbd@csbvUUI)47Tc>GmjDB@< zWloW^Zsua&foH>`ewi4dLr$35r4W~7ivaZcRmHD!{zAj^108` zcixG=rEA|J#tn==Dw?`JbZ^_g)Nw!`{Y&L}@B8xa?)Si*?0qk{@BUT3SdWx%*UN~D`mXGy>$mz1I_xW5oSMGKFK1aTm(Z{Ceg0~BM7xtg8 z$GaYHyA%fZ`Et9Lvb>kFy|3l=`5KM|T-#@uTbAP-g`WH8GV3%{A2RXfA{^lWbYs|9NOx3rw`8ekwxASnaPp0MnCbU zstx$byTW(UQVnMw!xPNBvL1H(6Mc4bGWv{~q1bYW?D7f52ILxdvtE5K=SNy1&&58Z zgZR-;wjZXaQD2;Ye|T*uy*I~pQ77i})av!fesZxVo$ad*&2x;NCfE7jK;y3T*7S+g zxNlwbGf|&&&fNUQtEXGj&8gP(&SX6tza;vysMo0j*6&`Ot_&YeZOrpO@Y`RZ=CmHa zdM&wq`y%gflzKwvVXc#jzCmbKGWOw3&qjV@KVAWOH8K@~C9|GxCPMLu=qa`TjCt6y zu)gp4S!w2v%)m~QWJP*D?8Eb7?PyO;?tf`6;Cx1xX|0)*uk>5nyJPfN)`<0X`unfv zXTC>WR(B5GbACB5PocZ2l?Ly@#MWcF-q7qT+i0J4&+%@%@5%GFzIvHW-TTtO0j}d0 z38sfnqn0y!Wx_whIk39k8w`Cgv~=eo@?3=5 zQub|V>}baJm32E$hu*CZ7hVX@3tY_D!?_B5{3G#slDUosxAT>U(rZiZ4=t~i^XR~# zCG`GzHoPmnM|h9)N>U%S-qZImMJ9~7a(*_=aO(u0mwY03SfikaXNdlmZ3n5(g|i(m z7L8mTHhk%LE7Z{K|7ni8Y^a|^zq(xS<9t2!d)MK6$i4;MJNrzHQw>!f^1b_6SqrP@ z-fS9sHL0YtoOg;fOIZipg`$Zndd<;Fj^t*K8ee$`odE`i^Z&k_qRqn zJX&<~TUjrBAN@{dZuZjgUFE)8_uux9`#5>Oe1G&g$>e??@^{6tYyJ(2?;6KU)Xnh! zJa<*$bk-f8BV&p1ymMSR2V)(F$Fb|Q-rD119Npq{gFf=-)9%%eDq~b3|Ro6gfy&dhig^pYsTH@s5S91@)Nox56=_IjrVB$?DEsngL_qBQw*x;dJXn z^tc40!|B$Us<98(WsaBA<#TI!rkk15!vE5JF!w}i-0~>?@F(%cKb-o=dpWk9@d7z9 z``12(?yjF6J%is^YxnzM`Xg)aOFi@%dTrr9O|@&k9ln-5%fFq*>zAhSBQK=Z&EHOa zyB|u`tG*d}dIP!X^&6;-#rJZ23t2Dl`3W*x=KIrcu{!=1b@OI3Un<_0<{kNZe>LYK z`ZFEJtK)OO{JZ--a4%eb=VR~wRlZn{EZTF?y}d2>x)eXT>@NEjR`>{4`Z^>kUi zXy86a=9TB=X&+ZOzC72<`HU`;%fj;)?{nSWS3ET`y0?9<*Nb-Vw!4jGJB#n$F-PI; zzw7c&KKFK6e2&cTc*AWufAxCO_advy>FVi!{+ItU{mXy-Z<3iW^7()Mum3HW-Aj9v z7FNI0pRT5Ub>?KcJT-t%{Ur6F^f`jhCwh)Xj>`{joKDjN$5UTZ725P6`1usNc58T1 z>`C<5+h@{G-yBc1yH2JaL&>GJ}9aS+!<%Z3qfGwOcV_5c`Vu<%2|O)B;hDcN-5vF2)}6jF(SSFF`dXOA z@xmKZ^t9Tvgj&!I>C=nt)Qm2N$v38^18~y*SJR=bhAf3lqJ`Asb<@;1t4<@|UCZ;g+2Jvk%9K0Dd(?Q_Blg4StWsF^6v zGdl)Qvk&ieMMsy-bDtm2b>wF|*BqR#PORR9r<1&wHP1gtt_}JUyfA;U4zaMh=XSMU zbvivc7yIE2Uk8>e-V=S4Se}-JA9_-^im&@ga z)xB<=XV&1E8{n~yW4tW$4LNIueXgcn(bWgs&uqI(Ff98o{I!fD%yV&n^}z#;dtMF? zh+`l%HTAer=F820Ft2T_ZdqFJ;IF4idXDc{et+8X@bk;`bU z-vnM^>mTGE>r9;s(3h_NSkAXDVvG!Vb1I!*axvHcz^hNBU8`U;@;t8$9gMz6F@~ci z*7syhrsIy2EpRIgeQ5+XM^Bf{XW;S3GKag*z~E}`!_Djm?w`}I0%z+#QJ0s~^^1F3 z&JOlxJ#xB>^I-aFF2LLVFSEL}q-LXMPx>_5Viu!g2y@iUmQ;(E?`8cN)+^7uOrqn* zdSH3Abr*f=QBR7_J{e1{C-t*bI}eXb;dE|WkKlLAF|^(Q({7K9|v1e7=th-90YlYW4Wc+x~Xsxu5*K^1BuH-O|k~kBi?enZEM-#TYRB zcFe!X=HUy&hhmM6z7*>dVq6ZZpX=n*)4_ zMkj%FWqy6@{?=JbQS%x-rSY;)HLXf*JD((D=CL%{upIrGzPtER7JZMrbG$A-$J(F6 z8=qmGlHUN9OKjtrW_0!)kCWl@TWP53>9lj{*HX>8hoZOXt`+yE*~XXBny0@)ed%vT zu6q4z-=l`~iF9=R{i*p@U!$z6%jvLss?~}3B(tS?R!Tn$Hy%hG=U*h7re0+JH*NaEo*Yoj(>s^Q2Esqy3 zeOa&D>NfvfeD3|9$LQtph1K0R`hU!3)cZ1@(SP=Pe-NDhul~)yO?qGc=D+;c;B^_@ zOm#1dPyK($Wvuwrug#u}K1Q7l)sf?(4`raGI{F56AKRDe_P!Q%po7g-^y5Yg>^zcw z{`ORQmu!}wa`_gzxw++gUW1j7>_{J78BK@xY((!mn(B71Nt;$ZpFY0W3%}sUCUm_=Rwm0eHkshExk9}lInJ?L=UIVh;z-Zb&Jyx#tr7Y3{#uhMICBi+)xWDD6@Xz2~R(0E|A z;B?NHYGsl2h_B`atacBp2x8 zvFDHdqlU?fP%5V~jy|^8V;qNtT7VE{%K0G=#<8 zJbg5BZDjDQH{v;vg*Xn((w5WgJ5<;`@=~~8zsn@tZ~mg%tUYw>f0_05+`nGm%QQ=P zpkqvAzf`>oTd1|bYs7P`HFn>+Puw5+)=R&3$1sHf$I(A8_VK#Z%JtLV(VS0fppU{* z`U3P->C3e@fL??%Fx8n3_8)T%O}jZ>@T|*6W@y@*^%QwWC&=?ZylG)@y!FS2x8en0 z%%vAdRyU{L`GC2;tgVmZKk@sd4<%R~4nIRZh@KXi+!~Sal5?M)acf=Fv}JfN)wNyJ z!p%9i_SQ1FuI&>A0st#^J!eiDD!RBk*c=`m-E=y$%ZMq zd#NWax_hoG&2t`pE_z>LPKD1-FOyl7^K;Z?cE?zGoRv8}>(seFQ1-E8cJ}kMN3O@e z_lI^~c--+c$DYSc@vnP3bos*X{IBr8V*p=AhA$d>S#M$Yd^^9M-!)&~j2Zo4_7cz& z<~-JgN*-3J1J%>leRwVZ=X=lpyQn)hBc*BQqR6A&vzFs&#}bYmYD>|u_pf_0e1W+K zGV4blzu2`Ywe5H;z4-WVFbDN2z2crsm-}}|t&hDDoCkD_=rWAX5SRRhd93M6Q%8^E z5bfJ+7QKg~=gt=|+z4efSpfzDzYPr;q5jQp47#VvM0q zKT`KHgW^p=$?`7-aUrSq_`)b<$ z{I8|1U5})W9gn14Fa7g$99_Mc9;GeYpNw3_9_m$F=y%k!pKKX;-P%yS=;ofv>QO_A zFTHSjv)-2~<{9{(|Nrvu?)SjGaQWvw_U>Qli}Of%R8E&c<#Dxgb!e~4yt28M-mjkQ zbuaaw6mPoPcG1eq&oM9vtxs@I1X_Adf2_Myw~{*Uarr-oX_p^ulpEZTTVBdQ62sF|L9L{^*XXA zshKaby1hxgEZnZ1Zk~GazkD9A|M0B~>HMkA=rMYIsw=&^d{L^~w<&%0)=W}YH;?=Z zHKsqhHkdZ8T$B!MUXC6<7JhU+C@YsdnT}R%qptK!`uRJj;dOdDl9he~oqj+0jNiY0 zI{J;9t)^$)oR-gSj>q#m>Zo}mU*`4G&1oBTqV_oYNnJ@gmY(^S9fn=|e7Z)u{2job<9`kd!J(?idtkwbA#I^TaVyv#?pJ%?XlX=>cb z`GY(b`TX{Rt_3fuJE?D)GpJu%E_Lo%W|wtKEu{YLaXcC_;3QrI`$T%4v zc>*Wv8_{2^#@&bJXDT z_{<8vri;w*#;GIe#%N9G?BVGN4P9-R+?&wU83!=#xyAkLPx+%PF_+Kn!szy_((|H! zLyw1Z5<_H4oTl%J^XzB4@Fn0$A36+Ita&&!Ysye0 z8kjqIf4V;UkIH3dd++LX$HF^4Vo5{7dudT;-IZ;E5Um3`=3s+0S=YVjo-z3A$N`_=Kyfj3({vR{0> zoFCeH(bIE%udiP|C$)4x)A;NvpPOu+=S%$Da;AE4wmi@0SB|Cfd!g^F%#HZ}lK(RQ z|MC2JzcIIN7gn!ueLTneT!P>8y44ZlJIgWbm@(@FesAzY_3(aRb9HpRQ)j3}Hs{K@ z6hF@%zRRWmf%9wOabi5EW}qH0)$%GH^2On6(F-_p;?;DibA5PEj%;0wjzQfD$6~ID z-+({-p|tmv`{UTE-SS*|eQ+ntY~P_JaZKfUQhSRrhGy~ms_*Y4-WHFyw!L~_ayFym z1jm{B)$BWG4XNH2b7AzR5AwaXXY};Z=hLl8{>?DEy^Drw8Fy51%=4SrvimtS zd+JKi?O*Rjmug*=RxbE0d@@g`gDbwCHZJ;S@cn(^YjNApHawfEUm*i#<$ctcKA6@$ z^J}Sp@1v<^&9_oLx#|s@$YrF@kv&P((d|PTjE)bz=;UUlNA2j|#avSFgqAL&_j9TD zMGt$^_NTu%K=}83r=Q2&_j=#oa})kSK3#s5y$h4ewrb_Y_ac+a+g_?!%fhm|jIM58 zSX$4E*L|KI8rk1<6-M`eYT$CS&nvtxt9#wYxyaov^L2G^+tWx^my^A&_e5>m>vFs- z?rWFvh1VS`_*!m9VR!G7w~J0bpU>xC|GfXZZW(>{!sYbVdmp9`KKViTUhGM#??q0x zFR85VBCC6;7bf)d|NcMcbUiRXe3N=mGR_+gY)tRq1)s(9qBef@)Cm}O56nA|-koiY z?8KJp4QazG&!wNdF$P;NOWR+4DgDlS7eikkfPLRROBM`l{s-?fFVS)+ef&DTiE5}j z;=C!h|K#SW$bsCvia9kpr(LK8a>y#Db;G9Nid_fey2o!WW&sGL37MDL_#{5N>1_O4IoPM)A%bs(~A z&XFVY(WSxYvvlPoURijnX+O14bz4L8v-Z^fGw1rz;$RH>$;-9dRy-D7Uo*w@i>o#6 zU%!a+BAi}XLhs@{DMPu)Z+bRmR<-mQYBlu|=>OJBEO*M=YDvR*fxFNqWnFc0vk${> z!tKZiZ|3p%7^1$i_)uVX@3US|PFI_k(a*HQv(`rjr=$Opd(cJik6v^f&jCj_J(13K zP&ddq&Ay@AVbaKx^qfAA(`W3ji04}UOl`bRPA@DF9KV;>Lt{tpj~ZH7-SI{9{@jmM zhKyW^3O@%^SNOW{dAZb!VV1ET7rpJl=E3Fq;q$%Q+_fJ1jnbo}XWxP}dhp5gz}Nn_RK1Dwe$;>Fxsrz6 z%hQ34FYx}YM@5fi9AN#hbp^Nj8C6&;{0=c^k#*Igugc)+=96${_Dkq*&UJ~|`;vXn zjsuED>$5Q*aePH+1%~$zS}@Tt=ICAFkCY<2dlfPx2F*4!R z6lHPsbg%0fw%4spuD0lBGF;*G$PPlolxd>>4Br8L33_{j(YY?Cw;x37|?>BuI~j7S9|w={rJ)yC#%PoePYd~i~B6@9V`y#rQ5)GJ#`rMjr)w?ap=Y zih6LpWF9LXQyxQR0-b4DlXkuQt;kFo|@Io>DZ3v;dZrl>Qp&K&1jr%=69}U37L=lKDSWs z&u`lh+C=E&)i3fIE28(18g|v{@21U5zeTnR9`Nnvn7@#!Uwu3nT~422+%eI>@8yxj zc+bBP9`yBi)N9s}`LYTh+_G<_i>)hC&C1_O%^SW!F5~@a`?7DOMs)O^T@R(h>mHyd z=|k!0Ms;=a8S%Z?ThzQ6SzXV$ULAFHz3KK%>OlKqO7SZ=hG$Z1hV#JMa*r<>FoU zc{07(VwQ+=d*ussKytmVAQc|)DO zjm$mYhdy-Ad1l)bEj=_iSscG=!!CMxGlq~`3#Y5~zBgGLwXJe`KjV$acR}k9eHTWT z0h}k-t0PZmy*}&bnJLu}x2GRoY>9l5@?P}K=mnD1W%iuif=`zBtUpM-*w@G$m|4B( z=;hMav$w1H&HD9AW}>xfF77)sYV=x9G_mh$$ma zl02@8$62n@w_`1zxt<;$W>Fs5v7BRxeaXH)#s3`FL~bSHnb>FSH;)_hH`Gge>6hL{ zjYW8)^batm%e`)whlXjssG7RRq&21wzl25grTP=eX;ZF7ENc61U}d8T^i=JU^bx|BCm; z%lS(jcQQH*9v&kCFS&Hu(MYdlGYg95Wsx6V!Z8)0arixeeB~F2*@G z$6_9DdcW%7W{)L(G0vsMTnoohJ3T&69eX8hT6TYG*oijG<6}(8_ti0T8yTtATU)z* zg1Q{DgUr&}{NjUY$14xVyqA6#b@c3eVH}L#>RLa)ksONy9JkKjn140M{T`FEt>jFh zPmkBvI-5|oWz=S529N?6E(2<*v+0fbAr16J=V1{254BF zddOSpuUeQEJ@^&!Tb@djwNH`d@{P3oiGP}^*L*jfZC;j^Kl+c-$bm=F`UPK2>lXfc zYT5cwUhun|JVZ|;eDKZa=w{EDFC&v@{k-I*({m&4qklDH1-&k9!R_Y8GoOXdZ|=;O ze|NVBK99Ta^}f4%r7zZ_3ct$EvTpI9%kDC|8ghAzm)_@N<#d@^-CLHH!F}$Q-3Qb5 zeTU*X-d8wXE#2F)cwzOj9xvzL@4AbJT`rc-eGM;Nj~cw|mEUD&AL|&yMNap9lre|z zLv3F+cf8@^{|cASznstL^Eut;&*yYAUq1Wk&x6zd;E(?_{qdjui}a^|{+H>`{^GBq zmh@l#tA7)`F0-qttEZPfrFX;WZ(pExl$`XRy>~wS=q7A_Xh*tvrav+f-<%srpT0hh zhh#5#=6Dp&jZy6Panhv{Dqzsa?+hVZ7pmX&@;IKOovTvy_LZrA-}=ze_~Ev^z?%TWh}iL zGWismlzC|Kuv)O^RJBrB$XZf8>GITR{0!l5;k+5Wj)KS0MGvEWF~{pXufE6zG7t1~ z)@^?way;brDr#l#-g6{^ocMnZBv z{2u3h$1-T^vb(qSsSm>+=HidjyRdKX<7x8flJw$Z{|wLd(im$MW|E;NIbLMs(5RUo zQO7Rzqh*|yS*fC*1|$8V7ea=U{WF)EyO^&Bqcbk__;Hcjd~J^*xz6Lr&muhcY=fL6 zqq~m}Y*@_L#eJJ|?VWRRJmdU>ysp2>eW*{$`31)&=D)~0GPcK{$DDlboX*i5OQU{J zCUXB24^=OZm5uZXn`0N=1N=m;$9?R$#~NZ;J$h6z-=kJ*28iD?`x5Bknd1AQhHQQ8 zz%ep&f^W$>l)c%<)}Q;`3>J5v^Z!ymS>_jlh4J~j-{j;n_R0H^apzI|7I67&)aAna zj0JL!QFM9MDX;f2HrKB%v&-vh`bBfsqvLg%JzvWF*0a(Bbx_|9<9O#qV16}q*Xeea z?Qr{Ie8#1pV{BKv&pZ}$tP-Cwm-9Ki9B=t}%K!7exXoidzDhkwsVNDMx_r(O49{_w ze|unYk0*{F_w^LNXMR6CmYj=mtm)$C($9C?@0#D$^X==yKkl5$L9~gfmeV4 z7y6jD#DCYz@uP3XW74|$!s+@7&7!pq^-Sx!+{2XPEI6IHLXTU=4~^T&Z^Y+PkB(ip z@o_YjCsNG@mi3RO^KEM)&%7R;d&f)nrS;E$Bl2F%lG(lTVYc_hw0`k7f{XREPn!9H z_hjZ6@Au%d@c6@N!-B7*)lYpjwQYYi4OcHpwJW}ob}sqN@Vg)1OfKW@C)38oUnlG3 z;ncWU-wU}faJrd{o$$B*8h>-!=k+y`+fPtK+Q~epo*Y@di9GjS^c3@7^uv7lcXxZ> zUYY#!9)EYQ^u>Bq(aY7*)yWIb7A7x#^TO*gb*Ukhmt|*lZ#j1JuBx5+1vYyzePr$&*tUv-sd`ef9@;w{I}o#=$1F#8d5##dezNmyv6IVx_Y`u)KX1-^(0&bk9+iW9i7gt*Pno zZfZ}d;cYsYKA3Aud)F^cFD@k4ZaF>fcfOpex4l9=*pbw@e|`GNo2S!p@)~P*k#BN% zNBCOwyx5DV6JO0GczdE3UYqQu29&-ez4>)oVeam_EosNA%hHM3on+GVr&C>Z>3H?l z^n>fC()H;c^4w?f&)~Dh=Prw17->#p9Y@k-bov`J-DF4hq)E8nyhr;d-8|D9-k3M0 zJCpUKwL6$QWzKuV9)-@8(_7^t=V9mRWirocr^&mRqVBK>FXcot`7qp87g7_tbq?kH z>Gj~Oie5H{R_}Rjiu`K5-Z2l&xzux~xhBpv%Uya_^n7~$GXF)UQZF8c1?~H;ZtpyD z2lLQX>ldV|*XXZ=-kyCk`eN)Cif&A9x?1M|bGZ66)ktMf&q?FtsHvx`9Ua?74HG^G zYhpLO{Al#ZnQMP7Rc~NUc0ak{%#AltFDZi-UHyE2Rpw?jI>s1kp`Xsxqoa~N&iVRW z=hjrWjrm({M?WJNQC4*O)tu$>;&Ji%TQL4y$Cfw`N9H(l1e%R|l!tgwN%2nSIP`dB!t(f@D;AGy161uz#5k-@AtF25Jxn z8(1&AlR5CVk3oOD9wx^f>XWy;3G>Ek(TB3|SEZ&j^P_sJ9G-c+)ctu|Ka7tl$B;}V zU+GU!la{M|zftSZc-se*y+G#fzee3}UHo4?-QF|d7vgh>no`Cm_8c`!BkBp*A97I1 z<#(JFzGKFK=7GvgdJpUo>C%H?NG8po{Y{u~SXrX3SUPJA#lzX{~6UKr%Jz53GVfn~HKmV~dG8m8YJ<1saG5(V_BB!ym$~uEICenim&?t3@p@VOpNs1> zW7F67wN5ey@vb;b)se@cJjNSuC15OIi=1T#{G=t)C^)C27bQQPwfMGvwUvdaoyJE zq9>7`rQ>k@FxI13_c6-%Np0KjRd}YD3p==B5uZKZGmbsI?;g9>OX$n9mZ4_T!tm0~ zw$Zl?4ck0*Jtt-n*=x+aA-}J=M=2h6j@h&Aj5Ddnlx3a&YQ?K=_IVt0)J^yu*2^+h zwqtR$)?rxA$>f&C;enRHSk-w>Y1;nq3Xrto}+!^ zK{>ek{&aBFx6{-2{jaHQCqDB{-%Yz-d%fr-q$>nPwtG7jNmeb{A7x`Kqm(zVMugk=~w&MkFms(Ys+~<4gI(_ZJ|89@l zCBqj^_cgu$PEJ>A_kGCSg~h$RlhX^omrK1fZoA`>H{O0PnEZEs{(F)8qPA{MqqqO$ z&;KI)FJ`H$qnAAO|KB>&d7S>vrHS^>`xnSY-;@6E`&ZLX$Y1>6LVs$m-jsT% z@qFhZ9+Z*xG|*O`-oJ7hZ+Sc1UY9;N$9%!Qm1*azFQiYd4AEnVy42}b>M|RG)$N1y z;l+OXCLKeopH6Si4Tj&vy3ytu7)IFPVY$X{z_iT6M zLF!>YNB_f99n_1G1v5<+oc+i3&^z~iwx3+(0di^j_rR^>2AnW!Ti&HF4>=ezNavw7 z_^|0aRN=95o|V(pyUg;_>mp0HR;`TuK6Rzgxp<5W?D<(QjP;80mu!BnXE*0jbk4(^ zKY6a_&|DjcE()vm)T~SgH!h0*sng46dP^Kr*h@%FU7gd+VLkMx=ouoX>*4GUuu4KZesft{Py!*8$f zF?#!{SDXJL511cbSVBHm`bfZVh7>`8>ufuz~N>{UEDm zUS(Z)DZ;1jee6FM*FXRIwUcD`!6P!J+ZvvIJR4oSw!NU7gO5ynatk*sy`TB_N7F`f zUhZUcbFtOa&(MQ3a;Gb7Gz6~~o+_6f1MZ_>u?oNY{NT0%5Hqf=WE?5?gJ`ueKq zAz&W6`J!s-X3#|cDd$7{EFEjavCaK3q~8TKb~S0)x~C3?Yln~d9{JtMxhi=dhW=jJ zpUyS7zx>X*&oi&1ku#^4{o82D>{HiikAi4TKddZCOe)nsBtjD6gYT2)hP4$a+GanOUD85_%_E<|3#}!(E z-xt4^=h~^udFcT>AxqJ+@nkS}m$R&L|Km%&>~HjQedl_j^ix^O62}j7YaW*)e9nIU z>Je)7Qzu~iqpO*lBoC2!nMs&i&vqL%66*5%);<}0-l}FVtFw4~&f+~hT}Spg99+MJ zJVt6MTpSztd#9dnz0E|!3Lf(a^{U^YcPLr}yuOV2u_Ng0)|Z~Df0=sLM^ZPnD2K>X zKlJLu^ecK0zY5tko1TcV`cwmXldnCH#;Tu4Tb}<~TJgkJQ}6DF$!moDS$ej9Bkf-H z8}R&h@Y39$_OJM6+P38D!RU?Tr?=7XNG;vv_%=Q2l^&#e(JOrJrF|`0(ak&d(WiAM zIgK#7%wE6wDKwQOUmPI(d%n|OhRHwgIe*X1_y_lNnN?=?QeKvg5ATfH)A|Ej(jR?%De@EFpKVTON65si*@Q=&|I?F5 z&8nkz6FrX5Tw1Ck>t&$%Ao~0ud5!&P&!!ddH@X?R{pE?CbalEfT_dN_OqM=;C_lK; zn}*0>+x6PZX|k^|GTzOf8E)AZSupRN>q$q*jZK$vJ9OJ};PzbF8f1%$)PZ9?p%-;o1Yw zzS{a8TR0y!?%=#YUPt3DG#fejNX~rJZ=+wm-3;EDmb`^Kpw zcxK2Wn?uU$R|rIeZ$LvX>QRm)j!;hRgY!UU=Oc3+F+iM=QEp_-Pp@ zn9HbdUr*|j-~IJeL(eODvS!N*a8uUMy)4&dE_p^@yc+PR+ypNbKKJwYG4hdP92u;5 zkBgRC{0Otu7yCYB8OMCt|DuMACL70tOb2VRI9@A{EnfZN9q{>;0FUaTSY}gyptn56efoC7>GctVC)z#f$Fc)h@ z^{i)4j2x9U_B=k!pQUxy&a?D0_UeS&9D9|VQn%IZ^8L7-?$2C@n>AtiwRnCqD`z$z z;rN$t-Jf!6nYRjG5c}J)pGzJK%C2hZ2ve3l>hI3v6ja7HN)@26m=42=g-&FZ?QVZrN^MYbA92{cuw5c^7&+oeYsY|_ttt4 z=d60euaf@SR)JdS9A3z9RhPO4CIs+1G>LAOFVxlJ+dWFKve953PNG>))ov<%L^}u8wXkQ1+gwou zS%S}H8Ej6E41R~gs}85DyZg8=|L$%Nd>(WEGWXrxt9@}EC7IRKrz(dZn}5kNOO z0cb>mU;wiyS(0r@*7aPElO)TsJ$Cud*!S8~rTJ~$=lOOou!R9ZS^Ui;s&<{m3H$7` z_daJo>s{~ne#<#sMwZhv$NPMlS=P?$k+-sq#((Q5Gc{}pB!FBmsZ+#!P zQI2 zuO7X9JbfF6w+?h+?0A|UYKuH}*Q1YJP2Ky=bG$&_%*;StWV!5q`8nQen4HK7xPL4B z&Ai0{7?U2Si)iQa`Qphg>QK#(=}7P4ZT< zqqU}V676&h-G8!ieJXkR{-~F-ABY_8XRue3e5GI1no4W5)UEAhQ?nEA3tr{UO7ix& zw#tx2zaE*h(DUA!s!8?>w70jqw9HrZDWO+5wXiap8ohO7=6x^c^h*P9C;M|ZI-O&J zN%Z$oG~2EU>S*yt>rs~v3!l3>df|B~IF)fovz!Ny!_&o5@cMGE`mMUU|98LG|6~~7 zzQ@w6H+%mK;6=4ZVQUF_gVqJ}8Qtc>WAPEA%WD@$YNJNjvC5X?Hvp;{^2C0hnx!ewgY*4LSdQpb7FTZ=bX{)F9p&RlPi`52lxtm8PvyiWfg{b88{ zF&9Ucv7eFiF>=rpc^#e?`efWk);0`>x8-H}h*G1$v6g3C924m!k2wtXxi!rCRD#2- z<72Gkxh|uRu;^{@b^VN|99sp8SCRSY-%A?0T734u=%>*GWzSZ}3Dy?qm6zAOb=!+R zR*VgnvT8ifKG$lB`elkRmY^uHTC$Ov3@_Z`^Db_ zHFSF)Sbyvs*ST)`aPhr6MXrllbkzK!b9;P3^LDNVPPbRYRP%yczOy5o+iHpb5WPE&JZ?LvYdoz46Z@u@e(Af2=>v^%ak&JF;`oI0JJLECm!s#DgpHDL*o#{g| z(7%0sHvQnOh0wpd8q3p<-Z>w=M{DG^>WMBGyF0yt z@5aAR5441?t`B`-q!lmv$yBy$ZTN5o;PU!XJhbTRo%nNRPaI2cF+Q+wsaY{y^(CwW zU7f`&nHe%BXNOxNKm8JYQq62UgZ8dJ{rdFrba|pNyx7O9_?;)y;XHjxFO1Yg@A}1_ zZOq3~|Ib{%I$|4KYwe!7z=fXrt6J)EUYFZtp3_`EW;@7GfT7g7TMp3U0xyl4tUj3V zfWseNTh+z$ytO^*GZ!zvHQQ0YiyCBS6?K8UkL>Q^>u1PkQ46iz`4rb=a%y&RT{`eg zysw@QIk~7ATo+>yue+hC!phE9tD)6%ozt_@gLhT#b3R-zj=pTS^ZG<}Tm!qx(So=} z%5DXVQUA&H)a$v|eHlCSc-TpPaxo8b7A?$vB!lG8SevVk=Kd{e5DQjxPTtq+o5)-z zr|NHxY)U;r>df4iZ`IthhJNd_-fS1dQA1*>o4|L z7Ccty>gNW^m&R3vrkfec=f$$b;#udtInN;z23Hn*W(JM^9dp<91V{EAwS1xf!dTYy zb+O+=FK2!v`}JiW?{mM(FyUo^b*Eu{{oiuGnyEFT`k>_C%toFM(|FF+D&5!C8p~An z>l(sWAgjq$MFu~5E5|SL@p!Dr5n?`!b4M1_?_wQap~<6_!|#LW?4!(yxXA3@r)ORL zUH^>F)kk3+tJ@!S2aG-Z49*AW_i{eOu~r}ZLQjnQ(O$1vFLxhi&0HP1IN$Y96zLovCd+>YVdyligA|5K6_7! zah1&P@ekdd*BA3AzVAolw|uVnSyN8WB3y{I|fpDqoT#rH!-wqNM^Zua|;)sd5;Z=@cb+&MLmzuzs- z8~rKg`}PGp`u#XT4f?K^?v4!Cg6rwuM*o39dXJjR=s9w>i`p92H$nc7J$@VaKNshz zzjGcB&rR3ucF6I5|Liq(u7mneeC1}d99nlzlUJC{06YdYKZlL0{1q8|3< zy^n{FMxXdd^-8pL?%(zx-2OcMNFPsYAN}prvG<--zK*=~eP2%{tG9FB|^d0hq`M%Q-9oGwqhei_~Okh`WI3{F&9= zCjBqIr<|VO+t>MA{WETt+q|67{r~dic5J@K|O2O_ygz!^`sB*XPq4^Zn7^d+=Co`oWF4^sS47k*Q)f`aC+b{f*38 z|I-gIQnN|zWp|N%{G%J>IHH4pcxfp7-Lm>3+&j=*n!bB&j5+6h>6MdY+*2RgNY=|N z`7&3|43garW1sGiTmN1>*&Bb$?X7szPr%O&tZ#%vCUkR=PsTgH?m}XagAQm-EJ})*VbwLvFFgd zoWr%&s$x6&DzMQBycUsZAfv!na;B_qU8&dG;<~FYsGk+hwfk_A+2s`P^IBYRUvc{p zHx$?A@Wa4>)&$C1U1-$4uO3eQE)$LL64!(>G8h~2x5$a-`VXWzYP!_f=Z|kKI6ZPA z;V*d-&a+PS@TMn%Bd?8>MFyL_an!Qv_Z8k%b7<7UbKR#57IOi7F88nA?vwTALZUHo zomMld-1=zviGt;V@ziQJh8`apGHj}be6kIG;MTct{|-HtZF3A^225zR+*%8ewe{t! zuJ&lps>p(0(&+4;ShtsX>eAI5OFa4Lx7I6~rB~?b#jOk``>2y<<_f)(VY z-T#}JAzL*ZB(o0f_|l2WxX*o&$2RKX9uvn?GSw;OFU+jdb7U=nT41JJbdiTX~5ZzSM!*)&`t|ajN>$G{nSNBYpp|fylNh~=eGV8ectwdEg0SJSMi(Sd78&F zdf|MnZ0vVtin>tiDD6AzT$0|kM!X_sEqUCXoALW(9fLh-2P>W;m;B+FhdQwK-X%{v zy@y!WjG8(1>g~+YIlk6U(}s`T|Id@nQo-+w=aFN5=XN|UnbjA1_?}TWbD?WXs@?H8 zzeji}nWOASSGV7o+vl8|+oLbc^Zr~fa|6e>q^YLW>FBom(m45tJD&T!$aJaO^=Q=j zpK0fOWjqYkQm&sJW zEAn2JOMVvztDcMTLl69}@5aY{?&tqLc@O-iOn$r9 zee%0~ww@siXFrO6%gS+wBgac|v5ed#_gYxq9Lb!CnIcFdjcTh8zKzK^^0 zxo(5w0d;jV8fEqOzy00dbp0>pzWn7+eiqq`xt4T!FH$`)_9OijkNT4L<-MzCLN_-* z{kyNx--+7F!Djr)_*Tqfv|mW={`IMP?;7%3$ZIayLALq~o^`S!;cxvX*Jg*(L{CHd zki7M^D<2@25p8#{A$a)hvpuO|&${&LR9o7&ksc0k`p~h;(BVfr$SOxuKRezP?5#iD zdeO5m`5%xI^M|jUq<`sD`u61!a$uUH*J&fZ7wb=l>7%4(K8BvJ*F{d(_u?X_oA+Wy z&9#}n$a~@*Ps?_t*JST`c2dy3mz@F-fMLBG|O;i4_e>ly7hsN z;LC2>`&6pk{Y*S&j*N^PeM{+2c>=Ai_2A0rEu!{nZ$jsy_pM(MjBsIqydM1d`e>Z< z*5}~$->kOmFL!QR)>IGA9t3&f-7`m0D?R!St-p`g!EflZYP6Asyi|jzHm4pt2@ANG z9b@MArG9cV+g^@rHg(`B=G`L?Vu?e2KcDY=HsSrh)u%qE9~{m%GbZ*A&p*qxzj7-% z>1FuT>2;sA(d9b&;*frCa^)B=Ifrr6C%wc|>YW}RIosP@_bG!OIhlRQQ_o!RSFC z--B_Ri~Q{|^VsXF(K98RJ1&&l&4jVW&-27{&CepMdz}0{YNkaV3?88U_>n>n-wBg$ zOgE;RV&8jC>&b9meKeO+)MogYJneY5@J6Z4^BEYcxGwo!Pgv;UJg=A^l8@nfj)nKf zxGLs6 z&tvOfxs|hJa~J-0JDmTyI#Ln)O%Ivl5I^HgC*KA73LURt?t*n^R`)f2COtqd))wo1 zI&+-yEWT}ziGCM*>X>b0pW;f!Yt=i*17vKhhV40}Z%%)nOj*9=k+evU(WAScW-iL? zA9`4I>_$J|6*UbWPtPsSp$W3kPd0B%b1kdV%TIlU+!wS7*BM&6^Im$@I2N3zY6x!2 zVmI~TdeJy9$Bt6#g8uB-poyMFozx*aN9K3I-xqUGrkd8Inl1OGozH(Q{OM7Li7q`% zjp%gS=J;*Pb)}bj`5g7nro+^f>Q6bij`Y)+!{g+eCrms_% ziq=k+`bf<)sT|I?hP8g@iqs8%kB}c39M1mNlWv`kIgkVNII^C!iyTL@)%(!YKmYg1 zd*F7w{hQwR$?x{rdWJl#rtWQKY8hAd&5P{2oYU3L%}Ljz;_Kve*Wq(q93xhNZ);9K5|s1huYDc2gqz8Baxokdp9vRhYnsv?s>)THSqD?@QMH7n{&a{o%M(4 z*L@_F>?S+octyH=>Ub*MvoZYaW9Zf&UK*xuvz7iK)v2Y7o)YkT$I%0LTn1q0#^7@` z^zgYajHIzHa$WGKzjI*>E&gca#r*iKsnFFglezxJxlwXl24gH?4$a%=hUk}iB782H z(bdq;;&FeId4WstxEV2L$z^W%cs|C7}mj9ijIUT9SE;>WFfPbNaI8EH#n(O}(z#TSgtM z2Ypq3$V?$C=qs0Py3pVv7uoAC^V#ZH`qtIfd0#$sy?QlT$Yk>xEZgg=mLFY;Ir}0bT%HY1gRPgdy1X5} zSLgVbIM?ye?$y+WG2YS(y`0bedkVj@oT1k#d@PKS9E*hp3Qv9HGcGi9Kckv&oICKL zJZ>GIJmp-!a{=MS=6-d;{v(W?I4(2vd-43zU+%3wakXu=aK|a`OS#s^|CZ z+i}NT+{)~7x{KpKJ?JC+J;r>Idb@KKQBR7dsV1t=DtZCLu|?nXme1zcV$@^HI^9ND ztR6)hCE;9cm0*&1JN&2HjZ&Czen~3)$>2wLC$&4?wI2$zGJdI zOKgAf8QfnU%NTQUjA!TxWId=g)f4pT)F&e6I?oc`H;#+P{K5dW7wGltpZIe4Z##iw>#5w9V zdF(uI9INY}@%N}5FNpq=n(dFG4WK)-et*BF`JOuGW53g>2KpzJKc3c+rC7i7QRe=h z4F5|JV%I9X zBNgfW3;lRs%G3JiSK#sPqLmdzaM=b2I?p8g?dtTbTb>TkoPh-+)So=1>0~udL^CeIg;L` zf9a|2N_u{mr^-F6(|hOoqKDED`7&qG)`wfru4NvsCE?Y?7ispv2%6+^ct~H!34T)> z$xxA1x4%d&(t%aX)sywW9CM+|ex#{i8>@`W$|HMU2;I)wLYdITdGW#rj^@NQ+WB~O zTm8pzUFP~`CW}1u%J9MPn|Giq6`TXpaLuz%s9AhbLmF)8wOXz(`ha>(FKRo@K{PLX zL)4Rw&~H$!td;AA+SN=u^@v>StmX2WEMGP3v*#+BFWRastClC9smJQ49IknR{v%ss z&betn*FnY&`jFLET_Up)z0d7yIz%o!>}=+8k=e~PUfyO5WKCjtp1HOLuQLXb!(;}% z7v{p71AhvwPTgNdP*ay*?5CqXYdv+f*! zpX;N3fX|@*KfxHOdM6qqx@2hSu=*SvuNE1-Uf^;)KUupD-$@-@3mc8Vf^NGEE~|S? z{M-2+kF}3mYvBEbR!t9F&JD+Nu20XeEGFB_Nsi&dJH)mP!p_D1W1n-3^#ptVJ5KPm zF>evu!1|ZGFrHIpcQ~h`jvloI96!ecGJ797yMFbkRm3}Nt+L}%bySaAd=5C>F_znV zzMt&#(7+2V{e!dZF@K~Mu3nuPz0lMP4~64q`CVRiAE-GOS~^_Feu(c0&v8uTcf#?L z>~8N?Z`GR}f63!Mo;@{s<<+Bu-{oEw{U$QKSu5eqVN7LRrgLQW`l{HzGPc9xXnu<0 zGc|8>y^mAt;dyDUX~EI*f5H91?tJ%Uch4(5KjyPI*RybJefT^UkFQTnyYN`xGt<+d z)~#3DeQTY1%=7r&TH4lPoZ;`+(!OIm-B!P&es9{C(^DVU=N7q$eAhiUJQj{CqGlK! zVHke)HF{WjIi5c5ewEYp%s9?7Gsf@fNwo3lX8L8JhgWTRFfw91=C0SC1fFAVw>ju$ zq3LO3qn-cdUUv*Gs=ObZ7e+&9}T5HJ*E3x(mJJ zu_7mi{ZhaC$)(>B>L>XB7+yuQR^;!wV~iQm(X)?7PM;tL@^bIiRJZH#bb=g2Gh#ZZ z`#jn35;{D;ZLM7M${$Uqj^bOP$5H1#7<}8;)1K$PkS1!LNTuuVO6D-y*J%HXznAts z|GR0dY6Y75H&WH6d(!&Hej8qYn7l^xbi6rTd5t^AqUTn5)qqGl~?t23L8?qcSmz7M(FUZMGU z{y#Ij>y(*gWnZtZ?QLe~e824LB7@8BnZ4z4|IVzQ8Qpa*zh5@bej6Y2b@_Aoesa2= zd;K@RDWm&3*QGx1I3)XBWORER{mGyHS@_cb>@R;3TDpAh^7sGnkCD%4U8$^ot6x3m zz(hVHn)<5?6Y2d|&O{H;se#7G8gHuHovzQ1q<1b(!sDH(k!;119n{vt#npS)ri0tp zpjDHZQ;N|Bh4E62tH>2HkVtD=z;;Ad!K;mTMnZ2!+z>+)AT}_K*P81N^mDyo-7%@c=ki| z-Gqnq{X0h?U&-pBrNZUv{*DV=-)ZV9WrJRH&z6#PH;-4=)U748wot7%YJfTRjyKdS z=g~>c>2OTt|HoR?W8K&Ez=Y9HwlMBuUrsZxF4ubO{VekPp_d&#Bi0PA=G7uexKG!o%Li{7mTdoCDeW9rd8<)jUrYce~_cwNTfi zf9o7vtd{L(J442w<3*3J{$#azHGXUN3Ju+w1GIhC={b4o7#cO(rthV_lwLC&PrWrV zncM7Rvg=7bH;mUj*2VEQd%f5Ww@qJ;yzYLG)1%icf4AWk^0&nEIJlZy^>TG|w^5$g z-{b2t+xJsbImTn=n#jazw?6LT_$_;4ZmxrMgz`@iH3zB9+~K(5h1fdF|K>8sMirx#w0VB9)n zzUTIntKIo@_~aM+_DAiEc`nwQT7P+L?*pl6=Y43@tHPh+JdvM8PocLmdMx~&4DtWT zx);L7-pE{D)s}~&pORx9dncUl+?cjK_cb{E+2~1JyY1odp`31fF-_OeznOd&GtnCxX>dQ7yTxR#Ra(k}j^z|~cjPI@M$?qfU%FJ@QT<+u9bCb35 z{2I5jt_jV+iB@)=6=!a18p_fS zZ_K3by1i)e$ML}&EwU5O4Wu8ud72)g^=WFLDQZ1uPqd}0^bwsU^W5H|7bnU3Ij|wU zw@4pXeD1z}&C~a$-Rtp8lI>!Bs97-YU!F+qwR_SOjNjh?R~*^H`wx)aNI#|1#+Lq zuE=XKzd*imk&81w%3X)aQP<;Y?b|TCtuAh#71`VRwO1yNrW(91S4S&?AMJmXS>0?u zJ*+-Yw)b!AO65O&05XPi-SURIql-Ph$+z9V_b90DnN7JLx0pQE6~Qx z_0Xe?_6xI_QSNpA;Q9w+y@key4}^W}7{WRC0j{I6dCv0l8Y|D~`_~`g`>DOkv93>z zU!G9k?NOJ7^|CHo)L6nEd_Iq-da=BvUaB9#49Fhl6U=y5v##GuP9-&`ZkM&exi5{J zZZA^DOWEUc4nI=Cxv(nxMSqCwug^t}^nK1)R|f<8xz55R&cEw>)%)(aVHzHG>|-{{ zkzM4pF+K>tIqOr8oa@*gbN^ix)(bd}u_kl#&Ce^l4{~2<+)JNZZjyK1A9-K-f4Qmf z%QzRJ52oO3kD;}+YWZ%v`)>+HcOT2+YNPgd*K<+yCS`xZQm1&`xqkfpaXid*VZR5L z!(?!}`HO>WpW1tDqw8avi-=Re)Kuy^^fKVO1C}3{wzE$?pL|neV&)X z>&!lj{l@syv9sq0uPHnjGP+)xoL|E>ux;*R_mTX*{JH+^@riy+jAwiw>lgig#TbF} zLr$0T9lw~hqTkGnN^5D=Z1v=;OFKX0xJUno40v?sV`=p0YQ8Uz<0E@K9p3z8WV9AF zDSQUj?c%xg%4k)LORSxkWnAYuRKM#ndgG$8lB?8%7F)6H$@m@dyzv-DpEKrpZgRhz z9_v&~|42{wJn?gS{3ctr##p>@AHEOrR_y7i=fvLu=RnlOJ=Y!A$C!#*1p5?wpP%j8 zNNM!sIlA+S_<^9$5$aE|kQ z_qF@k<2J=PX8nTWZ_f>X%MNXP6plX}zXyxGyV4`y_|NJ3Ain(lFh4b(_HMI2(;8HL zGBUouA(_>!fpN}k0)2kGo_V-^PZhsiWo$2VJl4TZF$XYq6ke{hev@^QZDTK_f%2zP z6@82p7oX?-*$3}ubK8Bt<=HQ?`SK-ywp(v~ zj<0iluG=1~7q7h*jQ-9C-~Ncx|KhJwXzA3C{`6-*|5Z-M_mWxtPX3pyso%IXmA?P_ zEEz217LvpA2X8J!rg(D&Jl9eYwWHsA^KAOjyXVvQUL$j*=V)5<%tPdj*CqRk-Z+c? zjlTZYdG^myv=#b$zJIvqO#PWKRwHc4_G62R5Q1Z+|YelJg>y1b5>r_iyK>3+^KS z8m3ZrQiqbk^cctoaMQo>X^q?2a}h)&Z+fT zkEvHyoocMEVAQNR%i7NK4lxHi0!zs8UT3G#%G4@-k3!4j|L{xHhH~9A<54zOKi7Y% z{%#&yW-vXca+!Uh4Q%$QyPvM$ztNy#K4{ zcjUOq{+{xzS&8c0$I9qo3Oic6=kd`iG2gu>)@9!rdqs`I=6Z9i)hm7Z{uuW-wo<3o zkM4LvZ%||_s^h{iGPQXbYL{|s)b+BxZnN6ya$a{|c%Pru&n%ff_Gt4&pWqK-i~TnWe23=zi-o1cFm^ziteu?^0Lxc>@` zT&|P1;dAzz{Aq2Y-Y3r$zsIgqFNNcim}g;|ymdaK57zWE7w1*M@v(08cGl&w@%!Q8 z@scBh(b*0;UB8rLX6HrpVMV_zjkoJ&$a_xtYl_rbQ-m^#m<{_U~xyA?H~j0^R-Swru4&0}=7 zhy74bPAy~fnjO?o!u8H?jfO^0=n3v$_jMoJ=$xFKKHtT6kl%vw>L=3v^=R$zyT30k z>I|L(em=*Ir=5%7`Fe>i4bfW`4d1%=D+9Yz+uny$Ep?h@>%T@X(0fze&PPJq@8q{Z zPFF|IobKOp`Ve)h=G)Zrn`iF?^?EgeQ9j3|-fiT+d=oGEBf-a$jntP?uRdIZPaaKt zxbjInHu&4io}i!6Z{tP3HyxnQQTKrdQ#bjG?Ti`P_dXPLs?}sbTH~7YU1WHD>TL)4 zZAM48=Y(^Zt;`G9U&%hD<~7ReW?;$Z{%&;J4~ZI~&;Q+d4}4lCzuoKa{EnZkM>F%v z+VZY^ER*UZagn*@-^{o&uRJZUs;T>2SzE4mQE$##y!ZQDb!ge#MZT8FeP6lP_w#v~ zyZwK@Pd?B5EqnX?{M!6{-_vdIaTj%YZ}a=(^Q`R_}#_SSg|+tG#xEn7Vp-9;OSL7l5`90lbM;s~5$39!2cl-&k3PT9U&i%# zN9w5B9NeytVsVh(;#`Z&((A0jJHYej`^rMYl@oo=9RJrZ?fv>z&0ibgx-LU^p?Aw8 zUZb=BMTYS@DT}%2J&>b1^)kRp)`)tomBnUwZ!QF zY;wN;V7kD5GE3SFY3I5d$gK2pI3MB|EALlX-`7VS0-Q2}J}d9ZvV~vY3`BT=`2`;v ziR=`;F>36LQQ%^at@>lZ!v!11Ilx%wCNFcG8 z^pMDlK9(1sBe&<8fr8UnFJr+@#)potLYI#*ggG_VpSsV6W+1lcD_gI z|N5TYH|9`Q+Y=UU_PyMvZl`=KFBkcn#r-~3aJZkXm^W|?XYF@9#=g;i!(-LZk+?Ye!AM>bK*Pv#};E;|pC zY2IJ{B>9JAxKO8Q&SDq*J4Mz@=JcDsmnHv;$H_VYe?y!@IL^K_Z{2aq6t$$gpZ`i~ z+51@N*=pW0^%%J?HJiT~dbxQqeWg#t7^8IUS5qySE)Co6!P|0QY(wjASe)@g)yBJ% zHKX=@Zim11p10DI$uXRIx?aN`vKXx+9iVrFUVC{x`jo=uGP;X({A%l;|GV=ZxE*JI z+WYSOj-RbZr+%fMOh&RnZcTjrfOGarxpT$$U~`COSfbF+-D$0c*J z|IeK6b7gSf+gsNmmwSJ{&-?xVa$Vi+&8+U@zL)&&;U+8k*}EfuXI{Vc z@674>e%J4IJ7#h2z~%gvYmu4$_WK`3#!L8K{-V&+fAZ76PI9{5mtXwt-{177XI9Ug z9{Df-cKiNEvic9-IY$=D!Svy^smOe}a=L?@m7S^f@Q&1sC#I$5K>DK_3+Z+ICTIHV z$WcFzKYSx>y)M0demHW@Yxk{9bq7|bo$H@YrMuRo?)rl;GrzknWpMc*Y~PQ5&X@^? ze{%+oM$fx4Lak*PeV#WxMZM}vsjsONKTBtLSKe3{O6EoW0lfa+LK{5<52xnRm(#X2 zPlPT%db|>?yp|eQ`*%hWC2V$}46LJw9h)$mnY8 zvV+{{wM~xkKCi7Zh}?sgwz8?0B8{ngZq zK1XX|80LiGYMIc*YrD*#=UpyTqgU^f)iZY$J`b6&;I;;Mq0RNfnP znC3KorpA3}TxOjFFTwZh|ETR-7LQ-pV{VL-yTq z>Lm51tC{I}F~dP-vu~@%EgvuUsZ1q%dMxxgOfb$eBT=Sse&J?~ExMoDpV=uzPI=)g zvR=_+ZB~mcs!zt_8{Q}Og@0#0m(fFaXB!-c=6spFpVhI8dQQiG&My>s*ZQhtc^Bt5 z{BEdyy06v63s&b`fPG_J00$RZexa*72UE~@rYxL;%{#YPM6VPH+>MiU!m(;r_1@UG?w#oIqr}N z!#~4o&ApKo<9o${GTC7*DHY?Hx5-y{R@?o_(rp3v$&w({z^ z4m6Pc^rNSaG>#j`#@`3eDd%{s(TrMQzN>O+IqV&Elk79=RrG^<%wk+XorZq%1vLEn zy({VCX^l4L9Q@yM7#*G8g(=R_LccHO9h{%?ymlMM>+tn34yZ66iv8wxsPDTJnOVCy zrZB1dmgDd5f;H$hyU^e{*Id*xa{WP!4>=e7zMREt<$IY6d68v-@kxK_qiLk_@zi)zkT0K`(FAASugiRji|o%q3A{WD0z(Eyvga&BZ6bz zO(wc?D)w|UTgO^fGb9J`r+32QYUdr?s-K&K>GS1wee0k9yYn9Sv`l`x*WdXaKUqJt*c3^C+i*2t9_uNHgt7a*yqWwKIY>8eZ7n=Gt0$tvKqF0?5)r9 ze%C8gyU5e7$92lxc^$52IkWq?Ebnu@^|e0V=lOpZy)ABUUh@0+8sFFVm(Lw*I6t6Y zJ@dG?YUs-spX)aGUTW!+GYi4z*WY~mrtihRMt}69AE*EO&;FvwW5oB8_4J(gvRqfs z^`v*?^k4pOGSO$#n~NvI=Q7#XoL<43^2S;APfKO$Z>y%?=()&HX{*J*0ZYGfx}93k z&FL-rAAS2WHNh2lWt;b*6K_v%FOZ*Ef#eeHBQybTt@ zqkdt$4V}FWKYa)Me=IEwR;Btw>m%Fkz^12pyoub%(&*Q8W}qSRBL^DESm-Q|>x-EY zT@`p(4zu8aF=uUx_p-j!TISIWndEN58nGp7AoZ|X!4V_+!f+^J0 zVTdKZ37w6<%~cEy8W#83Cl3_QkvVoTKA{c~{Ypm9>@KIN(aDi6UQ6|=j>FxNSIo6c zeb2e`UUDDgmRda5Cm9d;UTWiBk6&JS7wn+FxbWfnnW6^`?<=eIspm6St)A|>WY6%H z#AndM!ZyK!t}}YL@?4oz=JIu3gM&}uP?^K=f$Zk{+t0`2S+HuM(fj#}8pK`cVn6=> z8hQXS&X5(=*4xWrm!)G7y=fS0>3cDQLw#OOyTE*i^D6Tl=G?%%@VRxleO&jQW0%#` z&7voxb!*#J#5LDCy83-w(-~XIGx`)<%=T~_)t7^(^~~TYaQxzYy*x3({JgaU^1l1Z zMQ@CHyLxpO%p0C|b!&J%<_(rK%v${Wh zt*q~3oJZcD>qV_guuj&`5Ud=pcfHgIa9(APa5q`}qnszB__>3TIDTwbHQ`OIUeVI3QZsWyzselBZYtbwslsOOZQZH~OfQ+3bcr&y5= zZ@7<45YD0PPXy~)XJT#gj_1EdpJ6mxYXca2I)>t(>S+fu95wODqg-j z#*e;_9wo=W#qWSVEb>_C_2s;Wo*o%q&EMA_-OJdK@4p=Fyqa~izV2)<-wlqh9PR$K zznF7GdG5@dSal1tYCU(=t{pSkgR~XD$L440-Fe`pShrrm;yu(l_N4QC$E;~}JIzkj zpQ6uyjylyVy=1tMg?^fSRKDS^(6k$OKM_4ei?OY9HXqfJUO&M+;NC~Wn{E%L>g|t* z&fxcRpqhGle0zRx<>*e1p}ixl{helR#Ga$a5AeO+@ldkI=;RUR6D!C{-|&qzN=>iX zHs-6h(G#Ml|mtbjUgbYDf8gAHxUZ`?Zh{X_k8E>9BeG zp~5F+7K~c_=l|}!2X4pNpZ2~xzvE}?QTbP`SnXUrU2gVPHqDG}R*IZ%Un4Uav!_Hh zmv`07eSY?cWVV;jWnrJ=;{P+(yN=B0nbTc|+?{V_?pK2T!+DQ)h`!{X4Io!LLpq(Cahl z^|Pbt-OJ2>;77MF=pY*T_g}~Ba;g!Z$If*1WE)4P-ZoIbcP zkV>{apV}+8(3fa$I##|(|ycE*4H;<*4i9i z;dl)`_sD^P(e0}fxqxhg+u1-w|`# z`c55}WKX)+%)De)S5q^CV&>Rp@)912xnuJgWv*lBWxj{`5BeYqpTqjJ;hB4HYUyTK z#9TPsKZ{3NevoZ5ck02B)3fJXW|RG#>u`~=WDNOLEz@gjKfG!kpI#if%nTPlr~J@^ zAK2@%nVN-eTZ~g8&qQAX+%VltRv;Q%WC^lwj!{?OILdwQ{*HQJ7~L!qb$-VIyH-Dd z&$v9DY+OUXst1GJ^t%s`Vb{U?jW;mv;M(jpc!ZiXH9C8#?0S)Uv`s5wTopXC#OZ2| z=B9VBFS{B4jllUm%-Iank7@wjZvZV&@38Fdm?&$3H~UJlzuo6@`b{=n@_Oj^2sRHM zFMR9Hx#;h(=e$~}=SyaF`Bc7^%kw-z@Gy)n|LTD#{4#}>?YTSA!t;ZbSr@m#^s+JQ zattG%4N|Y?xT?@Fi&|ls-D55vI%lBL>akI|Y2HsO1&sjJz zF5^6rH64?<{aH^By`M3gOzpVF@t(S>V?xJ1`iw^C4?ICXfx#O16+Vr87}nu@k3BFw zwiEEVwHBVA=A_Djjs^V;o{wffshfMuhsXf5zOixlBjjVFp)#Iztn7BaIav|=!F^VE zaf-2oeKyPRNSk9gOMUmmQN7W4owvh)j4AXuxovW@x#BPS;l^X?OXLV#xswlip>wPpXmd^ zcR71rGOI84?qSS?cZlzy=U<04q-fdJBp&8=&gJ)?pH?-R<{=^T6>Ha;B;T}`M;0f1D}@1@AUeQf7j2}BWmZe zapq%rUC&EqYuVh)bZ-w<9tn1pz2)uY>@D-k$MSIYl*qsGu553Xqk6pSkb`}W>&d(< z>&wF~vbF4;HFTLgGkx~AWDVWtd!M|me((SDIKuyXzuW3q!}s!W*Ol+j+bX9oUoxlr z-p(!PcahVxFa0~;`@_ghm(%s9o1Jbp1N7KDs+H9|ss8d~j(bRqkFDTE1g~s}uF{ zoY$w@(pzU3r|o<;^dEf^=eo&cM(-)#`edplD|_op4>KM(l-@W)<~zMeuT37MZ)jN> zY(zW8=hDj@z!~1tY?uZ3yc2)9`ncNqY5dA+>Sna*As9b~pBz4)r$673J!mu3CHmZ) z@8_*L{AdeWIDcn7J?hZ7cIyZ3=6Yy-pBnvz6ZrB6%7ekp2vH|CqgjpJOp?jSZewh~ z^(^b(g^t9^6~KFRs^oIJd)Vr~I9L z5c&aRJT*HrY4o}4B{dhuT2r%~gWX}Tg4Nfg33UFFjSs;edO_4y(MI83vu^a~9NA6p z5PA)%GwOp@(>@Jv%#m$pKNhczYajbvG84(4t3)@4)78`Ebh9?~W4Jy!!&gy)Vx{u)(=CPTW7AM;|rPB@rnD}edyw`R_l#1Node&>&w{LbA!e6+_9VfBz0=D zk7O+Oxs2`pk&|Ti=t%?v7LQqrX&p1(b+}rOfA-2B-SbTBcWWnn+{N*c+Vw~s;}&?e zyW++8Ode~;9RnOIYa@N0>j~|f?}I$+Iedx!VsgBE?PGdATS1HrN>$n$E(ybN2V0t4Uf5A7q#>r{9u{=vra$9Z=I(3hP?*-l#vgm^Enz)(kz9oO3XDH0B`6s5Rj?!uk<^3-sw1`KHC(ou6kOymmkgOr^!r>9o^pSWJWiR_qmGm@y?*Zw*x0ez zDdtY}o#+iW(_E%@EIjD%7vo~jSI1YU8aX$QQVYKRE@}j*GdP6T#(b7CdaaQSGgSUq z+Vte_;z@$ztLQC?PsZO6$7(J;FnJg3-4}gE?KNs9qrHt@it&>53$nONAIvVp=Xsf4 zzyBJ+ZkA>DmQlgsC`J~SNU7M z&APO@yF4pbyDs@%2A9Wk-n#uuT~Ba-c}+08{OF}*!q7h24fkurYcw=;kIVA}l5 z*U1c^w*^}B&ead&afgrT%QVtpEUV-BVW?y12d-wQhNwOa`@W zu08gLKe`VeX%9Xe*xlN^X>!W-GWXU}cgl10nak#ryxwbGC!Y6UZGAMn-k$RIs+KxHqvG|lV6I{wTi%h`;<^qC zIDaf_sx|8^@mfF0b=>>(hwG8Q9iL}TKSLd*xiV)v(Vdx-w;s&8I2lU4OqTA2t7Id6 z>+UN(F0#4v%VUxfJT6GJ0lJ zAD4^GZ;)lJTUC#g{pGf9SX8~%{6+WwX)^EB2lW~`_K}G%swO{JOGM!rBY%9GI4?h|GuFUx`8@ZJ_TgMh=cIsnMBahxb@Lk!ahhkiy z|GMxx6)fXEFEaGZy&(6Vnpra%e}&cI#9oe(+O2c@!LRHS=M^%id#s0GMs?ajcy@?I zP7mJ;`!ni6Ilp8v8MM%!J>QsDK|gk%7rm4UPk8o)>-TZ)C3JNC<}8kJUtbs$<=-a|F-UT9uKw0+x3TT&$v^c zkH_`s9|k z4Ed;gh0z^PxrF}C`M8MhMZUGK&&hh~H{^6UJCE}{2lf5gCrV$tzYpPiqE5%}zu#MX zLS5)9>N?ta+%Zk&^lK*$aJX%kR5A2AuahujYVf$es&kxmxGqx;@v_C-QHO zntG8}$+pA#=782vQ*6G?Su~K#{kzFXyc^y6F?tWJ;BV?k$wNH0Z$;Du*fXe^eVldl z<*Y7?+soKvKh9WT3{U+4T&><+w-d%^{41-===#$~xt-wL7$~J@5qf$X`HLNg(8s9_ z?XOsg2mQV@QuSoo_VgE0?Y0NfaP>2VH|FqT>FD-{7!NUz!n!+_wDLjbSY&a>h33Bx zF;0-f`x(3SvB>B4C+&@~EX?lTJpc25AHN4aEsNjj^&kJPpRGsaXn9#amA&P3`Brw8 zcQ@}ol(z0INiw>eE${kxW?Gq7#+T83zPv2|=5_8lTotd~vgdHx!n(ZO#`@%T#{j;+ zJn#F-&a%2}t@iD0=63IQk+og?+wJf@y;UR6&&e8n_U-t%>+&|=mpR?-%-iaAyzpS?yB*aq8f>rEf<{gu(rNPoMz>E?e-Q*);`M2$$+9*zuj9)r^}tDm9<)}ADKTjce8 zzig-v#w@_>mr-{&d&Ig=J)qTG-_3$l>$PsxUYJvi1@d(+&v&as>m9J~XVx0kD`htI zcG*+v@H49xqJ74 zndN$H%z~4Bjx!cfWAmE-*6EtiR{PPfWFEZ)GM01uZofS@?e<4`92VlU=;P1cU;CY#PiO6=f9r2= zI)E33TGwJ<6g@B9$Bw()MzwqQoBjmnI@Hsh6L1`&=f!!8!no`eW zSx(pEE2qoN&eh23*$XAhtJC_J^Fn#Q`<&3!(Usj_a+~_Hf6G_uwEC*$Y8TnrzLc)V z_tSUc-{zL+MOM2s6R(Z=1pn4!a$wzqd_LHu!ukPxDNDMv`#8pGe5P6EdK{B@U$8p2 zj#<^ZAD-a-Jx}$Hj~szh$>XrEjG1_Ph4-w!KUi2k z_w&2n$Qk7I?r*&k>gU<3;@r-Nnmzm4#c{_8{4;yk+{;*99(^wSFY}%B7Gu7}8VJ4C zU7Y9onH)=$Z+jY+X3WH5AJ4<<@8x}{uiU}+oIG%O-JHZac-%3Q=a6G8`F5P+px%(Z zNglgkUmmwk+xZYRb=PkmdOco_17soUO{?ESohWlR=2PW*PjB_BIHzZwwSFk)oC*(1 zks&ijHmU5WFWx>ynb935TpKNm9Cqs>YqqZl-@L!O_5$%lSP2Jxonz8@VfTx@8tGEKWzghn5kEqYnPf6kbI@x6arL#u`^ zmpgWKuBpd-d=}@>>`76~rM>jog2I32r@a$rf7-|XotyF>_UZaiL@r{B@{^2JIN4IVp^uFVZckJ3LTN4>L-`lp6N>HQ1T43PP975~Xtdnxsr6{(VZ#cR`y zW$0@da8l^ zmW@%<+FMUn@rk2o@0@$vpNZ`A_R7sg%_*LC`Fy&!l3e&BX?~y@%^uy;TG4hi^v=>W z*;$e1$c*=K`>g7NQ8)71qdsL0jNWoJ^vvPj=0)~alkbP+Z+(vcm&2F8?)v0WdZ1Lo zr0dfT<^e*dmmimE9KF8jakf6xYo?m9*S4%Hs=eufQInI?t=ZF`9(m00wAb77eFs8I zlhHGm-+HUY<#k-2_B3^qYE;o51TD}ysHXjRD&Y{{SHE%L*(o?d&9nJ1dKK$;9{fB# zNzFazC`G$s{#*Xm8ylPnU&%=_ z>H5m)heFOnD?K91U#7Ro9_q$;PkBt8vG6G{)}SWQ{j49v<6|a|*_cI^9z3-)ZqWmy z|3ya8I}n})bU%CJxL@UTz3KWd%$GAqN5<8M;eILnFRu3^UM)Di@Q}!P>f!R4J}R~E zLTAS}!oGGf(?kw*jMq%PM(D~MN4Yh6lgj7l=u?a#vadv5wl*M+fj*QaM)y4Pea^#$ z;RQaj3T}mUVH8RazEd)| ze6K&O;9Ik59D6V}fGz!uxmMZp-0_h0({j3F0X5h|8|Zh#cB-E`CYfbkME%xWp>7t> z4SD(qb7R(d>Qk4a9s3^HLC)e*ov=O{$E8t!$~ou!hkb|4r16|Cw!<2M;=b5U9`o4A z@4@pt=D0&oni-7Ni+g_7?;|G^2G2DT*_-CAdV}LqYiRXn`P*V1yXU6;nNM@>dp@ei zo6qCe&EK2_v~$O9`uHoEQ}FmT>?7MS*2$QcbIU$##d+%S<2%H6!FejP`Xf_v*>}Nu zA?M-L)b+fa@8r3hL*0iTO$|FANGEF^j~+xPDxX4Azc2F5cfRi!$)MU!( z)_1!&|7D+{ky`v}oQG!N_`9Mn$>mhjhBV!@DvePq+PM4S)Jt}c`I@c!A5T5Zzvx$= zpr*8O*TYex>T_D*bp7cquzZn)USznK-;%jp4ZUm0>r(V4E&Oc*j1T(we)nW=*wXEP zSOEN#AMDd|_$R&oQ*PdWn3rc?ikzN#R(@5dmdSS>C=W(g``%w(6PmYNpMB=$sLQW< zL#(-!mDRTQmQ*LTba~u$sHMy7YU!b^!|H14a=J^_)!hcQZr9_j|CgiPKJUwq%jWrS z#}sal+m}B_=5d)^&X?;m+xuESqfDQDE+2R6dpLG6@5RrVdmH`fpZ#U%=z7uB(!G_> z<#qqImh@*o|C{tTzxcbzXUz4aa=PA^fBAp^zuV@gXWz^1GZ z;UnqdcvE_JzAc%<(pSGb{3_0IHq%#o(~A$|KX?G2#|!8%g%_mZ@P@Qw?GwS~-(Ktr zZMGku%qwFx@XxOF-dt;3Q|tCVm#XPsW8b0L-Or_xtt->1u5vVfeC2R$BkLJyJCv@R zY$c-wpENn^)|So>)~4~}Ranx-iz1#yhLf?c2$Tp&#nVQSu;RbY63P`dE4m z?Oq>>`72(F>~Cboqnfd|)7~pekOgL@|}zw9vFDE&_HE&nd&3Yy4UsW+m&zRA~j2Mai4DmtS%IN-I zz20lMbLm$H$$Y4x<_SI7Ytn!@ba+>s&o>Xm_mtUOLf403?Ek4BRu;H2QW2gR`O|IC zJ1mQyXdYDV>LwQHSxvt3`S}b?H~T<~52sGl%|c1`HazOeeR;n1%6+T5{;Uu;w5fl#hXoE{Dr*YV~fL`$m@bIYr)L z!RMYso(uNG%-U`7xJ-yY+GEPCoF&t$DSHeYA4Shok2{aMZkMYk$Uj2Aw13Mn>ggKL z8ujiUXMASPxEf=4anTUf7WMdh9`0THV7!MJpmMIY9CEA2-_P#n*6$Q!7M`z`t#?7j z()%<4o9kCGAG2ZCigdbhRVrD3PpaAWNN|~+1T(GG*yZ-pmmi3I?0ksxPE*VU$eEtM z(cg>DBr7{ka9rVdQBREC^q9+FA567wiu}Wa8y@Dh=I`Nq=eRk4WzKn_iJQ-aPmJ%S z>oZT>+{BsIb>YAAoOk>=X5A`t0CKuIy!+by;<@0We`WrdwU5uhzgzKz&_k_lL*%UM z&+&NpJq<5X%$xWdAXn>O(kn+!d3fc_94gL1&%=B!sxuV2HrwfW$@wrxA6CyXd!~iw zg>y=8yyG}~eL41T+((^)+sFGi?59=}P2Ar|`^Q}y-XC*Uj!~Nr6?Lcj>-GFapRpxQ zFUG2l8R%)jew*VvXU6Fe{f72F|GU)Nk`uG*p>%ld*MqfdHr*Y%_Mvt6Mx9IM^L%?{ zfO!b~app1F>rKze@k1+PjMlvO@nH7Q(wVPP8yHegr@q|!(7Nq#H`y|EJ01={%Q0$J z2k@KsmEljXz=uwbjN?6d{m3@zsi;dZ^T+ec`p_Q62l`y}re}Y8;cY3-cjqV6(fc`{ z<@A9XGo9>}>h0%x`o{t9CvozfOf~UOtY`m*4O93{Os_GiMi*-t=#OukgKuj{ei1rN939FM`iA zqnpPlqpPP!J?Y>6ebkg@|BI~tKmPe&ennHyeU5&G({It#<#ZYSB6XwhU7k$yBdzJX zuP>zcFOAb1bRw1SMW=2o#jk!Uy*_gsFUtPNMsK07(NJ4?Ix|og|9^e1J8D3!*?e=h zBfT}(nGSDRnaXy)gcgrqx}zk$Io+6!9^8=jz5GwD4)2Gz_Am7seQTCXPS$mXyp~tTtMM6^(ti~HYdv0s zMm#JXm3Uw1-$c!*88hna_AE8m(Y(p4ljb<`+Nrj5jrX@-(&dRJ{5pLxSF7fukKCHl zmJ-;2>q;!gxMeX{T`&0=JSxj|^Za+_a6ez>^II9+=lFVa7=2zp*IKWy^0<1GbJSkf zyrx;#YQ0x5maL90s~201Ury6^;at9)?zL2|m1zsFZBd7)?xzRhcAW0}>nm47KTm%1 z&gZ`t*E{EcccEosKt*4J}t%~r$Sm7#&jI$e0V?LqJB z<$x3D#9lYm++{NJIP66(+jpXw%QKz4r<$hPW}z#?ad3*-r~VVUBK8@)pk|kuK+lkV z`*U!5Ew#UKp26sHy4m+4llW3*%?k zlkW3_>EO6Am`09Pe~tMTK3h)>GI0gMs{nGbzPDBrk-jRZT(Es4O@UXy! zkvAW_S}?2oqHoFLEko;f%HDK2%Hyw|9-fXRJ>7j1OpSJ0jE&H^@mT41h+IydANR8^ zHCp>q2BX8~9#iK?{CwVe9%VL{{qx^$yWU&<*Ro3qJSLK9uUxdS6cRT(wla!|IM%^Bl&z;3DVGQDbPvo_Tr$@Q&w=gB>=R2vbWuGkeY)|v8YoZV4(H)PXcgxBfi+Wc+k6wR|X~E|^ zk~Jgx!2CXVzAfi;&qHfJGb_vJj#oV=?G@mdQ;(DLDth_dKb~9m3tiwdJ2rBxrAO!T zFg=)g57#-z@0Y(FmKUk@WV~L%oG4i=*6TWc%6y)0JwK|qQezGi2QxE18>(hZNdBUA zzxBKEoby{Wz<0=V%k$_|!zw)QD^m5Qd&q0YhXjw?Q_1&rZ0>Jf%O3j9!suo*Ho@}s zJ0A%~Z`*Iqi~U7mb$l-NOw!|G#=DH}c+_*$dQumE)57oKeVpIGijN*U#R)vUz6i<(#etE#vA>m$&ote6HN8k6ry-jagRrZ@nj(i}kXY6B7*0-&r?z zUFzySCeQo-%=G@9xm|tS@qq8^`(-Y7ectbDGUw;l_?XXg8)W&M(dd{%ZeOm^`@H2W z?)&(EZ}Z>zaoOKGSv@}XAC=S1chUQzb}p0u^sj#&f6M0n|0bWy=qy=J&spkvUu5-v z{kMM$|I4q-=~w5*QY>c%qo(w=xxUcV-=Q}2XvucCmi|LsmGl*&uk~c>BliYP^>vQ3kS3|8oNROJn zDl*kuBUem6WN#h4eA-H=b8Ska_;mW44v{fg!fRmhlgHAzktVpjExa)oPgHR|<$45n z$$;via=A66mqx0i@8~GZwVcuAbaTzD>r$W196pZ6UG|pMFO1Zn<>T>2Ys!3{Z*MX@ zuZ-AYD;T&QP29X9;T>hq zgUehzp25{JJFM>bXN+TG=8K*dd0ron>3GTGExS8M(2WLauTH&A?$;jlV2^|Qt;kG;ZP_R0Ect%ULz&@!X#KsxnVX*a zVr;j^QNKp?u|#imoa=k(;gJFDc{$TU7S^V_QvJ5O(@^Py>Cmb#rG=K~(&05m#rtia_fU+Gg9+__bl_dxAUF! zRAUU-#XfXQCa0U3YHuNrVHf8?)R6M~64{|J`U!G?%x)=J|4q)#`>7XQ$$9r|^fc||KMYePxYkB>W&i}Gsx`Lh)10`-0p8$9B1bZ zm%QnYM`iZU|J{BMd=h7W+Q)DIuAjYoGsDWUW}9SvTHRTWetF0KU}yO}v$Y&7m&>l| z=;jrg!S4U{%J{gP?rZYv)Vp1uei*fM7r9(*-NnB%r~4e)+jZzsaT{fIw=MI&jGi@l zxnJ&3lbpG&Ksx-Y#qe=KS*uZ@B?;KSN15Yfy(P%i*L{AjuG~xD`;dV;2?W-tM5+B+wiKH zJg(dNNjXG+jlPdU1H=P_cj4fAUIV)vMKAR{klFRi&UKQV40jjaWOdp?A0OdXeQb<5 z{vzWVwnHP8g?z1=xmvE8y}WL&iymOJpY_k$cSYWexqOa?ewXZ1@^+!WJZc24j+4(n zV0|xq%<;63i~O;`JpY9O##OM<$%dCw#ij?MPR;R``lS0>kMBHV7kSvZbGg}E7RL%^ zMLHI7ypVJ2Bg2MqqI}<8hL+2D6uJ6Kj4r3^jZwE8hBIcVNn9jjW0w9da$!3faOlJ^ zV|Ub@74PZ$>HY1)!=z8&#eE_xJBQ-&b&=2IY>!puX|-OTck^7}G5OTF8n-vj6<_ab zSoCnHr|WyZ$@;Lm_}d!!Th7 zSvZpotLd>x4;{v0W(ca2?|lBN;e9{Dc*UAjKf66Lr|OG|)*?fR-#_a$VPk(EoXfe%=rL~P_kuC1=byhNnbR-veK&*A z@pHv?`k2KWojQ7vZLSB;-x%-roYni~_t5dI9`z3DAw0+ZUd=P_==h~}7un*}jHqE` zpPst@a^H>HF+=|^&;4`l>-g=sFD5QdQtd1Gr6~(_s%Cdp73|XbI9Az z|J{BMd|D3wq}Sj6T|ayGUbuQanK!t2<<(^Npq%THGt;dh)wd!;>w!^gHcxzPYBn;? z)tJ@Oz0dwgF5ageFB@le_iq=uT`rc*)#_cc561gtX!Ua6-}jQwWouuT@6TF$zLmcn zXZT#b@p@cjblF-)*K41(bf4pU+=(KjRE~A<0nbY;8TR*Csz&x^j7YYP+U)w2`n4Qfi?T$~`^r7v}o z$vAwxCROg=lB_A+vw2ne(L3kTTZ`jlx=f_2Q(fu9S5A`m(w$zRpU?;AyCQ$wdDClS z)oItd$Ag{Uoa;&b_)u=lcc<4EPNX*%2GZV*&!wY>x2NrESEld3HpT5zX~(*!)5+et z^zEw?siBlCUHmk4hqt8CovYKUr(4qQ^-q#9vo`MQtldT5(U<9Y)RoTk*G1O4{`l+D zo$32m`qH~-_j=M_oAth9Y2PMv7Pet=yan%i3+%lwT_xkuK1mk_%R<{|*u(XOIc={& z2RA+z%$Ku4>^*cVtDCv*^{Jzh{52l8{&N~ng*lFDRzvu}hsav@Io(I7w}jtavZih} zO#a(^N3W~;Jd3$xbth{N(bwV2JWnlS`?qt|k&BFuZrxgu1yS&s%wBjQxNdvxhDUrn zv|jk6$ZGqjp49r$#i6p8%a-5f;cB&_vMu!cu$Oxa*I2eqUy)oa*U4!1W070TOm;rm z+-dz0vmLwQn%HuXtOZ!x+!&dq3vaG^xLJ!nSH?GM!(3|fWMsJpbXVt%3-7w#;35M? zkF@Nire`L#^=;OP$ls)ax!L4p}D^Y=>C{Z~vCoq8lBr*YzL?l1}1PCG# zL?jqNiWDhI6qVIMZgsnZ?P-tK9=mt!aoU;n+S9J`kMDjy&%sMxLTopCMy{<|300@g zjptsRd+t4-_xpaI?{hyM4eHl6lKVhk7e5EL?YUPCJkGx`j{C%% zl^L=i9VhA6aZX7M(Xm>w6h2_b3C?fGtM;NCric6_dG&fTrtv_x;@waOHWyM2v72#= zTB{i(j$NF?P~$!d7rMyLGJ1S2el~JD?Cj^BmzZbawqQwEUOhSY!ScQMd^z5ElHgY! z<9N&*BF6*%@3U~4{pbDM^sJo57qoZNW8`F_(c@XN7Bl7o7Q)Fv5 zuKQ*hs9KV$(OH|R8MSWId_+Hw5ssl9%O8j_)Fhs9eN^6_k1zci&cn#q{?E=a*dNq6 zg9&^b_9Hc$bA-=hu>Kjc`j#-p;IrV^b)K#8{!l~A{&&vB{pI&X)_1Y?bBuj|od0E< zzE>Xq(`{>`mytQ%yH~+~cp#cKQHO{wY;EdP3q3LMUzjK4IAb$jGqv(5H+A%V)n@NM&Rh?*sO8QTktsu+seE2|Z1kn8r>m70Y_8Wu zf7cPl2_Apy>2kTAEjj)stADPi{~|K}Wt{y#d;c$b-Ot+Xa{4Q;y^*fI`F6Vg?gzou zGOt>-+O=#hr@L0SR%f@SQZCo~Vh&37rsv+F-ma!CFT0kFWnDSlwao7}bLOMlmBF*_ z?Kr{5W$oL`-liV!BC}^k&)ap|vbfvub!Bw(U3`7@ea8)%`Q5J1`$fy`INfdd|6RE9 zdeoAd%lP~M;g4?Qy_m`PCx2ShkmjtH>`%|kUh03zoNmvfzsLWQvtMp-I!vCkUh?|= z_umgjm($0OpfkUAD!n#Kt?%j=(j|N_KYs5*`ssHrN2d8lSH{vo^3?4)`tJGRbd=sm zr|1!C#>w2k?sR>!ksRF3)OS9K|9d|^mbH;3F7$5l+TWQQN-fo8(TnNKXa_#{ zgK2jey)p;u(9&U(gVk_6yg|+A#fie-;`Z##G)KLtUYFS;jnP+WrneejOFcD@HNhQn zlXZ=op1&t_ThB4k8+4x0^)<^|dMeEHi}M}lrRe>^ZJFuStvoM|pmX=sug8DBE7fgz zE;M#^_RQ;E9wTSQ>+V1E$WI=wpnns2eVoriCuW@)eFBe*+bl9$;D64=vidaMQT1H? z$<9@q+ZLH>^9=9pp`XHDaZcyD9+9l8yZsAC_XIP^E$WM|x38dfYTL6n-iQ5*)YUSl zTRUm(pM4x*AdASHn|>HREQO^KR5$p*J;eV}6-) zv2}E6*Rpx8EA{%`O^?Imc+&Yl)vPDl@g2crYVziEhWDN^#W=pB8=O8?51+lvT*7m~ z8uGflVphvESU( zO-6P+WOjS@%6rVnFX01*QRE`IR1Nv!5q#0qK-S_7(K8aYm((Y^|E3SXE@cJZ>g~^* zeuTPQvl26_%ifv8T^IbQU%BX;C~a8!@0jOU6x`de@u760<=M1)>2Kn5k^LX0 zeiaWgUUa=Jd&`zY9;Cep&h}9AxNRxN4|TYV|72n3%k)k3l8>an`g}iiHh7tQ&qdA( z-xH4k@&V1#mYb~=buP%Ug!KWAS)Ai>&cS`6PsAJ)y2BtZ$osIaaWMAB3z5a* zaW7xn56ha;R&;&!^hx~Jdg>jY%5Soq{W5($_l^6-&)(V)Gant_dYfYn#~1bqI=q*$ z8Z52%t2kb%b7v0B+~GpbDcOqZsN;#kzr0I3;K1-4zz8w06E=y6?;7l zku#)cOm>#howra&S8q{A_qRk}y>l)82I<8z3&xsbvx?mRh4-A}h3zzzJskP=Eik+} zS8{kWb)@z@HM3Dp*P|})>vt)%bo(8tmlwH^9s~YHxQ}s>+4a1*&RH#Tvf~F?+{b3`O1@vejf?Ni z$I0t1KF_g5*3*4_9tZp?obK!Cch9|!zW>7?C;J=aKBVgE=DwKAXgz7JDb)v4%IkVy zviC(+*Qc(g{_~&Tnx!tUXFhi=o9lT|Pro!flCGW^O(#bVMLy%~P7z?W(h9Ag`u^+3Qx}^0Tc^4?7op$m;@rA-Q}}4q$#<-KCVl(T zFrFID(=BlI;d*rUM)DT-h4q9fc!zVEbI)5|eh5xPQ%6tN|00L0ox9HcO67EyzNWIc-3$`@ z8hLK?Tq!??--Yd{lSNhtuQTSteNl@T-UYav=UGQ)hFV_KzGZZ|OizPr{m8|+_f|dq z(oj{ff_kVrr~GDb*XCWE=U`PA-;1?kYUyTVWZ#PU3C`i_*|zR(7CpWnrm<#q5by3Q z@Q}K*kCAzNp1FH6xZd{2<>Q04q3dkp0Yd z-?e%%%!2m=HgTW(xykF7M=CitJ_iFAy=Bx5Wg4?CW&Ig+L0>z2YASp4tPKJq!LR^5}TnETKpq-MEqE8kW4N54x^du+`Ec|5$1IokRd+ILd- z$Ne36HHtCShUj6u{pEXu#od=DIyb>j&)_|IEI7KEOcy^3dD-o%sk<+%NpL(G`-1mw zW{s>r%(3kJh`mAUH$EI$jPh>5+;~Osj5z)}(Yie53)JpM_b!WEbv1Jt)J!F7I`qDW zpNjX@jb=W;=bURy^q%=0aE?eFU0uB3;o^Jh_*7QT^Ga$4ekWYivi%-gqfyk87r!%Z z!`q!>(sN(4VR8J17nzF1Z<@!hV@$Kut+8-?dV$`h2dNE@eEyjC<2~^DGx*-ka_p$0 zh9|U!`S&*eTjCs*{`6PqZDei1rT&d+$BTDGeozOWtNnuXNgc&I-cAjv-td}rX7W2H zLR~jLG3QV0W#!!8K|Wu3+VPORww!}fM|aF`u8OxiX7f31Xz%ta^|-Lc!RI;Vl*#=Z zhNwe!OyD+Mo9nW71LNiJq&pU%hK1*tzo>ri5?PEK+r@P~@mvmWpZBZt`{M6~I(zo5 zyZ-#|lY8J!82i(B%qL&@vv-SnxH%?oz4u{y?b=(xxw5Rj6EhX%^XyAe%l1C`S2out z&YnZaf2ykyq)e&0iWTpkCgn`h69 zobI+<93%K#m#n$_++W1#zvy<~lkY_@zT+8v>L35!kAl_J)y-+t|Du*|ucP4fKQC%b zGpoz%rJVlPfBSbgIK8y*ku{|Yb#>X?MOJq`eYAt#N0aH}>u1xYsh;q@ymw(JvKO!7 zZ>ibxV%o9(`Sd2)F82EAz=OMIBXxHD)sextWyRy^yB7|p$L{}f+OqQTwCbsQ({S6) z$bmUR9p~Ye>h!_IW5NB`&Y1hyPp_f2^ussC(4e=cE61CnF7#k+S=63R^zBFg-kV-t z_5eQhR#JRo&(jW^lYn{ zX5IA=y-2;!bLK2HjB>h~d+6&hxEj3M2wtCOb}!5AQ}|xwbbI!wc^z&*3x&nXi_tR9}DUnM%UxfEt%$Uos9MrT#yjUK45q`fos?^-|D4wLwp$Vz7) zkGB>*gZki3eKY!B^lQtZ_V;#Cmz7b~pwwdZqrWm(5g8$RQ=)bg-;4KGu751*i)Cc< z?kB0?l#%rzo$g_u`9HDkc05^!d5oNXX{0W=dFEgl`gx(7s=2D6nx*dX9iQ#Ihvw`+ zRk}R9JNQ|ql0$>7(D%)wo;|cJ^huxN;`q_yp;%xi_p_|SzSgs#&$VLtJ@htzG_<}R zG&Wyb|GRpj;~)7pJhm{0yy*T>Pn6T$*Yc&jcodEcy&UeA)vYUy>s&5!B)zTh$9Q{Q ze5`qX*%y_^c6!&n&G#xNs=Hb<>KM)1J;xK{`|-JuKdom#ZaGknM*%;#o*4byUY?~# zrGB16j5*Yb)wcbg^pxl=AEM7=*>m^d=O%M}H8qIKzmd$~7^}nEvf`_$XU79+h`he( zeNR$9`L$I3{MXX@WnYfD2Yu%;hQWU+gW>1yXM}s^N)LpGP&2`I#hKuft9xs!-xc|+qoaDJ4*Va|kZFnU7 z8T;{>o44-!a*nR8g88&~O=~dNMuk4B2hsr9f8{TI6YcdWye`&+6m`F{xZ?>I$AIBk zbI!ws`5M2+){Yjsc&^JR7&+#V=8st~%jxO`h1L$g^E=UMT{yoD9^;wk{hbOgIt<>% z_+sxC*p_iX%q#NUpTVo*_{VyGd#9Npdxb16^JkjL+jaXM_cJ}#=In^~Xip2r2l+Q7 zGrRh}M}I3_AKSyY>q)$F>-lWRUa4FPPd^yPNzIxE!oP2Z zt9rHhU-q$TVctWgS4Yn^rP=Qyr@N?M>q~cD#r(u$)Il^dKjZlA1nH#^!@v}#U zzx+S`G#LC&w(-l~$^ZW!Ay=!3zwy?)!P#=NOe;gL*sv}9DI3f8+~`G=>nZiVoO$Kd z(BjpY?RDgK^qS~N@9G~6epho>WA`?hT}@h!maEmj)!nU0&HY5>ZWp<@l$jkPl-?$5 z`#3fGteu=!vuvFZ*Qr-8Yz5p%&G8((~l7+uw94`;ONo`eY$&}enZEGuIi~4kS zgbW(^TpfL?Z!bA7`y>Blm@Jr!V=d{@@s@Ocq$#~IPS4cQis;Yc+^)V4SxUxHSB<`v zobTj6wQkRk`Ml@a^UoX{r$<_z&Y3JeRyH&DtPiiJ=dody;Pv2rH1>H`*H07oal0C9 zY)4(agwbVd&!sMfZeC=)sHGQmfkm$x=K`WfNr``5HY?@y?0a#pdz!2gdkT7<@f;#| zIabK$SJ!HBXZm;J5m!rJ#XSDgtXGDn+=r$d90&vD%X*uwsghsxrpuXXi*mVnF4mLE zRFTJkek{*S&<|!m-k0O_v<%H1kB3>>jv34_)K4HQ$=x0+dSth}^dNIO)S|L)+;8@3 zQZL-M{rS+it#v$ka1Gimni%5+Gj#mC3az{t|EPtVKdL zZL0h%!&%R2hP0Zd<15FkeLTm<>VfhzmVF%G=o>iMOKv-_GeN$MJ=O=RAD`C*J044p_4Ie-{-(wA&1oz+c$zHBWAtb5+Wuf_+;AUUPF6afai0Ge zCW}yg*%XsAb6?uM`oVa7E90Jqjf>LRE^3SM&`dThOWR-gYI^>` zUrQs^58?lLfX6?8KZu@`jG@&n9ao0;c-|j1#@KJFeSOl0ELZ7$F*8S>joC7OUe0&; z`Kq0tAmc|Lv$dsqWqj{5@jvOchr1as1)rmxtD}3YM*k`J-?hgYCXwlkglpFBU!7+1z_W!!4U zlRCSc?(g0yJb4~xb(_$c_ZGipbNJ<&?U^;t;(n*j9;ssdN-YBayPQ89S?zw$ipAfN z?4^0@ctv_+i2lvwP@08fJ%jTuGt9SGt0_zCdy~yYMr|`L+etQnS6UP2D z9&`Iw|7_i=F0MwLwQ$*2y$19wwWfo|r*7Qlb23-^`o4}_o_#WUWn4;G-S?vo?;`VOyQCc|2b(^{MCoU2l(L8vByU>9V<8?xN?#8d7UYZ{hTx(VLXp)zfds>3Y;lIelUF z%R*My2Q$!7pWZ%yJk3q^r|-T#o7(Dkgm?VnBsH}4+wj0lrgtwKPaj?!CfB72hF*rY zj#vF`PkQHMM|x+5-ccLLY`kzZefuI_a(b0sKGC15w!-@`y8iZVdYtaxgSV2tpjRi` z(4^OWykkp|`N8?h*HQPsIJhTtSsAQgSXpcvUd`u&p=IFEPGNL4 zZu!{TJZE`M3r6(0`8>(m%b~f?bGq};>gm2_cwS(0nOd)gjBc+Sm!d9|^R#+8=Wgf3 z?KR?KJkMKKDzmG@g;yP(&5Z6^=68w z_Ga-H=^OBTr|xWa!z49$dU>7qkiC76di>7~RFE%8-77gQGceP+ZrBJes$I{ynDe&m zow-7-TV^mjT1{0h)7Kzp`Tq~9L(YFTuBY%RnGr9;sP7ky&c5aKdtn!SPq|J(Jzw_G z+iu2-p7lw5183=3a{{08flUvln$`ElzR>4lU7`OmssSy3O7{(Sw(<}x0cudCHB zWVVi+9{v~DS^k#qg1tF*W%Jyd$je1mOL4o$cJ|1qnHNm&G2*eaCdL!`W*k>I598;W zGhpQ2Gl%d{p-CPl6MTlAG1Y4yOwHv*uD7+5W-<=J!}eBpjvzA8`M=abWh%AJw(a^$ zmd0o3xNm|S^|5_qucK==Z)WU8?cUg4mWE|y5`Gaa{i{(kYTjPq8+Ysn|FG{oh8*WP z)-fM)=gZ%W*HJ6CHe6 zeJ+k|9d8vq0r(vGy!^iUz4be69ZJ-V!{HiSm2O@tKdke9U^?%cF5W z^~;PS?UQVew)_~!pDt<Rlox~SYu?Bw`nnTv%voGH7 zU--#5-u1I=VGPn$&GCs(zVvs*-!p&LE{)Ke4lY00z9Jpicu)A9`l`t7T)il=f6QEQ zu0c=AICa*2@VP##maSy;!qP2dp3B{Gy4>q;O(~;0z8!$EqfUV_;`o7=@sW|G4sQ?E z^f0p`G=XR_W)xV`T?kF{;k+(nZYq74_W3eBEV5W)pJd0&Qn)UzrpE0FFfj5OV8eygOw_dK88nW_sG-?HMdB$t2h z@?h|-HG_@YUyAGzwVv|T^n{@w>M8s%Z_m>6bk$;*pLuh<=*JILC$nIN=|ei+T^+vk zp^nOQdgwrSUMA7lPYt52Qbl!K|2Cw_LthwLN*<;*5pDEt6eKBQ} zF7gb_K(61kjQ4eOzS{HbnLhaU@Q&aP`w@;t&y#1!c6f5074=o<1K_=(naexYa#_PE zyJQX6dc*Lu!#irP<~6D%s*~$SFKWcB6DxFO&yC@SX1mTUH{l;P^FhzB&o!ew{QI2$ z&mP$mS?8|~kaxkkc)STcY|rBK#C`uhvO=54uhExO>J5nT2VU8Z%9o=*lb@MhnATn7 zsiD(np2-ZPH$fkW$A$i*Q;c!!hgERPty;Q#Bm2nI>d&*xvDd7*pZCO=Vf#b8KQ#HR z`a<~M`G49N`_ye*61{)y#i`#%h7H{uCYRgYS23pHe|Nuzp3Z&`A500W2dB&GEP6fE z(6f$S)VtCLwTA4=(9+S*VRskjvh)<0zwhOIyPWUmZVl;N*NXJw!(X7c(7lm8c)FAC z3Yy}n&fUC<}fqv__lGi?luC9+k_A`HS&#Fc7 z`S^P7!`SEWx*3T%lNBzw#HB@5T1CWCF-16WP^z;@>5(C_naiQ0pUo|iYq>iB%Am)`$WTE6%T=;mg+ zEKZec=_kZ|RvU9H?khF#@kYjXyU3p^Ba>-!QPbH-y{CG5QQKjSI-0k~8jCe6j>qR&&kVkBUCQbCvd?v_;#`8>7xnb- z{ose8r|V14wWBh+EPe~8<9*4Tp6|~-^_$y9N$0FL55>>=x^p}Y+L>i&v_<&bfFth0U23Ut5W?| zek=FWX9iEpwpGj08FJdMP903W^cR)8>UjM7XAi|WV>kVe-hjPl`uC>kzIv91G}&7h znz}w1+5GT6bk_a`yf95spE@^C9a$5D{GRGNJ&cZI{hZl+a&FNZbY1j6(!U!Tv|bbz zFRS6|PtLV>_BNDf?BQbOg*u=0l_Ri(=W5wsw!ERK%j2Be@_Ey9pB(RecIfr^)YZ_` z%jNC74ozJjI`iN%d?~wUewW*CJWh^RW9RYKVD>lQg+Mb__rEmExJJ)7o&$4J%u+6V zH#b@R+z~u4j6XbgdoDkUr@(&i=FiE9p{2uva(X}K@^Q|UvW)e2aewRsc#`|nLG^a% zAF&UTH39Y-irO)BOBr46Qon52M9&-et77#d@H07XXza3)`%=!a)-C)%j3v$u?12%s zksGr#4c9G8v*blspZ3@{e?9&`pObmo{q3TkUB8TDt{%ovjqaOrr9&(6n2yWVFwPY<GP+llicyr-D&&F_o1OL3$KSgX3Q~Z zMm+X zW&G{4pKaS7_RT(ihd8!xEc3jcHFkSaTp8S!US9I$^wN^A@_Xal+|9ap^IqNPxthB^^xi76sH&MuL0fO!^l0eg z`T#xt+Bsf4{=(aWW^Rs=b6>&UdeB+Sypqr5^vF=>I6RE!Pfpk4l5aD^)Y?{m+dluh zbq{=+41Oouy7kpRd)M@yTPLc=CD)CrqnowjT257imW^dyHD$S84wu)};$39%QY}6A z0?mGw%;fTJW?r|KIo;RD_qooxcV1`i_Il~!V;yT`Ciig*c|J3|>wN!0HZQ%N**vek z&*%EO{@?n2vhT$jQuTCM-Mp95oEN<>dCA8%rOaXzapdjh|CdwTPDby~fw@SAipPr7@< zQ`Cw!Mn9zJF}~@UG|^L+E*@`7*G`ZXgKy=+SSuNeZRz!yPS#}eZ+EM@;k**jR7o_ot5|61{X!oF(Nj!7o*K$z>O_r-lRjJB)ZTek& z{OFgc$9oH(pZYTOc4mQ7--n(ZIW>&OWRg*Q>1JKq3$ha(Q;)Ge zVRc1$$FYb$Cbwmcp#A_e676}@OiikumZr^1V(!85ubzh~_Nz4wZhMsPoBOz7lNmYB z!NK^8^-?kBaZYQD@1|La=J$`GgZuqF)%rYrhQ1bct{%(2hVwM);r{RLQ+vaXc${*- zTxZ`?kEf_H#jj!=sre$#N9oJfpXKxQ5BYs{zQSDk$X6!|C+eQpJQ%+P_O$h}k(Y`$ z&hMn(>!|DHy7O3zb3#jJ zOo?&4*AFZxZ?(_Lp)^|HJwTf3;6%jfFwE^@ja z7qxO(ej%5aGI;4_Io>6EU-DY^&J3;w?qxYSbHA6pEnhFy)P1hkGp}bh&+Aeqzuo2h zKj*cN@v^M$|E#92FaP~-f0Tamhd)h!@YDYo-gN!x<}=FbnaeY$yY{x6{i5csrmmiz zIX!2n>w8(~eYu@S{q2i0=`B3!*UpX8KWHS49%@JfWVKvBdz7ri(e&P#u5@{{KKc%I z)vZhKo$gG{6=Xut?`P+R7wG-jl6uHoF^gsQmR0FTZ_lRs9ptlIItu3>P4Az^Bee0c zv~9(bbYWlz-t+@e!)YDk(+_R21n#f?6iPcMG$?A3R2DN8;OZ5kscTn`vE;7vZi_9FNrzM$kYJ2)z24NgEx$sx> zn{QTt`D^v$wDrR%_SV?9m0G5Hm=zw3EaRwEyg7d?qZjkTjtLwO@c+S}H+|{wHRtnS zao6F$D10r2N4@Z)dwX8;ynwuKA8@bB1p3~i=Lt-5p>H!@?sd^q<>jS!1;guSEyfZ> z4<@yDd!CHKFEY3O^sH+Ra@|Encd_b>N{aVJs+Nrt=lsPPtMmzp})p?5Pjh0$(zf(^JV&iuU{Nqay3!eaRd(i z1gFE)Id@0CK7s!2+=25ca*+LK)erOYeC)ZSH5?mcg6x3<=RGg-P}VPRa5`GOy;2SKYxxUHig)b?X8*R4Kvp$N}>+|gyrB}L_x(pfL#rF`;VY~L0UGwB! zk%Q@6h?zeg>-Mmp>spT1iJy2M{(XGs#XNtZ8_Mg$u(b0A2ViMEGJ0aH8?YB^E82I= z!Qgw5k<{Gv1Ur|af1#6co!fA1XT8G&^EmcWGH0(H?bXMc(H9xljGr7A=n*nQvhebw zZF9`(!Sc9serAA74zugczBHT0>>kJ0p{2V&V~oOg1V+~9V*P+jSh3>1becL2{V(p9 z=*Zk4vCeO#U&$+S8Yw3FZ)K)@Qhu>xP;CAl6Hc_8eEd6ryWl-nvw?j_1Cf0h8 znXb*LWy{0(#FwSh9WSSvHTQ9BeVxy__`X~J?YxM-|D*J_>e%)`GLzF@L*}%|%=SBQ zEGLu8#(j+W{Qb~B<97T!tOtlbQ!DRH{gupl?Be*VWIlysww=%3yd^ojAALfPc^ALg zW-M=e4YzFS}mI;HA9o zefj>p&iDIT?xWlnN=CoY3{zZ|M-dg z^xJa!Ki}$o`QG*O>B972IycduUOzpY_U_(H{V1%xow@C!)?_xp$gSxEJTH20x38in zA)0bq)#~&ix9xRq9UX2GVBo8h?E47(SPS>6N1uktblysCmY+*V~iz z;eYft^S7T`L{1l)?%dI;)U*w~1Rj6;OfNo`y{W&MJP)<;(A8V;t{h4`*DgzQLwjSn zHi$(yagoiF;g}=X*6AGfV8b;XJB3y6jQ6VR0;-mDB~o zLDpA=SDJI1{%_BjSx49ZZch3q^IgnWWL!XhlOhAcymj?D#|{OTd%jnP)AQnE)#J=7 z^nBWDt~cj)AM0GUOrZC{te(QFvo^R{9cy1XdMEP*<~`&&YqfQ~rH%*mx16IUvU1JC zg*SyUO0YV*teU#H*s_xQM?F$zH|s>dwPP9Qs;vn%KhK^=YM%09p|Rtez=vS=o~*5I zE-QJg=v`2Iwa!%D8m5P!{VVkiob8i~cfnNX*Yu`W7nZrLAFzhhtZjRm51DP=S!CL) ztD9plf4iKd-rzjPo%^T*-_;G>o%_7(V=fHU#rCb`ljR2w;2q)f%lsqT6uFRONYiKi zJo^62i+_V2_q7_aLGk?Lv#g|Ku!M}d4=9jd4Bdgjdd^MJ$YU| zJ^a)hGro8IXG0uIdK6^*`i+ZYjOQ_^j_&-Ko_x95|2fxys)d{1qIW%Xcg6{h9o*OY z*Bwh9hrz8`^fhBHj(zBNuoyct#{~o1ht+ynYnl)8+t>Ck*#i~`PH%7 z$jzxKW8C6zQz@TwId3b!PG-op~xO0c}#XS>qjMmmVcVKTaIo?RYSC?@$ZJOHS>wW2?wa#0wKOpBzW#>3jS* zKjXZN-0m?FJxICVx?k%O%#gAE!EKD}#j}pi9*mBTZe6n(>Uw27F6H)EN4;pS4VBGb zjAKYH4=o)IFUFDFH_zq8y3o-}J?Xwbnckibpa0#u2kwNeKh4M7`s$y(Yta)FPB%|Q z*495R1M5FGYf)a#o^n}PmY0QH%hPxq;S(d*4=1Fw$j;QUtI&mPpx~F=| zIgc(y!+Ht^+?+0rHl#gk7t@cXCh}hVjnzl;%8~L^weiVxZMqrF98H`0&?!7Dvbv1! zc3+=vr}lJRdTo3^wXA#6rLm$nYFp*1$Vs0%To;d*%k{rp<~jOh&JG`d+3~)>=%-mG z5ADXwP#JmK)|8&_LCb1-mYT}11~Z-P*~V}D1JNseBYDqxF52FV{V+t4QL-{>0QGd} zne{v#eK}!G&l#SVXS+70U90Hxxdq<<=hY$yq0rLxUg(p)k?(@9W&&1M<5yP?7U#V0 zytsP0Ebe(c`(5;~xOmQ&F@22soW2;fcXe@n9BSldAL~6;J3lu9`&~uoGz;$Gk*;aj5(91V92>{^heHNa!&SO$mlcV-bGItm{Om*{Wq;UHSa** zfh;EPw3Ef5_IMI)O+T(a1HBY7tA2Usv-g&f#RhYk@u3bs$TsEmA@s{(SkAGKUI%Ob zE)VU5b>TgD%Q<=3$A0OvJYI&)q!x5y{z>BX1}_J>POc5h7`^dp~YLL=Uc7Ff-`;Jsxgb8Q|> z{bn>f{0%a?pNYL(WpvrzG0&d0OF|=;AN9AWudC_DXN`6~>}Srp=x0>0x;(CS?)sL6 z&q?;SUeO$I=Ykw7sVD1K_j4<94H@GxW^&F$5015->Vs4CAw6|)RXW+hdx4jy_CJ$m znwFrc)A#;`Zv>mm=WFED){K4t^Uevzzlsl*4 z|JO@Ci~G)F+3|@CZT+U>ANRG7vDVb%-Q(136vv}xF`5bKe)4p%^`GW_>Z3Em z$YZbcILu7FaBXj8dpx+kq85hV0k-FSR0Fx`{$4pwABpdKiH<(c>80!*ugP-@-%G*q z`8~XQqLKNzMZw(GvglRo!1rg4ka?eu!L3P{KJYX-_xjGw0D6Lb^9;YWW$A3kOX-;h zem%8qS(K_)d@UHg4=ucn-bZ>{TDOt=iT14*#ad41TdaHWxbyS(xO04{_HF$_^p?Ws z(z$a<=;`X}Zo{#j$6JxB$b1N#9(n9L$?xIVHV;T$J-D2Gg~n#`C~us)Bjb}kUA&$Ij4V;i$6^Uzmsi!@*RA(ZrQY>Dm*VTuDqKyYB^L+w`Nj5 zw!M(NU-p)L^@Gdm*<<2mZ_8SE=I_kpKF`bf_PoxIckOLiU-x=ubZ>KUEZ}W2eb&+S z!8<p?$%lJS?IyFYV`9xp(-s=--;&4-XWpsaP z*ts_RFRis((|0b7q<2nr1v6hdejrWt)TFEUQqGTcr9XV{G+B(Zk*oOnbX&nn=+H9b z2d7%l3d@3(pMCW1bO`UtyZC3EcfN4A3N=*7=|9-OO(|J?p4v+Jkmn_WT2|_9Nk6QQPz!Z~mGLq_^1l za`PFi$LfF?Jr{d^uUh|D_)zVkqem#`B@{KJoaaJQ_k0IWbH3J-BEQM$p0A6g;B-Ca zF;9+X#@h#AarHLyz13zrD)k}J%Mk6q1)sI&@Vxjs>iD^jy*&s|lQnIIp}BZwP3!j# zmgjwBJzYk32~Q4s{~UcrCtJy`VE*58Yf;m9)1NM{yT~tQH0oED$2^b9=}`m9zLAO4 zbgg47{J`si5j|I%VXcqTZ0d`6q#WA~qqB|k`Lu5Z}yUlO0*Wz*5JTJ2Po6`r_hxUqL-#b=&>utuY9(-ZJsS!li13p>8@7}KjFTgmBa=GH#?e6`Bh|MK@dkIUrlU-z|Zk5?Jp z`_<{A)|s(@`?hH-+9WLMv0!f?FFRJ4pvR|7Wc{ps;`LE->!zDuNZX$NjkM+IFHvLq zjqoq&&-Jr*tm^0Ag)hY%b-hkrx2{f~liw{LE06nl=cc016>}x#<7}edv~mr7`cs-?f3X4_WKGwPecZ}y|vhqp%7jCy7L=GK|U^NKN|$L;Qw55)J?@2AJ0 z^9a^zx=%c2^`Dy^8h-T#d@zi4oVRcs?EH+rcaKfyh^G7=aJ)L!ImGzQ&%vCkV!n#G z5#~tL)Aisu2A!rJ+Bqis3E5}&2=i9@;5-iUSonzZZLqohvVws{qQtj%yQ^WfE z$a{G(Sp5K5GLFyN_)XbI%|gu8z|kH*@%sV?TjyXFOz<+k7W+%-H@61HnxO+*Wc{Kq zRX6qX-ma&{aiferNe#1gqxL8DJ%u-2uM2FRGhK$}#{k~u_ag3NylJhd_sR9X54Y+3 zpZ8nm?0a$?@%i7ad*Dvk`qO;Ot*`#syJn_~*^BDc`Z?67WpaCy+RH~yH-FI_#?0yR zuZ!#~o6ET}aH)Qt`P}>SeR6c>^UULUop1LsF8OvZXTHzuuAZLxTz1clo*(BrYxkMW z7p@nwdG@;Gb-q7e&w9K6kNZkb(6zVUi@v1hzL?J_ck4fw)AKq!>wgNb&o2vkU4MG1 z?D}|Ac);t^5o$w!aQ$S|V1D?@ z5c+lloZS<1uifOLzd75LdiRq@cW^Ix>tx7G;t5*!ILt^^E_(a*siyS&qiEH5W4=um z`<1bJ^p&#o?sNmaKkiA-Exs$gMh=X1fghY~O3yudSIos9J6J*9qJHzn$Z>h|1e*Fx zM?B8lb+fds*?Mv5H&es*m&sjhPZx&iMQZ*FY<`mGjp2W>C+XbqzF_o=!?jTtdA^?v zc79V&k)!PI=>T)wYH|8m<$`H4ueXsaexk#Ck`1u>V$QM5r@~6sU+E#W2CJz3qCOK% zQje-R)#{(JnSDcBE6A0B@zk;69Lc#cYw4lu!sqH~QLD| znw~D`^KM55S2xf3g9Ve5p{zCrqpO>#t*bLft|WS#=S=f2I#~2-%3$^uvNvjQ1CNjT zS=O1;&1kfiQ2wqjGwXsmW;iAI5KeKepTgS1DKZJw#PyYXescfnL5!%tw)t-1p{TxNof$Q1iV+?&5eOdCKT)tKqcM9m`Ys%Zp+kch;a2qnFF#a(G`8 znkLNNjlSMcPCobi?cV3|-ifBrvCWk8aiwftdO0(?x9O9Sqax>p&o4hN)_exCia9c7 zr(Yi0&D=fuaqZ%?M2socAPpx4&DL0J5giEaT6JNjK4e{oX?QO z)!nV{l?j8r*^hcQihLG*E%Tg?PsRJ?@$PE4L7kZU^j?SGi2FU(C((M%*>J94l4Bxj zADP!E>IznpdATJrX`ItgED!u4axY_Gr)-RrpQ{HrH2jW1a@KmeZZ5ajwcN8OJvI+On3NdHG*j`}^Z@@Asw9 z!x;nMiLqywzgb&fewfST@XR06nZ@&Kr<*WTv)RDZZOjt0V(Bgc*&m9Zu?app+6$`{2PP55Fes3jn$rJGt%b2ZKF z8OGb9R-lhgMtA-uFLJWSpmoN62kX{97#TwQ$`++2^!T>&N289^`ew6=te+@y(8>OZ z92qi$)a&uh^e}IzX74uj(5ad0iILg$I_5kVeK6K4sNqL0700$Zy|oRQ<^6rt`||nU zt$X0pWbixL)~&Dp*}JCSMFy39^>mmIu73XZ``-#qKmY30WN#mJb{Rfv-0In-KA6nq zS#NinZaedFX86*_Wvl=h|F)bM9Cg>26BzU7SdJwo;=ve28rI!E|ZnNSYmL zOW(abntt*Y{&RHjw@#6Te!MwdJk}iEa6Kf~XAh?GbuYm4r_$xg&U9s*44CDQN1xJf zT^dbS=yCMc>0bQh2h-J&3Varig$}A`#U7nf!(Xq zYg6rbxcXD{bgPHU&dx_4)r$gC=Xve$nQ~5+d*yP^&4re(uI2d>mS&koCskL~ zD=ZhtgQ_U!Q$v`H#9ML(Q~cYF|K9y;CA0jXtwj`;(1ng{vg+#p3pB!515nm zI`}6GEwk)#KTk$H%nCAKDBe6zcnqEg24lR#N^%m-N)iI0l7-KSy z5t-WKD!jtXQOUIW#;pY&$BS+qf_@kEahW}{(m3xy-mzv>e@gUv;(zk^aa<9e7PM1y z%+0?Z#&2By;y0)hvG)*Jcyju@4)3w&|L*Y_-f-qCWOVmco@;PF%HGyzsQWrj?5SZa zz_F|kT~EIKOVz}C@K!l?3g15a*!}D{Rd0H(JMjA)pQ+y;j$J=v7i&{OFAp|HFE7!` z{Vgcwy!2AtWb~W&MrpW`4OIar4d1Af4?hqo(tTv}eUPQWyCv zgY}Hts0lWMWvK4SbbRm9)VTKRsd>`_k*8=K=?rr>_Q7hU-_c%bk=4BIb>z5EKG$2~ zqBo_ehfo{mIHH%R96m@NqsEO7CUY5E>3M2zBePNUP+3PLQ+rJ7lXu(pGLq8^&gPhc z!;4I+B2PW)Nf`^s=`Owx@6YuZj!hklI_`6EJB}U9Z2bK1<{r2cuKu(ibMw_do0sHS zvs`3uGhC)losCR%wPN*jed;-HaeVencuahpT(7Pyv*xvzWo4OnNA=$5kL0#}4Ov-6 z_Ay>pm-f2+ER(wpxjXCQnc1_R?ql=fHZr&8+uY_tPWQTx%WR+DL)Q2+o0qOj**sr% z?PD^hyIsdA_Iq+XV@9L-jB4t7&t0sJ(qTuy+}R`^>7V4(vROcooctCPm^!{%1}*u?__i6qt;|y8LdnkUwDvA z_KxsXyh*0IJwZL6zR%-cJyuT-QhKe}OY~R^`glX+rB~u(e|@|uUB|;vN1nAlfOEZD z(%Pr)CNq-0N#_ot+3!V5ucX$rF&N!En7KiGGJVuywY`vLYVS_{+rF5V-u1tv=N|aC zZ zKELTl(Q7K7n~&^$dK;z=G8W+6uMgJe%4yy%vvrc=Xuh{|%kp?Wr)NI*TpxLD`wRZl z->QBlJDTm_dET*x;~BMCJq+g3nPVpJY#`%V4)^`&&yXdfzSTAF^R-bqotoI-L!JXW z>79_vIJ$K7dI)&-xA2I%OnvL7Ad6h;@bWfL z7i?Y}jCitpb2@vFY<1?X)o0cI%`rc+Z*v-e)19l&Y+lOInbY%quIC1-$RAo7?BxHa z2g?3N9>=B6U3hs^wz@5+>m{HEX-@^m3~O@X%bxvu+J!G;$I3;_v7pt$;rSSFzq)iq zrameXl=v+_Ko!$2VrwI6y+V8ME-^|-_KdRlEsnXB zGyQnQ@I2K~GqLdg{J4K6={W|IjsNXQB zvxC~uQEJ0S>&aWGB-?itW7`UHpvY?3i(h4|0nXlVKb-wg_*V2%IS*L)tju(!K9}Rp z#aw%tSY|c{y_;-w>rj2Jne2z?p;Wp0{>UgYpWVDr>uvPBcfjd|9*=j0Iv6iU-&2mQ z0lp_{<2O9&`dByyW%j~nQ*gT5QI8*ByzAq0-E^=%n)>H|H}}A&&ER*ky_>K8*}SCY zElbPF^0=IC|Dvnc-%hVyy%sF$?J}u(=|@J#)6ucX;PlMYna|zU_R9LmUbly7-gahO zvmU+8>zT7%`~1w(dF}1;u!{`7a4BWze4n@Zc-cKaw{)E!=em^5z3e`4S$MnG-EO`w zv%2rk`31)_a{Bjw_~XcDl*MIpeJ+{DfBGN)BpBXx=<4&#?qf5jM}GQkH1+IvDP3DX znwPgOOr~?=eQ4?9>Dp=P2X<^oW~*PAI24|dkatJYf`ueWd4>U42rZ)zbE()!VUvhy4_ zn3;Eh-tprHR-l9b4(C<8kzMjJQWmugphIX%DV z-!YG_rif36bF#ffg2DAgz;4bF>uHda^oLfPlZM_cPpNgPmFZ>hJRDw%cFvb@o9EBa zt=NW_v;QPCZy4J9G7GD-tEbDSvbY`obM}l8^gzhxnf>%- zJC^YM72K}I&i(M7b&}@3*+WHUwrg3AkkODUUsd8&Ii z-t_(SMPhDZ@ALFq-4*&|E1m`CL>y=N87}1W((BIq6yBxcGcNAK^MW_`2=%4@?NPf1jj#R;Ta3YL1>UfW1$#H|9RWZ*(y@KOHbo5xl_riP< zd79R}nImH6-=XTl*HUn@c_(;182|XWINuTM3lBSoZ_TzDMRJqcx;nC%iuPnT!$oe= zL*m#?ZqcVw)Ca@nFrv#0nMmr7YKSxV#B0{sU)0=_B8N_IxMMKq`44dWARYld3ZZku z=)N!YX|oos?VM_s(;q=2E$TtD-#BVn^}X<#ks}|TDLnl2N0p!Yg2`S;)~9w>JQ>HE z`@nuw{ubEdQqRu-o*$2QGdc@D4?gqI)UCILwb`y?0pFL`)!5DOR%>-X?_T{7`ib}5YGYt%`&sFG+5RFKKDE@9lF4|GWvG^U z5 zdpE`L&-?oP@8%x36R!TWA9M57Kbx2AXC#Zt$Li!}ndo(~j#U4P`HcG3)zZCh@c2}+ zj?!ArtbxnLa%^bmaJr1{b+?@t@AGmgORH;_YU66>Ss(vJe4bg`?UXM0_Plo6nbGrY zrPpuAt68_@^!%89=8 z-76Dm!^@8c(_Ww2m&%tfVm|#T^z`zy>Z$wF$U*v)jyI?KzxwNV+z+MkLzU^n)6}3+ zQ&f&OynF9PJn{R;e_`&pS*^O9jCHgc)}tNNEpcu*P4@5H;jQT+eJOV=zd!h4j$9J8 z_1$RedWNUE$@Dl<8yS4odYys)>~-O9_SWa_iry**w$po%KG}yj{~d0?!y#Y8e&&O` zh9{?uxn^tq+NcXP^RTG<ZGM@E)6Z@W_UJKod^W-RfCD%TEFRwSxio7?sd$O0$zKedD=$CqP zBl{YSRxVPnmCK8ozk=oTzu3!2PE=oY{Gr|aHa?iPbK0k6|99Pwq(OV?^Lq#vB zX|%cX)UDbZM{d)zp+>3>UPHgEBi8QvzcC(~?xC-ta~ZIB>5@6!+r0eNOf$6zn_+}S z%$?wCX1rlOcnkHW`kAah^)t_0zEC@#(xa|_-_MKvQ(A|r9(i@FE^2X${Y(~J+p0JQ zd-!~!rhu`U@7cxwPp|QT@~2@wY8aWTaSlTdjK`CU<2L;=YU#)EJWt|r)~|1EoIaD< z^$&B|Ie&8O;9hGeBCDBkjs1PBjrKFqbK-Iwu2(NLBSS7df#=Em%jWXOgQ*X0UmSIO zhwubPJ_ej_rlOyZe(xKcPEODiz5?rc$D25IHj&fGJV%keQPh4Gb0w>yKa#$J$YX)g z)yJKO2_{A}5C3k}Q>lS|0|#Iwud7e0r<--!V~r-qmpZ;{v-!Gg#g6x}08o&x_C7{>9A|dgO}l{OvUJU~)9^+p)2apF3KO zzEB?HcE<>g3;d1BkC(H5RW>huym>JGX4IC^Z+7#O@mp4U|Lrd4*UtC({m_>+*RwJ0 z+i*{M{N69bIMm~I=koiaZ>@Re<^!#L@~iw--^=*y;n2uEo*W-u=w6k2(b8KsF~;5e zK=dQ+-uWocxi>WN$mxfB)u;7~7dkb34lfVD=`9?~jxF_3$;oQ*buhl!>AiT|8_OPI zY=CZ0&m?tkdAyIlq>d5obJ|1Rka_CzwU^C;JcNHn?@AX89{M@F?U*3=oUy9oRlQqB z+v`-pl}-jidB&;M@jflr&k?{s@N-@#|^lI$tR%ISJJhQ_BuPoI1B zweVld?&`+!dG^2LI!;+#U0HUO!PU!if28btDc@6*FXiaW)_J|~ zzRb?~e%IbsdcE{=>GSh*e-W2wCeQc#`23uF+3mSs9Lrd1``z#TAXr@{m&fy>W_~+P z&sw|rjDP*Nf0zF2|NZyrAO4XX^?&-LPyH4x{hx1Y>1yg{j`yZF=yP=K+*ta-TW3gVv2N%+X z(S2#-i;tw$&n-@G%;IA|aU_+mell%c^+fvcY-iMnKKbxn>4nFs{c0*tuTSic{zi}9 z`z7@AXVK{!)5U)Hm%6g5b@Z)4dw*@RHO(BZW_-|`Rz1CldQd#)XyoRd1Z#1Qwr1!O zKJ~~8Ie?C{>*2I(#r@QRE=rXfpGqU`a3TGTPT_yiJF0Kkn#OK&>AK(?{pQ*4Jk-KD z76u&etYCh67rbot_}0i&(FYS;1zW3o%2)ESHHpKmavnaDu8QEv13Rr_Eb2HzBMl}m zwDepjW)_;B3HjX2KXvZ|JIHl}BWDiUOB9_ME&VVa7@6&K_omdyT!Vd*#5lukG;LiL z-kAMl!Ra5+k1qr30oRl7{DmC5=~=u2_gy)~mU_}QbijB%JN z;BqOeXGWhghZBE(3pwV??*ENAe>(SWFRJ!E=x7c2AY%T6{d5~|iyZEF>0JNr$e8i* zg_c=xz4trraLz!U^0oA?n88y#j^l~X!o~R%KM!+6^dG6W%U<@MDQXp*zo4#^c^~T& zodYpH#5_Q21I(_po=%Q%4quO~y)*UO3{z)dR=N4jJ6AF$Ww{jeISK>ur9HL)Gf4u#G)#YcX1rLuruPK-7D|hjK z3O<7XGGU z9x9K^Zqd`{kAuv&rMz2udEx#3USxfK27i_PjBoe&{Jj5>wY@0JOf`em41n8h!`EE+ zx{+bU`-`zNYk#L^J2$3^)r(_%<2;~sA^P7Rx%=1BrG9da%r(dBq~^Z)g?rQ0!SeL{ z!@r$Q;z>MMPJg(K_lFLCVAG;BzW;@&FK&Xf&Gs=7$2{ z-Y$Dv)#7KgKdF65+qRPn1a}vCE>A{AqsP9Qy1kCfGU~!BqhCkAx^qg7GxeD}x8mjA z(8#l{UU<{x^33*brwd<>^|7+KY;Wy^a{!g?uaQ|j`@=J%yUzM|DO-EFl&?$g zlb5}oxw-VdUv$}Rl|CnPcwYNH^JUlhdVURW%a`4b@7w+K>eV;H`|{DpKZyRMYUg>8 z*S##O%j^pmIo;l*fA?SiTl#N*PmcP}Z*qERO=)KJg>|H(nSTGni|L&UW9iCNXYg_hwVkiyjT!H*PFGJ2rr*0Zk?MAmZ8mr?YDj-@ zbvRh_+H@;=d1dO}w}WjC!t=wao|@0{wa=sc&m9qof!v1SR+-<_&A(T@-h&6%Tn(badOMQ<;3GS0!)@%7_%F0^oK5_iXIj>Fqi zXz{YTV*+arXX%S0n}>%OyJb$!pF#T+yq9NzE6A$#X+j&rwKt^BDL>t(s#?2vr! z^*nbH4c%PsxuZ4oNUbQ?5gwf-SKHn>&T|h_TlwlR;}i1T?a8UW#oMca! z4`a@HsmDU^i@qJb_4YTi7SXIdS)_uo%mnPcX34Lo?Js>Jm5~=O17uCz3{0OlO>JT1 z!r%|p6P$B9yu7!JzTU8ui#d9FgY{*og{wRHI(kNH0k>Fi^5B;XT6L4 zElbPF`bA`W{W8wG%uq+V`tdI@u6u#czVHjn==LR&|9zfg7Jc82HTA+|K6ZP)2k-ZB zj;qbqKN#BO)8T6>vc}0&VvHcC2UEwosArX}T^wiBF|V-wWj@D^kH&mc@ISsIbIYA8 zQ14WmH$%pGATzyV+`;zL&kLQNo>J}){PE+>%fnyYxCJd0zn0@jIem!FS1nyu_juJ? zr+)nE;4bRS3%{H?x18?r>2mXPmtl)>S{|>-z?pX!u5Wi=aa*ws=iWU2ZpYF8qqkXO zah6OczrXfYXxgsEaC^^te!t%D^TKN{r_YZ=_37DfdKX!k=H!?y>SF!PiEc7@VdLOw zk1u{RoZEA3roa0*eJr|mE+&Wd!T3Gut6Um>moeu0%usJ*jCvejlWZ&ts}=aXcIt}# zEpnXcZ%$B2gdP%UUkO{uJz;j-HSR@#?NXO&JB6&srBmt^E>+aU$F=NHTe5ZxA|HA3^GUS zPai}xcbPnSCLNnT8GaYN9eQ5$q|5QLxtWN0$(*hxF2`maU0pphZ)R%QR#x^oE?Gy< zT%DP`be-?}pIK)|r^E$uBU$!oNyqEL;;8?~C%lE(iQTo!r;8pZ@G;>1Y4vU!=eKo4-we^SA$3`p5tN-)~{{oYQzaPFF|&&TBJi>~M2% z`r+n1>CnDi>DsCOGMZAu z$hkWr2WC6on3?vKk>6!c7c*UEU{%@Ywc%aq?%(=fqvxIe#}^;_I_y*t{`WVh8lq>U zwTafkd7j=vc1$~YGP0lNwrTnx+3RTLFg^ItY)_zLw^gF4k-hG1`fet=tHRTxFMhhG zilq`AzA7|zJ(fW7)Bc?=rZ*=WLU&VF z4_4>-Gq9iMJUM-Ip7Uiwx4m}@`P0m~TQ4c|`To1fH_;=juf%hL{3{prk~gPb6+LgL z6E$NkGlFA+<9M8-e-aF@hHLJMjBNIH3q2Lh+M8kyV&ju!rNLD8Vl^w=_o}AuVn$Cd zbHvSCi>zvW2JYh?yf1pz+o-iur*{mH{Vv{ae?t8W>Sp$pv3^f4LHTm@G?-JJ|FvVx zbC6MOhP(3%@~?eD&(Ukty2swiWic<(T|fZPM_CM0)i`gVkIDX+Q!xA?eEc<=n1^s%d~WLM zYV7vT(YMvGiTX*#K=OrIb^0_0>z}2rgML-8Z|=2ezP~wxem3gSvZvfFqelJ?<1c*& z*5}zjzM))VYnQTTfG^y_Oo$>}n>V`M)Ib#!}KnZv4A zzZ=hV%TDyt(A4?vF)x(Ad$Hy-4;{SZ7${i1VBk{b&0OqnhQ9+jlPEvt##+tV-wei< zJ}2M4@N(YXovtqqRr7hQ3ja$_JvHP$@NZHR zSy^fX_JFW<#$)*`wISxUTiz0k19%7vxvPvm2*Rglg7J`|kJJR{rgC1+-kS{!qu+Ti)ohG)rQC-AbL^Mo z*g;+W^S{qI{r}5jK+Rj-IMDG&?t1tAt$mZrVx|ZL~Xq2_H7B1_`=d!v?EX!v8 z&5Z1AK0b49=I>ILF1?)Z|7GjU(XMaz*wXt;FX#7Hy7vCk>-loN-LHSL+>C^~* zmdlgrXh$_YjvC22Z={a2C%sEfEky~MW51kGFYm&txW&nU3#ic9!xD& z8}Z7lP4Cb3r_0CpQ!8li88XYN%IJ+Wlm=S&qz^8b@7SJ>bycSgFFp#-?vA|kH>dWc zXCL{U&?(IqUia*M>B&W3qK2?6RjgVBYm=S0l0MSRgUh8SJJ&MLeQ#Px{^Hi2vn`~<%CHT*c|2KVy%9Z{oNx9z3i^a+{ zu#^35-evacxW0azJP5QbYXj@hF4be5$FAG-I2tmZd39IbgXdnoE(hUqbyM{+#|@4n z92e+kaV|in)AyoQulIklLzblfCGS_RnLtx_jIqBQZshUuW*Z(AeI$BZO1V6)nblmYrTahWZ8BTFaSQYH%$eBhN)N?_ql_D2_wL#vpTC-1 zBmER+RE9sD`6In6^7Z+{o6>peFow|yYu4c9g|o}>2^~T&4qrF>%RW6ax;>>FBlY0% za-3vcrJt8|1%6)g=`@-5_IXv0cMN8>in;0f!Dr|t;M{*3{JtO0lfD|YLUUg9uH+h4 zncGEH&wPFit@OBaTyU@cC661o-N)F{|Hb#=n8D{c2cW0C;B@$&IRK9z{W9{p-Wi`G ztILyex_Z0bH}kKpG48_qB6F)@+6!TX`G%b1KgjEO$hHhZ!52T z%)-}^(S0wa^9BAkUZ38VULU6JejQ#Fa!}2gn&x*&-=OvQ`eMv&Jl(M(b?Kb5QQVSM#`9M^iQ&NKfN+>PhlTt#z!^q*T(8ag;kEHih*#d5mG!a?#}WaWN5 zFM3;!=y4-s#vJwi^gJ>zvL7zDMoA_=j`y#-;<2dBP*2zY;_cnkgz7QVd+zqt)BP?) zjyh}mBFXUuqdyg61hxEL^mKhUju~3e?bY}{|10*uooe6zT95mzehzZFTx|}bnt9gI zb3VG(QHR+ zC}l~ri)Rk)h&-5SxJ?~Yy-P;7u62xlI{I@Qe~fqS309w0hsQTFF~7_lu8Hk+RN}4W z{HvaB4Qk<^aQ+ydyXSS*v2b3@=SY1w&H*^*u7BD5x*_I#t&N+sZzSGt{RIQC%q%Rd z4ruQrby~+K@`a24!>Qiw(a+VabLW3Or}c6!+PCQ;G^Z!ia}R%!G0uyOgC64iD{B_> z`+6J9GO1a=g!Ar37$2_&=U;o?>vuPU!wf#_MfDc=S%l6XjJ^Rz$FqX2JA{7PwDk#m z8PCP@_3c<+U@sc|;{Egbwmpj652yPpqt4XaneeB`5Vv9Sg`BQ${T1?2I=4R*HNxF! z=W>*vn;s*_Sdo7YXDsx(#C2X1TFwXeKel_-YvZrMBr#qfdPd|N_%*VcMjB(%+ zG{jptU2fy^mebYJ&+y%_Pk{dOB5#olqQ0%^1io)QeHXaqYutetl$U@|o)Oo*=i! z{Ad~6F_?>fc)cK1Ys@W$cVKjxR$qM74RGAazSHEe*x#z~yYQU~1}^d*)jQQX<$5)A zwfEq1#tkz07&+zY=#K4VRC)X;Sva|uQ^Du-RONP=T~2o~AAYKX97QrE_if=AW^Tzk z2)_?|R#X3?FF5?_Mec~>N8fYQKdb+<_?;>Abo!l!hk~&P{)l?!D`5WQ$eVo5fjt5WR$IGvEr|a9X`0bvX-&Zg?$F?;k&LPR@dc@wEsE%G( zHEZcxMICuJ9n8c@R`%) zdzn?Hm0{&=b!KmKo%vg)m(N}D?fG#&HuJofOBc6WdVS&L%+NmWc8^_nzt=veILGO^>ph;dY48AqJdyf894cpUC-antN zbKCc?pG|-K?el2Hds0i~nsi{#n)EI7@~QsDbatdIbn1(v4R{qE4Da-}&d{r<&)oIS z^zCz<>4$Glrw?BFf7yHQFT2j{Jo8VOHETS!6*`b?HZ$3bU;qdbBoT?6Gf-8i0xF_% z&ZwMo&Q&PnK!5;q=$vF*Gah?98p)EaF!Fe0Ye`=EanJkgQy*|pU0|~%HPs1gopo+F z_ug~w{R;Q_-tXP-?zQh->J%eq+Uv`oR8G5cHl^Vv@1aM=emk-IWzTPcD_HM8->Kf+ z`oEDHA?ou|#gMCBc+9R(HQM`A70RzreW&z4IHKUFvM|IFY5U&rn#JoA_3meHDLH1X znnyI1ss>C9-G3^>TFb>p%4I)4SY`9Q74ol_8GTRj*-#G%vMt4XEYDsb%w?7T!+)~o#1&WOWh{66ZebL{Wnj)uQ2ItUW|To z`Q7DrlHWk`8a)GDyiJcHc#VERym$K2z&iMt(b&m>N7o&ZhCZ#@Qhe<2n`cuSE zS1voY#(zin?HMVTXI=RUd)7VUo?f)XTb$mXFYOV3fcy#K6LLye`=@Ua><$009^!pr ze2p= z??9hBo)_|2@VxL|(NUR8&<{4~{?6%I%Rkqyo}$VOYFEY!uW`$xERKQGBZd)2$;VFC z3mWVNjim;09zB7kl}S!+DYxT=Mr-#P2VIWlS(@i)?vs6FoqYA1RC}TNO}!RlGB06+ zf4}(I*#f7N<2filIvO%{mDHl5VNYnCiC&%DPVNi&DC7~sBh=NQtD_a-ODIoPCZ6gs zS;H9>%TJ53Dpk){r@1h5H}q@jHJK~k@{-_X(MEPkgZPO&jWKzcI1Zl1f5Z9@`aWYK z(zh2f7^R_yenf%SqrGZLbneVCcpMxL&y8q~f!~MPQ#5(z9OcQH^J&e3b86STk@rcR z1HCNC*hX*1$AiWmd@oTynjJp&@zJ392UaH&h(4pv=^6v{hDA@O?lF0nY94c={-BJn zPGze`49=W8#_S8@AaHMB-Ef^f$FmN_`X3rV{Frb#?C*G7jNz$;VZ3xmZ?DSS^E0!0 zcwW3`=mX*U;=R8&oiG1Kp&^9zBC?9kYR-D5Zil`8+ew{w^kK_F2M~=f%hxV`6L9xy8NpS>kQ2{X}dm z-oB+dY?cRJbTERf^X3eKp`uXCC|INSX z6ZpJ5{qs8R*Y$gV)2aQ$%M$8DxeR~9>s&@dht=V8u7^BEZiiI^d&Ax6C~FOJJ+iG z#v0F$p+@z}aE16U(eoH@3}#yD?&ad-bniKIVDroFmw0=m#IE#Z+2L)kTISKs_RWhu z)>M>W?@p9CS6}Kc^7N`Eyf|2Cz4G*2)49DrQ)h|0{S|h7tipTYRHiFC`N&%PaJJ5hQ+GSZquo>gdVQkC`3PqA9Aj}5erf#a zo+~4-JKh;Q?~#@+kBj^?cxuq;(VOT8N)ARtzWl#2-$l@IgMJ1J!hx>GN>`=E6fP!T zq}p>Nl@*z#{5Y-ovq#6o%TO+Tk*rCyzcX#A(ookq8{wZI4-wuvC5@A;X*Bir9I@Y# z$erl!=X7G z*^JB?cq}Y`Ml}}rcF6A|WAc`szQAUI)A{~7#eWT2Q^D_iwO_f@^2?K5zkbD|-iz1s zXJB;ID^pv`TnS$HzFNMIdXzE;!xKecENTHeVUsxzH-VyZqcRd{jq@HXU(4 zb1^a!@y?@lR;dnxT2AH(WX?nxM$*1D4mi&)@iMH=90G3(UMXr{;dM6mPHC-xu@u-H zeZ5`m$AHLjdjmo$5Hc4}^0#9ic%793gW`hJVn1@K^@tM@E;cF6nZ z9A>nJ#&a@H=X=F}6#1<6_k%xO^Oc!Xd#qZyPWaRKj-&5c>t3v(1V#^g?$_n`cw2m# z^%<`j*Z(Jr?+e$%b1dd{ZfE^(MC*T@^38N>%`ZIW@4FBG4=sMY|Ly4Y(9=Vv6ze|T zXIFC-#_aYr&soauRqoy5ZvwplAL5Mak48%Hfv;7j=Bt)_V7Y70)Lh`LDoNfbyg2nU&tvU=83DU@w6N49qj3DM!WRs3mY5t|#`qihaL3N?zwa|~0UPox+Xy>qY zZ;`Uy#p>`ooQ{UxU9ib{y1z(usp+e&K27txG}Wu7zTx+E=ga#dKTNCgN}ID(cdGk2 z7g!%=r$%+SY>Uxjm7I2-d#plpf#dSk=>Jsm;5l#VUVroNH=O=YIR@PKl2_tdI-CxB z!_RDRI{G=9I(u?n!u_y%=oJdL!ry_{*|WjuaqbR`&h5+t;9Ty9k>kgG*5$=K9oRd5 zdw5Q63->Rzk3Z(~UJmERdtvUu=fvkiJ?WWCSMA&1`=RUU)QrO7K|^QneEuIIKKEWo zcwYYSKe|61Egjzry-EM-um0ODPLJ1-22TIh_0x8Fs>eROJY^qUp0Ib%joA5-dTS_A z&EV;N5){s=TKWHC*Ub>t6nb`YY|UxvnC6Z@k3&QSW_oxxK5J!5iZh zcB#L>J)`8clM9!)TmP@-CD?ba42Z?ctgZaGm1jwZtj@BTo=Uqp-QbL!nXtpN-&6K$ z{Ztwy*<{&C+m#c4Q0Gvib1qc|V6lBNU+>y1%!YPEZzRuhlox%tF-N}i0-IC@`iPOehh|RSbod(| zQC_0-TGi9>TZ|Wj42<(#nXb!6-d?m)d<)`iuPH^dj~ENKBHx=_YqB!oJ~ZBmQ&Ei~ zY!6dq?0?OwG{1`KI?>bbtPf=#M*sCF=S5z0@$q6t54TOXiP6RBWLWTf&e}qc=2MZD z4o^ux*JsVZ6U|g_)m%?`(aKiB`@(t-yvw=^y+-LlRGIu* zRBtL4$2*RuN_}Xz)>y`s2ao2>xp7`-?0$ae>0)v`Q$1qw!0U`7){EGO3>xMd%srgb z#pfSzUS{g^U!*I$9L!X z_}Jw#Yf$yC@DKYz3rm;puF)~&!N7P%oY0Hp4_k8P36Zn zNI&l_rtifD)s{++S3VEgz?e9l`B$qncE&EA6VEZ1CSEJuo{WDy=dJRvun+%5B?+(S|Gjl~>iDb9)(ztD^2C?DCn`)H_`E3t5B+Mf`Wol^F7*U!S8Xcwsd(zE zQj{gC-lsj{{>~in{0Vt?y^Lx7kvUhFP;4JKJTyV_W-BE%OlgLoy!A1 zQ%6b`Bm7Ce@7S1oc$1oS+Jb6!ie&;SU%aC%^Lyy@>>nsQE`A8xVnu3Gy@^`h^b9aQ$qq?KeP zSVeA%eR^%$+N-nGi>OwP5Nf}HVfo=f5jS$jw!dLTpD?W-H`rG9csd^)zaGKq1SId zYpY~2WFFpN8Hc53s2;VkP(B0scV;__eXfzC z92@u?UY`(~v%%WSTA?-M-H_UMUBLA(eMC>3wqgN6Ba@HQm z2I-N<0anMmJfY*z{)WZC)M}zTunjN{WTay{tkS`yN7~M7Z*q-C5 z`JI$6cS6iU?gVT=U!=L#v^#v`+z)?~t<$761J?)9*u~}%r$>AA!cpn@tm(reWc5T$ zcAN1%4@Ul(b6R&mSG~n-F)f|>7OxjEO}ac(`CijY=1hV5%b=m-Z}xeFj*UDsuzpk@ z5d24s0hm3yPW?fuUGC4-nu+q(^*ytu)m19Sl-~uWWzC~0Pql8EuX%pTg5KOAZ5>UU zdTZ)*VcP+%caZy&zUu||3gbQSxgOpT@ipTGPA8kZR(wk>UHt-Q2X6_!D7L<0dO50g zFH_kZdj1x1I$m_nfjJs}GR7&4OwKwv?=X3X_TAcZ8BT}M8Pkk0d|G%~s7+-&k)^?T zp?OCcp3xY?ugu(n`6WD$9}bo$$A!N2)J?;B-akP9ufX!1zSf{MAgvd0PSn2g9y0bW zkJcvS$AZzR51}68v}!Xpu6WS@k80Lh%`N>LCSTal9nQ38`kdeWZQQ;vKMecD%*=SB zzS?W0eauDUjN`&%c>eG>E;E*?MPZDxO-oZRIHo*sjiYefKgK@1et52EejCk0dEJn4 zM1KJ0k@PL9NqNr&5Dhx+#5?`YNrouH3cOnZ4RQI33w*tv6pjc-6SV+^t#ak(BwG z-YOyDE=LL)l6DM4WzU zPF>d=~I>p zKA5u1gIX(<-&%f;vt7A%u{%@R>>kTFA`fA0uFcCge}1UOz4O<{s+{!)8uIPfzKu5B zSz_P1)aU;BYI*I^+WRzTnAKdM=Twfpf2PMh?6X}Z%4sPSM@UoE220Wxl|09h=6rdA z>fBphk+JudrXJWFW*^aUbINa@>xwk>vpogUYqf^1-`Y?=O8?VI<%jUQM-B*?=rAq0 zhWM+=u!KAMr5)1e2o{Snw&jUM&lP8&^P!zroY*Xl`gQlmprga~+z+D+R`rl{v@rgM0>&&RS}>vV@Q`Q_6J{hBz3;9(Dbh@h{tHgZ;VpKv4@kD>mMOzbEt z1g}fjB2Fh8(;1yPlCwLEuG=&=_+If^dkv>Jow*pEEZ#SaPW}t*j@KFvq9<0ZvTj(1 zfpe)vo^4bre`f>`*W^y(#Mmrz;}d?oZ1nX7=JoCI&(R+bZRoGG3LI` zBIPp5cY-H?@k8B0V07jYXzKVzyyjcunmJyV7!EFX9eqJd@6&b87Y_>a`O8{+K!?qh z{z@(An0Spk2GI2GwwXMSsp z`QP^KF&4%ed-sv(JyS~^zn#m0lfyiKeej)7Yt0;wdEk6!j@J0}eQJC!evY5V^;_q& zFlPC`i}j}qZTdb7H(B<9m0tIcC$d$w+};t<7R*v&-V0Uhdb8_HdcsI`C z93LLT^KxG}m&K1?{G6YM)5E!iJ+BeYCG5ld`K*07?=YVT=MAs3{s60!{SvYn|KJb* z$n(*Ic8#b5rHTfL4J=Q7^PdRgFfH1#X9>MJUL`e^4V`}XxY z`{uP-`Co=?rnlB6)PLy0c&Gi~#)Oq*9JU|boREiGUf+Gn$y2^db%B1bP7l~{OPQS> zY_^;8{g!uPpL_GY+Y4U%I>dc&3^x{m53YS?#Klhg`pBCk}0s2Y*^UQ=6T$zjdz3JvZdr z+?Z~(-a6^B?ef)#(MMEg`|*Wdd0%R6zPnIs*|}an+n@}a@m9R(MK;@A=AIe$+;(-O z%6&iR>Vefgw;g?5%zk00QoUCzoc+jGn-yPDCrTfs%gT|&4~ynV9VVQD{}`W5M~Qq9 z;xK1z>5;HUq;)3fH&C3U^=16W(Ks;bHVo^u@B24W4I5uTVVe z=#f|BAg0MQQ8~ixb2QX(Etv;wVXJy|l~ z9ijtP$uHpkb}=H8Mo9-^P1xo+w8=q2kiLPr(CCR)A>eq ztKw_TANr)@QyW++F9ZFtU~JAEe~;_w`a7cb6OY2d4NvLs;Lcu7{hGrvXT|S~znM8@ zlh~5KMfy>(c0nz``9}F*(x12dgtbwv2J=c7RgCQ0f)5>rX1*BB)9xH!@v*k}^3|at z@42w}cAkgZcn!2{{4I<_v}?|dxg5QgqD}Mrg}G-K%Zs0n>v(0Bx_znJCRLkF9r{xD z#cyNGGtTi>UG7S;w;wJdVkq2g9O|k5$X7RKS`|!ovR@`_;ed zWnWii4n`k^QPpu)NjIn0D04Kl^nTT9?p^(e#_SuO1JkQDkZO%zJSZ@9t9&l_%RA+B zX+J4XdG_nh;kPdsx}_GG<#pC$Rke)I1)oc>Qa z2H;K@91l8qE^sFtj*d>|3yeyW) zw}r=s>)|=WbH%U6FUOxhetY~fuNSuPIzQ{4^9mcR9ylFsozIQ=4cRZ>`{9q>kN!u0 z{3ouN!|8wWpQ2h(`20Wr*`MELboDpFmrf?*Qu*miar!moFkU-7WLIW-wIB4pqhy@F zD>j9Dvy=CEZev$LENK2h2ywwtvqfYOp56^X5YiY8jAKqkT8On%j zQ9k9QYDd%66GdK`PcHT=L$bx*o@rOMOtbtG>AqI*!5QTjW$Sleb)l}0cN9C zE7IjdU`&X&VF~nU#tFGOXFB8?(i%&(^z!aX)k(%YFEIJVfl~Q^_5H|O6?xKcdt$<| z6D>LN=VpsN#KFoapKnt}kQkNs!0$iWeM=EpEO@+cdk|oZrC0`rx!8Ns`4>*37M1hI z`@(txeVO{S9s+Aq^L(*OSsh|Fc!~_kXjAqDa|UHW23?&zPI}CeK|>}7jCU&=W=3|t3z``7W*SVrP9Ok@UFCx!WsEJ^1K)-~~^0-d{QrDcW zdX@9aRpoy2Ug*CI_fq>ls(NR<<6{*&?D&plo=Jp9o!Zd`)u&P)+Fy+4McgcYCT|g4 zyh$v6>ew=CP1U^i&@sa{IYVQ{ntw_} z`-OS!pQoSY^FH@4%!ly>p9pMDzfo8mO`ZMV#Ei2$Y|eG+Bm+0Y!-2hnw$6QIJ8~af z%>8jb=JH~WjvpJ?IsUkCe|Vmyu7~Fg`*3W0AAe3Re-@Vq{$9Kfk6C;>*B9&R%xk9R z&v{1UcYp9B&vSv%Ve_z|o#S))^93C}Fgl(WwDhI2UgCK#=;`z#B{Lnr`CH=k56%y& zZ)kztP#x*_ZcN!&TZwh3Kk2vMny~lJ_Ns=m$nsL;Cr#ULo7cQ7hHtX(UZ1q7&QfKW zNH^ zkJ^@1Pq+`ET|E|$?S4bOT%`TUCwh3xi>g7*R9)vm^))(dZ;jW>^HQxE&#iC{&NtLAyEIVTpS-*p@ZwpV3sLzNv*;4^Za&nSQ%E*=iR@ z8kOyyYyI-UyffP_y*@)e{2Y7lbh~?BPK&)Sk5uV33ali3pU+`hOQl!V$)h689skRW zJTdrZxK1tUY^Qpk%HMLji)_ZIZ_>1SCXID|3V1Do4+DlH zhuiA}nP;hvDnCKLW#Ur&Ak^MPtSqLL*XOMKJoFxFDw2nQe3u1Z`mMdRa`M#iw+!p^ zx^=sbbI*%z#~(v4DxMFIEH!m-D}JFK@ilDSSsLYwFV4J!J(gmQUU4{{b2jooVIlNF zILbBD1+I=RM>*1XYVf4c(`rs!lBG;_@)Pmg1pdb3a$0q+9XcQK?eXP@`+jmC^Qe>m zq75ydo-}w?Qun^@@AGV@-mm;vFc7&U5u-x&a!~OJI;+&bMk~>l^ z-x%u+c-$C2e5drf$~m&y{Ve#>`Ts7ip>vr$ry242TuX}At@8idp)D&SKbOYK-NqWX zM|GLE89qKHRaqhm`WzOTBan%D!V`=eh zo2Ab&{`i~Y(qIOZ6(wyt=fHAH+x?Q(X;jOp&y??&{CR2#()YaRpHq!$9_o}?m8;K} z|8J-%<~`2VYaS+6Cs(~%bqBs4n7`dJ_Pk_CTbIfIvePpY@ra|N_p1j)yZq%nxvQ=C z@bgwI&p1roCa-x{j`z+3{%5Q+>lJHDm;NrDy(U?#p8lHk6=>}#OSP(LD{cRpM;3hVtCjVl zy3(9gR(AA7%iio!k)TO7(IB=(bBn$ z?hdzyd`1{HaPeZ64!5(v8%qavzT5rbIl}#m_u>A#?SC4lFJ|w>+#RmRnLK_uXzJ+c zY#3EN*tM~B(rbQqobQ8@i?{`PiudeG7rb2`44%QMPM zpBuEP{$}OAjH{k>MD?XzHrP^O-+g=9P8F(daj?lgy*g%ZPnj@n#-f7 z?47AuxP-lOi3emr?N zC2%@SgAW{?+G{fx*mgqx0CHd8jyMCw`GU)QH||+*-F?B&u%Kr$ALTh)XMHZ@Su$rpgU7SLad0)>BD~Mc34W5%BdtANPwM^`=RJMq zsvpENO`liRobbAkO9O+upIRCvY(suNYaM*Q_*9s)kl%=w4L3*G@CjbiiKiW(iuV*^ zOvwLD&8KHO$~R1{G2VLSlEcgoRoh8EXT@pZIxLPKjBK5R&ClAA&CmIIRs4P)@0%Er+?R5V*;ajSp{9XM6Xt(>f1dBT zXlzh#?Bhm^&YBo`|LvN~c9v_7$aq^AKhD#iG5+G?GS1n7)2W4EJ&O4g>tf9D@M8J> z8iRq;XI1aor1}T`-l!>!Kkwr4e!A=KIqBh8bbd0FDl>O~=5vMP@q3XMaJEJMrK)Yp zUVTMlXQRz&ZG;|13i1yKa8Pq_0yu)Cz(8C`}6-DwaY`)p=+G6-iIDR#wVFD zgJr7q*ZAmHeGl=e5UPvhM6x zEN|B%mb~#HYm(Q+_3~X$`eSPnp0@g9;`pSeEq&`FR-YuFm6-n6#z(Ah-;>&4cjX01 zdv6i5x23(P%P;A9#QE~aWbSxEuk)((di}0#dqU^2+|T2Sp|M}wSNVDK_vd~7U))dV z=X+*&&S7)-o4%T8>To8E9{L->=;*}g>(rXU>)Zz8!^g0CoS&Cs=5T-fzQE}0!~Jot zjvpKDXCJ@)r(Ndx;#<(h!+tTR2Omq=!`@sDJRWXee4XR)sPnn>jZS(-4ms-7lai56 z&1lG8gwq%6>4DSH(&IIxpT+60`g<40)$fRW#woiv(P0&N$L;O;L2+uIveS>a#|7QI zTWoxDx>5O!jj9W+wyIp^{S|9nf3)3(+A38iStOrGuj|=W@{G`TG)=znlznU6J6N~8%hdI&^0!QMRoS_rI{DM{?EGkpU6sQ@TIdpPc0r>AKJOtW?prPr=)|TrN{Mj zXK^t#8a=*X_s7sDl*fsYc)V+xdJa4`{u=sS?2jF&U2321cIbt*(Q?`|ur{ z$MaBQ$Q*+C19_V0uMH>F7hH1$a;C`uIi>nV`k}kmLpGdR_Oci-#|Ei09P9r8r66Re8DK(P`y)lI=*pUTR6n?4b^ry1P#K zXBKn1=iM!l`EtwuqWgG1?j_OpjPEz{xTpqOzM2d24HPA*x2Cw;$B=6Al6SuFMo4eAQm_2ZqojK`QdWNJ6@qodC= z-^3qJR_l!FR3~dyPptbqBS`ZJfA0(9F5-07b|R0`h+b=|PICqM7n;e$J0Z>z6J>~j zPV8E)=fS&mo6`fUa~t`QUbm|8jy@kYd@r*Nhiu1dkBSpl>m1SJgMU3@beNIMmkx1y zv;5M`q3}HQRcqZyYbpG#!pQD*3FAUz83y;^gs~GiUB0V%&7GOMqpQbjS;Okdh@Wmm-j`wZ7Hv{qd51hL^~y}_mVVxu zB^H-1UVh|R>G&(;Pg!9l($q_iyyT4DpDSP2foH8V?OEHi>R##O@=!U0KWs@G9*|D{ ztd;D4+=}-%BlGfjE&Bvb=vp;QFJ0G*^BTwo2GQXZH-bZ)u%*0dk zf|VTjhLs$A+UJ(#M_;h&V=Lr?U;gujuwQ~_|GXUiMI84_@Nxa4pCWxl$tuBDO|A=C zIrWfmIvZL${&j9AJDuD{I6d$x4E(cjI>!cXUW&2fJRZNi)UkKFEj)jGAGkceUrHAb z?BpbY)7pFD-Uyy5ByyG;JSCSAT1&&E7pb;QnlUA{Uhf^DQy>`|^RemP(UT zE#yo$zLOU5{g{16S?i~V5t!=v-i&RsdjUldIHtk$Mc$dh&^x2w%U)c_uA#* zD%-YZnfEx#KOui&)p6UhdYOH!zNa(NBk6m1aLY>9O!1%$Hy4P(mDAT+?Dd_U)hF%J zSiQYF+vGi!$X-0K?G1UwOPsA*)N>U69`CHO>7Htv7pISPRN81qmG%`j)>*9#$^rZI z@_@W8ZI+&}Q~vb^Yp=?Z$NrRZDy!_1tk(P*m7;gggm&!+3@I}xA z5XOYt=`oML6`w0QDE$`6X+cXw@2kza&E@1J-)3)VRMOF@D-Bv@#N?4*9bGkk-B}-Q z7c;?0_+Ze@S$jq&rG^*J16kAP>YefhP-9q4rW8gBx|NIcaJ>S@)WD? zY_dt(vpl~w(sdh@<44abr<)epR-oesxiT1nY&TD%6pwvJqP+W z?2dj9&;=+S-DUaQ}hvWSjtf6?oj!|j3N@sRMk_$ttJleRCHzeT-E^>^xHKx_=B z!=G%-%R;R%f3t9NllRhPUKh;)!+tT#1|GlL{TzSm7`^5ltiCWm;I*k8oKdD!!SDtA!hL@fn+!!tXT=_7ZZ&(kAzo+m%*oXN9bs79U&9xl2 z3-T}ymu|Mq-OssKq%wJx(tWv!_bJqC%`G;Qizd!!po0jjXMRmPB zMcc*Z+da#XoR_L&@{OmwY}JV`$m60+7J1Ku@0@ziQ_0J{{<9|OMREFz&fsu(DZH2DgLfaT4tGB?zi@oh|BT2WN!MZC9e6BvwTO&qs$m7;>;yKIO{;>4)r=0V7O}1b6e_sTDf8N*l zb^I=1@7|FK*UHh$(bw_4pqq0$49}j-^mv^qJPRiW?u|2b(7eN*=&*az@x0KJ^!x9gv5D?ecJth* zGG9imu0+f_(rknBbI(|y%?-X>?~`QCExd2@8vI%)qs%4*zinMb6*m8sTi zti`&>V;pLBPQN_WDIa=+^(e=MOq;e!X{Aktc68TzyLr0TYhB5T|L$8O%Cph?d4E>E zd(A_p+muBqU424zs`99u?~~tLni92$ye~B1^8;n>g+?DgE#D{{*&vObT2V3^Z%);_ zo{O#vw~~hr+fwI8?jm)XWHMKz%NHy*I@2j1hxm&gN-!sV{D!5YQ(M(6hM?9HZJafF z=Nz$3ht}s|@2&-XJ8(FCMYtRoKJ3H&xAzez(Z6&?`5|~3@cojlO@1AHMCo}-y&g=) z{rKbCl|e&IAYO_d<;385C%>MWM*8-^FT9ujvOS({Oa{aLjW4)v9My|Py^3J$;CWfh z>CWPK&h@#%>Exp`?+J4s=0DuV+C87|>GmvTrOT(U&zH}S+DUxbt;%jD7cTT9g)=S> zs;)qfrS=p*``Py6?zJjOe$%x`>Ic!_VUv*2i2ocdxhYTio9f|G0qm;E^v1 zZxnMZ%?0#2@H%rYyhwOrm*w(k~0XW*vq(U%wa{ z4-I;CwDzL&6l0;m^Ek#|l#e3zs#CukY4Z50BEP#BU2})%TqEtA+EVI9`Hn)3E1Z71 zInlHA>ZR{@tLNmX^wjd?HR}DSx)$*nzWh)l8fWvx>uvA(7wVCwpy{)x# zxliZ7{1l%%bq{nI;vHsDo{;+&6jA!ZsyzkY*cg1bYsmWtHzHjv{MvrssXI&1A zyZD&EyXJYI*Sb1X zqMStKANq6NUT0eBy0iGgJS2X9{JEL)p6!rNMs@AfiL)I$oJ!9)b^3ObL>DwNapXT{rM>M?S zJ%3(?{vwXMF_)J8F&@m4NM&NfvuO~XO91@`+1IV ze|WyI56m5o3Af*EAC6y&&pD64=p+fAB|MOX^wa@}=WX$D96_|L=eGoENn8(AOw%y7xEwyGT0^8ajR# zF0=pm%A|ZD&C-`gY_6}y^VBa)bh`HikNW%b9j<{-byq3NaLPWMsj+5xa}RA@rT(7f zR+xUst|~L8LA`?L@j2L9ZU?uo6%Whz-d$tw&9%s*o+yUjBrkcL7`w_f_5<73D5pHf zzA2p^Px$r8M*DQG()p)MeUkEyDd$;_BkQogPVB1Ol-BZe>#03y9n!up`#NjO z7M5*EQ1gWnimC-tKAqYTHwMX)-@qk9HUpAqX#Yh5{H z^^paGw}H6;IwR)?N0AExbKx1FFA0xFt43$%HKKlyQH~5gWHQQG`-cPH9V@W3ozJO0 z;ZbRK(o^fi@Y2(#7kn?l=MuDZ=XLQoY|b2s`4QX-X9qrj4bUCQI;7T*44UdJd3Cg2 z&in_~j6QR+MGlHrwn+0-%^?~&x+MH9)`7KHyI>ANKUXpi%Tl+w?$7Hvr%S(_ly3p= zaq`X;^42P!LL5hpDfdU*lqNn>U4>qIUVXgaJ#ypebCPx774a0AgejgG#9R+u9-jnx ze|#UzY0&BW#Dx)~OFPFqA%>4{K~HB+GNYaZjp{|qS_XNG%|lnA_`8D=9dQ;|*j%Kd47roa=_m?M1W0G-8O((vt33=1I)t{zYeP+t#kEqR1 zk4Ne1)TxeE?yXi&IMmf;PAlRi@81APae{l)?>*2CHc0~ zoF0E)%mw^@oy&nu%cVK!@2VlulD565+JHp;4ZP|eb86YiStNINNLij<3##n?yn|7H zQvOezP`2xAqx6H4oyzN%cT5alc67ONH(&L>Ms+7%v%_ybsr;WOt*21^9h9xon!Vok zz5X@#l{cj*ck#$G)|zrM_IIr#{RL<8Bdfn^b^Crt z%zckFAHK(u*L~IMrI)|-(Enr^o9?l+^}k~WUis&CaMf?w@eTLbi8t@l^W1B7M;^Aa zee$>;eZY>c{<39lzQ>NOzt2wT_S84OYSjlHagF`Rn)`lDXz=cD^NZl`&-)s8Kg(a; zd&p^l(cw$HE$Hc7hcmCd{f_(9xsF~Owxu{daP(4~9=~rX9uK$09~*xSm^&O3=kxgS z;r2MEFU9I{P7fZJxNjxS=)B*+>4DV)le4xEHr5(gmtfE5h?dUhM~*t2{%`*G|HFHb zhTIplbQm4qOUQZ&^`k%GcUjQU1DBKSaz*u{H_wfG9qIe>r(c&J{qkg|=NHx#>NmS8 zU-hK}^1zHKyHI`?v38Df4&OQ5?HMht(&lROj(V@5>$6>6d-}uc%43($1)hIrzFS$2 zBSx*LbNkK>%4MvxAH6;7{QF(?0sT-um#kxZRD)S&)wv1w{mb3*eyb;@wDp8tZ%9Kg z@Vu3w=0asKR(fAiYCunS7b`!e-rke%rB^+V3epZL=e$exqsh|j+dM1rY;UpU9^dEZ zb#c61@2x{UoQlQi1J+WJZ6}pEiPnB|zE3%ny*Aoju3oHD_Q|DTWx^<@MOlvH^2)q5 z*{pShR=YM*DL&8k-((m#KVgH{hmqMqO(0%+c#WPltT*Q-ZFNqcRvsfgOUV|Gb2@cx z@Cr4SWRu|?pe77ml3q^e;IPZt4*gEcQ&OqlHTrsXsV{rTs;17)y%b`e8D$z??aPv{ z7M@X-wD=6qCwgeq4^-N?w88Vc{0G$P0{C zddNL3g~v8JPqH4sdBW*DqXvs69ZRrFNM9NX);+^j(l6 zIjcN&&w-I&2Oj6x#l9E(4tUg=|6ElcUe-K@w9Yaj&ZXWHkM)RZ?qDVAAOoMr_qY01 z!ReZR&Pn5kyYZT|$p1YrUpe|XwXTfc$m68mNaF4>YD+aPE7I_@D-%0p%;-4!)yzr< ztxnV0mNa&l9(}({9L_orHs?kOWfM)oMCr-{M5qdC2p{{2Qu~lg0fyzr%{^xrq9PR_O6icTw1yM+mgMQbKvF3 zx89)lq6~ZfKO{$XM%Slmq!}nzrBUl~u+nOa=o>sKCk?i$8DrU znTQ$7t?%TEmi*?|Z7BO0>FZC~?p62MaNf(d`;{-*z{%%qAoW2jJNSfceD0r#yYI37 zw8w1ovVUfc36EIrmM>Yx#xGgQ`Y&7E!Fz4{i~p;g+9(uyc4m@sU(#|ut z>i@FDhb`CrFkiR*tG;XnyB@N_Jr7xdH1_7C$1Qv7J<{eM|J4P+&-uMz z{*^h5K1UgOC9ajDo5Q8BEFSBN*KYV8HbrOVc6gY5oTCFHhkan>_%VUAFJ>-X{ad;TKeDqkN;t8chk}FyL|G=C-%;T31u>l*n1b$hxFXA zogQwp*#YuiCZwqkTW`Jk&q#~DIN9U4)=eo<(;m@36f)UGFuU*-1O>N7sj( z*9+6s+fn(2?G-2NTyLST6IW$M`OxQja&5b6MC(hGX+6|vmnYi2UXvV{YoitR>G>|J zEfDi4E0MlJwRzHimBE7dy*gLFx#I8h@~pf!uUh%vA0z5CfAsdKy)#p9 z-@MSNV~?qJRsPaE^_=WI<$C$Ilsog@xqkW1Ywe6)|HJeBc1h=OMLPS1F)_S6G4ytt zAFQ|c<*UD-I@xpb{Jej*&ogDt4pw^|={aRSp6SStzPCl**+k0|t9zz~bVV}W@CVGO zHY)F^v>)+F&B=Y5QxwUQkt;1u>%ZFIM|#*hLx`o&(D9w4fzoG%T21)6L%ABoNo!sE zqy83-Z`FN~|9iV@*Kju)F}gJwEaZ!nr>yg1(NWPk;bqu}EEXQiWoK4#6Fo`?%J*1t zg8J^k@ZxgU+r_r9IT||pCL9l^;|ZXbCH1hd9~tHJp}{X-DNhWHj!wyMG4Ch)sCtYP ztJbYD#WQW_oen={>-QL4HbZl=Q+di+7azE{MP4Z~(AlWTLqDHU4h}kZ)Uy+xN95f{ zBZQ&3pG-%*u=UDU$LE5M4)4NOurHj5=1&h!GFRG5H208CJ@WHLYy7+(nLDs~+kz*Z z?8d++%m>J?U><3kB`w9P!N=|HD;AnJybamzpX=0~?^1h^c-cC#IHY<@v&p8h0 zyt#i$I_T-<1o>ZHx0+17u6#K>H{VZVuCnW-;WED1c(3q!TvO*VbBlTDxeZzJ?-uX! zUa#cyWF1;-waO`tb9wx7R3D3;9{HHZwYJlzY{O~k$SpZrS*Hm}pi zNcrjMo2(+0%*LP8)47euQv;oUc%`yLqP_#CRF4^Xpp+-2OwmrwJ*oAEO~V+u+x`x& z)!5*;_-%pX;~X8ojpKbjs>i~=XyZXsk60aMXWXZ%??k5F*M3Xf{_^d*iG|0-&+n3I z;^WuD`GkG^zHm9*$2m~thhHZRBe5<()JsHUYyYnGS(`(hL zX0-MAQ&zh3EAqO0-ST%oYFXPJvh1CY%A>x_%J$r6nVa#{JmEb5D+7Fgk2mr~vG>pN zI)9J1@k{*>=X9}pdTz0^COitm;t7F0*@E5-1H;9i#nap$bnI|^VCgt(FTTvN;kIym zd>`&(A8wCd4!5xnufLel!*$-zVh>B;^1$ig{y3w<=`eb|Hs&$#Ib2SLC2Y=G1U0z9 z_wvo}{=hl?_y6s`Gkh<9Ab&cVIve>f=<0#f<9?T=ye`y^esp!#&Wv{2g^6xuyiD3n zWvHK@=(6`Oj;UsJz|IZV+njtKWSneAC zt`-x2M=VSZtt?Ca4do}2y)xcbWCO}od4I0Sn#$6xJX>B3 z)s>cKCyM#2mBEr}@1Jh9eDy{>Gu*28H)NCD)$+KMdG5>UfktID9<&?M)$!x^>pjk? zhIF*O!uOX{FN^o*>O`~Gxn3AjHhWK*=GM&L-l+Z_JzD?`j(ogxV zfdk-_+HA3hShHI`b~utOZ#d_CH@z~+y^DOlFfckGd5De5yCV<1I$iaaX`8ie@ftk% zp+!934?l}PSo3FY5NiJL&@{^n)2aH!=A3P=Cvpz>vFF;vj?z|Z#9nx6U?x1w)Ssc7 zR!a9AuRZK~JKhD@4Bo=GfX4<6zgv5_9qn{ZStVq_!N~M~XO2L99$9_vmC*aCmWJI> zAYE*s{&Pycm4Q={2FU9drEIpo8s$4L+z*@6%cxU%)Ogj&R3rlqKS-+2aapIw%a8viQ(kZKtnmPhlQ*c(n(V=+@*F;@4q*F{ye}_l3&`6Zux|^uI7K zz#Bc^qPpSSt+soeyttaTp~L%z7Qe*Cn$MJc%qrBqGrzQS)K*FoTPeCo`ZqWpcv&QEf8;M({e zJ)G;eSU09!b6dFGj|tox_Cc?XU*|S$j7dCS_~qy22WLK7c4D*o{O)qkOT_*W-^V%n z{pqSZI6a)};&TbNhduQ-^kVb>*EIj87s5|)`og(6r|UO^zlE#HQNP%E+tl$uhM*LVpG3m)*s?_1($Wr|bRdYkOAnSn6KLpX$K(SGdz^QeLrsdC}); zcUao?Cv3WGjUC_il)T{2xaXwp#Ivqxt@syKyyHuDWVM)o=OfBxd`w=O7p?8sW0t((KC%A2(%v8YrDnW; z=*j;q{QN~7`wx9jzif{WoQ|fRRaoY_GMpP&H|WnW?qU|^m~el%FYq+i!)5kp=W+c! ze&14$U3}Y8$A@FshjR|M1twp-hrgMJpr6N?Jos7ypNIWoPKVK9b+q%KpTp^FFgjlU z-jNAAfAzY3`02M@OGi`xxBvb>7@05hA*FT{&kH{F|Nhs1?X{!9@8XOe^ST62`t(4H zd(v;nqdneTZ{NB;Yv+`ycug5C=f*p|zVf4sL-x%pL)NZ3OZsne><4GN%ldmvkhg}^mbB}g$+CJB^@u~lBAD#9bnD(+1^%~k|pI+#3U76n#vc!9H(GMGTd5XZ|lDAT^n`3%MWi%sODAqiPFQ5AKGr;yE&umch!+9hvxiPhs}%I&+C1j z8ELa~($TqoWxChin(b4zWSjSQx;EQmm&V)td3l~WYF9OH8ED9L&-;7Rr`)H22Ny=C z{u5vJnU*B4jVeiA?^+RBc)2_Qbvdf76#Kn1Uh3RM#zm<4i!$hxiy>YoD}&n1O0hW% z4_B}*Pi}RO_yVn)%ni5)UkaJjed4*$t7b?UE@X2|tCvwl${SwG2`8b+lJ9~)2DU;s zg_F_E;Xw3o_$=?p8_w}$d61>Yd;$i?s|(Y#Xng=)CX<7{FOBkVz$(7xFK)s6i;m6Q z0e|?Qd(Ut83=KSv*PMP)_3BR>ZiCU88!)edmAxKUa{)5h>G_EE9`%_a%Ob! zM-0zvF^16);c#9HP5h#C!i;^d`ua|ke;#pkq^T=+M&B#`an}5qGvS?}9~9pO^9KC= zp@%3OJc7Qh&z<@JSaz~%hx@TTV}*J~eb)He-OLU9R7dRbn%&5-wbZ3tG z{ucUNkGTppq!T)Sd_iQpFc!&PB(IS5BE}nYx*5%ra@5a&aYN56`gUIIO7r^}$5Ucr zGU6*W*2(wb`^Q_O=Z_HL5f;?o=>*=+1`}Kb1sMe`= zLVouK`Ce}8?04$wGxD^c;ijseQi*h2=6Td0Ggst04!)DX)`4xqb;i$9m*cmEW1Mk) z4Bpn|quV03_L>a%JkIJ1c`u#~s`0`&C-diAN17GNXVs|8bkFq(UYA9WzcNVw=aY7> zJKMjrh~;np4J3@gJ6{Gx6#v1QEI(N>G>&zjj z>6xk5x?brfJ6$i2SMlpMS-Hjg4yErDS0}GA)|}`C+pe7SZfWYCr>_2^r}m)n{?mTrK3Nny3zYR=Oy9I$E+rS*Lu>qJzF`B zb-(6yq+b+!|17Wb%f{LN(DQ}QVRiKMz_hS#U}|oI#RIno9_BVQckT~t9B1jke=J=BMyr3XD7PH$-Mao-CX zI$L0M7@hq2@!5ILdx6#2(9r+zkN(*H-T(Oq-uH;>=;`e7rU%csD7FKZtbf$)$z7jQf6>_v%~|BThI6UEoUBi> z^5YwnBfZsYIESSV;;|@5+UVSbXZhX9%3FLMye0SnM#-iVGgnA!h0D>^;qhtJUQyGD zm-n2sdUSR?9Hr9ss-#^yr!TO2zn%xKMtdHV2Gy9o%{4XZ0`XB$w>YT%oU~4Q*6=*! zTf-i(Q-`#9JTZ9V(N1~p;M0N0%hR+*AigD|29FN@3_RA$>TdEj>)eUQv;davRg!NWq`EeAy|T+_xsf_~0>gjKvZsxvH^^jiNBhcb^MXTBzFgM2>9KGEEzp88k$UfkD$&Z#ZV z>S*iaRlw}{4VX80j->d*^>SzQD2wM(mpJyYdWY-W;kdxha0@ICuQCp5($P3~>b#>m z%TdkqSm)rgBo~LAPW<%D|L}LCJ+_Hg+Oky#k-x=zV@7i`&7BrFJ=B*jW^=BS;eJl* zHWz#I>{>r{&I#hpE&krg2Eq3-Ev=Jr!#1pOh^Ahx^Q4xxLmW)4FwC1H{}SGA#w9&H z8Q)|Mk)47+1fFiv+%d}2KjdpX%s-fKux`V~*k&#VH{<_4+pO~Vo};q|!R<(6)}!09upYp0GFMkl*shbw&j0@+< zv5PqUta6dw?$_F=)+ds8t&HX!3+EEfC!8~T7@gi;7yI(%l`?1+3~7aEy=vY1p6T0}wfh+xELvyz`PJhDt@f<+ zqQp16PwAktIMLl3vNr1f*Y%$J!`$xBdgUpmtW=JQG7!_2E6@B%>&tyr{X?I(luZv? zhP)^ABWh8;`O$Uv%ReQLdaiQR4?N*n=qcjvluZv=l{EFDJr7Guzu&zqWk*z>eC#ph zx%{?eiMdlX7H7-fkRGn=#RE^-{#Sq7kKL<$#$)U6vE8rUWA$mTy9VDNEx&NjBg$)h zRGxRuGu3k`TiQDLjK%w&@SOI4C};gLKmKRo=P&BmU*^yA?{n_ydBx7?@HBclTV_G2 z@3}2-aPY#w!0;~D<9yBIVCuzO&h^JEL>j5fX$ zk1usw(9zjbFB<1`>P6vnyf17)TMr&}@^awz;i);p`|_>t{m}XR$N&2GT}vk`9ls0P zfBCQfpVyS$;`BvYI-YcLUBWie+hEh`Kl=WK5qZ$N#NM4^uIHyP^P%2OO@%y%#Pg^_xB z-qY-wUb{j%`b<};T^m0oZKvF>j-9ek&$i0b-fb1R$Hd~T@}$?fpJlkc+I8~tQO#?yZd`!b>1`AVRiP`wVp6H*rLy4O!|6{eRy%i-akL&d5srFo0Rt=PrWij23+9 z{nD++QfdN9Q&e{r0AePR+9zFP`Dz3@>ks9&@2L-#?e?EZ&oNTfBg` z1uYf^@O2BV2cV1N2f_mlSE2_;o(;_x<#Xwg4;rrp=Z8O`vsB(4@x!1#A96WZgJ7#s zeJD9D&gnY;DBF>9jy%9*`jFq_>?8KSHdx?u61?m|8)O|Hmb=)cc|)u6H03jh^4gOk zkBK-r^dTZs^GsW+=aQ3=$eIK51$;){J4)XVHHuziET1=Hhwq!7Kw09%(F*mHQC?lX zY98?ZlNZBhzZ9Eu8=oJU)zmngX-)R}W9E;1Zp=~qdsN+Fs3GOEVGMPa$lt9og@2qZ zPPFK9y)V4y^E!XVjE_@!i)+*H4$F_FT>XNCb*`=R{88pmG#1J9tk)V2?*|ROSJ%lQ zqAqYmHG<>i%GcZdq;m1@lZW7bn=60KHoWj<+y0tr_>_}QJw|8H(gUZ6akE;v4D>pVZ%A{Uxf%Y00IrkbW;CEYkcz~YE&s?W-7l|__Y7OjhPXdR-{*KuOLmj%9!SorRmbl~1wj4m#ZGx043*Ym|Md*1&7 zmvcMg5N|vz&-xBpHQy0`zZ2@+oO47OTACZy=E!s8IYD~9@OV82ZH4hMtM|BP&106f z_Z6RGcFXe~e_bv|dN}<8#OnI{xH+6}m%38K)GxSK-2Fg!?@BfQkv}T(1V#OzI6vmJ z)V6vphUVGtk7nD=0j+6NZ+E_h)wB05vw{3KEPwBlRw_;&E_u@m4!`PLPK|v>fqH6X z%de+>SCM+tDjTM+beHCNs_iY<;x(jQxohp{n@`we#YW8mUQo}Wr#w%+GyQqnyy9MK zJN}ea9DK|*_Tv3d>b0J*BkR6yU8#@D6Z4dETE1ij;`NHdPx+joVAlh7a{GhM@OxkT znx$@k#u7I^X1S_SE#CXE*gKjBl&T*R{Y;CGzG4H#@(z}5P=@-8mb&#ZD?aqR<`a)u zZR%QUKJlU+`;EU3TK!5q=8NL)pY?TqB|hAr;Z2~UhYdb=AIyRWCa`y4YIqk79d-_! z&gF1ixEyEm_~rQhJZGG{xsNS=eEk0S@mvm^&N+oGaQWgr`Z=5pZ^Psvw`M6m=eD?x z9vD5I=|Vm_oF07Y)RP8Q$Fq+A<@}ZFuBX%I=+p0f-@f<5AKSnGzy5F6&O=7}-~8?0 z+F$+mzc%_C{WtC7Iq4zaCF}#I<5NFB(IY*5#@>~l+)$P&k9Ur>RH|lA3}2X`9EaTF zc5O<25!G)tm#GiBeA^d>_W1$z@GP-jd6vmTd{^G}vqN=0 zPayZ49!F%i*U7uyP?%s>N2{Et-We;j)I-XH&}-r~Cma3TSgYzpJKWC`ye;@$&X0FF zt2?KUb|~|vH{x}%JGqi?&ud*l+WK2Fs(#@THR7efW8l3dm3iU%v3RLX zdM|ZmWOvkviK!n%114J%F2)PNx#E$5)#<}S<|At*RasFEIzDKQA+Nht`4V07k_S$Q zzoULdck1X7tDkh8J#c#PyTIvJwFZx_NiQDHy^{uwHjekZL%;tp=vg4W$=vXrM zT)Xrfn2-k(`O(qv=XL&3&A}n>Ma6uK@1428K#b9+Rck?32xEyg7kvHXo8xET9Ps?p z|A=*zbIR94lP*5C&b=qOhhK~GgWRvhIuN;_nx|{N#GbK3#wgiEgBrii_!{Tr5Dkd6 znzNPtkrma89$9n0`vd4lleX(cOWg9Tds~9vCG30k_tm4hXtz8tWFC=m!`#?CLeydF zxi7ZqyDHq^EH_@GH39i#m>Y~%?X{f!%PsHVO78$T_ zv%c&Vw(j|Ryl-c(dK7gjAF=Sz3+_EXA-_@5_LuZp^4jI?@Hy>}dLr}MT}7&0R=x{8 zNLw>sQ?JjLtzH>0ZOUUDC|K=`yz{jO#p!Fj$I#Oc{!8^0z0XRO%>t9B$&-F;qp}j! z18MK7d%WinwWdXTAGNBZPs=y+pbh4&vc0d}D;@kXD~Ip*i|aQ$W`*iwT5{k?e~pv7 z@!9CMy^mSq<|nQBqKNrxija;*zu%tXExfKE7Sw&;4@aV|EZsWsD8B${aN|> zi#q;S>r?*e?(bY`j2|ZG>TwPa>>PMK91|FvV`1pP-HZ1eA7^py4-6ij zd+}}Y`@`kH=3&qIgpD~we8Y>5&n0+W@TJFDJ#cy0FQui!>F_z8m*9I@tf_~(TWU-D zMkj6V{3ZLgv~;}bc+t_$J%90U{?>giA>(B!Z~8mu$L(EZy5M!8pAq>kc+mr|)6a-Z zm&-H#%3rDVte1|OeEYo*&UqgBd|##AoKZb#{Yh(9o#&NNadSU?Ih9Y>s~nS#68reP z>S2qOV^W)LdGb9J9GBMBP-Ne}MBmYB<&Kxi&!9d#;_sn)Wve$xt86QAFUe$wdUnd= zLY`w;`d+&3!lwzc|_LUVLh2ugu^}?{GaG zPRIW;*;DVer`Kk>lntXfOWFa~_sQc4aA#d!szC(jrxB5cF{vJ$PJTbNnrH@}ZM$Q+rZb zIO<`G)=sY?j^lo^=gDe;wdoOq$0q3HXyN2@kBGTh)2H|9yy|rGlhoTp@0HuUhE>}1 z>81or-@8)2~p2&b*A=>M6}{&=+|vHs&07h?w_~ z=ZSA*PW{oTFQtzTo^|JLeP_I9<|R|gk}1^tgzwQ2OOL;)Y@zi!R^vzv#(TksALTVJ z)Qf7~66xt_?h)cSU{Uu~i^DJW=DKFiT0&!<{7^bK<~qJ<&c$Sf(ywwmI3o z+4#+;)CtRuUmK43iV)r&JJ&Q+%wC)XFMAEf{uAf&M z;dJJAp0~o^#lqi)v-T3aeK$^z-~JQNvB1@LaC^8dwvT$EqE{78qnPwj|uo|LKL{i!sEC9|LTAM??uzCwSmx=cS`#xc4* zIY(W2Z(72pr+t1+|Eowhpk79`=XwsW{g5|^tW;_v@Wr6vpKFr;ELj;k`D<;Wbe(Nm z@fCad@!v9fhvHH1RK^wg>W4Q!?;b63U0US(Vr`L)p0qXUmxPW^zuzL|R8^mlA3uGy zxcm*v+54QhU2`${%u5eGrS+Pp?3Jg#Vmn{?nx$=f!m_s9Ye&{9uSI>3*1zyovHN4n zTEE}>BxP)UKz{OXSmrk6p(m`czWgo7IPkoc zCoI=`z;n{mS15C4wR$h@usV&oj6E+X(`tn>-?gSwsK1edP3q0`!cPaOU(qAJDDM7Q zU*}i!U0;f=1AhmGhrPoV?pwTH%;%qn#{-v#{bC(GuARf_ zfzQ#b0bQ`e%P(_+5gQ zzL?QnOaHsu{fyxB@hX=P-iZV1jnt_u^;6Qkb3I24KS8DXh4$1am!QAKx3_27>{}PRy+-qcxkmYbb1X~# zX7bM3%TqkJ1^@d{W1igiTU7o6! zZ>4mnbkjGjLw(U%Uq|=D-!dRw@c(D;J)i4J^ZU*}VqfkH?`rLpRnlnkOy}HWCz4IF zo2i*Im`Q*D2_g}h0FeWcL4Y~ujx*goS<+aRY+079FtTJhZ+WY1zkl}g`5ipqZKy}m zXsUXvmW!%W=i68V4AD?FS-(LTby2b?0=&N7VJZvhjkfxxcXTZ zvbx^`ncPeeIY>?2`6;h+OgnvYO`5HLJ?(?jd*R8ZJ&V)%mNn_rp{23C){nZKKhK*k zw@)&b^7GYq7GeD43y)@AAZ_|IEs zJ}>dG6q+~Qt6s*K_`>WZr031!L?3-Arx%{BJy9bO-k{SPse6B(-c*F%KE3EaTO9KqpN=2hNAkWszh;?(`e?c; z)o%QH8YzDY-}pC@{X^Hk^egF|mw%PdYYD!R-%LAJe4Fp_vSj^@V?Xm?FOy@`Nsq8o z=+&JEnae>(KXu@hG6|{nD=` z{Z5@_k5l{bkHfcOt?BSV`kfwp5l#MOK4-F74skqh$74?Y=!LG)eP_B{7p#5TN|YIeMwS`REqCwDK3{#>W1 zWwtK1A69R~|MIB*{i6K*Mcw~V`#jXmWpx>SUQ_4)@U6@1+%B`r>RCIN%}W>gJM((J zJ~O-j=iBpjrF@?C@SnHNT>kSo-N$8CU&!e>6TMVNFJ*HtXEx70i{x^(a~E~<%;(wL zQks>Xy)Le;B`wWpG@H?WM{4T!JNof&|1^3YnVT-J%jut|qvw2=AKX6|wUPGM)XOqE z(1^y|oqC$8!sl^zpe@p9VmZENRpc*vuClNDu`+VC z8upS!UKcf`)7{6z>(b9y;O2M>J(EtN*Vm(|H<6E07yW^5O*E%#a^aaH>CyFM>SAHZs}A=zluV(?IUxso3tb11)pj^giYfMxuVy9Ll?lMS|I>C6(8` zEThZw)|uXf>Gix=M|xwjgB*4Gkd8Npj((2u!X#`tfmS@*eKb5C(`dqKTFyPoF&8?~ zt7}$8&%_&TE7RsT$PYM1t_1whh^Mz5R%j@Dt*9y7>s;;Y(NDW&KYfA7I_Si=BKs7a z!dx_*A_u9f%Q$0jlRlYo{1)wSl-cKInWw#l*D2=SvnIGV=Je&Ohq^Id6z1UV>tijfj9zd$Jc0k`B0WYgwyaHi z*S(MqY*-YG?*39gm36{z!g$PV@e6ndWQtSNU0S1gt*0#5QJs05xd8jNMsFPSboGD7 z74|ziyy5xqtE=;?r581Lyl>uH9t+9qGPGQ1-h1#5pOLrwSrua{8H({1*In)-!;<%< z|4iS@m9AaPLEzuU(`&|O5B_uOCGz+oj|pUS8O-sFJs?}i_HjNyP5jOPy|9=UYQ{h1 zabSs~!(8dmHs99{+l& zqRu+}9eSJi?QzLmo&PVr&fDVpIcA@~Trj(j{fst0_gv0hMXn*^+WF^~(dVAe-<{l3 z>muV)Ghy`u+26_Uk$t@KINaBFPE2OLa2n5e&6{ba?v1p0$=8@?AiEGY&b1x!*>g z>vrLDdgB}ETL8NG*|jk?mEE1#hLW^v4MIKFdE(ea%<)JDl$?>NA(F zrb{<&r+e>xn11wIKTUu6@BTV!Nk7Bs3u;GY^=o7gp6RHeK9qS*SoD*d6Xc|vOy9XV z6?$`b^Re`MpWIASaQUZqreS*ONvWsoYpqT{e)mFZIYCauaC>U1+7mkUOn(!(iO0jI zeR;ScefM%V87K#-9X*Vn?zJ~2cmD~$;0cT&(O^YGZnCW zJ^@GeH%9H~d1_a$jGqopS3{S-&0>tK7df2eCVU=jj^D-0H>odGTi5@hmVWO7a|`T) z`xgfArk_f;r#tC`O5RJ~aWZVE7d-~!Hqnc+_ZZuHBE}%H<|OAdIpzXc-TKJQvN*K* zo1ww9?t6uNVDfFq6|-lDbLsZqbB?#Ka(UF`dG2Z6zl2VJ9>)D6#(y{O-|np_0+TXiS7-Fg2LyWR-@?HDYXdngWY{`8zKt7lKQ*@E-uae1Bp z)!X%T=y!3x+bosvHNcyCP}CLG=z62(3{Hsbb7~epQ#WdTXnCQ(Gp?v)``Rkjh3`eb zlsR)n4nKUzYup~LNadSe4*t0#rD*q!MCu_%$z(z zmbbN>>Ui-!dB4uN%jdGFwWl-Gf6DCowDsf`^9)5ch4poE`W2Y-d@KGWvL_C#eU1i%EfIrOU7}THM?s2dV6NbQyD|!tt)#yv}m_apMNhkqVl%BD7`3`+SW$ih-0bK za9^+u8fNw-Wd?Wt!+qg+#rLZ|ns3XQGQL0Gllgkr$(`BsCR#VX6q(X&!E?B6Rgfy&bffgWC{(zxgAG~j3Db|ui=fbH*0%2o-6L-*vMmZ;^c<#Oqlgz zEo>9s5HIUN(PN@-r3asgb3X-d6}@1syU_bJeR6eL`2zKK_;z1=>>s7AOTJ3qnrH9< zJ;n2>$rpSc>tOaGlQC=SdS9G(iaJxiCvu#=u)gDKVodCKxa9yEELx_SIeK))PttDy zjo-0T=Jd?ve!ueK_72mhzI^?YY2TVB>9>Q9tCxq|8*9X)W|Fa!V@1cT^Q<2HUBc}0 zw2RlzT@HPn%UM&;*URLk_w#xg-Fdo8^aoh@Jl?mM3&Qu^Wi18SLG*u}ZrT`nv_7rk zm^CBx;dtEpI_Gn_g}J>$Pp50`t71;5u8f>R=040tA7?ISl;4i<$MF3(t4*+*l?`Hd{2&S2{k zfbNQ&tKI2AGOb8p3~=;JnQJ;eNk(l zyIvO0_str6=I_kuGIS}w=i6OpE#3R5jmybu*J{@KzP&6D%f~rK#oOfQT-zyU%k7!v zGvjBLcbzr$%;}lUv$s6!=h@Ga*ZFq0A^TWlb3Nxd8{J+;^7r8QbW$(Rm(6#P&0V}~ zE~EWO^}Se6dh7msk8tcG&f@b~W zd*kWj%RQ05Xm;Xd{OcEBSbP7RuBNt={FRB$W1NQ$prx-#zkRzu9o#}sIeZuGm7Js7 z=p%D{JIr0rQWILdoIXi5yFPY(5Hg3o<_GAjbZ8s8WIGwZRcOO(gMOI@=X>zCpMcX3 zrIF4W{Nyc>eQrOaOK|!%bn(lqd;!jb z>POcDYSwe~>wz)OwUApw-%@*rHtT7CHLZ^_H>T)2Do?;3EV6+NQM#7H^jkFGX$cQD zyr+-cK81Q`)w1M?#p{# z$Gi^zwY^-s@Y#f~BlKc*;=-Hbc*1do%qlBKjyarUUzh4#OVEJfGoH(A4Ebd~X99** zUpDt!pR|4ywZ=mCV_(eqjEBg9m%r^tdIR3Q+(r*qyccGi=y{3f4Nfl@D{4;J$9j0J zAvS~lTGuw%p4v)uW%F>{|GDl^rqkCeLr>H!OIw!VduQyTR_@$E=I^{#BXw$_GH4`II06q>u<6?3c)tbH>2pq{}y;TY4o zof90F_8017jOlSZ4EI{|pdV(Gapp`bdV1a4X}lJ{OVw*>+tRPXP%q&R!;eBuXsM2# zIlahVeCSaR4gKeN*Qo=E939vw*O}($&3vwp-Z7SakMx%<q-VI7^|(tXUx7B zB)i*uPZ#GVtSgA@(yVdMv3O?hdG0Rd_ss09Gqca%f5GErcaQV%Z+TnEW8*UaJGQic znw}%)Lj0WbIAWOZLLP_9%#LsUot{NcxCU>@)BTT~o zdY#PFAE|#?~{4j>wPZQGOy2(`*o@}pTBw|-F^3i(46l)ct6cvz7~EFpW6&_ z+1UH%*Ou>n4YxD%x$K`WXLis27Pm#-&#axZ6EmM@{XBbIe6QK#;(dMJu6@65i;I`t zCbwU2i%ZteU1z_GI=b)4#k`l_{r!I#y^icfYJa1jr>Xz$$G6gNy*m^6Cnqb*(kHj3 zq8F%rM!!Qo`i~!+3*Yyt6J@EqY(x6VyR)$BNIC=4Uz-{Tzlgbw7tpC6%y!bl^Bo>H z7=HCuG8V1vJU>vIZcnwPOJu;5t$&S-mM-#Njz?DdQL;bd;LZJ3N0U+PVIg$(}lN{pxg` zES3wyt!c2W8V#M-96eR!qm#iHd5hCUFQa?p!rvqlT~05u)6vQCyW9z1I-Yej^}F2X zu8e+hI1Q2)V?Am1z}%iCW1akUbLI7_Umk(c@!?FLuB5)Tnr*I5*9MQKJHtoO+qQ%c zqn)0L)%@Pe*qfGoi!5q%bLKzm@ZIV)mWQk>Rb%nIX6Bglq|S{tlXWK_sadL@yU6EP zy37lKd*BPRO4MQH1ZxE4YO`AG3pl{y`QLNAY}tW_yzMBwNL{X4_AGN6vYoYrW*>K; zo1eogp?+@Wi(KisUT(SA&3rt5YVRkbsY9x%d)^J-YiQ_&Fa05>!{&IOZj!Tnp1Fma zJ@mSw@2Jl^6gszjuiw2q^k_NN?RhYAFnR?Y+Vtu}PM`D7%Nj1ShOC}5=45g8@K)+P zJ-)&_FvsxLuT8_~&Ig?9pze*&!b}k7CiH$}pSRu{^E0domecJ8WX{KE^)mdo&ya=j za_~l>(W9s1+cC#cP7l8?+hpzNbv!v&JGanhp580lnIp&3t){64uI3$i7wivxI@`%I zdFJcCGT#?fHqU&ne?>-jtZMzLV}yKL;oF(xbU1n%?l;rtT=SZA`p6rR31gjc{VuYt z$(oieBVUm*o$NNqz7Bs)Xz9CSywYWM3=9USwDoHb&mnZTm5jb zb)=V>7udD@>o5#n0BT*$<>-Xd)m7z^LboomUxx9g>z#6(;(Sv#Y}mH%B|O8AMYi?! z6_4|nIZt}2md<4vJr+L0=y`;GZqB0FM%nY?THm_$rS601U5SpF`yuu4+53Ied!v`a z8WQWZeVpSl=ZrF|7i&Fc^d#-vh|m48_+Gj%!l%yuaDTbq{O-;7CC!{&%G3F}g=_Eg zdH2iL<@@u$W9)f7JwI-4?Reap3N!pq?0P-C=Wf@$|AcX4&v%#h1{^zm)1Xe>1i1dOVrAICSLs(Alji zZN|q^kC%M+Ti=Rax8{j<@m%WQwL2HV>d)YFS(bXKV=gD7#W@|dmGOFdXXA6x6ECal zYjGabe!ud%9!0g4c7D5^ukm-hVDq9Um*YHZuFa9nzvF%%9@W2p2tR*Ok9m|nlaD_6 zescNXyPrmm;QbFiN)JBxPO!6ld7DK&_{P0=)79Jef;s))``^C*emZyMdQv}@Pvut` zHS?`(EYG@_C9b~g?ee!Ao)@3P>s_)&tsd?Dd~6;g_%hfKvw%qLNOq{zE zzHqnKZO#0j-_Ls=eH`!kJD>g_yyIT);(PLax?M8%)m!&sJ$>PFT=sv*6_;<`iM3-2 z-@8j@cCT~0UA*l5eSdC?KJ|b3hkq1V>VNuYKZ`y`<}#WAV;+q8jJeOz4**(V={JhEeC!l_In^HgYkwf?MnA?E^U3w$)O2ir`ssJB(T8*(eMmj1 z8H>|>4XK+fn2*U8zhm7f`7Vt|Hj>#`mhRG*RF0}8Tk+yx9Uk=k={tC0TIn0#TfdK7 z^=^wrUOmCP8%6=n|WKUUj34-byQ-}Yuv zmwIdQx5CpY7uY|>bC~_%`_UNf8x$FK=y^TxL>pYL58eBO=18BG=sAS8)dyo)kLP3U z?Q(N~n%DD}{_v^X7*g?Jea_Wx3Ao_B0j5!j9z5Ce0PSNo$fu6+cDkD zoB_V^&~f2mUvH9anMHFqm)-qm_Wooe9u!_*?LRbs*fnc`&f7njsAf!2^r5%^sd+oo zo#aOhRK}Q2jtRdmI=^0feMo*LX0Ob`#*=8j)TNY zk5VhqwUO+Mr_%m+UW)zP$98$YyienO@Lu%UpM~$$pReK*kwMMl>7pJs`{ct*gpN6m z*U3IFYnf}=vizy}T0hx5FJtQN)CAP-E$U(AE&VS!>pbcQcrE8TZV#Z5!mB+n`b@)$ z$TBq3e7u2U2z}kYSbC>q^it1D(F>}?_kzw@c-41Be(05+J?R$QXFpw!0egA5M81%9 z(j4RF5{>bGDmFYDx@tYX3A5B?m0%NkgGLQB$IhUdI^#=^Yqz)a2;S(%HEFQ&we;pQ z|0Jz>g`V!)UV&#GdRuHg{`{W+JE3&#C`B9#05-&?;^>Ms7^0_+y;q}kM{b=*t z*L`5GQWvvR?G0d7%v8gg;4D4vnWtp*%;|n_d+_ws?pz$>X6s_D!_|wOS-3BbpE+;I z0*0RF@Dk?!dD{8Uz24_s`1q37DRL9>;W4M;KC&Lbxi9@E9y=aa&XJk&Q^Ag-s8<0}ofRui3@Pp zWkvK)R)hC(MfNGZ zJNQS)t7m_YGQOL%&%hD3Z}qpM9{79{y8j_Eg7CQyt*7)md>EM{vcdp*j z#dy>#0OxGF&{{keokLOwkj1TkwFcjLHZS}8>2Ll3%cJ=BMe+7O^mQJk&qR$^KZd>S z&HDbWpZ;$8o!|YvV0N=gWK+Exvag&iH_OoSaMqaRWOeDRwd>bbKlgucle05xtF33x zi(V5wG(Ohr)x!0g>tWa1;_cq1Hm+Xo?Ov~bUh1RqfA1r==iZ=lvfG<^Tg~1vh+~r6 zBlP3%|0uG}Kl#CrQ(iv(;ZNp!6X_?nN0ImQF|PCNUY6@K>&yOLcJ1Q*<#Mm{HNEcI zog!1+{c2vLtp3M;`scyu=D=82s>ZHA{U;w>PGjATX}p)7uY38;!-syHOqUyzr|99+ zPrl2hRK9y%sy)0dwbvd_z4+Cej~_^t`?jPXy?2Ft!ZXQC_4mkSG4rLT;b3Yzu|It0 z&6T^-`TiPu{g7)u(Uk6v*9Esvb{2$BU{h~DeCG)(Pi zJD&QE@Z0MzS1*5<^C|_#*r3! zHMNA-W~RR$J)LYudZJp#I^29P{5&;#-%4d`UrH+%eKS1N&K0j%^sVrYnw8<)f99nj zyaW0Riu2l*(BxzpeIJFN7oRg4mc2v=={r<#(w6AOuC`^~w%H+S#TWFOGS;cuLA@N> z*~Q)p=E4s#zd?^EwDZj3YQS=4{@=BHUSug+3ku6~pO4R#S^PCat?TFfY2M{W*m1Rwbs_v0HgTSITKJ_NVL+w|_p=yJC@r@pVTdc0e8 z^m0NE^}U4l$$c}Y7p$)Lh3_rAALBd53B`BVxvOGsqNwdHj@9f%iFJ(WN*Ft{w(C;% zp1a;-Z=T0L@4oplC5-O#$mwRHPq*#hec(Oe`0lG=EK!5c2v(2r9miF8tKenlcEU5o z?~|X=Y|AFR9@c`ch;gjr5Ra9ZS7H1X`BjX~^yZsgRkiVnbiVoR^y=fkf=>N>)F)fJ zP~W8}zGLTQ6Jx>OcBl(&8t7BYkJ8A`Ki{k!HzS zI{41hsfn?mpZz%gBeT$Jw>=$o4d$flSLxXMT&mmj^;Ev@n`Ev$n;OZWX)b#KE`L59 zr*~-AzNb_7{-;yfimx$0_GX%@q3)S{bo<`wrD?;nqVKS~LaqLlbadl0_;6(NC25-d z65jLB&X>n=rSCklx|lOEbJuZEQ6qr|aR-?I9K&+CH7SmF2HF397I~cOcj!_4`-k%L z7xlPD=`)duWnlSOFM9TVmmR7~JNA{wvg^Rn`8*i!pKCaMocEKN_Z+T@`)nyYl-^pu zEiGC3PFk^cOIr5!hV=UKwdsu&>*Bgsmaa;#y}4$7@qXTC`I^nK_}G>2Y)x-(*q%1- z+@H4ce4BP1NE>$SOPhBeOl!C7PV2UorFXXNi6!o{=WuL?+n+r<`rI8GsL{*o7q8z+ zS8m-+*Y7?E&0KDGk)>T^X_-2+yBsa2J8sEi7soG-Yx3AeFU!C9SN}RRa+&+jfA(*~ zfBu($_1EdI{`%jifA{bIL;ACy{YCUQ@_wa@kM;S~*L|#-dZ`cQ{p-`g>KDjx(RV)9 z4NsG2qAo3a-ka@82e*-WFkKpHOXu14NwQt+ zJ!<{ydwB3KtEt29deha_vo~GeOY}CPztJu0M(45_z5OcJsj=U~lYeEh7dFS69)9(q z@Txl=Fh^#zv%2WLbqDQrxx$BdMIA@?$yWjO{jKB>pnav+&wG@mV+{ylT?9|9Oz&>bJd4KMaSTSD>pN=JqIrkb3}5Iy8f>ly+PMP#y!vs}pD)1i zm%8_(xv_n0({;S+2RBiV#%C{2sKJH)#`*j#UYtUU!>i4EIm28)?vWI=$-L%S<^r4# zu-4KnN?CFSFN%I}_0zL(tJw=p_+n-KQ4 z_tNmR$l=l32|l+U(nV@mXJ9Tpyyi7JrpSJB8D0O3HG|edTtq`P%VoBO=dE9bkNTPD zJ=#&R3Jn`gkK@tj2_HjvTFj4s$mu?x`|Iv7y`~1rcrJQJ)!^IR@y=!pDz+Wpb3Z*S+wdFfF&^MGqYhH8VsYH;V!g?2YAnpl3C|Rt ziG6^hA1>cf_os{b;${%aqEX+;aUK4wgsiLTGO+on z;cH^s;@Dz4{oT-?lecmHIO16IyR25Ou5RC3YlVCCD*65x*I7H_{7LaX$qc2ga~xK$ zz#pU5Y-ZKwrQal9iMfbsK3nv6^I-L$+XJlWAa$x7b8cJdqW32Bb&fsnduym7>ch?C zJlAN})thOym40g+&uZTX*4mHv?Nqk%8>zqIwY2xGuc!W_OM}@PcRim*s_>3)qh56L z<9O1aiY&$UeT&m>*!(zoLPyqogIdz3!)vY|{uq6f?0}?uSENO6tc?4;x@>iFDP{R( zt2QQ=GVwLiEvnLfQeg-+c_mSJP6tDshhenWjN$I^6fZR$8dz84HW-QPm?`bjkQ zO4d!}HFl+`{?>H*AP3p-Qh}pm-wBkC-bE5cpC4hNay>i(@^sv zyf0fL&*h_Yt?AxGUHt!p8-3})bQ9j`jd&N1hHfa+H5}sH+9f6P={4!C$&x&gX1Xi!=~RZF{#t)|)DxML zZnpUQ6IJ1Th`ycVZ>yi{T~P;*%oO;q;BmQ0J&x>%;8f- z*k=9JkpWJB9{XXM2cxgP9Us0vezkq~i5?*PRH>uS;5U(*FOWNK4WXQ_@3aPO+;COXm^AFWTi(aY)TL%j=*1dR|V+EbrZ8Y=8Ir-@Z=I&wHCTfz+XO}Cj z%d~#MxsbwdoH@PlxtRN7zDMmYyzD#hGqi2Qd;AUj0BG@h$ZNq{t53MlSoOV-?a4Ap zKclh8KQD6f%qh~Z8~$9lMb4GchZrN7|E`Wb%o4gd*@**q4O-#j9{ScCLN`6OotozG zrWbrJqkCWd1m3r0ADN}RNBi7F<{h4eJT8#wt@RkKTa(^?=}YtsTNxRhQSX6ACcNip z=`y-n`fwe-5T4hX?Oyy{W~H7XM^%q?czlA<<#cl1@m!dpUbEw+sO`4S(tY9h&rB3A zn^S65PG(`h8%6yl$It?%{)}FpSv;>xIsNatoS)ZY(OMM!ZG2}O@9T$>3#~g)&s7hP zydjQjznf8$?0k&lSvYx`O#O@WA80lU7EX7*z~7q8=|0yGyzlcwExB_z$CuMnj4>hJ z6zffWOn(2a?Y&&J?Uhu%`IXog3pw3!w`0T+w#RuRb%&)-{_pe-dMfHkFEy`BLlrM^ zEPg!=(X;Ao9UiOdrBNq(cn$Td+nx)reD9H0!vE5>@2OO|_G@@uzLIvlNyhmhdS9Wr z_m;nwj&0)j+Dy-1GH}n(tD=oLoXU+)r)EBPkE;Q4eMW0nk#9@Cgni4x)8+h%9{X1I zNhcb*8C{MaJm&O4ng8i{G%p@w*7WFk$@?$sEBbv7{HOmM%YXdO|0Vs$|MXvi-SwfX zpXXXqb@aUCO!bd%&!*qO`|>;QpG&{}?lhd*hi+brx8n@;rQ_+RADj#R?5ra<4#*i%eWulbMLG>9KP^2^!D%FJBNpcd2;;Q6Q_@-T^rs^ zpI*XebeMT&^!2)f8`8UHTc|I612239`RZ+GEciJ%_uD(>@(@`qWHVZKdV!q7n`f%= zT`!Fcieu!Iyf;ZkvV5Tj4g)S@iX_-ho(M7Cd;K!a@)yQ)bk>vUuRqI zhIa)I441v`irmhkC&t`#{pp1_oh(N5baNc#^DAV=JKt~%PmPRzW2!R^v>Z)mc+Hu< z+EjCBOS(@^yxVxbsk_EZ?pQ-Wb4kf5?}hQks5S$d;@Tj*$4UxJU2#W8Nb`Z zFuB>?k+U+VImxCiu$!9G<-T&}^*2O*hv!Y1eT3&9gW=7!zR|lYYOap$To&h1>*CaT zDz;DyR)zMf84w z>tI^!m={wdj+9cV%>a=|lKl z+#c&YFSXIPv~DHd;uoXGj;|@B+t0}Tof%ypx;1+0o$|Cj!y2gTn;`f51l(+mtbP=k zX#~yPx`1|k5c^kuYi_JT-VWm?wRF8RYW3>wW(d0IGghBB55_#l@au5@e(tMBrts5~ zQN?(olF#B{PXnKi_rm^{+nsl@ALkIqn#X|}v8?KTo;vk89+%A6rTTd3ab4)Ub9sp|f1`hjUcYRwei`Q?b}au^WVu=&6Ph~T zL;2DretY=+@mNw99zZXaOA9Z%^L-EJ6@2gZ7jD@{UGs{^V$9&UrIgjZtUpa}%w_KT z;V5-Y+n-ODnwCY5?ame7hM!?y=7ZGL&Ck+5Zcb9qfoCIAQQmIf{|bGN@Z}v|M4tMK z>A>4x3+;USvac{^MZY-yR;*hNP&-Qt(SLW*c-6wue{EfDb$8$k3&%kds<2Zls9VD%@c{ugr~_3!9|FReB8vWxzCb6c!Swf<99S7*0ARDE4m&mI_cb$b-)-Ivuf zr>mv^t3UcTp{18{x?1@{R+rc9Z=@H-dQlfOcC~hSy|hPZ=5+HK-@P)CPFC(s4M)k5 zfK`8R?=1co`U&CtxIRt2Bz=Hxk%?k0<_8z?@>8!lOy;_Ihcjr+y-i2ckKenTCh)j7 zRh6aR`|dS->(r9M`VTITg+|@OeSZ4>YY_AbM^dnhWruNYSreBG;+REZ!~w?-+n#UK7QA# zXCqI~3~&30OtEtBz53bk0;?O^Q_|W!^;_9_A)kMqu3mbbOzLA?7a8gFTw(j7 z_YUl@zI?Hdo}&78sGaouTe}aR@Nslk{4hS3`^PcKbjv1sC34O^@D_QIE9W`=^1!k5 z(b?M2!_}4LI%~)r^GvsHk8DA6a)#J9ISW!o)(bCZpCe0AF1g;jFKWDGUO7E_E3%LE z(^xNBXy_03f%U8&r#{xqKtCgUIXYHUmo%@YiyBS!;Y$4f{cv~o_~-p-J?wd2-}wSP zHlD|iZeNOq&H0*rrcPf|MqhTAiacUTD>>tLiqk=hup(Q*0T1~ zZMxizFQ1+>GUwJeA4B8AD_f5Lq;X5yN6o9bEX~ZjOtmr&w^#yQT4W3w&%*?Qdjrm39 z6v?>mv*7g5unSLk)NbN+soDB$I^VD)t$Oj-s5M>`EG?(IkIY4vy{*xc)y(D_fVYNN z29Lgq7vh;zwZ&fdOXKzQCk&8VJz58+le5%R_I%`ISMNY;jXZU0NDEfibL0K{;d}M; z@ay1ZFvHtzm&qI}Io8ut@8>DM`#5=CzrLUE@Z4?sx$Jc%*E+WJ^KpJ+3NOixq4LNh zwN5&6h%$@+ebx(E{1^CNR(B3Z-8?>j*wFboJ?GA=#2A9(K+Pb=!OV?ZEFRGwahi8tV?K%j|`md*7CLV9+9*dr({d z&iJ9!c>vE6{Xti~^cy@D&p7*C58rs*>gYXTO~+|^f9h{JK$c{~F8UmywOiw$c5c0> zp7n<9&oD;dxsJo&N0?ip$DDjFm)rA7eca_Vo^<_AY8u`)K;47>ezgw0=YA*M29Jqu zedmt(V%*2PB|3mP0j1v$F9)l$-^}E4U#Xuv&aocXxeLFGkJ{fa!_HsiV;_~zC9|~a ztegLB>(cv|Ue0=X=~~t=T{54$e#q!=C4DlbjGndq%<6h+=Djd$;PeHozIxNnd9S*@ z9Q!osotM?EFSSP1%Q>@A4|~4N+!%S?%ocs@IqzH#jI6E)=KDYX?RlTN-WUDpa=My& z_PbaQ`X~6z)ztN*>s6Q8z3f`gx*B^audB7Iv;XJ+`hSJCUaGIl={fu5-lehh(UqYz zh(7!t8RR?HFHav{8xQuB+trfg(e8#L>C+n{>D*uwT69;en~uRijnwQl9Hwtlb!s5L zMTY(D53WRiq<8V6jKR*o^-;{ty595$Gk8qMShqJ)YbAOQ zJkwIaZ(QU4bY<{(Xl`Z-+@_w*bMfvq^kydK#Zpo2Ts&_nO~`jkD6^q|A#_|MIO$(*h){RW!4jIOqR>)deo@%8#xpK4~h z&*vDxTGG4t_#aS9dzbfid$K)pBD-qn{aLXoty+SQa_h?U;~U*k)2Wu$ir=Dz+uon9 zk9wu)=FRX0^-VChz2XluCoH2!el}}0Z+S}Zrt{aMU1T2=+NS5x zW8@v4V;^7dVH^Zs)b6F{49sAjNegot);XPFo?iy^+_dfO7bC+wGiF}P(k^m%zAmpH za(babd%w%nZknkQ+z#jJWjR$Pt5{n~onJ#4x%kX2z|a%$^z`ZSbmPp4bYpMi0i8vzg0q zf2na=_i9a{TA#To-PN2c=lm*a;rV^JHsj^?NOd}Yn!F6ObUD=8P3JXyY!?h{t(*I` z5x;+C^t?}^jud~o`Ilx}si$iunPxjC}l z^i#_LGJ*ak$6MAOJ2%xtHoV8eB;&v-#$)>J^})-QvaGeo=AWyd%2eiFf7X{QC+wzP zqCDLjF8aP-YA63@4}KC}SFemdk$Uug-$O4Np}MN|Z}Pd@A)lM|V?WV;^mmzCuZTG> zy|9e+braNxdK~I=ar~j?s5f0t_!ys!b)S>y-V@|sk5oJxIU}2vJsw)OI=VR;!{o4A z!>m`{+SD^><>60&)0_61W37K-1$i!b7x;ZJuU*FSxo1zVNSj{&N@V=i??!8dtFu-v ztGgZcG4Q?GJJlLM#{v4S)mXd9!PbLp9;G>xa=6FhFvn9H9(*}Y_LtqwjUCfF=JR-RK1r{OyqWpDRA0A;ntpYUv%;HRcziV{VX{00WFsoKMK}OpaR|&**j0kM4f*H{0)GAN$cdlgQ73)gQILFOs!? znb&$$K9|he3)#F>OaDBEUwB<9pL;p;xlHcm&u8?N_|*UYoF005aC+f=$(p+U7rpBG z>#b|mr*1E$%<6hza>jbDfwljU+PaKxZ=&phvDQ@oi}@_pmg;|z)3aAS*OKP?Q8_(( zU$U;Q_dIwVX7{qb^m&baj@PX*bx~W-te!P?c|GgunboZgeV2@s^($YYr{}8Z=VKP* zQ2UASWPk6@bZRB1{G%&_k=OX$8xv^KWZ=;EQ&#@~%~=mkJN2QJdpD%t{rE;|A|K|r z-oKcBa(^m~ch`~YI2hjTnXby{dDPnoOOfAld$J|99fuj(%fqkUUbQt{A36qqps8GF zqhDoFS7_fI=lyrko6al=v%O`U)7*Y>r~zHRGMyzO@-jIrjxF?&o2TyO8FFCM)y+(I z?x4`li|lm$>T4ak_1F$_F%GUI=i|lb>E2$x zHtLM@N9ZB0VH|Ru%+=7ZM@z5sHt$zx+xWp7 zb_c^+hiT@DV-s&LUF=PI3m?$U{(WidvTx!|UxMb&T=QK0sjP06ek<7|_Ry4%zx#X_@X<8j@wR`9{ZwUdpC|8|*bk?8ZN>?DZf*^iv+wcTv)|2f zH+RQ*gsX#9k;~(Gy$fB@&olBlA|Hn1ncT}G8=i}vwDo(KpC@0%_wG4g9X@p$viiKPu2-E!O<9e;l+&k}KQzPDT!2o-?tdGf z&)=rD&Uk3)bH9;Ry!e~3-|i0XjeHsV4$U^LBMjGklNXYMZL?ac0(*-QT~ysvRo-Hddz z&doWO)6H;{)wBOaRyPACXTRuwk=6CSxL6CiklEGPv%apT?vi=ky3)|s@xthfk=NDN z)z;;8J?#JezyFVU-+Jcty<69WKmGnpdwTCeFZGxW!ML)mHJ0Y6^pfdfZKayDc_?~d zu21)-v;8Mi?V-)-hj%7Y>oNMFR8z;)RY$MV33PEXxyfZ5Zb4@yvvIbsj?5Nv){kyS z!|zTXoo|m`N26`@!+~vYjn;+_-F%KqoHrhfk`u!D(|Ps1>*zPpPR1Y%XFZ+s$w#&> zNk_J?NY}^P(dldG!9enVZ(9`K{I@X#_)$C6nUmL_9)RXSdbfo*!Evc(!XX>e^ zh6{aouyHSak1EscGnIIamq(B8tz>1J>#X)TgkC6%)p1(~{vgk}dLT|6eJ3(39gke@ zKbo%g9f+(B&yCIGAfD~2K$|{7ekGZhQz!9ZEQt*I@6O=aC+lTDxd<|Y=Z^>DRlJ7t z*YE+nW#7fRGIATy*3}p7!{a%`{6an3g)WZv9Sm-7Q8jCr7Jc2@W&6Topp{JvZqvM}P&%V~TKXQzl?M>=D1pbon=EK#_A9mT zlYVluY>G^3`nkdy=B5ua7IBR5HyK?|568K$-Mc6DYv-{|(ckqXV++St`gD9P+24IR z#=d+oSx2oMkA;t>>ZpxG_mu@J(O~tS=(p%(4oTl{W}xt_@R{8h#N#B(q65n6?lWuo z^g~Tjt9GS_IR}_v482swlp7}+H-`4DkKk4heXr1l?Q?Fvy2qmXIWk&cl4103`CM<6 zbNL=W=I2<0sej7nvY%ts)|c4^dbsP4!OyM6XzgX_{Ct1SPEl_jj)fXdj=eT~!slAl z(_g{g@awVd*-Id+N5%#oluA4flMQe;EM@&@m%2LN8#(P1y&&bOs9S}rom0@qat8Jq zK0$8Bi6zm0XY}~ev~BrgF>Y`S;Wj>83LlIbexa%Bg;^aOXBMFBe{B2W@So?LnD8Ls zQSM-Wxv%`L>30dgHePPo%-qTgr^)qU9OO7)jJ{6#sLVvM7CU?%GI-|j%;gI?J^#8 z&GtFNn5@WmG5?#nPR1ZEnblpNri8ZyZ=$a(@-Q^YK$;@#h*0JU#43zc-F)ozGNTk1SM<3+ruMtiPA( zAGN8K8^kt^CZ>R_Z&VJYyB|$;dZkn^{$%3er3smDB(KEelc=NvgGct2$Jnc?=x zcbOeN6+ZTEd@uj(gLBc3==i?%se!DRj`}0%{75JMkY4oiJ*j&C=2Ul>`F%9>>7Ht8 zFppAe+7tatZ;aH126}wYYJBMxk)v)unp^lC%tBFvns7drIaPh?_FpgGj(?Ezm027W zJ2?Nh9!;G!dxD*BOm?L2Tssq4jhCq>o$q;scAjfT9c!40er3Y7`RMj2C8H5e{|u|o z@%p=X?{CfEm6_-YP5mNcfm>(0Qx)&)`*)@yJAJ67Je{uH8?~|eU;3FdxPzbP>OfWG z4%$P|am5MznZ748=IWS>myxVL)7Rnot`0A^S%3`(;0;(;E#BHpGsDeS(~Du>@CTE% z$=cc}eERn$8`I5^n&|UtuPAFsWu|@WUI-momNTgA_hAvXZT3EPJV`& z)W>%%pXc;@<2CrxYk~#p_Phx{m@7iB6t+{ADrz|4fbg%dUFeI2w_H6N4>;M49z)h- zI)~pHNCcc;`;-WbTFW9DJL-D{7!>adK*=4dNyr(biMZaMm+xY8eeK#LtmROr^S!`lVBf@M;WNlxt$Y& zr|}_}!E&;Ue0AzL)zy3P+Ng)h?)nzw^TJckTnpZxF}y1yHF%}!mY~yrBiZY+!M?2e za(I4y3wb+T7xk)WrRK^o52e4!x&!uqp9l= zknZf@%YUvNw^Z+5#&?_JF=|idI9*1Ux$`<-_W!)V^Lo1Mk!x=;kK=g;FXi>j z~zi(!69?@Psor_yBIa%zoVzz_3OI#WfK3mW^C z_BH9inkOP3ref1`=|cOKbft3}zd;+Q|Dm@swWHS29%J0;T+I;qFXr1?`>j99y#F!S z-SONQzq8KEM7;yY^%(h0&Z)@feqZ7}vS0kop7+6^vsh#7yqMQLYJa~BJAaXneN;Y| z%;%Zc^LnAa{&(?uDVvvG{ya{9$moUdC3|1~E}y!Zx_qvFp7R;K>>{VDsptF`v({bI z*3E2`*=2V*-Mn{wFnZLpKV43@mQ+36jP*P37I}?o>U!1nzvxw0Q_tDwdSJ3&J+Cvf ztFOE0Vb>4yCx2SxFlO(1X7;SHFVxr7)~!30(@TBpGP^xY?S?uGtzy8a-34{9pO zBpm5Dk$!OZY#L}KcM!e$R2_Ak_s>V}i+wsz)gDau(3ADZ{E)g-nf{->Kbtr!k!s>V)#^^h>0}sQIt&z8WdGJJJr&~|ieF9AfPouecSNhN&^*wU# zJr0+C_gq8z?ktRo*HLf8)xqlU6Uevrs2OgnBp>nw{hNyU0KMfG&a}roz#TMn`8<1H z^u2gF>*}A!=<4e8ERV0<=d=H+IqH*mdOo~*2LC=iKnELB7yE0RY|0}$*P^eJ`8ZY= z-fXqgE7Vpx*K9wJ5q{s#()&+uxw(BCmOepGQT#1)zLqAuBC_%a=NWU%)P**qUU&P< z(NwV&&qej-v}NUUJU{OdFHtA{pR-+ZFTQU)#~)7Dg?HVW#Sdp2(=GCz)y?HE^O0o^ zwNTGZ*6Mk_IS&uY_vT>8GHRLiC!6P@-&$|Ayew5;N`q3^@yY>S-ke1vs;`YiOa>q#&88qa$0^`X$U<>aC-lXC_IFJDDt ztS9fjgE@LVHN_kPOv6~f*U>ls@bwNwhNF3x=kaFgNq3%KZ@WI)ntkZ_^wb?gLwD|D zvh(5MnAEw4yCcV<-d2B%{vfJ@de$hN`_S()O&zivyJ-oT(7W(y;4jdV zU|s0-?wv80ARnKF6{o0&m}-P6sFyrRroVG5kyFBFuAjT`s=%j=59|{vi@TO#Wo>ys z*HfA)sh&K5ZY|ID99^D{Y+e-imCf^Fe=K`PTEpqM(Z~B-GOj*w>s7~USEg-C=vBYw z>4%&Ss~6nNHj>3+PToM(a(IniHt6a4)T6G}d=9)WUJh@*xh)*$MTX0o7za$%zm+yG z`D)au>akKQEoJmUwn^?bpV95okJHco@O`P*JBIP~oa1nu=-5V2hTq%Zx4GIv$1rBY z7jq8Q1*nN;9Jo+V&s<)*F5z&!D@Um3DC#cf z_`c+Jc|T{pxc2wQ-2UthH$O@qw!Xn0S$Z&>Z*eSVO|o+&ML$;FtDFg|JCEY~Q!^iM z>{a4{(#LncV^@4v!Eib#P>35=|#?b(TCT%oI4|x zWMFQN-l9vM`L$HHXDL}aOJQWQQJ1Eh^d6gLTb*Ya$D`hHU{M;bS`wM+W7SKNJxI5` z@$1wYzm~cVyqG%4{;7KBYxFsKihfAXrs^$ErR%52D&rmmQA^4$i;NFOs!?nb(@%;Qx^UOT}@q2jF~X%>bYmC8SCola=Lv(Z{2?{Sl#TG zQvXY4_1yo+9GFsGU#PL?TGPE=Oxe0`|s{dAcz2tAwbPM=Dj zUhPdIt#B>b@r{Sy!ArrMHN5G$ZknDn>T6TX;aY!prE4eWaeE0ZjXKoLZ@n1xwI7_V zhYOgC;JhvaJBQFnZujnYUQIu`PCh*6edpEBlUb;~t}jUKO|N$iy+ON9>`dRk+{)a9 zUTONra~@V>ZldRox=gaO187}&roAK4F?W+4< zA3TaS|5mz5UmrCld)Kdf?VB*qhJts|txNelUk*-ZuEBG-<1sTGGpE}V$+_>yEySZP zf9m&fzS+44YeKuL(PrTs>oc?7AH6{5INi)b_w{M|jOq`U({naVDVt|a+qLzhW<}cf z$c&=w@liLI)78yga5qv(?$rz1!kGxEurk4Qo z2{(t2rCVtCelGHLa5;10YHc~=yzmhe9)j#6(3fMcQ`u6UJi>RuzN%TbA6^vJ7>!^oe3E7gY8>Gh)N;=0<8oWp$MsE_ z1t|{?v6!P#&NgIyI&->p&S#r9hL^aNr3I!(KoKQr54YES?y8J$*~t+2sqtwhl@3X1BafCjK7*~FT`=_ zoWW-}o%gF>-uE+HfN8ih5^mG|pCSSN-cwGsLJ3klqFS+hB|IcaXS+ACj zoul)AFJEIkYBrSP2^qbp1EpsbnfVu6ontF{t~!?U7;$mG>7R4FUu5?b8vFHLa$`H` zxyy0Y!h3VR&~c=m4>{dMPS4{6b6K}6e>$>U_29Uur#qGyLrZ^myv4`nx0{sA4|tKK9;sG`)X?5@px+A z{X}Y@?`TKaV`=BoUys`2i!H11v_FxKQ)6oot=}EJnI0D&x6wD3V@f~N0JR+hXza4NewWC# zbX>&v$nW-}_V>%M^B4KpN9A+LeC}Efcbyr%l+*L=nalIKl*vEua^`f`f0NN4dS5c5 z=XLhJWRJR9da0hSex8@i=((0uR?q#9WcBP>&zicrx~wjz*EFAsJQ(XqWp#TY=~K5C zk~O9Bx_yw;)Ln9I>B4@c@_MPxo_#S3bJjDj>xEHc&;JL%|LkE-OsUQ;!$U_*t$` zoT67~Rr>w!UZQ?EENAR24w{t&!j!Vo}9zmNj|Kb#yp&F|Cy88T;k)|}*b}UVk zsi-&IY{rYDo#^6&;eD~ssC+JamvXwbq@U5$;q;=WwD7Fo=5a0)JttEq*)}~*mFau8 z#(Dpp@m|e;Q3Idtsp7phrT5RZh9Bh~UJ(2C*lW+c#0zLom(khmrD*M)dU_-N?dgcGNs24p|wIzMX>-6ENI1e|QF`<`5UqJcR zH>kB-9ex?-vE`CG1L)~6gj%3FkLMDZ_Z0V&(bO2vz)a?p=`)sl?5#cs>r`&z{0E0e zb|8B7)&BBSvH4|gTa^xNTojp#YQNKHYS+59@!32>Z%LTDo~(_f-;TNPlLzThxuBj@ zPWOC$d$=O_p}i7q3_pm=yVEDRo{W0t;GJjJ+o=}i`?0pv{BkpF%*}94Uro|QURP6} zp+ADzxXUIS^SlcYQ8$XY?f$^?uf&nR9ocb63p8o7e4pgX0)kAo7~=U+5(YU6gUy z8Rka(EIW@Zg@>OCKaIJQnbSuYqv^?L+5blHa9tU-c4f@laO{{l7&;-$5uOi@q4RK( zb*8fF1pX3z^zvus^Sr*=xh0)#T$}c-exi6jSVoo)Pm4SQYwH6)MV7T08`f+%Z`Kd1 zyG$_OWA=(Qq|Ic|gb$tZtUiSm+BX6DN46LJ4sXeCp23;pZibZaV$epS23oHd{DbND>-y4+g2d=8U4zH^>S zPm9`l;Xmhb@qIuy=UC0G9%~rg-^$B9j3=4Pa{Qow$-5uIk<4d5*GM)$zonPjsGXoM=~>2morhjajb)4Cdau(HV~(feL2HejThSwB zEkn%hShK*sbNr@XaBOV^{9L<^7r3o$y~m0{dsI& zdR^x8Qa$}|^7_Nfm#nWZU48w(|Bs@!v^2L-ZM})Q(C^)zM3W{rg-k*- z!>uX(?)8z>L60N-E+5|*!|O5)vk#J!2s^dGSf}8Svt+J}wUg7nJF*gQj<-dQ;zTDk zl@(<6QfvC&#s0{C`2<$)Z=lyC`6f-U&JaCp?6-Y&pdwi4YBxD_Xm90PUya{==h@9O zv_7wkobIx9i__i>uP1%(r>Rr5*O6H-SMZcyCimqUp7h&unJ?DGUL!9(*N@8U;ZL9Q zs7D>C-t_RN7vA;keYr91`~jYJG8)Z*9OiwRpKgwO!x8!U6k0a9Zu>Vx_GEW$S-L)4 zovsa4qPtq(xF0QaM=*noB_ElGt_P-U!&2D3E&b?PN3fweF6y*u&hO8h#OukNG}_Z7 z+UyKt0c%N}(>4R;djI}7cN|#vEcxk&qt}Xh`!v1%%HDngulloSqnvlxg|TVrw>S^NTxf{);{;ZZ=*iCGJo<08p$)>> zva0=0-45@U`8==n+xMV%?qBm1JoIufUam2)F5JGk>g9d(EgHa&HNLDs0Pqv?J*$`PDMTTUNx9DT~;3hSG{lr(=(7@?~vwhju8Am-Ha|4;v zeLs!^<ph1|^+E}ywPN2h^AL7`+e8$2Dgy#kQzJ)mg{p`+1nV)GE zh?$joU#z_x;rr!2xZ1ff?OgeI9P4trb5TXV0k}AGdS>v2T)y!Cd_UH+)Pr2&_tNZ8 zy&~2-Kjien<6V3|9@cM0&m%Z}mOi5T+qNwIMtt|x&z_`Quj%VwkV-N|DGzoYI0`zu}S zImB3XRn(%sJAlW(d~tZ8_S0i%n%_n9p!}^gyVl<{vl^X`X=EYE5Am4>T-@L z9=rHU%qgsnT*z+vCHR=p6O0?kld%WbNDbNfaJt9-cmw(A^g*(Zsadzq^>|!+oVwqv z$I$Q9is8m+?{AvFqmRx1FBtnRJ{#vB;E>i^?^{?AzC^kDTlpSrC6!v~jO z^OJCIbM*3jpFX7ht;gtTG)gbhPW&aU=|lRKUK?#nKe#=L7ri;{-@GDS8g5Mcw~+l@ zy)!i*+mpV3?;KukGW_t6-@h<`2fjPB;_u%YO?T1Q^>g>s?xZKkQM|qM524Ozh@6;P zBPXIp%irs=wJ)VZTk$IHc`NN%|5|!);&{4BZ%fbj>z6(ij6B*715J0Kr=Lvc$fVIL zf0b-T`y0h&{+H9uteNL?8NHO#)zabgn=CSV&VKPe{(t|{2>Cc;JYPqQS>C4~)OW7Z zN9jxhe&oZc9%etua-k0$e1hxnMR(HcN1u8PwWNBH>+!Qx?PTtJ|H|~@6Tg}6&vvJu z-0F|~4!NL_><()Q%VEEEH1x*9oI`n@wxjq*>vo53KMnhtF?fBja&De|7g^He9-#Bp z@AWyBk#q4x%n^r14x1Gt81Gn=t|!dS-MzE@p66;Pp{c z_r2xYW~k@9)K?YHdy^Vi=hCfn^W5gSUG{c<+@2`#V!`*`38(ZvCEpr_M2laSLxrUlslznDOX# z^j7>en^wM$?=Z>k&jrYCDSF(vd@~UmGQvbOuwDb|?!;7qpA~VB& zC}y?jpYYs1)k?1#STM5k7+ckI+^EfY?vDjlFY5m2Rb+oqau4-Y%cknUdRN*RpJhhR zeg-vV>n>-T*F~Rpv(K$7mcxS0@WYsQA@{4x%czC-qsTwceizr7(Ot`ZvW#Bf6FU}% zr(Iu*<2kv{@2tKZ`R?fY$0FB7?b@-S{G(plz__BD9+74v`MUbY>(Es7r097ur?pf| zALjPM8=mJm)}#v!`^&*oVw2%^3l;> zcP{@XnXpgA9Fy4|a+mMV=g|w&i`QQth~p>ctK6@y$H)vn-?|A+e|386`G1<;dG*VT zYu81VQ=SL<8=Nk;mo6n-{uy7(-1T}&u9BOit{vksz9Vf%(Z(|qvsTA;Y^m;HpEbvS z)A*(?bdV8A56?k--Hy{8t9iWmxpbG4b-3l(bPDEmtRkN}cj4#aZ-n{k&SSU_&9c#_ z?Yx4T@>Ju7sDUu6(lK?`)1w!}T&{~5se0qhWV+MCI0p8146yOFFVTbatLg1UUkNs! zCCB!9A6|OAR=&R(G8qr7dnSJ0)ExBfHIm8W_Bh6{kI_`aTcMYm*?9WkOW`|j+WB;9 z+VxE8;8=6}&025SOaG%|Z>H&bvT4Z%J-qgtT-4|r_1M=&0S|+FTFl9dtR3^x?EnmWF7tI@wz@2xm#=5$?b)~Ypd5!YA zSupl1b>!rJGx}9_qx1zy_~KG z#+p)VOZBFIUcP$vs~0+YL%MfI>WoL{_x2RAW4ew04uBPS#8WrRLU z=keXh=7p}_HJ>Ya_X2($>PpqrT_Qg{`(9vldA!im^}fLA*#k4j?ZN6ihrL|y&i19_ z2e#l#=}4d8OCN1Nl4=faVhqChx{b{2Gj(|HEAYNlqoW>yGp!SZlPk&efPL%tuOip7 z=mT;GzmH7PjCQB4={)?Y$Phdnx#^B&)O}~V$)bk`U8~Wmo5{jA8RL|1dYN;V8dT9Q z-kQH-+wpDgLK}kJovUxdKVmL{i}U#QfgC%zDbBG+;2h^}gQws!YpFIbdo23<=>1Sr zHd95-+H3~B;Me-;Q$?1UbG-Ipw1!Ttyons@HnJt13ow^3vv{oM`jcA!+gHbP!OBzc z@Kx$a)ynP3a(&=Xc$>@`cAq)NV8)`a?f5{yyzC*vn_nTP_tx#e=K|mIdO3G7^SA7M z@(}%YU~{$ezl+hmf97!Rk-+b|__n&$aJn~$^*G!Hb{N>n0@38f=)~Q(&YWBT3*M2{ItbFb~gFcI* z=8v9@)LpBQ+kdEqF;_5xOc@^P!j~Q%7RG2YdH&zmu#eS9)vNULq6QRhQEQd|L!;%`lG8`%13!&V zss??t751^d^en8^!0|7C*^9`Y?P|Nz_}x9Gq9+q9q{f~(U4Oabh)J^2M|h6@BQH{8 z`}NRuof~kwT-4I_-|Gju*uI{6!N<}Gw$Cv_A6_(j8ugN)EyGpgo2Y}s9J@Mh_4p1> z_c_qx<2kwPF;UdW>Pxnt6URH_8@=9BwM$YnjCgD_y;HZp9-MCef6N2@JPw!D7vAJBdOaDSM$A+?e&nE|Fe^v^tv77LczM$7ki92&meDm z{JitpSJOl-Jv;GfTeGR}KBZ25o-m*s|1$9^bg@ zd05}EP0{zoBis3ul2w@N`Jp7C;z{F z|3~4o$^4ypyp+*1hv(Z|dtE7q%jgTQ^LDRyopo_F^{kX7$YNt}~~r zr&~9g_4Lf*u5D-x9>CQ|~`u>f<)LMnsSxdiqG7`r+D$~Hp zy{WSv&grU8X9rp%!_bU$z1Hv23+R0RiReSxg*W7rE8W4Lvh9J*OJTG_Y0tWs(vcmj zB6I!y>3TA$_lCda0(Fz+jf76m=?sj82xoC~l{h|L~pw?4wx?_WD zWV_sltBX3)p81TIoT)CC=YFKY=izzD{`68#FY;e*;Zv9O@8N+tH`L5NslwxPD&3f9 zPbVvPM{Q~E$^Fse$=<3>73%AoQq^uaz+4wtQ{LUZ{*Cl6-XB2^Kbk&1-x%l5whFXF zd=UC$%vLmi*mLm=o@lk$VdhKKV%4F~k~4n|E&Xz@9KSPaKFtrm+DkuE&bQ`j+q1=a zSTjb)3=@Sa-k8FW|c-=amdHsM$KY^_9qmG~@7m7rqb} zU0=QDeS40}eC7yN(-*a)3XPWYvYK!$^9K56%sK3){>^d5XSDV3l^jVO)SOyFT4>6< z(!TZdkjLvggzv}m{23TrPq>jGlG#tcMr+Jf5`mucU)p zmi?{Td47!R{5;c)9rUov&GwmeTyvv`>>1uu#f}xh=FV$;W>HJWiyoeIwDhy+==ynN zm7*6D$0&?tMvVR39dGC__chE_JcEWl^Z&5-o=tY8*>&b$mYId``y1EPs zWnc@g;Jx=iB9QAm;fd+&Y1yFvkFyNm5;C57y?$QDJ4Lk4Gt8i^A@etTy<`{V`= zvQbS=Q4uVm1`#LD&5L_)UUP1qXRmkdwUxWbXHb>8PoI%=Sm~DNvCO$7f7x;XrR&n4 zfq#k5vQOEE%pRgInCx%nE4qIL9o@Bb7@E(E<0$(KbCq_=11?SR)OztW>-frIQUB&- z#Xe=+tuy}#eVfd3L~q9vMUMjg6&z1-9o;WGr_WR$3CFg6PdNN**pk!*In z_;^(!Mv`Y;-kiwCquYu1=j)~U7isz|Lj;rC?OV(dZ9;ov1*!O zu|XX&SRQ$?E5)ES`utj@8#IVbxexDcoBE9L(?zppwWc6H48D&N`J9TR3y@(&P0jk( zynKK3Vc=zBKE@4k`mKgTVfWf^g}&Tvq4FZxE9wC~udH;<#-*kq1D}lZ>dPBLhh`KN zh|!0N_l2YbE0wSKPRKa^mU)(P&%Uc3SZN>9|9kSJ52!B6J+oHpF5+v=I%>~Ue^c(} zP?NMKbj!P*sr!|vk94G1{RdYz+IkK;dQZ+4&Bj_`k5hVKZI~#PPOcu+wsd92q(oYK zbL!?$o2nyj$(6aahyged0Z&H-b8kzqK4g^uo`#rG6by z&|c%;H*!06nmRc!Z0PE)m&4|MnLXZi*W~ffcs{%9?A#uY44jTX zoy{}VozvX|<35-lK3ohR-xvxXYbNPO$|JlvCf4q&v)69uwv#m1mwcKll$88pOj1^4mlndS)%r zKl*|EIXA}IO;ac9g$-V3qc1e-C0)kpuBp3@ZhLq=%3F`TFg?cU)Gm1R>7kv{Jksyq z84KUP*%xw?PstCY+<86EM$Kz2NjnvO<7St!Dsyr&&hH5acWQ=<^x!V(!DvtLIOi|s zXHKiH>YCPtJ%<-YW2W|G!zE)K^m5BNE=|<=PnuJa^lJr7v+huZibEjm3J0J$F5S(?Z4S z_z>uoBOjw%y1Ms-;v5Vw91N&KqgC=Pa)d?+E@~ zeCbif9yt^dBbb)H#Od?O3o1-thKzhE(k8p)&n80}28XZv3igD<8@?e{*(uF=lkq$} z3m5mPPc!}0hF{9*i_$}<0N7v(^{iFBaXgaCvm^J3ls8Anl(xKH$eV%BU zy#7c}$ICO@a5jvT9SrAoy%JzhUK6?O_|wsmJF<5vJ4Bx76RWL981H$U(cxIuo9OL; z&3p9NwwIrW*EJ~LJN<_9mD^3L%{n3f&EA!oX)A`)x)AF=_)wh3zi5BEFEvPI}|h}NU@J=1y^wKd0F2eqDhu1j>^ zC=*@1ANZ!o<<#-R@y7gDW&?F=je%Z*;-u~NH-Z{4ssmYHz#oN=j=4me)U&bOv~=bb zEq3aAuKJSa(W{NjqPyM7Pc7OMPH+9T7<_v;x%DOU@n=ZmrU!LSz0$1lv1Vf)Gi4>- zY|(sUt-aLaNx8Z?^ki?g^_t{EZ<$AaNZef_oxEOtmHacS)c?6#9-dvcF4CN~CFGoZ zGvpk7Me7^V*DtRLotZk;l+#$Ap#Fg~Z`2#Isf#V;sfOGEo&_ti$(Ifk?-_% z`S)cw`S1HaUx&}eJulAY?BmxttNZ`ERvu?_zwF%Zw_y*T!{Kr5-1(e+oXOG7xh>Z@ zyStu_=Y`GtNaIZIm*H}l+_@Z|i~G`H^yPYba%Pm%NKdKfHKMP(7Y2SuSBKZ}#lY|G zfAKt+I}f6qb@#xyE)J{HTMBohkvp$DyZasu9>&Kr1F!qsQ}!@A9vL{@a@YUkADZ{& z&;I=Xc#`|#y1MU~g#@qPn;VK|7|jia-~Hr9nCT%~Mf&($U-)pbFXX43HC?$ZOL=fD z`Qbz5FXCf(Fxe6o2I`d0sQWz{3k?MqLu2t3^`%w?<`MPQDXXrpHq6WG{^`vD`PkD# z)}<5SlX-FWM3v3*G#{e!3GspOxBi;4)hpAFg-2p~&U^40T7G*~PMA^;X@9erU;U%E z)jvw^%MD$I&B;+`kCqN^N8Xoi)6-#g^SnI6=W*{##OiTgXV&Ss)(b43U26-SHMz=x z845prUvsWHO67gYF>asjQa`CYFyx(AWuFf}xjzzqdao~hGE*BKkCz&kPN~n7UOT+F z_>eibq1kd?BTw<Ky3*S5y{Dc~UzQk?JjMoj?O|9p`Z~#0 zx!a#_Ss3(c;@!sIaz8^WnwZ->mYTSIQrp)i8aMcO$VtUlS6A8qZ*O0rGY>-mx2h))+E zJ?jswgG^~7zh$bC9P4P-IGQ?MqyhO^&^s-QLtYN^3~TKlM#?%Xe~3K$qgn$&wmb2`jPKKg=uDW&q8nAR;F5Dl8SH}7mvv$gxyw(`qb#yqA+$3^gm|@eN5owzh%HSB6cc%O* z8I;lQ;d$ANB6;u0c$u#~q&cYHHqVQ3y6P`_S9>)-o-FN@BX66poplUj^rhMcMu+wB zX7jmp$|Fs7Br`Md<>ct|A$y%UO9N@IhFx#}FP1rT_2_Er7e?3i8J*Ozab2C`m|jr! zlgdHGmrea1zYX;rGvJsbK#k8#2L4V|ryo+T=vCEvIxdu-!g?1v`$!#mD$=xBt08Yh z#~-~MJSMlZj6fZC(d-@aBrl35_1bhCn$KQ;SFATcua&wFeYi$_#`x0hy%pzM@2qOd zapiyFVK3FO$Gk4`8Lz8%r6_5K`f|jkdTvAd8$s^XgFek{s@M^>to+B;H=1*1o%OEb zKgaI`=i>E()tO0zH>N!!>Ip@EFFgBpDAHDzuqu=*%Y|Ox##C{%eD$qqn{9oD9#_j# z%+!2Rd1CU;uD7|Rxu@O<)J`QAOZZyv{spo znrEst$@G(JwNA52_393NKQy~kHN>duG5r11c+B5w(D94!rCvTj>S~TVJTFOy*G2v$ z@j3mo)J6uM3>+vrA!h*VEy282d**{p}~Zy0bdG&gJ+9-{WnE(b41SPvtspgD1vW z{b%y2lim0yfBI+PPyg)Ct*;cXy63+*r?ZFE-LF0^KL6;(u;n#=c6%h$7GAX(roa2) zWVkg_XSz7tes{FiG}5YE<#cH#=@0LXidhHbBR_BRfrd3J2*1dpGFcuk_J_ItTFX%R zXi+_xy1u76Eu@^?6X}uS8n~=RS=*ORD2GdVg`B6D#a*DeM>*=Zoa-u(pZ$t?b3Rz; zkNht3rp)v=8MDt1wS;-{Uc~4R=GF76Omr?=CZoJBPkiaW;CqRAU(Bx_>FW1p2g1X} zA*~hYzM6r=8beKCN_c;!BmDH?ROqP6)O(X0K3-IRXj_5S5R{*obuMIFJZe3o^fQvr z!kRUH81!Qp45p@U7G_UBv(>uFmWjW*;(B6-Fpd6sL$) zv(CzwD{XyL*_wEp+Qf;2>RqeQeA~Qp8^r4JRVTbFU-fpq&uIVZ{nT+3=X5+Tw>1B1 zqUNOO=`~uj=QD}?;##vWlJ1?M96EVX+H>R^&PAu(Wc`)!G;<*{rJ0f^6VD@eM&~-# zZ1AU(jd)ZZUsw%~gx@CO=F`S@cm{Zl_+MZiJiRcw>*?fs;I}Beu*JOUaZbkvJgDb0 zRjIxU`5y4_Fkf}F?11IGJmqveD$zV6>X>-8zi zgEb{Mo%akz=RF^h_X(YOLU~I0x?OL9yxsCXP#aiJqcTCpN_K@c-~FG%-c|prwB0pf z+v;yyP9dC5h7Jvim9E|xec{zbHQ2Fdsp@MLisnU zfv1$i!x{`3OfWaKINw#~Ak$yWTw1(1{2jn|hnEbkn~fQ_eDAH7S>HeJPiD=gNBQ3z zv-~Y$4T1S+Xv6fL;{~EGow}QuqzTwr6Xy&D*L_Ukp7J{QcnX54yws z&hw$;^2?e<`;CxydX*isE$Lh3C7~ZeJq*&p^Db;N4;SlK%$jIO-69QJ+V*kHXb?}+ zA6j>LeaJrXruBF7{eZn2G}j1rZ^{s-r){%dgH~m?kiALPCK-|yNt;9R5pj5mYJ%iV zwswNoCI8H7)62<;q2IJKYm0m@TS9NH)|{lzU)cY))noM4p5FbIW!F*{(ic=CUs!{B z89FpKi8_WgIR2J1|APJ#dT!?B)2mEVKeuX@ugkwL!^vNT`@HC%4?GQvyC&{j?!3<4 z*_=I0?ms(=b6tG<#op0F&#<|(IvnnLxpTVjo!9*~Xz9!%MNju!7j$&@qsKGTm+R`w zc^ytqO3exJJoPxY$MtpQm(phnucN8sgK6sQHP6fV?1K4T;A=SDHFdOcSRD@xyzb17 zcir`NuH*mV@&}JUvK$#aG@d8JW3u6yf!ER0Jvt|I1Gn z%>Qxz$W~>p7e<_}xk{G%s7#sn)rY#!T_mrvJTc{3x7B=6a$p{gDZiyz=M`y0WWZEp z%9AWFdVccB@S{8Z%0*GHmvT3<5|vk>Oc|cr;;?#JrJr9{-U~VI@Ve!w%lm@o<(7I! zJvaTC?DS_i-F@nPx{vevv%30ytuK%_|2rRF51-!~4~6L$!tZ@NuexMRUYH8Ya+&BT z507R$!javZ!oU7>Qdxl)Lf)lAs$=j~D92m6?MGA9@^UK=QLOga^=@Tds)p#vQucb5 z&BA#!R&2AL?hoWd=Ui!tNr%^)CnZ^0FI54q}#`O7VwShW=UB^2vC?w?5UHW%WU~au%2K`BU~*T_BeKn>O@)yzL(hYpq8< zZoKf-%8!K4$@Fm@J+7sboe!UrDRXzAP@jQbL$_E;KB5uTQDlxzXwDT`71`&+8S?nj z_er)knj{(~*?#nd!r^$~N2UFeXO6Dhl&joPF+H>1c?^6PFf)B@_^JowMM*idA{^NG z9py?NwCo>#H;*6pZLqchV@}9Rl1uL>8n#%qM>7}kIP?}C2s5?EL#BKr@H?JcxC92K zzZu^xnJtm$_Nk{N&fxgB=bOck^0>o8k@gzhHtLm#`d9IU_lu43+>pP`d?py3H5}jb zy9Ud&{vzKwo^|JR(|6S~T5ziS; zU}M<2@*jq8{mTCo_O1Pf^;9$GfIM;50@2g)Vln>*?@FY5M_w;{D)ejPU(S_p&2pCD z^qBW0$~n^UukRbZqtvlg`i{_(%(@nw&e|4U^YJ=mC+hRZHw8nNil3S1%lZy|rF`dM z_2Jqi)s9-@)bYt<@Yv*i!t7m^39l?ceWuK&ZP#}^T4PYZvi^_tAAB;Cni0z9gci;W zPkPITm3u>WXPsWZXOFTTH&?ws?0oxI>{w-PL*a$Z=200a++#IXy4Fs}P^Z6ux{bbH zGBnG@(p48%ht7nlY|@5tJw+F`x*&~n_9F@$D5s65hX<@n&6rw0}O zr?;ayd!N;N)D}G7hl80`C$ru~UBj9L{cK^Ek`zkQ^mw65^`sd?(?d&>(m1cf z=lqP%#Wi<+hVS9@J7RQZDv>9{-kBfo3?3T1?DUqBuTD-Q*)RBC;PmHd>h4wl@uLOH zJp5p;Cyce1+3eDL^0wTaY7f8jcuJXzouRWT%dQ`4DhSP`DPf?wIFx56hTnWN8*UC( zhWh*q=I0*ktPrcCcejMWrhLme{CK`4JesOirugpg<6H8Q57()mw8Yj>nPZZ0aJ}j0 zt!46dNMpuR(^H!rKACF_>FPtZKGvFS%X)#+A1(|;xi8Yv$xpXAN8M#95PM>

$CJ=G-JeUX?+f| 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%0Ai$rfHzDMRpd{^VDCuPn- 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

-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

!0!6d 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

N|+sMv#s;{LKl-D9eZmhTot}kH`;W(Ki0=Y zBa{Bc8E3dGq7y8WaLEGb`kA=k

;3f;~dY^T*KxWm$7vIt?^_pr?#>lnQLP0%TGVrR5oE;PJ1aQUElh}uKL8I z`j@U;@}*k`Y%28is`BCS=<#!(SiOYsuvlAJS8Zt%2U}<5mFaCva=5Y?gIM0XIK9f{ z`#@c7v2}~p?TkLj^6F|sUqZ$r?)~a>vi*GjD6cJCZmhAdr;TvBvyf&lC_7nkCzf^X zeG%*z#o9QVt(+YlKhvAjy|AIncWu8Ver5|#Iy-ynd-v4ex_kdr&-&CEXU@~AA20vrZ=WlljipVeA^!g5U2VnehuZSl z-)!p^J=I=6!5{X^?ON^M;{)c%+9%u2r4N-h_`&wbZ+xQdT=Qc4(Y0;uH$L;ToyqAZ z@SbpVVrBmxIJM`McKhs(-q(?Bbrw!B{E6M=C*;u9*3V8Yd;0ZB?Mue~esP#s98MQw zar;Qw(G$Yw<9O!!rJZrR?{|Ht`pVzQrhdD8@VuMV`F|OFzV!1*C-;=bjxK(^!tL`1 zy1)4!+&J3LFgjN{rE>>MTh6xrE}QzGf4NqBN$J(Nxy!4OYH?-TK-=KUoZBKvYlT)vcAqy;>*Q3N6s>}&vZEJ z$eE)2@b6vsa@W7m#9;LcrJJ$O^tW&9={odB%BSa{&5OELhBk&K=J@tH!?d{h+o$Ur zZs+XsvG_!tlUsfr`F|-L`R-M9zUaDQ>{p(veW>&6{)yU8`mMgFl+VS@rDr*{ZGLHF z=JYd@dfoEd$oGr0k(`UfZq9ywW&g_lUU$2C?NdFsb8-ECwDd#M)_o7J_t64;=$GUk zD&i+>gHIB$OxQ6DJT50cHe_r*4&n6J%wtoZV)WwkpZnymOa-it!d71GPjkL|>y__@tYu>L(^kfn z^;K8fVNh}SG3nT9Tt0Q=XI!bDI=LUWg~!|rn9hC5hs&@S-ojb<%KkRCN?c`cU>FnQ zg}KEUN4PofSYqSBn3>-crxyo@(~T?ZqrJ45`DRY;m9r*-a_aiV5W81aIsF)`x$57y z1x{5Cvu8Zg!=u*Qby!z<`9gRf!&*aS@oj>7%IAK}#nxCz8Rb&8Gd6afY%}dnrPmz7 z)!NnurWW$-)S0R`$>8R!ymrL$GlsOMjP=Qw)9y@8cW;exx%UHGvTb``*x=*e1xJU| z*~{6!ed|S=E_RPe*`u|gPW-{B>wSwoJ)9oxdi<>0M~cz0IiD(Q@3=lT{4h5=xVNT<|Gx9+m?Q7Tw6WpxF=9{Y(Vc7CZ{02*H07W1 zSY3a=&OD+`xK(G9E_vbMI{WBgd*jsR^7-OP*jB#qr8cY1J9>4&lkLUFzC4^u$`@eSVg=`8e(zF+%X|Ai#N#_w z_iqFK)Gyi7c(l&dEUo(06UC4B%IW`kTJvHJ!s+4g&gqk^&YnKg|BG_r?9|Qucunti zJ+n^kQ+_6^dj{r~XAyfkpD$y-FJn&U=jHX<_j}{yj`p4Uz2j#6F0pORyw2cP%Fcc_ zPM@-=Pjb5b0B?59QTcBy`?>RwaQfBKsME3!+I3nNXPiz{sB=wEZts3!XrnHc{^d-4 zW9{F#sGn`>3?#l?_}zEjsq>H6(}(j**A=s`>$djm_1>J{v%K5N>0@yE#R}(3BlG%+ zYO}a}|JqsY;3k}2d3=Lbpr<)moc-qU)$Loq{<#%y*ogw7T6Mgr4d9 zNBM<0xqV^Vx3>I3ZYwSOj>TOEb9vvgdmyPh7rBox_2a453f%cE_~@yz`(l`cFi-LZ zuADv_NWL_T9Q$^7*?l+~Q;#_vllKsNx_A`udu;9O=&_}T>oGf4*Jk=izv1+7U1D<@ z^PPKn31PdibIOkyQ2n%#c5^>oGkMw>;^F&e+`eo1VM(#^XYB6vizV@&>xA(bX7+6i z>ZaZC95cSu&%CvZO%vox!)W@Btr){$F6W)I`LPSK`Qab7Qk;e@aboA*vR!K@V-#mx z`gX6+u(B94c77I5@~?7fBXiKc>$H)zk>*-kuC)yemCr#5h;`N!N$Yu?bL;4L7BQyAn^>Ce1)mGPhxA+8Os4oqZnTv%OED^IeDMeFGR9`?~$8c%C+f zeuW;~_XQpn@N+aQxI4CTc5wQ2{LHqFtK&maJ^7fNKN1(v(JAf~B%uWL%*jLKN?hK?cTXr@qew~UZwIX3d zXVg3Y=*{xaXz%9hXG{BhW_Raw9DUW9N5xqDX5Xl@L|4y$y8YIz!|g`-_;{nvk96ky z$?|jU?8h_Zzi!ilhr8Bb*UHDskNTsX$$ofwNBd`Q9cg>lFPQZCSHAtqk2*hq^zWC7 zft;1USKGe5F@RcCgrE@Y1>PN!GexO{fkEA?+J z8kh=vH4Zj*+V#Pw`f&DP7buT~A zCYF4o-p6m0mgTw9o4;Jz_^0c-e5scf3xoR|NPB!Y^6|2_+B{q=Ke6JO^8509x2xlH z8n2V(C+5Tc_c6TQUn}ro-;)oj7Z%4*7$+PT?i=_un%-%h2DTh?`q;J|_QdJ2t7GhN zy6bU}j>Y+hVK;Y=!^7a(kS50NVr{eCr!V7-{W^2Fm)JaqIS!l~<_l|v7ZYcl+`CSC zVr^+7>y~v)EDsN1CD-YHVD-TktZ#YR6lWeYug7IvCn&FfZD+jVwCg&oENwhj=>j&x zy7&)^;T~*)AFxX7owyC}(MG6a9@Gw>t_s)q-|y{`2sJ?oix+@|paDfDq#}hESZ##i*%DsTK_mv%7z|^?g`-S7NI{Q0zmluEP zV)@$1-cwxe`w^$R#^ma;$7?S({jk1vF~73vVCC>Tj>hO%ooyYvV|uKPoue&x?eD?g z1&(%RC~n5(7@fVIEge^5Y=MnF8XUHBZRk5~`d*Qq?*e@r2gc9Yr0n$=-QLna_`?bn zWA&VWgbicE4JU>Xr`d2g1Bt!$Qk^q&U~8QVS@zVo%ht+n`o`&P?Zqd)R`%Q4>v?`} z`=@Um@B2#mTXYW1j?x_Cp6{J2KOf~sgMQ$|mN{kLe6stzJ2&xCJG8DisC+cO@W_|C zzin(6jq|ng=l6rs(;O~;>U1v`%GZcJe z={+v{`Zzx}_HljJ;qb&s%es!!?^JhOZsr`aUv&IT*w(uyrflmtolX79@m=-%!tVCY zl_SO0#oA?4|0k~p};f>>+({GkN z{jJiz9IibB?CbFXgVhJk`rr$O&z@-2y&s+>KQNx>a9(M>2hJzmTl`H6Q;bf(P7~Ap zGnUpR`%Kx}r_#&*&M(ZZ6ZQOy(d|3EQ1|TXCrb0eALH$l>-+xE4GX^2b>z2>t|_g{ ztkR?`Zx>4g!?z+0%+c~e#E1H>73JS?)>qoD(!}gpQ~Ou9zT8>d8K@!Os6U{qV+@`+n&&JC}65`sMu}`+K>+X#2y@_Jer)!{*~TY!${0UxxF- zm*e!*naSy4b#2MR(cy8N?ONKnoNED>vy&_18XvHK;sOk&%`vAdGqbIXEAtt~jKc>8 z59^7;jmj#QH0fc(TF8E9`9z+{?o}*hgD9NPEgXp-s$aoOq5M6_dHgdVT{iCgTXdhE4l8 zCdVS**u=)6ZSzqF(@Ga-UnP!B`Q*D-K7FOG_LMh{)DtIQaM$LNG8t=sm+F1W^BK35 zvij}c6_e$Z5t7y!eDqs`^7`!g=3hZuLdNbIn`2wHa_1OfY^;sX?IVpY9jkk1<}6y? z(~^hp)njk>jOHv{-tF7I12MON&Byw5&n+w-pN{w&r+W{LA+~ocuC6pe89{o2cVHaY z>b2)v1FzG$W9INOTRA<7J)Z2}?B2MV?cYAtXw2E-oqLMaF*_E=*tncM99y%6%NN+m zeGlM#T6BHV)wpJ>*PruIW86e0)9Tb?MQ?q)h7HEgtt3 zPETF&xSsqwJ&Q1Vp2;+;4}Kc4y5Bs)>Uf>Dh2ETYg@1J4H5bb+{#yBe$-dEkzEQEb z_`;#mu2jtTOKj`d{rlGs_iv%$93)A8DtHp^t1HG%RP!=6!L`lFs6oobU8YyXTi5 z_OI1@_(JjdbLAg>WqYG|{Ah9dnVpL}tDo4uu={wVS9c!Lh24v4FYB6iXye?{b(Pkp z@|~r0>SKHQhX>dDtmcR1@DHjtlM`{)G#gIaW5b^EQ|3;b9tICbV`~9_i=_|zI`Ff$ z@KzX4zQFgNf7|hZf6p;ITe`X_6MMQojalA!Os+E**ZDj406Vg`tNgO71KfVr|N>AC8NvyoIK9S`I!SZi$2n&7T3h4LruN6d`pqmaZTwu#%k$BO;5u{9c=YQU zcVk*HUiY2GPHnxt3mDur2FL4zZGB09?w+?g2`M{k-je=Y{Ecf*+uFp@VQl^zV++UZ zf_v|eXDY_&xIA`vX$i`P^~L6Z_rvF6{U!EY$F@)BMbm=UF|**_?@H|MIa|~7KQ1f7#caKXm(C?Ki!!yS;tBe4W?6 z($`LIZf~C1+Rp7>-uBno?Q{wl>q6N*&+cB<{W!i>XV&nK=X^&x_H~P%Zd+EoSZ5`b z&9pd!)M z9$$yklQ#2y%-Q#Hopxr%>Skxs?z6EN{YLGtWg}-hXGa&_ zsQsl!%C}|LqE9k! zf6k6Rw_V=7u>Y=O|LL}}mpdQndE+1MBCsYll{shJ9Jr+nkwL z@Ie@L*ZlhoQ}6rf-t|TJh#6QB_lB>>>=?eoa^WNlh9^^QCL4#L=~ALGk4D|Se06ZC zwy-u0F*fM7yo#|FPV;X){*k8*ePSu~W2aYNU&b$J-+kt!PI%dTj6L>s*H|xe5-Tqj z%sISkOs-Ql?WAq#DXYztb*-JOU*fErv7|qBw43|%m3Grd+8&p;hBzx_jZ5F-pl_^6 zla0N?!P3o7oIc!l`|%_bh6UBbgq}~BQ#t*lu50zh`ooHzCEmi%cqp2KXXh;JTWmKcl)f_!v$<@F9#hu#uu}%)4^bEF>Q?ZRG#*=A;exU_Prpm%d5{ePXpt8(trE! z{<87+LIcBAPj5p9;|wIs*loEZABNw#ajNfM{NWFOIJJjyIE#MZK&);r=f)Lt+x{)9 z+V@Kvajnj?ab7%~3jM;4HM85EwdG%$Uyky-w`Ii(<^QAn-Ie~=9z5CsdIY?4lf(IXP1`dMER4seP&zt?P32ayKvW77jv=|)4lxQ=E?H?vaS3zmM_Qp zwzw1DPNn_l58g)_hK}ugD*o%ixBCD0pZ-(V#iU%~G4Ic0_LR9>e6O5t9$3BG(2Lct z*SVw9cJ^sMFxgj%)#=swQDOiU zOV@O0OYOm|J)+K!9nPgXRB6n)S1LU+w;22Albyf4NZS-D34~ z`)VI)#ob?H+1RIjH}bvy%B1F{Z0B{R5l%i?zSPg}UD>|}f9u-L_U$w4iqju&2TPZ7 zes`TyT0Rrm(fLtl_r7vqMfqA>SUy@7^xt!iZk*L_9kj3X<*N5car-mnYq5N(*E@Q& z_LJ^;rL^t+yK+@$^c}0p7Qb;`x7|A@0K*^NIH!LDd>G8S@1gZRT!0Vrp4>~F@b*kj z$6TFMMMV`&_Fdq>O&Y_o)<=sC+46CB!k9_(t%FO$t@1N(?OQwT7-Q__;#{k%&Y0EHhcxBH+A`k+>38Dv z{;X=e#$aywo=`t~V8i8!^=BOF=Dn~^30W_3Z>QSU{y2C))EBIoHTCU-&BNTWjav__ z?%r=EVr(u*SKs`UlZMq@=ex;oGumfc_dd*Bva+-Kn9*@J<`%{*9zMtGxZi!)T{-2w zd$E`MF0cnRwsV}GeDiZH_8rM@3=XG<5wn|Pbnh*G_CDizdG@Aac#KU4Bldmh{bMi3 z??Pc1`BztVyl1uRU;gAzyCxp{<9Bv-c6K&moH)g@ z#e#2@#^q-D8L>YzHe7p1&mZ32{>kkNWtS}-Oq~t-&ZY7#QW})kON;VGokhe>N>9um zA76X>Hx>(({q(J~NyLfF)`)=)1J-NHstTgGr^VXTRbKT;$XJgq-OOwGid}yL<^rgwhqc@6K`9>Mf z<6YM?7~QwYOl}U7OV4$WG5UY{>+aX`Zk(RBtY@z8H4dj|ufV&;J^Fr1`ZSx7)dyb3>9xPqxkr;)nAhqXhcEi!o5xwC)^IqR)c(=#pRqWdR=uB5I%!Y8Rlf82 z%0E_TQn8QY@E%VxIxRd6`bid0S-@c^m=S$nE3Kxpe>0Qp1?fXa9ceHtrf4=XBII?*`yHp%~bnC*>sx0ez zm99H4R(JL&|1Web=Sr`Bb@$x1?vpRqCTXcFyXKJP%v>BCs{lUSRnr#v>pIQW9! zXTGKR+Q84W4!G{!j5z$hq7P%pnz~QO+UsW=(jWUQHlumKme>%#j``fZfSWOLSh@4? zr2Yf1#{O)K_*cHN;bL{AYp2(p{0>OlDJPbeGGTOealbh2Xe(n?Ub?#dJ)V50jYpZZ z-^>f4kNx&&IX2^0(2$NFnH|fv7wK-9i#irz`L1p z#vpiy1^gT?$L;$jZSH=v3A1B(<&?+tuEX*16NBUFXxP#*y1x(KmSVPetggN|HguS#``+PL;{J-#PawpxzcdnnD=Je9NynW?(*H*C6zH{Yh*<*LKH_q+p zdrJ8Lw72y5juqVwzH4or1GByM93I_RjJ}~AEiExW*Ef#5()H^5*45cE>tF76_0!wt zmTmL7(iJ~lx`k!!hnIKuGW=Wkp* z()d`veyVimrF)70m#}*5>NtI1_1M&hJ*G74&NGVNbawP99ZWr2`$IdY7qipD>U_Qoj6QIBSp8ht%?Hhk^N$85k5(P4 zPxCrkIxP$vJ3b$LGt#~sExij(`nf$T+m-USzWl|nw`U*vZ1;V>y?&>`=zHt8oC|xG zcbocKC)c*^OCD*5YM;c-Iw#3~QGQ&m?qAZb@0r`y&iQir_y20&bGl{elWqNiN6W|K zytZ}uGu>X#XOZ)EovCze+oJL>v%GWq)q`~g)5h8dy=lL8VzOY$$d=P9JlR^+{P}1nZl2vmVAMNSEe1YdX%eCevZ~ZqR;s*!a~Ohm1`u{Z8Xg zTDUD7>^^O!OrE>E%ujjjCpH%I5L_Fda_VVAIUG(0z+W|6AD&(H;tr$m+Io-QsJZ$`eIV4EOpUP*f>gQd< zx1E-90UNL*@;`!FdTB$z{=BJL> z-0-(H^^J39FI+Y?)^K)W<%P^8b5qxx(jL7FR!=>BJX+i?jZJ;Lztr~|*2c$p9jAxY z*~p`fk!H_?^5Zho8ASd z<95s*zmW7@xLus{S5r=1?5(~KpX{-})3>m*b)n9qFQ1H8YrmhfkND1h?R5D! zKU8tqL~oY9{LRv@>|Hyj`&8%K#hLGXU%z#-{Ct#8jpcRL`)%jNYH!f_uUY%QeLTQoM)dx=ReqJW|JbOs- zc{J*5>R0<2NPNGP#=UFP%cqNYYHz8tkNA06Up~?ow&N3Jx1K!jh(E?5@bxn2)GzFF zMroaeb-ea=)_cWferVIYvbitryzczcQ}rGA%!8llIu<&ZQxgliW}WYs<~<@n0IbWHv?|Mov<|L`Aux(BTO4}R`b?Pq@Bmj;{qq(2#L>Ko5#2Q%Oe zbJQkgz$((hfBFdjnWMRecjYM;rcrmyhT%8)^3s-evR;YDYhg~)Yy8#TzI^=(Sug7! zcFveQE7$rGCtun0J97>hm-5QUH|KDhYxBxFWIpnJMBJnO8Rd;G4R`DO0rAY@&%F&^_cU0y=|X1xR9_M~agcT;Tf{tXbyV{-v#V`c13?}C}JwwMi_-CW?yk*5=hRwj0JwteN;<4YMNyYg zb8PsCIl5&*`P^I7zWRk4W?h!Dr6-;$ml1Ij;(vN9!WKb!Janz2MpY`vpFK{cLGs%E#livZp(H zlwJK?{l;-_KgOD1ucVRp`I8y7s--@C14bKkn?;kM}6ue6=3pRe<|7FWIUCsg~N z`50aD!b8RA{I%1)EbBIR=aU}W@^bkfefAzm>b*toduY867vQ~b!A~Z|zma&vztjHR z#*YGK3`d6H!Q#Ng7k1Ec=2HM3XVU#cwcENe!Vyvfc<%BTgm|w$j+DJKdw3Bs7Y&__3*xv!qnK@=m8IODU8Mpg{aUEr}>)GcyV@%`J zXVSv8?xlA-dW}I{*xwfBKurz2i1hUhMC{c$9Z<+%wn7 z_@pOz->oa&_4nhQS6|;LYh4oZ-nusr#ADv5DqJo^<^hhxX}X)D>$h z_H%91u-I$Lj&2^&&d|I^*Uo;9(*=Hw+|$Iw2jsv0(?6TCsfQJ3a(Y;ocKz+kN6VgG zx{EsZ@@DBFcCBArcJqnit#$2o`BTSMmk+HiRw{i!G1h_2wNJ112A;1yf)i^>J20`b z?CCGIcg}9>{_i#~eY!I_t@?szzS1riLv3FAWY-zc9j`AxkM^iybo*8R`FGB=-@bje z{jcA@Qref7N^i5j?cPxK%@ZHq=gZih9!5_bF27rx-y_D%{b8=N_IHZMtS;a4@Y{wn zs7}}K41Q0DZT&s=^sY-Ed@>IENu5=-r|n)>`jB;{&#p6z?9sJnRKV$*>dd0U+gEox zx^qcSm+c&*)3$W~iN)y``(Dy%P7j}l(XsfTN3SyYyw1W(xLWtu%C;^(TfWr&_VQj% zr+t~^^kVdj6`X@)Kk4c6@nSD&|1G9;FRve4QyjjaZ7)Bdhc?YGyZ6%K>?QSWxUo&F zdZBCC?FYSR&*`puA9pWlZyYT@F&m$5n-)FNwk&y~_K7~yj%=9SmOTHpwsOulJEPOW zpW9RCqSiM7E&P=OWyjyWwDz#B?Dl(p+4t1m=&J`;{n)T|A0q0Gv0s#XtPmZ_ zn4yyv9utSPF>u%upM{-LKa4L9tGiB{Vf65-bZPGOgR?LLuD}W52>oD1`B(&(se@Cs zfzP9LA2WN#rETLKGhSz~va4bY{DFz|ojHm1pK@Ux>G~BbZ%o?OmsrRejk#HV=5I~p zXoDth{H_J%^%wn(?G9^DuVLENmGT#?|uG@jmr(buVoyRK1kJy~-qLQ(pSb_{OpIG?vW0 zznhcw)Yq18Ae<}UORS48-DBat9@UQ6*!eJz7TY(J`$vnN^=mBJHP*0ro@4l2jM;OK z!)aK2v)LD_PifW*pL++i;a<9+Km3Ym)idt+cEshDT#*cs5q-jJj zF0PKv8<*o~L4N`}IzHwbk*yj7)0NPDYl9v}Us+3S;A&;nvCq@Jv0G;$oGuNYOA`y$ zI(Btq8{75qyRl$$`%Y=a@VD;=`WXGOljCq&c77VgIGrCDT+f&K?^ocjai%>zHudme z7+p+T^46u=FIbG|Je>=rasFZXTwyoudr6C>ofUt*c=}YGA$fRf?fWbqb0+2L`A>CU zFyB7Ey`O({w9YO%Q7nJyK>74p^i=5_=C}FJe69Rzl&0nE=B|5T1GQ)GKxrVHS$Vwn zFs@%ZtG*4Eln?b?ZOiI;#g7x6)6X877<`b^xQs(=(G{DM`6Yy>vG(1#oc~H8obLLs zCWExDgZT;B)W>UoCte>v6W>fU>c9E=nRaC7+S>a&_;(4Xzh3(YUOTtHbV{W`DjmAL zqWr1bD|)kn^?T?1&bIueCnvT4rGY7(%XhBS8MMXf7Y}XfzBjF}^G3gSWqdeypuf9;<1V6rC#*d-({#=23#O@!vSo|B#z6+OO zGu(h{#tbSyJStWS`lQ z7be70I00k0#x58L3kt5yF|35y^rf9Juy&wFU;vaY0>Vum#=MW zELKO*_c-V~d1CVwkH@5c>Do00&%!*ks~>%Yf6d!<=9c-TkD>43*@Vf}$vDNzq-|>` zWR1h;%FPVQWqp&E=jA?QO&eLG)JebcX;?6No?|pEd7gRRxz~^O)a~3{@0L35!{ME| zD;=9+PK>WCru80aOS_$MC%N0VWv@4RFE4zqzU$;?EZPuqua0}`V?LR`eEnNn;|WjV zLHx>IjPWpH{%+LA%-A-3ixDv+-BP|=(l$;HU&j{iK8!xLt;>J3xSL&`-*or>#=`6B z3I2AaDJ$Rifxi6~fb;#Wht=7%u{u5vqf2vb{50$48cxUR7#r)lW{+lLXKTmk*xNN; z#_-sf4g1Q?H@eOn2h)(?U-oY8`u~nGxMq{rrtblEaJG7Dhx_GQYpgD~9&rV>c%H7OYMK)5lle27ma+f6{H{d?yL)|8y_(F2DEtf6xO)cRnewzTvw>-(9K_>0Z*?c&CzvxhTk=z;Cw6Cc>Lpw2m6(fw~@#W%~Z2;YLg z{l@9GukQJR!RBL*onrOk^Qk%1wK?MR#P)t-?JY>o;#6ZHr#`W;?xSUH9)Y z=+Sq!le=E&nwDcb)>JurL?^oM9s5YJG(RoaJYlep7teaWrFlBJv+Ug%dy>2F6w^pK zzv$4G#r-TJ?5^F;=*8(n9q}Zq7pHg4%cSN# z96k;I-Z8HJjRD(-n|rxR%R7aMy)WLgDaNie<snAY*Xbws>95CCP8(DG zOs-j;lm6uSyTH8OXPk&Xv0nU$uq)$P`KjxDXYavoNKeYeOT2h7eEj=9;a`Cnn5W|wx35Z2`bUA}tyVAr>nVQPCX^rapBSWDjq`n9&k zmOg28jKdg}!{ojf*wv$Bj}8aJ)1|YgWAGpS?mz7|bKeiQ%daUNz4J=rgIzkNSJv63 z{J#9@pZ$5aCC9e>L9G7vl{)LFxRB46o26U6S$hk=bGdA{r|LZU(l+p=cwqCgZmYG| z@Iv`jJiU8O_XDzS$qSwB=vS`P{=pk3wsjrMI~Vt~z3b=K{=_+*y>_gg)z2Z#SvLG+ zAKtRC?JHaT&R6I4eX9Jx%zN%z?MH8yubf@$+IPSE-FMs3N8c7WJ-nNFio@t^>G&Ia zC%DJq_ep7xo z&z26o?-8BUpiZ(>mB9IY%FwpoC_B1ybFb{4*WNf>XX6#CZ(sIA?Hzrt*FRl*pWixOV<~@+ zKkk1Y6YKrC0zdA1aS0S;y2e=D=ZWy!#fxfUxq`&hhrARgW8mbn=ljh!6W|d z*G}rEZ(Jr#UBS47aH4YhmZwcj!H8hv7x^)+%jeiT!U;5NvLi!6kYg?Xi z$;&g8?^@7T)=)o~-B^@Y&K%8MuwLe&P5IK~3n`zqik@5SoyjvxId!DxebSb7XHyLi zCQqN{pw2M2>3y{9_R{4Gsgp5F%RJT$%l2}UZMqJdtC#CAy8Li?@_PMB*LNS^WEt;g-c$XlXPoAyU+ajQ`5$NR#hw@v zYtkx*A#tw16ZQ1v8gGUtu`edpSNbuwXkIXQcsrb~?`U46JzD&&eu8{;667nFvi?S; z3I2Y=>Hd!W4GXy3xQt(LJ!{_5&gyh87?|BU_H=e>%#6A1&BVgESvm7fxoF(26=ufi z_B!KY+7~wIfBkR%tlQN2QpDFdTYcX&Y~VQD`m%Lv2UpXkh}qiXHzs>qjUk#F`WgI> z)3JOwUAngLx_tai-@>OU?xsQa{S{6Z8?$nrxtL}LuhYO_QY;!~3@e5cI~x}3vgN*6 zx|i4M?8`SV9&A6jakTtt*O@cr@1^s3ohi=;$iyr2+W+?b(&5zEmH3dxV$X)frKu<# zM)CQT(yza9cGtk{#eMYWC(5Vejq(|@yL^dYF}6(SOk%Es8~E^8(ls?W?lj-qWw&24 z=gD?#=PUiYA$I2X#5L~BW6Z|*I{QR1_g_siI$OEm9;aKE@Vxuj(xrD>dbQJ8{m0b4 zjK`977iaAgXYAv6iq-3Ryj}Vi&jXtaw~DQuNyP8`wd320yUS0@WVl}6MfQGnKP~0& zg`IrY`bFLM%auCc^$HDoF?#pOSb6+z+9Qh1vsaY<{8|P3KfC^%?!0^~IyV$QZ(H$v zXWY)vW!Jt^dxrVs45#y@@0p&cXG_a+rpg@XTwlHxi`~z5zb-T{gFc;aM&;f-v!(B2 z@V$1b*!*nOqf0rzkA8f0x0U-w*kA98^uzTIZC>_l+0~boKhV~y?V$Gy^7t35;$DOsdM37i3t1WC;E zRG4R=fWkz~g^A!yiZY`(cCy?~JF=tE>5hjC{U&+gmpA)!?(-{Ll!{V8A|;BvT$Wccba!UQ<1K#Z z{xx6fc31rM4NE^)=O-=ec2t{R{p@cn7N_RqKADs{&YA}1K7tSMBAkW=!*=0V{Nryr zF2D`g088Sp$m2LnguyWb9@367OeJZ<-)YS3@2_bC1=`FJm#b^zGW5jmbFNhnLAKmt6NgAisG}J84s{ z9lFUpT}M~i)TeowC#H^^_SH=r@{}o;%tKqQjZs}~4d;>Tw5tzo;oFRbPLi}`Ts;H# z`qeMl$mmyl8H2XStLK`{+&jmCa@>cn{2mhK43~z()l*-aNog;<9$EcMsgwKUnOA&X zVr;)v@Nv;Def!;lU(x6Cz zpDsJCGw0c3r9O^!$xK-9RPlDdw{TP0bc@l-_jucjkG3=8*3r5BSA8Fp@cQRU&>%n@hDCLUjwFnU;Ad1Nqp@;@!FSx5pVmY4d}zya z74v0NV|Mb+6Xl04;d=h)cjLS4Xy=FWaj_ngUoHQZ#61^#Q=COSF0POLm{?cL6}*h8 z?fbOP#Vf7|8R1;wNQq!|btj z#putsc#Pum`%W$#Sl!*IvA8~6YXalBP%M6U<74g2Blh%DJNmevmkzEf+xxOUF1vG+ zYJAoJVx?a?xUzeD=EZK)Q@_)#d*XN6nWSQ+U)c9tw{Pu|vd@2|Tl?gv+qp>hi(DhI zesVQ%zu(GY_iTaVIF_S{cXl1_$~67N*n&p#wO-( zIp$Jd-#9VcseNN{@41vdUB}iOUMHJ!WyWRPxXIsnfAeud#)E|<_u)z7bDuSav1J_E z$GRDZ>x?gB)TcVblsRSWkqzT&Lp_XRoYoPThW@M>$a^knLp|d)j>Ff4BK(4iy`DBdVano+`7 zm9f?GBZ-~dzlZpd@EOyNZ_jhj8gs_(dYH(k zJvnZdTYrSpUB}-AQ?qOH9pNv6v)QY|;PFW@cXnz1BiMS#=kaw9r(=HH&Hj#k@wML~ za5^S-uN@4H)g#NV2HUftg?!r9~(F3w+1lAu(~$v6=jEa<`-TMr?cCem-iOi zI(xoxe80{fW#j+u_x`+bxv^faBnFK2fi(u77YvWn+1~%-U;b6|_rRMtav?Sh|FWk$ z>&O|U&9|ahegBp^^X6Ew;E`?Jv8gr1aTOP&?A>RJ0mbRQR=yO@y z`%J~lzE*M8`NJHkIF1+{)8RaR$ZVq0?6D2qj+IM_`&QODO2uD0D^_Ez8P+Ucvaruf zaco#UY#UC--$V8eqhs)Jx@$6#bsfK#aQcwdhrF(z`(gCxJmX8A@{E6&=bczPy?o(F z`;Ei81#d^ciGP?F<>yN0;wpMS=W8!0|8rbE$L7W9Ew+oYT3a2jc$-&?@7d4oA?1rc zU2*coXt7>8So7KW@4K;j#Y*QV z!=^s;OULPaQKsvAn5q5A=PQm-JD;@LJGb}wijnwqQnJ@jbw$D_YcD#SA;yvzP|7h(&eZ1M-7sFCRnNKdIjx!&A2Orcm=D~2W zyW%2jcb5(Co`H$c$c0<69>&2J{wCveY(WlJC212o%EMaW#-U8E!<_EbNx8b7WxVm- zz@vSP#$TVaL6b8#V^PnX!noQC$C1Hn?p7pSCd^rVL}@wd^CnM)=&ff&uX?Ze^3!jy~kWl>VdRyE1qEVT{KZ z%pv0mqh~(mq%UiT%uQK%Up?jO#h#w=DUWSCHsoAi@B`gK3laqg8# z)@jB{cm7S$Cl(#rlYJ)`6cfhR*){vQg#XxR@hpAgYdWXvur{uCZ5?i|uJ!31dKT7B zUG-fXQ`j1BllQGk>bX}pWn>mgzVR@5I33HU+_hwlAO9CRz}x&zVox_miM`x6=DBC= z*8XkDv9Iq?;x9+e8fAFz-ydHV_Ho>ebJ^1E&Gg#@{nB~%i}Lw*HWB}IT<$qe$M9mv zu)%xAzKz+{%brrqj@{L9#wgxacgX6w_I}kRgS-FTpMI4cilaN8Z|97@bM;WO`Lg@Ic7CecTl-7-zZ@@HxmekUw>;Bq zscf%DDn5)fJ@sPqQ+MXh&C^resXD9l;<1WVa`K17Wh`FLoEksZ95FS8`z(>*e=y=i+34ub3|N8wR^L-p*M= zEjCN(zUTFdU0!}M7mB%Yy7NQhgPwQPnF>$UTZ0AY&~_l?A_YH=xp{FUAj_C z%fIE)q17$^Ngx0I*~wa~;vw#$zj)55um$`pM6>y$t-O*u^g$TGj07*!rd2%ev_;OIjSpP0xIx zyLF<@$F1_?Tb}GTF8|$%^RA^LVZku3dXe*YK3qW# zN2V?O=3b7wB+r!PK6yA2kGT$C4xcMiKVvbDAzQna)W=5VkTGXW+Q)X<#Yq_(J)|vh z9^I1(v!y*_Fn%dx)ONP+-)hPei^hA>r+4Q)h1K7W(~XU6IGwztjc|JYpFoa0?vBkoJRar`m#5v_ zXU&Jzt@G%CpN@Ga-U}|L8~5~O?pPQXv!#dAu{k+OJ83KB;b-d{42+BapKtzI_pR@I zuW>hfyY&xyHy;=5jK{M!@(v_EG8jC*h9Us6I0!90({%~WV0QI3&Vu5+lJM}d*Ks(tM)FQ+P}Fm`t6E6^2&vZ z12a?pI$Kwk-}KQIL*%WiN1BiN$vtbk>*cHdO2y+ow&R5s51p-+ZMHv4ep9!9BZq;^I`rYIla~aKgyQ=!=6X~!!f5U?lhT{~Xuq%Fnj z)$2XIRQ@Ix4^}MmZObaQVSi503E5-o zjifVWGso-78m||t_xwKbqp4@s2i5==DyI7D=e9L}ckHeVr@wQd;!+-|dQ(r;KG4rs ze3mcP7;CTVu4jttKhs@5zOMPI^L;5cQ#cvdF?sl=+=pK-HJLhcmMjwnvcwM z`N{C3*}CH4w(oS;>LrUose5ETxs*E2{GJct1G)*fvAwcM<2u|Y;khspISdsx_Kb{s z*WozV%GATp^02IH?IdYWSyILl`HVxZEN!J<{Y2I?yrm3VlQEX8Kg`Q`JkPWAuM9Kc zGdZ@vPT?r_#{A}vH}DOXG~V>@S|3taU%Sx_`K)VFM_KyCIyeNQxW-O+4cD2M_RUe7 zl4t5FCxef|HR>CGc++!o8IScxuIVB?tRM9-Cf%e@{hEhdQZA7<2Yjp@^U_wzwc)vY zGW0gTU3JvWyj*LW+)y_Cr#)>ZnV+N&X?SlwbcMIssXcQ|caf9leQT3^)@5|)+BYzl zCd{rpa_VS5oStt-yGfoYkBnTslxIA~hts`N-<$V}mHBhvPK=1leW#vV7sZ#zdI;C1 z4*R(|NY)t{bDLA$$3~9PeK+`AUF;lI_e}q>#p{=BQrMh)%3KfIFwV>+T%P<3)mOe< zxqkzaYd&GgT}$Ei%-Nb2w@ZAi+&BK7Fgb>&yD&VC_nfRW5x-(PDa{x0n3SR5l`ZtEtA?>UZFhT}0a8@;;T9R_#JH(hyr*xCN2aC%r>j@9|y zgxie)r&}xVi(%V09-Pi!-CkJxPx+|-$G`Zi?l1rPKQ%7Ju^4g4fcbdZ*4EvQH5s+J|_j;xY1b5l?Zp_A#=<@{>MR=N<9Cuosa(1)mpt zM9&w4%f;RnqYoEi^O@qa!~((T{5cNR8Kv*uI8{D3Q{8KqPt@6*2b-Tu?9PqT|EBkS zQ5Nnszu3X&`=8I>Px_z#>;L})tR7BRH|-?X_AsT-#pdDh zJypq>qT(yQb@f>B_Eh)g<=SIaw>J<N_!++!vThO1KU+B12WDy$ktj=Wq7Z-v9sR?6jJ zHMx69KSQ3=Pwutl-uT1G+SOmmGADJCw3~V3C2Sl!Cf;Bd#Adj}-+J~toS+<2(T9FA zMmFrf`}hC1w%*aMe&ovK!?h4r_8gODZs9cTsUz3E^%H({PgYxGjTx89jgLPoyDJ{S zFySVQmb&U|Q~&xg7F$rNhOZDN}El(r#?v?#XJ;`^mdVo<7pX z{Qkn``c2=_TkDi%Cp9Boq0#Ez5{jS^ONsn_>BIO!r+))n;8o(_T4nD zFL`ZRw_snn`^bmW$$N(q#`SJ78e6&d9s9R$l?-`hVOwJ~uB=g_gRD37i@$x}>VEd2 zCHJtjb}_i;5?SrL4v!}%C;9F$b{HCiXAa84=EHo*=*rDia_yP=LslQkXN_VVjnCz| z4y)&Pg>X9CdC%!T$m+`Z81W-#zsB5b)3K}LUi^;ZF)=$h2FJy0-TNoMaqx}D-(=La z*OMQ*y7-(Q3zjF3_xY-0aE#7gZ#@=PALg#Z>3HAxtP!*;Sx>mf>KLBC4j&oG9#rQZ zVb1U&9vm_{E)(}hGB`YSMXNjY2kD|Da7mtW3f(_Rtu#sK$qB+qmo6*u%8S%?n32Kb471J^ttMb;04WpX2mlN_qTV!ubnw`cL5h5-uO+ zna40UzqhZS>0YX{jKorRo>9vyuHv?~FD|G1 zIZiJ-`fTkh5ZC-f{m$XN;dJ*`%P&cs^O>@z+vn-sBpwTUcW?V%Q|qYm7vEp3UFqtP zHDzypsP>B%r&kh3vBfpt)$cVpRqSrB=FzfY^IgH{?CG(ii>dFvx3iZId#wXnyvA^P zv$wOUi~CrZRzF(b$-1ilVs~ezzPE!fc9-i+qQ@WjC*4z@|KGb4 zo4;E7KR?qw{5!wi?OOFnJNtIJ?C<2;IO=yCHg&!{#&~}3ii(r|xr*KRNVjj@W9`h- znW>7~Uv~6^<@0i6(_@Puse45}xs*E2oCfaw8h-LSe|ND09>Pr+5X*(juou>i9TP`| zrO1$#$VqrB_pZr=-}E7c!LXZa&+{w{m-5^jTiTJk_sn(f!+lsia|qvNT>1&m85`Lo z?cgjNLoc{QePwLj_yA{NFKy5XzOvTAD44~w`TVC0E8)iIwefqga?kI--dG&R32&-v713S8i~a~#0`)|j!Ge)Xe19cd4v|H9w<)qD7qK0PR$b9AGJTq?B;qGvBa^sT1-pbvpD=Al|FUh?*<7(w> z`goV!+x*m39yV7dHQuf|v6E+gVXmH~-(ju|a%A*FPA*v+(7Sv-uMchKbk}ow+2M=X z@x2t=I#)kJWKI#`l|u zcKus*kIk*WuzL2Y>YE)sHg$}iG<;?(#(>kUDcJA7{*8at{ObAaeCNC0Z*k!HsM}MD zOR*}R#kGxj|E8F?xcBWFXWBXS{Gr7Gbmsia=MPmZzysyyvZFhFpyG!d-`V1CAFVy5 zZxk2aJiV(sVeett+4(l(J)A8L_wll;i$&sW9kE|L$B$SY+czKR@`J|lr*`vsDE=yY z=hlh~BmO$yYG>RV%RARk^)_{UK0np?%_HlN#g%gx~nt&nWWC3!s^${2MOCA-d1}p%kM}m`#b0N zHNPWqU)b1Nyv1U4YbW;g-hbUXX+wJ-c--$8_}m^}*FB^6wsc(0H;Fy{EPs|}+b%n_ z{iGF-9Our(ekuPK`-1tvh`Gr(C3&-%mk&BVf9c?wS}W8ZhT3Dw_o>BzY3l>OxAecS zG@CkBZ)=08 zKmU!SI%?p4zL&+wVh$XM&)8UTAuh*iVM=_5zrt4GHjEQaCyS@TdAUxVFjvp!ch8^4 zXkj-p;ljwP?|C>7^XT_(d2hdUZw#@^W~~q&!+FZI8_v=$9#t-PA3uSxEu9#XI#{gd z$G$DBtG&kI^&DpzgSy(m6#4s)Sul<9c&<0+#!N56xoZFK{M~=p#$#S|YV6*vLyP}S8`*>y)yS1mwVrgd-KGr z%Jh@|BCn0qYx6YMNeZ9mULHQi*sjT7UmWcnc=tF`nQy_n!H3=<_H3Lw;ZbdPr@kR$ zpkrf|^3JvEed9@OlgH;_ZvEijxp|aLAFF3hzDeJNI_Xav#u64*-&p0ta@W2o-*C#= z-^1!Dd!W8a9Bqu4S-CQ)&3DqaKCm`fTpiX9Z+QRI{ zLib7Hz(=cF5_kUO72;M*W@U6J2NP)Ok8@UOC#Gwx_cg-97$0TXyc3%MV6u5iz`* zjke0acBS@@)|ohG+Zj3)d%gG@ljCza{ytMYD5eNrjBP#V-|)BKKl9!!pAIp?>zvGr zHFK-Z__{d6wjcVx+{5XmyM-7$YlP$r$%My~ zM>ec}52x1}daBBF5V75r1RpyRNNhLUFg<3k$O(=<1IEnm|7=^ z?Sj{v{{6O5?}Y9p?_-YB%dUPNqc>izc#B6%7ONLCOZb+b3kL3){P|j=Rs5cb&wBQc z@_C7Gy0*k|oU^0Xnv5--zs>Od$3F(s<8bSOYh}aVv!>#DPE|a{YNPq&l<&;zwMY5Y zGqo0}*e$Qk)NeTZmUgS3_-uFk9eV`r~CaT`(ynMpzT}7Yt2w+ zm>#Nqr3;qjDRtDq{d_Nrk;UNn4IlpEul(Aatu>s6@5o>( za`*w`NO%C-k;Tc%a7B1oJ=gP@nhaKxJR35bHt`r<@wXXEk#Fo$Y=kv>`|bbL{zm(I z?e8r17_zAAaH2k}A5x|*W$qVFVv3q$jJS>B_nUFT%3%RU7KS#-+1ZI z{I#1D4#(+|I!W}C@~j2I;&MJP_Jr~e;k%yotvpG2*1x!!4>@0SwrX~3Wf8?j2%|j7RJZg%EIT#+0t=5Tl&!dg*}}gJlj1#b^TdO@TX@( z$Lts#t7CU%5_>U*4HL3a^8tUk_AO#UJ}=?{o;k3kduR4U^FiTvarwlq#_MM)o;qK4 z&zxI&Wc%|Kf3c4_B0l4E+0Ywf7ZdV{Vbi^0kE8vL6JBIv$BXRh_%Ja>@Y$q5i>t_!)o4T=IojK6G^2#f7zUyIKdF<&e&P&aAK8Is- z_VlE%dh*!RV^5cd)#ci6sn!E{yrl`hFU05J@$mUD&$v@Id@mR3Y|_~?2Pf%3t)-k# z>P%8+AC-N5y3QgkcIW5P>%5QoVh?HdkG5F$wN^^Z#kM{Qv)8&P<$RIm{L;he#l!s5 z&+e^wJ>`GG*32Je_So8rrSiqb>3vL>vU``^Tne8L8T}mpmX_>0T~oY$*QU;vf6qFh zd|R3=zxs7{5`UZN@_C;wex6$Om5TfFZ1a_B`;#kv3!cAJ@n|j`c)rdeeV}abUv7ME z4WS=#+1b)@I=_5t0kI~0#;27XzjaeR)o9$mrTJE;(7x=H#kfZF?rQdX4M* zSd{t+)2eIk9D$M%+2S8EnSM=OWW5uiK)nE{Jnqq2h9ft+w)T!CS{nL4^8+yIW{+D{e;!s zTNkLKKjXvd#>nS|pNn`e-}&D6Tg-KPO5>+)Pi5@sm~iMza`XJr=4)Z^;w#1KuU|S+ zoL*5L6l%VQ_i)Jb9ic$LX=D5AEvV^*K(*=9RE}Sp0rDJ!2p8dftl|JeQ~U z7N=Ltok}!jZAXtEZnbrByEzi(JK zHHP;tYOQo-!mwDq+0xn5C!Bt@e7c=4%2v)N<=V0JZC~efaXSvi;FuVvH$KPgVyKsY zi`b8zd&Y<6SjFLF-;Uo)+rv7yR-4%Mt8eQA3?3UkTeo=Yzjy6m<8>N9~KBd%&jC;xbP$$Z?E6*5kzxMoAk#&wbX`5VR)iYLY;Ns}SoQ>W1%t!7W zq@FzQ(U?3l5B<1SKkvqz$-388bf8|wuV4B!2D$s84vi)K;l3ej(x*1l?(o{P@NvrB zV@>ZdoE-l3ESw%Ws|`? z%JVx$lP$hpNQRy;EoOIZZD1^tv1N|NoO0unj3xV=)l-(WhqXXs`iXtt7&G?NGe&)q z9dbIpP73$3Nn={P8=E-R#^&nc41UJv*4uKn?)Z{x zJ7dncvwpzd+Q#L|-0M4I#_v+(%|puA%#q)Vd(6wejd8^{WC!PaVlM!nGO<$0U~;}L zo?&Gy&EJHdIZo#r!yc}jjaz%znNPZQ+2Z-Vy!$VHzxlxMPhn$c|0av^>q(Bst(Pv;?;YZo^Mg^wX06=&>wV5w zHMVcIb$;mHZTYw)F8Z-qC8r{BHrZL8{qN7DuwZRi_!8cWs*?r|LE!#L{V zQ*7+nkbAXbOxn_R#%tc{dTyNR#n(kYl6Eo=ZDgEbZO>gB8@Y_ry|(aq*k2i0a;Z0L z$2ekVHlB=EpROaDYwf$1u%|YSx!LOL9U8AT@fxO<4;fG&(GC64i+k@fTuny*!$jwF zhdCu|=-wD4&(#l)=RWO*ztcy)KY5tCZ>#@a!m*KyOvYhO%FK_9c2gFfb#HFk%KLYn zHq$rx*vGYJZzv8Adp8!Z`>avqjnyaiZ_FGS*O9}wI5(Vby!y=h80N<1K4UVD@V7G0 zQ(qsku^WfJBP-7s$VmFfz}R}o(HIxMVpj|s&c)Z^bT)Kt3_0C146H4(I2(g2SC)Pn zrx&{qIb9$8!1>+lS5lVx_&iBlxI0{)bwC&#r>iUBeQlVNay(Bi&xg4^*LWOXV|0v* zePibqM+v9%IpLckVdU7)$zo&dEb&th!^ii9PYNCv7lyyOGehl3#p=!>!t3f~|EZWQ zn4En-oUY&axUivT-JnnXvG=Ey#S+1TW#=qbpD7MMQ)eQv zxnG-hMrmS-^!pfbnYeuR2C}7J^t{<{S9iBg*14F)U-knY*!)bLkNSK!wZ6`MFHRTN zoqaj$iy_~Jfw6Bm-F%0f9v)8~yE@%0meYs4KF8`4`+D<(S%BNa;~8Vd?cTGzlayzE ze&@Jt-@v)z^-9h6h5t+a&cXlXTE*kJRYIrFO^fSj52$mG>RULx`KfNxb6=`BHRbzK z>kF}h#H``Na-iZYZhGc-y8~+;?)I$uQrj2GhQ4n@`RkP53r@dUYe#c6j?2aBub$r2 zy?kPIxBkiB?*7kz^tZbsoA|0f(HPyiO^f|+B-Bv@G_ct3WwCNN4%7JC>u)d~z(=?* zJQIG!pEwZu)>{v|a9fw2de#px1y?06Ze7zYXJ(AM~d#7)Q z?2xO&nFMKv_5O>d1v~}+{`ay5660LjH&Bhd+JDOM?Kft z2&2pC3uDWpJG_p2W1o(_S58)n3^^$}^6x90OD^jNeH(-EWgN!R##6R)tlj#rzFm_s zCpm@;Gg>DPP{PX~|lCt)9FJ7+6bhKrT6Ym1+V<2}d4IGOF-b$Hvg#8;hv4I4Qh7(OZX zq_V4j<6r$@_ecNsPv&@9EOboI_RhAhUp93~|JDRp+?b5TdO;aR&$_{L$$CSK8fT$e z2k?DiFUIRwoxeIB#f7okh6m+1UHo+M5NB)eB0mc;8!sN8YHa@2wdoc!@#fimWuvWq zr4=uIw$8U?v$cnm&Gz`zs_x~pySs-z{ZC6~Yh%M}C(3?XY;~v@>tyXQWfMJH{EpR+ zZm)RQ&6ZpDmESzMx%j-!h}^%jd+kh};ac`kHrsQD%T8Rj{i|i$zmhYMYRuu<b;x{@;5a_W7J1Ue9=QpLw+R^EZ8* z8*3+g?(C!NE5+&T=~v4~{c8EZV0FK5SUa(&dpF|0h{@xuQa&->M>{8}_+89JF(~=OudIEdw@z)Tbwc^ul)w4a z<6ByMN$UqOTEXL6D1sgCnU^}zpt1M(_m3@a*T)# z!&>riq-T*0k47$hKIAXg+LvoH?CV+?9&w#7J!t#^@fqh6U57F=brJuq7F7 zlDEEa9T{c053}Mabv)A_7I!UWu4%{ftR?70xwgZKo~fVy%oR%-KUvqxB<=H^7yrex z%+>hZdu~4NJ;U_s8?SfT7<9t9vA1Hq=-Io*hT%YCr2p`(xoM9cv=^3CFVD2)xjIsG z*6X_GZnEYpX)ks3=RVJKZBF4*W0UkhOv7<2kABVBIMg>5ZF;7RT-uXIKWz>63Lr z#u!fbZ#(=NR!tkRX}gaP35L)A5Abd{UEl8YiOulxv;#xlhQYTb^hq~|MGK5&W?_WF>(@S#_AZE z9}J$x>1^lx(sQp&!q8Y9r;DNP>?Ho}_}RWv`#dG_VB~D+I9(m=tuMB8eM#)>Lry2N zzgRtfH~PovZ0`E8Hqe*&jQI3>fBqjDr+@pq-<#ufTsUNO*YCaeUKih&Z`?W8y?*(4 zvEYI7f7#hs9kbs$cd*%TXNwEP1Z11V=+3-!R?(@w>$;cE?d|r~UeN0^ySm%u%YOTG z`56`S?PcHGUG~iKT|ZSeRs7WU_Z2^#E89BW+q?eBV)crlUcL$JsH>m;LbqrA(r&|w z$C~fU(W$b}7N^IiKHnA{9v*T!zkGJ{#^=T6@dLu;)-U$lO0LOR+q_>q^)UH-9#8pv zRv(Th*J1L7@^HFmjn(VD+^XLYa53jspY7sw@8!m+^2@H@GQ#Ot z9ivMZ>UR(N?>W8VHkJ*%o&Q-jWWL_V%MbiS#XRBva&Ysq7BiFWn{Uf(G4si0o8H`b zncoXvac!J!elo@R#rXWz+1hcr-%6Y_gx612x$Bu0oAEBEpJPvNemH&n&VCKIVbV9- z`>Jkx?GfEq`xdbM^wi4w&1Q4^ErxwxEX6~cpKd(A?(yI3UOQfP_B~H^PkrJ4Xl+;< zUasE`jK%um_RO}5oBnwF?O^uE%I=MsHQlD=4|G=!JX?EYztG~^jGR95_x)&KvER#L z<^Jbi{9ikXy*C_*^KcA*SbT$PJPU7zTk(`@Oc~}1Plh)!*j?Vb*OsnaKVdj+Xir^j zho?Npp`Im$%Z&@4hWpeFv$|fWocu76i)^m7VGQo|nek+-^Pjm_$DGKxm+Qy1airX} zvan<9(CSM1B&$7nuC?VIu$8C3u)2DgD|ut?*8u;xy*rFbpO`NR7b;UXY>iPdJQf^s zu>SO~?Z|p}>MQd+;~zfH+{j2|$Y!k3Me4dIr>~UB!_?T-*yeM)xeUK0&n0EawQIcE zQZ}6593$77Lm%{jgJa94GuP6P!(&&+-kw>rLkhVaaTDp7AByz|KNA-UeD%V?_WZ=ui^bvV+Ic%W%isLij(*=M`|0K4t(=L;j>`9#Ka8_^_&{L0 z4bMJOcH#1SuRW|=S3TYA{rt9D449h3@Z2VBi*dum=4p;>WLGB@fX@xI^^>C*Y_~|#0MtphKwtW?mpMa!|LI5@8|War`q|jXDjB8^GPq2 z-%9>%!pP+2&^vx$63-|jr zpKW_K{k9?Y&go)w@5nxbi}k(^ZF#2lWmYUk&uXpZw~pr1RIJW#T@0A%@?AfJ)A`R7 zmwTUW|7iJ~Sc_@HJ8$-Me)IMHB;LDy$2U&a80+^Jed+swY0z)*RM@)_~?<{Koq7nVsdozO0+sRsQaKS9FKgeYy6a zKGq%G{CLG?T-xGJE|#b6hvi1ukFN$6`@Jky4x|51f9F@a|K*qdL9@T|?Z$y}oEN5w zT^Rp`NAXj58C#N#Jl+bg;UndkN!gIUlzUDdn`zrM8H^VW)V}9Q#(~l0o~2E7-D^kg zK5dhg(hnKeLpj&RG|bbN^7JEj?^(*#>BoJSNAY0lc%Hec6RtFlFeLpLQ`(o)LB1Hfgaff8-czP6N#A&Nn8LKiu3a+5W9)f1+D`kKhv#|UsY5=p za(!wu{mau1ow!z4oAeltbuA6Y>6%>ncTYy2@?O`yoj-h@`e`fe(^29r;^WxW>8vq$ z*|Zyf4}40na9A5dtA`E4*xDq6)0L6YhB0Wa!)sUnP4hF>@Fk$KrT?7Kz^;zQwZom6Ty$b;IW2V&&Qki(_qU ztWJ_KdH!_8o+nF&4l%mibG|RJ$Lqs~O;`agTlTTga(H?p06S~xISlv7& z_qZIRv!i47$nYDdcdU-z@p_mZw_|n8j-}bW*~f7+-xfaVxEZVCXsph*j@Q}LaXO~w zH^VlL)76(SxO?rguVeObx_-#3$F@&ijK;)o*C&5?e(~Zqe)~J$YxZJ%IOISq*f_n; zJGxT7CC=IT!#6K=U%z#x+q-E+oj=r{U*GRt>|?AS+3{lccAaOxcjL3|Or#s9`}p4M zy8XV!sm6$#RxD{Y-09-=ook+I?0%)9qS|_pmx<#?g42oqRs0^98bYNz8ei zPKGR252we^Jw7nlKk2{KIj9SQ?F^)sFgZS#DqiCSoLh-sp4urD(vab zuHr{-edWEh`0FL>94qHjiFL^5`*``UPnV6IKRXuZgN~h#)fr08uVRN!E^d17SN?3{ zbnm?FZ=G=Zh4P~pYu`5^8JqVmp5!0gKHS|twY6f+EbXSt=lpW@&G*F~WbFR#m3@ul z`N*8yv9vqA^XYE+mw%`E>a=(-%^!brjj!Uum#@wr-a622T=rmhe9M#VtRs6+cdz<# z)m`4rlt0X3|NHoo=Qy+b(ZFKAm&MA7LxR!&_AmYYIaZGkG#h*Dwc)<76u!c4I6ds^ zUc!$oX3uE#;{OFma-HaO}rffKej91&*Bd^SR$h&Z#d74w^CD*4hxsLwG zy4PPAmW;OPPRe@=!-mr{hdd95XUwUaT>I)qPM*2ypWOU!LAmjGCRZozxyGo{uwCO+ zCXcLsGC#TUl*#9Fy1E!03*&1EBM%v!4Lr|cAIIAm8h=aS>G>@0zLib*3OvS<8{v> zZ=8{Npjh2C8OgP>B(h1d_sjKb3~g>TCps`!^On0$S+2c

GU5X1}Rx?`FvFc$z(& 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 Date: Fri, 23 Aug 2024 00:01:57 +0200 Subject: [PATCH 03/17] ft: Improved autosize function for scatter plots. --- csep/utils/plots.py | 114 +++++++++++++++++++------------------- tests/test_plots.py | 132 +++++++++++++++++++++++++++++--------------- 2 files changed, 145 insertions(+), 101 deletions(-) diff --git a/csep/utils/plots.py b/csep/utils/plots.py index ff0f759d..ea612fb3 100644 --- a/csep/utils/plots.py +++ b/csep/utils/plots.py @@ -2,7 +2,7 @@ import shutil import string import warnings -from typing import TYPE_CHECKING, Optional, Any, List, Union, Tuple +from typing import TYPE_CHECKING, Optional, Any, List, Union, Tuple, Sequence import cartopy import cartopy.crs as ccrs @@ -76,7 +76,7 @@ # Consistency and Comparison tests "capsize": 2, "hbars": True, - # Specific to spatial plotting + # Spatial plotting "grid_labels": True, "grid_fontsize": 8, "region_color": "black", @@ -100,7 +100,8 @@ def plot_magnitude_vs_time( ax: Optional[Axes] = None, color: Optional[str] = "steelblue", size: Optional[int] = 4, - mag_scale: Optional[int] = 6, + max_size: Optional[int] = 300, + power: Optional[int] = 4, alpha: Optional[float] = 0.5, show: bool = False, **kwargs: Any, @@ -118,9 +119,11 @@ def plot_magnitude_vs_time( Color of the scatter plot points. If not provided, defaults to value in `DEFAULT_PLOT_ARGS`. size (int): - Size of the scatter plot markers. - mag_scale (int): - Scaling factor for the magnitudes. + Size of the event with the minimum magnitude + max_size (int): + Size of the event with the maximum magnitude + power (int): + Power scaling of the scatter sizing. alpha (float): Transparency level for the scatter plot points. If not provided, defaults to value in `DEFAULT_PLOT_ARGS`. @@ -149,7 +152,7 @@ def plot_magnitude_vs_time( mag, marker="o", c=color, - s=_autosize_scatter(size, mag, mag_scale), + s=_autosize_scatter(mag, min_size=size, max_size=max_size, power=power), alpha=alpha, ) @@ -1419,10 +1422,14 @@ def plot_catalog( ax: Optional[matplotlib.axes.Axes] = None, projection: Optional[Union[ccrs.Projection, str]] = ccrs.PlateCarree(), show: bool = False, - extent: Optional[List[float]] = None, + extent: Optional[Sequence[float]] = None, set_global: bool = False, - mag_scale: float = 1, - mag_ticks: Optional[List[float]] = None, + mag_ticks: Optional[Union[Sequence[float], np.ndarray, int]] = None, + size: float = 15, + max_size: float = 300, + power: float = 3, + min_val: Optional[float] = None, + max_val: Optional[float] = None, plot_region: bool = False, **kwargs, ) -> matplotlib.axes.Axes: @@ -1436,10 +1443,14 @@ def plot_catalog( extent (list): Default 1.05 * :func:`catalog.region.get_bbox()`. projection (cartopy.crs.Projection): Projection to be used in the underlying basemap set_global (bool): Display the complete globe as basemap. - mag_scale (float): Scaling of the scatter. - mag_ticks (list): Ticks to display in the legend. + size (float): Size of the event with the minimum magnitude + max_size (float): Size of the catalog's maximum magnitude + power (float, list): Power scaling of the scatter sizing. + min_val (float): Override minimum magnitude of the catalog for scatter sizing + max_val (float): Override maximum magnitude of the catalog for scatter sizing + mag_ticks (list, int): Ticks to display in the legend. plot_region (bool): Flag to plot the catalog region border. - kwargs: size, alpha, markercolor, markeredgecolor, figsize, legend, + kwargs: alpha, markercolor, markeredgecolor, figsize, legend, legend_title, legend_labelspacing, legend_borderpad, legend_framealpha Returns: @@ -1455,10 +1466,11 @@ def plot_catalog( ax = plot_basemap(basemap, extent, ax=ax, set_global=set_global, show=False, **plot_args) # Plot catalog - scatter = ax.scatter( + ax.scatter( catalog.get_longitudes(), catalog.get_latitudes(), - s=_size_map(plot_args["size"], catalog.get_magnitudes(), mag_scale), + s=_autosize_scatter(values=catalog.get_magnitudes(), min_size=size, max_size=max_size, + power=power, min_val=min_val, max_val=max_val), transform=ccrs.PlateCarree(), color=plot_args["markercolor"], edgecolors=plot_args["markeredgecolor"], @@ -1467,22 +1479,32 @@ def plot_catalog( # Legend if plot_args["legend"]: - mw_range = [min(catalog.get_magnitudes()), max(catalog.get_magnitudes())] - - if isinstance(mag_ticks, (tuple, list, numpy.ndarray)): - if not numpy.all([mw_range[0] <= i <= mw_range[1] for i in mag_ticks]): - print("Magnitude ticks do not lie within the catalog magnitude range") - elif mag_ticks is None: - mag_ticks = numpy.linspace(mw_range[0], mw_range[1], 4) - - handles, labels = scatter.legend_elements( - prop="sizes", - num=list(_size_map(plot_args["size"], mag_ticks, mag_scale)), - alpha=0.3, + if isinstance(mag_ticks, (list, np.ndarray)): + mag_ticks = np.array(mag_ticks) + else: + mw_range = [min(catalog.get_magnitudes()), max(catalog.get_magnitudes())] + mag_ticks = np.linspace(mw_range[0], mw_range[1], mag_ticks or 4, endpoint=True) + + # Map mag_ticks to marker sizes using the custom size mapping function + legend_sizes = _autosize_scatter( + values=mag_ticks, + min_size=size, + max_size=max_size, + power=power, + min_val=min_val or np.min(catalog.get_magnitudes()), + max_val=max_val or np.max(catalog.get_magnitudes()) ) + + # Create custom legend handles + handles = [pyplot.Line2D([0], [0], marker='o', lw=0, label=str(m), + markersize=np.sqrt(s), markerfacecolor='gray', alpha=0.5, + markeredgewidth=0.8, + markeredgecolor='black') + for m, s in zip(mag_ticks, legend_sizes)] + ax.legend( handles, - numpy.round(mag_ticks, 1), + np.round(mag_ticks, 1), loc=plot_args["legend_loc"], handletextpad=5, title=plot_args.get("legend_title") or "Magnitudes", @@ -2127,25 +2149,14 @@ def _plot_pvalues_and_intervals(test_results, ax, var=None): return ax -def _autosize_scatter(markersize, values, scale): - if isinstance(scale, (int, float)): - # return (values - min(values) + markersize) ** scale # Adjust this formula as needed for better visualization - # return mark0ersize * (1 + (values - numpy.min(values)) / (numpy.max(values) - numpy.min(values)) ** scale) - return markersize / (scale ** min(values)) * numpy.power(values, scale) - - elif isinstance(scale, (numpy.ndarray, list)): - return scale - else: - raise ValueError("scale data type not supported") - +def _autosize_scatter(values, min_size=50., max_size=400., power=3.0, min_val=None, + max_val=None): -def _size_map(markersize, values, scale): - if isinstance(scale, (int, float)): - return markersize / (scale ** min(values)) * numpy.power(values, scale) - elif isinstance(scale, (numpy.ndarray, list)): - return scale - else: - raise ValueError("Scale data type not supported") + min_val = min_val or np.min(values) + max_val = max_val or np.max(values) + normalized_values = ((values - min_val) / (max_val - min_val)) ** power + marker_sizes = min_size + normalized_values * (max_size - min_size) * bool(power) + return marker_sizes def _autoscale_histogram(ax: pyplot.Axes, bin_edges, simulated, observation, mass=99.5): @@ -2286,17 +2297,6 @@ def _create_geo_axes(figsize, extent, projection, set_global): return ax -def _calculate_marker_size(markersize, magnitudes, scale): - mw_range = [min(magnitudes), max(magnitudes)] - if isinstance(scale, (int, float)): - return (markersize / (scale ** mw_range[0])) * numpy.power(magnitudes, scale) - elif isinstance(scale, (numpy.ndarray, list)): - return scale - else: - raise ValueError("Scale data type not supported") - - -# Helper function to add gridlines def _add_gridlines(ax, grid_labels, grid_fontsize): gl = ax.gridlines(draw_labels=grid_labels, alpha=0.5) gl.right_labels = False diff --git a/tests/test_plots.py b/tests/test_plots.py index 0190871a..e5de65fa 100644 --- a/tests/test_plots.py +++ b/tests/test_plots.py @@ -42,7 +42,6 @@ _get_basemap, # noqa _calculate_spatial_extent, # noqa _create_geo_axes, # noqa - _calculate_marker_size, # noqa _add_gridlines, # noqa _get_marker_style, # noqa _get_marker_t_color, # noqa @@ -50,7 +49,6 @@ _get_axis_limits, # noqa _add_labels_for_publication, # noqa _autosize_scatter, # noqa - _size_map, # noqa _autoscale_histogram, # noqa _annotate_distribution_plot, # noqa _define_colormap_and_alpha, # noqa @@ -71,7 +69,7 @@ def is_internet_available(): is_github_actions = os.getenv("GITHUB_ACTIONS") == "true" -show_plots = False +show_plots = True class TestPlots(unittest.TestCase): @@ -125,10 +123,10 @@ def test_plot_magnitude_vs_time(self): self.assertTrue(all(scatter_color[:3] == (1.0, 0.0, 0.0))) # Check if color is red # Test with custom marker size - ax = plot_magnitude_vs_time(catalog=self.observation_m2, size=10, mag_scale=1, + ax = plot_magnitude_vs_time(catalog=self.observation_m2, size=25, max_size=600, show=show_plots) scatter_sizes = ax.collections[0].get_sizes() - func_sizes = _autosize_scatter(10, self.observation_m2.data["magnitude"], 1) + func_sizes = _autosize_scatter(self.observation_m2.data["magnitude"], 25, 600, 4) numpy.testing.assert_array_almost_equal(scatter_sizes, func_sizes) # Test with custom alpha @@ -136,14 +134,14 @@ def test_plot_magnitude_vs_time(self): scatter_alpha = ax.collections[0].get_alpha() self.assertEqual(scatter_alpha, 0.5) - # Test with custom mag_scale - ax = plot_magnitude_vs_time(catalog=self.observation_m2, mag_scale=8, show=show_plots) + # Test with custom marker size power + ax = plot_magnitude_vs_time(catalog=self.observation_m2, power=6, show=show_plots) scatter_sizes = ax.collections[0].get_sizes() - func_sizes = _autosize_scatter(4, self.observation_m2.data["magnitude"], 8) + func_sizes = _autosize_scatter(self.observation_m2.data["magnitude"], 4, 300, 6) numpy.testing.assert_array_almost_equal(scatter_sizes, func_sizes) - - # Test with show=show_plots (just to ensure no errors occur) - plot_magnitude_vs_time(catalog=self.observation_m2, show=show_plots) + # + # # Test with show=True (just to ensure no errors occur) + plot_magnitude_vs_time(catalog=self.observation_m2, show=True) def test_plot_cumulative_events_default(self): # Test with default arguments to ensure basic functionality @@ -832,8 +830,14 @@ def setUp(self): [[-125, 25], [-85, 25], [-85, 65], [-125, 65], [-125, 25]] ) + self.mock_fix = MagicMock() + self.mock_fix.get_magnitudes.return_value = numpy.array([4, 5, 6, 7, 8]) + self.mock_fix.get_latitudes.return_value = numpy.array([36, 35, 34, 33, 32]) + self.mock_fix.get_longitudes.return_value = numpy.array([-110, -110, -110, -110, -110]) + self.mock_fix.get_bbox.return_value = [-114, -104, 31.5, 37.5] + def test_plot_catalog_default(self): - # Test plot with default settings + # Test plot with default settings4 ax = plot_catalog(self.mock_catalog, show=show_plots) self.assertIsInstance(ax, plt.Axes) self.assertEqual(ax.get_title(), '') @@ -850,6 +854,42 @@ def test_plot_catalog_without_legend(self): legend = ax.get_legend() self.assertIsNone(legend) + def test_plot_catalog_custom_legend(self): + + ax = plot_catalog(self.mock_catalog, mag_ticks=5, + show=show_plots) + legend = ax.get_legend() + self.assertIsNotNone(legend) + + mags = self.mock_catalog.get_magnitudes() + mag_bins = numpy.linspace(min(mags), max(mags), 3, endpoint=True) + ax = plot_catalog(self.mock_catalog, mag_ticks=mag_bins, show=show_plots) + legend = ax.get_legend() + self.assertIsNotNone(legend) + + def test_plot_catalog_correct_sizing(self): + + ax = plot_catalog(self.mock_fix, + figsize=(4,6), + mag_ticks=[4, 5, 6, 7, 8], + legend_loc='right', + show=show_plots) + legend = ax.get_legend() + self.assertIsNotNone(legend) + + def test_plot_catalog_custom_sizes(self): + + ax = plot_catalog(self.mock_catalog, size=5, max_size=800, power=6, + show=show_plots) + legend = ax.get_legend() + self.assertIsNotNone(legend) + + def test_plot_catalog_same_size(self): + + ax = plot_catalog(self.mock_catalog, size=30, power=0, show=show_plots) + legend = ax.get_legend() + self.assertIsNotNone(legend) + def test_plot_catalog_with_custom_extent(self): # Test plot with custom extent custom_extent = (-130, 20, 10, 80) @@ -1080,19 +1120,43 @@ def test_add_labels_for_publication(self): self.assertEqual(len(annotations), 1) self.assertEqual(annotations[0].get_text(), "(a)") - def test_autosize_scatter(self): - values = numpy.array([1, 2, 3]) - scale = 1.5 - expected_sizes = (2 / (scale**1)) * numpy.power(values, scale) - numpy.testing.assert_array_almost_equal( - _autosize_scatter(2, values, scale), expected_sizes - ) - def test_size_map(self): - values = numpy.array([1, 2, 3]) - scale = 1.5 - expected_sizes = (2 / (scale**1)) * numpy.power(values, scale) - numpy.testing.assert_array_almost_equal(_size_map(2, values, scale), expected_sizes) + def test_autosize_scatter(self): + values = numpy.array([1, 2, 3, 4, 5]) + expected_sizes = _autosize_scatter(values, min_size=50., max_size=400., power=3.0) + result = _autosize_scatter(values, min_size=50., max_size=400., power=3.0) + numpy.testing.assert_almost_equal(result, expected_sizes, decimal=2) + + values = numpy.array([1, 2, 3, 4, 5]) + min_val = 0 + max_val = 10 + expected_sizes = _autosize_scatter(values, min_size=50., max_size=400., power=3.0, + min_val=min_val, max_val=max_val) + result = _autosize_scatter(values, min_size=50., max_size=400., power=3.0, min_val=min_val, + max_val=max_val) + numpy.testing.assert_almost_equal(result, expected_sizes, decimal=2) + + values = numpy.array([1, 2, 3, 4, 5]) + power = 2.0 + expected_sizes = _autosize_scatter(values, min_size=50., max_size=400., power=power) + result = _autosize_scatter(values, min_size=50., max_size=400., power=power) + numpy.testing.assert_almost_equal(result, expected_sizes, decimal=2) + + values = numpy.array([1, 2, 3, 4, 5]) + power = 0.0 + expected_sizes = _autosize_scatter(values, min_size=50., max_size=400., power=power) + result = _autosize_scatter(values, min_size=50., max_size=400., power=power) + numpy.testing.assert_almost_equal(result, expected_sizes, decimal=2) + + values = numpy.array([5, 5, 5, 5, 5]) + expected_sizes = _autosize_scatter(values, min_size=50., max_size=400., power=3.0) + result = _autosize_scatter(values, min_size=50., max_size=400., power=3.0) + numpy.testing.assert_almost_equal(result, expected_sizes, decimal=2) + + values = numpy.array([10, 100, 1000, 10000, 100000]) + expected_sizes = _autosize_scatter(values, min_size=50., max_size=400., power=3.0) + result = _autosize_scatter(values, min_size=50., max_size=400., power=3.0) + numpy.testing.assert_almost_equal(result, expected_sizes, decimal=2) def test_autoscale_histogram(self): fig, ax = plt.subplots() @@ -1177,26 +1241,6 @@ def test_create_geo_axes(self): self.assertIsInstance(ax, plt.Axes) self.assertAlmostEqual(ax.get_extent(), extent) - def test_calculate_marker_size(self): - # Test marker size calculation with a scale factor - magnitudes = numpy.array([4.0, 5.0, 6.0]) - markersize = 5 - scale = 1.2 - sizes = _calculate_marker_size(markersize, magnitudes, scale) - expected_sizes = (markersize / (scale ** min(magnitudes))) * numpy.power( - magnitudes, scale - ) - numpy.testing.assert_array_almost_equal(sizes, expected_sizes) - - # Test marker size calculation with a fixed scale array - scale_array = numpy.array([10, 20, 30]) - sizes = _calculate_marker_size(markersize, magnitudes, scale_array) - numpy.testing.assert_array_almost_equal(sizes, scale_array) - - # Test invalid scale type - with self.assertRaises(ValueError): - _calculate_marker_size(markersize, magnitudes, "invalid_scale") - def test_add_gridlines(self): # Test adding gridlines to an axis fig, ax = plt.subplots(subplot_kw={"projection": ccrs.PlateCarree()}) From f1ee186952eaa0a15ba9ff5f9f83d21e38654d2c Mon Sep 17 00:00:00 2001 From: pciturri Date: Fri, 23 Aug 2024 13:11:25 +0200 Subject: [PATCH 04/17] refactor: standardize alarm-based plots with the rest of the plotting functions. --- csep/utils/plots.py | 294 ++++++++++++++++++++++---------------------- 1 file changed, 144 insertions(+), 150 deletions(-) diff --git a/csep/utils/plots.py b/csep/utils/plots.py index ea612fb3..d864b585 100644 --- a/csep/utils/plots.py +++ b/csep/utils/plots.py @@ -63,8 +63,11 @@ "legend_framealpha": None, # Line/Scatter parameters "color": "steelblue", + "secondary_color": "red", "alpha": 0.8, "linewidth": 1, + "linestyle": '-', + "secondary_linestyle": "red", "size": 5, "marker": "o", "markersize": 5, @@ -932,35 +935,41 @@ def plot_consistency_test( # Alarm-based plots ################### def plot_concentration_ROC_diagram( - forecast, - catalog, - linear=True, - axes=None, - plot_uniform=True, - show=True, - figsize=(9, 8), - forecast_linecolor="black", - forecast_linestyle="-", - observed_linecolor="blue", - observed_linestyle="-", - legend_fontsize=16, - legend_loc="upper left", - title_fontsize=18, - label_fontsize=14, - title="Concentration ROC Curve", -): - if not catalog.region == forecast.region: - raise RuntimeError("catalog region and forecast region must be identical.") + forecast: "GriddedForecast", + catalog: "CSEPCatalog", + linear: bool = True, + plot_uniform: bool = True, + show: bool = True, + ax: Optional[pyplot.Axes] = None, + **kwargs +) -> matplotlib.axes.Axes: + """ + Plots the Concentration ROC Diagram for a given forecast and observed catalog. - name = forecast.name - forecast_label = f"Forecast {name}" if name else "Forecast" - observed_label = f"Observed {name}" if name else "Observed" + Args: + forecast (GriddedForecast): Forecast object containing spatial forecast data. + catalog (CSEPCatalog): Catalog object containing observed data. + linear (bool): If True, uses a linear scale for the X-axis, otherwise logarithmic. + ax (Optional[pyplot.Axes]): Axes object to plot on (default: None). + plot_uniform (bool): If True, plots the uniform (random) model as a reference (default: True). + show (bool): If True, displays the plot (default: True). + ax (Optional[pyplot.Axes]): Axes object to plot on (default: None). + **kwargs: Additional keyword arguments for customization. - # Initialize figure - if axes is not None: - ax = axes - else: - fig, ax = pyplot.subplots(figsize=figsize) + Returns: + matplotlib.axes.Axes: The Axes object with the plot. + """ + + # Initialize plot + plot_args = {**DEFAULT_PLOT_ARGS, **kwargs} + fig, ax = pyplot.subplots(figsize=plot_args["figsize"]) if ax is None else (ax.figure, ax) + + if not catalog.region == forecast.region: + raise AttributeError("catalog region and forecast region must be identical.") + + # Getting data + forecast_label = plot_args.get("forecast_label", forecast.name or "Forecast") + observed_label = plot_args.get("observation_label", "Observations") area_km2 = catalog.region.get_cell_area() obs_counts = catalog.spatial_counts() @@ -973,6 +982,7 @@ def plot_concentration_ROC_diagram( area_norm_sorted = numpy.cumsum(area_km2[I]) / numpy.sum(area_km2) obs_norm_sorted = numpy.cumsum(obs_counts[I]) / numpy.sum(obs_counts) + # Plot data if plot_uniform: ax.plot(area_norm_sorted, area_norm_sorted, "k--", label="Uniform") @@ -980,27 +990,29 @@ def plot_concentration_ROC_diagram( area_norm_sorted, fore_norm_sorted, label=forecast_label, - color=forecast_linecolor, - linestyle=forecast_linestyle, + color=plot_args['secondary_color'] ) ax.step( area_norm_sorted, obs_norm_sorted, label=observed_label, - color=observed_linecolor, - linestyle=observed_linestyle, + color=plot_args['color'], + linestyle=plot_args['linestyle'], ) - ax.set_ylabel("True Positive Rate", fontsize=label_fontsize) - ax.set_xlabel("False Positive Rate (Normalized Area)", fontsize=label_fontsize) - + # Plot formatting + ax.set_title(plot_args['title'], fontsize=plot_args['title_fontsize']) + ax.grid(plot_args["grid"]) if not linear: ax.set_xscale("log") - - ax.legend(loc=legend_loc, shadow=True, fontsize=legend_fontsize) - ax.set_title(title, fontsize=title_fontsize) - + ax.set_ylabel(plot_args['ylabel'] or "True Positive Rate", fontsize=plot_args['ylabel_fontsize']) + ax.set_xlabel(plot_args['xlabel'] or "False Positive Rate (Normalized Area)", fontsize=plot_args['xlabel_fontsize']) + if plot_args["legend"]: + ax.legend(loc=plot_args['legend_loc'], shadow=True, fontsize=plot_args['legend_fontsize'], + framealpha=plot_args['legend_framealpha']) + if plot_args["tight_layout"]: + fig.tight_layout() if show: pyplot.show() @@ -1008,33 +1020,41 @@ def plot_concentration_ROC_diagram( def plot_ROC_diagram( - forecast, - catalog, - linear=True, - axes=None, - plot_uniform=True, - show=True, - figsize=(9, 8), - forecast_linestyle="-", - legend_fontsize=16, - legend_loc="upper left", - title_fontsize=16, - label_fontsize=14, - title="ROC Curve from contingency table", -): + forecast: "GriddedForecast", + catalog: "CSEPCatalog", + linear: bool = True, + plot_uniform: bool = True, + show: bool = True, + ax: Optional[pyplot.Axes] = None, + **kwargs +) -> matplotlib.pyplot.Axes: + """ + Plots the ROC (Receiver Operating Characteristic) curve for a given forecast and observed catalog. + + Args: + forecast (GriddedForecast): Forecast object containing spatial forecast data. + catalog (CSEPCatalog): Catalog object containing observed data. + linear (bool): If True, uses a linear scale for the X-axis, otherwise logarithmic. + plot_uniform (bool): If True, plots the uniform (random) model as a reference (default: True). + show (bool): If True, displays the plot (default: True). + ax (Optional[pyplot.Axes]): Axes object to plot on (default: None). + **kwargs: Additional keyword arguments for customization. + + Returns: + pyplot.Axes: The Axes object with the plot. + """ + + # Initialize plot + plot_args = {**DEFAULT_PLOT_ARGS, **kwargs} + fig, ax = pyplot.subplots(figsize=plot_args["figsize"]) if ax is None else (ax.figure, ax) + if not catalog.region == forecast.region: raise RuntimeError("catalog region and forecast region must be identical.") - if axes is not None: - ax = axes - else: - fig, ax = pyplot.subplots(figsize=figsize) - rate = forecast.spatial_counts() obs_counts = catalog.spatial_counts() - I = numpy.argsort(rate) - I = numpy.flip(I) + I = numpy.argsort(rate)[::-1] # Sort in descending order thresholds = (rate[I]) / numpy.sum(rate) obs_counts = obs_counts[I] @@ -1043,7 +1063,6 @@ def plot_ROC_diagram( for threshold in thresholds: threshold = float(threshold) - binary_forecast = numpy.where(thresholds >= threshold, 1, 0) forecastedYes_observedYes = obs_counts[(binary_forecast == 1) & (obs_counts > 0)] forecastedYes_observedNo = obs_counts[(binary_forecast == 1) & (obs_counts == 0)] @@ -1069,9 +1088,9 @@ def plot_ROC_diagram( ax.plot( Table_ROC["F"], Table_ROC["H"], - label=forecast.name or "Forecast", - color="black", - linestyle=forecast_linestyle, + label=plot_args.get("forecast_label", forecast.name or "Forecast"), + color=plot_args['color'], + linestyle=plot_args['linestyle'], ) if plot_uniform: @@ -1080,20 +1099,23 @@ def plot_ROC_diagram( numpy.arange(0, 1.001, 0.001), linestyle="--", color="gray", - label="SUP", + label="Uniform", ) - ax.set_ylabel("Hit Rate", fontsize=label_fontsize) - ax.set_xlabel("Fraction of false alarms", fontsize=label_fontsize) - + # Plot formatting + ax.set_ylabel(plot_args['ylabel'] or "Hit Rate", fontsize=plot_args['ylabel_fontsize']) + ax.set_xlabel(plot_args['xlabel'] or "Fraction of False Alarms", fontsize=plot_args['xlabel_fontsize']) if not linear: ax.set_xscale("log") - ax.set_yscale("linear") - ax.tick_params(axis="x", labelsize=label_fontsize) - ax.tick_params(axis="y", labelsize=label_fontsize) - ax.legend(loc=legend_loc, shadow=True, fontsize=legend_fontsize) - ax.set_title(title, fontsize=title_fontsize) + ax.tick_params(axis="x", labelsize=plot_args['xticks_fontsize']) + ax.tick_params(axis="y", labelsize=plot_args['yticks_fontsize']) + if plot_args['legend']: + ax.legend(loc=plot_args['legend_loc'], shadow=True, + fontsize=plot_args['legend_fontsize']) + ax.set_title(plot_args['title'], fontsize=plot_args['title_fontsize']) + if plot_args['tight_layout']: + fig.tight_layout() if show: pyplot.show() @@ -1102,83 +1124,58 @@ def plot_ROC_diagram( def plot_Molchan_diagram( - forecast, - catalog, - linear=True, - axes=None, - plot_uniform=True, - show=True, - figsize=(9, 8), - forecast_linestyle="-", - legend_fontsize=16, - legend_loc="lower left", - title_fontsize=16, - label_fontsize=14, - title="Molchan diagram", - forecast_label=None, - observed_label=None, - color="black", -): + forecast: "GriddedForecast", + catalog: "CSEPCatalog", + linear: bool = True, + plot_uniform: bool = True, + show: bool = True, + ax: Optional[pyplot.Axes] = None, + **kwargs +) -> matplotlib.axes.Axes: """ Plot the Molchan Diagram based on forecast and test catalogs using the contingency table. The Area Skill score and its error are shown in the legend. The Molchan diagram is computed following this procedure: - (1) Obtain spatial rates from GriddedForecast and the observed events from the observed catalog. - (2) Rank the rates in descending order (highest rates first). - (3) Sort forecasted rates by ordering found in (2), and normalize rates so their sum is equal to unity. - (4) Obtain binned spatial rates from the observed catalog. - (5) Sort gridded observed rates by ordering found in (2). - (6) Test each ordered and normalized forecasted rate defined in (3) as a threshold value to obtain the - corresponding contingency table. - (7) Define the "nu" (Miss rate) and "tau" (Fraction of spatial alarmed cells) for each threshold using the - information provided by the corresponding contingency table defined in (6). - - Note that: - (1) The testing catalog and forecast should have exactly the same time-window (duration). - (2) Forecasts should be defined over the same region. - (3) If calling this function multiple times, update the color in the arguments. - (4) The user can choose the x-scale (linear or log). + 1. Obtain spatial rates from the GriddedForecast and the observed events from the catalog. + 2. Rank the rates in descending order (highest rates first). + 3. Sort forecasted rates by ordering found in (2), and normalize rates so their sum is equal to unity. + 4. Obtain binned spatial rates from the observed catalog. + 5. Sort gridded observed rates by ordering found in (2). + 6. Test each ordered and normalized forecasted rate defined in (3) as a threshold value to obtain the + corresponding contingency table. + 7. Define the "nu" (Miss rate) and "tau" (Fraction of spatial alarmed cells) for each threshold using the + information provided by the corresponding contingency table defined in (6). + + Note: + 1. The testing catalog and forecast should have exactly the same time-window (duration). + 2. Forecasts should be defined over the same region. + 3. If calling this function multiple times, update the color in the arguments. + 4. The user can choose the x-scale (linear or log). Args: - forecast (:class: `csep.forecast.GriddedForecast`): - catalog (:class:`AbstractBaseCatalog`): evaluation catalog - linear (bool): if true, a linear x-axis is used; if false, a logarithmic x-axis is used. - axes (:class:`matplotlib.pyplot.Axes`): Previously defined ax object. - plot_uniform (bool): if true, include uniform forecast on plot. - show (bool): if true, displays the plot. - figsize (tuple): Figure size - default: (9, 8). - forecast_linestyle (str): Linestyle for the forecast line - default: '-'. - legend_fontsize (float): Fontsize of the plot legend - default: 16. - legend_loc (str): Location of the plot legend - default: 'lower left'. - title_fontsize (float): Fontsize of the plot title - default: 16. - label_fontsize (float): Fontsize of the axis labels - default: 14. - title (str): Title of the plot - default: 'Molchan diagram'. - forecast_label (str): Label for the forecast in the legend - default: forecast name. - observed_label (str): Label for the observed catalog in the legend - default: forecast name. - color (str): Color of the forecast line - default: 'black'. + forecast (GriddedForecast): The forecast object. + catalog (CSEPCatalog): The evaluation catalog. + linear (bool): If True, a linear x-axis is used; if False, a logarithmic x-axis is used. + plot_uniform (bool): If True, include a uniform forecast on the plot. + show (bool): If True, displays the plot. + ax (Optional[pyplot.Axes]): Axes object to plot on (default: None). + **kwargs: Additional keyword arguments for customization. Returns: - :class:`matplotlib.pyplot.Axes` object + matplotlib.axes.Axes: The Axes object with the plot. Raises: - TypeError: Throws error if a CatalogForecast-like object is provided. - RuntimeError: Throws error if Catalog and Forecast do not have the same region. + RuntimeError: If the catalog and forecast do not have the same region. """ - if not catalog.region == forecast.region: - raise RuntimeError("Catalog region and forecast region must be identical.") - # Initialize figure - if axes is not None: - ax = axes - else: - fig, ax = pyplot.subplots(figsize=figsize) + plot_args = {**DEFAULT_PLOT_ARGS, **kwargs} + fig, ax = pyplot.subplots(figsize=plot_args["figsize"]) if ax is None else (ax.figure, ax) - if forecast_label is None: - forecast_label = forecast.name if forecast.name else "" + if not catalog.region == forecast.region: + raise RuntimeError("Catalog region and forecast region must be identical.") - if observed_label is None: - observed_label = forecast.name if forecast.name else "" + forecast_label = plot_args.get("forecast_label", forecast.name or "Forecast") # Obtain forecast rates (or counts) and observed catalog aggregated in spatial cells rate = forecast.spatial_counts() @@ -1295,33 +1292,30 @@ def plot_Molchan_diagram( Table_molchan["tau"], Table_molchan["nu"], label=f"{forecast_label}, ASS={ASscore}±{dev_std} ", - color=color, - linestyle=forecast_linestyle, + color=plot_args['color'], + linestyle=plot_args['linestyle'], ) # Plot uniform forecast if plot_uniform: x_uniform = numpy.arange(0, 1.001, 0.001) y_uniform = numpy.arange(1.00, -0.001, -0.001) - ax.plot(x_uniform, y_uniform, linestyle="--", color="gray", label="SUP") - - # Plotting arguments - ax.set_ylabel("Miss Rate", fontsize=label_fontsize) - ax.set_xlabel("Fraction of area occupied by alarms", fontsize=label_fontsize) + ax.plot(x_uniform, y_uniform, linestyle="--", color="gray", label="Uniform") - if linear: - legend_loc = "upper right" - else: + # Plot formatting + ax.set_ylabel(plot_args['ylabel'] or "Miss Rate", fontsize=plot_args['ylabel_fontsize']) + ax.set_xlabel(plot_args['xlabel'] or "Fraction of area occupied by alarms", fontsize=plot_args['xlabel_fontsize']) + if not linear: ax.set_xscale("log") + ax.tick_params(axis="x", labelsize=plot_args['xlabel_fontsize']) + ax.tick_params(axis="y", labelsize=plot_args['ylabel_fontsize']) + ax.legend(loc=plot_args['legend_loc'], shadow=True, fontsize=plot_args['legend_fontsize']) + ax.set_title(plot_args['title'] or "Molchan Diagram", fontsize=plot_args['title_fontsize']) - ax.tick_params(axis="x", labelsize=label_fontsize) - ax.tick_params(axis="y", labelsize=label_fontsize) - ax.legend(loc=legend_loc, shadow=True, fontsize=legend_fontsize) - ax.set_title(title, fontsize=title_fontsize) - + if plot_args["tight_layout"]: + fig.tight_layout() if show: pyplot.show() - return ax From 9ca35729f64c2b4f05a9c7841a23473c1ec73ff0 Mon Sep 17 00:00:00 2001 From: pciturri Date: Fri, 23 Aug 2024 14:47:29 +0200 Subject: [PATCH 05/17] refactor: Added type hints and docstrings to helper functions. Removed unused helper functions --- .github/workflows/build-test.yml | 2 +- csep/utils/plots.py | 927 ++++++++++++------------------- requirements.yml | 1 - tests/test_plots.py | 402 +++++++------- 4 files changed, 571 insertions(+), 761 deletions(-) diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 9bb56913..d4df63ac 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -72,5 +72,5 @@ jobs: - name: Test with pytest run: | - pip install vcrpy pytest pytest-cov + pip install vcrpy==4.3.1 pytest pytest-cov pytest --cov=./ --cov-config=.coveragerc diff --git a/csep/utils/plots.py b/csep/utils/plots.py index d864b585..840ca36c 100644 --- a/csep/utils/plots.py +++ b/csep/utils/plots.py @@ -1,8 +1,7 @@ import os import shutil -import string import warnings -from typing import TYPE_CHECKING, Optional, Any, List, Union, Tuple, Sequence +from typing import TYPE_CHECKING, Optional, Any, List, Union, Tuple, Sequence, Dict import cartopy import cartopy.crs as ccrs @@ -13,8 +12,6 @@ import numpy import numpy as np import pandas as pandas -import rasterio -import scipy.stats from cartopy.io import img_tiles from cartopy.io.img_tiles import GoogleWTS from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER @@ -22,8 +19,10 @@ from matplotlib.dates import AutoDateLocator, DateFormatter from matplotlib.lines import Line2D from rasterio import DatasetReader -from rasterio import plot as rioplot +from rasterio import plot as rio_plot +from rasterio import open as rio_open from scipy.integrate import cumulative_trapezoid +from scipy.stats import poisson, nbinom, beta # PyCSEP imports import csep.utils.time_utils @@ -66,7 +65,7 @@ "secondary_color": "red", "alpha": 0.8, "linewidth": 1, - "linestyle": '-', + "linestyle": "-", "secondary_linestyle": "red", "size": 5, "marker": "o", @@ -532,7 +531,7 @@ def plot_distribution_test( linestyle="--", label=obs_label + numpy.isinf(observation) * " (-inf)", ) - else: + elif isinstance(observation, (list, np.ndarray)): observation = observation[~numpy.isnan(observation)] ax.hist( observation, @@ -592,11 +591,14 @@ def plot_calibration_test( Plots a calibration test (QQ plot) with confidence intervals. Args: - evaluation_result (EvaluationResult): The evaluation result object containing the test distribution. + evaluation_result (EvaluationResult): The evaluation result object containing the test + distribution. percentile (float): Percentile to build confidence interval - ax (Optional[matplotlib.axes.Axes]): Axes object to plot on. If None, creates a new figure. + ax (Optional[matplotlib.axes.Axes]): Axes object to plot on. If None, creates a new + figure. show (bool): If True, displays the plot. Default is False. - label (Optional[str]): Label for the plotted data. If None, uses `evaluation_result.sim_name`. + label (Optional[str]): Label for the plotted data. If None, uses + `evaluation_result.sim_name`. **kwargs: Additional keyword arguments for customizing the plot. These are merged with `DEFAULT_PLOT_ARGS`. @@ -615,8 +617,8 @@ def plot_calibration_test( # Compute confidence intervals for order statistics using beta distribution inf = (100 - percentile) / 2 sup = 100 - (100 - percentile) / 2 - ulow = scipy.stats.beta.ppf(inf / 100, k, n - k + 1) - uhigh = scipy.stats.beta.ppf(sup / 100, k, n - k + 1) + ulow = beta.ppf(inf / 100, k, n - k + 1) + uhigh = beta.ppf(sup / 100, k, n - k + 1) # Quantiles should be sorted for plotting sorted_td = numpy.sort(evaluation_result.test_distribution) @@ -935,13 +937,13 @@ def plot_consistency_test( # Alarm-based plots ################### def plot_concentration_ROC_diagram( - forecast: "GriddedForecast", - catalog: "CSEPCatalog", - linear: bool = True, - plot_uniform: bool = True, - show: bool = True, - ax: Optional[pyplot.Axes] = None, - **kwargs + forecast: "GriddedForecast", + catalog: "CSEPCatalog", + linear: bool = True, + plot_uniform: bool = True, + show: bool = True, + ax: Optional[pyplot.Axes] = None, + **kwargs, ) -> matplotlib.axes.Axes: """ Plots the Concentration ROC Diagram for a given forecast and observed catalog. @@ -951,7 +953,8 @@ def plot_concentration_ROC_diagram( catalog (CSEPCatalog): Catalog object containing observed data. linear (bool): If True, uses a linear scale for the X-axis, otherwise logarithmic. ax (Optional[pyplot.Axes]): Axes object to plot on (default: None). - plot_uniform (bool): If True, plots the uniform (random) model as a reference (default: True). + plot_uniform (bool): If True, plots the uniform (random) model as a reference + (default: True). show (bool): If True, displays the plot (default: True). ax (Optional[pyplot.Axes]): Axes object to plot on (default: None). **kwargs: Additional keyword arguments for customization. @@ -975,12 +978,12 @@ def plot_concentration_ROC_diagram( obs_counts = catalog.spatial_counts() rate = forecast.spatial_counts() - I = numpy.argsort(rate) - I = numpy.flip(I) + indices = numpy.argsort(rate) + indices = numpy.flip(indices) - fore_norm_sorted = numpy.cumsum(rate[I]) / numpy.sum(rate) - area_norm_sorted = numpy.cumsum(area_km2[I]) / numpy.sum(area_km2) - obs_norm_sorted = numpy.cumsum(obs_counts[I]) / numpy.sum(obs_counts) + fore_norm_sorted = numpy.cumsum(rate[indices]) / numpy.sum(rate) + area_norm_sorted = numpy.cumsum(area_km2[indices]) / numpy.sum(area_km2) + obs_norm_sorted = numpy.cumsum(obs_counts[indices]) / numpy.sum(obs_counts) # Plot data if plot_uniform: @@ -990,27 +993,36 @@ def plot_concentration_ROC_diagram( area_norm_sorted, fore_norm_sorted, label=forecast_label, - color=plot_args['secondary_color'] + color=plot_args["secondary_color"], ) ax.step( area_norm_sorted, obs_norm_sorted, label=observed_label, - color=plot_args['color'], - linestyle=plot_args['linestyle'], + color=plot_args["color"], + linestyle=plot_args["linestyle"], ) # Plot formatting - ax.set_title(plot_args['title'], fontsize=plot_args['title_fontsize']) + ax.set_title(plot_args["title"], fontsize=plot_args["title_fontsize"]) ax.grid(plot_args["grid"]) if not linear: ax.set_xscale("log") - ax.set_ylabel(plot_args['ylabel'] or "True Positive Rate", fontsize=plot_args['ylabel_fontsize']) - ax.set_xlabel(plot_args['xlabel'] or "False Positive Rate (Normalized Area)", fontsize=plot_args['xlabel_fontsize']) + ax.set_ylabel( + plot_args["ylabel"] or "True Positive Rate", fontsize=plot_args["ylabel_fontsize"] + ) + ax.set_xlabel( + plot_args["xlabel"] or "False Positive Rate (Normalized Area)", + fontsize=plot_args["xlabel_fontsize"], + ) if plot_args["legend"]: - ax.legend(loc=plot_args['legend_loc'], shadow=True, fontsize=plot_args['legend_fontsize'], - framealpha=plot_args['legend_framealpha']) + ax.legend( + loc=plot_args["legend_loc"], + shadow=True, + fontsize=plot_args["legend_fontsize"], + framealpha=plot_args["legend_framealpha"], + ) if plot_args["tight_layout"]: fig.tight_layout() if show: @@ -1020,28 +1032,30 @@ def plot_concentration_ROC_diagram( def plot_ROC_diagram( - forecast: "GriddedForecast", - catalog: "CSEPCatalog", - linear: bool = True, - plot_uniform: bool = True, - show: bool = True, - ax: Optional[pyplot.Axes] = None, - **kwargs + forecast: "GriddedForecast", + catalog: "CSEPCatalog", + linear: bool = True, + plot_uniform: bool = True, + show: bool = True, + ax: Optional[pyplot.Axes] = None, + **kwargs, ) -> matplotlib.pyplot.Axes: """ - Plots the ROC (Receiver Operating Characteristic) curve for a given forecast and observed catalog. - - Args: - forecast (GriddedForecast): Forecast object containing spatial forecast data. - catalog (CSEPCatalog): Catalog object containing observed data. - linear (bool): If True, uses a linear scale for the X-axis, otherwise logarithmic. - plot_uniform (bool): If True, plots the uniform (random) model as a reference (default: True). - show (bool): If True, displays the plot (default: True). - ax (Optional[pyplot.Axes]): Axes object to plot on (default: None). - **kwargs: Additional keyword arguments for customization. - - Returns: - pyplot.Axes: The Axes object with the plot. + Plots the ROC (Receiver Operating Characteristic) curve for a given forecast and observed + catalog. + + Args: + forecast (GriddedForecast): Forecast object containing spatial forecast data. + catalog (CSEPCatalog): Catalog object containing observed data. + linear (bool): If True, uses a linear scale for the X-axis, otherwise logarithmic. + plot_uniform (bool): If True, plots the uniform (random) model as a reference (default: + True). + show (bool): If True, displays the plot (default: True). + ax (Optional[pyplot.Axes]): Axes object to plot on (default: None). + **kwargs: Additional keyword arguments for customization. + + Returns: + pyplot.Axes: The Axes object with the plot. """ # Initialize plot @@ -1054,10 +1068,10 @@ def plot_ROC_diagram( rate = forecast.spatial_counts() obs_counts = catalog.spatial_counts() - I = numpy.argsort(rate)[::-1] # Sort in descending order + indices = numpy.argsort(rate)[::-1] # Sort in descending order - thresholds = (rate[I]) / numpy.sum(rate) - obs_counts = obs_counts[I] + thresholds = (rate[indices]) / numpy.sum(rate) + obs_counts = obs_counts[indices] Table_ROC = pandas.DataFrame({"Threshold": [], "H": [], "F": []}) @@ -1089,8 +1103,8 @@ def plot_ROC_diagram( Table_ROC["F"], Table_ROC["H"], label=plot_args.get("forecast_label", forecast.name or "Forecast"), - color=plot_args['color'], - linestyle=plot_args['linestyle'], + color=plot_args["color"], + linestyle=plot_args["linestyle"], ) if plot_uniform: @@ -1103,18 +1117,21 @@ def plot_ROC_diagram( ) # Plot formatting - ax.set_ylabel(plot_args['ylabel'] or "Hit Rate", fontsize=plot_args['ylabel_fontsize']) - ax.set_xlabel(plot_args['xlabel'] or "Fraction of False Alarms", fontsize=plot_args['xlabel_fontsize']) + ax.set_ylabel(plot_args["ylabel"] or "Hit Rate", fontsize=plot_args["ylabel_fontsize"]) + ax.set_xlabel( + plot_args["xlabel"] or "Fraction of False Alarms", fontsize=plot_args["xlabel_fontsize"] + ) if not linear: ax.set_xscale("log") ax.set_yscale("linear") - ax.tick_params(axis="x", labelsize=plot_args['xticks_fontsize']) - ax.tick_params(axis="y", labelsize=plot_args['yticks_fontsize']) - if plot_args['legend']: - ax.legend(loc=plot_args['legend_loc'], shadow=True, - fontsize=plot_args['legend_fontsize']) - ax.set_title(plot_args['title'], fontsize=plot_args['title_fontsize']) - if plot_args['tight_layout']: + ax.tick_params(axis="x", labelsize=plot_args["xticks_fontsize"]) + ax.tick_params(axis="y", labelsize=plot_args["yticks_fontsize"]) + if plot_args["legend"]: + ax.legend( + loc=plot_args["legend_loc"], shadow=True, fontsize=plot_args["legend_fontsize"] + ) + ax.set_title(plot_args["title"], fontsize=plot_args["title_fontsize"]) + if plot_args["tight_layout"]: fig.tight_layout() if show: @@ -1124,13 +1141,13 @@ def plot_ROC_diagram( def plot_Molchan_diagram( - forecast: "GriddedForecast", - catalog: "CSEPCatalog", - linear: bool = True, - plot_uniform: bool = True, - show: bool = True, - ax: Optional[pyplot.Axes] = None, - **kwargs + forecast: "GriddedForecast", + catalog: "CSEPCatalog", + linear: bool = True, + plot_uniform: bool = True, + show: bool = True, + ax: Optional[pyplot.Axes] = None, + **kwargs, ) -> matplotlib.axes.Axes: """ Plot the Molchan Diagram based on forecast and test catalogs using the contingency table. @@ -1139,13 +1156,15 @@ def plot_Molchan_diagram( The Molchan diagram is computed following this procedure: 1. Obtain spatial rates from the GriddedForecast and the observed events from the catalog. 2. Rank the rates in descending order (highest rates first). - 3. Sort forecasted rates by ordering found in (2), and normalize rates so their sum is equal to unity. + 3. Sort forecasted rates by ordering found in (2), and normalize rates so their sum is equal + to unity. 4. Obtain binned spatial rates from the observed catalog. 5. Sort gridded observed rates by ordering found in (2). - 6. Test each ordered and normalized forecasted rate defined in (3) as a threshold value to obtain the - corresponding contingency table. - 7. Define the "nu" (Miss rate) and "tau" (Fraction of spatial alarmed cells) for each threshold using the - information provided by the corresponding contingency table defined in (6). + 6. Test each ordered and normalized forecasted rate defined in (3) as a threshold value to + obtain the corresponding contingency table. + 7. Define the "nu" (Miss rate) and "tau" (Fraction of spatial alarmed cells) for each + threshold using the information provided by the corresponding contingency table defined in + (6). Note: 1. The testing catalog and forecast should have exactly the same time-window (duration). @@ -1182,12 +1201,12 @@ def plot_Molchan_diagram( obs_counts = catalog.spatial_counts() # Get index of rates (descending sort) - I = numpy.argsort(rate) - I = numpy.flip(I) + indices = numpy.argsort(rate) + indices = numpy.flip(indices) # Order forecast and cells rates by highest rate cells first - thresholds = (rate[I]) / numpy.sum(rate) - obs_counts = obs_counts[I] + thresholds = (rate[indices]) / numpy.sum(rate) + obs_counts = obs_counts[indices] Table_molchan = pandas.DataFrame( { @@ -1280,11 +1299,11 @@ def plot_Molchan_diagram( ) ASscore = numpy.round(Tab_as_score.loc[Tab_as_score.index[-1], "AS_score"], 2) - bin = 0.01 + bin_size = 0.01 devstd = numpy.sqrt(1 / (12 * Table_molchan["Obs_active_bins"].iloc[0])) - devstd = devstd * bin**-1 + devstd = devstd * bin_size**-1 devstd = numpy.ceil(devstd + 0.5) - devstd = devstd / bin**-1 + devstd = devstd / bin_size**-1 dev_std = numpy.round(devstd, 2) # Plot the Molchan trajectory @@ -1292,8 +1311,8 @@ def plot_Molchan_diagram( Table_molchan["tau"], Table_molchan["nu"], label=f"{forecast_label}, ASS={ASscore}±{dev_std} ", - color=plot_args['color'], - linestyle=plot_args['linestyle'], + color=plot_args["color"], + linestyle=plot_args["linestyle"], ) # Plot uniform forecast @@ -1303,14 +1322,17 @@ def plot_Molchan_diagram( ax.plot(x_uniform, y_uniform, linestyle="--", color="gray", label="Uniform") # Plot formatting - ax.set_ylabel(plot_args['ylabel'] or "Miss Rate", fontsize=plot_args['ylabel_fontsize']) - ax.set_xlabel(plot_args['xlabel'] or "Fraction of area occupied by alarms", fontsize=plot_args['xlabel_fontsize']) + ax.set_ylabel(plot_args["ylabel"] or "Miss Rate", fontsize=plot_args["ylabel_fontsize"]) + ax.set_xlabel( + plot_args["xlabel"] or "Fraction of area occupied by alarms", + fontsize=plot_args["xlabel_fontsize"], + ) if not linear: ax.set_xscale("log") - ax.tick_params(axis="x", labelsize=plot_args['xlabel_fontsize']) - ax.tick_params(axis="y", labelsize=plot_args['ylabel_fontsize']) - ax.legend(loc=plot_args['legend_loc'], shadow=True, fontsize=plot_args['legend_fontsize']) - ax.set_title(plot_args['title'] or "Molchan Diagram", fontsize=plot_args['title_fontsize']) + ax.tick_params(axis="x", labelsize=plot_args["xlabel_fontsize"]) + ax.tick_params(axis="y", labelsize=plot_args["ylabel_fontsize"]) + ax.legend(loc=plot_args["legend_loc"], shadow=True, fontsize=plot_args["legend_fontsize"]) + ax.set_title(plot_args["title"] or "Molchan Diagram", fontsize=plot_args["title_fontsize"]) if plot_args["tight_layout"]: fig.tight_layout() @@ -1392,7 +1414,7 @@ def plot_basemap( ax.add_image(basemap_obj, tile_depth) # basemap_obj is a rasterio image elif isinstance(basemap_obj, DatasetReader): - ax = rioplot.show(basemap_obj, ax=ax) + ax = rio_plot.show(basemap_obj, ax=ax) except Exception as e: print( @@ -1463,8 +1485,14 @@ def plot_catalog( ax.scatter( catalog.get_longitudes(), catalog.get_latitudes(), - s=_autosize_scatter(values=catalog.get_magnitudes(), min_size=size, max_size=max_size, - power=power, min_val=min_val, max_val=max_val), + s=_autosize_scatter( + values=catalog.get_magnitudes(), + min_size=size, + max_size=max_size, + power=power, + min_val=min_val, + max_val=max_val, + ), transform=ccrs.PlateCarree(), color=plot_args["markercolor"], edgecolors=plot_args["markeredgecolor"], @@ -1486,15 +1514,25 @@ def plot_catalog( max_size=max_size, power=power, min_val=min_val or np.min(catalog.get_magnitudes()), - max_val=max_val or np.max(catalog.get_magnitudes()) + max_val=max_val or np.max(catalog.get_magnitudes()), ) # Create custom legend handles - handles = [pyplot.Line2D([0], [0], marker='o', lw=0, label=str(m), - markersize=np.sqrt(s), markerfacecolor='gray', alpha=0.5, - markeredgewidth=0.8, - markeredgecolor='black') - for m, s in zip(mag_ticks, legend_sizes)] + handles = [ + pyplot.Line2D( + [0], + [0], + marker="o", + lw=0, + label=str(m), + markersize=np.sqrt(s), + markerfacecolor="gray", + alpha=0.5, + markeredgewidth=0.8, + markeredgecolor="black", + ) + for m, s in zip(mag_ticks, legend_sizes) + ] ax.legend( handles, @@ -1581,7 +1619,7 @@ def plot_spatial_dataset( ax = plot_basemap(basemap, extent, ax=ax, set_global=set_global, show=False, **plot_args) # Define colormap and alpha transparency - colormap, alpha = _define_colormap_and_alpha(colormap, alpha_exp, alpha) + colormap, alpha = _get_colormap(colormap, alpha_exp, alpha) # Plot spatial dataset lons, lats = numpy.meshgrid( @@ -1595,10 +1633,18 @@ def plot_spatial_dataset( # Colorbar options if colorbar: - _add_colorbar( - ax, im, clabel, plot_args["colorbar_labelsize"], plot_args["colorbar_ticksize"] + cax = ax.get_figure().add_axes( + [ + ax.get_position().x1 + 0.01, + ax.get_position().y0, + 0.025, + ax.get_position().height, + ], + label="Colorbar", ) - + cbar = ax.get_figure().colorbar(im, ax=ax, cax=cax) + cbar.set_label(clabel, fontsize=plot_args["colorbar_labelsize"]) + cbar.ax.tick_params(labelsize=plot_args["colorbar_ticksize"]) # Draw forecast's region border if plot_region and not set_global: try: @@ -1618,8 +1664,18 @@ def plot_spatial_dataset( ##################### # Plot helper functions ##################### -def _get_marker_style(obs_stat, p, one_sided_lower): - """Returns matplotlib marker style as fmt string""" +def _get_marker_style(obs_stat: float, p: Sequence[float], one_sided_lower: bool) -> str: + """ + Returns the matplotlib marker style as a format string. + + Args: + obs_stat (float): The observed statistic. + p (Sequence[float, float]): A tuple of lower and upper percentiles. + one_sided_lower (bool): Indicates if the test is one-sided lower. + + Returns: + str: A format string representing the marker style. + """ if obs_stat < p[0] or obs_stat > p[1]: # red circle fmt = "ro" @@ -1634,21 +1690,39 @@ def _get_marker_style(obs_stat, p, one_sided_lower): return fmt -def _get_marker_t_color(distribution): - """Returns matplotlib marker style as fmt string""" +def _get_marker_t_color(distribution: Sequence[float]) -> str: + """ + Returns the color for the marker based on the distribution. + + Args: + distribution (Sequence[float, float]): A tuple representing the lower and upper bounds + of the test distribution. + + Returns: + str: Marker color + """ if distribution[0] > 0.0 and distribution[1] > 0.0: - fmt = "green" + color = "green" elif distribution[0] < 0.0 and distribution[1] < 0.0: - fmt = "red" + color = "red" else: - fmt = "grey" + color = "grey" + + return color - return fmt +def _get_marker_w_color(distribution: float, percentile: float) -> bool: + """ + Returns a boolean indicating whether the distribution's percentile is below a given + threshold. -def _get_marker_w_color(distribution, percentile): - """Returns matplotlib marker style as fmt string""" + Args: + distribution (float): The value of the distribution's percentile. + percentile (float): The percentile threshold. + Returns: + bool: True if the distribution's percentile is below the threshold, False otherwise. + """ if distribution < (1 - percentile / 100): fmt = True else: @@ -1657,34 +1731,59 @@ def _get_marker_w_color(distribution, percentile): return fmt -def _get_axis_limits(pnts, border=0.05): - """Returns a tuple of x_min and x_max given points on plot.""" - x_min = numpy.min(pnts) - x_max = numpy.max(pnts) +def _get_axis_limits(points: Union[Sequence, numpy.ndarray], + border: float = 0.05) -> Tuple[float, float]: + """ + Returns a tuple of x_min and x_max given points on a plot. + + Args: + points (numpy.ndarray): An array of points. + border (float): The border fraction to apply to the limits. + + Returns: + Sequence[float, float]: The x_min and x_max values adjusted with the border. + """ + x_min = numpy.min(points) + x_max = numpy.max(points) xd = (x_max - x_min) * border return x_min - xd, x_max + xd -def _get_basemap(basemap): - last_cache = os.path.join(os.path.dirname(cartopy.config["cache_dir"]), 'last_cartopy_cache') +def _get_basemap(basemap: str) -> Union[img_tiles.GoogleTiles, DatasetReader]: + """ + Returns the basemap tiles for a given basemap type or web service. + + Args: + basemap (str): The type of basemap for cartopy, an URL for a web service or a TIF file + path. + + Returns: + Union[img_tiles.GoogleTiles, rasterio.io.DatasetReader]: The corresponding tiles or + raster object. + + """ + last_cache = os.path.join( + os.path.dirname(cartopy.config["cache_dir"]), "last_cartopy_cache" + ) def _clean_cache(basemap_): if os.path.isfile(last_cache): - with open(last_cache, 'r') as fp: + with open(last_cache, "r") as fp: cache_src = fp.read() if cache_src != basemap_: if os.path.isdir(cartopy.config["cache_dir"]): - print(f'Cleaning existing {basemap_} cache') + print(f"Cleaning existing {basemap_} cache") shutil.rmtree(cartopy.config["cache_dir"]) def _save_cache_src(basemap_): - with open(last_cache, 'w') as fp: + with open(last_cache, "w") as fp: fp.write(basemap_) cache = True - warning_message_to_suppress = ('Cartopy created the following directory to cache' - ' GoogleWTS tiles') + warning_message_to_suppress = ( + "Cartopy created the following directory to cache" " GoogleWTS tiles" + ) with warnings.catch_warnings(): warnings.filterwarnings("ignore", message=warning_message_to_suppress) if basemap == "google-satellite": @@ -1729,7 +1828,7 @@ def _save_cache_src(basemap_): _save_cache_src(basemap) elif os.path.isfile(basemap): - return rasterio.open(basemap) + return rio_open(basemap) else: try: @@ -1743,409 +1842,28 @@ def _save_cache_src(basemap_): return tiles -def _add_labels_for_publication(figure, style="bssa", labelsize=16): - """Adds publication labels too the outside of a figure.""" - all_axes = figure.get_axes() - ascii_iter = iter(string.ascii_lowercase) - for ax in all_axes: - # check for colorbar and ignore for annotations - if ax.get_label() == "Colorbar": - continue - annot = next(ascii_iter) - if style == "bssa": - ax.annotate( - f"({annot})", (0.025, 1.025), xycoords="axes fraction", fontsize=labelsize - ) - - return - - -def _plot_pvalues_and_intervals(test_results, ax, var=None): - """Plots p-values and intervals for a list of Poisson or NBD test results +def _autosize_scatter( + values: numpy.ndarray, + min_size: float = 50.0, + max_size: float = 400.0, + power: float = 3.0, + min_val: Optional[float] = None, + max_val: Optional[float] = None, +) -> numpy.ndarray: + """ + Auto-sizes scatter plot markers based on values. Args: - test_results (list): list of EvaluationResults for N-test. All tests should use the same - distribution (ie Poisson or NBD). - ax (matplotlib.axes.Axes.axis): axes to use for plot. create using matplotlib - var (float): variance of the NBD distribution. Must be used for NBD plots. + values (numpy.ndarray): The data values (e.g., magnitude) to base the sizing on. + min_size (float): The minimum marker size. + max_size (float): The maximum marker size. + power (float): The power to apply for scaling. + min_val (Optional[float]): The minimum value (e.g., magnitude) for normalization. + max_val (Optional[float]): The maximum value (e.g., magnitude) for normalization. Returns: - ax (matplotlib.axes.Axes.axis): axes handle containing this plot - - Raises: - ValueError: throws error if NBD tests are supplied without a variance + numpy.ndarray: The calculated marker sizes. """ - - variance = var - percentile = 97.5 - p_values = [] - - # Differentiate between N-tests and other consistency tests - if test_results[0].name == "NBD N-Test" or test_results[0].name == "Poisson N-Test": - legend_elements = [ - matplotlib.lines.Line2D( - [0], - [0], - marker="o", - color="red", - lw=0, - label=r"p < 10e-5", - markersize=10, - markeredgecolor="k", - ), - matplotlib.lines.Line2D( - [0], - [0], - marker="o", - color="#FF7F50", - lw=0, - label=r"10e-5 $\leq$ p < 10e-4", - markersize=10, - markeredgecolor="k", - ), - matplotlib.lines.Line2D( - [0], - [0], - marker="o", - color="gold", - lw=0, - label=r"10e-4 $\leq$ p < 10e-3", - markersize=10, - markeredgecolor="k", - ), - matplotlib.lines.Line2D( - [0], - [0], - marker="o", - color="white", - lw=0, - label=r"10e-3 $\leq$ p < 0.0125", - markersize=10, - markeredgecolor="k", - ), - matplotlib.lines.Line2D( - [0], - [0], - marker="o", - color="skyblue", - lw=0, - label=r"0.0125 $\leq$ p < 0.025", - markersize=10, - markeredgecolor="k", - ), - matplotlib.lines.Line2D( - [0], - [0], - marker="o", - color="blue", - lw=0, - label=r"p $\geq$ 0.025", - markersize=10, - markeredgecolor="k", - ), - ] - ax.legend(handles=legend_elements, loc=4, fontsize=13, edgecolor="k") - # Act on Negative binomial tests - if test_results[0].name == "NBD N-Test": - if var is None: - raise ValueError("var must not be None if N-tests use the NBD distribution.") - - for i in range(len(test_results)): - mean = test_results[i].test_distribution[1] - upsilon = 1.0 - ((variance - mean) / variance) - tau = mean**2 / (variance - mean) - phigh97 = scipy.stats.nbinom.ppf((1 - percentile / 100.0) / 2.0, tau, upsilon) - plow97 = scipy.stats.nbinom.ppf( - 1 - (1 - percentile / 100.0) / 2.0, tau, upsilon - ) - low97 = test_results[i].observed_statistic - plow97 - high97 = phigh97 - test_results[i].observed_statistic - ax.errorbar( - test_results[i].observed_statistic, - (len(test_results) - 1) - i, - xerr=numpy.array([[low97, high97]]).T, - capsize=4, - color="slategray", - alpha=1.0, - zorder=0, - ) - p_values.append( - test_results[i].quantile[1] * 2.0 - ) # Calculated p-values according to Meletti et al., (2021) - - if p_values[i] < 10e-5: - ax.plot( - test_results[i].observed_statistic, - (len(test_results) - 1) - i, - marker="o", - color="red", - markersize=8, - zorder=2, - ) - if p_values[i] >= 10e-5 and p_values[i] < 10e-4: - ax.plot( - test_results[i].observed_statistic, - (len(test_results) - 1) - i, - marker="o", - color="#FF7F50", - markersize=8, - zorder=2, - ) - if p_values[i] >= 10e-4 and p_values[i] < 10e-3: - ax.plot( - test_results[i].observed_statistic, - (len(test_results) - 1) - i, - marker="o", - color="gold", - markersize=8, - zorder=2, - ) - if p_values[i] >= 10e-3 and p_values[i] < 0.0125: - ax.plot( - test_results[i].observed_statistic, - (len(test_results) - 1) - i, - marker="o", - color="white", - markersize=8, - zorder=2, - ) - if p_values[i] >= 0.0125 and p_values[i] < 0.025: - ax.plot( - test_results[i].observed_statistic, - (len(test_results) - 1) - i, - marker="o", - color="skyblue", - markersize=8, - zorder=2, - ) - if p_values[i] >= 0.025: - ax.plot( - test_results[i].observed_statistic, - (len(test_results) - 1) - i, - marker="o", - color="blue", - markersize=8, - zorder=2, - ) - # Act on Poisson N-test - if test_results[0].name == "Poisson N-Test": - for i in range(len(test_results)): - plow97 = scipy.stats.poisson.ppf( - (1 - percentile / 100.0) / 2.0, test_results[i].test_distribution[1] - ) - phigh97 = scipy.stats.poisson.ppf( - 1 - (1 - percentile / 100.0) / 2.0, test_results[i].test_distribution[1] - ) - low97 = test_results[i].observed_statistic - plow97 - high97 = phigh97 - test_results[i].observed_statistic - ax.errorbar( - test_results[i].observed_statistic, - (len(test_results) - 1) - i, - xerr=numpy.array([[low97, high97]]).T, - capsize=4, - color="slategray", - alpha=1.0, - zorder=0, - ) - p_values.append(test_results[i].quantile[1] * 2.0) - if p_values[i] < 10e-5: - ax.plot( - test_results[i].observed_statistic, - (len(test_results) - 1) - i, - marker="o", - color="red", - markersize=8, - zorder=2, - ) - elif p_values[i] >= 10e-5 and p_values[i] < 10e-4: - ax.plot( - test_results[i].observed_statistic, - (len(test_results) - 1) - i, - marker="o", - color="#FF7F50", - markersize=8, - zorder=2, - ) - elif p_values[i] >= 10e-4 and p_values[i] < 10e-3: - ax.plot( - test_results[i].observed_statistic, - (len(test_results) - 1) - i, - marker="o", - color="gold", - markersize=8, - zorder=2, - ) - elif p_values[i] >= 10e-3 and p_values[i] < 0.0125: - ax.plot( - test_results[i].observed_statistic, - (len(test_results) - 1) - i, - marker="o", - color="white", - markersize=8, - zorder=2, - ) - elif p_values[i] >= 0.0125 and p_values[i] < 0.025: - ax.plot( - test_results[i].observed_statistic, - (len(test_results) - 1) - i, - marker="o", - color="skyblue", - markersize=8, - zorder=2, - ) - elif p_values[i] >= 0.025: - ax.plot( - test_results[i].observed_statistic, - (len(test_results) - 1) - i, - marker="o", - color="blue", - markersize=8, - zorder=2, - ) - # Operate on all other consistency tests - else: - for i in range(len(test_results)): - plow97 = numpy.percentile(test_results[i].test_distribution, 2.5) - phigh97 = numpy.percentile(test_results[i].test_distribution, 97.5) - low97 = test_results[i].observed_statistic - plow97 - high97 = phigh97 - test_results[i].observed_statistic - ax.errorbar( - test_results[i].observed_statistic, - (len(test_results) - 1) - i, - xerr=numpy.array([[low97, high97]]).T, - capsize=4, - color="slategray", - alpha=1.0, - zorder=0, - ) - p_values.append(test_results[i].quantile) - - if p_values[i] < 10e-5: - ax.plot( - test_results[i].observed_statistic, - (len(test_results) - 1) - i, - marker="o", - color="red", - markersize=8, - zorder=2, - ) - elif p_values[i] >= 10e-5 and p_values[i] < 10e-4: - ax.plot( - test_results[i].observed_statistic, - (len(test_results) - 1) - i, - marker="o", - color="#FF7F50", - markersize=8, - zorder=2, - ) - elif p_values[i] >= 10e-4 and p_values[i] < 10e-3: - ax.plot( - test_results[i].observed_statistic, - (len(test_results) - 1) - i, - marker="o", - color="gold", - markersize=8, - zorder=2, - ) - elif p_values[i] >= 10e-3 and p_values[i] < 0.025: - ax.plot( - test_results[i].observed_statistic, - (len(test_results) - 1) - i, - marker="o", - color="white", - markersize=8, - zorder=2, - ) - elif p_values[i] >= 0.025 and p_values[i] < 0.05: - ax.plot( - test_results[i].observed_statistic, - (len(test_results) - 1) - i, - marker="o", - color="skyblue", - markersize=8, - zorder=2, - ) - elif p_values[i] >= 0.05: - ax.plot( - test_results[i].observed_statistic, - (len(test_results) - 1) - i, - marker="o", - color="blue", - markersize=8, - zorder=2, - ) - - legend_elements = [ - matplotlib.lines.Line2D( - [0], - [0], - marker="o", - color="red", - lw=0, - label=r"p < 10e-5", - markersize=10, - markeredgecolor="k", - ), - matplotlib.lines.Line2D( - [0], - [0], - marker="o", - color="#FF7F50", - lw=0, - label=r"10e-5 $\leq$ p < 10e-4", - markersize=10, - markeredgecolor="k", - ), - matplotlib.lines.Line2D( - [0], - [0], - marker="o", - color="gold", - lw=0, - label=r"10e-4 $\leq$ p < 10e-3", - markersize=10, - markeredgecolor="k", - ), - matplotlib.lines.Line2D( - [0], - [0], - marker="o", - color="white", - lw=0, - label=r"10e-3 $\leq$ p < 0.025", - markersize=10, - markeredgecolor="k", - ), - matplotlib.lines.Line2D( - [0], - [0], - marker="o", - color="skyblue", - lw=0, - label=r"0.025 $\leq$ p < 0.05", - markersize=10, - markeredgecolor="k", - ), - matplotlib.lines.Line2D( - [0], - [0], - marker="o", - color="blue", - lw=0, - label=r"p $\geq$ 0.05", - markersize=10, - markeredgecolor="k", - ), - ] - - ax.legend(handles=legend_elements, loc=4, fontsize=13, edgecolor="k") - - return ax - - -def _autosize_scatter(values, min_size=50., max_size=400., power=3.0, min_val=None, - max_val=None): - min_val = min_val or np.min(values) max_val = max_val or np.max(values) normalized_values = ((values - min_val) / (max_val - min_val)) ** power @@ -2153,7 +1871,26 @@ def _autosize_scatter(values, min_size=50., max_size=400., power=3.0, min_val=No return marker_sizes -def _autoscale_histogram(ax: pyplot.Axes, bin_edges, simulated, observation, mass=99.5): +def _autoscale_histogram( + ax: matplotlib.axes.Axes, + bin_edges: numpy.ndarray, + simulated: numpy.ndarray, + observation: numpy.ndarray, + mass: float = 99.5, +) -> matplotlib.axes.Axes: + """ + Autoscale the histogram axes based on the data distribution. + + Args: + ax (matplotlib.axes.Axes): The axes to apply the scaling to. + bin_edges (numpy.ndarray): The edges of the histogram bins. + simulated (numpy.ndarray): Simulated data values. + observation (numpy.ndarray): Observed data values. + mass (float): The percentage of the data mass to consider. + + Returns: + matplotlib.axes.Axes: The scaled axes + """ upper_xlim = numpy.percentile(simulated, 100 - (100 - mass) / 2) upper_xlim = numpy.max([upper_xlim, numpy.max(observation)]) @@ -2180,10 +1917,23 @@ def _autoscale_histogram(ax: pyplot.Axes, bin_edges, simulated, observation, mas def _annotate_distribution_plot( - ax, evaluation_result, auto_annotate, plot_args + ax: matplotlib.axes.Axes, + evaluation_result: "EvaluationResult", + auto_annotate: bool, + plot_args: Dict[str, Any], ) -> matplotlib.axes.Axes: - """Returns specific plot details based on the type of evaluation_result.""" + """ + Annotates a distribution plot based on the evaluation result type. + + Args: + ax (matplotlib.axes.Axes): The axes to annotate. + evaluation_result (EvaluationResult): The evaluation result object. + auto_annotate (bool): If True, automatically annotates the plot based on result type. + plot_args (Dict[str, Any]): Additional plotting arguments. + Returns: + matplotlib.axes.Axes: The annotated axes. + """ annotation_text = None annotation_xy = None title = None @@ -2214,7 +1964,8 @@ def _annotate_distribution_plot( title = f"{evaluation_result.name}: {evaluation_result.sim_name}" annotation_xy = (0.2, 0.6) annotation_text = ( - f"$\\gamma = P(X \\leq x) = {numpy.array(evaluation_result.quantile).ravel()[-1]:.2f}$\n" + f"$\\gamma = P(X \\leq x) = " + f"{numpy.array(evaluation_result.quantile).ravel()[-1]:.2f}$\n" f"$\\omega = {evaluation_result.observed_statistic:.2f}$" ) @@ -2224,7 +1975,8 @@ def _annotate_distribution_plot( title = f"{evaluation_result.name}: {evaluation_result.sim_name}" annotation_xy = (0.55, 0.6) annotation_text = ( - f"$\\gamma = P(X \\geq x) = {numpy.array(evaluation_result.quantile).ravel()[0]:.2f}$\n" + f"$\\gamma = P(X \\geq x) = " + f"{numpy.array(evaluation_result.quantile).ravel()[0]:.2f}$\n" f"$\\omega = {evaluation_result.observed_statistic:.2f}$" ) elif evaluation_result.name == "Catalog PL-Test": @@ -2233,7 +1985,8 @@ def _annotate_distribution_plot( title = f"{evaluation_result.name}: {evaluation_result.sim_name}" annotation_xy = (0.55, 0.3) annotation_text = ( - f"$\\gamma = P(X \\leq x) = {numpy.array(evaluation_result.quantile).ravel()[-1]:.2f}$\n" + f"$\\gamma = P(X \\leq x) = " + f"{numpy.array(evaluation_result.quantile).ravel()[-1]:.2f}$\n" f"$\\omega = {evaluation_result.observed_statistic:.2f}$" ) @@ -2255,12 +2008,30 @@ def _annotate_distribution_plot( return ax -def _calculate_spatial_extent(catalog, set_global, region_border, padding_fraction=0.05): +def _calculate_spatial_extent( + element: Union["CSEPCatalog", "CartesianGrid2D"], + set_global: bool, + region_border: bool, + padding_fraction: float = 0.05, +) -> Optional[List[float]]: + """ + Calculates the spatial extent for plotting based on the catalog. + + Args: + element (CSEPCatalog), CartesianGrid2D: The catalog or region object to base the extent + on. + set_global (bool): If True, sets the extent to the global view. + region_border (bool): If True, uses the catalog's region border. + padding_fraction (float): The fraction of padding to apply to the extent. + + Returns: + Optional[List[float]]: The calculated extent or None if global view is set. + """ # todo: perhaps calculate extent also from chained ax object - bbox = catalog.get_bbox() + bbox = element.get_bbox() if region_border: try: - bbox = catalog.region.get_bbox() + bbox = element.region.get_bbox() except AttributeError: pass @@ -2272,7 +2043,24 @@ def _calculate_spatial_extent(catalog, set_global, region_border, padding_fracti return [bbox[0] - dh, bbox[1] + dh, bbox[2] - dv, bbox[3] + dv] -def _create_geo_axes(figsize, extent, projection, set_global): +def _create_geo_axes( + figsize: Optional[Tuple[float, float]], + extent: Optional[List[float]], + projection: Union[ccrs.Projection, str], + set_global: bool, +) -> pyplot.Axes: + """ + Creates and returns GeoAxes for plotting. + + Args: + figsize (Optional[Tuple[float, float]]): The size of the figure. + extent (Optional[List[float]]): The spatial extent to set. + projection (Union[ccrs.Projection, str]): The projection to use. + set_global (bool): If True, sets the global view. + + Returns: + pyplot.Axes: The created GeoAxes object. + """ if projection == "approx": fig = pyplot.figure(figsize=figsize) @@ -2291,7 +2079,15 @@ def _create_geo_axes(figsize, extent, projection, set_global): return ax -def _add_gridlines(ax, grid_labels, grid_fontsize): +def _add_gridlines(ax: matplotlib.axes.Axes, grid_labels: bool, grid_fontsize: float) -> None: + """ + Adds gridlines and optionally labels to the axes. + + Args: + ax (matplotlib.axes.Axes): The axes to add gridlines to. + grid_labels (bool): If True, labels the gridlines. + grid_fontsize (float): The font size of the grid labels. + """ gl = ax.gridlines(draw_labels=grid_labels, alpha=0.5) gl.right_labels = False gl.top_labels = False @@ -2301,18 +2097,22 @@ def _add_gridlines(ax, grid_labels, grid_fontsize): gl.yformatter = LATITUDE_FORMATTER -def _define_colormap_and_alpha(cmap, alpha_exp, alpha_0=None): +def _get_colormap( + cmap: Union[str, matplotlib.colors.Colormap], + alpha_exp: float, + alpha_0: Optional[float] = None, +) -> Tuple[matplotlib.colors.ListedColormap, Optional[float]]: """ Defines the colormap and applies alpha transparency based on the given parameters. Args: - cmap (str or matplotlib.colors.Colormap): The colormap to be used. - alpha_0 (float or None): If set, this alpha will be applied uniformly across the colormap. - alpha_exp (float): Exponent to control transparency scaling. If set to 0, no alpha scaling is applied. + cmap (Union[str, matplotlib.colors.Colormap]): The colormap to use. + alpha_exp (float): The exponent to control transparency scaling. + alpha_0 (Optional[float]): If set, applies a uniform alpha across the colormap. Returns: - cmap (matplotlib.colors.ListedColormap): The resulting colormap with applied alpha. - alpha (float or None): The alpha value used for the entire colormap, or None if alpha is scaled per color. + Tuple[matplotlib.colors.ListedColormap, Optional[float]]: The modified colormap + and the alpha value used for the entire colormap. """ # Get the colormap object if a string is provided @@ -2336,32 +2136,41 @@ def _define_colormap_and_alpha(cmap, alpha_exp, alpha_0=None): return cmap, alpha -def _add_colorbar(ax, im, clabel, clabel_fontsize, cticks_fontsize): - fig = ax.get_figure() - cax = fig.add_axes( - [ax.get_position().x1 + 0.01, ax.get_position().y0, 0.025, ax.get_position().height], - label="Colorbar", - ) - cbar = fig.colorbar(im, ax=ax, cax=cax) - cbar.set_label(clabel, fontsize=clabel_fontsize) - cbar.ax.tick_params(labelsize=cticks_fontsize) +def _process_stat_distribution( + res: "EvaluationResult", + percentile: float, + variance: Optional[float], + normalize: bool, + one_sided_lower: bool, +) -> Tuple[float, float, float, float]: + """ + Processes the statistical distribution based on its type and returns plotting values. + Args: + res (EvaluationResult): The evaluation result object containing the distribution data. + percentile (float): The percentile for calculating the confidence intervals. + variance (Optional[float]): The variance of the negative binomial distribution, if + applicable. + normalize (bool): If True, normalizes the distribution by the observed statistic. + one_sided_lower (bool): If True, performs a one-sided lower test. -def _process_stat_distribution(res, percentile, variance, normalize, one_sided_lower): - """Process the distribution based on its type and return plotting values.""" + Returns: + Tuple[float, float, float, float]: A tuple containing the lower percentile, + upper percentile, mean, and observed statistic. + """ dist_type = res.test_distribution[0] if dist_type == "poisson": mean = res.test_distribution[1] - plow = scipy.stats.poisson.ppf((1 - percentile / 100.0) / 2.0, mean) - phigh = scipy.stats.poisson.ppf(1 - (1 - percentile / 100.0) / 2.0, mean) + plow = poisson.ppf((1 - percentile / 100.0) / 2.0, mean) + phigh = poisson.ppf(1 - (1 - percentile / 100.0) / 2.0, mean) observed_statistic = res.observed_statistic elif dist_type == "negative_binomial": mean = res.test_distribution[1] upsilon = 1.0 - ((variance - mean) / variance) tau = mean**2 / (variance - mean) - plow = scipy.stats.nbinom.ppf((1 - percentile / 100.0) / 2.0, tau, upsilon) - phigh = scipy.stats.nbinom.ppf(1 - (1 - percentile / 100.0) / 2.0, tau, upsilon) + plow = nbinom.ppf((1 - percentile / 100.0) / 2.0, tau, upsilon) + phigh = nbinom.ppf(1 - (1 - percentile / 100.0) / 2.0, tau, upsilon) observed_statistic = res.observed_statistic else: diff --git a/requirements.yml b/requirements.yml index 82d6d180..be2fd220 100644 --- a/requirements.yml +++ b/requirements.yml @@ -11,7 +11,6 @@ dependencies: - pyproj - obspy - python-dateutil - - rasterio - cartopy - shapely - mercantile diff --git a/tests/test_plots.py b/tests/test_plots.py index e5de65fa..bd8139cd 100644 --- a/tests/test_plots.py +++ b/tests/test_plots.py @@ -14,9 +14,9 @@ import numpy from cartopy import crs as ccrs from matplotlib import colors -from matplotlib.text import Annotation import csep +from csep.core import catalogs from csep.core.catalog_evaluations import ( CatalogNumberTestResult, CatalogSpatialTestResult, @@ -24,7 +24,6 @@ CatalogPseudolikelihoodTestResult, CalibrationTestResult, ) -from csep.core import catalogs from csep.utils.plots import ( plot_cumulative_events_versus_time, plot_magnitude_vs_time, @@ -47,29 +46,30 @@ _get_marker_t_color, # noqa _get_marker_w_color, # noqa _get_axis_limits, # noqa - _add_labels_for_publication, # noqa _autosize_scatter, # noqa _autoscale_histogram, # noqa _annotate_distribution_plot, # noqa - _define_colormap_and_alpha, # noqa - _add_colorbar, # noqa + _get_colormap, # noqa _process_stat_distribution, # noqa ) def is_internet_available(): - """Check if internet is available by attempting to connect to a well-known host.""" try: - # Try to connect to Google's DNS server - socket.create_connection(("8.8.8.8", 53), timeout=1) + socket.create_connection(("8.8.8.8", 53), timeout=3) return True except OSError: return False -is_github_actions = os.getenv("GITHUB_ACTIONS") == "true" +def is_github_ci(): + if os.getenv("GITHUB_ACTIONS") or os.getenv("CI") or os.getenv("GITHUB_ACTION"): + return True + else: + return False + -show_plots = True +show_plots = False class TestPlots(unittest.TestCase): @@ -85,6 +85,7 @@ def savefig(self, ax, name): ax.figure.savefig(os.path.join(self.save_dir, name)) +# class TestTimeSeriesPlots(TestPlots): def setUp(self): @@ -118,13 +119,14 @@ def test_plot_magnitude_vs_time(self): self.assertEqual(ax.get_ylabel(), "$M$") # Test with custom color - ax = plot_magnitude_vs_time(catalog=self.observation_m2, color='red', show=show_plots) + ax = plot_magnitude_vs_time(catalog=self.observation_m2, color="red", show=show_plots) scatter_color = ax.collections[0].get_facecolor()[0] self.assertTrue(all(scatter_color[:3] == (1.0, 0.0, 0.0))) # Check if color is red # Test with custom marker size - ax = plot_magnitude_vs_time(catalog=self.observation_m2, size=25, max_size=600, - show=show_plots) + ax = plot_magnitude_vs_time( + catalog=self.observation_m2, size=25, max_size=600, show=show_plots + ) scatter_sizes = ax.collections[0].get_sizes() func_sizes = _autosize_scatter(self.observation_m2.data["magnitude"], 25, 600, 4) numpy.testing.assert_array_almost_equal(scatter_sizes, func_sizes) @@ -141,14 +143,15 @@ def test_plot_magnitude_vs_time(self): numpy.testing.assert_array_almost_equal(scatter_sizes, func_sizes) # # # Test with show=True (just to ensure no errors occur) - plot_magnitude_vs_time(catalog=self.observation_m2, show=True) + plot_magnitude_vs_time(catalog=self.observation_m2, show=False) + plt.close("all") def test_plot_cumulative_events_default(self): # Test with default arguments to ensure basic functionality ax = plot_cumulative_events_versus_time( catalog_forecast=self.stochastic_event_sets, observation=self.observation_m5, - show=show_plots + show=show_plots, ) self.assertIsNotNone(ax.get_title()) @@ -166,7 +169,7 @@ def test_plot_cumulative_events_hours(self): ylabel="Cumulative Event Count", title="Cumulative Event Counts by Hour", legend_loc="upper left", - show=show_plots + show=show_plots, ) self.assertEqual(ax.get_xlabel(), "Hours since Mainshock") @@ -185,7 +188,7 @@ def test_plot_cumulative_events_different_bins(self): xlabel="Days since Mainshock", ylabel="Cumulative Event Count", title="Cumulative Event Counts with More Bins", - legend_loc="best" + legend_loc="best", ) self.assertEqual(ax.get_title(), "Cumulative Event Counts with More Bins") @@ -205,7 +208,7 @@ def test_plot_cumulative_events_custom_legend(self): ylabel="Cumulative Event Count", title="Cumulative Event Counts with Custom Legend", legend_loc="lower right", - legend_fontsize=14 + legend_fontsize=14, ) self.assertEqual(ax.get_legend()._get_loc(), 4) @@ -237,7 +240,6 @@ def gr_dist(num_events, mag_min=3.0, mag_max=8.0, b_val=1.0): self.mock_cat.get_magnitudes.return_value = gr_dist(500, b_val=1.2) self.mock_cat.get_number_of_events.return_value = 500 self.mock_cat.region.magnitudes = numpy.arange(3.0, 8.0, 0.1) - self.save_dir = os.path.join(os.path.dirname(__file__), "artifacts", "plots") cat_file_m5 = os.path.join( self.artifacts, @@ -259,28 +261,19 @@ def gr_dist(num_events, mag_min=3.0, mag_max=8.0, b_val=1.0): def test_plot_magnitude_histogram_basic(self): # Test with basic arguments - ax = plot_magnitude_histogram(self.mock_forecast, - self.mock_cat, show=show_plots, - density=True) + plot_magnitude_histogram( + self.mock_forecast, self.mock_cat, show=show_plots, density=True + ) # Verify that magnitudes were retrieved for catalog in self.mock_forecast: catalog.get_magnitudes.assert_called_once() self.mock_cat.get_magnitudes.assert_called_once() self.mock_cat.get_number_of_events.assert_called_once() - ax.figure.savefig(os.path.join(self.save_dir, "magnitude_histogram.png")) def test_plot_magnitude_histogram_ucerf(self): # Test with basic arguments - ax = plot_magnitude_histogram(self.stochastic_event_sets, self.comcat, - show=show_plots) - - # # Verify that magnitudes were retrieved - # for catalog in self.stochastic_event_sets: - # catalog.get_magnitudes.assert_called_once() - # self.comcat.get_magnitudes.assert_called_once() - # self.comcat.get_number_of_events.assert_called_once() - ax.figure.savefig(os.path.join(self.save_dir, "magnitude_histogram_ucerf.png")) + plot_magnitude_histogram(self.stochastic_event_sets, self.comcat, show=show_plots) def tearDown(self): plt.close("all") @@ -404,45 +397,39 @@ def test_plot_dist_test_xlim(self): xlim=xlim, show=show_plots, ) - self.savefig(ax, "plot_dist_test_xlims.png") self.assertEqual(ax.get_xlim(), xlim) def test_plot_dist_test_autoxlim_nan(self): - ax = plot_distribution_test( + plot_distribution_test( evaluation_result=self.result_nan, percentile=95, show=show_plots, ) - self.savefig(ax, "plot_dist_test_xlims_inf.png") def test_plot_n_test(self): - ax = plot_distribution_test( + plot_distribution_test( self.n_test, show=show_plots, ) - self.savefig(ax, "plot_n_test.png") def test_plot_m_test(self): - ax = plot_distribution_test( + plot_distribution_test( self.m_test, show=show_plots, ) - self.savefig(ax, "plot_m_test.png") def test_plot_s_test(self): - ax = plot_distribution_test( + plot_distribution_test( self.s_test, show=show_plots, ) - self.savefig(ax, "plot_s_test.png") def test_plot_l_test(self): - ax = plot_distribution_test( + plot_distribution_test( self.l_test, show=show_plots, ) - self.savefig(ax, "plot_l_test.png") def tearDown(self): plt.close("all") @@ -523,7 +510,7 @@ def setUp(self): def test_plot_consistency_basic(self): ax = plot_consistency_test(eval_results=self.mock_result, show=show_plots) - self.assertEqual(ax.get_title(), '') + self.assertEqual(ax.get_title(), "") self.assertEqual(ax.get_xlabel(), "Statistic distribution") def test_plot_consistency_with_multiple_results(self): @@ -532,8 +519,9 @@ def test_plot_consistency_with_multiple_results(self): self.assertEqual(len(ax.get_yticklabels()), 5) def test_plot_consistency_with_normalization(self): - ax = plot_consistency_test(eval_results=self.mock_result, normalize=True, - show=show_plots) + ax = plot_consistency_test( + eval_results=self.mock_result, normalize=True, show=show_plots + ) # Assert that the observed statistic is plotted at 0 self.assertEqual(ax.lines[0].get_xdata(), 0) @@ -541,38 +529,47 @@ def test_plot_consistency_with_one_sided_lower(self): mock_result = copy.deepcopy(self.mock_result) # THe observed statistic is placed to the right of the model test distribution. mock_result.observed_statistic = max(self.mock_result.test_distribution) + 1 - ax = plot_consistency_test(eval_results=mock_result, one_sided_lower=True, - show=show_plots) + ax = plot_consistency_test( + eval_results=mock_result, one_sided_lower=True, show=show_plots + ) # The end of the infinite dashed line should extend way away from the plot limit self.assertGreater(ax.lines[-1].get_xdata()[-1], ax.get_xlim()[1]) def test_plot_consistency_with_custom_percentile(self): - ax = plot_consistency_test(eval_results=self.mock_result, percentile=99, - show=show_plots) + ax = plot_consistency_test( + eval_results=self.mock_result, percentile=99, show=show_plots + ) # Check that the line extent equals the lower 0.5 % percentile - self.assertAlmostEqual(ax.lines[2].get_xdata(), - numpy.percentile(self.mock_result.test_distribution, 0.5)) + self.assertAlmostEqual( + ax.lines[2].get_xdata(), numpy.percentile(self.mock_result.test_distribution, 0.5) + ) def test_plot_consistency_with_variance(self): mock_nb = copy.deepcopy(self.mock_result) mock_poisson = copy.deepcopy(self.mock_result) - mock_nb.test_distribution = ('negative_binomial', 8) - mock_poisson.test_distribution = ('poisson', 8) + mock_nb.test_distribution = ("negative_binomial", 8) + mock_poisson.test_distribution = ("poisson", 8) ax_nb = plot_consistency_test(eval_results=mock_nb, variance=16, show=show_plots) ax_p = plot_consistency_test(eval_results=mock_poisson, variance=None, show=show_plots) # Ensure the negative binomial has a larger x-axis extent than poisson self.assertTrue(ax_p.get_xlim()[1] < ax_nb.get_xlim()[1]) def test_plot_consistency_with_custom_plot_args(self): - ax = plot_consistency_test(eval_results=self.mock_result, show=show_plots, - xlabel="Custom X", ylabel="Custom Y", title="Custom Title") + ax = plot_consistency_test( + eval_results=self.mock_result, + show=show_plots, + xlabel="Custom X", + ylabel="Custom Y", + title="Custom Title", + ) self.assertEqual(ax.get_xlabel(), "Custom X") self.assertEqual(ax.get_title(), "Custom Title") def test_plot_consistency_with_mean(self): - ax = plot_consistency_test(eval_results=self.mock_result, plot_mean=True, - show=show_plots) + ax = plot_consistency_test( + eval_results=self.mock_result, plot_mean=True, show=show_plots + ) # Check for the mean line plotted as a circle self.assertTrue(any(["o" in str(line.get_marker()) for line in ax.lines])) @@ -593,7 +590,7 @@ def test_SingleNTestPlot(self): [i.get_text() for i in matplotlib.pyplot.gca().get_yticklabels()], [i.sim_name for i in [Ntest_result]], ) - self.assertEqual(matplotlib.pyplot.gca().get_title(), '') + self.assertEqual(matplotlib.pyplot.gca().get_title(), "") def test_MultiNTestPlot(self): @@ -650,7 +647,7 @@ def test_MultiTTestPlot(self): t_plots = numpy.random.randint(2, 20) t_tests = [] - def rand(limit=10, offset=0.): + def rand(limit=10, offset=0.0): return limit * (numpy.random.random() - offset) for n in range(t_plots): @@ -704,7 +701,7 @@ def test_plot_basemap_with_features(self, mock_get_basemap): mock_tiles = MagicMock() mock_get_basemap.return_value = mock_tiles - basemap = 'stock_img' + basemap = "stock_img" ax = plot_basemap( basemap=basemap, extent=self.chiloe_extent, @@ -721,7 +718,7 @@ def test_plot_basemap_with_features(self, mock_get_basemap): mock_get_basemap.assert_not_called() self.assertTrue(ax.get_legend() is None) - @unittest.skipIf(is_github_actions, "Skipping test in GitHub CI environment") + @unittest.skipIf(is_github_ci(), "Skipping test in GitHub CI environment") @unittest.skipIf(not is_internet_available(), "Skipping test due to no internet connection") def test_plot_google_satellite(self): basemap = "google-satellite" @@ -735,7 +732,7 @@ def test_plot_google_satellite(self): self.assertIsInstance(ax, plt.Axes) self.assertTrue(ax.get_legend() is None) - @unittest.skipIf(is_github_actions, "Skipping test in GitHub CI environment") + @unittest.skipIf(is_github_ci(), "Skipping test in GitHub CI environment") @unittest.skipIf(not is_internet_available(), "Skipping test due to no internet connection") def test_plot_esri(self): basemap = "ESRI_terrain" @@ -766,6 +763,7 @@ def test_plot_basemap_set_global(self, mock_get_basemap): mock_get_basemap.assert_not_called() self.assertTrue(ax.get_extent() == (-180, 180, -90, 90)) + @unittest.skipIf(is_github_ci(), "Skipping test in GitHub CI environment") def test_plot_basemap_tif_file(self): basemap = csep.datasets.basemap_california projection = ccrs.PlateCarree() @@ -786,15 +784,17 @@ def test_plot_basemap_with_custom_projection(self): def test_plot_basemap_with_custom_projection_and_features(self): projection = ccrs.Mercator() basemap = None - ax = plot_basemap(basemap=basemap, - extent=self.chiloe_extent, - projection=projection, - coastline=True, - borders=True, - grid=True, - grid_labels=True, - grid_fontsize=8, - show=show_plots) + ax = plot_basemap( + basemap=basemap, + extent=self.chiloe_extent, + projection=projection, + coastline=True, + borders=True, + grid=True, + grid_labels=True, + grid_fontsize=8, + show=show_plots, + ) self.assertIsInstance(ax, plt.Axes) self.assertEqual(ax.projection, projection) @@ -821,7 +821,7 @@ def setUp(self): numpy.min(self.mock_catalog.get_longitudes()), numpy.max(self.mock_catalog.get_longitudes()), numpy.min(self.mock_catalog.get_latitudes()), - numpy.max(self.mock_catalog.get_latitudes()) + numpy.max(self.mock_catalog.get_latitudes()), ] # Mock region if needed @@ -840,13 +840,13 @@ def test_plot_catalog_default(self): # Test plot with default settings4 ax = plot_catalog(self.mock_catalog, show=show_plots) self.assertIsInstance(ax, plt.Axes) - self.assertEqual(ax.get_title(), '') + self.assertEqual(ax.get_title(), "") def test_plot_catalog_title(self): # Test plot with default settings ax = plot_catalog(self.mock_catalog, show=show_plots, title=self.mock_catalog.name) self.assertIsInstance(ax, plt.Axes) - self.assertEqual(ax.get_title(), 'Mock Catalog') + self.assertEqual(ax.get_title(), "Mock Catalog") def test_plot_catalog_without_legend(self): # Test plot with legend @@ -856,8 +856,7 @@ def test_plot_catalog_without_legend(self): def test_plot_catalog_custom_legend(self): - ax = plot_catalog(self.mock_catalog, mag_ticks=5, - show=show_plots) + ax = plot_catalog(self.mock_catalog, mag_ticks=5, show=show_plots) legend = ax.get_legend() self.assertIsNotNone(legend) @@ -869,18 +868,19 @@ def test_plot_catalog_custom_legend(self): def test_plot_catalog_correct_sizing(self): - ax = plot_catalog(self.mock_fix, - figsize=(4,6), - mag_ticks=[4, 5, 6, 7, 8], - legend_loc='right', - show=show_plots) + ax = plot_catalog( + self.mock_fix, + figsize=(4, 6), + mag_ticks=[4, 5, 6, 7, 8], + legend_loc="right", + show=show_plots, + ) legend = ax.get_legend() self.assertIsNotNone(legend) def test_plot_catalog_custom_sizes(self): - ax = plot_catalog(self.mock_catalog, size=5, max_size=800, power=6, - show=show_plots) + ax = plot_catalog(self.mock_catalog, size=5, max_size=800, power=6, show=show_plots) legend = ax.get_legend() self.assertIsNotNone(legend) @@ -909,44 +909,48 @@ def test_plot_catalog_with_region_border(self): def test_plot_catalog_with_no_grid(self): # Test plot with grid disabled - ax = plot_catalog( - self.mock_catalog, show=show_plots, grid=False - ) + ax = plot_catalog(self.mock_catalog, show=show_plots, grid=False) gl = ax.gridlines() self.assertIsNotNone(gl) def test_plot_catalog_w_basemap(self): # Test plot with default settings - ax = plot_catalog(self.mock_catalog, basemap='stock_img', show=show_plots) + ax = plot_catalog(self.mock_catalog, basemap="stock_img", show=show_plots) self.assertIsInstance(ax, plt.Axes) - self.assertEqual(ax.get_title(), '') + self.assertEqual(ax.get_title(), "") def test_plot_catalog_w_basemap_stream_kwargs(self): projection = ccrs.Mercator() - ax = plot_catalog(self.mock_catalog, basemap=None, - projection=projection, - coastline=True, - borders=True, - grid=True, - grid_labels=True, - grid_fontsize=8, - show=show_plots) + ax = plot_catalog( + self.mock_catalog, + basemap=None, + projection=projection, + coastline=True, + borders=True, + grid=True, + grid_labels=True, + grid_fontsize=8, + show=show_plots, + ) self.assertIsInstance(ax, plt.Axes) - self.assertEqual(ax.get_title(), '') + self.assertEqual(ax.get_title(), "") def test_plot_catalog_w_approx_projection(self): - projection = 'approx' - ax = plot_catalog(self.mock_catalog, basemap='stock_img', - projection=projection, - coastline=True, - borders=True, - grid=True, - grid_labels=True, - grid_fontsize=8, - show=show_plots) + projection = "approx" + ax = plot_catalog( + self.mock_catalog, + basemap="stock_img", + projection=projection, + coastline=True, + borders=True, + grid=True, + grid_labels=True, + grid_fontsize=8, + show=show_plots, + ) self.assertIsInstance(ax, plt.Axes) - self.assertEqual(ax.get_title(), '') + self.assertEqual(ax.get_title(), "") def tearDown(self): plt.close("all") @@ -981,7 +985,7 @@ def test_default_plot(self): def test_extent_setting_w_ax(self): extent = (-30, 30, -20, 20) ax = plot_spatial_dataset( - self.gridded_data, self.region, extent=extent, show=show_plots + self.gridded_data, self.region, extent=extent, show=show_plots ) numpy.testing.assert_array_almost_equal(ax.get_extent(crs=ccrs.PlateCarree()), extent) @@ -996,17 +1000,23 @@ def test_extent_setting(self): def test_color_mapping(self): cmap = plt.get_cmap("plasma") fig, ax = plt.subplots(subplot_kw={"projection": ccrs.PlateCarree()}) - ax = plot_spatial_dataset(self.gridded_data, self.region, ax=ax, colormap=cmap, show=show_plots) + ax = plot_spatial_dataset( + self.gridded_data, self.region, ax=ax, colormap=cmap, show=show_plots + ) self.assertIsInstance(ax.collections[0].cmap, colors.ListedColormap) def test_gridlines(self): fig, ax = plt.subplots(subplot_kw={"projection": ccrs.PlateCarree()}) - ax = plot_spatial_dataset(self.gridded_data, self.region, ax=ax, grid=True, show=show_plots) + ax = plot_spatial_dataset( + self.gridded_data, self.region, ax=ax, grid=True, show=show_plots + ) self.assertTrue(ax.gridlines()) def test_alpha_transparency(self): fig, ax = plt.subplots(subplot_kw={"projection": ccrs.PlateCarree()}) - ax = plot_spatial_dataset(self.gridded_data, self.region, ax=ax, alpha=0.5, show=show_plots) + ax = plot_spatial_dataset( + self.gridded_data, self.region, ax=ax, alpha=0.5, show=show_plots + ) self.assertIsInstance(ax, plt.Axes) def test_plot_with_alpha_exp(self): @@ -1049,17 +1059,18 @@ def test_plot_spatial_dataset_w_basemap_stream_kwargs(self): grid_labels=True, grid_fontsize=8, show=show_plots, - plot_region=False + plot_region=False, ) self.assertIsInstance(ax, plt.Axes) - self.assertEqual(ax.get_title(), '') + self.assertEqual(ax.get_title(), "") def test_plot_spatial_dataset_w_approx_projection(self): - projection = 'approx' + projection = "approx" ax = plot_spatial_dataset( self.gridded_data, - self.region, basemap='stock_img', + self.region, + basemap="stock_img", extent=[-20, 40, -5, 25], projection=projection, coastline=True, @@ -1068,11 +1079,11 @@ def test_plot_spatial_dataset_w_approx_projection(self): grid_labels=True, grid_fontsize=8, show=show_plots, - plot_region=False + plot_region=False, ) self.assertIsInstance(ax, plt.Axes) - self.assertEqual(ax.get_title(), '') + self.assertEqual(ax.get_title(), "") def tearDown(self): plt.close("all") @@ -1112,50 +1123,43 @@ def test_get_axis_limits(self): expected_limits = (0.8, 5.2) self.assertEqual(_get_axis_limits(pnts, border=0.05), expected_limits) - def test_add_labels_for_publication(self): - fig = plt.figure() - ax = fig.add_subplot(111) - _add_labels_for_publication(fig) - annotations = [child for child in ax.get_children() if isinstance(child, Annotation)] - self.assertEqual(len(annotations), 1) - self.assertEqual(annotations[0].get_text(), "(a)") - - def test_autosize_scatter(self): values = numpy.array([1, 2, 3, 4, 5]) - expected_sizes = _autosize_scatter(values, min_size=50., max_size=400., power=3.0) - result = _autosize_scatter(values, min_size=50., max_size=400., power=3.0) + expected_sizes = _autosize_scatter(values, min_size=50.0, max_size=400.0, power=3.0) + result = _autosize_scatter(values, min_size=50.0, max_size=400.0, power=3.0) numpy.testing.assert_almost_equal(result, expected_sizes, decimal=2) values = numpy.array([1, 2, 3, 4, 5]) min_val = 0 max_val = 10 - expected_sizes = _autosize_scatter(values, min_size=50., max_size=400., power=3.0, - min_val=min_val, max_val=max_val) - result = _autosize_scatter(values, min_size=50., max_size=400., power=3.0, min_val=min_val, - max_val=max_val) + expected_sizes = _autosize_scatter( + values, min_size=50.0, max_size=400.0, power=3.0, min_val=min_val, max_val=max_val + ) + result = _autosize_scatter( + values, min_size=50.0, max_size=400.0, power=3.0, min_val=min_val, max_val=max_val + ) numpy.testing.assert_almost_equal(result, expected_sizes, decimal=2) values = numpy.array([1, 2, 3, 4, 5]) power = 2.0 - expected_sizes = _autosize_scatter(values, min_size=50., max_size=400., power=power) - result = _autosize_scatter(values, min_size=50., max_size=400., power=power) + expected_sizes = _autosize_scatter(values, min_size=50.0, max_size=400.0, power=power) + result = _autosize_scatter(values, min_size=50.0, max_size=400.0, power=power) numpy.testing.assert_almost_equal(result, expected_sizes, decimal=2) values = numpy.array([1, 2, 3, 4, 5]) power = 0.0 - expected_sizes = _autosize_scatter(values, min_size=50., max_size=400., power=power) - result = _autosize_scatter(values, min_size=50., max_size=400., power=power) + expected_sizes = _autosize_scatter(values, min_size=50.0, max_size=400.0, power=power) + result = _autosize_scatter(values, min_size=50.0, max_size=400.0, power=power) numpy.testing.assert_almost_equal(result, expected_sizes, decimal=2) values = numpy.array([5, 5, 5, 5, 5]) - expected_sizes = _autosize_scatter(values, min_size=50., max_size=400., power=3.0) - result = _autosize_scatter(values, min_size=50., max_size=400., power=3.0) + expected_sizes = _autosize_scatter(values, min_size=50.0, max_size=400.0, power=3.0) + result = _autosize_scatter(values, min_size=50.0, max_size=400.0, power=3.0) numpy.testing.assert_almost_equal(result, expected_sizes, decimal=2) values = numpy.array([10, 100, 1000, 10000, 100000]) - expected_sizes = _autosize_scatter(values, min_size=50., max_size=400., power=3.0) - result = _autosize_scatter(values, min_size=50., max_size=400., power=3.0) + expected_sizes = _autosize_scatter(values, min_size=50.0, max_size=400.0, power=3.0) + result = _autosize_scatter(values, min_size=50.0, max_size=400.0, power=3.0) numpy.testing.assert_almost_equal(result, expected_sizes, decimal=2) def test_autoscale_histogram(self): @@ -1175,8 +1179,8 @@ def test_autoscale_histogram(self): def test_annotate_distribution_plot(self): # Mock evaluation_result for Catalog N-Test evaluation_result = Mock() - evaluation_result.name = 'Catalog N-Test' - evaluation_result.sim_name = 'Simulated Catalog' + evaluation_result.name = "Catalog N-Test" + evaluation_result.sim_name = "Simulated Catalog" evaluation_result.quantile = [0.25, 0.75] evaluation_result.observed_statistic = 5.0 @@ -1190,19 +1194,20 @@ def test_annotate_distribution_plot(self): "title": None, } - ax = _annotate_distribution_plot(ax, evaluation_result, auto_annotate=True, - plot_args=plot_args) + ax = _annotate_distribution_plot( + ax, evaluation_result, auto_annotate=True, plot_args=plot_args + ) # Assertions to check if the annotations were correctly set - self.assertEqual(ax.get_xlabel(), 'Event Count') - self.assertEqual(ax.get_ylabel(), 'Number of Catalogs') - self.assertEqual(ax.get_title(), 'Catalog N-Test: Simulated Catalog') + self.assertEqual(ax.get_xlabel(), "Event Count") + self.assertEqual(ax.get_ylabel(), "Number of Catalogs") + self.assertEqual(ax.get_title(), "Catalog N-Test: Simulated Catalog") annotation = ax.texts[0].get_text() expected_annotation = ( - f'$\\delta_1 = P(X \\geq x) = 0.25$\n' - f'$\\delta_2 = P(X \\leq x) = 0.75$\n' - f'$\\omega = 5.00$' + f"$\\delta_1 = P(X \\geq x) = 0.25$\n" + f"$\\delta_2 = P(X \\leq x) = 0.75$\n" + f"$\\omega = 5.00$" ) self.assertEqual(annotation, expected_annotation) @@ -1228,16 +1233,18 @@ def test_calculate_spatial_extent(self): def test_create_geo_axes(self): # Test GeoAxes creation with no extent (global) - ax = _create_geo_axes(figsize=(10, 8), extent=None, projection=ccrs.PlateCarree(), - set_global=True) + ax = _create_geo_axes( + figsize=(10, 8), extent=None, projection=ccrs.PlateCarree(), set_global=True + ) self.assertIsInstance(ax, plt.Axes) self.assertAlmostEqual(ax.get_xlim(), (-180, 180)) self.assertAlmostEqual(ax.get_ylim(), (-90, 90)) # Test GeoAxes creation with a specific extent extent = (-125, -110, 25, 40) - ax = _create_geo_axes(figsize=(10, 8), extent=extent, projection=ccrs.PlateCarree(), - set_global=False) + ax = _create_geo_axes( + figsize=(10, 8), extent=extent, projection=ccrs.PlateCarree(), set_global=False + ) self.assertIsInstance(ax, plt.Axes) self.assertAlmostEqual(ax.get_extent(), extent) @@ -1263,8 +1270,8 @@ def test_get_basemap_esri_terrain(self, mock_google_tiles): tiles = _get_basemap("ESRI_terrain") mock_google_tiles.assert_called_once_with( url="https://server.arcgisonline.com/ArcGIS/rest/services/World_Terrain_Base/" - "MapServer/tile/{z}/{y}/{x}.jpg", - cache=True + "MapServer/tile/{z}/{y}/{x}.jpg", + cache=True, ) self.assertIsNotNone(tiles) @@ -1292,55 +1299,30 @@ def test_plot_basemap_no_basemap(self): self.assertIsInstance(ax, plt.Axes) def test_default_colormap(self): - cmap, alpha = _define_colormap_and_alpha("viridis", 0) + cmap, alpha = _get_colormap("viridis", 0) self.assertIsInstance(cmap, matplotlib.colors.ListedColormap) expected_cmap = plt.get_cmap("viridis") self.assertTrue(numpy.allclose(cmap.colors, expected_cmap(numpy.arange(cmap.N)))) def test_custom_colormap(self): cmap = plt.get_cmap("plasma") - cmap, alpha = _define_colormap_and_alpha(cmap, 0) + cmap, alpha = _get_colormap(cmap, 0) self.assertIsInstance(cmap, matplotlib.colors.ListedColormap) expected_cmap = plt.get_cmap("plasma") self.assertTrue(numpy.allclose(cmap.colors, expected_cmap(numpy.arange(cmap.N)))) def test_alpha_exponent(self): - cmap, alpha = _define_colormap_and_alpha("viridis", 0.5) + cmap, alpha = _get_colormap("viridis", 0.5) self.assertIsInstance(cmap, matplotlib.colors.ListedColormap) self.assertIsNone(alpha) # Check that alpha values are correctly modified self.assertTrue(numpy.all(cmap.colors[:, -1] == numpy.linspace(0, 1, cmap.N) ** 0.5)) def test_no_alpha_exponent(self): - cmap, alpha = _define_colormap_and_alpha("viridis", 0) + cmap, alpha = _get_colormap("viridis", 0) self.assertEqual(alpha, 1) self.assertTrue(numpy.all(cmap.colors[:, -1] == 1)) # No alpha modification - def test_add_colorbar(self): - fig, ax = plt.subplots() - im = ax.imshow(numpy.random.rand(10, 10), cmap="viridis") - _add_colorbar( - ax, im, clabel="Colorbar Label", clabel_fontsize=12, cticks_fontsize=10 - ) - - # Check if the colorbar is added to the figure - colorbars = [ - child - for child in fig.get_children() - if isinstance(child, plt.Axes) and "Colorbar" in child.get_label() - ] - self.assertGreater(len(colorbars), 0) - - # Check colorbar label and font sizes - cbar = colorbars[0] - self.assertEqual(cbar.get_ylabel(), "Colorbar Label") - self.assertEqual(cbar.get_ylabel(), "Colorbar Label") - self.assertEqual(cbar.yaxis.label.get_size(), 12) - - # Check tick label font size - tick_labels = cbar.get_yticklabels() - self.assertTrue(all(label.get_fontsize() == 10 for label in tick_labels)) - def tearDown(self): plt.close("all") gc.collect() @@ -1383,11 +1365,11 @@ class TestProcessDistribution(unittest.TestCase): def setUp(self): self.result_poisson = mock.Mock() - self.result_poisson.test_distribution = ['poisson', 10] + self.result_poisson.test_distribution = ["poisson", 10] self.result_poisson.observed_statistic = 8 self.result_neg_binom = mock.Mock() - self.result_neg_binom.test_distribution = ['negative_binomial', 10] + self.result_neg_binom.test_distribution = ["negative_binomial", 10] self.result_neg_binom.observed_statistic = 8 self.result_empirical = mock.Mock() @@ -1396,8 +1378,11 @@ def setUp(self): def test_process_distribution_poisson(self): plow, phigh, mean, observed_statistic = _process_stat_distribution( - self.result_poisson, percentile=95, variance=None, normalize=False, - one_sided_lower=False + self.result_poisson, + percentile=95, + variance=None, + normalize=False, + one_sided_lower=False, ) self.assertAlmostEqual(mean, 10) self.assertAlmostEqual(observed_statistic, 8) @@ -1406,8 +1391,11 @@ def test_process_distribution_poisson(self): def test_process_distribution_negative_binomial(self): variance = 12 plow, phigh, mean, observed_statistic = _process_stat_distribution( - self.result_neg_binom, percentile=95, variance=variance, normalize=False, - one_sided_lower=False + self.result_neg_binom, + percentile=95, + variance=variance, + normalize=False, + one_sided_lower=False, ) self.assertAlmostEqual(mean, 10) self.assertAlmostEqual(observed_statistic, 8) @@ -1415,8 +1403,11 @@ def test_process_distribution_negative_binomial(self): def test_process_distribution_empirical(self): plow, phigh, mean, observed_statistic = _process_stat_distribution( - self.result_empirical, percentile=95, variance=None, normalize=False, - one_sided_lower=False + self.result_empirical, + percentile=95, + variance=None, + normalize=False, + one_sided_lower=False, ) self.assertAlmostEqual(mean, numpy.mean(self.result_empirical.test_distribution)) self.assertAlmostEqual(observed_statistic, 8) @@ -1424,18 +1415,29 @@ def test_process_distribution_empirical(self): def test_process_distribution_empirical_normalized(self): plow, phigh, mean, observed_statistic = _process_stat_distribution( - self.result_empirical, percentile=95, variance=None, normalize=True, - one_sided_lower=False + self.result_empirical, + percentile=95, + variance=None, + normalize=True, + one_sided_lower=False, + ) + self.assertAlmostEqual( + mean, + numpy.mean( + self.result_empirical.test_distribution + - self.result_empirical.observed_statistic + ), ) - self.assertAlmostEqual(mean, numpy.mean(self.result_empirical.test_distribution - - self.result_empirical.observed_statistic)) self.assertAlmostEqual(observed_statistic, 0) self.assertTrue(plow < mean < phigh) def test_process_distribution_empirical_one_sided(self): plow, phigh, mean, observed_statistic = _process_stat_distribution( - self.result_empirical, percentile=95, variance=None, normalize=False, - one_sided_lower=True + self.result_empirical, + percentile=95, + variance=None, + normalize=False, + one_sided_lower=True, ) self.assertAlmostEqual(mean, numpy.mean(self.result_empirical.test_distribution)) self.assertAlmostEqual(observed_statistic, 8) From 483dc2aede421a1fc60e90418c46a893fbb43293 Mon Sep 17 00:00:00 2001 From: pciturri Date: Tue, 27 Aug 2024 20:41:57 +0200 Subject: [PATCH 06/17] refactor: negative_binomial_number_test now stores the variance argument into the EvaluationResult, as part of the test_distribution attribute: ('negbinom', mean, variance). plot_consistency_test() now does not accept variance as attribute, but it is rather obtained when processing the negative binomial distribution. tests: unittests of consistency test now do not accept variance argument, and negative_binomial mocks contain the second variance parameter as part of the test_distribution --- csep/core/binomial_evaluations.py | 2 +- csep/utils/plots.py | 7 ++----- tests/test_plots.py | 10 ++-------- 3 files changed, 5 insertions(+), 14 deletions(-) diff --git a/csep/core/binomial_evaluations.py b/csep/core/binomial_evaluations.py index 58fd7f50..121d19fc 100644 --- a/csep/core/binomial_evaluations.py +++ b/csep/core/binomial_evaluations.py @@ -65,7 +65,7 @@ def negative_binomial_number_test(gridded_forecast, observed_catalog, variance): delta1, delta2 = _nbd_number_test_ndarray(fore_cnt, obs_cnt, variance, epsilon=epsilon) # store results - result.test_distribution = ('negative_binomial', fore_cnt) + result.test_distribution = ('negative_binomial', fore_cnt, variance) result.name = 'NBD N-Test' result.observed_statistic = obs_cnt result.quantile = (delta1, delta2) diff --git a/csep/utils/plots.py b/csep/utils/plots.py index 840ca36c..c1634a6a 100644 --- a/csep/utils/plots.py +++ b/csep/utils/plots.py @@ -813,7 +813,6 @@ def plot_consistency_test( normalize: bool = False, one_sided_lower: bool = False, percentile: float = 95, - variance: Optional[float] = None, ax: Optional[pyplot.Axes] = None, plot_mean: bool = False, color: str = "black", @@ -836,8 +835,6 @@ def plot_consistency_test( Percentile for the extent of the model score distribution (default: 95). one_sided_lower (bool): Plot for a one-sided test (default: False). - variance (Optional[float]): - Variance for negative binomial distribution (default: None). ax (Optional[pyplot.Axes]): Axes object to plot on (default: None). plot_mean (bool): @@ -865,7 +862,7 @@ def plot_consistency_test( for index, res in enumerate(results): plow, phigh, mean, observed_statistic = _process_stat_distribution( - res, percentile, variance, normalize, one_sided_lower + res, percentile, normalize, one_sided_lower ) if not numpy.isinf(observed_statistic): # Check if test result does not diverge @@ -2139,7 +2136,6 @@ def _get_colormap( def _process_stat_distribution( res: "EvaluationResult", percentile: float, - variance: Optional[float], normalize: bool, one_sided_lower: bool, ) -> Tuple[float, float, float, float]: @@ -2167,6 +2163,7 @@ def _process_stat_distribution( observed_statistic = res.observed_statistic elif dist_type == "negative_binomial": mean = res.test_distribution[1] + variance = res.test_distribution[2] upsilon = 1.0 - ((variance - mean) / variance) tau = mean**2 / (variance - mean) plow = nbinom.ppf((1 - percentile / 100.0) / 2.0, tau, upsilon) diff --git a/tests/test_plots.py b/tests/test_plots.py index bd8139cd..35802ea7 100644 --- a/tests/test_plots.py +++ b/tests/test_plots.py @@ -548,7 +548,7 @@ def test_plot_consistency_with_custom_percentile(self): def test_plot_consistency_with_variance(self): mock_nb = copy.deepcopy(self.mock_result) mock_poisson = copy.deepcopy(self.mock_result) - mock_nb.test_distribution = ("negative_binomial", 8) + mock_nb.test_distribution = ("negative_binomial", 8, 16) mock_poisson.test_distribution = ("poisson", 8) ax_nb = plot_consistency_test(eval_results=mock_nb, variance=16, show=show_plots) ax_p = plot_consistency_test(eval_results=mock_poisson, variance=None, show=show_plots) @@ -1369,7 +1369,7 @@ def setUp(self): self.result_poisson.observed_statistic = 8 self.result_neg_binom = mock.Mock() - self.result_neg_binom.test_distribution = ["negative_binomial", 10] + self.result_neg_binom.test_distribution = ["negative_binomial", 10, 12] self.result_neg_binom.observed_statistic = 8 self.result_empirical = mock.Mock() @@ -1380,7 +1380,6 @@ def test_process_distribution_poisson(self): plow, phigh, mean, observed_statistic = _process_stat_distribution( self.result_poisson, percentile=95, - variance=None, normalize=False, one_sided_lower=False, ) @@ -1389,11 +1388,9 @@ def test_process_distribution_poisson(self): self.assertTrue(plow < mean < phigh) def test_process_distribution_negative_binomial(self): - variance = 12 plow, phigh, mean, observed_statistic = _process_stat_distribution( self.result_neg_binom, percentile=95, - variance=variance, normalize=False, one_sided_lower=False, ) @@ -1405,7 +1402,6 @@ def test_process_distribution_empirical(self): plow, phigh, mean, observed_statistic = _process_stat_distribution( self.result_empirical, percentile=95, - variance=None, normalize=False, one_sided_lower=False, ) @@ -1417,7 +1413,6 @@ def test_process_distribution_empirical_normalized(self): plow, phigh, mean, observed_statistic = _process_stat_distribution( self.result_empirical, percentile=95, - variance=None, normalize=True, one_sided_lower=False, ) @@ -1435,7 +1430,6 @@ def test_process_distribution_empirical_one_sided(self): plow, phigh, mean, observed_statistic = _process_stat_distribution( self.result_empirical, percentile=95, - variance=None, normalize=False, one_sided_lower=True, ) From 4e7ddf1a0c84c9b71c859ef7e35df09cb6756f8e Mon Sep 17 00:00:00 2001 From: pciturri Date: Tue, 27 Aug 2024 21:15:24 +0200 Subject: [PATCH 07/17] refactor: t-test EvaluationResult() now includes value of alpha, so it is not necessary to set it again when plotting. plot_comparison_test() includes a default legend that explains the symbology therein. --- csep/core/poisson_evaluations.py | 2 +- csep/utils/plots.py | 3 ++- tests/test_plots.py | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/csep/core/poisson_evaluations.py b/csep/core/poisson_evaluations.py index 6c0f5e22..4725bcbb 100644 --- a/csep/core/poisson_evaluations.py +++ b/csep/core/poisson_evaluations.py @@ -47,7 +47,7 @@ def paired_t_test(forecast, benchmark_forecast, observed_catalog, result.name = 'Paired T-Test' result.test_distribution = (out['ig_lower'], out['ig_upper']) result.observed_statistic = out['information_gain'] - result.quantile = (out['t_statistic'], out['t_critical']) + result.quantile = (out['t_statistic'], out['t_critical'], alpha) result.sim_name = (forecast.name, benchmark_forecast.name) result.obs_name = observed_catalog.name result.status = 'normal' diff --git a/csep/utils/plots.py b/csep/utils/plots.py index c1634a6a..84bdc8f5 100644 --- a/csep/utils/plots.py +++ b/csep/utils/plots.py @@ -773,7 +773,8 @@ def plot_comparison_test( if plot_args["legend"]: # Add custom legend to explain results legend_elements = [ - Line2D([0], [0], color="red", lw=2, label="T-test rejected"), + Line2D([0], [0], color="red", lw=2, + label=f"T-test rejected ($\\alpha = {results_t[0].quantile[-1]}$)"), Line2D([0], [0], color="green", lw=2, label="T-test non-rejected"), Line2D([0], [0], color="gray", lw=2, label="T-test indistinguishable"), Line2D( diff --git a/tests/test_plots.py b/tests/test_plots.py index 35802ea7..66ccc5da 100644 --- a/tests/test_plots.py +++ b/tests/test_plots.py @@ -662,7 +662,7 @@ def rand(limit=10, offset=0.0): t_result.observed_statistic - rand(5), t_result.observed_statistic + rand(5), ] - + t_result.quantile = (None, None, 0.05) if numpy.random.random() < 0.05: # sim possible infinite values t_result.observed_statistic = -numpy.inf t_tests.append(t_result) From 6078750fecdb3bd904d401d42a7b65f02653b87b Mon Sep 17 00:00:00 2001 From: pciturri Date: Fri, 30 Aug 2024 04:19:10 +0200 Subject: [PATCH 08/17] docs: Harmonized docstrings of all plotting main functions, making them compatible with sphinx docs. Reordered the index of the API reference docs for plotting functions. Also added EvaluationResult and CartesianGrid2D.get_cartesian, which are referenced by the plot docs. Added cartopy for intersphinx_mapping refac: Renamed plot_spatial_dataset to plot_gridded_dataset (since catalogs are also a spatial datasets) --- csep/core/forecasts.py | 6 +- csep/core/regions.py | 6 +- csep/utils/plots.py | 2240 +++++++++-------- docs/conf.py | 3 +- docs/reference/api_reference.rst | 53 +- examples/tutorials/plot_customizations.py | 6 +- .../quadtree_gridded_forecast_evaluation.py | 4 +- tests/test_plots.py | 42 +- 8 files changed, 1297 insertions(+), 1063 deletions(-) diff --git a/csep/core/forecasts.py b/csep/core/forecasts.py index 333af409..b57b178c 100644 --- a/csep/core/forecasts.py +++ b/csep/core/forecasts.py @@ -13,7 +13,7 @@ from csep.utils.time_utils import decimal_year, datetime_to_utc_epoch from csep.core.catalogs import AbstractBaseCatalog from csep.utils.constants import SECONDS_PER_ASTRONOMICAL_YEAR -from csep.utils.plots import plot_spatial_dataset +from csep.utils.plots import plot_gridded_dataset # idea: should this be a SpatialDataSet and the class below SpaceMagnitudeDataSet, bc of functions like @@ -458,11 +458,11 @@ def plot(self, ax=None, show=False, log=True, extent=None, set_global=False, plo if log: plot_args.setdefault('clabel', f'log10 M{self.min_magnitude}+ rate per cell per {time}') with numpy.errstate(divide='ignore'): - ax = plot_spatial_dataset(numpy.log10(self.spatial_counts(cartesian=True)), self.region, ax=ax, + ax = plot_gridded_dataset(numpy.log10(self.spatial_counts(cartesian=True)), self.region, ax=ax, show=show, extent=extent, set_global=set_global, plot_args=plot_args) else: plot_args.setdefault('clabel', f'M{self.min_magnitude}+ rate per cell per {time}') - ax = plot_spatial_dataset(self.spatial_counts(cartesian=True), self.region, ax=ax,show=show, extent=extent, + ax = plot_gridded_dataset(self.spatial_counts(cartesian=True), self.region, ax=ax, show=show, extent=extent, set_global=set_global, plot_args=plot_args) return ax diff --git a/csep/core/regions.py b/csep/core/regions.py index c5c4de3d..5a7065a8 100644 --- a/csep/core/regions.py +++ b/csep/core/regions.py @@ -658,7 +658,11 @@ def get_cartesian(self, data): """Returns 2d ndrray representation of the data set, corresponding to the bounding box. Args: - data: + data: An array of values, whose indices corresponds to each cell of the region + + Returns: + A 2D array of values, corresponding to the original data projected onto the region. + Values outside the region polygon are represented as np.nan """ assert len(data) == len(self.polygons) results = numpy.zeros(self.bbox_mask.shape[:2]) diff --git a/csep/utils/plots.py b/csep/utils/plots.py index 84bdc8f5..c48ed30d 100644 --- a/csep/utils/plots.py +++ b/csep/utils/plots.py @@ -3,15 +3,14 @@ import warnings from typing import TYPE_CHECKING, Optional, Any, List, Union, Tuple, Sequence, Dict +# Third-party imports +import numpy +import pandas import cartopy import cartopy.crs as ccrs import matplotlib import matplotlib.lines import matplotlib.pyplot as pyplot -# Third-party imports -import numpy -import numpy as np -import pandas as pandas from cartopy.io import img_tiles from cartopy.io.img_tiles import GoogleWTS from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER @@ -66,7 +65,6 @@ "alpha": 0.8, "linewidth": 1, "linestyle": "-", - "secondary_linestyle": "red", "size": 5, "marker": "o", "markersize": 5, @@ -85,7 +83,6 @@ "coastline": True, "coastline_color": "black", "coastline_linewidth": 1.5, - "borders": False, "borders_color": "black", "borders_linewidth": 1.5, # Color bars @@ -97,51 +94,54 @@ ######################## # Data-exploratory plots ######################## -def plot_magnitude_vs_time( +def plot_magnitude_versus_time( catalog: "CSEPCatalog", - ax: Optional[Axes] = None, - color: Optional[str] = "steelblue", - size: Optional[int] = 4, - max_size: Optional[int] = 300, - power: Optional[int] = 4, - alpha: Optional[float] = 0.5, + color: str = "steelblue", + size: int = 4, + max_size: int = 300, + power: int = 4, + alpha: float = 0.5, + ax: Optional[matplotlib.axes.Axes] = None, show: bool = False, **kwargs: Any, ) -> matplotlib.axes.Axes: """ - Plots magnitude versus time for a given catalog. + Scatter plot of the catalog magnitudes and origin times. The size of each event is scaled + exponentially by its magnitude using the parameters ``size``,``max_size`` and ``power``. Args: - catalog (:class:`csep.core.catalogs.CSEPCatalog`): - Catalog of seismic events to be plotted. - ax (Axes): - Matplotlib axis object on which to plot. If not provided, a new figure and axis are - created. - color (str): - Color of the scatter plot points. If not provided, defaults to value in - `DEFAULT_PLOT_ARGS`. - size (int): - Size of the event with the minimum magnitude - max_size (int): - Size of the event with the maximum magnitude - power (int): - Power scaling of the scatter sizing. - alpha (float): - Transparency level for the scatter plot points. If not provided, defaults to value - in `DEFAULT_PLOT_ARGS`. - show (bool): - Whether to display the plot. Defaults to `False`. + catalog (CSEPCatalog): Catalog of seismic events to be plotted. + color (str, optional): Color of the scatter plot. Defaults to `'steelblue'`. + size (int, optional): Marker size for the event with the minimum magnitude. Defaults + to `4`. + max_size (int, optional): Marker size for the event with the maximum magnitude. + Defaults to `300`. + power (int, optional): Power scaling of the scatter sizing. Defaults to `4`. + alpha (float, optional): Transparency level for the scatter points. Defaults to `0.5`. + ax (matplotlib.axes.Axes, optional): Axis object on which to plot. If not provided, a + new figure and axis are created. Defaults to `None`. + show (bool, optional): Whether to display the plot. Defaults to `False`. **kwargs: - Additional keyword arguments for customizing the plot. These are merged with - `DEFAULT_PLOT_ARGS`. - + Additional keyword arguments to customize the plot: + + - **figsize** (`tuple`): The size of the figure. + - **title** (`str`): Plot title. Defaults to `None`. + - **title_fontsize** (`int`): Font size for the plot title. + - **xlabel** (`str`): Label for the X-axis. Defaults to `'Datetime'`. + - **xlabel_fontsize** (`int`): Font size for the X-axis label. + - **ylabel** (`str`): Label for the Y-axis. Defaults to `'Magnitude'`. + - **ylabel_fontsize** (`int`): Font size for the Y-axis label. + - **datetime_locator** (`matplotlib.dates.Locator`): Locator for the + X-axis datetime ticks. + - **datetime_formatter** (`str` or `matplotlib.dates.Formatter`): + Formatter for the datetime axis. Defaults to `'%Y-%m-%d'`. + - **grid** (`bool`): Whether to show grid lines. Defaults to `True`. + - **tight_layout** (`bool`): Whether to use a tight layout for the figure. + Defaults to `True`. Returns: - Axes: - The Matplotlib axes object with the plotted data. - + matplotlib.axes.Axes: The Matplotlib axes object with the plotted data. """ - # Initialize plot plot_args = {**DEFAULT_PLOT_ARGS, **kwargs} fig, ax = pyplot.subplots(figsize=plot_args["figsize"]) if ax is None else (ax.figure, ax) @@ -160,10 +160,8 @@ def plot_magnitude_vs_time( # Set labels and title ax.set_xlabel(plot_args["xlabel"] or "Datetime", fontsize=plot_args["xlabel_fontsize"]) - ax.set_ylabel(plot_args["ylabel"] or "$M$", fontsize=plot_args["ylabel_fontsize"]) - ax.set_title( - plot_args["title"] or "Magnitude vs. Time", fontsize=plot_args["title_fontsize"] - ) + ax.set_ylabel(plot_args["ylabel"] or "Magnitude", fontsize=plot_args["ylabel_fontsize"]) + ax.set_title(plot_args["title"], fontsize=plot_args["title_fontsize"]) # Autoformat ticks and labels ax.xaxis.set_major_locator(plot_args["datetime_locator"]) @@ -184,30 +182,55 @@ def plot_cumulative_events_versus_time( observation: "CSEPCatalog", time_axis: str = "datetime", bins: int = 50, - ax: Optional[matplotlib.axes.Axes] = None, sim_label: Optional[str] = "Simulated", obs_label: Optional[str] = "Observation", + ax: Optional[matplotlib.axes.Axes] = None, show: bool = False, **kwargs, ) -> matplotlib.axes.Axes: """ - Plots the cumulative number of forecasted events versus observed events over time. + Plots the cumulative number of forecasted events from a + :class:`~csep.core.forecasts.CatalogForecast` versus the observed events over time. Args: - catalog_forecast (GriddedForecast): The forecasted catalogs. - observation (CSEPCatalog): The observed catalog of events. - time_axis (str): The type of time axis ('datetime', 'days', 'hours'). Defaults - to 'datetime'. - ax (Optional[pyplot.Axes]): The axes to plot on. If None, a new figure and - axes are created. - bins (int): The number of bins for time slicing. Defaults to 50. - sim_label (str): Label for simulated data. Defaults to 'Simulated'. - obs_label (str): Label for observed data. Defaults to 'Observation'. - show (bool): If True, displays the plot. Defaults to False. - **kwargs: Additional plotting arguments to override `DEFAULT_PLOT_ARGS`. + catalog_forecast (CatalogForecast): The forecasted synthetic catalogs. + observation (CSEPCatalog): The observed catalog. + time_axis (str, optional): The type of time axis (`'datetime'`, `'days'`, `'hours'`). + Defaults to `'datetime'`. + bins (int, optional): The number of bins for time slicing. Defaults to `50`. + sim_label (str, optional): Label for simulated data. Defaults to `'Simulated'`. + obs_label (str, optional): Label for observed data. Defaults to `'Observation'`. + ax (matplotlib.axes.Axes, optional): Axis object on which to plot. If not provided, a + new figure and axis are created. Defaults to `None`. + show (bool, optional): If True, displays the plot. Defaults to `False`. + **kwargs: Additional keyword arguments to customize the plot: + + - **figsize** (`tuple`): The size of the figure. + - **xlabel** (`str`): Label for the X-axis. Defaults to `'Datetime'`, + `'Days after Mainshock'`, or `'Hours after Mainshock'`, depending on + `time_axis`. + - **xlabel_fontsize** (`int`): Font size for the X-axis label. + - **ylabel** (`str`): Label for the Y-axis. Defaults to + `'Cumulative event counts'`. + - **ylabel_fontsize** (`int`): Font size for the Y-axis label. + - **title** (`str`): Title of the plot. Defaults to `None`. + - **title_fontsize** (`int`): Font size for the plot title. + - **color** (`str`): Color for the simulated forecast. + - **linewidth** (`float`): Line width for the plot lines. Defaults to + `1.5`. + - **grid** (`bool`): Whether to show grid lines. Defaults to `True`. + - **legend** (`bool`): Whether to show the legend. Defaults to `True`. + - **legend_loc** (`str`): Location of the legend. Defaults to `'best'`. + - **legend_fontsize** (`int`): Font size of the legend text. + - **tight_layout** (`bool`): Whether to use tight layout for the figure. + Defaults to `True`. + - **datetime_locator** (`matplotlib.dates.Locator`): Locator for the + X-axis datetime ticks. + - **datetime_formatter** (`str` or `matplotlib.dates.Formatter`): + Formatter for the datetime axis. Defaults to ``'%Y-%m-%d'``. Returns: - pyplot.Axes: The axes with the cumulative event plot. + matplotlib.axes.Axes: The Matplotlib axes object with the plotted data. """ # Initialize plot @@ -347,19 +370,41 @@ def plot_magnitude_histogram( event counts. Args: - catalog_forecast (CatalogForecast, List[CSEPCatalog]): A Catalog-based forecast + catalog_forecast (CatalogForecast or list of CSEPCatalog): A catalog-based forecast + or a list of observed catalogs. observation (CSEPCatalog): The observed catalog for comparison. - magnitude_bins (Optional[Union[List[float], numpy.ndarray]]): The bins for magnitude - histograms. If None, defaults to the region magnitudes or standard CSEP bins. - percentile (int): The percentile used for uncertainty intervals (default: 95). - ax (Optional[pyplot.Axes]): The axes object to draw the plot on. If None, a new - figure and axes are created. - show (bool): Whether to display the plot immediately (default: False). - **kwargs: Additional keyword arguments for plot customization. These override defaults. + magnitude_bins (list of float or numpy.ndarray, optional): The bins for magnitude + histograms. If `None`, defaults to the region magnitudes or standard CSEP bins. + Defaults to `None`. + percentile (int, optional): The percentile used for uncertainty intervals. Defaults to + `95`. + ax (matplotlib.axes.Axes, optional): The axes object to draw the plot on. If `None`, a + new figure and axes are created. Defaults to `None`. + show (bool, optional): Whether to display the plot immediately. Defaults to `False`. + **kwargs: Additional keyword arguments to customize the plot: + + - **figsize** (`tuple`): The size of the figure. + - **color** (`str`): Color for the observed histogram points. + - **markersize** (`int`): Size of the markers in the plot. Defaults to `6`. + - **capsize** (`float`): Size of the error bar caps. Defaults to `4`. + - **linewidth** (`float`): Width of the error bar lines. Defaults to `1.5`. + - **xlim** (`tuple`): Limits for the X-axis. + - **xlabel** (`str`): Label for the X-axis. Defaults to `'Magnitude'`. + - **xlabel_fontsize** (`int`): Font size for the X-axis label. + - **ylabel** (`str`): Label for the Y-axis. Defaults to `'Event count'`. + - **ylabel_fontsize** (`int`): Font size for the Y-axis label. + - **title** (`str`): Title of the plot. Defaults to `'Magnitude Histogram'`. + - **title_fontsize** (`int`): Font size for the plot title. + - **grid** (`bool`): Whether to show grid lines. Defaults to `True`. + - **legend_loc** (`str`): Location of the legend. Defaults to `'best'`. + - **legend_fontsize** (`int`): Font size of the legend text. + - **tight_layout** (`bool`): Whether to use tight layout for the figure. + Defaults to `True`. Returns: matplotlib.axes.Axes: The axes object containing the plot. """ + # Initialize plot plot_args = {**DEFAULT_PLOT_ARGS, **kwargs} fig, ax = pyplot.subplots(figsize=plot_args["figsize"]) if ax is None else (ax.figure, ax) @@ -459,349 +504,379 @@ def get_histogram_synthetic_cat(x, mags, normed=True): return ax -##################### -# Single Result plots -##################### -def plot_distribution_test( - evaluation_result: "EvaluationResult", - bins: Union[str, int, List[Any]] = "fd", - percentile: Optional[int] = 95, - ax: Optional[matplotlib.axes.Axes] = None, - auto_annotate: Union[bool, dict] = True, - sim_label: str = "Simulated", - obs_label: str = "Observation", - legend: bool = True, +############### +# Spatial plots +############### +def plot_basemap( + basemap: Optional[str] = None, + extent: Optional[List[float]] = None, + coastline: bool = True, + borders: bool = False, + tile_depth: Union[str, int] = "auto", + set_global: bool = False, + projection: Optional[ccrs.Projection] = None, + ax: Optional[pyplot.Axes] = None, show: bool = False, **kwargs, ) -> matplotlib.axes.Axes: """ - Plots a histogram of a single statistic for stochastic event sets and observations. + Wrapper function for multiple Cartopy base plots, including access to standard raster + web services and filesystem geoTIFF. Args: - evaluation_result (EvaluationResult): Object containing test distributions and - observed statistics. - bins (Union[str, int], optional): Binning strategy for the histogram. Defaults - to 'fd'. - percentile (int, optional): Percentile for shading regions. Defaults to None - (use global setting). - ax (Optional[matplotlib.axes.Axes], optional): Axes object to plot on. If None, - creates a new figure and axes. - auto_annotate (bool, dict): If True, automatically format the plot details based - on the evaluation result. It can be customized by passing the keyword arguments - `xlabel`, `ylabel`, `annotation_text`, `annotation_xy` and `annotation_fontsize`. - sim_label (str, optional): Label for the simulated data. - obs_label (str, optional): Label for the observation data. - legend (Optional[bool], optional): Whether to display the legend. Defaults to - global setting. - show (bool, optional): If True, show the plot. Defaults to False. - **kwargs: Additional keyword arguments for plot customization. + basemap (str): Possible values are: `'stock_img'`, `'google-satellite'`, + `'ESRI_terrain'`, `'ESRI_imagery'`, `'ESRI_relief'`, `'ESRI_topo'`, a custom web + service link, or a GeoTiff filepath. Defaults to `None`. + extent (list of float): `[lon_min, lon_max, lat_min, lat_max]`. Defaults to `None`. + coastline (bool): Flag to plot coastline. Defaults to `True`. + borders (bool): Flag to plot country borders. Defaults to `False`. + tile_depth (str or int): Zoom resolution level (`1-12`) of the basemap tiles. If + `'auto'`, it is automatically derived from extent. Defaults to `'auto'`. + set_global (bool): Display the complete globe as basemap. Required by global forecasts. + Defaults to `False`. + projection (cartopy.crs.Projection): Projection to be used in the basemap. It can be a + cartopy projection instance, or `approx` for a quick approximation of Mercator. + Defaults to :class:`~cartopy.crs.PlateCarree` if `None`. + ax (matplotlib.axes.Axes, optional): Previously defined ax object. If `None`, a new + axis is created. Defaults to `None`. + show (bool): If `True`, displays the plot. Defaults to `False`. + **kwargs: Additional keyword arguments to customize the plot: + + - **figsize** (`tuple`): The size of the figure. + - **coastline_color** (`str`): Color for the coastlines. + - **coastline_linewidth** (`float`): Line width for the coastlines. + - **borders_color** (`str`): Color for the borders. + - **borders_linewidth** (`float`): Line width for the borders. + - **grid** (`bool`): Whether to show grid lines. Defaults to `True`. + - **grid_labels** (`bool`): Whether to show grid labels. + - **grid_fontsize** (`int`): Font size for the grid labels. Returns: - matplotlib.axes.Axes: Matplotlib axes handle. + matplotlib.axes.Axes: The Matplotlib axes object with the plotted data. """ - # Initialize plot plot_args = {**DEFAULT_PLOT_ARGS, **kwargs} - fig, ax = pyplot.subplots(figsize=plot_args["figsize"]) if ax is None else (ax.figure, ax) - - # Get distributions - simulated = evaluation_result.test_distribution - observation = evaluation_result.observed_statistic - - # Remove any potential nans from arrays - simulated = numpy.array(simulated) - simulated = simulated[~numpy.isnan(simulated)] + ax = ax or _create_geo_axes(plot_args["figsize"], extent, projection, set_global) - # Plot forecast statistic histogram - n, bin_edges, patches = ax.hist( - simulated, - bins=bins, - label=sim_label, - color=plot_args["color"], - alpha=plot_args["alpha"], - edgecolor=None, - linewidth=0, + line_autoscaler = cartopy.feature.AdaptiveScaler("110m", (("50m", 50), ("10m", 5))) + tile_autoscaler = cartopy.feature.AdaptiveScaler(5, ((6, 50), (7, 15))) + tile_depth = ( + 4 + if set_global + else (tile_autoscaler.scale_from_extent(extent) if tile_depth == "auto" else tile_depth) ) - - # Plot observation statistic value/distribution - if isinstance(observation, (float, int)): - ax.axvline( - x=observation, - color="black", - linestyle="--", - label=obs_label + numpy.isinf(observation) * " (-inf)", + # Add coastlines and borders + if coastline: + ax.coastlines( + color=plot_args["coastline_color"], linewidth=plot_args["coastline_linewidth"] ) - elif isinstance(observation, (list, np.ndarray)): - observation = observation[~numpy.isnan(observation)] - ax.hist( - observation, - bins=bins, - label=obs_label, - edgecolor=None, - linewidth=0, - alpha=plot_args["alpha"], - color="green", + if borders: + borders = cartopy.feature.NaturalEarthFeature( + "cultural", + "admin_0_boundary_lines_land", + line_autoscaler, + edgecolor=plot_args["borders_color"], + facecolor="never", ) + ax.add_feature(borders, linewidth=plot_args["borders_linewidth"]) - # Annotate statistic analysis - ax = _annotate_distribution_plot(ax, evaluation_result, auto_annotate, plot_args) - - # Format axis object - if plot_args["xlim"] is None: - ax = _autoscale_histogram(ax, bin_edges, simulated, observation) - else: - ax.set_xlim(plot_args["xlim"]) - ax.grid(plot_args["grid"]) - - if legend: - ax.legend(loc=plot_args["legend_loc"], fontsize=plot_args["legend_fontsize"]) + # Add basemap tiles + try: + if basemap == "stock_img": + ax.stock_img() + elif basemap is not None: + basemap_obj = _get_basemap(basemap) + # basemap_obj is a cartopy TILE IMAGE + if isinstance(basemap_obj, GoogleWTS): + ax.add_image(basemap_obj, tile_depth) + # basemap_obj is a rasterio image + elif isinstance(basemap_obj, DatasetReader): + ax = rio_plot.show(basemap_obj, ax=ax) - # Color bars for rejection area (after setting legend) - if percentile is not None: - inc = (100 - percentile) / 2 - inc_high = 100 - inc - inc_low = inc + except Exception as e: + print( + f"Unable to plot basemap. This might be due to no internet access. " + f"Error: {str(e)}" + ) - p_high = numpy.percentile(simulated, inc_high) - idx_high = numpy.digitize(p_high, bin_edges) - p_low = numpy.percentile(simulated, inc_low) - idx_low = numpy.digitize(p_low, bin_edges) - for idx in range(idx_low): - patches[idx].set_fc("red") - for idx in range(idx_high, len(patches)): - patches[idx].set_fc("red") + # Set up Grid-lines + if plot_args["grid"]: + _add_gridlines(ax, plot_args["grid_labels"], plot_args["grid_fontsize"]) - if plot_args["tight_layout"]: - fig.tight_layout() if show: pyplot.show() return ax -def plot_calibration_test( - evaluation_result: "EvaluationResult", - percentile: float = 95, +def plot_catalog( + catalog: "CSEPCatalog", + basemap: Optional[str] = None, + projection: Optional[Union[ccrs.Projection, str]] = None, + extent: Optional[Sequence[float]] = None, + set_global: bool = False, + mag_ticks: Optional[Union[Sequence[float], numpy.ndarray, int]] = None, + size: float = 15, + max_size: float = 300, + power: float = 3, + min_val: Optional[float] = None, + max_val: Optional[float] = None, + plot_region: bool = False, ax: Optional[matplotlib.axes.Axes] = None, - label: Optional[str] = None, show: bool = False, **kwargs, ) -> matplotlib.axes.Axes: """ - Plots a calibration test (QQ plot) with confidence intervals. + Spatial plot of catalog. Can be plotted over a basemap if desired, by passing the keyword + parameters of the function :func:`~csep.utils.plots.plot_basemap`. The size of the events + is automatically scaled according to their magnitude. Fine-tuning of an exponential sizing + function can be set with the parameters ``size``, ``max_size``, ``power``, ``min_val`` and + ``max_val``. Args: - evaluation_result (EvaluationResult): The evaluation result object containing the test - distribution. - percentile (float): Percentile to build confidence interval - ax (Optional[matplotlib.axes.Axes]): Axes object to plot on. If None, creates a new - figure. - show (bool): If True, displays the plot. Default is False. - label (Optional[str]): Label for the plotted data. If None, uses - `evaluation_result.sim_name`. - **kwargs: Additional keyword arguments for customizing the plot. These are merged with - `DEFAULT_PLOT_ARGS`. + catalog (CSEPCatalog): Catalog object to be plotted. + basemap (str): Passed to :func:`~csep.utils.plots.plot_basemap` along with `kwargs`. + Possible values are: `'stock_img'`, `'google-satellite'`, `'ESRI_terrain'`, + `'ESRI_imagery'`, `'ESRI_relief'`, `'ESRI_topo'`, a custom web service link, or a + GeoTiff filepath. Defaults to `None`. + projection (cartopy.crs.Projection or str): Projection to be used in the underlying + basemap. Can be a cartopy projection instance, or `approx` for a quick approximation + of Mercator. Defaults to :class:`~cartopy.crs.PlateCarree` if `None`. + extent (list of float): Defaults to `1.05` * :meth:`catalog.region.get_bbox`. Defaults + to `None`. + set_global (bool): Display the complete globe. Defaults to `False`. + mag_ticks (list of float, int): Ticks to display in the legend. Can be an array/list of + magnitudes, or a number of bins to discretize the magnitude range. Defaults to + `None`. + size (float): Size of the minimum magnitude event. Defaults to `15`. + max_size (float): Size of the maximum magnitude event. Defaults to `300`. + power (float): Power scaling of the scatter sizing. Defaults to `3`. + min_val (float): Override minimum magnitude of the catalog for scatter sizing. Useful + to plot multiple catalogs with different magnitude ranges. Defaults to `None`. + max_val (float): Override maximum magnitude of the catalog for scatter sizing. Useful + to plot multiple catalogs with different magnitude ranges. Defaults to `None`. + plot_region (bool): Flag to plot the catalog region border. Defaults to `False`. + ax (matplotlib.axes.Axes): Previously defined ax object. Defaults to `None`. + show (bool): If `True`, displays the plot. Defaults to `False`. + **kwargs: Additional keyword arguments to customize the plot: + + - **alpha** (`float`): Transparency level for the scatter points. + - **markercolor** (`str`): Color for the scatter points. + - **markeredgecolor** (`str`): Color for the edges of the scatter points. + - **figsize** (`tuple`): The size of the figure. + - **legend** (`bool`): Whether to display a legend. Defaults to `True`. + - **legend_title** (`str`): Title for the legend. + - **legend_labelspacing** (`float`): Spacing between labels in the legend. + - **legend_borderpad** (`float`): Border padding for the legend. + - **legend_framealpha** (`float`): Frame alpha for the legend. + - **region_color** (`str`): Color for the region border. + - **title** (`str`): Title of the plot. + - **title_fontsize** (`int`): Font size of the plot title. + - **tight_layout** (`bool`): Whether to use tight layout for the figure. Returns: - pyplot.Axes: The matplotlib axes object containing the plot. + matplotlib.axes.Axes: The Matplotlib axes object with the plotted data. """ - # Initialize plot - plot_args = {**DEFAULT_PLOT_ARGS, **kwargs} - fig, ax = pyplot.subplots(figsize=plot_args["figsize"]) if ax is None else (ax.figure, ax) - - # Set up QQ plots and KS test - n = len(evaluation_result.test_distribution) - k = numpy.arange(1, n + 1) - # Plotting points for uniform quantiles - pp = k / (n + 1) - # Compute confidence intervals for order statistics using beta distribution - inf = (100 - percentile) / 2 - sup = 100 - (100 - percentile) / 2 - ulow = beta.ppf(inf / 100, k, n - k + 1) - uhigh = beta.ppf(sup / 100, k, n - k + 1) - # Quantiles should be sorted for plotting - sorted_td = numpy.sort(evaluation_result.test_distribution) - - if ax is None: - fig, ax = pyplot.subplots() - else: - ax = ax + plot_args = {**DEFAULT_PLOT_ARGS, **kwargs} + # Get spatial information for plotting + extent = extent or _calculate_spatial_extent(catalog, set_global, plot_region) + # Instantiate GeoAxes object + ax = ax or _create_geo_axes(plot_args["figsize"], extent, projection, set_global) + # chain basemap + ax = plot_basemap(basemap, extent, ax=ax, set_global=set_global, show=False, **plot_args) - # Plot QQ plot - ax.plot( - sorted_td, - pp, - linewidth=0, - label=label or evaluation_result.sim_name, - c=plot_args["color"], - marker=plot_args["marker"], - markersize=plot_args["markersize"], + # Plot catalog + ax.scatter( + catalog.get_longitudes(), + catalog.get_latitudes(), + s=_autosize_scatter( + values=catalog.get_magnitudes(), + min_size=size, + max_size=max_size, + power=power, + min_val=min_val, + max_val=max_val, + ), + transform=ccrs.PlateCarree(), + color=plot_args["markercolor"], + edgecolors=plot_args["markeredgecolor"], + alpha=plot_args["alpha"], ) - # Plot uncertainty on uniform quantiles - ax.plot(pp, pp, "-k") - ax.plot(ulow, pp, ":k") - ax.plot(uhigh, pp, ":k") + # Legend + if plot_args["legend"]: + if isinstance(mag_ticks, (list, numpy.ndarray)): + mag_ticks = numpy.array(mag_ticks) + else: + mw_range = [min(catalog.get_magnitudes()), max(catalog.get_magnitudes())] + mag_ticks = numpy.linspace(mw_range[0], mw_range[1], mag_ticks or 4, endpoint=True) - # Format plot - ax.grid(plot_args["grid"]) - ax.set_title(plot_args["title"] or "Calibration test", fontsize=plot_args["title_fontsize"]) - ax.set_xlabel( - plot_args["xlabel"] or "Quantile scores", fontsize=plot_args["xlabel_fontsize"] - ) - ax.set_ylabel( - plot_args["ylabel"] or "Standard uniform quantiles", - fontsize=plot_args["ylabel_fontsize"], - ) - ax.legend(loc=plot_args["legend_loc"], fontsize=plot_args["legend_fontsize"]) + # Map mag_ticks to marker sizes using the custom size mapping function + legend_sizes = _autosize_scatter( + values=mag_ticks, + min_size=size, + max_size=max_size, + power=power, + min_val=min_val or numpy.min(catalog.get_magnitudes()), + max_val=max_val or numpy.max(catalog.get_magnitudes()), + ) - if plot_args["tight_layout"]: - fig.tight_layout() - if show: - pyplot.show() + # Create custom legend handles + handles = [ + pyplot.Line2D( + [0], + [0], + marker="o", + lw=0, + label=str(m), + markersize=numpy.sqrt(s), + markerfacecolor="gray", + alpha=0.5, + markeredgewidth=0.8, + markeredgecolor="black", + ) + for m, s in zip(mag_ticks, legend_sizes) + ] + + ax.legend( + handles, + numpy.round(mag_ticks, 1), + loc=plot_args["legend_loc"], + handletextpad=5, + title=plot_args.get("legend_title") or "Magnitudes", + fontsize=plot_args["legend_fontsize"], + title_fontsize=plot_args["legend_titlesize"], + labelspacing=plot_args["legend_labelspacing"], + borderpad=plot_args["legend_borderpad"], + framealpha=plot_args["legend_framealpha"], + ) + + # Draw catalog's region border + if plot_region: + try: + pts = catalog.region.tight_bbox() + ax.plot(pts[:, 0], pts[:, 1], lw=1, color=plot_args["region_color"]) + except AttributeError: + pass + + ax.set_title(plot_args["title"], fontsize=plot_args["title_fontsize"], y=1.06) + + if plot_args["tight_layout"]: + ax.figure.tight_layout() + + if show: + pyplot.show() return ax -##################### -# Results batch plots -##################### -def plot_comparison_test( - results_t: List["EvaluationResult"], - results_w: Optional[List["EvaluationResult"]] = None, - percentile: int = 95, - ax: Optional[matplotlib.axes.Axes] = None, +def plot_gridded_dataset( + gridded: numpy.ndarray, + region: "CartesianGrid2D", + basemap: Optional[str] = None, + ax: Optional[pyplot.Axes] = None, + projection: Optional[Union[ccrs.Projection, str]] = None, show: bool = False, + extent: Optional[List[float]] = None, + set_global: bool = False, + plot_region: bool = True, + colorbar: bool = True, + colormap: Union[str, matplotlib.colors.Colormap] = "viridis", + clim: Optional[Tuple[float, float]] = None, + clabel: Optional[str] = None, + alpha: Optional[float] = None, + alpha_exp: float = 0, **kwargs, -) -> pyplot.Axes: +) -> matplotlib.axes.Axes: """ - Plots a list of T-Test (and optional W-Test) results on a single axis. + Plot spatial gridded dataset such as data from a gridded forecast. Can be plotted over a + basemap if desired, by passing the keyword parameters of the function + :func:`~csep.utils.plots.plot_basemap`. The color map can be fine-tuned using the arguments + ``colorbar``, ``colormap``, ``clim``. An exponential transparency function can be set + with ``alpha`` and ``alpha_exp``. Args: - results_t (List[EvaluationResult]): List of T-Test results. - results_w (Optional[List[EvaluationResult]]): List of W-Test results. If provided, they - are plotted alongside the T-Test results. - percentile (int): Percentile for coloring W-Test results. Default is 95. - ax (Optional[matplotlib.axes.Axes]): Matplotlib axes object to plot on. If None, a new - figure and axes are created. - show (bool): If True, the plot is displayed after creation. Default is False. - **kwargs: Additional plotting arguments to override defaults. + gridded (numpy.ndarray): 2D-square array of values corresponding to the region. See + :class:`~csep.core.regions.CartesianGrid2D` and + :meth:`~csep.core.regions.CartesianGrid2D.get_cartesian` to convert a 1D array + (whose indices correspond to each spatial cell) to a 2D-square array. + region (CartesianGrid2D): Region in which gridded values are contained. + basemap (str): Passed to :func:`~csep.utils.plots.plot_basemap` along with `kwargs`. + ax (matplotlib.axes.Axes): Previously defined ax object. Defaults to `None`. + projection (cartopy.crs.Projection or str): Projection to be used in the underlying + basemap. It can be a cartopy projection instance, or `approx` for a quick + approximation of Mercator. Defaults to :class:`~cartopy.crs.PlateCarree` if `None`. + show (bool): If `True`, displays the plot. Defaults to `False`. + extent (list of float): ``[lon_min, lon_max, lat_min, lat_max]``. Defaults to `None`. + set_global (bool): Display the complete globe as basemap. Defaults to `False`. + plot_region (bool): If `True`, plot the dataset region border. Defaults to `True`. + colorbar (bool): If `True`, include a colorbar. Defaults to `True`. + colormap (str or matplotlib.colors.Colormap): Colormap to use. Defaults to `'viridis'`. + clim (tuple of float): Range of the colorbar. Defaults to `None`. + clabel (str): Label of the colorbar. Defaults to `None`. + alpha (float): Transparency level. Defaults to `None`. + alpha_exp (float): Exponent for the alpha function (recommended between `0.4` and `1`). + Defaults to `0`. + **kwargs: Additional keyword arguments to customize the plot: + + - **colorbar_labelsize** (`int`): Font size for the colorbar label. + - **colorbar_ticksize** (`int`): Font size for the colorbar ticks. + - **figsize** (`tuple`): The size of the figure. + - **region_color** (`str`): Color for the region border. + - **title** (`str`): Title of the plot. + - **title_fontsize** (`int`): Font size of the plot title. Returns: - pyplot.Axes: The matplotlib axes object containing the plot. + matplotlib.axes.Axes: Matplotlib axes object. """ - # Initialize plot plot_args = {**DEFAULT_PLOT_ARGS, **kwargs} - fig, ax = pyplot.subplots(figsize=plot_args["figsize"]) if ax is None else (ax.figure, ax) - - # Iterate through T-test results, or jointly through t- and w- test results - Results = zip(results_t, results_w) if results_w else zip(results_t) - for index, result in enumerate(Results): - result_t = result[0] - result_w = result[1] if results_w else None - - # Get confidence bounds - ylow = result_t.observed_statistic - result_t.test_distribution[0] - yhigh = result_t.test_distribution[1] - result_t.observed_statistic - color = _get_marker_t_color(result_t.test_distribution) - if not numpy.isinf(result_t.observed_statistic): - # Plot observed statistic and confidence bounds - ax.errorbar( - index, - result_t.observed_statistic, - yerr=numpy.array([[ylow, yhigh]]).T, - color=color, - linewidth=plot_args["linewidth"], - capsize=plot_args["capsize"], - ) + # Get spatial information for plotting + extent = extent or _calculate_spatial_extent(region, set_global, plot_region) + # Instantiate GeoAxes object + ax = ax or _create_geo_axes(plot_args["figsize"], extent, projection, set_global) - facecolor = "white" - if result_w is not None: - if _get_marker_w_color(result_w.quantile, percentile): - facecolor = _get_marker_t_color(result_t.test_distribution) + # chain basemap + ax = plot_basemap(basemap, extent, ax=ax, set_global=set_global, show=False, **plot_args) - ax.plot( - index, - result_t.observed_statistic, - marker="o", - markerfacecolor=facecolor, - markeredgecolor=color, - markersize=plot_args["markersize"], - ) - else: - print( - f"Diverging information gain for forecast {result_t.sim_name}, index {index}. " - f"Check for zero-valued bins within the forecast" - ) - ax.axvspan(index - 0.5, index + 0.5, alpha=0.5, facecolor="red") + # Define colormap and alpha transparency + colormap, alpha = _get_colormap(colormap, alpha_exp, alpha) - # Format plot - ax.axhline(y=0, linestyle="--", color="black") - ax.set_xticks(numpy.arange(len(results_t))) - ax.set_xticklabels( - [res.sim_name[0] for res in results_t], - rotation=90, - fontsize=plot_args["xlabel_fontsize"], + # Plot spatial dataset + lons, lats = numpy.meshgrid( + numpy.append(region.xs, region.get_bbox()[1]), + numpy.append(region.ys, region.get_bbox()[3]), ) - ax.set_ylabel( - plot_args["ylabel"] or "Information gain per earthquake", - fontsize=plot_args["ylabel_fontsize"], + im = ax.pcolor( + lons, lats, gridded, cmap=colormap, alpha=alpha, snap=True, transform=ccrs.PlateCarree() ) + im.set_clim(clim) - ax.set_title(plot_args["title"] or results_t[0].name) - ax.set_ylim(plot_args["ylim"]) - ax.set_xlim([-0.5, len(results_t) - 0.5]) - - if plot_args["grid"]: - ax.yaxis.grid() - ax.yaxis.set_major_locator(pyplot.MaxNLocator(integer=True)) - - if plot_args["hbars"]: - if len(results_t) > 2: - ax.bar( - ax.get_xticks(), - numpy.array([9999] * len(ax.get_xticks())), - bottom=-2000, - width=(ax.get_xticks()[1] - ax.get_xticks()[0]), - color=["gray", "w"], - alpha=0.2, - ) - - if plot_args["legend"]: - # Add custom legend to explain results - legend_elements = [ - Line2D([0], [0], color="red", lw=2, - label=f"T-test rejected ($\\alpha = {results_t[0].quantile[-1]}$)"), - Line2D([0], [0], color="green", lw=2, label="T-test non-rejected"), - Line2D([0], [0], color="gray", lw=2, label="T-test indistinguishable"), - Line2D( - [0], - [0], - color="gray", - lw=2, - marker="o", - markersize=6, - markerfacecolor="green", - label="W-test non-rejected", - ), - Line2D( - [0], - [0], - color="gray", - lw=2, - marker="o", - markersize=6, - markerfacecolor="white", - label="W-test indistinguishable", - ), - ] - ax.legend(handles=legend_elements, loc="best", fontsize=plot_args["legend_fontsize"]) + # Colorbar options + if colorbar: + cax = ax.get_figure().add_axes( + [ + ax.get_position().x1 + 0.01, + ax.get_position().y0, + 0.025, + ax.get_position().height, + ], + label="Colorbar", + ) + cbar = ax.get_figure().colorbar(im, ax=ax, cax=cax) + cbar.set_label(clabel, fontsize=plot_args["colorbar_labelsize"]) + cbar.ax.tick_params(labelsize=plot_args["colorbar_ticksize"]) + # Draw forecast's region border + if plot_region and not set_global: + try: + pts = region.tight_bbox() + ax.plot(pts[:, 0], pts[:, 1], lw=1, color=plot_args["region_color"]) + except AttributeError: + pass - if plot_args["tight_layout"]: - fig.tight_layout() + ax.set_title(plot_args["title"], fontsize=plot_args["title_fontsize"], y=1.06) if show: pyplot.show() @@ -809,218 +884,234 @@ def plot_comparison_test( return ax -def plot_consistency_test( - eval_results: Union[List["EvaluationResult"], "EvaluationResult"], - normalize: bool = False, - one_sided_lower: bool = False, - percentile: float = 95, - ax: Optional[pyplot.Axes] = None, - plot_mean: bool = False, - color: str = "black", +##################### +# Single Result plots +##################### +def plot_distribution_test( + evaluation_result: "EvaluationResult", + bins: Union[str, int, List[Any]] = "fd", + percentile: Optional[int] = 95, + ax: Optional[matplotlib.axes.Axes] = None, + auto_annotate: Union[bool, dict] = True, + sim_label: str = "Simulated", + obs_label: str = "Observation", + legend: bool = True, show: bool = False, **kwargs, ) -> matplotlib.axes.Axes: """ - Plots the results from ultiple consistency tests. The distribution of score results from - multiple realizations of a model are plotted as a line representing for a given percentile. - The score of the observation under a model is plotted as a marker. The model is assumed - inconsistent when the observation score lies outside from the model distribution for a - two-sided test, or lies to the right of the distribution for a one-sided test. + Plots a histogram of a single statistic for stochastic event sets and observations. Args: - eval_results (Union[List[EvaluationResult], EvaluationResult]): - Evaluation results from one or multiple models - normalize (bool): - Normalize the forecast likelihood by observed likelihood (default: False). - percentile (float): - Percentile for the extent of the model score distribution (default: 95). - one_sided_lower (bool): - Plot for a one-sided test (default: False). - ax (Optional[pyplot.Axes]): - Axes object to plot on (default: None). - plot_mean (bool): - Plot the mean of the test distribution (default: False). - color (str): - Color for the line representing a model score distribution (default: 'black'). - show (bool): - If True, display the plot (default: False). - **kwargs: - Additional keyword arguments for plot customization from DEFAULT_PLOT_ARGS. + evaluation_result (EvaluationResult): Object containing test + distributions and observed statistics. + bins (str, int, or list): Binning strategy for the histogram. See + :func:`matplotlib.pyplot.hist` for details on this parameter. Defaults to `'fd'`. + percentile (int): Percentile for shading regions. Defaults to `95`. + ax (matplotlib.axes.Axes): Axes object to plot on. If `None`, creates a new figure + and axes. Defaults to `None`. + auto_annotate (bool or dict): If `True`, automatically formats the plot details based + on the evaluation result. It can be further customized by passing the keyword + arguments `xlabel`, `ylabel`, `annotation_text`, `annotation_xy`, and + `annotation_fontsize`. Defaults to `True`. + sim_label (str): Label for the simulated data. Defaults to `'Simulated'`. + obs_label (str): Label for the observation data. Defaults to `'Observation'`. + legend (bool): Whether to display the legend. Defaults to `True`. + show (bool): If `True`, shows the plot. Defaults to `False`. + **kwargs: Additional keyword arguments for plot customization. + + - **color** (`str`): Color of the histogram bars. + - **alpha** (`float`): Transparency level for the histogram bars. + - **figsize** (`tuple`): The size of the figure. + - **xlim** (`tuple`): Limits for the X-axis. + - **grid** (`bool`): Whether to display grid lines. Defaults to `True`. + - **legend_loc** (`str`): Location of the legend. Defaults to `'best'`. + - **legend_fontsize** (`int`): Font size of the legend text. + - **xlabel**: Label of the X-axis. If `auto_annotate` is `True`, will be set to the + test statistic name. + - **ylabel**: Label of the Y-axis. + - **annotate_text**: Annotate the plot. If `auto_annotate` is `True`, it will + provide information about the statistics of the test. + - **annotate_xy**: Position for `annotate_text` in axes fraction. Can be override + if `auto_annotate` does not give an optimal position + - **annotate_fontsize**: Size of the annotation. + - **tight_layout** (`bool`): Whether to use tight layout for the figure. + Defaults to `True`. Returns: - matplotlib.axes.Axes: Matplotlib axes object with the consistency test plot. + matplotlib.axes.Axes: Matplotlib axes handle. """ # Initialize plot plot_args = {**DEFAULT_PLOT_ARGS, **kwargs} fig, ax = pyplot.subplots(figsize=plot_args["figsize"]) if ax is None else (ax.figure, ax) - # Ensure eval_results is a list - results = list(eval_results) if isinstance(eval_results, list) else [eval_results] - results.reverse() + # Get distributions + simulated = evaluation_result.test_distribution + observation = evaluation_result.observed_statistic - xlims = [] + # Remove any potential nans from arrays + simulated = numpy.array(simulated) + simulated = simulated[~numpy.isnan(simulated)] - for index, res in enumerate(results): - plow, phigh, mean, observed_statistic = _process_stat_distribution( - res, percentile, normalize, one_sided_lower - ) + # Plot forecast statistic histogram + n, bin_edges, patches = ax.hist( + simulated, + bins=bins, + label=sim_label, + color=plot_args["color"], + alpha=plot_args["alpha"], + edgecolor=None, + linewidth=0, + ) - if not numpy.isinf(observed_statistic): # Check if test result does not diverge - percentile_lims = numpy.abs(numpy.array([[mean - plow, phigh - mean]]).T) - ax.plot( - observed_statistic, - index, - _get_marker_style(observed_statistic, (plow, phigh), one_sided_lower), - ) - ax.errorbar( - mean, - index, - xerr=percentile_lims, - fmt="ko" if plot_mean else "k", - capsize=plot_args["capsize"], - linewidth=plot_args["linewidth"], - ecolor=color, - ) - # Determine the limits to use - xlims.append((plow, phigh, observed_statistic)) + # Plot observation statistic value/distribution + if isinstance(observation, (float, int)): + ax.axvline( + x=observation, + color="black", + linestyle="--", + label=obs_label + numpy.isinf(observation) * " (-inf)", + ) + elif isinstance(observation, (list, numpy.ndarray)): + observation = observation[~numpy.isnan(observation)] + ax.hist( + observation, + bins=bins, + label=obs_label, + edgecolor=None, + linewidth=0, + alpha=plot_args["alpha"], + color="green", + ) - # Extend distribution to +inf, in case it is a one-sided test - if one_sided_lower and observed_statistic >= plow and phigh < observed_statistic: - xt = numpy.linspace(phigh, 99999, 100) - yt = numpy.ones(100) * index - ax.plot(xt, yt, linestyle="--", linewidth=plot_args["linewidth"], color=color) - else: - print( - f"Observed statistic diverges for forecast {res.sim_name}, index {index}. " - f"Check for zero-valued bins within the forecast" - ) - ax.barh(index, 99999, left=-10000, height=1, color=["red"], alpha=0.5) + # Annotate statistic analysis + ax = _annotate_distribution_plot(ax, evaluation_result, auto_annotate, plot_args) + + # Format axis object + if plot_args["xlim"] is None: + ax = _autoscale_histogram(ax, bin_edges, simulated, observation) + else: + ax.set_xlim(plot_args["xlim"]) + ax.grid(plot_args["grid"]) + + if legend: + ax.legend(loc=plot_args["legend_loc"], fontsize=plot_args["legend_fontsize"]) + + # Color bars for rejection area (after setting legend) + if percentile is not None: + inc = (100 - percentile) / 2 + inc_high = 100 - inc + inc_low = inc + + p_high = numpy.percentile(simulated, inc_high) + idx_high = numpy.digitize(p_high, bin_edges) + p_low = numpy.percentile(simulated, inc_low) + idx_low = numpy.digitize(p_low, bin_edges) + for idx in range(idx_low): + patches[idx].set_fc("red") + for idx in range(idx_high, len(patches)): + patches[idx].set_fc("red") - # Plot formatting - try: - ax.set_xlim(*_get_axis_limits(xlims)) - except ValueError: - raise ValueError("All EvaluationResults have infinite observed_statistics") - ax.set_ylim([-0.5, len(results) - 0.5]) - ax.set_yticks(numpy.arange(len(results))) - ax.set_yticklabels([res.sim_name for res in results], fontsize=plot_args["ylabel_fontsize"]) - ax.set_xlabel( - plot_args["xlabel"] or "Statistic distribution", fontsize=plot_args["xlabel_fontsize"] - ) - ax.tick_params(axis="x", labelsize=plot_args["xticks_fontsize"]) - ax.set_title(plot_args["title"], fontsize=plot_args["title_fontsize"]) - if plot_args["hbars"]: - yTickPos = ax.get_yticks() - if len(yTickPos) >= 2: - ax.barh( - yTickPos, - numpy.array([99999] * len(yTickPos)), - left=-10000, - height=(yTickPos[1] - yTickPos[0]), - color=["w", "gray"], - alpha=0.2, - zorder=0, - ) if plot_args["tight_layout"]: fig.tight_layout() - if show: pyplot.show() return ax -################### -# Alarm-based plots -################### -def plot_concentration_ROC_diagram( - forecast: "GriddedForecast", - catalog: "CSEPCatalog", - linear: bool = True, - plot_uniform: bool = True, - show: bool = True, - ax: Optional[pyplot.Axes] = None, +def plot_calibration_test( + evaluation_result: "EvaluationResult", + percentile: float = 95, + ax: Optional[matplotlib.axes.Axes] = None, + label: Optional[str] = None, + show: bool = False, **kwargs, ) -> matplotlib.axes.Axes: """ - Plots the Concentration ROC Diagram for a given forecast and observed catalog. + Plots a calibration test (Quantile-Quantile plot) with confidence intervals. Args: - forecast (GriddedForecast): Forecast object containing spatial forecast data. - catalog (CSEPCatalog): Catalog object containing observed data. - linear (bool): If True, uses a linear scale for the X-axis, otherwise logarithmic. - ax (Optional[pyplot.Axes]): Axes object to plot on (default: None). - plot_uniform (bool): If True, plots the uniform (random) model as a reference - (default: True). - show (bool): If True, displays the plot (default: True). - ax (Optional[pyplot.Axes]): Axes object to plot on (default: None). - **kwargs: Additional keyword arguments for customization. + evaluation_result (EvaluationResult): The evaluation result object containing + the test distribution. + percentile (float): Percentile to build confidence interval. Defaults to `95`. + ax (matplotlib.axes.Axes): Axes object to plot on. If `None`, creates a new figure. + Defaults to `None`. + label (str): Label for the plotted data. If `None`, uses + `evaluation_result.sim_name`. Defaults to `None`. + show (bool): If `True`, displays the plot. Defaults to `False`. + **kwargs: Additional keyword arguments for customizing the plot: + + - **color** (`str`): Color of the plot line and markers. + - **marker** (`str`): Marker style for the data points. + - **markersize** (`float`): Size of the markers. + - **grid** (`bool`): Whether to display grid lines. Defaults to `True`. + - **title** (`str`): Title of the plot. + - **title_fontsize** (`int`): Font size for the plot title. + - **xlabel** (`str`): Label for the X-axis. + - **xlabel_fontsize** (`int`): Font size for the X-axis label. + - **ylabel** (`str`): Label for the Y-axis. + - **ylabel_fontsize** (`int`): Font size for the Y-axis label. + - **legend_loc** (`str`): Location of the legend. Defaults to `'best'`. + - **legend_fontsize** (`int`): Font size of the legend text. + - **tight_layout** (`bool`): Whether to use tight layout for the figure. + Defaults to `True`. Returns: - matplotlib.axes.Axes: The Axes object with the plot. + matplotlib.axes.Axes: The Matplotlib axes object containing the plot. """ - # Initialize plot plot_args = {**DEFAULT_PLOT_ARGS, **kwargs} fig, ax = pyplot.subplots(figsize=plot_args["figsize"]) if ax is None else (ax.figure, ax) - if not catalog.region == forecast.region: - raise AttributeError("catalog region and forecast region must be identical.") - - # Getting data - forecast_label = plot_args.get("forecast_label", forecast.name or "Forecast") - observed_label = plot_args.get("observation_label", "Observations") - - area_km2 = catalog.region.get_cell_area() - obs_counts = catalog.spatial_counts() - rate = forecast.spatial_counts() - - indices = numpy.argsort(rate) - indices = numpy.flip(indices) + # Set up QQ plots and KS test + n = len(evaluation_result.test_distribution) + k = numpy.arange(1, n + 1) + # Plotting points for uniform quantiles + pp = k / (n + 1) + # Compute confidence intervals for order statistics using beta distribution + inf = (100 - percentile) / 2 + sup = 100 - (100 - percentile) / 2 + ulow = beta.ppf(inf / 100, k, n - k + 1) + uhigh = beta.ppf(sup / 100, k, n - k + 1) - fore_norm_sorted = numpy.cumsum(rate[indices]) / numpy.sum(rate) - area_norm_sorted = numpy.cumsum(area_km2[indices]) / numpy.sum(area_km2) - obs_norm_sorted = numpy.cumsum(obs_counts[indices]) / numpy.sum(obs_counts) + # Quantiles should be sorted for plotting + sorted_td = numpy.sort(evaluation_result.test_distribution) - # Plot data - if plot_uniform: - ax.plot(area_norm_sorted, area_norm_sorted, "k--", label="Uniform") + if ax is None: + fig, ax = pyplot.subplots() + else: + ax = ax + # Plot QQ plot ax.plot( - area_norm_sorted, - fore_norm_sorted, - label=forecast_label, - color=plot_args["secondary_color"], + sorted_td, + pp, + linewidth=0, + label=label or evaluation_result.sim_name, + c=plot_args["color"], + marker=plot_args["marker"], + markersize=plot_args["markersize"], ) - ax.step( - area_norm_sorted, - obs_norm_sorted, - label=observed_label, - color=plot_args["color"], - linestyle=plot_args["linestyle"], - ) + # Plot uncertainty on uniform quantiles + ax.plot(pp, pp, "-k") + ax.plot(ulow, pp, ":k") + ax.plot(uhigh, pp, ":k") - # Plot formatting - ax.set_title(plot_args["title"], fontsize=plot_args["title_fontsize"]) + # Format plot ax.grid(plot_args["grid"]) - if not linear: - ax.set_xscale("log") - ax.set_ylabel( - plot_args["ylabel"] or "True Positive Rate", fontsize=plot_args["ylabel_fontsize"] - ) + ax.set_title(plot_args["title"] or "Calibration test", fontsize=plot_args["title_fontsize"]) ax.set_xlabel( - plot_args["xlabel"] or "False Positive Rate (Normalized Area)", - fontsize=plot_args["xlabel_fontsize"], + plot_args["xlabel"] or "Quantile scores", fontsize=plot_args["xlabel_fontsize"] ) - if plot_args["legend"]: - ax.legend( - loc=plot_args["legend_loc"], - shadow=True, - fontsize=plot_args["legend_fontsize"], - framealpha=plot_args["legend_framealpha"], - ) + ax.set_ylabel( + plot_args["ylabel"] or "Standard uniform quantiles", + fontsize=plot_args["ylabel_fontsize"], + ) + ax.legend(loc=plot_args["legend_loc"], fontsize=plot_args["legend_fontsize"]) + if plot_args["tight_layout"]: fig.tight_layout() if show: @@ -1029,106 +1120,157 @@ def plot_concentration_ROC_diagram( return ax -def plot_ROC_diagram( - forecast: "GriddedForecast", - catalog: "CSEPCatalog", - linear: bool = True, - plot_uniform: bool = True, - show: bool = True, - ax: Optional[pyplot.Axes] = None, +##################### +# Results batch plots +##################### +def plot_comparison_test( + results_t: List["EvaluationResult"], + results_w: Optional[List["EvaluationResult"]] = None, + percentile: int = 95, + ax: Optional[matplotlib.axes.Axes] = None, + show: bool = False, **kwargs, -) -> matplotlib.pyplot.Axes: +) -> pyplot.Axes: """ - Plots the ROC (Receiver Operating Characteristic) curve for a given forecast and observed - catalog. + Plots a list of T-Test (and optional W-Test) results on a single axis. Args: - forecast (GriddedForecast): Forecast object containing spatial forecast data. - catalog (CSEPCatalog): Catalog object containing observed data. - linear (bool): If True, uses a linear scale for the X-axis, otherwise logarithmic. - plot_uniform (bool): If True, plots the uniform (random) model as a reference (default: - True). - show (bool): If True, displays the plot (default: True). - ax (Optional[pyplot.Axes]): Axes object to plot on (default: None). - **kwargs: Additional keyword arguments for customization. + results_t (list of EvaluationResult): List of T-Test results. + results_w (list of EvaluationResult, optional): List of W-Test results. If + provided, they are plotted alongside the T-Test results. Defaults to `None`. + percentile (int): Percentile for coloring W-Test results. Defaults to `95`. + ax (matplotlib.axes.Axes): Matplotlib axes object to plot on. If `None`, a new + figure and axes are created. Defaults to `None`. + show (bool): If `True`, the plot is displayed after creation. Defaults to `False`. + **kwargs: Additional keyword arguments for customizing the plot: + + - **linewidth** (`float`): Width of the error bars. + - **capsize** (`float`): Size of the caps on the error bars. + - **markersize** (`float`): Size of the markers. + - **xlabel_fontsize** (`int`): Font size for the X-axis labels. + - **ylabel** (`str`): Label for the Y-axis. Defaults to `'Information gain per earthquake'`. + - **ylabel_fontsize** (`int`): Font size for the Y-axis label. + - **title** (`str`): Title of the plot. Defaults to the name of the first T-Test result. + - **ylim** (`tuple`): Limits for the Y-axis. + - **grid** (`bool`): Whether to display grid lines. Defaults to `True`. + - **hbars** (`bool`): Whether to include horizontal bars for visual separation. + - **legend** (`bool`): Whether to display a legend. Defaults to `True`. + - **legend_fontsize** (`int`): Font size for the legend text. + - **tight_layout** (`bool`): Whether to use tight layout for the figure. Defaults + to `True`. Returns: - pyplot.Axes: The Axes object with the plot. + matplotlib.axes.Axes: The Matplotlib axes object containing the plot. """ # Initialize plot plot_args = {**DEFAULT_PLOT_ARGS, **kwargs} fig, ax = pyplot.subplots(figsize=plot_args["figsize"]) if ax is None else (ax.figure, ax) - if not catalog.region == forecast.region: - raise RuntimeError("catalog region and forecast region must be identical.") - - rate = forecast.spatial_counts() - obs_counts = catalog.spatial_counts() - - indices = numpy.argsort(rate)[::-1] # Sort in descending order + # Iterate through T-test results, or jointly through t- and w- test results + Results = zip(results_t, results_w) if results_w else zip(results_t) + for index, result in enumerate(Results): + result_t = result[0] + result_w = result[1] if results_w else None - thresholds = (rate[indices]) / numpy.sum(rate) - obs_counts = obs_counts[indices] + # Get confidence bounds + ylow = result_t.observed_statistic - result_t.test_distribution[0] + yhigh = result_t.test_distribution[1] - result_t.observed_statistic + color = _get_marker_t_color(result_t.test_distribution) - Table_ROC = pandas.DataFrame({"Threshold": [], "H": [], "F": []}) + if not numpy.isinf(result_t.observed_statistic): + # Plot observed statistic and confidence bounds + ax.errorbar( + index, + result_t.observed_statistic, + yerr=numpy.array([[ylow, yhigh]]).T, + color=color, + linewidth=plot_args["linewidth"], + capsize=plot_args["capsize"], + ) - for threshold in thresholds: - threshold = float(threshold) - binary_forecast = numpy.where(thresholds >= threshold, 1, 0) - forecastedYes_observedYes = obs_counts[(binary_forecast == 1) & (obs_counts > 0)] - forecastedYes_observedNo = obs_counts[(binary_forecast == 1) & (obs_counts == 0)] - forecastedNo_observedYes = obs_counts[(binary_forecast == 0) & (obs_counts > 0)] - forecastedNo_observedNo = obs_counts[(binary_forecast == 0) & (obs_counts == 0)] + facecolor = "white" + if result_w is not None: + if _get_marker_w_color(result_w.quantile, percentile): + facecolor = _get_marker_t_color(result_t.test_distribution) - H = len(forecastedYes_observedYes) / ( - len(forecastedYes_observedYes) + len(forecastedNo_observedYes) - ) - F = len(forecastedYes_observedNo) / ( - len(forecastedYes_observedNo) + len(forecastedNo_observedNo) - ) - - threshold_row = {"Threshold": threshold, "H": H, "F": F} - Table_ROC = pandas.concat( - [Table_ROC, pandas.DataFrame([threshold_row])], ignore_index=True - ) + ax.plot( + index, + result_t.observed_statistic, + marker="o", + markerfacecolor=facecolor, + markeredgecolor=color, + markersize=plot_args["markersize"], + ) + else: + print( + f"Diverging information gain for forecast {result_t.sim_name}, index {index}. " + f"Check for zero-valued bins within the forecast" + ) + ax.axvspan(index - 0.5, index + 0.5, alpha=0.5, facecolor="red") - Table_ROC = pandas.concat( - [pandas.DataFrame({"H": [0], "F": [0]}), Table_ROC], ignore_index=True + # Format plot + ax.axhline(y=0, linestyle="--", color="black") + ax.set_xticks(numpy.arange(len(results_t))) + ax.set_xticklabels( + [res.sim_name[0] for res in results_t], + rotation=90, + fontsize=plot_args["xlabel_fontsize"], ) - - ax.plot( - Table_ROC["F"], - Table_ROC["H"], - label=plot_args.get("forecast_label", forecast.name or "Forecast"), - color=plot_args["color"], - linestyle=plot_args["linestyle"], + ax.set_ylabel( + plot_args["ylabel"] or "Information gain per earthquake", + fontsize=plot_args["ylabel_fontsize"], ) - if plot_uniform: - ax.plot( - numpy.arange(0, 1.001, 0.001), - numpy.arange(0, 1.001, 0.001), - linestyle="--", - color="gray", - label="Uniform", - ) + ax.set_title(plot_args["title"] or results_t[0].name) + ax.set_ylim(plot_args["ylim"]) + ax.set_xlim([-0.5, len(results_t) - 0.5]) + + if plot_args["grid"]: + ax.yaxis.grid() + ax.yaxis.set_major_locator(pyplot.MaxNLocator(integer=True)) + + if plot_args["hbars"]: + if len(results_t) > 2: + ax.bar( + ax.get_xticks(), + numpy.array([9999] * len(ax.get_xticks())), + bottom=-2000, + width=(ax.get_xticks()[1] - ax.get_xticks()[0]), + color=["gray", "w"], + alpha=0.2, + ) - # Plot formatting - ax.set_ylabel(plot_args["ylabel"] or "Hit Rate", fontsize=plot_args["ylabel_fontsize"]) - ax.set_xlabel( - plot_args["xlabel"] or "Fraction of False Alarms", fontsize=plot_args["xlabel_fontsize"] - ) - if not linear: - ax.set_xscale("log") - ax.set_yscale("linear") - ax.tick_params(axis="x", labelsize=plot_args["xticks_fontsize"]) - ax.tick_params(axis="y", labelsize=plot_args["yticks_fontsize"]) if plot_args["legend"]: - ax.legend( - loc=plot_args["legend_loc"], shadow=True, fontsize=plot_args["legend_fontsize"] - ) - ax.set_title(plot_args["title"], fontsize=plot_args["title_fontsize"]) + # Add custom legend to explain results + legend_elements = [ + Line2D([0], [0], color="red", lw=2, + label=f"T-test rejected ($\\alpha = {results_t[0].quantile[-1]}$)"), + Line2D([0], [0], color="green", lw=2, label="T-test non-rejected"), + Line2D([0], [0], color="gray", lw=2, label="T-test indistinguishable"), + Line2D( + [0], + [0], + color="gray", + lw=2, + marker="o", + markersize=6, + markerfacecolor="green", + label="W-test non-rejected", + ), + Line2D( + [0], + [0], + color="gray", + lw=2, + marker="o", + markersize=6, + markerfacecolor="white", + label="W-test indistinguishable", + ), + ] + ax.legend(handles=legend_elements, loc="best", fontsize=plot_args["legend_fontsize"]) + if plot_args["tight_layout"]: fig.tight_layout() @@ -1138,425 +1280,376 @@ def plot_ROC_diagram( return ax -def plot_Molchan_diagram( - forecast: "GriddedForecast", - catalog: "CSEPCatalog", - linear: bool = True, - plot_uniform: bool = True, - show: bool = True, +def plot_consistency_test( + eval_results: Union[List["EvaluationResult"], "EvaluationResult"], + normalize: bool = False, + one_sided_lower: bool = False, + percentile: float = 95, ax: Optional[pyplot.Axes] = None, + plot_mean: bool = False, + color: str = "black", + show: bool = False, **kwargs, ) -> matplotlib.axes.Axes: """ - Plot the Molchan Diagram based on forecast and test catalogs using the contingency table. - The Area Skill score and its error are shown in the legend. - - The Molchan diagram is computed following this procedure: - 1. Obtain spatial rates from the GriddedForecast and the observed events from the catalog. - 2. Rank the rates in descending order (highest rates first). - 3. Sort forecasted rates by ordering found in (2), and normalize rates so their sum is equal - to unity. - 4. Obtain binned spatial rates from the observed catalog. - 5. Sort gridded observed rates by ordering found in (2). - 6. Test each ordered and normalized forecasted rate defined in (3) as a threshold value to - obtain the corresponding contingency table. - 7. Define the "nu" (Miss rate) and "tau" (Fraction of spatial alarmed cells) for each - threshold using the information provided by the corresponding contingency table defined in - (6). - - Note: - 1. The testing catalog and forecast should have exactly the same time-window (duration). - 2. Forecasts should be defined over the same region. - 3. If calling this function multiple times, update the color in the arguments. - 4. The user can choose the x-scale (linear or log). + Plots the results from multiple consistency tests. The distribution of score results from + multiple realizations of a model are plotted as a line representing a given percentile. + The score of the observation under a model is plotted as a marker. The model is assumed + inconsistent when the observation score lies outside the model distribution for a + two-sided test, or lies to the right of the distribution for a one-sided test. Args: - forecast (GriddedForecast): The forecast object. - catalog (CSEPCatalog): The evaluation catalog. - linear (bool): If True, a linear x-axis is used; if False, a logarithmic x-axis is used. - plot_uniform (bool): If True, include a uniform forecast on the plot. - show (bool): If True, displays the plot. - ax (Optional[pyplot.Axes]): Axes object to plot on (default: None). - **kwargs: Additional keyword arguments for customization. + eval_results (list of EvaluationResult or EvaluationResult): Evaluation results from one + or multiple models. + normalize (bool): Normalize the forecast likelihood by observed likelihood. Defaults + to `False`. + one_sided_lower (bool): Plot for a one-sided test. Defaults to `False`. + percentile (float): Percentile for the extent of the model score distribution. Defaults + to `95`. + ax (matplotlib.axes.Axes): Axes object to plot on. If `None`, creates a new figure. + Defaults to `None`. + plot_mean (bool): Plot the mean of the test distribution. Defaults to `False`. + color (str): Color for the line representing a model score distribution. Defaults to + `'black'`. + show (bool): If `True`, displays the plot. Defaults to `False`. + **kwargs: Additional keyword arguments for plot customization: + + - **figsize** (`tuple`): The size of the figure. + - **capsize** (`float`): Size of the caps on the error bars. + - **linewidth** (`float`): Width of the error bars and lines. + - **xlabel** (`str`): Label for the X-axis. + - **xlabel_fontsize** (`int`): Font size for the X-axis label. + - **ylabel_fontsize** (`int`): Font size for the Y-axis labels. + - **xticks_fontsize** (`int`): Font size for the X-axis ticks. + - **title** (`str`): Title of the plot. + - **title_fontsize** (`int`): Font size of the plot title. + - **hbars** (`bool`): Whether to include horizontal bars for visual separation. + - **tight_layout** (`bool`): Whether to use tight layout for the figure. + Defaults to `True`. Returns: - matplotlib.axes.Axes: The Axes object with the plot. - - Raises: - RuntimeError: If the catalog and forecast do not have the same region. + matplotlib.axes.Axes: Matplotlib axes object with the consistency test plot. """ + # Initialize plot plot_args = {**DEFAULT_PLOT_ARGS, **kwargs} fig, ax = pyplot.subplots(figsize=plot_args["figsize"]) if ax is None else (ax.figure, ax) - if not catalog.region == forecast.region: - raise RuntimeError("Catalog region and forecast region must be identical.") - - forecast_label = plot_args.get("forecast_label", forecast.name or "Forecast") - - # Obtain forecast rates (or counts) and observed catalog aggregated in spatial cells - rate = forecast.spatial_counts() - obs_counts = catalog.spatial_counts() - - # Get index of rates (descending sort) - indices = numpy.argsort(rate) - indices = numpy.flip(indices) - - # Order forecast and cells rates by highest rate cells first - thresholds = (rate[indices]) / numpy.sum(rate) - obs_counts = obs_counts[indices] - - Table_molchan = pandas.DataFrame( - { - "Threshold": [], - "Successful_bins": [], - "Obs_active_bins": [], - "tau": [], - "nu": [], - "R_score": [], - } - ) - - # Each forecasted and normalized rate is tested as a threshold value to define the - # contingency table. - for threshold in thresholds: - threshold = float(threshold) + # Ensure eval_results is a list + results = list(eval_results) if isinstance(eval_results, list) else [eval_results] + results.reverse() - binary_forecast = numpy.where(thresholds >= threshold, 1, 0) - forecastedYes_observedYes = obs_counts[(binary_forecast == 1) & (obs_counts > 0)] - forecastedYes_observedNo = obs_counts[(binary_forecast == 1) & (obs_counts == 0)] - forecastedNo_observedYes = obs_counts[(binary_forecast == 0) & (obs_counts > 0)] - forecastedNo_observedNo = obs_counts[(binary_forecast == 0) & (obs_counts == 0)] + xlims = [] - # Creating the DataFrame for the contingency table - data = { - "Observed": [len(forecastedYes_observedYes), len(forecastedNo_observedYes)], - "Not Observed": [len(forecastedYes_observedNo), len(forecastedNo_observedNo)], - } - index = ["Forecasted", "Not Forecasted"] - contingency_df = pandas.DataFrame(data, index=index) - nu = contingency_df.loc["Not Forecasted", "Observed"] / contingency_df["Observed"].sum() - tau = contingency_df.loc["Forecasted"].sum() / ( - contingency_df.loc["Forecasted"].sum() + contingency_df.loc["Not Forecasted"].sum() - ) - R_score = ( - contingency_df.loc["Forecasted", "Observed"] / contingency_df["Observed"].sum() - ) - ( - contingency_df.loc["Forecasted", "Not Observed"] - / contingency_df["Not Observed"].sum() + for index, res in enumerate(results): + plow, phigh, mean, observed_statistic = _process_stat_distribution( + res, percentile, normalize, one_sided_lower ) - threshold_row = { - "Threshold": threshold, - "Successful_bins": contingency_df.loc["Forecasted", "Observed"], - "Obs_active_bins": contingency_df["Observed"].sum(), - "tau": tau, - "nu": nu, - "R_score": R_score, - } - threshold_row_df = pandas.DataFrame([threshold_row]) - - Table_molchan = pandas.concat([Table_molchan, threshold_row_df], ignore_index=True) - - bottom_row = { - "Threshold": "Full alarms", - "tau": 1, - "nu": 0, - "Obs_active_bins": contingency_df["Observed"].sum(), - } - top_row = { - "Threshold": "No alarms", - "tau": 0, - "nu": 1, - "Obs_active_bins": contingency_df["Observed"].sum(), - } - - Table_molchan = pandas.concat( - [pandas.DataFrame([top_row]), Table_molchan], ignore_index=True - ) - Table_molchan = pandas.concat( - [Table_molchan, pandas.DataFrame([bottom_row])], ignore_index=True - ) - - # Computation of Area Skill score (ASS) - Tab_as_score = pandas.DataFrame() - Tab_as_score["Threshold"] = Table_molchan["Threshold"] - Tab_as_score["tau"] = Table_molchan["tau"] - Tab_as_score["nu"] = Table_molchan["nu"] - - ONE = numpy.ones(len(Tab_as_score)) - Tab_as_score["CUM_BAND"] = cumulative_trapezoid( - ONE, Tab_as_score["tau"], initial=0 - ) - cumulative_trapezoid(Tab_as_score["nu"], Tab_as_score["tau"], initial=0) - Tab_as_score["AS_score"] = numpy.divide( - Tab_as_score["CUM_BAND"], - cumulative_trapezoid(ONE, Tab_as_score["tau"], initial=0) + 1e-10, - ) - Tab_as_score.loc[Tab_as_score.index[-1], "AS_score"] = max( - 0.5, Tab_as_score["AS_score"].iloc[-1] - ) - ASscore = numpy.round(Tab_as_score.loc[Tab_as_score.index[-1], "AS_score"], 2) - - bin_size = 0.01 - devstd = numpy.sqrt(1 / (12 * Table_molchan["Obs_active_bins"].iloc[0])) - devstd = devstd * bin_size**-1 - devstd = numpy.ceil(devstd + 0.5) - devstd = devstd / bin_size**-1 - dev_std = numpy.round(devstd, 2) - - # Plot the Molchan trajectory - ax.plot( - Table_molchan["tau"], - Table_molchan["nu"], - label=f"{forecast_label}, ASS={ASscore}±{dev_std} ", - color=plot_args["color"], - linestyle=plot_args["linestyle"], - ) + if not numpy.isinf(observed_statistic): # Check if test result does not diverge + percentile_lims = numpy.abs(numpy.array([[mean - plow, phigh - mean]]).T) + ax.plot( + observed_statistic, + index, + _get_marker_style(observed_statistic, (plow, phigh), one_sided_lower), + ) + ax.errorbar( + mean, + index, + xerr=percentile_lims, + fmt="ko" if plot_mean else "k", + capsize=plot_args["capsize"], + linewidth=plot_args["linewidth"], + ecolor=color, + ) + # Determine the limits to use + xlims.append((plow, phigh, observed_statistic)) - # Plot uniform forecast - if plot_uniform: - x_uniform = numpy.arange(0, 1.001, 0.001) - y_uniform = numpy.arange(1.00, -0.001, -0.001) - ax.plot(x_uniform, y_uniform, linestyle="--", color="gray", label="Uniform") + # Extend distribution to +inf, in case it is a one-sided test + if one_sided_lower and observed_statistic >= plow and phigh < observed_statistic: + xt = numpy.linspace(phigh, 99999, 100) + yt = numpy.ones(100) * index + ax.plot(xt, yt, linestyle="--", linewidth=plot_args["linewidth"], color=color) + else: + print( + f"Observed statistic diverges for forecast {res.sim_name}, index {index}. " + f"Check for zero-valued bins within the forecast" + ) + ax.barh(index, 99999, left=-10000, height=1, color=["red"], alpha=0.5) # Plot formatting - ax.set_ylabel(plot_args["ylabel"] or "Miss Rate", fontsize=plot_args["ylabel_fontsize"]) + try: + ax.set_xlim(*_get_axis_limits(xlims)) + except ValueError: + raise ValueError("All EvaluationResults have infinite observed_statistics") + ax.set_ylim([-0.5, len(results) - 0.5]) + ax.set_yticks(numpy.arange(len(results))) + ax.set_yticklabels([res.sim_name for res in results], fontsize=plot_args["ylabel_fontsize"]) ax.set_xlabel( - plot_args["xlabel"] or "Fraction of area occupied by alarms", - fontsize=plot_args["xlabel_fontsize"], + plot_args["xlabel"] or "Statistic distribution", fontsize=plot_args["xlabel_fontsize"] ) - if not linear: - ax.set_xscale("log") - ax.tick_params(axis="x", labelsize=plot_args["xlabel_fontsize"]) - ax.tick_params(axis="y", labelsize=plot_args["ylabel_fontsize"]) - ax.legend(loc=plot_args["legend_loc"], shadow=True, fontsize=plot_args["legend_fontsize"]) - ax.set_title(plot_args["title"] or "Molchan Diagram", fontsize=plot_args["title_fontsize"]) - + ax.tick_params(axis="x", labelsize=plot_args["xticks_fontsize"]) + ax.set_title(plot_args["title"], fontsize=plot_args["title_fontsize"]) + if plot_args["hbars"]: + yTickPos = ax.get_yticks() + if len(yTickPos) >= 2: + ax.barh( + yTickPos, + numpy.array([99999] * len(yTickPos)), + left=-10000, + height=(yTickPos[1] - yTickPos[0]), + color=["w", "gray"], + alpha=0.2, + zorder=0, + ) if plot_args["tight_layout"]: fig.tight_layout() + if show: pyplot.show() + return ax -############### -# Spatial plots -############### -def plot_basemap( - basemap: Optional[str] = None, - extent: Optional[List[float]] = None, - coastline: bool = True, - borders: bool = False, - tile_depth: Union[str, int] = "auto", - set_global: bool = False, - projection: ccrs.Projection = ccrs.PlateCarree(), +################### +# Alarm-based plots +################### +def plot_concentration_ROC_diagram( + forecast: "GriddedForecast", + catalog: "CSEPCatalog", + linear: bool = True, + plot_uniform: bool = True, + show: bool = True, ax: Optional[pyplot.Axes] = None, - show: bool = False, **kwargs, ) -> matplotlib.axes.Axes: """ - Wrapper function for multiple Cartopy base plots, including access to standard raster - webservices. + Plots the Concentration ROC Diagram for a given forecast and observed catalog. Args: - basemap (str): Possible values are: 'stock_img', 'google-satellite', 'ESRI_terrain', - 'ESRI_imagery', 'ESRI_relief', 'ESRI_topo', a custom webservice link, - or a GeoTiff filepath. Default is None. - extent (list): [lon_min, lon_max, lat_min, lat_max] - ax (matplotlib.Axes): Previously defined ax object. - coastline (bool): Flag to plot coastline. Default True. - borders (bool): Flag to plot country borders. Default False. - tile_depth (str/int): Zoom level (1-12) of the basemap tiles. If 'auto', it is - automatically derived from extent. - set_global (bool): Display the complete globe as basemap. - projection (cartopy.crs.Projection): Projection to be used in the basemap. - show (bool): If True, displays the plot. + forecast (GriddedForecast): Forecast object containing spatial forecast data. + catalog (CSEPCatalog): Catalog object containing observed data. + linear (bool): If True, uses a linear scale for the X-axis, otherwise logarithmic. + Defaults to `True`. + plot_uniform (bool): If True, plots the uniform (random) model as a reference. + Defaults to `True`. + show (bool): If True, displays the plot. Defaults to `True`. + ax (matplotlib.axes.Axes): Axes object to plot on. If `None`, creates a new figure. + Defaults to `None`. + **kwargs: Additional keyword arguments for customization: + + - **figsize** (`tuple`): The size of the figure. + - **forecast_label** (`str`): Label for the forecast data in the plot. + - **observation_label** (`str`): Label for the observation data in the plot. + - **color** (`str`): Color for the observed data line. + - **secondary_color** (`str`): Color for the forecast data line. + - **linestyle** (`str`): Line style for the observed data line. + - **title** (`str`): Title of the plot. + - **title_fontsize** (`int`): Font size of the plot title. + - **xlabel** (`str`): Label for the X-axis. + - **xlabel_fontsize** (`int`): Font size for the X-axis label. + - **ylabel** (`str`): Label for the Y-axis. + - **ylabel_fontsize** (`int`): Font size for the Y-axis label. + - **grid** (`bool`): Whether to show grid lines. Defaults to `True`. + - **legend** (`bool`): Whether to display a legend. Defaults to `True`. + - **legend_loc** (`str`): Location of the legend. Defaults to `'best'`. + - **legend_fontsize** (`int`): Font size of the legend text. + - **legend_framealpha** (`float`): Transparency level for the legend frame. + - **tight_layout** (`bool`): Whether to use tight layout for the figure. + Defaults to `True`. Returns: - matplotlib.Axes: Matplotlib Axes object. + matplotlib.axes.Axes: The Axes object with the plot. """ + # Initialize plot plot_args = {**DEFAULT_PLOT_ARGS, **kwargs} - ax = ax or _create_geo_axes(plot_args["figsize"], extent, projection, set_global) + fig, ax = pyplot.subplots(figsize=plot_args["figsize"]) if ax is None else (ax.figure, ax) - line_autoscaler = cartopy.feature.AdaptiveScaler("110m", (("50m", 50), ("10m", 5))) - tile_autoscaler = cartopy.feature.AdaptiveScaler(5, ((6, 50), (7, 15))) - tile_depth = ( - 4 - if set_global - else (tile_autoscaler.scale_from_extent(extent) if tile_depth == "auto" else tile_depth) - ) - # Add coastlines and borders - if coastline: - ax.coastlines( - color=plot_args["coastline_color"], linewidth=plot_args["coastline_linewidth"] - ) - if borders: - borders = cartopy.feature.NaturalEarthFeature( - "cultural", - "admin_0_boundary_lines_land", - line_autoscaler, - edgecolor=plot_args["borders_color"], - facecolor="never", - ) - ax.add_feature(borders, linewidth=plot_args["borders_linewidth"]) + if not catalog.region == forecast.region: + raise AttributeError("catalog region and forecast region must be identical.") - # Add basemap tiles - try: - if basemap == "stock_img": - ax.stock_img() - elif basemap is not None: - basemap_obj = _get_basemap(basemap) - # basemap_obj is a cartopy TILE IMAGE - if isinstance(basemap_obj, GoogleWTS): - ax.add_image(basemap_obj, tile_depth) - # basemap_obj is a rasterio image - elif isinstance(basemap_obj, DatasetReader): - ax = rio_plot.show(basemap_obj, ax=ax) + # Getting data + forecast_label = plot_args.get("forecast_label", forecast.name or "Forecast") + observed_label = plot_args.get("observation_label", "Observations") - except Exception as e: - print( - f"Unable to plot basemap. This might be due to no internet access. " - f"Error: {str(e)}" - ) + area_km2 = catalog.region.get_cell_area() + obs_counts = catalog.spatial_counts() + rate = forecast.spatial_counts() - # Set up Grid-lines - if plot_args["grid"]: - _add_gridlines(ax, plot_args["grid_labels"], plot_args["grid_fontsize"]) + indices = numpy.argsort(rate) + indices = numpy.flip(indices) + + fore_norm_sorted = numpy.cumsum(rate[indices]) / numpy.sum(rate) + area_norm_sorted = numpy.cumsum(area_km2[indices]) / numpy.sum(area_km2) + obs_norm_sorted = numpy.cumsum(obs_counts[indices]) / numpy.sum(obs_counts) + + # Plot data + if plot_uniform: + ax.plot(area_norm_sorted, area_norm_sorted, "k--", label="Uniform") + + ax.plot( + area_norm_sorted, + fore_norm_sorted, + label=forecast_label, + color=plot_args["secondary_color"], + ) + + ax.step( + area_norm_sorted, + obs_norm_sorted, + label=observed_label, + color=plot_args["color"], + linestyle=plot_args["linestyle"], + ) + # Plot formatting + ax.set_title(plot_args["title"], fontsize=plot_args["title_fontsize"]) + ax.grid(plot_args["grid"]) + if not linear: + ax.set_xscale("log") + ax.set_ylabel( + plot_args["ylabel"] or "True Positive Rate", fontsize=plot_args["ylabel_fontsize"] + ) + ax.set_xlabel( + plot_args["xlabel"] or "False Positive Rate (Normalized Area)", + fontsize=plot_args["xlabel_fontsize"], + ) + if plot_args["legend"]: + ax.legend( + loc=plot_args["legend_loc"], + shadow=True, + fontsize=plot_args["legend_fontsize"], + framealpha=plot_args["legend_framealpha"], + ) + if plot_args["tight_layout"]: + fig.tight_layout() if show: pyplot.show() return ax -def plot_catalog( +def plot_ROC_diagram( + forecast: "GriddedForecast", catalog: "CSEPCatalog", - basemap: Optional[str] = None, - ax: Optional[matplotlib.axes.Axes] = None, - projection: Optional[Union[ccrs.Projection, str]] = ccrs.PlateCarree(), - show: bool = False, - extent: Optional[Sequence[float]] = None, - set_global: bool = False, - mag_ticks: Optional[Union[Sequence[float], np.ndarray, int]] = None, - size: float = 15, - max_size: float = 300, - power: float = 3, - min_val: Optional[float] = None, - max_val: Optional[float] = None, - plot_region: bool = False, + linear: bool = True, + plot_uniform: bool = True, + show: bool = True, + ax: Optional[pyplot.Axes] = None, **kwargs, -) -> matplotlib.axes.Axes: - """Plot catalog in a region. +) -> matplotlib.pyplot.Axes: + """ + Plots the ROC (Receiver Operating Characteristic) curve for a given forecast and observed + catalog. Args: - catalog (:class:`CSEPCatalog`): Catalog object to be plotted. - basemap (str): Optional. Passed to :func:`plot_basemap` along with `kwargs` - ax (:class:`matplotlib.pyplot.ax`): Previously defined ax object. - show (bool): Flag if the figure is displayed. - extent (list): Default 1.05 * :func:`catalog.region.get_bbox()`. - projection (cartopy.crs.Projection): Projection to be used in the underlying basemap - set_global (bool): Display the complete globe as basemap. - size (float): Size of the event with the minimum magnitude - max_size (float): Size of the catalog's maximum magnitude - power (float, list): Power scaling of the scatter sizing. - min_val (float): Override minimum magnitude of the catalog for scatter sizing - max_val (float): Override maximum magnitude of the catalog for scatter sizing - mag_ticks (list, int): Ticks to display in the legend. - plot_region (bool): Flag to plot the catalog region border. - kwargs: alpha, markercolor, markeredgecolor, figsize, legend, - legend_title, legend_labelspacing, legend_borderpad, legend_framealpha + forecast (GriddedForecast): Forecast object containing spatial forecast data. + catalog (CSEPCatalog): Catalog object containing observed data. + linear (bool): If True, uses a linear scale for the X-axis, otherwise logarithmic. + Defaults to `True`. + plot_uniform (bool): If True, plots the uniform (random) model as a reference. + Defaults to `True`. + show (bool): If True, displays the plot. Defaults to `True`. + ax (matplotlib.axes.Axes): Axes object to plot on. If `None`, creates a new figure. + Defaults to `None`. + **kwargs: Additional keyword arguments for customization: + + - **figsize** (`tuple`): The size of the figure. + - **forecast_label** (`str`): Label for the forecast data in the plot. + - **color** (`str`): Color for the ROC curve line. + - **linestyle** (`str`): Line style for the ROC curve. + - **xlabel** (`str`): Label for the X-axis. + - **xlabel_fontsize** (`int`): Font size for the X-axis label. + - **ylabel** (`str`): Label for the Y-axis. + - **ylabel_fontsize** (`int`): Font size for the Y-axis label. + - **xticks_fontsize** (`int`): Font size for the X-axis ticks. + - **yticks_fontsize** (`int`): Font size for the Y-axis ticks. + - **legend** (`bool`): Whether to display a legend. Defaults to `True`. + - **legend_loc** (`str`): Location of the legend. Defaults to `'best'`. + - **legend_fontsize** (`int`): Font size of the legend text. + - **tight_layout** (`bool`): Whether to use tight layout for the figure. + Defaults to `True`. Returns: - :class:`matplotlib.pyplot.ax` object + matplotlib.pyplot.Axes: The Axes object with the plot. """ + # Initialize plot plot_args = {**DEFAULT_PLOT_ARGS, **kwargs} - # Get spatial information for plotting - extent = extent or _calculate_spatial_extent(catalog, set_global, plot_region) - # Instantiate GeoAxes object - ax = ax or _create_geo_axes(plot_args["figsize"], extent, projection, set_global) - # chain basemap - ax = plot_basemap(basemap, extent, ax=ax, set_global=set_global, show=False, **plot_args) + fig, ax = pyplot.subplots(figsize=plot_args["figsize"]) if ax is None else (ax.figure, ax) - # Plot catalog - ax.scatter( - catalog.get_longitudes(), - catalog.get_latitudes(), - s=_autosize_scatter( - values=catalog.get_magnitudes(), - min_size=size, - max_size=max_size, - power=power, - min_val=min_val, - max_val=max_val, - ), - transform=ccrs.PlateCarree(), - color=plot_args["markercolor"], - edgecolors=plot_args["markeredgecolor"], - alpha=plot_args["alpha"], - ) + if not catalog.region == forecast.region: + raise RuntimeError("catalog region and forecast region must be identical.") - # Legend - if plot_args["legend"]: - if isinstance(mag_ticks, (list, np.ndarray)): - mag_ticks = np.array(mag_ticks) - else: - mw_range = [min(catalog.get_magnitudes()), max(catalog.get_magnitudes())] - mag_ticks = np.linspace(mw_range[0], mw_range[1], mag_ticks or 4, endpoint=True) + rate = forecast.spatial_counts() + obs_counts = catalog.spatial_counts() - # Map mag_ticks to marker sizes using the custom size mapping function - legend_sizes = _autosize_scatter( - values=mag_ticks, - min_size=size, - max_size=max_size, - power=power, - min_val=min_val or np.min(catalog.get_magnitudes()), - max_val=max_val or np.max(catalog.get_magnitudes()), - ) + indices = numpy.argsort(rate)[::-1] # Sort in descending order - # Create custom legend handles - handles = [ - pyplot.Line2D( - [0], - [0], - marker="o", - lw=0, - label=str(m), - markersize=np.sqrt(s), - markerfacecolor="gray", - alpha=0.5, - markeredgewidth=0.8, - markeredgecolor="black", - ) - for m, s in zip(mag_ticks, legend_sizes) - ] + thresholds = (rate[indices]) / numpy.sum(rate) + obs_counts = obs_counts[indices] - ax.legend( - handles, - np.round(mag_ticks, 1), - loc=plot_args["legend_loc"], - handletextpad=5, - title=plot_args.get("legend_title") or "Magnitudes", - fontsize=plot_args["legend_fontsize"], - title_fontsize=plot_args["legend_titlesize"], - labelspacing=plot_args["legend_labelspacing"], - borderpad=plot_args["legend_borderpad"], - framealpha=plot_args["legend_framealpha"], + Table_ROC = pandas.DataFrame({"Threshold": [], "H": [], "F": []}) + + for threshold in thresholds: + threshold = float(threshold) + binary_forecast = numpy.where(thresholds >= threshold, 1, 0) + forecastedYes_observedYes = obs_counts[(binary_forecast == 1) & (obs_counts > 0)] + forecastedYes_observedNo = obs_counts[(binary_forecast == 1) & (obs_counts == 0)] + forecastedNo_observedYes = obs_counts[(binary_forecast == 0) & (obs_counts > 0)] + forecastedNo_observedNo = obs_counts[(binary_forecast == 0) & (obs_counts == 0)] + + H = len(forecastedYes_observedYes) / ( + len(forecastedYes_observedYes) + len(forecastedNo_observedYes) + ) + F = len(forecastedYes_observedNo) / ( + len(forecastedYes_observedNo) + len(forecastedNo_observedNo) ) - # Draw catalog's region border - if plot_region: - try: - pts = catalog.region.tight_bbox() - ax.plot(pts[:, 0], pts[:, 1], lw=1, color=plot_args["region_color"]) - except AttributeError: - pass + threshold_row = {"Threshold": threshold, "H": H, "F": F} + Table_ROC = pandas.concat( + [Table_ROC, pandas.DataFrame([threshold_row])], ignore_index=True + ) + + Table_ROC = pandas.concat( + [pandas.DataFrame({"H": [0], "F": [0]}), Table_ROC], ignore_index=True + ) + + ax.plot( + Table_ROC["F"], + Table_ROC["H"], + label=plot_args.get("forecast_label", forecast.name or "Forecast"), + color=plot_args["color"], + linestyle=plot_args["linestyle"], + ) - ax.set_title(plot_args["title"], fontsize=plot_args["title_fontsize"], y=1.06) + if plot_uniform: + ax.plot( + numpy.arange(0, 1.001, 0.001), + numpy.arange(0, 1.001, 0.001), + linestyle="--", + color="gray", + label="Uniform", + ) + # Plot formatting + ax.set_ylabel(plot_args["ylabel"] or "Hit Rate", fontsize=plot_args["ylabel_fontsize"]) + ax.set_xlabel( + plot_args["xlabel"] or "Fraction of False Alarms", fontsize=plot_args["xlabel_fontsize"] + ) + if not linear: + ax.set_xscale("log") + ax.set_yscale("linear") + ax.tick_params(axis="x", labelsize=plot_args["xticks_fontsize"]) + ax.tick_params(axis="y", labelsize=plot_args["yticks_fontsize"]) + if plot_args["legend"]: + ax.legend( + loc=plot_args["legend_loc"], shadow=True, fontsize=plot_args["legend_fontsize"] + ) + ax.set_title(plot_args["title"], fontsize=plot_args["title_fontsize"]) if plot_args["tight_layout"]: - ax.figure.tight_layout() + fig.tight_layout() if show: pyplot.show() @@ -1564,98 +1657,221 @@ def plot_catalog( return ax -def plot_spatial_dataset( - gridded: numpy.ndarray, - region: "CartesianGrid2D", - basemap: Optional[str] = None, +def plot_Molchan_diagram( + forecast: "GriddedForecast", + catalog: "CSEPCatalog", + linear: bool = True, + plot_uniform: bool = True, + show: bool = True, ax: Optional[pyplot.Axes] = None, - projection: Optional[Union[ccrs.Projection, str]] = ccrs.PlateCarree(), - show: bool = False, - extent: Optional[List[float]] = None, - set_global: bool = False, - plot_region: bool = True, - colorbar: bool = True, - colormap: Union[str, matplotlib.colors.Colormap] = "viridis", - clim: Optional[Tuple[float, float]] = None, - clabel: Optional[str] = None, - alpha: Optional[float] = None, - alpha_exp: float = 0, **kwargs, ) -> matplotlib.axes.Axes: + """ - Plot spatial dataset such as data from a gridded forecast. + Plot the Molchan Diagram based on forecast and test catalogs using the contingency table. + The Area Skill score and its error are shown in the legend. + + The Molchan diagram is computed following this procedure: + + 1. Obtain spatial rates from the GriddedForecast and the observed events from the catalog. + 2. Rank the rates in descending order (highest rates first). + 3. Sort forecasted rates by ordering found in (2), and normalize rates so their sum is equal + to unity. + 4. Obtain binned spatial rates from the observed catalog. + 5. Sort gridded observed rates by ordering found in (2). + 6. Test each ordered and normalized forecasted rate defined in (3) as a threshold value to + obtain the corresponding contingency table. + 7. Define the "nu" (Miss rate) and "tau" (Fraction of spatial alarmed cells) for each + threshold using the information provided by the corresponding contingency table defined in + (6). + + Note: + 1. The testing catalog and forecast should have exactly the same time-window (duration). + 2. Forecasts should be defined over the same region. + 3. If calling this function multiple times, update the color in the arguments. + 4. The user can choose the x-scale (linear or log). Args: - gridded (numpy.ndarray): 2D array of values corresponding to the region. - region (CartesianGrid2D): Region in which gridded values are contained. - basemap (str): Optional. Passed to :func:`plot_basemap` along with `kwargs` - ax (Optional[pyplot.Axes]): Previously defined ax object. - projection (cartopy.crs.Projection): Projection to be used in the basemap. - show (bool): If True, displays the plot. - extent (Optional[List[float]]): [lon_min, lon_max, lat_min, lat_max]. - set_global (bool): Display the complete globe as basemap. - plot_region (bool): If True, plot the dataset region border. - colorbar (bool): If True, include a colorbar. - colormap (Union[str, matplotlib.colors.Colormap]): Colormap to use. - clim (Optional[Tuple[float, float]]): Range of the colorbar. - clabel (Optional[str]): Label of the colorbar. - alpha (Optional[float]): Transparency level. - alpha_exp (float): Exponent for the alpha function (recommended between 0.4 and 1). - kwargs: colorbar_labelsize, colorbar_ticksize + forecast (GriddedForecast): The forecast object. + catalog (CSEPCatalog): The evaluation catalog. + linear (bool): If True, a linear x-axis is used; if False, a logarithmic x-axis is used. + Defaults to `True`. + plot_uniform (bool): If True, include a uniform forecast on the plot. Defaults to `True`. + show (bool): If True, displays the plot. Defaults to `True`. + ax (matplotlib.axes.Axes): Axes object to plot on. If `None`, creates a new figure. + Defaults to `None`. + **kwargs: Additional keyword arguments for customization: + + - **figsize** (`tuple`): The size of the figure. + - **forecast_label** (`str`): Label for the forecast data in the plot. + - **color** (`str`): Color for the Molchan diagram line. + - **linestyle** (`str`): Line style for the Molchan diagram line. + - **xlabel** (`str`): Label for the X-axis. + - **xlabel_fontsize** (`int`): Font size for the X-axis label. + - **ylabel** (`str`): Label for the Y-axis. + - **ylabel_fontsize** (`int`): Font size for the Y-axis label. + - **legend_loc** (`str`): Location of the legend. Defaults to `'best'`. + - **legend_fontsize** (`int`): Font size of the legend text. + - **tight_layout** (`bool`): Whether to use tight layout for the figure. + Defaults to `True`. + Returns: - matplotlib.axes.Axes: Matplotlib axes handle. + matplotlib.axes.Axes: The Axes object with the plot. + + Raises: + RuntimeError: If the catalog and forecast do not have the same region. """ plot_args = {**DEFAULT_PLOT_ARGS, **kwargs} + fig, ax = pyplot.subplots(figsize=plot_args["figsize"]) if ax is None else (ax.figure, ax) - # Get spatial information for plotting - extent = extent or _calculate_spatial_extent(region, set_global, plot_region) - # Instantiate GeoAxes object - ax = ax or _create_geo_axes(plot_args["figsize"], extent, projection, set_global) + if not catalog.region == forecast.region: + raise RuntimeError("Catalog region and forecast region must be identical.") - # chain basemap - ax = plot_basemap(basemap, extent, ax=ax, set_global=set_global, show=False, **plot_args) + forecast_label = plot_args.get("forecast_label", forecast.name or "Forecast") - # Define colormap and alpha transparency - colormap, alpha = _get_colormap(colormap, alpha_exp, alpha) + # Obtain forecast rates (or counts) and observed catalog aggregated in spatial cells + rate = forecast.spatial_counts() + obs_counts = catalog.spatial_counts() - # Plot spatial dataset - lons, lats = numpy.meshgrid( - numpy.append(region.xs, region.get_bbox()[1]), - numpy.append(region.ys, region.get_bbox()[3]), - ) - im = ax.pcolor( - lons, lats, gridded, cmap=colormap, alpha=alpha, snap=True, transform=ccrs.PlateCarree() + # Get index of rates (descending sort) + indices = numpy.argsort(rate) + indices = numpy.flip(indices) + + # Order forecast and cells rates by highest rate cells first + thresholds = (rate[indices]) / numpy.sum(rate) + obs_counts = obs_counts[indices] + + Table_molchan = pandas.DataFrame( + { + "Threshold": [], + "Successful_bins": [], + "Obs_active_bins": [], + "tau": [], + "nu": [], + "R_score": [], + } ) - im.set_clim(clim) - # Colorbar options - if colorbar: - cax = ax.get_figure().add_axes( - [ - ax.get_position().x1 + 0.01, - ax.get_position().y0, - 0.025, - ax.get_position().height, - ], - label="Colorbar", + # Each forecasted and normalized rate is tested as a threshold value to define the + # contingency table. + for threshold in thresholds: + threshold = float(threshold) + + binary_forecast = numpy.where(thresholds >= threshold, 1, 0) + forecastedYes_observedYes = obs_counts[(binary_forecast == 1) & (obs_counts > 0)] + forecastedYes_observedNo = obs_counts[(binary_forecast == 1) & (obs_counts == 0)] + forecastedNo_observedYes = obs_counts[(binary_forecast == 0) & (obs_counts > 0)] + forecastedNo_observedNo = obs_counts[(binary_forecast == 0) & (obs_counts == 0)] + + # Creating the DataFrame for the contingency table + data = { + "Observed": [len(forecastedYes_observedYes), len(forecastedNo_observedYes)], + "Not Observed": [len(forecastedYes_observedNo), len(forecastedNo_observedNo)], + } + index = ["Forecasted", "Not Forecasted"] + contingency_df = pandas.DataFrame(data, index=index) + nu = contingency_df.loc["Not Forecasted", "Observed"] / contingency_df["Observed"].sum() + tau = contingency_df.loc["Forecasted"].sum() / ( + contingency_df.loc["Forecasted"].sum() + contingency_df.loc["Not Forecasted"].sum() + ) + R_score = ( + contingency_df.loc["Forecasted", "Observed"] / contingency_df["Observed"].sum() + ) - ( + contingency_df.loc["Forecasted", "Not Observed"] + / contingency_df["Not Observed"].sum() ) - cbar = ax.get_figure().colorbar(im, ax=ax, cax=cax) - cbar.set_label(clabel, fontsize=plot_args["colorbar_labelsize"]) - cbar.ax.tick_params(labelsize=plot_args["colorbar_ticksize"]) - # Draw forecast's region border - if plot_region and not set_global: - try: - pts = region.tight_bbox() - ax.plot(pts[:, 0], pts[:, 1], lw=1, color=plot_args["region_color"]) - except AttributeError: - pass - ax.set_title(plot_args["title"], fontsize=plot_args["title_fontsize"], y=1.06) + threshold_row = { + "Threshold": threshold, + "Successful_bins": contingency_df.loc["Forecasted", "Observed"], + "Obs_active_bins": contingency_df["Observed"].sum(), + "tau": tau, + "nu": nu, + "R_score": R_score, + } + threshold_row_df = pandas.DataFrame([threshold_row]) + + Table_molchan = pandas.concat([Table_molchan, threshold_row_df], ignore_index=True) + + bottom_row = { + "Threshold": "Full alarms", + "tau": 1, + "nu": 0, + "Obs_active_bins": contingency_df["Observed"].sum(), + } + top_row = { + "Threshold": "No alarms", + "tau": 0, + "nu": 1, + "Obs_active_bins": contingency_df["Observed"].sum(), + } + + Table_molchan = pandas.concat( + [pandas.DataFrame([top_row]), Table_molchan], ignore_index=True + ) + Table_molchan = pandas.concat( + [Table_molchan, pandas.DataFrame([bottom_row])], ignore_index=True + ) + + # Computation of Area Skill score (ASS) + Tab_as_score = pandas.DataFrame() + Tab_as_score["Threshold"] = Table_molchan["Threshold"] + Tab_as_score["tau"] = Table_molchan["tau"] + Tab_as_score["nu"] = Table_molchan["nu"] + + ONE = numpy.ones(len(Tab_as_score)) + Tab_as_score["CUM_BAND"] = cumulative_trapezoid( + ONE, Tab_as_score["tau"], initial=0 + ) - cumulative_trapezoid(Tab_as_score["nu"], Tab_as_score["tau"], initial=0) + Tab_as_score["AS_score"] = numpy.divide( + Tab_as_score["CUM_BAND"], + cumulative_trapezoid(ONE, Tab_as_score["tau"], initial=0) + 1e-10, + ) + Tab_as_score.loc[Tab_as_score.index[-1], "AS_score"] = max( + 0.5, Tab_as_score["AS_score"].iloc[-1] + ) + ASscore = numpy.round(Tab_as_score.loc[Tab_as_score.index[-1], "AS_score"], 2) + + bin_size = 0.01 + devstd = numpy.sqrt(1 / (12 * Table_molchan["Obs_active_bins"].iloc[0])) + devstd = devstd * bin_size**-1 + devstd = numpy.ceil(devstd + 0.5) + devstd = devstd / bin_size**-1 + dev_std = numpy.round(devstd, 2) + + # Plot the Molchan trajectory + ax.plot( + Table_molchan["tau"], + Table_molchan["nu"], + label=f"{forecast_label}, ASS={ASscore}±{dev_std} ", + color=plot_args["color"], + linestyle=plot_args["linestyle"], + ) + + # Plot uniform forecast + if plot_uniform: + x_uniform = numpy.arange(0, 1.001, 0.001) + y_uniform = numpy.arange(1.00, -0.001, -0.001) + ax.plot(x_uniform, y_uniform, linestyle="--", color="gray", label="Uniform") + + # Plot formatting + ax.set_ylabel(plot_args["ylabel"] or "Miss Rate", fontsize=plot_args["ylabel_fontsize"]) + ax.set_xlabel( + plot_args["xlabel"] or "Fraction of area occupied by alarms", + fontsize=plot_args["xlabel_fontsize"], + ) + if not linear: + ax.set_xscale("log") + ax.tick_params(axis="x", labelsize=plot_args["xlabel_fontsize"]) + ax.tick_params(axis="y", labelsize=plot_args["ylabel_fontsize"]) + ax.legend(loc=plot_args["legend_loc"], shadow=True, fontsize=plot_args["legend_fontsize"]) + ax.set_title(plot_args["title"] or "Molchan Diagram", fontsize=plot_args["title_fontsize"]) + if plot_args["tight_layout"]: + fig.tight_layout() if show: pyplot.show() - return ax @@ -1862,8 +2078,8 @@ def _autosize_scatter( Returns: numpy.ndarray: The calculated marker sizes. """ - min_val = min_val or np.min(values) - max_val = max_val or np.max(values) + min_val = min_val or numpy.min(values) + max_val = max_val or numpy.max(values) normalized_values = ((values - min_val) / (max_val - min_val)) ** power marker_sizes = min_size + normalized_values * (max_size - min_size) * bool(power) return marker_sizes @@ -1944,7 +2160,7 @@ def _annotate_distribution_plot( ylabel = "Number of Catalogs" title = f"{evaluation_result.name}: {evaluation_result.sim_name}" annotation_xy = (0.5, 0.3) - if isinstance(evaluation_result.quantile, (list, np.ndarray)): + if isinstance(evaluation_result.quantile, (list, tuple, numpy.ndarray)): annotation_text = ( f"$\\delta_1 = P(X \\geq x) = {evaluation_result.quantile[0]:.2f}$\n" f"$\\delta_2 = P(X \\leq x) = {evaluation_result.quantile[1]:.2f}$\n" @@ -2067,6 +2283,10 @@ def _create_geo_axes( # Set plot aspect according to local longitude-latitude ratio in metric units LATKM = 110.574 # length of a ° of latitude [km] --> ignores Earth's flattening ax.set_aspect(LATKM / (111.320 * numpy.cos(numpy.deg2rad(central_latitude)))) + elif projection is None: + projection = ccrs.PlateCarree() + fig = pyplot.figure(figsize=figsize) + ax = fig.add_subplot(111, projection=projection) else: fig = pyplot.figure(figsize=figsize) ax = fig.add_subplot(111, projection=projection) diff --git a/docs/conf.py b/docs/conf.py index abd696d2..78b1ba60 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -102,7 +102,8 @@ "numpy": ("https://numpy.org/doc/stable/", None), "pandas": ("http://pandas.pydata.org/pandas-docs/stable/", None), "scipy": ("https://docs.scipy.org/doc/scipy/", None), - "matplotlib": ("https://matplotlib.org/stable", None) + "matplotlib": ("https://matplotlib.org/stable", None), + "cartopy": ('https://scitools.org.uk/cartopy/docs/latest/', None) } html_theme_options = {} diff --git a/docs/reference/api_reference.rst b/docs/reference/api_reference.rst index 6afc7132..c0f82f64 100644 --- a/docs/reference/api_reference.rst +++ b/docs/reference/api_reference.rst @@ -179,6 +179,17 @@ Grid-based forecast evaluations: paired_t_test w_test +Evaluation result base class + +.. automodule:: csep.models + +.. autosummary:: + :toctree: generated + + EvaluationResult + + +.. currentmodule:: csep.core.regions .. automodule:: csep.core.regions Regions @@ -193,6 +204,7 @@ Region class(es): :toctree: generated CartesianGrid2D + CartesianGrid2D.get_cartesian Testing regions: @@ -201,6 +213,7 @@ Testing regions: california_relm_region italy_csep_region + nz_csep_region global_region Region utilities: @@ -215,53 +228,49 @@ Region utilities: masked_region generate_aftershock_region +.. currentmodule:: csep.utils.plots +.. automodule:: csep.utils.plots Plotting -------- -.. automodule:: csep.utils.plots - General plotting: .. autosummary:: :toctree: generated - plot_histogram - plot_ecdf + plot_magnitude_versus_time + plot_cumulative_events_versus_time + plot_magnitude_histogram plot_basemap - plot_spatial_dataset - add_labels_for_publication + plot_catalog + plot_gridded_dataset -Plotting from catalogs: +Plotting catalog-based evaluations: .. autosummary:: :toctree: generated - plot_magnitude_versus_time - plot_catalog + plot_distribution_test + plot_calibration_test -Plotting stochastic event sets and evaluations: +Plotting grid-based evaluations: .. autosummary:: :toctree: generated - plot_cumulative_events_versus_time - plot_magnitude_histogram - plot_number_test - plot_magnitude_test - plot_distribution_test - plot_likelihood_test - plot_spatial_test - plot_calibration_test + plot_comparison_test + plot_consistency_test -Plotting gridded forecasts and evaluations: +Plotting alarm-based evaluations: .. autosummary:: :toctree: generated - plot_spatial_dataset - plot_comparison_test - plot_poisson_consistency_test + plot_ROC_diagram + plot_concentration_ROC_diagram + plot_Molchan_diagram + .. automodule:: csep.utils.time_utils diff --git a/examples/tutorials/plot_customizations.py b/examples/tutorials/plot_customizations.py index 7c66aa23..94ec50ca 100644 --- a/examples/tutorials/plot_customizations.py +++ b/examples/tutorials/plot_customizations.py @@ -119,9 +119,9 @@ # To plot a global forecast, we must assign the option ``set_global=True``, which is required by :ref:cartopy to handle # internally the extent of the plot -ax = plots.plot_spatial_dataset(numpy.log10(rate_sum), forecast.region, - show=True, set_global=True, - plot_args=plot_args) +ax = plots.plot_gridded_dataset(numpy.log10(rate_sum), forecast.region, + show=True, set_global=True, + plot_args=plot_args) #################################################################################################################################### diff --git a/examples/tutorials/quadtree_gridded_forecast_evaluation.py b/examples/tutorials/quadtree_gridded_forecast_evaluation.py index 540608c1..dd8dbd80 100644 --- a/examples/tutorials/quadtree_gridded_forecast_evaluation.py +++ b/examples/tutorials/quadtree_gridded_forecast_evaluation.py @@ -194,9 +194,9 @@ stest_result = [spatial_test_single_res_result, spatial_test_multi_res_result] -ax_spatial = plots.plot_poisson_consistency_test(stest_result, +ax_spatial = plots.plot_consistency_test(stest_result, plot_args={'xlabel': 'Spatial likelihood'}) ntest_result = [number_test_single_res_result, number_test_multi_res_result] -ax_number = plots.plot_poisson_consistency_test(ntest_result, +ax_number = plots.plot_consistency_test(ntest_result, plot_args={'xlabel': 'Number of Earthquakes'}) diff --git a/tests/test_plots.py b/tests/test_plots.py index 66ccc5da..c94f552d 100644 --- a/tests/test_plots.py +++ b/tests/test_plots.py @@ -26,7 +26,7 @@ ) from csep.utils.plots import ( plot_cumulative_events_versus_time, - plot_magnitude_vs_time, + plot_magnitude_versus_time, plot_distribution_test, plot_magnitude_histogram, plot_calibration_test, @@ -34,7 +34,7 @@ plot_consistency_test, plot_basemap, plot_catalog, - plot_spatial_dataset, + plot_gridded_dataset, plot_concentration_ROC_diagram, plot_Molchan_diagram, plot_ROC_diagram, @@ -113,18 +113,18 @@ def setUp(self): def test_plot_magnitude_vs_time(self): # Basic test - ax = plot_magnitude_vs_time(catalog=self.observation_m2, show=show_plots) - self.assertEqual(ax.get_title(), "Magnitude vs. Time") + ax = plot_magnitude_versus_time(catalog=self.observation_m2, show=show_plots) + self.assertEqual(ax.get_title(), "") self.assertEqual(ax.get_xlabel(), "Datetime") - self.assertEqual(ax.get_ylabel(), "$M$") + self.assertEqual(ax.get_ylabel(), "Magnitude") # Test with custom color - ax = plot_magnitude_vs_time(catalog=self.observation_m2, color="red", show=show_plots) + ax = plot_magnitude_versus_time(catalog=self.observation_m2, color="red", show=show_plots) scatter_color = ax.collections[0].get_facecolor()[0] self.assertTrue(all(scatter_color[:3] == (1.0, 0.0, 0.0))) # Check if color is red # Test with custom marker size - ax = plot_magnitude_vs_time( + ax = plot_magnitude_versus_time( catalog=self.observation_m2, size=25, max_size=600, show=show_plots ) scatter_sizes = ax.collections[0].get_sizes() @@ -132,18 +132,18 @@ def test_plot_magnitude_vs_time(self): numpy.testing.assert_array_almost_equal(scatter_sizes, func_sizes) # Test with custom alpha - ax = plot_magnitude_vs_time(catalog=self.observation_m2, alpha=0.5, show=show_plots) + ax = plot_magnitude_versus_time(catalog=self.observation_m2, alpha=0.5, show=show_plots) scatter_alpha = ax.collections[0].get_alpha() self.assertEqual(scatter_alpha, 0.5) # Test with custom marker size power - ax = plot_magnitude_vs_time(catalog=self.observation_m2, power=6, show=show_plots) + ax = plot_magnitude_versus_time(catalog=self.observation_m2, power=6, show=show_plots) scatter_sizes = ax.collections[0].get_sizes() func_sizes = _autosize_scatter(self.observation_m2.data["magnitude"], 4, 300, 6) numpy.testing.assert_array_almost_equal(scatter_sizes, func_sizes) # # # Test with show=True (just to ensure no errors occur) - plot_magnitude_vs_time(catalog=self.observation_m2, show=False) + plot_magnitude_versus_time(catalog=self.observation_m2, show=False) plt.close("all") def test_plot_cumulative_events_default(self): @@ -979,19 +979,19 @@ def tight_bbox(): def test_default_plot(self): fig, ax = plt.subplots(subplot_kw={"projection": ccrs.PlateCarree()}) - ax = plot_spatial_dataset(self.gridded_data, self.region, ax=ax) + ax = plot_gridded_dataset(self.gridded_data, self.region, ax=ax) self.assertIsInstance(ax, plt.Axes) def test_extent_setting_w_ax(self): extent = (-30, 30, -20, 20) - ax = plot_spatial_dataset( + ax = plot_gridded_dataset( self.gridded_data, self.region, extent=extent, show=show_plots ) numpy.testing.assert_array_almost_equal(ax.get_extent(crs=ccrs.PlateCarree()), extent) def test_extent_setting(self): extent = (-30, 30, -20, 20) - ax = plot_spatial_dataset( + ax = plot_gridded_dataset( self.gridded_data, self.region, extent=extent, show=show_plots ) numpy.testing.assert_array_almost_equal(ax.get_extent(crs=ccrs.PlateCarree()), extent) @@ -1000,34 +1000,34 @@ def test_extent_setting(self): def test_color_mapping(self): cmap = plt.get_cmap("plasma") fig, ax = plt.subplots(subplot_kw={"projection": ccrs.PlateCarree()}) - ax = plot_spatial_dataset( + ax = plot_gridded_dataset( self.gridded_data, self.region, ax=ax, colormap=cmap, show=show_plots ) self.assertIsInstance(ax.collections[0].cmap, colors.ListedColormap) def test_gridlines(self): fig, ax = plt.subplots(subplot_kw={"projection": ccrs.PlateCarree()}) - ax = plot_spatial_dataset( + ax = plot_gridded_dataset( self.gridded_data, self.region, ax=ax, grid=True, show=show_plots ) self.assertTrue(ax.gridlines()) def test_alpha_transparency(self): fig, ax = plt.subplots(subplot_kw={"projection": ccrs.PlateCarree()}) - ax = plot_spatial_dataset( + ax = plot_gridded_dataset( self.gridded_data, self.region, ax=ax, alpha=0.5, show=show_plots ) self.assertIsInstance(ax, plt.Axes) def test_plot_with_alpha_exp(self): - ax = plot_spatial_dataset( + ax = plot_gridded_dataset( self.gridded_data, self.region, alpha_exp=0.5, include_cbar=True, show=show_plots ) self.assertIsInstance(ax, plt.Axes) def test_include_colorbar(self): fig, ax = plt.subplots(subplot_kw={"projection": ccrs.PlateCarree()}) - ax = plot_spatial_dataset( + ax = plot_gridded_dataset( self.gridded_data, self.region, ax=ax, include_cbar=True, show=show_plots ) colorbars = [ @@ -1039,7 +1039,7 @@ def test_include_colorbar(self): def test_no_region_border(self): fig, ax = plt.subplots(subplot_kw={"projection": ccrs.PlateCarree()}) - ax = plot_spatial_dataset( + ax = plot_gridded_dataset( self.gridded_data, self.region, ax=ax, plot_region=False, show=show_plots ) lines = ax.get_lines() @@ -1048,7 +1048,7 @@ def test_no_region_border(self): def test_plot_spatial_dataset_w_basemap_stream_kwargs(self): projection = ccrs.Mercator() - ax = plot_spatial_dataset( + ax = plot_gridded_dataset( self.gridded_data, self.region, extent=[-20, 40, -5, 25], @@ -1067,7 +1067,7 @@ def test_plot_spatial_dataset_w_basemap_stream_kwargs(self): def test_plot_spatial_dataset_w_approx_projection(self): projection = "approx" - ax = plot_spatial_dataset( + ax = plot_gridded_dataset( self.gridded_data, self.region, basemap="stock_img", From 974bddba9bdba8769c84a9af8c39b4c431e1ddec Mon Sep 17 00:00:00 2001 From: pciturri Date: Fri, 30 Aug 2024 05:39:38 +0200 Subject: [PATCH 09/17] refactor: catalog and forecasts plot methods now uses kwargs instead of plot_args. Kept the `plot_args` for legacy compatibility. docs: Adapted tutorials to the new plot refactoring. Added catalog_plot to Catalog Operations tutorial. ft: Added higher resolutions for basemap autoscale functions, in case extent is lower. --- csep/core/catalogs.py | 19 +-- csep/core/forecasts.py | 17 ++- csep/utils/plots.py | 15 ++- examples/tutorials/catalog_filtering.py | 8 ++ .../tutorials/catalog_forecast_evaluation.py | 2 +- .../tutorials/gridded_forecast_evaluation.py | 2 +- examples/tutorials/plot_customizations.py | 119 +++++++++--------- .../quadtree_gridded_forecast_evaluation.py | 4 +- 8 files changed, 95 insertions(+), 91 deletions(-) diff --git a/csep/core/catalogs.py b/csep/core/catalogs.py index dc1d880c..6e576993 100644 --- a/csep/core/catalogs.py +++ b/csep/core/catalogs.py @@ -840,7 +840,8 @@ def b_positive(self): """ Implements the b-positive indicator from Nicholas van der Elst """ pass - def plot(self, ax=None, show=False, extent=None, set_global=False, plot_args=None): + def plot(self, ax=None, show=False, extent=None, set_global=False, plot_args=None, + **kwargs): """ Plot catalog according to plate-carree projection Args: @@ -855,17 +856,7 @@ def plot(self, ax=None, show=False, extent=None, set_global=False, plot_args=Non # no mutable function arguments plot_args_default = { - 'basemap': 'ESRI_terrain', - 'markersize': 2, - 'markercolor': 'red', - 'alpha': 0.3, - 'mag_scale': 7, - 'legend': True, - 'grid_labels': True, - 'legend_loc': 3, - 'figsize': (8, 8), - 'title': self.name, - 'mag_ticks': False + 'basemap': kwargs.pop('basemap', None) or 'ESRI_terrain', } # Plot the region border (if it exists) by default @@ -880,8 +871,8 @@ def plot(self, ax=None, show=False, extent=None, set_global=False, plot_args=Non plot_args_default.update(plot_args) # this call requires internet connection and basemap - ax = plot_catalog(self, ax=ax,show=show, extent=extent, - set_global=set_global, plot_args=plot_args_default) + ax = plot_catalog(self, ax=ax, show=show, extent=extent, + set_global=set_global, **plot_args_default, **kwargs) return ax diff --git a/csep/core/forecasts.py b/csep/core/forecasts.py index b57b178c..a1cbfad1 100644 --- a/csep/core/forecasts.py +++ b/csep/core/forecasts.py @@ -432,7 +432,8 @@ def load_ascii(cls, ascii_fname, start_date=None, end_date=None, name=None, swap gds = cls(start_date, end_date, magnitudes=mws, name=name, region=region, data=rates) return gds - def plot(self, ax=None, show=False, log=True, extent=None, set_global=False, plot_args=None): + def plot(self, ax=None, show=False, log=True, extent=None, set_global=False, plot_args=None, + **kwargs): """ Plot gridded forecast according to plate-carree projection Args: @@ -451,19 +452,23 @@ def plot(self, ax=None, show=False, log=True, extent=None, set_global=False, plo time = f'{round(end-start,3)} years' plot_args = plot_args or {} - plot_args.setdefault('figsize', (10, 10)) - plot_args.setdefault('title', self.name) - + plot_args.update({ + 'basemap': kwargs.pop('basemap', None) or 'ESRI_terrain', + 'title': kwargs.pop('title', None) or self.name, + 'figsize': kwargs.pop('figsize', None) or (8, 8), + }) + plot_args.update(**kwargs) # this call requires internet connection and basemap if log: plot_args.setdefault('clabel', f'log10 M{self.min_magnitude}+ rate per cell per {time}') with numpy.errstate(divide='ignore'): ax = plot_gridded_dataset(numpy.log10(self.spatial_counts(cartesian=True)), self.region, ax=ax, - show=show, extent=extent, set_global=set_global, plot_args=plot_args) + show=show, extent=extent, set_global=set_global, + **plot_args) else: plot_args.setdefault('clabel', f'M{self.min_magnitude}+ rate per cell per {time}') ax = plot_gridded_dataset(self.spatial_counts(cartesian=True), self.region, ax=ax, show=show, extent=extent, - set_global=set_global, plot_args=plot_args) + set_global=set_global, **plot_args) return ax diff --git a/csep/utils/plots.py b/csep/utils/plots.py index c48ed30d..8b855580 100644 --- a/csep/utils/plots.py +++ b/csep/utils/plots.py @@ -559,7 +559,7 @@ def plot_basemap( ax = ax or _create_geo_axes(plot_args["figsize"], extent, projection, set_global) line_autoscaler = cartopy.feature.AdaptiveScaler("110m", (("50m", 50), ("10m", 5))) - tile_autoscaler = cartopy.feature.AdaptiveScaler(5, ((6, 50), (7, 15))) + tile_autoscaler = cartopy.feature.AdaptiveScaler(5, ((6, 50), (7, 15), (8, 5), (9, 1))) tile_depth = ( 4 if set_global @@ -1148,9 +1148,11 @@ def plot_comparison_test( - **capsize** (`float`): Size of the caps on the error bars. - **markersize** (`float`): Size of the markers. - **xlabel_fontsize** (`int`): Font size for the X-axis labels. - - **ylabel** (`str`): Label for the Y-axis. Defaults to `'Information gain per earthquake'`. + - **ylabel** (`str`): Label for the Y-axis. Defaults to + `'Information gain per earthquake'`. - **ylabel_fontsize** (`int`): Font size for the Y-axis label. - - **title** (`str`): Title of the plot. Defaults to the name of the first T-Test result. + - **title** (`str`): Title of the plot. Defaults to the name of the first T-Test + result. - **ylim** (`tuple`): Limits for the Y-axis. - **grid** (`bool`): Whether to display grid lines. Defaults to `True`. - **hbars** (`bool`): Whether to include horizontal bars for visual separation. @@ -1682,8 +1684,8 @@ def plot_Molchan_diagram( 6. Test each ordered and normalized forecasted rate defined in (3) as a threshold value to obtain the corresponding contingency table. 7. Define the "nu" (Miss rate) and "tau" (Fraction of spatial alarmed cells) for each - threshold using the information provided by the corresponding contingency table defined in - (6). + threshold using the information provided by the corresponding contingency table defined + in (6). Note: 1. The testing catalog and forecast should have exactly the same time-window (duration). @@ -1696,7 +1698,8 @@ def plot_Molchan_diagram( catalog (CSEPCatalog): The evaluation catalog. linear (bool): If True, a linear x-axis is used; if False, a logarithmic x-axis is used. Defaults to `True`. - plot_uniform (bool): If True, include a uniform forecast on the plot. Defaults to `True`. + plot_uniform (bool): If True, include a uniform forecast on the plot. Defaults to + `True`. show (bool): If True, displays the plot. Defaults to `True`. ax (matplotlib.axes.Axes): Axes object to plot on. If `None`, creates a new figure. Defaults to `None`. diff --git a/examples/tutorials/catalog_filtering.py b/examples/tutorials/catalog_filtering.py index ce85f5c9..092c5c92 100644 --- a/examples/tutorials/catalog_filtering.py +++ b/examples/tutorials/catalog_filtering.py @@ -92,6 +92,14 @@ print(catalog) +#################################################################################################################################### +# Plot catalog +# ------------- +# +# To visualize the catalog, use :meth:`csep.core.catalogs.AbstractBaseCatalog.plot` to plot it spatially +catalog.plot(show=True) + + #################################################################################################################################### # Write catalog # ------------- diff --git a/examples/tutorials/catalog_forecast_evaluation.py b/examples/tutorials/catalog_forecast_evaluation.py index 9677f9d2..24bbe715 100644 --- a/examples/tutorials/catalog_forecast_evaluation.py +++ b/examples/tutorials/catalog_forecast_evaluation.py @@ -97,7 +97,7 @@ print(comcat_catalog) # Plot the catalog -comcat_catalog.plot() +comcat_catalog.plot(show=True) #################################################################################################################################### # Perform number test diff --git a/examples/tutorials/gridded_forecast_evaluation.py b/examples/tutorials/gridded_forecast_evaluation.py index 447569aa..3a784f80 100644 --- a/examples/tutorials/gridded_forecast_evaluation.py +++ b/examples/tutorials/gridded_forecast_evaluation.py @@ -103,7 +103,7 @@ # consistency tests. ax = plots.plot_consistency_test(spatial_test_result, - plot_args={'xlabel': 'Spatial likelihood'}) + xlabel='Spatial likelihood') plt.show() #################################################################################################################################### diff --git a/examples/tutorials/plot_customizations.py b/examples/tutorials/plot_customizations.py index 94ec50ca..70d426c2 100644 --- a/examples/tutorials/plot_customizations.py +++ b/examples/tutorials/plot_customizations.py @@ -34,39 +34,35 @@ forecast = csep.load_gridded_forecast(datasets.hires_ssm_italy_fname, name='Werner, et al (2010) Italy') #################################################################################################################################### -# **Selecting plotting arguments** -# -# Create a dictionary containing the plot arguments -args_dict = {'title': 'Italy 10 year forecast', - 'grid_labels': True, - 'borders': True, - 'feature_lw': 0.5, - 'basemap': 'ESRI_imagery', - 'cmap': 'rainbow', - 'alpha_exp': 0.8, - 'projection': cartopy.crs.Mercator()} +# **Plotting the dataset with fine-tuned arguments** + #################################################################################################################################### # These arguments are, in order: # +# * Set an extent +# * Select ESRI Imagery as a basemap. # * Assign a title # * Set labels to the geographic axes # * Draw country borders -# * Set a linewidth of 0.5 to country borders -# * Select ESRI Imagery as a basemap. -# * Assign ``'rainbow'`` as colormap. Possible values from from ``matplotlib.cm`` library +# * Set a linewidth of 0.5 to country border +# * Assign ``'rainbow'`` as colormap. Possible values from ``matplotlib.cm`` library # * Defines 0.8 for an exponential transparency function (default is 0 for constant alpha, whereas 1 for linear). # * An object cartopy.crs.Projection() is passed as Projection to the map # -# The complete description of plot arguments can be found in :func:`csep.utils.plots.plot_spatial_dataset` +# The complete description of plot arguments can be found in :func:`csep.utils.plots.plot_gridded_dataset` #################################################################################################################################### -# **Plotting the dataset** -# -# The map `extent` can be defined. Otherwise, the extent of the data would be used. The dictionary defined must be passed as argument ax = forecast.plot(extent=[3, 22, 35, 48], - show=True, - plot_args=args_dict) + basemap='ESRI_imagery', + title='Italy 10 year forecast', + grid_labels=True, + borders=True, + borders_linewidth=1.5, + cmap='rainbow', + alpha_exp=0.8, + projection=cartopy.crs.Mercator(), + show=True) #################################################################################################################################### # Example 2: Plot a global forecast and a selected magnitude bin range @@ -101,27 +97,23 @@ rate_sum = forecast.region.get_cartesian(rate_sum) -#################################################################################################################################### -# **Define plot arguments** -# -# We define the arguments and a global projection, centered at $lon=-180$ - -plot_args = {'figsize': (10,6), 'coastline':True, 'feature_color':'black', - 'projection': cartopy.crs.Robinson(central_longitude=180.0), - 'title': forecast.name, 'grid_labels': False, - 'cmap': 'magma', - 'clabel': r'$\log_{10}\lambda\left(M_w \in [{%.2f},\,{%.2f}]\right)$ per ' - r'${%.1f}^\circ\times {%.1f}^\circ $ per forecast period' % - (low_bound, upper_bound, forecast.region.dh, forecast.region.dh)} - #################################################################################################################################### # **Plotting the dataset** # To plot a global forecast, we must assign the option ``set_global=True``, which is required by :ref:cartopy to handle -# internally the extent of the plot +# internally the extent of the plot. We can further customize the plot using the required arguments from :func:`csep.utils.plots.plot_gridded_dataset` ax = plots.plot_gridded_dataset(numpy.log10(rate_sum), forecast.region, - show=True, set_global=True, - plot_args=plot_args) + figsize=(10,6), + set_global=True, + coastline_color='black', + projection=cartopy.crs.Robinson(central_longitude=180.0), + title=forecast.name, + grid_labels=False, + colormap='magma', + clabel= r'$\log_{10}\lambda\left(M_w \in [{%.2f},\,{%.2f}]\right)$ per ' \ + r'${%.1f}^\circ\times {%.1f}^\circ $ per forecast period' % \ + (low_bound, upper_bound, forecast.region.dh, forecast.region.dh), + show=True) #################################################################################################################################### @@ -139,21 +131,12 @@ min_mag = 4.5 catalog = csep.query_comcat(start_time, end_time, min_magnitude=min_mag, verbose=False) -# **Define plotting arguments** -plot_args = {'basemap': csep.datasets.basemap_california, - 'markersize': 2, - 'markercolor': 'red', - 'alpha': 0.3, - 'mag_scale': 7, - 'legend': True, - 'legend_loc': 3, - 'coastline': False, - 'mag_ticks': [4.0, 5.0, 6.0, 7.0]} +# **Define plotting arguments* #################################################################################################################################### # These arguments are, in order: # -# * Assign as basemap the ESRI_terrain webservice +# * Assign as basemap a TIFF file in the same reference as the plot # * Set minimum markersize of 2 with red color # * Set a 0.3 transparency # * mag_scale is used to exponentially scale the size with respect to magnitude. Recommended 1-8 @@ -161,11 +144,24 @@ # * Set a list of Magnitude ticks to display in the legend # # The complete description of plot arguments can be found in :func:`csep.utils.plots.plot_catalog` +# The arguments can be stored as a dictionary a priori and then unpacked to the function with `**`. + + +plot_args = {'basemap': csep.datasets.basemap_california, + 'size': 7, + 'max_size': 500, + 'markercolor': 'red', + 'alpha': 0.3, + 'mag_scale': 8, + 'legend': True, + 'legend_loc': 3, + 'coastline': False, + 'mag_ticks': [4.0, 5.0, 6.0, 7.0]} #################################################################################################################################### # **Plot the catalog** -ax = catalog.plot(show=False, plot_args=plot_args) +ax = catalog.plot(show=True, **plot_args) #################################################################################################################################### @@ -177,24 +173,25 @@ # :doc:`gridded_forecast_evaluation` for information on calculating and storing evaluation results) L_results = [csep.load_evaluation_result(i) for i in datasets.l_test_examples] -args = {'figsize': (6,5), - 'title': r'$\mathcal{L}-\mathrm{test}$', - 'title_fontsize': 18, - 'xlabel': 'Log-likelihood', - 'xticks_fontsize': 9, - 'ylabel_fontsize': 9, - 'linewidth': 0.8, - 'capsize': 3, - 'hbars':True, - 'tight_layout': True} +plot_args = {'figsize': (6, 5), + 'title': r'$\mathcal{L}-\mathrm{test}$', + 'title_fontsize': 18, + 'xlabel': 'Log-likelihood', + 'xticks_fontsize': 9, + 'ylabel_fontsize': 9, + 'linewidth': 0.8, + 'capsize': 3, + 'hbars':True, + 'tight_layout': True} #################################################################################################################################### # Description of plot arguments can be found in :func:`plot_poisson_consistency_test`. # We set ``one_sided_lower=True`` as usual for an L-test, where the model is rejected if the observed # is located within the lower tail of the simulated distribution. -ax = plots.plot_consistency_test(L_results, one_sided_lower=True, plot_args=args) +ax = plots.plot_consistency_test(L_results, + one_sided_lower=True, + show=True, + **plot_args) -# Needed to show plots if running as script -plt.show() diff --git a/examples/tutorials/quadtree_gridded_forecast_evaluation.py b/examples/tutorials/quadtree_gridded_forecast_evaluation.py index dd8dbd80..3006b197 100644 --- a/examples/tutorials/quadtree_gridded_forecast_evaluation.py +++ b/examples/tutorials/quadtree_gridded_forecast_evaluation.py @@ -195,8 +195,8 @@ stest_result = [spatial_test_single_res_result, spatial_test_multi_res_result] ax_spatial = plots.plot_consistency_test(stest_result, - plot_args={'xlabel': 'Spatial likelihood'}) + xlabel='Spatial likelihood') ntest_result = [number_test_single_res_result, number_test_multi_res_result] ax_number = plots.plot_consistency_test(ntest_result, - plot_args={'xlabel': 'Number of Earthquakes'}) + xlabel='Number of Earthquakes') From 1a0f9084f5d10100c290ef3d01d5bf8c4b22cdd9 Mon Sep 17 00:00:00 2001 From: pciturri Date: Wed, 2 Apr 2025 15:06:49 +0200 Subject: [PATCH 10/17] API changes: Added backwards-compatibility layer for all plotting functions that would otherwise be broke with proposed changes. Deprecation strategy were issued for distinct cases: - Functions to be removed (plot_cumulative_events_versus_time_dev, plot_histogram, plot_ecdf, plot_magnitude_histogram_dev, add_labels_for_publication) fallback to legacy code and issue warning of future removal. - Abstracted functions ( [plot_number_test, plot_spatial_test, plot_magnitude_test, plot_likelihood_test] >> plot_test_distribution ; plot_poisson_consistency_test >> plot_consistency test ) also fallback to legacy code and issue deprecation warning hinting the new function and docs. - Refactored functions with strong API breaks (plot_cumulative_events_versus_time, plot_basemap, plot_consistency_test (when NB-distributed)) adapts to new call with known cases OR fallsback to legacy code. - Refactored functions with minor API breaks (plot_comparison_test, plot_concentration_ROC_diagram, plot_ROC_diagram, plot_Molchan_diagram) only adapts to new code with known cases without fallback to legacy. - Renamed function (plot_spatial_dataset >> plot_gridded_dataset) just wraps to correct function. refac: renamed plot_distribution_test to plot_test_distribution. Added to all catalog-based-test's names the prefix "Catalog" for consistency. ft: Added 'reset_times' to plot_magnitude_versus_time for backwards compat. tests: added unit tests for plot_magnitude_versus_time includint reset_times arg. --- csep/core/catalog_evaluations.py | 4 +- csep/models.py | 8 +- csep/utils/plots.py | 72 +- csep/utils/plots_legacy.py | 1843 ++++++++++++++++++++++++++++++ tests/test_plots.py | 41 +- 5 files changed, 1931 insertions(+), 37 deletions(-) create mode 100644 csep/utils/plots_legacy.py diff --git a/csep/core/catalog_evaluations.py b/csep/core/catalog_evaluations.py index 7caa12f7..60b45ddb 100644 --- a/csep/core/catalog_evaluations.py +++ b/csep/core/catalog_evaluations.py @@ -212,7 +212,7 @@ def magnitude_test(forecast, observed_catalog, verbose=True): # prepare result result = CatalogMagnitudeTestResult(test_distribution=test_distribution, - name='M-Test', + name='Catalog M-Test', observed_statistic=obs_d_statistic, quantile=(delta_1, delta_2), status='normal', @@ -307,7 +307,7 @@ def pseudolikelihood_test(forecast, observed_catalog, verbose=True): # prepare evaluation result result = CatalogPseudolikelihoodTestResult( test_distribution=test_distribution_1d, - name='PL-Test', + name='Catalog PL-Test', observed_statistic=obs_plh, quantile=(delta_1, delta_2), status=message, diff --git a/csep/models.py b/csep/models.py index 65e94c73..fbf59388 100644 --- a/csep/models.py +++ b/csep/models.py @@ -143,7 +143,7 @@ def plot(self, show=False, plot_args=None): 'bins': bins} # looks funny, but will update the defaults with the user defined arguments plot_args_defaults.update(plot_args) - ax = plots.plot_distribution_test(self, show=show) + ax = plots.plot_test_distribution(self, show=show) return ax @@ -160,7 +160,7 @@ def plot(self, show=False, plot_args=None): 'bins': 'auto'} # looks funny, but will update the defaults with the user defined arguments plot_args_defaults.update(plot_args) - ax = plots.plot_distribution_test(self, show=show) + ax = plots.plot_test_distribution(self, show=show) return ax @@ -175,7 +175,7 @@ def plot(self, show=False, plot_args=None): 'title': 'Magnitude Test', 'bins': 'auto'} plot_args_defaults.update(plot_args) - ax = plots.plot_distribution_test(self, show=show) + ax = plots.plot_test_distribution(self, show=show) return ax @@ -194,7 +194,7 @@ def plot(self, show=False, plot_args=None): } # looks funny, but will update the defaults with the user defined arguments plot_args_defaults.update(plot_args) - ax = plots.plot_distribution_test(self, show=show) + ax = plots.plot_test_distribution(self, show=show) return ax diff --git a/csep/utils/plots.py b/csep/utils/plots.py index 8b855580..0ca691af 100644 --- a/csep/utils/plots.py +++ b/csep/utils/plots.py @@ -101,6 +101,7 @@ def plot_magnitude_versus_time( max_size: int = 300, power: int = 4, alpha: float = 0.5, + reset_times: bool = False, ax: Optional[matplotlib.axes.Axes] = None, show: bool = False, **kwargs: Any, @@ -118,6 +119,7 @@ def plot_magnitude_versus_time( Defaults to `300`. power (int, optional): Power scaling of the scatter sizing. Defaults to `4`. alpha (float, optional): Transparency level for the scatter points. Defaults to `0.5`. + reset_times (bool): If True, x-axis shows time in days since first event. ax (matplotlib.axes.Axes, optional): Axis object on which to plot. If not provided, a new figure and axis are created. Defaults to `None`. show (bool, optional): Whether to display the plot. Defaults to `False`. @@ -149,8 +151,19 @@ def plot_magnitude_versus_time( # Plot data mag = catalog.data["magnitude"] datetimes = catalog.get_datetimes() + + if reset_times: + # Convert to days since first event + SECONDS_PER_DAY = 86400 + timestamps = numpy.array([dt.timestamp() for dt in datetimes]) + xdata = (timestamps - timestamps[0]) / SECONDS_PER_DAY + xlabel = plot_args["xlabel"] or "Days since first event" + else: + xdata = datetimes + xlabel = plot_args["xlabel"] or "Datetime" + ax.scatter( - datetimes, + xdata, mag, marker="o", c=color, @@ -159,15 +172,16 @@ def plot_magnitude_versus_time( ) # Set labels and title - ax.set_xlabel(plot_args["xlabel"] or "Datetime", fontsize=plot_args["xlabel_fontsize"]) + ax.set_xlabel(xlabel, fontsize=plot_args["xlabel_fontsize"]) ax.set_ylabel(plot_args["ylabel"] or "Magnitude", fontsize=plot_args["ylabel_fontsize"]) ax.set_title(plot_args["title"], fontsize=plot_args["title_fontsize"]) # Autoformat ticks and labels - ax.xaxis.set_major_locator(plot_args["datetime_locator"]) - ax.xaxis.set_major_formatter(plot_args["datetime_formatter"]) + if not reset_times: + ax.xaxis.set_major_locator(plot_args["datetime_locator"]) + ax.xaxis.set_major_formatter(plot_args["datetime_formatter"]) + fig.autofmt_xdate() ax.grid(plot_args["grid"]) - fig.autofmt_xdate() if plot_args["tight_layout"]: fig.tight_layout() @@ -177,7 +191,7 @@ def plot_magnitude_versus_time( return ax -def plot_cumulative_events_versus_time( +def _plot_cumulative_events_versus_time( catalog_forecast: "CatalogForecast", observation: "CSEPCatalog", time_axis: str = "datetime", @@ -232,7 +246,6 @@ def plot_cumulative_events_versus_time( Returns: matplotlib.axes.Axes: The Matplotlib axes object with the plotted data. """ - # Initialize plot plot_args = {**DEFAULT_PLOT_ARGS, **kwargs} fig, ax = pyplot.subplots(figsize=plot_args["figsize"]) if ax is None else (ax.figure, ax) @@ -507,7 +520,7 @@ def get_histogram_synthetic_cat(x, mags, normed=True): ############### # Spatial plots ############### -def plot_basemap( +def _plot_basemap( basemap: Optional[str] = None, extent: Optional[List[float]] = None, coastline: bool = True, @@ -887,7 +900,7 @@ def plot_gridded_dataset( ##################### # Single Result plots ##################### -def plot_distribution_test( +def plot_test_distribution( evaluation_result: "EvaluationResult", bins: Union[str, int, List[Any]] = "fd", percentile: Optional[int] = 95, @@ -1123,7 +1136,7 @@ def plot_calibration_test( ##################### # Results batch plots ##################### -def plot_comparison_test( +def _plot_comparison_test( results_t: List["EvaluationResult"], results_w: Optional[List["EvaluationResult"]] = None, percentile: int = 95, @@ -1282,7 +1295,7 @@ def plot_comparison_test( return ax -def plot_consistency_test( +def _plot_consistency_test( eval_results: Union[List["EvaluationResult"], "EvaluationResult"], normalize: bool = False, one_sided_lower: bool = False, @@ -1416,7 +1429,7 @@ def plot_consistency_test( ################### # Alarm-based plots ################### -def plot_concentration_ROC_diagram( +def _plot_concentration_ROC_diagram( forecast: "GriddedForecast", catalog: "CSEPCatalog", linear: bool = True, @@ -1532,7 +1545,7 @@ def plot_concentration_ROC_diagram( return ax -def plot_ROC_diagram( +def _plot_ROC_diagram( forecast: "GriddedForecast", catalog: "CSEPCatalog", linear: bool = True, @@ -1659,7 +1672,7 @@ def plot_ROC_diagram( return ax -def plot_Molchan_diagram( +def _plot_Molchan_diagram( forecast: "GriddedForecast", catalog: "CSEPCatalog", linear: bool = True, @@ -2159,7 +2172,7 @@ def _annotate_distribution_plot( if auto_annotate: if evaluation_result.name == "Catalog N-Test": - xlabel = "Event Count" + xlabel = "Event Counts" ylabel = "Number of Catalogs" title = f"{evaluation_result.name}: {evaluation_result.sim_name}" annotation_xy = (0.5, 0.3) @@ -2176,7 +2189,7 @@ def _annotate_distribution_plot( ) elif evaluation_result.name == "Catalog S-Test": - xlabel = "Normalized Spatial Statistic" + xlabel = "Spatial Statistic" ylabel = "Number of Catalogs" title = f"{evaluation_result.name}: {evaluation_result.sim_name}" annotation_xy = (0.2, 0.6) @@ -2187,7 +2200,7 @@ def _annotate_distribution_plot( ) elif evaluation_result.name == "Catalog M-Test": - xlabel = "Magnitude" + xlabel = "Magnitude Statistic" ylabel = "Number of Catalogs" title = f"{evaluation_result.name}: {evaluation_result.sim_name}" annotation_xy = (0.55, 0.6) @@ -2197,7 +2210,7 @@ def _annotate_distribution_plot( f"$\\omega = {evaluation_result.observed_statistic:.2f}$" ) elif evaluation_result.name == "Catalog PL-Test": - xlabel = "Likelihood" + xlabel = "Pseudo-Likelihood" ylabel = "Number of Catalogs" title = f"{evaluation_result.name}: {evaluation_result.sim_name}" annotation_xy = (0.55, 0.3) @@ -2411,3 +2424,26 @@ def _process_stat_distribution( mean = numpy.mean(test_distribution) return plow, phigh, mean, observed_statistic + + +# Public export of function wrappers for backwards/legacy compatibility. +from .plots_legacy import (plot_cumulative_events_versus_time, + plot_cumulative_events_versus_time_dev, + plot_histogram, + plot_ecdf, + plot_magnitude_histogram_dev, + plot_basemap, + plot_spatial_dataset, + plot_number_test, + plot_magnitude_test, + plot_distribution_test, + plot_likelihood_test, + plot_spatial_test, + plot_poisson_consistency_test, + plot_comparison_test, + plot_consistency_test, + plot_pvalues_and_intervals, + plot_concentration_ROC_diagram, + plot_ROC_diagram, + plot_Molchan_diagram) + diff --git a/csep/utils/plots_legacy.py b/csep/utils/plots_legacy.py new file mode 100644 index 00000000..5723211d --- /dev/null +++ b/csep/utils/plots_legacy.py @@ -0,0 +1,1843 @@ +import time +import warnings +from functools import wraps + +# Third-party imports +import numpy +import string +import scipy.stats +import matplotlib +import matplotlib.lines +from matplotlib.collections import PatchCollection +import matplotlib.pyplot as pyplot +from cartopy.io import img_tiles + +# PyCSEP imports +from csep.utils.calc import bin1d_vec +from csep.utils.time_utils import datetime_to_utc_epoch +from csep.utils.plots import (_plot_cumulative_events_versus_time, _plot_basemap, + _plot_comparison_test, _plot_consistency_test, _plot_concentration_ROC_diagram, _plot_ROC_diagram, _plot_Molchan_diagram) + + +def plot_cumulative_events_versus_time_dev(xdata, ydata, obs_data, + plot_args, show=False): + """ + + .. deprecated:: 0.7.0 + This function is deprecated and will be removed in version 1.0. + Please use :func:`~csep.utils.plots.plot_test_distribution` instead. + + + Args: + xdata (ndarray): time bins for plotting shape (N,) + ydata (ndarray or list like): ydata for plotting; shape (N,5) in order 2.5%Per, 25%Per, 50%Per, 75%Per, 97.5%Per + obs_data (ndarry): same shape as xdata + plot_args: + show: + + Returns: + + """ + warnings.warn( + "'plot_cumulative_events_versus_time_dev' is deprecated and will be removed in version 1.0.\n" + "Please use 'plot_cumulative_events_versus_time' with the appropriate keyword arguments instead:\n" + " catalog_forecast (CatalogForecast), observation (CSEPCatalog), show (bool), etc.\n\n" + "See the updated documentation at:\n" + " https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_cumulative_events_versus_time.html\n", + DeprecationWarning, + stacklevel=2 + ) + + figsize = plot_args.get('figsize', None) + sim_label = plot_args.get('sim_label', 'Simulated') + obs_label = plot_args.get('obs_label', 'Observation') + legend_loc = plot_args.get('legend_loc', 'best') + title = plot_args.get('title', 'Cumulative Event Counts') + xlabel = plot_args.get('xlabel', 'Days') + + fig, ax = pyplot.subplots(figsize=figsize) + try: + fifth_per = ydata[0, :] + first_quar = ydata[1, :] + med_counts = ydata[2, :] + second_quar = ydata[3, :] + nine_fifth = ydata[4, :] + except: + raise TypeError("ydata must be a [N,5] ndarray.") + # plotting + + ax.plot(xdata, obs_data, color='black', label=obs_label) + ax.plot(xdata, med_counts, color='red', label=sim_label) + ax.fill_between(xdata, fifth_per, nine_fifth, color='red', alpha=0.2, + label='5%-95%') + ax.fill_between(xdata, first_quar, second_quar, color='red', alpha=0.5, + label='25%-75%') + ax.legend(loc=legend_loc) + ax.set_xlabel(xlabel) + ax.set_ylabel('Cumulative event count') + ax.set_title(title) + # pyplot.subplots_adjust(right=0.75) + # annotate the plot with information from data + # ax.annotate(str(observation), xycoords='axes fraction', xy=xycoords, fontsize=10, annotation_clip=False) + # save figure + filename = plot_args.get('filename', None) + if filename is not None: + fig.savefig(filename + '.pdf') + fig.savefig(filename + '.png', dpi=300) + # optionally show figure + if show: + pyplot.show() + + return ax + + +@wraps(_plot_cumulative_events_versus_time) +def plot_cumulative_events_versus_time(*args, **kwargs): + """ + Legacy-compatible wrapper for plot_cumulative_events_versus_time. + + Deprecated usage will emit warnings and fall back to legacy logic. + This wrapper will be removed in a future version. + """ + from csep.core.forecasts import CatalogForecast + from csep.core.catalogs import CSEPCatalog + from .plots_legacy import _plot_cumulative_events_versus_time_legacy_impl + + try: + return _plot_cumulative_events_versus_time(*args, **kwargs) + except Exception as e: + # Determine if the call is legacy-style + is_legacy_call = False + + if len(args) >= 2: + is_legacy_call = ( + not isinstance(args[0], CatalogForecast) and + isinstance(args[1], CSEPCatalog) + ) + elif 'catalog_forecast' not in kwargs or not isinstance(kwargs['catalog_forecast'], + CatalogForecast): + is_legacy_call = True + + if is_legacy_call: + warnings.warn( + "'plot_cumulative_events_versus_time' was called with deprecated arguments, and falling back to legacy implementation.\n" + "As of version 1.0, this behavior is deprecated. " + "Please use the new keyword arguments:\n" + " catalog_forecast (CatalogForecast), observation (CSEPCatalog), show (bool), etc.\n\n" + "See the updated documentation at:\n" + " https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_cumulative_events_versus_time.html\n", + DeprecationWarning, + stacklevel=2 + ) + + return _plot_cumulative_events_versus_time_legacy_impl(*args, **kwargs) + + raise + + +def _plot_cumulative_events_versus_time_legacy_impl(stochastic_event_sets, observation, + show=False, plot_args=None): + """ + Same as below but performs the statistics on numpy arrays without using pandas data frames. + + .. deprecated:: 0.7.0 + This function is deprecated and will be removed in version 1.0. + Please use :func:`~csep.utils.plots.plot_test_distribution` instead. + + Args: + stochastic_event_sets: + observation: + show: + plot_args: + + Returns: + ax: matplotlib.Axes + """ + plot_args = plot_args or {} + figsize = plot_args.get('figsize', None) + fig, ax = pyplot.subplots(figsize=figsize) + # get global information from stochastic event set + t0 = time.time() + n_cat = len(stochastic_event_sets) + + extreme_times = [] + for ses in stochastic_event_sets: + start_epoch = datetime_to_utc_epoch(ses.start_time) + end_epoch = datetime_to_utc_epoch(ses.end_time) + if start_epoch == None or end_epoch == None: + continue + + extreme_times.append((start_epoch, end_epoch)) + + # offsets to start at 0 time and converts from millis to hours + time_bins, dt = numpy.linspace(numpy.min(extreme_times), + numpy.max(extreme_times), 100, + endpoint=True, retstep=True) + n_bins = time_bins.shape[0] + binned_counts = numpy.zeros((n_cat, n_bins)) + for i, ses in enumerate(stochastic_event_sets): + n_events = ses.data.shape[0] + ses_origin_time = ses.get_epoch_times() + inds = bin1d_vec(ses_origin_time, time_bins) + for j in range(n_events): + binned_counts[i, inds[j]] += 1 + if (i + 1) % 1500 == 0: + t1 = time.time() + print(f"Processed {i + 1} catalogs in {t1 - t0} seconds.") + t1 = time.time() + print(f'Collected binned counts in {t1 - t0} seconds.') + summed_counts = numpy.cumsum(binned_counts, axis=1) + + # compute summary statistics for plotting + fifth_per = numpy.percentile(summed_counts, 5, axis=0) + first_quar = numpy.percentile(summed_counts, 25, axis=0) + med_counts = numpy.percentile(summed_counts, 50, axis=0) + second_quar = numpy.percentile(summed_counts, 75, axis=0) + nine_fifth = numpy.percentile(summed_counts, 95, axis=0) + # compute median for comcat data + obs_binned_counts = numpy.zeros(n_bins) + inds = bin1d_vec(observation.get_epoch_times(), time_bins) + for j in range(observation.event_count): + obs_binned_counts[inds[j]] += 1 + obs_summed_counts = numpy.cumsum(obs_binned_counts) + + # update time_bins for plotting + millis_to_hours = 60 * 60 * 1000 * 24 + time_bins = (time_bins - time_bins[0]) / millis_to_hours + time_bins = time_bins + (dt / millis_to_hours) + # make all arrays start at zero + time_bins = numpy.insert(time_bins, 0, 0) + fifth_per = numpy.insert(fifth_per, 0, 0) + first_quar = numpy.insert(first_quar, 0, 0) + med_counts = numpy.insert(med_counts, 0, 0) + second_quar = numpy.insert(second_quar, 0, 0) + nine_fifth = numpy.insert(nine_fifth, 0, 0) + obs_summed_counts = numpy.insert(obs_summed_counts, 0, 0) + + # get values from plotting args + sim_label = plot_args.get('sim_label', 'Simulated') + obs_label = plot_args.get('obs_label', 'Observation') + xycoords = plot_args.get('xycoords', (1.00, 0.40)) + legend_loc = plot_args.get('legend_loc', 'best') + title = plot_args.get('title', 'Cumulative Event Counts') + # plotting + ax.plot(time_bins, obs_summed_counts, color='black', label=obs_label) + ax.plot(time_bins, med_counts, color='red', label=sim_label) + ax.fill_between(time_bins, fifth_per, nine_fifth, color='red', alpha=0.2, + label='5%-95%') + ax.fill_between(time_bins, first_quar, second_quar, color='red', alpha=0.5, + label='25%-75%') + ax.legend(loc=legend_loc) + ax.set_xlabel('Days since Mainshock') + ax.set_ylabel('Cumulative Event Count') + ax.set_title(title) + pyplot.subplots_adjust(right=0.75) + # annotate the plot with information from data + # ax.annotate(str(observation), xycoords='axes fraction', xy=xycoords, fontsize=10, annotation_clip=False) + # save figure + filename = plot_args.get('filename', None) + if filename is not None: + fig.savefig(filename + '.pdf') + fig.savefig(filename + '.png', dpi=300) + # optionally show figure + if show: + pyplot.show() + + return ax + + +def plot_histogram(simulated, observation, bins='fd', percentile=None, + show=False, axes=None, catalog=None, plot_args=None): + """ + Plots histogram of single statistic for stochastic event sets and observations. The function will behave differently depending on the inumpyuts. + + .. deprecated:: 0.7.0 + This function is deprecated and will be removed in version 1.0. + Please use :func:`~csep.utils.plots.plot_test_distribution` instead. + + + Simulated should always be either a list or numpy.array where there would be one value per data in the stochastic event + set. Observation could either be a scalar or a numpy.array/list. If observation is a scale a vertical line would be + plotted, if observation is iterable a second histogram would be plotted. + + This allows for comparisons to be made against catalogs where there are multiple values e.g., magnitude, and single values + e.g., event count. + + If an axis handle is included, additional function calls will only addition extra simulations, observations will not be + plotted. Since this function returns an axes handle, any extra modifications to the figure can be made using that. + + Args: + simulated (numpy.arrays): numpy.array like representation of statistics computed from catalogs. + observation(numpy.array or scalar): observation to plot against stochastic event set + filename (str): filename to save figure + show (bool): show interactive version of the figure + ax (axis object): axis object with interface defined by matplotlib + catalog (csep.AbstractBaseCatalog): used for annotating the figures + plot_args (dict): additional plotting commands. TODO: Documentation + + Returns: + axis: matplolib axes handle + """ + # Plotting + + warnings.warn( + "'plot_histogram' is deprecated and will be removed in version 1.0.\n" + "Please use 'plot_test_distribution' instead, which provides improved support for test statistics.\n\n" + "See the documentation at:\n" + " https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_test_distribution.html", + DeprecationWarning, + stacklevel=2 + ) + + plot_args = plot_args or {} + chained = False + figsize = plot_args.get('figsize', None) + if axes is not None: + chained = True + ax = axes + else: + if catalog: + fig, ax = pyplot.subplots(figsize=figsize) + else: + fig, ax = pyplot.subplots() + + # parse plotting arguments + sim_label = plot_args.get('sim_label', 'Simulated') + obs_label = plot_args.get('obs_label', 'Observation') + xlabel = plot_args.get('xlabel', 'X') + ylabel = plot_args.get('ylabel', 'Frequency') + xycoords = plot_args.get('xycoords', (1.00, 0.40)) + title = plot_args.get('title', None) + legend_loc = plot_args.get('legend_loc', 'best') + legend = plot_args.get('legend', True) + bins = plot_args.get('bins', bins) + color = plot_args.get('color', '') + filename = plot_args.get('filename', None) + xlim = plot_args.get('xlim', None) + + # this could throw an error exposing bad implementation + observation = numpy.array(observation) + + try: + n = len(observation) + except TypeError: + ax.axvline(x=observation, color='black', linestyle='--', + label=obs_label) + + else: + # remove any nan values + observation = observation[~numpy.isnan(observation)] + ax.hist(observation, bins=bins, label=obs_label, edgecolor=None, + linewidth=0) + + # remove any potential nans from arrays + simulated = numpy.array(simulated) + simulated = simulated[~numpy.isnan(simulated)] + + if color: + n, bin_edges, patches = ax.hist(simulated, bins=bins, label=sim_label, + color=color, edgecolor=None, + linewidth=0) + else: + n, bin_edges, patches = ax.hist(simulated, bins=bins, label=sim_label, + edgecolor=None, linewidth=0) + + # color bars for rejection area + if percentile is not None: + inc = (100 - percentile) / 2 + inc_high = 100 - inc + inc_low = inc + p_high = numpy.percentile(simulated, inc_high) + idx_high = numpy.digitize(p_high, bin_edges) + p_low = numpy.percentile(simulated, inc_low) + idx_low = numpy.digitize(p_low, bin_edges) + + # show 99.5% of data + if xlim is None: + upper_xlim = numpy.percentile(simulated, 99.75) + upper_xlim = numpy.max([upper_xlim, numpy.max(observation)]) + d_bin = bin_edges[1] - bin_edges[0] + upper_xlim = upper_xlim + 2 * d_bin + + lower_xlim = numpy.percentile(simulated, 0.25) + lower_xlim = numpy.min([lower_xlim, numpy.min(observation)]) + lower_xlim = lower_xlim - 2 * d_bin + + try: + ax.set_xlim([lower_xlim, upper_xlim]) + except ValueError: + print('Ignoring observation in axis scaling because inf or -inf') + upper_xlim = numpy.percentile(simulated, 99.75) + upper_xlim = upper_xlim + 2 * d_bin + + lower_xlim = numpy.percentile(simulated, 0.25) + lower_xlim = lower_xlim - 2 * d_bin + + ax.set_xlim([lower_xlim, upper_xlim]) + else: + ax.set_xlim(xlim) + + ax.set_title(title) + ax.set_xlabel(xlabel) + ax.set_ylabel(ylabel) + if legend: + ax.legend(loc=legend_loc) + + # hacky workaround for coloring legend, by calling after legend is drawn. + if percentile is not None: + for idx in range(idx_low): + patches[idx].set_fc('red') + for idx in range(idx_high, len(patches)): + patches[idx].set_fc('red') + if filename is not None: + ax.figure.savefig(filename + '.pdf') + ax.figure.savefig(filename + '.png', dpi=300) + if show: + pyplot.show() + return ax + + +def plot_ecdf(x, ecdf, axes=None, xv=None, show=False, plot_args=None): + """ Plots empirical cumulative distribution function. """ + warnings.warn( + "'plot_ecdf' will be removed in a future version of the package.\n" + "If you rely on this functionality, consider switching to a custom ECDF implementation", + DeprecationWarning, + stacklevel=2 + ) + + plot_args = plot_args or {} + # get values from plotting args + sim_label = plot_args.get('sim_label', 'Simulated') + obs_label = plot_args.get('obs_label', 'Observation') + xlabel = plot_args.get('xlabel', 'X') + ylabel = plot_args.get('ylabel', '$P(X \leq x)$') + xycoords = plot_args.get('xycoords', (1.00, 0.40)) + legend_loc = plot_args.get('legend_loc', 'best') + filename = plot_args.get('filename', None) + + # make figure + if axes == None: + fig, ax = pyplot.subplots() + else: + ax = axes + fig = axes.figure + ax.plot(x, ecdf, label=sim_label) + if xv: + ax.axvline(x=xv, color='black', linestyle='--', label=obs_label) + ax.set_xlabel(xlabel) + ax.set_ylabel(ylabel) + ax.legend(loc=legend_loc) + + # if data is not None: + # ax.annotate(str(data), xycoords='axes fraction', xy=xycoords, fontsize=10, annotation_clip=False) + + if filename is not None: + fig.savefig(filename + '.pdf') + fig.savefig(filename + '.png', dpi=300) + + if show: + pyplot.show() + + return ax + + +def plot_magnitude_histogram_dev(ses_data, obs, plot_args, show=False): + warnings.warn( + "'plot_magnitude_histogram_dev' is deprecated and will be removed in version 1.0.\n" + "Please use 'plot_magnitude_instagram' instead.\n" + "See the documentation at:\n" + " https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_magnitude_instagram.html", + DeprecationWarning, + stacklevel=2 + ) + + bin_edges, obs_hist = obs.magnitude_counts(retbins=True) + n_obs = numpy.sum(obs_hist) + event_counts = numpy.sum(ses_data, axis=1) + # normalize all histograms by counts in each + scale = n_obs / event_counts + # use broadcasting + ses_data = ses_data * scale.reshape(-1, 1) + figsize = plot_args.get('figsize', None) + fig = pyplot.figure(figsize=figsize) + ax = fig.gca() + u3etas_median = numpy.median(ses_data, axis=0) + u3etas_low = numpy.percentile(ses_data, 2.5, axis=0) + u3etas_high = numpy.percentile(ses_data, 97.5, axis=0) + u3etas_min = numpy.min(ses_data, axis=0) + u3etas_max = numpy.max(ses_data, axis=0) + u3etas_emax = u3etas_max - u3etas_median + u3etas_emin = u3etas_median - u3etas_min + dmw = bin_edges[1] - bin_edges[0] + bin_edges_plot = bin_edges + dmw / 2 + + # u3etas_emax = u3etas_max + # plot 95% range as rectangles + rectangles = [] + for i in range(len(bin_edges)): + width = dmw / 2 + height = u3etas_high[i] - u3etas_low[i] + xi = bin_edges[i] + width / 2 + yi = u3etas_low[i] + rect = matplotlib.patches.Rectangle((xi, yi), width, height) + rectangles.append(rect) + pc = matplotlib.collections.PatchCollection(rectangles, facecolor='blue', + alpha=0.3, edgecolor='blue') + ax.add_collection(pc) + # plot whiskers + sim_label = plot_args.get('sim_label', 'Simulated Catalogs') + obs_label = plot_args.get('obs_label', 'Observed Catalog') + xlim = plot_args.get('xlim', None) + title = plot_args.get('title', "UCERF3-ETAS Histogram") + filename = plot_args.get('filename', None) + + ax.errorbar(bin_edges_plot, u3etas_median, yerr=[u3etas_emin, u3etas_emax], + xerr=0.8 * dmw / 2, fmt=' ', label=sim_label, + color='blue', alpha=0.7) + ax.plot(bin_edges_plot, obs_hist, '.k', markersize=10, label=obs_label) + ax.legend(loc='upper right') + ax.set_xlim(xlim) + ax.set_xlabel('Magnitude') + ax.set_ylabel('Event count per magnitude bin') + ax.set_title(title) + # ax.annotate(str(comcat), xycoords='axes fraction', xy=xycoords, fontsize=10, annotation_clip=False) + # pyplot.subplots_adjust(right=0.75) + if filename is not None: + fig.savefig(filename + '.pdf') + fig.savefig(filename + '.png', dpi=300) + if show: + pyplot.show() + return ax + + +@wraps(_plot_basemap) +def plot_basemap(*args, **kwargs): + legacy_keys = {"tile_scaling", "apprx", "central_latitude"} + + if any(k in kwargs for k in legacy_keys): + warnings.warn( + "'plot_basemap' was called with deprecated arguments. These options are no longer supported " + "and will be removed in version 1.0.\n\n" + "Please consult the updated documentation at:\n" + " https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_basemap.html\n", + DeprecationWarning, + stacklevel=2 + ) + + return _plot_basemap(*args, **kwargs) + + +def _get_basemap(basemap): + if basemap == 'stamen_terrain': + tiles = img_tiles.Stamen('terrain') + elif basemap == 'stamen_terrain-background': + tiles = img_tiles.Stamen('terrain-background') + elif basemap == 'google-satellite': + tiles = img_tiles.GoogleTiles(style='satellite') + elif basemap == 'ESRI_terrain': + webservice = 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Terrain_Base/' \ + 'MapServer/tile/{z}/{y}/{x}.jpg' + tiles = img_tiles.GoogleTiles(url=webservice) + elif basemap == 'ESRI_imagery': + webservice = 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/' \ + 'MapServer/tile/{z}/{y}/{x}.jpg' + tiles = img_tiles.GoogleTiles(url=webservice) + elif basemap == 'ESRI_relief': + webservice = 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/' \ + 'MapServer/tile/{z}/{y}/{x}.jpg' + tiles = img_tiles.GoogleTiles(url=webservice) + elif basemap == 'ESRI_topo': + webservice = 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/' \ + 'MapServer/tile/{z}/{y}/{x}.jpg' + tiles = img_tiles.GoogleTiles(url=webservice) + else: + try: + webservice = basemap + tiles = img_tiles.GoogleTiles(url=webservice) + except: + raise ValueError('Basemap type not valid or not implemented') + + return tiles + + +def plot_spatial_dataset(gridded, region, ax=None, show=False, extent=None, + set_global=False, plot_args=None, **kwargs): + """ + Legacy-compatible wrapper for plot_gridded_dataset. + """ + from .plots import plot_gridded_dataset + + plot_args = plot_args or {} + warnings.warn( + "'plot_spatial_dataset' is deprecated and will be removed in version 1.0.\n" + "Please use 'plot_gridded_dataset' instead.\n" + "See https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_gridded_dataset.html", + DeprecationWarning, + stacklevel=2 + ) + + return plot_gridded_dataset( + gridded=gridded, + region=region, + ax=ax, + show=show, + extent=extent, + set_global=set_global, + **plot_args, + **kwargs + ) + + +def plot_number_test(evaluation_result, axes=None, show=True, plot_args=None): + """ + Takes result from evaluation and generates a specific histogram plot to show the results of the statistical evaluation + for the n-test. + + + .. deprecated:: 0.7.0 + This function is deprecated and will be removed in version 1.0. + Please use :func:`~csep.utils.plots.plot_test_distribution` instead + + Args: + evaluation_result: object-like var that implements the interface of the above EvaluationResult + axes (matplotlib.Axes): axes object used to chain this plot + show (bool): if true, call pyplot.show() + plot_args(dict): optional argument containing a dictionary of plotting arguments, with keys as strings and items as described below + + Optional plotting arguments: + * figsize: (:class:`list`/:class:`tuple`) - default: [6.4, 4.8] + * title: (:class:`str`) - default: name of the first evaluation result type + * title_fontsize: (:class:`float`) Fontsize of the plot title - default: 10 + * xlabel: (:class:`str`) - default: 'X' + * xlabel_fontsize: (:class:`float`) - default: 10 + * xticks_fontsize: (:class:`float`) - default: 10 + * ylabel_fontsize: (:class:`float`) - default: 10 + * text_fontsize: (:class:`float`) - default: 14 + * tight_layout: (:class:`bool`) Set matplotlib.figure.tight_layout to remove excess blank space in the plot - default: True + * percentile (:class:`float`) Critial region to shade on histogram - default: 95 + * bins: (:class:`str`) - Set binning type. see matplotlib.hist for more info - default: 'auto' + * xy: (:class:`list`/:class:`tuple`) - default: (0.55, 0.3) + + Returns: + ax (matplotlib.axes.Axes): can be used to modify the figure + + """ + warnings.warn( + "'plot_number_test' is deprecated and will be removed in version 1.0.\n" + "Use 'plot_test_distribution' instead.\n" + "Documentation: https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_test_distribution.html", + DeprecationWarning, + stacklevel=2 + ) + # chain plotting axes if requested + if axes: + chained = True + else: + chained = False + + # default plotting arguments + plot_args = plot_args or {} + title = plot_args.get('title', 'Number Test') + title_fontsize = plot_args.get('title_fontsize', None) + xlabel = plot_args.get('xlabel', 'Event count of catalogs') + xlabel_fontsize = plot_args.get('xlabel_fontsize', None) + ylabel = plot_args.get('ylabel', 'Number of catalogs') + ylabel_fontsize = plot_args.get('ylabel_fontsize', None) + text_fontsize = plot_args.get('text_fontsize', 14) + tight_layout = plot_args.get('tight_layout', True) + percentile = plot_args.get('percentile', 95) + filename = plot_args.get('filename', None) + bins = plot_args.get('bins', 'auto') + xy = plot_args.get('xy', (0.5, 0.3)) + + # set default plotting arguments + fixed_plot_args = {'obs_label': evaluation_result.obs_name, + 'sim_label': evaluation_result.sim_name} + plot_args.update(fixed_plot_args) + ax = plot_histogram(evaluation_result.test_distribution, + evaluation_result.observed_statistic, + catalog=evaluation_result.obs_catalog_repr, + plot_args=plot_args, + bins=bins, + axes=axes, + percentile=percentile) + + # annotate plot with p-values + if not chained: + try: + ax.annotate( + '$\delta_1 = P(X \geq x) = {:.2f}$\n$\delta_2 = P(X \leq x) = {:.2f}$\n$\omega = {:d}$' + .format(*evaluation_result.quantile, + evaluation_result.observed_statistic), + xycoords='axes fraction', + xy=xy, + fontsize=text_fontsize) + except: + ax.annotate('$\gamma = P(X \leq x) = {:.2f}$\n$\omega = {:.2f}$' + .format(evaluation_result.quantile, + evaluation_result.observed_statistic), + xycoords='axes fraction', + xy=xy, + fontsize=text_fontsize) + + ax.set_title(title, fontsize=title_fontsize) + ax.set_xlabel(xlabel, fontsize=xlabel_fontsize) + ax.set_ylabel(ylabel, fontsize=ylabel_fontsize) + + if tight_layout: + ax.figure.tight_layout() + + if filename is not None: + ax.figure.savefig(filename + '.pdf') + ax.figure.savefig(filename + '.png', dpi=300) + + # func has different return types, before release refactor and remove plotting from evaluation. + # plotting should be separated from evaluation. + # evaluation should return some object that can be plotted maybe with verbose option. + if show: + pyplot.show() + + return ax + + +def plot_magnitude_test(evaluation_result, axes=None, show=True, + plot_args=None): + """ + Takes result from evaluation and generates a specific histogram plot to show the results of the statistical evaluation + for the M-test. + + .. deprecated:: 0.7.0 + This function is deprecated and will be removed in version 1.0. + Please use :func:`~csep.utils.plots.plot_test_distribution` instead + + Args: + evaluation_result: object-like var that implements the interface of the above EvaluationResult + axes (matplotlib.Axes): axes object used to chain this plot + show (bool): if true, call pyplot.show() + plot_args(dict): optional argument containing a dictionary of plotting arguments, with keys as strings and items as described below + + Optional plotting arguments: + * figsize: (:class:`list`/:class:`tuple`) - default: [6.4, 4.8] + * title: (:class:`str`) - default: name of the first evaluation result type + * title_fontsize: (:class:`float`) Fontsize of the plot title - default: 10 + * xlabel: (:class:`str`) - default: 'X' + * xlabel_fontsize: (:class:`float`) - default: 10 + * xticks_fontsize: (:class:`float`) - default: 10 + * ylabel_fontsize: (:class:`float`) - default: 10 + * tight_layout: (:class:`bool`) Set matplotlib.figure.tight_layout to remove excess blank space in the plot - default: True + * percentile (:class:`float`) Critial region to shade on histogram - default: 95 + * bins: (:class:`str`) - Set binning type. see matplotlib.hist for more info - default: 'auto' + * xy: (:class:`list`/:class:`tuple`) - default: (0.55, 0.6) + + Returns: + ax (matplotlib.Axes): containing the new plot + + """ + warnings.warn( + "'plot_magnitude_test' is deprecated and will be removed in version 1.0.\n" + "Use 'plot_test_distribution' instead.\n" + "Documentation: https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_test_distribution.html", + DeprecationWarning, + stacklevel=2 + ) + plot_args = plot_args or {} + title = plot_args.get('title', 'Magnitude Test') + title_fontsize = plot_args.get('title_fontsize', None) + xlabel = plot_args.get('xlabel', 'D* Statistic') + xlabel_fontsize = plot_args.get('xlabel_fontsize', None) + ylabel = plot_args.get('ylabel', 'Number of catalogs') + ylabel_fontsize = plot_args.get('ylabel_fontsize', None) + tight_layout = plot_args.get('tight_layout', True) + percentile = plot_args.get('percentile', 95) + text_fontsize = plot_args.get('text_fontsize', 14) + filename = plot_args.get('filename', None) + bins = plot_args.get('bins', 'auto') + xy = plot_args.get('xy', (0.55, 0.6)) + + # handle plotting + if axes: + chained = True + else: + chained = False + + # supply fixed arguments to plots + # might want to add other defaults here + fixed_plot_args = {'obs_label': evaluation_result.obs_name, + 'sim_label': evaluation_result.sim_name} + plot_args.update(fixed_plot_args) + ax = plot_histogram(evaluation_result.test_distribution, + evaluation_result.observed_statistic, + catalog=evaluation_result.obs_catalog_repr, + plot_args=plot_args, + bins=bins, + axes=axes, + percentile=percentile) + + # annotate plot with quantile values + if not chained: + try: + ax.annotate('$\gamma = P(X \geq x) = {:.2f}$\n$\omega = {:.2f}$' + .format(evaluation_result.quantile, + evaluation_result.observed_statistic), + xycoords='axes fraction', + xy=xy, + fontsize=text_fontsize) + except TypeError: + # if both quantiles are provided, we want to plot the greater-equal quantile + ax.annotate('$\gamma = P(X \geq x) = {:.2f}$\n$\omega = {:.2f}$' + .format(evaluation_result.quantile[0], + evaluation_result.observed_statistic), + xycoords='axes fraction', + xy=xy, + fontsize=text_fontsize) + + ax.set_title(title, fontsize=title_fontsize) + ax.set_xlabel(xlabel, fontsize=xlabel_fontsize) + ax.set_ylabel(ylabel, fontsize=ylabel_fontsize) + + if tight_layout: + var = ax.get_figure().tight_layout + () + + if filename is not None: + ax.figure.savefig(filename + '.pdf') + ax.figure.savefig(filename + '.png', dpi=300) + + # func has different return types, before release refactor and remove plotting from evaluation. + # plotting should be separated from evaluation. + # evaluation should return some object that can be plotted maybe with verbose option. + if show: + pyplot.show() + + return ax + + +def plot_distribution_test(evaluation_result, axes=None, show=True, + plot_args=None): + """ + Takes result from evaluation and generates a specific histogram plot to show the results of the statistical evaluation + for the M-test. + + .. deprecated:: 0.7.0 + This function is deprecated and will be removed in version 1.0. + Please use :func:`~csep.utils.plots.plot_test_distribution` instead + + Args: + evaluation_result: object-like var that implements the interface of the above EvaluationResult + + Returns: + ax (matplotlib.axes.Axes): can be used to modify the figure + + """ + warnings.warn( + "'plot_distribution_test' is deprecated and will be removed in version 1.0.\n" + "Use 'plot_test_distribution' instead.\n" + "Documentation: https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_test_distribution.html", + DeprecationWarning, + stacklevel=2 + ) + plot_args = plot_args or {} + # handle plotting + if axes: + chained = True + else: + chained = False + # supply fixed arguments to plots + # might want to add other defaults here + filename = plot_args.get('filename', None) + xlabel = plot_args.get('xlabel', '') + ylabel = plot_args.get('ylabel', '') + fixed_plot_args = {'obs_label': evaluation_result.obs_name, + 'sim_label': evaluation_result.sim_name} + plot_args.update(fixed_plot_args) + bins = plot_args.get('bins', 'auto') + percentile = plot_args.get('percentile', 95) + ax = plot_histogram(evaluation_result.test_distribution, + evaluation_result.observed_statistic, + catalog=evaluation_result.obs_catalog_repr, + plot_args=plot_args, + bins=bins, + axes=axes, + percentile=percentile) + + # annotate plot with p-values + if not chained: + ax.annotate('$\gamma = P(X \leq x) = {:.3f}$\n$\omega$ = {:.3f}' + .format(evaluation_result.quantile, + evaluation_result.observed_statistic), + xycoords='axes fraction', + xy=(0.5, 0.3), + fontsize=14) + + title = plot_args.get('title', evaluation_result.name) + ax.set_title(title, fontsize=14) + ax.set_xlabel(xlabel) + ax.set_ylabel(ylabel) + + if filename is not None: + ax.figure.savefig(filename + '.pdf') + ax.figure.savefig(filename + '.png', dpi=300) + + # func has different return types, before release refactor and remove plotting from evaluation. + # plotting should be separated from evaluation. + # evaluation should return some object that can be plotted maybe with verbose option. + if show: + pyplot.show() + + return ax + + +def plot_likelihood_test(evaluation_result, axes=None, show=True, + plot_args=None): + """ + Takes result from evaluation and generates a specific histogram plot to show the results of the statistical evaluation for the L-test. + + + .. deprecated:: 0.7.0 + This function is deprecated and will be removed in version 1.0. + Please use :func:`~csep.utils.plots.plot_test_distribution` instead. + + Args: + evaluation_result: object-like var that implements the interface of the above EvaluationResult + axes (matplotlib.Axes): axes object used to chain this plot + show (bool): if true, call pyplot.show() + plot_args(dict): optional argument containing a dictionary of plotting arguments, with keys as strings and items as described below + + Optional plotting arguments: + * figsize: (:class:`list`/:class:`tuple`) - default: [6.4, 4.8] + * title: (:class:`str`) - default: name of the first evaluation result type + * title_fontsize: (:class:`float`) Fontsize of the plot title - default: 10 + * xlabel: (:class:`str`) - default: 'X' + * xlabel_fontsize: (:class:`float`) - default: 10 + * xticks_fontsize: (:class:`float`) - default: 10 + * ylabel_fontsize: (:class:`float`) - default: 10 + * text_fontsize: (:class:`float`) - default: 14 + * tight_layout: (:class:`bool`) Set matplotlib.figure.tight_layout to remove excess blank space in the plot - default: True + * percentile (:class:`float`) Critial region to shade on histogram - default: 95 + * bins: (:class:`str`) - Set binning type. see matplotlib.hist for more info - default: 'auto' + * xy: (:class:`list`/:class:`tuple`) - default: (0.55, 0.3) + + Returns: + ax (matplotlib.axes.Axes): can be used to modify the figure + """ + warnings.warn( + "'plot_likelihood_test' is deprecated and will be removed in version 1.0.\n" + "Use 'plot_test_distribution' instead.\n" + "Documentation: https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_test_distribution.html", + DeprecationWarning, + stacklevel=2 + ) + plot_args = plot_args or {} + title = plot_args.get('title', 'Pseudo-likelihood Test') + title_fontsize = plot_args.get('title_fontsize', None) + xlabel = plot_args.get('xlabel', 'Pseudo likelihood') + xlabel_fontsize = plot_args.get('xlabel_fontsize', None) + ylabel = plot_args.get('ylabel', 'Number of catalogs') + ylabel_fontsize = plot_args.get('ylabel_fontsize', None) + text_fontsize = plot_args.get('text_fontsize', 14) + tight_layout = plot_args.get('tight_layout', True) + percentile = plot_args.get('percentile', 95) + filename = plot_args.get('filename', None) + bins = plot_args.get('bins', 'auto') + xy = plot_args.get('xy', (0.55, 0.3)) + + # handle plotting + if axes: + chained = True + else: + chained = False + # supply fixed arguments to plots + # might want to add other defaults here + fixed_plot_args = {'obs_label': evaluation_result.obs_name, + 'sim_label': evaluation_result.sim_name} + plot_args.update(fixed_plot_args) + ax = plot_histogram(evaluation_result.test_distribution, + evaluation_result.observed_statistic, + catalog=evaluation_result.obs_catalog_repr, + plot_args=plot_args, + bins=bins, + axes=axes, + percentile=percentile) + + # annotate plot with p-values + if not chained: + try: + ax.annotate('$\gamma = P(X \leq x) = {:.2f}$\n$\omega = {:.2f}$' + .format(evaluation_result.quantile, + evaluation_result.observed_statistic), + xycoords='axes fraction', + xy=xy, + fontsize=text_fontsize) + except TypeError: + # if both quantiles are provided, we want to plot the greater-equal quantile + ax.annotate('$\gamma = P(X \leq x) = {:.2f}$\n$\omega = {:.2f}$' + .format(evaluation_result.quantile[1], + evaluation_result.observed_statistic), + xycoords='axes fraction', + xy=xy, + fontsize=text_fontsize) + + ax.set_title(title, fontsize=title_fontsize) + ax.set_xlabel(xlabel, fontsize=xlabel_fontsize) + ax.set_ylabel(ylabel, fontsize=ylabel_fontsize) + + if tight_layout: + ax.figure.tight_layout() + + if filename is not None: + ax.figure.savefig(filename + '.pdf') + ax.figure.savefig(filename + '.png', dpi=300) + + # func has different return types, before release refactor and remove plotting from evaluation. + # plotting should be separated from evaluation. + # evaluation should return some object that can be plotted maybe with verbose option. + if show: + pyplot.show() + return ax + + +def plot_spatial_test(evaluation_result, axes=None, plot_args=None, show=True): + """ + Plot spatial test result from catalog based forecast + + .. deprecated:: 0.7.0 + This function is deprecated and will be removed in version 1.0. + Please use :func:`~csep.utils.plots.plot_test_distribution` instead + + + Args: + evaluation_result: object-like var that implements the interface of the above EvaluationResult + axes (matplotlib.Axes): axes object used to chain this plot + show (bool): if true, call pyplot.show() + plot_args(dict): optional argument containing a dictionary of plotting arguments, with keys as strings and items as described below + + Optional plotting arguments: + * figsize: (:class:`list`/:class:`tuple`) - default: [6.4, 4.8] + * title: (:class:`str`) - default: name of the first evaluation result type + * title_fontsize: (:class:`float`) Fontsize of the plot title - default: 10 + * xlabel: (:class:`str`) - default: 'X' + * xlabel_fontsize: (:class:`float`) - default: 10 + * xticks_fontsize: (:class:`float`) - default: 10 + * ylabel_fontsize: (:class:`float`) - default: 10 + * text_fontsize: (:class:`float`) - default: 14 + * tight_layout: (:class:`bool`) Set matplotlib.figure.tight_layout to remove excess blank space in the plot - default: True + * percentile (:class:`float`) Critial region to shade on histogram - default: 95 + * bins: (:class:`str`) - Set binning type. see matplotlib.hist for more info - default: 'auto' + * xy: (:class:`list`/:class:`tuple`) - default: (0.2, 0.6) + + Returns: + ax (matplotlib.axes.Axes): can be used to modify the figure + """ + warnings.warn( + "'plot_spatial_test' is deprecated and will be removed in version 1.0.\n" + "Use 'plot_test_distribution' instead.\n" + "Documentation: https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_test_distribution.html", + DeprecationWarning, + stacklevel=2 + ) + plot_args = plot_args or {} + title = plot_args.get('title', 'Spatial Test') + title_fontsize = plot_args.get('title_fontsize', None) + xlabel = plot_args.get('xlabel', 'Normalized pseudo-likelihood') + xlabel_fontsize = plot_args.get('xlabel_fontsize', None) + ylabel = plot_args.get('ylabel', 'Number of catalogs') + ylabel_fontsize = plot_args.get('ylabel_fontsize', None) + text_fontsize = plot_args.get('text_fontsize', 14) + tight_layout = plot_args.get('tight_layout', True) + percentile = plot_args.get('percentile', 95) + filename = plot_args.get('filename', None) + bins = plot_args.get('bins', 'auto') + xy = plot_args.get('xy', (0.2, 0.6)) + + # handle plotting + if axes: + chained = True + else: + chained = False + + # supply fixed arguments to plots + # might want to add other defaults here + fixed_plot_args = {'obs_label': evaluation_result.obs_name, + 'sim_label': evaluation_result.sim_name} + plot_args.update(fixed_plot_args) + + ax = plot_histogram(evaluation_result.test_distribution, + evaluation_result.observed_statistic, + catalog=evaluation_result.obs_catalog_repr, + plot_args=plot_args, + bins=bins, + axes=axes, + percentile=percentile) + + # annotate plot with p-values + if not chained: + try: + ax.annotate('$\gamma = P(X \leq x) = {:.2f}$\n$\omega = {:.2f}$' + .format(evaluation_result.quantile, + evaluation_result.observed_statistic), + xycoords='axes fraction', + xy=xy, + fontsize=text_fontsize) + except TypeError: + # if both quantiles are provided, we want to plot the greater-equal quantile + ax.annotate('$\gamma = P(X \leq x) = {:.2f}$\n$\omega = {:.2f}$' + .format(evaluation_result.quantile[1], + evaluation_result.observed_statistic), + xycoords='axes fraction', + xy=xy, + fontsize=text_fontsize) + + ax.set_title(title, fontsize=title_fontsize) + ax.set_xlabel(xlabel, fontsize=xlabel_fontsize) + ax.set_ylabel(ylabel, fontsize=ylabel_fontsize) + + if tight_layout: + ax.figure.tight_layout() + + if filename is not None: + ax.figure.savefig(filename + '.pdf') + ax.figure.savefig(filename + '.png', dpi=300) + + # func has different return types, before release refactor and remove plotting from evaluation. + # plotting should be separated from evaluation. + # evaluation should return some object that can be plotted maybe with verbose option. + if show: + pyplot.show() + + return ax + + + +def plot_poisson_consistency_test(eval_results, normalize=False, + one_sided_lower=False, axes=None, + plot_args=None, show=False): + """ Plots results from CSEP1 tests following the CSEP1 convention. + + .. deprecated:: 0.7.0 + This function is deprecated and will be removed in version 1.0. + Please use :func:`~csep.utils.plots.plot_consistency_test` instead + + Note: All of the evaluations should be from the same type of evaluation, otherwise the results will not be + comparable on the same figure. + + Args: + results (list): Contains the tests results :class:`csep.core.evaluations.EvaluationResult` (see note above) + normalize (bool): select this if the forecast likelihood should be normalized by the observed likelihood. useful + for plotting simulation based simulation tests. + one_sided_lower (bool): select this if the plot should be for a one sided test + plot_args(dict): optional argument containing a dictionary of plotting arguments, with keys as strings and items as described below + + Optional plotting arguments: + * figsize: (:class:`list`/:class:`tuple`) - default: [6.4, 4.8] + * title: (:class:`str`) - default: name of the first evaluation result type + * title_fontsize: (:class:`float`) Fontsize of the plot title - default: 10 + * xlabel: (:class:`str`) - default: 'X' + * xlabel_fontsize: (:class:`float`) - default: 10 + * xticks_fontsize: (:class:`float`) - default: 10 + * ylabel_fontsize: (:class:`float`) - default: 10 + * color: (:class:`float`/:class:`None`) If None, sets it to red/green according to :func:`_get_marker_style` - default: 'black' + * linewidth: (:class:`float`) - default: 1.5 + * capsize: (:class:`float`) - default: 4 + * hbars: (:class:`bool`) Flag to draw horizontal bars for each model - default: True + * tight_layout: (:class:`bool`) Set matplotlib.figure.tight_layout to remove excess blank space in the plot - default: True + + Returns: + ax (:class:`matplotlib.pyplot.axes` object) + """ + warnings.warn( + "'plot_spatial_test' is deprecated and will be removed in version 1.0.\n" + "Use 'plot_test_distribution' instead.\n" + "Documentation: https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_consistency_test.html", + DeprecationWarning, + stacklevel=2 + ) + try: + results = list(eval_results) + except TypeError: + results = [eval_results] + results.reverse() + # Parse plot arguments. More can be added here + if plot_args is None: + plot_args = {} + figsize = plot_args.get('figsize', None) + title = plot_args.get('title', results[0].name) + title_fontsize = plot_args.get('title_fontsize', None) + xlabel = plot_args.get('xlabel', '') + xlabel_fontsize = plot_args.get('xlabel_fontsize', None) + xticks_fontsize = plot_args.get('xticks_fontsize', None) + ylabel_fontsize = plot_args.get('ylabel_fontsize', None) + color = plot_args.get('color', 'black') + linewidth = plot_args.get('linewidth', None) + capsize = plot_args.get('capsize', 4) + hbars = plot_args.get('hbars', True) + tight_layout = plot_args.get('tight_layout', True) + percentile = plot_args.get('percentile', 95) + plot_mean = plot_args.get('mean', False) + + if axes is None: + fig, ax = pyplot.subplots(figsize=figsize) + else: + ax = axes + fig = ax.get_figure() + + xlims = [] + for index, res in enumerate(results): + # handle analytical distributions first, they are all in the form ['name', parameters]. + if res.test_distribution[0] == 'poisson': + plow = scipy.stats.poisson.ppf((1 - percentile / 100.) / 2., + res.test_distribution[1]) + phigh = scipy.stats.poisson.ppf(1 - (1 - percentile / 100.) / 2., + res.test_distribution[1]) + mean = res.test_distribution[1] + observed_statistic = res.observed_statistic + # empirical distributions + else: + if normalize: + test_distribution = numpy.array( + res.test_distribution) - res.observed_statistic + observed_statistic = 0 + else: + test_distribution = numpy.array(res.test_distribution) + observed_statistic = res.observed_statistic + # compute distribution depending on type of test + if one_sided_lower: + plow = numpy.percentile(test_distribution, 100 - percentile) + phigh = numpy.percentile(test_distribution, 100) + else: + plow = numpy.percentile(test_distribution, + (100 - percentile) / 2.) + phigh = numpy.percentile(test_distribution, + 100 - (100 - percentile) / 2.) + mean = numpy.mean(test_distribution) + + if not numpy.isinf( + observed_statistic): # Check if test result does not diverges + percentile_lims = numpy.abs(numpy.array([[mean - plow, + phigh - mean]]).T) + ax.plot(observed_statistic, index, + _get_marker_style(observed_statistic, (plow, phigh), + one_sided_lower)) + ax.errorbar(mean, index, xerr=percentile_lims, + fmt='ko' * plot_mean, capsize=capsize, + linewidth=linewidth, ecolor=color) + # determine the limits to use + xlims.append((plow, phigh, observed_statistic)) + # we want to only extent the distribution where it falls outside of it in the acceptable tail + if one_sided_lower: + if observed_statistic >= plow and phigh < observed_statistic: + # draw dashed line to infinity + xt = numpy.linspace(phigh, 99999, 100) + yt = numpy.ones(100) * index + ax.plot(xt, yt, linestyle='--', linewidth=linewidth, + color=color) + + else: + print('Observed statistic diverges for forecast %s, index %i.' + ' Check for zero-valued bins within the forecast' % ( + res.sim_name, index)) + ax.barh(index, 99999, left=-10000, height=1, color=['red'], + alpha=0.5) + + try: + ax.set_xlim(*_get_axis_limits(xlims)) + except ValueError: + raise ValueError('All EvaluationResults have infinite ' + 'observed_statistics') + ax.set_yticks(numpy.arange(len(results))) + ax.set_yticklabels([res.sim_name for res in results], + fontsize=ylabel_fontsize) + ax.set_ylim([-0.5, len(results) - 0.5]) + if hbars: + yTickPos = ax.get_yticks() + if len(yTickPos) >= 2: + ax.barh(yTickPos, numpy.array([99999] * len(yTickPos)), + left=-10000, + height=(yTickPos[1] - yTickPos[0]), color=['w', 'gray'], + alpha=0.2, zorder=0) + ax.set_title(title, fontsize=title_fontsize) + ax.set_xlabel(xlabel, fontsize=xlabel_fontsize) + ax.tick_params(axis='x', labelsize=xticks_fontsize) + if tight_layout: + ax.figure.tight_layout() + fig.tight_layout() + + if show: + pyplot.show() + + return ax + +def _get_marker_style(obs_stat, p, one_sided_lower): + """Returns matplotlib marker style as fmt string""" + if obs_stat < p[0] or obs_stat > p[1]: + # red circle + fmt = 'ro' + else: + # green square + fmt = 'gs' + if one_sided_lower: + if obs_stat < p[0]: + fmt = 'ro' + else: + fmt = 'gs' + return fmt + + +def _get_axis_limits(pnts, border=0.05): + """Returns a tuple of x_min and x_max given points on plot.""" + x_min = numpy.min(pnts) + x_max = numpy.max(pnts) + xd = (x_max - x_min) * border + return (x_min - xd, x_max + xd) + + + +@wraps(_plot_comparison_test) +def plot_comparison_test(*args, **kwargs): + if 'axes' in kwargs: + warnings.warn( + "'plot_comparison_test' was called using the legacy 'axes' argument, which is deprecated.\n" + "Please update your call to use:\n" + " plot_comparison_test(..., ax=, ...)\n\n" + "For documentation, see:\n" + " https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_comparison_test.html", + DeprecationWarning, + stacklevel=2 + ) + kwargs['ax'] = kwargs.pop('axes') + + return _plot_comparison_test(*args, **kwargs) + +def _get_marker_t_color(distribution): + """Returns matplotlib marker style as fmt string""" + if distribution[0] > 0. and distribution[1] > 0.: + fmt = 'green' + elif distribution[0] < 0. and distribution[1] < 0.: + fmt = 'red' + else: + fmt = 'grey' + + return fmt + + +def _get_marker_w_color(distribution, percentile): + """Returns matplotlib marker style as fmt string""" + + if distribution < (1 - percentile / 100): + fmt = True + else: + fmt = False + + return fmt + + +@wraps(_plot_consistency_test) +def plot_consistency_test(*args, **kwargs): + """ + Legacy-compatible wrapper for plot_consistency_test. + + Detects deprecated usage (e.g., 'plot_args', 'axes') and falls back to legacy logic. + """ + is_legacy_call = False + + # Detect legacy-style call (e.g., positional or 'plot_args' / 'axes' / 'variance') + if len(args) > 1 or any(k in kwargs for k in ("plot_args", "axes", "variance")): + is_legacy_call = True + + if is_legacy_call: + warnings.warn( + "'plot_consistency_test' was called using deprecated arguments and will fall back to legacy behavior.\n" + "This fallback is deprecated and will be removed in version 1.0.\n" + "Please update your usage to the new function signature:\n" + " plot_consistency_test(eval_results, normalize=False, one_sided_lower=False, percentile=95, ...)\n\n" + "Refer to the updated documentation:\n" + " https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_consistency_test.html", + DeprecationWarning, + stacklevel=2 + ) + return _plot_consistency_test_legacy_impl(*args, **kwargs) + + return _plot_consistency_test(*args, **kwargs) + +def _plot_consistency_test_legacy_impl(eval_results, normalize=False, axes=None, + one_sided_lower=False, variance=None, plot_args=None, + show=False): + """ Plots results from CSEP1 tests following the CSEP1 convention. + + Note: All of the evaluations should be from the same type of evaluation, otherwise the results will not be + comparable on the same figure. + + Args: + eval_results (list): Contains the tests results :class:`csep.core.evaluations.EvaluationResult` (see note above) + normalize (bool): select this if the forecast likelihood should be normalized by the observed likelihood. useful + for plotting simulation based simulation tests. + one_sided_lower (bool): select this if the plot should be for a one sided test + plot_args(dict): optional argument containing a dictionary of plotting arguments, with keys as strings and items as described below + + Optional plotting arguments: + * figsize: (:class:`list`/:class:`tuple`) - default: [6.4, 4.8] + * title: (:class:`str`) - default: name of the first evaluation result type + * title_fontsize: (:class:`float`) Fontsize of the plot title - default: 10 + * xlabel: (:class:`str`) - default: 'X' + * xlabel_fontsize: (:class:`float`) - default: 10 + * xticks_fontsize: (:class:`float`) - default: 10 + * ylabel_fontsize: (:class:`float`) - default: 10 + * color: (:class:`float`/:class:`None`) If None, sets it to red/green according to :func:`_get_marker_style` - default: 'black' + * linewidth: (:class:`float`) - default: 1.5 + * capsize: (:class:`float`) - default: 4 + * hbars: (:class:`bool`) Flag to draw horizontal bars for each model - default: True + * tight_layout: (:class:`bool`) Set matplotlib.figure.tight_layout to remove excess blank space in the plot - default: True + + Returns: + ax (:class:`matplotlib.pyplot.axes` object) + """ + + try: + results = list(eval_results) + except TypeError: + results = [eval_results] + results.reverse() + # Parse plot arguments. More can be added here + if plot_args is None: + plot_args = {} + figsize = plot_args.get('figsize', None) + title = plot_args.get('title', results[0].name) + title_fontsize = plot_args.get('title_fontsize', None) + xlabel = plot_args.get('xlabel', '') + xlabel_fontsize = plot_args.get('xlabel_fontsize', None) + xticks_fontsize = plot_args.get('xticks_fontsize', None) + ylabel_fontsize = plot_args.get('ylabel_fontsize', None) + color = plot_args.get('color', 'black') + linewidth = plot_args.get('linewidth', None) + capsize = plot_args.get('capsize', 4) + hbars = plot_args.get('hbars', True) + tight_layout = plot_args.get('tight_layout', True) + percentile = plot_args.get('percentile', 95) + plot_mean = plot_args.get('mean', False) + + if axes is None: + fig, ax = pyplot.subplots(figsize=figsize) + else: + ax = axes + fig = ax.get_figure() + + xlims = [] + + for index, res in enumerate(results): + # handle analytical distributions first, they are all in the form ['name', parameters]. + if res.test_distribution[0] == 'poisson': + plow = scipy.stats.poisson.ppf((1 - percentile / 100.) / 2., + res.test_distribution[1]) + phigh = scipy.stats.poisson.ppf(1 - (1 - percentile / 100.) / 2., + res.test_distribution[1]) + mean = res.test_distribution[1] + observed_statistic = res.observed_statistic + + elif res.test_distribution[0] == 'negative_binomial': + var = variance + observed_statistic = res.observed_statistic + mean = res.test_distribution[1] + upsilon = 1.0 - ((var - mean) / var) + tau = (mean ** 2 / (var - mean)) + plow = scipy.stats.nbinom.ppf((1 - percentile / 100.) / 2., tau, + upsilon) + phigh = scipy.stats.nbinom.ppf(1 - (1 - percentile / 100.) / 2., + tau, upsilon) + + # empirical distributions + else: + if normalize: + test_distribution = numpy.array( + res.test_distribution) - res.observed_statistic + observed_statistic = 0 + else: + test_distribution = numpy.array(res.test_distribution) + observed_statistic = res.observed_statistic + # compute distribution depending on type of test + if one_sided_lower: + plow = numpy.percentile(test_distribution, 5) + phigh = numpy.percentile(test_distribution, 100) + else: + plow = numpy.percentile(test_distribution, 2.5) + phigh = numpy.percentile(test_distribution, 97.5) + mean = numpy.mean(res.test_distribution) + + if not numpy.isinf( + observed_statistic): # Check if test result does not diverges + percentile_lims = numpy.array([[mean - plow, phigh - mean]]).T + ax.plot(observed_statistic, index, + _get_marker_style(observed_statistic, (plow, phigh), + one_sided_lower)) + ax.errorbar(mean, index, xerr=percentile_lims, + fmt='ko' * plot_mean, capsize=capsize, + linewidth=linewidth, ecolor=color) + # determine the limits to use + xlims.append((plow, phigh, observed_statistic)) + # we want to only extent the distribution where it falls outside of it in the acceptable tail + if one_sided_lower: + if observed_statistic >= plow and phigh < observed_statistic: + # draw dashed line to infinity + xt = numpy.linspace(phigh, 99999, 100) + yt = numpy.ones(100) * index + ax.plot(xt, yt, linestyle='--', linewidth=linewidth, + color=color) + + else: + print('Observed statistic diverges for forecast %s, index %i.' + ' Check for zero-valued bins within the forecast' % ( + res.sim_name, index)) + ax.barh(index, 99999, left=-10000, height=1, color=['red'], + alpha=0.5) + + try: + ax.set_xlim(*_get_axis_limits(xlims)) + except ValueError: + raise ValueError( + 'All EvaluationResults have infinite observed_statistics') + ax.set_yticks(numpy.arange(len(results))) + ax.set_yticklabels([res.sim_name for res in results], + fontsize=ylabel_fontsize) + ax.set_ylim([-0.5, len(results) - 0.5]) + if hbars: + yTickPos = ax.get_yticks() + if len(yTickPos) >= 2: + ax.barh(yTickPos, numpy.array([99999] * len(yTickPos)), + left=-10000, + height=(yTickPos[1] - yTickPos[0]), color=['w', 'gray'], + alpha=0.2, zorder=0) + ax.set_title(title, fontsize=title_fontsize) + ax.set_xlabel(xlabel, fontsize=xlabel_fontsize) + ax.tick_params(axis='x', labelsize=xticks_fontsize) + if tight_layout: + ax.figure.tight_layout() + fig.tight_layout() + + if show: + pyplot.show() + + return ax + + +@wraps(_plot_concentration_ROC_diagram) +def plot_concentration_ROC_diagram(*args, **kwargs): + """ + Backward-compatible wrapper for `plot_ROC_diagram`. + + Supports legacy arguments like 'axes' and 'plot_args'. Will be removed in version 1.0. + """ + is_legacy_call = False + + if 'axes' in kwargs: + is_legacy_call = True + kwargs['ax'] = kwargs.pop('axes') + + if 'plot_args' in kwargs: + is_legacy_call = True + kwargs.update(kwargs.pop('plot_args')) + + if is_legacy_call: + warnings.warn( + "'plot_concentration_ROC_diagram' was called with legacy-style arguments (e.g. 'axes', 'plot_args').\n" + "As of version 0.7.0, this usage is deprecated and will be removed in version 1.0.\n\n" + "Please update your call to use keyword arguments directly, e.g.:\n" + " plot_ROC_diagram(..., ax=, ...)\n\n" + "Documentation:\n" + " https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_ROC_diagram.html", + DeprecationWarning, + stacklevel=2 + ) + + return _plot_concentration_ROC_diagram(*args, **kwargs) + + +@wraps(_plot_ROC_diagram) +def plot_ROC_diagram(*args, **kwargs): + """ + Backward-compatible wrapper for `plot_ROC_diagram`. + + Supports legacy arguments like 'axes' and 'plot_args'. Will be removed in version 1.0. + """ + is_legacy_call = False + + if 'axes' in kwargs: + is_legacy_call = True + kwargs['ax'] = kwargs.pop('axes') + + if 'plot_args' in kwargs: + is_legacy_call = True + kwargs.update(kwargs.pop('plot_args')) + + if is_legacy_call: + warnings.warn( + "'plot_ROC_diagram' was called with legacy-style arguments (e.g. 'axes', 'plot_args').\n" + "As of version 0.7.0, this usage is deprecated and will be removed in version 1.0.\n\n" + "Please update your call to use keyword arguments directly, e.g.:\n" + " plot_ROC_diagram(..., ax=,...)\n\n" + "Documentation:\n" + " https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_ROC_diagram.html", + DeprecationWarning, + stacklevel=2 + ) + + return _plot_ROC_diagram(*args, **kwargs) + + +@wraps(_plot_Molchan_diagram) +def plot_Molchan_diagram(*args, **kwargs): + """ + Backward-compatible wrapper for `plot_Molchan_diagram`. + + Supports legacy arguments like 'axes' and 'plot_args'. Will be removed in version 1.0. + """ + is_legacy_call = False + + if 'axes' in kwargs: + is_legacy_call = True + kwargs['ax'] = kwargs.pop('axes') + + if 'plot_args' in kwargs: + is_legacy_call = True + kwargs.update(kwargs.pop('plot_args')) + + if is_legacy_call: + warnings.warn( + "'plot_Molchan_diagram' was called with legacy-style arguments (e.g. 'axes', 'plot_args').\n" + "As of version 0.7.0, this usage is deprecated and will be removed in version 1.0.\n\n" + "Please update your call to use keyword arguments directly, e.g.:\n" + " plot_Molchan_diagram(..., ax=, ...)\n\n" + "Documentation:\n" + " https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_Molchan_diagram.html", + DeprecationWarning, + stacklevel=2 + ) + + return _plot_Molchan_diagram(*args, **kwargs) + + +def plot_pvalues_and_intervals(test_results, ax, var=None): + """ Plots p-values and intervals for a list of Poisson or NBD test results + + Args: + test_results (list): list of EvaluationResults for N-test. All tests should use the same distribution (ie Poisson or NBD). + ax (matplotlib.axes.Axes.axis): axes to use for plot. create using matplotlib + var (float): variance of the NBD distribution. Must be used for NBD plots. + + Returns: + ax (matplotlib.axes.Axes.axis): axes handle containing this plot + + Raises: + ValueError: throws error if NBD tests are supplied without a variance + """ + warnings.warn( + "'plot_pvalues_and_intervals' is being modified for version 1.0.\n" + "Refer to the documentation:\n" + " https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_pvalues_and_intervals.html", + DeprecationWarning, + stacklevel=2 + ) + variance = var + percentile = 97.5 + p_values = [] + + # Differentiate between N-tests and other consistency tests + if test_results[0].name == 'NBD N-Test' or test_results[ + 0].name == 'Poisson N-Test': + legend_elements = [ + matplotlib.lines.Line2D([0], [0], marker='o', color='red', lw=0, + label=r'p < 10e-5', markersize=10, + markeredgecolor='k'), + matplotlib.lines.Line2D([0], [0], marker='o', color='#FF7F50', + lw=0, label=r'10e-5 $\leq$ p < 10e-4', + markersize=10, markeredgecolor='k'), + matplotlib.lines.Line2D([0], [0], marker='o', color='gold', lw=0, + label=r'10e-4 $\leq$ p < 10e-3', + markersize=10, markeredgecolor='k'), + matplotlib.lines.Line2D([0], [0], marker='o', color='white', lw=0, + label=r'10e-3 $\leq$ p < 0.0125', + markersize=10, markeredgecolor='k'), + matplotlib.lines.Line2D([0], [0], marker='o', color='skyblue', + lw=0, label=r'0.0125 $\leq$ p < 0.025', + markersize=10, markeredgecolor='k'), + matplotlib.lines.Line2D([0], [0], marker='o', color='blue', lw=0, + label=r'p $\geq$ 0.025', markersize=10, + markeredgecolor='k')] + ax.legend(handles=legend_elements, loc=4, fontsize=13, edgecolor='k') + # Act on Negative binomial tests + if test_results[0].name == 'NBD N-Test': + if var is None: + raise ValueError( + "var must not be None if N-tests use the NBD distribution.") + + for i in range(len(test_results)): + mean = test_results[i].test_distribution[1] + upsilon = 1.0 - ((variance - mean) / variance) + tau = (mean ** 2 / (variance - mean)) + phigh97 = scipy.stats.nbinom.ppf( + (1 - percentile / 100.) / 2., tau, upsilon + ) + plow97 = scipy.stats.nbinom.ppf( + 1 - (1 - percentile / 100.) / 2., tau, upsilon + ) + low97 = test_results[i].observed_statistic - plow97 + high97 = phigh97 - test_results[i].observed_statistic + ax.errorbar(test_results[i].observed_statistic, + (len(test_results) - 1) - i, + xerr=numpy.array([[low97, high97]]).T, capsize=4, + color='slategray', alpha=1.0, zorder=0) + p_values.append(test_results[i].quantile[ + 1] * 2.0) # Calculated p-values according to Meletti et al., (2021) + + if p_values[i] < 10e-5: + ax.plot(test_results[i].observed_statistic, + (len(test_results) - 1) - i, marker='o', + color='red', markersize=8, zorder=2) + if p_values[i] >= 10e-5 and p_values[i] < 10e-4: + ax.plot(test_results[i].observed_statistic, + (len(test_results) - 1) - i, marker='o', + color='#FF7F50', markersize=8, zorder=2) + if p_values[i] >= 10e-4 and p_values[i] < 10e-3: + ax.plot(test_results[i].observed_statistic, + (len(test_results) - 1) - i, marker='o', + color='gold', markersize=8, zorder=2) + if p_values[i] >= 10e-3 and p_values[i] < 0.0125: + ax.plot(test_results[i].observed_statistic, + (len(test_results) - 1) - i, marker='o', + color='white', markersize=8, zorder=2) + if p_values[i] >= 0.0125 and p_values[i] < 0.025: + ax.plot(test_results[i].observed_statistic, + (len(test_results) - 1) - i, marker='o', + color='skyblue', markersize=8, zorder=2) + if p_values[i] >= 0.025: + ax.plot(test_results[i].observed_statistic, + (len(test_results) - 1) - i, marker='o', + color='blue', markersize=8, zorder=2) + # Act on Poisson N-test + if test_results[0].name == 'Poisson N-Test': + for i in range(len(test_results)): + plow97 = scipy.stats.poisson.ppf((1 - percentile / 100.) / 2., + test_results[ + i].test_distribution[1]) + phigh97 = scipy.stats.poisson.ppf( + 1 - (1 - percentile / 100.) / 2., + test_results[i].test_distribution[1]) + low97 = test_results[i].observed_statistic - plow97 + high97 = phigh97 - test_results[i].observed_statistic + ax.errorbar(test_results[i].observed_statistic, + (len(test_results) - 1) - i, + xerr=numpy.array([[low97, high97]]).T, capsize=4, + color='slategray', alpha=1.0, zorder=0) + p_values.append(test_results[i].quantile[1] * 2.0) + if p_values[i] < 10e-5: + ax.plot(test_results[i].observed_statistic, + (len(test_results) - 1) - i, marker='o', + color='red', markersize=8, zorder=2) + elif p_values[i] >= 10e-5 and p_values[i] < 10e-4: + ax.plot(test_results[i].observed_statistic, + (len(test_results) - 1) - i, marker='o', + color='#FF7F50', markersize=8, zorder=2) + elif p_values[i] >= 10e-4 and p_values[i] < 10e-3: + ax.plot(test_results[i].observed_statistic, + (len(test_results) - 1) - i, marker='o', + color='gold', markersize=8, zorder=2) + elif p_values[i] >= 10e-3 and p_values[i] < 0.0125: + ax.plot(test_results[i].observed_statistic, + (len(test_results) - 1) - i, marker='o', + color='white', markersize=8, zorder=2) + elif p_values[i] >= 0.0125 and p_values[i] < 0.025: + ax.plot(test_results[i].observed_statistic, + (len(test_results) - 1) - i, marker='o', + color='skyblue', markersize=8, zorder=2) + elif p_values[i] >= 0.025: + ax.plot(test_results[i].observed_statistic, + (len(test_results) - 1) - i, marker='o', + color='blue', markersize=8, zorder=2) + # Operate on all other consistency tests + else: + for i in range(len(test_results)): + plow97 = numpy.percentile(test_results[i].test_distribution, 2.5) + phigh97 = numpy.percentile(test_results[i].test_distribution, 97.5) + low97 = test_results[i].observed_statistic - plow97 + high97 = phigh97 - test_results[i].observed_statistic + ax.errorbar(test_results[i].observed_statistic, + (len(test_results) - 1) - i, + xerr=numpy.array([[low97, high97]]).T, capsize=4, + color='slategray', alpha=1.0, zorder=0) + p_values.append(test_results[i].quantile) + + if p_values[i] < 10e-5: + ax.plot(test_results[i].observed_statistic, + (len(test_results) - 1) - i, marker='o', color='red', + markersize=8, zorder=2) + elif p_values[i] >= 10e-5 and p_values[i] < 10e-4: + ax.plot(test_results[i].observed_statistic, + (len(test_results) - 1) - i, marker='o', + color='#FF7F50', markersize=8, zorder=2) + elif p_values[i] >= 10e-4 and p_values[i] < 10e-3: + ax.plot(test_results[i].observed_statistic, + (len(test_results) - 1) - i, marker='o', color='gold', + markersize=8, zorder=2) + elif p_values[i] >= 10e-3 and p_values[i] < 0.025: + ax.plot(test_results[i].observed_statistic, + (len(test_results) - 1) - i, marker='o', color='white', + markersize=8, zorder=2) + elif p_values[i] >= 0.025 and p_values[i] < 0.05: + ax.plot(test_results[i].observed_statistic, + (len(test_results) - 1) - i, marker='o', + color='skyblue', markersize=8, zorder=2) + elif p_values[i] >= 0.05: + ax.plot(test_results[i].observed_statistic, + (len(test_results) - 1) - i, marker='o', color='blue', + markersize=8, zorder=2) + + legend_elements = [ + matplotlib.lines.Line2D([0], [0], marker='o', color='red', lw=0, + label=r'p < 10e-5', markersize=10, + markeredgecolor='k'), + matplotlib.lines.Line2D([0], [0], marker='o', color='#FF7F50', + lw=0, label=r'10e-5 $\leq$ p < 10e-4', + markersize=10, markeredgecolor='k'), + matplotlib.lines.Line2D([0], [0], marker='o', color='gold', lw=0, + label=r'10e-4 $\leq$ p < 10e-3', + markersize=10, markeredgecolor='k'), + matplotlib.lines.Line2D([0], [0], marker='o', color='white', lw=0, + label=r'10e-3 $\leq$ p < 0.025', + markersize=10, markeredgecolor='k'), + matplotlib.lines.Line2D([0], [0], marker='o', color='skyblue', + lw=0, label=r'0.025 $\leq$ p < 0.05', + markersize=10, markeredgecolor='k'), + matplotlib.lines.Line2D([0], [0], marker='o', color='blue', lw=0, + label=r'p $\geq$ 0.05', markersize=10, + markeredgecolor='k')] + + ax.legend(handles=legend_elements, loc=4, fontsize=13, edgecolor='k') + + return ax + + +def add_labels_for_publication(figure, style='bssa', labelsize=16): + """ Adds publication labels too the outside of a figure. + + .. deprecated:: 0.7.0 + This function is deprecated and will be removed in version 1.0. + + """ + + warnings.warn( + "'plot_spatial_test' is deprecated and will be removed in version 1.0.\n" + "Use 'plot_test_distribution' instead.\n" + "Documentation: https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_test_distribution.html", + DeprecationWarning, + stacklevel=2 + ) + all_axes = figure.get_axes() + ascii_iter = iter(string.ascii_lowercase) + for ax in all_axes: + # check for colorbar and ignore for annotations + if ax.get_label() == 'Colorbar': + continue + annot = next(ascii_iter) + if style == 'bssa': + ax.annotate(f'({annot})', (0.025, 1.025), xycoords='axes fraction', + fontsize=labelsize) + + return \ No newline at end of file diff --git a/tests/test_plots.py b/tests/test_plots.py index c94f552d..134cd151 100644 --- a/tests/test_plots.py +++ b/tests/test_plots.py @@ -27,7 +27,7 @@ from csep.utils.plots import ( plot_cumulative_events_versus_time, plot_magnitude_versus_time, - plot_distribution_test, + plot_test_distribution, plot_magnitude_histogram, plot_calibration_test, plot_comparison_test, @@ -146,6 +146,21 @@ def test_plot_magnitude_vs_time(self): plot_magnitude_versus_time(catalog=self.observation_m2, show=False) plt.close("all") + # Test with reset_times=True + ax = plot_magnitude_versus_time(catalog=self.observation_m2, reset_times=True, show=show_plots) + x_data = ax.collections[0].get_offsets().data[:, 0] # extract x from scatter plot + + # Check that the X-axis label is correct + self.assertEqual(ax.get_xlabel(), "Days since first event") + + # Check that time starts at 0 + self.assertAlmostEqual(x_data.min(), 0.0, places=4) + + # Check that time increases + self.assertTrue(numpy.all(numpy.diff(x_data) >= 0)) + + plt.close("all") + def test_plot_cumulative_events_default(self): # Test with default arguments to ensure basic functionality ax = plot_cumulative_events_versus_time( @@ -319,7 +334,7 @@ def setUp(self): self.l_test = CatalogPseudolikelihoodTestResult.from_dict(json.load(fp)) def test_plot_dist_test_with_scalar_observation_default(self): - ax = plot_distribution_test( + ax = plot_test_distribution( evaluation_result=self.result_obs_scalar, show=show_plots, ) @@ -330,7 +345,7 @@ def test_plot_dist_test_with_scalar_observation_default(self): self.assertEqual(lines[0].get_xdata()[0], self.result_obs_scalar.observed_statistic) def test_plot_dist_test_with_scalar_observation_w_labels(self): - ax = plot_distribution_test( + ax = plot_test_distribution( evaluation_result=self.result_obs_scalar, xlabel="Test X Label", ylabel="Test Y Label", @@ -344,7 +359,7 @@ def test_plot_dist_test_with_scalar_observation_w_labels(self): self.assertEqual(lines[0].get_xdata()[0], self.result_obs_scalar.observed_statistic) def test_plot_dist_test_with_array_observation(self): - ax = plot_distribution_test( + ax = plot_test_distribution( evaluation_result=self.result_obs_array, alpha=0.5, show=show_plots, @@ -356,7 +371,7 @@ def test_plot_dist_test_with_array_observation(self): ) def test_plot_dist_test_with_percentile_shading(self): - ax = plot_distribution_test( + ax = plot_test_distribution( evaluation_result=self.result_obs_scalar, percentile=60, show=show_plots, @@ -375,7 +390,7 @@ def test_plot_dist_test_with_percentile_shading(self): def test_plot_dist_test_with_annotation(self): annotation_text = "Test Annotation" - ax = plot_distribution_test( + ax = plot_test_distribution( evaluation_result=self.result_obs_scalar, xlabel="Test X Label", ylabel="Test Y Label", @@ -391,7 +406,7 @@ def test_plot_dist_test_with_annotation(self): def test_plot_dist_test_xlim(self): xlim = (-5, 5) - ax = plot_distribution_test( + ax = plot_test_distribution( evaluation_result=self.result_obs_scalar, percentile=95, xlim=xlim, @@ -401,32 +416,32 @@ def test_plot_dist_test_xlim(self): def test_plot_dist_test_autoxlim_nan(self): - plot_distribution_test( + plot_test_distribution( evaluation_result=self.result_nan, percentile=95, show=show_plots, ) def test_plot_n_test(self): - plot_distribution_test( + plot_test_distribution( self.n_test, show=show_plots, ) def test_plot_m_test(self): - plot_distribution_test( + plot_test_distribution( self.m_test, show=show_plots, ) def test_plot_s_test(self): - plot_distribution_test( + plot_test_distribution( self.s_test, show=show_plots, ) def test_plot_l_test(self): - plot_distribution_test( + plot_test_distribution( self.l_test, show=show_plots, ) @@ -1199,7 +1214,7 @@ def test_annotate_distribution_plot(self): ) # Assertions to check if the annotations were correctly set - self.assertEqual(ax.get_xlabel(), "Event Count") + self.assertEqual(ax.get_xlabel(), "Event Counts") self.assertEqual(ax.get_ylabel(), "Number of Catalogs") self.assertEqual(ax.get_title(), "Catalog N-Test: Simulated Catalog") From 58cf36fd9ac4f6e4aad50389c7591b3bc011209b Mon Sep 17 00:00:00 2001 From: pciturri Date: Wed, 2 Apr 2025 16:49:37 +0200 Subject: [PATCH 11/17] API changes: Added Deprecation warnings for all functions when plot_args is passed as arguments. Backtracked on plot_spatial_dataset, which now fallbacks to legacy call + deprecwarning. --- csep/utils/plots.py | 147 +++++++++++++++++++++++++++++++++---- csep/utils/plots_legacy.py | 132 ++++++++++++++++++++++++++++++--- 2 files changed, 254 insertions(+), 25 deletions(-) diff --git a/csep/utils/plots.py b/csep/utils/plots.py index 0ca691af..e5a69808 100644 --- a/csep/utils/plots.py +++ b/csep/utils/plots.py @@ -145,7 +145,17 @@ def plot_magnitude_versus_time( matplotlib.axes.Axes: The Matplotlib axes object with the plotted data. """ # Initialize plot - plot_args = {**DEFAULT_PLOT_ARGS, **kwargs} + if "plot_args" in kwargs: + warnings.warn( + "'plot_args' usage is deprecated and will be removed in version 1.0.\n" + "Fine-tuning of plot appearance may not behave as expected'.\n" + "Please use explicit arguments instead (e.g., color='red').\n" + "Refer to the function's documentation for supported keyword arguments:\n" + " https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_magnitude_versus_time.html", + DeprecationWarning, + stacklevel=2 + ) + plot_args = {**DEFAULT_PLOT_ARGS, **kwargs.get("plot_args", {}), **kwargs} fig, ax = pyplot.subplots(figsize=plot_args["figsize"]) if ax is None else (ax.figure, ax) # Plot data @@ -247,7 +257,17 @@ def _plot_cumulative_events_versus_time( matplotlib.axes.Axes: The Matplotlib axes object with the plotted data. """ # Initialize plot - plot_args = {**DEFAULT_PLOT_ARGS, **kwargs} + if "plot_args" in kwargs: + warnings.warn( + "'plot_args' usage is deprecated and will be removed in version 1.0.\n" + "Fine-tuning of plot appearance may not behave as expected'.\n" + "Please use explicit arguments instead (e.g., color='red').\n" + "Refer to the function's documentation for supported keyword arguments:\n" + " https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_cumulative_events_versus_time.html", + DeprecationWarning, + stacklevel=2 + ) + plot_args = {**DEFAULT_PLOT_ARGS, **kwargs.get("plot_args", {}), **kwargs} fig, ax = pyplot.subplots(figsize=plot_args["figsize"]) if ax is None else (ax.figure, ax) # Get information from stochastic event set @@ -419,7 +439,17 @@ def plot_magnitude_histogram( """ # Initialize plot - plot_args = {**DEFAULT_PLOT_ARGS, **kwargs} + if "plot_args" in kwargs: + warnings.warn( + "'plot_args' usage is deprecated and will be removed in version 1.0.\n" + "Fine-tuning of plot appearance may not behave as expected'.\n" + "Please use explicit arguments instead (e.g., color='red').\n" + "Refer to the function's documentation for supported keyword arguments:\n" + " https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_magnitude_histogram.html", + DeprecationWarning, + stacklevel=2 + ) + plot_args = {**DEFAULT_PLOT_ARGS, **kwargs.get("plot_args", {}), **kwargs} fig, ax = pyplot.subplots(figsize=plot_args["figsize"]) if ax is None else (ax.figure, ax) # Get magnitudes from observations and (lazily) from forecast @@ -691,7 +721,17 @@ def plot_catalog( matplotlib.axes.Axes: The Matplotlib axes object with the plotted data. """ - plot_args = {**DEFAULT_PLOT_ARGS, **kwargs} + if "plot_args" in kwargs: + warnings.warn( + "'plot_args' usage is deprecated and will be removed in version 1.0.\n" + "Fine-tuning of plot appearance may not behave as expected'.\n" + "Please use explicit arguments instead (e.g., color='red').\n" + "Refer to the function's documentation for supported keyword arguments:\n" + " https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_catalog.html", + DeprecationWarning, + stacklevel=2 + ) + plot_args = {**DEFAULT_PLOT_ARGS, **kwargs.get("plot_args", {}), **kwargs} # Get spatial information for plotting extent = extent or _calculate_spatial_extent(catalog, set_global, plot_region) # Instantiate GeoAxes object @@ -844,8 +884,17 @@ def plot_gridded_dataset( matplotlib.axes.Axes: Matplotlib axes object. """ - plot_args = {**DEFAULT_PLOT_ARGS, **kwargs} - + if "plot_args" in kwargs: + warnings.warn( + "'plot_args' usage is deprecated and will be removed in version 1.0.\n" + "Fine-tuning of plot appearance may not behave as expected'.\n" + "Please use explicit arguments instead (e.g., color='red').\n" + "Refer to the function's documentation for supported keyword arguments:\n" + " https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_gridded_dataset.html", + DeprecationWarning, + stacklevel=2 + ) + plot_args = {**DEFAULT_PLOT_ARGS, **kwargs.get("plot_args", {}), **kwargs} # Get spatial information for plotting extent = extent or _calculate_spatial_extent(region, set_global, plot_region) # Instantiate GeoAxes object @@ -955,8 +1004,18 @@ def plot_test_distribution( matplotlib.axes.Axes: Matplotlib axes handle. """ - # Initialize plot - plot_args = {**DEFAULT_PLOT_ARGS, **kwargs} + # Initialize plot] + if "plot_args" in kwargs: + warnings.warn( + "'plot_args' usage is deprecated and will be removed in version 1.0.\n" + "Fine-tuning of plot appearance may not behave as expected'.\n" + "Please use explicit arguments instead (e.g., color='red').\n" + "Refer to the function's documentation for supported keyword arguments:\n" + " https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_test_distribution.html", + DeprecationWarning, + stacklevel=2 + ) + plot_args = {**DEFAULT_PLOT_ARGS, **kwargs.get("plot_args", {}), **kwargs} fig, ax = pyplot.subplots(figsize=plot_args["figsize"]) if ax is None else (ax.figure, ax) # Get distributions @@ -1075,7 +1134,17 @@ def plot_calibration_test( matplotlib.axes.Axes: The Matplotlib axes object containing the plot. """ # Initialize plot - plot_args = {**DEFAULT_PLOT_ARGS, **kwargs} + if "plot_args" in kwargs: + warnings.warn( + "'plot_args' usage is deprecated and will be removed in version 1.0.\n" + "Fine-tuning of plot appearance may not behave as expected'.\n" + "Please use explicit arguments instead (e.g., color='red').\n" + "Refer to the function's documentation for supported keyword arguments:\n" + " https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_calibration_test.html", + DeprecationWarning, + stacklevel=2 + ) + plot_args = {**DEFAULT_PLOT_ARGS, **kwargs.get("plot_args", {}), **kwargs} fig, ax = pyplot.subplots(figsize=plot_args["figsize"]) if ax is None else (ax.figure, ax) # Set up QQ plots and KS test @@ -1179,7 +1248,17 @@ def _plot_comparison_test( """ # Initialize plot - plot_args = {**DEFAULT_PLOT_ARGS, **kwargs} + if "plot_args" in kwargs: + warnings.warn( + "'plot_args' usage is deprecated and will be removed in version 1.0.\n" + "Fine-tuning of plot appearance may not behave as expected'.\n" + "Please use explicit arguments instead (e.g., color='red').\n" + "Refer to the function's documentation for supported keyword arguments:\n" + " https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_comparison_test.html", + DeprecationWarning, + stacklevel=2 + ) + plot_args = {**DEFAULT_PLOT_ARGS, **kwargs.get("plot_args", {}), **kwargs} fig, ax = pyplot.subplots(figsize=plot_args["figsize"]) if ax is None else (ax.figure, ax) # Iterate through T-test results, or jointly through t- and w- test results @@ -1347,7 +1426,17 @@ def _plot_consistency_test( """ # Initialize plot - plot_args = {**DEFAULT_PLOT_ARGS, **kwargs} + if "plot_args" in kwargs: + warnings.warn( + "'plot_args' usage is deprecated and will be removed in version 1.0.\n" + "Fine-tuning of plot appearance may not behave as expected'.\n" + "Please use explicit arguments instead (e.g., color='red').\n" + "Refer to the function's documentation for supported keyword arguments:\n" + " https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_consistency_test.html", + DeprecationWarning, + stacklevel=2 + ) + plot_args = {**DEFAULT_PLOT_ARGS, **kwargs.get("plot_args", {}), **kwargs} fig, ax = pyplot.subplots(figsize=plot_args["figsize"]) if ax is None else (ax.figure, ax) # Ensure eval_results is a list @@ -1478,7 +1567,17 @@ def _plot_concentration_ROC_diagram( """ # Initialize plot - plot_args = {**DEFAULT_PLOT_ARGS, **kwargs} + if "plot_args" in kwargs: + warnings.warn( + "'plot_args' usage is deprecated and will be removed in version 1.0.\n" + "Fine-tuning of plot appearance may not behave as expected'.\n" + "Please use explicit arguments instead (e.g., color='red').\n" + "Refer to the function's documentation for supported keyword arguments:\n" + " https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_concentration_ROC_diagram.html", + DeprecationWarning, + stacklevel=2 + ) + plot_args = {**DEFAULT_PLOT_ARGS, **kwargs.get("plot_args", {}), **kwargs} fig, ax = pyplot.subplots(figsize=plot_args["figsize"]) if ax is None else (ax.figure, ax) if not catalog.region == forecast.region: @@ -1591,7 +1690,17 @@ def _plot_ROC_diagram( """ # Initialize plot - plot_args = {**DEFAULT_PLOT_ARGS, **kwargs} + if "plot_args" in kwargs: + warnings.warn( + "'plot_args' usage is deprecated and will be removed in version 1.0.\n" + "Fine-tuning of plot appearance may not behave as expected'.\n" + "Please use explicit arguments instead (e.g., color='red').\n" + "Refer to the function's documentation for supported keyword arguments:\n" + " https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_ROC_diagram.html", + DeprecationWarning, + stacklevel=2 + ) + plot_args = {**DEFAULT_PLOT_ARGS, **kwargs.get("plot_args", {}), **kwargs} fig, ax = pyplot.subplots(figsize=plot_args["figsize"]) if ax is None else (ax.figure, ax) if not catalog.region == forecast.region: @@ -1738,7 +1847,17 @@ def _plot_Molchan_diagram( RuntimeError: If the catalog and forecast do not have the same region. """ - plot_args = {**DEFAULT_PLOT_ARGS, **kwargs} + if "plot_args" in kwargs: + warnings.warn( + "'plot_args' usage is deprecated and will be removed in version 1.0.\n" + "Fine-tuning of plot appearance may not behave as expected'.\n" + "Please use explicit arguments instead (e.g., color='red').\n" + "Refer to the function's documentation for supported keyword arguments:\n" + " https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_Molchan_diagram.html", + DeprecationWarning, + stacklevel=2 + ) + plot_args = {**DEFAULT_PLOT_ARGS, **kwargs.get("plot_args", {}), **kwargs} fig, ax = pyplot.subplots(figsize=plot_args["figsize"]) if ax is None else (ax.figure, ax) if not catalog.region == forecast.region: diff --git a/csep/utils/plots_legacy.py b/csep/utils/plots_legacy.py index 5723211d..ae7d2858 100644 --- a/csep/utils/plots_legacy.py +++ b/csep/utils/plots_legacy.py @@ -10,7 +10,9 @@ import matplotlib.lines from matplotlib.collections import PatchCollection import matplotlib.pyplot as pyplot +import cartopy.crs as ccrs from cartopy.io import img_tiles +from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER # PyCSEP imports from csep.utils.calc import bin1d_vec @@ -566,7 +568,6 @@ def plot_spatial_dataset(gridded, region, ax=None, show=False, extent=None, """ Legacy-compatible wrapper for plot_gridded_dataset. """ - from .plots import plot_gridded_dataset plot_args = plot_args or {} warnings.warn( @@ -577,16 +578,125 @@ def plot_spatial_dataset(gridded, region, ax=None, show=False, extent=None, stacklevel=2 ) - return plot_gridded_dataset( - gridded=gridded, - region=region, - ax=ax, - show=show, - extent=extent, - set_global=set_global, - **plot_args, - **kwargs - ) + # Get spatial information for plotting + bbox = region.get_bbox() + if extent is None and not set_global: + extent = [bbox[0], bbox[1], bbox[2], bbox[3]] + + # Retrieve plot arguments + plot_args = plot_args or {} + # figure and axes properties + figsize = plot_args.get('figsize', None) + title = plot_args.get('title', None) + title_size = plot_args.get('title_size', None) + filename = plot_args.get('filename', None) + # cartopy properties + projection = plot_args.get('projection', + ccrs.PlateCarree(central_longitude=0.0)) + grid = plot_args.get('grid', True) + grid_labels = plot_args.get('grid_labels', False) + grid_fontsize = plot_args.get('grid_fontsize', False) + basemap = plot_args.get('basemap', None) + coastline = plot_args.get('coastline', True) + borders = plot_args.get('borders', False) + tile_scaling = plot_args.get('tile_scaling', 'auto') + linewidth = plot_args.get('linewidth', True) + linecolor = plot_args.get('linecolor', 'black') + region_border = plot_args.get('region_border', True) + # color bar properties + include_cbar = plot_args.get('include_cbar', True) + cmap = plot_args.get('cmap', None) + clim = plot_args.get('clim', None) + clabel = plot_args.get('clabel', None) + clabel_fontsize = plot_args.get('clabel_fontsize', None) + cticks_fontsize = plot_args.get('cticks_fontsize', None) + alpha = plot_args.get('alpha', 1) + alpha_exp = plot_args.get('alpha_exp', 0) + + apprx = False + central_latitude = 0.0 + if projection == 'fast': + projection = ccrs.PlateCarree() + apprx = True + n_lats = len(region.ys) // 2 + central_latitude = region.ys[n_lats] + + # Instantiate GeoAxes object + if ax is None: + fig = pyplot.figure(figsize=figsize) + ax = fig.add_subplot(111, projection=projection) + else: + fig = ax.get_figure() + + if set_global: + ax.set_global() + region_border = False + else: + ax.set_extent(extents=extent, + crs=ccrs.PlateCarree()) # Defined extent always in lat/lon + + # Basemap plotting + ax = plot_basemap(basemap, extent, ax=ax, coastline=coastline, + borders=borders, + linecolor=linecolor, linewidth=linewidth, + projection=projection, apprx=apprx, + central_latitude=central_latitude, + tile_scaling=tile_scaling, set_global=set_global) + + ## Define colormap and transparency function + if isinstance(cmap, str) or not cmap: + cmap = pyplot.get_cmap(cmap) + cmap_tup = cmap(numpy.arange(cmap.N)) + if isinstance(alpha_exp, (float, int)): + if alpha_exp != 0: + cmap_tup[:, -1] = numpy.linspace(0, 1, cmap.N) ** alpha_exp + alpha = None + cmap = matplotlib.colors.ListedColormap(cmap_tup) + + ## Plot spatial dataset + lons, lats = numpy.meshgrid(numpy.append(region.xs, bbox[1]), + numpy.append(region.ys, bbox[3])) + im = ax.pcolor(lons, lats, gridded, cmap=cmap, alpha=alpha, snap=True, + transform=ccrs.PlateCarree()) + im.set_clim(clim) + + + # Colorbar options + # create an axes on the right side of ax. The width of cax will be 5% + # of ax and the padding between cax and ax will be fixed at 0.05 inch. + if include_cbar: + cax = fig.add_axes( + [ax.get_position().x1 + 0.01, ax.get_position().y0, 0.025, + ax.get_position().height], + label='Colorbar') + cbar = fig.colorbar(im, ax=ax, cax=cax) + cbar.set_label(clabel, fontsize=clabel_fontsize) + cbar.ax.tick_params(labelsize=cticks_fontsize) + + # Gridline options + if grid: + gl = ax.gridlines(draw_labels=grid_labels, alpha=0.5) + gl.right_labels = False + gl.top_labels = False + gl.xlabel_style['fontsize'] = grid_fontsize + gl.ylabel_style['fontsize'] = grid_fontsize + gl.xformatter = LONGITUDE_FORMATTER + gl.yformatter = LATITUDE_FORMATTER + + if region_border: + pts = region.tight_bbox() + ax.plot(pts[:, 0], pts[:, 1], lw=1, color='black', + transform=ccrs.PlateCarree()) + + # matplotlib figure options + ax.set_title(title, y=1.06, fontsize=title_size) + if filename is not None: + ax.get_figure().savefig(filename + '.pdf') + ax.get_figure().savefig(filename + '.png', dpi=300) + if show: + pyplot.show() + + return ax def plot_number_test(evaluation_result, axes=None, show=True, plot_args=None): From c03f693194da3a338c661b1fc11628dba36ca727 Mon Sep 17 00:00:00 2001 From: pciturri Date: Thu, 3 Apr 2025 17:01:03 +0200 Subject: [PATCH 12/17] docs: Added query_gns, query_gcmt to docs index. Fixed catalog filtering tutorial links and expanded with m_vs_t plot. Added reference links to multiple tutorials. Changed sphinx confx to not display full function signature in API docs. Added comparative tests/plots to gridded_forecast_+tutorial refac: shifted some function args ordering ft: Comparative plots now handle being passed only one forecast. --- .github/workflows/build-test.yml | 2 +- csep/core/catalogs.py | 30 ++++++++++++--- csep/utils/plots.py | 37 ++++++++++++------- docs/concepts/regions.rst | 17 +++++++-- docs/conf.py | 1 + docs/getting_started/theory.rst | 2 + docs/reference/api_reference.rst | 4 +- examples/tutorials/catalog_filtering.py | 31 +++++++++++++--- .../tutorials/gridded_forecast_evaluation.py | 23 ++++++++++++ examples/tutorials/plot_customizations.py | 2 + examples/tutorials/plot_gridded_forecast.py | 6 +-- .../working_with_catalog_forecasts.py | 3 +- 12 files changed, 122 insertions(+), 36 deletions(-) diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index d4df63ac..9bb56913 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -72,5 +72,5 @@ jobs: - name: Test with pytest run: | - pip install vcrpy==4.3.1 pytest pytest-cov + pip install vcrpy pytest pytest-cov pytest --cov=./ --cov-config=.coveragerc diff --git a/csep/core/catalogs.py b/csep/core/catalogs.py index 6e576993..2bc0e928 100644 --- a/csep/core/catalogs.py +++ b/csep/core/catalogs.py @@ -23,7 +23,7 @@ from csep.utils.log import LoggingMixin from csep.utils.readers import csep_ascii from csep.utils.file import get_file_extension -from csep.utils.plots import plot_catalog +from csep.utils.plots import plot_catalog, plot_magnitude_versus_time class AbstractBaseCatalog(LoggingMixin): @@ -840,15 +840,16 @@ def b_positive(self): """ Implements the b-positive indicator from Nicholas van der Elst """ pass - def plot(self, ax=None, show=False, extent=None, set_global=False, plot_args=None, - **kwargs): - """ Plot catalog according to plate-carree projection + def plot(self, ax=None, show=False, extent=None, set_global=False, **kwargs): + """ Plot catalog according to plate-carree projection. See + https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_catalog.html for + a description of keyword arguments. Args: ax (`matplotlib.pyplot.axes`): Previous axes onto which catalog can be drawn show (bool): if true, show the figure. this call is blocking. extent (list): Force an extent [lon_min, lon_max, lat_min, lat_max] - plot_args (optional/dict): dictionary containing plotting arguments for making figures + set_global (bool): Whether to plot using a global projection Returns: axes: matplotlib.Axes.axes @@ -867,7 +868,7 @@ def plot(self, ax=None, show=False, extent=None, set_global=False, plot_args=Non except AttributeError: pass - plot_args = plot_args or {} + plot_args = kwargs.get('plot_args', {}) plot_args_default.update(plot_args) # this call requires internet connection and basemap @@ -875,6 +876,23 @@ def plot(self, ax=None, show=False, extent=None, set_global=False, plot_args=Non set_global=set_global, **plot_args_default, **kwargs) return ax + def plot_magnitude_versus_time(self, ax=None, show=False, **kwargs): + """ Plot the magnitude-time series of a catalog. See + https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_magnitude_versus_time.html for + a description of keyword arguments. + + Args: + ax (`matplotlib.pyplot.axes`): Previous axes onto which catalog can be drawn + show (bool): if true, show the figure. this call is blocking. + + Returns: + axes: matplotlib.Axes.axes + """ + + ax = plot_magnitude_versus_time(self, ax=ax, show=show, **kwargs) + + return ax + class CSEPCatalog(AbstractBaseCatalog): """ diff --git a/csep/utils/plots.py b/csep/utils/plots.py index e5a69808..2ded08fc 100644 --- a/csep/utils/plots.py +++ b/csep/utils/plots.py @@ -828,9 +828,7 @@ def plot_gridded_dataset( gridded: numpy.ndarray, region: "CartesianGrid2D", basemap: Optional[str] = None, - ax: Optional[pyplot.Axes] = None, projection: Optional[Union[ccrs.Projection, str]] = None, - show: bool = False, extent: Optional[List[float]] = None, set_global: bool = False, plot_region: bool = True, @@ -840,6 +838,8 @@ def plot_gridded_dataset( clabel: Optional[str] = None, alpha: Optional[float] = None, alpha_exp: float = 0, + ax: Optional[pyplot.Axes] = None, + show: bool = False, **kwargs, ) -> matplotlib.axes.Axes: """ @@ -856,11 +856,9 @@ def plot_gridded_dataset( (whose indices correspond to each spatial cell) to a 2D-square array. region (CartesianGrid2D): Region in which gridded values are contained. basemap (str): Passed to :func:`~csep.utils.plots.plot_basemap` along with `kwargs`. - ax (matplotlib.axes.Axes): Previously defined ax object. Defaults to `None`. projection (cartopy.crs.Projection or str): Projection to be used in the underlying basemap. It can be a cartopy projection instance, or `approx` for a quick approximation of Mercator. Defaults to :class:`~cartopy.crs.PlateCarree` if `None`. - show (bool): If `True`, displays the plot. Defaults to `False`. extent (list of float): ``[lon_min, lon_max, lat_min, lat_max]``. Defaults to `None`. set_global (bool): Display the complete globe as basemap. Defaults to `False`. plot_region (bool): If `True`, plot the dataset region border. Defaults to `True`. @@ -871,6 +869,8 @@ def plot_gridded_dataset( alpha (float): Transparency level. Defaults to `None`. alpha_exp (float): Exponent for the alpha function (recommended between `0.4` and `1`). Defaults to `0`. + ax (matplotlib.axes.Axes): Previously defined ax object. Defaults to `None`. + show (bool): If `True`, displays the plot. Defaults to `False`. **kwargs: Additional keyword arguments to customize the plot: - **colorbar_labelsize** (`int`): Font size for the colorbar label. @@ -953,11 +953,11 @@ def plot_test_distribution( evaluation_result: "EvaluationResult", bins: Union[str, int, List[Any]] = "fd", percentile: Optional[int] = 95, - ax: Optional[matplotlib.axes.Axes] = None, auto_annotate: Union[bool, dict] = True, sim_label: str = "Simulated", obs_label: str = "Observation", legend: bool = True, + ax: Optional[matplotlib.axes.Axes] = None, show: bool = False, **kwargs, ) -> matplotlib.axes.Axes: @@ -1096,8 +1096,8 @@ def plot_test_distribution( def plot_calibration_test( evaluation_result: "EvaluationResult", percentile: float = 95, - ax: Optional[matplotlib.axes.Axes] = None, label: Optional[str] = None, + ax: Optional[matplotlib.axes.Axes] = None, show: bool = False, **kwargs, ) -> matplotlib.axes.Axes: @@ -1261,6 +1261,13 @@ def _plot_comparison_test( plot_args = {**DEFAULT_PLOT_ARGS, **kwargs.get("plot_args", {}), **kwargs} fig, ax = pyplot.subplots(figsize=plot_args["figsize"]) if ax is None else (ax.figure, ax) + # Handle case when there is only a single pair of t_results and w_results + if not isinstance(results_t, list): + results_t = [results_t] + + if results_w is not None and not isinstance(results_w, list): + results_w = [results_w] + # Iterate through T-test results, or jointly through t- and w- test results Results = zip(results_t, results_w) if results_w else zip(results_t) for index, result in enumerate(Results): @@ -1337,11 +1344,15 @@ def _plot_comparison_test( if plot_args["legend"]: # Add custom legend to explain results + legend_elements = [ Line2D([0], [0], color="red", lw=2, label=f"T-test rejected ($\\alpha = {results_t[0].quantile[-1]}$)"), Line2D([0], [0], color="green", lw=2, label="T-test non-rejected"), - Line2D([0], [0], color="gray", lw=2, label="T-test indistinguishable"), + Line2D([0], [0], color="gray", lw=2, label="T-test indistinguishable") + ] + if results_w is not None: + legend_elements.extend([ Line2D( [0], [0], @@ -1361,8 +1372,8 @@ def _plot_comparison_test( markersize=6, markerfacecolor="white", label="W-test indistinguishable", - ), - ] + )]) + ax.legend(handles=legend_elements, loc="best", fontsize=plot_args["legend_fontsize"]) if plot_args["tight_layout"]: @@ -1379,9 +1390,9 @@ def _plot_consistency_test( normalize: bool = False, one_sided_lower: bool = False, percentile: float = 95, - ax: Optional[pyplot.Axes] = None, plot_mean: bool = False, color: str = "black", + ax: Optional[pyplot.Axes] = None, show: bool = False, **kwargs, ) -> matplotlib.axes.Axes: @@ -1523,8 +1534,8 @@ def _plot_concentration_ROC_diagram( catalog: "CSEPCatalog", linear: bool = True, plot_uniform: bool = True, - show: bool = True, ax: Optional[pyplot.Axes] = None, + show: bool = True, **kwargs, ) -> matplotlib.axes.Axes: """ @@ -1649,8 +1660,8 @@ def _plot_ROC_diagram( catalog: "CSEPCatalog", linear: bool = True, plot_uniform: bool = True, - show: bool = True, ax: Optional[pyplot.Axes] = None, + show: bool = True, **kwargs, ) -> matplotlib.pyplot.Axes: """ @@ -1786,8 +1797,8 @@ def _plot_Molchan_diagram( catalog: "CSEPCatalog", linear: bool = True, plot_uniform: bool = True, - show: bool = True, ax: Optional[pyplot.Axes] = None, + show: bool = True, **kwargs, ) -> matplotlib.axes.Axes: diff --git a/docs/concepts/regions.rst b/docs/concepts/regions.rst index 23b1b316..e4bc753d 100644 --- a/docs/concepts/regions.rst +++ b/docs/concepts/regions.rst @@ -4,6 +4,8 @@ Regions ####### +.. automodule:: csep.core.regions + :no-index: .. automodule:: csep.utils.basic_types :no-index: @@ -16,8 +18,6 @@ module is early in development and will be a focus of future development. .. :currentmodule:: csep -.. automodule:: csep.core.regions - :no-index: Practically speaking, earthquake forecasts, especially time-dependent forecasts, treat time differently than space and magnitude. If we consider a family of monthly forecasts for the state of California for earthquakes with **M** 3.95+, @@ -100,7 +100,8 @@ mapping defined in (2). The :meth:`get_index_of`_: :func:`csep.query_comcat` +# * `INGV Bolletino Sismico Italiano (BSI) `_: :func:`csep.query_bsi` +# * `GNS New Zealand GeoNet `_: :func:`csep.query_gns` +# * `Global CMT `_ (through the `ISC `_ API): :func:`csep.query_gcmt` +# +# These functions require a :class:`datetime.datetime` to specify the start and end dates of the query. start_time = csep.utils.time_utils.strptime_to_utc_datetime('2019-01-01 00:00:00.0') end_time = csep.utils.time_utils.utc_now_datetime() @@ -91,18 +95,33 @@ catalog = catalog.filter_spatial(aftershock_region).apply_mct(event.magnitude, m71_epoch) print(catalog) +#################################################################################################################################### +# Additional CSEP regions (e.g., California, Italy, New Zealand) can be accessed through the :mod:`csep.core.regions` module. See :ref:`testing-regions` for more information. + #################################################################################################################################### # Plot catalog # ------------- # -# To visualize the catalog, use :meth:`csep.core.catalogs.AbstractBaseCatalog.plot` to plot it spatially +# To visualize the catalog spatially, simply use the method :meth:`~csep.core.catalogs.CSEPCatalog.plot` catalog.plot(show=True) +#################################################################################################################################### +# To plot the magnitude time series, use :meth:`~csep.core.catalogs.CSEPCatalog.plot_magnitude_vs_time` +catalog.plot_magnitude_versus_time(show=True) + #################################################################################################################################### # Write catalog # ------------- # -# Use :meth:`csep.core.catalogs.AbstractBaseCatalog.write_ascii` to write the catalog into the comma separated value format. +# Use the method :meth:`~csep.core.catalogs.CSEPCatalog.write_ascii` to write the catalog into the comma separated value format. catalog.write_ascii('2019-11-11-comcat.csv') + + +#################################################################################################################################### +# Load catalog +# ------------ +# +# Also, the function :func:`csep.load_catalog` can be used to read catalogs un multiple formats (See :ref:`catalogs-reference`) +catalog = csep.load_catalog('2019-11-11-comcat.csv') diff --git a/examples/tutorials/gridded_forecast_evaluation.py b/examples/tutorials/gridded_forecast_evaluation.py index 3a784f80..b1e29e9b 100644 --- a/examples/tutorials/gridded_forecast_evaluation.py +++ b/examples/tutorials/gridded_forecast_evaluation.py @@ -106,6 +106,28 @@ xlabel='Spatial likelihood') plt.show() + +#################################################################################################################################### +# Performing a comparative test +# ----------------------------- +# +# Comparative tests assess the relative performance of a forecasts against a reference forecast. We load a baseline version of the +# Helmstetter forecasts that does not account for the influence of aftershocks. We perform the paired T-test to calculate the +# Information Gain and its significance (See :ref:`forecast-comparison-tests` for more information). +# + +ref_forecast = csep.load_gridded_forecast(datasets.helmstetter_mainshock_fname, + start_date=start_date, + end_date=end_date, + name='helmstetter_mainshock') + +t_test = poisson.paired_t_test(forecast=forecast, + benchmark_forecast=ref_forecast, + observed_catalog=catalog) + +plots.plot_comparison_test(t_test, show=True) + + #################################################################################################################################### # Plot ROC Curves # --------------- @@ -120,6 +142,7 @@ # Note: This figure just shows an example of plotting an ROC curve with a catalog forecast. # If "linear=True" the diagram is represented using a linear x-axis. # If "linear=False" the diagram is represented using a logarithmic x-axis. +# print("Plotting concentration ROC curve") diff --git a/examples/tutorials/plot_customizations.py b/examples/tutorials/plot_customizations.py index 70d426c2..7d9a73bb 100644 --- a/examples/tutorials/plot_customizations.py +++ b/examples/tutorials/plot_customizations.py @@ -1,4 +1,6 @@ """ +.. _tutorial-plot-customizations: + Plot customizations =================== diff --git a/examples/tutorials/plot_gridded_forecast.py b/examples/tutorials/plot_gridded_forecast.py index 84bdd46e..13f0065d 100644 --- a/examples/tutorials/plot_gridded_forecast.py +++ b/examples/tutorials/plot_gridded_forecast.py @@ -21,7 +21,7 @@ # # We choose a :ref:`time-independent-forecast` to show how to evaluate a grid-based earthquake forecast using PyCSEP. Note, # the start and end date should be chosen based on the creation of the forecast. This is important for time-independent forecasts -# because they can be rescale to any arbitrary time period. +# because they can be rescaled to any arbitrary time period. start_date = time_utils.strptime_to_utc_datetime('2006-11-12 00:00:00.0') end_date = time_utils.strptime_to_utc_datetime('2011-11-12 00:00:00.0') @@ -42,8 +42,8 @@ # Plot forecast # ------------- # -# The forecast object provides :meth:`csep.core.forecasts.GriddedForecast.plot` to plot a gridded forecast. This function -# returns a matplotlib axes, so more specific attributes can be set on the figure. +# The forecast object provides a :meth:`~csep.core.forecasts.GriddedForecast.plot` method to plot its data spatially. This function +# returns a matplotlib axes, so more specific attributes can be set on the figure (See :ref:`tutorial-plot-customizations` and :func:`~csep.utils.plots.plot_gridded_dataset` for more information). ax = forecast.plot(show=True) diff --git a/examples/tutorials/working_with_catalog_forecasts.py b/examples/tutorials/working_with_catalog_forecasts.py index 4b0320cc..499dbbb4 100644 --- a/examples/tutorials/working_with_catalog_forecasts.py +++ b/examples/tutorials/working_with_catalog_forecasts.py @@ -20,7 +20,6 @@ # :mod:`csep.utils` subpackage. import numpy - import csep from csep.core import regions from csep.utils import datasets @@ -71,7 +70,7 @@ # # We can plot the expected event counts the same way that we plot a :class:`csep.core.forecasts.GriddedForecast` -ax = forecast.expected_rates.plot(plot_args={'clim': [-3.5, 0]}, show=True) +ax = forecast.expected_rates.plot(clim=[-3.5, 0], show=True) #################################################################################################################################### # The images holes in the image are due to under-sampling from the forecast. From 6f2c505c17fb1b4f5126e3269125143202a977f9 Mon Sep 17 00:00:00 2001 From: pciturri Date: Sat, 5 Apr 2025 20:43:59 +0200 Subject: [PATCH 13/17] build: added rasterio to conda requirements docs: Added "plot composition" section to Plotting tutorial. Added plot_magnitude_vs_time and plot_magnitude_histogram examples to Catalog-forecast tutorial. Added reflinks to tutorial headers. Added load_evaluation_result to API ref. ft: Added default plot_region=True to forecast.plot(). Added log_scale option to plot_magnitude_histogram for y axis, and also the mean is plotted now instead of median. Remove tight_layout from plot_catalog() option. fix: added transform argument when plotting the region in plot_gridded_dataset. --- csep/core/catalogs.py | 5 +- csep/core/forecasts.py | 3 +- csep/utils/plots.py | 21 ++- docs/reference/api_reference.rst | 7 +- examples/tutorials/catalog_filtering.py | 2 +- .../tutorials/catalog_forecast_evaluation.py | 32 +++- .../tutorials/gridded_forecast_evaluation.py | 12 +- examples/tutorials/plot_customizations.py | 140 ++++++++++++------ examples/tutorials/plot_gridded_forecast.py | 7 +- .../quadtree_gridded_forecast_evaluation.py | 4 +- .../working_with_catalog_forecasts.py | 5 +- requirements.yml | 1 + 12 files changed, 158 insertions(+), 81 deletions(-) diff --git a/csep/core/catalogs.py b/csep/core/catalogs.py index 2bc0e928..a6632cbe 100644 --- a/csep/core/catalogs.py +++ b/csep/core/catalogs.py @@ -857,7 +857,7 @@ def plot(self, ax=None, show=False, extent=None, set_global=False, **kwargs): # no mutable function arguments plot_args_default = { - 'basemap': kwargs.pop('basemap', None) or 'ESRI_terrain', + 'basemap': kwargs.pop('basemap', 'ESRI_terrain') if ax is None else None } # Plot the region border (if it exists) by default @@ -870,10 +870,11 @@ def plot(self, ax=None, show=False, extent=None, set_global=False, **kwargs): plot_args = kwargs.get('plot_args', {}) plot_args_default.update(plot_args) + plot_args_default.update(kwargs) # this call requires internet connection and basemap ax = plot_catalog(self, ax=ax, show=show, extent=extent, - set_global=set_global, **plot_args_default, **kwargs) + set_global=set_global, **plot_args_default) return ax def plot_magnitude_versus_time(self, ax=None, show=False, **kwargs): diff --git a/csep/core/forecasts.py b/csep/core/forecasts.py index a1cbfad1..6b638382 100644 --- a/csep/core/forecasts.py +++ b/csep/core/forecasts.py @@ -453,9 +453,10 @@ def plot(self, ax=None, show=False, log=True, extent=None, set_global=False, plo plot_args = plot_args or {} plot_args.update({ - 'basemap': kwargs.pop('basemap', None) or 'ESRI_terrain', + 'basemap': kwargs.pop('basemap', 'ESRI_terrain') if ax is None else None, 'title': kwargs.pop('title', None) or self.name, 'figsize': kwargs.pop('figsize', None) or (8, 8), + 'plot_region': True }) plot_args.update(**kwargs) # this call requires internet connection and basemap diff --git a/csep/utils/plots.py b/csep/utils/plots.py index 2ded08fc..5c0d724e 100644 --- a/csep/utils/plots.py +++ b/csep/utils/plots.py @@ -393,6 +393,7 @@ def plot_magnitude_histogram( observation: "CSEPCatalog", magnitude_bins: Optional[Union[List[float], numpy.ndarray]] = None, percentile: int = 95, + log_scale: bool = True, ax: Optional["matplotlib.axes.Axes"] = None, show: bool = False, **kwargs, @@ -411,6 +412,8 @@ def plot_magnitude_histogram( Defaults to `None`. percentile (int, optional): The percentile used for uncertainty intervals. Defaults to `95`. + log_scale (bool, optional): Whether to plot the y-axis in logarithmic scale. Defaults to + True. ax (matplotlib.axes.Axes, optional): The axes object to draw the plot on. If `None`, a new figure and axes are created. Defaults to `None`. show (bool, optional): Whether to display the plot immediately. Defaults to `False`. @@ -482,6 +485,7 @@ def get_histogram_synthetic_cat(x, mags, normed=True): bin_centers = (bin_edges[1:] + bin_edges[:-1]) / 2 # Compute statistics for the forecast histograms + forecast_mean = numpy.mean(forecast_hist, axis=0) forecast_median = numpy.median(forecast_hist, axis=0) forecast_low = numpy.percentile(forecast_hist, (100 - percentile) / 2.0, axis=0) forecast_high = numpy.percentile(forecast_hist, 100 - (100 - percentile) / 2.0, axis=0) @@ -490,7 +494,12 @@ def get_histogram_synthetic_cat(x, mags, normed=True): forecast_err_upper = forecast_high - forecast_median # Plot observed histogram - ax.semilogy( + if log_scale: + plot_func = ax.semilogy + else: + plot_func = ax.plot + + plot_func( bin_centers, obs_hist, color=plot_args["color"], @@ -504,11 +513,11 @@ def get_histogram_synthetic_cat(x, mags, normed=True): # Plot forecast histograms as bar plot with error bars ax.plot( bin_centers, - forecast_median, + forecast_mean, ".", markersize=plot_args["markersize"], color="darkred", - label="Forecast Median", + label="Forecast Mean", ) ax.errorbar( bin_centers, @@ -815,9 +824,6 @@ def plot_catalog( ax.set_title(plot_args["title"], fontsize=plot_args["title_fontsize"], y=1.06) - if plot_args["tight_layout"]: - ax.figure.tight_layout() - if show: pyplot.show() @@ -934,7 +940,8 @@ def plot_gridded_dataset( if plot_region and not set_global: try: pts = region.tight_bbox() - ax.plot(pts[:, 0], pts[:, 1], lw=1, color=plot_args["region_color"]) + ax.plot(pts[:, 0], pts[:, 1], lw=1, color=plot_args["region_color"], + transform=ccrs.PlateCarree()) except AttributeError: pass diff --git a/docs/reference/api_reference.rst b/docs/reference/api_reference.rst index 365a4dba..a4cf76d1 100644 --- a/docs/reference/api_reference.rst +++ b/docs/reference/api_reference.rst @@ -7,13 +7,12 @@ This contains a reference document to the PyCSEP API. .. :currentmodule:: csep -Loading catalogs and forecasts ------------------------------- +Loading catalogs, forecasts and results +--------------------------------------- .. autosummary:: :toctree: generated - load_stochastic_event_sets load_catalog query_comcat query_bsi @@ -21,6 +20,8 @@ Loading catalogs and forecasts query_gcmt load_gridded_forecast load_catalog_forecast + load_stochastic_event_sets + load_evaluation_result Catalogs -------- diff --git a/examples/tutorials/catalog_filtering.py b/examples/tutorials/catalog_filtering.py index 66a91cf8..0e8e142c 100644 --- a/examples/tutorials/catalog_filtering.py +++ b/examples/tutorials/catalog_filtering.py @@ -1,7 +1,7 @@ """ .. _tutorial-catalog-filtering: -Catalogs operations +Catalogs Operations =================== This example demonstrates how to perform standard operations on a catalog. This example requires an internet diff --git a/examples/tutorials/catalog_forecast_evaluation.py b/examples/tutorials/catalog_forecast_evaluation.py index 24bbe715..a1f3bf5a 100644 --- a/examples/tutorials/catalog_forecast_evaluation.py +++ b/examples/tutorials/catalog_forecast_evaluation.py @@ -1,5 +1,6 @@ """ -.. _catalog-forecast-evaluation: + +.. _tutorial-catalog-forecast-evaluation: Catalog-based Forecast Evaluation ================================= @@ -24,7 +25,7 @@ import csep from csep.core import regions, catalog_evaluations -from csep.utils import datasets, time_utils +from csep.utils import datasets, time_utils, plots #################################################################################################################################### # Define start and end times of forecast @@ -71,12 +72,13 @@ # More fine-grain control and optimizations can be achieved by creating a :class:`csep.core.forecasts.CatalogForecast` directly. forecast = csep.load_catalog_forecast(datasets.ucerf3_ascii_format_landers_fname, - start_time = start_time, end_time = end_time, - region = space_magnitude_region, - apply_filters = True) + start_time=start_time, end_time=end_time, + region=space_magnitude_region, + apply_filters=True) # Assign filters to forecast -forecast.filters = [f'origin_time >= {forecast.start_epoch}', f'origin_time < {forecast.end_epoch}'] +forecast.filters = [f'origin_time >= {forecast.start_epoch}', + f'origin_time < {forecast.end_epoch}'] #################################################################################################################################### # Obtain evaluation catalog from ComCat @@ -99,6 +101,22 @@ # Plot the catalog comcat_catalog.plot(show=True) +#################################################################################################################################### +# Exploratory visualizations +# -------------------------- +# +# We can visualize differences between the distribution of event counts of the observations against the forecast: + +plots.plot_cumulative_events_versus_time(forecast, comcat_catalog, time_axis='days', show=True) + + +#################################################################################################################################### +# +# and their magnitude histograms +# + +plots.plot_magnitude_histogram(forecast, comcat_catalog, log_scale=False, show=True) + #################################################################################################################################### # Perform number test # ------------------- @@ -113,4 +131,4 @@ # # We can create a simple visualization of the number test from the evaluation result class. -ax = number_test_result.plot(show=True) \ No newline at end of file +ax = number_test_result.plot(show=True) diff --git a/examples/tutorials/gridded_forecast_evaluation.py b/examples/tutorials/gridded_forecast_evaluation.py index b1e29e9b..13c8cdf3 100644 --- a/examples/tutorials/gridded_forecast_evaluation.py +++ b/examples/tutorials/gridded_forecast_evaluation.py @@ -28,17 +28,14 @@ from csep.core import poisson_evaluations as poisson from csep.utils import datasets, time_utils, plots -# Needed to show plots from the terminal -import matplotlib.pyplot as plt - #################################################################################################################################### # Define forecast properties # -------------------------- # # We choose a :ref:`time-independent-forecast` to show how to evaluate a grid-based earthquake forecast using PyCSEP. Note, # the start and end date should be chosen based on the creation of the forecast. This is important for time-independent forecasts -# because they can be rescale to any arbitrary time period. -from csep.utils.stats import get_Kagan_I1_score +# because they can be rescaled to any arbitrary time period. + start_date = time_utils.strptime_to_utc_datetime('2006-11-12 00:00:00.0') end_date = time_utils.strptime_to_utc_datetime('2011-11-12 00:00:00.0') @@ -103,8 +100,8 @@ # consistency tests. ax = plots.plot_consistency_test(spatial_test_result, - xlabel='Spatial likelihood') -plt.show() + xlabel='Spatial likelihood', + show=True) #################################################################################################################################### @@ -182,5 +179,6 @@ # We can also get the Kagan's I_1 score for a gridded forecast # (see Kagan, YanY. [2009] Testing long-term earthquake forecasts: likelihood methods and error diagrams, Geophys. J. Int., v.177, pages 532-542). +from csep.utils.stats import get_Kagan_I1_score I_1 = get_Kagan_I1_score(forecast, catalog) print("I_1score is: ", I_1) diff --git a/examples/tutorials/plot_customizations.py b/examples/tutorials/plot_customizations.py index 7d9a73bb..4ac90afe 100644 --- a/examples/tutorials/plot_customizations.py +++ b/examples/tutorials/plot_customizations.py @@ -4,14 +4,15 @@ Plot customizations =================== -This example shows how to include some advanced options in the spatial visualization -of Gridded Forecasts and Evaluation Results +This example shows how to include some advanced options in the visualization of catalogs, +forecasts and evaluation results Overview: 1. Define optional plotting arguments - 2. Set extent of maps + 2. Set the extent of maps 3. Visualizing selected magnitude bins 4. Plot global maps + 5. Composing plots 5. Plot multiple Evaluation Results """ @@ -26,34 +27,35 @@ import csep import cartopy import numpy -from csep.utils import datasets, plots -import matplotlib.pyplot as plt +from csep.utils import datasets, plots #################################################################################################################################### # **Load a Grid Forecast from the datasets** # +# We use one of the gridded forecasts provided in the datasets +# + forecast = csep.load_gridded_forecast(datasets.hires_ssm_italy_fname, name='Werner, et al (2010) Italy') -#################################################################################################################################### -# **Plotting the dataset with fine-tuned arguments** #################################################################################################################################### +# **Plotting the dataset with fine-tuned arguments** +# # These arguments are, in order: # -# * Set an extent -# * Select ESRI Imagery as a basemap. +# * Set the spatial extent of the plot +# * Access ESRI Imagery as a basemap. # * Assign a title # * Set labels to the geographic axes # * Draw country borders # * Set a linewidth of 0.5 to country border -# * Assign ``'rainbow'`` as colormap. Possible values from ``matplotlib.cm`` library +# * Assign ``'rainbow'`` as the colormap. Possible values from ``matplotlib.cm`` library # * Defines 0.8 for an exponential transparency function (default is 0 for constant alpha, whereas 1 for linear). # * An object cartopy.crs.Projection() is passed as Projection to the map # # The complete description of plot arguments can be found in :func:`csep.utils.plots.plot_gridded_dataset` - -#################################################################################################################################### +# ax = forecast.plot(extent=[3, 22, 35, 48], basemap='ESRI_imagery', @@ -70,7 +72,6 @@ # Example 2: Plot a global forecast and a selected magnitude bin range # -------------------------------------------------------------------- # -# # **Load a Global Forecast from the datasets** # # A downsampled version of the `GEAR1 `_ forecast can be found in datasets. @@ -81,12 +82,12 @@ #################################################################################################################################### # **Filter by magnitudes** # -# We get the rate of events of 5.95<=M_w<=7.5 +# We get the rate of events of 6.15<=M_w<=7.55 low_bound = 6.15 upper_bound = 7.55 mw_bins = forecast.get_magnitudes() -mw_ind = numpy.where(numpy.logical_and( mw_bins >= low_bound, mw_bins <= upper_bound))[0] +mw_ind = numpy.where(numpy.logical_and(mw_bins >= low_bound, mw_bins <= upper_bound))[0] rates_mw = forecast.data[:, mw_ind] #################################################################################################################################### @@ -95,35 +96,38 @@ rate_sum = rates_mw.sum(axis=1) #################################################################################################################################### -# The data is stored in a 1D array, so it should be projected into `region` 2D cartesian grid. +# The data is stored in a 1D array, so it should be projected into the `region` 2D cartesian grid. rate_sum = forecast.region.get_cartesian(rate_sum) #################################################################################################################################### # **Plotting the dataset** -# To plot a global forecast, we must assign the option ``set_global=True``, which is required by :ref:cartopy to handle -# internally the extent of the plot. We can further customize the plot using the required arguments from :func:`csep.utils.plots.plot_gridded_dataset` +# +# To plot a global forecast, we must assign the option ``set_global=True``, which is required by :ref:`cartopy` to handle +# internally the extent of the plot. We can further customize the plot using the required arguments from :func:`~csep.utils.plots.plot_gridded_dataset` +# -ax = plots.plot_gridded_dataset(numpy.log10(rate_sum), forecast.region, - figsize=(10,6), - set_global=True, - coastline_color='black', - projection=cartopy.crs.Robinson(central_longitude=180.0), - title=forecast.name, - grid_labels=False, - colormap='magma', - clabel= r'$\log_{10}\lambda\left(M_w \in [{%.2f},\,{%.2f}]\right)$ per ' \ - r'${%.1f}^\circ\times {%.1f}^\circ $ per forecast period' % \ - (low_bound, upper_bound, forecast.region.dh, forecast.region.dh), - show=True) +ax = plots.plot_gridded_dataset( + numpy.log10(rate_sum), forecast.region, + figsize=(10, 6), + set_global=True, + coastline_color='black', + projection=cartopy.crs.Robinson(central_longitude=180.0), + title=forecast.name, + grid_labels=False, + colormap='magma', + clabel=r'$\log_{10}\lambda\left(M_w \in [{%.2f},\,{%.2f}]\right)$ per ' \ + r'${%.1f}^\circ\times {%.1f}^\circ $ per forecast period' % \ + (low_bound, upper_bound, forecast.region.dh, + forecast.region.dh), + show=True) #################################################################################################################################### - #################################################################################################################################### -# Example 3: Plot a catalog -# ------------------------------------------- +# Example 3: Plot a catalog with a custom basemap +# ----------------------------------------------- #################################################################################################################################### # **Load a Catalog from ComCat** @@ -133,20 +137,22 @@ min_mag = 4.5 catalog = csep.query_comcat(start_time, end_time, min_magnitude=min_mag, verbose=False) -# **Define plotting arguments* - #################################################################################################################################### +# +# **Define plotting arguments** +# # These arguments are, in order: # -# * Assign as basemap a TIFF file in the same reference as the plot -# * Set minimum markersize of 2 with red color +# * Assign a TIFF file as basemap. The TIFF must have the same coordinate reference as the plot. +# * Set minimum and maximum marker size of 7 and 500, respectively. +# * Set the marker color red # * Set a 0.3 transparency # * mag_scale is used to exponentially scale the size with respect to magnitude. Recommended 1-8 # * Set legend True and location in 3 (lower-left corner) -# * Set a list of Magnitude ticks to display in the legend +# * Set a list of magnitude ticks to display in the legend # -# The complete description of plot arguments can be found in :func:`csep.utils.plots.plot_catalog` -# The arguments can be stored as a dictionary a priori and then unpacked to the function with `**`. +# The complete description of plot arguments can be found in :func:`csep.utils.plots.plot_catalog`. +# In case we want to store the arguments (i.e., for future plots) we can store them as a dictionary and then unpack them into the function with `**`. plot_args = {'basemap': csep.datasets.basemap_california, @@ -161,13 +167,54 @@ 'mag_ticks': [4.0, 5.0, 6.0, 7.0]} #################################################################################################################################### - +# # **Plot the catalog** +# + ax = catalog.plot(show=True, **plot_args) #################################################################################################################################### -# Example 4: Plot multiple evaluation results +# Example 4: Plot composition +# ----------------------------------------------- +# +# Multiple spatial plots can be chained to form a plot composite. For instance, plotting a custom basemap, a gridded forecast and a +# catalog can be done by simply chaining the plotting functions. + +#################################################################################################################################### +# **Load a forecast from the datasets** + +forecast = csep.load_gridded_forecast(csep.datasets.helmstetter_mainshock_fname) + +#################################################################################################################################### +# **Load a catalog from ComCat** + +start_time = csep.utils.time_utils.strptime_to_utc_datetime('2009-01-01 00:00:00.0') +end_time = csep.utils.time_utils.strptime_to_utc_datetime('2014-01-01 00:00:00.0') +min_mag = 4.95 +catalog = csep.query_comcat(start_time, end_time, min_magnitude=min_mag, verbose=False) + +#################################################################################################################################### +# **Initialize a basemap with desired arguments** +# +# Plot the basemap using :func:`csep.utils.plots.plot_basemap`. Do not set ```show=True``` and store the returned ```ax``` object to +# start the composite plot + +ax = plots.plot_basemap(figsize=(8, 8), + projection=cartopy.crs.AlbersEqualArea(central_longitude=-120.), + extent=forecast.region.get_bbox(), + basemap='ESRI_terrain', + coastline_color='darkred', + ) + +# Pass the ax object into a consecutive plot +ax = forecast.plot(colormap='PuBu_r', ax=ax) + +# Use show=True to finalize the composite. +catalog.plot(markercolor='darkred', ax=ax, show=True) + +#################################################################################################################################### +# Example 5: Plot multiple evaluation results # ------------------------------------------- #################################################################################################################################### @@ -183,17 +230,14 @@ 'ylabel_fontsize': 9, 'linewidth': 0.8, 'capsize': 3, - 'hbars':True, + 'hbars': True, 'tight_layout': True} #################################################################################################################################### -# Description of plot arguments can be found in :func:`plot_poisson_consistency_test`. +# Description of plot arguments can be found in :func:`~csep.utils.plots.plot_consistency_test`. # We set ``one_sided_lower=True`` as usual for an L-test, where the model is rejected if the observed # is located within the lower tail of the simulated distribution. ax = plots.plot_consistency_test(L_results, one_sided_lower=True, show=True, - **plot_args) - - - + **plot_args) # < Unpack arguments diff --git a/examples/tutorials/plot_gridded_forecast.py b/examples/tutorials/plot_gridded_forecast.py index 13f0065d..1d54000d 100644 --- a/examples/tutorials/plot_gridded_forecast.py +++ b/examples/tutorials/plot_gridded_forecast.py @@ -1,6 +1,9 @@ """ -Plotting gridded forecast -========================= + +.. tutorial-handling-grid-forecast: + +Handling Grid-based Forecasts +============================= This example show you how to load a gridded forecast stored in the default ASCII format. """ diff --git a/examples/tutorials/quadtree_gridded_forecast_evaluation.py b/examples/tutorials/quadtree_gridded_forecast_evaluation.py index 3006b197..d4a9306d 100644 --- a/examples/tutorials/quadtree_gridded_forecast_evaluation.py +++ b/examples/tutorials/quadtree_gridded_forecast_evaluation.py @@ -2,8 +2,8 @@ .. _quadtree_gridded-forecast-evaluation: -Quadtree Grid-based Forecast Evaluation -======================================= +Quadtree-based Forecast Evaluation +================================== This example demonstrates how to create a quadtree based single resolution-grid and multi-resolution grid. Multi-resolution grid is created using earthquake catalog, in which seismic density determines the size of a grid cell. diff --git a/examples/tutorials/working_with_catalog_forecasts.py b/examples/tutorials/working_with_catalog_forecasts.py index 499dbbb4..c8e9185b 100644 --- a/examples/tutorials/working_with_catalog_forecasts.py +++ b/examples/tutorials/working_with_catalog_forecasts.py @@ -1,5 +1,8 @@ """ -Working with catalog-based forecasts + +.. _tutorial-working-catalog-forecasts: + +Working with Catalog-based Forecasts ==================================== This example shows some basic interactions with data-based forecasts. We will load in a forecast stored in the CSEP diff --git a/requirements.yml b/requirements.yml index be2fd220..82d6d180 100644 --- a/requirements.yml +++ b/requirements.yml @@ -11,6 +11,7 @@ dependencies: - pyproj - obspy - python-dateutil + - rasterio - cartopy - shapely - mercantile From c9dea549744db51a0a543261117163708dd0baea Mon Sep 17 00:00:00 2001 From: pciturri Date: Sun, 6 Apr 2025 00:45:35 +0200 Subject: [PATCH 14/17] ci: added plots.py to coverage ft: added helper to issue deprecation warning when plot_args is passed. Added typehinting overload to legacy wrappers, so IDEs can detect signature/docstrings. fix: avoid drawing basemap when an ax is passed to plot_catalog and plot_gridded_dataset. modified .plot methods to be consistent with new plot functionality docs: remove plots.rst --- .coveragerc | 1 - csep/core/catalogs.py | 23 +-- csep/core/forecasts.py | 17 +- csep/utils/plots.py | 209 +++++++--------------- csep/utils/plots_legacy.py | 94 +++++++++- examples/tutorials/plot_customizations.py | 24 ++- 6 files changed, 197 insertions(+), 171 deletions(-) diff --git a/.coveragerc b/.coveragerc index 431e17c5..30914e73 100644 --- a/.coveragerc +++ b/.coveragerc @@ -5,7 +5,6 @@ omit = tests/* docs/* examples/* - csep/utils/plots.py csep/utils/constants.py csep/utils/datasets.py csep/utils/documents.py diff --git a/csep/core/catalogs.py b/csep/core/catalogs.py index a6632cbe..494daf52 100644 --- a/csep/core/catalogs.py +++ b/csep/core/catalogs.py @@ -841,22 +841,24 @@ def b_positive(self): pass def plot(self, ax=None, show=False, extent=None, set_global=False, **kwargs): - """ Plot catalog according to plate-carree projection. See - https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_catalog.html for - a description of keyword arguments. + """ Plots the catalog epicenters. + + See :func:`csep.utils.plots.plot_catalog` for a description of keyword arguments. Args: - ax (`matplotlib.pyplot.axes`): Previous axes onto which catalog can be drawn - show (bool): if true, show the figure. this call is blocking. + ax (matplotlib.pyplot.axes): Previous axes onto which catalog can be drawn + show (bool): If True, shows the figure. extent (list): Force an extent [lon_min, lon_max, lat_min, lat_max] set_global (bool): Whether to plot using a global projection + **kwargs (dict): Keyword arguments passed to + :func:`csep.utils.plots.plot_catalog` Returns: axes: matplotlib.Axes.axes """ # no mutable function arguments - plot_args_default = { + plot_args = { 'basemap': kwargs.pop('basemap', 'ESRI_terrain') if ax is None else None } @@ -864,17 +866,16 @@ def plot(self, ax=None, show=False, extent=None, set_global=False, **kwargs): try: # This will throw error if catalog does not have region _ = self.region.num_nodes - plot_args_default['region_border'] = True + plot_args['region_border'] = True except AttributeError: pass - plot_args = kwargs.get('plot_args', {}) - plot_args_default.update(plot_args) - plot_args_default.update(kwargs) + plot_args.update(kwargs.get('plot_args', {})) + plot_args.update(kwargs) # this call requires internet connection and basemap ax = plot_catalog(self, ax=ax, show=show, extent=extent, - set_global=set_global, **plot_args_default) + set_global=set_global, **plot_args) return ax def plot_magnitude_versus_time(self, ax=None, show=False, **kwargs): diff --git a/csep/core/forecasts.py b/csep/core/forecasts.py index 6b638382..200c2486 100644 --- a/csep/core/forecasts.py +++ b/csep/core/forecasts.py @@ -434,16 +434,25 @@ def load_ascii(cls, ascii_fname, start_date=None, end_date=None, name=None, swap def plot(self, ax=None, show=False, log=True, extent=None, set_global=False, plot_args=None, **kwargs): - """ Plot gridded forecast according to plate-carree projection + """ Plot the spatial rate of the forecast + + See :func:`csep.utils.plots.plot_gridded_dataset` for a detailed description of the + keyword arguments. Args: - show (bool): if true, show the figure. this call is blocking. - plot_args (optional/dict): dictionary containing plotting arguments for making figures + ax (`matplotlib.pyplot.axes`): Previous axes onto which catalog can be drawn + show (bool): If True, shows the figure. + log (bool): If True, plots the base-10 logarithm of the spatial rates + extent (list): Force an extent [lon_min, lon_max, lat_min, lat_max] + set_global (bool): Whether to plot using a global projection + **kwargs (dict): Keyword arguments passed to + :func:`csep.utils.plots.plot_gridded_dataset` Returns: axes: matplotlib.Axes.axes """ - # no mutable function arguments + + if self.start_time is None or self.end_time is None: time = 'forecast period' else: diff --git a/csep/utils/plots.py b/csep/utils/plots.py index 5c0d724e..3de5140c 100644 --- a/csep/utils/plots.py +++ b/csep/utils/plots.py @@ -146,19 +146,12 @@ def plot_magnitude_versus_time( """ # Initialize plot if "plot_args" in kwargs: - warnings.warn( - "'plot_args' usage is deprecated and will be removed in version 1.0.\n" - "Fine-tuning of plot appearance may not behave as expected'.\n" - "Please use explicit arguments instead (e.g., color='red').\n" - "Refer to the function's documentation for supported keyword arguments:\n" - " https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_magnitude_versus_time.html", - DeprecationWarning, - stacklevel=2 - ) + _warning_plot_args("plot_magnitude_versus_time") + plot_args = {**DEFAULT_PLOT_ARGS, **kwargs.get("plot_args", {}), **kwargs} fig, ax = pyplot.subplots(figsize=plot_args["figsize"]) if ax is None else (ax.figure, ax) - # Plot data + # Get data mag = catalog.data["magnitude"] datetimes = catalog.get_datetimes() @@ -172,6 +165,7 @@ def plot_magnitude_versus_time( xdata = datetimes xlabel = plot_args["xlabel"] or "Datetime" + # Plot data ax.scatter( xdata, mag, @@ -258,15 +252,8 @@ def _plot_cumulative_events_versus_time( """ # Initialize plot if "plot_args" in kwargs: - warnings.warn( - "'plot_args' usage is deprecated and will be removed in version 1.0.\n" - "Fine-tuning of plot appearance may not behave as expected'.\n" - "Please use explicit arguments instead (e.g., color='red').\n" - "Refer to the function's documentation for supported keyword arguments:\n" - " https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_cumulative_events_versus_time.html", - DeprecationWarning, - stacklevel=2 - ) + _warning_plot_args("plot_cumulative_events_versus_time") + plot_args = {**DEFAULT_PLOT_ARGS, **kwargs.get("plot_args", {}), **kwargs} fig, ax = pyplot.subplots(figsize=plot_args["figsize"]) if ax is None else (ax.figure, ax) @@ -443,15 +430,8 @@ def plot_magnitude_histogram( # Initialize plot if "plot_args" in kwargs: - warnings.warn( - "'plot_args' usage is deprecated and will be removed in version 1.0.\n" - "Fine-tuning of plot appearance may not behave as expected'.\n" - "Please use explicit arguments instead (e.g., color='red').\n" - "Refer to the function's documentation for supported keyword arguments:\n" - " https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_magnitude_histogram.html", - DeprecationWarning, - stacklevel=2 - ) + _warning_plot_args("plot_magnitude_histogram") + plot_args = {**DEFAULT_PLOT_ARGS, **kwargs.get("plot_args", {}), **kwargs} fig, ax = pyplot.subplots(figsize=plot_args["figsize"]) if ax is None else (ax.figure, ax) @@ -480,7 +460,6 @@ def get_histogram_synthetic_cat(x, mags, normed=True): forecast_hist = numpy.array( list(map(lambda x: get_histogram_synthetic_cat(x, magnitude_bins), forecast_mws)) ) - obs_hist, bin_edges = numpy.histogram(obs_mw, bins=magnitude_bins) bin_centers = (bin_edges[1:] + bin_edges[:-1]) / 2 @@ -489,17 +468,11 @@ def get_histogram_synthetic_cat(x, mags, normed=True): forecast_median = numpy.median(forecast_hist, axis=0) forecast_low = numpy.percentile(forecast_hist, (100 - percentile) / 2.0, axis=0) forecast_high = numpy.percentile(forecast_hist, 100 - (100 - percentile) / 2.0, axis=0) - forecast_err_lower = forecast_median - forecast_low forecast_err_upper = forecast_high - forecast_median - # Plot observed histogram - if log_scale: - plot_func = ax.semilogy - else: - plot_func = ax.plot - - plot_func( + # Plot observed counts + ax.plot( bin_centers, obs_hist, color=plot_args["color"], @@ -509,7 +482,6 @@ def get_histogram_synthetic_cat(x, mags, normed=True): label="Observation", zorder=3, ) - # Plot forecast histograms as bar plot with error bars ax.plot( bin_centers, @@ -538,7 +510,9 @@ def get_histogram_synthetic_cat(x, mags, normed=True): ax = _autoscale_histogram( ax, magnitude_bins, numpy.hstack(forecast_mws), obs_mw, mass=100 ) - + # Scale y-axis + if log_scale: + ax.set_yscale('log') # Format plot ax.grid(plot_args["grid"]) ax.legend(loc=plot_args["legend_loc"], fontsize=plot_args["legend_fontsize"]) @@ -729,24 +703,17 @@ def plot_catalog( Returns: matplotlib.axes.Axes: The Matplotlib axes object with the plotted data. """ - if "plot_args" in kwargs: - warnings.warn( - "'plot_args' usage is deprecated and will be removed in version 1.0.\n" - "Fine-tuning of plot appearance may not behave as expected'.\n" - "Please use explicit arguments instead (e.g., color='red').\n" - "Refer to the function's documentation for supported keyword arguments:\n" - " https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_catalog.html", - DeprecationWarning, - stacklevel=2 - ) + _warning_plot_args("plot_catalog") + plot_args = {**DEFAULT_PLOT_ARGS, **kwargs.get("plot_args", {}), **kwargs} # Get spatial information for plotting extent = extent or _calculate_spatial_extent(catalog, set_global, plot_region) # Instantiate GeoAxes object - ax = ax or _create_geo_axes(plot_args["figsize"], extent, projection, set_global) - # chain basemap - ax = plot_basemap(basemap, extent, ax=ax, set_global=set_global, show=False, **plot_args) + if ax is None: + ax = _create_geo_axes(plot_args["figsize"], extent, projection, set_global) + ax = plot_basemap(basemap, extent, ax=ax, set_global=set_global, show=False, + **plot_args) # Plot catalog ax.scatter( @@ -765,7 +732,6 @@ def plot_catalog( edgecolors=plot_args["markeredgecolor"], alpha=plot_args["alpha"], ) - # Legend if plot_args["legend"]: if isinstance(mag_ticks, (list, numpy.ndarray)): @@ -773,7 +739,6 @@ def plot_catalog( else: mw_range = [min(catalog.get_magnitudes()), max(catalog.get_magnitudes())] mag_ticks = numpy.linspace(mw_range[0], mw_range[1], mag_ticks or 4, endpoint=True) - # Map mag_ticks to marker sizes using the custom size mapping function legend_sizes = _autosize_scatter( values=mag_ticks, @@ -783,7 +748,6 @@ def plot_catalog( min_val=min_val or numpy.min(catalog.get_magnitudes()), max_val=max_val or numpy.max(catalog.get_magnitudes()), ) - # Create custom legend handles handles = [ pyplot.Line2D( @@ -800,7 +764,6 @@ def plot_catalog( ) for m, s in zip(mag_ticks, legend_sizes) ] - ax.legend( handles, numpy.round(mag_ticks, 1), @@ -813,7 +776,6 @@ def plot_catalog( borderpad=plot_args["legend_borderpad"], framealpha=plot_args["legend_framealpha"], ) - # Draw catalog's region border if plot_region: try: @@ -821,7 +783,6 @@ def plot_catalog( ax.plot(pts[:, 0], pts[:, 1], lw=1, color=plot_args["region_color"]) except AttributeError: pass - ax.set_title(plot_args["title"], fontsize=plot_args["title_fontsize"], y=1.06) if show: @@ -889,26 +850,17 @@ def plot_gridded_dataset( Returns: matplotlib.axes.Axes: Matplotlib axes object. """ - if "plot_args" in kwargs: - warnings.warn( - "'plot_args' usage is deprecated and will be removed in version 1.0.\n" - "Fine-tuning of plot appearance may not behave as expected'.\n" - "Please use explicit arguments instead (e.g., color='red').\n" - "Refer to the function's documentation for supported keyword arguments:\n" - " https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_gridded_dataset.html", - DeprecationWarning, - stacklevel=2 - ) + _warning_plot_args("plot_gridded_dataset") + plot_args = {**DEFAULT_PLOT_ARGS, **kwargs.get("plot_args", {}), **kwargs} # Get spatial information for plotting extent = extent or _calculate_spatial_extent(region, set_global, plot_region) # Instantiate GeoAxes object - ax = ax or _create_geo_axes(plot_args["figsize"], extent, projection, set_global) - - # chain basemap - ax = plot_basemap(basemap, extent, ax=ax, set_global=set_global, show=False, **plot_args) - + if ax is None: + ax = _create_geo_axes(plot_args["figsize"], extent, projection, set_global) + ax = plot_basemap(basemap, extent, ax=ax, set_global=set_global, show=False, + **plot_args) # Define colormap and alpha transparency colormap, alpha = _get_colormap(colormap, alpha_exp, alpha) @@ -944,7 +896,6 @@ def plot_gridded_dataset( transform=ccrs.PlateCarree()) except AttributeError: pass - ax.set_title(plot_args["title"], fontsize=plot_args["title_fontsize"], y=1.06) if show: @@ -1011,17 +962,10 @@ def plot_test_distribution( matplotlib.axes.Axes: Matplotlib axes handle. """ - # Initialize plot] if "plot_args" in kwargs: - warnings.warn( - "'plot_args' usage is deprecated and will be removed in version 1.0.\n" - "Fine-tuning of plot appearance may not behave as expected'.\n" - "Please use explicit arguments instead (e.g., color='red').\n" - "Refer to the function's documentation for supported keyword arguments:\n" - " https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_test_distribution.html", - DeprecationWarning, - stacklevel=2 - ) + _warning_plot_args("plot_test_distribution") + + # Initialize plot plot_args = {**DEFAULT_PLOT_ARGS, **kwargs.get("plot_args", {}), **kwargs} fig, ax = pyplot.subplots(figsize=plot_args["figsize"]) if ax is None else (ax.figure, ax) @@ -1140,17 +1084,10 @@ def plot_calibration_test( Returns: matplotlib.axes.Axes: The Matplotlib axes object containing the plot. """ - # Initialize plot if "plot_args" in kwargs: - warnings.warn( - "'plot_args' usage is deprecated and will be removed in version 1.0.\n" - "Fine-tuning of plot appearance may not behave as expected'.\n" - "Please use explicit arguments instead (e.g., color='red').\n" - "Refer to the function's documentation for supported keyword arguments:\n" - " https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_calibration_test.html", - DeprecationWarning, - stacklevel=2 - ) + _warning_plot_args("plot_calibration_test") + + # Initialize plot plot_args = {**DEFAULT_PLOT_ARGS, **kwargs.get("plot_args", {}), **kwargs} fig, ax = pyplot.subplots(figsize=plot_args["figsize"]) if ax is None else (ax.figure, ax) @@ -1253,18 +1190,10 @@ def _plot_comparison_test( Returns: matplotlib.axes.Axes: The Matplotlib axes object containing the plot. """ + if "plot_args" in kwargs: + _warning_plot_args("plot_comparison_test") # Initialize plot - if "plot_args" in kwargs: - warnings.warn( - "'plot_args' usage is deprecated and will be removed in version 1.0.\n" - "Fine-tuning of plot appearance may not behave as expected'.\n" - "Please use explicit arguments instead (e.g., color='red').\n" - "Refer to the function's documentation for supported keyword arguments:\n" - " https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_comparison_test.html", - DeprecationWarning, - stacklevel=2 - ) plot_args = {**DEFAULT_PLOT_ARGS, **kwargs.get("plot_args", {}), **kwargs} fig, ax = pyplot.subplots(figsize=plot_args["figsize"]) if ax is None else (ax.figure, ax) @@ -1442,18 +1371,10 @@ def _plot_consistency_test( Returns: matplotlib.axes.Axes: Matplotlib axes object with the consistency test plot. """ + if "plot_args" in kwargs: + _warning_plot_args("plot_consistency_test") # Initialize plot - if "plot_args" in kwargs: - warnings.warn( - "'plot_args' usage is deprecated and will be removed in version 1.0.\n" - "Fine-tuning of plot appearance may not behave as expected'.\n" - "Please use explicit arguments instead (e.g., color='red').\n" - "Refer to the function's documentation for supported keyword arguments:\n" - " https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_consistency_test.html", - DeprecationWarning, - stacklevel=2 - ) plot_args = {**DEFAULT_PLOT_ARGS, **kwargs.get("plot_args", {}), **kwargs} fig, ax = pyplot.subplots(figsize=plot_args["figsize"]) if ax is None else (ax.figure, ax) @@ -1583,18 +1504,10 @@ def _plot_concentration_ROC_diagram( Returns: matplotlib.axes.Axes: The Axes object with the plot. """ + if "plot_args" in kwargs: + _warning_plot_args("plot_concentration_ROC_diagram") # Initialize plot - if "plot_args" in kwargs: - warnings.warn( - "'plot_args' usage is deprecated and will be removed in version 1.0.\n" - "Fine-tuning of plot appearance may not behave as expected'.\n" - "Please use explicit arguments instead (e.g., color='red').\n" - "Refer to the function's documentation for supported keyword arguments:\n" - " https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_concentration_ROC_diagram.html", - DeprecationWarning, - stacklevel=2 - ) plot_args = {**DEFAULT_PLOT_ARGS, **kwargs.get("plot_args", {}), **kwargs} fig, ax = pyplot.subplots(figsize=plot_args["figsize"]) if ax is None else (ax.figure, ax) @@ -1706,18 +1619,10 @@ def _plot_ROC_diagram( Returns: matplotlib.pyplot.Axes: The Axes object with the plot. """ + if "plot_args" in kwargs: + _warning_plot_args("plot_ROC_diagram") # Initialize plot - if "plot_args" in kwargs: - warnings.warn( - "'plot_args' usage is deprecated and will be removed in version 1.0.\n" - "Fine-tuning of plot appearance may not behave as expected'.\n" - "Please use explicit arguments instead (e.g., color='red').\n" - "Refer to the function's documentation for supported keyword arguments:\n" - " https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_ROC_diagram.html", - DeprecationWarning, - stacklevel=2 - ) plot_args = {**DEFAULT_PLOT_ARGS, **kwargs.get("plot_args", {}), **kwargs} fig, ax = pyplot.subplots(figsize=plot_args["figsize"]) if ax is None else (ax.figure, ax) @@ -1864,17 +1769,9 @@ def _plot_Molchan_diagram( Raises: RuntimeError: If the catalog and forecast do not have the same region. """ - if "plot_args" in kwargs: - warnings.warn( - "'plot_args' usage is deprecated and will be removed in version 1.0.\n" - "Fine-tuning of plot appearance may not behave as expected'.\n" - "Please use explicit arguments instead (e.g., color='red').\n" - "Refer to the function's documentation for supported keyword arguments:\n" - " https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_Molchan_diagram.html", - DeprecationWarning, - stacklevel=2 - ) + _warning_plot_args("plot_Molchan_diagram") + plot_args = {**DEFAULT_PLOT_ARGS, **kwargs.get("plot_args", {}), **kwargs} fig, ax = pyplot.subplots(figsize=plot_args["figsize"]) if ax is None else (ax.figure, ax) @@ -2139,7 +2036,7 @@ def _clean_cache(basemap_): cache_src = fp.read() if cache_src != basemap_: if os.path.isdir(cartopy.config["cache_dir"]): - print(f"Cleaning existing {basemap_} cache") + print(f"Cleaning existing basemap cache") shutil.rmtree(cartopy.config["cache_dir"]) def _save_cache_src(basemap_): @@ -2535,6 +2432,7 @@ def _process_stat_distribution( plow = poisson.ppf((1 - percentile / 100.0) / 2.0, mean) phigh = poisson.ppf(1 - (1 - percentile / 100.0) / 2.0, mean) observed_statistic = res.observed_statistic + elif dist_type == "negative_binomial": mean = res.test_distribution[1] variance = res.test_distribution[2] @@ -2563,6 +2461,27 @@ def _process_stat_distribution( return plow, phigh, mean, observed_statistic +def _warning_plot_args(func_name: str): + """ + Issues a standardized DeprecationWarning for use of 'plot_args' in plotting functions. + + Args: + func_name (str): The full function name (e.g., 'csep.utils.plots.plot_catalog'). + """ + base_url = "https://docs.cseptesting.org/reference/generated/" + doc_url = f"{base_url}/csep.utils.plots.{func_name}.html" + + warnings.warn( + f"'plot_args' usage is deprecated and will be removed in version 1.0.\n" + f"Please use explicit keyword arguments instead (e.g., color='red').\n" + f"Fine-tuning of plot appearance via 'plot_args' may no longer behave as expected.\n\n" + f"Refer to the updated function documentation at:\n" + f" {doc_url}", + DeprecationWarning, + stacklevel=2 + ) + + # Public export of function wrappers for backwards/legacy compatibility. from .plots_legacy import (plot_cumulative_events_versus_time, plot_cumulative_events_versus_time_dev, diff --git a/csep/utils/plots_legacy.py b/csep/utils/plots_legacy.py index ae7d2858..e4648e46 100644 --- a/csep/utils/plots_legacy.py +++ b/csep/utils/plots_legacy.py @@ -1,6 +1,7 @@ import time import warnings from functools import wraps +from typing import overload, Optional, List, Union # Third-party imports import numpy @@ -93,6 +94,20 @@ def plot_cumulative_events_versus_time_dev(xdata, ydata, obs_data, return ax +@overload +def plot_cumulative_events_versus_time( + catalog_forecast: "CatalogForecast", + observation: "CSEPCatalog", + time_axis: str = "datetime", + bins: int = 50, + sim_label: Optional[str] = "Simulated", + obs_label: Optional[str] = "Observation", + ax: Optional[matplotlib.axes.Axes] = None, + show: bool = False, + **kwargs, +) -> matplotlib.axes.Axes: ... + + @wraps(_plot_cumulative_events_versus_time) def plot_cumulative_events_versus_time(*args, **kwargs): """ @@ -513,6 +528,21 @@ def plot_magnitude_histogram_dev(ses_data, obs, plot_args, show=False): return ax +@overload +def plot_basemap( + basemap: Optional[str] = None, + extent: Optional[List[float]] = None, + coastline: bool = True, + borders: bool = False, + tile_depth: Union[str, int] = "auto", + set_global: bool = False, + projection: Optional[ccrs.Projection] = None, + ax: Optional[pyplot.Axes] = None, + show: bool = False, + **kwargs, +) -> matplotlib.axes.Axes: ... + + @wraps(_plot_basemap) def plot_basemap(*args, **kwargs): legacy_keys = {"tile_scaling", "apprx", "central_latitude"} @@ -1218,7 +1248,6 @@ def plot_spatial_test(evaluation_result, axes=None, plot_args=None, show=True): return ax - def plot_poisson_consistency_test(eval_results, normalize=False, one_sided_lower=False, axes=None, plot_args=None, show=False): @@ -1377,6 +1406,7 @@ def plot_poisson_consistency_test(eval_results, normalize=False, return ax + def _get_marker_style(obs_stat, p, one_sided_lower): """Returns matplotlib marker style as fmt string""" if obs_stat < p[0] or obs_stat > p[1]: @@ -1401,6 +1431,16 @@ def _get_axis_limits(pnts, border=0.05): return (x_min - xd, x_max + xd) +@overload +def plot_comparison_test( + results_t: List["EvaluationResult"], + results_w: Optional[List["EvaluationResult"]] = None, + percentile: int = 95, + ax: Optional[matplotlib.axes.Axes] = None, + show: bool = False, + **kwargs, +) -> pyplot.Axes: ... + @wraps(_plot_comparison_test) def plot_comparison_test(*args, **kwargs): @@ -1418,6 +1458,7 @@ def plot_comparison_test(*args, **kwargs): return _plot_comparison_test(*args, **kwargs) + def _get_marker_t_color(distribution): """Returns matplotlib marker style as fmt string""" if distribution[0] > 0. and distribution[1] > 0.: @@ -1441,6 +1482,20 @@ def _get_marker_w_color(distribution, percentile): return fmt +@overload +def plot_consistency_test( + eval_results: Union[List["EvaluationResult"], "EvaluationResult"], + normalize: bool = False, + one_sided_lower: bool = False, + percentile: float = 95, + plot_mean: bool = False, + color: str = "black", + ax: Optional[pyplot.Axes] = None, + show: bool = False, + **kwargs, +) -> matplotlib.axes.Axes: ... + + @wraps(_plot_consistency_test) def plot_consistency_test(*args, **kwargs): """ @@ -1469,6 +1524,7 @@ def plot_consistency_test(*args, **kwargs): return _plot_consistency_test(*args, **kwargs) + def _plot_consistency_test_legacy_impl(eval_results, normalize=False, axes=None, one_sided_lower=False, variance=None, plot_args=None, show=False): @@ -1628,6 +1684,18 @@ def _plot_consistency_test_legacy_impl(eval_results, normalize=False, axes=None, return ax +@overload +def plot_concentration_ROC_diagram( + forecast: "GriddedForecast", + catalog: "CSEPCatalog", + linear: bool = True, + plot_uniform: bool = True, + ax: Optional[pyplot.Axes] = None, + show: bool = True, + **kwargs, +) -> matplotlib.axes.Axes: ... + + @wraps(_plot_concentration_ROC_diagram) def plot_concentration_ROC_diagram(*args, **kwargs): """ @@ -1660,6 +1728,18 @@ def plot_concentration_ROC_diagram(*args, **kwargs): return _plot_concentration_ROC_diagram(*args, **kwargs) +@overload +def plot_ROC_diagram( + forecast: "GriddedForecast", + catalog: "CSEPCatalog", + linear: bool = True, + plot_uniform: bool = True, + ax: Optional[pyplot.Axes] = None, + show: bool = True, + **kwargs, +) -> matplotlib.pyplot.Axes: ... + + @wraps(_plot_ROC_diagram) def plot_ROC_diagram(*args, **kwargs): """ @@ -1692,6 +1772,18 @@ def plot_ROC_diagram(*args, **kwargs): return _plot_ROC_diagram(*args, **kwargs) +@overload +def plot_Molchan_diagram( + forecast: "GriddedForecast", + catalog: "CSEPCatalog", + linear: bool = True, + plot_uniform: bool = True, + ax: Optional[pyplot.Axes] = None, + show: bool = True, + **kwargs, +) -> matplotlib.axes.Axes: ... + + @wraps(_plot_Molchan_diagram) def plot_Molchan_diagram(*args, **kwargs): """ diff --git a/examples/tutorials/plot_customizations.py b/examples/tutorials/plot_customizations.py index 4ac90afe..20b58599 100644 --- a/examples/tutorials/plot_customizations.py +++ b/examples/tutorials/plot_customizations.py @@ -12,8 +12,8 @@ 2. Set the extent of maps 3. Visualizing selected magnitude bins 4. Plot global maps - 5. Composing plots - 5. Plot multiple Evaluation Results + 5. Creating composite plots + 6. Plot multiple Evaluation Results """ @@ -27,7 +27,6 @@ import csep import cartopy import numpy - from csep.utils import datasets, plots #################################################################################################################################### @@ -44,6 +43,7 @@ # # These arguments are, in order: # +# * Set the figure size # * Set the spatial extent of the plot # * Access ESRI Imagery as a basemap. # * Assign a title @@ -57,7 +57,8 @@ # The complete description of plot arguments can be found in :func:`csep.utils.plots.plot_gridded_dataset` # -ax = forecast.plot(extent=[3, 22, 35, 48], +ax = forecast.plot(figsize=(10, 8), + extent=[3, 22, 35, 48], basemap='ESRI_imagery', title='Italy 10 year forecast', grid_labels=True, @@ -99,6 +100,7 @@ # The data is stored in a 1D array, so it should be projected into the `region` 2D cartesian grid. rate_sum = forecast.region.get_cartesian(rate_sum) +rate_sum_log = numpy.log10(rate_sum) #################################################################################################################################### # **Plotting the dataset** @@ -108,7 +110,10 @@ # ax = plots.plot_gridded_dataset( - numpy.log10(rate_sum), forecast.region, + # Required arguments + rate_sum_log, + forecast.region, + # Optional keyword arguments figsize=(10, 6), set_global=True, coastline_color='black', @@ -197,18 +202,19 @@ #################################################################################################################################### # **Initialize a basemap with desired arguments** # -# Plot the basemap using :func:`csep.utils.plots.plot_basemap`. Do not set ```show=True``` and store the returned ```ax``` object to +# Plot the basemap alone by using :func:`csep.utils.plots.plot_basemap`. Do not set ``show=True`` and store the returned ``ax`` object to # start the composite plot ax = plots.plot_basemap(figsize=(8, 8), projection=cartopy.crs.AlbersEqualArea(central_longitude=-120.), extent=forecast.region.get_bbox(), - basemap='ESRI_terrain', - coastline_color='darkred', + basemap='ESRI_relief', + coastline_color='gray', + coastline_linewidth=1 ) # Pass the ax object into a consecutive plot -ax = forecast.plot(colormap='PuBu_r', ax=ax) +ax = forecast.plot(colormap='PuBu_r', alpha_exp=0.5, ax=ax) # Use show=True to finalize the composite. catalog.plot(markercolor='darkred', ax=ax, show=True) From aebad739325a12863f2c628dce9f660e5e831888 Mon Sep 17 00:00:00 2001 From: pciturri Date: Sun, 6 Apr 2025 14:16:19 +0200 Subject: [PATCH 15/17] docs: detailed plot_basemap args within plot_gridded_datasets. Added plot legend option to plot_consistency() to explain its symbology. Abstracted draw_shaded_bars from plot_consistency and plot_comparison test. Plot_consistency defaults to plot name of the first EvaluationResult. --- csep/utils/plots.py | 456 ++++++++++++++++++++++++-------------------- tests/test_plots.py | 37 +++- 2 files changed, 278 insertions(+), 215 deletions(-) diff --git a/csep/utils/plots.py b/csep/utils/plots.py index 3de5140c..39c21038 100644 --- a/csep/utils/plots.py +++ b/csep/utils/plots.py @@ -35,7 +35,6 @@ from csep.models import EvaluationResult from csep.core.regions import CartesianGrid2D - DEFAULT_PLOT_ARGS = { # General figure/axes handling "figsize": None, @@ -95,16 +94,16 @@ # Data-exploratory plots ######################## def plot_magnitude_versus_time( - catalog: "CSEPCatalog", - color: str = "steelblue", - size: int = 4, - max_size: int = 300, - power: int = 4, - alpha: float = 0.5, - reset_times: bool = False, - ax: Optional[matplotlib.axes.Axes] = None, - show: bool = False, - **kwargs: Any, + catalog: "CSEPCatalog", + color: str = "steelblue", + size: int = 4, + max_size: int = 300, + power: int = 4, + alpha: float = 0.5, + reset_times: bool = False, + ax: Optional[matplotlib.axes.Axes] = None, + show: bool = False, + **kwargs: Any, ) -> matplotlib.axes.Axes: """ Scatter plot of the catalog magnitudes and origin times. The size of each event is scaled @@ -196,15 +195,15 @@ def plot_magnitude_versus_time( def _plot_cumulative_events_versus_time( - catalog_forecast: "CatalogForecast", - observation: "CSEPCatalog", - time_axis: str = "datetime", - bins: int = 50, - sim_label: Optional[str] = "Simulated", - obs_label: Optional[str] = "Observation", - ax: Optional[matplotlib.axes.Axes] = None, - show: bool = False, - **kwargs, + catalog_forecast: "CatalogForecast", + observation: "CSEPCatalog", + time_axis: str = "datetime", + bins: int = 50, + sim_label: Optional[str] = "Simulated", + obs_label: Optional[str] = "Observation", + ax: Optional[matplotlib.axes.Axes] = None, + show: bool = False, + **kwargs, ) -> matplotlib.axes.Axes: """ Plots the cumulative number of forecasted events from a @@ -376,14 +375,14 @@ def _plot_cumulative_events_versus_time( def plot_magnitude_histogram( - catalog_forecast: Union["CatalogForecast", List["CSEPCatalog"]], - observation: "CSEPCatalog", - magnitude_bins: Optional[Union[List[float], numpy.ndarray]] = None, - percentile: int = 95, - log_scale: bool = True, - ax: Optional["matplotlib.axes.Axes"] = None, - show: bool = False, - **kwargs, + catalog_forecast: Union["CatalogForecast", List["CSEPCatalog"]], + observation: "CSEPCatalog", + magnitude_bins: Optional[Union[List[float], numpy.ndarray]] = None, + percentile: int = 95, + log_scale: bool = True, + ax: Optional["matplotlib.axes.Axes"] = None, + show: bool = False, + **kwargs, ) -> matplotlib.axes.Axes: """ Generates a semi-log magnitude histogram comparing a catalog-based forecast with observed @@ -534,16 +533,16 @@ def get_histogram_synthetic_cat(x, mags, normed=True): # Spatial plots ############### def _plot_basemap( - basemap: Optional[str] = None, - extent: Optional[List[float]] = None, - coastline: bool = True, - borders: bool = False, - tile_depth: Union[str, int] = "auto", - set_global: bool = False, - projection: Optional[ccrs.Projection] = None, - ax: Optional[pyplot.Axes] = None, - show: bool = False, - **kwargs, + basemap: Optional[str] = None, + extent: Optional[List[float]] = None, + coastline: bool = True, + borders: bool = False, + tile_depth: Union[str, int] = "auto", + set_global: bool = False, + projection: Optional[ccrs.Projection] = None, + ax: Optional[pyplot.Axes] = None, + show: bool = False, + **kwargs, ) -> matplotlib.axes.Axes: """ Wrapper function for multiple Cartopy base plots, including access to standard raster @@ -636,21 +635,21 @@ def _plot_basemap( def plot_catalog( - catalog: "CSEPCatalog", - basemap: Optional[str] = None, - projection: Optional[Union[ccrs.Projection, str]] = None, - extent: Optional[Sequence[float]] = None, - set_global: bool = False, - mag_ticks: Optional[Union[Sequence[float], numpy.ndarray, int]] = None, - size: float = 15, - max_size: float = 300, - power: float = 3, - min_val: Optional[float] = None, - max_val: Optional[float] = None, - plot_region: bool = False, - ax: Optional[matplotlib.axes.Axes] = None, - show: bool = False, - **kwargs, + catalog: "CSEPCatalog", + basemap: Optional[str] = None, + projection: Optional[Union[ccrs.Projection, str]] = None, + extent: Optional[Sequence[float]] = None, + set_global: bool = False, + mag_ticks: Optional[Union[Sequence[float], numpy.ndarray, int]] = None, + size: float = 15, + max_size: float = 300, + power: float = 3, + min_val: Optional[float] = None, + max_val: Optional[float] = None, + plot_region: bool = False, + ax: Optional[matplotlib.axes.Axes] = None, + show: bool = False, + **kwargs, ) -> matplotlib.axes.Axes: """ Spatial plot of catalog. Can be plotted over a basemap if desired, by passing the keyword @@ -792,22 +791,22 @@ def plot_catalog( def plot_gridded_dataset( - gridded: numpy.ndarray, - region: "CartesianGrid2D", - basemap: Optional[str] = None, - projection: Optional[Union[ccrs.Projection, str]] = None, - extent: Optional[List[float]] = None, - set_global: bool = False, - plot_region: bool = True, - colorbar: bool = True, - colormap: Union[str, matplotlib.colors.Colormap] = "viridis", - clim: Optional[Tuple[float, float]] = None, - clabel: Optional[str] = None, - alpha: Optional[float] = None, - alpha_exp: float = 0, - ax: Optional[pyplot.Axes] = None, - show: bool = False, - **kwargs, + gridded: numpy.ndarray, + region: "CartesianGrid2D", + basemap: Optional[str] = None, + projection: Optional[Union[ccrs.Projection, str]] = None, + extent: Optional[List[float]] = None, + set_global: bool = False, + plot_region: bool = True, + colorbar: bool = True, + colormap: Union[str, matplotlib.colors.Colormap] = "viridis", + clim: Optional[Tuple[float, float]] = None, + clabel: Optional[str] = None, + alpha: Optional[float] = None, + alpha_exp: float = 0, + ax: Optional[pyplot.Axes] = None, + show: bool = False, + **kwargs, ) -> matplotlib.axes.Axes: """ Plot spatial gridded dataset such as data from a gridded forecast. Can be plotted over a @@ -823,6 +822,9 @@ def plot_gridded_dataset( (whose indices correspond to each spatial cell) to a 2D-square array. region (CartesianGrid2D): Region in which gridded values are contained. basemap (str): Passed to :func:`~csep.utils.plots.plot_basemap` along with `kwargs`. + Possible values are: `'stock_img'`, `'google-satellite'`, `'ESRI_terrain'`, + `'ESRI_imagery'`, `'ESRI_relief'`, `'ESRI_topo'`, a custom web service link, or a + GeoTiff filepath. Defaults to `None`. projection (cartopy.crs.Projection or str): Projection to be used in the underlying basemap. It can be a cartopy projection instance, or `approx` for a quick approximation of Mercator. Defaults to :class:`~cartopy.crs.PlateCarree` if `None`. @@ -908,16 +910,16 @@ def plot_gridded_dataset( # Single Result plots ##################### def plot_test_distribution( - evaluation_result: "EvaluationResult", - bins: Union[str, int, List[Any]] = "fd", - percentile: Optional[int] = 95, - auto_annotate: Union[bool, dict] = True, - sim_label: str = "Simulated", - obs_label: str = "Observation", - legend: bool = True, - ax: Optional[matplotlib.axes.Axes] = None, - show: bool = False, - **kwargs, + evaluation_result: "EvaluationResult", + bins: Union[str, int, List[Any]] = "fd", + percentile: Optional[int] = 95, + auto_annotate: Union[bool, dict] = True, + sim_label: str = "Simulated", + obs_label: str = "Observation", + legend: bool = True, + ax: Optional[matplotlib.axes.Axes] = None, + show: bool = False, + **kwargs, ) -> matplotlib.axes.Axes: """ Plots a histogram of a single statistic for stochastic event sets and observations. @@ -1045,12 +1047,12 @@ def plot_test_distribution( def plot_calibration_test( - evaluation_result: "EvaluationResult", - percentile: float = 95, - label: Optional[str] = None, - ax: Optional[matplotlib.axes.Axes] = None, - show: bool = False, - **kwargs, + evaluation_result: "EvaluationResult", + percentile: float = 95, + label: Optional[str] = None, + ax: Optional[matplotlib.axes.Axes] = None, + show: bool = False, + **kwargs, ) -> matplotlib.axes.Axes: """ Plots a calibration test (Quantile-Quantile plot) with confidence intervals. @@ -1150,12 +1152,12 @@ def plot_calibration_test( # Results batch plots ##################### def _plot_comparison_test( - results_t: List["EvaluationResult"], - results_w: Optional[List["EvaluationResult"]] = None, - percentile: int = 95, - ax: Optional[matplotlib.axes.Axes] = None, - show: bool = False, - **kwargs, + results_t: List["EvaluationResult"], + results_w: Optional[List["EvaluationResult"]] = None, + percentile: int = 95, + ax: Optional[matplotlib.axes.Axes] = None, + show: bool = False, + **kwargs, ) -> pyplot.Axes: """ Plots a list of T-Test (and optional W-Test) results on a single axis. @@ -1268,15 +1270,7 @@ def _plot_comparison_test( ax.yaxis.set_major_locator(pyplot.MaxNLocator(integer=True)) if plot_args["hbars"]: - if len(results_t) > 2: - ax.bar( - ax.get_xticks(), - numpy.array([9999] * len(ax.get_xticks())), - bottom=-2000, - width=(ax.get_xticks()[1] - ax.get_xticks()[0]), - color=["gray", "w"], - alpha=0.2, - ) + ax = _draw_shaded_bars(ax, len(results_t), orientation='vertical') if plot_args["legend"]: # Add custom legend to explain results @@ -1289,28 +1283,33 @@ def _plot_comparison_test( ] if results_w is not None: legend_elements.extend([ - Line2D( - [0], - [0], - color="gray", - lw=2, - marker="o", - markersize=6, - markerfacecolor="green", - label="W-test non-rejected", - ), - Line2D( - [0], - [0], - color="gray", - lw=2, - marker="o", - markersize=6, - markerfacecolor="white", - label="W-test indistinguishable", - )]) - - ax.legend(handles=legend_elements, loc="best", fontsize=plot_args["legend_fontsize"]) + Line2D( + [0], + [0], + color="gray", + lw=2, + marker="o", + markersize=6, + markerfacecolor="green", + label="W-test non-rejected", + ), + Line2D( + [0], + [0], + color="gray", + lw=2, + marker="o", + markersize=6, + markerfacecolor="white", + label="W-test indistinguishable", + )]) + + ax.legend(handles=legend_elements, + loc=plot_args['legend_loc'], + fontsize=plot_args["legend_fontsize"], + labelspacing=plot_args["legend_labelspacing"], + borderpad=plot_args["legend_borderpad"], + framealpha=plot_args["legend_framealpha"]) if plot_args["tight_layout"]: fig.tight_layout() @@ -1322,15 +1321,15 @@ def _plot_comparison_test( def _plot_consistency_test( - eval_results: Union[List["EvaluationResult"], "EvaluationResult"], - normalize: bool = False, - one_sided_lower: bool = False, - percentile: float = 95, - plot_mean: bool = False, - color: str = "black", - ax: Optional[pyplot.Axes] = None, - show: bool = False, - **kwargs, + eval_results: Union[List["EvaluationResult"], "EvaluationResult"], + normalize: bool = False, + one_sided_lower: bool = False, + percentile: float = 95, + plot_mean: bool = False, + color: str = "black", + ax: Optional[pyplot.Axes] = None, + show: bool = False, + **kwargs, ) -> matplotlib.axes.Axes: """ Plots the results from multiple consistency tests. The distribution of score results from @@ -1428,23 +1427,35 @@ def _plot_consistency_test( ax.set_ylim([-0.5, len(results) - 0.5]) ax.set_yticks(numpy.arange(len(results))) ax.set_yticklabels([res.sim_name for res in results], fontsize=plot_args["ylabel_fontsize"]) + ax.tick_params(axis="x", labelsize=plot_args["xticks_fontsize"]) + ax.set_xlabel( - plot_args["xlabel"] or "Statistic distribution", fontsize=plot_args["xlabel_fontsize"] + plot_args["xlabel"] or "Statistic value", fontsize=plot_args["xlabel_fontsize"] ) - ax.tick_params(axis="x", labelsize=plot_args["xticks_fontsize"]) - ax.set_title(plot_args["title"], fontsize=plot_args["title_fontsize"]) + ax.set_title(plot_args["title"] or results[0].name, fontsize=plot_args["title_fontsize"]) + if plot_args["hbars"]: - yTickPos = ax.get_yticks() - if len(yTickPos) >= 2: - ax.barh( - yTickPos, - numpy.array([99999] * len(yTickPos)), - left=-10000, - height=(yTickPos[1] - yTickPos[0]), - color=["w", "gray"], - alpha=0.2, - zorder=0, + _draw_shaded_bars(ax, len(results), orientation='horizontal') + + if plot_args["legend"]: + legend_elements = [Line2D([0], [1], color='green', marker='s', lw=0, markersize=4, + label='Observations (consistent)'), + Line2D([0], [1], color='red', marker='o', lw=0, markersize=4, + label='Observations (rejected)'), + Line2D([0], [0], color='k', lw=1, + label=f'Simulations {percentile}% conf.')] + if plot_mean: + legend_elements.append( + Line2D([0], [0], marker='o', lw=0, label='Simulations mean value', + color='k', markersize=2), ) + ax.legend(handles=legend_elements, + loc=plot_args['legend_loc'], + fontsize=plot_args["legend_fontsize"], + labelspacing=plot_args["legend_labelspacing"], + borderpad=plot_args["legend_borderpad"], + framealpha=plot_args["legend_framealpha"]) + if plot_args["tight_layout"]: fig.tight_layout() @@ -1458,13 +1469,13 @@ def _plot_consistency_test( # Alarm-based plots ################### def _plot_concentration_ROC_diagram( - forecast: "GriddedForecast", - catalog: "CSEPCatalog", - linear: bool = True, - plot_uniform: bool = True, - ax: Optional[pyplot.Axes] = None, - show: bool = True, - **kwargs, + forecast: "GriddedForecast", + catalog: "CSEPCatalog", + linear: bool = True, + plot_uniform: bool = True, + ax: Optional[pyplot.Axes] = None, + show: bool = True, + **kwargs, ) -> matplotlib.axes.Axes: """ Plots the Concentration ROC Diagram for a given forecast and observed catalog. @@ -1576,13 +1587,13 @@ def _plot_concentration_ROC_diagram( def _plot_ROC_diagram( - forecast: "GriddedForecast", - catalog: "CSEPCatalog", - linear: bool = True, - plot_uniform: bool = True, - ax: Optional[pyplot.Axes] = None, - show: bool = True, - **kwargs, + forecast: "GriddedForecast", + catalog: "CSEPCatalog", + linear: bool = True, + plot_uniform: bool = True, + ax: Optional[pyplot.Axes] = None, + show: bool = True, + **kwargs, ) -> matplotlib.pyplot.Axes: """ Plots the ROC (Receiver Operating Characteristic) curve for a given forecast and observed @@ -1648,10 +1659,10 @@ def _plot_ROC_diagram( forecastedNo_observedNo = obs_counts[(binary_forecast == 0) & (obs_counts == 0)] H = len(forecastedYes_observedYes) / ( - len(forecastedYes_observedYes) + len(forecastedNo_observedYes) + len(forecastedYes_observedYes) + len(forecastedNo_observedYes) ) F = len(forecastedYes_observedNo) / ( - len(forecastedYes_observedNo) + len(forecastedNo_observedNo) + len(forecastedYes_observedNo) + len(forecastedNo_observedNo) ) threshold_row = {"Threshold": threshold, "H": H, "F": F} @@ -1705,15 +1716,14 @@ def _plot_ROC_diagram( def _plot_Molchan_diagram( - forecast: "GriddedForecast", - catalog: "CSEPCatalog", - linear: bool = True, - plot_uniform: bool = True, - ax: Optional[pyplot.Axes] = None, - show: bool = True, - **kwargs, + forecast: "GriddedForecast", + catalog: "CSEPCatalog", + linear: bool = True, + plot_uniform: bool = True, + ax: Optional[pyplot.Axes] = None, + show: bool = True, + **kwargs, ) -> matplotlib.axes.Axes: - """ Plot the Molchan Diagram based on forecast and test catalogs using the contingency table. The Area Skill score and its error are shown in the legend. @@ -1823,14 +1833,16 @@ def _plot_Molchan_diagram( contingency_df = pandas.DataFrame(data, index=index) nu = contingency_df.loc["Not Forecasted", "Observed"] / contingency_df["Observed"].sum() tau = contingency_df.loc["Forecasted"].sum() / ( - contingency_df.loc["Forecasted"].sum() + contingency_df.loc["Not Forecasted"].sum() + contingency_df.loc["Forecasted"].sum() + contingency_df.loc[ + "Not Forecasted"].sum() ) R_score = ( - contingency_df.loc["Forecasted", "Observed"] / contingency_df["Observed"].sum() - ) - ( - contingency_df.loc["Forecasted", "Not Observed"] - / contingency_df["Not Observed"].sum() - ) + contingency_df.loc["Forecasted", "Observed"] / contingency_df[ + "Observed"].sum() + ) - ( + contingency_df.loc["Forecasted", "Not Observed"] + / contingency_df["Not Observed"].sum() + ) threshold_row = { "Threshold": threshold, @@ -1885,9 +1897,9 @@ def _plot_Molchan_diagram( bin_size = 0.01 devstd = numpy.sqrt(1 / (12 * Table_molchan["Obs_active_bins"].iloc[0])) - devstd = devstd * bin_size**-1 + devstd = devstd * bin_size ** -1 devstd = numpy.ceil(devstd + 0.5) - devstd = devstd / bin_size**-1 + devstd = devstd / bin_size ** -1 dev_std = numpy.round(devstd, 2) # Plot the Molchan trajectory @@ -2107,12 +2119,12 @@ def _save_cache_src(basemap_): def _autosize_scatter( - values: numpy.ndarray, - min_size: float = 50.0, - max_size: float = 400.0, - power: float = 3.0, - min_val: Optional[float] = None, - max_val: Optional[float] = None, + values: numpy.ndarray, + min_size: float = 50.0, + max_size: float = 400.0, + power: float = 3.0, + min_val: Optional[float] = None, + max_val: Optional[float] = None, ) -> numpy.ndarray: """ Auto-sizes scatter plot markers based on values. @@ -2136,11 +2148,11 @@ def _autosize_scatter( def _autoscale_histogram( - ax: matplotlib.axes.Axes, - bin_edges: numpy.ndarray, - simulated: numpy.ndarray, - observation: numpy.ndarray, - mass: float = 99.5, + ax: matplotlib.axes.Axes, + bin_edges: numpy.ndarray, + simulated: numpy.ndarray, + observation: numpy.ndarray, + mass: float = 99.5, ) -> matplotlib.axes.Axes: """ Autoscale the histogram axes based on the data distribution. @@ -2180,11 +2192,38 @@ def _autoscale_histogram( return ax +def _draw_shaded_bars(ax, n_results, orientation='vertical'): + if n_results > 2: + if orientation == 'vertical': + ax.bar( + ax.get_xticks(), + numpy.array([9999] * len(ax.get_xticks())), + bottom=-2000, + width=(ax.get_xticks()[1] - ax.get_xticks()[0]), + color=["gray", "w"], + alpha=0.2, + ) + if orientation == 'horizontal': + yTickPos = ax.get_yticks() + if len(yTickPos) >= 2: + ax.barh( + yTickPos, + numpy.array([99999] * len(yTickPos)), + left=-10000, + height=(yTickPos[1] - yTickPos[0]), + color=["w", "gray"], + alpha=0.2, + zorder=0, + ) + + return ax + + def _annotate_distribution_plot( - ax: matplotlib.axes.Axes, - evaluation_result: "EvaluationResult", - auto_annotate: bool, - plot_args: Dict[str, Any], + ax: matplotlib.axes.Axes, + evaluation_result: "EvaluationResult", + auto_annotate: bool, + plot_args: Dict[str, Any], ) -> matplotlib.axes.Axes: """ Annotates a distribution plot based on the evaluation result type. @@ -2255,7 +2294,7 @@ def _annotate_distribution_plot( ) else: - xlabel = "Statistic" + xlabel = "Statistic value" ylabel = "Number of Catalogs" if annotation_text or plot_args.get("annotation_text"): @@ -2273,10 +2312,10 @@ def _annotate_distribution_plot( def _calculate_spatial_extent( - element: Union["CSEPCatalog", "CartesianGrid2D"], - set_global: bool, - region_border: bool, - padding_fraction: float = 0.05, + element: Union["CSEPCatalog", "CartesianGrid2D"], + set_global: bool, + region_border: bool, + padding_fraction: float = 0.05, ) -> Optional[List[float]]: """ Calculates the spatial extent for plotting based on the catalog. @@ -2308,10 +2347,10 @@ def _calculate_spatial_extent( def _create_geo_axes( - figsize: Optional[Tuple[float, float]], - extent: Optional[List[float]], - projection: Union[ccrs.Projection, str], - set_global: bool, + figsize: Optional[Tuple[float, float]], + extent: Optional[List[float]], + projection: Union[ccrs.Projection, str], + set_global: bool, ) -> pyplot.Axes: """ Creates and returns GeoAxes for plotting. @@ -2366,9 +2405,9 @@ def _add_gridlines(ax: matplotlib.axes.Axes, grid_labels: bool, grid_fontsize: f def _get_colormap( - cmap: Union[str, matplotlib.colors.Colormap], - alpha_exp: float, - alpha_0: Optional[float] = None, + cmap: Union[str, matplotlib.colors.Colormap], + alpha_exp: float, + alpha_0: Optional[float] = None, ) -> Tuple[matplotlib.colors.ListedColormap, Optional[float]]: """ Defines the colormap and applies alpha transparency based on the given parameters. @@ -2405,10 +2444,10 @@ def _get_colormap( def _process_stat_distribution( - res: "EvaluationResult", - percentile: float, - normalize: bool, - one_sided_lower: bool, + res: "EvaluationResult", + percentile: float, + normalize: bool, + one_sided_lower: bool, ) -> Tuple[float, float, float, float]: """ Processes the statistical distribution based on its type and returns plotting values. @@ -2437,7 +2476,7 @@ def _process_stat_distribution( mean = res.test_distribution[1] variance = res.test_distribution[2] upsilon = 1.0 - ((variance - mean) / variance) - tau = mean**2 / (variance - mean) + tau = mean ** 2 / (variance - mean) plow = nbinom.ppf((1 - percentile / 100.0) / 2.0, tau, upsilon) phigh = nbinom.ppf(1 - (1 - percentile / 100.0) / 2.0, tau, upsilon) observed_statistic = res.observed_statistic @@ -2502,4 +2541,3 @@ def _warning_plot_args(func_name: str): plot_concentration_ROC_diagram, plot_ROC_diagram, plot_Molchan_diagram) - diff --git a/tests/test_plots.py b/tests/test_plots.py index 134cd151..8988a62a 100644 --- a/tests/test_plots.py +++ b/tests/test_plots.py @@ -50,7 +50,7 @@ _autoscale_histogram, # noqa _annotate_distribution_plot, # noqa _get_colormap, # noqa - _process_stat_distribution, # noqa + _process_stat_distribution, _draw_shaded_bars, # noqa ) @@ -119,7 +119,8 @@ def test_plot_magnitude_vs_time(self): self.assertEqual(ax.get_ylabel(), "Magnitude") # Test with custom color - ax = plot_magnitude_versus_time(catalog=self.observation_m2, color="red", show=show_plots) + ax = plot_magnitude_versus_time(catalog=self.observation_m2, color="red", + show=show_plots) scatter_color = ax.collections[0].get_facecolor()[0] self.assertTrue(all(scatter_color[:3] == (1.0, 0.0, 0.0))) # Check if color is red @@ -147,7 +148,8 @@ def test_plot_magnitude_vs_time(self): plt.close("all") # Test with reset_times=True - ax = plot_magnitude_versus_time(catalog=self.observation_m2, reset_times=True, show=show_plots) + ax = plot_magnitude_versus_time(catalog=self.observation_m2, reset_times=True, + show=show_plots) x_data = ax.collections[0].get_offsets().data[:, 0] # extract x from scatter plot # Check that the X-axis label is correct @@ -520,13 +522,14 @@ def setUp(self): # Mocking EvaluationResult for testing self.mock_result = Mock() self.mock_result.sim_name = "Mock Forecast" + self.mock_result.name = "Mock Test" self.mock_result.test_distribution = numpy.random.normal(loc=10, scale=2, size=100) self.mock_result.observed_statistic = 8 def test_plot_consistency_basic(self): ax = plot_consistency_test(eval_results=self.mock_result, show=show_plots) - self.assertEqual(ax.get_title(), "") - self.assertEqual(ax.get_xlabel(), "Statistic distribution") + self.assertEqual(ax.get_title(), "Mock Test") + self.assertEqual(ax.get_xlabel(), "Statistic value") def test_plot_consistency_with_multiple_results(self): mock_results = [self.mock_result for _ in range(5)] @@ -605,7 +608,7 @@ def test_SingleNTestPlot(self): [i.get_text() for i in matplotlib.pyplot.gca().get_yticklabels()], [i.sim_name for i in [Ntest_result]], ) - self.assertEqual(matplotlib.pyplot.gca().get_title(), "") + self.assertEqual(matplotlib.pyplot.gca().get_title(), "Mock NTest") def test_MultiNTestPlot(self): @@ -1338,6 +1341,28 @@ def test_no_alpha_exponent(self): self.assertEqual(alpha, 1) self.assertTrue(numpy.all(cmap.colors[:, -1] == 1)) # No alpha modification + def test_plot_shaded_bars_vertical(self): + fig, ax = plt.subplots() + ax.set_xticks([0, 1, 2, 3]) + ax = _draw_shaded_bars(ax, n_results=4, orientation="vertical") + self.assertGreater(len(ax.patches), 0) + for patch_ in ax.patches: + self.assertGreaterEqual(patch_.get_alpha(), 0.2) + + def test_plot_shaded_bars_horizontal(self): + fig, ax = plt.subplots() + ax.set_yticks([0, 1, 2, 3]) + ax = _draw_shaded_bars(ax, n_results=4, orientation="horizontal") + self.assertGreater(len(ax.patches), 0) + for patch_ in ax.patches: + self.assertGreaterEqual(patch_.get_alpha(), 0.2) + + def test_plot_shaded_bars_skips_when_few_results(self): + fig, ax = plt.subplots() + ax.set_xticks([0, 1, 2]) + ax = _draw_shaded_bars(ax, n_results=2, orientation="vertical") + self.assertEqual(len(ax.patches), 0) + def tearDown(self): plt.close("all") gc.collect() From 9888bcfdbe3141917df8330d0ec81ec30fe94f9d Mon Sep 17 00:00:00 2001 From: pciturri Date: Sun, 13 Apr 2025 22:38:09 +0200 Subject: [PATCH 16/17] docs: added references to plotting API. added references in each docstring to where the function is used in the tutorials. Added and fixed multiple docs references. Added changelogs in docstrings with versionchanged/versionadded directives to outline major changes. Added optional label to multiple args in docstrings ft: re-added xlabel_rotation for comparison_plots fix: typos in docstrings build-sphinx: rewrite "make clean" directive, to effectively delete generated sphinx-gallery and sphinx-autodocs material. --- csep/__init__.py | 2 +- csep/utils/plots.py | 463 ++++++++++++------ docs/Makefile | 3 +- docs/concepts/evaluations.rst | 2 +- docs/concepts/forecasts.rst | 2 +- docs/concepts/regions.rst | 2 - docs/getting_started/theory.rst | 4 + docs/reference/api_reference.rst | 24 +- examples/tutorials/catalog_filtering.py | 3 + .../tutorials/catalog_forecast_evaluation.py | 6 + .../tutorials/gridded_forecast_evaluation.py | 12 + examples/tutorials/plot_customizations.py | 41 +- examples/tutorials/plot_gridded_forecast.py | 5 +- .../quadtree_gridded_forecast_evaluation.py | 3 + .../working_with_catalog_forecasts.py | 3 + 15 files changed, 400 insertions(+), 175 deletions(-) diff --git a/csep/__init__.py b/csep/__init__.py index 2710d0f5..d0d581f9 100644 --- a/csep/__init__.py +++ b/csep/__init__.py @@ -333,7 +333,7 @@ def query_gns(start_time, end_time, min_magnitude=2.950, verbose (bool): print catalog summary statistics Returns: - :class:`csep.core.catalogs.CSEPCatalog + :class:`csep.core.catalogs.CSEPCatalog` """ # Timezone should be in UTC diff --git a/csep/utils/plots.py b/csep/utils/plots.py index 39c21038..4addb83f 100644 --- a/csep/utils/plots.py +++ b/csep/utils/plots.py @@ -46,6 +46,7 @@ "ylabel": None, "xlabel_fontsize": 12, "ylabel_fontsize": 12, + "xlabel_rotation": 90, "xticks_fontsize": 12, "yticks_fontsize": 12, "xlim": None, @@ -107,7 +108,11 @@ def plot_magnitude_versus_time( ) -> matplotlib.axes.Axes: """ Scatter plot of the catalog magnitudes and origin times. The size of each event is scaled - exponentially by its magnitude using the parameters ``size``,``max_size`` and ``power``. + exponentially by its magnitude using the parameters ``size``, ``max_size`` and ``power``. + + .. admonition:: Usage Tutorials + + - :ref:`tutorial-catalog-filtering-plot` Args: catalog (CSEPCatalog): Catalog of seismic events to be plotted. @@ -118,7 +123,8 @@ def plot_magnitude_versus_time( Defaults to `300`. power (int, optional): Power scaling of the scatter sizing. Defaults to `4`. alpha (float, optional): Transparency level for the scatter points. Defaults to `0.5`. - reset_times (bool): If True, x-axis shows time in days since first event. + reset_times (bool, optional): If True, x-axis shows time in days since first event. + Defaults to False. ax (matplotlib.axes.Axes, optional): Axis object on which to plot. If not provided, a new figure and axis are created. Defaults to `None`. show (bool, optional): Whether to display the plot. Defaults to `False`. @@ -142,6 +148,12 @@ def plot_magnitude_versus_time( Returns: matplotlib.axes.Axes: The Matplotlib axes object with the plotted data. + + .. versionchanged:: 0.8.0 + The `plot_args` dictionary is only partially supported and will be removed in v1.0.0 + .. versionadded:: 0.8.0 + Added parameters to customize magnitude sizing. Show datetime when `reset_times` is + False. """ # Initialize plot if "plot_args" in kwargs: @@ -156,7 +168,6 @@ def plot_magnitude_versus_time( if reset_times: # Convert to days since first event - SECONDS_PER_DAY = 86400 timestamps = numpy.array([dt.timestamp() for dt in datetimes]) xdata = (timestamps - timestamps[0]) / SECONDS_PER_DAY xlabel = plot_args["xlabel"] or "Days since first event" @@ -203,12 +214,16 @@ def _plot_cumulative_events_versus_time( obs_label: Optional[str] = "Observation", ax: Optional[matplotlib.axes.Axes] = None, show: bool = False, - **kwargs, + **kwargs: Any, ) -> matplotlib.axes.Axes: """ Plots the cumulative number of forecasted events from a :class:`~csep.core.forecasts.CatalogForecast` versus the observed events over time. + .. admonition:: Usage Tutorials + + - :ref:`Catalog-based Forecast Plots` + Args: catalog_forecast (CatalogForecast): The forecasted synthetic catalogs. observation (CSEPCatalog): The observed catalog. @@ -220,7 +235,7 @@ def _plot_cumulative_events_versus_time( ax (matplotlib.axes.Axes, optional): Axis object on which to plot. If not provided, a new figure and axis are created. Defaults to `None`. show (bool, optional): If True, displays the plot. Defaults to `False`. - **kwargs: Additional keyword arguments to customize the plot: + **kwargs (optional): Additional keyword arguments to customize the plot: - **figsize** (`tuple`): The size of the figure. - **xlabel** (`str`): Label for the X-axis. Defaults to `'Datetime'`, @@ -248,6 +263,13 @@ def _plot_cumulative_events_versus_time( Returns: matplotlib.axes.Axes: The Matplotlib axes object with the plotted data. + + .. versionchanged:: 0.8.0 + It now requires a `CatalogForecast` rather than a list of stochastic event sets. The + `plot_args` dictionary is only partially supported and will be removed in v1.0.0 + .. versionadded:: 0.8.0 + Added `time_axis` parameter to show x-axis as daytimes or time-unit after first event. + Added parameters to customize coloring, formatting and sizing of the plot elements. """ # Initialize plot if "plot_args" in kwargs: @@ -382,13 +404,17 @@ def plot_magnitude_histogram( log_scale: bool = True, ax: Optional["matplotlib.axes.Axes"] = None, show: bool = False, - **kwargs, + **kwargs: Any, ) -> matplotlib.axes.Axes: """ Generates a semi-log magnitude histogram comparing a catalog-based forecast with observed - data. The forecast's median and uncertainty intervals are displayed along with the observed + data. The forecast's mean and uncertainty intervals are displayed along with the observed event counts. + .. admonition:: Usage Tutorials + + - :ref:`Catalog-based Forecast Plots` + Args: catalog_forecast (CatalogForecast or list of CSEPCatalog): A catalog-based forecast or a list of observed catalogs. @@ -403,7 +429,7 @@ def plot_magnitude_histogram( ax (matplotlib.axes.Axes, optional): The axes object to draw the plot on. If `None`, a new figure and axes are created. Defaults to `None`. show (bool, optional): Whether to display the plot immediately. Defaults to `False`. - **kwargs: Additional keyword arguments to customize the plot: + **kwargs (optional): Additional keyword arguments to customize the plot: - **figsize** (`tuple`): The size of the figure. - **color** (`str`): Color for the observed histogram points. @@ -425,6 +451,13 @@ def plot_magnitude_histogram( Returns: matplotlib.axes.Axes: The axes object containing the plot. + + .. versionchanged:: 0.8.0 + It now requires a `CatalogForecast` rather than a list of stochastic event sets. The + `plot_args` dictionary is only partially supported and will be removed in v1.0.0 + .. versionadded:: 0.8.0 + Added `magnitude_bins`, `percentile` and `log_scale` to fine-tune the plot. + Added parameters to customize coloring, formatting and sizing of the plot elements. """ # Initialize plot @@ -542,30 +575,35 @@ def _plot_basemap( projection: Optional[ccrs.Projection] = None, ax: Optional[pyplot.Axes] = None, show: bool = False, - **kwargs, + **kwargs: Any, ) -> matplotlib.axes.Axes: """ Wrapper function for multiple Cartopy base plots, including access to standard raster - web services and filesystem geoTIFF. + web services and reading of filesystem geoTIFF. + + .. admonition:: Usage Tutorials + + - :ref:`tutorial-plot-customizations-ex4` Args: - basemap (str): Possible values are: `'stock_img'`, `'google-satellite'`, + basemap (str, optional): Possible values are: `'stock_img'`, `'google-satellite'`, `'ESRI_terrain'`, `'ESRI_imagery'`, `'ESRI_relief'`, `'ESRI_topo'`, a custom web service link, or a GeoTiff filepath. Defaults to `None`. - extent (list of float): `[lon_min, lon_max, lat_min, lat_max]`. Defaults to `None`. - coastline (bool): Flag to plot coastline. Defaults to `True`. - borders (bool): Flag to plot country borders. Defaults to `False`. - tile_depth (str or int): Zoom resolution level (`1-12`) of the basemap tiles. If - `'auto'`, it is automatically derived from extent. Defaults to `'auto'`. - set_global (bool): Display the complete globe as basemap. Required by global forecasts. - Defaults to `False`. - projection (cartopy.crs.Projection): Projection to be used in the basemap. It can be a - cartopy projection instance, or `approx` for a quick approximation of Mercator. - Defaults to :class:`~cartopy.crs.PlateCarree` if `None`. + extent (list of float, optional): `[lon_min, lon_max, lat_min, lat_max]`. Defaults to + `None`. + coastline (bool, optional): Flag to plot coastline. Defaults to `True`. + borders (bool, optional): Flag to plot country borders. Defaults to `False`. + tile_depth (str or int, optional): Zoom resolution level (`1-12`) of the basemap tiles. + If `'auto'`, it is automatically derived from extent. Defaults to `'auto'`. + set_global (bool, optional): Display the complete globe as basemap. Required by global + forecasts. Defaults to `False`. + projection (cartopy.crs.Projection, optional): Projection to be used in the basemap. It + can be a cartopy projection instance, or `approx` for a quick approximation of + Mercator. Defaults to :class:`~cartopy.crs.PlateCarree` if `None`. ax (matplotlib.axes.Axes, optional): Previously defined ax object. If `None`, a new axis is created. Defaults to `None`. - show (bool): If `True`, displays the plot. Defaults to `False`. - **kwargs: Additional keyword arguments to customize the plot: + show (bool, optional): If `True`, displays the plot. Defaults to `False`. + **kwargs (optional): Additional keyword arguments to customize the plot: - **figsize** (`tuple`): The size of the figure. - **coastline_color** (`str`): Color for the coastlines. @@ -578,6 +616,12 @@ def _plot_basemap( Returns: matplotlib.axes.Axes: The Matplotlib axes object with the plotted data. + + .. versionchanged:: 0.8.0 + Change `tile_scaling` to `tile_depth`. Reassigned many aesthetic args to kwargs. + Modified automatic scaling with intermediate steps. + .. versionadded:: 0.8.0 + Added functionality to use a TIFF image from filesystem as basemap """ plot_args = {**DEFAULT_PLOT_ARGS, **kwargs} @@ -649,41 +693,50 @@ def plot_catalog( plot_region: bool = False, ax: Optional[matplotlib.axes.Axes] = None, show: bool = False, - **kwargs, + **kwargs: Any, ) -> matplotlib.axes.Axes: """ - Spatial plot of catalog. Can be plotted over a basemap if desired, by passing the keyword - parameters of the function :func:`~csep.utils.plots.plot_basemap`. The size of the events - is automatically scaled according to their magnitude. Fine-tuning of an exponential sizing - function can be set with the parameters ``size``, ``max_size``, ``power``, ``min_val`` and - ``max_val``. + Spatial plot of catalog epicenters. Can be plotted over a basemap if desired by passing the + keyword parameters of the function :func:`~csep.utils.plots.plot_basemap`. The size of the + events is automatically scaled according to their magnitude. Fine-tuning of an exponential + sizing function can be set with the parameters ``size``, ``max_size``, ``power``, + ``min_val`` and ``max_val``. + + .. admonition:: Usage Tutorials + + - :ref:`tutorial-catalog-filtering-plot` + - :ref:`tutorial-plot-customizations-ex3` + - :ref:`tutorial-plot-customizations-ex4` Args: catalog (CSEPCatalog): Catalog object to be plotted. - basemap (str): Passed to :func:`~csep.utils.plots.plot_basemap` along with `kwargs`. - Possible values are: `'stock_img'`, `'google-satellite'`, `'ESRI_terrain'`, - `'ESRI_imagery'`, `'ESRI_relief'`, `'ESRI_topo'`, a custom web service link, or a - GeoTiff filepath. Defaults to `None`. - projection (cartopy.crs.Projection or str): Projection to be used in the underlying - basemap. Can be a cartopy projection instance, or `approx` for a quick approximation - of Mercator. Defaults to :class:`~cartopy.crs.PlateCarree` if `None`. - extent (list of float): Defaults to `1.05` * :meth:`catalog.region.get_bbox`. Defaults - to `None`. - set_global (bool): Display the complete globe. Defaults to `False`. - mag_ticks (list of float, int): Ticks to display in the legend. Can be an array/list of - magnitudes, or a number of bins to discretize the magnitude range. Defaults to + basemap (str, optional): Passed to :func:`~csep.utils.plots.plot_basemap` along with + `kwargs`. Possible values are: `'stock_img'`, `'google-satellite'`, + `'ESRI_terrain'`, `'ESRI_imagery'`, `'ESRI_relief'`, `'ESRI_topo'`, a custom web + service link, or a GeoTiff filepath. Defaults to `None`. + projection (cartopy.crs.Projection or str, optional): Projection to be used in the + underlying basemap. Can be a cartopy projection instance, or `approx` for a quick + approximation of Mercator. Defaults to :class:`~cartopy.crs.PlateCarree` if `None`. + extent (list of float, optional): Defaults to `1.05` * :meth:`catalog.region.get_bbox`. + Defaults to `None`. + set_global (bool, optional): Display the complete globe. Defaults to `False`. + mag_ticks (list of float or int, optional): Ticks to display in the legend. Can be an + array/list of magnitudes, or a number of bins to discretize the magnitude range. + Defaults to `None`. + size (float, optional): Size of the minimum magnitude event. Defaults to `15`. + max_size (float, optional): Size of the maximum magnitude event. Defaults to `300`. + power (float, optional): Power scaling of the scatter sizing. Defaults to `3`. + min_val (float, optional): Override minimum magnitude of the catalog for scatter sizing. + Useful to plot multiple catalogs with different magnitude ranges. Defaults to `None`. - size (float): Size of the minimum magnitude event. Defaults to `15`. - max_size (float): Size of the maximum magnitude event. Defaults to `300`. - power (float): Power scaling of the scatter sizing. Defaults to `3`. - min_val (float): Override minimum magnitude of the catalog for scatter sizing. Useful - to plot multiple catalogs with different magnitude ranges. Defaults to `None`. - max_val (float): Override maximum magnitude of the catalog for scatter sizing. Useful - to plot multiple catalogs with different magnitude ranges. Defaults to `None`. - plot_region (bool): Flag to plot the catalog region border. Defaults to `False`. - ax (matplotlib.axes.Axes): Previously defined ax object. Defaults to `None`. - show (bool): If `True`, displays the plot. Defaults to `False`. - **kwargs: Additional keyword arguments to customize the plot: + max_val (float, optional): Override maximum magnitude of the catalog for scatter sizing. + Useful to plot multiple catalogs with different magnitude ranges. Defaults to + `None`. + plot_region (bool, optional): Flag to plot the catalog region border. Defaults to + `False`. + ax (matplotlib.axes.Axes, optional): Previously defined ax object. Defaults to `None`. + show (bool, optional): If `True`, displays the plot. Defaults to `False`. + **kwargs (optional): Additional keyword arguments to customize the plot: - **alpha** (`float`): Transparency level for the scatter points. - **markercolor** (`str`): Color for the scatter points. @@ -701,6 +754,14 @@ def plot_catalog( Returns: matplotlib.axes.Axes: The Matplotlib axes object with the plotted data. + + .. versionchanged:: 0.8.0 + The `plot_args` dictionary is only partially supported and will be removed in v1.0.0. + Changed `region_border` name to `plot_region`. Scaling the events size through + `mag_scale` is no longer used. + .. versionadded:: 0.8.0 + Added parameters `size`, `max_size`, `power`, `min_val`, `max_val` for fine-tuning of + the events sizing. """ if "plot_args" in kwargs: _warning_plot_args("plot_catalog") @@ -806,41 +867,52 @@ def plot_gridded_dataset( alpha_exp: float = 0, ax: Optional[pyplot.Axes] = None, show: bool = False, - **kwargs, + **kwargs: Any, ) -> matplotlib.axes.Axes: """ Plot spatial gridded dataset such as data from a gridded forecast. Can be plotted over a - basemap if desired, by passing the keyword parameters of the function - :func:`~csep.utils.plots.plot_basemap`. The color map can be fine-tuned using the arguments + basemap by passing the keyword parameters of the function + :func:`~csep.utils.plots.plot_basemap`. The color-map can be fine-tuned using the arguments ``colorbar``, ``colormap``, ``clim``. An exponential transparency function can be set with ``alpha`` and ``alpha_exp``. + .. admonition:: Usage Tutorials + + - :ref:`tutorial-handling-grid-forecast-plot` + - :ref:`tutorial-working-catalog-forecasts-plot` + - :ref:`tutorial-plot-customizations-ex1` + - :ref:`tutorial-plot-customizations-ex2` + - :ref:`tutorial-plot-customizations-ex4` + Args: gridded (numpy.ndarray): 2D-square array of values corresponding to the region. See :class:`~csep.core.regions.CartesianGrid2D` and :meth:`~csep.core.regions.CartesianGrid2D.get_cartesian` to convert a 1D array (whose indices correspond to each spatial cell) to a 2D-square array. region (CartesianGrid2D): Region in which gridded values are contained. - basemap (str): Passed to :func:`~csep.utils.plots.plot_basemap` along with `kwargs`. - Possible values are: `'stock_img'`, `'google-satellite'`, `'ESRI_terrain'`, - `'ESRI_imagery'`, `'ESRI_relief'`, `'ESRI_topo'`, a custom web service link, or a - GeoTiff filepath. Defaults to `None`. - projection (cartopy.crs.Projection or str): Projection to be used in the underlying - basemap. It can be a cartopy projection instance, or `approx` for a quick + basemap (str, optional): Passed to :func:`~csep.utils.plots.plot_basemap` along with + `kwargs`. Possible values are: `'stock_img'`, `'google-satellite'`, + `'ESRI_terrain'`, `'ESRI_imagery'`, `'ESRI_relief'`, `'ESRI_topo'`, a custom web + service link, or a GeoTiff filepath. Defaults to `None`. + projection (cartopy.crs.Projection or str, optional): Projection to be used in the + underlying basemap. It can be a cartopy projection instance, or `approx` for a quick approximation of Mercator. Defaults to :class:`~cartopy.crs.PlateCarree` if `None`. - extent (list of float): ``[lon_min, lon_max, lat_min, lat_max]``. Defaults to `None`. - set_global (bool): Display the complete globe as basemap. Defaults to `False`. - plot_region (bool): If `True`, plot the dataset region border. Defaults to `True`. - colorbar (bool): If `True`, include a colorbar. Defaults to `True`. - colormap (str or matplotlib.colors.Colormap): Colormap to use. Defaults to `'viridis'`. - clim (tuple of float): Range of the colorbar. Defaults to `None`. - clabel (str): Label of the colorbar. Defaults to `None`. - alpha (float): Transparency level. Defaults to `None`. - alpha_exp (float): Exponent for the alpha function (recommended between `0.4` and `1`). + extent (list of float, optional): ``[lon_min, lon_max, lat_min, lat_max]``. Defaults to + `None`. + set_global (bool, optional): Display the complete globe as basemap. Defaults to `False`. + plot_region (bool, optional): If `True`, plot the dataset region border. Defaults to + `True`. + colorbar (bool, optional): If `True`, include a colorbar. Defaults to `True`. + colormap (str or matplotlib.colors.Colormap, optional): Colormap to use. Defaults to + `'viridis'`. + clim (tuple of float, optional): Range of the colorbar. Defaults to `None`. + clabel (str, optional): Label of the colorbar. Defaults to `None`. + alpha (float, optional): Transparency level. Defaults to `None`. + alpha_exp (float, optional): Exponent for the alpha function (recommended between `0.4` and `1`). Defaults to `0`. - ax (matplotlib.axes.Axes): Previously defined ax object. Defaults to `None`. - show (bool): If `True`, displays the plot. Defaults to `False`. - **kwargs: Additional keyword arguments to customize the plot: + ax (matplotlib.axes.Axes, optional): Previously defined ax object. Defaults to `None`. + show (bool, optional): If `True`, displays the plot. Defaults to `False`. + **kwargs (optional): Additional keyword arguments to customize the plot: - **colorbar_labelsize** (`int`): Font size for the colorbar label. - **colorbar_ticksize** (`int`): Font size for the colorbar ticks. @@ -851,6 +923,11 @@ def plot_gridded_dataset( Returns: matplotlib.axes.Axes: Matplotlib axes object. + + .. versionchanged:: 0.8.0 + This function was renamed from `plot_spatial_dataset`. `plot_args` dictionary is only + partially supported and will be removed in v1.0.0. Changed `region_border` name to + `plot_region`. """ if "plot_args" in kwargs: _warning_plot_args("plot_gridded_dataset") @@ -919,28 +996,34 @@ def plot_test_distribution( legend: bool = True, ax: Optional[matplotlib.axes.Axes] = None, show: bool = False, - **kwargs, + **kwargs: Any, ) -> matplotlib.axes.Axes: """ - Plots a histogram of a single statistic for stochastic event sets and observations. + Plots the histogram of a test statistic distribution calculated from stochastic event sets + along with the observed statistic. + + .. admonition:: Usage Tutorials + + - :ref:`catalog-forecast-evaluation-plot` + - :ref:`Theory of Catalog-Based Forecasts ` Args: - evaluation_result (EvaluationResult): Object containing test - distributions and observed statistics. - bins (str, int, or list): Binning strategy for the histogram. See + evaluation_result (EvaluationResult): Result containing test distributions and observed + statistics. + bins (str, int, or list, optional): Binning strategy for the histogram. See :func:`matplotlib.pyplot.hist` for details on this parameter. Defaults to `'fd'`. - percentile (int): Percentile for shading regions. Defaults to `95`. - ax (matplotlib.axes.Axes): Axes object to plot on. If `None`, creates a new figure - and axes. Defaults to `None`. - auto_annotate (bool or dict): If `True`, automatically formats the plot details based - on the evaluation result. It can be further customized by passing the keyword - arguments `xlabel`, `ylabel`, `annotation_text`, `annotation_xy`, and + percentile (int, optional): Percentile for shading regions. Defaults to `95`. + ax (matplotlib.axes.Axes, optional): Axes object to plot on. If `None`, creates a new + figure and axes. Defaults to `None`. + auto_annotate (bool or dict, optional): If `True`, automatically formats the plot + details based on the evaluation result. It can be further customized by passing the + keyword arguments `xlabel`, `ylabel`, `annotation_text`, `annotation_xy`, and `annotation_fontsize`. Defaults to `True`. - sim_label (str): Label for the simulated data. Defaults to `'Simulated'`. - obs_label (str): Label for the observation data. Defaults to `'Observation'`. - legend (bool): Whether to display the legend. Defaults to `True`. - show (bool): If `True`, shows the plot. Defaults to `False`. - **kwargs: Additional keyword arguments for plot customization. + sim_label (str, optional): Label for the simulated data. Defaults to `'Simulated'`. + obs_label (str, optional): Label for the observation data. Defaults to `'Observation'`. + legend (bool, optional): Whether to display the legend. Defaults to `True`. + show (bool, optional): If `True`, shows the plot. Defaults to `False`. + **kwargs (optional): Additional keyword arguments for plot customization. - **color** (`str`): Color of the histogram bars. - **alpha** (`float`): Transparency level for the histogram bars. @@ -949,19 +1032,28 @@ def plot_test_distribution( - **grid** (`bool`): Whether to display grid lines. Defaults to `True`. - **legend_loc** (`str`): Location of the legend. Defaults to `'best'`. - **legend_fontsize** (`int`): Font size of the legend text. - - **xlabel**: Label of the X-axis. If `auto_annotate` is `True`, will be set to the - test statistic name. - - **ylabel**: Label of the Y-axis. - - **annotate_text**: Annotate the plot. If `auto_annotate` is `True`, it will - provide information about the statistics of the test. - - **annotate_xy**: Position for `annotate_text` in axes fraction. Can be override - if `auto_annotate` does not give an optimal position - - **annotate_fontsize**: Size of the annotation. + - **xlabel** (`str`): Label of the X-axis. If `auto_annotate` is `True`, will be set + to the test statistic name. + - **ylabel** (`str`): Label of the Y-axis. + - **annotate_text** (`str`): Text to annotate the plot with. If `auto_annotate` is + `True`, it will provide information about the statistics of the test. + - **annotate_xy** (`tuple`): Position for `annotate_text` in axes fraction. Can be + used to override position of `auto_annotate` if not optimal. + - **annotate_fontsize** (`int`): Size of the annotation. - **tight_layout** (`bool`): Whether to use tight layout for the figure. Defaults to `True`. Returns: matplotlib.axes.Axes: Matplotlib axes handle. + + .. versionchanged:: 0.8.0 + This function was renamed from `plot_distribution_test` and replaces + `plot_spatial_test`, `plot_number_test`, `plot_magnitude_test` and + `plot_likelihood_test`. `plot_args` dictionary is only partially supported and will be + removed in v1.0.0. + .. versionadded:: 0.8.0 + Added auto_annotate function to detect which test is being plotted and write down labels + and quantiles accordingly. """ if "plot_args" in kwargs: @@ -1052,7 +1144,7 @@ def plot_calibration_test( label: Optional[str] = None, ax: Optional[matplotlib.axes.Axes] = None, show: bool = False, - **kwargs, + **kwargs: Any, ) -> matplotlib.axes.Axes: """ Plots a calibration test (Quantile-Quantile plot) with confidence intervals. @@ -1060,13 +1152,13 @@ def plot_calibration_test( Args: evaluation_result (EvaluationResult): The evaluation result object containing the test distribution. - percentile (float): Percentile to build confidence interval. Defaults to `95`. - ax (matplotlib.axes.Axes): Axes object to plot on. If `None`, creates a new figure. - Defaults to `None`. - label (str): Label for the plotted data. If `None`, uses + percentile (float, optional): Percentile to build confidence interval. Defaults to `95`. + ax (matplotlib.axes.Axes, optional): Axes object to plot on. If `None`, creates a new + figure. Defaults to `None`. + label (str, optional): Label for the plotted data. If `None`, uses `evaluation_result.sim_name`. Defaults to `None`. - show (bool): If `True`, displays the plot. Defaults to `False`. - **kwargs: Additional keyword arguments for customizing the plot: + show (bool, optional): If `True`, displays the plot. Defaults to `False`. + **kwargs (optional): Additional keyword arguments for customizing the plot: - **color** (`str`): Color of the plot line and markers. - **marker** (`str`): Marker style for the data points. @@ -1085,6 +1177,11 @@ def plot_calibration_test( Returns: matplotlib.axes.Axes: The Matplotlib axes object containing the plot. + + .. versionchanged:: 0.8.0 + `plot_args` dictionary is only partially supported and will be removed in v1.0.0. + .. versionadded:: 0.8.0 + Added `percentile` option. """ if "plot_args" in kwargs: _warning_plot_args("plot_calibration_test") @@ -1157,25 +1254,32 @@ def _plot_comparison_test( percentile: int = 95, ax: Optional[matplotlib.axes.Axes] = None, show: bool = False, - **kwargs, + **kwargs: Any, ) -> pyplot.Axes: """ Plots a list of T-Test (and optional W-Test) results on a single axis. + .. admonition:: Usage Tutorials + + - :ref:`grid-forecast-evaluation-plot-comparison` + - :ref:`Theory of Forecast Comparison Tests ` + Args: results_t (list of EvaluationResult): List of T-Test results. results_w (list of EvaluationResult, optional): List of W-Test results. If provided, they are plotted alongside the T-Test results. Defaults to `None`. - percentile (int): Percentile for coloring W-Test results. Defaults to `95`. - ax (matplotlib.axes.Axes): Matplotlib axes object to plot on. If `None`, a new + percentile (int, optional): Percentile for coloring W-Test results. Defaults to `95`. + ax (matplotlib.axes.Axes, optional): Matplotlib axes object to plot on. If `None`, a new figure and axes are created. Defaults to `None`. - show (bool): If `True`, the plot is displayed after creation. Defaults to `False`. - **kwargs: Additional keyword arguments for customizing the plot: + show (bool, optional): If `True`, the plot is displayed after creation. Defaults to + `False`. + **kwargs (optional): Additional keyword arguments for customizing the plot: - **linewidth** (`float`): Width of the error bars. - **capsize** (`float`): Size of the caps on the error bars. - **markersize** (`float`): Size of the markers. - **xlabel_fontsize** (`int`): Font size for the X-axis labels. + - **xlabel_rotation** (`int`): Angle to rotate X-axis tick labels - **ylabel** (`str`): Label for the Y-axis. Defaults to `'Information gain per earthquake'`. - **ylabel_fontsize** (`int`): Font size for the Y-axis label. @@ -1184,13 +1288,22 @@ def _plot_comparison_test( - **ylim** (`tuple`): Limits for the Y-axis. - **grid** (`bool`): Whether to display grid lines. Defaults to `True`. - **hbars** (`bool`): Whether to include horizontal bars for visual separation. - - **legend** (`bool`): Whether to display a legend. Defaults to `True`. + - **legend** (`bool`): Automatic legend display.. Defaults to `True`. + - **legend_loc** ('int', `str`): Location of the legend. Defaults to `'best'`. - **legend_fontsize** (`int`): Font size for the legend text. + - **legend_labelspacing** (`float`): Vertical spacing between legend elements. + - **legend_borderpad** (`float`): Padding between legend frame and elements. + - **legend_framealpha** (`float`): Transparency value for the legend frame. - **tight_layout** (`bool`): Whether to use tight layout for the figure. Defaults to `True`. Returns: matplotlib.axes.Axes: The Matplotlib axes object containing the plot. + + .. versionchanged:: 0.8.0 + `plot_args` dictionary is only partially supported and will be removed in v1.0.0. + .. versionadded:: 0.8.0 + Added `legend` option to automatically create legend """ if "plot_args" in kwargs: _warning_plot_args("plot_comparison_test") @@ -1253,7 +1366,7 @@ def _plot_comparison_test( ax.set_xticks(numpy.arange(len(results_t))) ax.set_xticklabels( [res.sim_name[0] for res in results_t], - rotation=90, + rotation=plot_args["xlabel_rotation"], fontsize=plot_args["xlabel_fontsize"], ) ax.set_ylabel( @@ -1329,30 +1442,36 @@ def _plot_consistency_test( color: str = "black", ax: Optional[pyplot.Axes] = None, show: bool = False, - **kwargs, + **kwargs: Any, ) -> matplotlib.axes.Axes: """ - Plots the results from multiple consistency tests. The distribution of score results from - multiple realizations of a model are plotted as a line representing a given percentile. + Plots the results from one or multiple consistency tests. The distribution of score results + from multiple realizations of a model are plotted as a line representing a given percentile. The score of the observation under a model is plotted as a marker. The model is assumed inconsistent when the observation score lies outside the model distribution for a two-sided test, or lies to the right of the distribution for a one-sided test. + .. admonition:: Usage Tutorials + + - :ref:`grid-forecast-evaluation-plot` + - :ref:`Theory of Consistency Tests ` + - :ref:`tutorial-plot-customizations-ex5` + Args: eval_results (list of EvaluationResult or EvaluationResult): Evaluation results from one or multiple models. - normalize (bool): Normalize the forecast likelihood by observed likelihood. Defaults - to `False`. - one_sided_lower (bool): Plot for a one-sided test. Defaults to `False`. - percentile (float): Percentile for the extent of the model score distribution. Defaults - to `95`. - ax (matplotlib.axes.Axes): Axes object to plot on. If `None`, creates a new figure. - Defaults to `None`. - plot_mean (bool): Plot the mean of the test distribution. Defaults to `False`. - color (str): Color for the line representing a model score distribution. Defaults to - `'black'`. - show (bool): If `True`, displays the plot. Defaults to `False`. - **kwargs: Additional keyword arguments for plot customization: + normalize (bool, optional): Normalize the forecast likelihood by observed likelihood. + Defaults to `False`. + one_sided_lower (bool, optional): Plot for a one-sided test. Defaults to `False`. + percentile (float, optional): Percentile for the extent of the model score distribution. + Defaults to `95`. + ax (matplotlib.axes.Axes, optional): Axes object to plot on. If `None`, creates a new + figure. Defaults to `None`. + plot_mean (bool, optional): Plot the mean of the test distribution. Defaults to `False`. + color (str, optional): Color for the line representing a model score distribution. + Defaults to `'black'`. + show (bool, optional): If `True`, displays the plot. Defaults to `False`. + **kwargs (optional): Additional keyword arguments for plot customization: - **figsize** (`tuple`): The size of the figure. - **capsize** (`float`): Size of the caps on the error bars. @@ -1364,11 +1483,23 @@ def _plot_consistency_test( - **title** (`str`): Title of the plot. - **title_fontsize** (`int`): Font size of the plot title. - **hbars** (`bool`): Whether to include horizontal bars for visual separation. + - **legend** (`bool`): Whether to display a legend. Defaults to `True`. + - **legend_loc** ('int', `str`): Location of the legend. Defaults to `'best'`. + - **legend_fontsize** (`int`): Font size for the legend text. + - **legend_labelspacing** (`float`): Vertical spacing between legend elements. + - **legend_borderpad** (`float`): Padding between legend frame and elements. + - **legend_framealpha** (`float`): Transparency value for the legend frame. - **tight_layout** (`bool`): Whether to use tight layout for the figure. Defaults to `True`. Returns: matplotlib.axes.Axes: Matplotlib axes object with the consistency test plot. + + .. versionchanged:: 0.8.0 + `plot_args` dictionary is only partially supported and will be removed in v1.0.0. + .. versionadded:: 0.8.0 + Added option to plot mean statistic. Added `legend` option to automatically create + legend. """ if "plot_args" in kwargs: _warning_plot_args("plot_consistency_test") @@ -1475,22 +1606,26 @@ def _plot_concentration_ROC_diagram( plot_uniform: bool = True, ax: Optional[pyplot.Axes] = None, show: bool = True, - **kwargs, + **kwargs: Any, ) -> matplotlib.axes.Axes: """ Plots the Concentration ROC Diagram for a given forecast and observed catalog. + .. admonition:: Usage Tutorials + + - :ref:`grid-forecast-evaluation-concentration-roc` + Args: forecast (GriddedForecast): Forecast object containing spatial forecast data. catalog (CSEPCatalog): Catalog object containing observed data. - linear (bool): If True, uses a linear scale for the X-axis, otherwise logarithmic. - Defaults to `True`. - plot_uniform (bool): If True, plots the uniform (random) model as a reference. + linear (bool, optional): If True, uses a linear scale for the X-axis, otherwise + logarithmic. Defaults to `True`. + plot_uniform (bool, optional): If True, plots the uniform (random) model as a reference. Defaults to `True`. - show (bool): If True, displays the plot. Defaults to `True`. - ax (matplotlib.axes.Axes): Axes object to plot on. If `None`, creates a new figure. - Defaults to `None`. - **kwargs: Additional keyword arguments for customization: + show (bool, optional): If True, displays the plot. Defaults to `True`. + ax (matplotlib.axes.Axes, optional): Axes object to plot on. If `None`, creates a new + figure. Defaults to `None`. + **kwargs (optional): Additional keyword arguments for customization: - **figsize** (`tuple`): The size of the figure. - **forecast_label** (`str`): Label for the forecast data in the plot. @@ -1514,6 +1649,9 @@ def _plot_concentration_ROC_diagram( Returns: matplotlib.axes.Axes: The Axes object with the plot. + + .. versionchanged:: 0.8.0 + `plot_args` dictionary is only partially supported and will be removed in v1.0.0. """ if "plot_args" in kwargs: _warning_plot_args("plot_concentration_ROC_diagram") @@ -1593,23 +1731,27 @@ def _plot_ROC_diagram( plot_uniform: bool = True, ax: Optional[pyplot.Axes] = None, show: bool = True, - **kwargs, + **kwargs: Any, ) -> matplotlib.pyplot.Axes: """ Plots the ROC (Receiver Operating Characteristic) curve for a given forecast and observed catalog. + .. admonition:: Usage Tutorials + + - :ref:`grid-forecast-evaluation-roc-and-molchan` + Args: forecast (GriddedForecast): Forecast object containing spatial forecast data. catalog (CSEPCatalog): Catalog object containing observed data. - linear (bool): If True, uses a linear scale for the X-axis, otherwise logarithmic. + linear (bool, optional): If True, uses a linear scale for the X-axis, otherwise + logarithmic. Defaults to `True`. + plot_uniform (bool, optional): If True, plots the uniform (random) model as a reference. Defaults to `True`. - plot_uniform (bool): If True, plots the uniform (random) model as a reference. - Defaults to `True`. - show (bool): If True, displays the plot. Defaults to `True`. - ax (matplotlib.axes.Axes): Axes object to plot on. If `None`, creates a new figure. - Defaults to `None`. - **kwargs: Additional keyword arguments for customization: + show (bool, optional): If True, displays the plot. Defaults to `True`. + ax (matplotlib.axes.Axes, optional): Axes object to plot on. If `None`, creates a new + figure. Defaults to `None`. + **kwargs (optional): Additional keyword arguments for customization: - **figsize** (`tuple`): The size of the figure. - **forecast_label** (`str`): Label for the forecast data in the plot. @@ -1629,6 +1771,9 @@ def _plot_ROC_diagram( Returns: matplotlib.pyplot.Axes: The Axes object with the plot. + + .. versionchanged:: 0.8.0 + `plot_args` dictionary is only partially supported and will be removed in v1.0.0. """ if "plot_args" in kwargs: _warning_plot_args("plot_ROC_diagram") @@ -1722,7 +1867,7 @@ def _plot_Molchan_diagram( plot_uniform: bool = True, ax: Optional[pyplot.Axes] = None, show: bool = True, - **kwargs, + **kwargs: Any, ) -> matplotlib.axes.Axes: """ Plot the Molchan Diagram based on forecast and test catalogs using the contingency table. @@ -1748,17 +1893,21 @@ def _plot_Molchan_diagram( 3. If calling this function multiple times, update the color in the arguments. 4. The user can choose the x-scale (linear or log). + .. admonition:: Usage Tutorials + + - :ref:`grid-forecast-evaluation-roc-and-molchan` + Args: forecast (GriddedForecast): The forecast object. catalog (CSEPCatalog): The evaluation catalog. - linear (bool): If True, a linear x-axis is used; if False, a logarithmic x-axis is used. - Defaults to `True`. - plot_uniform (bool): If True, include a uniform forecast on the plot. Defaults to - `True`. - show (bool): If True, displays the plot. Defaults to `True`. - ax (matplotlib.axes.Axes): Axes object to plot on. If `None`, creates a new figure. - Defaults to `None`. - **kwargs: Additional keyword arguments for customization: + linear (bool, optional): If True, a linear x-axis is used; if False, a logarithmic + x-axis is used. Defaults to `True`. + plot_uniform (bool, optional): If True, include a uniform forecast on the plot. Defaults + to `True`. + show (bool, optional): If True, displays the plot. Defaults to `True`. + ax (matplotlib.axes.Axes, optional): Axes object to plot on. If `None`, creates a new + figure. Defaults to `None`. + **kwargs (optional): Additional keyword arguments for customization: - **figsize** (`tuple`): The size of the figure. - **forecast_label** (`str`): Label for the forecast data in the plot. @@ -2014,7 +2163,7 @@ def _get_axis_limits(points: Union[Sequence, numpy.ndarray], Args: points (numpy.ndarray): An array of points. - border (float): The border fraction to apply to the limits. + border (float, optional): The border fraction to apply to the limits. Returns: Sequence[float, float]: The x_min and x_max values adjusted with the border. @@ -2193,6 +2342,16 @@ def _autoscale_histogram( def _draw_shaded_bars(ax, n_results, orientation='vertical'): + """ + Plot the shaded bars for comparison and consistency plots + + Args: + ax (pyplot.ax): Axes where to draw the shaded bars. + n_results: Number of results to be plotted on the bars + + Returns + ax (pyplot.ax): Same ax object with the drawn shaded bars + """ if n_results > 2: if orientation == 'vertical': ax.bar( diff --git a/docs/Makefile b/docs/Makefile index 55b04e9e..b6558d26 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -17,7 +17,8 @@ livehtml: clean: rm -rf $(BUILDDIR)/* - rm -rf auto_examples/ + rm -rf tutorials/* + rm -rf reference/generated .PHONY: help Makefile diff --git a/docs/concepts/evaluations.rst b/docs/concepts/evaluations.rst index c01d6b47..2a5acaf7 100644 --- a/docs/concepts/evaluations.rst +++ b/docs/concepts/evaluations.rst @@ -91,7 +91,7 @@ statistics from these catalogs and compare them against one another. We provide four statistics that probe fundamental aspects of the earthquake forecasts. Please see :ref:`Savran et al., 2020` for a complete description of the individual tests. For the implementation -details please follow the links below and see the :ref:`example` for catalog-based +details please follow the links below and see the :ref:`Example ` for catalog-based forecast evaluation for an end-to-end walk through. .. automodule:: csep.core.catalog_evaluations diff --git a/docs/concepts/forecasts.rst b/docs/concepts/forecasts.rst index bb1662ea..1090bd3e 100644 --- a/docs/concepts/forecasts.rst +++ b/docs/concepts/forecasts.rst @@ -129,7 +129,7 @@ Working with catalog-based forecasts .. autosummary:: csep.core.forecasts.CatalogForecast -Please see visit :ref:`this` example for an end-to-end tutorial on how to evaluate a catalog-based +Please see visit :ref:`this Example ` for an end-to-end tutorial on how to evaluate a catalog-based earthquake forecast. An example of a catalog-based forecast stored in the default pyCSEP format can be found `here `__. diff --git a/docs/concepts/regions.rst b/docs/concepts/regions.rst index e4bc753d..c814f56f 100644 --- a/docs/concepts/regions.rst +++ b/docs/concepts/regions.rst @@ -6,8 +6,6 @@ Regions .. automodule:: csep.core.regions :no-index: -.. automodule:: csep.utils.basic_types - :no-index: PyCSEP includes commonly used CSEP testing regions and classes that facilitate working with gridded data sets. This module is early in development and will be a focus of future development. diff --git a/docs/getting_started/theory.rst b/docs/getting_started/theory.rst index 9314cfcb..64e067df 100644 --- a/docs/getting_started/theory.rst +++ b/docs/getting_started/theory.rst @@ -104,6 +104,8 @@ examples use the Helmstetter et al (2007) smoothed seismicity forecast Found 24 events in the ComCat catalog. +.. _theory-consistency-tests: + Consistency tests ~~~~~~~~~~~~~~~~~ @@ -655,6 +657,8 @@ case, the model with aftershocks performs statistically worse than the benchmark model. We note that this comparison is used for demonstation purposes only. +.. _theory-catalog-forecasts: + Catalog-based forecast tests ---------------------------- diff --git a/docs/reference/api_reference.rst b/docs/reference/api_reference.rst index a4cf76d1..bd80d34a 100644 --- a/docs/reference/api_reference.rst +++ b/docs/reference/api_reference.rst @@ -234,10 +234,14 @@ Region utilities: .. currentmodule:: csep.utils.plots .. automodule:: csep.utils.plots +.. _api-plot-functions: + Plotting -------- -General plotting: +PyCSEP offers multiple plot functionalities to visually explore forecasts, catalogs and results. + +Exploratory plotting: .. autosummary:: :toctree: generated @@ -245,17 +249,15 @@ General plotting: plot_magnitude_versus_time plot_cumulative_events_versus_time plot_magnitude_histogram - plot_basemap - plot_catalog - plot_gridded_dataset -Plotting catalog-based evaluations: +Spatial plotting: .. autosummary:: :toctree: generated - plot_test_distribution - plot_calibration_test + plot_basemap + plot_catalog + plot_gridded_dataset Plotting grid-based evaluations: @@ -265,6 +267,14 @@ Plotting grid-based evaluations: plot_comparison_test plot_consistency_test +Plotting catalog-based evaluations: + +.. autosummary:: + :toctree: generated + + plot_test_distribution + plot_calibration_test + Plotting alarm-based evaluations: .. autosummary:: diff --git a/examples/tutorials/catalog_filtering.py b/examples/tutorials/catalog_filtering.py index 0e8e142c..40a57d90 100644 --- a/examples/tutorials/catalog_filtering.py +++ b/examples/tutorials/catalog_filtering.py @@ -100,6 +100,9 @@ #################################################################################################################################### +# +# .. _tutorial-catalog-filtering-plot: +# # Plot catalog # ------------- # diff --git a/examples/tutorials/catalog_forecast_evaluation.py b/examples/tutorials/catalog_forecast_evaluation.py index a1f3bf5a..a9fde968 100644 --- a/examples/tutorials/catalog_forecast_evaluation.py +++ b/examples/tutorials/catalog_forecast_evaluation.py @@ -102,6 +102,9 @@ comcat_catalog.plot(show=True) #################################################################################################################################### +# +# .. _catalog-forecast-evaluation-exploratory: +# # Exploratory visualizations # -------------------------- # @@ -126,6 +129,9 @@ number_test_result = catalog_evaluations.number_test(forecast, comcat_catalog) #################################################################################################################################### +# +# .. _catalog-forecast-evaluation-plot: +# # Plot number test result # ----------------------- # diff --git a/examples/tutorials/gridded_forecast_evaluation.py b/examples/tutorials/gridded_forecast_evaluation.py index 13c8cdf3..4b9b8032 100644 --- a/examples/tutorials/gridded_forecast_evaluation.py +++ b/examples/tutorials/gridded_forecast_evaluation.py @@ -93,6 +93,9 @@ csep.write_json(spatial_test_result, 'example_spatial_test.json') #################################################################################################################################### +# +# .. _grid-forecast-evaluation-plot: +# # Plot spatial test results # ------------------------- # @@ -105,6 +108,9 @@ #################################################################################################################################### +# +# .. _grid-forecast-evaluation-plot-comparison: +# # Performing a comparative test # ----------------------------- # @@ -126,6 +132,9 @@ #################################################################################################################################### +# +# .. _grid-forecast-evaluation-concentration-roc: +# # Plot ROC Curves # --------------- # @@ -149,6 +158,9 @@ #################################################################################################################################### +# +# .. _grid-forecast-evaluation-roc-and-molchan: +# # Plot ROC and Molchan curves using the alarm-based approach # ---------------------------------------------------------- diff --git a/examples/tutorials/plot_customizations.py b/examples/tutorials/plot_customizations.py index 20b58599..eddf7306 100644 --- a/examples/tutorials/plot_customizations.py +++ b/examples/tutorials/plot_customizations.py @@ -15,11 +15,17 @@ 5. Creating composite plots 6. Plot multiple Evaluation Results + +Please refer to the :ref:`Plotting API Reference ` for a description of all +PyCSEP plotting functionality. """ ################################################################################################################ -# Example 1: Spatial dataset plot arguments -# ----------------------------------------- +# +# .. _tutorial-plot-customizations-ex1: +# +# Example 1: Customizing Gridded Dataset Plot +# ------------------------------------------- #################################################################################################################################### # **Load required libraries** @@ -49,10 +55,10 @@ # * Assign a title # * Set labels to the geographic axes # * Draw country borders -# * Set a linewidth of 0.5 to country border -# * Assign ``'rainbow'`` as the colormap. Possible values from ``matplotlib.cm`` library +# * Set a linewidth of 1.5 to country border +# * Assign ``'rainbow'`` as the colormap. Possible values from :mod:`matplotlib.cm` library # * Defines 0.8 for an exponential transparency function (default is 0 for constant alpha, whereas 1 for linear). -# * An object cartopy.crs.Projection() is passed as Projection to the map +# * An object :class:`cartopy.crs.Projection` (in this case :class:`cartopy.crs.Mercator`) is passed to the map # # The complete description of plot arguments can be found in :func:`csep.utils.plots.plot_gridded_dataset` # @@ -70,6 +76,9 @@ show=True) #################################################################################################################################### +# +# .. _tutorial-plot-customizations-ex2: +# # Example 2: Plot a global forecast and a selected magnitude bin range # -------------------------------------------------------------------- # @@ -105,7 +114,7 @@ #################################################################################################################################### # **Plotting the dataset** # -# To plot a global forecast, we must assign the option ``set_global=True``, which is required by :ref:`cartopy` to handle +# To plot a global forecast, we must assign the option ``set_global=True``, which is required by :mod:`cartopy` to handle # internally the extent of the plot. We can further customize the plot using the required arguments from :func:`~csep.utils.plots.plot_gridded_dataset` # @@ -131,6 +140,9 @@ #################################################################################################################################### +# +# .. _tutorial-plot-customizations-ex3: +# # Example 3: Plot a catalog with a custom basemap # ----------------------------------------------- @@ -152,7 +164,7 @@ # * Set minimum and maximum marker size of 7 and 500, respectively. # * Set the marker color red # * Set a 0.3 transparency -# * mag_scale is used to exponentially scale the size with respect to magnitude. Recommended 1-8 +# * `power` is used to exponentially scale the size with respect to magnitude. Recommended 1-8 # * Set legend True and location in 3 (lower-left corner) # * Set a list of magnitude ticks to display in the legend # @@ -165,7 +177,7 @@ 'max_size': 500, 'markercolor': 'red', 'alpha': 0.3, - 'mag_scale': 8, + 'power': 4, 'legend': True, 'legend_loc': 3, 'coastline': False, @@ -178,8 +190,15 @@ ax = catalog.plot(show=True, **plot_args) +#################################################################################################################################### +# Alternatively, it can be plotted using the :func:`csep.utils.plots.plot_catalog` function + +plots.plot_catalog(catalog=catalog, show=True, **plot_args) #################################################################################################################################### +# +# .. _tutorial-plot-customizations-ex4: +# # Example 4: Plot composition # ----------------------------------------------- # @@ -205,6 +224,7 @@ # Plot the basemap alone by using :func:`csep.utils.plots.plot_basemap`. Do not set ``show=True`` and store the returned ``ax`` object to # start the composite plot +# Start the base plot ax = plots.plot_basemap(figsize=(8, 8), projection=cartopy.crs.AlbersEqualArea(central_longitude=-120.), extent=forecast.region.get_bbox(), @@ -217,9 +237,12 @@ ax = forecast.plot(colormap='PuBu_r', alpha_exp=0.5, ax=ax) # Use show=True to finalize the composite. -catalog.plot(markercolor='darkred', ax=ax, show=True) +plots.plot_catalog(catalog=catalog, markercolor='darkred', ax=ax, show=True) #################################################################################################################################### +# +# .. _tutorial-plot-customizations-ex5: +# # Example 5: Plot multiple evaluation results # ------------------------------------------- diff --git a/examples/tutorials/plot_gridded_forecast.py b/examples/tutorials/plot_gridded_forecast.py index 1d54000d..16bce61a 100644 --- a/examples/tutorials/plot_gridded_forecast.py +++ b/examples/tutorials/plot_gridded_forecast.py @@ -1,6 +1,6 @@ """ -.. tutorial-handling-grid-forecast: +.. _tutorial-handling-grid-forecast: Handling Grid-based Forecasts ============================= @@ -42,6 +42,9 @@ name='helmstetter_mainshock') #################################################################################################################################### +# +# .. _tutorial-handling-grid-forecast-plot: +# # Plot forecast # ------------- # diff --git a/examples/tutorials/quadtree_gridded_forecast_evaluation.py b/examples/tutorials/quadtree_gridded_forecast_evaluation.py index d4a9306d..14d84b96 100644 --- a/examples/tutorials/quadtree_gridded_forecast_evaluation.py +++ b/examples/tutorials/quadtree_gridded_forecast_evaluation.py @@ -186,6 +186,9 @@ #################################################################################################################################### +# +# .. _quadtree_gridded-forecast-evaluation-plot: +# # Plot spatial test results # ------------------------- # diff --git a/examples/tutorials/working_with_catalog_forecasts.py b/examples/tutorials/working_with_catalog_forecasts.py index c8e9185b..93201312 100644 --- a/examples/tutorials/working_with_catalog_forecasts.py +++ b/examples/tutorials/working_with_catalog_forecasts.py @@ -68,6 +68,9 @@ #################################################################################################################################### +# +# .. _tutorial-working-catalog-forecasts-plot: +# # Plot expected event counts # -------------------------- # From ac8864409b5f7eadc77eb9fc6bec4a371a3c38de Mon Sep 17 00:00:00 2001 From: pciturri Date: Tue, 22 Apr 2025 16:41:41 +0200 Subject: [PATCH 17/17] ft: added backwards compatibility for pycsep reproducibility package --- csep/utils/plots.py | 13 +++++++++++-- csep/utils/plots_legacy.py | 6 ++---- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/csep/utils/plots.py b/csep/utils/plots.py index 4addb83f..b365a3d8 100644 --- a/csep/utils/plots.py +++ b/csep/utils/plots.py @@ -2174,7 +2174,7 @@ def _get_axis_limits(points: Union[Sequence, numpy.ndarray], return x_min - xd, x_max + xd -def _get_basemap(basemap: str) -> Union[img_tiles.GoogleTiles, DatasetReader]: +def _get_basemap(basemap: str) -> Union[img_tiles.GoogleTiles, DatasetReader, None]: """ Returns the basemap tiles for a given basemap type or web service. @@ -2251,6 +2251,14 @@ def _save_cache_src(basemap_): ) tiles = img_tiles.GoogleTiles(url=webservice, cache=cache) _save_cache_src(basemap) + elif basemap == 'stamen_terrain-background' or basemap == 'stamen_terrain': + warnings.warn( + f"stamen basemaps are no longer supported. Please try one of:" + f" 'google-satellite`, `ESRI_terrain`, `ESRI_relief`, etc.\n", + DeprecationWarning, + stacklevel=2 + ) + return None elif os.path.isfile(basemap): return rio_open(basemap) @@ -2699,4 +2707,5 @@ def _warning_plot_args(func_name: str): plot_pvalues_and_intervals, plot_concentration_ROC_diagram, plot_ROC_diagram, - plot_Molchan_diagram) + plot_Molchan_diagram, + add_labels_for_publication) diff --git a/csep/utils/plots_legacy.py b/csep/utils/plots_legacy.py index e4648e46..40964cfe 100644 --- a/csep/utils/plots_legacy.py +++ b/csep/utils/plots_legacy.py @@ -2023,11 +2023,9 @@ def add_labels_for_publication(figure, style='bssa', labelsize=16): This function is deprecated and will be removed in version 1.0. """ - + import string warnings.warn( - "'plot_spatial_test' is deprecated and will be removed in version 1.0.\n" - "Use 'plot_test_distribution' instead.\n" - "Documentation: https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_test_distribution.html", + "'add_labels_for_publication' is deprecated and will be removed in version 1.0.\n", DeprecationWarning, stacklevel=2 )

Qz=coJG?)oIjMd1^7Ax> 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%0DHKJi5L7?va<>IUVi$5vP-FgvNWL`K+x| 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