def animationFilename(target_year,
                      variety,
                      model_name,
                      map_group,
                      map_type,
                      lo_gdd_th=None,
                      hi_gdd_th=None,
                      test_path=False):
    params = {
        'model': nameToFilepath(model_name),
    }

    if isinstance(target_year, basestring): params['date_str'] = target_year
    else: params['date_str'] = str(target_year)

    if variety is not None:
        template = fromConfig('crops.apple.filenames.animation.variety')
        params['variety'] = nameToFilepath(varietyName(variety))
    else:
        template = fromConfig('crops.apple.filenames.animation.%s' % map_group)

    if map_type == 'gdd': params['map_type'] = 'GDD'
    else: params['map_type'] = nameToFilepath(map_type)

    return template % params
Example #2
0
    def newVarietyGridManager(self,
                              target_year,
                              variety,
                              models,
                              gdd_thresholds,
                              test_file=False,
                              verbose=False,
                              **kwargs):
        from frost.apple.variety.grid import AppleVarietyGridBuilder
        start_date, end_date = self.getTargetDateSpan(target_year)
        if models is None: models = fromConfig('crops.apple.chill.models')
        if gdd_thresholds is None:
            gdd_thresholds = fromConfig('crops.apple.gdd_thresholds')

        filepath = self.getVarietyFilePath(target_year, variety, test_file)
        dest_dir = os.path.split(filepath)[0]
        if not os.path.exists(dest_dir): os.makedirs(dest_dir)

        if 'lons' in kwargs:
            return AppleVarietyGridBuilder(variety, start_date, end_date,
                                           kwargs['lons'], kwargs['lats'],
                                           models, gdd_thresholds, test_file,
                                           verbose, **kwargs)
        else:
            reader = self.getTempGridReader(target_year, test_file)
            return AppleVarietyGridBuilder(variety, start_date, end_date,
                                           reader.lons, reader.lats, models,
                                           gdd_thresholds, test_file, verbose,
                                           **kwargs)
Example #3
0
    def _postInitGrape_(self, target_year, variety, **kwargs):
        """ Initialize class attributes that are common to all subclasses
        """
        self.target_year = target_year

        if isinstance(variety, basestring):
            _variety_ = fromConfig('crops.grape.varieties.%s' % variety)
        else: _variety_ = variety

        try:
            self.provenance.update(fromConfig('crops.grape.provenance'))
        except AttributeError:
            pass

        # cache the configuration so we don't do config lookups for every call
        self.variety = _variety_
        self.acclimation_rate = _variety_.acclimation_rate
        self.deacclimation_rate = _variety_.deacclimation_rate
        self.ecodormancy_threshold = _variety_.ecodormancy_threshold
        self.hardiness = _variety_.hardiness
        self.stage_thresholds = _variety_.stage_thresholds
        self.theta = _variety_.theta

        dormancy = fromConfig('crops.grape.dormancy')
        self.dormancy_descriptions = dormancy.stages.attributes
        self.dormancy_stages = dormancy.stages.attributes.keys()[1:]
        self.dormancyIndexFromStage = dormancy.indexFromStage
        self.dormancyStageFromIndex = dormancy.stageFromIndex
def mapFilename(date,
                variety,
                model_name,
                map_group,
                map_type,
                lo_gdd_th=None,
                hi_gdd_th=None,
                test_path=False):
    params = {
        'model': nameToFilepath(model_name),
    }

    if isinstance(date, basestring): params['date_str'] = date
    else: params['date_str'] = asAcisQueryDate(date)

    if variety is not None:
        template = fromConfig('crops.apple.filenames.maps.variety')
        params['variety'] = nameToFilepath(varietyName(variety))
    else:
        template = fromConfig('crops.apple.filenames.maps.%s' % map_group)

    if map_type == 'gdd': params['map_type'] = 'GDD'
    else: params['map_type'] = nameToFilepath(map_type)

    if lo_gdd_th is not None:
        params['thresholds'] = gddThresholdName(lo_gdd_th, hi_gdd_th)

    return template % params
