Commit b2e7cb71 authored by Sean Fitzgibbon's avatar Sean Fitzgibbon
Browse files

neurolucida ascii parser extracts more fields

color, closed, guid, resolution
parent 395170ba
......@@ -41,17 +41,91 @@ import numpy as np
# WANTED_SECTIONS = {
# 'Asterix': 0,
# }
# UNWANTED_SECTION_NAMES = [
# 'Color', 'Closed','Stereology','StereologyPropertyExtension','MBFObjectType','FillDensity', 'GUID', 'ImageCoords', 'MBFObjectType',
# 'Marker', 'Name', 'Resolution', 'Set', 'Description',
# 'Cross', 'Dot', 'DoubleCircle', 'FilledCircle', 'FilledDownTriangle',
# 'FilledSquare', 'FilledStar', 'FilledUpTriangle', 'FilledUpTriangle', 'Flower',
# 'Flower2', 'OpenCircle', 'OpenDiamond', 'OpenDownTriangle', 'OpenSquare', 'OpenStar',
# 'OpenUpTriangle', 'Plus', 'ShadedStar', 'Splat', 'TriStar', 'Sections', 'SSM', 'SSM2',
# ]
UNWANTED_SECTION_NAMES = [
'Color', 'Closed','Stereology','StereologyPropertyExtension','MBFObjectType','FillDensity', 'GUID', 'ImageCoords', 'MBFObjectType',
'Marker', 'Name', 'Resolution', 'Set', 'Description',
'Stereology','StereologyPropertyExtension','MBFObjectType','FillDensity', 'ImageCoords', 'MBFObjectType',
'Marker', 'Name', 'Set', 'Description',
'Cross', 'Dot', 'DoubleCircle', 'FilledCircle', 'FilledDownTriangle',
'FilledSquare', 'FilledStar', 'FilledUpTriangle', 'FilledUpTriangle', 'Flower',
'Flower2', 'OpenCircle', 'OpenDiamond', 'OpenDownTriangle', 'OpenSquare', 'OpenStar',
'OpenUpTriangle', 'Plus', 'ShadedStar', 'Splat', 'TriStar', 'Sections', 'SSM', 'SSM2',
'OpenUpTriangle', 'Plus', 'ShadedStar', 'Splat', 'TriStar', 'Sections', 'SSM', 'SSM2', 'Site'
]
UNWANTED_SECTIONS = {name: True for name in UNWANTED_SECTION_NAMES}
def is_number(s):
'''Test if string is a number'''
try:
float(s)
return True
except ValueError:
return False
def is_point(p):
'''Test if section looks like a point section'''
result = True
if len(p) != 5: result = False
if not all([is_number(n) for n in p[:-1]]): result = False
return result
def parse_point(p):
'''Parse a point section'''
return [float(p0) for p0 in p[:-1]] + [p[-1]]
def parse_contour(c0):
'''Convert contour section into a dictionary'''
c0_dict = {
'name': c0[0].replace('"',''),
}
points = []
for p in c0[1:]:
if p[0] == 'Closed':
c0_dict['closed'] = True
elif p[0] == 'Color':
c0_dict['color'] = p[1]
elif p[0] == 'GUID':
c0_dict['guid'] = p[1].replace('"','')
elif p[0] == 'Resolution':
c0_dict['resolution'] = float(p[1])
elif is_point(p):
points.append(parse_point(p)[:4])
else:
raise ValueError(f'Unknown property: ({p})')
c0_dict['points'] = np.array(points, dtype=np.float64)
return c0_dict
def parse_cell(cell):
'''Convert cell (asterisk) section into a dictionary'''
cell_dict = {}
for prop in cell[1:]:
if prop[0] == 'Color':
cell_dict['color'] = prop[1]
elif is_point(prop):
cell_dict['point'] = np.array(parse_point(prop)[:-1])
else:
raise ValueError(f'Unknown property: ({prop})')
return cell_dict
def _match_section(section, match):
'''checks whether the `type` of section is in the `match` dictionary
......@@ -178,15 +252,16 @@ def _flatten_subsection(subsection, _type, offset, parent):
yield _row
def _to_data(sections):
def to_data(sections):
# convert sections to dicts
cells = []
contour = []
for section in sections:
if section[0] == 'Asterisk': # Cell
cells.append( np.asarray(section[2][:4],dtype=np.float64) )
cells.append(parse_cell(section))
else:
contour.append((section[0].replace('"',''), np.asarray([s[:4] for s in section[1:]],dtype=np.float64)))
contour.append(parse_contour(section))
cells = np.asarray(cells)
......@@ -199,5 +274,7 @@ def read(file):
with open(file, encoding='utf-8', errors='replace') as fd:
sections = _parse_sections(fd)
contour, cells = _to_data(sections)
return contour, cells
\ No newline at end of file
contour, cells = to_data(sections)
return contour, cells
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment