Пример #1
0
    def __init__(self, args):
        """
        Initialize the job state from the arguments dictionary.

        :param args: the forecast job arguments
        """
        super(JobState, self).__init__(args)
        self.grib_source = self.resolve_grib_source(self.grib_source)
        self.start_utc = round_time_to_hour(
            self.start_utc,
            up=False,
            period_hours=self.grib_source.period_hours)
        self.end_utc = round_time_to_hour(
            self.end_utc, up=True, period_hours=self.grib_source.period_hours)
        self.fc_hrs = compute_fc_hours(self.start_utc, self.end_utc)
        if 'job_id' in args:
            logging.info('job_id given in the job description.')
            self.job_id = args['job_id']
        else:
            logging.warning('job_id not given, creating.')
            self.job_id = 'wfc-' + self.grid_code + '-' + utc_to_esmf(
                self.start_utc) + '-{0:02d}'.format(self.fc_hrs)
        self.emails = self.parse_emails(args)
        self.domains = args['domains']
        self.ignitions = args.get('ignitions', None)
        self.fmda = self.parse_fmda(args)
        self.postproc = args['postproc']
        self.wrfxpy_dir = args['sys_install_path']
        self.args = args
Пример #2
0
def process_arguments(args):
    """
    Convert arguments passed into program via the JSON configuration file and job json argument.
    This is processed after the configuration is updated by the job json file.

    Transforms unicode strings into standard strings.

    :param args: the input arguments
    """
    # resolve possible relative time specifications
    start_utc = timespec_to_utc(args['start_utc'])
    args['orig_start_utc'] = start_utc
    args['start_utc'] = round_time_to_hour(start_utc)
    args['end_utc'] = round_time_to_hour(
        timespec_to_utc(args['end_utc'], args['start_utc']), True)
    args['cycle_start_utc'] = timespec_to_utc(args.get('cycle_start_utc',
                                                       None))

    # defaults
    if args['ref_utc'] is not None:
        args['ref_utc'] = timespec_to_utc(args['ref_utc'], args['start_utc'])

    for k, v in args.iteritems():
        if type(v) == unicode:
            args[k] = v.encode('ascii')
Пример #3
0
def process_arguments(args):
    """
    Convert arguments passed into program via the JSON configuration file.

    Transforms unicode strings into standard strings.

    :param args: the input arguments
    """
    # resolve possible relative time specifications
    start_utc = timespec_to_utc(args['start_utc'])
    args['orig_start_utc'] = start_utc
    args['start_utc'] = round_time_to_hour(start_utc)
    args['end_utc'] = round_time_to_hour(timespec_to_utc(args['end_utc'], args['start_utc']), True)

    for k, v in args.iteritems():
        if type(v) == unicode:
            args[k] = v.encode('ascii')
Пример #4
0
def process_arguments(args):
    """
    Convert arguments passed into program via the JSON configuration file.

    Transforms unicode strings into standard strings.

    :param args: the input arguments
    """
    # resolve possible relative time specifications
    start_utc = timespec_to_utc(args['start_utc'])
    args['orig_start_utc'] = start_utc
    args['start_utc'] = round_time_to_hour(start_utc)
    args['end_utc'] = round_time_to_hour(
        timespec_to_utc(args['end_utc'], args['start_utc']), True)

    for k, v in args.iteritems():
        if type(v) == unicode:
            args[k] = v.encode('ascii')
Пример #5
0
    def __init__(self, args):
        """
        Initialize the job state from the arguments dictionary.

        :param args: the forecast job arguments
        """
        super(JobState, self).__init__(args)
        #self.grib_source = [self.grib_source] if isinstance(self.grib_source, basestring) else self.grib_source
        #self.grib_source = [self.resolve_grib_source(g, args) for g in self.grib_source]
        self.grib_source = self.resolve_grib_source(self.grib_source, args)
        logging.info('Simulation requested from %s to %s' %
                     (str(self.start_utc), str(self.end_utc)))
        self.start_utc = round_time_to_hour(
            self.start_utc,
            up=False,
            period_hours=self.grib_source[0].period_hours)
        self.end_utc = round_time_to_hour(
            self.end_utc,
            up=True,
            period_hours=self.grib_source[0].period_hours)
        self.cycle_start_utc = round_time_to_hour(
            self.get('cycle_start_utc', None),
            period_hours=self.grib_source[0].cycle_hours)
        logging.info('Simulation times rounded  %s to %s' %
                     (str(self.start_utc), str(self.end_utc)))
        #self.start_utc = round_time_to_hour(self.start_utc, up=False, period_hours=self.grib_source.period_hours);
        #self.end_utc = round_time_to_hour(self.end_utc, up=True, period_hours=self.grib_source.period_hours);
        self.fc_hrs = timedelta_hours(self.end_utc - self.start_utc)
        if 'job_id' in args:
            logging.info('job_id %s given in the job description' %
                         args['job_id'])
            self.job_id = args['job_id']
        else:
            logging.warning('job_id not given, creating.')
            self.job_id = 'wfc-' + self.grid_code + '-' + utc_to_esmf(
                self.start_utc) + '-{0:02d}'.format(self.fc_hrs)
        self.emails = self.parse_emails(args)
        self.domains = args['domains']
        self.ignitions = args.get('ignitions', None)
        self.fmda = self.parse_fmda(args)
        self.postproc = args['postproc']
        self.wrfxpy_dir = args['sys_install_path']
        self.args = args
        logging.debug('JobState initialized: ' + str(self))
Пример #6
0
    def __init__(self, args):
        """
        Initialize the job state from the arguments dictionary.

        :param args: the forecast job arguments
        """
        super(JobState, self).__init__(args)
        self.grib_source = self.resolve_grib_source(self.grib_source)
        self.start_utc = round_time_to_hour(self.start_utc, up=False, period_hours=self.grib_source.period_hours);
        self.end_utc = round_time_to_hour(self.end_utc, up=True, period_hours=self.grib_source.period_hours);
        self.fc_hrs = compute_fc_hours(self.start_utc, self.end_utc)
        if 'job_id' in args:
            logging.info('job_id given in the job description.')
            self.job_id = args['job_id']
        else:
            logging.warning('job_id not given, creating.')
            self.job_id = 'wfc-' + self.grid_code + '-' + utc_to_esmf(self.start_utc) + '-{0:02d}'.format(self.fc_hrs)
        self.emails = self.parse_emails(args)
        self.domains = args['domains']
        self.ignitions = args.get('ignitions', None)
        self.fmda = self.parse_fmda(args)
        self.postproc = args['postproc']
        self.wrfxpy_dir = args['sys_install_path']
        self.args = args
