Skip to content

Commit

Permalink
integrate the Initial_Condition converter to the ext_old_to_new
Browse files Browse the repository at this point in the history
  • Loading branch information
MAfarrag committed Nov 21, 2024
1 parent 86142e7 commit a1ccf9c
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 9 deletions.
5 changes: 4 additions & 1 deletion hydrolib/tools/ext_old_to_new/converter_factory.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from hydrolib.core.dflowfm.extold.models import ExtOldMeteoQuantity
from hydrolib.core.dflowfm.extold.models import ExtOldMeteoQuantity, ExtOldInitialConditionQuantity

from .base_converter import BaseConverter
from .meteo_converter import MeteoConverter
from hydrolib.tools.ext_old_to_new.initial_condition_converter import InitialConditionConverter


def __contains__(cls, item):
Expand Down Expand Up @@ -34,5 +35,7 @@ def create_converter(quantity) -> BaseConverter:
"""
if __contains__(ExtOldMeteoQuantity, quantity):
return MeteoConverter()
if __contains__(ExtOldInitialConditionQuantity, quantity):
return InitialConditionConverter()
else:
raise ValueError(f"No converter available for QUANTITY={quantity}.")
11 changes: 5 additions & 6 deletions hydrolib/tools/ext_old_to_new/main_converter.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import argparse
import os
import sys
from typing import Tuple

from typing import Tuple, Union
from pathlib import Path
from hydrolib.core import __version__
from hydrolib.core.basemodel import PathOrStr
from hydrolib.core.dflowfm.ext.models import Boundary, ExtModel, Lateral, Meteo
from hydrolib.core.dflowfm.extold.models import *
from hydrolib.core.dflowfm.extold.models import ExtOldModel
from hydrolib.core.basemodel import FileModel
from hydrolib.core.dflowfm.inifield.models import (
IniFieldModel,
InitialField,
Expand Down Expand Up @@ -53,7 +54,7 @@ def ext_old_to_new(
structurefile: PathOrStr = None,
backup: bool = False,
postfix: str = "",
) -> Tuple[ExtOldModel, ExtModel, IniFieldModel, StructureModel]:
) -> Union[Tuple[ExtOldModel, FileModel, FileModel, FileModel], None]:
"""
Convert old external forcing file to new format files.
When the output files are existing, output will be appended to them.
Expand Down Expand Up @@ -119,8 +120,6 @@ def ext_old_to_new(
f"Unsupported model class {type(new_quantity_block)} for {forcing.quantity} in {extoldfile}."
)

print(new_quantity_block)

backup_file(ext_model.filepath, backup)
ext_model.save()

Expand Down
13 changes: 12 additions & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from pathlib import Path
from typing import List
from typing import List, Dict

import pytest

Expand Down Expand Up @@ -101,6 +101,17 @@ def old_forcing_file() -> Path:
return Path("tests/data/input/old-external-forcing.ext")


@pytest.fixture(scope="function")
def old_forcing_file_initial_condition() -> Dict[str, Path]:
return {
"path": Path("tests/data/input/old-external-forcing-initial-contitions-only.ext"),
"quantities": ["initialwaterlevel","initialwaterlevel", "initialsalinity"],
"file_type": ["polygon", "sample", "sample"],
"file_path": ["iniwaterlevel1.pol", "iniwaterlevel.xyz", "inisalinity.xyz"],

}


