ARM-DOE / pyart

The Python-ARM Radar Toolkit. A data model driven interactive toolkit for working with weather radar data.
https://arm-doe.github.io/pyart/
Other
513 stars 266 forks source link

BUG: vad_michelson produces strange, apparently incorrect results on Py-ART 1.14.2+ #1426

Closed CAM-Gerlach closed 1 year ago

CAM-Gerlach commented 1 year ago

Description

In in Py-ART 1.14.2 and above, up to and including 1.15.0, the pyart.retrieve.vad_michelson function produces strange and apparently incorrect results, with much too high and variable wind speeds, on both raw and corrected NEXRAD and MAX data, including some with indicated wind speeds on the order of many hundreds to even thousands of meters per second.

By contrast, in Py-ART 1.14.1 and below, the VAD wind profiles match the actual data and the expected results much more closely. I don't see where such an intentional change is documented in the release notes, nor does this appear to be the same issue as that discussed in #992 (given it only occurred recently, and results in the values being too high and variable rather than too low.

We've confirmed this on multiple files, including this sample one in the reproducer below and the sole change to the environment that causes the problem to reproduce or not is the Py-ART version, rather than any dependencies or other changes. This was tested in a brand new conda environment just freshly created today with only Py-ART (and Spyder-kernels) installed.

What I Did

Here's a minimal reproducer that produces drastically different results on Py-ART 1.14.1 vs. 1.14.2 on the same file (a KJAX WSR-88D volume scan, in this instance, which I've attached)

import pyart
import matplotlib.pyplot as plt
import numpy as np

radar = pyart.io.read('cfradial.20080822_1502_VolScan_KJAX_SUR.nc')
vad = pyart.retrieve.vad_michelson(radar, vel_field='velocity')

fig = plt.figure(figsize=(5,8))
ax = fig.add_subplot(111)
ax.plot(vad.speed, vad.height)
plt.title('KJAX VAD from 22 Aug. 2008 at 1502 Z - Velocity')
ax.set_xlabel('Wind Speed [m/s]')
ax.set_ylabel('Height [AGL]')
ax.set_xlim(0, np.nanmax(vad.speed) + 2)

Expected/Actual

Expected (Py-ART 1.14.1) Actual (Py-ART 1.14.2)
image image

To note, the printed output from running the function is the same as the Expected case, for what that's worth. It was only the returned values that were different.

Conda list output

