Source code for soma.aims.io_ext

'''
IO formats readers / writers written in python for aims.

Currently:

Numpy format for matrices
YAML format for Object
'''


import numpy as np
import atexit
import sys
from . import gltf_io
aims = sys.modules['soma.aims']


[docs] class NpyFormat(aims.FileFormat_SparseOrDenseMatrix):
[docs] def read(self, filename, obj, context, options=None): mat = np.load(filename) # currently we need to perform a full copy of the array because # we cannot prevent it from deleting (when getting back to the C++ # layer the python wrapper is destroyed and any references it holds # also disapear. # Or we should manually increment the ref counter in the numpy PyObject # but it would never be destroyed then. #vol = aims.Volume(mat) #vol._npy = mat vol = aims.Volume(mat.shape, dtype=mat.dtype) np.asarray(vol)[:, :, 0, 0] = mat if isinstance(obj, aims.carto.AllocatorContext): # return the object variant options = context context = obj obj = aims.SparseOrDenseMatrix() obj.setMatrix(vol) return obj # otherwise fill in obj obj.setMatrix(vol) return True
[docs] def write(self, filename, obj, options): mat = np.asarray(obj.asDense()) np.save(filename, mat) hdr = obj.header() aims.write(hdr, '%s.minf' % filename) return True
[docs] class NpyFinderFormat(aims.FinderFormat):
[docs] def check(self, filename, finder): if filename.endswith('.npy'): hdr = { 'file_type': 'NPY', 'object_type': 'SparseMatrix', 'data_type': 'DOUBLE', } finder.setHeader(hdr) finder.setObjectType('SparseMatrix') finder.setDataType('DOUBLE') return True return False
aims.Finder.registerFormat('NUMPY', NpyFinderFormat(), ['npy']) aims.FileFormatDictionary_SparseOrDenseMatrix.registerFormat( 'NUMPY', NpyFormat(), ['npy']) # ---
[docs] class YamlFormat(aims.FileFormat_Object):
[docs] def read(self, filename, obj, context, options=None): import yaml with open(filename) as f: ydict = yaml.safe_load(f) if isinstance(obj, aims.carto.AllocatorContext): # return the object variant options = context context = obj obj = aims.Object(ydict) return obj obj.update(ydict) return True
[docs] def write(self, filename, obj, options): import yaml # yaml cannot automatically represent aims.Object instances class MyDumper(yaml.Dumper): def represent_data(self, data): if isinstance(data, (aims.Object, aims.carto.GenericObject)): try: if data.keys(): data = dict(data) else: data = list(data) except: pass elif type(data).__module__.startswith('soma.aims') \ and hasattr(type(data), '__getitem__'): data = list(data) return super().represent_data(data) with open(filename, 'w') as f: yaml.dump(obj, f, Dumper=MyDumper) return True
[docs] class YamlFinderFormat(aims.FinderFormat):
[docs] def check(self, filename, finder): if filename.endswith('.yaml'): hdr = { 'file_type': 'YAML', 'object_type': 'genericobject', 'data_type': 'any', } finder.setHeader(hdr) finder.setObjectType('genericobject') finder.setDataType('any') return True return False
aims.Finder.registerFormat('YAML', YamlFinderFormat(), ['yaml']) aims.FileFormatDictionary_Object.registerFormat( 'YAML', YamlFormat(), ['yaml'])
[docs] class GLTFFormat(aims.FileFormat_Object):
[docs] def read(self, filename, obj, context, options=None): meshes = gltf_io.load_gltf(filename) if isinstance(obj, aims.carto.AllocatorContext): # return the object variant options = context context = obj obj = aims.Object(meshes) return obj obj.update(meshes) return True
[docs] def write(self, filename, obj, options): opts = {} for opt in ('matrix', 'tex_format', 'images_as_buffers', 'single_buffer'): if opt in options: opts[opt] = options[opt] if not isinstance(obj, dict) and not ( hasattr(obj, 'isDictionary') and obj.isDictionary()): # not a dict-like object: consider it as a list of meshes obj = {'objects': [{'mesh': m} for m in obj]} gltf = gltf_io.meshes_dict_to_gltf(obj, **opts) use_draco = options.get('use_draco', True) gltf_io.save_gltf(gltf, filename, use_draco=use_draco) return True
[docs] class GLTFMeshFormat_3(aims.FileFormat_AimsTimeSurface_3_VOID):
[docs] def read(self, filename, obj, context, options=None): meshes = gltf_io.load_gltf(filename) mesh = meshes['objects'][0] while isinstance(mesh, list): mesh = mesh[0] mesh = mesh['mesh'] if isinstance(obj, aims.carto.AllocatorContext): # return the object variant options = context context = obj obj = mesh return obj obj.vertex().assign(mesh.vertex()) obj.normal().assign(mesh.normal()) obj.polygon().assign(mesh.polygon()) h = obj.header() for k in h: del h[k] h.update(mesh.header()) return True
[docs] def write(self, filename, obj, options): meshes = {'objects': [{'mesh': obj}]} return GLTFFormat().write(filename, meshes, options)
[docs] class GLTFMeshFormat_2(aims.FileFormat_AimsTimeSurface_2_VOID):
[docs] def read(self, filename, obj, context, options=None): meshes = gltf_io.load_gltf(filename) mesh = meshes['objects'][0] while isinstance(mesh, list): mesh = mesh[0] mesh = mesh['mesh'] if isinstance(obj, aims.carto.AllocatorContext): # return the object variant options = context context = obj obj = mesh return obj obj.vertex().assign(mesh.vertex()) obj.normal().assign(mesh.normal()) obj.polygon().assign(mesh.polygon()) h = obj.header() for k in h: del h[k] h.update(mesh.header()) return True
[docs] def write(self, filename, obj, options): meshes = {'objects': [{'mesh': obj}]} return GLTFFormat().write(filename, meshes, options)
[docs] class GLTFFinderFormat(aims.FinderFormat):
[docs] def check(self, filename, finder): if filename.endswith('.gltf') or filename.endswith('.glb'): hdr = { 'file_type': 'GLTF', 'object_type': 'genericobject', 'data_type': 'any', } finder.setHeader(hdr) finder.setObjectType('genericobject') finder.setDataType('any') finder.setFormat('GLTF') return True return False
aims.Finder.registerFormat('GLTF', GLTFFinderFormat(), ['gltf', 'glb']) aims.FileFormatDictionary_Object.registerFormat( 'GLTF', GLTFFormat(), ['gltf', 'glb']) aims.FileFormatDictionary_AimsTimeSurface_3_VOID.registerFormat( 'GLTF', GLTFMeshFormat_3(), ['gltf', 'glb']) aims.FileFormatDictionary_AimsTimeSurface_2_VOID.registerFormat( 'GLTF', GLTFMeshFormat_2(), ['gltf', 'glb']) def remove_python_formats(): aims.Finder.unregisterFormat('NUMPY') aims.Finder.unregisterFormat('YAML') aims.Finder.unregisterFormat('GLTF') aims.FileFormatDictionary_SparseOrDenseMatrix.unregisterFormat('NUMPY') aims.FileFormatDictionary_Object.unregisterFormat('YAML') aims.FileFormatDictionary_Object.unregisterFormat('GLTF') aims.FileFormatDictionary_AimsTimeSurface_3_VOID.unregisterFormat('GLTF') aims.FileFormatDictionary_AimsTimeSurface_2_VOID.unregisterFormat('GLTF') atexit.register(remove_python_formats)