Example #5
0
    def getAcisGridData(self, elems, start_date, end_date=None, meta=None,
                              bbox=None, grid=None, debug=False):
        if bbox is None: bbox = fromConfig('default.bbox.data')
        if grid is None: grid = fromConfig('default.acis_grid')
        query = '{"grid":"%d","bbox":"%s"' % (grid, bbox)
        _start_date = asAcisQueryDate(start_date)
        if end_date is not None:
            _end_date = asAcisQueryDate(end_date)
            query += ',"sdate":"%s","edate":"%s"' % (_start_date, _end_date)
        else:
            query += ',"date":"%s"' % _start_date

        if isinstance(elems, basestring):
            if ',' in elems: _elems = elems.split(',')
            else: _elems = elems
        if isinstance(_elems, (list,tuple)):
            _elems_ = [ ]
            for name in _elems:
                _elems_.append('{"name":"%s"}' % name)
            query += ',"elems":[%s]' % ','.join(_elems_)
        else: query += ',"elems":"%s"' % _elems

        if isinstance(meta, basestring): query += ',"meta":"%s"' % meta
        elif isinstance(meta, (list,tuple)):
            query += ',"meta":"%s"' % ','.join(meta)

        query += '}'
        if debug: print 'factory.getAcisGridData :\n', query

        client = AcisGridDataClient(debug=debug)
        # returns python dict { 'meta' = { "lat" : grid, 'lon' : grid }
        #                       'data' = [ [date string, mint_grid] ]
        query_result = json.loads(client.query(query)[0])

        return self.unpackQueryResults(query_result, _elems, meta)
Example #6
0
    def initChillGroups(self, verbose=False, chill_groups=None):
        """ Initialize chill groups and datasets in a new file.

        WARNING : DO NOT USE IN AN FILE THAT ALREADY HAS THESE DATASETS !!!
                  IT WILL FAIL AND THE FILE MAY BECOME HOPELESSLY CORRUPTED.
        """
        getThresholdString = fromConfig('crops.grape.chill.getThresholdString')

        if chill_groups is None:
            chill_groups = fromConfig('crops.grape.groups.chill')

        # create the chill master group
        if 'chill' not in self._group_names:
            if verbose: print 'creating chill group'
            description='Container for chill data groups'
            self.open('a')
            self.createGroup('chill', description=description)
            self.close()

        for chill_type in chill_groups.children:
            datasets = [ ]
            th_key, th_value = getThresholdString(chill_type.name, self.variety)
            for dataset in chill_type.datasets.children:
                attrs = dict(dataset.attributes)
                attrs[th_key] = th_value
                datasets.append((dataset.name, attrs))
            group_name = self.chillGroupPath(chill_type.name)
            self._initModelDatasets(group_name, tuple(datasets),
                           chill_type.description, verbose=verbose,
                           prov_key='accum')
Example #7
0
    def drawGDDMap(self, date, verbose=False):
        min_gdd = fromConfig('crops.grape.maps.min_gdd_to_post')
        min_percent = fromConfig('crops.grape.maps.min_percent_nodes')
        lats = self.lats
        lons = self.lons
        # get initiaized map options from config file
        map_options = self.initMapOptions(date,
                                          'variety', 'gdd', 'gdd')

        # get GDD accumulations for the date and draw the map
        gdd_grid = self.getGdd(model.name, date)
        gdd_grid[N.where(gdd_grid < 0.99)] = N.nan

        finite = N.where(N.isfinite(gdd_grid))
        num_finite = len(finite[0])
        if num_finite > 0:
            num_ge_min = float(len(N.where(gdd_grid[finite] >= min_gdd)[0]))
            draw_contours = (num_ge_min / num_finite) > min_percent
        else: draw_contours = False
        if draw_contours:
            map_options['finish'] = False
            options, _map_, fig, axes, fig1, xy_extremes = \
            drawFilledContours(gdd_grid, lats, lons, **map_options)
            addModelText(fig, **map_options)
            finishMap(fig, axes, fig1, **options)
            return options['outputfile']
        else:
            config = fromConfig('crops.grape.maps.no_data.gdd.attrs')
            return drawNoDataMap(lons, lats, config=config, model=model,
                                 **map_options)
Example #8
0
    def _loadManagerAttributes_(self):
        FrostGridFileManager._loadManagerAttributes_(self)

        packer = fromConfig('packers.temp')
        unpacker = fromConfig('unpackers.temp')
        for dataset_path in self._dataset_names:
            if not dataset_path.endswith('provenance'):
                if 'maxt' in dataset_path or 'mint' in dataset_path:
                    self._packers[dataset_path] = packer
                    self._unpackers[dataset_path] = unpacker
