source: inundation/pyvolution/util.py @ 3085

Last change on this file since 3085 was 3083, checked in by sexton, 19 years ago

legend now

File size: 37.2 KB
Line 
1"""This module contains various auxiliary function used by pyvolution.
2
3It is also a clearing house for functions that may later earn a module
4of their own.
5"""
6
7
8import utilities.polygon
9from warnings import warn
10
11
12
13def file_function(filename,
14                  domain = None,
15                  quantities = None,
16                  interpolation_points = None,
17                  verbose = False,
18                  use_cache = False):
19    """Read time history of spatial data from NetCDF file and return
20    a callable object.
21
22    Input variables:
23   
24    filename - Name of sww or tms file
25       
26       If the file has extension 'sww' then it is assumed to be spatio-temporal
27       or temporal and the callable object will have the form f(t,x,y) or f(t)
28       depending on whether the file contains spatial data
29
30       If the file has extension 'tms' then it is assumed to be temporal only
31       and the callable object will have the form f(t)
32
33       Either form will return interpolated values based on the input file
34       using the underlying interpolation_function.
35
36    domain - Associated domain object   
37       If domain is specified, model time (domain.starttime)
38       will be checked and possibly modified.
39   
40       All times are assumed to be in UTC
41       
42       All spatial information is assumed to be in absolute UTM coordinates.
43
44    quantities - the name of the quantity to be interpolated or a
45                 list of quantity names. The resulting function will return
46                 a tuple of values - one for each quantity 
47
48    interpolation_points - list of absolute UTM coordinates for points (N x 2) at
49    which values are sought
50   
51    use_cache: True means that caching of intermediate result of
52               Interpolation_function is attempted
53
54   
55    See Interpolation function for further documentation
56    """
57
58
59    if use_cache is True:
60        try:
61            from caching import cache
62        except:
63            msg = 'Caching was requested, but caching module'+\
64                  'could not be imported'
65            raise msg
66
67
68        f = cache(_file_function,
69                  filename,
70                  {'domain': domain,
71                   'quantities': quantities,
72                   'interpolation_points': interpolation_points,
73                   'verbose': verbose},
74                  dependencies = [filename],
75                  compression = False,
76                  verbose = verbose)
77        #FIXME (Ole): Pass cache arguments, such as compression, in some sort of
78        #structure
79       
80    else:
81        f = _file_function(filename,
82                           domain,
83                           quantities,
84                           interpolation_points,
85                           verbose)           
86
87    return f
88
89
90
91def _file_function(filename,
92                   domain = None,
93                   quantities = None,
94                   interpolation_points = None,
95                   verbose = False):
96    """Internal function
97   
98    See file_function for documentatiton
99    """
100   
101
102    #FIXME (OLE): Should check origin of domain against that of file
103    #In fact, this is where origin should be converted to that of domain
104    #Also, check that file covers domain fully.
105    #If we use the suggested Point_set class for interpolation points
106    #here it would be easier
107
108    #Take into account:
109    #- domain's georef
110    #- sww file's georef
111    #- interpolation points as absolute UTM coordinates
112
113
114    assert type(filename) == type(''),\
115               'First argument to File_function must be a string'
116
117    try:
118        fid = open(filename)
119    except Exception, e:
120        msg = 'File "%s" could not be opened: Error="%s"'\
121                  %(filename, e)
122        raise msg
123
124    line = fid.readline()
125    fid.close()
126
127    if quantities is None: 
128        if domain is not None:
129            quantities = domain.conserved_quantities
130
131
132
133    if line[:3] == 'CDF':
134        return get_netcdf_file_function(filename, domain, quantities,
135                                        interpolation_points,
136                                        verbose = verbose)
137    else:
138        raise 'Must be a NetCDF File'
139
140
141
142def get_netcdf_file_function(filename,
143                             domain=None,
144                             quantity_names=None,
145                             interpolation_points=None,
146                             verbose = False):
147    """Read time history of spatial data from NetCDF sww file and
148    return a callable object f(t,x,y)
149    which will return interpolated values based on the input file.
150
151    If domain is specified, model time (domain.starttime)
152    will be checked and possibly modified
153   
154    All times are assumed to be in UTC
155
156    See Interpolation function for further documetation
157   
158    """
159   
160   
161    #FIXME: Check that model origin is the same as file's origin
162    #(both in UTM coordinates)
163    #If not - modify those from file to match domain
164    #Take this code from e.g. dem2pts in data_manager.py
165    #FIXME: Use geo_reference to read and write xllcorner...
166       
167
168    #FIXME: Maybe move caching out to this level rather than at the
169    #Interpolation_function level (below)
170
171    import time, calendar, types
172    from config import time_format
173    from Scientific.IO.NetCDF import NetCDFFile
174    from Numeric import array, zeros, Float, alltrue, concatenate, reshape
175    from utilities.numerical_tools import ensure_numeric   
176
177    #Open NetCDF file
178    if verbose: print 'Reading', filename
179    fid = NetCDFFile(filename, 'r')
180
181    if type(quantity_names) == types.StringType:
182        quantity_names = [quantity_names]       
183   
184    if quantity_names is None or len(quantity_names) < 1:
185        #If no quantities are specified get quantities from file
186        #x, y, time are assumed as the independent variables so
187        #they are excluded as potentiol quantities
188        quantity_names = []
189        for name in fid.variables.keys():
190            if name not in ['x', 'y', 'time']:
191                quantity_names.append(name)
192
193    if len(quantity_names) < 1:               
194        msg = 'ERROR: At least one independent value must be specified'
195        raise msg
196
197
198    if interpolation_points is not None:
199        interpolation_points = ensure_numeric(interpolation_points, Float)
200        msg = 'Points must by N x 2. I got %d' %interpolation_points.shape[1]
201        assert interpolation_points.shape[1] == 2, msg
202
203
204    #Now assert that requested quantitites (and the independent ones)
205    #are present in file
206    missing = []
207    for quantity in ['time'] + quantity_names:
208        if not fid.variables.has_key(quantity):
209            missing.append(quantity)
210
211    if len(missing) > 0:
212        msg = 'Quantities %s could not be found in file %s'\
213              %(str(missing), filename)
214        fid.close()
215        raise msg
216
217    #Decide whether this data has a spatial dimension
218    spatial = True
219    for quantity in ['x', 'y']:
220        if not fid.variables.has_key(quantity):
221            spatial = False
222
223    if filename[-3:] == 'tms' and spatial is True:
224        msg = 'Files of type tms must not contain spatial information'
225        raise msg
226
227    if filename[-3:] == 'sww' and spatial is False:
228        msg = 'Files of type sww must contain spatial information'       
229        raise msg       
230
231    #Get first timestep
232    try:
233        starttime = fid.starttime[0]
234    except ValueError:
235        msg = 'Could not read starttime from file %s' %filename
236        raise msg
237
238    #Get variables
239    if verbose: print 'Get variables'   
240    time = fid.variables['time'][:]   
241
242    if spatial:
243        #Get origin
244        xllcorner = fid.xllcorner[0]
245        yllcorner = fid.yllcorner[0]
246        zone = fid.zone[0]       
247
248        x = fid.variables['x'][:]
249        y = fid.variables['y'][:]
250        triangles = fid.variables['volumes'][:]
251
252        x = reshape(x, (len(x),1))
253        y = reshape(y, (len(y),1))
254        vertex_coordinates = concatenate((x,y), axis=1) #m x 2 array
255
256        if interpolation_points is not None:
257            #Adjust for georef
258            interpolation_points[:,0] -= xllcorner
259            interpolation_points[:,1] -= yllcorner       
260       
261
262
263
264    if domain is not None:
265        #Update domain.startime if it is *earlier* than starttime
266        if starttime > domain.starttime:
267            msg = 'WARNING: Start time as specified in domain (%f)'\
268                  %domain.starttime
269            msg += ' is earlier than the starttime of file %s (%f).'\
270                     %(filename, starttime)
271            msg += ' Modifying domain starttime accordingly.'
272           
273            if verbose: print msg
274            domain.starttime = starttime #Modifying model time
275            if verbose: print 'Domain starttime is now set to %f'\
276               %domain.starttime
277
278
279        #If domain.startime is *later* than starttime,
280        #move time back - relative to domain's time
281        if domain.starttime > starttime:
282            time = time - domain.starttime + starttime
283
284        #FIXME Use method in geo to reconcile
285        #if spatial:
286        #assert domain.geo_reference.xllcorner == xllcorner
287        #assert domain.geo_reference.yllcorner == yllcorner
288        #assert domain.geo_reference.zone == zone       
289       
290    if verbose:
291        print 'File_function data obtained from: %s' %filename
292        print '  References:'
293        #print '    Datum ....' #FIXME
294        if spatial:
295            print '    Lower left corner: [%f, %f]'\
296                  %(xllcorner, yllcorner)
297        print '    Start time:   %f' %starttime               
298       
299   
300    #Produce values for desired data points at
301    #each timestep
302
303    quantities = {}
304    for i, name in enumerate(quantity_names):
305        quantities[name] = fid.variables[name][:]
306    fid.close()
307   
308
309    #from least_squares import Interpolation_function
310    from fit_interpolate.interpolate import Interpolation_function
311
312    if not spatial:
313        vertex_coordinates = triangles = interpolation_points = None         
314
315
316    return Interpolation_function(time,
317                                  quantities,
318                                  quantity_names,
319                                  vertex_coordinates,
320                                  triangles,
321                                  interpolation_points,
322                                  verbose = verbose)
323
324
325
326
327
328def multiple_replace(text, dictionary):
329    """Multiple replace of words in text
330
331    text:       String to be modified
332    dictionary: Mapping of words that are to be substituted
333
334    Python Cookbook 3.14 page 88 and page 90
335    """
336
337    import re
338   
339    #Create a regular expression from all of the dictionary keys
340    #matching only entire words
341    regex = re.compile(r'\b'+ \
342                       r'\b|\b'.join(map(re.escape, dictionary.keys()))+ \
343                       r'\b' )
344
345    #For each match, lookup the corresponding value in the dictionary
346    return regex.sub(lambda match: dictionary[match.group(0)], text)
347
348
349
350
351def apply_expression_to_dictionary(expression, dictionary):#dictionary):
352    """Apply arbitrary expression to values of dictionary
353
354    Given an expression in terms of the keys, replace key by the
355    corresponding values and evaluate.
356   
357
358    expression: Arbitrary, e.g. arithmetric, expression relating keys
359                from dictionary.
360
361    dictionary: Mapping between symbols in expression and objects that
362                will be evaluated by expression.
363                Values in dictionary must support operators given in
364                expression e.g. by overloading
365
366    due to a limitation with Numeric, this can not evaluate 0/0
367    In general, the user can fix by adding 1e-30 to the numerator.
368    SciPy core can handle this situation.
369    """
370
371    import types
372    import re
373
374    assert isinstance(expression, basestring)
375    assert type(dictionary) == types.DictType
376
377    #Convert dictionary values to textual representations suitable for eval
378    D = {}
379    for key in dictionary:
380        D[key] = 'dictionary["%s"]' %key
381
382    #Perform substitution of variables   
383    expression = multiple_replace(expression, D)
384
385    #Evaluate and return
386    try:
387        return eval(expression)
388    except NameError, e:
389        msg = 'Expression "%s" could not be evaluated: %s' %(expression, e)
390        raise NameError, msg
391    except ValueError, e:
392        msg = 'Expression "%s" could not be evaluated: %s' %(expression, e)
393        raise ValueError, msg
394   
395
396
397
398####################################
399####OBSOLETE STUFF
400
401
402def angle(v1, v2):
403    """Temporary Interface to new location"""
404
405    import utilities.numerical_tools as NT     
406   
407    msg = 'angle has moved from util.py.  '
408    msg += 'Please use "from utilities.numerical_tools import angle"'
409    warn(msg, DeprecationWarning) 
410
411    return NT.angle(v1, v2)
412   
413def anglediff(v0, v1):
414    """Temporary Interface to new location"""
415
416    import utilities.numerical_tools as NT
417   
418    msg = 'anglediff has moved from util.py.  '
419    msg += 'Please use "from utilities.numerical_tools import anglediff"'
420    warn(msg, DeprecationWarning) 
421
422    return NT.anglediff(v0, v1)   
423
424   
425def mean(x):
426    """Temporary Interface to new location"""
427
428    import utilities.numerical_tools as NT   
429   
430    msg = 'mean has moved from util.py.  '
431    msg += 'Please use "from utilities.numerical_tools import mean"'
432    warn(msg, DeprecationWarning) 
433
434    return NT.mean(x)   
435
436def point_on_line(*args, **kwargs):
437    """Temporary Interface to new location"""
438
439    msg = 'point_on_line has moved from util.py.  '
440    msg += 'Please use "from utilities.polygon import point_on_line"'
441    warn(msg, DeprecationWarning) 
442
443    return utilities.polygon.point_on_line(*args, **kwargs)     
444   
445def inside_polygon(*args, **kwargs):
446    """Temporary Interface to new location"""
447
448    print 'inside_polygon has moved from util.py.  ',
449    print 'Please use "from utilities.polygon import inside_polygon"'
450
451    return utilities.polygon.inside_polygon(*args, **kwargs)   
452   
453def outside_polygon(*args, **kwargs):
454    """Temporary Interface to new location"""
455
456    print 'outside_polygon has moved from util.py.  ',
457    print 'Please use "from utilities.polygon import outside_polygon"'
458
459    return utilities.polygon.outside_polygon(*args, **kwargs)   
460
461
462def separate_points_by_polygon(*args, **kwargs):
463    """Temporary Interface to new location"""
464
465    print 'separate_points_by_polygon has moved from util.py.  ',
466    print 'Please use "from utilities.polygon import separate_points_by_polygon"'
467
468    return utilities.polygon.separate_points_by_polygon(*args, **kwargs)   
469
470
471
472def read_polygon(*args, **kwargs):
473    """Temporary Interface to new location"""
474
475    print 'read_polygon has moved from util.py.  ',
476    print 'Please use "from utilities.polygon import read_polygon"'
477
478    return utilities.polygon.read_polygon(*args, **kwargs)   
479
480
481def populate_polygon(*args, **kwargs):
482    """Temporary Interface to new location"""
483
484    print 'populate_polygon has moved from util.py.  ',
485    print 'Please use "from utilities.polygon import populate_polygon"'
486
487    return utilities.polygon.populate_polygon(*args, **kwargs)   
488
489'''
490this simply catches the screen output and files it to a file
491'''
492from os import sep
493
494class Screen_Catcher:
495
496    def __init__(self, filename):
497#        self.data = ''
498        self.filename = filename
499
500    def write(self, stuff):
501        fid = open(self.filename, 'a')
502#        fid = open(self.filename, 'w')
503#        self.data = self.data + stuff
504        fid.write(stuff)
505        fid.close()
506       
507def get_version_info():
508    """gets the version number of the SVN
509    """
510   
511    import os, sys
512
513    # Create dummy info
514    info = 'Revision: Version info could not be obtained.'
515    info += 'A command line version of svn and access to the '
516    info += 'repository is necessary and the output must '
517    info += 'contain a line starting with "Revision:"'
518
519    try:
520        fid = os.popen('svn info')
521    except:
522        msg = 'svn is not recognised'
523        warn(msg, UserWarning)
524    else:   
525        lines = fid.readlines()
526        fid.close()
527        for line in lines:
528            if line.startswith('Revision:'):
529                info = line
530                break
531       
532    return info
533   
534    #if sys.platform == 'win32':
535    #    msg = 'does not work in Windows .... yet'
536    #    raise OSError, msg
537    #else:   
538    #    fid = os.popen('svn -info')
539    #    info = fid.readlines()
540    #    fid.close()
541    #    return info
542   
543   
544def sww2timeseries(swwfiles,
545                   gauge_filename,
546                   #label_id,
547                   production_dirs,
548                   report = None,
549                   plot_quantity = None,
550                   time_min = None,
551                   time_max = None,
552                   title_on = None,
553                   verbose = False):
554   
555    """ Read sww file and plot the time series for the
556    prescribed quantities at defined gauge locations and
557    prescribed time range.
558
559    Input variables:
560
561    swwfiles        - dictionary of sww files with label_ids (used in
562                      generating latex output. It will be part of
563                      the directory name of file_loc (typically the timestamp).
564                      Helps to differentiate latex files for different simulations
565                      for a particular scenario. 
566                    - assume that all conserved quantities have been stored
567                    - assume each sww file has been simulated with same timestep
568                   
569    gauge_filename  - name of file containing gauge data
570                        - name, easting, northing
571                    - OR (this is not yet done)
572                        - structure which can be converted to a Numeric array,
573                          such as a geospatial data object
574                     
575    report          - if True, then write figures to report_figures directory in
576                      relevant production directory
577                    - if False, figures are already stored with sww file
578                    - default to False
579   
580    plot_quantity   - list containing quantities to plot, they must
581                      be the name of an existing quantity or one of
582                      the following possibilities
583                    - possibilities:
584                        - stage; 'stage'
585                        - depth; 'depth'
586                        - speed; calculated as absolute momentum
587                         (pointwise) divided by depth; 'speed'
588                        - bearing; calculated as the angle of the momentum
589                          vector (xmomentum, ymomentum) from the North; 'bearing'
590                        - absolute momentum; calculated as
591                          sqrt(xmomentum^2 + ymomentum^2); 'momentum'
592                        - x momentum; 'xmomentum'
593                        - y momentum; 'ymomentum'
594                    - default will be ['stage', 'speed', 'bearing']
595
596    time_min         - beginning of user defined time range for plotting purposes
597                        - default will be first available time found in swwfile
598                       
599    time_max         - end of user defined time range for plotting purposes
600                        - default will be last available time found in swwfile
601                       
602    title_on        - if True, export standard graphics with title
603                    - if False, export standard graphics without title
604
605
606                     
607    Output:
608   
609    - time series data stored in .csv for later use if required.
610      Name = gauges_timeseries followed by gauge name
611    - latex file will be generated in same directory as where script is
612      run (usually production scenario directory.
613      Name = latexoutputlabel_id.tex
614
615    Other important information:
616   
617    It is assumed that the used has stored all the conserved quantities
618    and elevation during the scenario run, i.e.
619    ['stage', 'elevation', 'xmomentum', 'ymomentum']
620    If this has not occurred then sww2timeseries will not work.
621                     
622    """
623
624   
625    k = _sww2timeseries(swwfiles,
626                        gauge_filename,
627                        #label_id,
628                        production_dirs,
629                        report,
630                        plot_quantity,
631                        time_min,
632                        time_max,
633                        title_on,
634                        verbose)
635
636    return k
637
638def _sww2timeseries(swwfiles,
639                    gauge_filename,
640                    #label_id,
641                    production_dirs,
642                    report = None,
643                    plot_quantity = None,
644                    time_min = None,
645                    time_max = None,
646                    title_on = None,
647                    verbose = False):   
648
649    #assert type(swwfile) == type(''),\
650    #           'The sww filename must be a string'
651
652    #try:
653    #    fid = open(swwfile)
654    #except Exception, e:
655    #    msg = 'File "%s" could not be opened: Error="%s"'\
656    #              %(swwfile, e)
657    #    raise msg
658
659    #index = swwfile.rfind(sep)
660    #file_loc = swwfile[:index+1]
661       
662    assert type(gauge_filename) == type(''),\
663               'Gauge filename must be a string'
664   
665    try:
666        fid = open(gauge_filename)
667    except Exception, e:
668        msg = 'File "%s" could not be opened: Error="%s"'\
669                  %(gauge_filename, e)
670        raise msg
671
672    if report is None:
673        report = False
674       
675    assert type(plot_quantity) == list,\
676               'plot_quantity must be a list'
677   
678    if plot_quantity is None:
679        plot_quantity = ['depth', 'speed', 'bearing']
680    else:
681        check_list(plot_quantity)
682
683    if title_on is None:
684        title_on = True
685     
686    #assert type(label_id) == type(''),\
687    #           'label_id to sww2timeseries must be a string'
688   
689    if verbose: print '\n Gauges obtained from: %s \n' %gauge_filename
690    gauges, locations, elev = get_gauges_from_file(gauge_filename)
691
692    sww_quantity = ['stage', 'elevation', 'xmomentum', 'ymomentum']
693
694    file_loc = []
695    f_list = []
696    label_id = []
697   
698    for swwfile in swwfiles.keys():
699
700        try:
701            fid = open(swwfile)
702        except Exception, e:
703            msg = 'File "%s" could not be opened: Error="%s"'\
704                  %(swwfile, e)
705            raise msg
706
707        f = file_function(swwfile,
708                          quantities = sww_quantity,
709                          interpolation_points = gauges,
710                          verbose = True,
711                          use_cache = True)
712       
713        #if max(f.quantities['xmomentum']) > 1.e10:
714        #    msg = 'Not all conserved quantities available from sww file. \n sww2timeseries requires all conserved quantities stored in sww file'
715        #    raise Exception, msg
716   
717        index = swwfile.rfind(sep)
718        file_loc.append(swwfile[:index+1])
719        label_id.append(swwfiles[swwfile])
720        f_list.append(f)
721       
722    #T.append(f.get_time())
723    T = f.get_time()
724       
725    if time_min is None:
726        time_min = min(T)
727    else:
728        if time_min < min(T):
729            msg = 'Minimum time entered not correct - please try again'
730            raise Exception, msg
731
732    if time_max is None:
733        time_max = max(T)
734    else:
735        if time_max > max(T):
736            msg = 'Maximum time entered not correct - please try again'
737            raise Exception, msg
738
739    if verbose: print 'Inputs OK - going to generate figures'
740
741    return generate_figures(plot_quantity, file_loc, report,
742                            f_list, gauges, locations, production_dirs,
743                            time_min, time_max, title_on, label_id, verbose)
744                         
745
746def get_gauges_from_file(filename):
747    from os import sep, getcwd, access, F_OK, mkdir
748    fid = open(filename)
749    lines = fid.readlines()
750    fid.close()
751   
752    gauges = []
753    gaugelocation = []
754    elev = []
755    line1 = lines[0]
756    line11 = line1.split(',')
757    for i in range(len(line11)):
758        if line11[i].strip('\n').strip(' ') == 'Easting': east_index = i
759        if line11[i].strip('\n').strip(' ') == 'Northing': north_index = i
760        if line11[i].strip('\n').strip(' ') == 'Name': name_index = i
761        if line11[i].strip('\n').strip(' ') == 'Elevation': elev_index = i
762   
763    for line in lines[1:]:
764        fields = line.split(',')
765        gauges.append([float(fields[east_index]), float(fields[north_index])])
766        elev.append(float(fields[elev_index]))
767        loc = fields[name_index]
768        gaugelocation.append(loc.strip('\n'))
769
770    return gauges, gaugelocation, elev
771
772def check_list(quantity):
773
774    all_quantity = ['stage', 'depth', 'momentum', 'xmomentum',
775                    'ymomentum', 'speed', 'bearing', 'elevation']
776
777    p = list(set(quantity).difference(set(all_quantity)))
778    if len(p) <> 0:
779        msg = 'Quantities %s do not exist - please try again' %p
780        raise Exception, msg
781       
782    return 
783
784def calc_bearing(uh, vh):
785
786    from math import atan, degrees
787   
788    angle = degrees(atan(vh/(uh+1.e-15)))
789    if (0 < angle < 90.0):
790        if vh > 0:
791            bearing = 90.0 - abs(angle)
792        if vh < 0:
793            bearing = 270.0 - abs(angle)
794    if (-90 < angle < 0):
795        if vh < 0:
796            bearing = 90.0 - abs(angle)
797        if vh > 0:
798            bearing = 270.0 - abs(angle)
799    if angle == 0: bearing = 0.0
800           
801    return bearing
802
803def generate_figures(plot_quantity, file_loc, report, f_list, gauges,
804                     locations, production_dirs, time_min, time_max,
805                     title_on, label_id, verbose):
806
807    from math import sqrt, atan, degrees
808    from Numeric import ones, allclose, zeros, Float
809    from os import sep, altsep, getcwd, mkdir, access, F_OK, environ
810    from pylab import ion, hold, plot, axis, figure, legend, savefig, \
811         xlabel, ylabel, title, close, subplot
812
813    #filename = file_loc.split(sep)
814
815    if report == True:   
816        texdir = getcwd()+sep+'report'+sep
817        if access(texdir,F_OK) == 0:
818            mkdir (texdir)
819        if len(label_id) == 1:
820            label_id1 = label_id[0].replace(sep,'')
821            label_id2 = label_id1.replace('_','')
822            texfile = texdir+'latexoutput%s' %(label_id2)
823            texfile2 = 'latexoutput%s' %(label_id2)
824            texfilename = texfile + '.tex' 
825            if verbose: print '\n Latex output printed to %s \n' %texfilename
826            fid = open(texfilename, 'w')
827        else:
828            texfile = texdir+'latexoutput' 
829            texfile2 = 'latexoutput'
830            texfilename = texfile + '.tex' 
831            if verbose: print '\n Latex output printed to %s \n' %texfilename
832            fid = open(texfilename, 'w')
833            leg_label = []
834            for label_id in production_dirs.keys():
835                leg_label.append(production_dirs[label_id])
836    else:
837        texfile = ''
838
839    p = len(f_list)
840    n = []
841    n0 = 0
842    for i in range(len(f_list)):
843        n.append(len(f_list[i].get_time()))
844        if n[i] > n0: n0 = n[i] 
845    n0 = int(n0)
846    m = len(locations)
847    model_time = zeros((n0,m,p), Float) 
848    stages = zeros((n0,m,p), Float)
849    elevations = zeros((n0,m,p), Float) 
850    momenta = zeros((n0,m,p), Float)
851    xmom = zeros((n0,m,p), Float)
852    ymom = zeros((n0,m,p), Float)
853    speed = zeros((n0,m,p), Float)
854    bearings = zeros((n0,m,p), Float)
855    depths = zeros((n0,m,p), Float)
856    min_stages = []
857    max_stages = []
858    max_momentums = []
859    max_speeds = []
860    c = 0
861    ##### loop over each swwfile #####
862    for j, f in enumerate(f_list):
863        if verbose: print 'swwfile %d of %d' %(j, len(f_list))
864        ##### loop over each gauge #####
865        for k, g in enumerate(gauges):
866            if verbose: print 'Gauge %d of %d' %(k, len(gauges))
867            min_stage = 10
868            max_stage = 0
869            max_momentum = 0
870            max_speed = 0   
871            gaugeloc = locations[k]
872            thisfile = file_loc[j]+sep+'gauges_time_series'+'_'+gaugeloc+'.csv'
873            fid_out = open(thisfile, 'w')
874            s = 'Time, Stage, Momentum, Speed \n'
875            fid_out.write(s)
876            #### generate quantities #######
877           
878            for i, t in enumerate(f.get_time()):
879                if time_min <= t <= time_max:
880                    w = f(t, point_id = k)[0]
881                    z = f(t, point_id = k)[1]
882                    uh = f(t, point_id = k)[2]
883                    vh = f(t, point_id = k)[3]     
884                    depth = w-z     
885                    m = sqrt(uh*uh + vh*vh)   
886                    if m < 0.001:
887                        vel = 0.0
888                    else:
889                        vel = m / (depth + 1.e-30) 
890                    bearing = calc_bearing(uh, vh)
891                    model_time[i,k,j] = t/60.0         
892                    stages[i,k,j] = w
893                    elevations[i,k,j] = z
894                    xmom[i,k,j] = uh
895                    ymom[i,k,j] = vh
896                    momenta[i,k,j] = m
897                    speed[i,k,j] = vel
898                    bearings[i,k,j] = bearing
899                    depths[i,k,j] = depth
900                    s = '%.2f, %.2f, %.2f, %.2f\n' %(t, w, m, vel)
901                    fid_out.write(s)
902                    if w > max_stage: max_stage = w
903                    if w < min_stage: min_stage = w
904                    if m > max_momentum: max_momentum = m
905                    if vel > max_speed:
906                        last_i = i
907                        last_k = k
908                        max_speed = vel
909
910            max_stages.append(max_stage)
911            min_stages.append(min_stage)
912            max_momentums.append(max_momentum)
913            max_speeds.append(max_speed)       
914           
915            #### finished generating quantities for each swwfile #####
916           
917    #### finished generating quantities for all swwfiles #####
918           
919    stage_axis = axis([time_min/60.0, time_max/60.0, min(min_stages), max(max_stages)*1.1])
920    vel_axis = axis([time_min/60.0, time_max/60.0, min(max_speeds), max(max_speeds)*1.1])
921    mom_axis = axis([time_min/60.0, time_max/60.0, min(max_momentums), max(max_momentums)*1.1])
922
923    cstr = ['g', 'r', 'b', 'c', 'm', 'y', 'k']
924    nn = len(plot_quantity)
925    no_cols = 2
926    if len(label_id) > 1: graphname_report = []
927    for k, g in enumerate(gauges):
928        count1 = 0
929        if report == True and len(label_id) > 1:
930            s = '\\begin{figure}[hbt] \n \\centering \n \\begin{tabular}{cc} \n'
931            fid.write(s)
932        if len(label_id) > 1: graphname_report = []
933        #### generate figures for each gauge ###
934        for j, f in enumerate(f_list):
935            ion()
936            hold(True)
937            count = 0
938            where1 = 0
939            where2 = 0
940            word_quantity = ''
941            if report == True and len(label_id) == 1:
942                s = '\\begin{figure}[hbt] \n \\centering \n \\begin{tabular}{cc} \n'
943                fid.write(s)
944               
945            for which_quantity in plot_quantity:
946                count += 1
947                where1 += 1
948                figure(count, frameon = False)
949                if which_quantity == 'depth':
950                    plot(model_time[0:n[j]-1,k,j], depths[0:n[j]-1,k,j], '-', c = cstr[j])
951                    units = 'm'
952                if which_quantity == 'stage':
953                    plot(model_time[0:n[j]-1,k,j], stages[0:n[j]-1,k,j], '-', c = cstr[j])
954                    axis(stage_axis)
955                    units = 'm'
956                if which_quantity == 'momentum':
957                    plot(model_time[0:n[j]-1,k,j], momenta[0:n[j]-1,k,j], '-', c = cstr[j])
958                    axis(mom_axis)
959                    units = 'm^2 / sec'
960                if which_quantity == 'xmomentum':
961                    plot(model_time[0:n[j]-1,k,j], xmom[0:n[j]-1,k,j], '-', c = cstr[j])
962                    axis(mom_axis)
963                    units = 'm^2 / sec'
964                if which_quantity == 'ymomentum':
965                    plot(model_time[0:n[j]-1,k,j], ymom[0:n[j]-1,k,j], '-', c = cstr[j])
966                    axis(mom_axis)
967                    units = 'm^2 / sec'
968                if which_quantity == 'speed':
969                    plot(model_time[0:n[j]-1,k,j], speed[0:n[j]-1,k,j], '-', c = cstr[j])
970                    axis(vel_axis)
971                    units = 'm / sec'
972                if which_quantity == 'bearing':
973                    due_east = 90.0*ones(shape(model_time[0:n[j]-1,k,j],Float))
974                    due_west = 270.0*ones(shape(model_time[0:n[j]-1,k,j],Float))
975                    plot(model_time[0:n[j]-1,k,j], bearings, '-', 
976                         model_time[0:n[j]-1,k,j], due_west, '-.', 
977                         model_time[0:n[j]-1,k,j], due_east, '-.')
978                    units = 'degrees from North'
979                    ax = axis([time_min, time_max, 0.0, 360.0])
980                    legend(('Bearing','West','East'))
981
982                xlabel('time (mins)')
983                ylabel('%s (%s)' %(which_quantity, units))
984                legend((leg_label),loc='upper right')
985
986                gaugeloc1 = gaugeloc.replace(' ','')
987                #gaugeloc2 = gaugeloc1.replace('_','')
988                gaugeloc2 = locations[k].replace(' ','')
989                graphname = '%sgauge%s_%s' %(file_loc[j], gaugeloc2, which_quantity)
990
991                if report == True and len(label_id) > 1:
992                    figdir = getcwd()+sep+'report_figures'+sep
993                    if access(figdir,F_OK) == 0 :
994                        mkdir (figdir)
995                    latex_file_loc = figdir.replace(sep,altsep) 
996                    # storing files in production directory
997                    graphname_latex = '%sgauge%s%s' %(latex_file_loc, gaugeloc2, which_quantity)     
998                    # giving location in latex output file
999                    graphname_report_input = '%sgauge%s%s' %('..'+altsep+'report_figures'+altsep, gaugeloc2, which_quantity)
1000                    graphname_report.append(graphname_report_input)
1001                   
1002                    savefig(graphname_latex) # save figures in production directory for report generation
1003
1004                if report == True:
1005
1006                    figdir = getcwd()+sep+'report_figures'+sep
1007                    if access(figdir,F_OK) == 0 :
1008                        mkdir (figdir)
1009                    latex_file_loc = figdir.replace(sep,altsep)   
1010
1011                    if len(label_id) == 1: 
1012                        # storing files in production directory
1013                        graphname_latex = '%sgauge%s%s%s' %(latex_file_loc, gaugeloc2, which_quantity, label_id2)     
1014                        # giving location in latex output file
1015                        graphname_report = '%sgauge%s%s%s' %('..'+altsep+'report_figures'+altsep, gaugeloc2, which_quantity, label_id2)
1016                        s = '\includegraphics[width=0.49\linewidth, height=50mm]{%s%s}' %(graphname_report, '.png')
1017                        fid.write(s)
1018                        if where1 % 2 == 0:
1019                            s = '\\\\ \n'
1020                            where1 = 0
1021                        else:
1022                            s = '& \n'
1023                        fid.write(s)                       
1024               
1025                if title_on == True:
1026                    title('%s scenario: %s at %s gauge' %(label_id, which_quantity, gaugeloc))
1027
1028                savefig(graphname) # save figures with sww file
1029
1030            if report == True and len(label_id) == 1:
1031                for i in range(nn-1):
1032                    if nn > 2:
1033                        word_quantity += plot_quantity[i] + ', '
1034                    else:
1035                        word_quantity += plot_quantity[i]
1036                   
1037                word_quantity += ' and ' + plot_quantity[nn-1]               
1038                caption = 'Time series for %s at %s gauge location' %(word_quantity, locations[k]) #gaugeloc.replace('_',' '))
1039                label = '%sgauge%s' %(label_id2, gaugeloc2)
1040                s = '\end{tabular} \n \\caption{%s} \n \label{fig:%s} \n \end{figure} \n \n' %(caption, label)
1041                fid.write(s)
1042                c += 1
1043                if c % 25 == 0: fid.write('\\clearpage \n')
1044                savefig(graphname_latex)               
1045               
1046        if report == True and len(label_id) > 1:
1047            for i in range(nn-1):
1048                if nn > 2:
1049                    word_quantity += plot_quantity[i] + ', '
1050                else:
1051                    word_quantity += plot_quantity[i]
1052                where1 = 0
1053                count1 += 1
1054                index = j*len(plot_quantity)
1055                for which_quantity in plot_quantity:
1056                    where1 += 1
1057                    #index = j*len(plot_quantity)*k
1058                    s = '\includegraphics[width=0.49\linewidth, height=50mm]{%s%s}' %(graphname_report[index], '.png')
1059                    index += 1
1060                    fid.write(s)
1061                    if where1 % 2 == 0:
1062                        s = '\\\\ \n'
1063                        where1 = 0
1064                    else:
1065                        s = '& \n'
1066                    fid.write(s)
1067            word_quantity += ' and ' + plot_quantity[nn-1]           
1068            label = 'gauge%s' %(gaugeloc2) 
1069            caption = 'Time series for %s at %s gauge location' %(word_quantity, locations[k]) #gaugeloc.replace('_',' '))
1070           
1071            #s = '\\caption{%s} \n \label{fig:%s} \n \end{figure} \n \n' %(caption, label)
1072            s = '\end{tabular} \n \\caption{%s} \n \label{fig:%s} \n \end{figure} \n \n' %(caption, label)
1073            fid.write(s)
1074            c += 1
1075            if c % 25 == 0: fid.write('\\clearpage \n')
1076               
1077           
1078            #### finished generating figures ###
1079
1080        close('all')
1081   
1082    return texfile2
Note: See TracBrowser for help on using the repository browser.