python.observation.dataset_interface

Created on Sun Oct 2 22:24:59 2022

@author: philippe@loco-labs.io

The python.observation.dataset_interface module contains the DatasetInterface class (python.observation.dataset.Dataset methods).

  1# -*- coding: utf-8 -*-
  2"""
  3Created on Sun Oct  2 22:24:59 2022
  4
  5@author: philippe@loco-labs.io
  6
  7The `python.observation.dataset_interface` module contains the `DatasetInterface` class
  8(`python.observation.dataset.Dataset` methods).
  9"""
 10
 11# %% declarations
 12import csv
 13import math
 14import json
 15import xarray
 16import numpy as np
 17import matplotlib.pyplot as plt
 18from tabulate import tabulate
 19
 20from json_ntv.ntv import NtvList, NtvJsonEncoder
 21from observation.field import Field
 22from observation.util import util
 23
 24#import sys
 25#print("In module dataset_interface sys.path[0], __package__ ==", sys.path[0], __package__)
 26#print("In module dataset_interface __package__, __name__ ==", __package__, __name__)
 27
 28
 29class DatasetError(Exception):
 30    ''' Dataset Exception'''
 31    # pass
 32
 33
 34class DatasetInterface:
 35    '''this class includes Dataset methods :
 36
 37    - `DatasetInterface.json`
 38    - `DatasetInterface.plot`
 39    - `DatasetInterface.to_obj`
 40    - `DatasetInterface.to_csv`
 41    - `DatasetInterface.to_file`
 42    - `DatasetInterface.to_xarray`
 43    - `DatasetInterface.to_dataframe`
 44    - `DatasetInterface.view`
 45    - `DatasetInterface.vlist`
 46    - `DatasetInterface.voxel`
 47    '''
 48
 49    def json(self, **kwargs):
 50        '''
 51        Return json dict, json string or Cbor binary.
 52
 53        *Parameters (kwargs)*
 54
 55        - **encoded** : boolean (default False) - choice for return format
 56        (string/bytes if True, dict else)
 57        - **format**  : string (default 'json')- choice for return format (json, cbor)
 58        - **codif** : dict (default ES.codeb). Numerical value for string in CBOR encoder
 59        - **modecodec** : string (default 'optimize') - if 'full', each index is with a full codec
 60        if 'default' each index has keys, if 'optimize' keys are optimized, 
 61        if 'dict' dict format is used, if 'nokeys' keys are absent
 62        - **name** : boolean (default False) - if False, default index name are not included
 63        - **geojson** : boolean (default False) - geojson for LocationValue if True
 64
 65        *Returns* : string or dict'''
 66        return self.to_obj(**kwargs)
 67
 68    def plot(self, varname=None, idxname=None, order=None, line=True, size=5, marker='o', maxlen=20):
 69        '''
 70        This function visualize data with line or colormesh.
 71
 72        *Parameters*
 73
 74        - **varname** : string (default none) - Name of the variable to use. If None,
 75        first lvarname is used.
 76        - **line** : Boolean (default True) - Choice line or colormesh.
 77        - **order** : list (defaut None) - order of the axes (x, y, hue or col)
 78        - **size** : int (defaut 5) - plot size
 79        - **marker** : Char (default 'o') - Symbol for each point.
 80        - **maxlen** : Integer (default 20) - maximum length for string
 81
 82        *Returns*
 83
 84        - **None**  '''
 85        if not self.consistent:
 86            return None
 87        if idxname:
 88            idxname = [name for name in idxname if len(
 89                self.nindex(name).codec) > 1]
 90        #xar = self.to_xarray(numeric=True, varname=varname, idxname=idxname, lisfunc=[util.cast],##
 91        xar = self.to_xarray(numeric=True, varname=varname, idxname=idxname, lisfunc=None,
 92                             dtype='str', npdtype='str', maxlen=maxlen, coord=True)
 93        if not order:
 94            order = [0, 1, 2]
 95
 96        if len(xar.dims) == 1:
 97            xar.plot.line(x=xar.dims[0]+'_row', size=size, marker=marker)
 98        elif len(xar.dims) == 2 and line:
 99            xar.plot.line(x=xar.dims[order[0]] + '_row',
100                          xticks=list(xar.coords[xar.dims[0]+'_row'].values),
101                          hue=xar.dims[order[1]], size=size, marker=marker)
102        elif len(xar.dims) == 2 and not line:
103            xar.plot(x=xar.dims[order[0]]+'_row', y=xar.dims[order[1]]+'_row',
104                     xticks=list(xar.coords[xar.dims[order[0]]+'_row'].values),
105                     yticks=list(xar.coords[xar.dims[order[1]]+'_row'].values),
106                     size=size)
107        elif len(xar.dims) == 3 and line:
108            xar.plot.line(x=xar.dims[order[0]] + '_row', col=xar.dims[order[1]],
109                          xticks=list(
110                xar.coords[xar.dims[order[0]]+'_row'].values),
111                hue=xar.dims[order[2]], col_wrap=2, size=size, marker=marker)
112        elif len(xar.dims) == 3 and not line:
113            xar.plot(x=xar.dims[order[0]]+'_row', y=xar.dims[order[1]]+'_row',
114                     xticks=list(xar.coords[xar.dims[order[0]]+'_row'].values),
115                     yticks=list(xar.coords[xar.dims[order[1]]+'_row'].values),
116                     col=xar.dims[order[2]], col_wrap=2, size=size)
117        plt.show()
118        return {xar.dims[i]: list(xar.coords[xar.dims[i]].values) for i in range(len(xar.dims))}
119
120    def to_csv(self, filename, optcsv={'quoting': csv.QUOTE_NONNUMERIC}, **kwargs):
121        '''
122        Generate csv file to display data.
123
124        *Parameters*
125
126        - **filename** : string - file name (with path)
127        - **optcsv** : parameter for csv.writer
128
129        *Parameters (kwargs)*
130
131        - **name=listcode** : element (default None) - eg location='ns'
132            - listcode : string with Code for each index (j: json, n: name, s: simple).
133            - name : name of the index
134        - **lenres** : Integer (default : 0) - Number of raws (all if 0)
135        - **header** : Boolean (default : True) - If True, first line with names
136        - **optcsv** : parameter for csv.writer
137        - **ifunc** : function (default None) - function to apply to indexes
138        - **other kwargs** : parameter for ifunc
139
140        *Returns* : size of csv file '''
141        size = 0
142        if not optcsv:
143            optcsv = {}
144        tab = self._to_tab(**kwargs)
145        with open(filename, 'w', newline='', encoding="utf-8") as csvfile:
146            writer = csv.writer(csvfile, **optcsv)
147            for lign in tab:
148                size += writer.writerow(lign)
149        return size
150
151    def to_dataframe(self, info=False, idx=None, fillvalue='?', fillextern=True,
152                     lisfunc=None, name=None, numeric=False, npdtype=None, **kwargs):
153        '''
154        Complete the Object and generate a Pandas DataFrame with the dimension define by idx.
155
156        *Parameters*
157
158        - **info** : boolean (default False) - if True, add _dict attributes to attrs Xarray
159        - **idx** : list (default none) - list of idx to be completed. If [],
160        self.primary is used.
161        - **fillvalue** : object (default '?') - value used for the new extval
162        - **fillextern** : boolean(default True) - if True, fillvalue is converted to internal value
163        - **lisfunc** : function (default none) - list of function to apply to indexes before export
164        - **name** : string (default None) - DataArray name. If None, variable name
165        - **numeric** : Boolean (default False) - Generate a numeric DataArray.Values.
166        - **npdtype** : string (default None) - numpy dtype for the DataArray ('object' if None)
167        - **kwargs** : parameter for lisfunc
168
169        *Returns* : pandas.DataFrame '''
170        if self.consistent:
171            return self.to_xarray(info=info, idx=idx, fillvalue=fillvalue,
172                                  fillextern=fillextern, lisfunc=lisfunc, name=name,
173                                  numeric=numeric, npdtype=npdtype, **kwargs
174                                  ).to_dataframe(name=name)
175        return None
176
177    def to_file(self, filename, **kwargs):
178        '''Generate file to display data.
179
180         *Parameters (kwargs)*
181
182        - **filename** : string - file name (with path)
183        - **kwargs** : see 'to_ntv' parameters
184
185        *Returns* : Integer - file lenght (bytes)  '''
186        option = {'format': 'cbor', 'modecodec': 'optimize'} | kwargs | {'encoded': True}
187        data = self.to_ntv(modecodec=option['modecodec']).to_obj(**option)
188        if option['format'] == 'cbor':
189            size = len(data)
190            with open(filename, 'wb') as file:
191                file.write(data)
192        else:
193            size = len(bytes(data, 'UTF-8'))
194            with open(filename, 'w', newline='', encoding="utf-8") as file:
195                file.write(data)
196        return size
197
198    def to_ntv(self, modecodec='optimize', def_type='json', name=False):
199        '''Return a Ntv tab value (whithout name) .
200
201        *Parameters (kwargs)*
202
203        - **modecodec** : string (default 'optimize') - if 'full', each index is with a full codec
204        if 'default' each index has keys, if 'optimize' keys are optimized, 
205        if 'dict' dict format is used, if 'nokeys' keys are absent
206        - **def_type** : string (default 'json') - default ntv_type for NtvList or NtvSet
207        - **name** : boolean (default False) - if False, default index name are not included
208        
209
210        *Returns* : Ntv object'''
211        idxname = [name or iname != 'i' + str(i) for i, iname in enumerate(self.lname)]
212        if modecodec != 'optimize':
213            lis = [index.to_ntv(modecodec=modecodec, name=iname) 
214                   for index, iname in zip(self.lindex, idxname)]
215        else:
216            lis = []
217            indexinfos = self.indexinfos()
218            for idx, inf, iname in zip(self.lindex, indexinfos, idxname):
219                coef = Field.encode_coef(idx.keys)
220                if inf['cat'] == 'unique':
221                    lis.append(idx.to_ntv(name=iname))
222                elif inf['cat'] == 'coupled':
223                    idx_coup = idx.setkeys(self.lindex[inf['parent']].keys, inplace=False)
224                    lis.append(idx_coup.to_ntv(parent=inf['parent'], name=iname))
225                elif coef:
226                    lis.append(idx.to_ntv(keys=[coef], name=iname))
227                elif inf['parent'] == -1:  # cat='variable' or 'secondary'
228                    if idx.keys == list(range(len(self))):
229                        lis.append(idx.to_ntv(modecodec='full', name=iname))
230                    else:
231                        lis.append(idx.to_ntv(modecodec='default', name=iname))                
232                else:  # derived
233                    if len(self.lindex[inf['parent']].codec) == len(self):
234                        lis.append(idx.to_ntv(modecodec='default', name=iname))             
235                    #elif idx.iskeysfromderkeys(self.lindex[inf['parent']]): # periodic derived
236                    #    lis.append(Field.to_ntv(idx, parent=inf['parent'], name=iname))
237                    else: #derived
238                        keys = idx.derkeys(self.lindex[inf['parent']])
239                        lis.append(idx.to_ntv(keys=keys, parent=inf['parent'], name=iname))            
240        return NtvList(lis, None, ntv_type=def_type)
241
242    """def to_obj(self, **kwargs):
243        '''Return a formatted object (json string, cbor bytes or json dict).
244
245        *Parameters (kwargs)*
246
247        - **encoded** : boolean (default False) - choice for return format
248        (string/bytes if True, dict else)
249        - **format**  : string (default 'json')- choice for return format (json, cbor)
250        - **codif** : dict (default ES.codeb). Numerical value for string in CBOR encoder
251        - **modecodec** : string (default 'optimize') - if 'full', each index is with a full codec
252        if 'default' each index has keys, if 'optimize' keys are optimized, 
253        if 'dict' dict format is used, if 'nokeys' keys are absent
254        - **name** : boolean (default False) - if False, default index name are not included
255        - **fullvar** : boolean (default True) - if True and modecodec='optimize, 
256        variable index is with a full codec
257        - **geojson** : boolean (default False) - geojson for LocationValue if True
258        - **id** : integer (default None) - Observation.id if Dataset is attached to an Observation
259
260        *Returns* : string, bytes or dict'''
261        option = {'modecodec': 'optimize', 'encoded': False,
262                  'format': 'json', 'codif': ES.codeb, 'name': False,
263                  'geojson': False, 'fullvar': True, 'id': None} | kwargs
264        option2 = {'encoded': False, 'format': 'json',
265                   'codif': option['codif'], 'geojson': option['geojson'],
266                   'modecodec': option['modecodec'], 'fullvar': option['fullvar']}
267        if option['modecodec'] == 'dict':
268            lis = {}
269            for idx in self.lindex:
270                name, dicval = list(idx.to_dict_obj(**option2).items())[0]
271                if name in self.lvarname:
272                    dicval['var'] = True
273                lis[name] = dicval
274        elif option['modecodec'] == 'ndjson':
275            if not option['id']:
276                raise DatasetError("an  id is necessary for 'ndjson'")                
277            lis = []
278            for rec in self:
279                lis.append({ES.id: option[ES.id]} | 
280                           {name: util.json(val, encoded=False, typevalue=None,
281                                           simpleval=False, modecodec='ndjson',
282                                           untyped=False, datetime=False,
283                                           geojson=False) 
284                            for name, val in zip(self.lname, rec)})              
285        else:
286            indexname = [option['name'] or name != 'i' + str(i)
287                         for i, name in enumerate(self.lname)]
288            if option['modecodec'] != 'optimize':
289                lis = [idx.to_obj(name=iname, **option2)
290                       for idx, iname in zip(self.lindex, indexname)]
291            else:
292                lis = self._optimize_obj(indexname, **option2)
293
294        if option['encoded'] and option['format'] == 'json':
295            return json.dumps(lis, cls=FieldEncoder)
296        if option['encoded'] and option['format'] == 'cbor':
297            return cbor2.dumps(lis, datetime_as_timestamp=True,
298                               timezone=datetime.timezone.utc, canonical=True)
299        return lis"""
300
301    def to_xarray(self, info=False, idxname=None, varname=None, fillvalue='?',
302                  fillextern=True, lisfunc=None, name=None, numeric=False,
303                  npdtype=None, attrs=None, coord=False, **kwargs):
304        '''
305        Complete the Object and generate a Xarray DataArray with the dimension define by idx.
306        Only the first variable is incuded.
307
308        *Parameters*
309
310        - **info** : boolean (default False) - if True, add _dict attributes to attrs Xarray
311        - **idxname** : list (default none) - list of idx to be completed. If None,
312        self.primary is used.
313        - **varname** : string (default none) - Name of the variable to use. If None,
314        first lvarname is used.
315        - **fillvalue** : object (default '?') - value used for the new extval
316        - **fillextern** : boolean(default True) - if True, fillvalue is converted to internal value
317        - **lisfunc** : function (default none) - list of function to apply to indexes before export
318        - **name** : string (default None) - DataArray name. If None, variable name
319        - **numeric** : Boolean (default False) - Generate a numeric DataArray.Values.
320        - **npdtype** : string (default None) - numpy dtype for the DataArray ('object' if None)
321        - **attrs** : dict (default None) - attributes for the DataArray
322        - **coord** : boolean (default False) - if True, add derivated coords
323        - **kwargs** : parameter for lisfunc
324
325        *Returns* : DataArray '''
326        option = {'dtype': None} | kwargs
327        if not self.consistent:
328            raise DatasetError("Dataset not consistent")
329        if idxname is None or idxname == []:
330            idxname = self.primaryname
331        ilf = self.full(idxname=idxname, varname=varname, fillvalue=fillvalue,
332                        fillextern=fillextern, inplace=False)
333        ilf.setcanonorder()
334        if not varname and len(ilf.lvarname) != 0:
335            varname = ilf.lvarname[0]
336        if not varname in ilf.lname:
337            ivar = -1
338        else:
339            ivar = ilf.lname.index(varname)
340        if isinstance(lisfunc, list) and len(lisfunc) == 1:
341            lisfunc = lisfunc * ilf.lenindex
342        elif isinstance(lisfunc, list) and len(lisfunc) != ilf.lenindex:
343            lisfunc = [None] * ilf.lenindex
344        elif not isinstance(lisfunc, list):
345            funcvar = lisfunc
346            lisfunc = [None] * ilf.lenindex
347            if ivar != -1:
348                lisfunc[ivar] = funcvar
349        lisfuncname = dict(zip(ilf.lname, lisfunc))
350        coords = ilf._xcoord(idxname, ivar, lisfuncname, coord, **option)
351        dims = idxname
352        if numeric:
353            #lisfunc[ivar] = util.cast
354            fillvalue = math.nan
355            npdtype = 'float'
356            option['dtype'] = 'float'
357        if ivar == -1:
358            data = self.field(list(range(len(ilf)))).to_numpy(npdtype='int')\
359                .reshape([len(ilf.nindex(name).codec) for name in idxname])
360        else:
361            data = ilf.lindex[ivar]\
362                .to_numpy(func=lisfunc[ivar], npdtype=npdtype, **option)\
363                .reshape([len(ilf.nindex(name).codec) for name in idxname])
364        if not name and ivar == -1:
365            name = ilf.name
366        elif not name:
367            name = ilf.lname[ivar]
368        if not isinstance(attrs, dict):
369            attrs = {}
370        for nam in ilf.lunicname:
371            attrs[nam] = ilf.nindex(nam).codec[0]
372        if info:
373            attrs |= ilf.indexinfos()
374        return xarray.DataArray(data, coords, dims, attrs=attrs, name=name)
375
376    def voxel(self, idxname=None, varname=None):
377        '''
378        Plot not null values in a cube with voxels and return indexes values.
379
380        *Parameters*
381
382        - **idxname** : list (default none) - list of idx to be completed. If None,
383        self.primary is used.
384        - **varname** : string (default none) - Name of the variable to use. If None,
385        first lvarname is used.
386
387        *Returns* : **dict of indexes values**
388        '''
389        if not self.consistent:
390            return None
391        if idxname is None or idxname == []:
392            idxname = self.primaryname
393        if varname is None and self.lvarname:
394            varname = self.lvarname[0]
395        if len(idxname) > 3:
396            raise DatasetError('number of idx > 3')
397        if len(idxname) == 2:
398            self.addindex(self.field('null', ' ', keys=[0]*len(self)))
399            idxname += [' ']
400        elif len(idxname) == 1:
401            self.addindex(self.field('null', ' ', keys=[0]*len(self)))
402            self.addindex(self.field('null', '  ', keys=[0]*len(self)))
403            idxname += [' ', '  ']
404        xar = self.to_xarray(idxname=idxname, varname=varname, fillvalue='?',
405                             fillextern=False, lisfunc=util.isNotEqual, tovalue='?')
406        axe = plt.figure().add_subplot(projection='3d')
407        axe.voxels(xar, edgecolor='k')
408        axe.set_xticks(np.arange(self.idxlen[self.idxname.index(xar.dims[0])]))
409        axe.set_yticks(np.arange(self.idxlen[self.idxname.index(xar.dims[1])]))
410        axe.set_zticks(np.arange(self.idxlen[self.idxname.index(xar.dims[2])]))
411        axe.set(xlabel=xar.dims[0][:8],
412                ylabel=xar.dims[1][:8],
413                zlabel=xar.dims[2][:8])
414        plt.show()
415        self.delindex([' ', '  '])
416        return {xar.dims[i]: list(xar.coords[xar.dims[i]].values)
417                for i in range(len(xar.dims))}
418
419    def view(self, **kwargs):
420        '''
421        Generate tabular list to display data.
422
423        *Parameters (kwargs)*
424
425        - **name=listcode** : element (default None) - eg location='ns'
426            - listcode : string with Code for each index (j: json, n: name, s: simple).
427            - name : name of the index
428        - **defcode** : String (default : 'j') - default list code (if 'all' is True)
429        - **all** : Boolean (default : True) - 'defcode apply to all indexes or none
430        - **lenres** : Integer (default : 0) - Number of raws (all if 0)
431        - **header** : Boolean (default : True) - First line with names
432        - **width** : Integer (default None) - Number of characters displayed for each
433        attribute (all if None)
434        - **ifunc** : function (default None) - function to apply to indexes
435        - **tabulate params** : default 'tablefmt': 'simple', 'numalign': 'left',
436        'stralign': 'left', 'floatfmt': '.3f' - See tabulate module
437        - **other kwargs** : parameter for ifunc
438
439        *Returns* : list or html table (tabulate format) '''
440        # print(kwargs)
441        opttab = {'defcode': 'j', 'all': True, 'lenres': 0, 'header': True}
442        optview = {'tablefmt': 'simple', 'numalign': 'decimal',
443                   'stralign': 'left', 'floatfmt': '.2f'}
444        option = opttab | optview | kwargs
445        tab = self._to_tab(**option)
446        width = ({'width': None} | kwargs)['width']
447        if width:
448            tab = [[(lambda x: x[:width] if isinstance(x, str) else x)(val)
449                    for val in lig] for lig in tab]
450        return tabulate(tab, headers='firstrow', **{k: option[k] for k in optview})
451
452    def vlist(self, *args, func=None, index=-1, **kwargs):
453        '''
454        Apply a function to an index and return the result.
455
456        *Parameters*
457
458        - **func** : function (default none) - function to apply to extval or extidx
459        - **args, kwargs** : parameters for the function
460        - **index** : integer - index to update (index=-1 for first variable)
461
462        *Returns* : list of func result'''
463        if index == -1 and self.lvar:
464            return self.lvar[0].vlist(func, *args, **kwargs)
465        if index == -1 and self.lenindex == 1:
466            index = 0
467        return self.lindex[index].vlist(func, *args, **kwargs)
468
469    # %%internal
470    """def _optimize_obj(self, idxname, **option2):
471        '''return list object with optimize modecodec'''
472        indexinfos = self.indexinfos()
473        notkeys = True
474        lis = []
475        if self.iscanonorder():
476            notkeys = None
477        for idx, iname, inf in zip(self.lindex, idxname, indexinfos):
478            if inf['cat'] == 'unique':
479                lis.append(idx.tostdcodec(full=False).to_obj(
480                    name=iname, **option2))
481            elif inf['cat'] == 'primary':
482                lis.append(idx.to_obj(keys=notkeys, name=iname, **option2))
483            elif inf['cat'] == 'coupled':
484                lis.append(idx.setkeys(self.lindex[inf['parent']].keys, inplace=False).
485                           to_obj(parent=inf['parent'], name=iname, **option2))
486            elif inf['parent'] == -1:  # cat='variable' or 'secondary'
487                if option2['fullvar'] and inf['cat'] == 'variable' and not(inf['child']):
488                    opt = option2 | {'modecodec': 'full'}
489                    lis.append(idx.to_obj(name=iname, **opt))
490                elif idx.keys == list(range(len(self))):
491                    lis.append(idx.to_obj(name=iname, **option2))
492                else:
493                    lis.append(idx.to_obj(keys=True, name=iname, **option2))
494            else:  # derived
495                if len(self.lindex[inf['parent']].codec) == len(self):
496                    lis.append(idx.to_obj(keys=True, name=iname, **option2))
497                elif idx.iskeysfromderkeys(self.lindex[inf['parent']]):
498                    lis.append(idx.to_obj(parent=inf['parent'],
499                                          name=iname, **option2))
500                else: # periodic derived
501                    keys = idx.derkeys(self.lindex[inf['parent']])
502                    lis.append(idx.to_obj(keys=keys, parent=inf['parent'],
503                                          name=iname, **option2))
504        return lis"""
505
506    def _to_tab(self, **kwargs):
507        ''' data preparation (dict of dict) for view or csv export.
508        Representation is included if :
509            - code is definie in the name element of the field
510            - or code is defined in 'defcode' element and 'all' element is True
511
512        *Parameters (kwargs)*
513
514        - **name=listcode** : element (default None) - eg location='ns'
515            - listcode : string with Code for each index (j: json, n: name, s: simple, f: ifunc).
516            - name : name of the index
517        - **defcode** : String (default : 'j') - default list code (if 'all' is True)
518        - **all** : Boolean (default : True) - 'defcode apply to all indexes or none
519        - **lenres** : Integer (default : 0) - Number of raws (all if 0)
520        - **ifunc** : function (default None) - function to apply to indexes
521        - **other kwargs** : parameter for ifunc'''
522
523        option = {'defcode': 'j', 'all': True, 'lenres': 0, 'ifunc': None,
524                  'header': True} | kwargs
525        tab = []
526        reslist = []
527        diccode = {'j': '', 'n': 'name-', 's': 'smpl-', 'f': 'func-'}
528        if option['header']:
529            for name in self.lname:
530                '''if name in option:
531                    for char, code in diccode.items():
532                        if char in option[name]:
533                            reslist.append(code + name)
534                elif option['all']:
535                    for char, code in diccode.items():
536                        if char in option['defcode']:
537                            reslist.append(code + name)'''
538                opt = name if name in option else 'defcode'
539                if opt != 'defcode' or option['all']:
540                    for char, code in diccode.items():
541                        if char in option[opt]:
542                            reslist.append(code + name)
543            tab.append(reslist)
544        lenres = option['lenres']
545        if lenres == 0:
546            lenres = len(self)
547        for i in range(min(lenres, len(self))):
548            reslist = []
549            for name in self.lname:
550                opt = name if name in option else 'defcode'
551                if opt != 'defcode' or option['all']:
552                    for char, code in diccode.items():
553                        if char in option[opt]:
554                            val = self.nindex(name).values[i]
555                            if char == 'j':
556                                #reslist.append(util.cast(val, dtype='json'))
557                                reslist.append(json.dumps(self.field.s_to_e(val), cls=NtvJsonEncoder))
558                            elif char == 'n':
559                                reslist.append(self.field.i_to_name(val))
560                            elif char == 's':
561                                reslist.append(json.dumps(self.field.s_to_e(val), cls=NtvJsonEncoder))
562                            elif char == 'f':
563                                reslist.append(util.funclist(
564                                    val, option['ifunc'], **kwargs))                    
565                '''if name in option:
566                    for char, code in diccode.items():
567                        if char in option[name]:
568                            val = self.nindex(name).values[i]
569                            if char == 'j':
570                                #reslist.append(util.cast(val, dtype='json'))
571                                reslist.append(self.field.s_to_e(val))
572                            elif char == 'n':
573                                reslist.append(self.field.i_to_name(val))
574                            elif char == 's':
575                                reslist.append(
576                                    json.dumps(self.field.s_to_e(val)))
577                            elif char == 'f':
578                                reslist.append(util.funclist(
579                                    val, option['ifunc'], **kwargs))
580                elif option['all']:
581                    for char, code in diccode.items():
582                        if char in option['defcode']:
583                            val = self.nindex(name).values[i]
584                            if char == 'j':
585                                reslist.append(util.cast(val, dtype='json'))
586                            elif char == 'n':
587                                reslist.append(util.cast(val, dtype='name'))
588                            elif char == 's':
589                                reslist.append(
590                                    util.cast(val, dtype='json', string=True))
591                            elif char == 'f':
592                                reslist.append(util.funclist(
593                                    val, option['ifunc'], **kwargs))'''
594            tab.append(reslist)
595        return tab
596
597    def _xcoord(self, axename, ivar, lisfuncname=None, coord=False, **kwargs):
598        ''' Coords generation for Xarray'''
599        #maxlen = kwargs.get('maxlen', 20)
600        info = self.indexinfos()
601        coords = {}
602        for i in range(self.lenindex):
603            fieldi = info[i]
604            iname = self.lname[i]
605            if fieldi['pparent'] == -1 or i == ivar:
606                continue
607            if isinstance(lisfuncname, dict) and len(lisfuncname) == self.lenindex:
608                funci = lisfuncname[iname]
609            else:
610                funci = None
611            if iname in axename:
612                coords[iname] = self.lindex[i].to_numpy(
613                    func=funci, codec=True, **kwargs)
614                if coord:
615                    coords[iname+'_row'] = (iname,
616                                            np.arange(len(coords[iname])))
617                    #coords[iname+'_str'] = (iname, self.lindex[i].to_numpy(func=util.cast,
618                    #                                                       codec=True, dtype='str', maxlen=maxlen))
619                    coords[iname+'_str'] = (iname, self.lindex[i].to_numpy(func=str, codec=True))
620            else:
621                self.lindex[i].setkeys(
622                    self.lindex[fieldi['pparent']].keys)  # !!!
623                coords[iname] = (self.lname[fieldi['pparent']],
624                                 self.lindex[i].to_numpy(func=funci, codec=True, **kwargs))
625        return coords
class DatasetError(builtins.Exception):
30class DatasetError(Exception):
31    ''' Dataset Exception'''
32    # pass

