Commit 0b3176001c676d5bbc46c2abac6fdb273d586098

Authored by Vernisse Yoann
1 parent fec5faec
Exists in master

added several modules

modified nan manipulation in data : changed -1**31 to np.nan objects
added writing cef functions
__init__.py
... ... @@ -16,6 +16,7 @@ from clExport import clExport
16 16 from ihm import HoverInfo
17 17  
18 18 from display_lib import display1d
  19 +from display_lib import display2d
19 20 from display_lib import display3d
20 21 from display_lib import display_colormaps
21 22  
... ...
ceflib_mods.py
1 1 #! /bin/env python
2 2 # coding: utf8
  3 +import numpy as np
  4 +import datetime
3 5  
4 6 class cefwrite(object) :
5 7  
6   - def __init__(self, data = None, filename = 'test.cef'):
  8 + def __init__(self, data = None, filename = 'test.cef', mode = 'w', checkVariableOrder = False):
7 9 """
8   - Data of the form data['field1'] = numpy array, and data['epoch'] = numpy time array
  10 + Write data into a cef file format
  11 + data must be of the form data['field1'] = numpy array, and data['epoch'] = numpy time array
  12 + provide filename (default is test.cef)
  13 + mode : 'w' start from fresh empty file
  14 + 'a' start from existing file and add only lines (variables must have same names)
  15 + default is 'w'
9 16 """
10   - self.data = data
  17 + self.data = {key:np.copy(data[key]) for key in data}
  18 +
11 19 self.fichier = filename
  20 + self.mode = mode
  21 +
  22 + self.variables = sorted(list(set(self.data.keys()) - set(['epoch'])))
  23 +
  24 + self.deleteAllNan()
  25 + self.changeNanToFillVal()
12 26  
  27 + if checkVariableOrder : print self.variables
  28 +
  29 + if mode == 'w':
  30 + self.makeHeader()
  31 + self.writeData()
  32 + elif mode == 'a':
  33 + self.writeData()
  34 +
  35 + def changeNanToFillVal(self):
  36 + """
  37 + For CL : change NAN to -10E31
  38 + seems to work fine :)
  39 + """
  40 + for key in self.variables : self.data[key][np.isnan(self.data[key])] = -10**31
  41 +
  42 + def deleteAnyNan(self):
  43 + """
  44 + Delete all lines containing at least one np.nan
  45 + """
  46 + for var in self.variables :
  47 + inds = np.where(np.isnan(self.data[var]))
  48 + for key in self.data :
  49 + self.data[key] = np.delete(self.data[key], inds)
  50 +
  51 + def deleteAllNan(self):
  52 + """
  53 + Delete all lines where all data exept time are np.nan
  54 + """
  55 + inds0 = set(np.where(np.isnan(self.data[self.variables[0]]))[0])
  56 + for var in self.variables[1:] :
  57 + inds1 = set(np.where(np.isnan(self.data[var]))[0]).intersection(inds0)
  58 + inds0 = inds1
  59 +
  60 + for key in self.data :
  61 + self.data[key] = np.delete(self.data[key], list(inds1))
  62 +
  63 + def makeHeader(self):
13 64 self.initializeHeader()
14   - variables = sorted(list(set(self.data.keys()) - set(['epoch'])))
15   - for var in variables : self.addvariableHeader(var)
  65 + for var in self.variables : self.addvariableHeader(var)
16 66 self.closeHeader()
17   -
  67 +
  68 + def writeData(self):
18 69 out = open(self.fichier, 'a')
19 70 for i,t in enumerate(self.data['epoch']):
20   -
21   - out.write(t.isoformat())
22   - #print >> out, t.isoformat()
23   - for var in variables :
24   - out.write(' ')
25   - #print >> out, str(self.data[key][i])
  71 + out.write(t.isoformat()+'Z')
  72 + for var in self.variables :
  73 + out.write(', ')
26 74 out.write('{:f}'.format(self.data[var][i]))
27   - out.write('\n')
28   -
  75 + out.write(';\n')
