FpInputMetMkavail: mkAVAIL.py

File mkAVAIL.py, 7.7 KB (added by pesei, 5 years ago)

mkAVAIL.py v0.005

Line 
1#!/usr/bin/env python
2
3"""
4SYNOPSIS
5
6    mk_AVAILABLE.py:  [-s,--startdate] [-e,--enddate] [-m,--model /ECWMF/ERAI/GFS] [-p, --path] [-a, --avpath] [-i, --interval] [-h] [-v,--verbose] [--version]
7
8DESCRIPTION
9
10    mk_AVAIL is a script to create AVAILABLE files for FLEXPART windfields.
11
12    Example usage:
13    %mk_AVAIL.py -s 200601 -e 200701 -m ECMWF -p . -h
14
15    would create a file: AVAIALABLE that contained paths
16    of all files available in the current directory between 200601 and 200701.
17    The default start date is 197001 and the default end date is TODAY.
18   
19    adapted and simplified version / Petra Seibert
20    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
21    v.005: check whether any files are found before opening AVAILABLE, if not issue warning and stop. / Petra Seibert 2015-12-07
22   
23QUESTIONS
24
25    JFB: <jfb@nilu.no>
26    v.003: petra.seibert at boku.ac.at
27    v.004: petra.seibert at boku.ac.at
28    v.005: petra.seibert at boku.ac.at
29
30LICENSE
31
32    This script follows creative commons usage.
33
34VERSION
35
36    $Id: 0.004 $
37
38"""
39
40import sys
41import os
42import traceback
43import optparse
44import time
45import datetime
46import socket
47import glob
48import string
49
50
51def main ():
52
53    global options, args
54   
55    WIND_dir = '/xnilu_wrk/flex_wrk/WIND_FIELDS'
56   
57    ## THE AVAILABE MODEL PRODUCTS (ultimately this comes from a DB)
58    MODEL = {}
59    MODEL['ECMWF'] = {'prefix':'EN', 'timeindex':2}
60    MODEL['ERAI'] = {'prefix':'EI', 'timeindex':2}
61    MODEL['GFS']   = {'prefix':'GF', 'timeindex':2}
62
63    AVAIL_head = """DATE     TIME         FILENAME             SPECIFICATIONS\
64    \nYYYYMMDD HHMISS\
65    \n________ ______      __________________      __________________\n"""
66    start_date = options.startdate
67    sy = int(start_date[0:4])
68    sm = int(start_date[4:6])
69    end_date = options.enddate
70    ey = int(end_date[0:4])
71    em = int(end_date[4:6])
72#    print end_date
73   
74    #Get the directory information
75    M = MODEL[options.model]
76    prfx = M['prefix']
77    t = options.path
78    avpath = options.avpath
79   
80   
81    #Loop through the files in the directories
82    warned = False
83    d = t #directory
84#    print d
85    tind = M['timeindex'] #timestamp index
86    searchstr = os.path.join(t,prfx)
87    print 'searchstring:',searchstr
88    files = glob.glob(searchstr+'*')
89#    print files
90    dict_dates={}
91    for f in files:
92        if (f[0:2] == './'): f = f[2:] # PS - remove this part if present
93        fn = os.path.basename(f)
94        if fn[-1]!='*':
95            timestamp = fn[tind:]
96            year = int(timestamp[0:2])
97            if year < 58:
98                year += 2000
99            else:
100                year += 1900
101            dtstring = str(year)+' '+timestamp[2:9]
102            dict_dates[dtstring] = f
103    dates=sorted(dict_dates.items())
104    if len(dates) == 0:
105      print 'no files found with this search string'
106      print 'aborting. '
107      sys.exit(0)
108    else:
109      print 'found ',len(dates),'files'
110      #Prepare output files
111      fout = file(os.path.join(avpath,'AVAILABLE'),'w')
112      fout.write(AVAIL_head)
113
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+1 # as i starts with 0
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 ERAI 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'
hosted by ZAMG