Changes between Version 8 and Version 9 of FpInputMetMkavail


Ignore:
Timestamp:
Jan 31, 2022, 5:25:58 PM (2 years ago)
Author:
pesei
Comment:

replace v7 (Py2) by v8 (Py3)

Legend:

Unmodified
Added
Removed
Modified
  • FpInputMetMkavail

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