|  | @@ -52,6 +52,35 @@ def setlocale(temporary_locale):
 | 
											
												
													
														|  |  Vertex = collections.namedtuple('Vertex', ['right', 'anterior', 'superior'])
 |  |  Vertex = collections.namedtuple('Vertex', ['right', 'anterior', 'superior'])
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +class Annotation:
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    # pylint: disable=too-few-public-methods
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    _TAG_OLD_COLORTABLE = b'\0\0\0\x01'
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    def __init__(self):
 | 
											
												
													
														|  | 
 |  | +        self.vertex_values = {}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    def _read(self, stream: typing.BinaryIO) -> None:
 | 
											
												
													
														|  | 
 |  | +        # https://surfer.nmr.mgh.harvard.edu/fswiki/LabelsClutsAnnotationFiles
 | 
											
												
													
														|  | 
 |  | +        annotations_num, = struct.unpack('>I', stream.read(4))
 | 
											
												
													
														|  | 
 |  | +        annotations = (struct.unpack('>II', stream.read(4 * 2))
 | 
											
												
													
														|  | 
 |  | +                       for _ in range(annotations_num))
 | 
											
												
													
														|  | 
 |  | +        self.vertex_values = {vertex_index: annotation_value
 | 
											
												
													
														|  | 
 |  | +                              for vertex_index, annotation_value in annotations}
 | 
											
												
													
														|  | 
 |  | +        assert all((annotation_value >> (8 * 3)) == 0
 | 
											
												
													
														|  | 
 |  | +                   for annotation_value in self.vertex_values.values())
 | 
											
												
													
														|  | 
 |  | +        assert stream.read(4) == self._TAG_OLD_COLORTABLE
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    @classmethod
 | 
											
												
													
														|  | 
 |  | +    def read(cls, annotation_file_path: str) -> 'Annotation':
 | 
											
												
													
														|  | 
 |  | +        annotation = cls()
 | 
											
												
													
														|  | 
 |  | +        with open(annotation_file_path, 'rb') as annotation_file:
 | 
											
												
													
														|  | 
 |  | +            # pylint: disable=protected-access
 | 
											
												
													
														|  | 
 |  | +            annotation._read(annotation_file)
 | 
											
												
													
														|  | 
 |  | +        return annotation
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |  class Surface:
 |  |  class Surface:
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      # pylint: disable=too-many-instance-attributes
 |  |      # pylint: disable=too-many-instance-attributes
 | 
											
										
											
												
													
														|  | @@ -61,10 +90,11 @@ class Surface:
 | 
											
												
													
														|  |      _TAG_CMDLINE = b'\x00\x00\x00\x03'
 |  |      _TAG_CMDLINE = b'\x00\x00\x00\x03'
 | 
											
												
													
														|  |      _TAG_OLD_SURF_GEOM = b'\x00\x00\x00\x14'
 |  |      _TAG_OLD_SURF_GEOM = b'\x00\x00\x00\x14'
 | 
											
												
													
														|  |      _TAG_OLD_USEREALRAS = b'\x00\x00\x00\x02'
 |  |      _TAG_OLD_USEREALRAS = b'\x00\x00\x00\x02'
 | 
											
												
													
														|  | -    _TAG_OLD_COLORTABLE = b'\0\0\0\x01'
 |  | 
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      _DATETIME_FORMAT = '%a %b %d %H:%M:%S %Y'
 |  |      _DATETIME_FORMAT = '%a %b %d %H:%M:%S %Y'
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +    annotation: typing.Optional[Annotation] = None
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |      def __init__(self):
 |  |      def __init__(self):
 | 
											
												
													
														|  |          self.creator = None
 |  |          self.creator = None
 | 
											
												
													
														|  |          self.creation_datetime = None
 |  |          self.creation_datetime = None
 | 
											
										
											
												
													
														|  | @@ -73,7 +103,6 @@ class Surface:
 | 
											
												
													
														|  |          self.using_old_real_ras = False
 |  |          self.using_old_real_ras = False
 | 
											
												
													
														|  |          self.volume_geometry_info = None
 |  |          self.volume_geometry_info = None
 | 
											
												
													
														|  |          self.command_lines = []
 |  |          self.command_lines = []
 | 
											
												
													
														|  | -        self.vertex_annotation_values = None
 |  | 
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      @classmethod
 |  |      @classmethod
 | 
											
												
													
														|  |      def _read_cmdlines(cls, stream: typing.BinaryIO) -> typing.Iterator[str]:
 |  |      def _read_cmdlines(cls, stream: typing.BinaryIO) -> typing.Iterator[str]:
 | 
											
										
											
												
													
														|  | @@ -155,20 +184,12 @@ class Surface:
 | 
											
												
													
														|  |                  surface_file.write(self._TAG_CMDLINE + struct.pack('>Q', len(command_line) + 1)
 |  |                  surface_file.write(self._TAG_CMDLINE + struct.pack('>Q', len(command_line) + 1)
 | 
											
												
													
														|  |                                     + command_line + b'\0')
 |  |                                     + command_line + b'\0')
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -    def load_annotation(self, annotation_file_path: str) -> None:
 |  | 
 | 
											
												
													
														|  | -        # https://surfer.nmr.mgh.harvard.edu/fswiki/LabelsClutsAnnotationFiles
 |  | 
 | 
											
												
													
														|  | -        with open(annotation_file_path, 'rb') as annotation_file:
 |  | 
 | 
											
												
													
														|  | -            annotations_num, = struct.unpack('>I', annotation_file.read(4))
 |  | 
 | 
											
												
													
														|  | -            assert annotations_num <= len(self.vertices)
 |  | 
 | 
											
												
													
														|  | -            annotations = (struct.unpack('>II', annotation_file.read(4 * 2))
 |  | 
 | 
											
												
													
														|  | -                           for _ in range(annotations_num))
 |  | 
 | 
											
												
													
														|  | -            self.vertex_annotation_values = {vertex_index: annotation_value
 |  | 
 | 
											
												
													
														|  | -                                             for vertex_index, annotation_value in annotations}
 |  | 
 | 
											
												
													
														|  | -            assert all(0 <= vertex_index < len(self.vertices)
 |  | 
 | 
											
												
													
														|  | -                       for vertex_index in self.vertex_annotation_values.keys())
 |  | 
 | 
											
												
													
														|  | -            assert all((annotation_value >> (8 * 3)) == 0
 |  | 
 | 
											
												
													
														|  | -                       for annotation_value in self.vertex_annotation_values.values())
 |  | 
 | 
											
												
													
														|  | -            assert annotation_file.read(4) == self._TAG_OLD_COLORTABLE
 |  | 
 | 
											
												
													
														|  | 
 |  | +    def load_annotation_file(self, annotation_file_path: str) -> None:
 | 
											
												
													
														|  | 
 |  | +        annotation = Annotation.read(annotation_file_path)
 | 
											
												
													
														|  | 
 |  | +        assert len(annotation.vertex_values) <= len(self.vertices)
 | 
											
												
													
														|  | 
 |  | +        assert all(0 <= vertex_index < len(self.vertices)
 | 
											
												
													
														|  | 
 |  | +                   for vertex_index in annotation.vertex_values.keys())
 | 
											
												
													
														|  | 
 |  | +        self.annotation = annotation
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      def add_vertex(self, vertex: Vertex) -> int:
 |  |      def add_vertex(self, vertex: Vertex) -> int:
 | 
											
												
													
														|  |          self.vertices.append(vertex)
 |  |          self.vertices.append(vertex)
 |