def alter_yearly_monthly_output_profiles(self, parameters):
        """
        Adjusts the output profiles to avoid JULES errors like:
        "Jules error:file_ts_open: When using data_period=-1, data must start at 00:00:00 on 1st of month"
        caused by asking for output profiles that aren't valid for the selected run starts and ends
        :param parameters: List of parameters
        :return:
        """
        run_start = utils.get_first_parameter_value_from_parameter_list(parameters,
                                                                        constants.JULES_PARAM_RUN_START)
        run_end = utils.get_first_parameter_value_from_parameter_list(parameters,
                                                                      constants.JULES_PARAM_RUN_END)

        output_starts_to_add = []

        for parameter in parameters:
            if parameter.namelist.name == constants.JULES_PARAM_OUTPUT_PERIOD[0]:
                if parameter.name == constants.JULES_PARAM_OUTPUT_PERIOD[1]:
                    for pv_output_period in parameter.parameter_values:
                        period = pv_output_period.get_value_as_python()
                        group_id = pv_output_period.group_id
                        if period == constants.JULES_YEARLY_PERIOD:
                            if not utils.is_first_of_year(run_start):
                                next_year = utils.next_first_of_year(run_start)
                                if next_year <= run_end:
                                    output_start = ParameterValue()
                                    output_start.set_value_from_python(next_year)
                                    output_start.group_id = group_id
                                    output_starts_to_add.append(output_start)
                        elif period == constants.JULES_MONTHLY_PERIOD:
                            if not utils.is_first_of_month(run_start):
                                next_month = utils.next_first_of_month(run_start)
                                if next_month <= run_end:
                                    output_start = ParameterValue()
                                    output_start.set_value_from_python(next_month)
                                    output_start.group_id = group_id
                                    output_starts_to_add.append(output_start)

        # Add parameter values (output_start)
        for parameter in parameters:
            if parameter.namelist.name == constants.JULES_PARAM_OUTPUT_START[0]:
                if parameter.name == constants.JULES_PARAM_OUTPUT_START[1]:
                    parameter.parameter_values += output_starts_to_add

        return parameters
    def _create_new_model_run(self, session, user):
        """
        Create a brand new model run for user
        :param session: session to use
        :param user: Currently logged in user
        :return: New model run
        """
        model_run = ModelRun()
        model_run.change_status(session, constants.MODEL_RUN_STATUS_CREATED)
        model_run.user = user

        parameters = [
            [constants.JULES_PARAM_TIMESTEP_LEN, constants.TIMESTEP_LEN, None],
            [constants.JULES_PARAM_OUTPUT_RUN_ID, constants.RUN_ID, None],
            [constants.JULES_PARAM_OUTPUT_OUTPUT_DIR, "./" + constants.OUTPUT_DIR, None],
        ]

        # Add CHESS defaults:
        chess_defaults = ['surf_roff', 'sub_surf_roff', 'fqw_gb', 'rad_net', 'ftl_gb', 'gpp_gb', 'resp_p_gb',
                          'tstar_gb', 'snow_mass_gb', 't_soil', 'smc_tot', 'smcl', 'swet_liq_tot']
        chess_periods = [(constants.JULES_MONTHLY_PERIOD, "_monthly")]

        group_id = 0
        for output_variable in chess_defaults:
            for period, period_profile_name in chess_periods:
                parameters.append([constants.JULES_PARAM_OUTPUT_VAR, output_variable, group_id])
                parameters.append([constants.JULES_PARAM_OUTPUT_PERIOD, period, group_id])
                parameters.append([constants.JULES_PARAM_OUTPUT_PROFILE_NAME,
                                   output_variable + period_profile_name, group_id])
                parameters.append([constants.JULES_PARAM_OUTPUT_NVARS, 1, group_id])
                parameters.append([constants.JULES_PARAM_OUTPUT_MAIN_RUN, True, group_id])
                parameters.append([constants.JULES_PARAM_OUTPUT_TYPE, 'M', group_id])
                group_id += 1
        parameters.append([constants.JULES_PARAM_OUTPUT_NPROFILES, group_id, None])

        for constant, value, group_id in parameters:
            param = self.parameter_service.get_parameter_by_constant(constant, session)
            param_value = ParameterValue()
            param_value.parameter = param
            param_value.model_run = model_run
            param_value.group_id = group_id
            param_value.set_value_from_python(value)

        return model_run
    def _create_parameter_value_for_parameter(self, parameters, parameter_dict_name, parameter_dict_value, group_id):
        """
        Create parameter value for a parameter
        :param parameters: the parameters list
        :param parameter_dict_name: the name of the parameter in the dictionary
        :param parameter_dict_value: the value in the dictionary
        :param group_id: group id
        :return: the parameter value
        """
        for parameter in parameters:
            if parameter_dict_name.lower() == parameter.name.lower():
                pv = ParameterValue()
                pv.parameter = parameter
                pv.group_id = group_id
                pv.value = parameter_dict_value
                return pv

        log.critical("Can not find matching parameter for %s" % parameter_dict_name)
        exit()
 def save_parameter(self, model_run, param_namelist_name, value, session, group_id=None):
     """
     Save parameter using a supplied session
     :param model_run: Model run to save against
     :param param_namelist_name: List containing the parameter namelist, name
     :param session: Session to use
     :param value: Value to set
     :param group_id: Specify an optional group_id to group parameters
     :return:
     """
     parameter = self.get_parameter_by_constant(param_namelist_name, session)
     try:
         parameter_value = session.query(ParameterValue) \
             .filter(ParameterValue.model_run_id == model_run.id) \
             .filter(ParameterValue.group_id == group_id) \
             .filter(ParameterValue.parameter_id == parameter.id).one()
     except NoResultFound:
         parameter_value = ParameterValue()
         parameter_value.parameter = parameter
         parameter_value.model_run = model_run
         parameter_value.group_id = group_id
     parameter_value.set_value_from_python(value)
     session.add(parameter_value)