29 76 out.close()
30 77  
31 78 def initializeHeader(self):
32   -
33 79 #set time variable as first variable
34 80 out = open(self.fichier, 'w')
35 81 out.write(
  82 + "!------------------------------------------------------------------------|\n"
  83 + "! |\n"
  84 + "! Generated by the mms_tools_lib, developped by Yoann Vernisse, IRAP |\n"
  85 + "! ASCII Format |\n"
  86 + "!------------------------------------------------------------------------|\n"
  87 + "\n"
  88 + 'FILE_FORMAT_VERSION = "CEF-2.0"\n'
  89 + "\n"
  90 + "\n"
  91 + "!------------------------------------------------------------------------|\n"
  92 + "! Global Metadata |\n"
  93 + "!------------------------------------------------------------------------|\n"
  94 + "\n"
  95 + "START_META = Generation_date\n"
  96 + " VALUE_TYPE = ISO_TIME\n"
  97 + " ENTRY = "+ datetime.datetime.now().isoformat() +"\n"
  98 + "END_META = Generation_date\n"
  99 + "\n"
  100 + "START_META = Generated_by\n"
  101 + ' ENTRY = "mms_tools_lib"\n'
  102 + "END_META = Generated_by\n"
  103 + "\n"
  104 + "START_META = Mission_Group\n"
  105 + ' ENTRY = "MMS"\n'
  106 + "END_META = Mission_Group\n"
  107 + "\n"
  108 + 'END_OF_RECORD_MARKER = ";"\n'
  109 + "\n"
  110 + "!------------------------------------------------------------------------|\n"
  111 + "! Variables |\n"
  112 + "!------------------------------------------------------------------------|\n"
  113 + "\n"
36 114 'START_VARIABLE = epoch \n'
37   - ' PARAMETER_TYPE = "Support_Data" \n'
38   - ' VALUE_TYPE = ISO_TIME \n'
39   - ' UNITS = "s" \n'
40   - ' DELTA_PLUS = 0 \n'
41   - ' DELTA_MINUS = 0 \n'
42   - 'END_VARIABLE = epoch \n'
43   - ' \n'
  115 + ' PARAMETER_TYPE = "Support_Data"\n'
  116 + ' VALUE_TYPE = ISO_TIME\n'
  117 + ' UNITS = "s"\n'
  118 + ' DELTA_PLUS = 0\n'
  119 + ' DELTA_MINUS = 0\n'
  120 + 'END_VARIABLE = epoch\n'
  121 + '\n'
44 122 )
45 123  
46 124 def addvariableHeader(self, variable):
47 125  
48 126 out = open(self.fichier, 'a')
49 127 out.write(
50   - 'START_VARIABLE = '+variable +'\n'
51   - ' PARAMETER_TYPE = "Data" \n'
52   - ' VALUE_TYPE = FLOAT \n'
53   - ' FILLVAL = -1.000E+31 \n'
54   - ' DEPEND_0 = epoch \n'
55   - ' UNITS = "" \n'
56   - ' FIELDNAM = "" \n'
  128 + 'START_VARIABLE = '+variable +'\n'
  129 + ' PARAMETER_TYPE = "Data"\n'
  130 + ' VALUE_TYPE = FLOAT\n'
  131 + ' FILLVAL = -1.000E+31\n'
  132 + ' DEPEND_0 = epoch\n'
  133 + ' UNITS = ""\n'
  134 + ' FIELDNAM = ""\n'
57 135 'END_VARIABLE = '+variable+ '\n'
58   - ' \n'
  136 + '\n'
59 137 )
60 138  
61 139 def closeHeader(self):
62 140  
63 141 out = open(self.fichier, 'a')
64 142 out.write(
65   - 'DATA_UNTIL = EOF \n'
66   - )
  143 + "!------------------------------------------------------------------------|\n"
  144 + "! Data |\n"
  145 + "!------------------------------------------------------------------------|\n"
  146 + '\n'
  147 + 'DATA_UNTIL = EOF\n'
  148 + )
67 149  
68 150 \ No newline at end of file
... ...
display_lib.py
... ... @@ -4,8 +4,41 @@
4 4 import numpy as np
5 5 import matplotlib.pyplot as plt
6 6 from mpl_toolkits.mplot3d import Axes3D
  7 +import os