Dataset Exception

Inherited Members
builtins.Exception
Exception
builtins.BaseException
with_traceback
args
class DatasetInterface:
 35class DatasetInterface:
 36    '''this class includes Dataset methods :
 37
 38    - `DatasetInterface.json`
 39    - `DatasetInterface.plot`
 40    - `DatasetInterface.to_obj`
 41    - `DatasetInterface.to_csv`
 42    - `DatasetInterface.to_file`
 43    - `DatasetInterface.to_xarray`
 44    - `DatasetInterface.to_dataframe`
 45    - `DatasetInterface.view`
 46    - `DatasetInterface.vlist`
 47    - `DatasetInterface.voxel`
 48    '''
 49
 50    def json(self, **kwargs):
 51        '''
 52        Return json dict, json string or Cbor binary.
 53
 54        *Parameters (kwargs)*
 55
 56        - **encoded** : boolean (default False) - choice for return format
 57        (string/bytes if True, dict else)
 58        - **format**  : string (default 'json')- choice for return format (json, cbor)
 59        - **codif** : dict (default ES.codeb). Numerical value for string in CBOR encoder
 60        - **modecodec** : string (default 'optimize') - if 'full', each index is with a full codec
 61        if 'default' each index has keys, if 'optimize' keys are optimized, 
 62        if 'dict' dict format is used, if 'nokeys' keys are absent
 63        - **name** : boolean (default False) - if False, default index name are not included
 64        - **geojson** : boolean (default False) - geojson for LocationValue if True
 65
 66        *Returns* : string or dict'''
 67        return self.to_obj(**kwargs)
 68
 69    def plot(self, varname=None, idxname=None, order=None, line=True, size=5, marker='o', maxlen=20):
 70        '''
 71        This function visualize data with line or colormesh.
 72
 73        *Parameters*
 74
 75        - **varname** : string (default none) - Name of the variable to use. If None,
 76        first lvarname is used.
 77        - **line** : Boolean (default True) - Choice line or colormesh.
 78        - **order** : list (defaut None) - order of the axes (x, y, hue or col)
 79        - **size** : int (defaut 5) - plot size
 80        - **marker** : Char (default 'o') - Symbol for each point.
 81        - **maxlen** : Integer (default 20) - maximum length for string
 82
 83        *Returns*
 84
 85        - **None**  '''
 86        if not self.consistent:
 87            return None
 88        if idxname:
 89            idxname = [name for name in idxname if len(
 90                self.nindex(name).codec) > 1]
 91        #xar = self.to_xarray(numeric=True, varname=varname, idxname=idxname, lisfunc=[util.cast],##
 92        xar = self.to_xarray(numeric=True, varname=varname, idxname=idxname, lisfunc=None,
 93                             dtype='str', npdtype='str', maxlen=maxlen, coord=True)
 94        if not order:
 95            order = [0, 1, 2]
 96
 97        if len(xar.dims) == 1:
 98            xar.plot.line(x=xar.dims[0]+'_row', size=size, marker=marker)
 99        elif len(xar.dims) == 2 and line:
100            xar.plot.line(x=xar.dims[order[0]] + '_row',
101                          xticks=list(xar.coords[xar.dims[0]+'_row'].values),
102                          hue=xar.dims[order[1]], size=size, marker=marker)
103        elif len(xar.dims) == 2 and not line:
104            xar.plot(x=xar.dims[order[0]]+'_row', y=xar.dims[order[1]]+'_row',
105                     xticks=list(xar.coords[xar.dims[order[0]]+'_row'].values),
106                     yticks=list(xar.coords[xar.dims[order[1]]+'_row'].values),
107                     size=size)
108        elif len(xar.dims) == 3 and line:
109            xar.plot.line(x=xar.dims[order[0]] + '_row', col=xar.dims[order[1]],
110                          xticks=list(
111                xar.coords[xar.dims[order[0]]+'_row'].values),
112                hue=xar.dims[order[2]], col_wrap=2, size=size, marker=marker)
113        elif len(xar.dims) == 3 and not line:
114            xar.plot(x=xar.dims[order[0]]+'_row', y=xar.dims[order[1]]+'_row',
115                     xticks=list(xar.coords[xar.dims[order[0]]+'_row'].values),
116                     yticks=list(xar.coords[xar.dims[order[1]]+'_row'].values),
117                     col=xar.dims[order[2]], col_wrap=2, size=size)
118        plt.show()
119        return {xar.dims[i]: list(xar.coords[xar.dims[i]].values) for i in range(len(xar.dims))}
120
121    def to_csv(self, filename, optcsv={'quoting': csv.QUOTE_NONNUMERIC}, **kwargs):
122        '''
123        Generate csv file to display data.
124
125        *Parameters*
126
127        - **filename** : string - file name (with path)
128        - **optcsv** : parameter for csv.writer
129
130        *Parameters (kwargs)*
131
132        - **name=listcode** : element (default None) - eg location='ns'
133            - listcode : string with Code for each index (j: json, n: name, s: simple).
134            - name : name of the index
135        - **lenres** : Integer (default : 0) - Number of raws (all if 0)
136        - **header** : Boolean (default : True) - If True, first line with names
137        - **optcsv** : parameter for csv.writer
138        - **ifunc** : function (default None) - function to apply to indexes
139        - **other kwargs** : parameter for ifunc
140
141        *Returns* : size of csv file '''
142        size = 0
143        if not optcsv:
144            optcsv = {}
145        tab = self._to_tab(**kwargs)
146        with open(filename, 'w', newline='', encoding="utf-8") as csvfile:
147            writer = csv.writer(csvfile, **optcsv)
148            for lign in tab:
149                size += writer.writerow(lign)
150        return size
151
152    def to_dataframe(self, info=False, idx=None, fillvalue='?', fillextern=True,
153                     lisfunc=None, name=None, numeric=False, npdtype=None, **kwargs):
154        '''
155        Complete the Object and generate a Pandas DataFrame with the dimension define by idx.
156
157        *Parameters*
158
159        - **info** : boolean (default False) - if True, add _dict attributes to attrs Xarray
160        - **idx** : list (default none) - list of idx to be completed. If [],
161        self.primary is used.
162        - **fillvalue** : object (default '?') - value used for the new extval
163        - **fillextern** : boolean(default True) - if True, fillvalue is converted to internal value
164        - **lisfunc** : function (default none) - list of function to apply to indexes before export
165        - **name** : string (default None) - DataArray name. If None, variable name
166        - **numeric** : Boolean (default False) - Generate a numeric DataArray.Values.
167        - **npdtype** : string (default None) - numpy dtype for the DataArray ('object' if None)
168        - **kwargs** : parameter for lisfunc
169
170        *Returns* : pandas.DataFrame '''
171        if self.consistent:
172            return self.to_xarray(info=info, idx=idx, fillvalue=fillvalue,
173                                  fillextern=fillextern, lisfunc=lisfunc, name=name,
174                                  numeric=numeric, npdtype=npdtype, **kwargs
175                                  ).to_dataframe(name=name)
176        return None
177
178    def to_file(self, filename, **kwargs):
179        '''Generate file to display data.
180
181         *Parameters (kwargs)*
182
183        - **filename** : string - file name (with path)
184        - **kwargs** : see 'to_ntv' parameters
185
186        *Returns* : Integer - file lenght (bytes)  '''
187        option = {'format': 'cbor', 'modecodec': 'optimize'} | kwargs | {'encoded': True}
188        data = self.to_ntv(modecodec=option['modecodec']).to_obj(**option)
189        if option['format'] == 'cbor':
190            size = len(data)
191            with open(filename, 'wb') as file:
192                file.write(data)
193        else:
194            size = len(bytes(data, 'UTF-8'))
195            with open(filename, 'w', newline='', encoding="utf-8") as file:
196                file.write(data)
197        return size
198
199    def to_ntv(self, modecodec='optimize', def_type='json', name=False):
200        '''Return a Ntv tab value (whithout name) .
201
202        *Parameters (kwargs)*
203
204        - **modecodec** : string (default 'optimize') - if 'full', each index is with a full codec
205        if 'default' each index has keys, if 'optimize' keys are optimized, 
206        if 'dict' dict format is used, if 'nokeys' keys are absent
207        - **def_type** : string (default 'json') - default ntv_type for NtvList or NtvSet
208        - **name** : boolean (default False) - if False, default index name are not included
209        
210
211        *Returns* : Ntv object'''
212        idxname = [name or iname != 'i' + str(i) for i, iname in enumerate(self.lname)]
213        if modecodec != 'optimize':
214            lis = [index.to_ntv(modecodec=modecodec, name=iname) 
215                   for index, iname in zip(self.lindex, idxname)]
216        else:
217            lis = []
218            indexinfos = self.indexinfos()
219            for idx, inf, iname in zip(self.lindex, indexinfos, idxname):
220                coef = Field.encode_coef(idx.keys)
221                if inf['cat'] == 'unique':
222                    lis.append(idx.to_ntv(name=iname))
223                elif inf['cat'] == 'coupled':
224                    idx_coup = idx.setkeys(self.lindex[inf['parent']].keys, inplace=False)
225                    lis.append(idx_coup.to_ntv(parent=inf['parent'], name=iname))
226                elif coef:
227                    lis.append(idx.to_ntv(keys=[coef], name=iname))
228                elif inf['parent'] == -1:  # cat='variable' or 'secondary'
229                    if idx.keys == list(range(len(self))):
230                        lis.append(idx.to_ntv(modecodec='full', name=iname))
231                    else:
232                        lis.append(idx.to_ntv(modecodec='default', name=iname))                
233                else:  # derived
234                    if len(self.lindex[inf['parent']].codec) == len(self):
235                        lis.append(idx.to_ntv(modecodec='default', name=iname))             
236                    #elif idx.iskeysfromderkeys(self.lindex[inf['parent']]): # periodic derived
237                    #    lis.append(Field.to_ntv(idx, parent=inf['parent'], name=iname))
238                    else: #derived
239                        keys = idx.derkeys(self.lindex[inf['parent']])
240                        lis.append(idx.to_ntv(keys=keys, parent=inf['parent'], name=iname))            
241        return NtvList(lis, None, ntv_type=def_type)
242
243    """def to_obj(self, **kwargs):
244        '''Return a formatted object (json string, cbor bytes or json dict).
245
246        *Parameters (kwargs)*
247
248        - **encoded** : boolean (default False) - choice for return format
249        (string/bytes if True, dict else)
250        - **format**  : string (default 'json')- choice for return format (json, cbor)
251        - **codif** : dict (default ES.codeb). Numerical value for string in CBOR encoder
252        - **modecodec** : string (default 'optimize') - if 'full', each index is with a full codec
253        if 'default' each index has keys, if 'optimize' keys are optimized, 
254        if 'dict' dict format is used, if 'nokeys' keys are absent
255        - **name** : boolean (default False) - if False, default index name are not included
256        - **fullvar** : boolean (default True) - if True and modecodec='optimize, 
257        variable index is with a full codec
258        - **geojson** : boolean (default False) - geojson for LocationValue if True
259        - **id** : integer (default None) - Observation.id if Dataset is attached to an Observation
260
261        *Returns* : string, bytes or dict'''
262        option = {'modecodec': 'optimize', 'encoded': False,
263                  'format': 'json', 'codif': ES.codeb, 'name': False,
264                  'geojson': False, 'fullvar': True, 'id': None} | kwargs
265        option2 = {'encoded': False, 'format': 'json',
266                   'codif': option['codif'], 'geojson': option['geojson'],
267                   'modecodec': option['modecodec'], 'fullvar': option['fullvar']}
268        if option['modecodec'] == 'dict':
269            lis = {}
270            for idx in self.lindex:
271                name, dicval = list(idx.to_dict_obj(**option2).items())[0]
272                if name in self.lvarname:
273                    dicval['var'] = True
274                lis[name] = dicval
275        elif option['modecodec'] == 'ndjson':
276            if not option['id']:
277                raise DatasetError("an  id is necessary for 'ndjson'")                
278            lis = []
279            for rec in self:
280                lis.append({ES.id: option[ES.id]} | 
281                           {name: util.json(val, encoded=False, typevalue=None,
282                                           simpleval=False, modecodec='ndjson',
283                                           untyped=False, datetime=False,
284                                           geojson=False) 
285                            for name, val in zip(self.lname, rec)})              
286        else:
287            indexname = [option['name'] or name != 'i' + str(i)
288                         for i, name in enumerate(self.lname)]
289            if option['modecodec'] != 'optimize':
290                lis = [idx.to_obj(name=iname, **option2)
291                       for idx, iname in zip(self.lindex, indexname)]
292            else:
293                lis = self._optimize_obj(indexname, **option2)
294
295        if option['encoded'] and option['format'] == 'json':
296            return json.dumps(lis, cls=FieldEncoder)
297        if option['encoded'] and option['format'] == 'cbor':
298            return cbor2.dumps(lis, datetime_as_timestamp=True,
299                               timezone=datetime.timezone.utc, canonical=True)
300        return lis"""
301
302    def to_xarray(self, info=False, idxname=None, varname=None, fillvalue='?',
303                  fillextern=True, lisfunc=None, name=None, numeric=False,
304                  npdtype=None, attrs=None, coord=False, **kwargs):
305        '''
306        Complete the Object and generate a Xarray DataArray with the dimension define by idx.
307        Only the first variable is incuded.
308
309        *Parameters*
310
311        - **info** : boolean (default False) - if True, add _dict attributes to attrs Xarray
312        - **idxname** : list (default none) - list of idx to be completed. If None,
313        self.primary is used.
314        - **varname** : string (default none) - Name of the variable to use. If None,
315        first lvarname is used.
316        - **fillvalue** : object (default '?') - value used for the new extval
317        - **fillextern** : boolean(default True) - if True, fillvalue is converted to internal value
318        - **lisfunc** : function (default none) - list of function to apply to indexes before export
319        - **name** : string (default None) - DataArray name. If None, variable name
320        - **numeric** : Boolean (default False) - Generate a numeric DataArray.Values.
321        - **npdtype** : string (default None) - numpy dtype for the DataArray ('object' if None)
322        - **attrs** : dict (default None) - attributes for the DataArray
323        - **coord** : boolean (default False) - if True, add derivated coords
324        - **kwargs** : parameter for lisfunc
325
326        *Returns* : DataArray '''
327        option = {'dtype': None} | kwargs
328        if not self.consistent:
329            raise DatasetError("Dataset not consistent")
330        if idxname is None or idxname == []:
331            idxname = self.primaryname
332        ilf = self.full(idxname=idxname, varname=varname, fillvalue=fillvalue,
333                        fillextern=fillextern, inplace=False)
334        ilf.setcanonorder()
335        if not varname and len(ilf.lvarname) != 0:
336            varname = ilf.lvarname[0]
337        if not varname in ilf.lname:
338            ivar = -1
339        else:
340            ivar = ilf.lname.index(varname)
341        if isinstance(lisfunc, list) and len(lisfunc) == 1:
342            lisfunc = lisfunc * ilf.lenindex
343        elif isinstance(lisfunc, list) and len(lisfunc) != ilf.lenindex:
344            lisfunc = [None] * ilf.lenindex
345        elif not isinstance(lisfunc, list):
346            funcvar = lisfunc
347            lisfunc = [None] * ilf.lenindex
348            if ivar != -1:
349                lisfunc[ivar] = funcvar
350        lisfuncname = dict(zip(ilf.lname, lisfunc))
351        coords = ilf._xcoord(idxname, ivar, lisfuncname, coord, **option)
352        dims = idxname
353        if numeric:
354            #lisfunc[ivar] = util.cast
355            fillvalue = math.nan
356            npdtype = 'float'
357            option['dtype'] = 'float'
358        if ivar == -1:
359            data = self.field(list(range(len(ilf)))).to_numpy(npdtype='int')\
360                .reshape([len(ilf.nindex(name).codec) for name in idxname])
361        else:
362            data = ilf.lindex[ivar]\
363                .to_numpy(func=lisfunc[ivar], npdtype=npdtype, **option)\
364                .reshape([len(ilf.nindex(name).codec) for name in idxname])
365        if not name and ivar == -1:
366            name = ilf.name
367        elif not name:
368            name = ilf.lname[ivar]
369        if not isinstance(attrs, dict):
370            attrs = {}
371        for nam in ilf.lunicname:
372            attrs[nam] = ilf.nindex(nam).codec[0]
373        if info:
374            attrs |= ilf.indexinfos()
375        return xarray.DataArray(data, coords, dims, attrs=attrs, name=name)
376
377    def voxel(self, idxname=None, varname=None):
378        '''
379        Plot not null values in a cube with voxels and return indexes values.
380
381        *Parameters*
382
383        - **idxname** : list (default none) - list of idx to be completed. If None,
384        self.primary is used.
385        - **varname** : string (default none) - Name of the variable to use. If None,
386        first lvarname is used.
387
388        *Returns* : **dict of indexes values**
389        '''
390        if not self.consistent:
391            return None
392        if idxname is None or idxname == []:
393            idxname = self.primaryname
394        if varname is None and self.lvarname:
395            varname = self.lvarname[0]
396        if len(idxname) > 3:
397            raise DatasetError('number of idx > 3')
398        if len(idxname) == 2:
399            self.addindex(self.field('null', ' ', keys=[0]*len(self)))
400            idxname += [' ']
401        elif len(idxname) == 1:
402            self.addindex(self.field('null', ' ', keys=[0]*len(self)))
403            self.addindex(self.field('null', '  ', keys=[0]*len(self)))
404            idxname += [' ', '  ']
405        xar = self.to_xarray(idxname=idxname, varname=varname, fillvalue='?',
406                             fillextern=False, lisfunc=util.isNotEqual, tovalue='?')
407        axe = plt.figure().add_subplot(projection='3d')
408        axe.voxels(xar, edgecolor='k')
409        axe.set_xticks(np.arange(self.idxlen[self.idxname.index(xar.dims[0])]))
410        axe.set_yticks(np.arange(self.idxlen[self.idxname.index(xar.dims[1])]))
411        axe.set_zticks(np.arange(self.idxlen[self.idxname.index(xar.dims[2])]))
412        axe.set(xlabel=xar.dims[0][:8],
413                ylabel=xar.dims[1][:8],
414                zlabel=xar.dims[2][:8])
415        plt.show()
416        self.delindex([' ', '  '])
417        return {xar.dims[i]: list(xar.coords[xar.dims[i]].values)
418                for i in range(len(xar.dims))}
419
420    def view(self, **kwargs):
421        '''
422        Generate tabular list to display data.
423
424        *Parameters (kwargs)*
425
426        - **name=listcode** : element (default None) - eg location='ns'
427            - listcode : string with Code for each index (j: json, n: name, s: simple).
428            - name : name of the index
429        - **defcode** : String (default : 'j') - default list code (if 'all' is True)
430        - **all** : Boolean (default : True) - 'defcode apply to all indexes or none
431        - **lenres** : Integer (default : 0) - Number of raws (all if 0)
432        - **header** : Boolean (default : True) - First line with names
433        - **width** : Integer (default None) - Number of characters displayed for each
434        attribute (all if None)
435        - **ifunc** : function (default None) - function to apply to indexes
436        - **tabulate params** : default 'tablefmt': 'simple', 'numalign': 'left',
437        'stralign': 'left', 'floatfmt': '.3f' - See tabulate module
438        - **other kwargs** : parameter for ifunc
439
440        *Returns* : list or html table (tabulate format) '''
441        # print(kwargs)
442        opttab = {'defcode': 'j', 'all': True, 'lenres': 0, 'header': True}
443        optview = {'tablefmt': 'simple', 'numalign': 'decimal',
444                   'stralign': 'left', 'floatfmt': '.2f'}
445        option = opttab | optview | kwargs
446        tab = self._to_tab(**option)
447        width = ({'width': None} | kwargs)['width']
448        if width:
449            tab = [[(lambda x: x[:width] if isinstance(x, str) else x)(val)
450                    for val in lig] for lig in tab]
451        return tabulate(tab, headers='firstrow', **{k: option[k] for k in optview})
452
453    def vlist(self, *args, func=None, index=-1, **kwargs):
454        '''
455        Apply a function to an index and return the result.
456
457        *Parameters*
458
459        - **func** : function (default none) - function to apply to extval or extidx
460        - **args, kwargs** : parameters for the function
461        - **index** : integer - index to update (index=-1 for first variable)
462
463        *Returns* : list of func result'''
464        if index == -1 and self.lvar:
465            return self.lvar[0].vlist(func, *args, **kwargs)
466        if index == -1 and self.lenindex == 1:
467            index = 0
468        return self.lindex[index].vlist(func, *args, **kwargs)
469
470    # %%internal
471    """def _optimize_obj(self, idxname, **option2):
472        '''return list object with optimize modecodec'''
473        indexinfos = self.indexinfos()
474        notkeys = True
475        lis = []
476        if self.iscanonorder():
477            notkeys = None
478        for idx, iname, inf in zip(self.lindex, idxname, indexinfos):
479            if inf['cat'] == 'unique':
480                lis.append(idx.tostdcodec(full=False).to_obj(
481                    name=iname, **option2))
482            elif inf['cat'] == 'primary':
483                lis.append(idx.to_obj(keys=notkeys, name=iname, **option2))
484            elif inf['cat'] == 'coupled':
485                lis.append(idx.setkeys(self.lindex[inf['parent']].keys, inplace=False).
486                           to_obj(parent=inf['parent'], name=iname, **option2))
487            elif inf['parent'] == -1:  # cat='variable' or 'secondary'
488                if option2['fullvar'] and inf['cat'] == 'variable' and not(inf['child']):
489                    opt = option2 | {'modecodec': 'full'}
490                    lis.append(idx.to_obj(name=iname, **opt))
491                elif idx.keys == list(range(len(self))):
492                    lis.append(idx.to_obj(name=iname, **option2))
493                else:
494                    lis.append(idx.to_obj(keys=True, name=iname, **option2))
495            else:  # derived
496                if len(self.lindex[inf['parent']].codec) == len(self):
497                    lis.append(idx.to_obj(keys=True, name=iname, **option2))
498                elif idx.iskeysfromderkeys(self.lindex[inf['parent']]):
499                    lis.append(idx.to_obj(parent=inf['parent'],
500                                          name=iname, **option2))
501                else: # periodic derived
502                    keys = idx.derkeys(self.lindex[inf['parent']])
503                    lis.append(idx.to_obj(keys=keys, parent=inf['parent'],
504                                          name=iname, **option2))
505        return lis"""
506
507    def _to_tab(self, **kwargs):
508        ''' data preparation (dict of dict) for view or csv export.
509        Representation is included if :
510            - code is definie in the name element of the field
511            - or code is defined in 'defcode' element and 'all' element is True
512
513        *Parameters (kwargs)*
514
515        - **name=listcode** : element (default None) - eg location='ns'
516            - listcode : string with Code for each index (j: json, n: name, s: simple, f: ifunc).
517            - name : name of the index
518        - **defcode** : String (default : 'j') - default list code (if 'all' is True)
519        - **all** : Boolean (default : True) - 'defcode apply to all indexes or none
520        - **lenres** : Integer (default : 0) - Number of raws (all if 0)
521        - **ifunc** : function (default None) - function to apply to indexes
522        - **other kwargs** : parameter for ifunc'''
523
524        option = {'defcode': 'j', 'all': True, 'lenres': 0, 'ifunc': None,
525                  'header': True} | kwargs
526        tab = []
527        reslist = []
528        diccode = {'j': '', 'n': 'name-', 's': 'smpl-', 'f': 'func-'}
529        if option['header']:
530            for name in self.lname:
531                '''if name in option:
532                    for char, code in diccode.items():
533                        if char in option[name]:
534                            reslist.append(code + name)
535                elif option['all']:
536                    for char, code in diccode.items():
537                        if char in option['defcode']:
538                            reslist.append(code + name)'''
539                opt = name if name in option else 'defcode'
540                if opt != 'defcode' or option['all']:
541                    for char, code in diccode.items():
542                        if char in option[opt]:
543                            reslist.append(code + name)
544            tab.append(reslist)
545        lenres = option['lenres']
546        if lenres == 0:
547            lenres = len(self)
548        for i in range(min(lenres, len(self))):
549            reslist = []
550            for name in self.lname:
551                opt = name if name in option else 'defcode'
552                if opt != 'defcode' or option['all']:
553                    for char, code in diccode.items():
554                        if char in option[opt]:
555                            val = self.nindex(name).values[i]
556                            if char == 'j':
557                                #reslist.append(util.cast(val, dtype='json'))
558                                reslist.append(json.dumps(self.field.s_to_e(val), cls=NtvJsonEncoder))
559                            elif char == 'n':
560                                reslist.append(self.field.i_to_name(val))
561                            elif char == 's':
562                                reslist.append(json.dumps(self.field.s_to_e(val), cls=NtvJsonEncoder))
563                            elif char == 'f':
564                                reslist.append(util.funclist(
565                                    val, option['ifunc'], **kwargs))                    
566                '''if name in option:
567                    for char, code in diccode.items():
568                        if char in option[name]:
569                            val = self.nindex(name).values[i]
570                            if char == 'j':
571                                #reslist.append(util.cast(val, dtype='json'))
572                                reslist.append(self.field.s_to_e(val))
573                            elif char == 'n':
574                                reslist.append(self.field.i_to_name(val))
575                            elif char == 's':
576                                reslist.append(
577                                    json.dumps(self.field.s_to_e(val)))
578                            elif char == 'f':
579                                reslist.append(util.funclist(
580                                    val, option['ifunc'], **kwargs))
581                elif option['all']:
582                    for char, code in diccode.items():
583                        if char in option['defcode']:
584                            val = self.nindex(name).values[i]
585                            if char == 'j':
586                                reslist.append(util.cast(val, dtype='json'))
587                            elif char == 'n':
588                                reslist.append(util.cast(val, dtype='name'))
589                            elif char == 's':
590                                reslist.append(
591                                    util.cast(val, dtype='json', string=True))
592                            elif char == 'f':
593                                reslist.append(util.funclist(
594                                    val, option['ifunc'], **kwargs))'''
595            tab.append(reslist)
596        return tab
597
598    def _xcoord(self, axename, ivar, lisfuncname=None, coord=False, **kwargs):
599        ''' Coords generation for Xarray'''
600        #maxlen = kwargs.get('maxlen', 20)
601        info = self.indexinfos()
602        coords = {}
603        for i in range(self.lenindex):
604            fieldi = info[i]
605            iname = self.lname[i]
606            if fieldi['pparent'] == -1 or i == ivar:
607                continue
608            if isinstance(lisfuncname, dict) and len(lisfuncname) == self.lenindex:
609                funci = lisfuncname[iname]
610            else:
611                funci = None
612            if iname in axename:
613                coords[iname] = self.lindex[i].to_numpy(
614                    func=funci, codec=True, **kwargs)
615                if coord:
616                    coords[iname+'_row'] = (iname,
617                                            np.arange(len(coords[iname])))
618                    #coords[iname+'_str'] = (iname, self.lindex[i].to_numpy(func=util.cast,
619                    #                                                       codec=True, dtype='str', maxlen=maxlen))
620                    coords[iname+'_str'] = (iname, self.lindex[i].to_numpy(func=str, codec=True))
621            else:
622                self.lindex[i].setkeys(
623                    self.lindex[fieldi['pparent']].keys)  # !!!
624                coords[iname] = (self.lname[fieldi['pparent']],
625                                 self.lindex[i].to_numpy(func=funci, codec=True, **kwargs))
626        return coords
def json(self, **kwargs):
50    def json(self, **kwargs):
51        '''
52        Return json dict, json string or Cbor binary.
53
54        *Parameters (kwargs)*
55
56        - **encoded** : boolean (default False) - choice for return format
57        (string/bytes if True, dict else)
58        - **format**  : string (default 'json')- choice for return format (json, cbor)
59        - **codif** : dict (default ES.codeb). Numerical value for string in CBOR encoder
60        - **modecodec** : string (default 'optimize') - if 'full', each index is with a full codec
61        if 'default' each index has keys, if 'optimize' keys are optimized, 
62        if 'dict' dict format is used, if 'nokeys' keys are absent
63        - **name** : boolean (default False) - if False, default index name are not included
64        - **geojson** : boolean (default False) - geojson for LocationValue if True
65
66        *Returns* : string or dict'''
67        return self.to_obj(**kwargs)

