HWRF  trunk@4391
rocoto_from_vitals.py
1 #! /usr/bin/env python
2 
3 import sys, logging, collections
4 import produtil.setup
6 
7 from hwrf.numerics import to_timedelta, to_datetime
8 
9 ##@namespace ush.rocoto_from_vitals
10 # Reads the tcvitals, and generates Rocoto XML entities for storm cycle lists.
11 #
12 # Call as follows:
13 # @code{.sh}
14 # rocoto-from-vitals.py [-n] /path/to/vitals-file1 [/path/to/vitals-file2 [...]]
15 # @endcode
16 #
17 # Where:
18 # * -n --- disable storm renumbering (use this for running Invests)
19 # * /path/to/vitals/file --- a tcvitals database file to read
20 
21 def main():
23 
24  renumber=True
25  args=sys.argv[1:]
26 
27  if args[0]=='-n':
28  renumber=False
29  args=args[1:]
30 
31  if len(args)<1:
32  print>>sys.stderr, """ERROR: Format: rocoto-from-vitals.py [-n] /path/to/vitals-file1 [/path/to/vitals-file2 [...]]
33  -n = disable renumbering (do this for invests)
34 
35  ERROR: Script requires at least one argument."""
36  sys.exit(1)
37 
38  logger=logging.getLogger('rocoto_from_vitals')
39  revital=hwrf.revital.Revital(logger=logger)
40  logger.info('Read input files: '+repr(args))
41  revital.readfiles(args,raise_all=False)
42  if renumber:
43  logger.info('Renumber invests.')
44  revital.renumber()
45  else:
46  logger.info('Not renumbering vitals. Just clean them up')
47  revital.clean_up_vitals()
48 
49  basins=dict()
50  numbers=dict()
51  storms=collections.defaultdict(set)
52  epsilon=to_timedelta(5)
53  six_hours=to_timedelta(6*3600)
54 
55  for vit in revital:
56  storms[vit.longstormid].add(vit.when.strftime('%Y%m%d%H'))
57  basins[vit.longstormid]=vit.basin1.upper()
58  numbers[vit.longstormid]=vit.stnum
59 
60  sortstorms=[ x for x in storms.iterkeys() ]
61  sortstorms.sort()
62 
63  for storm in sortstorms:
64  unsorted_cycles=storms[storm]
65  cycles=list(unsorted_cycles)
66  cycles = [ to_datetime(x) for x in cycles ]
67  cycles.sort()
68  basin1=basins[storm]
69  number=numbers[storm]
70 
71  if number>=50:
72  sys.stderr.write("Skipping %02d%s\n"%(number,basin1))
73  continue
74 
75  sys.stdout.write('<!ENTITY %ssid "%02d%s">\n'%(storm,number,basin1))
76  sys.stdout.write('<!ENTITY %ssidlc "%02d%s">\n'
77  %(storm,number,basin1.lower()))
78  sys.stdout.write('<!ENTITY %scyc "'%(storm,))
79  first=cycles[0]
80  last=cycles[0]
81  sent=cycles[0]-six_hours
82  for cycle in cycles:
83  if to_datetime(cycle) > to_datetime(last)+six_hours+epsilon:
84  # Found a break in the cycles
85  sys.stdout.write('<cycledef>%s00 %s00 06:00:00</cycledef> '
86  %(first.strftime('%Y%m%d%H'),
87  last.strftime('%Y%m%d%H')))
88  first=cycle
89  last=cycle
90  sent=cycle
91  else:
92  last=cycle
93  if sent+epsilon < last:
94  # Need to send the last group of cycles
95  sys.stdout.write('<cycledef>%s00 %s00 06:00:00</cycledef> '
96  %(first.strftime('%Y%m%d%H'),
97  last.strftime('%Y%m%d%H')))
98  sys.stdout.write('">\n')
99 
100 if __name__=='__main__': main()
Contains setup(), which initializes the produtil package.
Definition: setup.py:1
Defines the Revital class which manipulates tcvitals files.
Definition: revital.py:1
def setup(ignore_hup=False, dbnalert_logger=None, jobname=None, cluster=None, send_dbn=None, thread_logger=False, thread_stack=2 **24, kwargs)
Initializes the produtil package.
Definition: setup.py:15
Time manipulation and other numerical routines.
Definition: numerics.py:1
This class reads one or more tcvitals files and rewrites them as requested.
Definition: revital.py:38