7 8  
8   -class display1d(object):
  9 +
  10 +class display_general(object):
  11 + """
  12 + Object with general functions for plotting objects
  13 + namely : save figure, show; others?
  14 + """
  15 +
  16 + def __init__(self):
  17 +
  18 + self.setTitle('Figure_from_displaylib')
  19 +
  20 + def setTitle(self, title) :
  21 + self.title = title
  22 +
  23 + def getTitle(self) :
  24 + return self.title
  25 +
  26 + def savefig(self, f = None) :
  27 + if not f :
  28 + i = 0
  29 + while i < 999 :
  30 + f = self.title + str(int(i)) + '.png'
  31 + if os.path.exists(os.path.join(os.curdir, f)) : i+=1
  32 + else : break
  33 + print 'Saving figure in ', f
  34 + self.fig.savefig(f, bbox_inches='tight')
  35 + plt.close()
  36 +
  37 + def show(self):
  38 + plt.show()
  39 +
  40 +
  41 +class display1d(display_general):
9 42 """
10 43 Functions to easily add options to 1d objects plots
11 44 initialize as display1d(3,2) for 3 columns and 2 rows
... ... @@ -15,8 +48,9 @@ class display1d(object):
15 48 add colorscale to a scatter plot
16 49 NOTE : Not made for timeseries!!
17 50 """
18   - def __init__(self, ncols = 1, nrows = 1) :
  51 + def __init__(self, ncols = 1, nrows = 1, title = 'display1d') :
19 52  
  53 + self.setTitle(title)
20 54 self.fig = plt.figure(figsize = (16, 10), dpi = 96)
21 55 self.ncols = int(ncols)
22 56 self.nrows = int(nrows)
... ... @@ -27,7 +61,7 @@ class display1d(object):
27 61 for i in range(nrows*ncols-1) :
28 62 self.plots.append({})
29 63 self.plots[-1]['label'] = {'data' : None, 'xaxis' : None, 'yaxis' : None, 'cbar' : None, 'title' : None}
30   -
  64 +
31 65 #self.set_colorscale()
32 66 #self.set_errorbar(x = np.arange(len(self.y))/5.)
33 67 #self.set_logscale()
... ... @@ -84,7 +118,9 @@ class display1d(object):
84 118 def set_colorscale(self, col_arr = [0], minmax = 'auto', cmap = 'plasma') :
85 119 i = self.get_actualPlotNumber()
86 120 self.plots[i]['col_arr'] = np.array(col_arr)
87   - if self.plots[i]['col_arr'].shape != self.plots[i]['data'].shape : self.plots[i]['col_arr'] = self.plots[i]['data']
  121 + if len(self.plots[i]['col_arr']) != len(self.plots[i]['data']) :
  122 + print 'WRONG COLOR ARRAY SIZE, SETTING DATA IN COLOR INSTEAD'
  123 + self.plots[i]['col_arr'] = self.plots[i]['data']
