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

Add Ngen Calibration Request Variant #217

Closed
wants to merge 5 commits into from
Closed
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/lib/communication/dmod/communication/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
PartitionerServiceClient, SchedulerClient
from .maas_request import get_available_models, get_available_outputs, get_distribution_types, get_parameters, \
get_request, Distribution, ExternalRequest, ExternalRequestResponse, ModelExecRequest, ModelExecRequestResponse, \
NWMRequest, NWMRequestResponse, Scalar, NGENRequest, NGENRequestResponse
NWMRequest, NWMRequestResponse, Scalar, NGENRequest, NGENRequestResponse, NGENCalibrationRequest
from .message import AbstractInitRequest, MessageEventType, Message, Response, InvalidMessage, InvalidMessageResponse, \
InitRequestResponseReason
from .metadata_message import MetadataPurpose, MetadataMessage, MetadataResponse
Expand Down
18 changes: 14 additions & 4 deletions python/lib/communication/dmod/communication/maas_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,18 @@ def get_available_models() -> dict:
"""
:return: The names of all models mapped to their class
"""
available_models = dict()

for subclass in ModelExecRequest.__subclasses__(): # type: ModelExecRequest
available_models[subclass.model_name] = subclass
def recursively_get_all_model_subclasses(model_exec_request: "ModelExecRequest") -> dict:
available_models = dict()

return available_models
for subclass in model_exec_request.__subclasses__(): # type: ModelExecRequest
available_models[subclass.model_name] = subclass
# TODO: what to do if descendant subclass "overwrites" ancestor subclass?
available_models.update(recursively_get_all_model_subclasses(subclass))

return available_models

return recursively_get_all_model_subclasses(ModelExecRequest)


def get_available_outputs() -> set:
Expand Down Expand Up @@ -1364,3 +1370,7 @@ def get_request(model: str, config_data_id: str, session_secret: str = '', *args
raise ValueError(err_msg.format(model, get_available_models()))

return get_available_models()[model](config_data_id=config_data_id, session_secret=session_secret, *args, **kwargs)


class NGENCalibrationRequest(NGENRequest):
model_name: str = "ngen_cal"
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import unittest
from ..communication.maas_request import NGENCalibrationRequest
from dmod.core.meta_data import TimeRange


def create_time_range(begin, end, var=None) -> TimeRange:
serialized = {
"begin": begin,
"end": end,
"datetime_pattern": "%Y-%m-%d %H:%M:%S",
"subclass": TimeRange.__name__,
"variable": "Time" if var is None else var,
}
return TimeRange.factory_init_from_deserialized_json(serialized)


class TestNGENCalibrationRequest(unittest.TestCase):
@property
def time_range(self):
return create_time_range("2022-01-01 00:00:00", "2022-03-01 00:00:00")

@property
def cat_ids_list(self):
return ["cat-1", "cat-2", "cat-3"]

def test_model_name_eq_ngen_cal(self):
request = NGENCalibrationRequest(
session_secret="f21f27ac3d443c0948aab924bddefc64891c455a756ca77a4d86ec2f697cd13c",
cpu_count=1,
allocation_paradigm="ROUND_ROBIN",
time_range=self.time_range,
hydrofabric_uid="0123456789",
hydrofabric_data_id="9876543210",
config_data_id="02468",
bmi_cfg_data_id="02468",
catchments=self.cat_ids_list,
)
self.assertEqual(request.model_name, NGENCalibrationRequest.model_name)

def test_factory_init_from_deserialized_json(self):
msg = {
"model": {
"name": "ngen_cal",
"allocation_paradigm": "ROUND_ROBIN",
"cpu_count": 0,
"time_range": self.time_range.to_dict(),
"hydrofabric_data_id": "9876543210",
"hydrofabric_uid": "0123456789",
"config_data_id": "02468",
"bmi_config_data_id": "02468",
"catchments": self.cat_ids_list,
},
"session-secret": "f21f27ac3d443c0948aab924bddefc64891c455a756ca77a4d86ec2f697cd13c",
}
request = NGENCalibrationRequest.factory_init_from_deserialized_json(msg)
self.maxDiff = None
self.assertDictEqual(msg, request.to_dict())

def test_factory_init_correct_response_subtype(self):
msg = {
"model": {
"name": "ngen_cal",
"allocation_paradigm": "ROUND_ROBIN",
"cpu_count": 0,
"time_range": self.time_range.to_dict(),
"hydrofabric_data_id": "9876543210",
"hydrofabric_uid": "0123456789",
"config_data_id": "02468",
"bmi_config_data_id": "02468",
"catchments": self.cat_ids_list,
},
"session-secret": "f21f27ac3d443c0948aab924bddefc64891c455a756ca77a4d86ec2f697cd13c",
}
request = (
NGENCalibrationRequest.factory_init_correct_subtype_from_deserialized_json(
msg
)
)

self.assertEqual(request.model_name, NGENCalibrationRequest.model_name)
# use `type()` instead of `isinstance()` for specificity.
self.assertEqual(type(request), NGENCalibrationRequest)

if __name__ == "__main__":
unittest.main()
5 changes: 4 additions & 1 deletion python/lib/scheduler/dmod/scheduler/scheduler.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import logging
from requests.exceptions import ReadTimeout
from dmod.communication import MessageEventType, NGENRequest, NWMRequest
from dmod.communication import MessageEventType, NGENRequest, NGENCalibrationRequest, NWMRequest
from dmod.core.exception import DmodRuntimeError
from dmod.core.meta_data import DataCategory, DataFormat
from os import getenv
Expand Down Expand Up @@ -489,6 +489,9 @@ def determine_image_for_job(self, job: 'Job') -> str:
str
String name, including tag, of the appropriate Docker image for this job.
"""
if isinstance(job.model_request, NGENCalibrationRequest):
return "127.0.0.1:5000/ngen_cal:latest"

if isinstance(job.model_request, NGENRequest):
return "127.0.0.1:5000/ngen:latest"
# For now, this is the only thing supported
Expand Down