source: trunk/UTIL/PYTHON/planetoplot_v2/ppcompute.py @ 916

Last change on this file since 916 was 910, checked in by aslmd, 12 years ago

PLANETOPLOT v2


  1. Spiga LMD/UPMC 24/03/2013

Contents


core


  • ppclass.py --> main class with pp() objects (need ppplot and ppcompute)
  • ppplot.py --> plot class (can be used independently, need ppcompute)
  • ppcompute.py --> computation class (can be used independently)

scripts


  • pp.py --> command line utility to use ppclass
  • pp_reload.py --> command line utility to load saved plot objects *.ppobj
  • example/* --> example scripts using ppclass

settings files


  • set_area.txt --> setting file: predefined areas for plotting (can be omitted)
  • set_back.txt --> setting file: predefined backgrounds for plotting (can be omitted)
  • set_multiplot.txt --> setting file: predefined coefficients for multiplots (can be omitted)
  • set_ppclass.txt --> setting file: predefined variables for x,y,z,t (can be omitted)
  • set_var.txt --> setting file: predefined colorbars, format, labels, etc... for variables (can be omitted)

documentation


  • README.TXT --> this README file

data


  • demo_data/* --> plot objects for a demonstration tour and customizing tests

Requirements


python + numpy + matplotlib + netCDF4

  • for mapping --> Basemap
  • for scientific computations --> scipy

[recommended: Enthought Python Distribution (free for academics)]

Installation


  • install required softwares and librairies in requirements
  • add planetoplot_v2 in your PYTHONPATH environment variable (and in your PATH to use pp.py)

Take a demo tour


pp_reload.py demo_data/*

Improvements compared to v1


  • code readability and structuration for future improvements
  • modularity (class formulation) + easy definition/addition of attributes
  • separation between data retrieval and plotting
  • versatility + command line (pp.py)

--> for quick inspection

+ interactive session (ipython)

--> for testing and exploring

+ scripts

--> for powerful and fully customized results

  • performance (overall and on large files) + memory consumption (only retrieve what is needed)
  • saving/loading plot objects in/from *.ppobj
  • plot aesthetics and customizing (see header in ppplot)
  • multiplot flexibility with .plotin attribute
  • easy definition of presets with set_*.txt files
  • function: one field vs. another one
  • emulation of + - / * operations on fields (between two fields or between a field and a int/float)
  • computations of min/max in addition to mean
  • simple inspection of dimensions+variables in a file (pp.py -f file)
  • verbose / non verbose mode

Acknowledgements


Thanks to A. Colaitis, T. Navarro, J. Leconte
for feedbacks and contributions on version 1

File size: 6.6 KB
Line 
1###############################################
2## PLANETOPLOT                               ##
3## --> PPCOMPUTE                             ##
4###############################################
5# python built-in librairies
6import os
7# added librairies
8import numpy as np
9import scipy.signal as sp_signal
10###############################################
11
12## first a useful function to find settings in a folder in PYTHONPATH
13def findset(whereset,string="planetoplot_v2"):
14    # ... set a default whereset if it was set to None
15    # ... default is in the planetoplot_v2 folder
16    if whereset is None:
17        for path in os.environ['PYTHONPATH'].split(os.pathsep):
18            if string in path: whereset = path
19        if whereset is None: 
20            print "!! ERROR !! "+ string + "not in $PYTHONPATH"
21            print "--> either put it in $PYTHONPATH or change whereset"
22            exit()
23    # ... if the last / is missing put it
24    if whereset[-1] != "/": whereset = whereset + "/"
25    return whereset
26
27##########################
28#### MAX MEAN MIN SUM ####
29#####################################
30#### WITH SUPPORT FOR NaN VALUES ####
31#####################################
32
33## compute min
34## author AS + AC
35def min (field,axis=None): 
36        if field is None: return None
37        if type(field).__name__=='MaskedArray':
38              field.set_fill_value(np.NaN)
39              return np.ma.array(field).min(axis=axis)
40        elif (np.isnan(np.sum(field)) and (type(field).__name__ not in 'MaskedArray')):
41              return np.ma.masked_invalid(field).min(axis=axis)
42        else: return np.array(field).min(axis=axis)
43
44## compute max
45## author AS + AC
46def max (field,axis=None):
47        if field is None: return None
48        if type(field).__name__=='MaskedArray':
49              field.set_fill_value(np.NaN)
50              return np.ma.array(field).max(axis=axis)
51        elif (np.isnan(np.sum(field)) and (type(field).__name__ not in 'MaskedArray')):
52              return np.ma.masked_invalid(field).max(axis=axis) 
53        else: return np.array(field).max(axis=axis)
54
55## compute mean
56## author AS + AC
57def mean (field,axis=None):
58        if field is None: return None
59        else: 
60           if type(field).__name__=='MaskedArray':
61              field.set_fill_value(np.NaN)
62              zout=np.ma.array(field).mean(axis=axis)
63              if axis is not None:
64                 zout.set_fill_value(np.NaN)
65                 return zout.filled()
66              else:return zout
67           elif (np.isnan(np.sum(field)) and (type(field).__name__ not in 'MaskedArray')):
68              zout=np.ma.masked_invalid(field).mean(axis=axis)
69              if axis is not None:
70                 zout.set_fill_value([np.NaN])
71                 return zout.filled()
72              else:return zout
73           else: 
74              return np.array(field).mean(axis=axis)
75
76## compute sum
77## author AS + AC
78def sum (field,axis=None):
79        if field is None: return None
80        else:
81           if type(field).__name__=='MaskedArray':
82              field.set_fill_value(np.NaN)
83              zout=np.ma.array(field).sum(axis=axis)
84              if axis is not None:
85                 zout.set_fill_value(np.NaN)
86                 return zout.filled()
87              else:return zout
88           elif (np.isnan(np.sum(field)) and (type(field).__name__ not in 'MaskedArray')):
89              zout=np.ma.masked_invalid(field).sum(axis=axis)
90              if axis is not None:
91                 zout.set_fill_value([np.NaN])
92                 return zout.filled()
93              else:return zout
94           else:
95              return np.array(field).sum(axis=axis)
96
97################
98#### SMOOTH ####
99################
100### TBD: works with missing values
101
102## Author: AS. uses gauss_kern and blur_image.
103def smooth2d(field, window=10):
104        ## actually blur_image could work with different coeff on x and y
105        if True in np.isnan(field):
106            print "!! ERROR !! Smooth is a disaster with missing values. This will be fixed."
107            exit()
108        if window > 1:  result = blur_image(field,int(window))
109        else:           result = field
110        return result
111
112## FROM COOKBOOK http://www.scipy.org/Cookbook/SignalSmooth
113def gauss_kern(size, sizey=None):
114        # Returns a normalized 2D gauss kernel array for convolutions
115        size = int(size)
116        if not sizey:
117                sizey = size
118        else:
119                sizey = int(sizey)
120        x, y = np.mgrid[-size:size+1, -sizey:sizey+1]
121        g = np.exp(-(x**2/float(size)+y**2/float(sizey)))
122        return g / g.sum()
123
124## FROM COOKBOOK http://www.scipy.org/Cookbook/SignalSmooth
125def blur_image(im, n, ny=None) :
126        # blurs the image by convolving with a gaussian kernel of typical size n.
127        # The optional keyword argument ny allows for a different size in the y direction.
128        g = gauss_kern(n, sizey=ny)
129        improc = sp_signal.convolve(im, g, mode='same')
130        return improc
131
132## FROM COOKBOOK http://www.scipy.org/Cookbook/SignalSmooth
133def smooth1d(x,window=11,window_type='hanning'):
134    """smooth the data using a window with requested size.
135    This method is based on the convolution of a scaled window with the signal.
136    The signal is prepared by introducing reflected copies of the signal
137    (with the window size) in both ends so that transient parts are minimized
138    in the begining and end part of the output signal.
139    input:
140        x: the input signal
141        window: the dimension of the smoothing window; should be an odd integer
142        window_type: the type of window from 'flat', 'hanning', 'hamming', 'bartlett', 'blackman'
143            flat window will produce a moving average smoothing.
144    output:
145        the smoothed signal
146    example:
147    t=linspace(-2,2,0.1)
148    x=sin(t)+randn(len(t))*0.1
149    y=smooth(x)
150    see also:
151    numpy.hanning, numpy.hamming, numpy.bartlett, numpy.blackman, numpy.convolve
152    scipy.signal.lfilter
153    TODO: the window parameter could be the window itself if an array instead of a string   
154    """
155    if True in np.isnan(field):
156        print "!! ERROR !! Smooth is a disaster with missing values. This will be fixed."
157        exit()   
158    x = np.array(x)
159    if x.ndim != 1:
160        raise ValueError, "smooth only accepts 1 dimension arrays."
161    if x.size < window:
162        raise ValueError, "Input vector needs to be bigger than window size."
163    if window<3:
164        return x
165    if not window_type in ['flat', 'hanning', 'hamming', 'bartlett', 'blackman']:
166        raise ValueError, "Window is on of 'flat', 'hanning', 'hamming', 'bartlett', 'blackman'"
167    s=np.r_[x[window-1:0:-1],x,x[-1:-window:-1]]
168    #print(len(s))
169    if window == 'flat': #moving average
170        w=np.ones(window,'d')
171    else:
172        w=eval('np.'+window_type+'(window)')
173    y=np.convolve(w/w.sum(),s,mode='valid')
174    return y
Note: See TracBrowser for help on using the repository browser.