FpInputMetMkavail: mkAVAIL_v8.py.check

File mkAVAIL_v8.py.check, 7.6 KB (added by pesei, 2 years ago)

Version 8 (Python 3)

Line 
1#!/usr/bin/env python3
2
3"""
4SYNOPSIS
5
6  mk_AVAILABLE.py: [-s,--startdate] [-e,--enddate] [-m,--model /ECWMF/ERAI/EI/E5/EA/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 . 
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  v.006 PS 2018-04-24: add ERA5 as model option
23  v.007 PS 2018-06-25: correct bug introduced in v006: 2 spaces missing in output format
24  v.008 PS 2022-01-31: convert to Python3 and some fixes
25QUESTIONS to
26  JFB: <jfb@nilu.no>
27  version>=003: petra.seibert at univie.ac.at
28
29LICENSE
30  This script follows creative commons usage.
31  Valid-License-Identifier: CC-BY-4.0
32
33VERSION
34  $Id: 0.008 $
35"""
36
37import sys
38import os
39import traceback
40import optparse
41import time
42import datetime
43import socket
44import glob
45import string
46
47
48def main ():
49
50  global options, args, models
51  version = '$Id: 0.006 $' 
52 
53  WIND_dir = '/xnilu_wrk/flex_wrk/WIND_FIELDS'
54 
55  # dict of dicts with model information
56  # timeindex: index in the filne name string where the time information starts
57  print(list(MODEL.keys()))
58
59  AVAIL_head = \
60  """DATE     TIME        FILENAME             SPECIFICATIONS\
61   \nYYYYMMDD HHMISS\
62  \n________ ______      __________________    __________________\n"""
63  start_date = options.startdate
64  sy = int(start_date[0:4])
65  sm = int(start_date[4:6])
66  end_date = options.enddate
67  ey = int(end_date[0:4])
68  em = int(end_date[4:6])
69 
70  #Get the directory information
71  M = MODEL[options.model]
72  prfx = M['prefix']
73  t = options.path
74  avpath = options.avpath
75 
76 
77  #Loop through the files in the directories
78 
79  warned = False
80  d = t #directory
81 
82  tind = M['timeindex'] #timestamp index
83  searchstr = os.path.join(t,prfx)
84  print('searchstring:',searchstr)
85  files = glob.glob(searchstr + '*')
86  if options.verbose: print(len(files), ' wind-field files found')
87  dict_dates={}
88  for f in files:
89    if (f[0:2] == './'): f = f[2:] # PS - remove this part if present
90    fn = os.path.basename(f)
91    if fn[-1] != '*':
92      timestamp = fn[tind:]
93      year = int(timestamp[0:2])
94      if year < 58:
95        year += 2000
96      else:
97        year += 1900
98      dtstring = str(year)+' '+timestamp[2:9]
99      dict_dates[dtstring] = f
100  dates = sorted(dict_dates.items())
101  if len(dates) == 0:
102    print('no files found with this search string')
103    print('aborting. ')
104    sys.exit(0)
105  else:
106    print('found ',len(dates),'files')
107    #Prepare output files
108    fout = open(os.path.join(avpath,'AVAILABLE'),'w')
109    fout.write(AVAIL_head)
110
111  icount = 0
112  for i,date in enumerate(dates): # go through dates in ascending order
113    f = date[1] # now we have the filename+path
114    fn = os.path.basename(f)
115    if fn[-1]!='*':
116      timestamp = fn[tind:]
117      year = int(timestamp[0:2])
118      if year < 58:
119        year += 2000
120      else:
121        year += 1900
122      month = int(timestamp[2:4])
123      day   = int(timestamp[4:6])
124      hour  = int(timestamp[6:8])
125      fileT = year*100 + int(month)
126# PS: now check for irregular intervals     
127      date = datetime.datetime(year,month,day,hour)
128      if i == 2:
129        if options.timeint == '':
130          timeint = date - date1
131        else:
132          timeint = datetime.timedelta(0,3600*int(options.timeint)) 
133        if timeint != date - date1:
134          print('WARNING - irregular interval',date - date1)
135          print(date1,f1,'\n',date, f,'\n')
136      elif i > 2:
137        if timeint != date - date1: 
138          print('WARNING - irregular interval',date - date1)
139          print(date1,f1,'\n',date, f,'\n')
140        if options.timeint == '': timeint = date - date1
141      date1 = date 
142      f1 = f
143     
144      if i%5000 == 0: print('progress:', i, 'of', len(dates), f)
145     
146      if fileT >= sy*100 + sm and fileT <= ey*100 + em :
147     
148        if os.path.dirname(fn) != '': 
149          relpath = os.path.relpath( os.path.dirname(f), avpath )
150          f = os.path.join(relpath,fn)
151        else:
152          f = fn
153
154        if (f[0:2] == './'): f = f[2:] #  remove this part if present
155
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
162        #This is the fortran format: (i8,1x,i6,2(6x,a18))
163        string = "%s%s%s %s0000      %s    ON DISC\n" %\
164         (year,str(month).zfill(2),str(day).zfill(2),str(hour).zfill(2),f.ljust(18))
165        fout.write(string)
166        icount = icount + 1
167
168  print('Done: ',i+1) # i starts with 0
169  print('Written', icount, 'entries to', os.path.join(avpath,'AVAILABLE'))
170  fout.close()
171
172if __name__ == '__main__':
173  MODEL = {}
174  MODEL['ECMWF'] = {'prefix':'EN', 'timeindex':2}
175  MODEL['ERAI']  = {'prefix':'EI', 'timeindex':2}
176  MODEL['EI']  = {'prefix':'EI', 'timeindex':2}
177  MODEL['E5']  = {'prefix':'E5', 'timeindex':2}
178  MODEL['EA']  = {'prefix':'EA', 'timeindex':2}
179  MODEL['GFS']   = {'prefix':'GF', 'timeindex':2}
180 
181  models = '/'.join(list(MODEL.keys()))
182 
183  try:
184    start_time = time.time()
185    today = datetime.datetime.now()
186
187    parser = optparse.OptionParser(
188        formatter = optparse.TitledHelpFormatter(),
189        usage = globals()['__doc__'])
190
191    parser.add_option ('-v', '--verbose', action = 'store_true',
192        default = False, help = 'verbose output')
193
194    parser.add_option ('-s', '--startdate',
195        dest = 'startdate',
196        default = '190001',
197        help = 'startdate YYYYMM integer')
198
199    parser.add_option ('-e', '--enddate',
200        # setting default as TODAY
201        dest = 'enddate',
202        default = str(today.year) + str(today.month).zfill(2),
203        #default = '200712',
204        help = 'enddate YYYYMM integer')
205
206    parser.add_option ('-m', '--model',
207        dest = 'model',
208        default = 'ECMWF', help = models)
209
210    parser.add_option ('-p', '--path',
211        dest = 'path',
212        default = '.', help = 'path to be searched for windfields. Escape or quote * and ? ')
213
214    parser.add_option ('-a', '--avpath',
215        dest = 'avpath',
216        default = '.', help = 'path for AVAILABLE file ')
217
218    parser.add_option ('-i', '--interval',
219        dest = 'timeint',
220        default = '', help = 'expected time interval in h. If omitted, show every change')
221
222    (options, args) = parser.parse_args()
223
224    #QUERY['modelType'] = options.model
225    #QUERY['start_date'] = options.startdate
226    #QUERY['end_date'] = options.enddate
227 
228    #if len(args) < 1:
229    #  parser.error ('missing argument')
230
231    if options.verbose: print(time.asctime())
232    exit_code = main()
233    if exit_code is None:
234      exit_code = 0
235    if options.verbose: print(time.asctime())
236    if options.verbose: print('TOTAL TIME IN MINUTES:', end=' ')
237    if options.verbose: print((time.time() - start_time) / 60.0)
238    sys.exit(exit_code)
239  except KeyboardInterrupt as e: # Ctrl-C
240    raise e
241  except SystemExit as e: # sys.exit()
242    raise e
243  except Exception as e:
244    print('ERROR, UNEXPECTED EXCEPTION')
245    print(str(e))
246    traceback.print_exc()
247    os._exit(1)
248   
249 
250
251# vim:set sr et ts=4 sw=4 ft=python fenc=utf-8: // See Vim, :help 'modeline'
hosted by ZAMG