예제 #1
0
    def test_sensors(self):

        dt = sensors.Sensors(load_default=True)
        dt.configure()

        summary_info = dt.summary_info
        self.assertEqual(summary_info['Sensor type'], '')
        self.assertEqual(summary_info['Number of Sensors'], 62)
        self.assertFalse(dt.has_orientation)
        self.assertEqual(dt.labels.shape, (62, ))
        self.assertEqual(dt.locations.shape, (62, 3))
        self.assertEqual(dt.number_of_sensors, 62)
        self.assertEqual(dt.orientations.shape, (0, ))
        self.assertEqual(dt.sensors_type, '')

        ## Mapping 62 sensors on a Skin surface should work
        surf = SkinAir(load_default=True)
        surf.configure()
        mapping = dt.sensors_to_surface(surf)
        self.assertEqual(mapping.shape, (62, 3))

        ## Mapping on a surface with holes should fail
        dummy_surf = SkinAir()
        dummy_surf.vertices = numpy.array(range(30)).reshape(10, 3)
        dummy_surf.triangles = numpy.array(range(9)).reshape(3, 3)
        dummy_surf.configure()
        try:
            dt.sensors_to_surface(dummy_surf)
            self.fail("Should have failed for this simple surface!")
        except Exception:
            pass
예제 #2
0
    def test_sensors(self):

        dt = sensors.Sensors(load_file="eeg_brainstorm_65.txt")
        dt.configure()

        summary_info = dt._find_summary_info()
        assert summary_info['Sensor type'] == ''
        assert summary_info['Number of Sensors'] == 65
        assert not dt.has_orientation
        assert dt.labels.shape == (65,)
        assert dt.locations.shape == (65, 3)
        assert dt.number_of_sensors == 65
        assert dt.orientations.shape == (0,)
        assert dt.sensors_type == ''

        ## Mapping 62 sensors on a Skin surface should work
        surf = SkinAir(load_file="outer_skin_4096.zip")
        surf.configure()
        mapping = dt.sensors_to_surface(surf)
        assert mapping.shape == (65, 3)

        ## Mapping on a surface with holes should fail
        dummy_surf = SkinAir()
        dummy_surf.vertices = numpy.array(range(30)).reshape(10, 3).astype('f')
        dummy_surf.triangles = numpy.array(range(9)).reshape(3, 3)
        dummy_surf.configure()
        try:
            dt.sensors_to_surface(dummy_surf)
            pytest.fail("Should have failed for this simple surface!")
        except Exception:
            pass
예제 #3
0
    def test_sensors(self):

        dt = sensors.Sensors.from_file()
        dt.configure()

        summary_info = dt.summary_info()
        assert summary_info['Sensor type'] is None
        assert summary_info['Number of Sensors'] == 65
        assert not dt.has_orientation
        assert dt.labels.shape == (65,)
        assert dt.locations.shape == (65, 3)
        assert dt.number_of_sensors == 65
        assert dt.orientations is None
        assert dt.sensors_type is None

        ## Mapping 62 sensors on a Skin surface should work
        surf = SkinAir.from_file()
        surf.configure()
        mapping = dt.sensors_to_surface(surf)
        assert mapping.shape == (65, 3)

        ## Mapping on a surface with holes should fail
        dummy_surf = SkinAir()
        dummy_surf.vertices = numpy.array(list(range(30))).reshape(10, 3).astype('f')
        dummy_surf.triangles = numpy.array(list(range(9))).reshape(3, 3)
        dummy_surf.configure()
        try:
            dt.sensors_to_surface(dummy_surf)
            self.fail("Should have failed for this simple surface!")
        except Exception:
            pass
    def launch(self, uploaded, surface_type, zero_based_triangles = False):
        """
        Execute import operations: unpack ZIP and build Surface object as result.
        """
        if uploaded is None:
            raise LaunchException ("Please select ZIP file which contains data to import")
  
        self.logger.debug("Start to import surface: '%s' from file: %s"%(surface_type, uploaded))
        try:
            files = FilesHelper().unpack_zip(uploaded, self.storage_path)
        except IOError:
            exception_str = "Did not find the specified ZIP at %s" % uploaded
            raise LaunchException(exception_str)
        
        vertices = []
        normals = []
        triangles = []
        for file_name in files:
            if file_name.lower().find(self.VERTICES_TOKEN) >= 0:
                vertices.append(file_name)            
                continue
            if file_name.lower().find(self.NORMALS_TOKEN) >= 0:
                normals.append(file_name)            
                continue
            if file_name.lower().find(self.TRIANGLES_TOKEN) >= 0:
                triangles.append(file_name)
                
        # Now detect and instantiate correct surface type
        self.logger.debug("Create surface instance")
        if surface_type == CORTICAL:
            surface = CorticalSurface()
        elif surface_type == INNER_SKULL:
            surface = BrainSkull()
        elif surface_type == OUTER_SKULL:
            surface = SkullSkin()
        elif surface_type == OUTER_SKIN:
            surface = SkinAir()
        elif surface_type == EEG_CAP:
            surface = EEGCap()
        elif surface_type == FACE:
            surface = FaceSurface()
        else:
            exception_str = "Could not determine surface type (selected option %s)" % surface_type
            raise LaunchException(exception_str)
            
        surface.storage_path = self.storage_path

        all_vertices, all_normals, all_triangles = self._process_files(vertices, normals, triangles)
        FilesHelper.remove_files(files, True)
        surface.zero_based_triangles = zero_based_triangles
        surface.vertices = all_vertices
        surface.vertex_normals = all_normals
        if zero_based_triangles:
            surface.triangles = all_triangles
        else :
            surface.triangles = all_triangles - 1
        surface.triangle_normals = None

        # Now check if the triangles of the surface are valid   
        triangles_min_vertex = numpy.amin(surface.triangles)
        if triangles_min_vertex < 0:
            if triangles_min_vertex == -1 and not zero_based_triangles:
                raise RuntimeError("Triangles contain a negative vertex index. Maybe you have a ZERO based surface.")
            else:
                raise RuntimeError("Your triangles contain a negative vertex index: %d" %triangles_min_vertex)
        
        no_of_vertices = len(surface.vertices)        
        triangles_max_vertex = numpy.amax(surface.triangles)
        if triangles_max_vertex >= no_of_vertices:
            if triangles_max_vertex == no_of_vertices and zero_based_triangles:
                raise RuntimeError("Your triangles contain an invalid vertex index: %d. \
                Maybe your surface is NOT ZERO Based."%triangles_max_vertex)
            else:
                raise RuntimeError("Your triangles contain an invalid vertex index: %d." %triangles_max_vertex)
            
        self.logger.debug("Surface ready to be stored")
        return surface
예제 #5
0
class GIFTIParser():
    """
        This class reads content of a GIFTI file and builds / returns a Surface instance 
        filled with details.
    """
    UNIQUE_ID_ATTR = "UniqueID"
    SUBJECT_ATTR = "SubjectID"
    ASP_ATTR = "AnatomicalStructurePrimary"
    DATE_ATTR = "Date"
    DESCRIPTION_ATTR = "Description"
    NAME_ATTR = "Name"
    TIME_STEP_ATTR = "TimeStep"
    
    def __init__(self, storage_path, operation_id):
        self.logger = get_logger(__name__)
        self.storage_path = storage_path
        self.operation_id = operation_id
        
    def parse(self, data_file):
        """
            Parse NIFTI file and returns TimeSeries for it. 
        """
        self.logger.debug("Start to parse GIFTI file: %s"%data_file)
        if data_file is None:
            raise ParseException ("Please select GIFTI file which contains data to import")
        if not os.path.exists(data_file):
            raise ParseException ("Provided file %s does not exists"%data_file)
        try:
            gifti_image = giftiio.read(data_file)
            self.logger.debug("File parsed successfully")
        except Exception, excep:
            self.logger.exception(excep)
            msg = "File: %s does not have a valid GIFTI format." % data_file
            raise ParseException(msg)
        
        
        # Now try to determine what data is stored in GIFTI file
        data_arrays = gifti_image.darrays
        
        self.logger.debug("Determine data type stored in GIFTI file")
        
        # First check if it's a surface
        if (len(data_arrays) == 2 
            and intent_codes.code["NIFTI_INTENT_POINTSET"] == data_arrays[0].intent
            and data_type_codes.code["NIFTI_TYPE_FLOAT32"] == data_arrays[0].datatype
            and intent_codes.code["NIFTI_INTENT_TRIANGLE"] == data_arrays[1].intent
            and data_type_codes.code["NIFTI_TYPE_INT32"] == data_arrays[1].datatype):
            
            # Now try to determine what type of surface we have
            data_array_meta = data_arrays[0].meta
            surface = None
            gid = None
            subject = None
            title = None
            
            if (data_array_meta is not None and data_array_meta.data is not None 
                   and len(data_array_meta.data) > 0):
                anatomical_structure_primary = None
                
                for meta_pair in data_array_meta.data:
                    if meta_pair.name == self.ASP_ATTR:
                        anatomical_structure_primary = meta_pair.value
                    elif meta_pair.name == self.UNIQUE_ID_ATTR:
                        gid = meta_pair.value.replace("{", "").replace("}", "")
                    elif meta_pair.name == self.SUBJECT_ATTR:
                        subject = meta_pair.value
                    elif meta_pair.name == self.NAME_ATTR:
                        title = meta_pair.value
                        
                # Based on info found in meta create correct surface type
                if anatomical_structure_primary == "Head":
                    surface = SkinAir()
                elif anatomical_structure_primary.startswith("Cortex"):
                    surface = CorticalSurface()
                
            
            if surface is None:
                raise ParseException("Could not determine type of the surface")
            
            # Now fill TVB data type with info
            if gid is not None:
                surface.gid = gid
            
            surface.storage_path = self.storage_path
            surface.set_operation_id(self.operation_id)
            
            surface.zero_based_triangles = True
            surface.vertices = data_arrays[0].data
            surface.triangles = data_arrays[1].data
            
            if subject is not None:
                surface.subject = subject
            if title is not None:
                surface.title = title
            
            return surface
        
        elif(len(data_arrays) > 1 
            and intent_codes.code["NIFTI_INTENT_TIME_SERIES"] == data_arrays[0].intent
            and data_type_codes.code["NIFTI_TYPE_FLOAT32"] == data_arrays[0].datatype):
            
            # Create TVB time series to be filled
            time_series = TimeSeriesSurface()
            time_series.storage_path = self.storage_path
            time_series.set_operation_id(self.operation_id)
            time_series.start_time = 0.0
            time_series.sample_period = 1.0

            # First process first data_array and extract important data from it's metadata            
            data_array_meta = data_arrays[0].meta
            if (data_array_meta is not None and data_array_meta.data is not None 
                   and len(data_array_meta.data) > 0):
                for meta_pair in data_array_meta.data:
                    if meta_pair.name == self.UNIQUE_ID_ATTR:
                        gid = meta_pair.value.replace("{", "").replace("}", "")
                        if gid is not None and len(gid) > 0:
                            time_series.gid = gid
                    elif meta_pair.name == self.SUBJECT_ATTR:
                        time_series.subject = meta_pair.value
                    elif meta_pair.name == self.NAME_ATTR:
                        time_series.title = meta_pair.value
                    elif meta_pair.name == self.TIME_STEP_ATTR:
                        time_series.sample_period = float(meta_pair.value)
            
            
            # Now read time series data
            for data_array in data_arrays:
                time_series.write_data_slice([data_array.data])
            
            # Close file after writing data
            time_series.close_file()
            
            return time_series
        else:
            raise ParseException("Could not map data from GIFTI file to a TVB data type")