Example #9
0
    def drawKillMap(self, date, model, lo_gdd_th, hi_gdd_th, verbose=False):
        lats = self.lats
        lons = self.lons
        # get initiaized map options from config file
        map_options = self.initMapOptions(date, model, None, None, 'variety',
                                          'kill', 'kill')
        var_config = fromConfig('crops.apple.variety')

        # extract options required for plotting markers
        marker_colors = map_options['markercolors']
        kill_probabilities = var_config.kill_probabilities

        # get stage index for date and draw the map
        kill = self.getKill(model.name, lo_gdd_th, hi_gdd_th, date)
        indexes = N.where(kill > 0)
        # kill is probable at one or more grid nodes
        if len(indexes[0]) > 0:
            options, _map_, map_fig, axes, xy_extremes, x, y, _grid_ = \
            hiResMap(kill, lats, lons, **map_options)
            del x, y, _grid_

            kill = kill[indexes].flatten()
            _lats_ = lats[indexes].flatten()
            _lons_ = lons[indexes].flatten()

            # draw a separate map layer for each probability
            for indx, probability in enumerate(kill_probabilities, start=1):
                prob_indexes = N.where(kill == probability)
                if len(prob_indexes[0]) > 0:
                    kill[prob_indexes] = indx

                    fig = addScatterToMap(options,
                                          _map_,
                                          map_fig,
                                          kill[prob_indexes],
                                          _lats_[prob_indexes],
                                          _lons_[prob_indexes],
                                          markercolor=marker_colors[indx - 1])
            addModelText(map_fig, model, **map_options)
            finishMap(map_fig, axes, map_fig, **options)
            return options['outputfile']

        # no kill events - draw a blank map
        else:
            config = fromConfig('crops.apple.variety.maps.no_data.kill.attrs')
            return drawNoDataMap(lons,
                                 lats,
                                 config=config,
                                 model=model,
                                 **map_options)
Example #10
0
    def initMapOptions(self,
                       date,
                       model,
                       lo_gdd_th,
                       hi_gdd_th,
                       map_group,
                       map_type,
                       title_key=None):
        # import map options from the config file
        config_path =\
        'crops.apple.%s.maps.options.%s.attrs' % (map_group, map_type)
        config_options = fromConfig(config_path)
        map_options = config_options.copy()
        map_options['date'] = date

        # set the map title
        if title_key is not None:
            #if lo_gdd_th is not None:
            #    # create threshold key for title
            #    thresholds = '%d<AVGT>%d' % (lo_gdd_th, hi_gdd_th)
            #    title = self.mapTitle(date, model, title_key, thresholds=thresholds)
            #else: title = self.mapTitle(date, model, title_key)
            title = self.mapTitle(date, model, title_key)
            map_options['title'] = title

        # set the map file path
        map_options['outputfile'] =\
        self.mapFilepath(date, model, map_group, map_type, None, None)
        return map_options
Example #11
0
    def getTargetDateSpan(self, year_or_start_date, crop=None, variety=None):
        if crop is not None:
            path = 'crops.%s' % crop 
            if variety is not None:
                if isinstance(variety, basestring):
                    path ='%s.variety.%s' % (path, variety)
                else: path ='%s.variety.%s' % (path, variety.name)
        else: path = 'default'
        config = fromConfig(path)

        if isinstance(year_or_start_date, int):
            target_year = year_or_start_date
            start_date = (target_year-1,) + default.start_day
            end_date = (target_year,) + default.end_day
        elif isinstance(year_or_start_date, (tuple,list)):
            _date = datetime.datetime(*year_or_start_date)
            start_date, end_date = self._targetSpanFromDate(_date, config)
        elif isinstance(year_or_start_date, (datetime.datetime,datetime.date)):
            _date = year_or_start_date
            start_date, end_date = self._targetSpanFromDate(_date, config)
        else:
            errmsg = "Invalid type for 'year_or_start_date' argument : %s"
            raise TypeError, errmsg % type(year_or_start_date)

        return datetime.datetime(*start_date), datetime.datetime(*end_date)
Example #12
0
 def chillCalculator(self,
                     model_name,
                     previous_accumulated=None,
                     previous_daily=None):
     config_path = 'crops.apple.chill.%s.accumulators.grid' % model_name
     Klass = fromConfig(config_path)
     return Klass(previous_accumulated, previous_daily)
