コード例 #1
0
    def test_submit_noise_configuration_happy(self, connectivity_factory):
        """
        Submit noise configuration writes the noise array on the required key in the burst configuration
        """
        self.init()
        noise_controller = NoiseConfigurationController()
        simulator_controller = SimulatorController()
        simulator_controller.index()
        simulator = simulator_controller.context.simulator
        connectivity = connectivity_factory()
        simulator.connectivity = connectivity.gid
        simulator.integrator = HeunStochasticViewModel()

        # a noise configuration in the format expected by submit. Assumes Generic2dOscillator model.
        nodes_range = list(range(connectivity.number_of_regions))
        noise_in = [{'V': 1.0, 'W': 2.0} for _ in nodes_range]
        noise_in = json.dumps(noise_in)

        self._expect_redirect('/burst/', noise_controller.submit, noise_in)

        expected_noise_arr = [[1.0 for _ in nodes_range],
                              [2.0 for _ in nodes_range]]
        actual_noise_arr = simulator.integrator.noise.nsig
        assert (expected_noise_arr == actual_noise_arr).all()

        self.cleanup()
コード例 #2
0
ファイル: flow_controller.py プロジェクト: liadomide/tvb-root
    def __init__(self):
        BaseController.__init__(self)
        self.context = SelectedAdapterContext()
        self.operation_services = OperationService()
        self.simulator_controller = SimulatorController()

        analyze_category, groups = self.algorithm_service.get_analyze_groups()
        adapters_list = []
        for adapter_group in groups:

            if len(adapter_group.children) > 1:
                ids = [str(child.id) for child in adapter_group.children]
                ids = ','.join(ids)
                adapter_link = '/flow/show_group_of_algorithms/' + str(
                    analyze_category.id) + "/" + ids
            else:
                adapter_link = self.get_url_adapter(
                    analyze_category.id, adapter_group.children[0].id)

            adapters_list.append({
                common.KEY_TITLE:
                adapter_group.name,
                'link':
                adapter_link,
                'description':
                adapter_group.description,
                'subsection':
                adapter_group.children[0].subsection_name
            })
        self.analyze_adapters = adapters_list
コード例 #3
0
 def transactional_setup_method(self):
     """
     Sets up the environment for testing;
     creates a `RegionsModelParametersController` and a connectivity
     """
     self.init()
     self.region_m_p_c = RegionsModelParametersController()
     simulator_controller = SimulatorController()
     simulator_controller.index()
     self.simulator = simulator_controller.context.simulator
     self._setup_dynamic()
コード例 #4
0
 def setup_method(self):
     """
     Sets up the environment for testing;
     creates a `FlowController`
     """
     self.init()
     self.flow_c = FlowController()
     self.burst_c = SimulatorController()
     self.operation_service = OperationService()
コード例 #5
0
    def test_edit_model_parameters(self, region_mapping_index_factory):
        self.init()
        surface_m_p_c = SurfaceModelParametersController()
        simulator_controller = SimulatorController()
        simulator_controller.index()
        simulator = simulator_controller.context.simulator
        region_mapping_index = region_mapping_index_factory()
        simulator.connectivity = region_mapping_index.fk_connectivity_gid
        simulator.surface = CortexViewModel()
        simulator.surface.surface_gid = region_mapping_index.fk_surface_gid
        simulator.surface.region_mapping_data = region_mapping_index.gid

        result_dict = surface_m_p_c.edit_model_parameters()
        expected_keys = ['urlNormals', 'urlNormalsPick', 'urlTriangles', 'urlTrianglesPick',
                         'urlVertices', 'urlVerticesPick', 'mainContent', 'parametersEquationPlotForm',
                         'baseUrl', 'equationsPrefixes', 'brainCenter', 'applied_equations']
        # map(lambda x: self.assertTrue(x in result_dict), expected_keys)
        assert all(x in result_dict for x in expected_keys)
        assert result_dict['baseUrl'] == '/spatial/modelparameters/surface'
        assert result_dict['mainContent'] == 'spatial/model_param_surface_main'