Return json dict, json string or Cbor binary.

Parameters (kwargs)

  • encoded : boolean (default False) - choice for return format (string/bytes if True, dict else)
  • format : string (default 'json')- choice for return format (json, cbor)
  • codif : dict (default ES.codeb). Numerical value for string in CBOR encoder
  • modecodec : string (default 'optimize') - if 'full', each index is with a full codec if 'default' each index has keys, if 'optimize' keys are optimized, if 'dict' dict format is used, if 'nokeys' keys are absent
  • name : boolean (default False) - if False, default index name are not included
  • geojson : boolean (default False) - geojson for LocationValue if True

Returns : string or dict

def plot( self, varname=None, idxname=None, order=None, line=True, size=5, marker='o', maxlen=20):
 69    def plot(self, varname=None, idxname=None, order=None, line=True, size=5, marker='o', maxlen=20):
 70        '''
 71        This function visualize data with line or colormesh.
 72
 73        *Parameters*
 74
 75        - **varname** : string (default none) - Name of the variable to use. If None,
 76        first lvarname is used.
 77        - **line** : Boolean (default True) - Choice line or colormesh.
 78        - **order** : list (defaut None) - order of the axes (x, y, hue or col)
 79        - **size** : int (defaut 5) - plot size
 80        - **marker** : Char (default 'o') - Symbol for each point.
 81        - **maxlen** : Integer (default 20) - maximum length for string
 82
 83        *Returns*
 84
 85        - **None**  '''
 86        if not self.consistent:
 87            return None
 88        if idxname:
 89            idxname = [name for name in idxname if len(
 90                self.nindex(name).codec) > 1]
 91        #xar = self.to_xarray(numeric=True, varname=varname, idxname=idxname, lisfunc=[util.cast],##
 92        xar = self.to_xarray(numeric=True, varname=varname, idxname=idxname, lisfunc=None,
 93                             dtype='str', npdtype='str', maxlen=maxlen, coord=True)
 94        if not order:
 95            order = [0, 1, 2]
 96
 97        if len(xar.dims) == 1:
 98            xar.plot.line(x=xar.dims[0]+'_row', size=size, marker=marker)
 99        elif len(xar.dims) == 2 and line:
100            xar.plot.line(x=xar.dims[order[0]] + '_row',
101                          xticks=list(xar.coords[xar.dims[0]+'_row'].values),
102                          hue=xar.dims[order[1]], size=size, marker=marker)
103        elif len(xar.dims) == 2 and not line:
104            xar.plot(x=xar.dims[order[0]]+'_row', y=xar.dims[order[1]]+'_row',
105                     xticks=list(xar.coords[xar.dims[order[0]]+'_row'].values),
106                     yticks=list(xar.coords[xar.dims[order[1]]+'_row'].values),
107                     size=size)
108        elif len(xar.dims) == 3 and line:
109            xar.plot.line(x=xar.dims[order[0]] + '_row', col=xar.dims[order[1]],
110                          xticks=list(
111                xar.coords[xar.dims[order[0]]+'_row'].values),
112                hue=xar.dims[order[2]], col_wrap=2, size=size, marker=marker)
113        elif len(xar.dims) == 3 and not line:
114            xar.plot(x=xar.dims[order[0]]+'_row', y=xar.dims[order[1]]+'_row',
115                     xticks=list(xar.coords[xar.dims[order[0]]+'_row'].values),
116                     yticks=list(xar.coords[xar.dims[order[1]]+'_row'].values),
117                     col=xar.dims[order[2]], col_wrap=2, size=size)
118        plt.show()
119        return {xar.dims[i]: list(xar.coords[xar.dims[i]].values) for i in range(len(xar.dims))}

