Skip to content

Add delft3D to datacube converter#1

Open
yukms wants to merge 8 commits into
sandpiper-toolchain:mainfrom
yukms:main
Open

Add delft3D to datacube converter#1
yukms wants to merge 8 commits into
sandpiper-toolchain:mainfrom
yukms:main

Conversation

@yukms
Copy link
Copy Markdown

@yukms yukms commented Mar 11, 2026

No description provided.

Copilot AI review requested due to automatic review settings March 11, 2026 23:08
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a Delft3D (TRIM NetCDF) → Sandplover DataCube conversion utility under render/, along with a companion notebook demonstrating usage.

Changes:

  • Add Delft3DConverter to extract key Delft3D variables and write a NetCDF-formatted cube.
  • Add an example Jupyter notebook documenting and running the conversion workflow.
  • Add render/ documentation + license file (plus unintended .DS_Store artifacts).

Reviewed changes

Copilot reviewed 4 out of 6 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
render/Delft3D_to_datacube/delft3d_converter.py Implements Delft3D → DataCube conversion and NetCDF export.
render/Delft3D_to_datacube/create_datacube_from_Delft3D.ipynb Demonstrates running the converter and describes produced variables.
render/README.md Documents the purpose of the render/ tools directory.
render/LICENSE Adds a GPLv3 license copy within render/.
render/.DS_Store Unintended macOS metadata file added to repo.
.DS_Store Unintended macOS metadata file added to repo.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +222 to +224
# Delete existing file if needed
if os.path.exists(output_path) and overwrite:
os.remove(output_path)
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

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

overwrite=False currently doesn’t prevent overwriting an existing file: if output_path exists and overwrite is false, the code falls through and later to_netcdf will still write with the default overwrite mode. Add an explicit guard (raise if the file exists) or pass a non-overwriting mode (e.g., mode='w-') when overwrite is false.

Suggested change
# Delete existing file if needed
if os.path.exists(output_path) and overwrite:
os.remove(output_path)
# Handle existing file according to overwrite flag
if os.path.exists(output_path):
if overwrite:
os.remove(output_path)
else:
raise FileExistsError(
f"Output file '{output_path}' already exists and overwrite is set to False."
)

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I agree with the AI that this should probably raise an error rather than allow the user to continue.

Comment thread render/Delft3D_to_datacube/delft3d_converter.py Outdated
"- **sand_frac**: Sand fraction (1 - MUDFRAC)\n",
"\n",
"**Note:** x and y dimensions are swapped in the output file.\n",
"**Note:** To customize variables, edit 'delft3d_converter.py"
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

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

This note line is missing its closing quote/backtick/period, so it renders as an unterminated string in the markdown cell. Please close the filename reference (prefer backticks, e.g., delft3d_converter.py) and end the sentence properly.

Suggested change
"**Note:** To customize variables, edit 'delft3d_converter.py"
"**Note:** To customize variables, edit `delft3d_converter.py`.\n"

Copilot uses AI. Check for mistakes.
Comment on lines +108 to +113
"# Set file paths: change to NETCDF file location\n",
"trim_file = '/Users/minsik/Desktop/NETCDFoutput_TEST/trim-DV_run.nc'\n",
"output_file = '/Users/minsik/Desktop/NETCDFoutput_TEST/sandplover_cube.nc'\n",
"\n",
"# Run conversion\n",
"converter = Delft3DConverter(trim_file).convert(output_file, show_stats=True)"
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

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

The example uses hard-coded absolute paths under /Users/..., which won’t work for other users or CI. Consider using a relative path, a configurable parameter (env var/CLI arg), or a placeholder string (e.g., '/path/to/trim.nc') in the notebook example.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think the second option would be the better repair. If you make them placeholder strings, that will be better.


def load_dataset(self):
"""Load the Delft3D NetCDF dataset."""
self.trim_ds = xr.open_dataset(self.trim_file_path)
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

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

xr.open_dataset is currently called without an explicit decode_timedelta setting. The included notebook run shows FutureWarnings about timedelta decoding; consider passing decode_timedelta=True/False explicitly (or otherwise handling these variables) to keep behavior stable across xarray versions.

Suggested change
self.trim_ds = xr.open_dataset(self.trim_file_path)
self.trim_ds = xr.open_dataset(self.trim_file_path, decode_timedelta=True)

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Up to you if you want to follow the AI

Comment on lines +13 to +14
"- **eta**: Bed elevation (DPS)\n",
"- **water_depth**: Water depth (S1)\n",
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

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

The variable descriptions in the notebook don’t match the converter logic: the code computes eta = S1 - DPS and stores water_depth from DPS, but the notebook lists eta as “(DPS)” and water_depth as “(S1)”. Please update these bullets to reflect the actual calculations/sources.

Suggested change
"- **eta**: Bed elevation (DPS)\n",
"- **water_depth**: Water depth (S1)\n",
"- **eta**: Water depth (S1 - DPS)\n",
"- **water_depth**: Bed elevation (DPS)\n",

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Worth checking this. You know Delft better than me, but it looks like the AI might be confused, since I suppose S1 might be the water surface elevation and the depth is probably DPS, giving $\eta$ as the difference. So it might be worth clarifying.