コード例 #6
0
ファイル: run.py プロジェクト: nuuria8/tvb-root
def init_cherrypy(arguments=None):
    #### Mount static folders from modules marked for introspection
    arguments = arguments or []
    CONFIGUER = TvbProfile.current.web.CHERRYPY_CONFIGURATION
    if DataEncryptionHandler.encryption_enabled():
        CONFIGUER["/"]["tools.sessions.storage_class"] = CleanupSessionHandler
    for module in arguments:
        module_inst = importlib.import_module(str(module))
        module_path = os.path.dirname(os.path.abspath(module_inst.__file__))
        CONFIGUER["/static_" + str(module)] = {
            'tools.staticdir.on': True,
            'tools.staticdir.dir': '.',
            'tools.staticdir.root': module_path
        }

    #### Mount controllers, and specify the root URL for them.
    cherrypy.tree.mount(BaseController(), "/", config=CONFIGUER)
    cherrypy.tree.mount(UserController(), "/user/", config=CONFIGUER)
    cherrypy.tree.mount(ProjectController(), "/project/", config=CONFIGUER)
    cherrypy.tree.mount(FigureController(),
                        "/project/figure/",
                        config=CONFIGUER)
    cherrypy.tree.mount(FlowController(), "/flow/", config=CONFIGUER)
    cherrypy.tree.mount(SettingsController(), "/settings/", config=CONFIGUER)
    cherrypy.tree.mount(HelpController(), "/help/", config=CONFIGUER)
    cherrypy.tree.mount(SimulatorController(), "/burst/", config=CONFIGUER)
    cherrypy.tree.mount(ParameterExplorationController(),
                        "/burst/explore/",
                        config=CONFIGUER)
    cherrypy.tree.mount(DynamicModelController(),
                        "/burst/dynamic/",
                        config=CONFIGUER)
    cherrypy.tree.mount(SpatioTemporalController(),
                        "/spatial/",
                        config=CONFIGUER)
    cherrypy.tree.mount(RegionsModelParametersController(),
                        "/burst/modelparameters/regions/",
                        config=CONFIGUER)
    cherrypy.tree.mount(SurfaceModelParametersController(),
                        "/spatial/modelparameters/surface/",
                        config=CONFIGUER)
    cherrypy.tree.mount(RegionStimulusController(),
                        "/spatial/stimulus/region/",
                        config=CONFIGUER)
    cherrypy.tree.mount(SurfaceStimulusController(),
                        "/spatial/stimulus/surface/",
                        config=CONFIGUER)
    cherrypy.tree.mount(LocalConnectivityController(),
                        "/spatial/localconnectivity/",
                        config=CONFIGUER)
    cherrypy.tree.mount(NoiseConfigurationController(),
                        "/burst/noise/",
                        config=CONFIGUER)
    cherrypy.tree.mount(HPCController(), "/hpc/", config=CONFIGUER)

    cherrypy.config.update(CONFIGUER)

    # ----------------- Register additional request handlers -----------------
    # This tool checks for MAX upload size
    cherrypy.tools.upload = Tool('on_start_resource',
                                 RequestHandler.check_upload_size)
    # This tools clean up files on disk (mainly after export)
    cherrypy.tools.cleanup = Tool('on_end_request',
                                  RequestHandler.clean_files_on_disk)
    # ----------------- End register additional request handlers ----------------

    # Register housekeeping job
    if TvbProfile.current.hpc.IS_HPC_RUN and TvbProfile.current.hpc.CAN_RUN_HPC:
        cherrypy.engine.housekeeper = cherrypy.process.plugins.BackgroundTask(
            TvbProfile.current.hpc.BACKGROUND_JOB_INTERVAL,
            HPCOperationService.check_operations_job)
        cherrypy.engine.housekeeper.start()

    # HTTP Server is fired now ######
    cherrypy.engine.start()