88 124  
89 125 #self.new_val = (self.col_arr - self.col_arr.min())/(self.col_arr.max() - self.col_arr.min())
90 126 #self.carray = plt.get_cmap(cmap)(self.new_val)
... ... @@ -126,7 +162,100 @@ class display1d(object):
126 162  
127 163  
128 164  
129   -class display3d(object) :
  165 +class display2d(display_general):
  166 + """
  167 + Grid used to make 2D plots.
  168 + This create ONLY linear grid plot. For non linear 2D plot, another routine should be made.
  169 + input : 2D numpy array
  170 + NOTE : meshgrid can be tricky regarding x/y indexing : check option indexing = 'ij' or 'xy'
  171 + """
  172 + def __init__(self, z = None, title = '', Zinit = True):
  173 + #np.ndarray.__init__(self)
  174 +
  175 + self.x = {}
  176 + self.y = {}
  177 + self.z = {}
  178 + self.minmax = {}
  179 + self.title = title
  180 + self.layers = {}
  181 +
  182 + if z is None : z = np.zeros([10,10])
  183 +
  184 + xsize = float(z.shape[0])
  185 + ysize = float(z.shape[1])
  186 +
  187 + self.initialize(xsize, ysize)
  188 + self.meshinit()
  189 + self.zmesh, tmp = np.meshgrid(np.zeros(z.shape[0]), np.zeros(z.shape[1]))
  190 + self.zmesh = self.zmesh[:-1, :-1]
  191 + if Zinit : self.zmesh = z.T[:-1, :-1]
  192 +
  193 + def initialize(self, xsize, ysize) :
  194 + self.minmax['xmin'] = 0.
  195 + self.minmax['xmax'] = xsize
  196 + self.x['res'] = xsize
  197 +
  198 + self.minmax['ymin'] = 0.
  199 + self.minmax['ymax'] = ysize
  200 + self.y['res'] = ysize
  201 +
  202 + def set_layers(self, layers = ['Name']):
  203 + for layer in layers : self.layers[layer] = np.zeros(self.zmesh.shape)
  204 +
  205 + def meshinit(self) :
  206 + self.x['points'] = np.linspace(self.minmax['xmin'], self.minmax['xmax'], num = self.x['res'], dtype = 'double', endpoint = True)
  207 + self.y['points'] = np.linspace(self.minmax['ymin'], self.minmax['ymax'], num = self.y['res'], dtype = 'double', endpoint = True)
  208 + self.xmesh, self.ymesh = np.meshgrid(self.x['points'], self.y['points'])
  209 +
  210 + def set_minmax(self, cle, val) : #cle = xmax, xmin, ymax, ymin, zmin, zmax
  211 + self.minmax[cle] = float(val)
  212 + self.meshinit()
  213 +
  214 + def set_layers_val(self, x, y, layers_val = {'Name' : 0}):
  215 + xind = self.postoindicex(x)
  216 + yind = self.postoindicey(y)
  217 + if xind is not None and yind is not None :
  218 + for layer in self.layers : self.layers[layer][yind, xind] = layers_val[layer]
  219 +
  220 + def set_val(self, x, y, val): #x et y en position, PAS EN INDICE!!
  221 + xind = self.postoindicex(x)
  222 + yind = self.postoindicey(y)
  223 + if xind is not None and yind is not None : self.zmesh[yind, xind] = val
  224 +
  225 + def postoindicex(self, x):
  226 + if self.minmax['xmin'] < x < self.minmax['xmax'] : return (abs(self.x['points'] - x)).argmin()
  227 + #else : print 'X OUT OF BOUNDS', x, self.x['min'], self.x['max']
  228 + def postoindicey(self, x):
  229 + if self.minmax['ymin'] < x < self.minmax['ymax'] : return (abs(self.y['points'] - x)).argmin()
  230 + #else : print 'Y OUT OF BOUNDS', x, self.y['min'], self.y['max']
  231 +
  232 + def add_plot(self, x, y) :
  233 + plt.plot(x, y, 'H', color = 'white')
  234 +
  235 + def plot(self, layer = None, autominmax = True, cmap = 'seismic') :
  236 + if layer : z = self.layers[layer]
  237 + else : z = self.zmesh
  238 +
  239 + if autominmax or 'zmin' not in self.minmax or 'zmax' not in self.minmax:
  240 + vmin = z.min()
  241 + vmax = z.max()
  242 + else :
  243 + vmin = self.minmax['zmin']
  244 + vmax = self.minmax['zmax']
  245 +
  246 + self.fig = plt.figure()
  247 + plt.pcolormesh(self.xmesh, self.ymesh, z, vmin = vmin, vmax = vmax, cmap = cmap)
  248 + plt.title(self.title)
  249 + plt.colorbar()
  250 +
  251 + def xlineplot(self, x) :
  252 + simumods.lineplot(self.zmesh[self.postoindicex(x), :], x = self.xmesh[self.postoindicex(0), :])
  253 + def ylineplot(self, x) :
  254 + simumods.lineplot(self.zmesh[:, self.postoindicey(x)], x = self.ymesh[:, self.postoindicey(0)])
  255 +
  256 +
  257 +
  258 +class display3d(display_general) :
130 259 """
131 260 3D plotting object
132 261 works fine! init 3D coordinates as numpy arrays (x,y,z)
... ... @@ -135,14 +264,16 @@ class display3d(object) :
135 264 Thus this object impose an invisible cube at first
136 265 use set_autoscatter for a default scatter plot of x,y,z (NOT generated by default, must be called!!)
137 266 """
138   - def __init__(self, x, y, z) :
  267 + def __init__(self, x, y, z, title = 'display3d') :
139 268  
140 269 self.x = x
141 270 self.y = y
142 271 self.z = z
143 272 self.planet = False
  273 + self.trisurf = False
144 274 self._initialize()
145 275 self.plots = {}
  276 + self.setTitle(title)
146 277  
147 278 def _initialize(self):
148 279  
... ... @@ -152,10 +283,22 @@ class display3d(object) :
152 283  
153 284 ### Create a cube to force aspect ratio 1:1
154 285 self.ax.set_aspect('equal')
155   - MAX = max(np.concatenate([abs(self.x),abs(self.y),abs(self.z)]))
  286 + self._max = max(np.concatenate([abs(self.x),abs(self.y),abs(self.z)]))