Example #13
0
    def mapTitle(self, date, title_key, **kwargs):
        title_args = { 'variety':self.variety.description, }
        if kwargs: title_args.update(kwargs)

        # get the map title template and initialize the map title
        title_template = fromConfig('crops.grape.maps.titles.%s' % title_key)
        return title_template % title_args
Example #14
0
    def drawNoDataMap(self, map_key, **options):
        from frost.visual.maps import mapSetup

        no_data = fromConfig('crops.grape.maps.no_data.%s.attrs' % map_key)
        options.update(no_data)

        map_options, _basemap_, map_fig, axes, xy_extremes = \
        mapSetup(options, self.lats, self.lons)

        if 'contourbounds' in options:
            from frost.visual import resolveColorMapOptions
            x_min = xy_extremes[0]
            x = N.array( [ [x_min, x_min+1.0], [x_min, x_min+1.0 ] ] )
            y_min = xy_extremes[2]
            y = N.array( [ [y_min, y_min], [y_min+1.0, y_min+1.0 ] ] )
            zero = N.array( [ [0.0, 0.0], [0.0, 0.0] ] )

            cmap_options = resolveColorMapOptions(**map_options)
            fig1 = _basemap_.contourf(x, y, zero, options['contourbounds'],
                                     **cmap_options)
            finishMap(map_fig, axes, fig1, **map_options)

        else: finishMap(map_fig, axes, map_fig, **map_options)

        return map_options['outputfile']
Example #15
0
    def drawStageContourMap(self,
                            date,
                            model,
                            lo_gdd_th,
                            hi_gdd_th,
                            verbose=False):
        lats = self.lats
        lons = self.lons
        # get initiaized map options from config file
        map_options = self.initMapOptions(date, model, lo_gdd_th, lo_gdd_th,
                                          'variety', 'stage', 'stage')

        # get stage index for date and draw the map
        stage_grid = self.getStage(model.name, lo_gdd_th, hi_gdd_th, date)

        isfinite = N.where(N.isfinite(stage_grid))
        if len(N.where(stage_grid[isfinite] > 0)[0]) > 0:
            map_options['finish'] = False
            options, _map_, fig, axes, fig1, xy_extremes = \
            drawFilledContours(stage_grid, lats, lons, **map_options)
            addModelText(fig, model, **map_options)
            finishMap(fig, axes, fig1, **options)
            return options['outputfile']
        else:
            config = fromConfig('crops.apple.variety.maps.no_data.stage.attrs')
            return drawNoDataMap(lons,
                                 lats,
                                 config=config,
                                 model=model,
                                 **map_options)
Example #16
0
def animationFilename(target_year, variety, map_key, test_path=False):
    params = { }
    params['variety'] = nameToFilepath(variety.description)
    params['anim_key'] = nameToFilepath(map_key)
    if isinstance(target_year, basestring): params['year'] = target_year
    else: params['year'] = str(target_year)
    template = fromConfig('crops.grape.filenames.anim.variety')
    return template % params
def getGddThresholds(options, manager):
    if options.gdd_thresholds is not None:  # use thresholds passed via options
        return stringToTuple(options.gdd_thresholds, int)
    else:  # no thresholds in options
        # check which GDD thresholds are in the current file
        if manager is not None: return manager.gddThresholds()
        # use the GDD thresholds in the configuration file
        return fromConfig('crops.apple.gdd_thresholds')
