source: inundation/pyvolution/util.py @ 3262

Last change on this file since 3262 was 3262, checked in by duncan, 18 years ago

using/expanding ensure_absolute

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