def _land_cover(self, model_run, values, errors): land_cover_controller_helper = LandCoverControllerHelper() if not request.POST: self._user_service.set_current_model_run_creation_action(self.current_user, "land_cover") land_cover_controller_helper.add_land_covers_to_context(c, errors, model_run) if len(errors) > 0: helpers.error_flash(errors['land_cover_actions']) return render('model_run/land_cover.html') else: land_cover_controller_helper.save_land_cover_actions(values, errors, model_run) if len(errors) > 0: helpers.error_flash(errors['land_cover_actions']) return render('model_run/land_cover.html') else: # Get the action to perform self._model_run_controller_helper.check_user_quota(self.current_user) try: action = values['submit'] except KeyError: action = None if action == u'Next': redirect(url(controller='model_run', action='output')) else: redirect(url(controller='model_run', action='extents'))
def _single_cell_land_cover(self, model_run, values, errors): land_cover_controller_helper = LandCoverControllerHelper() if not request.POST: self._user_service.set_current_model_run_creation_action(self.current_user, "land_cover") land_cover_controller_helper.add_fractional_land_cover_to_context(c, errors, model_run, self.current_user) return render('model_run/fractional_land_cover.html') else: land_cover_controller_helper.save_fractional_land_cover(values, errors, model_run, self.current_user) if len(errors) > 0: if 'land_cover_frac' in errors: helpers.error_flash(errors['land_cover_frac']) land_cover_controller_helper.add_fractional_land_cover_to_context( c, errors, model_run, self.current_user) c.land_cover_values = values del values['submit'] html = render('model_run/fractional_land_cover.html') return htmlfill.render( html, defaults=values, errors=errors, auto_error_formatter=BaseController.error_formatter ) else: self._model_run_controller_helper.check_user_quota(self.current_user) try: action = values['submit'] except KeyError: action = None if action == u'Next': redirect(url(controller='model_run', action='output')) else: redirect(url(controller='model_run', action='extents'))
def land_cover(self): """ Set the land cover options """ model_run = self.get_model_run_being_created_or_redirect(self._model_run_service) values = dict(request.params) errors = {} multicell = not model_run.is_for_single_cell() and not 'fractional_cover' in values if 'reset_fractional_cover' in values: land_cover_controller_helper = LandCoverControllerHelper() land_cover_controller_helper.reset_fractional_cover(model_run) redirect(url(controller='model_run', action='land_cover')) if multicell: return self._land_cover(model_run, values, errors) else: latlon = model_run.get_python_parameter_value(constants.JULES_PARAM_POINTS_FILE, is_list=True) if latlon is None: helpers.error_flash(u"You must set model run extents set before you can edit the land cover") redirect(url(controller='model_run', action='extents')) return self._single_cell_land_cover(model_run, values, errors)
def setUp(self): driving_data = DrivingDataset() driving_data.name = "Driving1" driving_data.id = 1 self.return_dd_id = 10 self.model_run = ModelRun() self.model_run.name = "Model Run1" self.model_run.driving_dataset = driving_data self.model_run.driving_dataset_id = 1 self.land_cover_service = LandCoverService() self.land_cover_service.get_land_cover_region_by_id = self._mock_lcs_get_land_cover_region self.land_cover_service.get_land_cover_values = self._mock_get_land_cover_values self.land_cover_service.get_land_cover_categories = self._mock_get_land_cover_categories self.land_cover_service.save_land_cover_actions_for_model = MagicMock() self.land_cover_service.get_land_cover_actions_for_model = self._mock_lcs_get_actions_for_model_run self.land_cover_service.save_fractional_land_cover_for_model = MagicMock() self.land_cover_service.get_default_fractional_cover = self._mock_lcs_get_default_fractional_cover self.land_cover_service.save_default_soil_properties = MagicMock() self.land_cover_helper = LandCoverControllerHelper(land_cover_service=self.land_cover_service)
class TestLandCoverControllerHelper(BaseTest): def setUp(self): driving_data = DrivingDataset() driving_data.name = "Driving1" driving_data.id = 1 self.return_dd_id = 10 self.model_run = ModelRun() self.model_run.name = "Model Run1" self.model_run.driving_dataset = driving_data self.model_run.driving_dataset_id = 1 self.land_cover_service = LandCoverService() self.land_cover_service.get_land_cover_region_by_id = self._mock_lcs_get_land_cover_region self.land_cover_service.get_land_cover_values = self._mock_get_land_cover_values self.land_cover_service.get_land_cover_categories = self._mock_get_land_cover_categories self.land_cover_service.save_land_cover_actions_for_model = MagicMock() self.land_cover_service.get_land_cover_actions_for_model = self._mock_lcs_get_actions_for_model_run self.land_cover_service.save_fractional_land_cover_for_model = MagicMock() self.land_cover_service.get_default_fractional_cover = self._mock_lcs_get_default_fractional_cover self.land_cover_service.save_default_soil_properties = MagicMock() self.land_cover_helper = LandCoverControllerHelper(land_cover_service=self.land_cover_service) class Context(object): """ Mock context object """ pass @staticmethod def _mock_get_land_cover_values(model_run, return_ice=False): land_cover_values = [] types = {1: "BT", 2: "NT", 3: "C3G", 4: "C4G", 5: "Shrub", 6: "Urban", 7: "Lake", 8: "Soil", 9: "Ice"} for index in types: land_cover_value = LandCoverValue() land_cover_value.id = index land_cover_value.index = index land_cover_value.name = types[index] land_cover_values.append(land_cover_value) return land_cover_values @staticmethod def _mock_get_land_cover_categories(driving_data_id): cat1 = LandCoverRegionCategory() cat1.driving_dataset_id = driving_data_id cat1.name = "Rivers" cat1.id = 1 region1 = LandCoverRegion() region1.id = 1 region1.name = "Thames" region1.category_id = 1 region1.category = cat1 region2 = LandCoverRegion() region2.id = 2 region2.name = "Itchen" region2.category_id = 1 region2.category = cat1 cat1.regions = [region1, region2] cat2 = LandCoverRegionCategory() cat2.driving_dataset_id = driving_data_id cat2.name = "Counties" cat2.id = 2 region3 = LandCoverRegion() region3.id = 3 region3.name = "Hampshire" region3.category_id = 2 region3.category = cat2 region4 = LandCoverRegion() region4.id = 4 region4.name = "Oxfordshire" region4.category_id = 2 region4.category = cat2 cat2.regions = [region3, region4] return [cat1, cat2] @staticmethod def _mock_lcs_get_land_cover_region(id): dds = DrivingDataset() dds.id = 1 land_cover_type = LandCoverRegionCategory() land_cover_type.id = 1 land_cover_type.driving_dataset_id = 1 land_cover_type.driving_dataset = dds land_cover_region = LandCoverRegion() land_cover_region.id = id land_cover_region.name = "Sand" land_cover_region.category = land_cover_type return land_cover_region @staticmethod def _mock_lcs_get_land_cover_region_wrong_dataset(id): dds = DrivingDataset() dds.id = 7 land_cover_type = LandCoverRegionCategory() land_cover_type.id = 1 land_cover_type.driving_dataset_id = 7 land_cover_type.driving_dataset = dds land_cover_region = LandCoverRegion() land_cover_region.id = id land_cover_region.name = "Sand" land_cover_region.category = land_cover_type return land_cover_region @staticmethod def _mock_lcs_get_actions_for_model_run(model_run): cat = LandCoverRegionCategory() cat.id = 1 cat.name = "Countries" cat.driving_dataset_id = 1 region = LandCoverRegion() region.id = 1 region.name = "Wales" region.category = cat action = LandCoverAction() action.id = 1 action.region = region action.value_id = 1 return [action] @staticmethod def _mock_lcs_get_actions_for_model_run_wrong_dataset(model_run): cat = LandCoverRegionCategory() cat.id = 1 cat.name = "Countries" cat.driving_dataset_id = 2 region = LandCoverRegion() region.id = 1 region.name = "Wales" region.category = cat action = LandCoverAction() action.id = 1 action.region = region action.value_id = 1 return [action] @staticmethod def _mock_lcs_get_actions_for_model_run_no_actions(model_run, user): return [] @staticmethod def _mock_lcs_get_default_fractional_cover(model_run, user): return [0.02, 0.11, 0.02, 0.05, 0.35, 0.19, 0.22, 0.04, 0.0] @staticmethod def _mock_lcs_get_awkward_default_fractional_cover(model_run, user): return [0.0102193951607, 0.0, 0.361101979017, 0.0344029143453, 0.0, 0.369327515364, 0.0, 0.124948188663, 0.0] @staticmethod def _mock_lcs_get_missing_default_fractional_cover(model_run, user): return 9 * [-9999.99] def test_GIVEN_single_action_WHEN_save_land_cover_THEN_land_cover_action_saved(self): values = {"action_1_region": u"1", "action_1_value": u"8", "action_1_order": u"1"} self.land_cover_helper.save_land_cover_actions(values, {}, self.model_run) called_land_cover_actions = self.land_cover_service.save_land_cover_actions_for_model.call_args[0][1] lca1 = called_land_cover_actions[0] assert_that(lca1.region_id, is_(1)) assert_that(lca1.value_id, is_(8)) def test_GIVEN_two_actions_WHEN_save_land_cover_THEN_both_saved_with_correct_order(self): values = { "action_1_region": u"1", "action_1_value": u"8", "action_1_order": u"1", "action_2_region": u"3", "action_2_value": u"7", "action_2_order": u"2", } self.land_cover_helper.save_land_cover_actions(values, {}, self.model_run) called_land_cover_actions = self.land_cover_service.save_land_cover_actions_for_model.call_args[0][1] lca1 = called_land_cover_actions[0] assert_that(lca1.region_id, is_(1)) assert_that(lca1.value_id, is_(8)) assert_that(lca1.order, is_(1)) lca2 = called_land_cover_actions[1] assert_that(lca2.region_id, is_(3)) assert_that(lca2.value_id, is_(7)) assert_that(lca2.order, is_(2)) def test_GIVEN_invalid_region_WHEN_save_land_cover_THEN_error_returned(self): # In this test, the region is for another dataset self.land_cover_service.get_land_cover_region_by_id = self._mock_lcs_get_land_cover_region_wrong_dataset values = {"action_1_region": u"10", "action_1_value": u"8", "action_1_order": u"1"} errors = {} self.land_cover_helper.save_land_cover_actions(values, errors, self.model_run) assert_that(len(errors), is_(1)) def test_GIVEN_invalid_region_WHEN_save_land_cover_THEN_land_covers_not_saved(self): # In this test, the region is for another dataset self.land_cover_service.get_land_cover_region_by_id = self._mock_lcs_get_land_cover_region_wrong_dataset values = {"action_1_region": u"10", "action_1_value": u"8", "action_1_order": u"1"} errors = {} self.land_cover_helper.save_land_cover_actions(values, errors, self.model_run) assert not self.land_cover_service.save_land_cover_actions_for_model.called def test_GIVEN_invalid_land_cover_value_WHEN_save_land_cover_THEN_error_returned(self): # In this test, the land cover value doesn't exist values = {"action_1_region": u"1", "action_1_value": u"77", "action_1_order": u"1"} errors = {} self.land_cover_helper.save_land_cover_actions(values, errors, self.model_run) assert_that(len(errors), is_(1)) def test_GIVEN_invalid_land_cover_value_WHEN_save_land_cover_THEN_land_covers_not_saved(self): # In this test, the land cover value doesn't exist values = {"action_1_region": u"1", "action_1_value": u"77", "action_1_order": u"1"} errors = {} self.land_cover_helper.save_land_cover_actions(values, errors, self.model_run) assert not self.land_cover_service.save_land_cover_actions_for_model.called def test_GIVEN_valid_values_WHEN_save_fractional_land_cover_THEN_values_saved_to_file(self): values = { "submit": u"Next", "fractional_cover": u"1", "land_cover_value_1": u"20", "land_cover_value_2": u"20", "land_cover_value_3": u"10", "land_cover_value_4": u"10", "land_cover_value_5": u"10", "land_cover_value_6": u"10", "land_cover_value_7": u"10", "land_cover_value_8": u"10", } errors = {} self.land_cover_helper.save_fractional_land_cover(values, errors, self.model_run, User()) assert_that(len(errors), is_(0)) called_save_frac_cover = self.land_cover_service.save_fractional_land_cover_for_model.call_args_list[0][0][1] assert_that(called_save_frac_cover, is_("0.2\t0.2\t0.1\t0.1\t0.1\t0.1\t0.1\t0.1\t0")) def test_GIVEN_values_dont_add_up_WHEN_save_fractional_land_cover_THEN_error_and_values_not_saved_to_file(self): values = { "submit": u"Next", "fractional_cover": u"1", "land_cover_value_1": u"20", "land_cover_value_2": u"25", "land_cover_value_3": u"10", "land_cover_value_4": u"10", "land_cover_value_5": u"10", "land_cover_value_6": u"10", "land_cover_value_7": u"10", "land_cover_value_8": u"15", } errors = {} self.land_cover_helper.save_fractional_land_cover(values, errors, self.model_run, User()) assert_that(errors["land_cover_frac"], is_("The sum of all the land cover fractions must be 100%")) assert not self.land_cover_service.save_fractional_land_cover_for_model.called def test_GIVEN_empty_values_WHEN_save_fractional_land_cover_THEN_error_returned(self): values = { "submit": u"Next", "fractional_cover": u"1", "land_cover_value_1": u"20", "land_cover_value_2": u"25", "land_cover_value_3": u"10", "land_cover_value_4": u"", "land_cover_value_5": u"10", "land_cover_value_6": u"10", "land_cover_value_7": u"10", "land_cover_value_8": u"15", } errors = {} self.land_cover_helper.save_fractional_land_cover(values, errors, self.model_run, User()) assert_that(errors["land_cover_value_4"], is_("Please enter a number")) assert not self.land_cover_service.save_fractional_land_cover_for_model.called def test_GIVEN_negative_value_WHEN_save_fractional_land_cover_THEN_error_returned(self): values = { "submit": u"Next", "fractional_cover": u"1", "land_cover_value_1": u"20", "land_cover_value_2": u"20", "land_cover_value_3": u"20", "land_cover_value_4": u"-25", "land_cover_value_5": u"20", "land_cover_value_6": u"20", "land_cover_value_7": u"10", "land_cover_value_8": u"15", } errors = {} self.land_cover_helper.save_fractional_land_cover(values, errors, self.model_run, User()) assert_that(errors["land_cover_value_4"], is_("Please enter a positive number")) assert not self.land_cover_service.save_fractional_land_cover_for_model.called def test_GIVEN_ice_chosen_WHEN_save_fractional_land_cover_THEN_values_saved_to_file(self): values = {"submit": u"Next", "land_cover_ice": u"1"} errors = {} self.land_cover_helper.save_fractional_land_cover(values, errors, self.model_run, User()) assert_that(len(errors), is_(0)) called_save_frac_cover = self.land_cover_service.save_fractional_land_cover_for_model.call_args_list[0][0][1] assert_that(called_save_frac_cover, is_("0\t0\t0\t0\t0\t0\t0\t0\t1")) def test_GIVEN_no_land_cover_actions_saved_WHEN_add_to_context_THEN_no_errors_returned(self): self.land_cover_service.save_land_cover_actions_for_model = self._mock_lcs_get_actions_for_model_run errors = {} self.land_cover_helper.add_land_covers_to_context(self.Context(), errors, self.model_run) assert_that(len(errors), is_(0)) def test_GIVEN_driving_data_has_categories_WHEN_add_to_context_THEN_context_contains_land_cover_categories(self): context = self.Context() self.land_cover_helper.add_land_covers_to_context(context, {}, self.model_run) assert_that(len(context.land_cover_categories), is_(2)) def test_GIVEN_nothing_saved_WHEN_add_to_context_THEN_context_contains_land_cover_values(self): context = self.Context() self.land_cover_helper.add_land_covers_to_context(context, {}, self.model_run) assert_that(len(context.land_cover_values), is_(9)) def test_GIVEN_land_cover_actions_saved_WHEN_add_to_context_THEN_context_contains_actions(self): context = self.Context() self.land_cover_helper.add_land_covers_to_context(context, {}, self.model_run) assert_that(len(context.land_cover_actions), is_(1)) def test_GIVEN_invalid_land_cover_actions_saved_WHEN_add_to_context_THEN_errors_returned(self): self.land_cover_service.get_land_cover_actions_for_model = ( self._mock_lcs_get_actions_for_model_run_wrong_dataset ) errors = {} self.land_cover_helper.add_land_covers_to_context(self.Context(), errors, self.model_run) assert_that(len(errors), is_(1)) def test_GIVEN_invalid_land_cover_actions_saved_WHEN_add_to_context_THEN_no_actions_returned(self): self.land_cover_service.get_land_cover_actions_for_model = ( self._mock_lcs_get_actions_for_model_run_wrong_dataset ) context = self.Context() self.land_cover_helper.add_land_covers_to_context(context, {}, self.model_run) assert_that(len(context.land_cover_actions), is_(0)) def test_GIVEN_nothing_WHEN_add_fractional_cover_to_context_THEN_cover_types_added(self): self.model_run.land_cover_frac = "0\t0\t0\t0\t0\t0\t0\t0\t1" context = self.Context() self.land_cover_helper.add_fractional_land_cover_to_context(context, {}, self.model_run, User()) assert_that(len(context.land_cover_values), is_(9)) def test_GIVEN_fractional_land_cover_saved_WHEN_add_fractional_cover_to_context_THEN_cover_values_added(self): self.model_run.land_cover_frac = "0\t0\t0\t0\t0\t0\t0\t0\t1" context = self.Context() self.land_cover_helper.add_fractional_land_cover_to_context(context, {}, self.model_run, User()) assert_that(len(context.land_cover_values), is_(9)) assert_that(context.land_cover_values["land_cover_ice"], is_(1)) def test_GIVEN_nothing_WHEN_add_fractional_cover_to_context_THEN_ice_index_added(self): self.model_run.land_cover_frac = "0\t0\t0\t0\t0\t0\t0\t0\t1" context = self.Context() self.land_cover_helper.add_fractional_land_cover_to_context(context, {}, self.model_run, User()) assert_that(context.ice_index, is_(9)) def test_GIVEN_no_fractional_land_cover_saved_WHEN_add_fractional_cover_to_context_THEN_defaults_returned(self): context = self.Context() self.land_cover_helper.add_fractional_land_cover_to_context(context, {}, self.model_run, User()) context_vals = [context.land_cover_values[key] for key in sorted(context.land_cover_values)] assert_that(context_vals, is_([2.0, 11.0, 2.0, 5.0, 35.0, 19.0, 22.0, 4.0])) def test_GIVEN_awkward_default_fractional_cover_WHEN_add_cover_to_context_THEN_truncated_and_adds_to_one(self): # Sometimes the default fractional cover retrieved from the netCDF file is awkward in that the # fractions are long (11 decimal places) and don't add up to precisely 1.0 self.land_cover_service.get_default_fractional_cover = self._mock_lcs_get_awkward_default_fractional_cover context = self.Context() self.land_cover_helper.add_fractional_land_cover_to_context(context, {}, self.model_run, User()) context_vals = [ context.land_cover_values[key] for key in sorted(context.land_cover_values) if "land_cover_value" in key ] assert sum(context_vals) - 100.0 < 0.00000001 def test_GIVEN_missing_fractional_cover_WHEN_add_cover_to_context_THEN_zeros_returned(self): self.land_cover_service.get_default_fractional_cover = self._mock_lcs_get_missing_default_fractional_cover context = self.Context() self.land_cover_helper.add_fractional_land_cover_to_context(context, {}, self.model_run, User()) for value in context.land_cover_values.values(): assert_that(value, is_(0.0))
def add_summary_fields_to_context(self, model_run, context, user): """ Add summary information to a template context, containing basic information for each of the pages in the workflow. :param model_run: Model run being created :param context: Context to summary fields to :param user: user :return: """ # Create page context.model_run = model_run context.science_config = self._model_run_service.get_science_configuration_by_id( model_run.science_configuration_id) # Driving data page driving_data = model_run.driving_dataset context.driving_data_name = model_run.driving_dataset.name # Extents page extents_controller_helper = ExtentsControllerHelper() context.extents_values = extents_controller_helper.create_values_dict_from_database(model_run, driving_data) # Land cover page land_cover_service = LandCoverService() context.land_cover_actions = land_cover_service.get_land_cover_actions_for_model(model_run) land_cover_helper = LandCoverControllerHelper() try: land_cover_helper.add_fractional_land_cover_to_context(context, {}, model_run, user) except ServiceException: pass # Outputs page output_variables = self._model_run_service.get_output_variables() output_variable_dict = dict((x.name, x.description) for x in output_variables) selected_vars = model_run.get_parameter_values(constants.JULES_PARAM_OUTPUT_VAR) selected_output_periods = model_run.get_parameter_values(constants.JULES_PARAM_OUTPUT_PERIOD) outputs = {} # Each group contains one output variable and one output period for selected_var in selected_vars: var_name = selected_var.get_value_as_python() if var_name not in outputs: outputs[var_name] = [] for output_period in selected_output_periods: if output_period.group_id == selected_var.group_id: period = output_period.get_value_as_python() if period == constants.JULES_YEARLY_PERIOD: outputs[var_name].append('Yearly') elif period == constants.JULES_MONTHLY_PERIOD: outputs[var_name].append('Monthly') elif period == constants.JULES_DAILY_PERIOD: outputs[var_name].append('Daily') else: outputs[var_name].append('Hourly') context.outputs = [] for output in outputs: context.outputs.append(output_variable_dict[output] + ' - ' + ', '.join(map(str, outputs[output])) + '') context.outputs.sort() if model_run.status.allow_visualise(): # Downloads context.output_variable_dict = output_variable_dict context.output_variable_id_dict = dict((x.name, x.id) for x in output_variables) context.downloads = outputs context.download_formats = ["NetCDF"] if context.extents_values['site'] == 'single': context.download_formats.append('ASCII')