Example #18
0
    def drawStageMap(self, date, model, lo_gdd_th, hi_gdd_th, verbose=False):
        lats = self.lats
        lons = self.lons
        # get initiaized map options from config file
        map_options = self.initMapOptions(date, model, lo_gdd_th, lo_gdd_th,
                                          'variety', 'stage', 'stage')
        var_config = fromConfig('crops.apple.variety')

        # extract options required for plotting markers
        marker_colors = map_options['markercolors']
        stage_name_map = var_config.stage_name_map

        # get stage index for date and draw the map
        stage_data = self.getStage(model.name, lo_gdd_th, hi_gdd_th, date)

        isfinite = N.where(N.isfinite(stage_data))
        if len(N.where(stage_data[isfinite] > 0)[0]) > 0:
            options, _map_, map_fig, axes, xy_extremes, x, y, _grid_ = \
            hiResMap(stage_data, lats, lons, **map_options)
            del x, y, _grid_

            _lats_ = lats[isfinite].flatten()
            _lons_ = lons[isfinite].flatten()
            stage_data = stage_data[isfinite].flatten()

            for stage in range(len(stage_name_map.attrs)):
                indexes = N.where(stage_data == stage)
                if len(indexes[0]) > 0:
                    fig = addScatterToMap(map_options,
                                          _map_,
                                          map_fig,
                                          stage_data[indexes],
                                          _lats_[indexes],
                                          _lons_[indexes],
                                          markercolor=marker_colors[stage])
            addModelText(map_fig, model, **map_options)
            finishMap(map_fig, axes, map_fig, **options)
            return options['outputfile']
        else:
            config = fromConfig('crops.apple.variety.maps.no_data.stage.attrs')
            return drawNoDataMap(lons,
                                 lats,
                                 config=config,
                                 model=model,
                                 **map_options)
Example #19
0
 def _resolveGridSourceAttributes(self, **kwargs):
     default = fromConfig('default')
     source = kwargs.get('source', default.data_source)
     attrs = {
         'source': source,
     }
     if 'acis' in source.lower():
         attrs['acis_grid'] = kwargs.get('acis_grid', default.acis_grid)
     return attrs
Example #20
0
def webGraphicFilename(date, variety, graphic_key, ext, parse_keywords=True):
    params = { 'variety': nameToFilepath(variety.description), 'ext': ext }
    if isinstance(date, basestring): params['date_str'] = date
    else: params['date_str'] = asAcisQueryDate(date)

    template = fromConfig('crops.grape.filenames.web_graphic.variety')
    if parse_keywords: params['keywords'] = nameToFilepath(graphic_key)
    else: params['keywords'] = graphic_key
    return template % params
Example #21
0
    def initDormancyGroup(self, verbose=False):
        """ Initialize dormancy stage group and datasets in a new file.

        WARNING : DO NOT USE IN AN FILE THAT ALREADY HAS THESE DATASETS !!!
                  IT WILL FAIL AND THE FILE MAY BECOME HOPELESSLY CORRUPTED.
        """
        group = fromConfig('crops.grape.groups.dormancy')
        attrs = dict(group.datasets.stage.attributes)
        self._initModelDatasets('dormancy', (('stage',attrs),),
                                group.description, verbose=verbose)
Example #22
0
    def initHardinessGroup(self, verbose=False):
        """ Initialize hardiness group and datasets in a new file.

        WARNING : DO NOT USE IN AN FILE THAT ALREADY HAS THESE DATASETS !!!
                  IT WILL FAIL AND THE FILE MAY BECOME HOPELESSLY CORRUPTED.
        """
        group = fromConfig('crops.grape.groups.hardiness')
        attrs = dict(group.datasets.temp.attributes)
        self._initModelDatasets('hardiness', (('temp',attrs),),
                                group.description, verbose=verbose, 
                                prov_key='stats')
Example #23
0
    def __init__(self,
                 target_year,
                 filepath,
                 mode='r',
                 unpackers=None,
                 packers=None):

        self._preInitFrost_(target_year)
        Hdf5DateGridFileManager.__init__(self, filepath, mode)
        self._postInitFrost_()

        self.provenance = fromConfig('provenance')
def webMapFilename(date,
                   variety,
                   model_name,
                   map_group,
                   map_type,
                   config_key='web_maps'):
    params = {
        'model': nameToFilepath(model_name),
    }

    if isinstance(date, basestring): params['date_str'] = date
    else: params['date_str'] = asAcisQueryDate(date)

    if variety is not None:
        template = fromConfig('crops.apple.filenames.%s.variety' % config_key)
        params['variety'] = nameToFilepath(varietyName(variety))
    else:
        template = \
        fromConfig('crops.apple.filenames.%s.%s' % (config_key, map_group))
    params['map_type'] = nameToFilepath(map_type)
    return template % params
Example #25
0
 def _validateKwargs(self, kwargs):
     default = fromConfig('default')
     if 'acis_grid' not in kwargs: kwargs['acis_grid'] = default.acis_grid
     if 'search_bbox' not in kwargs:
         if 'bbox' in kwargs:
             kwargs['search_bbox'] = kwargs['bbox']
             del kwargs['bbox']
         else:
             kwargs['search_bbox'] = default.bbox.data
     if 'node_spacing' not in kwargs:
         kwargs['node_spacing'] = default.node_spacing
     if 'source' not in kwargs: kwargs['source'] = default.source
     return kwargs
