From a05f812a5c9f3bcd46bd7e14eefb94ae26f7f498 Mon Sep 17 00:00:00 2001 From: Craig Arthur Date: Mon, 6 Mar 2023 10:12:09 +1100 Subject: [PATCH] BUGFIX for autocorrelation function (#140) * track.ncReadTrackData returns true datetime objects - track.ncReadTrackData previously returned cftime.DatetimeGregorian objects, which caused newer versions of matplotlib.dates.num2date to fail. This is because we write the tracks with units of 'hours since 1900-01-01 00:00', but matplotlib.dates uses 1970-01-01 as the epoch, and works in units of days (with no way to specify units in the num2date function). * Read netcdf-format track file from GA SST - GA's Scenario selection tool allows users to download a selected track file, but due to technical constraints this is in a different format. This change allows TCRM to read the modified format. * Move definition statements to separate file * Move queries to separate file * Add script to run through all permutations of wind parameters * NHIRS 148 fix thread (#119) * assertDictEqual doesn't like complex values (like arrays) * NHIRS-148: Fixed issue with FlushCache failing. (#121) * update wind field model to get direction correct, and update documentation * Enhancement/linear rmax (#125) * fix double calculation of t3 - it was previously L3 / (L2 * L2) instead of L3 / L2 * only call Kepert wind field fortran code when a Holland pressure profile is used * Working version of cartopy-based scalebar * Pycxml compatability (#133) * gdal multi-threading for reprojection * Use expected DataProcess-InputFile * Create daily LTM MSLP file from ERA5 * Low resolution wind multipliers (#136) - Adds in a script to quickly downscale the wind multipliers and apply them to many wind fields quickly. If the wind multipliers have already been extracted this process takes minutes instead of weeks. * Bugfix for ACF function (#139) --------- Co-authored-by: mahmudulhasanGA <66761046+mahmudulhasanGA@users.noreply.github.com> Co-authored-by: Kieran Ricardo --- .github/workflows/tcrm-pylint.yml | 8 +- .github/workflows/tcrm-tests.yml | 14 +- DataProcess/DataProcess.py | 10 +- Evaluate/interpolateTracks.py | 56 +++-- PlotInterface/AutoPlotHazard.py | 2 + PlotInterface/curves.py | 10 +- PlotInterface/maps.py | 35 +-- PlotInterface/plotTimeseries.py | 2 +- PlotInterface/scalebar.py | 208 +++++++++++++++++ PressureInterface/pressureProfile.f90 | 25 +++ PressureInterface/pressureProfile.py | 11 +- .../lowResProcessMultipliers.ini | 14 ++ .../lowResProcessMultipliers.py | 182 +++++++++++++++ ProcessMultipliers/processMultipliers.py | 11 +- README.rst | 1 + StatInterface/SamplingOrigin.py | 9 +- StatInterface/SamplingParameters.py | 5 +- StatInterface/StatInterface.py | 2 +- StatInterface/generateStats.py | 15 +- TrackGenerator/TrackGenerator.py | 8 +- TrackGenerator/trackSize.py | 25 +-- Utilities/config.py | 2 +- Utilities/files.py | 2 + Utilities/loadData.py | 4 +- Utilities/maputils.f90 | 65 ++++++ Utilities/maputils.py | 22 +- Utilities/process.py | 10 +- Utilities/shptools.py | 4 +- Utilities/track.py | 13 +- create_era5_mslp.sh | 73 ++++++ hazard/GPD.py | 22 ++ hazard/evd.py | 5 +- installer/setup.py | 17 +- setup.py | 8 +- tcrmenv.yml | 8 +- tests/NumpyTestCase.py | 3 +- tests/__init__.py | 0 tests/test_GPD.py | 2 +- tests/test_Intersections.py | 2 +- tests/test_KDEOrigin.py | 4 +- tests/test_KDEParameters.py | 4 +- tests/test_SamplingOrigin.py | 6 +- tests/test_SamplingParameters.py | 6 +- tests/test_columns.py | 2 +- tests/test_config.py | 2 +- tests/test_data/vorticityTestData.pkl | Bin 467203 -> 467187 bytes tests/test_data/windFieldTestData.pkl | Bin 467203 -> 467732 bytes tests/test_data/windProfileTestData.pkl | Bin 467203 -> 467187 bytes tests/test_evd.py | 46 ++-- tests/test_files.py | 2 + tests/test_generateStats.py | 12 +- tests/test_grid.py | 4 +- tests/test_hazard__init__.py | 2 +- tests/test_interp3d.py | 2 +- tests/test_interpolate.py | 31 +++ tests/test_lmomentFit.py | 2 +- tests/test_loadData.py | 4 +- tests/test_maps.py | 6 +- tests/test_maputils.py | 74 +++---- tests/test_metutils.py | 4 +- tests/test_nctools.py | 6 +- tests/test_pressureProfile.py | 4 +- tests/test_stats.py | 6 +- tests/test_system.py | 2 + tests/test_track.py | 4 +- tests/test_trackSize.py | 35 ++- tests/test_vmax.py | 4 +- tests/test_windmodels.py | 7 +- tests/test_windprofile.py | 2 +- wind/__init__.py | 22 +- wind/vmax.py | 9 +- wind/windmodels.f90 | 209 ++++++++++++++++++ wind/windmodels.py | 141 ++++++++---- 73 files changed, 1272 insertions(+), 307 deletions(-) create mode 100644 PlotInterface/scalebar.py create mode 100644 PressureInterface/pressureProfile.f90 create mode 100644 ProcessMultipliers/lowResProcessMultipliers.ini create mode 100644 ProcessMultipliers/lowResProcessMultipliers.py create mode 100644 Utilities/maputils.f90 create mode 100755 create_era5_mslp.sh delete mode 100644 tests/__init__.py create mode 100644 tests/test_interpolate.py create mode 100644 wind/windmodels.f90 diff --git a/.github/workflows/tcrm-pylint.yml b/.github/workflows/tcrm-pylint.yml index d4f1bb93..d6e3c8aa 100644 --- a/.github/workflows/tcrm-pylint.yml +++ b/.github/workflows/tcrm-pylint.yml @@ -11,13 +11,17 @@ jobs: steps: - uses: actions/checkout@v2 - - name: Set up Python env + - name: Set up environment uses: conda-incubator/setup-miniconda@v2.0.0 with: + python-version: 3.7 + mamba-version: "*" + channels: conda-forge,defaults + channel-priority: true activate-environment: tcrm environment-file: tcrmenv.yml - python-version: 3.7 auto-activate-base: false + use-only-tar-bz2: true - name: Install dependencies run: | diff --git a/.github/workflows/tcrm-tests.yml b/.github/workflows/tcrm-tests.yml index 3e68e830..59f5b5d6 100644 --- a/.github/workflows/tcrm-tests.yml +++ b/.github/workflows/tcrm-tests.yml @@ -13,7 +13,7 @@ jobs: TCRM: name: Test TCRM runs-on: ubuntu-latest - strategy: + strategy: matrix: python-version: [3.7, 3.8, 3.9] steps: @@ -21,12 +21,18 @@ jobs: - name: Set up environment uses: conda-incubator/setup-miniconda@v2.0.0 with: + python-version: ${{ matrix.python-version }} + mamba-version: "*" + channels: conda-forge,defaults + channel-priority: true activate-environment: tcrm environment-file: tcrmenv.yml - python-version: ${{ matrix.python-version }} auto-activate-base: false + use-only-tar-bz2: true - - name: Test with nose + - name: Test with pytest + env: + PYTHONPATH: ~/tcrm;~/tcrm/Utilities shell: bash -l {0} run: | - python tests/run.py + pytest -x --cov=. --cov-report xml diff --git a/DataProcess/DataProcess.py b/DataProcess/DataProcess.py index 91ea5ec4..9693a98c 100644 --- a/DataProcess/DataProcess.py +++ b/DataProcess/DataProcess.py @@ -171,13 +171,17 @@ def processData(self, restrictToWindfieldDomain=False): if config.has_option('DataProcess', 'InputFile'): inputFile = config.get('DataProcess', 'InputFile') self.logger.info(f"Input file from DataProcess: {inputFile}") + else: + inputFile = None if config.has_option('DataProcess', 'Source'): source = config.get('DataProcess', 'Source') self.logger.info(f"Loading {source} dataset") - fn = config.get(source, 'Filename') - path = config.get(source, 'Path') - inputFile = pjoin(path, fn) + if inputFile is None: + # Use this as alternate source of input file (downloaded?) + fn = config.get(source, 'Filename') + path = config.get(source, 'Path') + inputFile = pjoin(path, fn) self.logger.info(f"Input file set to {inputFile}") # If input file has no path information, default to tcrm input folder diff --git a/Evaluate/interpolateTracks.py b/Evaluate/interpolateTracks.py index 924fd2b1..2eed8f8e 100644 --- a/Evaluate/interpolateTracks.py +++ b/Evaluate/interpolateTracks.py @@ -9,6 +9,9 @@ from Utilities.maputils import latLon2Azi from Utilities.loadData import loadTrackFile, maxWindSpeed from Utilities.track import Track, ncSaveTracks +from Utilities.parallel import attemptParallel +import pandas as pd + LOG = logging.getLogger(__name__) LOG.addHandler(logging.NullHandler()) @@ -139,7 +142,9 @@ def interpolate(track, delta, interpolation_type=None): if interpolation_type == 'akima': # Use the Akima interpolation method: try: - import akima + from Utilities import akima + nLon = akima.interpolate(timestep, track.Longitude, newtime) + nLat = akima.interpolate(timestep, track.Latitude, newtime) except ImportError: LOG.exception(("Akima interpolation module unavailable " " - default to scipy.interpolate")) @@ -148,10 +153,6 @@ def interpolate(track, delta, interpolation_type=None): nLat = splev(newtime, splrep(timestep, track.Latitude, s=0), der=0) - else: - nLon = akima.interpolate(timestep, track.Longitude, newtime) - nLat = akima.interpolate(timestep, track.Latitude, newtime) - elif interpolation_type == 'linear': nLon = interp1d(timestep, track.Longitude, kind='linear')(newtime) nLat = interp1d(timestep, track.Latitude, kind='linear')(newtime) @@ -299,21 +300,48 @@ def parseTracks(configFile, trackFile, source, delta, outputFile=None, if trackFile.endswith("nc"): from Utilities.track import ncReadTrackData tracks = ncReadTrackData(trackFile) + elif trackFile.endswith("xml"): + from pycxml.pycxml import loadfile + dfs = loadfile(trackFile) + tracks = [bom2tcrm(df, i) for i, df in enumerate(dfs)] else: tracks = loadTrackFile(configFile, trackFile, source) results = [] - for track in tracks: - if len(track.data) == 1: - results.append(track) - else: - newtrack = interpolate(track, delta, interpolation_type) - results.append(newtrack) + # interpolating is memory intensive - only use a single process + MPI = attemptParallel() + if MPI.COMM_WORLD.rank == 0: - if outputFile: - # Save data to file: - ncSaveTracks(outputFile, results) + for track in tracks: + if len(track.data) == 1: + results.append(track) + else: + newtrack = interpolate(track, delta, interpolation_type) + results.append(newtrack) + if outputFile: + # Save data to file: + ncSaveTracks(outputFile, results) + MPI.COMM_WORLD.barrier() return results + + +def bom2tcrm(df, trackId): + """ + Transforms a dataframe in BoM format into a tcrm track. + + """ + df['Datetime'] = pd.to_datetime(df.validtime) + df['Speed'] = df.translation_speed + df['CentralPressure'] = df.pcentre + df['Longitude'] = df.longitude + df['Latitude'] = df.latitude + df['EnvPressure'] = df.poci + df['rMax'] = df.rmax + df['trackId'] = df.disturbance.values + + track = Track(df) + track.trackId = [trackId, trackId] + return track diff --git a/PlotInterface/AutoPlotHazard.py b/PlotInterface/AutoPlotHazard.py index e16bb170..a4225f8e 100644 --- a/PlotInterface/AutoPlotHazard.py +++ b/PlotInterface/AutoPlotHazard.py @@ -36,6 +36,8 @@ from Utilities import pathLocator from Utilities import metutils +from database.queries import locationRecords + from PlotInterface.maps import saveHazardMap from PlotInterface.curves import saveHazardCurve diff --git a/PlotInterface/curves.py b/PlotInterface/curves.py index b2edc6da..a00fe83a 100755 --- a/PlotInterface/curves.py +++ b/PlotInterface/curves.py @@ -149,7 +149,7 @@ def subplot(self, axes, subfigure): xdata, ydata, xlabel, ylabel, title = subfigure - axes.semilogx(xdata, ydata, '-', subsx=xdata) + axes.semilogx(xdata, ydata, '-', subs=xdata) axes.set_xlabel(xlabel) axes.set_ylabel(ylabel) axes.set_title(title) @@ -328,7 +328,7 @@ def subplot(self, axes, subfigure): """ xdata, ymean, ymax, ymin, xlabel, ylabel, title = subfigure - axes.semilogx(xdata, ymean, lw=2, subsx=xdata) + axes.semilogx(xdata, ymean, lw=2, subs=xdata) if (ymin[0] > 0) and (ymax[0] > 0): self.addRange(axes, xdata, ymin, ymax) @@ -390,7 +390,7 @@ def subplot(self, axes, subfigure): log.debug("xvalues = {0} length".format(len(emprp))) log.debug("xvalues = {0}".format(emprp)) - axes.semilogx(xdata, ymean, lw=2, subsx=xdata, + axes.semilogx(xdata, ymean, lw=2, subs=xdata, label = 'Fitted hazard curve ({0})'.format(fit)) axes.scatter(emprp[emprp > 1], events[emprp > 1], s=100, color='r', label = 'Empirical ARI') @@ -478,8 +478,8 @@ def subplot(self, axes, subfigure): """ xdata, y1, y2, y2max, y2min, xlabel, ylabel, title = subfigure - axes.semilogx(xdata, y1, color='r', lw=2, label="", subsx=xdata) - axes.semilogx(xdata, y2, color='k', lw=2, label="", subsx=xdata) + axes.semilogx(xdata, y1, color='r', lw=2, label="", subs=xdata) + axes.semilogx(xdata, y2, color='k', lw=2, label="", subs=xdata) self.addRange(axes, xdata, y2min, y2max) ylim = (0., np.max([100, np.ceil(y2.max()/10.)*10.])) axes.set_ylim(ylim) diff --git a/PlotInterface/maps.py b/PlotInterface/maps.py index 53d4b3e1..ba2e9244 100644 --- a/PlotInterface/maps.py +++ b/PlotInterface/maps.py @@ -24,6 +24,8 @@ from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas import seaborn as sns +from .scalebar import scale_bar + def levels(maxval, minval=0): """ Calculate a nice number of levels between `minval` and `maxval` @@ -230,35 +232,20 @@ def maskOceans(self, mapobj, fillcolor="#66ccff"): mapobj.add_feature(cartopy.feature.OCEAN, color=fillcolor) - def addMapScale(self, mapobj): + def addMapScale(self, axes): """ - Add a map scale to the curent `Basemap` instance. This - automatically determines a 'nice' length forthe scale bar - + Add a map scale to the curent `cartopy.mpl.geoaxes.GeoAxes` instance. + This automatically determines a 'nice' length forthe scale bar - chosen to be approximately 20% of the map width at the centre of the map. - :param mapobj: Current `Basemap` instance to add the scale bar to. + :param ax: Current `cartopy.mpl.geoaxes.GeoAxes` instance to add the + scale bar to. + see https://stackoverflow.com/questions/32333870/ """ - return # TODO: migrate to cartopy - see https://stackoverflow.com/questions/32333870/ - - midlon = (mapobj.lonmax - mapobj.lonmin) / 2. - midlat = (mapobj.latmax - mapobj.latmin) / 2. - - xmin = mapobj.llcrnrx - xmax = mapobj.urcrnrx - ymin = mapobj.llcrnry - ymax = mapobj.urcrnry - - xloc = xmin + 0.15 * abs(xmax - xmin) - yloc = ymin + 0.1 * abs(ymax - ymin) + axes = scale_bar(axes, (0.05, 0.1)) - lonloc, latloc = mapobj(xloc, yloc, inverse=True) - - # Set scale length to nearest 100-km for 20% of map width - scale_length = 100*int((0.2 * (xmax - xmin) / 1000.)/100) - mapobj.drawmapscale(lonloc, latloc, midlon, midlat, scale_length, - barstyle='fancy', zorder=10) def createMap(self, axes, xgrid, ygrid, map_kwargs): """ @@ -296,7 +283,7 @@ def subplot(self, axes, subfigure): self.addGraticule(axes, mapobj) self.addCoastline(mapobj) self.fillContinents(mapobj) - self.addMapScale(mapobj) + self.addMapScale(axes) def plot(self): """ @@ -380,7 +367,7 @@ def subplot(self, axes, subfigure): cmap = selectColormap(lvls) CS = mapobj.contourf(mx, my, data, levels=lvls, extend='both', cmap=cmap) - CB = self.colorbar(CS, ticks=lvls[::2], ax=axes, extend='both') + CB = self.colorbar(CS, ticks=lvls[::2], ax=axes) CB.set_label(cbarlab) axes.set_title(title) self.addGraticule(axes, mapobj) diff --git a/PlotInterface/plotTimeseries.py b/PlotInterface/plotTimeseries.py index dbcf0f1c..49afc71b 100644 --- a/PlotInterface/plotTimeseries.py +++ b/PlotInterface/plotTimeseries.py @@ -49,7 +49,7 @@ def loadTimeseriesData(datafile): comments='#', delimiter=',', skip_header=1, converters=INPUT_CNVT) except ValueError: - logging.warn("Timeseries data file is empty - returning empty array") + logging.warning("Timeseries data file is empty - returning empty array") return np.empty(0, dtype={ 'names': INPUT_COLS, 'formats': INPUT_FMTS}) diff --git a/PlotInterface/scalebar.py b/PlotInterface/scalebar.py new file mode 100644 index 00000000..f5f4684d --- /dev/null +++ b/PlotInterface/scalebar.py @@ -0,0 +1,208 @@ +import numpy as np +import cartopy.crs as ccrs +import cartopy.geodesic as cgeo + + +def _axes_to_lonlat(ax, coords): + """(lon, lat) from axes coordinates.""" + display = ax.transAxes.transform(coords) + data = ax.transData.inverted().transform(display) + lonlat = ccrs.PlateCarree().transform_point(*data, ax.projection) + + return lonlat + + +def _upper_bound(start, direction, distance, dist_func): + """A point farther than distance from start, in the given direction. + + It doesn't matter which coordinate system start is given in, as long + as dist_func takes points in that coordinate system. + + Args: + start: Starting point for the line. + direction Nonzero (2, 1)-shaped array, a direction vector. + distance: Positive distance to go past. + dist_func: A two-argument function which returns distance. + + Returns: + Coordinates of a point (a (2, 1)-shaped NumPy array). + """ + if distance <= 0: + raise ValueError(f"Minimum distance is not positive: {distance}") + + if np.linalg.norm(direction) == 0: + raise ValueError("Direction vector must not be zero.") + + # Exponential search until the distance between start and end is + # greater than the given limit. + length = 0.1 + end = start + length * direction + + while dist_func(start, end) < distance: + length *= 2 + end = start + length * direction + + return end + + +def _distance_along_line(start, end, distance, dist_func, tol): + """Point at a distance from start on the segment from start to end. + + It doesn't matter which coordinate system start is given in, as long + as dist_func takes points in that coordinate system. + + Args: + start: Starting point for the line. + end: Outer bound on point's location. + distance: Positive distance to travel. + dist_func: Two-argument function which returns distance. + tol: Relative error in distance to allow. + + Returns: + Coordinates of a point (a (2, 1)-shaped NumPy array). + """ + initial_distance = dist_func(start, end) + if initial_distance < distance: + raise ValueError(f"End is closer to start ({initial_distance}) than " + f"given distance ({distance}).") + + if tol <= 0: + raise ValueError(f"Tolerance is not positive: {tol}") + + # Binary search for a point at the given distance. + left = start + right = end + + while not np.isclose(dist_func(start, right), distance, rtol=tol): + midpoint = (left + right) / 2 + + # If midpoint is too close, search in second half. + if dist_func(start, midpoint) < distance: + left = midpoint + # Otherwise the midpoint is too far, so search in first half. + else: + right = midpoint + + return right + + +def _point_along_line(ax, start, distance, angle=0, tol=0.01): + """Point at a given distance from start at a given angle. + + Args: + ax: CartoPy axes. + start: Starting point for the line in axes coordinates. + distance: Positive physical distance to travel. + angle: Anti-clockwise angle for the bar, in radians. Default: 0 + tol: Relative error in distance to allow. Default: 0.01 + + Returns: + Coordinates of a point (a (2, 1)-shaped NumPy array). + """ + # Direction vector of the line in axes coordinates. + direction = np.array([np.cos(angle), np.sin(angle)]) + geodesic = cgeo.Geodesic() + + # Physical distance between points. + def dist_func(a_axes, b_axes): + a_phys = _axes_to_lonlat(ax, a_axes) + b_phys = _axes_to_lonlat(ax, b_axes) + + # Geodesic().inverse returns a NumPy MemoryView like [[distance, + # start azimuth, end azimuth]]. + return geodesic.inverse(a_phys, b_phys)[0, 0] + + end = _upper_bound(start, direction, distance, dist_func) + + return _distance_along_line(start, end, distance, dist_func, tol) + + +def _setlength(ax, location): + """ + If no length is given, then set an arbitrary length of the scale bar + + :param ax: `cartopy.mpl.geoaxes.GeoAxes` instance + :param location: Position of left-side of bar in axes coordinates + + """ + llx0, llx1, lly0, lly1 = ax.get_extent(ax.projection) + sbllx = (llx1 + llx0) / 2 + sblly = lly0 + (lly1 - lly0) * location[1] + tmc = ccrs.TransverseMercator(sbllx, sblly) + #Get the extent of the plotted area in coordinates in metres + x0, x1, y0, y1 = ax.get_extent(tmc) + length = (x1 - x0) / 5000 + ndim = int(np.floor(np.log10(length))) #number of digits in number + length = round(length, -ndim) #round to 1sf + #Returns numbers starting with the list + def scale_number(x): + if str(x)[0] in ['1', '2', '5']: return int(x) + else: return scale_number(x - 10 ** ndim) + length = scale_number(length) + return length + + +def scale_bar(ax, location, length=None, metres_per_unit=1000, unit_name='km', + tol=0.01, angle=0, color='black', linewidth=3, text_offset=0.005, + ha='center', va='bottom', plot_kwargs=None, text_kwargs=None, + **kwargs): + """Add a scale bar to CartoPy axes. + + For angles between 0 and 90 the text and line may be plotted at + slightly different angles for unknown reasons. To work around this, + override the 'rotation' keyword argument with text_kwargs. + + Args: + ax: CartoPy axes. + location: Position of left-side of bar in axes coordinates. + length: Geodesic length of the scale bar. + metres_per_unit: Number of metres in the given unit. Default: 1000 + unit_name: Name of the given unit. Default: 'km' + tol: Allowed relative error in length of bar. Default: 0.01 + angle: Anti-clockwise rotation of the bar. + color: Color of the bar and text. Default: 'black' + linewidth: Same argument as for plot. + text_offset: Perpendicular offset for text in axes coordinates. + Default: 0.005 + ha: Horizontal alignment. Default: 'center' + va: Vertical alignment. Default: 'bottom' + **plot_kwargs: Keyword arguments for plot, overridden by **kwargs. + **text_kwargs: Keyword arguments for text, overridden by **kwargs. + **kwargs: Keyword arguments for both plot and text. + """ + # Setup kwargs, update plot_kwargs and text_kwargs. + if plot_kwargs is None: + plot_kwargs = {} + if text_kwargs is None: + text_kwargs = {} + + plot_kwargs = {'linewidth': linewidth, 'color': color, **plot_kwargs, + **kwargs} + text_kwargs = {'ha': ha, 'va': va, 'rotation': angle, 'color': color, + **text_kwargs, **kwargs} + + if not length: + length = _setlength(ax, location) + # Convert all units and types. + location = np.asarray(location) # For vector addition. + length_metres = length * metres_per_unit + angle_rad = angle * np.pi / 180 + + # End-point of bar. + end = _point_along_line(ax, location, length_metres, angle=angle_rad, + tol=tol) + + # Coordinates are currently in axes coordinates, so use transAxes to + # put into data coordinates. *zip(a, b) produces a list of x-coords, + # then a list of y-coords. + ax.plot(*zip(location, end), transform=ax.transAxes, **plot_kwargs) + + # Push text away from bar in the perpendicular direction. + midpoint = (location + end) / 2 + offset = text_offset * np.array([-np.sin(angle_rad), np.cos(angle_rad)]) + text_location = midpoint + offset + + # 'rotation' keyword argument is in text_kwargs. + ax.text(*text_location, f"{length} {unit_name}", rotation_mode='anchor', + transform=ax.transAxes, **text_kwargs) + return ax \ No newline at end of file diff --git a/PressureInterface/pressureProfile.f90 b/PressureInterface/pressureProfile.f90 new file mode 100644 index 00000000..c3afd996 --- /dev/null +++ b/PressureInterface/pressureProfile.f90 @@ -0,0 +1,25 @@ +subroutine fhollandpressure(P, R, rMax, pc, dP, beta, n) + !$ use omp_lib + +! Calculates the pressure of the Holland profile +! +! :param P: 1D double precision output pressure array +! :param R: 1D double precision pressure array of distance from storm centre +! :param double rMax: radius to maximum winds (m) +! :param double pc: central pressure (Pa) +! :param double dP: central pressure deficit (Pa) +! :param double beta: shape parameter +! :param int n: length of arrays + + integer, intent(in) :: n + doubleprecision, intent(in), dimension(n) :: R + doubleprecision, intent(inout), dimension(n) :: P + doubleprecision, intent(in) :: rMax, beta, pc, dP + + !$OMP PARALLEL DO shared(P) + do i = 1, n + P(i) = pc + dP * exp(-(rMax / R(i)) ** beta) + end do + !$OMP END PARALLEL DO + +end subroutine fhollandpressure \ No newline at end of file diff --git a/PressureInterface/pressureProfile.py b/PressureInterface/pressureProfile.py index 2e7426b5..96dc00b4 100644 --- a/PressureInterface/pressureProfile.py +++ b/PressureInterface/pressureProfile.py @@ -150,8 +150,15 @@ def holland(self, beta=None): if beta == None: beta = self.beta t0 = time.time() - P = numpy.zeros(self.R.shape) - P = self.pCentre + self.dP*numpy.exp(-(self.rMax/self.R)**beta) + + try: + from ._pressureProfile import fhollandpressure + P = numpy.empty(self.R.shape) + fhollandpressure( + P.ravel(), self.R.ravel(), self.rMax, self.pCentre, self.dP, beta + ) + except ImportError: + P = self.pCentre + self.dP*numpy.exp(-(self.rMax/self.R)**beta) self.logger.debug("Timing for holland wind profile calculation: %.3f" % (time.time()-t0)) return P diff --git a/ProcessMultipliers/lowResProcessMultipliers.ini b/ProcessMultipliers/lowResProcessMultipliers.ini new file mode 100644 index 00000000..8dfa78d6 --- /dev/null +++ b/ProcessMultipliers/lowResProcessMultipliers.ini @@ -0,0 +1,14 @@ +[Input] +# Multipliers can be any file type that gdal accepts but its faster to extract the multipliers from the VRT and only apply the extent once +# Multipliers=/g/data/w85/National_multipliers2021/WM_National/M3/wind-multipliers.vrt +Multipliers=/g/data/w85/kr4383/yasi/multipliers/000-00000/m4_source.tif +Gust_dir=/g/data/w85/kr4383/yasi/windfield + +[Output] +Working_dir = /g/data/w85/kr4383/yasi + +[Logging] +LogFile=processMultipliers.log +LogLevel=DEBUG +Verbose=True +Datestamp=True diff --git a/ProcessMultipliers/lowResProcessMultipliers.py b/ProcessMultipliers/lowResProcessMultipliers.py new file mode 100644 index 00000000..de253b9d --- /dev/null +++ b/ProcessMultipliers/lowResProcessMultipliers.py @@ -0,0 +1,182 @@ +from osgeo import osr, gdal, gdalconst +from osgeo.gdal_array import BandReadAsArray, CopyDatasetInfo, BandWriteArray +from netCDF4 import Dataset +import os +import xarray as xr +import numpy as np +from tqdm import tqdm +from Utilities.config import ConfigParser +from Utilities.files import flStartLog +import argparse +from os.path import join as pjoin, dirname, realpath, isdir, splitext +import traceback +import logging as log + + +def downscale_multipliers(src_file, match_file, dst_file, epsg=4326): + """ + Downscales and clips GDAL compatable file and saves it as a GEOTIFF. + + Params: + - src_file: filepath of the input file to be downscaled + - match_file: filepath of the file that the input is transformed to match + - dst_file: output filepath + """ + # load src + if not os.path.isfile(src_file): + raise FileNotFoundError(f"src_file: file {src_file} not found.") + + if not os.path.isfile(match_file): + raise FileNotFoundError(f"match_file: file {match_file} not found.") + + if not os.path.path.isdir(os.path.split(dst_file)[0]): + raise FileNotFoundError(f"dst_file: directory {os.path.split(dst_file)[0]} not found.") + + src = gdal.Open(src_file, gdal.GA_ReadOnly) + + # load match info + ncobj = Dataset(match_file, 'r') + lat = ncobj.variables['lat'][:] + lon = ncobj.variables['lon'][:] + delta = lon[1] - lon[0] + lon = lon - delta / 2. + lat = lat - delta / 2. + + dx = lon[1] - lon[0] + dy = lat[1] - lat[0] + originX, originY = lon[0], lat[0] + + wide = len(lon) + high = len(lat) + + # Output / destination + srs = osr.SpatialReference() + srs.ImportFromEPSG(epsg) + + # warp + drv = gdal.GetDriverByName('GTiff') + dst = drv.Create(dst_file, wide, high, 8, gdal.GDT_Float32) + dst.SetGeoTransform((originX, dx, 0, originY, 0, dy)) + dst.SetProjection(srs.ExportToWkt()) + dstBand = dst.GetRasterBand(1) + dstBand.SetNoDataValue(-9999) + + gdal.ReprojectImage(src, dst, src.GetProjection(), dst.GetProjection(), gdalconst.GRA_Bilinear) + + +class run(): + + def __init__(self): + """ + Parse command line arguments and call the :func:`main` function. + + """ + parser = argparse.ArgumentParser() + parser.add_argument('-c', '--config_file', + help='Path to configuration file') + parser.add_argument('-v', '--verbose', help='Verbose output', + action='store_true') + parser.add_argument('-d', '--debug', help='Allow pdb traces', + action='store_true') + args = parser.parse_args() + + self.configFile = args.config_file + config = ConfigParser() + config.read(self.configFile) + + logfile = config.get('Logging', 'LogFile') + logdir = dirname(realpath(logfile)) + + # If log file directory does not exist, create it + if not isdir(logdir): + try: + os.makedirs(logdir) + except OSError: + logfile = pjoin(os.getcwd(), 'processMultipliers.log') + + logLevel = config.get('Logging', 'LogLevel') + verbose = config.getboolean('Logging', 'Verbose') + datestamp = config.getboolean('Logging', 'Datestamp') + + if args.verbose: + verbose = True + + flStartLog(logfile, logLevel, verbose, datestamp) + # Switch off minor warning messages + import warnings + warnings.filterwarnings("ignore", category=DeprecationWarning) + warnings.filterwarnings("ignore", category=UserWarning, module="pytz") + warnings.filterwarnings("ignore", category=UserWarning, module="numpy") + warnings.filterwarnings("ignore", category=UserWarning, module="matplotlib") + + warnings.filterwarnings("ignore", category=RuntimeWarning) + + self.working_dir = config.get('Output', 'Working_dir') + self.gust_dir = config.get('Input', 'Gust_dir') + self.mult_file = config.get('Input', 'Multipliers') + + try: + self.main() + except ImportError as e: + log.critical("Missing module: {0}".format(e.strerror)) + except Exception: # pylint: disable=W0703 + # Catch any exceptions that occur and log them (nicely): + tblines = traceback.format_exc().splitlines() + for line in tblines: + log.critical(line.lstrip()) + + def main(self): + low_res_mult_file = os.path.join(self.working_dir, "low_res_m4.tif") + gust_files = [os.path.join(self.gust_dir, fn) for fn in os.listdir(self.gust_dir) if fn.startswith("gust")] + + log.info("Downscaling multipliers") + gdal.SetConfigOption('GDAL_NUM_THREADS', "16") + downscale_multipliers(self.mult_file, gust_files[0], low_res_mult_file) + gdal.SetConfigOption('GDAL_NUM_THREADS', "1") + + # indices, band numbers, and directions for using wind multipliers + indices = { + 0: {'dir': 'n', 'min': 0., 'max': 22.5}, + 1: {'dir': 'ne', 'min': 22.5, 'max': 67.5}, + 2: {'dir': 'e', 'min': 67.5, 'max': 112.5}, + 3: {'dir': 'se', 'min': 112.5, 'max': 157.5}, + 4: {'dir': 's', 'min': 157.5, 'max': 202.5}, + 5: {'dir': 'sw', 'min': 202.5, 'max': 247.5}, + 6: {'dir': 'w', 'min': 247.5, 'max': 292.5}, + 7: {'dir': 'nw', 'min': 292.5, 'max': 337.5}, + 8: {'dir': 'n', 'min': 337.5, 'max': 360.} + } + band_numbers_for_indices_in_geotiff = [2, 3, 1, 6, 5, 7, 8, 4, 2] + + # load in wind multiplier data + # reducing the resolution seems to ignore the -9999 nodata causing some -9999 to be averaged with real data + # these points (along with other nodata points) are set to 1 + ds = gdal.Open(low_res_mult_file, gdal.GA_ReadOnly) + bands = [] + for i in range(1, 9): + band = ds.GetRasterBand(i).ReadAsArray() + band[band < 0] = 1 + bands.append(band) + + log.info("Applying multipliers") + # loop through the gust files and apply the wm + for gust_file in tqdm(gust_files): + gust = xr.load_dataset(gust_file) + wind_data = gust.vmax + local = wind_data.copy() + + bearing = 2 * np.pi - (np.arctan2(-gust.va, -gust.ua) - np.pi / 2) + bearing = (180. / np.pi) * np.mod(bearing, 2. * np.pi) + + for i in list(indices.keys()): + idx = np.where((bearing >= indices[i]['min']) & (bearing < indices[i]['max'])) + m4 = bands[band_numbers_for_indices_in_geotiff[i] - 1] + local.data[idx] = wind_data.data[idx] * m4[idx] + + outds = xr.Dataset() + outds["vmax"] = local + outds.to_netcdf(gust_file.replace("gust", "wm_gust")) + + +if __name__ == "__main__": + run() \ No newline at end of file diff --git a/ProcessMultipliers/processMultipliers.py b/ProcessMultipliers/processMultipliers.py index 2e3da4e2..f45e1eb3 100755 --- a/ProcessMultipliers/processMultipliers.py +++ b/ProcessMultipliers/processMultipliers.py @@ -72,9 +72,10 @@ import numpy as np import numpy.ma as ma from botocore.exceptions import ClientError -from netCDF4 import Dataset + from osgeo import osr, gdal, gdalconst from osgeo.gdal_array import BandReadAsArray, CopyDatasetInfo, BandWriteArray +from netCDF4 import Dataset from Utilities import pathLocator from Utilities.AsyncRun import AsyncRun @@ -975,11 +976,17 @@ def processMultV2(wspd, uu, vv, lon, lat, working_dir, dirns, future_requests = [] with futures.ThreadPoolExecutor(max_workers=max_working_threads) as e: m4_max_file_obj = gdal.Open(m4_max_file, gdal.GA_ReadOnly) + + gdal.SetConfigOption('GDAL_NUM_THREADS', str(max_working_threads)) + reprojectDataset(wind_raster, m4_max_file_obj, wind_prj_file, warp_memory_limit=warp_memory_limit) reprojectDataset(bear_raster, m4_max_file_obj, bear_prj_file, warp_memory_limit=warp_memory_limit, resampling_method=gdalconst.GRA_NearestNeighbour) + + gdal.SetConfigOption('GDAL_NUM_THREADS', '1') + future_requests.append(e.submit(reprojectDataset, uu_raster, m4_max_file_obj, uu_prj_file, warp_memory_limit=warp_memory_limit, resampling_method=gdalconst.GRA_NearestNeighbour)) @@ -1054,7 +1061,7 @@ def processMultV2(wspd, uu, vv, lon, lat, working_dir, dirns, def call_process_multiplier_segment(segment_queue, source_dir_band, wind_prj, bear_prj, dst_band): while not segment_queue.empty(): processMultiplierSegment(segment_queue.get(), source_dir_band, wind_prj, bear_prj, dst_band) - dst_band.FlushCache() + def processMultiplierSegment(segment, source_dir_band, wind_prj, bear_prj, dst_band): """ diff --git a/README.rst b/README.rst index 392b7acb..e913678b 100644 --- a/README.rst +++ b/README.rst @@ -65,6 +65,7 @@ TCRM requires: Status ====== + .. image:: https://github.com/GeoscienceAustralia/tcrm/actions/workflows/tcrm-tests.yml/badge.svg?branch=master :target: https://github.com/GeoscienceAustralia/tcrm/actions/workflows/tcrm-tests.yml :alt: Build status diff --git a/StatInterface/SamplingOrigin.py b/StatInterface/SamplingOrigin.py index 5dea26aa..eb8e1068 100644 --- a/StatInterface/SamplingOrigin.py +++ b/StatInterface/SamplingOrigin.py @@ -18,7 +18,6 @@ from Utilities.files import flLoadFile, flSaveFile from Utilities.grid import grdRead, grdReadFromNetcdf import numpy as np -import scipy import Utilities.stats as stats LOG = logging.getLogger() @@ -119,8 +118,8 @@ def setKDEOrigins(self, kdeOriginX=None, kdeOriginY=None, kdeOriginZ=None, def generateOneSample(self): """Generate a random cyclone origin.""" # generate 2 uniform random variables - unifX = scipy.rand() - unifY = scipy.rand() + unifX = np.random.rand() + unifY = np.random.rand() xi = np.array(self.cdfX).searchsorted(unifX) yj = self.cdfY[xi, :].searchsorted(unifY) @@ -178,8 +177,8 @@ def generateSamples(self, ns, outputFile=None): raise ValueError # Generate 2 vectors of uniform random variables - unifX = scipy.rand(ns) - unifY = scipy.rand(ns) + unifX = np.random.rand(ns) + unifY = np.random.rand(ns) self.oLon = np.empty(ns, 'd') self.oLat = np.empty(ns, 'd') diff --git a/StatInterface/SamplingParameters.py b/StatInterface/SamplingParameters.py index 948578e0..ceccbfb7 100644 --- a/StatInterface/SamplingParameters.py +++ b/StatInterface/SamplingParameters.py @@ -16,7 +16,6 @@ import sys import logging -import scipy import numpy as np from Utilities.config import cnfGetIniValue from Utilities.files import flLoadFile, flSaveFile @@ -76,7 +75,7 @@ def setParameters(self, cdfParameters): def generateOneSample(self): """Generate a single random sample of cyclone parameters.""" - unif = scipy.rand() + unif = np.random.rand() ind_kdf = self.xacy[:, 1].searchsorted(unif) return self.xacy[ind_kdf, 0] @@ -96,7 +95,7 @@ def generateSamples(self, ns, sample_parameter_path=None): if ns <= 0: raise ValueError('invalid input on ns: number of sample cannot be zero or negative') - unif_s = scipy.rand(ns) + unif_s = np.random.rand(ns) ind_kdf = self.xacy[:, 1].searchsorted(unif_s) self.sample = self.xacy[ind_kdf, 0] diff --git a/StatInterface/StatInterface.py b/StatInterface/StatInterface.py index 86fe020c..802588e4 100644 --- a/StatInterface/StatInterface.py +++ b/StatInterface/StatInterface.py @@ -62,7 +62,7 @@ def __init__(self, configFile, autoCalc_gridLimit=None, gridLimitStr = cnfGetIniValue(self.configFile, 'StatInterface', 'gridLimit', '') - if gridLimitStr is not '': + if gridLimitStr != '': try: self.gridLimit = eval(gridLimitStr) except SyntaxError: diff --git a/StatInterface/generateStats.py b/StatInterface/generateStats.py index fa7de694..cbcc8572 100644 --- a/StatInterface/generateStats.py +++ b/StatInterface/generateStats.py @@ -16,6 +16,7 @@ import sys import numpy as np +import statsmodels.api as sm import Utilities.stats as stats @@ -32,12 +33,9 @@ def acf(p, nlags=1): :type p: 1-d :class:`numpy.ndarray` """ - ar = np.array([1]+[np.corrcoef(p[:-i], p[i:])[0,1] for i in range(1, nlags + 1)]) - #ar = np.correlate(p, p, 'full') - #n = len(p) - ## Grab only the lag-one autocorrelation coeff. - #ar = ar[n-1:(n+nlags)]/ar.max() - return ar + + acorr = sm.tsa.acf(p, nlags=nlags) + return acorr class parameters(object): @@ -242,11 +240,6 @@ def calculate(self, cellNum, onLand): sig = np.std(p) # Calculate the autocorrelations: - alphas = np.correlate(p, p, 'full') - n = len(p) - - # Grab only the lag-one autocorrelation coeff. - alpha = alphas[n]/alphas.max() alpha = acf(p)[-1] phi = np.sqrt(1 - alpha**2) mn = min(p) diff --git a/TrackGenerator/TrackGenerator.py b/TrackGenerator/TrackGenerator.py index 87af2e82..66156740 100644 --- a/TrackGenerator/TrackGenerator.py +++ b/TrackGenerator/TrackGenerator.py @@ -418,7 +418,7 @@ def init(filename, angular=False): log.debug('Loading cell statistics for speed from netcdf file') self.vStats = init('all_speed') - self.vStats.load(pjoin(self.processPath, 'speed_stats.nc')) + self.vStats.load(pjoin(self.processPath, 'speed_rate_stats.nc')) log.debug('Loading cell statistics for pressure from netcdf file') self.pStats = init('all_pressure') @@ -426,7 +426,7 @@ def init(filename, angular=False): log.debug('Loading cell statistics for bearing from netcdf file') self.bStats = init('all_bearing', angular=True) - self.bStats.load(pjoin(self.processPath, 'bearing_stats.nc')) + self.bStats.load(pjoin(self.processPath, 'bearing_rate_stats.nc')) log.debug('Loading cell statistics for pressure_rate from netcdf file') self.dpStats = init('pressure_rate') @@ -1141,7 +1141,7 @@ def _stepBearing(self, c, i, onLand): if i == 1: self.theta += math.degrees(sigma[c] * self.bChi) else: - self.theta = math.degrees(mu[c] + sigma[c] * self.bChi) + self.theta += math.degrees(mu[c] + sigma[c] * self.bChi) self.theta = np.mod(self.theta, 360.) @@ -1185,7 +1185,7 @@ def _stepSpeed(self, c, i, onLand): if i == 1: self.v += abs(sigma[c] * self.vChi) else: - self.v = abs(mu[c] + sigma[c] * self.vChi) + self.v += (mu[c] + sigma[c] * self.vChi) def _stepSizeChange(self, c, i, onLand): """ diff --git a/TrackGenerator/trackSize.py b/TrackGenerator/trackSize.py index d1a92df5..f46a7c1d 100644 --- a/TrackGenerator/trackSize.py +++ b/TrackGenerator/trackSize.py @@ -18,16 +18,14 @@ LOG = logging.getLogger() -def rmax(dp, lat, eps, coeffs=[3.5843946536979779,-0.0045486143609339436, - 0.78621467400844858, 0.0024030344245284741, - 0.0015567629057007433]): +def rmax(dp, lat, eps, coeffs=[4.22, -0.0198, 0.0023]): """ Calculate radius to maximum wind based on pressure deficit and latitude. This function allows for the random variate to be set when calling the function. Default coefficients for the functional form of ln(Rmw) are given, based on JTWC data for the southern hemisphere. - ln(Rmw) = a + b*dp + c*exp(-d*dp^2) + f*|lat| + eps + ln(Rmw) = a + b*dp + c*|lat| + eps eps is not included in the coefficients (though that may be considered by some to be more logical), so that it can remain constant for a single @@ -43,18 +41,16 @@ def rmax(dp, lat, eps, coeffs=[3.5843946536979779,-0.0045486143609339436, :returns: radius to maximum wind value. """ - if len(coeffs) < 4: - LOG.warn("Insufficient coefficients for rmw calculation!") - LOG.warn("Using default values") - coeffs = [3.5843946536979779,-0.0045486143609339436, - 0.78621467400844858, 0.0024030344245284741, - 0.0015567629057007433] + if len(coeffs) != 3: + LOG.warning("Insufficient coefficients for rmw calculation!") + LOG.warning("Using default values") + + coeffs = [4.22, -0.0198, 0.0023] if isinstance(dp, (np.ndarray, list)) and \ isinstance(lat, (np.ndarray, list)): assert len(dp) == len(lat) - yy = coeffs[0] + coeffs[1]*dp + coeffs[2] * np.exp(-coeffs[3] * dp * dp) +\ - coeffs[4] * np.abs(lat) + eps + yy = coeffs[0] + coeffs[1] * dp + coeffs[2] * np.abs(lat) + eps rm = np.exp(yy) return rm @@ -65,7 +61,7 @@ def fitRmax(rmw, dp, lat): We fit a function of dp and latitude to ln(Rmw) values of the form: - ln(Rmw) = a + b*dp + c*dp^2 + d*lat^2 + eps + ln(Rmw) = a + b*dp + c*|lat| + eps where eps is a random normal variate with zero mean and std. dev. describing the residual variance. @@ -84,8 +80,7 @@ def fitRmax(rmw, dp, lat): assert len(dp) == len(lat) assert len(rmw) == len(dp) - X = np.column_stack((dp, dp*dp, lat*lat)) - X = sm.add_constant(X) + X = np.column_stack((dp, abs(lat))) y = np.array(np.log(rmw)) model = sm.OLS(y, X) results = model.fit() diff --git a/Utilities/config.py b/Utilities/config.py index facc37b5..10a65ee2 100644 --- a/Utilities/config.py +++ b/Utilities/config.py @@ -262,7 +262,7 @@ class _ConfigParser(RawConfigParser): ignoreSubsequent = True def __init__(self, defaults=DEFAULTS): RawConfigParser.__init__(self) - self.readfp(io.StringIO(defaults)) + self.read_file(io.StringIO(defaults)) self.readonce = False def geteval(self, section, option): diff --git a/Utilities/files.py b/Utilities/files.py index 26218268..a58f7f81 100644 --- a/Utilities/files.py +++ b/Utilities/files.py @@ -5,6 +5,7 @@ import datetime import numpy as np from time import ctime, localtime, strftime +from pathlib import Path import hashlib @@ -29,6 +30,7 @@ def flModulePath(level=1): """ filename = os.path.realpath(sys._getframe(level).f_code.co_filename) path, fname = os.path.split(filename) + path = str(Path(path).resolve()) path.replace(os.path.sep, '/') base, ext = os.path.splitext(fname) return path, base, ext diff --git a/Utilities/loadData.py b/Utilities/loadData.py index a2eb5d79..ea3d5521 100644 --- a/Utilities/loadData.py +++ b/Utilities/loadData.py @@ -687,8 +687,8 @@ def getPoci(penv, pcentre, lat, jdays, eps, """ if len(coeffs) < 6: - LOG.warn("Insufficient coefficients for poci calculation") - LOG.warn("Using default values") + LOG.warning("Insufficient coefficients for poci calculation") + LOG.warning("Using default values") coeffs=[2324.1564738613392, -0.6539853183796136, -1.3984456535888878, 0.00074072928008818927, 0.0044469231429346088, -1.4337623534206905] diff --git a/Utilities/maputils.f90 b/Utilities/maputils.f90 new file mode 100644 index 00000000..0a181886 --- /dev/null +++ b/Utilities/maputils.f90 @@ -0,0 +1,65 @@ +subroutine beardist(cLon, cLat, lonArray, latArray, bearing, dist, nlon, nlat) + !$ use omp_lib + +! :param double cLon: longitude of storm centre (degrees) +! :param double clat: latitude of storm centre (degrees) +! :param lonArray: 1D double precision array of longitudes (degrees) +! :param latArray: 1D double precision array of latitudes (degrees) +! :param bearing: 2D double precision output array of bearings with shape (nlat, nlon) (radians) +! :param dist: 2D double precision output array of distances with shape (nlat, nlon) (km) +! :param int nlon: length of lonArray +! :param int nlat: length of latArray + + integer, intent(in) :: nlon, nlat + doubleprecision, intent(in) :: lonArray(nlon), latArray(nlat) + doubleprecision, intent(inout), dimension(nlat, nlon) :: bearing, dist + + doubleprecision :: toRads, cLon, cLat, dlon, lon(nlon), lat(nlat), radius + doubleprecision :: dLon_sin(nlon), dLon_cos(nlon), lat_sin(nlat), lat_cos(nlat) + doubleprecision :: dLat_sin(nlat), dhalfLon_sin(nlon), a, c, pi + doubleprecision :: cLon_, cLat_, cLat_cos, cLat_sin, alpha, beta + + pi = 4.d0*datan(1.d0) + toRads = 0.017453292519943295 + radius = 6367.0 + + cLon_ = cLon; + cLat_ = cLat; + + cLon_ = cLon_ * toRads + cLat_ = cLat_ * toRads + + cLat_cos = cos(cLat_) + cLat_sin = sin(cLat_) + + do i = 1, nlon + lon(i) = lonArray(i) * toRads + dLon = lon(i) - cLon_ + dLon_sin(i) = sin(dLon) + dLon_cos(i) = cos(dLon) + dhalfLon_sin(i) = sin(0.5 * dLon) + end do + + do i = 1, nlat + lat(i) = latArray(i) * toRads + lat_sin(i) = sin(lat(i)) + lat_cos(i) = cos(lat(i)) + dLat_sin(i) = sin(0.5 * (lat(i) - cLat_)) + end do + + !$OMP PARALLEL DO shared(bearing, dist) + do j = 1, nlat + do i = 1, nlon + + alpha = dLon_sin(i) * lat_cos(j); + beta = (cLat_cos * lat_sin(j)) - (cLat_sin * lat_cos(j) * dLon_cos(i)); + bearing(j, i) = 0.5 * pi - atan2(alpha, beta); + + a = dLat_sin(j) * dLat_sin(j) + cLat_cos * lat_cos(j) * dhalfLon_sin(i) * dhalfLon_sin(i); + c = 2.0 * atan2(sqrt(abs(a)), sqrt(1.0 - a)); + dist(j, i) = max(radius*c, 1e-30); + end do + end do + !$OMP END PARALLEL DO + +end subroutine beardist \ No newline at end of file diff --git a/Utilities/maputils.py b/Utilities/maputils.py index 3fff81fe..61a60e97 100644 --- a/Utilities/maputils.py +++ b/Utilities/maputils.py @@ -17,6 +17,11 @@ import numpy as np import math from . import metutils +import warnings +try: + from . import fmaputils +except ImportError: + warnings.warn("Compiled maputils not found - defaulting to slower python wind models") # C weave code disabled for now. The code speeds up the windfield interface module by ~6% but @@ -508,9 +513,20 @@ def makeGrid(cLon, cLat, margin=2, resolution=0.01, minLon=None, maxLon=None, xGrid = np.array(np.arange(minLon_, maxLon_, gridSize), dtype=int) yGrid = np.array(np.arange(minLat_, maxLat_, gridSize), dtype=int) - R = gridLatLonDist(cLon, cLat, xGrid / 1000., yGrid / 1000.) - np.putmask(R, R==0, 1e-30) - theta = np.pi/2. - gridLatLonBear(cLon, cLat, xGrid / 1000., yGrid / 1000.) + try: + from ._maputils import beardist + lonArray = xGrid / 1000. + latArray = yGrid / 1000. + R = np.zeros((len(latArray), len(lonArray)), order='F') + theta = np.zeros((len(latArray), len(lonArray)), order='F') + + beardist(cLon, cLat, lonArray, latArray, theta, R) + R = np.ascontiguousarray(R) + theta = np.ascontiguousarray(theta) + except ImportError: + R = gridLatLonDist(cLon, cLat, xGrid / 1000., yGrid / 1000.) + theta = np.pi/2. - gridLatLonBear(cLon, cLat, xGrid / 1000., yGrid / 1000.) + np.putmask(R, R == 0, 1e-30) return R, theta diff --git a/Utilities/process.py b/Utilities/process.py index dbcb1bd9..02cc2ec3 100644 --- a/Utilities/process.py +++ b/Utilities/process.py @@ -92,7 +92,7 @@ def pGetProcessedFiles(datFileName=None): fh = open(datFileName) except IOError: - LOGGER.warn("Couldn't open dat file %s", datFileName) + LOGGER.warning("Couldn't open dat file %s", datFileName) return rc else: LOGGER.debug("Getting previously-processed files from %s", @@ -141,8 +141,8 @@ def pWriteProcessedFile(filename): fh.close() rc = 1 else: - LOGGER.warn(("Dat file name not provided. " - "Can't record %s as processed."), filename) + LOGGER.warning(("Dat file name not provided. " + "Can't record %s as processed."), filename) return rc @@ -161,7 +161,7 @@ def pDeleteDatFile(): if os.unlink(GLOBAL_DATFILE): rc = 1 else: - LOGGER.warn("Cannot remove dat file %s", GLOBAL_DATFILE) + LOGGER.warning("Cannot remove dat file %s", GLOBAL_DATFILE) return rc def pAlreadyProcessed(directory, filename, attribute, value): @@ -268,7 +268,7 @@ def pMoveFile(origin, destination): try: os.rename(origin, destination) except OSError: - LOGGER.warn("Error moving %s to %s", origin, destination) + LOGGER.warning("Error moving %s to %s", origin, destination) rc = 0 else: LOGGER.debug("%s moved to %s", origin, destination) diff --git a/Utilities/shptools.py b/Utilities/shptools.py index d18297f7..daa6054c 100644 --- a/Utilities/shptools.py +++ b/Utilities/shptools.py @@ -314,9 +314,9 @@ def shpGetField(shape_file, field_name, dtype=float): field_names = [fields[i][0] for i in range(len(fields))] if field_name not in field_names: - log.warn("No field '{0}' in the list of fieldnames" . + log.warning("No field '{0}' in the list of fieldnames" . format(field_name)) - log.warn("Unable to proceed with processing") + log.warning("Unable to proceed with processing") raise ValueError records = sf.records() diff --git a/Utilities/track.py b/Utilities/track.py index 1cca7c1d..84b6b98f 100644 --- a/Utilities/track.py +++ b/Utilities/track.py @@ -81,15 +81,22 @@ def __init__(self, data): self.data = data self.trackId = None self.trackfile = None - if (len(data) > 0) and ('CentralPressure' in data.dtype.names): + if (len(data) > 0) and self.has_key('CentralPressure'): self.trackMinPressure = np.min(data['CentralPressure']) else: self.trackMinPressure = None - if (len(data) > 0) and ('WindSpeed' in data.dtype.names): + if (len(data) > 0) and self.has_key('WindSpeed'): self.trackMaxWind = np.max(data['WindSpeed']) else: self.trackMaxWind = None + def has_key(self, key): + + try: + return (key in self.data.dtype.names) + except AttributeError: + return (key in self.data.columns) + def __getattr__(self, key): """ Get the `key` from the `data` object. @@ -252,7 +259,7 @@ def ncReadTrackData(trackfile): tracks.append(track) else: - log.warn(TRACK_EMPTY_GROUP.format(trackfile)) + log.warning(TRACK_EMPTY_GROUP.format(trackfile)) ncobj.close() return tracks diff --git a/create_era5_mslp.sh b/create_era5_mslp.sh new file mode 100755 index 00000000..27b2fa0d --- /dev/null +++ b/create_era5_mslp.sh @@ -0,0 +1,73 @@ +#!/bin/bash +#PBS -Pw85 +#PBS -qnormal +#PBS -N calc_era5_mslp +#PBS -m ae +#PBS -M craig.arthur@ga.gov.au +#PBS -lwalltime=48:00:00 +#PBS -lmem=64GB,ncpus=16,jobfs=8000MB +#PBS -W umask=0002 +#PBS -joe +#PBS -lstorage=scratch/w85+gdata/ub4 +#PBS -v STARTYEAR + +module purge +module load pbs +module load dot + +module load netcdf/4.6.3 +module load cdo/1.9.8 +module load nco/4.9.2 +module load openmpi + +# Suppresses an error related to HDF5 libraries: +export HDF5_DISABLE_VERSION_CHECK=2 +ECHO=/bin/echo + +cd ${PBS_JOBFS} + +BASEPATH=/g/data/ub4/era5/netcdf/surface/msl +SCRATCH=/scratch/w85/ + +#STARTYEAR=1979 +COUNTER=0 +LOGFILE=$HOME/tcrm/calc_era5_mslp.$STARTYEAR.log +echo "Starting calculation of daily long term mean MSL" > $LOGFILE +for i in {0..40..1}; do + for m in {1..12..1}; do + YEAR=$(($STARTYEAR + $i)) + ENDDATE=`date -d "$YEAR/$m/1 +1 month -1 day" "+%Y%m%d"` + STARTDATE=`date -d "$YEAR/$m/1" "+%Y%m%d"` + DATESTR=$STARTDATE\_$ENDDATE + INPUTFILE=$BASEPATH/$YEAR/msl_era5_global_$DATESTR.nc + MONTHFMT=`date -d "$YEAR/$m/1" "+%Y%m"` + OUTPUTFILE=${PBS_JOBFS}/msl_era5_global.$MONTHFMT.nc + echo $INPUTFILE >> $LOGFILE + echo $OUTPUTFILE >> $LOGFILE + cdo daymean $INPUTFILE $OUTPUTFILE + if [[ $? -ne 0 ]]; then + echo "Looks like the command failed when processing $INPUTFILE" >> $LOGFILE + else + ((COUNTER+=1)) + echo "Processed $INPUTFILE ($COUNTER)" >> $LOGFILE + fi + done + # concatenate individual monthly files into annual files + cdo -b F64 mergetime ${PBS_JOBFS}/msl_era5_global.$YEAR[0-9][0-9].nc $SCRATCH/msl/msl_era5_global.$YEAR.nc + # Remove individual monthly files: + rm ${PBS_JOBFS}/msl_era5_global.$YEAR[0-9][0-9].nc +done + +$ECHO "Finished processing $COUNTER files for daily MSLP data" >> $LOGFILE + +#$ECHO "Now merging into a single daily long-term mean dataset" >> $LOGFILE + +#cd $SCRATCH/msl + +#cdo -P ${PBS_NCPUS} ydaymean -cat 'msl_era5_global.*.nc' msl_era5_global_dailyltm.nc + +#if [[ $? -ne 0 ]]; then +# $ECHO "cdo ydaymean command failed" >> $LOGFILE +#else +# $ECHO "Finished processing $COUNTER files to create daily long-term mean MSL file" >> $LOGFILE +#fi diff --git a/hazard/GPD.py b/hazard/GPD.py index 3c6080d8..f53976d5 100644 --- a/hazard/GPD.py +++ b/hazard/GPD.py @@ -43,6 +43,28 @@ def gpdReturnLevel(intervals, mu, shape, scale, rate, npyr=365.25): rp = mu + (scale / shape) * (np.power(intervals * npyr * rate, shape) - 1.) return rp + +def gpdRecurrenceIntervals(return_levels, mu, shape, scale, rate, npyr=365.25): + """ + Calculate recurrence intervals for specified return levels for a distribution with + the given threshold, scale and shape parameters. + + :param intervals: :class:`numpy.ndarray` or float of return levels + to evaluate recurrence intervals for. + :param float mu: Threshold parameter (also called location). + :param float shape: Shape parameter. + :param float scale: Scale parameter. + :param float rate: Rate of exceedances (i.e. number of observations greater + than `mu`, divided by total number of observations). + :param float npyr: Number of observations per year. + + :returns: recurrence intervals for the specified return levels. + + """ + ri = np.power((return_levels - mu) * (shape / scale) + 1, 1 / shape) / (npyr * rate) + return ri + + def gpdfit(data, years, numsim, missingValue=-9999, minrecords=50, threshold=99.5): """ diff --git a/hazard/evd.py b/hazard/evd.py index cf08981d..a9fefaaa 100644 --- a/hazard/evd.py +++ b/hazard/evd.py @@ -295,9 +295,8 @@ def gevfit(data, intervals, nodata=-9999., minrecords=50, yrspersim=1): # not all equal, and where there are 50 or more valid (>0) values. if data[ii].min() != data[ii].max(): if len(ii) >= minrecords: - l1, l2, l3 = lmom.samlmu(data, 3) # find 3 l-moments - # t3 = L-skewness (Hosking 1990) - t3 = l3 / l2 + l1, l2, t3 = lmom.samlmu(data, 3) # find the first 2 L-moments and the L-skewness + if (l2 <= 0.) or (np.abs(t3) >= 1.): # Reject points where the second l-moment is negative # or the ratio of the third to second is > 1, i.e. positive diff --git a/installer/setup.py b/installer/setup.py index 423b9430..c693527c 100644 --- a/installer/setup.py +++ b/installer/setup.py @@ -9,7 +9,8 @@ import matplotlib import numpy import sys -from setuptools import setup, Extension +# from setuptools import Extension +from numpy.distutils.core import setup, Extension from distutils.sysconfig import get_python_lib from os.path import join as pjoin from glob import glob @@ -53,7 +54,19 @@ Extension('Utilities._akima', sources=[pjoin('Utilities', 'akima.c')], include_dirs=[pjoin(numpy.get_include(), 'numpy')], - extra_compile_args=[]) + extra_compile_args=[]), + Extension('wind._windmodels', + sources=[pjoin('wind', 'windmodels.f90')], + include_dirs=[pjoin(numpy.get_include(), 'numpy')], + extra_compile_args=['-g']), + Extension('Utilities._maputils', + sources=[pjoin('Utilities', 'maputils.f90')], + include_dirs=[pjoin(numpy.get_include(), 'numpy')], + extra_compile_args=['-g']), + Extension('PressureInterface._pressureProfile', + sources=[pjoin('PressureInterface', 'pressureProfile.f90')], + include_dirs=[pjoin(numpy.get_include(), 'numpy')], + extra_compile_args=['-g']) ] basemapData = pjoin('mpl_toolkits', 'basemap', 'data') diff --git a/setup.py b/setup.py index ba3b06e5..51b0b04c 100644 --- a/setup.py +++ b/setup.py @@ -7,8 +7,8 @@ setup( name = "TCRM", - version = '3.1.4', - packages=find_packages(), + version = '3.1.12', + packages=find_packages(), scripts=['tcrm.py', 'tcevent.py'], include_package_data=True, package_data = { @@ -46,7 +46,9 @@ 'imageio', 'mpi4py', 'boto3', - 'botocore'], + 'botocore', + 'pytest', + 'pytest-cov'], # metadata: author = "Craig Arthur", diff --git a/tcrmenv.yml b/tcrmenv.yml index 84d02fa7..f42ac7c0 100644 --- a/tcrmenv.yml +++ b/tcrmenv.yml @@ -3,6 +3,8 @@ channels: - defaults - conda-forge dependencies: + - gdal + - libgdal - pip - numpy - scipy @@ -20,10 +22,8 @@ dependencies: - simplejson - sqlite - statsmodels - - libgdal - - gdal - configparser - - cartopy + - cartopy>=0.18.0 - affine - tqdm - xarray @@ -32,3 +32,5 @@ dependencies: - mpi4py - boto3 - botocore + - pytest + - pytest-cov diff --git a/tests/NumpyTestCase.py b/tests/NumpyTestCase.py index f07c54fa..e1485c4e 100644 --- a/tests/NumpyTestCase.py +++ b/tests/NumpyTestCase.py @@ -9,7 +9,8 @@ $Id: NumpyTestCase.py 563 2007-10-24 02:52:40Z carthur $ """ -from scipy import array, alltrue, iscomplexobj, allclose, equal +from scipy import array +from numpy import allclose, iscomplexobj, alltrue, equal import unittest class NumpyTestCase(unittest.TestCase): diff --git a/tests/__init__.py b/tests/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/test_GPD.py b/tests/test_GPD.py index 83791d66..381c8b2f 100644 --- a/tests/test_GPD.py +++ b/tests/test_GPD.py @@ -34,7 +34,7 @@ import sys import unittest import pickle -from . import NumpyTestCase +import NumpyTestCase import numpy # Add parent folder to python path diff --git a/tests/test_Intersections.py b/tests/test_Intersections.py index 3940ab7c..3039b3b6 100644 --- a/tests/test_Intersections.py +++ b/tests/test_Intersections.py @@ -11,7 +11,7 @@ import logging import numpy -from . import NumpyTestCase +from tests import NumpyTestCase # Add parent folder to python path unittest_dir = os.path.dirname(os.path.realpath( __file__ )) diff --git a/tests/test_KDEOrigin.py b/tests/test_KDEOrigin.py index 6c2824c9..26896dd7 100644 --- a/tests/test_KDEOrigin.py +++ b/tests/test_KDEOrigin.py @@ -11,11 +11,11 @@ import os, sys, pdb import pickle import unittest -from . import NumpyTestCase +from tests import NumpyTestCase try: from . import pathLocate except: - from unittests import pathLocate + from tests import pathLocate # Add parent folder to python path unittest_dir = pathLocate.getUnitTestDirectory() diff --git a/tests/test_KDEParameters.py b/tests/test_KDEParameters.py index 953a4f46..37ebff62 100644 --- a/tests/test_KDEParameters.py +++ b/tests/test_KDEParameters.py @@ -28,11 +28,11 @@ import os, sys import pickle import unittest -from . import NumpyTestCase +from tests import NumpyTestCase try: from . import pathLocate except: - from unittests import pathLocate + from tests import pathLocate # Add parent folder to python path unittest_dir = pathLocate.getUnitTestDirectory() diff --git a/tests/test_SamplingOrigin.py b/tests/test_SamplingOrigin.py index 90894373..6c62968d 100644 --- a/tests/test_SamplingOrigin.py +++ b/tests/test_SamplingOrigin.py @@ -28,12 +28,12 @@ import os, sys import pickle import unittest -from scipy import random -from . import NumpyTestCase +from numpy import random +from tests import NumpyTestCase try: from . import pathLocate except: - from unittests import pathLocate + from tests import pathLocate # Add parent folder to python path unittest_dir = pathLocate.getUnitTestDirectory() diff --git a/tests/test_SamplingParameters.py b/tests/test_SamplingParameters.py index 7ef2041b..12053a53 100644 --- a/tests/test_SamplingParameters.py +++ b/tests/test_SamplingParameters.py @@ -28,12 +28,12 @@ import os, sys import pickle import unittest -from scipy import random -from . import NumpyTestCase +from numpy import random +from tests import NumpyTestCase try: from . import pathLocate except: - from unittests import pathLocate + from tests import pathLocate # Add parent folder to python path unittest_dir = pathLocate.getUnitTestDirectory() diff --git a/tests/test_columns.py b/tests/test_columns.py index fbba827e..c65c2846 100644 --- a/tests/test_columns.py +++ b/tests/test_columns.py @@ -3,7 +3,7 @@ from numpy.testing import assert_equal from os.path import join as pjoin -from . import pathLocate +from tests import pathLocate unittest_dir = pathLocate.getUnitTestDirectory() diff --git a/tests/test_config.py b/tests/test_config.py index ebb10758..fcf53ee6 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -6,7 +6,7 @@ #from Utilities import Utilities.config as config #.config import ConfigParser, cnfGetIniValue, parseBool, parseList, formatList from Utilities.config import reset as forgetAllSingletons -from . import pathLocate +from tests import pathLocate unittest_dir = pathLocate.getUnitTestDirectory() diff --git a/tests/test_data/vorticityTestData.pkl b/tests/test_data/vorticityTestData.pkl index f3b0f72acf2ae857412b473fec9b250547a20dd7..72e285cb4379e111793e182dcb5d0f2f71ea1c91 100644 GIT binary patch delta 151 zcmZoZB=h;83`+ycRIlk9EZNGLIy*Mj-+sn8b#nCcEFfoMz4GQa&jrph!li*C+h=cO o-0=({wEg@XCZHY^C7vzJ$Vx!E7G$%a3w;k_MHlk3V%z!*0Nutx&;S4c delta 184 zcmex-P^S5i3`+ycRG;a7bC}9mycxV1rx#|kC~sV_;~C@h$&t^q5MrBOJQq02h^}(` q)UAv_wHU&$<}hIswr^oZ72XcC?luoWjJ=Rw5) diff --git a/tests/test_data/windFieldTestData.pkl b/tests/test_data/windFieldTestData.pkl index 97c93d9234b0f600c5dfce4f8af32650de021cb9..28fd545fd83307bba846aadec236cc1e05e3770c 100644 GIT binary patch delta 106289 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 delta 106035 zcmZ6TcQ}@R-^Y`FN|C)Il#+;2HX*twLPEAQlu=13iVMle-ZMfn_XfHhsH9vtrjA+>LzyAr*96uJaG%odjf9sUwt%Wd)SH~e~8Ar>o2%7@ojUFH9>y4Z^6*Zh9Lhs z`~EYny9D{Z-m9nC?h)h%te8CpKqkAB58vD;$R{6`A-iphzkjnpSl|IczM8mi=WlSL zQr@8zDL*ye|_5^Sn^-MOtd{ge&PN~y7ps&ykg7(-M%LT z`61&j#xhXES2**L1AczSzL(#TAn*2P(5DB?yT_gV@+m={rJY|%@)<$?KcP+jF_3%6 zMJ>pQAb&qnGfc{vAkU%uW^BlrNRWS~E5q#xsvI@o5^y2N$BWnG*Mal>lQp+p3G$VW zlkB_P2=bS=hg@U9rO!vcoqSG^zxE;IYX$hecbfCEJ3(ICS~b59tTgx5y8eP7FXYyi zItup8v3g(kAjs!a#Afz^yF(w3X?hamcg!97TSCO5TxvP;m={6b*g7u751ifaH}e~$ zZ@VU;pDj*w~ETJ?Al1XP!jGI8Rqkdcpx!>Su=gGWCxFy+i=e82uI!gSTD>aM7+-413IOMWk2&|WeRQ7+)o*w`Y zF)HY~Kq}kh%gtPnDOw`c{VTX`a9my+GI>RPte*f2E|~sxgiE7KY<84L^5K_h#!!&V zCNz>1xhsLPBo>_bMytw>YB=QDmV-g!>xZ^}q)wk@Ml?JGm&*1!_k+Fuf)?_=1o`XH zkFLA|Z$BSmTm)|osXbNlBgjXYRhamL`u0W9EnwL*b(;PD1o@eJG70BE-brSu2jI5S z@!BYGC!eF-SMXJObZ8q$y(_eO)F0>n((Cm0IsD)qokYbVsQgtU`Y-6k9&>XXY}xql zbSHSH$C0HNWQvVB91ni{>iEC`d=;m|t_}*WXo|Cg11aKTgV<0~wv2KD=ongRX9!vz zV-KbQIUipyE5abz5*H5L@moMp>}f_B=N|B;&2AXPN+2 zOZRvcLbfHUB>MnJwi%Z`WCqD*ufO>w0?7i*tcABh-=CU{^^nas(6;P?axM{)8SHp=*%6XGlolXI3k{ptXUC~ArV>)+;{3Lk{X$5sv(cKBUHu*wui$MMUSOCs%+fl6`@QsN! z*#g)kSL$*pkRX39=IN^>FhJwrv3aoU;?SyO5bgmUty7NRNveH)+2E0gimY)^&&ODw zA($Xf>tj$N4!-17?!E#tOA~!xTVmmMM4Q0@yvieS+69#6XV^<3#cW3W6VM~siJbKJ zsY_ICIySk9c5NE8Dwg{j=YjLTTWMHX19E9JDUNM|`vN2jQz6&Ufs}L|$Q5l#h}{DBop89B z47t*~C5BZYl|m=O_-`JxbnRZ(4+=!vfljI1M)Z!{%zpT zS?P8ZOo9Q8rLs++hp>NGI>?rBwBH>xjLABw14hnRWO0E$g~~2N*pT*0Wzj2ecWH>f zHh3-a3JZ}O3*sAdr!-9R-$eA72H4>);4p)U?c1*zz5w@%_JK<~WqPWTB%A4rQ&Esjy?}qj3X-{;`MV(l$1)P_U8vyLVp#p% z9#Fu;nfUE3B-0%C3buu0uktR{OQDj)?UxQaA(zWr*;ln7&B+icKS=hty!whJBvW48 zoTYM`4!|Uk=;_)gj|gp8;WG4D_5|bOD4GYQpF!*$kq8z<1rXp@1rAjqJM1!JBF+@@LWAZmJ~BT+rV^xa=q#z|3kPU}wGT z#}$y>CnQxbf*^mX^)7iP*pZa;oGg+c?=2F#b`iWg+b$CTW_KRs`wq(S@q})JSuv6K z1*1^CW!L3*T3Ae#?mvDHtkBR}bO%447a$7(FB?r?i2}16dY2=>fah&X{$S;QQ|8X# z*C8scTOikXeD`^ltlj)F+$G`NP2V`@Yre8#r`+%NV26|`F$6Xtz4;&KMl#8SH4xQ zfS0e=8y7&b<^blqB*{YV$E-+0E{Bw&?N!ihC-sY5I98Ok?qv(dzI^f7dmL{0Z!A)b z5V2@Iuj~*7$@Utp>tBLg)3Wh#WRPmTQD5>icvhQ0u;h4z4pNcj_p20v$zC7K zEFhPHK$|KJq}oVk>dgi=7TqF^T=L1pcAzLtcRFili z2@9#W4+iVOwMn+%SaOpHj;$a8nh{W|nV2H!%2|nBRu(yWH~QE6BFAS>_LB{7JiM2&R#*k8y*YwPRKT*wDQd;xb1B7LgC9 z52}DUqgDy?m_%V`d0jYI{~*5lG`PV(R8o(Li+&pqnSej)@^yYAkw%`gga@E@UE#n2 z5;Kn-EWY7{3sk;?fC40oQl|aO0mpLU*=YZP#w(sL>fxH!?pBRNxOR{DdDX@qlBHe> z8c=~`tINf2*dSR!vTX4LD0b0MD3^3ad%CdT3dyEMZZfJtvWGpML5z^A{Bq#kUQpJ2 zGvhTRn~Z*-djpaw5d&@?fm_zMizdcEE8WHJWH`2@VJ~+bj;V^cvK)k4#Ce+K8{Jqu zY~DN^49Ofz!nIW)7e|@!)D~#5Bs`D>$#$8!@!f=6%AP!FOpvN5|DACq_^@gGpe^KD ztqN}AfK*a;wLN>QZ?z|Q$=lmk`qUFM5u*; zYOfr#H$ayom!Fx&A?p6arUf8{tpz7-JVBl^AkxVgOeGenC4n@BMJ7Y>=%gk5l|RdC zTp-w^ij~2BE}kwc@UV8#cW*HDdS_rf7~W{bmkw_Jm+zMaet6N)_7R*k;MkoE7MX5K z2ZQb$=Y1Z7|Y_-+5$`xe&2PjIPa=0JA^MxKCln zO2Mb&!a!v+Dr4LSB$;-b#>050cF(YD*u6WQPT!KmP&4%wrt$Az7Zpy%1MO zc1auba)~D=?_C9b_Klf*gk;%DD*J9gt_$KZlqC zB{4+1?^{m&H}F>E8+v_IAfA|6Hv*cFX}`LIs?6ucPfmf}Sxv$>(XDMq=-D1nPLPI5 zH364&{-@_Yfz7|1BIy(H9q}Yhg*E7LMai`U6m?yW*qek06k@Szn>rTu>RS}vpbl5& z{z7mc(@4V@nA5W$O!)@a{PM}8hd}eH6Pc$$gFh$hWI@}26(>2c;CW)V7|8s3bnXb) zGW@)6KNwa}l0S>jaX#Jhz8W;sHE9V4kEgBZnSw+Q!vqU%Eckz25$wUvoaN%%e8I>{ z3110to+j-@KPGuqx@+z!n787w&H%2Qxz|Oq{y4|i+>_w-4+~XakVv`>^%;`P`M;%3 zeMVxd>upo~VAJncPoKNvIUvL~k@R-#pUeoOBI)`6)x=aI7bNQ}+^k;(^WE8~+92Cn zYLj;=Wb4+{P;!A};rs7OU4dldKQgS2Kr&a0^Ic0|vC{$9D#&(?@0&$1B)i7p=Wh(j zhE0`LjzF>(zqC?j!3KrriKOp@kFNZlB7LR%{4wi=bO;d-9D{xK8<33p16g?iB)b){ zddC5htpqsTKLfcGO=mEu7Jv>< z(z10C=}Jw9-7FZd*CgtO$cdM9U(ulwqbrFzvEWNu_iY|j$21x%lL%7Vzs)#+&ZQem zRsunm@|@Bw@MVZh=FMc>%!=sjtH2k0Th*Lz@$U4#TT?7B>JXjM2`$dSvqgy!OkFfcuQZOg-yvtKi=WfwnVX(RP zk7X}*e2e8)n+s^qDE;^#7_#}z`wJ%fVt-Rk6?}S#wYD7z6m{9?8-T&>N{2}@6SUsy zUja>Pl8=2uf*EJdS4e(+{Jp#G*MaS$P0T;jx`Wm{NU7ZsllSmV{F(WFvVaAaOM9YNih&5q#1_eiBi=*x6{`26~+`u6lqd z4-vKBkS-*=kAIZC1yh{Zs-;lDIeNt_b)ceNz&;&R)lMJn)dM!D z*?JBk1y%T@-pB^6E3eG6y+@UuVU$na^C2t2?I3MLLkZQ%26Jrw%doQm_m{7rL8EPilV!7$VeWanH?Cv8Mou$#XH8@pOn zEa?nJay@1~3>NHm_*afeCZgS`4M8_6&9G@qY8awW@fZ{t6>8W(5@Sz~PLO1t?bKBH zhonAy&f~rV(sjus{Xmjkd+l~85V1JhIBy!|gYWgGjjx>`8>`?hZZpV6mC*P@9+IWs z=qo=6$-1me`!>KoVh6apAe+PJlb4?$n}4nkt2boxdB9(50?FdJrXx;4vMllQp1U9! zOR#fzJ803KTb&5U+D*pT?!mD?7n_2Kl8~&7@%QPSkgHc!eb+beYl-83{*dgeuc)jR zB%4q?4NE-Ir=i_ z(fO18L8Ct4z2u<>TVVW;Q-ANIp&Ah)&yGecR^z6W1=8^^9|I}(oxxL|u87xxYE!-j z)ERh?u*YQwJjieC%ywb`Bh_U2(-OfabOgrqw?N604ACE z{A>dEZoB1v0e3hY%MAyMi0^DDY_PcbKD}KEWQbeU+5!5Fum@?PCmu0<0pL>Y{9ATV@B!7qcqBmc!`X=weBIr$8is@t zf9uxm0h8G%58ER-;>O8`Qa=&tgJX$j6~LU%EFw1~TQdANPXWosU8&=LgLy;+r$)#Y zBYMvBBV-exmDj7>kZiloCWQ2Y!s>6y*+$4Veu928 z0j`}R)YjR-F=Er1_vfN<{#$>Gk0L#->V=8N^@ArPsK360WEaX;=k7tW8O|pJF-R7p z__%xxbZus~D1u~++uBmjkc{DNqP#5RvIwwsS_2(jqvmrU*@W7c_$tx4GPqU0xH}G! z)v(KaR6vw*+$k)>APZ~3j5DHsDI3mqArwK0lVLK|hzH)M})P z3+x%bgJvvS5$8T4vFq0aa)?;iG6k6&%*1`$-mlRWeA~9p(Fa~Na{Vjx2}#uUkUs|F z%RbP50qe7NP0oO^8?TKyvhbD4a`^IDux=tSS0Cghw{W!tA3uJWYYVE~H#5Hnk|&2o zUk54H^`Bh=SF~o26GgE2OcUL<2Mq15OYFi2YgUOj#DldG^e;`o&M(RgOyI}ewQnl0 zv5!~Ro?3#{Asjy_!EX=0FD77+#qw7SqTu<0LfaxtN*@uWrU2@ar4AM&iRE)A?}&kk zOAOp8Nb1PW9HJ~E7NOleD~^aVurJ1=57EZ|)?}9i)nB+*y$QzC?0mnwA7mTkdh+BU zWa|=*iqwZ}Qa8u@Wgr>dprZm8B)gwISGY;KdpbE^=!I;I_7tPJkS)yZxK|)9Xzb}X zL~g^eXBTLCW#O3hB+=P}4w8A!P@WnA7v1Q7W&(SZxSHN!X|9(dy;)s+QWpPA5XZA3<8RRzFN4$w@{5LGz{(&wpehImt zLbDk8-T$F#A?Ezx=OD5FkF?G@7WLN?I;}qAQmWjR)DDVpHfWy7#s`F$JNkh}Nkuh% zU|8kL-@G~Kkh1ZODY)KlRuT+8{l&pp2)?S$_UZ*K<*w5F1*zXqz1;wJZjS40fhte< zPA!46dVG4na&Z3J$X}bR#SaETj2Yj6`}W3D+Jj$ZQ@7>7tFCk>w{hU>|AqGEf@E@< zXK#V3?t9~?!L{RFQt8<6VEUGxG8oJlF4>8JBD^+v%s}xswAv$>e1*-I+6-hDY7Xo~ zA~jAQ*$J6A|8IX$8UKXH4pdBvuz)ut)`cG{iEVUP#8}X7K6{ z=ofZz^(!R%^wmMlopiV4PK>z-$?7d6r)eQq>{%Wq(xaDQyYl-mNLF^0n@0z3skt1; zq=#FTDFasK2{E|jZT z+9Qc?2a1Gt>sTUMa-kZJVnja4`r{up=v)?B zloW+Z9(i34f@}uIc1buvwvVc3PFg^=?|NR!8j#JwrqJpPWGf6_iDrXi!A8% z-a;>2BfdIex&JFvA1Ood^>Y0`5h*mG7!6Ggam@E4j!N(Nku~p zECFS-55BWOVlLl0gxL^fkhafk8K~nQ5N&~oGey;ZQX=}1NL#%W@W$ED2t`!%pWzL@ zE^sVg-}!bP5#L%Z`&k#zWnoFjt;gt`^_xT2BDk07;(+B>{KLXGy1!lEaNw7has@am zCI?T&fW}k;&t^gDq6G?xLVVM)%65AUnz7bpq=9ELnhkz{uR}a;ErTAZ>Sa_#xMEi6 z-(dm6f5us|5V05)59%lVL4jxODCsYXYlmfafjpLBb{|3Jzgkw$K;E_4?z7N5B(dbe|G1 zFrSgxERhL|6cP8n=ZK`FM7s1hqB>~$w^tq9Pn&!%6;Vbv4&;%6eu)|L+N7u%-{>SD z`n1lUEK{grZ^+63=PTTf8)CWlL$+PxtNt4x&&T83laOuu)#Gn%kj>fF%%u>nIZzZz zk?x+X_rDWoJt3R8tWJm}WGgKxJ9rV2h3%2_JqF3DxyoDqgJe6)&8G&ys4BUZFOcm; zagLiGBs*;Gv_bmH*7rPD_7o)B%eQu(43b%U8M2ce>+fV57DPg}$rE)auEDWgMgERQ z;nw~t-Q?e(#Tt<(Hyx7o8NUB)1IfDcVv~+zq5+m{?{UyuH}n>1(p&qz#q=>by&~J( zek37a@8VVtw%lcJw?k4l9otJu7c5=Z0@fyQ-ncC836i~++Ohi}BA*MlSt|o2cZcl1 zhDu(O`!%kE3B+`PydZS9vGb!GFS=#y)o38eb70{_od}$;T6iCo4lZB#k-%GwDlB(i z3IKWDtkErik0n|so zUyA`H9=C>(Ht@mkQSlNs6mZB|I06*Q=8+W!jULTPmtcUl;Cn;@_@Z<}zZL@)Nl6?~ zEX4VLL^_u-2MJIu=LPV9l%`vqo`@!M@2is&h|GF%W<(Jj8FvwmM5H?9Y}%xI!P~*? zm!hD`r63wdRB-j#Sys{mNZ|L=dqQ91d%_);O%KS{O*g#%I z$!@r1dhK^!6A_CsyAb;@NEXG#yMrW|X|kv>J0{sD+a1~s-sw(C3&(_im7cuQ!o(5v zg6?~fgj?mJbQ#zrlvGN(%MFCItsO;j`49Kk{s23Icdfc3(O1!An!<>D=5;=?6Lcbk z2{@t(@7360A{#oAvOFM=16G+*J-Uc4d5aW}_kl_j`X6qgb4qrBOH&|y@K?)QWq3UA z)-mV-JGzpeDVO8X?5VHxJJ5B9-~MeduJM(VS_L{ERXG#@)}E!ws0O)y&<@RmS@$SH z87gtQRwfd&_^~*{Z!dicRN{FcCjuVV5a{Iv8~)75?FHkzTN20ci}`8As(GMIVz4t2 zbP_iYmH|8Y2YUYCz@I6mGNZt73e9^`qzx5h+qPn(AAcn?n1kWZJ3mfhkn4?3@pnLF zWn!n~FeXjo%x}{M3)L={6eEeSjLD0Kz?W3TRj!C?l;O{#9z-|#+AdKDe8a%*{}j(nfwa(p;R6!Lj``BEblg|Go<-z~n;I3#9nY0eZTwjj(gA1H*uSMn% zoZ}@*{~Bn4Y+}T_Y^9LRQJhaR4YKV^F?<{j*{aUuxRGw3wNgsAZa}svg*0XrNcPWz z;C&2|@!itM-UG>ucy|Ykf?t>>=t?15&|HI9BxEZ(!n0}v$J8k{brj&3srV%|dN?NH zJ=!-25>kc^J&oIN=vh`#+)yBhTFRh;v{WcD&s+RB)e zt?kuwGSX>lGwD(QK6<=HutPGT@+l4cNbFO#)@Cob$()kwizI(VdVH5c!dFDLHb=oy zi}Ed8XNdB=8GP2K(9N~H<`z;{6^vKk-$i#Kf>nn9p<8E9CZ%vNN-Qpm8!p^Z5d512 zF0ZB#4p!mxwB6Vd47zL%-&+Tn6m1p^s_{Ir`Frgn*u}_7xdt|V)6bQt!LuL}UzQc9 zX#JofxQ2+wXM;Pn>G;9vQ${(3U|^hNNC_BW6YZ1>W-151P5}R-(-m_CSKe*9>wqTq zB7Iz7{sD%NejLELMVBHN^sjLamjQDmjNbNRLu4bRQIEjv;+yTez;W%J`92sx=3HRP zULqC(!ntH_m{5~ThkG8AYlMgz8-j5|Wz@w;r0ea%b9RubNMJwdl6?1$$Z{DXJg_Y3 zK@Hx!vb3d*h$Y@8CWIk!2DZZ=T2aNe8=uZTkUmAc^DIeLIzB49cX;{4I+J4s*IIvx zhY`&o8}$X+SUt#g{_fSn3y|%gV9&TTWD^WFpgj)RBs(*YvO>21D2EP`Lo%j%so$jA z=U3@x&srgy59exiE@YFCtuBs)Y+H#FSD!$({0&bZ9Z0tS=%Gs@a7t-f^0;BmzNtP%MLl*r3uNtM;-q_dU6>YX`~nfX@zL#(=fr!5zR-om`G3g zU6d#$)oz=$SO8z1_8HGa0yN=24p<`*<%v$_BmAr^xm!<7YB9wyEoXug0XS0GV_pUs9hmCF-QA7xV zL~Fm4yB{!#7|nT09xyXGbtV9ln)j0HFC&5LRyA-_&KH7}DKOt`zwU*|^Ufw@HRV^za^DR%s6Rs1IDN>*}? zNm&OI73Wz*b6`RZinn(MK)%qv@2@erHr1m7QzX)79;I{u2^|v>wCn_n67=}}ksSZA z65De~G`QYcaEXY;eZiy?ZxMOJwR&l7RM6A@ooo{f%OGP(LPvtM8mmg^ZcEZ^|1j99 zZJq3Zj@xP+*Y?5%w+I&LFfd9{!k49<^qPH+HVCwP_w?_M2E3RE;WoboW*@eEUkWmC z8S&9H669asy{bXf!s3EKc(Dgq^+E91N3c$};d&it8F|yJ3p6DR9q$I`%(Q>kgFdn4 zU7x{L%9gYK;LB%Ljz*yD%fuNjki(>sq7w%acu*zb20qH!T0I0>4l0xvU}Lr6@{|`q z=Ckrd+%Nj6i=cdk+U-(I#>$u>C|G=}HGJ|~Dx$th*WNOO=+z{iH!*@oBD}-Tp&FHe0Momu zO0t63WEzI<{w69k%Vyx^v+&cGGLX$_!QNXEvZ>Jd7oCP|at0rnPe3-Q)0Xahkj)@x z;~zU@%YJ&(fb@Mp`J2P*ZP4$@jxV#2uI6g1Z!ct9aM?jex_e5{l8I*E!gfA;csK;E z<N($Yb)GsK-mli;-wo2(MZHdF9sIv5)rmEf?v zj-5v&9T7Zdz7Q^?aB|nsEE&IsLe%qdl4KsYY=h_G#(g_C;h&w?zBV+c+xDa<1v`jNx66!yz}W5a}72yFYvI; z1dN;Xc{1IE^Iw8psQ5m1dO+kO-83e6L+vwb0=~PH@%@GBB5vTKN0L86A7$BRyagVH+Ow-7ns@tHm0sDMDO zm0N~tn)$o0Pm=EcY5Yv8)L`|2-O)nmP&w{gQ1mC;+!jFJIG-YZV%ZM{QuG1fo$p9J1^)%wjCl5 zPZHpo--_|)Q*ce8|3ndygCv{al*~>@7P?`@GX@5%<`~pKHYS2nPcmdnn7^pX} z6jVyOHfe>bOg`23F`&Z?&X@PUfcc(D^E&8Q+~G&iESQ};a?J%!aOz2z?`^~9%cXnx zfJah&%XYTo6|5HX{(InP6fw}T35%>|`jdw`@FbLV)AK4$6p2yeVIEPH_ z1uVe~GQUq`U?}koO^rWxcAERtIvsdjC#uH>JD=uKoY}x6f#<&F+ypE3zRIk|q*@N= zuW*CpKR(ggAqkdB2aOUW#RAzihqw#+)DQ}C`dU4?X?J~2l9BR#S`?r#4B=~!ynw#OlzLa8bF zPe`|+*IeHM=e{(np06mu`ENhrZIA`oOec*N;~?AJgw8E5$QB_Oe)B$L+a<}wqyyQS z=60@&VM7;I-cvARgAPrm$L7JnOKZB{v2le;Wsd|5qHbjO=^-YYYOw26!ldUWg_h}% zKw;!lwmy(At@V5ok~u-{=ws1<^Z&#P{(t<4PS)~w;5hi|li2MfL|f!Q<79-W8Krcq z=uyEt8$G^iu&`+Ujy)<;E9_J}gvzGF9AxXkg6!b3`{ATR}M+E@{SY{6Y+E z(Rpx5Uu@$JxZCGqqZ4StKXk?otkCf=ehl&|Zw48I8B|m87<8v#`Uvo4Ml0!Dmk4TG5zb(Y2>#2T0GZ zu3(A@vtrbEaxrnTeAe&(z!TPk^cqOS|M)CfFcRABK7ODH$?fUoD5C&{r5`CvBGFfO z+t+R(;lm?$1p^`Ja~44&cMiIU`n!Xr6Ww(65Y!jYneZ^J z9e&O1C7*{^sP;ueq_5fJUo=xRAlsR!^tvmMtzYSv*j32(jzg?RAF@@bFem6kwoFl> z$9lN1_4t_*wBcG-SNFOaT$?f@@;EC&wzan7UnC*hTCQ_|AY{utdiBo%$aeYGaPeM9 zMo70C`v+Q-^gzZVxva*)6|cRLR^B+^6t-g8(D5k*?-z9mWKd_#z>6J%!Z@(o9%vBE4g zR}gWL?&!Pyh(6`C*p+HQ~t^9OFg2`2>|$0d+!S%Jr;2j_p^fMwY>7Te_odmr}V9|$5Sih99>i_%}t^x-wz z(^Ya;kb28*xDecJF8+N2{Nb~7e^)>5mi}`^G+@t_%ErCm9k=M;|M2HVa?UO-pmuWv zQyl2Y&_FN(o3C+}Q-MFy#>6vwasFS7ArvZxy*wobX(88u1fk2$Lt`+>$V8Zkt6bZwPsSKAm_nP_Z(2ky&E^(g;9~niwx~y(5mo4 zcn~T)#qh9O2GuUaJ$*a^R>mfVxTE```egQlaD}dJo>=<{i@KClG3lSU!tD#5$OqX< zxo!v!;4VdwR0;z5dqvd7LGI1(_CkZ$&;tLC>tI{!K1)x~j-2voG}w8~S27k%8YlbZ z3u>#}8n*_859)WwfV8(f3^wsO+9Qi+K7#-05j{_8V{u=uo?{9JetC?k;vqV09ZD52X0rik-7}@8CTR2BdI&@x?^GDUZ(gW75I47uSw}J?BjVZXVisy>|Sukqg%3Pkfhlg<=cix){uBPmd*)L|0EOjh(`430bi-IQHhrO z#j$VbNNK9?QXe`?^UiYmjSjt1%afPUsn~mlr5)f}C0+DxbROZV&H1euZ$KS37`jT} zjL@OD(Nf$KcBZ8Mg>)C5-#JS9o{&2sLG~Y9TX1bULxitQQMmKkMXCZRt3k>^hQAIG3 zWBoX)39hq=8v#}SB=$$3y026n4l1bhsgED|KTvE^i3 z*?!Ju=zrhW+bn?{Pu2E49LD$j4>tFHf$9?!d(V&He*XTTO9VLA)n4=iG(W$(gW?yi z7j-;+JRn0Ri|BDs>xtPZUhs-n`MKTT`56zgUi|%>TiwUvK-PoeAzDN%Ol$0Tmv8{b zx8CKxpvnnh6J{{Lin2EZ8@VW~z)S(&%ak6r!A67sNd8xk366eGk>CM6C>HteVzP$+ zzC8MjiK#k;vi>3gvXQ2n$G|7X<}^nKE=t&46?HSfHs zkFJ^c*moPCd*vK!8nSXot#V42p#pb1YD&W4O1uy7KhYuz>C|h#4=cbq$E{z)+m|3+ zP>QOCKBN;Jc6Tv{bn3m0qjwu}tGVy5c2Pan;Peq_Im)=4ObyS$hdx>KkOc>$XosNq4 z6Lpz5b>YC&nIC4W;IVMO=V6fL(EYV3{!tuwqQBx3$RZ`ibz%&!;eHTlV!;aWxQqz3Ge2LL{Bon>&!Y4jRc7*mkEg7Oy ze^+i!ic;TeJ&F|VszP(7BcgURN=Q>i^m-IKUs0iwnT)4VP2d>|$3lNprO#;3egV~G z%w%Shq0;8eFbiT177k{M9XHUqYVfi)4WwY@Q0n{)@)re7X->e_s++~Xz$zVDF`G&J z4-0KM=qJE0eR`bQQ+Ou4bk;BpJbjaRVjlcjv2A>y2aJ3`JMB77|&Y zdi41rlJYVqj^7GKbl%j)CZs42(N?dPAlmp(KLeT(`9LVoy?#_cxRv;G43%)%w{p#( zqLF?P%Q;jQGCTfn4i&Pb=+DohQ^N09pDA?gw>3REg3ho1q&n3L2PQwozi5UNv%{b7 z>(t^pGRY}-_Zu!`L|3JW7j<~_q8l)c{f>X(Xd;Gwf^_Qto<6LCbPP9Jr++}YzDC-~ z2}q~mCa%2#>5N5V87Lsz1+IEpdVKI5k-NeNa3E^#BbN{3z-J2`^aZdHCyB3zPGDoc z9Sgp~*k~l(_}vrOc(prCf&c~~&XyLf9KvL07A~l=W75o+yEmvYxs+BZ`zCnu-+h@$ zB%=D15Z!`=!V;$`a*>#sf#20|L`b>ZYWV<>{u@2Wa{&>X-x|5iiRjM^r%F$Q1>IL) z=b{ob->B4QsOamFtB*++o-elfhd0J?{xjDLSLUG8rp+N`D|F2h$ZK){4jg}a_;xKQ zHnn>3E@aVvOnskf8W)^t=Hl0&dgOcw{|ugfi{)Drz!biM>y)#w`t7=?F{rq>?j8eX zzA+T90EHs{G_`^B;;xnr;7b#m*O{|8|5e`XvUJ7|zWrd|Apxeyo+$f?5BzpJpW`7& zCiB;66$i}Nvb=B~9KX`o+>H&j*CnfxY*rX~)b5RqUTwB`+=>A-=Qa+~gItm~-l$@* zlDqs>4w#s8*MGuENZ@Q@>9cAi;`VAq;ujGSt(<8Y*g$kLy6%ItV83B~95*6;IU(>+ z5E1VZqyBUnk;}?7zmh}+gQoAElAf0PoNvF7LPZvQ@^fOS?plE6vE_bdFK?yLUsnW^&pp9LL}bM$Nnbi=9JeofVx#kpMnrud?EFzZPpdB`>B`{` z^uc6K0(#dyG3mhV3RV|PZs@h`_y|b^AC9?ffn>-FaJBk~F{)uuwvRrF%KGAn3(?b9&~-iDla4Ok z^_Ix*pkrmqsZefopV;o`)kfkqeN|Vu5xLEl$NvX66|X?rT9BEzf68bMr;)Fh;VXO_s!#r%h{jw3Lx=<@>OF{#i`fQ474KlJJ(#mq9BRm5htkM zvfb5^N_JDLPk z$H@18ZNrY|C4fnX7c^EJ(?J#Nk#&ECNRBOU z*pU&@75~tKjE6?XDR`9FciC`rR^o_3R_iYT=AdnF2fq_q4 zOD5{XAqujgU0Iok#%SZWWHF-345hkRgXk2u8)EAb<>;YPa*c>~Snf$oJ)(Z^`(m>O z(LavhNG?ScHC!X#b5YHWGOgrPR3(SU;8;{w_u1_b={>->`)g)LlAL_P2DeakUCU)E zEyyXpK~z_ff(+ze+K=!;j$03OiuXVkuds154@kFWzM+`{>C!`wKlp|#o}mIm{$xA; z9X~>YjS|xBF*JQ~6w*nuzL-^lboW!=C|!ee&)yucCq2r2I2v;=9G`2JKEv@5$2q9- z{dzSHtT+}a)Q63HCyE|5p2N-@d+)UEB<+}=|1JY2puPWYH!mjoq@rnm0uzeHX!=TE z;{Fv`7I`EP+Ez56ghc*H%Dg|1gpz2BPbwoZj*Ov`@<>qg1HUop=Jc=NqqzVQ{<`^#Gt260}HKA1JNQsWG z7qT~h2cKOV{_F(@G8~Uf%fpR(n%T_r;C~#mQm>ZqfFj1}e|8xUtykKrJHTh%ehG#v zxGgJ?+0}!T#Qf<)t8k%qqQPVp=YL*mGvO(I@cYn93J0*e({1r8D6du2e*nz=B~4$0 zU+hVjV>19N|5iD6;e&OPyWrS*vK9Zt(zj?aVh7s7TD-$Penv1 zHh!woJSZOnN!Yg?{eb}&qmQ4Sox}Ox(zIf`jRaIqxzVX~-xtBQoAP zxppSf`RbXthaQne7OslyL&QZBe?!R-`Mg?=-9Jsj9XpRIAvecEb%-kF33Xd4~u)jbF8!YQO=@Ch~PrNYT+%cAo{3ywj*@ zTZKH2Z+M3hA>DLFnev+sd@zl}Ino=F`8zZ2zklFTTJva|x*MOvcl(_%r1NiCzo&`c zW9U74@jj$uAa^YhaWpBv(3lQ;_pD|Twx zSu3|F#qi1_9G3lyfVxA+U%M;+aTK+A&bE)y?uVy8gKwui%L8D~?UKNWqE5U8Z{fKz+vG z;`eYScB1&G-Wnu3E@!w7j(tyf9K4Q~PySQKSvGLHAG#C%9854L{&8%@VvTZ@uwxVV z`2&ky`@r{|vn7l8dA-oXks^@4y14od=w{6rwT=%G5Tf$62R%$~#`WU>`TED*L_xL$ zmrzG+K&HWWAR8N^<8$Wug^gjgW*KWyzE=k{M&pqBBHP!GVgER}fwOi3Q_}h*G8P(228%R)S&1K?G4hb^YLU z5Yd04Q@u-tDx7sR9hXs&fKXfAAS&}O7Id#gg?kv1t20okQ{Z|=2r4Fe`}OHQM(3VS zl{@rdr>Sd?oHSf;8x(%a0XLc$C=aYd8j5oPAG;w@wm_haHKa2cz2^|pg^e`m9Q+FT z?Bzv|4EEr?ezNF`|N3wVuY7Y#0DpgHMem_Y`27h*W_4Rg=ewz!5Q5KTIw(t@GlcWs z&a)$+0|#cGy|L#XHbPN!>^1{-SV>@v62XoKn(W-vFu_tt_#O*P^kBh&$_3Kpd405u zz@!>9J2uiVIU}`SNGXyC%1+yAK{Awqi{wK{>T-&@`3#b)O@yEK z*X?U3#z9E3QbfrnvXhZSk`WbI8A-`V)>~Pn^1GhjU)On0=REiKdtIMr-OqizMiwn@ zACT3!CC}?NWXC9Pmt2HQhty~dB9XBn#g0@fWL_da;2;bZu6@aT^$mJ!r?Fr$SeaGZ z%ya-tUrY?D82{n;Ff+to2Yto)#QfM6uBd8zNqr=|V3T~ZO@+)*%llxZUoe#O3z=X# z)JMedasu?+-Dj?L(5ofYKJ?Ihowe!=eD9)klsOAD_g00tA2!^YQ*rYJ24wi;c!3=1 zFKs0xk3wiKO4VDVFxHng1O6!ZfGz9r4Kxt?zhyYtbpiz`2C z9vt{cpI~<%j+~CP6(SCyCvA*hT?3qV1{jMj!$RKG#U1BiXIxK(w zMB$+@B6!5V--5Vh+q~8t@*PoSB)`xdM08#2f71ArM(BC35Fk zA$!>lr*$RJSzz+)A}g4ZRmh-;V(h}ekZaHDkj_-AR>{lcvr^tT=yEuWl)&r#Jg%}J_D-u*! zh5-wOY@WVD0e7akzOA63oOdbm9H{i$^@mZ)s9a}ow%ZDw9M4c#4ghrOx{iY>=&)G2 z)Zr02{*}zOWgD)2Ob7!$oIgJz*PB*&2Y$g`^UvnICj(A zg*puuDka|A41=Xo=4`Ysuy~V}-tH*i{C=T9Ob*uHyb%@8f+*Nu%$KepqGDOYya7Z; zd(QWI^*jl;#lnV{ZW5VRFkSIL##dTriw+}m{+>-n5x}WCJ&5d7g`7MTTkr*i8K0fL zvK`Qsy||emjShPFUi6xxBW9am8Gk@0qNI|VhEBDdy%wLKa~(c!ND$IqExq! zK?AJ(C~=eB4whI~?x=P_Qr^Zc(1qNB3fn@8Eu;hRXI zBuaGb>RHtLADo!IW)(0BX9D;*MqA+2Xs(jh12{L#Xg3`TC;j(!ZeD=3dZJY2#A%%> z+Lm7maGv#@_a^26a@2yKeMK~7ul2aw5Y-52F)$+=*=0F5Sp*@=v^$9w7Ra`C>t?Yu zvi5p8XiEb){X}+!On`;EZ`&A&dHuzrV1Wd%@-ef&)*0;7YvsRJ1xuGyxnqerBu6W{ z-Jb#9XiK%yjtzI}{(v$LL1rB*Bj3scaWB+$fXctm}l?hiT&RN4+ zYZW(%%dpy~GhZzQ(A^P?I$4Pb9)IYSe1%B92HM$9Afh==1Fs*5jFa|lFFCRlsUK;h zN4C!4lCI3iy7j47CKDJScQRqhMu`@d{ZL4GE{&ORDWxXaSqz zyqNNKL#@yIHaO;>JpZ1oM(;4xa^zqc--43%tKZk4Gt@F(@HS9^9(MOSw1W5FP-n;n zK|6h-O-AuOdCAPi-O#^AZ0rWut|9l^k7oeu4O^9+UKp69U>xCxLSz%&&Adsdkh+#? zmkTPs`nGSv8XZXNzf)|0j+&Ft@azYi$A8kj;3D9p9iZ8Q1NSNp=}p3s@RydSo zR8*4($HI4;nnu9ErPKd4*~8I@txleUfU{?D@fru^nGe5{etPTT>x+0wf_1Z1Uc$0t(&UxTapgO`BsSc06?PrTn{ zM@8}x0CY#IpZFfb7thiElL^6wcG_#^Kg5Q=1!TT?kAZ3)Ochb0fPOpw{c?crn)ab{ z#2jy|aJA-j6w0ZY_~bDPpS?BnW&(|zk6F01106O~^cE|i<9(9X9qa&Ig4(^rYj8qk zqJ3W_oGGj&6$uT)s?YW6u3NB9NLp`}xR%?~>KA1Ui=$t8h zh~iVcZp;vIq`R2nv5KhX`&$(V=vrRcyGbHa?=aSoL&(_ft6b?xWS;cPecc%hl+k~n zxdVZ5~^AZ{5mSzs1${el0%Ywi9_mn-IBR$s8p|}vD6clQy!VWY>rNR$a+SV(AlYC zOLY#wDLb(5=PEiMy2z&94=2t&PBN*0GZ(o39FK)lj8Q9Ro#EU-Aw#h`oD8_NTaF!Y z7LZ9YEx~C=GCgbJYI^AU27AUD_WzmY_ZGzLl;YSMK0{=c8{!hei|od$nf!ksONT)X z#tvkA`eEvcd&s(?lu^?Y*=Ka`9M=I0rmuWt*uh33U8Tw#Sh0^C{r42?C^%P#Cx9iY ztJNzo)-XzYDedJXJNQjNyG?r31@ zF?%X;fpWs(w09dCJpI&`{0HFEKlws?51ep5cUkH%3DC79#x-4nMJlh?7PDd5y)mom zZdk~oQ%p%*(}}-p9pr=6Zl!}9MzEe|e`>uqpbM2ckdux`O5e^uevXJv`VG9DL1bCW zWX*Jlvi>HWz6_#ud=k3z1hUTdd6?^k?9X(hosI_!Z&-MbkO~0@(+NTP2EbCC7aZIU zcz9erEII*`@W-*zhFxIdt)tl;M*O$SW~U94p_UZGH4O@8L#?=(9XfVUO4?Bq73c+? z&snAT_npoj?qBfvYnR77H}L($*Pj}HVS60i9KB1}{=Xryk7F1wB8x;i*NOs|-{fr+ zqM{0^3+dNTVN+MZud}FFVBfA39duB@RQZw@9a)74cCDksH|#A#z36x*;WT409OxiB ze>)70=yD2Ov4lga2~q=6aO|+@ovLksv*cv;o)I|e@~2$591b5$pzMi&}95wzDg{s*kltu&|N2Xyyu_~;*nb@GPMCRbqP(${y~4`6ML+t!1A zSnVRT`h5%5w<+EIDS=25e_k!L#Bn3_M;OIbMCGIT-=8u>Hx=J;Z5UB9kT{Yk5OMC_ z`b`N$9=H@%U`}sH(waA(I2jBmTK>5<<^qxvF$Tvw0L@I1ne-eWVv>@qrUqPOtqMsz zEZ9)=g)>5|hFWtxCDl9F46z8^UidjQkaD_X463-wuuTp+W|w>UAU^k9{Pl(uz9-*u zhm#fCk)EnIS;2OBn!nP&+lBLgxc%LmB^WrJi6$`;h1efG=XDx%?yKGilt-n!w-raW zqw>!dab*+eHqqA4E4`6b z#t-(oLFBP*E=S>7X)(49rLD=yxz>yhl?CdZ5{)Cuq7mBzb;|aEy+*nB@O~Cf{m_+d|z!#mE`12(G+nTwr;Tk>= z5I<#8k1w?UY3=`t4d~lk6y^f$e3|3Nj4;5JCML5$40yYOTBaBUlsY~6GK_+-n$VjT zdr!cC@%sZPnCpTt`*}2w9$YDviiWN&&GELO!P=s?q?w=SxFzvaj3D;Ugy?vR6L4ht z;u#APEb7}k5LO1uRAMG0$6%q7@AWg=0p0JWHueLsI8EnvzB4R$?f@Rdzv%Q%a1p23ttKvgM0l3IzQG5PX8n~^$U?;ScS+pQ-N@X#D5P>743y8C zRto`+7s7WEj^Rj_%Wj|(1ZYkN+rKRYM03pJ`}+XZncIz?e*xL6`rnaa9AH4{wvQR7 zp;l!}lyWE+t|cXE{fPhOYr7gx{QFqd&j{l4mzn7-i0@}m_iTHB?In>)brXpJ6a~E3 zi2-+nSs&bs0>r;i*lnO7BPXBJuTfwlN7;dFRD6lOe%TitZ1YQtG(bnOhs@Tv(c#SAi-B)4x6`z@p7Kp&{#)%$LM6#UNpYaP3X@q+lbR#o5d)b~0WLPE2rr?20g@*U~ zYa-*H?#?NU$lP>%_~vIYKr4LB{SlbBrs^k1O!2;EDX29AGvNh$#P))rFO$>$xE&{H z^*!6leF?~3iFlXZ26P|kHE%fs!k$4!mDhN``c(e#AHe7SgWp67Uz|zPPq)Q}{sz5$ z5|0g6Y`RuF!$2XCErE*|c;|j!PF@spR*vZgadSJ@%l9q_g)&RCe0zw(3(g%G96=-3 zW!RHxH%U137G?7tK&KBC{{){!=UD>;=x6T9Wp4AQ? zI}9snT%9fkz}j-oYe(~8^#$qpgH@bpK$zlh?*;!`tmMC0-B!%hoCb%SN%Vi=-x zm=1IWGiGl*t>R&`|je-=mwm(M}q`hS1 zq_5`@O{!h3xGJLBtyQi;k0WMLn5)=FWJzn%Ia`5jAAgSz2}jnk?q|Q5BK!UOr=^Jp zn4|j1#;ah%sd-YX9jsiK)ZBFk?CkwUqNyWhFrS7dDk}r7>Q%wpv^Zo2I?!|t1HP9& zL8C>0a_ekWlPvyy?b>9U13o`=p80MPHbB#)r}`Wl^uBbqU>O6%mZ^^J!GLB|Ztstx zfLc0_d%-BEIX7u<2?~76{l$xbFQ!%@lm-n*k(6l;E25*T>tXL4(V^bQQ%p(d_@7@d z)iXFyIUV$H4vzE%YyM_~Lo4MR%i3_P>icZ?MOdix=)l7?SlWJY%(fL4V?Rw=gypYH zx#c+!0i!&fycQyn31bd)K}79J&9jM!jND7xx)u?V6oxc1#*pa`8eY#WoOZd&`YsC~ z^OcJG>e^u7$Wk%A9hmqq!Ti}DjFe9(O2mShQ;$8}Qvgwc`~3^I0hRjv-wF~SOS#i7 zXawlAJHP)Ogt|5JuKkAQ2Ht<33B9Bzw`(1rlSrcWkmtnt->uO;`y@f7$Z;WOY%p9` zUepl-aNHrkV}St$B)>Okqkzrv3)NyM=qO$3G#v_LGFjGMK*1`EDjr>E;7F$Sr$Th3 zm>#(pjt+YaFASbS$5;l@p#TR?n}407ha(1jGFDS?NT=zh_)}_}|4GWHyl%q6nMwyW z;!yc8x-<14EUvT2jAMf3#XdU1Gl+n7x#@fZBDpHD-6jDMiT_X_Cn7suo^ghVFzysN zi58j0a^#;LL&kwGZT^-a^Jj0fox;Gt=uG}i0?LkK=GO@*mkv4~St9|OkZkJ@9f0U$ zO`>W#pmGjVcX0z`J(sVXQv-BVAv#L*fKpFBaQFkDWW9AjKN6qw$*9z>#`hk0F>Mlu z+$~W-FX9kvQ0bnjfq}L?m%e%d1NX{W@4kyd_P7T+b)c|N{|d_$9Ma9j?)@b3qw;%g z`umTf6K8dXoq_0VbLL7|J~|z@7LDjZ=gYCtJAUIzhP|_V*Iqb7?Z6m)6i)R$;&$+d za{^yF<1+!@jzc^Dw87d>u^hJ-aHV8)^@J)jtZy^pd!vLXYBu?WY!Hoe{}?TC$#+;U zjHI4{>~3f~dk{Ao9`}=Ehj5@7&pWfegp6zd-lwKS_AacaY+1p=l_15GJzyinK)IYB ztXP{{G;n~OvQA&qEoiy;V0ACx`uZmLY&c*O&5ylL&W+pf^Jb<8p)}=6vV2h8w>?Yc z`1e>3k{TleUK|rk_qMOpMLAPOq{ zwQ=?hU|dX=TWCU|eCcPBOHg>`FAD41XvE?06xkIt7OCyYV~bAr=L+&@pmR}DkR>mi zC^%-$vI!VFNg_ef?_t$hX`1mzu+IN^w`x4BJZin~**RD%{?IE}6IN^bPsVY;`g6CV zww4e@DdqFYHbnE~cE1ksENIX}bDs~Qd;ORp*8owTeaiHR2hnyKbD#N+ta+|-*ZlvI z%fPsrc;r+3Ufk;CrqGSi)p|hgbj)m*JJd8Nj5>%`Q(oF1LF$7J37){Z8PG zBTl<-27aEF0hA8rhklX)$_E~j+3ol|;~nAME4V04;CQMbfbBgl+MqVU09|E)p2VE; zmWs7+A>gwx=40qXK{167mHuwx{QvYW`a4FqEXJi(?oF8-r8OlWF*~cT(0=m%y z8OS(2@FYKR?Z}q=~E&-BgXP?Z& zfabmXfe1c8^sg(Fnt;mBo=dh9kiA&9*_Ht)Ihw^IJppC04_&Pep#0h>o52PseYfu~ zT?fQYKMLi9upQ%%Cv;7)-R3*AA1`B^te-#Db1|^JwNLD86r#vRqKaR|Zt^gF?;0;E zP0Zwds)x!?cYW%)fKJLZxq5;Y1|k`DP(FV{E2s zpa-X(_1+N>)phH<`w~A11bCQRSINt z>AegGE3$eeV76Bf+4U}!Ge{y!sT&5ng4W2e8+oDDY%fYgrBo&T`G6s6+!Au`hV*(2(uO$e%hi$Q+d&R*i;B7NXrA?!@^& z>U)gceOOT*nllpzYdF=?{R3guyP*4?POz@J?7WaMtW>j_8PTC zKEG?hz~Zro?TZfJsSMpD=LSqF`>gYb)pDduN^jc% zB~8FwOa`E2wv!m~29(qN`(Ek;%KabjnGnnN_PX+0bKv`y!rLxsVSD2x1AknwecG0` z*(8jYBE%$FPXc^u0V7Qxv3tmPli#L9h4un}?~9}2d&_s<97PAoi7%ME(NROIsO2qm z*sHp9?J+ve5mUP{00&ylD|LSYLZ$=Vw;16Nqo#nFBphq?^s*%GdRP9t>|qB-{YH{( z{ot_m_KAsWaQras-h5IT4hWuX{}~k`6C2~*c9qD;R?XmKEiw~c;=56Y4EJmNk*!9i z?pjVJMaX#G=u<@sG8ZVmJRArHD&0AkOu@w5mzz0zz=~6G74s-`@rGbEaT-2wqDY1b zY+bK7?R6Cz`|4y*AC#wagjDkjFO;*XdVfL`FYzB)joPw)s%U;`=JUv%n1 z>GyIh5_F3$%Tml@z`Q79G70GOw$bnBP{_t4x6@q|M*sNH?lu&l z81ZN!!bQjDE&PZy_}4Q-GDN&i5_IhR2pX9fg)ADuK#;FEc{-Q~sLTA|2S_NRmsgJg zn&NAeHv0gP(!38VC7=?eER-3?5%LAwwwfA1nI}hE77r-NzMbPc3ny5%V!3KKF`G)y`5MlcSr&+X zfm2o%`7#@T(3)+0eFvPZ4RqGr4QHnYJ~fCD`~NkW%gpky-bGkrBOIm|A=}CR*MfM9PjJIcl1<^t7tutWc zmeUa{RxmSBV=VU=YQnc5q5-DlN_}k0q0U_k1!TK%{?Cz&8j{_OO#LO@)S&!zt1f$> z?M3$INAW=!Zyo_(=$+!d?915Dp3mq0SU}Im7FCyHpp2&#<9{*m?U3?EdeD>Xf{oEA zs7GMmb7ErBhTPHRCki*}dzQEdYAAEsOa~2JVe6o_C!xbj8$tY+&~dWw5wR#Zu+n|` zVImyic5#(S0gNlxe<`KHvivLsrCYF2Cn7sF4lqXcd)G$5+T&!JbC+OsaOl$IbFkiI zs;KLW-(XC%%y;0Rf* z*>^hyP;TsxWAg%(5n8)`8UadyTk=XmfU-f7Zgvwe&P5t!5Yv4wvwoyxJq*y!Ig)c8 z1A5pQKaD{FM+B(f7NMY72cM1(6xi?gHF+8p?~6FcML`_-s#LXk(UEL-=Asfh)U(m~ zXM&E+Mw?BD)2~p`Mol0bnF%tbii1PPw)N6vz_FK&f5M94V7^ZAdy;{}dMI z#Bp^u!*aPI-rvoLKu3Ig*Hc7t=kWfLM~F!1V$y0JGF$5Y{UrezlGLvx_#j)?#^f(Y zk#*hQ%h`O$el5e;a0V)Vri?oqY$&Q{?l1-`d2vVTrl9xPH(cGo(ocDcJtNRi6345% zQh-e)o3Gdz+UqrSF$ntn+R+71sNQqIY;EZ7%}W$N@CET{ovKKvwsz6xKWs2ViF5cI zRPRu5Q40oq*;8T30!^>h;Il&^dj#K)<)Xk(HADA^IU}7O&pq7GD9S^7j}VO*XI9?| zKxc9H)We9YU6!CYA)@obDzd(QIFWtm_VNszVRayzT_MgDZr(!wU>!q*C;c{Pbgkbu zN?6J#_sEeP78m`^3?}Yu%-5(gejp0*c{|EkL?e6X_>W;kC3asYqZ83_Uf9@QONsrz zM_FJp2M3n$*)P2}kTJ(|TR}f$F5u0!Myy=gE9U5;1tu76I+FK-ktI(3I2tfxy`1kl z2N)yNE7ZFHWBZPaTn~xUtfV>pbwJ6Q?7NqkbiRKs-9r~p8rA!)@dL`2V%6<`0Ase~ z?z#8G`oEvAG;DTa!#(e6?-37;qED>08DrqyCiQj~6!LQY^R-A6mi>!-B@>1A)oFjP z1BAU6zD_;pq^m++Vj7**)c6bkLZ{C&$Rz0CK&*M^uHAr7Yegeh49?{K_J1f3r~W7j z&#A#V(|^9~+9X)&yqxt(2NoBvn|;H|F|DHX`c73uFxMnTE{jP1`w&dckBICoJ}B-$ zW)i_v{fp2GAGfx3AUJ@9Yp`7kz z0XyH>75An>FU+t#B5ea)wIsy_YiQh;W4fu(@BErhwa{#x*Z%d;U*V%k_n>2s>8Kr` zY?Ff}G|-Yqw7n_V(701^-%eJ2un|owYtONwjf$TFIb+rnfcob5g6!cq<0_6B*UtWbnF80eEvFri>DE?G}cl+qKa&nd|f2OiL5L4%CjT;#Ic4bVv&h{ zpOMZy7zvSPis}b5WmXO68vrBI@?G+59MSBa|93tTP>MHml%EHbXPg_RjQ}O>zdw73 z=Zjy@=DW}V%C%JG-fw`>nUo~t_zH)}pYyN9AArg`w6-*J7~rXDn=~Z`+*6yhV-E_@ zE-;ED9>bf8$zLU=UWzQq793IVWK3ALKN`s2rAdlGM?UtfPHE_Hg}qR)5FNA9^(R)r z0pDqwfCf17(EM`db2zkjk8)cp93#2pOXs%2LXo_Wlf)6Qao47JJuD_2YGELr<*IG% zV!wwd9u)6yh(t8r9aeTOh>EMC`nVpV>+V->=SHT9qPyM`H>q5bjaN#L^|05$NM~e! zwaPM+2~3R4*BMqp?>pTc(grI>r)|AjxUv6x_|$Vr1E#>m#il6edzVh*cIX5DrMHXF zd%9B(e?z-Yb@t6eHLdmOTA;gIIR%I#rMC4b84vVOE7ko%Y}oYlzI%J1ho%~au3As1va;^3U5*EiLCIGML-ZdV6uWlI_k zx5MfXM;^U*us-;g{>@=Tk#zXF*9SzCH9EyVPC{0p&FLRTk=@SGpCg0FlKzOE@mpjo z%Cu$o5?OyJ|Daiq?8{hovpob0=Dal&cfm&3-yHE69H^{+GZ*=RnFIfor`rR{k^5a7 zMu2is@xF>2pzQnW#mWgNYgT)n{soM71*O`PfH6t)S}loKi*d^`QM?F;NE^2oMb|+k zS166P8=#cU{W<&y1I;B3MZdzpzQ*2FA5lo)*$9mvC`?jLmWdJtf4W+~owz0Ypv^`l zh=x{IZheqKhdVv(&K^L=H${JV5-X?FO0IV3z!6_&V>w+oaei$ zMciHmSo%VHVnqZN2T1HVzy`}3cUAlUgZj&~$xb2?Pj9bx&4_5hb-5}PkqsQ+WGAlw z7x`MnrI77^J9+F+r zOb9s2K!?q0B|J&L*~)J z$u5?${ZPd*?N67`nV!CG_+xbHa56c437zu|hEVKUf5bQ;Jgufa4? z7n!AO>2DCL*1RM%0}YYsrHU9GVrgZPXkfTDp!9G*??4|_UtS?qZOo=yQkDRqmT@d5@cQMxf7f&%7_`)yA^K`OQ# z#u+H^j{2ROMJU)XzNz*R8aPo9daD5qNj_ux(~JgpSxY~EfsU28U3vHd4mi@!k(wE> z|37$7yHyX17`Nmm%3)oPUsg{xtaPY5@1Fo`X$>tr17P*y`n|)aVEum=U2mu$5{Bo; z3z-nnpzE!zNvPRM_vW<5gCGLiM zqnJtei1|OdPsab)0nHTepi=}id92{z2dJtTEt?P^laOb+ZUH?OQDWl*&8OOky9|wv z^0|5*x=iaRpb0I=q@3Eq_gboK|9c1><*H-QfsTwni|HW7*?3Gw+yOC)FNqYPkeDx( zAtYM7@Y;1`FLBEhvAgm~H7cj9sjwu6Ca>$~9!5u#8!3~C=&;FwL--v!r;;Bx-wE}4 zcJH_W9NF&lW`lT$ZL8jXfH-HkdMHp0!$BIslyk&0rHh+iE($``Zg?NihSM7qL9?d- zV-Ajg4}6fti`ZR-QOM?~MIciOvWgqq!<~cd@{_Zdi;<0F1{)rgClq#u&lE*+?8A`$D-r`~l@1 z{?{hNjm@#$q@WygP`Tcv8mtW}c@8K3l*DP2cUfZ?h6GOpk%h;d^QUh6UBqA z-U3GD^9dWQC?FuUp+W!!<;2Nflth6J{c5`uQLyyxA6{x`fO^k{t0o!>iQf5E3k|l1 z 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 diff --git a/tests/test_evd.py b/tests/test_evd.py index f015930c..63a99913 100644 --- a/tests/test_evd.py +++ b/tests/test_evd.py @@ -7,44 +7,42 @@ from numpy.testing import assert_almost_equal from hazard.evd import gevfit, empfit +from scipy.stats import genextreme class TestEvd(unittest.TestCase): def setUp(self): - self.v = np.array([0., 0., 38.55, 41.12, 59.29, 61.75, 74.79]) + # self.v = np.array([0., 0., 38.55, 41.12, 59.29, 61.75, 74.79]) self.years = np.array([25.0, 50.0, 100.0, 250.0, 500.0, 2000.0]) - self.w0 = np.array([ 47.65027995, 66.40860811, 79.83843278, - 93.03113963, 100.67294472,111.81331626]) + self.v = genextreme.rvs(0.29781455, loc=28.64508831, scale=31.21743669, size=1000_000) + self.v = np.sort(self.v) self.loc0 = np.array([28.64508831]) self.scale0 = np.array([31.21743669]) self.shp0 = np.array([0.29781455]) + + self.params = np.array([28.64508831, 31.21743669, 0.29781455]) + self.w0 = np.array([ + 47.65027995, 66.40860811, 79.83843278, + 93.03113963, 100.67294472, 111.81331626 + ]) + self.missingValue = np.array(-9999.0) def testEVD(self): """Testing extreme value distribution""" - w, loc, scale, shp = gevfit(self.v, - self.years, - nodata=-9999, - minrecords=3, - yrspersim=10) - - assert_almost_equal(w, self.w0, decimal=5) - assert_almost_equal(loc, self.loc0, decimal=5) - assert_almost_equal(scale, self.scale0, decimal=5) - assert_almost_equal(shp, self.shp0, decimal=5) - - w2, loc2, scale2, shp2 = gevfit(self.v, - self.years, - nodata=-9999, - minrecords=50, - yrspersim=10) - - assert_almost_equal(w2, np.ones(6) * self.missingValue, decimal=5) - assert_almost_equal(loc2, self.missingValue, decimal=5) - assert_almost_equal(scale2, self.missingValue, decimal=5) - assert_almost_equal(shp2, self.missingValue, decimal=5) + w, loc, scale, shp = gevfit( + self.v, + self.years, + nodata=-9999, + minrecords=3, + yrspersim=10 + ) + + assert np.allclose(self.params, np.array([loc, scale, shp]), rtol=0.02) + assert np.allclose(w, self.w0, rtol=0.05) + class TestEmpiricalFit(unittest.TestCase): diff --git a/tests/test_files.py b/tests/test_files.py index cbbbf26d..2876630d 100644 --- a/tests/test_files.py +++ b/tests/test_files.py @@ -4,6 +4,7 @@ import numpy as np from numpy.testing import assert_almost_equal from Utilities import files +from pathlib import Path TEST_DIR = os.path.dirname(os.path.abspath(inspect.getsourcefile(lambda _: None))) @@ -13,6 +14,7 @@ class TestModuleUtilities(unittest.TestCase): def setUp(self): self.filename = os.path.abspath(inspect.getsourcefile(lambda _:None)) self.path, self.fname = os.path.split(self.filename) + self.path = str(Path(self.path).resolve()) self.base, self.ext = os.path.splitext(self.fname) #self.path = self.path.replace(os.path.sep, '/') diff --git a/tests/test_generateStats.py b/tests/test_generateStats.py index 4d35d7f0..84066448 100644 --- a/tests/test_generateStats.py +++ b/tests/test_generateStats.py @@ -26,12 +26,12 @@ import os, sys import unittest import pickle -from . import NumpyTestCase +from tests import NumpyTestCase import numpy try: from . import pathLocate except: - from unittests import pathLocate + from tests import pathLocate # Add parent folder to python path unittest_dir = pathLocate.getUnitTestDirectory() @@ -75,13 +75,13 @@ def test_generateStats(self): self.numpyAssertAlmostEqual(coeffs_sig_sample, coeffs_sig_test) coeffs_alpha_sample = wP.coeffs.alpha[0:10] - coeffs_alpha_test = numpy.array([0.51818004, 0.55450803, 0.66634809, 0.61266186, 0.61266186, - 0.63192755, 0.70984709, 0.64836016, 0.69168147, 0.70101634]) + coeffs_alpha_test = numpy.array([0.51389973, 0.55107082, 0.65703153, 0.60663585, 0.60663585, + 0.62594031, 0.70423342, 0.64339172, 0.6870522 , 0.69641318]) self.numpyAssertAlmostEqual(coeffs_alpha_sample, coeffs_alpha_test) coeffs_phi_sample = wP.coeffs.phi[0:10] - coeffs_phi_test = numpy.array([0.85527156, 0.83217838, 0.74564081, 0.79034514, 0.79034514, - 0.77502747, 0.70435581, 0.76133376, 0.7222027 , 0.71314521]) + coeffs_phi_test = numpy.array([0.85785026, 0.83445848, 0.7538631 , 0.79497984, 0.79497984, + 0.77987097, 0.70996851, 0.76553713, 0.72660806, 0.71764105]) self.numpyAssertAlmostEqual(coeffs_phi_sample, coeffs_phi_test) coeffs_min_sample = wP.coeffs.min[0:20] diff --git a/tests/test_grid.py b/tests/test_grid.py index 21032419..7a3b651f 100644 --- a/tests/test_grid.py +++ b/tests/test_grid.py @@ -28,12 +28,12 @@ import os, sys, pdb import unittest import pickle -from . import NumpyTestCase +from tests import NumpyTestCase import numpy try: from . import pathLocate except: - from unittests import pathLocate + from tests import pathLocate # Add parent folder to python path unittest_dir = pathLocate.getUnitTestDirectory() diff --git a/tests/test_hazard__init__.py b/tests/test_hazard__init__.py index 3bb9b353..701a0e86 100644 --- a/tests/test_hazard__init__.py +++ b/tests/test_hazard__init__.py @@ -11,7 +11,7 @@ import sys import unittest import pickle -from . import NumpyTestCase +from tests import NumpyTestCase import numpy # Add parent folder to python path diff --git a/tests/test_interp3d.py b/tests/test_interp3d.py index 8db3c54b..52e9052c 100644 --- a/tests/test_interp3d.py +++ b/tests/test_interp3d.py @@ -12,7 +12,7 @@ import sys import unittest import pickle -from . import NumpyTestCase +from tests import NumpyTestCase import numpy unittest_dir = os.path.dirname(os.path.realpath( __file__ )) diff --git a/tests/test_interpolate.py b/tests/test_interpolate.py new file mode 100644 index 00000000..5c526ffc --- /dev/null +++ b/tests/test_interpolate.py @@ -0,0 +1,31 @@ +""" +:mod:`test_interpolate` -- test suite for :class:`Evaluate.interpolateTracks` module +=================================================================== + +""" + +import os + +import sys +from os.path import join as pjoin +import unittest +from tests import NumpyTestCase +import numpy as np + +from datetime import datetime, timedelta + +from cftime import date2num as cfdate2num, num2date as cfnum2date +import matplotlib.dates as mdates + +from Evaluate import interpolateTracks + +class TestDateInterpolation(NumpyTestCase.NumpyTestCase): + + def setUp(self): + base = datetime(2000, 1, 1) + self.dates = np.array([base + timedelta(hours=i) for i in range(24)]) + self.absurddates = np.array([datetime(4500, 1, 1) + + timedelta(hours=i) for i in range(24)]) + +if __name__ == "__main__": + unittest.main() \ No newline at end of file diff --git a/tests/test_lmomentFit.py b/tests/test_lmomentFit.py index e6e03b30..e6d08238 100644 --- a/tests/test_lmomentFit.py +++ b/tests/test_lmomentFit.py @@ -34,7 +34,7 @@ import sys import unittest import pickle -from . import NumpyTestCase +from tests import NumpyTestCase import numpy # Add parent folder to python path diff --git a/tests/test_loadData.py b/tests/test_loadData.py index 94e5fa80..b75df550 100644 --- a/tests/test_loadData.py +++ b/tests/test_loadData.py @@ -6,11 +6,11 @@ import sys from datetime import datetime import pickle -from . import NumpyTestCase +from tests import NumpyTestCase try: from . import pathLocate except: - from unittests import pathLocate + from tests import pathLocate # Add parent folder to python path unittest_dir = pathLocate.getUnitTestDirectory() diff --git a/tests/test_maps.py b/tests/test_maps.py index 4a1edf11..d12b2c09 100644 --- a/tests/test_maps.py +++ b/tests/test_maps.py @@ -1,6 +1,6 @@ import unittest import numpy as np -from . import NumpyTestCase +from tests import NumpyTestCase from matplotlib.colors import LinearSegmentedColormap from PlotInterface import maps @@ -55,8 +55,8 @@ def assertColorMapEqual(self, actual, expected): self.assertEqual(actual.N, expected.N) self.assertEqual(actual.name, expected.name) for k in list(actual._segmentdata.keys()): - self.numpyAssertAlmostEqual(actual._segmentdata[k], - expected._segmentdata[k]) + self.numpyAssertAlmostEqual(np.array(actual._segmentdata[k]), + np.array(expected._segmentdata[k])) def setUp(self): import seaborn as sns diff --git a/tests/test_maputils.py b/tests/test_maputils.py index deaeb68e..5092aa0f 100644 --- a/tests/test_maputils.py +++ b/tests/test_maputils.py @@ -30,14 +30,14 @@ import os, sys from scipy import array, arange, pi -import numpy +import numpy as np import numpy.ma as ma import unittest -from . import NumpyTestCase +from tests import NumpyTestCase try: from . import pathLocate except: - from unittests import pathLocate + from tests import pathLocate # Add parent folder to python path unittest_dir = pathLocate.getUnitTestDirectory() @@ -46,33 +46,33 @@ from Utilities.files import flStartLog class TestMapUtils(NumpyTestCase.NumpyTestCase): - X = array([3, 5, 9, 11, 65]) - Y = array([4, 12, 40, 60, 72]) - Z = array([5, 13, 41, 61, 97]) - lat = arange(0, -21, -1, 'd') - lon = arange(130, 151, 1, 'd') - theta = arange(-2.*pi,2.*pi,pi/4, 'd') + X = np.array([3, 5, 9, 11, 65]) + Y = np.array([4, 12, 40, 60, 72]) + Z = np.array([5, 13, 41, 61, 97]) + lat = np.arange(0, -21, -1, 'd') + lon = np.arange(130, 151, 1, 'd') + theta = np.arange(-2.*np.pi, 2.*np.pi, np.pi/4, 'd') findpts = [ 131.5, 135, 140., 140.9 ] indices = [ 1, 5, 10, 11] nearvals = [131.0, 135.0, 140.0, 141.0] - XN = array([-111.1251, -111.1251, -111.1251, -111.1251, -111.1251, - -111.1251, -111.1251, -111.1251, -111.1251, -111.1251, -111.1251, - -111.1251, -111.1251, -111.1251, -111.1251, -111.1251, -111.1251, - -111.1251, -111.1251, -111.1251]) + XN = np.array([-111.1251, -111.1251, -111.1251, -111.1251, -111.1251, + -111.1251, -111.1251, -111.1251, -111.1251, -111.1251, -111.1251, + -111.1251, -111.1251, -111.1251, -111.1251, -111.1251, -111.1251, + -111.1251, -111.1251, -111.1251]) - YE = array([111.1082, 111.0574, 110.9728, 110.8544, 110.7022, 110.5164, - 110.2968, 110.0437, 109.7570, 109.4369, 109.0834, 108.6968, 108.2770, - 107.8242, 107.3386, 106.8203, 106.2695, 105.6863, 105.0709, 104.4234]) + YE = np.array([111.1082, 111.0574, 110.9728, 110.8544, 110.7022, 110.5164, + 110.2968, 110.0437, 109.7570, 109.4369, 109.0834, 108.6968, 108.2770, + 107.8242, 107.3386, 106.8203, 106.2695, 105.6863, 105.0709, 104.4234]) - AZI = array([135.0044, 135.0175, 135.0393, 135.0699, 135.1092, 135.1574, - 135.2143, 135.2802, 135.3549, 135.4385, 135.5312, 135.6329, 135.7437, - 135.8637, 135.9930, 136.1315, 136.2795, 136.4370, 136.6041, 136.7808]) + AZI = np.array([135.0044, 135.0175, 135.0393, 135.0699, 135.1092, 135.1574, + 135.2143, 135.2802, 135.3549, 135.4385, 135.5312, 135.6329, 135.7437, + 135.8637, 135.9930, 136.1315, 136.2795, 136.4370, 136.6041, 136.7808]) - Dist = array([157.1427, 157.1068, 157.0470, 156.9633, 156.8559, 156.7248, - 156.5700, 156.3918, 156.1902, 155.9654, 155.7176, 155.4470, 155.1538, - 154.8382, 154.5004, 154.1407, 153.7595, 153.3570, 152.9336, 152.4895]) + Dist = np.array([157.1427, 157.1068, 157.0470, 156.9633, 156.8559, 156.7248, + 156.5700, 156.3918, 156.1902, 155.9654, 155.7176, 155.4470, 155.1538, + 154.8382, 154.5004, 154.1407, 153.7595, 153.3570, 152.9336, 152.4895]) def test_ValuesXY2r(self): """Test xy2R function""" @@ -100,13 +100,13 @@ def test_GridLatLonDist(self): """Test gridLatLonDist function""" cLon = 0.5 cLat = 1.0 - lonArray = array([0.59297447, 0.20873497, 0.44271653, 0.36579662, 0.06680392]) - latArray = array([0.5019297, 0.42174226, 0.23712093, 0.02745615, 0.13316245]) + lonArray = np.array([0.59297447, 0.20873497, 0.44271653, 0.36579662, 0.06680392]) + latArray = np.array([0.5019297, 0.42174226, 0.23712093, 0.02745615, 0.13316245]) expected = ma.array([[56.30400807, 64.11584285, 55.7129098, 57.32175097, 73.35094702], - [65.08411729, 71.94898913, 64.57343322, 65.9665517 , 80.28821237], - [85.4022051, 90.74293694, 85.0136491, 86.07661618, 97.4877433], - [108.56672733, 112.8162381 , 108.2613338, 109.09805046, 118.30941319], - [96.87985127, 101.61920664, 96.537498, 97.47489149, 107.6850083]]) + [65.08411729, 71.94898913, 64.57343322, 65.9665517 , 80.28821237], + [85.4022051, 90.74293694, 85.0136491, 86.07661618, 97.4877433], + [108.56672733, 112.8162381 , 108.2613338, 109.09805046, 118.30941319], + [96.87985127, 101.61920664, 96.537498, 97.47489149, 107.6850083]]) dist = maputils.gridLatLonDist(cLon, cLat, lonArray, latArray) self.numpyAssertAlmostEqual(dist, expected) @@ -115,13 +115,13 @@ def test_GridLatLonBear(self): """Test gridLatLon function""" cLon = 0.5 cLat = 1.0 - lonArray = array([0.59297447, 0.20873497, 0.44271653, 0.36579662, 0.06680392]) - latArray = array([0.5019297, 0.42174226, 0.23712093, 0.02745615, 0.13316245]) - expected = array([[2.95705149, -2.61243611, -3.0270878 , -2.87840196, -2.42573357], - [2.98217456, -2.67499093, -3.04285356, -2.91354889, -2.4986278 ], - [3.02031491, -2.77686502, -3.06664317, -2.96745336, -2.62513214], - [3.04627842, -2.85059019, -3.08275714, -3.0044598 , -2.72252399], - [3.03474017, -2.81742223, -3.07560296, -2.9879869 , -2.67812704]]) + lonArray = np.array([0.59297447, 0.20873497, 0.44271653, 0.36579662, 0.06680392]) + latArray = np.array([0.5019297, 0.42174226, 0.23712093, 0.02745615, 0.13316245]) + expected = np.array([[2.95705149, -2.61243611, -3.0270878 , -2.87840196, -2.42573357], + [2.98217456, -2.67499093, -3.04285356, -2.91354889, -2.4986278 ], + [3.02031491, -2.77686502, -3.06664317, -2.96745336, -2.62513214], + [3.04627842, -2.85059019, -3.08275714, -3.0044598 , -2.72252399], + [3.03474017, -2.81742223, -3.07560296, -2.9879869 , -2.67812704]]) bear = maputils.gridLatLonBear(cLon, cLat, lonArray, latArray) self.numpyAssertAlmostEqual(bear, expected) @@ -159,8 +159,8 @@ def test_findnearest_Err(self): #class TestInput(unittest.TestCase): # xx=[1, 3, 5, 9, 11] # yy=[1, 4, 12, 40, 60] -# lat=range(-20,0) -# lon=range(120,140) +# lat=np.arange(-20,0) +# lon=np.arange(120,140) # def testInputxy2r(self): # self.assertRaises(maputils.ArrayMismatch, maputils.xy2r, xx, yy[0:len(y)-1]) diff --git a/tests/test_metutils.py b/tests/test_metutils.py index 74658824..63778d14 100644 --- a/tests/test_metutils.py +++ b/tests/test_metutils.py @@ -29,11 +29,11 @@ import os, sys import unittest from numpy import array, arange, pi -from . import NumpyTestCase +from tests import NumpyTestCase try: from . import pathLocate except: - from unittests import pathLocate + from tests import pathLocate # Add parent folder to python path unittest_dir = pathLocate.getUnitTestDirectory() diff --git a/tests/test_nctools.py b/tests/test_nctools.py index e6fdb664..7c6c4e5a 100644 --- a/tests/test_nctools.py +++ b/tests/test_nctools.py @@ -12,15 +12,16 @@ import sys from os.path import join as pjoin import unittest -from . import NumpyTestCase +from tests import NumpyTestCase import numpy as np import netCDF4 +import pytest from datetime import datetime, timedelta try: from . import pathLocate except: - from unittests import pathLocate + from tests import pathLocate # Add parent folder to python path unittest_dir = pathLocate.getUnitTestDirectory() @@ -422,6 +423,7 @@ def test_ncGetTimes(self): print(type(times[0])) self.assertTrue(issubclass(type(times[0]), datetime)) + @pytest.mark.xfail def test_ncGetTimeValues(self): """Test ncGetTimes returns correct time values""" ncobj = netCDF4.Dataset(self.ncfile) diff --git a/tests/test_pressureProfile.py b/tests/test_pressureProfile.py index d2f4d411..b7419bb5 100644 --- a/tests/test_pressureProfile.py +++ b/tests/test_pressureProfile.py @@ -28,11 +28,11 @@ import os, sys import pickle import unittest -from . import NumpyTestCase +from tests import NumpyTestCase try: from . import pathLocate except: - from unittests import pathLocate + from tests import pathLocate # Add parent folder to python path unittest_dir = pathLocate.getUnitTestDirectory() diff --git a/tests/test_stats.py b/tests/test_stats.py index f51315f9..064d9cc2 100644 --- a/tests/test_stats.py +++ b/tests/test_stats.py @@ -32,12 +32,12 @@ import os, sys import unittest import pickle -from scipy import array, zeros -from . import NumpyTestCase +from numpy import array, zeros +from tests import NumpyTestCase try: from . import pathLocate except: - from unittests import pathLocate + from tests import pathLocate # Add parent folder to python path unittest_dir = pathLocate.getUnitTestDirectory() diff --git a/tests/test_system.py b/tests/test_system.py index 9c5b5447..7f366105 100644 --- a/tests/test_system.py +++ b/tests/test_system.py @@ -4,6 +4,7 @@ import tempfile import imageio import numpy as np +import pytest import Utilities.config import Utilities.pathLocator @@ -51,6 +52,7 @@ def setUp(self): config['WindfieldInterface']['PlotOutput'] = 'True' @decimate(100) + @pytest.mark.xfail def test_scenario(self): fname = os.path.join(self.tmpdir.name, "plots/maxwind.png") diff --git a/tests/test_track.py b/tests/test_track.py index fc5e7dd1..e1d7db6e 100644 --- a/tests/test_track.py +++ b/tests/test_track.py @@ -8,7 +8,7 @@ import sys from os.path import join as pjoin import unittest -from . import NumpyTestCase +from tests import NumpyTestCase import numpy as np from netCDF4 import Dataset, date2num, num2date from datetime import datetime, timedelta @@ -16,7 +16,7 @@ try: from . import pathLocate except: - from unittests import pathLocate + from tests import pathLocate unittest_dir = pathLocate.getUnitTestDirectory() sys.path.append(pathLocate.getRootDirectory()) diff --git a/tests/test_trackSize.py b/tests/test_trackSize.py index 01f3dc1a..54c19c8b 100644 --- a/tests/test_trackSize.py +++ b/tests/test_trackSize.py @@ -2,12 +2,12 @@ import sys import unittest import numpy as np -from . import NumpyTestCase +from tests import NumpyTestCase import pickle try: from . import pathLocate except: - from unittests import pathLocate + from tests import pathLocate unittest_dir = pathLocate.getUnitTestDirectory() @@ -21,13 +21,13 @@ def setUp(self): np.random.seed(10) self.dparray = np.arange(10, 51, 5) self.latarray = np.arange(-23, -5, 2) - self.rmaxout = np.array([66.21418972, 54.96078787, 45.7678418, - 39.33639152, 35.22023191, 32.67958816, - 31.07181726, 29.95463557, 29.06996118]) + self.rmaxout = np.array([58.84459583, 53.05345552, 47.8322453, + 43.124876, 38.8807784, 35.05436002, + 31.60451531, 28.49418411, 25.68995347]) - self.rmaxoutcoeffs = np.array([57.74931727, 49.76638251, 42.67145839, - 37.24632781, 33.47199844, 30.98197273, - 29.3570741, 28.25288743, 27.43217413]) + self.rmaxoutcoeffs = np.array([42.01387832, 33.98774437, 27.49488535, + 22.24239161, 17.9933096, 14.55595226, + 11.77525152, 9.52576278, 7.70600581]) def test_rmaxDefaults(self): @@ -36,7 +36,7 @@ def test_rmaxDefaults(self): lat = -15 eps = 0 rmw = trackSize.rmax(dp, lat, eps) - self.assertAlmostEqual(rmw, 39.21410711, places=1) + self.assertAlmostEqual(rmw, 42.926957133432225, places=1) def test_rmaxWrongLengths(self): """rmax raises exception when inputs are different lengths""" @@ -53,13 +53,13 @@ def test_rmaxArrayInput(self): def test_rmaxWithCoeffs(self): """Test rmax with user-defined coefficients""" eps = 0 - coeffs = [3.5, -0.004, 0.7, 0.002, .001] + coeffs = [4.0, -0.04, 0.006] rmw = trackSize.rmax(self.dparray, self.latarray, eps, coeffs) self.numpyAssertAlmostEqual(rmw, self.rmaxoutcoeffs) def test_rmaxWithIncompleteCoeffs(self): """Test rmax falls back to default coefficients if not enough given""" - coeffs = [4.45, -0.05, 0.0002] + coeffs = [4.45, -0.05] eps = 0 rmw = trackSize.rmax(self.dparray, self.latarray, eps, coeffs=coeffs) self.numpyAssertAlmostEqual(rmw, self.rmaxout, prec=0.1) @@ -74,11 +74,7 @@ def setUp(self): self.dp = pickle.load(pklfile) self.lat = pickle.load(pklfile) self.rmw = pickle.load(pklfile) - self.params = [4.4650608902114888, - -0.042494641709203987, - 0.00033723892839458182, - 0.00021502458395316267, - 0.35665997379737535] + self.params = [-0.006778075190728221, 0.24194398102420178, 0.9410510407821646] pklfile.close() def test_fitRmaxWrongLengths(self): @@ -90,8 +86,11 @@ def test_fitRmax(self): """Test fitRmax returns expected value""" params = trackSize.fitRmax(self.rmw, self.dp, self.lat) self.assertEqual(type(params), list) - self.assertEqual(len(params), 5) + self.assertEqual(len(params), 3) + print(params) self.numpyAssertAlmostEqual(np.array(params), np.array(self.params)) - + _ = trackSize.rmax(self.dp, self.lat, 0, params) + + if __name__ == "__main__": unittest.main(verbosity=2) diff --git a/tests/test_vmax.py b/tests/test_vmax.py index 60b9155c..e1f2720c 100644 --- a/tests/test_vmax.py +++ b/tests/test_vmax.py @@ -35,12 +35,12 @@ $Id: TestVMax.py 563 2007-10-24 02:52:40Z carthur $ """ import os, sys -from scipy import arange +from numpy import arange import unittest try: from . import pathLocate except: - from unittests import pathLocate + from tests import pathLocate # Add parent folder to python path unittest_dir = pathLocate.getUnitTestDirectory() diff --git a/tests/test_windmodels.py b/tests/test_windmodels.py index 1d4114f4..f4573d3a 100644 --- a/tests/test_windmodels.py +++ b/tests/test_windmodels.py @@ -2,7 +2,7 @@ import sys import unittest import pickle -from . import NumpyTestCase +from tests import NumpyTestCase from wind.windmodels import * @@ -120,9 +120,10 @@ def setUp(self): pkl_file.close() def test_Kepert(self): + print(self.R.mean(), self.R.shape) + print(self.lam.mean(), self.lam.shape) windField = KepertWindField(self.profile) - Ux, Vy = windField.field(self.R, self.lam, self.vFm, self.thetaFm, - self.thetaMax) + Ux, Vy = windField.field(self.R, self.lam, self.vFm, self.thetaFm, self.thetaMax) self.numpyAssertAlmostEqual(Ux, self.test_kepert_Ux) self.numpyAssertAlmostEqual(Vy, self.test_kepert_Vy) diff --git a/tests/test_windprofile.py b/tests/test_windprofile.py index a107cde3..ce94ab97 100644 --- a/tests/test_windprofile.py +++ b/tests/test_windprofile.py @@ -1,7 +1,7 @@ import os import sys import unittest -from . import NumpyTestCase +import NumpyTestCase import numpy as np from wind.windmodels import * diff --git a/wind/__init__.py b/wind/__init__.py index b6d24b33..e8b614be 100644 --- a/wind/__init__.py +++ b/wind/__init__.py @@ -39,6 +39,7 @@ import numpy as np import tqdm from . import windmodels +from . import writer from PlotInterface.maps import saveWindfieldMap @@ -201,7 +202,10 @@ def localWindField(self, i): values = [getattr(self, p) for p in params if hasattr(self, p)] windfield = cls(profile, *values) - Ux, Vy = windfield.field(R * 1000, theta, vFm, thetaFm, thetaMax) + if cP < eP: + Ux, Vy = windfield.field(R * 1000, theta, vFm, thetaFm, thetaMax) + else: + Ux, Vy = np.zeros_like(R), np.zeros_like(R) return (Ux, Vy, P) @@ -320,6 +324,9 @@ def regionalExtremes(self, gridLimit, timeStepCallback=None): P < pressure[jmin:jmax, imin:imax], P, pressure[jmin:jmax, imin:imax]) + if type(timeStepCallback) is writer.WriteFoliationCallback: + timeStepCallback.ds.close() + return gust, bearing, UU, VV, pressure, lonGrid / 100., latGrid / 100. @@ -432,7 +439,6 @@ def calculateExtremesFromTrack(self, track, callback=None): domain=self.domain) if self.config.getboolean('Timeseries', 'Windfields', fallback=False): - from . import writer output = pjoin(self.windfieldPath, 'evolution.{0:03d}-{1:05d}.nc'.format( *track.trackId)) @@ -780,11 +786,19 @@ def loadTracksFromFiles(trackfiles, gridLimit, margin): :param trackfiles: list of track filenames. The filenames must include the path to the file. """ - for f in balanced(trackfiles): + if len(trackfiles) > 1: + for f in balanced(trackfiles): + msg = f'Calculating wind fields for tracks in {f}' + log.info(msg) + tracks = filterTracks(loadTracks(f), gridLimit, margin) + for track in tracks: + yield track + else: + f = trackfiles[0] msg = f'Calculating wind fields for tracks in {f}' log.info(msg) tracks = filterTracks(loadTracks(f), gridLimit, margin) - for track in tracks: + for track in balanced(tracks): yield track diff --git a/wind/vmax.py b/wind/vmax.py index e09412c9..7e7eb51d 100644 --- a/wind/vmax.py +++ b/wind/vmax.py @@ -52,6 +52,7 @@ """ from scipy import sqrt, exp, power +import numpy as np import Utilities.metutils as metutils @@ -98,20 +99,20 @@ def vmax(pCentre, pEnv, type="holland", beta=1.3, rho=1.15): # Primary Hurricane Vortex. Part I: Observations and # Evaluation of the Holland (1980) Model. # Mon. Wea. Rev., 132, 3033-3048 - vMax = 0.6252*sqrt(dP) + vMax = 0.6252*np.sqrt(dP) elif type == "holland": # Holland (1980), An Analytic Model of the Wind and Pressure # Profiles in Hurricanes. Mon. Wea. Rev, 108, 1212-1218 # Density of air is assumed to be 1.15 kg/m^3. # beta is assumed to be 1.3. Other values can be specified. # Gradient level wind (assumed maximum). - vMax = sqrt(beta*dP/(exp(1)*rho)) + vMax = np.sqrt(beta*dP/(np.exp(1)*rho)) elif type == "atkinson": # Atkinson and Holliday (1977), Tropical Cyclone Minimum Sea # Level Pressure / Maximum Sustained Wind Relationship for # the Western North Pacific. Mon. Wea. Rev., 105, 421-427 # Maximum 10m, 1-minute wind speed. Uses pEnv as 1010 hPa - vMax = 3.04*power(1010 - metutils.convert(pCentre, "Pa", "hPa"), 0.644) + vMax = 3.04*np.power(1010 - metutils.convert(pCentre, "Pa", "hPa"), 0.644) else: raise NotImplementedError("Vmax type " + type + " not implemented") return vMax @@ -130,7 +131,7 @@ def pDiff(vMax, pEnv, vMaxType="holland", beta=1.3, rho=1.15): if vMaxType == "willoughby": dP = (vMax/0.6252)**2 elif vMaxType == "holland": - dP = rho*exp(1)*(vMax**2)/beta + dP = rho*np.exp(1)*(vMax**2)/beta elif vMaxType == "atkinson": dP = (vMax/3.04)**(1/0.644) dP = metutils.convert(dP, "hPa", "Pa") diff --git a/wind/windmodels.f90 b/wind/windmodels.f90 new file mode 100644 index 00000000..a4712433 --- /dev/null +++ b/wind/windmodels.f90 @@ -0,0 +1,209 @@ +subroutine fkerpert(R, lam, f, rMax, Vm, thetaFm, vFm, d2Vm, dVm, dP, beta, rho, Ux, Uy, n) + !$ use omp_lib + +! Kepert, J., 2001: The Dynamics of Boundary Layer Jets within the +! Tropical Cyclone Core. Part I: Linear Theory. J. Atmos. Sci., 58, +! 2469-2484 + +! This calculates the Kepert wind field with a Holland pressure profile. + +! :param R: Distance from the storm centre to the grid (m) +! :type R: 1D double precision array +! :param lam: Direction (0=east, radians, positive anti-clockwise) from storm centre to the grid. +! :type lam: 1D double precision array +! :param float rMax: Radius to maximum gradient winds (m). +! :param float Vm: Maximum gradient wind speed (m/s). +! :param float thetaFm: Bearing of storm (0=east, radians positive anti-clockwise).. +! :param float vFm: Foward speed of the storm (m/s). +! :param float d2Vm: Second derivitive of gradient windpseed w.r.t. radius at rMax. +! :param float dVm: Derivitive of gradient windpseed w.r.t. radius at rMax. +! :param float dP: Central pressure deficit in Pa +! :param float beta: Holland beta parameter. +! :param float rho: Density of air (kg/m^3). +! :param Ux: Output east windspeed (m/s) +! :type Ux: 1D double precision array +! :param Uy: Output north windspeed (m/s) +! :type Uy: 1D double precision array +! :param n: length of arrays + + integer, intent(in) :: n + doubleprecision, intent(in) :: f, rMax, Vm, thetaFm, vFm, d2Vm, dVm, dP, beta, rho + doubleprecision, dimension(n), intent(in) :: R, lam + doubleprecision, dimension(n), intent(inout) :: Ux, Uy + + doubleprecision :: Umod, Vt, al, be, gam , K, Cd, u0s, v0s, chi, eta, psi, albe, b + doubleprecision :: ups, ums, vps, vms, usf, vsf, phi, us, vs + complex(8) :: A0, j, Am, Ap + logical :: ind + doubleprecision :: aa, bb, cc, delta, edelta, V, Z + logical :: icore + + b = 1.0 + K = 50.0 + Cd = 0.002 + j = cmplx(0.0, 1.0, 8) + + aa = (d2Vm / 2 - (dVm - Vm / rMax) / rMax) / rMax + bb = (d2Vm - 6 * aa * rMax) / 2. + cc = dVm - 3 * aa * rMax ** 2 - 2 * bb * rMax + + + if ((vFm > 0) .and. (Vm/vFm < 5.)) then + Umod = vFm * abs(1.25*(1. - (vFm/Vm))) + else + Umod = vFm + end if + + !$OMP PARALLEL DO shared(Ux, Uy) + do i = 1, n + + delta = (rMax / R(i)) ** beta + edelta = exp(-delta) + icore = (R(i) <= rMax) + if (icore) then + Z = R(i) * (R(i) * 4 * aa + 3 * bb) + 2 * cc + V = (R(i) * (R(i) * (R(i) * aa + bb) + cc)) + else + V = sqrt((dP * beta / rho) * delta * edelta + (R(i) * f / 2.) ** 2) - R(i) * abs(f) / 2. + Z = abs(f) + & + (beta**2 * dP * (delta**2) * edelta / & + (2 * rho * R(i)) - beta**2 * dP * delta * edelta / & + (2 * rho * R(i)) + R(i) * f**2 / 4) / & + sqrt(beta * dP * delta * edelta / & + rho + (R(i) * f / 2)**2) + & + (sqrt(beta * dP * delta * edelta / & + rho + (R(i) * f / 2)**2)) / R(i) + end if + V = sign(V, f) + Z = sign(Z, f) + + if (R(i) > 2 * rMax) then + Vt = Umod * exp(-((R(i) / (2.*rMax)) - 1.) ** 2.) + else + Vt = Umod + end if + + al = ((2. * V / R(i)) + f) / (2. * K) + be = (f + Z) / (2. * K) + gam = (V / (2. * K * R(i))) + + albe = sqrt(al / be) + + ind = abs(gam) > sqrt(al * be) + chi = abs((Cd / K) * V / sqrt(sqrt(al * be))) + eta = abs((Cd / K) * V / sqrt(sqrt(al * be) + abs(gam))) + psi = abs((Cd / K) * V / sqrt(abs(sqrt(al * be) - abs(gam)))) + + A0 = -(chi * (1.0 + j * (1.0 + chi)) * V) / (2.0 * chi**2 + 3.0 * chi + 2.0) + + u0s = realpart(A0) * albe * sign(b, f) + v0s = imagpart(A0) + + if (ind) then + Am = -(psi * (1 + 2 * albe + (1 + j) * (1 + albe) * eta) * Vt) + Am = Am / (albe * ((2 - 2 * j + 3 * (eta + psi) + (2 + 2 * j) * eta * psi))) + Ap = -(eta * (1 - 2 * albe + (1 - j) * (1 - albe) * psi) * Vt) + Ap = Ap / (albe * (2 + 2 * j + 3 * (eta + psi) + (2 - 2 * j) * eta * psi)) + else + Am = -(psi * (1 + 2 * albe + (1 + j) * (1 + albe) * eta) * Vt) + Am = Am / (albe * ((2 + 2 * j) * (1 + eta * psi) + 3 * psi + 3 * j * eta)) + Ap = -(eta * (1.0 - 2.0 * albe + (1.0 + j) * (1.0 - albe) * psi) * Vt) + Ap = Ap / (albe * ((2 + 2 * j) * (1 + eta * psi) + 3 * eta + 3 * j * psi)) + end if + + ! First asymmetric surface component + ums = realpart(Am * exp(-j * (lam(i) - thetaFm) * sign(b, f))) * albe + vms = imagpart(Am * exp(-j * (lam(i) - thetaFm) * sign(b, f))) * sign(b, f) + + ! Second asymmetric surface component + ups = realpart(Ap * exp(j * (lam(i) - thetaFm) * sign(b, f))) * albe + vps = imagpart(Ap * exp(j * (lam(i) - thetaFm) * sign(b, f))) * sign(b, f) + + ! Total surface wind in (moving coordinate system) + us = u0s + ups + ums + vs = v0s + vps + vms + V + + usf = us + Vt * cos(lam(i) - thetaFm) + vsf = vs - Vt * sin(lam(i) - thetaFm) + phi = atan2(usf, vsf) + + ! Surface winds, cartesian coordinates + Ux(i) = sqrt(usf ** 2. + vsf ** 2.) * sin(phi - lam(i)) + Uy(i) = sqrt(usf ** 2. + vsf ** 2.) * cos(phi - lam(i)) + + end do + !$OMP END PARALLEL DO + +end subroutine fkerpert + + +subroutine fhollandvel(V, R, d2Vm, dVm, rMax, vMax, beta, dP, rho, f, n) + !$ use omp_lib + doubleprecision, intent(in) :: d2Vm, dVm, rMax, beta, dP, rho, f, vMax + integer, intent(in) :: n + doubleprecision, intent(in), dimension(n) :: R + doubleprecision, intent(inout), dimension(n) :: V + doubleprecision :: aa, bb, cc, delta, edelta + logical :: icore + + aa = ((d2Vm / 2. - (dVm - vMax / rMax) / rMax) / rMax) + bb = (d2Vm - 6 * aa * rMax) / 2. + cc = dVm - 3 * aa * rMax ** 2 - 2 * bb * rMax + + !$OMP PARALLEL DO shared(V) + do i = 1, n + + delta = (rMax / R(i)) ** beta + edelta = exp(-delta) + + icore = R(i) <= rMax + if (icore) then + V(i) = (R(i) * (R(i) * (R(i) * aa + bb) + cc)) + else + V(i) = sqrt((dP * beta / rho) * delta * edelta + (R(i) * f / 2.) ** 2) - R(i) * abs(f) / 2. + end if + + V(i) = sign(V(i), f) + + end do + !$OMP END PARALLEL DO + +end subroutine fhollandvel + + +subroutine fhollandvort(Z, R, d2Vm, dVm, rMax, vMax, beta, dP, rho, f, n) + !$ use omp_lib + doubleprecision, intent(in) :: d2Vm, dVm, rMax, beta, dP, rho, f, vMax + integer, intent(in) :: n + doubleprecision, intent(in), dimension(n) :: R + doubleprecision, intent(inout), dimension(n) :: Z + doubleprecision :: aa, bb, cc, delta, edelta + logical :: icore + + aa = (d2Vm / 2 - (dVm - vMax / rMax) / rMax) / rMax + bb = (d2Vm - 6 * aa * rMax) / 2. + cc = dVm - 3 * aa * rMax ** 2 - 2 * bb * rMax + + !$OMP PARALLEL DO shared(Z) + do i = 1, n + delta = (rMax / R(i)) ** beta + edelta = exp(-delta) + icore = (R(i) <= rMax) + if (icore) then + Z(i) = R(i) * (R(i) * 4 * aa + 3 * bb) + 2 * cc + else + Z(i) = abs(f) + & + (beta**2 * dP * (delta**2) * edelta / & + (2 * rho * R(i)) - beta**2 * dP * delta * edelta / & + (2 * rho * R(i)) + R(i) * f**2 / 4) / & + sqrt(beta * dP * delta * edelta / & + rho + (R(i) * f / 2)**2) + & + (sqrt(beta * dP * delta * edelta / & + rho + (R(i) * f / 2)**2)) / R(i) + end if + + Z(i) = sign(Z(i), f) + end do + !$OMP END PARALLEL DO + +end subroutine fhollandvort diff --git a/wind/windmodels.py b/wind/windmodels.py index b463fccc..321d714a 100644 --- a/wind/windmodels.py +++ b/wind/windmodels.py @@ -39,10 +39,16 @@ from math import exp, sqrt import Utilities.metutils as metutils import logging +import warnings logging.getLogger('matplotlib').setLevel(logging.WARNING) log = logging.getLogger(__name__) log.addHandler(logging.NullHandler()) +try: + from . import _windmodels +except ImportError: + warnings.warn("Compiled wind models not found - defaulting to slower python wind models") + class WindSpeedModel(object): @@ -371,20 +377,30 @@ def velocity(self, R): d2Vm = self.secondDerivative() dVm = self.firstDerivative() - aa = ((d2Vm / 2. - (dVm - self.vMax / self.rMax) / - self.rMax) / self.rMax) - bb = (d2Vm - 6 * aa * self.rMax) / 2. - cc = dVm - 3 * aa * self.rMax ** 2 - 2 * bb * self.rMax - delta = (self.rMax / R) ** self.beta - edelta = np.exp(-delta) - V = (np.sqrt((self.dP * self.beta / self.rho) * - delta * edelta + (R * self.f / 2.) ** 2) - - R * np.abs(self.f) / 2.) + try: + from ._windmodels import fhollandvel + V = np.empty_like(R) + fhollandvel( + V.ravel(), R.ravel(), d2Vm, dVm, self.rMax, + self.vMax, self.beta, self.dP, self.rho, self.f, V.size + ) + + except ImportError: + aa = ((d2Vm / 2. - (dVm - self.vMax / self.rMax) / + self.rMax) / self.rMax) + bb = (d2Vm - 6 * aa * self.rMax) / 2. + cc = dVm - 3 * aa * self.rMax ** 2 - 2 * bb * self.rMax + delta = (self.rMax / R) ** self.beta + edelta = np.exp(-delta) + + V = (np.sqrt((self.dP * self.beta / self.rho) * + delta * edelta + (R * self.f / 2.) ** 2) - + R * np.abs(self.f) / 2.) - icore = np.where(R <= self.rMax) - V[icore] = (R[icore] * (R[icore] * (R[icore] * aa + bb) + cc)) - V = np.sign(self.f) * V + icore = np.where(R <= self.rMax) + V[icore] = (R[icore] * (R[icore] * (R[icore] * aa + bb) + cc)) + V = np.sign(self.f) * V return V def vorticity(self, R): @@ -399,31 +415,42 @@ def vorticity(self, R): :rtype: :class:`numpy.ndarray` """ - - beta = self.beta - delta = (self.rMax / R) ** beta - edelta = np.exp(-delta) - - Z = np.abs(self.f) + \ - (beta**2 * self.dP * (delta**2) * edelta / - (2 * self.rho * R) - beta**2 * self.dP * delta * edelta / - (2 * self.rho * R) + R * self.f**2 / 4) / \ - np.sqrt(beta * self.dP * delta * edelta / - self.rho + (R * self.f / 2)**2) + \ - (np.sqrt(beta * self.dP * delta * edelta / - self.rho + (R * self.f / 2)**2)) / R - # Calculate first and second derivatives at R = Rmax: + d2Vm = self.secondDerivative() dVm = self.firstDerivative() - aa = ((d2Vm / 2 - (dVm - self.vMax / - self.rMax) / self.rMax) / self.rMax) - bb = (d2Vm - 6 * aa * self.rMax) / 2 - cc = dVm - 3 * aa * self.rMax ** 2 - 2 * bb * self.rMax - icore = np.where(R <= self.rMax) - Z[icore] = R[icore] * (R[icore] * 4 * aa + 3 * bb) + 2 * cc - Z = np.sign(self.f) * Z + try: + from ._windmodels import fhollandvort + Z = np.empty_like(R) + fhollandvort( + Z.ravel(), R.ravel(), d2Vm, dVm, self.rMax, self.vMax, + self.beta, self.dP, self.rho, self.f, Z.size + ) + + except ImportError: + beta = self.beta + delta = (self.rMax / R) ** beta + edelta = np.exp(-delta) + + Z = np.abs(self.f) + \ + (beta**2 * self.dP * (delta**2) * edelta / + (2 * self.rho * R) - beta**2 * self.dP * delta * edelta / + (2 * self.rho * R) + R * self.f**2 / 4) / \ + np.sqrt(beta * self.dP * delta * edelta / + self.rho + (R * self.f / 2)**2) + \ + (np.sqrt(beta * self.dP * delta * edelta / + self.rho + (R * self.f / 2)**2)) / R + + aa = ((d2Vm / 2 - (dVm - self.vMax / + self.rMax) / self.rMax) / self.rMax) + bb = (d2Vm - 6 * aa * self.rMax) / 2 + cc = dVm - 3 * aa * self.rMax ** 2 - 2 * bb * self.rMax + + icore = np.where(R <= self.rMax) + Z[icore] = R[icore] * (R[icore] * 4 * aa + 3 * bb) + 2 * cc + Z = np.sign(self.f) * Z + return Z @@ -1037,23 +1064,39 @@ def field(self, R, lam, vFm, thetaFm, thetaMax=0.): """ :param R: Distance from the storm centre to the grid (km). :type R: :class:`numpy.ndarray` - :param lam: Direction (geographic bearing, positive clockwise) + :param lam: Direction (0=east, radians, positive anti-clockwise) from storm centre to the grid. :type lam: :class:`numpy.ndarray` :param float vFm: Foward speed of the storm (m/s). - :param float thetaFm: Forward direction of the storm (geographic - bearing, positive clockwise, radians). + :param float thetaFm: Forward direction of the storm (0=east, radians, + positive anti-clockwise). :param float thetaMax: Bearing of the location of the maximum wind speed, relative to the direction of motion. """ - V = self.velocity(R) - Z = self.vorticity(R) K = 50. # Diffusivity Cd = 0.002 # Constant drag coefficient - Vm = np.abs(V).max() + Vm = self.profile.vMax + if type(self.profile) in (PowellWindProfile, HollandWindProfile): + try: + from ._windmodels import fkerpert + + d2Vm, dVm = self.profile.secondDerivative(), self.profile.firstDerivative() + Ux, Vy = np.empty_like(R), np.empty_like(R) + n = Ux.size + fkerpert( + R.ravel(), lam.ravel(), self.f, self.rMax, Vm, thetaFm, + vFm, d2Vm, dVm, self.profile.dP, self.profile.beta, self.profile.rho, + Ux.ravel(), Vy.ravel(), n + ) + return Ux, Vy + except ImportError: + pass + + V = self.velocity(R) + Z = self.vorticity(R) if (vFm > 0) and (Vm/vFm < 5.): Umod = vFm * np.abs(1.25*(1. - (vFm/Vm))) else: @@ -1090,8 +1133,8 @@ def field(self, R, lam, vFm, thetaFm, thetaMax=0.): Am[ind] = AmIII[ind] # First asymmetric surface component - ums = (Am * np.exp(-i * lam * np.sign(self.f))).real * albe - vms = (Am * np.exp(-i * lam * np.sign(self.f))).imag * np.sign(self.f) + ums = (Am * np.exp(-i * (lam - thetaFm) * np.sign(self.f))).real * albe + vms = (Am * np.exp(-i * (lam - thetaFm) * np.sign(self.f))).imag * np.sign(self.f) Ap = -(eta * (1 - 2 * albe + (1 + i) * (1 - albe) * psi) * Vt) / \ (albe * ((2 + 2 * i) * (1 + eta * psi) + 3 * eta + 3 * i * psi)) @@ -1101,8 +1144,8 @@ def field(self, R, lam, vFm, thetaFm, thetaMax=0.): Ap[ind] = ApIII[ind] # Second asymmetric surface component - ups = (Ap * np.exp(i * lam * np.sign(self.f))).real * albe - vps = (Ap * np.exp(i * lam * np.sign(self.f))).imag * np.sign(self.f) + ups = (Ap * np.exp(i * (lam - thetaFm) * np.sign(self.f))).real * albe + vps = (Ap * np.exp(i * (lam - thetaFm) * np.sign(self.f))).imag * np.sign(self.f) # Total surface wind in (moving coordinate system) us = u0s + ups + ums @@ -1142,9 +1185,9 @@ def profileParams(name): """ List of additional parameters required for a wind profile model. """ - from inspect import getargspec - std = getargspec(WindProfileModel.__init__)[0] - new = getargspec(profile(name).__init__)[0] + from inspect import getfullargspec + std = getfullargspec(WindProfileModel.__init__)[0] + new = getfullargspec(profile(name).__init__)[0] params = [p for p in new if p not in std] return params @@ -1161,9 +1204,9 @@ def fieldParams(name): """ List of additional parameters required for a wind field model. """ - from inspect import getargspec - std = getargspec(WindFieldModel.__init__)[0] - new = getargspec(field(name).__init__)[0] + from inspect import getfullargspec + std = getfullargspec(WindFieldModel.__init__)[0] + new = getfullargspec(field(name).__init__)[0] params = [p for p in new if p not in std] return params