diff --git a/setup.cfg b/setup.cfg index cabd3ddd2d5..b5af859b676 100644 --- a/setup.cfg +++ b/setup.cfg @@ -77,15 +77,14 @@ copyright-check = True copyright-author = MetPy Developers inline-quotes = single multiline-quotes = double -rst-roles = class, data, func, meth, mod -rst-directives = plot +rst-roles = class, data, doc, func, meth, mod +rst-directives = plot, versionchanged docstring-convention = numpy exclude = docs build src/metpy/io/metar_parser.py select = A B C D E F H I M Q RST S T W B902 ignore = F405 W503 RST902 per-file-ignores = examples/*.py: D T003 T001 tutorials/*.py: D T003 T001 - tutorials/xarray_tutorial.py: D RST304 src/metpy/xarray.py: RST304 src/metpy/deprecation.py: C801 src/metpy/calc/*.py: RST306 diff --git a/src/metpy/calc/basic.py b/src/metpy/calc/basic.py index 366814cae4f..d38f9d909d9 100644 --- a/src/metpy/calc/basic.py +++ b/src/metpy/calc/basic.py @@ -139,6 +139,9 @@ def wind_components(speed, wind_direction): >>> metpy.calc.wind_components(10. * units('m/s'), 225. * units.deg) (, ) + .. versionchanged:: 1.0 + Renamed ``wdir`` parameter to ``wind_direction`` + """ wind_direction = _check_radians(wind_direction, max_radians=4 * np.pi) u = -speed * np.sin(wind_direction) @@ -185,7 +188,7 @@ def windchill(temperature, speed, face_level_winds=False, mask_undefined=True): See Also -------- - heat_index + heat_index, apparent_temperature """ # Correct for lower height measurement of winds if necessary @@ -239,9 +242,13 @@ def heat_index(temperature, relative_humidity, mask_undefined=True): A flag indicating whether a masked array should be returned with values masked where the temperature < 80F. Defaults to `True`. + + .. versionchanged:: 1.0 + Renamed ``rh`` parameter to ``relative_humidity`` + See Also -------- - windchill + windchill, apparent_temperature """ temperature = np.atleast_1d(temperature) @@ -352,6 +359,10 @@ def apparent_temperature(temperature, relative_humidity, speed, face_level_winds `pint.Quantity` Corresponding apparent temperature value(s) + + .. versionchanged:: 1.0 + Renamed ``rh`` parameter to ``relative_humidity`` + See Also -------- heat_index, windchill @@ -532,6 +543,9 @@ def geopotential_to_height(geopotential): (Prior to MetPy v0.11, this formula instead calculated :math:`g(z)` from Newton's Law of Gravitation assuming a spherical Earth and no centrifugal force effects.) + .. versionchanged:: 1.0 + Renamed ``geopot`` parameter to ``geopotential`` + See Also -------- height_to_geopotential @@ -680,6 +694,9 @@ def sigma_to_pressure(sigma, pressure_sfc, pressure_top): * :math:`p_{sfc}` is pressure at the surface or model floor * :math:`p_{top}` is pressure at the top of the model domain + .. versionchanged:: 1.0 + Renamed ``psfc``, ``ptop`` parameters to ``pressure_sfc``, ``pressure_top`` + """ if np.any(sigma < 0) or np.any(sigma > 1): raise ValueError('Sigma values should be bounded by 0 and 1') diff --git a/src/metpy/calc/cross_sections.py b/src/metpy/calc/cross_sections.py index b1e0d67e338..eb05dd830ad 100644 --- a/src/metpy/calc/cross_sections.py +++ b/src/metpy/calc/cross_sections.py @@ -287,6 +287,9 @@ def absolute_momentum(u, v, index='index'): ----- The coordinates of `u` and `v` must match. + .. versionchanged:: 1.0 + Renamed ``u_wind``, ``v_wind`` parameters to ``u``, ``v`` + """ # Get the normal component of the wind norm_wind = normal_component(u, v, index=index).metpy.convert_units('m/s') diff --git a/src/metpy/calc/indices.py b/src/metpy/calc/indices.py index ad3b4ee5553..0a4dad7ffaa 100644 --- a/src/metpy/calc/indices.py +++ b/src/metpy/calc/indices.py @@ -55,6 +55,9 @@ def precipitable_water(pressure, dewpoint, *, bottom=None, top=None): ----- Only functions on 1D profiles (not higher-dimension vertical cross sections or grids). + .. versionchanged:: 1.0 + Signature changed from ``(dewpt, pressure, bottom=None, top=None)`` + """ # Sort pressure and dewpoint to be in decreasing pressure order (increasing height) sort_inds = np.argsort(pressure)[::-1] @@ -120,6 +123,9 @@ def mean_pressure_weighted(pressure, *args, height=None, bottom=None, depth=None Since this function returns scalar values when given a profile, this will return Pint Quantities even when given xarray DataArray profiles. + .. versionchanged:: 1.0 + Renamed ``heights`` parameter to ``height`` + """ ret = [] # Returned variable means in layer layer_arg = get_layer(pressure, *args, height=height, @@ -176,6 +182,9 @@ def bunkers_storm_motion(pressure, u, v, height): Since this function returns scalar values when given a profile, this will return Pint Quantities even when given xarray DataArray profiles. + .. versionchanged:: 1.0 + Renamed ``heights`` parameter to ``height`` + """ # mean wind from sfc-6km wind_mean = concatenate(mean_pressure_weighted(pressure, u, v, height=height, @@ -252,6 +261,9 @@ def bulk_shear(pressure, u, v, height=None, bottom=None, depth=None): Since this function returns scalar values when given a profile, this will return Pint Quantities even when given xarray DataArray profiles. + .. versionchanged:: 1.0 + Renamed ``heights`` parameter to ``height`` + """ _, u_layer, v_layer = get_layer(pressure, u, v, height=height, bottom=bottom, depth=depth) @@ -407,6 +419,9 @@ def critical_angle(pressure, u, v, height, u_storm, v_storm): Since this function returns scalar values when given a profile, this will return Pint Quantities even when given xarray DataArray profiles. + .. versionchanged:: 1.0 + Renamed ``heights`` parameter to ``height`` + """ # Convert everything to m/s u = u.to('m/s') diff --git a/src/metpy/calc/kinematics.py b/src/metpy/calc/kinematics.py index c2c785bc36d..5e2281cdefc 100644 --- a/src/metpy/calc/kinematics.py +++ b/src/metpy/calc/kinematics.py @@ -47,6 +47,10 @@ def vorticity(u, v, *, dx=None, dy=None, x_dim=-1, y_dim=-2): (..., M, N) `xarray.DataArray` or `pint.Quantity` vertical vorticity + + .. versionchanged:: 1.0 + Changed signature from ``(u, v, dx, dy)`` + See Also -------- divergence @@ -90,6 +94,10 @@ def divergence(u, v, *, dx=None, dy=None, x_dim=-1, y_dim=-2): (..., M, N) `xarray.DataArray` or `pint.Quantity` The horizontal divergence + + .. versionchanged:: 1.0 + Changed signature from ``(u, v, dx, dy)`` + See Also -------- vorticity @@ -133,6 +141,10 @@ def shearing_deformation(u, v, dx=None, dy=None, x_dim=-1, y_dim=-2): (..., M, N) `xarray.DataArray` or `pint.Quantity` Shearing Deformation + + .. versionchanged:: 1.0 + Changed signature from ``(u, v, dx, dy)`` + See Also -------- stretching_deformation, total_deformation @@ -176,6 +188,10 @@ def stretching_deformation(u, v, dx=None, dy=None, x_dim=-1, y_dim=-2): (..., M, N) `xarray.DataArray` or `pint.Quantity` Stretching Deformation + + .. versionchanged:: 1.0 + Changed signature from ``(u, v, dx, dy)`` + See Also -------- shearing_deformation, total_deformation @@ -219,15 +235,18 @@ def total_deformation(u, v, dx=None, dy=None, x_dim=-1, y_dim=-2): (..., M, N) `xarray.DataArray` or `pint.Quantity` Total Deformation - See Also - -------- - shearing_deformation, stretching_deformation - Notes ----- If inputs have more than two dimensions, they are assumed to have either leading dimensions of (x, y) or trailing dimensions of (y, x), depending on the value of ``dim_order``. + .. versionchanged:: 1.0 + Changed signature from ``(u, v, dx, dy)`` + + See Also + -------- + shearing_deformation, stretching_deformation + """ dudy, dudx = gradient(u, deltas=(dy, dx), axes=(y_dim, x_dim)) dvdy, dvdx = gradient(v, deltas=(dy, dx), axes=(y_dim, x_dim)) @@ -286,6 +305,10 @@ def advection( `pint.Quantity` or `xarray.DataArray` An N-dimensional array containing the advection at all grid points. + + .. versionchanged:: 1.0 + Changed signature from ``(scalar, wind, deltas)`` + """ return -sum( wind * first_derivative(scalar, axis=axis, delta=delta) @@ -352,6 +375,9 @@ def frontogenesis(potential_temperature, u, v, dx=None, dy=None, x_dim=-1, y_dim Conversion factor to go from [temperature units]/m/s to [temperature units/100km/3h] :math:`1.08e4*1.e5` + .. versionchanged:: 1.0 + Changed signature from ``(thta, u, v, dx, dy, dim_order='yx')`` + """ # Get gradients of potential temperature in both x and y ddy_thta = first_derivative(potential_temperature, delta=dy, axis=y_dim) @@ -411,6 +437,10 @@ def geostrophic_wind(height, dx=None, dy=None, latitude=None, x_dim=-1, y_dim=-2 A 2-item tuple of arrays A tuple of the u-component and v-component of the geostrophic wind. + + .. versionchanged:: 1.0 + Changed signature from ``(heights, f, dx, dy)`` + """ f = coriolis_parameter(latitude) if height.dimensionality['[length]'] == 2.0: @@ -472,6 +502,10 @@ def ageostrophic_wind(height, u, v, dx=None, dy=None, latitude=None, x_dim=-1, y A 2-item tuple of arrays A tuple of the u-component and v-component of the ageostrophic wind + + .. versionchanged:: 1.0 + Changed signature from ``(heights, f, dx, dy, u, v, dim_order='yx')`` + """ u_geostrophic, v_geostrophic = geostrophic_wind( height, @@ -583,6 +617,10 @@ def storm_relative_helicity(height, u, v, depth, *, bottom=0 * units.m, Since this function returns scalar values when given a profile, this will return Pint Quantities even when given xarray DataArray profiles. + .. versionchanged:: 1.0 + Renamed ``heights`` parameter to ``height`` and converted ``bottom``, ``storm_u``, and + ``storm_v`` parameters to keyword-only arguments + """ _, u, v = get_layer_heights(height, depth, u, v, with_agl=True, bottom=bottom) @@ -643,6 +681,10 @@ def absolute_vorticity(u, v, dx=None, dy=None, latitude=None, x_dim=-1, y_dim=-2 (..., M, N) `xarray.DataArray` or `pint.Quantity` absolute vorticity + + .. versionchanged:: 1.0 + Changed signature from ``(u, v, dx, dy, lats, dim_order='yx')`` + """ f = coriolis_parameter(latitude) relative_vorticity = vorticity(u, v, dx=dx, dy=dy, x_dim=x_dim, y_dim=y_dim) @@ -728,6 +770,9 @@ def potential_vorticity_baroclinic( one-dimensional, and not given as `xarray.DataArray`, p[:, None, None] can be used to make it appear multi-dimensional.) + .. versionchanged:: 1.0 + Changed signature from ``(potential_temperature, pressure, u, v, dx, dy, lats)`` + """ if ( np.shape(potential_temperature)[vertical_dim] < 3 @@ -809,6 +854,10 @@ def potential_vorticity_barotropic( (..., M, N) `xarray.DataArray` or `pint.Quantity` barotropic potential vorticity + + .. versionchanged:: 1.0 + Changed signature from ``(heights, u, v, dx, dy, lats, dim_order='yx')`` + """ avor = absolute_vorticity(u, v, dx, dy, latitude, x_dim=x_dim, y_dim=y_dim) return (avor / height).to('meter**-1 * second**-1') @@ -890,6 +939,9 @@ def inertial_advective_wind( wind to both be the geostrophic wind. To do so, pass the x and y components of the geostrophic wind for u and u_geostrophic/v and v_geostrophic. + .. versionchanged:: 1.0 + Changed signature from ``(u, v, u_geostrophic, v_geostrophic, dx, dy, lats)`` + """ f = coriolis_parameter(latitude) @@ -970,6 +1022,10 @@ def q_vector( tuple of (..., M, N) `xarray.DataArray` or `pint.Quantity` The components of the Q-vector in the u- and v-directions respectively + + .. versionchanged:: 1.0 + Changed signature from ``(u, v, temperature, pressure, dx, dy, static_stability=1)`` + See Also -------- static_stability diff --git a/src/metpy/calc/thermo.py b/src/metpy/calc/thermo.py index e420b72fb13..c1888321c6d 100644 --- a/src/metpy/calc/thermo.py +++ b/src/metpy/calc/thermo.py @@ -45,6 +45,10 @@ def relative_humidity_from_dewpoint(temperature, dewpoint): `pint.Quantity` Relative humidity + + .. versionchanged:: 1.0 + Renamed ``dewpt`` parameter to ``dewpoint`` + See Also -------- saturation_vapor_pressure @@ -178,6 +182,9 @@ def temperature_from_potential_temperature(pressure, potential_temperature): >>> p = 850 * units.mbar >>> T = temperature_from_potential_temperature(p, theta) + .. versionchanged:: 1.0 + Renamed ``theta`` parameter to ``potential_temperature`` + """ return potential_temperature * exner_function(pressure) @@ -222,6 +229,9 @@ def dry_lapse(pressure, temperature, reference_pressure=None, vertical_dim=0): Only reliably functions on 1D profiles (not higher-dimension vertical cross sections or grids) unless reference_pressure is specified. + .. versionchanged:: 1.0 + Renamed ``ref_pressure`` parameter to ``reference_pressure`` + """ if reference_pressure is None: reference_pressure = pressure[0] @@ -276,6 +286,9 @@ def moist_lapse(pressure, temperature, reference_pressure=None): Only reliably functions on 1D profiles (not higher-dimension vertical cross sections or grids). + .. versionchanged:: 1.0 + Renamed ``ref_pressure`` parameter to ``reference_pressure`` + """ def dt(t, p): t = units.Quantity(t, temperature.units) @@ -380,6 +393,9 @@ def lcl(pressure, temperature, dewpoint, max_iters=50, eps=1e-5): Since this function returns scalar values when given a profile, this will return Pint Quantities even when given xarray DataArray profiles. + .. versionchanged:: 1.0 + Renamed ``dewpt`` parameter to ``dewpoint`` + """ def _lcl_iter(p, p0, w, t): td = globals()['dewpoint'](vapor_pressure(units.Quantity(p, pressure.units), w)) @@ -453,6 +469,9 @@ def lfc(pressure, temperature, dewpoint, parcel_temperature_profile=None, dewpoi Since this function returns scalar values when given a profile, this will return Pint Quantities even when given xarray DataArray profiles. + .. versionchanged:: 1.0 + Renamed ``dewpt``,``dewpoint_start`` parameters to ``dewpoint``, ``dewpoint_start`` + """ pressure, temperature, dewpoint = _remove_nans(pressure, temperature, dewpoint) # Default to surface parcel if no profile or starting pressure level is given @@ -633,6 +652,9 @@ def el(pressure, temperature, dewpoint, parcel_temperature_profile=None, which=' Since this function returns scalar values when given a profile, this will return Pint Quantities even when given xarray DataArray profiles. + .. versionchanged:: 1.0 + Renamed ``dewpt`` parameter to ``dewpoint`` + """ pressure, temperature, dewpoint = _remove_nans(pressure, temperature, dewpoint) # Default to surface parcel if no profile or starting pressure level is given @@ -694,6 +716,9 @@ def parcel_profile(pressure, temperature, dewpoint): ----- Only functions on 1D profiles (not higher-dimension vertical cross sections or grids). + .. versionchanged:: 1.0 + Renamed ``dewpt`` parameter to ``dewpoint`` + """ _, _, _, t_l, _, t_u = _parcel_profile_helper(pressure, temperature, dewpoint) return concatenate((t_l, t_u)) @@ -749,6 +774,9 @@ def parcel_profile_with_lcl(pressure, temperature, dewpoint): Also, will only return Pint Quantities, even when given xarray DataArray profiles. To obtain a xarray Dataset instead, use `parcel_profile_with_lcl_as_dataset` instead. + .. versionchanged:: 1.0 + Renamed ``dewpt`` parameter to ``dewpoint`` + """ p_l, p_lcl, p_u, t_l, t_lcl, t_u = _parcel_profile_helper(pressure, temperature[0], dewpoint[0]) @@ -899,6 +927,9 @@ def vapor_pressure(pressure, mixing_ratio): .. math:: e = p \frac{r}{r + \epsilon} + .. versionchanged:: 1.0 + Renamed ``mixing`` parameter to ``mixing_ratio`` + See Also -------- saturation_vapor_pressure, dewpoint @@ -962,6 +993,10 @@ def dewpoint_from_relative_humidity(temperature, relative_humidity): `pint.Quantity` Dewpoint temperature + + .. versionchanged:: 1.0 + Renamed ``rh`` parameter to ``relative_humidity`` + See Also -------- dewpoint, saturation_vapor_pressure @@ -1000,6 +1035,9 @@ def dewpoint(vapor_pressure): .. math:: T = \frac{243.5 log(e / 6.112)}{17.67 - log(e / 6.112)} + .. versionchanged:: 1.0 + Renamed ``e`` parameter to ``vapor_pressure`` + """ val = np.log(vapor_pressure / sat_pressure_0c) return 0. * units.degC + 243.5 * units.delta_degC * val / (17.67 - val) @@ -1040,6 +1078,9 @@ def mixing_ratio(partial_press, total_press, molecular_weight_ratio=mpconsts.eps .. math:: r = \epsilon \frac{e}{p - e} + .. versionchanged:: 1.0 + Renamed ``part_press``, ``tot_press`` parameters to ``partial_press``, ``total_press`` + See Also -------- saturation_mixing_ratio, vapor_pressure @@ -1077,6 +1118,9 @@ def saturation_mixing_ratio(total_press, temperature): .. math:: r_s = \epsilon \frac{e_s}{p - e_s} + .. versionchanged:: 1.0 + Renamed ``tot_press`` parameter to ``total_press`` + """ return mixing_ratio(saturation_vapor_pressure(temperature), total_press) @@ -1239,6 +1283,9 @@ def virtual_temperature(temperature, mixing_ratio, molecular_weight_ratio=mpcons ----- .. math:: T_v = T \frac{\text{w} + \epsilon}{\epsilon\,(1 + \text{w})} + .. versionchanged:: 1.0 + Renamed ``mixing`` parameter to ``mixing_ratio`` + """ return temperature * ((mixing_ratio + molecular_weight_ratio) / (molecular_weight_ratio * (1 + mixing_ratio))) @@ -1282,6 +1329,9 @@ def virtual_potential_temperature(pressure, temperature, mixing_ratio, ----- .. math:: \Theta_v = \Theta \frac{\text{w} + \epsilon}{\epsilon\,(1 + \text{w})} + .. versionchanged:: 1.0 + Renamed ``mixing`` parameter to ``mixing_ratio`` + """ pottemp = potential_temperature(pressure, temperature) return virtual_temperature(pottemp, mixing_ratio, molecular_weight_ratio) @@ -1324,6 +1374,9 @@ def density(pressure, temperature, mixing_ratio, molecular_weight_ratio=mpconsts ----- .. math:: \rho = \frac{p}{R_dT_v} + .. versionchanged:: 1.0 + Renamed ``mixing`` parameter to ``mixing_ratio`` + """ virttemp = virtual_temperature(temperature, mixing_ratio, molecular_weight_ratio) return (pressure / (mpconsts.Rd * virttemp)).to(units.kilogram / units.meter ** 3) @@ -1366,6 +1419,10 @@ def relative_humidity_wet_psychrometric(pressure, dry_bulb_temperature, wet_bulb * :math:`e` is vapor pressure from the wet psychrometric calculation * :math:`e_s` is the saturation vapor pressure + .. versionchanged:: 1.0 + Changed signature from + ``(dry_bulb_temperature, web_bulb_temperature, pressure, **kwargs)`` + See Also -------- psychrometric_vapor_pressure_wet, saturation_vapor_pressure @@ -1423,6 +1480,10 @@ def psychrometric_vapor_pressure_wet(pressure, dry_bulb_temperature, wet_bulb_te Psychrometer coefficient depends on the specific instrument being used and the ventilation of the instrument. + .. versionchanged:: 1.0 + Changed signature from + ``(dry_bulb_temperature, wet_bulb_temperature, pressure, psychrometer_coefficient)`` + See Also -------- saturation_vapor_pressure @@ -1468,6 +1529,9 @@ def mixing_ratio_from_relative_humidity(pressure, temperature, relative_humidity * :math:`relative_humidity` is relative humidity as a unitless ratio * :math:`w_s` is the saturation mixing ratio + .. versionchanged:: 1.0 + Changed signature from ``(relative_humidity, temperature, pressure)`` + See Also -------- relative_humidity_from_mixing_ratio, saturation_mixing_ratio @@ -1512,6 +1576,9 @@ def relative_humidity_from_mixing_ratio(pressure, temperature, mixing_ratio): * :math:`w` is mixing ratio * :math:`w_s` is the saturation mixing ratio + .. versionchanged:: 1.0 + Changed signature from ``(mixing_ratio, temperature, pressure)`` + See Also -------- mixing_ratio_from_relative_humidity, saturation_mixing_ratio @@ -1629,6 +1696,9 @@ def relative_humidity_from_specific_humidity(pressure, temperature, specific_hum * :math:`q` is specific humidity * :math:`w_s` is the saturation mixing ratio + .. versionchanged:: 1.0 + Changed signature from ``(specific_humidity, temperature, pressure)`` + See Also -------- relative_humidity_from_mixing_ratio @@ -1705,6 +1775,9 @@ def cape_cin(pressure, temperature, dewpoint, parcel_profile, which_lfc='bottom' Since this function returns scalar values when given a profile, this will return Pint Quantities even when given xarray DataArray profiles. + .. versionchanged:: 1.0 + Renamed ``dewpt`` parameter to ``dewpoint`` + See Also -------- lfc, el @@ -1850,6 +1923,9 @@ def most_unstable_parcel(pressure, temperature, dewpoint, height=None, Since this function returns scalar values when given a profile, this will return Pint Quantities even when given xarray DataArray profiles. + .. versionchanged:: 1.0 + Renamed ``heights`` parameter to ``height`` + """ p_layer, t_layer, td_layer = get_layer(pressure, temperature, dewpoint, bottom=bottom, depth=depth, height=height, interpolate=False) @@ -1915,6 +1991,9 @@ def isentropic_interpolation(levels, pressure, temperature, *args, vertical_dim= Will only return Pint Quantities, even when given xarray DataArray profiles. To obtain a xarray Dataset instead, use `isentropic_interpolation_as_dataset` instead. + .. versionchanged:: 1.0 + Renamed ``theta_levels``, ``axis`` parameters to ``levels``, ``vertical_dim`` + See Also -------- potential_temperature, isentropic_interpolation_as_dataset @@ -2344,6 +2423,10 @@ def mixed_parcel(pressure, temperature, dewpoint, parcel_start_pressure=None, Since this function returns scalar values when given a profile, this will return Pint Quantities even when given xarray DataArray profiles. + .. versionchanged:: 1.0 + Renamed ``p``, ``dewpt``, ``heights`` parameters to + ``pressure``, ``dewpoint``, ``height`` + """ # If a parcel starting pressure is not provided, use the surface if not parcel_start_pressure: @@ -2415,6 +2498,9 @@ def mixed_layer(pressure, *args, height=None, bottom=None, depth=100 * units.hPa Since this function returns scalar values when given a profile, this will return Pint Quantities even when given xarray DataArray profiles. + .. versionchanged:: 1.0 + Renamed ``p``, ``heights`` parameters to ``pressure``, ``height`` + """ layer = get_layer(pressure, *args, height=height, bottom=bottom, depth=depth, interpolate=interpolate) @@ -2458,6 +2544,10 @@ def dry_static_energy(height, temperature): `pint.Quantity` Dry static energy + + .. versionchanged:: 1.0 + Renamed ``heights`` parameter to ``height`` + See Also -------- montgomery_streamfunction @@ -2478,14 +2568,6 @@ def moist_static_energy(height, temperature, specific_humidity): This function will calculate the moist static energy following equation 3.72 in [Hobbs2006]_. - Notes - ----- - .. math::\text{moist static energy} = c_{pd} * T + gz + L_v q - - * :math:`T` is temperature - * :math:`z` is height - * :math:`q` is specific humidity - Parameters ---------- height : `pint.Quantity` @@ -2502,6 +2584,17 @@ def moist_static_energy(height, temperature, specific_humidity): `pint.Quantity` Moist static energy + Notes + ----- + .. math::\text{moist static energy} = c_{pd} * T + gz + L_v q + + * :math:`T` is temperature + * :math:`z` is height + * :math:`q` is specific humidity + + .. versionchanged:: 1.0 + Renamed ``heights`` parameter to ``height`` + """ return (dry_static_energy(height, temperature) + mpconsts.Lv * specific_humidity.to('dimensionless')).to('kJ/kg') @@ -2562,6 +2655,9 @@ def thickness_hydrostatic(pressure, temperature, mixing_ratio=None, Since this function returns scalar values when given a profile, this will return Pint Quantities even when given xarray DataArray profiles. + .. versionchanged:: 1.0 + Renamed ``mixing`` parameter to ``mixing_ratio`` + """ # Get the data for the layer, conditional upon bottom/depth being specified and mixing # ratio being given @@ -2683,6 +2779,10 @@ def brunt_vaisala_frequency_squared(height, potential_temperature, vertical_dim= `height` and `potential_temperature` arguments are given as `xarray.DataArray`, in which case will be `xarray.DataArray`. + + .. versionchanged:: 1.0 + Renamed ``heights``, ``axis`` parameters to ``height``, ``vertical_dim`` + See Also -------- brunt_vaisala_frequency, brunt_vaisala_period, potential_temperature @@ -2735,6 +2835,10 @@ def brunt_vaisala_frequency(height, potential_temperature, vertical_dim=0): `height` and `potential_temperature` arguments are given as `xarray.DataArray`, in which case will be `xarray.DataArray`. + + .. versionchanged:: 1.0 + Renamed ``heights``, ``axis`` parameters to ``height``, ``vertical_dim`` + See Also -------- brunt_vaisala_frequency_squared, brunt_vaisala_period, potential_temperature @@ -2782,6 +2886,9 @@ def brunt_vaisala_period(height, potential_temperature, vertical_dim=0): which case will be `xarray.DataArray`. + .. versionchanged:: 1.0 + Renamed ``heights``, ``axis`` parameters to ``height``, ``vertical_dim`` + See Also -------- brunt_vaisala_frequency, brunt_vaisala_frequency_squared, potential_temperature @@ -2886,6 +2993,10 @@ def static_stability(pressure, temperature, vertical_dim=0): `pint.Quantity` The profile of static stability + + .. versionchanged:: 1.0 + Renamed ``axis`` parameter ``vertical_dim`` + """ theta = potential_temperature(pressure, temperature) @@ -2921,6 +3032,10 @@ def dewpoint_from_specific_humidity(pressure, temperature, specific_humidity): `pint.Quantity` Dew point temperature + + .. versionchanged:: 1.0 + Changed signature from ``(specific_humidity, temperature, pressure)`` + See Also -------- relative_humidity_from_mixing_ratio, dewpoint_from_relative_humidity @@ -3048,6 +3163,10 @@ def specific_humidity_from_dewpoint(pressure, dewpoint): `pint.Quantity` Specific humidity + + .. versionchanged:: 1.0 + Changed signature from ``(dewpoint, pressure)`` + See Also -------- mixing_ratio, saturation_mixing_ratio diff --git a/src/metpy/calc/tools.py b/src/metpy/calc/tools.py index c2910f7cea7..078c6c8510a 100644 --- a/src/metpy/calc/tools.py +++ b/src/metpy/calc/tools.py @@ -456,6 +456,9 @@ def get_layer_heights(height, depth, *args, bottom=None, interpolate=True, with_ Only functions on 1D profiles (not higher-dimension vertical cross sections or grids). Also, this will return Pint Quantities even when given xarray DataArray profiles. + .. versionchanged:: 1.0 + Renamed ``heights`` parameter to ``height`` + """ # Make sure pressure and datavars are the same length for datavar in args: @@ -557,6 +560,9 @@ def get_layer(pressure, *args, height=None, bottom=None, depth=100 * units.hPa, Only functions on 1D profiles (not higher-dimension vertical cross sections or grids). Also, this will return Pint Quantities even when given xarray DataArray profiles. + .. versionchanged:: 1.0 + Renamed ``heights`` parameter to ``height`` + """ # If we get the depth kwarg, but it's None, set it to the default as well if depth is None: @@ -800,6 +806,9 @@ def lat_lon_grid_deltas(longitude, latitude, x_dim=-1, y_dim=-2, geod=None): This function will only return `pint.Quantity` arrays (not `xarray.DataArray` or another array-like type). It will also "densify" your data if using Dask or lazy-loading. + .. versionchanged:: 1.0 + Changed signature from ``(longitude, latitude, **kwargs)`` + """ # Inputs must be the same number of dimensions if latitude.ndim != longitude.ndim: @@ -966,6 +975,10 @@ def first_derivative(f, axis=None, x=None, delta=None): array-like The first derivative calculated along the selected axis + + .. versionchanged:: 1.0 + Changed signature from ``(f, **kwargs)`` + See Also -------- second_derivative @@ -1056,6 +1069,10 @@ def second_derivative(f, axis=None, x=None, delta=None): array-like The second derivative calculated along the selected axis + + .. versionchanged:: 1.0 + Changed signature from ``(f, **kwargs)`` + See Also -------- first_derivative @@ -1141,15 +1158,18 @@ def gradient(f, axes=None, coordinates=None, deltas=None): tuple of array-like The first derivative calculated along each specified axis of the original array - See Also - -------- - laplacian, first_derivative - Notes ----- If this function is used without the `axes` parameter, the length of `coordinates` or `deltas` (as applicable) should match the number of dimensions of `f`. + .. versionchanged:: 1.0 + Changed signature from ``(f, **kwargs)`` + + See Also + -------- + laplacian, first_derivative + """ pos_kwarg, positions, axes = _process_gradient_args(f, axes, coordinates, deltas) return tuple(first_derivative(f, axis=axis, **{pos_kwarg: positions[ind]}) @@ -1192,15 +1212,18 @@ def laplacian(f, axes=None, coordinates=None, deltas=None): array-like The laplacian - See Also - -------- - gradient, second_derivative - Notes ----- If this function is used without the `axes` parameter, the length of `coordinates` or `deltas` (as applicable) should match the number of dimensions of `f`. + .. versionchanged:: 1.0 + Changed signature from ``(f, **kwargs)`` + + See Also + -------- + gradient, second_derivative + """ pos_kwarg, positions, axes = _process_gradient_args(f, axes, coordinates, deltas) derivs = [second_derivative(f, axis=axis, **{pos_kwarg: positions[ind]}) diff --git a/src/metpy/units.py b/src/metpy/units.py index f50f87c89fd..8e172d18da2 100644 --- a/src/metpy/units.py +++ b/src/metpy/units.py @@ -196,6 +196,12 @@ def _check_argument_units(args, defaults, dimensionality): yield arg, 'none', need +def _get_changed_version(docstring): + """Find the most recent version in which the docs say a function changed.""" + matches = re.findall(r'.. versionchanged:: ([\d.]+)', docstring) + return max(matches) if matches else None + + def check_units(*units_by_pos, **units_by_name): """Create a decorator to check units of function arguments.""" def dec(func): @@ -228,7 +234,14 @@ def wrapper(*args, **kwargs): if 'none' in msg: msg += ('\nAny variable `x` can be assigned a unit as follows:\n' ' from metpy.units import units\n' - ' x = x * units.meter / units.second') + ' x = units.Quantity(x, "m/s")') + + # If function has changed, mention that fact + if func.__doc__: + changed_version = _get_changed_version(func.__doc__) + if changed_version: + msg = (f'This function changed in {changed_version}--double check ' + 'that the function is being called properly.\n') + msg raise ValueError(msg) return func(*args, **kwargs) diff --git a/tests/calc/test_thermo.py b/tests/calc/test_thermo.py index b2697af1e58..11e25c786fc 100644 --- a/tests/calc/test_thermo.py +++ b/tests/calc/test_thermo.py @@ -1475,7 +1475,7 @@ def test_static_stability_cross_section(): def test_dewpoint_specific_humidity(): - """Test relative humidity from specific humidity.""" + """Test dewpoint from specific humidity.""" p = 1013.25 * units.mbar temperature = 20. * units.degC q = 0.012 * units.dimensionless @@ -1483,6 +1483,15 @@ def test_dewpoint_specific_humidity(): assert_almost_equal(td, 16.973 * units.degC, 3) +def test_dewpoint_specific_humidity_old_signature(): + """Test dewpoint from specific humidity using old signature issues specific error.""" + p = 1013.25 * units.mbar + temperature = 20. * units.degC + q = 0.012 * units.dimensionless + with pytest.raises(ValueError, match='changed in 1.0'): + dewpoint_from_specific_humidity(q, temperature, p) + + def test_lfc_not_below_lcl(): """Test sounding where LFC appears to be (but isn't) below LCL.""" levels = np.array([1002.5, 1001.7, 1001., 1000.3, 999.7, 999., 998.2, 977.9,