root/branches/packaged_tools/NeuroTools/HDF5Tools/HDF5Factory/generator.py @ 162

Revision 162, 24.4 KB (checked in by brizzi, 5 years ago)

Codejam2 version

Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3
4"""
5HDF5 Tools for FACETS
6Low-level API
7
8Creates hdf5 objects. Handles classic pytables objects like Arrays, CArrays, EArrays, VLArrays and Tables, specific NeuroTools objects like SpikeTrains and SpikeLists and all kind of python objects with serialization mechanisms. Functions deal with default compression level (9), possibility to add directly attributes relative to a node and erase an existing one (tags and overwrite parameters).
9
10Thierry Brizzi, Andrew Davison, Laurent Perrinet, Pierre Yger, INCM & UNIC, CNRS -- March 2008
11
12$ Id $
13
14"""
15
16from ..tables.parameters import EXPECTED_ROWS_TABLE
17from ..tables.file import _checkfilters
18from NeuroTools.PythonObjects.spikes import SpikeTrain, SpikeList
19from NeuroTools.HDF5Tools.HDF5Objects import h5spiketrain, h5spikelist, h5serializer, h5image, h5movie
20from ..tables import File, Node, Atom, Filters
21
22class HDF5Object(File) :
23    """Gives new functionalities to the pytables File base class about objects insertions in a hdf5 file tree."""
24   
25    def _overwrite(self, where, name) :
26        """Removes a specific node in the file tree in object creation context."""
27       
28        assert where and name, "where and name parameter should not be 'void'"
29        assert (isinstance(where, str) and isinstance(name, str)), "where and name parameters should be strings because of object creation context."
30       
31        if where == '/' :
32            path = where + name
33        else :
34            path = where + "/" + name
35        if self.__contains__(path) :
36            self.removeNode(where, name, recursive = True)
37       
38        assert not self.__contains__(path), "problem during node deletion."   
39 
40    def createGroup(self, where, name, tags=None, title='', createparents=False, overwrite=False) :
41       
42        if overwrite :
43            self._overwrite(where, name)
44        filters = Filters(complevel=9, complib='zlib', shuffle=1, fletcher32=1)   
45        group = super(HDF5Object, self).createGroup(where, name, title, filters, createparents)
46        if tags :
47            for tag in tags :
48                setattr(group, tag, tags[tag])
49        return group
50
51    def createTable(self, where, name, description, tags=None, title='', expectedrows=10000,
52                                createparents=False, overwrite = False, chunkshape=None, byteorder=None) :
53        if overwrite :
54            self._overwrite(where, name)
55        filters = Filters(complevel=9, complib='zlib', shuffle=1, fletcher32=1)
56        table = super(HDF5Object, self).createTable(where, name, description, title, filters, 
57                                                                            expectedrows, chunkshape, byteorder, 
58                                                                            createparents)
59        if tags :
60            for tag in tags :
61                setattr(group, tag, tags[tag])
62        return tables
63
64    def createArray(self, where, name, object, tags=None, title='', 
65                                createparents=False, overwrite=False, byteorder=None) :
66        if overwrite :
67            self._overwrite(where, name)
68        h5array = super(HDF5Object, self).createArray(where, name, object, title, byteorder, createparents)
69        if tags :
70            for tag in tags :
71                setattr(group, tag, tags[tag])
72        return h5array
73
74    def createCArray(self, where, name, atom, shape, tags=None, title='',
75                                  createparents=False, overwrite = False, chunkshape=None, byteorder=None) :
76        if overwrite :
77            self._overwrite(where, name)
78        filters = Filters(complevel=9, complib='zlib', shuffle=1, fletcher32=1)
79        carray = super(HDF5Object, self).createCArray(where, name, atom, shape, title, filters, 
80                                                                                chunkshape, byteorder, createparents)
81        if tags :
82            for tag in tags :
83                setattr(group, tag, tags[tag])
84        return carray
85   
86    def createEArray(self, where, name, atom, shape, tags=None, title='', 
87                                 expectedrows=1000, createparents=False, 
88                                 overwrite = False, chunkshape=None, byteorder=None) :
89        if overwrite :
90            self._overwrite(where, name)
91        filters = Filters(complevel=9, complib='zlib', shuffle=1, fletcher32=1)
92        earry = super(HDF5Object, self).createEArray(where, name, atom, shape, title,
93                                                                   filters, expectedrows, chunkshape, 
94                                                                   byteorder, createparents)
95        if tags :
96            for tag in tags :
97                setattr(group, tag, tags[tag])
98        return earray
99
100    def createVLArray(self, where, name, tags=None, atom=None, title='', 
101                                    expectedsizeinMB=1.0, createparents=False, 
102                                    overwrite = False, chunkshape=None, byteorder=None) :
103        if overwrite :
104            self._overwrite(where, name)
105        filters = Filters(complevel=9, complib='zlib', shuffle=1, fletcher32=1)
106        vlarray = super(HDF5Object, self).createVLArray(where, name, atom, title,
107                                                                    filters, expectedsizeinMB,
108                                                                    chunkshape, byteorder,
109                                                                    createparents)
110        if tags :
111            for tag in tags :
112                setattr(group, tag, tags[tag])
113        return vlarray
114   
115##    def createAdvancedTable(self, where, name, description, rows = None, title="",
116##                                                filters=None, expectedrows=10000,
117##                                                chunkshape=None, byteorder=None,
118##                                                createparents=False, overwrite =False):
119##        if overwrite :
120##            self._overwrite(where, name)
121##        parentNode = self._getOrCreatePath(where, createparents)
122##        fprops = _checkfilters(filters)
123##        advancedtable = AdvancedTable(parentNode, name, description=description, title=title,
124##                                                            filters=fprops, expectedrows=expectedrows,
125##                                                            chunkshape=chunkshape, byteorder=byteorder)
126##        if rows != None :
127##            advancedtable.append(rows)
128##        return advancedtable
129   
130    def createSpikeTrain(self, spiketrain, where, name, title = '', tags = None, createparents = False, overwrite = False) :
131       
132        assert isinstance(spiketrain, SpikeTrain), "A H5SpikeTrain Object must be initialized with a SpikeTrain one."
133        assert (tags == None) or isinstance(tags, dict), "Tags must be None or a dictionary."
134       
135        if overwrite :
136            self._overwrite(where, name)
137       
138        parentNode = self._getOrCreatePath(where, createparents)
139        return h5spiketrain.H5SpikeTrain(parentNode, name, spiketrain = spiketrain, title = title, tags = tags, _open = True)
140   
141    def retrieveSpikeTrain(self, node) :
142        if not isinstance(node, Node) :
143            node = self.getNode(node)
144        assert isinstance(node, h5spiketrain.H5SpikeTrain), "The node must correspond to a H5SpikeTrain object."
145        dt = node._v_attrs.dt
146        spike_times = [k*dt for k in node.read()]
147        return SpikeTrain(spike_times, dt = dt, t_start = node._v_attrs.t_start, t_stop = node._v_attrs.t_stop)
148   
149    def createSpikeList(self, spikelist, where, name, title = "", tags=None, createparents=False, 
150                                      overwrite = False, expectedsizeinMB = 1.0) :
151       
152        assert  isinstance(spikelist, SpikeList), "A H5SpikeList Object must be initialized with a SpikeList one."
153        assert (tags == None) or isinstance(tags, dict), "Tags must be None or a dictionary."
154       
155        if overwrite :
156            self._overwrite(where, name)
157        parentNode = self._getOrCreatePath(where, createparents)
158        return h5spikelist.H5SpikeList(parentNode, name, spikelist = spikelist, title=title, tags = tags, expectedsizeinMB = expectedsizeinMB, _open = True) 
159   
160    def retrieveSpikeList(self, node) :
161        if not isinstance(node, Node) :
162            node = self.getNode(node)
163        assert isinstance(node, h5spikelist.H5SpikeList), "The node must correspond to a H5SpikeList object."
164        dt = node._v_attrs.dt
165        id_list = []
166        spikes = []
167        for row in node.read() :
168            id = row[0]
169            id_list.append(id)
170            for time in row[1:] :
171                spikes.append((id, time * dt))
172        return SpikeList(spikes, id_list, dt = dt, t_start = node._v_attrs.t_start, t_stop = node._v_attrs.t_stop)
173   
174    def createSerializer(self, objects, where, name, title = "", tags=None, createparents=False, 
175                                       overwrite = False, expectedsizeinMB = 1.0) :
176        assert isinstance(objects, list)
177        assert (tags == None) or isinstance(tags, dict), "Tags must be None or a dictionary."
178##        for obj in objects :
179##            assert issubclass(type(obj), object), "Objects must be a subclass of python base object class."
180       
181        if overwrite :
182            self._overwrite(where, name)
183        parentNode = self._getOrCreatePath(where, createparents)
184        return h5serializer.H5Serializer(objects, parentNode, name, title=title, tags = tags, expectedsizeinMB = expectedsizeinMB, _open = True) 
185   
186    def retrieveSerializer(self, where, row = None, column = None) :
187        node = self.getNode(where)
188        assert isinstance(node, h5serializer.H5Serializer), "The node must correspond to a H5Serializer object."
189        if (row != None) and (column != None) :
190            try :
191                return node.read(start = row)[0][column]
192            except :
193                raise "No object stored at these coordinates."
194        elif row != None :
195            try :
196                return node.read(start = row)[0]
197            except :
198                raise "No object stored at this row"
199        elif column != None :
200            object_list = []
201            for row in node.read() :
202                cnt = 0
203                for col in row :
204                    if cnt == column :
205                        object_list.append(row[cnt])
206                    cnt += 1
207            if len(object_list) < 1 :
208                raise "No object stored at this column." 
209            else :
210                return object_list
211        else :
212            return node.read()
213   
214    def createImage(self, url, where, name, interlace = "INTERLACE_PIXEL", title = '', tags = None, createparents=False, overwrite = False) :
215       
216        if overwrite :
217            self._overwrite(where, name)
218        parentNode = self._getOrCreatePath(where, createparents)
219        return h5image.H5Image(parentNode, name, url=url, interlace = interlace, title = title, tags=tags, _open = True)
220   
221    def convertImage(self, url, node, format = 'png') :
222        if not isinstance(node, Node) :
223            node = self.getNode(node)
224        assert isinstance(node, h5image.H5Image), "The node must correspond to a H5Image object."
225        node.convert(url, format)
226   
227    def retrieveImage(self, url, node, format = 'png') :
228        if not isinstance(node, Node) :
229            node = self.getNode(node)
230        assert isinstance(node, h5image.H5Image), "The node must correspond to a H5Image object."
231        return node.retrieve(url, format)
232   
233    def createMovie(self, url, where, name, interlace = "INTERLACE_PIXEL",title = '', frame_duration = None, tags=None, createparents=False, overwrite = False) :
234       
235        if overwrite :
236            self._overwrite(where, name)
237        parentNode = self._getOrCreatePath(where, createparents)
238        return h5movie.H5Movie(parentNode, name, url=url, interlace = interlace, title = title, frame_duration=frame_duration, tags=tags, _open = True)
239   
240    def createVLMovie(self, url, where, name, interlace = "INTERLACE_PIXEL",title = '', createparents=False, overwrite = False) :
241       
242        if overwrite :
243            self._overwrite(where, name)
244        parentNode = self._getOrCreatePath(where, createparents)
245        return h5movie.H5VLMovie(parentNode, name, url=url, _open = True)
246   
247    def convertMovie(self, url, node, format = 'png') :
248        if not isinstance(node, Node) :
249            node = self.getNode(node)
250        assert isinstance(node, h5movie.H5Movie), "The node must correspond to a H5Movie object."
251        node.convert(url, format)
252   
253    def retrieveMovie(self, url, node, format = 'png') :
254        if not isinstance(node, Node) :
255            node = self.getNode(node)
256        assert isinstance(node, h5movie.H5Movie), "The node must correspond to a H5Movie object."
257        return node.retrieve(url, format)
258   
259    ##    def createSpikeList(self, where, name, dt = None, spec = 'reltime_id', ref = None, rows = None, title = "", filters=None, expectedrows=EXPECTED_ROWS_TABLE, compress=None, complib=None,  # deprecated
260##                                                    createparents=False, overwrite = False) :
261##        """Create a new spikelist into the HDF5 file.
262##
263##        Arguments :
264##
265##        where -- The parent group where the new spikelist will hang
266##            from. "where" parameter can be a path string (for example
267##            "/level1/leaf5"), or Group instance.
268##
269##        name -- The name of the new spikelist.
270##
271##        dt -- The sampling time
272##
273##        spec -- The specification keyword. Only 'reltime_id' is implemented.
274##                      In future it would change the SpikeList 'description' format storage in HDF5 File.
275##
276##        title -- Sets a TITLE attribute on the table entity.
277##
278##        filters -- An instance of the Filters class that provides
279##        information about the desired I/O filters to be applied
280##        during the life of this object.
281##
282##        expectedrows -- An user estimate about the number of rows that
283##        will be on table. If not provided, the default value is
284##        10000. If you plan to save bigger tables try providing a
285##        guess; this will optimize the HDF5 B-Tree creation and
286##        management process time and the amount of memory used.
287##
288##        createparents -- Whether to create the needed groups for the
289##        parent path to exist (not done by default).
290##        """
291##        #TODO : Add more specifications possibilities
292##        try :
293##            if overwrite == True :
294##                if self.isVisibleNode(where + "/" + name):
295##                    self.removeNode(where, name)
296##        except NoSuchNodeError, error :
297##            pass ##print 'Erreur : %s. But it is okay.' % str(error)
298##
299##        if ref != None :
300##            ref = self.walkNodes(ref).next()
301##        parentNode = self._getOrCreatePath(where, createparents)
302##        fprops = _checkfilters(filters) #, compress, complib)
303##        spikelist = SpikeList(parentNode, name, dt = dt, spec = spec, ref = ref, title=title,
304##                                                filters=fprops, expectedrows=expectedrows, _open = True)
305##        if (rows != None) :
306##            if (len(rows) != 0) & (not isinstance(rows, str)) & (not isinstance(rows, int)) &  (not isinstance(rows, float)) & (not isinstance(rows, float)) & (not isinstance(rows, dict)):
307##                spikelist.append(rows)
308##        return spikelist
309
310    def createNeuronIndex(self, where, name, ref = None, spec = 'int_2D', rows = None,
311                                                            title="", filters=None, expectedrows = EXPECTED_ROWS_TABLE,
312                                                            compress=None, complib=None,  # deprecated
313                                                            createparents=False, overwrite = False) :
314        """Create a new neuron index corresponding to an existing spikelist.
315
316        Arguments :
317
318        where -- The parent group where the new spikelist will hang
319        from. "where" parameter can be a path string (for example
320        "/level1/leaf5"), or Group instance.
321
322        name -- The name of the new spikelist.
323
324        ref -- The complete path of the corresponding SpikeList node.
325
326        spec -- The specification keyword :
327
328                    if spec = 'float_3D' the neuron index table is define like :
329
330                        class NeuronIndexDescription(IsDescription) :
331                            neuron_id = Int64Col()
332                            pos_x = float64Col()
333                            pos_y = float64Col()
334                            pos_z = float64Col()
335
336                    if spec = 'float_3D' the neuron index is define like this :
337
338                        class NeuronIndexDescription(IsDescription) :
339                            neuron_id = Int64Col()
340                            pos_x = int64Col()
341                            pos_y = Int64Col()
342                            pos_z = Int64Col()
343
344                    if spec = 'int_2D' is defined like this :
345
346                        class NeuronIndexDescription(IsDescription) :
347                                neuron_id = Int64Col()
348                                pos_x = Int64Col()
349                                pos_y = Int64Col()
350                                layer = UInt64Col()
351
352                    if spec = 'float_2D' is defined like this :
353
354                        class NeuronIndexDescription(IsDescription) :
355                                neuron_id = Int64Col()
356                                pos_x = Float64Col()
357                                pos_y = Float64Col()
358                                layer = UInt64Col()
359
360        title -- Sets a TITLE attribute on the table entity.
361
362        filters -- An instance of the Filters class that provides
363        information about the desired I/O filters to be applied
364        during the life of this object.
365
366        expectedrows -- An user estimate about the number of rows that
367        will be on table. If not provided, the default value is
368        10000. If you plan to save bigger tables try providing a
369        guess; this will optimize the HDF5 B-Tree creation and
370        management process time and the amount of memory used.
371
372        createparents -- Whether to create the needed groups for the
373        parent path to exist (not done by default).
374
375        """
376        try :
377            if overwrite == True :
378                if self.isVisibleNode(where + "/" + name):
379                    self.removeNode(where, name)
380        except NoSuchNodeError, error :
381            pass ##print 'Erreur : %s. But it is okay.' % str(error)
382
383        if ref != None :
384            ref = self.walkNodes(ref).next()
385        parentNode = self._getOrCreatePath(where, createparents)
386        fprops = _checkfilters(filters) #, compress, complib)
387        neuronindex = NeuronIndex(parentNode, name, spec = spec, ref = ref,
388                                                                    title=title, filters=fprops, expectedrows=expectedrows, _open = True)
389        if rows != None :
390            neuronindex.append(rows)
391        return neuronindex
392
393    def createSpikingNeurons(self, where, name, dt = None, spec = 'reltime_size_ids', ref = None, title="", rows = None,
394                                                                    filters=None, expectedsizeinMB=1.0,
395                                                                    compress=None, complib=None,
396                                                                    createparents=False, overwrite = False):
397            """Create a new instance SpikingNeurons with name "name" in "where" location.
398
399            Keyword arguments:
400
401            where -- The parent group where the new table will hang
402                from. "where" parameter can be a path string (for example
403                "/level1/leaf5"), or Group instance.
404
405            name -- The name of the new array.
406
407            title -- Sets a TITLE attribute on the array entity.
408
409            atom -- A Atom object representing the shape, type and flavor
410                of the atomic object to be saved.
411
412            dt -- The sampling time
413
414            spec -- The specification keyword. Only 'reltime_id' is implemented.
415                      In future it would change the SpikeList 'description' format storage in HDF5 File.
416
417            filters -- An instance of the Filters class that provides
418                information about the desired I/O filters to be applied
419                during the life of this object.
420
421            expectedsizeinMB -- An user estimate about the size (in MB) in
422                the final VLArray object. If not provided, the default
423                value is 1 MB.  If you plan to create both much smaller or
424                much bigger Arrays try providing a guess; this will
425                optimize the HDF5 B-Tree creation and management process
426                time and the amount of memory used.
427
428            createparents -- Whether to create the needed groups for the
429                parent path to exist (not done by default).
430            """
431            try :
432                if overwrite == True :
433                    if self.isVisibleNode(where + "/" + name):
434                        self.removeNode(where, name)
435            except NoSuchNodeError, error :
436                pass ##print 'Erreur : %s. But it is okay.' % str(error)
437
438            if ref != None :
439                ref = self.walkNodes(ref).next()
440            parentNode = self._getOrCreatePath(where, createparents)
441            fprops = _checkfilters(filters) #, compress, complib)
442            spikingneurons = SpikingNeurons(parentNode, name, dt = None,  spec = 'reltime_size_ids', ref = ref,
443                                                                                    title=title, filters=fprops,
444                                                                                    expectedsizeinMB=expectedsizeinMB, _open = True)
445            if rows != None :
446                if (len(rows) != 0) & (not isinstance(rows, str)) & (not isinstance(rows, int)) &  (not isinstance(rows, float)) & (not isinstance(rows, float)) & (not isinstance(rows, dict)):
447                    for row in rows :
448                        spikingneurons.append(row)
449            return spikingneurons
450
451   
452
453##    def createMovie(self, where, name, url, coding = 64, subclass = 'MOVIE_COLOR',
454##                         title = '', complevel = 0, createparents=False, # flavor = 'numpy',
455##                         expectedsizeinMB=1.0, compress=None, complib=None, overwrite=False,
456##                         frame_duration=40.0):
457##
458##        try :
459##            if overwrite == True :
460##                if self.isVisibleNode(where + "/" + name):
461##                    self.removeNode(where, name)
462##        except NoSuchNodeError, error :
463##            pass ##print 'Erreur : %s. But it is okay.' % str(error)
464##
465##        if (subclass != "MOVIE_COLOR") & (subclass != "MOVIE_GREYSCALE") : raise "Not implemented case."
466##        filters = Filters(complevel=complevel, complib='zlib')
467##        parentNode = self._getOrCreatePath(where, createparents)
468##        fprops = _checkfilters(filters) #, compress, complib)
469##        movie = Movie(parentNode, name, url, coding=coding, subclass=subclass,
470##                          title=title, filters=filters, #flavor=flavor,
471##                          expectedsizeinMB=expectedsizeinMB,  _open=True,
472##                          frame_duration=frame_duration)
473##        return movie
474##
475##    def createCMovie(self, where, name, url, coding = 64, subclass = 'MOVIE_COLOR',
476##                         title = '', complevel = 0, createparents=False, #flavor = 'numpy',
477##                         compress=None, complib=None, overwrite=False,
478##                         frame_duration=40.0):
479##
480##        try :
481##            if overwrite == True :
482##                if self.isVisibleNode(where + "/" + name):
483##                    self.removeNode(where, name)
484##        except NoSuchNodeError, error :
485##            pass ##print 'Erreur : %s. But it is okay.' % str(error)
486##
487##        if (subclass != "MOVIE_COLOR") & (subclass != "MOVIE_GREYSCALE") : raise "Not implemented case."
488##        filters = Filters(complevel=complevel, complib='zlib')
489##        parentNode = self._getOrCreatePath(where, createparents)
490##        fprops = _checkfilters(filters) #, compress, complib)
491##        movie = CMovie(parentNode, name, url, coding=coding, subclass=subclass,
492##                          title=title, filters=filters, #flavor=flavor,
493##                          _open=True, frame_duration=frame_duration)
494##        return movie
495
Note: See TracBrowser for help on using the browser.