156 287 for direction in (-1, 1):
157   - for point in np.diag(direction * MAX * np.array([1,1,1])):
  288 + for point in np.diag(direction * self._max * np.array([1,1,1])):
158 289 self.ax.plot([point[0]], [point[1]], [point[2]], 'w')
  290 +
  291 + self.set_xyzlabels()
  292 +
  293 + def set_xyzlabels(self, x = None, y = None, z = None):
  294 +
  295 + if x is None : x = 'X-axis'
  296 + if y is None : y = 'Y-axis'
  297 + if z is None : z = 'Z-axis'
  298 +
  299 + self.ax.set_xlabel(x)
  300 + self.ax.set_ylabel(y)
  301 + self.ax.set_zlabel(z)
159 302  
160 303 def forceEqualRatio(self):
161 304  
... ... @@ -164,12 +307,11 @@ class display3d(object) :
164 307 for key in self.plots : mlist.append(abs(np.concatenate(self.plots[key]['data'])).max())
165 308 mlist.append(abs(np.concatenate([self.x,self.y,self.z])).max())
166 309 #add any other data to the list
167   - MAX = max(mlist)
  310 + self._max = max(mlist)
168 311 for direction in (-1, 1):
169   - for point in np.diag(direction * MAX * np.array([1,1,1])):
  312 + for point in np.diag(direction * self._max * np.array([1,1,1])):
170 313 self.ax.plot([point[0]], [point[1]], [point[2]], 'w')
171 314  
172   -
173 315 def redraw(self):
174 316 self._initialize()
175 317 if self.trisurf : self.set_trisurf(tripos = self.trisurf['tripos'], trival = self.trisurf['trival'], minmax = self.trisurf['minmax'])
... ... @@ -201,10 +343,16 @@ class display3d(object) :
201 343 def set_scatter(self, scatter, c = None) :
202 344 self.scatter = self.ax.scatter(scatter[:,0], scatter[:,1], scatter[:,2], c = c, cmap = 'seismic')
203 345  
204   - def set_autoscatter(self, c = None, vmin = None, vmax = None):
205   - self.autoscatter = self.ax.scatter(self.x, self.y, self.z, vmin = vmin, vmax = vmax, c = c, cmap = 'seismic')
206   - cbar = self.fig.colorbar(self.autoscatter)
207   -
  346 + def set_autoscatter(self, c = None, vmin = None, vmax = None, **kw):
  347 + self.autoscatter = self.ax.scatter(self.x, self.y, self.z, vmin = vmin, vmax = vmax, c = c, cmap = 'seismic', **kw)
  348 + if c is not None : cbar = self.fig.colorbar(self.autoscatter)
  349 +
  350 +
  351 + def set_centralAxis(self, linewidth = .5):
  352 + self.ax.plot([-self._max, self._max], [0,0], [0,0], '-k', linewidth = linewidth)
  353 + self.ax.plot([0,0], [-self._max, self._max], [0,0], '-k', linewidth = linewidth)
  354 + self.ax.plot([0,0], [0,0], [-self._max, self._max], '-k', linewidth = linewidth)
  355 +
208 356 def set_planet(self) :
209 357 self.planet = True
210 358 u, v = np.mgrid[0:2*np.pi:20j, 0:np.pi:10j]
... ... @@ -223,10 +371,6 @@ class display3d(object) :
223 371 if save : self.plots[len(self.plots)] = {'data' : plot, 'color' : color}
224 372 self.ax.plot(plot[:,0], plot[:,1], plot[:,2], linewidth = 3., color = color)
225 373  
226   - def show(self) :
227   - plt.show()
228   -
229   -
230 374  
231 375  
232 376  
... ...
mva.py
... ... @@ -23,7 +23,7 @@ class mva(object):
23 23 self.results = {}
24 24 self.calc(noprint = noprint)
25 25 #self.noprint = noprint
26   - if field2 != None :
  26 + if field2 is not None :
27 27 self.field_cross = field2 # en entrรฉ : deux vecteurs de 3 composantes dรฉjร  moyennรฉ
28 28 self.calc_cross(noprint = noprint)
29 29  
... ...
read_data.py
... ... @@ -7,6 +7,7 @@ from datetime import timedelta
7 7 import numpy as np
8 8 import os
9 9 import matplotlib.pyplot as plt
  10 +import pickle
