1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
|
# Authors: Alexandre Gramfort <alexandre.gramfort@inria.fr>
# Matti Hämäläinen <msh@nmr.mgh.harvard.edu>
#
# License: BSD-3-Clause
import numpy as np
from .constants import FIFF
from .tag import Tag
from .tag import read_tag
from .write import write_id, start_block, end_block, _write
from ..utils import logger, verbose
def dir_tree_find(tree, kind):
"""Find nodes of the given kind from a directory tree structure.
Parameters
----------
tree : dict
Directory tree.
kind : int
Kind to find.
Returns
-------
nodes : list
List of matching nodes.
"""
nodes = []
if isinstance(tree, list):
for t in tree:
nodes += dir_tree_find(t, kind)
else:
# Am I desirable myself?
if tree['block'] == kind:
nodes.append(tree)
# Search the subtrees
for child in tree['children']:
nodes += dir_tree_find(child, kind)
return nodes
@verbose
def make_dir_tree(fid, directory, start=0, indent=0, verbose=None):
"""Create the directory tree structure."""
FIFF_BLOCK_START = 104
FIFF_BLOCK_END = 105
FIFF_FILE_ID = 100
FIFF_BLOCK_ID = 103
FIFF_PARENT_BLOCK_ID = 110
if directory[start].kind == FIFF_BLOCK_START:
tag = read_tag(fid, directory[start].pos)
block = tag.data
else:
block = 0
logger.debug(' ' * indent + 'start { %d' % block)
this = start
tree = dict()
tree['block'] = block
tree['id'] = None
tree['parent_id'] = None
tree['nent'] = 0
tree['nchild'] = 0
tree['directory'] = directory[this]
tree['children'] = []
while this < len(directory):
if directory[this].kind == FIFF_BLOCK_START:
if this != start:
child, this = make_dir_tree(fid, directory, this, indent + 1)
tree['nchild'] += 1
tree['children'].append(child)
elif directory[this].kind == FIFF_BLOCK_END:
tag = read_tag(fid, directory[start].pos)
if tag.data == block:
break
else:
tree['nent'] += 1
if tree['nent'] == 1:
tree['directory'] = list()
tree['directory'].append(directory[this])
# Add the id information if available
if block == 0:
if directory[this].kind == FIFF_FILE_ID:
tag = read_tag(fid, directory[this].pos)
tree['id'] = tag.data
else:
if directory[this].kind == FIFF_BLOCK_ID:
tag = read_tag(fid, directory[this].pos)
tree['id'] = tag.data
elif directory[this].kind == FIFF_PARENT_BLOCK_ID:
tag = read_tag(fid, directory[this].pos)
tree['parent_id'] = tag.data
this += 1
# Eliminate the empty directory
if tree['nent'] == 0:
tree['directory'] = None
logger.debug(' ' * (indent + 1) + 'block = %d nent = %d nchild = %d'
% (tree['block'], tree['nent'], tree['nchild']))
logger.debug(' ' * indent + 'end } %d' % block)
last = this
return tree, last
###############################################################################
# Writing
def copy_tree(fidin, in_id, nodes, fidout):
"""Copy directory subtrees from fidin to fidout."""
if len(nodes) <= 0:
return
if not isinstance(nodes, list):
nodes = [nodes]
for node in nodes:
start_block(fidout, node['block'])
if node['id'] is not None:
if in_id is not None:
write_id(fidout, FIFF.FIFF_PARENT_FILE_ID, in_id)
write_id(fidout, FIFF.FIFF_BLOCK_ID, in_id)
write_id(fidout, FIFF.FIFF_PARENT_BLOCK_ID, node['id'])
if node['directory'] is not None:
for d in node['directory']:
# Do not copy these tags
if d.kind == FIFF.FIFF_BLOCK_ID or \
d.kind == FIFF.FIFF_PARENT_BLOCK_ID or \
d.kind == FIFF.FIFF_PARENT_FILE_ID:
continue
# Read and write tags, pass data through transparently
fidin.seek(d.pos, 0)
tag = Tag(*np.fromfile(fidin, ('>i4,>I4,>i4,>i4'), 1)[0])
tag.data = np.fromfile(fidin, '>B', tag.size)
_write(fidout, tag.data, tag.kind, 1, tag.type, '>B')
for child in node['children']:
copy_tree(fidin, in_id, child, fidout)
end_block(fidout, node['block'])
|