Comment on lines +54 to +62
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/Users/minsik/Desktop/NETCDFoutput_TEST/delft3d_converter.py:37: FutureWarning: In a future version, xarray will not decode the variable 'MORFT' into a timedelta64 dtype based on the presence of a timedelta-like 'units' attribute by default. Instead it will rely on the presence of a timedelta64 'dtype' attribute, which is now xarray's default way of encoding timedelta64 values.\n",
"To continue decoding into a timedelta64 dtype, either set `decode_timedelta=True` when opening this dataset, or add the attribute `dtype='timedelta64[ns]'` to this variable on disk.\n",
"To opt-in to future behavior, set `decode_timedelta=False`.\n",
" self.trim_ds = xr.open_dataset(self.trim_file_path)\n",
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

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

The notebook is committed with execution outputs that include local filesystem paths (e.g., /Users/...) and warning logs. Please clear all cell outputs before committing (and consider keeping example output minimal) to avoid leaking local environment details and to reduce noisy diffs.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I also agree with the AI about this. It's best practice to clear output cells before committing.

@ericbarefoot ericbarefoot self-requested a review March 12, 2026 15:47
@ericbarefoot ericbarefoot self-assigned this Mar 12, 2026
Copy link
Copy Markdown
Member

@ericbarefoot ericbarefoot left a comment

Choose a reason for hiding this comment

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

So, no issues with the class itself or the method. Looks good. The AI review actually caught a few things that could be improved. I think the main thing that would help is to have a more verbose notebook. When you are deleting the files, you could also reasonably ask CoPilot to make a more verbose description of how to get a file out of delft and how to use it. Then when you make the next notebook that works with the .dat files, you can use the same text and formulae, but with the .dat file.

Comment thread render/Delft3D_to_datacube/delft3d_converter.py Outdated
Comment on lines +222 to +224
# Delete existing file if needed
if os.path.exists(output_path) and overwrite:
os.remove(output_path)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I agree with the AI that this should probably raise an error rather than allow the user to continue.

Comment on lines +108 to +113
"# Set file paths: change to NETCDF file location\n",
"trim_file = '/Users/minsik/Desktop/NETCDFoutput_TEST/trim-DV_run.nc'\n",
"output_file = '/Users/minsik/Desktop/NETCDFoutput_TEST/sandplover_cube.nc'\n",
"\n",
"# Run conversion\n",
"converter = Delft3DConverter(trim_file).convert(output_file, show_stats=True)"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think the second option would be the better repair. If you make them placeholder strings, that will be better.

Comment on lines +54 to +62
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/Users/minsik/Desktop/NETCDFoutput_TEST/delft3d_converter.py:37: FutureWarning: In a future version, xarray will not decode the variable 'MORFT' into a timedelta64 dtype based on the presence of a timedelta-like 'units' attribute by default. Instead it will rely on the presence of a timedelta64 'dtype' attribute, which is now xarray's default way of encoding timedelta64 values.\n",
"To continue decoding into a timedelta64 dtype, either set `decode_timedelta=True` when opening this dataset, or add the attribute `dtype='timedelta64[ns]'` to this variable on disk.\n",
"To opt-in to future behavior, set `decode_timedelta=False`.\n",
" self.trim_ds = xr.open_dataset(self.trim_file_path)\n",
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I also agree with the AI about this. It's best practice to clear output cells before committing.

Comment on lines +13 to +14
"- **eta**: Bed elevation (DPS)\n",
"- **water_depth**: Water depth (S1)\n",
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Worth checking this. You know Delft better than me, but it looks like the AI might be confused, since I suppose S1 might be the water surface elevation and the depth is probably DPS, giving $\eta$ as the difference. So it might be worth clarifying.

Comment thread render/LICENSE Outdated
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can you remove this file from the commit?

Comment thread .DS_Store Outdated
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can you also remove the .DS_Store files from the commit? These are just mac finder placeholder files. I will make a .gitignore for this repo that will propagate back down to you, but for the moment it would be better if these were just removed from the PR entirely.

Comment thread render/.DS_Store Outdated
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Also remove this one please.

Comment thread render/Delft3D_to_datacube/trim-Test.nc Outdated
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think it is bad practice to include the actual data in the repository, since that will end up being cumbersome. for now, let's just make this PR without the data, and then I will suggest a change that will make this a little more lightweight. (it will involve pooch)

Comment thread render/README.md Outdated
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I also don't think we need to overwrite the readme. Can you remove this one too?

Copy link
Copy Markdown
Member

@ericbarefoot ericbarefoot left a comment

Choose a reason for hiding this comment

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

So, no issues with the file or the method. There are few things that I want to see changed before merging.

  • remove data files and the mac-generated .DS_Store files.
  • add more descriptive text and explanation to the notebook. Copilot will probably do a good job of this.
  • most of the AI-generated suggestions are reasonable things to change. I have highlighted a few places where it might have been mistaken.

김민식 and others added 4 commits March 12, 2026 11:27
- Remove .DS_Store, data files (.nc), LICENSE, README.md from tracking
- Add .gitignore to exclude .DS_Store, LICENSE, README.md, *.nc, __pycache__, sandplover_analysis.ipynb
- Clear all cell outputs from notebook (removes local paths from committed output)
- Replace hardcoded filenames with placeholder paths in notebook
- Expand notebook markdown with variable table, prerequisites, and step-by-step instructions for adding optional variables

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Move transpose from save_datacube() to extract_variables() so DataCube is created in correct (time, x=227, y=302) order from the start
- Fix coord assignments in save_datacube(): dim1→x, dim2→y
- Fix misleading comments on coord assignments
- Clear all cell outputs and replace hardcoded filenames with placeholder paths in notebook
- Expand notebook markdown with variable table, prerequisites, and step-by-step instructions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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