10 11  
11 12 class donnee(object) :
12 13  
... ... @@ -14,9 +15,15 @@ class donnee(object) :
14 15 """
15 16 Donnee object : open data from cef file
16 17 This object is useful to manage timeseries with implemented calculation on timedeltas
17   - get metadata from ceffile and store it in self._metadata
18   - to load data use self._get_data() (THIS MUST BE IMPROVED)
  18 +
19 19 all data are stored in self.donnee
  20 + REMAINING TO DO : Harmonize all methods conventional name (use either _ of capital)
  21 + Rename self.donnee into self.data
  22 + Rename the class into a more appropriate international word
  23 + Add Nan & Fillvall treatment to all methods
  24 + Add a write to cef file method
  25 + Add a get_as_tensor method (similar to get_as_field)
  26 + Vectorize all methods
20 27 """
21 28 ceflib.verbosity(0)
22 29 self._fichier = fichier
... ... @@ -28,11 +35,14 @@ class donnee(object) :
28 35 ceflib.close()
29 36  
30 37 self.donnee = {}
  38 + self.varattributes = {}
31 39 self._get_time()
32   -
  40 +
33 41 def _get_time(self) :
34 42 ceflib.read(self._fichier)
35 43 self.donnee['epoch'] = np.copy(np.array([datetime.utcfromtimestamp(ceflib.milli_to_timestamp(i)) for i in ceflib.var('epoch')]))
  44 + self.varattributes['epoch'] = {}
  45 + for attribute in ceflib.vattributes('epoch') : self.varattributes['epoch'][attribute] = ceflib.vattr('epoch', attribute)
36 46 ceflib.close()
37 47  
38 48 def get_time(self) :
... ... @@ -42,14 +52,29 @@ class donnee(object) :
42 52 def get_varnames(self) :
43 53 return self._varnames
44 54  
45   - def _get_data(self, var = 'all') :
46   - #self.donnee = {}
47   - ceflib.read(self._fichier)
48   - if var == 'all' :
49   - for nom in self._varnames:
50   - if nom not in ['epoch', 'K001', 'K002'] : self.donnee[nom] = np.copy(ceflib.var(nom))
51   - else : self.donnee[var] = np.copy(ceflib.var(var))
52   - ceflib.close()
  55 + #def _get_data(self, var = 'all') :
  56 + ##self.donnee = {}
  57 + #ceflib.read(self._fichier)
  58 + #if var == 'all' :
  59 + #for nom in self._varnames:
  60 + #if nom not in ['epoch', 'K001', 'K002'] : self.donnee[nom] = np.copy(ceflib.var(nom))
  61 + #else : self.donnee[var] = np.copy(ceflib.var(var))
  62 + #ceflib.close()
  63 +
  64 + def _modify_fillval_to_nan(self, var):
  65 + self.donnee[var][self.donnee[var] == float(self.varattributes[var]['FILLVAL'])] = np.nan
  66 + return self.donnee[var]
  67 +
  68 + def _load_var(self, var) :
  69 + if var not in self.donnee :
  70 + if var in self._varnames :
  71 + ceflib.read(self._fichier)
  72 + self.donnee[var] = np.copy(ceflib.var(var))
  73 + self.varattributes[var] = {}
  74 + for attribute in ceflib.vattributes(var) : self.varattributes[var][attribute] = ceflib.vattr(var, attribute)
  75 + ceflib.close()
  76 + if 'FILLVAL' in self.varattributes[var] : self._modify_fillval_to_nan(var)
  77 + else : print "!!!Input Variable Not Found!!!"
53 78  
54 79 def get_data(self, var) :
55 80 self._load_var(var)
... ... @@ -99,11 +124,16 @@ class donnee(object) :
99 124 return out2
100 125  
101 126 def get_mean(self, t1, t2, var) :
  127 + """
  128 + # NOTE: a.mean() when a posseses NaN return NaN -> treatment required
  129 + get mean value of an interval. NaN treatment implemented
  130 + """
102 131 self._load_var(var)
103 132 i1 = abs(self.donnee['epoch'] - t1).argmin()
104 133 i2 = abs(self.donnee['epoch'] - t2).argmin()
105   - return self.donnee[var][i1:i2].mean()
106   -
  134 + return self.donnee[var][i1:i2][~np.isnan(self.donnee[var][i1:i2])].mean()
  135 + #return self.donnee[var][i1:i2].mean()
  136 +
