Changeset 3f36e42 in flex_extract.git


Ignore:
Timestamp:
Dec 4, 2018, 9:46:22 PM (5 years ago)
Author:
Anne Philipp <anne.philipp@…>
Branches:
master, ctbto, dev
Children:
fdda1b9
Parents:
97f4f4c
Message:

outsourced some checks from CONTROL class to checks module; translated namelist generation by genshi templating; corrected a bug in grib2 conversion

Location:
source/python
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • source/python/classes/ControlFile.py

    r97f4f4c r3f36e42  
    6161import _config
    6262from mods.tools import my_error, silent_remove
    63 from mods.checks import check_grid_area
     63from mods.checks import check_grid, check_area, check_levels
    6464
    6565# ------------------------------------------------------------------------------
     
    345345                sys.exit(1)
    346346
    347         # assure consistency of levelist and level
    348         if not self.levelist and not self.level:
    349             print('Warning: neither levelist nor level \
    350                                specified in CONTROL file')
    351             sys.exit(1)
    352         elif not self.levelist and self.level:
    353             self.levelist = '1/to/' + self.level
    354         elif (self.levelist and not self.level) or \
    355              (self.levelist[-1] != self.level[-1]):
    356             self.level = self.levelist.split('/')[-1]
    357         else:
    358             pass
    359 
    360         # check if max level is a valid level
    361         if int(self.level) not in _config.MAX_LEVEL_LIST:
    362             print('ERROR: ')
    363             print('LEVEL must be the maximum level of a specified '
    364                   'level list from ECMWF, e.g.')
    365             print(_config.MAX_LEVEL_LIST)
    366             print('Check parameter "LEVEL" or the max level of "LEVELIST"!')
    367             sys.exit(1)
     347        self.levelist, self.level = check_levels(self.levelist, self.level)
     348
     349        # # assure consistency of levelist and level
     350        # if not self.levelist and not self.level:
     351            # print('Warning: neither levelist nor level \
     352                               # specified in CONTROL file')
     353            # sys.exit(1)
     354        # elif not self.levelist and self.level:
     355            # self.levelist = '1/to/' + self.level
     356        # elif (self.levelist and not self.level) or \
     357             # (self.levelist[-1] != self.level[-1]):
     358            # self.level = self.levelist.split('/')[-1]
     359        # else:
     360            # pass
     361
     362        # # check if max level is a valid level
     363        # if int(self.level) not in _config.MAX_LEVEL_LIST:
     364            # print('ERROR: ')
     365            # print('LEVEL must be the maximum level of a specified '
     366                  # 'level list from ECMWF, e.g.')
     367            # print(_config.MAX_LEVEL_LIST)
     368            # print('Check parameter "LEVEL" or the max level of "LEVELIST"!')
     369            # sys.exit(1)
    368370
    369371        # prepare step list if "/" signs are found
     
    477479
    478480
    479         self.grid, self.area = check_grid_area(self.grid, self.area,
    480                                                self.upper, self.lower,
    481                                                self.left, self.right)
    482 
    483 
    484 
    485         # convert grid and area components to correct format and input
    486         #if 'N' in self.grid:  # Gaussian output grid
    487         #    self.area = 'G'
    488         # else:
    489             # if '/' in self.grid:
    490                 # gridx, gridy = self.grid.split('/')
    491                 # if gridx == gridy:
    492                     # self.grid = gridx
    493 
    494 
    495             # # check on grid format
    496             # if float(self.grid) / 100. >= 0.5:
    497                 # # grid is defined in 1/1000 degrees; old format
    498                 # self.grid = '{}/{}'.format(float(self.grid) / 1000.,
    499                                            # float(self.grid) / 1000.)
    500                 # self.area = '{}/{}/{}/{}'.format(float(self.upper) / 1000.,
    501                                                  # float(self.left) / 1000.,
    502                                                  # float(self.lower) / 1000.,
    503                                                  # float(self.right) / 1000.)
    504             # elif float(self.grid) / 100. < 0.5:
    505                 # # grid is defined in normal degree; new format
    506                 # self.grid = '{}/{}'.format(float(self.grid), float(self.grid))
    507                 # self.area = '{}/{}/{}/{}'.format(float(self.upper),
    508                                                  # float(self.left),
    509                                                  # float(self.lower),
    510                                                  # float(self.right))
     481        self.grid = check_grid(self.grid)
     482
     483        self.area = check_area(self.grid, self.area, self.upper, self.lower,
     484                               self.left, self.right)
     485
    511486
    512487        return
     
    555530        return sorted(l)
    556531
    557     def check_ppid(self, ppid):
    558         '''Sets the current PPID.
    559 
    560         Parameters
    561         ----------
    562         ppid : :obj:`int` or :obj:`None`
    563             Contains the ppid number provided by the command line parameter
    564             of is None otherwise.
    565 
    566         Return
    567         ------
    568 
    569         '''
    570 
    571         if not ppid:
    572             self.ppid = str(os.getppid())
    573         else:
    574             self.ppid = ppid
    575 
    576         return
  • source/python/classes/EcFlexpart.py

    r2d56c04 r3f36e42  
    147147        i = 0
    148148        if fluxes and c.maxstep <= 24:
    149             # no forecast beyond one day is needed!
    150             # Thus, prepare flux data manually as usual
    151             # with only forecast fields with start times at 00/12
    152             # (but without 00/12 fields since these are
    153             # the initialisation times of the flux fields
    154             # and therefore are zero all the time)
    155149            self.types[str(c.acctype)] = {'times': str(c.acctime),
    156150                                          'steps': '{}/to/{}/by/{}'.format(
     
    523517                retr_param_dict['gaussian'] = self.gaussian
    524518
    525                 if pk == 'OG__SL':
    526                     pass
    527519                if pk == 'OG_OROLSM__SL' and not oro:
    528520                    oro = True
     
    658650        from genshi.template.text import NewTextTemplate
    659651        from genshi.template import  TemplateLoader
    660 
    661         loader = TemplateLoader(_config.PATH_TEMPLATES, auto_reload=False)
    662         namelist_template = loader.load(_config.TEMPFILE_NAMELIST,
    663                                        cls=NewTextTemplate)
    664 
    665         self.inputdir = c.inputdir
    666         area = np.asarray(self.area.split('/')).astype(float)
    667         grid = np.asarray(self.grid.split('/')).astype(float)
    668 
    669         if area[1] > area[3]:
    670             area[1] -= 360
    671         maxl = int((area[3] - area[1]) / grid[1]) + 1
    672         maxb = int((area[0] - area[2]) / grid[0]) + 1
    673 
    674         stream = namelist_template.generate(
    675             maxl = str(maxl),
    676             maxb = str(maxb),
    677             mlevel = str(self.level),
    678             mlevelist = str(self.levelist),
    679             mnauf = str(self.resol),
    680             metapar = '77',
    681             rlo0 = str(area[1]),
    682             rlo1 = str(area[3]),
    683             rla0 = str(area[2]),
    684             rla1 = str(area[0]),
    685             momega = str(c.omega),
    686             momegadiff = str(c.omegadiff),
    687             mgauss = str(c.gauss),
    688             msmooth = str(c.smooth),
    689             meta = str(c.eta),
    690             metadiff = str(c.etadiff),
    691             mdpdeta = str(c.dpdeta)
    692         )
    693 
    694         namelistfile = os.path.join(self.inputdir, _config.FILE_NAMELIST)
    695 
    696         with open(namelistfile, 'w') as f:
    697             f.write(stream.render('text'))
     652        from genshi.template.eval import  UndefinedError
     653
     654        try:
     655            loader = TemplateLoader(_config.PATH_TEMPLATES, auto_reload=False)
     656            namelist_template = loader.load(_config.TEMPFILE_NAMELIST,
     657                                            cls=NewTextTemplate)
     658
     659            self.inputdir = c.inputdir
     660            area = np.asarray(self.area.split('/')).astype(float)
     661            grid = np.asarray(self.grid.split('/')).astype(float)
     662
     663            if area[1] > area[3]:
     664                area[1] -= 360
     665            maxl = int((area[3] - area[1]) / grid[1]) + 1
     666            maxb = int((area[0] - area[2]) / grid[0]) + 1
     667
     668            stream = namelist_template.generate(
     669                maxl = str(maxl),
     670                maxb = str(maxb),
     671                mlevel = str(self.level),
     672                mlevelist = str(self.levelist),
     673                mnauf = str(self.resol),
     674                metapar = '77',
     675                rlo0 = str(area[1]),
     676                rlo1 = str(area[3]),
     677                rla0 = str(area[2]),
     678                rla1 = str(area[0]),
     679                momega = str(c.omega),
     680                momegadiff = str(c.omegadiff),
     681                mgauss = str(c.gauss),
     682                msmooth = str(c.smooth),
     683                meta = str(c.eta),
     684                metadiff = str(c.etadiff),
     685                mdpdeta = str(c.dpdeta)
     686            )
     687        except UndefinedError as e:
     688            print('... ERROR ' + str(e))
     689
     690            sys.exit('\n... error occured while trying to generate namelist ' +
     691                     _config.TEMPFILE_NAMELIST)
     692        except OSError as e:
     693            print('... ERROR CODE: ' + str(e.errno))
     694            print('... ERROR MESSAGE:\n \t ' + str(e.strerror))
     695
     696            sys.exit('\n... error occured while trying to generate template ' +
     697                     _config.TEMPFILE_NAMELIST)
     698
     699        try:
     700            namelistfile = os.path.join(self.inputdir, _config.FILE_NAMELIST)
     701
     702            with open(namelistfile, 'w') as f:
     703                f.write(stream.render('text'))
     704        except OSError as e:
     705            print('... ERROR CODE: ' + str(e.errno))
     706            print('... ERROR MESSAGE:\n \t ' + str(e.strerror))
     707
     708            sys.exit('\n... error occured while trying to write ' +
     709                     namelistfile)
    698710
    699711        return
     
    701713
    702714    def deacc_fluxes(self, inputfiles, c):
    703         '''Goes through all flux fields in ordered time and de-accumulate
     715        '''De-accumulate and disaggregate flux data.
     716
     717        Goes through all flux fields in ordered time and de-accumulate
    704718        the fields. Afterwards the fields are disaggregated in time.
    705719        Different versions of disaggregation is provided for rainfall
     
    9881002            if not gid:
    9891003                continue
    990 
     1004#============================================================================================
    9911005            # remove old fort.* files and open new ones
    9921006            # they are just valid for a single product
     
    9951009                silent_remove(fortfile)
    9961010                fdict[k] = open(fortfile, 'w')
    997 
     1011#============================================================================================
    9981012            # create correct timestamp from the three time informations
    9991013            cdate = str(codes_get(gid, 'date'))
     
    10191033                                'WRF' + cdate + '.' + ctime + '.000.grb2'), 'w')
    10201034                    olddate = cdate[:]
    1021 
     1035#============================================================================================
    10221036            # savedfields remembers which fields were already used.
    10231037            savedfields = []
     
    10831097                codes_release(gid)
    10841098                gid = codes_new_from_index(iid)
    1085 
     1099#============================================================================================
    10861100            for f in fdict.values():
    10871101                f.close()
    1088 
     1102#============================================================================================
    10891103            # call for Fortran program to convert e.g. reduced_gg grids to
    10901104            # regular_ll and calculate detadot/dp
     
    10971111                my_error(c.mailfail, 'fort.21 is empty while parameter eta \
    10981112                         is set to 1 in CONTROL file')
    1099 
     1113#============================================================================================
    11001114            # write out all output to log file before starting fortran programm
    11011115            sys.stdout.flush()
     
    11051119                c.exedir, _config.FORTRAN_EXECUTABLE)], shell=True)
    11061120            os.chdir(pwd)
    1107 
     1121#============================================================================================
    11081122            # create name of final output file, e.g. EN13040500 (ENYYMMDDHH)
    11091123            if c.maxstep > 12:
     
    11151129            # collect for final processing
    11161130            self.outputfilelist.append(os.path.basename(fnout))
    1117 
     1131#============================================================================================
    11181132            # create outputfile and copy all data from intermediate files
    11191133            # to the outputfile (final GRIB input files for FLEXPART)
     
    11351149                    shutil.copyfileobj(open(os.path.join(c.inputdir, 'fort.25'),
    11361150                                            'rb'), fout)
    1137 
     1151#============================================================================================
    11381152        if c.wrf:
    11391153            fwrf.close()
     
    11451159
    11461160    def process_output(self, c):
    1147         '''The grib files are postprocessed depending on the selection in
     1161        '''Postprocessing of FLEXPART input files.
     1162
     1163        The grib files are postprocessed depending on the selection in
    11481164        CONTROL file. The resulting files are moved to the output
    11491165        directory if its not equal to the input directory.
     
    11801196
    11811197            if c.format.lower() == 'grib2':
    1182                 p = subprocess.check_call(['codes_set', '-s', 'edition=2,',
     1198                p = subprocess.check_call(['grib_set', '-s', 'edition=2,',
    11831199                                           'productDefinitionTemplateNumber=8',
    11841200                                           ofile, ofile + '_2'])
  • source/python/mods/checks.py

    r97f4f4c r3f36e42  
    2626# ------------------------------------------------------------------------------
    2727
    28 
     28import _config
    2929# ------------------------------------------------------------------------------
    3030# FUNCTIONS
     
    3232
    3333
    34 def check_grid_area(grid, area, upper, lower, left , right):
    35     '''
     34def check_grid(grid):
    3635
    37 
    38     '''
    39     # if area was provided
    40     # decompose area into its 4 components
    41     if area:
    42         components = area.split('/')
    43         upper, left, lower, right = components
    44 
    45     if 'N' in grid:  # Gaussian output grid
    46         area = 'G'
    47         return grid, area
    48 
     36    if 'N' in grid:
     37        return grid
    4938    if '/' in grid:
    5039        gridx, gridy = grid.split('/')
     
    6251        # grid is defined in normal degree; new format
    6352        grid = '{}/{}'.format(float(grid), float(grid))
     53
     54    return grid
     55
     56def check_area(grid, area, upper, lower, left , right):
     57    '''
     58
     59
     60    '''
     61    if 'N' in grid:  # Gaussian output grid
     62        area = 'G'
     63        return area
     64
     65    # if area was provided decompose area into its 4 components
     66    if area:
     67        components = area.split('/')
     68        upper, left, lower, right = components
    6469
    6570    # determine area format
     
    8691                         'formats: %s ' (area))
    8792
    88     return grid, area
     93    return area
     94
     95def check_levels(levelist, level):
     96    '''
     97
     98    Parameters
     99    ----------
     100    par : :obj:``
     101        ...
     102
     103    Return
     104    ------
     105
     106    '''
     107    # assure consistency of levelist and level
     108    if not levelist and not level:
     109        raise ValueError('ERROR: neither levelist nor level '
     110                         'specified in CONTROL file')
     111    elif not levelist and level:
     112        levelist = '1/to/' + level
     113    elif (levelist and not level) or \
     114         (levelist[-1] != level[-1]):
     115        level = levelist.split('/')[-1]
     116    else:
     117        pass
     118
     119    # check if max level is a valid level
     120    if int(level) not in _config.MAX_LEVEL_LIST:
     121        raise ValueError('ERROR: \n'
     122                         'LEVEL must be the maximum level of a specified '
     123                         'level list from ECMWF, e.g. {} \n'
     124                         'Check parameter "LEVEL" or the max level of '
     125                         '"LEVELIST"!'.format(str(_config.MAX_LEVEL_LIST)))
     126
     127    return levelist, level
     128
     129
     130def check_ppid(c, ppid):
     131    '''Sets the current PPID.
     132
     133    Parameters
     134    ----------
     135    c : :obj:`ControlFile`
     136            Contains all the parameters of CONTROL file and
     137            command line.
     138
     139    ppid : :obj:`int` or :obj:`None`
     140        Contains the ppid number provided by the command line parameter
     141        of is None otherwise.
     142
     143    Return
     144    ------
     145
     146    '''
     147
     148    if not ppid:
     149        c.ppid = str(os.getppid())
     150    else:
     151        c.ppid = ppid
     152
     153    return
     154
     155
     156def check_():
     157    '''
     158
     159    Parameters
     160    ----------
     161    par : :obj:``
     162        ...
     163
     164    Return
     165    ------
     166
     167    '''
     168    return
  • source/python/mods/get_mars_data.py

    r1d15e27 r3f36e42  
    266266
    267267def remove_old(pattern, inputdir):
    268     '''Deletes old retrieval files matching the pattern.
     268    '''Deletes old retrieval files from current input directory
     269    matching the pattern.
    269270
    270271    Parameters
  • source/python/mods/prepare_flexpart.py

    r631ba13 r3f36e42  
    6363    inspect.getfile(inspect.currentframe()))) + '/../')
    6464import _config
     65from checks import check_ppid
    6566from classes.UioFiles import UioFiles
    6667from classes.ControlFile import ControlFile
     
    126127
    127128    '''
    128     c.check_ppid(ppid)
     129    check_ppid(c, ppid)
    129130
    130131    c.ecapi = ecapi
Note: See TracChangeset for help on using the changeset viewer.
hosted by ZAMG