From 79164261fc0702aa51c83a3da52582d107f1db9e Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Tue, 22 Feb 2022 01:00:30 +0100 Subject: [PATCH 01/48] Create twoaxistrackerfield.py --- twoaxistracking/twoaxistrackerfield.py | 112 +++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 twoaxistracking/twoaxistrackerfield.py diff --git a/twoaxistracking/twoaxistrackerfield.py b/twoaxistracking/twoaxistrackerfield.py new file mode 100644 index 0000000..9dc9e1e --- /dev/null +++ b/twoaxistracking/twoaxistrackerfield.py @@ -0,0 +1,112 @@ +""" +The ``TwoAxisTrackerField`` module contains functions and classes that +combine the collector definition, field layout generation, and shading +calculation steps. Using the `TwoAxisTrackerField` class make it easy to +get started with the package and keeps track of the variables that are +passed from one function to the next. +""" + +from twoaxistracking import layout, shading, plotting +import numpy as np +import pandas as pd + + +class TwoAxisTrackerField: + """ + TwoAxisTrackerField is a convient container for the collector geometry + and field layout, and allows for calculating the shaded fraction. + + Parameters + ---------- + total_collector_geometry: Shapely Polygon + Collector geometry + neighbor_order: int + Order of neighbors to include in layout. neighbor_order=1 includes only + the 8 directly adjacent collectors. + gcr: float + Ground cover ratio. Ratio of collector area to ground area. + aspect_ratio: float, optional + Ratio of the spacing in the primary direction to the secondary. + offset: float, optional + Relative row offset in the secondary direction as fraction of the + spacing in the secondary direction. -0.5 <= offset < 0.5. + rotation: float, optional + Counterclockwise rotation of the field in degrees. 0 <= rotation < 180 + """ + + def __init__(self, collector_geometry, neighbor_order, gcr, + aspect_ratio=None, offset=None, rotation=None, + layout_type=None): + + # Collector geometry + self.collector_geometry = collector_geometry + self.collector_area = self.collector_geometry.area + self.L_min = layout._calculate_l_min(self.collector_geometry) + # Field layout + self.neighbor_order = neighbor_order + self.gcr = gcr + self.aspect_ratio = aspect_ratio + self.offset = offset + self.rotation = rotation + # Calculate position of neighboring collectors based on field layout + self.X, self.Y, self.tracker_distance, self.relative_azimuth = \ + layout.generate_field_layout( + self.gcr, self.collector_area, self.L_min, + neighbor_order=self.neighbor_order, + aspect_ratio=self.aspect_ratio, offset=self.offset, + rotation=self.rotation) + plotting._plot_field_layout(X=self.X, Y=self.Y, L_min=self.L_min) + + def plot_field_layout(self): + """Plot the field layout.""" + plotting._plot_field_layout(X=self.X, Y=self.Y, L_min=self.L_min) + + def get_shaded_fraction(self, solar_elevation, solar_azimuth, + plot=False): + """Calculate the shaded fraction for the specified solar positions. + + Uses the :py:func:`twoaxistracking.shaded_fraction` function to + calculate the shaded fraction corresponding to the specified solar + elevation and azimuth angles. + + Parameters + ---------- + solar_elevation : array-like + Solar elevation angles in degrees. + solar_azimuth : array-like + Solar azimuth angles in degrees. + plot : boolean, default: False + Whether to plot the unshaded and shading geometries for each solar + position. + + Returns + ------- + shaded_fractions : array-like + The shaded fractions for the specified collector geometry, + field layout, and solar angles. + """ + # Wrap scalars in an array + if isinstance(solar_elevation, (int, float)): + solar_elevation = np.array([solar_elevation]) + solar_azimuth = np.array([solar_azimuth]) + + shaded_fractions = [] + for (elevation, azimuth) in zip(solar_elevation, solar_azimuth): + shaded_fraction = shading.shaded_fraction( + solar_elevation=elevation, + solar_azimuth=azimuth, + collector_geometry=self.collector_geometry, + tracker_distance=self.tracker_distance, + relative_azimuth=self.relative_azimuth, + L_min=self.L_min, + plot=False) + shaded_fractions.append(shaded_fraction) + + # Return the shaded_fractions as the same type as the input + if isinstance(solar_elevation, pd.Series): + shaded_fractions = pd.Series(shaded_fractions, + index=solar_elevation.index) + elif isinstance(solar_elevation, np.array): + shaded_fractions = np.array(shaded_fractions) + + return shaded_fractions From 396e297bae6b71f0a13c75a347792cfa8f15ca55 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Tue, 22 Feb 2022 01:00:54 +0100 Subject: [PATCH 02/48] Add TwoAxisTrackerField to __init__.py and documentation.rst --- docs/source/documentation.rst | 3 ++- twoaxistracking/__init__.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/source/documentation.rst b/docs/source/documentation.rst index e019bb1..4c8460c 100644 --- a/docs/source/documentation.rst +++ b/docs/source/documentation.rst @@ -8,4 +8,5 @@ Code documentation :toctree: generated/ shaded_fraction - generate_field_layout \ No newline at end of file + generate_field_layout + TwoAxisTrackerField \ No newline at end of file diff --git a/twoaxistracking/__init__.py b/twoaxistracking/__init__.py index 249c06e..2479116 100644 --- a/twoaxistracking/__init__.py +++ b/twoaxistracking/__init__.py @@ -1,6 +1,6 @@ from .layout import generate_field_layout # noqa: F401 from .shading import shaded_fraction # noqa: F401 - +from .twoaxistrackerfield import TwoAxisTrackerField # noqa: F401 try: from shapely.geos import lgeos # noqa: F401 From 97bf6229b5193957d42f748140003d7a15fbabae Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Tue, 22 Feb 2022 01:01:10 +0100 Subject: [PATCH 03/48] Add _calculate_l_min to layout --- twoaxistracking/layout.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/twoaxistracking/layout.py b/twoaxistracking/layout.py index 6e8465e..c933746 100644 --- a/twoaxistracking/layout.py +++ b/twoaxistracking/layout.py @@ -1,6 +1,6 @@ import numpy as np from twoaxistracking import plotting - +from shapely import geometry def _rotate_origin(x, y, rotation_deg): """Rotate a set of 2D points counterclockwise around the origin (0, 0).""" @@ -11,6 +11,11 @@ def _rotate_origin(x, y, rotation_deg): return xx, yy +def _calculate_l_min(collector_geometry): + L_min = 2 * collector_geometry.hausdorff_distance(geometry.Point(0, 0)) + return L_min + + def generate_field_layout(gcr, total_collector_area, L_min, neighbor_order, aspect_ratio=None, offset=None, rotation=None, layout_type=None, slope_azimuth=0, From 15614344747c20e6cd7063a94b2e08579660bd19 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Tue, 22 Feb 2022 01:08:25 +0100 Subject: [PATCH 04/48] Fix linter error --- twoaxistracking/layout.py | 1 + twoaxistracking/twoaxistrackerfield.py | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/twoaxistracking/layout.py b/twoaxistracking/layout.py index c933746..358e439 100644 --- a/twoaxistracking/layout.py +++ b/twoaxistracking/layout.py @@ -2,6 +2,7 @@ from twoaxistracking import plotting from shapely import geometry + def _rotate_origin(x, y, rotation_deg): """Rotate a set of 2D points counterclockwise around the origin (0, 0).""" rotation_rad = np.deg2rad(rotation_deg) diff --git a/twoaxistracking/twoaxistrackerfield.py b/twoaxistracking/twoaxistrackerfield.py index 9dc9e1e..7d4e84d 100644 --- a/twoaxistracking/twoaxistrackerfield.py +++ b/twoaxistracking/twoaxistrackerfield.py @@ -66,8 +66,8 @@ def get_shaded_fraction(self, solar_elevation, solar_azimuth, """Calculate the shaded fraction for the specified solar positions. Uses the :py:func:`twoaxistracking.shaded_fraction` function to - calculate the shaded fraction corresponding to the specified solar - elevation and azimuth angles. + calculate the shaded fraction for to the specified solar elevation and + azimuth angles. Parameters ---------- From 5e4cbf6b0245d493befd5e8355a0d6f84ac3bd8e Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Tue, 22 Feb 2022 01:45:21 +0100 Subject: [PATCH 05/48] Update twoaxistrackerfield.py --- twoaxistracking/twoaxistrackerfield.py | 54 +++++++++++++++++++------- 1 file changed, 39 insertions(+), 15 deletions(-) diff --git a/twoaxistracking/twoaxistrackerfield.py b/twoaxistracking/twoaxistrackerfield.py index 7d4e84d..5f4d8c6 100644 --- a/twoaxistracking/twoaxistrackerfield.py +++ b/twoaxistracking/twoaxistrackerfield.py @@ -19,7 +19,9 @@ class TwoAxisTrackerField: Parameters ---------- total_collector_geometry: Shapely Polygon - Collector geometry + Polygon corresponding to the total collector area. + active_collector_geometry: Shapely Polygon or MultiPolygon + One or more polygons defining the active collector area. neighbor_order: int Order of neighbors to include in layout. neighbor_order=1 includes only the 8 directly adjacent collectors. @@ -32,34 +34,51 @@ class TwoAxisTrackerField: spacing in the secondary direction. -0.5 <= offset < 0.5. rotation: float, optional Counterclockwise rotation of the field in degrees. 0 <= rotation < 180 + layout_type: {square, square_rotated, hexagon_e_w, hexagon_n_s}, optional + Specification of the special layout type (only depend on gcr). + slope_azimuth : float, optional + Direction of normal to slope on horizontal [degrees] + slope_tilt : float, optional + Tilt of slope relative to horizontal [degrees] """ - def __init__(self, collector_geometry, neighbor_order, gcr, - aspect_ratio=None, offset=None, rotation=None, - layout_type=None): + def __init__(self, total_collector_geometry, active_collector_geometry, + neighbor_order, gcr, aspect_ratio=None, offset=None, + rotation=None, layout_type=None, slope_azimuth=0, + slope_tilt=0): # Collector geometry - self.collector_geometry = collector_geometry - self.collector_area = self.collector_geometry.area - self.L_min = layout._calculate_l_min(self.collector_geometry) + self.total_collector_geometry = total_collector_geometry + self.active_collector_geometry = active_collector_geometry + # Derive properties from geometries + self.total_collector_area = self.total_collector_geometry.area + self.active_collector_area = self.active_collector_geometry.area + self.L_min = layout._calculate_l_min(self.total_collector_geometry) + # Field layout self.neighbor_order = neighbor_order self.gcr = gcr self.aspect_ratio = aspect_ratio self.offset = offset self.rotation = rotation + self.layout_type = layout_type + self.slope_azimuth = slope_azimuth + self.slope_tilt = slope_tilt + # Calculate position of neighboring collectors based on field layout - self.X, self.Y, self.tracker_distance, self.relative_azimuth = \ + self.X, self.Y, self.Z, self.tracker_distance, self.relative_azimuth, self.relative_slope = \ layout.generate_field_layout( - self.gcr, self.collector_area, self.L_min, - neighbor_order=self.neighbor_order, + gcr=self.gcr, total_collector_area=self.total_collector_area, + L_min=self.L_min, neighbor_order=self.neighbor_order, aspect_ratio=self.aspect_ratio, offset=self.offset, - rotation=self.rotation) - plotting._plot_field_layout(X=self.X, Y=self.Y, L_min=self.L_min) + rotation=self.rotation, layout_type=self.layout_type, + slope_azimuth=self.slope_azimuth, slope_tilt=self.slope_tilt, + plot=False) def plot_field_layout(self): """Plot the field layout.""" - plotting._plot_field_layout(X=self.X, Y=self.Y, L_min=self.L_min) + plotting._plot_field_layout(X=self.X, Y=self.Y, Z=self.Z, + L_min=self.L_min) def get_shaded_fraction(self, solar_elevation, solar_azimuth, plot=False): @@ -90,15 +109,20 @@ def get_shaded_fraction(self, solar_elevation, solar_azimuth, solar_elevation = np.array([solar_elevation]) solar_azimuth = np.array([solar_azimuth]) + # Calculate the shaded fraction for each solar position shaded_fractions = [] for (elevation, azimuth) in zip(solar_elevation, solar_azimuth): shaded_fraction = shading.shaded_fraction( solar_elevation=elevation, solar_azimuth=azimuth, - collector_geometry=self.collector_geometry, + total_collector_geometry=self.total_collector_geometry, + active_collector_geometry=self.active_collector_geometry, + L_min=self.L_min, tracker_distance=self.tracker_distance, relative_azimuth=self.relative_azimuth, - L_min=self.L_min, + relative_slope=self.relative_slope, + slope_azimuth=self.slope_azimuth, + slope_tilt=self.slope_tilt, plot=False) shaded_fractions.append(shaded_fraction) From b63e676251660fe87217a534ca0c8f125b60bfd0 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Wed, 23 Feb 2022 13:14:53 +0100 Subject: [PATCH 06/48] Reorder layout ValueError warnings --- twoaxistracking/layout.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/twoaxistracking/layout.py b/twoaxistracking/layout.py index 358e439..d461932 100644 --- a/twoaxistracking/layout.py +++ b/twoaxistracking/layout.py @@ -114,21 +114,21 @@ def generate_field_layout(gcr, total_collector_area, L_min, neighbor_order, 'specified when no layout type has not been selected') # Check parameters are within their ranges - if aspect_ratio < np.sqrt(1-offset**2): - raise ValueError('Aspect ratio is too low and not feasible') - if aspect_ratio > total_collector_area/(gcr*L_min**2): - raise ValueError('Apsect ratio is too high and not feasible') if (offset < -0.5) | (offset >= 0.5): raise ValueError('The specified offset is outside the valid range.') if (rotation < 0) | (rotation >= 180): raise ValueError('The specified rotation is outside the valid range.') - # Check if mimimum and maximum ground cover ratios are exceded - gcr_max = total_collector_area / (L_min**2 * np.sqrt(1-offset**2)) - if (gcr < 0) or (gcr > gcr_max): - raise ValueError('Maximum ground cover ratio exceded.') # Check if Lmin is physically possible given the collector area. if (L_min < np.sqrt(4*total_collector_area/np.pi)): raise ValueError('Lmin is not physically possible.') + # Check if mimimum and maximum ground cover ratios are exceded + gcr_max = total_collector_area / (L_min**2 * np.sqrt(1-offset**2)) + if (gcr < 0) or (gcr > gcr_max): + raise ValueError('Maximum ground cover ratio exceded or less than 0.') + if aspect_ratio < np.sqrt(1-offset**2): + raise ValueError('Aspect ratio is too low and not feasible') + if aspect_ratio > total_collector_area/(gcr*L_min**2): + raise ValueError('Aspect ratio is too high and not feasible') N = 1 + 2 * neighbor_order # Number of collectors along each side From 9ee9bd99ac203106e0a742b3260509ed86996446 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Sun, 27 Feb 2022 17:50:27 +0100 Subject: [PATCH 07/48] Fix typo --- twoaxistracking/plotting.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/twoaxistracking/plotting.py b/twoaxistracking/plotting.py index aa9378b..9b36aff 100644 --- a/twoaxistracking/plotting.py +++ b/twoaxistracking/plotting.py @@ -59,7 +59,7 @@ def _plot_shading(active_collector_geometry, unshaded_geometry, shading_geometries, facecolor='blue', linewidth=0.5, alpha=0.5) fig, axes = plt.subplots(1, 2, subplot_kw=dict(aspect='equal')) - axes[0].set_title('Unshaded and shading areas') + axes[0].set_title('Total area and shading areas') axes[0].add_collection(active_patches, autolim=True) axes[0].add_collection(shading_patches, autolim=True) axes[1].set_title('Unshaded area') From de7b7d754aeb25d564c18d6308bd513ac329baa6 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Sun, 27 Feb 2022 18:07:48 +0100 Subject: [PATCH 08/48] Remove layout_type from generate_field_layout function --- twoaxistracking/layout.py | 44 ++++----------------------------------- 1 file changed, 4 insertions(+), 40 deletions(-) diff --git a/twoaxistracking/layout.py b/twoaxistracking/layout.py index d461932..7194615 100644 --- a/twoaxistracking/layout.py +++ b/twoaxistracking/layout.py @@ -18,21 +18,13 @@ def _calculate_l_min(collector_geometry): def generate_field_layout(gcr, total_collector_area, L_min, neighbor_order, - aspect_ratio=None, offset=None, rotation=None, - layout_type=None, slope_azimuth=0, + aspect_ratio, offset, rotation, slope_azimuth=0, slope_tilt=0, plot=False): """ Generate a regularly-spaced collector field layout. Field layout parameters and limits are described in [1]_. - Notes - ----- - The field layout can be specified either by selecting a standard layout - using the layout_type argument or by specifying the individual layout - parameters aspect_ratio, offset, and rotation. For both cases the ground - cover ratio (gcr) needs to be specified. - Any length unit can be used as long as the usage is consistent with the collector geometry. @@ -47,15 +39,13 @@ def generate_field_layout(gcr, total_collector_area, L_min, neighbor_order, neighbor_order: int Order of neighbors to include in layout. neighbor_order=1 includes only the 8 directly adjacent collectors. - aspect_ratio: float, optional + aspect_ratio: float Ratio of the spacing in the primary direction to the secondary. - offset: float, optional + offset: float Relative row offset in the secondary direction as fraction of the spacing in the primary direction. -0.5 <= offset < 0.5. - rotation: float, optional + rotation: float Counterclockwise rotation of the field in degrees. 0 <= rotation < 180 - layout_type: {square, square_rotated, hexagon_e_w, hexagon_n_s}, optional - Specification of the special layout type (only depend on gcr). slope_azimuth : float, optional Direction of normal to slope on horizontal [degrees] slope_tilt : float, optional @@ -87,32 +77,6 @@ def generate_field_layout(gcr, total_collector_area, L_min, neighbor_order, .. [1] `Shading and land use in regularly-spaced sun-tracking collectors, Cumpston & Pye. `_ """ - # Consider special layouts which can be defined only by GCR - if layout_type == 'square': - aspect_ratio = 1 - offset = 0 - rotation = 0 - # Diagonal layout is the square layout rotated 45 degrees - elif layout_type == 'diagonal': - aspect_ratio = 1 - offset = 0 - rotation = 45 - # Hexagonal layouts are defined by aspect_ratio=0.866 and offset=-0.5 - elif layout_type == 'hexagonal_n_s': - aspect_ratio = np.sqrt(3)/2 - offset = -0.5 - rotation = 0 - # The hexagonal E-W layout is the hexagonal N-S layout rotated 90 degrees - elif layout_type == 'hexagonal_e_w': - aspect_ratio = np.sqrt(3)/2 - offset = -0.5 - rotation = 90 - elif layout_type is not None: - raise ValueError('The layout type specified was not recognized.') - elif ((aspect_ratio is None) or (offset is None) or (rotation is None)): - raise ValueError('Aspect ratio, offset, and rotation needs to be ' - 'specified when no layout type has not been selected') - # Check parameters are within their ranges if (offset < -0.5) | (offset >= 0.5): raise ValueError('The specified offset is outside the valid range.') From 31f45a223ec209be6e8e2ff706401ac716805d85 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Sun, 27 Feb 2022 18:08:14 +0100 Subject: [PATCH 09/48] Add layout_type code to TwoAxisTrackerField --- twoaxistracking/twoaxistrackerfield.py | 40 ++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/twoaxistracking/twoaxistrackerfield.py b/twoaxistracking/twoaxistrackerfield.py index 5f4d8c6..220cedc 100644 --- a/twoaxistracking/twoaxistrackerfield.py +++ b/twoaxistracking/twoaxistrackerfield.py @@ -11,6 +11,17 @@ import pandas as pd +STANDARD_FIELD_LAYOUT_PARAMETERS = { + 'square': {'aspect_ratio': 1, 'offset': 0, 'rotation': 0}, + # Diagonal layout is the square layout rotated 45 degrees + 'diagonal': {'aspect_ratio': 1, 'offset': 0, 'rotation': 45}, + # Hexagonal layouts are defined by aspect_ratio=0.866 and offset=-0.5 + 'hexagonal_n_s': {'aspect_ratio': np.sqrt(3)/2, 'offset': -0.5, 'rotation': 0}, + # The hexagonal E-W layout is the hexagonal N-S layout rotated 90 degrees + 'hexagonal_e_w': {'aspect_ratio': np.sqrt(3)/2, 'offset': -0.5, 'rotation': 90}, +} + + class TwoAxisTrackerField: """ TwoAxisTrackerField is a convient container for the collector geometry @@ -27,6 +38,8 @@ class TwoAxisTrackerField: the 8 directly adjacent collectors. gcr: float Ground cover ratio. Ratio of collector area to ground area. + layout_type: {square, square_rotated, hexagon_e_w, hexagon_n_s}, optional + Specification of the special layout type (only depend on gcr). aspect_ratio: float, optional Ratio of the spacing in the primary direction to the secondary. offset: float, optional @@ -34,18 +47,22 @@ class TwoAxisTrackerField: spacing in the secondary direction. -0.5 <= offset < 0.5. rotation: float, optional Counterclockwise rotation of the field in degrees. 0 <= rotation < 180 - layout_type: {square, square_rotated, hexagon_e_w, hexagon_n_s}, optional - Specification of the special layout type (only depend on gcr). slope_azimuth : float, optional Direction of normal to slope on horizontal [degrees] slope_tilt : float, optional Tilt of slope relative to horizontal [degrees] + + Notes + ----- + The field layout can be specified either by selecting a standard layout + using the layout_type argument or by specifying the individual layout + parameters aspect_ratio, offset, and rotation. For both cases the ground + cover ratio (gcr) needs to be specified. """ def __init__(self, total_collector_geometry, active_collector_geometry, - neighbor_order, gcr, aspect_ratio=None, offset=None, - rotation=None, layout_type=None, slope_azimuth=0, - slope_tilt=0): + neighbor_order, gcr, layout_type=None, aspect_ratio=None, + offset=None, rotation=None, slope_azimuth=0, slope_tilt=0): # Collector geometry self.total_collector_geometry = total_collector_geometry @@ -55,6 +72,19 @@ def __init__(self, total_collector_geometry, active_collector_geometry, self.active_collector_area = self.active_collector_geometry.area self.L_min = layout._calculate_l_min(self.total_collector_geometry) + # Standard layout parameters + if layout_type is not None: + if layout_type not in ['mcclear', 'cams_radiation']: + raise ValueError('Layout type must be one of: ' + f'{list(STANDARD_FIELD_LAYOUT_PARAMETERS)}') + layout_params = STANDARD_FIELD_LAYOUT_PARAMETERS[layout_type] + aspect_ratio = layout_params['aspect_ratio'] + offset = layout_params['offset'] + rotation = layout_params['rotation'] + elif ((aspect_ratio is None) or (offset is None) or (rotation is None)): + raise ValueError('Aspect ratio, offset, and rotation needs to be ' + 'specified when no layout type has not been selected') + # Field layout self.neighbor_order = neighbor_order self.gcr = gcr From 156d98fcb54907f864cfddc622fc2ae968126bec Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Sun, 27 Feb 2022 21:42:34 +0100 Subject: [PATCH 10/48] L_min -> min_tracker_spacing --- twoaxistracking/layout.py | 26 ++++++++++---------------- twoaxistracking/plotting.py | 29 +++++++++++++++-------------- twoaxistracking/shading.py | 19 +++++-------------- 3 files changed, 30 insertions(+), 44 deletions(-) diff --git a/twoaxistracking/layout.py b/twoaxistracking/layout.py index 7194615..bb1319f 100644 --- a/twoaxistracking/layout.py +++ b/twoaxistracking/layout.py @@ -12,14 +12,14 @@ def _rotate_origin(x, y, rotation_deg): return xx, yy -def _calculate_l_min(collector_geometry): - L_min = 2 * collector_geometry.hausdorff_distance(geometry.Point(0, 0)) - return L_min +def _calculate_min_tracker_spacing(collector_geometry): + min_tracker_spacing = 2 * collector_geometry.hausdorff_distance(geometry.Point(0, 0)) + return min_tracker_spacing -def generate_field_layout(gcr, total_collector_area, L_min, neighbor_order, - aspect_ratio, offset, rotation, slope_azimuth=0, - slope_tilt=0, plot=False): +def generate_field_layout(gcr, total_collector_area, min_tracker_spacing, + neighbor_order, aspect_ratio, offset, rotation, + slope_azimuth=0, slope_tilt=0): """ Generate a regularly-spaced collector field layout. @@ -34,7 +34,7 @@ def generate_field_layout(gcr, total_collector_area, L_min, neighbor_order, Ground cover ratio. Ratio of collector area to ground area. total_collector_area: float Surface area of one collector. - L_min: float + min_tracker_spacing: float Minimum distance between collectors. neighbor_order: int Order of neighbors to include in layout. neighbor_order=1 includes only @@ -50,8 +50,6 @@ def generate_field_layout(gcr, total_collector_area, L_min, neighbor_order, Direction of normal to slope on horizontal [degrees] slope_tilt : float, optional Tilt of slope relative to horizontal [degrees] - plot: bool, default: False - Whether to plot the field layout. Returns ------- @@ -83,15 +81,15 @@ def generate_field_layout(gcr, total_collector_area, L_min, neighbor_order, if (rotation < 0) | (rotation >= 180): raise ValueError('The specified rotation is outside the valid range.') # Check if Lmin is physically possible given the collector area. - if (L_min < np.sqrt(4*total_collector_area/np.pi)): + if (min_tracker_spacing < np.sqrt(4*total_collector_area/np.pi)): raise ValueError('Lmin is not physically possible.') # Check if mimimum and maximum ground cover ratios are exceded - gcr_max = total_collector_area / (L_min**2 * np.sqrt(1-offset**2)) + gcr_max = total_collector_area / (min_tracker_spacing**2 * np.sqrt(1-offset**2)) if (gcr < 0) or (gcr > gcr_max): raise ValueError('Maximum ground cover ratio exceded or less than 0.') if aspect_ratio < np.sqrt(1-offset**2): raise ValueError('Aspect ratio is too low and not feasible') - if aspect_ratio > total_collector_area/(gcr*L_min**2): + if aspect_ratio > total_collector_area/(gcr*min_tracker_spacing**2): raise ValueError('Aspect ratio is too high and not feasible') N = 1 + 2 * neighbor_order # Number of collectors along each side @@ -126,8 +124,4 @@ def generate_field_layout(gcr, total_collector_area, L_min, neighbor_order, # positive means collector is higher than reference collector relative_slope = -np.cos(np.deg2rad(slope_azimuth - relative_azimuth)) * slope_tilt # noqa: E501 - # Visualize layout - if plot: - plotting._plot_field_layout(X, Y, Z, L_min) - return X, Y, Z, tracker_distance, relative_azimuth, relative_slope diff --git a/twoaxistracking/plotting.py b/twoaxistracking/plotting.py index 9b36aff..368d818 100644 --- a/twoaxistracking/plotting.py +++ b/twoaxistracking/plotting.py @@ -6,7 +6,7 @@ from matplotlib import cm -def _plot_field_layout(X, Y, Z, L_min): +def _plot_field_layout(X, Y, Z, min_tracker_spacing): """Plot field layout.""" # Collector heights is illustrated with colors from a colormap norm = mcolors.Normalize(vmin=min(Z)-0.000001, vmax=max(Z)+0.000001) @@ -15,24 +15,25 @@ def _plot_field_layout(X, Y, Z, L_min): cmap = cm.viridis_r colors = cmap(norm(Z)) fig, ax = plt.subplots(figsize=(6, 6), subplot_kw={'aspect': 'equal'}) - # Plot a circle for each neighboring collector (diameter equals L_min) + # Plot a circle for each neighboring collector (diameter equals min_tracker_spacing) ax.add_collection(collections.EllipseCollection( - widths=L_min, heights=L_min, angles=0, units='xy', facecolors=colors, - edgecolors=("black",), linewidths=(1,), offsets=list(zip(X, Y)), - transOffset=ax.transData)) + widths=min_tracker_spacing, heights=min_tracker_spacing, angles=0, + units='xy', facecolors=colors, edgecolors=("black",), linewidths=(1,), + offsets=list(zip(X, Y)), transOffset=ax.transData)) # Similarly, add a circle for the origin ax.add_collection(collections.EllipseCollection( - widths=L_min, heights=L_min, angles=0, units='xy', facecolors='red', - edgecolors=("black",), linewidths=(1,), offsets=[0, 0], - transOffset=ax.transData)) + widths=min_tracker_spacing, heights=min_tracker_spacing, angles=0, + units='xy', facecolors='red', edgecolors=("black",), linewidths=(1,), + offsets=[0, 0], transOffset=ax.transData)) plt.axis('equal') fig.colorbar(cm.ScalarMappable(norm=norm, cmap=cmap), ax=ax, shrink=0.8, label='Relative tracker height (vertical)') # Set limits - lower_lim = min(min(X), min(Y)) - L_min - upper_lim = max(max(X), max(Y)) + L_min + lower_lim = min(min(X), min(Y)) - min_tracker_spacing + upper_lim = max(max(X), max(Y)) + min_tracker_spacing ax.set_ylim(lower_lim, upper_lim) ax.set_xlim(lower_lim, upper_lim) + return fig def _polygons_to_patch_collection(geometries, **kwargs): @@ -49,7 +50,7 @@ def _polygons_to_patch_collection(geometries, **kwargs): def _plot_shading(active_collector_geometry, unshaded_geometry, - shading_geometries, L_min): + shading_geometries, min_tracker_spacing): """Plot the shaded and unshaded area for a specific solar position.""" active_patches = _polygons_to_patch_collection( active_collector_geometry, facecolor='red', linewidth=0.5, alpha=0.5) @@ -65,6 +66,6 @@ def _plot_shading(active_collector_geometry, unshaded_geometry, axes[1].set_title('Unshaded area') axes[1].add_collection(unshaded_patches, autolim=True) for ax in axes: - ax.set_xlim(-L_min, L_min) - ax.set_ylim(-L_min, L_min) - plt.show() + ax.set_xlim(-min_tracker_spacing, min_tracker_spacing) + ax.set_ylim(-min_tracker_spacing, min_tracker_spacing) + return fig diff --git a/twoaxistracking/shading.py b/twoaxistracking/shading.py index 9a2c6cb..a01a910 100644 --- a/twoaxistracking/shading.py +++ b/twoaxistracking/shading.py @@ -3,19 +3,10 @@ from twoaxistracking import plotting -def _rotate_origin(x, y, rotation_deg): - """Rotate a set of 2D points counterclockwise around the origin (0, 0).""" - rotation_rad = np.deg2rad(rotation_deg) - # Rotation is set negative to make counterclockwise rotation - xx = x * np.cos(-rotation_rad) + y * np.sin(-rotation_rad) - yy = -x * np.sin(-rotation_rad) + y * np.cos(-rotation_rad) - return xx, yy - - def shaded_fraction(solar_elevation, solar_azimuth, total_collector_geometry, active_collector_geometry, - L_min, tracker_distance, relative_azimuth, relative_slope, - slope_azimuth=0, slope_tilt=0, plot=False): + min_tracker_spacing, tracker_distance, relative_azimuth, + relative_slope, slope_azimuth=0, slope_tilt=0, plot=False): """Calculate the shaded fraction for any layout of two-axis tracking collectors. Parameters @@ -28,7 +19,7 @@ def shaded_fraction(solar_elevation, solar_azimuth, Polygon corresponding to the total collector area. active_collector_geometry: Shapely Polygon or MultiPolygon One or more polygons defining the active collector area. - L_min: float + min_tracker_spacing: float Minimum distance between collectors. Used for selecting possible shading collectors. tracker_distance: array of floats @@ -75,7 +66,7 @@ def shaded_fraction(solar_elevation, solar_azimuth, unshaded_geometry = active_collector_geometry shading_geometries = [] for i, (x, y) in enumerate(zip(xoff, yoff)): - if np.sqrt(x**2+y**2) < L_min: + if np.sqrt(x**2+y**2) < min_tracker_spacing: # Project the geometry of the shading collector (total area) onto # the plane of the reference collector shading_geometry = shapely.affinity.translate(total_collector_geometry, x, y) # noqa: E501 @@ -86,7 +77,7 @@ def shaded_fraction(solar_elevation, solar_azimuth, if plot: plotting._plot_shading(active_collector_geometry, unshaded_geometry, - shading_geometries, L_min) + shading_geometries, min_tracker_spacing) shaded_fraction = 1 - unshaded_geometry.area / active_collector_geometry.area return shaded_fraction From 90893d1398baa92abef696e40880bfe45c2ed495 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Sun, 27 Feb 2022 21:54:57 +0100 Subject: [PATCH 11/48] Add whatsnew entry --- README.md | 2 -- docs/source/whatsnew.md | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 8dc3b23..077a455 100644 --- a/README.md +++ b/README.md @@ -15,8 +15,6 @@ The main non-standard dependency is `shapely`, which handles the geometric opera The solar modeling library `pvlib` is recommended for calculating the solar position and can be installed by the command: - pip install pvlib - ## Citing If you use the package in published work, please cite: > Adam R. Jensen et al. 2022. diff --git a/docs/source/whatsnew.md b/docs/source/whatsnew.md index 44d41d9..d3b2f9f 100644 --- a/docs/source/whatsnew.md +++ b/docs/source/whatsnew.md @@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Changed names of notebooks - Change repository name from "two_axis_tracker_shading" to "twoaxistracking" +- Changed naming of ``L_min`` to ``min_tracker_distance`` ### Testing - Linting using flake8 was added in PR#11 From f5db9d158d67ca020f0c5f6182ffdf54740400e9 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Sun, 27 Feb 2022 22:02:06 +0100 Subject: [PATCH 12/48] Fix linting errors --- twoaxistracking/layout.py | 1 - twoaxistracking/twoaxistrackerfield.py | 17 ++++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/twoaxistracking/layout.py b/twoaxistracking/layout.py index bb1319f..68c6b7d 100644 --- a/twoaxistracking/layout.py +++ b/twoaxistracking/layout.py @@ -1,5 +1,4 @@ import numpy as np -from twoaxistracking import plotting from shapely import geometry diff --git a/twoaxistracking/twoaxistrackerfield.py b/twoaxistracking/twoaxistrackerfield.py index 220cedc..0770fae 100644 --- a/twoaxistracking/twoaxistrackerfield.py +++ b/twoaxistracking/twoaxistrackerfield.py @@ -70,11 +70,12 @@ def __init__(self, total_collector_geometry, active_collector_geometry, # Derive properties from geometries self.total_collector_area = self.total_collector_geometry.area self.active_collector_area = self.active_collector_geometry.area - self.L_min = layout._calculate_l_min(self.total_collector_geometry) + self.min_tracker_spacing = \ + layout._calculate_min_tracker_spacing(self.total_collector_geometry) # Standard layout parameters if layout_type is not None: - if layout_type not in ['mcclear', 'cams_radiation']: + if layout_type not in list(STANDARD_FIELD_LAYOUT_PARAMETERS): raise ValueError('Layout type must be one of: ' f'{list(STANDARD_FIELD_LAYOUT_PARAMETERS)}') layout_params = STANDARD_FIELD_LAYOUT_PARAMETERS[layout_type] @@ -83,7 +84,7 @@ def __init__(self, total_collector_geometry, active_collector_geometry, rotation = layout_params['rotation'] elif ((aspect_ratio is None) or (offset is None) or (rotation is None)): raise ValueError('Aspect ratio, offset, and rotation needs to be ' - 'specified when no layout type has not been selected') + 'specified when no layout type has been selected') # Field layout self.neighbor_order = neighbor_order @@ -96,10 +97,12 @@ def __init__(self, total_collector_geometry, active_collector_geometry, self.slope_tilt = slope_tilt # Calculate position of neighboring collectors based on field layout - self.X, self.Y, self.Z, self.tracker_distance, self.relative_azimuth, self.relative_slope = \ + (self.X, self.Y, self.Z, self.tracker_distance, self.relative_azimuth, + self.relative_slope) = \ layout.generate_field_layout( gcr=self.gcr, total_collector_area=self.total_collector_area, - L_min=self.L_min, neighbor_order=self.neighbor_order, + min_tracker_spacing=self.min_tracker_spacing, + neighbor_order=self.neighbor_order, aspect_ratio=self.aspect_ratio, offset=self.offset, rotation=self.rotation, layout_type=self.layout_type, slope_azimuth=self.slope_azimuth, slope_tilt=self.slope_tilt, @@ -108,7 +111,7 @@ def __init__(self, total_collector_geometry, active_collector_geometry, def plot_field_layout(self): """Plot the field layout.""" plotting._plot_field_layout(X=self.X, Y=self.Y, Z=self.Z, - L_min=self.L_min) + min_tracker_spacing=self.min_tracker_spacing) def get_shaded_fraction(self, solar_elevation, solar_azimuth, plot=False): @@ -147,7 +150,7 @@ def get_shaded_fraction(self, solar_elevation, solar_azimuth, solar_azimuth=azimuth, total_collector_geometry=self.total_collector_geometry, active_collector_geometry=self.active_collector_geometry, - L_min=self.L_min, + min_tracker_spacing=self.min_tracker_spacing, tracker_distance=self.tracker_distance, relative_azimuth=self.relative_azimuth, relative_slope=self.relative_slope, From 6fcbc4c94662cb2ff0786a1f3fbfffe8d868434c Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Mon, 28 Feb 2022 00:01:01 +0100 Subject: [PATCH 13/48] Update twoaxistrackerfield.py --- twoaxistracking/twoaxistrackerfield.py | 31 ++++++++++++++------------ 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/twoaxistracking/twoaxistrackerfield.py b/twoaxistracking/twoaxistrackerfield.py index 0770fae..a0a818c 100644 --- a/twoaxistracking/twoaxistrackerfield.py +++ b/twoaxistracking/twoaxistrackerfield.py @@ -78,21 +78,22 @@ def __init__(self, total_collector_geometry, active_collector_geometry, if layout_type not in list(STANDARD_FIELD_LAYOUT_PARAMETERS): raise ValueError('Layout type must be one of: ' f'{list(STANDARD_FIELD_LAYOUT_PARAMETERS)}') - layout_params = STANDARD_FIELD_LAYOUT_PARAMETERS[layout_type] - aspect_ratio = layout_params['aspect_ratio'] - offset = layout_params['offset'] - rotation = layout_params['rotation'] + else: + layout_params = STANDARD_FIELD_LAYOUT_PARAMETERS[layout_type] + aspect_ratio = layout_params['aspect_ratio'] + offset = layout_params['offset'] + rotation = layout_params['rotation'] elif ((aspect_ratio is None) or (offset is None) or (rotation is None)): raise ValueError('Aspect ratio, offset, and rotation needs to be ' 'specified when no layout type has been selected') - # Field layout + # Field layout parameters self.neighbor_order = neighbor_order self.gcr = gcr + self.layout_type = layout_type self.aspect_ratio = aspect_ratio self.offset = offset self.rotation = rotation - self.layout_type = layout_type self.slope_azimuth = slope_azimuth self.slope_tilt = slope_tilt @@ -100,18 +101,20 @@ def __init__(self, total_collector_geometry, active_collector_geometry, (self.X, self.Y, self.Z, self.tracker_distance, self.relative_azimuth, self.relative_slope) = \ layout.generate_field_layout( - gcr=self.gcr, total_collector_area=self.total_collector_area, + gcr=self.gcr, + total_collector_area=self.total_collector_area, min_tracker_spacing=self.min_tracker_spacing, neighbor_order=self.neighbor_order, - aspect_ratio=self.aspect_ratio, offset=self.offset, - rotation=self.rotation, layout_type=self.layout_type, - slope_azimuth=self.slope_azimuth, slope_tilt=self.slope_tilt, - plot=False) + aspect_ratio=self.aspect_ratio, + offset=self.offset, + rotation=self.rotation, + slope_azimuth=self.slope_azimuth, + slope_tilt=self.slope_tilt) def plot_field_layout(self): """Plot the field layout.""" - plotting._plot_field_layout(X=self.X, Y=self.Y, Z=self.Z, - min_tracker_spacing=self.min_tracker_spacing) + return plotting._plot_field_layout( + X=self.X, Y=self.Y, Z=self.Z, min_tracker_spacing=self.min_tracker_spacing) def get_shaded_fraction(self, solar_elevation, solar_azimuth, plot=False): @@ -163,7 +166,7 @@ def get_shaded_fraction(self, solar_elevation, solar_azimuth, if isinstance(solar_elevation, pd.Series): shaded_fractions = pd.Series(shaded_fractions, index=solar_elevation.index) - elif isinstance(solar_elevation, np.array): + elif isinstance(solar_elevation, np.ndarray): shaded_fractions = np.array(shaded_fractions) return shaded_fractions From 167078f22fd2d33a357391f52140a91f9c7ae634 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Mon, 28 Feb 2022 14:28:07 +0100 Subject: [PATCH 14/48] Correct horizon shading --- twoaxistracking/shading.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/twoaxistracking/shading.py b/twoaxistracking/shading.py index a01a910..bf6acee 100644 --- a/twoaxistracking/shading.py +++ b/twoaxistracking/shading.py @@ -48,7 +48,9 @@ def shaded_fraction(solar_elevation, solar_azimuth, return np.nan # Set shaded fraction to 1 (fully shaded) if the solar elevation is below # the horizon line caused by the tilted ground - elif solar_elevation < - np.cos(np.deg2rad(slope_azimuth-solar_azimuth)) * slope_tilt: + elif np.tan(np.deg2rad(solar_elevation)) <= ( + - np.cos(np.deg2rad(slope_azimuth-solar_azimuth)) + * np.tan(np.deg2rad(slope_tilt))): return 1 azimuth_difference = solar_azimuth - relative_azimuth From dd40bcd2ddd015a511df922784e48334fee507fe Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Mon, 28 Feb 2022 17:41:39 +0100 Subject: [PATCH 15/48] Update twoaxistracking/twoaxistrackerfield.py Co-authored-by: Kevin Anderson <57452607+kanderso-nrel@users.noreply.github.com> --- twoaxistracking/twoaxistrackerfield.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/twoaxistracking/twoaxistrackerfield.py b/twoaxistracking/twoaxistrackerfield.py index a0a818c..dffe5a2 100644 --- a/twoaxistracking/twoaxistrackerfield.py +++ b/twoaxistracking/twoaxistrackerfield.py @@ -24,7 +24,7 @@ class TwoAxisTrackerField: """ - TwoAxisTrackerField is a convient container for the collector geometry + TwoAxisTrackerField is a convenient container for the collector geometry and field layout, and allows for calculating the shaded fraction. Parameters From d898205a007f80ffb6b7f9ecd039694ad2fa5fcd Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Mon, 28 Feb 2022 17:41:44 +0100 Subject: [PATCH 16/48] Update twoaxistracking/twoaxistrackerfield.py Co-authored-by: Kevin Anderson <57452607+kanderso-nrel@users.noreply.github.com> --- twoaxistracking/twoaxistrackerfield.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/twoaxistracking/twoaxistrackerfield.py b/twoaxistracking/twoaxistrackerfield.py index dffe5a2..b4036bd 100644 --- a/twoaxistracking/twoaxistrackerfield.py +++ b/twoaxistracking/twoaxistrackerfield.py @@ -121,7 +121,7 @@ def get_shaded_fraction(self, solar_elevation, solar_azimuth, """Calculate the shaded fraction for the specified solar positions. Uses the :py:func:`twoaxistracking.shaded_fraction` function to - calculate the shaded fraction for to the specified solar elevation and + calculate the shaded fraction for the specified solar elevation and azimuth angles. Parameters From bc9329335dd4791cbfdef6b7510de57ac465a060 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Mon, 28 Feb 2022 17:42:13 +0100 Subject: [PATCH 17/48] Update twoaxistracking/twoaxistrackerfield.py Co-authored-by: Kevin Anderson <57452607+kanderso-nrel@users.noreply.github.com> --- twoaxistracking/twoaxistrackerfield.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/twoaxistracking/twoaxistrackerfield.py b/twoaxistracking/twoaxistrackerfield.py index b4036bd..36daf8d 100644 --- a/twoaxistracking/twoaxistrackerfield.py +++ b/twoaxistracking/twoaxistrackerfield.py @@ -129,7 +129,7 @@ def get_shaded_fraction(self, solar_elevation, solar_azimuth, solar_elevation : array-like Solar elevation angles in degrees. solar_azimuth : array-like - Solar azimuth angles in degrees. + Solar azimuth angles in degrees. plot : boolean, default: False Whether to plot the unshaded and shading geometries for each solar position. From 6fd57174faf9f3f2ac469a176c4f98edbb881fe2 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Mon, 28 Feb 2022 18:31:09 +0100 Subject: [PATCH 18/48] Return scalar when scalar is passed --- twoaxistracking/twoaxistrackerfield.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/twoaxistracking/twoaxistrackerfield.py b/twoaxistracking/twoaxistrackerfield.py index 36daf8d..4eb34dc 100644 --- a/twoaxistracking/twoaxistrackerfield.py +++ b/twoaxistracking/twoaxistrackerfield.py @@ -140,10 +140,12 @@ def get_shaded_fraction(self, solar_elevation, solar_azimuth, The shaded fractions for the specified collector geometry, field layout, and solar angles. """ - # Wrap scalars in an array - if isinstance(solar_elevation, (int, float)): - solar_elevation = np.array([solar_elevation]) - solar_azimuth = np.array([solar_azimuth]) + is_scalar = False + # Wrap scalars in a list + if isinstance(solar_elevation, np.isscalar): + solar_elevation = [solar_elevation] + solar_azimuth = [solar_azimuth] + is_scalar = True # Calculate the shaded fraction for each solar position shaded_fractions = [] @@ -168,5 +170,7 @@ def get_shaded_fraction(self, solar_elevation, solar_azimuth, index=solar_elevation.index) elif isinstance(solar_elevation, np.ndarray): shaded_fractions = np.array(shaded_fractions) + elif is_scalar: + shaded_fractions = shaded_fractions[0] return shaded_fractions From 5177ff9e873598455d109cb3f03a8a0c85660129 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Mon, 28 Feb 2022 18:37:24 +0100 Subject: [PATCH 19/48] Correct use of np.isscalar --- twoaxistracking/twoaxistrackerfield.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/twoaxistracking/twoaxistrackerfield.py b/twoaxistracking/twoaxistrackerfield.py index 4eb34dc..63b4a9c 100644 --- a/twoaxistracking/twoaxistrackerfield.py +++ b/twoaxistracking/twoaxistrackerfield.py @@ -142,7 +142,7 @@ def get_shaded_fraction(self, solar_elevation, solar_azimuth, """ is_scalar = False # Wrap scalars in a list - if isinstance(solar_elevation, np.isscalar): + if np.isscalar(solar_elevation): solar_elevation = [solar_elevation] solar_azimuth = [solar_azimuth] is_scalar = True From 4e36d1dbc50479edf8a41a69719c010791935e8a Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Mon, 28 Feb 2022 20:15:36 +0100 Subject: [PATCH 20/48] Update documentation --- docs/source/documentation.rst | 4 +++- twoaxistracking/twoaxistrackerfield.py | 8 +++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/docs/source/documentation.rst b/docs/source/documentation.rst index 4c8460c..459bdfb 100644 --- a/docs/source/documentation.rst +++ b/docs/source/documentation.rst @@ -9,4 +9,6 @@ Code documentation shaded_fraction generate_field_layout - TwoAxisTrackerField \ No newline at end of file + TwoAxisTrackerField + TwoAxisTrackerField.get_shaded_fraction + TwoAxisTrackerField.plot_field_layout \ No newline at end of file diff --git a/twoaxistracking/twoaxistrackerfield.py b/twoaxistracking/twoaxistrackerfield.py index 63b4a9c..4ab2fb8 100644 --- a/twoaxistracking/twoaxistrackerfield.py +++ b/twoaxistracking/twoaxistrackerfield.py @@ -112,7 +112,13 @@ def __init__(self, total_collector_geometry, active_collector_geometry, slope_tilt=self.slope_tilt) def plot_field_layout(self): - """Plot the field layout.""" + """Create a plot of the field layout. + + Returns + ------- + fig : matplotlib.figure.Figure + Figure with two axes + """ return plotting._plot_field_layout( X=self.X, Y=self.Y, Z=self.Z, min_tracker_spacing=self.min_tracker_spacing) From 77a5abcf63bd7dc21425fd2878fa7b3f6a9ded4e Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Mon, 28 Feb 2022 20:35:29 +0100 Subject: [PATCH 21/48] Update whatsnew --- docs/source/documentation.rst | 2 +- docs/source/whatsnew.md | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/source/documentation.rst b/docs/source/documentation.rst index 459bdfb..e47a6bc 100644 --- a/docs/source/documentation.rst +++ b/docs/source/documentation.rst @@ -11,4 +11,4 @@ Code documentation generate_field_layout TwoAxisTrackerField TwoAxisTrackerField.get_shaded_fraction - TwoAxisTrackerField.plot_field_layout \ No newline at end of file + TwoAxisTrackerField.plot_field_layout diff --git a/docs/source/whatsnew.md b/docs/source/whatsnew.md index d3b2f9f..a6d4ad3 100644 --- a/docs/source/whatsnew.md +++ b/docs/source/whatsnew.md @@ -13,7 +13,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Tilted fields can now be simulated by specifyig the keywords ``slope_azimuth`` and ``slope_tilt`` (see PR#7). - The code now is able to differentiate between the active area and total area (see PR#11). - +- The class TwoAxisTrackerField has been added, which is now the recommended way for using + the package and is sufficient for most use cases. ### Changed - Divide code into modules: shading, plotting, and layout @@ -21,7 +22,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Changed names of notebooks - Change repository name from "two_axis_tracker_shading" to "twoaxistracking" -- Changed naming of ``L_min`` to ``min_tracker_distance`` +- Changed naming of ``L_min`` to ``min_tracker_spacing`` +- Changed naming of ``collector_area`` to ``total_collector_area`` ### Testing - Linting using flake8 was added in PR#11 From 9210ac344e0ab0a318061495ddb2b198e778a7ee Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Mon, 28 Feb 2022 21:49:08 +0100 Subject: [PATCH 22/48] Rework intro_tutorial.ipynb --- docs/source/notebooks/intro_tutorial.ipynb | 413 +++++++++++---------- twoaxistracking/plotting.py | 7 +- 2 files changed, 214 insertions(+), 206 deletions(-) diff --git a/docs/source/notebooks/intro_tutorial.ipynb b/docs/source/notebooks/intro_tutorial.ipynb index c111397..d05e461 100644 --- a/docs/source/notebooks/intro_tutorial.ipynb +++ b/docs/source/notebooks/intro_tutorial.ipynb @@ -18,8 +18,6 @@ "outputs": [], "source": [ "import pandas as pd\n", - "# The following libraries are not standard and have to be installed seperately.\n", - "# It is recommended to install shapely using conda.\n", "from shapely import geometry\n", "import pvlib\n", "import twoaxistracking" @@ -29,18 +27,84 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "
\n", + "## Definition of collector geometry\n", "\n", - "Now, the first step is to define the location/site for where shading is to be calculated. The location is used to determine the solar position in the next steps." + "The first step is to define the collector geometry. Two geometries have to be created, one which represents the total collector area and one or more geometries representing the active collector area. The geometries can be created using the `shapely` library, e.g.:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "image/svg+xml": [ + "" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "location = pvlib.location.Location(latitude=54.9788, longitude=12.2666, altitude=100)" + "# geometry.box(minx, miny, maxx, maxy)\n", + "total_collector_geometry = geometry.box(-1, -0.5, 1, 0.5)\n", + "\n", + "total_collector_geometry" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The active collector geometry can be made up of one or more polygons. In this example, the collector has eight active regions:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "image/svg+xml": [ + "" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "active_collector_geometry = geometry.MultiPolygon([\n", + " geometry.box(-0.95, -0.45, -0.55, -0.05),\n", + " geometry.box(-0.45, -0.45, -0.05, -0.05),\n", + " geometry.box(0.05, -0.45, 0.45, -0.05),\n", + " geometry.box(0.55, -0.45, 0.95, -0.05),\n", + " geometry.box(-0.95, 0.05, -0.55, 0.45),\n", + " geometry.box(-0.45, 0.05, -0.05, 0.45),\n", + " geometry.box(0.05, 0.05, 0.45, 0.45),\n", + " geometry.box(0.55, 0.05, 0.95, 0.45)])\n", + "\n", + "active_collector_geometry" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The collector geometries can be defined as any arbitrary polygon using the `shapely` library. However, it is important to note that the `total_collector_geometry` should completely enclose all of the active areas. Circular geometries can be created by: ``shapely.geometry.Point(x_0, y_0).buffer(radius)`` and are approximated as 64 sided polygons.\n", + "\n", + "Note, any unit of length can be used, though it is important to be consistent! Also, the absolute dimensions are generally not of importance, as the GCR parameter scales the distance between collectors according to the total collector area." ] }, { @@ -49,36 +113,152 @@ "source": [ "
\n", "\n", - "The second step involves deciding on the discrete time-steps for which shading shall be calculated. Generally the time series should cover one year (preferably not a leap year).\n", + "## Specification of collector field layout" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Once the collector geometry has been determined, the field layout can be defined. As previously mentioned, the ground cover ratio (GCR), which is the ratio of the collector are to the ground area, determines how close the trackers are arranged.\n", + "\n", + "### Neighbor order\n", + "Another required input is the ``neighbor_order``, which determines how many collectors to take into account. For a neighbor order of one the immidiate 8 neighboring collectors are considered, whereas for a neighbor order of two, 24 shading collectors are considered. It is recommended to use atleast a neighbor order of 2, though the computation time increases dramtically with increasing neighbor order.\n", + "\n", + "### Standard vs. custom field layouts\n", + "Any regularly-spaced field layout can be specified using the keywords: `aspect ratio`, `offset`, `rotation`, and `gcr`. For a description of the layout parameters, see the paper by [Cumpston and Pye (2014)](https://doi.org/10.1016/j.solener.2014.06.012) or check out the function documentation.\n", + "\n", "\n", - "The most **important parameter is the frequency**, e.g., '1min', '15min', '1hr'.\n", + "Furthermore, it is possible to choose from four different standard field layouts: `square`, `diagonal`, `hexagon_e_w`, and `hexagon_n_s`. These four layouts corresponds to a fixed set of aspect ratios, offsets, and rotations, and only require the user to specify the GCR.\n", "\n", - "It is also important to set the timezone as this affects the calculation of the solar position. It is recommended to consistently use UTC to avoid mix-ups." + "In the example below, a tracker field is created with a neighbor order of two, a ground cover ratio of 0.2, and a square field layout." ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 4, "metadata": {}, "outputs": [], + "source": [ + "tracker_field = twoaxistracking.TwoAxisTrackerField(\n", + " total_collector_geometry,\n", + " active_collector_geometry,\n", + " neighbor_order=2,\n", + " gcr=0.2,\n", + " layout_type='square'\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "\n", + "The field layout can be visualized by the following command:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig = tracker_field.plot_field_layout() " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "\n", + "## Shading calculation\n", + "\n", + "The final step is to calculate the shaded fraction for the desired solar positions. The typical use case is to simulate shading for a specified period with a fixed interval, e.g., for a yearly simulation with a time-step of 15-minutes.\n", + "\n", + "To calculate the solar position,the discrete time-steps shall be first determined. The below code cell demonstrates how to generate a series of timestamps for one year with a 15-minute interval." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "DatetimeIndex(['2019-01-01 00:00:00+00:00', '2019-01-01 00:15:00+00:00',\n", + " '2019-01-01 00:30:00+00:00', '2019-01-01 00:45:00+00:00',\n", + " '2019-01-01 01:00:00+00:00'],\n", + " dtype='datetime64[ns, UTC]', freq='15T')" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "times = pd.date_range(\n", " start='2019-1-1 00:00',\n", " end='2019-12-31 23:59',\n", - " freq='15min', # Edit the frequecy for a shorter or longer time step\n", - " tz='UTC')" + " freq='15min',\n", + " tz='UTC')\n", + "\n", + "times[:5] # Show the first 5 timestamps" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "\n", + "It is also important to set the timezone corretly, as it affects the calculation of the solar position. It is recommended to consistently use UTC to avoid mix-ups." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Next, the solar position is calculated for all of the time time steps using the [`pvlib-python`](https://pvlib-python.readthedocs.io/en/stable/) package:" + "
\n", + "\n", + "To calculate the solar position for the timestamps, it is recommended to use the [``pvlib`` library](http://pvlib-python.readthedocs.io/). A convient way to do this is first to create a location object for the location of interest. In this example, a two-axis tracker field in Lendemarke, Denmark is simulated:" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "location = pvlib.location.Location(latitude=54.9788, longitude=12.2666, altitude=100, name='Lendemarke, Denmark')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The location object can then be used to calculate the solar position for the timestamps:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, "metadata": {}, "outputs": [ { @@ -176,7 +356,7 @@ "2019-01-01 01:00:00+00:00 -52.491152 42.334286 -3.215687 " ] }, - "execution_count": 4, + "execution_count": 8, "metadata": {}, "output_type": "execute_result" } @@ -191,195 +371,18 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Define the collector aperture geometry\n", - "\n", - "In this step, the solar collector geometry is defined:" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "" - ], - "text/plain": [ - "" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Change these parameters to suit your particular collector aperture\n", - "collector_width = 5.697\n", - "collector_height = 3.075\n", - "\n", - "collector_geometry = geometry.box(\n", - " -collector_width/2, # left x-coordinate\n", - " -collector_height/2, # bottom y-coordinate\n", - " collector_width/2, # top y-coordinate\n", - " collector_height/2) # right x-coordinate\n", - "\n", - "collector_geometry" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Similarly, a cirular geometry can be defined as:" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "" - ], - "text/plain": [ - "" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "radius = 2\n", - "circular_collector = geometry.Point(0, 0).buffer(radius)\n", - "circular_collector" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "
\n", - "\n", - "Note, the absolute dimensions do not matter, as the GCR parameter scales the distance between collectors according to the collector area.\n", - "\n", "
\n", "\n", - "Derive properties from the collector geometry:" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Collector area: 17.5\n", - "Collector L_min: 6.47\n" - ] - } - ], - "source": [ - "total_collector_area = collector_geometry.area\n", - "# Calculate the miminum distance between collectors\n", - "# Note, L_min is also referred to as D_min by some authors\n", - "L_min = 2 * collector_geometry.hausdorff_distance(geometry.Point(0, 0))\n", - "\n", - "print(\"Collector area: %2.1f\"% total_collector_area)\n", - "print(\"Collector L_min: %1.2f\"% L_min)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Field layout definition\n", - "\n", - "Once the collector aperture has been determined, the field layout can be defined. It is important to specify the ground cover ratio (GCR), which is the ratio of the collector are to the ground area.\n", - "\n", - "### Neighbor order\n", - "The neighbor order determines how many collectors to take into account - for a neighbor order of 1 the immidiate 8 collectors are considered, whereas for a neighbor order of 2, 24 shading collectors are considered. It is recommended to use atleast a neighbor order of 2.\n", - "\n", - "### Standard vs. custom field layouts\n", - "It is possible to choose from four different standard field layouts: `square`, `diagonal`, `hexagon_e_w`, and `hexagon_n_s`.\n", - "\n", - "It is also possible to specify a custom layout using the keywords: `aspect ratio`, `offset`, `rotation`, and `gcr`. For a description of the layout parameters, see the paper by [Cumpston and Pye (2014)](https://doi.org/10.1016/j.solener.2014.06.012) or check out the function documentation." - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYcAAAFlCAYAAAAAkiT3AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAAC2yklEQVR4nOydd3hU1daH3z0zmUwyKTQpIaE3aQKpSAfFLt1CFQVEqdZrvZZrbzSVLkWw0ESx0VFRUum9Q0LoLcn0sr8/ktwvF0NmJjmTzOC8z3Mekpm911mHzJzf2WvvvZaQUhIgQIAAAQIURVXRDgQIECBAAN8jIA4BAgQIEOBvBMQhQIAAAQL8jYA4BAgQIECAvxEQhwABAgQI8DcC4hAgQIAAAf6GpqIdKEq1atVkvXr1KtqNAAEC+AEZGRkXpJQ3VbQfNyo+JQ716tUjPT29ot0IECCAHyCEOFHRPtzIBMJKAQIECBDgbwTEIUCAAAEC/I2AOAQIECBAgL8REIcAAQIECPA3AuIQIECAAAH+RkAcAgQIECDA3wiIQ4AAAQIE+BtlFgchRIwQYqMQYq8QYo8QYkLB61WEEGuFEIcK/q1cdncDBAgQIEB5oMTIwQ48I6VsDiQBY4QQzYEXgPVSysbA+oLfAwQIECCAH1BmcZBSnpZSbi34ORfYB9QGegELCpotAHqX9VwBAgQIEKB8UHTOQQhRD2gLpAA1pJSnC946A9RQ8lwBAgQIEMB7KCYOQogwYDkwUUqZU/Q9mV+outhi1UKIUUKIdCFE+vnz55VyJ0CAAAEClAFFxEEIEUS+MCyWUq4oePmsEKJWwfu1gHPF9ZVSzpJSxkkp4266KZBgMUCAAAF8ASVWKwlgLrBPSvlJkbd+AIYV/DwM+L6s5woQIECAAOWDEim7OwBDgF1CiO0Fr70EvAcsEUI8BpwAHlDgXAECBAgQoBwoszhIKTcD4jpv9yir/QABAgQIUP4EdkgHCBAgQIC/ERCHAAECBAjwNwLiECBAgAAB/kZAHAIECBAgwN8IiEOAAAFuCIQQXwghzgkhditkr44QYo0QYl9BYtF6Stj1F5RYylrh2O129u/fT3p6Ovv27yfXYMBkNhOk0RAWGkp07dq0a9eOdu3aERERUdHulgopJZmZmWRkZLB9xw4uXbmCwWhECEFoSAg3ValCmzZtiI2NJSoqivztJ/7H5cuX2bp1KxkZGWSfPYvRaMRmtxMaEkJEWBgtmjcnNjaWJk2aoFarK9rdUmE2m9m1axcZGRkcOXqUXIMBs8WCLjiYsNBQGtSvT2xsLK1btyYkJKSi3S0VTqeTQ4cOkZGRwe49e7iam4vRZEKtVhOm11PzppuIjY0lNjaWKlWqKHXa+cCnwEKF7C0E3pZSri3IAOFUyK5fIPIzW/gGcXFxMj093a22e/bsYeacOWz8/XcO7dtHSJUqaKNrY61aBZVWi9BokA4n0m5DlZuLyD5DTmYmN9WoQVxcHEMffpj7778fjcZ39fH8+fN8MW8eP/zyC7t27MApBPo6MdirV4cQHaLAd2mzgcmE+uw58k6cJDgoiNZt2tD7nnsY/sgjVKpUqWIvpAQsFgsrVqxg0ZIlZGRkcPnCBSLr1cVZsybOMD0iKAihUiHtdqTZQtClS5hPZmLJyeHmli3p0aULj48cSePGjSv6Uq6LlJI///yT2fPm8WdyMiePHCG8Vi3UtaOwV6qE0AYh1Bqkw4602dBcuYozO5ucU9nE1K/PrUlJPDZsGF26dPFp0T927BgzZs1i3aZN7N21C21YGLqYGGzVqiKCgxFBGqTTibTbUeXloTpzlpwTJ4msVIm27doxsH9/HnjgAXQ6nVvnE0JkSCnjrnmtHvCjlLJlwe8Ngc+AmwAjMFJKud8N282BWVLKjp79L9w4+JU4WK1WVq5cyQeTJ7P/wAF08XEENWpIcHRtVG48YUmHA9u5c1iOn0Bu34m8coUxo0fzxOOPU6tWLSUvpdRIKUlJSeHjKVP46acf0bdqjap5U4KjY1BHRri8OUgpcVy5guVkJs69+zDs3Ue/fv14evx42rZtW05X4ZqTJ0/y6eefM2vOHIJq1oRbWhFcpw5B1W9CqFxHOx1GI9asLOyHDmNMS6dd23Y8N3Ei99xzj8+MKHJzc1m0aBEfTZ3CxZxcNPGxaOvXRxsVhUob5LK/02bDdvo0lmPHcaRnEBGs49nx4xk6dCiRkZHlcAWucTgcrF69mg8nTyYlJYXQuFiCmjZGGx2NWq932V86ndgvXMRy8iRy5y4smVmMePRRxj75JA0aNCixr5visB4YLaU8JIRIBN6VUnZ35ZcQojcwArAC9YF1wAtSSofLi7pB8AtxkFIy94sveP7FF1HdVA11QjyhrVoiyngTsGZnY0lOJW/rNvr06cOnkycrOcT1mNTUVIaNHEn2+fMEJcajj49HrQ8tk01Hbi7G1DQsyak0rF+PhXPm0qpVK4U89pyzZ8/y+JgxrF27ltC4WIITE9DWqF4mm06bDeOOnThS01DnGfh00iQeeKDiNuTbbDbeeudtPvpkEqGNG6FJjEfXuHGZnvqllJiPHsWenIph/wHGjhnDf15/neDgYAU994zvv/+e0WPHYg0ORpUQh75tW7dEryRs5y9gTknFmJZO586dmTN9OrVr1y62rStxKAgFnQcOFGkSLKW8WQjRF3izGLOnpJR3CCH6k58WqC1wEvgW+FlKObdMF+hH+Lw4ZGVlMeiRR9h55Aih/foQHBOt+HmdJhOG1Wtx7t3H/DlzuO+++xQ/R0mYzWZeevVVZs2dS+i9d6Nv28atp2dPkE4nhtQ0DL+s5rmnn+blF18kKKhsX2SPzi8lX3/9NU+MG4c2rh36Ht1ReeHGZj56DMPy7+gUF8cXs2ZRvXrZhMdTdu7cyQODBnFBJQjpfT9BXnjYsF+5ivH7VUQYDCxZvJi4uDjXnRTk0qVLjHrySdb89hv6fn0IadxI8XM4rTYMGzdhSU5h6iefMGzYsL+JqxviEAEckFJ6HBYQQiQB70spuxT8PgRIklKOKe01+Rs+u1qpcLTQvHVr9uqCqTTuSa8IA4AqJITw3vejfaA/g0aN5IGBA7l8+bJXznUtqamp3Ny6NQs3bKDq0xMIi22nuDAACJWKsKREqk4cx7RlS2kdG8uuXbsUP09xnD17lnt69eLJf/2LsEeGEH73XV4RBgBdg/pUnjiOFKOBJs2bs2TJEq+c51psNhuvvfE6t3bpwqVWLQkfPswrwgCgqRRJ+NBBGBLj6drzdp574QUsFotXznUtP/zwA41vvpnfzp2lytMTvCIMACptEOF33E74Y8N56vXXue3OOzl16pRHNgpKBxwTQgyA/CShQohb3OyeBlQSQhSmiu4O7PXIAT/HJ0cOTqeTUU8+wbJffiXsoQFoo6LKzQenxYLhp1/QZWby56bfqFOnjtfO9e233/LYE08Qet89+aOFcppslFJiSEnF+Osaln39NXfeeafXznXgwAE6d++Os0Vz9D1vQ1WOoxXz8RMYvl3KqKFD+eDdd732/2swGLj7/vvZdfYsYQP6oinHBQD2nBwMy7+jUVg46375hfDwcK+cR0rJm2/9h48//YywBwega1jyfICi57bbyVu/AWfGNjatW/ffsOi1IwchxNdAV6AacBZ4DdgATAdqAUHAN1LK4sJJf0MIcTvwMfm54zKAUVJKqxv9vgDuBc4Vzn1c874ApgB3kz9J/khhNU0hxDDglYKmb0kpF1zbv7zwOXFISUnhocGDWb9tGxHDh6Jyc+WC0uT9/gckp/Lnpk1eWQkzZ84cJr7wApUee6Rcxa8o5mPHyVn4JfNmzmLAgAGK29+xYwfdbr+doNt7oE+IV9y+Ozjy8rg6dx4Det7BrOnTFReInJwcut1+OyfUKsL79y3zPFhpkE4neSu/p/rVXDZv3EjlypWVtS8lTz37LPOXLiVixKNoIitmObhh6zbMP/7Mul9/JT4+vtiwki8ghOgM5AELryMOdwPjyBeHRGCKlDJRCFEFSAfiyC+OlgHESinLJ4xxDT4XVhr22GNs2LmTiMeGV5gwAIR17gSdOtCxWzcyMzMVtf3VV1/x1AsvUHn0yAoTBgBd/XpEjniM4Y+P4ueff1bU9sGDB/OF4e47K0wYANRhYVR6fCTL1q1j4jPPoOTDkMlk4va77uJksJbwAf0qRBigIGTYpzdnq1am6+23k5eXp6j9l199lQUrlhM5elSFCQOAvl1bQvr25va77mL3bkX2uXkFKeXvwKUSmvQiXziklDKZ/PBVLeAOYK2U8lKBIKwFvDesd4FPicOpU6f4+c8/CR82uMyrHpQgrH0SMiGOTt27KfaF27hxI6PGjiFyxHCCfKDyXXDtKCKGDeXBQYNwd4+JKy5cuEDn7t0Juq07+rZtFLFZFlQ6HRGPPsKCZcv46OOPFbEppaTfgw9yxG4jrE8vr8wTeYIQgvD77iVbF8w9vXvjdCqzX2v6jBl8Nm8eEY8NL/PKOSUIbdmC4LvvpOtttylir5qoKSNEFY8OIcTuwtLGBccoD09bGyj6xJlV8Nr1Xq8QfGoH2Lnz54keM9prk5WlIaxLZ3LPnOWpZ59l9owZZbKVm5vLQ0OGEDagP1of2VcBoKtXF8d99zBg4ED279pV5uWRo558AkfTJoQnJijkYdlR60MJHz6UN956i3vuvpvmzZuXyd78BQv4a+dOKo97ssKFoRAhBGF9e7Nr+kw+mz6dcWPKtrDm8OHDPPfCC1R6cjRqL81llAZ9bDtyz5+HX9eU2ZYVK4mq2z3qs865xOyL4Syl8Y1PdQGqSpV86kNYSOh99/DNsmVs3LixTHbGP/UUznp1CW1+s0KeKUdou7bkhofxyr//XSY73333Hes3/4n+zp4KeaYcQVWqEHrH7TwwaBB2u73Udk6dOsWEp59GP6Dff3ep+wpCrSZ0QD9efPlljh07Vmo7TqeTh4cOJbRb1zLvQ/EGYbcpV0dMqIRHhwKcAmKK/B5d8Nr1Xq8QfEscQn0zj4w6NBR9394MHDa01OGldevWseyHH9Dfe7fC3imDEILQ3vczfdYs0tLSSmXjwoULPDpqFPoBfVFptQp7qAz69kmctll574MPStVfSsmQ4cMJTkokOLrCRvwloq1Rg9CuXXhoyJBSh5emTJvGkQsX0Hf2zewRiomyECBUnh1l5wdgaMHS2iTgqpTyNLAa6CmEqCyEqAz0LHitQvApcfBlQls0xxYdzYuvvuK68TVYrVYGDx+Ovk8vt9J8VBSaiAj0993Dw0OHluqmMu7pp9C0boXORdqDikQIQWi/Prz34QccPXrU4/5Llixh68EDhPXo5gXvlEPfpROHzp5h/vz5Hvc9deoUr772GqH9+/pMyMxbCJQfORQsqd0CNBVCZAkhHhNCjBZCjC5o8jNwFDgMzAaeBJBSXgL+Q/4eizTgzYLXKoQb+y+vMKF33M4XX8zzePSwcuVK7BHhPhlOupbQdm25ZDKxYcMGj/qdO3eO71euJPQ2l2lrKpygKlUIiY9jyqefetz3P++/j+7223wunHQtQqUiuOftvP3BBx6v0Pp8xgxC2tzik+Ekr6DwyEFK+bCUspaUMkhKGS2lnCulnCGlnFHwvpRSjpFSNpRStpJSphfp+4WUslHBMc+LV+2SgDh4gKZSJUIbNWLRokUe9ftg8mTUFbic0xOEEKgT4vlwyhSP+s2aPRv9La1Rh1b8ihZ30CUmMm/+PEwmk9t9MjIyOJmVRYgfiDyArnEjLubl8eeff7rdx2azMX3mTIKTEr3omQ8hAJXw7PiHEBAHD9EkxvPRlCluP43t2bOH/QcOENrqb3thfBZ9XDv++O03srKy3GrvcDiY+vlnaBP954YSVK0qwXXqeJReY9K0aQQnJvhNqEUI8d/Pq7usXLkSVbWqaGvV9KJnvoQomHfw4PiH4B+fch9C17gRF3Jz3H4amzxtGiGJ8RW2Qao0qIKD0ce25bPpn7vV/ueff8ah13st95W3UCfE88GkSW61vXz5MitWrCA00T9GgIXo4+JY8+uvnD171q32H0yejMpPRrlKIVQqj45/Cv+cK1UIoVKhbt2KlT9871b771etIriNu7m+fIegNm1YutK9a1y2ciW0bOFdh7xAyM3NOHrkCOfOnXPZduPGjYQ1qO+TS61LQh0aQtjNzVizxvWegJycHHZs3Yrej0a5ihAYORRLQBxKQVB0NJuTU1y2u3DhAjlXr/rETmhP0UZFcfLIEcxms8u2W1JTCa4T47KdryFUKsLr1SUjI8Nl2+TUVBx+Gmpx1KzBltRUl+22bdtGZEyMz0+2K4oQoFJ5dvxD+OdcqYJoY6LZvWOHy3mHjIwMIurV9cuhqEobRHhULZdpvS0WC8cPHUJ7nYIsvo6zZk3S3Egbsjk5maBo/wqbFaKNieGvFNcPMxkZGRDlOzv3y43AyKFY/O+u5QNoIiIQWi3Hjx8vsV16ejrOmv75tAmgjopy+VS9e/duwmvW8NlNb65Q1Y7ij+TkEttIKdm1YwdaP5tTKUQbHc3+PXtwOEqucPlHcvI/UxwCq5WKJSAOpSQ0JoatW7eW2GZzaioqP/6yOWvWcPnEuW3bNtR+OmoACI6OZvu2bSW2ycrKQgqBxkfqNnuKOjQEXUQEhw4dKrFdxtataP10dBRAef5BwUWFCQvl0qWSNy+ev3ABdbT/ioM6PJyzFy6U2ObixYs4fDTtiTuow8PIvXq1xDYXL14k2E+FoRBtZITLz+vVy5eJDA8rJ498BAFCmZQYNxyK/K8IIb4QQpwTQuwu8trrQohTQojtBYdvJhUqJVKjcbmBymwyIcqx8pnSiKAgl9doMplw+tEy3WsRQUHYXJTYNJlMPpFCviy487e0WSzlWqnPN/AwpBQIK3nMfIovSjFJStmm4FC2mkwFIxEuY7j5+Yn8+MMkXF9j/vv+fY3S6SxxcYHf/x3Brb+l0+n8R024/pfAhHSxKBJWklL+LoSop4Qtf0E4HIS4SKIXrNMhy5AauqKRdrvLawwJCUHlLPmm48tIux2NVlti+VCdn/8dAaTN9d8yKDjY76+zVPyDbvie4O1g21ghxM6CsFOxhW2FEKMKKyo58gxedkc5hMWKXq8vsU2YXo/T4nqfgK/iNJsJdxGD1uv1qKy2cvJIeZxmMzoX+aDCwsKwe5CDyRdxmM0uP68hoaE43djXckMhCOxzuA7evNLpQEOgDXAaKLY+o5RylpQyTkoZpw4r+cPrS9jPnKZFi5J3Bce1aYP99Jly8kh55NlzxN/SpsQ2LVq0QLixw9hXsZ0+TeOmTUts06BBA0yXL+N0MTfhq0i7ndwzZ2jWrFmJ7Zre3Axr9uly8spXCORWuh5eEwcp5VkppUNK6SQ/Z7nv1IwsI06LhdwzZ2nZsuQ0A4nx8WjOuJfTxhdRnT5NXFzJ1RDbtWvH1eMnkArVLC5vrJlZdHCRMDAoKIiGTZtizaqwolxlwnr6DFExMYS6GCF1TmqP/ZR/XmOZCIhDsXhNHIQQRddw9gF2X6+tv2HNzqZ+k8ZoXWz8io2NxXQys8Q2vop0Osk5cZLY2NgS21WpUoXKVatiO3e+nDxTFs2ZcyQluH5uaZ+QgCXTvSy1voYlK4t4FyIPkBAfj9qPH2ZKTUAcikWppax/q3wEfCCE2CWE2Al0A55S4ly+gCUzi6R41zeUhg0bYjcZcZSytGhFYr9wkYjISKpWreqybbt27bC6md7b1zBnZroUQIBbExP99sYpTp+mU1KSy3axsbEYTpzwuDiQXyMILGW9DoqIw3UqHw0pqHLUWkp5f0GN1BsC1eEj9OzuuuKZSqUisf2tGPfuKwevlMW8bx9dOnd2q+2dPXogDx32skfKYz1zFpXDQePGjV227dSpE8aDB/1uNY90OrHsP0hnN/6WtWvXJjwsDKufjpBKTWDkUCz/nKl3hbBduIAlM5O+ffu61f6psWNxprlO7OZLSKcTa0oaE8aMcav9kCFDMOzdhyM318ueKYslOYXRo0aicmMFSpMmTbi5aVMMu/wrOmrat5+YWrVo06aNy7ZCCMaOfgJriusMrjcOAqXLhN4o/HOuVCHMyak8OvxRl2vGC7nnnntQGwxYMv1n7sF86DA3RUTQoUMHt9pXrlyZvn37YkxJ87JnyuG0WDBs3caYJ550u8/zTz2FM9V/rhHAkZrG80+5H9EdNXIkhp07cRiNXvTKhwiEla5LQBw8wGm1YUxLZ9yT7t9Q1Go1458c41dPY/aUNJ6dMKHEjWHX8vT48VhSUv1m1ZIhYyudOncm2oNEc71798Z54SJWP1mebLtwEcvJkzzwwANu96levTp33XU3xlT/Gu2WiUBYqVgC4uABhpQU4uLjadiwoUf9Ro0ciXHHLuyXL3vJM+WwnjmL6cgRBg8e7FG/du3aUa9ODIatJWc49QWk3Y7try08N2GCR/2CgoJ4cvRozL/97iXPlMX0+x8Mf2S426PcQp6dOBHLli04rVYveeZjBMShWALi4Ca2i5cwrd/AdA+KtRdSvXp1nn/uOQzLvvPplSDS4cCwdDnvv/02YWGeZ+ec/dnnGH/6xefnHvLWrSex9S306NHD477/eu451JlZPr/IwHT4CHL/AV5/9VWP+7Zv357bOnfG8Kvr0qL+T2AT3PXwKXGQNt9cCSKlxLjiO158/l80b968VDZefvFFaqjVGHw4vJT3+x80i4riiSeeKFX/xMRERj76KIaVqxT2TDksmZlYU9NZMHeuR2GzQsLDw/lqwQIMK1bi9NGUGk6LBcOy5cyfM4fKlYvNWuOS2dNn4Ni1G/PRowp752N4ac5BCHGnEOKAEOKwEOKFYt6fVCRj9UEhxJUi7zmKvPeDYtfqIT4lDs7Ll30yZm3YkkyUNph/PfdcqW1oNBqWLF6M4ZfVPhlesp45i/m3P/h64UK3Vu9cj3ffeouwK1fI27ZdOecUQtrtGJYu5/OpU6lZhgp9PXr0YEDv3hh+9M1Ew4ZfVnNnt+7cd999pbZRtWpVvpg1i7ylK3wyvGTcs1c5YwqPHIQQauAz4C6gOfCwEOJ/niqllE8VZqwGpgErirxtKpLN+n7FrtNDfEocgjUaDKvXVrQb/4MlMwvjmnV8u2gRmjIWXm/ZsiX/evZZ8r7+1qe+cE6Tibyvv+W9t96iXr16ZbKl0+n4dvFijD+swnrWdzaNSSnJ+2EViS1bMXDgwDLbm/LJJ2hOnMSQXnIZ1fLGuGMnct9+Zn72WZlt9e7dm9s6dSRvxUqfemizXbhI3vLvFLMnhfDocIME4LCU8qiU0gp8A/Qqof3DwNcKXIqi+JQ4NG7UiNDDR8jb5BsTftazZ7k6bwFffvFFqcNJ1/LKSy/Ro10suYu+8okNVU6rlZz5C3ngrrt40oNVWCWRmJjI1I8/4eqcL7C5qD5WXhhWr+GmKzks/frrUoWTriU8PJx1v/6K5ZfVGHfvUcDDsmM6cADj96tY+8svpQ4nXcuXX8wjxuEk78effWK+zH71KlfnzOW9N99UzqjKw8M1tYGia9ezCl77G0KIukB9YEORl3UFmaqThRC9PbgSRfEpcdBoNGzetAl1xlbyNm6qUF+s2dlcmTWXTz/5hD59+ihmV6VS8dXChcTH1CHny8U4KzDdtdNsJueL+dweG8eMzz5T5KZZyKPDh/PGSy9zdcZsbOdLLjXqTaSU5P78C2FHj/HbunVEREQoZrtFixas/eUXjMu/w7Bzl2J2S4Nx7z7yvl7Cz99/T9u2bRWzq9fr2bhmDVXPniPvhx8rdARhu3SJKzNm8/y48Yx1c4OmSwSlCStVKywzUHCMKoMHDwHLpJRFi6LUlVLGAQOByUIIz5ZHKoRPiQNAdHQ06Vu2oN+zj5xVP1XI07Xp4CGuzJ7LnE8/5ZFhwxS3HxQUxKrvvqNr02bkzJ2HPSdH8XO4wn75MldnzqFP5858/eWXZZpnuB5PT5zI+2+8weUZszAfP6G4fVc4rTZyl39H9TPnSP3zL2666SbFzxEfH8+mdeuw/vAjeZv/KvenaykleSmpmJatYO0vv9CxY0fFz1GpUiWSN28mJs9A7pJlFZK63JKZxZXpM3ntued45aWXFLRcqtVKFwrLDBQcs64xegqIKfJ7dMFrxfEQ14SUpJSnCv49CmwClFN7D/A5cYD8HC9pW7bQWqXm8rTPsZRTqmSnxULud99jW/4d3327hIceeshr5woKCmLp118zok8fLn0yBUPG1nK5sUgpyduSzKXJ03h25EjmzJjpFWEo5InRo1k0Zw7GLxeT+9MvOG3lM1IyHzvO5SlTaX9Tdbb88QfVqlXz2rnatWtH8ubNVD1wkNwv5pfbggP71RxyFywifOt2/vztN5LcSK5XWipVqsQfGzfSvX4DLk2agunwEa+dqyjSbif31zXkfjGf2VOn8YwHu73dRvmlrGlAYyFEfSGElnwB+NuqIyFEM6Ay+UlLC1+rLIQILvi5GtABUHD23X18UhwAqlWrxvrVq/nktdfInTuP3DVrvTqKMB06zKVPptAjOoZD+/Zx++23e+1chahUKj549102rllDaHIquQsXeXUUYb98mZw586i27wDJmzfz8osvKhpKuh69e/fm4N69JISEcmXKNK+OIpxWG7k//oxp8dfMnTyFVStWKBpKuh5NmzZlZ0YGY/sP4OLkaeQlp3hN7KWU5KVncHHSFEbcdRd7d+xwWVtECfR6PUu++orFs2ZjXbKM3JU/eHUUYcnM4vLUz7hFwv7du732sKb0hLSU0g6MBVYD+4AlUso9Qog3hRBFVx89BHwj//eDcjOQLoTYAWwE3pNSVog4CF+YZCokLi5Opqf/fdv+qVOnGDx8ONv27iUoKQF9XCwqD3d9Fod0OjEfOow9JRV5KpsFc+dyzz33lNluabBYLLzy73/z+cyZhCbEoUtMJKia63TZ7mA9exZLcirGrdv417PP8tILL5R55VVpkFKyZMkSHh8zhqCGDQhKTCC4QX1FBMphMGBITceanEzXDh2ZO2OGV8JI7rBz504eHDyYc2YT6qRE9Le0Rijw/y3tdgy7duNISaWShCWLF7uVbtwbXLp0idFjx/LLunXokhIJTYxHXYqNk9cipcRy4iS2lFQs+w/w6eTJDBkypNjPiBAioyA2X2oi9VEyqdlIj/qs2fpmmc/rD/iFOED+h2bTpk18PHUq69etI6xdG7QJCWhrR3l8c3EYjBjT07GlplE1PJxnx09g8ODBhIeHK3EZZeLw4cNM+fRT5i9YgK5uHdQJ8YQ0a4pQqz2yI+12jHv24khNw376DKNGjmTME09Qt25dL3nuPleuXGHe/Pl8MnUqeQ4HmoR49LFtPRZ8KSXWk5lYU1LJ27mLe+65h2cmTKB9+/Ze8tx97HY7q1at4oNJk9i5axchCXGEJCYQ5EZ9jL/ZunwZU0oaptRUmjVtxvMTJ9KnTx+CgoK84LlnpKen88nUqaz87jv0LZoTlJRAcN26CA9DlYWJEB2p6QTb7Tw1bhyPPfpoifVEFBOHmz2bT16T8UZAHMqbksShKNnZ2cyYNYsZs2eRl2cgvF5d7DVqoImuTVCNGqiCtQiNBulwIu027JevYM3KQnPmLNasUxgvXuSue+/l2QkT6NChQ7mEVjzFaDTy7bff8tGUKRw6cIDImBiIqgVRtdDWjkIVEooIyn8alTYbTqMxv4zl6dPI7NPkZGbR4pZbeH7iRPr27UtwcHAFX9HfkVKyYcMGPpw8mQ1r1xJW/SY0taNx1KpBcEw06ogIRFAQQqVC2u04LRasp8/gPJWN6swZco+foHKVKowdPZqRI0ZU2EjBFfv372fqZ5/x5aJFoNEQWicGe43qBMXEEHRTtfxrVKuRDgfSZsN24SK2rCw0Z89hOnESh9nMwIEDmThunMu65RXFpUuX+GLePKZ8/jkXzp4lvG5dnLVqooqqhTaqFiI4GFVQENLpRNrsOHJzsGRmoT5zFsepU+SeOUunrl15buJEevbs6dY8mGLi0Pxxj/qsSX89IA7ljbviUJTs7GwyMjJITUvjj5RkDh04iNlswmqxotFoCNbpuKl6ddonJHBrYiKxsbHcfPPNFRJWKS05OTls27aNjIwMfk/ewo4dO8nLzcVqNoMQaIODiYiMpF3btnRKSiI2NpY2bdqg1+sr2nW3sVqt7Nmzh4yMDP5MSSElLY2LFy5gtVhwOBxotVp0ISHc3Lw5nZKSiI+Lo127dtSoUaOiXXcbKSXHjh0jIyODlLRUNiencOLEcSxmCzarlSCtFm1wMDExMXRMSiIxPp64uDgaNGjg1UUDSnP+/Hm2bt1Keno6vycns3fPHkxGI1arFZVKRbBOR+WqVUiMi6dDwXeyZcuWHj/AKCEOEfraMqmFZ+KwNu21gDiUN6URhwABAvwzUUQcwmrLpJYeikPKP0Mc/OfxOUCAAAG8gQ+GlX2BgDgECBDgH42b+ZL+cQTEIUCAAP9sAtpQLAFxCBAgwD+bwMihWALiECBAgH8uAqT/LAQrVwLiECBAgH82gZFDsdxQ4nD69GkOHjyI0WjEYrGg0WgICQmhZs2aNG3a1K/2NlyP3Nxc9uzZQ05ODiaTCSEEOp2OSpUq0bJlS0JDQyvaxTJjs9nYt28f586dw2w2Y7fb0el06PV6mjVr5rOb3TxBSsnx48c5fvw4JpMJq9Wav5dDp6Nu3bo0aNDAJzdnesrFixfZt28feXl5mM1m1Go1ISEhVKtWjebNm6PVaivaRaT//zd7Bb+9WzocDjZs2MDmP//kj+Rktm/bhtlsIiyqNiJYm7/j1OkEux3rpcuYLl+mSfPm3JqYQPuERO655x6vZupUip07d7J+/Xr+SE4mLT2ds9nZRETXRh0a+t98PdJmw2EwknPqFFF16pAQH0+npCRuv/12mjVrVsFX4JozZ87w888/82dyMltSUzly4ACh1aqhrRQJQUEIIfJ3D5st5J46RVhYGG3ataNz+/Z06tiRzp07+/wmMZPJxC+//MJfyVvYnJzC7p07EUFBhFSvjkobBAU7pLHZMJ07j8NspkXr1nRMTOTW9u25++67fV74pZRs3ryZP/74g9+2bGHb1q3kXL1KRHRtRHBwftYCKcFux3blKobz56nfpDFJ8Ql0SEzk7rvvpnbtYmvieBG3M63+4/C7TXDnzp1j1uzZTP38MxyhoVC/HproaLTR0WiqVL7u05bTZMKSdQprVhbqU9nkHTjIvffeyzMTJpCQkOBTT2lms5lly5bxweTJHDtxAl2L5lCrJsF1YgiqUeO6eZak3Y719BksWVmI7NOY9uyh+c3NeX7iRHr16uUTuXgKkVLyxx9/8NGUKaxds4bwFs1x1KpFcEw02ujaqK6zW1ZKif3iRSwnM3FmZ+M8fJQQKXlq3DgeHT6cKlWqlPOVlMyRI0eY+tlnzJs/j+Da0ThjogmKro02JhpNCdliHbm5WLJOYcvMQp2VhenkSYYOGcqEsWNp0qRJOV6Ba65evcqCBQv4eOpUcqxW1E0ao4qqRXBMDJpqVa+bZ8lpsWDNzs5Po5F9mrw9e+narRvPTphAt27dXH4nFdkEFxEt4+M8Kxy0YeNL/4hNcH4jDocPH+b5l17i119/QX9La7SJCQTHxBTb1h0cBgPG1HSsKanUqlaNN199lQEDBlSoSOTl5fHmW28xc/bs/PxJCfGENr/Z46R7hUi7HcPOXThT03FeusT4MWN44fnn0el0CnvugU9SMm/+fP7z3rtcNhoJSixbll0pJZbjJ7CnpJK3Zy+9e/fm/bffJqYMnw0lSE5O5l+vvEJ6ejqh8XHokhIIKsNI1XbxEuaUVIypadzSujXv/ec/dO7cWUGPPef06dO8+OqrLFmyBP3NzdAkxqMrQzjMaTZjyNiKPSWNcI2Gl//1L0aOGHHdUaFS4hAXP9ajPhs3vOhX4iCEqAxEASbguJTSrXJ+ioiDEOIL4F7gnJSyZcFrVYBvgXrAceABKWWJVVCKEwen08nkKVP49xtvENK5I6Htk1ArOLyWTiem/Qcw/7KapNatmT9nDjVr1lTMvrts3LiRgcOGYouuTUj3bgQpHFe3nj6Ned0G9FeusmTxYhITExW17w4nTpxg4LBh7M3MRHdnT3SNGykqxo68PAyb/8SSnMonH37IiMceK3exN5lMvPDyy8xdsICQnrehb9cuP2ykENJuJ2/bdsy/ruHhAQOY9NFH5Z5DS0rJokWLGDtxItrYdoR06lDiKKg09i3HjmH+ZQ2NbrqJrxcupGHDv1fKVEwcEj0Uh3W+Lw5CiEhgDPAwoAXOAzqgBpAMfC6l3FiiDYXEoTOQBywsIg4fAJeklO8JIV4AKksp/1WSnWvF4fDhwzw4eDDHLl9GP6Cv4jfMoki7nby167GmpfP51KkMHDiwXG4seXl5THzmGb5dsQJ9396ENr/Zq+czbN+B4ftVjHz0Ud59661yGUVIKZk5cybPvfgiuk4dCOvapdSjIXewZp/GsHQZreo3YPH8+eU2itiyZQsPDR6MoWoV9L3uU6S+wfVwGI0YVv2E9tQpvl74JV26dPHauYpy+vRphj32GKl79qAf0I/gmGivnUs6nRh+34xx4ybeevNNxo8d+z+jCCXEITwiWsYljfOoz6a1L/iDOKwFFgKrpJRXrnkvFhgC7JJSzr2uDaXCSkKIesCPRcThANBVSnlaCFEL2CSlbFqSjaLisHz5coY99hihPbqh79jB4/zwpcVyMhPD0mXc3qEjXy1c6NU4/eHDh+ly221Ya0cReu89qEPLXsDIHRy5uRhW/kClPAOb1q0jOtp7X3CTyUSvfv1IO3AA/YB+aGuVz6hMOhzkbdyEefNfrFiyxOuV/d59/33e/uAD9L3uQ39La6+eqyjG3XswrPyeCU88yX/eeMOrDzS///479/XpQ3BiPPoe3RUpYOQO1rPnMC5bQcuYGH7+/nvCCkRXEXGILIU4rPF9cVACb95xa0gpTxf8fIb84YxbfPHFFwwbNZLIkY8S1rlTuQkDQHCdGCqNG8uG/fu48957MZlMXjnPzp07SezQAVtSAuEP9C83YQBQh4cTMWQQOc2aEte+PYcPH/bKeXJycujcowdbL16g0pjR5SYMAEKtJvy2HoQPHUSfBx5g+fLlXjmPlJJnn3+e9z/9lCrjx5arMACEtmxBlQnj+PTLhTw5bixOp1vhZI/5+eefubtXL0IfHEDYHT3LTRgAtDWqE/nEKPZazHTo2pVLly4pal8Kzw5/QAjRrqTDHRvlctctqJFa7BBFCDFKCJEuhEg/f/48C7/8kgn/+heVHh9FsBefaEtCpQ0iYsggdly+xN3334/ValXU/r59++jSoweaO3sS1t57ReFdEdatC84O7bm1c2dOnFC2rrPRaKRbz54c06gJf+gBr4aRSkLXoAGRI4YzbORIVq1apbj95198kTlLlxI5eiSaSpGK23cHdXg4kaNG8s3q1YydMF7x2tVr167lgUGDiHhkKCFNK2allFCpCO/fl1OREXTu0YPc3FwFjQvPDv/g4xKOj9wx4E1xOFsQTqLg33PFNZJSzpJSxkkp47RaLU9OnEjkiEfR1qjuRddcI9T5N7WdF87z4KCBin3hMjMz6dKjB9o7bkffrq0iNstCWPskxK1JdOjalfPnzyti0263c0+vXpwQEN6nV7mO/IojODqayOFDeXjoUH777TfF7L7/4YfMWryIyBHDvTq/4A7q0BAiHh3OV6t+5LU33lDMbkpKCn0ffICIoYPQ1avYErNCCMLvu4ez4WHcdtdditm9EUcOUspuJRzd3bHhzW/tD8Cwgp+HAd+76nD02DEihg5GW9M3qnsJtZrwQQ+zaetWZs2aVWZ7TqeTBwYNQrZriz7ed0KW+k4dsTSszyMjRigigu9/+CE7TmURPqBfhQtDIcF16hD24AD6PfQQV65cKbO99PR0/vPuO0Q+VvHCUIg6NITIEcP5ZNo0/vjjjzLby8vLo/eAAYT26Y2uQQMFPCw7QgjC+vTicG6OgkY9PPwMIURLIcQDQoihhYc7/RT55gohvga2AE2FEFlCiMeA94DbhRCHgNsKfi/ZGb2+wp9OrkUVFIR+QD+efeEFTp48WSZb06dPZ392NmHduyrjnILo77yDP7dmsGTJkjLZ2bt3L++8/z76/v0qLJR0PUJvboZo0pgnx48vkx2LxcIDgwahv/ceNJUrK+SdMqjDw9H36cXDQ4ZgNBrLZOvpZ5/FFl0bfetWCnmnDEKlQt+vj0LGAJXw7PAjhBCvAdMKjm7AB8D97vRVRByklA9LKWtJKYOklNFSyrlSyotSyh5SysZSytuklC5nkVQR4Uq4ozjaWrXQdezAwGHDSv1kffz4cf718svoB/T1uZsm5ItgaP9+PD5mDOfOFRsBdIndbufBwYPR97yNoKq+tVO5EP3dd/Lj6tX88ssvpbbxymuvkaMPJdQHwoLFoW/VEnON6jz7r+dLbWPTpk18vXwZ+vvuUdAz5dBEKje/cyOGlYrQH+gBnJFSDgduAdz6z/ONMX8hPjzZE9atC3tOnmDOnDke95VSMnDYMEK6dEJbARvs3EVXry5B7dry2OOe1dQt5MOPPybbYkZfgZPsrlDpdOj792XIo4+Sk+N5aGLr1q1MnzmT0D69fCrlyrXoe93Hwq++5s8///S4r9Fo5OGhQ9H36a3ohlOf5cYOK5kKdkTbhRAR5M/9urXxx7fEwYcRajUh99/Hq2++icPh8KhvcnIyew4dJKxLxaY7cAd9z9vY+Ntv7Nu3z6N+ZrOZ995/n5Be9/nMPMP1CGnSGGKimTdvnsd9X33zTUJ6dFN0R7A3UOv1hPS8jZdff93jvl999RX2KlUIbdFcecd8EG+MHIQQdwohDgghDhdsAr72/UeEEOeFENsLjhFF3hsmhDhUcAy7tq+HpAshKgGzgQxgK/lTAC7x7W+xjxFctw5WrZbVq1d71O/jqVMISkjwyXDStaiCgtDFxzH1s0896rds2TK0tWujreEbiwlcoU1K5OOpUz0KE2ZnZ7Nh/XqfWkxQEvp27UhLS+Po0aNu95FS8sGkSaiTErzomQ/h6TJWN0aLQgg18BlwF9AceFgIUZzSfiulbFNwzCnoWwV4DUgEEoDXCnIjlQop5ZNSyitSyhnA7cCwgvCSSwLi4AFCCNSJ8Xw4ebLbfc6fP89PP/6EPsE/bigAoe0T+XLRYgwGg9t9Ppg8GZUfXWNwg/rk2u1s3Fhiepn/YfrMmYS1a4OqAhMXeoJKG0RoXCyffv65231SUlI4e+lShe1nKG8kXhk5JACHpZRHpZRW4Bugl5su3QGslVJeKshFtxa4sxSXBoAQok9BniWklMeBk0KI3u70DYiDh+jbtiElJYVjx4651X72nDmEtW6FupyTo5UFTeXKhDRowOLFi91qv23bNo6dOOFXYQghBJqEeD6aMsWt9jabjc9nzCA4qfwTFpYFXVIic774ArPZ7Fb7j6dOQZuY4POhQUXxfM6hWuHG3YJj1DUWawOZRX7PKnjtWvoJIXYKIZYJIQrnAdzt6y6vSSmvFv5SkGfpNXc6/oM+Acqg0moJbduGb775xq32cxcuJCjOrd3qPoU6rh2z5s93q+2XixYRHNvOL8JmRdHHtWP92rVujZB+//13iAhHGxVVDp4pR9BN1QiOqsXatWtdtrXZbKxa+T2h8bHl4Jlfc6Fw427BUZpNUKuAelLK1uSPDhYo6+J/Ke4e71buk4A4lAJVnRg2/fWXy3ZGo5HMY8cIrlOnHLxSluB6ddmzc6dbuXp+37IFjY/tT3EHlU5HeO0otm/f7rJtWloaok7F1ogoLc7o2iSnpLhst2fPHkKrVfWZTX3lhRfCSqf43xVB0QWv/f8585f6Wwp+nQPEutvXQ9KFEJ8IIRoWHJ+QPzHtkoA4lILgmBi2bd3qst2OHTsIrx1VrknKlEKt16MNC+PQoUMltnM6nezdtdOrqZu9iSqqFhkZrr8rfyQno/KzUUMhmtq1+SMl2WW7jIwMNLX98+9YagTeyK2UBjQWQtQXQmiBh8jPGPH/py1ILVTA/UDh8sDVQE8hROWCieieBa+VlnGAlfzaOt8CFvLrPLgkIA6lQFOtKjlXr3Lx4sUS22VkZKAu95q4yqGrE+PyxnnkyBE0oXq/fdqUtWrxR7IbN86tW9H6qQAGx0Szc9t2lyuz/kpJwVHLP1abKYnSIwcppR0YS/5NfR+wREq5RwjxphCicHfyeCHEHiHEDmA88EhB30vAf8gXmDTgTXc2EJfgi0FK+UKRENiLUkq3VpoExKEUCJWKiHp1Xd44Nycn4/ThTW+usNeoQXJqaoltMjIyCPHTcAuANiaaNBd1yy9fvsyVixe9WmzKm6grVcLmcJCdnV1iuy2pqX47AiwTXtgEJ6X8WUrZRErZUEr5dsFr/5ZS/lDw84tSyhZSylsKkuHtL9L3Cyllo4LD8804gBBicsG/q4QQP1x7uGPD/+IdPoKoVInMzMwS2xw9cQJNS/9ZwXMt6iqVOXz8eIltMjMzcfj4hrCS0FSpyrnTJd80MzMzCa1WzW9X8AghCL2pGpmZmdQuYSR7+tQpwqtULUfPfAPpn39WV3xZ8K9b6bmLIyAOpURqNC4LAZlMJlRerCTnbYQ2yGXyNpPJhFPjX6uUiqLSBmE1W0psYzKZUCtYB7oiEEFBLj+vVosF4cef11LhnykxXCKlLAxrtJFS/s96bSHEBOA3VzZuTM0sB5xqlcsiQDarFfxseWdRhFqDxcU1WiwWpMp/rxG1GofdXmI83mq1ItT+/RwlNBqXn1e7zYbwY6EvLTd44r3i0m884k5H//7EVyAqh4Pg4OAS22iDg5EOezl5pDzSbkfn4hp1Oh3Cw1xTvoS029EEBZWYRC84OBin3X//jgDSZnf5eQ3SapF2O7hod8PhwwkUS4sQ4mFgINDgmjmGcMCtCe6AOJQSYXcQElJy3efQkBCk1VZOHimPtNkIdZGVMyQkBJU/C6DNRpCLm2FISAhOhUvFljfSZnP5edUGByOtVvCj3fxlpTB9xg3IX8BpoBr5pUELyQV2umMgIA6lxHnhIg1cVMdq2rgxh86fh5ublZNXyuI4f4HmrVqX2KZBgwaoL10uJ4+Ux3buPLXrlryBr169euSdP0+kw+F3u8AhP5le3pkz1K9fv8R2MXXrcu78BZ8rYOR1bkBxkFKeEEJkAWYppcv5heIIzDmUAulwkHPyJG3bti2xXYfERNRnzpaTV8qjOXuWxPj4EtvExsZiOJmpeFH78sKalUWSi2sMDw+nRq1a2M7659/SfvEiYWFhVK9ecl32WxMTsWZllZNXPoKH8w3+NMqQUjoAZ2HiPU8JiEMpsJ07R7Ua1Yl0UY0qNjYWe1ZZdr5XLMYTJ4mNLTnPTp06dRBOJ46rCtb0LUdUp8/QIdF1Mr24uDgsJ0teuuyrWE5m0qad6/xe7RMS0Pjxw0yp8cI+Bx8iD9glhJgrhJhaeLjTMSAOpcCSmUVsO9fJyVq2bEne2bM4LSUvlfRF7Dk5SLudevXqldhOCEGrW27BkuWfN07HqWyXAgjQKSkJTp8pB4+Ux5mdne+/C2JjY7Fk/sNGDty4I4cCVgCvAr+Tn1Op8HBJQBxKw4mTdO3QwWWz4OBgGt98MxYXG8l8EfORo7Rp186tUphdO3bEcexEOXilLI68PAznztGqVSuXbRMTE3EcO+6f4bMTJ0lyY3TUrFkzrLm52K9c8b5PvsQNPHKQUi4AlgDJUsoFhYc7fQPi4CFOk4m8HTsZOHCgW+2feOwx7GluCbVPIdO3MmbkSLfaPjJ0KKaMDJw2/1qZZUxLp1fv3ujcKN7Tvn17dIDluH+JoOVUNuTm0b17d5dt1Wo1Dz/8MMaUklOm3GjcyCMHIcR9wHbg14Lf27ibPiMgDh5iSM/g9p49qelmzqShQ4diPHAQ+9WrXvZMOaxnz2I7c4a+ffu61b5Jkya0uaUNxh1urZDzCaTTiSU5lWcmTHCrvUql4qlx47D52Y3TmpLCmNGj0biZGXjiuHGYU9KQfrx3xSM8HTX4mTgAr5Nfme4KgJRyO1DyMssCAuLgAVJKbCmpPOvmDQUgIiKCBx98EFOy/9xUzFtSGTVihMtNU0V5buJEHKlpXvRKWUz7DxBVvTrxLlYqFeXR4cMx7N6DIy/Pi54ph9NkIm/rdkaPurZQ2fVp1aoVTRo3xrhrtxc98y2kEB4dfoataCW4AlwXaSEgDh5hOnCQyqF6OnXq5FG/iePGYU5Nw+kHG+KcJhPGrVsZ88QTHvW79957ETm5WE6e9JJnymJPTuH5iRPdmlMppGrVqvTq3QvDFtcpvn2BvNQ0brv9dmrVquW6cRGenzgRe3KKf86vlIYbe+SwRwgxEFALIRoLIaaRv0HOJQFxcBOn1Yrp+1V8/O67Ht1QAFq3bk3XTp0wrHFdqrGiMfz4Mw8OGEBdFxvDrkWj0fDuf/6D8bvvfT4kYdi+A32ewe15o6K8+e/XMG/+C9v5C17wTDnsly9j2rCJt19/3eO+/fr1o6pKjSHd/+bKPKVwh/SNOudAfrGfFuQX+fkKuApMdKejb4mDGyUpKwrD6rV073Cr23H4a5k7cya2bdsx+/CEpnHfflTHTzDlk09K1X/EY4/Rqn4D8jZsUtYxBXHk5WH44Ue+XbzYrYnoa2ncuDGvvfIKhuUrkD76eZVSYlixkmefeorWrUve4V4cQUFBLFm8GONPv2C/4j9zZaXmxh45NJNSviyljC84XpFSmt3p6FPi4PTRjVTmo8dw7NzF7OkzSm2jevXqzJ4+HcPSZT4ZXnKaTBhWrGTx/PlElLI+gxCCxfPnY/7zL6wuCstUFIaVPzDikUdIcmPd//V4+qmnqBsegeFPt0bn5Y4hJZXqCF556aVS22jTpg0Txo7FsOI7nwwv2c6dV8bQjT8h/bEQYp8Q4j9CiJaedPQpccBiwbhnb0V78T84jEYMy5YzZ8YMqlWrViZbAwYMoFN8Ank//ayQd8ogpSRv5Q/0u+8+brvttjLZiomJ4eMPPsCwZJnPbf7LS89Af+ky7771VpnsqNVqvl20COO6DVh9bGOc7fwFDL+sZsnixQSVsTbDa6++SlW7A8NfvjXH4rTZyFuyTDF7N3JYSUrZDegGnAdmCiF2CSFecaevT4lDo4YNyVu6HPPRoxXtCgBOi4XceQsY3K9/qcNJ17Jw7lwiTp8mb/1GReyVFSkleT/9Qi2LlU+nTFHE5sgRI7ijQ0dyv1ycnwLaBzDu3Yfl519Z9d13LrOTukOTJk2Y/umnXJ07D5uLWuLlhf3KFa7OnssnH3zg1sY+V2i1WlatWIFt4yYMO3cp4GHZkQ4HeV99Q+dShMuuy409ckBKeUZKORUYTf6eh3+708/r4iCEOF6gVtuFECUW69Xr9az49ltyFi7GfOyYt10rEafZTM78hdyZ1J5pkycrZrdKlSr8sWEjmu07yPvtd8XslgYpJYY1a4k4mcmmdesICwtTxK4QgkXz55NQrz45i76q8M1xxv0HMCxZxq8//liqGPz1GDJ4MO+89hpXZ82tcIGwX77M1dlzefHpp3ncg6WrrmjatCnrV6/G9N33GHZX7PJWabeT+80SWlWtxtKvv1bO7g08chBC3CyEeF0IsQsoXKnkVqHw8ho5dJNStpFSxrlq2LNnT5Z9/TU5CxZh3LffVXOv4MjL4+rsL7g3MYkv581DpXDt4Nq1a5O8eTO6HbvI/XVNhUxsSqeTvO9XUeVkFlv++IOqVZWtHazRaPh++XI61G9A7rwFOM1uzYEpjmH7DozfLuWXVato37694vbHjR3L26++yuXPZ2I9fVpx++5gPXuOy9Nn8tKEibz4r38pbr9du3asX70ay3c/VNgKJqfFQs6CL2l30038smoVWq1WOeM39sjhC+AycIeUsquUcrqU8pw7HX0qrFTInXfeya+rVmFZ/h25P/xYroVWDLt3c3HSVB7r25cFX3yB2kv5++vUqUP6li3UOneenDlfYLvoVnEmRbCePcvVz2fSyOEkefNml6mcS4tWq+W7pUvp26kzFz+ZgungQa+cpzicZjO5y1YgV6/lt/Xr6dixo9fONW7MGGZMmcKVGbPJ++33chN76XSSu/lPLn8+g0lvv8O/nnvOa+eKj4/nr99/R/3bH+R8uxSHi9riSmI+cpRLk6ZyZ9t2/LTy+1KtMrsuHo4a/G3kIKVsL6WcIqX0eIVIeYiDBNYIITKEEH8b7wohRgkh0oUQ6efP//8KhI4dO3Jo3z46VK7C5UlTMR/1bpjJYTCS880S1GvW8dPy5Xz0wQce72fwlOrVq7M1JYWnBg3m0tRPyftzi1dXhkink7xNv3Hl85m8Nn48f27aRKVKlbx2PsifvJ09YwbfzpuHfcX35K74zuujCOP+A1z8eDJ3NmrMoX37XNbdUILBgwaxPT2dOqfPcnXGbOVW01wH28WLXJ09l1pHj5O+ZQsjRozw6vkAmjdvzsG9e+nT+hYufTzZ64tHnBYLud+vwvzNEhZOn87iBQvKPMleLDfgyEEIsUoIcZ8Q4m//YUKIBkKIN4UQj5Zow9vL1IQQtaWUp4QQ1YG1wDgpZbHB9ri4OJme/vdpiRUrVvDY44+jvrkZIZ06ElT9JsX8c1osGNK3YtqwkUEPPMAnH36IvgLKJO7Zs4cHBw/mtMWCtlsXdI0bKSZO0unEtP8A1g2baFS9Ol8vXEjDhg0Vse0JV65c4cnx41m1ejW6Ht3Qt22LSqvcl92afRrzH5tRHT/Bl/Pmcccddyhm212cTidTpk3j1ddeQ3drEqFJSWgiS7c0uDgcubkYklMxbf6TV158keeffdZro9uS2LhxIwOHDcVWqxbBnTsRHF1bMdvSbsewfQeW9Rvp0akjsz+fXmzYUwiR4U6ouiRCa8TIxg8/7VGfnVOeLvN5vY0QoibwNNCP/JrR5wEdUA84Anwqpfy+RBvluYZZCPE6kCel/Ki4968nDgAXLlzg3fffZ87cuQTVjkKdEE9oi+alLttoPXMGS3IKhoxtdOrcmX+/+CId3EjD7U3sdjtz5szh/UmTuGw0oEmIRx8Xhzq0dKtrHHl5GNPSsSanUuumm3jx2WcZMmSI4nMonrJ+/XrefPdd0tPTCY2LRZeUSNBNpVsmLO12DDt34UxNw3nxEk+OHs1zzzzjshCTtzly5Aj/efddlixZgr5ZUzSJCegaNiiV4EspsRw7ji0lFcOevfTp25d/v/QSTZs29YLn7pOXl8cnkyYxbfrnOMPD87+Tt7RGVcqne9vFS5hTUjCmptPmllt49YUXuPPOO6/bXilxaDTQM3HYNdm1OAgh7gSmAGpgjpTyvWvefxoYAdjJv3E/KqU8UfCeAyhcHnZSSnm/Rw7+3Zd6QC3ABByUUroVE/SqOAgh9IBKSplb8PNa4E0p5a/FtS9JHAqxWCwsW7aMDyZP5uixY4Q2boS9Rg20MdEER9dGVUw8Ujoc2M6dyy9kkn0aeeoUjstXGD1qJE+OfoKYmBgFrlY5pJT88ccffDxlCmvXrCG8UUPsNWsSFF0bbUw0mmJufFJKHFeuYMnMwn7qFOozZ8k9cpT777+fZyZMID4+3uthMk85cuQI0z7/nC/mzSO4+k3I2lGooqLQxkQTdNNNiGJEzGE0Yc3KwpqZiebsOQyHDtO8eXOenziRXr16eSfsUAauXr3KggUL+HjqVK6aTWjr1cNZqybBMTEERdUq9kYq7Xas2aexZGYhTp/GfuIEoSo1T48fz/BHHqFKlSoVcCXXx26389NPP/Hh5Mls276dsMaNsNeojjYmGm10DGp96N/6SKcT+4WLWDIzcWafRmRnYz59hmFDhzJ+zBiaNGni8ryKicMgD8VhUsniIIRQAweB24EsIA14WEq5t0ibbkCKlNIohHgC6CqlfLDgvTwppTJLB8uAt8WhAfBdwa8a4Csp5dvXa++OOBRl//79bNmyhb9SUtiSmsqhffsIDg9HExyMKigIp8OB02bDdOUKVatXJ7ZdOzq3b09cXBwdOnRQdsWDlzh79iybN28mJS2NzcnJ7NqxAyeg1ev/e2NxWq1Y8vII0mho3bYNnRKTSExIoGPHjoqvQvIGJpOJzZs3k56ezh/JyWzdupUrly6hi4xErdUiVAKnzY7dbMZqMNC0ZQtuTUikfUICt956K40aNaroS3CJlJKMjAxSU1PZnJJMalo6J48eJbRyZVTaIFRqDU6HHYfVhunyZaLr1SMhLo6OSUnEx8cTHx9f4SM+dzh27Bh//fUXW1JS+DM1hX27dhMUEoImRIc6KAjplDhsNsxXrxIRGUnbdu3onJREXFwcnTp1IjT070JyPZQQh5BSiMNu1+LQHnhdSnlHwe8vAkgp371O+7bkh3k6FPx+44uDp3gqDtdit9vJzMzEaDRiNpsJCgoiJCSE6tVd13v2F6SUZGdnk5ubi8lkQgiBTqcjMjKSmjVr+tzooLRcunSJCxcuYDabsdvt6HQ6QkNDiYmJqZAYuzcwmUycOnUKs9mMxWIhODgYnU5HVFSURzdJX8bhcJCVlYXBYMBsNqNWqwkJCaFq1aplfnBRRBxqlkIcPnn6BFA08+IsKeWsIn71B+6UUo4o+H0IkCilHFucPSHEp8AZKeVbBb/byd+sZgfek1Ku9MhBhXCvAoifoNFoqF+/fkW74VWEENSurdzkn69SpUoVnwufKE1ISIhfjHrKglqt9jjDb7nj+fPUBaUmpIUQg4E4oEuRl+sWLOJpAGwQQuySUh4ppf0JUsoprl4rDt8fpwYIECCAF/HCPodTQNGJzOiC1/4HIcRtwMvA/VLK/yYik1KeKvj3KLAJKMta7GHFvPaIOx1vqJFDgAABAniM8pHYNKCxEKI++aLwEPA/xUMK5hlmkh9+Olfk9cqAUUppEUJUAzoAH3jqgBDi4YJz1r+mZnQ4+UtbXRIQhwABAvyjUXrXs5TSLoQYC6wmfynrF1LKPUKIN4F0KeUPwIdAGLC0YJ6wcMnqzeRnT3WSH9l5r+gqJw/4CzgNVAM+LvJ6LuBWsfeAOAQIEOCfi5d2PUspfwZ+vua1fxf5udjc+FLKv4Ayp9Qt2DNxAih1QrHAnEOAAAH+2dyA6TMKEUL0FUIcEkJcFULkCCFyhRBuVVW7IUcOTqcTi8WCRqPxuU1RSiGlxGKxIIRAq9XeMEtY/4k4HA6sVitarfaGWaZ7LYXfSbVaTVBQkE99Xv0tmZ6HfADcJ6Xc52lHvxYHk8nEjh07yMjIYHNyMilpaWQeO4bDZkNdsAkOoFK1qtzSpi2dkpJIiI8nNjaWmjVrVrD37uFwODhw4AAZGRlsSU3lr5QUDu7bi9lgRKXJ//M57XZCwsJo1qIFHZKSSIqPJy4ujkaNGvnFxqniuHDhAidOnMBsNv/3xqnT6ahbt26ZK/JVFFevXmXr1q1kZGTw+5YtZGzN4GzWKZwOB+qgIBw2G0Klonrt2rQrsjksNjbW6wkSlcJqtbJ7927S09P5MyWF5LRUjh86jM1i+e93UkpJeKVKtLylNZ2T2v/3OxkTE1MxonFji8PZ0ggD+OkmuK1bt/LJ1KksX7aM0BrVUdeujbNmTYJjogmqWQNR5MlEOhzYr1zBWpBWQnPmLDnHT9C0WTOenziRfv36ERwc7O1L85js7Gymz5zJ5zNm4FCrCY6Jxl6zBtroaLS1a6MK0f03vYR0OnEajVhPncKamYXm7DnMJ04SEhTE+DFjGDliBDfdpFyyQqWx2+1s3LiR1JQUMn77jYxt27iSm0sDnY5QIdACVsAoJUfNZiqFhxPbti2xXbqQkJhIt27d0Gh88zlHSsn69ev5aMoUNm3YQHhMDNSqCVG18lNo3FQN1GqEEPkZeR0ObBcuYs3Kwpmdjcg+Q+7Jk3To3JnnJkygZ8+ePin4Bw4cYMqn01j45SKCK0Wirl0bR80aBMdEo61VC6HV/v/n1eHAkZuLJSsLe9YpNGfOkXf8OFG1avHshAkMGjTIrcJTimyCqxUj6z/m2Sa4fW/7ReK9wtKVXYCawEqg6HLZFS5t+Is42Gw2vv76az6YPJmTWVkEJyYQmhiPOjzc4/NIhwPjnr04UlKxnT7DqBEjmDBuHNHRbhVI8iq///4773/yCRvWryesXRuCk5LQRtUqlS3LyUysyank7dzJPffcw/NPP01CQoLCHpee7Oxs5syYwaxPPyXa4aCj0Uis3U4c0JDiJ8Sc5KeUTAcyNBo2h4aSpVYzauxYRj7xBLVqle7/Smlyc3OZM3cun0ydSp7TgSYhAX1cO1SleBBxWq0Ytm7DkZJGsN3OU+PGMWrkyAofTTidTr7//ns+mDSJXbt3ExIfhy4pgaBSbF6UTiemg4dwpKRhPHKEIYMH8czEp2jcuPF1+ygiDlExsp6H4rD/Lb8Qh3klvC2llCWm6wY/EYcdO3bwwKBBXHA40HRsT2jz5sUmZSsN1rNnMW9JxbxtG++//TZPPPFEhTyZXbp0iVFPPsmaTZsI7tQBfVxssUkES4PDYMSQloZl81/079WLqZMmEV4KUVWK7du38/ZLL7F+40YeBJ4wmylL8c6dwHSdjm+k5Lbu3Xn5nXdo06aNMs6WgjVr1jB4+HCcUbXQ3ppEcP36ioRLpJRYTpzEtiUZefwE8+fM4d5771XAY885duwYDw0ZwsHsbII63or+ltYIhUZv9suXMSWnYkpO4blnnuGlF14odu5QMXEY4aE4/Mf3xUEJfFocbDYb/3n7LT6ePAX93XehT4jzWkzSeuYMhqUraBYVxdcLF1KvXj2vnKc4vv/+e4aPHIm6ZQv0d/Ys1dOlOzhNJgw//ozq+AkWz5/PbbcVu5rOa1itVt5+/XWmT57MK2Yzj0iJcpUOIAeYLwRv6XQ8MXEiL7/+erkmV8zJyWHsxIl89+OP6Pv1IbSZ91Jqmw4dxrBsBXf16MGMTz+lcuXKXjtXUZxOJ59+/jkvvfIKod26oO/cSbEHtWuxX76MYfl3VBcqlixeTKtW/7vCUwlx0EXFyHojPROHA2/6jzgIIaYW8/JV8vdblFjPwfeClwUcPXqUVu3a8dmKFVR9ajxhid5NOa2tWZNKTz7O4cqRtGzThgULFnjtXIWYzWYeHDSQIaNHE/zQAMJ73ec1YQBQhYQQPqAf4t676TNwICNHj8Zut3vtfEXZvn07CS1asHXKFLabTIxXWBgAIoDxUrLdZCJjyhQSWrRg+/btCp+leLZs2UKjm2/ml0MHqfrMRK8KA0BI40ZUeXoCG7KzaHzzzWzatMmr5wM4f/48t3bpwutTplDpyccJ69rFa8IAoKlcmYjHhnOxxc0kderE+x9+6J1KiTfwUlbyC/y0AQ4VHK3JT+fxmBBickkdfVIc9uzZQ8Ktt3KpaWMiHn0ETTnFVoVaTXj3blQaPYqxzz/PBx9+6LVz5ebm0r1nT9YfPEiVp8YTUo6V2UJvbkbVpyew4q+/uKd3L8xeLtv56ZQp9Lz1Vp4+fJgfjEaivHo2iAJWGY08dfgwPW+9lc+mFvfwpByrV6/m9rvvRnXPXYT376tYONAVquBgwnv3IqhvL+7t04cffvjBdadSkpmZSVz7JI6EhhD55ONoa9Tw2rmKIoQgLCmRqhPH8e60aUx4+mnlBeLGFofWQDcp5TQp5TTgNqAZ0AfoWVJHnxOH3bt306FLF9Q9byOsU8cKWdqmrVWTyk+M4u3Jk3nrnXcUt5+Xl0fnHj04JJ2ED3zIq6OF66EKCSFi2GAyzp6l5913Y7FYXHfyECklb776KlNeeokUk4mhlN93S5CfcSzFZGLSiy/y5quveuWp85dffqHfQw8RMXQwoS2aK27fHUKaNiXy0UcY+MgjLF++XHH7WVlZJNx6K6ZWrQi/+06vjhauh6ZyZSJHj+LLH1cx6oknlPtbeph0zw/3RFQmP01HIXqgipTSQZHVS8XhU+JgsVjoetttBN9zF/rYdhXqi6ZyZSIfH8EH06by6WefKWbXYrFw1333kRmkIaxfnwr5ohUiNBrCH36QPVev0PfBBxUPMf3n3/9m6Sef8IfRSEUlUq8P/GE0suSTT3jrtdcUtf3HH38wYOBAIoYNQdegYlPFB9eJIfLRRxg2YgRr165VzO758+fp2LUrjrh2hHXtrJjd0qDWhxL52HCWrVnNv156STnDN/bI4QNguxBinhBiPrAN+LCgMue6kjr6lDgcOnwYVcdb0bcrS4Za5dBERhI54jFeePVVtmzZoojNp597lr1XLhPer49P7BIVajURAx9iy8ED/OfttxSz++mUKXz5ySesNRqp6O2GtYB1RiMLPv5YsRDTuXPnuK9PH8IeegBd/XqK2CwrwTHRRAwZRL8HHiArK6vM9qSU9HvwQQz16xHWtYvrDuWAKiSEiMeGM2P+/Ip2xS+QUs4FbiV/n8N3QEcp5RwppUFK+VxJfX1KHOxCoO/YoaLd+B+CqlVF3+s+Hho8GJPJVCZbmzdvZsHirwjr3xfhQ2kShEZD2IMD+GjSZHbudCthY4ls27aNN198kTU+IAyF1ATWGo288cILikxSPzpqFEFt23h94tlTdA0bEHxrEoOHDy9z6GX2nDnsOn6MsLvuUMg7ZVCHhRH2YH/F7N2IYSUhRLOCf9uR/3yUWXDULHjNJT4lDqpKlXziafpa9G1uwVClCi+8/HKpbRiNRh4aPBh97/tRu7H7s7zRVKqE/u47eWDQIGw2W6ntWK1WHhkwgI9MpgoLJV2P+sCHJhOPDBiA1WottZ0lS5bwR3o6+jtuV845BQnr0Z0dhw/xxbyS9kGVzMmTJ3nm+efRD+jvUw8yheiUrPh4Y4aVCtfnflzM8ZE7BnxKHITG9z6Eheh738fcBQtKHV56/sUXMNeojr51mbPxeg19QjznBbz1ztultvH2669T5/Rphijol5IMBaKzs3nnjTdK1f/cuXOMevJJ9AP6ofLRpI5CrSZ0QH8mPvNMqcJLUkoGP/IIuo63lnp3vl9xA4qDlHJUwb/dijm6u2PDp8TBl1GHhRF6952MmTjR474nTpzgi/kL0N9fMbtZ3UUIgb5vbz786GMuXrzocf/t27czffJkZhqNPvsdEsAso5HPJ00qVXjpP++8g6ZVS3T1fLsucnDtKIIT4nj19dc97rt27Vp2HT5MWLeuSrsVoJwRQoQKIV4RQswq+L2xEMKtG1FAHDxA37YNB48cYdeuXR71+2z6dPSx7XwynHQtmsqV0bdqydwvvvC479svvcQrZrPX9zGUlSjgZbOZdzwMExqNRuYvWEBIJ9+aF7seoR06sGTpUq5evepRvw+nTEFza5JPhpMU58ZfyjqP/LyVtxb8fgpwa+VJQBw8QKjV6BLimeTBiheLxcLM2bMJTkr0omfKEpSYwKRp03A6nW73yc7OZt2GDTziQ+lYSuIRKVm7fj2nT592u88333yDrm5dgqpW9aJnyqGJjEDftAkLFy50u8/Jkyf5c/Nmn1kxWC7cgGGlIjSUUn4A2ACklEbcvIqAOHhIaFIC3377LTk5bhVTYvny5Whr1UJbo7qXPVOO4Lp1sARpWLNmjdt95syYwUOgeEoMbxEJPCgEc2bMcKu9lJIPJk9CnRjvXccURp2YwEdTp7q9cunTzz9HH1u67LH+yg0+crAKIUIACSCEaIiLzW+FBMTBQzSRkYQ2bcK3337rVvsp06ejio/1slfKIoRAHR/HlM8/d6u9zWZj1qef8oQXdll7kyfMZmZOm+bW5r+dO3eSffYcIT62dNUVuoYNyDGb3VpIIaVk9ty5BCf6Tlr3cuHGHjm8BvwKxAghFgPrgefd6RgQh1Ig69dnw++/u2zncDjYkZGBrkmTcvBKWXRNmpCSkuJW202bNhHtcJQp7XZFcAtQ2253K2ndX3/9ha5xowrd0V4ahBBoGjXkr7/+ctn22LFj2AFtzfLJm+QzCOnZ4UdIKdcCfYFHgK+BOCnlJnf6+tcn3UcIjokmJS3NZbv9+/ejq1QJdWhIOXilLJoqlTGbTW7F5FNTUuhoNJaDV8rT0WQi1Q0R3JySjLOWr2zp85CoWvzuxsghIyOD0Dox5eCQ7+BpSMkPw0qQn5n1MvlZ7ZsLIdzKgxIQh1KgjapF1vHjLndMZ2RkEBxT8dXlSoMQgvC6dcnIyHDZNuO334gtp9TfShNrt5Px228u26WkpaP1gUqBpSE4JpqMra7/jilpqdj9aG5MMW7gsJIQ4n3gT+Bl4LmC41l3+npdHIQQdwohDgghDgshXvD2+coDodEQUbs2O3bsKLHdltRU7H48RHfUrEmaGzW9M7Ztwy8qnxRDHPn+l4TZbObkkSNoo3x9kW7xBFWvzoWz51wuad2cnEJQzD9r5AB4RRxc3feEEMFCiG8L3k8RQtQr8t6LBa8fEEKUNXdJb6CplPIeKeV9Bcf97nT0qjgIIdTAZ8BdQHPgYSFExeQ1Vhh1jRrs37+/xDY79+whqJzy3nsDVY3qbHWxp+PChQtczc2l/KpRKEsj4HJODhcuXLhum6NHj6KvVg2V1jd3RLtCqNWE16rFwYMHS2x3+OBBv/68lhalw0pu3vceAy5LKRsBk4D3C/o2Bx4CWgB3Ap8X2CstR4FSfXCVKfp6fRKAw1LKowBCiG+AXsBeL5/X60itxmVYyWA0Ivx4SaDQajFeuFRimxMnTlBfp0NVhlxFFYkKaKDTceLECapVq1ZsG6PRiFrnv39HyC8M5Orzajab0QeXX1lVn0H5UJE7971ewOsFPy8DPhX5ieV6Ad9IKS3AMSHE4QJ7HuXtEUJMI3/5qpH8lN3rKbKEVUo53pUNb4tDbfIzARaSBfjPbrAScKrVLr9sFrNZsaLrFYEICsLoxg0l1AeTJXpCiBAlFjsym82o/PjvCCCCXD/M2K1Wv/68lgrvzCO4c9/7bxsppV0IcRWoWvB68jV9a5fCh8J4cAZQqhKBFf5JEEKMAkYBqMupSLoSqJySIBeJ19QaDXiwy9jncDrRurhGq9WKvz9raqFEcdBoNEinfy1h/BsOp8vPq0qt9v/rLA2eL0+tJoQoOhk3S0o5S0GPyoyUckFZbXhbHE4BRWe4ogte+y8F/6mzAILrxPjNJ1PY7YSElLxENSQkBFmG9NcVjbTZCHGxDFer1eKfAaX/xwoElxD+CwkJwWnz76t02mwuP6/a4OCCz6v/Lb0uC6VYnnpBSlnSGgyX970ibbKEEBryN+1fdLNvueDt1UppQGMhRH0hhJb8iRbvVUEvT3JzqV695GV/tWrUwO5h0jNfwn7lKtG1Sk7ZrNPpMPpJPqXrYZKyRHGoUaMGpkuXvFKDurywXL7s8vNa9aabcPjx59WHcOe+9wP5Zc4B+gMbZP4H7AfgoYLVTPWBxkBqOfn9P3hVHKSUdmAssBrYByyRUu7x5jnLAykleSdOEhtbclqMTklJkO1+YjdfQ3P2LLcmlDxFVLduXY6azfhr8MwJHDWbqVv3+im4a9asiS5Yh/3S5fJzTEEceXk4zGYaNGhQYru42FgsmWUvL+p3KLyU9Xr3PSHEm0KIwmWkc4GqBRPOTwMvFPTdAywhf/L6V2CMlNJRqssSQi2EcKuwT3F4fc5BSvkz8LO3z1OeOK5cIUitJsrFuve4uDiYO7ecvFIeW9YplwJYrVo1KoWHc+TiRRqXk19KchioHBFx3ZVKhdzSti17s7IIqlqlfBxTEEtmFi1at3ZZZbFTUhIbl7iXM+xGwhu7nou770kp/13kZzMw4Dp93wZKX3Hr/+04hBAdS9s/sEO6FFgys2jdto3LL1u7du3IOXkS6SiV8FcoTrMZw/nzNG/ueltKbNu2uN4q55ukk++/KzolJWEvRVU1X8CWmUXHRNeLBGNjY3GcqpDwdsUhuKFzKwHbhBA/CCGGCCH6Fh7udAyIQymwZ2bSKTHJZbvIyEiq1aiB9fSZcvBKWSyZWTRs2tTlCheA2C5dyPDTJZAZQUHEdunisl1CfDxqPw0Rqk+fJjHBdabVW265hdxT2Tj9LLtumbmB02eQn1fpItAduK/gCFSC8wbS4cC6bQcD+vd3q/1D/ftj2VpyegZfxL5tO0MeesittgmJiWwODfWyR95hs05HghtP1d26dcOYdQrbxZI3Bfoa9pwc8g4f4Y47XGdhCA0NpWPXrhi2bfe+Y77EDSwOUsrhxRyPutM3IA4eYtyzlwb16tGmTRu32o998kmM6Rk4/WgHscNgwLBrFyNHjHCrfbdu3chSq9npZb+UZgeQHRRE165dXbbV6/UMHTIEk5tpzH0FU2oa/fv3p1KlSm61f27CBBypaX69MstjbmBxEEI0EUKsF0LsLvi9tRDiFXf6BsTBQ5yp6Tw/caLb7evXr09iYqJfPY0Z09K55957XU7SFqLRaBg1dizT/SxVyHSdjlFjx6JxMyQ2YexYzGkZSD/JQCudTswpaTw93mWmhP9yxx13oLXasJ7MdN34hsDD+Qb/m3OYDbzI/5cJ3Un+0lqXBMTBA2znzmPNzqa/myGlQp6bOBFHin88jUmnE2tKKs+Mn+BRvxGjR/MN+Qnj/YGrwLdSMmL0aLf7NG3alFYtW2LY4R9jJOOevdSvU8ftUS6ASqXiqXHjsCb71wip1Hg6avCzkQMQKqW8dp+EW083AXFwEyklxp9+5qkJ40vcMFUcd9xxB1W0WgwZW73knXIY/vyLRnXqkuhGHL4oUVFR3Na9O/P9JM/SfCG4vUcParnY5Hctr7/8Mua163x+0tZps2H+dQ2vv/SSx31HPPYY1gMHsfxDRg83eLGfCwV1owtrSPcH3FpZ4Vvi4MMP1oa0DKpYbbz0wose91Wr1Xzz5ZcYfvwZ+1Xffba2XbiAYd0GvlqwwOUy3eJ4+Z13eEunI9sLvinJKeBtnY6X33nH47533HEHd3XvjuHnX5V3TEEMa9bRMTaWPn36eNy3atWqfD51Koaly/0mhFYmbuyw0hhgJtBMCHEKmAi4NVz2KXFwGvIq2oVisV+9ivHnX1iyeDFabenSzMXFxTHm8ccxfve9T4aXpNOJYekK/v3yyzRt2rRUNtq0acMTEycyKjTUZ3VeAo+HhvLkU09xyy23lMrGjE8/Q+4/gOnQYWWdUwjz8RPYtm5j3uzZpRJ5gIEDB5LYuhWGtesV9k4ZnGazcsZu7LBSZSnlbcBNQDMpZUeglTsdfUsccnKxXbhY0W78D1JKDCtWMn7MGNq6sVmqJP7zxhtEmkwY0l2XbCxvDH/+Rd2ICJ59+uky2Xn59dfJioriS4X8UpqFQpAVFcVLr71WahuVK1dm/pw5GJatUPYmpQBOqw3jsuXM+vxzl7mUSkIIwYI5c7GkpWM5cVJBD5XB8JNySReE8OzwM2YLIVpKKQ1SylwhxEPAq+509ClxqB0VRc68+ThycyvaFaAgh9Kqn6gTpOX1f//bdQcXBAcHs+zrrzH9/Cumw0cU8FAZjHv2Yt30O0sWL0atLkvRqfwsrfOXLuXZkBCOKeSfUhwDntPpmL90aalHgIXce++99L//fnIXLsbpI5l3pcNB7uKvuKNzZwYMKDYzg0fUrFmTebNnc3XhImznr18pr7zJ++13Qk8ptCHxxt8h3R9YKIRoJoQYSX6Yqac7HX1KHKpXr86Twx4hZ+48HAZDhfoipSRvzVoqnT7DhjVrynwzKaRt27asXLqU3EVfYT5+QhGbZcF08CCGZStY8/PPNG6sTHakNm3a8O9336VnaCi+sjf8NHB7aCivvfeeR6t3SmL29Ol0aNqUvK++qfDYvHQ4yP1mCe1qRbFofunmjIqjb9++fPjWW1yd8wW2SxW/ATBvSzIiNZ3NmzYpZ/QGDisVVKN7CFgB9AN6SindSr3rU+IA8M5bbzG8/wCuTJ+F/Ypb16A4hSOGSsdOsHnjRiorXISoR48eLFm8mJz5CzG5qOvrTQw7d2H4egk/rVxJghvpFTxh7IQJDHn6aW7zAYEoFIZhzzzDGA/W/LtCrVaz7JtvSIiOIWf+wgpbweS02cj5cjGtK1XmhxUr3Ep54glPjB7Nmy++yJXpM7GePauobU/I2/Qbqs1/8eemTcTExLju4C43oDgIIXYJIXYKIXaSX4a0ClAfSCl4zSU+lxBHCMEnH35IlcqVeX/SJPT9+hB6c7NyO7/9ag7G71YSrdaw8a+/FBeGQu6++25+WrmS+/r0wd6pA2FdOiPKGNJxF2m3k7duA/b0DDauXesy82ppefXNNxFC0PHjj1lrNFLfK2cpmWP8vzC88sYbitvXarX8sGIFQ4YP55fPZ6Af0J/g6NJUdSwd1tNnMCxdTtd2bfl28VeKjXCvZeKECURGRjLuqafQ33cPoe3aKjY6cYXDaML440/oz53jjy1blBUGwKeXSZYet/InlYTPjRwKeeWll/ju66+RP/5M7tLlOF3Uvy0rUkry0jO4OGkKI+66m5Q///SaMBTSpUsXdmRk0PDSFa5On4n1jPefyiyZWVye+hm3SNizY4fXhAHyhf7VN99k4jvvkBgSwgLK72sogQVAYkgIT7377n+FyhtoNBq+WriQSa+/Qe7ceeStWev1MJN0OMhdv4ErM2bxzrPPsmJJ2edRXDH8kUfYtHYt+pQ0chcuwp7j/WXZxr37uPTJZO5v0ZJdW7d5QRi4IUcOUsoTUsoTQC3gUpHfLwM13bEhfGlZZVxcnExP/9/kzzk5OYx/6imWr/qB0PvuJbRlC4RKWU2zXbiI6cefiTSZWLJ4sVdvmMXhdDr5fPp0Xnj5ZUI6d0Lf8VZUCqeicJpMGH77HUtKGp9OnsyQIUPK7ckPYPv27TwyYADR2dnMMhopuRJG2ThF/nLVrKgo5i9dqtgcg1vnPnWKIcOHs/XgQUJ7309wvbqK/z9bTmZi/P4HmkfH8NWCBSUWKvIGFouFV157jekzZxJ6953oY9spPuq1X72KafVa1Ccz+WrBArp37/63NkKIDBflOl0S3CBaRr05xqM+x4e8VObzlhdCiG1Au4IqcwghVEC6lLKdq74+O3IoJCIigvlz57Ji8VdEpqRy6cOPyd34W5knrKXTiXHPXnK/WMCVTz/n8XvvZa+Xn6Svh0qlYuyYMezato1YCefefo/c71cpEt+1nMomd/l3nH37PTqERbB/926GDh1arsIA+ZPUqXv2EDdxIm1CQpgqhOKpNq4CU4SgbUgIcRMnkrpnT7kKA0Dt2rVZv3o1k994A+fy78iZ9jm5ySllTrzotNnITU3n6mfTsX79Le8++xybN24sd2GA/FV3H773HpvWriXm6DEuvPM+uavXlrkkrpQS06HD5C76mgsfTWJAu1gO7d1brDAoyg04ciiCkEVGAFJKJ25OJ/j8yKEoUkpSUlL4eOoUflz1I2EtW0CDBgTHRBNUo7rLEYU9JwdrZha2k5nYtm0nplYtnps4kQcffNBl8fXy5OTJk3w2fTozZ88mqGYNnE2bEBwTg7Z2FCoXoQOnxYI16xSWzCzEvn1w5SpjnniC0aNGeZwqwlts376dd15+mXUbNvAA8KTZTOsy2NtBfhK9b6Xk9h49eOntt8tdFIrD4XCwevVqPpwymZTkFELbtkFVry7BMdFoqlYtUaCllNgvXcaamYnjxElM27bTrm1bnps4kXvuuafMS46VZNeuXUyeNo1vvvmG0KZNoGEDtDHRaGvWRLhIaugwGLBmZWE9mYlzxy4iQ0J4dvx4hg4dSkRERIl9lRk51Ja13/Js5HBs0Mv+NHJYAWwCphe89CTQTUrZ22VffxKHopw/f57Fixez/vffydiawcVz54ioUxdxUzWcQUFItRrhdKJyOBA5ORhPZiJtNlrecgsdkxJ5cMADxMfHe/mKyobFYuG7777j5zVrSE5L4/ihQ4TVrEFQVBTO4GCcajUIUNntqMwWbKeyyTt3jobNmnJrQiL33nUX9913n9tZR8ub06dPM2fGDGZOm0Ztu52OJhNxdjuxQCOKH9Y6yS/tmQ5kaDRsDgnhlEbD4+PGMWL0aJ8RwGs5duwYixYvZtOff7J92zaMBgPh9epClSo4NRqkSoVwOlDZHXD5MnknTqAL1nFL27Z0ufVWBg8aRKNGjSr6MkokJyeHb775hjUbN5KalsaZrCwiYqJR1aiBM0iL1KjAKVE7HAijEfPJTKx5edzcsiUdEhPp16cPXbp0cXtUq5g4vO2hOAz0K3GoDkwlv9iPBNYDE6WU51z29VdxuJYrV66wdetWDh48iNFoxGw2ExQUREhICDVq1CA2Npb69euXezhFSSwWC7t27WLnzp3k5uZiMpkQQqDT6YiMjKRNmza0aNFC8aWM3sZut7Np0yZSU1LI+O03MrZt43JODg10OkKEQAtYAZOUHDWbqRwRQWzbtsR26UJCYiJdu3b1WQG8HmfPniUjI4Njx45hNpuxWCwEBwej0+moU6cOcXFxPit07pKXl8f27dvZu3cvBoMBs9mMWq0mJCSEqlWr0q5dO5o0aYKqlHOISolD9DueicPRh/1HHMrCDSMOAW4sLly4wIkTJ7BYLP+9cQYHB1O3bl2360wEuLFRRBwa1pbR7zzpUZ+jD73iN+IghNABjwEtyC8ZCoA71eD863ErwD+GatWqBUQggNcRgPC/lBie8CWwH7gDeBMYBOxzp6PPr1YKECBAAG9ygyfeaySlfBUwSCkXAPcAbhVrCYwcAgQI8I/mBh85FGaFvCKEaAmcAdxK1xsYOQQIEOCfTTnucxBCVBFCrBVCHCr4929pGIQQbYQQW4QQewryIz1Y5L35QohjQojtBUcbF6ecVXCOV4AfgL3A++74Ghg5BAgQ4J+LKPeRwwvAeinle0KIFwp+/9c1bYzAUCnlISFEFJAhhFgtpbxS8P5zUsplrk5UsBs6R0p5GfgdaOCJo4GRQ4AAAf7RlPMG6V7kp/2i4N/e1zaQUh6UUh4q+DkbOEd+JTePKNgN/XxpHfX7kYOUkiNHjpCRkUFyaio7CtZUWywWNBoNoSEhREdF0SExkdjYWG655Raf2g3tLufOnSMjI4O09HSSMzK4evUqxoJ9DiE6HVUqV6Z9XBxxcXHExsZStWrVinbZYwwGA9u3bycjI4PNKSlknzmD2WzGbrej0+kIC9PTtmUrEuPjiY2NpV69en63b8Vut7Nv3z4yMjLYkprCgcNHMJpMWK1WtFotITodjRs24NaE/M9r8+bN/W7fipSSkydPkpGRQUpaGtt27SInN/d/9jnUrF6djgXfybZt2xIWFlYhvgpkaUYO1YQQRdfcz5JSznKzbw0pZWGlojNAjRL9EyIB0AJFq4O9LYT4N/kb2l6QUpaUK36dEOJZ4FvgvzmHpJQui3P45T4Hm83GypUrmTpjBhmpqWhCQwmpE4O9RnU0NWogtNr8bftOB9Jmx37lCqrTZ3BmZ5NzKpuY+vUZ/NBDPpVS4loKU4VMmjaN9RvWY8jL31HrrFkTVa2aqEJD/5uaQNpsOI1GnNmnUZ05Q86Jk0RWqsQdPXvy9PjxPpFK4noUpgr5dvlysk+ezN9RGxWFs1ZNNBERiKAgUKmQdjvSYsF+5iyaM2cxnjyJtNtJTEpiwpNP+lxKiaLk5eWxaNEipn/xBQd27yakShW00bWx16yJ5qaqqIK0oFGD3YG02bBduIjm7FmsmVkYL1ygSYvmPP7IcLdSSlQUTqeT1atXM+mzT0n+awtOIdDXqYO9ZnU0NWsigoPz/5ZOJ9Jux5GTA6fPQPZprmZmUjMqiv59+jBuzBjq13cvubsS+xxCGkXJ+h+N8qjPvj5vlHheIcQ6is98+jKwQEpZqUjby1LKYtM/CyFqkZ/6YpiUMrnIa2fIF4xZwBEp5Zsl+FJcQUYppXQZYvKaOAghXgdGAucLXnpJSlli4VdX4pCVlcX0mTOZPnMmqmpVUcXHEdKkMWoPnjqk3Y4lMwv7tm3kbt3ObbffzrMTJtC5c2efeAo1Go189dVXfDh5MmcuXkSbmICuVQuXuXiKIp1ObOcvYNm1C3NKGvXr1OH5iRPp378/Op3OtQEv43Q6WbduHR9OmcKfmzejj22Htm0btFG1XObiKYo9JwfT/oM409JQGwyMf3IMo0aOLFPtZCXZt28fk6ZOZfFXXxHauBHq2HboGtRH5cHfwGk2Yz5+Akf6VgwHDvDggw/y9PjxtGrlVo14r3PhwgXmfvEFk6ZNw6oNQp0QT8jNzdBERrptQzocWE+fxrptO4a0DBITE3lu4kTuuOOOEgVfKXFo8LFn4rC3d8niUBJCiANAVynl6cKbv5SyaTHtIsgXhneuN78ghOgKPCulvG7tBiGETkppdvVasX29LA55UsqP3O1zPXEwmUw8/9JLzJ07F327tgQnJaKt5VZK8hJxmkwY0jOwpaRSp3oNvvnyS5o3b15mu6VBSsmXX37JuKcmoq1TF3ViPCFNm5Q5Pbl0ODDu3YczNQ3HmbPMnTmTPn36KOS152zdupWHhgzhgtGAOjEBfbu2iqQnt2RmYk1JxbBjF09NmMBrr77q9foG1+PChQuMGD2adRs3oEuIJzQxAY0CtUHsV69iTE7FnJpGp/btmTd7NjVrlv17UCpf7Hbeff993n3/ffQtW6BNSkRbJ6bMD1hOqxXDtu04UtKIVKv55ssvSUwsflm+UuLQ6JORHvXZ3evNsojDh8DFIhPSVaSUz1/TRgv8AqySUk6+5r1aBcIigEmAWUr5Qgnn23pteu7iXiu2r6+Lw19//cVDQwZjrFIFfe/7PRoluIt0OjFsScGwZi0v/etf/Ou558o1V8/p06cZ+uijpO3di35AP4Jjor1yHvPRo+QtXc5tHTsye/qMcp2XsFqt/Pv115k2fTr6e+5CHxfrlZGa/cpVDCu+o6rdwZLFi8s9pLZ8+XJGjB6N5pbW6O/oiUqr/HyBtNvJW7sea1o6n0+dysCBA8t11Ltnzx4eHDyY0zYrof36EFSlilfOk7dtO8YffmTko4/y7ltv/W3Uq4Q4hDaOko0+GeFRn133/6cs4lAVWALUAU4AD0gpLwkh4oDRUsoRQojBwDxgT5Guj0gptwshNpA/OS2A7QV98oo5T02gNrAIGMj/z6VHADOklC7La3pbHB4BcshPovlMwZKqa9uNAkYB1KlTJ/bEiRNAfpK55154gS8WLkR//73o29ziFT+LYrt4CePyFUQF61j61Vc0a+b98qSLFi3iyfHj0SUloO/R3aOwSmlwWq0YVq/BsXM382bPplevXl49H+Sn6B7w8MNc1gUT2qc3mkjvxs2llBjSMzD+9AsTxo7ljdde87rYX7p0ieEjR7IpJRl9/77o3IyblwXLyUwMS5eTdEtrFs79wuvhNKfTydvvvsv7H35I6J090Sclel2UHLm5GFb+gP7KVZZ+9dX/1DpXShwaT3rMoz4773vL53MrCSGGkX//jQPS+H9xyCF/3mOFSxtlEQcXEy/JwAXy08T+B6jlKtlT4cjBYDBw5733svfKZcL69/XKaOF6SCkx/LkF68ZNrP7pp+sOaZU4z79ff50ps2cTPvAhr40Wrof56DFyv/6WN19+macmTPDaedavX0/vAQMIuftOr40Wrof9ylXyliwlqWEjvlu6lGCFq+sVcurUKTp170ZOVBRhd9/lldHC9ZB2O3m/riH48GH+3PSb14r/2Gw2Hh4yhA3bthL28IOKhMk8IW/bdkzfr+LbxYu5++67AeXEoclkz8Rhx72+Lw6FCCH6SSmXl6ZvmQLaUsrbpJQtizm+l1KelVI6CtbazgYSXNkDyM3NpWO3buyzWogYMqhchQFACEFYx1vR9evDbXfdxW+//ab4OaSUTHjmGabNn0/lJx8vd2EA0DWoT6UnRvHa++/x5ltveeUcP/30E7369yds8MOExceV+4S/plIkkY8+Qkr2KW6/6y7MZpdzcB5z8uRJ4tq3J69ZUyJ631+uwgAgNBrC770ba2w74tu35/Dhw4qfw2q1ck/vXmzcv4+IEY+VuzAAhLVtQ/gjQ3lg8CCWLl2qoGWJSnh2+BOlFQbw4ia4gpn4QvoAu131kVLS8+67yQzWEt6/r+J1aT0htPnNhD38IPf16YPSacT//frrLFy+nMjRI1GHhytq2xOCqlSh0ujH+ejzz5g8ZYqitjdt2sSDgwcTOXwYIQ0bKmrbE4RGQ8TAh9ibm0Ov/v2w2+2K2T579iwdunbBER9LWPduitktDWGdOiI6d6Rjt25kZWUpZtfhcPDgoEFkZGcTMXRwuYtfUXT16hI54jGGPz6KX3/9VRGbhVlZPTn+KXhzh/QHQohdQoidQDfgKVcdjh07xiGLmfC+vcu8SkcJQpo0JqRvb26/6y5Onz7tuoMbLFy4kCmzZxE58lHUoaGK2CwLmsgIIkc8xqtvv82qVasUsXnkyBHu79uX8EEPE1y3jiI2y4JQqwl/6AHST55kzPjxiti02Wz0uPNOzM2aEta5kyI2y4q+fRLO2HZ0u/12xUZJz7/4Ir/t2U34oIcr9GGtkODaUUQMHcyAhx+uaFdueLx2B5ZSDpFStpJStpZS3l9kV+B1uZqXR9iAfj4hDIXoW7VEExfLsMceo6yT96dOnWLsxImEDxpYoSOGawmqWoWwhwbwyIgRXLrkcuNkiTidTh4aMgRdl86ENPadspZCoyHs4Yf4aulSNm7cWGZ7b7/7LqcddsJ63q6Ad8qh79qZy6EhvPraa2W2lZyczMw5cwgf+BAqH9qlratfn5CetylmT4X06PAnhBChQohXhRCzC35vLIS47r6IovjOXRhQV66EqoLWppdE2G3dSd29m0WLFpXahpSSIcOHE5yUSHB0bQW9U4aQhg1RNb+Zx8d4VjLxWqZMm8aRCxfQd+6okGfKoQ4NQd+nFwOHDSUv72+r/9xm586dfPjJJ+j79vaJjZNFEUKg79OL6bNmkZaWVmo7JpOJBwcNQt/rPp96kClE3z5JGUMe1nLwsT+3O8wDLED7gt9PAW5NMvqUOAgvrSYpK0KjQf9AP8ZMmFDq8NL8BQvYevAgYT0qNjZdEvq77mD1po388MMPpep/+PBhXn3tNfQ+NvorSmiL5tijo3nq2WdL1d9ms/Hg4MHo77qjQiZm3UEdHo7+vnt4YNCgUoeXXnzlFQyVK5XLEvLSoJQoC7ihJ6SBhlLKDyio6yClNOJm/kDf/Ab7IMExMQQnxDP+6ac97pubm8uEp5/Ov2mW4+Y6T1EFB6Pv349HR43CarV63H/UmDGEdO1CUHWPE0iWK6H33cs3y5axdetWj/t+Pn0655xO9IluLb6rMELbtSU3TM/Hn3zicd99+/YxZ94X6Hvf7wXPfI8bfELaKoQIIX9LAUKIhuSPJFwSEAcPCO3SiZ9++pFz58551G/RokUE16/vk+Gkawlp1BCqVmHlypUe9Tty5AgpKSnoO9zqHccURB0agu7WJD72cIWW0+nkw0mTCO7R1efCSdcihCC4ezcmfzoNh8PhUd9JU6eiS0zwyXCS8tzYS1mB14FfgRghxGLyM7m6lcY7IA4eoA4NRX9La2bNnu12HyklH02dgiYx3oueKYs6IZ4PJk/2qM/Uzz4jND6uQpc6ekJoYgLfffcdly//bdP+ddmwYQMG6SS4HHY/K0FwTDTOsHB++uknt/vk5eXlJwr08ZGRktzIIwcp5RqgL/m7pb8G4qSUm9zpGxAHD9EmJjL188/cfhr7888/uZibh65JYy97phyhrVqy/8AB9uzZ47ox+ZOX8+bPQ5fkPzcUdVgYYS2a88W8eW73+WjKFDQJCT4/aiiKOjGeDz0Q+kWLFhHauJHPzqcojRA39pyDEGIV0JP87K8/SikvuNs3IA4eEhwTjUOv5+efS8w+/l8+mTqVoIR4v7qhCLUaXUI8k6dNc6v90qVLCY6pQ1C1al72TFk0iQlMmjbNrSXKp06d4vfffkMf5zKZpU8Rektrtm7bxpEjR1w3Bj6eOhVNgv+McpXgRl7KCnwEdAL2CiGWCSH6CyHcyhkfEIfScHMzflmzxmUzKSXr168npHXLcnBKWXStW/Lr2rVutf3hl1+QN/8tJb3PE1yvLldycsjMzHTZdtOmTYQ3bapIevHyRBUUhL75zWzYsMFl2wsXLpB58iQ6H9qfUh7c4GGl36SUT5JfP3om8AD5ZUddEhCHUqCNjuavlBSX7U6dOoXd6UBdqZL3nVKYoBo1OJudTW5ursu2aenpFZIfqqyIgmplGRkZLttuSU3FXrPEio4+i6NmDf504/OakZFBRN26PrsM2RuIG39CmoLVSv2A0UA8/1/DukT+OZ8CBdFGR7N/zx6X8w7p6eno69b1q5BSIUKtJjImhm3btpXYLi8vj9OZmWgrqOhMWbHXrE5yaqrLdn+lpKCN8f3VZsURHBPNllTX4pCeno5TgSJa/saNLA5CiCXAPqA78Cn5+x7GudM3IA6lQB0agi4ykgMHDpTYLjUtDYefPm0CEFXL5VP19u3biYiJ9un9GyWhia7N5pTkEts4nU727d6NNtr/RkcA2tq1OXbwkMu9K78nJ6OK8s2a6t7iH7AJbi75gjBaSrmxIEu2WwTEoZQER9dmx44dJbZJ3roVTS0//rLVrMEWFxlpd+7cicpPRw0AwbVrs3dXyQmDjx07RlBoKGq9vpy8UhaVVktY9ers37+/xHY7d+5EW9s/R0el5gZdrSSE6F7wox7oJYToW/Rwx4Z/Pu75AFKnIycnp8Q2V65cQdWgXvk45AVUoaFcPne+xDZXr17FofOvSdqiqEJDMbrIs3T16lWCwvxTGApRh4a6/LwacnOprK/4TMHljR+uQHKHLsAG4L5i3pOAy0pwAXEoJVKjwWQyldjGbDIhfCibpaeIoCBMxpKv0Wg04lT778dIBAVhs1iQUl53bshkMqEK8r2EkJ6gCgpy+Xm1Wix+/XktDYUT0jcaUsrCtLxvSimPFX1PCOHWLs5AWKkMuJxo9sOJ6L/h4hr8cbL9f5Dyxr/GAlxdx41ynZ5yI4aVilBcJbhl7nT030e+CkbY7eh0Je8l0el0SJutnDxSHmmzERJS8jWGhISgcihXXa28kXY7QVptiTdGnU6H0+Z5IkJfwmmzufy8Bmm1+Z9XF+1uJAonpG80hBDNgBZA5DVzDBGAW3/ggDiUEmE2ExERUWKbSpUqccpoLCePlMdpNFI5slKJbSIjI1Gb3Ury6JM4jUZCXdQpr1SpErY8Qzl55B0cRqPLz2tYRDgOg/EfknDv/7kRxQFoCtwLVOJ/5x1ygZHuGAiElUqJJesUt9xScq77pHbtsCtUXrRCOHOW9nFxJTZp3bo1zjNnyskh5bGcOkXzViXvYK9Xrx42oxGHwT8FwmmxkHfuHM2aNSuxXatWrbGeOlVOXvkGghszfYaU8nsp5XDgXinl8CLHeCnlX+7YCIhDKXAYTZivXqVp05JTRiQmJKA+c7acvPIC2aeJcyEObdq0ISczC2n3z9CSPesUnZLal9hGpVJxc8uWWLOyyskrZbFmZ9OgaRO0Lqosdk5Kwpntxw8zpcHD+QY/HGVsE0KMEUJ8LoT4ovBwp2NAHEqBNSuLZi1aoHZRcD02NhbDiZNlrj1dEUiHg6uZmbRt27bEdmFhYdSKicHqp6MHzZlzJMa7TjTXITERa6Z/PlVbMrNIinedMTcuLg6Vn/4dy4JKOD06yoIQoooQYq0Q4lDBv8WmvxVCOIQQ2wuOH4q8Xl8IkSKEOCyE+FYI4WoZ3ZdATeAO4DcgmvzQkksC4lAKrJmZ3JqY6LJd7dq10ahUOK5c8b5TCmM9c5YaUVGEuYjHA8THxWHJ9L+naiklhhMniI2Nddk2KSEBjZ+OAtWnz9LBjc9rbGwsOcdPIJ1luwH6ExWwQ/oFYL2UsjH5hXdeuE47k5SyTcFRtCTf+8AkKWUj4DLwmIvzNZJSvgoYpJQLgHsA1x8GAuJQOvYf4O477nDZTAhBjx49MO3cVQ5OKYt1927u6tnTrbb333UXYl/Ju299Ecvx41SKjCQmJsZl265du5J74ADOUtZkriicNhuGffvo3r27y7bVqlUjpm4dzIcOlYNnvkM5zzn04v8T3y0AervbUeQvqevO/y9Fdad/4XLJK0KIlkAkUN2d8wXEwUMsmZmoDQbuuusut9o/PX481pQ0v3oak3Y7ppQ0Jowd61b7AQMGYMnMxHbB7ToiPoEtOY2nxo1za31/7dq16dylC4YMz+tOVySG7Tto17YtDRs2dKv9M+PGY09J87JXvkMps7JWE0KkFzlGeXDKGlLKwomdM8D1kq/pCmwnCyF6F7xWFbgipSyc4MsCXOU7mVUQunoV+AHYC3zgjqMBcfAQa3Iq458c43K+oZAOHTpQLSIc86HDXvZMOQy7dtOsaVNatGjhVvuQkBCGPzIcc7Lr7Ka+giM3F8PevTw6fLjbfZ6dMAF7appfzSE5U9N5buJEt9sPHjwY4+Ej2D0on+rvlGLO4YKUMq7IMauoPSHEOiHE7mKOXkXbyfwP0vU+THWllHHAQGCyEMI9db8GKeUcKeXlgroODaSU1aWUM9zpG9jn4AEOo5G8HTsZteI7t/sIIXh2/AT+PWcONG3iRe+Uw5maxvOvv+FRn/FjxjAnNhZ9z9v9oo60MTWNPn36UNmDcpjdu3cnTKXGcuwYugYNvOidMlgys1Ab8rjnnnvc7hMWFsbgQQNZkZJK+J2uQ6f+jhCgVngFkpTytuufT5wVQtSSUp4WQtTiOoV3pJSnCv49KoTYBLQlf7dzJSGEpmD0EA0Uu0pCCPG0Cx8/cXUdgZGDBxg3/c69991L9epuhez+y+DBg7EcO4bFD5ZCmg4fQVy+Qu/evT3q17BhQxITEzH86dYS6grFYTRi/iuZZyZM8KifSqXi2YkTsazf6POjBykllg0bmTh2nNuj3EImjhuPKSUVhxuFnm4EynnO4QdgWMHPw4Dvr20ghKgshAgu+Lka0AHYWzDS2Aj0L6l/AeEuDpcExMFNLCczsaZnMPVjl4L7N8LDw5n6yScYli736f0ATosFw7LlfDFrlss18cUx+/PPMW36DetZt6oQVhjGVT/xUP/+tGvneT3oJ594guoqNYYU3w6hGbduIyLPwDNPl/gAWSw333wzI4Y/imHlD64b+z2yXJeyAu8BtwshDgG3FfyOECJOCDGnoM3NQLoQYgf5YvCelHJvwXv/Ap4WQhwmfw5ibrFXJeUbJR3uOOpT4iAtvpmGQdrtGJYt57MpU6hVyvoMw4YNI7ZpM/LWu67lW1EYflnNnd26c999xWX5dU3Dhg156803MS5b7rMT8MY9ewnKOsWkjz4qVf+goCCWLF6M4ZfVPhuXt+fkYFj1E98uXkxwKWtev/f22+ivXCVv23ZlnVMIpUZu5b2UVUp5UUrZQ0rZWEp5m5TyUsHr6VLKEQU//yWlbCWlvKXg37lF+h+VUiZIKRtJKQdIKUu8aQohmggh1gshdhf83loI8Yo7vpZJHIQQA4QQe4QQTiFE3DXvvViwUeOAEMKt4KXj8hWcLqpVVQR569aT2LIVgwYNKrUNIQRfzpuHJTnVJ8NLpsNHcO7dx8zPPiuTnfFjx9Kw2k3k/f6HQp4ph8NoxLBiJV8tXOjW/o3r0apVK55/5hkMy77zufCSlBLjd9/zxKhRxLuxue966HQ6vl20COMPP/pkeMnwV8nV+zxBjfTo8DNmAy9SsKRVSrkTeMidjmUdOewG+gK/F31RCNG8wIEWwJ3A50IIl4HPyLAw8pYs86mnTsPOXdjTtzJ/zpwypzSOiorisylTyF30NXYXhVfKE9vFS+R9s4QFc+d6NEFbHCqVim++/BLLb39gOug76+Wl3U7uV98y6MEH6dq1a5ntvfTCC0RptRjWrCu7cwqSt+k3KpvMvPXmm2W2lZSUxOiRI8ld/DVOq+9kFzYfPYZprTL/76L8w0rlTaiU8toYqFux7TKJg5Ryn5SyuELKvYBvpJSWgkIThwGX+/fr169Pk5BQ8las9AmBMB08iOm771n366+lDiddy5AhQ3hq9OPkzJmHw1DxGVvtV3O4Onsub736Kvfee68iNhs2bMiq774j96tvMB8/oYjNsiAdDnK/WUJCvXp8OmWKIjaDgoJY/+uv6A4cJO833xglGbYko9m6nU3r1pU6nHQtH7z7Ll1btSZ38Vc+MV9myTpFzpeLWfbNN4rZvMFzK10oWAYrAYQQ/QG3Emh5a86hNpBZ5Hd3NmsghGDNzz9Tx2ojb9kKpMPhJfdcY9yzl7yvl/DjypVupVfwhNf//RrDBwzg6szZFTqCsF28xJUZM3lu3FgmjB+vqO0uXbqwZPFicub/X3v3HR9FnT9+/PXZ3WSTbOg9JKFJ76TRbQh6VrChIuUsIIhgu7Ocd+cpX+9UpBdRKWoUkCIoAoKASEklVOktBJLQQsom2z+/P7Lc5Qchm83ObnZlnj7m4WYz85n3LpN5z3zmU76k5NhxRct2h7TZKEj8lo41a/H9d9+h0ynXerthw4Zs27wZXfouin7ZrFi5VWH8bRty6za2bd5MUwXngdZoNCxJTCQuMoqCL7+u1mpf06nT5H8xn4Xz5jGoEiMUVMbVpqzuLAFmHPAp0E4IcRaYCIypzIYuk0NlO3RUlRDi+as9DS9cuEB4eDhbN22ivT6Egi+/xu5ifl+lSYeDwm3bMa34nl/WraN///6K70MIwScffcTEZ/7MldmfYj5zxvVGCjMdP8GVufN47403eeett72yjz/96U+sXr6cosRvKaqGzmO2K/nkf7GAXtHN+Pmnn1xOdlMV0dHRpO3cSfjhwxSsXOXzk6e02Sj8YQ3BuzJI3bmz0j2h3REUFMQPK1dyR4eOFHw2H+vly4rvoyJSSop2ZVC48Eu+S/yGRx55xPVGbtDgcGsJJM4H2AOABkA7SueW7luZbV0mB+cT9U7lLDdqXwulHTPKDlhzw84aUsp5V3saNmjQAACDwcCGtWt5+s4BXJo8FePuPZX5LB6zXrpEwWfzaXLiFMnbtxMf73oky6oSQvDPv/+DuZMnU7TgSwrXrffJbbvDYqFw1Q+YFi8l8fPPFb9juNYdd9zBts2bqZWxh8KFX2LLz/fq/sB5MklO5dKUaYx79FFWLVumWDVLeSIiIkjbmUS/Bg3JmzId04mTrjdSgDkzk7ypM4gNDWNXcgrNmjXz2r6CgoJYkpjIq6NGkTd9JkU7dvok2dsLCyn86hsMO5LY9PPPlR62prKqOHyG3xNC1HQ2CpophLgLKKa0X8Qx4LHKlOGtaqXVwFAhhN45mXVrwK2G4Xq9nqmTJ7NhzRpCtm6j4OtvvNZqQjocFG3bweXps3htxAgyUlJcztWglCeffJJD+/fTXWjJmz4Tc6b37iJMx09wecp0+jVowNGDB3nggQdcb6SArl27cmD3bp6/734uT5lOUUqa104stitXKFiwiDp797Hj1195791/ud0JrCrq1q3Lyu++Y8HMmZi+XULh6h+9dhchbTYKf1pL0cKvmP2f//DT6tVcvbDyJo1Gw9tvvknK9h00PHKs9C7iknfuIq7eLVz6ZBrD77iDg/v2edT6qiJaHG4tAeIrSmeD20fpzG+bgUeBwVLKStX6CE/+SIUQg4EZlN6yXAF2SykHOX/3NvBnSp+MT5RSrnVVXmxsrExLS7vu/ZKSEt54+23mffYZ4T26oe/Zk+AIzx8Q24tLMKamYUtJpXmTJnz75Ze0b9/e43KrQkpJYmIi4ya8RHBUNNqEOELbtUVoPMvf0m6n+MDvOFJScZy/wBeffup272clZWRkMPTpp7lQVIQ2PhZDTA80ClT3mDPPYElKwbhvH6++PJG//+0dgoKqZxiPixcv8twLL7Dhl18IjYsltFcCOg9bgUFpNVlxUjKmlFT69+nDgs8+o1GjG43b5l02m43/fPQRkz74AEOnjgQlxKNvFu1xiz6HxYJxVwb2lFRqaXUs/uorEm4w3LgQIt05/lCVRXSsI59ZfJtb27zf5XuP9+ttQoh9UsrOztdaSh9CR0spKz2ssEfJQWk3Sg5XnT17lrnz5jF77lxEnTpo4mIIbdvGrTlvHRYrlqwsrLsyMO7ew8BBg3h1wgT69u3r8YGthOLiYhYvXsyHU6aQfeECQQlxhHbuhK5evUonCulwYD1/AdO+fZiTU2jVoiV/mTiRhx9+2KvVK5XlcDjYtGkTH0+bxtZff8XQoztB3buhj2yKcOOBsS0/n5JDh3GkpKEzlfDS2HE89+yzbg9v4i2HDh1i2swZfPV1IqEtW6CNjUHfogXasNBKl+EwmTCdPIU9fRfFR47yxBNDmfjieDp1qnhqU1+5dOkS8xcsYMqMGZi0GjTxcYS1a4u2du1K/z1Jmw1LdjaWjD0Y09Lp1bs3r0+YwMCBA9FUcMwrkxxqy+eX3OrWNu92Xh0IyWGXlLLHjX6uVBmBlByuslqtrF69mmlz5pCekoJGrycsOhpb44boGjVCBAeXnmQcdqTVhu3KFTTZOdjPnaPwXDbNWrXi6aFDef6552jcuLEPPpn7pJSkpqYyZcZ0Nv6yiaKCAmo0b4ajcWM0TRqjCQtznkgl0mrDXlyMzM5Gk51DwelMaterxz0DBzJx/HiXc11XpzNnzjB77hwWL1vO2dOnqdm0KZqmETgaN0ZXqyYiSAcaLdJqRVos2HJy0eXkYszMRDgcJPTsycRx47jnnnt8Un1UFUajkcTERObOn8/ve/cSUqc2+shIbI0boatfHxEUhNDpkHY70mrFdvESutxcLGeyKL50iXadOjF61CiefvpparhxIeRLDoeDDRs2MGXmTHZu345NSsKbNcPeuBGaxo3Q6PWlx6uUSJsNe0EBIjsHx7lzFJzJoklUFI889BDjx42jefPmldqnEsmhacfacvQS9xqd/KPzD4GQHOzA1UnPBRBK6XMHQemAsDVdlhGIyaEsKSUnT54kLS2N5NQU9hz4HWNxMSaTiaCgIMJCQ4mMiKBPQgIxMTF06dLFK61WvO3ChQvs2rWL1NRUdqank19QQElJCUIIQkJCqFu7Nr3j4oiNjaVHjx7UrVu3ukN2W3FxMXv27CE9PZ3fkpLIyc2lxGTCZrMRGhKCwWCge+fOJMTFERMTQ3S059UYvma32zl06BDp6ensTEnh0LGjlJSYMJvN6PV6QkNCaN2iBb179iQmJob27dsr2vzWF6SUZGVlkZ6eTkpqKul791BUZKTEZEKr1RIWGkrDBg3o5/yM3bp1w2AwuL0fpZLD2KWVarzzX3/rtMbvk4MSAj45qFSqm5MSySGyUy05bmkft7Z5q+PamyI5BNYliUqlUiksAMdL8gk1OahUqptW6aisAdM81afU5KBSqW5iATnSqk+oyUGlUt201DuHG1OTg0qluqkFUK9nn1KTg0qlumldHVtJdb0/THLIy8sjPT2dI0eOUFxcjNlsRqfTERoaSuPGjenRowetWrUKuHbxZZlMJvbt28fevXspuKafQ+3atenatSudOnWq0vzP/sLhcHD06FF27drF+fPnMTn7OYQ4+zm0a9eOHj16ULOmyz48fi07O5v09HROnTpFSUkJFouF4OBgQkJCaNasGTExMURERAT08VpYWEhGRgYHDx6kqKgIk7OfQ2hoKPXr16d79+60bdu22jsvqncO5QvY5HD+/HkSExPZ+OuvpO/axZVLl6jZLBoaNMCh0yG1WpAOtHY7oqCQkswz2E0mOnbpQt+EBIY+/jhxcXF+/cdnNptZsWIFP65fR3JqGpnHj1Mjogm6Jk1whITg0JYOLaCx2dGYTFjPnqMoN5eWbdvQMy6e+++5hwceeKDaxhiqDCkl27ZtY+ny5WxPSuLg/v0E1wgnJCoKh8GAQ6cFoUHjsCMsVuT5CxRkZlK/UUNiY2IZePvtPPnkkx7PYOdtJ06c4Kuvv2bL9u3sycjAZDZRo3lzZJ06OHQ6HFoNGrsDjc2GuHKFotOZBGm1dOnejdt692HYU0/Rpk2b6v4YFcrPz+fbb7/l582bSU1NJTc7m1pRUWgaN8QeFPzfv0mN3YGmqAhz1llM+fm069iR3gkJPDJ4MLfffrtP/yYFoFWfOZQroDrBSSnZuXMnk6dNY+3anzB07oxo2YLgqEiCGjRwOfaQvbAQc9ZZrKczsWbsJqJhQ/4ycSJDhw4lLCxM6Y9TZadOnWLm7Nl89sUXBEdEINu1ITgykuCICDTBFZ/oHWYzlnPnMGdmIQ4eRF7OY+yYMbwwejQRERE++gSuFRYW8tVXX/Hx9GlcLjKi7daF4OgogiMj0broLSvtdqznz2M+kwXHT2D8/SCDBw/mlZdeUnxiJk/Y7XbWrl3LR9OmkpaaRmiP7mibNyM4MhJd3ToVngSllNivXMF8Jgv7qdOU7MqgW9euvD5xIvfdd59f9Zres2cPU2fMYMnSpRjatoHWt6CPiiSoUSOEi7sCe3ExlqyzWDLP4Nizl5rBwbz60kuMGDGCWrVqVbitEp3gmncKl39f0c2tbZ5pu/2m6AQXMMnh559/ZtzLL3M+L4/ghHjC4mLRGqp+QpcOByWHDmNPTsV0+hTjx73IP955p1oHpjtx4gRjxo9n27bfMMTGok+IJ7iRZ4PIWc5lY05KpmhXBoMGDWLWtGmKzhTmLqPRyJvvvMMXX3xBWJvW6OLjCGl9i0dXi/bCQoqTUzEnpxAd2ZS502fQt697QyIoSUrJgoULeeudd7CGhKBJiMPQrZvLxF5hmTYbxt17sKekIgoKee/vf2f06NEVDkznbSkpKYwZP56jx4+j7xlPWHw8ulpVr+6TUmI6cQJbUirGQ4cYMXw4H37wwQ3Hk1IiObToHC7/uaKLW9uMbLNTTQ6+Vl5yKCgoYNyECXy/Zg1hD95HWIcOHg9jfS3rxUuUrPmJmsZiliYmEhvr2393h8PBzNmzeetvfyP01n4Y+vRGo3CScphMGH/dijkphemffMKIESN8XqW2detWnnj6aSwRTQi9eyC62rUVLV86HBh376H4x58Y8dRTfPTvf/v8jjArK4tho0ax59gxQh96gJDmyk/AYz5zhuLvf6BdRATffvllpQeqU4rJZOJvf/87cz//nLA/3Y2hR3eXdwjushUUULJ+A5pTp0lcuJABAwZct45SyeFfK9wb4XZ4m+SbIjlU32VHJfz888/c0r49644dpd6rEzF06qR4YgAIql+PGsOHYUyI47aBd/H6G29gNpsV3095Tpw4Qa/+/fnntGnUHjuaGnfcrnhiANCEhFBj0EBqPDOKl//5TwbcfTdnz5Y7OZ/ijEYjL7w4jnuHDME28E5qDH1M8cQAIDQawnt0p96rE1mSnETbjh3Ztm2b4vspj5SSL+bPp0OXLhzQB1N7/FivJAYAfVQUtceO5lidWnTq1o1Zs2bhcPim3jwlJYX2Xbqw8JdfqPfKBMLjYhVPDAC6mjWp8ejDiPv+xOAnn2TUs89S6KXJvnxJCFFXCLFBCHHU+f/rHpYJIW4XQuwus5iEEA85f7dQCHGyzO+6eS1Wf7xzkFLy/v9N4sNp0zE8PJiwdr6ZlQ1Kr1iKV66iqdCwecMGr45uumXLFh4YMoSQW/th6N/PK4mvPNJmw7hpM5bkVDauW+fVO6Xs7Gz633EHeTVrYHjwAY+qAt1l3LsP4/er+eBf/2L8uHFe24/NZmPYyJGs374dw2MPE+zDZzuWnByM3y3n1m7dWPrNt15tqTZ//nxeeu01DPffS1j3bj6783SUlGD88SfCcnLZtnkzUVGlMxArcefQsrNBvr/SvTuHp1qnVHm/QogPgctSyn8LId4A6kgp/1rB+nUpndozUkpZLIRYCPwopVxWlf27w+/uHKSUvPL660z+9FPqvDjWp4kBnFcsw4dxrk5t4nv3Jicnxyv7WbNmDfcNHozhyaGE33arzxIDgNDpCB94F/rBD3D7wIH8+uuvXtnPqVOniO3Vi/zWrajxxOM+TQwAhi6dqTN2DG+/9x7vTXrfK/swm83cP3gwG/bsodbY0T5NDADBjRtTa8zzbDtxgkH33ktJSYlX9jN5yhQmvPEGtcc8X1qN5MMqSU1oKDUefZiSLp2I7dWLo0ePKla2wOfThD4ILHK+XgQ85GL9R4C1UspiT3fsLr9LDm++/TYLli+n1pjnPXq45QkhBOH3/Yn8li3od/vtXL6s7Dy5Gzdu5PFhw6g1agShrW9RtGx3GDp1IvyJx7lv8GCSk5MVLTs7O5s+t92KNaY74XfeUW1NhoPq16P22NF8NHs2H338saJl2+12Hh46lJSzWdQc+TSaaupfogkKosawJ9mXf4X7HnoIq9WqaPmzZs/m3f/8hzpjR3vcQMIT4bf2R/btTZ/bbiMzM1OxcjXC4dbioUZSymzn6xzA1TyvQ4Fvr3lvkhBirxBiihDCay1o/KpaKSo6WhY4HNR+4Xm04eHVHU7pJOc//kTTK/mk7NihyC17RkYG/e+8k/BhTxDaqpUCUXqu+MDvmFZ8T8qOHYq0pS8qKqJbbCwFrW8hfMAdCkToOVteHnlz5jHro48YPny4ImWOeu45Vu/cQc1RI9ya3tRbpN1OwZdfc2eHjixJTFQkIS9fvpyRo0dT+4XnCapfX4EoPVe09TdCdu/hzImTHlcr3dI5TH74vXu1Ew/fsvs0cLHMW/OklPOu/iCE2AiUN8Xk28AiKWXtMuvmSSnL7aQjhGgC7AUipJTWMu/lAMHAPOC4lPJfbn2ASvKrO4dz585R888j/CIxwP/uILJsVv7x7rsel2c2m3l46FBC773HbxIDQFjHDgTf1p/HnnoKu93ucXkvv/YaV2rXxnDn7QpEpwxdnTrUGjmccRMmKHLV+cMPP7D8xx+o8fRTfpEYAIRWS42nnmT9b1tZunSpx+VlZ2cz6rnnqDlimN8kBoDw/v0oUbA5tlZItxbgopQytswyr2x5UsoBUspO5SyrgFznCf7qif58BaE9Bqy8mhicZWfLUmZgARCv2BdxDb9KDpqaNQmqV6+6w/j/CCEIG/IQ02fPZteuXR6V9bd//IMCQxiGGLfm+fYJQ5/eZBqL+PiTTzwqZ8uWLSxetgzDg/f5Xe/z4IgmhPTtw5MjRuDJHfPly5cZ+eyzGB4egsbPppzVBAcR/ugjjB43jtzc3CqXI6VkxDPPoI+PQx8drWCEyjDce48i5QhAg8OtxUOrgRHO1yOAVRWs+wTXVCmVSSyC0ucV+z0N6Eb8KzlUYR5ZX9DVqoXh3nt4fNgwLBZLlcpIS0tjzqefEjb4Qb87aUJpM1DDw0P416RJHD58uEplFBUV8cTwpzEMeQitH/U4Lyv89ls5kJnJvHnzXK98A2NefBFNh3bV+ryoIvpm0QTHdGfUc89VOQkmJiaScmA/4XfdqXB0ylAuKUu0wuHW4qF/A3cJIY4CA5w/I4SIFUJ8fnUlIURzIAq4trVIohBiH7APqA94p6UFfpYc8L9z5n8ZYmPICw7i/f/7P7e3tdvtPD5sGIb770XnxwPGBdWvh+GuO3li+PAqnVT++tZbWCMjCevYwQvRKUNotRgeHcJrb7xBdna26w2usW7dOtZt3oThnru9EJ1ywu4awPaMXaxcudLtbS9dusS4CRMwPPKw31SZeYuvWytJKS9JKe+UUrZ2Vj9ddr6fJqV8tsx6p6SUTaWUjmu2v0NK2dlZTTVMSlnkUUAV8K/k4MeEEITe+yemTZ+OyWRya9t169aRZ7US1qO7l6JTjqF3L46fySQpKcmt7a5cucKChQsJu3uQlyJTTnCTJoR07cKsOXPc3vafkyYRctcAr3RUVJImKIiQuwfyj0mT3N72s88/J7htG/TRUV6IzP9okG4tNws1ObghqGEDgps2Zdky9/qffDR1KtoE/x4B9iqh0RAUH8/k6dPc2m7RokUY2rWrtubH7tL3jGfOp5+61ezz4MGD7D9wAENX98biqS5hHTpw+swZt56V2e12ps6cSXDPBC9G5j+E8Hm1UsBQk4ObNAlxfDh1aqXXP3HiBCkpKRi6d/NaTEozxMfx05o1XLhwoVLrSymZPH06up5xXo5MOcFNmiDq1mXVqoqeB/7/ps+aSWhcbMBUtQiNBn1CPFNmzKj0NuvXr8caHEzwTXLXAKB1ziNd2eVmoSYHN4V1aM/JzEwyMjIqtf7M2bMxxMVUWwepqtAawjB07sJnn3/uemVg8+bNFFqthLRs6eXIlKWJj610ojcajXz1dSIhPb3WctArwhLiWL58OVeuXKnU+h9Nm4omPjYg7nKVUA2tlQKGmhzcJLRagrt1Zdny5ZVaf/GyZQT38L+mq67oenTj6yVLKrXu4qVL0XTrEnAnFEOXzuzNyCAvL8/lups2bSIsMpIgL4615Q3aGjUIb30L69evd7lucXEx23/diiEAno0pR61WuhE1OVSBLiqS35JdP7DNz8/n0vnzBDcpr7Okf9NHRXL88OFK1cnvSEkhuJl3RiD1JqHTUbNZdKXq5FPT0nBENPFBVMqzN2lMckqKy/X27NlDzaZNA+ou11OlrZXUaqXyeJQchBCPCiEOCCEcQojYMu83F0KUlBlWdq7nofoPfVQkezN2u2zuuWvXLmpGR/t0UD2laPR6DA0a8Pvvv1e4ns1m4+jBg+gjq28CIU84mjSmotkHr9qatBNtgH7GoMhIfqvE2Fnp6elomvrPbIG+ohHSreVm4elZaz8wBNhazu+OSym7OZcxHu7Hr2hr18Zqt7ucDyE1NRUZgHcNVwVFNnV54vz9998Jq1fP73oKV5YmIoKtO3e6XG9vxm6CIyN9EJHy9FGRHNizx+XFzG9JSTgaB+7xWhUC6etRWQOGR8lBSnlQSlm17rQBTAhBeCWqI7YlJyMCtCoCwNaoETtTK66O2LVrF8EBekUNEBwZyS4XjQtycnIwmU3o6pY7Pprf04aHowsN5cSJExWul5aejj4qMBNgVanVSjfmzfqOFkKIDCHEr0KIfjdaSQjxvBAiTQiRZi8yejEchdWowfnzFY2ZBdm5uehcTJLuz3S1a5Hlohfx+fPnsfnJQIlVoatdiyuXLlW4Tm5uLqF16wbcA/ey9HXquDxeL124gDaAj9eqUquVyueywXZFw886RxksTzYQLaW8JISIAb4XQnSUUhZcu6JzRMN5AProqID55qVO53JilZKSEkRQ1SeVr24iKIiSYtefUeqUnybSV0RQEBYXPd5LSkrQBAX2Q1pNUJDL49ViNgf08VoVV+8cVNdzmRyklNfP7O16GzNgdr5OF0IcB9oArp/8BQiHRrhsyWO32SAAH0b/l0aDxcVntFqtyAC+okYIHHY7Usob3hnYbDaEJoA/I4BW4/J4ddjtgf85q0BNDuXzSldPIUQDSudJtQshWgKtgYorPAOMxm4nNDS0wnX0ISFIm81HESlPWq2EufiMoaGhaOyB+5BO2uwE6fUVVhmFhITgCOB/RwBptbk8XoP0+oA+XqtCADdhPqwUT5uyDhZCZAG9gDVCiKs9bfoDe4UQu4FlwJirow/+UQiL1eUfmyEsDGk2+ygi5UmLBYOLobfDwsLQKDwtpS9Ji5lgF4PohYWFYTcF7r8jgMNsdn0xo9fjMFdtSPrA5d7D6JvpLsPT1korpZSRUkq9lLKRlHKQ8/3lUsqOzmasPaSUPygTrv+w5+bSrl27Ctfp0rEj1pwcH0WkPHtuLt07d65wnbZt2yIuXqxwHX9myc6hhYt5GVq2bInx4kUclsBMgtJupzA72+UUsLe0aRPQx2tVlA6f4d5ys7iZPqtipM1GwdlzdO3atcL1esXHo8utuIWIP9Pl5BIXW/EUvTExMRSeOu3RzGrVyZKVRe/4isdLCgkJIbpVKyznzvkoKmVZz5+nfqOG1HLREqlvzwSsWVk+ispPCNC6udws1ORQBZZz2US1aOHyNj02NhbzmcD8Y5NSUnj6NDExMRWu16hRIwzhBmwumoP6K11OLr0TerpcLyEuFkuAnjjNZ7KIjak4yQMkxAX2xUxVCARaN5ebhZocqsB8Jot4F1fUUFrlYsrPx+6iOag/sl3OIyQklCZNXHfi69a9R8AmQUvWWZcJEKBvQk802QFa5XIum/69erlcLSYmhuLMMz4IyL+o1Urlu5k+q2LEyZPceeutLtfTarV07dED05EjPohKWSVHjtCzl+sraoABt96KPB54jdGsly5jLSpy+ewIoHfv3piOHkM6AqtllpQS2/Hj9O7d2+W6LVq0QAdYcnK9H5ifEIBWCLeWm4WaHNxky8+n+MhRHnvssUqtP3HsWByp6V6OSllSShzJqUx4YWyl1h85YgTG3XtwuOhk5W9MySmMHDECXSUm7+natSuRjRtTciiwRosxHT9BrZBQevZ0neiFEIx+7lnMya5HcP0j0SDcWm4WanJwU0lSCkMff5yaNSs3HeaQIUOw5uRgyQ2cqzHz6UxCHA7uuuuuSq3fuHFj7ho4kKLUwOnjKG02ilNSeWncuEpv8/rEidgD7MRpS0rhtZdeqvTQH2PHvIAxfReOAG6C7Y7SHtLqM4fyqMnBDdJupyQllYnjx1d6G71ez/PPPos5KXBOKtbkFF4ePx6NG727X50wAVtyasC0WjLu3kO3rl1dNu8s6/HHH8d0OhPrxcB4+G7Lz8d4+DDDhw+v9DbR0dH06dsXY3rl550OdOqdQ/nU5OAGY8Zu2rRqRWcXbf+v9eLYsRjTd2EvKvJSZMqx5eVh3LefP48a5dZ2/fr1o67BQMnvB70UmXKkw4FtRxKvTZjg1nZhYWGMHDGCkm3bvRSZsoq37eDxxx6r9F3uVa9PmIB1ZxLSbvdSZP5D4N7zBvWZg+o69sJCitesZfa0aW5vGx0dzZ9HjsS4+kcvRKYcKSXGFd/zl9dfp169em5tK4RgzvTpFK/6AYeLgeyqm/G3bbRq1IgHH3zQ7W3feestbPv2Yzp12guRKcecdRZLWjrvv/uu29vedddddGndhqJNW5QPzA9p3PzvZuFXn1Ta/PdKxbjqB54dNapSD/bK8+EHHxB6/gLGPXsVjkw5xuQUGiJ4+803q7T9oEGDeOCeezCuWatwZMqxnr9A8aYtLP7qK7eqza5q2LAhn82Zg/G7ZX7bY1rabBi/W87UyZNp2tT9uTaEECQuXIhp+46A7fhXWaU9pH1XrXSj2TPLWe9uIcRhIcQxIcQbZd5vIYRIdr6/RAjhteGC/So5OK5c8cs6a+PuPRgu5/HB++9XuYywsDAWf/01xlWr/bJ6yZaXh3HtepYmJhLkwbDNs6ZNg2PHKTnsf813pcOBcdkK3nv3XVq1alXlch599FH6xcZh/HmDgtEpp2jTZmLatmXUyJFVLiMqKorJH36I8bvlflm9ZDpxUqGSBFqhcWvxUEWzZ5ZGJIQWmAXcA3QAnhBCdHD++j/AFCnlLUAe8IynAd2IXyUHnZQY/aw+13rxIsZVP7AkMdFlj2hX+vTpw8hhT1P03Qq/+oOTNhtFS5fx+iuvuP085Vq1atXi6wULKFq2AtuVfIUiVEbRxl9oWbcuE9xoUHAj8+fNw5qxm+KDhxSITDklx49j3pnMl/Pnezw50XPPPkvnFi0pWrve9co+ZC8qomjpMkXKKr1z8F21UiVnz4wHjkkpT0gpLcBi4EFR+g96B6WDmQIsAh7yKKAK+FVyaH3LLcjtO/2mpYTtSj75n83nP++/X+XqpGtN/vBDOtatS+GylX7RoUra7RR+s5g+bdvxzttvK1LmoEGD+MuECeR/Ph+70T9m9zNu20Hwgd/5YcWKKlUnXathw4b8+P33FC35DtNJpa5iPWM+c4bCr75hxdKlVapOupYQghVLlhB+6jRFm39VIELPOUpKyP98AS+42WDiRtL3mtdrmxxNd2cBQq7OXulcnlckmP9pCpTtqp7lfK8ecEVKabvmfa/wq+Sg1+vZsnEjlrXrMaZVb8cxW14e+fM+568TJjBubOU6g1WGXq9n7Q8/EG2zUbTi+2pNENJmo/DbJXSsXYdlixej1So3o9vf3nqLZ4YOpeCzL7AXFipWblUYt+9Abt/Bts1bKjUcSGX17duXZd9+S8GirzG5mJ/Z28yZmeTPX8RX8+czYIDb83PdUP369dm2ZQvaXRkUbaneBGE3FpP/+QIev+ce/j1pkiJlSinvllLGurl0uubneWXLFEJsFELsL2dxvwVENfKr5ADQsWNHtm3ZgmPjJop+/a1ankFYsrPJm/0p77z6apUfzlbEYDCwddMm2mi0FH6zuFo6HNmLSyhY9BWxjZuwfs0a9C7mNHCXEILJH37IC08N48qceVirYVhv6XBQuGEjupRUkrdvp0WLForv4+6772bFkiUUfJlI8f4DipdfGcWHDpM/fxHfLlrE4MGDFS+/adOmpO7YQdj+AxT+tLZaLmisly+TP3ceIx58kLmzZvn1fN5SygHOBHLtcqNpla91Fogq83Ok871LQG0hhO6a973C75IDlCaIlB07qHfsOAXzF2LLy/PJfqXdTuEvm8n/9HNmffwxr73yitf2FR4ezi/r1zOgbVsuT5lGybHjXtvXtYp/P8jlT6bycJ++/LhyJSEhIV7ZjxCC/3v/fSa99RZ5M2ZTtG27z04s1gsXyf/0c6IuXCJtZ5JXEsNVAwcOZOPatci16yn8brnPhhFxmM0UrlyFbeUq1nz/Pffff7/X9hUZGUnqjp3cUmImf/Zcn42/JKWkaGcSedNm8vZLLzHl44/9OjEoJBVo7WyZFAwMBVbL0ivlzcAjzvVGAJVNOG7zy+QApYOA7U1PZ/wjj3Jp6gyKkpK9ehdhyc7hyuy5tCkoZP/u3W71Kq2qkJAQFn+dSOK8z7AsXUbh96u8ehdhLy6hcOky+Gkdq5YsYd6cOZUaV8hTL44bR3pyMhGnMsmf94VX7yKkw0HR1t/Imzmbt59/ntQdOxStSrqRnj17cuzgQe5r155Ln0zz+oPqkqPHuPzJNAZERXP04EFurcRAkJ5q0KAB27ds4b2JL5M/dx6Fm7d4NdlbL1+m4PP5NDh0hKRt23j9tdcCPjHcaPZMIUSEEOInAOczhReB9cBBYKmU8upt6V+BV4QQxyh9BvGF12L1p6ajsbGxMi3t+vF59u7dy+PDhnHeakHXuxdhHTsgFKoft+TkYk5KpiRjNx998AFjxoyplgPw8uXLjHnxRdZt+gV93z4YYmPQeNg66iq70UhxShqm7dt5bPAQpk6eTI0aNRQp26047HY+/uQT3ps0idDYGEJ6JRBUv74iZUubDePefdi276R5vXos+fprWrdurUjZ7tq4cSNPjRyJvXFjgnonENKypSLHlJQS86lTWHYmw+lMFn3xBffee68CEbvv1KlTPDF8OIeyzhDUpzeGbl0RCl1oWC9fpiQpGVNyKn99/XXe/Otfy72IEUKkSyldj52vqpKASA4AVquVxYsX89G0aZw8fZqQhHhCE+LQuTk0AJRWHxXv2489JRVb7nlGP/ccL734oiItPDz122+/8eGUKWzcsIHw7t0ITohHH+l+XFJKLJlnsCQlU7RvP/fffz+vv/wycXFxXojaPSdPnmTqjBksWLgAfVQU2vg4Qju0R1ShFZEtL4/i5BRMKam0b9eev0ycyJAhQxR9uF4VhYWFLFiwgMnTp1NgsaBNiCM8NgZNFarwHGZz6fArKamESnh5/Hiee/ZZlzO7eZvD4WD16tV8NHUqu/fsISw+lpCEBILq1XW7LOlwUHL4CPbkVEpOnmTE8OG8/NJL3HLLjadwVZODdwVMcigrIyODKTNm8N3SpYQ1bIA2IgJHk8boo6IIatwIERSE0GhKq6HsdmxXrmA+k4Xj7Dk0OTkUnjpN+44d/3siCQ72WifDKsvOzmbuvHnMmjMHKxASHYWtUSOCoyIJbhqBJizsvydTabfjKC7GnHUWa1YWutzzlJzOJEyv5+Xx43nmz3+mvkJX6EoqKSlh6dKlfDhlCidPnqBG8+bYGzVCG9mU4MhIdLVqglaLEALpcCAtFizZOZjPnEGbk4v97FlMl/N46qmnmDh+PB06dHC9Ux+TUrJ582Y+njaNTRs3UKNpJEQ0gYgm6KMi0TVogNDpSj+jlEibDdvFS6WTJ507B9k5FGZm0u/223l9wgQGDBigSFNcpR05coTps2axcNEigmvWQNc0EnuTRuijIglu0gSh1//vb9LhwF5QgPlMFrazZ9Hl5FJ46jSRkU35y8SXeeKJJzAYDC73qSYH7wrI5HCVyWRi7969pKensy05ieSUVDJPnMBmsaDR6XDY7Wg0GmrXr0e37j3o17Mn8XFxxMTE0LBhQy9+EuU4HA6OHDlCeno6O1NS2JGczKEDBzAVF/+3qkJKSVh4OO07daJvz54kxMURGxtLy5Yt/fJEUp5z586Rnp5OaloaW5N2sjdjN/mXLyOlRKPR4LDbCdLrad76FnrGxdMnIYGYmBg6deqkeEsrbykoKCAjI4P09HR+S0oiLS2NnKws7DZb6fFqs6HV6WgQEUFsTAz9evYkNjaWHj16VPtdQmVZrVYOHDhAWloa25OTSUpN4eSRo1hMJjRaLQ6HAyEENWrXpnO3rvTv2eu/f5NNmzZ1q/pNTQ7eFdDJ4UaklJjNZoKCgqq9esFbpJRYrVaEEOicV55/RDabDbvdTnBw8B/2MzocDiwWC8HBwQGTzN0lpcRisaDVahVrBKEmB+/yflOVaiCE8FrzTH8hhPDL6jCl6XQ6n7Soqk4ajeamOF4D5Q5PVeqPeZmiUqlUKo+oyUGlUqlU11GTg0qlUqmuoyYHlUqlUl1HTQ4qlUqluo5HyUEI8ZEQ4pAQYq8QYqUQonaZ373pnMrusBBikMeRqlQqlcpnPL1z2AB0klJ2AY4AbwI4p7QbCnQE7gZmO6e+U6lUKlUA8Cg5SCl/LjMrURKl44sDPAgsllKapZQngWOUTn2nUqlUqgCg5DOHPwNrna9vNM2dSqVSqQKAy66nQoiNQONyfvX21ZmNhBBvAzYg0d0AnPOvPg8QHR3t7uYqlUql8gKXyUFKWeGEtEKIkcB9wJ3yfwM13Wiau/LKnwfMg9KxlVyHrFKpVCpv87S10t3AX4AHpJTFZX61GhgqhNALIVoArYEUT/alUqlUKt/xdESzmYAe2OAcMTNJSjlGSnlACLEU+J3S6qZxUkq7h/tSqVQqlY94lByklDecpklKOQmY5En5KpVKpaoeag9plUqlUl1HTQ4qlUqluo6aHFQqlUp1HTU5qFQqleo6anJQqVQq1XXU5KBSqVSq66jJQaVSqVTXUZODSqVSqa4j/jccUvUTQlwATnuh6PrARS+U6wl/jAn8My5/jAn8My5/jAm8E1czKWUDhctUOflVcvAWIUSalDK2uuMoyx9jAv+Myx9jAv+Myx9jAv+NS3VjarWSSqVSqa6jJgeVSqVSXedmSQ7zqjuAcvhjTOCfcfljTOCfcfljTOC/calu4KZ45qBSqVQq99wsdw4qlUqlcsMfNjkIIR4VQhwQQjiEELFl3m8uhCgRQux2LnP9IS7n794UQhwTQhwWQgzyZVzXxPFPIcTZMt/Rn6oxlrud38cxIcQb1RVHWUKIU0KIfc7vJq0a45gvhDgvhNhf5r26QogNQoijzv/X8YOY/OZ4UlXeHzY5APuBIcDWcn53XErZzbmM8Ye4hBAdgKFAR+BuYLYQQuvj2MqaUuY7+qk6AnB+/lnAPUAH4Ann9+QPbnd+N9XZPHMhpcdKWW8Av0gpWwO/OH+u7pjAD44nlXv+sMlBSnlQSnm4uuO4VgVxPQgsllKapZQngWNAvG+j8zvxwDEp5QkppQVYTOn3pAKklFuBy9e8/SCwyPl6EfCQH8SkCkB/2OTgQgshRIYQ4lchRL/qDsapKXCmzM9Zzveqy4tCiL3OagKfVk2U4W/fyVUS+FkIkS6EeL66g7lGIylltvN1DtCoOoMpwx+OJ5UbAjo5CCE2CiH2l7NUdHWZDURLKbsDrwDfCCFq+kFcPuUixjlAK6Abpd/X5OqM1Q/1lVL2oLS6a5wQon91B1QeWdoU0R+aI6rHUwDSVXcAnpBSDqjCNmbA7HydLoQ4DrQBFHuwWJW4gLNAVJmfI53veUVlYxRCfAb86K04XPDpd1JZUsqzzv+fF0KspLT6q7xnW9UhVwjRREqZLYRoApyv7oCklLlXX1fz8aRyQ0DfOVSFEKLB1Qe9QoiWQGvgRPVGBcBqYKgQQi+EaEFpXCnVEYjzpHLVYEofoleHVKC1EKKFECKY0gf2q6spFgCEEAYhRI2rr4GBVN/3U57VwAjn6xHAqmqMBfCr40nlhoC+c6iIEGIwMANoAKwRQuyWUg4C+gP/EkJYAQcwRkrpswdoN4pLSnlACLEU+B2wAeOklHZfxXWND4UQ3SitkjgFjK6OIKSUNiHEi8B6QAvMl1IeqI5YymgErBRCQOnfzzdSynXVEYgQ4lvgNqC+ECIL+Afwb2CpEOIZSkc4fswPYrrNH44nlXvUHtIqlUqlus5NV62kUqlUKtfU5KBSqVSq66jJQaVSqVTXUZODSqVSqa6jJgeVSqVSXUdNDiqVSqW6jpocVCqVSnUdNTmoVCqV6jr/DzR/6rxpVoaFAAAAAElFTkSuQmCC\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "X, Y, Z, tracker_distance, relative_azimuth, relative_slope = \\\n", - " twoaxistracking.generate_field_layout(\n", - " gcr=0.3, # Change this parameter according to your desired density of collectors\n", - " neighbor_order=2,\n", - " layout_type='square',\n", - " L_min=L_min, # calculated from collector geometry - do not change\n", - " total_collector_area=total_collector_area, # calculated from collector geometry - do not change\n", - " plot=True)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Calculate shading fraction\n", - "\n", - "Now that the collector geometry and field layout have been defined, it is time to do the actual shading calculations. This step is relatively computational intensive and is mainly affected by the time step, neighbor order, and computational resources available. Typical run times vary between 5 s and 3 min." + "Now that the solar positions have been determined, the shaded fraction can be calculated by passing the solar positions to the function ``get_shaded_fraction``:" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Wall time: 5.55 s\n" - ] - } - ], + "outputs": [], "source": [ - "%%time\n", - "df['shaded_fraction'] = \\\n", - " df.apply(lambda x: twoaxistracking.shaded_fraction(\n", - " solar_azimuth=x['azimuth'],\n", - " solar_elevation=x['elevation'],\n", - " total_collector_geometry=collector_geometry,\n", - " active_collector_geometry=collector_geometry,\n", - " tracker_distance=tracker_distance,\n", - " relative_azimuth=relative_azimuth,\n", - " relative_slope=relative_slope,\n", - " L_min=L_min,\n", - " plot=False),\n", - " axis=1)" + "df['shaded_fraction'] = tracker_field.get_shaded_fraction(df['elevation'], df['azimuth'])" ] }, { @@ -388,7 +391,9 @@ "source": [ "## Visualize the shading fraction\n", "\n", - "Plot the shading fraction for one example day:" + "Once the shaded fraction has been calculated it can be used for solar power calculations.\n", + "\n", + "As an example, the shaded fraction is shown for one day:" ] }, { @@ -398,7 +403,7 @@ "outputs": [ { "data": { - "image/png": "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RLl5hn9MT8IAbw+NxddHm+Xsor1c3EzbRrV4qFtz3liygxuiQhnUPsLuSAV6fuFmtqScdOo+W4bV4LmbWhW5zZkzZ7jllltITk4mNzeXZ555BoD33nuPhQsXkp2dzcyZM4mKimLNmjX87W9/IzMzkypVqjBx4kRatGhBRkYGo0ePJikpiaioKDIyMi7sf8mSJTz33HOcO3eOpk2bMnHiRKpVq8aiRYt46KGHCA4O5pprrik035EjR7jttttITU0lNjaW2bNn07VrV4YOHcrSpUt57LHHOHXqFOPGjSMrK4tmzZrx+eefExwczOHDh7nnnnvYs2cPAB999BHvvvsuu3fvJjY2lu7du3P//ffTt29fNm3aRGZmJvfeey/x8fH4+fnx1ltvcf311zNp0iQWLFjA2bNn2b17NwMHDuS1115zwjtUsP+u3M2avcd48+a2NKqjA4jspEfobujeLs24PLI2z87fzP5jOs1ufosWLSIsLIykpCQ2bdpEr169AKhbty4JCQnce++9vPHGGwBERUXx448/sn79el544QX++c9/AlahDA4OZuvWrTz//POsW7cOgKNHj/Liiy+ybNkyEhISiIuL46233iIzM5O77rqLhQsXsm7dOg4dOlRovtDQUMaPH0/nzp1JTEykaVOr+SEkJISEhASGDRvGoEGDWLt2LUlJSURHRzNhwgQAHnzwQa677jqSkpJISEigVatWvPLKKzRt2pTExERef/31Pz3XBx98gIiwceNGpk6dysiRIy/0WklMTGT69Ols3LiR6dOns3+/a1bK2piczltLdnBjm4YMah/ukudQJadH6G7I10d4e2gsvf/zI3+fnsj0u69yu6+xxR1Ju0qbNm14+OGHefzxx+nbty+dO3cGYNCgQQB06NCBOXPmAJCens7IkSPZuXMnIkJ2tnVeYuXKlTz44IMAxMTEEBMTA8Dq1avZsmULnTp1AiArK4urrrqKbdu20aRJE5o3bw7Abbfdxrhx40qVO3/Ty6ZNm3j66ac5ceIEp0+fpmfPngB8//33fPbZZwD4+vpSs2ZNjh8vfFqIn376ib/+9a+A9eHVuHFjduzYAUDXrl2pWbMmAC1btmTfvn00atSoVJmLk5mdy99nJBJSLYCXBrbWHlBuQI/Q3VRE7WCe79+K+H3HmbjqN7vjuI3LLruMhIQE2rRpw9NPP80L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\n", + "image/png": "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\n", "text/plain": [ "
" ] @@ -410,16 +415,18 @@ } ], "source": [ - "axes = df.loc['2019-06-28':'2019-06-28', ['shaded_fraction','elevation']].plot(subplots=True, ylim=[0,None])" + "axes = df.loc['2019-06-28':'2019-06-28', ['shaded_fraction', 'elevation']].plot(subplots=True, ylim=[0,None])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ + "Notice how the shaded fraction is zero (unshaded) throughout most of the day, with the exception of some shading in the morning when the solar elevation angle is low.\n", + "\n", "
\n", "\n", - "Visualize the average daily shading fraction:" + "Shading is also seasonal dependent, which can be seen from the plot of the average daily shading fraction below:" ] }, { @@ -430,7 +437,7 @@ { "data": { "text/plain": [ - "" + "(0.0, 0.4737615916403633)" ] }, "execution_count": 11, @@ -439,7 +446,7 @@ }, { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXQAAAEECAYAAAA4Qc+SAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAAA8H0lEQVR4nO3dd3xc1ZXA8d9R75LVLFnFKpYt3LsNLvSE3kNJA5IAKZQUskCyIQmkEFg2m2RJaKGFpZdgqulgXLDlbtmWbcmqtnrv0szdP95oNLJlq1jSSKPz/Xz8sebNm7n3ad4c3XdueWKMQSml1Njn5e4KKKWUGhoa0JVSykNoQFdKKQ+hAV0ppTyEBnSllPIQGtCVUspD+Lir4OjoaJOSkuKu4pVSakzavHlzpTEmprfn+hXQReQc4C+AN/C4Mea+Xva5EvgNYIDtxpivH+89U1JSyMrK6k/xSimlHESk4FjP9RnQRcQbeAg4GygGNonIKmPMbpd9MoC7gGXGmBoRiT3xaiullBqI/uTQFwMHjDF5xph24AXg4iP2uQF4yBhTA2CMKR/aaiqllOpLfwJ6AlDk8rjYsc3VVGCqiKwVkQ2OFI1SSqkRNFSdoj5ABnAakAh8LiKzjDG1rjuJyI3AjQDJyclDVLRSSinoXwu9BEhyeZzo2OaqGFhljOkwxhwE9mEF+B6MMY8aYxYaYxbGxPTaSauUUmqQ+hPQNwEZIpIqIn7A1cCqI/b5N1brHBGJxkrB5A1dNZVSSvWlz4BujOkEbgZWA3uAl4wx2SJyj4hc5NhtNVAlIruBT4CfG2OqhqvSSinlaVo7bFQ0tNFpsw/6PcRd66EvXLjQ6Dh0pdR4Zrcb3thewtPrCthRXIvdgJ+3Fysyornp1HQWp0Ye9RoR2WyMWdjb+7ltpqhSSo1n5Q2t3Pr8VjbkVTN1Ygg3nz6F6FB/DlY28daOw1z5yHq+uTSZuy+YgZ9P/1ZpcVtAP1zX6q6ilVLKrcrrW7ni4fWUN7Typ8tn8bUFSXh5ifP5//hqJv/9QQ6PrTlIXkUTT1y3iABf7z7f122Lc1U2tlFU3eyu4pVSyi1qmtr55j+/pLKxjeduWMpVi5J7BHOAQD9vfnn+dB782hzW51Vx2wtbsdn7To+7LaAL8PBnue4qXimlRpzdbrj1ha3kVzXz+LULmZ884bj7X74gkbsvmM7q7DLufWv3cfcFNwb0CcF+vJxVTFm9pl6UUuPDE2sPsmZ/Jb+5cAanpEf36zXXL0vl+mUpPLUun09yjr+qitsCekyIPzZjeHyNDldXSnm+vaX13P9eDmdPn8g1i5P6foGLO87JZNrEUO54Zcdx93NbQPfz8eK8WfG8sKmI5vZOd1VDKaWGnTGGu9/IJiTAh/sum4WI9P0iFwG+3jx45Ryqm9qPu59b71j07ZMn09DayRvbDrmzGkopNeS2F9XS2GY1Vt/dVcrGg9X89OypRIX4D+r9ZiaE8/tLZx53H7cG9IWTJ5AZF8oz6wtw1wQnpZQaavmVTVz80FrufXM3rR02/vDOHjLjQrl60cBSLUe6atHxFzV0a0AXEb518mT2HK5nc0GNO6uilFJD5vmNhQBkH67j+Y2FFNe08KsLpuPjPbwh1+03ib5kbgIh/j48v7Go752VUmqUa++088rmYgBK69p45LM8lqRGsmxK/0a1nAi3B/Rgfx/OnxXPe7sOa+eoUmrM+2xfBVVN7SybEkVlYxul9a3ccsZRq4kPC7cHdIDL5ifQ1G7j/ewyd1dFKaVOyGtbiokO8eMHp04BYF5yBMumRI1I2aMioC9KiSRxQiCvbil2d1WUUmrQapvb+WhPORfPTWD+5AiWpkXyi/NOGvAwxcEaFQHdy0u4bF4Caw9UUqqLdimlxqg3dxym3WbnsvkJBPn58MKNJ7Mo5eglcIfLqAjoAJfOT8Ru4K0dOiZdKTU2/XtrCZlxoUyPD3NL+aMmoKdGBzNjUhhv7zzs7qoopdSAHa5rYXNBDRfOmTRiKZYjjZqADnD+7Hi2FtZSUtvi7qoopdSAvLuzFIBzZ8a5rQ6jK6DPigfgXW2lK6XGmHd3HSYzLpS0mBC31WFUBfTJUcHMTAjjrR0a0JVSY0dZfStZBTWc52iUusuoCugA582KZ1tRLcU1ejcjpdTYsDq7FGPgvFnuS7fAKAzo5860/sJ9uFsnGSmlxoa3dxwmIzaEKbGhbq3HqAvoqdHBpMcE8+Gecj7NKed3/bjtklJKuUtFQxsb86vdnm4B8HF3BXpz9vQ4Hl+TR2uHjayCGr67IpX48EB3V0sppY7SnW5xf0AfdS10gLOnx9JpN2Q5ltRde6DKzTVSSqnefbSnjMlRQUyd6L7RLV1GZUCfmzSB6BA/5+O1ByrdWBullOpda4eNdblVnD4t1m2TiVyNyoDu7SWckRkLwILJE/jiQKXe0UgpNepsyKuirdPOadNi3F0VYJTm0AFuOSOD+ckT8BLhP17dwf7yRqZOdG8PslJKufo0pwJ/Hy+Wpo3M8rh9GZUtdICkyCCuXpzMsgzrLh9f7Ne0i1JqdPk0p5xT0qMI8PV2d1WAURzQuyREBJIaHax5dKWUW3Xa7Nzxyg4+3F3GBX9bw2f7Ksivaua0abHurprTqE25uFo2JYrXt5TQYbPjO8w3WVVKqd7sLKnjxawi3t55mMa2Tu5+YxfAqMmfwxhooQMsnxJNU7uN7UW17q6KUmqc2pRfDUBjm3Xv44KqZtKig5kcFezOavUwJgL6yWnReAms0Ty6UspNNh6sOWrbqaOodQ5jJKCHB/kyKyGc9bk6wUgpNfLsdkNWQTUnp0Xh5+3lXPP89FGUP4cxkkMHWJIWxVNr82ntsI2aHmWl1PhwoKKR2uYOLpufwKPfXoC/jzcX7SljhWMU3mgxJlroAItTImm32TWPrpQacV8etPLni1MjCQ3wxc/Hi3NnxY+K2aGu+hXQReQcEckRkQMicmcvz18nIhUiss3x73tDXdFFKZGIdP9ilVJqpGw6WE1sqD/JkUHurspx9RnQRcQbeAg4F5gOXCMi03vZ9UVjzFzHv8eHuJ6EB/mSGRfGRkdA77DZeXLtQZrbO4e6KKWU6iErv5pFqZGjrkV+pP600BcDB4wxecaYduAF4OLhrVbvlqRGsrmghg6bnQ93l/HbN3fr7eqUUsPqUG0Lh+paWTh5grur0qf+BPQEoMjlcbFj25EuF5EdIvKKiCQNSe2OsCQ1kpYOGztL6njfcUejHcW1w1GUUkoBsKXQGq64wEMCen+8CaQYY2YDHwBP97aTiNwoIlkiklVRUTHgQhalRgKwPreKj/eWA7C9qG6wdVZKqT5tLqghwNeLk+LD3F2VPvUnoJcAri3uRMc2J2NMlTGmzfHwcWBBb29kjHnUGLPQGLMwJmbgA/KjQ/yZEhvCU+vyqWvpIC0mmD2H62ntsA34vZRSqj+2FNYyOzFiTCw70p8abgIyRCRVRPyAq4FVrjuIiOu9ly4C9gxdFXtanBpJRUMbInDTyjQ67YY9h+uHqzil1DjW2mEju6RuTKRboB8B3RjTCdwMrMYK1C8ZY7JF5B4Rucix260iki0i24FbgeuGq8JLHGmXmZPCOXWqNUtLx6YrpYbDjuI6Ou2GBcljI6D3a6aoMeYd4J0jtt3t8vNdwF1DW7XeLUm1FpJfNiWauPAAYkP92VGseXSl1NDr6hCdlxzh3or005iZ+t8lLjyAp7+zmLmJEQDMSYpgm450UUoNg80FNaRGBxMV4u/uqvTLmAvoAKdO7e5QnZMYzge7y6hr6SA80NeNtVJKeYrXtxazZl8lWwpqRtUNLPoy+rtt+zAnKQKAXSWadlFKDY3XtpTw2tYSqpramT85wt3V6bcxH9BnJ0QAsE07RpVSQ8AY06NfbqyMcAEPCOjhQb6kRgfrSBel1JAoqm6hrqUDgBB/HzJiQ91co/4bkzn0I81JDGdDnq7CqJQ6cTsd6dtbz8wgNtQfb6/RvSCXK88I6EkR/HvbIUrrWokLD3B3dZRSY9iOklp8vYUfnZ6Ov8/YupnOmE+5AMx2DGHcrsMXlVInaFdJHZlxYWMumIOHBPQZk8Lw8RJdeVEpdUK6OkRnJYa7uyqD4hEBPcDXm2lxobryolLqhBRUNdPQ2smsBA3objUnKYLtxbXY7cbdVVFKjVFdHaIa0N1sdkI4Da2dFNU0u7sqSqkxamdJHX7eXkydOHaGKrrymIA+0/EXdVeJLqWrlBqcncV1nBQfip/P2AyNY7PWvciYGIKvt7DrkObRlVIDZ7cbdpWM3Q5R8KCA7u/jzdSJobqmi1JqUAqqm2loG7sdouBBAR2sm17sKqnDGO0YVUoNTNew51mO9aHGIs8K6Alh1DR3sDq7jGxNvSil+sEYwyc55WwtrMXPx4uMiSHurtKgecTU/y4zHJdK3392MwD5953vzuoopcaADXnVXP/kJgDmJo2Nm0Efy9iteS9OigvDdR2dTpvdfZVRSo16drthf3mD8/HsMdwhCh4W0AP9vJkS2325NP3Xq3l6Xb77KqSUGrXaOm2k/eId7n4j27lt5hjuEAUPC+gAl81PdC5I395p59ersvt4hVJqPDpQ3uj8OSEikDmJ4azIiHZjjU6cxwX075+azvM3LHU+jgjS+4wqpY6293B3qiUtJpg3bl5OfHigG2t04jwuoAP4+Xhx/ux4AGqbO6hr7nBzjZRSo83eUmtWeXigLzetTHdzbYaGRwZ0gIe+Pp8nr1sEwD6XTg+llALYW9rArIRwtv/6Kywf46mWLh4b0AGmxVkL7Owt1YCulOppz+EGZ4zwFB4d0OPDAwgN8GGfBnSllIvKxjYqG9vI1IA+dogI0yaGkqMBXSnlYl+ZFRO0hT7GTI0LJaesQdd3UUo5dV21Txuj654fi8cH9My4UOpaOiirb3N3VZRSo0ROWSMRQb7EhPq7uypDyuMDetedR3LKNO2ilLLsK2tg2sRQRKTvnccQjw/oXZdUOaV6JyOllLW64r5SzxvhAuMgoE8I9iM21J+c0sa+d1ZKebxDda00tHWO2fuGHo/HB3SwerL3acpFKYVLh6i20MemaROtgG6z60gXpca7rv60qbEa0MekaXGhtHXaKaxudndVlFJutq+0gbiwAMI9cOG+cRPQQTtGlVJWC32qB6ZboJ8BXUTOEZEcETkgInceZ7/LRcSIyMKhq+KJy4gNRQTtGFVqnLPZDfvLG5k2hu8bejx9BnQR8QYeAs4FpgPXiMj0XvYLBW4DvhzqSp6oQD9vJkcGkVOmLXSlxrOCqibaO+0eOcIF+tdCXwwcMMbkGWPagReAi3vZ717gT0DrENZvyEyL0zVdlBrvcjx4hAv0L6AnAEUuj4sd25xEZD6QZIx5ewjrNqSmTQwlv6qZ1g6bu6uilHKTnLIGRKw0rCc64U5REfEC/hv4WT/2vVFEskQkq6Ki4kSLHpBpcWHY7KbHfQSVUuPLvrIGJkcGEejn7e6qDIv+BPQSIMnlcaJjW5dQYCbwqYjkA0uBVb11jBpjHjXGLDTGLIyJiRl8rQdhqqMTZL/evUipcSuntMFj8+fQv4C+CcgQkVQR8QOuBlZ1PWmMqTPGRBtjUowxKcAG4CJjTNaw1HiQUqKD8fES9pdpC12p8ai1w0Z+VbPH5s+hHwHdGNMJ3AysBvYALxljskXkHhG5aLgrOFR8vb1IjQ5mQ14Vz24o0PXRlRpHHl+TR+av3sNmNx7dQvfpz07GmHeAd47Ydvcx9j3txKs1PKZODOXtnYfZUljL0rQopsR65lhUpVRP97271/nzuG6he5KECYHOn7VzVKnxY1JE93c/JSrYjTUZXv1qoXuKOYkRzp9zKzSgK+XpWtptrMutpKS2hchgP86ZGYefj+e2Yz33yHpx3qw41t15BvHhATz4fg4/fWmbu6uklBpGj3yey3efzsJmN/z6wun84dJZ7q7SsBpXAV1EmBQRyOSoIOwGXttSQnN7p7urpZQaJmX13RPXx0Of2bgK6F1cl0XPq2hyX0WUUsOquKbF+XN6jAZ0j3T3BdM5fZo1sSmvUgO6Up4qt7yRS+ZOYu+95xDg65mzQ12Ny4A+MyGcf3xzASLWB66U8jzN7Z0cqmslPSZkXARzGKcBHSDA15uEiEBtoSvlobrSqenjIHfeZdwGdIC0mBDydPiiUh6pa2jyeMiddxnXAT09JpiDlU26DIBSHii3ogkRmBwV5O6qjJhxHdDTYkJobrdRWj8q78mhlDoBeRWNJE0IGjf5cxjnAT092poCnFuueXSlPE1uRRPpMZ47zb834zqgpzlya3mVmkdXypPY7YaDlY3O7/h4Ma4D+sQwf4L9vHVykVIe5lBdC60d9nHVIQrjPKCLCGkxIbpQl1IeJrdryKKmXMaXtJhgbaEr5WG6JgxqymWcSYsOoaS2hZZ2m7uropQaInmVjYQF+BAd4ufuqowoDeiOS7KDOmNUKY+RW95EWkwIIuLuqowoDeiOgK4jXZTyHLkVjeOuQxQ0oJMW7Ri6qHl0pTxCQ2sH5Q1tpMeOrw5R0IBOoJ9jkS4d6aKUR+hqnHU11saTcR/QwUq75GoLXSmP0JU+naIt9PEpLTqYvIpGXaRLKQ+QW96Et5eQHDn+ArqPuyswGqTFhNDUbqO8oY2JYQHuro5SahCMMay4/xOKa1pIjQ7Gz2f8tVfH3xH3oqs3fMkfPuKlTUVuro1SajAO17U67yGaGj3+WuegAR3oHroI8Pt39rixJkqpwXIdqdbaMT4nCmpAB+Jc0izx4ZpyUWqsKaltYVN+NQAzJoXx47OmurlG7qE5dMDLS/jtRTN47stC8quayKtoZHJUMN5e42uWmVJj1bL7PgYg1N+Ht25ZPu5miHbRFrrDtaek8O1TJtPaYeeMBz/j2Q0F7q6SUqofOmx258/tNvu4DeagAb0H16nCew7Xu7EmSqn+Kqjqzp2P187QLppyceEa0Csa2txYE6VUfx1w3ELytxfN4OzpE91cG/fSFrqLmFB//nrNPJakRupNL5QaI7q+q1csSGRSRKCba+NeGtCPcNGcSSxJjaSwupm2zvE59EmpsSS3vJH48ACC/TXhoAG9F+mxIdgNFFQ1u7sqSqk+HBinS+X2RgN6L7pOjq7bWCmlRidjDLnljUyJ1YAOGtB71dVTrnl0pUa30vpWmtpt4+5m0MfSr4AuIueISI6IHBCRO3t5/vsislNEtonIFyIyfeirOnKC/X2YFB6gS+oqNcrlOka4pGsLHehHQBcRb+Ah4FxgOnBNLwH7OWPMLGPMXOB+4L+HuqIjLT02hAOaclFqVDtQ3gDAFM2hA/1roS8GDhhj8owx7cALwMWuOxhjXGfhBANjfmHx9JgQcnWNdKVGtdyKJkIDfIgJ9Xd3VUaF/ozzSQBc15QtBpYcuZOI/Aj4KeAHnDEktXOj9JhgmtttlNa3Eh8+vse2KjVaHSi3RriM5+n+roasU9QY85AxJh24A/jP3vYRkRtFJEtEsioqKoaq6GHRPdJF8+hKjVa5FTrCxVV/AnoJkOTyONGx7VheAC7p7QljzKPGmIXGmIUxMTH9rqQ7dJ0kOtJFqdGpvrWD8oY2HYPuoj8BfROQISKpIuIHXA2sct1BRDJcHp4P7B+6KrpHTKg/of4+GtCVGqW65oloC71bnzl0Y0yniNwMrAa8gSeMMdkicg+QZYxZBdwsImcBHUANcO1wVnokiAhpsSEa0JUapbpGoekY9G79WvzAGPMO8M4R2+52+fm2Ia7XqJAeE8y6A1XuroZSqhe5FU34egvJkUHursqooTNFjyM9JoTS+lYa2zrdXRWl1BEOlDeSEhWMj7eGsS76mzgOXdNFqdErTxflOooG9OOYEqtruig12uwqqeOmf2WRV9mkHaJH0IB+HMmR1o2iswpq2FxQ7e7qKKWAP767h9XZZQCkx2qHqCsN6Mfh5+PF5MggnvuykMv/sV5veKGUmzW3d+LnkjOfEhPqxtqMPhrQ+5AwoXvaf36l3vBCKXfZXFDN9LtX80lO9yzzNB2y2IMG9D502roX5/rzB/t4Zn2++yqj1DjmOoT4G0uSeer6RXrbuSNoQO/D3RdO55rF1soH72WXcvcb2boCo1JuUFjdfYW8NC2K06bFurE2o5MG9D6cFB/GHy+b3WNbeUObm2qj1Pi1t7TB+fPUiZo7741erwzC7kP1TAwLcHc1lBo3Om12csoa+N7yVK5alESGBvReaQu9n568bhE3rUwDYPfh+j72VkoNpYOVTbR32jkpPkyD+XFoC72fTs+M5fTMWN7LLmX3IQ3oSo2kXYfqAJiVGO7mmoxu2kIfoOnxYWQ7Ti6l1MjYUVxHoK+3TvXvgwb0AZoeH0Z+VbMu2KXUCNpZXMeMSWF4e+mt5o5HA/oATZ8UBsBezaMrNSJsdkP2oXpmJmi6pS8a0AeoK6Brx6hSIyO3opGWDhuzNX/eJw3oAxQXFsCEIF+ySzSgKzUSdhRbfVYa0PumAX2ARISZCeHsLNGOUaVGwq6SOoL8vEmN1g7RvmhAH4RZCeHsK2ugtUNXX1RquO0ormXmpHDtEO0HDeiDMDsxgk67YY/m0ZUaNutzq8gpbWD3Ye0Q7S+dWDQIXbm8HcV1zEmMwMtLaGm3Eejn7eaaKeUZ7HbDD/5vM8F+PrR22DV/3k/aQh+E+PAAokP8WbO/krn3vM9/rc5h1m9Ws7NY8+pKDYW8ykZqmzsoqW0BdIZof2lAHwQRYXZiOB/tLaO+tZNHPs+l0274NKfc3VVTyiNsLqhx/hzi70NqlN7Ioj805TJIsxLC+XivFcA7HDfB2Jiv9x1V6kSs2n6I7JI6aprb8fUWOmyGGZPC8NIO0X7RgD5Ic5KOvgTcXFBDp82Oj7de+Cg1GE98cZCdJXVMighgRUYMB8obWT4l2t3VGjM08gzSrIQIADJirbGxi1MjaW63ka0rMSo1KI1tnewsqcNmNxRVt7Bg8gQ+/Omp/Oj0Ke6u2pihAX2QYkL9uf/y2Tz27YX8+sLp3HfZLAA2HtS0i1IDsb2oliv+sY7P91Vgs3ff3nHB5An4+XhpumUANOVyAq5cZN1r9ProVABSo4P58mA1NzhuhPHerlLaOm1cPDfBbXVUarR7bUsxWQU1tHba8PESwgJ9qWvpYE5ihLurNuZoQB9Ci1MieS+7FLvd4OUlPLB6L3UtHVw4e5K2MpQ6hi8OVAKwq6SeBZMnMDkqiLL6Vp3XMQga0IfQ4tRIXswqYl95A/FhgeRWNAGwp7SeGZN0HK1SRzpc1+L8ngAsTYvkJ2dNxRznNerYNIc+hBanRgJWHn1bca1z++f7Kt1UI6VGt7UHqgCY5rhP6NK0KHy8vfDVkWKDor+1IZQ4IZD48AA2Hqxma2ENIjA5Kog1+yvcXTWlRqW1ByqJCvbjhpVpRAX7sWDyBHdXaUzTlMsQEhEWp0ayLreK+tZOpsaGcuq0GJ5am09zeydBfvrrVuPb3z89wIxJ4XgJzEmK4IsDlZwyJZorFiRy2bwE7Ws6QdpCH2JL06KoaGhjfW4l85IjWJERTbvNzpd51nBGYwyf5JT3GJ6l1HhQ3dTOA6tzuPuNXXzrnxu569WdVDS0sXxKFIAG8yGgAX2Idc1q67AZ5idPYFFKJP4+Xny2z0q7bC+u4/onN/HalmJ3VlOpEffZvnKMgYKqZgDe3nkYgGU6E3TIaEAfYkmRQSRHBgEwLzmCAF9vlqRFOfPohx2rx3WdzEp5KmN6XoV+tOfoxetSooJInBA0UlXyeP0K6CJyjojkiMgBEbmzl+d/KiK7RWSHiHwkIpOHvqpjxxmZsUSH+JEeYy0LsDIjmtyKJkpqW6hobAPgi/2V1Da3u7OaSg2bN7cfYuHvPqS5vROADpudz/ZVcMHseAJ8vUiKDAS0dT7U+gzoIuINPAScC0wHrhGR6UfsthVYaIyZDbwC3D/UFR1L7jgnk7duWeHMCa6cGgPA5/sqqGiwAnqn3fB+dpnb6qjUcHpy7UGqmto5XNcKWAvXNbR2csHsSbx583Ke+95S4sMDuGD2JDfX1LP0p4W+GDhgjMkzxrQDLwAXu+5gjPnEGNPseLgBSBzaao4tgX7exIUHOB9nxIYwKTyAT/aWU9nYRnSIP8mRQbw1iLTLh7vL+M2q7F4uZ8uoa+k44bordTyFVc2808d5e6C8kS2FtQBUNVpXoR/vLcfXW1ieEU3GxFCSIoNYf9eZnJweNdxVHlf6E9ATgCKXx8WObcfyXeDdE6mUpxERzjxpImv2V1Jc00JMqD/nzYpn3YFKapp6pl3e3XmYzQXHXuDr2S8LeGpdfo8bANQ2t/Pdp7O4/729w3YManxp7bBx07+y2HTEGv93vb6Dm5/bQlNbJ/e+tZu/fbT/qNe+6tLhX93UhjGGD3aXsTQtihB/Hbo7nIa0U1REvgksBB44xvM3ikiWiGRVVIyvyTZnnhRLS4eNdblVxIT6c/6seCvtsrvUuY8xhrte38nPXtqO3W6w2Q2Pr8lztryNMWwrqgXgibUHna8rd6RxXttSoq10NSClda28vePoFvcb20pYnV3GS5u623I7i+tYe6AKu7E69Z9Ye5DXtpb0eJ3NbnhtSzEzJoUBUNnYzt7SBg5WNnHOzLjhPRjVr4BeAiS5PE50bOtBRM4CfglcZIxp6+2NjDGPGmMWGmMWxsTEDKa+Y9bJ6VEE+3ljsxtiQvyZmRBmpV1cvkxl9W3UNneQX9XMR3vL2VxQw+/e3sM/Ps0FIL+qmdrmDhIiAnlvVylF1VaWqysv39Jh4+WsoqMLV+oYfvtmNj96bgtVjd1fWWMMj6+xGgzr86qc2x/5PJcAXytk/P7tPRgD+VVNtLTbnPt8vq+Csvo2bnSsOFrd1M67Ow/jJfCV6RrQh1t/AvomIENEUkXED7gaWOW6g4jMAx7BCuZ6Y81e+Pt4syLD+iMWE+qPiFhpl9wqKhvbeGrtQa57ciMAvt7CP7/IY2+pdbOM574soKmtk62FVprld5fORER4el0+AJWOL2N8eADPrC84atLSH9/dww//b/NIHKYaQwqrmlmdbV0h7ijpvsH5p/sq2F/eyPzkCIprWiiqbnbmzq89OYXoEH/qWqyGhTFwxcPr+GC31cH/7IYCokP8OXdmPKEBPlQ1tvHurlIWp0YSE+rvluMcT/oM6MaYTuBmYDWwB3jJGJMtIveIyEWO3R4AQoCXRWSbiKw6xtuNa2eeFAvgPLEvmTcJm93w5vZD/ObN3ewtbQDgppXpbMir5vWtJfh4CfWtnby6pZhtRbUE+3mzMiOG82bF8+KmIhrbOp0t9FvPzKCwuvmom1W/u7OUd3aWssvxpa1r6cCuM1U92oHyBj7p46blT6w9iLeXIAI7iroD+mOf5xEXFsA9F88EYENeFY9/kYe3l/Cd5anMTLDSKfdeMgOA7EP1/OTFbRTXNPNxTjlXL0rCz8eL6BB/vjxYzf7yRs6bFT9MR6pc9SuHbox5xxgz1RiTboz5vWPb3caYVY6fzzLGTDTGzHX8u+j47zg+nT19IjMTwljoWIAoMy6MGZPCeGFjzzTJDSvTCPbzZmthLfMnT2BuUgRPfHGQrPwa5iRF4O0lfHd5Kg1tnbycVURFQxt+3l5csSCRuLAAnnK03Lvyo4WO1MyTa/Np7bCx4k8f84/Pckf02NXI+vkrO/jR/23pcbVW1djGyvs/4ZOccuqaO3gpq4iL5iSQHhPCDsfqoLtK6liXW8V1y1KYHh9GZLAf7+w8zEtZRVw6L4GJYQHctDKd31w4ndOmxjrfOzzQl+c3FiLANUuSAYgM9nM2Ur46Q9MtI0Fnio6giCA/3rplBXOSIpzbLpufSE5Zg/PxpfMSCA/05WsLrW6LzLhQvrs8lfyqZnYfrmeu47VzkyJYMHkCT67Np6y+lZhQf3y9vfjm0mTW7K/kQHkjt72wlR89twWAqRNDeHP7IT7bV0F9aydPrs2nvdM+YseuhkdD69FXW7tK6thaWEtzu43NBTXOjvJnNxRSWN3MZzkV/N/GAprbbXx3eSqzE8PZXlzryJ3nEeznzTWLk/HyEpamRfJJTgWtHXZnXvzk9CiuW5aKl5dw25kZJEQEcriuhRc3FXFGZiwJEdakoahgPwAWTp7AxLAA1PDTgO5mF82ZhLdjAtLaO8/gz1fNBeA7y1IJ8PViweQJnDszzvklmZfcvbzod5alUljdzL+3HSI6xPryXL04GT9vL55Zn+9smQP88bLZtNvs3PPmbsDKu7+76zBbCmtYdt/HFNc083JWET94dvNRY9xf2lREeX3rsP0O1OCUN7Sy9A8f8fymwh7bn1mf7zynrnxkPZc+tJa2Thv/2lAAwNbCGp5el8/yKdFMnxTGnMQIKhvb2VJYw1s7DnPVomTCA30BODnNGid+1kkTmRIbelQdfnL2VO46LxO7sUa0fGNp9yTxKMc5ea6mW0aMBnQ3iwn15/RpMUSH+DPJZTJSclQQG395FhfNmYSPtxc3rEjF38eL+ckRzn2+OmOiM9B35eWjQ/y5cM4kXt1cTLVjjHt0iLXO9BmZsZTUthAd4k9adDBPrcvn4z3llNS28Mz6Al7bUsK7u0pZn9s9siG/son/eHUH96/OGYHfhhqI578soqndxtoD3TdQqWlq541th7hyYffcvrzKJt7YeojKxjYy40LZXlxHWX0b31th3Qt3dqJ1N607Xt2JAa5fluJ87RknTSQ1Opjbzsw4Zj26bk6RFBnIqRndo9diQq3zWYcrjhwN6KPAfZfP5vkbliDSc/nQsABf57ZrT0lhw11nEhXSPVLAx9uL7y63vpTFNS3O7dedkkJTu422TjsPXDGbtXeeAXR/UeckhvOtkyeztbDWuerjCxsLnXnUrhw84JzAtGr7oR5D29TI+ecXBznljx/1SJF12Ow8t7GrxV3r3P7y5iLaOu1ce0oKoS6TeB54P4dpE0P5juN8yYgN4VTHkhQnxYfh6y0cKG/k3JlxJEV2L5aVEBHIJ7efxqzEY99CMSU6mISIQG5cmd5jCdxvLZ3MU9cvcjY61PDTgD4KRIf4kzHx6MtZVyLCBEdO0tVVi6xc+2XzuyfvzkoMd7bkZydG4O9j3Wx3+ZRoLp2XwOULErl8QSJBft4cqmvlpPgw6ls7aWq3kRodzId7yiiusdI1Wwpr8PPxor3TzgubdIz7SOu02bn3rd0cqmt1DmMF+GB3GWX1bSybEsXhulYO17XQabPz9LoClqRGkhkXxtu3ruAvV88FrLkK31mewsLJExCBm05NdzYWAny9yYyzRq7csCJtwHX09fbiiztO51tLe67JFxPqz2nTYo/xKjUcNKCPccH+Phz4/bncuDK9x/bbvzqNr86YSHpMsHObiPDnq+Zy3qx4wgJ8uXy+dVl+3SmTmR5vfaF/7xjj3pVv3VJYy5LUSJZPiebZDQV02Hp2pL6947BzX1fl9a1c9+RG5+QndXz5lU3O4aeu3t3VPZPYtSX+zPp8EiIC+enZ0wDYVljLh3vKKKlt4fplVis8OSqI82fFE+jrTVSwHxfPTSAtJoR1d57BFQt6Lrd05cJErl6U1KPDfiCOvLpU7qEB3QP49HJD3VPSo3nkWwt7fa7LDSvSWJIayWnTYrnz3EwunZfAyWlRfGX6RF7cVERVYxs5pfXMS4rg2lNSOFzXetQKkX/7eD+/XZV9VODeUljDpzkV3PPW7qE5yGHU0m5jXW4lTW2dbim/rrmDS/6+ll/9e1eP7cYYHv4sl7ToYGJC/Z0Ty3aV1LEhr5pvnTyZWQnh+Pl4sbWolifXWkH+7OkTne/h4+3FLWdO4e4LpxPga12pxYcfnQL51skp3Hf57GE8SjUSNKCPY8lRQbx408lMDAtg5dQY/nzVXESEa09Joba5g3vf2o3dwDxHh2pSZKBzdipAY1snOWUNdNrNUePaKxyr7H2wu8x5t6Yj2eyGu9/Y5QxUw6W2uZ3a5nZaO2zUNXdQUNXE5/sqePizXL739Cbm3/sBX3/syx59B/1V0dDGY5/n0Wk79hDQDpudhz/L7bUFDtZ9NmubO8gqqOkxwmjN/kqyD9Xz/VPTWTh5gnMFw8dchhb6+XgxY1IYq7Yd4suD1Vx7ymTnCJcuPzxtChfPPd56espT6NJn6ihWDjaUf287BMD8pAl4ewnfXprC79/Zw87iOmYlhrOjqBZjYEpsCK9kFXPLGVOcrb+uDtSUqCB+uyqb9368Ej+fnu2H/eUNPLO+gLd3HOaNm5f1eeeahtYOvvbwepZPieb2r05ztjiPZ29pPef8z5pjPp8aHczlCxL4cHe5cyZtf1U2tvH1xzawv7yRGQlhnJLe+80aHnx/Hw9/lktTWyc/+8q0Hs8V1zTz5Lp8IoJ8qWxs41Bdq7MT8R+f5hIXFsDF8yZR29LOu7tK2Vlcx1s7DnPdKSnOoYXzkiawtfAggb7eXLUweUDHoDyLttDVUbpa6QDpMcGEB1mB46rFSYQG+PCPzw4AsNWx8uP/XDUXuzH8/ZPuVnplYxsTgnz59YUzyKts4ql1BznSzmIrgDa0dXLDM5udd7c5lh3FdewtbeDxLw5y3l/WHHeZ4S5deeefnDWVn391Gr+6YDoPXDGbF29cyub/PItPbj+N310yi3nJEc5Zjf1R3tDKNx//0jnW/1h/DLLyq3lsTR4AuRWNRz3/4Pv7EOC+y2YBVi4crJTV+rwqvrciFX8fb+f8g9tf3g70HFo4z9EBftn8BOdnpcYnDeiqV5fMTSAy2I+lad03IAgL8OXak1N4d1cpB8ob2FJQQ3pMMDMTwrlyURLPbywkv7IJgMqGdqJC/Dk9M5YzM2P5y4f7Kalt6VHGrpI6gv28efib89lbWs/tL28/atbjnsP17D5kje7IPmQFzf/9+jzaOu1c/o/13PbCVgqqmo55HDmlDQT5eXPLGVP40elT+O7yVL62MIklaVE9hoBmxoWRX9XU5x8VgLyKRi7/xzoKqpp54jprWN6ukvqj9qttbufW57eSEBHIqVNj2Hiwmlc3Fzun4+8qqeP1rSVcvyyV0zNj8fP2Yrtj6OiD7+cQFezHNYutFveshHB8vIScsgbOnxXf42pm5dQYzp8Vz/dPTT+qDmp80YCuehXo5827t63gF+ed1GP79ctSCPDx5u+f5rK1qNbZcvzxmRn4envxwPvWBKSqpjbn7NXfXDQDu4Ffvr6zR454Z0kdMyaFc0bmRO46N5N3dpbyh3f29Njn1ue3cvFDX/BSVhG7D9U7b1u2+icr+cFp6azOLuXMBz/jrtd2kNNLC3t/eQMZE0N7jI/uTWZ8KMbAdU9uOu6a8lsLa7ji4fU0t9l44calLJsSbeWwtx/i649tcAZrYwz/8coOKhrb+N+vz2PZlCgqG9v52cvbWbO/Arvd8Ns3s4kI8uUHp6Xj7+PN9ElhbCusZV1uJWsPVPHD06cQ7BhLHuBrPQ9HDy0MD/TloW/M7zF+XI1PGtDVMU0MC3AGlC5RIf5csziZ17eWUN3U7rzcjw0L4IaVaby94zBbC2uobGwn2tECTooM4udfncanORW84cjLd9rs7D5cz8wEa8LKDSvSuPbkyTz+xUFnB2tzeycHKhoJ8PHmP17Zwbu7Sp3DK0P8fbjjnEw+//npXL04iVe3lPDV//mcSx5ay2Of57GvrAG73ZBT2si0iSF9HussRz02HqxmtctQwS7GGF7cVMhVj24gxN+HV39winOI37Q4aw7ButwqDjquUJ5ZX8D7u8u445xMZidGMCcxwvle2YfqeTGriE35Nfzi3JOcufC5SRHsLKnjgdU5xIcH8I0lPfPhX1+czLdPnnzcST5qfNOArgbshpWp+DhavPOSuteWuXFlGtEh/tzz1m4qG9qcAR2sma7zkiP4zZvZlNW3klvRRGuHnVmJVoAWEX594QwumjOJ+9/L4fmNhewtbcAY+NMVs/nGkmTaOu3MdgmMYP0h+d0ls/jyrjO569xMOmx2fv/OHr7y58+Z8st3qGxsY2ofk7YAJkUE8uFPT0WEo3LpLe02fv7KDu54dSeLUyJ5/YenkBLdPb7/msXJnONYTTD7UB0b8qq4963dnJEZ65zJuzg1kieuW0hCRCCf5pTzx3f2sCQ1kq+5TNGfmxRBS4eNrYW13HJGxlGdvlcvTnYuaatUb3SUixqw+PBArlqUxLs7S5nq0voN8ffhznMznR13XSkXAG8v4b++Nofz/7qG21/ezkVzrLu9d7WMAbwc+9S3dvCL13dyiuMGwrMTwzl3ZhwXzZl0zNbphGA/bjo1nZtOTaeoupkvD1aztbCGQ7UtnHXSxF5fc6QpsSHMTgjvMSNzc0E1P39lBwcrm7jtzAxuPTPjqGGBkyIC+dvX5zHj16t5b1cpG/KqSI4Kcg4DBesP1hmZE3l98iHe3H4IP28v/nDZrB4TcrpW0kyODOoR6JXqLw3oalB+feEMfnLW1KMmLl02L4FnNxSwrai2RwsdID0mhF+eP51f/XsXa/ZXEuTnTWp0z3SIn48XD39zAT94djOf5FQQHuhLQkQgIsKStP7dIT4pMoikyKCjZkP2R2ZcGB/sKeNQbQt/+XA/L20uYlJ4IP/6zhKWZ/Q+LBGs6e8nxYXy7q5SwgN9+ee1i5ypFFezE8J5c/shfnT6FNJjeh775KggLp2XwCXzEvA9zoQwpY5FA7oaFF9vrx6jRLp4eQn3XDyDbzz2JZmOfLerby5J5tO95Xy0t5xgf5+jWrtgdQA+8q2F3P3GLsICfUd0Wvm0uFBezCritAc+Bawlin9y9tR+3a1+dmIEuw7V89DX55PqkpJxdcm8BNo6bdyw8ug1U7qWZlBqsOTIta9HysKFC01WVpZbylbDz243xxxZUtfcwcUPfcGVi5L44WlTRrhmx7f7UD2X/n0tF86ZxI/PyuhzspOr6qZ2SmpatNNSDSsR2WyMWdjrcxrQlTsYY3RBJ6UG4XgBXRN1yi00mCs19DSgK6WUh9CArpRSHkIDulJKeQgN6Eop5SE0oCullIfQgK6UUh5CA7pSSnkIt00sEpEGIKeXp8KB3m7/MtDtvT0XDVQO8DUDLaerjIHW7UTKdy2zv68Z7HH69lLWUHw2x9ve1+c21Mc50N/niZZ/ZHkjcZzRQMcAXzPY8ns7Z4ajnJH+rruWdazf5VCW07U9zhjT+xKixhi3/AOyjrH90aHY3ttzXWUO5DUDLcf1uIaynD7ea0C/yxM5zt7KGorP5njb+/rchuE4h+Tc7O9rjixvJI4TyBrO71pf58xwH+dIfNf787scyd+nMWZUplzeHKLtnvaa473XQMsYbDnj5bNxd/mj9TXuLn8wr3F3+SP5GremXLLMMdYjGMtleupxuaMsd5Xp6eWNdJl6fCNXnjtb6I96aJmeelzuKMtdZXp6eSNdph7fCJXntha6UkqpoTUac+hKKaUGQQO6Ukp5iGEP6CLSONxluJRlE5FtLv9SjrPvpyIy4I4METEi8qzLYx8RqRCRtwZZ7f6We4mj7MxhLMMtx+ZS3oidK/0tc7DnyRHvMeyfXS9l/lJEskVkh+O7sGSYy0sUkTdEZL+I5IrIX0TE7zj7/1hE+n87qJ6vNSLyoMvj20XkN4N5r36W1xVXskVku4j8TERGZWN4VFbqBLQYY+a6/MsfhjKagJkiEuh4fDZQMpA3EJHB3Mv1GuALx/8DKct7ALuf8LGpXg3qsxssETkZuACYb4yZDZwFFA1jeQK8BvzbGJMBTAVCgN8f52U/BgYV0IE24DIROfZdu4dWV1yZgfWdOBf49QiVPSAjEtBFJEREPhKRLSKyU0QudmxPEZE9IvKY46/f+y7BZKjKXiAin4nIZhFZLSLxLk9/y/GXd5eILB7A274DnO/4+RrgeZfyFovIehHZKiLrRGSaY/t1IrJKRD4GPhrgMYQAy4HvAlc7tp0mIp+LyNsikiMiD3e1GkSkUUQeFJHtwMkDKWuQx/a5iMx12e8LEZkzwHK7Xnua6xWBiPyviFzn+DlfRH7rch4NSYv3eGUOwXsf67M71jGeJyJ7HefrXwd5dRQPVBpj2gCMMZXGmEPH+i44rkL+MsjvAsAZQKsx5klHeTbgJ8B3RCRYRP7L8b47ROQWEbkVmAR8IiKfDOL4OrFGevzkyCccMeVjR1kfiUiyiISLSIHL9yNYRIpExHegBRtjyoEbgZvF4i0iD4jIJkeZN7nU5Q7HebpdRO4bxHEO2Ei10FuBS40x84HTgQcdf9UBMoCHHH/9aoHLT6CcQOlOt7zu+MD+BlxhjFkAPEHPVkOQMWYu8EPHc/31AnC1iAQAs4EvXZ7bC6wwxswD7gb+4PLcfEddTh3gcV0MvGeM2QdUicgCx/bFwC3AdCAduMyxPRj40hgzxxjzxQDLGsyx/RO4DkBEpgIBxpjtAyy3vyod59E/gNuHqYyhdKzP7iiO3/kjwLmO8zVmkGW+DySJyD4R+buInDqM3wWAGcBm1w3GmHqgEPgekALMdVwt/J8x5q/AIeB0Y8zpAz46y0PAN0TkyDty/w14uqss4K/GmDpgG9D1vbsAWG2M6RhMwcaYPMAbiMX6Q11njFkELAJuEJFUETkX67NfYoyZA9w/mLIGajCX/oMhwB9EZCVgBxKAiY7nDhpjtjl+3oz14Q9Wi+OktAoVmQnMBD5w/P3wBg677P88gDHmcxEJE5EIY0xtX4UYY3aIlZ+/BqtF6yoceFpEMgCDtY5Flw+MMdUDPShHOX9x/PyC4/FbwEbHyYWIPI/VEnwFsAGvDqKcwR7by8CvROTnwHeApwZTdj+95vh/M91/wEazY312vckE8owxBx2Pn8dqDQ6IMabR8YdjBVYD6kXgdwzDd6EfTgP+bozpdLz/YM7/oxhj6kXkGeBWoMXlqZPpPi/+RXcgfRG4CvgE60rp70NRD+ArwGwRucLxOByrkXoW8KQxptlR3yE57r6MVED/BlZrY4ExpkNE8oEAx3NtLvvZgKFMuQiQbYw5VtrhyEH4AxmUvwr4L6wTNspl+73AJ8aYSx2B8VOX55oG8P4AiEgk1iXtLBExWF9EA7zdS327Hrc6LnsHa0DHZoxpFpEPsFokVwLHbIX2Qyc9rxwDjni+63yxMXTnb19lDspxPrs3hqM8V47P/1PgUxHZCfyI4fsu7AaucN0gImFAMpA/gPcZqP8BtgBP9mPfVViNykis8/PjwRYqImlY5185Voy5xRiz+oh9vjrY9z8RI5VyCQfKHcH8dGDyCJWbA8SI1UmEiPiKyAyX569ybF+Oddl0rJXPevME8FtjzM4jtofT3ZF43aBq3dMVwL+MMZONMSnGmCTgIFbra7Hj8s4L61gGml45lsEc2+PAX4FNxpiaEyi7AJguIv4iEgGceQLv5e4yj/XZeR2jvBwgTbpHZ101mEJFZJrjKqrLXGAPw/dd+AgIEpFvO97DG3gQ60ptNXCTOAYCOAIqQAPQ+4qB/eRo9b6Elfbosg5HXwVWQ3KNY99GYBPW1dJbg23wiEgM8DDwv8aalbka+EFXPl5EpopIMPABcL04RvK4HPewGtYWuuNDbMPKZb3paClkYeVih50xpt1xKfRXR67NB+uverZjl1YR2YqVOvjOAN+7GCuAHel+rLTEf2K1ok/UNcCfjtj2KvADrBP0f4EpWJeSrw9BeYM6NmPMZhGpp3+tpaN0nSvGmCIReQnYhRX8tg7m/UZJmcf67K7GCkQ9yjPGtIjID4H3RKQJ6/MdjBDgb44/Fp3AAazUzaMMz3fBiMilwN9F5FdYf7DeAX6B1ZKdCuwQkQ7gMaxz9lHHcR46gTw6WH84bnZ5fAvwpCP9VwFc7/Lci1jpwdMGWEagiGzD+t10YqVy/tvx3ONYaeItjn7BCuASY8x7Yg0UyBKRdrp/H8NqWKf+izXS4TFjzEB7zVUfROQ04HZjzAVurgoAIjIJ6xI/0xhjH8TrR/xcGY3np4iEOHLggtXxt98Y8+dhLvNTrHMpazjLUcNv2FIuIvJ9rI6W/xyuMtTo4LjU/hL45SCD+YifK6P4/LzB0RrMxkpxPeLe6qixRBfnUkopDzFkLXQRSRKRT0Rkt1iThG5zbI8UkQ/EmhL8gYhMcGzPFGuSSpuI3H7Ee90m1kSEbBH58VDVUSmlPNlQplw6gZ8ZY6YDS4Efich04E7gI8eU4I8cjwGqscaQ/pfrmzjGjt+ANWlmDnCBiEwZwnoqpZRHGrKAbow5bIzZ4vi5AWuYVALW2OSnHbs9DVzi2KfcGLMJ6+aqrk7CmuXY7JiM8BljYwKJUkq51bB0ijrG0c7D6iibaIzpmpFWSvcM0WPZBawQkSjHGM7zgKThqKdSSnmSIR+HLtZiRK8CP3ZMz3U+5xivetxeWGPMHhH5E9Z6FE1YazCcyKxHpZQaF4a0he6YLfUq1gI8XWtulEn3qm7xWNNlj8sY809jzAJjzEqgBtg3lPVUSilPNJSjXARr1b09xpj/dnlqFXCt4+drsdax6Ou9Yh3/J2Plz58bqnoqpZSnGrJx6I41INYAO7FWVARrquuXWNOck7HWzLjSGFMtInFYywCEOfZvBKY70jRrsBaF6gB+aowZ0PrhSik1HunEIqWU8hCedgs6pZQatzSgK6WUh9CArpRSHkIDulJKeQgN6Eop5SE0oCullIfQgK6UUh5CA7pSSnmI/wejiBy44aCO9AAAAABJRU5ErkJggg==\n", + "image/png": "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\n", "text/plain": [ "
" ] @@ -451,7 +458,9 @@ } ], "source": [ - "df['shaded_fraction'].resample('1d').mean().plot()" + "ax = df.loc[df['elevation']>0, 'shaded_fraction'].resample('1d').mean().plot()\n", + "ax.set_ylabel('Daily average shading fraction')\n", + "ax.set_ylim(0, None)" ] }, { diff --git a/twoaxistracking/plotting.py b/twoaxistracking/plotting.py index 368d818..6d58832 100644 --- a/twoaxistracking/plotting.py +++ b/twoaxistracking/plotting.py @@ -7,10 +7,10 @@ def _plot_field_layout(X, Y, Z, min_tracker_spacing): - """Plot field layout.""" + """Create a plot of the field layout.""" # Collector heights is illustrated with colors from a colormap norm = mcolors.Normalize(vmin=min(Z)-0.000001, vmax=max(Z)+0.000001) - # 0.000001 is added/subtracted for the limits in order for the colormap + # 0.000001 is added/subtracted to/from the limits in order for the colormap # to correctly display the middle color when all tracker Z coords are zero cmap = cm.viridis_r colors = cmap(norm(Z)) @@ -25,14 +25,13 @@ def _plot_field_layout(X, Y, Z, min_tracker_spacing): widths=min_tracker_spacing, heights=min_tracker_spacing, angles=0, units='xy', facecolors='red', edgecolors=("black",), linewidths=(1,), offsets=[0, 0], transOffset=ax.transData)) - plt.axis('equal') fig.colorbar(cm.ScalarMappable(norm=norm, cmap=cmap), ax=ax, shrink=0.8, label='Relative tracker height (vertical)') # Set limits lower_lim = min(min(X), min(Y)) - min_tracker_spacing upper_lim = max(max(X), max(Y)) + min_tracker_spacing - ax.set_ylim(lower_lim, upper_lim) ax.set_xlim(lower_lim, upper_lim) + ax.set_ylim(lower_lim, upper_lim) return fig From 82116a735357729435bb063ca54ee4d9d6091e6b Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Sun, 27 Feb 2022 17:50:19 +0100 Subject: [PATCH 23/48] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 077a455..8dc3b23 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,8 @@ The main non-standard dependency is `shapely`, which handles the geometric opera The solar modeling library `pvlib` is recommended for calculating the solar position and can be installed by the command: + pip install pvlib + ## Citing If you use the package in published work, please cite: > Adam R. Jensen et al. 2022. From 86cf94735830002659a5c2a95ff690916a6748c7 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Sun, 27 Feb 2022 15:49:17 +0100 Subject: [PATCH 24/48] Create test_layout.py --- test/test_layout.py | 115 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 test/test_layout.py diff --git a/test/test_layout.py b/test/test_layout.py new file mode 100644 index 0000000..42e2335 --- /dev/null +++ b/test/test_layout.py @@ -0,0 +1,115 @@ +from twoaxistracking import layout +from shapely import geometry +import numpy as np +import pytest + + +@pytest.fixture +def rectangular_geometry(): + collector_geometry = geometry.box(-2, -1, 2, 1) + total_collector_area = collector_geometry.area + l_min = layout._calculate_l_min(collector_geometry) + return collector_geometry, total_collector_area, l_min + + +def test_l_min_rectangle(rectangular_geometry): + # Test calculation of L_min for a rectangular collector + l_min = layout._calculate_l_min(rectangular_geometry[0]) + assert l_min == np.sqrt(4**2+2**2) + + +def test_l_min_circle(): + # Test calculation of L_min for a circular collector with radius 1 + collector_geometry = geometry.Point(0, 0).buffer(1) + l_min = layout._calculate_l_min(collector_geometry) + assert l_min == 2 + + +def test_l_min_circle_offcenter(): + # Test calculation of L_min for a circular collector with radius 1 rotating + # off-center around the point (0, 1) + collector_geometry = geometry.Point(0, 1).buffer(1) + l_min = layout._calculate_l_min(collector_geometry) + assert l_min == 4 + + +def test_l_min_polygon(): + # Test calculation of L_min for a polygon + collector_geometry = geometry.Polygon([(-1, -1), (3, 2), (4, 4), (1, 2), (-1, -1)]) + l_min = layout._calculate_l_min(collector_geometry) + assert l_min == 2 * np.sqrt(4**2 + 4**2) + + +def test_square_layout_generation(rectangular_geometry): + # Test square field layout defined using tje built-in layout types + collector_geometry, total_collector_area, L_min = rectangular_geometry + + X, Y, Z, tracker_distance, relative_azimuth, relative_slope = \ + layout.generate_field_layout( + gcr=0.25, total_collector_area=total_collector_area, L_min=L_min, + neighbor_order=1, layout_type='square', + slope_azimuth=0, slope_tilt=0, plot=False) + assert np.isclose(X, np.array([-5.65685425, 0, 5.65685425, -5.65685425, + 5.65685425, -5.65685425, 0, 5.65685425]) + ).all() + + +def test_layout_generation_value_error(rectangular_geometry): + # Test if value errors are correctly raised + collector_geometry, total_collector_area, L_min = rectangular_geometry + + # Test if ValueError is raised when an incorrect layout_type is specified + with pytest.raises(ValueError, match="layout type specified was not recognized"): + _ = layout.generate_field_layout( + gcr=0.25, total_collector_area=total_collector_area, L_min=L_min, + neighbor_order=1, layout_type='this_is_not_a_layout_type') + + # Test if ValueError is raised if too few layout parameters are specified + with pytest.raises(ValueError, match="no layout type has not been selected"): + _ = layout.generate_field_layout( + gcr=0.25, total_collector_area=total_collector_area, L_min=L_min, + neighbor_order=1, rotation=0) + + # Test if ValueError is raised if offset is out of range + with pytest.raises(ValueError, match="offset is outside the valid range"): + _ = layout.generate_field_layout( + gcr=0.25, total_collector_area=total_collector_area, L_min=L_min, + neighbor_order=1, rotation=0, offset=1.1, aspect_ratio=1) + + # Test if ValueError is raised if aspect ratio is too low + with pytest.raises(ValueError, match="Aspect ratio is too low"): + _ = layout.generate_field_layout( + gcr=0.25, total_collector_area=total_collector_area, L_min=L_min, + neighbor_order=1, rotation=0, offset=0, aspect_ratio=0.6) + + # Test if ValueError is raised if aspect ratio is too high + with pytest.raises(ValueError, match="Aspect ratio is too high"): + _ = layout.generate_field_layout( + gcr=0.25, total_collector_area=total_collector_area, L_min=L_min, + neighbor_order=1, rotation=0, offset=0, aspect_ratio=5) + + # Test if ValueError is raised if rotation is outside valid range + with pytest.raises(ValueError, match="rotation is outside the valid range"): + _ = layout.generate_field_layout( + gcr=0.25, total_collector_area=total_collector_area, L_min=L_min, + neighbor_order=1, rotation=190, offset=0, aspect_ratio=1.2) + + # Test if ValueError is raised if L_min is outside valid range + with pytest.raises(ValueError, match="Lmin is not physically possible"): + _ = layout.generate_field_layout( + gcr=0.25, total_collector_area=total_collector_area, L_min=1, + neighbor_order=1, rotation=90, offset=0, aspect_ratio=1.2) + + # Test if ValueError is raised if rotation is outside valid range + with pytest.raises(ValueError, match="Maximum ground cover ratio exceded"): + _ = layout.generate_field_layout( + gcr=0.5, total_collector_area=total_collector_area, L_min=L_min, + neighbor_order=1, rotation=0, offset=0, aspect_ratio=1) + +# Test custom layout +# Test slope +# Test neighbor order + +# Inputs (0, negative numbers) +# All types of inputs, e.g., scalars, numpy array and series, list +# Test coverage From 8f5098e55d7bff75d858464d3bad5a3521592d7e Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Sun, 27 Feb 2022 17:16:13 +0100 Subject: [PATCH 25/48] Update test_layout.py --- test/test_layout.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/test/test_layout.py b/test/test_layout.py index 42e2335..fcac3d9 100644 --- a/test/test_layout.py +++ b/test/test_layout.py @@ -12,6 +12,18 @@ def rectangular_geometry(): return collector_geometry, total_collector_area, l_min +@pytest.fixture +def square_field_layout(): + # Corresponds to GCR 0.125 with the rectangular_geometry + X = np.array([-8., 0., 8., -8., 8., -8., 0., 8.]) + Y = np.array([-8., -8., -8., 0., 0., 8., 8., 8.]) + tracker_distance = (X**2 + Y**2)**0.5 + relative_azimuth = np.array([225., 180., 135., 270., 90., 315., 0., 45.]) + Z = np.zeros(8) + relative_slope = np.zeros(8) + return X, Y, Z, tracker_distance, relative_azimuth, relative_slope + + def test_l_min_rectangle(rectangular_geometry): # Test calculation of L_min for a rectangular collector l_min = layout._calculate_l_min(rectangular_geometry[0]) @@ -106,6 +118,21 @@ def test_layout_generation_value_error(rectangular_geometry): gcr=0.5, total_collector_area=total_collector_area, L_min=L_min, neighbor_order=1, rotation=0, offset=0, aspect_ratio=1) + +def test_square_field_layout(rectangular_geometry, square_field_layout): + # Test that a square field layout is returned correctly + collector_geometry, total_collector_area, L_min = rectangular_geometry + X_exp, Y_exp, Z_exp, tracker_distance_exp, relative_azimuth_exp, relative_slope_exp = \ + square_field_layout + + X, Y, Z, tracker_distance, relative_azimuth, relative_slope = \ + layout.generate_field_layout( + gcr=0.125, + total_collector_area=total_collector_area, + L_min=L_min, + neighbor_order=1, + layout_type='square') + # Test custom layout # Test slope # Test neighbor order From 2f0ef348f62d0162ffe5f0201412f4a25bac1c9b Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Sun, 27 Feb 2022 17:16:56 +0100 Subject: [PATCH 26/48] Use test folder in package folder --- {test => twoaxistracking/tests}/test_layout.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {test => twoaxistracking/tests}/test_layout.py (100%) diff --git a/test/test_layout.py b/twoaxistracking/tests/test_layout.py similarity index 100% rename from test/test_layout.py rename to twoaxistracking/tests/test_layout.py From 49e3ac7a8b462eb5119f0dbc45631fbb3b84b65a Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Sun, 27 Feb 2022 17:17:09 +0100 Subject: [PATCH 27/48] Delete test_placeholder.py --- twoaxistracking/tests/test_placeholder.py | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 twoaxistracking/tests/test_placeholder.py diff --git a/twoaxistracking/tests/test_placeholder.py b/twoaxistracking/tests/test_placeholder.py deleted file mode 100644 index 8acf64e..0000000 --- a/twoaxistracking/tests/test_placeholder.py +++ /dev/null @@ -1,6 +0,0 @@ -import pytest # noqa: F401 -import twoaxistracking # noqa: F401 - - -def test_placeholder(): - pass From 18c65491093e5cf02af88132dc144ffec0e92116 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Mon, 28 Feb 2022 00:02:13 +0100 Subject: [PATCH 28/48] Add test files --- twoaxistracking/tests/test_layout.py | 148 +++++++------ twoaxistracking/tests/test_plotting.py | 52 +++++ twoaxistracking/tests/test_shading.py | 125 +++++++++++ .../tests/test_twoaxistrackerfield.py | 200 ++++++++++++++++++ 4 files changed, 457 insertions(+), 68 deletions(-) create mode 100644 twoaxistracking/tests/test_plotting.py create mode 100644 twoaxistracking/tests/test_shading.py create mode 100644 twoaxistracking/tests/test_twoaxistrackerfield.py diff --git a/twoaxistracking/tests/test_layout.py b/twoaxistracking/tests/test_layout.py index fcac3d9..751a170 100644 --- a/twoaxistracking/tests/test_layout.py +++ b/twoaxistracking/tests/test_layout.py @@ -1,4 +1,4 @@ -from twoaxistracking import layout +from twoaxistracking import layout, twoaxistrackerfield from shapely import geometry import numpy as np import pytest @@ -8,132 +8,144 @@ def rectangular_geometry(): collector_geometry = geometry.box(-2, -1, 2, 1) total_collector_area = collector_geometry.area - l_min = layout._calculate_l_min(collector_geometry) - return collector_geometry, total_collector_area, l_min + min_tracker_spacing = layout._calculate_min_tracker_spacing(collector_geometry) + return collector_geometry, total_collector_area, min_tracker_spacing @pytest.fixture def square_field_layout(): # Corresponds to GCR 0.125 with the rectangular_geometry - X = np.array([-8., 0., 8., -8., 8., -8., 0., 8.]) - Y = np.array([-8., -8., -8., 0., 0., 8., 8., 8.]) + X = np.array([-8, 0, 8, -8, 8, -8, 0, 8]) + Y = np.array([-8, -8, -8, 0, 0, 8, 8, 8]) tracker_distance = (X**2 + Y**2)**0.5 - relative_azimuth = np.array([225., 180., 135., 270., 90., 315., 0., 45.]) + relative_azimuth = np.array([225, 180, 135, 270, 90, 315, 0, 45]) Z = np.zeros(8) relative_slope = np.zeros(8) return X, Y, Z, tracker_distance, relative_azimuth, relative_slope -def test_l_min_rectangle(rectangular_geometry): - # Test calculation of L_min for a rectangular collector - l_min = layout._calculate_l_min(rectangular_geometry[0]) - assert l_min == np.sqrt(4**2+2**2) +def test_min_tracker_spacing_rectangle(rectangular_geometry): + # Test calculation of min_tracker_spacing for a rectangular collector + min_tracker_spacing = layout._calculate_min_tracker_spacing(rectangular_geometry[0]) + assert min_tracker_spacing == np.sqrt(4**2+2**2) -def test_l_min_circle(): - # Test calculation of L_min for a circular collector with radius 1 +def test_min_tracker_spacing_circle(): + # Test calculation of min_tracker_spacing for a circular collector with radius 1 collector_geometry = geometry.Point(0, 0).buffer(1) - l_min = layout._calculate_l_min(collector_geometry) - assert l_min == 2 + min_tracker_spacing = layout._calculate_min_tracker_spacing(collector_geometry) + assert min_tracker_spacing == 2 -def test_l_min_circle_offcenter(): - # Test calculation of L_min for a circular collector with radius 1 rotating +def test_min_tracker_spacing_circle_offcenter(): + # Test calculation of min_tracker_spacing for a circular collector with radius 1 rotating # off-center around the point (0, 1) collector_geometry = geometry.Point(0, 1).buffer(1) - l_min = layout._calculate_l_min(collector_geometry) - assert l_min == 4 + min_tracker_spacing = layout._calculate_min_tracker_spacing(collector_geometry) + assert min_tracker_spacing == 4 -def test_l_min_polygon(): - # Test calculation of L_min for a polygon +def test_min_tracker_spacingpolygon(): + # Test calculation of min_tracker_spacing for a polygon collector_geometry = geometry.Polygon([(-1, -1), (3, 2), (4, 4), (1, 2), (-1, -1)]) - l_min = layout._calculate_l_min(collector_geometry) - assert l_min == 2 * np.sqrt(4**2 + 4**2) + min_tracker_spacing = layout._calculate_min_tracker_spacing(collector_geometry) + assert min_tracker_spacing == 2 * np.sqrt(4**2 + 4**2) -def test_square_layout_generation(rectangular_geometry): - # Test square field layout defined using tje built-in layout types - collector_geometry, total_collector_area, L_min = rectangular_geometry +def test_square_layout_generation(rectangular_geometry, square_field_layout): + # Test that a square field layout is returned correctly + collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry + X_exp, Y_exp, Z_exp, tracker_distance_exp, relative_azimuth_exp, relative_slope_exp = \ + square_field_layout X, Y, Z, tracker_distance, relative_azimuth, relative_slope = \ layout.generate_field_layout( - gcr=0.25, total_collector_area=total_collector_area, L_min=L_min, - neighbor_order=1, layout_type='square', - slope_azimuth=0, slope_tilt=0, plot=False) - assert np.isclose(X, np.array([-5.65685425, 0, 5.65685425, -5.65685425, - 5.65685425, -5.65685425, 0, 5.65685425]) - ).all() + gcr=0.125, + total_collector_area=total_collector_area, + min_tracker_spacing=min_tracker_spacing, + neighbor_order=1, + aspect_ratio=1, + offset=0, + rotation=0) + assert (X == X_exp).all() + assert (Y == Y_exp).all() + assert (Z == Z_exp).all() + assert (tracker_distance_exp == tracker_distance_exp).all() + assert (relative_azimuth == relative_azimuth_exp).all() + assert (relative_slope == relative_slope_exp).all() def test_layout_generation_value_error(rectangular_geometry): # Test if value errors are correctly raised - collector_geometry, total_collector_area, L_min = rectangular_geometry - - # Test if ValueError is raised when an incorrect layout_type is specified - with pytest.raises(ValueError, match="layout type specified was not recognized"): - _ = layout.generate_field_layout( - gcr=0.25, total_collector_area=total_collector_area, L_min=L_min, - neighbor_order=1, layout_type='this_is_not_a_layout_type') - - # Test if ValueError is raised if too few layout parameters are specified - with pytest.raises(ValueError, match="no layout type has not been selected"): - _ = layout.generate_field_layout( - gcr=0.25, total_collector_area=total_collector_area, L_min=L_min, - neighbor_order=1, rotation=0) + collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry # Test if ValueError is raised if offset is out of range with pytest.raises(ValueError, match="offset is outside the valid range"): _ = layout.generate_field_layout( - gcr=0.25, total_collector_area=total_collector_area, L_min=L_min, - neighbor_order=1, rotation=0, offset=1.1, aspect_ratio=1) + gcr=0.25, total_collector_area=total_collector_area, + min_tracker_spacing=min_tracker_spacing, neighbor_order=1, + aspect_ratio=1, offset=1.1, rotation=0) # Test if ValueError is raised if aspect ratio is too low with pytest.raises(ValueError, match="Aspect ratio is too low"): _ = layout.generate_field_layout( - gcr=0.25, total_collector_area=total_collector_area, L_min=L_min, - neighbor_order=1, rotation=0, offset=0, aspect_ratio=0.6) + gcr=0.25, total_collector_area=total_collector_area, + min_tracker_spacing=min_tracker_spacing, neighbor_order=1, + aspect_ratio=0.6, offset=0, rotation=0) # Test if ValueError is raised if aspect ratio is too high with pytest.raises(ValueError, match="Aspect ratio is too high"): _ = layout.generate_field_layout( - gcr=0.25, total_collector_area=total_collector_area, L_min=L_min, - neighbor_order=1, rotation=0, offset=0, aspect_ratio=5) + gcr=0.25, total_collector_area=total_collector_area, + min_tracker_spacing=min_tracker_spacing, neighbor_order=1, + aspect_ratio=5, offset=0, rotation=0) - # Test if ValueError is raised if rotation is outside valid range + # Test if ValueError is raised if rotation is greater than 180 degrees with pytest.raises(ValueError, match="rotation is outside the valid range"): _ = layout.generate_field_layout( - gcr=0.25, total_collector_area=total_collector_area, L_min=L_min, - neighbor_order=1, rotation=190, offset=0, aspect_ratio=1.2) + gcr=0.25, total_collector_area=total_collector_area, + min_tracker_spacing=min_tracker_spacing, neighbor_order=1, + aspect_ratio=1.2, offset=0, rotation=190) - # Test if ValueError is raised if L_min is outside valid range + # Test if ValueError is raised if rotation is less than 0 + with pytest.raises(ValueError, match="rotation is outside the valid range"): + _ = layout.generate_field_layout( + gcr=0.5, total_collector_area=total_collector_area, + min_tracker_spacing=min_tracker_spacing, neighbor_order=1, + aspect_ratio=1, offset=0, rotation=-1) + + # Test if ValueError is raised if min_tracker_spacing is outside valid range with pytest.raises(ValueError, match="Lmin is not physically possible"): _ = layout.generate_field_layout( - gcr=0.25, total_collector_area=total_collector_area, L_min=1, - neighbor_order=1, rotation=90, offset=0, aspect_ratio=1.2) + gcr=0.25, total_collector_area=total_collector_area, + min_tracker_spacing=1, neighbor_order=1, aspect_ratio=1.2, + offset=0, rotation=90) - # Test if ValueError is raised if rotation is outside valid range + # Test if ValueError is raised if maximum ground cover ratio is exceeded with pytest.raises(ValueError, match="Maximum ground cover ratio exceded"): _ = layout.generate_field_layout( - gcr=0.5, total_collector_area=total_collector_area, L_min=L_min, - neighbor_order=1, rotation=0, offset=0, aspect_ratio=1) + gcr=0.5, total_collector_area=total_collector_area, + min_tracker_spacing=min_tracker_spacing, neighbor_order=1, + aspect_ratio=1, offset=0, rotation=0) -def test_square_field_layout(rectangular_geometry, square_field_layout): - # Test that a square field layout is returned correctly - collector_geometry, total_collector_area, L_min = rectangular_geometry - X_exp, Y_exp, Z_exp, tracker_distance_exp, relative_azimuth_exp, relative_slope_exp = \ - square_field_layout +def test_field_slope(): + assert True + +def test_neighbor_order(rectangular_geometry): + collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry X, Y, Z, tracker_distance, relative_azimuth, relative_slope = \ layout.generate_field_layout( gcr=0.125, total_collector_area=total_collector_area, - L_min=L_min, - neighbor_order=1, - layout_type='square') + min_tracker_spacing=min_tracker_spacing, + neighbor_order=3, + aspect_ratio=1, + offset=0, + rotation=0) + assert len(X) == (7*7-1) -# Test custom layout # Test slope # Test neighbor order diff --git a/twoaxistracking/tests/test_plotting.py b/twoaxistracking/tests/test_plotting.py new file mode 100644 index 0000000..3f00224 --- /dev/null +++ b/twoaxistracking/tests/test_plotting.py @@ -0,0 +1,52 @@ +import matplotlib.pyplot as plt +from twoaxistracking import plotting, layout, twoaxistrackerfield +from shapely import geometry +import numpy as np +import pytest + + +def assert_isinstance(obj, klass): + assert isinstance(obj, klass), f'got {type(obj)}, expected {klass}' + + +def test_field_layout_plot(): + X = np.array([-8, 0, 8, -8, 8, -8, 0, 8]) + Y = np.array([-8, -8, -8, 0, 0, 8, 8, 8]) + Z = np.array([0.1237, 0.0619, 0, 0.0619, -0.0619, 0, -0.0619, -0.1237]) + L_min = 4.4721 + result = plotting._plot_field_layout(X, Y, Z, L_min) + assert_isinstance(result, plt.Figure) + plt.close('all') + + +@pytest.fixture +def rectangular_geometry(): + collector_geometry = geometry.box(-2, -1, 2, 1) + total_collector_area = collector_geometry.area + min_tracker_spacing = layout._calculate_min_tracker_spacing(collector_geometry) + return collector_geometry, total_collector_area, min_tracker_spacing + + +def test_shading_plot(rectangular_geometry): + collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry + result = plotting._plot_shading(collector_geometry, collector_geometry, + collector_geometry, min_tracker_spacing) + assert_isinstance(result, plt.Figure) + plt.close('all') + + +def test_plotting_of_field_layout(rectangular_geometry): + # Test if plot_field_layout returns a figure object + collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry + field = twoaxistrackerfield.TwoAxisTrackerField( + total_collector_geometry=collector_geometry, + active_collector_geometry=collector_geometry, + neighbor_order=1, + gcr=0.25, + aspect_ratio=1, + offset=0.45, + rotation=30, + ) + result = field.plot_field_layout() + assert_isinstance(result, plt.Figure) + plt.close('all') diff --git a/twoaxistracking/tests/test_shading.py b/twoaxistracking/tests/test_shading.py new file mode 100644 index 0000000..0755ed6 --- /dev/null +++ b/twoaxistracking/tests/test_shading.py @@ -0,0 +1,125 @@ +from twoaxistracking import shading, layout +from shapely import geometry +import numpy as np +import pytest + + +@pytest.fixture +def rectangular_geometry(): + collector_geometry = geometry.box(-2, -1, 2, 1) + total_collector_area = collector_geometry.area + min_tracker_spacing = layout._calculate_min_tracker_spacing(collector_geometry) + return collector_geometry, total_collector_area, min_tracker_spacing + + +@pytest.fixture +def square_field_layout(): + # Corresponds to GCR 0.125 with the rectangular_geometry + X = np.array([-8, 0, 8, -8, 8, -8, 0, 8]) + Y = np.array([-8, -8, -8, 0, 0, 8, 8, 8]) + tracker_distance = (X**2 + Y**2)**0.5 + relative_azimuth = np.array([225, 180, 135, 270, 90, 315, 0, 45]) + Z = np.zeros(8) + relative_slope = np.zeros(8) + return X, Y, Z, tracker_distance, relative_azimuth, relative_slope + + +def test_shading(rectangular_geometry, square_field_layout): + # Test shading when geometries completly overlap + # Also plots the geometry (ensures no errors occurs) + collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry + X, Y, Z, tracker_distance, relative_azimuth, relative_slope = \ + square_field_layout + shaded_fraction = shading.shaded_fraction( + solar_elevation=3, + solar_azimuth=120, + total_collector_geometry=collector_geometry, + active_collector_geometry=collector_geometry, + min_tracker_spacing=min_tracker_spacing, + tracker_distance=tracker_distance, + relative_azimuth=relative_azimuth, + relative_slope=relative_slope, + slope_azimuth=0, + slope_tilt=0, + plot=True) + assert np.isclose(shaded_fraction, 0.191324) + + +def test_shading_zero_solar_elevation(rectangular_geometry, square_field_layout): + collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry + X, Y, Z, tracker_distance, relative_azimuth, relative_slope = \ + square_field_layout + # Test shading when geometries completly overlap + shaded_fraction = shading.shaded_fraction( + solar_elevation=0, + solar_azimuth=180, + total_collector_geometry=collector_geometry, + active_collector_geometry=collector_geometry, + min_tracker_spacing=min_tracker_spacing, + tracker_distance=tracker_distance, + relative_azimuth=relative_azimuth, + relative_slope=relative_slope, + slope_azimuth=0, + slope_tilt=0, + plot=False) + assert shaded_fraction == 1 + + +def test_no_shading(rectangular_geometry, square_field_layout): + # Test shading calculation when there is no shading (high solar elevation) + collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry + X, Y, Z, tracker_distance, relative_azimuth, relative_slope = \ + square_field_layout + shaded_fraction = shading.shaded_fraction( + solar_elevation=45, + solar_azimuth=180, + total_collector_geometry=collector_geometry, + active_collector_geometry=collector_geometry, + min_tracker_spacing=min_tracker_spacing, + tracker_distance=tracker_distance, + relative_azimuth=relative_azimuth, + relative_slope=relative_slope, + slope_azimuth=0, + slope_tilt=0, + plot=False) + assert shaded_fraction == 0 + + +def test_shading_below_horizon(rectangular_geometry, square_field_layout): + # Test shading calculation when sun is below the horizon (elevation<0) + collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry + X, Y, Z, tracker_distance, relative_azimuth, relative_slope = \ + square_field_layout + shaded_fraction = shading.shaded_fraction( + solar_elevation=-5.1, + solar_azimuth=180, + total_collector_geometry=collector_geometry, + active_collector_geometry=collector_geometry, + min_tracker_spacing=min_tracker_spacing, + tracker_distance=tracker_distance, + relative_azimuth=relative_azimuth, + relative_slope=relative_slope, + slope_azimuth=0, + slope_tilt=0, + plot=False) + assert np.isnan(shaded_fraction) + + +def test_shading_below_hill_horizon(rectangular_geometry, square_field_layout): + # Test shading calculation when there is no shading (high solar elevation) + collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry + X, Y, Z, tracker_distance, relative_azimuth, relative_slope = \ + square_field_layout + shaded_fraction = shading.shaded_fraction( + solar_elevation=9, + solar_azimuth=180, + total_collector_geometry=collector_geometry, + active_collector_geometry=collector_geometry, + min_tracker_spacing=min_tracker_spacing, + tracker_distance=tracker_distance, + relative_azimuth=relative_azimuth, + relative_slope=relative_slope, + slope_azimuth=0, + slope_tilt=10, + plot=False) + assert shaded_fraction == 1 diff --git a/twoaxistracking/tests/test_twoaxistrackerfield.py b/twoaxistracking/tests/test_twoaxistrackerfield.py new file mode 100644 index 0000000..b0b8792 --- /dev/null +++ b/twoaxistracking/tests/test_twoaxistrackerfield.py @@ -0,0 +1,200 @@ +from twoaxistracking import layout, twoaxistrackerfield +from shapely import geometry +import numpy as np +import pandas as pd +import pytest + + +@pytest.fixture +def rectangular_geometry(): + collector_geometry = geometry.box(-2, -1, 2, 1) + total_collector_area = collector_geometry.area + min_tracker_spacing = layout._calculate_min_tracker_spacing(collector_geometry) + return collector_geometry, total_collector_area, min_tracker_spacing + + +def test_invalid_layout_type(rectangular_geometry): + # Test if ValueError is raised when an incorrect layout_type is specified + collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry + with pytest.raises(ValueError, match="Layout type must be one of"): + _ = twoaxistrackerfield.TwoAxisTrackerField( + total_collector_geometry=collector_geometry, + active_collector_geometry=collector_geometry, + neighbor_order=1, + gcr=0.25, + layout_type='this_is_not_a_layout_type') + + +def test_square_layout_type(rectangular_geometry): + # Assert that layout field parameters are correctly set for the square layout + collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry + field = twoaxistrackerfield.TwoAxisTrackerField( + total_collector_geometry=collector_geometry, + active_collector_geometry=collector_geometry, + neighbor_order=2, + gcr=0.25, + layout_type='square') + assert field.gcr == 0.25 + assert field.aspect_ratio == 1 + assert field.offset == 0 + assert field.rotation == 0 + + +def test_diagonal_layout_type(rectangular_geometry): + # Assert that layout field parameters are correctly set for the diagonal layout + collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry + field = twoaxistrackerfield.TwoAxisTrackerField( + total_collector_geometry=collector_geometry, + active_collector_geometry=collector_geometry, + neighbor_order=2, + gcr=0.1, + layout_type='diagonal') + assert field.gcr == 0.1 + assert field.aspect_ratio == 1 + assert field.offset == 0 + assert field.rotation == 45 + + +def test_hexagonal_n_s_layout_type(rectangular_geometry): + # Assert that layout field parameters are correctly set for the diagonal layout + collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry + field = twoaxistrackerfield.TwoAxisTrackerField( + total_collector_geometry=collector_geometry, + active_collector_geometry=collector_geometry, + neighbor_order=4, + gcr=0.4, + layout_type='hexagonal_n_s') + assert field.gcr == 0.4 + assert field.aspect_ratio == np.sqrt(3)/2 + assert field.offset == -0.5 + assert field.rotation == 0 + + +def test_hexagonal_e_w_layout_type(rectangular_geometry): + # Assert that layout field parameters are correctly set for the diagonal layout + collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry + field = twoaxistrackerfield.TwoAxisTrackerField( + total_collector_geometry=collector_geometry, + active_collector_geometry=collector_geometry, + neighbor_order=4, + gcr=0.4, + layout_type='hexagonal_e_w') + assert field.gcr == 0.4 + assert field.aspect_ratio == np.sqrt(3)/2 + assert field.offset == -0.5 + assert field.rotation == 90 + + +def test_unspecifed_layout_type(rectangular_geometry): + # Test if ValueError is raised when one or more layout parameters are unspecified + collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry + with pytest.raises(ValueError, match="needs to be specified"): + _ = twoaxistrackerfield.TwoAxisTrackerField( + total_collector_geometry=collector_geometry, + active_collector_geometry=collector_geometry, + neighbor_order=1, + gcr=0.25, + aspect_ratio=1, + offset=0, + # rotation unspecified + ) + + +@pytest.fixture +def solar_position(): + solar_elevation = [-1, 0, 1, 2, 40] + solar_azimuth = [90, 100, 110, 120, 180] + return solar_elevation, solar_azimuth + + +@pytest.fixture +def expected_shaded_fraction(): + return [np.nan, 1.0, 0.71775, 0.60360, 0.0] + + +def is_close_with_nans(test, expected): + return (np.isclose(test, expected) | (np.isnan(test) & + (np.isnan(test) == np.isnan(expected)))).all() + + +def test_calculation_of_shaded_fraction_list(rectangular_geometry, solar_position, + expected_shaded_fraction): + # Test if shaded fraction is calculated correct when solar elevation and + # azimuth are lists + collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry + field = twoaxistrackerfield.TwoAxisTrackerField( + total_collector_geometry=collector_geometry, + active_collector_geometry=collector_geometry, + neighbor_order=1, + gcr=0.25, + aspect_ratio=1, + offset=0, + rotation=170) + solar_elevation, solar_azimuth = solar_position + result = field.get_shaded_fraction(solar_elevation, solar_azimuth) + # Test that calculated shaded fraction are equal or both nan + # using np.isclose(np.nan, np.nan) does not identify + assert is_close_with_nans(result, expected_shaded_fraction) + assert isinstance(result, list) + + +def test_calculation_of_shaded_fraction_series(rectangular_geometry, solar_position, + expected_shaded_fraction): + # Test if shaded fraction is calculated correct when solar elevation and + # azimuth are pandas Series + collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry + field = twoaxistrackerfield.TwoAxisTrackerField( + total_collector_geometry=collector_geometry, + active_collector_geometry=collector_geometry, + neighbor_order=1, + gcr=0.25, + aspect_ratio=1, + offset=0, + rotation=170) + solar_elevation, solar_azimuth = solar_position + result = field.get_shaded_fraction(pd.Series(solar_elevation), pd.Series(solar_azimuth)) + # Test that calculated shaded fraction are equal or both nan + # using np.isclose(np.nan, np.nan) does not identify + assert is_close_with_nans(result, expected_shaded_fraction) + assert isinstance(result, pd.Series) + + +def test_calculation_of_shaded_fraction_array(rectangular_geometry, solar_position, + expected_shaded_fraction): + # Test if shaded fraction is calculated correct when solar elevation and + # azimuth are pandas Series + collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry + field = twoaxistrackerfield.TwoAxisTrackerField( + total_collector_geometry=collector_geometry, + active_collector_geometry=collector_geometry, + neighbor_order=1, + gcr=0.25, + aspect_ratio=1, + offset=0, + rotation=170) + solar_elevation, solar_azimuth = solar_position + result = field.get_shaded_fraction(np.array(solar_elevation), np.array(solar_azimuth)) + # Test that calculated shaded fraction are equal or both nan + # using np.isclose(np.nan, np.nan) does not identify + assert is_close_with_nans(result, expected_shaded_fraction) + assert isinstance(result, np.ndarray) + + +def test_calculation_of_shaded_fraction_float(rectangular_geometry, solar_position): + # Test if shaded fraction is calculated correct when solar elevation and + # azimuth are pandas Series + collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry + field = twoaxistrackerfield.TwoAxisTrackerField( + total_collector_geometry=collector_geometry, + active_collector_geometry=collector_geometry, + neighbor_order=1, + gcr=0.25, + aspect_ratio=1, + offset=0, + rotation=170) + solar_elevation, solar_azimuth = solar_position + result = field.get_shaded_fraction(40, 180) + # Test that calculated shaded fraction are equal or both nan + # using np.isclose(np.nan, np.nan) does not identify + assert result == 0 + assert isinstance(result, np.ndarray) From 057e3aafc3cada830131ceb0bf01da1e17ad67c0 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Mon, 28 Feb 2022 10:21:17 +0100 Subject: [PATCH 29/48] Fix linting errors --- twoaxistracking/tests/test_layout.py | 2 +- twoaxistracking/tests/test_twoaxistrackerfield.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/twoaxistracking/tests/test_layout.py b/twoaxistracking/tests/test_layout.py index 751a170..5a1ad7e 100644 --- a/twoaxistracking/tests/test_layout.py +++ b/twoaxistracking/tests/test_layout.py @@ -1,4 +1,4 @@ -from twoaxistracking import layout, twoaxistrackerfield +from twoaxistracking import layout from shapely import geometry import numpy as np import pytest diff --git a/twoaxistracking/tests/test_twoaxistrackerfield.py b/twoaxistracking/tests/test_twoaxistrackerfield.py index b0b8792..5b82107 100644 --- a/twoaxistracking/tests/test_twoaxistrackerfield.py +++ b/twoaxistracking/tests/test_twoaxistrackerfield.py @@ -139,7 +139,7 @@ def test_calculation_of_shaded_fraction_list(rectangular_geometry, solar_positio def test_calculation_of_shaded_fraction_series(rectangular_geometry, solar_position, - expected_shaded_fraction): + expected_shaded_fraction): # Test if shaded fraction is calculated correct when solar elevation and # azimuth are pandas Series collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry From 901111a813bfd517d1b3056c0f08cac809afe248 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Mon, 28 Feb 2022 21:50:13 +0100 Subject: [PATCH 30/48] Update scalar test --- twoaxistracking/tests/test_twoaxistrackerfield.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/twoaxistracking/tests/test_twoaxistrackerfield.py b/twoaxistracking/tests/test_twoaxistrackerfield.py index 5b82107..a18ce82 100644 --- a/twoaxistracking/tests/test_twoaxistrackerfield.py +++ b/twoaxistracking/tests/test_twoaxistrackerfield.py @@ -197,4 +197,4 @@ def test_calculation_of_shaded_fraction_float(rectangular_geometry, solar_positi # Test that calculated shaded fraction are equal or both nan # using np.isclose(np.nan, np.nan) does not identify assert result == 0 - assert isinstance(result, np.ndarray) + assert np.isscalar(result) From 3e4994767babcbc25bbb4454632d00a26d31ff26 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Mon, 28 Feb 2022 22:16:02 +0100 Subject: [PATCH 31/48] Add pandas to test in setup.cfg --- setup.cfg | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.cfg b/setup.cfg index 20d2ef3..648022e 100644 --- a/setup.cfg +++ b/setup.cfg @@ -28,6 +28,7 @@ install_requires = test = pytest pytest-cov + pandas doc = sphinx==4.4.0 myst-nb==0.13.2 From bcf59084ceb4f6c3db90b19633f58fbce53dbb5c Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Mon, 28 Feb 2022 23:41:26 +0100 Subject: [PATCH 32/48] Revert "package metadata and doc build updates (#17)" This reverts commit e9b5810f72e0dd62c63c0915e27f910405f009fc. --- .readthedocs.yml | 17 +- README.md | 4 +- docs/environment.yml | 15 + docs/source/documentation.rst | 5 +- docs/source/notebooks/intro_tutorial.ipynb | 413 +++++++++--------- docs/source/whatsnew.md | 5 +- setup.cfg | 21 +- twoaxistracking/__init__.py | 2 +- twoaxistracking/layout.py | 81 +++- twoaxistracking/plotting.py | 38 +- twoaxistracking/shading.py | 23 +- twoaxistracking/tests/test_layout.py | 154 ------- twoaxistracking/tests/test_placeholder.py | 6 + twoaxistracking/tests/test_plotting.py | 52 --- twoaxistracking/tests/test_shading.py | 125 ------ .../tests/test_twoaxistrackerfield.py | 200 --------- twoaxistracking/twoaxistrackerfield.py | 182 -------- 17 files changed, 336 insertions(+), 1007 deletions(-) create mode 100644 docs/environment.yml delete mode 100644 twoaxistracking/tests/test_layout.py create mode 100644 twoaxistracking/tests/test_placeholder.py delete mode 100644 twoaxistracking/tests/test_plotting.py delete mode 100644 twoaxistracking/tests/test_shading.py delete mode 100644 twoaxistracking/tests/test_twoaxistrackerfield.py delete mode 100644 twoaxistracking/twoaxistrackerfield.py diff --git a/.readthedocs.yml b/.readthedocs.yml index 2b0adf9..fb783c8 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -1,17 +1,18 @@ version: 2 +conda: + environment: docs/environment.yml build: - os: ubuntu-20.04 - tools: - python: "3.7" + image: latest +# This part is necessary otherwise the project is not built python: - # only use the packages specified in setup.py - system_packages: false - + version: 3.7 install: - method: pip path: . - extra_requirements: - - doc + +# By default readthedocs does not checkout git submodules +submodules: + include: all \ No newline at end of file diff --git a/README.md b/README.md index 8dc3b23..75b6509 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Open source code for calculating self-shading of two-axis tracking solar collectors -twoaxistracking is a python package for simulating two-axis tracking solar collectors, particularly self-shading. +"twoaxistracking" is a python package for simulating self-shading in fields of two-axis trackers. ## Documentation The documentation can be found at [readthedocs](https://twoaxistracking.readthedocs.io/). @@ -15,8 +15,6 @@ The main non-standard dependency is `shapely`, which handles the geometric opera The solar modeling library `pvlib` is recommended for calculating the solar position and can be installed by the command: - pip install pvlib - ## Citing If you use the package in published work, please cite: > Adam R. Jensen et al. 2022. diff --git a/docs/environment.yml b/docs/environment.yml new file mode 100644 index 0000000..5abc2b3 --- /dev/null +++ b/docs/environment.yml @@ -0,0 +1,15 @@ +name: readthedocs +channels: + - defaults + - conda-forge +dependencies: + - python=3.7 + - pandas + - matplotlib + - numpy + - shapely # Should be installed with conda + - sphinx + - pip: + - pvlib + - myst-nb + - sphinx-book-theme diff --git a/docs/source/documentation.rst b/docs/source/documentation.rst index e47a6bc..e019bb1 100644 --- a/docs/source/documentation.rst +++ b/docs/source/documentation.rst @@ -8,7 +8,4 @@ Code documentation :toctree: generated/ shaded_fraction - generate_field_layout - TwoAxisTrackerField - TwoAxisTrackerField.get_shaded_fraction - TwoAxisTrackerField.plot_field_layout + generate_field_layout \ No newline at end of file diff --git a/docs/source/notebooks/intro_tutorial.ipynb b/docs/source/notebooks/intro_tutorial.ipynb index d05e461..c111397 100644 --- a/docs/source/notebooks/intro_tutorial.ipynb +++ b/docs/source/notebooks/intro_tutorial.ipynb @@ -18,135 +18,29 @@ "outputs": [], "source": [ "import pandas as pd\n", + "# The following libraries are not standard and have to be installed seperately.\n", + "# It is recommended to install shapely using conda.\n", "from shapely import geometry\n", "import pvlib\n", "import twoaxistracking" ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Definition of collector geometry\n", - "\n", - "The first step is to define the collector geometry. Two geometries have to be created, one which represents the total collector area and one or more geometries representing the active collector area. The geometries can be created using the `shapely` library, e.g.:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "" - ], - "text/plain": [ - "" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# geometry.box(minx, miny, maxx, maxy)\n", - "total_collector_geometry = geometry.box(-1, -0.5, 1, 0.5)\n", - "\n", - "total_collector_geometry" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The active collector geometry can be made up of one or more polygons. In this example, the collector has eight active regions:" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "" - ], - "text/plain": [ - "" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "active_collector_geometry = geometry.MultiPolygon([\n", - " geometry.box(-0.95, -0.45, -0.55, -0.05),\n", - " geometry.box(-0.45, -0.45, -0.05, -0.05),\n", - " geometry.box(0.05, -0.45, 0.45, -0.05),\n", - " geometry.box(0.55, -0.45, 0.95, -0.05),\n", - " geometry.box(-0.95, 0.05, -0.55, 0.45),\n", - " geometry.box(-0.45, 0.05, -0.05, 0.45),\n", - " geometry.box(0.05, 0.05, 0.45, 0.45),\n", - " geometry.box(0.55, 0.05, 0.95, 0.45)])\n", - "\n", - "active_collector_geometry" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The collector geometries can be defined as any arbitrary polygon using the `shapely` library. However, it is important to note that the `total_collector_geometry` should completely enclose all of the active areas. Circular geometries can be created by: ``shapely.geometry.Point(x_0, y_0).buffer(radius)`` and are approximated as 64 sided polygons.\n", - "\n", - "Note, any unit of length can be used, though it is important to be consistent! Also, the absolute dimensions are generally not of importance, as the GCR parameter scales the distance between collectors according to the total collector area." - ] - }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", - "## Specification of collector field layout" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Once the collector geometry has been determined, the field layout can be defined. As previously mentioned, the ground cover ratio (GCR), which is the ratio of the collector are to the ground area, determines how close the trackers are arranged.\n", - "\n", - "### Neighbor order\n", - "Another required input is the ``neighbor_order``, which determines how many collectors to take into account. For a neighbor order of one the immidiate 8 neighboring collectors are considered, whereas for a neighbor order of two, 24 shading collectors are considered. It is recommended to use atleast a neighbor order of 2, though the computation time increases dramtically with increasing neighbor order.\n", - "\n", - "### Standard vs. custom field layouts\n", - "Any regularly-spaced field layout can be specified using the keywords: `aspect ratio`, `offset`, `rotation`, and `gcr`. For a description of the layout parameters, see the paper by [Cumpston and Pye (2014)](https://doi.org/10.1016/j.solener.2014.06.012) or check out the function documentation.\n", - "\n", - "\n", - "Furthermore, it is possible to choose from four different standard field layouts: `square`, `diagonal`, `hexagon_e_w`, and `hexagon_n_s`. These four layouts corresponds to a fixed set of aspect ratios, offsets, and rotations, and only require the user to specify the GCR.\n", - "\n", - "In the example below, a tracker field is created with a neighbor order of two, a ground cover ratio of 0.2, and a square field layout." + "Now, the first step is to define the location/site for where shading is to be calculated. The location is used to determine the solar position in the next steps." ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ - "tracker_field = twoaxistracking.TwoAxisTrackerField(\n", - " total_collector_geometry,\n", - " active_collector_geometry,\n", - " neighbor_order=2,\n", - " gcr=0.2,\n", - " layout_type='square'\n", - ")" + "location = pvlib.location.Location(latitude=54.9788, longitude=12.2666, altitude=100)" ] }, { @@ -155,110 +49,36 @@ "source": [ "
\n", "\n", - "The field layout can be visualized by the following command:" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "fig = tracker_field.plot_field_layout() " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "
\n", + "The second step involves deciding on the discrete time-steps for which shading shall be calculated. Generally the time series should cover one year (preferably not a leap year).\n", "\n", - "## Shading calculation\n", + "The most **important parameter is the frequency**, e.g., '1min', '15min', '1hr'.\n", "\n", - "The final step is to calculate the shaded fraction for the desired solar positions. The typical use case is to simulate shading for a specified period with a fixed interval, e.g., for a yearly simulation with a time-step of 15-minutes.\n", - "\n", - "To calculate the solar position,the discrete time-steps shall be first determined. The below code cell demonstrates how to generate a series of timestamps for one year with a 15-minute interval." + "It is also important to set the timezone as this affects the calculation of the solar position. It is recommended to consistently use UTC to avoid mix-ups." ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 3, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "DatetimeIndex(['2019-01-01 00:00:00+00:00', '2019-01-01 00:15:00+00:00',\n", - " '2019-01-01 00:30:00+00:00', '2019-01-01 00:45:00+00:00',\n", - " '2019-01-01 01:00:00+00:00'],\n", - " dtype='datetime64[ns, UTC]', freq='15T')" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "times = pd.date_range(\n", " start='2019-1-1 00:00',\n", " end='2019-12-31 23:59',\n", - " freq='15min',\n", - " tz='UTC')\n", - "\n", - "times[:5] # Show the first 5 timestamps" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "
\n", - "\n", - "It is also important to set the timezone corretly, as it affects the calculation of the solar position. It is recommended to consistently use UTC to avoid mix-ups." + " freq='15min', # Edit the frequecy for a shorter or longer time step\n", + " tz='UTC')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "
\n", - "\n", - "To calculate the solar position for the timestamps, it is recommended to use the [``pvlib`` library](http://pvlib-python.readthedocs.io/). A convient way to do this is first to create a location object for the location of interest. In this example, a two-axis tracker field in Lendemarke, Denmark is simulated:" + "Next, the solar position is calculated for all of the time time steps using the [`pvlib-python`](https://pvlib-python.readthedocs.io/en/stable/) package:" ] }, { "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [], - "source": [ - "location = pvlib.location.Location(latitude=54.9788, longitude=12.2666, altitude=100, name='Lendemarke, Denmark')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The location object can then be used to calculate the solar position for the timestamps:" - ] - }, - { - "cell_type": "code", - "execution_count": 8, + "execution_count": 4, "metadata": {}, "outputs": [ { @@ -356,7 +176,7 @@ "2019-01-01 01:00:00+00:00 -52.491152 42.334286 -3.215687 " ] }, - "execution_count": 8, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } @@ -371,18 +191,195 @@ "cell_type": "markdown", "metadata": {}, "source": [ + "## Define the collector aperture geometry\n", + "\n", + "In this step, the solar collector geometry is defined:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "image/svg+xml": [ + "" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Change these parameters to suit your particular collector aperture\n", + "collector_width = 5.697\n", + "collector_height = 3.075\n", + "\n", + "collector_geometry = geometry.box(\n", + " -collector_width/2, # left x-coordinate\n", + " -collector_height/2, # bottom y-coordinate\n", + " collector_width/2, # top y-coordinate\n", + " collector_height/2) # right x-coordinate\n", + "\n", + "collector_geometry" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Similarly, a cirular geometry can be defined as:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "image/svg+xml": [ + "" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "radius = 2\n", + "circular_collector = geometry.Point(0, 0).buffer(radius)\n", + "circular_collector" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "\n", + "Note, the absolute dimensions do not matter, as the GCR parameter scales the distance between collectors according to the collector area.\n", + "\n", "
\n", "\n", - "Now that the solar positions have been determined, the shaded fraction can be calculated by passing the solar positions to the function ``get_shaded_fraction``:" + "Derive properties from the collector geometry:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Collector area: 17.5\n", + "Collector L_min: 6.47\n" + ] + } + ], + "source": [ + "total_collector_area = collector_geometry.area\n", + "# Calculate the miminum distance between collectors\n", + "# Note, L_min is also referred to as D_min by some authors\n", + "L_min = 2 * collector_geometry.hausdorff_distance(geometry.Point(0, 0))\n", + "\n", + "print(\"Collector area: %2.1f\"% total_collector_area)\n", + "print(\"Collector L_min: %1.2f\"% L_min)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Field layout definition\n", + "\n", + "Once the collector aperture has been determined, the field layout can be defined. It is important to specify the ground cover ratio (GCR), which is the ratio of the collector are to the ground area.\n", + "\n", + "### Neighbor order\n", + "The neighbor order determines how many collectors to take into account - for a neighbor order of 1 the immidiate 8 collectors are considered, whereas for a neighbor order of 2, 24 shading collectors are considered. It is recommended to use atleast a neighbor order of 2.\n", + "\n", + "### Standard vs. custom field layouts\n", + "It is possible to choose from four different standard field layouts: `square`, `diagonal`, `hexagon_e_w`, and `hexagon_n_s`.\n", + "\n", + "It is also possible to specify a custom layout using the keywords: `aspect ratio`, `offset`, `rotation`, and `gcr`. For a description of the layout parameters, see the paper by [Cumpston and Pye (2014)](https://doi.org/10.1016/j.solener.2014.06.012) or check out the function documentation." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "X, Y, Z, tracker_distance, relative_azimuth, relative_slope = \\\n", + " twoaxistracking.generate_field_layout(\n", + " gcr=0.3, # Change this parameter according to your desired density of collectors\n", + " neighbor_order=2,\n", + " layout_type='square',\n", + " L_min=L_min, # calculated from collector geometry - do not change\n", + " total_collector_area=total_collector_area, # calculated from collector geometry - do not change\n", + " plot=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Calculate shading fraction\n", + "\n", + "Now that the collector geometry and field layout have been defined, it is time to do the actual shading calculations. This step is relatively computational intensive and is mainly affected by the time step, neighbor order, and computational resources available. Typical run times vary between 5 s and 3 min." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Wall time: 5.55 s\n" + ] + } + ], "source": [ - "df['shaded_fraction'] = tracker_field.get_shaded_fraction(df['elevation'], df['azimuth'])" + "%%time\n", + "df['shaded_fraction'] = \\\n", + " df.apply(lambda x: twoaxistracking.shaded_fraction(\n", + " solar_azimuth=x['azimuth'],\n", + " solar_elevation=x['elevation'],\n", + " total_collector_geometry=collector_geometry,\n", + " active_collector_geometry=collector_geometry,\n", + " tracker_distance=tracker_distance,\n", + " relative_azimuth=relative_azimuth,\n", + " relative_slope=relative_slope,\n", + " L_min=L_min,\n", + " plot=False),\n", + " axis=1)" ] }, { @@ -391,9 +388,7 @@ "source": [ "## Visualize the shading fraction\n", "\n", - "Once the shaded fraction has been calculated it can be used for solar power calculations.\n", - "\n", - "As an example, the shaded fraction is shown for one day:" + "Plot the shading fraction for one example day:" ] }, { @@ -403,7 +398,7 @@ "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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RLl5hn9MT8IAbw+NxddHm+Xsor1c3EzbRrV4qFtz3liygxuiQhnUPsLuSAV6fuFmtqScdOo+W4bV4LmbWhW5zZkzZ7jllltITk4mNzeXZ555BoD33nuPhQsXkp2dzcyZM4mKimLNmjX87W9/IzMzkypVqjBx4kRatGhBRkYGo0ePJikpiaioKDIyMi7sf8mSJTz33HOcO3eOpk2bMnHiRKpVq8aiRYt46KGHCA4O5pprrik035EjR7jttttITU0lNjaW2bNn07VrV4YOHcrSpUt57LHHOHXqFOPGjSMrK4tmzZrx+eefExwczOHDh7nnnnvYs2cPAB999BHvvvsuu3fvJjY2lu7du3P//ffTt29fNm3aRGZmJvfeey/x8fH4+fnx1ltvcf311zNp0iQWLFjA2bNn2b17NwMHDuS1115zwjtUsP+u3M2avcd48+a2NKqjA4jspEfobujeLs24PLI2z87fzP5jOs1ufosWLSIsLIykpCQ2bdpEr169AKhbty4JCQnce++9vPHGGwBERUXx448/sn79el544QX++c9/AlahDA4OZuvWrTz//POsW7cOgKNHj/Liiy+ybNkyEhISiIuL46233iIzM5O77rqLhQsXsm7dOg4dOlRovtDQUMaPH0/nzp1JTEykaVOr+SEkJISEhASGDRvGoEGDWLt2LUlJSURHRzNhwgQAHnzwQa677jqSkpJISEigVatWvPLKKzRt2pTExERef/31Pz3XBx98gIiwceNGpk6dysiRIy/0WklMTGT69Ols3LiR6dOns3+/a1bK2piczltLdnBjm4YMah/ukudQJadH6G7I10d4e2gsvf/zI3+fnsj0u69yu6+xxR1Ju0qbNm14+OGHefzxx+nbty+dO3cGYNCgQQB06NCBOXPmAJCens7IkSPZuXMnIkJ2tnVeYuXKlTz44IMAxMTEEBMTA8Dq1avZsmULnTp1AiArK4urrrqKbdu20aRJE5o3bw7Abbfdxrhx40qVO3/Ty6ZNm3j66ac5ceIEp0+fpmfPngB8//33fPbZZwD4+vpSs2ZNjh8vfFqIn376ib/+9a+A9eHVuHFjduzYAUDXrl2pWbMmAC1btmTfvn00atSoVJmLk5mdy99nJBJSLYCXBrbWHlBuQI/Q3VRE7WCe79+K+H3HmbjqN7vjuI3LLruMhIQE2rRpw9NPP80L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\n", "text/plain": [ "
" ] @@ -415,18 +410,16 @@ } ], "source": [ - "axes = df.loc['2019-06-28':'2019-06-28', ['shaded_fraction', 'elevation']].plot(subplots=True, ylim=[0,None])" + "axes = df.loc['2019-06-28':'2019-06-28', ['shaded_fraction','elevation']].plot(subplots=True, ylim=[0,None])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Notice how the shaded fraction is zero (unshaded) throughout most of the day, with the exception of some shading in the morning when the solar elevation angle is low.\n", - "\n", "
\n", "\n", - "Shading is also seasonal dependent, which can be seen from the plot of the average daily shading fraction below:" + "Visualize the average daily shading fraction:" ] }, { @@ -437,7 +430,7 @@ { "data": { "text/plain": [ - "(0.0, 0.4737615916403633)" + "" ] }, "execution_count": 11, @@ -446,7 +439,7 @@ }, { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] @@ -458,9 +451,7 @@ } ], "source": [ - "ax = df.loc[df['elevation']>0, 'shaded_fraction'].resample('1d').mean().plot()\n", - "ax.set_ylabel('Daily average shading fraction')\n", - "ax.set_ylim(0, None)" + "df['shaded_fraction'].resample('1d').mean().plot()" ] }, { diff --git a/docs/source/whatsnew.md b/docs/source/whatsnew.md index a6d4ad3..44d41d9 100644 --- a/docs/source/whatsnew.md +++ b/docs/source/whatsnew.md @@ -13,8 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Tilted fields can now be simulated by specifyig the keywords ``slope_azimuth`` and ``slope_tilt`` (see PR#7). - The code now is able to differentiate between the active area and total area (see PR#11). -- The class TwoAxisTrackerField has been added, which is now the recommended way for using - the package and is sufficient for most use cases. + ### Changed - Divide code into modules: shading, plotting, and layout @@ -22,8 +21,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Changed names of notebooks - Change repository name from "two_axis_tracker_shading" to "twoaxistracking" -- Changed naming of ``L_min`` to ``min_tracker_spacing`` -- Changed naming of ``collector_area`` to ``total_collector_area`` ### Testing - Linting using flake8 was added in PR#11 diff --git a/setup.cfg b/setup.cfg index 648022e..d64eb90 100644 --- a/setup.cfg +++ b/setup.cfg @@ -3,15 +3,15 @@ name = twoaxistracking version = 0.1.0 author = Adam R. Jensen author_email = adam-r-j@hotmail.com -description = twoaxistracking is a python package for simulating two-axis tracking solar collectors, particularly self-shading. +description = Functions for simulating self-shading of two-axis trackers long_description = file: README.md long_description_content_type = text/markdown -url = https://github.com/pvlib/twoaxistracking +url = https://github.com/AdamRJensen/twoaxistracking project_urls = - Bug Tracker = https://github.com/pvlib/twoaxistracking/issues + Bug Tracker = https://github.com/AdamRJensen/twoaxistracking/issues classifiers = Programming Language :: Python :: 3 - License :: OSI Approved :: BSD License + License :: OSI Approved :: MIT License Operating System :: OS Independent Topic :: Scientific/Engineering Intended Audience :: Science/Research @@ -20,21 +20,14 @@ classifiers = packages = twoaxistracking python_requires = >=3.7 install_requires = + pvlib numpy + pandas matplotlib shapely [options.extras_require] -test = - pytest - pytest-cov - pandas -doc = - sphinx==4.4.0 - myst-nb==0.13.2 - sphinx-book-theme==0.2.0 - pvlib==0.9.0 - pandas==1.3.5 +test = pytest;pytest-cov; [tool:pytest] addopts = --cov=twoaxistracking --cov-fail-under=100 --cov-report=term-missing diff --git a/twoaxistracking/__init__.py b/twoaxistracking/__init__.py index 2479116..249c06e 100644 --- a/twoaxistracking/__init__.py +++ b/twoaxistracking/__init__.py @@ -1,6 +1,6 @@ from .layout import generate_field_layout # noqa: F401 from .shading import shaded_fraction # noqa: F401 -from .twoaxistrackerfield import TwoAxisTrackerField # noqa: F401 + try: from shapely.geos import lgeos # noqa: F401 diff --git a/twoaxistracking/layout.py b/twoaxistracking/layout.py index 68c6b7d..6e8465e 100644 --- a/twoaxistracking/layout.py +++ b/twoaxistracking/layout.py @@ -1,5 +1,5 @@ import numpy as np -from shapely import geometry +from twoaxistracking import plotting def _rotate_origin(x, y, rotation_deg): @@ -11,19 +11,22 @@ def _rotate_origin(x, y, rotation_deg): return xx, yy -def _calculate_min_tracker_spacing(collector_geometry): - min_tracker_spacing = 2 * collector_geometry.hausdorff_distance(geometry.Point(0, 0)) - return min_tracker_spacing - - -def generate_field_layout(gcr, total_collector_area, min_tracker_spacing, - neighbor_order, aspect_ratio, offset, rotation, - slope_azimuth=0, slope_tilt=0): +def generate_field_layout(gcr, total_collector_area, L_min, neighbor_order, + aspect_ratio=None, offset=None, rotation=None, + layout_type=None, slope_azimuth=0, + slope_tilt=0, plot=False): """ Generate a regularly-spaced collector field layout. Field layout parameters and limits are described in [1]_. + Notes + ----- + The field layout can be specified either by selecting a standard layout + using the layout_type argument or by specifying the individual layout + parameters aspect_ratio, offset, and rotation. For both cases the ground + cover ratio (gcr) needs to be specified. + Any length unit can be used as long as the usage is consistent with the collector geometry. @@ -33,22 +36,26 @@ def generate_field_layout(gcr, total_collector_area, min_tracker_spacing, Ground cover ratio. Ratio of collector area to ground area. total_collector_area: float Surface area of one collector. - min_tracker_spacing: float + L_min: float Minimum distance between collectors. neighbor_order: int Order of neighbors to include in layout. neighbor_order=1 includes only the 8 directly adjacent collectors. - aspect_ratio: float + aspect_ratio: float, optional Ratio of the spacing in the primary direction to the secondary. - offset: float + offset: float, optional Relative row offset in the secondary direction as fraction of the spacing in the primary direction. -0.5 <= offset < 0.5. - rotation: float + rotation: float, optional Counterclockwise rotation of the field in degrees. 0 <= rotation < 180 + layout_type: {square, square_rotated, hexagon_e_w, hexagon_n_s}, optional + Specification of the special layout type (only depend on gcr). slope_azimuth : float, optional Direction of normal to slope on horizontal [degrees] slope_tilt : float, optional Tilt of slope relative to horizontal [degrees] + plot: bool, default: False + Whether to plot the field layout. Returns ------- @@ -74,22 +81,48 @@ def generate_field_layout(gcr, total_collector_area, min_tracker_spacing, .. [1] `Shading and land use in regularly-spaced sun-tracking collectors, Cumpston & Pye. `_ """ + # Consider special layouts which can be defined only by GCR + if layout_type == 'square': + aspect_ratio = 1 + offset = 0 + rotation = 0 + # Diagonal layout is the square layout rotated 45 degrees + elif layout_type == 'diagonal': + aspect_ratio = 1 + offset = 0 + rotation = 45 + # Hexagonal layouts are defined by aspect_ratio=0.866 and offset=-0.5 + elif layout_type == 'hexagonal_n_s': + aspect_ratio = np.sqrt(3)/2 + offset = -0.5 + rotation = 0 + # The hexagonal E-W layout is the hexagonal N-S layout rotated 90 degrees + elif layout_type == 'hexagonal_e_w': + aspect_ratio = np.sqrt(3)/2 + offset = -0.5 + rotation = 90 + elif layout_type is not None: + raise ValueError('The layout type specified was not recognized.') + elif ((aspect_ratio is None) or (offset is None) or (rotation is None)): + raise ValueError('Aspect ratio, offset, and rotation needs to be ' + 'specified when no layout type has not been selected') + # Check parameters are within their ranges + if aspect_ratio < np.sqrt(1-offset**2): + raise ValueError('Aspect ratio is too low and not feasible') + if aspect_ratio > total_collector_area/(gcr*L_min**2): + raise ValueError('Apsect ratio is too high and not feasible') if (offset < -0.5) | (offset >= 0.5): raise ValueError('The specified offset is outside the valid range.') if (rotation < 0) | (rotation >= 180): raise ValueError('The specified rotation is outside the valid range.') - # Check if Lmin is physically possible given the collector area. - if (min_tracker_spacing < np.sqrt(4*total_collector_area/np.pi)): - raise ValueError('Lmin is not physically possible.') # Check if mimimum and maximum ground cover ratios are exceded - gcr_max = total_collector_area / (min_tracker_spacing**2 * np.sqrt(1-offset**2)) + gcr_max = total_collector_area / (L_min**2 * np.sqrt(1-offset**2)) if (gcr < 0) or (gcr > gcr_max): - raise ValueError('Maximum ground cover ratio exceded or less than 0.') - if aspect_ratio < np.sqrt(1-offset**2): - raise ValueError('Aspect ratio is too low and not feasible') - if aspect_ratio > total_collector_area/(gcr*min_tracker_spacing**2): - raise ValueError('Aspect ratio is too high and not feasible') + raise ValueError('Maximum ground cover ratio exceded.') + # Check if Lmin is physically possible given the collector area. + if (L_min < np.sqrt(4*total_collector_area/np.pi)): + raise ValueError('Lmin is not physically possible.') N = 1 + 2 * neighbor_order # Number of collectors along each side @@ -123,4 +156,8 @@ def generate_field_layout(gcr, total_collector_area, min_tracker_spacing, # positive means collector is higher than reference collector relative_slope = -np.cos(np.deg2rad(slope_azimuth - relative_azimuth)) * slope_tilt # noqa: E501 + # Visualize layout + if plot: + plotting._plot_field_layout(X, Y, Z, L_min) + return X, Y, Z, tracker_distance, relative_azimuth, relative_slope diff --git a/twoaxistracking/plotting.py b/twoaxistracking/plotting.py index 6d58832..aa9378b 100644 --- a/twoaxistracking/plotting.py +++ b/twoaxistracking/plotting.py @@ -6,33 +6,33 @@ from matplotlib import cm -def _plot_field_layout(X, Y, Z, min_tracker_spacing): - """Create a plot of the field layout.""" +def _plot_field_layout(X, Y, Z, L_min): + """Plot field layout.""" # Collector heights is illustrated with colors from a colormap norm = mcolors.Normalize(vmin=min(Z)-0.000001, vmax=max(Z)+0.000001) - # 0.000001 is added/subtracted to/from the limits in order for the colormap + # 0.000001 is added/subtracted for the limits in order for the colormap # to correctly display the middle color when all tracker Z coords are zero cmap = cm.viridis_r colors = cmap(norm(Z)) fig, ax = plt.subplots(figsize=(6, 6), subplot_kw={'aspect': 'equal'}) - # Plot a circle for each neighboring collector (diameter equals min_tracker_spacing) + # Plot a circle for each neighboring collector (diameter equals L_min) ax.add_collection(collections.EllipseCollection( - widths=min_tracker_spacing, heights=min_tracker_spacing, angles=0, - units='xy', facecolors=colors, edgecolors=("black",), linewidths=(1,), - offsets=list(zip(X, Y)), transOffset=ax.transData)) + widths=L_min, heights=L_min, angles=0, units='xy', facecolors=colors, + edgecolors=("black",), linewidths=(1,), offsets=list(zip(X, Y)), + transOffset=ax.transData)) # Similarly, add a circle for the origin ax.add_collection(collections.EllipseCollection( - widths=min_tracker_spacing, heights=min_tracker_spacing, angles=0, - units='xy', facecolors='red', edgecolors=("black",), linewidths=(1,), - offsets=[0, 0], transOffset=ax.transData)) + widths=L_min, heights=L_min, angles=0, units='xy', facecolors='red', + edgecolors=("black",), linewidths=(1,), offsets=[0, 0], + transOffset=ax.transData)) + plt.axis('equal') fig.colorbar(cm.ScalarMappable(norm=norm, cmap=cmap), ax=ax, shrink=0.8, label='Relative tracker height (vertical)') # Set limits - lower_lim = min(min(X), min(Y)) - min_tracker_spacing - upper_lim = max(max(X), max(Y)) + min_tracker_spacing - ax.set_xlim(lower_lim, upper_lim) + lower_lim = min(min(X), min(Y)) - L_min + upper_lim = max(max(X), max(Y)) + L_min ax.set_ylim(lower_lim, upper_lim) - return fig + ax.set_xlim(lower_lim, upper_lim) def _polygons_to_patch_collection(geometries, **kwargs): @@ -49,7 +49,7 @@ def _polygons_to_patch_collection(geometries, **kwargs): def _plot_shading(active_collector_geometry, unshaded_geometry, - shading_geometries, min_tracker_spacing): + shading_geometries, L_min): """Plot the shaded and unshaded area for a specific solar position.""" active_patches = _polygons_to_patch_collection( active_collector_geometry, facecolor='red', linewidth=0.5, alpha=0.5) @@ -59,12 +59,12 @@ def _plot_shading(active_collector_geometry, unshaded_geometry, shading_geometries, facecolor='blue', linewidth=0.5, alpha=0.5) fig, axes = plt.subplots(1, 2, subplot_kw=dict(aspect='equal')) - axes[0].set_title('Total area and shading areas') + axes[0].set_title('Unshaded and shading areas') axes[0].add_collection(active_patches, autolim=True) axes[0].add_collection(shading_patches, autolim=True) axes[1].set_title('Unshaded area') axes[1].add_collection(unshaded_patches, autolim=True) for ax in axes: - ax.set_xlim(-min_tracker_spacing, min_tracker_spacing) - ax.set_ylim(-min_tracker_spacing, min_tracker_spacing) - return fig + ax.set_xlim(-L_min, L_min) + ax.set_ylim(-L_min, L_min) + plt.show() diff --git a/twoaxistracking/shading.py b/twoaxistracking/shading.py index bf6acee..9a2c6cb 100644 --- a/twoaxistracking/shading.py +++ b/twoaxistracking/shading.py @@ -3,10 +3,19 @@ from twoaxistracking import plotting +def _rotate_origin(x, y, rotation_deg): + """Rotate a set of 2D points counterclockwise around the origin (0, 0).""" + rotation_rad = np.deg2rad(rotation_deg) + # Rotation is set negative to make counterclockwise rotation + xx = x * np.cos(-rotation_rad) + y * np.sin(-rotation_rad) + yy = -x * np.sin(-rotation_rad) + y * np.cos(-rotation_rad) + return xx, yy + + def shaded_fraction(solar_elevation, solar_azimuth, total_collector_geometry, active_collector_geometry, - min_tracker_spacing, tracker_distance, relative_azimuth, - relative_slope, slope_azimuth=0, slope_tilt=0, plot=False): + L_min, tracker_distance, relative_azimuth, relative_slope, + slope_azimuth=0, slope_tilt=0, plot=False): """Calculate the shaded fraction for any layout of two-axis tracking collectors. Parameters @@ -19,7 +28,7 @@ def shaded_fraction(solar_elevation, solar_azimuth, Polygon corresponding to the total collector area. active_collector_geometry: Shapely Polygon or MultiPolygon One or more polygons defining the active collector area. - min_tracker_spacing: float + L_min: float Minimum distance between collectors. Used for selecting possible shading collectors. tracker_distance: array of floats @@ -48,9 +57,7 @@ def shaded_fraction(solar_elevation, solar_azimuth, return np.nan # Set shaded fraction to 1 (fully shaded) if the solar elevation is below # the horizon line caused by the tilted ground - elif np.tan(np.deg2rad(solar_elevation)) <= ( - - np.cos(np.deg2rad(slope_azimuth-solar_azimuth)) - * np.tan(np.deg2rad(slope_tilt))): + elif solar_elevation < - np.cos(np.deg2rad(slope_azimuth-solar_azimuth)) * slope_tilt: return 1 azimuth_difference = solar_azimuth - relative_azimuth @@ -68,7 +75,7 @@ def shaded_fraction(solar_elevation, solar_azimuth, unshaded_geometry = active_collector_geometry shading_geometries = [] for i, (x, y) in enumerate(zip(xoff, yoff)): - if np.sqrt(x**2+y**2) < min_tracker_spacing: + if np.sqrt(x**2+y**2) < L_min: # Project the geometry of the shading collector (total area) onto # the plane of the reference collector shading_geometry = shapely.affinity.translate(total_collector_geometry, x, y) # noqa: E501 @@ -79,7 +86,7 @@ def shaded_fraction(solar_elevation, solar_azimuth, if plot: plotting._plot_shading(active_collector_geometry, unshaded_geometry, - shading_geometries, min_tracker_spacing) + shading_geometries, L_min) shaded_fraction = 1 - unshaded_geometry.area / active_collector_geometry.area return shaded_fraction diff --git a/twoaxistracking/tests/test_layout.py b/twoaxistracking/tests/test_layout.py deleted file mode 100644 index 5a1ad7e..0000000 --- a/twoaxistracking/tests/test_layout.py +++ /dev/null @@ -1,154 +0,0 @@ -from twoaxistracking import layout -from shapely import geometry -import numpy as np -import pytest - - -@pytest.fixture -def rectangular_geometry(): - collector_geometry = geometry.box(-2, -1, 2, 1) - total_collector_area = collector_geometry.area - min_tracker_spacing = layout._calculate_min_tracker_spacing(collector_geometry) - return collector_geometry, total_collector_area, min_tracker_spacing - - -@pytest.fixture -def square_field_layout(): - # Corresponds to GCR 0.125 with the rectangular_geometry - X = np.array([-8, 0, 8, -8, 8, -8, 0, 8]) - Y = np.array([-8, -8, -8, 0, 0, 8, 8, 8]) - tracker_distance = (X**2 + Y**2)**0.5 - relative_azimuth = np.array([225, 180, 135, 270, 90, 315, 0, 45]) - Z = np.zeros(8) - relative_slope = np.zeros(8) - return X, Y, Z, tracker_distance, relative_azimuth, relative_slope - - -def test_min_tracker_spacing_rectangle(rectangular_geometry): - # Test calculation of min_tracker_spacing for a rectangular collector - min_tracker_spacing = layout._calculate_min_tracker_spacing(rectangular_geometry[0]) - assert min_tracker_spacing == np.sqrt(4**2+2**2) - - -def test_min_tracker_spacing_circle(): - # Test calculation of min_tracker_spacing for a circular collector with radius 1 - collector_geometry = geometry.Point(0, 0).buffer(1) - min_tracker_spacing = layout._calculate_min_tracker_spacing(collector_geometry) - assert min_tracker_spacing == 2 - - -def test_min_tracker_spacing_circle_offcenter(): - # Test calculation of min_tracker_spacing for a circular collector with radius 1 rotating - # off-center around the point (0, 1) - collector_geometry = geometry.Point(0, 1).buffer(1) - min_tracker_spacing = layout._calculate_min_tracker_spacing(collector_geometry) - assert min_tracker_spacing == 4 - - -def test_min_tracker_spacingpolygon(): - # Test calculation of min_tracker_spacing for a polygon - collector_geometry = geometry.Polygon([(-1, -1), (3, 2), (4, 4), (1, 2), (-1, -1)]) - min_tracker_spacing = layout._calculate_min_tracker_spacing(collector_geometry) - assert min_tracker_spacing == 2 * np.sqrt(4**2 + 4**2) - - -def test_square_layout_generation(rectangular_geometry, square_field_layout): - # Test that a square field layout is returned correctly - collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry - X_exp, Y_exp, Z_exp, tracker_distance_exp, relative_azimuth_exp, relative_slope_exp = \ - square_field_layout - - X, Y, Z, tracker_distance, relative_azimuth, relative_slope = \ - layout.generate_field_layout( - gcr=0.125, - total_collector_area=total_collector_area, - min_tracker_spacing=min_tracker_spacing, - neighbor_order=1, - aspect_ratio=1, - offset=0, - rotation=0) - assert (X == X_exp).all() - assert (Y == Y_exp).all() - assert (Z == Z_exp).all() - assert (tracker_distance_exp == tracker_distance_exp).all() - assert (relative_azimuth == relative_azimuth_exp).all() - assert (relative_slope == relative_slope_exp).all() - - -def test_layout_generation_value_error(rectangular_geometry): - # Test if value errors are correctly raised - collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry - - # Test if ValueError is raised if offset is out of range - with pytest.raises(ValueError, match="offset is outside the valid range"): - _ = layout.generate_field_layout( - gcr=0.25, total_collector_area=total_collector_area, - min_tracker_spacing=min_tracker_spacing, neighbor_order=1, - aspect_ratio=1, offset=1.1, rotation=0) - - # Test if ValueError is raised if aspect ratio is too low - with pytest.raises(ValueError, match="Aspect ratio is too low"): - _ = layout.generate_field_layout( - gcr=0.25, total_collector_area=total_collector_area, - min_tracker_spacing=min_tracker_spacing, neighbor_order=1, - aspect_ratio=0.6, offset=0, rotation=0) - - # Test if ValueError is raised if aspect ratio is too high - with pytest.raises(ValueError, match="Aspect ratio is too high"): - _ = layout.generate_field_layout( - gcr=0.25, total_collector_area=total_collector_area, - min_tracker_spacing=min_tracker_spacing, neighbor_order=1, - aspect_ratio=5, offset=0, rotation=0) - - # Test if ValueError is raised if rotation is greater than 180 degrees - with pytest.raises(ValueError, match="rotation is outside the valid range"): - _ = layout.generate_field_layout( - gcr=0.25, total_collector_area=total_collector_area, - min_tracker_spacing=min_tracker_spacing, neighbor_order=1, - aspect_ratio=1.2, offset=0, rotation=190) - - # Test if ValueError is raised if rotation is less than 0 - with pytest.raises(ValueError, match="rotation is outside the valid range"): - _ = layout.generate_field_layout( - gcr=0.5, total_collector_area=total_collector_area, - min_tracker_spacing=min_tracker_spacing, neighbor_order=1, - aspect_ratio=1, offset=0, rotation=-1) - - # Test if ValueError is raised if min_tracker_spacing is outside valid range - with pytest.raises(ValueError, match="Lmin is not physically possible"): - _ = layout.generate_field_layout( - gcr=0.25, total_collector_area=total_collector_area, - min_tracker_spacing=1, neighbor_order=1, aspect_ratio=1.2, - offset=0, rotation=90) - - # Test if ValueError is raised if maximum ground cover ratio is exceeded - with pytest.raises(ValueError, match="Maximum ground cover ratio exceded"): - _ = layout.generate_field_layout( - gcr=0.5, total_collector_area=total_collector_area, - min_tracker_spacing=min_tracker_spacing, neighbor_order=1, - aspect_ratio=1, offset=0, rotation=0) - - -def test_field_slope(): - assert True - - -def test_neighbor_order(rectangular_geometry): - collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry - X, Y, Z, tracker_distance, relative_azimuth, relative_slope = \ - layout.generate_field_layout( - gcr=0.125, - total_collector_area=total_collector_area, - min_tracker_spacing=min_tracker_spacing, - neighbor_order=3, - aspect_ratio=1, - offset=0, - rotation=0) - assert len(X) == (7*7-1) - -# Test slope -# Test neighbor order - -# Inputs (0, negative numbers) -# All types of inputs, e.g., scalars, numpy array and series, list -# Test coverage diff --git a/twoaxistracking/tests/test_placeholder.py b/twoaxistracking/tests/test_placeholder.py new file mode 100644 index 0000000..8acf64e --- /dev/null +++ b/twoaxistracking/tests/test_placeholder.py @@ -0,0 +1,6 @@ +import pytest # noqa: F401 +import twoaxistracking # noqa: F401 + + +def test_placeholder(): + pass diff --git a/twoaxistracking/tests/test_plotting.py b/twoaxistracking/tests/test_plotting.py deleted file mode 100644 index 3f00224..0000000 --- a/twoaxistracking/tests/test_plotting.py +++ /dev/null @@ -1,52 +0,0 @@ -import matplotlib.pyplot as plt -from twoaxistracking import plotting, layout, twoaxistrackerfield -from shapely import geometry -import numpy as np -import pytest - - -def assert_isinstance(obj, klass): - assert isinstance(obj, klass), f'got {type(obj)}, expected {klass}' - - -def test_field_layout_plot(): - X = np.array([-8, 0, 8, -8, 8, -8, 0, 8]) - Y = np.array([-8, -8, -8, 0, 0, 8, 8, 8]) - Z = np.array([0.1237, 0.0619, 0, 0.0619, -0.0619, 0, -0.0619, -0.1237]) - L_min = 4.4721 - result = plotting._plot_field_layout(X, Y, Z, L_min) - assert_isinstance(result, plt.Figure) - plt.close('all') - - -@pytest.fixture -def rectangular_geometry(): - collector_geometry = geometry.box(-2, -1, 2, 1) - total_collector_area = collector_geometry.area - min_tracker_spacing = layout._calculate_min_tracker_spacing(collector_geometry) - return collector_geometry, total_collector_area, min_tracker_spacing - - -def test_shading_plot(rectangular_geometry): - collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry - result = plotting._plot_shading(collector_geometry, collector_geometry, - collector_geometry, min_tracker_spacing) - assert_isinstance(result, plt.Figure) - plt.close('all') - - -def test_plotting_of_field_layout(rectangular_geometry): - # Test if plot_field_layout returns a figure object - collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry - field = twoaxistrackerfield.TwoAxisTrackerField( - total_collector_geometry=collector_geometry, - active_collector_geometry=collector_geometry, - neighbor_order=1, - gcr=0.25, - aspect_ratio=1, - offset=0.45, - rotation=30, - ) - result = field.plot_field_layout() - assert_isinstance(result, plt.Figure) - plt.close('all') diff --git a/twoaxistracking/tests/test_shading.py b/twoaxistracking/tests/test_shading.py deleted file mode 100644 index 0755ed6..0000000 --- a/twoaxistracking/tests/test_shading.py +++ /dev/null @@ -1,125 +0,0 @@ -from twoaxistracking import shading, layout -from shapely import geometry -import numpy as np -import pytest - - -@pytest.fixture -def rectangular_geometry(): - collector_geometry = geometry.box(-2, -1, 2, 1) - total_collector_area = collector_geometry.area - min_tracker_spacing = layout._calculate_min_tracker_spacing(collector_geometry) - return collector_geometry, total_collector_area, min_tracker_spacing - - -@pytest.fixture -def square_field_layout(): - # Corresponds to GCR 0.125 with the rectangular_geometry - X = np.array([-8, 0, 8, -8, 8, -8, 0, 8]) - Y = np.array([-8, -8, -8, 0, 0, 8, 8, 8]) - tracker_distance = (X**2 + Y**2)**0.5 - relative_azimuth = np.array([225, 180, 135, 270, 90, 315, 0, 45]) - Z = np.zeros(8) - relative_slope = np.zeros(8) - return X, Y, Z, tracker_distance, relative_azimuth, relative_slope - - -def test_shading(rectangular_geometry, square_field_layout): - # Test shading when geometries completly overlap - # Also plots the geometry (ensures no errors occurs) - collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry - X, Y, Z, tracker_distance, relative_azimuth, relative_slope = \ - square_field_layout - shaded_fraction = shading.shaded_fraction( - solar_elevation=3, - solar_azimuth=120, - total_collector_geometry=collector_geometry, - active_collector_geometry=collector_geometry, - min_tracker_spacing=min_tracker_spacing, - tracker_distance=tracker_distance, - relative_azimuth=relative_azimuth, - relative_slope=relative_slope, - slope_azimuth=0, - slope_tilt=0, - plot=True) - assert np.isclose(shaded_fraction, 0.191324) - - -def test_shading_zero_solar_elevation(rectangular_geometry, square_field_layout): - collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry - X, Y, Z, tracker_distance, relative_azimuth, relative_slope = \ - square_field_layout - # Test shading when geometries completly overlap - shaded_fraction = shading.shaded_fraction( - solar_elevation=0, - solar_azimuth=180, - total_collector_geometry=collector_geometry, - active_collector_geometry=collector_geometry, - min_tracker_spacing=min_tracker_spacing, - tracker_distance=tracker_distance, - relative_azimuth=relative_azimuth, - relative_slope=relative_slope, - slope_azimuth=0, - slope_tilt=0, - plot=False) - assert shaded_fraction == 1 - - -def test_no_shading(rectangular_geometry, square_field_layout): - # Test shading calculation when there is no shading (high solar elevation) - collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry - X, Y, Z, tracker_distance, relative_azimuth, relative_slope = \ - square_field_layout - shaded_fraction = shading.shaded_fraction( - solar_elevation=45, - solar_azimuth=180, - total_collector_geometry=collector_geometry, - active_collector_geometry=collector_geometry, - min_tracker_spacing=min_tracker_spacing, - tracker_distance=tracker_distance, - relative_azimuth=relative_azimuth, - relative_slope=relative_slope, - slope_azimuth=0, - slope_tilt=0, - plot=False) - assert shaded_fraction == 0 - - -def test_shading_below_horizon(rectangular_geometry, square_field_layout): - # Test shading calculation when sun is below the horizon (elevation<0) - collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry - X, Y, Z, tracker_distance, relative_azimuth, relative_slope = \ - square_field_layout - shaded_fraction = shading.shaded_fraction( - solar_elevation=-5.1, - solar_azimuth=180, - total_collector_geometry=collector_geometry, - active_collector_geometry=collector_geometry, - min_tracker_spacing=min_tracker_spacing, - tracker_distance=tracker_distance, - relative_azimuth=relative_azimuth, - relative_slope=relative_slope, - slope_azimuth=0, - slope_tilt=0, - plot=False) - assert np.isnan(shaded_fraction) - - -def test_shading_below_hill_horizon(rectangular_geometry, square_field_layout): - # Test shading calculation when there is no shading (high solar elevation) - collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry - X, Y, Z, tracker_distance, relative_azimuth, relative_slope = \ - square_field_layout - shaded_fraction = shading.shaded_fraction( - solar_elevation=9, - solar_azimuth=180, - total_collector_geometry=collector_geometry, - active_collector_geometry=collector_geometry, - min_tracker_spacing=min_tracker_spacing, - tracker_distance=tracker_distance, - relative_azimuth=relative_azimuth, - relative_slope=relative_slope, - slope_azimuth=0, - slope_tilt=10, - plot=False) - assert shaded_fraction == 1 diff --git a/twoaxistracking/tests/test_twoaxistrackerfield.py b/twoaxistracking/tests/test_twoaxistrackerfield.py deleted file mode 100644 index a18ce82..0000000 --- a/twoaxistracking/tests/test_twoaxistrackerfield.py +++ /dev/null @@ -1,200 +0,0 @@ -from twoaxistracking import layout, twoaxistrackerfield -from shapely import geometry -import numpy as np -import pandas as pd -import pytest - - -@pytest.fixture -def rectangular_geometry(): - collector_geometry = geometry.box(-2, -1, 2, 1) - total_collector_area = collector_geometry.area - min_tracker_spacing = layout._calculate_min_tracker_spacing(collector_geometry) - return collector_geometry, total_collector_area, min_tracker_spacing - - -def test_invalid_layout_type(rectangular_geometry): - # Test if ValueError is raised when an incorrect layout_type is specified - collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry - with pytest.raises(ValueError, match="Layout type must be one of"): - _ = twoaxistrackerfield.TwoAxisTrackerField( - total_collector_geometry=collector_geometry, - active_collector_geometry=collector_geometry, - neighbor_order=1, - gcr=0.25, - layout_type='this_is_not_a_layout_type') - - -def test_square_layout_type(rectangular_geometry): - # Assert that layout field parameters are correctly set for the square layout - collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry - field = twoaxistrackerfield.TwoAxisTrackerField( - total_collector_geometry=collector_geometry, - active_collector_geometry=collector_geometry, - neighbor_order=2, - gcr=0.25, - layout_type='square') - assert field.gcr == 0.25 - assert field.aspect_ratio == 1 - assert field.offset == 0 - assert field.rotation == 0 - - -def test_diagonal_layout_type(rectangular_geometry): - # Assert that layout field parameters are correctly set for the diagonal layout - collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry - field = twoaxistrackerfield.TwoAxisTrackerField( - total_collector_geometry=collector_geometry, - active_collector_geometry=collector_geometry, - neighbor_order=2, - gcr=0.1, - layout_type='diagonal') - assert field.gcr == 0.1 - assert field.aspect_ratio == 1 - assert field.offset == 0 - assert field.rotation == 45 - - -def test_hexagonal_n_s_layout_type(rectangular_geometry): - # Assert that layout field parameters are correctly set for the diagonal layout - collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry - field = twoaxistrackerfield.TwoAxisTrackerField( - total_collector_geometry=collector_geometry, - active_collector_geometry=collector_geometry, - neighbor_order=4, - gcr=0.4, - layout_type='hexagonal_n_s') - assert field.gcr == 0.4 - assert field.aspect_ratio == np.sqrt(3)/2 - assert field.offset == -0.5 - assert field.rotation == 0 - - -def test_hexagonal_e_w_layout_type(rectangular_geometry): - # Assert that layout field parameters are correctly set for the diagonal layout - collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry - field = twoaxistrackerfield.TwoAxisTrackerField( - total_collector_geometry=collector_geometry, - active_collector_geometry=collector_geometry, - neighbor_order=4, - gcr=0.4, - layout_type='hexagonal_e_w') - assert field.gcr == 0.4 - assert field.aspect_ratio == np.sqrt(3)/2 - assert field.offset == -0.5 - assert field.rotation == 90 - - -def test_unspecifed_layout_type(rectangular_geometry): - # Test if ValueError is raised when one or more layout parameters are unspecified - collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry - with pytest.raises(ValueError, match="needs to be specified"): - _ = twoaxistrackerfield.TwoAxisTrackerField( - total_collector_geometry=collector_geometry, - active_collector_geometry=collector_geometry, - neighbor_order=1, - gcr=0.25, - aspect_ratio=1, - offset=0, - # rotation unspecified - ) - - -@pytest.fixture -def solar_position(): - solar_elevation = [-1, 0, 1, 2, 40] - solar_azimuth = [90, 100, 110, 120, 180] - return solar_elevation, solar_azimuth - - -@pytest.fixture -def expected_shaded_fraction(): - return [np.nan, 1.0, 0.71775, 0.60360, 0.0] - - -def is_close_with_nans(test, expected): - return (np.isclose(test, expected) | (np.isnan(test) & - (np.isnan(test) == np.isnan(expected)))).all() - - -def test_calculation_of_shaded_fraction_list(rectangular_geometry, solar_position, - expected_shaded_fraction): - # Test if shaded fraction is calculated correct when solar elevation and - # azimuth are lists - collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry - field = twoaxistrackerfield.TwoAxisTrackerField( - total_collector_geometry=collector_geometry, - active_collector_geometry=collector_geometry, - neighbor_order=1, - gcr=0.25, - aspect_ratio=1, - offset=0, - rotation=170) - solar_elevation, solar_azimuth = solar_position - result = field.get_shaded_fraction(solar_elevation, solar_azimuth) - # Test that calculated shaded fraction are equal or both nan - # using np.isclose(np.nan, np.nan) does not identify - assert is_close_with_nans(result, expected_shaded_fraction) - assert isinstance(result, list) - - -def test_calculation_of_shaded_fraction_series(rectangular_geometry, solar_position, - expected_shaded_fraction): - # Test if shaded fraction is calculated correct when solar elevation and - # azimuth are pandas Series - collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry - field = twoaxistrackerfield.TwoAxisTrackerField( - total_collector_geometry=collector_geometry, - active_collector_geometry=collector_geometry, - neighbor_order=1, - gcr=0.25, - aspect_ratio=1, - offset=0, - rotation=170) - solar_elevation, solar_azimuth = solar_position - result = field.get_shaded_fraction(pd.Series(solar_elevation), pd.Series(solar_azimuth)) - # Test that calculated shaded fraction are equal or both nan - # using np.isclose(np.nan, np.nan) does not identify - assert is_close_with_nans(result, expected_shaded_fraction) - assert isinstance(result, pd.Series) - - -def test_calculation_of_shaded_fraction_array(rectangular_geometry, solar_position, - expected_shaded_fraction): - # Test if shaded fraction is calculated correct when solar elevation and - # azimuth are pandas Series - collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry - field = twoaxistrackerfield.TwoAxisTrackerField( - total_collector_geometry=collector_geometry, - active_collector_geometry=collector_geometry, - neighbor_order=1, - gcr=0.25, - aspect_ratio=1, - offset=0, - rotation=170) - solar_elevation, solar_azimuth = solar_position - result = field.get_shaded_fraction(np.array(solar_elevation), np.array(solar_azimuth)) - # Test that calculated shaded fraction are equal or both nan - # using np.isclose(np.nan, np.nan) does not identify - assert is_close_with_nans(result, expected_shaded_fraction) - assert isinstance(result, np.ndarray) - - -def test_calculation_of_shaded_fraction_float(rectangular_geometry, solar_position): - # Test if shaded fraction is calculated correct when solar elevation and - # azimuth are pandas Series - collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry - field = twoaxistrackerfield.TwoAxisTrackerField( - total_collector_geometry=collector_geometry, - active_collector_geometry=collector_geometry, - neighbor_order=1, - gcr=0.25, - aspect_ratio=1, - offset=0, - rotation=170) - solar_elevation, solar_azimuth = solar_position - result = field.get_shaded_fraction(40, 180) - # Test that calculated shaded fraction are equal or both nan - # using np.isclose(np.nan, np.nan) does not identify - assert result == 0 - assert np.isscalar(result) diff --git a/twoaxistracking/twoaxistrackerfield.py b/twoaxistracking/twoaxistrackerfield.py deleted file mode 100644 index 4ab2fb8..0000000 --- a/twoaxistracking/twoaxistrackerfield.py +++ /dev/null @@ -1,182 +0,0 @@ -""" -The ``TwoAxisTrackerField`` module contains functions and classes that -combine the collector definition, field layout generation, and shading -calculation steps. Using the `TwoAxisTrackerField` class make it easy to -get started with the package and keeps track of the variables that are -passed from one function to the next. -""" - -from twoaxistracking import layout, shading, plotting -import numpy as np -import pandas as pd - - -STANDARD_FIELD_LAYOUT_PARAMETERS = { - 'square': {'aspect_ratio': 1, 'offset': 0, 'rotation': 0}, - # Diagonal layout is the square layout rotated 45 degrees - 'diagonal': {'aspect_ratio': 1, 'offset': 0, 'rotation': 45}, - # Hexagonal layouts are defined by aspect_ratio=0.866 and offset=-0.5 - 'hexagonal_n_s': {'aspect_ratio': np.sqrt(3)/2, 'offset': -0.5, 'rotation': 0}, - # The hexagonal E-W layout is the hexagonal N-S layout rotated 90 degrees - 'hexagonal_e_w': {'aspect_ratio': np.sqrt(3)/2, 'offset': -0.5, 'rotation': 90}, -} - - -class TwoAxisTrackerField: - """ - TwoAxisTrackerField is a convenient container for the collector geometry - and field layout, and allows for calculating the shaded fraction. - - Parameters - ---------- - total_collector_geometry: Shapely Polygon - Polygon corresponding to the total collector area. - active_collector_geometry: Shapely Polygon or MultiPolygon - One or more polygons defining the active collector area. - neighbor_order: int - Order of neighbors to include in layout. neighbor_order=1 includes only - the 8 directly adjacent collectors. - gcr: float - Ground cover ratio. Ratio of collector area to ground area. - layout_type: {square, square_rotated, hexagon_e_w, hexagon_n_s}, optional - Specification of the special layout type (only depend on gcr). - aspect_ratio: float, optional - Ratio of the spacing in the primary direction to the secondary. - offset: float, optional - Relative row offset in the secondary direction as fraction of the - spacing in the secondary direction. -0.5 <= offset < 0.5. - rotation: float, optional - Counterclockwise rotation of the field in degrees. 0 <= rotation < 180 - slope_azimuth : float, optional - Direction of normal to slope on horizontal [degrees] - slope_tilt : float, optional - Tilt of slope relative to horizontal [degrees] - - Notes - ----- - The field layout can be specified either by selecting a standard layout - using the layout_type argument or by specifying the individual layout - parameters aspect_ratio, offset, and rotation. For both cases the ground - cover ratio (gcr) needs to be specified. - """ - - def __init__(self, total_collector_geometry, active_collector_geometry, - neighbor_order, gcr, layout_type=None, aspect_ratio=None, - offset=None, rotation=None, slope_azimuth=0, slope_tilt=0): - - # Collector geometry - self.total_collector_geometry = total_collector_geometry - self.active_collector_geometry = active_collector_geometry - # Derive properties from geometries - self.total_collector_area = self.total_collector_geometry.area - self.active_collector_area = self.active_collector_geometry.area - self.min_tracker_spacing = \ - layout._calculate_min_tracker_spacing(self.total_collector_geometry) - - # Standard layout parameters - if layout_type is not None: - if layout_type not in list(STANDARD_FIELD_LAYOUT_PARAMETERS): - raise ValueError('Layout type must be one of: ' - f'{list(STANDARD_FIELD_LAYOUT_PARAMETERS)}') - else: - layout_params = STANDARD_FIELD_LAYOUT_PARAMETERS[layout_type] - aspect_ratio = layout_params['aspect_ratio'] - offset = layout_params['offset'] - rotation = layout_params['rotation'] - elif ((aspect_ratio is None) or (offset is None) or (rotation is None)): - raise ValueError('Aspect ratio, offset, and rotation needs to be ' - 'specified when no layout type has been selected') - - # Field layout parameters - self.neighbor_order = neighbor_order - self.gcr = gcr - self.layout_type = layout_type - self.aspect_ratio = aspect_ratio - self.offset = offset - self.rotation = rotation - self.slope_azimuth = slope_azimuth - self.slope_tilt = slope_tilt - - # Calculate position of neighboring collectors based on field layout - (self.X, self.Y, self.Z, self.tracker_distance, self.relative_azimuth, - self.relative_slope) = \ - layout.generate_field_layout( - gcr=self.gcr, - total_collector_area=self.total_collector_area, - min_tracker_spacing=self.min_tracker_spacing, - neighbor_order=self.neighbor_order, - aspect_ratio=self.aspect_ratio, - offset=self.offset, - rotation=self.rotation, - slope_azimuth=self.slope_azimuth, - slope_tilt=self.slope_tilt) - - def plot_field_layout(self): - """Create a plot of the field layout. - - Returns - ------- - fig : matplotlib.figure.Figure - Figure with two axes - """ - return plotting._plot_field_layout( - X=self.X, Y=self.Y, Z=self.Z, min_tracker_spacing=self.min_tracker_spacing) - - def get_shaded_fraction(self, solar_elevation, solar_azimuth, - plot=False): - """Calculate the shaded fraction for the specified solar positions. - - Uses the :py:func:`twoaxistracking.shaded_fraction` function to - calculate the shaded fraction for the specified solar elevation and - azimuth angles. - - Parameters - ---------- - solar_elevation : array-like - Solar elevation angles in degrees. - solar_azimuth : array-like - Solar azimuth angles in degrees. - plot : boolean, default: False - Whether to plot the unshaded and shading geometries for each solar - position. - - Returns - ------- - shaded_fractions : array-like - The shaded fractions for the specified collector geometry, - field layout, and solar angles. - """ - is_scalar = False - # Wrap scalars in a list - if np.isscalar(solar_elevation): - solar_elevation = [solar_elevation] - solar_azimuth = [solar_azimuth] - is_scalar = True - - # Calculate the shaded fraction for each solar position - shaded_fractions = [] - for (elevation, azimuth) in zip(solar_elevation, solar_azimuth): - shaded_fraction = shading.shaded_fraction( - solar_elevation=elevation, - solar_azimuth=azimuth, - total_collector_geometry=self.total_collector_geometry, - active_collector_geometry=self.active_collector_geometry, - min_tracker_spacing=self.min_tracker_spacing, - tracker_distance=self.tracker_distance, - relative_azimuth=self.relative_azimuth, - relative_slope=self.relative_slope, - slope_azimuth=self.slope_azimuth, - slope_tilt=self.slope_tilt, - plot=False) - shaded_fractions.append(shaded_fraction) - - # Return the shaded_fractions as the same type as the input - if isinstance(solar_elevation, pd.Series): - shaded_fractions = pd.Series(shaded_fractions, - index=solar_elevation.index) - elif isinstance(solar_elevation, np.ndarray): - shaded_fractions = np.array(shaded_fractions) - elif is_scalar: - shaded_fractions = shaded_fractions[0] - - return shaded_fractions From 147ba2a5f48d973469441f1cf2c2318acff6cc93 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Mon, 28 Feb 2022 23:57:57 +0100 Subject: [PATCH 33/48] Undo commits --- .readthedocs.yml | 17 +++++++++-------- README.md | 4 +--- docs/environment.yml | 15 +++++++++++++++ setup.cfg | 20 +++++++------------- 4 files changed, 32 insertions(+), 24 deletions(-) create mode 100644 docs/environment.yml diff --git a/.readthedocs.yml b/.readthedocs.yml index 2b0adf9..fb783c8 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -1,17 +1,18 @@ version: 2 +conda: + environment: docs/environment.yml build: - os: ubuntu-20.04 - tools: - python: "3.7" + image: latest +# This part is necessary otherwise the project is not built python: - # only use the packages specified in setup.py - system_packages: false - + version: 3.7 install: - method: pip path: . - extra_requirements: - - doc + +# By default readthedocs does not checkout git submodules +submodules: + include: all \ No newline at end of file diff --git a/README.md b/README.md index 8dc3b23..75b6509 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Open source code for calculating self-shading of two-axis tracking solar collectors -twoaxistracking is a python package for simulating two-axis tracking solar collectors, particularly self-shading. +"twoaxistracking" is a python package for simulating self-shading in fields of two-axis trackers. ## Documentation The documentation can be found at [readthedocs](https://twoaxistracking.readthedocs.io/). @@ -15,8 +15,6 @@ The main non-standard dependency is `shapely`, which handles the geometric opera The solar modeling library `pvlib` is recommended for calculating the solar position and can be installed by the command: - pip install pvlib - ## Citing If you use the package in published work, please cite: > Adam R. Jensen et al. 2022. diff --git a/docs/environment.yml b/docs/environment.yml new file mode 100644 index 0000000..5abc2b3 --- /dev/null +++ b/docs/environment.yml @@ -0,0 +1,15 @@ +name: readthedocs +channels: + - defaults + - conda-forge +dependencies: + - python=3.7 + - pandas + - matplotlib + - numpy + - shapely # Should be installed with conda + - sphinx + - pip: + - pvlib + - myst-nb + - sphinx-book-theme diff --git a/setup.cfg b/setup.cfg index 20d2ef3..d64eb90 100644 --- a/setup.cfg +++ b/setup.cfg @@ -3,15 +3,15 @@ name = twoaxistracking version = 0.1.0 author = Adam R. Jensen author_email = adam-r-j@hotmail.com -description = twoaxistracking is a python package for simulating two-axis tracking solar collectors, particularly self-shading. +description = Functions for simulating self-shading of two-axis trackers long_description = file: README.md long_description_content_type = text/markdown -url = https://github.com/pvlib/twoaxistracking +url = https://github.com/AdamRJensen/twoaxistracking project_urls = - Bug Tracker = https://github.com/pvlib/twoaxistracking/issues + Bug Tracker = https://github.com/AdamRJensen/twoaxistracking/issues classifiers = Programming Language :: Python :: 3 - License :: OSI Approved :: BSD License + License :: OSI Approved :: MIT License Operating System :: OS Independent Topic :: Scientific/Engineering Intended Audience :: Science/Research @@ -20,20 +20,14 @@ classifiers = packages = twoaxistracking python_requires = >=3.7 install_requires = + pvlib numpy + pandas matplotlib shapely [options.extras_require] -test = - pytest - pytest-cov -doc = - sphinx==4.4.0 - myst-nb==0.13.2 - sphinx-book-theme==0.2.0 - pvlib==0.9.0 - pandas==1.3.5 +test = pytest;pytest-cov; [tool:pytest] addopts = --cov=twoaxistracking --cov-fail-under=100 --cov-report=term-missing From e9cc008514e4cbc54fad6fad0372e5eecb0ff9af Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Mon, 28 Feb 2022 23:58:50 +0100 Subject: [PATCH 34/48] Revert "Undo commits" This reverts commit 147ba2a5f48d973469441f1cf2c2318acff6cc93. --- .readthedocs.yml | 17 ++++++++--------- README.md | 4 +++- docs/environment.yml | 15 --------------- setup.cfg | 20 +++++++++++++------- 4 files changed, 24 insertions(+), 32 deletions(-) delete mode 100644 docs/environment.yml diff --git a/.readthedocs.yml b/.readthedocs.yml index fb783c8..2b0adf9 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -1,18 +1,17 @@ version: 2 -conda: - environment: docs/environment.yml build: - image: latest + os: ubuntu-20.04 + tools: + python: "3.7" -# This part is necessary otherwise the project is not built python: - version: 3.7 + # only use the packages specified in setup.py + system_packages: false + install: - method: pip path: . - -# By default readthedocs does not checkout git submodules -submodules: - include: all \ No newline at end of file + extra_requirements: + - doc diff --git a/README.md b/README.md index 75b6509..8dc3b23 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Open source code for calculating self-shading of two-axis tracking solar collectors -"twoaxistracking" is a python package for simulating self-shading in fields of two-axis trackers. +twoaxistracking is a python package for simulating two-axis tracking solar collectors, particularly self-shading. ## Documentation The documentation can be found at [readthedocs](https://twoaxistracking.readthedocs.io/). @@ -15,6 +15,8 @@ The main non-standard dependency is `shapely`, which handles the geometric opera The solar modeling library `pvlib` is recommended for calculating the solar position and can be installed by the command: + pip install pvlib + ## Citing If you use the package in published work, please cite: > Adam R. Jensen et al. 2022. diff --git a/docs/environment.yml b/docs/environment.yml deleted file mode 100644 index 5abc2b3..0000000 --- a/docs/environment.yml +++ /dev/null @@ -1,15 +0,0 @@ -name: readthedocs -channels: - - defaults - - conda-forge -dependencies: - - python=3.7 - - pandas - - matplotlib - - numpy - - shapely # Should be installed with conda - - sphinx - - pip: - - pvlib - - myst-nb - - sphinx-book-theme diff --git a/setup.cfg b/setup.cfg index d64eb90..20d2ef3 100644 --- a/setup.cfg +++ b/setup.cfg @@ -3,15 +3,15 @@ name = twoaxistracking version = 0.1.0 author = Adam R. Jensen author_email = adam-r-j@hotmail.com -description = Functions for simulating self-shading of two-axis trackers +description = twoaxistracking is a python package for simulating two-axis tracking solar collectors, particularly self-shading. long_description = file: README.md long_description_content_type = text/markdown -url = https://github.com/AdamRJensen/twoaxistracking +url = https://github.com/pvlib/twoaxistracking project_urls = - Bug Tracker = https://github.com/AdamRJensen/twoaxistracking/issues + Bug Tracker = https://github.com/pvlib/twoaxistracking/issues classifiers = Programming Language :: Python :: 3 - License :: OSI Approved :: MIT License + License :: OSI Approved :: BSD License Operating System :: OS Independent Topic :: Scientific/Engineering Intended Audience :: Science/Research @@ -20,14 +20,20 @@ classifiers = packages = twoaxistracking python_requires = >=3.7 install_requires = - pvlib numpy - pandas matplotlib shapely [options.extras_require] -test = pytest;pytest-cov; +test = + pytest + pytest-cov +doc = + sphinx==4.4.0 + myst-nb==0.13.2 + sphinx-book-theme==0.2.0 + pvlib==0.9.0 + pandas==1.3.5 [tool:pytest] addopts = --cov=twoaxistracking --cov-fail-under=100 --cov-report=term-missing From e4d2d82d075ac352a6fbcf1d6063908e3257eedc Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Tue, 1 Mar 2022 00:00:42 +0100 Subject: [PATCH 35/48] Add test files --- setup.cfg | 1 + twoaxistracking/tests/test_layout.py | 147 +++++++++++++ twoaxistracking/tests/test_placeholder.py | 6 - twoaxistracking/tests/test_plotting.py | 52 +++++ twoaxistracking/tests/test_shading.py | 125 +++++++++++ .../tests/test_twoaxistrackerfield.py | 201 ++++++++++++++++++ 6 files changed, 526 insertions(+), 6 deletions(-) create mode 100644 twoaxistracking/tests/test_layout.py delete mode 100644 twoaxistracking/tests/test_placeholder.py create mode 100644 twoaxistracking/tests/test_plotting.py create mode 100644 twoaxistracking/tests/test_shading.py create mode 100644 twoaxistracking/tests/test_twoaxistrackerfield.py diff --git a/setup.cfg b/setup.cfg index 20d2ef3..648022e 100644 --- a/setup.cfg +++ b/setup.cfg @@ -28,6 +28,7 @@ install_requires = test = pytest pytest-cov + pandas doc = sphinx==4.4.0 myst-nb==0.13.2 diff --git a/twoaxistracking/tests/test_layout.py b/twoaxistracking/tests/test_layout.py new file mode 100644 index 0000000..ce95077 --- /dev/null +++ b/twoaxistracking/tests/test_layout.py @@ -0,0 +1,147 @@ +from twoaxistracking import layout +from shapely import geometry +import numpy as np +import pytest + + +@pytest.fixture +def rectangular_geometry(): + collector_geometry = geometry.box(-2, -1, 2, 1) + total_collector_area = collector_geometry.area + min_tracker_spacing = layout._calculate_min_tracker_spacing(collector_geometry) + return collector_geometry, total_collector_area, min_tracker_spacing + + +@pytest.fixture +def square_field_layout(): + # Corresponds to GCR 0.125 with the rectangular_geometry + X = np.array([-8, 0, 8, -8, 8, -8, 0, 8]) + Y = np.array([-8, -8, -8, 0, 0, 8, 8, 8]) + tracker_distance = (X**2 + Y**2)**0.5 + relative_azimuth = np.array([225, 180, 135, 270, 90, 315, 0, 45]) + Z = np.zeros(8) + relative_slope = np.zeros(8) + return X, Y, Z, tracker_distance, relative_azimuth, relative_slope + + +def test_min_tracker_spacing_rectangle(rectangular_geometry): + # Test calculation of min_tracker_spacing for a rectangular collector + min_tracker_spacing = layout._calculate_min_tracker_spacing(rectangular_geometry[0]) + assert np.isclose(min_tracker_spacing, np.sqrt(4**2+2**2)) + + +def test_min_tracker_spacing_circle(): + # Test calculation of min_tracker_spacing for a circular collector with radius 1 + collector_geometry = geometry.Point(0, 0).buffer(1) + min_tracker_spacing = layout._calculate_min_tracker_spacing(collector_geometry) + assert min_tracker_spacing == 2 + + +def test_min_tracker_spacing_circle_offcenter(): + # Test calculation of min_tracker_spacing for a circular collector with radius 1 rotating + # off-center around the point (0, 1) + collector_geometry = geometry.Point(0, 1).buffer(1) + min_tracker_spacing = layout._calculate_min_tracker_spacing(collector_geometry) + assert min_tracker_spacing == 4 + + +def test_min_tracker_spacingpolygon(): + # Test calculation of min_tracker_spacing for a polygon + collector_geometry = geometry.Polygon([(-1, -1), (3, 2), (4, 4), (1, 2), (-1, -1)]) + min_tracker_spacing = layout._calculate_min_tracker_spacing(collector_geometry) + assert np.isclose(min_tracker_spacing, 2 * np.sqrt(4**2 + 4**2)) + + +def test_square_layout_generation(rectangular_geometry, square_field_layout): + # Test that a square field layout is returned correctly + collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry + X_exp, Y_exp, Z_exp, tracker_distance_exp, relative_azimuth_exp, relative_slope_exp = \ + square_field_layout + + X, Y, Z, tracker_distance, relative_azimuth, relative_slope = \ + layout.generate_field_layout( + gcr=0.125, + total_collector_area=total_collector_area, + min_tracker_spacing=min_tracker_spacing, + neighbor_order=1, + aspect_ratio=1, + offset=0, + rotation=0) + np.testing.assert_allclose(X, X_exp) + np.testing.assert_allclose(Y, Y_exp) + np.testing.assert_allclose(Z, Z_exp) + np.testing.assert_allclose(tracker_distance_exp, tracker_distance_exp) + np.testing.assert_allclose(relative_azimuth, relative_azimuth_exp) + np.testing.assert_allclose(relative_slope, relative_slope_exp) + + +def test_layout_generation_value_error(rectangular_geometry): + # Test if value errors are correctly raised + collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry + + # Test if ValueError is raised if offset is out of range + with pytest.raises(ValueError, match="offset is outside the valid range"): + _ = layout.generate_field_layout( + gcr=0.25, total_collector_area=total_collector_area, + min_tracker_spacing=min_tracker_spacing, neighbor_order=1, + aspect_ratio=1, offset=1.1, rotation=0) + + # Test if ValueError is raised if aspect ratio is too low + with pytest.raises(ValueError, match="Aspect ratio is too low"): + _ = layout.generate_field_layout( + gcr=0.25, total_collector_area=total_collector_area, + min_tracker_spacing=min_tracker_spacing, neighbor_order=1, + aspect_ratio=0.6, offset=0, rotation=0) + + # Test if ValueError is raised if aspect ratio is too high + with pytest.raises(ValueError, match="Aspect ratio is too high"): + _ = layout.generate_field_layout( + gcr=0.25, total_collector_area=total_collector_area, + min_tracker_spacing=min_tracker_spacing, neighbor_order=1, + aspect_ratio=5, offset=0, rotation=0) + + # Test if ValueError is raised if rotation is greater than 180 degrees + with pytest.raises(ValueError, match="rotation is outside the valid range"): + _ = layout.generate_field_layout( + gcr=0.25, total_collector_area=total_collector_area, + min_tracker_spacing=min_tracker_spacing, neighbor_order=1, + aspect_ratio=1.2, offset=0, rotation=190) + + # Test if ValueError is raised if rotation is less than 0 + with pytest.raises(ValueError, match="rotation is outside the valid range"): + _ = layout.generate_field_layout( + gcr=0.5, total_collector_area=total_collector_area, + min_tracker_spacing=min_tracker_spacing, neighbor_order=1, + aspect_ratio=1, offset=0, rotation=-1) + + # Test if ValueError is raised if min_tracker_spacing is outside valid range + with pytest.raises(ValueError, match="Lmin is not physically possible"): + _ = layout.generate_field_layout( + gcr=0.25, total_collector_area=total_collector_area, + min_tracker_spacing=1, neighbor_order=1, aspect_ratio=1.2, + offset=0, rotation=90) + + # Test if ValueError is raised if maximum ground cover ratio is exceeded + with pytest.raises(ValueError, match="Maximum ground cover ratio exceded"): + _ = layout.generate_field_layout( + gcr=0.5, total_collector_area=total_collector_area, + min_tracker_spacing=min_tracker_spacing, neighbor_order=1, + aspect_ratio=1, offset=0, rotation=0) + + +def test_field_slope(): + assert True + + +def test_neighbor_order(rectangular_geometry): + collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry + X, Y, Z, tracker_distance, relative_azimuth, relative_slope = \ + layout.generate_field_layout( + gcr=0.125, + total_collector_area=total_collector_area, + min_tracker_spacing=min_tracker_spacing, + neighbor_order=3, + aspect_ratio=1, + offset=0, + rotation=0) + assert len(X) == (7*7-1) diff --git a/twoaxistracking/tests/test_placeholder.py b/twoaxistracking/tests/test_placeholder.py deleted file mode 100644 index 8acf64e..0000000 --- a/twoaxistracking/tests/test_placeholder.py +++ /dev/null @@ -1,6 +0,0 @@ -import pytest # noqa: F401 -import twoaxistracking # noqa: F401 - - -def test_placeholder(): - pass diff --git a/twoaxistracking/tests/test_plotting.py b/twoaxistracking/tests/test_plotting.py new file mode 100644 index 0000000..3f00224 --- /dev/null +++ b/twoaxistracking/tests/test_plotting.py @@ -0,0 +1,52 @@ +import matplotlib.pyplot as plt +from twoaxistracking import plotting, layout, twoaxistrackerfield +from shapely import geometry +import numpy as np +import pytest + + +def assert_isinstance(obj, klass): + assert isinstance(obj, klass), f'got {type(obj)}, expected {klass}' + + +def test_field_layout_plot(): + X = np.array([-8, 0, 8, -8, 8, -8, 0, 8]) + Y = np.array([-8, -8, -8, 0, 0, 8, 8, 8]) + Z = np.array([0.1237, 0.0619, 0, 0.0619, -0.0619, 0, -0.0619, -0.1237]) + L_min = 4.4721 + result = plotting._plot_field_layout(X, Y, Z, L_min) + assert_isinstance(result, plt.Figure) + plt.close('all') + + +@pytest.fixture +def rectangular_geometry(): + collector_geometry = geometry.box(-2, -1, 2, 1) + total_collector_area = collector_geometry.area + min_tracker_spacing = layout._calculate_min_tracker_spacing(collector_geometry) + return collector_geometry, total_collector_area, min_tracker_spacing + + +def test_shading_plot(rectangular_geometry): + collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry + result = plotting._plot_shading(collector_geometry, collector_geometry, + collector_geometry, min_tracker_spacing) + assert_isinstance(result, plt.Figure) + plt.close('all') + + +def test_plotting_of_field_layout(rectangular_geometry): + # Test if plot_field_layout returns a figure object + collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry + field = twoaxistrackerfield.TwoAxisTrackerField( + total_collector_geometry=collector_geometry, + active_collector_geometry=collector_geometry, + neighbor_order=1, + gcr=0.25, + aspect_ratio=1, + offset=0.45, + rotation=30, + ) + result = field.plot_field_layout() + assert_isinstance(result, plt.Figure) + plt.close('all') diff --git a/twoaxistracking/tests/test_shading.py b/twoaxistracking/tests/test_shading.py new file mode 100644 index 0000000..8f99ba4 --- /dev/null +++ b/twoaxistracking/tests/test_shading.py @@ -0,0 +1,125 @@ +from twoaxistracking import shading, layout +from shapely import geometry +import numpy as np +import pytest + + +@pytest.fixture +def rectangular_geometry(): + collector_geometry = geometry.box(-2, -1, 2, 1) + total_collector_area = collector_geometry.area + min_tracker_spacing = layout._calculate_min_tracker_spacing(collector_geometry) + return collector_geometry, total_collector_area, min_tracker_spacing + + +@pytest.fixture +def square_field_layout(): + # Corresponds to GCR 0.125 with the rectangular_geometry + X = np.array([-8, 0, 8, -8, 8, -8, 0, 8]) + Y = np.array([-8, -8, -8, 0, 0, 8, 8, 8]) + tracker_distance = (X**2 + Y**2)**0.5 + relative_azimuth = np.array([225, 180, 135, 270, 90, 315, 0, 45]) + Z = np.zeros(8) + relative_slope = np.zeros(8) + return X, Y, Z, tracker_distance, relative_azimuth, relative_slope + + +def test_shading(rectangular_geometry, square_field_layout): + # Test shading calculation + # Also plots the geometry (ensures no errors occurs) + collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry + X, Y, Z, tracker_distance, relative_azimuth, relative_slope = \ + square_field_layout + shaded_fraction = shading.shaded_fraction( + solar_elevation=3, + solar_azimuth=120, + total_collector_geometry=collector_geometry, + active_collector_geometry=collector_geometry, + min_tracker_spacing=min_tracker_spacing, + tracker_distance=tracker_distance, + relative_azimuth=relative_azimuth, + relative_slope=relative_slope, + slope_azimuth=0, + slope_tilt=0, + plot=True) + assert np.isclose(shaded_fraction, 0.191324) + + +def test_shading_zero_solar_elevation(rectangular_geometry, square_field_layout): + # Test shading when geometries completly overlap + collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry + X, Y, Z, tracker_distance, relative_azimuth, relative_slope = \ + square_field_layout + shaded_fraction = shading.shaded_fraction( + solar_elevation=0, + solar_azimuth=180, + total_collector_geometry=collector_geometry, + active_collector_geometry=collector_geometry, + min_tracker_spacing=min_tracker_spacing, + tracker_distance=tracker_distance, + relative_azimuth=relative_azimuth, + relative_slope=relative_slope, + slope_azimuth=0, + slope_tilt=0, + plot=False) + assert shaded_fraction == 1 + + +def test_no_shading(rectangular_geometry, square_field_layout): + # Test shading calculation when there is no shading (high solar elevation) + collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry + X, Y, Z, tracker_distance, relative_azimuth, relative_slope = \ + square_field_layout + shaded_fraction = shading.shaded_fraction( + solar_elevation=45, + solar_azimuth=180, + total_collector_geometry=collector_geometry, + active_collector_geometry=collector_geometry, + min_tracker_spacing=min_tracker_spacing, + tracker_distance=tracker_distance, + relative_azimuth=relative_azimuth, + relative_slope=relative_slope, + slope_azimuth=0, + slope_tilt=0, + plot=False) + assert shaded_fraction == 0 + + +def test_shading_below_horizon(rectangular_geometry, square_field_layout): + # Test shading calculation when sun is below the horizon (elevation<0) + collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry + X, Y, Z, tracker_distance, relative_azimuth, relative_slope = \ + square_field_layout + shaded_fraction = shading.shaded_fraction( + solar_elevation=-5.1, + solar_azimuth=180, + total_collector_geometry=collector_geometry, + active_collector_geometry=collector_geometry, + min_tracker_spacing=min_tracker_spacing, + tracker_distance=tracker_distance, + relative_azimuth=relative_azimuth, + relative_slope=relative_slope, + slope_azimuth=0, + slope_tilt=0, + plot=False) + assert np.isnan(shaded_fraction) + + +def test_shading_below_hill_horizon(rectangular_geometry, square_field_layout): + # Test shading calculation when there is no shading (high solar elevation) + collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry + X, Y, Z, tracker_distance, relative_azimuth, relative_slope = \ + square_field_layout + shaded_fraction = shading.shaded_fraction( + solar_elevation=9, + solar_azimuth=180, + total_collector_geometry=collector_geometry, + active_collector_geometry=collector_geometry, + min_tracker_spacing=min_tracker_spacing, + tracker_distance=tracker_distance, + relative_azimuth=relative_azimuth, + relative_slope=relative_slope, + slope_azimuth=0, + slope_tilt=10, + plot=False) + assert shaded_fraction == 1 diff --git a/twoaxistracking/tests/test_twoaxistrackerfield.py b/twoaxistracking/tests/test_twoaxistrackerfield.py new file mode 100644 index 0000000..551fae7 --- /dev/null +++ b/twoaxistracking/tests/test_twoaxistrackerfield.py @@ -0,0 +1,201 @@ +from twoaxistracking import layout, twoaxistrackerfield +from shapely import geometry +import numpy as np +import pandas as pd +import pytest + + +@pytest.fixture +def rectangular_geometry(): + collector_geometry = geometry.box(-2, -1, 2, 1) + total_collector_area = collector_geometry.area + min_tracker_spacing = layout._calculate_min_tracker_spacing(collector_geometry) + return collector_geometry, total_collector_area, min_tracker_spacing + + +def test_invalid_layout_type(rectangular_geometry): + # Test if ValueError is raised when an incorrect layout_type is specified + collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry + with pytest.raises(ValueError, match="Layout type must be one of"): + _ = twoaxistrackerfield.TwoAxisTrackerField( + total_collector_geometry=collector_geometry, + active_collector_geometry=collector_geometry, + neighbor_order=1, + gcr=0.25, + layout_type='this_is_not_a_layout_type') + + +def test_square_layout_type(rectangular_geometry): + # Assert that layout field parameters are correctly set for the square layout + collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry + field = twoaxistrackerfield.TwoAxisTrackerField( + total_collector_geometry=collector_geometry, + active_collector_geometry=collector_geometry, + neighbor_order=2, + gcr=0.25, + layout_type='square') + assert field.gcr == 0.25 + assert field.aspect_ratio == 1 + assert field.offset == 0 + assert field.rotation == 0 + + +def test_diagonal_layout_type(rectangular_geometry): + # Assert that layout field parameters are correctly set for the diagonal layout + collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry + field = twoaxistrackerfield.TwoAxisTrackerField( + total_collector_geometry=collector_geometry, + active_collector_geometry=collector_geometry, + neighbor_order=2, + gcr=0.1, + layout_type='diagonal') + assert field.gcr == 0.1 + assert field.aspect_ratio == 1 + assert field.offset == 0 + assert field.rotation == 45 + + +def test_hexagonal_n_s_layout_type(rectangular_geometry): + # Assert that layout field parameters are correctly set for the diagonal layout + collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry + field = twoaxistrackerfield.TwoAxisTrackerField( + total_collector_geometry=collector_geometry, + active_collector_geometry=collector_geometry, + neighbor_order=4, + gcr=0.4, + layout_type='hexagonal_n_s') + assert field.gcr == 0.4 + assert field.aspect_ratio == np.sqrt(3)/2 + assert field.offset == -0.5 + assert field.rotation == 0 + + +def test_hexagonal_e_w_layout_type(rectangular_geometry): + # Assert that layout field parameters are correctly set for the diagonal layout + collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry + field = twoaxistrackerfield.TwoAxisTrackerField( + total_collector_geometry=collector_geometry, + active_collector_geometry=collector_geometry, + neighbor_order=4, + gcr=0.4, + layout_type='hexagonal_e_w') + assert field.gcr == 0.4 + assert field.aspect_ratio == np.sqrt(3)/2 + assert field.offset == -0.5 + assert field.rotation == 90 + + +def test_unspecifed_layout_type(rectangular_geometry): + # Test if ValueError is raised when one or more layout parameters are unspecified + collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry + with pytest.raises(ValueError, match="needs to be specified"): + _ = twoaxistrackerfield.TwoAxisTrackerField( + total_collector_geometry=collector_geometry, + active_collector_geometry=collector_geometry, + neighbor_order=1, + gcr=0.25, + aspect_ratio=1, + offset=0, + # rotation unspecified + ) + + +@pytest.fixture +def solar_position(): + solar_elevation = [-1, 0, 1, 2, 40] + solar_azimuth = [90, 100, 110, 120, 180] + return solar_elevation, solar_azimuth + + +@pytest.fixture +def expected_shaded_fraction(): + return [np.nan, 1.0, 0.7177496, 0.6036017, 0.0] + + +@pytest.fixture +def expected_datetime_index(): + return pd.date_range('2020-01-01 12', freq='15min', periods=5) + + +def test_calculation_of_shaded_fraction_list(rectangular_geometry, solar_position, + expected_shaded_fraction): + # Test if shaded fraction is calculated correct when solar elevation and + # azimuth are lists + collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry + field = twoaxistrackerfield.TwoAxisTrackerField( + total_collector_geometry=collector_geometry, + active_collector_geometry=collector_geometry, + neighbor_order=1, + gcr=0.25, + aspect_ratio=1, + offset=0, + rotation=170) + solar_elevation, solar_azimuth = solar_position + result = field.get_shaded_fraction(solar_elevation, solar_azimuth) + # Test that calculated shaded fraction are equal or both nan + # using np.isclose(np.nan, np.nan) does not identify + np.testing.assert_allclose(result, expected_shaded_fraction) + assert isinstance(result, list) + + +def test_calculation_of_shaded_fraction_series( + rectangular_geometry, solar_position, expected_shaded_fraction, expected_datetime_index): + # Test if shaded fraction is calculated correct when solar elevation and + # azimuth are pandas Series + collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry + field = twoaxistrackerfield.TwoAxisTrackerField( + total_collector_geometry=collector_geometry, + active_collector_geometry=collector_geometry, + neighbor_order=1, + gcr=0.25, + aspect_ratio=1, + offset=0, + rotation=170) + solar_elevation, solar_azimuth = solar_position + solar_elevation = pd.Series(solar_elevation) + solar_azimuth = pd.Series(solar_azimuth) + solar_elevation.index = expected_datetime_index + solar_azimuth.index = expected_datetime_index + result = field.get_shaded_fraction(solar_elevation, solar_azimuth) + + np.testing.assert_allclose(result, expected_shaded_fraction) + assert isinstance(result, pd.Series) + pd.testing.assert_index_equal(result.index, solar_elevation.index) + + +def test_calculation_of_shaded_fraction_array(rectangular_geometry, solar_position, + expected_shaded_fraction): + # Test if shaded fraction is calculated correct when solar elevation and + # azimuth are numpy arrays + collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry + field = twoaxistrackerfield.TwoAxisTrackerField( + total_collector_geometry=collector_geometry, + active_collector_geometry=collector_geometry, + neighbor_order=1, + gcr=0.25, + aspect_ratio=1, + offset=0, + rotation=170) + solar_elevation, solar_azimuth = solar_position + result = field.get_shaded_fraction(np.array(solar_elevation), np.array(solar_azimuth)) + # Test that calculated shaded fraction are equal or both nan + # using np.isclose(np.nan, np.nan) does not identify + np.testing.assert_allclose(result, expected_shaded_fraction) + assert isinstance(result, np.ndarray) + + +def test_calculation_of_shaded_fraction_float(rectangular_geometry): + # Test if shaded fraction is calculated correct when solar elevation and + # azimuth are scalar + collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry + field = twoaxistrackerfield.TwoAxisTrackerField( + total_collector_geometry=collector_geometry, + active_collector_geometry=collector_geometry, + neighbor_order=1, + gcr=0.25, + aspect_ratio=1, + offset=0, + rotation=170) + result = field.get_shaded_fraction(40, 180) + np.testing.assert_allclose(result, 0) + assert np.isscalar(result) From 0cdfffc42341c962789b3b807bab6c038cd6120b Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Tue, 1 Mar 2022 00:26:08 +0100 Subject: [PATCH 36/48] Switch to using np.testing.assert_allclose --- twoaxistracking/tests/test_layout.py | 16 ++++++++++++++-- twoaxistracking/tests/test_shading.py | 8 ++++---- .../tests/test_twoaxistrackerfield.py | 10 ++++++---- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/twoaxistracking/tests/test_layout.py b/twoaxistracking/tests/test_layout.py index ce95077..38e4dec 100644 --- a/twoaxistracking/tests/test_layout.py +++ b/twoaxistracking/tests/test_layout.py @@ -24,10 +24,22 @@ def square_field_layout(): return X, Y, Z, tracker_distance, relative_azimuth, relative_slope +@pytest.fixture +def square_field_layout_sloped(): + # Corresponds to GCR 0.125 with the rectangular_geometry + X = np.array([-8, 0, 8, -8, 8, -8, 0, 8]) + Y = np.array([-8, -8, -8, 0, 0, 8, 8, 8]) + tracker_distance = (X**2 + Y**2)**0.5 + relative_azimuth = np.array([225, 180, 135, 270, 90, 315, 0, 45]) + Z = + relative_slope = + return X, Y, Z, tracker_distance, relative_azimuth, relative_slope + + def test_min_tracker_spacing_rectangle(rectangular_geometry): # Test calculation of min_tracker_spacing for a rectangular collector min_tracker_spacing = layout._calculate_min_tracker_spacing(rectangular_geometry[0]) - assert np.isclose(min_tracker_spacing, np.sqrt(4**2+2**2)) + np.testing.assert_allclose(min_tracker_spacing, np.sqrt(4**2+2**2)) def test_min_tracker_spacing_circle(): @@ -49,7 +61,7 @@ def test_min_tracker_spacingpolygon(): # Test calculation of min_tracker_spacing for a polygon collector_geometry = geometry.Polygon([(-1, -1), (3, 2), (4, 4), (1, 2), (-1, -1)]) min_tracker_spacing = layout._calculate_min_tracker_spacing(collector_geometry) - assert np.isclose(min_tracker_spacing, 2 * np.sqrt(4**2 + 4**2)) + np.testing.assert_allclose(min_tracker_spacing, 2 * np.sqrt(4**2 + 4**2)) def test_square_layout_generation(rectangular_geometry, square_field_layout): diff --git a/twoaxistracking/tests/test_shading.py b/twoaxistracking/tests/test_shading.py index 8f99ba4..4ca3a4f 100644 --- a/twoaxistracking/tests/test_shading.py +++ b/twoaxistracking/tests/test_shading.py @@ -26,7 +26,7 @@ def square_field_layout(): def test_shading(rectangular_geometry, square_field_layout): # Test shading calculation - # Also plots the geometry (ensures no errors occurs) + # Also plots the geometry (ensures no errors are raised) collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry X, Y, Z, tracker_distance, relative_azimuth, relative_slope = \ square_field_layout @@ -42,11 +42,11 @@ def test_shading(rectangular_geometry, square_field_layout): slope_azimuth=0, slope_tilt=0, plot=True) - assert np.isclose(shaded_fraction, 0.191324) + np.testing.assert_allclose(shaded_fraction, 0.191324) def test_shading_zero_solar_elevation(rectangular_geometry, square_field_layout): - # Test shading when geometries completly overlap + # Test shading when geometries completely overlap collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry X, Y, Z, tracker_distance, relative_azimuth, relative_slope = \ square_field_layout @@ -106,7 +106,7 @@ def test_shading_below_horizon(rectangular_geometry, square_field_layout): def test_shading_below_hill_horizon(rectangular_geometry, square_field_layout): - # Test shading calculation when there is no shading (high solar elevation) + # Test shading when sun is below horizon line caused by sloped surface collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry X, Y, Z, tracker_distance, relative_azimuth, relative_slope = \ square_field_layout diff --git a/twoaxistracking/tests/test_twoaxistrackerfield.py b/twoaxistracking/tests/test_twoaxistrackerfield.py index 551fae7..d8935ca 100644 --- a/twoaxistracking/tests/test_twoaxistrackerfield.py +++ b/twoaxistracking/tests/test_twoaxistrackerfield.py @@ -132,9 +132,9 @@ def test_calculation_of_shaded_fraction_list(rectangular_geometry, solar_positio rotation=170) solar_elevation, solar_azimuth = solar_position result = field.get_shaded_fraction(solar_elevation, solar_azimuth) - # Test that calculated shaded fraction are equal or both nan - # using np.isclose(np.nan, np.nan) does not identify + # Compare the calculated and expected shaded fraction np.testing.assert_allclose(result, expected_shaded_fraction) + # Check that the output is of the same type as the inputs assert isinstance(result, list) @@ -151,6 +151,7 @@ def test_calculation_of_shaded_fraction_series( aspect_ratio=1, offset=0, rotation=170) + # Set solar elevation and azimuth as pandas Series with datetime index solar_elevation, solar_azimuth = solar_position solar_elevation = pd.Series(solar_elevation) solar_azimuth = pd.Series(solar_azimuth) @@ -160,6 +161,7 @@ def test_calculation_of_shaded_fraction_series( np.testing.assert_allclose(result, expected_shaded_fraction) assert isinstance(result, pd.Series) + # Check that returned series of shaded fraction has correct index pd.testing.assert_index_equal(result.index, solar_elevation.index) @@ -178,8 +180,7 @@ def test_calculation_of_shaded_fraction_array(rectangular_geometry, solar_positi rotation=170) solar_elevation, solar_azimuth = solar_position result = field.get_shaded_fraction(np.array(solar_elevation), np.array(solar_azimuth)) - # Test that calculated shaded fraction are equal or both nan - # using np.isclose(np.nan, np.nan) does not identify + np.testing.assert_allclose(result, expected_shaded_fraction) assert isinstance(result, np.ndarray) @@ -196,6 +197,7 @@ def test_calculation_of_shaded_fraction_float(rectangular_geometry): aspect_ratio=1, offset=0, rotation=170) + result = field.get_shaded_fraction(40, 180) np.testing.assert_allclose(result, 0) assert np.isscalar(result) From 13c7bd552d0e18acf6df12177e5b0989a8c61e4c Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Tue, 1 Mar 2022 00:40:52 +0100 Subject: [PATCH 37/48] Add test for sloped field layout --- twoaxistracking/tests/test_layout.py | 34 ++++++++++++++++++++++----- twoaxistracking/tests/test_shading.py | 2 +- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/twoaxistracking/tests/test_layout.py b/twoaxistracking/tests/test_layout.py index 38e4dec..69b59e8 100644 --- a/twoaxistracking/tests/test_layout.py +++ b/twoaxistracking/tests/test_layout.py @@ -31,8 +31,10 @@ def square_field_layout_sloped(): Y = np.array([-8, -8, -8, 0, 0, 8, 8, 8]) tracker_distance = (X**2 + Y**2)**0.5 relative_azimuth = np.array([225, 180, 135, 270, 90, 315, 0, 45]) - Z = - relative_slope = + Z = np.array([0.12372765, 0.06186383, 0, 0.06186383, + -0.06186383, 0, -0.06186383, -0.12372765]) + relative_slope = np.array([5, 3.53553391, 0, 3.53553391, + -3.53553391, 0, -3.53553391, -5]) return X, Y, Z, tracker_distance, relative_azimuth, relative_slope @@ -87,6 +89,30 @@ def test_square_layout_generation(rectangular_geometry, square_field_layout): np.testing.assert_allclose(relative_slope, relative_slope_exp) +def test_field_slope(rectangular_geometry, square_field_layout_sloped): + # Test that a square field layout on tilted surface is returned correctly + collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry + X_exp, Y_exp, Z_exp, tracker_distance_exp, relative_azimuth_exp, relative_slope_exp = \ + square_field_layout_sloped + X, Y, Z, tracker_distance, relative_azimuth, relative_slope = \ + layout.generate_field_layout( + gcr=0.125, + total_collector_area=total_collector_area, + min_tracker_spacing=min_tracker_spacing, + neighbor_order=1, + aspect_ratio=1, + offset=0, + rotation=0, + slope_azimuth=45, + slope_tilt=5) + np.testing.assert_allclose(X, X_exp) + np.testing.assert_allclose(Y, Y_exp) + np.testing.assert_allclose(Z, Z_exp) + np.testing.assert_allclose(tracker_distance_exp, tracker_distance_exp) + np.testing.assert_allclose(relative_azimuth, relative_azimuth_exp) + np.testing.assert_allclose(relative_slope, relative_slope_exp, atol=10**-9) + + def test_layout_generation_value_error(rectangular_geometry): # Test if value errors are correctly raised collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry @@ -141,10 +167,6 @@ def test_layout_generation_value_error(rectangular_geometry): aspect_ratio=1, offset=0, rotation=0) -def test_field_slope(): - assert True - - def test_neighbor_order(rectangular_geometry): collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry X, Y, Z, tracker_distance, relative_azimuth, relative_slope = \ diff --git a/twoaxistracking/tests/test_shading.py b/twoaxistracking/tests/test_shading.py index 4ca3a4f..a646801 100644 --- a/twoaxistracking/tests/test_shading.py +++ b/twoaxistracking/tests/test_shading.py @@ -42,7 +42,7 @@ def test_shading(rectangular_geometry, square_field_layout): slope_azimuth=0, slope_tilt=0, plot=True) - np.testing.assert_allclose(shaded_fraction, 0.191324) + np.testing.assert_allclose(shaded_fraction, 0.191324034) def test_shading_zero_solar_elevation(rectangular_geometry, square_field_layout): From 4a752407145e1975bf9b0ae654baabe5e0c95c46 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Tue, 1 Mar 2022 13:55:06 +0100 Subject: [PATCH 38/48] Move test_twoaxistracker to twoaxistracker PR --- .../tests/test_twoaxistrackerfield.py | 203 ------------------ 1 file changed, 203 deletions(-) delete mode 100644 twoaxistracking/tests/test_twoaxistrackerfield.py diff --git a/twoaxistracking/tests/test_twoaxistrackerfield.py b/twoaxistracking/tests/test_twoaxistrackerfield.py deleted file mode 100644 index d8935ca..0000000 --- a/twoaxistracking/tests/test_twoaxistrackerfield.py +++ /dev/null @@ -1,203 +0,0 @@ -from twoaxistracking import layout, twoaxistrackerfield -from shapely import geometry -import numpy as np -import pandas as pd -import pytest - - -@pytest.fixture -def rectangular_geometry(): - collector_geometry = geometry.box(-2, -1, 2, 1) - total_collector_area = collector_geometry.area - min_tracker_spacing = layout._calculate_min_tracker_spacing(collector_geometry) - return collector_geometry, total_collector_area, min_tracker_spacing - - -def test_invalid_layout_type(rectangular_geometry): - # Test if ValueError is raised when an incorrect layout_type is specified - collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry - with pytest.raises(ValueError, match="Layout type must be one of"): - _ = twoaxistrackerfield.TwoAxisTrackerField( - total_collector_geometry=collector_geometry, - active_collector_geometry=collector_geometry, - neighbor_order=1, - gcr=0.25, - layout_type='this_is_not_a_layout_type') - - -def test_square_layout_type(rectangular_geometry): - # Assert that layout field parameters are correctly set for the square layout - collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry - field = twoaxistrackerfield.TwoAxisTrackerField( - total_collector_geometry=collector_geometry, - active_collector_geometry=collector_geometry, - neighbor_order=2, - gcr=0.25, - layout_type='square') - assert field.gcr == 0.25 - assert field.aspect_ratio == 1 - assert field.offset == 0 - assert field.rotation == 0 - - -def test_diagonal_layout_type(rectangular_geometry): - # Assert that layout field parameters are correctly set for the diagonal layout - collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry - field = twoaxistrackerfield.TwoAxisTrackerField( - total_collector_geometry=collector_geometry, - active_collector_geometry=collector_geometry, - neighbor_order=2, - gcr=0.1, - layout_type='diagonal') - assert field.gcr == 0.1 - assert field.aspect_ratio == 1 - assert field.offset == 0 - assert field.rotation == 45 - - -def test_hexagonal_n_s_layout_type(rectangular_geometry): - # Assert that layout field parameters are correctly set for the diagonal layout - collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry - field = twoaxistrackerfield.TwoAxisTrackerField( - total_collector_geometry=collector_geometry, - active_collector_geometry=collector_geometry, - neighbor_order=4, - gcr=0.4, - layout_type='hexagonal_n_s') - assert field.gcr == 0.4 - assert field.aspect_ratio == np.sqrt(3)/2 - assert field.offset == -0.5 - assert field.rotation == 0 - - -def test_hexagonal_e_w_layout_type(rectangular_geometry): - # Assert that layout field parameters are correctly set for the diagonal layout - collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry - field = twoaxistrackerfield.TwoAxisTrackerField( - total_collector_geometry=collector_geometry, - active_collector_geometry=collector_geometry, - neighbor_order=4, - gcr=0.4, - layout_type='hexagonal_e_w') - assert field.gcr == 0.4 - assert field.aspect_ratio == np.sqrt(3)/2 - assert field.offset == -0.5 - assert field.rotation == 90 - - -def test_unspecifed_layout_type(rectangular_geometry): - # Test if ValueError is raised when one or more layout parameters are unspecified - collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry - with pytest.raises(ValueError, match="needs to be specified"): - _ = twoaxistrackerfield.TwoAxisTrackerField( - total_collector_geometry=collector_geometry, - active_collector_geometry=collector_geometry, - neighbor_order=1, - gcr=0.25, - aspect_ratio=1, - offset=0, - # rotation unspecified - ) - - -@pytest.fixture -def solar_position(): - solar_elevation = [-1, 0, 1, 2, 40] - solar_azimuth = [90, 100, 110, 120, 180] - return solar_elevation, solar_azimuth - - -@pytest.fixture -def expected_shaded_fraction(): - return [np.nan, 1.0, 0.7177496, 0.6036017, 0.0] - - -@pytest.fixture -def expected_datetime_index(): - return pd.date_range('2020-01-01 12', freq='15min', periods=5) - - -def test_calculation_of_shaded_fraction_list(rectangular_geometry, solar_position, - expected_shaded_fraction): - # Test if shaded fraction is calculated correct when solar elevation and - # azimuth are lists - collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry - field = twoaxistrackerfield.TwoAxisTrackerField( - total_collector_geometry=collector_geometry, - active_collector_geometry=collector_geometry, - neighbor_order=1, - gcr=0.25, - aspect_ratio=1, - offset=0, - rotation=170) - solar_elevation, solar_azimuth = solar_position - result = field.get_shaded_fraction(solar_elevation, solar_azimuth) - # Compare the calculated and expected shaded fraction - np.testing.assert_allclose(result, expected_shaded_fraction) - # Check that the output is of the same type as the inputs - assert isinstance(result, list) - - -def test_calculation_of_shaded_fraction_series( - rectangular_geometry, solar_position, expected_shaded_fraction, expected_datetime_index): - # Test if shaded fraction is calculated correct when solar elevation and - # azimuth are pandas Series - collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry - field = twoaxistrackerfield.TwoAxisTrackerField( - total_collector_geometry=collector_geometry, - active_collector_geometry=collector_geometry, - neighbor_order=1, - gcr=0.25, - aspect_ratio=1, - offset=0, - rotation=170) - # Set solar elevation and azimuth as pandas Series with datetime index - solar_elevation, solar_azimuth = solar_position - solar_elevation = pd.Series(solar_elevation) - solar_azimuth = pd.Series(solar_azimuth) - solar_elevation.index = expected_datetime_index - solar_azimuth.index = expected_datetime_index - result = field.get_shaded_fraction(solar_elevation, solar_azimuth) - - np.testing.assert_allclose(result, expected_shaded_fraction) - assert isinstance(result, pd.Series) - # Check that returned series of shaded fraction has correct index - pd.testing.assert_index_equal(result.index, solar_elevation.index) - - -def test_calculation_of_shaded_fraction_array(rectangular_geometry, solar_position, - expected_shaded_fraction): - # Test if shaded fraction is calculated correct when solar elevation and - # azimuth are numpy arrays - collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry - field = twoaxistrackerfield.TwoAxisTrackerField( - total_collector_geometry=collector_geometry, - active_collector_geometry=collector_geometry, - neighbor_order=1, - gcr=0.25, - aspect_ratio=1, - offset=0, - rotation=170) - solar_elevation, solar_azimuth = solar_position - result = field.get_shaded_fraction(np.array(solar_elevation), np.array(solar_azimuth)) - - np.testing.assert_allclose(result, expected_shaded_fraction) - assert isinstance(result, np.ndarray) - - -def test_calculation_of_shaded_fraction_float(rectangular_geometry): - # Test if shaded fraction is calculated correct when solar elevation and - # azimuth are scalar - collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry - field = twoaxistrackerfield.TwoAxisTrackerField( - total_collector_geometry=collector_geometry, - active_collector_geometry=collector_geometry, - neighbor_order=1, - gcr=0.25, - aspect_ratio=1, - offset=0, - rotation=170) - - result = field.get_shaded_fraction(40, 180) - np.testing.assert_allclose(result, 0) - assert np.isscalar(result) From a9f368a583dd31dc3ee20e61d4dec86c612c3643 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Tue, 1 Mar 2022 16:05:14 +0100 Subject: [PATCH 39/48] Add conftest.py to avoid duplicate fixtures --- twoaxistracking/tests/conftest.py | 28 ++++++++++++++++++++++++++ twoaxistracking/tests/test_layout.py | 21 +------------------ twoaxistracking/tests/test_plotting.py | 17 ++-------------- twoaxistracking/tests/test_shading.py | 24 ++-------------------- 4 files changed, 33 insertions(+), 57 deletions(-) create mode 100644 twoaxistracking/tests/conftest.py diff --git a/twoaxistracking/tests/conftest.py b/twoaxistracking/tests/conftest.py new file mode 100644 index 0000000..e90a461 --- /dev/null +++ b/twoaxistracking/tests/conftest.py @@ -0,0 +1,28 @@ +import pytest +from shapely import geometry +import numpy as np +from twoaxistracking import layout + + +@pytest.fixture +def rectangular_geometry(): + collector_geometry = geometry.box(-2, -1, 2, 1) + total_collector_area = collector_geometry.area + min_tracker_spacing = layout._calculate_min_tracker_spacing(collector_geometry) + return collector_geometry, total_collector_area, min_tracker_spacing + + +@pytest.fixture +def square_field_layout(): + # Corresponds to GCR 0.125 with the rectangular_geometry + X = np.array([-8, 0, 8, -8, 8, -8, 0, 8]) + Y = np.array([-8, -8, -8, 0, 0, 8, 8, 8]) + tracker_distance = (X**2 + Y**2)**0.5 + relative_azimuth = np.array([225, 180, 135, 270, 90, 315, 0, 45]) + Z = np.zeros(8) + relative_slope = np.zeros(8) + return X, Y, Z, tracker_distance, relative_azimuth, relative_slope + + +def assert_isinstance(obj, klass): + assert isinstance(obj, klass), f'got {type(obj)}, expected {klass}' diff --git a/twoaxistracking/tests/test_layout.py b/twoaxistracking/tests/test_layout.py index 69b59e8..461f9f3 100644 --- a/twoaxistracking/tests/test_layout.py +++ b/twoaxistracking/tests/test_layout.py @@ -2,26 +2,7 @@ from shapely import geometry import numpy as np import pytest - - -@pytest.fixture -def rectangular_geometry(): - collector_geometry = geometry.box(-2, -1, 2, 1) - total_collector_area = collector_geometry.area - min_tracker_spacing = layout._calculate_min_tracker_spacing(collector_geometry) - return collector_geometry, total_collector_area, min_tracker_spacing - - -@pytest.fixture -def square_field_layout(): - # Corresponds to GCR 0.125 with the rectangular_geometry - X = np.array([-8, 0, 8, -8, 8, -8, 0, 8]) - Y = np.array([-8, -8, -8, 0, 0, 8, 8, 8]) - tracker_distance = (X**2 + Y**2)**0.5 - relative_azimuth = np.array([225, 180, 135, 270, 90, 315, 0, 45]) - Z = np.zeros(8) - relative_slope = np.zeros(8) - return X, Y, Z, tracker_distance, relative_azimuth, relative_slope +from conftest import rectangular_geometry, square_field_layout @pytest.fixture diff --git a/twoaxistracking/tests/test_plotting.py b/twoaxistracking/tests/test_plotting.py index 3f00224..3f9978c 100644 --- a/twoaxistracking/tests/test_plotting.py +++ b/twoaxistracking/tests/test_plotting.py @@ -1,12 +1,7 @@ import matplotlib.pyplot as plt -from twoaxistracking import plotting, layout, twoaxistrackerfield -from shapely import geometry +from twoaxistracking import plotting, twoaxistrackerfield +from conftest import rectangular_geometry, assert_isinstance import numpy as np -import pytest - - -def assert_isinstance(obj, klass): - assert isinstance(obj, klass), f'got {type(obj)}, expected {klass}' def test_field_layout_plot(): @@ -19,14 +14,6 @@ def test_field_layout_plot(): plt.close('all') -@pytest.fixture -def rectangular_geometry(): - collector_geometry = geometry.box(-2, -1, 2, 1) - total_collector_area = collector_geometry.area - min_tracker_spacing = layout._calculate_min_tracker_spacing(collector_geometry) - return collector_geometry, total_collector_area, min_tracker_spacing - - def test_shading_plot(rectangular_geometry): collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry result = plotting._plot_shading(collector_geometry, collector_geometry, diff --git a/twoaxistracking/tests/test_shading.py b/twoaxistracking/tests/test_shading.py index a646801..247c16b 100644 --- a/twoaxistracking/tests/test_shading.py +++ b/twoaxistracking/tests/test_shading.py @@ -1,27 +1,7 @@ -from twoaxistracking import shading, layout +from twoaxistracking import shading from shapely import geometry import numpy as np -import pytest - - -@pytest.fixture -def rectangular_geometry(): - collector_geometry = geometry.box(-2, -1, 2, 1) - total_collector_area = collector_geometry.area - min_tracker_spacing = layout._calculate_min_tracker_spacing(collector_geometry) - return collector_geometry, total_collector_area, min_tracker_spacing - - -@pytest.fixture -def square_field_layout(): - # Corresponds to GCR 0.125 with the rectangular_geometry - X = np.array([-8, 0, 8, -8, 8, -8, 0, 8]) - Y = np.array([-8, -8, -8, 0, 0, 8, 8, 8]) - tracker_distance = (X**2 + Y**2)**0.5 - relative_azimuth = np.array([225, 180, 135, 270, 90, 315, 0, 45]) - Z = np.zeros(8) - relative_slope = np.zeros(8) - return X, Y, Z, tracker_distance, relative_azimuth, relative_slope +from conftest import rectangular_geometry, square_field_layout def test_shading(rectangular_geometry, square_field_layout): From c517f4e434578df0c01de96a605d2324f191d3cb Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Tue, 1 Mar 2022 18:13:42 +0100 Subject: [PATCH 40/48] Remove imports of fixtures from conftest --- twoaxistracking/tests/test_layout.py | 1 - twoaxistracking/tests/test_plotting.py | 2 +- twoaxistracking/tests/test_shading.py | 2 -- twoaxistracking/tests/test_twoaxistrackerfield.py | 8 -------- 4 files changed, 1 insertion(+), 12 deletions(-) diff --git a/twoaxistracking/tests/test_layout.py b/twoaxistracking/tests/test_layout.py index 461f9f3..ca18b47 100644 --- a/twoaxistracking/tests/test_layout.py +++ b/twoaxistracking/tests/test_layout.py @@ -2,7 +2,6 @@ from shapely import geometry import numpy as np import pytest -from conftest import rectangular_geometry, square_field_layout @pytest.fixture diff --git a/twoaxistracking/tests/test_plotting.py b/twoaxistracking/tests/test_plotting.py index 3f9978c..6cd46a5 100644 --- a/twoaxistracking/tests/test_plotting.py +++ b/twoaxistracking/tests/test_plotting.py @@ -1,6 +1,6 @@ import matplotlib.pyplot as plt from twoaxistracking import plotting, twoaxistrackerfield -from conftest import rectangular_geometry, assert_isinstance +from conftest import assert_isinstance import numpy as np diff --git a/twoaxistracking/tests/test_shading.py b/twoaxistracking/tests/test_shading.py index 247c16b..00c13a5 100644 --- a/twoaxistracking/tests/test_shading.py +++ b/twoaxistracking/tests/test_shading.py @@ -1,7 +1,5 @@ from twoaxistracking import shading -from shapely import geometry import numpy as np -from conftest import rectangular_geometry, square_field_layout def test_shading(rectangular_geometry, square_field_layout): diff --git a/twoaxistracking/tests/test_twoaxistrackerfield.py b/twoaxistracking/tests/test_twoaxistrackerfield.py index d8935ca..197db1a 100644 --- a/twoaxistracking/tests/test_twoaxistrackerfield.py +++ b/twoaxistracking/tests/test_twoaxistrackerfield.py @@ -5,14 +5,6 @@ import pytest -@pytest.fixture -def rectangular_geometry(): - collector_geometry = geometry.box(-2, -1, 2, 1) - total_collector_area = collector_geometry.area - min_tracker_spacing = layout._calculate_min_tracker_spacing(collector_geometry) - return collector_geometry, total_collector_area, min_tracker_spacing - - def test_invalid_layout_type(rectangular_geometry): # Test if ValueError is raised when an incorrect layout_type is specified collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry From 37ee22fb0d898a2edba61abc1e5e80bd094f0fa1 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Tue, 1 Mar 2022 18:15:26 +0100 Subject: [PATCH 41/48] Remove unnecessary imports --- twoaxistracking/tests/test_twoaxistrackerfield.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/twoaxistracking/tests/test_twoaxistrackerfield.py b/twoaxistracking/tests/test_twoaxistrackerfield.py index 197db1a..6be0c3f 100644 --- a/twoaxistracking/tests/test_twoaxistrackerfield.py +++ b/twoaxistracking/tests/test_twoaxistrackerfield.py @@ -1,5 +1,4 @@ -from twoaxistracking import layout, twoaxistrackerfield -from shapely import geometry +from twoaxistracking import twoaxistrackerfield import numpy as np import pandas as pd import pytest From eda911a273ec4f8619e08e8881a4aee07175a7ac Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Tue, 1 Mar 2022 18:45:22 +0100 Subject: [PATCH 42/48] Increase test tolerance for test_field_slope --- twoaxistracking/plotting.py | 9 ++++++--- twoaxistracking/tests/test_layout.py | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/twoaxistracking/plotting.py b/twoaxistracking/plotting.py index 6d58832..2bff8f6 100644 --- a/twoaxistracking/plotting.py +++ b/twoaxistracking/plotting.py @@ -4,6 +4,7 @@ from shapely import geometry import matplotlib.colors as mcolors from matplotlib import cm +import numpy as np def _plot_field_layout(X, Y, Z, min_tracker_spacing): @@ -40,10 +41,12 @@ def _polygons_to_patch_collection(geometries, **kwargs): kwargs are passed to PatchCollection """ - # Convert geometries to a MultiPolygon if it is a Polygon + # Convert geometries to a list if isinstance(geometries, geometry.Polygon): - geometries = geometry.MultiPolygon([geometries]) - exteriors = [patches.Polygon(g.exterior) for g in geometries] + geometries = [geometries] + elif isinstance(geometries, geometry.MultiPolygon): + geometries = list(geometry.geoms) + exteriors = [patches.Polygon(np.array(g.exterior)) for g in geometries] path_collection = collections.PatchCollection(exteriors, **kwargs) return path_collection diff --git a/twoaxistracking/tests/test_layout.py b/twoaxistracking/tests/test_layout.py index ca18b47..69bd13d 100644 --- a/twoaxistracking/tests/test_layout.py +++ b/twoaxistracking/tests/test_layout.py @@ -87,7 +87,7 @@ def test_field_slope(rectangular_geometry, square_field_layout_sloped): slope_tilt=5) np.testing.assert_allclose(X, X_exp) np.testing.assert_allclose(Y, Y_exp) - np.testing.assert_allclose(Z, Z_exp) + np.testing.assert_allclose(Z, Z_exp, atol=10**-9) np.testing.assert_allclose(tracker_distance_exp, tracker_distance_exp) np.testing.assert_allclose(relative_azimuth, relative_azimuth_exp) np.testing.assert_allclose(relative_slope, relative_slope_exp, atol=10**-9) From 6d6a3917158e47ad3fdf29c8feed1529850e6b4f Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Tue, 1 Mar 2022 19:03:20 +0100 Subject: [PATCH 43/48] Add multi-polygon active area test --- twoaxistracking/plotting.py | 2 +- twoaxistracking/tests/conftest.py | 10 ++++++++++ twoaxistracking/tests/test_plotting.py | 9 ++++++--- twoaxistracking/tests/test_shading.py | 6 +++--- twoaxistracking/twoaxistrackerfield.py | 2 +- 5 files changed, 21 insertions(+), 8 deletions(-) diff --git a/twoaxistracking/plotting.py b/twoaxistracking/plotting.py index 2bff8f6..1d485d9 100644 --- a/twoaxistracking/plotting.py +++ b/twoaxistracking/plotting.py @@ -45,7 +45,7 @@ def _polygons_to_patch_collection(geometries, **kwargs): if isinstance(geometries, geometry.Polygon): geometries = [geometries] elif isinstance(geometries, geometry.MultiPolygon): - geometries = list(geometry.geoms) + geometries = list(geometries.geoms) exteriors = [patches.Polygon(np.array(g.exterior)) for g in geometries] path_collection = collections.PatchCollection(exteriors, **kwargs) return path_collection diff --git a/twoaxistracking/tests/conftest.py b/twoaxistracking/tests/conftest.py index e90a461..c8dd79f 100644 --- a/twoaxistracking/tests/conftest.py +++ b/twoaxistracking/tests/conftest.py @@ -12,6 +12,16 @@ def rectangular_geometry(): return collector_geometry, total_collector_area, min_tracker_spacing +@pytest.fixture +def active_geometry_split(): + active_collector_geometry = geometry.MultiPolygon([ + geometry.box(-1.9, -0.9, -0.1, -0.1), + geometry.box(0.1, -0.9, 1.9, -0.1), + geometry.box(-1.9, 0.1, -0.1, 0.9), + geometry.box(0.1, 0.1, 1.9, 0.9)]) + return active_collector_geometry + + @pytest.fixture def square_field_layout(): # Corresponds to GCR 0.125 with the rectangular_geometry diff --git a/twoaxistracking/tests/test_plotting.py b/twoaxistracking/tests/test_plotting.py index 6cd46a5..5429596 100644 --- a/twoaxistracking/tests/test_plotting.py +++ b/twoaxistracking/tests/test_plotting.py @@ -14,10 +14,13 @@ def test_field_layout_plot(): plt.close('all') -def test_shading_plot(rectangular_geometry): +def test_shading_plot(rectangular_geometry, active_geometry_split): collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry - result = plotting._plot_shading(collector_geometry, collector_geometry, - collector_geometry, min_tracker_spacing) + result = plotting._plot_shading( + active_geometry_split, + collector_geometry, + collector_geometry, + min_tracker_spacing) assert_isinstance(result, plt.Figure) plt.close('all') diff --git a/twoaxistracking/tests/test_shading.py b/twoaxistracking/tests/test_shading.py index 00c13a5..df47c87 100644 --- a/twoaxistracking/tests/test_shading.py +++ b/twoaxistracking/tests/test_shading.py @@ -2,7 +2,7 @@ import numpy as np -def test_shading(rectangular_geometry, square_field_layout): +def test_shading(rectangular_geometry, active_geometry_split, square_field_layout): # Test shading calculation # Also plots the geometry (ensures no errors are raised) collector_geometry, total_collector_area, min_tracker_spacing = rectangular_geometry @@ -12,7 +12,7 @@ def test_shading(rectangular_geometry, square_field_layout): solar_elevation=3, solar_azimuth=120, total_collector_geometry=collector_geometry, - active_collector_geometry=collector_geometry, + active_collector_geometry=active_geometry_split, min_tracker_spacing=min_tracker_spacing, tracker_distance=tracker_distance, relative_azimuth=relative_azimuth, @@ -20,7 +20,7 @@ def test_shading(rectangular_geometry, square_field_layout): slope_azimuth=0, slope_tilt=0, plot=True) - np.testing.assert_allclose(shaded_fraction, 0.191324034) + np.testing.assert_allclose(shaded_fraction, 0.190320666774) def test_shading_zero_solar_elevation(rectangular_geometry, square_field_layout): diff --git a/twoaxistracking/twoaxistrackerfield.py b/twoaxistracking/twoaxistrackerfield.py index 4ab2fb8..976f3bd 100644 --- a/twoaxistracking/twoaxistrackerfield.py +++ b/twoaxistracking/twoaxistrackerfield.py @@ -167,7 +167,7 @@ def get_shaded_fraction(self, solar_elevation, solar_azimuth, relative_slope=self.relative_slope, slope_azimuth=self.slope_azimuth, slope_tilt=self.slope_tilt, - plot=False) + plot=plot) shaded_fractions.append(shaded_fraction) # Return the shaded_fractions as the same type as the input From e4ea335df4a96edd7813806bb756bf80c43a7e78 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Tue, 1 Mar 2022 19:09:13 +0100 Subject: [PATCH 44/48] Add empty __init__.py --- twoaxistracking/tests/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 twoaxistracking/tests/__init__.py diff --git a/twoaxistracking/tests/__init__.py b/twoaxistracking/tests/__init__.py new file mode 100644 index 0000000..e69de29 From 4c84e5d4bd0faf36ac3d7c51f4123046794bbff3 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Tue, 1 Mar 2022 19:12:10 +0100 Subject: [PATCH 45/48] Use "from .conftest" as Kevin said.. --- twoaxistracking/tests/test_plotting.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/twoaxistracking/tests/test_plotting.py b/twoaxistracking/tests/test_plotting.py index 5429596..0168e03 100644 --- a/twoaxistracking/tests/test_plotting.py +++ b/twoaxistracking/tests/test_plotting.py @@ -1,6 +1,6 @@ import matplotlib.pyplot as plt from twoaxistracking import plotting, twoaxistrackerfield -from conftest import assert_isinstance +from .conftest import assert_isinstance import numpy as np From b3d24963b7a220719e538c871316fa962d50e1c5 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Wed, 2 Mar 2022 14:51:27 +0100 Subject: [PATCH 46/48] Base square_field_layout_slope fixture off square_field_layout --- twoaxistracking/tests/conftest.py | 13 +++++++++++++ twoaxistracking/tests/test_layout.py | 13 ------------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/twoaxistracking/tests/conftest.py b/twoaxistracking/tests/conftest.py index c8dd79f..e340844 100644 --- a/twoaxistracking/tests/conftest.py +++ b/twoaxistracking/tests/conftest.py @@ -34,5 +34,18 @@ def square_field_layout(): return X, Y, Z, tracker_distance, relative_azimuth, relative_slope +@pytest.fixture +def square_field_layout_sloped(square_field_layout): + # Corresponds to GCR 0.125 with the rectangular_geometry and tilted slope + # Based on the square_field_layout + X, Y, _, tracker_distance, relative_azimuth, _ = \ + square_field_layout + Z = np.array([0.12372765, 0.06186383, 0, 0.06186383, + -0.06186383, 0, -0.06186383, -0.12372765]) + relative_slope = np.array([5, 3.53553391, 0, 3.53553391, + -3.53553391, 0, -3.53553391, -5]) + return X, Y, Z, tracker_distance, relative_azimuth, relative_slope + + def assert_isinstance(obj, klass): assert isinstance(obj, klass), f'got {type(obj)}, expected {klass}' diff --git a/twoaxistracking/tests/test_layout.py b/twoaxistracking/tests/test_layout.py index 69bd13d..b89a7d8 100644 --- a/twoaxistracking/tests/test_layout.py +++ b/twoaxistracking/tests/test_layout.py @@ -4,19 +4,6 @@ import pytest -@pytest.fixture -def square_field_layout_sloped(): - # Corresponds to GCR 0.125 with the rectangular_geometry - X = np.array([-8, 0, 8, -8, 8, -8, 0, 8]) - Y = np.array([-8, -8, -8, 0, 0, 8, 8, 8]) - tracker_distance = (X**2 + Y**2)**0.5 - relative_azimuth = np.array([225, 180, 135, 270, 90, 315, 0, 45]) - Z = np.array([0.12372765, 0.06186383, 0, 0.06186383, - -0.06186383, 0, -0.06186383, -0.12372765]) - relative_slope = np.array([5, 3.53553391, 0, 3.53553391, - -3.53553391, 0, -3.53553391, -5]) - return X, Y, Z, tracker_distance, relative_azimuth, relative_slope - def test_min_tracker_spacing_rectangle(rectangular_geometry): # Test calculation of min_tracker_spacing for a rectangular collector From 735208586a50ce9021b858a58aaf913a6e4d016d Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Wed, 2 Mar 2022 14:53:14 +0100 Subject: [PATCH 47/48] Fix linter error --- twoaxistracking/tests/test_layout.py | 1 - 1 file changed, 1 deletion(-) diff --git a/twoaxistracking/tests/test_layout.py b/twoaxistracking/tests/test_layout.py index b89a7d8..786ff17 100644 --- a/twoaxistracking/tests/test_layout.py +++ b/twoaxistracking/tests/test_layout.py @@ -4,7 +4,6 @@ import pytest - def test_min_tracker_spacing_rectangle(rectangular_geometry): # Test calculation of min_tracker_spacing for a rectangular collector min_tracker_spacing = layout._calculate_min_tracker_spacing(rectangular_geometry[0]) From 39c94e6314601b4493c3a28ed91244ce15d3b374 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Wed, 2 Mar 2022 15:02:03 +0100 Subject: [PATCH 48/48] Remove backslash in conftest.py --- twoaxistracking/tests/conftest.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/twoaxistracking/tests/conftest.py b/twoaxistracking/tests/conftest.py index e340844..3432638 100644 --- a/twoaxistracking/tests/conftest.py +++ b/twoaxistracking/tests/conftest.py @@ -38,8 +38,7 @@ def square_field_layout(): def square_field_layout_sloped(square_field_layout): # Corresponds to GCR 0.125 with the rectangular_geometry and tilted slope # Based on the square_field_layout - X, Y, _, tracker_distance, relative_azimuth, _ = \ - square_field_layout + X, Y, _, tracker_distance, relative_azimuth, _ = square_field_layout Z = np.array([0.12372765, 0.06186383, 0, 0.06186383, -0.06186383, 0, -0.06186383, -0.12372765]) relative_slope = np.array([5, 3.53553391, 0, 3.53553391,