-
Notifications
You must be signed in to change notification settings - Fork 7
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
Split get_background into 3d and 4d tasks #268
base: develop
Are you sure you want to change the base?
Changes from 1 commit
c8d9c31
aa3ebde
93efcb5
f2d5399
de540a7
9f4fcc5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
@@ -0,0 +1,140 @@ | ||||
#!/usr/bin/env python | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure this is quite the right design. We ultimately need to map between suites, tasks and questions. If you ask tasks/get_background3d.py You can put your class in utilities if you like. But everything you access from the config needs to be in the codes in tasks. It doesn't matter that there might be duplicate things being taken from the config in each. The issue is that you otherwise break the connection between suites, tasks and task_questions. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here is the code that builds a list of tasks from the suite file (flow.cylc)
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Once it has a list of tasks it greps all the task code in the tasks directory to see which things in the config will be requests. From there it can ask all those questions and create experiement.yaml |
||||
|
||||
# (C) Copyright 2021- United States Government as represented by the Administrator of the | ||||
# National Aeronautics and Space Administration. All Rights Reserved. | ||||
# | ||||
# This software is licensed under the terms of the Apache Licence Version 2.0 | ||||
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. | ||||
|
||||
# ------------------------------------------------------------------------------------------------- | ||||
|
||||
|
||||
from abc import ABC, abstractmethod | ||||
import isodate | ||||
|
||||
# -------------------------------------------------------------------------------------------------- | ||||
# Prep Background superclass | ||||
# -------------------------------------------------------------------------------------------------- | ||||
class PrepBackground(ABC): | ||||
|
||||
def __init__(self, config): | ||||
|
||||
# Delegate config object | ||||
self.config = config | ||||
|
||||
# Parse a few config elements | ||||
self.background_experiment = config.background_experiment() | ||||
self.background_frequency = config.background_frequency(None) | ||||
self.forecast_offset = config.analysis_forecast_window_offset() | ||||
self.horizontal_resolution = config.horizontal_resolution() | ||||
self.window_length = config.window_length() | ||||
self.window_offset = config.window_offset() | ||||
|
||||
# Duration parameters | ||||
self.window_length_dur = None | ||||
self.forecast_offset_dur = None | ||||
self.forecast_duration_for_background = None | ||||
|
||||
# Offset parameters | ||||
self.window_offset_dur = None | ||||
|
||||
# Forecast start time | ||||
self.forecast_start_time = None | ||||
|
||||
# Initialize a list of background time steps | ||||
self.bkg_steps = [] | ||||
|
||||
@classmethod | ||||
def fromConfig(cls, config): | ||||
return cls(config) | ||||
|
||||
def prep(self, cycle_time_dto): | ||||
|
||||
# Reset bkg_steps to empty list if necessary | ||||
self.bkg_steps = [] | ||||
|
||||
self._parse_dur() | ||||
self._offset() | ||||
self._add_bkg_steps(cycle_time_dto) | ||||
self._set_forecast_start_time(cycle_time_dto) | ||||
|
||||
def _parse_dur(self): | ||||
|
||||
# Convert to datetime durations | ||||
self.window_length_dur = isodate.parse_duration(self.window_length) | ||||
self.forecast_offset_dur = isodate.parse_duration(self.forecast_offset) | ||||
self.forecast_duration_for_background = self.window_length_dur - self.forecast_offset_dur | ||||
|
||||
def _set_forecast_start_time(self, cycle_time_dto): | ||||
self.forecast_start_time = cycle_time_dto - self.window_length_dur + self.forecast_offset_dur | ||||
|
||||
@abstractmethod | ||||
def _offset(self): | ||||
pass | ||||
|
||||
@abstractmethod | ||||
def _add_bkg_steps(self, *args): | ||||
pass | ||||
|
||||
# -------------------------------------------------------------------------------------------------- | ||||
# Prep 3D Background subclass | ||||
# -------------------------------------------------------------------------------------------------- | ||||
class PrepBackground3D(PrepBackground): | ||||
|
||||
def _offset(self): | ||||
return None | ||||
|
||||
def _add_bkg_steps(self, *args): | ||||
|
||||
self.bkg_steps.append(isodate.duration_isoformat(self.forecast_duration_for_background)) | ||||
|
||||
return None | ||||
|
||||
# -------------------------------------------------------------------------------------------------- | ||||
# Prep 4D Background sublcass | ||||
# -------------------------------------------------------------------------------------------------- | ||||
class PrepBackground4D(PrepBackground): | ||||
|
||||
# ------------------------------------------------------------------------------- | ||||
def _offset(self): | ||||
|
||||
# If the window type is 4D then remove the window offset as first background | ||||
# occurs at the beginning of the window | ||||
self.window_offset_dur = isodate.parse_duration(self.window_offset) | ||||
|
||||
self.forecast_duration_for_background =\ | ||||
self.forecast_duration_for_background - self.window_offset_dur | ||||
|
||||
return None | ||||
|
||||
# ------------------------------------------------------------------------------- | ||||
def _add_bkg_steps(self, cycle_time_dto): | ||||
|
||||
self.bkg_steps.append(isodate.duration_isoformat(self.forecast_duration_for_background)) | ||||
|
||||
# If background is provided though files get all backgrounds | ||||
bkg_freq_dur = isodate.parse_duration(self.background_frequency) | ||||
|
||||
# Check for a sensible frequency | ||||
if (self.window_length_dur/bkg_freq_dur) % 2: | ||||
# !!!!!!!!!!!!!!!! no logger in self | ||||
# self.logger.abort('Window length not divisible by background frequency') | ||||
raise ValueError("Need to call logger somehow.") | ||||
|
||||
# Loop over window | ||||
print('cycle_time_dto', cycle_time_dto) | ||||
print('window_offset_dur', self.window_offset_dur) | ||||
|
||||
start_date = cycle_time_dto - self.window_offset_dur | ||||
final_date = cycle_time_dto + self.window_offset_dur | ||||
|
||||
loop_date = start_date + bkg_freq_dur | ||||
|
||||
while loop_date <= final_date: | ||||
|
||||
duration_in = loop_date - start_date + self.forecast_duration_for_background | ||||
self.bkg_steps.append(isodate.duration_isoformat(duration_in)) | ||||
loop_date += bkg_freq_dur | ||||
|
||||
return None | ||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps it's not necessary to create a function for holding this? Since it's only used in one place?