This function visualize data with line or colormesh.

Parameters

  • varname : string (default none) - Name of the variable to use. If None, first lvarname is used.
  • line : Boolean (default True) - Choice line or colormesh.
  • order : list (defaut None) - order of the axes (x, y, hue or col)
  • size : int (defaut 5) - plot size
  • marker : Char (default 'o') - Symbol for each point.
  • maxlen : Integer (default 20) - maximum length for string

Returns

  • None
def to_csv(self, filename, optcsv={'quoting': 2}, **kwargs):
121    def to_csv(self, filename, optcsv={'quoting': csv.QUOTE_NONNUMERIC}, **kwargs):
122        '''
123        Generate csv file to display data.
124
125        *Parameters*
126
127        - **filename** : string - file name (with path)
128        - **optcsv** : parameter for csv.writer
129
130        *Parameters (kwargs)*
131
132        - **name=listcode** : element (default None) - eg location='ns'
133            - listcode : string with Code for each index (j: json, n: name, s: simple).
134            - name : name of the index
135        - **lenres** : Integer (default : 0) - Number of raws (all if 0)
136        - **header** : Boolean (default : True) - If True, first line with names
137        - **optcsv** : parameter for csv.writer
138        - **ifunc** : function (default None) - function to apply to indexes
139        - **other kwargs** : parameter for ifunc
140
141        *Returns* : size of csv file '''
142        size = 0
143        if not optcsv:
144            optcsv = {}
145        tab = self._to_tab(**kwargs)
146        with open(filename, 'w', newline='', encoding="utf-8") as csvfile:
147            writer = csv.writer(csvfile, **optcsv)
148            for lign in tab:
149                size += writer.writerow(lign)
150        return size

