Repository: climate Updated Branches: refs/heads/master 2c81aa84b -> 82dd6b69d
removig old cli code Project: http://git-wip-us.apache.org/repos/asf/climate/repo Commit: http://git-wip-us.apache.org/repos/asf/climate/commit/f0e89482 Tree: http://git-wip-us.apache.org/repos/asf/climate/tree/f0e89482 Diff: http://git-wip-us.apache.org/repos/asf/climate/diff/f0e89482 Branch: refs/heads/master Commit: f0e89482c5a5b7a4d214673bf6f80f8803734237 Parents: 6ab02d8 Author: Maziyar Boustani <[email protected]> Authored: Thu May 28 12:07:56 2015 -0700 Committer: Maziyar Boustani <[email protected]> Committed: Thu May 28 12:07:56 2015 -0700 ---------------------------------------------------------------------- ocw-cli/ocw_cli.py | 848 ------------------------------------------------ 1 file changed, 848 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/climate/blob/f0e89482/ocw-cli/ocw_cli.py ---------------------------------------------------------------------- diff --git a/ocw-cli/ocw_cli.py b/ocw-cli/ocw_cli.py deleted file mode 100644 index 85fe2ab..0000000 --- a/ocw-cli/ocw_cli.py +++ /dev/null @@ -1,848 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -import curses -import sys -import os -import numpy as np - -from netCDF4 import Dataset -from datetime import datetime, timedelta - -import ocw.metrics as metrics -import ocw.plotter as plotter -import ocw.dataset_processor as dsp -import ocw.evaluation as evaluation -import ocw.data_source.rcmed as rcmed -from ocw.dataset import Bounds -from ocw.data_source.local import load_file - - -def ready_screen(page, note=""): - ''' Generates page borders, header, footer and notification center. - - :param note: Notification that system returns and will be shown - at the bottom of page - :type note: string - :param page: Name of current page - :type page: string - - :returns: y and x as location of text on screen - :rtype: integer - ''' - - screen.clear() - y, x = screen.getmaxyx() - screen.border(0) - screen.addstr(0, x/2-len(TITLE)/2, TITLE) - screen.addstr(y-1, x/2-len(ORGANIZATION)/2, ORGANIZATION) - screen.addstr(y-3, 1, "Notification:") - for each in range(1, x-1): - screen.addstr(y-4, each, "-") - if page == "main_menu": - screen.addstr(y-3, x-21, "(NC) = Not complete") - screen.addstr(y-2, x-21, "(C) = Complete") - screen.addstr(y-2, 1, note) - - return y, x - - -############################################################## -# Manage Model Screen -############################################################## - -def load_model_screen(header): - '''Generates screen to be able to load model file. - Path to model file (netCDF) and variable name is required. - - :param header: Header of page - :type header: string - - :returns: Notification - :rtype: string - ''' - - ready_screen("load_model_screen") - screen.addstr(1, 1, header + " > Load Model File ") - screen.addstr(4, 2, "Enter model path: ") - model_path = screen.getstr() - try: - netCDF_file = Dataset(model_path, 'r') - all_netcdf_variables = [variable.encode() for variable in netCDF_file.variables.keys()] - netCDF_file.close() - try: - screen.addstr(6, 2, "Enter model variable name {0}: ".format(all_netcdf_variables)) - variable_name = screen.getstr() - model_dataset = load_file(model_path, variable_name) - model_datasets.append(model_dataset) - models_info.append({ 'directory': model_path, - 'variable_name': variable_name - }) - note = "Model file successfully added." - except: - note = "WARNING: Model file cannot be added. The variable [{0}] is not accepted. Please try again.".format(variable_name) - except: - note = "WARNING: Model file cannot be read. Please check the file directory or format. Only netCDF format is accepted." - - return note - - - -def unload_model_screen(header): - '''Generates screen to be able to unload model file. - It lists all loaded model with index for each. - Selection of model with index will remove model from list of models. - - :param header: Header of page - :type header: string - - :returns: Notification - :rtype: string - ''' - - ready_screen("unload_model_screen") - screen.addstr(1, 1, header + " > Unload Model File") - screen.addstr(6, 1, "List of Model:") - for i, model in enumerate(models_info): - screen.addstr(8 + i, 10, "Model Number:[{0}] - Model path:[{1}] - Variables:[{2}]".format(str(i), model['directory'], model['variable_name'])) - screen.addstr(3, 2, "Select the model number to remove (press enter to go back): ") - try: - model_remove_index = screen.getstr() - models_info.pop(int(model_remove_index)) - model_datasets.pop(int(model_remove_index)) - note = "Model file unloaded successfully" - except: - note = "WARNING: Model file was not unloaded successfully." - - return note - - -def list_model_screen(header): - '''Generates screen to list all model files. - - :param header: Header of page - :type header: string - ''' - - ready_screen("list_model_screen") - screen.addstr(1, 1, header + " > List Model File ") - screen.addstr(6, 6, "List of model(s): ") - for i, model in enumerate(models_info): - screen.addstr(8 + i, 10, "Model Number:[{0}] - Model path:[{1}] - Variables:[{2}]".format(str(i), model['directory'], model['variable_name'])) - screen.addstr(4, 4, "Return to Manage Model (press Enter) :") - screen.getstr() - - -def manage_model_screen(header, note=""): - '''Generates Manage Model screen. - - :param header: Header of page - :type header: string - :param note: Notification, defult to empty string. - :type note: string - ''' - - option = '' - while option != '0': - ready_screen("manage_model_screen", note) - screen.addstr(1, 1, header) - screen.addstr(4, 4, "1 - Load Model File [Number of loaded model: {0}]".format(len(model_datasets))) - screen.addstr(6, 4, "2 - Unload Model File") - screen.addstr(8, 4, "3 - List Model File") - screen.addstr(10, 4, "0 - Return to Main Menu") - screen.addstr(12, 2, "Select an option: ") - screen.refresh() - option = screen.getstr() - - if option == '1': - note = load_model_screen(header) - if option == '2': - note = unload_model_screen(header) - if option == '3': - note = list_model_screen(header) - note = " " - - -############################################################## -# Manage Observation Screen -############################################################## - -def select_obs_screen(header): #TODO: if the observation is already selected, don't select again. - '''Generates screen to select observation. - It reterives list of observations from database and make a table from that. - User has to select observation with dataset_id, parameter_id, start_date, end_date, minimum and maximum of lat and lon. - If the size of terminal screen is small to show whole table, a notification with link to parameter table on website will show up instead. - - :param header: Header of page - :type header: string - - :returns: Notification - :rtype: string - ''' - - ready_screen("select_obs_screen") - screen.addstr(1, 1, header + " > Select Observation ") - screen.addstr(8, 1, "Observations Table: ") - screen.addstr(9, 2, "|Dataset ID| - |Parameter ID| - |Time Step| - |Start Date| - | End Date | - | Min Lat | - | Max Lat | - | Min Lon | - | Max Lat | - |Database name") - screen.addstr(10, 2, "|----------| - |------------| - |---------| - |----------| - |----------| - |---------| - |---------| - |---------| - |---------| - |-------------") - all_obs_info = rcmed.get_parameters_metadata() - try: - for position, obs_info in enumerate(all_obs_info): - dataset_id = obs_info['dataset_id'] - parameter_id = obs_info['parameter_id'] - timestep = obs_info['timestep'] - start_date = obs_info['start_date'] - end_date = obs_info['end_date'] - min_lat = eval(obs_info['bounding_box'].encode())[2][0] if obs_info['bounding_box'] else None - max_lat = eval(obs_info['bounding_box'].encode())[0][0] if obs_info['bounding_box'] else None - min_lon = eval(obs_info['bounding_box'].encode())[2][1] if obs_info['bounding_box'] else None - max_lon = eval(obs_info['bounding_box'].encode())[0][1] if obs_info['bounding_box'] else None - database = obs_info['database'] - line = "|{0:>10}| - |{1:>12}| - |{2:>9}| - |{3}| - |{4}| - |{5:>9}| - |{6:>9}| - |{7:>9}| - |{8:>9}| - |{9}".format( - dataset_id, parameter_id, timestep, start_date, end_date, - str(min_lat), str(max_lat), str(min_lon), str(max_lon), database) - screen.addstr(11 + position, 2, line) - except: - ready_screen("select_obs_screen") - screen.addstr(1, 1, header + " > Select Observation ") - screen.addstr(10, 1, "Observation table cannot be shown due to small screen size. ") - screen.addstr(11, 1, "Please enlarge your screen and try again or refer to 'http://rcmes.jpl.nasa.gov/rcmed/parameters'. ") - try: - screen.addstr(4, 2, "Enter Dataset ID: ") - dataset_id = screen.getstr() - screen.addstr(5, 2, "Enter Parameter ID: ") - parameter_id = screen.getstr() - - for obs in all_obs_info: - if obs['dataset_id'] == dataset_id and obs['parameter_id'] == parameter_id: - observations_info.append({ - 'database':obs['database'], - 'dataset_id':dataset_id, - 'parameter_id':parameter_id, - 'start_date':obs['start_date'], - 'end_date':obs['end_date'], - 'bounding_box':obs['bounding_box'], - 'timestep':obs['timestep'], - 'min_lat':float(eval(obs['bounding_box'].encode())[2][0]) if obs['bounding_box'] else None, - 'max_lat':float(eval(obs['bounding_box'].encode())[0][0]) if obs['bounding_box'] else None, - 'min_lon':float(eval(obs['bounding_box'].encode())[2][1]) if obs['bounding_box'] else None, - 'max_lon':float(eval(obs['bounding_box'].encode())[0][1]) if obs['bounding_box'] else None, - 'timestep':obs['timestep'], - 'timestep':obs['timestep'], - 'timestep':obs['timestep'], - 'lat_res':float(obs['lat_res'].encode()), - 'lon_res':float(obs['lon_res'].encode()) - }) - note = "Observation sucessfully selected." - break - else: - note = "WARNING: Observation cannot be selected. There is no observation with given info." - except: - note = "WARNING: Observation cannot be selected, dataset or parameter id is wrong." - - return note - - -def unselect_obs_screen(header): - '''Generates screen to be able to unselect observations. - Observations can be unselected by entering index allocated to them. - - :param header: Header of page - :type header: string - - :returns: Notification - :rtype: string - ''' - - ready_screen("unselect_obs_screen") - screen.addstr(1, 1, header + " > Unselect Observation ") - screen.addstr(6, 1, "List Observation(s):") - for i, obs_info in enumerate(observations_info): - screen.addstr(8 + i, 10, " [" + str(i) + "] : " + " Dataset ID: " + obs_info['dataset_id'] + " - Parameter ID: "+ obs_info['parameter_id'] + " - Database: "+ obs_info['database']) - screen.addstr(3, 2, "Select the observation to remove (press enter to go back): ") - try: - obs_remove_index = screen.getstr() - observations_info.pop(int(obs_remove_index)) - note = "Observation sucessfully unselected." - except: - note = "WARNING: Unselecting model was not successful." - - return note - - -def list_obs_screen(header): - '''Generates screen to list observations. - - :param header: Header of page - :type header: string - ''' - - ready_screen("list_obs_screen") - screen.addstr(1, 1, header + " > List Observation ") - screen.addstr(6, 6, "List of observation(s): ") - for i, obs_info in enumerate(observations_info): - screen.addstr(8 + i, 10, " [" + str(i) + "] : " + " Dataset ID: " + obs_info['dataset_id'] + " - Parameter ID: "+ obs_info['parameter_id'] + " - Database: "+ obs_info['database']) - screen.addstr(4, 4, "Return to Manage Observation (press Enter) :") - screen.getstr() - - -def manage_obs_screen(header, note=""): - '''Generates Manage Observation screen. - - :param header: Header of page - :type header: string - :param note: Notification, defult to empty string. - :type note: string - ''' - - option = '' - while option != '0': - ready_screen("manage_obs_screen", note) - screen.addstr(1, 1, header) - screen.addstr(4, 4, "1 - Select Observation [Number of selected observation: {0}]".format(len(observations_info))) - screen.addstr(6, 4, "2 - Unselect Observation") - screen.addstr(8, 4, "3 - List Observation") - screen.addstr(10, 4, "0 - Return to Main Menu") - screen.addstr(12, 2, "Select an option: ") - screen.refresh() - - option = screen.getstr() - if option == '1': - note = select_obs_screen(header) - if option == '2': - note = unselect_obs_screen(header) - if option == '3': - list_obs_screen(header) - note = " " - - -############################################################## -# Run Evaluation Screen -############################################################## - -def run_screen(model_datasets, models_info, observations_info, - overlap_start_time, overlap_end_time, overlap_min_lat, - overlap_max_lat, overlap_min_lon, overlap_max_lon, - temp_grid_setting, spatial_grid_setting, working_directory, plot_title): - '''Generates screen to show running evaluation process. - - :param model_datasets: list of model dataset objects - :type model_datasets: list - :param models_info: list of dictionaries that contain information for each model - :type models_info: list - :param observations_info: list of dictionaries that contain information for each observation - :type observations_info: list - :param overlap_start_time: overlap start time between model and obs start time - :type overlap_start_time: datetime - :param overlap_end_time: overlap end time between model and obs end time - :type overlap_end_time: float - :param overlap_min_lat: overlap minimum lat between model and obs minimum lat - :type overlap_min_lat: float - :param overlap_max_lat: overlap maximum lat between model and obs maximum lat - :type overlap_max_lat: float - :param overlap_min_lon: overlap minimum lon between model and obs minimum lon - :type overlap_min_lon: float - :param overlap_max_lon: overlap maximum lon between model and obs maximum lon - :type overlap_max_lon: float - :param temp_grid_setting: temporal grid option such as hourly, daily, monthly and annually - :type temp_grid_setting: string - :param spatial_grid_setting: - :type spatial_grid_setting: string - :param working_directory: path to a directory for storring outputs - :type working_directory: string - :param plot_title: Title for plot - :type plot_title: string - ''' - - option = None - if option != "0": - ready_screen("manage_obs_screen") - y = screen.getmaxyx()[0] - screen.addstr(2, 2, "Evaluation started....") - screen.refresh() - - OUTPUT_PLOT = "plot" - - dataset_id = int(observations_info[0]['dataset_id']) #just accepts one dataset at this time - parameter_id = int(observations_info[0]['parameter_id']) #just accepts one dataset at this time - - new_bounds = Bounds(overlap_min_lat, overlap_max_lat, overlap_min_lon, overlap_max_lon, overlap_start_time, overlap_end_time) - model_dataset = dsp.subset(new_bounds, model_datasets[0]) #just accepts one model at this time - - #Getting bound info of subseted model file to retrive obs data with same bound as subseted model - new_model_spatial_bounds = model_dataset.spatial_boundaries() - new_model_temp_bounds = model_dataset.time_range() - new_min_lat = new_model_spatial_bounds[0] - new_max_lat = new_model_spatial_bounds[1] - new_min_lon = new_model_spatial_bounds[2] - new_max_lon = new_model_spatial_bounds[3] - new_start_time = new_model_temp_bounds[0] - new_end_time = new_model_temp_bounds[1] - - screen.addstr(4, 4, "Retrieving data...") - screen.refresh() - - #Retrieve obs data - obs_dataset = rcmed.parameter_dataset( - dataset_id, - parameter_id, - new_min_lat, - new_max_lat, - new_min_lon, - new_max_lon, - new_start_time, - new_end_time) - screen.addstr(4, 4, "--> Data retrieved.") - screen.refresh() - - screen.addstr(5, 4, "Temporally regridding...") - screen.refresh() - if temp_grid_setting.lower() == 'hourly': - days = 0.5 - elif temp_grid_setting.lower() == 'daily': - days = 1 - elif temp_grid_setting.lower() == 'monthly': - days = 31 - else: - days = 365 - model_dataset = dsp.temporal_rebin(model_dataset, timedelta(days)) - obs_dataset = dsp.temporal_rebin(obs_dataset, timedelta(days)) - screen.addstr(5, 4, "--> Temporally regridded.") - screen.refresh() - - new_lats = np.arange(new_min_lat, new_max_lat, spatial_grid_setting) - new_lons = np.arange(new_min_lon, new_max_lon, spatial_grid_setting) - - screen.addstr(6, 4, "Spatially regridding...") - screen.refresh() - spatial_gridded_model = dsp.spatial_regrid(model_dataset, new_lats, new_lons) - spatial_gridded_obs = dsp.spatial_regrid(obs_dataset, new_lats, new_lons) - screen.addstr(6, 4, "--> Spatially regridded.") - screen.refresh() - - screen.addstr(7, 4, "Setting up metrics...") - screen.refresh() - bias = metrics.Bias() - bias_evaluation = evaluation.Evaluation(spatial_gridded_model, [spatial_gridded_obs], [bias]) - screen.addstr(7, 4, "--> Metrics setting done.") - screen.refresh() - - screen.addstr(8, 4, "Running evaluation.....") - screen.refresh() - bias_evaluation.run() - results = bias_evaluation.results[0][0] - screen.addstr(8, 4, "--> Evaluation Finished.") - screen.refresh() - - screen.addstr(9, 4, "Generating plots....") - screen.refresh() - lats = new_lats - lons = new_lons - - gridshape = (1, 1) - sub_titles = [""] #No subtitle set for now - - if not os.path.exists(working_directory): - os.makedirs(working_directory) - - for i in range(len(results)): - fname = working_directory + OUTPUT_PLOT + str(i) - plotter.draw_contour_map(results[i], lats, lons, fname, - gridshape=gridshape, ptitle=plot_title, - subtitles=sub_titles) - screen.addstr(9, 4, "--> Plots generated.") - screen.refresh() - screen.addstr(y-2, 1, "Press 'enter' to Exit: ") - option = screen.getstr() - - -############################################################## -# Settings Screen -############################################################## - -def get_model_temp_bound(): - '''Get model temporal bound. - - :returns: model start and end time - :rtypes: (datatime, datetime) - ''' - - models_start_time = [] - models_end_time = [] - for model in model_datasets: - models_start_time.append(model.time_range()[0]) - models_end_time.append(model.time_range()[1]) - - return models_start_time, models_end_time - - -def get_obs_temp_bound(): - '''Get observation temporal bound. - - :returns: observation start and end time - :rtype: (datetime, datetime) - ''' - - observations_start_time = [] - observations_end_time = [] - for obs in observations_info: - obs_start_time = datetime.strptime(obs['start_date'], "%Y-%m-%d") - observations_start_time.append(obs_start_time) - obs_end_time = datetime.strptime(obs['end_date'], "%Y-%m-%d") - observations_end_time.append(obs_end_time) - - return observations_start_time, observations_end_time - - -def get_temp_overlap(models_start_time, models_end_time, observations_start_time, observations_end_time): - '''Calculate temporal overlap between given datasets. - - :param models_start_time: models start time - :type models_start_time: list of datetimes - :param models_end_time: models end time - :type models_end_time: list of datetime - :param observations_start_time: obs start time - :type observations_start_time: list of datetimes - :param observations_end_time: obs end time - :type observations_end_time: list of datetimes - - :returns: overlap start and end time between model and observation - :rtype: (datetime, datetime) - ''' - - overlap_start_time = max(models_start_time + observations_start_time) - overlap_end_time = min(models_end_time + observations_end_time) - - #Need to check if all datasets have temporal overlap, otherwise return - # to main menu and print a warning as notification. - if overlap_end_time <= overlap_start_time: - main_menu(model_datasets, models_info, observation_datasets, observations_info, note="WARNING: One or more dataset does not have temporal overlap with others.") - - return overlap_start_time, overlap_end_time - - -def get_model_spatial_bound(): #TODO: convert longitudes to -180, 180 to match with observation data - '''Get model spatial bound. - - :returns: all models spatial boundaries - :rtype: list - ''' - - models_bound = [] - for model in model_datasets: - models_bound.append(model.spatial_boundaries()) - - return models_bound - - -def get_obs_spatial_bound(): - '''Get observation spatial bound. - - :returns: all observations spatial boundaries - :rtype: list - ''' - - observations_bound = [] - for obs in observations_info: - observations_bound.append([obs['min_lat'], obs['max_lat'], obs['min_lon'], obs['max_lon']]) - - return observations_bound - - -def get_spatial_overlap(models_bound, observations_bound): - '''Calculate spatial overlap between given datasets. - - :param models_bound: all models spatial boundaries information - :type models_bound: list - :param observations_bound: all observations spatial boundaries information - :type observations_bound: list - - :returns: spatial boundaries overlap between model and observation - :rtype: (float, float, float, float) - ''' - - datasets_bound = models_bound + observations_bound - overlap_min_lat = max(each[0] for each in datasets_bound) - overlap_max_lat = min(each[1] for each in datasets_bound) - overlap_min_lon = max(each[2] for each in datasets_bound) - overlap_max_lon = min(each[3] for each in datasets_bound) - - #Need to check if all datasets have spatial overlap, otherwise return - # to main menu and print a warning as notification. - if overlap_max_lat <= overlap_min_lat or overlap_max_lon <= overlap_min_lon: - main_menu(model_datasets, models_info, observation_datasets, observations_info, note="WARNING: One or more dataset does not have spatial overlap with others.") - - return overlap_min_lat, overlap_max_lat, overlap_min_lon, overlap_max_lon - - -def settings_screen(header): - '''Generates screen for settings before running evaluation. - - :param header: Header of page - :type header: string - ''' - - note = "" - models_start_time, models_end_time = get_model_temp_bound() - observations_start_time, observations_end_time = get_obs_temp_bound() - overlap_start_time, overlap_end_time = get_temp_overlap(models_start_time, models_end_time, observations_start_time, observations_end_time) - models_bound = get_model_spatial_bound() - observations_bound = get_obs_spatial_bound() - overlap_min_lat, overlap_max_lat, overlap_min_lon, overlap_max_lon = get_spatial_overlap(models_bound, observations_bound) - model_temp_res = model_datasets[0].temporal_resolution() #just accepts one model at this time - obs_temp_res = observations_info[0]['timestep'] #just accepts one obs at this time - model_lat_res = model_datasets[0].spatial_resolution()[0] #just accepts one model at this time - model_lon_res = model_datasets[0].spatial_resolution()[1] #just accepts one model at this time - obs_lat_res = observations_info[0]['lat_res'] #just accepts one obs at this time - obs_lon_res = observations_info[0]['lon_res'] #just accepts one obs at this time - - temp_grid_option = "Observation" - temp_grid_setting = obs_temp_res - spatial_grid_option = "Observation" - spatial_grid_setting = obs_lat_res - subregion_path = None - metrics = 'BIAS' - working_directory = os.getcwd() + "/plots/" #Default value of working directory set to "plots" folder in current directory - plot_title = '' #TODO: ask user about plot title or figure out automatically - - fix_min_time = overlap_start_time - fix_max_time = overlap_end_time - fix_min_lat = overlap_min_lat - fix_max_lat = overlap_max_lat - fix_min_lon = overlap_min_lon - fix_max_lon = overlap_max_lon - - option = '' - while option != '0': - ready_screen("settings_screen", note) - screen.addstr(1, 1, header) - screen.addstr(4, 4, "Number of model file: {0}".format(str(len(model_datasets)))) - screen.addstr(5, 4, "Number of observation: {0}".format(str(len(observations_info)))) - screen.addstr(6, 4, "Temporal Boundaries: [start time = {0} - end time = {1}]".format(overlap_start_time, overlap_end_time)) - screen.addstr(7, 4, "Spatial Boundaries: [min-lat={0} max-lat={1} min-lon={2} max-lon={3}]".format(overlap_min_lat, overlap_max_lat, overlap_min_lon, overlap_max_lon)) - screen.addstr(8, 4, "Temporal Resolution: [Model={0} - Observation={1}]".format(model_temp_res, obs_temp_res)) - screen.addstr(9, 4, "Spatial Resolution: [Model: lat={0} lon={1} - Observation: lat={2} lon={3}]".format(model_lat_res, model_lon_res, obs_lat_res, obs_lon_res)) - screen.addstr(10, 4, "Temporal Grid Option: [{0}]".format(temp_grid_option)) - screen.addstr(11, 4, "Spatial Grid Option: [{0}]".format(spatial_grid_option)) - screen.addstr(12, 4, "Working Directory: {0}".format(working_directory)) - screen.addstr(13, 4, "Metrics: {0}".format(metrics)) - - screen.addstr(15, 5, "1 - Change Temporal Boundaries") - screen.addstr(16, 5, "2 - Change Spatial Boundaries") - screen.addstr(17, 5, "3 - Change Temporal Gridding") - screen.addstr(18, 5, "4 - Change Spatial Gridding") - screen.addstr(19, 5, "5 - Add Subregion file (txt file) [Coming Soon....]") - screen.addstr(20, 5, "6 - Modify Metric (add/remove) [Coming Soon....]") - screen.addstr(21, 5, "7 - Change Working Directory") - screen.addstr(22, 5, "8 - Change Plot Title [Coming Soon....]") - screen.addstr(23, 5, "0 - Return to Main Menu") - screen.addstr(26, 5, "r - Run Evaluation") - screen.addstr(28, 2, "Select an option: ") - - screen.refresh() - option = screen.getstr() - ### TODO: It breaks when you want to pick start time after end time and same issue with lat, lon. - - if option == '1': - screen.addstr(33, 4, "Enter Start Time [min time: {0}] (Format YYYY-MM-DD):".format(fix_min_time)) - new_start_time = screen.getstr() - try: - new_start_time = datetime.strptime(new_start_time, '%Y-%m-%d') - if new_start_time < fix_min_time or new_start_time > fix_max_time or new_start_time > overlap_end_time: - note = "Start time has not changed." - else: - overlap_start_time = new_start_time - note = "Start time has changed successfully." - except: - note = "Start time has not changed." - screen.addstr(34, 4, "Enter End Time [max time:{0}] (Format YYYY-MM-DD):".format(fix_max_time)) - new_max_time = screen.getstr() - try: - new_max_time = datetime.strptime(new_max_time, '%Y-%m-%d') - if new_max_time > fix_max_time or new_max_time < fix_min_time or new_max_time < overlap_start_time: - note = note + " End time has not changed." - else: - overlap_end_time = new_max_time - note = note + "End time has changed successfully." - except: - note = note + " End time has not changed." - - if option == '2': - screen.addstr(33, 4, "Enter Minimum Latitude [{0}]:".format(fix_min_lat)) - new_min_lat = screen.getstr() - try: - new_min_lat = float(new_min_lat) - if new_min_lat < fix_min_lat or new_min_lat > fix_max_lat or new_min_lat > overlap_max_lat: - note = "Minimum latitude has not changed." - else: - overlap_min_lat = new_min_lat - note = "Minimum latitude has changed successfully." - except: - note = "Minimum latitude has not changed." - screen.addstr(34, 4, "Enter Maximum Latitude [{0}]:".format(fix_max_lat)) - new_max_lat = screen.getstr() - try: - new_max_lat = float(new_max_lat) - if new_max_lat > fix_max_lat or new_max_lat < fix_min_lat or new_max_lat < overlap_min_lat: - note = note + " Maximum latitude has not changed." - else: - overlap_max_lat = new_max_lat - note = note + "Maximum latitude has changed successfully." - except: - note = note + " Maximum latitude has not changed." - screen.addstr(35, 4, "Enter Minimum Longitude [{0}]:".format(fix_min_lon)) - new_min_lon = screen.getstr() - try: - new_min_lon = float(new_min_lon) - if new_min_lon < fix_min_lon or new_min_lon > fix_max_lon or new_min_lon > overlap_max_lon: - note = note + " Minimum longitude has not changed." - else: - overlap_min_lon = new_min_lon - note = note + "Minimum longitude has changed successfully." - except: - note = note + " Minimum longitude has not changed." - screen.addstr(36, 4, "Enter Maximum Longitude [{0}]:".format(fix_max_lon)) - new_max_lon = screen.getstr() - try: - new_max_lon = float(new_max_lon) - if new_max_lon > fix_max_lon or new_max_lon < fix_min_lon or new_max_lon < overlap_min_lon: - note = note + " Maximum longitude has not changed." - else: - overlap_max_lon = new_max_lon - note = note + "Maximum longitude has changed successfully." - except: - note = note + " Maximum longitude has not changed." - - if option == '3': - screen.addstr(33, 4, "Enter Temporal Gridding Option [Model or Observation]:") - new_temp_grid_option = screen.getstr() - if new_temp_grid_option.lower() == 'model': - temp_grid_option = 'Model' - temp_grid_setting = model_temp_res - note = "Temporal gridding option has changed successfully to {0}".format(temp_grid_option) - elif new_temp_grid_option.lower() == 'observation': - temp_grid_option = 'Observation' - temp_grid_setting = obs_temp_res - note = "Temporal gridding option has changed successfully to {0}".format(temp_grid_option) - else: - note = "Temporal gridding option has not be changed." - - if option == '4': - screen.addstr(33, 4, "Enter Spatial Gridding Option [Model, Observation or User]:") - new_spatial_grid_option = screen.getstr() - if new_spatial_grid_option.lower() == 'model': - spatial_grid_option = 'Model' - spatial_grid_setting = model_lat_res - note = "Spatial gridding option has changed successfully to {0}".format(spatial_grid_option) - elif new_spatial_grid_option.lower() == 'observation': - spatial_grid_option = 'Observation' - spatial_grid_setting = obs_lat_res - note = "Spatial gridding option has changed successfully to {0}".format(spatial_grid_option) - elif new_spatial_grid_option.lower() == 'user': - screen.addstr(34, 4, "Please enter spatial resolution: ") - user_res = screen.getstr() - try: - user_res = float(user_res) - spatial_grid_option = 'User: resolution {0}'.format(str(user_res)) - spatial_grid_setting = user_res - note = "Spatial gridding option has changed successfully to {0}".format(spatial_grid_option) - except: - note = "Spatial gridding option has not be changed." - else: - note = "Spatial gridding option has not be changed." - - ''' - if option == '5': - screen.addstr(33, 4, "Please enter one Subregion path:") - subregion_path = screen.getstr() - ''' - if option == '7': - screen.addstr(33, 4, "Please enter working directory path:") - working_directory = screen.getstr() - if working_directory[-1] != '/': - working_directory = working_directory + "/" - - if option == '8': - screen.addstr(33, 4, "Please enter plot title:") - plot_title = screen.getstr() - - if option.lower() == 'r': - run_screen(model_datasets, models_info, observations_info, overlap_start_time, overlap_end_time, \ - overlap_min_lat, overlap_max_lat, overlap_min_lon, overlap_max_lon, \ - temp_grid_setting, spatial_grid_setting, working_directory, plot_title) - - -############################################################## -# Main Menu Screen -############################################################## - -def main_menu(model_datasets, models_info, observation_datasets, observations_info, note=""): - '''This function Generates main menu page. - - :param model_datasets: list of model dataset objects - :type model_datasets: list - :param models_info: list of dictionaries that contain information for each model - :type models_info: list - :param observation_datasets: list of observation dataset objects - :type observation_datasets: list - :param observations_info: list of dictionaries that contain information for each observation - :type observations_info: list - ''' - - option = '' - while option != '0': - ready_screen("main_menu", note) - model_status = "NC" if len(model_datasets) == 0 else "C" #NC (Not Complete), if there is no model added, C (Complete) if model is added - obs_status = "NC" if len(observations_info) == 0 else "C" #NC (Not Complete), if there is no observation added, C (Complete) if observation is added - screen.addstr(1, 1, "Main Menu:") - screen.addstr(4, 4, "1 - Manage Model ({0})".format(model_status)) - screen.addstr(6, 4, "2 - Manage Observation ({0})".format(obs_status)) - screen.addstr(8, 4, "3 - Run(Config File) [coming soon....]") - screen.addstr(10, 4, "4 - Run(Settings)") - screen.addstr(12, 4, "0 - EXIT") - screen.addstr(18, 2, "Select an option: ") - screen.refresh() - option = screen.getstr() - - if option == '1': - header = "Main Menu > Manage Model" - manage_model_screen(header) - if option == '2': - header = "Main Menu > Manage Observation" - manage_obs_screen(header) - if option == '3': - header = "Main Menu > Run(Config File)" - #TODO: function to read config file and run evaluation - if option == '4': - if model_status =='NC' or obs_status == 'NC': - main_menu(model_datasets, models_info, observation_datasets, observations_info, note="WARNING: Please complete step 1 and 2 before 4.") - else: - header = "Main Menu > Run(Settings)" - settings_screen(header) - curses.endwin() - sys.exit() - - -if __name__ == '__main__': - TITLE = "Open Climate Workbench Evaluation System" - ORGANIZATION = "Apache Software Foundation" - screen = curses.initscr() - model_datasets = [] #list of model dataset objects - models_info = [] #list of dictionaries that contain information for each model - observation_datasets = [] #list of observation dataset objects - observations_info = [] #list of dictionaries that contain information for each observation - main_menu(model_datasets, models_info, observation_datasets, observations_info)