107 137 def getIndex(self, t = None):
108 138 if t : return abs(self.donnee['epoch'] - t).argmin()
109 139 else : return None
... ... @@ -111,26 +141,26 @@ class donnee(object) :
111 141 def get_projected(self, varz, matrice, new_coord = ['l', 'm', 'n']) :
112 142 """
113 143 !!! Only works with 3D array at the moment
114   - user must provide a transport matrix, with L,M,N in each colums of the matrix, so that :
115   - new_vect = old_vect([x,y,z]) * matrix, or new_vect = inv(matrix) * old_vect[[x], [y], [z]]
  144 + user must provide a transport matrix, with L,M,N in each colums of the matrix, so that:
  145 + mat[:,0] = l, mat[:,1] = m, mat[:,2] = n, with mat being a numpy.mat object
  146 + and new_vect = old_vect([x,y,z]) * matrix, or new_vect = inv(matrix) * old_vect[[x], [y], [z]]
  147 + Example : l = numpy.array([ 0.16631492, -0.08297703, 0.98257527])
  148 + m = numpy.array([-0.4464368 , -0.89481517, 0. ])
  149 + n = numpy.array([ 0.87922325, -0.43865776, -0.18586511])
  150 + matrice = numpy.mat([l,m,n]).transpose()
116 151 """
117 152 field = self.get_data_as_field(varz)
118 153 f = np.array([vect * matrice for vect in field])[:,0]
119 154 self.donnee[new_coord[0]] = f[:,0]
120 155 self.donnee[new_coord[1]] = f[:,1]
121 156 self.donnee[new_coord[2]] = f[:,2]
122   -
123   - def _load_var(self, var) :
124   - if var not in self.donnee :
125   - ceflib.read(self._fichier)
126   - self.donnee[var] = np.copy(ceflib.var(var))
127   - ceflib.close()
128   -
  157 + return {new_coord[i] : self.donnee[new_coord[i]] for i in range(3)}
129 158  
130 159 def addField(self, field, abscisse = None, name = 'New_interpolated_field') :
131 160 """
132 161 Add new field in the donnee object, use old abscisse to interpolate on current absisse
133 162 If no abscisse is given... do something?
  163 + TO DO : modify self._varnames ????
134 164 """
135 165 def interp(xnew, xold, yold) :
136 166 def tofloat(d) :
... ... @@ -143,7 +173,6 @@ class donnee(object) :
143 173 self.donnee[name] = interp(self.donnee['epoch'], abscisse, field)
144 174 return self.donnee[name]
145 175  
146   -
147 176 def get_interval(self, var, t1 = None, t2 = None, include = False) :
148 177 """
149 178 get part of the data set, between start time t1 and stop time t2
... ... @@ -175,7 +204,6 @@ class donnee(object) :
175 204 if show : plt.show()
176 205  
177 206  
178   -
179 207 def time_interpolation(x1, x2, y2) :
180 208 """
181 209 Time interpolation for 2D data :
... ... @@ -194,8 +222,35 @@ def time_interpolation(x1, x2, y2) :
194 222 return y3
195 223  
196 224  
  225 +def pickleSave(filename = 'pickleSave', data = ''):
  226 + """
  227 + Input filename WITHOUT any extension
  228 + a .save extension will be added to the name
  229 + This routine DO NOT allow overwriting!!
  230 + """
  231 + if os.path.exists(filename) :
  232 + i = 0
  233 + while os.path.exists(filename) :
  234 + filename = filename + str(i)
  235 + i+=1
  236 + filename = filename + '.save'
  237 + print 'Saving data into ', filename
  238 + print 'FYI current working directory is ', os.get_cwd()
  239 + with open(filename, 'w') as sv : pickle.dump(data, sv)
  240 + return data
197 241  
198   -
  242 +def pickleLoad(filename = 'pickleSave', filename_has_extension = False):
  243 +
  244 + if not filename_has_extension :
  245 + print 'Assume file extension is not provided, adding .save to the filename'
  246 + filename = filename + '.save'
  247 +
  248 + if os.path.exists(filename):
  249 + print 'returning data'
  250 + with open(savename, 'rb') as sv: return pickle.load(sv)
  251 + else :
  252 + print 'file not found, please check filename and extension ', filename
  253 +
199 254  
200 255  
201 256 #class field(np.ndarray) :
... ...