Generate csv file to display data.

Parameters

  • filename : string - file name (with path)
  • optcsv : parameter for csv.writer

Parameters (kwargs)

  • name=listcode : element (default None) - eg location='ns'
    • listcode : string with Code for each index (j: json, n: name, s: simple).
    • name : name of the index
  • lenres : Integer (default : 0) - Number of raws (all if 0)
  • header : Boolean (default : True) - If True, first line with names
  • optcsv : parameter for csv.writer
  • ifunc : function (default None) - function to apply to indexes
  • other kwargs : parameter for ifunc

Returns : size of csv file

def to_dataframe( self, info=False, idx=None, fillvalue='?', fillextern=True, lisfunc=None, name=None, numeric=False, npdtype=None, **kwargs):
152    def to_dataframe(self, info=False, idx=None, fillvalue='?', fillextern=True,
153                     lisfunc=None, name=None, numeric=False, npdtype=None, **kwargs):
154        '''
155        Complete the Object and generate a Pandas DataFrame with the dimension define by idx.
156
157        *Parameters*
158
159        - **info** : boolean (default False) - if True, add _dict attributes to attrs Xarray
160        - **idx** : list (default none) - list of idx to be completed. If [],
161        self.primary is used.
162        - **fillvalue** : object (default '?') - value used for the new extval
163        - **fillextern** : boolean(default True) - if True, fillvalue is converted to internal value
164        - **lisfunc** : function (default none) - list of function to apply to indexes before export
165        - **name** : string (default None) - DataArray name. If None, variable name
166        - **numeric** : Boolean (default False) - Generate a numeric DataArray.Values.
167        - **npdtype** : string (default None) - numpy dtype for the DataArray ('object' if None)
168        - **kwargs** : parameter for lisfunc
169
170        *Returns* : pandas.DataFrame '''
171        if self.consistent:
172            return self.to_xarray(info=info, idx=idx, fillvalue=fillvalue,
173                                  fillextern=fillextern, lisfunc=lisfunc, name=name,
174                                  numeric=numeric, npdtype=npdtype, **kwargs
175                                  ).to_dataframe(name=name)
176        return None

Complete the Object and generate a Pandas DataFrame with the dimension define by idx.

Parameters

  • info : boolean (default False) - if True, add _dict attributes to attrs Xarray
  • idx : list (default none) - list of idx to be completed. If [], self.primary is used.
  • fillvalue : object (default '?') - value used for the new extval
  • fillextern : boolean(default True) - if True, fillvalue is converted to internal value
  • lisfunc : function (default none) - list of function to apply to indexes before export
  • name : string (default None) - DataArray name. If None, variable name
  • numeric : Boolean (default False) - Generate a numeric DataArray.Values.
  • npdtype : string (default None) - numpy dtype for the DataArray ('object' if None)
  • kwargs : parameter for lisfunc

Returns : pandas.DataFrame

def to_file(self, filename, **kwargs):
178    def to_file(self, filename, **kwargs):
179        '''Generate file to display data.
180
181         *Parameters (kwargs)*
182
183        - **filename** : string - file name (with path)
184        - **kwargs** : see 'to_ntv' parameters
185
186        *Returns* : Integer - file lenght (bytes)  '''
187        option = {'format': 'cbor', 'modecodec': 'optimize'} | kwargs | {'encoded': True}
188        data = self.to_ntv(modecodec=option['modecodec']).to_obj(**option)
189        if option['format'] == 'cbor':
190            size = len(data)
191            with open(filename, 'wb') as file:
192                file.write(data)
193        else:
194            size = len(bytes(data, 'UTF-8'))
195            with open(filename, 'w', newline='', encoding="utf-8") as file:
196                file.write(data)
197        return size

Generate file to display data.

Parameters (kwargs)

  • filename : string - file name (with path)
  • kwargs : see 'to_ntv' parameters

Returns : Integer - file lenght (bytes)

def to_ntv(self, modecodec='optimize', def_type='json', name=False):
199    def to_ntv(self, modecodec='optimize', def_type='json', name=False):
200        '''Return a Ntv tab value (whithout name) .
201
202        *Parameters (kwargs)*
203
204        - **modecodec** : string (default 'optimize') - if 'full', each index is with a full codec
205        if 'default' each index has keys, if 'optimize' keys are optimized, 
206        if 'dict' dict format is used, if 'nokeys' keys are absent
207        - **def_type** : string (default 'json') - default ntv_type for NtvList or NtvSet
208        - **name** : boolean (default False) - if False, default index name are not included
209        
210
211        *Returns* : Ntv object'''
212        idxname = [name or iname != 'i' + str(i) for i, iname in enumerate(self.lname)]
213        if modecodec != 'optimize':
214            lis = [index.to_ntv(modecodec=modecodec, name=iname) 
215                   for index, iname in zip(self.lindex, idxname)]
216        else:
217            lis = []
218            indexinfos = self.indexinfos()
219            for idx, inf, iname in zip(self.lindex, indexinfos, idxname):
220                coef = Field.encode_coef(idx.keys)
221                if inf['cat'] == 'unique':
222                    lis.append(idx.to_ntv(name=iname))
223                elif inf['cat'] == 'coupled':
224                    idx_coup = idx.setkeys(self.lindex[inf['parent']].keys, inplace=False)
225                    lis.append(idx_coup.to_ntv(parent=inf['parent'], name=iname))
226                elif coef:
227                    lis.append(idx.to_ntv(keys=[coef], name=iname))
228                elif inf['parent'] == -1:  # cat='variable' or 'secondary'
229                    if idx.keys == list(range(len(self))):
230                        lis.append(idx.to_ntv(modecodec='full', name=iname))
231                    else:
232                        lis.append(idx.to_ntv(modecodec='default', name=iname))                
233                else:  # derived
234                    if len(self.lindex[inf['parent']].codec) == len(self):
235                        lis.append(idx.to_ntv(modecodec='default', name=iname))             
236                    #elif idx.iskeysfromderkeys(self.lindex[inf['parent']]): # periodic derived
237                    #    lis.append(Field.to_ntv(idx, parent=inf['parent'], name=iname))
238                    else: #derived
239                        keys = idx.derkeys(self.lindex[inf['parent']])
240                        lis.append(idx.to_ntv(keys=keys, parent=inf['parent'], name=iname))            
241        return NtvList(lis, None, ntv_type=def_type)

Return a Ntv tab value (whithout name) .

Parameters (kwargs)

  • modecodec : string (default 'optimize') - if 'full', each index is with a full codec if 'default' each index has keys, if 'optimize' keys are optimized, if 'dict' dict format is used, if 'nokeys' keys are absent
  • def_type : string (default 'json') - default ntv_type for NtvList or NtvSet
  • name : boolean (default False) - if False, default index name are not included

Returns : Ntv object

