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

feat: add lgar, sft, and smp modules #97

Merged
merged 4 commits into from
Mar 20, 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
2 changes: 1 addition & 1 deletion python/ngen_conf/src/ngen/config/_version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '0.2.5'
__version__ = '0.2.6'
11 changes: 7 additions & 4 deletions python/ngen_conf/src/ngen/config/all_formulations.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
from typing import Union

from ngen.config.cfe import CFE
from ngen.config.pet import PET
from ngen.config.lgar import LGAR
from ngen.config.lstm import LSTM
from ngen.config.noahowp import NoahOWP
from ngen.config.multi import MultiBMI
from ngen.config.topmod import Topmod
from ngen.config.noahowp import NoahOWP
from ngen.config.pet import PET
from ngen.config.sloth import SLOTH
from ngen.config.soil_freeze_thaw import SoilFreezeThaw
from ngen.config.soil_moisture_profile import SoilMoistureProfile
from ngen.config.topmod import Topmod

#NOTE the order of this union is important for validation
#unless the model class is using smart_union!
KnownFormulations = Union[Topmod, CFE, PET, NoahOWP, LSTM, SLOTH, MultiBMI]
KnownFormulations = Union[Topmod, CFE, PET, NoahOWP, LSTM, SLOTH, LGAR, SoilFreezeThaw, SoilMoistureProfile, MultiBMI]

#See notes in multi.py and formulation.py about the recursive
#type of MultiBMI modules and how the forward_refs are handled.
18 changes: 18 additions & 0 deletions python/ngen_conf/src/ngen/config/lgar.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from pydantic import Field

from .bmi_formulation import BMICxx


class LGAR(BMICxx):
"""A BMIC++ implementation for LGAR module"""

registration_function: str = "none"
main_output_variable: str = "precipitation_rate"
model_name: str = Field("LGAR", const=True, alias="model_type_name")

_variable_names_map = {
# QINSUR from noah owp modular
"precipitation_rate": "QINSUR",
# EVAPOTRANS from noah owp modular
"potential_evapotranspiration_rate": "EVAPOTRANS",
}
27 changes: 27 additions & 0 deletions python/ngen_conf/src/ngen/config/soil_freeze_thaw.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from typing import Optional

from pydantic import BaseModel, Field

from .bmi_formulation import BMICxx


class SoilFreezeThawParams(BaseModel):
"""Class for validating Soil Freeze Thaw Parameters"""

smcmax: Optional[float]
b: Optional[float]
satpsi: Optional[float]


class SoilFreezeThaw(BMICxx):
"""A BMIC++ implementation for Soil Freeze Thaw module"""

model_params: Optional[SoilFreezeThawParams]
registration_function: str = "none"
main_output_variable: str = "num_cells"
model_name: str = Field("SoilFreezeThaw", const=True, alias="model_type_name")

_variable_names_map = {
# TG from noah owp modular
"ground_temperature": "TG"
}
29 changes: 29 additions & 0 deletions python/ngen_conf/src/ngen/config/soil_moisture_profile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from typing import Optional

from pydantic import BaseModel, Field

from .bmi_formulation import BMICxx


class SoilMoistureProfileParams(BaseModel):
"""Class for validating Soil Moisture Profile Parameters"""

smcmax: Optional[float]
b: Optional[float]
satpsi: Optional[float]


class SoilMoistureProfile(BMICxx):
"""A BMIC++ implementation for Soil Moisture Profile module"""

model_params: Optional[SoilMoistureProfileParams]
registration_function: str = "none"
main_output_variable: str = "soil_water_table"
model_name: str = Field("SoilMoistureProfile", const=True, alias="model_type_name")

_variable_names_map = {
# SOIL_STORAGE from cfe
"soil_storage": "SOIL_STORAGE",
# SOIL_STORAGE_CHANGE from cfe
"soil_storage_change": "SOIL_STORAGE_CHANGE",
}
58 changes: 56 additions & 2 deletions python/ngen_conf/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@
from ngen.config.cfe import CFE
from ngen.config.sloth import SLOTH
from ngen.config.noahowp import NoahOWP
from ngen.config.lgar import LGAR
from ngen.config.soil_freeze_thaw import SoilFreezeThaw
from ngen.config.soil_moisture_profile import SoilMoistureProfile
from ngen.config.topmod import Topmod
from ngen.config.lstm import LSTM
from ngen.config.multi import MultiBMI

#set the workdir relative to this test config
#and use that to look for test data
# set the workdir relative to this test config
# and use that to look for test data
_workdir=Path(__file__).parent
_datadir = _workdir / "data"
_cfe_config_data_path = _datadir / "init_config_data" / "cat_87_bmi_config_cfe.ini"
Expand Down Expand Up @@ -107,6 +110,45 @@ def lstm_params():
'config': "{{id}}_config.txt"}
return data

@pytest.fixture
def lgar_params():
path = _workdir.joinpath("data/dne/")
data = {
'model_type_name': 'LGAR',
'name': 'bmi_c++',
'registration_function': 'none',
'library': 'libfakecfe.so',
'config_prefix': path,
'config': "{{id}}_config.txt",
}
return data

