def fill_default_attributes(self, template_dictionary): """ Overwrite base controller to add required parameters for adapter templates. """ context = base.get_from_session(KEY_REGION_CONTEXT) template_dictionary["entitiySavedName"] = [{ 'name': DataTypeMetaData.KEY_TAG_1, 'label': 'Display name', 'type': 'str', "disabled": "False", "default": context.equation_kwargs.get(DataTypeMetaData.KEY_TAG_1, '') }] template_dictionary['loadExistentEntityUrl'] = LOAD_EXISTING_URL template_dictionary['resetToDefaultUrl'] = RELOAD_DEFAULT_PAGE_URL template_dictionary['displayedMessage'] = base.get_from_session( base.KEY_MESSAGE) template_dictionary['messageType'] = base.get_from_session( base.KEY_MESSAGE_TYPE) return SpatioTemporalController.fill_default_attributes( self, template_dictionary, subsection='regionstim')
def submit_model_parameters(self): """ Collects the model parameters values from all the models used for the surface vertices. """ context_model_parameters = base.get_from_session(KEY_CONTEXT_MPS) burst_configuration = base.get_from_session(base.KEY_BURST_CONFIG) for original_param, modified_param in context_model_parameters.prepared_model_parameter_names.items( ): full_name = PARAMS_MODEL_PATTERN % ( context_model_parameters.model_name, original_param) param_data = context_model_parameters.get_data_for_model_param( original_param, modified_param) if isinstance(param_data, dict): equation = param_data[KEY_EQUATION] param_data[KEY_EQUATION] = equation.to_json(equation) param_data[KEY_FOCAL_POINTS] = json.dumps( param_data[KEY_FOCAL_POINTS]) param_data = json.dumps(param_data) burst_configuration.update_simulation_parameter( full_name, param_data) ### Clean from session drawing context base.remove_from_session(KEY_CONTEXT_MPS) ### Update in session BURST configuration for burst-page. base.add2session(base.KEY_BURST_CONFIG, burst_configuration.clone()) raise cherrypy.HTTPRedirect("/burst/")
def step_2(self, **kwargs): """ Generate the html for the second step of the local connectivity page. :param kwargs: not actually used, but parameters are still submitted from UI since we just use the same js function for this. TODO: do this in a smarter way """ context = base.get_from_session(KEY_LCONN_CONTEXT) left_side_interface = self.get_select_existent_entities( 'Load Local Connectivity:', LocalConnectivity, context.selected_entity) template_specification = dict(title="Surface - Local Connectivity") template_specification[ 'mainContent'] = 'spatial/local_connectivity_step2_main' template_specification[ 'existentEntitiesInputList'] = left_side_interface template_specification['loadExistentEntityUrl'] = LOAD_EXISTING_URL template_specification['resetToDefaultUrl'] = RELOAD_DEFAULT_PAGE_URL template_specification[ 'next_step_url'] = '/spatial/localconnectivity/step_1' template_specification['displayedMessage'] = base.get_from_session( base.KEY_MESSAGE) context = base.get_from_session(KEY_LCONN_CONTEXT) if context.selected_entity != None: selected_local_conn = ABCAdapter.load_entity_by_gid( context.selected_entity) template_specification.update( self.display_surface(selected_local_conn.surface.gid)) template_specification['no_local_connectivity'] = False else: template_specification['no_local_connectivity'] = True template_specification[base.KEY_PARAMETERS_CONFIG] = False return self.fill_default_attributes(template_specification)
def get_stimulus_chunk(self, chunk_idx): """ Get the next chunk of the stimulus data. """ stimulus = base.get_from_session(KEY_STIMULUS) surface_gid = base.get_from_session(PARAM_SURFACE) chunk_idx = int(chunk_idx) if stimulus.surface.gid != surface_gid: raise Exception("TODO: Surface changed while visualizing stimulus. See how to handle this.") data = [] for idx in range(chunk_idx * CHUNK_SIZE, min((chunk_idx + 1) * CHUNK_SIZE, stimulus.temporal_pattern.shape[1]), 1): data.append(stimulus(idx).tolist()) return data
def fill_default_attributes(self, template_specification): """ Add some entries that are used in both steps then fill the default required attributes. """ context = base.get_from_session(KEY_SURFACE_CONTEXT) template_specification["entitiySavedName"] = [ {'name': DataTypeMetaData.KEY_TAG_1, 'label': 'Display name', 'type': 'str', "disabled": "False", "default": context.equation_kwargs.get(DataTypeMetaData.KEY_TAG_1, '')}] template_specification['loadExistentEntityUrl'] = LOAD_EXISTING_URL template_specification['resetToDefaultUrl'] = RELOAD_DEFAULT_PAGE_URL template_specification['displayedMessage'] = base.get_from_session(base.KEY_MESSAGE) template_specification['messageType'] = base.get_from_session(base.KEY_MESSAGE_TYPE) return super(SurfaceStimulusController, self).fill_default_attributes(template_specification, subsection='surfacestim')
def submit_model_parameters(self): """ Collects the model parameters values from all the models used for the connectivity nodes. """ context_model_parameters = base.get_from_session(KEY_CONTEXT_MPR) burst_configuration = base.get_from_session(base.KEY_BURST_CONFIG) for param_name in context_model_parameters.model_parameter_names: full_name = PARAMS_MODEL_PATTERN % (context_model_parameters.model_name, param_name) full_values = context_model_parameters.get_values_for_parameter(param_name) burst_configuration.update_simulation_parameter(full_name, full_values) ### Clean from session drawing context base.remove_from_session(KEY_CONTEXT_MPR) ### Update in session BURST configuration for burst-page. base.add2session(base.KEY_BURST_CONFIG, burst_configuration.clone()) raise cherrypy.HTTPRedirect("/burst/")
def launch_burst(self, launch_mode, burst_name, **data): """ Do the actual burst launch, using the configuration saved in current session. :param launch_mode: new/branch/continue :param burst_name: user-given burst name. It can be empty (case in which we will fill with simulation_x) :param data: kwargs for simulation input parameters. """ burst_config = base.get_from_session(base.KEY_BURST_CONFIG) ## Validate new burst-name if burst_name != 'none_undefined': self._validate_burst_name(burst_name) burst_config.name = burst_name ## Fill all parameters user_id = base.get_logged_user().id data[base.KEY_ADAPTER] = self.cached_simulator_algorithm_id burst_config.update_simulator_configuration(data) burst_config.fk_project = base.get_current_project().id ## Do the asynchronous launch burst_id, burst_name = self.burst_service.launch_burst( burst_config, 0, self.cached_simulator_algorithm_id, user_id, launch_mode) return [burst_id, burst_name]
def save_parameters(self, index_in_tab, **data): """ Save parameters :param tab_nr: the index of the selected tab :param index_in_tab: the index of the configured portlet in the selected tab :param data: the {name:value} dictionary configuration of the current portlet Having these inputs, update the configuration of the portletin the corresponding tab position form the burst configuration . """ burst_config = base.get_from_session(base.KEY_BURST_CONFIG) tab_nr = burst_config.selected_tab old_portlet_config = burst_config.tabs[int(tab_nr)].portlets[int( index_in_tab)] # Replace all void entries with 'None' for entry in data: if data[entry] == '': data[entry] = None need_relaunch = self.burst_service.update_portlet_configuration( old_portlet_config, data) if need_relaunch: #### Reset Burst Configuration into an entity not persisted (id = None for all) base.add2session(base.KEY_BURST_CONFIG, burst_config.clone()) return "relaunchView" else: self.workflow_service.store_workflow_step( old_portlet_config.visualizer) return "noRelaunch"
def get_portlet_configurable_interface(self, index_in_tab): """ From the position given by the tab index and the index from that tab, get the portlet configuration and build the configurable interface for that portlet. """ burst_config = base.get_from_session(base.KEY_BURST_CONFIG) tab_index = burst_config.selected_tab portlet_config = burst_config.tabs[tab_index].portlets[int( index_in_tab)] portlet_interface = self.burst_service.build_portlet_interface( portlet_config, base.get_current_project().id) full_portlet_input_tree = [] for entry in portlet_interface: full_portlet_input_tree.extend(entry.interface) self.context.add_portlet_to_session(full_portlet_input_tree) portlet_interface = { "adapters_list": portlet_interface, base.KEY_PARAMETERS_CONFIG: False, base.KEY_SESSION_TREE: self.context.KEY_PORTLET_CONFIGURATION } return self.fill_default_attributes(portlet_interface)
def clean_files_on_disk(): """ This method is executed at the end of a request and checks if there is any file which should be deleted on disk. """ files_list = bc.get_from_session(bc.FILES_TO_DELETE_ATTR) if files_list is not None and len(files_list) > 0: for (i, file_to_delete) in enumerate(files_list): if os.path.exists(file_to_delete): try: LOG.debug("End of request - deleting file/folder:%s" % file_to_delete) if os.path.isfile(file_to_delete): os.remove(file_to_delete) else: shutil.rmtree(file_to_delete) # Delete success - now remove file from list del files_list[i] except Exception, exc: LOG.error("Could not delete file/folder: %s" % file_to_delete) LOG.exception(exc) else: # File not found on disk, so we remove it from list del files_list[i]
def step_2(self): """ Generate the required template dictionary for the second step. """ context = base.get_from_session(KEY_REGION_CONTEXT) selected_stimulus_gid = context.selected_stimulus left_side_interface = self.get_select_existent_entities( 'Load Region Stimulus:', StimuliRegion, selected_stimulus_gid) template_specification = dict( title="Spatio temporal - Region stimulus") template_specification[ 'mainContent'] = 'spatial/stimulus_region_step2_main' template_specification[ 'next_step_url'] = '/spatial/stimulus/region/step_2_submit' template_specification[ 'existentEntitiesInputList'] = left_side_interface default_weights = context.get_weights() if len(default_weights) == 0: selected_connectivity = ABCAdapter.load_entity_by_gid( context.get_session_connectivity()) default_weights = StimuliRegion.get_default_weights( selected_connectivity.number_of_regions) template_specification['node_weights'] = json.dumps(default_weights) template_specification[base.KEY_PARAMETERS_CONFIG] = False template_specification.update( self.display_connectivity(context.get_session_connectivity())) return self.fill_default_attributes(template_specification)
def step_1(self): """ Generate the required template dictionary for the first step. """ context = base.get_from_session(KEY_REGION_CONTEXT) right_side_interface, any_scaling = self._get_stimulus_interface() selected_stimulus_gid = context.selected_stimulus left_side_interface = self.get_select_existent_entities( 'Load Region Stimulus:', StimuliRegion, selected_stimulus_gid) #add interface to session, needed for filters self.add_interface_to_session(left_side_interface, right_side_interface['inputList']) template_specification = dict( title="Spatio temporal - Region stimulus") template_specification[ 'mainContent'] = 'spatial/stimulus_region_step1_main' template_specification['isSingleMode'] = True template_specification.update(right_side_interface) template_specification[ 'existentEntitiesInputList'] = left_side_interface template_specification[ 'equationViewerUrl'] = '/spatial/stimulus/region/get_equation_chart' template_specification['fieldsPrefixes'] = json.dumps( self.fields_prefixes) template_specification[ 'next_step_url'] = '/spatial/stimulus/region/step_1_submit' template_specification['anyScaling'] = any_scaling return self.fill_default_attributes(template_specification)
def configure_simulator_parameters(self): """ Return the required input tree to generate the simulator interface for the burst page in 'configuration mode', meaning with checkboxes next to each input that are checked or not depending on if the user selected them so, and with the user filled defaults. """ burst_config = base.get_from_session(base.KEY_BURST_CONFIG) default_values, any_checked = burst_config.get_all_simulator_values() simulator_input_tree = self.cached_simulator_input_tree simulator_input_tree = ABCAdapter.fill_defaults( simulator_input_tree, default_values) ### Add simulator tree to session to be available in filters self.context.add_adapter_to_session(self.cached_simulator_algo_group, simulator_input_tree, default_values) template_specification = { "inputList": simulator_input_tree, base.KEY_PARAMETERS_CONFIG: True, 'none_checked': not any_checked, 'selectedParametersDictionary': burst_config.simulator_configuration } ## Setting this to true means check-boxes are displayed next to all inputs ## return self.fill_default_attributes(template_specification)
def get_reduced_simulator_interface(self): """ Get a simulator interface that only contains the inputs that are marked as KEY_PARAMETER_CHECKED in the current session. """ burst_config = base.get_from_session(base.KEY_BURST_CONFIG) simulator_config = burst_config.simulator_configuration ## Fill with stored defaults, and see if any parameter was checked by user ## default_values, any_checked = burst_config.get_all_simulator_values() simulator_input_tree = self.cached_simulator_input_tree simulator_input_tree = ABCAdapter.fill_defaults( simulator_input_tree, default_values) ## In case no values were checked just skip tree-cut part and show entire simulator tree ## if any_checked: simulator_input_tree = self.burst_service.select_simulator_inputs( simulator_input_tree, simulator_config) ### Add simulator tree to session to be available in filters self.context.add_adapter_to_session(self.cached_simulator_algo_group, simulator_input_tree, default_values) template_specification = { "inputList": simulator_input_tree, base.KEY_PARAMETERS_CONFIG: False, 'draw_hidden_ranges': True } return self.fill_default_attributes(template_specification)
def stop_burst_operation(self, operation_id, is_group, remove_after_stop=False): """ For a given operation id that is part of a burst just stop the given burst. """ operation_id = int(operation_id) if int(is_group) == 0: operation = self.flow_service.load_operation(operation_id) else: op_group = ProjectService.get_operation_group_by_id(operation_id) first_op = ProjectService.get_operations_in_group(op_group)[0] operation = self.flow_service.load_operation(int(first_op.id)) try: burst_service = BurstService() burst_service.stop_burst(operation.burst) if remove_after_stop: current_burst = base.get_from_session(base.KEY_BURST_CONFIG) if current_burst and current_burst.id == operation.burst.id: base.remove_from_session(base.KEY_BURST_CONFIG) burst_service.remove_burst(operation.burst.id) return True except Exception, ex: self.logger.exception(ex) return False
def _add_extra_fields_to_interface(input_list): """ The fields that have to be added to the existent adapter interface should be added in this method. """ context = base.get_from_session(KEY_SURFACE_CONTEXT) temporal_iface = [] min_tmp_x = {'name': 'min_tmp_x', 'label': 'Temporal Start Time(ms)', 'type': 'str', "disabled": "False", "default": context.equation_kwargs.get('min_tmp_x', 0), "description": "The minimum value of the x-axis for temporal equation plot."} max_tmp_x = {'name': 'max_tmp_x', 'label': 'Temporal End Time(ms)', 'type': 'str', "disabled": "False", "default": context.equation_kwargs.get('max_tmp_x', 100), "description": "The maximum value of the x-axis for temporal equation plot."} temporal_iface.append(min_tmp_x) temporal_iface.append(max_tmp_x) spatial_iface = [] min_space_x = {'name': 'min_space_x', 'label': 'Spatial Start Distance(mm)', 'type': 'str', "disabled": "False", "default": context.equation_kwargs.get('min_space_x', 0), "description": "The minimum value of the x-axis for spatial equation plot."} max_space_x = {'name': 'max_space_x', 'label': 'Spatial End Distance(mm)', 'type': 'str', "disabled": "False", "default": context.equation_kwargs.get('max_space_x', 100), "description": "The maximum value of the x-axis for spatial equation plot."} spatial_iface.append(min_space_x) spatial_iface.append(max_space_x) input_list['spatialPlotInputList'] = spatial_iface input_list['temporalPlotInputList'] = temporal_iface return input_list
def add_adapter_to_session(self, algo_group, input_tree, default_data=None): """ Put in session information about currently selected adapter. Will be used by filters and efficiency load. """ previous_algo = self.get_current_substep() current_algo = algo_group.id if algo_group is not None else ( default_data[base.KEY_ADAPTER] if default_data is not None else None) if current_algo is None or str(current_algo) != str(previous_algo): self.clean_from_session() adapter_info = {} else: adapter_info = base.get_from_session(self.KEY_CURRENT_ADAPTER_INFO) if default_data is not None: adapter_info[self._KEY_SELECTED_DATA] = default_data if input_tree is not None: adapter_info[self._KEY_INPUT_TREE] = input_tree if algo_group is not None: adapter_info[self._KEY_CURRENT_STEP] = algo_group.fk_category adapter_info[self._KEY_CURRENT_SUBSTEP] = algo_group.id base.add2session(self.KEY_CURRENT_ADAPTER_INFO, adapter_info)
def _fill_default_values(input_list, model_param): """ If the user already applied an equation, for the given model parameter, than the form should be filled with the provided data for that equation. """ #TODO: try to use fill_defaults from abcadapter context_model_parameters = base.get_from_session(KEY_CONTEXT_MPS) if model_param in context_model_parameters.applied_equations: model_param_data = context_model_parameters.applied_equations[ model_param] if KEY_EQUATION in model_param_data: equation = model_param_data[KEY_EQUATION] equation_name = equation.__class__.__name__ equation_params = equation.parameters for input in input_list: if input['name'] == 'model_param_equation': input['default'] = equation_name for option in input['options']: if option['name'] == equation_name: for attr in option['attributes']: if attr['name'] == 'parameters': for attribute in attr['attributes']: attribute[ 'default'] = equation_params[ attribute['name']] return
def get_data_from_burst_configuration(self): """ Returns the model, integrator, connectivity and surface instances from the burst configuration. """ ### Read from session current burst-configuration burst_configuration = base.get_from_session(base.KEY_BURST_CONFIG) if burst_configuration is None: return None, None, None first_range = burst_configuration.get_simulation_parameter_value( 'first_range') second_range = burst_configuration.get_simulation_parameter_value( 'second_range') if ((first_range is not None and str(first_range).startswith(MODEL_PARAMETERS)) or (second_range is not None and str(second_range).startswith(MODEL_PARAMETERS))): base.set_error_message( "When configuring model parameters you are not allowed to specify range values." ) raise cherrypy.HTTPRedirect("/burst/") group = self.flow_service.get_algorithm_by_module_and_class( SIMULATOR_MODULE, SIMULATOR_CLASS)[1] simulator_adapter = self.flow_service.build_adapter_instance(group) try: params_dict = simulator_adapter.convert_ui_inputs( burst_configuration.get_all_simulator_values()[0], False) except Exception, excep: self.logger.exception(excep) base.set_error_message( "Some of the provided parameters have an invalid value.") raise cherrypy.HTTPRedirect("/burst/")
def launch_full_visualizer(self, index_in_tab): """ Launch the full scale visualizer from a small preview from the burst cockpit. """ burst = base.get_from_session(base.KEY_BURST_CONFIG) selected_tab = burst.selected_tab visualizer = burst.tabs[selected_tab].portlets[int( index_in_tab)].visualizer result, input_data, operation_id = self.burst_service.launch_visualization( visualizer, is_preview=False) algorithm = self.flow_service.get_algorithm_by_identifier( visualizer.fk_algorithm) result[base.KEY_TITLE] = algorithm.name result[base.KEY_ADAPTER] = algorithm.algo_group.id result[base.KEY_OPERATION_ID] = operation_id result[base.KEY_INCLUDE_RESOURCES] = 'flow/included_resources' ## Add required field to input dictionary and return it so that it can be used ## ## for top right control. #### input_data[base.KEY_ADAPTER] = algorithm.algo_group.id if base.KEY_PARENT_DIV not in result: result[base.KEY_PARENT_DIV] = '' self.context.add_adapter_to_session(algorithm.algo_group, None, copy.deepcopy(input_data)) self._populate_section(algorithm.algo_group, result) result[base.KEY_DISPLAY_MENU] = True result[base.KEY_BACK_PAGE] = "/burst" result[base.KEY_SUBMIT_LINK] = self.get_url_adapter( algorithm.algo_group.group_category.id, algorithm.algo_group.id, 'burst') if KEY_CONTROLLS not in result: result[KEY_CONTROLLS] = '' return self.fill_default_attributes(result)
def save_simulator_configuration(self, exclude_ranges, **data): """ :param exclude_ranges: should be a boolean value. If it is True than the ranges will be excluded from the simulation parameters. Data is a dictionary with pairs in one of the forms: { 'simulator_parameters' : { $name$ : { 'value' : $value$, 'is_disabled' : true/false } }, 'burstName': $burst_name} The names for the checkboxes next to the parameter with name $name$ is always $name$_checked Save this dictionary in an easy to process form from which you could rebuild either only the selected entries, or all of the simulator tree with the given default values. """ #if the method is called from js then the parameter will be set as string exclude_ranges = eval(str(exclude_ranges)) burst_config = base.get_from_session(base.KEY_BURST_CONFIG) if BURST_NAME in data: burst_config.name = data[BURST_NAME] data = json.loads(data['simulator_parameters']) for entry in data: if exclude_ranges and (entry.endswith("_checked") or entry == 'first_range' or entry == 'second_range'): continue burst_config.update_simulation_parameter(entry, data[entry]) checkbox_for_entry = entry + "_checked" if checkbox_for_entry in data: burst_config.update_simulation_parameter( entry, data[checkbox_for_entry], KEY_PARAMETER_CHECKED)
def load_noise_values_for_connectivity_node(self, connectivity_index): connectivity_index = int(connectivity_index) context_noise_config = base.get_from_session(KEY_CONTEXT_NC) node_values = {} for idx in xrange(len(context_noise_config.noise_values)): node_values[idx] = context_noise_config.noise_values[idx][ connectivity_index] return node_values
def submit_noise_configuration(self): """ Collects the model parameters values from all the models used for the connectivity nodes. """ context_noise_config = base.get_from_session(KEY_CONTEXT_NC) burst_configuration = base.get_from_session(base.KEY_BURST_CONFIG) _, simulator_group = FlowService().get_algorithm_by_module_and_class( SIMULATOR_MODULE, SIMULATOR_CLASS) simulator_adapter = ABCAdapter.build_adapter(simulator_group) for param_name in simulator_adapter.noise_configurable_parameters(): burst_configuration.update_simulation_parameter( param_name, str(context_noise_config.noise_values)) ### Clean from session drawing context base.remove_from_session(KEY_CONTEXT_NC) ### Update in session BURST configuration for burst-page. base.add2session(base.KEY_BURST_CONFIG, burst_configuration.clone()) raise cherrypy.HTTPRedirect("/burst/")
def get_current_input_tree(self): """ Get from session previously selected InputTree. """ full_description = base.get_from_session(self.KEY_CURRENT_ADAPTER_INFO) if full_description is not None and self._KEY_INPUT_TREE in full_description: return full_description[self._KEY_INPUT_TREE] return None
def get_current_step(self): """ Get from session previously selected step (category ID). """ full_description = base.get_from_session(self.KEY_CURRENT_ADAPTER_INFO) if full_description is not None and self._KEY_CURRENT_STEP in full_description: return full_description[self._KEY_CURRENT_STEP] return None
def load_burst_history(self): """ Load the available burst that are stored in the database at this time. This is one alternative to 'chrome-back problem'. """ session_burst = base.get_from_session(base.KEY_BURST_CONFIG) return {'burst_list': self.burst_service.get_available_bursts(base.get_current_project().id), 'selectedBurst': session_burst.id}
def get_portlet_session_configuration(self): """ Get the current configuration of portlets stored in session for this burst, as a json. """ burst_entity = base.get_from_session(base.KEY_BURST_CONFIG) returned_configuration = burst_entity.update_selected_portlets() return returned_configuration
def step_2_submit(self, next_step, **kwargs): """ Any submit from the second step should be handled here. Update the context and then do the next step as required. """ context = base.get_from_session(KEY_REGION_CONTEXT) context.equation_kwargs[DataTypeMetaData.KEY_TAG_1] = kwargs[ DataTypeMetaData.KEY_TAG_1] return self.do_step(next_step, 2)
def copy_configuration(self, from_node, to_nodes): from_node = int(from_node) to_nodes = json.loads(to_nodes) if from_node < 0 or not len(to_nodes): return context_model_parameters = base.get_from_session(KEY_CONTEXT_NC) context_model_parameters.set_noise_connectivity_nodes( from_node, to_nodes) base.add2session(KEY_CONTEXT_NC, context_model_parameters)
def add_portlet_to_session(self, portlet_interface): """ Add a portlet configuration to the session. Used for applying filters on portlet configurations. """ full_description = base.get_from_session(self.KEY_CURRENT_ADAPTER_INFO) if full_description is None or full_description is {}: raise Exception("Should not add portlet interface to session") full_description[self.KEY_PORTLET_CONFIGURATION] = portlet_interface