Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AMAROC-819 Add support for numpy >2.0 #129

Merged
merged 3 commits into from
Jun 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- [regDaniel, 2024-04-09] Minor adaptions to better comply with PEP standards.
- [fpavogt, 2024-03-26] Use "height" in "ft aal" throughout.
### Changed:
- [fpavogt, 2024-06-25] Add support for numpy >2.0
- [fpavogt, 2024-04-28] Add a rogue point to the mock example.
- [fpavogt, 2024-03-25] Set the fluffiness boost to 2 (fixes #123).
- [fpavogt, 2024-03-23] Changed default mock dataset to be 900s long (instead of 2400s).
Expand Down
13 changes: 11 additions & 2 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,19 @@ Welcome to the ampycloud documentation
--------------------------------------

* **What:** ampycloud refers to both a **Python package** and the **algorithm** at its core, designed
to characterize cloud layers (i.e. height and sky coverage fraction) using ceilometer measurements
(i.e. automatic cloud base *hits*), and derive a corresponding METAR-like message.
to characterize cloud layers (i.e. sky coverage fraction and base height) using ceilometer measurements
(i.e. cloud base *hits*), and derive a corresponding METAR-like message.
A visual illustration of the algorithm is visible in :numref:`fig-demo`.

.. note::
At the moment, ampycloud **cannot** use backscatter profiles to derive cloud base hits independantly.

.. note::
ampycloud does not challenge the quality/nature of the cloud base hits that it is being provided.
It trusts them all fully and equally. The capacity of the algorithm to provide an accurate
assessment of cloud layers above an aerodrome is thus directly limited by the ability of
ceilometers to report clouds up to the aerodrome's Minimum Sector Altitude in the first place.

* **Where:** ampycloud lives in `a dedicated repository <https://github.com/MeteoSwiss/ampycloud>`_
under the `MeteoSwiss organization <https://github.com/MeteoSwiss>`_ on Github, where you can
submit all your `questions <https://github.com/MeteoSwiss/ampycloud/discussions>`_ and
Expand Down
4 changes: 2 additions & 2 deletions docs/source/running.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ A no-words example for those that want to get started quickly
The input data
--------------

The ampycloud algorithm is meant to process cloud base *hits* from ceilometer observations. A given
set of hits to be processed by the ampycloud package must be stored inside a
The ampycloud algorithm is meant to process cloud base *hits* derived from ceilometer observations.
A given set of hits to be processed by the ampycloud package must be stored inside a
:py:class:`pandas.DataFrame` with a specific set of characteristics outlined below. Users can use
the following utility function to check whether a given :py:class:`pandas.DataFrame` meets all the
requirements of ampycloud.
Expand Down
10 changes: 5 additions & 5 deletions docs/source/scope.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ which requires all its dependencies to be robust and stable.

This has the following implications for ampycloud:

* The scope of ampycloud will remain limited to the **automatic processing of ceilometer
hits**. In particular, ampycloud does not process Vertical Visibility (VV) measurements.
Depending on the ceilometer type, the user will need to decide how to treat VV hits *before*
passing them to ampycloud, e.g. by removing them or by converting them to cloud base
heights.
* The scope of ampycloud will remain limited to the **automatic processing of cloud base
hits derived using ceilometers**. Furthermore, ampycloud does not process
Vertical Visibility (VV) measurements. Depending on the ceilometer type, the user will need
to decide how to treat VV hits *before* passing them to ampycloud, e.g. by removing them or
by converting them to cloud base heights.

* Note that regulation says that "if there are no clouds of operational significance
and no restriction on vertical visibility and the abbreviation 'CAVOK' is not
Expand Down
2 changes: 1 addition & 1 deletion src/ampycloud/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -1047,7 +1047,7 @@ def metar_msg(self, which: str = 'layers') -> str:

# Deal with the MSA: set it to infinity if None was specified
if self.msa is None:
msa_val = np.infty
msa_val = np.inf
else:
msa_val = self.msa

Expand Down
4 changes: 2 additions & 2 deletions src/ampycloud/scaler.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,11 +154,11 @@ def step_scale(vals: np.ndarray,
offsets = [0] + steps

# Get the bin edges for the scale mode
edges_in = [-np.infty] + steps + [np.infty]
edges_in = [-np.inf] + steps + [np.inf]
# Idem for the descale mode ... this is more complex because of the continuity requirement
edges_out = [steps[0]/scales[0] + np.sum((np.diff(steps)/scales[1:-1])[:ind])
for ind in range(len(steps))]
edges_out = [-np.infty] + edges_out + [np.infty]
edges_out = [-np.inf] + edges_out + [np.inf]

# Prepare the output
out = np.full_like(vals, np.nan, dtype=float)
Expand Down
4 changes: 2 additions & 2 deletions src/ampycloud/utils/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,10 +185,10 @@ def check_data_consistency(pdf: pd.DataFrame,
msgs += ['Some type=0 hits have non-NaNs height values ?!']
if np.any(np.isnan(data.loc[data.type == 1, 'height'])):
msgs += ['Some type=1 hits have NaNs height values ?!']
if not np.all(np.in1d(data.loc[data.type == 2, 'dt'].values,
if not np.all(np.isin(data.loc[data.type == 2, 'dt'].values,
data.loc[data.type == 1, 'dt'].values)):
msgs += ['Some type=2 hits have no coincident type=1 hits ?!']
if not np.all(np.in1d(data.loc[data.type == 3, 'dt'].values,
if not np.all(np.isin(data.loc[data.type == 3, 'dt'].values,
data.loc[data.type == 2, 'dt'].values)):
msgs += ['Some type=3 hits have no coincident type=2 hits ?!']

Expand Down