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
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
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
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")