HWRF  trunk@4391
rocoto.py
1 """!This module contains utilities for plugging HWRF into the Rocoto
2 workflow manager."""
3 
4 ##@var __all__
5 # List of symbols exported by "from hwrf.rocoto import *"
6 __all__=['cycles_as_entity']
7 
8 import StringIO, random
9 import hwrf.numerics
10 
11 from hwrf.numerics import to_datetime, to_timedelta
12 
13 ##@var epsilon
14 # An epsilon value for time equality comparisons
15 epsilon=to_timedelta(5)
16 
17 ##@var six_hours
18 # A datetime.timedelta that represents +6 hours
19 six_hours=to_timedelta(6*3600)
20 
21 ##@var sanity_quotes
22 # A list of quotes to print (one at random) when a sanity check fails.
23 # The purpose of this is to assure the user that he/she/it is not alone
24 # in lacking sanity; and that sanity, perhaps, is not something that
25 # one should strive for anyway.
26 # @hideinitializer
27 sanity_quotes=list([
28  '''"I am thankful the most important key in history was invented. It's
29 not the key to your house, your car, your boat, your safety deposit
30 box, your bike lock or your private community. It's the key to order,
31 sanity, and peace of mind. The key is 'Delete.'" -- Elayne Boosler''',
32  '''"For me, insanity is super sanity. The normal is psychotic. Normal
33 means lack of imagination, lack of creativity." -- Jean Dubuffet''',
34  '''"Too much sanity may be madness and the maddest of all, to see life as
35 it is and not as it should be." -- Miguel de Cervantes''',
36  '''"One of the definitions of sanity is the ability to tell real from
37 unreal. Soon we'll need a new definition." -- Alvin Toffler''',
38  '''"You have to keep your sanity as well as know how to distance yourself
39 from it while still holding onto the reins tightly. That is a very
40 difficult thing to do, but I'm learning." -- Diahann Carroll''',
41  '''"The statistics on sanity are that one out of every four Americans is
42 suffering from some form of mental illness. Think of your three best
43 friends. If they're okay, then it's you." -- Rita Mae Brown''',
44  '''"[HWRF is] a camel designed by a comedian."
45  -- unattributed''',
46  '''"Well, sanity, I suppose, is getting people to see the world your
47 way." -- Paul Merton''',
48  '''"Our sense of worth, of well-being, even our sanity depends upon our
49 remembering. But, alas, our sense of worth, our well-being, our sanity
50 also depend upon our forgetting." -- Joyce Appleby''',
51  '''"I had a quick grasp of the secret to sanity, it had become the
52 ability to hold the maximum of impossible combinations in one's mind."
53 -- Norman Mailer''',
54  '''"Sanity calms, but madness is more interesting." -- John Russell''',
55  '''"Sanity is surely not about normality in the statistical sense: it is
56 about an eternal and natural idea of the healthy personality - which
57 indeed may be a rare achievement." -- Michael Leunig''',
58  '''"Sanity is madness put to good use." -- George Santayana''',
59  '''"In a mad world, only the mad are sane." -- Akiro Kurosawa''',
60  '''"We are all born mad. Some remain so." -- Samuel Beckett''',
61  '''"Insanity is doing the same thing in the same way and
62 expecting a different outcome." -- Chinese Proverb''',
63  '''"I feel like a fugitive from the law of averages."
64  -- William H. Mauldin''',
65  '''"You should listen to your heart, and not the voices in your head."
66  -- Matt Groening''',
67  '''"No excellent soul is exempt from a mixture of madness." -- Aristotle''',
68  '''"Everything great in the world is done by neurotics; they alone
69 founded our religions and created our masterpieces." -- Marcel Proust''',
70  '''"Today I felt pass over me a breath of wind from the wings of
71 madness." -- Charles Baudelaire''',
72  '''"When we remember we are all mad, the mysteries disappear and life
73 stands explained." -- Mark Twain''',
74  '''"Without bigots, eccentrics, cranks and heretics the world would not
75 progress." -- Frank Gelett Burgess''',
76  '''"Correct me if I'm wrong, but hasn't the fine line between sanity and
77 madness gotten finer?" -- George Price''',
78  '''"Ordinarily he was insane, but he had lucid moments when he was merely
79 stupid." -- Heinrich Heine''',
80  '''"Oh, that way madness lies; let me shun that." -- William Shakespeare''',
81  '''"You're only given a little spark of madness. You mustn't lose it."
82  -- Robin Williams''',
83  '''"There's a fine line between genius and insanity. I have erased this
84 line." -- Oscar Levant''',
85  '''"Sanity is not statistical." -- George Orwell''',
86  '''"Part of being sane, is being a little bit crazy." -- Janet Long''',
87  '''"I don't really trust a sane person." -- Lyle Alzado''',
88  '''"Truly great madness cannot be achieved without significant intelligence."
89  -- Henrik Tikkanen''',
90  '''"Might we not say to the confused voices which sometimes arise from
91 the depths of our being, 'ladies, be so kind as to speak only four at
92 a time?'" -- Madame Swetchine''',
93  '''"Insanity is often the logic of an accurate mind overtasked."
94  -- Oliver W. Holmes''',
95  '''"Flibbidy Jibbit." -- HWRF Sanity Checker''',
96  '''"I became insane, with long intervals of horrible sanity."
97  -- Edgar Allan Poe''',
98  '''"Sanity and happiness are an impossible combination."
99  -- Mark Twain''',
100  '''"One person's craziness is another person's reality."
101  -- Tim Burton''',
102  '''"Don't worry. You're just as sane as I am."
103  -- J.K. Rowling, "Harry Potter and the Order of the Phoenix"''',
104  '''"Here lies a nuisance dedicated to sanity." -- David Low''',
105  '''"Sanity is only that which is within the frame of reference of
106 conventional thought." -- Erich Fromm''',
107  '''"If you think anyone is sane you just don't know enough about
108 them." -- Christopher Moore, "Practical Demonkeeping"''',
109  '''"I mean, maybe I am crazy. I mean, maybe. But if this is all
110 there is, then I don't want to be sane."
111  -- Neil Gaiman, "Neverwhere"''',
112  '''"Show me a sane man and I will cure him for you." -- C.G. Jung''',
113  '''"When you're the only sane person, you look like the only insane
114 person." -- Criss Jami, "Diotima, Battery, Electric Personality"''',
115  '''"When the whole world is crazy, it doesn't pay to be sane."
116  -- Terry Goodkind, "The Pillars of Creation"''',
117  '''"Sanity is a cozy lie." -- Susan Sontag''',
118  '''"One must be sane to think clearly, but one can think deeply and
119 be quite insane." -- Nikola Tesla''',
120  '''"When dealing with the insane, the best method is to pretend to
121 be sane." -- Hermann Hesse''',
122  '''"Perfect sanity is a myth propagated by straitjacket salesmen."
123  -- Rebecca McKinsey''',
124  '''"As long as you doubt your sanity, you can't be insane."
125  -- Miles Keaton Andrew''',
126  '''"Sometimes, to regain sanity, one had to acknowledge and embrace
127 the madness." -- Morgan Rhodes, "Rebel Spring"''',
128  '''"Sanity is transmuting all the insane parts of your brain into
129 a creative outlet" -- Jaeda DeWalt''',
130  '''"Reality is a hallucination shared by most sane men."
131  -- Mokokoma Mokhonoana''',
132  '''"Sanity? Sorry, but I don't remember having such a useless
133 thing in the first place" -- Tite Kubo''' ])
134 """A set of famous quotes about sanity. These are printed by the
135 sanity_check_failed function after a failure of a sanity check. The
136 purpose is to give the user a measure of emotional support after
137 failure to configure an inevitably complex system."""
138 
139 def entity_quote(string):
140  """!Returns a copy of the string with & " < % and > replaced with
141  their respective XML entities &#38; &#34; &#60; &#37; and &#62;
142  @param string the string to parse.
143  @returns a new string with proper replacements"""
144  return string.replace('&','&#38;') \
145  .replace('"','&#34;') \
146  .replace('<','&#60;') \
147  .replace('%','&#37;') \
148  .replace('>','&#62;')
149 
150 def sanity_check_failed(logger,ex):
151  """!Logs information about a failure of a sanity check routine.
152  The failure is in exception ex, and the "logger" argument must be
153  a logging.Logger.
154  @param ex the failure information
155  @param logger a logging.Logger for log messages"""
156  quote=sanity_quotes[random.randint(0,len(sanity_quotes)-1)]
157  logger.critical('Sanity check failed.',exc_info=True)
158  logger.info('\n'+quote+'\n'
159  'HWRF SANITY CHECK FAILED. Cannot run this configuration.\n'
160  'Check paths and conf files. See earlier messages for details.')
161 
162 def cycles_as_entity(cycleset):
163  """!Returns a set of Rocoto XML <cycledef> tags to add to an XML
164  file. The tags will define the list of cycles specified in the
165  cycleset argument. That argument must be a set of datetime
166  objects.
167  @param cycleset an iterable of cycles to convert. These can be
168  anything accepted by hwrf.numerics.to_datetime()"""
169  cycles=list(cycleset)
170  cycles = [ to_datetime(x) for x in cycles ]
171  cycles.sort()
172  ctream=StringIO.StringIO()
173  first=cycles[0]
174  last=cycles[0]
175  sent=cycles[0]-six_hours
176  for cycle in cycles:
177  if to_datetime(cycle) > to_datetime(last)+six_hours+epsilon:
178  # Found a break in the cycles
179  writeme='<cycledef>%s00 %s00 06:00:00</cycledef> ' \
180  %(first.strftime('%Y%m%d%H'),
181  last.strftime('%Y%m%d%H'))
182  ctream.write(writeme)
183  sent=last
184  first=cycle
185  last=cycle
186  else:
187  last=cycle
188  if sent+epsilon < last:
189  # Need to send the last group of cycles
190  writeme='<cycledef>%s00 %s00 06:00:00</cycledef> ' \
191  %(first.strftime('%Y%m%d%H'),
192  last.strftime('%Y%m%d%H'))
193  ctream.write(writeme)
194  ctream.write('\n')
195 
196  out=str(ctream.getvalue())
197  ctream.close()
198  return out
199 
def cycles_as_entity(cycleset)
Returns a set of Rocoto XML tags to add to an XML file.
Definition: rocoto.py:162
Time manipulation and other numerical routines.
Definition: numerics.py:1
def sanity_check_failed(logger, ex)
Logs information about a failure of a sanity check routine.
Definition: rocoto.py:150
def entity_quote(string)
Returns a copy of the string with & " < % and > replaced with their respective XML entities & " < % and >...
Definition: rocoto.py:139