def display_surface(surface_gid, region_mapping_gid=None): """ Generates the HTML for displaying the surface with the given ID. """ surface_h5 = h5.h5_file_for_gid(surface_gid) if surface_h5 is None: raise MissingDataException( SpatioTemporalController.MSG_MISSING_SURFACE + "!!") common.add2session(PARAM_SURFACE, surface_gid) url_vertices_pick, url_normals_pick, url_triangles_pick = SurfaceURLGenerator.get_urls_for_pick_rendering( surface_h5) url_vertices, url_normals, _, url_triangles, _ = SurfaceURLGenerator.get_urls_for_rendering( surface_h5, region_mapping_gid) surface_h5.close() return { 'urlVerticesPick': json.dumps(url_vertices_pick), 'urlTrianglesPick': json.dumps(url_triangles_pick), 'urlNormalsPick': json.dumps(url_normals_pick), 'urlVertices': json.dumps(url_vertices), 'urlTriangles': json.dumps(url_triangles), 'urlNormals': json.dumps(url_normals), 'brainCenter': json.dumps(surface_h5.center()) }
def compute_parameters(self, time_series, shell_surface=None): """ Create the required parameter dictionary for the HTML/JS viewer. :rtype: `dict` :raises Exception: when * number of measure points exceeds the maximum allowed * a Face object cannot be found in database """ self.populate_surface_fields(time_series) url_vertices, url_normals, url_lines, url_triangles, url_region_map = SurfaceURLGenerator.get_urls_for_rendering( self.surface_h5, self.region_map_gid) hemisphere_chunk_mask = self.surface_h5.get_slices_to_hemisphere_mask() params = self.retrieve_measure_points_params(time_series) if not self.one_to_one_map and self.measure_points_no > MAX_MEASURE_POINTS_LENGTH: raise Exception("Max number of measure points " + str(MAX_MEASURE_POINTS_LENGTH) + " exceeded.") time_series_h5 = h5.h5_file_for_index(time_series) assert isinstance(time_series_h5, TimeSeriesH5) base_adapter_url, time_urls = self._prepare_data_slices(time_series) min_val, max_val = time_series_h5.get_min_max_values() legend_labels = self._compute_legend_labels(min_val, max_val) state_variables = time_series.get_labels_for_dimension(1) if self.surface_gid and self.region_map_gid: boundary_url = SurfaceURLGenerator.get_url_for_region_boundaries(self.surface_gid, self.region_map_gid, self.stored_adapter.id) else: boundary_url = '' shell_surface = ensure_shell_surface(self.current_project_id, shell_surface) params.update(dict(title="Cerebral Activity: " + time_series.title, isOneToOneMapping=self.one_to_one_map, urlVertices=json.dumps(url_vertices), urlTriangles=json.dumps(url_triangles), urlLines=json.dumps(url_lines), urlNormals=json.dumps(url_normals), urlRegionMap=json.dumps(url_region_map), base_adapter_url=base_adapter_url, time=json.dumps(time_urls), minActivity=min_val, maxActivity=max_val, legendLabels=legend_labels, labelsStateVar=state_variables, labelsModes=list(range(time_series.data_length_4d)), extended_view=False, shellObject=self.prepare_shell_surface_params(shell_surface, SurfaceURLGenerator), biHemispheric=self.surface_h5.bi_hemispheric.load(), hemisphereChunkMask=json.dumps(hemisphere_chunk_mask), pageSize=self.PAGE_SIZE, urlRegionBoundaries=boundary_url, measurePointsLabels=self.get_space_labels(time_series_h5), measurePointsTitle=time_series.title)) params.update(self.build_params_for_subselectable_ts(time_series_h5)) time_series_h5.close() if self.surface_h5: self.surface_h5.close() return params
def launch(self, view_model): # type: (ConnectivityAnnotationsViewModel) -> dict annotations_index = self.load_entity_by_gid(view_model.annotations_index) if view_model.connectivity_index is None: connectivity_index = self.load_entity_by_gid(annotations_index.connectivity_gid) else: connectivity_index = self.load_entity_by_gid(view_model.connectivity_index) if view_model.region_mapping_index is None: region_map = dao.get_generic_entity(RegionMappingIndex, connectivity_index.gid, 'connectivity_gid') if len(region_map) < 1: raise LaunchException( "Can not launch this viewer unless we have at least a RegionMapping for the current Connectivity!") region_mapping_index = region_map[0] else: region_mapping_index = self.load_entity_by_gid(view_model.region_mapping_index) boundary_url = SurfaceURLGenerator.get_url_for_region_boundaries(region_mapping_index.surface_gid, region_mapping_index.gid, self.stored_adapter.id) surface_index = self.load_entity_by_gid(region_mapping_index.surface_gid) surface_h5 = h5.h5_file_for_index(surface_index) assert isinstance(surface_h5, SurfaceH5) url_vertices_pick, url_normals_pick, url_triangles_pick = SurfaceURLGenerator.get_urls_for_pick_rendering( surface_h5) url_vertices, url_normals, _, url_triangles, url_region_map = SurfaceURLGenerator.get_urls_for_rendering( surface_h5, region_mapping_index.gid) params = dict(title="Connectivity Annotations Visualizer", baseUrl=TvbProfile.current.web.BASE_URL, annotationsTreeUrl=URLGenerator.build_url(self.stored_adapter.id, 'tree_json', view_model.annotations_index), urlTriangleToRegion=URLGenerator.build_url(self.stored_adapter.id, "get_triangles_mapping", region_mapping_index.gid), urlActivationPatterns=URLGenerator.paths2url(view_model.annotations_index, "get_activation_patterns"), minValue=0, maxValue=connectivity_index.number_of_regions - 1, urlColors=json.dumps(url_region_map), urlVerticesPick=json.dumps(url_vertices_pick), urlTrianglesPick=json.dumps(url_triangles_pick), urlNormalsPick=json.dumps(url_normals_pick), brainCenter=json.dumps(surface_h5.center()), urlVertices=json.dumps(url_vertices), urlTriangles=json.dumps(url_triangles), urlNormals=json.dumps(url_normals), urlRegionBoundaries=boundary_url) return self.build_display_result("annotations/annotations_view", params, pages={"controlPage": "annotations/annotations_controls"})
def _prepare_data_slices(time_series_h5): """ Prepare data URL for retrieval with slices of timeSeries activity and Time-Line. :returns: [activity_urls], [timeline_urls] Currently timeline_urls has just one value, as on client is loaded entirely anyway. """ overall_shape = time_series_h5.read_data_shape() time_series_gid = time_series_h5.gid.load().hex activity_base_url = SurfaceURLGenerator.build_base_h5_url(time_series_gid) time_urls = [SurfaceURLGenerator.build_h5_url(time_series_gid, 'read_time_page', parameter="current_page=0;page_size=" + str(overall_shape[0]))] return activity_base_url, time_urls
def _compute_connectivity_global_params(self, connectivity): """ Returns a dictionary which contains the data needed for drawing a connectivity. :param connectivity: the `Connectivity(HasTraits)` object """ conn_gid = connectivity.gid.hex path_weights = SurfaceURLGenerator.paths2url(conn_gid, 'ordered_weights') path_pos = SurfaceURLGenerator.paths2url(conn_gid, 'ordered_centres') path_tracts = SurfaceURLGenerator.paths2url(conn_gid, 'ordered_tracts') path_labels = SurfaceURLGenerator.paths2url(conn_gid, 'ordered_labels') path_hemisphere_order_indices = SurfaceURLGenerator.paths2url( conn_gid, 'hemisphere_order_indices') algo = AlgorithmService().get_algorithm_by_module_and_class( CONNECTIVITY_CREATOR_MODULE, CONNECTIVITY_CREATOR_CLASS) submit_url = '/{}/{}/{}'.format(SurfaceURLGenerator.FLOW, algo.fk_category, algo.id) global_pages = dict(controlPage="connectivity/top_right_controls") minimum, maximum, minimum_non_zero = self._compute_matrix_extrema( connectivity.ordered_weights) minimum_t, maximum_t, minimum_non_zero_t = self._compute_matrix_extrema( connectivity.ordered_tracts) global_params = dict( urlWeights=path_weights, urlPositions=path_pos, urlTracts=path_tracts, urlLabels=path_labels, originalConnectivity=conn_gid, title="Connectivity Control", submitURL=submit_url, positions=connectivity.ordered_centres, tractsMin=minimum_t, tractsMax=maximum_t, weightsMin=minimum, weightsMax=maximum, tractsNonZeroMin=minimum_non_zero_t, weightsNonZeroMin=minimum_non_zero, pointsLabels=connectivity.ordered_labels, conductionSpeed=1, connectivity_entity=connectivity, base_selection=connectivity.saved_selection_labels, hemisphereOrderUrl=path_hemisphere_order_indices, leftHemisphereCount=(connectivity.hemispheres == 0).sum()) global_params.update( self.build_params_for_selectable_connectivity(connectivity)) return global_params, global_pages
def _compute_surface_params(self, surface_h5): url_vertices_pick, url_normals_pick, url_triangles_pick = SurfaceURLGenerator.get_urls_for_pick_rendering( surface_h5) url_vertices, url_normals, _, url_triangles, _ = SurfaceURLGenerator.get_urls_for_rendering( surface_h5) return { 'urlVerticesPick': json.dumps(url_vertices_pick), 'urlTrianglesPick': json.dumps(url_triangles_pick), 'urlNormalsPick': json.dumps(url_normals_pick), 'urlVertices': json.dumps(url_vertices), 'urlTriangles': json.dumps(url_triangles), 'urlNormals': json.dumps(url_normals), 'brainCenter': json.dumps(surface_h5.center()) }
def generate_preview(self, time_series, shell_surface=None, figure_size=None): """ Generate the preview for the burst page """ self.populate_surface_fields(time_series) url_vertices, url_normals, url_lines, url_triangles, url_region_map = \ SurfaceURLGenerator.get_urls_for_rendering(self.surface_h5, self.region_map_gid) params = self.retrieve_measure_points_prams(time_series) time_series_h5 = h5.h5_file_for_index(time_series) assert isinstance(time_series_h5, TimeSeriesH5) base_activity_url, time_urls = self._prepare_data_slices( time_series_h5) min_val, max_val = time_series_h5.get_min_max_values() time_series_h5.close() if self.surface_h5 and self.region_map_gid: boundary_url = SurfaceURLGenerator.get_url_for_region_boundaries( self.surface_h5, self.region_map_gid, self.stored_adapter.id) else: boundary_url = '' params.update(urlVertices=json.dumps(url_vertices), urlTriangles=json.dumps(url_triangles), urlLines=json.dumps(url_lines), urlNormals=json.dumps(url_normals), urlRegionMap=json.dumps(url_region_map), urlRegionBoundaries=boundary_url, base_activity_url=base_activity_url, isOneToOneMapping=self.one_to_one_map, minActivity=min_val, maxActivity=max_val) normalization_factor = figure_size[0] / 800 if figure_size[1] / 600 < normalization_factor: normalization_factor = figure_size[1] / 600 params['width'] = figure_size[0] * normalization_factor params['height'] = figure_size[1] * normalization_factor if self.surface_h5: self.surface_h5.close() return self.build_display_result("brain/portlet_preview", params)
def launch(self, view_model): # type: (ConnectivityViewerModel) -> dict """ Given the input connectivity data and the surface data, build the HTML response to be displayed. """ connectivity, colors, rays = self._load_input_data(view_model) global_params, global_pages = self._compute_connectivity_global_params( connectivity) if view_model.surface_data is not None: surface_h5 = self.load_traited_by_gid(view_model.surface_data) url_vertices, url_normals, _, url_triangles, _ = SurfaceURLGenerator.get_urls_for_rendering( surface_h5) else: url_vertices, url_normals, url_triangles = [], [], [] global_params["urlVertices"] = json.dumps(url_vertices) global_params["urlTriangles"] = json.dumps(url_triangles) global_params["urlNormals"] = json.dumps(url_normals) global_params['isSingleMode'] = False result_params, result_pages = Connectivity2DViewer( ).compute_parameters(connectivity, colors, rays, view_model.step) result_params.update(global_params) result_pages.update(global_pages) _params, _pages = Connectivity3DViewer().compute_parameters( connectivity, colors, rays) result_params.update(_params) result_pages.update(_pages) return self.build_display_result("connectivity/main_connectivity", result_params, result_pages)
def launch(self, input_data, surface_data=None, colors=None, rays=None, step=None): """ Given the input connectivity data and the surface data, build the HTML response to be displayed. :param input_data: index towards the `Connectivity` object which will be displayed :type input_data: `ConnectivityIndex` :param surface_data: if provided, it is displayed as a shadow to give an idea of the connectivity \ position relative to the full brain cortical surface :type surface_data: `SurfaceIndex` :param colors: used to establish a colormap for the nodes displayed in 2D Connectivity viewers :type colors: `ConnectivityMeasureIndex` :param rays: used to establish the size of the spheres representing each node in 3D Nodes viewer :type rays: `ConnectivityMeasureIndex` :param step: a threshold applied to the 2D Connectivity Viewers to differentiate 2 types of nodes \ the ones with a value greater that this will be displayed as red discs, instead of yellow :type step: float """ connectivity = h5.load_from_index(input_data) assert isinstance(connectivity, Connectivity) if colors: colors_dt = h5.load_from_index(colors) else: colors_dt = None if rays: rays_dt = h5.load_from_index(rays) else: rays_dt = None global_params, global_pages = self._compute_connectivity_global_params( connectivity) if surface_data is not None: surface_h5 = h5.h5_file_for_index(surface_data) url_vertices, url_normals, _, url_triangles, _ = SurfaceURLGenerator.get_urls_for_rendering( surface_h5) else: url_vertices, url_normals, url_triangles = [], [], [] global_params["urlVertices"] = json.dumps(url_vertices) global_params["urlTriangles"] = json.dumps(url_triangles) global_params["urlNormals"] = json.dumps(url_normals) global_params['isSingleMode'] = False result_params, result_pages = Connectivity2DViewer( ).compute_parameters(connectivity, colors_dt, rays_dt, step) result_params.update(global_params) result_pages.update(global_pages) _params, _pages = Connectivity3DViewer().compute_parameters( connectivity, colors_dt, rays_dt) result_params.update(_params) result_pages.update(_pages) return self.build_display_result("connectivity/main_connectivity", result_params, result_pages)
def retrieve_measure_points_params(self, time_series): """ To be overwritten method, for retrieving the measurement points (region centers, EEG sensors). """ if self.connectivity_index is None: self.measure_points_no = 0 return {'urlMeasurePoints': [], 'urlMeasurePointsLabels': [], 'noOfMeasurePoints': 0} connectivity_gid = self.connectivity_index.gid measure_points = SurfaceURLGenerator.build_h5_url(connectivity_gid, 'get_centres') measure_points_labels = SurfaceURLGenerator.build_h5_url(connectivity_gid, 'get_region_labels') self.measure_points_no = self.connectivity_index.number_of_regions return {'urlMeasurePoints': measure_points, 'urlMeasurePointsLabels': measure_points_labels, 'noOfMeasurePoints': self.measure_points_no}
def _prepare_data_slices(self, time_series_index): """ Prepare data URL for retrieval with slices of timeSeries activity and Time-Line. :returns: [activity_urls], [timeline_urls] Currently timeline_urls has just one value, as on client is loaded entirely anyway. """ time_series_gid = time_series_index.gid activity_base_url = URLGenerator.build_url(self.stored_adapter.id, 'read_data_page_split', time_series_gid, "") time_urls = [SurfaceURLGenerator.build_h5_url(time_series_gid, 'read_time_page', parameter="current_page=0;page_size=" + str(time_series_index.data_length_1d))] return activity_base_url, time_urls
def _prepare_shell_surface_params(self, shell_surface): if shell_surface: shell_h5_class, shell_h5_path = self._load_h5_of_gid( shell_surface.gid) with shell_h5_class(shell_h5_path) as shell_h5: shell_vertices, shell_normals, _, shell_triangles, _ = SurfaceURLGenerator.get_urls_for_rendering( shell_h5) shelfObject = json.dumps( [shell_vertices, shell_normals, shell_triangles]) return shelfObject return None
def display_surface(surface_gid, region_mapping_gid=None): """ Generates the HTML for displaying the surface with the given ID. """ surface = ABCAdapter.load_entity_by_gid(surface_gid) common.add2session(PARAM_SURFACE, surface_gid) surface_h5 = h5.h5_file_for_index(surface) url_vertices_pick, url_normals_pick, url_triangles_pick = SurfaceURLGenerator.get_urls_for_pick_rendering( surface_h5) url_vertices, url_normals, _, url_triangles, _ = SurfaceURLGenerator.get_urls_for_rendering( surface_h5, region_mapping_gid) surface_h5.close() return { 'urlVerticesPick': json.dumps(url_vertices_pick), 'urlTrianglesPick': json.dumps(url_triangles_pick), 'urlNormalsPick': json.dumps(url_normals_pick), 'urlVertices': json.dumps(url_vertices), 'urlTriangles': json.dumps(url_triangles), 'urlNormals': json.dumps(url_normals), 'brainCenter': json.dumps(surface_h5.center()) }
def _compute_surface_params(surface_h5): rendering_urls = [ json.dumps(url) for url in SurfaceURLGenerator.get_urls_for_rendering(surface_h5) ] url_vertices, url_normals, url_lines, url_triangles, _ = rendering_urls return { 'urlVertices': url_vertices, 'urlTriangles': url_triangles, 'urlLines': url_lines, 'urlNormals': url_normals }