コード例 #7
0
class FlowController(BaseController):
    """
    This class takes care of executing steps in projects.
    """

    def __init__(self):
        BaseController.__init__(self)
        self.context = SelectedAdapterContext()
        self.files_helper = FilesHelper()
        self.operation_services = OperationService()
        self.simulator_controller = SimulatorController()

        analyze_category, groups = self.algorithm_service.get_analyze_groups()
        adapters_list = []
        for adapter_group in groups:

            if len(adapter_group.children) > 1:
                ids = [str(child.id) for child in adapter_group.children]
                ids = ','.join(ids)
                adapter_link = '/flow/show_group_of_algorithms/' + str(analyze_category.id) + "/" + ids
            else:
                adapter_link = self.get_url_adapter(analyze_category.id, adapter_group.children[0].id)

            adapters_list.append({common.KEY_TITLE: adapter_group.name,
                                  'link': adapter_link,
                                  'description': adapter_group.description,
                                  'subsection': adapter_group.children[0].subsection_name})
        self.analyze_adapters = adapters_list

    @expose_page
    @settings
    @context_selected
    def step_analyzers(self):
        """
        Choose exact action/adapter for current step.
        """
        try:
            analyze_category, groups = self.algorithm_service.get_analyze_groups()
            step_name = analyze_category.displayname.lower()
            template_specification = dict(mainContent="header_menu", section_name=step_name, controlPage=None,
                                          title="Select an analyzer", displayControl=False)
            template_specification[common.KEY_SUBMENU_LIST] = self.analyze_adapters
            return self.fill_default_attributes(template_specification)

        except ValueError:
            message = 'Could not load analyzers!'
            common.set_warning_message(message)
            self.logger.warning(message)
            raise cherrypy.HTTPRedirect('/tvb')

    @expose_page
    @settings
    @context_selected
    def step_connectivity(self):
        """
        Display menu for Connectivity Footer tab.
        """
        template_specification = dict(mainContent="header_menu", section_name='connectivity', controlPage=None,
                                      title="Select an algorithm", displayControl=False, subsection_name='step',
                                      submenu_list=self.connectivity_submenu)
        return self.fill_default_attributes(template_specification)

    @staticmethod
    def _compute_back_link(back_indicator, project):
        """
        Based on a simple indicator, compute URL for anchor BACK.
        """
        if back_indicator is None:
            # This applies to Connectivity and other visualizers when RELAUNCH button is used from Operation page.
            back_page_link = None
        elif back_indicator == 'burst':
            back_page_link = "/burst"
        elif back_indicator == 'operations':
            back_page_link = '/project/viewoperations/' + str(project.id)
        else:
            back_page_link = '/project/editstructure/' + str(project.id)
        return back_page_link

    @expose_page
    @settings
    @context_selected
    def show_group_of_algorithms(self, step_key, algorithm_ids):

        project = common.get_current_project()
        category = self.algorithm_service.get_category_by_id(step_key)
        algorithms = []
        for i in algorithm_ids.split(','):
            algorithm_id = int(i)
            algorithm = self.algorithm_service.get_algorithm_by_identifier(algorithm_id)
            algorithm.link = self.get_url_adapter(step_key, algorithm_id)
            adapter_instance = self.algorithm_service.prepare_adapter(algorithm)
            adapter_form = self.algorithm_service.prepare_adapter_form(adapter_instance=adapter_instance,
                                                                       project_id=project.id)
            algorithm.form = self.render_adapter_form(adapter_form)
            algorithms.append(algorithm)

        template_specification = dict(mainContent="flow/algorithms_list", algorithms=algorithms,
                                      title="Select an algorithm", section_name=category.displayname.lower())
        self._populate_section(algorithms[0], template_specification)
        self.fill_default_attributes(template_specification, algorithms[0].group_name)
        return template_specification

    @expose_page
    @settings
    @context_selected
    def prepare_group_launch(self, group_gid, step_key, algorithm_id, **data):
        """
        Receives as input a group gid and an algorithm given by category and id, along
        with data that gives the name of the required input parameter for the algorithm.
        Having these generate a range of GID's for all the DataTypes in the group and
        launch a new operation group.
        """
        dt_group = self.project_service.get_datatypegroup_by_gid(group_gid)
        datatypes = self.project_service.get_datatypes_from_datatype_group(dt_group.id)
        range_param_name = data.pop('range_param_name')
        data[RANGE_PARAMETER_1] = range_param_name
        data[range_param_name] = ','.join(dt.gid for dt in datatypes)
        self.operation_services.group_operation_launch(common.get_logged_user().id, common.get_current_project(),
                                                       int(algorithm_id), int(step_key), **data)
        redirect_url = self._compute_back_link('operations', common.get_current_project())
        raise cherrypy.HTTPRedirect(redirect_url)

    @expose_page
    @settings
    @context_selected
    def default(self, step_key, adapter_key, cancel=False, back_page=None, **data):
        """
        Render a specific adapter.
        'data' are arguments for POST
        """
        project = common.get_current_project()
        algorithm = self.algorithm_service.get_algorithm_by_identifier(adapter_key)
        back_page_link = self._compute_back_link(back_page, project)

        if algorithm is None:
            raise cherrypy.HTTPRedirect("/tvb?error=True")

        if cherrypy.request.method == 'POST' and cancel:
            raise cherrypy.HTTPRedirect(back_page_link)

        submit_link = self.get_url_adapter(step_key, adapter_key, back_page)
        is_burst = back_page not in ['operations', 'data']
        if cherrypy.request.method == 'POST':
            data[common.KEY_ADAPTER] = adapter_key
            template_specification = self.execute_post(project.id, submit_link, step_key, algorithm, **data)
            self._populate_section(algorithm, template_specification, is_burst)
        else:
            template_specification = self.get_template_for_adapter(project.id, step_key, algorithm,
                                                                   submit_link, is_burst=is_burst)
        if template_specification is None:
            raise cherrypy.HTTPRedirect('/tvb')

        if KEY_CONTROLLS not in template_specification:
            template_specification[KEY_CONTROLLS] = None
        if common.KEY_SUBMIT_LINK not in template_specification:
            template_specification[common.KEY_SUBMIT_LINK] = submit_link
        if KEY_CONTENT not in template_specification:
            template_specification[KEY_CONTENT] = "flow/full_adapter_interface"
            template_specification[common.KEY_DISPLAY_MENU] = False
        else:
            template_specification[common.KEY_DISPLAY_MENU] = True
            template_specification[common.KEY_BACK_PAGE] = back_page_link

        template_specification[common.KEY_ADAPTER] = adapter_key
        template_specification[ABCDisplayer.KEY_IS_ADAPTER] = True
        self.fill_default_attributes(template_specification, algorithm.displayname)
        return template_specification

    @expose_fragment('form_fields/options_field')
    @settings
    @context_selected
    def get_filtered_datatypes(self, dt_module, dt_class, filters, has_all_option, has_none_option):
        """
        Given the name from the input tree, the dataType required and a number of
        filters, return the available dataType that satisfy the conditions imposed.
        """
        index_class = getattr(sys.modules[dt_module], dt_class)()
        filters_dict = json.loads(filters)

        for idx in range(len(filters_dict['fields'])):
            if filters_dict['values'][idx] in ['True', 'False']:
                filters_dict['values'][idx] = string2bool(filters_dict['values'][idx])

        filter = FilterChain(fields=filters_dict['fields'], operations=filters_dict['operations'],
                             values=filters_dict['values'])
        project = common.get_current_project()

        data_type_gid_attr = DataTypeGidAttr(linked_datatype=REGISTRY.get_datatype_for_index(index_class))
        data_type_gid_attr.required = not string2bool(has_none_option)

        select_field = TraitDataTypeSelectField(data_type_gid_attr, conditions=filter,
                                                has_all_option=string2bool(has_all_option))
        self.algorithm_service.fill_selectfield_with_datatypes(select_field, project.id)

        return {'options': select_field.options()}

    def execute_post(self, project_id, submit_url, step_key, algorithm, **data):
        """ Execute HTTP POST on a generic step."""
        errors = None
        adapter_instance = ABCAdapter.build_adapter(algorithm)

        try:
            form = self.algorithm_service.fill_adapter_form(adapter_instance, data, project_id)
            if form.validate():
                try:
                    view_model = form.get_view_model()()
                    form.fill_trait(view_model)
                    self.context.add_view_model_to_session(view_model)
                except NotImplementedError:
                    self.logger.exception("Form and/or ViewModel not fully implemented for " + str(form))
                    raise InvalidFormValues("Invalid form inputs! Could not find a model for this form!",
                                            error_dict=form.get_errors_dict())
            else:
                raise InvalidFormValues("Invalid form inputs! Could not fill algorithm from the given inputs!",
                                        error_dict=form.get_errors_dict())

            adapter_instance.submit_form(form)

            if issubclass(type(adapter_instance), ABCDisplayer):
                adapter_instance.current_project_id = project_id
                adapter_instance.user_id = common.get_logged_user().id
                result = adapter_instance.launch(view_model)
                if isinstance(result, dict):
                    return result
                else:
                    common.set_error_message("Invalid result returned from Displayer! Dictionary is expected!")
                return {}

            self.operation_services.fire_operation(adapter_instance, common.get_logged_user(), project_id,
                                                   view_model=view_model)
            common.set_important_message("Launched an operation.")

        except formencode.Invalid as excep:
            errors = excep.unpack_errors()
            common.set_error_message("Invalid form inputs")
            self.logger.warning("Invalid form inputs %s" % errors)
        except (OperationException, LaunchException, TraitValueError) as excep1:
            self.logger.exception("Error while executing a Launch procedure:" + excep1.message)
            common.set_error_message(excep1.message)
        except InvalidFormValues as excep2:
            message, errors = excep2.display_full_errors()
            common.set_error_message(message)
            self.logger.warning("%s \n %s" % (message, errors))

        template_specification = self.get_template_for_adapter(project_id, step_key, algorithm, submit_url)
        if (errors is not None) and (template_specification is not None):
            template_specification[common.KEY_ERRORS] = errors
        return template_specification

    def get_template_for_adapter(self, project_id, step_key, stored_adapter, submit_url, is_burst=True,
                                 is_callout=False):
        """ Get Input HTML Interface template or a given adapter """
        try:
            group = None
            category = self.algorithm_service.get_category_by_id(step_key)
            title = "Fill parameters for step " + category.displayname.lower()
            if group:
                title = title + " - " + group.displayname

            adapter_instance = self.algorithm_service.prepare_adapter(stored_adapter)

            adapter_form = self.algorithm_service.prepare_adapter_form(adapter_instance=adapter_instance,
                                                                       project_id=project_id)
            vm = self.context.get_view_model_from_session()
            if vm and type(vm) == adapter_form.get_view_model():
                adapter_form.fill_from_trait(vm)
            else:
                self.context.clean_from_session()
            template_specification = dict(submitLink=submit_url,
                                          adapter_form=self.render_adapter_form(adapter_form, is_callout=is_callout),
                                          title=title)

            self._populate_section(stored_adapter, template_specification, is_burst)
            return template_specification
        except OperationException as oexc:
            self.logger.error("Inconsistent Adapter")
            self.logger.exception(oexc)
            common.set_warning_message('Inconsistent Adapter!  Please review the link (development problem)!')
        return None

    @cherrypy.expose
    @handle_error(redirect=False)
    @check_user
    def readserverstaticfile(self, coded_path):
        """
        Retrieve file from Local storage, having a File System Path.
        """
        try:
            with open(url2path(coded_path), "rb") as f:
                return f.read()
        except Exception as excep:
            self.logger.error("Could not retrieve file from path:" + str(coded_path))
            self.logger.exception(excep)

    def _read_datatype_attribute(self, entity_gid, dataset_name, datatype_kwargs='null', **kwargs):

        self.logger.debug("Starting to read HDF5: " + entity_gid + "/" + dataset_name + "/" + str(kwargs))
        entity_dt = h5.load_from_gid(entity_gid)

        datatype_kwargs = json.loads(datatype_kwargs)
        if datatype_kwargs:
            for key, value in six.iteritems(datatype_kwargs):
                kwargs[key] = load_entity_by_gid(value)

        result = getattr(entity_dt, dataset_name)
        if callable(result):
            if kwargs:
                result = result(**kwargs)
            else:
                result = result()
        return result

    @expose_json
    def invoke_adapter(self, algo_id, method_name, entity_gid, **kwargs):
        algorithm = self.algorithm_service.get_algorithm_by_identifier(algo_id)
        adapter_instance = ABCAdapter.build_adapter(algorithm)
        entity = load_entity_by_gid(entity_gid)
        storage_path = self.files_helper.get_project_folder(entity.parent_operation.project,
                                                            str(entity.fk_from_operation))
        adapter_instance.storage_path = storage_path
        method = getattr(adapter_instance, method_name)
        if kwargs:
            return method(entity_gid, **kwargs)
        return method(entity_gid)

    def _read_from_h5(self, entity_gid, method_name, datatype_kwargs='null', **kwargs):
        self.logger.debug("Starting to read HDF5: " + entity_gid + "/" + method_name + "/" + str(kwargs))

        datatype_kwargs = json.loads(datatype_kwargs)
        if datatype_kwargs:
            for key, value in six.iteritems(datatype_kwargs):
                kwargs[key] = load_entity_by_gid(value)

        with h5.h5_file_for_gid(entity_gid) as entity_h5:
            result = getattr(entity_h5, method_name)
            if kwargs:
                result = result(**kwargs)
            else:
                result = result()

        return result

    @expose_json
    def read_from_h5_file(self, entity_gid, method_name, flatten=False, datatype_kwargs='null', **kwargs):
        result = self._read_from_h5(entity_gid, method_name, datatype_kwargs, **kwargs)
        return self._prepare_result(result, flatten)

    @expose_json
    def read_datatype_attribute(self, entity_gid, dataset_name, flatten=False, datatype_kwargs='null', **kwargs):
        """
        Retrieve from a given DataType a property or a method result.

        :returns: JSON representation of the attribute.
        :param entity_gid: GID for DataType entity
        :param dataset_name: name of the dataType property /method
        :param flatten: result should be flatten before return (use with WebGL data mainly e.g vertices/triangles)
            Ignored if the attribute is not an ndarray
        :param datatype_kwargs: if passed, will contain a dictionary of type {'name' : 'gid'}, and for each such
            pair, a load_entity will be performed and kwargs will be updated to contain the result
        :param kwargs: extra parameters to be passed when dataset_name is method.

        """
        result = self._read_datatype_attribute(entity_gid, dataset_name, datatype_kwargs, **kwargs)
        return self._prepare_result(result, flatten)

    def _prepare_result(self, result, flatten):
        if isinstance(result, numpy.ndarray):
            # for ndarrays honor the flatten kwarg and convert to lists as ndarrs are not json-able
            if flatten is True or flatten == "True":
                result = result.flatten()
            return result.tolist()
        else:
            return result

    @expose_numpy_array
    def read_binary_datatype_attribute(self, entity_gid, method_name, datatype_kwargs='null', **kwargs):
        return self._read_from_h5(entity_gid, method_name, datatype_kwargs, **kwargs)

    @expose_fragment("flow/genericAdapterFormFields")
    def get_simple_adapter_interface(self, algorithm_id, parent_div='', is_uploader=False):
        """
        AJAX exposed method. Will return only the interface for a adapter, to
        be used when tabs are needed.
        """
        curent_project = common.get_current_project()
        is_uploader = string2bool(is_uploader)
        template_specification = self.get_adapter_template(curent_project.id, algorithm_id, is_uploader)
        template_specification[common.KEY_PARENT_DIV] = parent_div
        return self.fill_default_attributes(template_specification)

    @expose_fragment("flow/full_adapter_interface")
    def getadapterinterface(self, project_id, algorithm_id, back_page=None):
        """
        AJAX exposed method. Will return only a piece of a page,
        to be integrated as part in another page.
        """
        template_specification = self.get_adapter_template(project_id, algorithm_id, False, back_page, is_callout=True)
        template_specification["isCallout"] = True
        return self.fill_default_attributes(template_specification)

    def get_adapter_template(self, project_id, algorithm_id, is_upload=False, back_page=None, is_callout=False):
        """
        Get the template for an adapter based on the algo group id.
        """
        if not (project_id and int(project_id) and (algorithm_id is not None) and int(algorithm_id)):
            return ""

        algorithm = self.algorithm_service.get_algorithm_by_identifier(algorithm_id)
        if is_upload:
            submit_link = "/project/launchloader/" + str(project_id) + "/" + str(algorithm_id)
        else:
            submit_link = self.get_url_adapter(algorithm.fk_category, algorithm.id, back_page)

        template_specification = self.get_template_for_adapter(project_id, algorithm.fk_category, algorithm,
                                                               submit_link, is_callout=is_callout)
        if template_specification is None:
            return ""
        template_specification[common.KEY_DISPLAY_MENU] = not is_upload
        return template_specification

    @cherrypy.expose
    @handle_error(redirect=True)
    @context_selected
    def reloadoperation(self, operation_id, **_):
        """Redirect to Operation Input selection page, with input data already selected."""
        operation = OperationService.load_operation(operation_id)
        # Reload previous parameters in session
        adapter_instance = ABCAdapter.build_adapter(operation.algorithm)
        view_model = adapter_instance.load_view_model(operation)
        self.context.add_view_model_to_session(view_model)
        # Display the inputs tree for the current op
        category_id = operation.algorithm.fk_category
        algo_id = operation.fk_from_algo
        raise cherrypy.HTTPRedirect("/flow/" + str(category_id) + "/" + str(algo_id))

    @cherrypy.expose
    @handle_error(redirect=True)
    @context_selected
    def reload_burst_operation(self, operation_id, is_group, **_):
        """
        Find out from which burst was this operation launched. Set that burst as the selected one and
        redirect to the burst page.
        """
        is_group = int(is_group)
        if not is_group:
            operation = OperationService.load_operation(int(operation_id))
        else:
            op_group = ProjectService.get_operation_group_by_id(operation_id)
            first_op = ProjectService.get_operations_in_group(op_group)[0]
            operation = OperationService.load_operation(int(first_op.id))
        self.simulator_controller.copy_simulator_configuration(operation.burst.id)

        raise cherrypy.HTTPRedirect("/burst/")

    @expose_json
    def cancel_or_remove_operation(self, operation_id, is_group, remove_after_stop=False):
        """
        Stop the operation given by operation_id. If is_group is true stop all the
        operations from that group.
        """
        operation_id = int(operation_id)
        is_group = int(is_group) != 0
        if isinstance(remove_after_stop, str):
            remove_after_stop = bool(remove_after_stop)
        return self.simulator_controller.cancel_or_remove_operation(operation_id, is_group, remove_after_stop)

    def fill_default_attributes(self, template_dictionary, title='-'):
        """
        Overwrite base controller to add required parameters for adapter templates.
        """
        if common.KEY_TITLE not in template_dictionary:
            template_dictionary[common.KEY_TITLE] = title

        if common.KEY_PARENT_DIV not in template_dictionary:
            template_dictionary[common.KEY_PARENT_DIV] = ''
        if common.KEY_PARAMETERS_CONFIG not in template_dictionary:
            template_dictionary[common.KEY_PARAMETERS_CONFIG] = False

        template_dictionary[common.KEY_INCLUDE_RESOURCES] = 'flow/included_resources'
        BaseController.fill_default_attributes(self, template_dictionary)
        return template_dictionary

    NEW_SELECTION_NAME = 'New selection'

    def _get_available_selections(self, datatype_gid):
        """
        selection retrieval common to selection component and connectivity selection
        """
        curent_project = common.get_current_project()
        selections = self.algorithm_service.get_selections_for_project(curent_project.id, datatype_gid)
        names, sel_values = [], []

        for selection in selections:
            names.append(selection.ui_name)
            sel_values.append(selection.selected_nodes)

        return names, sel_values

    @expose_fragment('visualizers/commons/channel_selector_opts')
    def get_available_selections(self, **data):
        sel_names, sel_values = self._get_available_selections(data['datatype_gid'])
        return dict(namedSelections=list(zip(sel_names, sel_values)))

    @expose_json
    def store_measure_points_selection(self, ui_name, **data):
        """
        Save a MeasurePoints selection (new or update existing entity).
        """
        if ui_name and ui_name != self.NEW_SELECTION_NAME:
            sel_project_id = common.get_current_project().id
            # client sends integers as strings:
            selection = json.dumps([int(s) for s in json.loads(data['selection'])])
            datatype_gid = data['datatype_gid']
            self.algorithm_service.save_measure_points_selection(ui_name, selection, datatype_gid, sel_project_id)
            return [True, 'Selection saved successfully.']

        else:
            error_msg = self.NEW_SELECTION_NAME + " or empty name are not  valid as selection names."
            return [False, error_msg]

    @expose_fragment("visualizers/pse_discrete/inserting_new_threshold_spec_bar")
    def create_row_of_specs(self, count):
        return dict(id_increment_count=count)

    @expose_json
    def store_pse_filter(self, config_name, **data):
        # this will need to be updated in such a way that the expose_json actually gets used
        ## also this is going to be changed to be storing through the flow service and dao. Stay updated
        try:
            ##this is to check whether there is already an entry in the
            for i, (name, Val) in enumerate(self.PSE_names_list):
                if name == config_name:
                    self.PSE_names_list[i] = (config_name, (
                            data['threshold_value'] + "," + data['threshold_type'] + "," + data[
                        'not_presence']))  # replace the previous occurence of the config name, and carry on.
                    self.get_pse_filters()
                    return [True, 'Selected Text stored, and selection updated']
            self.PSE_names_list.append(
                (config_name, (data['threshold_value'] + "," + data['threshold_type'] + "," + data['not_presence'])))
        except AttributeError:
            self.PSE_names_list = [
                (config_name, (data['threshold_value'] + "," + data['threshold_type'] + "," + data['not_presence']))]

        self.get_pse_filters()
        return [True, 'Selected Text stored, and selection updated']

    @expose_fragment("visualizers/commons/channel_selector_opts")
    def get_pse_filters(self):
        try:
            return dict(namedSelections=self.PSE_names_list)
        except AttributeError:
            return dict(namedSelections=[])  # this will give us back atleast the New Selection option in the select
        except:
            raise

    @expose_json
    def store_exploration_section(self, val_range, step, dt_group_guid):
        """
        Launching method for further simulations.
        """
        range_list = [float(num) for num in val_range.split(",")]
        step_list = [float(num) for num in step.split(",")]

        datatype_group_ob = self.project_service.get_datatypegroup_by_gid(dt_group_guid)
        operation_grp = datatype_group_ob.parent_operation_group
        operation_obj = OperationService.load_operation(datatype_group_ob.fk_from_operation)
        parameters = {}

        range1name, range1_dict = json.loads(operation_grp.range1)
        range2name, range2_dict = json.loads(operation_grp.range2)
        parameters[RANGE_PARAMETER_1] = range1name
        parameters[RANGE_PARAMETER_2] = range2name

        # change the existing simulator parameters to be min max step types
        range1_dict = {constants.ATT_MINVALUE: range_list[0],
                       constants.ATT_MAXVALUE: range_list[1],
                       constants.ATT_STEP: step_list[0]}
        range2_dict = {constants.ATT_MINVALUE: range_list[2],
                       constants.ATT_MAXVALUE: range_list[3],
                       constants.ATT_STEP: step_list[1]}
        parameters[range1name] = json.dumps(range1_dict)  # this is for the x axis parameter
        parameters[range2name] = json.dumps(range2_dict)  # this is for the y axis parameter

        OperationService().group_operation_launch(common.get_logged_user().id, common.get_current_project(),
                                                  operation_obj.algorithm.id, operation_obj.algorithm.fk_category,
                                                  **parameters)

        return [True, 'Stored the exploration material successfully']