diff --git a/README.md b/README.md index bf430f7ef..e94ef59aa 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ [![Full test](https://github.com/DHI/mikeio/actions/workflows/full_test.yml/badge.svg)](https://github.com/DHI/mikeio/actions/workflows/full_test.yml) [![PyPI version](https://badge.fury.io/py/mikeio.svg)](https://badge.fury.io/py/mikeio) ![OS](https://img.shields.io/badge/OS-Windows%20%7C%20Linux-blue) +[![License](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://github.com/DHI/mikeio/blob/main/License.txt) Read, write and manipulate dfs0, dfs1, dfs2, dfs3, dfsu and mesh files. diff --git a/docs/index.qmd b/docs/index.qmd index cdd29ba39..5222fcbf8 100644 --- a/docs/index.qmd +++ b/docs/index.qmd @@ -4,6 +4,7 @@ # MIKE IO: input/output of MIKE files in Python ![Python version](https://img.shields.io/pypi/pyversions/mikeio.svg) [![PyPI version](https://badge.fury.io/py/mikeio.svg)](https://badge.fury.io/py/mikeio) +[![License](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://github.com/DHI/mikeio/blob/main/License.txt) Read, write and manipulate dfs0, dfs1, dfs2, dfs3, dfsu and mesh files. diff --git a/mikeio/generic.py b/mikeio/generic.py index 555467435..8a93733a8 100644 --- a/mikeio/generic.py +++ b/mikeio/generic.py @@ -526,8 +526,8 @@ def concat( darray = d.astype(np.float32) dfs_o.WriteItemTimeStepNext(0, darray) - end_time = ( - start_time + timedelta(seconds=timestep * dt) + end_time = start_time + timedelta( + seconds=timestep * dt ) # reuse last timestep since there is no EndDateTime attribute in t_axis. dfs_i.Close() @@ -552,6 +552,79 @@ def concat( ) # get end time from current file dfs_i.Close() + if keep == "average": + if i == 0: + # For first file, write all timesteps normally + for timestep in range(n_time_steps): + current_time = start_time + timedelta(seconds=timestep * dt) + + for item in range(n_items): + itemdata = dfs_i.ReadItemTimeStep(int(item + 1), int(timestep)) + darray = itemdata.Data.astype(np.float32) + dfs_o.WriteItemTimeStepNext(0, darray) + end_time = start_time + timedelta(seconds=(n_time_steps - 1) * dt) + first_start_time = start_time # Store the start time of first file + dfs_i.Close() + else: + # For subsequent files, we need to handle overlapping periods + # Calculate overlap in timesteps + if start_time <= end_time: + overlap_end = int((end_time - start_time).total_seconds() / dt) + 1 + + # Read current file data + for timestep in range(n_time_steps): + current_time = start_time + timedelta(seconds=timestep * dt) + + for item in range(n_items): + itemdata = dfs_i.ReadItemTimeStep( + int(item + 1), int(timestep) + ) + current_data = itemdata.Data.astype(np.float32) + + if ( + int(timestep) <= overlap_end + ): # Convert back to int for comparison + # In overlapping period + existing_pos = int( + (current_time - first_start_time).total_seconds() + / dt + - 1 + ) + if existing_pos >= 0: + # Read existing data + dfs_o.Flush() + temp_dfs = DfsFileFactory.DfsGenericOpen( + str(outfilename) + ) + existing_data = temp_dfs.ReadItemTimeStep( + int(item + 1), int(existing_pos) + ).Data + temp_dfs.Close() + + # Calculate average + averaged_data = (existing_data + current_data) / 2 + + # Write averaged data + dfs_o.WriteItemTimeStepNext(0, averaged_data) + + else: + # After overlap period - write new data + dfs_o.WriteItemTimeStepNext(0, current_data) + + else: + # No overlap - write all timesteps + for timestep in range(n_time_steps): + current_time = start_time + timedelta(seconds=timestep * dt) + for item in range(n_items): + itemdata = dfs_i.ReadItemTimeStep( + str(item + 1), str(timestep) + ) + darray = itemdata.Data.astype(np.float32) + dfs_o.WriteItemTimeStepNext(0, darray) + + end_time = start_time + timedelta(seconds=(n_time_steps - 1) * dt) + dfs_i.Close() + n_time_steps_prev_file = n_time_steps dfs_o.Close()