Skip to content

Feature/b2i marine and testing#50

Open
givelberg wants to merge 6 commits intofeature/marine_obs_builderfrom
feature/b2i-marine-and-testing
Open

Feature/b2i marine and testing#50
givelberg wants to merge 6 commits intofeature/marine_obs_builderfrom
feature/b2i-marine-and-testing

Conversation

@givelberg
Copy link
Copy Markdown

  1. basic testing framework for spoc
  2. specific testing for marine b2i converters
  3. b2i converters

@givelberg givelberg self-assigned this Jun 11, 2025
Comment thread dump/mapping/__init__.py Outdated
Copy link
Copy Markdown

@ilianagenkova ilianagenkova left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am approving this PR despite my limited understanding of SPOC. I have not tested the code.

Comment thread dump/mapping/bufr_marine_insitu_config.py
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like the satwnd processing is more unified now, and the "obstype" drives the show? (therefore lots of code was deleted). Am I correct?

@rmclaren rmclaren changed the base branch from develop to feature/marine_obs_builder June 12, 2025 03:55
@rmclaren
Copy link
Copy Markdown
Collaborator

Changed the base the the feature/marine_obs_builder branch. Once we merge into there we can merge into feature/obs_builder.

Copy link
Copy Markdown
Collaborator

@rmclaren rmclaren left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't checked everything yet. Still need to review the test framework and related files.

Comment thread dump/mapping/bufr_marine_insitu_obs_builder.py Outdated
Comment on lines +130 to +157
mask &= (lat >= -90) & (lat <= 90) & ~np.isnan(lat)

# Validate longitude: all in [-180, 180] or all in [0, 360]
valid_lons = lon[mask] # Longitudes where lat is valid
if len(valid_lons) == 0:
return mask

# Check longitude range consistency
in_neg180_180 = (valid_lons >= -180) & (valid_lons <= 180)
in_0_360 = (valid_lons >= 0) & (valid_lons <= 360)

# Determine if all valid longitudes are in one range
all_neg180_180 = np.all(in_neg180_180)
all_0_360 = np.all(in_0_360)

# If neither range is fully consistent, use dominant range
# if the fraction of the "other" range is too large,
# probably needs to throw an error
if not (all_neg180_180 or all_0_360):
if np.sum(in_neg180_180) >= np.sum(in_0_360):
mask &= (lon >= -180) & (lon <= 180)
else:
mask &= (lon >= 0) & (lon <= 360)
else:
if all_neg180_180:
mask &= (lon >= -180) & (lon <= 180)
else:
mask &= (lon >= 0) & (lon <= 360)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In your YAML file (mapping file), use transforms wrap to [-180, 180]. This will make this code uneccessary.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you getting values outside of the proper ranges (excluding missing values)?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, it happened once.

Comment on lines +104 to +118
# Handle undefined or None inputs
if lat is None or lon is None:
return np.array([], dtype=bool)

# Convert inputs to NumPy arrays, preserving masked arrays
try:
lat = np.asarray(lat, dtype=float)
lon = np.asarray(lon, dtype=float)
except (ValueError, TypeError):
return np.zeros_like(lat, dtype=bool)

# Ensure arrays have the same shape
# probably needs to throw an exception
if lat.shape != lon.shape:
return np.zeros_like(lat, dtype=bool)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All these checks should be unneccesary as the data container guarntees these things.

Comment thread dump/mapping/bufr_marine_insitu_obs_builder.py Outdated
Comment on lines +108 to +113
# Convert inputs to NumPy arrays, preserving masked arrays
try:
lat = np.asarray(lat, dtype=float)
lon = np.asarray(lon, dtype=float)
except (ValueError, TypeError):
return np.zeros_like(lat, dtype=bool)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why? ma masked arrays ARE numpy arrays. I would not do this...

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code deletes the masks... missing values are already indicated in the mask.

mask &= (lon >= 0) & (lon <= 360)

# Ensure no NaN in longitude
mask &= ~np.isnan(lon)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

? does this happen

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, happened once




def clean_lat_lon(lat, lon):
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

name

Comment thread dump/mapping/bufr_marine_insitu_obs_builder.py Outdated
Comment thread dump/mapping/bufr_marine_insitu_obs_builder.py Outdated
Comment thread test/marine/b2i_config.py
)


class Bufr2iodaConfig:
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should probably be GdasAppConfig.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needs to be cleaned; contains unnecessary code

@rmclaren rmclaren requested review from emilyhcliu and removed request for emilyhcliu June 17, 2025 16:56
Copy link
Copy Markdown
Collaborator

@rmclaren rmclaren left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some more comments

Comment on lines +60 to +68
# print("BBBBBBBBBBBBBBBBBBB")
# print(buoy_mask)
# print(temp_mask.size)
# print(buoy_type.size)
# print(buoy_mask.size)
# print(np.count_nonzero(buoy_mask))
# print(np.count_nonzero(temp_mask))
# print("BBBBBBBBBBBBBBBBBBB")
# container.apply_mask(buoy_mask & temp_mask)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove commented out code.


# rpid = stationID: string array (e.g., 'A8xxx')
# buoy_type: int array (e.g., 1, 2, 3), etc.
drifter_mask = np.isin(buoy_type, drifter_buoy_types, assume_unique=True)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Usage of the assume_unique=True flag is not recommended here as bouy_type array will definitely have duplicate values. Under certain circumstances this can lead to unexpected results.


# Handle masked (missing) BUYT values
# If BUYT is masked, assume not a drifter unless RPID suggests otherwise
drifter_mask = np.where(buoy_type.mask, rpid_drifter_mask, drifter_mask)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be drifter_mask = drifter_mask & ~bouy_type.mask, basically mask out the values when the bouy_type mask is a "missing" element.

Comment on lines 38 to -39
print(np.count_nonzero(buoy_mask))
print(np.count_nonzero(temp_mask))
print("BBBBBBBBBBBBBBBBBBB")
# container.apply_mask(buoy_mask & temp_mask)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please delete debug print statements

Comment thread test/marine/b2i_config.py
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gdas_config.py ?

Comment thread test/marine/b2i_tests.py
from dataclasses import dataclass


OCEAN_BASIN_FILE = "/work/noaa/global/glopara/fix/gdas/soca/20240802/common/RECCAP2_region_masks_all_v20221025.nc"
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hard coded path string... this will only work on Orion and Hercules HPCs...

I think the right way to handle this is to add the project "https://github.com/RECCAP2-ocean/R2-shared-resources" as a submodule to this project. This way it would be platform independent...

@rmclaren
Copy link
Copy Markdown
Collaborator

DId you mean to check in "spoc-tests.yaml"?

@rmclaren
Copy link
Copy Markdown
Collaborator

rmclaren commented Sep 9, 2025

Please remove code related to testing from this branch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants