Changes between Initial Version and Version 1 of FpInputMetMkavail


Ignore:
Timestamp:
Oct 21, 2015, 7:24:28 PM (9 years ago)
Author:
pesei
Comment:

create this with v.004 of mkAVAIL.py

Legend:

Unmodified
Added
Removed
Modified
  • FpInputMetMkavail

    v1 v1  
     1
     2== How to make an AVAILABLE file ==
     3
     4There used to be a Fortran programme for automatic creation of the AVAILBLE file (which is read by FLEXPART to know which windfields are available). Thanks to John Burkhardt's efforts, it has been superseded by python programme with better functionality.
     5
     6Find the latest version of `mkAVAIL.py` below:
     7
     8
     9{{{
     10#!/usr/bin/env python
     11
     12"""
     13SYNOPSIS
     14
     15    mk_AVAILABLE.py:  [-s,--startdate] [-e,--enddate] [-m,--model /ECWMF/ERAI/GFS] [-p, --path] [-a, --avpath] [-i, --interval] [-h] [-v,--verbose] [--version]
     16
     17DESCRIPTION
     18
     19    mk_AVAIL is a script to create AVAILABLE files for FLEXPART windfields.
     20
     21    Example usage:
     22    %mk_AVAIL.py -s 200601 -e 200701 -m ECMWF -p . -h
     23
     24    would create a file: AVAIALABLE that contained paths
     25    of all files available in the current directory between 200601 and 200701.
     26    The default start date is 197001 and the default end date is TODAY.
     27   
     28    adapted and simplified version / Petra Seibert
     29    v.004: add ERA-Interim with EI as model, proper sorting of dates if year 2000 included, option to define a path for AVAILABLE / Petra Seibert 2015-10-21
     30   
     31QUESTIONS
     32
     33    JFB: <jfb@nilu.no>
     34    v.003: petra.seibert at boku.ac.at
     35    v.004: petra.seibert at boku.ac.at
     36
     37LICENSE
     38
     39    This script follows creative commons usage.
     40
     41VERSION
     42
     43    $Id: 0.004 $
     44
     45"""
     46
     47import sys
     48import os
     49import traceback
     50import optparse
     51import time
     52import datetime
     53import socket
     54import glob
     55import string
     56
     57
     58def main ():
     59
     60    global options, args
     61   
     62    WIND_dir = '/xnilu_wrk/flex_wrk/WIND_FIELDS'
     63   
     64    ## THE AVAILABE MODEL PRODUCTS (ultimately this comes from a DB)
     65    MODEL = {}
     66    MODEL['ECMWF'] = {'prefix':'EN', 'timeindex':2}
     67    MODEL['ERAI'] = {'prefix':'EI', 'timeindex':2}
     68    MODEL['GFS']   = {'prefix':'GF', 'timeindex':2}
     69
     70    AVAIL_head = """DATE     TIME         FILENAME             SPECIFICATIONS\
     71    \nYYYYMMDD HHMISS\
     72    \n________ ______      __________________      __________________\n"""
     73    start_date = options.startdate
     74    sy = int(start_date[0:4])
     75    sm = int(start_date[4:6])
     76    end_date = options.enddate
     77    ey = int(end_date[0:4])
     78    em = int(end_date[4:6])
     79#    print end_date
     80   
     81    #Get the directory information
     82    M = MODEL[options.model]
     83    prfx = M['prefix']
     84    t = options.path
     85    avpath = options.avpath
     86   
     87   
     88    #Loop through the files in the directories
     89    warned = False
     90    d = t #directory
     91#    print d
     92    tind = M['timeindex'] #timestamp index
     93    searchstr = os.path.join(t,prfx)
     94    #Prepare output files
     95    fout = file(os.path.join(avpath,'AVAILABLE'),'w')
     96    fout.write(AVAIL_head)
     97    print 'searchstring:',searchstr
     98    files = glob.glob(searchstr+'*')
     99#    print files
     100    dict_dates={}
     101    for f in files:
     102        if (f[0:2] == './'): f = f[2:] # PS - remove this part if present
     103        fn = os.path.basename(f)
     104        if fn[-1]!='*':
     105            timestamp = fn[tind:]
     106            year = int(timestamp[0:2])
     107            if year < 58:
     108                year += 2000
     109            else:
     110                year += 1900
     111            dtstring = str(year)+' '+timestamp[2:9]
     112            dict_dates[dtstring] = f
     113    dates=sorted(dict_dates.items())
     114    for i,date in enumerate(dates): # go through dates in ascending order
     115        f = date[1] # now we have the filename+path
     116        fn = os.path.basename(f)
     117        if fn[-1]!='*':
     118            timestamp = fn[tind:]
     119            year = int(timestamp[0:2])
     120            if year < 58:
     121                year += 2000
     122            else:
     123                year += 1900
     124            month = int(timestamp[2:4])
     125            day = int(timestamp[4:6])
     126            hour = int(timestamp[6:8])
     127            fileT = year*100 + int(timestamp[2:4])
     128# PS: check for irregular intervals           
     129            date = datetime.datetime(year,month,day,hour)
     130            if i == 2:
     131              if options.timeint == '':
     132                timeint = date - date1
     133              else:
     134                timeint = datetime.timedelta(0,3600*int(options.timeint)) 
     135                if timeint != date - date1:
     136                  print 'WARNING - irregular interval',date - date1
     137                  print date1,f1,'\n',date, f,'\n'
     138            elif i > 2:
     139              if timeint != date - date1:
     140                print 'WARNING - irregular interval',date - date1
     141                print date1,f1,'\n',date, f,'\n'
     142                if options.timeint == '': timeint = date - date1
     143            date1 = date 
     144            f1 = f
     145           
     146            if i%5000 == 0: print 'progress:', i, f
     147           
     148            if fileT <= ey*100 + em and fileT >= sy*100 + sm:
     149                #if month <= em and month >= sm:
     150                    #print 'Match: %s' % fn
     151                #This is the fortran format: (i8,1x,i6,2(6x,a18))
     152                relpath = os.path.relpath(os.path.dirname(f),avpath)
     153                f = os.path.join(relpath,fn)
     154                if (f[0:2] == './'): f = f[2:] #  remove this part if present
     155#                print fn,f
     156                if len(f) > 18: #PS
     157                 if not warned:
     158                  print 'WARNING: Flexpart can only read 18 chars in WF-name'
     159                  print f, ' has ', len(f), ' characters!\n'
     160                  warned = True
     161                string = "%s%s%s %s0000      %s      ON DISC\n" %\
     162                 (year,str(month).zfill(2),str(day).zfill(2),str(hour).zfill(2),f.ljust(18))
     163                fout.write(string)
     164
     165    print 'Done: ',i
     166    print 'Written:', os.path.join(avpath,'AVAILABLE')
     167    fout.close()
     168
     169if __name__ == '__main__':
     170   
     171    try:
     172        start_time = time.time()
     173        today = datetime.datetime.now()
     174        parser = optparse.OptionParser(
     175                formatter=optparse.TitledHelpFormatter(),
     176                usage=globals()['__doc__'],
     177                version='$Id: 0.001 $')
     178        parser.add_option ('-v', '--verbose', action='store_true',
     179                default=False, help='verbose output')
     180        parser.add_option ('-s', '--startdate',
     181                dest='startdate',
     182                default='197001',
     183                help='YYYYMM integer')
     184        parser.add_option ('-e', '--enddate',
     185                # setting default as TODAY
     186                dest='enddate',
     187                default = str(today.year) + str(today.month).zfill(2),
     188                #default='200712',
     189                help='YYYYMM integer')
     190        parser.add_option ('-m', '--model',
     191                dest='model',
     192                default='ECMWF', help='ECMWF or GFS')
     193        parser.add_option ('-p', '--path',
     194                dest='path',
     195                default='.', help='path to be searched. Escape or quote * and ? ')
     196        parser.add_option ('-a', '--avpath',
     197                dest='avpath',
     198                default='.', help='path for AVAILABLE file ')
     199        parser.add_option ('-i', '--interval',
     200                dest='timeint',
     201                default='', help='expected time interval in h. If omitted, show every change')
     202        (options, args) = parser.parse_args()
     203        #QUERY['modelType'] = options.model
     204        #QUERY['start_date'] = options.startdate
     205        #QUERY['end_date'] = options.enddate
     206 
     207        #if len(args) < 1:
     208        #    parser.error ('missing argument')
     209        if options.verbose: print time.asctime()
     210        exit_code = main()
     211        if exit_code is None:
     212            exit_code = 0
     213        if options.verbose: print time.asctime()
     214        if options.verbose: print 'TOTAL TIME IN MINUTES:',
     215        if options.verbose: print (time.time() - start_time) / 60.0
     216        sys.exit(exit_code)
     217    except KeyboardInterrupt, e: # Ctrl-C
     218        raise e
     219    except SystemExit, e: # sys.exit()
     220        raise e
     221    except Exception, e:
     222        print 'ERROR, UNEXPECTED EXCEPTION'
     223        print str(e)
     224        traceback.print_exc()
     225        os._exit(1)
     226       
     227   
     228
     229# vim:set sr et ts=4 sw=4 ft=python fenc=utf-8: // See Vim, :help 'modeline'
     230
     231}}}