Example #26
0
    def drawChillMaskMap(self,
                         date,
                         model,
                         lo_gdd_th,
                         hi_gdd_th,
                         verbose=False):
        lats = self.lats
        lons = self.lons
        # get initiaized map options from config file
        map_options = self.initMapOptions(date, model, None, None, 'variety',
                                          'mask', 'mask')
        var_config = fromConfig('crops.apple.variety')

        # get stage index for date and draw the map
        mask = self.getChillMask(model.name, lo_gdd_th, hi_gdd_th, date)
        indexes = N.where(mask == True)

        # kill is probable at one or more grid nodes
        if len(indexes[0]) > 0:

            options, _map_, map_fig, axes, xy_extremes, x, y, _grid_ = \
            hiResMap(mask, lats, lons, **map_options)
            del x, y, _grid_

            x, y = _map_(lons[indexes].flatten(), lats[indexes].flatten())
            fig1 = _map_.scatter(x, y, c='r', s=3, marker='^', linewidths=0)
            addModelText(map_fig, model, **map_options)
            finishMap(map_fig, axes, map_fig, **options)
            return options['outputfile']

        # no kill events - draw a blank map
        else:
            config = fromConfig('crops.apple.variety.maps.no_data.kill.attrs')
            return drawNoDataMap(lons,
                                 lats,
                                 config=config,
                                 model=model,
                                 **map_options)
Example #27
0
    def __init__(self, variety_name):
        variety = fromConfig('crops.grape.variety.%s.self' % variety.name)
        # cache the configuration so we don't do config lookups for every call
        self.acclimation = variety.acclimation
        self.deacclimation = variety.deacclimation
        self.ecodormancy_threshold = variety.ecodormancy_threshold
        self.hardiness = variety.hardiness
        self.temp_thresholds = variety.temp_thresholds
        self.theta = variety.theta

        parent = variety.parent
        self.dormancy_states = parent.dormancy_states
        self.dormancyIndexFromState = parent.dormancyIndexFromState
        self.dormancyStateFromIndex = parent.dormancyStateFromIndex
Example #28
0
 def _resolveCommonAttributes(self, **kwargs):
     default = fromConfig('default')
     if 'created' in kwargs: attrs = {'created': kwargs['created']}
     else: attrs = {}
     # source based attributes
     source = kwargs.get('source', default.data_source)
     if 'acis' in source.lower():
         attrs['grid_type'] = kwargs.get('grid_type', default.grid_type)
         attrs['node_spacing'] = \
              kwargs.get('node_spacing', default.node_spacing)
     else:
         attrs['grid_type'] = kwargs.get('grid_type', 'unknown')
         attrs['node_spacing'] = kwargs.get('node_spacing', 'unknown')
     return attrs
Example #29
0
    def initDeacclimationGroup(self, verbose=False):
        """ Initialize deacclimation group and datasets in a new file.

        WARNING : DO NOT USE IN AN FILE THAT ALREADY HAS THESE DATASETS !!!
                  IT WILL FAIL AND THE FILE MAY BECOME HOPELESSLY CORRUPTED.
        """
        rates = ( 'endo=%-4.2f' % self.variety.deacclimation_rate.endo,
                  'eco=%-4.2f' % self.variety.deacclimation_rate.eco )
        group = fromConfig('crops.grape.groups.deacclimation')
        attrs = dict(group.datasets.factor.attributes)
        attrs['deacclimation_rates'] = ', '.join(rates)
        self._initModelDatasets('deacclimation', (('factor', attrs),),
                                group.description, verbose=verbose,
                                prov_key='stats')
Example #30
0
    def mapTitle(self, date, model, title_key, **kwargs):
        title_args = {
            'variety': self.variety.description,
        }
        if len(kwargs) > 0: title_args.update(kwargs)

        # get the map title template and initialize the map title
        if '%' not in title_key:
            title_template =\
            fromConfig('crops.apple.variety.maps.titles.%s' % title_key)
            return title_template % title_args
        # a template was passed
        else:
            return title_key % title_args