@pytest.fixture
def old_forcing_file_quantities() -> List[str]:
return [
Expand Down
83 changes: 83 additions & 0 deletions tests/data/input/old-external-forcing-initial-contitions-only.ext
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
* QUANTITY : waterlevelbnd, velocitybnd, dischargebnd, tangentialvelocitybnd, normalvelocitybnd filetype=9 method=2,3
* : outflowbnd, neumannbnd, qhbnd filetype=9 method=2,3
* : salinitybnd filetype=9 method=2,3
* : gateloweredgelevel, damlevel, pump filetype=9 method=2,3
* : frictioncoefficient, horizontaleddyviscositycoefficient, advectiontype, ibotlevtype filetype=4,7,10 method=4
* : initialwaterlevel filetype=4,7,10,12 method=4,5
* : initialtemperature filetype=4,7,10,12 method=4,5
* : initialsalinity, initialsalinitytop: use initialsalinity for depth-uniform, or
* : as bed level value in combination with initialsalinitytop filetype=4,7,10 method=4
* : initialverticaltemperatureprofile filetype=9,10 method=
* : initialverticalsalinityprofile filetype=9,10 method=
* : windx, windy, windxy, rainfall_mmperday, atmosphericpressure filetype=1,2,4,7,8 method=1,2,3
* : shiptxy, movingstationtxy filetype=1 method=1
* : discharge_salinity_temperature_sorsin filetype=9 method=1
*
* kx = Vectormax = Nr of variables specified on the same time/space frame. Eg. Wind magnitude,direction: kx = 2
* FILETYPE=1 : uniform kx = 1 value 1 dim array uni
* FILETYPE=2 : unimagdir kx = 2 values 1 dim array, uni mag/dir transf to u,v, in index 1,2
* FILETYPE=3 : svwp kx = 3 fields u,v,p 3 dim array nointerpolation
* FILETYPE=4 : arcinfo kx = 1 field 2 dim array bilin/direct
* FILETYPE=5 : spiderweb kx = 3 fields 3 dim array bilin/spw
* FILETYPE=6 : curvi kx = ? bilin/findnm
* FILETYPE=7 : triangulation kx = 1 field 1 dim array triangulation
* FILETYPE=8 : triangulation_magdir kx = 2 fields consisting of Filetype=2 triangulation in (wind) stations
*
* FILETYPE=9 : polyline kx = 1 For polyline points i= 1 through N specify boundary signals, either as
* timeseries or Fourier components or tidal constituents
* Timeseries are in files *_000i.tim, two columns: time (min) values
* Fourier components and or tidal constituents are in files *_000i.cmp, three columns
* period (min) or constituent name (e.g. M2), amplitude and phase (deg)
* If no file is specified for a node, its value will be interpolated from surrounding nodes
* If only one signal file is specified, the boundary gets a uniform signal
* For a dischargebnd, only one signal file must be specified
*
* FILETYPE=10 : inside_polygon kx = 1 field uniform value inside polygon for INITIAL fields
* FILETYPE=11 : ncgrid currently not in use
* FILETYPE=12 : ncflow kx = 1 field 1 dim array triangulation
*
* METHOD =0 : provider just updates, another provider that pointers to this one does the actual interpolation
* =1 : intp space and time (getval) keep 2 meteofields in memory
* =2 : first intp space (update), next intp. time (getval) keep 2 flowfields in memory
* =3 : save weightfactors, intp space and time (getval), keep 2 pointer- and weight sets in memory.
* =4 : only spatial, inside polygon
* =5 : only spatial, triangulation
* =6 : only spatial, averaging
* =7 : only spatial, index triangulation
* =8 : only spatial, smoothing
* =9 : only spatial, internal diffusion
* =10 : only initial vertical profiles
*
* OPERAND =O : Override at all points
* =+ : Add to previously specified value
* =* : Multiply with previously specified value
* =A : Apply only if no value specified previously (For Initial fields, similar to Quickin preserving best data specified first)
* =X : MAX with prev. spec.
* =N : MIN with prev. spec.
*
* VALUE = : Offset value for this provider
*
* FACTOR = : Conversion factor for this provider
*
**************************************************************************************************************


* First 1D2D:
QUANTITY =initialwaterlevel
FILENAME =iniwaterlevel1.pol
FILETYPE =10
METHOD =4
OPERAND =O
VALUE =1.0

QUANTITY =initialwaterlevel
FILENAME =iniwaterlevel.xyz
FILETYPE =7
METHOD =5
OPERAND =O

QUANTITY =initialsalinity
FILENAME =inisalinity.xyz
FILETYPE =7
METHOD =5
OPERAND =O
37 changes: 36 additions & 1 deletion tests/tools/test_main_converter.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from pathlib import Path
from typing import List
from typing import List, Dict

from hydrolib.tools.ext_old_to_new import main_converter
from hydrolib.tools.ext_old_to_new.main_converter import (
_read_ext_old_data,
ext_old_to_new,
ext_old_to_new_dir_recursive,
ext_old_to_new_from_mdu,
)
Expand Down Expand Up @@ -68,3 +69,37 @@ def test__read_ext_old_data(
assert captured.out.startswith(
f"Read {(len(old_forcing_file_quantities))} forcing blocks from {old_forcing_file}."
)


class TestExtOldToNew:

def test_ext_with_only_initial_contitions(self, old_forcing_file_initial_condition: Dict[str, str]):
new_ext_file = Path("tests/data/input/new-external-forcing.ext")
new_initial_file = Path("tests/data/input/new-initial-conditions.ext")
new_structure_file = Path("tests/data/input/new-structure.ext")

path = old_forcing_file_initial_condition["path"]
extold_model, ext_model, inifield_model, structure_model = \
ext_old_to_new(path, new_ext_file, new_initial_file, new_structure_file)

assert new_ext_file.exists()
assert new_initial_file.exists()
assert new_structure_file.exists()
# all the quantities in the old external file are initial conditions
# check that all the quantities (3) were converted to initial conditions
num_quantities = len(old_forcing_file_initial_condition["quantities"])
assert len(inifield_model.initial) == num_quantities
# no parameters or any other structures, lateral or meteo data
assert len(inifield_model.parameter) == 0
assert len(ext_model.lateral) == 0
assert len(ext_model.meteo) == 0
assert len(structure_model.structure) == 0
assert ([inifield_model.initial[i].datafiletype for i in range(num_quantities)] ==
old_forcing_file_initial_condition["file_type"])
assert ([str(inifield_model.initial[i].datafile.filepath) for i in range(num_quantities)] ==
old_forcing_file_initial_condition["file_path"])
# clean up
# try
new_initial_file.unlink()
new_ext_file.unlink()
new_structure_file.unlink()

0 comments on commit a1ccf9c

Please sign in to comment.