Пример #7
0
def questionnaire():
    """
    Give a questionnaire to the user (with sensible default) to create
    a simple domain configuration.

    :return: a dictionary with the configuration of a fire simulation
    """
    cfg = {}

    cfg['wps_namelist_path'] = 'etc/nlists/default.wps'
    cfg['wrf_namelist_path'] = 'etc/nlists/default.input'
    cfg['fire_namelist_path'] = 'etc/nlists/default.fire'
    cfg['emissions_namelist_path'] = 'etc/nlists/default.fire_emissions'

    print_question('Enter a name for your job [default = experiment]:')
    cfg['grid_code'] = read_string('experiment')
    print_answer('Name is %s' % cfg['grid_code'])

    print_header('IGNITION section')
    newline()

    print_question(
        'Enter the ignition point as lat, lon [default = 39.1, -104.3]:')
    ign_latlon = read_location('39.1, -104.3')
    print_answer('Ignition point is at latlon %g %g' % ign_latlon)

    print_question(
        'Enter the ignition time in UTC timezone as an ESMF string or relative time'
    )
    print(
        'Examples: 2016-03-30_16:00:00 or T-60 or T+30 (minutes), [default = now]'
    )
    ign_utc = read_time_indicator('T+0')
    print_answer('Ignition time is %s\n' % str(ign_utc))

    print_question(
        'Enter the duration of the ignition process in seconds [default = 240]'
    )
    ign_dur = read_integer('240')
    print_answer('The ignition will remain active for %d seconds.' % ign_dur)

    newline()
    print_header('SIMULATION section')

    start_utc = utils.round_time_to_hour(ign_utc - timedelta(minutes=30))
    while True:
        print_question(
            'Enter the start time of the simulation in UTC timezone [default = 30 mins before ignition time]'
        )
        start_utc = read_time_indicator(utils.utc_to_esmf(start_utc))
        start_utc = utils.round_time_to_hour(start_utc)
        if start_utc < ign_utc:
            break
        print(('Simulation start must be before ignition time %s' %
               utils.utc_to_esmf(ign_utc)))
    cfg['start_utc'] = utils.utc_to_esmf(start_utc)
    print_answer('Simulation will start at %s.' % cfg['start_utc'])

    end_utc = start_utc + timedelta(hours=5)
    while True:
        print_question(
            'Enter the end time of the simulation [default = start_time + 5 hours]'
        )
        end_utc = read_time_indicator(utils.utc_to_esmf(end_utc))
        end_utc = utils.round_time_to_hour(end_utc, True)
        if end_utc > ign_utc:
            break
        print(('Simulation end must be after ignition time %s' %
               utils.utc_to_esmf(ign_utc)))
    cfg['end_utc'] = utils.utc_to_esmf(end_utc)
    print_answer('Simulation will end at %s.' % cfg['end_utc'])

    print_question(
        'Please enter the cell size in meters for the atmospheric mesh [default 1000]'
    )
    cell_size = read_integer('1000')
    print_answer('The cell size is %d meters.' % cell_size)

    print_question(
        'Enter the number of grid cells in the longitudinal and latitudinal position [default 61, 61]'
    )
    domain_size = read_size('61, 61')
    print_answer('The domain size is %d x %d grid points.' % domain_size)

    print_question('Enter the refinement ratio for the fire grid [default=40]')
    refinement = read_integer('40')
    print_answer(
        'The refinement ratio is %d for a fire mesh size of %g meters.' %
        (refinement, float(cell_size) / refinement))

    print_question(
        'Enter the interval between output frames in minutes [default=15]')
    history_interval = read_integer('15')
    print_answer('The interval between output frames is %d minutes.' %
                 history_interval)

    cfg['grib_source'] = select_grib_source(start_utc)
    print_answer('Selected GRIB2 source %s' % cfg['grib_source'])

    print_question('Process satellite data? [default=no]')
    sat = read_boolean('no')
    if sat:
        cfg['satellite_source'] = ["Aqua", "Terra", "SNPP"]
        print_answer('Selected Satellite sources %s' % cfg['satellite_source'])
    else:
        print_answer('No Satellite sources selected.')

    def_geog_path = None
    try:
        def_geog_path = json.load(open('etc/conf.json'))['wps_geog_path']
    except Exception as e:
        print(e)
        pass
    print_question(
        'Enter the path to geogrid information (WPS-GEOG) [default=%s]' %
        def_geog_path)
    cfg['wps_geog_path'] = read_string(def_geog_path)
    print_answer('The WPS-GEOG path is %s' % cfg['wps_geog_path'])

    cfg['domains'] = {
        '1': {
            'cell_size': (cell_size, cell_size),
            'domain_size': domain_size,
            'subgrid_ratio': (refinement, refinement),
            'geog_res': '.3s',
            'center_latlon': ign_latlon,
            'truelats': (ign_latlon[0], ign_latlon[0]),
            'stand_lon': ign_latlon[1],
            'history_interval': history_interval,
            'time_step': max(1, 5 * cell_size // 1000)
        }
    }

    cfg['ignitions'] = {
        '1': [{
            'time_utc': utils.utc_to_esmf(ign_utc),
            'duration_s': ign_dur,
            'latlon': ign_latlon
        }]
    }

    print_header('PARALLEL JOB configuration')
    print_question('Enter number of parallel nodes [default=8]')
    cfg['num_nodes'] = read_integer('8')
    print_answer('Parallel job will use %d nodes.' % cfg['num_nodes'])

    print_question('Enter number of cores per node [default=12]')
    cfg['ppn'] = read_integer('12')
    print_answer('Parallel job will use %d cores per node.' % cfg['ppn'])

    print_question('Enter the max walltime in hours [default=2]')
    cfg['wall_time_hrs'] = read_integer('2')
    print_answer('Parallel job will reserve %d hours of walltime.' %
                 cfg['wall_time_hrs'])

    qsys_opts = queuing_systems()
    while True:
        def_qsys = socket.gethostname().split('.')[0]
        print(('Enter queuing system [choices are %s, default is %s]' %
               (qsys_opts, def_qsys)))
        cfg['qsys'] = read_string(def_qsys)
        if cfg['qsys'] in qsys_opts:
            break
        print('Invalid queuing system selected, please try again')
    print_answer('Parallel job will submit for %s' % cfg['qsys'])

    print_header('POSTPROCESSING')
    print_question(
        'Which variables should wrfxpy postprocess? [default T2,PSFC,WINDSPD,WINDVEC,FIRE_AREA,FGRNHFX,FLINEINT,SMOKE_INT]'
    )
    pp_vars = read_string(
        'T2,PSFC,WINDSPD,WINDVEC,FIRE_AREA,FGRNHFX,FLINEINT,SMOKE_INT').split(
            ',')
    print_answer('Will postprocess %d variables.' % len(pp_vars))

    print_question('Send variables to visualization server? [default=no]')
    shuttle = read_boolean('no')

    desc = ''
    if shuttle:
        print_question(
            'Enter a short description of your job [default=experimental run]')
        desc = read_string('experimental run')

    cfg['postproc'] = {'1': pp_vars}
    if shuttle:
        cfg['postproc']['shuttle'] = 'incremental'
        cfg['postproc']['description'] = desc

    return cfg
Пример #8
0
def questionnaire():
    """
    Give a questionnaire to the user (with sensible default) to create
    a simple domain configuration.
    
    :return: a dictionary with the configuration of a fire simulation
    """
    cfg = {}

    cfg['wps_namelist_path'] = 'etc/nlists/default.wps'
    cfg['wrf_namelist_path'] = 'etc/nlists/default.input'
    cfg['fire_namelist_path'] = 'etc/nlists/default.fire'
    cfg['emissions_namelist_path'] = 'etc/nlists/default.fire_emissions'

    print_question('Enter a name for your job [default = experiment]:')
    cfg['grid_code'] = read_string('experiment')
    print_answer('Name is %s' % cfg['grid_code'])

    print_header('IGNITION section')
    newline()

    print_question('Enter the ignition point as lat, lon [default = 39.1, -104.3]:')
    ign_latlon = read_location('39.1, -104.3')
    print_answer('Ignition point is at latlon %g %g' % ign_latlon)

    print_question('Enter the ignition time in UTC timezone as an ESMF string or relative time')
    print('Examples: 2016-03-30_16:00:00 or T-60 or T+30 (minutes), [default = now]')
    ign_utc = read_time_indicator('T+0') 
    print_answer('Ignition time is %s\n' % str(ign_utc))

    print_question('Enter the duration of the ignition process in seconds [default = 240]')
    ign_dur = read_integer('240')
    print_answer('The ignition will remain active for %d seconds.' % ign_dur)

    newline()
    print_header('SIMULATION section')

    start_utc = utils.round_time_to_hour(ign_utc - timedelta(minutes=30))
    while True:
        print_question('Enter the start time of the simulation in UTC timezone [default = 30 mins before ignition time]')
        start_utc = read_time_indicator(utils.utc_to_esmf(start_utc))
        start_utc = utils.round_time_to_hour(start_utc)
        if start_utc < ign_utc:
            break
        print('Simulation start must be before ignition time %s' % utils.utc_to_esmf(ign_utc))
    cfg['start_utc'] = utils.utc_to_esmf(start_utc)
    print_answer('Simulation will start at %s.' % cfg['start_utc'])
    
    end_utc = start_utc + timedelta(hours=5)
    while True:
        print_question('Enter the end time of the simulation [default = start_time + 5 hours]')
        end_utc = read_time_indicator(utils.utc_to_esmf(end_utc))
        end_utc = utils.round_time_to_hour(end_utc, True)
        if end_utc > ign_utc:
            break
        print('Simulation end must be after ignition time %s' % utils.utc_to_esmf(ign_utc))
    cfg['end_utc'] = utils.utc_to_esmf(end_utc)
    print_answer('Simulation will end at %s.' % cfg['end_utc'])

    print_question('Please enter the cell size in meters for the atmospheric mesh [default 1000]')
    cell_size = read_integer('1000')
    print_answer('The cell size is %d meters.' % cell_size)

    print_question('Enter the number of grid cells in the longitudinal and latitudinal position [default 61, 61]')
    domain_size = read_size('61, 61')
    print_answer('The domain size is %d x %d grid points.' % domain_size)

    print_question('Enter the refinement ratio for the fire grid [default=40]')
    refinement = read_integer('40')
    print_answer('The refinement ratio is %d for a fire mesh size of %g meters.' % (refinement, float(cell_size)/refinement))

    print_question('Enter the interval between output frames in minutes [default=15]')
    history_interval = read_integer('15')
    print_answer('The interval between output frames is %d minutes.' % history_interval)

    cfg['grib_source'] = select_grib_source(start_utc)
    print_answer('Selected GRIB2 source %s' % cfg['grib_source'])

    def_geog_path = None
    try:
        def_geog_path = json.load(open('etc/conf.json'))['wps_geog_path']
    except Exception as e:
        print(e)
        pass
    print_question('Enter the path to geogrid information (WPS-GEOG) [default=%s]' % def_geog_path)
    cfg['wps_geog_path'] = read_string(def_geog_path)
    print_answer('The WPS-GEOG path is %s' % cfg['wps_geog_path'])

    cfg['domains'] = { '1' : {
        'cell_size' : (cell_size,cell_size),
        'domain_size' : domain_size,
        'subgrid_ratio' : (refinement, refinement),
        'geog_res' : '.3s',
        'center_latlon' : ign_latlon,
        'truelats' : (ign_latlon[0], ign_latlon[0]),
        'stand_lon' : ign_latlon[1],
        'history_interval' : history_interval,
        'time_step' : max(1, 5 * cell_size / 1000)
        }
    }

    cfg['ignitions'] = { '1' : [ { 'time_utc' : utils.utc_to_esmf(ign_utc),
                                   'duration_s' : ign_dur,
                                   'latlon' : ign_latlon } ] }


    print_header('PARALLEL JOB configuration')
    print_question('Enter number of parallel nodes [default=8]')
    cfg['num_nodes'] = read_integer('8')
    print_answer('Parallel job will use %d nodes.' % cfg['num_nodes'])

    print_question('Enter number of cores per node [default=12]')
    cfg['ppn'] = read_integer('12')
    print_answer('Parallel job will use %d cores per node.' % cfg['ppn'])

    print_question('Enter the max walltime in hours [default=2]')
    cfg['wall_time_hrs'] = read_integer('2')
    print_answer('Parallel job will reserve %d hours of walltime.' % cfg['wall_time_hrs'])

    qsys_opts = queuing_systems()
    while True:
        def_qsys = socket.gethostname().split('.')[0]
        print('Enter queuing system [choices are %s, default is %s]' % (qsys_opts, def_qsys))
        cfg['qsys'] = read_string(def_qsys)
        if cfg['qsys'] in qsys_opts:
            break
        print('Invalid queuing system selected, please try again')
    print_answer('Parallel job will submit for %s' % cfg['qsys'])

    print_header('POSTPROCESSING')
    print_question('Which variables should wrfxpy postprocess? [default T2,PSFC,WINDSPD,WINDVEC,FIRE_AREA,FGRNHFX,FLINEINT,SMOKE_INT]')
    pp_vars = read_string('T2,PSFC,WINDSPD,WINDVEC,FIRE_AREA,FGRNHFX,FLINEINT,SMOKE_INT').split(',')
    print_answer('Will postprocess %d variables.' % len(pp_vars))

    print_question('Send variables to visualization server? [default=no]')
    shuttle = read_boolean('no')

    desc = ''
    if shuttle:
        print_question('Enter a short description of your job [default=experimental run]')
        desc = read_string('experimental run')
    
    cfg['postproc'] = { '1' : pp_vars }
    if shuttle:
        cfg['postproc']['shuttle'] = 'incremental'
        cfg['postproc']['description'] = desc

    return cfg