@pytest.fixture
def soil_freeze_thaw_params():
path = _workdir.joinpath("data/dne/")
data = {
'model_type_name': 'SoilFreezeThaw',
'name': 'bmi_c++',
'registration_function': 'none',
'library': 'libfakecfe.so',
'config_prefix': path,
'config': "{{id}}_config.txt",
}
return data

@pytest.fixture
def soil_moisture_profile_params():
path = _workdir.joinpath("data/dne/")
data = {
'model_type_name': 'SoilMoistureProfile',
'name': 'bmi_c++',
'registration_function': 'none',
'library': 'libfakecfe.so',
'config_prefix': path,
'config': "{{id}}_config.txt",
}
return data

@pytest.fixture
def cfe(cfe_params):
return CFE(**cfe_params)
Expand All @@ -127,6 +169,18 @@ def noahowp(noahowp_params):
def lstm(lstm_params):
return LSTM(**lstm_params)

@pytest.fixture
def lgar(lgar_params):
return LGAR(**lgar_params)

@pytest.fixture
def soil_freeze_thaw(soil_freeze_thaw_params):
return SoilFreezeThaw(**soil_freeze_thaw_params)

@pytest.fixture
def soil_moisture_profile(soil_moisture_profile_params):
return SoilMoistureProfile(**soil_moisture_profile_params)

@pytest.fixture
def multi(cfe, noahowp):
cfe.allow_exceed_end_time=True
Expand Down
23 changes: 23 additions & 0 deletions python/ngen_conf/tests/test_lgar.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from ngen.config.formulation import Formulation
from ngen.config.lgar import LGAR


def test_init(lgar_params):
LGAR(**lgar_params)


def test_name_map(lgar_params):
lgar = LGAR(**lgar_params)
assert lgar.name_map["precipitation_rate"] == "QINSUR"
assert lgar.name_map["potential_evapotranspiration_rate"] == "EVAPOTRANS"


def test_lgar_formulation(lgar_params):
lgar = LGAR(**lgar_params)
f = {"params": lgar, "name": "bmi_c++"}
lgar_formulation = Formulation(**f)
_lgar = lgar_formulation.params
assert _lgar.name == "bmi_c++"
assert _lgar.model_name == "LGAR"
serialized = _lgar.dict(by_alias=True)
assert serialized["model_type_name"] == "LGAR"
22 changes: 22 additions & 0 deletions python/ngen_conf/tests/test_soil_freeze_thaw.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from ngen.config.formulation import Formulation
from ngen.config.soil_freeze_thaw import SoilFreezeThaw


def test_init(soil_freeze_thaw_params):
SoilFreezeThaw(**soil_freeze_thaw_params)


def test_name_map(soil_freeze_thaw_params):
soil_freeze_thaw = SoilFreezeThaw(**soil_freeze_thaw_params)
assert soil_freeze_thaw.name_map["ground_temperature"] == "TG"


def test_soil_freeze_thaw_formulation(soil_freeze_thaw_params):
soil_freeze_thaw = SoilFreezeThaw(**soil_freeze_thaw_params)
f = {"params": soil_freeze_thaw, "name": "bmi_c++"}
soil_freeze_thaw_formulation = Formulation(**f)
_soil_freeze_thaw = soil_freeze_thaw_formulation.params
assert _soil_freeze_thaw.name == "bmi_c++"
assert _soil_freeze_thaw.model_name == "SoilFreezeThaw"
serialized = _soil_freeze_thaw.dict(by_alias=True)
assert serialized["model_type_name"] == "SoilFreezeThaw"
23 changes: 23 additions & 0 deletions python/ngen_conf/tests/test_soil_moisture_profile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from ngen.config.formulation import Formulation
from ngen.config.soil_moisture_profile import SoilMoistureProfile


def test_init(soil_moisture_profile_params):
SoilMoistureProfile(**soil_moisture_profile_params)


def test_name_map(soil_moisture_profile_params):
soil_moisture_profile = SoilMoistureProfile(**soil_moisture_profile_params)
assert soil_moisture_profile.name_map["soil_storage"] == "SOIL_STORAGE"
assert soil_moisture_profile.name_map["soil_storage_change"] == "SOIL_STORAGE_CHANGE"


def test_soil_moisture_profile_formulation(soil_moisture_profile_params):
soil_moisture_profile = SoilMoistureProfile(**soil_moisture_profile_params)
f = {"params": soil_moisture_profile, "name": "bmi_c++"}
soil_moisture_profile_formulation = Formulation(**f)
_soil_moisture_profile = soil_moisture_profile_formulation.params
assert _soil_moisture_profile.name == "bmi_c++"
assert _soil_moisture_profile.model_name == "SoilMoistureProfile"
serialized = _soil_moisture_profile.dict(by_alias=True)
assert serialized["model_type_name"] == "SoilMoistureProfile"
Loading