def to_xarray( self, info=False, idxname=None, varname=None, fillvalue='?', fillextern=True, lisfunc=None, name=None, numeric=False, npdtype=None, attrs=None, coord=False, **kwargs):
302    def to_xarray(self, info=False, idxname=None, varname=None, fillvalue='?',
303                  fillextern=True, lisfunc=None, name=None, numeric=False,
304                  npdtype=None, attrs=None, coord=False, **kwargs):
305        '''
306        Complete the Object and generate a Xarray DataArray with the dimension define by idx.
307        Only the first variable is incuded.
308
309        *Parameters*
310
311        - **info** : boolean (default False) - if True, add _dict attributes to attrs Xarray
312        - **idxname** : list (default none) - list of idx to be completed. If None,
313        self.primary is used.
314        - **varname** : string (default none) - Name of the variable to use. If None,
315        first lvarname is used.
316        - **fillvalue** : object (default '?') - value used for the new extval
317        - **fillextern** : boolean(default True) - if True, fillvalue is converted to internal value
318        - **lisfunc** : function (default none) - list of function to apply to indexes before export
319        - **name** : string (default None) - DataArray name. If None, variable name
320        - **numeric** : Boolean (default False) - Generate a numeric DataArray.Values.
321        - **npdtype** : string (default None) - numpy dtype for the DataArray ('object' if None)
322        - **attrs** : dict (default None) - attributes for the DataArray
323        - **coord** : boolean (default False) - if True, add derivated coords
324        - **kwargs** : parameter for lisfunc
325
326        *Returns* : DataArray '''
327        option = {'dtype': None} | kwargs
328        if not self.consistent:
329            raise DatasetError("Dataset not consistent")
330        if idxname is None or idxname == []:
331            idxname = self.primaryname
332        ilf = self.full(idxname=idxname, varname=varname, fillvalue=fillvalue,
333                        fillextern=fillextern, inplace=False)
334        ilf.setcanonorder()
335        if not varname and len(ilf.lvarname) != 0:
336            varname = ilf.lvarname[0]
337        if not varname in ilf.lname:
338            ivar = -1
339        else:
340            ivar = ilf.lname.index(varname)
341        if isinstance(lisfunc, list) and len(lisfunc) == 1:
342            lisfunc = lisfunc * ilf.lenindex
343        elif isinstance(lisfunc, list) and len(lisfunc) != ilf.lenindex:
344            lisfunc = [None] * ilf.lenindex
345        elif not isinstance(lisfunc, list):
346            funcvar = lisfunc
347            lisfunc = [None] * ilf.lenindex
348            if ivar != -1:
349                lisfunc[ivar] = funcvar
350        lisfuncname = dict(zip(ilf.lname, lisfunc))
351        coords = ilf._xcoord(idxname, ivar, lisfuncname, coord, **option)
352        dims = idxname
353        if numeric:
354            #lisfunc[ivar] = util.cast
355            fillvalue = math.nan
356            npdtype = 'float'
357            option['dtype'] = 'float'
358        if ivar == -1:
359            data = self.field(list(range(len(ilf)))).to_numpy(npdtype='int')\
360                .reshape([len(ilf.nindex(name).codec) for name in idxname])
361        else:
362            data = ilf.lindex[ivar]\
363                .to_numpy(func=lisfunc[ivar], npdtype=npdtype, **option)\
364                .reshape([len(ilf.nindex(name).codec) for name in idxname])
365        if not name and ivar == -1:
366            name = ilf.name
367        elif not name:
368            name = ilf.lname[ivar]
369        if not isinstance(attrs, dict):
370            attrs = {}
371        for nam in ilf.lunicname:
372            attrs[nam] = ilf.nindex(nam).codec[0]
373        if info:
374            attrs |= ilf.indexinfos()
375        return xarray.DataArray(data, coords, dims, attrs=attrs, name=name)

Complete the Object and generate a Xarray DataArray with the dimension define by idx. Only the first variable is incuded.

Parameters

  • info : boolean (default False) - if True, add _dict attributes to attrs Xarray
  • idxname : list (default none) - list of idx to be completed. If None, self.primary is used.
  • varname : string (default none) - Name of the variable to use. If None, first lvarname is used.
  • fillvalue : object (default '?') - value used for the new extval
  • fillextern : boolean(default True) - if True, fillvalue is converted to internal value
  • lisfunc : function (default none) - list of function to apply to indexes before export
  • name : string (default None) - DataArray name. If None, variable name
  • numeric : Boolean (default False) - Generate a numeric DataArray.Values.
  • npdtype : string (default None) - numpy dtype for the DataArray ('object' if None)
  • attrs : dict (default None) - attributes for the DataArray
  • coord : boolean (default False) - if True, add derivated coords
  • kwargs : parameter for lisfunc

Returns : DataArray

def voxel(self, idxname=None, varname=None):
377    def voxel(self, idxname=None, varname=None):
378        '''
379        Plot not null values in a cube with voxels and return indexes values.
380
381        *Parameters*
382
383        - **idxname** : list (default none) - list of idx to be completed. If None,
384        self.primary is used.
385        - **varname** : string (default none) - Name of the variable to use. If None,
386        first lvarname is used.
387
388        *Returns* : **dict of indexes values**
389        '''
390        if not self.consistent:
391            return None
392        if idxname is None or idxname == []:
393            idxname = self.primaryname
394        if varname is None and self.lvarname:
395            varname = self.lvarname[0]
396        if len(idxname) > 3:
397            raise DatasetError('number of idx > 3')
398        if len(idxname) == 2:
399            self.addindex(self.field('null', ' ', keys=[0]*len(self)))
400            idxname += [' ']
401        elif len(idxname) == 1:
402            self.addindex(self.field('null', ' ', keys=[0]*len(self)))
403            self.addindex(self.field('null', '  ', keys=[0]*len(self)))
404            idxname += [' ', '  ']
405        xar = self.to_xarray(idxname=idxname, varname=varname, fillvalue='?',
406                             fillextern=False, lisfunc=util.isNotEqual, tovalue='?')
407        axe = plt.figure().add_subplot(projection='3d')
408        axe.voxels(xar, edgecolor='k')
409        axe.set_xticks(np.arange(self.idxlen[self.idxname.index(xar.dims[0])]))
410        axe.set_yticks(np.arange(self.idxlen[self.idxname.index(xar.dims[1])]))
411        axe.set_zticks(np.arange(self.idxlen[self.idxname.index(xar.dims[2])]))
412        axe.set(xlabel=xar.dims[0][:8],
413                ylabel=xar.dims[1][:8],
414                zlabel=xar.dims[2][:8])
415        plt.show()
416        self.delindex([' ', '  '])
417        return {xar.dims[i]: list(xar.coords[xar.dims[i]].values)
418                for i in range(len(xar.dims))}

Plot not null values in a cube with voxels and return indexes values.

Parameters

  • idxname : list (default none) - list of idx to be completed. If None, self.primary is used.
  • varname : string (default none) - Name of the variable to use. If None, first lvarname is used.

Returns : dict of indexes values

def view(self, **kwargs):
420    def view(self, **kwargs):
421        '''
422        Generate tabular list to display data.
423
424        *Parameters (kwargs)*
425
426        - **name=listcode** : element (default None) - eg location='ns'
427            - listcode : string with Code for each index (j: json, n: name, s: simple).
428            - name : name of the index
429        - **defcode** : String (default : 'j') - default list code (if 'all' is True)
430        - **all** : Boolean (default : True) - 'defcode apply to all indexes or none
431        - **lenres** : Integer (default : 0) - Number of raws (all if 0)
432        - **header** : Boolean (default : True) - First line with names
433        - **width** : Integer (default None) - Number of characters displayed for each
434        attribute (all if None)
435        - **ifunc** : function (default None) - function to apply to indexes
436        - **tabulate params** : default 'tablefmt': 'simple', 'numalign': 'left',
437        'stralign': 'left', 'floatfmt': '.3f' - See tabulate module
438        - **other kwargs** : parameter for ifunc
439
440        *Returns* : list or html table (tabulate format) '''
441        # print(kwargs)
442        opttab = {'defcode': 'j', 'all': True, 'lenres': 0, 'header': True}
443        optview = {'tablefmt': 'simple', 'numalign': 'decimal',
444                   'stralign': 'left', 'floatfmt': '.2f'}
445        option = opttab | optview | kwargs
446        tab = self._to_tab(**option)
447        width = ({'width': None} | kwargs)['width']
448        if width:
449            tab = [[(lambda x: x[:width] if isinstance(x, str) else x)(val)
450                    for val in lig] for lig in tab]
451        return tabulate(tab, headers='firstrow', **{k: option[k] for k in optview})

Generate tabular list to display data.

Parameters (kwargs)

  • name=listcode : element (default None) - eg location='ns'
    • listcode : string with Code for each index (j: json, n: name, s: simple).
    • name : name of the index
  • defcode : String (default : 'j') - default list code (if 'all' is True)
  • all : Boolean (default : True) - 'defcode apply to all indexes or none
  • lenres : Integer (default : 0) - Number of raws (all if 0)
  • header : Boolean (default : True) - First line with names
  • width : Integer (default None) - Number of characters displayed for each attribute (all if None)
  • ifunc : function (default None) - function to apply to indexes
  • tabulate params : default 'tablefmt': 'simple', 'numalign': 'left', 'stralign': 'left', 'floatfmt': '.3f' - See tabulate module
  • other kwargs : parameter for ifunc

Returns : list or html table (tabulate format)

def vlist(self, *args, func=None, index=-1, **kwargs):
453    def vlist(self, *args, func=None, index=-1, **kwargs):
454        '''
455        Apply a function to an index and return the result.
456
457        *Parameters*
458
459        - **func** : function (default none) - function to apply to extval or extidx
460        - **args, kwargs** : parameters for the function
461        - **index** : integer - index to update (index=-1 for first variable)
462
463        *Returns* : list of func result'''
464        if index == -1 and self.lvar:
465            return self.lvar[0].vlist(func, *args, **kwargs)
466        if index == -1 and self.lenindex == 1:
467            index = 0
468        return self.lindex[index].vlist(func, *args, **kwargs)

Apply a function to an index and return the result.

Parameters

  • func : function (default none) - function to apply to extval or extidx
  • args, kwargs : parameters for the function
  • index : integer - index to update (index=-1 for first variable)

Returns : list of func result