Conda list output of an affected environment ``` # packages in environment at C:\Users\Owner\miniforge3\envs\pyart: # # Name Version Build Channel aiobotocore 2.5.0 pyhd8ed1ab_0 conda-forge aiohttp 3.8.4 py311ha68e1ae_0 conda-forge aioitertools 0.11.0 pyhd8ed1ab_0 conda-forge aiosignal 1.3.1 pyhd8ed1ab_0 conda-forge arm_pyart 1.15.0 py311ha68e1ae_1 conda-forge asttokens 2.2.1 pyhd8ed1ab_0 conda-forge async-timeout 4.0.2 pyhd8ed1ab_0 conda-forge attrs 23.1.0 pyh71513ae_1 conda-forge backcall 0.2.0 pyh9f0ad1d_0 conda-forge backports 1.0 pyhd8ed1ab_3 conda-forge backports.functools_lru_cache 1.6.4 pyhd8ed1ab_0 conda-forge blosc 1.21.3 hdccc3a2_0 conda-forge botocore 1.29.76 pyhd8ed1ab_0 conda-forge brotli 1.0.9 hcfcfb64_8 conda-forge brotli-bin 1.0.9 hcfcfb64_8 conda-forge brotlipy 0.7.0 py311ha68e1ae_1005 conda-forge bzip2 1.0.8 h8ffe710_4 conda-forge ca-certificates 2023.5.7 h56e8100_0 conda-forge certifi 2023.5.7 pyhd8ed1ab_0 conda-forge cffi 1.15.1 py311h7d9ee11_3 conda-forge cftime 1.6.2 py311h59ca53f_1 conda-forge charset-normalizer 2.1.1 pyhd8ed1ab_0 conda-forge cloudpickle 2.2.1 pyhd8ed1ab_0 conda-forge colorama 0.4.6 pyhd8ed1ab_0 conda-forge comm 0.1.3 pyhd8ed1ab_0 conda-forge contourpy 1.0.7 py311h005e61a_0 conda-forge cryptography 40.0.2 py311h28e9c30_0 conda-forge curl 8.0.1 h68f0423_0 conda-forge cycler 0.11.0 pyhd8ed1ab_0 conda-forge cython 0.29.34 py311h12c1d0e_0 conda-forge debugpy 1.6.7 py311h12c1d0e_0 conda-forge decorator 5.1.1 pyhd8ed1ab_0 conda-forge executing 1.2.0 pyhd8ed1ab_0 conda-forge fonttools 4.39.4 py311ha68e1ae_0 conda-forge freetype 2.12.1 h546665d_1 conda-forge frozenlist 1.3.3 py311ha68e1ae_0 conda-forge fsspec 2023.5.0 pyh1a96a4e_0 conda-forge hdf4 4.2.15 h1334946_6 conda-forge hdf5 1.14.0 nompi_h918d9b7_103 conda-forge idna 3.4 pyhd8ed1ab_0 conda-forge importlib-metadata 6.6.0 pyha770c72_0 conda-forge importlib_metadata 6.6.0 hd8ed1ab_0 conda-forge intel-openmp 2023.1.0 h57928b3_46319 conda-forge ipykernel 6.23.0 pyh025b116_0 conda-forge ipython 8.13.2 pyh08f2357_0 conda-forge jedi 0.18.2 pyhd8ed1ab_0 conda-forge jmespath 1.0.1 pyhd8ed1ab_0 conda-forge jupyter_client 8.2.0 pyhd8ed1ab_0 conda-forge jupyter_core 5.3.0 py311h1ea47a8_0 conda-forge kiwisolver 1.4.4 py311h005e61a_1 conda-forge krb5 1.20.1 heb0366b_0 conda-forge lcms2 2.15 h3e3b177_1 conda-forge lerc 4.0.0 h63175ca_0 conda-forge libaec 1.0.6 h63175ca_1 conda-forge libblas 3.9.0 16_win64_mkl conda-forge libbrotlicommon 1.0.9 hcfcfb64_8 conda-forge libbrotlidec 1.0.9 hcfcfb64_8 conda-forge libbrotlienc 1.0.9 hcfcfb64_8 conda-forge libcblas 3.9.0 16_win64_mkl conda-forge libcurl 8.0.1 h68f0423_0 conda-forge libdeflate 1.18 hcfcfb64_0 conda-forge libexpat 2.5.0 h63175ca_1 conda-forge libffi 3.4.2 h8ffe710_5 conda-forge libhwloc 2.9.1 h51c2c0f_0 conda-forge libiconv 1.17 h8ffe710_0 conda-forge libjpeg-turbo 2.1.5.1 hcfcfb64_0 conda-forge liblapack 3.9.0 16_win64_mkl conda-forge libnetcdf 4.9.2 nompi_hc664c2b_104 conda-forge libpng 1.6.39 h19919ed_0 conda-forge libsodium 1.0.18 h8d14728_1 conda-forge libsqlite 3.41.2 hcfcfb64_1 conda-forge libssh2 1.10.0 h9a1e1f7_3 conda-forge libtiff 4.5.0 h6c8260b_6 conda-forge libwebp-base 1.3.0 hcfcfb64_0 conda-forge libxcb 1.13 hcd874cb_1004 conda-forge libxml2 2.10.4 hc3477c8_0 conda-forge libzip 1.9.2 h519de47_1 conda-forge libzlib 1.2.13 hcfcfb64_4 conda-forge lz4-c 1.9.4 hcfcfb64_0 conda-forge m2w64-gcc-libgfortran 5.3.0 6 conda-forge m2w64-gcc-libs 5.3.0 7 conda-forge m2w64-gcc-libs-core 5.3.0 7 conda-forge m2w64-gmp 6.1.0 2 conda-forge m2w64-libwinpthread-git 5.0.0.4634.697f757 2 conda-forge matplotlib-base 3.7.1 py311h6e989c2_0 conda-forge matplotlib-inline 0.1.6 pyhd8ed1ab_0 conda-forge mkl 2022.1.0 h6a75c08_874 conda-forge msys2-conda-epoch 20160418 1 conda-forge multidict 6.0.4 py311ha68e1ae_0 conda-forge munkres 1.1.4 pyh9f0ad1d_0 conda-forge nest-asyncio 1.5.6 pyhd8ed1ab_0 conda-forge netcdf4 1.6.3 nompi_py311h896b27b_102 conda-forge numpy 1.24.3 py311h0b4df5a_0 conda-forge openjpeg 2.5.0 ha2aaf27_2 conda-forge openssl 3.1.0 hcfcfb64_3 conda-forge packaging 23.1 pyhd8ed1ab_0 conda-forge pandas 2.0.1 py311hf63dbb6_1 conda-forge parso 0.8.3 pyhd8ed1ab_0 conda-forge pickleshare 0.7.5 py_1003 conda-forge pillow 9.5.0 py311hc67b2de_0 conda-forge pip 23.1.2 pyhd8ed1ab_0 conda-forge platformdirs 3.5.0 pyhd8ed1ab_0 conda-forge pooch 1.7.0 pyha770c72_3 conda-forge prompt-toolkit 3.0.38 pyha770c72_0 conda-forge prompt_toolkit 3.0.38 hd8ed1ab_0 conda-forge psutil 5.9.5 py311ha68e1ae_0 conda-forge pthread-stubs 0.4 hcd874cb_1001 conda-forge pthreads-win32 2.9.1 hfa6e2cd_3 conda-forge pure_eval 0.2.2 pyhd8ed1ab_0 conda-forge pycparser 2.21 pyhd8ed1ab_0 conda-forge pygments 2.15.1 pyhd8ed1ab_0 conda-forge pyopenssl 23.1.1 pyhd8ed1ab_0 conda-forge pyparsing 3.0.9 pyhd8ed1ab_0 conda-forge pysocks 1.7.1 pyh0701188_6 conda-forge python 3.11.3 h2628c8c_0_cpython conda-forge python-dateutil 2.8.2 pyhd8ed1ab_0 conda-forge python-tzdata 2023.3 pyhd8ed1ab_0 conda-forge python_abi 3.11 3_cp311 conda-forge pytz 2023.3 pyhd8ed1ab_0 conda-forge pywin32 304 py311h12c1d0e_2 conda-forge pyzmq 25.0.2 py311h7b3f143_0 conda-forge requests 2.29.0 pyhd8ed1ab_0 conda-forge s3fs 2023.5.0 pyhd8ed1ab_0 conda-forge scipy 1.10.1 py311h37ff6ca_2 conda-forge setuptools 67.7.2 pyhd8ed1ab_0 conda-forge setuptools-scm 7.1.0 pyhd8ed1ab_0 conda-forge setuptools_scm 7.1.0 hd8ed1ab_0 conda-forge six 1.16.0 pyh6c4a22f_0 conda-forge snappy 1.1.10 hfb803bf_0 conda-forge spyder-kernels 2.4.3 win_pyhd8ed1ab_0 conda-forge stack_data 0.6.2 pyhd8ed1ab_0 conda-forge tbb 2021.9.0 h91493d7_0 conda-forge tk 8.6.12 h8ffe710_0 conda-forge tomli 2.0.1 pyhd8ed1ab_0 conda-forge tornado 6.3 py311ha68e1ae_0 conda-forge traitlets 5.9.0 pyhd8ed1ab_0 conda-forge typing-extensions 4.5.0 hd8ed1ab_0 conda-forge typing_extensions 4.5.0 pyha770c72_0 conda-forge tzdata 2023c h71feb2d_0 conda-forge ucrt 10.0.22621.0 h57928b3_0 conda-forge urllib3 1.26.15 pyhd8ed1ab_0 conda-forge vc 14.3 hb25d44b_16 conda-forge vc14_runtime 14.34.31931 h5081d32_16 conda-forge versioneer 0.28 pyhd8ed1ab_0 conda-forge vs2015_runtime 14.34.31931 hed1258a_16 conda-forge wcwidth 0.2.6 pyhd8ed1ab_0 conda-forge wheel 0.40.0 pyhd8ed1ab_0 conda-forge win_inet_pton 1.1.0 pyhd8ed1ab_6 conda-forge wrapt 1.15.0 py311ha68e1ae_0 conda-forge xarray 2023.4.2 pyhd8ed1ab_0 conda-forge xorg-libxau 1.0.9 hcd874cb_0 conda-forge xorg-libxdmcp 1.1.3 hcd874cb_0 conda-forge xz 5.2.6 h8d14728_0 conda-forge yarl 1.9.1 py311ha68e1ae_0 conda-forge zeromq 4.3.4 h0e60522_1 conda-forge zipp 3.15.0 pyhd8ed1ab_0 conda-forge zstd 1.5.2 h12be248_6 conda-forge ```

Version 1.14.2-py311ha68e1ae_0 was also affected, while 1.14.1-py311ha68e1ae_0 was confirmed okay.

Let us know if there's anything else you need from our end. Thanks!

zssherman commented 1 year ago

@CAM-Gerlach Hmm, yeah that's very interesting. As you stated, yeah nothing has been changed besides a warning removal. I'm wondering if there is a dependency issue or a dependency updated how nans or masked values are being handled and is causing issues... @mgrover1 thoughts?

mgrover1 commented 1 year ago

Yeah, I suspect it is to do with with how the booleans (masked values) are being handled. I will dig into this.

mgrover1 commented 1 year ago

Thank you for catching this @CAM-Gerlach - during our formatting changes, a logical argument was changed and caused this issue... a fix is implemented in #1428 and we will be sure to cut a new release with this bug fix.

CAM-Gerlach commented 1 year ago

Thanks for the fix!